solidrun.patch 6.9 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703627046270562706627076270862709627106271162712627136271462715627166271762718627196272062721627226272362724627256272662727627286272962730627316273262733627346273562736627376273862739627406274162742627436274462745627466274762748627496275062751627526275362754627556275662757627586275962760627616276262763627646276562766627676276862769627706277162772627736277462775627766277762778627796278062781627826278362784627856278662787627886278962790627916279262793627946279562796627976279862799628006280162802628036280462805628066280762808628096281062811628126281362814628156281662817628186281962820628216282262823628246282562826628276282862829628306283162832628336283462835628366283762838628396284062841628426284362844628456284662847628486284962850628516285262853628546285562856628576285862859628606286162862628636286462865628666286762868628696287062871628726287362874628756287662877628786287962880628816288262883628846288562886628876288862889628906289162892628936289462895628966289762898628996290062901629026290362904629056290662907629086290962910629116291262913629146291562916629176291862919629206292162922629236292462925629266292762928629296293062931629326293362934629356293662937629386293962940629416294262943629446294562946629476294862949629506295162952629536295462955629566295762958629596296062961629626296362964629656296662967629686296962970629716297262973629746297562976629776297862979629806298162982629836298462985629866298762988629896299062991629926299362994629956299662997629986299963000630016300263003630046300563006630076300863009630106301163012630136301463015630166301763018630196302063021630226302363024630256302663027630286302963030630316303263033630346303563036630376303863039630406304163042630436304463045630466304763048630496305063051630526305363054630556305663057630586305963060630616306263063630646306563066630676306863069630706307163072630736307463075630766307763078630796308063081630826308363084630856308663087630886308963090630916309263093630946309563096630976309863099631006310163102631036310463105631066310763108631096311063111631126311363114631156311663117631186311963120631216312263123631246312563126631276312863129631306313163132631336313463135631366313763138631396314063141631426314363144631456314663147631486314963150631516315263153631546315563156631576315863159631606316163162631636316463165631666316763168631696317063171631726317363174631756317663177631786317963180631816318263183631846318563186631876318863189631906319163192631936319463195631966319763198631996320063201632026320363204632056320663207632086320963210632116321263213632146321563216632176321863219632206322163222632236322463225632266322763228632296323063231632326323363234632356323663237632386323963240632416324263243632446324563246632476324863249632506325163252632536325463255632566325763258632596326063261632626326363264632656326663267632686326963270632716327263273632746327563276632776327863279632806328163282632836328463285632866328763288632896329063291632926329363294632956329663297632986329963300633016330263303633046330563306633076330863309633106331163312633136331463315633166331763318633196332063321633226332363324633256332663327633286332963330633316333263333633346333563336633376333863339633406334163342633436334463345633466334763348633496335063351633526335363354633556335663357633586335963360633616336263363633646336563366633676336863369633706337163372633736337463375633766337763378633796338063381633826338363384633856338663387633886338963390633916339263393633946339563396633976339863399634006340163402634036340463405634066340763408634096341063411634126341363414634156341663417634186341963420634216342263423634246342563426634276342863429634306343163432634336343463435634366343763438634396344063441634426344363444634456344663447634486344963450634516345263453634546345563456634576345863459634606346163462634636346463465634666346763468634696347063471634726347363474634756347663477634786347963480634816348263483634846348563486634876348863489634906349163492634936349463495634966349763498634996350063501635026350363504635056350663507635086350963510635116351263513635146351563516635176351863519635206352163522635236352463525635266352763528635296353063531635326353363534635356353663537635386353963540635416354263543635446354563546635476354863549635506355163552635536355463555635566355763558635596356063561635626356363564635656356663567635686356963570635716357263573635746357563576635776357863579635806358163582635836358463585635866358763588635896359063591635926359363594635956359663597635986359963600636016360263603636046360563606636076360863609636106361163612636136361463615636166361763618636196362063621636226362363624636256362663627636286362963630636316363263633636346363563636636376363863639636406364163642636436364463645636466364763648636496365063651636526365363654636556365663657636586365963660636616366263663636646366563666636676366863669636706367163672636736367463675636766367763678636796368063681636826368363684636856368663687636886368963690636916369263693636946369563696636976369863699637006370163702637036370463705637066370763708637096371063711637126371363714637156371663717637186371963720637216372263723637246372563726637276372863729637306373163732637336373463735637366373763738637396374063741637426374363744637456374663747637486374963750637516375263753637546375563756637576375863759637606376163762637636376463765637666376763768637696377063771637726377363774637756377663777637786377963780637816378263783637846378563786637876378863789637906379163792637936379463795637966379763798637996380063801638026380363804638056380663807638086380963810638116381263813638146381563816638176381863819638206382163822638236382463825638266382763828638296383063831638326383363834638356383663837638386383963840638416384263843638446384563846638476384863849638506385163852638536385463855638566385763858638596386063861638626386363864638656386663867638686386963870638716387263873638746387563876638776387863879638806388163882638836388463885638866388763888638896389063891638926389363894638956389663897638986389963900639016390263903639046390563906639076390863909639106391163912639136391463915639166391763918639196392063921639226392363924639256392663927639286392963930639316393263933639346393563936639376393863939639406394163942639436394463945639466394763948639496395063951639526395363954639556395663957639586395963960639616396263963639646396563966639676396863969639706397163972639736397463975639766397763978639796398063981639826398363984639856398663987639886398963990639916399263993639946399563996639976399863999640006400164002640036400464005640066400764008640096401064011640126401364014640156401664017640186401964020640216402264023640246402564026640276402864029640306403164032640336403464035640366403764038640396404064041640426404364044640456404664047640486404964050640516405264053640546405564056640576405864059640606406164062640636406464065640666406764068640696407064071640726407364074640756407664077640786407964080640816408264083640846408564086640876408864089640906409164092640936409464095640966409764098640996410064101641026410364104641056410664107641086410964110641116411264113641146411564116641176411864119641206412164122641236412464125641266412764128641296413064131641326413364134641356413664137641386413964140641416414264143641446414564146641476414864149641506415164152641536415464155641566415764158641596416064161641626416364164641656416664167641686416964170641716417264173641746417564176641776417864179641806418164182641836418464185641866418764188641896419064191641926419364194641956419664197641986419964200642016420264203642046420564206642076420864209642106421164212642136421464215642166421764218642196422064221642226422364224642256422664227642286422964230642316423264233642346423564236642376423864239642406424164242642436424464245642466424764248642496425064251642526425364254642556425664257642586425964260642616426264263642646426564266642676426864269642706427164272642736427464275642766427764278642796428064281642826428364284642856428664287642886428964290642916429264293642946429564296642976429864299643006430164302643036430464305643066430764308643096431064311643126431364314643156431664317643186431964320643216432264323643246432564326643276432864329643306433164332643336433464335643366433764338643396434064341643426434364344643456434664347643486434964350643516435264353643546435564356643576435864359643606436164362643636436464365643666436764368643696437064371643726437364374643756437664377643786437964380643816438264383643846438564386643876438864389643906439164392643936439464395643966439764398643996440064401644026440364404644056440664407644086440964410644116441264413644146441564416644176441864419644206442164422644236442464425644266442764428644296443064431644326443364434644356443664437644386443964440644416444264443644446444564446644476444864449644506445164452644536445464455644566445764458644596446064461644626446364464644656446664467644686446964470644716447264473644746447564476644776447864479644806448164482644836448464485644866448764488644896449064491644926449364494644956449664497644986449964500645016450264503645046450564506645076450864509645106451164512645136451464515645166451764518645196452064521645226452364524645256452664527645286452964530645316453264533645346453564536645376453864539645406454164542645436454464545645466454764548645496455064551645526455364554645556455664557645586455964560645616456264563645646456564566645676456864569645706457164572645736457464575645766457764578645796458064581645826458364584645856458664587645886458964590645916459264593645946459564596645976459864599646006460164602646036460464605646066460764608646096461064611646126461364614646156461664617646186461964620646216462264623646246462564626646276462864629646306463164632646336463464635646366463764638646396464064641646426464364644646456464664647646486464964650646516465264653646546465564656646576465864659646606466164662646636466464665646666466764668646696467064671646726467364674646756467664677646786467964680646816468264683646846468564686646876468864689646906469164692646936469464695646966469764698646996470064701647026470364704647056470664707647086470964710647116471264713647146471564716647176471864719647206472164722647236472464725647266472764728647296473064731647326473364734647356473664737647386473964740647416474264743647446474564746647476474864749647506475164752647536475464755647566475764758647596476064761647626476364764647656476664767647686476964770647716477264773647746477564776647776477864779647806478164782647836478464785647866478764788647896479064791647926479364794647956479664797647986479964800648016480264803648046480564806648076480864809648106481164812648136481464815648166481764818648196482064821648226482364824648256482664827648286482964830648316483264833648346483564836648376483864839648406484164842648436484464845648466484764848648496485064851648526485364854648556485664857648586485964860648616486264863648646486564866648676486864869648706487164872648736487464875648766487764878648796488064881648826488364884648856488664887648886488964890648916489264893648946489564896648976489864899649006490164902649036490464905649066490764908649096491064911649126491364914649156491664917649186491964920649216492264923649246492564926649276492864929649306493164932649336493464935649366493764938649396494064941649426494364944649456494664947649486494964950649516495264953649546495564956649576495864959649606496164962649636496464965649666496764968649696497064971649726497364974649756497664977649786497964980649816498264983649846498564986649876498864989649906499164992649936499464995649966499764998649996500065001650026500365004650056500665007650086500965010650116501265013650146501565016650176501865019650206502165022650236502465025650266502765028650296503065031650326503365034650356503665037650386503965040650416504265043650446504565046650476504865049650506505165052650536505465055650566505765058650596506065061650626506365064650656506665067650686506965070650716507265073650746507565076650776507865079650806508165082650836508465085650866508765088650896509065091650926509365094650956509665097650986509965100651016510265103651046510565106651076510865109651106511165112651136511465115651166511765118651196512065121651226512365124651256512665127651286512965130651316513265133651346513565136651376513865139651406514165142651436514465145651466514765148651496515065151651526515365154651556515665157651586515965160651616516265163651646516565166651676516865169651706517165172651736517465175651766517765178651796518065181651826518365184651856518665187651886518965190651916519265193651946519565196651976519865199652006520165202652036520465205652066520765208652096521065211652126521365214652156521665217652186521965220652216522265223652246522565226652276522865229652306523165232652336523465235652366523765238652396524065241652426524365244652456524665247652486524965250652516525265253652546525565256652576525865259652606526165262652636526465265652666526765268652696527065271652726527365274652756527665277652786527965280652816528265283652846528565286652876528865289652906529165292652936529465295652966529765298652996530065301653026530365304653056530665307653086530965310653116531265313653146531565316653176531865319653206532165322653236532465325653266532765328653296533065331653326533365334653356533665337653386533965340653416534265343653446534565346653476534865349653506535165352653536535465355653566535765358653596536065361653626536365364653656536665367653686536965370653716537265373653746537565376653776537865379653806538165382653836538465385653866538765388653896539065391653926539365394653956539665397653986539965400654016540265403654046540565406654076540865409654106541165412654136541465415654166541765418654196542065421654226542365424654256542665427654286542965430654316543265433654346543565436654376543865439654406544165442654436544465445654466544765448654496545065451654526545365454654556545665457654586545965460654616546265463654646546565466654676546865469654706547165472654736547465475654766547765478654796548065481654826548365484654856548665487654886548965490654916549265493654946549565496654976549865499655006550165502655036550465505655066550765508655096551065511655126551365514655156551665517655186551965520655216552265523655246552565526655276552865529655306553165532655336553465535655366553765538655396554065541655426554365544655456554665547655486554965550655516555265553655546555565556655576555865559655606556165562655636556465565655666556765568655696557065571655726557365574655756557665577655786557965580655816558265583655846558565586655876558865589655906559165592655936559465595655966559765598655996560065601656026560365604656056560665607656086560965610656116561265613656146561565616656176561865619656206562165622656236562465625656266562765628656296563065631656326563365634656356563665637656386563965640656416564265643656446564565646656476564865649656506565165652656536565465655656566565765658656596566065661656626566365664656656566665667656686566965670656716567265673656746567565676656776567865679656806568165682656836568465685656866568765688656896569065691656926569365694656956569665697656986569965700657016570265703657046570565706657076570865709657106571165712657136571465715657166571765718657196572065721657226572365724657256572665727657286572965730657316573265733657346573565736657376573865739657406574165742657436574465745657466574765748657496575065751657526575365754657556575665757657586575965760657616576265763657646576565766657676576865769657706577165772657736577465775657766577765778657796578065781657826578365784657856578665787657886578965790657916579265793657946579565796657976579865799658006580165802658036580465805658066580765808658096581065811658126581365814658156581665817658186581965820658216582265823658246582565826658276582865829658306583165832658336583465835658366583765838658396584065841658426584365844658456584665847658486584965850658516585265853658546585565856658576585865859658606586165862658636586465865658666586765868658696587065871658726587365874658756587665877658786587965880658816588265883658846588565886658876588865889658906589165892658936589465895658966589765898658996590065901659026590365904659056590665907659086590965910659116591265913659146591565916659176591865919659206592165922659236592465925659266592765928659296593065931659326593365934659356593665937659386593965940659416594265943659446594565946659476594865949659506595165952659536595465955659566595765958659596596065961659626596365964659656596665967659686596965970659716597265973659746597565976659776597865979659806598165982659836598465985659866598765988659896599065991659926599365994659956599665997659986599966000660016600266003660046600566006660076600866009660106601166012660136601466015660166601766018660196602066021660226602366024660256602666027660286602966030660316603266033660346603566036660376603866039660406604166042660436604466045660466604766048660496605066051660526605366054660556605666057660586605966060660616606266063660646606566066660676606866069660706607166072660736607466075660766607766078660796608066081660826608366084660856608666087660886608966090660916609266093660946609566096660976609866099661006610166102661036610466105661066610766108661096611066111661126611366114661156611666117661186611966120661216612266123661246612566126661276612866129661306613166132661336613466135661366613766138661396614066141661426614366144661456614666147661486614966150661516615266153661546615566156661576615866159661606616166162661636616466165661666616766168661696617066171661726617366174661756617666177661786617966180661816618266183661846618566186661876618866189661906619166192661936619466195661966619766198661996620066201662026620366204662056620666207662086620966210662116621266213662146621566216662176621866219662206622166222662236622466225662266622766228662296623066231662326623366234662356623666237662386623966240662416624266243662446624566246662476624866249662506625166252662536625466255662566625766258662596626066261662626626366264662656626666267662686626966270662716627266273662746627566276662776627866279662806628166282662836628466285662866628766288662896629066291662926629366294662956629666297662986629966300663016630266303663046630566306663076630866309663106631166312663136631466315663166631766318663196632066321663226632366324663256632666327663286632966330663316633266333663346633566336663376633866339663406634166342663436634466345663466634766348663496635066351663526635366354663556635666357663586635966360663616636266363663646636566366663676636866369663706637166372663736637466375663766637766378663796638066381663826638366384663856638666387663886638966390663916639266393663946639566396663976639866399664006640166402664036640466405664066640766408664096641066411664126641366414664156641666417664186641966420664216642266423664246642566426664276642866429664306643166432664336643466435664366643766438664396644066441664426644366444664456644666447664486644966450664516645266453664546645566456664576645866459664606646166462664636646466465664666646766468664696647066471664726647366474664756647666477664786647966480664816648266483664846648566486664876648866489664906649166492664936649466495664966649766498664996650066501665026650366504665056650666507665086650966510665116651266513665146651566516665176651866519665206652166522665236652466525665266652766528665296653066531665326653366534665356653666537665386653966540665416654266543665446654566546665476654866549665506655166552665536655466555665566655766558665596656066561665626656366564665656656666567665686656966570665716657266573665746657566576665776657866579665806658166582665836658466585665866658766588665896659066591665926659366594665956659666597665986659966600666016660266603666046660566606666076660866609666106661166612666136661466615666166661766618666196662066621666226662366624666256662666627666286662966630666316663266633666346663566636666376663866639666406664166642666436664466645666466664766648666496665066651666526665366654666556665666657666586665966660666616666266663666646666566666666676666866669666706667166672666736667466675666766667766678666796668066681666826668366684666856668666687666886668966690666916669266693666946669566696666976669866699667006670166702667036670466705667066670766708667096671066711667126671366714667156671666717667186671966720667216672266723667246672566726667276672866729667306673166732667336673466735667366673766738667396674066741667426674366744667456674666747667486674966750667516675266753667546675566756667576675866759667606676166762667636676466765667666676766768667696677066771667726677366774667756677666777667786677966780667816678266783667846678566786667876678866789667906679166792667936679466795667966679766798667996680066801668026680366804668056680666807668086680966810668116681266813668146681566816668176681866819668206682166822668236682466825668266682766828668296683066831668326683366834668356683666837668386683966840668416684266843668446684566846668476684866849668506685166852668536685466855668566685766858668596686066861668626686366864668656686666867668686686966870668716687266873668746687566876668776687866879668806688166882668836688466885668866688766888668896689066891668926689366894668956689666897668986689966900669016690266903669046690566906669076690866909669106691166912669136691466915669166691766918669196692066921669226692366924669256692666927669286692966930669316693266933669346693566936669376693866939669406694166942669436694466945669466694766948669496695066951669526695366954669556695666957669586695966960669616696266963669646696566966669676696866969669706697166972669736697466975669766697766978669796698066981669826698366984669856698666987669886698966990669916699266993669946699566996669976699866999670006700167002670036700467005670066700767008670096701067011670126701367014670156701667017670186701967020670216702267023670246702567026670276702867029670306703167032670336703467035670366703767038670396704067041670426704367044670456704667047670486704967050670516705267053670546705567056670576705867059670606706167062670636706467065670666706767068670696707067071670726707367074670756707667077670786707967080670816708267083670846708567086670876708867089670906709167092670936709467095670966709767098670996710067101671026710367104671056710667107671086710967110671116711267113671146711567116671176711867119671206712167122671236712467125671266712767128671296713067131671326713367134671356713667137671386713967140671416714267143671446714567146671476714867149671506715167152671536715467155671566715767158671596716067161671626716367164671656716667167671686716967170671716717267173671746717567176671776717867179671806718167182671836718467185671866718767188671896719067191671926719367194671956719667197671986719967200672016720267203672046720567206672076720867209672106721167212672136721467215672166721767218672196722067221672226722367224672256722667227672286722967230672316723267233672346723567236672376723867239672406724167242672436724467245672466724767248672496725067251672526725367254672556725667257672586725967260672616726267263672646726567266672676726867269672706727167272672736727467275672766727767278672796728067281672826728367284672856728667287672886728967290672916729267293672946729567296672976729867299673006730167302673036730467305673066730767308673096731067311673126731367314673156731667317673186731967320673216732267323673246732567326673276732867329673306733167332673336733467335673366733767338673396734067341673426734367344673456734667347673486734967350673516735267353673546735567356673576735867359673606736167362673636736467365673666736767368673696737067371673726737367374673756737667377673786737967380673816738267383673846738567386673876738867389673906739167392673936739467395673966739767398673996740067401674026740367404674056740667407674086740967410674116741267413674146741567416674176741867419674206742167422674236742467425674266742767428674296743067431674326743367434674356743667437674386743967440674416744267443674446744567446674476744867449674506745167452674536745467455674566745767458674596746067461674626746367464674656746667467674686746967470674716747267473674746747567476674776747867479674806748167482674836748467485674866748767488674896749067491674926749367494674956749667497674986749967500675016750267503675046750567506675076750867509675106751167512675136751467515675166751767518675196752067521675226752367524675256752667527675286752967530675316753267533675346753567536675376753867539675406754167542675436754467545675466754767548675496755067551675526755367554675556755667557675586755967560675616756267563675646756567566675676756867569675706757167572675736757467575675766757767578675796758067581675826758367584675856758667587675886758967590675916759267593675946759567596675976759867599676006760167602676036760467605676066760767608676096761067611676126761367614676156761667617676186761967620676216762267623676246762567626676276762867629676306763167632676336763467635676366763767638676396764067641676426764367644676456764667647676486764967650676516765267653676546765567656676576765867659676606766167662676636766467665676666766767668676696767067671676726767367674676756767667677676786767967680676816768267683676846768567686676876768867689676906769167692676936769467695676966769767698676996770067701677026770367704677056770667707677086770967710677116771267713677146771567716677176771867719677206772167722677236772467725677266772767728677296773067731677326773367734677356773667737677386773967740677416774267743677446774567746677476774867749677506775167752677536775467755677566775767758677596776067761677626776367764677656776667767677686776967770677716777267773677746777567776677776777867779677806778167782677836778467785677866778767788677896779067791677926779367794677956779667797677986779967800678016780267803678046780567806678076780867809678106781167812678136781467815678166781767818678196782067821678226782367824678256782667827678286782967830678316783267833678346783567836678376783867839678406784167842678436784467845678466784767848678496785067851678526785367854678556785667857678586785967860678616786267863678646786567866678676786867869678706787167872678736787467875678766787767878678796788067881678826788367884678856788667887678886788967890678916789267893678946789567896678976789867899679006790167902679036790467905679066790767908679096791067911679126791367914679156791667917679186791967920679216792267923679246792567926679276792867929679306793167932679336793467935679366793767938679396794067941679426794367944679456794667947679486794967950679516795267953679546795567956679576795867959679606796167962679636796467965679666796767968679696797067971679726797367974679756797667977679786797967980679816798267983679846798567986679876798867989679906799167992679936799467995679966799767998679996800068001680026800368004680056800668007680086800968010680116801268013680146801568016680176801868019680206802168022680236802468025680266802768028680296803068031680326803368034680356803668037680386803968040680416804268043680446804568046680476804868049680506805168052680536805468055680566805768058680596806068061680626806368064680656806668067680686806968070680716807268073680746807568076680776807868079680806808168082680836808468085680866808768088680896809068091680926809368094680956809668097680986809968100681016810268103681046810568106681076810868109681106811168112681136811468115681166811768118681196812068121681226812368124681256812668127681286812968130681316813268133681346813568136681376813868139681406814168142681436814468145681466814768148681496815068151681526815368154681556815668157681586815968160681616816268163681646816568166681676816868169681706817168172681736817468175681766817768178681796818068181681826818368184681856818668187681886818968190681916819268193681946819568196681976819868199682006820168202682036820468205682066820768208682096821068211682126821368214682156821668217682186821968220682216822268223682246822568226682276822868229682306823168232682336823468235682366823768238682396824068241682426824368244682456824668247682486824968250682516825268253682546825568256682576825868259682606826168262682636826468265682666826768268682696827068271682726827368274682756827668277682786827968280682816828268283682846828568286682876828868289682906829168292682936829468295682966829768298682996830068301683026830368304683056830668307683086830968310683116831268313683146831568316683176831868319683206832168322683236832468325683266832768328683296833068331683326833368334683356833668337683386833968340683416834268343683446834568346683476834868349683506835168352683536835468355683566835768358683596836068361683626836368364683656836668367683686836968370683716837268373683746837568376683776837868379683806838168382683836838468385683866838768388683896839068391683926839368394683956839668397683986839968400684016840268403684046840568406684076840868409684106841168412684136841468415684166841768418684196842068421684226842368424684256842668427684286842968430684316843268433684346843568436684376843868439684406844168442684436844468445684466844768448684496845068451684526845368454684556845668457684586845968460684616846268463684646846568466684676846868469684706847168472684736847468475684766847768478684796848068481684826848368484684856848668487684886848968490684916849268493684946849568496684976849868499685006850168502685036850468505685066850768508685096851068511685126851368514685156851668517685186851968520685216852268523685246852568526685276852868529685306853168532685336853468535685366853768538685396854068541685426854368544685456854668547685486854968550685516855268553685546855568556685576855868559685606856168562685636856468565685666856768568685696857068571685726857368574685756857668577685786857968580685816858268583685846858568586685876858868589685906859168592685936859468595685966859768598685996860068601686026860368604686056860668607686086860968610686116861268613686146861568616686176861868619686206862168622686236862468625686266862768628686296863068631686326863368634686356863668637686386863968640686416864268643686446864568646686476864868649686506865168652686536865468655686566865768658686596866068661686626866368664686656866668667686686866968670686716867268673686746867568676686776867868679686806868168682686836868468685686866868768688686896869068691686926869368694686956869668697686986869968700687016870268703687046870568706687076870868709687106871168712687136871468715687166871768718687196872068721687226872368724687256872668727687286872968730687316873268733687346873568736687376873868739687406874168742687436874468745687466874768748687496875068751687526875368754687556875668757687586875968760687616876268763687646876568766687676876868769687706877168772687736877468775687766877768778687796878068781687826878368784687856878668787687886878968790687916879268793687946879568796687976879868799688006880168802688036880468805688066880768808688096881068811688126881368814688156881668817688186881968820688216882268823688246882568826688276882868829688306883168832688336883468835688366883768838688396884068841688426884368844688456884668847688486884968850688516885268853688546885568856688576885868859688606886168862688636886468865688666886768868688696887068871688726887368874688756887668877688786887968880688816888268883688846888568886688876888868889688906889168892688936889468895688966889768898688996890068901689026890368904689056890668907689086890968910689116891268913689146891568916689176891868919689206892168922689236892468925689266892768928689296893068931689326893368934689356893668937689386893968940689416894268943689446894568946689476894868949689506895168952689536895468955689566895768958689596896068961689626896368964689656896668967689686896968970689716897268973689746897568976689776897868979689806898168982689836898468985689866898768988689896899068991689926899368994689956899668997689986899969000690016900269003690046900569006690076900869009690106901169012690136901469015690166901769018690196902069021690226902369024690256902669027690286902969030690316903269033690346903569036690376903869039690406904169042690436904469045690466904769048690496905069051690526905369054690556905669057690586905969060690616906269063690646906569066690676906869069690706907169072690736907469075690766907769078690796908069081690826908369084690856908669087690886908969090690916909269093690946909569096690976909869099691006910169102691036910469105691066910769108691096911069111691126911369114691156911669117691186911969120691216912269123691246912569126691276912869129691306913169132691336913469135691366913769138691396914069141691426914369144691456914669147691486914969150691516915269153691546915569156691576915869159691606916169162691636916469165691666916769168691696917069171691726917369174691756917669177691786917969180691816918269183691846918569186691876918869189691906919169192691936919469195691966919769198691996920069201692026920369204692056920669207692086920969210692116921269213692146921569216692176921869219692206922169222692236922469225692266922769228692296923069231692326923369234692356923669237692386923969240692416924269243692446924569246692476924869249692506925169252692536925469255692566925769258692596926069261692626926369264692656926669267692686926969270692716927269273692746927569276692776927869279692806928169282692836928469285692866928769288692896929069291692926929369294692956929669297692986929969300693016930269303693046930569306693076930869309693106931169312693136931469315693166931769318693196932069321693226932369324693256932669327693286932969330693316933269333693346933569336693376933869339693406934169342693436934469345693466934769348693496935069351693526935369354693556935669357693586935969360693616936269363693646936569366693676936869369693706937169372693736937469375693766937769378693796938069381693826938369384693856938669387693886938969390693916939269393693946939569396693976939869399694006940169402694036940469405694066940769408694096941069411694126941369414694156941669417694186941969420694216942269423694246942569426694276942869429694306943169432694336943469435694366943769438694396944069441694426944369444694456944669447694486944969450694516945269453694546945569456694576945869459694606946169462694636946469465694666946769468694696947069471694726947369474694756947669477694786947969480694816948269483694846948569486694876948869489694906949169492694936949469495694966949769498694996950069501695026950369504695056950669507695086950969510695116951269513695146951569516695176951869519695206952169522695236952469525695266952769528695296953069531695326953369534695356953669537695386953969540695416954269543695446954569546695476954869549695506955169552695536955469555695566955769558695596956069561695626956369564695656956669567695686956969570695716957269573695746957569576695776957869579695806958169582695836958469585695866958769588695896959069591695926959369594695956959669597695986959969600696016960269603696046960569606696076960869609696106961169612696136961469615696166961769618696196962069621696226962369624696256962669627696286962969630696316963269633696346963569636696376963869639696406964169642696436964469645696466964769648696496965069651696526965369654696556965669657696586965969660696616966269663696646966569666696676966869669696706967169672696736967469675696766967769678696796968069681696826968369684696856968669687696886968969690696916969269693696946969569696696976969869699697006970169702697036970469705697066970769708697096971069711697126971369714697156971669717697186971969720697216972269723697246972569726697276972869729697306973169732697336973469735697366973769738697396974069741697426974369744697456974669747697486974969750697516975269753697546975569756697576975869759697606976169762697636976469765697666976769768697696977069771697726977369774697756977669777697786977969780697816978269783697846978569786697876978869789697906979169792697936979469795697966979769798697996980069801698026980369804698056980669807698086980969810698116981269813698146981569816698176981869819698206982169822698236982469825698266982769828698296983069831698326983369834698356983669837698386983969840698416984269843698446984569846698476984869849698506985169852698536985469855698566985769858698596986069861698626986369864698656986669867698686986969870698716987269873698746987569876698776987869879698806988169882698836988469885698866988769888698896989069891698926989369894698956989669897698986989969900699016990269903699046990569906699076990869909699106991169912699136991469915699166991769918699196992069921699226992369924699256992669927699286992969930699316993269933699346993569936699376993869939699406994169942699436994469945699466994769948699496995069951699526995369954699556995669957699586995969960699616996269963699646996569966699676996869969699706997169972699736997469975699766997769978699796998069981699826998369984699856998669987699886998969990699916999269993699946999569996699976999869999700007000170002700037000470005700067000770008700097001070011700127001370014700157001670017700187001970020700217002270023700247002570026700277002870029700307003170032700337003470035700367003770038700397004070041700427004370044700457004670047700487004970050700517005270053700547005570056700577005870059700607006170062700637006470065700667006770068700697007070071700727007370074700757007670077700787007970080700817008270083700847008570086700877008870089700907009170092700937009470095700967009770098700997010070101701027010370104701057010670107701087010970110701117011270113701147011570116701177011870119701207012170122701237012470125701267012770128701297013070131701327013370134701357013670137701387013970140701417014270143701447014570146701477014870149701507015170152701537015470155701567015770158701597016070161701627016370164701657016670167701687016970170701717017270173701747017570176701777017870179701807018170182701837018470185701867018770188701897019070191701927019370194701957019670197701987019970200702017020270203702047020570206702077020870209702107021170212702137021470215702167021770218702197022070221702227022370224702257022670227702287022970230702317023270233702347023570236702377023870239702407024170242702437024470245702467024770248702497025070251702527025370254702557025670257702587025970260702617026270263702647026570266702677026870269702707027170272702737027470275702767027770278702797028070281702827028370284702857028670287702887028970290702917029270293702947029570296702977029870299703007030170302703037030470305703067030770308703097031070311703127031370314703157031670317703187031970320703217032270323703247032570326703277032870329703307033170332703337033470335703367033770338703397034070341703427034370344703457034670347703487034970350703517035270353703547035570356703577035870359703607036170362703637036470365703667036770368703697037070371703727037370374703757037670377703787037970380703817038270383703847038570386703877038870389703907039170392703937039470395703967039770398703997040070401704027040370404704057040670407704087040970410704117041270413704147041570416704177041870419704207042170422704237042470425704267042770428704297043070431704327043370434704357043670437704387043970440704417044270443704447044570446704477044870449704507045170452704537045470455704567045770458704597046070461704627046370464704657046670467704687046970470704717047270473704747047570476704777047870479704807048170482704837048470485704867048770488704897049070491704927049370494704957049670497704987049970500705017050270503705047050570506705077050870509705107051170512705137051470515705167051770518705197052070521705227052370524705257052670527705287052970530705317053270533705347053570536705377053870539705407054170542705437054470545705467054770548705497055070551705527055370554705557055670557705587055970560705617056270563705647056570566705677056870569705707057170572705737057470575705767057770578705797058070581705827058370584705857058670587705887058970590705917059270593705947059570596705977059870599706007060170602706037060470605706067060770608706097061070611706127061370614706157061670617706187061970620706217062270623706247062570626706277062870629706307063170632706337063470635706367063770638706397064070641706427064370644706457064670647706487064970650706517065270653706547065570656706577065870659706607066170662706637066470665706667066770668706697067070671706727067370674706757067670677706787067970680706817068270683706847068570686706877068870689706907069170692706937069470695706967069770698706997070070701707027070370704707057070670707707087070970710707117071270713707147071570716707177071870719707207072170722707237072470725707267072770728707297073070731707327073370734707357073670737707387073970740707417074270743707447074570746707477074870749707507075170752707537075470755707567075770758707597076070761707627076370764707657076670767707687076970770707717077270773707747077570776707777077870779707807078170782707837078470785707867078770788707897079070791707927079370794707957079670797707987079970800708017080270803708047080570806708077080870809708107081170812708137081470815708167081770818708197082070821708227082370824708257082670827708287082970830708317083270833708347083570836708377083870839708407084170842708437084470845708467084770848708497085070851708527085370854708557085670857708587085970860708617086270863708647086570866708677086870869708707087170872708737087470875708767087770878708797088070881708827088370884708857088670887708887088970890708917089270893708947089570896708977089870899709007090170902709037090470905709067090770908709097091070911709127091370914709157091670917709187091970920709217092270923709247092570926709277092870929709307093170932709337093470935709367093770938709397094070941709427094370944709457094670947709487094970950709517095270953709547095570956709577095870959709607096170962709637096470965709667096770968709697097070971709727097370974709757097670977709787097970980709817098270983709847098570986709877098870989709907099170992709937099470995709967099770998709997100071001710027100371004710057100671007710087100971010710117101271013710147101571016710177101871019710207102171022710237102471025710267102771028710297103071031710327103371034710357103671037710387103971040710417104271043710447104571046710477104871049710507105171052710537105471055710567105771058710597106071061710627106371064710657106671067710687106971070710717107271073710747107571076710777107871079710807108171082710837108471085710867108771088710897109071091710927109371094710957109671097710987109971100711017110271103711047110571106711077110871109711107111171112711137111471115711167111771118711197112071121711227112371124711257112671127711287112971130711317113271133711347113571136711377113871139711407114171142711437114471145711467114771148711497115071151711527115371154711557115671157711587115971160711617116271163711647116571166711677116871169711707117171172711737117471175711767117771178711797118071181711827118371184711857118671187711887118971190711917119271193711947119571196711977119871199712007120171202712037120471205712067120771208712097121071211712127121371214712157121671217712187121971220712217122271223712247122571226712277122871229712307123171232712337123471235712367123771238712397124071241712427124371244712457124671247712487124971250712517125271253712547125571256712577125871259712607126171262712637126471265712667126771268712697127071271712727127371274712757127671277712787127971280712817128271283712847128571286712877128871289712907129171292712937129471295712967129771298712997130071301713027130371304713057130671307713087130971310713117131271313713147131571316713177131871319713207132171322713237132471325713267132771328713297133071331713327133371334713357133671337713387133971340713417134271343713447134571346713477134871349713507135171352713537135471355713567135771358713597136071361713627136371364713657136671367713687136971370713717137271373713747137571376713777137871379713807138171382713837138471385713867138771388713897139071391713927139371394713957139671397713987139971400714017140271403714047140571406714077140871409714107141171412714137141471415714167141771418714197142071421714227142371424714257142671427714287142971430714317143271433714347143571436714377143871439714407144171442714437144471445714467144771448714497145071451714527145371454714557145671457714587145971460714617146271463714647146571466714677146871469714707147171472714737147471475714767147771478714797148071481714827148371484714857148671487714887148971490714917149271493714947149571496714977149871499715007150171502715037150471505715067150771508715097151071511715127151371514715157151671517715187151971520715217152271523715247152571526715277152871529715307153171532715337153471535715367153771538715397154071541715427154371544715457154671547715487154971550715517155271553715547155571556715577155871559715607156171562715637156471565715667156771568715697157071571715727157371574715757157671577715787157971580715817158271583715847158571586715877158871589715907159171592715937159471595715967159771598715997160071601716027160371604716057160671607716087160971610716117161271613716147161571616716177161871619716207162171622716237162471625716267162771628716297163071631716327163371634716357163671637716387163971640716417164271643716447164571646716477164871649716507165171652716537165471655716567165771658716597166071661716627166371664716657166671667716687166971670716717167271673716747167571676716777167871679716807168171682716837168471685716867168771688716897169071691716927169371694716957169671697716987169971700717017170271703717047170571706717077170871709717107171171712717137171471715717167171771718717197172071721717227172371724717257172671727717287172971730717317173271733717347173571736717377173871739717407174171742717437174471745717467174771748717497175071751717527175371754717557175671757717587175971760717617176271763717647176571766717677176871769717707177171772717737177471775717767177771778717797178071781717827178371784717857178671787717887178971790717917179271793717947179571796717977179871799718007180171802718037180471805718067180771808718097181071811718127181371814718157181671817718187181971820718217182271823718247182571826718277182871829718307183171832718337183471835718367183771838718397184071841718427184371844718457184671847718487184971850718517185271853718547185571856718577185871859718607186171862718637186471865718667186771868718697187071871718727187371874718757187671877718787187971880718817188271883718847188571886718877188871889718907189171892718937189471895718967189771898718997190071901719027190371904719057190671907719087190971910719117191271913719147191571916719177191871919719207192171922719237192471925719267192771928719297193071931719327193371934719357193671937719387193971940719417194271943719447194571946719477194871949719507195171952719537195471955719567195771958719597196071961719627196371964719657196671967719687196971970719717197271973719747197571976719777197871979719807198171982719837198471985719867198771988719897199071991719927199371994719957199671997719987199972000720017200272003720047200572006720077200872009720107201172012720137201472015720167201772018720197202072021720227202372024720257202672027720287202972030720317203272033720347203572036720377203872039720407204172042720437204472045720467204772048720497205072051720527205372054720557205672057720587205972060720617206272063720647206572066720677206872069720707207172072720737207472075720767207772078720797208072081720827208372084720857208672087720887208972090720917209272093720947209572096720977209872099721007210172102721037210472105721067210772108721097211072111721127211372114721157211672117721187211972120721217212272123721247212572126721277212872129721307213172132721337213472135721367213772138721397214072141721427214372144721457214672147721487214972150721517215272153721547215572156721577215872159721607216172162721637216472165721667216772168721697217072171721727217372174721757217672177721787217972180721817218272183721847218572186721877218872189721907219172192721937219472195721967219772198721997220072201722027220372204722057220672207722087220972210722117221272213722147221572216722177221872219722207222172222722237222472225722267222772228722297223072231722327223372234722357223672237722387223972240722417224272243722447224572246722477224872249722507225172252722537225472255722567225772258722597226072261722627226372264722657226672267722687226972270722717227272273722747227572276722777227872279722807228172282722837228472285722867228772288722897229072291722927229372294722957229672297722987229972300723017230272303723047230572306723077230872309723107231172312723137231472315723167231772318723197232072321723227232372324723257232672327723287232972330723317233272333723347233572336723377233872339723407234172342723437234472345723467234772348723497235072351723527235372354723557235672357723587235972360723617236272363723647236572366723677236872369723707237172372723737237472375723767237772378723797238072381723827238372384723857238672387723887238972390723917239272393723947239572396723977239872399724007240172402724037240472405724067240772408724097241072411724127241372414724157241672417724187241972420724217242272423724247242572426724277242872429724307243172432724337243472435724367243772438724397244072441724427244372444724457244672447724487244972450724517245272453724547245572456724577245872459724607246172462724637246472465724667246772468724697247072471724727247372474724757247672477724787247972480724817248272483724847248572486724877248872489724907249172492724937249472495724967249772498724997250072501725027250372504725057250672507725087250972510725117251272513725147251572516725177251872519725207252172522725237252472525725267252772528725297253072531725327253372534725357253672537725387253972540725417254272543725447254572546725477254872549725507255172552725537255472555725567255772558725597256072561725627256372564725657256672567725687256972570725717257272573725747257572576725777257872579725807258172582725837258472585725867258772588725897259072591725927259372594725957259672597725987259972600726017260272603726047260572606726077260872609726107261172612726137261472615726167261772618726197262072621726227262372624726257262672627726287262972630726317263272633726347263572636726377263872639726407264172642726437264472645726467264772648726497265072651726527265372654726557265672657726587265972660726617266272663726647266572666726677266872669726707267172672726737267472675726767267772678726797268072681726827268372684726857268672687726887268972690726917269272693726947269572696726977269872699727007270172702727037270472705727067270772708727097271072711727127271372714727157271672717727187271972720727217272272723727247272572726727277272872729727307273172732727337273472735727367273772738727397274072741727427274372744727457274672747727487274972750727517275272753727547275572756727577275872759727607276172762727637276472765727667276772768727697277072771727727277372774727757277672777727787277972780727817278272783727847278572786727877278872789727907279172792727937279472795727967279772798727997280072801728027280372804728057280672807728087280972810728117281272813728147281572816728177281872819728207282172822728237282472825728267282772828728297283072831728327283372834728357283672837728387283972840728417284272843728447284572846728477284872849728507285172852728537285472855728567285772858728597286072861728627286372864728657286672867728687286972870728717287272873728747287572876728777287872879728807288172882728837288472885728867288772888728897289072891728927289372894728957289672897728987289972900729017290272903729047290572906729077290872909729107291172912729137291472915729167291772918729197292072921729227292372924729257292672927729287292972930729317293272933729347293572936729377293872939729407294172942729437294472945729467294772948729497295072951729527295372954729557295672957729587295972960729617296272963729647296572966729677296872969729707297172972729737297472975729767297772978729797298072981729827298372984729857298672987729887298972990729917299272993729947299572996729977299872999730007300173002730037300473005730067300773008730097301073011730127301373014730157301673017730187301973020730217302273023730247302573026730277302873029730307303173032730337303473035730367303773038730397304073041730427304373044730457304673047730487304973050730517305273053730547305573056730577305873059730607306173062730637306473065730667306773068730697307073071730727307373074730757307673077730787307973080730817308273083730847308573086730877308873089730907309173092730937309473095730967309773098730997310073101731027310373104731057310673107731087310973110731117311273113731147311573116731177311873119731207312173122731237312473125731267312773128731297313073131731327313373134731357313673137731387313973140731417314273143731447314573146731477314873149731507315173152731537315473155731567315773158731597316073161731627316373164731657316673167731687316973170731717317273173731747317573176731777317873179731807318173182731837318473185731867318773188731897319073191731927319373194731957319673197731987319973200732017320273203732047320573206732077320873209732107321173212732137321473215732167321773218732197322073221732227322373224732257322673227732287322973230732317323273233732347323573236732377323873239732407324173242732437324473245732467324773248732497325073251732527325373254732557325673257732587325973260732617326273263732647326573266732677326873269732707327173272732737327473275732767327773278732797328073281732827328373284732857328673287732887328973290732917329273293732947329573296732977329873299733007330173302733037330473305733067330773308733097331073311733127331373314733157331673317733187331973320733217332273323733247332573326733277332873329733307333173332733337333473335733367333773338733397334073341733427334373344733457334673347733487334973350733517335273353733547335573356733577335873359733607336173362733637336473365733667336773368733697337073371733727337373374733757337673377733787337973380733817338273383733847338573386733877338873389733907339173392733937339473395733967339773398733997340073401734027340373404734057340673407734087340973410734117341273413734147341573416734177341873419734207342173422734237342473425734267342773428734297343073431734327343373434734357343673437734387343973440734417344273443734447344573446734477344873449734507345173452734537345473455734567345773458734597346073461734627346373464734657346673467734687346973470734717347273473734747347573476734777347873479734807348173482734837348473485734867348773488734897349073491734927349373494734957349673497734987349973500735017350273503735047350573506735077350873509735107351173512735137351473515735167351773518735197352073521735227352373524735257352673527735287352973530735317353273533735347353573536735377353873539735407354173542735437354473545735467354773548735497355073551735527355373554735557355673557735587355973560735617356273563735647356573566735677356873569735707357173572735737357473575735767357773578735797358073581735827358373584735857358673587735887358973590735917359273593735947359573596735977359873599736007360173602736037360473605736067360773608736097361073611736127361373614736157361673617736187361973620736217362273623736247362573626736277362873629736307363173632736337363473635736367363773638736397364073641736427364373644736457364673647736487364973650736517365273653736547365573656736577365873659736607366173662736637366473665736667366773668736697367073671736727367373674736757367673677736787367973680736817368273683736847368573686736877368873689736907369173692736937369473695736967369773698736997370073701737027370373704737057370673707737087370973710737117371273713737147371573716737177371873719737207372173722737237372473725737267372773728737297373073731737327373373734737357373673737737387373973740737417374273743737447374573746737477374873749737507375173752737537375473755737567375773758737597376073761737627376373764737657376673767737687376973770737717377273773737747377573776737777377873779737807378173782737837378473785737867378773788737897379073791737927379373794737957379673797737987379973800738017380273803738047380573806738077380873809738107381173812738137381473815738167381773818738197382073821738227382373824738257382673827738287382973830738317383273833738347383573836738377383873839738407384173842738437384473845738467384773848738497385073851738527385373854738557385673857738587385973860738617386273863738647386573866738677386873869738707387173872738737387473875738767387773878738797388073881738827388373884738857388673887738887388973890738917389273893738947389573896738977389873899739007390173902739037390473905739067390773908739097391073911739127391373914739157391673917739187391973920739217392273923739247392573926739277392873929739307393173932739337393473935739367393773938739397394073941739427394373944739457394673947739487394973950739517395273953739547395573956739577395873959739607396173962739637396473965739667396773968739697397073971739727397373974739757397673977739787397973980739817398273983739847398573986739877398873989739907399173992739937399473995739967399773998739997400074001740027400374004740057400674007740087400974010740117401274013740147401574016740177401874019740207402174022740237402474025740267402774028740297403074031740327403374034740357403674037740387403974040740417404274043740447404574046740477404874049740507405174052740537405474055740567405774058740597406074061740627406374064740657406674067740687406974070740717407274073740747407574076740777407874079740807408174082740837408474085740867408774088740897409074091740927409374094740957409674097740987409974100741017410274103741047410574106741077410874109741107411174112741137411474115741167411774118741197412074121741227412374124741257412674127741287412974130741317413274133741347413574136741377413874139741407414174142741437414474145741467414774148741497415074151741527415374154741557415674157741587415974160741617416274163741647416574166741677416874169741707417174172741737417474175741767417774178741797418074181741827418374184741857418674187741887418974190741917419274193741947419574196741977419874199742007420174202742037420474205742067420774208742097421074211742127421374214742157421674217742187421974220742217422274223742247422574226742277422874229742307423174232742337423474235742367423774238742397424074241742427424374244742457424674247742487424974250742517425274253742547425574256742577425874259742607426174262742637426474265742667426774268742697427074271742727427374274742757427674277742787427974280742817428274283742847428574286742877428874289742907429174292742937429474295742967429774298742997430074301743027430374304743057430674307743087430974310743117431274313743147431574316743177431874319743207432174322743237432474325743267432774328743297433074331743327433374334743357433674337743387433974340743417434274343743447434574346743477434874349743507435174352743537435474355743567435774358743597436074361743627436374364743657436674367743687436974370743717437274373743747437574376743777437874379743807438174382743837438474385743867438774388743897439074391743927439374394743957439674397743987439974400744017440274403744047440574406744077440874409744107441174412744137441474415744167441774418744197442074421744227442374424744257442674427744287442974430744317443274433744347443574436744377443874439744407444174442744437444474445744467444774448744497445074451744527445374454744557445674457744587445974460744617446274463744647446574466744677446874469744707447174472744737447474475744767447774478744797448074481744827448374484744857448674487744887448974490744917449274493744947449574496744977449874499745007450174502745037450474505745067450774508745097451074511745127451374514745157451674517745187451974520745217452274523745247452574526745277452874529745307453174532745337453474535745367453774538745397454074541745427454374544745457454674547745487454974550745517455274553745547455574556745577455874559745607456174562745637456474565745667456774568745697457074571745727457374574745757457674577745787457974580745817458274583745847458574586745877458874589745907459174592745937459474595745967459774598745997460074601746027460374604746057460674607746087460974610746117461274613746147461574616746177461874619746207462174622746237462474625746267462774628746297463074631746327463374634746357463674637746387463974640746417464274643746447464574646746477464874649746507465174652746537465474655746567465774658746597466074661746627466374664746657466674667746687466974670746717467274673746747467574676746777467874679746807468174682746837468474685746867468774688746897469074691746927469374694746957469674697746987469974700747017470274703747047470574706747077470874709747107471174712747137471474715747167471774718747197472074721747227472374724747257472674727747287472974730747317473274733747347473574736747377473874739747407474174742747437474474745747467474774748747497475074751747527475374754747557475674757747587475974760747617476274763747647476574766747677476874769747707477174772747737477474775747767477774778747797478074781747827478374784747857478674787747887478974790747917479274793747947479574796747977479874799748007480174802748037480474805748067480774808748097481074811748127481374814748157481674817748187481974820748217482274823748247482574826748277482874829748307483174832748337483474835748367483774838748397484074841748427484374844748457484674847748487484974850748517485274853748547485574856748577485874859748607486174862748637486474865748667486774868748697487074871748727487374874748757487674877748787487974880748817488274883748847488574886748877488874889748907489174892748937489474895748967489774898748997490074901749027490374904749057490674907749087490974910749117491274913749147491574916749177491874919749207492174922749237492474925749267492774928749297493074931749327493374934749357493674937749387493974940749417494274943749447494574946749477494874949749507495174952749537495474955749567495774958749597496074961749627496374964749657496674967749687496974970749717497274973749747497574976749777497874979749807498174982749837498474985749867498774988749897499074991749927499374994749957499674997749987499975000750017500275003750047500575006750077500875009750107501175012750137501475015750167501775018750197502075021750227502375024750257502675027750287502975030750317503275033750347503575036750377503875039750407504175042750437504475045750467504775048750497505075051750527505375054750557505675057750587505975060750617506275063750647506575066750677506875069750707507175072750737507475075750767507775078750797508075081750827508375084750857508675087750887508975090750917509275093750947509575096750977509875099751007510175102751037510475105751067510775108751097511075111751127511375114751157511675117751187511975120751217512275123751247512575126751277512875129751307513175132751337513475135751367513775138751397514075141751427514375144751457514675147751487514975150751517515275153751547515575156751577515875159751607516175162751637516475165751667516775168751697517075171751727517375174751757517675177751787517975180751817518275183751847518575186751877518875189751907519175192751937519475195751967519775198751997520075201752027520375204752057520675207752087520975210752117521275213752147521575216752177521875219752207522175222752237522475225752267522775228752297523075231752327523375234752357523675237752387523975240752417524275243752447524575246752477524875249752507525175252752537525475255752567525775258752597526075261752627526375264752657526675267752687526975270752717527275273752747527575276752777527875279752807528175282752837528475285752867528775288752897529075291752927529375294752957529675297752987529975300753017530275303753047530575306753077530875309753107531175312753137531475315753167531775318753197532075321753227532375324753257532675327753287532975330753317533275333753347533575336753377533875339753407534175342753437534475345753467534775348753497535075351753527535375354753557535675357753587535975360753617536275363753647536575366753677536875369753707537175372753737537475375753767537775378753797538075381753827538375384753857538675387753887538975390753917539275393753947539575396753977539875399754007540175402754037540475405754067540775408754097541075411754127541375414754157541675417754187541975420754217542275423754247542575426754277542875429754307543175432754337543475435754367543775438754397544075441754427544375444754457544675447754487544975450754517545275453754547545575456754577545875459754607546175462754637546475465754667546775468754697547075471754727547375474754757547675477754787547975480754817548275483754847548575486754877548875489754907549175492754937549475495754967549775498754997550075501755027550375504755057550675507755087550975510755117551275513755147551575516755177551875519755207552175522755237552475525755267552775528755297553075531755327553375534755357553675537755387553975540755417554275543755447554575546755477554875549755507555175552755537555475555755567555775558755597556075561755627556375564755657556675567755687556975570755717557275573755747557575576755777557875579755807558175582755837558475585755867558775588755897559075591755927559375594755957559675597755987559975600756017560275603756047560575606756077560875609756107561175612756137561475615756167561775618756197562075621756227562375624756257562675627756287562975630756317563275633756347563575636756377563875639756407564175642756437564475645756467564775648756497565075651756527565375654756557565675657756587565975660756617566275663756647566575666756677566875669756707567175672756737567475675756767567775678756797568075681756827568375684756857568675687756887568975690756917569275693756947569575696756977569875699757007570175702757037570475705757067570775708757097571075711757127571375714757157571675717757187571975720757217572275723757247572575726757277572875729757307573175732757337573475735757367573775738757397574075741757427574375744757457574675747757487574975750757517575275753757547575575756757577575875759757607576175762757637576475765757667576775768757697577075771757727577375774757757577675777757787577975780757817578275783757847578575786757877578875789757907579175792757937579475795757967579775798757997580075801758027580375804758057580675807758087580975810758117581275813758147581575816758177581875819758207582175822758237582475825758267582775828758297583075831758327583375834758357583675837758387583975840758417584275843758447584575846758477584875849758507585175852758537585475855758567585775858758597586075861758627586375864758657586675867758687586975870758717587275873758747587575876758777587875879758807588175882758837588475885758867588775888758897589075891758927589375894758957589675897758987589975900759017590275903759047590575906759077590875909759107591175912759137591475915759167591775918759197592075921759227592375924759257592675927759287592975930759317593275933759347593575936759377593875939759407594175942759437594475945759467594775948759497595075951759527595375954759557595675957759587595975960759617596275963759647596575966759677596875969759707597175972759737597475975759767597775978759797598075981759827598375984759857598675987759887598975990759917599275993759947599575996759977599875999760007600176002760037600476005760067600776008760097601076011760127601376014760157601676017760187601976020760217602276023760247602576026760277602876029760307603176032760337603476035760367603776038760397604076041760427604376044760457604676047760487604976050760517605276053760547605576056760577605876059760607606176062760637606476065760667606776068760697607076071760727607376074760757607676077760787607976080760817608276083760847608576086760877608876089760907609176092760937609476095760967609776098760997610076101761027610376104761057610676107761087610976110761117611276113761147611576116761177611876119761207612176122761237612476125761267612776128761297613076131761327613376134761357613676137761387613976140761417614276143761447614576146761477614876149761507615176152761537615476155761567615776158761597616076161761627616376164761657616676167761687616976170761717617276173761747617576176761777617876179761807618176182761837618476185761867618776188761897619076191761927619376194761957619676197761987619976200762017620276203762047620576206762077620876209762107621176212762137621476215762167621776218762197622076221762227622376224762257622676227762287622976230762317623276233762347623576236762377623876239762407624176242762437624476245762467624776248762497625076251762527625376254762557625676257762587625976260762617626276263762647626576266762677626876269762707627176272762737627476275762767627776278762797628076281762827628376284762857628676287762887628976290762917629276293762947629576296762977629876299763007630176302763037630476305763067630776308763097631076311763127631376314763157631676317763187631976320763217632276323763247632576326763277632876329763307633176332763337633476335763367633776338763397634076341763427634376344763457634676347763487634976350763517635276353763547635576356763577635876359763607636176362763637636476365763667636776368763697637076371763727637376374763757637676377763787637976380763817638276383763847638576386763877638876389763907639176392763937639476395763967639776398763997640076401764027640376404764057640676407764087640976410764117641276413764147641576416764177641876419764207642176422764237642476425764267642776428764297643076431764327643376434764357643676437764387643976440764417644276443764447644576446764477644876449764507645176452764537645476455764567645776458764597646076461764627646376464764657646676467764687646976470764717647276473764747647576476764777647876479764807648176482764837648476485764867648776488764897649076491764927649376494764957649676497764987649976500765017650276503765047650576506765077650876509765107651176512765137651476515765167651776518765197652076521765227652376524765257652676527765287652976530765317653276533765347653576536765377653876539765407654176542765437654476545765467654776548765497655076551765527655376554765557655676557765587655976560765617656276563765647656576566765677656876569765707657176572765737657476575765767657776578765797658076581765827658376584765857658676587765887658976590765917659276593765947659576596765977659876599766007660176602766037660476605766067660776608766097661076611766127661376614766157661676617766187661976620766217662276623766247662576626766277662876629766307663176632766337663476635766367663776638766397664076641766427664376644766457664676647766487664976650766517665276653766547665576656766577665876659766607666176662766637666476665766667666776668766697667076671766727667376674766757667676677766787667976680766817668276683766847668576686766877668876689766907669176692766937669476695766967669776698766997670076701767027670376704767057670676707767087670976710767117671276713767147671576716767177671876719767207672176722767237672476725767267672776728767297673076731767327673376734767357673676737767387673976740767417674276743767447674576746767477674876749767507675176752767537675476755767567675776758767597676076761767627676376764767657676676767767687676976770767717677276773767747677576776767777677876779767807678176782767837678476785767867678776788767897679076791767927679376794767957679676797767987679976800768017680276803768047680576806768077680876809768107681176812768137681476815768167681776818768197682076821768227682376824768257682676827768287682976830768317683276833768347683576836768377683876839768407684176842768437684476845768467684776848768497685076851768527685376854768557685676857768587685976860768617686276863768647686576866768677686876869768707687176872768737687476875768767687776878768797688076881768827688376884768857688676887768887688976890768917689276893768947689576896768977689876899769007690176902769037690476905769067690776908769097691076911769127691376914769157691676917769187691976920769217692276923769247692576926769277692876929769307693176932769337693476935769367693776938769397694076941769427694376944769457694676947769487694976950769517695276953769547695576956769577695876959769607696176962769637696476965769667696776968769697697076971769727697376974769757697676977769787697976980769817698276983769847698576986769877698876989769907699176992769937699476995769967699776998769997700077001770027700377004770057700677007770087700977010770117701277013770147701577016770177701877019770207702177022770237702477025770267702777028770297703077031770327703377034770357703677037770387703977040770417704277043770447704577046770477704877049770507705177052770537705477055770567705777058770597706077061770627706377064770657706677067770687706977070770717707277073770747707577076770777707877079770807708177082770837708477085770867708777088770897709077091770927709377094770957709677097770987709977100771017710277103771047710577106771077710877109771107711177112771137711477115771167711777118771197712077121771227712377124771257712677127771287712977130771317713277133771347713577136771377713877139771407714177142771437714477145771467714777148771497715077151771527715377154771557715677157771587715977160771617716277163771647716577166771677716877169771707717177172771737717477175771767717777178771797718077181771827718377184771857718677187771887718977190771917719277193771947719577196771977719877199772007720177202772037720477205772067720777208772097721077211772127721377214772157721677217772187721977220772217722277223772247722577226772277722877229772307723177232772337723477235772367723777238772397724077241772427724377244772457724677247772487724977250772517725277253772547725577256772577725877259772607726177262772637726477265772667726777268772697727077271772727727377274772757727677277772787727977280772817728277283772847728577286772877728877289772907729177292772937729477295772967729777298772997730077301773027730377304773057730677307773087730977310773117731277313773147731577316773177731877319773207732177322773237732477325773267732777328773297733077331773327733377334773357733677337773387733977340773417734277343773447734577346773477734877349773507735177352773537735477355773567735777358773597736077361773627736377364773657736677367773687736977370773717737277373773747737577376773777737877379773807738177382773837738477385773867738777388773897739077391773927739377394773957739677397773987739977400774017740277403774047740577406774077740877409774107741177412774137741477415774167741777418774197742077421774227742377424774257742677427774287742977430774317743277433774347743577436774377743877439774407744177442774437744477445774467744777448774497745077451774527745377454774557745677457774587745977460774617746277463774647746577466774677746877469774707747177472774737747477475774767747777478774797748077481774827748377484774857748677487774887748977490774917749277493774947749577496774977749877499775007750177502775037750477505775067750777508775097751077511775127751377514775157751677517775187751977520775217752277523775247752577526775277752877529775307753177532775337753477535775367753777538775397754077541775427754377544775457754677547775487754977550775517755277553775547755577556775577755877559775607756177562775637756477565775667756777568775697757077571775727757377574775757757677577775787757977580775817758277583775847758577586775877758877589775907759177592775937759477595775967759777598775997760077601776027760377604776057760677607776087760977610776117761277613776147761577616776177761877619776207762177622776237762477625776267762777628776297763077631776327763377634776357763677637776387763977640776417764277643776447764577646776477764877649776507765177652776537765477655776567765777658776597766077661776627766377664776657766677667776687766977670776717767277673776747767577676776777767877679776807768177682776837768477685776867768777688776897769077691776927769377694776957769677697776987769977700777017770277703777047770577706777077770877709777107771177712777137771477715777167771777718777197772077721777227772377724777257772677727777287772977730777317773277733777347773577736777377773877739777407774177742777437774477745777467774777748777497775077751777527775377754777557775677757777587775977760777617776277763777647776577766777677776877769777707777177772777737777477775777767777777778777797778077781777827778377784777857778677787777887778977790777917779277793777947779577796777977779877799778007780177802778037780477805778067780777808778097781077811778127781377814778157781677817778187781977820778217782277823778247782577826778277782877829778307783177832778337783477835778367783777838778397784077841778427784377844778457784677847778487784977850778517785277853778547785577856778577785877859778607786177862778637786477865778667786777868778697787077871778727787377874778757787677877778787787977880778817788277883778847788577886778877788877889778907789177892778937789477895778967789777898778997790077901779027790377904779057790677907779087790977910779117791277913779147791577916779177791877919779207792177922779237792477925779267792777928779297793077931779327793377934779357793677937779387793977940779417794277943779447794577946779477794877949779507795177952779537795477955779567795777958779597796077961779627796377964779657796677967779687796977970779717797277973779747797577976779777797877979779807798177982779837798477985779867798777988779897799077991779927799377994779957799677997779987799978000780017800278003780047800578006780077800878009780107801178012780137801478015780167801778018780197802078021780227802378024780257802678027780287802978030780317803278033780347803578036780377803878039780407804178042780437804478045780467804778048780497805078051780527805378054780557805678057780587805978060780617806278063780647806578066780677806878069780707807178072780737807478075780767807778078780797808078081780827808378084780857808678087780887808978090780917809278093780947809578096780977809878099781007810178102781037810478105781067810778108781097811078111781127811378114781157811678117781187811978120781217812278123781247812578126781277812878129781307813178132781337813478135781367813778138781397814078141781427814378144781457814678147781487814978150781517815278153781547815578156781577815878159781607816178162781637816478165781667816778168781697817078171781727817378174781757817678177781787817978180781817818278183781847818578186781877818878189781907819178192781937819478195781967819778198781997820078201782027820378204782057820678207782087820978210782117821278213782147821578216782177821878219782207822178222782237822478225782267822778228782297823078231782327823378234782357823678237782387823978240782417824278243782447824578246782477824878249782507825178252782537825478255782567825778258782597826078261782627826378264782657826678267782687826978270782717827278273782747827578276782777827878279782807828178282782837828478285782867828778288782897829078291782927829378294782957829678297782987829978300783017830278303783047830578306783077830878309783107831178312783137831478315783167831778318783197832078321783227832378324783257832678327783287832978330783317833278333783347833578336783377833878339783407834178342783437834478345783467834778348783497835078351783527835378354783557835678357783587835978360783617836278363783647836578366783677836878369783707837178372783737837478375783767837778378783797838078381783827838378384783857838678387783887838978390783917839278393783947839578396783977839878399784007840178402784037840478405784067840778408784097841078411784127841378414784157841678417784187841978420784217842278423784247842578426784277842878429784307843178432784337843478435784367843778438784397844078441784427844378444784457844678447784487844978450784517845278453784547845578456784577845878459784607846178462784637846478465784667846778468784697847078471784727847378474784757847678477784787847978480784817848278483784847848578486784877848878489784907849178492784937849478495784967849778498784997850078501785027850378504785057850678507785087850978510785117851278513785147851578516785177851878519785207852178522785237852478525785267852778528785297853078531785327853378534785357853678537785387853978540785417854278543785447854578546785477854878549785507855178552785537855478555785567855778558785597856078561785627856378564785657856678567785687856978570785717857278573785747857578576785777857878579785807858178582785837858478585785867858778588785897859078591785927859378594785957859678597785987859978600786017860278603786047860578606786077860878609786107861178612786137861478615786167861778618786197862078621786227862378624786257862678627786287862978630786317863278633786347863578636786377863878639786407864178642786437864478645786467864778648786497865078651786527865378654786557865678657786587865978660786617866278663786647866578666786677866878669786707867178672786737867478675786767867778678786797868078681786827868378684786857868678687786887868978690786917869278693786947869578696786977869878699787007870178702787037870478705787067870778708787097871078711787127871378714787157871678717787187871978720787217872278723787247872578726787277872878729787307873178732787337873478735787367873778738787397874078741787427874378744787457874678747787487874978750787517875278753787547875578756787577875878759787607876178762787637876478765787667876778768787697877078771787727877378774787757877678777787787877978780787817878278783787847878578786787877878878789787907879178792787937879478795787967879778798787997880078801788027880378804788057880678807788087880978810788117881278813788147881578816788177881878819788207882178822788237882478825788267882778828788297883078831788327883378834788357883678837788387883978840788417884278843788447884578846788477884878849788507885178852788537885478855788567885778858788597886078861788627886378864788657886678867788687886978870788717887278873788747887578876788777887878879788807888178882788837888478885788867888778888788897889078891788927889378894788957889678897788987889978900789017890278903789047890578906789077890878909789107891178912789137891478915789167891778918789197892078921789227892378924789257892678927789287892978930789317893278933789347893578936789377893878939789407894178942789437894478945789467894778948789497895078951789527895378954789557895678957789587895978960789617896278963789647896578966789677896878969789707897178972789737897478975789767897778978789797898078981789827898378984789857898678987789887898978990789917899278993789947899578996789977899878999790007900179002790037900479005790067900779008790097901079011790127901379014790157901679017790187901979020790217902279023790247902579026790277902879029790307903179032790337903479035790367903779038790397904079041790427904379044790457904679047790487904979050790517905279053790547905579056790577905879059790607906179062790637906479065790667906779068790697907079071790727907379074790757907679077790787907979080790817908279083790847908579086790877908879089790907909179092790937909479095790967909779098790997910079101791027910379104791057910679107791087910979110791117911279113791147911579116791177911879119791207912179122791237912479125791267912779128791297913079131791327913379134791357913679137791387913979140791417914279143791447914579146791477914879149791507915179152791537915479155791567915779158791597916079161791627916379164791657916679167791687916979170791717917279173791747917579176791777917879179791807918179182791837918479185791867918779188791897919079191791927919379194791957919679197791987919979200792017920279203792047920579206792077920879209792107921179212792137921479215792167921779218792197922079221792227922379224792257922679227792287922979230792317923279233792347923579236792377923879239792407924179242792437924479245792467924779248792497925079251792527925379254792557925679257792587925979260792617926279263792647926579266792677926879269792707927179272792737927479275792767927779278792797928079281792827928379284792857928679287792887928979290792917929279293792947929579296792977929879299793007930179302793037930479305793067930779308793097931079311793127931379314793157931679317793187931979320793217932279323793247932579326793277932879329793307933179332793337933479335793367933779338793397934079341793427934379344793457934679347793487934979350793517935279353793547935579356793577935879359793607936179362793637936479365793667936779368793697937079371793727937379374793757937679377793787937979380793817938279383793847938579386793877938879389793907939179392793937939479395793967939779398793997940079401794027940379404794057940679407794087940979410794117941279413794147941579416794177941879419794207942179422794237942479425794267942779428794297943079431794327943379434794357943679437794387943979440794417944279443794447944579446794477944879449794507945179452794537945479455794567945779458794597946079461794627946379464794657946679467794687946979470794717947279473794747947579476794777947879479794807948179482794837948479485794867948779488794897949079491794927949379494794957949679497794987949979500795017950279503795047950579506795077950879509795107951179512795137951479515795167951779518795197952079521795227952379524795257952679527795287952979530795317953279533795347953579536795377953879539795407954179542795437954479545795467954779548795497955079551795527955379554795557955679557795587955979560795617956279563795647956579566795677956879569795707957179572795737957479575795767957779578795797958079581795827958379584795857958679587795887958979590795917959279593795947959579596795977959879599796007960179602796037960479605796067960779608796097961079611796127961379614796157961679617796187961979620796217962279623796247962579626796277962879629796307963179632796337963479635796367963779638796397964079641796427964379644796457964679647796487964979650796517965279653796547965579656796577965879659796607966179662796637966479665796667966779668796697967079671796727967379674796757967679677796787967979680796817968279683796847968579686796877968879689796907969179692796937969479695796967969779698796997970079701797027970379704797057970679707797087970979710797117971279713797147971579716797177971879719797207972179722797237972479725797267972779728797297973079731797327973379734797357973679737797387973979740797417974279743797447974579746797477974879749797507975179752797537975479755797567975779758797597976079761797627976379764797657976679767797687976979770797717977279773797747977579776797777977879779797807978179782797837978479785797867978779788797897979079791797927979379794797957979679797797987979979800798017980279803798047980579806798077980879809798107981179812798137981479815798167981779818798197982079821798227982379824798257982679827798287982979830798317983279833798347983579836798377983879839798407984179842798437984479845798467984779848798497985079851798527985379854798557985679857798587985979860798617986279863798647986579866798677986879869798707987179872798737987479875798767987779878798797988079881798827988379884798857988679887798887988979890798917989279893798947989579896798977989879899799007990179902799037990479905799067990779908799097991079911799127991379914799157991679917799187991979920799217992279923799247992579926799277992879929799307993179932799337993479935799367993779938799397994079941799427994379944799457994679947799487994979950799517995279953799547995579956799577995879959799607996179962799637996479965799667996779968799697997079971799727997379974799757997679977799787997979980799817998279983799847998579986799877998879989799907999179992799937999479995799967999779998799998000080001800028000380004800058000680007800088000980010800118001280013800148001580016800178001880019800208002180022800238002480025800268002780028800298003080031800328003380034800358003680037800388003980040800418004280043800448004580046800478004880049800508005180052800538005480055800568005780058800598006080061800628006380064800658006680067800688006980070800718007280073800748007580076800778007880079800808008180082800838008480085800868008780088800898009080091800928009380094800958009680097800988009980100801018010280103801048010580106801078010880109801108011180112801138011480115801168011780118801198012080121801228012380124801258012680127801288012980130801318013280133801348013580136801378013880139801408014180142801438014480145801468014780148801498015080151801528015380154801558015680157801588015980160801618016280163801648016580166801678016880169801708017180172801738017480175801768017780178801798018080181801828018380184801858018680187801888018980190801918019280193801948019580196801978019880199802008020180202802038020480205802068020780208802098021080211802128021380214802158021680217802188021980220802218022280223802248022580226802278022880229802308023180232802338023480235802368023780238802398024080241802428024380244802458024680247802488024980250802518025280253802548025580256802578025880259802608026180262802638026480265802668026780268802698027080271802728027380274802758027680277802788027980280802818028280283802848028580286802878028880289802908029180292802938029480295802968029780298802998030080301803028030380304803058030680307803088030980310803118031280313803148031580316803178031880319803208032180322803238032480325803268032780328803298033080331803328033380334803358033680337803388033980340803418034280343803448034580346803478034880349803508035180352803538035480355803568035780358803598036080361803628036380364803658036680367803688036980370803718037280373803748037580376803778037880379803808038180382803838038480385803868038780388803898039080391803928039380394803958039680397803988039980400804018040280403804048040580406804078040880409804108041180412804138041480415804168041780418804198042080421804228042380424804258042680427804288042980430804318043280433804348043580436804378043880439804408044180442804438044480445804468044780448804498045080451804528045380454804558045680457804588045980460804618046280463804648046580466804678046880469804708047180472804738047480475804768047780478804798048080481804828048380484804858048680487804888048980490804918049280493804948049580496804978049880499805008050180502805038050480505805068050780508805098051080511805128051380514805158051680517805188051980520805218052280523805248052580526805278052880529805308053180532805338053480535805368053780538805398054080541805428054380544805458054680547805488054980550805518055280553805548055580556805578055880559805608056180562805638056480565805668056780568805698057080571805728057380574805758057680577805788057980580805818058280583805848058580586805878058880589805908059180592805938059480595805968059780598805998060080601806028060380604806058060680607806088060980610806118061280613806148061580616806178061880619806208062180622806238062480625806268062780628806298063080631806328063380634806358063680637806388063980640806418064280643806448064580646806478064880649806508065180652806538065480655806568065780658806598066080661806628066380664806658066680667806688066980670806718067280673806748067580676806778067880679806808068180682806838068480685806868068780688806898069080691806928069380694806958069680697806988069980700807018070280703807048070580706807078070880709807108071180712807138071480715807168071780718807198072080721807228072380724807258072680727807288072980730807318073280733807348073580736807378073880739807408074180742807438074480745807468074780748807498075080751807528075380754807558075680757807588075980760807618076280763807648076580766807678076880769807708077180772807738077480775807768077780778807798078080781807828078380784807858078680787807888078980790807918079280793807948079580796807978079880799808008080180802808038080480805808068080780808808098081080811808128081380814808158081680817808188081980820808218082280823808248082580826808278082880829808308083180832808338083480835808368083780838808398084080841808428084380844808458084680847808488084980850808518085280853808548085580856808578085880859808608086180862808638086480865808668086780868808698087080871808728087380874808758087680877808788087980880808818088280883808848088580886808878088880889808908089180892808938089480895808968089780898808998090080901809028090380904809058090680907809088090980910809118091280913809148091580916809178091880919809208092180922809238092480925809268092780928809298093080931809328093380934809358093680937809388093980940809418094280943809448094580946809478094880949809508095180952809538095480955809568095780958809598096080961809628096380964809658096680967809688096980970809718097280973809748097580976809778097880979809808098180982809838098480985809868098780988809898099080991809928099380994809958099680997809988099981000810018100281003810048100581006810078100881009810108101181012810138101481015810168101781018810198102081021810228102381024810258102681027810288102981030810318103281033810348103581036810378103881039810408104181042810438104481045810468104781048810498105081051810528105381054810558105681057810588105981060810618106281063810648106581066810678106881069810708107181072810738107481075810768107781078810798108081081810828108381084810858108681087810888108981090810918109281093810948109581096810978109881099811008110181102811038110481105811068110781108811098111081111811128111381114811158111681117811188111981120811218112281123811248112581126811278112881129811308113181132811338113481135811368113781138811398114081141811428114381144811458114681147811488114981150811518115281153811548115581156811578115881159811608116181162811638116481165811668116781168811698117081171811728117381174811758117681177811788117981180811818118281183811848118581186811878118881189811908119181192811938119481195811968119781198811998120081201812028120381204812058120681207812088120981210812118121281213812148121581216812178121881219812208122181222812238122481225812268122781228812298123081231812328123381234812358123681237812388123981240812418124281243812448124581246812478124881249812508125181252812538125481255812568125781258812598126081261812628126381264812658126681267812688126981270812718127281273812748127581276812778127881279812808128181282812838128481285812868128781288812898129081291812928129381294812958129681297812988129981300813018130281303813048130581306813078130881309813108131181312813138131481315813168131781318813198132081321813228132381324813258132681327813288132981330813318133281333813348133581336813378133881339813408134181342813438134481345813468134781348813498135081351813528135381354813558135681357813588135981360813618136281363813648136581366813678136881369813708137181372813738137481375813768137781378813798138081381813828138381384813858138681387813888138981390813918139281393813948139581396813978139881399814008140181402814038140481405814068140781408814098141081411814128141381414814158141681417814188141981420814218142281423814248142581426814278142881429814308143181432814338143481435814368143781438814398144081441814428144381444814458144681447814488144981450814518145281453814548145581456814578145881459814608146181462814638146481465814668146781468814698147081471814728147381474814758147681477814788147981480814818148281483814848148581486814878148881489814908149181492814938149481495814968149781498814998150081501815028150381504815058150681507815088150981510815118151281513815148151581516815178151881519815208152181522815238152481525815268152781528815298153081531815328153381534815358153681537815388153981540815418154281543815448154581546815478154881549815508155181552815538155481555815568155781558815598156081561815628156381564815658156681567815688156981570815718157281573815748157581576815778157881579815808158181582815838158481585815868158781588815898159081591815928159381594815958159681597815988159981600816018160281603816048160581606816078160881609816108161181612816138161481615816168161781618816198162081621816228162381624816258162681627816288162981630816318163281633816348163581636816378163881639816408164181642816438164481645816468164781648816498165081651816528165381654816558165681657816588165981660816618166281663816648166581666816678166881669816708167181672816738167481675816768167781678816798168081681816828168381684816858168681687816888168981690816918169281693816948169581696816978169881699817008170181702817038170481705817068170781708817098171081711817128171381714817158171681717817188171981720817218172281723817248172581726817278172881729817308173181732817338173481735817368173781738817398174081741817428174381744817458174681747817488174981750817518175281753817548175581756817578175881759817608176181762817638176481765817668176781768817698177081771817728177381774817758177681777817788177981780817818178281783817848178581786817878178881789817908179181792817938179481795817968179781798817998180081801818028180381804818058180681807818088180981810818118181281813818148181581816818178181881819818208182181822818238182481825818268182781828818298183081831818328183381834818358183681837818388183981840818418184281843818448184581846818478184881849818508185181852818538185481855818568185781858818598186081861818628186381864818658186681867818688186981870818718187281873818748187581876818778187881879818808188181882818838188481885818868188781888818898189081891818928189381894818958189681897818988189981900819018190281903819048190581906819078190881909819108191181912819138191481915819168191781918819198192081921819228192381924819258192681927819288192981930819318193281933819348193581936819378193881939819408194181942819438194481945819468194781948819498195081951819528195381954819558195681957819588195981960819618196281963819648196581966819678196881969819708197181972819738197481975819768197781978819798198081981819828198381984819858198681987819888198981990819918199281993819948199581996819978199881999820008200182002820038200482005820068200782008820098201082011820128201382014820158201682017820188201982020820218202282023820248202582026820278202882029820308203182032820338203482035820368203782038820398204082041820428204382044820458204682047820488204982050820518205282053820548205582056820578205882059820608206182062820638206482065820668206782068820698207082071820728207382074820758207682077820788207982080820818208282083820848208582086820878208882089820908209182092820938209482095820968209782098820998210082101821028210382104821058210682107821088210982110821118211282113821148211582116821178211882119821208212182122821238212482125821268212782128821298213082131821328213382134821358213682137821388213982140821418214282143821448214582146821478214882149821508215182152821538215482155821568215782158821598216082161821628216382164821658216682167821688216982170821718217282173821748217582176821778217882179821808218182182821838218482185821868218782188821898219082191821928219382194821958219682197821988219982200822018220282203822048220582206822078220882209822108221182212822138221482215822168221782218822198222082221822228222382224822258222682227822288222982230822318223282233822348223582236822378223882239822408224182242822438224482245822468224782248822498225082251822528225382254822558225682257822588225982260822618226282263822648226582266822678226882269822708227182272822738227482275822768227782278822798228082281822828228382284822858228682287822888228982290822918229282293822948229582296822978229882299823008230182302823038230482305823068230782308823098231082311823128231382314823158231682317823188231982320823218232282323823248232582326823278232882329823308233182332823338233482335823368233782338823398234082341823428234382344823458234682347823488234982350823518235282353823548235582356823578235882359823608236182362823638236482365823668236782368823698237082371823728237382374823758237682377823788237982380823818238282383823848238582386823878238882389823908239182392823938239482395823968239782398823998240082401824028240382404824058240682407824088240982410824118241282413824148241582416824178241882419824208242182422824238242482425824268242782428824298243082431824328243382434824358243682437824388243982440824418244282443824448244582446824478244882449824508245182452824538245482455824568245782458824598246082461824628246382464824658246682467824688246982470824718247282473824748247582476824778247882479824808248182482824838248482485824868248782488824898249082491824928249382494824958249682497824988249982500825018250282503825048250582506825078250882509825108251182512825138251482515825168251782518825198252082521825228252382524825258252682527825288252982530825318253282533825348253582536825378253882539825408254182542825438254482545825468254782548825498255082551825528255382554825558255682557825588255982560825618256282563825648256582566825678256882569825708257182572825738257482575825768257782578825798258082581825828258382584825858258682587825888258982590825918259282593825948259582596825978259882599826008260182602826038260482605826068260782608826098261082611826128261382614826158261682617826188261982620826218262282623826248262582626826278262882629826308263182632826338263482635826368263782638826398264082641826428264382644826458264682647826488264982650826518265282653826548265582656826578265882659826608266182662826638266482665826668266782668826698267082671826728267382674826758267682677826788267982680826818268282683826848268582686826878268882689826908269182692826938269482695826968269782698826998270082701827028270382704827058270682707827088270982710827118271282713827148271582716827178271882719827208272182722827238272482725827268272782728827298273082731827328273382734827358273682737827388273982740827418274282743827448274582746827478274882749827508275182752827538275482755827568275782758827598276082761827628276382764827658276682767827688276982770827718277282773827748277582776827778277882779827808278182782827838278482785827868278782788827898279082791827928279382794827958279682797827988279982800828018280282803828048280582806828078280882809828108281182812828138281482815828168281782818828198282082821828228282382824828258282682827828288282982830828318283282833828348283582836828378283882839828408284182842828438284482845828468284782848828498285082851828528285382854828558285682857828588285982860828618286282863828648286582866828678286882869828708287182872828738287482875828768287782878828798288082881828828288382884828858288682887828888288982890828918289282893828948289582896828978289882899829008290182902829038290482905829068290782908829098291082911829128291382914829158291682917829188291982920829218292282923829248292582926829278292882929829308293182932829338293482935829368293782938829398294082941829428294382944829458294682947829488294982950829518295282953829548295582956829578295882959829608296182962829638296482965829668296782968829698297082971829728297382974829758297682977829788297982980829818298282983829848298582986829878298882989829908299182992829938299482995829968299782998829998300083001830028300383004830058300683007830088300983010830118301283013830148301583016830178301883019830208302183022830238302483025830268302783028830298303083031830328303383034830358303683037830388303983040830418304283043830448304583046830478304883049830508305183052830538305483055830568305783058830598306083061830628306383064830658306683067830688306983070830718307283073830748307583076830778307883079830808308183082830838308483085830868308783088830898309083091830928309383094830958309683097830988309983100831018310283103831048310583106831078310883109831108311183112831138311483115831168311783118831198312083121831228312383124831258312683127831288312983130831318313283133831348313583136831378313883139831408314183142831438314483145831468314783148831498315083151831528315383154831558315683157831588315983160831618316283163831648316583166831678316883169831708317183172831738317483175831768317783178831798318083181831828318383184831858318683187831888318983190831918319283193831948319583196831978319883199832008320183202832038320483205832068320783208832098321083211832128321383214832158321683217832188321983220832218322283223832248322583226832278322883229832308323183232832338323483235832368323783238832398324083241832428324383244832458324683247832488324983250832518325283253832548325583256832578325883259832608326183262832638326483265832668326783268832698327083271832728327383274832758327683277832788327983280832818328283283832848328583286832878328883289832908329183292832938329483295832968329783298832998330083301833028330383304833058330683307833088330983310833118331283313833148331583316833178331883319833208332183322833238332483325833268332783328833298333083331833328333383334833358333683337833388333983340833418334283343833448334583346833478334883349833508335183352833538335483355833568335783358833598336083361833628336383364833658336683367833688336983370833718337283373833748337583376833778337883379833808338183382833838338483385833868338783388833898339083391833928339383394833958339683397833988339983400834018340283403834048340583406834078340883409834108341183412834138341483415834168341783418834198342083421834228342383424834258342683427834288342983430834318343283433834348343583436834378343883439834408344183442834438344483445834468344783448834498345083451834528345383454834558345683457834588345983460834618346283463834648346583466834678346883469834708347183472834738347483475834768347783478834798348083481834828348383484834858348683487834888348983490834918349283493834948349583496834978349883499835008350183502835038350483505835068350783508835098351083511835128351383514835158351683517835188351983520835218352283523835248352583526835278352883529835308353183532835338353483535835368353783538835398354083541835428354383544835458354683547835488354983550835518355283553835548355583556835578355883559835608356183562835638356483565835668356783568835698357083571835728357383574835758357683577835788357983580835818358283583835848358583586835878358883589835908359183592835938359483595835968359783598835998360083601836028360383604836058360683607836088360983610836118361283613836148361583616836178361883619836208362183622836238362483625836268362783628836298363083631836328363383634836358363683637836388363983640836418364283643836448364583646836478364883649836508365183652836538365483655836568365783658836598366083661836628366383664836658366683667836688366983670836718367283673836748367583676836778367883679836808368183682836838368483685836868368783688836898369083691836928369383694836958369683697836988369983700837018370283703837048370583706837078370883709837108371183712837138371483715837168371783718837198372083721837228372383724837258372683727837288372983730837318373283733837348373583736837378373883739837408374183742837438374483745837468374783748837498375083751837528375383754837558375683757837588375983760837618376283763837648376583766837678376883769837708377183772837738377483775837768377783778837798378083781837828378383784837858378683787837888378983790837918379283793837948379583796837978379883799838008380183802838038380483805838068380783808838098381083811838128381383814838158381683817838188381983820838218382283823838248382583826838278382883829838308383183832838338383483835838368383783838838398384083841838428384383844838458384683847838488384983850838518385283853838548385583856838578385883859838608386183862838638386483865838668386783868838698387083871838728387383874838758387683877838788387983880838818388283883838848388583886838878388883889838908389183892838938389483895838968389783898838998390083901839028390383904839058390683907839088390983910839118391283913839148391583916839178391883919839208392183922839238392483925839268392783928839298393083931839328393383934839358393683937839388393983940839418394283943839448394583946839478394883949839508395183952839538395483955839568395783958839598396083961839628396383964839658396683967839688396983970839718397283973839748397583976839778397883979839808398183982839838398483985839868398783988839898399083991839928399383994839958399683997839988399984000840018400284003840048400584006840078400884009840108401184012840138401484015840168401784018840198402084021840228402384024840258402684027840288402984030840318403284033840348403584036840378403884039840408404184042840438404484045840468404784048840498405084051840528405384054840558405684057840588405984060840618406284063840648406584066840678406884069840708407184072840738407484075840768407784078840798408084081840828408384084840858408684087840888408984090840918409284093840948409584096840978409884099841008410184102841038410484105841068410784108841098411084111841128411384114841158411684117841188411984120841218412284123841248412584126841278412884129841308413184132841338413484135841368413784138841398414084141841428414384144841458414684147841488414984150841518415284153841548415584156841578415884159841608416184162841638416484165841668416784168841698417084171841728417384174841758417684177841788417984180841818418284183841848418584186841878418884189841908419184192841938419484195841968419784198841998420084201842028420384204842058420684207842088420984210842118421284213842148421584216842178421884219842208422184222842238422484225842268422784228842298423084231842328423384234842358423684237842388423984240842418424284243842448424584246842478424884249842508425184252842538425484255842568425784258842598426084261842628426384264842658426684267842688426984270842718427284273842748427584276842778427884279842808428184282842838428484285842868428784288842898429084291842928429384294842958429684297842988429984300843018430284303843048430584306843078430884309843108431184312843138431484315843168431784318843198432084321843228432384324843258432684327843288432984330843318433284333843348433584336843378433884339843408434184342843438434484345843468434784348843498435084351843528435384354843558435684357843588435984360843618436284363843648436584366843678436884369843708437184372843738437484375843768437784378843798438084381843828438384384843858438684387843888438984390843918439284393843948439584396843978439884399844008440184402844038440484405844068440784408844098441084411844128441384414844158441684417844188441984420844218442284423844248442584426844278442884429844308443184432844338443484435844368443784438844398444084441844428444384444844458444684447844488444984450844518445284453844548445584456844578445884459844608446184462844638446484465844668446784468844698447084471844728447384474844758447684477844788447984480844818448284483844848448584486844878448884489844908449184492844938449484495844968449784498844998450084501845028450384504845058450684507845088450984510845118451284513845148451584516845178451884519845208452184522845238452484525845268452784528845298453084531845328453384534845358453684537845388453984540845418454284543845448454584546845478454884549845508455184552845538455484555845568455784558845598456084561845628456384564845658456684567845688456984570845718457284573845748457584576845778457884579845808458184582845838458484585845868458784588845898459084591845928459384594845958459684597845988459984600846018460284603846048460584606846078460884609846108461184612846138461484615846168461784618846198462084621846228462384624846258462684627846288462984630846318463284633846348463584636846378463884639846408464184642846438464484645846468464784648846498465084651846528465384654846558465684657846588465984660846618466284663846648466584666846678466884669846708467184672846738467484675846768467784678846798468084681846828468384684846858468684687846888468984690846918469284693846948469584696846978469884699847008470184702847038470484705847068470784708847098471084711847128471384714847158471684717847188471984720847218472284723847248472584726847278472884729847308473184732847338473484735847368473784738847398474084741847428474384744847458474684747847488474984750847518475284753847548475584756847578475884759847608476184762847638476484765847668476784768847698477084771847728477384774847758477684777847788477984780847818478284783847848478584786847878478884789847908479184792847938479484795847968479784798847998480084801848028480384804848058480684807848088480984810848118481284813848148481584816848178481884819848208482184822848238482484825848268482784828848298483084831848328483384834848358483684837848388483984840848418484284843848448484584846848478484884849848508485184852848538485484855848568485784858848598486084861848628486384864848658486684867848688486984870848718487284873848748487584876848778487884879848808488184882848838488484885848868488784888848898489084891848928489384894848958489684897848988489984900849018490284903849048490584906849078490884909849108491184912849138491484915849168491784918849198492084921849228492384924849258492684927849288492984930849318493284933849348493584936849378493884939849408494184942849438494484945849468494784948849498495084951849528495384954849558495684957849588495984960849618496284963849648496584966849678496884969849708497184972849738497484975849768497784978849798498084981849828498384984849858498684987849888498984990849918499284993849948499584996849978499884999850008500185002850038500485005850068500785008850098501085011850128501385014850158501685017850188501985020850218502285023850248502585026850278502885029850308503185032850338503485035850368503785038850398504085041850428504385044850458504685047850488504985050850518505285053850548505585056850578505885059850608506185062850638506485065850668506785068850698507085071850728507385074850758507685077850788507985080850818508285083850848508585086850878508885089850908509185092850938509485095850968509785098850998510085101851028510385104851058510685107851088510985110851118511285113851148511585116851178511885119851208512185122851238512485125851268512785128851298513085131851328513385134851358513685137851388513985140851418514285143851448514585146851478514885149851508515185152851538515485155851568515785158851598516085161851628516385164851658516685167851688516985170851718517285173851748517585176851778517885179851808518185182851838518485185851868518785188851898519085191851928519385194851958519685197851988519985200852018520285203852048520585206852078520885209852108521185212852138521485215852168521785218852198522085221852228522385224852258522685227852288522985230852318523285233852348523585236852378523885239852408524185242852438524485245852468524785248852498525085251852528525385254852558525685257852588525985260852618526285263852648526585266852678526885269852708527185272852738527485275852768527785278852798528085281852828528385284852858528685287852888528985290852918529285293852948529585296852978529885299853008530185302853038530485305853068530785308853098531085311853128531385314853158531685317853188531985320853218532285323853248532585326853278532885329853308533185332853338533485335853368533785338853398534085341853428534385344853458534685347853488534985350853518535285353853548535585356853578535885359853608536185362853638536485365853668536785368853698537085371853728537385374853758537685377853788537985380853818538285383853848538585386853878538885389853908539185392853938539485395853968539785398853998540085401854028540385404854058540685407854088540985410854118541285413854148541585416854178541885419854208542185422854238542485425854268542785428854298543085431854328543385434854358543685437854388543985440854418544285443854448544585446854478544885449854508545185452854538545485455854568545785458854598546085461854628546385464854658546685467854688546985470854718547285473854748547585476854778547885479854808548185482854838548485485854868548785488854898549085491854928549385494854958549685497854988549985500855018550285503855048550585506855078550885509855108551185512855138551485515855168551785518855198552085521855228552385524855258552685527855288552985530855318553285533855348553585536855378553885539855408554185542855438554485545855468554785548855498555085551855528555385554855558555685557855588555985560855618556285563855648556585566855678556885569855708557185572855738557485575855768557785578855798558085581855828558385584855858558685587855888558985590855918559285593855948559585596855978559885599856008560185602856038560485605856068560785608856098561085611856128561385614856158561685617856188561985620856218562285623856248562585626856278562885629856308563185632856338563485635856368563785638856398564085641856428564385644856458564685647856488564985650856518565285653856548565585656856578565885659856608566185662856638566485665856668566785668856698567085671856728567385674856758567685677856788567985680856818568285683856848568585686856878568885689856908569185692856938569485695856968569785698856998570085701857028570385704857058570685707857088570985710857118571285713857148571585716857178571885719857208572185722857238572485725857268572785728857298573085731857328573385734857358573685737857388573985740857418574285743857448574585746857478574885749857508575185752857538575485755857568575785758857598576085761857628576385764857658576685767857688576985770857718577285773857748577585776857778577885779857808578185782857838578485785857868578785788857898579085791857928579385794857958579685797857988579985800858018580285803858048580585806858078580885809858108581185812858138581485815858168581785818858198582085821858228582385824858258582685827858288582985830858318583285833858348583585836858378583885839858408584185842858438584485845858468584785848858498585085851858528585385854858558585685857858588585985860858618586285863858648586585866858678586885869858708587185872858738587485875858768587785878858798588085881858828588385884858858588685887858888588985890858918589285893858948589585896858978589885899859008590185902859038590485905859068590785908859098591085911859128591385914859158591685917859188591985920859218592285923859248592585926859278592885929859308593185932859338593485935859368593785938859398594085941859428594385944859458594685947859488594985950859518595285953859548595585956859578595885959859608596185962859638596485965859668596785968859698597085971859728597385974859758597685977859788597985980859818598285983859848598585986859878598885989859908599185992859938599485995859968599785998859998600086001860028600386004860058600686007860088600986010860118601286013860148601586016860178601886019860208602186022860238602486025860268602786028860298603086031860328603386034860358603686037860388603986040860418604286043860448604586046860478604886049860508605186052860538605486055860568605786058860598606086061860628606386064860658606686067860688606986070860718607286073860748607586076860778607886079860808608186082860838608486085860868608786088860898609086091860928609386094860958609686097860988609986100861018610286103861048610586106861078610886109861108611186112861138611486115861168611786118861198612086121861228612386124861258612686127861288612986130861318613286133861348613586136861378613886139861408614186142861438614486145861468614786148861498615086151861528615386154861558615686157861588615986160861618616286163861648616586166861678616886169861708617186172861738617486175861768617786178861798618086181861828618386184861858618686187861888618986190861918619286193861948619586196861978619886199862008620186202862038620486205862068620786208862098621086211862128621386214862158621686217862188621986220862218622286223862248622586226862278622886229862308623186232862338623486235862368623786238862398624086241862428624386244862458624686247862488624986250862518625286253862548625586256862578625886259862608626186262862638626486265862668626786268862698627086271862728627386274862758627686277862788627986280862818628286283862848628586286862878628886289862908629186292862938629486295862968629786298862998630086301863028630386304863058630686307863088630986310863118631286313863148631586316863178631886319863208632186322863238632486325863268632786328863298633086331863328633386334863358633686337863388633986340863418634286343863448634586346863478634886349863508635186352863538635486355863568635786358863598636086361863628636386364863658636686367863688636986370863718637286373863748637586376863778637886379863808638186382863838638486385863868638786388863898639086391863928639386394863958639686397863988639986400864018640286403864048640586406864078640886409864108641186412864138641486415864168641786418864198642086421864228642386424864258642686427864288642986430864318643286433864348643586436864378643886439864408644186442864438644486445864468644786448864498645086451864528645386454864558645686457864588645986460864618646286463864648646586466864678646886469864708647186472864738647486475864768647786478864798648086481864828648386484864858648686487864888648986490864918649286493864948649586496864978649886499865008650186502865038650486505865068650786508865098651086511865128651386514865158651686517865188651986520865218652286523865248652586526865278652886529865308653186532865338653486535865368653786538865398654086541865428654386544865458654686547865488654986550865518655286553865548655586556865578655886559865608656186562865638656486565865668656786568865698657086571865728657386574865758657686577865788657986580865818658286583865848658586586865878658886589865908659186592865938659486595865968659786598865998660086601866028660386604866058660686607866088660986610866118661286613866148661586616866178661886619866208662186622866238662486625866268662786628866298663086631866328663386634866358663686637866388663986640866418664286643866448664586646866478664886649866508665186652866538665486655866568665786658866598666086661866628666386664866658666686667866688666986670866718667286673866748667586676866778667886679866808668186682866838668486685866868668786688866898669086691866928669386694866958669686697866988669986700867018670286703867048670586706867078670886709867108671186712867138671486715867168671786718867198672086721867228672386724867258672686727867288672986730867318673286733867348673586736867378673886739867408674186742867438674486745867468674786748867498675086751867528675386754867558675686757867588675986760867618676286763867648676586766867678676886769867708677186772867738677486775867768677786778867798678086781867828678386784867858678686787867888678986790867918679286793867948679586796867978679886799868008680186802868038680486805868068680786808868098681086811868128681386814868158681686817868188681986820868218682286823868248682586826868278682886829868308683186832868338683486835868368683786838868398684086841868428684386844868458684686847868488684986850868518685286853868548685586856868578685886859868608686186862868638686486865868668686786868868698687086871868728687386874868758687686877868788687986880868818688286883868848688586886868878688886889868908689186892868938689486895868968689786898868998690086901869028690386904869058690686907869088690986910869118691286913869148691586916869178691886919869208692186922869238692486925869268692786928869298693086931869328693386934869358693686937869388693986940869418694286943869448694586946869478694886949869508695186952869538695486955869568695786958869598696086961869628696386964869658696686967869688696986970869718697286973869748697586976869778697886979869808698186982869838698486985869868698786988869898699086991869928699386994869958699686997869988699987000870018700287003870048700587006870078700887009870108701187012870138701487015870168701787018870198702087021870228702387024870258702687027870288702987030870318703287033870348703587036870378703887039870408704187042870438704487045870468704787048870498705087051870528705387054870558705687057870588705987060870618706287063870648706587066870678706887069870708707187072870738707487075870768707787078870798708087081870828708387084870858708687087870888708987090870918709287093870948709587096870978709887099871008710187102871038710487105871068710787108871098711087111871128711387114871158711687117871188711987120871218712287123871248712587126871278712887129871308713187132871338713487135871368713787138871398714087141871428714387144871458714687147871488714987150871518715287153871548715587156871578715887159871608716187162871638716487165871668716787168871698717087171871728717387174871758717687177871788717987180871818718287183871848718587186871878718887189871908719187192871938719487195871968719787198871998720087201872028720387204872058720687207872088720987210872118721287213872148721587216872178721887219872208722187222872238722487225872268722787228872298723087231872328723387234872358723687237872388723987240872418724287243872448724587246872478724887249872508725187252872538725487255872568725787258872598726087261872628726387264872658726687267872688726987270872718727287273872748727587276872778727887279872808728187282872838728487285872868728787288872898729087291872928729387294872958729687297872988729987300873018730287303873048730587306873078730887309873108731187312873138731487315873168731787318873198732087321873228732387324873258732687327873288732987330873318733287333873348733587336873378733887339873408734187342873438734487345873468734787348873498735087351873528735387354873558735687357873588735987360873618736287363873648736587366873678736887369873708737187372873738737487375873768737787378873798738087381873828738387384873858738687387873888738987390873918739287393873948739587396873978739887399874008740187402874038740487405874068740787408874098741087411874128741387414874158741687417874188741987420874218742287423874248742587426874278742887429874308743187432874338743487435874368743787438874398744087441874428744387444874458744687447874488744987450874518745287453874548745587456874578745887459874608746187462874638746487465874668746787468874698747087471874728747387474874758747687477874788747987480874818748287483874848748587486874878748887489874908749187492874938749487495874968749787498874998750087501875028750387504875058750687507875088750987510875118751287513875148751587516875178751887519875208752187522875238752487525875268752787528875298753087531875328753387534875358753687537875388753987540875418754287543875448754587546875478754887549875508755187552875538755487555875568755787558875598756087561875628756387564875658756687567875688756987570875718757287573875748757587576875778757887579875808758187582875838758487585875868758787588875898759087591875928759387594875958759687597875988759987600876018760287603876048760587606876078760887609876108761187612876138761487615876168761787618876198762087621876228762387624876258762687627876288762987630876318763287633876348763587636876378763887639876408764187642876438764487645876468764787648876498765087651876528765387654876558765687657876588765987660876618766287663876648766587666876678766887669876708767187672876738767487675876768767787678876798768087681876828768387684876858768687687876888768987690876918769287693876948769587696876978769887699877008770187702877038770487705877068770787708877098771087711877128771387714877158771687717877188771987720877218772287723877248772587726877278772887729877308773187732877338773487735877368773787738877398774087741877428774387744877458774687747877488774987750877518775287753877548775587756877578775887759877608776187762877638776487765877668776787768877698777087771877728777387774877758777687777877788777987780877818778287783877848778587786877878778887789877908779187792877938779487795877968779787798877998780087801878028780387804878058780687807878088780987810878118781287813878148781587816878178781887819878208782187822878238782487825878268782787828878298783087831878328783387834878358783687837878388783987840878418784287843878448784587846878478784887849878508785187852878538785487855878568785787858878598786087861878628786387864878658786687867878688786987870878718787287873878748787587876878778787887879878808788187882878838788487885878868788787888878898789087891878928789387894878958789687897878988789987900879018790287903879048790587906879078790887909879108791187912879138791487915879168791787918879198792087921879228792387924879258792687927879288792987930879318793287933879348793587936879378793887939879408794187942879438794487945879468794787948879498795087951879528795387954879558795687957879588795987960879618796287963879648796587966879678796887969879708797187972879738797487975879768797787978879798798087981879828798387984879858798687987879888798987990879918799287993879948799587996879978799887999880008800188002880038800488005880068800788008880098801088011880128801388014880158801688017880188801988020880218802288023880248802588026880278802888029880308803188032880338803488035880368803788038880398804088041880428804388044880458804688047880488804988050880518805288053880548805588056880578805888059880608806188062880638806488065880668806788068880698807088071880728807388074880758807688077880788807988080880818808288083880848808588086880878808888089880908809188092880938809488095880968809788098880998810088101881028810388104881058810688107881088810988110881118811288113881148811588116881178811888119881208812188122881238812488125881268812788128881298813088131881328813388134881358813688137881388813988140881418814288143881448814588146881478814888149881508815188152881538815488155881568815788158881598816088161881628816388164881658816688167881688816988170881718817288173881748817588176881778817888179881808818188182881838818488185881868818788188881898819088191881928819388194881958819688197881988819988200882018820288203882048820588206882078820888209882108821188212882138821488215882168821788218882198822088221882228822388224882258822688227882288822988230882318823288233882348823588236882378823888239882408824188242882438824488245882468824788248882498825088251882528825388254882558825688257882588825988260882618826288263882648826588266882678826888269882708827188272882738827488275882768827788278882798828088281882828828388284882858828688287882888828988290882918829288293882948829588296882978829888299883008830188302883038830488305883068830788308883098831088311883128831388314883158831688317883188831988320883218832288323883248832588326883278832888329883308833188332883338833488335883368833788338883398834088341883428834388344883458834688347883488834988350883518835288353883548835588356883578835888359883608836188362883638836488365883668836788368883698837088371883728837388374883758837688377883788837988380883818838288383883848838588386883878838888389883908839188392883938839488395883968839788398883998840088401884028840388404884058840688407884088840988410884118841288413884148841588416884178841888419884208842188422884238842488425884268842788428884298843088431884328843388434884358843688437884388843988440884418844288443884448844588446884478844888449884508845188452884538845488455884568845788458884598846088461884628846388464884658846688467884688846988470884718847288473884748847588476884778847888479884808848188482884838848488485884868848788488884898849088491884928849388494884958849688497884988849988500885018850288503885048850588506885078850888509885108851188512885138851488515885168851788518885198852088521885228852388524885258852688527885288852988530885318853288533885348853588536885378853888539885408854188542885438854488545885468854788548885498855088551885528855388554885558855688557885588855988560885618856288563885648856588566885678856888569885708857188572885738857488575885768857788578885798858088581885828858388584885858858688587885888858988590885918859288593885948859588596885978859888599886008860188602886038860488605886068860788608886098861088611886128861388614886158861688617886188861988620886218862288623886248862588626886278862888629886308863188632886338863488635886368863788638886398864088641886428864388644886458864688647886488864988650886518865288653886548865588656886578865888659886608866188662886638866488665886668866788668886698867088671886728867388674886758867688677886788867988680886818868288683886848868588686886878868888689886908869188692886938869488695886968869788698886998870088701887028870388704887058870688707887088870988710887118871288713887148871588716887178871888719887208872188722887238872488725887268872788728887298873088731887328873388734887358873688737887388873988740887418874288743887448874588746887478874888749887508875188752887538875488755887568875788758887598876088761887628876388764887658876688767887688876988770887718877288773887748877588776887778877888779887808878188782887838878488785887868878788788887898879088791887928879388794887958879688797887988879988800888018880288803888048880588806888078880888809888108881188812888138881488815888168881788818888198882088821888228882388824888258882688827888288882988830888318883288833888348883588836888378883888839888408884188842888438884488845888468884788848888498885088851888528885388854888558885688857888588885988860888618886288863888648886588866888678886888869888708887188872888738887488875888768887788878888798888088881888828888388884888858888688887888888888988890888918889288893888948889588896888978889888899889008890188902889038890488905889068890788908889098891088911889128891388914889158891688917889188891988920889218892288923889248892588926889278892888929889308893188932889338893488935889368893788938889398894088941889428894388944889458894688947889488894988950889518895288953889548895588956889578895888959889608896188962889638896488965889668896788968889698897088971889728897388974889758897688977889788897988980889818898288983889848898588986889878898888989889908899188992889938899488995889968899788998889998900089001890028900389004890058900689007890088900989010890118901289013890148901589016890178901889019890208902189022890238902489025890268902789028890298903089031890328903389034890358903689037890388903989040890418904289043890448904589046890478904889049890508905189052890538905489055890568905789058890598906089061890628906389064890658906689067890688906989070890718907289073890748907589076890778907889079890808908189082890838908489085890868908789088890898909089091890928909389094890958909689097890988909989100891018910289103891048910589106891078910889109891108911189112891138911489115891168911789118891198912089121891228912389124891258912689127891288912989130891318913289133891348913589136891378913889139891408914189142891438914489145891468914789148891498915089151891528915389154891558915689157891588915989160891618916289163891648916589166891678916889169891708917189172891738917489175891768917789178891798918089181891828918389184891858918689187891888918989190891918919289193891948919589196891978919889199892008920189202892038920489205892068920789208892098921089211892128921389214892158921689217892188921989220892218922289223892248922589226892278922889229892308923189232892338923489235892368923789238892398924089241892428924389244892458924689247892488924989250892518925289253892548925589256892578925889259892608926189262892638926489265892668926789268892698927089271892728927389274892758927689277892788927989280892818928289283892848928589286892878928889289892908929189292892938929489295892968929789298892998930089301893028930389304893058930689307893088930989310893118931289313893148931589316893178931889319893208932189322893238932489325893268932789328893298933089331893328933389334893358933689337893388933989340893418934289343893448934589346893478934889349893508935189352893538935489355893568935789358893598936089361893628936389364893658936689367893688936989370893718937289373893748937589376893778937889379893808938189382893838938489385893868938789388893898939089391893928939389394893958939689397893988939989400894018940289403894048940589406894078940889409894108941189412894138941489415894168941789418894198942089421894228942389424894258942689427894288942989430894318943289433894348943589436894378943889439894408944189442894438944489445894468944789448894498945089451894528945389454894558945689457894588945989460894618946289463894648946589466894678946889469894708947189472894738947489475894768947789478894798948089481894828948389484894858948689487894888948989490894918949289493894948949589496894978949889499895008950189502895038950489505895068950789508895098951089511895128951389514895158951689517895188951989520895218952289523895248952589526895278952889529895308953189532895338953489535895368953789538895398954089541895428954389544895458954689547895488954989550895518955289553895548955589556895578955889559895608956189562895638956489565895668956789568895698957089571895728957389574895758957689577895788957989580895818958289583895848958589586895878958889589895908959189592895938959489595895968959789598895998960089601896028960389604896058960689607896088960989610896118961289613896148961589616896178961889619896208962189622896238962489625896268962789628896298963089631896328963389634896358963689637896388963989640896418964289643896448964589646896478964889649896508965189652896538965489655896568965789658896598966089661896628966389664896658966689667896688966989670896718967289673896748967589676896778967889679896808968189682896838968489685896868968789688896898969089691896928969389694896958969689697896988969989700897018970289703897048970589706897078970889709897108971189712897138971489715897168971789718897198972089721897228972389724897258972689727897288972989730897318973289733897348973589736897378973889739897408974189742897438974489745897468974789748897498975089751897528975389754897558975689757897588975989760897618976289763897648976589766897678976889769897708977189772897738977489775897768977789778897798978089781897828978389784897858978689787897888978989790897918979289793897948979589796897978979889799898008980189802898038980489805898068980789808898098981089811898128981389814898158981689817898188981989820898218982289823898248982589826898278982889829898308983189832898338983489835898368983789838898398984089841898428984389844898458984689847898488984989850898518985289853898548985589856898578985889859898608986189862898638986489865898668986789868898698987089871898728987389874898758987689877898788987989880898818988289883898848988589886898878988889889898908989189892898938989489895898968989789898898998990089901899028990389904899058990689907899088990989910899118991289913899148991589916899178991889919899208992189922899238992489925899268992789928899298993089931899328993389934899358993689937899388993989940899418994289943899448994589946899478994889949899508995189952899538995489955899568995789958899598996089961899628996389964899658996689967899688996989970899718997289973899748997589976899778997889979899808998189982899838998489985899868998789988899898999089991899928999389994899958999689997899988999990000900019000290003900049000590006900079000890009900109001190012900139001490015900169001790018900199002090021900229002390024900259002690027900289002990030900319003290033900349003590036900379003890039900409004190042900439004490045900469004790048900499005090051900529005390054900559005690057900589005990060900619006290063900649006590066900679006890069900709007190072900739007490075900769007790078900799008090081900829008390084900859008690087900889008990090900919009290093900949009590096900979009890099901009010190102901039010490105901069010790108901099011090111901129011390114901159011690117901189011990120901219012290123901249012590126901279012890129901309013190132901339013490135901369013790138901399014090141901429014390144901459014690147901489014990150901519015290153901549015590156901579015890159901609016190162901639016490165901669016790168901699017090171901729017390174901759017690177901789017990180901819018290183901849018590186901879018890189901909019190192901939019490195901969019790198901999020090201902029020390204902059020690207902089020990210902119021290213902149021590216902179021890219902209022190222902239022490225902269022790228902299023090231902329023390234902359023690237902389023990240902419024290243902449024590246902479024890249902509025190252902539025490255902569025790258902599026090261902629026390264902659026690267902689026990270902719027290273902749027590276902779027890279902809028190282902839028490285902869028790288902899029090291902929029390294902959029690297902989029990300903019030290303903049030590306903079030890309903109031190312903139031490315903169031790318903199032090321903229032390324903259032690327903289032990330903319033290333903349033590336903379033890339903409034190342903439034490345903469034790348903499035090351903529035390354903559035690357903589035990360903619036290363903649036590366903679036890369903709037190372903739037490375903769037790378903799038090381903829038390384903859038690387903889038990390903919039290393903949039590396903979039890399904009040190402904039040490405904069040790408904099041090411904129041390414904159041690417904189041990420904219042290423904249042590426904279042890429904309043190432904339043490435904369043790438904399044090441904429044390444904459044690447904489044990450904519045290453904549045590456904579045890459904609046190462904639046490465904669046790468904699047090471904729047390474904759047690477904789047990480904819048290483904849048590486904879048890489904909049190492904939049490495904969049790498904999050090501905029050390504905059050690507905089050990510905119051290513905149051590516905179051890519905209052190522905239052490525905269052790528905299053090531905329053390534905359053690537905389053990540905419054290543905449054590546905479054890549905509055190552905539055490555905569055790558905599056090561905629056390564905659056690567905689056990570905719057290573905749057590576905779057890579905809058190582905839058490585905869058790588905899059090591905929059390594905959059690597905989059990600906019060290603906049060590606906079060890609906109061190612906139061490615906169061790618906199062090621906229062390624906259062690627906289062990630906319063290633906349063590636906379063890639906409064190642906439064490645906469064790648906499065090651906529065390654906559065690657906589065990660906619066290663906649066590666906679066890669906709067190672906739067490675906769067790678906799068090681906829068390684906859068690687906889068990690906919069290693906949069590696906979069890699907009070190702907039070490705907069070790708907099071090711907129071390714907159071690717907189071990720907219072290723907249072590726907279072890729907309073190732907339073490735907369073790738907399074090741907429074390744907459074690747907489074990750907519075290753907549075590756907579075890759907609076190762907639076490765907669076790768907699077090771907729077390774907759077690777907789077990780907819078290783907849078590786907879078890789907909079190792907939079490795907969079790798907999080090801908029080390804908059080690807908089080990810908119081290813908149081590816908179081890819908209082190822908239082490825908269082790828908299083090831908329083390834908359083690837908389083990840908419084290843908449084590846908479084890849908509085190852908539085490855908569085790858908599086090861908629086390864908659086690867908689086990870908719087290873908749087590876908779087890879908809088190882908839088490885908869088790888908899089090891908929089390894908959089690897908989089990900909019090290903909049090590906909079090890909909109091190912909139091490915909169091790918909199092090921909229092390924909259092690927909289092990930909319093290933909349093590936909379093890939909409094190942909439094490945909469094790948909499095090951909529095390954909559095690957909589095990960909619096290963909649096590966909679096890969909709097190972909739097490975909769097790978909799098090981909829098390984909859098690987909889098990990909919099290993909949099590996909979099890999910009100191002910039100491005910069100791008910099101091011910129101391014910159101691017910189101991020910219102291023910249102591026910279102891029910309103191032910339103491035910369103791038910399104091041910429104391044910459104691047910489104991050910519105291053910549105591056910579105891059910609106191062910639106491065910669106791068910699107091071910729107391074910759107691077910789107991080910819108291083910849108591086910879108891089910909109191092910939109491095910969109791098910999110091101911029110391104911059110691107911089110991110911119111291113911149111591116911179111891119911209112191122911239112491125911269112791128911299113091131911329113391134911359113691137911389113991140911419114291143911449114591146911479114891149911509115191152911539115491155911569115791158911599116091161911629116391164911659116691167911689116991170911719117291173911749117591176911779117891179911809118191182911839118491185911869118791188911899119091191911929119391194911959119691197911989119991200912019120291203912049120591206912079120891209912109121191212912139121491215912169121791218912199122091221912229122391224912259122691227912289122991230912319123291233912349123591236912379123891239912409124191242912439124491245912469124791248912499125091251912529125391254912559125691257912589125991260912619126291263912649126591266912679126891269912709127191272912739127491275912769127791278912799128091281912829128391284912859128691287912889128991290912919129291293912949129591296912979129891299913009130191302913039130491305913069130791308913099131091311913129131391314913159131691317913189131991320913219132291323913249132591326913279132891329913309133191332913339133491335913369133791338913399134091341913429134391344913459134691347913489134991350913519135291353913549135591356913579135891359913609136191362913639136491365913669136791368913699137091371913729137391374913759137691377913789137991380913819138291383913849138591386913879138891389913909139191392913939139491395913969139791398913999140091401914029140391404914059140691407914089140991410914119141291413914149141591416914179141891419914209142191422914239142491425914269142791428914299143091431914329143391434914359143691437914389143991440914419144291443914449144591446914479144891449914509145191452914539145491455914569145791458914599146091461914629146391464914659146691467914689146991470914719147291473914749147591476914779147891479914809148191482914839148491485914869148791488914899149091491914929149391494914959149691497914989149991500915019150291503915049150591506915079150891509915109151191512915139151491515915169151791518915199152091521915229152391524915259152691527915289152991530915319153291533915349153591536915379153891539915409154191542915439154491545915469154791548915499155091551915529155391554915559155691557915589155991560915619156291563915649156591566915679156891569915709157191572915739157491575915769157791578915799158091581915829158391584915859158691587915889158991590915919159291593915949159591596915979159891599916009160191602916039160491605916069160791608916099161091611916129161391614916159161691617916189161991620916219162291623916249162591626916279162891629916309163191632916339163491635916369163791638916399164091641916429164391644916459164691647916489164991650916519165291653916549165591656916579165891659916609166191662916639166491665916669166791668916699167091671916729167391674916759167691677916789167991680916819168291683916849168591686916879168891689916909169191692916939169491695916969169791698916999170091701917029170391704917059170691707917089170991710917119171291713917149171591716917179171891719917209172191722917239172491725917269172791728917299173091731917329173391734917359173691737917389173991740917419174291743917449174591746917479174891749917509175191752917539175491755917569175791758917599176091761917629176391764917659176691767917689176991770917719177291773917749177591776917779177891779917809178191782917839178491785917869178791788917899179091791917929179391794917959179691797917989179991800918019180291803918049180591806918079180891809918109181191812918139181491815918169181791818918199182091821918229182391824918259182691827918289182991830918319183291833918349183591836918379183891839918409184191842918439184491845918469184791848918499185091851918529185391854918559185691857918589185991860918619186291863918649186591866918679186891869918709187191872918739187491875918769187791878918799188091881918829188391884918859188691887918889188991890918919189291893918949189591896918979189891899919009190191902919039190491905919069190791908919099191091911919129191391914919159191691917919189191991920919219192291923919249192591926919279192891929919309193191932919339193491935919369193791938919399194091941919429194391944919459194691947919489194991950919519195291953919549195591956919579195891959919609196191962919639196491965919669196791968919699197091971919729197391974919759197691977919789197991980919819198291983919849198591986919879198891989919909199191992919939199491995919969199791998919999200092001920029200392004920059200692007920089200992010920119201292013920149201592016920179201892019920209202192022920239202492025920269202792028920299203092031920329203392034920359203692037920389203992040920419204292043920449204592046920479204892049920509205192052920539205492055920569205792058920599206092061920629206392064920659206692067920689206992070920719207292073920749207592076920779207892079920809208192082920839208492085920869208792088920899209092091920929209392094920959209692097920989209992100921019210292103921049210592106921079210892109921109211192112921139211492115921169211792118921199212092121921229212392124921259212692127921289212992130921319213292133921349213592136921379213892139921409214192142921439214492145921469214792148921499215092151921529215392154921559215692157921589215992160921619216292163921649216592166921679216892169921709217192172921739217492175921769217792178921799218092181921829218392184921859218692187921889218992190921919219292193921949219592196921979219892199922009220192202922039220492205922069220792208922099221092211922129221392214922159221692217922189221992220922219222292223922249222592226922279222892229922309223192232922339223492235922369223792238922399224092241922429224392244922459224692247922489224992250922519225292253922549225592256922579225892259922609226192262922639226492265922669226792268922699227092271922729227392274922759227692277922789227992280922819228292283922849228592286922879228892289922909229192292922939229492295922969229792298922999230092301923029230392304923059230692307923089230992310923119231292313923149231592316923179231892319923209232192322923239232492325923269232792328923299233092331923329233392334923359233692337923389233992340923419234292343923449234592346923479234892349923509235192352923539235492355923569235792358923599236092361923629236392364923659236692367923689236992370923719237292373923749237592376923779237892379923809238192382923839238492385923869238792388923899239092391923929239392394923959239692397923989239992400924019240292403924049240592406924079240892409924109241192412924139241492415924169241792418924199242092421924229242392424924259242692427924289242992430924319243292433924349243592436924379243892439924409244192442924439244492445924469244792448924499245092451924529245392454924559245692457924589245992460924619246292463924649246592466924679246892469924709247192472924739247492475924769247792478924799248092481924829248392484924859248692487924889248992490924919249292493924949249592496924979249892499925009250192502925039250492505925069250792508925099251092511925129251392514925159251692517925189251992520925219252292523925249252592526925279252892529925309253192532925339253492535925369253792538925399254092541925429254392544925459254692547925489254992550925519255292553925549255592556925579255892559925609256192562925639256492565925669256792568925699257092571925729257392574925759257692577925789257992580925819258292583925849258592586925879258892589925909259192592925939259492595925969259792598925999260092601926029260392604926059260692607926089260992610926119261292613926149261592616926179261892619926209262192622926239262492625926269262792628926299263092631926329263392634926359263692637926389263992640926419264292643926449264592646926479264892649926509265192652926539265492655926569265792658926599266092661926629266392664926659266692667926689266992670926719267292673926749267592676926779267892679926809268192682926839268492685926869268792688926899269092691926929269392694926959269692697926989269992700927019270292703927049270592706927079270892709927109271192712927139271492715927169271792718927199272092721927229272392724927259272692727927289272992730927319273292733927349273592736927379273892739927409274192742927439274492745927469274792748927499275092751927529275392754927559275692757927589275992760927619276292763927649276592766927679276892769927709277192772927739277492775927769277792778927799278092781927829278392784927859278692787927889278992790927919279292793927949279592796927979279892799928009280192802928039280492805928069280792808928099281092811928129281392814928159281692817928189281992820928219282292823928249282592826928279282892829928309283192832928339283492835928369283792838928399284092841928429284392844928459284692847928489284992850928519285292853928549285592856928579285892859928609286192862928639286492865928669286792868928699287092871928729287392874928759287692877928789287992880928819288292883928849288592886928879288892889928909289192892928939289492895928969289792898928999290092901929029290392904929059290692907929089290992910929119291292913929149291592916929179291892919929209292192922929239292492925929269292792928929299293092931929329293392934929359293692937929389293992940929419294292943929449294592946929479294892949929509295192952929539295492955929569295792958929599296092961929629296392964929659296692967929689296992970929719297292973929749297592976929779297892979929809298192982929839298492985929869298792988929899299092991929929299392994929959299692997929989299993000930019300293003930049300593006930079300893009930109301193012930139301493015930169301793018930199302093021930229302393024930259302693027930289302993030930319303293033930349303593036930379303893039930409304193042930439304493045930469304793048930499305093051930529305393054930559305693057930589305993060930619306293063930649306593066930679306893069930709307193072930739307493075930769307793078930799308093081930829308393084930859308693087930889308993090930919309293093930949309593096930979309893099931009310193102931039310493105931069310793108931099311093111931129311393114931159311693117931189311993120931219312293123931249312593126931279312893129931309313193132931339313493135931369313793138931399314093141931429314393144931459314693147931489314993150931519315293153931549315593156931579315893159931609316193162931639316493165931669316793168931699317093171931729317393174931759317693177931789317993180931819318293183931849318593186931879318893189931909319193192931939319493195931969319793198931999320093201932029320393204932059320693207932089320993210932119321293213932149321593216932179321893219932209322193222932239322493225932269322793228932299323093231932329323393234932359323693237932389323993240932419324293243932449324593246932479324893249932509325193252932539325493255932569325793258932599326093261932629326393264932659326693267932689326993270932719327293273932749327593276932779327893279932809328193282932839328493285932869328793288932899329093291932929329393294932959329693297932989329993300933019330293303933049330593306933079330893309933109331193312933139331493315933169331793318933199332093321933229332393324933259332693327933289332993330933319333293333933349333593336933379333893339933409334193342933439334493345933469334793348933499335093351933529335393354933559335693357933589335993360933619336293363933649336593366933679336893369933709337193372933739337493375933769337793378933799338093381933829338393384933859338693387933889338993390933919339293393933949339593396933979339893399934009340193402934039340493405934069340793408934099341093411934129341393414934159341693417934189341993420934219342293423934249342593426934279342893429934309343193432934339343493435934369343793438934399344093441934429344393444934459344693447934489344993450934519345293453934549345593456934579345893459934609346193462934639346493465934669346793468934699347093471934729347393474934759347693477934789347993480934819348293483934849348593486934879348893489934909349193492934939349493495934969349793498934999350093501935029350393504935059350693507935089350993510935119351293513935149351593516935179351893519935209352193522935239352493525935269352793528935299353093531935329353393534935359353693537935389353993540935419354293543935449354593546935479354893549935509355193552935539355493555935569355793558935599356093561935629356393564935659356693567935689356993570935719357293573935749357593576935779357893579935809358193582935839358493585935869358793588935899359093591935929359393594935959359693597935989359993600936019360293603936049360593606936079360893609936109361193612936139361493615936169361793618936199362093621936229362393624936259362693627936289362993630936319363293633936349363593636936379363893639936409364193642936439364493645936469364793648936499365093651936529365393654936559365693657936589365993660936619366293663936649366593666936679366893669936709367193672936739367493675936769367793678936799368093681936829368393684936859368693687936889368993690936919369293693936949369593696936979369893699937009370193702937039370493705937069370793708937099371093711937129371393714937159371693717937189371993720937219372293723937249372593726937279372893729937309373193732937339373493735937369373793738937399374093741937429374393744937459374693747937489374993750937519375293753937549375593756937579375893759937609376193762937639376493765937669376793768937699377093771937729377393774937759377693777937789377993780937819378293783937849378593786937879378893789937909379193792937939379493795937969379793798937999380093801938029380393804938059380693807938089380993810938119381293813938149381593816938179381893819938209382193822938239382493825938269382793828938299383093831938329383393834938359383693837938389383993840938419384293843938449384593846938479384893849938509385193852938539385493855938569385793858938599386093861938629386393864938659386693867938689386993870938719387293873938749387593876938779387893879938809388193882938839388493885938869388793888938899389093891938929389393894938959389693897938989389993900939019390293903939049390593906939079390893909939109391193912939139391493915939169391793918939199392093921939229392393924939259392693927939289392993930939319393293933939349393593936939379393893939939409394193942939439394493945939469394793948939499395093951939529395393954939559395693957939589395993960939619396293963939649396593966939679396893969939709397193972939739397493975939769397793978939799398093981939829398393984939859398693987939889398993990939919399293993939949399593996939979399893999940009400194002940039400494005940069400794008940099401094011940129401394014940159401694017940189401994020940219402294023940249402594026940279402894029940309403194032940339403494035940369403794038940399404094041940429404394044940459404694047940489404994050940519405294053940549405594056940579405894059940609406194062940639406494065940669406794068940699407094071940729407394074940759407694077940789407994080940819408294083940849408594086940879408894089940909409194092940939409494095940969409794098940999410094101941029410394104941059410694107941089410994110941119411294113941149411594116941179411894119941209412194122941239412494125941269412794128941299413094131941329413394134941359413694137941389413994140941419414294143941449414594146941479414894149941509415194152941539415494155941569415794158941599416094161941629416394164941659416694167941689416994170941719417294173941749417594176941779417894179941809418194182941839418494185941869418794188941899419094191941929419394194941959419694197941989419994200942019420294203942049420594206942079420894209942109421194212942139421494215942169421794218942199422094221942229422394224942259422694227942289422994230942319423294233942349423594236942379423894239942409424194242942439424494245942469424794248942499425094251942529425394254942559425694257942589425994260942619426294263942649426594266942679426894269942709427194272942739427494275942769427794278942799428094281942829428394284942859428694287942889428994290942919429294293942949429594296942979429894299943009430194302943039430494305943069430794308943099431094311943129431394314943159431694317943189431994320943219432294323943249432594326943279432894329943309433194332943339433494335943369433794338943399434094341943429434394344943459434694347943489434994350943519435294353943549435594356943579435894359943609436194362943639436494365943669436794368943699437094371943729437394374943759437694377943789437994380943819438294383943849438594386943879438894389943909439194392943939439494395943969439794398943999440094401944029440394404944059440694407944089440994410944119441294413944149441594416944179441894419944209442194422944239442494425944269442794428944299443094431944329443394434944359443694437944389443994440944419444294443944449444594446944479444894449944509445194452944539445494455944569445794458944599446094461944629446394464944659446694467944689446994470944719447294473944749447594476944779447894479944809448194482944839448494485944869448794488944899449094491944929449394494944959449694497944989449994500945019450294503945049450594506945079450894509945109451194512945139451494515945169451794518945199452094521945229452394524945259452694527945289452994530945319453294533945349453594536945379453894539945409454194542945439454494545945469454794548945499455094551945529455394554945559455694557945589455994560945619456294563945649456594566945679456894569945709457194572945739457494575945769457794578945799458094581945829458394584945859458694587945889458994590945919459294593945949459594596945979459894599946009460194602946039460494605946069460794608946099461094611946129461394614946159461694617946189461994620946219462294623946249462594626946279462894629946309463194632946339463494635946369463794638946399464094641946429464394644946459464694647946489464994650946519465294653946549465594656946579465894659946609466194662946639466494665946669466794668946699467094671946729467394674946759467694677946789467994680946819468294683946849468594686946879468894689946909469194692946939469494695946969469794698946999470094701947029470394704947059470694707947089470994710947119471294713947149471594716947179471894719947209472194722947239472494725947269472794728947299473094731947329473394734947359473694737947389473994740947419474294743947449474594746947479474894749947509475194752947539475494755947569475794758947599476094761947629476394764947659476694767947689476994770947719477294773947749477594776947779477894779947809478194782947839478494785947869478794788947899479094791947929479394794947959479694797947989479994800948019480294803948049480594806948079480894809948109481194812948139481494815948169481794818948199482094821948229482394824948259482694827948289482994830948319483294833948349483594836948379483894839948409484194842948439484494845948469484794848948499485094851948529485394854948559485694857948589485994860948619486294863948649486594866948679486894869948709487194872948739487494875948769487794878948799488094881948829488394884948859488694887948889488994890948919489294893948949489594896948979489894899949009490194902949039490494905949069490794908949099491094911949129491394914949159491694917949189491994920949219492294923949249492594926949279492894929949309493194932949339493494935949369493794938949399494094941949429494394944949459494694947949489494994950949519495294953949549495594956949579495894959949609496194962949639496494965949669496794968949699497094971949729497394974949759497694977949789497994980949819498294983949849498594986949879498894989949909499194992949939499494995949969499794998949999500095001950029500395004950059500695007950089500995010950119501295013950149501595016950179501895019950209502195022950239502495025950269502795028950299503095031950329503395034950359503695037950389503995040950419504295043950449504595046950479504895049950509505195052950539505495055950569505795058950599506095061950629506395064950659506695067950689506995070950719507295073950749507595076950779507895079950809508195082950839508495085950869508795088950899509095091950929509395094950959509695097950989509995100951019510295103951049510595106951079510895109951109511195112951139511495115951169511795118951199512095121951229512395124951259512695127951289512995130951319513295133951349513595136951379513895139951409514195142951439514495145951469514795148951499515095151951529515395154951559515695157951589515995160951619516295163951649516595166951679516895169951709517195172951739517495175951769517795178951799518095181951829518395184951859518695187951889518995190951919519295193951949519595196951979519895199952009520195202952039520495205952069520795208952099521095211952129521395214952159521695217952189521995220952219522295223952249522595226952279522895229952309523195232952339523495235952369523795238952399524095241952429524395244952459524695247952489524995250952519525295253952549525595256952579525895259952609526195262952639526495265952669526795268952699527095271952729527395274952759527695277952789527995280952819528295283952849528595286952879528895289952909529195292952939529495295952969529795298952999530095301953029530395304953059530695307953089530995310953119531295313953149531595316953179531895319953209532195322953239532495325953269532795328953299533095331953329533395334953359533695337953389533995340953419534295343953449534595346953479534895349953509535195352953539535495355953569535795358953599536095361953629536395364953659536695367953689536995370953719537295373953749537595376953779537895379953809538195382953839538495385953869538795388953899539095391953929539395394953959539695397953989539995400954019540295403954049540595406954079540895409954109541195412954139541495415954169541795418954199542095421954229542395424954259542695427954289542995430954319543295433954349543595436954379543895439954409544195442954439544495445954469544795448954499545095451954529545395454954559545695457954589545995460954619546295463954649546595466954679546895469954709547195472954739547495475954769547795478954799548095481954829548395484954859548695487954889548995490954919549295493954949549595496954979549895499955009550195502955039550495505955069550795508955099551095511955129551395514955159551695517955189551995520955219552295523955249552595526955279552895529955309553195532955339553495535955369553795538955399554095541955429554395544955459554695547955489554995550955519555295553955549555595556955579555895559955609556195562955639556495565955669556795568955699557095571955729557395574955759557695577955789557995580955819558295583955849558595586955879558895589955909559195592955939559495595955969559795598955999560095601956029560395604956059560695607956089560995610956119561295613956149561595616956179561895619956209562195622956239562495625956269562795628956299563095631956329563395634956359563695637956389563995640956419564295643956449564595646956479564895649956509565195652956539565495655956569565795658956599566095661956629566395664956659566695667956689566995670956719567295673956749567595676956779567895679956809568195682956839568495685956869568795688956899569095691956929569395694956959569695697956989569995700957019570295703957049570595706957079570895709957109571195712957139571495715957169571795718957199572095721957229572395724957259572695727957289572995730957319573295733957349573595736957379573895739957409574195742957439574495745957469574795748957499575095751957529575395754957559575695757957589575995760957619576295763957649576595766957679576895769957709577195772957739577495775957769577795778957799578095781957829578395784957859578695787957889578995790957919579295793957949579595796957979579895799958009580195802958039580495805958069580795808958099581095811958129581395814958159581695817958189581995820958219582295823958249582595826958279582895829958309583195832958339583495835958369583795838958399584095841958429584395844958459584695847958489584995850958519585295853958549585595856958579585895859958609586195862958639586495865958669586795868958699587095871958729587395874958759587695877958789587995880958819588295883958849588595886958879588895889958909589195892958939589495895958969589795898958999590095901959029590395904959059590695907959089590995910959119591295913959149591595916959179591895919959209592195922959239592495925959269592795928959299593095931959329593395934959359593695937959389593995940959419594295943959449594595946959479594895949959509595195952959539595495955959569595795958959599596095961959629596395964959659596695967959689596995970959719597295973959749597595976959779597895979959809598195982959839598495985959869598795988959899599095991959929599395994959959599695997959989599996000960019600296003960049600596006960079600896009960109601196012960139601496015960169601796018960199602096021960229602396024960259602696027960289602996030960319603296033960349603596036960379603896039960409604196042960439604496045960469604796048960499605096051960529605396054960559605696057960589605996060960619606296063960649606596066960679606896069960709607196072960739607496075960769607796078960799608096081960829608396084960859608696087960889608996090960919609296093960949609596096960979609896099961009610196102961039610496105961069610796108961099611096111961129611396114961159611696117961189611996120961219612296123961249612596126961279612896129961309613196132961339613496135961369613796138961399614096141961429614396144961459614696147961489614996150961519615296153961549615596156961579615896159961609616196162961639616496165961669616796168961699617096171961729617396174961759617696177961789617996180961819618296183961849618596186961879618896189961909619196192961939619496195961969619796198961999620096201962029620396204962059620696207962089620996210962119621296213962149621596216962179621896219962209622196222962239622496225962269622796228962299623096231962329623396234962359623696237962389623996240962419624296243962449624596246962479624896249962509625196252962539625496255962569625796258962599626096261962629626396264962659626696267962689626996270962719627296273962749627596276962779627896279962809628196282962839628496285962869628796288962899629096291962929629396294962959629696297962989629996300963019630296303963049630596306963079630896309963109631196312963139631496315963169631796318963199632096321963229632396324963259632696327963289632996330963319633296333963349633596336963379633896339963409634196342963439634496345963469634796348963499635096351963529635396354963559635696357963589635996360963619636296363963649636596366963679636896369963709637196372963739637496375963769637796378963799638096381963829638396384963859638696387963889638996390963919639296393963949639596396963979639896399964009640196402964039640496405964069640796408964099641096411964129641396414964159641696417964189641996420964219642296423964249642596426964279642896429964309643196432964339643496435964369643796438964399644096441964429644396444964459644696447964489644996450964519645296453964549645596456964579645896459964609646196462964639646496465964669646796468964699647096471964729647396474964759647696477964789647996480964819648296483964849648596486964879648896489964909649196492964939649496495964969649796498964999650096501965029650396504965059650696507965089650996510965119651296513965149651596516965179651896519965209652196522965239652496525965269652796528965299653096531965329653396534965359653696537965389653996540965419654296543965449654596546965479654896549965509655196552965539655496555965569655796558965599656096561965629656396564965659656696567965689656996570965719657296573965749657596576965779657896579965809658196582965839658496585965869658796588965899659096591965929659396594965959659696597965989659996600966019660296603966049660596606966079660896609966109661196612966139661496615966169661796618966199662096621966229662396624966259662696627966289662996630966319663296633966349663596636966379663896639966409664196642966439664496645966469664796648966499665096651966529665396654966559665696657966589665996660966619666296663966649666596666966679666896669966709667196672966739667496675966769667796678966799668096681966829668396684966859668696687966889668996690966919669296693966949669596696966979669896699967009670196702967039670496705967069670796708967099671096711967129671396714967159671696717967189671996720967219672296723967249672596726967279672896729967309673196732967339673496735967369673796738967399674096741967429674396744967459674696747967489674996750967519675296753967549675596756967579675896759967609676196762967639676496765967669676796768967699677096771967729677396774967759677696777967789677996780967819678296783967849678596786967879678896789967909679196792967939679496795967969679796798967999680096801968029680396804968059680696807968089680996810968119681296813968149681596816968179681896819968209682196822968239682496825968269682796828968299683096831968329683396834968359683696837968389683996840968419684296843968449684596846968479684896849968509685196852968539685496855968569685796858968599686096861968629686396864968659686696867968689686996870968719687296873968749687596876968779687896879968809688196882968839688496885968869688796888968899689096891968929689396894968959689696897968989689996900969019690296903969049690596906969079690896909969109691196912969139691496915969169691796918969199692096921969229692396924969259692696927969289692996930969319693296933969349693596936969379693896939969409694196942969439694496945969469694796948969499695096951969529695396954969559695696957969589695996960969619696296963969649696596966969679696896969969709697196972969739697496975969769697796978969799698096981969829698396984969859698696987969889698996990969919699296993969949699596996969979699896999970009700197002970039700497005970069700797008970099701097011970129701397014970159701697017970189701997020970219702297023970249702597026970279702897029970309703197032970339703497035970369703797038970399704097041970429704397044970459704697047970489704997050970519705297053970549705597056970579705897059970609706197062970639706497065970669706797068970699707097071970729707397074970759707697077970789707997080970819708297083970849708597086970879708897089970909709197092970939709497095970969709797098970999710097101971029710397104971059710697107971089710997110971119711297113971149711597116971179711897119971209712197122971239712497125971269712797128971299713097131971329713397134971359713697137971389713997140971419714297143971449714597146971479714897149971509715197152971539715497155971569715797158971599716097161971629716397164971659716697167971689716997170971719717297173971749717597176971779717897179971809718197182971839718497185971869718797188971899719097191971929719397194971959719697197971989719997200972019720297203972049720597206972079720897209972109721197212972139721497215972169721797218972199722097221972229722397224972259722697227972289722997230972319723297233972349723597236972379723897239972409724197242972439724497245972469724797248972499725097251972529725397254972559725697257972589725997260972619726297263972649726597266972679726897269972709727197272972739727497275972769727797278972799728097281972829728397284972859728697287972889728997290972919729297293972949729597296972979729897299973009730197302973039730497305973069730797308973099731097311973129731397314973159731697317973189731997320973219732297323973249732597326973279732897329973309733197332973339733497335973369733797338973399734097341973429734397344973459734697347973489734997350973519735297353973549735597356973579735897359973609736197362973639736497365973669736797368973699737097371973729737397374973759737697377973789737997380973819738297383973849738597386973879738897389973909739197392973939739497395973969739797398973999740097401974029740397404974059740697407974089740997410974119741297413974149741597416974179741897419974209742197422974239742497425974269742797428974299743097431974329743397434974359743697437974389743997440974419744297443974449744597446974479744897449974509745197452974539745497455974569745797458974599746097461974629746397464974659746697467974689746997470974719747297473974749747597476974779747897479974809748197482974839748497485974869748797488974899749097491974929749397494974959749697497974989749997500975019750297503975049750597506975079750897509975109751197512975139751497515975169751797518975199752097521975229752397524975259752697527975289752997530975319753297533975349753597536975379753897539975409754197542975439754497545975469754797548975499755097551975529755397554975559755697557975589755997560975619756297563975649756597566975679756897569975709757197572975739757497575975769757797578975799758097581975829758397584975859758697587975889758997590975919759297593975949759597596975979759897599976009760197602976039760497605976069760797608976099761097611976129761397614976159761697617976189761997620976219762297623976249762597626976279762897629976309763197632976339763497635976369763797638976399764097641976429764397644976459764697647976489764997650976519765297653976549765597656976579765897659976609766197662976639766497665976669766797668976699767097671976729767397674976759767697677976789767997680976819768297683976849768597686976879768897689976909769197692976939769497695976969769797698976999770097701977029770397704977059770697707977089770997710977119771297713977149771597716977179771897719977209772197722977239772497725977269772797728977299773097731977329773397734977359773697737977389773997740977419774297743977449774597746977479774897749977509775197752977539775497755977569775797758977599776097761977629776397764977659776697767977689776997770977719777297773977749777597776977779777897779977809778197782977839778497785977869778797788977899779097791977929779397794977959779697797977989779997800978019780297803978049780597806978079780897809978109781197812978139781497815978169781797818978199782097821978229782397824978259782697827978289782997830978319783297833978349783597836978379783897839978409784197842978439784497845978469784797848978499785097851978529785397854978559785697857978589785997860978619786297863978649786597866978679786897869978709787197872978739787497875978769787797878978799788097881978829788397884978859788697887978889788997890978919789297893978949789597896978979789897899979009790197902979039790497905979069790797908979099791097911979129791397914979159791697917979189791997920979219792297923979249792597926979279792897929979309793197932979339793497935979369793797938979399794097941979429794397944979459794697947979489794997950979519795297953979549795597956979579795897959979609796197962979639796497965979669796797968979699797097971979729797397974979759797697977979789797997980979819798297983979849798597986979879798897989979909799197992979939799497995979969799797998979999800098001980029800398004980059800698007980089800998010980119801298013980149801598016980179801898019980209802198022980239802498025980269802798028980299803098031980329803398034980359803698037980389803998040980419804298043980449804598046980479804898049980509805198052980539805498055980569805798058980599806098061980629806398064980659806698067980689806998070980719807298073980749807598076980779807898079980809808198082980839808498085980869808798088980899809098091980929809398094980959809698097980989809998100981019810298103981049810598106981079810898109981109811198112981139811498115981169811798118981199812098121981229812398124981259812698127981289812998130981319813298133981349813598136981379813898139981409814198142981439814498145981469814798148981499815098151981529815398154981559815698157981589815998160981619816298163981649816598166981679816898169981709817198172981739817498175981769817798178981799818098181981829818398184981859818698187981889818998190981919819298193981949819598196981979819898199982009820198202982039820498205982069820798208982099821098211982129821398214982159821698217982189821998220982219822298223982249822598226982279822898229982309823198232982339823498235982369823798238982399824098241982429824398244982459824698247982489824998250982519825298253982549825598256982579825898259982609826198262982639826498265982669826798268982699827098271982729827398274982759827698277982789827998280982819828298283982849828598286982879828898289982909829198292982939829498295982969829798298982999830098301983029830398304983059830698307983089830998310983119831298313983149831598316983179831898319983209832198322983239832498325983269832798328983299833098331983329833398334983359833698337983389833998340983419834298343983449834598346983479834898349983509835198352983539835498355983569835798358983599836098361983629836398364983659836698367983689836998370983719837298373983749837598376983779837898379983809838198382983839838498385983869838798388983899839098391983929839398394983959839698397983989839998400984019840298403984049840598406984079840898409984109841198412984139841498415984169841798418984199842098421984229842398424984259842698427984289842998430984319843298433984349843598436984379843898439984409844198442984439844498445984469844798448984499845098451984529845398454984559845698457984589845998460984619846298463984649846598466984679846898469984709847198472984739847498475984769847798478984799848098481984829848398484984859848698487984889848998490984919849298493984949849598496984979849898499985009850198502985039850498505985069850798508985099851098511985129851398514985159851698517985189851998520985219852298523985249852598526985279852898529985309853198532985339853498535985369853798538985399854098541985429854398544985459854698547985489854998550985519855298553985549855598556985579855898559985609856198562985639856498565985669856798568985699857098571985729857398574985759857698577985789857998580985819858298583985849858598586985879858898589985909859198592985939859498595985969859798598985999860098601986029860398604986059860698607986089860998610986119861298613986149861598616986179861898619986209862198622986239862498625986269862798628986299863098631986329863398634986359863698637986389863998640986419864298643986449864598646986479864898649986509865198652986539865498655986569865798658986599866098661986629866398664986659866698667986689866998670986719867298673986749867598676986779867898679986809868198682986839868498685986869868798688986899869098691986929869398694986959869698697986989869998700987019870298703987049870598706987079870898709987109871198712987139871498715987169871798718987199872098721987229872398724987259872698727987289872998730987319873298733987349873598736987379873898739987409874198742987439874498745987469874798748987499875098751987529875398754987559875698757987589875998760987619876298763987649876598766987679876898769987709877198772987739877498775987769877798778987799878098781987829878398784987859878698787987889878998790987919879298793987949879598796987979879898799988009880198802988039880498805988069880798808988099881098811988129881398814988159881698817988189881998820988219882298823988249882598826988279882898829988309883198832988339883498835988369883798838988399884098841988429884398844988459884698847988489884998850988519885298853988549885598856988579885898859988609886198862988639886498865988669886798868988699887098871988729887398874988759887698877988789887998880988819888298883988849888598886988879888898889988909889198892988939889498895988969889798898988999890098901989029890398904989059890698907989089890998910989119891298913989149891598916989179891898919989209892198922989239892498925989269892798928989299893098931989329893398934989359893698937989389893998940989419894298943989449894598946989479894898949989509895198952989539895498955989569895798958989599896098961989629896398964989659896698967989689896998970989719897298973989749897598976989779897898979989809898198982989839898498985989869898798988989899899098991989929899398994989959899698997989989899999000990019900299003990049900599006990079900899009990109901199012990139901499015990169901799018990199902099021990229902399024990259902699027990289902999030990319903299033990349903599036990379903899039990409904199042990439904499045990469904799048990499905099051990529905399054990559905699057990589905999060990619906299063990649906599066990679906899069990709907199072990739907499075990769907799078990799908099081990829908399084990859908699087990889908999090990919909299093990949909599096990979909899099991009910199102991039910499105991069910799108991099911099111991129911399114991159911699117991189911999120991219912299123991249912599126991279912899129991309913199132991339913499135991369913799138991399914099141991429914399144991459914699147991489914999150991519915299153991549915599156991579915899159991609916199162991639916499165991669916799168991699917099171991729917399174991759917699177991789917999180991819918299183991849918599186991879918899189991909919199192991939919499195991969919799198991999920099201992029920399204992059920699207992089920999210992119921299213992149921599216992179921899219992209922199222992239922499225992269922799228992299923099231992329923399234992359923699237992389923999240992419924299243992449924599246992479924899249992509925199252992539925499255992569925799258992599926099261992629926399264992659926699267992689926999270992719927299273992749927599276992779927899279992809928199282992839928499285992869928799288992899929099291992929929399294992959929699297992989929999300993019930299303993049930599306993079930899309993109931199312993139931499315993169931799318993199932099321993229932399324993259932699327993289932999330993319933299333993349933599336993379933899339993409934199342993439934499345993469934799348993499935099351993529935399354993559935699357993589935999360993619936299363993649936599366993679936899369993709937199372993739937499375993769937799378993799938099381993829938399384993859938699387993889938999390993919939299393993949939599396993979939899399994009940199402994039940499405994069940799408994099941099411994129941399414994159941699417994189941999420994219942299423994249942599426994279942899429994309943199432994339943499435994369943799438994399944099441994429944399444994459944699447994489944999450994519945299453994549945599456994579945899459994609946199462994639946499465994669946799468994699947099471994729947399474994759947699477994789947999480994819948299483994849948599486994879948899489994909949199492994939949499495994969949799498994999950099501995029950399504995059950699507995089950999510995119951299513995149951599516995179951899519995209952199522995239952499525995269952799528995299953099531995329953399534995359953699537995389953999540995419954299543995449954599546995479954899549995509955199552995539955499555995569955799558995599956099561995629956399564995659956699567995689956999570995719957299573995749957599576995779957899579995809958199582995839958499585995869958799588995899959099591995929959399594995959959699597995989959999600996019960299603996049960599606996079960899609996109961199612996139961499615996169961799618996199962099621996229962399624996259962699627996289962999630996319963299633996349963599636996379963899639996409964199642996439964499645996469964799648996499965099651996529965399654996559965699657996589965999660996619966299663996649966599666996679966899669996709967199672996739967499675996769967799678996799968099681996829968399684996859968699687996889968999690996919969299693996949969599696996979969899699997009970199702997039970499705997069970799708997099971099711997129971399714997159971699717997189971999720997219972299723997249972599726997279972899729997309973199732997339973499735997369973799738997399974099741997429974399744997459974699747997489974999750997519975299753997549975599756997579975899759997609976199762997639976499765997669976799768997699977099771997729977399774997759977699777997789977999780997819978299783997849978599786997879978899789997909979199792997939979499795997969979799798997999980099801998029980399804998059980699807998089980999810998119981299813998149981599816998179981899819998209982199822998239982499825998269982799828998299983099831998329983399834998359983699837998389983999840998419984299843998449984599846998479984899849998509985199852998539985499855998569985799858998599986099861998629986399864998659986699867998689986999870998719987299873998749987599876998779987899879998809988199882998839988499885998869988799888998899989099891998929989399894998959989699897998989989999900999019990299903999049990599906999079990899909999109991199912999139991499915999169991799918999199992099921999229992399924999259992699927999289992999930999319993299933999349993599936999379993899939999409994199942999439994499945999469994799948999499995099951999529995399954999559995699957999589995999960999619996299963999649996599966999679996899969999709997199972999739997499975999769997799978999799998099981999829998399984999859998699987999889998999990999919999299993999949999599996999979999899999100000100001100002100003100004100005100006100007100008100009100010100011100012100013100014100015100016100017100018100019100020100021100022100023100024100025100026100027100028100029100030100031100032100033100034100035100036100037100038100039100040100041100042100043100044100045100046100047100048100049100050100051100052100053100054100055100056100057100058100059100060100061100062100063100064100065100066100067100068100069100070100071100072100073100074100075100076100077100078100079100080100081100082100083100084100085100086100087100088100089100090100091100092100093100094100095100096100097100098100099100100100101100102100103100104100105100106100107100108100109100110100111100112100113100114100115100116100117100118100119100120100121100122100123100124100125100126100127100128100129100130100131100132100133100134100135100136100137100138100139100140100141100142100143100144100145100146100147100148100149100150100151100152100153100154100155100156100157100158100159100160100161100162100163100164100165100166100167100168100169100170100171100172100173100174100175100176100177100178100179100180100181100182100183100184100185100186100187100188100189100190100191100192100193100194100195100196100197100198100199100200100201100202100203100204100205100206100207100208100209100210100211100212100213100214100215100216100217100218100219100220100221100222100223100224100225100226100227100228100229100230100231100232100233100234100235100236100237100238100239100240100241100242100243100244100245100246100247100248100249100250100251100252100253100254100255100256100257100258100259100260100261100262100263100264100265100266100267100268100269100270100271100272100273100274100275100276100277100278100279100280100281100282100283100284100285100286100287100288100289100290100291100292100293100294100295100296100297100298100299100300100301100302100303100304100305100306100307100308100309100310100311100312100313100314100315100316100317100318100319100320100321100322100323100324100325100326100327100328100329100330100331100332100333100334100335100336100337100338100339100340100341100342100343100344100345100346100347100348100349100350100351100352100353100354100355100356100357100358100359100360100361100362100363100364100365100366100367100368100369100370100371100372100373100374100375100376100377100378100379100380100381100382100383100384100385100386100387100388100389100390100391100392100393100394100395100396100397100398100399100400100401100402100403100404100405100406100407100408100409100410100411100412100413100414100415100416100417100418100419100420100421100422100423100424100425100426100427100428100429100430100431100432100433100434100435100436100437100438100439100440100441100442100443100444100445100446100447100448100449100450100451100452100453100454100455100456100457100458100459100460100461100462100463100464100465100466100467100468100469100470100471100472100473100474100475100476100477100478100479100480100481100482100483100484100485100486100487100488100489100490100491100492100493100494100495100496100497100498100499100500100501100502100503100504100505100506100507100508100509100510100511100512100513100514100515100516100517100518100519100520100521100522100523100524100525100526100527100528100529100530100531100532100533100534100535100536100537100538100539100540100541100542100543100544100545100546100547100548100549100550100551100552100553100554100555100556100557100558100559100560100561100562100563100564100565100566100567100568100569100570100571100572100573100574100575100576100577100578100579100580100581100582100583100584100585100586100587100588100589100590100591100592100593100594100595100596100597100598100599100600100601100602100603100604100605100606100607100608100609100610100611100612100613100614100615100616100617100618100619100620100621100622100623100624100625100626100627100628100629100630100631100632100633100634100635100636100637100638100639100640100641100642100643100644100645100646100647100648100649100650100651100652100653100654100655100656100657100658100659100660100661100662100663100664100665100666100667100668100669100670100671100672100673100674100675100676100677100678100679100680100681100682100683100684100685100686100687100688100689100690100691100692100693100694100695100696100697100698100699100700100701100702100703100704100705100706100707100708100709100710100711100712100713100714100715100716100717100718100719100720100721100722100723100724100725100726100727100728100729100730100731100732100733100734100735100736100737100738100739100740100741100742100743100744100745100746100747100748100749100750100751100752100753100754100755100756100757100758100759100760100761100762100763100764100765100766100767100768100769100770100771100772100773100774100775100776100777100778100779100780100781100782100783100784100785100786100787100788100789100790100791100792100793100794100795100796100797100798100799100800100801100802100803100804100805100806100807100808100809100810100811100812100813100814100815100816100817100818100819100820100821100822100823100824100825100826100827100828100829100830100831100832100833100834100835100836100837100838100839100840100841100842100843100844100845100846100847100848100849100850100851100852100853100854100855100856100857100858100859100860100861100862100863100864100865100866100867100868100869100870100871100872100873100874100875100876100877100878100879100880100881100882100883100884100885100886100887100888100889100890100891100892100893100894100895100896100897100898100899100900100901100902100903100904100905100906100907100908100909100910100911100912100913100914100915100916100917100918100919100920100921100922100923100924100925100926100927100928100929100930100931100932100933100934100935100936100937100938100939100940100941100942100943100944100945100946100947100948100949100950100951100952100953100954100955100956100957100958100959100960100961100962100963100964100965100966100967100968100969100970100971100972100973100974100975100976100977100978100979100980100981100982100983100984100985100986100987100988100989100990100991100992100993100994100995100996100997100998100999101000101001101002101003101004101005101006101007101008101009101010101011101012101013101014101015101016101017101018101019101020101021101022101023101024101025101026101027101028101029101030101031101032101033101034101035101036101037101038101039101040101041101042101043101044101045101046101047101048101049101050101051101052101053101054101055101056101057101058101059101060101061101062101063101064101065101066101067101068101069101070101071101072101073101074101075101076101077101078101079101080101081101082101083101084101085101086101087101088101089101090101091101092101093101094101095101096101097101098101099101100101101101102101103101104101105101106101107101108101109101110101111101112101113101114101115101116101117101118101119101120101121101122101123101124101125101126101127101128101129101130101131101132101133101134101135101136101137101138101139101140101141101142101143101144101145101146101147101148101149101150101151101152101153101154101155101156101157101158101159101160101161101162101163101164101165101166101167101168101169101170101171101172101173101174101175101176101177101178101179101180101181101182101183101184101185101186101187101188101189101190101191101192101193101194101195101196101197101198101199101200101201101202101203101204101205101206101207101208101209101210101211101212101213101214101215101216101217101218101219101220101221101222101223101224101225101226101227101228101229101230101231101232101233101234101235101236101237101238101239101240101241101242101243101244101245101246101247101248101249101250101251101252101253101254101255101256101257101258101259101260101261101262101263101264101265101266101267101268101269101270101271101272101273101274101275101276101277101278101279101280101281101282101283101284101285101286101287101288101289101290101291101292101293101294101295101296101297101298101299101300101301101302101303101304101305101306101307101308101309101310101311101312101313101314101315101316101317101318101319101320101321101322101323101324101325101326101327101328101329101330101331101332101333101334101335101336101337101338101339101340101341101342101343101344101345101346101347101348101349101350101351101352101353101354101355101356101357101358101359101360101361101362101363101364101365101366101367101368101369101370101371101372101373101374101375101376101377101378101379101380101381101382101383101384101385101386101387101388101389101390101391101392101393101394101395101396101397101398101399101400101401101402101403101404101405101406101407101408101409101410101411101412101413101414101415101416101417101418101419101420101421101422101423101424101425101426101427101428101429101430101431101432101433101434101435101436101437101438101439101440101441101442101443101444101445101446101447101448101449101450101451101452101453101454101455101456101457101458101459101460101461101462101463101464101465101466101467101468101469101470101471101472101473101474101475101476101477101478101479101480101481101482101483101484101485101486101487101488101489101490101491101492101493101494101495101496101497101498101499101500101501101502101503101504101505101506101507101508101509101510101511101512101513101514101515101516101517101518101519101520101521101522101523101524101525101526101527101528101529101530101531101532101533101534101535101536101537101538101539101540101541101542101543101544101545101546101547101548101549101550101551101552101553101554101555101556101557101558101559101560101561101562101563101564101565101566101567101568101569101570101571101572101573101574101575101576101577101578101579101580101581101582101583101584101585101586101587101588101589101590101591101592101593101594101595101596101597101598101599101600101601101602101603101604101605101606101607101608101609101610101611101612101613101614101615101616101617101618101619101620101621101622101623101624101625101626101627101628101629101630101631101632101633101634101635101636101637101638101639101640101641101642101643101644101645101646101647101648101649101650101651101652101653101654101655101656101657101658101659101660101661101662101663101664101665101666101667101668101669101670101671101672101673101674101675101676101677101678101679101680101681101682101683101684101685101686101687101688101689101690101691101692101693101694101695101696101697101698101699101700101701101702101703101704101705101706101707101708101709101710101711101712101713101714101715101716101717101718101719101720101721101722101723101724101725101726101727101728101729101730101731101732101733101734101735101736101737101738101739101740101741101742101743101744101745101746101747101748101749101750101751101752101753101754101755101756101757101758101759101760101761101762101763101764101765101766101767101768101769101770101771101772101773101774101775101776101777101778101779101780101781101782101783101784101785101786101787101788101789101790101791101792101793101794101795101796101797101798101799101800101801101802101803101804101805101806101807101808101809101810101811101812101813101814101815101816101817101818101819101820101821101822101823101824101825101826101827101828101829101830101831101832101833101834101835101836101837101838101839101840101841101842101843101844101845101846101847101848101849101850101851101852101853101854101855101856101857101858101859101860101861101862101863101864101865101866101867101868101869101870101871101872101873101874101875101876101877101878101879101880101881101882101883101884101885101886101887101888101889101890101891101892101893101894101895101896101897101898101899101900101901101902101903101904101905101906101907101908101909101910101911101912101913101914101915101916101917101918101919101920101921101922101923101924101925101926101927101928101929101930101931101932101933101934101935101936101937101938101939101940101941101942101943101944101945101946101947101948101949101950101951101952101953101954101955101956101957101958101959101960101961101962101963101964101965101966101967101968101969101970101971101972101973101974101975101976101977101978101979101980101981101982101983101984101985101986101987101988101989101990101991101992101993101994101995101996101997101998101999102000102001102002102003102004102005102006102007102008102009102010102011102012102013102014102015102016102017102018102019102020102021102022102023102024102025102026102027102028102029102030102031102032102033102034102035102036102037102038102039102040102041102042102043102044102045102046102047102048102049102050102051102052102053102054102055102056102057102058102059102060102061102062102063102064102065102066102067102068102069102070102071102072102073102074102075102076102077102078102079102080102081102082102083102084102085102086102087102088102089102090102091102092102093102094102095102096102097102098102099102100102101102102102103102104102105102106102107102108102109102110102111102112102113102114102115102116102117102118102119102120102121102122102123102124102125102126102127102128102129102130102131102132102133102134102135102136102137102138102139102140102141102142102143102144102145102146102147102148102149102150102151102152102153102154102155102156102157102158102159102160102161102162102163102164102165102166102167102168102169102170102171102172102173102174102175102176102177102178102179102180102181102182102183102184102185102186102187102188102189102190102191102192102193102194102195102196102197102198102199102200102201102202102203102204102205102206102207102208102209102210102211102212102213102214102215102216102217102218102219102220102221102222102223102224102225102226102227102228102229102230102231102232102233102234102235102236102237102238102239102240102241102242102243102244102245102246102247102248102249102250102251102252102253102254102255102256102257102258102259102260102261102262102263102264102265102266102267102268102269102270102271102272102273102274102275102276102277102278102279102280102281102282102283102284102285102286102287102288102289102290102291102292102293102294102295102296102297102298102299102300102301102302102303102304102305102306102307102308102309102310102311102312102313102314102315102316102317102318102319102320102321102322102323102324102325102326102327102328102329102330102331102332102333102334102335102336102337102338102339102340102341102342102343102344102345102346102347102348102349102350102351102352102353102354102355102356102357102358102359102360102361102362102363102364102365102366102367102368102369102370102371102372102373102374102375102376102377102378102379102380102381102382102383102384102385102386102387102388102389102390102391102392102393102394102395102396102397102398102399102400102401102402102403102404102405102406102407102408102409102410102411102412102413102414102415102416102417102418102419102420102421102422102423102424102425102426102427102428102429102430102431102432102433102434102435102436102437102438102439102440102441102442102443102444102445102446102447102448102449102450102451102452102453102454102455102456102457102458102459102460102461102462102463102464102465102466102467102468102469102470102471102472102473102474102475102476102477102478102479102480102481102482102483102484102485102486102487102488102489102490102491102492102493102494102495102496102497102498102499102500102501102502102503102504102505102506102507102508102509102510102511102512102513102514102515102516102517102518102519102520102521102522102523102524102525102526102527102528102529102530102531102532102533102534102535102536102537102538102539102540102541102542102543102544102545102546102547102548102549102550102551102552102553102554102555102556102557102558102559102560102561102562102563102564102565102566102567102568102569102570102571102572102573102574102575102576102577102578102579102580102581102582102583102584102585102586102587102588102589102590102591102592102593102594102595102596102597102598102599102600102601102602102603102604102605102606102607102608102609102610102611102612102613102614102615102616102617102618102619102620102621102622102623102624102625102626102627102628102629102630102631102632102633102634102635102636102637102638102639102640102641102642102643102644102645102646102647102648102649102650102651102652102653102654102655102656102657102658102659102660102661102662102663102664102665102666102667102668102669102670102671102672102673102674102675102676102677102678102679102680102681102682102683102684102685102686102687102688102689102690102691102692102693102694102695102696102697102698102699102700102701102702102703102704102705102706102707102708102709102710102711102712102713102714102715102716102717102718102719102720102721102722102723102724102725102726102727102728102729102730102731102732102733102734102735102736102737102738102739102740102741102742102743102744102745102746102747102748102749102750102751102752102753102754102755102756102757102758102759102760102761102762102763102764102765102766102767102768102769102770102771102772102773102774102775102776102777102778102779102780102781102782102783102784102785102786102787102788102789102790102791102792102793102794102795102796102797102798102799102800102801102802102803102804102805102806102807102808102809102810102811102812102813102814102815102816102817102818102819102820102821102822102823102824102825102826102827102828102829102830102831102832102833102834102835102836102837102838102839102840102841102842102843102844102845102846102847102848102849102850102851102852102853102854102855102856102857102858102859102860102861102862102863102864102865102866102867102868102869102870102871102872102873102874102875102876102877102878102879102880102881102882102883102884102885102886102887102888102889102890102891102892102893102894102895102896102897102898102899102900102901102902102903102904102905102906102907102908102909102910102911102912102913102914102915102916102917102918102919102920102921102922102923102924102925102926102927102928102929102930102931102932102933102934102935102936102937102938102939102940102941102942102943102944102945102946102947102948102949102950102951102952102953102954102955102956102957102958102959102960102961102962102963102964102965102966102967102968102969102970102971102972102973102974102975102976102977102978102979102980102981102982102983102984102985102986102987102988102989102990102991102992102993102994102995102996102997102998102999103000103001103002103003103004103005103006103007103008103009103010103011103012103013103014103015103016103017103018103019103020103021103022103023103024103025103026103027103028103029103030103031103032103033103034103035103036103037103038103039103040103041103042103043103044103045103046103047103048103049103050103051103052103053103054103055103056103057103058103059103060103061103062103063103064103065103066103067103068103069103070103071103072103073103074103075103076103077103078103079103080103081103082103083103084103085103086103087103088103089103090103091103092103093103094103095103096103097103098103099103100103101103102103103103104103105103106103107103108103109103110103111103112103113103114103115103116103117103118103119103120103121103122103123103124103125103126103127103128103129103130103131103132103133103134103135103136103137103138103139103140103141103142103143103144103145103146103147103148103149103150103151103152103153103154103155103156103157103158103159103160103161103162103163103164103165103166103167103168103169103170103171103172103173103174103175103176103177103178103179103180103181103182103183103184103185103186103187103188103189103190103191103192103193103194103195103196103197103198103199103200103201103202103203103204103205103206103207103208103209103210103211103212103213103214103215103216103217103218103219103220103221103222103223103224103225103226103227103228103229103230103231103232103233103234103235103236103237103238103239103240103241103242103243103244103245103246103247103248103249103250103251103252103253103254103255103256103257103258103259103260103261103262103263103264103265103266103267103268103269103270103271103272103273103274103275103276103277103278103279103280103281103282103283103284103285103286103287103288103289103290103291103292103293103294103295103296103297103298103299103300103301103302103303103304103305103306103307103308103309103310103311103312103313103314103315103316103317103318103319103320103321103322103323103324103325103326103327103328103329103330103331103332103333103334103335103336103337103338103339103340103341103342103343103344103345103346103347103348103349103350103351103352103353103354103355103356103357103358103359103360103361103362103363103364103365103366103367103368103369103370103371103372103373103374103375103376103377103378103379103380103381103382103383103384103385103386103387103388103389103390103391103392103393103394103395103396103397103398103399103400103401103402103403103404103405103406103407103408103409103410103411103412103413103414103415103416103417103418103419103420103421103422103423103424103425103426103427103428103429103430103431103432103433103434103435103436103437103438103439103440103441103442103443103444103445103446103447103448103449103450103451103452103453103454103455103456103457103458103459103460103461103462103463103464103465103466103467103468103469103470103471103472103473103474103475103476103477103478103479103480103481103482103483103484103485103486103487103488103489103490103491103492103493103494103495103496103497103498103499103500103501103502103503103504103505103506103507103508103509103510103511103512103513103514103515103516103517103518103519103520103521103522103523103524103525103526103527103528103529103530103531103532103533103534103535103536103537103538103539103540103541103542103543103544103545103546103547103548103549103550103551103552103553103554103555103556103557103558103559103560103561103562103563103564103565103566103567103568103569103570103571103572103573103574103575103576103577103578103579103580103581103582103583103584103585103586103587103588103589103590103591103592103593103594103595103596103597103598103599103600103601103602103603103604103605103606103607103608103609103610103611103612103613103614103615103616103617103618103619103620103621103622103623103624103625103626103627103628103629103630103631103632103633103634103635103636103637103638103639103640103641103642103643103644103645103646103647103648103649103650103651103652103653103654103655103656103657103658103659103660103661103662103663103664103665103666103667103668103669103670103671103672103673103674103675103676103677103678103679103680103681103682103683103684103685103686103687103688103689103690103691103692103693103694103695103696103697103698103699103700103701103702103703103704103705103706103707103708103709103710103711103712103713103714103715103716103717103718103719103720103721103722103723103724103725103726103727103728103729103730103731103732103733103734103735103736103737103738103739103740103741103742103743103744103745103746103747103748103749103750103751103752103753103754103755103756103757103758103759103760103761103762103763103764103765103766103767103768103769103770103771103772103773103774103775103776103777103778103779103780103781103782103783103784103785103786103787103788103789103790103791103792103793103794103795103796103797103798103799103800103801103802103803103804103805103806103807103808103809103810103811103812103813103814103815103816103817103818103819103820103821103822103823103824103825103826103827103828103829103830103831103832103833103834103835103836103837103838103839103840103841103842103843103844103845103846103847103848103849103850103851103852103853103854103855103856103857103858103859103860103861103862103863103864103865103866103867103868103869103870103871103872103873103874103875103876103877103878103879103880103881103882103883103884103885103886103887103888103889103890103891103892103893103894103895103896103897103898103899103900103901103902103903103904103905103906103907103908103909103910103911103912103913103914103915103916103917103918103919103920103921103922103923103924103925103926103927103928103929103930103931103932103933103934103935103936103937103938103939103940103941103942103943103944103945103946103947103948103949103950103951103952103953103954103955103956103957103958103959103960103961103962103963103964103965103966103967103968103969103970103971103972103973103974103975103976103977103978103979103980103981103982103983103984103985103986103987103988103989103990103991103992103993103994103995103996103997103998103999104000104001104002104003104004104005104006104007104008104009104010104011104012104013104014104015104016104017104018104019104020104021104022104023104024104025104026104027104028104029104030104031104032104033104034104035104036104037104038104039104040104041104042104043104044104045104046104047104048104049104050104051104052104053104054104055104056104057104058104059104060104061104062104063104064104065104066104067104068104069104070104071104072104073104074104075104076104077104078104079104080104081104082104083104084104085104086104087104088104089104090104091104092104093104094104095104096104097104098104099104100104101104102104103104104104105104106104107104108104109104110104111104112104113104114104115104116104117104118104119104120104121104122104123104124104125104126104127104128104129104130104131104132104133104134104135104136104137104138104139104140104141104142104143104144104145104146104147104148104149104150104151104152104153104154104155104156104157104158104159104160104161104162104163104164104165104166104167104168104169104170104171104172104173104174104175104176104177104178104179104180104181104182104183104184104185104186104187104188104189104190104191104192104193104194104195104196104197104198104199104200104201104202104203104204104205104206104207104208104209104210104211104212104213104214104215104216104217104218104219104220104221104222104223104224104225104226104227104228104229104230104231104232104233104234104235104236104237104238104239104240104241104242104243104244104245104246104247104248104249104250104251104252104253104254104255104256104257104258104259104260104261104262104263104264104265104266104267104268104269104270104271104272104273104274104275104276104277104278104279104280104281104282104283104284104285104286104287104288104289104290104291104292104293104294104295104296104297104298104299104300104301104302104303104304104305104306104307104308104309104310104311104312104313104314104315104316104317104318104319104320104321104322104323104324104325104326104327104328104329104330104331104332104333104334104335104336104337104338104339104340104341104342104343104344104345104346104347104348104349104350104351104352104353104354104355104356104357104358104359104360104361104362104363104364104365104366104367104368104369104370104371104372104373104374104375104376104377104378104379104380104381104382104383104384104385104386104387104388104389104390104391104392104393104394104395104396104397104398104399104400104401104402104403104404104405104406104407104408104409104410104411104412104413104414104415104416104417104418104419104420104421104422104423104424104425104426104427104428104429104430104431104432104433104434104435104436104437104438104439104440104441104442104443104444104445104446104447104448104449104450104451104452104453104454104455104456104457104458104459104460104461104462104463104464104465104466104467104468104469104470104471104472104473104474104475104476104477104478104479104480104481104482104483104484104485104486104487104488104489104490104491104492104493104494104495104496104497104498104499104500104501104502104503104504104505104506104507104508104509104510104511104512104513104514104515104516104517104518104519104520104521104522104523104524104525104526104527104528104529104530104531104532104533104534104535104536104537104538104539104540104541104542104543104544104545104546104547104548104549104550104551104552104553104554104555104556104557104558104559104560104561104562104563104564104565104566104567104568104569104570104571104572104573104574104575104576104577104578104579104580104581104582104583104584104585104586104587104588104589104590104591104592104593104594104595104596104597104598104599104600104601104602104603104604104605104606104607104608104609104610104611104612104613104614104615104616104617104618104619104620104621104622104623104624104625104626104627104628104629104630104631104632104633104634104635104636104637104638104639104640104641104642104643104644104645104646104647104648104649104650104651104652104653104654104655104656104657104658104659104660104661104662104663104664104665104666104667104668104669104670104671104672104673104674104675104676104677104678104679104680104681104682104683104684104685104686104687104688104689104690104691104692104693104694104695104696104697104698104699104700104701104702104703104704104705104706104707104708104709104710104711104712104713104714104715104716104717104718104719104720104721104722104723104724104725104726104727104728104729104730104731104732104733104734104735104736104737104738104739104740104741104742104743104744104745104746104747104748104749104750104751104752104753104754104755104756104757104758104759104760104761104762104763104764104765104766104767104768104769104770104771104772104773104774104775104776104777104778104779104780104781104782104783104784104785104786104787104788104789104790104791104792104793104794104795104796104797104798104799104800104801104802104803104804104805104806104807104808104809104810104811104812104813104814104815104816104817104818104819104820104821104822104823104824104825104826104827104828104829104830104831104832104833104834104835104836104837104838104839104840104841104842104843104844104845104846104847104848104849104850104851104852104853104854104855104856104857104858104859104860104861104862104863104864104865104866104867104868104869104870104871104872104873104874104875104876104877104878104879104880104881104882104883104884104885104886104887104888104889104890104891104892104893104894104895104896104897104898104899104900104901104902104903104904104905104906104907104908104909104910104911104912104913104914104915104916104917104918104919104920104921104922104923104924104925104926104927104928104929104930104931104932104933104934104935104936104937104938104939104940104941104942104943104944104945104946104947104948104949104950104951104952104953104954104955104956104957104958104959104960104961104962104963104964104965104966104967104968104969104970104971104972104973104974104975104976104977104978104979104980104981104982104983104984104985104986104987104988104989104990104991104992104993104994104995104996104997104998104999105000105001105002105003105004105005105006105007105008105009105010105011105012105013105014105015105016105017105018105019105020105021105022105023105024105025105026105027105028105029105030105031105032105033105034105035105036105037105038105039105040105041105042105043105044105045105046105047105048105049105050105051105052105053105054105055105056105057105058105059105060105061105062105063105064105065105066105067105068105069105070105071105072105073105074105075105076105077105078105079105080105081105082105083105084105085105086105087105088105089105090105091105092105093105094105095105096105097105098105099105100105101105102105103105104105105105106105107105108105109105110105111105112105113105114105115105116105117105118105119105120105121105122105123105124105125105126105127105128105129105130105131105132105133105134105135105136105137105138105139105140105141105142105143105144105145105146105147105148105149105150105151105152105153105154105155105156105157105158105159105160105161105162105163105164105165105166105167105168105169105170105171105172105173105174105175105176105177105178105179105180105181105182105183105184105185105186105187105188105189105190105191105192105193105194105195105196105197105198105199105200105201105202105203105204105205105206105207105208105209105210105211105212105213105214105215105216105217105218105219105220105221105222105223105224105225105226105227105228105229105230105231105232105233105234105235105236105237105238105239105240105241105242105243105244105245105246105247105248105249105250105251105252105253105254105255105256105257105258105259105260105261105262105263105264105265105266105267105268105269105270105271105272105273105274105275105276105277105278105279105280105281105282105283105284105285105286105287105288105289105290105291105292105293105294105295105296105297105298105299105300105301105302105303105304105305105306105307105308105309105310105311105312105313105314105315105316105317105318105319105320105321105322105323105324105325105326105327105328105329105330105331105332105333105334105335105336105337105338105339105340105341105342105343105344105345105346105347105348105349105350105351105352105353105354105355105356105357105358105359105360105361105362105363105364105365105366105367105368105369105370105371105372105373105374105375105376105377105378105379105380105381105382105383105384105385105386105387105388105389105390105391105392105393105394105395105396105397105398105399105400105401105402105403105404105405105406105407105408105409105410105411105412105413105414105415105416105417105418105419105420105421105422105423105424105425105426105427105428105429105430105431105432105433105434105435105436105437105438105439105440105441105442105443105444105445105446105447105448105449105450105451105452105453105454105455105456105457105458105459105460105461105462105463105464105465105466105467105468105469105470105471105472105473105474105475105476105477105478105479105480105481105482105483105484105485105486105487105488105489105490105491105492105493105494105495105496105497105498105499105500105501105502105503105504105505105506105507105508105509105510105511105512105513105514105515105516105517105518105519105520105521105522105523105524105525105526105527105528105529105530105531105532105533105534105535105536105537105538105539105540105541105542105543105544105545105546105547105548105549105550105551105552105553105554105555105556105557105558105559105560105561105562105563105564105565105566105567105568105569105570105571105572105573105574105575105576105577105578105579105580105581105582105583105584105585105586105587105588105589105590105591105592105593105594105595105596105597105598105599105600105601105602105603105604105605105606105607105608105609105610105611105612105613105614105615105616105617105618105619105620105621105622105623105624105625105626105627105628105629105630105631105632105633105634105635105636105637105638105639105640105641105642105643105644105645105646105647105648105649105650105651105652105653105654105655105656105657105658105659105660105661105662105663105664105665105666105667105668105669105670105671105672105673105674105675105676105677105678105679105680105681105682105683105684105685105686105687105688105689105690105691105692105693105694105695105696105697105698105699105700105701105702105703105704105705105706105707105708105709105710105711105712105713105714105715105716105717105718105719105720105721105722105723105724105725105726105727105728105729105730105731105732105733105734105735105736105737105738105739105740105741105742105743105744105745105746105747105748105749105750105751105752105753105754105755105756105757105758105759105760105761105762105763105764105765105766105767105768105769105770105771105772105773105774105775105776105777105778105779105780105781105782105783105784105785105786105787105788105789105790105791105792105793105794105795105796105797105798105799105800105801105802105803105804105805105806105807105808105809105810105811105812105813105814105815105816105817105818105819105820105821105822105823105824105825105826105827105828105829105830105831105832105833105834105835105836105837105838105839105840105841105842105843105844105845105846105847105848105849105850105851105852105853105854105855105856105857105858105859105860105861105862105863105864105865105866105867105868105869105870105871105872105873105874105875105876105877105878105879105880105881105882105883105884105885105886105887105888105889105890105891105892105893105894105895105896105897105898105899105900105901105902105903105904105905105906105907105908105909105910105911105912105913105914105915105916105917105918105919105920105921105922105923105924105925105926105927105928105929105930105931105932105933105934105935105936105937105938105939105940105941105942105943105944105945105946105947105948105949105950105951105952105953105954105955105956105957105958105959105960105961105962105963105964105965105966105967105968105969105970105971105972105973105974105975105976105977105978105979105980105981105982105983105984105985105986105987105988105989105990105991105992105993105994105995105996105997105998105999106000106001106002106003106004106005106006106007106008106009106010106011106012106013106014106015106016106017106018106019106020106021106022106023106024106025106026106027106028106029106030106031106032106033106034106035106036106037106038106039106040106041106042106043106044106045106046106047106048106049106050106051106052106053106054106055106056106057106058106059106060106061106062106063106064106065106066106067106068106069106070106071106072106073106074106075106076106077106078106079106080106081106082106083106084106085106086106087106088106089106090106091106092106093106094106095106096106097106098106099106100106101106102106103106104106105106106106107106108106109106110106111106112106113106114106115106116106117106118106119106120106121106122106123106124106125106126106127106128106129106130106131106132106133106134106135106136106137106138106139106140106141106142106143106144106145106146106147106148106149106150106151106152106153106154106155106156106157106158106159106160106161106162106163106164106165106166106167106168106169106170106171106172106173106174106175106176106177106178106179106180106181106182106183106184106185106186106187106188106189106190106191106192106193106194106195106196106197106198106199106200106201106202106203106204106205106206106207106208106209106210106211106212106213106214106215106216106217106218106219106220106221106222106223106224106225106226106227106228106229106230106231106232106233106234106235106236106237106238106239106240106241106242106243106244106245106246106247106248106249106250106251106252106253106254106255106256106257106258106259106260106261106262106263106264106265106266106267106268106269106270106271106272106273106274106275106276106277106278106279106280106281106282106283106284106285106286106287106288106289106290106291106292106293106294106295106296106297106298106299106300106301106302106303106304106305106306106307106308106309106310106311106312106313106314106315106316106317106318106319106320106321106322106323106324106325106326106327106328106329106330106331106332106333106334106335106336106337106338106339106340106341106342106343106344106345106346106347106348106349106350106351106352106353106354106355106356106357106358106359106360106361106362106363106364106365106366106367106368106369106370106371106372106373106374106375106376106377106378106379106380106381106382106383106384106385106386106387106388106389106390106391106392106393106394106395106396106397106398106399106400106401106402106403106404106405106406106407106408106409106410106411106412106413106414106415106416106417106418106419106420106421106422106423106424106425106426106427106428106429106430106431106432106433106434106435106436106437106438106439106440106441106442106443106444106445106446106447106448106449106450106451106452106453106454106455106456106457106458106459106460106461106462106463106464106465106466106467106468106469106470106471106472106473106474106475106476106477106478106479106480106481106482106483106484106485106486106487106488106489106490106491106492106493106494106495106496106497106498106499106500106501106502106503106504106505106506106507106508106509106510106511106512106513106514106515106516106517106518106519106520106521106522106523106524106525106526106527106528106529106530106531106532106533106534106535106536106537106538106539106540106541106542106543106544106545106546106547106548106549106550106551106552106553106554106555106556106557106558106559106560106561106562106563106564106565106566106567106568106569106570106571106572106573106574106575106576106577106578106579106580106581106582106583106584106585106586106587106588106589106590106591106592106593106594106595106596106597106598106599106600106601106602106603106604106605106606106607106608106609106610106611106612106613106614106615106616106617106618106619106620106621106622106623106624106625106626106627106628106629106630106631106632106633106634106635106636106637106638106639106640106641106642106643106644106645106646106647106648106649106650106651106652106653106654106655106656106657106658106659106660106661106662106663106664106665106666106667106668106669106670106671106672106673106674106675106676106677106678106679106680106681106682106683106684106685106686106687106688106689106690106691106692106693106694106695106696106697106698106699106700106701106702106703106704106705106706106707106708106709106710106711106712106713106714106715106716106717106718106719106720106721106722106723106724106725106726106727106728106729106730106731106732106733106734106735106736106737106738106739106740106741106742106743106744106745106746106747106748106749106750106751106752106753106754106755106756106757106758106759106760106761106762106763106764106765106766106767106768106769106770106771106772106773106774106775106776106777106778106779106780106781106782106783106784106785106786106787106788106789106790106791106792106793106794106795106796106797106798106799106800106801106802106803106804106805106806106807106808106809106810106811106812106813106814106815106816106817106818106819106820106821106822106823106824106825106826106827106828106829106830106831106832106833106834106835106836106837106838106839106840106841106842106843106844106845106846106847106848106849106850106851106852106853106854106855106856106857106858106859106860106861106862106863106864106865106866106867106868106869106870106871106872106873106874106875106876106877106878106879106880106881106882106883106884106885106886106887106888106889106890106891106892106893106894106895106896106897106898106899106900106901106902106903106904106905106906106907106908106909106910106911106912106913106914106915106916106917106918106919106920106921106922106923106924106925106926106927106928106929106930106931106932106933106934106935106936106937106938106939106940106941106942106943106944106945106946106947106948106949106950106951106952106953106954106955106956106957106958106959106960106961106962106963106964106965106966106967106968106969106970106971106972106973106974106975106976106977106978106979106980106981106982106983106984106985106986106987106988106989106990106991106992106993106994106995106996106997106998106999107000107001107002107003107004107005107006107007107008107009107010107011107012107013107014107015107016107017107018107019107020107021107022107023107024107025107026107027107028107029107030107031107032107033107034107035107036107037107038107039107040107041107042107043107044107045107046107047107048107049107050107051107052107053107054107055107056107057107058107059107060107061107062107063107064107065107066107067107068107069107070107071107072107073107074107075107076107077107078107079107080107081107082107083107084107085107086107087107088107089107090107091107092107093107094107095107096107097107098107099107100107101107102107103107104107105107106107107107108107109107110107111107112107113107114107115107116107117107118107119107120107121107122107123107124107125107126107127107128107129107130107131107132107133107134107135107136107137107138107139107140107141107142107143107144107145107146107147107148107149107150107151107152107153107154107155107156107157107158107159107160107161107162107163107164107165107166107167107168107169107170107171107172107173107174107175107176107177107178107179107180107181107182107183107184107185107186107187107188107189107190107191107192107193107194107195107196107197107198107199107200107201107202107203107204107205107206107207107208107209107210107211107212107213107214107215107216107217107218107219107220107221107222107223107224107225107226107227107228107229107230107231107232107233107234107235107236107237107238107239107240107241107242107243107244107245107246107247107248107249107250107251107252107253107254107255107256107257107258107259107260107261107262107263107264107265107266107267107268107269107270107271107272107273107274107275107276107277107278107279107280107281107282107283107284107285107286107287107288107289107290107291107292107293107294107295107296107297107298107299107300107301107302107303107304107305107306107307107308107309107310107311107312107313107314107315107316107317107318107319107320107321107322107323107324107325107326107327107328107329107330107331107332107333107334107335107336107337107338107339107340107341107342107343107344107345107346107347107348107349107350107351107352107353107354107355107356107357107358107359107360107361107362107363107364107365107366107367107368107369107370107371107372107373107374107375107376107377107378107379107380107381107382107383107384107385107386107387107388107389107390107391107392107393107394107395107396107397107398107399107400107401107402107403107404107405107406107407107408107409107410107411107412107413107414107415107416107417107418107419107420107421107422107423107424107425107426107427107428107429107430107431107432107433107434107435107436107437107438107439107440107441107442107443107444107445107446107447107448107449107450107451107452107453107454107455107456107457107458107459107460107461107462107463107464107465107466107467107468107469107470107471107472107473107474107475107476107477107478107479107480107481107482107483107484107485107486107487107488107489107490107491107492107493107494107495107496107497107498107499107500107501107502107503107504107505107506107507107508107509107510107511107512107513107514107515107516107517107518107519107520107521107522107523107524107525107526107527107528107529107530107531107532107533107534107535107536107537107538107539107540107541107542107543107544107545107546107547107548107549107550107551107552107553107554107555107556107557107558107559107560107561107562107563107564107565107566107567107568107569107570107571107572107573107574107575107576107577107578107579107580107581107582107583107584107585107586107587107588107589107590107591107592107593107594107595107596107597107598107599107600107601107602107603107604107605107606107607107608107609107610107611107612107613107614107615107616107617107618107619107620107621107622107623107624107625107626107627107628107629107630107631107632107633107634107635107636107637107638107639107640107641107642107643107644107645107646107647107648107649107650107651107652107653107654107655107656107657107658107659107660107661107662107663107664107665107666107667107668107669107670107671107672107673107674107675107676107677107678107679107680107681107682107683107684107685107686107687107688107689107690107691107692107693107694107695107696107697107698107699107700107701107702107703107704107705107706107707107708107709107710107711107712107713107714107715107716107717107718107719107720107721107722107723107724107725107726107727107728107729107730107731107732107733107734107735107736107737107738107739107740107741107742107743107744107745107746107747107748107749107750107751107752107753107754107755107756107757107758107759107760107761107762107763107764107765107766107767107768107769107770107771107772107773107774107775107776107777107778107779107780107781107782107783107784107785107786107787107788107789107790107791107792107793107794107795107796107797107798107799107800107801107802107803107804107805107806107807107808107809107810107811107812107813107814107815107816107817107818107819107820107821107822107823107824107825107826107827107828107829107830107831107832107833107834107835107836107837107838107839107840107841107842107843107844107845107846107847107848107849107850107851107852107853107854107855107856107857107858107859107860107861107862107863107864107865107866107867107868107869107870107871107872107873107874107875107876107877107878107879107880107881107882107883107884107885107886107887107888107889107890107891107892107893107894107895107896107897107898107899107900107901107902107903107904107905107906107907107908107909107910107911107912107913107914107915107916107917107918107919107920107921107922107923107924107925107926107927107928107929107930107931107932107933107934107935107936107937107938107939107940107941107942107943107944107945107946107947107948107949107950107951107952107953107954107955107956107957107958107959107960107961107962107963107964107965107966107967107968107969107970107971107972107973107974107975107976107977107978107979107980107981107982107983107984107985107986107987107988107989107990107991107992107993107994107995107996107997107998107999108000108001108002108003108004108005108006108007108008108009108010108011108012108013108014108015108016108017108018108019108020108021108022108023108024108025108026108027108028108029108030108031108032108033108034108035108036108037108038108039108040108041108042108043108044108045108046108047108048108049108050108051108052108053108054108055108056108057108058108059108060108061108062108063108064108065108066108067108068108069108070108071108072108073108074108075108076108077108078108079108080108081108082108083108084108085108086108087108088108089108090108091108092108093108094108095108096108097108098108099108100108101108102108103108104108105108106108107108108108109108110108111108112108113108114108115108116108117108118108119108120108121108122108123108124108125108126108127108128108129108130108131108132108133108134108135108136108137108138108139108140108141108142108143108144108145108146108147108148108149108150108151108152108153108154108155108156108157108158108159108160108161108162108163108164108165108166108167108168108169108170108171108172108173108174108175108176108177108178108179108180108181108182108183108184108185108186108187108188108189108190108191108192108193108194108195108196108197108198108199108200108201108202108203108204108205108206108207108208108209108210108211108212108213108214108215108216108217108218108219108220108221108222108223108224108225108226108227108228108229108230108231108232108233108234108235108236108237108238108239108240108241108242108243108244108245108246108247108248108249108250108251108252108253108254108255108256108257108258108259108260108261108262108263108264108265108266108267108268108269108270108271108272108273108274108275108276108277108278108279108280108281108282108283108284108285108286108287108288108289108290108291108292108293108294108295108296108297108298108299108300108301108302108303108304108305108306108307108308108309108310108311108312108313108314108315108316108317108318108319108320108321108322108323108324108325108326108327108328108329108330108331108332108333108334108335108336108337108338108339108340108341108342108343108344108345108346108347108348108349108350108351108352108353108354108355108356108357108358108359108360108361108362108363108364108365108366108367108368108369108370108371108372108373108374108375108376108377108378108379108380108381108382108383108384108385108386108387108388108389108390108391108392108393108394108395108396108397108398108399108400108401108402108403108404108405108406108407108408108409108410108411108412108413108414108415108416108417108418108419108420108421108422108423108424108425108426108427108428108429108430108431108432108433108434108435108436108437108438108439108440108441108442108443108444108445108446108447108448108449108450108451108452108453108454108455108456108457108458108459108460108461108462108463108464108465108466108467108468108469108470108471108472108473108474108475108476108477108478108479108480108481108482108483108484108485108486108487108488108489108490108491108492108493108494108495108496108497108498108499108500108501108502108503108504108505108506108507108508108509108510108511108512108513108514108515108516108517108518108519108520108521108522108523108524108525108526108527108528108529108530108531108532108533108534108535108536108537108538108539108540108541108542108543108544108545108546108547108548108549108550108551108552108553108554108555108556108557108558108559108560108561108562108563108564108565108566108567108568108569108570108571108572108573108574108575108576108577108578108579108580108581108582108583108584108585108586108587108588108589108590108591108592108593108594108595108596108597108598108599108600108601108602108603108604108605108606108607108608108609108610108611108612108613108614108615108616108617108618108619108620108621108622108623108624108625108626108627108628108629108630108631108632108633108634108635108636108637108638108639108640108641108642108643108644108645108646108647108648108649108650108651108652108653108654108655108656108657108658108659108660108661108662108663108664108665108666108667108668108669108670108671108672108673108674108675108676108677108678108679108680108681108682108683108684108685108686108687108688108689108690108691108692108693108694108695108696108697108698108699108700108701108702108703108704108705108706108707108708108709108710108711108712108713108714108715108716108717108718108719108720108721108722108723108724108725108726108727108728108729108730108731108732108733108734108735108736108737108738108739108740108741108742108743108744108745108746108747108748108749108750108751108752108753108754108755108756108757108758108759108760108761108762108763108764108765108766108767108768108769108770108771108772108773108774108775108776108777108778108779108780108781108782108783108784108785108786108787108788108789108790108791108792108793108794108795108796108797108798108799108800108801108802108803108804108805108806108807108808108809108810108811108812108813108814108815108816108817108818108819108820108821108822108823108824108825108826108827108828108829108830108831108832108833108834108835108836108837108838108839108840108841108842108843108844108845108846108847108848108849108850108851108852108853108854108855108856108857108858108859108860108861108862108863108864108865108866108867108868108869108870108871108872108873108874108875108876108877108878108879108880108881108882108883108884108885108886108887108888108889108890108891108892108893108894108895108896108897108898108899108900108901108902108903108904108905108906108907108908108909108910108911108912108913108914108915108916108917108918108919108920108921108922108923108924108925108926108927108928108929108930108931108932108933108934108935108936108937108938108939108940108941108942108943108944108945108946108947108948108949108950108951108952108953108954108955108956108957108958108959108960108961108962108963108964108965108966108967108968108969108970108971108972108973108974108975108976108977108978108979108980108981108982108983108984108985108986108987108988108989108990108991108992108993108994108995108996108997108998108999109000109001109002109003109004109005109006109007109008109009109010109011109012109013109014109015109016109017109018109019109020109021109022109023109024109025109026109027109028109029109030109031109032109033109034109035109036109037109038109039109040109041109042109043109044109045109046109047109048109049109050109051109052109053109054109055109056109057109058109059109060109061109062109063109064109065109066109067109068109069109070109071109072109073109074109075109076109077109078109079109080109081109082109083109084109085109086109087109088109089109090109091109092109093109094109095109096109097109098109099109100109101109102109103109104109105109106109107109108109109109110109111109112109113109114109115109116109117109118109119109120109121109122109123109124109125109126109127109128109129109130109131109132109133109134109135109136109137109138109139109140109141109142109143109144109145109146109147109148109149109150109151109152109153109154109155109156109157109158109159109160109161109162109163109164109165109166109167109168109169109170109171109172109173109174109175109176109177109178109179109180109181109182109183109184109185109186109187109188109189109190109191109192109193109194109195109196109197109198109199109200109201109202109203109204109205109206109207109208109209109210109211109212109213109214109215109216109217109218109219109220109221109222109223109224109225109226109227109228109229109230109231109232109233109234109235109236109237109238109239109240109241109242109243109244109245109246109247109248109249109250109251109252109253109254109255109256109257109258109259109260109261109262109263109264109265109266109267109268109269109270109271109272109273109274109275109276109277109278109279109280109281109282109283109284109285109286109287109288109289109290109291109292109293109294109295109296109297109298109299109300109301109302109303109304109305109306109307109308109309109310109311109312109313109314109315109316109317109318109319109320109321109322109323109324109325109326109327109328109329109330109331109332109333109334109335109336109337109338109339109340109341109342109343109344109345109346109347109348109349109350109351109352109353109354109355109356109357109358109359109360109361109362109363109364109365109366109367109368109369109370109371109372109373109374109375109376109377109378109379109380109381109382109383109384109385109386109387109388109389109390109391109392109393109394109395109396109397109398109399109400109401109402109403109404109405109406109407109408109409109410109411109412109413109414109415109416109417109418109419109420109421109422109423109424109425109426109427109428109429109430109431109432109433109434109435109436109437109438109439109440109441109442109443109444109445109446109447109448109449109450109451109452109453109454109455109456109457109458109459109460109461109462109463109464109465109466109467109468109469109470109471109472109473109474109475109476109477109478109479109480109481109482109483109484109485109486109487109488109489109490109491109492109493109494109495109496109497109498109499109500109501109502109503109504109505109506109507109508109509109510109511109512109513109514109515109516109517109518109519109520109521109522109523109524109525109526109527109528109529109530109531109532109533109534109535109536109537109538109539109540109541109542109543109544109545109546109547109548109549109550109551109552109553109554109555109556109557109558109559109560109561109562109563109564109565109566109567109568109569109570109571109572109573109574109575109576109577109578109579109580109581109582109583109584109585109586109587109588109589109590109591109592109593109594109595109596109597109598109599109600109601109602109603109604109605109606109607109608109609109610109611109612109613109614109615109616109617109618109619109620109621109622109623109624109625109626109627109628109629109630109631109632109633109634109635109636109637109638109639109640109641109642109643109644109645109646109647109648109649109650109651109652109653109654109655109656109657109658109659109660109661109662109663109664109665109666109667109668109669109670109671109672109673109674109675109676109677109678109679109680109681109682109683109684109685109686109687109688109689109690109691109692109693109694109695109696109697109698109699109700109701109702109703109704109705109706109707109708109709109710109711109712109713109714109715109716109717109718109719109720109721109722109723109724109725109726109727109728109729109730109731109732109733109734109735109736109737109738109739109740109741109742109743109744109745109746109747109748109749109750109751109752109753109754109755109756109757109758109759109760109761109762109763109764109765109766109767109768109769109770109771109772109773109774109775109776109777109778109779109780109781109782109783109784109785109786109787109788109789109790109791109792109793109794109795109796109797109798109799109800109801109802109803109804109805109806109807109808109809109810109811109812109813109814109815109816109817109818109819109820109821109822109823109824109825109826109827109828109829109830109831109832109833109834109835109836109837109838109839109840109841109842109843109844109845109846109847109848109849109850109851109852109853109854109855109856109857109858109859109860109861109862109863109864109865109866109867109868109869109870109871109872109873109874109875109876109877109878109879109880109881109882109883109884109885109886109887109888109889109890109891109892109893109894109895109896109897109898109899109900109901109902109903109904109905109906109907109908109909109910109911109912109913109914109915109916109917109918109919109920109921109922109923109924109925109926109927109928109929109930109931109932109933109934109935109936109937109938109939109940109941109942109943109944109945109946109947109948109949109950109951109952109953109954109955109956109957109958109959109960109961109962109963109964109965109966109967109968109969109970109971109972109973109974109975109976109977109978109979109980109981109982109983109984109985109986109987109988109989109990109991109992109993109994109995109996109997109998109999110000110001110002110003110004110005110006110007110008110009110010110011110012110013110014110015110016110017110018110019110020110021110022110023110024110025110026110027110028110029110030110031110032110033110034110035110036110037110038110039110040110041110042110043110044110045110046110047110048110049110050110051110052110053110054110055110056110057110058110059110060110061110062110063110064110065110066110067110068110069110070110071110072110073110074110075110076110077110078110079110080110081110082110083110084110085110086110087110088110089110090110091110092110093110094110095110096110097110098110099110100110101110102110103110104110105110106110107110108110109110110110111110112110113110114110115110116110117110118110119110120110121110122110123110124110125110126110127110128110129110130110131110132110133110134110135110136110137110138110139110140110141110142110143110144110145110146110147110148110149110150110151110152110153110154110155110156110157110158110159110160110161110162110163110164110165110166110167110168110169110170110171110172110173110174110175110176110177110178110179110180110181110182110183110184110185110186110187110188110189110190110191110192110193110194110195110196110197110198110199110200110201110202110203110204110205110206110207110208110209110210110211110212110213110214110215110216110217110218110219110220110221110222110223110224110225110226110227110228110229110230110231110232110233110234110235110236110237110238110239110240110241110242110243110244110245110246110247110248110249110250110251110252110253110254110255110256110257110258110259110260110261110262110263110264110265110266110267110268110269110270110271110272110273110274110275110276110277110278110279110280110281110282110283110284110285110286110287110288110289110290110291110292110293110294110295110296110297110298110299110300110301110302110303110304110305110306110307110308110309110310110311110312110313110314110315110316110317110318110319110320110321110322110323110324110325110326110327110328110329110330110331110332110333110334110335110336110337110338110339110340110341110342110343110344110345110346110347110348110349110350110351110352110353110354110355110356110357110358110359110360110361110362110363110364110365110366110367110368110369110370110371110372110373110374110375110376110377110378110379110380110381110382110383110384110385110386110387110388110389110390110391110392110393110394110395110396110397110398110399110400110401110402110403110404110405110406110407110408110409110410110411110412110413110414110415110416110417110418110419110420110421110422110423110424110425110426110427110428110429110430110431110432110433110434110435110436110437110438110439110440110441110442110443110444110445110446110447110448110449110450110451110452110453110454110455110456110457110458110459110460110461110462110463110464110465110466110467110468110469110470110471110472110473110474110475110476110477110478110479110480110481110482110483110484110485110486110487110488110489110490110491110492110493110494110495110496110497110498110499110500110501110502110503110504110505110506110507110508110509110510110511110512110513110514110515110516110517110518110519110520110521110522110523110524110525110526110527110528110529110530110531110532110533110534110535110536110537110538110539110540110541110542110543110544110545110546110547110548110549110550110551110552110553110554110555110556110557110558110559110560110561110562110563110564110565110566110567110568110569110570110571110572110573110574110575110576110577110578110579110580110581110582110583110584110585110586110587110588110589110590110591110592110593110594110595110596110597110598110599110600110601110602110603110604110605110606110607110608110609110610110611110612110613110614110615110616110617110618110619110620110621110622110623110624110625110626110627110628110629110630110631110632110633110634110635110636110637110638110639110640110641110642110643110644110645110646110647110648110649110650110651110652110653110654110655110656110657110658110659110660110661110662110663110664110665110666110667110668110669110670110671110672110673110674110675110676110677110678110679110680110681110682110683110684110685110686110687110688110689110690110691110692110693110694110695110696110697110698110699110700110701110702110703110704110705110706110707110708110709110710110711110712110713110714110715110716110717110718110719110720110721110722110723110724110725110726110727110728110729110730110731110732110733110734110735110736110737110738110739110740110741110742110743110744110745110746110747110748110749110750110751110752110753110754110755110756110757110758110759110760110761110762110763110764110765110766110767110768110769110770110771110772110773110774110775110776110777110778110779110780110781110782110783110784110785110786110787110788110789110790110791110792110793110794110795110796110797110798110799110800110801110802110803110804110805110806110807110808110809110810110811110812110813110814110815110816110817110818110819110820110821110822110823110824110825110826110827110828110829110830110831110832110833110834110835110836110837110838110839110840110841110842110843110844110845110846110847110848110849110850110851110852110853110854110855110856110857110858110859110860110861110862110863110864110865110866110867110868110869110870110871110872110873110874110875110876110877110878110879110880110881110882110883110884110885110886110887110888110889110890110891110892110893110894110895110896110897110898110899110900110901110902110903110904110905110906110907110908110909110910110911110912110913110914110915110916110917110918110919110920110921110922110923110924110925110926110927110928110929110930110931110932110933110934110935110936110937110938110939110940110941110942110943110944110945110946110947110948110949110950110951110952110953110954110955110956110957110958110959110960110961110962110963110964110965110966110967110968110969110970110971110972110973110974110975110976110977110978110979110980110981110982110983110984110985110986110987110988110989110990110991110992110993110994110995110996110997110998110999111000111001111002111003111004111005111006111007111008111009111010111011111012111013111014111015111016111017111018111019111020111021111022111023111024111025111026111027111028111029111030111031111032111033111034111035111036111037111038111039111040111041111042111043111044111045111046111047111048111049111050111051111052111053111054111055111056111057111058111059111060111061111062111063111064111065111066111067111068111069111070111071111072111073111074111075111076111077111078111079111080111081111082111083111084111085111086111087111088111089111090111091111092111093111094111095111096111097111098111099111100111101111102111103111104111105111106111107111108111109111110111111111112111113111114111115111116111117111118111119111120111121111122111123111124111125111126111127111128111129111130111131111132111133111134111135111136111137111138111139111140111141111142111143111144111145111146111147111148111149111150111151111152111153111154111155111156111157111158111159111160111161111162111163111164111165111166111167111168111169111170111171111172111173111174111175111176111177111178111179111180111181111182111183111184111185111186111187111188111189111190111191111192111193111194111195111196111197111198111199111200111201111202111203111204111205111206111207111208111209111210111211111212111213111214111215111216111217111218111219111220111221111222111223111224111225111226111227111228111229111230111231111232111233111234111235111236111237111238111239111240111241111242111243111244111245111246111247111248111249111250111251111252111253111254111255111256111257111258111259111260111261111262111263111264111265111266111267111268111269111270111271111272111273111274111275111276111277111278111279111280111281111282111283111284111285111286111287111288111289111290111291111292111293111294111295111296111297111298111299111300111301111302111303111304111305111306111307111308111309111310111311111312111313111314111315111316111317111318111319111320111321111322111323111324111325111326111327111328111329111330111331111332111333111334111335111336111337111338111339111340111341111342111343111344111345111346111347111348111349111350111351111352111353111354111355111356111357111358111359111360111361111362111363111364111365111366111367111368111369111370111371111372111373111374111375111376111377111378111379111380111381111382111383111384111385111386111387111388111389111390111391111392111393111394111395111396111397111398111399111400111401111402111403111404111405111406111407111408111409111410111411111412111413111414111415111416111417111418111419111420111421111422111423111424111425111426111427111428111429111430111431111432111433111434111435111436111437111438111439111440111441111442111443111444111445111446111447111448111449111450111451111452111453111454111455111456111457111458111459111460111461111462111463111464111465111466111467111468111469111470111471111472111473111474111475111476111477111478111479111480111481111482111483111484111485111486111487111488111489111490111491111492111493111494111495111496111497111498111499111500111501111502111503111504111505111506111507111508111509111510111511111512111513111514111515111516111517111518111519111520111521111522111523111524111525111526111527111528111529111530111531111532111533111534111535111536111537111538111539111540111541111542111543111544111545111546111547111548111549111550111551111552111553111554111555111556111557111558111559111560111561111562111563111564111565111566111567111568111569111570111571111572111573111574111575111576111577111578111579111580111581111582111583111584111585111586111587111588111589111590111591111592111593111594111595111596111597111598111599111600111601111602111603111604111605111606111607111608111609111610111611111612111613111614111615111616111617111618111619111620111621111622111623111624111625111626111627111628111629111630111631111632111633111634111635111636111637111638111639111640111641111642111643111644111645111646111647111648111649111650111651111652111653111654111655111656111657111658111659111660111661111662111663111664111665111666111667111668111669111670111671111672111673111674111675111676111677111678111679111680111681111682111683111684111685111686111687111688111689111690111691111692111693111694111695111696111697111698111699111700111701111702111703111704111705111706111707111708111709111710111711111712111713111714111715111716111717111718111719111720111721111722111723111724111725111726111727111728111729111730111731111732111733111734111735111736111737111738111739111740111741111742111743111744111745111746111747111748111749111750111751111752111753111754111755111756111757111758111759111760111761111762111763111764111765111766111767111768111769111770111771111772111773111774111775111776111777111778111779111780111781111782111783111784111785111786111787111788111789111790111791111792111793111794111795111796111797111798111799111800111801111802111803111804111805111806111807111808111809111810111811111812111813111814111815111816111817111818111819111820111821111822111823111824111825111826111827111828111829111830111831111832111833111834111835111836111837111838111839111840111841111842111843111844111845111846111847111848111849111850111851111852111853111854111855111856111857111858111859111860111861111862111863111864111865111866111867111868111869111870111871111872111873111874111875111876111877111878111879111880111881111882111883111884111885111886111887111888111889111890111891111892111893111894111895111896111897111898111899111900111901111902111903111904111905111906111907111908111909111910111911111912111913111914111915111916111917111918111919111920111921111922111923111924111925111926111927111928111929111930111931111932111933111934111935111936111937111938111939111940111941111942111943111944111945111946111947111948111949111950111951111952111953111954111955111956111957111958111959111960111961111962111963111964111965111966111967111968111969111970111971111972111973111974111975111976111977111978111979111980111981111982111983111984111985111986111987111988111989111990111991111992111993111994111995111996111997111998111999112000112001112002112003112004112005112006112007112008112009112010112011112012112013112014112015112016112017112018112019112020112021112022112023112024112025112026112027112028112029112030112031112032112033112034112035112036112037112038112039112040112041112042112043112044112045112046112047112048112049112050112051112052112053112054112055112056112057112058112059112060112061112062112063112064112065112066112067112068112069112070112071112072112073112074112075112076112077112078112079112080112081112082112083112084112085112086112087112088112089112090112091112092112093112094112095112096112097112098112099112100112101112102112103112104112105112106112107112108112109112110112111112112112113112114112115112116112117112118112119112120112121112122112123112124112125112126112127112128112129112130112131112132112133112134112135112136112137112138112139112140112141112142112143112144112145112146112147112148112149112150112151112152112153112154112155112156112157112158112159112160112161112162112163112164112165112166112167112168112169112170112171112172112173112174112175112176112177112178112179112180112181112182112183112184112185112186112187112188112189112190112191112192112193112194112195112196112197112198112199112200112201112202112203112204112205112206112207112208112209112210112211112212112213112214112215112216112217112218112219112220112221112222112223112224112225112226112227112228112229112230112231112232112233112234112235112236112237112238112239112240112241112242112243112244112245112246112247112248112249112250112251112252112253112254112255112256112257112258112259112260112261112262112263112264112265112266112267112268112269112270112271112272112273112274112275112276112277112278112279112280112281112282112283112284112285112286112287112288112289112290112291112292112293112294112295112296112297112298112299112300112301112302112303112304112305112306112307112308112309112310112311112312112313112314112315112316112317112318112319112320112321112322112323112324112325112326112327112328112329112330112331112332112333112334112335112336112337112338112339112340112341112342112343112344112345112346112347112348112349112350112351112352112353112354112355112356112357112358112359112360112361112362112363112364112365112366112367112368112369112370112371112372112373112374112375112376112377112378112379112380112381112382112383112384112385112386112387112388112389112390112391112392112393112394112395112396112397112398112399112400112401112402112403112404112405112406112407112408112409112410112411112412112413112414112415112416112417112418112419112420112421112422112423112424112425112426112427112428112429112430112431112432112433112434112435112436112437112438112439112440112441112442112443112444112445112446112447112448112449112450112451112452112453112454112455112456112457112458112459112460112461112462112463112464112465112466112467112468112469112470112471112472112473112474112475112476112477112478112479112480112481112482112483112484112485112486112487112488112489112490112491112492112493112494112495112496112497112498112499112500112501112502112503112504112505112506112507112508112509112510112511112512112513112514112515112516112517112518112519112520112521112522112523112524112525112526112527112528112529112530112531112532112533112534112535112536112537112538112539112540112541112542112543112544112545112546112547112548112549112550112551112552112553112554112555112556112557112558112559112560112561112562112563112564112565112566112567112568112569112570112571112572112573112574112575112576112577112578112579112580112581112582112583112584112585112586112587112588112589112590112591112592112593112594112595112596112597112598112599112600112601112602112603112604112605112606112607112608112609112610112611112612112613112614112615112616112617112618112619112620112621112622112623112624112625112626112627112628112629112630112631112632112633112634112635112636112637112638112639112640112641112642112643112644112645112646112647112648112649112650112651112652112653112654112655112656112657112658112659112660112661112662112663112664112665112666112667112668112669112670112671112672112673112674112675112676112677112678112679112680112681112682112683112684112685112686112687112688112689112690112691112692112693112694112695112696112697112698112699112700112701112702112703112704112705112706112707112708112709112710112711112712112713112714112715112716112717112718112719112720112721112722112723112724112725112726112727112728112729112730112731112732112733112734112735112736112737112738112739112740112741112742112743112744112745112746112747112748112749112750112751112752112753112754112755112756112757112758112759112760112761112762112763112764112765112766112767112768112769112770112771112772112773112774112775112776112777112778112779112780112781112782112783112784112785112786112787112788112789112790112791112792112793112794112795112796112797112798112799112800112801112802112803112804112805112806112807112808112809112810112811112812112813112814112815112816112817112818112819112820112821112822112823112824112825112826112827112828112829112830112831112832112833112834112835112836112837112838112839112840112841112842112843112844112845112846112847112848112849112850112851112852112853112854112855112856112857112858112859112860112861112862112863112864112865112866112867112868112869112870112871112872112873112874112875112876112877112878112879112880112881112882112883112884112885112886112887112888112889112890112891112892112893112894112895112896112897112898112899112900112901112902112903112904112905112906112907112908112909112910112911112912112913112914112915112916112917112918112919112920112921112922112923112924112925112926112927112928112929112930112931112932112933112934112935112936112937112938112939112940112941112942112943112944112945112946112947112948112949112950112951112952112953112954112955112956112957112958112959112960112961112962112963112964112965112966112967112968112969112970112971112972112973112974112975112976112977112978112979112980112981112982112983112984112985112986112987112988112989112990112991112992112993112994112995112996112997112998112999113000113001113002113003113004113005113006113007113008113009113010113011113012113013113014113015113016113017113018113019113020113021113022113023113024113025113026113027113028113029113030113031113032113033113034113035113036113037113038113039113040113041113042113043113044113045113046113047113048113049113050113051113052113053113054113055113056113057113058113059113060113061113062113063113064113065113066113067113068113069113070113071113072113073113074113075113076113077113078113079113080113081113082113083113084113085113086113087113088113089113090113091113092113093113094113095113096113097113098113099113100113101113102113103113104113105113106113107113108113109113110113111113112113113113114113115113116113117113118113119113120113121113122113123113124113125113126113127113128113129113130113131113132113133113134113135113136113137113138113139113140113141113142113143113144113145113146113147113148113149113150113151113152113153113154113155113156113157113158113159113160113161113162113163113164113165113166113167113168113169113170113171113172113173113174113175113176113177113178113179113180113181113182113183113184113185113186113187113188113189113190113191113192113193113194113195113196113197113198113199113200113201113202113203113204113205113206113207113208113209113210113211113212113213113214113215113216113217113218113219113220113221113222113223113224113225113226113227113228113229113230113231113232113233113234113235113236113237113238113239113240113241113242113243113244113245113246113247113248113249113250113251113252113253113254113255113256113257113258113259113260113261113262113263113264113265113266113267113268113269113270113271113272113273113274113275113276113277113278113279113280113281113282113283113284113285113286113287113288113289113290113291113292113293113294113295113296113297113298113299113300113301113302113303113304113305113306113307113308113309113310113311113312113313113314113315113316113317113318113319113320113321113322113323113324113325113326113327113328113329113330113331113332113333113334113335113336113337113338113339113340113341113342113343113344113345113346113347113348113349113350113351113352113353113354113355113356113357113358113359113360113361113362113363113364113365113366113367113368113369113370113371113372113373113374113375113376113377113378113379113380113381113382113383113384113385113386113387113388113389113390113391113392113393113394113395113396113397113398113399113400113401113402113403113404113405113406113407113408113409113410113411113412113413113414113415113416113417113418113419113420113421113422113423113424113425113426113427113428113429113430113431113432113433113434113435113436113437113438113439113440113441113442113443113444113445113446113447113448113449113450113451113452113453113454113455113456113457113458113459113460113461113462113463113464113465113466113467113468113469113470113471113472113473113474113475113476113477113478113479113480113481113482113483113484113485113486113487113488113489113490113491113492113493113494113495113496113497113498113499113500113501113502113503113504113505113506113507113508113509113510113511113512113513113514113515113516113517113518113519113520113521113522113523113524113525113526113527113528113529113530113531113532113533113534113535113536113537113538113539113540113541113542113543113544113545113546113547113548113549113550113551113552113553113554113555113556113557113558113559113560113561113562113563113564113565113566113567113568113569113570113571113572113573113574113575113576113577113578113579113580113581113582113583113584113585113586113587113588113589113590113591113592113593113594113595113596113597113598113599113600113601113602113603113604113605113606113607113608113609113610113611113612113613113614113615113616113617113618113619113620113621113622113623113624113625113626113627113628113629113630113631113632113633113634113635113636113637113638113639113640113641113642113643113644113645113646113647113648113649113650113651113652113653113654113655113656113657113658113659113660113661113662113663113664113665113666113667113668113669113670113671113672113673113674113675113676113677113678113679113680113681113682113683113684113685113686113687113688113689113690113691113692113693113694113695113696113697113698113699113700113701113702113703113704113705113706113707113708113709113710113711113712113713113714113715113716113717113718113719113720113721113722113723113724113725113726113727113728113729113730113731113732113733113734113735113736113737113738113739113740113741113742113743113744113745113746113747113748113749113750113751113752113753113754113755113756113757113758113759113760113761113762113763113764113765113766113767113768113769113770113771113772113773113774113775113776113777113778113779113780113781113782113783113784113785113786113787113788113789113790113791113792113793113794113795113796113797113798113799113800113801113802113803113804113805113806113807113808113809113810113811113812113813113814113815113816113817113818113819113820113821113822113823113824113825113826113827113828113829113830113831113832113833113834113835113836113837113838113839113840113841113842113843113844113845113846113847113848113849113850113851113852113853113854113855113856113857113858113859113860113861113862113863113864113865113866113867113868113869113870113871113872113873113874113875113876113877113878113879113880113881113882113883113884113885113886113887113888113889113890113891113892113893113894113895113896113897113898113899113900113901113902113903113904113905113906113907113908113909113910113911113912113913113914113915113916113917113918113919113920113921113922113923113924113925113926113927113928113929113930113931113932113933113934113935113936113937113938113939113940113941113942113943113944113945113946113947113948113949113950113951113952113953113954113955113956113957113958113959113960113961113962113963113964113965113966113967113968113969113970113971113972113973113974113975113976113977113978113979113980113981113982113983113984113985113986113987113988113989113990113991113992113993113994113995113996113997113998113999114000114001114002114003114004114005114006114007114008114009114010114011114012114013114014114015114016114017114018114019114020114021114022114023114024114025114026114027114028114029114030114031114032114033114034114035114036114037114038114039114040114041114042114043114044114045114046114047114048114049114050114051114052114053114054114055114056114057114058114059114060114061114062114063114064114065114066114067114068114069114070114071114072114073114074114075114076114077114078114079114080114081114082114083114084114085114086114087114088114089114090114091114092114093114094114095114096114097114098114099114100114101114102114103114104114105114106114107114108114109114110114111114112114113114114114115114116114117114118114119114120114121114122114123114124114125114126114127114128114129114130114131114132114133114134114135114136114137114138114139114140114141114142114143114144114145114146114147114148114149114150114151114152114153114154114155114156114157114158114159114160114161114162114163114164114165114166114167114168114169114170114171114172114173114174114175114176114177114178114179114180114181114182114183114184114185114186114187114188114189114190114191114192114193114194114195114196114197114198114199114200114201114202114203114204114205114206114207114208114209114210114211114212114213114214114215114216114217114218114219114220114221114222114223114224114225114226114227114228114229114230114231114232114233114234114235114236114237114238114239114240114241114242114243114244114245114246114247114248114249114250114251114252114253114254114255114256114257114258114259114260114261114262114263114264114265114266114267114268114269114270114271114272114273114274114275114276114277114278114279114280114281114282114283114284114285114286114287114288114289114290114291114292114293114294114295114296114297114298114299114300114301114302114303114304114305114306114307114308114309114310114311114312114313114314114315114316114317114318114319114320114321114322114323114324114325114326114327114328114329114330114331114332114333114334114335114336114337114338114339114340114341114342114343114344114345114346114347114348114349114350114351114352114353114354114355114356114357114358114359114360114361114362114363114364114365114366114367114368114369114370114371114372114373114374114375114376114377114378114379114380114381114382114383114384114385114386114387114388114389114390114391114392114393114394114395114396114397114398114399114400114401114402114403114404114405114406114407114408114409114410114411114412114413114414114415114416114417114418114419114420114421114422114423114424114425114426114427114428114429114430114431114432114433114434114435114436114437114438114439114440114441114442114443114444114445114446114447114448114449114450114451114452114453114454114455114456114457114458114459114460114461114462114463114464114465114466114467114468114469114470114471114472114473114474114475114476114477114478114479114480114481114482114483114484114485114486114487114488114489114490114491114492114493114494114495114496114497114498114499114500114501114502114503114504114505114506114507114508114509114510114511114512114513114514114515114516114517114518114519114520114521114522114523114524114525114526114527114528114529114530114531114532114533114534114535114536114537114538114539114540114541114542114543114544114545114546114547114548114549114550114551114552114553114554114555114556114557114558114559114560114561114562114563114564114565114566114567114568114569114570114571114572114573114574114575114576114577114578114579114580114581114582114583114584114585114586114587114588114589114590114591114592114593114594114595114596114597114598114599114600114601114602114603114604114605114606114607114608114609114610114611114612114613114614114615114616114617114618114619114620114621114622114623114624114625114626114627114628114629114630114631114632114633114634114635114636114637114638114639114640114641114642114643114644114645114646114647114648114649114650114651114652114653114654114655114656114657114658114659114660114661114662114663114664114665114666114667114668114669114670114671114672114673114674114675114676114677114678114679114680114681114682114683114684114685114686114687114688114689114690114691114692114693114694114695114696114697114698114699114700114701114702114703114704114705114706114707114708114709114710114711114712114713114714114715114716114717114718114719114720114721114722114723114724114725114726114727114728114729114730114731114732114733114734114735114736114737114738114739114740114741114742114743114744114745114746114747114748114749114750114751114752114753114754114755114756114757114758114759114760114761114762114763114764114765114766114767114768114769114770114771114772114773114774114775114776114777114778114779114780114781114782114783114784114785114786114787114788114789114790114791114792114793114794114795114796114797114798114799114800114801114802114803114804114805114806114807114808114809114810114811114812114813114814114815114816114817114818114819114820114821114822114823114824114825114826114827114828114829114830114831114832114833114834114835114836114837114838114839114840114841114842114843114844114845114846114847114848114849114850114851114852114853114854114855114856114857114858114859114860114861114862114863114864114865114866114867114868114869114870114871114872114873114874114875114876114877114878114879114880114881114882114883114884114885114886114887114888114889114890114891114892114893114894114895114896114897114898114899114900114901114902114903114904114905114906114907114908114909114910114911114912114913114914114915114916114917114918114919114920114921114922114923114924114925114926114927114928114929114930114931114932114933114934114935114936114937114938114939114940114941114942114943114944114945114946114947114948114949114950114951114952114953114954114955114956114957114958114959114960114961114962114963114964114965114966114967114968114969114970114971114972114973114974114975114976114977114978114979114980114981114982114983114984114985114986114987114988114989114990114991114992114993114994114995114996114997114998114999115000115001115002115003115004115005115006115007115008115009115010115011115012115013115014115015115016115017115018115019115020115021115022115023115024115025115026115027115028115029115030115031115032115033115034115035115036115037115038115039115040115041115042115043115044115045115046115047115048115049115050115051115052115053115054115055115056115057115058115059115060115061115062115063115064115065115066115067115068115069115070115071115072115073115074115075115076115077115078115079115080115081115082115083115084115085115086115087115088115089115090115091115092115093115094115095115096115097115098115099115100115101115102115103115104115105115106115107115108115109115110115111115112115113115114115115115116115117115118115119115120115121115122115123115124115125115126115127115128115129115130115131115132115133115134115135115136115137115138115139115140115141115142115143115144115145115146115147115148115149115150115151115152115153115154115155115156115157115158115159115160115161115162115163115164115165115166115167115168115169115170115171115172115173115174115175115176115177115178115179115180115181115182115183115184115185115186115187115188115189115190115191115192115193115194115195115196115197115198115199115200115201115202115203115204115205115206115207115208115209115210115211115212115213115214115215115216115217115218115219115220115221115222115223115224115225115226115227115228115229115230115231115232115233115234115235115236115237115238115239115240115241115242115243115244115245115246115247115248115249115250115251115252115253115254115255115256115257115258115259115260115261115262115263115264115265115266115267115268115269115270115271115272115273115274115275115276115277115278115279115280115281115282115283115284115285115286115287115288115289115290115291115292115293115294115295115296115297115298115299115300115301115302115303115304115305115306115307115308115309115310115311115312115313115314115315115316115317115318115319115320115321115322115323115324115325115326115327115328115329115330115331115332115333115334115335115336115337115338115339115340115341115342115343115344115345115346115347115348115349115350115351115352115353115354115355115356115357115358115359115360115361115362115363115364115365115366115367115368115369115370115371115372115373115374115375115376115377115378115379115380115381115382115383115384115385115386115387115388115389115390115391115392115393115394115395115396115397115398115399115400115401115402115403115404115405115406115407115408115409115410115411115412115413115414115415115416115417115418115419115420115421115422115423115424115425115426115427115428115429115430115431115432115433115434115435115436115437115438115439115440115441115442115443115444115445115446115447115448115449115450115451115452115453115454115455115456115457115458115459115460115461115462115463115464115465115466115467115468115469115470115471115472115473115474115475115476115477115478115479115480115481115482115483115484115485115486115487115488115489115490115491115492115493115494115495115496115497115498115499115500115501115502115503115504115505115506115507115508115509115510115511115512115513115514115515115516115517115518115519115520115521115522115523115524115525115526115527115528115529115530115531115532115533115534115535115536115537115538115539115540115541115542115543115544115545115546115547115548115549115550115551115552115553115554115555115556115557115558115559115560115561115562115563115564115565115566115567115568115569115570115571115572115573115574115575115576115577115578115579115580115581115582115583115584115585115586115587115588115589115590115591115592115593115594115595115596115597115598115599115600115601115602115603115604115605115606115607115608115609115610115611115612115613115614115615115616115617115618115619115620115621115622115623115624115625115626115627115628115629115630115631115632115633115634115635115636115637115638115639115640115641115642115643115644115645115646115647115648115649115650115651115652115653115654115655115656115657115658115659115660115661115662115663115664115665115666115667115668115669115670115671115672115673115674115675115676115677115678115679115680115681115682115683115684115685115686115687115688115689115690115691115692115693115694115695115696115697115698115699115700115701115702115703115704115705115706115707115708115709115710115711115712115713115714115715115716115717115718115719115720115721115722115723115724115725115726115727115728115729115730115731115732115733115734115735115736115737115738115739115740115741115742115743115744115745115746115747115748115749115750115751115752115753115754115755115756115757115758115759115760115761115762115763115764115765115766115767115768115769115770115771115772115773115774115775115776115777115778115779115780115781115782115783115784115785115786115787115788115789115790115791115792115793115794115795115796115797115798115799115800115801115802115803115804115805115806115807115808115809115810115811115812115813115814115815115816115817115818115819115820115821115822115823115824115825115826115827115828115829115830115831115832115833115834115835115836115837115838115839115840115841115842115843115844115845115846115847115848115849115850115851115852115853115854115855115856115857115858115859115860115861115862115863115864115865115866115867115868115869115870115871115872115873115874115875115876115877115878115879115880115881115882115883115884115885115886115887115888115889115890115891115892115893115894115895115896115897115898115899115900115901115902115903115904115905115906115907115908115909115910115911115912115913115914115915115916115917115918115919115920115921115922115923115924115925115926115927115928115929115930115931115932115933115934115935115936115937115938115939115940115941115942115943115944115945115946115947115948115949115950115951115952115953115954115955115956115957115958115959115960115961115962115963115964115965115966115967115968115969115970115971115972115973115974115975115976115977115978115979115980115981115982115983115984115985115986115987115988115989115990115991115992115993115994115995115996115997115998115999116000116001116002116003116004116005116006116007116008116009116010116011116012116013116014116015116016116017116018116019116020116021116022116023116024116025116026116027116028116029116030116031116032116033116034116035116036116037116038116039116040116041116042116043116044116045116046116047116048116049116050116051116052116053116054116055116056116057116058116059116060116061116062116063116064116065116066116067116068116069116070116071116072116073116074116075116076116077116078116079116080116081116082116083116084116085116086116087116088116089116090116091116092116093116094116095116096116097116098116099116100116101116102116103116104116105116106116107116108116109116110116111116112116113116114116115116116116117116118116119116120116121116122116123116124116125116126116127116128116129116130116131116132116133116134116135116136116137116138116139116140116141116142116143116144116145116146116147116148116149116150116151116152116153116154116155116156116157116158116159116160116161116162116163116164116165116166116167116168116169116170116171116172116173116174116175116176116177116178116179116180116181116182116183116184116185116186116187116188116189116190116191116192116193116194116195116196116197116198116199116200116201116202116203116204116205116206116207116208116209116210116211116212116213116214116215116216116217116218116219116220116221116222116223116224116225116226116227116228116229116230116231116232116233116234116235116236116237116238116239116240116241116242116243116244116245116246116247116248116249116250116251116252116253116254116255116256116257116258116259116260116261116262116263116264116265116266116267116268116269116270116271116272116273116274116275116276116277116278116279116280116281116282116283116284116285116286116287116288116289116290116291116292116293116294116295116296116297116298116299116300116301116302116303116304116305116306116307116308116309116310116311116312116313116314116315116316116317116318116319116320116321116322116323116324116325116326116327116328116329116330116331116332116333116334116335116336116337116338116339116340116341116342116343116344116345116346116347116348116349116350116351116352116353116354116355116356116357116358116359116360116361116362116363116364116365116366116367116368116369116370116371116372116373116374116375116376116377116378116379116380116381116382116383116384116385116386116387116388116389116390116391116392116393116394116395116396116397116398116399116400116401116402116403116404116405116406116407116408116409116410116411116412116413116414116415116416116417116418116419116420116421116422116423116424116425116426116427116428116429116430116431116432116433116434116435116436116437116438116439116440116441116442116443116444116445116446116447116448116449116450116451116452116453116454116455116456116457116458116459116460116461116462116463116464116465116466116467116468116469116470116471116472116473116474116475116476116477116478116479116480116481116482116483116484116485116486116487116488116489116490116491116492116493116494116495116496116497116498116499116500116501116502116503116504116505116506116507116508116509116510116511116512116513116514116515116516116517116518116519116520116521116522116523116524116525116526116527116528116529116530116531116532116533116534116535116536116537116538116539116540116541116542116543116544116545116546116547116548116549116550116551116552116553116554116555116556116557116558116559116560116561116562116563116564116565116566116567116568116569116570116571116572116573116574116575116576116577116578116579116580116581116582116583116584116585116586116587116588116589116590116591116592116593116594116595116596116597116598116599116600116601116602116603116604116605116606116607116608116609116610116611116612116613116614116615116616116617116618116619116620116621116622116623116624116625116626116627116628116629116630116631116632116633116634116635116636116637116638116639116640116641116642116643116644116645116646116647116648116649116650116651116652116653116654116655116656116657116658116659116660116661116662116663116664116665116666116667116668116669116670116671116672116673116674116675116676116677116678116679116680116681116682116683116684116685116686116687116688116689116690116691116692116693116694116695116696116697116698116699116700116701116702116703116704116705116706116707116708116709116710116711116712116713116714116715116716116717116718116719116720116721116722116723116724116725116726116727116728116729116730116731116732116733116734116735116736116737116738116739116740116741116742116743116744116745116746116747116748116749116750116751116752116753116754116755116756116757116758116759116760116761116762116763116764116765116766116767116768116769116770116771116772116773116774116775116776116777116778116779116780116781116782116783116784116785116786116787116788116789116790116791116792116793116794116795116796116797116798116799116800116801116802116803116804116805116806116807116808116809116810116811116812116813116814116815116816116817116818116819116820116821116822116823116824116825116826116827116828116829116830116831116832116833116834116835116836116837116838116839116840116841116842116843116844116845116846116847116848116849116850116851116852116853116854116855116856116857116858116859116860116861116862116863116864116865116866116867116868116869116870116871116872116873116874116875116876116877116878116879116880116881116882116883116884116885116886116887116888116889116890116891116892116893116894116895116896116897116898116899116900116901116902116903116904116905116906116907116908116909116910116911116912116913116914116915116916116917116918116919116920116921116922116923116924116925116926116927116928116929116930116931116932116933116934116935116936116937116938116939116940116941116942116943116944116945116946116947116948116949116950116951116952116953116954116955116956116957116958116959116960116961116962116963116964116965116966116967116968116969116970116971116972116973116974116975116976116977116978116979116980116981116982116983116984116985116986116987116988116989116990116991116992116993116994116995116996116997116998116999117000117001117002117003117004117005117006117007117008117009117010117011117012117013117014117015117016117017117018117019117020117021117022117023117024117025117026117027117028117029117030117031117032117033117034117035117036117037117038117039117040117041117042117043117044117045117046117047117048117049117050117051117052117053117054117055117056117057117058117059117060117061117062117063117064117065117066117067117068117069117070117071117072117073117074117075117076117077117078117079117080117081117082117083117084117085117086117087117088117089117090117091117092117093117094117095117096117097117098117099117100117101117102117103117104117105117106117107117108117109117110117111117112117113117114117115117116117117117118117119117120117121117122117123117124117125117126117127117128117129117130117131117132117133117134117135117136117137117138117139117140117141117142117143117144117145117146117147117148117149117150117151117152117153117154117155117156117157117158117159117160117161117162117163117164117165117166117167117168117169117170117171117172117173117174117175117176117177117178117179117180117181117182117183117184117185117186117187117188117189117190117191117192117193117194117195117196117197117198117199117200117201117202117203117204117205117206117207117208117209117210117211117212117213117214117215117216117217117218117219117220117221117222117223117224117225117226117227117228117229117230117231117232117233117234117235117236117237117238117239117240117241117242117243117244117245117246117247117248117249117250117251117252117253117254117255117256117257117258117259117260117261117262117263117264117265117266117267117268117269117270117271117272117273117274117275117276117277117278117279117280117281117282117283117284117285117286117287117288117289117290117291117292117293117294117295117296117297117298117299117300117301117302117303117304117305117306117307117308117309117310117311117312117313117314117315117316117317117318117319117320117321117322117323117324117325117326117327117328117329117330117331117332117333117334117335117336117337117338117339117340117341117342117343117344117345117346117347117348117349117350117351117352117353117354117355117356117357117358117359117360117361117362117363117364117365117366117367117368117369117370117371117372117373117374117375117376117377117378117379117380117381117382117383117384117385117386117387117388117389117390117391117392117393117394117395117396117397117398117399117400117401117402117403117404117405117406117407117408117409117410117411117412117413117414117415117416117417117418117419117420117421117422117423117424117425117426117427117428117429117430117431117432117433117434117435117436117437117438117439117440117441117442117443117444117445117446117447117448117449117450117451117452117453117454117455117456117457117458117459117460117461117462117463117464117465117466117467117468117469117470117471117472117473117474117475117476117477117478117479117480117481117482117483117484117485117486117487117488117489117490117491117492117493117494117495117496117497117498117499117500117501117502117503117504117505117506117507117508117509117510117511117512117513117514117515117516117517117518117519117520117521117522117523117524117525117526117527117528117529117530117531117532117533117534117535117536117537117538117539117540117541117542117543117544117545117546117547117548117549117550117551117552117553117554117555117556117557117558117559117560117561117562117563117564117565117566117567117568117569117570117571117572117573117574117575117576117577117578117579117580117581117582117583117584117585117586117587117588117589117590117591117592117593117594117595117596117597117598117599117600117601117602117603117604117605117606117607117608117609117610117611117612117613117614117615117616117617117618117619117620117621117622117623117624117625117626117627117628117629117630117631117632117633117634117635117636117637117638117639117640117641117642117643117644117645117646117647117648117649117650117651117652117653117654117655117656117657117658117659117660117661117662117663117664117665117666117667117668117669117670117671117672117673117674117675117676117677117678117679117680117681117682117683117684117685117686117687117688117689117690117691117692117693117694117695117696117697117698117699117700117701117702117703117704117705117706117707117708117709117710117711117712117713117714117715117716117717117718117719117720117721117722117723117724117725117726117727117728117729117730117731117732117733117734117735117736117737117738117739117740117741117742117743117744117745117746117747117748117749117750117751117752117753117754117755117756117757117758117759117760117761117762117763117764117765117766117767117768117769117770117771117772117773117774117775117776117777117778117779117780117781117782117783117784117785117786117787117788117789117790117791117792117793117794117795117796117797117798117799117800117801117802117803117804117805117806117807117808117809117810117811117812117813117814117815117816117817117818117819117820117821117822117823117824117825117826117827117828117829117830117831117832117833117834117835117836117837117838117839117840117841117842117843117844117845117846117847117848117849117850117851117852117853117854117855117856117857117858117859117860117861117862117863117864117865117866117867117868117869117870117871117872117873117874117875117876117877117878117879117880117881117882117883117884117885117886117887117888117889117890117891117892117893117894117895117896117897117898117899117900117901117902117903117904117905117906117907117908117909117910117911117912117913117914117915117916117917117918117919117920117921117922117923117924117925117926117927117928117929117930117931117932117933117934117935117936117937117938117939117940117941117942117943117944117945117946117947117948117949117950117951117952117953117954117955117956117957117958117959117960117961117962117963117964117965117966117967117968117969117970117971117972117973117974117975117976117977117978117979117980117981117982117983117984117985117986117987117988117989117990117991117992117993117994117995117996117997117998117999118000118001118002118003118004118005118006118007118008118009118010118011118012118013118014118015118016118017118018118019118020118021118022118023118024118025118026118027118028118029118030118031118032118033118034118035118036118037118038118039118040118041118042118043118044118045118046118047118048118049118050118051118052118053118054118055118056118057118058118059118060118061118062118063118064118065118066118067118068118069118070118071118072118073118074118075118076118077118078118079118080118081118082118083118084118085118086118087118088118089118090118091118092118093118094118095118096118097118098118099118100118101118102118103118104118105118106118107118108118109118110118111118112118113118114118115118116118117118118118119118120118121118122118123118124118125118126118127118128118129118130118131118132118133118134118135118136118137118138118139118140118141118142118143118144118145118146118147118148118149118150118151118152118153118154118155118156118157118158118159118160118161118162118163118164118165118166118167118168118169118170118171118172118173118174118175118176118177118178118179118180118181118182118183118184118185118186118187118188118189118190118191118192118193118194118195118196118197118198118199118200118201118202118203118204118205118206118207118208118209118210118211118212118213118214118215118216118217118218118219118220118221118222118223118224118225118226118227118228118229118230118231118232118233118234118235118236118237118238118239118240118241118242118243118244118245118246118247118248118249118250118251118252118253118254118255118256118257118258118259118260118261118262118263118264118265118266118267118268118269118270118271118272118273118274118275118276118277118278118279118280118281118282118283118284118285118286118287118288118289118290118291118292118293118294118295118296118297118298118299118300118301118302118303118304118305118306118307118308118309118310118311118312118313118314118315118316118317118318118319118320118321118322118323118324118325118326118327118328118329118330118331118332118333118334118335118336118337118338118339118340118341118342118343118344118345118346118347118348118349118350118351118352118353118354118355118356118357118358118359118360118361118362118363118364118365118366118367118368118369118370118371118372118373118374118375118376118377118378118379118380118381118382118383118384118385118386118387118388118389118390118391118392118393118394118395118396118397118398118399118400118401118402118403118404118405118406118407118408118409118410118411118412118413118414118415118416118417118418118419118420118421118422118423118424118425118426118427118428118429118430118431118432118433118434118435118436118437118438118439118440118441118442118443118444118445118446118447118448118449118450118451118452118453118454118455118456118457118458118459118460118461118462118463118464118465118466118467118468118469118470118471118472118473118474118475118476118477118478118479118480118481118482118483118484118485118486118487118488118489118490118491118492118493118494118495118496118497118498118499118500118501118502118503118504118505118506118507118508118509118510118511118512118513118514118515118516118517118518118519118520118521118522118523118524118525118526118527118528118529118530118531118532118533118534118535118536118537118538118539118540118541118542118543118544118545118546118547118548118549118550118551118552118553118554118555118556118557118558118559118560118561118562118563118564118565118566118567118568118569118570118571118572118573118574118575118576118577118578118579118580118581118582118583118584118585118586118587118588118589118590118591118592118593118594118595118596118597118598118599118600118601118602118603118604118605118606118607118608118609118610118611118612118613118614118615118616118617118618118619118620118621118622118623118624118625118626118627118628118629118630118631118632118633118634118635118636118637118638118639118640118641118642118643118644118645118646118647118648118649118650118651118652118653118654118655118656118657118658118659118660118661118662118663118664118665118666118667118668118669118670118671118672118673118674118675118676118677118678118679118680118681118682118683118684118685118686118687118688118689118690118691118692118693118694118695118696118697118698118699118700118701118702118703118704118705118706118707118708118709118710118711118712118713118714118715118716118717118718118719118720118721118722118723118724118725118726118727118728118729118730118731118732118733118734118735118736118737118738118739118740118741118742118743118744118745118746118747118748118749118750118751118752118753118754118755118756118757118758118759118760118761118762118763118764118765118766118767118768118769118770118771118772118773118774118775118776118777118778118779118780118781118782118783118784118785118786118787118788118789118790118791118792118793118794118795118796118797118798118799118800118801118802118803118804118805118806118807118808118809118810118811118812118813118814118815118816118817118818118819118820118821118822118823118824118825118826118827118828118829118830118831118832118833118834118835118836118837118838118839118840118841118842118843118844118845118846118847118848118849118850118851118852118853118854118855118856118857118858118859118860118861118862118863118864118865118866118867118868118869118870118871118872118873118874118875118876118877118878118879118880118881118882118883118884118885118886118887118888118889118890118891118892118893118894118895118896118897118898118899118900118901118902118903118904118905118906118907118908118909118910118911118912118913118914118915118916118917118918118919118920118921118922118923118924118925118926118927118928118929118930118931118932118933118934118935118936118937118938118939118940118941118942118943118944118945118946118947118948118949118950118951118952118953118954118955118956118957118958118959118960118961118962118963118964118965118966118967118968118969118970118971118972118973118974118975118976118977118978118979118980118981118982118983118984118985118986118987118988118989118990118991118992118993118994118995118996118997118998118999119000119001119002119003119004119005119006119007119008119009119010119011119012119013119014119015119016119017119018119019119020119021119022119023119024119025119026119027119028119029119030119031119032119033119034119035119036119037119038119039119040119041119042119043119044119045119046119047119048119049119050119051119052119053119054119055119056119057119058119059119060119061119062119063119064119065119066119067119068119069119070119071119072119073119074119075119076119077119078119079119080119081119082119083119084119085119086119087119088119089119090119091119092119093119094119095119096119097119098119099119100119101119102119103119104119105119106119107119108119109119110119111119112119113119114119115119116119117119118119119119120119121119122119123119124119125119126119127119128119129119130119131119132119133119134119135119136119137119138119139119140119141119142119143119144119145119146119147119148119149119150119151119152119153119154119155119156119157119158119159119160119161119162119163119164119165119166119167119168119169119170119171119172119173119174119175119176119177119178119179119180119181119182119183119184119185119186119187119188119189119190119191119192119193119194119195119196119197119198119199119200119201119202119203119204119205119206119207119208119209119210119211119212119213119214119215119216119217119218119219119220119221119222119223119224119225119226119227119228119229119230119231119232119233119234119235119236119237119238119239119240119241119242119243119244119245119246119247119248119249119250119251119252119253119254119255119256119257119258119259119260119261119262119263119264119265119266119267119268119269119270119271119272119273119274119275119276119277119278119279119280119281119282119283119284119285119286119287119288119289119290119291119292119293119294119295119296119297119298119299119300119301119302119303119304119305119306119307119308119309119310119311119312119313119314119315119316119317119318119319119320119321119322119323119324119325119326119327119328119329119330119331119332119333119334119335119336119337119338119339119340119341119342119343119344119345119346119347119348119349119350119351119352119353119354119355119356119357119358119359119360119361119362119363119364119365119366119367119368119369119370119371119372119373119374119375119376119377119378119379119380119381119382119383119384119385119386119387119388119389119390119391119392119393119394119395119396119397119398119399119400119401119402119403119404119405119406119407119408119409119410119411119412119413119414119415119416119417119418119419119420119421119422119423119424119425119426119427119428119429119430119431119432119433119434119435119436119437119438119439119440119441119442119443119444119445119446119447119448119449119450119451119452119453119454119455119456119457119458119459119460119461119462119463119464119465119466119467119468119469119470119471119472119473119474119475119476119477119478119479119480119481119482119483119484119485119486119487119488119489119490119491119492119493119494119495119496119497119498119499119500119501119502119503119504119505119506119507119508119509119510119511119512119513119514119515119516119517119518119519119520119521119522119523119524119525119526119527119528119529119530119531119532119533119534119535119536119537119538119539119540119541119542119543119544119545119546119547119548119549119550119551119552119553119554119555119556119557119558119559119560119561119562119563119564119565119566119567119568119569119570119571119572119573119574119575119576119577119578119579119580119581119582119583119584119585119586119587119588119589119590119591119592119593119594119595119596119597119598119599119600119601119602119603119604119605119606119607119608119609119610119611119612119613119614119615119616119617119618119619119620119621119622119623119624119625119626119627119628119629119630119631119632119633119634119635119636119637119638119639119640119641119642119643119644119645119646119647119648119649119650119651119652119653119654119655119656119657119658119659119660119661119662119663119664119665119666119667119668119669119670119671119672119673119674119675119676119677119678119679119680119681119682119683119684119685119686119687119688119689119690119691119692119693119694119695119696119697119698119699119700119701119702119703119704119705119706119707119708119709119710119711119712119713119714119715119716119717119718119719119720119721119722119723119724119725119726119727119728119729119730119731119732119733119734119735119736119737119738119739119740119741119742119743119744119745119746119747119748119749119750119751119752119753119754119755119756119757119758119759119760119761119762119763119764119765119766119767119768119769119770119771119772119773119774119775119776119777119778119779119780119781119782119783119784119785119786119787119788119789119790119791119792119793119794119795119796119797119798119799119800119801119802119803119804119805119806119807119808119809119810119811119812119813119814119815119816119817119818119819119820119821119822119823119824119825119826119827119828119829119830119831119832119833119834119835119836119837119838119839119840119841119842119843119844119845119846119847119848119849119850119851119852119853119854119855119856119857119858119859119860119861119862119863119864119865119866119867119868119869119870119871119872119873119874119875119876119877119878119879119880119881119882119883119884119885119886119887119888119889119890119891119892119893119894119895119896119897119898119899119900119901119902119903119904119905119906119907119908119909119910119911119912119913119914119915119916119917119918119919119920119921119922119923119924119925119926119927119928119929119930119931119932119933119934119935119936119937119938119939119940119941119942119943119944119945119946119947119948119949119950119951119952119953119954119955119956119957119958119959119960119961119962119963119964119965119966119967119968119969119970119971119972119973119974119975119976119977119978119979119980119981119982119983119984119985119986119987119988119989119990119991119992119993119994119995119996119997119998119999120000120001120002120003120004120005120006120007120008120009120010120011120012120013120014120015120016120017120018120019120020120021120022120023120024120025120026120027120028120029120030120031120032120033120034120035120036120037120038120039120040120041120042120043120044120045120046120047120048120049120050120051120052120053120054120055120056120057120058120059120060120061120062120063120064120065120066120067120068120069120070120071120072120073120074120075120076120077120078120079120080120081120082120083120084120085120086120087120088120089120090120091120092120093120094120095120096120097120098120099120100120101120102120103120104120105120106120107120108120109120110120111120112120113120114120115120116120117120118120119120120120121120122120123120124120125120126120127120128120129120130120131120132120133120134120135120136120137120138120139120140120141120142120143120144120145120146120147120148120149120150120151120152120153120154120155120156120157120158120159120160120161120162120163120164120165120166120167120168120169120170120171120172120173120174120175120176120177120178120179120180120181120182120183120184120185120186120187120188120189120190120191120192120193120194120195120196120197120198120199120200120201120202120203120204120205120206120207120208120209120210120211120212120213120214120215120216120217120218120219120220120221120222120223120224120225120226120227120228120229120230120231120232120233120234120235120236120237120238120239120240120241120242120243120244120245120246120247120248120249120250120251120252120253120254120255120256120257120258120259120260120261120262120263120264120265120266120267120268120269120270120271120272120273120274120275120276120277120278120279120280120281120282120283120284120285120286120287120288120289120290120291120292120293120294120295120296120297120298120299120300120301120302120303120304120305120306120307120308120309120310120311120312120313120314120315120316120317120318120319120320120321120322120323120324120325120326120327120328120329120330120331120332120333120334120335120336120337120338120339120340120341120342120343120344120345120346120347120348120349120350120351120352120353120354120355120356120357120358120359120360120361120362120363120364120365120366120367120368120369120370120371120372120373120374120375120376120377120378120379120380120381120382120383120384120385120386120387120388120389120390120391120392120393120394120395120396120397120398120399120400120401120402120403120404120405120406120407120408120409120410120411120412120413120414120415120416120417120418120419120420120421120422120423120424120425120426120427120428120429120430120431120432120433120434120435120436120437120438120439120440120441120442120443120444120445120446120447120448120449120450120451120452120453120454120455120456120457120458120459120460120461120462120463120464120465120466120467120468120469120470120471120472120473120474120475120476120477120478120479120480120481120482120483120484120485120486120487120488120489120490120491120492120493120494120495120496120497120498120499120500120501120502120503120504120505120506120507120508120509120510120511120512120513120514120515120516120517120518120519120520120521120522120523120524120525120526120527120528120529120530120531120532120533120534120535120536120537120538120539120540120541120542120543120544120545120546120547120548120549120550120551120552120553120554120555120556120557120558120559120560120561120562120563120564120565120566120567120568120569120570120571120572120573120574120575120576120577120578120579120580120581120582120583120584120585120586120587120588120589120590120591120592120593120594120595120596120597120598120599120600120601120602120603120604120605120606120607120608120609120610120611120612120613120614120615120616120617120618120619120620120621120622120623120624120625120626120627120628120629120630120631120632120633120634120635120636120637120638120639120640120641120642120643120644120645120646120647120648120649120650120651120652120653120654120655120656120657120658120659120660120661120662120663120664120665120666120667120668120669120670120671120672120673120674120675120676120677120678120679120680120681120682120683120684120685120686120687120688120689120690120691120692120693120694120695120696120697120698120699120700120701120702120703120704120705120706120707120708120709120710120711120712120713120714120715120716120717120718120719120720120721120722120723120724120725120726120727120728120729120730120731120732120733120734120735120736120737120738120739120740120741120742120743120744120745120746120747120748120749120750120751120752120753120754120755120756120757120758120759120760120761120762120763120764120765120766120767120768120769120770120771120772120773120774120775120776120777120778120779120780120781120782120783120784120785120786120787120788120789120790120791120792120793120794120795120796120797120798120799120800120801120802120803120804120805120806120807120808120809120810120811120812120813120814120815120816120817120818120819120820120821120822120823120824120825120826120827120828120829120830120831120832120833120834120835120836120837120838120839120840120841120842120843120844120845120846120847120848120849120850120851120852120853120854120855120856120857120858120859120860120861120862120863120864120865120866120867120868120869120870120871120872120873120874120875120876120877120878120879120880120881120882120883120884120885120886120887120888120889120890120891120892120893120894120895120896120897120898120899120900120901120902120903120904120905120906120907120908120909120910120911120912120913120914120915120916120917120918120919120920120921120922120923120924120925120926120927120928120929120930120931120932120933120934120935120936120937120938120939120940120941120942120943120944120945120946120947120948120949120950120951120952120953120954120955120956120957120958120959120960120961120962120963120964120965120966120967120968120969120970120971120972120973120974120975120976120977120978120979120980120981120982120983120984120985120986120987120988120989120990120991120992120993120994120995120996120997120998120999121000121001121002121003121004121005121006121007121008121009121010121011121012121013121014121015121016121017121018121019121020121021121022121023121024121025121026121027121028121029121030121031121032121033121034121035121036121037121038121039121040121041121042121043121044121045121046121047121048121049121050121051121052121053121054121055121056121057121058121059121060121061121062121063121064121065121066121067121068121069121070121071121072121073121074121075121076121077121078121079121080121081121082121083121084121085121086121087121088121089121090121091121092121093121094121095121096121097121098121099121100121101121102121103121104121105121106121107121108121109121110121111121112121113121114121115121116121117121118121119121120121121121122121123121124121125121126121127121128121129121130121131121132121133121134121135121136121137121138121139121140121141121142121143121144121145121146121147121148121149121150121151121152121153121154121155121156121157121158121159121160121161121162121163121164121165121166121167121168121169121170121171121172121173121174121175121176121177121178121179121180121181121182121183121184121185121186121187121188121189121190121191121192121193121194121195121196121197121198121199121200121201121202121203121204121205121206121207121208121209121210121211121212121213121214121215121216121217121218121219121220121221121222121223121224121225121226121227121228121229121230121231121232121233121234121235121236121237121238121239121240121241121242121243121244121245121246121247121248121249121250121251121252121253121254121255121256121257121258121259121260121261121262121263121264121265121266121267121268121269121270121271121272121273121274121275121276121277121278121279121280121281121282121283121284121285121286121287121288121289121290121291121292121293121294121295121296121297121298121299121300121301121302121303121304121305121306121307121308121309121310121311121312121313121314121315121316121317121318121319121320121321121322121323121324121325121326121327121328121329121330121331121332121333121334121335121336121337121338121339121340121341121342121343121344121345121346121347121348121349121350121351121352121353121354121355121356121357121358121359121360121361121362121363121364121365121366121367121368121369121370121371121372121373121374121375121376121377121378121379121380121381121382121383121384121385121386121387121388121389121390121391121392121393121394121395121396121397121398121399121400121401121402121403121404121405121406121407121408121409121410121411121412121413121414121415121416121417121418121419121420121421121422121423121424121425121426121427121428121429121430121431121432121433121434121435121436121437121438121439121440121441121442121443121444121445121446121447121448121449121450121451121452121453121454121455121456121457121458121459121460121461121462121463121464121465121466121467121468121469121470121471121472121473121474121475121476121477121478121479121480121481121482121483121484121485121486121487121488121489121490121491121492121493121494121495121496121497121498121499121500121501121502121503121504121505121506121507121508121509121510121511121512121513121514121515121516121517121518121519121520121521121522121523121524121525121526121527121528121529121530121531121532121533121534121535121536121537121538121539121540121541121542121543121544121545121546121547121548121549121550121551121552121553121554121555121556121557121558121559121560121561121562121563121564121565121566121567121568121569121570121571121572121573121574121575121576121577121578121579121580121581121582121583121584121585121586121587121588121589121590121591121592121593121594121595121596121597121598121599121600121601121602121603121604121605121606121607121608121609121610121611121612121613121614121615121616121617121618121619121620121621121622121623121624121625121626121627121628121629121630121631121632121633121634121635121636121637121638121639121640121641121642121643121644121645121646121647121648121649121650121651121652121653121654121655121656121657121658121659121660121661121662121663121664121665121666121667121668121669121670121671121672121673121674121675121676121677121678121679121680121681121682121683121684121685121686121687121688121689121690121691121692121693121694121695121696121697121698121699121700121701121702121703121704121705121706121707121708121709121710121711121712121713121714121715121716121717121718121719121720121721121722121723121724121725121726121727121728121729121730121731121732121733121734121735121736121737121738121739121740121741121742121743121744121745121746121747121748121749121750121751121752121753121754121755121756121757121758121759121760121761121762121763121764121765121766121767121768121769121770121771121772121773121774121775121776121777121778121779121780121781121782121783121784121785121786121787121788121789121790121791121792121793121794121795121796121797121798121799121800121801121802121803121804121805121806121807121808121809121810121811121812121813121814121815121816121817121818121819121820121821121822121823121824121825121826121827121828121829121830121831121832121833121834121835121836121837121838121839121840121841121842121843121844121845121846121847121848121849121850121851121852121853121854121855121856121857121858121859121860121861121862121863121864121865121866121867121868121869121870121871121872121873121874121875121876121877121878121879121880121881121882121883121884121885121886121887121888121889121890121891121892121893121894121895121896121897121898121899121900121901121902121903121904121905121906121907121908121909121910121911121912121913121914121915121916121917121918121919121920121921121922121923121924121925121926121927121928121929121930121931121932121933121934121935121936121937121938121939121940121941121942121943121944121945121946121947121948121949121950121951121952121953121954121955121956121957121958121959121960121961121962121963121964121965121966121967121968121969121970121971121972121973121974121975121976121977121978121979121980121981121982121983121984121985121986121987121988121989121990121991121992121993121994121995121996121997121998121999122000122001122002122003122004122005122006122007122008122009122010122011122012122013122014122015122016122017122018122019122020122021122022122023122024122025122026122027122028122029122030122031122032122033122034122035122036122037122038122039122040122041122042122043122044122045122046122047122048122049122050122051122052122053122054122055122056122057122058122059122060122061122062122063122064122065122066122067122068122069122070122071122072122073122074122075122076122077122078122079122080122081122082122083122084122085122086122087122088122089122090122091122092122093122094122095122096122097122098122099122100122101122102122103122104122105122106122107122108122109122110122111122112122113122114122115122116122117122118122119122120122121122122122123122124122125122126122127122128122129122130122131122132122133122134122135122136122137122138122139122140122141122142122143122144122145122146122147122148122149122150122151122152122153122154122155122156122157122158122159122160122161122162122163122164122165122166122167122168122169122170122171122172122173122174122175122176122177122178122179122180122181122182122183122184122185122186122187122188122189122190122191122192122193122194122195122196122197122198122199122200122201122202122203122204122205122206122207122208122209122210122211122212122213122214122215122216122217122218122219122220122221122222122223122224122225122226122227122228122229122230122231122232122233122234122235122236122237122238122239122240122241122242122243122244122245122246122247122248122249122250122251122252122253122254122255122256122257122258122259122260122261122262122263122264122265122266122267122268122269122270122271122272122273122274122275122276122277122278122279122280122281122282122283122284122285122286122287122288122289122290122291122292122293122294122295122296122297122298122299122300122301122302122303122304122305122306122307122308122309122310122311122312122313122314122315122316122317122318122319122320122321122322122323122324122325122326122327122328122329122330122331122332122333122334122335122336122337122338122339122340122341122342122343122344122345122346122347122348122349122350122351122352122353122354122355122356122357122358122359122360122361122362122363122364122365122366122367122368122369122370122371122372122373122374122375122376122377122378122379122380122381122382122383122384122385122386122387122388122389122390122391122392122393122394122395122396122397122398122399122400122401122402122403122404122405122406122407122408122409122410122411122412122413122414122415122416122417122418122419122420122421122422122423122424122425122426122427122428122429122430122431122432122433122434122435122436122437122438122439122440122441122442122443122444122445122446122447122448122449122450122451122452122453122454122455122456122457122458122459122460122461122462122463122464122465122466122467122468122469122470122471122472122473122474122475122476122477122478122479122480122481122482122483122484122485122486122487122488122489122490122491122492122493122494122495122496122497122498122499122500122501122502122503122504122505122506122507122508122509122510122511122512122513122514122515122516122517122518122519122520122521122522122523122524122525122526122527122528122529122530122531122532122533122534122535122536122537122538122539122540122541122542122543122544122545122546122547122548122549122550122551122552122553122554122555122556122557122558122559122560122561122562122563122564122565122566122567122568122569122570122571122572122573122574122575122576122577122578122579122580122581122582122583122584122585122586122587122588122589122590122591122592122593122594122595122596122597122598122599122600122601122602122603122604122605122606122607122608122609122610122611122612122613122614122615122616122617122618122619122620122621122622122623122624122625122626122627122628122629122630122631122632122633122634122635122636122637122638122639122640122641122642122643122644122645122646122647122648122649122650122651122652122653122654122655122656122657122658122659122660122661122662122663122664122665122666122667122668122669122670122671122672122673122674122675122676122677122678122679122680122681122682122683122684122685122686122687122688122689122690122691122692122693122694122695122696122697122698122699122700122701122702122703122704122705122706122707122708122709122710122711122712122713122714122715122716122717122718122719122720122721122722122723122724122725122726122727122728122729122730122731122732122733122734122735122736122737122738122739122740122741122742122743122744122745122746122747122748122749122750122751122752122753122754122755122756122757122758122759122760122761122762122763122764122765122766122767122768122769122770122771122772122773122774122775122776122777122778122779122780122781122782122783122784122785122786122787122788122789122790122791122792122793122794122795122796122797122798122799122800122801122802122803122804122805122806122807122808122809122810122811122812122813122814122815122816122817122818122819122820122821122822122823122824122825122826122827122828122829122830122831122832122833122834122835122836122837122838122839122840122841122842122843122844122845122846122847122848122849122850122851122852122853122854122855122856122857122858122859122860122861122862122863122864122865122866122867122868122869122870122871122872122873122874122875122876122877122878122879122880122881122882122883122884122885122886122887122888122889122890122891122892122893122894122895122896122897122898122899122900122901122902122903122904122905122906122907122908122909122910122911122912122913122914122915122916122917122918122919122920122921122922122923122924122925122926122927122928122929122930122931122932122933122934122935122936122937122938122939122940122941122942122943122944122945122946122947122948122949122950122951122952122953122954122955122956122957122958122959122960122961122962122963122964122965122966122967122968122969122970122971122972122973122974122975122976122977122978122979122980122981122982122983122984122985122986122987122988122989122990122991122992122993122994122995122996122997122998122999123000123001123002123003123004123005123006123007123008123009123010123011123012123013123014123015123016123017123018123019123020123021123022123023123024123025123026123027123028123029123030123031123032123033123034123035123036123037123038123039123040123041123042123043123044123045123046123047123048123049123050123051123052123053123054123055123056123057123058123059123060123061123062123063123064123065123066123067123068123069123070123071123072123073123074123075123076123077123078123079123080123081123082123083123084123085123086123087123088123089123090123091123092123093123094123095123096123097123098123099123100123101123102123103123104123105123106123107123108123109123110123111123112123113123114123115123116123117123118123119123120123121123122123123123124123125123126123127123128123129123130123131123132123133123134123135123136123137123138123139123140123141123142123143123144123145123146123147123148123149123150123151123152123153123154123155123156123157123158123159123160123161123162123163123164123165123166123167123168123169123170123171123172123173123174123175123176123177123178123179123180123181123182123183123184123185123186123187123188123189123190123191123192123193123194123195123196123197123198123199123200123201123202123203123204123205123206123207123208123209123210123211123212123213123214123215123216123217123218123219123220123221123222123223123224123225123226123227123228123229123230123231123232123233123234123235123236123237123238123239123240123241123242123243123244123245123246123247123248123249123250123251123252123253123254123255123256123257123258123259123260123261123262123263123264123265123266123267123268123269123270123271123272123273123274123275123276123277123278123279123280123281123282123283123284123285123286123287123288123289123290123291123292123293123294123295123296123297123298123299123300123301123302123303123304123305123306123307123308123309123310123311123312123313123314123315123316123317123318123319123320123321123322123323123324123325123326123327123328123329123330123331123332123333123334123335123336123337123338123339123340123341123342123343123344123345123346123347123348123349123350123351123352123353123354123355123356123357123358123359123360123361123362123363123364123365123366123367123368123369123370123371123372123373123374123375123376123377123378123379123380123381123382123383123384123385123386123387123388123389123390123391123392123393123394123395123396123397123398123399123400123401123402123403123404123405123406123407123408123409123410123411123412123413123414123415123416123417123418123419123420123421123422123423123424123425123426123427123428123429123430123431123432123433123434123435123436123437123438123439123440123441123442123443123444123445123446123447123448123449123450123451123452123453123454123455123456123457123458123459123460123461123462123463123464123465123466123467123468123469123470123471123472123473123474123475123476123477123478123479123480123481123482123483123484123485123486123487123488123489123490123491123492123493123494123495123496123497123498123499123500123501123502123503123504123505123506123507123508123509123510123511123512123513123514123515123516123517123518123519123520123521123522123523123524123525123526123527123528123529123530123531123532123533123534123535123536123537123538123539123540123541123542123543123544123545123546123547123548123549123550123551123552123553123554123555123556123557123558123559123560123561123562123563123564123565123566123567123568123569123570123571123572123573123574123575123576123577123578123579123580123581123582123583123584123585123586123587123588123589123590123591123592123593123594123595123596123597123598123599123600123601123602123603123604123605123606123607123608123609123610123611123612123613123614123615123616123617123618123619123620123621123622123623123624123625123626123627123628123629123630123631123632123633123634123635123636123637123638123639123640123641123642123643123644123645123646123647123648123649123650123651123652123653123654123655123656123657123658123659123660123661123662123663123664123665123666123667123668123669123670123671123672123673123674123675123676123677123678123679123680123681123682123683123684123685123686123687123688123689123690123691123692123693123694123695123696123697123698123699123700123701123702123703123704123705123706123707123708123709123710123711123712123713123714123715123716123717123718123719123720123721123722123723123724123725123726123727123728123729123730123731123732123733123734123735123736123737123738123739123740123741123742123743123744123745123746123747123748123749123750123751123752123753123754123755123756123757123758123759123760123761123762123763123764123765123766123767123768123769123770123771123772123773123774123775123776123777123778123779123780123781123782123783123784123785123786123787123788123789123790123791123792123793123794123795123796123797123798123799123800123801123802123803123804123805123806123807123808123809123810123811123812123813123814123815123816123817123818123819123820123821123822123823123824123825123826123827123828123829123830123831123832123833123834123835123836123837123838123839123840123841123842123843123844123845123846123847123848123849123850123851123852123853123854123855123856123857123858123859123860123861123862123863123864123865123866123867123868123869123870123871123872123873123874123875123876123877123878123879123880123881123882123883123884123885123886123887123888123889123890123891123892123893123894123895123896123897123898123899123900123901123902123903123904123905123906123907123908123909123910123911123912123913123914123915123916123917123918123919123920123921123922123923123924123925123926123927123928123929123930123931123932123933123934123935123936123937123938123939123940123941123942123943123944123945123946123947123948123949123950123951123952123953123954123955123956123957123958123959123960123961123962123963123964123965123966123967123968123969123970123971123972123973123974123975123976123977123978123979123980123981123982123983123984123985123986123987123988123989123990123991123992123993123994123995123996123997123998123999124000124001124002124003124004124005124006124007124008124009124010124011124012124013124014124015124016124017124018124019124020124021124022124023124024124025124026124027124028124029124030124031124032124033124034124035124036124037124038124039124040124041124042124043124044124045124046124047124048124049124050124051124052124053124054124055124056124057124058124059124060124061124062124063124064124065124066124067124068124069124070124071124072124073124074124075124076124077124078124079124080124081124082124083124084124085124086124087124088124089124090124091124092124093124094124095124096124097124098124099124100124101124102124103124104124105124106124107124108124109124110124111124112124113124114124115124116124117124118124119124120124121124122124123124124124125124126124127124128124129124130124131124132124133124134124135124136124137124138124139124140124141124142124143124144124145124146124147124148124149124150124151124152124153124154124155124156124157124158124159124160124161124162124163124164124165124166124167124168124169124170124171124172124173124174124175124176124177124178124179124180124181124182124183124184124185124186124187124188124189124190124191124192124193124194124195124196124197124198124199124200124201124202124203124204124205124206124207124208124209124210124211124212124213124214124215124216124217124218124219124220124221124222124223124224124225124226124227124228124229124230124231124232124233124234124235124236124237124238124239124240124241124242124243124244124245124246124247124248124249124250124251124252124253124254124255124256124257124258124259124260124261124262124263124264124265124266124267124268124269124270124271124272124273124274124275124276124277124278124279124280124281124282124283124284124285124286124287124288124289124290124291124292124293124294124295124296124297124298124299124300124301124302124303124304124305124306124307124308124309124310124311124312124313124314124315124316124317124318124319124320124321124322124323124324124325124326124327124328124329124330124331124332124333124334124335124336124337124338124339124340124341124342124343124344124345124346124347124348124349124350124351124352124353124354124355124356124357124358124359124360124361124362124363124364124365124366124367124368124369124370124371124372124373124374124375124376124377124378124379124380124381124382124383124384124385124386124387124388124389124390124391124392124393124394124395124396124397124398124399124400124401124402124403124404124405124406124407124408124409124410124411124412124413124414124415124416124417124418124419124420124421124422124423124424124425124426124427124428124429124430124431124432124433124434124435124436124437124438124439124440124441124442124443124444124445124446124447124448124449124450124451124452124453124454124455124456124457124458124459124460124461124462124463124464124465124466124467124468124469124470124471124472124473124474124475124476124477124478124479124480124481124482124483124484124485124486124487124488124489124490124491124492124493124494124495124496124497124498124499124500124501124502124503124504124505124506124507124508124509124510124511124512124513124514124515124516124517124518124519124520124521124522124523124524124525124526124527124528124529124530124531124532124533124534124535124536124537124538124539124540124541124542124543124544124545124546124547124548124549124550124551124552124553124554124555124556124557124558124559124560124561124562124563124564124565124566124567124568124569124570124571124572124573124574124575124576124577124578124579124580124581124582124583124584124585124586124587124588124589124590124591124592124593124594124595124596124597124598124599124600124601124602124603124604124605124606124607124608124609124610124611124612124613124614124615124616124617124618124619124620124621124622124623124624124625124626124627124628124629124630124631124632124633124634124635124636124637124638124639124640124641124642124643124644124645124646124647124648124649124650124651124652124653124654124655124656124657124658124659124660124661124662124663124664124665124666124667124668124669124670124671124672124673124674124675124676124677124678124679124680124681124682124683124684124685124686124687124688124689124690124691124692124693124694124695124696124697124698124699124700124701124702124703124704124705124706124707124708124709124710124711124712124713124714124715124716124717124718124719124720124721124722124723124724124725124726124727124728124729124730124731124732124733124734124735124736124737124738124739124740124741124742124743124744124745124746124747124748124749124750124751124752124753124754124755124756124757124758124759124760124761124762124763124764124765124766124767124768124769124770124771124772124773124774124775124776124777124778124779124780124781124782124783124784124785124786124787124788124789124790124791124792124793124794124795124796124797124798124799124800124801124802124803124804124805124806124807124808124809124810124811124812124813124814124815124816124817124818124819124820124821124822124823124824124825124826124827124828124829124830124831124832124833124834124835124836124837124838124839124840124841124842124843124844124845124846124847124848124849124850124851124852124853124854124855124856124857124858124859124860124861124862124863124864124865124866124867124868124869124870124871124872124873124874124875124876124877124878124879124880124881124882124883124884124885124886124887124888124889124890124891124892124893124894124895124896124897124898124899124900124901124902124903124904124905124906124907124908124909124910124911124912124913124914124915124916124917124918124919124920124921124922124923124924124925124926124927124928124929124930124931124932124933124934124935124936124937124938124939124940124941124942124943124944124945124946124947124948124949124950124951124952124953124954124955124956124957124958124959124960124961124962124963124964124965124966124967124968124969124970124971124972124973124974124975124976124977124978124979124980124981124982124983124984124985124986124987124988124989124990124991124992124993124994124995124996124997124998124999125000125001125002125003125004125005125006125007125008125009125010125011125012125013125014125015125016125017125018125019125020125021125022125023125024125025125026125027125028125029125030125031125032125033125034125035125036125037125038125039125040125041125042125043125044125045125046125047125048125049125050125051125052125053125054125055125056125057125058125059125060125061125062125063125064125065125066125067125068125069125070125071125072125073125074125075125076125077125078125079125080125081125082125083125084125085125086125087125088125089125090125091125092125093125094125095125096125097125098125099125100125101125102125103125104125105125106125107125108125109125110125111125112125113125114125115125116125117125118125119125120125121125122125123125124125125125126125127125128125129125130125131125132125133125134125135125136125137125138125139125140125141125142125143125144125145125146125147125148125149125150125151125152125153125154125155125156125157125158125159125160125161125162125163125164125165125166125167125168125169125170125171125172125173125174125175125176125177125178125179125180125181125182125183125184125185125186125187125188125189125190125191125192125193125194125195125196125197125198125199125200125201125202125203125204125205125206125207125208125209125210125211125212125213125214125215125216125217125218125219125220125221125222125223125224125225125226125227125228125229125230125231125232125233125234125235125236125237125238125239125240125241125242125243125244125245125246125247125248125249125250125251125252125253125254125255125256125257125258125259125260125261125262125263125264125265125266125267125268125269125270125271125272125273125274125275125276125277125278125279125280125281125282125283125284125285125286125287125288125289125290125291125292125293125294125295125296125297125298125299125300125301125302125303125304125305125306125307125308125309125310125311125312125313125314125315125316125317125318125319125320125321125322125323125324125325125326125327125328125329125330125331125332125333125334125335125336125337125338125339125340125341125342125343125344125345125346125347125348125349125350125351125352125353125354125355125356125357125358125359125360125361125362125363125364125365125366125367125368125369125370125371125372125373125374125375125376125377125378125379125380125381125382125383125384125385125386125387125388125389125390125391125392125393125394125395125396125397125398125399125400125401125402125403125404125405125406125407125408125409125410125411125412125413125414125415125416125417125418125419125420125421125422125423125424125425125426125427125428125429125430125431125432125433125434125435125436125437125438125439125440125441125442125443125444125445125446125447125448125449125450125451125452125453125454125455125456125457125458125459125460125461125462125463125464125465125466125467125468125469125470125471125472125473125474125475125476125477125478125479125480125481125482125483125484125485125486125487125488125489125490125491125492125493125494125495125496125497125498125499125500125501125502125503125504125505125506125507125508125509125510125511125512125513125514125515125516125517125518125519125520125521125522125523125524125525125526125527125528125529125530125531125532125533125534125535125536125537125538125539125540125541125542125543125544125545125546125547125548125549125550125551125552125553125554125555125556125557125558125559125560125561125562125563125564125565125566125567125568125569125570125571125572125573125574125575125576125577125578125579125580125581125582125583125584125585125586125587125588125589125590125591125592125593125594125595125596125597125598125599125600125601125602125603125604125605125606125607125608125609125610125611125612125613125614125615125616125617125618125619125620125621125622125623125624125625125626125627125628125629125630125631125632125633125634125635125636125637125638125639125640125641125642125643125644125645125646125647125648125649125650125651125652125653125654125655125656125657125658125659125660125661125662125663125664125665125666125667125668125669125670125671125672125673125674125675125676125677125678125679125680125681125682125683125684125685125686125687125688125689125690125691125692125693125694125695125696125697125698125699125700125701125702125703125704125705125706125707125708125709125710125711125712125713125714125715125716125717125718125719125720125721125722125723125724125725125726125727125728125729125730125731125732125733125734125735125736125737125738125739125740125741125742125743125744125745125746125747125748125749125750125751125752125753125754125755125756125757125758125759125760125761125762125763125764125765125766125767125768125769125770125771125772125773125774125775125776125777125778125779125780125781125782125783125784125785125786125787125788125789125790125791125792125793125794125795125796125797125798125799125800125801125802125803125804125805125806125807125808125809125810125811125812125813125814125815125816125817125818125819125820125821125822125823125824125825125826125827125828125829125830125831125832125833125834125835125836125837125838125839125840125841125842125843125844125845125846125847125848125849125850125851125852125853125854125855125856125857125858125859125860125861125862125863125864125865125866125867125868125869125870125871125872125873125874125875125876125877125878125879125880125881125882125883125884125885125886125887125888125889125890125891125892125893125894125895125896125897125898125899125900125901125902125903125904125905125906125907125908125909125910125911125912125913125914125915125916125917125918125919125920125921125922125923125924125925125926125927125928125929125930125931125932125933125934125935125936125937125938125939125940125941125942125943125944125945125946125947125948125949125950125951125952125953125954125955125956125957125958125959125960125961125962125963125964125965125966125967125968125969125970125971125972125973125974125975125976125977125978125979125980125981125982125983125984125985125986125987125988125989125990125991125992125993125994125995125996125997125998125999126000126001126002126003126004126005126006126007126008126009126010126011126012126013126014126015126016126017126018126019126020126021126022126023126024126025126026126027126028126029126030126031126032126033126034126035126036126037126038126039126040126041126042126043126044126045126046126047126048126049126050126051126052126053126054126055126056126057126058126059126060126061126062126063126064126065126066126067126068126069126070126071126072126073126074126075126076126077126078126079126080126081126082126083126084126085126086126087126088126089126090126091126092126093126094126095126096126097126098126099126100126101126102126103126104126105126106126107126108126109126110126111126112126113126114126115126116126117126118126119126120126121126122126123126124126125126126126127126128126129126130126131126132126133126134126135126136126137126138126139126140126141126142126143126144126145126146126147126148126149126150126151126152126153126154126155126156126157126158126159126160126161126162126163126164126165126166126167126168126169126170126171126172126173126174126175126176126177126178126179126180126181126182126183126184126185126186126187126188126189126190126191126192126193126194126195126196126197126198126199126200126201126202126203126204126205126206126207126208126209126210126211126212126213126214126215126216126217126218126219126220126221126222126223126224126225126226126227126228126229126230126231126232126233126234126235126236126237126238126239126240126241126242126243126244126245126246126247126248126249126250126251126252126253126254126255126256126257126258126259126260126261126262126263126264126265126266126267126268126269126270126271126272126273126274126275126276126277126278126279126280126281126282126283126284126285126286126287126288126289126290126291126292126293126294126295126296126297126298126299126300126301126302126303126304126305126306126307126308126309126310126311126312126313126314126315126316126317126318126319126320126321126322126323126324126325126326126327126328126329126330126331126332126333126334126335126336126337126338126339126340126341126342126343126344126345126346126347126348126349126350126351126352126353126354126355126356126357126358126359126360126361126362126363126364126365126366126367126368126369126370126371126372126373126374126375126376126377126378126379126380126381126382126383126384126385126386126387126388126389126390126391126392126393126394126395126396126397126398126399126400126401126402126403126404126405126406126407126408126409126410126411126412126413126414126415126416126417126418126419126420126421126422126423126424126425126426126427126428126429126430126431126432126433126434126435126436126437126438126439126440126441126442126443126444126445126446126447126448126449126450126451126452126453126454126455126456126457126458126459126460126461126462126463126464126465126466126467126468126469126470126471126472126473126474126475126476126477126478126479126480126481126482126483126484126485126486126487126488126489126490126491126492126493126494126495126496126497126498126499126500126501126502126503126504126505126506126507126508126509126510126511126512126513126514126515126516126517126518126519126520126521126522126523126524126525126526126527126528126529126530126531126532126533126534126535126536126537126538126539126540126541126542126543126544126545126546126547126548126549126550126551126552126553126554126555126556126557126558126559126560126561126562126563126564126565126566126567126568126569126570126571126572126573126574126575126576126577126578126579126580126581126582126583126584126585126586126587126588126589126590126591126592126593126594126595126596126597126598126599126600126601126602126603126604126605126606126607126608126609126610126611126612126613126614126615126616126617126618126619126620126621126622126623126624126625126626126627126628126629126630126631126632126633126634126635126636126637126638126639126640126641126642126643126644126645126646126647126648126649126650126651126652126653126654126655126656126657126658126659126660126661126662126663126664126665126666126667126668126669126670126671126672126673126674126675126676126677126678126679126680126681126682126683126684126685126686126687126688126689126690126691126692126693126694126695126696126697126698126699126700126701126702126703126704126705126706126707126708126709126710126711126712126713126714126715126716126717126718126719126720126721126722126723126724126725126726126727126728126729126730126731126732126733126734126735126736126737126738126739126740126741126742126743126744126745126746126747126748126749126750126751126752126753126754126755126756126757126758126759126760126761126762126763126764126765126766126767126768126769126770126771126772126773126774126775126776126777126778126779126780126781126782126783126784126785126786126787126788126789126790126791126792126793126794126795126796126797126798126799126800126801126802126803126804126805126806126807126808126809126810126811126812126813126814126815126816126817126818126819126820126821126822126823126824126825126826126827126828126829126830126831126832126833126834126835126836126837126838126839126840126841126842126843126844126845126846126847126848126849126850126851126852126853126854126855126856126857126858126859126860126861126862126863126864126865126866126867126868126869126870126871126872126873126874126875126876126877126878126879126880126881126882126883126884126885126886126887126888126889126890126891126892126893126894126895126896126897126898126899126900126901126902126903126904126905126906126907126908126909126910126911126912126913126914126915126916126917126918126919126920126921126922126923126924126925126926126927126928126929126930126931126932126933126934126935126936126937126938126939126940126941126942126943126944126945126946126947126948126949126950126951126952126953126954126955126956126957126958126959126960126961126962126963126964126965126966126967126968126969126970126971126972126973126974126975126976126977126978126979126980126981126982126983126984126985126986126987126988126989126990126991126992126993126994126995126996126997126998126999127000127001127002127003127004127005127006127007127008127009127010127011127012127013127014127015127016127017127018127019127020127021127022127023127024127025127026127027127028127029127030127031127032127033127034127035127036127037127038127039127040127041127042127043127044127045127046127047127048127049127050127051127052127053127054127055127056127057127058127059127060127061127062127063127064127065127066127067127068127069127070127071127072127073127074127075127076127077127078127079127080127081127082127083127084127085127086127087127088127089127090127091127092127093127094127095127096127097127098127099127100127101127102127103127104127105127106127107127108127109127110127111127112127113127114127115127116127117127118127119127120127121127122127123127124127125127126127127127128127129127130127131127132127133127134127135127136127137127138127139127140127141127142127143127144127145127146127147127148127149127150127151127152127153127154127155127156127157127158127159127160127161127162127163127164127165127166127167127168127169127170127171127172127173127174127175127176127177127178127179127180127181127182127183127184127185127186127187127188127189127190127191127192127193127194127195127196127197127198127199127200127201127202127203127204127205127206127207127208127209127210127211127212127213127214127215127216127217127218127219127220127221127222127223127224127225127226127227127228127229127230127231127232127233127234127235127236127237127238127239127240127241127242127243127244127245127246127247127248127249127250127251127252127253127254127255127256127257127258127259127260127261127262127263127264127265127266127267127268127269127270127271127272127273127274127275127276127277127278127279127280127281127282127283127284127285127286127287127288127289127290127291127292127293127294127295127296127297127298127299127300127301127302127303127304127305127306127307127308127309127310127311127312127313127314127315127316127317127318127319127320127321127322127323127324127325127326127327127328127329127330127331127332127333127334127335127336127337127338127339127340127341127342127343127344127345127346127347127348127349127350127351127352127353127354127355127356127357127358127359127360127361127362127363127364127365127366127367127368127369127370127371127372127373127374127375127376127377127378127379127380127381127382127383127384127385127386127387127388127389127390127391127392127393127394127395127396127397127398127399127400127401127402127403127404127405127406127407127408127409127410127411127412127413127414127415127416127417127418127419127420127421127422127423127424127425127426127427127428127429127430127431127432127433127434127435127436127437127438127439127440127441127442127443127444127445127446127447127448127449127450127451127452127453127454127455127456127457127458127459127460127461127462127463127464127465127466127467127468127469127470127471127472127473127474127475127476127477127478127479127480127481127482127483127484127485127486127487127488127489127490127491127492127493127494127495127496127497127498127499127500127501127502127503127504127505127506127507127508127509127510127511127512127513127514127515127516127517127518127519127520127521127522127523127524127525127526127527127528127529127530127531127532127533127534127535127536127537127538127539127540127541127542127543127544127545127546127547127548127549127550127551127552127553127554127555127556127557127558127559127560127561127562127563127564127565127566127567127568127569127570127571127572127573127574127575127576127577127578127579127580127581127582127583127584127585127586127587127588127589127590127591127592127593127594127595127596127597127598127599127600127601127602127603127604127605127606127607127608127609127610127611127612127613127614127615127616127617127618127619127620127621127622127623127624127625127626127627127628127629127630127631127632127633127634127635127636127637127638127639127640127641127642127643127644127645127646127647127648127649127650127651127652127653127654127655127656127657127658127659127660127661127662127663127664127665127666127667127668127669127670127671127672127673127674127675127676127677127678127679127680127681127682127683127684127685127686127687127688127689127690127691127692127693127694127695127696127697127698127699127700127701127702127703127704127705127706127707127708127709127710127711127712127713127714127715127716127717127718127719127720127721127722127723127724127725127726127727127728127729127730127731127732127733127734127735127736127737127738127739127740127741127742127743127744127745127746127747127748127749127750127751127752127753127754127755127756127757127758127759127760127761127762127763127764127765127766127767127768127769127770127771127772127773127774127775127776127777127778127779127780127781127782127783127784127785127786127787127788127789127790127791127792127793127794127795127796127797127798127799127800127801127802127803127804127805127806127807127808127809127810127811127812127813127814127815127816127817127818127819127820127821127822127823127824127825127826127827127828127829127830127831127832127833127834127835127836127837127838127839127840127841127842127843127844127845127846127847127848127849127850127851127852127853127854127855127856127857127858127859127860127861127862127863127864127865127866127867127868127869127870127871127872127873127874127875127876127877127878127879127880127881127882127883127884127885127886127887127888127889127890127891127892127893127894127895127896127897127898127899127900127901127902127903127904127905127906127907127908127909127910127911127912127913127914127915127916127917127918127919127920127921127922127923127924127925127926127927127928127929127930127931127932127933127934127935127936127937127938127939127940127941127942127943127944127945127946127947127948127949127950127951127952127953127954127955127956127957127958127959127960127961127962127963127964127965127966127967127968127969127970127971127972127973127974127975127976127977127978127979127980127981127982127983127984127985127986127987127988127989127990127991127992127993127994127995127996127997127998127999128000128001128002128003128004128005128006128007128008128009128010128011128012128013128014128015128016128017128018128019128020128021128022128023128024128025128026128027128028128029128030128031128032128033128034128035128036128037128038128039128040128041128042128043128044128045128046128047128048128049128050128051128052128053128054128055128056128057128058128059128060128061128062128063128064128065128066128067128068128069128070128071128072128073128074128075128076128077128078128079128080128081128082128083128084128085128086128087128088128089128090128091128092128093128094128095128096128097128098128099128100128101128102128103128104128105128106128107128108128109128110128111128112128113128114128115128116128117128118128119128120128121128122128123128124128125128126128127128128128129128130128131128132128133128134128135128136128137128138128139128140128141128142128143128144128145128146128147128148128149128150128151128152128153128154128155128156128157128158128159128160128161128162128163128164128165128166128167128168128169128170128171128172128173128174128175128176128177128178128179128180128181128182128183128184128185128186128187128188128189128190128191128192128193128194128195128196128197128198128199128200128201128202128203128204128205128206128207128208128209128210128211128212128213128214128215128216128217128218128219128220128221128222128223128224128225128226128227128228128229128230128231128232128233128234128235128236128237128238128239128240128241128242128243128244128245128246128247128248128249128250128251128252128253128254128255128256128257128258128259128260128261128262128263128264128265128266128267128268128269128270128271128272128273128274128275128276128277128278128279128280128281128282128283128284128285128286128287128288128289128290128291128292128293128294128295128296128297128298128299128300128301128302128303128304128305128306128307128308128309128310128311128312128313128314128315128316128317128318128319128320128321128322128323128324128325128326128327128328128329128330128331128332128333128334128335128336128337128338128339128340128341128342128343128344128345128346128347128348128349128350128351128352128353128354128355128356128357128358128359128360128361128362128363128364128365128366128367128368128369128370128371128372128373128374128375128376128377128378128379128380128381128382128383128384128385128386128387128388128389128390128391128392128393128394128395128396128397128398128399128400128401128402128403128404128405128406128407128408128409128410128411128412128413128414128415128416128417128418128419128420128421128422128423128424128425128426128427128428128429128430128431128432128433128434128435128436128437128438128439128440128441128442128443128444128445128446128447128448128449128450128451128452128453128454128455128456128457128458128459128460128461128462128463128464128465128466128467128468128469128470128471128472128473128474128475128476128477128478128479128480128481128482128483128484128485128486128487128488128489128490128491128492128493128494128495128496128497128498128499128500128501128502128503128504128505128506128507128508128509128510128511128512128513128514128515128516128517128518128519128520128521128522128523128524128525128526128527128528128529128530128531128532128533128534128535128536128537128538128539128540128541128542128543128544128545128546128547128548128549128550128551128552128553128554128555128556128557128558128559128560128561128562128563128564128565128566128567128568128569128570128571128572128573128574128575128576128577128578128579128580128581128582128583128584128585128586128587128588128589128590128591128592128593128594128595128596128597128598128599128600128601128602128603128604128605128606128607128608128609128610128611128612128613128614128615128616128617128618128619128620128621128622128623128624128625128626128627128628128629128630128631128632128633128634128635128636128637128638128639128640128641128642128643128644128645128646128647128648128649128650128651128652128653128654128655128656128657128658128659128660128661128662128663128664128665128666128667128668128669128670128671128672128673128674128675128676128677128678128679128680128681128682128683128684128685128686128687128688128689128690128691128692128693128694128695128696128697128698128699128700128701128702128703128704128705128706128707128708128709128710128711128712128713128714128715128716128717128718128719128720128721128722128723128724128725128726128727128728128729128730128731128732128733128734128735128736128737128738128739128740128741128742128743128744128745128746128747128748128749128750128751128752128753128754128755128756128757128758128759128760128761128762128763128764128765128766128767128768128769128770128771128772128773128774128775128776128777128778128779128780128781128782128783128784128785128786128787128788128789128790128791128792128793128794128795128796128797128798128799128800128801128802128803128804128805128806128807128808128809128810128811128812128813128814128815128816128817128818128819128820128821128822128823128824128825128826128827128828128829128830128831128832128833128834128835128836128837128838128839128840128841128842128843128844128845128846128847128848128849128850128851128852128853128854128855128856128857128858128859128860128861128862128863128864128865128866128867128868128869128870128871128872128873128874128875128876128877128878128879128880128881128882128883128884128885128886128887128888128889128890128891128892128893128894128895128896128897128898128899128900128901128902128903128904128905128906128907128908128909128910128911128912128913128914128915128916128917128918128919128920128921128922128923128924128925128926128927128928128929128930128931128932128933128934128935128936128937128938128939128940128941128942128943128944128945128946128947128948128949128950128951128952128953128954128955128956128957128958128959128960128961128962128963128964128965128966128967128968128969128970128971128972128973128974128975128976128977128978128979128980128981128982128983128984128985128986128987128988128989128990128991128992128993128994128995128996128997128998128999129000129001129002129003129004129005129006129007129008129009129010129011129012129013129014129015129016129017129018129019129020129021129022129023129024129025129026129027129028129029129030129031129032129033129034129035129036129037129038129039129040129041129042129043129044129045129046129047129048129049129050129051129052129053129054129055129056129057129058129059129060129061129062129063129064129065129066129067129068129069129070129071129072129073129074129075129076129077129078129079129080129081129082129083129084129085129086129087129088129089129090129091129092129093129094129095129096129097129098129099129100129101129102129103129104129105129106129107129108129109129110129111129112129113129114129115129116129117129118129119129120129121129122129123129124129125129126129127129128129129129130129131129132129133129134129135129136129137129138129139129140129141129142129143129144129145129146129147129148129149129150129151129152129153129154129155129156129157129158129159129160129161129162129163129164129165129166129167129168129169129170129171129172129173129174129175129176129177129178129179129180129181129182129183129184129185129186129187129188129189129190129191129192129193129194129195129196129197129198129199129200129201129202129203129204129205129206129207129208129209129210129211129212129213129214129215129216129217129218129219129220129221129222129223129224129225129226129227129228129229129230129231129232129233129234129235129236129237129238129239129240129241129242129243129244129245129246129247129248129249129250129251129252129253129254129255129256129257129258129259129260129261129262129263129264129265129266129267129268129269129270129271129272129273129274129275129276129277129278129279129280129281129282129283129284129285129286129287129288129289129290129291129292129293129294129295129296129297129298129299129300129301129302129303129304129305129306129307129308129309129310129311129312129313129314129315129316129317129318129319129320129321129322129323129324129325129326129327129328129329129330129331129332129333129334129335129336129337129338129339129340129341129342129343129344129345129346129347129348129349129350129351129352129353129354129355129356129357129358129359129360129361129362129363129364129365129366129367129368129369129370129371129372129373129374129375129376129377129378129379129380129381129382129383129384129385129386129387129388129389129390129391129392129393129394129395129396129397129398129399129400129401129402129403129404129405129406129407129408129409129410129411129412129413129414129415129416129417129418129419129420129421129422129423129424129425129426129427129428129429129430129431129432129433129434129435129436129437129438129439129440129441129442129443129444129445129446129447129448129449129450129451129452129453129454129455129456129457129458129459129460129461129462129463129464129465129466129467129468129469129470129471129472129473129474129475129476129477129478129479129480129481129482129483129484129485129486129487129488129489129490129491129492129493129494129495129496129497129498129499129500129501129502129503129504129505129506129507129508129509129510129511129512129513129514129515129516129517129518129519129520129521129522129523129524129525129526129527129528129529129530129531129532129533129534129535129536129537129538129539129540129541129542129543129544129545129546129547129548129549129550129551129552129553129554129555129556129557129558129559129560129561129562129563129564129565129566129567129568129569129570129571129572129573129574129575129576129577129578129579129580129581129582129583129584129585129586129587129588129589129590129591129592129593129594129595129596129597129598129599129600129601129602129603129604129605129606129607129608129609129610129611129612129613129614129615129616129617129618129619129620129621129622129623129624129625129626129627129628129629129630129631129632129633129634129635129636129637129638129639129640129641129642129643129644129645129646129647129648129649129650129651129652129653129654129655129656129657129658129659129660129661129662129663129664129665129666129667129668129669129670129671129672129673129674129675129676129677129678129679129680129681129682129683129684129685129686129687129688129689129690129691129692129693129694129695129696129697129698129699129700129701129702129703129704129705129706129707129708129709129710129711129712129713129714129715129716129717129718129719129720129721129722129723129724129725129726129727129728129729129730129731129732129733129734129735129736129737129738129739129740129741129742129743129744129745129746129747129748129749129750129751129752129753129754129755129756129757129758129759129760129761129762129763129764129765129766129767129768129769129770129771129772129773129774129775129776129777129778129779129780129781129782129783129784129785129786129787129788129789129790129791129792129793129794129795129796129797129798129799129800129801129802129803129804129805129806129807129808129809129810129811129812129813129814129815129816129817129818129819129820129821129822129823129824129825129826129827129828129829129830129831129832129833129834129835129836129837129838129839129840129841129842129843129844129845129846129847129848129849129850129851129852129853129854129855129856129857129858129859129860129861129862129863129864129865129866129867129868129869129870129871129872129873129874129875129876129877129878129879129880129881129882129883129884129885129886129887129888129889129890129891129892129893129894129895129896129897129898129899129900129901129902129903129904129905129906129907129908129909129910129911129912129913129914129915129916129917129918129919129920129921129922129923129924129925129926129927129928129929129930129931129932129933129934129935129936129937129938129939129940129941129942129943129944129945129946129947129948129949129950129951129952129953129954129955129956129957129958129959129960129961129962129963129964129965129966129967129968129969129970129971129972129973129974129975129976129977129978129979129980129981129982129983129984129985129986129987129988129989129990129991129992129993129994129995129996129997129998129999130000130001130002130003130004130005130006130007130008130009130010130011130012130013130014130015130016130017130018130019130020130021130022130023130024130025130026130027130028130029130030130031130032130033130034130035130036130037130038130039130040130041130042130043130044130045130046130047130048130049130050130051130052130053130054130055130056130057130058130059130060130061130062130063130064130065130066130067130068130069130070130071130072130073130074130075130076130077130078130079130080130081130082130083130084130085130086130087130088130089130090130091130092130093130094130095130096130097130098130099130100130101130102130103130104130105130106130107130108130109130110130111130112130113130114130115130116130117130118130119130120130121130122130123130124130125130126130127130128130129130130130131130132130133130134130135130136130137130138130139130140130141130142130143130144130145130146130147130148130149130150130151130152130153130154130155130156130157130158130159130160130161130162130163130164130165130166130167130168130169130170130171130172130173130174130175130176130177130178130179130180130181130182130183130184130185130186130187130188130189130190130191130192130193130194130195130196130197130198130199130200130201130202130203130204130205130206130207130208130209130210130211130212130213130214130215130216130217130218130219130220130221130222130223130224130225130226130227130228130229130230130231130232130233130234130235130236130237130238130239130240130241130242130243130244130245130246130247130248130249130250130251130252130253130254130255130256130257130258130259130260130261130262130263130264130265130266130267130268130269130270130271130272130273130274130275130276130277130278130279130280130281130282130283130284130285130286130287130288130289130290130291130292130293130294130295130296130297130298130299130300130301130302130303130304130305130306130307130308130309130310130311130312130313130314130315130316130317130318130319130320130321130322130323130324130325130326130327130328130329130330130331130332130333130334130335130336130337130338130339130340130341130342130343130344130345130346130347130348130349130350130351130352130353130354130355130356130357130358130359130360130361130362130363130364130365130366130367130368130369130370130371130372130373130374130375130376130377130378130379130380130381130382130383130384130385130386130387130388130389130390130391130392130393130394130395130396130397130398130399130400130401130402130403130404130405130406130407130408130409130410130411130412130413130414130415130416130417130418130419130420130421130422130423130424130425130426130427130428130429130430130431130432130433130434130435130436130437130438130439130440130441130442130443130444130445130446130447130448130449130450130451130452130453130454130455130456130457130458130459130460130461130462130463130464130465130466130467130468130469130470130471130472130473130474130475130476130477130478130479130480130481130482130483130484130485130486130487130488130489130490130491130492130493130494130495130496130497130498130499130500130501130502130503130504130505130506130507130508130509130510130511130512130513130514130515130516130517130518130519130520130521130522130523130524130525130526130527130528130529130530130531130532130533130534130535130536130537130538130539130540130541130542130543130544130545130546130547130548130549130550130551130552130553130554130555130556130557130558130559130560130561130562130563130564130565130566130567130568130569130570130571130572130573130574130575130576130577130578130579130580130581130582130583130584130585130586130587130588130589130590130591130592130593130594130595130596130597130598130599130600130601130602130603130604130605130606130607130608130609130610130611130612130613130614130615130616130617130618130619130620130621130622130623130624130625130626130627130628130629130630130631130632130633130634130635130636130637130638130639130640130641130642130643130644130645130646130647130648130649130650130651130652130653130654130655130656130657130658130659130660130661130662130663130664130665130666130667130668130669130670130671130672130673130674130675130676130677130678130679130680130681130682130683130684130685130686130687130688130689130690130691130692130693130694130695130696130697130698130699130700130701130702130703130704130705130706130707130708130709130710130711130712130713130714130715130716130717130718130719130720130721130722130723130724130725130726130727130728130729130730130731130732130733130734130735130736130737130738130739130740130741130742130743130744130745130746130747130748130749130750130751130752130753130754130755130756130757130758130759130760130761130762130763130764130765130766130767130768130769130770130771130772130773130774130775130776130777130778130779130780130781130782130783130784130785130786130787130788130789130790130791130792130793130794130795130796130797130798130799130800130801130802130803130804130805130806130807130808130809130810130811130812130813130814130815130816130817130818130819130820130821130822130823130824130825130826130827130828130829130830130831130832130833130834130835130836130837130838130839130840130841130842130843130844130845130846130847130848130849130850130851130852130853130854130855130856130857130858130859130860130861130862130863130864130865130866130867130868130869130870130871130872130873130874130875130876130877130878130879130880130881130882130883130884130885130886130887130888130889130890130891130892130893130894130895130896130897130898130899130900130901130902130903130904130905130906130907130908130909130910130911130912130913130914130915130916130917130918130919130920130921130922130923130924130925130926130927130928130929130930130931130932130933130934130935130936130937130938130939130940130941130942130943130944130945130946130947130948130949130950130951130952130953130954130955130956130957130958130959130960130961130962130963130964130965130966130967130968130969130970130971130972130973130974130975130976130977130978130979130980130981130982130983130984130985130986130987130988130989130990130991130992130993130994130995130996130997130998130999131000131001131002131003131004131005131006131007131008131009131010131011131012131013131014131015131016131017131018131019131020131021131022131023131024131025131026131027131028131029131030131031131032131033131034131035131036131037131038131039131040131041131042131043131044131045131046131047131048131049131050131051131052131053131054131055131056131057131058131059131060131061131062131063131064131065131066131067131068131069131070131071131072131073131074131075131076131077131078131079131080131081131082131083131084131085131086131087131088131089131090131091131092131093131094131095131096131097131098131099131100131101131102131103131104131105131106131107131108131109131110131111131112131113131114131115131116131117131118131119131120131121131122131123131124131125131126131127131128131129131130131131131132131133131134131135131136131137131138131139131140131141131142131143131144131145131146131147131148131149131150131151131152131153131154131155131156131157131158131159131160131161131162131163131164131165131166131167131168131169131170131171131172131173131174131175131176131177131178131179131180131181131182131183131184131185131186131187131188131189131190131191131192131193131194131195131196131197131198131199131200131201131202131203131204131205131206131207131208131209131210131211131212131213131214131215131216131217131218131219131220131221131222131223131224131225131226131227131228131229131230131231131232131233131234131235131236131237131238131239131240131241131242131243131244131245131246131247131248131249131250131251131252131253131254131255131256131257131258131259131260131261131262131263131264131265131266131267131268131269131270131271131272131273131274131275131276131277131278131279131280131281131282131283131284131285131286131287131288131289131290131291131292131293131294131295131296131297131298131299131300131301131302131303131304131305131306131307131308131309131310131311131312131313131314131315131316131317131318131319131320131321131322131323131324131325131326131327131328131329131330131331131332131333131334131335131336131337131338131339131340131341131342131343131344131345131346131347131348131349131350131351131352131353131354131355131356131357131358131359131360131361131362131363131364131365131366131367131368131369131370131371131372131373131374131375131376131377131378131379131380131381131382131383131384131385131386131387131388131389131390131391131392131393131394131395131396131397131398131399131400131401131402131403131404131405131406131407131408131409131410131411131412131413131414131415131416131417131418131419131420131421131422131423131424131425131426131427131428131429131430131431131432131433131434131435131436131437131438131439131440131441131442131443131444131445131446131447131448131449131450131451131452131453131454131455131456131457131458131459131460131461131462131463131464131465131466131467131468131469131470131471131472131473131474131475131476131477131478131479131480131481131482131483131484131485131486131487131488131489131490131491131492131493131494131495131496131497131498131499131500131501131502131503131504131505131506131507131508131509131510131511131512131513131514131515131516131517131518131519131520131521131522131523131524131525131526131527131528131529131530131531131532131533131534131535131536131537131538131539131540131541131542131543131544131545131546131547131548131549131550131551131552131553131554131555131556131557131558131559131560131561131562131563131564131565131566131567131568131569131570131571131572131573131574131575131576131577131578131579131580131581131582131583131584131585131586131587131588131589131590131591131592131593131594131595131596131597131598131599131600131601131602131603131604131605131606131607131608131609131610131611131612131613131614131615131616131617131618131619131620131621131622131623131624131625131626131627131628131629131630131631131632131633131634131635131636131637131638131639131640131641131642131643131644131645131646131647131648131649131650131651131652131653131654131655131656131657131658131659131660131661131662131663131664131665131666131667131668131669131670131671131672131673131674131675131676131677131678131679131680131681131682131683131684131685131686131687131688131689131690131691131692131693131694131695131696131697131698131699131700131701131702131703131704131705131706131707131708131709131710131711131712131713131714131715131716131717131718131719131720131721131722131723131724131725131726131727131728131729131730131731131732131733131734131735131736131737131738131739131740131741131742131743131744131745131746131747131748131749131750131751131752131753131754131755131756131757131758131759131760131761131762131763131764131765131766131767131768131769131770131771131772131773131774131775131776131777131778131779131780131781131782131783131784131785131786131787131788131789131790131791131792131793131794131795131796131797131798131799131800131801131802131803131804131805131806131807131808131809131810131811131812131813131814131815131816131817131818131819131820131821131822131823131824131825131826131827131828131829131830131831131832131833131834131835131836131837131838131839131840131841131842131843131844131845131846131847131848131849131850131851131852131853131854131855131856131857131858131859131860131861131862131863131864131865131866131867131868131869131870131871131872131873131874131875131876131877131878131879131880131881131882131883131884131885131886131887131888131889131890131891131892131893131894131895131896131897131898131899131900131901131902131903131904131905131906131907131908131909131910131911131912131913131914131915131916131917131918131919131920131921131922131923131924131925131926131927131928131929131930131931131932131933131934131935131936131937131938131939131940131941131942131943131944131945131946131947131948131949131950131951131952131953131954131955131956131957131958131959131960131961131962131963131964131965131966131967131968131969131970131971131972131973131974131975131976131977131978131979131980131981131982131983131984131985131986131987131988131989131990131991131992131993131994131995131996131997131998131999132000132001132002132003132004132005132006132007132008132009132010132011132012132013132014132015132016132017132018132019132020132021132022132023132024132025132026132027132028132029132030132031132032132033132034132035132036132037132038132039132040132041132042132043132044132045132046132047132048132049132050132051132052132053132054132055132056132057132058132059132060132061132062132063132064132065132066132067132068132069132070132071132072132073132074132075132076132077132078132079132080132081132082132083132084132085132086132087132088132089132090132091132092132093132094132095132096132097132098132099132100132101132102132103132104132105132106132107132108132109132110132111132112132113132114132115132116132117132118132119132120132121132122132123132124132125132126132127132128132129132130132131132132132133132134132135132136132137132138132139132140132141132142132143132144132145132146132147132148132149132150132151132152132153132154132155132156132157132158132159132160132161132162132163132164132165132166132167132168132169132170132171132172132173132174132175132176132177132178132179132180132181132182132183132184132185132186132187132188132189132190132191132192132193132194132195132196132197132198132199132200132201132202132203132204132205132206132207132208132209132210132211132212132213132214132215132216132217132218132219132220132221132222132223132224132225132226132227132228132229132230132231132232132233132234132235132236132237132238132239132240132241132242132243132244132245132246132247132248132249132250132251132252132253132254132255132256132257132258132259132260132261132262132263132264132265132266132267132268132269132270132271132272132273132274132275132276132277132278132279132280132281132282132283132284132285132286132287132288132289132290132291132292132293132294132295132296132297132298132299132300132301132302132303132304132305132306132307132308132309132310132311132312132313132314132315132316132317132318132319132320132321132322132323132324132325132326132327132328132329132330132331132332132333132334132335132336132337132338132339132340132341132342132343132344132345132346132347132348132349132350132351132352132353132354132355132356132357132358132359132360132361132362132363132364132365132366132367132368132369132370132371132372132373132374132375132376132377132378132379132380132381132382132383132384132385132386132387132388132389132390132391132392132393132394132395132396132397132398132399132400132401132402132403132404132405132406132407132408132409132410132411132412132413132414132415132416132417132418132419132420132421132422132423132424132425132426132427132428132429132430132431132432132433132434132435132436132437132438132439132440132441132442132443132444132445132446132447132448132449132450132451132452132453132454132455132456132457132458132459132460132461132462132463132464132465132466132467132468132469132470132471132472132473132474132475132476132477132478132479132480132481132482132483132484132485132486132487132488132489132490132491132492132493132494132495132496132497132498132499132500132501132502132503132504132505132506132507132508132509132510132511132512132513132514132515132516132517132518132519132520132521132522132523132524132525132526132527132528132529132530132531132532132533132534132535132536132537132538132539132540132541132542132543132544132545132546132547132548132549132550132551132552132553132554132555132556132557132558132559132560132561132562132563132564132565132566132567132568132569132570132571132572132573132574132575132576132577132578132579132580132581132582132583132584132585132586132587132588132589132590132591132592132593132594132595132596132597132598132599132600132601132602132603132604132605132606132607132608132609132610132611132612132613132614132615132616132617132618132619132620132621132622132623132624132625132626132627132628132629132630132631132632132633132634132635132636132637132638132639132640132641132642132643132644132645132646132647132648132649132650132651132652132653132654132655132656132657132658132659132660132661132662132663132664132665132666132667132668132669132670132671132672132673132674132675132676132677132678132679132680132681132682132683132684132685132686132687132688132689132690132691132692132693132694132695132696132697132698132699132700132701132702132703132704132705132706132707132708132709132710132711132712132713132714132715132716132717132718132719132720132721132722132723132724132725132726132727132728132729132730132731132732132733132734132735132736132737132738132739132740132741132742132743132744132745132746132747132748132749132750132751132752132753132754132755132756132757132758132759132760132761132762132763132764132765132766132767132768132769132770132771132772132773132774132775132776132777132778132779132780132781132782132783132784132785132786132787132788132789132790132791132792132793132794132795132796132797132798132799132800132801132802132803132804132805132806132807132808132809132810132811132812132813132814132815132816132817132818132819132820132821132822132823132824132825132826132827132828132829132830132831132832132833132834132835132836132837132838132839132840132841132842132843132844132845132846132847132848132849132850132851132852132853132854132855132856132857132858132859132860132861132862132863132864132865132866132867132868132869132870132871132872132873132874132875132876132877132878132879132880132881132882132883132884132885132886132887132888132889132890132891132892132893132894132895132896132897132898132899132900132901132902132903132904132905132906132907132908132909132910132911132912132913132914132915132916132917132918132919132920132921132922132923132924132925132926132927132928132929132930132931132932132933132934132935132936132937132938132939132940132941132942132943132944132945132946132947132948132949132950132951132952132953132954132955132956132957132958132959132960132961132962132963132964132965132966132967132968132969132970132971132972132973132974132975132976132977132978132979132980132981132982132983132984132985132986132987132988132989132990132991132992132993132994132995132996132997132998132999133000133001133002133003133004133005133006133007133008133009133010133011133012133013133014133015133016133017133018133019133020133021133022133023133024133025133026133027133028133029133030133031133032133033133034133035133036133037133038133039133040133041133042133043133044133045133046133047133048133049133050133051133052133053133054133055133056133057133058133059133060133061133062133063133064133065133066133067133068133069133070133071133072133073133074133075133076133077133078133079133080133081133082133083133084133085133086133087133088133089133090133091133092133093133094133095133096133097133098133099133100133101133102133103133104133105133106133107133108133109133110133111133112133113133114133115133116133117133118133119133120133121133122133123133124133125133126133127133128133129133130133131133132133133133134133135133136133137133138133139133140133141133142133143133144133145133146133147133148133149133150133151133152133153133154133155133156133157133158133159133160133161133162133163133164133165133166133167133168133169133170133171133172133173133174133175133176133177133178133179133180133181133182133183133184133185133186133187133188133189133190133191133192133193133194133195133196133197133198133199133200133201133202133203133204133205133206133207133208133209133210133211133212133213133214133215133216133217133218133219133220133221133222133223133224133225133226133227133228133229133230133231133232133233133234133235133236133237133238133239133240133241133242133243133244133245133246133247133248133249133250133251133252133253133254133255133256133257133258133259133260133261133262133263133264133265133266133267133268133269133270133271133272133273133274133275133276133277133278133279133280133281133282133283133284133285133286133287133288133289133290133291133292133293133294133295133296133297133298133299133300133301133302133303133304133305133306133307133308133309133310133311133312133313133314133315133316133317133318133319133320133321133322133323133324133325133326133327133328133329133330133331133332133333133334133335133336133337133338133339133340133341133342133343133344133345133346133347133348133349133350133351133352133353133354133355133356133357133358133359133360133361133362133363133364133365133366133367133368133369133370133371133372133373133374133375133376133377133378133379133380133381133382133383133384133385133386133387133388133389133390133391133392133393133394133395133396133397133398133399133400133401133402133403133404133405133406133407133408133409133410133411133412133413133414133415133416133417133418133419133420133421133422133423133424133425133426133427133428133429133430133431133432133433133434133435133436133437133438133439133440133441133442133443133444133445133446133447133448133449133450133451133452133453133454133455133456133457133458133459133460133461133462133463133464133465133466133467133468133469133470133471133472133473133474133475133476133477133478133479133480133481133482133483133484133485133486133487133488133489133490133491133492133493133494133495133496133497133498133499133500133501133502133503133504133505133506133507133508133509133510133511133512133513133514133515133516133517133518133519133520133521133522133523133524133525133526133527133528133529133530133531133532133533133534133535133536133537133538133539133540133541133542133543133544133545133546133547133548133549133550133551133552133553133554133555133556133557133558133559133560133561133562133563133564133565133566133567133568133569133570133571133572133573133574133575133576133577133578133579133580133581133582133583133584133585133586133587133588133589133590133591133592133593133594133595133596133597133598133599133600133601133602133603133604133605133606133607133608133609133610133611133612133613133614133615133616133617133618133619133620133621133622133623133624133625133626133627133628133629133630133631133632133633133634133635133636133637133638133639133640133641133642133643133644133645133646133647133648133649133650133651133652133653133654133655133656133657133658133659133660133661133662133663133664133665133666133667133668133669133670133671133672133673133674133675133676133677133678133679133680133681133682133683133684133685133686133687133688133689133690133691133692133693133694133695133696133697133698133699133700133701133702133703133704133705133706133707133708133709133710133711133712133713133714133715133716133717133718133719133720133721133722133723133724133725133726133727133728133729133730133731133732133733133734133735133736133737133738133739133740133741133742133743133744133745133746133747133748133749133750133751133752133753133754133755133756133757133758133759133760133761133762133763133764133765133766133767133768133769133770133771133772133773133774133775133776133777133778133779133780133781133782133783133784133785133786133787133788133789133790133791133792133793133794133795133796133797133798133799133800133801133802133803133804133805133806133807133808133809133810133811133812133813133814133815133816133817133818133819133820133821133822133823133824133825133826133827133828133829133830133831133832133833133834133835133836133837133838133839133840133841133842133843133844133845133846133847133848133849133850133851133852133853133854133855133856133857133858133859133860133861133862133863133864133865133866133867133868133869133870133871133872133873133874133875133876133877133878133879133880133881133882133883133884133885133886133887133888133889133890133891133892133893133894133895133896133897133898133899133900133901133902133903133904133905133906133907133908133909133910133911133912133913133914133915133916133917133918133919133920133921133922133923133924133925133926133927133928133929133930133931133932133933133934133935133936133937133938133939133940133941133942133943133944133945133946133947133948133949133950133951133952133953133954133955133956133957133958133959133960133961133962133963133964133965133966133967133968133969133970133971133972133973133974133975133976133977133978133979133980133981133982133983133984133985133986133987133988133989133990133991133992133993133994133995133996133997133998133999134000134001134002134003134004134005134006134007134008134009134010134011134012134013134014134015134016134017134018134019134020134021134022134023134024134025134026134027134028134029134030134031134032134033134034134035134036134037134038134039134040134041134042134043134044134045134046134047134048134049134050134051134052134053134054134055134056134057134058134059134060134061134062134063134064134065134066134067134068134069134070134071134072134073134074134075134076134077134078134079134080134081134082134083134084134085134086134087134088134089134090134091134092134093134094134095134096134097134098134099134100134101134102134103134104134105134106134107134108134109134110134111134112134113134114134115134116134117134118134119134120134121134122134123134124134125134126134127134128134129134130134131134132134133134134134135134136134137134138134139134140134141134142134143134144134145134146134147134148134149134150134151134152134153134154134155134156134157134158134159134160134161134162134163134164134165134166134167134168134169134170134171134172134173134174134175134176134177134178134179134180134181134182134183134184134185134186134187134188134189134190134191134192134193134194134195134196134197134198134199134200134201134202134203134204134205134206134207134208134209134210134211134212134213134214134215134216134217134218134219134220134221134222134223134224134225134226134227134228134229134230134231134232134233134234134235134236134237134238134239134240134241134242134243134244134245134246134247134248134249134250134251134252134253134254134255134256134257134258134259134260134261134262134263134264134265134266134267134268134269134270134271134272134273134274134275134276134277134278134279134280134281134282134283134284134285134286134287134288134289134290134291134292134293134294134295134296134297134298134299134300134301134302134303134304134305134306134307134308134309134310134311134312134313134314134315134316134317134318134319134320134321134322134323134324134325134326134327134328134329134330134331134332134333134334134335134336134337134338134339134340134341134342134343134344134345134346134347134348134349134350134351134352134353134354134355134356134357134358134359134360134361134362134363134364134365134366134367134368134369134370134371134372134373134374134375134376134377134378134379134380134381134382134383134384134385134386134387134388134389134390134391134392134393134394134395134396134397134398134399134400134401134402134403134404134405134406134407134408134409134410134411134412134413134414134415134416134417134418134419134420134421134422134423134424134425134426134427134428134429134430134431134432134433134434134435134436134437134438134439134440134441134442134443134444134445134446134447134448134449134450134451134452134453134454134455134456134457134458134459134460134461134462134463134464134465134466134467134468134469134470134471134472134473134474134475134476134477134478134479134480134481134482134483134484134485134486134487134488134489134490134491134492134493134494134495134496134497134498134499134500134501134502134503134504134505134506134507134508134509134510134511134512134513134514134515134516134517134518134519134520134521134522134523134524134525134526134527134528134529134530134531134532134533134534134535134536134537134538134539134540134541134542134543134544134545134546134547134548134549134550134551134552134553134554134555134556134557134558134559134560134561134562134563134564134565134566134567134568134569134570134571134572134573134574134575134576134577134578134579134580134581134582134583134584134585134586134587134588134589134590134591134592134593134594134595134596134597134598134599134600134601134602134603134604134605134606134607134608134609134610134611134612134613134614134615134616134617134618134619134620134621134622134623134624134625134626134627134628134629134630134631134632134633134634134635134636134637134638134639134640134641134642134643134644134645134646134647134648134649134650134651134652134653134654134655134656134657134658134659134660134661134662134663134664134665134666134667134668134669134670134671134672134673134674134675134676134677134678134679134680134681134682134683134684134685134686134687134688134689134690134691134692134693134694134695134696134697134698134699134700134701134702134703134704134705134706134707134708134709134710134711134712134713134714134715134716134717134718134719134720134721134722134723134724134725134726134727134728134729134730134731134732134733134734134735134736134737134738134739134740134741134742134743134744134745134746134747134748134749134750134751134752134753134754134755134756134757134758134759134760134761134762134763134764134765134766134767134768134769134770134771134772134773134774134775134776134777134778134779134780134781134782134783134784134785134786134787134788134789134790134791134792134793134794134795134796134797134798134799134800134801134802134803134804134805134806134807134808134809134810134811134812134813134814134815134816134817134818134819134820134821134822134823134824134825134826134827134828134829134830134831134832134833134834134835134836134837134838134839134840134841134842134843134844134845134846134847134848134849134850134851134852134853134854134855134856134857134858134859134860134861134862134863134864134865134866134867134868134869134870134871134872134873134874134875134876134877134878134879134880134881134882134883134884134885134886134887134888134889134890134891134892134893134894134895134896134897134898134899134900134901134902134903134904134905134906134907134908134909134910134911134912134913134914134915134916134917134918134919134920134921134922134923134924134925134926134927134928134929134930134931134932134933134934134935134936134937134938134939134940134941134942134943134944134945134946134947134948134949134950134951134952134953134954134955134956134957134958134959134960134961134962134963134964134965134966134967134968134969134970134971134972134973134974134975134976134977134978134979134980134981134982134983134984134985134986134987134988134989134990134991134992134993134994134995134996134997134998134999135000135001135002135003135004135005135006135007135008135009135010135011135012135013135014135015135016135017135018135019135020135021135022135023135024135025135026135027135028135029135030135031135032135033135034135035135036135037135038135039135040135041135042135043135044135045135046135047135048135049135050135051135052135053135054135055135056135057135058135059135060135061135062135063135064135065135066135067135068135069135070135071135072135073135074135075135076135077135078135079135080135081135082135083135084135085135086135087135088135089135090135091135092135093135094135095135096135097135098135099135100135101135102135103135104135105135106135107135108135109135110135111135112135113135114135115135116135117135118135119135120135121135122135123135124135125135126135127135128135129135130135131135132135133135134135135135136135137135138135139135140135141135142135143135144135145135146135147135148135149135150135151135152135153135154135155135156135157135158135159135160135161135162135163135164135165135166135167135168135169135170135171135172135173135174135175135176135177135178135179135180135181135182135183135184135185135186135187135188135189135190135191135192135193135194135195135196135197135198135199135200135201135202135203135204135205135206135207135208135209135210135211135212135213135214135215135216135217135218135219135220135221135222135223135224135225135226135227135228135229135230135231135232135233135234135235135236135237135238135239135240135241135242135243135244135245135246135247135248135249135250135251135252135253135254135255135256135257135258135259135260135261135262135263135264135265135266135267135268135269135270135271135272135273135274135275135276135277135278135279135280135281135282135283135284135285135286135287135288135289135290135291135292135293135294135295135296135297135298135299135300135301135302135303135304135305135306135307135308135309135310135311135312135313135314135315135316135317135318135319135320135321135322135323135324135325135326135327135328135329135330135331135332135333135334135335135336135337135338135339135340135341135342135343135344135345135346135347135348135349135350135351135352135353135354135355135356135357135358135359135360135361135362135363135364135365135366135367135368135369135370135371135372135373135374135375135376135377135378135379135380135381135382135383135384135385135386135387135388135389135390135391135392135393135394135395135396135397135398135399135400135401135402135403135404135405135406135407135408135409135410135411135412135413135414135415135416135417135418135419135420135421135422135423135424135425135426135427135428135429135430135431135432135433135434135435135436135437135438135439135440135441135442135443135444135445135446135447135448135449135450135451135452135453135454135455135456135457135458135459135460135461135462135463135464135465135466135467135468135469135470135471135472135473135474135475135476135477135478135479135480135481135482135483135484135485135486135487135488135489135490135491135492135493135494135495135496135497135498135499135500135501135502135503135504135505135506135507135508135509135510135511135512135513135514135515135516135517135518135519135520135521135522135523135524135525135526135527135528135529135530135531135532135533135534135535135536135537135538135539135540135541135542135543135544135545135546135547135548135549135550135551135552135553135554135555135556135557135558135559135560135561135562135563135564135565135566135567135568135569135570135571135572135573135574135575135576135577135578135579135580135581135582135583135584135585135586135587135588135589135590135591135592135593135594135595135596135597135598135599135600135601135602135603135604135605135606135607135608135609135610135611135612135613135614135615135616135617135618135619135620135621135622135623135624135625135626135627135628135629135630135631135632135633135634135635135636135637135638135639135640135641135642135643135644135645135646135647135648135649135650135651135652135653135654135655135656135657135658135659135660135661135662135663135664135665135666135667135668135669135670135671135672135673135674135675135676135677135678135679135680135681135682135683135684135685135686135687135688135689135690135691135692135693135694135695135696135697135698135699135700135701135702135703135704135705135706135707135708135709135710135711135712135713135714135715135716135717135718135719135720135721135722135723135724135725135726135727135728135729135730135731135732135733135734135735135736135737135738135739135740135741135742135743135744135745135746135747135748135749135750135751135752135753135754135755135756135757135758135759135760135761135762135763135764135765135766135767135768135769135770135771135772135773135774135775135776135777135778135779135780135781135782135783135784135785135786135787135788135789135790135791135792135793135794135795135796135797135798135799135800135801135802135803135804135805135806135807135808135809135810135811135812135813135814135815135816135817135818135819135820135821135822135823135824135825135826135827135828135829135830135831135832135833135834135835135836135837135838135839135840135841135842135843135844135845135846135847135848135849135850135851135852135853135854135855135856135857135858135859135860135861135862135863135864135865135866135867135868135869135870135871135872135873135874135875135876135877135878135879135880135881135882135883135884135885135886135887135888135889135890135891135892135893135894135895135896135897135898135899135900135901135902135903135904135905135906135907135908135909135910135911135912135913135914135915135916135917135918135919135920135921135922135923135924135925135926135927135928135929135930135931135932135933135934135935135936135937135938135939135940135941135942135943135944135945135946135947135948135949135950135951135952135953135954135955135956135957135958135959135960135961135962135963135964135965135966135967135968135969135970135971135972135973135974135975135976135977135978135979135980135981135982135983135984135985135986135987135988135989135990135991135992135993135994135995135996135997135998135999136000136001136002136003136004136005136006136007136008136009136010136011136012136013136014136015136016136017136018136019136020136021136022136023136024136025136026136027136028136029136030136031136032136033136034136035136036136037136038136039136040136041136042136043136044136045136046136047136048136049136050136051136052136053136054136055136056136057136058136059136060136061136062136063136064136065136066136067136068136069136070136071136072136073136074136075136076136077136078136079136080136081136082136083136084136085136086136087136088136089136090136091136092136093136094136095136096136097136098136099136100136101136102136103136104136105136106136107136108136109136110136111136112136113136114136115136116136117136118136119136120136121136122136123136124136125136126136127136128136129136130136131136132136133136134136135136136136137136138136139136140136141136142136143136144136145136146136147136148136149136150136151136152136153136154136155136156136157136158136159136160136161136162136163136164136165136166136167136168136169136170136171136172136173136174136175136176136177136178136179136180136181136182136183136184136185136186136187136188136189136190136191136192136193136194136195136196136197136198136199136200136201136202136203136204136205136206136207136208136209136210136211136212136213136214136215136216136217136218136219136220136221136222136223136224136225136226136227136228136229136230136231136232136233136234136235136236136237136238136239136240136241136242136243136244136245136246136247136248136249136250136251136252136253136254136255136256136257136258136259136260136261136262136263136264136265136266136267136268136269136270136271136272136273136274136275136276136277136278136279136280136281136282136283136284136285136286136287136288136289136290136291136292136293136294136295136296136297136298136299136300136301136302136303136304136305136306136307136308136309136310136311136312136313136314136315136316136317136318136319136320136321136322136323136324136325136326136327136328136329136330136331136332136333136334136335136336136337136338136339136340136341136342136343136344136345136346136347136348136349136350136351136352136353136354136355136356136357136358136359136360136361136362136363136364136365136366136367136368136369136370136371136372136373136374136375136376136377136378136379136380136381136382136383136384136385136386136387136388136389136390136391136392136393136394136395136396136397136398136399136400136401136402136403136404136405136406136407136408136409136410136411136412136413136414136415136416136417136418136419136420136421136422136423136424136425136426136427136428136429136430136431136432136433136434136435136436136437136438136439136440136441136442136443136444136445136446136447136448136449136450136451136452136453136454136455136456136457136458136459136460136461136462136463136464136465136466136467136468136469136470136471136472136473136474136475136476136477136478136479136480136481136482136483136484136485136486136487136488136489136490136491136492136493136494136495136496136497136498136499136500136501136502136503136504136505136506136507136508136509136510136511136512136513136514136515136516136517136518136519136520136521136522136523136524136525136526136527136528136529136530136531136532136533136534136535136536136537136538136539136540136541136542136543136544136545136546136547136548136549136550136551136552136553136554136555136556136557136558136559136560136561136562136563136564136565136566136567136568136569136570136571136572136573136574136575136576136577136578136579136580136581136582136583136584136585136586136587136588136589136590136591136592136593136594136595136596136597136598136599136600136601136602136603136604136605136606136607136608136609136610136611136612136613136614136615136616136617136618136619136620136621136622136623136624136625136626136627136628136629136630136631136632136633136634136635136636136637136638136639136640136641136642136643136644136645136646136647136648136649136650136651136652136653136654136655136656136657136658136659136660136661136662136663136664136665136666136667136668136669136670136671136672136673136674136675136676136677136678136679136680136681136682136683136684136685136686136687136688136689136690136691136692136693136694136695136696136697136698136699136700136701136702136703136704136705136706136707136708136709136710136711136712136713136714136715136716136717136718136719136720136721136722136723136724136725136726136727136728136729136730136731136732136733136734136735136736136737136738136739136740136741136742136743136744136745136746136747136748136749136750136751136752136753136754136755136756136757136758136759136760136761136762136763136764136765136766136767136768136769136770136771136772136773136774136775136776136777136778136779136780136781136782136783136784136785136786136787136788136789136790136791136792136793136794136795136796136797136798136799136800136801136802136803136804136805136806136807136808136809136810136811136812136813136814136815136816136817136818136819136820136821136822136823136824136825136826136827136828136829136830136831136832136833136834136835136836136837136838136839136840136841136842136843136844136845136846136847136848136849136850136851136852136853136854136855136856136857136858136859136860136861136862136863136864136865136866136867136868136869136870136871136872136873136874136875136876136877136878136879136880136881136882136883136884136885136886136887136888136889136890136891136892136893136894136895136896136897136898136899136900136901136902136903136904136905136906136907136908136909136910136911136912136913136914136915136916136917136918136919136920136921136922136923136924136925136926136927136928136929136930136931136932136933136934136935136936136937136938136939136940136941136942136943136944136945136946136947136948136949136950136951136952136953136954136955136956136957136958136959136960136961136962136963136964136965136966136967136968136969136970136971136972136973136974136975136976136977136978136979136980136981136982136983136984136985136986136987136988136989136990136991136992136993136994136995136996136997136998136999137000137001137002137003137004137005137006137007137008137009137010137011137012137013137014137015137016137017137018137019137020137021137022137023137024137025137026137027137028137029137030137031137032137033137034137035137036137037137038137039137040137041137042137043137044137045137046137047137048137049137050137051137052137053137054137055137056137057137058137059137060137061137062137063137064137065137066137067137068137069137070137071137072137073137074137075137076137077137078137079137080137081137082137083137084137085137086137087137088137089137090137091137092137093137094137095137096137097137098137099137100137101137102137103137104137105137106137107137108137109137110137111137112137113137114137115137116137117137118137119137120137121137122137123137124137125137126137127137128137129137130137131137132137133137134137135137136137137137138137139137140137141137142137143137144137145137146137147137148137149137150137151137152137153137154137155137156137157137158137159137160137161137162137163137164137165137166137167137168137169137170137171137172137173137174137175137176137177137178137179137180137181137182137183137184137185137186137187137188137189137190137191137192137193137194137195137196137197137198137199137200137201137202137203137204137205137206137207137208137209137210137211137212137213137214137215137216137217137218137219137220137221137222137223137224137225137226137227137228137229137230137231137232137233137234137235137236137237137238137239137240137241137242137243137244137245137246137247137248137249137250137251137252137253137254137255137256137257137258137259137260137261137262137263137264137265137266137267137268137269137270137271137272137273137274137275137276137277137278137279137280137281137282137283137284137285137286137287137288137289137290137291137292137293137294137295137296137297137298137299137300137301137302137303137304137305137306137307137308137309137310137311137312137313137314137315137316137317137318137319137320137321137322137323137324137325137326137327137328137329137330137331137332137333137334137335137336137337137338137339137340137341137342137343137344137345137346137347137348137349137350137351137352137353137354137355137356137357137358137359137360137361137362137363137364137365137366137367137368137369137370137371137372137373137374137375137376137377137378137379137380137381137382137383137384137385137386137387137388137389137390137391137392137393137394137395137396137397137398137399137400137401137402137403137404137405137406137407137408137409137410137411137412137413137414137415137416137417137418137419137420137421137422137423137424137425137426137427137428137429137430137431137432137433137434137435137436137437137438137439137440137441137442137443137444137445137446137447137448137449137450137451137452137453137454137455137456137457137458137459137460137461137462137463137464137465137466137467137468137469137470137471137472137473137474137475137476137477137478137479137480137481137482137483137484137485137486137487137488137489137490137491137492137493137494137495137496137497137498137499137500137501137502137503137504137505137506137507137508137509137510137511137512137513137514137515137516137517137518137519137520137521137522137523137524137525137526137527137528137529137530137531137532137533137534137535137536137537137538137539137540137541137542137543137544137545137546137547137548137549137550137551137552137553137554137555137556137557137558137559137560137561137562137563137564137565137566137567137568137569137570137571137572137573137574137575137576137577137578137579137580137581137582137583137584137585137586137587137588137589137590137591137592137593137594137595137596137597137598137599137600137601137602137603137604137605137606137607137608137609137610137611137612137613137614137615137616137617137618137619137620137621137622137623137624137625137626137627137628137629137630137631137632137633137634137635137636137637137638137639137640137641137642137643137644137645137646137647137648137649137650137651137652137653137654137655137656137657137658137659137660137661137662137663137664137665137666137667137668137669137670137671137672137673137674137675137676137677137678137679137680137681137682137683137684137685137686137687137688137689137690137691137692137693137694137695137696137697137698137699137700137701137702137703137704137705137706137707137708137709137710137711137712137713137714137715137716137717137718137719137720137721137722137723137724137725137726137727137728137729137730137731137732137733137734137735137736137737137738137739137740137741137742137743137744137745137746137747137748137749137750137751137752137753137754137755137756137757137758137759137760137761137762137763137764137765137766137767137768137769137770137771137772137773137774137775137776137777137778137779137780137781137782137783137784137785137786137787137788137789137790137791137792137793137794137795137796137797137798137799137800137801137802137803137804137805137806137807137808137809137810137811137812137813137814137815137816137817137818137819137820137821137822137823137824137825137826137827137828137829137830137831137832137833137834137835137836137837137838137839137840137841137842137843137844137845137846137847137848137849137850137851137852137853137854137855137856137857137858137859137860137861137862137863137864137865137866137867137868137869137870137871137872137873137874137875137876137877137878137879137880137881137882137883137884137885137886137887137888137889137890137891137892137893137894137895137896137897137898137899137900137901137902137903137904137905137906137907137908137909137910137911137912137913137914137915137916137917137918137919137920137921137922137923137924137925137926137927137928137929137930137931137932137933137934137935137936137937137938137939137940137941137942137943137944137945137946137947137948137949137950137951137952137953137954137955137956137957137958137959137960137961137962137963137964137965137966137967137968137969137970137971137972137973137974137975137976137977137978137979137980137981137982137983137984137985137986137987137988137989137990137991137992137993137994137995137996137997137998137999138000138001138002138003138004138005138006138007138008138009138010138011138012138013138014138015138016138017138018138019138020138021138022138023138024138025138026138027138028138029138030138031138032138033138034138035138036138037138038138039138040138041138042138043138044138045138046138047138048138049138050138051138052138053138054138055138056138057138058138059138060138061138062138063138064138065138066138067138068138069138070138071138072138073138074138075138076138077138078138079138080138081138082138083138084138085138086138087138088138089138090138091138092138093138094138095138096138097138098138099138100138101138102138103138104138105138106138107138108138109138110138111138112138113138114138115138116138117138118138119138120138121138122138123138124138125138126138127138128138129138130138131138132138133138134138135138136138137138138138139138140138141138142138143138144138145138146138147138148138149138150138151138152138153138154138155138156138157138158138159138160138161138162138163138164138165138166138167138168138169138170138171138172138173138174138175138176138177138178138179138180138181138182138183138184138185138186138187138188138189138190138191138192138193138194138195138196138197138198138199138200138201138202138203138204138205138206138207138208138209138210138211138212138213138214138215138216138217138218138219138220138221138222138223138224138225138226138227138228138229138230138231138232138233138234138235138236138237138238138239138240138241138242138243138244138245138246138247138248138249138250138251138252138253138254138255138256138257138258138259138260138261138262138263138264138265138266138267138268138269138270138271138272138273138274138275138276138277138278138279138280138281138282138283138284138285138286138287138288138289138290138291138292138293138294138295138296138297138298138299138300138301138302138303138304138305138306138307138308138309138310138311138312138313138314138315138316138317138318138319138320138321138322138323138324138325138326138327138328138329138330138331138332138333138334138335138336138337138338138339138340138341138342138343138344138345138346138347138348138349138350138351138352138353138354138355138356138357138358138359138360138361138362138363138364138365138366138367138368138369138370138371138372138373138374138375138376138377138378138379138380138381138382138383138384138385138386138387138388138389138390138391138392138393138394138395138396138397138398138399138400138401138402138403138404138405138406138407138408138409138410138411138412138413138414138415138416138417138418138419138420138421138422138423138424138425138426138427138428138429138430138431138432138433138434138435138436138437138438138439138440138441138442138443138444138445138446138447138448138449138450138451138452138453138454138455138456138457138458138459138460138461138462138463138464138465138466138467138468138469138470138471138472138473138474138475138476138477138478138479138480138481138482138483138484138485138486138487138488138489138490138491138492138493138494138495138496138497138498138499138500138501138502138503138504138505138506138507138508138509138510138511138512138513138514138515138516138517138518138519138520138521138522138523138524138525138526138527138528138529138530138531138532138533138534138535138536138537138538138539138540138541138542138543138544138545138546138547138548138549138550138551138552138553138554138555138556138557138558138559138560138561138562138563138564138565138566138567138568138569138570138571138572138573138574138575138576138577138578138579138580138581138582138583138584138585138586138587138588138589138590138591138592138593138594138595138596138597138598138599138600138601138602138603138604138605138606138607138608138609138610138611138612138613138614138615138616138617138618138619138620138621138622138623138624138625138626138627138628138629138630138631138632138633138634138635138636138637138638138639138640138641138642138643138644138645138646138647138648138649138650138651138652138653138654138655138656138657138658138659138660138661138662138663138664138665138666138667138668138669138670138671138672138673138674138675138676138677138678138679138680138681138682138683138684138685138686138687138688138689138690138691138692138693138694138695138696138697138698138699138700138701138702138703138704138705138706138707138708138709138710138711138712138713138714138715138716138717138718138719138720138721138722138723138724138725138726138727138728138729138730138731138732138733138734138735138736138737138738138739138740138741138742138743138744138745138746138747138748138749138750138751138752138753138754138755138756138757138758138759138760138761138762138763138764138765138766138767138768138769138770138771138772138773138774138775138776138777138778138779138780138781138782138783138784138785138786138787138788138789138790138791138792138793138794138795138796138797138798138799138800138801138802138803138804138805138806138807138808138809138810138811138812138813138814138815138816138817138818138819138820138821138822138823138824138825138826138827138828138829138830138831138832138833138834138835138836138837138838138839138840138841138842138843138844138845138846138847138848138849138850138851138852138853138854138855138856138857138858138859138860138861138862138863138864138865138866138867138868138869138870138871138872138873138874138875138876138877138878138879138880138881138882138883138884138885138886138887138888138889138890138891138892138893138894138895138896138897138898138899138900138901138902138903138904138905138906138907138908138909138910138911138912138913138914138915138916138917138918138919138920138921138922138923138924138925138926138927138928138929138930138931138932138933138934138935138936138937138938138939138940138941138942138943138944138945138946138947138948138949138950138951138952138953138954138955138956138957138958138959138960138961138962138963138964138965138966138967138968138969138970138971138972138973138974138975138976138977138978138979138980138981138982138983138984138985138986138987138988138989138990138991138992138993138994138995138996138997138998138999139000139001139002139003139004139005139006139007139008139009139010139011139012139013139014139015139016139017139018139019139020139021139022139023139024139025139026139027139028139029139030139031139032139033139034139035139036139037139038139039139040139041139042139043139044139045139046139047139048139049139050139051139052139053139054139055139056139057139058139059139060139061139062139063139064139065139066139067139068139069139070139071139072139073139074139075139076139077139078139079139080139081139082139083139084139085139086139087139088139089139090139091139092139093139094139095139096139097139098139099139100139101139102139103139104139105139106139107139108139109139110139111139112139113139114139115139116139117139118139119139120139121139122139123139124139125139126139127139128139129139130139131139132139133139134139135139136139137139138139139139140139141139142139143139144139145139146139147139148139149139150139151139152139153139154139155139156139157139158139159139160139161139162139163139164139165139166139167139168139169139170139171139172139173139174139175139176139177139178139179139180139181139182139183139184139185139186139187139188139189139190139191139192139193139194139195139196139197139198139199139200139201139202139203139204139205139206139207139208139209139210139211139212139213139214139215139216139217139218139219139220139221139222139223139224139225139226139227139228139229139230139231139232139233139234139235139236139237139238139239139240139241139242139243139244139245139246139247139248139249139250139251139252139253139254139255139256139257139258139259139260139261139262139263139264139265139266139267139268139269139270139271139272139273139274139275139276139277139278139279139280139281139282139283139284139285139286139287139288139289139290139291139292139293139294139295139296139297139298139299139300139301139302139303139304139305139306139307139308139309139310139311139312139313139314139315139316139317139318139319139320139321139322139323139324139325139326139327139328139329139330139331139332139333139334139335139336139337139338139339139340139341139342139343139344139345139346139347139348139349139350139351139352139353139354139355139356139357139358139359139360139361139362139363139364139365139366139367139368139369139370139371139372139373139374139375139376139377139378139379139380139381139382139383139384139385139386139387139388139389139390139391139392139393139394139395139396139397139398139399139400139401139402139403139404139405139406139407139408139409139410139411139412139413139414139415139416139417139418139419139420139421139422139423139424139425139426139427139428139429139430139431139432139433139434139435139436139437139438139439139440139441139442139443139444139445139446139447139448139449139450139451139452139453139454139455139456139457139458139459139460139461139462139463139464139465139466139467139468139469139470139471139472139473139474139475139476139477139478139479139480139481139482139483139484139485139486139487139488139489139490139491139492139493139494139495139496139497139498139499139500139501139502139503139504139505139506139507139508139509139510139511139512139513139514139515139516139517139518139519139520139521139522139523139524139525139526139527139528139529139530139531139532139533139534139535139536139537139538139539139540139541139542139543139544139545139546139547139548139549139550139551139552139553139554139555139556139557139558139559139560139561139562139563139564139565139566139567139568139569139570139571139572139573139574139575139576139577139578139579139580139581139582139583139584139585139586139587139588139589139590139591139592139593139594139595139596139597139598139599139600139601139602139603139604139605139606139607139608139609139610139611139612139613139614139615139616139617139618139619139620139621139622139623139624139625139626139627139628139629139630139631139632139633139634139635139636139637139638139639139640139641139642139643139644139645139646139647139648139649139650139651139652139653139654139655139656139657139658139659139660139661139662139663139664139665139666139667139668139669139670139671139672139673139674139675139676139677139678139679139680139681139682139683139684139685139686139687139688139689139690139691139692139693139694139695139696139697139698139699139700139701139702139703139704139705139706139707139708139709139710139711139712139713139714139715139716139717139718139719139720139721139722139723139724139725139726139727139728139729139730139731139732139733139734139735139736139737139738139739139740139741139742139743139744139745139746139747139748139749139750139751139752139753139754139755139756139757139758139759139760139761139762139763139764139765139766139767139768139769139770139771139772139773139774139775139776139777139778139779139780139781139782139783139784139785139786139787139788139789139790139791139792139793139794139795139796139797139798139799139800139801139802139803139804139805139806139807139808139809139810139811139812139813139814139815139816139817139818139819139820139821139822139823139824139825139826139827139828139829139830139831139832139833139834139835139836139837139838139839139840139841139842139843139844139845139846139847139848139849139850139851139852139853139854139855139856139857139858139859139860139861139862139863139864139865139866139867139868139869139870139871139872139873139874139875139876139877139878139879139880139881139882139883139884139885139886139887139888139889139890139891139892139893139894139895139896139897139898139899139900139901139902139903139904139905139906139907139908139909139910139911139912139913139914139915139916139917139918139919139920139921139922139923139924139925139926139927139928139929139930139931139932139933139934139935139936139937139938139939139940139941139942139943139944139945139946139947139948139949139950139951139952139953139954139955139956139957139958139959139960139961139962139963139964139965139966139967139968139969139970139971139972139973139974139975139976139977139978139979139980139981139982139983139984139985139986139987139988139989139990139991139992139993139994139995139996139997139998139999140000140001140002140003140004140005140006140007140008140009140010140011140012140013140014140015140016140017140018140019140020140021140022140023140024140025140026140027140028140029140030140031140032140033140034140035140036140037140038140039140040140041140042140043140044140045140046140047140048140049140050140051140052140053140054140055140056140057140058140059140060140061140062140063140064140065140066140067140068140069140070140071140072140073140074140075140076140077140078140079140080140081140082140083140084140085140086140087140088140089140090140091140092140093140094140095140096140097140098140099140100140101140102140103140104140105140106140107140108140109140110140111140112140113140114140115140116140117140118140119140120140121140122140123140124140125140126140127140128140129140130140131140132140133140134140135140136140137140138140139140140140141140142140143140144140145140146140147140148140149140150140151140152140153140154140155140156140157140158140159140160140161140162140163140164140165140166140167140168140169140170140171140172140173140174140175140176140177140178140179140180140181140182140183140184140185140186140187140188140189140190140191140192140193140194140195140196140197140198140199140200140201140202140203140204140205140206140207140208140209140210140211140212140213140214140215140216140217140218140219140220140221140222140223140224140225140226140227140228140229140230140231140232140233140234140235140236140237140238140239140240140241140242140243140244140245140246140247140248140249140250140251140252140253140254140255140256140257140258140259140260140261140262140263140264140265140266140267140268140269140270140271140272140273140274140275140276140277140278140279140280140281140282140283140284140285140286140287140288140289140290140291140292140293140294140295140296140297140298140299140300140301140302140303140304140305140306140307140308140309140310140311140312140313140314140315140316140317140318140319140320140321140322140323140324140325140326140327140328140329140330140331140332140333140334140335140336140337140338140339140340140341140342140343140344140345140346140347140348140349140350140351140352140353140354140355140356140357140358140359140360140361140362140363140364140365140366140367140368140369140370140371140372140373140374140375140376140377140378140379140380140381140382140383140384140385140386140387140388140389140390140391140392140393140394140395140396140397140398140399140400140401140402140403140404140405140406140407140408140409140410140411140412140413140414140415140416140417140418140419140420140421140422140423140424140425140426140427140428140429140430140431140432140433140434140435140436140437140438140439140440140441140442140443140444140445140446140447140448140449140450140451140452140453140454140455140456140457140458140459140460140461140462140463140464140465140466140467140468140469140470140471140472140473140474140475140476140477140478140479140480140481140482140483140484140485140486140487140488140489140490140491140492140493140494140495140496140497140498140499140500140501140502140503140504140505140506140507140508140509140510140511140512140513140514140515140516140517140518140519140520140521140522140523140524140525140526140527140528140529140530140531140532140533140534140535140536140537140538140539140540140541140542140543140544140545140546140547140548140549140550140551140552140553140554140555140556140557140558140559140560140561140562140563140564140565140566140567140568140569140570140571140572140573140574140575140576140577140578140579140580140581140582140583140584140585140586140587140588140589140590140591140592140593140594140595140596140597140598140599140600140601140602140603140604140605140606140607140608140609140610140611140612140613140614140615140616140617140618140619140620140621140622140623140624140625140626140627140628140629140630140631140632140633140634140635140636140637140638140639140640140641140642140643140644140645140646140647140648140649140650140651140652140653140654140655140656140657140658140659140660140661140662140663140664140665140666140667140668140669140670140671140672140673140674140675140676140677140678140679140680140681140682140683140684140685140686140687140688140689140690140691140692140693140694140695140696140697140698140699140700140701140702140703140704140705140706140707140708140709140710140711140712140713140714140715140716140717140718140719140720140721140722140723140724140725140726140727140728140729140730140731140732140733140734140735140736140737140738140739140740140741140742140743140744140745140746140747140748140749140750140751140752140753140754140755140756140757140758140759140760140761140762140763140764140765140766140767140768140769140770140771140772140773140774140775140776140777140778140779140780140781140782140783140784140785140786140787140788140789140790140791140792140793140794140795140796140797140798140799140800140801140802140803140804140805140806140807140808140809140810140811140812140813140814140815140816140817140818140819140820140821140822140823140824140825140826140827140828140829140830140831140832140833140834140835140836140837140838140839140840140841140842140843140844140845140846140847140848140849140850140851140852140853140854140855140856140857140858140859140860140861140862140863140864140865140866140867140868140869140870140871140872140873140874140875140876140877140878140879140880140881140882140883140884140885140886140887140888140889140890140891140892140893140894140895140896140897140898140899140900140901140902140903140904140905140906140907140908140909140910140911140912140913140914140915140916140917140918140919140920140921140922140923140924140925140926140927140928140929140930140931140932140933140934140935140936140937140938140939140940140941140942140943140944140945140946140947140948140949140950140951140952140953140954140955140956140957140958140959140960140961140962140963140964140965140966140967140968140969140970140971140972140973140974140975140976140977140978140979140980140981140982140983140984140985140986140987140988140989140990140991140992140993140994140995140996140997140998140999141000141001141002141003141004141005141006141007141008141009141010141011141012141013141014141015141016141017141018141019141020141021141022141023141024141025141026141027141028141029141030141031141032141033141034141035141036141037141038141039141040141041141042141043141044141045141046141047141048141049141050141051141052141053141054141055141056141057141058141059141060141061141062141063141064141065141066141067141068141069141070141071141072141073141074141075141076141077141078141079141080141081141082141083141084141085141086141087141088141089141090141091141092141093141094141095141096141097141098141099141100141101141102141103141104141105141106141107141108141109141110141111141112141113141114141115141116141117141118141119141120141121141122141123141124141125141126141127141128141129141130141131141132141133141134141135141136141137141138141139141140141141141142141143141144141145141146141147141148141149141150141151141152141153141154141155141156141157141158141159141160141161141162141163141164141165141166141167141168141169141170141171141172141173141174141175141176141177141178141179141180141181141182141183141184141185141186141187141188141189141190141191141192141193141194141195141196141197141198141199141200141201141202141203141204141205141206141207141208141209141210141211141212141213141214141215141216141217141218141219141220141221141222141223141224141225141226141227141228141229141230141231141232141233141234141235141236141237141238141239141240141241141242141243141244141245141246141247141248141249141250141251141252141253141254141255141256141257141258141259141260141261141262141263141264141265141266141267141268141269141270141271141272141273141274141275141276141277141278141279141280141281141282141283141284141285141286141287141288141289141290141291141292141293141294141295141296141297141298141299141300141301141302141303141304141305141306141307141308141309141310141311141312141313141314141315141316141317141318141319141320141321141322141323141324141325141326141327141328141329141330141331141332141333141334141335141336141337141338141339141340141341141342141343141344141345141346141347141348141349141350141351141352141353141354141355141356141357141358141359141360141361141362141363141364141365141366141367141368141369141370141371141372141373141374141375141376141377141378141379141380141381141382141383141384141385141386141387141388141389141390141391141392141393141394141395141396141397141398141399141400141401141402141403141404141405141406141407141408141409141410141411141412141413141414141415141416141417141418141419141420141421141422141423141424141425141426141427141428141429141430141431141432141433141434141435141436141437141438141439141440141441141442141443141444141445141446141447141448141449141450141451141452141453141454141455141456141457141458141459141460141461141462141463141464141465141466141467141468141469141470141471141472141473141474141475141476141477141478141479141480141481141482141483141484141485141486141487141488141489141490141491141492141493141494141495141496141497141498141499141500141501141502141503141504141505141506141507141508141509141510141511141512141513141514141515141516141517141518141519141520141521141522141523141524141525141526141527141528141529141530141531141532141533141534141535141536141537141538141539141540141541141542141543141544141545141546141547141548141549141550141551141552141553141554141555141556141557141558141559141560141561141562141563141564141565141566141567141568141569141570141571141572141573141574141575141576141577141578141579141580141581141582141583141584141585141586141587141588141589141590141591141592141593141594141595141596141597141598141599141600141601141602141603141604141605141606141607141608141609141610141611141612141613141614141615141616141617141618141619141620141621141622141623141624141625141626141627141628141629141630141631141632141633141634141635141636141637141638141639141640141641141642141643141644141645141646141647141648141649141650141651141652141653141654141655141656141657141658141659141660141661141662141663141664141665141666141667141668141669141670141671141672141673141674141675141676141677141678141679141680141681141682141683141684141685141686141687141688141689141690141691141692141693141694141695141696141697141698141699141700141701141702141703141704141705141706141707141708141709141710141711141712141713141714141715141716141717141718141719141720141721141722141723141724141725141726141727141728141729141730141731141732141733141734141735141736141737141738141739141740141741141742141743141744141745141746141747141748141749141750141751141752141753141754141755141756141757141758141759141760141761141762141763141764141765141766141767141768141769141770141771141772141773141774141775141776141777141778141779141780141781141782141783141784141785141786141787141788141789141790141791141792141793141794141795141796141797141798141799141800141801141802141803141804141805141806141807141808141809141810141811141812141813141814141815141816141817141818141819141820141821141822141823141824141825141826141827141828141829141830141831141832141833141834141835141836141837141838141839141840141841141842141843141844141845141846141847141848141849141850141851141852141853141854141855141856141857141858141859141860141861141862141863141864141865141866141867141868141869141870141871141872141873141874141875141876141877141878141879141880141881141882141883141884141885141886141887141888141889141890141891141892141893141894141895141896141897141898141899141900141901141902141903141904141905141906141907141908141909141910141911141912141913141914141915141916141917141918141919141920141921141922141923141924141925141926141927141928141929141930141931141932141933141934141935141936141937141938141939141940141941141942141943141944141945141946141947141948141949141950141951141952141953141954141955141956141957141958141959141960141961141962141963141964141965141966141967141968141969141970141971141972141973141974141975141976141977141978141979141980141981141982141983141984141985141986141987141988141989141990141991141992141993141994141995141996141997141998141999142000142001142002142003142004142005142006142007142008142009142010142011142012142013142014142015142016142017142018142019142020142021142022142023142024142025142026142027142028142029142030142031142032142033142034142035142036142037142038142039142040142041142042142043142044142045142046142047142048142049142050142051142052142053142054142055142056142057142058142059142060142061142062142063142064142065142066142067142068142069142070142071142072142073142074142075142076142077142078142079142080142081142082142083142084142085142086142087142088142089142090142091142092142093142094142095142096142097142098142099142100142101142102142103142104142105142106142107142108142109142110142111142112142113142114142115142116142117142118142119142120142121142122142123142124142125142126142127142128142129142130142131142132142133142134142135142136142137142138142139142140142141142142142143142144142145142146142147142148142149142150142151142152142153142154142155142156142157142158142159142160142161142162142163142164142165142166142167142168142169142170142171142172142173142174142175142176142177142178142179142180142181142182142183142184142185142186142187142188142189142190142191142192142193142194142195142196142197142198142199142200142201142202142203142204142205142206142207142208142209142210142211142212142213142214142215142216142217142218142219142220142221142222142223142224142225142226142227142228142229142230142231142232142233142234142235142236142237142238142239142240142241142242142243142244142245142246142247142248142249142250142251142252142253142254142255142256142257142258142259142260142261142262142263142264142265142266142267142268142269142270142271142272142273142274142275142276142277142278142279142280142281142282142283142284142285142286142287142288142289142290142291142292142293142294142295142296142297142298142299142300142301142302142303142304142305142306142307142308142309142310142311142312142313142314142315142316142317142318142319142320142321142322142323142324142325142326142327142328142329142330142331142332142333142334142335142336142337142338142339142340142341142342142343142344142345142346142347142348142349142350142351142352142353142354142355142356142357142358142359142360142361142362142363142364142365142366142367142368142369142370142371142372142373142374142375142376142377142378142379142380142381142382142383142384142385142386142387142388142389142390142391142392142393142394142395142396142397142398142399142400142401142402142403142404142405142406142407142408142409142410142411142412142413142414142415142416142417142418142419142420142421142422142423142424142425142426142427142428142429142430142431142432142433142434142435142436142437142438142439142440142441142442142443142444142445142446142447142448142449142450142451142452142453142454142455142456142457142458142459142460142461142462142463142464142465142466142467142468142469142470142471142472142473142474142475142476142477142478142479142480142481142482142483142484142485142486142487142488142489142490142491142492142493142494142495142496142497142498142499142500142501142502142503142504142505142506142507142508142509142510142511142512142513142514142515142516142517142518142519142520142521142522142523142524142525142526142527142528142529142530142531142532142533142534142535142536142537142538142539142540142541142542142543142544142545142546142547142548142549142550142551142552142553142554142555142556142557142558142559142560142561142562142563142564142565142566142567142568142569142570142571142572142573142574142575142576142577142578142579142580142581142582142583142584142585142586142587142588142589142590142591142592142593142594142595142596142597142598142599142600142601142602142603142604142605142606142607142608142609142610142611142612142613142614142615142616142617142618142619142620142621142622142623142624142625142626142627142628142629142630142631142632142633142634142635142636142637142638142639142640142641142642142643142644142645142646142647142648142649142650142651142652142653142654142655142656142657142658142659142660142661142662142663142664142665142666142667142668142669142670142671142672142673142674142675142676142677142678142679142680142681142682142683142684142685142686142687142688142689142690142691142692142693142694142695142696142697142698142699142700142701142702142703142704142705142706142707142708142709142710142711142712142713142714142715142716142717142718142719142720142721142722142723142724142725142726142727142728142729142730142731142732142733142734142735142736142737142738142739142740142741142742142743142744142745142746142747142748142749142750142751142752142753142754142755142756142757142758142759142760142761142762142763142764142765142766142767142768142769142770142771142772142773142774142775142776142777142778142779142780142781142782142783142784142785142786142787142788142789142790142791142792142793142794142795142796142797142798142799142800142801142802142803142804142805142806142807142808142809142810142811142812142813142814142815142816142817142818142819142820142821142822142823142824142825142826142827142828142829142830142831142832142833142834142835142836142837142838142839142840142841142842142843142844142845142846142847142848142849142850142851142852142853142854142855142856142857142858142859142860142861142862142863142864142865142866142867142868142869142870142871142872142873142874142875142876142877142878142879142880142881142882142883142884142885142886142887142888142889142890142891142892142893142894142895142896142897142898142899142900142901142902142903142904142905142906142907142908142909142910142911142912142913142914142915142916142917142918142919142920142921142922142923142924142925142926142927142928142929142930142931142932142933142934142935142936142937142938142939142940142941142942142943142944142945142946142947142948142949142950142951142952142953142954142955142956142957142958142959142960142961142962142963142964142965142966142967142968142969142970142971142972142973142974142975142976142977142978142979142980142981142982142983142984142985142986142987142988142989142990142991142992142993142994142995142996142997142998142999143000143001143002143003143004143005143006143007143008143009143010143011143012143013143014143015143016143017143018143019143020143021143022143023143024143025143026143027143028143029143030143031143032143033143034143035143036143037143038143039143040143041143042143043143044143045143046143047143048143049143050143051143052143053143054143055143056143057143058143059143060143061143062143063143064143065143066143067143068143069143070143071143072143073143074143075143076143077143078143079143080143081143082143083143084143085143086143087143088143089143090143091143092143093143094143095143096143097143098143099143100143101143102143103143104143105143106143107143108143109143110143111143112143113143114143115143116143117143118143119143120143121143122143123143124143125143126143127143128143129143130143131143132143133143134143135143136143137143138143139143140143141143142143143143144143145143146143147143148143149143150143151143152143153143154143155143156143157143158143159143160143161143162143163143164143165143166143167143168143169143170143171143172143173143174143175143176143177143178143179143180143181143182143183143184143185143186143187143188143189143190143191143192143193143194143195143196143197143198143199143200143201143202143203143204143205143206143207143208143209143210143211143212143213143214143215143216143217143218143219143220143221143222143223143224143225143226143227143228143229143230143231143232143233143234143235143236143237143238143239143240143241143242143243143244143245143246143247143248143249143250143251143252143253143254143255143256143257143258143259143260143261143262143263143264143265143266143267143268143269143270143271143272143273143274143275143276143277143278143279143280143281143282143283143284143285143286143287143288143289143290143291143292143293143294143295143296143297143298143299143300143301143302143303143304143305143306143307143308143309143310143311143312143313143314143315143316143317143318143319143320143321143322143323143324143325143326143327143328143329143330143331143332143333143334143335143336143337143338143339143340143341143342143343143344143345143346143347143348143349143350143351143352143353143354143355143356143357143358143359143360143361143362143363143364143365143366143367143368143369143370143371143372143373143374143375143376143377143378143379143380143381143382143383143384143385143386143387143388143389143390143391143392143393143394143395143396143397143398143399143400143401143402143403143404143405143406143407143408143409143410143411143412143413143414143415143416143417143418143419143420143421143422143423143424143425143426143427143428143429143430143431143432143433143434143435143436143437143438143439143440143441143442143443143444143445143446143447143448143449143450143451143452143453143454143455143456143457143458143459143460143461143462143463143464143465143466143467143468143469143470143471143472143473143474143475143476143477143478143479143480143481143482143483143484143485143486143487143488143489143490143491143492143493143494143495143496143497143498143499143500143501143502143503143504143505143506143507143508143509143510143511143512143513143514143515143516143517143518143519143520143521143522143523143524143525143526143527143528143529143530143531143532143533143534143535143536143537143538143539143540143541143542143543143544143545143546143547143548143549143550143551143552143553143554143555143556143557143558143559143560143561143562143563143564143565143566143567143568143569143570143571143572143573143574143575143576143577143578143579143580143581143582143583143584143585143586143587143588143589143590143591143592143593143594143595143596143597143598143599143600143601143602143603143604143605143606143607143608143609143610143611143612143613143614143615143616143617143618143619143620143621143622143623143624143625143626143627143628143629143630143631143632143633143634143635143636143637143638143639143640143641143642143643143644143645143646143647143648143649143650143651143652143653143654143655143656143657143658143659143660143661143662143663143664143665143666143667143668143669143670143671143672143673143674143675143676143677143678143679143680143681143682143683143684143685143686143687143688143689143690143691143692143693143694143695143696143697143698143699143700143701143702143703143704143705143706143707143708143709143710143711143712143713143714143715143716143717143718143719143720143721143722143723143724143725143726143727143728143729143730143731143732143733143734143735143736143737143738143739143740143741143742143743143744143745143746143747143748143749143750143751143752143753143754143755143756143757143758143759143760143761143762143763143764143765143766143767143768143769143770143771143772143773143774143775143776143777143778143779143780143781143782143783143784143785143786143787143788143789143790143791143792143793143794143795143796143797143798143799143800143801143802143803143804143805143806143807143808143809143810143811143812143813143814143815143816143817143818143819143820143821143822143823143824143825143826143827143828143829143830143831143832143833143834143835143836143837143838143839143840143841143842143843143844143845143846143847143848143849143850143851143852143853143854143855143856143857143858143859143860143861143862143863143864143865143866143867143868143869143870143871143872143873143874143875143876143877143878143879143880143881143882143883143884143885143886143887143888143889143890143891143892143893143894143895143896143897143898143899143900143901143902143903143904143905143906143907143908143909143910143911143912143913143914143915143916143917143918143919143920143921143922143923143924143925143926143927143928143929143930143931143932143933143934143935143936143937143938143939143940143941143942143943143944143945143946143947143948143949143950143951143952143953143954143955143956143957143958143959143960143961143962143963143964143965143966143967143968143969143970143971143972143973143974143975143976143977143978143979143980143981143982143983143984143985143986143987143988143989143990143991143992143993143994143995143996143997143998143999144000144001144002144003144004144005144006144007144008144009144010144011144012144013144014144015144016144017144018144019144020144021144022144023144024144025144026144027144028144029144030144031144032144033144034144035144036144037144038144039144040144041144042144043144044144045144046144047144048144049144050144051144052144053144054144055144056144057144058144059144060144061144062144063144064144065144066144067144068144069144070144071144072144073144074144075144076144077144078144079144080144081144082144083144084144085144086144087144088144089144090144091144092144093144094144095144096144097144098144099144100144101144102144103144104144105144106144107144108144109144110144111144112144113144114144115144116144117144118144119144120144121144122144123144124144125144126144127144128144129144130144131144132144133144134144135144136144137144138144139144140144141144142144143144144144145144146144147144148144149144150144151144152144153144154144155144156144157144158144159144160144161144162144163144164144165144166144167144168144169144170144171144172144173144174144175144176144177144178144179144180144181144182144183144184144185144186144187144188144189144190144191144192144193144194144195144196144197144198144199144200144201144202144203144204144205144206144207144208144209144210144211144212144213144214144215144216144217144218144219144220144221144222144223144224144225144226144227144228144229144230144231144232144233144234144235144236144237144238144239144240144241144242144243144244144245144246144247144248144249144250144251144252144253144254144255144256144257144258144259144260144261144262144263144264144265144266144267144268144269144270144271144272144273144274144275144276144277144278144279144280144281144282144283144284144285144286144287144288144289144290144291144292144293144294144295144296144297144298144299144300144301144302144303144304144305144306144307144308144309144310144311144312144313144314144315144316144317144318144319144320144321144322144323144324144325144326144327144328144329144330144331144332144333144334144335144336144337144338144339144340144341144342144343144344144345144346144347144348144349144350144351144352144353144354144355144356144357144358144359144360144361144362144363144364144365144366144367144368144369144370144371144372144373144374144375144376144377144378144379144380144381144382144383144384144385144386144387144388144389144390144391144392144393144394144395144396144397144398144399144400144401144402144403144404144405144406144407144408144409144410144411144412144413144414144415144416144417144418144419144420144421144422144423144424144425144426144427144428144429144430144431144432144433144434144435144436144437144438144439144440144441144442144443144444144445144446144447144448144449144450144451144452144453144454144455144456144457144458144459144460144461144462144463144464144465144466144467144468144469144470144471144472144473144474144475144476144477144478144479144480144481144482144483144484144485144486144487144488144489144490144491144492144493144494144495144496144497144498144499144500144501144502144503144504144505144506144507144508144509144510144511144512144513144514144515144516144517144518144519144520144521144522144523144524144525144526144527144528144529144530144531144532144533144534144535144536144537144538144539144540144541144542144543144544144545144546144547144548144549144550144551144552144553144554144555144556144557144558144559144560144561144562144563144564144565144566144567144568144569144570144571144572144573144574144575144576144577144578144579144580144581144582144583144584144585144586144587144588144589144590144591144592144593144594144595144596144597144598144599144600144601144602144603144604144605144606144607144608144609144610144611144612144613144614144615144616144617144618144619144620144621144622144623144624144625144626144627144628144629144630144631144632144633144634144635144636144637144638144639144640144641144642144643144644144645144646144647144648144649144650144651144652144653144654144655144656144657144658144659144660144661144662144663144664144665144666144667144668144669144670144671144672144673144674144675144676144677144678144679144680144681144682144683144684144685144686144687144688144689144690144691144692144693144694144695144696144697144698144699144700144701144702144703144704144705144706144707144708144709144710144711144712144713144714144715144716144717144718144719144720144721144722144723144724144725144726144727144728144729144730144731144732144733144734144735144736144737144738144739144740144741144742144743144744144745144746144747144748144749144750144751144752144753144754144755144756144757144758144759144760144761144762144763144764144765144766144767144768144769144770144771144772144773144774144775144776144777144778144779144780144781144782144783144784144785144786144787144788144789144790144791144792144793144794144795144796144797144798144799144800144801144802144803144804144805144806144807144808144809144810144811144812144813144814144815144816144817144818144819144820144821144822144823144824144825144826144827144828144829144830144831144832144833144834144835144836144837144838144839144840144841144842144843144844144845144846144847144848144849144850144851144852144853144854144855144856144857144858144859144860144861144862144863144864144865144866144867144868144869144870144871144872144873144874144875144876144877144878144879144880144881144882144883144884144885144886144887144888144889144890144891144892144893144894144895144896144897144898144899144900144901144902144903144904144905144906144907144908144909144910144911144912144913144914144915144916144917144918144919144920144921144922144923144924144925144926144927144928144929144930144931144932144933144934144935144936144937144938144939144940144941144942144943144944144945144946144947144948144949144950144951144952144953144954144955144956144957144958144959144960144961144962144963144964144965144966144967144968144969144970144971144972144973144974144975144976144977144978144979144980144981144982144983144984144985144986144987144988144989144990144991144992144993144994144995144996144997144998144999145000145001145002145003145004145005145006145007145008145009145010145011145012145013145014145015145016145017145018145019145020145021145022145023145024145025145026145027145028145029145030145031145032145033145034145035145036145037145038145039145040145041145042145043145044145045145046145047145048145049145050145051145052145053145054145055145056145057145058145059145060145061145062145063145064145065145066145067145068145069145070145071145072145073145074145075145076145077145078145079145080145081145082145083145084145085145086145087145088145089145090145091145092145093145094145095145096145097145098145099145100145101145102145103145104145105145106145107145108145109145110145111145112145113145114145115145116145117145118145119145120145121145122145123145124145125145126145127145128145129145130145131145132145133145134145135145136145137145138145139145140145141145142145143145144145145145146145147145148145149145150145151145152145153145154145155145156145157145158145159145160145161145162145163145164145165145166145167145168145169145170145171145172145173145174145175145176145177145178145179145180145181145182145183145184145185145186145187145188145189145190145191145192145193145194145195145196145197145198145199145200145201145202145203145204145205145206145207145208145209145210145211145212145213145214145215145216145217145218145219145220145221145222145223145224145225145226145227145228145229145230145231145232145233145234145235145236145237145238145239145240145241145242145243145244145245145246145247145248145249145250145251145252145253145254145255145256145257145258145259145260145261145262145263145264145265145266145267145268145269145270145271145272145273145274145275145276145277145278145279145280145281145282145283145284145285145286145287145288145289145290145291145292145293145294145295145296145297145298145299145300145301145302145303145304145305145306145307145308145309145310145311145312145313145314145315145316145317145318145319145320145321145322145323145324145325145326145327145328145329145330145331145332145333145334145335145336145337145338145339145340145341145342145343145344145345145346145347145348145349145350145351145352145353145354145355145356145357145358145359145360145361145362145363145364145365145366145367145368145369145370145371145372145373145374145375145376145377145378145379145380145381145382145383145384145385145386145387145388145389145390145391145392145393145394145395145396145397145398145399145400145401145402145403145404145405145406145407145408145409145410145411145412145413145414145415145416145417145418145419145420145421145422145423145424145425145426145427145428145429145430145431145432145433145434145435145436145437145438145439145440145441145442145443145444145445145446145447145448145449145450145451145452145453145454145455145456145457145458145459145460145461145462145463145464145465145466145467145468145469145470145471145472145473145474145475145476145477145478145479145480145481145482145483145484145485145486145487145488145489145490145491145492145493145494145495145496145497145498145499145500145501145502145503145504145505145506145507145508145509145510145511145512145513145514145515145516145517145518145519145520145521145522145523145524145525145526145527145528145529145530145531145532145533145534145535145536145537145538145539145540145541145542145543145544145545145546145547145548145549145550145551145552145553145554145555145556145557145558145559145560145561145562145563145564145565145566145567145568145569145570145571145572145573145574145575145576145577145578145579145580145581145582145583145584145585145586145587145588145589145590145591145592145593145594145595145596145597145598145599145600145601145602145603145604145605145606145607145608145609145610145611145612145613145614145615145616145617145618145619145620145621145622145623145624145625145626145627145628145629145630145631145632145633145634145635145636145637145638145639145640145641145642145643145644145645145646145647145648145649145650145651145652145653145654145655145656145657145658145659145660145661145662145663145664145665145666145667145668145669145670145671145672145673145674145675145676145677145678145679145680145681145682145683145684145685145686145687145688145689145690145691145692145693145694145695145696145697145698145699145700145701145702145703145704145705145706145707145708145709145710145711145712145713145714145715145716145717145718145719145720145721145722145723145724145725145726145727145728145729145730145731145732145733145734145735145736145737145738145739145740145741145742145743145744145745145746145747145748145749145750145751145752145753145754145755145756145757145758145759145760145761145762145763145764145765145766145767145768145769145770145771145772145773145774145775145776145777145778145779145780145781145782145783145784145785145786145787145788145789145790145791145792145793145794145795145796145797145798145799145800145801145802145803145804145805145806145807145808145809145810145811145812145813145814145815145816145817145818145819145820145821145822145823145824145825145826145827145828145829145830145831145832145833145834145835145836145837145838145839145840145841145842145843145844145845145846145847145848145849145850145851145852145853145854145855145856145857145858145859145860145861145862145863145864145865145866145867145868145869145870145871145872145873145874145875145876145877145878145879145880145881145882145883145884145885145886145887145888145889145890145891145892145893145894145895145896145897145898145899145900145901145902145903145904145905145906145907145908145909145910145911145912145913145914145915145916145917145918145919145920145921145922145923145924145925145926145927145928145929145930145931145932145933145934145935145936145937145938145939145940145941145942145943145944145945145946145947145948145949145950145951145952145953145954145955145956145957145958145959145960145961145962145963145964145965145966145967145968145969145970145971145972145973145974145975145976145977145978145979145980145981145982145983145984145985145986145987145988145989145990145991145992145993145994145995145996145997145998145999146000146001146002146003146004146005146006146007146008146009146010146011146012146013146014146015146016146017146018146019146020146021146022146023146024146025146026146027146028146029146030146031146032146033146034146035146036146037146038146039146040146041146042146043146044146045146046146047146048146049146050146051146052146053146054146055146056146057146058146059146060146061146062146063146064146065146066146067146068146069146070146071146072146073146074146075146076146077146078146079146080146081146082146083146084146085146086146087146088146089146090146091146092146093146094146095146096146097146098146099146100146101146102146103146104146105146106146107146108146109146110146111146112146113146114146115146116146117146118146119146120146121146122146123146124146125146126146127146128146129146130146131146132146133146134146135146136146137146138146139146140146141146142146143146144146145146146146147146148146149146150146151146152146153146154146155146156146157146158146159146160146161146162146163146164146165146166146167146168146169146170146171146172146173146174146175146176146177146178146179146180146181146182146183146184146185146186146187146188146189146190146191146192146193146194146195146196146197146198146199146200146201146202146203146204146205146206146207146208146209146210146211146212146213146214146215146216146217146218146219146220146221146222146223146224146225146226146227146228146229146230146231146232146233146234146235146236146237146238146239146240146241146242146243146244146245146246146247146248146249146250146251146252146253146254146255146256146257146258146259146260146261146262146263146264146265146266146267146268146269146270146271146272146273146274146275146276146277146278146279146280146281146282146283146284146285146286146287146288146289146290146291146292146293146294146295146296146297146298146299146300146301146302146303146304146305146306146307146308146309146310146311146312146313146314146315146316146317146318146319146320146321146322146323146324146325146326146327146328146329146330146331146332146333146334146335146336146337146338146339146340146341146342146343146344146345146346146347146348146349146350146351146352146353146354146355146356146357146358146359146360146361146362146363146364146365146366146367146368146369146370146371146372146373146374146375146376146377146378146379146380146381146382146383146384146385146386146387146388146389146390146391146392146393146394146395146396146397146398146399146400146401146402146403146404146405146406146407146408146409146410146411146412146413146414146415146416146417146418146419146420146421146422146423146424146425146426146427146428146429146430146431146432146433146434146435146436146437146438146439146440146441146442146443146444146445146446146447146448146449146450146451146452146453146454146455146456146457146458146459146460146461146462146463146464146465146466146467146468146469146470146471146472146473146474146475146476146477146478146479146480146481146482146483146484146485146486146487146488146489146490146491146492146493146494146495146496146497146498146499146500146501146502146503146504146505146506146507146508146509146510146511146512146513146514146515146516146517146518146519146520146521146522146523146524146525146526146527146528146529146530146531146532146533146534146535146536146537146538146539146540146541146542146543146544146545146546146547146548146549146550146551146552146553146554146555146556146557146558146559146560146561146562146563146564146565146566146567146568146569146570146571146572146573146574146575146576146577146578146579146580146581146582146583146584146585146586146587146588146589146590146591146592146593146594146595146596146597146598146599146600146601146602146603146604146605146606146607146608146609146610146611146612146613146614146615146616146617146618146619146620146621146622146623146624146625146626146627146628146629146630146631146632146633146634146635146636146637146638146639146640146641146642146643146644146645146646146647146648146649146650146651146652146653146654146655146656146657146658146659146660146661146662146663146664146665146666146667146668146669146670146671146672146673146674146675146676146677146678146679146680146681146682146683146684146685146686146687146688146689146690146691146692146693146694146695146696146697146698146699146700146701146702146703146704146705146706146707146708146709146710146711146712146713146714146715146716146717146718146719146720146721146722146723146724146725146726146727146728146729146730146731146732146733146734146735146736146737146738146739146740146741146742146743146744146745146746146747146748146749146750146751146752146753146754146755146756146757146758146759146760146761146762146763146764146765146766146767146768146769146770146771146772146773146774146775146776146777146778146779146780146781146782146783146784146785146786146787146788146789146790146791146792146793146794146795146796146797146798146799146800146801146802146803146804146805146806146807146808146809146810146811146812146813146814146815146816146817146818146819146820146821146822146823146824146825146826146827146828146829146830146831146832146833146834146835146836146837146838146839146840146841146842146843146844146845146846146847146848146849146850146851146852146853146854146855146856146857146858146859146860146861146862146863146864146865146866146867146868146869146870146871146872146873146874146875146876146877146878146879146880146881146882146883146884146885146886146887146888146889146890146891146892146893146894146895146896146897146898146899146900146901146902146903146904146905146906146907146908146909146910146911146912146913146914146915146916146917146918146919146920146921146922146923146924146925146926146927146928146929146930146931146932146933146934146935146936146937146938146939146940146941146942146943146944146945146946146947146948146949146950146951146952146953146954146955146956146957146958146959146960146961146962146963146964146965146966146967146968146969146970146971146972146973146974146975146976146977146978146979146980146981146982146983146984146985146986146987146988146989146990146991146992146993146994146995146996146997146998146999147000147001147002147003147004147005147006147007147008147009147010147011147012147013147014147015147016147017147018147019147020147021147022147023147024147025147026147027147028147029147030147031147032147033147034147035147036147037147038147039147040147041147042147043147044147045147046147047147048147049147050147051147052147053147054147055147056147057147058147059147060147061147062147063147064147065147066147067147068147069147070147071147072147073147074147075147076147077147078147079147080147081147082147083147084147085147086147087147088147089147090147091147092147093147094147095147096147097147098147099147100147101147102147103147104147105147106147107147108147109147110147111147112147113147114147115147116147117147118147119147120147121147122147123147124147125147126147127147128147129147130147131147132147133147134147135147136147137147138147139147140147141147142147143147144147145147146147147147148147149147150147151147152147153147154147155147156147157147158147159147160147161147162147163147164147165147166147167147168147169147170147171147172147173147174147175147176147177147178147179147180147181147182147183147184147185147186147187147188147189147190147191147192147193147194147195147196147197147198147199147200147201147202147203147204147205147206147207147208147209147210147211147212147213147214147215147216147217147218147219147220147221147222147223147224147225147226147227147228147229147230147231147232147233147234147235147236147237147238147239147240147241147242147243147244147245147246147247147248147249147250147251147252147253147254147255147256147257147258147259147260147261147262147263147264147265147266147267147268147269147270147271147272147273147274147275147276147277147278147279147280147281147282147283147284147285147286147287147288147289147290147291147292147293147294147295147296147297147298147299147300147301147302147303147304147305147306147307147308147309147310147311147312147313147314147315147316147317147318147319147320147321147322147323147324147325147326147327147328147329147330147331147332147333147334147335147336147337147338147339147340147341147342147343147344147345147346147347147348147349147350147351147352147353147354147355147356147357147358147359147360147361147362147363147364147365147366147367147368147369147370147371147372147373147374147375147376147377147378147379147380147381147382147383147384147385147386147387147388147389147390147391147392147393147394147395147396147397147398147399147400147401147402147403147404147405147406147407147408147409147410147411147412147413147414147415147416147417147418147419147420147421147422147423147424147425147426147427147428147429147430147431147432147433147434147435147436147437147438147439147440147441147442147443147444147445147446147447147448147449147450147451147452147453147454147455147456147457147458147459147460147461147462147463147464147465147466147467147468147469147470147471147472147473147474147475147476147477147478147479147480147481147482147483147484147485147486147487147488147489147490147491147492147493147494147495147496147497147498147499147500147501147502147503147504147505147506147507147508147509147510147511147512147513147514147515147516147517147518147519147520147521147522147523147524147525147526147527147528147529147530147531147532147533147534147535147536147537147538147539147540147541147542147543147544147545147546147547147548147549147550147551147552147553147554147555147556147557147558147559147560147561147562147563147564147565147566147567147568147569147570147571147572147573147574147575147576147577147578147579147580147581147582147583147584147585147586147587147588147589147590147591147592147593147594147595147596147597147598147599147600147601147602147603147604147605147606147607147608147609147610147611147612147613147614147615147616147617147618147619147620147621147622147623147624147625147626147627147628147629147630147631147632147633147634147635147636147637147638147639147640147641147642147643147644147645147646147647147648147649147650147651147652147653147654147655147656147657147658147659147660147661147662147663147664147665147666147667147668147669147670147671147672147673147674147675147676147677147678147679147680147681147682147683147684147685147686147687147688147689147690147691147692147693147694147695147696147697147698147699147700147701147702147703147704147705147706147707147708147709147710147711147712147713147714147715147716147717147718147719147720147721147722147723147724147725147726147727147728147729147730147731147732147733147734147735147736147737147738147739147740147741147742147743147744147745147746147747147748147749147750147751147752147753147754147755147756147757147758147759147760147761147762147763147764147765147766147767147768147769147770147771147772147773147774147775147776147777147778147779147780147781147782147783147784147785147786147787147788147789147790147791147792147793147794147795147796147797147798147799147800147801147802147803147804147805147806147807147808147809147810147811147812147813147814147815147816147817147818147819147820147821147822147823147824147825147826147827147828147829147830147831147832147833147834147835147836147837147838147839147840147841147842147843147844147845147846147847147848147849147850147851147852147853147854147855147856147857147858147859147860147861147862147863147864147865147866147867147868147869147870147871147872147873147874147875147876147877147878147879147880147881147882147883147884147885147886147887147888147889147890147891147892147893147894147895147896147897147898147899147900147901147902147903147904147905147906147907147908147909147910147911147912147913147914147915147916147917147918147919147920147921147922147923147924147925147926147927147928147929147930147931147932147933147934147935147936147937147938147939147940147941147942147943147944147945147946147947147948147949147950147951147952147953147954147955147956147957147958147959147960147961147962147963147964147965147966147967147968147969147970147971147972147973147974147975147976147977147978147979147980147981147982147983147984147985147986147987147988147989147990147991147992147993147994147995147996147997147998147999148000148001148002148003148004148005148006148007148008148009148010148011148012148013148014148015148016148017148018148019148020148021148022148023148024148025148026148027148028148029148030148031148032148033148034148035148036148037148038148039148040148041148042148043148044148045148046148047148048148049148050148051148052148053148054148055148056148057148058148059148060148061148062148063148064148065148066148067148068148069148070148071148072148073148074148075148076148077148078148079148080148081148082148083148084148085148086148087148088148089148090148091148092148093148094148095148096148097148098148099148100148101148102148103148104148105148106148107148108148109148110148111148112148113148114148115148116148117148118148119148120148121148122148123148124148125148126148127148128148129148130148131148132148133148134148135148136148137148138148139148140148141148142148143148144148145148146148147148148148149148150148151148152148153148154148155148156148157148158148159148160148161148162148163148164148165148166148167148168148169148170148171148172148173148174148175148176148177148178148179148180148181148182148183148184148185148186148187148188148189148190148191148192148193148194148195148196148197148198148199148200148201148202148203148204148205148206148207148208148209148210148211148212148213148214148215148216148217148218148219148220148221148222148223148224148225148226148227148228148229148230148231148232148233148234148235148236148237148238148239148240148241148242148243148244148245148246148247148248148249148250148251148252148253148254148255148256148257148258148259148260148261148262148263148264148265148266148267148268148269148270148271148272148273148274148275148276148277148278148279148280148281148282148283148284148285148286148287148288148289148290148291148292148293148294148295148296148297148298148299148300148301148302148303148304148305148306148307148308148309148310148311148312148313148314148315148316148317148318148319148320148321148322148323148324148325148326148327148328148329148330148331148332148333148334148335148336148337148338148339148340148341148342148343148344148345148346148347148348148349148350148351148352148353148354148355148356148357148358148359148360148361148362148363148364148365148366148367148368148369148370148371148372148373148374148375148376148377148378148379148380148381148382148383148384148385148386148387148388148389148390148391148392148393148394148395148396148397148398148399148400148401148402148403148404148405148406148407148408148409148410148411148412148413148414148415148416148417148418148419148420148421148422148423148424148425148426148427148428148429148430148431148432148433148434148435148436148437148438148439148440148441148442148443148444148445148446148447148448148449148450148451148452148453148454148455148456148457148458148459148460148461148462148463148464148465148466148467148468148469148470148471148472148473148474148475148476148477148478148479148480148481148482148483148484148485148486148487148488148489148490148491148492148493148494148495148496148497148498148499148500148501148502148503148504148505148506148507148508148509148510148511148512148513148514148515148516148517148518148519148520148521148522148523148524148525148526148527148528148529148530148531148532148533148534148535148536148537148538148539148540148541148542148543148544148545148546148547148548148549148550148551148552148553148554148555148556148557148558148559148560148561148562148563148564148565148566148567148568148569148570148571148572148573148574148575148576148577148578148579148580148581148582148583148584148585148586148587148588148589148590148591148592148593148594148595148596148597148598148599148600148601148602148603148604148605148606148607148608148609148610148611148612148613148614148615148616148617148618148619148620148621148622148623148624148625148626148627148628148629148630148631148632148633148634148635148636148637148638148639148640148641148642148643148644148645148646148647148648148649148650148651148652148653148654148655148656148657148658148659148660148661148662148663148664148665148666148667148668148669148670148671148672148673148674148675148676148677148678148679148680148681148682148683148684148685148686148687148688148689148690148691148692148693148694148695148696148697148698148699148700148701148702148703148704148705148706148707148708148709148710148711148712148713148714148715148716148717148718148719148720148721148722148723148724148725148726148727148728148729148730148731148732148733148734148735148736148737148738148739148740148741148742148743148744148745148746148747148748148749148750148751148752148753148754148755148756148757148758148759148760148761148762148763148764148765148766148767148768148769148770148771148772148773148774148775148776148777148778148779148780148781148782148783148784148785148786148787148788148789148790148791148792148793148794148795148796148797148798148799148800148801148802148803148804148805148806148807148808148809148810148811148812148813148814148815148816148817148818148819148820148821148822148823148824148825148826148827148828148829148830148831148832148833148834148835148836148837148838148839148840148841148842148843148844148845148846148847148848148849148850148851148852148853148854148855148856148857148858148859148860148861148862148863148864148865148866148867148868148869148870148871148872148873148874148875148876148877148878148879148880148881148882148883148884148885148886148887148888148889148890148891148892148893148894148895148896148897148898148899148900148901148902148903148904148905148906148907148908148909148910148911148912148913148914148915148916148917148918148919148920148921148922148923148924148925148926148927148928148929148930148931148932148933148934148935148936148937148938148939148940148941148942148943148944148945148946148947148948148949148950148951148952148953148954148955148956148957148958148959148960148961148962148963148964148965148966148967148968148969148970148971148972148973148974148975148976148977148978148979148980148981148982148983148984148985148986148987148988148989148990148991148992148993148994148995148996148997148998148999149000149001149002149003149004149005149006149007149008149009149010149011149012149013149014149015149016149017149018149019149020149021149022149023149024149025149026149027149028149029149030149031149032149033149034149035149036149037149038149039149040149041149042149043149044149045149046149047149048149049149050149051149052149053149054149055149056149057149058149059149060149061149062149063149064149065149066149067149068149069149070149071149072149073149074149075149076149077149078149079149080149081149082149083149084149085149086149087149088149089149090149091149092149093149094149095149096149097149098149099149100149101149102149103149104149105149106149107149108149109149110149111149112149113149114149115149116149117149118149119149120149121149122149123149124149125149126149127149128149129149130149131149132149133149134149135149136149137149138149139149140149141149142149143149144149145149146149147149148149149149150149151149152149153149154149155149156149157149158149159149160149161149162149163149164149165149166149167149168149169149170149171149172149173149174149175149176149177149178149179149180149181149182149183149184149185149186149187149188149189149190149191149192149193149194149195149196149197149198149199149200149201149202149203149204149205149206149207149208149209149210149211149212149213149214149215149216149217149218149219149220149221149222149223149224149225149226149227149228149229149230149231149232149233149234149235149236149237149238149239149240149241149242149243149244149245149246149247149248149249149250149251149252149253149254149255149256149257149258149259149260149261149262149263149264149265149266149267149268149269149270149271149272149273149274149275149276149277149278149279149280149281149282149283149284149285149286149287149288149289149290149291149292149293149294149295149296149297149298149299149300149301149302149303149304149305149306149307149308149309149310149311149312149313149314149315149316149317149318149319149320149321149322149323149324149325149326149327149328149329149330149331149332149333149334149335149336149337149338149339149340149341149342149343149344149345149346149347149348149349149350149351149352149353149354149355149356149357149358149359149360149361149362149363149364149365149366149367149368149369149370149371149372149373149374149375149376149377149378149379149380149381149382149383149384149385149386149387149388149389149390149391149392149393149394149395149396149397149398149399149400149401149402149403149404149405149406149407149408149409149410149411149412149413149414149415149416149417149418149419149420149421149422149423149424149425149426149427149428149429149430149431149432149433149434149435149436149437149438149439149440149441149442149443149444149445149446149447149448149449149450149451149452149453149454149455149456149457149458149459149460149461149462149463149464149465149466149467149468149469149470149471149472149473149474149475149476149477149478149479149480149481149482149483149484149485149486149487149488149489149490149491149492149493149494149495149496149497149498149499149500149501149502149503149504149505149506149507149508149509149510149511149512149513149514149515149516149517149518149519149520149521149522149523149524149525149526149527149528149529149530149531149532149533149534149535149536149537149538149539149540149541149542149543149544149545149546149547149548149549149550149551149552149553149554149555149556149557149558149559149560149561149562149563149564149565149566149567149568149569149570149571149572149573149574149575149576149577149578149579149580149581149582149583149584149585149586149587149588149589149590149591149592149593149594149595149596149597149598149599149600149601149602149603149604149605149606149607149608149609149610149611149612149613149614149615149616149617149618149619149620149621149622149623149624149625149626149627149628149629149630149631149632149633149634149635149636149637149638149639149640149641149642149643149644149645149646149647149648149649149650149651149652149653149654149655149656149657149658149659149660149661149662149663149664149665149666149667149668149669149670149671149672149673149674149675149676149677149678149679149680149681149682149683149684149685149686149687149688149689149690149691149692149693149694149695149696149697149698149699149700149701149702149703149704149705149706149707149708149709149710149711149712149713149714149715149716149717149718149719149720149721149722149723149724149725149726149727149728149729149730149731149732149733149734149735149736149737149738149739149740149741149742149743149744149745149746149747149748149749149750149751149752149753149754149755149756149757149758149759149760149761149762149763149764149765149766149767149768149769149770149771149772149773149774149775149776149777149778149779149780149781149782149783149784149785149786149787149788149789149790149791149792149793149794149795149796149797149798149799149800149801149802149803149804149805149806149807149808149809149810149811149812149813149814149815149816149817149818149819149820149821149822149823149824149825149826149827149828149829149830149831149832149833149834149835149836149837149838149839149840149841149842149843149844149845149846149847149848149849149850149851149852149853149854149855149856149857149858149859149860149861149862149863149864149865149866149867149868149869149870149871149872149873149874149875149876149877149878149879149880149881149882149883149884149885149886149887149888149889149890149891149892149893149894149895149896149897149898149899149900149901149902149903149904149905149906149907149908149909149910149911149912149913149914149915149916149917149918149919149920149921149922149923149924149925149926149927149928149929149930149931149932149933149934149935149936149937149938149939149940149941149942149943149944149945149946149947149948149949149950149951149952149953149954149955149956149957149958149959149960149961149962149963149964149965149966149967149968149969149970149971149972149973149974149975149976149977149978149979149980149981149982149983149984149985149986149987149988149989149990149991149992149993149994149995149996149997149998149999150000150001150002150003150004150005150006150007150008150009150010150011150012150013150014150015150016150017150018150019150020150021150022150023150024150025150026150027150028150029150030150031150032150033150034150035150036150037150038150039150040150041150042150043150044150045150046150047150048150049150050150051150052150053150054150055150056150057150058150059150060150061150062150063150064150065150066150067150068150069150070150071150072150073150074150075150076150077150078150079150080150081150082150083150084150085150086150087150088150089150090150091150092150093150094150095150096150097150098150099150100150101150102150103150104150105150106150107150108150109150110150111150112150113150114150115150116150117150118150119150120150121150122150123150124150125150126150127150128150129150130150131150132150133150134150135150136150137150138150139150140150141150142150143150144150145150146150147150148150149150150150151150152150153150154150155150156150157150158150159150160150161150162150163150164150165150166150167150168150169150170150171150172150173150174150175150176150177150178150179150180150181150182150183150184150185150186150187150188150189150190150191150192150193150194150195150196150197150198150199150200150201150202150203150204150205150206150207150208150209150210150211150212150213150214150215150216150217150218150219150220150221150222150223150224150225150226150227150228150229150230150231150232150233150234150235150236150237150238150239150240150241150242150243150244150245150246150247150248150249150250150251150252150253150254150255150256150257150258150259150260150261150262150263150264150265150266150267150268150269150270150271150272150273150274150275150276150277150278150279150280150281150282150283150284150285150286150287150288150289150290150291150292150293150294150295150296150297150298150299150300150301150302150303150304150305150306150307150308150309150310150311150312150313150314150315150316150317150318150319150320150321150322150323150324150325150326150327150328150329150330150331150332150333150334150335150336150337150338150339150340150341150342150343150344150345150346150347150348150349150350150351150352150353150354150355150356150357150358150359150360150361150362150363150364150365150366150367150368150369150370150371150372150373150374150375150376150377150378150379150380150381150382150383150384150385150386150387150388150389150390150391150392150393150394150395150396150397150398150399150400150401150402150403150404150405150406150407150408150409150410150411150412150413150414150415150416150417150418150419150420150421150422150423150424150425150426150427150428150429150430150431150432150433150434150435150436150437150438150439150440150441150442150443150444150445150446150447150448150449150450150451150452150453150454150455150456150457150458150459150460150461150462150463150464150465150466150467150468150469150470150471150472150473150474150475150476150477150478150479150480150481150482150483150484150485150486150487150488150489150490150491150492150493150494150495150496150497150498150499150500150501150502150503150504150505150506150507150508150509150510150511150512150513150514150515150516150517150518150519150520150521150522150523150524150525150526150527150528150529150530150531150532150533150534150535150536150537150538150539150540150541150542150543150544150545150546150547150548150549150550150551150552150553150554150555150556150557150558150559150560150561150562150563150564150565150566150567150568150569150570150571150572150573150574150575150576150577150578150579150580150581150582150583150584150585150586150587150588150589150590150591150592150593150594150595150596150597150598150599150600150601150602150603150604150605150606150607150608150609150610150611150612150613150614150615150616150617150618150619150620150621150622150623150624150625150626150627150628150629150630150631150632150633150634150635150636150637150638150639150640150641150642150643150644150645150646150647150648150649150650150651150652150653150654150655150656150657150658150659150660150661150662150663150664150665150666150667150668150669150670150671150672150673150674150675150676150677150678150679150680150681150682150683150684150685150686150687150688150689150690150691150692150693150694150695150696150697150698150699150700150701150702150703150704150705150706150707150708150709150710150711150712150713150714150715150716150717150718150719150720150721150722150723150724150725150726150727150728150729150730150731150732150733150734150735150736150737150738150739150740150741150742150743150744150745150746150747150748150749150750150751150752150753150754150755150756150757150758150759150760150761150762150763150764150765150766150767150768150769150770150771150772150773150774150775150776150777150778150779150780150781150782150783150784150785150786150787150788150789150790150791150792150793150794150795150796150797150798150799150800150801150802150803150804150805150806150807150808150809150810150811150812150813150814150815150816150817150818150819150820150821150822150823150824150825150826150827150828150829150830150831150832150833150834150835150836150837150838150839150840150841150842150843150844150845150846150847150848150849150850150851150852150853150854150855150856150857150858150859150860150861150862150863150864150865150866150867150868150869150870150871150872150873150874150875150876150877150878150879150880150881150882150883150884150885150886150887150888150889150890150891150892150893150894150895150896150897150898150899150900150901150902150903150904150905150906150907150908150909150910150911150912150913150914150915150916150917150918150919150920150921150922150923150924150925150926150927150928150929150930150931150932150933150934150935150936150937150938150939150940150941150942150943150944150945150946150947150948150949150950150951150952150953150954150955150956150957150958150959150960150961150962150963150964150965150966150967150968150969150970150971150972150973150974150975150976150977150978150979150980150981150982150983150984150985150986150987150988150989150990150991150992150993150994150995150996150997150998150999151000151001151002151003151004151005151006151007151008151009151010151011151012151013151014151015151016151017151018151019151020151021151022151023151024151025151026151027151028151029151030151031151032151033151034151035151036151037151038151039151040151041151042151043151044151045151046151047151048151049151050151051151052151053151054151055151056151057151058151059151060151061151062151063151064151065151066151067151068151069151070151071151072151073151074151075151076151077151078151079151080151081151082151083151084151085151086151087151088151089151090151091151092151093151094151095151096151097151098151099151100151101151102151103151104151105151106151107151108151109151110151111151112151113151114151115151116151117151118151119151120151121151122151123151124151125151126151127151128151129151130151131151132151133151134151135151136151137151138151139151140151141151142151143151144151145151146151147151148151149151150151151151152151153151154151155151156151157151158151159151160151161151162151163151164151165151166151167151168151169151170151171151172151173151174151175151176151177151178151179151180151181151182151183151184151185151186151187151188151189151190151191151192151193151194151195151196151197151198151199151200151201151202151203151204151205151206151207151208151209151210151211151212151213151214151215151216151217151218151219151220151221151222151223151224151225151226151227151228151229151230151231151232151233151234151235151236151237151238151239151240151241151242151243151244151245151246151247151248151249151250151251151252151253151254151255151256151257151258151259151260151261151262151263151264151265151266151267151268151269151270151271151272151273151274151275151276151277151278151279151280151281151282151283151284151285151286151287151288151289151290151291151292151293151294151295151296151297151298151299151300151301151302151303151304151305151306151307151308151309151310151311151312151313151314151315151316151317151318151319151320151321151322151323151324151325151326151327151328151329151330151331151332151333151334151335151336151337151338151339151340151341151342151343151344151345151346151347151348151349151350151351151352151353151354151355151356151357151358151359151360151361151362151363151364151365151366151367151368151369151370151371151372151373151374151375151376151377151378151379151380151381151382151383151384151385151386151387151388151389151390151391151392151393151394151395151396151397151398151399151400151401151402151403151404151405151406151407151408151409151410151411151412151413151414151415151416151417151418151419151420151421151422151423151424151425151426151427151428151429151430151431151432151433151434151435151436151437151438151439151440151441151442151443151444151445151446151447151448151449151450151451151452151453151454151455151456151457151458151459151460151461151462151463151464151465151466151467151468151469151470151471151472151473151474151475151476151477151478151479151480151481151482151483151484151485151486151487151488151489151490151491151492151493151494151495151496151497151498151499151500151501151502151503151504151505151506151507151508151509151510151511151512151513151514151515151516151517151518151519151520151521151522151523151524151525151526151527151528151529151530151531151532151533151534151535151536151537151538151539151540151541151542151543151544151545151546151547151548151549151550151551151552151553151554151555151556151557151558151559151560151561151562151563151564151565151566151567151568151569151570151571151572151573151574151575151576151577151578151579151580151581151582151583151584151585151586151587151588151589151590151591151592151593151594151595151596151597151598151599151600151601151602151603151604151605151606151607151608151609151610151611151612151613151614151615151616151617151618151619151620151621151622151623151624151625151626151627151628151629151630151631151632151633151634151635151636151637151638151639151640151641151642151643151644151645151646151647151648151649151650151651151652151653151654151655151656151657151658151659151660151661151662151663151664151665151666151667151668151669151670151671151672151673151674151675151676151677151678151679151680151681151682151683151684151685151686151687151688151689151690151691151692151693151694151695151696151697151698151699151700151701151702151703151704151705151706151707151708151709151710151711151712151713151714151715151716151717151718151719151720151721151722151723151724151725151726151727151728151729151730151731151732151733151734151735151736151737151738151739151740151741151742151743151744151745151746151747151748151749151750151751151752151753151754151755151756151757151758151759151760151761151762151763151764151765151766151767151768151769151770151771151772151773151774151775151776151777151778151779151780151781151782151783151784151785151786151787151788151789151790151791151792151793151794151795151796151797151798151799151800151801151802151803151804151805151806151807151808151809151810151811151812151813151814151815151816151817151818151819151820151821151822151823151824151825151826151827151828151829151830151831151832151833151834151835151836151837151838151839151840151841151842151843151844151845151846151847151848151849151850151851151852151853151854151855151856151857151858151859151860151861151862151863151864151865151866151867151868151869151870151871151872151873151874151875151876151877151878151879151880151881151882151883151884151885151886151887151888151889151890151891151892151893151894151895151896151897151898151899151900151901151902151903151904151905151906151907151908151909151910151911151912151913151914151915151916151917151918151919151920151921151922151923151924151925151926151927151928151929151930151931151932151933151934151935151936151937151938151939151940151941151942151943151944151945151946151947151948151949151950151951151952151953151954151955151956151957151958151959151960151961151962151963151964151965151966151967151968151969151970151971151972151973151974151975151976151977151978151979151980151981151982151983151984151985151986151987151988151989151990151991151992151993151994151995151996151997151998151999152000152001152002152003152004152005152006152007152008152009152010152011152012152013152014152015152016152017152018152019152020152021152022152023152024152025152026152027152028152029152030152031152032152033152034152035152036152037152038152039152040152041152042152043152044152045152046152047152048152049152050152051152052152053152054152055152056152057152058152059152060152061152062152063152064152065152066152067152068152069152070152071152072152073152074152075152076152077152078152079152080152081152082152083152084152085152086152087152088152089152090152091152092152093152094152095152096152097152098152099152100152101152102152103152104152105152106152107152108152109152110152111152112152113152114152115152116152117152118152119152120152121152122152123152124152125152126152127152128152129152130152131152132152133152134152135152136152137152138152139152140152141152142152143152144152145152146152147152148152149152150152151152152152153152154152155152156152157152158152159152160152161152162152163152164152165152166152167152168152169152170152171152172152173152174152175152176152177152178152179152180152181152182152183152184152185152186152187152188152189152190152191152192152193152194152195152196152197152198152199152200152201152202152203152204152205152206152207152208152209152210152211152212152213152214152215152216152217152218152219152220152221152222152223152224152225152226152227152228152229152230152231152232152233152234152235152236152237152238152239152240152241152242152243152244152245152246152247152248152249152250152251152252152253152254152255152256152257152258152259152260152261152262152263152264152265152266152267152268152269152270152271152272152273152274152275152276152277152278152279152280152281152282152283152284152285152286152287152288152289152290152291152292152293152294152295152296152297152298152299152300152301152302152303152304152305152306152307152308152309152310152311152312152313152314152315152316152317152318152319152320152321152322152323152324152325152326152327152328152329152330152331152332152333152334152335152336152337152338152339152340152341152342152343152344152345152346152347152348152349152350152351152352152353152354152355152356152357152358152359152360152361152362152363152364152365152366152367152368152369152370152371152372152373152374152375152376152377152378152379152380152381152382152383152384152385152386152387152388152389152390152391152392152393152394152395152396152397152398152399152400152401152402152403152404152405152406152407152408152409152410152411152412152413152414152415152416152417152418152419152420152421152422152423152424152425152426152427152428152429152430152431152432152433152434152435152436152437152438152439152440152441152442152443152444152445152446152447152448152449152450152451152452152453152454152455152456152457152458152459152460152461152462152463152464152465152466152467152468152469152470152471152472152473152474152475152476152477152478152479152480152481152482152483152484152485152486152487152488152489152490152491152492152493152494152495152496152497152498152499152500152501152502152503152504152505152506152507152508152509152510152511152512152513152514152515152516152517152518152519152520152521152522152523152524152525152526152527152528152529152530152531152532152533152534152535152536152537152538152539152540152541152542152543152544152545152546152547152548152549152550152551152552152553152554152555152556152557152558152559152560152561152562152563152564152565152566152567152568152569152570152571152572152573152574152575152576152577152578152579152580152581152582152583152584152585152586152587152588152589152590152591152592152593152594152595152596152597152598152599152600152601152602152603152604152605152606152607152608152609152610152611152612152613152614152615152616152617152618152619152620152621152622152623152624152625152626152627152628152629152630152631152632152633152634152635152636152637152638152639152640152641152642152643152644152645152646152647152648152649152650152651152652152653152654152655152656152657152658152659152660152661152662152663152664152665152666152667152668152669152670152671152672152673152674152675152676152677152678152679152680152681152682152683152684152685152686152687152688152689152690152691152692152693152694152695152696152697152698152699152700152701152702152703152704152705152706152707152708152709152710152711152712152713152714152715152716152717152718152719152720152721152722152723152724152725152726152727152728152729152730152731152732152733152734152735152736152737152738152739152740152741152742152743152744152745152746152747152748152749152750152751152752152753152754152755152756152757152758152759152760152761152762152763152764152765152766152767152768152769152770152771152772152773152774152775152776152777152778152779152780152781152782152783152784152785152786152787152788152789152790152791152792152793152794152795152796152797152798152799152800152801152802152803152804152805152806152807152808152809152810152811152812152813152814152815152816152817152818152819152820152821152822152823152824152825152826152827152828152829152830152831152832152833152834152835152836152837152838152839152840152841152842152843152844152845152846152847152848152849152850152851152852152853152854152855152856152857152858152859152860152861152862152863152864152865152866152867152868152869152870152871152872152873152874152875152876152877152878152879152880152881152882152883152884152885152886152887152888152889152890152891152892152893152894152895152896152897152898152899152900152901152902152903152904152905152906152907152908152909152910152911152912152913152914152915152916152917152918152919152920152921152922152923152924152925152926152927152928152929152930152931152932152933152934152935152936152937152938152939152940152941152942152943152944152945152946152947152948152949152950152951152952152953152954152955152956152957152958152959152960152961152962152963152964152965152966152967152968152969152970152971152972152973152974152975152976152977152978152979152980152981152982152983152984152985152986152987152988152989152990152991152992152993152994152995152996152997152998152999153000153001153002153003153004153005153006153007153008153009153010153011153012153013153014153015153016153017153018153019153020153021153022153023153024153025153026153027153028153029153030153031153032153033153034153035153036153037153038153039153040153041153042153043153044153045153046153047153048153049153050153051153052153053153054153055153056153057153058153059153060153061153062153063153064153065153066153067153068153069153070153071153072153073153074153075153076153077153078153079153080153081153082153083153084153085153086153087153088153089153090153091153092153093153094153095153096153097153098153099153100153101153102153103153104153105153106153107153108153109153110153111153112153113153114153115153116153117153118153119153120153121153122153123153124153125153126153127153128153129153130153131153132153133153134153135153136153137153138153139153140153141153142153143153144153145153146153147153148153149153150153151153152153153153154153155153156153157153158153159153160153161153162153163153164153165153166153167153168153169153170153171153172153173153174153175153176153177153178153179153180153181153182153183153184153185153186153187153188153189153190153191153192153193153194153195153196153197153198153199153200153201153202153203153204153205153206153207153208153209153210153211153212153213153214153215153216153217153218153219153220153221153222153223153224153225153226153227153228153229153230153231153232153233153234153235153236153237153238153239153240153241153242153243153244153245153246153247153248153249153250153251153252153253153254153255153256153257153258153259153260153261153262153263153264153265153266153267153268153269153270153271153272153273153274153275153276153277153278153279153280153281153282153283153284153285153286153287153288153289153290153291153292153293153294153295153296153297153298153299153300153301153302153303153304153305153306153307153308153309153310153311153312153313153314153315153316153317153318153319153320153321153322153323153324153325153326153327153328153329153330153331153332153333153334153335153336153337153338153339153340153341153342153343153344153345153346153347153348153349153350153351153352153353153354153355153356153357153358153359153360153361153362153363153364153365153366153367153368153369153370153371153372153373153374153375153376153377153378153379153380153381153382153383153384153385153386153387153388153389153390153391153392153393153394153395153396153397153398153399153400153401153402153403153404153405153406153407153408153409153410153411153412153413153414153415153416153417153418153419153420153421153422153423153424153425153426153427153428153429153430153431153432153433153434153435153436153437153438153439153440153441153442153443153444153445153446153447153448153449153450153451153452153453153454153455153456153457153458153459153460153461153462153463153464153465153466153467153468153469153470153471153472153473153474153475153476153477153478153479153480153481153482153483153484153485153486153487153488153489153490153491153492153493153494153495153496153497153498153499153500153501153502153503153504153505153506153507153508153509153510153511153512153513153514153515153516153517153518153519153520153521153522153523153524153525153526153527153528153529153530153531153532153533153534153535153536153537153538153539153540153541153542153543153544153545153546153547153548153549153550153551153552153553153554153555153556153557153558153559153560153561153562153563153564153565153566153567153568153569153570153571153572153573153574153575153576153577153578153579153580153581153582153583153584153585153586153587153588153589153590153591153592153593153594153595153596153597153598153599153600153601153602153603153604153605153606153607153608153609153610153611153612153613153614153615153616153617153618153619153620153621153622153623153624153625153626153627153628153629153630153631153632153633153634153635153636153637153638153639153640153641153642153643153644153645153646153647153648153649153650153651153652153653153654153655153656153657153658153659153660153661153662153663153664153665153666153667153668153669153670153671153672153673153674153675153676153677153678153679153680153681153682153683153684153685153686153687153688153689153690153691153692153693153694153695153696153697153698153699153700153701153702153703153704153705153706153707153708153709153710153711153712153713153714153715153716153717153718153719153720153721153722153723153724153725153726153727153728153729153730153731153732153733153734153735153736153737153738153739153740153741153742153743153744153745153746153747153748153749153750153751153752153753153754153755153756153757153758153759153760153761153762153763153764153765153766153767153768153769153770153771153772153773153774153775153776153777153778153779153780153781153782153783153784153785153786153787153788153789153790153791153792153793153794153795153796153797153798153799153800153801153802153803153804153805153806153807153808153809153810153811153812153813153814153815153816153817153818153819153820153821153822153823153824153825153826153827153828153829153830153831153832153833153834153835153836153837153838153839153840153841153842153843153844153845153846153847153848153849153850153851153852153853153854153855153856153857153858153859153860153861153862153863153864153865153866153867153868153869153870153871153872153873153874153875153876153877153878153879153880153881153882153883153884153885153886153887153888153889153890153891153892153893153894153895153896153897153898153899153900153901153902153903153904153905153906153907153908153909153910153911153912153913153914153915153916153917153918153919153920153921153922153923153924153925153926153927153928153929153930153931153932153933153934153935153936153937153938153939153940153941153942153943153944153945153946153947153948153949153950153951153952153953153954153955153956153957153958153959153960153961153962153963153964153965153966153967153968153969153970153971153972153973153974153975153976153977153978153979153980153981153982153983153984153985153986153987153988153989153990153991153992153993153994153995153996153997153998153999154000154001154002154003154004154005154006154007154008154009154010154011154012154013154014154015154016154017154018154019154020154021154022154023154024154025154026154027154028154029154030154031154032154033154034154035154036154037154038154039154040154041154042154043154044154045154046154047154048154049154050154051154052154053154054154055154056154057154058154059154060154061154062154063154064154065154066154067154068154069154070154071154072154073154074154075154076154077154078154079154080154081154082154083154084154085154086154087154088154089154090154091154092154093154094154095154096154097154098154099154100154101154102154103154104154105154106154107154108154109154110154111154112154113154114154115154116154117154118154119154120154121154122154123154124154125154126154127154128154129154130154131154132154133154134154135154136154137154138154139154140154141154142154143154144154145154146154147154148154149154150154151154152154153154154154155154156154157154158154159154160154161154162154163154164154165154166154167154168154169154170154171154172154173154174154175154176154177154178154179154180154181154182154183154184154185154186154187154188154189154190154191154192154193154194154195154196154197154198154199154200154201154202154203154204154205154206154207154208154209154210154211154212154213154214154215154216154217154218154219154220154221154222154223154224154225154226154227154228154229154230154231154232154233154234154235154236154237154238154239154240154241154242154243154244154245154246154247154248154249154250154251154252154253154254154255154256154257154258154259154260154261154262154263154264154265154266154267154268154269154270154271154272154273154274154275154276154277154278154279154280154281154282154283154284154285154286154287154288154289154290154291154292154293154294154295154296154297154298154299154300154301154302154303154304154305154306154307154308154309154310154311154312154313154314154315154316154317154318154319154320154321154322154323154324154325154326154327154328154329154330154331154332154333154334154335154336154337154338154339154340154341154342154343154344154345154346154347154348154349154350154351154352154353154354154355154356154357154358154359154360154361154362154363154364154365154366154367154368154369154370154371154372154373154374154375154376154377154378154379154380154381154382154383154384154385154386154387154388154389154390154391154392154393154394154395154396154397154398154399154400154401154402154403154404154405154406154407154408154409154410154411154412154413154414154415154416154417154418154419154420154421154422154423154424154425154426154427154428154429154430154431154432154433154434154435154436154437154438154439154440154441154442154443154444154445154446154447154448154449154450154451154452154453154454154455154456154457154458154459154460154461154462154463154464154465154466154467154468154469154470154471154472154473154474154475154476154477154478154479154480154481154482154483154484154485154486154487154488154489154490154491154492154493154494154495154496154497154498154499154500154501154502154503154504154505154506154507154508154509154510154511154512154513154514154515154516154517154518154519154520154521154522154523154524154525154526154527154528154529154530154531154532154533154534154535154536154537154538154539154540154541154542154543154544154545154546154547154548154549154550154551154552154553154554154555154556154557154558154559154560154561154562154563154564154565154566154567154568154569154570154571154572154573154574154575154576154577154578154579154580154581154582154583154584154585154586154587154588154589154590154591154592154593154594154595154596154597154598154599154600154601154602154603154604154605154606154607154608154609154610154611154612154613154614154615154616154617154618154619154620154621154622154623154624154625154626154627154628154629154630154631154632154633154634154635154636154637154638154639154640154641154642154643154644154645154646154647154648154649154650154651154652154653154654154655154656154657154658154659154660154661154662154663154664154665154666154667154668154669154670154671154672154673154674154675154676154677154678154679154680154681154682154683154684154685154686154687154688154689154690154691154692154693154694154695154696154697154698154699154700154701154702154703154704154705154706154707154708154709154710154711154712154713154714154715154716154717154718154719154720154721154722154723154724154725154726154727154728154729154730154731154732154733154734154735154736154737154738154739154740154741154742154743154744154745154746154747154748154749154750154751154752154753154754154755154756154757154758154759154760154761154762154763154764154765154766154767154768154769154770154771154772154773154774154775154776154777154778154779154780154781154782154783154784154785154786154787154788154789154790154791154792154793154794154795154796154797154798154799154800154801154802154803154804154805154806154807154808154809154810154811154812154813154814154815154816154817154818154819154820154821154822154823154824154825154826154827154828154829154830154831154832154833154834154835154836154837154838154839154840154841154842154843154844154845154846154847154848154849154850154851154852154853154854154855154856154857154858154859154860154861154862154863154864154865154866154867154868154869154870154871154872154873154874154875154876154877154878154879154880154881154882154883154884154885154886154887154888154889154890154891154892154893154894154895154896154897154898154899154900154901154902154903154904154905154906154907154908154909154910154911154912154913154914154915154916154917154918154919154920154921154922154923154924154925154926154927154928154929154930154931154932154933154934154935154936154937154938154939154940154941154942154943154944154945154946154947154948154949154950154951154952154953154954154955154956154957154958154959154960154961154962154963154964154965154966154967154968154969154970154971154972154973154974154975154976154977154978154979154980154981154982154983154984154985154986154987154988154989154990154991154992154993154994154995154996154997154998154999155000155001155002155003155004155005155006155007155008155009155010155011155012155013155014155015155016155017155018155019155020155021155022155023155024155025155026155027155028155029155030155031155032155033155034155035155036155037155038155039155040155041155042155043155044155045155046155047155048155049155050155051155052155053155054155055155056155057155058155059155060155061155062155063155064155065155066155067155068155069155070155071155072155073155074155075155076155077155078155079155080155081155082155083155084155085155086155087155088155089155090155091155092155093155094155095155096155097155098155099155100155101155102155103155104155105155106155107155108155109155110155111155112155113155114155115155116155117155118155119155120155121155122155123155124155125155126155127155128155129155130155131155132155133155134155135155136155137155138155139155140155141155142155143155144155145155146155147155148155149155150155151155152155153155154155155155156155157155158155159155160155161155162155163155164155165155166155167155168155169155170155171155172155173155174155175155176155177155178155179155180155181155182155183155184155185155186155187155188155189155190155191155192155193155194155195155196155197155198155199155200155201155202155203155204155205155206155207155208155209155210155211155212155213155214155215155216155217155218155219155220155221155222155223155224155225155226155227155228155229155230155231155232155233155234155235155236155237155238155239155240155241155242155243155244155245155246155247155248155249155250155251155252155253155254155255155256155257155258155259155260155261155262155263155264155265155266155267155268155269155270155271155272155273155274155275155276155277155278155279155280155281155282155283155284155285155286155287155288155289155290155291155292155293155294155295155296155297155298155299155300155301155302155303155304155305155306155307155308155309155310155311155312155313155314155315155316155317155318155319155320155321155322155323155324155325155326155327155328155329155330155331155332155333155334155335155336155337155338155339155340155341155342155343155344155345155346155347155348155349155350155351155352155353155354155355155356155357155358155359155360155361155362155363155364155365155366155367155368155369155370155371155372155373155374155375155376155377155378155379155380155381155382155383155384155385155386155387155388155389155390155391155392155393155394155395155396155397155398155399155400155401155402155403155404155405155406155407155408155409155410155411155412155413155414155415155416155417155418155419155420155421155422155423155424155425155426155427155428155429155430155431155432155433155434155435155436155437155438155439155440155441155442155443155444155445155446155447155448155449155450155451155452155453155454155455155456155457155458155459155460155461155462155463155464155465155466155467155468155469155470155471155472155473155474155475155476155477155478155479155480155481155482155483155484155485155486155487155488155489155490155491155492155493155494155495155496155497155498155499155500155501155502155503155504155505155506155507155508155509155510155511155512155513155514155515155516155517155518155519155520155521155522155523155524155525155526155527155528155529155530155531155532155533155534155535155536155537155538155539155540155541155542155543155544155545155546155547155548155549155550155551155552155553155554155555155556155557155558155559155560155561155562155563155564155565155566155567155568155569155570155571155572155573155574155575155576155577155578155579155580155581155582155583155584155585155586155587155588155589155590155591155592155593155594155595155596155597155598155599155600155601155602155603155604155605155606155607155608155609155610155611155612155613155614155615155616155617155618155619155620155621155622155623155624155625155626155627155628155629155630155631155632155633155634155635155636155637155638155639155640155641155642155643155644155645155646155647155648155649155650155651155652155653155654155655155656155657155658155659155660155661155662155663155664155665155666155667155668155669155670155671155672155673155674155675155676155677155678155679155680155681155682155683155684155685155686155687155688155689155690155691155692155693155694155695155696155697155698155699155700155701155702155703155704155705155706155707155708155709155710155711155712155713155714155715155716155717155718155719155720155721155722155723155724155725155726155727155728155729155730155731155732155733155734155735155736155737155738155739155740155741155742155743155744155745155746155747155748155749155750155751155752155753155754155755155756155757155758155759155760155761155762155763155764155765155766155767155768155769155770155771155772155773155774155775155776155777155778155779155780155781155782155783155784155785155786155787155788155789155790155791155792155793155794155795155796155797155798155799155800155801155802155803155804155805155806155807155808155809155810155811155812155813155814155815155816155817155818155819155820155821155822155823155824155825155826155827155828155829155830155831155832155833155834155835155836155837155838155839155840155841155842155843155844155845155846155847155848155849155850155851155852155853155854155855155856155857155858155859155860155861155862155863155864155865155866155867155868155869155870155871155872155873155874155875155876155877155878155879155880155881155882155883155884155885155886155887155888155889155890155891155892155893155894155895155896155897155898155899155900155901155902155903155904155905155906155907155908155909155910155911155912155913155914155915155916155917155918155919155920155921155922155923155924155925155926155927155928155929155930155931155932155933155934155935155936155937155938155939155940155941155942155943155944155945155946155947155948155949155950155951155952155953155954155955155956155957155958155959155960155961155962155963155964155965155966155967155968155969155970155971155972155973155974155975155976155977155978155979155980155981155982155983155984155985155986155987155988155989155990155991155992155993155994155995155996155997155998155999156000156001156002156003156004156005156006156007156008156009156010156011156012156013156014156015156016156017156018156019156020156021156022156023156024156025156026156027156028156029156030156031156032156033156034156035156036156037156038156039156040156041156042156043156044156045156046156047156048156049156050156051156052156053156054156055156056156057156058156059156060156061156062156063156064156065156066156067156068156069156070156071156072156073156074156075156076156077156078156079156080156081156082156083156084156085156086156087156088156089156090156091156092156093156094156095156096156097156098156099156100156101156102156103156104156105156106156107156108156109156110156111156112156113156114156115156116156117156118156119156120156121156122156123156124156125156126156127156128156129156130156131156132156133156134156135156136156137156138156139156140156141156142156143156144156145156146156147156148156149156150156151156152156153156154156155156156156157156158156159156160156161156162156163156164156165156166156167156168156169156170156171156172156173156174156175156176156177156178156179156180156181156182156183156184156185156186156187156188156189156190156191156192156193156194156195156196156197156198156199156200156201156202156203156204156205156206156207156208156209156210156211156212156213156214156215156216156217156218156219156220156221156222156223156224156225156226156227156228156229156230156231156232156233156234156235156236156237156238156239156240156241156242156243156244156245156246156247156248156249156250156251156252156253156254156255156256156257156258156259156260156261156262156263156264156265156266156267156268156269156270156271156272156273156274156275156276156277156278156279156280156281156282156283156284156285156286156287156288156289156290156291156292156293156294156295156296156297156298156299156300156301156302156303156304156305156306156307156308156309156310156311156312156313156314156315156316156317156318156319156320156321156322156323156324156325156326156327156328156329156330156331156332156333156334156335156336156337156338156339156340156341156342156343156344156345156346156347156348156349156350156351156352156353156354156355156356156357156358156359156360156361156362156363156364156365156366156367156368156369156370156371156372156373156374156375156376156377156378156379156380156381156382156383156384156385156386156387156388156389156390156391156392156393156394156395156396156397156398156399156400156401156402156403156404156405156406156407156408156409156410156411156412156413156414156415156416156417156418156419156420156421156422156423156424156425156426156427156428156429156430156431156432156433156434156435156436156437156438156439156440156441156442156443156444156445156446156447156448156449156450156451156452156453156454156455156456156457156458156459156460156461156462156463156464156465156466156467156468156469156470156471156472156473156474156475156476156477156478156479156480156481156482156483156484156485156486156487156488156489156490156491156492156493156494156495156496156497156498156499156500156501156502156503156504156505156506156507156508156509156510156511156512156513156514156515156516156517156518156519156520156521156522156523156524156525156526156527156528156529156530156531156532156533156534156535156536156537156538156539156540156541156542156543156544156545156546156547156548156549156550156551156552156553156554156555156556156557156558156559156560156561156562156563156564156565156566156567156568156569156570156571156572156573156574156575156576156577156578156579156580156581156582156583156584156585156586156587156588156589156590156591156592156593156594156595156596156597156598156599156600156601156602156603156604156605156606156607156608156609156610156611156612156613156614156615156616156617156618156619156620156621156622156623156624156625156626156627156628156629156630156631156632156633156634156635156636156637156638156639156640156641156642156643156644156645156646156647156648156649156650156651156652156653156654156655156656156657156658156659156660156661156662156663156664156665156666156667156668156669156670156671156672156673156674156675156676156677156678156679156680156681156682156683156684156685156686156687156688156689156690156691156692156693156694156695156696156697156698156699156700156701156702156703156704156705156706156707156708156709156710156711156712156713156714156715156716156717156718156719156720156721156722156723156724156725156726156727156728156729156730156731156732156733156734156735156736156737156738156739156740156741156742156743156744156745156746156747156748156749156750156751156752156753156754156755156756156757156758156759156760156761156762156763156764156765156766156767156768156769156770156771156772156773156774156775156776156777156778156779156780156781156782156783156784156785156786156787156788156789156790156791156792156793156794156795156796156797156798156799156800156801156802156803156804156805156806156807156808156809156810156811156812156813156814156815156816156817156818156819156820156821156822156823156824156825156826156827156828156829156830156831156832156833156834156835156836156837156838156839156840156841156842156843156844156845156846156847156848156849156850156851156852156853156854156855156856156857156858156859156860156861156862156863156864156865156866156867156868156869156870156871156872156873156874156875156876156877156878156879156880156881156882156883156884156885156886156887156888156889156890156891156892156893156894156895156896156897156898156899156900156901156902156903156904156905156906156907156908156909156910156911156912156913156914156915156916156917156918156919156920156921156922156923156924156925156926156927156928156929156930156931156932156933156934156935156936156937156938156939156940156941156942156943156944156945156946156947156948156949156950156951156952156953156954156955156956156957156958156959156960156961156962156963156964156965156966156967156968156969156970156971156972156973156974156975156976156977156978156979156980156981156982156983156984156985156986156987156988156989156990156991156992156993156994156995156996156997156998156999157000157001157002157003157004157005157006157007157008157009157010157011157012157013157014157015157016157017157018157019157020157021157022157023157024157025157026157027157028157029157030157031157032157033157034157035157036157037157038157039157040157041157042157043157044157045157046157047157048157049157050157051157052157053157054157055157056157057157058157059157060157061157062157063157064157065157066157067157068157069157070157071157072157073157074157075157076157077157078157079157080157081157082157083157084157085157086157087157088157089157090157091157092157093157094157095157096157097157098157099157100157101157102157103157104157105157106157107157108157109157110157111157112157113157114157115157116157117157118157119157120157121157122157123157124157125157126157127157128157129157130157131157132157133157134157135157136157137157138157139157140157141157142157143157144157145157146157147157148157149157150157151157152157153157154157155157156157157157158157159157160157161157162157163157164157165157166157167157168157169157170157171157172157173157174157175157176157177157178157179157180157181157182157183157184157185157186157187157188157189157190157191157192157193157194157195157196157197157198157199157200157201157202157203157204157205157206157207157208157209157210157211157212157213157214157215157216157217157218157219157220157221157222157223157224157225157226157227157228157229157230157231157232157233157234157235157236157237157238157239157240157241157242157243157244157245157246157247157248157249157250157251157252157253157254157255157256157257157258157259157260157261157262157263157264157265157266157267157268157269157270157271157272157273157274157275157276157277157278157279157280157281157282157283157284157285157286157287157288157289157290157291157292157293157294157295157296157297157298157299157300157301157302157303157304157305157306157307157308157309157310157311157312157313157314157315157316157317157318157319157320157321157322157323157324157325157326157327157328157329157330157331157332157333157334157335157336157337157338157339157340157341157342157343157344157345157346157347157348157349157350157351157352157353157354157355157356157357157358157359157360157361157362157363157364157365157366157367157368157369157370157371157372157373157374157375157376157377157378157379157380157381157382157383157384157385157386157387157388157389157390157391157392157393157394157395157396157397157398157399157400157401157402157403157404157405157406157407157408157409157410157411157412157413157414157415157416157417157418157419157420157421157422157423157424157425157426157427157428157429157430157431157432157433157434157435157436157437157438157439157440157441157442157443157444157445157446157447157448157449157450157451157452157453157454157455157456157457157458157459157460157461157462157463157464157465157466157467157468157469157470157471157472157473157474157475157476157477157478157479157480157481157482157483157484157485157486157487157488157489157490157491157492157493157494157495157496157497157498157499157500157501157502157503157504157505157506157507157508157509157510157511157512157513157514157515157516157517157518157519157520157521157522157523157524157525157526157527157528157529157530157531157532157533157534157535157536157537157538157539157540157541157542157543157544157545157546157547157548157549157550157551157552157553157554157555157556157557157558157559157560157561157562157563157564157565157566157567157568157569157570157571157572157573157574157575157576157577157578157579157580157581157582157583157584157585157586157587157588157589157590157591157592157593157594157595157596157597157598157599157600157601157602157603157604157605157606157607157608157609157610157611157612157613157614157615157616157617157618157619157620157621157622157623157624157625157626157627157628157629157630157631157632157633157634157635157636157637157638157639157640157641157642157643157644157645157646157647157648157649157650157651157652157653157654157655157656157657157658157659157660157661157662157663157664157665157666157667157668157669157670157671157672157673157674157675157676157677157678157679157680157681157682157683157684157685157686157687157688157689157690157691157692157693157694157695157696157697157698157699157700157701157702157703157704157705157706157707157708157709157710157711157712157713157714157715157716157717157718157719157720157721157722157723157724157725157726157727157728157729157730157731157732157733157734157735157736157737157738157739157740157741157742157743157744157745157746157747157748157749157750157751157752157753157754157755157756157757157758157759157760157761157762157763157764157765157766157767157768157769157770157771157772157773157774157775157776157777157778157779157780157781157782157783157784157785157786157787157788157789157790157791157792157793157794157795157796157797157798157799157800157801157802157803157804157805157806157807157808157809157810157811157812157813157814157815157816157817157818157819157820157821157822157823157824157825157826157827157828157829157830157831157832157833157834157835157836157837157838157839157840157841157842157843157844157845157846157847157848157849157850157851157852157853157854157855157856157857157858157859157860157861157862157863157864157865157866157867157868157869157870157871157872157873157874157875157876157877157878157879157880157881157882157883157884157885157886157887157888157889157890157891157892157893157894157895157896157897157898157899157900157901157902157903157904157905157906157907157908157909157910157911157912157913157914157915157916157917157918157919157920157921157922157923157924157925157926157927157928157929157930157931157932157933157934157935157936157937157938157939157940157941157942157943157944157945157946157947157948157949157950157951157952157953157954157955157956157957157958157959157960157961157962157963157964157965157966157967157968157969157970157971157972157973157974157975157976157977157978157979157980157981157982157983157984157985157986157987157988157989157990157991157992157993157994157995157996157997157998157999158000158001158002158003158004158005158006158007158008158009158010158011158012158013158014158015158016158017158018158019158020158021158022158023158024158025158026158027158028158029158030158031158032158033158034158035158036158037158038158039158040158041158042158043158044158045158046158047158048158049158050158051158052158053158054158055158056158057158058158059158060158061158062158063158064158065158066158067158068158069158070158071158072158073158074158075158076158077158078158079158080158081158082158083158084158085158086158087158088158089158090158091158092158093158094158095158096158097158098158099158100158101158102158103158104158105158106158107158108158109158110158111158112158113158114158115158116158117158118158119158120158121158122158123158124158125158126158127158128158129158130158131158132158133158134158135158136158137158138158139158140158141158142158143158144158145158146158147158148158149158150158151158152158153158154158155158156158157158158158159158160158161158162158163158164158165158166158167158168158169158170158171158172158173158174158175158176158177158178158179158180158181158182158183158184158185158186158187158188158189158190158191158192158193158194158195158196158197158198158199158200158201158202158203158204158205158206158207158208158209158210158211158212158213158214158215158216158217158218158219158220158221158222158223158224158225158226158227158228158229158230158231158232158233158234158235158236158237158238158239158240158241158242158243158244158245158246158247158248158249158250158251158252158253158254158255158256158257158258158259158260158261158262158263158264158265158266158267158268158269158270158271158272158273158274158275158276158277158278158279158280158281158282158283158284158285158286158287158288158289158290158291158292158293158294158295158296158297158298158299158300158301158302158303158304158305158306158307158308158309158310158311158312158313158314158315158316158317158318158319158320158321158322158323158324158325158326158327158328158329158330158331158332158333158334158335158336158337158338158339158340158341158342158343158344158345158346158347158348158349158350158351158352158353158354158355158356158357158358158359158360158361158362158363158364158365158366158367158368158369158370158371158372158373158374158375158376158377158378158379158380158381158382158383158384158385158386158387158388158389158390158391158392158393158394158395158396158397158398158399158400158401158402158403158404158405158406158407158408158409158410158411158412158413158414158415158416158417158418158419158420158421158422158423158424158425158426158427158428158429158430158431158432158433158434158435158436158437158438158439158440158441158442158443158444158445158446158447158448158449158450158451158452158453158454158455158456158457158458158459158460158461158462158463158464158465158466158467158468158469158470158471158472158473158474158475158476158477158478158479158480158481158482158483158484158485158486158487158488158489158490158491158492158493158494158495158496158497158498158499158500158501158502158503158504158505158506158507158508158509158510158511158512158513158514158515158516158517158518158519158520158521158522158523158524158525158526158527158528158529158530158531158532158533158534158535158536158537158538158539158540158541158542158543158544158545158546158547158548158549158550158551158552158553158554158555158556158557158558158559158560158561158562158563158564158565158566158567158568158569158570158571158572158573158574158575158576158577158578158579158580158581158582158583158584158585158586158587158588158589158590158591158592158593158594158595158596158597158598158599158600158601158602158603158604158605158606158607158608158609158610158611158612158613158614158615158616158617158618158619158620158621158622158623158624158625158626158627158628158629158630158631158632158633158634158635158636158637158638158639158640158641158642158643158644158645158646158647158648158649158650158651158652158653158654158655158656158657158658158659158660158661158662158663158664158665158666158667158668158669158670158671158672158673158674158675158676158677158678158679158680158681158682158683158684158685158686158687158688158689158690158691158692158693158694158695158696158697158698158699158700158701158702158703158704158705158706158707158708158709158710158711158712158713158714158715158716158717158718158719158720158721158722158723158724158725158726158727158728158729158730158731158732158733158734158735158736158737158738158739158740158741158742158743158744158745158746158747158748158749158750158751158752158753158754158755158756158757158758158759158760158761158762158763158764158765158766158767158768158769158770158771158772158773158774158775158776158777158778158779158780158781158782158783158784158785158786158787158788158789158790158791158792158793158794158795158796158797158798158799158800158801158802158803158804158805158806158807158808158809158810158811158812158813158814158815158816158817158818158819158820158821158822158823158824158825158826158827158828158829158830158831158832158833158834158835158836158837158838158839158840158841158842158843158844158845158846158847158848158849158850158851158852158853158854158855158856158857158858158859158860158861158862158863158864158865158866158867158868158869158870158871158872158873158874158875158876158877158878158879158880158881158882158883158884158885158886158887158888158889158890158891158892158893158894158895158896158897158898158899158900158901158902158903158904158905158906158907158908158909158910158911158912158913158914158915158916158917158918158919158920158921158922158923158924158925158926158927158928158929158930158931158932158933158934158935158936158937158938158939158940158941158942158943158944158945158946158947158948158949158950158951158952158953158954158955158956158957158958158959158960158961158962158963158964158965158966158967158968158969158970158971158972158973158974158975158976158977158978158979158980158981158982158983158984158985158986158987158988158989158990158991158992158993158994158995158996158997158998158999159000159001159002159003159004159005159006159007159008159009159010159011159012159013159014159015159016159017159018159019159020159021159022159023159024159025159026159027159028159029159030159031159032159033159034159035159036159037159038159039159040159041159042159043159044159045159046159047159048159049159050159051159052159053159054159055159056159057159058159059159060159061159062159063159064159065159066159067159068159069159070159071159072159073159074159075159076159077159078159079159080159081159082159083159084159085159086159087159088159089159090159091159092159093159094159095159096159097159098159099159100159101159102159103159104159105159106159107159108159109159110159111159112159113159114159115159116159117159118159119159120159121159122159123159124159125159126159127159128159129159130159131159132159133159134159135159136159137159138159139159140159141159142159143159144159145159146159147159148159149159150159151159152159153159154159155159156159157159158159159159160159161159162159163159164159165159166159167159168159169159170159171159172159173159174159175159176159177159178159179159180159181159182159183159184159185159186159187159188159189159190159191159192159193159194159195159196159197159198159199159200159201159202159203159204159205159206159207159208159209159210159211159212159213159214159215159216159217159218159219159220159221159222159223159224159225159226159227159228159229159230159231159232159233159234159235159236159237159238159239159240159241159242159243159244159245159246159247159248159249159250159251159252159253159254159255159256159257159258159259159260159261159262159263159264159265159266159267159268159269159270159271159272159273159274159275159276159277159278159279159280159281159282159283159284159285159286159287159288159289159290159291159292159293159294159295159296159297159298159299159300159301159302159303159304159305159306159307159308159309159310159311159312159313159314159315159316159317159318159319159320159321159322159323159324159325159326159327159328159329159330159331159332159333159334159335159336159337159338159339159340159341159342159343159344159345159346159347159348159349159350159351159352159353159354159355159356159357159358159359159360159361159362159363159364159365159366159367159368159369159370159371159372159373159374159375159376159377159378159379159380159381159382159383159384159385159386159387159388159389159390159391159392159393159394159395159396159397159398159399159400159401159402159403159404159405159406159407159408159409159410159411159412159413159414159415159416159417159418159419159420159421159422159423159424159425159426159427159428159429159430159431159432159433159434159435159436159437159438159439159440159441159442159443159444159445159446159447159448159449159450159451159452159453159454159455159456159457159458159459159460159461159462159463159464159465159466159467159468159469159470159471159472159473159474159475159476159477159478159479159480159481159482159483159484159485159486159487159488159489159490159491159492159493159494159495159496159497159498159499159500159501159502159503159504159505159506159507159508159509159510159511159512159513159514159515159516159517159518159519159520159521159522159523159524159525159526159527159528159529159530159531159532159533159534159535159536159537159538159539159540159541159542159543159544159545159546159547159548159549159550159551159552159553159554159555159556159557159558159559159560159561159562159563159564159565159566159567159568159569159570159571159572159573159574159575159576159577159578159579159580159581159582159583159584159585159586159587159588159589159590159591159592159593159594159595159596159597159598159599159600159601159602159603159604159605159606159607159608159609159610159611159612159613159614159615159616159617159618159619159620159621159622159623159624159625159626159627159628159629159630159631159632159633159634159635159636159637159638159639159640159641159642159643159644159645159646159647159648159649159650159651159652159653159654159655159656159657159658159659159660159661159662159663159664159665159666159667159668159669159670159671159672159673159674159675159676159677159678159679159680159681159682159683159684159685159686159687159688159689159690159691159692159693159694159695159696159697159698159699159700159701159702159703159704159705159706159707159708159709159710159711159712159713159714159715159716159717159718159719159720159721159722159723159724159725159726159727159728159729159730159731159732159733159734159735159736159737159738159739159740159741159742159743159744159745159746159747159748159749159750159751159752159753159754159755159756159757159758159759159760159761159762159763159764159765159766159767159768159769159770159771159772159773159774159775159776159777159778159779159780159781159782159783159784159785159786159787159788159789159790159791159792159793159794159795159796159797159798159799159800159801159802159803159804159805159806159807159808159809159810159811159812159813159814159815159816159817159818159819159820159821159822159823159824159825159826159827159828159829159830159831159832159833159834159835159836159837159838159839159840159841159842159843159844159845159846159847159848159849159850159851159852159853159854159855159856159857159858159859159860159861159862159863159864159865159866159867159868159869159870159871159872159873159874159875159876159877159878159879159880159881159882159883159884159885159886159887159888159889159890159891159892159893159894159895159896159897159898159899159900159901159902159903159904159905159906159907159908159909159910159911159912159913159914159915159916159917159918159919159920159921159922159923159924159925159926159927159928159929159930159931159932159933159934159935159936159937159938159939159940159941159942159943159944159945159946159947159948159949159950159951159952159953159954159955159956159957159958159959159960159961159962159963159964159965159966159967159968159969159970159971159972159973159974159975159976159977159978159979159980159981159982159983159984159985159986159987159988159989159990159991159992159993159994159995159996159997159998159999160000160001160002160003160004160005160006160007160008160009160010160011160012160013160014160015160016160017160018160019160020160021160022160023160024160025160026160027160028160029160030160031160032160033160034160035160036160037160038160039160040160041160042160043160044160045160046160047160048160049160050160051160052160053160054160055160056160057160058160059160060160061160062160063160064160065160066160067160068160069160070160071160072160073160074160075160076160077160078160079160080160081160082160083160084160085160086160087160088160089160090160091160092160093160094160095160096160097160098160099160100160101160102160103160104160105160106160107160108160109160110160111160112160113160114160115160116160117160118160119160120160121160122160123160124160125160126160127160128160129160130160131160132160133160134160135160136160137160138160139160140160141160142160143160144160145160146160147160148160149160150160151160152160153160154160155160156160157160158160159160160160161160162160163160164160165160166160167160168160169160170160171160172160173160174160175160176160177160178160179160180160181160182160183160184160185160186160187160188160189160190160191160192160193160194160195160196160197160198160199160200160201160202160203160204160205160206160207160208160209160210160211160212160213160214160215160216160217160218160219160220160221160222160223160224160225160226160227160228160229160230160231160232160233160234160235160236160237160238160239160240160241160242160243160244160245160246160247160248160249160250160251160252160253160254160255160256160257160258160259160260160261160262160263160264160265160266160267160268160269160270160271160272160273160274160275160276160277160278160279160280160281160282160283160284160285160286160287160288160289160290160291160292160293160294160295160296160297160298160299160300160301160302160303160304160305160306160307160308160309160310160311160312160313160314160315160316160317160318160319160320160321160322160323160324160325160326160327160328160329160330160331160332160333160334160335160336160337160338160339160340160341160342160343160344160345160346160347160348160349160350160351160352160353160354160355160356160357160358160359160360160361160362160363160364160365160366160367160368160369160370160371160372160373160374160375160376160377160378160379160380160381160382160383160384160385160386160387160388160389160390160391160392160393160394160395160396160397160398160399160400160401160402160403160404160405160406160407160408160409160410160411160412160413160414160415160416160417160418160419160420160421160422160423160424160425160426160427160428160429160430160431160432160433160434160435160436160437160438160439160440160441160442160443160444160445160446160447160448160449160450160451160452160453160454160455160456160457160458160459160460160461160462160463160464160465160466160467160468160469160470160471160472160473160474160475160476160477160478160479160480160481160482160483160484160485160486160487160488160489160490160491160492160493160494160495160496160497160498160499160500160501160502160503160504160505160506160507160508160509160510160511160512160513160514160515160516160517160518160519160520160521160522160523160524160525160526160527160528160529160530160531160532160533160534160535160536160537160538160539160540160541160542160543160544160545160546160547160548160549160550160551160552160553160554160555160556160557160558160559160560160561160562160563160564160565160566160567160568160569160570160571160572160573160574160575160576160577160578160579160580160581160582160583160584160585160586160587160588160589160590160591160592160593160594160595160596160597160598160599160600160601160602160603160604160605160606160607160608160609160610160611160612160613160614160615160616160617160618160619160620160621160622160623160624160625160626160627160628160629160630160631160632160633160634160635160636160637160638160639160640160641160642160643160644160645160646160647160648160649160650160651160652160653160654160655160656160657160658160659160660160661160662160663160664160665160666160667160668160669160670160671160672160673160674160675160676160677160678160679160680160681160682160683160684160685160686160687160688160689160690160691160692160693160694160695160696160697160698160699160700160701160702160703160704160705160706160707160708160709160710160711160712160713160714160715160716160717160718160719160720160721160722160723160724160725160726160727160728160729160730160731160732160733160734160735160736160737160738160739160740160741160742160743160744160745160746160747160748160749160750160751160752160753160754160755160756160757160758160759160760160761160762160763160764160765160766160767160768160769160770160771160772160773160774160775160776160777160778160779160780160781160782160783160784160785160786160787160788160789160790160791160792160793160794160795160796160797160798160799160800160801160802160803160804160805160806160807160808160809160810160811160812160813160814160815160816160817160818160819160820160821160822160823160824160825160826160827160828160829160830160831160832160833160834160835160836160837160838160839160840160841160842160843160844160845160846160847160848160849160850160851160852160853160854160855160856160857160858160859160860160861160862160863160864160865160866160867160868160869160870160871160872160873160874160875160876160877160878160879160880160881160882160883160884160885160886160887160888160889160890160891160892160893160894160895160896160897160898160899160900160901160902160903160904160905160906160907160908160909160910160911160912160913160914160915160916160917160918160919160920160921160922160923160924160925160926160927160928160929160930160931160932160933160934160935160936160937160938160939160940160941160942160943160944160945160946160947160948160949160950160951160952160953160954160955160956160957160958160959160960160961160962160963160964160965160966160967160968160969160970160971160972160973160974160975160976160977160978160979160980160981160982160983160984160985160986160987160988160989160990160991160992160993160994160995160996160997160998160999161000161001161002161003161004161005161006161007161008161009161010161011161012161013161014161015161016161017161018161019161020161021161022161023161024161025161026161027161028161029161030161031161032161033161034161035161036161037161038161039161040161041161042161043161044161045161046161047161048161049161050161051161052161053161054161055161056161057161058161059161060161061161062161063161064161065161066161067161068161069161070161071161072161073161074161075161076161077161078161079161080161081161082161083161084161085161086161087161088161089161090161091161092161093161094161095161096161097161098161099161100161101161102161103161104161105161106161107161108161109161110161111161112161113161114161115161116161117161118161119161120161121161122161123161124161125161126161127161128161129161130161131161132161133161134161135161136161137161138161139161140161141161142161143161144161145161146161147161148161149161150161151161152161153161154161155161156161157161158161159161160161161161162161163161164161165161166161167161168161169161170161171161172161173161174161175161176161177161178161179161180161181161182161183161184161185161186161187161188161189161190161191161192161193161194161195161196161197161198161199161200161201161202161203161204161205161206161207161208161209161210161211161212161213161214161215161216161217161218161219161220161221161222161223161224161225161226161227161228161229161230161231161232161233161234161235161236161237161238161239161240161241161242161243161244161245161246161247161248161249161250161251161252161253161254161255161256161257161258161259161260161261161262161263161264161265161266161267161268161269161270161271161272161273161274161275161276161277161278161279161280161281161282161283161284161285161286161287161288161289161290161291161292161293161294161295161296161297161298161299161300161301161302161303161304161305161306161307161308161309161310161311161312161313161314161315161316161317161318161319161320161321161322161323161324161325161326161327161328161329161330161331161332161333161334161335161336161337161338161339161340161341161342161343161344161345161346161347161348161349161350161351161352161353161354161355161356161357161358161359161360161361161362161363161364161365161366161367161368161369161370161371161372161373161374161375161376161377161378161379161380161381161382161383161384161385161386161387161388161389161390161391161392161393161394161395161396161397161398161399161400161401161402161403161404161405161406161407161408161409161410161411161412161413161414161415161416161417161418161419161420161421161422161423161424161425161426161427161428161429161430161431161432161433161434161435161436161437161438161439161440161441161442161443161444161445161446161447161448161449161450161451161452161453161454161455161456161457161458161459161460161461161462161463161464161465161466161467161468161469161470161471161472161473161474161475161476161477161478161479161480161481161482161483161484161485161486161487161488161489161490161491161492161493161494161495161496161497161498161499161500161501161502161503161504161505161506161507161508161509161510161511161512161513161514161515161516161517161518161519161520161521161522161523161524161525161526161527161528161529161530161531161532161533161534161535161536161537161538161539161540161541161542161543161544161545161546161547161548161549161550161551161552161553161554161555161556161557161558161559161560161561161562161563161564161565161566161567161568161569161570161571161572161573161574161575161576161577161578161579161580161581161582161583161584161585161586161587161588161589161590161591161592161593161594161595161596161597161598161599161600161601161602161603161604161605161606161607161608161609161610161611161612161613161614161615161616161617161618161619161620161621161622161623161624161625161626161627161628161629161630161631161632161633161634161635161636161637161638161639161640161641161642161643161644161645161646161647161648161649161650161651161652161653161654161655161656161657161658161659161660161661161662161663161664161665161666161667161668161669161670161671161672161673161674161675161676161677161678161679161680161681161682161683161684161685161686161687161688161689161690161691161692161693161694161695161696161697161698161699161700161701161702161703161704161705161706161707161708161709161710161711161712161713161714161715161716161717161718161719161720161721161722161723161724161725161726161727161728161729161730161731161732161733161734161735161736161737161738161739161740161741161742161743161744161745161746161747161748161749161750161751161752161753161754161755161756161757161758161759161760161761161762161763161764161765161766161767161768161769161770161771161772161773161774161775161776161777161778161779161780161781161782161783161784161785161786161787161788161789161790161791161792161793161794161795161796161797161798161799161800161801161802161803161804161805161806161807161808161809161810161811161812161813161814161815161816161817161818161819161820161821161822161823161824161825161826161827161828161829161830161831161832161833161834161835161836161837161838161839161840161841161842161843161844161845161846161847161848161849161850161851161852161853161854161855161856161857161858161859161860161861161862161863161864161865161866161867161868161869161870161871161872161873161874161875161876161877161878161879161880161881161882161883161884161885161886161887161888161889161890161891161892161893161894161895161896161897161898161899161900161901161902161903161904161905161906161907161908161909161910161911161912161913161914161915161916161917161918161919161920161921161922161923161924161925161926161927161928161929161930161931161932161933161934161935161936161937161938161939161940161941161942161943161944161945161946161947161948161949161950161951161952161953161954161955161956161957161958161959161960161961161962161963161964161965161966161967161968161969161970161971161972161973161974161975161976161977161978161979161980161981161982161983161984161985161986161987161988161989161990161991161992161993161994161995161996161997161998161999162000162001162002162003162004162005162006162007162008162009162010162011162012162013162014162015162016162017162018162019162020162021162022162023162024162025162026162027162028162029162030162031162032162033162034162035162036162037162038162039162040162041162042162043162044162045162046162047162048162049162050162051162052162053162054162055162056162057162058162059162060162061162062162063162064162065162066162067162068162069162070162071162072162073162074162075162076162077162078162079162080162081162082162083162084162085162086162087162088162089162090162091162092162093162094162095162096162097162098162099162100162101162102162103162104162105162106162107162108162109162110162111162112162113162114162115162116162117162118162119162120162121162122162123162124162125162126162127162128162129162130162131162132162133162134162135162136162137162138162139162140162141162142162143162144162145162146162147162148162149162150162151162152162153162154162155162156162157162158162159162160162161162162162163162164162165162166162167162168162169162170162171162172162173162174162175162176162177162178162179162180162181162182162183162184162185162186162187162188162189162190162191162192162193162194162195162196162197162198162199162200162201162202162203162204162205162206162207162208162209162210162211162212162213162214162215162216162217162218162219162220162221162222162223162224162225162226162227162228162229162230162231162232162233162234162235162236162237162238162239162240162241162242162243162244162245162246162247162248162249162250162251162252162253162254162255162256162257162258162259162260162261162262162263162264162265162266162267162268162269162270162271162272162273162274162275162276162277162278162279162280162281162282162283162284162285162286162287162288162289162290162291162292162293162294162295162296162297162298162299162300162301162302162303162304162305162306162307162308162309162310162311162312162313162314162315162316162317162318162319162320162321162322162323162324162325162326162327162328162329162330162331162332162333162334162335162336162337162338162339162340162341162342162343162344162345162346162347162348162349162350162351162352162353162354162355162356162357162358162359162360162361162362162363162364162365162366162367162368162369162370162371162372162373162374162375162376162377162378162379162380162381162382162383162384162385162386162387162388162389162390162391162392162393162394162395162396162397162398162399162400162401162402162403162404162405162406162407162408162409162410162411162412162413162414162415162416162417162418162419162420162421162422162423162424162425162426162427162428162429162430162431162432162433162434162435162436162437162438162439162440162441162442162443162444162445162446162447162448162449162450162451162452162453162454162455162456162457162458162459162460162461162462162463162464162465162466162467162468162469162470162471162472162473162474162475162476162477162478162479162480162481162482162483162484162485162486162487162488162489162490162491162492162493162494162495162496162497162498162499162500162501162502162503162504162505162506162507162508162509162510162511162512162513162514162515162516162517162518162519162520162521162522162523162524162525162526162527162528162529162530162531162532162533162534162535162536162537162538162539162540162541162542162543162544162545162546162547162548162549162550162551162552162553162554162555162556162557162558162559162560162561162562162563162564162565162566162567162568162569162570162571162572162573162574162575162576162577162578162579162580162581162582162583162584162585162586162587162588162589162590162591162592162593162594162595162596162597162598162599162600162601162602162603162604162605162606162607162608162609162610162611162612162613162614162615162616162617162618162619162620162621162622162623162624162625162626162627162628162629162630162631162632162633162634162635162636162637162638162639162640162641162642162643162644162645162646162647162648162649162650162651162652162653162654162655162656162657162658162659162660162661162662162663162664162665162666162667162668162669162670162671162672162673162674162675162676162677162678162679162680162681162682162683162684162685162686162687162688162689162690162691162692162693162694162695162696162697162698162699162700162701162702162703162704162705162706162707162708162709162710162711162712162713162714162715162716162717162718162719162720162721162722162723162724162725162726162727162728162729162730162731162732162733162734162735162736162737162738162739162740162741162742162743162744162745162746162747162748162749162750162751162752162753162754162755162756162757162758162759162760162761162762162763162764162765162766162767162768162769162770162771162772162773162774162775162776162777162778162779162780162781162782162783162784162785162786162787162788162789162790162791162792162793162794162795162796162797162798162799162800162801162802162803162804162805162806162807162808162809162810162811162812162813162814162815162816162817162818162819162820162821162822162823162824162825162826162827162828162829162830162831162832162833162834162835162836162837162838162839162840162841162842162843162844162845162846162847162848162849162850162851162852162853162854162855162856162857162858162859162860162861162862162863162864162865162866162867162868162869162870162871162872162873162874162875162876162877162878162879162880162881162882162883162884162885162886162887162888162889162890162891162892162893162894162895162896162897162898162899162900162901162902162903162904162905162906162907162908162909162910162911162912162913162914162915162916162917162918162919162920162921162922162923162924162925162926162927162928162929162930162931162932162933162934162935162936162937162938162939162940162941162942162943162944162945162946162947162948162949162950162951162952162953162954162955162956162957162958162959162960162961162962162963162964162965162966162967162968162969162970162971162972162973162974162975162976162977162978162979162980162981162982162983162984162985162986162987162988162989162990162991162992162993162994162995162996162997162998162999163000163001163002163003163004163005163006163007163008163009163010163011163012163013163014163015163016163017163018163019163020163021163022163023163024163025163026163027163028163029163030163031163032163033163034163035163036163037163038163039163040163041163042163043163044163045163046163047163048163049163050163051163052163053163054163055163056163057163058163059163060163061163062163063163064163065163066163067163068163069163070163071163072163073163074163075163076163077163078163079163080163081163082163083163084163085163086163087163088163089163090163091163092163093163094163095163096163097163098163099163100163101163102163103163104163105163106163107163108163109163110163111163112163113163114163115163116163117163118163119163120163121163122163123163124163125163126163127163128163129163130163131163132163133163134163135163136163137163138163139163140163141163142163143163144163145163146163147163148163149163150163151163152163153163154163155163156163157163158163159163160163161163162163163163164163165163166163167163168163169163170163171163172163173163174163175163176163177163178163179163180163181163182163183163184163185163186163187163188163189163190163191163192163193163194163195163196163197163198163199163200163201163202163203163204163205163206163207163208163209163210163211163212163213163214163215163216163217163218163219163220163221163222163223163224163225163226163227163228163229163230163231163232163233163234163235163236163237163238163239163240163241163242163243163244163245163246163247163248163249163250163251163252163253163254163255163256163257163258163259163260163261163262163263163264163265163266163267163268163269163270163271163272163273163274163275163276163277163278163279163280163281163282163283163284163285163286163287163288163289163290163291163292163293163294163295163296163297163298163299163300163301163302163303163304163305163306163307163308163309163310163311163312163313163314163315163316163317163318163319163320163321163322163323163324163325163326163327163328163329163330163331163332163333163334163335163336163337163338163339163340163341163342163343163344163345163346163347163348163349163350163351163352163353163354163355163356163357163358163359163360163361163362163363163364163365163366163367163368163369163370163371163372163373163374163375163376163377163378163379163380163381163382163383163384163385163386163387163388163389163390163391163392163393163394163395163396163397163398163399163400163401163402163403163404163405163406163407163408163409163410163411163412163413163414163415163416163417163418163419163420163421163422163423163424163425163426163427163428163429163430163431163432163433163434163435163436163437163438163439163440163441163442163443163444163445163446163447163448163449163450163451163452163453163454163455163456163457163458163459163460163461163462163463163464163465163466163467163468163469163470163471163472163473163474163475163476163477163478163479163480163481163482163483163484163485163486163487163488163489163490163491163492163493163494163495163496163497163498163499163500163501163502163503163504163505163506163507163508163509163510163511163512163513163514163515163516163517163518163519163520163521163522163523163524163525163526163527163528163529163530163531163532163533163534163535163536163537163538163539163540163541163542163543163544163545163546163547163548163549163550163551163552163553163554163555163556163557163558163559163560163561163562163563163564163565163566163567163568163569163570163571163572163573163574163575163576163577163578163579163580163581163582163583163584163585163586163587163588163589163590163591163592163593163594163595163596163597163598163599163600163601163602163603163604163605163606163607163608163609163610163611163612163613163614163615163616163617163618163619163620163621163622163623163624163625163626163627163628163629163630163631163632163633163634163635163636163637163638163639163640163641163642163643163644163645163646163647163648163649163650163651163652163653163654163655163656163657163658163659163660163661163662163663163664163665163666163667163668163669163670163671163672163673163674163675163676163677163678163679163680163681163682163683163684163685163686163687163688163689163690163691163692163693163694163695163696163697163698163699163700163701163702163703163704163705163706163707163708163709163710163711163712163713163714163715163716163717163718163719163720163721163722163723163724163725163726163727163728163729163730163731163732163733163734163735163736163737163738163739163740163741163742163743163744163745163746163747163748163749163750163751163752163753163754163755163756163757163758163759163760163761163762163763163764163765163766163767163768163769163770163771163772163773163774163775163776163777163778163779163780163781163782163783163784163785163786163787163788163789163790163791163792163793163794163795163796163797163798163799163800163801163802163803163804163805163806163807163808163809163810163811163812163813163814163815163816163817163818163819163820163821163822163823163824163825163826163827163828163829163830163831163832163833163834163835163836163837163838163839163840163841163842163843163844163845163846163847163848163849163850163851163852163853163854163855163856163857163858163859163860163861163862163863163864163865163866163867163868163869163870163871163872163873163874163875163876163877163878163879163880163881163882163883163884163885163886163887163888163889163890163891163892163893163894163895163896163897163898163899163900163901163902163903163904163905163906163907163908163909163910163911163912163913163914163915163916163917163918163919163920163921163922163923163924163925163926163927163928163929163930163931163932163933163934163935163936163937163938163939163940163941163942163943163944163945163946163947163948163949163950163951163952163953163954163955163956163957163958163959163960163961163962163963163964163965163966163967163968163969163970163971163972163973163974163975163976163977163978163979163980163981163982163983163984163985163986163987163988163989163990163991163992163993163994163995163996163997163998163999164000164001164002164003164004164005164006164007164008164009164010164011164012164013164014164015164016164017164018164019164020164021164022164023164024164025164026164027164028164029164030164031164032164033164034164035164036164037164038164039164040164041164042164043164044164045164046164047164048164049164050164051164052164053164054164055164056164057164058164059164060164061164062164063164064164065164066164067164068164069164070164071164072164073164074164075164076164077164078164079164080164081164082164083164084164085164086164087164088164089164090164091164092164093164094164095164096164097164098164099164100164101164102164103164104164105164106164107164108164109164110164111164112164113164114164115164116164117164118164119164120164121164122164123164124164125164126164127164128164129164130164131164132164133164134164135164136164137164138164139164140164141164142164143164144164145164146164147164148164149164150164151164152164153164154164155164156164157164158164159164160164161164162164163164164164165164166164167164168164169164170164171164172164173164174164175164176164177164178164179164180164181164182164183164184164185164186164187164188164189164190164191164192164193164194164195164196164197164198164199164200164201164202164203164204164205164206164207164208164209164210164211164212164213164214164215164216164217164218164219164220164221164222164223164224164225164226164227164228164229164230164231164232164233164234164235164236164237164238164239164240164241164242164243164244164245164246164247164248164249164250164251164252164253164254164255164256164257164258164259164260164261164262164263164264164265164266164267164268164269164270164271164272164273164274164275164276164277164278164279164280164281164282164283164284164285164286164287164288164289164290164291164292164293164294164295164296164297164298164299164300164301164302164303164304164305164306164307164308164309164310164311164312164313164314164315164316164317164318164319164320164321164322164323164324164325164326164327164328164329164330164331164332164333164334164335164336164337164338164339164340164341164342164343164344164345164346164347164348164349164350164351164352164353164354164355164356164357164358164359164360164361164362164363164364164365164366164367164368164369164370164371164372164373164374164375164376164377164378164379164380164381164382164383164384164385164386164387164388164389164390164391164392164393164394164395164396164397164398164399164400164401164402164403164404164405164406164407164408164409164410164411164412164413164414164415164416164417164418164419164420164421164422164423164424164425164426164427164428164429164430164431164432164433164434164435164436164437164438164439164440164441164442164443164444164445164446164447164448164449164450164451164452164453164454164455164456164457164458164459164460164461164462164463164464164465164466164467164468164469164470164471164472164473164474164475164476164477164478164479164480164481164482164483164484164485164486164487164488164489164490164491164492164493164494164495164496164497164498164499164500164501164502164503164504164505164506164507164508164509164510164511164512164513164514164515164516164517164518164519164520164521164522164523164524164525164526164527164528164529164530164531164532164533164534164535164536164537164538164539164540164541164542164543164544164545164546164547164548164549164550164551164552164553164554164555164556164557164558164559164560164561164562164563164564164565164566164567164568164569164570164571164572164573164574164575164576164577164578164579164580164581164582164583164584164585164586164587164588164589164590164591164592164593164594164595164596164597164598164599164600164601164602164603164604164605164606164607164608164609164610164611164612164613164614164615164616164617164618164619164620164621164622164623164624164625164626164627164628164629164630164631164632164633164634164635164636164637164638164639164640164641164642164643164644164645164646164647164648164649164650164651164652164653164654164655164656164657164658164659164660164661164662164663164664164665164666164667164668164669164670164671164672164673164674164675164676164677164678164679164680164681164682164683164684164685164686164687164688164689164690164691164692164693164694164695164696164697164698164699164700164701164702164703164704164705164706164707164708164709164710164711164712164713164714164715164716164717164718164719164720164721164722164723164724164725164726164727164728164729164730164731164732164733164734164735164736164737164738164739164740164741164742164743164744164745164746164747164748164749164750164751164752164753164754164755164756164757164758164759164760164761164762164763164764164765164766164767164768164769164770164771164772164773164774164775164776164777164778164779164780164781164782164783164784164785164786164787164788164789164790164791164792164793164794164795164796164797164798164799164800164801164802164803164804164805164806164807164808164809164810164811164812164813164814164815164816164817164818164819164820164821164822164823164824164825164826164827164828164829164830164831164832164833164834164835164836164837164838164839164840164841164842164843164844164845164846164847164848164849164850164851164852164853164854164855164856164857164858164859164860164861164862164863164864164865164866164867164868164869164870164871164872164873164874164875164876164877164878164879164880164881164882164883164884164885164886164887164888164889164890164891164892164893164894164895164896164897164898164899164900164901164902164903164904164905164906164907164908164909164910164911164912164913164914164915164916164917164918164919164920164921164922164923164924164925164926164927164928164929164930164931164932164933164934164935164936164937164938164939164940164941164942164943164944164945164946164947164948164949164950164951164952164953164954164955164956164957164958164959164960164961164962164963164964164965164966164967164968164969164970164971164972164973164974164975164976164977164978164979164980164981164982164983164984164985164986164987164988164989164990164991164992164993164994164995164996164997164998164999165000165001165002165003165004165005165006165007165008165009165010165011165012165013165014165015165016165017165018165019165020165021165022165023165024165025165026165027165028165029165030165031165032165033165034165035165036165037165038165039165040165041165042165043165044165045165046165047165048165049165050165051165052165053165054165055165056165057165058165059165060165061165062165063165064165065165066165067165068165069165070165071165072165073165074165075165076165077165078165079165080165081165082165083165084165085165086165087165088165089165090165091165092165093165094165095165096165097165098165099165100165101165102165103165104165105165106165107165108165109165110165111165112165113165114165115165116165117165118165119165120165121165122165123165124165125165126165127165128165129165130165131165132165133165134165135165136165137165138165139165140165141165142165143165144165145165146165147165148165149165150165151165152165153165154165155165156165157165158165159165160165161165162165163165164165165165166165167165168165169165170165171165172165173165174165175165176165177165178165179165180165181165182165183165184165185165186165187165188165189165190165191165192165193165194165195165196165197165198165199165200165201165202165203165204165205165206165207165208165209165210165211165212165213165214165215165216165217165218165219165220165221165222165223165224165225165226165227165228165229165230165231165232165233165234165235165236165237165238165239165240165241165242165243165244165245165246165247165248165249165250165251165252165253165254165255165256165257165258165259165260165261165262165263165264165265165266165267165268165269165270165271165272165273165274165275165276165277165278165279165280165281165282165283165284165285165286165287165288165289165290165291165292165293165294165295165296165297165298165299165300165301165302165303165304165305165306165307165308165309165310165311165312165313165314165315165316165317165318165319165320165321165322165323165324165325165326165327165328165329165330165331165332165333165334165335165336165337165338165339165340165341165342165343165344165345165346165347165348165349165350165351165352165353165354165355165356165357165358165359165360165361165362165363165364165365165366165367165368165369165370165371165372165373165374165375165376165377165378165379165380165381165382165383165384165385165386165387165388165389165390165391165392165393165394165395165396165397165398165399165400165401165402165403165404165405165406165407165408165409165410165411165412165413165414165415165416165417165418165419165420165421165422165423165424165425165426165427165428165429165430165431165432165433165434165435165436165437165438165439165440165441165442165443165444165445165446165447165448165449165450165451165452165453165454165455165456165457165458165459165460165461165462165463165464165465165466165467165468165469165470165471165472165473165474165475165476165477165478165479165480165481165482165483165484165485165486165487165488165489165490165491165492165493165494165495165496165497165498165499165500165501165502165503165504165505165506165507165508165509165510165511165512165513165514165515165516165517165518165519165520165521165522165523165524165525165526165527165528165529165530165531165532165533165534165535165536165537165538165539165540165541165542165543165544165545165546165547165548165549165550165551165552165553165554165555165556165557165558165559165560165561165562165563165564165565165566165567165568165569165570165571165572165573165574165575165576165577165578165579165580165581165582165583165584165585165586165587165588165589165590165591165592165593165594165595165596165597165598165599165600165601165602165603165604165605165606165607165608165609165610165611165612165613165614165615165616165617165618165619165620165621165622165623165624165625165626165627165628165629165630165631165632165633165634165635165636165637165638165639165640165641165642165643165644165645165646165647165648165649165650165651165652165653165654165655165656165657165658165659165660165661165662165663165664165665165666165667165668165669165670165671165672165673165674165675165676165677165678165679165680165681165682165683165684165685165686165687165688165689165690165691165692165693165694165695165696165697165698165699165700165701165702165703165704165705165706165707165708165709165710165711165712165713165714165715165716165717165718165719165720165721165722165723165724165725165726165727165728165729165730165731165732165733165734165735165736165737165738165739165740165741165742165743165744165745165746165747165748165749165750165751165752165753165754165755165756165757165758165759165760165761165762165763165764165765165766165767165768165769165770165771165772165773165774165775165776165777165778165779165780165781165782165783165784165785165786165787165788165789165790165791165792165793165794165795165796165797165798165799165800165801165802165803165804165805165806165807165808165809165810165811165812165813165814165815165816165817165818165819165820165821165822165823165824165825165826165827165828165829165830165831165832165833165834165835165836165837165838165839165840165841165842165843165844165845165846165847165848165849165850165851165852165853165854165855165856165857165858165859165860165861165862165863165864165865165866165867165868165869165870165871165872165873165874165875165876165877165878165879165880165881165882165883165884165885165886165887165888165889165890165891165892165893165894165895165896165897165898165899165900165901165902165903165904165905165906165907165908165909165910165911165912165913165914165915165916165917165918165919165920165921165922165923165924165925165926165927165928165929165930165931165932165933165934165935165936165937165938165939165940165941165942165943165944165945165946165947165948165949165950165951165952165953165954165955165956165957165958165959165960165961165962165963165964165965165966165967165968165969165970165971165972165973165974165975165976165977165978165979165980165981165982165983165984165985165986165987165988165989165990165991165992165993165994165995165996165997165998165999166000166001166002166003166004166005166006166007166008166009166010166011166012166013166014166015166016166017166018166019166020166021166022166023166024166025166026166027166028166029166030166031166032166033166034166035166036166037166038166039166040166041166042166043166044166045166046166047166048166049166050166051166052166053166054166055166056166057166058166059166060166061166062166063166064166065166066166067166068166069166070166071166072166073166074166075166076166077166078166079166080166081166082166083166084166085166086166087166088166089166090166091166092166093166094166095166096166097166098166099166100166101166102166103166104166105166106166107166108166109166110166111166112166113166114166115166116166117166118166119166120166121166122166123166124166125166126166127166128166129166130166131166132166133166134166135166136166137166138166139166140166141166142166143166144166145166146166147166148166149166150166151166152166153166154166155166156166157166158166159166160166161166162166163166164166165166166166167166168166169166170166171166172166173166174166175166176166177166178166179166180166181166182166183166184166185166186166187166188166189166190166191166192166193166194166195166196166197166198166199166200166201166202166203166204166205166206166207166208166209166210166211166212166213166214166215166216166217166218166219166220166221166222166223166224166225166226166227166228166229166230166231166232166233166234166235166236166237166238166239166240166241166242166243166244166245166246166247166248166249166250166251166252166253166254166255166256166257166258166259166260166261166262166263166264166265166266166267166268166269166270166271166272166273166274166275166276166277166278166279166280166281166282166283166284166285166286166287166288166289166290166291166292166293166294166295166296166297166298166299166300166301166302166303166304166305166306166307166308166309166310166311166312166313166314166315166316166317166318166319166320166321166322166323166324166325166326166327166328166329166330166331166332166333166334166335166336166337166338166339166340166341166342166343166344166345166346166347166348166349166350166351166352166353166354166355166356166357166358166359166360166361166362166363166364166365166366166367166368166369166370166371166372166373166374166375166376166377166378166379166380166381166382166383166384166385166386166387166388166389166390166391166392166393166394166395166396166397166398166399166400166401166402166403166404166405166406166407166408166409166410166411166412166413166414166415166416166417166418166419166420166421166422166423166424166425166426166427166428166429166430166431166432166433166434166435166436166437166438166439166440166441166442166443166444166445166446166447166448166449166450166451166452166453166454166455166456166457166458166459166460166461166462166463166464166465166466166467166468166469166470166471166472166473166474166475166476166477166478166479166480166481166482166483166484166485166486166487166488166489166490166491166492166493166494166495166496166497166498166499166500166501166502166503166504166505166506166507166508166509166510166511166512166513166514166515166516166517166518166519166520166521166522166523166524166525166526166527166528166529166530166531166532166533166534166535166536166537166538166539166540166541166542166543166544166545166546166547166548166549166550166551166552166553166554166555166556166557166558166559166560166561166562166563166564166565166566166567166568166569166570166571166572166573166574166575166576166577166578166579166580166581166582166583166584166585166586166587166588166589166590166591166592166593166594166595166596166597166598166599166600166601166602166603166604166605166606166607166608166609166610166611166612166613166614166615166616166617166618166619166620166621166622166623166624166625166626166627166628166629166630166631166632166633166634166635166636166637166638166639166640166641166642166643166644166645166646166647166648166649166650166651166652166653166654166655166656166657166658166659166660166661166662166663166664166665166666166667166668166669166670166671166672166673166674166675166676166677166678166679166680166681166682166683166684166685166686166687166688166689166690166691166692166693166694166695166696166697166698166699166700166701166702166703166704166705166706166707166708166709166710166711166712166713166714166715166716166717166718166719166720166721166722166723166724166725166726166727166728166729166730166731166732166733166734166735166736166737166738166739166740166741166742166743166744166745166746166747166748166749166750166751166752166753166754166755166756166757166758166759166760166761166762166763166764166765166766166767166768166769166770166771166772166773166774166775166776166777166778166779166780166781166782166783166784166785166786166787166788166789166790166791166792166793166794166795166796166797166798166799166800166801166802166803166804166805166806166807166808166809166810166811166812166813166814166815166816166817166818166819166820166821166822166823166824166825166826166827166828166829166830166831166832166833166834166835166836166837166838166839166840166841166842166843166844166845166846166847166848166849166850166851166852166853166854166855166856166857166858166859166860166861166862166863166864166865166866166867166868166869166870166871166872166873166874166875166876166877166878166879166880166881166882166883166884166885166886166887166888166889166890166891166892166893166894166895166896166897166898166899166900166901166902166903166904166905166906166907166908166909166910166911166912166913166914166915166916166917166918166919166920166921166922166923166924166925166926166927166928166929166930166931166932166933166934166935166936166937166938166939166940166941166942166943166944166945166946166947166948166949166950166951166952166953166954166955166956166957166958166959166960166961166962166963166964166965166966166967166968166969166970166971166972166973166974166975166976166977166978166979166980166981166982166983166984166985166986166987166988166989166990166991166992166993166994166995166996166997166998166999167000167001167002167003167004167005167006167007167008167009167010167011167012167013167014167015167016167017167018167019167020167021167022167023167024167025167026167027167028167029167030167031167032167033167034167035167036167037167038167039167040167041167042167043167044167045167046167047167048167049167050167051167052167053167054167055167056167057167058167059167060167061167062167063167064167065167066167067167068167069167070167071167072167073167074167075167076167077167078167079167080167081167082167083167084167085167086167087167088167089167090167091167092167093167094167095167096167097167098167099167100167101167102167103167104167105167106167107167108167109167110167111167112167113167114167115167116167117167118167119167120167121167122167123167124167125167126167127167128167129167130167131167132167133167134167135167136167137167138167139167140167141167142167143167144167145167146167147167148167149167150167151167152167153167154167155167156167157167158167159167160167161167162167163167164167165167166167167167168167169167170167171167172167173167174167175167176167177167178167179167180167181167182167183167184167185167186167187167188167189167190167191167192167193167194167195167196167197167198167199167200167201167202167203167204167205167206167207167208167209167210167211167212167213167214167215167216167217167218167219167220167221167222167223167224167225167226167227167228167229167230167231167232167233167234167235167236167237167238167239167240167241167242167243167244167245167246167247167248167249167250167251167252167253167254167255167256167257167258167259167260167261167262167263167264167265167266167267167268167269167270167271167272167273167274167275167276167277167278167279167280167281167282167283167284167285167286167287167288167289167290167291167292167293167294167295167296167297167298167299167300167301167302167303167304167305167306167307167308167309167310167311167312167313167314167315167316167317167318167319167320167321167322167323167324167325167326167327167328167329167330167331167332167333167334167335167336167337167338167339167340167341167342167343167344167345167346167347167348167349167350167351167352167353167354167355167356167357167358167359167360167361167362167363167364167365167366167367167368167369167370167371167372167373167374167375167376167377167378167379167380167381167382167383167384167385167386167387167388167389167390167391167392167393167394167395167396167397167398167399167400167401167402167403167404167405167406167407167408167409167410167411167412167413167414167415167416167417167418167419167420167421167422167423167424167425167426167427167428167429167430167431167432167433167434167435167436167437167438167439167440167441167442167443167444167445167446167447167448167449167450167451167452167453167454167455167456167457167458167459167460167461167462167463167464167465167466167467167468167469167470167471167472167473167474167475167476167477167478167479167480167481167482167483167484167485167486167487167488167489167490167491167492167493167494167495167496167497167498167499167500167501167502167503167504167505167506167507167508167509167510167511167512167513167514167515167516167517167518167519167520167521167522167523167524167525167526167527167528167529167530167531167532167533167534167535167536167537167538167539167540167541167542167543167544167545167546167547167548167549167550167551167552167553167554167555167556167557167558167559167560167561167562167563167564167565167566167567167568167569167570167571167572167573167574167575167576167577167578167579167580167581167582167583167584167585167586167587167588167589167590167591167592167593167594167595167596167597167598167599167600167601167602167603167604167605167606167607167608167609167610167611167612167613167614167615167616167617167618167619167620167621167622167623167624167625167626167627167628167629167630167631167632167633167634167635167636167637167638167639167640167641167642167643167644167645167646167647167648167649167650167651167652167653167654167655167656167657167658167659167660167661167662167663167664167665167666167667167668167669167670167671167672167673167674167675167676167677167678167679167680167681167682167683167684167685167686167687167688167689167690167691167692167693167694167695167696167697167698167699167700167701167702167703167704167705167706167707167708167709167710167711167712167713167714167715167716167717167718167719167720167721167722167723167724167725167726167727167728167729167730167731167732167733167734167735167736167737167738167739167740167741167742167743167744167745167746167747167748167749167750167751167752167753167754167755167756167757167758167759167760167761167762167763167764167765167766167767167768167769167770167771167772167773167774167775167776167777167778167779167780167781167782167783167784167785167786167787167788167789167790167791167792167793167794167795167796167797167798167799167800167801167802167803167804167805167806167807167808167809167810167811167812167813167814167815167816167817167818167819167820167821167822167823167824167825167826167827167828167829167830167831167832167833167834167835167836167837167838167839167840167841167842167843167844167845167846167847167848167849167850167851167852167853167854167855167856167857167858167859167860167861167862167863167864167865167866167867167868167869167870167871167872167873167874167875167876167877167878167879167880167881167882167883167884167885167886167887167888167889167890167891167892167893167894167895167896167897167898167899167900167901167902167903167904167905167906167907167908167909167910167911167912167913167914167915167916167917167918167919167920167921167922167923167924167925167926167927167928167929167930167931167932167933167934167935167936167937167938167939167940167941167942167943167944167945167946167947167948167949167950167951167952167953167954167955167956167957167958167959167960167961167962167963167964167965167966167967167968167969167970167971167972167973167974167975167976167977167978167979167980167981167982167983167984167985167986167987167988167989167990167991167992167993167994167995167996167997167998167999168000168001168002168003168004168005168006168007168008168009168010168011168012168013168014168015168016168017168018168019168020168021168022168023168024168025168026168027168028168029168030168031168032168033168034168035168036168037168038168039168040168041168042168043168044168045168046168047168048168049168050168051168052168053168054168055168056168057168058168059168060168061168062168063168064168065168066168067168068168069168070168071168072168073168074168075168076168077168078168079168080168081168082168083168084168085168086168087168088168089168090168091168092168093168094168095168096168097168098168099168100168101168102168103168104168105168106168107168108168109168110168111168112168113168114168115168116168117168118168119168120168121168122168123168124168125168126168127168128168129168130168131168132168133168134168135168136168137168138168139168140168141168142168143168144168145168146168147168148168149168150168151168152168153168154168155168156168157168158168159168160168161168162168163168164168165168166168167168168168169168170168171168172168173168174168175168176168177168178168179168180168181168182168183168184168185168186168187168188168189168190168191168192168193168194168195168196168197168198168199168200168201168202168203168204168205168206168207168208168209168210168211168212168213168214168215168216168217168218168219168220168221168222168223168224168225168226168227168228168229168230168231168232168233168234168235168236168237168238168239168240168241168242168243168244168245168246168247168248168249168250168251168252168253168254168255168256168257168258168259168260168261168262168263168264168265168266168267168268168269168270168271168272168273168274168275168276168277168278168279168280168281168282168283168284168285168286168287168288168289168290168291168292168293168294168295168296168297168298168299168300168301168302168303168304168305168306168307168308168309168310168311168312168313168314168315168316168317168318168319168320168321168322168323168324168325168326168327168328168329168330168331168332168333168334168335168336168337168338168339168340168341168342168343168344168345168346168347168348168349168350168351168352168353168354168355168356168357168358168359168360168361168362168363168364168365168366168367168368168369168370168371168372168373168374168375168376168377168378168379168380168381168382168383168384168385168386168387168388168389168390168391168392168393168394168395168396168397168398168399168400168401168402168403168404168405168406168407168408168409168410168411168412168413168414168415168416168417168418168419168420168421168422168423168424168425168426168427168428168429168430168431168432168433168434168435168436168437168438168439168440168441168442168443168444168445168446168447168448168449168450168451168452168453168454168455168456168457168458168459168460168461168462168463168464168465168466168467168468168469168470168471168472168473168474168475168476168477168478168479168480168481168482168483168484168485168486168487168488168489168490168491168492168493168494168495168496168497168498168499168500168501168502168503168504168505168506168507168508168509168510168511168512168513168514168515168516168517168518168519168520168521168522168523168524168525168526168527168528168529168530168531168532168533168534168535168536168537168538168539168540168541168542168543168544168545168546168547168548168549168550168551168552168553168554168555168556168557168558168559168560168561168562168563168564168565168566168567168568168569168570168571168572168573168574168575168576168577168578168579168580168581168582168583168584168585168586168587168588168589168590168591168592168593168594168595168596168597168598168599168600168601168602168603168604168605168606168607168608168609168610168611168612168613168614168615168616168617168618168619168620168621168622168623168624168625168626168627168628168629168630168631168632168633168634168635168636168637168638168639168640168641168642168643168644168645168646168647168648168649168650168651168652168653168654168655168656168657168658168659168660168661168662168663168664168665168666168667168668168669168670168671168672168673168674168675168676168677168678168679168680168681168682168683168684168685168686168687168688168689168690168691168692168693168694168695168696168697168698168699168700168701168702168703168704168705168706168707168708168709168710168711168712168713168714168715168716168717168718168719168720168721168722168723168724168725168726168727168728168729168730168731168732168733168734168735168736168737168738168739168740168741168742168743168744168745168746168747168748168749168750168751168752168753168754168755168756168757168758168759168760168761168762168763168764168765168766168767168768168769168770168771168772168773168774168775168776168777168778168779168780168781168782168783168784168785168786168787168788168789168790168791168792168793168794168795168796168797168798168799168800168801168802168803168804168805168806168807168808168809168810168811168812168813168814168815168816168817168818168819168820168821168822168823168824168825168826168827168828168829168830168831168832168833168834168835168836168837168838168839168840168841168842168843168844168845168846168847168848168849168850168851168852168853168854168855168856168857168858168859168860168861168862168863168864168865168866168867168868168869168870168871168872168873168874168875168876168877168878168879168880168881168882168883168884168885168886168887168888168889168890168891168892168893168894168895168896168897168898168899168900168901168902168903168904168905168906168907168908168909168910168911168912168913168914168915168916168917168918168919168920168921168922168923168924168925168926168927168928168929168930168931168932168933168934168935168936168937168938168939168940168941168942168943168944168945168946168947168948168949168950168951168952168953168954168955168956168957168958168959168960168961168962168963168964168965168966168967168968168969168970168971168972168973168974168975168976168977168978168979168980168981168982168983168984168985168986168987168988168989168990168991168992168993168994168995168996168997168998168999169000169001169002169003169004169005169006169007169008169009169010169011169012169013169014169015169016169017169018169019169020169021169022169023169024169025169026169027169028169029169030169031169032169033169034169035169036169037169038169039169040169041169042169043169044169045169046169047169048169049169050169051169052169053169054169055169056169057169058169059169060169061169062169063169064169065169066169067169068169069169070169071169072169073169074169075169076169077169078169079169080169081169082169083169084169085169086169087169088169089169090169091169092169093169094169095169096169097169098169099169100169101169102169103169104169105169106169107169108169109169110169111169112169113169114169115169116169117169118169119169120169121169122169123169124169125169126169127169128169129169130169131169132169133169134169135169136169137169138169139169140169141169142169143169144169145169146169147169148169149169150169151169152169153169154169155169156169157169158169159169160169161169162169163169164169165169166169167169168169169169170169171169172169173169174169175169176169177169178169179169180169181169182169183169184169185169186169187169188169189169190169191169192169193169194169195169196169197169198169199169200169201169202169203169204169205169206169207169208169209169210169211169212169213169214169215169216169217169218169219169220169221169222169223169224169225169226169227169228169229169230169231169232169233169234169235169236169237169238169239169240169241169242169243169244169245169246169247169248169249169250169251169252169253169254169255169256169257169258169259169260169261169262169263169264169265169266169267169268169269169270169271169272169273169274169275169276169277169278169279169280169281169282169283169284169285169286169287169288169289169290169291169292169293169294169295169296169297169298169299169300169301169302169303169304169305169306169307169308169309169310169311169312169313169314169315169316169317169318169319169320169321169322169323169324169325169326169327169328169329169330169331169332169333169334169335169336169337169338169339169340169341169342169343169344169345169346169347169348169349169350169351169352169353169354169355169356169357169358169359169360169361169362169363169364169365169366169367169368169369169370169371169372169373169374169375169376169377169378169379169380169381169382169383169384169385169386169387169388169389169390169391169392169393169394169395169396169397169398169399169400169401169402169403169404169405169406169407169408169409169410169411169412169413169414169415169416169417169418169419169420169421169422169423169424169425169426169427169428169429169430169431169432169433169434169435169436169437169438169439169440169441169442169443169444169445169446169447169448169449169450169451169452169453169454169455169456169457169458169459169460169461169462169463169464169465169466169467169468169469169470169471169472169473169474169475169476169477169478169479169480169481169482169483169484169485169486169487169488169489169490169491169492169493169494169495169496169497169498169499169500169501169502169503169504169505169506169507169508169509169510169511169512169513169514169515169516169517169518169519169520169521169522169523169524169525169526169527169528169529169530169531169532169533169534169535169536169537169538169539169540169541169542169543169544169545169546169547169548169549169550169551169552169553169554169555169556169557169558169559169560169561169562169563169564169565169566169567169568169569169570169571169572169573169574169575169576169577169578169579169580169581169582169583169584169585169586169587169588169589169590169591169592169593169594169595169596169597169598169599169600169601169602169603169604169605169606169607169608169609169610169611169612169613169614169615169616169617169618169619169620169621169622169623169624169625169626169627169628169629169630169631169632169633169634169635169636169637169638169639169640169641169642169643169644169645169646169647169648169649169650169651169652169653169654169655169656169657169658169659169660169661169662169663169664169665169666169667169668169669169670169671169672169673169674169675169676169677169678169679169680169681169682169683169684169685169686169687169688169689169690169691169692169693169694169695169696169697169698169699169700169701169702169703169704169705169706169707169708169709169710169711169712169713169714169715169716169717169718169719169720169721169722169723169724169725169726169727169728169729169730169731169732169733169734169735169736169737169738169739169740169741169742169743169744169745169746169747169748169749169750169751169752169753169754169755169756169757169758169759169760169761169762169763169764169765169766169767169768169769169770169771169772169773169774169775169776169777169778169779169780169781169782169783169784169785169786169787169788169789169790169791169792169793169794169795169796169797169798169799169800169801169802169803169804169805169806169807169808169809169810169811169812169813169814169815169816169817169818169819169820169821169822169823169824169825169826169827169828169829169830169831169832169833169834169835169836169837169838169839169840169841169842169843169844169845169846169847169848169849169850169851169852169853169854169855169856169857169858169859169860169861169862169863169864169865169866169867169868169869169870169871169872169873169874169875169876169877169878169879169880169881169882169883169884169885169886169887169888169889169890169891169892169893169894169895169896169897169898169899169900169901169902169903169904169905169906169907169908169909169910169911169912169913169914169915169916169917169918169919169920169921169922169923169924169925169926169927169928169929169930169931169932169933169934169935169936169937169938169939169940169941169942169943169944169945169946169947169948169949169950169951169952169953169954169955169956169957169958169959169960169961169962169963169964169965169966169967169968169969169970169971169972169973169974169975169976169977169978169979169980169981169982169983169984169985169986169987169988169989169990169991169992169993169994169995169996169997169998169999170000170001170002170003170004170005170006170007170008170009170010170011170012170013170014170015170016170017170018170019170020170021170022170023170024170025170026170027170028170029170030170031170032170033170034170035170036170037170038170039170040170041170042170043170044170045170046170047170048170049170050170051170052170053170054170055170056170057170058170059170060170061170062170063170064170065170066170067170068170069170070170071170072170073170074170075170076170077170078170079170080170081170082170083170084170085170086170087170088170089170090170091170092170093170094170095170096170097170098170099170100170101170102170103170104170105170106170107170108170109170110170111170112170113170114170115170116170117170118170119170120170121170122170123170124170125170126170127170128170129170130170131170132170133170134170135170136170137170138170139170140170141170142170143170144170145170146170147170148170149170150170151170152170153170154170155170156170157170158170159170160170161170162170163170164170165170166170167170168170169170170170171170172170173170174170175170176170177170178170179170180170181170182170183170184170185170186170187170188170189170190170191170192170193170194170195170196170197170198170199170200170201170202170203170204170205170206170207170208170209170210170211170212170213170214170215170216170217170218170219170220170221170222170223170224170225170226170227170228170229170230170231170232170233170234170235170236170237170238170239170240170241170242170243170244170245170246170247170248170249170250170251170252170253170254170255170256170257170258170259170260170261170262170263170264170265170266170267170268170269170270170271170272170273170274170275170276170277170278170279170280170281170282170283170284170285170286170287170288170289170290170291170292170293170294170295170296170297170298170299170300170301170302170303170304170305170306170307170308170309170310170311170312170313170314170315170316170317170318170319170320170321170322170323170324170325170326170327170328170329170330170331170332170333170334170335170336170337170338170339170340170341170342170343170344170345170346170347170348170349170350170351170352170353170354170355170356170357170358170359170360170361170362170363170364170365170366170367170368170369170370170371170372170373170374170375170376170377170378170379170380170381170382170383170384170385170386170387170388170389170390170391170392170393170394170395170396170397170398170399170400170401170402170403170404170405170406170407170408170409170410170411170412170413170414170415170416170417170418170419170420170421170422170423170424170425170426170427170428170429170430170431170432170433170434170435170436170437170438170439170440170441170442170443170444170445170446170447170448170449170450170451170452170453170454170455170456170457170458170459170460170461170462170463170464170465170466170467170468170469170470170471170472170473170474170475170476170477170478170479170480170481170482170483170484170485170486170487170488170489170490170491170492170493170494170495170496170497170498170499170500170501170502170503170504170505170506170507170508170509170510170511170512170513170514170515170516170517170518170519170520170521170522170523170524170525170526170527170528170529170530170531170532170533170534170535170536170537170538170539170540170541170542170543170544170545170546170547170548170549170550170551170552170553170554170555170556170557170558170559170560170561170562170563170564170565170566170567170568170569170570170571170572170573170574170575170576170577170578170579170580170581170582170583170584170585170586170587170588170589170590170591170592170593170594170595170596170597170598170599170600170601170602170603170604170605170606170607170608170609170610170611170612170613170614170615170616170617170618170619170620170621170622170623170624170625170626170627170628170629170630170631170632170633170634170635170636170637170638170639170640170641170642170643170644170645170646170647170648170649170650170651170652170653170654170655170656170657170658170659170660170661170662170663170664170665170666170667170668170669170670170671170672170673170674170675170676170677170678170679170680170681170682170683170684170685170686170687170688170689170690170691170692170693170694170695170696170697170698170699170700170701170702170703170704170705170706170707170708170709170710170711170712170713170714170715170716170717170718170719170720170721170722170723170724170725170726170727170728170729170730170731170732170733170734170735170736170737170738170739170740170741170742170743170744170745170746170747170748170749170750170751170752170753170754170755170756170757170758170759170760170761170762170763170764170765170766170767170768170769170770170771170772170773170774170775170776170777170778170779170780170781170782170783170784170785170786170787170788170789170790170791170792170793170794170795170796170797170798170799170800170801170802170803170804170805170806170807170808170809170810170811170812170813170814170815170816170817170818170819170820170821170822170823170824170825170826170827170828170829170830170831170832170833170834170835170836170837170838170839170840170841170842170843170844170845170846170847170848170849170850170851170852170853170854170855170856170857170858170859170860170861170862170863170864170865170866170867170868170869170870170871170872170873170874170875170876170877170878170879170880170881170882170883170884170885170886170887170888170889170890170891170892170893170894170895170896170897170898170899170900170901170902170903170904170905170906170907170908170909170910170911170912170913170914170915170916170917170918170919170920170921170922170923170924170925170926170927170928170929170930170931170932170933170934170935170936170937170938170939170940170941170942170943170944170945170946170947170948170949170950170951170952170953170954170955170956170957170958170959170960170961170962170963170964170965170966170967170968170969170970170971170972170973170974170975170976170977170978170979170980170981170982170983170984170985170986170987170988170989170990170991170992170993170994170995170996170997170998170999171000171001171002171003171004171005171006171007171008171009171010171011171012171013171014171015171016171017171018171019171020171021171022171023171024171025171026171027171028171029171030171031171032171033171034171035171036171037171038171039171040171041171042171043171044171045171046171047171048171049171050171051171052171053171054171055171056171057171058171059171060171061171062171063171064171065171066171067171068171069171070171071171072171073171074171075171076171077171078171079171080171081171082171083171084171085171086171087171088171089171090171091171092171093171094171095171096171097171098171099171100171101171102171103171104171105171106171107171108171109171110171111171112171113171114171115171116171117171118171119171120171121171122171123171124171125171126171127171128171129171130171131171132171133171134171135171136171137171138171139171140171141171142171143171144171145171146171147171148171149171150171151171152171153171154171155171156171157171158171159171160171161171162171163171164171165171166171167171168171169171170171171171172171173171174171175171176171177171178171179171180171181171182171183171184171185171186171187171188171189171190171191171192171193171194171195171196171197171198171199171200171201171202171203171204171205171206171207171208171209171210171211171212171213171214171215171216171217171218171219171220171221171222171223171224171225171226171227171228171229171230171231171232171233171234171235171236171237171238171239171240171241171242171243171244171245171246171247171248171249171250171251171252171253171254171255171256171257171258171259171260171261171262171263171264171265171266171267171268171269171270171271171272171273171274171275171276171277171278171279171280171281171282171283171284171285171286171287171288171289171290171291171292171293171294171295171296171297171298171299171300171301171302171303171304171305171306171307171308171309171310171311171312171313171314171315171316171317171318171319171320171321171322171323171324171325171326171327171328171329171330171331171332171333171334171335171336171337171338171339171340171341171342171343171344171345171346171347171348171349171350171351171352171353171354171355171356171357171358171359171360171361171362171363171364171365171366171367171368171369171370171371171372171373171374171375171376171377171378171379171380171381171382171383171384171385171386171387171388171389171390171391171392171393171394171395171396171397171398171399171400171401171402171403171404171405171406171407171408171409171410171411171412171413171414171415171416171417171418171419171420171421171422171423171424171425171426171427171428171429171430171431171432171433171434171435171436171437171438171439171440171441171442171443171444171445171446171447171448171449171450171451171452171453171454171455171456171457171458171459171460171461171462171463171464171465171466171467171468171469171470171471171472171473171474171475171476171477171478171479171480171481171482171483171484171485171486171487171488171489171490171491171492171493171494171495171496171497171498171499171500171501171502171503171504171505171506171507171508171509171510171511171512171513171514171515171516171517171518171519171520171521171522171523171524171525171526171527171528171529171530171531171532171533171534171535171536171537171538171539171540171541171542171543171544171545171546171547171548171549171550171551171552171553171554171555171556171557171558171559171560171561171562171563171564171565171566171567171568171569171570171571171572171573171574171575171576171577171578171579171580171581171582171583171584171585171586171587171588171589171590171591171592171593171594171595171596171597171598171599171600171601171602171603171604171605171606171607171608171609171610171611171612171613171614171615171616171617171618171619171620171621171622171623171624171625171626171627171628171629171630171631171632171633171634171635171636171637171638171639171640171641171642171643171644171645171646171647171648171649171650171651171652171653171654171655171656171657171658171659171660171661171662171663171664171665171666171667171668171669171670171671171672171673171674171675171676171677171678171679171680171681171682171683171684171685171686171687171688171689171690171691171692171693171694171695171696171697171698171699171700171701171702171703171704171705171706171707171708171709171710171711171712171713171714171715171716171717171718171719171720171721171722171723171724171725171726171727171728171729171730171731171732171733171734171735171736171737171738171739171740171741171742171743171744171745171746171747171748171749171750171751171752171753171754171755171756171757171758171759171760171761171762171763171764171765171766171767171768171769171770171771171772171773171774171775171776171777171778171779171780171781171782171783171784171785171786171787171788171789171790171791171792171793171794171795171796171797171798171799171800171801171802171803171804171805171806171807171808171809171810171811171812171813171814171815171816171817171818171819171820171821171822171823171824171825171826171827171828171829171830171831171832171833171834171835171836171837171838171839171840171841171842171843171844171845171846171847171848171849171850171851171852171853171854171855171856171857171858171859171860171861171862171863171864171865171866171867171868171869171870171871171872171873171874171875171876171877171878171879171880171881171882171883171884171885171886171887171888171889171890171891171892171893171894171895171896171897171898171899171900171901171902171903171904171905171906171907171908171909171910171911171912171913171914171915171916171917171918171919171920171921171922171923171924171925171926171927171928171929171930171931171932171933171934171935171936171937171938171939171940171941171942171943171944171945171946171947171948171949171950171951171952171953171954171955171956171957171958171959171960171961171962171963171964171965171966171967171968171969171970171971171972171973171974171975171976171977171978171979171980171981171982171983171984171985171986171987171988171989171990171991171992171993171994171995171996171997171998171999172000172001172002172003172004172005172006172007172008172009172010172011172012172013172014172015172016172017172018172019172020172021172022172023172024172025172026172027172028172029172030172031172032172033172034172035172036172037172038172039172040172041172042172043172044172045172046172047172048172049172050172051172052172053172054172055172056172057172058172059172060172061172062172063172064172065172066172067172068172069172070172071172072172073172074172075172076172077172078172079172080172081172082172083172084172085172086172087172088172089172090172091172092172093172094172095172096172097172098172099172100172101172102172103172104172105172106172107172108172109172110172111172112172113172114172115172116172117172118172119172120172121172122172123172124172125172126172127172128172129172130172131172132172133172134172135172136172137172138172139172140172141172142172143172144172145172146172147172148172149172150172151172152172153172154172155172156172157172158172159172160172161172162172163172164172165172166172167172168172169172170172171172172172173172174172175172176172177172178172179172180172181172182172183172184172185172186172187172188172189172190172191172192172193172194172195172196172197172198172199172200172201172202172203172204172205172206172207172208172209172210172211172212172213172214172215172216172217172218172219172220172221172222172223172224172225172226172227172228172229172230172231172232172233172234172235172236172237172238172239172240172241172242172243172244172245172246172247172248172249172250172251172252172253172254172255172256172257172258172259172260172261172262172263172264172265172266172267172268172269172270172271172272172273172274172275172276172277172278172279172280172281172282172283172284172285172286172287172288172289172290172291172292172293172294172295172296172297172298172299172300172301172302172303172304172305172306172307172308172309172310172311172312172313172314172315172316172317172318172319172320172321172322172323172324172325172326172327172328172329172330172331172332172333172334172335172336172337172338172339172340172341172342172343172344172345172346172347172348172349172350172351172352172353172354172355172356172357172358172359172360172361172362172363172364172365172366172367172368172369172370172371172372172373172374172375172376172377172378172379172380172381172382172383172384172385172386172387172388172389172390172391172392172393172394172395172396172397172398172399172400172401172402172403172404172405172406172407172408172409172410172411172412172413172414172415172416172417172418172419172420172421172422172423172424172425172426172427172428172429172430172431172432172433172434172435172436172437172438172439172440172441172442172443172444172445172446172447172448172449172450172451172452172453172454172455172456172457172458172459172460172461172462172463172464172465172466172467172468172469172470172471172472172473172474172475172476172477172478172479172480172481172482172483172484172485172486172487172488172489172490172491172492172493172494172495172496172497172498172499172500172501172502172503172504172505172506172507172508172509172510172511172512172513172514172515172516172517172518172519172520172521172522172523172524172525172526172527172528172529172530172531172532172533172534172535172536172537172538172539172540172541172542172543172544172545172546172547172548172549172550172551172552172553172554172555172556172557172558172559172560172561172562172563172564172565172566172567172568172569172570172571172572172573172574172575172576172577172578172579172580172581172582172583172584172585172586172587172588172589172590172591172592172593172594172595172596172597172598172599172600172601172602172603172604172605172606172607172608172609172610172611172612172613172614172615172616172617172618172619172620172621172622172623172624172625172626172627172628172629172630172631172632172633172634172635172636172637172638172639172640172641172642172643172644172645172646172647172648172649172650172651172652172653172654172655172656172657172658172659172660172661172662172663172664172665172666172667172668172669172670172671172672172673172674172675172676172677172678172679172680172681172682172683172684172685172686172687172688172689172690172691172692172693172694172695172696172697172698172699172700172701172702172703172704172705172706172707172708172709172710172711172712172713172714172715172716172717172718172719172720172721172722172723172724172725172726172727172728172729172730172731172732172733172734172735172736172737172738172739172740172741172742172743172744172745172746172747172748172749172750172751172752172753172754172755172756172757172758172759172760172761172762172763172764172765172766172767172768172769172770172771172772172773172774172775172776172777172778172779172780172781172782172783172784172785172786172787172788172789172790172791172792172793172794172795172796172797172798172799172800172801172802172803172804172805172806172807172808172809172810172811172812172813172814172815172816172817172818172819172820172821172822172823172824172825172826172827172828172829172830172831172832172833172834172835172836172837172838172839172840172841172842172843172844172845172846172847172848172849172850172851172852172853172854172855172856172857172858172859172860172861172862172863172864172865172866172867172868172869172870172871172872172873172874172875172876172877172878172879172880172881172882172883172884172885172886172887172888172889172890172891172892172893172894172895172896172897172898172899172900172901172902172903172904172905172906172907172908172909172910172911172912172913172914172915172916172917172918172919172920172921172922172923172924172925172926172927172928172929172930172931172932172933172934172935172936172937172938172939172940172941172942172943172944172945172946172947172948172949172950172951172952172953172954172955172956172957172958172959172960172961172962172963172964172965172966172967172968172969172970172971172972172973172974172975172976172977172978172979172980172981172982172983172984172985172986172987172988172989172990172991172992172993172994172995172996172997172998172999173000173001173002173003173004173005173006173007173008173009173010173011173012173013173014173015173016173017173018173019173020173021173022173023173024173025173026173027173028173029173030173031173032173033173034173035173036173037173038173039173040173041173042173043173044173045173046173047173048173049173050173051173052173053173054173055173056173057173058173059173060173061173062173063173064173065173066173067173068173069173070173071173072173073173074173075173076173077173078173079173080173081173082173083173084173085173086173087173088173089173090173091173092173093173094173095173096173097173098173099173100173101173102173103173104173105173106173107173108173109173110173111173112173113173114173115173116173117173118173119173120173121173122173123173124173125173126173127173128173129173130173131173132173133173134173135173136173137173138173139173140173141173142173143173144173145173146173147173148173149173150173151173152173153173154173155173156173157173158173159173160173161173162173163173164173165173166173167173168173169173170173171173172173173173174173175173176173177173178173179173180173181173182173183173184173185173186173187173188173189173190173191173192173193173194173195173196173197173198173199173200173201173202173203173204173205173206173207173208173209173210173211173212173213173214173215173216173217173218173219173220173221173222173223173224173225173226173227173228173229173230173231173232173233173234173235173236173237173238173239173240173241173242173243173244173245173246173247173248173249173250173251173252173253173254173255173256173257173258173259173260173261173262173263173264173265173266173267173268173269173270173271173272173273173274173275173276173277173278173279173280173281173282173283173284173285173286173287173288173289173290173291173292173293173294173295173296173297173298173299173300173301173302173303173304173305173306173307173308173309173310173311173312173313173314173315173316173317173318173319173320173321173322173323173324173325173326173327173328173329173330173331173332173333173334173335173336173337173338173339173340173341173342173343173344173345173346173347173348173349173350173351173352173353173354173355173356173357173358173359173360173361173362173363173364173365173366173367173368173369173370173371173372173373173374173375173376173377173378173379173380173381173382173383173384173385173386173387173388173389173390173391173392173393173394173395173396173397173398173399173400173401173402173403173404173405173406173407173408173409173410173411173412173413173414173415173416173417173418173419173420173421173422173423173424173425173426173427173428173429173430173431173432173433173434173435173436173437173438173439173440173441173442173443173444173445173446173447173448173449173450173451173452173453173454173455173456173457173458173459173460173461173462173463173464173465173466173467173468173469173470173471173472173473173474173475173476173477173478173479173480173481173482173483173484173485173486173487173488173489173490173491173492173493173494173495173496173497173498173499173500173501173502173503173504173505173506173507173508173509173510173511173512173513173514173515173516173517173518173519173520173521173522173523173524173525173526173527173528173529173530173531173532173533173534173535173536173537173538173539173540173541173542173543173544173545173546173547173548173549173550173551173552173553173554173555173556173557173558173559173560173561173562173563173564173565173566173567173568173569173570173571173572173573173574173575173576173577173578173579173580173581173582173583173584173585173586173587173588173589173590173591173592173593173594173595173596173597173598173599173600173601173602173603173604173605173606173607173608173609173610173611173612173613173614173615173616173617173618173619173620173621173622173623173624173625173626173627173628173629173630173631173632173633173634173635173636173637173638173639173640173641173642173643173644173645173646173647173648173649173650173651173652173653173654173655173656173657173658173659173660173661173662173663173664173665173666173667173668173669173670173671173672173673173674173675173676173677173678173679173680173681173682173683173684173685173686173687173688173689173690173691173692173693173694173695173696173697173698173699173700173701173702173703173704173705173706173707173708173709173710173711173712173713173714173715173716173717173718173719173720173721173722173723173724173725173726173727173728173729173730173731173732173733173734173735173736173737173738173739173740173741173742173743173744173745173746173747173748173749173750173751173752173753173754173755173756173757173758173759173760173761173762173763173764173765173766173767173768173769173770173771173772173773173774173775173776173777173778173779173780173781173782173783173784173785173786173787173788173789173790173791173792173793173794173795173796173797173798173799173800173801173802173803173804173805173806173807173808173809173810173811173812173813173814173815173816173817173818173819173820173821173822173823173824173825173826173827173828173829173830173831173832173833173834173835173836173837173838173839173840173841173842173843173844173845173846173847173848173849173850173851173852173853173854173855173856173857173858173859173860173861173862173863173864173865173866173867173868173869173870173871173872173873173874173875173876173877173878173879173880173881173882173883173884173885173886173887173888173889173890173891173892173893173894173895173896173897173898173899173900173901173902173903173904173905173906173907173908173909173910173911173912173913173914173915173916173917173918173919173920173921173922173923173924173925173926173927173928173929173930173931173932173933173934173935173936173937173938173939173940173941173942173943173944173945173946173947173948173949173950173951173952173953173954173955173956173957173958173959173960173961173962173963173964173965173966173967173968173969173970173971173972173973173974173975173976173977173978173979173980173981173982173983173984173985173986173987173988173989173990173991173992173993173994173995173996173997173998173999174000174001174002174003174004174005174006174007174008174009174010174011174012174013174014174015174016174017174018174019174020174021174022174023174024174025174026174027174028174029174030174031174032174033174034174035174036174037174038174039174040174041174042174043174044174045174046174047174048174049174050174051174052174053174054174055174056174057174058174059174060174061174062174063174064174065174066174067174068174069174070174071174072174073174074174075174076174077174078174079174080174081174082174083174084174085174086174087174088174089174090174091174092174093174094174095174096174097174098174099174100174101174102174103174104174105174106174107174108174109174110174111174112174113174114174115174116174117174118174119174120174121174122174123174124174125174126174127174128174129174130174131174132174133174134174135174136174137174138174139174140174141174142174143174144174145174146174147174148174149174150174151174152174153174154174155174156174157174158174159174160174161174162174163174164174165174166174167174168174169174170174171174172174173174174174175174176174177174178174179174180174181174182174183174184174185174186174187174188174189174190174191174192174193174194174195174196174197174198174199174200174201174202174203174204174205174206174207174208174209174210174211174212174213174214174215174216174217174218174219174220174221174222174223174224174225174226174227174228174229174230174231174232174233174234174235174236174237174238174239174240174241174242174243174244174245174246174247174248174249174250174251174252174253174254174255174256174257174258174259174260174261174262174263174264174265174266174267174268174269174270174271174272174273174274174275174276174277174278174279174280174281174282174283174284174285174286174287174288174289174290174291174292174293174294174295174296174297174298174299174300174301174302174303174304174305174306174307174308174309174310174311174312174313174314174315174316174317174318174319174320174321174322174323174324174325174326174327174328174329174330174331174332174333174334174335174336174337174338174339174340174341174342174343174344174345174346174347174348174349174350174351174352174353174354174355174356174357174358174359174360174361174362174363174364174365174366174367174368174369174370174371174372174373174374174375174376174377174378174379174380174381174382174383174384174385174386174387174388174389174390174391174392174393174394174395174396174397174398174399174400174401174402174403174404174405174406174407174408174409174410174411174412174413174414174415174416174417174418174419174420174421174422174423174424174425174426174427174428174429174430174431174432174433174434174435174436174437174438174439174440174441174442174443174444174445174446174447174448174449174450174451174452174453174454174455174456174457174458174459174460174461174462174463174464174465174466174467174468174469174470174471174472174473174474174475174476174477174478174479174480174481174482174483174484174485174486174487174488174489174490174491174492174493174494174495174496174497174498174499174500174501174502174503174504174505174506174507174508174509174510174511174512174513174514174515174516174517174518174519174520174521174522174523174524174525174526174527174528174529174530174531174532174533174534174535174536174537174538174539174540174541174542174543174544174545174546174547174548174549174550174551174552174553174554174555174556174557174558174559174560174561174562174563174564174565174566174567174568174569174570174571174572174573174574174575174576174577174578174579174580174581174582174583174584174585174586174587174588174589174590174591174592174593174594174595174596174597174598174599174600174601174602174603174604174605174606174607174608174609174610174611174612174613174614174615174616174617174618174619174620174621174622174623174624174625174626174627174628174629174630174631174632174633174634174635174636174637174638174639174640174641174642174643174644174645174646174647174648174649174650174651174652174653174654174655174656174657174658174659174660174661174662174663174664174665174666174667174668174669174670174671174672174673174674174675174676174677174678174679174680174681174682174683174684174685174686174687174688174689174690174691174692174693174694174695174696174697174698174699174700174701174702174703174704174705174706174707174708174709174710174711174712174713174714174715174716174717174718174719174720174721174722174723174724174725174726174727174728174729174730174731174732174733174734174735174736174737174738174739174740174741174742174743174744174745174746174747174748174749174750174751174752174753174754174755174756174757174758174759174760174761174762174763174764174765174766174767174768174769174770174771174772174773174774174775174776174777174778174779174780174781174782174783174784174785174786174787174788174789174790174791174792174793174794174795174796174797174798174799174800174801174802174803174804174805174806174807174808174809174810174811174812174813174814174815174816174817174818174819174820174821174822174823174824174825174826174827174828174829174830174831174832174833174834174835174836174837174838174839174840174841174842174843174844174845174846174847174848174849174850174851174852174853174854174855174856174857174858174859174860174861174862174863174864174865174866174867174868174869174870174871174872174873174874174875174876174877174878174879174880174881174882174883174884174885174886174887174888174889174890174891174892174893174894174895174896174897174898174899174900174901174902174903174904174905174906174907174908174909174910174911174912174913174914174915174916174917174918174919174920174921174922174923174924174925174926174927174928174929174930174931174932174933174934174935174936174937174938174939174940174941174942174943174944174945174946174947174948174949174950174951174952174953174954174955174956174957174958174959174960174961174962174963174964174965174966174967174968174969174970174971174972174973174974174975174976174977174978174979174980174981174982174983174984174985174986174987174988174989174990174991174992174993174994174995174996174997174998174999175000175001175002175003175004175005175006175007175008175009175010175011175012175013175014175015175016175017175018175019175020175021175022175023175024175025175026175027175028175029175030175031175032175033175034175035175036175037175038175039175040175041175042175043175044175045175046175047175048175049175050175051175052175053175054175055175056175057175058175059175060175061175062175063175064175065175066175067175068175069175070175071175072175073175074175075175076175077175078175079175080175081175082175083175084175085175086175087175088175089175090175091175092175093175094175095175096175097175098175099175100175101175102175103175104175105175106175107175108175109175110175111175112175113175114175115175116175117175118175119175120175121175122175123175124175125175126175127175128175129175130175131175132175133175134175135175136175137175138175139175140175141175142175143175144175145175146175147175148175149175150175151175152175153175154175155175156175157175158175159175160175161175162175163175164175165175166175167175168175169175170175171175172175173175174175175175176175177175178175179175180175181175182175183175184175185175186175187175188175189175190175191175192175193175194175195175196175197175198175199175200175201175202175203175204175205175206175207175208175209175210175211175212175213175214175215175216175217175218175219175220175221175222175223175224175225175226175227175228175229175230175231175232175233175234175235175236175237175238175239175240175241175242175243175244175245175246175247175248175249175250175251175252175253175254175255175256175257175258175259175260175261175262175263175264175265175266175267175268175269175270175271175272175273175274175275175276175277175278175279175280175281175282175283175284175285175286175287175288175289175290175291175292175293175294175295175296175297175298175299175300175301175302175303175304175305175306175307175308175309175310175311175312175313175314175315175316175317175318175319175320175321175322175323175324175325175326175327175328175329175330175331175332175333175334175335175336175337175338175339175340175341175342175343175344175345175346175347175348175349175350175351175352175353175354175355175356175357175358175359175360175361175362175363175364175365175366175367175368175369175370175371175372175373175374175375175376175377175378175379175380175381175382175383175384175385175386175387175388175389175390175391175392175393175394175395175396175397175398175399175400175401175402175403175404175405175406175407175408175409175410175411175412175413175414175415175416175417175418175419175420175421175422175423175424175425175426175427175428175429175430175431175432175433175434175435175436175437175438175439175440175441175442175443175444175445175446175447175448175449175450175451175452175453175454175455175456175457175458175459175460175461175462175463175464175465175466175467175468175469175470175471175472175473175474175475175476175477175478175479175480175481175482175483175484175485175486175487175488175489175490175491175492175493175494175495175496175497175498175499175500175501175502175503175504175505175506175507175508175509175510175511175512175513175514175515175516175517175518175519175520175521175522175523175524175525175526175527175528175529175530175531175532175533175534175535175536175537175538175539175540175541175542175543175544175545175546175547175548175549175550175551175552175553175554175555175556175557175558175559175560175561175562175563175564175565175566175567175568175569175570175571175572175573175574175575175576175577175578175579175580175581175582175583175584175585175586175587175588175589175590175591175592175593175594175595175596175597175598175599175600175601175602175603175604175605175606175607175608175609175610175611175612175613175614175615175616175617175618175619175620175621175622175623175624175625175626175627175628175629175630175631175632175633175634175635175636175637175638175639175640175641175642175643175644175645175646175647175648175649175650175651175652175653175654175655175656175657175658175659175660175661175662175663175664175665175666175667175668175669175670175671175672175673175674175675175676175677175678175679175680175681175682175683175684175685175686175687175688175689175690175691175692175693175694175695175696175697175698175699175700175701175702175703175704175705175706175707175708175709175710175711175712175713175714175715175716175717175718175719175720175721175722175723175724175725175726175727175728175729175730175731175732175733175734175735175736175737175738175739175740175741175742175743175744175745175746175747175748175749175750175751175752175753175754175755175756175757175758175759175760175761175762175763175764175765175766175767175768175769175770175771175772175773175774175775175776175777175778175779175780175781175782175783175784175785175786175787175788175789175790175791175792175793175794175795175796175797175798175799175800175801175802175803175804175805175806175807175808175809175810175811175812175813175814175815175816175817175818175819175820175821175822175823175824175825175826175827175828175829175830175831175832175833175834175835175836175837175838175839175840175841175842175843175844175845175846175847175848175849175850175851175852175853175854175855175856175857175858175859175860175861175862175863175864175865175866175867175868175869175870175871175872175873175874175875175876175877175878175879175880175881175882175883175884175885175886175887175888175889175890175891175892175893175894175895175896175897175898175899175900175901175902175903175904175905175906175907175908175909175910175911175912175913175914175915175916175917175918175919175920175921175922175923175924175925175926175927175928175929175930175931175932175933175934175935175936175937175938175939175940175941175942175943175944175945175946175947175948175949175950175951175952175953175954175955175956175957175958175959175960175961175962175963175964175965175966175967175968175969175970175971175972175973175974175975175976175977175978175979175980175981175982175983175984175985175986175987175988175989175990175991175992175993175994175995175996175997175998175999176000176001176002176003176004176005176006176007176008176009176010176011176012176013176014176015176016176017176018176019176020176021176022176023176024176025176026176027176028176029176030176031176032176033176034176035176036176037176038176039176040176041176042176043176044176045176046176047176048176049176050176051176052176053176054176055176056176057176058176059176060176061176062176063176064176065176066176067176068176069176070176071176072176073176074176075176076176077176078176079176080176081176082176083176084176085176086176087176088176089176090176091176092176093176094176095176096176097176098176099176100176101176102176103176104176105176106176107176108176109176110176111176112176113176114176115176116176117176118176119176120176121176122176123176124176125176126176127176128176129176130176131176132176133176134176135176136176137176138176139176140176141176142176143176144176145176146176147176148176149176150176151176152176153176154176155176156176157176158176159176160176161176162176163176164176165176166176167176168176169176170176171176172176173176174176175176176176177176178176179176180176181176182176183176184176185176186176187176188176189176190176191176192176193176194176195176196176197176198176199176200176201176202176203176204176205176206176207176208176209176210176211176212176213176214176215176216176217176218176219176220176221176222176223176224176225176226176227176228176229176230176231176232176233176234176235176236176237176238176239176240176241176242176243176244176245176246176247176248176249176250176251176252176253176254176255176256176257176258176259176260176261176262176263176264176265176266176267176268176269176270176271176272176273176274176275176276176277176278176279176280176281176282176283176284176285176286176287176288176289176290176291176292176293176294176295176296176297176298176299176300176301176302176303176304176305176306176307176308176309176310176311176312176313176314176315176316176317176318176319176320176321176322176323176324176325176326176327176328176329176330176331176332176333176334176335176336176337176338176339176340176341176342176343176344176345176346176347176348176349176350176351176352176353176354176355176356176357176358176359176360176361176362176363176364176365176366176367176368176369176370176371176372176373176374176375176376176377176378176379176380176381176382176383176384176385176386176387176388176389176390176391176392176393176394176395176396176397176398176399176400176401176402176403176404176405176406176407176408176409176410176411176412176413176414176415176416176417176418176419176420176421176422176423176424176425176426176427176428176429176430176431176432176433176434176435176436176437176438176439176440176441176442176443176444176445176446176447176448176449176450176451176452176453176454176455176456176457176458176459176460176461176462176463176464176465176466176467176468176469176470176471176472176473176474176475176476176477176478176479176480176481176482176483176484176485176486176487176488176489176490176491176492176493176494176495176496176497176498176499176500176501176502176503176504176505176506176507176508176509176510176511176512176513176514176515176516176517176518176519176520176521176522176523176524176525176526176527176528176529176530176531176532176533176534176535176536176537176538176539176540176541176542176543176544176545176546176547176548176549176550176551176552176553176554176555176556176557176558176559176560176561176562176563176564176565176566176567176568176569176570176571176572176573176574176575176576176577176578176579176580176581176582176583176584176585176586176587176588176589176590176591176592176593176594176595176596176597176598176599176600176601176602176603176604176605176606176607176608176609176610176611176612176613176614176615176616176617176618176619176620176621176622176623176624176625176626176627176628176629176630176631176632176633176634176635176636176637176638176639176640176641176642176643176644176645176646176647176648176649176650176651176652176653176654176655176656176657176658176659176660176661176662176663176664176665176666176667176668176669176670176671176672176673176674176675176676176677176678176679176680176681176682176683176684176685176686176687176688176689176690176691176692176693176694176695176696176697176698176699176700176701176702176703176704176705176706176707176708176709176710176711176712176713176714176715176716176717176718176719176720176721176722176723176724176725176726176727176728176729176730176731176732176733176734176735176736176737176738176739176740176741176742176743176744176745176746176747176748176749176750176751176752176753176754176755176756176757176758176759176760176761176762176763176764176765176766176767176768176769176770176771176772176773176774176775176776176777176778176779176780176781176782176783176784176785176786176787176788176789176790176791176792176793176794176795176796176797176798176799176800176801176802176803176804176805176806176807176808176809176810176811176812176813176814176815176816176817176818176819176820176821176822176823176824176825176826176827176828176829176830176831176832176833176834176835176836176837176838176839176840176841176842176843176844176845176846176847176848176849176850176851176852176853176854176855176856176857176858176859176860176861176862176863176864176865176866176867176868176869176870176871176872176873176874176875176876176877176878176879176880176881176882176883176884176885176886176887176888176889176890176891176892176893176894176895176896176897176898176899176900176901176902176903176904176905176906176907176908176909176910176911176912176913176914176915176916176917176918176919176920176921176922176923176924176925176926176927176928176929176930176931176932176933176934176935176936176937176938176939176940176941176942176943176944176945176946176947176948176949176950176951176952176953176954176955176956176957176958176959176960176961176962176963176964176965176966176967176968176969176970176971176972176973176974176975176976176977176978176979176980176981176982176983176984176985176986176987176988176989176990176991176992176993176994176995176996176997176998176999177000177001177002177003177004177005177006177007177008177009177010177011177012177013177014177015177016177017177018177019177020177021177022177023177024177025177026177027177028177029177030177031177032177033177034177035177036177037177038177039177040177041177042177043177044177045177046177047177048177049177050177051177052177053177054177055177056177057177058177059177060177061177062177063177064177065177066177067177068177069177070177071177072177073177074177075177076177077177078177079177080177081177082177083177084177085177086177087177088177089177090177091177092177093177094177095177096177097177098177099177100177101177102177103177104177105177106177107177108177109177110177111177112177113177114177115177116177117177118177119177120177121177122177123177124177125177126177127177128177129177130177131177132177133177134177135177136177137177138177139177140177141177142177143177144177145177146177147177148177149177150177151177152177153177154177155177156177157177158177159177160177161177162177163177164177165177166177167177168177169177170177171177172177173177174177175177176177177177178177179177180177181177182177183177184177185177186177187177188177189177190177191177192177193177194177195177196177197177198177199177200177201177202177203177204177205177206177207177208177209177210177211177212177213177214177215177216177217177218177219177220177221177222177223177224177225177226177227177228177229177230177231177232177233177234177235177236177237177238177239177240177241177242177243177244177245177246177247177248177249177250177251177252177253177254177255177256177257177258177259177260177261177262177263177264177265177266177267177268177269177270177271177272177273177274177275177276177277177278177279177280177281177282177283177284177285177286177287177288177289177290177291177292177293177294177295177296177297177298177299177300177301177302177303177304177305177306177307177308177309177310177311177312177313177314177315177316177317177318177319177320177321177322177323177324177325177326177327177328177329177330177331177332177333177334177335177336177337177338177339177340177341177342177343177344177345177346177347177348177349177350177351177352177353177354177355177356177357177358177359177360177361177362177363177364177365177366177367177368177369177370177371177372177373177374177375177376177377177378177379177380177381177382177383177384177385177386177387177388177389177390177391177392177393177394177395177396177397177398177399177400177401177402177403177404177405177406177407177408177409177410177411177412177413177414177415177416177417177418177419177420177421177422177423177424177425177426177427177428177429177430177431177432177433177434177435177436177437177438177439177440177441177442177443177444177445177446177447177448177449177450177451177452177453177454177455177456177457177458177459177460177461177462177463177464177465177466177467177468177469177470177471177472177473177474177475177476177477177478177479177480177481177482177483177484177485177486177487177488177489177490177491177492177493177494177495177496177497177498177499177500177501177502177503177504177505177506177507177508177509177510177511177512177513177514177515177516177517177518177519177520177521177522177523177524177525177526177527177528177529177530177531177532177533177534177535177536177537177538177539177540177541177542177543177544177545177546177547177548177549177550177551177552177553177554177555177556177557177558177559177560177561177562177563177564177565177566177567177568177569177570177571177572177573177574177575177576177577177578177579177580177581177582177583177584177585177586177587177588177589177590177591177592177593177594177595177596177597177598177599177600177601177602177603177604177605177606177607177608177609177610177611177612177613177614177615177616177617177618177619177620177621177622177623177624177625177626177627177628177629177630177631177632177633177634177635177636177637177638177639177640177641177642177643177644177645177646177647177648177649177650177651177652177653177654177655177656177657177658177659177660177661177662177663177664177665177666177667177668177669177670177671177672177673177674177675177676177677177678177679177680177681177682177683177684177685177686177687177688177689177690177691177692177693177694177695177696177697177698177699177700177701177702177703177704177705177706177707177708177709177710177711177712177713177714177715177716177717177718177719177720177721177722177723177724177725177726177727177728177729177730177731177732177733177734177735177736177737177738177739177740177741177742177743177744177745177746177747177748177749177750177751177752177753177754177755177756177757177758177759177760177761177762177763177764177765177766177767177768177769177770177771177772177773177774177775177776177777177778177779177780177781177782177783177784177785177786177787177788177789177790177791177792177793177794177795177796177797177798177799177800177801177802177803177804177805177806177807177808177809177810177811177812177813177814177815177816177817177818177819177820177821177822177823177824177825177826177827177828177829177830177831177832177833177834177835177836177837177838177839177840177841177842177843177844177845177846177847177848177849177850177851177852177853177854177855177856177857177858177859177860177861177862177863177864177865177866177867177868177869177870177871177872177873177874177875177876177877177878177879177880177881177882177883177884177885177886177887177888177889177890177891177892177893177894177895177896177897177898177899177900177901177902177903177904177905177906177907177908177909177910177911177912177913177914177915177916177917177918177919177920177921177922177923177924177925177926177927177928177929177930177931177932177933177934177935177936177937177938177939177940177941177942177943177944177945177946177947177948177949177950177951177952177953177954177955177956177957177958177959177960177961177962177963177964177965177966177967177968177969177970177971177972177973177974177975177976177977177978177979177980177981177982177983177984177985177986177987177988177989177990177991177992177993177994177995177996177997177998177999178000178001178002178003178004178005178006178007178008178009178010178011178012178013178014178015178016178017178018178019178020178021178022178023178024178025178026178027178028178029178030178031178032178033178034178035178036178037178038178039178040178041178042178043178044178045178046178047178048178049178050178051178052178053178054178055178056178057178058178059178060178061178062178063178064178065178066178067178068178069178070178071178072178073178074178075178076178077178078178079178080178081178082178083178084178085178086178087178088178089178090178091178092178093178094178095178096178097178098178099178100178101178102178103178104178105178106178107178108178109178110178111178112178113178114178115178116178117178118178119178120178121178122178123178124178125178126178127178128178129178130178131178132178133178134178135178136178137178138178139178140178141178142178143178144178145178146178147178148178149178150178151178152178153178154178155178156178157178158178159178160178161178162178163178164178165178166178167178168178169178170178171178172178173178174178175178176178177178178178179178180178181178182178183178184178185178186178187178188178189178190178191178192178193178194178195178196178197178198178199178200178201178202178203178204178205178206178207178208178209178210178211178212178213178214178215178216178217178218178219178220178221178222178223178224178225178226178227178228178229178230178231178232178233178234178235178236178237178238178239178240178241178242178243178244178245178246178247178248178249178250178251178252178253178254178255178256178257178258178259178260178261178262178263178264178265178266178267178268178269178270178271178272178273178274178275178276178277178278178279178280178281178282178283178284178285178286178287178288178289178290178291178292178293178294178295178296178297178298178299178300178301178302178303178304178305178306178307178308178309178310178311178312178313178314178315178316178317178318178319178320178321178322178323178324178325178326178327178328178329178330178331178332178333178334178335178336178337178338178339178340178341178342178343178344178345178346178347178348178349178350178351178352178353178354178355178356178357178358178359178360178361178362178363178364178365178366178367178368178369178370178371178372178373178374178375178376178377178378178379178380178381178382178383178384178385178386178387178388178389178390178391178392178393178394178395178396178397178398178399178400178401178402178403178404178405178406178407178408178409178410178411178412178413178414178415178416178417178418178419178420178421178422178423178424178425178426178427178428178429178430178431178432178433178434178435178436178437178438178439178440178441178442178443178444178445178446178447178448178449178450178451178452178453178454178455178456178457178458178459178460178461178462178463178464178465178466178467178468178469178470178471178472178473178474178475178476178477178478178479178480178481178482178483178484178485178486178487178488178489178490178491178492178493178494178495178496178497178498178499178500178501178502178503178504178505178506178507178508178509178510178511178512178513178514178515178516178517178518178519178520178521178522178523178524178525178526178527178528178529178530178531178532178533178534178535178536178537178538178539178540178541178542178543178544178545178546178547178548178549178550178551178552178553178554178555178556178557178558178559178560178561178562178563178564178565178566178567178568178569178570178571178572178573178574178575178576178577178578178579178580178581178582178583178584178585178586178587178588178589178590178591178592178593178594178595178596178597178598178599178600178601178602178603178604178605178606178607178608178609178610178611178612178613178614178615178616178617178618178619178620178621178622178623178624178625178626178627178628178629178630178631178632178633178634178635178636178637178638178639178640178641178642178643178644178645178646178647178648178649178650178651178652178653178654178655178656178657178658178659178660178661178662178663178664178665178666178667178668178669178670178671178672178673178674178675178676178677178678178679178680178681178682178683178684178685178686178687178688178689178690178691178692178693178694178695178696178697178698178699178700178701178702178703178704178705178706178707178708178709178710178711178712178713178714178715178716178717178718178719178720178721178722178723178724178725178726178727178728178729178730178731178732178733178734178735178736178737178738178739178740178741178742178743178744178745178746178747178748178749178750178751178752178753178754178755178756178757178758178759178760178761178762178763178764178765178766178767178768178769178770178771178772178773178774178775178776178777178778178779178780178781178782178783178784178785178786178787178788178789178790178791178792178793178794178795178796178797178798178799178800178801178802178803178804178805178806178807178808178809178810178811178812178813178814178815178816178817178818178819178820178821178822178823178824178825178826178827178828178829178830178831178832178833178834178835178836178837178838178839178840178841178842178843178844178845178846178847178848178849178850178851178852178853178854178855178856178857178858178859178860178861178862178863178864178865178866178867178868178869178870178871178872178873178874178875178876178877178878178879178880178881178882178883178884178885178886178887178888178889178890178891178892178893178894178895178896178897178898178899178900178901178902178903178904178905178906178907178908178909178910178911178912178913178914178915178916178917178918178919178920178921178922178923178924178925178926178927178928178929178930178931178932178933178934178935178936178937178938178939178940178941178942178943178944178945178946178947178948178949178950178951178952178953178954178955178956178957178958178959178960178961178962178963178964178965178966178967178968178969178970178971178972178973178974178975178976178977178978178979178980178981178982178983178984178985178986178987178988178989178990178991178992178993178994178995178996178997178998178999179000179001179002179003179004179005179006179007179008179009179010179011179012179013179014179015179016179017179018179019179020179021179022179023179024179025179026179027179028179029179030179031179032179033179034179035179036179037179038179039179040179041179042179043179044179045179046179047179048179049179050179051179052179053179054179055179056179057179058179059179060179061179062179063179064179065179066179067179068179069179070179071179072179073179074179075179076179077179078179079179080179081179082179083179084179085179086179087179088179089179090179091179092179093179094179095179096179097179098179099179100179101179102179103179104179105179106179107179108179109179110179111179112179113179114179115179116179117179118179119179120179121179122179123179124179125179126179127179128179129179130179131179132179133179134179135179136179137179138179139179140179141179142179143179144179145179146179147179148179149179150179151179152179153179154179155179156179157179158179159179160179161179162179163179164179165179166179167179168179169179170179171179172179173179174179175179176179177179178179179179180179181179182179183179184179185179186179187179188179189179190179191179192179193179194179195179196179197179198179199179200179201179202179203179204179205179206179207179208179209179210179211179212179213179214179215179216179217179218179219179220179221179222179223179224179225179226179227179228179229179230179231179232179233179234179235179236179237179238179239179240179241179242179243179244179245179246179247179248179249179250179251179252179253179254179255179256179257179258179259179260179261179262179263179264179265179266179267179268179269179270179271179272179273179274179275179276179277179278179279179280179281179282179283179284179285179286179287179288179289179290179291179292179293179294179295179296179297179298179299179300179301179302179303179304179305179306179307179308179309179310179311179312179313179314179315179316179317179318179319179320179321179322179323179324179325179326179327179328179329179330179331179332179333179334179335179336179337179338179339179340179341179342179343179344179345179346179347179348179349179350179351179352179353179354179355179356179357179358179359179360179361179362179363179364179365179366179367179368179369179370179371179372179373179374179375179376179377179378179379179380179381179382179383179384179385179386179387179388179389179390179391179392179393179394179395179396179397179398179399179400179401179402179403179404179405179406179407179408179409179410179411179412179413179414179415179416179417179418179419179420179421179422179423179424179425179426179427179428179429179430179431179432179433179434179435179436179437179438179439179440179441179442179443179444179445179446179447179448179449179450179451179452179453179454179455179456179457179458179459179460179461179462179463179464179465179466179467179468179469179470179471179472179473179474179475179476179477179478179479179480179481179482179483179484179485179486179487179488179489179490179491179492179493179494179495179496179497179498179499179500179501179502179503179504179505179506179507179508179509179510179511179512179513179514179515179516179517179518179519179520179521179522179523179524179525179526179527179528179529179530179531179532179533179534179535179536179537179538179539179540179541179542179543179544179545179546179547179548179549179550179551179552179553179554179555179556179557179558179559179560179561179562179563179564179565179566179567179568179569179570179571179572179573179574179575179576179577179578179579179580179581179582179583179584179585179586179587179588179589179590179591179592179593179594179595179596179597179598179599179600179601179602179603179604179605179606179607179608179609179610179611179612179613179614179615179616179617179618179619179620179621179622179623179624179625179626179627179628179629179630179631179632179633179634179635179636179637179638179639179640179641179642179643179644179645179646179647179648179649179650179651179652179653179654179655179656179657179658179659179660179661179662179663179664179665179666179667179668179669179670179671179672179673179674179675179676179677179678179679179680179681179682179683179684179685179686179687179688179689179690179691179692179693179694179695179696179697179698179699179700179701179702179703179704179705179706179707179708179709179710179711179712179713179714179715179716179717179718179719179720179721179722179723179724179725179726179727179728179729179730179731179732179733179734179735179736179737179738179739179740179741179742179743179744179745179746179747179748179749179750179751179752179753179754179755179756179757179758179759179760179761179762179763179764179765179766179767179768179769179770179771179772179773179774179775179776179777179778179779179780179781179782179783179784179785179786179787179788179789179790179791179792179793179794179795179796179797179798179799179800179801179802179803179804179805179806179807179808179809179810179811179812179813179814179815179816179817179818179819179820179821179822179823179824179825179826179827179828179829179830179831179832179833179834179835179836179837179838179839179840179841179842179843179844179845179846179847179848179849179850179851179852179853179854179855179856179857179858179859179860179861179862179863179864179865179866179867179868179869179870179871179872179873179874179875179876179877179878179879179880179881179882179883179884179885179886179887179888179889179890179891179892179893179894179895179896179897179898179899179900179901179902179903179904179905179906179907179908179909179910179911179912179913179914179915179916179917179918179919179920179921179922179923179924179925179926179927179928179929179930179931179932179933179934179935179936179937179938179939179940179941179942179943179944179945179946179947179948179949179950179951179952179953179954179955179956179957179958179959179960179961179962179963179964179965179966179967179968179969179970179971179972179973179974179975179976179977179978179979179980179981179982179983179984179985179986179987179988179989179990179991179992179993179994179995179996179997179998179999180000180001180002180003180004180005180006180007180008180009180010180011180012180013180014180015180016180017180018180019180020180021180022180023180024180025180026180027180028180029180030180031180032180033180034180035180036180037180038180039180040180041180042180043180044180045180046180047180048180049180050180051180052180053180054180055180056180057180058180059180060180061180062180063180064180065180066180067180068180069180070180071180072180073180074180075180076180077180078180079180080180081180082180083180084180085180086180087180088180089180090180091180092180093180094180095180096180097180098180099180100180101180102180103180104180105180106180107180108180109180110180111180112180113180114180115180116180117180118180119180120180121180122180123180124180125180126180127180128180129180130180131180132180133180134180135180136180137180138180139180140180141180142180143180144180145180146180147180148180149180150180151180152180153180154180155180156180157180158180159180160180161180162180163180164180165180166180167180168180169180170180171180172180173180174180175180176180177180178180179180180180181180182180183180184180185180186180187180188180189180190180191180192180193180194180195180196180197180198180199180200180201180202180203180204180205180206180207180208180209180210180211180212180213180214180215180216180217180218180219180220180221180222180223180224180225180226180227180228180229180230180231180232180233180234180235180236180237180238180239180240180241180242180243180244180245180246180247180248180249180250180251180252180253180254180255180256180257180258180259180260180261180262180263180264180265180266180267180268180269180270180271180272180273180274180275180276180277180278180279180280180281180282180283180284180285180286180287180288180289180290180291180292180293180294180295180296180297180298180299180300180301180302180303180304180305180306180307180308180309180310180311180312180313180314180315180316180317180318180319180320180321180322180323180324180325180326180327180328180329180330180331180332180333180334180335180336180337180338180339180340180341180342180343180344180345180346180347180348180349180350180351180352180353180354180355180356180357180358180359180360180361180362180363180364180365180366180367180368180369180370180371180372180373180374180375180376180377180378180379180380180381180382180383180384180385180386180387180388180389180390180391180392180393180394180395180396180397180398180399180400180401180402180403180404180405180406180407180408180409180410180411180412180413180414180415180416180417180418180419180420180421180422180423180424180425180426180427180428180429180430180431180432180433180434180435180436180437180438180439180440180441180442180443180444180445180446180447180448180449180450180451180452180453180454180455180456180457180458180459180460180461180462180463180464180465180466180467180468180469180470180471180472180473180474180475180476180477180478180479180480180481180482180483180484180485180486180487180488180489180490180491180492180493180494180495180496180497180498180499180500180501180502180503180504180505180506180507180508180509180510180511180512180513180514180515180516180517180518180519180520180521180522180523180524180525180526180527180528180529180530180531180532180533180534180535180536180537180538180539180540180541180542180543180544180545180546180547180548180549180550180551180552180553180554180555180556180557180558180559180560180561180562180563180564180565180566180567180568180569180570180571180572180573180574180575180576180577180578180579180580180581180582180583180584180585180586180587180588180589180590180591180592180593180594180595180596180597180598180599180600180601180602180603180604180605180606180607180608180609180610180611180612180613180614180615180616180617180618180619180620180621180622180623180624180625180626180627180628180629180630180631180632180633180634180635180636180637180638180639180640180641180642180643180644180645180646180647180648180649180650180651180652180653180654180655180656180657180658180659180660180661180662180663180664180665180666180667180668180669180670180671180672180673180674180675180676180677180678180679180680180681180682180683180684180685180686180687180688180689180690180691180692180693180694180695180696180697180698180699180700180701180702180703180704180705180706180707180708180709180710180711180712180713180714180715180716180717180718180719180720180721180722180723180724180725180726180727180728180729180730180731180732180733180734180735180736180737180738180739180740180741180742180743180744180745180746180747180748180749180750180751180752180753180754180755180756180757180758180759180760180761180762180763180764180765180766180767180768180769180770180771180772180773180774180775180776180777180778180779180780180781180782180783180784180785180786180787180788180789180790180791180792180793180794180795180796180797180798180799180800180801180802180803180804180805180806180807180808180809180810180811180812180813180814180815180816180817180818180819180820180821180822180823180824180825180826180827180828180829180830180831180832180833180834180835180836180837180838180839180840180841180842180843180844180845180846180847180848180849180850180851180852180853180854180855180856180857180858180859180860180861180862180863180864180865180866180867180868180869180870180871180872180873180874180875180876180877180878180879180880180881180882180883180884180885180886180887180888180889180890180891180892180893180894180895180896180897180898180899180900180901180902180903180904180905180906180907180908180909180910180911180912180913180914180915180916180917180918180919180920180921180922180923180924180925180926180927180928180929180930180931180932180933180934180935180936180937180938180939180940180941180942180943180944180945180946180947180948180949180950180951180952180953180954180955180956180957180958180959180960180961180962180963180964180965180966180967180968180969180970180971180972180973180974180975180976180977180978180979180980180981180982180983180984180985180986180987180988180989180990180991180992180993180994180995180996180997180998180999181000181001181002181003181004181005181006181007181008181009181010181011181012181013181014181015181016181017181018181019181020181021181022181023181024181025181026181027181028181029181030181031181032181033181034181035181036181037181038181039181040181041181042181043181044181045181046181047181048181049181050181051181052181053181054181055181056181057181058181059181060181061181062181063181064181065181066181067181068181069181070181071181072181073181074181075181076181077181078181079181080181081181082181083181084181085181086181087181088181089181090181091181092181093181094181095181096181097181098181099181100181101181102181103181104181105181106181107181108181109181110181111181112181113181114181115181116181117181118181119181120181121181122181123181124181125181126181127181128181129181130181131181132181133181134181135181136181137181138181139181140181141181142181143181144181145181146181147181148181149181150181151181152181153181154181155181156181157181158181159181160181161181162181163181164181165181166181167181168181169181170181171181172181173181174181175181176181177181178181179181180181181181182181183181184181185181186181187181188181189181190181191181192181193181194181195181196181197181198181199181200181201181202181203181204181205181206181207181208181209181210181211181212181213181214181215181216181217181218181219181220181221181222181223181224181225181226181227181228181229181230181231181232181233181234181235181236181237181238181239181240181241181242181243181244181245181246181247181248181249181250181251181252181253181254181255181256181257181258181259181260181261181262181263181264181265181266181267181268181269181270181271181272181273181274181275181276181277181278181279181280181281181282181283181284181285181286181287181288181289181290181291181292181293181294181295181296181297181298181299181300181301181302181303181304181305181306181307181308181309181310181311181312181313181314181315181316181317181318181319181320181321181322181323181324181325181326181327181328181329181330181331181332181333181334181335181336181337181338181339181340181341181342181343181344181345181346181347181348181349181350181351181352181353181354181355181356181357181358181359181360181361181362181363181364181365181366181367181368181369181370181371181372181373181374181375181376181377181378181379181380181381181382181383181384181385181386181387181388181389181390181391181392181393181394181395181396181397181398181399181400181401181402181403181404181405181406181407181408181409181410181411181412181413181414181415181416181417181418181419181420181421181422181423181424181425181426181427181428181429181430181431181432181433181434181435181436181437181438181439181440181441181442181443181444181445181446181447181448181449181450181451181452181453181454181455181456181457181458181459181460181461181462181463181464181465181466181467181468181469181470181471181472181473181474181475181476181477181478181479181480181481181482181483181484181485181486181487181488181489181490181491181492181493181494181495181496181497181498181499181500181501181502181503181504181505181506181507181508181509181510181511181512181513181514181515181516181517181518181519181520181521181522181523181524181525181526181527181528181529181530181531181532181533181534181535181536181537181538181539181540181541181542181543181544181545181546181547181548181549181550181551181552181553181554181555181556181557181558181559181560181561181562181563181564181565181566181567181568181569181570181571181572181573181574181575181576181577181578181579181580181581181582181583181584181585181586181587181588181589181590181591181592181593181594181595181596181597181598181599181600181601181602181603181604181605181606181607181608181609181610181611181612181613181614181615181616181617181618181619181620181621181622181623181624181625181626181627181628181629181630181631181632181633181634181635181636181637181638181639181640181641181642181643181644181645181646181647181648181649181650181651181652181653181654181655181656181657181658181659181660181661181662181663181664181665181666181667181668181669181670181671181672181673181674181675181676181677181678181679181680181681181682181683181684181685181686181687181688181689181690181691181692181693181694181695181696181697181698181699181700181701181702181703181704181705181706181707181708181709181710181711181712181713181714181715181716181717181718181719181720181721181722181723181724181725181726181727181728181729181730181731181732181733181734181735181736181737181738181739181740181741181742181743181744181745181746181747181748181749181750181751181752181753181754181755181756181757181758181759181760181761181762181763181764181765181766181767181768181769181770181771181772181773181774181775181776181777181778181779181780181781181782181783181784181785181786181787181788181789181790181791181792181793181794181795181796181797181798181799181800181801181802181803181804181805181806181807181808181809181810181811181812181813181814181815181816181817181818181819181820181821181822181823181824181825181826181827181828181829181830181831181832181833181834181835181836181837181838181839181840181841181842181843181844181845181846181847181848181849181850181851181852181853181854181855181856181857181858181859181860181861181862181863181864181865181866181867181868181869181870181871181872181873181874181875181876181877181878181879181880181881181882181883181884181885181886181887181888181889181890181891181892181893181894181895181896181897181898181899181900181901181902181903181904181905181906181907181908181909181910181911181912181913181914181915181916181917181918181919181920181921181922181923181924181925181926181927181928181929181930181931181932181933181934181935181936181937181938181939181940181941181942181943181944181945181946181947181948181949181950181951181952181953181954181955181956181957181958181959181960181961181962181963181964181965181966181967181968181969181970181971181972181973181974181975181976181977181978181979181980181981181982181983181984181985181986181987181988181989181990181991181992181993181994181995181996181997181998181999182000182001182002182003182004182005182006182007182008182009182010182011182012182013182014182015182016182017182018182019182020182021182022182023182024182025182026182027182028182029182030182031182032182033182034182035182036182037182038182039182040182041182042182043182044182045182046182047182048182049182050182051182052182053182054182055182056182057182058182059182060182061182062182063182064182065182066182067182068182069182070182071182072182073182074182075182076182077182078182079182080182081182082182083182084182085182086182087182088182089182090182091182092182093182094182095182096182097182098182099182100182101182102182103182104182105182106182107182108182109182110182111182112182113182114182115182116182117182118182119182120182121182122182123182124182125182126182127182128182129182130182131182132182133182134182135182136182137182138182139182140182141182142182143182144182145182146182147182148182149182150182151182152182153182154182155182156182157182158182159182160182161182162182163182164182165182166182167182168182169182170182171182172182173182174182175182176182177182178182179182180182181182182182183182184182185182186182187182188182189182190182191182192182193182194182195182196182197182198182199182200182201182202182203182204182205182206182207182208182209182210182211182212182213182214182215182216182217182218182219182220182221182222182223182224182225182226182227182228182229182230182231182232182233182234182235182236182237182238182239182240182241182242182243182244182245182246182247182248182249182250182251182252182253182254182255182256182257182258182259182260182261182262182263182264182265182266182267182268182269182270182271182272182273182274182275182276182277182278182279182280182281182282182283182284182285182286182287182288182289182290182291182292182293182294182295182296182297182298182299182300182301182302182303182304182305182306182307182308182309182310182311182312182313182314182315182316182317182318182319182320182321182322182323182324182325182326182327182328182329182330182331182332182333182334182335182336182337182338182339182340182341182342182343182344182345182346182347182348182349182350182351182352182353182354182355182356182357182358182359182360182361182362182363182364182365182366182367182368182369182370182371182372182373182374182375182376182377182378182379182380182381182382182383182384182385182386182387182388182389182390182391182392182393182394182395182396182397182398182399182400182401182402182403182404182405182406182407182408182409182410182411182412182413182414182415182416182417182418182419182420182421182422182423182424182425182426182427182428182429182430182431182432182433182434182435182436182437182438182439182440182441182442182443182444182445182446182447182448182449182450182451182452182453182454182455182456182457182458182459182460182461182462182463182464182465182466182467182468182469182470182471182472182473182474182475182476182477182478182479182480182481182482182483182484182485182486182487182488182489182490182491182492182493182494182495182496182497182498182499182500182501182502182503182504182505182506182507182508182509182510182511182512182513182514182515182516182517182518182519182520182521182522182523182524182525182526182527182528182529182530182531182532182533182534182535182536182537182538182539182540182541182542182543182544182545182546182547182548182549182550182551182552182553182554182555182556182557182558182559182560182561182562182563182564182565182566182567182568182569182570182571182572182573182574182575182576182577182578182579182580182581182582182583182584182585182586182587182588182589182590182591182592182593182594182595182596182597182598182599182600182601182602182603182604182605182606182607182608182609182610182611182612182613182614182615182616182617182618182619182620182621182622182623182624182625182626182627182628182629182630182631182632182633182634182635182636182637182638182639182640182641182642182643182644182645182646182647182648182649182650182651182652182653182654182655182656182657182658182659182660182661182662182663182664182665182666182667182668182669182670182671182672182673182674182675182676182677182678182679182680182681182682182683182684182685182686182687182688182689182690182691182692182693182694182695182696182697182698182699182700182701182702182703182704182705182706182707182708182709182710182711182712182713182714182715182716182717182718182719182720182721182722182723182724182725182726182727182728182729182730182731182732182733182734182735182736182737182738182739182740182741182742182743182744182745182746182747182748182749182750182751182752182753182754182755182756182757182758182759182760182761182762182763182764182765182766182767182768182769182770182771182772182773182774182775182776182777182778182779182780182781182782182783182784182785182786182787182788182789182790182791182792182793182794182795182796182797182798182799182800182801182802182803182804182805182806182807182808182809182810182811182812182813182814182815182816182817182818182819182820182821182822182823182824182825182826182827182828182829182830182831182832182833182834182835182836182837182838182839182840182841182842182843182844182845182846182847182848182849182850182851182852182853182854182855182856182857182858182859182860182861182862182863182864182865182866182867182868182869182870182871182872182873182874182875182876182877182878182879182880182881182882182883182884182885182886182887182888182889182890182891182892182893182894182895182896182897182898182899182900182901182902182903182904182905182906182907182908182909182910182911182912182913182914182915182916182917182918182919182920182921182922182923182924182925182926182927182928182929182930182931182932182933182934182935182936182937182938182939182940182941182942182943182944182945182946182947182948182949182950182951182952182953182954182955182956182957182958182959182960182961182962182963182964182965182966182967182968182969182970182971182972182973182974182975182976182977182978182979182980182981182982182983182984182985182986182987182988182989182990182991182992182993182994182995182996182997182998182999183000183001183002183003183004183005183006183007183008183009183010183011183012183013183014183015183016183017183018183019183020183021183022183023183024183025183026183027183028183029183030183031183032183033183034183035183036183037183038183039183040183041183042183043183044183045183046183047183048183049183050183051183052183053183054183055183056183057183058183059183060183061183062183063183064183065183066183067183068183069183070183071183072183073183074183075183076183077183078183079183080183081183082183083183084183085183086183087183088183089183090183091183092183093183094183095183096183097183098183099183100183101183102183103183104183105183106183107183108183109183110183111183112183113183114183115183116183117183118183119183120183121183122183123183124183125183126183127183128183129183130183131183132183133183134183135183136183137183138183139183140183141183142183143183144183145183146183147183148183149183150183151183152183153183154183155183156183157183158183159183160183161183162183163183164183165183166183167183168183169183170183171183172183173183174183175183176183177183178183179183180183181183182183183183184183185183186183187183188183189183190183191183192183193183194183195183196183197183198183199183200183201183202183203183204183205183206183207183208183209183210183211183212183213183214183215183216183217183218183219183220183221183222183223183224183225183226183227183228183229183230183231183232183233183234183235183236183237183238183239183240183241183242183243183244183245183246183247183248183249183250183251183252183253183254183255183256183257183258183259183260183261183262183263183264183265183266183267183268183269183270183271183272183273183274183275183276183277183278183279183280183281183282183283183284183285183286183287183288183289183290183291183292183293183294183295183296183297183298183299183300183301183302183303183304183305183306183307183308183309183310183311183312183313183314183315183316183317183318183319183320183321183322183323183324183325183326183327183328183329183330183331183332183333183334183335183336183337183338183339183340183341183342183343183344183345183346183347183348183349183350183351183352183353183354183355183356183357183358183359183360183361183362183363183364183365183366183367183368183369183370183371183372183373183374183375183376183377183378183379183380183381183382183383183384183385183386183387183388183389183390183391183392183393183394183395183396183397183398183399183400183401183402183403183404183405183406183407183408183409183410183411183412183413183414183415183416183417183418183419183420183421183422183423183424183425183426183427183428183429183430183431183432183433183434183435183436183437183438183439183440183441183442183443183444183445183446183447183448183449183450183451183452183453183454183455183456183457183458183459183460183461183462183463183464183465183466183467183468183469183470183471183472183473183474183475183476183477183478183479183480183481183482183483183484183485183486183487183488183489183490183491183492183493183494183495183496183497183498183499183500183501183502183503183504183505183506183507183508183509183510183511183512183513183514183515183516183517183518183519183520183521183522183523183524183525183526183527183528183529183530183531183532183533183534183535183536183537183538183539183540183541183542183543183544183545183546183547183548183549183550183551183552183553183554183555183556183557183558183559183560183561183562183563183564183565183566183567183568183569183570183571183572183573183574183575183576183577183578183579183580183581183582183583183584183585183586183587183588183589183590183591183592183593183594183595183596183597183598183599183600183601183602183603183604183605183606183607183608183609183610183611183612183613183614183615183616183617183618183619183620183621183622183623183624183625183626183627183628183629183630183631183632183633183634183635183636183637183638183639183640183641183642183643183644183645183646183647183648183649183650183651183652183653183654183655183656183657183658183659183660183661183662183663183664183665183666183667183668183669183670183671183672183673183674183675183676183677183678183679183680183681183682183683183684183685183686183687183688183689183690183691183692183693183694183695183696183697183698183699183700183701183702183703183704183705183706183707183708183709183710183711183712183713183714183715183716183717183718183719183720183721183722183723183724183725183726183727183728183729183730183731183732183733183734183735183736183737183738183739183740183741183742183743183744183745183746183747183748183749183750183751183752183753183754183755183756183757183758183759183760183761183762183763183764183765183766183767183768183769183770183771183772183773183774183775183776183777183778183779183780183781183782183783183784183785183786183787183788183789183790183791183792183793183794183795183796183797183798183799183800183801183802183803183804183805183806183807183808183809183810183811183812183813183814183815183816183817183818183819183820183821183822183823183824183825183826183827183828183829183830183831183832183833183834183835183836183837183838183839183840183841183842183843183844183845183846183847183848183849183850183851183852183853183854183855183856183857183858183859183860183861183862183863183864183865183866183867183868183869183870183871183872183873183874183875183876183877183878183879183880183881183882183883183884183885183886183887183888183889183890183891183892183893183894183895183896183897183898183899183900183901183902183903183904183905183906183907183908183909183910183911183912183913183914183915183916183917183918183919183920183921183922183923183924183925183926183927183928183929183930183931183932183933183934183935183936183937183938183939183940183941183942183943183944183945183946183947183948183949183950183951183952183953183954183955183956183957183958183959183960183961183962183963183964183965183966183967183968183969183970183971183972183973183974183975183976183977183978183979183980183981183982183983183984183985183986183987183988183989183990183991183992183993183994183995183996183997183998183999184000184001184002184003184004184005184006184007184008184009184010184011184012184013184014184015184016184017184018184019184020184021184022184023184024184025184026184027184028184029184030184031184032184033184034184035184036184037184038184039184040184041184042184043184044184045184046184047184048184049184050184051184052184053184054184055184056184057184058184059184060184061184062184063184064184065184066184067184068184069184070184071184072184073184074184075184076184077184078184079184080184081184082184083184084184085184086184087184088184089184090184091184092184093184094184095184096184097184098184099184100184101184102184103184104184105184106184107184108184109184110184111184112184113184114184115184116184117184118184119184120184121184122184123184124184125184126184127184128184129184130184131184132184133184134184135184136184137184138184139184140184141184142184143184144184145184146184147184148184149184150184151184152184153184154184155184156184157184158184159184160184161184162184163184164184165184166184167184168184169184170184171184172184173184174184175184176184177184178184179184180184181184182184183184184184185184186184187184188184189184190184191184192184193184194184195184196184197184198184199184200184201184202184203184204184205184206184207184208184209184210184211184212184213184214184215184216184217184218184219184220184221184222184223184224184225184226184227184228184229184230184231184232184233184234184235184236184237184238184239184240184241184242184243184244184245184246184247184248184249184250184251184252184253184254184255184256184257184258184259184260184261184262184263184264184265184266184267184268184269184270184271184272184273184274184275184276184277184278184279184280184281184282184283184284184285184286184287184288184289184290184291184292184293184294184295184296184297184298184299184300184301184302184303184304184305184306184307184308184309184310184311184312184313184314184315184316184317184318184319184320184321184322184323184324184325184326184327184328184329184330184331184332184333184334184335184336184337184338184339184340184341184342184343184344184345184346184347184348184349184350184351184352184353184354184355184356184357184358184359184360184361184362184363184364184365184366184367184368184369184370184371184372184373184374184375184376184377184378184379184380184381184382184383184384184385184386184387184388184389184390184391184392184393184394184395184396184397184398184399184400184401184402184403184404184405184406184407184408184409184410184411184412184413184414184415184416184417184418184419184420184421184422184423184424184425184426184427184428184429184430184431184432184433184434184435184436184437184438184439184440184441184442184443184444184445184446184447184448184449184450184451184452184453184454184455184456184457184458184459184460184461184462184463184464184465184466184467184468184469184470184471184472184473184474184475184476184477184478184479184480184481184482184483184484184485184486184487184488184489184490184491184492184493184494184495184496184497184498184499184500184501184502184503184504184505184506184507184508184509184510184511184512184513184514184515184516184517184518184519184520184521184522184523184524184525184526184527184528184529184530184531184532184533184534184535184536184537184538184539184540184541184542184543184544184545184546184547184548184549184550184551184552184553184554184555184556184557184558184559184560184561184562184563184564184565184566184567184568184569184570184571184572184573184574184575184576184577184578184579184580184581184582184583184584184585184586184587184588184589184590184591184592184593184594184595184596184597184598184599184600184601184602184603184604184605184606184607184608184609184610184611184612184613184614184615184616184617184618184619184620184621184622184623184624184625184626184627184628184629184630184631184632184633184634184635184636184637184638184639184640184641184642184643184644184645184646184647184648184649184650184651184652184653184654184655184656184657184658184659184660184661184662184663184664184665184666184667184668184669184670184671184672184673184674184675184676184677184678184679184680184681184682184683184684184685184686184687184688184689184690184691184692184693184694184695184696184697184698184699184700184701184702184703184704184705184706184707184708184709184710184711184712184713184714184715184716184717184718184719184720184721184722184723184724184725184726184727184728184729184730184731184732184733184734184735184736184737184738184739184740184741184742184743184744184745184746184747184748184749184750184751184752184753184754184755184756184757184758184759184760184761184762184763184764184765184766184767184768184769184770184771184772184773184774184775184776184777184778184779184780184781184782184783184784184785184786184787184788184789184790184791184792184793184794184795184796184797184798184799184800184801184802184803184804184805184806184807184808184809184810184811184812184813184814184815184816184817184818184819184820184821184822184823184824184825184826184827184828184829184830184831184832184833184834184835184836184837184838184839184840184841184842184843184844184845184846184847184848184849184850184851184852184853184854184855184856184857184858184859184860184861184862184863184864184865184866184867184868184869184870184871184872184873184874184875184876184877184878184879184880184881184882184883184884184885184886184887184888184889184890184891184892184893184894184895184896184897184898184899184900184901184902184903184904184905184906184907184908184909184910184911184912184913184914184915184916184917184918184919184920184921184922184923184924184925184926184927184928184929184930184931184932184933184934184935184936184937184938184939184940184941184942184943184944184945184946184947184948184949184950184951184952184953184954184955184956184957184958184959184960184961184962184963184964184965184966184967184968184969184970184971184972184973184974184975184976184977184978184979184980184981184982184983184984184985184986184987184988184989184990184991184992184993184994184995184996184997184998184999185000185001185002185003185004185005185006185007185008185009185010185011185012185013185014185015185016185017185018185019185020185021185022185023185024185025185026185027185028185029185030185031185032185033185034185035185036185037185038185039185040185041185042185043185044185045185046185047185048185049185050185051185052185053185054185055185056185057185058185059185060185061185062185063185064185065185066185067185068185069185070185071185072185073185074185075185076185077185078185079185080185081185082185083185084185085185086185087185088185089185090185091185092185093185094185095185096185097185098185099185100185101185102185103185104185105185106185107185108185109185110185111185112185113185114185115185116185117185118185119185120185121185122185123185124185125185126185127185128185129185130185131185132185133185134185135185136185137185138185139185140185141185142185143185144185145185146185147185148185149185150185151185152185153185154185155185156185157185158185159185160185161185162185163185164185165185166185167185168185169185170185171185172185173185174185175185176185177185178185179185180185181185182185183185184185185185186185187185188185189185190185191185192185193185194185195185196185197185198185199185200185201185202185203185204185205185206185207185208185209185210185211185212185213185214185215185216185217185218185219185220185221185222185223185224185225185226185227185228185229185230185231185232185233185234185235185236185237185238185239185240185241185242185243185244185245185246185247185248185249185250185251185252185253185254185255185256185257185258185259185260185261185262185263185264185265185266185267185268185269185270185271185272185273185274185275185276185277185278185279185280185281185282185283185284185285185286185287185288185289185290185291185292185293185294185295185296185297185298185299185300185301185302185303185304185305185306185307185308185309185310185311185312185313185314185315185316185317185318185319185320185321185322185323185324185325185326185327185328185329185330185331185332185333185334185335185336185337185338185339185340185341185342185343185344185345185346185347185348185349185350185351185352185353185354185355185356185357185358185359185360185361185362185363185364185365185366185367185368185369185370185371185372185373185374185375185376185377185378185379185380185381185382185383185384185385185386185387185388185389185390185391185392185393185394185395185396185397185398185399185400185401185402185403185404185405185406185407185408185409185410185411185412185413185414185415185416185417185418185419185420185421185422185423185424185425185426185427185428185429185430185431185432185433185434185435185436185437185438185439185440185441185442185443185444185445185446185447185448185449185450185451185452185453185454185455185456185457185458185459185460185461185462185463185464185465185466185467185468185469185470185471185472185473185474185475185476185477185478185479185480185481185482185483185484185485185486185487185488185489185490185491185492185493185494185495185496185497185498185499185500185501185502185503185504185505185506185507185508185509185510185511185512185513185514185515185516185517185518185519185520185521185522185523185524185525185526185527185528185529185530185531185532185533185534185535185536185537185538185539185540185541185542185543185544185545185546185547185548185549185550185551185552185553185554185555185556185557185558185559185560185561185562185563185564185565185566185567185568185569185570185571185572185573185574185575185576185577185578185579185580185581185582185583185584185585185586185587185588185589185590185591185592185593185594185595185596185597185598185599185600185601185602185603185604185605185606185607185608185609185610185611185612185613185614185615185616185617185618185619185620185621185622185623185624185625185626185627185628185629185630185631185632185633185634185635185636185637185638185639185640185641185642185643185644185645185646185647185648185649185650185651185652185653185654185655185656185657185658185659185660185661185662185663185664185665185666185667185668185669185670185671185672185673185674185675185676185677185678185679185680185681185682185683185684185685185686185687185688185689185690185691185692185693185694185695185696185697185698185699185700185701185702185703185704185705185706185707185708185709185710185711185712185713185714185715185716185717185718185719185720185721185722185723185724185725185726185727185728185729185730185731185732185733185734185735185736185737185738185739185740185741185742185743185744185745185746185747185748185749185750185751185752185753185754185755185756185757185758185759185760185761185762185763185764185765185766185767185768185769185770185771185772185773185774185775185776185777185778185779185780185781185782185783185784185785185786185787185788185789185790185791185792185793185794185795185796185797185798185799185800185801185802185803185804185805185806185807185808185809185810185811185812185813185814185815185816185817185818185819185820185821185822185823185824185825185826185827185828185829185830185831185832185833185834185835185836185837185838185839185840185841185842185843185844185845185846185847185848185849185850185851185852185853185854185855185856185857185858185859185860185861185862185863185864185865185866185867185868185869185870185871185872185873185874185875185876185877185878185879185880185881185882185883185884185885185886185887185888185889185890185891185892185893185894185895185896185897185898185899185900185901185902185903185904185905185906185907185908185909185910185911185912185913185914185915185916185917185918185919185920185921185922185923185924185925185926185927185928185929185930185931185932185933185934185935185936185937185938185939185940185941185942185943185944185945185946185947185948185949185950185951185952185953185954185955185956185957185958185959185960185961185962185963185964185965185966185967185968185969185970185971185972185973185974185975185976185977185978185979185980185981185982185983185984185985185986185987185988185989185990185991185992185993185994185995185996185997185998185999186000186001186002186003186004186005186006186007186008186009186010186011186012186013186014186015186016186017186018186019186020186021186022186023186024186025186026186027186028186029186030186031186032186033186034186035186036186037186038186039186040186041186042186043186044186045186046186047186048186049186050186051186052186053186054186055186056186057186058186059186060186061186062186063186064186065186066186067186068186069186070186071186072186073186074186075186076186077186078186079186080186081186082186083186084186085186086186087186088186089186090186091186092186093186094186095186096186097186098186099186100186101186102186103186104186105186106186107186108186109186110186111186112186113186114186115186116186117186118186119186120186121186122186123186124186125186126186127186128186129186130186131186132186133186134186135186136186137186138186139186140186141186142186143186144186145186146186147186148186149186150186151186152186153186154186155186156186157186158186159186160186161186162186163186164186165186166186167186168186169186170186171186172186173186174186175186176186177186178186179186180186181186182186183186184186185186186186187186188186189186190186191186192186193186194186195186196186197186198186199186200186201186202186203186204186205186206186207186208186209186210186211186212186213186214186215186216186217186218186219186220186221186222186223186224186225186226186227186228186229186230186231186232186233186234186235186236186237186238186239186240186241186242186243186244186245186246186247186248186249186250186251186252186253186254186255186256186257186258186259186260186261186262186263186264186265186266186267186268186269186270186271186272186273186274186275186276186277186278186279186280186281186282186283186284186285186286186287186288186289186290186291186292186293186294186295186296186297186298186299186300186301186302186303186304186305186306186307186308186309186310186311186312186313186314186315186316186317186318186319186320186321186322186323186324186325186326186327186328186329186330186331186332186333186334186335186336186337186338186339186340186341186342186343186344186345186346186347186348186349186350186351186352186353186354186355186356186357186358186359186360186361186362186363186364186365186366186367186368186369186370186371186372186373186374186375186376186377186378186379186380186381186382186383186384186385186386186387186388186389186390186391186392186393186394186395186396186397186398186399186400186401186402186403186404186405186406186407186408186409186410186411186412186413186414186415186416186417186418186419186420186421186422186423186424186425186426186427186428186429186430186431186432186433186434186435186436186437186438186439186440186441186442186443186444186445186446186447186448186449186450186451186452186453186454186455186456186457186458186459186460186461186462186463186464186465186466186467186468186469186470186471186472186473186474186475186476186477186478186479186480186481186482186483186484186485186486186487186488186489186490186491186492186493186494186495186496186497186498186499186500186501186502186503186504186505186506186507186508186509186510186511186512186513186514186515186516186517186518186519186520186521186522186523186524186525186526186527186528186529186530186531186532186533186534186535186536186537186538186539186540186541186542186543186544186545186546186547186548186549186550186551186552186553186554186555186556186557186558186559186560186561186562186563186564186565186566186567186568186569186570186571186572186573186574186575186576186577186578186579186580186581186582186583186584186585186586186587186588186589186590186591186592186593186594186595186596186597186598186599186600186601186602186603186604186605186606186607186608186609186610186611186612186613186614186615186616186617186618186619186620186621186622186623186624186625186626186627186628186629186630186631186632186633186634186635186636186637186638186639186640186641186642186643186644186645186646186647186648186649186650186651186652186653186654186655186656186657186658186659186660186661186662186663186664186665186666186667186668186669186670186671186672186673186674186675186676186677186678186679186680186681186682186683186684186685186686186687186688186689186690186691186692186693186694186695186696186697186698186699186700186701186702186703186704186705186706186707186708186709186710186711186712186713186714186715186716186717186718186719186720186721186722186723186724186725186726186727186728186729186730186731186732186733186734186735186736186737186738186739186740186741186742186743186744186745186746186747186748186749186750186751186752186753186754186755186756186757186758186759186760186761186762186763186764186765186766186767186768186769186770186771186772186773186774186775186776186777186778186779186780186781186782186783186784186785186786186787186788186789186790186791186792186793186794186795186796186797186798186799186800186801186802186803186804186805186806186807186808186809186810186811186812186813186814186815186816186817186818186819186820186821186822186823186824186825186826186827186828186829186830186831186832186833186834186835186836186837186838186839186840186841186842186843186844186845186846186847186848186849186850186851186852186853186854186855186856186857186858186859186860186861186862186863186864186865186866186867186868186869186870186871186872186873186874186875186876186877186878186879186880186881186882186883186884186885186886186887186888186889186890186891186892186893186894186895186896186897186898186899186900186901186902186903186904186905186906186907186908186909186910186911186912186913186914186915186916186917186918186919186920186921186922186923186924186925186926186927186928186929186930186931186932186933186934186935186936186937186938186939186940186941186942186943186944186945186946186947186948186949186950186951186952186953186954186955186956186957186958186959186960186961186962186963186964186965186966186967186968186969186970186971186972186973186974186975186976186977186978186979186980186981186982186983186984186985186986186987186988186989186990186991186992186993186994186995186996186997186998186999187000187001187002187003187004187005187006187007187008187009187010187011187012187013187014187015187016187017187018187019187020187021187022187023187024187025187026187027187028187029187030187031187032187033187034187035187036187037187038187039187040187041187042187043187044187045187046187047187048187049187050187051187052187053187054187055187056187057187058187059187060187061187062187063187064187065187066187067187068187069187070187071187072187073187074187075187076187077187078187079187080187081187082187083187084187085187086187087187088187089187090187091187092187093187094187095187096187097187098187099187100187101187102187103187104187105187106187107187108187109187110187111187112187113187114187115187116187117187118187119187120187121187122187123187124187125187126187127187128187129187130187131187132187133187134187135187136187137187138187139187140187141187142187143187144187145187146187147187148187149187150187151187152187153187154187155187156187157187158187159187160187161187162187163187164187165187166187167187168187169187170187171187172187173187174187175187176187177187178187179187180187181187182187183187184187185187186187187187188187189187190187191187192187193187194187195187196187197187198187199187200187201187202187203187204187205187206187207187208187209187210187211187212187213187214187215187216187217187218187219187220187221187222187223187224187225187226187227187228187229187230187231187232187233187234187235187236187237187238187239187240187241187242187243187244187245187246187247187248187249187250187251187252187253187254187255187256187257187258187259187260187261187262187263187264187265187266187267187268187269187270187271187272187273187274187275187276187277187278187279187280187281187282187283187284187285187286187287187288187289187290187291187292187293187294187295187296187297187298187299187300187301187302187303187304187305187306187307187308187309187310187311187312187313187314187315187316187317187318187319187320187321187322187323187324187325187326187327187328187329187330187331187332187333187334187335187336187337187338187339187340187341187342187343187344187345187346187347187348187349187350187351187352187353187354187355187356187357187358187359187360187361187362187363187364187365187366187367187368187369187370187371187372187373187374187375187376187377187378187379187380187381187382187383187384187385187386187387187388187389187390187391187392187393187394187395187396187397187398187399187400187401187402187403187404187405187406187407187408187409187410187411187412187413187414187415187416187417187418187419187420187421187422187423187424187425187426187427187428187429187430187431187432187433187434187435187436187437187438187439187440187441187442187443187444187445187446187447187448187449187450187451187452187453187454187455187456187457187458187459187460187461187462187463187464187465187466187467187468187469187470187471187472187473187474187475187476187477187478187479187480187481187482187483187484187485187486187487187488187489187490187491187492187493187494187495187496187497187498187499187500187501187502187503187504187505187506187507187508187509187510187511187512187513187514187515187516187517187518187519187520187521187522187523187524187525187526187527187528187529187530187531187532187533187534187535187536187537187538187539187540187541187542187543187544187545187546187547187548187549187550187551187552187553187554187555187556187557187558187559187560187561187562187563187564187565187566187567187568187569187570187571187572187573187574187575187576187577187578187579187580187581187582187583187584187585187586187587187588187589187590187591187592187593187594187595187596187597187598187599187600187601187602187603187604187605187606187607187608187609187610187611187612187613187614187615187616187617187618187619187620187621187622187623187624187625187626187627187628187629187630187631187632187633187634187635187636187637187638187639187640187641187642187643187644187645187646187647187648187649187650187651187652187653187654187655187656187657187658187659187660187661187662187663187664187665187666187667187668187669187670187671187672187673187674187675187676187677187678187679187680187681187682187683187684187685187686187687187688187689187690187691187692187693187694187695187696187697187698187699187700187701187702187703187704187705187706187707187708187709187710187711187712187713187714187715187716187717187718187719187720187721187722187723187724187725187726187727187728187729187730187731187732187733187734187735187736187737187738187739187740187741187742187743187744187745187746187747187748187749187750187751187752187753187754187755187756187757187758187759187760187761187762187763187764187765187766187767187768187769187770187771187772187773187774187775187776187777187778187779187780187781187782187783187784187785187786187787187788187789187790187791187792187793187794187795187796187797187798187799187800187801187802187803187804187805187806187807187808187809187810187811187812187813187814187815187816187817187818187819187820187821187822187823187824187825187826187827187828187829187830187831187832187833187834187835187836187837187838187839187840187841187842187843187844187845187846187847187848187849187850187851187852187853187854187855187856187857187858187859187860187861187862187863187864187865187866187867187868187869187870187871187872187873187874187875187876187877187878187879187880187881187882187883187884187885187886187887187888187889187890187891187892187893187894187895187896187897187898187899187900187901187902187903187904187905187906187907187908187909187910187911187912187913187914187915187916187917187918187919187920187921187922187923187924187925187926187927187928187929187930187931187932187933187934187935187936187937187938187939187940187941187942187943187944187945187946187947187948187949187950187951187952187953187954187955187956187957187958187959187960187961187962187963187964187965187966187967187968187969187970187971187972187973187974187975187976187977187978187979187980187981187982187983187984187985187986187987187988187989187990187991187992187993187994187995187996187997187998187999188000188001188002188003188004188005188006188007188008188009188010188011188012188013188014188015188016188017188018188019188020188021188022188023188024188025188026188027188028188029188030188031188032188033188034188035188036188037188038188039188040188041188042188043188044188045188046188047188048188049188050188051188052188053188054188055188056188057188058188059188060188061188062188063188064188065188066188067188068188069188070188071188072188073188074188075188076188077188078188079188080188081188082188083188084188085188086188087188088188089188090188091188092188093188094188095188096188097188098188099188100188101188102188103188104188105188106188107188108188109188110188111188112188113188114188115188116188117188118188119188120188121188122188123188124188125188126188127188128188129188130188131188132188133188134188135188136188137188138188139188140188141188142188143188144188145188146188147188148188149188150188151188152188153188154188155188156188157188158188159188160188161188162188163188164188165188166188167188168188169188170188171188172188173188174188175188176188177188178188179188180188181188182188183188184188185188186188187188188188189188190188191188192188193188194188195188196188197188198188199188200188201188202188203188204188205188206188207188208188209188210188211188212188213188214188215188216188217188218188219188220188221188222188223188224188225188226188227188228188229188230188231188232188233188234188235188236188237188238188239188240188241188242188243188244188245188246188247188248188249188250188251188252188253188254188255188256188257188258188259188260188261188262188263188264188265188266188267188268188269188270188271188272188273188274188275188276188277188278188279188280188281188282188283188284188285188286188287188288188289188290188291188292188293188294188295188296188297188298188299188300188301188302188303188304188305188306188307188308188309188310188311188312188313188314188315188316188317188318188319188320188321188322188323188324188325188326188327188328188329188330188331188332188333188334188335188336188337188338188339188340188341188342188343188344188345188346188347188348188349188350188351188352188353188354188355188356188357188358188359188360188361188362188363188364188365188366188367188368188369188370188371188372188373188374188375188376188377188378188379188380188381188382188383188384188385188386188387188388188389188390188391188392188393188394188395188396188397188398188399188400188401188402188403188404188405188406188407188408188409188410188411188412188413188414188415188416188417188418188419188420188421188422188423188424188425188426188427188428188429188430188431188432188433188434188435188436188437188438188439188440188441188442188443188444188445188446188447188448188449188450188451188452188453188454188455188456188457188458188459188460188461188462188463188464188465188466188467188468188469188470188471188472188473188474188475188476188477188478188479188480188481188482188483188484188485188486188487188488188489188490188491188492188493188494188495188496188497188498188499188500188501188502188503188504188505188506188507188508188509188510188511188512188513188514188515188516188517188518188519188520188521188522188523188524188525188526188527188528188529188530188531188532188533188534188535188536188537188538188539188540188541188542188543188544188545188546188547188548188549188550188551188552188553188554188555188556188557188558188559188560188561188562188563188564188565188566188567188568188569188570188571188572188573188574188575188576188577188578188579188580188581188582188583188584188585188586188587188588188589188590188591188592188593188594188595188596188597188598188599188600188601188602188603188604188605188606188607188608188609188610188611188612188613188614188615188616188617188618188619188620188621188622188623188624188625188626188627188628188629188630188631188632188633188634188635188636188637188638188639188640188641188642188643188644188645188646188647188648188649188650188651188652188653188654188655188656188657188658188659188660188661188662188663188664188665188666188667188668188669188670188671188672188673188674188675188676188677188678188679188680188681188682188683188684188685188686188687188688188689188690188691188692188693188694188695188696188697188698188699188700188701188702188703188704188705188706188707188708188709188710188711188712188713188714188715188716188717188718188719188720188721188722188723188724188725188726188727188728188729188730188731188732188733188734188735188736188737188738188739188740188741188742188743188744188745188746188747188748188749188750188751188752188753188754188755188756188757188758188759188760188761188762188763188764188765188766188767188768188769188770188771188772188773188774188775188776188777188778188779188780188781188782188783188784188785188786188787188788188789188790188791188792188793188794188795188796188797188798188799188800188801188802188803188804188805188806188807188808188809188810188811188812188813188814188815188816188817188818188819188820188821188822188823188824188825188826188827188828188829188830188831188832188833188834188835188836188837188838188839188840188841188842188843188844188845188846188847188848188849188850188851188852188853188854188855188856188857188858188859188860188861188862188863188864188865188866188867188868188869188870188871188872188873188874188875188876188877188878188879188880188881188882188883188884188885188886188887188888188889188890188891188892188893188894188895188896188897188898188899188900188901188902188903188904188905188906188907188908188909188910188911188912188913188914188915188916188917188918188919188920188921188922188923188924188925188926188927188928188929188930188931188932188933188934188935188936188937188938188939188940188941188942188943188944188945188946188947188948188949188950188951188952188953188954188955188956188957188958188959188960188961188962188963188964188965188966188967188968188969188970188971188972188973188974188975188976188977188978188979188980188981188982188983188984188985188986188987188988188989188990188991188992188993188994188995188996188997188998188999189000189001189002189003189004189005189006189007189008189009189010189011189012189013189014189015189016189017189018189019189020189021189022189023189024189025189026189027189028189029189030189031189032189033189034189035189036189037189038189039189040189041189042189043189044189045189046189047189048189049189050189051189052189053189054189055189056189057189058189059189060189061189062189063189064189065189066189067189068189069189070189071189072189073189074189075189076189077189078189079189080189081189082189083189084189085189086189087189088189089189090189091189092189093189094189095189096189097189098189099189100189101189102189103189104189105189106189107189108189109189110189111189112189113189114189115189116189117189118189119189120189121189122189123189124189125189126189127189128189129189130189131189132189133189134189135189136189137189138189139189140189141189142189143189144189145189146189147189148189149189150189151189152189153189154189155189156189157189158189159189160189161189162189163189164189165189166189167189168189169189170189171189172189173189174189175189176189177189178189179189180189181189182189183189184189185189186189187189188189189189190189191189192189193189194189195189196189197189198189199189200189201189202189203189204189205189206189207189208189209189210189211189212189213189214189215189216189217189218189219189220189221189222189223189224189225189226189227189228189229189230189231189232189233189234189235189236189237189238189239189240189241189242189243189244189245189246189247189248189249189250189251189252189253189254189255189256189257189258189259189260189261189262189263189264189265189266189267189268189269189270189271189272189273189274189275189276189277189278189279189280189281189282189283189284189285189286189287189288189289189290189291189292189293189294189295189296189297189298189299189300189301189302189303189304189305189306189307189308189309189310189311189312189313189314189315189316189317189318189319189320189321189322189323189324189325189326189327189328189329189330189331189332189333189334189335189336189337189338189339189340189341189342189343189344189345189346189347189348189349189350189351189352189353189354189355189356189357189358189359189360189361189362189363189364189365189366189367189368189369189370189371189372189373189374189375189376189377189378189379189380189381189382189383189384189385189386189387189388189389189390189391189392189393189394189395189396189397189398189399189400189401189402189403189404189405189406189407189408189409189410189411189412189413189414189415189416189417189418189419189420189421189422189423189424189425189426189427189428189429189430189431189432189433189434189435189436189437189438189439189440189441189442189443189444189445189446189447189448189449189450189451189452189453189454189455189456189457189458189459189460189461189462189463189464189465189466189467189468189469189470189471189472189473189474189475189476189477189478189479189480189481189482189483189484189485189486189487189488189489189490189491189492189493189494189495189496189497189498189499189500189501189502189503189504189505189506189507189508189509189510189511189512189513189514189515189516189517189518189519189520189521189522189523189524189525189526189527189528189529189530189531189532189533189534189535189536189537189538189539189540189541189542189543189544189545189546189547189548189549189550189551189552189553189554189555189556189557189558189559189560189561189562189563189564189565189566189567189568189569189570189571189572189573189574189575189576189577189578189579189580189581189582189583189584189585189586189587189588189589189590189591189592189593189594189595189596189597189598189599189600189601189602189603189604189605189606189607189608189609189610189611189612189613189614189615189616189617189618189619189620189621189622189623189624189625189626189627189628189629189630189631189632189633189634189635189636189637189638189639189640189641189642189643189644189645189646189647189648189649189650189651189652189653189654189655189656189657189658189659189660189661189662189663189664189665189666189667189668189669189670189671189672189673189674189675189676189677189678189679189680189681189682189683189684189685189686189687189688189689189690189691189692189693189694189695189696189697189698189699189700189701189702189703189704189705189706189707189708189709189710189711189712189713189714189715189716189717189718189719189720189721189722189723189724189725189726189727189728189729189730189731189732189733189734189735189736189737189738189739189740189741189742189743189744189745189746189747189748189749189750189751189752189753189754189755189756189757189758189759189760189761189762189763189764189765189766189767189768189769189770189771189772189773189774189775189776189777189778189779189780189781189782189783189784189785189786189787189788189789189790189791189792189793189794189795189796189797189798189799189800189801189802189803189804189805189806189807189808189809189810189811189812189813189814189815189816189817189818189819189820189821189822189823189824189825189826189827189828189829189830189831189832189833189834189835189836189837189838189839189840189841189842189843189844189845189846189847189848189849189850189851189852189853189854189855189856189857189858189859189860189861189862189863189864189865189866189867189868189869189870189871189872189873189874189875189876189877189878189879189880189881189882189883189884189885189886189887189888189889189890189891189892189893189894189895189896189897189898189899189900189901189902189903189904189905189906189907189908189909189910189911189912189913189914189915189916189917189918189919189920189921189922189923189924189925189926189927189928189929189930189931189932189933189934189935189936189937189938189939189940189941189942189943189944189945189946189947189948189949189950189951189952189953189954189955189956189957189958189959189960189961189962189963189964189965189966189967189968189969189970189971189972189973189974189975189976189977189978189979189980189981189982189983189984189985189986189987189988189989189990189991189992189993189994189995189996189997189998189999190000190001190002190003190004190005190006190007190008190009190010190011190012190013190014190015190016190017190018190019190020190021190022190023190024190025190026190027190028190029190030190031190032190033190034190035190036190037190038190039190040190041190042190043190044190045190046190047190048190049190050190051190052190053190054190055190056190057190058190059190060190061190062190063190064190065190066190067190068190069190070190071190072190073190074190075190076190077190078190079190080190081190082190083190084190085190086190087190088190089190090190091190092190093190094190095190096190097190098190099190100190101190102190103190104190105190106190107190108190109190110190111190112190113190114190115190116190117190118190119190120190121190122190123190124190125190126190127190128190129190130190131190132190133190134190135190136190137190138190139190140190141190142190143190144190145190146190147190148190149190150190151190152190153190154190155190156190157190158190159190160190161190162190163190164190165190166190167190168190169190170190171190172190173190174190175190176190177190178190179190180190181190182190183190184190185190186190187190188190189190190190191190192190193190194190195190196190197190198190199190200190201190202190203190204190205190206190207190208190209190210190211190212190213190214190215190216190217190218190219190220190221190222190223190224190225190226190227190228190229190230190231190232190233190234190235190236190237190238190239190240190241190242190243190244190245190246190247190248190249190250190251190252190253190254190255190256190257190258190259190260190261190262190263190264190265190266190267190268190269190270190271190272190273190274190275190276190277190278190279190280190281190282190283190284190285190286190287190288190289190290190291190292190293190294190295190296190297190298190299190300190301190302190303190304190305190306190307190308190309190310190311190312190313190314190315190316190317190318190319190320190321190322190323190324190325190326190327190328190329190330190331190332190333190334190335190336190337190338190339190340190341190342190343190344190345190346190347190348190349190350190351190352190353190354190355190356190357190358190359190360190361190362190363190364190365190366190367190368190369190370190371190372190373190374190375190376190377190378190379190380190381190382190383190384190385190386190387190388190389190390190391190392190393190394190395190396190397190398190399190400190401190402190403190404190405190406190407190408190409190410190411190412190413190414190415190416190417190418190419190420190421190422190423190424190425190426190427190428190429190430190431190432190433190434190435190436190437190438190439190440190441190442190443190444190445190446190447190448190449190450190451190452190453190454190455190456190457190458190459190460190461190462190463190464190465190466190467190468190469190470190471190472190473190474190475190476190477190478190479190480190481190482190483190484190485190486190487190488190489190490190491190492190493190494190495190496190497190498190499190500190501190502190503190504190505190506190507190508190509190510190511190512190513190514190515190516190517190518190519190520190521190522190523190524190525190526190527190528190529190530190531190532190533190534190535190536190537190538190539190540190541190542190543190544190545190546190547190548190549190550190551190552190553190554190555190556190557190558190559190560190561190562190563190564190565190566190567190568190569190570190571190572190573190574190575190576190577190578190579190580190581190582190583190584190585190586190587190588190589190590190591190592190593190594190595190596190597190598190599190600190601190602190603190604190605190606190607190608190609190610190611190612190613190614190615190616190617190618190619190620190621190622190623190624190625190626190627190628190629190630190631190632190633190634190635190636190637190638190639190640190641190642190643190644190645190646190647190648190649190650190651190652190653190654190655190656190657190658190659190660190661190662190663190664190665190666190667190668190669190670190671190672190673190674190675190676190677190678190679190680190681190682190683190684190685190686190687190688190689190690190691190692190693190694190695190696190697190698190699190700190701190702190703190704190705190706190707190708190709190710190711190712190713190714190715190716190717190718190719190720190721190722190723190724190725190726190727190728190729190730190731190732190733190734190735190736190737190738190739190740190741190742190743190744190745190746190747190748190749190750190751190752190753190754190755190756190757190758190759190760190761190762190763190764190765190766190767190768190769190770190771190772190773190774190775190776190777190778190779190780190781190782190783190784190785190786190787190788190789190790190791190792190793190794190795190796190797190798190799190800190801190802190803190804190805190806190807190808190809190810190811190812190813190814190815190816190817190818190819190820190821190822190823190824190825190826190827190828190829190830190831190832190833190834190835190836190837190838190839190840190841190842190843190844190845190846190847190848190849190850190851190852190853190854190855190856190857190858190859190860190861190862190863190864190865190866190867190868190869190870190871190872190873190874190875190876190877190878190879190880190881190882190883190884190885190886190887190888190889190890190891190892190893190894190895190896190897190898190899190900190901190902190903190904190905190906190907190908190909190910190911190912190913190914190915190916190917190918190919190920190921190922190923190924190925190926190927190928190929190930190931190932190933190934190935190936190937190938190939190940190941190942190943190944190945190946190947190948190949190950190951190952190953190954190955190956190957190958190959190960190961190962190963190964190965190966190967190968190969190970190971190972190973190974190975190976190977190978190979190980190981190982190983190984190985190986190987190988190989190990190991190992190993190994190995190996190997190998190999191000191001191002191003191004191005191006191007191008191009191010191011191012191013191014191015191016191017191018191019191020191021191022191023191024191025191026191027191028191029191030191031191032191033191034191035191036191037191038191039191040191041191042191043191044191045191046191047191048191049191050191051191052191053191054191055191056191057191058191059191060191061191062191063191064191065191066191067191068191069191070191071191072191073191074191075191076191077191078191079191080191081191082191083191084191085191086191087191088191089191090191091191092191093191094191095191096191097191098191099191100191101191102191103191104191105191106191107191108191109191110191111191112191113191114191115191116191117191118191119191120191121191122191123191124191125191126191127191128191129191130191131191132191133191134191135191136191137191138191139191140191141191142191143191144191145191146191147191148191149191150191151191152191153191154191155191156191157191158191159191160191161191162191163191164191165191166191167191168191169191170191171191172191173191174191175191176191177191178191179191180191181191182191183191184191185191186191187191188191189191190191191191192191193191194191195191196191197191198191199191200191201191202191203191204191205191206191207191208191209191210191211191212191213191214191215191216191217191218191219191220191221191222191223191224191225191226191227191228191229191230191231191232191233191234191235191236191237191238191239191240191241191242191243191244191245191246191247191248191249191250191251191252191253191254191255191256191257191258191259191260191261191262191263191264191265191266191267191268191269191270191271191272191273191274191275191276191277191278191279191280191281191282191283191284191285191286191287191288191289191290191291191292191293191294191295191296191297191298191299191300191301191302191303191304191305191306191307191308191309191310191311191312191313191314191315191316191317191318191319191320191321191322191323191324191325191326191327191328191329191330191331191332191333191334191335191336191337191338191339191340191341191342191343191344191345191346191347191348191349191350191351191352191353191354191355191356191357191358191359191360191361191362191363191364191365191366191367191368191369191370191371191372191373191374191375191376191377191378191379191380191381191382191383191384191385191386191387191388191389191390191391191392191393191394191395191396191397191398191399191400191401191402191403191404191405191406191407191408191409191410191411191412191413191414191415191416191417191418191419191420191421191422191423191424191425191426191427191428191429191430191431191432191433191434191435191436191437191438191439191440191441191442191443191444191445191446191447191448191449191450191451191452191453191454191455191456191457191458191459191460191461191462191463191464191465191466191467191468191469191470191471191472191473191474191475191476191477191478191479191480191481191482191483191484191485191486191487191488191489191490191491191492191493191494191495191496191497191498191499191500191501191502191503191504191505191506191507191508191509191510191511191512191513191514191515191516191517191518191519191520191521191522191523191524191525191526191527191528191529191530191531191532191533191534191535191536191537191538191539191540191541191542191543191544191545191546191547191548191549191550191551191552191553191554191555191556191557191558191559191560191561191562191563191564191565191566191567191568191569191570191571191572191573191574191575191576191577191578191579191580191581191582191583191584191585191586191587191588191589191590191591191592191593191594191595191596191597191598191599191600191601191602191603191604191605191606191607191608191609191610191611191612191613191614191615191616191617191618191619191620191621191622191623191624191625191626191627191628191629191630191631191632191633191634191635191636191637191638191639191640191641191642191643191644191645191646191647191648191649191650191651191652191653191654191655191656191657191658191659191660191661191662191663191664191665191666191667191668191669191670191671191672191673191674191675191676191677191678191679191680191681191682191683191684191685191686191687191688191689191690191691191692191693191694191695191696191697191698191699191700191701191702191703191704191705191706191707191708191709191710191711191712191713191714191715191716191717191718191719191720191721191722191723191724191725191726191727191728191729191730191731191732191733191734191735191736191737191738191739191740191741191742191743191744191745191746191747191748191749191750191751191752191753191754191755191756191757191758191759191760191761191762191763191764191765191766191767191768191769191770191771191772191773191774191775191776191777191778191779191780191781191782191783191784191785191786191787191788191789191790191791191792191793191794191795191796191797191798191799191800191801191802191803191804191805191806191807191808191809191810191811191812191813191814191815191816191817191818191819191820191821191822191823191824191825191826191827191828191829191830191831191832191833191834191835191836191837191838191839191840191841191842191843191844191845191846191847191848191849191850191851191852191853191854191855191856191857191858191859191860191861191862191863191864191865191866191867191868191869191870191871191872191873191874191875191876191877191878191879191880191881191882191883191884191885191886191887191888191889191890191891191892191893191894191895191896191897191898191899191900191901191902191903191904191905191906191907191908191909191910191911191912191913191914191915191916191917191918191919191920191921191922191923191924191925191926191927191928191929191930191931191932191933191934191935191936191937191938191939191940191941191942191943191944191945191946191947191948191949191950191951191952191953191954191955191956191957191958191959191960191961191962191963191964191965191966191967191968191969191970191971191972191973191974191975191976191977191978191979191980191981191982191983191984191985191986191987191988191989191990191991191992191993191994191995191996191997191998191999192000192001192002192003192004192005192006192007192008192009192010192011192012192013192014192015192016192017192018192019192020192021192022192023192024192025192026192027192028192029192030192031192032192033192034192035192036192037192038192039192040192041192042192043192044192045192046192047192048192049192050192051192052192053192054192055192056192057192058192059192060192061192062192063192064192065192066192067192068192069192070192071192072192073192074192075192076192077192078192079192080192081192082192083192084192085192086192087192088192089192090192091192092192093192094192095192096192097192098192099192100192101192102192103192104192105192106192107192108192109192110192111192112192113192114192115192116192117192118192119192120192121192122192123192124192125192126192127192128192129192130192131192132192133192134192135192136192137192138192139192140192141192142192143192144192145192146192147192148192149192150192151192152192153192154192155192156192157192158192159192160192161192162192163192164192165192166192167192168192169192170192171192172192173192174192175192176192177192178192179192180192181192182192183192184192185192186192187192188192189192190192191192192192193192194192195192196192197192198192199192200192201192202192203192204192205192206192207192208192209192210192211192212192213192214192215192216192217192218192219192220192221192222192223192224192225192226192227192228192229192230192231192232192233192234192235192236192237192238192239192240192241192242192243192244192245192246192247192248192249192250192251192252192253192254192255192256192257192258192259192260192261192262192263192264192265192266192267192268192269192270192271192272192273192274192275192276192277192278192279192280192281192282192283192284192285192286192287192288192289192290192291192292192293192294192295192296192297192298192299192300192301192302192303192304192305192306192307192308192309192310192311192312192313192314192315192316192317192318192319192320192321192322192323192324192325192326192327192328192329192330192331192332192333192334192335192336192337192338192339192340192341192342192343192344192345192346192347192348192349192350192351192352192353192354192355192356192357192358192359192360192361192362192363192364192365192366192367192368192369192370192371192372192373192374192375192376192377192378192379192380192381192382192383192384192385192386192387192388192389192390192391192392192393192394192395192396192397192398192399192400192401192402192403192404192405192406192407192408192409192410192411192412192413192414192415192416192417192418192419192420192421192422192423192424192425192426192427192428192429192430192431192432192433192434192435192436192437192438192439192440192441192442192443192444192445192446192447192448192449192450192451192452192453192454192455192456192457192458192459192460192461192462192463192464192465192466192467192468192469192470192471192472192473192474192475192476192477192478192479192480192481192482192483192484192485192486192487192488192489192490192491192492192493192494192495192496192497192498192499192500192501192502192503192504192505192506192507192508192509192510192511192512192513192514192515192516192517192518192519192520192521192522192523192524192525192526192527192528192529192530192531192532192533192534192535192536192537192538192539192540192541192542192543192544192545192546192547192548192549192550192551192552192553192554192555192556192557192558192559192560192561192562192563192564192565192566192567192568192569192570192571192572192573192574192575192576192577192578192579192580192581192582192583192584192585192586192587192588192589192590192591192592192593192594192595192596192597192598192599192600192601192602192603192604192605192606192607192608192609192610192611192612192613192614192615192616192617192618192619192620192621192622192623192624192625192626192627192628192629192630192631192632192633192634192635192636192637192638192639192640192641192642192643192644192645192646192647192648192649192650192651192652192653192654192655192656192657192658192659192660192661192662192663192664192665192666192667192668192669192670192671192672192673192674192675192676192677192678192679192680192681192682192683192684192685192686192687192688192689192690192691192692192693192694192695192696192697192698192699192700192701192702192703192704192705192706192707192708192709192710192711192712192713192714192715192716192717192718192719192720192721192722192723192724192725192726192727192728192729192730192731192732192733192734192735192736192737192738192739192740192741192742192743192744192745192746192747192748192749192750192751192752192753192754192755192756192757192758192759192760192761192762192763192764192765192766192767192768192769192770192771192772192773192774192775192776192777192778192779192780192781192782192783192784192785192786192787192788192789192790192791192792192793192794192795192796192797192798192799192800192801192802192803192804192805192806192807192808192809192810192811192812192813192814192815192816192817192818192819192820192821192822192823192824192825192826192827192828192829192830192831192832192833192834192835192836192837192838192839192840192841192842192843192844192845192846192847192848192849192850192851192852192853192854192855192856192857192858192859192860192861192862192863192864192865192866192867192868192869192870192871192872192873192874192875192876192877192878192879192880192881192882192883192884192885192886192887192888192889192890192891192892192893192894192895192896192897192898192899192900192901192902192903192904192905192906192907192908192909192910192911192912192913192914192915192916192917192918192919192920192921192922192923192924192925192926192927192928192929192930192931192932192933192934192935192936192937192938192939192940192941192942192943192944192945192946192947192948192949192950192951192952192953192954192955192956192957192958192959192960192961192962192963192964192965192966192967192968192969192970192971192972192973192974192975192976192977192978192979192980192981192982192983192984192985192986192987192988192989192990192991192992192993192994192995192996192997192998192999193000193001193002193003193004193005193006193007193008193009193010193011193012193013193014193015193016193017193018193019193020193021193022193023193024193025193026193027193028193029193030193031193032193033193034193035193036193037193038193039193040193041193042193043193044193045193046193047193048193049193050193051193052193053193054193055193056193057193058193059193060193061193062193063193064193065193066193067193068193069193070193071193072193073193074193075193076193077193078193079193080193081193082193083193084193085193086193087193088193089193090193091193092193093193094193095193096193097193098193099193100193101193102193103193104193105193106193107193108193109193110193111193112193113193114193115193116193117193118193119193120193121193122193123193124193125193126193127193128193129193130193131193132193133193134193135193136193137193138193139193140193141193142193143193144193145193146193147193148193149193150193151193152193153193154193155193156193157193158193159193160193161193162193163193164193165193166193167193168193169193170193171193172193173193174193175193176193177193178193179193180193181193182193183193184193185193186193187193188193189193190193191193192193193193194193195193196193197193198193199193200193201193202193203193204193205193206193207193208193209193210193211193212193213193214193215193216193217193218193219193220193221193222193223193224193225193226193227193228193229193230193231193232193233193234193235193236193237193238193239193240193241193242193243193244193245193246193247193248193249193250193251193252193253193254193255193256193257193258193259193260193261193262193263193264193265193266193267193268193269193270193271193272193273193274193275193276193277193278193279193280193281193282193283193284193285193286193287193288193289193290193291193292193293193294193295193296193297193298193299193300193301193302193303193304193305193306193307193308193309193310193311193312193313193314193315193316193317193318193319193320193321193322193323193324193325193326193327193328193329193330193331193332193333193334193335193336193337193338193339193340193341193342193343193344193345193346193347193348193349193350193351193352193353193354193355193356193357193358193359193360193361193362193363193364193365193366193367193368193369193370193371193372193373193374193375193376193377193378193379193380193381193382193383193384193385193386193387193388193389193390193391193392193393193394193395193396193397193398193399193400193401193402193403193404193405193406193407193408193409193410193411193412193413193414193415193416193417193418193419193420193421193422193423193424193425193426193427193428193429193430193431193432193433193434193435193436193437193438193439193440193441193442193443193444193445193446193447193448193449193450193451193452193453193454193455193456193457193458193459193460193461193462193463193464193465193466193467193468193469193470193471193472193473193474193475193476193477193478193479193480193481193482193483193484193485193486193487193488193489193490193491193492193493193494193495193496193497193498193499193500193501193502193503193504193505193506193507193508193509193510193511193512193513193514193515193516193517193518193519193520193521193522193523193524193525193526193527193528193529193530193531193532193533193534193535193536193537193538193539193540193541193542193543193544193545193546193547193548193549193550193551193552193553193554193555193556193557193558193559193560193561193562193563193564193565193566193567193568193569193570193571193572193573193574193575193576193577193578193579193580193581193582193583193584193585193586193587193588193589193590193591193592193593193594193595193596193597193598193599193600193601193602193603193604193605193606193607193608193609193610193611193612193613193614193615193616193617193618193619193620193621193622193623193624193625193626193627193628193629193630193631193632193633193634193635193636193637193638193639193640193641193642193643193644193645193646193647193648193649193650193651193652193653193654193655193656193657193658193659193660193661193662193663193664193665193666193667193668193669193670193671193672193673193674193675193676193677193678193679193680193681193682193683193684193685193686193687193688193689193690193691193692193693193694193695193696193697193698193699193700193701193702193703193704193705193706193707193708193709193710193711193712193713193714193715193716193717193718193719193720193721193722193723193724193725193726193727193728193729193730193731193732193733193734193735193736193737193738193739193740193741193742193743193744193745193746193747193748193749193750193751193752193753193754193755193756193757193758193759193760193761193762193763193764193765193766193767193768193769193770193771193772193773193774193775193776193777193778193779193780193781193782193783193784193785193786193787193788193789193790193791193792193793193794193795193796193797193798193799193800193801193802193803193804193805193806193807193808193809193810193811193812193813193814193815193816193817193818193819193820193821193822193823193824193825193826193827193828193829193830193831193832193833193834193835193836193837193838193839193840193841193842193843193844193845193846193847193848193849193850193851193852193853193854193855193856193857193858193859193860193861193862193863193864193865193866193867193868193869193870193871193872193873193874193875193876193877193878193879193880193881193882193883193884193885193886193887193888193889193890193891193892193893193894193895193896193897193898193899193900193901193902193903193904193905193906193907193908193909193910193911193912193913193914193915193916193917193918193919193920193921193922193923193924193925193926193927193928193929193930193931193932193933193934193935193936193937193938193939193940193941193942193943193944193945193946193947193948193949193950193951193952193953193954193955193956193957193958193959193960193961193962193963193964193965193966193967193968193969193970193971193972193973193974193975193976193977193978193979193980193981193982193983193984193985193986193987193988193989193990193991193992193993193994193995193996193997193998193999194000194001194002194003194004194005194006194007194008194009194010194011194012194013194014194015194016194017194018194019194020194021194022194023194024194025194026194027194028194029194030194031194032194033194034194035194036194037194038194039194040194041194042194043194044194045194046194047194048194049194050194051194052194053194054194055194056194057194058194059194060194061194062194063194064194065194066194067194068194069194070194071194072194073194074194075194076194077194078194079194080194081194082194083194084194085194086194087194088194089194090194091194092194093194094194095194096194097194098194099194100194101194102194103194104194105194106194107194108194109194110194111194112194113194114194115194116194117194118194119194120194121194122194123194124194125194126194127194128194129194130194131194132194133194134194135194136194137194138194139194140194141194142194143194144194145194146194147194148194149194150194151194152194153194154194155194156194157194158194159194160194161194162194163194164194165194166194167194168194169194170194171194172194173194174194175194176194177194178194179194180194181194182194183194184194185194186194187194188194189194190194191194192194193194194194195194196194197194198194199194200194201194202194203194204194205194206194207194208194209194210194211194212194213194214194215194216194217194218194219194220194221194222194223194224194225194226194227194228194229194230194231194232194233194234194235194236194237194238194239194240194241194242194243194244194245194246194247194248194249194250194251194252194253194254194255194256194257194258194259194260194261194262194263194264194265194266194267194268194269194270194271194272194273194274194275194276194277194278194279194280194281194282194283194284194285194286194287194288194289194290194291194292194293194294194295194296194297194298194299194300194301194302194303194304194305194306194307194308194309194310194311194312194313194314194315194316194317194318194319194320194321194322194323194324194325194326194327194328194329194330194331194332194333194334194335194336194337194338194339194340194341194342194343194344194345194346194347194348194349194350194351194352194353194354194355194356194357194358194359194360194361194362194363194364194365194366194367194368194369194370194371194372194373194374194375194376194377194378194379194380194381194382194383194384194385194386194387194388194389194390194391194392194393194394194395194396194397194398194399194400194401194402194403194404194405194406194407194408194409194410194411194412194413194414194415194416194417194418194419194420194421194422194423194424194425194426194427194428194429194430194431194432194433194434194435194436194437194438194439194440194441194442194443194444194445194446194447194448194449194450194451194452194453194454194455194456194457194458194459194460194461194462194463194464194465194466194467194468194469194470194471194472194473194474194475194476194477194478194479194480194481194482194483194484194485194486194487194488194489194490194491194492194493194494194495194496194497194498194499194500194501194502194503194504194505194506194507194508194509194510194511194512194513194514194515194516194517194518194519194520194521194522194523194524194525194526194527194528194529194530194531194532194533194534194535194536194537194538194539194540194541194542194543194544194545194546194547194548194549194550194551194552194553194554194555194556194557194558194559194560194561194562194563194564194565194566194567194568194569194570194571194572194573194574194575194576194577194578194579194580194581194582194583194584194585194586194587194588194589194590194591194592194593194594194595194596194597194598194599194600194601194602194603194604194605194606194607194608194609194610194611194612194613194614194615194616194617194618194619194620194621194622194623194624194625194626194627194628194629194630194631194632194633194634194635194636194637194638194639194640194641194642194643194644194645194646194647194648194649194650194651194652194653194654194655194656194657194658194659194660194661194662194663194664194665194666194667194668194669194670194671194672194673194674194675194676194677194678194679194680194681194682194683194684194685194686194687194688194689194690194691194692194693194694194695194696194697194698194699194700194701194702194703194704194705194706194707194708194709194710194711194712194713194714194715194716194717194718194719194720194721194722194723194724194725194726194727194728194729194730194731194732194733194734194735194736194737194738194739194740194741194742194743194744194745194746194747194748194749194750194751194752194753194754194755194756194757194758194759194760194761194762194763194764194765194766194767194768194769194770194771194772194773194774194775194776194777194778194779194780194781194782194783194784194785194786194787194788194789194790194791194792194793194794194795194796194797194798194799194800194801194802194803194804194805194806194807194808194809194810194811194812194813194814194815194816194817194818194819194820194821194822194823194824194825194826194827194828194829194830194831194832194833194834194835194836194837194838194839194840194841194842194843194844194845194846194847194848194849194850194851194852194853194854194855194856194857194858194859194860194861194862194863194864194865194866194867194868194869194870194871194872194873194874194875194876194877194878194879194880194881194882194883194884194885194886194887194888194889194890194891194892194893194894194895194896194897194898194899194900194901194902194903194904194905194906194907194908194909194910194911194912194913194914194915194916194917194918194919194920194921194922194923194924194925194926194927194928194929194930194931194932194933194934194935194936194937194938194939194940194941194942194943194944194945194946194947194948194949194950194951194952194953194954194955194956194957194958194959194960194961194962194963194964194965194966194967194968194969194970194971194972194973194974194975194976194977194978194979194980194981194982194983194984194985194986194987194988194989194990194991194992194993194994194995194996194997194998194999195000195001195002195003195004195005195006195007195008195009195010195011195012195013195014195015195016195017195018195019195020195021195022195023195024195025195026195027195028195029195030195031195032195033195034195035195036195037195038195039195040195041195042195043195044195045195046195047195048195049195050195051195052195053195054195055195056195057195058195059195060195061195062195063195064195065195066195067195068195069195070195071195072195073195074195075195076195077195078195079195080195081195082195083195084195085195086195087195088195089195090195091195092195093195094195095195096195097195098195099195100195101195102195103195104195105195106195107195108195109195110195111195112195113195114195115195116195117195118195119195120195121195122195123195124195125195126195127195128195129195130195131195132195133195134195135195136195137195138195139195140195141195142195143195144195145195146195147195148195149195150195151195152195153195154195155195156195157195158195159195160195161195162195163195164195165195166195167195168195169195170195171195172195173195174195175195176195177195178195179195180195181195182195183195184195185195186195187195188195189195190195191195192195193195194195195195196195197195198195199195200195201195202195203195204195205195206195207195208195209195210195211195212195213195214195215195216195217195218195219195220195221195222195223195224195225195226195227195228195229195230195231195232195233195234195235195236195237195238195239195240195241195242195243195244195245195246195247195248195249195250195251195252195253195254195255195256195257195258195259195260195261195262195263195264195265195266195267195268195269195270195271195272195273195274195275195276195277195278195279195280195281195282195283195284195285195286195287195288195289195290195291195292195293195294195295195296195297195298195299195300195301195302195303195304195305195306195307195308195309195310195311195312195313195314195315195316195317195318195319195320195321195322195323195324195325195326195327195328195329195330195331195332195333195334195335195336195337195338195339195340195341195342195343195344195345195346195347195348195349195350195351195352195353195354195355195356195357195358195359195360195361195362195363195364195365195366195367195368195369195370195371195372195373195374195375195376195377195378195379195380195381195382195383195384195385195386195387195388195389195390195391195392195393195394195395195396195397195398195399195400195401195402195403195404195405195406195407195408195409195410195411195412195413195414195415195416195417195418195419195420195421195422195423195424195425195426195427195428195429195430195431195432195433195434195435195436195437195438195439195440195441195442195443195444195445195446195447195448195449195450195451195452195453195454195455195456195457195458195459195460195461195462195463195464195465195466195467195468195469195470195471195472195473195474195475195476195477195478195479195480195481195482195483195484195485195486195487195488195489195490195491195492195493195494195495195496195497195498195499195500195501195502195503195504195505195506195507195508195509195510195511195512195513195514195515195516195517195518195519195520195521195522195523195524195525195526195527195528195529195530195531195532195533195534195535195536195537195538195539195540195541195542195543195544195545195546195547195548195549195550195551195552195553195554195555195556195557195558195559195560195561195562195563195564195565195566195567195568195569195570195571195572195573195574195575195576195577195578195579195580195581195582195583195584195585195586195587195588195589195590195591195592195593195594195595195596195597195598195599195600195601195602195603195604195605195606195607195608195609195610195611195612195613195614195615195616195617195618195619195620195621195622195623195624195625195626195627195628195629195630195631195632195633195634195635195636195637195638195639195640195641195642195643195644195645195646195647195648195649195650195651195652195653195654195655195656195657195658195659195660195661195662195663195664195665195666195667195668195669195670195671195672195673195674195675195676195677195678195679195680195681195682195683195684195685195686195687195688195689195690195691195692195693195694195695195696195697195698195699195700195701195702195703195704195705195706195707195708195709195710195711195712195713195714195715195716195717195718195719195720195721195722195723195724195725195726195727195728195729195730195731195732195733195734195735195736195737195738195739195740195741195742195743195744195745195746195747195748195749195750195751195752195753195754195755195756195757195758195759195760195761195762195763195764195765195766195767195768195769195770195771195772195773195774195775195776195777195778195779195780195781195782195783195784195785195786195787195788195789195790195791195792195793195794195795195796195797195798195799195800195801195802195803195804195805195806195807195808195809195810195811195812195813195814195815195816195817195818195819195820195821195822195823195824195825195826195827195828195829195830195831195832195833195834195835195836195837195838195839195840195841195842195843195844195845195846195847195848195849195850195851195852195853195854195855195856195857195858195859195860195861195862195863195864195865195866195867195868195869195870195871195872195873195874195875195876195877195878195879195880195881195882195883195884195885195886195887195888195889195890195891195892195893195894195895195896195897195898195899195900195901195902195903195904195905195906195907195908195909195910195911195912195913195914195915195916195917195918195919195920195921195922195923195924195925195926195927195928195929195930195931195932195933195934195935195936195937195938195939195940195941195942195943195944195945195946195947195948195949195950195951195952195953195954195955195956195957195958195959195960195961195962195963195964195965195966195967195968195969195970195971195972195973195974195975195976195977195978195979195980195981195982195983195984195985195986195987195988195989195990195991195992195993195994195995195996195997195998195999196000196001196002196003196004196005196006196007196008196009196010196011196012196013196014196015196016196017196018196019196020196021196022196023196024196025196026196027196028196029196030196031196032196033196034196035196036196037196038196039196040196041196042196043196044196045196046196047196048196049196050196051196052196053196054196055196056196057196058196059196060196061196062196063196064196065196066196067196068196069196070196071196072196073196074196075196076196077196078196079196080196081196082196083196084196085196086196087196088196089196090196091196092196093196094196095196096196097196098196099196100196101196102196103196104196105196106196107196108196109196110196111196112196113196114196115196116196117196118196119196120196121196122196123196124196125196126196127196128196129196130196131196132196133196134196135196136196137196138196139196140196141196142196143196144196145196146196147196148196149196150196151196152196153196154196155196156196157196158196159196160196161196162196163196164196165196166196167196168196169196170196171196172196173196174196175196176196177196178196179196180196181196182196183196184196185196186196187196188196189196190196191196192196193196194196195196196196197196198196199196200196201196202196203196204196205196206196207196208196209196210196211196212196213196214196215196216196217196218196219196220196221196222196223196224196225196226196227196228196229196230196231196232196233196234196235196236196237196238196239196240196241196242196243196244196245196246196247196248196249196250196251196252196253196254196255196256196257196258196259196260196261196262196263196264196265196266196267196268196269196270196271196272196273196274196275196276196277196278196279196280196281196282196283196284196285196286196287196288196289196290196291196292196293196294196295196296196297196298196299196300196301196302196303196304196305196306196307196308196309196310196311196312196313196314196315196316196317196318196319196320196321196322196323196324196325196326196327196328196329196330196331196332196333196334196335196336196337196338196339196340196341196342196343196344196345196346196347196348196349196350196351196352196353196354196355196356196357196358196359196360196361196362196363196364196365196366196367196368196369196370196371196372196373196374196375196376196377196378196379196380196381196382196383196384196385196386196387196388196389196390196391196392196393196394196395196396196397196398196399196400196401196402196403196404196405196406196407196408196409196410196411196412196413196414196415196416196417196418196419196420196421196422196423196424196425196426196427196428196429196430196431196432196433196434196435196436196437196438196439196440196441196442196443196444196445196446196447196448196449196450196451196452196453196454196455196456196457196458196459196460196461196462196463196464196465196466196467196468196469196470196471196472196473196474196475196476196477196478196479196480196481196482196483196484196485196486196487196488196489196490196491196492196493196494196495196496196497196498196499196500196501196502196503196504196505196506196507196508196509196510196511196512196513196514196515196516196517196518196519196520196521196522196523196524196525196526196527196528196529196530196531196532196533196534196535196536196537196538196539196540196541196542196543196544196545196546196547196548196549196550196551196552196553196554196555196556196557196558196559196560196561196562196563196564196565196566196567196568196569196570196571196572196573196574196575196576196577196578196579196580196581196582196583196584196585196586196587196588196589196590196591196592196593196594196595196596196597196598196599196600196601196602196603196604196605196606196607196608196609196610196611196612196613196614196615196616196617196618196619196620196621196622196623196624196625196626196627196628196629196630196631196632196633196634196635196636196637196638196639196640196641196642196643196644196645196646196647196648196649196650196651196652196653196654196655196656196657196658196659196660196661196662196663196664196665196666196667196668196669196670196671196672196673196674196675196676196677196678196679196680196681196682196683196684196685196686196687196688196689196690196691196692196693196694196695196696196697196698196699196700196701196702196703196704196705196706196707196708196709196710196711196712196713196714196715196716196717196718196719196720196721196722196723196724196725196726196727196728196729196730196731196732196733196734196735196736196737196738196739196740196741196742196743196744196745196746196747196748196749196750196751196752196753196754196755196756196757196758196759196760196761196762196763196764196765196766196767196768196769196770196771196772196773196774196775196776196777196778196779196780196781196782196783196784196785196786196787196788196789196790196791196792196793196794196795196796196797196798196799196800196801196802196803196804196805196806196807196808196809196810196811196812196813196814196815196816196817196818196819196820196821196822196823196824196825196826196827196828196829196830196831196832196833196834196835196836196837196838196839196840196841196842196843196844196845196846196847196848196849196850196851196852196853196854196855196856196857196858196859196860196861196862196863196864196865196866196867196868196869196870196871196872196873196874196875196876196877196878196879196880196881196882196883196884196885196886196887196888196889196890196891196892196893196894196895196896196897196898196899196900196901196902196903196904196905196906196907196908196909196910196911196912196913196914196915196916196917196918196919196920196921196922196923196924196925196926196927196928196929196930196931196932196933196934196935196936196937196938196939196940196941196942196943196944196945196946196947196948196949196950196951196952196953196954196955196956196957196958196959196960196961196962196963196964196965196966196967196968196969196970196971196972196973196974196975196976196977196978196979196980196981196982196983196984196985196986196987196988196989196990196991196992196993196994196995196996196997196998196999197000197001197002197003197004197005197006197007197008197009197010197011197012197013197014197015197016197017197018197019197020197021197022197023197024197025197026197027197028197029197030197031197032197033197034197035197036197037197038197039197040197041197042197043197044197045197046197047197048197049197050197051197052197053197054197055197056197057197058197059197060197061197062197063197064197065197066197067197068197069197070197071197072197073197074197075197076197077197078197079197080197081197082197083197084197085197086197087197088197089197090197091197092197093197094197095197096197097197098197099197100197101197102197103197104197105197106197107197108197109197110197111197112197113197114197115197116197117197118197119197120197121197122197123197124197125197126197127197128197129197130197131197132197133197134197135197136197137197138197139197140197141197142197143197144197145197146197147197148197149197150197151197152197153197154197155197156197157197158197159197160197161197162197163197164197165197166197167197168197169197170197171197172197173197174197175197176197177197178197179197180197181197182197183197184197185197186197187197188197189197190197191197192197193197194197195197196197197197198197199197200197201197202197203197204197205197206197207197208197209197210197211197212197213197214197215197216197217197218197219197220197221197222197223197224197225197226197227197228197229197230197231197232197233197234197235197236197237197238197239197240197241197242197243197244197245197246197247197248197249197250197251197252197253197254197255197256197257197258197259197260197261197262197263197264197265197266197267197268197269197270197271197272197273197274197275197276197277197278197279197280197281197282197283197284197285197286197287197288197289197290197291197292197293197294197295197296197297197298197299197300197301197302197303197304197305197306197307197308197309197310197311197312197313197314197315197316197317197318197319197320197321197322197323197324197325197326197327197328197329197330197331197332197333197334197335197336197337197338197339197340197341197342197343197344197345197346197347197348197349197350197351197352197353197354197355197356197357197358197359197360197361197362197363197364197365197366197367197368197369197370197371197372197373197374197375197376197377197378197379197380197381197382197383197384197385197386197387197388197389197390197391197392197393197394197395197396197397197398197399197400197401197402197403197404197405197406197407197408197409197410197411197412197413197414197415197416197417197418197419197420197421197422197423197424197425197426197427197428197429197430197431197432197433197434197435197436197437197438197439197440197441197442197443197444197445197446197447197448197449197450197451197452197453197454197455197456197457197458197459197460197461197462197463197464197465197466197467197468197469197470197471197472197473197474197475197476197477197478197479197480197481197482197483197484197485197486197487197488197489197490197491197492197493197494197495197496197497197498197499197500197501197502197503197504197505197506197507197508197509197510197511197512197513197514197515197516197517197518197519197520197521197522197523197524197525197526197527197528197529197530197531197532197533197534197535197536197537197538197539197540197541197542197543197544197545197546197547197548197549197550197551197552197553197554197555197556197557197558197559197560197561197562197563197564197565197566197567197568197569197570197571197572197573197574197575197576197577197578197579197580197581197582197583197584197585197586197587197588197589197590197591197592197593197594197595197596197597197598197599197600197601197602197603197604197605197606197607197608197609197610197611197612197613197614197615197616197617197618197619197620197621197622197623197624197625197626197627197628197629197630197631197632197633197634197635197636197637197638197639197640197641197642197643197644197645197646197647197648197649197650197651197652197653197654197655197656197657197658197659197660197661197662197663197664197665197666197667197668197669197670197671197672197673197674197675197676197677197678197679197680197681197682197683197684197685197686197687197688197689197690197691197692197693197694197695197696197697197698197699197700197701197702197703197704197705197706197707197708197709197710197711197712197713197714197715197716197717197718197719197720197721197722197723197724197725197726197727197728197729197730197731197732197733197734197735197736197737197738197739197740197741197742197743197744197745197746197747197748197749197750197751197752197753197754197755197756197757197758197759197760197761197762197763197764197765197766197767197768197769197770197771197772197773197774197775197776197777197778197779197780197781197782197783197784197785197786197787197788197789197790197791197792197793197794197795197796197797197798197799197800197801197802197803197804197805197806197807197808197809197810197811197812197813197814197815197816197817197818197819197820197821197822197823197824197825197826197827197828197829197830197831197832197833197834197835197836197837197838197839197840197841197842197843197844197845197846197847197848197849197850197851197852197853197854197855197856197857197858197859197860197861197862197863197864197865197866197867197868197869197870197871197872197873197874197875197876197877197878197879197880197881197882197883197884197885197886197887197888197889197890197891197892197893197894197895197896197897197898197899197900197901197902197903197904197905197906197907197908197909197910197911197912197913197914197915197916197917197918197919197920197921197922197923197924197925197926197927197928197929197930197931197932197933197934197935197936197937197938197939197940197941197942197943197944197945197946197947197948197949197950197951197952197953197954197955197956197957197958197959197960197961197962197963197964197965197966197967197968197969197970197971197972197973197974197975197976197977197978197979197980197981197982197983197984197985197986197987197988197989197990197991197992197993197994197995197996197997197998197999198000198001198002198003198004198005198006198007198008198009198010198011198012198013198014198015198016198017198018198019198020198021198022198023198024198025198026198027198028198029198030198031198032198033198034198035198036198037198038198039198040198041198042198043198044198045198046198047198048198049198050198051198052198053198054198055198056198057198058198059198060198061198062198063198064198065198066198067198068198069198070198071198072198073198074198075198076198077198078198079198080198081198082198083198084198085198086198087198088198089198090198091198092198093198094198095198096198097198098198099198100198101198102198103198104198105198106198107198108198109198110198111198112198113198114198115198116198117198118198119198120198121198122198123198124198125198126198127198128198129198130198131198132198133198134198135198136198137198138198139198140198141198142198143198144198145198146198147198148198149198150198151198152198153198154198155198156198157198158198159198160198161198162198163198164198165198166198167198168198169198170198171198172198173198174198175198176198177198178198179198180198181198182198183198184198185198186198187198188198189198190198191198192198193198194198195198196198197198198198199198200198201198202198203198204198205198206198207198208198209198210198211198212198213198214198215198216198217198218198219198220198221198222198223198224198225198226198227198228198229198230198231198232198233198234198235198236198237198238198239198240198241198242198243198244198245198246198247198248198249198250198251198252198253198254198255198256198257198258198259198260198261198262198263198264198265198266198267198268198269198270198271198272198273198274198275198276198277198278198279198280198281198282198283198284198285198286198287198288198289198290198291198292198293198294198295198296198297198298198299198300198301198302198303198304198305198306198307198308198309198310198311198312198313198314198315198316198317198318198319198320198321198322198323198324198325198326198327198328198329198330198331198332198333198334198335198336198337198338198339198340198341198342198343198344198345198346198347198348198349198350198351198352198353198354198355198356198357198358198359198360198361198362198363198364198365198366198367198368198369198370198371198372198373198374198375198376198377198378198379198380198381198382198383198384198385198386198387198388198389198390198391198392198393198394198395198396198397198398198399198400198401198402198403198404198405198406198407198408198409198410198411198412198413198414198415198416198417198418198419198420198421198422198423198424198425198426198427198428198429198430198431198432198433198434198435198436198437198438198439198440198441198442198443198444198445198446198447198448198449198450198451198452198453198454198455198456198457198458198459198460198461198462198463198464198465198466198467198468198469198470198471198472198473198474198475198476198477198478198479198480198481198482198483198484198485198486198487198488198489198490198491198492198493198494198495198496198497198498198499198500198501198502198503198504198505198506198507198508198509198510198511198512198513198514198515198516198517198518198519198520198521198522198523198524198525198526198527198528198529198530198531198532198533198534198535198536198537198538198539198540198541198542198543198544198545198546198547198548198549198550198551198552198553198554198555198556198557198558198559198560198561198562198563198564198565198566198567198568198569198570198571198572198573198574198575198576198577198578198579198580198581198582198583198584198585198586198587198588198589198590198591198592198593198594198595198596198597198598198599198600198601198602198603198604198605198606198607198608198609198610198611198612198613198614198615198616198617198618198619198620198621198622198623198624198625198626198627198628198629198630198631198632198633198634198635198636198637198638198639198640198641198642198643198644198645198646198647198648198649198650198651198652198653198654198655198656198657198658198659198660198661198662198663198664198665198666198667198668198669198670198671198672198673198674198675198676198677198678198679198680198681198682198683198684198685198686198687198688198689198690198691198692198693198694198695198696198697198698198699198700198701198702198703198704198705198706198707198708198709198710198711198712198713198714198715198716198717198718198719198720198721198722198723198724198725198726198727198728198729198730198731198732198733198734198735198736198737198738198739198740198741198742198743198744198745198746198747198748198749198750198751198752198753198754198755198756198757198758198759198760198761198762198763198764198765198766198767198768198769198770198771198772198773198774198775198776198777198778198779198780198781198782198783198784198785198786198787198788198789198790198791198792198793198794198795198796198797198798198799198800198801198802198803198804198805198806198807198808198809198810198811198812198813198814198815198816198817198818198819198820198821198822198823198824198825198826198827198828198829198830198831198832198833198834198835198836198837198838198839198840198841198842198843198844198845198846198847198848198849198850198851198852198853198854198855198856198857198858198859198860198861198862198863198864198865198866198867198868198869198870198871198872198873198874198875198876198877198878198879198880198881198882198883198884198885198886198887198888198889198890198891198892198893198894198895198896198897198898198899198900198901198902198903198904198905198906198907198908198909198910198911198912198913198914198915198916198917198918198919198920198921198922198923198924198925198926198927198928198929198930198931198932198933198934198935198936198937198938198939198940198941198942198943198944198945198946198947198948198949198950198951198952198953198954198955198956198957198958198959198960198961198962198963198964198965198966198967198968198969198970198971198972198973198974198975198976198977198978198979198980198981198982198983198984198985198986198987198988198989198990198991198992198993198994198995198996198997198998198999199000199001199002199003199004199005199006199007199008199009199010199011199012199013199014199015199016199017199018199019199020199021199022199023199024199025199026199027199028199029199030199031199032199033199034199035199036199037199038199039199040199041199042199043199044199045199046199047199048199049199050199051199052199053199054199055199056199057199058199059199060199061199062199063199064199065199066199067199068199069199070199071199072199073199074199075199076199077199078199079199080199081199082199083199084199085199086199087199088199089199090199091199092199093199094199095199096199097199098199099199100199101199102199103199104199105199106199107199108199109199110199111199112199113199114199115199116199117199118199119199120199121199122199123199124199125199126199127199128199129199130199131199132199133199134199135199136199137199138199139199140199141199142199143199144199145199146199147199148199149199150199151199152199153199154199155199156199157199158199159199160199161199162199163199164199165199166199167199168199169199170199171199172199173199174199175199176199177199178199179199180199181199182199183199184199185199186199187199188199189199190199191199192199193199194199195199196199197199198199199199200199201199202199203199204199205199206199207199208199209199210199211199212199213199214199215199216199217199218199219199220199221199222199223199224199225199226199227199228199229199230199231199232199233199234199235199236199237199238199239199240199241199242199243199244199245199246199247199248199249199250199251199252199253199254199255199256199257199258199259199260199261199262199263199264199265199266199267199268199269199270199271199272199273199274199275199276199277199278199279199280199281199282199283199284199285199286199287199288199289199290199291199292199293199294199295199296199297199298199299199300199301199302199303199304199305199306199307199308199309199310199311199312199313199314199315199316199317199318199319199320199321199322199323199324199325199326199327199328199329199330199331199332199333199334199335199336199337199338199339199340199341199342199343199344199345199346199347199348199349199350199351199352199353199354199355199356199357199358199359199360199361199362199363199364199365199366199367199368199369199370199371199372199373199374199375199376199377199378199379199380199381199382199383199384199385199386199387199388199389199390199391199392199393199394199395199396199397199398199399199400199401199402199403199404199405199406199407199408199409199410199411199412199413199414199415199416199417199418199419199420199421199422199423199424199425199426199427199428199429199430199431199432199433199434199435199436199437199438199439199440199441199442199443199444199445199446199447199448199449199450199451199452199453199454199455199456199457199458199459199460199461199462199463199464199465199466199467199468199469199470199471199472199473199474199475199476199477199478199479199480199481199482199483199484199485199486199487199488199489199490199491199492199493199494199495199496199497199498199499199500199501199502199503199504199505199506199507199508199509199510199511199512199513199514199515199516199517199518199519199520199521199522199523199524199525199526199527199528199529199530199531199532199533199534199535199536199537199538199539199540199541199542199543199544199545199546199547199548199549199550199551199552199553199554199555199556199557199558199559199560199561199562199563199564199565199566199567199568199569199570199571199572199573199574199575199576199577199578199579199580199581199582199583199584199585199586199587199588199589199590199591199592199593199594199595199596199597199598199599199600199601199602199603199604199605199606199607199608199609199610199611199612199613199614199615199616199617199618199619199620199621199622199623199624199625199626199627199628199629199630199631199632199633199634199635199636199637199638199639199640199641199642199643199644199645199646199647199648199649199650199651199652199653199654199655199656199657199658199659199660199661199662199663199664199665199666199667199668199669199670199671199672199673199674199675199676199677199678199679199680199681199682199683199684199685199686199687199688199689199690199691199692199693199694199695199696199697199698199699199700199701199702199703199704199705199706199707199708199709199710199711199712199713199714199715199716199717199718199719199720199721199722199723199724199725199726199727199728199729199730199731199732199733199734199735199736199737199738199739199740199741199742199743199744199745199746199747199748199749199750199751199752199753199754199755199756199757199758199759199760199761199762199763199764199765199766199767199768199769199770199771199772199773199774199775199776199777199778199779199780199781199782199783199784199785199786199787199788199789199790199791199792199793199794199795199796199797199798199799199800199801199802199803199804199805199806199807199808199809199810199811199812199813199814199815199816199817199818199819199820199821199822199823199824199825199826199827199828199829199830199831199832199833199834199835199836199837199838199839199840199841199842199843199844199845199846199847199848199849199850199851199852199853199854199855199856199857199858199859199860199861199862199863199864199865199866199867199868199869199870199871199872199873199874199875199876199877199878199879199880199881199882199883199884199885199886199887199888199889199890199891199892199893199894199895199896199897199898199899199900199901199902199903199904199905199906199907199908199909199910199911199912199913199914199915199916199917199918199919199920199921199922199923199924199925199926199927199928199929199930199931199932199933199934199935199936199937199938199939199940199941199942199943199944199945199946199947199948199949199950199951199952199953199954199955199956199957199958199959199960199961199962199963199964199965199966199967199968199969199970199971199972199973199974199975199976199977199978199979199980199981199982199983199984199985199986199987199988199989199990199991199992199993199994199995199996199997199998199999200000200001200002200003200004200005200006200007200008200009200010200011200012200013200014200015200016200017200018200019200020200021200022200023200024200025200026200027200028200029200030200031200032200033200034200035200036200037200038200039200040200041200042200043200044200045200046200047200048200049200050200051200052200053200054200055200056200057200058200059200060200061200062200063200064200065200066200067200068200069200070200071200072200073200074200075200076200077200078200079200080200081200082200083200084200085200086200087200088200089200090200091200092200093200094200095200096200097200098200099200100200101200102200103200104200105200106200107200108200109200110200111200112200113200114200115200116200117200118200119200120200121200122200123200124200125200126200127200128200129200130200131200132200133200134200135200136200137200138200139200140200141200142200143200144200145200146200147200148200149200150200151200152200153200154200155200156200157200158200159200160200161200162200163200164200165200166200167200168200169200170200171200172200173200174200175200176200177200178200179200180200181200182200183200184200185200186200187200188200189200190200191200192200193200194200195200196200197200198200199200200200201200202200203200204200205200206200207200208200209200210200211200212200213200214200215200216200217200218200219200220200221200222200223200224200225200226200227200228200229200230200231200232200233200234200235200236200237200238200239200240200241200242200243200244200245200246200247200248200249200250200251200252200253200254200255200256200257200258200259200260200261200262200263200264200265200266200267200268200269200270200271200272200273200274200275200276200277200278200279200280200281200282200283200284200285200286200287200288200289200290200291200292200293200294200295200296200297200298200299200300200301200302200303200304200305200306200307200308200309200310200311200312200313200314200315200316200317200318200319200320200321200322200323200324200325200326200327200328200329200330200331200332200333200334200335200336200337200338200339200340200341200342200343200344200345200346200347200348200349200350200351200352200353200354200355200356200357200358200359200360200361200362200363200364200365200366200367200368200369200370200371200372200373200374200375200376200377200378200379200380200381200382200383200384200385200386200387200388200389200390200391200392200393200394200395200396200397200398200399200400200401200402200403200404200405200406200407200408200409200410200411200412200413200414200415200416200417200418200419200420200421200422200423200424200425200426200427200428200429200430200431200432200433200434200435200436200437200438200439200440200441200442200443200444200445200446200447200448200449200450200451200452200453200454200455200456200457200458200459200460200461200462200463200464200465200466200467200468200469200470200471200472200473200474200475200476200477200478200479200480200481200482200483200484200485200486200487200488200489200490200491200492200493200494200495200496200497200498200499200500200501200502200503200504200505200506200507200508200509200510200511200512200513200514200515200516200517200518200519200520200521200522200523200524200525200526200527200528200529200530200531200532200533200534200535200536200537200538200539200540200541200542200543200544200545200546200547200548200549200550200551200552200553200554200555200556200557200558200559200560200561200562200563200564200565200566200567200568200569200570200571200572200573200574200575200576200577200578200579200580200581200582200583200584200585200586200587200588200589200590200591200592200593200594200595200596200597200598200599200600200601200602200603200604200605200606200607200608200609200610200611200612200613200614200615200616200617200618200619200620200621200622200623200624200625200626200627200628200629200630200631200632200633200634200635200636200637200638200639200640200641200642200643200644200645200646200647200648200649200650200651200652200653200654200655200656200657200658200659200660200661200662200663200664200665200666200667200668200669200670200671200672200673200674200675200676200677200678200679200680200681200682200683200684200685200686200687200688200689200690200691200692200693200694200695200696200697200698200699200700200701200702200703200704200705200706200707200708200709200710200711200712200713200714200715200716200717200718200719200720200721200722200723200724200725200726200727200728200729200730200731200732200733200734200735200736200737200738200739200740200741200742200743200744200745200746200747200748200749200750200751200752200753200754200755200756200757200758200759200760200761200762200763200764200765200766200767200768200769200770200771200772200773200774200775200776200777200778200779200780200781200782200783200784200785200786200787200788200789200790200791200792200793200794200795200796200797200798200799200800200801200802200803200804200805200806200807200808200809200810200811200812200813200814200815200816200817200818200819200820200821200822200823200824200825200826200827200828200829200830200831200832200833200834200835200836200837200838200839200840200841200842200843200844200845200846200847200848200849200850200851200852200853200854200855200856200857200858200859200860200861200862200863200864200865200866200867200868200869200870200871200872200873200874200875200876200877200878200879200880200881200882200883200884200885200886200887200888200889200890200891200892200893200894200895200896200897200898200899200900200901200902200903200904200905200906200907200908200909200910200911200912200913200914200915200916200917200918200919200920200921200922200923200924200925200926200927200928200929200930200931200932200933200934200935200936200937200938200939200940200941200942200943200944200945200946200947200948200949200950200951200952200953200954200955200956200957200958200959200960200961200962200963200964200965200966200967200968200969200970200971200972200973200974200975200976200977200978200979200980200981200982200983200984200985200986200987200988200989200990200991200992200993200994200995200996200997200998200999201000201001201002201003201004201005201006201007201008201009201010201011201012201013201014201015201016201017201018201019201020201021201022201023201024201025201026201027201028201029201030201031201032201033201034201035201036201037201038201039201040201041201042201043201044201045201046201047201048201049201050201051201052201053201054201055201056201057201058201059201060201061201062201063201064201065201066201067201068201069201070201071201072201073201074201075201076201077201078201079201080201081201082201083201084201085201086201087201088201089201090201091201092201093201094201095201096201097201098201099201100201101201102201103201104201105201106201107201108201109201110201111201112201113201114201115201116201117201118201119201120201121201122201123201124201125201126201127201128201129201130201131201132201133201134201135201136201137201138201139201140201141201142201143201144201145201146201147201148201149201150201151201152201153201154201155201156201157201158201159201160201161201162201163201164201165201166201167201168201169201170201171201172201173201174201175201176201177201178201179201180201181201182201183201184201185201186201187201188201189201190201191201192201193201194201195201196201197201198201199201200201201201202201203201204201205201206201207201208201209201210201211201212201213201214201215201216201217201218201219201220201221201222201223201224201225201226201227201228201229201230201231201232201233201234201235201236201237201238201239201240201241201242201243201244201245201246201247201248201249201250201251201252201253201254201255201256201257201258201259201260201261201262201263201264201265201266201267201268201269201270201271201272201273201274201275201276201277201278201279201280201281201282201283201284201285201286201287201288201289201290201291201292201293201294201295201296201297201298201299201300201301201302201303201304201305201306201307201308201309201310201311201312201313201314201315201316201317201318201319201320201321201322201323201324201325201326201327201328201329201330201331201332201333201334201335201336201337201338201339201340201341201342201343201344201345201346201347201348201349201350201351201352201353201354201355201356201357201358201359201360201361201362201363201364201365201366201367201368201369201370201371201372201373201374201375201376201377201378201379201380201381201382201383201384201385201386201387201388201389201390201391201392201393201394201395201396201397201398201399201400201401201402201403201404201405201406201407201408201409201410201411201412201413201414201415201416201417201418201419201420201421201422201423201424201425201426201427201428201429201430201431201432201433201434201435201436201437201438201439201440201441201442201443201444201445201446201447201448201449201450201451201452201453201454201455201456201457201458201459201460201461201462201463201464201465201466201467201468201469201470201471201472201473201474201475201476201477201478201479201480201481201482201483201484201485201486201487201488201489201490201491201492201493201494201495201496201497201498201499201500201501201502201503201504201505201506201507201508201509201510201511201512201513201514201515201516201517201518201519201520201521201522201523201524201525201526201527201528201529201530201531201532201533201534201535201536201537201538201539201540201541201542201543201544201545201546201547201548201549201550201551201552201553201554201555201556201557201558201559201560201561201562201563201564201565201566201567201568201569201570201571201572201573201574201575201576201577201578201579201580201581201582201583201584201585201586201587201588201589201590201591201592201593201594201595201596201597201598201599201600201601201602201603201604201605201606201607201608201609201610201611201612201613201614201615201616201617201618201619201620201621201622201623201624201625201626201627201628201629201630201631201632201633201634201635201636201637201638201639201640201641201642201643201644201645201646201647201648201649201650201651201652201653201654201655201656201657201658201659201660201661201662201663201664201665201666201667201668201669201670201671201672201673201674201675201676201677201678201679201680201681201682201683201684201685201686201687201688201689201690201691201692201693201694201695201696201697201698201699201700201701201702201703201704201705201706201707201708201709201710201711201712201713201714201715201716201717201718201719201720201721201722201723201724201725201726201727201728201729201730201731201732201733201734201735201736201737201738201739201740201741201742201743201744201745201746201747201748201749201750201751201752201753201754201755201756201757201758201759201760201761201762201763201764201765201766201767201768201769201770201771201772201773201774201775201776201777201778201779201780201781201782201783201784201785201786201787201788201789201790201791201792201793201794201795201796201797201798201799201800201801201802201803201804201805201806201807201808201809201810201811201812201813201814201815201816201817201818201819201820201821201822201823201824201825201826201827201828201829201830201831201832201833201834201835201836201837201838201839201840201841201842201843201844201845201846201847201848201849201850201851201852201853201854201855201856201857201858201859201860201861201862201863201864201865201866201867201868201869201870201871201872201873201874201875201876201877201878201879201880201881201882201883201884201885201886201887201888201889201890201891201892201893201894201895201896201897201898201899201900201901201902201903201904201905201906201907201908201909201910201911201912201913201914201915201916201917201918201919201920201921201922201923201924201925201926201927201928201929201930201931201932201933201934201935201936201937201938201939201940201941201942201943201944201945201946201947201948201949201950201951201952201953201954201955201956201957201958201959201960201961201962201963201964201965201966201967201968201969201970201971201972201973201974201975201976201977201978201979201980201981201982201983201984201985201986201987201988201989201990201991201992201993201994201995201996201997201998201999202000202001202002202003202004202005202006202007202008202009202010202011202012202013202014202015202016202017202018202019202020202021202022202023202024202025202026202027202028202029202030202031202032202033202034202035202036202037202038202039202040202041202042202043202044202045202046202047202048202049202050202051202052202053202054202055202056202057202058202059202060202061202062202063202064202065202066202067202068202069202070202071202072202073202074202075202076202077202078202079202080202081202082202083202084202085202086202087202088202089202090202091202092202093202094202095202096202097202098202099202100202101202102202103202104202105202106202107202108202109202110202111202112202113202114202115202116202117202118202119202120202121202122202123202124202125202126202127202128202129202130202131202132202133202134202135202136202137202138202139202140202141202142202143202144202145202146202147202148202149202150202151202152202153202154202155202156202157202158202159202160202161202162202163202164202165202166202167202168202169202170202171202172202173202174202175202176202177202178202179202180202181202182202183202184202185202186202187202188202189202190202191202192202193202194202195202196202197202198202199202200202201202202202203202204202205202206202207202208202209202210202211202212202213202214202215202216202217202218202219202220202221202222202223202224202225202226202227202228202229202230202231202232202233202234202235202236202237202238202239202240202241202242202243202244202245202246202247202248202249202250202251202252202253202254202255202256202257202258202259202260202261202262202263202264202265202266202267202268202269202270202271202272202273202274202275202276202277202278202279202280202281202282202283202284202285202286202287202288202289202290202291202292202293202294202295202296202297202298202299202300202301202302202303202304202305202306202307202308202309202310202311202312202313202314202315202316202317202318202319202320202321202322202323202324202325202326202327202328202329202330202331202332202333202334202335202336202337202338202339202340202341202342202343202344202345202346202347202348202349202350202351202352202353202354202355202356202357202358202359202360202361202362202363202364202365202366202367202368202369202370202371202372202373202374202375202376202377202378202379202380202381202382202383202384202385202386202387202388202389202390202391202392202393202394202395202396202397202398202399202400202401202402202403202404202405202406202407202408202409202410202411202412202413202414202415202416202417202418202419202420202421202422202423202424202425202426202427202428202429202430202431202432202433202434202435202436202437202438202439202440202441202442202443202444202445202446202447202448202449202450202451202452202453202454202455202456202457202458202459202460202461202462202463202464202465202466202467202468202469202470202471202472202473202474202475202476202477202478202479202480202481202482202483202484202485202486202487202488202489202490202491202492202493202494202495202496202497202498202499202500202501202502202503202504202505202506202507202508202509202510202511202512202513202514202515202516202517202518202519202520202521202522202523202524202525202526202527202528202529202530202531202532202533202534202535202536202537202538202539202540202541202542202543202544202545202546202547202548202549202550202551202552202553202554202555202556202557202558202559202560202561202562202563202564202565202566202567202568202569202570202571202572202573202574202575202576202577202578202579202580202581202582202583202584202585202586202587202588202589202590202591202592202593202594202595202596202597202598202599202600202601202602202603202604202605202606202607202608202609202610202611202612202613202614202615202616202617202618202619202620202621202622202623202624202625202626202627202628202629202630202631202632202633202634202635202636202637202638202639202640202641202642202643202644202645202646202647202648202649202650202651202652202653202654202655202656202657202658202659202660202661202662202663202664202665202666202667202668202669202670202671202672202673202674202675202676202677202678202679202680202681202682202683202684202685202686202687202688202689202690202691202692202693202694202695202696202697202698202699202700202701202702202703202704202705202706202707202708202709202710202711202712202713202714202715202716202717202718202719202720202721202722202723202724202725202726202727202728202729202730202731202732202733202734202735202736202737202738202739202740202741202742202743202744202745202746202747202748202749202750202751202752202753202754202755202756202757202758202759202760202761202762202763202764202765202766202767202768202769202770202771202772202773202774202775202776202777202778202779202780202781202782202783202784202785202786202787202788202789202790202791202792202793202794202795202796202797202798202799202800202801202802202803202804202805202806202807202808202809202810202811202812202813202814202815202816202817202818202819202820202821202822202823202824202825202826202827202828202829202830202831202832202833202834202835202836202837202838202839202840202841202842202843202844202845202846202847202848202849202850202851202852202853202854202855202856202857202858202859202860202861202862202863202864202865202866202867202868202869202870202871202872202873202874202875202876202877202878202879202880202881202882202883202884202885202886202887202888202889202890202891202892202893202894202895202896202897202898202899202900202901202902202903202904202905202906202907202908202909202910202911202912202913202914202915202916202917202918202919202920202921202922202923202924202925202926202927202928202929202930202931202932202933202934202935202936202937202938202939202940202941202942202943202944202945202946202947202948202949202950202951202952202953202954202955202956202957202958202959202960202961202962202963202964202965202966202967202968202969202970202971202972202973202974202975202976202977202978202979202980202981202982202983202984202985202986202987202988202989202990202991202992202993202994202995202996202997202998202999203000203001203002203003203004203005203006203007203008203009203010203011203012203013203014203015203016203017203018203019203020203021203022203023203024203025203026203027203028203029203030203031203032203033203034203035203036203037203038203039203040203041203042203043203044203045203046203047203048203049203050203051203052203053203054203055203056203057203058203059203060203061203062203063203064203065203066203067203068203069203070203071203072203073203074203075203076203077203078203079203080203081203082203083203084203085203086203087203088203089203090203091203092203093203094203095203096203097203098203099203100203101203102203103203104203105203106203107203108203109203110203111203112203113203114203115203116203117203118203119203120203121203122203123203124203125203126203127203128203129203130203131203132203133203134203135203136203137203138203139203140203141203142203143203144203145203146203147203148203149203150203151203152203153203154203155203156203157203158203159203160203161203162203163203164203165203166203167203168203169203170203171203172203173203174203175203176203177203178203179203180203181203182203183203184203185203186203187203188203189203190203191203192203193203194203195203196203197203198203199203200203201203202203203203204203205203206203207203208203209203210203211203212203213203214203215203216203217203218203219203220203221203222203223203224203225203226203227203228203229203230203231203232203233203234203235203236203237203238203239203240203241203242203243203244203245203246203247203248203249203250203251203252203253203254203255203256203257203258203259203260203261203262203263203264203265203266203267203268203269203270203271203272203273203274203275203276203277203278203279203280203281203282203283203284203285203286203287203288203289203290203291203292203293203294203295203296203297203298203299203300203301203302203303203304203305203306203307203308203309203310203311203312203313203314203315203316203317203318203319203320203321203322203323203324203325203326203327203328203329203330203331203332203333203334203335203336203337203338203339203340203341203342203343203344203345203346203347203348203349203350203351203352203353203354203355203356203357203358203359203360203361203362203363203364203365203366203367203368203369203370203371203372203373203374203375203376203377203378203379203380203381203382203383203384203385203386203387203388203389203390203391203392203393203394203395203396203397203398203399203400203401203402203403203404203405203406203407203408203409203410203411203412203413203414203415203416203417203418203419203420203421203422203423203424203425203426203427203428203429203430203431203432203433203434203435203436203437203438203439203440203441203442203443203444203445203446203447203448203449203450203451203452203453203454203455203456203457203458203459203460203461203462203463203464203465203466203467203468203469203470203471203472203473203474203475203476203477203478203479203480203481203482203483203484203485203486203487203488203489203490203491203492203493203494203495203496203497203498203499203500203501203502203503203504203505203506203507203508203509203510203511203512203513203514203515203516203517203518203519203520203521203522203523203524203525203526203527203528203529203530203531203532203533203534203535203536203537203538203539203540203541203542203543203544203545203546203547203548203549203550203551203552203553203554203555203556203557203558203559203560203561203562203563203564203565203566203567203568203569203570203571203572203573203574203575203576203577203578203579203580203581203582203583203584203585203586203587203588203589203590203591203592203593203594203595203596203597203598203599203600203601203602203603203604203605203606203607203608203609203610203611203612203613203614203615203616203617203618203619203620203621203622203623203624203625203626203627203628203629203630203631203632203633203634203635203636203637203638203639203640203641203642203643203644203645203646203647203648203649203650203651203652203653203654203655203656203657203658203659203660203661203662203663203664203665203666203667203668203669203670203671203672203673203674203675203676203677203678203679203680203681203682203683203684203685203686203687203688203689203690203691203692203693203694203695203696203697203698203699203700203701203702203703203704203705203706203707203708203709203710203711203712203713203714203715203716203717203718203719203720203721203722203723203724203725203726203727203728203729203730203731203732203733203734203735203736203737203738203739203740203741203742203743203744203745203746203747203748203749203750203751203752203753203754203755203756203757203758203759203760203761203762203763203764203765203766203767203768203769203770203771203772203773203774203775203776203777203778203779203780203781203782203783203784203785203786203787203788203789203790203791203792203793203794203795203796203797203798203799203800203801203802203803203804203805203806203807203808203809203810203811203812203813203814203815203816203817203818203819203820203821203822203823203824203825203826203827203828203829203830203831203832203833203834203835203836203837203838203839203840203841203842203843203844203845203846203847203848203849203850203851203852203853203854203855203856203857203858203859203860203861203862203863203864203865203866203867203868203869203870203871203872203873203874203875203876203877203878203879203880203881203882203883203884203885203886203887203888203889203890203891203892203893203894203895203896203897203898203899203900203901203902203903203904203905203906203907203908203909203910203911203912203913203914203915203916203917203918203919203920203921203922203923203924203925203926203927203928203929203930203931203932203933203934203935203936203937203938203939203940203941203942203943203944203945203946203947203948203949203950203951203952203953203954203955203956203957203958203959203960203961203962203963203964203965203966203967203968203969203970203971203972203973203974203975203976203977203978203979203980203981203982203983203984203985203986203987203988203989203990203991203992203993203994203995203996203997203998203999204000204001204002204003204004204005204006204007204008204009204010204011204012204013204014204015204016204017204018204019204020204021204022204023204024204025204026204027204028204029204030204031204032204033204034204035204036204037204038204039204040204041204042204043204044204045204046204047204048204049204050204051204052204053204054204055204056204057204058204059204060204061204062204063204064204065204066204067204068204069204070204071204072204073204074204075204076204077204078204079204080204081204082204083204084204085204086204087204088204089204090204091204092204093204094204095204096204097204098204099204100204101204102204103204104204105204106204107204108204109204110204111204112204113204114204115204116204117204118204119204120204121204122204123204124204125204126204127204128204129204130204131204132204133204134204135204136204137204138204139204140204141204142204143204144204145204146204147204148204149204150204151204152204153204154204155204156204157204158204159204160204161204162204163204164204165204166204167204168204169204170204171204172204173204174204175204176204177204178204179204180204181204182204183204184204185204186204187204188204189204190204191204192204193204194204195204196204197204198204199204200204201204202204203204204204205204206204207204208204209204210204211204212204213204214204215204216204217204218204219204220204221204222204223204224204225204226204227204228204229204230204231204232204233204234204235204236204237204238204239204240204241204242204243204244204245204246204247204248204249204250204251204252204253204254204255204256204257204258204259204260204261204262204263204264204265204266204267204268204269204270204271204272204273204274204275204276204277204278204279204280204281204282204283204284204285204286204287204288204289204290204291204292204293204294204295204296204297204298204299204300204301204302204303204304204305204306204307204308204309204310204311204312204313204314204315204316204317204318204319204320204321204322204323204324204325204326204327204328204329204330204331204332204333204334204335204336204337204338204339204340204341204342204343204344204345204346204347204348204349204350204351204352204353204354204355204356204357204358204359204360204361204362204363204364204365204366204367204368204369204370204371204372204373204374204375204376204377204378204379204380204381204382204383204384204385204386204387204388204389204390204391204392204393204394204395204396204397204398204399204400204401204402204403204404204405204406204407204408204409204410204411204412204413204414204415204416204417204418204419204420204421204422204423204424204425204426204427204428204429204430204431204432204433204434204435204436204437204438204439204440204441204442204443204444204445204446204447204448204449204450204451204452204453204454204455204456204457204458204459204460204461204462204463204464204465204466204467204468204469204470204471204472204473204474204475204476204477204478204479204480204481204482204483204484204485204486204487204488204489204490204491204492204493204494204495204496204497204498204499204500204501204502204503204504204505204506204507204508204509204510204511204512204513204514204515204516204517204518204519204520204521204522204523204524204525204526204527204528204529204530204531204532204533204534204535204536204537204538204539204540204541204542204543204544204545204546204547204548204549204550204551204552204553204554204555204556204557204558204559204560204561204562204563204564204565204566204567204568204569204570204571204572204573204574204575204576204577204578204579204580204581204582204583204584204585204586204587204588204589204590204591204592204593204594204595204596204597204598204599204600204601204602204603204604204605204606204607204608204609204610204611204612204613204614204615204616204617204618204619204620204621204622204623204624204625204626204627204628204629204630204631204632204633204634204635204636204637204638204639204640204641204642204643204644204645204646204647204648204649204650204651204652204653204654204655204656204657204658204659204660204661204662204663204664204665204666204667204668204669204670204671204672204673204674204675204676204677204678204679204680204681204682204683204684204685204686204687204688204689204690204691204692204693204694204695204696204697204698204699204700204701204702204703204704204705204706204707204708204709204710204711204712204713204714204715204716204717204718204719204720204721204722204723204724204725204726204727204728204729204730204731204732204733204734204735204736204737204738204739204740204741204742204743204744204745204746204747204748204749204750204751204752204753204754204755204756204757204758204759204760204761204762204763204764204765204766204767204768204769204770204771204772204773204774204775204776204777204778204779204780204781204782204783204784204785204786204787204788204789204790204791204792204793204794204795204796204797204798204799204800204801204802204803204804204805204806204807204808204809204810204811204812204813204814204815204816204817204818204819204820204821204822204823204824204825204826204827204828204829204830204831204832204833204834204835204836204837204838204839204840204841204842204843204844204845204846204847204848204849204850204851204852204853204854204855204856204857204858204859204860204861204862204863204864204865204866204867204868204869204870204871204872204873204874204875204876204877204878204879204880204881204882204883204884204885204886204887204888204889204890204891204892204893204894204895204896204897204898204899204900204901204902204903204904204905204906204907204908204909204910204911204912204913204914204915204916204917204918204919204920204921204922204923204924204925204926204927204928204929204930204931204932204933204934204935204936204937204938204939204940204941204942204943204944204945204946204947204948204949204950204951204952204953204954204955204956204957204958204959204960204961204962204963204964204965204966204967204968204969204970204971204972204973204974204975204976204977204978204979204980204981204982204983204984204985204986204987204988204989204990204991204992204993204994204995204996204997204998204999205000205001205002205003205004205005205006205007205008205009205010205011205012205013205014205015205016205017205018205019205020205021205022205023205024205025205026205027205028205029205030205031205032205033205034205035205036205037205038205039205040205041205042205043205044205045205046205047205048205049205050205051205052205053205054205055205056205057205058205059205060205061205062205063205064205065205066205067205068205069205070205071205072205073205074205075205076205077205078205079205080205081205082205083205084205085205086205087205088205089205090205091205092205093205094205095205096205097205098205099205100205101205102205103205104205105205106205107205108205109205110205111205112205113205114205115205116205117205118205119205120205121205122205123205124205125205126205127205128205129205130205131205132205133205134205135205136205137205138205139205140205141205142205143205144205145205146205147205148205149205150205151205152205153205154205155205156205157205158205159205160205161205162205163205164205165205166205167205168205169205170205171205172205173205174205175205176205177205178205179205180205181205182205183205184205185205186205187205188205189205190205191205192205193205194205195205196205197205198205199205200205201205202205203205204205205205206205207205208205209205210205211205212205213205214205215205216205217205218205219205220205221205222205223205224205225205226205227205228205229205230205231205232205233205234205235205236205237205238205239205240205241205242205243205244205245205246205247205248205249205250205251205252205253205254205255205256205257205258205259205260205261205262205263205264205265205266205267205268205269205270205271205272205273205274205275205276205277205278205279205280205281205282205283205284205285205286205287205288205289205290205291205292205293205294205295205296205297205298205299205300205301205302205303205304205305205306205307205308205309205310205311205312205313205314205315205316205317205318205319205320205321205322205323205324205325205326205327205328205329205330205331205332205333205334205335205336205337205338205339205340205341205342205343205344205345205346205347205348205349205350205351205352205353205354205355205356205357205358205359205360205361205362205363205364205365205366205367205368205369205370205371205372205373205374205375205376205377205378205379205380205381205382205383205384205385205386205387205388205389205390205391205392205393205394205395205396205397205398205399205400205401205402205403205404205405205406205407205408205409205410205411205412205413205414205415205416205417205418205419205420205421205422205423205424205425205426205427205428205429205430205431205432205433205434205435205436205437205438205439205440205441205442205443205444205445205446205447205448205449205450205451205452205453205454205455205456205457205458205459205460205461205462205463205464205465205466205467205468205469205470205471205472205473205474205475205476205477205478205479205480205481205482205483205484205485205486205487205488205489205490205491205492205493205494205495205496205497205498205499205500205501205502205503205504205505205506205507205508205509205510205511205512205513205514205515205516205517205518205519205520205521205522205523205524205525205526205527205528205529205530205531205532205533205534205535205536205537205538205539205540205541205542205543205544205545205546205547205548205549205550205551205552205553205554205555205556205557205558205559205560205561205562205563205564205565205566205567205568205569205570205571205572205573205574205575205576205577205578205579205580205581205582205583205584205585205586205587205588205589205590205591205592205593205594205595205596205597205598205599205600205601205602205603205604205605205606205607205608205609205610205611205612205613205614205615205616205617205618205619205620205621205622205623205624205625205626205627205628205629205630205631205632205633205634205635205636205637205638205639205640205641205642205643205644205645205646205647205648205649205650205651205652205653205654205655205656205657205658205659205660205661205662205663205664205665205666205667205668205669205670205671205672205673205674205675205676205677205678205679205680205681205682205683205684205685205686205687205688205689205690205691205692205693205694205695205696205697205698205699205700205701205702205703205704205705205706205707205708205709205710205711205712205713205714205715205716205717205718205719205720205721205722205723205724205725205726205727205728205729205730205731205732205733205734205735205736205737205738205739205740205741205742205743205744205745205746205747205748205749205750205751205752205753205754205755205756205757205758205759205760205761205762205763205764205765205766205767205768205769205770205771205772205773205774205775205776205777205778205779205780205781205782205783205784205785205786205787205788205789205790205791205792205793205794205795205796205797205798205799205800205801205802205803205804205805205806205807205808205809205810205811205812205813205814205815205816205817205818205819205820205821205822205823205824205825205826205827205828205829205830205831205832205833205834205835205836205837205838205839205840205841205842205843205844205845205846205847205848205849205850205851205852205853205854205855205856205857205858205859205860205861205862205863205864205865205866205867205868205869205870205871205872205873205874205875205876205877205878205879205880205881205882205883205884205885205886205887205888205889205890205891205892205893205894205895205896205897205898205899205900205901205902205903205904205905205906205907205908205909205910205911205912205913205914205915205916205917205918205919205920205921205922205923205924205925205926205927205928205929205930205931205932205933205934205935205936205937205938205939205940205941205942205943205944205945205946205947205948205949205950205951205952205953205954205955205956205957205958205959205960205961205962205963205964205965205966205967205968205969205970205971205972205973205974205975205976205977205978205979205980205981205982205983205984205985205986205987205988205989205990205991205992205993205994205995205996205997205998205999206000206001206002206003206004206005206006206007206008206009206010206011206012206013206014206015206016206017206018206019206020206021206022206023206024206025206026206027206028206029206030206031206032206033206034206035206036206037206038206039206040206041206042206043206044206045206046206047206048206049206050206051206052206053206054206055206056206057206058206059206060206061206062206063206064206065206066206067206068206069206070206071206072206073206074206075206076206077206078206079206080206081206082206083206084206085206086206087206088206089206090206091206092206093206094206095206096206097206098206099206100206101206102206103206104206105206106206107206108206109206110206111206112206113206114206115206116206117206118206119206120206121206122206123206124206125206126206127206128206129206130206131206132206133206134206135206136206137206138206139206140206141206142206143206144206145206146206147206148206149206150206151206152206153206154206155206156206157206158206159206160206161206162206163206164206165206166206167206168206169206170206171206172206173206174206175206176206177206178206179206180206181206182206183206184206185206186206187206188206189206190206191206192206193206194206195206196206197206198206199206200206201206202206203206204206205206206206207206208206209206210206211206212206213206214206215206216206217206218206219206220206221206222206223206224206225206226206227206228206229206230206231206232206233206234206235206236206237206238206239206240206241206242206243206244206245206246206247206248206249206250206251206252206253206254206255206256206257206258206259206260206261206262206263206264206265206266206267206268206269206270206271206272206273206274206275206276206277206278206279206280206281206282206283206284206285206286206287206288206289206290206291206292206293206294206295206296206297206298206299206300206301206302206303206304206305206306206307206308206309206310206311206312206313206314206315206316206317206318206319206320206321206322206323206324206325206326206327206328206329206330206331206332206333206334206335206336206337206338206339206340206341206342206343206344206345206346206347206348206349206350206351206352206353206354206355206356206357206358206359206360206361206362206363206364206365206366206367206368206369206370206371206372206373206374206375206376206377206378206379206380206381206382206383206384206385206386206387206388206389206390206391206392206393206394206395206396206397206398206399206400206401206402206403206404206405206406206407206408206409206410206411206412206413206414206415206416206417206418206419206420206421206422206423206424206425206426206427206428206429206430206431206432206433206434206435206436206437206438206439206440206441206442206443206444206445206446206447206448206449206450206451206452206453206454206455206456206457206458206459206460206461206462206463206464206465206466206467206468206469206470206471206472206473206474206475206476206477206478206479206480206481206482206483206484206485206486206487206488206489206490206491206492206493206494206495206496206497206498206499206500206501206502206503206504206505206506206507206508206509206510206511206512206513206514206515206516206517206518206519206520206521206522206523206524206525206526206527206528206529206530206531206532206533206534206535206536206537206538206539206540206541206542206543206544206545206546206547206548206549206550206551206552206553206554206555206556206557206558206559206560206561206562206563206564206565206566206567206568206569206570206571206572206573206574206575206576206577206578206579206580206581206582206583206584206585206586206587206588206589206590206591206592206593206594206595206596206597206598206599206600206601206602206603206604206605206606206607206608206609206610206611206612206613206614206615206616206617206618206619206620206621206622206623206624206625206626206627206628206629206630206631206632206633206634206635206636206637206638206639206640206641206642206643206644206645206646206647206648206649206650206651206652206653206654206655206656206657206658206659206660206661206662206663206664206665206666206667206668206669206670206671206672206673206674206675206676206677206678206679206680206681206682206683206684206685206686206687206688206689206690206691206692206693206694206695206696206697206698206699206700206701206702206703206704206705206706206707206708206709206710206711206712206713206714206715206716206717206718206719206720206721206722206723206724206725206726206727206728206729206730206731206732206733206734206735206736206737206738206739206740206741206742206743206744206745206746206747206748206749206750206751206752206753206754206755206756206757206758206759206760206761206762206763206764206765206766206767206768206769206770206771206772206773206774206775206776206777206778206779206780206781206782206783206784206785206786206787206788206789206790206791206792206793206794206795206796206797206798206799206800206801206802206803206804206805206806206807206808206809206810206811206812206813206814206815206816206817206818206819206820206821206822206823206824206825206826206827206828206829206830206831206832206833206834206835206836206837206838206839206840206841206842206843206844206845206846206847206848206849206850206851206852206853206854206855206856206857206858206859206860206861206862206863206864206865206866206867206868206869206870206871206872206873206874206875206876206877206878206879206880206881206882206883206884206885206886206887206888206889206890206891206892206893206894206895206896206897206898206899206900206901206902206903206904206905206906206907206908206909206910206911206912206913206914206915206916206917206918206919206920206921206922206923206924206925206926206927206928206929206930206931206932206933206934206935206936206937206938206939206940206941206942206943206944206945206946206947206948206949206950206951206952206953206954206955206956206957206958206959206960206961206962206963206964206965206966206967206968206969206970206971206972206973206974206975206976206977206978206979206980206981206982206983206984206985206986206987206988206989206990206991206992206993206994206995206996206997206998206999207000207001207002207003207004207005207006207007207008207009207010207011207012207013207014207015207016207017207018207019207020207021207022207023207024207025207026207027207028207029207030207031207032207033207034207035207036207037207038207039207040207041207042207043207044207045207046207047207048207049207050207051207052207053207054207055207056207057207058207059207060207061207062207063207064207065207066207067207068207069207070207071207072207073207074207075207076207077207078207079207080207081207082207083207084207085207086207087207088207089207090207091207092207093207094207095207096207097207098207099207100207101207102207103207104207105207106207107207108207109207110207111207112207113207114207115207116207117207118207119207120207121207122207123207124207125207126207127207128207129207130207131207132207133207134207135207136207137207138207139207140207141207142207143207144207145207146207147207148207149207150207151207152207153207154207155207156207157207158207159207160207161207162207163207164207165207166207167207168207169207170207171207172207173207174207175207176207177207178207179207180207181207182207183207184207185207186207187207188207189207190207191207192207193207194207195207196207197207198207199207200207201207202207203207204207205207206207207207208207209207210207211207212207213207214207215207216207217207218207219207220207221207222207223207224207225207226207227207228207229207230207231207232207233207234207235207236207237207238207239207240207241207242207243207244207245207246207247207248207249207250207251207252207253207254207255207256207257207258207259207260207261207262207263207264207265207266207267207268207269207270207271207272207273207274207275207276207277207278207279207280207281207282207283207284207285207286207287207288207289207290207291207292207293207294207295207296207297207298207299207300207301207302207303207304207305207306207307207308207309207310207311207312207313207314207315207316207317207318207319207320207321207322207323207324207325207326207327207328207329207330207331207332207333207334207335207336207337207338207339207340207341207342207343207344207345207346207347207348207349207350207351207352207353207354207355207356207357207358207359207360207361207362207363207364207365207366207367207368207369207370207371207372207373207374207375207376207377207378207379207380207381207382207383207384207385207386207387207388207389207390207391207392207393207394207395207396207397207398207399207400207401207402207403207404207405207406207407207408207409207410207411207412207413207414207415207416207417207418207419207420207421207422207423207424207425207426207427207428207429207430207431207432207433207434207435207436207437207438207439207440207441207442207443207444207445207446207447207448207449207450207451207452207453207454207455207456207457207458207459207460207461207462207463207464207465207466207467207468207469207470207471207472207473207474207475207476207477207478207479207480207481207482207483207484207485207486207487207488207489207490207491207492207493207494207495207496207497207498207499207500207501207502207503207504207505207506207507207508207509207510207511207512207513207514207515207516207517207518207519207520207521207522207523207524207525207526207527207528207529207530207531207532207533207534207535207536207537207538207539207540207541207542207543207544207545207546207547207548207549207550207551207552207553207554207555207556207557207558207559207560207561207562207563207564207565207566207567207568207569207570207571207572207573207574207575207576207577207578207579207580207581207582207583207584207585207586207587207588207589207590207591207592207593207594207595207596207597207598207599207600207601207602207603207604207605207606207607207608207609207610207611207612207613207614207615207616207617207618207619207620207621207622207623207624207625207626207627207628207629207630207631207632207633207634207635207636207637207638207639207640207641207642207643207644207645207646207647207648207649207650207651207652207653207654207655207656207657207658207659207660207661207662207663207664207665207666207667207668207669207670207671207672207673207674207675207676207677207678207679207680207681207682207683207684207685207686207687207688207689207690207691207692207693207694207695207696207697207698207699207700207701207702207703207704207705207706207707207708207709207710207711207712207713207714207715207716207717207718207719207720207721207722207723207724207725207726207727207728207729207730207731207732207733207734207735207736207737207738207739207740207741207742207743207744207745207746207747207748207749207750207751207752207753207754207755207756207757207758207759207760207761207762207763207764207765207766207767207768207769207770207771207772207773207774207775207776207777207778207779207780207781207782207783207784207785207786207787207788207789207790207791207792207793207794207795207796207797207798207799207800207801207802207803207804207805207806207807207808207809207810207811207812207813207814207815207816207817207818207819207820207821207822207823207824207825207826207827207828207829207830207831207832207833207834207835207836207837207838207839207840207841207842207843207844207845207846207847207848207849207850207851207852207853207854207855207856207857207858207859207860207861207862207863207864207865207866207867207868207869207870207871207872207873207874207875207876207877207878207879207880207881207882207883207884207885207886207887207888207889207890207891207892207893207894207895207896207897207898207899207900207901207902207903207904207905207906207907207908207909207910207911207912207913207914207915207916207917207918207919207920207921207922207923207924207925207926207927207928207929207930207931207932207933207934207935207936207937207938207939207940207941207942207943207944207945207946207947207948207949207950207951207952207953207954207955207956207957207958207959207960207961207962207963207964207965207966207967207968207969207970207971207972207973207974207975207976207977207978207979207980207981207982207983207984207985207986207987207988207989207990207991207992207993207994207995207996207997207998207999208000208001208002208003208004208005208006208007208008208009208010208011208012208013208014208015208016208017208018208019208020208021208022208023208024208025208026208027208028208029208030208031208032208033208034208035208036208037208038208039208040208041208042208043208044208045208046208047208048208049208050208051208052208053208054208055208056208057208058208059208060208061208062208063208064208065208066208067208068208069208070208071208072208073208074208075208076208077208078208079208080208081208082208083208084208085208086208087208088208089208090208091208092208093208094208095208096208097208098208099208100208101208102208103208104208105208106208107208108208109208110208111208112208113208114208115208116208117208118208119208120208121208122208123208124208125208126208127208128208129208130208131208132208133208134208135208136208137208138208139208140208141208142208143208144208145208146208147208148208149208150208151208152208153208154208155208156208157208158208159208160208161208162208163208164208165208166208167208168208169208170208171208172208173208174208175208176208177208178208179208180208181208182208183208184208185208186208187208188208189208190208191208192208193208194208195208196208197208198208199208200208201208202208203208204208205208206208207208208208209208210208211208212208213208214208215208216208217208218208219208220208221208222208223208224208225208226208227208228208229208230208231208232208233208234208235208236208237208238208239208240208241208242208243208244208245208246208247208248208249208250208251208252208253208254208255208256208257208258208259208260208261208262208263208264208265208266208267208268208269208270208271208272208273208274208275208276208277208278208279208280208281208282208283208284208285208286208287208288208289208290208291208292208293208294208295208296208297208298208299208300208301208302208303208304208305208306208307208308208309208310208311208312208313208314208315208316208317208318208319208320208321208322208323208324208325208326208327208328208329208330208331208332208333208334208335208336208337208338208339208340208341208342208343208344208345208346208347208348208349208350208351208352208353208354208355208356208357208358208359208360208361208362208363208364208365208366208367208368208369208370208371208372208373208374208375208376208377208378208379208380208381208382208383208384208385208386208387208388208389208390208391208392208393208394208395208396208397208398208399208400208401208402208403208404208405208406208407208408208409208410208411208412208413208414208415208416208417208418208419208420208421208422208423208424208425208426208427208428208429208430208431208432208433208434208435208436208437208438208439208440208441208442208443208444208445208446208447208448208449208450208451208452208453208454208455208456208457208458208459208460208461208462208463208464208465208466208467208468208469208470208471208472208473208474208475208476208477208478208479208480208481208482208483208484208485208486208487208488208489208490208491208492208493208494208495208496208497208498208499208500208501208502208503208504208505208506208507208508208509208510208511208512208513208514208515208516208517208518208519208520208521208522208523208524208525208526208527208528208529208530208531208532208533208534208535208536208537208538208539208540208541208542208543208544208545208546208547208548208549208550208551208552208553208554208555208556208557208558208559208560208561208562208563208564208565208566208567208568208569208570208571208572208573208574208575208576208577208578208579208580208581208582208583208584208585208586208587208588208589208590208591208592208593208594208595208596208597208598208599208600208601208602208603208604208605208606208607208608208609208610208611208612208613208614208615208616208617208618208619208620208621208622208623208624208625208626208627208628208629208630208631208632208633208634208635208636208637208638208639208640208641208642208643208644208645208646208647208648208649208650208651208652208653208654208655208656208657208658208659208660208661208662208663208664208665208666208667208668208669208670208671208672208673208674208675208676208677208678208679208680208681208682208683208684208685208686208687208688208689208690208691208692208693208694208695208696208697208698208699208700208701208702208703208704208705208706208707208708208709208710208711208712208713208714208715208716208717208718208719208720208721208722208723208724208725208726208727208728208729208730208731208732208733208734208735208736208737208738208739208740208741208742208743208744208745208746208747208748208749208750208751208752208753208754208755208756208757208758208759208760208761208762208763208764208765208766208767208768208769208770208771208772208773208774208775208776208777208778208779208780208781208782208783208784208785208786208787208788208789208790208791208792208793208794208795208796208797208798208799208800208801208802208803208804208805208806208807208808208809208810208811208812208813208814208815208816208817208818208819208820208821208822208823208824208825208826208827208828208829208830208831208832208833208834208835208836208837208838208839208840208841208842208843208844208845208846208847208848208849208850208851208852208853208854208855208856208857208858208859208860208861208862208863208864208865208866208867208868208869208870208871208872208873208874208875208876208877208878208879208880208881208882208883208884208885208886208887208888208889208890208891208892208893208894208895208896208897208898208899208900208901208902208903208904208905208906208907208908208909208910208911208912208913208914208915208916208917208918208919208920208921208922208923208924208925208926208927208928208929208930208931208932208933208934208935208936208937208938208939208940208941208942208943208944208945208946208947208948208949208950208951208952208953208954208955208956208957208958208959208960208961208962208963208964208965208966208967208968208969208970208971208972208973208974208975208976208977208978208979208980208981208982208983208984208985208986208987208988208989208990208991208992208993208994208995208996208997208998208999209000209001209002209003209004209005209006209007209008209009209010209011209012209013209014209015209016209017209018209019209020209021209022209023209024209025209026209027209028209029209030209031209032209033209034209035209036209037209038209039209040209041209042209043209044209045209046209047209048209049209050209051209052209053209054209055209056209057209058209059209060209061209062209063209064209065209066209067209068209069209070209071209072209073209074209075209076209077209078209079209080209081209082209083209084209085209086209087209088209089209090209091209092209093209094209095209096209097209098209099209100209101209102209103209104209105209106209107209108209109209110209111209112209113209114209115209116209117209118209119209120209121209122209123209124209125209126209127209128209129209130209131209132209133209134209135209136209137209138209139209140209141209142209143209144209145209146209147209148209149209150209151209152209153209154209155209156209157209158209159209160209161209162209163209164209165209166209167209168209169209170209171209172209173209174209175209176209177209178209179209180209181209182209183209184209185209186209187209188209189209190209191209192209193209194209195209196209197209198209199209200209201209202209203209204209205209206209207209208209209209210209211209212209213209214209215209216209217209218209219209220209221209222209223209224209225209226209227209228209229209230209231209232209233209234209235209236209237209238209239209240209241209242209243209244209245209246209247209248209249209250209251209252209253209254209255209256209257209258209259209260209261209262209263209264209265209266209267209268209269209270209271209272209273209274209275209276209277209278209279209280209281209282209283209284209285209286209287209288209289209290209291209292209293209294209295209296209297209298209299209300209301209302209303209304209305209306209307209308209309209310209311209312209313209314209315209316209317209318209319209320209321209322209323209324209325209326209327209328209329209330209331209332209333209334209335209336209337209338209339209340209341209342209343209344209345209346209347209348209349209350209351209352209353209354209355209356209357209358209359209360209361209362209363209364209365209366209367209368209369209370209371209372209373209374209375209376209377209378209379209380209381209382209383209384209385209386209387209388209389209390209391209392209393209394209395209396209397209398209399209400209401209402209403209404209405209406209407209408209409209410209411209412209413209414209415209416209417209418209419209420209421209422209423209424209425209426209427209428209429209430209431209432209433209434209435209436209437209438209439209440209441209442209443209444209445209446209447209448209449209450209451209452209453209454209455209456209457209458209459209460209461209462209463209464209465209466209467209468209469209470209471209472209473209474209475209476209477209478209479209480209481209482209483209484209485209486209487209488209489209490209491209492209493209494209495209496209497209498209499209500209501209502209503209504209505209506209507209508209509209510209511209512209513209514209515209516209517209518209519209520209521209522209523209524209525209526209527209528209529209530209531209532209533209534209535209536209537209538209539209540209541209542209543209544209545209546209547209548209549209550209551209552209553209554209555209556209557209558209559209560209561209562209563209564209565209566209567209568209569209570209571209572209573209574209575209576209577209578209579209580209581209582209583209584209585209586209587209588209589209590209591209592209593209594209595209596209597209598209599209600209601209602209603209604209605209606209607209608209609209610209611209612209613209614209615209616209617209618209619209620209621209622209623209624209625209626209627209628209629209630209631209632209633209634209635209636209637209638209639209640209641209642209643209644209645209646209647209648209649209650209651209652209653209654209655209656209657209658209659209660209661209662209663209664209665209666209667209668209669209670209671209672209673209674209675209676209677209678209679209680209681209682209683209684209685209686209687209688209689209690209691209692209693209694209695209696209697209698209699209700209701209702209703209704209705209706209707209708209709209710209711209712209713209714209715209716209717209718209719209720209721209722209723209724209725209726209727209728209729209730209731209732209733209734209735209736209737209738209739209740209741209742209743209744209745209746209747209748209749209750209751209752209753209754209755209756209757209758209759209760209761209762209763209764209765209766209767209768209769209770209771209772209773209774209775209776209777209778209779209780209781209782209783209784209785209786209787209788209789209790209791209792209793209794209795209796209797209798209799209800209801209802209803209804209805209806209807209808209809209810209811209812209813209814209815209816209817209818209819209820209821209822209823209824209825209826209827209828209829209830209831209832209833209834209835209836209837209838209839209840209841209842209843209844209845209846209847209848209849209850209851209852209853209854209855209856209857209858209859209860209861209862209863209864209865209866209867209868209869209870209871209872209873209874209875209876209877209878209879209880209881209882209883209884209885209886209887209888209889209890209891209892209893209894209895209896209897209898209899209900209901209902209903209904209905209906209907209908209909209910209911209912209913209914209915209916209917209918209919209920209921209922209923209924209925209926209927209928209929209930209931209932209933209934209935209936209937209938209939209940209941209942209943209944209945209946209947209948209949209950209951209952209953209954209955209956209957209958209959209960209961209962209963209964209965209966209967209968209969209970209971209972209973209974209975209976209977209978209979209980209981209982209983209984209985209986209987209988209989209990209991209992209993209994209995209996209997209998209999210000210001210002210003210004210005210006210007210008210009210010210011210012210013210014210015210016210017210018210019210020210021210022210023210024210025210026210027210028210029210030210031210032210033210034210035210036210037210038210039210040210041210042210043210044210045210046210047210048210049210050210051210052210053210054210055210056210057210058210059210060210061210062210063210064210065210066210067210068210069210070210071210072210073210074210075210076210077210078210079210080210081210082210083210084210085210086210087210088210089210090210091210092210093210094210095210096210097210098210099210100210101210102210103210104210105210106210107210108210109210110210111210112210113210114210115210116210117210118210119210120210121210122210123210124210125210126210127210128210129210130210131210132210133210134210135210136210137210138210139210140210141210142210143210144210145210146210147210148210149210150210151210152210153210154210155210156210157210158210159210160210161210162210163210164210165210166210167210168210169210170210171210172210173210174210175210176210177210178210179210180210181210182210183210184210185210186210187210188210189210190210191210192210193210194210195210196210197210198210199210200210201210202210203210204210205210206210207210208210209210210210211210212210213210214210215210216210217210218210219210220210221210222210223210224210225210226210227210228210229210230210231210232210233210234210235210236210237210238210239210240210241210242210243210244210245210246210247210248210249210250210251210252210253210254210255210256210257210258210259210260210261210262210263210264210265210266210267210268210269210270210271210272210273210274210275210276210277210278210279210280210281210282210283210284210285210286210287210288210289210290210291210292210293210294210295210296210297210298210299210300210301210302210303210304210305210306210307210308210309210310210311210312210313210314210315210316210317210318210319210320210321210322210323210324210325210326210327210328210329210330210331210332210333210334210335210336210337210338210339210340210341210342210343210344210345210346210347210348210349210350210351210352210353210354210355210356210357210358210359210360210361210362210363210364210365210366210367210368210369210370210371210372210373210374210375210376210377210378210379210380210381210382210383210384210385210386210387210388210389210390210391210392210393210394210395210396210397210398210399210400210401210402210403210404210405210406210407210408210409210410210411210412210413210414210415210416210417210418210419210420210421210422210423210424210425210426210427210428210429210430210431210432210433210434210435210436210437210438210439210440210441210442210443210444210445210446210447210448210449210450210451210452210453210454210455210456210457210458210459210460210461210462210463210464210465210466210467210468210469210470210471210472210473210474210475210476210477210478210479210480210481210482210483210484210485210486210487210488210489210490210491210492210493210494210495210496210497210498210499210500210501210502210503210504210505210506210507210508210509210510210511210512210513210514210515210516210517210518210519210520210521210522210523210524210525210526210527210528210529210530210531210532210533210534210535210536210537210538210539210540210541210542210543210544210545210546210547210548210549210550210551210552210553210554210555210556210557210558210559210560210561210562210563210564210565210566210567210568210569210570210571210572210573210574210575210576210577210578210579210580210581210582210583210584210585210586210587210588210589210590210591210592210593210594210595210596210597210598210599210600210601210602210603210604210605210606210607210608210609210610210611210612210613210614210615210616210617210618210619210620210621210622210623210624210625210626210627210628210629210630210631210632210633210634210635210636210637210638210639210640210641210642210643210644210645210646210647210648210649210650210651210652210653210654210655210656210657210658210659210660210661210662210663210664210665210666210667210668210669210670210671210672210673210674210675210676210677210678210679210680210681210682210683210684210685210686210687210688210689210690210691210692210693210694210695210696210697210698210699210700210701210702210703210704210705210706210707210708210709210710210711210712210713210714210715210716210717210718210719210720210721210722210723210724210725210726210727210728210729210730210731210732210733210734210735210736210737210738210739210740210741210742210743210744210745210746210747210748210749210750210751210752210753210754210755210756210757210758210759210760210761210762210763210764210765210766210767210768210769210770210771210772210773210774210775210776210777210778210779210780210781210782210783210784210785210786210787210788210789210790210791210792210793210794210795210796210797210798210799210800210801210802210803210804210805210806210807210808210809210810210811210812210813210814210815210816210817210818210819210820210821210822210823210824210825210826210827210828210829210830210831210832210833210834210835210836210837210838210839210840210841210842210843210844210845210846210847210848210849210850210851210852210853210854210855210856210857210858210859210860210861210862210863210864210865210866210867210868210869210870210871210872210873210874210875210876210877210878210879210880210881210882210883210884210885210886210887210888210889210890210891210892210893210894210895210896210897210898210899210900210901210902210903210904210905210906210907210908210909210910210911210912210913210914210915210916210917210918210919210920210921210922210923210924210925210926210927210928210929210930210931210932210933210934210935210936210937210938210939210940210941210942210943210944210945210946210947210948210949210950210951210952210953210954210955210956210957210958210959210960210961210962210963210964210965210966210967210968210969210970210971210972210973210974210975210976210977210978210979210980210981210982210983210984210985210986210987210988210989210990210991210992210993210994210995210996210997210998210999211000211001211002211003211004211005211006211007211008211009211010211011211012211013211014211015211016211017211018211019211020211021211022211023211024211025211026211027211028211029211030211031211032211033211034211035211036211037211038211039211040211041211042211043211044211045211046211047211048211049211050211051211052211053211054211055211056211057211058211059211060211061211062211063211064211065211066211067211068211069211070211071211072211073211074211075211076211077211078211079211080211081211082211083211084211085211086211087211088211089211090211091211092211093211094211095211096211097211098211099211100211101211102211103211104211105211106211107211108211109211110211111211112211113211114211115211116211117211118211119211120211121211122211123211124211125211126211127211128211129211130211131211132211133211134211135211136211137211138211139211140211141211142211143211144211145211146211147211148211149211150211151211152211153211154211155211156211157211158211159211160211161211162211163211164211165211166211167211168211169211170211171211172211173211174211175211176211177211178211179211180211181211182211183211184211185211186211187211188211189211190211191211192211193211194211195211196211197211198211199211200211201211202211203211204211205211206211207211208211209211210211211211212211213211214211215211216211217211218211219211220211221211222211223211224211225211226211227211228211229211230211231211232211233211234211235211236211237211238211239211240211241211242211243211244211245211246211247211248211249211250211251211252211253211254211255211256211257211258211259211260211261211262211263211264211265211266211267211268211269211270211271211272211273211274211275211276211277211278211279211280211281211282211283211284211285211286211287211288211289211290211291211292211293211294211295211296211297211298211299211300211301211302211303211304211305211306211307211308211309211310211311211312211313211314211315211316211317211318211319211320211321211322211323211324211325211326211327211328211329211330211331211332211333211334211335211336211337211338211339211340211341211342211343211344211345211346211347211348211349211350211351211352211353211354211355211356211357211358211359211360211361211362211363211364211365211366211367211368211369211370211371211372211373211374211375211376211377211378211379211380211381211382211383211384211385211386211387211388211389211390211391211392211393211394211395211396211397211398211399211400211401211402211403211404211405211406211407211408211409211410211411211412211413211414211415211416211417211418211419211420211421211422211423211424211425211426211427211428211429211430211431211432211433211434211435211436211437211438211439211440211441211442211443211444211445211446211447211448211449211450211451211452211453211454211455211456211457211458211459211460211461211462211463211464211465211466211467211468211469211470211471211472211473211474211475211476211477211478211479211480211481211482211483211484211485211486211487211488211489211490211491211492211493211494211495211496211497211498211499211500211501211502211503211504211505211506211507211508211509211510211511211512211513211514211515211516211517211518211519211520211521211522211523211524211525211526211527211528211529211530211531211532211533211534211535211536211537211538211539211540211541211542211543211544211545211546211547211548211549211550211551211552211553211554211555211556211557211558211559211560211561211562211563211564211565211566211567211568211569211570211571211572211573211574211575211576211577211578211579211580211581211582211583211584211585211586211587211588211589211590211591211592211593211594211595211596211597211598211599211600211601211602211603211604211605211606211607211608211609211610211611211612211613211614211615211616211617211618211619211620211621211622211623211624211625211626211627211628211629211630211631211632211633211634211635211636211637211638211639211640211641211642211643211644211645211646211647211648211649211650211651211652211653211654211655211656211657211658211659211660211661211662211663211664211665211666211667211668211669211670211671211672211673211674211675211676211677211678211679211680211681211682211683211684211685211686211687211688211689211690211691211692211693211694211695211696211697211698211699211700211701211702211703211704211705211706211707211708211709211710211711211712211713211714211715211716211717211718211719211720211721211722211723211724211725211726211727211728211729211730211731211732211733211734211735211736211737211738211739211740211741211742211743211744211745211746211747211748211749211750211751211752211753211754211755211756211757211758211759211760211761211762211763211764211765211766211767211768211769211770211771211772211773211774211775211776211777211778211779211780211781211782211783211784211785211786211787211788211789211790211791211792211793211794211795211796211797211798211799211800211801211802211803211804211805211806211807211808211809211810211811211812211813211814211815211816211817211818211819211820211821211822211823211824211825211826211827211828211829211830211831211832211833211834211835211836211837211838211839211840211841211842211843211844211845211846211847211848211849211850211851211852211853211854211855211856211857211858211859211860211861211862211863211864211865211866211867211868211869211870211871211872211873211874211875211876211877211878211879211880211881211882211883211884211885211886211887211888211889211890211891211892211893211894211895211896211897211898211899211900211901211902211903211904211905211906211907211908211909211910211911211912211913211914211915211916211917211918211919211920211921211922211923211924211925211926211927211928211929211930211931211932211933211934211935211936211937211938211939211940211941211942211943211944211945211946211947211948211949211950211951211952211953211954211955211956211957211958211959211960211961211962211963211964211965211966211967211968211969211970211971211972211973211974211975211976211977211978211979211980211981211982211983211984211985211986211987211988211989211990211991211992211993211994211995211996211997211998211999212000212001212002212003212004212005212006212007212008212009212010212011212012212013212014212015212016212017212018212019212020212021212022212023212024212025212026212027212028212029212030212031212032212033212034212035212036212037212038212039212040212041212042212043212044212045212046212047212048212049212050212051212052212053212054212055212056212057212058212059212060212061212062212063212064212065212066212067212068212069212070212071212072212073212074212075212076212077212078212079212080212081212082212083212084212085212086212087212088212089212090212091212092212093212094212095212096212097212098212099212100212101212102212103212104212105212106212107212108212109212110212111212112212113212114212115212116212117212118212119212120212121212122212123212124212125212126212127212128212129212130212131212132212133212134212135212136212137212138212139212140212141212142212143212144212145212146212147212148212149212150212151212152212153212154212155212156212157212158212159212160212161212162212163212164212165212166212167212168212169212170212171212172212173212174212175212176212177212178212179212180212181212182212183212184212185212186212187212188212189212190212191212192212193212194212195212196212197212198212199212200212201212202212203212204212205212206212207212208212209212210212211212212212213212214212215212216212217212218212219212220212221212222212223212224212225212226212227212228212229212230212231212232212233212234212235212236212237212238212239212240212241212242212243212244212245212246212247212248212249212250212251212252212253212254212255212256212257212258212259212260212261212262212263212264212265212266212267212268212269212270212271212272212273212274212275212276212277212278212279212280212281212282212283212284212285212286212287212288212289212290212291212292212293212294212295212296212297212298212299212300212301212302212303212304212305212306212307212308212309212310212311212312212313212314212315212316212317212318212319212320212321212322212323212324212325212326212327212328212329212330212331212332212333212334212335212336212337212338212339212340212341212342212343212344212345212346212347212348212349212350212351212352212353212354212355212356212357212358212359212360212361212362212363212364212365212366212367212368212369212370212371212372212373212374212375212376212377212378212379212380212381212382212383212384212385212386212387212388212389212390212391212392212393212394212395212396212397212398212399212400212401212402212403212404212405212406212407212408212409212410212411212412212413212414212415212416212417212418212419212420212421212422212423212424212425212426212427212428212429212430212431212432212433212434212435212436212437212438212439212440212441212442212443212444212445212446212447212448212449212450212451212452212453212454212455212456212457212458212459212460212461212462212463212464212465212466212467212468212469212470212471212472212473212474212475212476212477212478212479212480212481212482212483212484212485212486212487212488212489212490212491212492212493212494212495212496212497212498212499212500212501212502212503212504212505212506212507212508212509212510212511212512212513212514212515212516212517212518212519212520212521212522212523212524212525212526212527212528212529212530212531212532212533212534212535212536212537212538212539212540212541212542212543212544212545212546212547212548212549212550212551212552212553212554212555212556212557212558212559212560212561212562212563212564212565212566212567212568212569212570212571212572212573212574212575212576212577212578212579212580212581212582212583212584212585212586212587212588212589212590212591212592212593212594212595212596212597212598212599212600212601212602212603212604212605212606212607212608212609212610212611212612212613212614212615212616212617212618212619212620212621212622212623212624212625212626212627212628212629212630212631212632212633212634212635212636212637212638212639212640212641212642212643212644212645212646212647212648212649212650212651212652212653212654212655212656212657212658212659212660212661212662212663212664212665212666212667212668212669212670212671212672212673212674212675212676212677212678212679212680212681212682212683212684212685212686212687212688212689212690212691212692212693212694212695212696212697212698212699212700212701212702212703212704212705212706212707212708212709212710212711212712212713212714212715212716212717212718212719212720212721212722212723212724212725212726212727212728212729212730212731212732212733212734212735212736212737212738212739212740212741212742212743212744212745212746212747212748212749212750212751212752212753212754212755212756212757212758212759212760212761212762212763212764212765212766212767212768212769212770212771212772212773212774212775212776212777212778212779212780212781212782212783212784212785212786212787212788212789212790212791212792212793212794212795212796212797212798212799212800212801212802212803212804212805212806212807212808212809212810212811212812212813212814212815212816212817212818212819212820212821212822212823212824212825212826212827212828212829212830212831212832212833212834212835212836212837212838212839212840212841212842212843212844212845212846212847212848212849212850212851212852212853212854212855212856212857212858212859212860212861212862212863212864212865212866212867212868212869212870212871212872212873212874212875212876212877212878212879212880212881212882212883212884212885212886212887212888212889212890212891212892212893212894212895212896212897212898212899212900212901212902212903212904212905212906212907212908212909212910212911212912212913212914212915212916212917212918212919212920212921212922212923212924212925212926212927212928212929212930212931212932212933212934212935212936212937212938212939212940212941212942212943212944212945212946212947212948212949212950212951212952212953212954212955212956212957212958212959212960212961212962212963212964212965212966212967212968212969212970212971212972212973212974212975212976212977212978212979212980212981212982212983212984212985212986212987212988212989212990212991212992212993212994212995212996212997212998212999213000213001213002213003213004213005213006213007213008213009213010213011213012213013213014213015213016213017213018213019213020213021213022213023213024213025213026213027213028213029213030213031213032213033213034213035213036213037213038213039213040213041213042213043213044213045213046213047213048213049213050213051213052213053213054213055213056213057213058213059213060213061213062213063213064213065213066213067213068213069213070213071213072213073213074213075213076213077213078213079213080213081213082213083213084213085213086213087213088213089213090213091213092213093213094213095213096213097213098213099213100213101213102213103213104213105213106213107213108213109213110213111213112213113213114213115213116213117213118213119213120213121213122213123213124213125213126213127213128213129213130213131213132213133213134213135213136213137213138213139213140213141213142213143213144213145213146213147213148213149213150213151213152213153213154213155213156213157213158213159213160213161213162213163213164213165213166213167213168213169213170213171213172213173213174213175213176213177213178213179213180213181213182213183213184213185213186213187213188213189213190213191213192213193213194213195213196213197213198213199213200213201213202213203213204213205213206213207213208213209213210213211213212213213213214213215213216213217213218213219213220213221213222213223213224213225213226213227213228213229213230213231213232213233213234213235213236213237213238213239213240213241213242213243213244213245213246213247213248213249213250213251213252213253213254213255213256213257213258213259213260213261213262213263213264213265213266213267213268213269213270213271213272213273213274213275213276213277213278213279213280213281213282213283213284213285213286213287213288213289213290213291213292213293213294213295213296213297213298213299213300213301213302213303213304213305213306213307213308213309213310213311213312213313213314213315213316213317213318213319213320213321213322213323213324213325213326213327213328213329213330213331213332213333213334213335213336213337213338213339213340213341213342213343213344213345213346213347213348213349213350213351213352213353213354213355213356213357213358213359213360213361213362213363213364213365213366213367213368213369213370213371213372213373213374213375213376213377213378213379213380213381213382213383213384213385213386213387213388213389213390213391213392213393213394213395213396213397213398213399213400213401213402213403213404213405213406213407213408213409213410213411213412213413213414213415213416213417213418213419213420213421213422213423213424213425213426213427213428213429213430213431213432213433213434213435213436213437213438213439213440213441213442213443213444213445213446213447213448213449213450213451213452213453213454213455213456213457213458213459213460213461213462213463213464213465213466213467213468213469213470213471213472213473213474213475213476213477213478213479213480213481213482213483213484213485213486213487213488213489213490213491213492213493213494213495213496213497213498213499213500213501213502213503213504213505213506213507213508213509213510213511213512213513213514213515213516213517213518213519213520213521213522213523213524213525213526213527213528213529213530213531213532213533213534213535213536213537213538213539213540213541213542213543213544213545213546213547213548213549213550213551213552213553213554213555213556213557213558213559213560213561213562213563213564213565213566213567213568213569213570213571213572213573213574213575213576213577213578213579213580213581213582213583213584213585213586213587213588213589213590213591213592213593213594213595213596213597213598213599213600213601213602213603213604213605213606213607213608213609213610213611213612213613213614213615213616213617213618213619213620213621213622213623213624213625213626213627213628213629213630213631213632213633213634213635213636213637213638213639213640213641213642213643213644213645213646213647213648213649213650213651213652213653213654213655213656213657213658213659213660213661213662213663213664213665213666213667213668213669213670213671213672213673213674213675213676213677213678213679213680213681213682213683213684213685213686213687213688213689213690213691213692213693213694213695213696213697213698213699213700213701213702213703213704213705213706213707213708213709213710213711213712213713213714213715213716213717213718213719213720213721213722213723213724213725213726213727213728213729213730213731213732213733213734213735213736213737213738213739213740213741213742213743213744213745213746213747213748213749213750213751213752213753213754213755213756213757213758213759213760213761213762213763213764213765213766213767213768213769213770213771213772213773213774213775213776213777213778213779213780213781213782213783213784213785213786213787213788213789213790213791213792213793213794213795213796213797213798213799213800213801213802213803213804213805213806213807213808213809213810213811213812213813213814213815213816213817213818213819213820213821213822213823213824213825213826213827213828213829213830213831213832213833213834213835213836213837213838213839213840213841213842213843213844213845213846213847213848213849213850213851213852213853213854213855213856213857213858213859213860213861213862213863213864213865213866213867213868213869213870213871213872213873213874213875213876213877213878213879213880213881213882213883213884213885213886213887213888213889213890213891213892213893213894213895213896213897213898213899213900213901213902213903213904213905213906213907213908213909213910213911213912213913213914213915213916213917213918213919213920213921213922213923213924213925213926213927213928213929213930213931213932213933213934213935213936213937213938213939213940213941213942213943213944213945213946213947213948213949213950213951213952213953213954213955213956213957213958213959213960213961213962213963213964213965213966213967213968213969213970213971213972213973213974213975213976213977213978213979213980213981213982213983213984213985213986213987213988213989213990213991213992213993213994213995213996213997213998213999214000214001214002214003214004214005214006214007214008214009214010214011214012214013214014214015214016214017214018214019214020214021214022214023214024214025214026214027214028214029214030214031214032214033214034214035214036214037214038214039214040214041214042214043214044214045214046214047214048214049214050214051214052214053214054214055214056214057214058214059214060214061214062214063214064214065214066214067214068214069214070214071214072214073214074214075214076214077214078214079214080214081214082214083214084214085214086214087214088214089214090214091214092214093214094214095214096214097214098214099214100214101214102214103214104214105214106214107214108214109214110214111214112214113214114214115214116214117214118214119214120214121214122214123214124214125214126214127214128214129214130214131214132214133214134214135214136214137214138214139214140214141214142214143214144214145214146214147214148214149214150214151214152214153214154214155214156214157214158214159214160214161214162214163214164214165214166214167214168214169214170214171214172214173214174214175214176214177214178214179214180214181214182214183214184214185214186214187214188214189214190214191214192214193214194214195214196214197214198214199214200214201214202214203214204214205214206214207214208214209214210214211214212214213214214214215214216214217214218214219214220214221214222214223214224214225214226214227214228214229214230214231214232214233214234214235214236214237214238214239214240214241214242214243214244214245214246214247214248214249214250214251214252214253214254214255214256214257214258214259214260214261214262214263214264214265214266214267214268214269214270214271214272214273214274214275214276214277214278214279214280214281214282214283214284214285214286214287214288214289214290214291214292214293214294214295214296214297214298214299214300214301214302214303214304214305214306214307214308214309214310214311214312214313214314214315214316214317214318214319214320214321214322214323214324214325214326214327214328214329214330214331214332214333214334214335214336214337214338214339214340214341214342214343214344214345214346214347214348214349214350214351214352214353214354214355214356214357214358214359214360214361214362214363214364214365214366214367214368214369214370214371214372214373214374214375214376214377214378214379214380214381214382214383214384214385214386214387214388214389214390214391214392214393214394214395214396214397214398214399214400214401214402214403214404214405214406214407214408214409214410214411214412214413214414214415214416214417214418214419214420214421214422214423214424214425214426214427214428214429214430214431214432214433214434214435214436214437214438214439214440214441214442214443214444214445214446214447214448214449214450214451214452214453214454214455214456214457214458214459214460214461214462214463214464214465214466214467214468214469214470214471214472214473214474214475214476214477214478214479214480214481214482214483214484214485214486214487214488214489214490214491214492214493214494214495214496214497214498214499214500214501214502214503214504214505214506214507214508214509214510214511214512214513214514214515214516214517214518214519214520214521214522214523214524214525214526214527214528214529214530214531214532214533214534214535214536214537214538214539214540214541214542214543214544214545214546214547214548214549214550214551214552214553214554214555214556214557214558214559214560214561214562214563214564214565214566214567214568214569214570214571214572214573214574214575214576214577214578214579214580214581214582214583214584214585214586214587214588214589214590214591214592214593214594214595214596214597214598214599214600214601214602214603214604214605214606214607214608214609214610214611214612214613214614214615214616214617214618214619214620214621214622214623214624214625214626214627214628214629214630214631214632214633214634214635214636214637214638214639214640214641214642214643214644214645214646214647214648214649214650214651214652214653214654214655214656214657214658214659214660214661214662214663214664214665214666214667214668214669214670214671214672214673214674214675214676214677214678214679214680214681214682214683214684214685214686214687214688214689214690214691214692214693214694214695214696214697214698214699214700214701214702214703214704214705214706214707214708214709214710214711214712214713214714214715214716214717214718214719214720214721214722214723214724214725214726214727214728214729214730214731214732214733214734214735214736214737214738214739214740214741214742214743214744214745214746214747214748214749214750214751214752214753214754214755214756214757214758214759214760214761214762214763214764214765214766214767214768214769214770214771214772214773214774214775214776214777214778214779214780214781214782214783214784214785214786214787214788214789214790214791214792214793214794214795214796214797214798214799214800214801214802214803214804214805214806214807214808214809214810214811214812214813214814214815214816214817214818214819214820214821214822214823214824214825214826214827214828214829214830214831214832214833214834214835214836214837214838214839214840214841214842214843214844214845214846214847214848214849214850214851214852214853214854214855214856214857214858214859214860214861214862214863214864214865214866214867214868214869214870214871214872214873214874214875214876214877214878214879214880214881214882214883214884214885214886214887214888214889214890214891214892214893214894214895214896214897214898214899214900214901214902214903214904214905214906214907214908214909214910214911214912214913214914214915214916214917214918214919214920214921214922214923214924214925214926214927214928214929214930214931214932214933214934214935214936214937214938214939214940214941214942214943214944214945214946214947214948214949214950214951214952214953214954214955214956214957214958214959214960214961214962214963214964214965214966214967214968214969214970214971214972214973214974214975214976214977214978214979214980214981214982214983214984214985214986214987214988214989214990214991214992214993214994214995214996214997214998214999215000215001215002215003215004215005215006215007215008215009215010215011215012215013215014215015215016215017215018215019215020215021215022215023215024215025215026215027215028215029215030215031215032215033215034215035215036215037215038215039215040215041215042215043215044215045215046215047215048215049215050215051215052215053215054215055215056215057215058215059215060215061215062215063215064215065215066215067215068215069215070215071215072215073215074215075215076215077215078215079215080215081215082215083215084215085215086215087215088215089215090215091215092215093215094215095215096215097215098215099215100215101215102215103215104215105215106215107215108215109215110215111215112215113215114215115215116215117215118215119215120215121215122215123215124215125215126215127215128215129215130215131215132215133215134215135215136215137215138215139215140215141215142215143215144215145215146215147215148215149215150215151215152215153215154215155215156215157215158215159215160215161215162215163215164215165215166215167215168215169215170215171215172215173215174215175215176215177215178215179215180215181215182215183215184215185215186215187215188215189215190215191215192215193215194215195215196215197215198215199215200215201215202215203215204215205215206215207215208215209215210215211215212215213215214215215215216215217215218215219215220215221215222215223215224215225215226215227215228215229215230215231215232215233215234215235215236215237215238215239215240215241215242215243215244215245215246215247215248215249215250215251215252215253215254215255215256215257215258215259215260215261215262215263215264215265215266215267215268215269215270215271215272215273215274215275215276215277215278215279215280215281215282215283215284215285215286215287215288215289215290215291215292215293215294215295215296215297215298215299215300215301215302215303215304215305215306215307215308215309215310215311215312215313215314215315215316215317215318215319215320215321215322215323215324215325215326215327215328215329215330215331215332215333215334215335215336215337215338215339215340215341215342215343215344215345215346215347215348215349215350215351215352215353215354215355215356215357215358215359215360215361215362215363215364215365215366215367215368215369215370215371215372215373215374215375215376215377215378215379215380215381215382215383215384215385215386215387215388215389215390215391215392215393215394215395215396215397215398215399215400215401215402215403215404215405215406215407215408215409215410215411215412215413215414215415215416215417215418215419215420215421215422215423215424215425215426215427215428215429215430215431215432215433215434215435215436215437215438215439215440215441215442215443215444215445215446215447215448215449215450215451215452215453215454215455215456215457215458215459215460215461215462215463215464215465215466215467215468215469215470215471215472215473215474215475215476215477215478215479215480215481215482215483215484215485215486215487215488215489215490215491215492215493215494215495215496215497215498215499215500215501215502215503215504215505215506215507215508215509215510215511215512215513215514215515215516215517215518215519215520215521215522215523215524215525215526215527215528215529215530215531215532215533215534215535215536215537215538215539215540215541215542215543215544215545215546215547215548215549215550215551215552215553215554215555215556215557215558215559215560215561215562215563215564215565215566215567215568215569215570215571215572215573215574215575215576215577215578215579215580215581215582215583215584215585215586215587215588215589215590215591215592215593215594215595215596215597215598215599215600215601215602215603215604215605215606215607215608215609215610215611215612215613215614215615215616215617215618215619215620215621215622215623215624215625215626215627215628215629215630215631215632215633215634215635215636215637215638215639215640215641215642215643215644215645215646215647215648215649215650215651215652215653215654215655215656215657215658215659215660215661215662215663215664215665215666215667215668215669215670215671215672215673215674215675215676215677215678215679215680215681215682215683215684215685215686215687215688215689215690215691215692215693215694215695215696215697215698215699215700215701215702215703215704215705215706215707215708215709215710215711215712215713215714215715215716215717215718215719215720215721215722215723215724215725215726215727215728215729215730215731215732215733215734215735215736215737215738215739215740215741215742215743215744215745215746215747215748215749215750215751215752215753215754215755215756215757215758215759215760215761215762215763215764215765215766215767215768215769215770215771215772215773215774215775215776215777215778215779215780215781215782215783215784215785215786215787215788215789215790215791215792215793215794215795215796215797215798215799215800215801215802215803215804215805215806215807215808215809215810215811215812215813215814215815215816215817215818215819215820215821215822215823215824215825215826215827215828215829215830215831215832215833215834215835215836215837215838215839215840215841215842215843215844215845215846215847215848215849215850215851215852215853215854215855215856215857215858215859215860215861215862215863215864215865215866215867215868215869215870215871215872215873215874215875215876215877215878215879215880215881215882215883215884215885215886215887215888215889215890215891215892215893215894215895215896215897215898215899215900215901215902215903215904215905215906215907215908215909215910215911215912215913215914215915215916215917215918215919215920215921215922215923215924215925215926215927215928215929215930215931215932215933215934215935215936215937215938215939215940215941215942215943215944215945215946215947215948215949215950215951215952215953215954215955215956215957215958215959215960215961215962215963215964215965215966215967215968215969215970215971215972215973215974215975215976215977215978215979215980215981215982215983215984215985215986215987215988215989215990215991215992215993215994215995215996215997215998215999216000216001216002216003216004216005216006216007216008216009216010216011216012216013216014216015216016216017216018216019216020216021216022216023216024216025216026216027216028216029216030216031216032216033216034216035216036216037216038216039216040216041216042216043216044216045216046216047216048216049216050216051216052216053216054216055216056216057216058216059216060216061216062216063216064216065216066216067216068216069216070216071216072216073216074216075216076216077216078216079216080216081216082216083216084216085216086216087216088216089216090216091216092216093216094216095216096216097216098216099216100216101216102216103216104216105216106216107216108216109216110216111216112216113216114216115216116216117216118216119216120216121216122216123216124216125216126216127216128216129216130216131216132216133216134216135216136216137216138216139216140216141216142216143216144216145216146216147216148216149216150216151216152216153216154216155216156216157216158216159216160216161216162216163216164216165216166216167216168216169216170216171216172216173216174216175216176216177216178216179216180216181216182216183216184216185216186216187216188216189216190216191216192216193216194216195216196216197216198216199216200216201216202216203216204216205216206216207216208216209216210216211216212216213216214216215216216216217216218216219216220216221216222216223216224216225216226216227216228216229216230216231216232216233216234216235216236216237216238216239216240216241216242216243216244216245216246216247216248216249216250216251216252216253216254216255216256216257216258216259216260216261216262216263216264216265216266216267216268216269216270216271216272216273216274216275216276216277216278216279216280216281216282216283216284216285216286216287216288216289216290216291216292216293216294216295216296216297216298216299216300216301216302216303216304216305216306216307216308216309216310216311216312216313216314216315216316216317216318216319216320216321216322216323216324216325216326216327216328216329216330216331216332216333216334216335216336216337216338216339216340216341216342216343216344216345216346216347216348216349216350216351216352216353216354216355216356216357216358216359216360216361216362216363216364216365216366216367216368216369216370216371216372216373216374216375216376216377216378216379216380216381216382216383216384216385216386216387216388216389216390216391216392216393216394216395216396216397216398216399216400216401216402216403216404216405216406216407216408216409216410216411216412216413216414216415216416216417216418216419216420216421216422216423216424216425216426216427216428216429216430216431216432216433216434216435216436216437216438216439216440216441216442216443216444216445216446216447216448216449216450216451216452216453216454216455216456216457216458216459216460216461216462216463216464216465216466216467216468216469216470216471216472216473216474216475216476216477216478216479216480216481216482216483216484216485216486216487216488216489216490216491216492216493216494216495216496216497216498216499216500216501216502216503216504216505216506216507216508216509216510216511216512216513216514216515216516216517216518216519216520216521216522216523216524216525216526216527216528216529216530216531216532216533216534216535216536216537216538216539216540216541216542216543216544216545216546216547216548216549216550216551216552216553216554216555216556216557216558216559216560216561216562216563216564216565216566216567216568216569216570216571216572216573216574216575216576216577216578216579216580216581216582216583216584216585216586216587216588216589216590216591216592216593216594216595216596216597216598216599216600216601216602216603216604216605216606216607216608216609216610216611216612216613216614216615216616216617216618216619216620216621216622216623216624216625216626216627216628216629216630216631216632216633216634216635216636216637216638216639216640216641216642216643216644216645216646216647216648216649216650216651216652216653216654216655216656216657216658216659216660216661216662216663216664216665216666216667216668216669216670216671216672216673216674216675216676216677216678216679216680216681216682216683216684216685216686216687216688216689216690216691216692216693216694216695216696216697216698216699216700216701216702216703216704216705216706216707216708216709216710216711216712216713216714216715216716216717216718216719216720216721216722216723216724216725216726216727216728216729216730216731216732216733216734216735216736216737216738216739216740216741216742216743216744216745216746216747216748216749216750216751216752216753216754216755216756216757216758216759216760216761216762216763216764216765216766216767216768216769216770216771216772216773216774216775216776216777216778216779216780216781216782216783216784216785216786216787216788216789216790216791216792216793216794216795216796216797216798216799216800216801216802216803216804216805216806216807216808216809216810216811216812216813216814216815216816216817216818216819216820216821216822216823216824216825216826216827216828216829216830216831216832216833216834216835216836216837216838216839216840216841216842216843216844216845216846216847216848216849216850216851216852216853216854216855216856216857216858216859216860216861216862216863216864216865216866216867216868216869216870216871216872216873216874216875216876216877216878216879216880216881216882216883216884216885216886216887216888216889216890216891216892216893216894216895216896216897216898216899216900216901216902216903216904216905216906216907216908216909216910216911216912216913216914216915216916216917216918216919216920216921216922216923216924216925216926216927216928216929216930216931216932216933216934216935216936216937216938216939216940216941216942216943216944216945216946216947216948216949216950216951216952216953216954216955216956216957216958216959216960216961216962216963216964216965216966216967216968216969216970216971216972216973216974216975216976216977216978216979216980216981216982216983216984216985216986216987216988216989216990216991216992216993216994216995216996216997216998216999217000217001217002217003217004217005217006217007217008217009217010217011217012217013217014217015217016217017217018217019217020217021217022217023217024217025217026217027217028217029217030217031217032217033217034217035217036217037217038217039217040217041217042217043217044217045217046217047217048217049217050217051217052217053217054217055217056217057217058217059217060217061217062217063217064217065217066217067217068217069217070217071217072217073217074217075217076217077217078217079217080217081217082217083217084217085217086217087217088217089217090217091217092217093217094217095217096217097217098217099217100217101217102217103217104217105217106217107217108217109217110217111217112217113217114217115217116217117217118217119217120217121217122217123217124217125217126217127217128217129217130217131217132217133217134217135217136217137217138217139217140217141217142217143217144217145217146217147217148217149217150217151217152217153217154217155217156217157217158217159217160217161217162217163217164217165217166217167217168217169217170217171217172217173217174217175217176217177217178217179217180217181217182217183217184217185217186217187217188217189217190217191217192217193217194217195217196217197217198217199217200217201217202217203217204217205217206217207217208217209217210217211217212217213217214217215217216217217217218217219217220217221217222217223217224217225217226217227217228217229217230217231217232217233217234217235217236217237217238217239217240217241217242217243217244217245217246217247217248217249217250217251217252217253217254217255217256217257217258217259217260217261217262217263217264217265217266217267217268217269217270217271217272217273217274217275217276217277217278217279217280217281217282217283217284217285217286217287217288217289217290217291217292217293217294217295217296217297217298217299217300217301217302217303217304217305217306217307217308217309217310217311217312217313217314217315217316217317217318217319217320217321217322217323217324217325217326217327217328217329217330217331217332217333217334217335217336217337217338217339217340217341217342217343217344217345217346217347217348217349217350217351217352217353217354217355217356217357217358217359217360217361217362217363217364217365217366217367217368217369217370217371217372217373217374217375217376217377217378217379217380217381217382217383217384217385217386217387217388217389217390217391217392217393217394217395217396217397217398217399217400217401217402217403217404217405217406217407217408217409217410217411217412217413217414217415217416217417217418217419217420217421217422217423217424217425217426217427217428217429217430217431217432217433217434217435217436217437217438217439217440217441217442217443217444217445217446217447217448217449217450217451217452217453217454217455217456217457217458217459217460217461217462217463217464217465217466217467217468217469217470217471217472217473217474217475217476217477217478217479217480217481217482217483217484217485217486217487217488217489217490217491217492217493217494217495217496217497217498217499217500217501217502217503217504217505217506217507217508217509217510217511217512217513217514217515217516217517217518217519217520217521217522217523217524217525217526217527217528217529217530217531217532217533217534217535217536217537217538217539217540217541217542217543217544217545217546217547217548217549217550217551217552217553217554217555217556217557217558217559217560217561217562217563217564217565217566217567217568217569217570217571217572217573217574217575217576217577217578217579217580217581217582217583217584217585217586217587217588217589217590217591217592217593217594217595217596217597217598217599217600217601217602217603217604217605217606217607217608217609217610217611217612217613217614217615217616217617217618217619217620217621217622217623217624217625217626217627217628217629217630217631217632217633217634217635217636217637217638217639217640217641217642217643217644217645217646217647217648217649217650217651217652217653217654217655217656217657217658217659217660217661217662217663217664217665217666217667217668217669217670217671217672217673217674217675217676217677217678217679217680217681217682217683217684217685217686217687217688217689217690217691217692217693217694217695217696217697217698217699217700217701217702217703217704217705217706217707217708217709217710217711217712217713217714217715217716217717217718217719217720217721217722217723217724217725217726217727217728217729217730217731217732217733217734217735217736217737217738217739217740217741217742217743217744217745217746217747217748217749217750217751217752217753217754217755217756217757217758217759217760217761217762217763217764217765217766217767217768217769217770217771217772217773217774217775217776217777217778217779217780217781217782217783217784217785217786217787217788217789217790217791217792217793217794217795217796217797217798217799217800217801217802217803217804217805217806217807217808217809217810217811217812217813217814217815217816217817217818217819217820217821217822217823217824217825217826217827217828217829217830217831217832217833217834217835217836217837217838217839217840217841217842217843217844217845217846217847217848217849217850217851217852217853217854217855217856217857217858217859217860217861217862217863217864217865217866217867217868217869217870217871217872217873217874217875217876217877217878217879217880217881217882217883217884217885217886217887217888217889217890217891217892217893217894217895217896217897217898217899217900217901217902217903217904217905217906217907217908217909217910217911217912217913217914217915217916217917217918217919217920217921217922217923217924217925217926217927217928217929217930217931217932217933217934217935217936217937217938217939217940217941217942217943217944217945217946217947217948217949217950217951217952217953217954217955217956217957217958217959217960217961217962217963217964217965217966217967217968217969217970217971217972217973217974217975217976217977217978217979217980217981217982217983217984217985217986217987217988217989217990217991217992217993217994217995217996217997217998217999218000218001218002218003218004218005218006218007218008218009218010218011218012218013218014218015218016218017218018218019218020218021218022218023218024218025218026218027218028218029218030218031218032218033218034218035218036218037218038218039218040218041218042218043218044218045218046218047218048218049218050218051218052218053218054218055218056218057218058218059218060218061218062218063218064218065218066218067218068218069218070218071218072218073218074218075218076218077218078218079218080218081218082218083218084218085218086218087218088218089218090218091218092218093218094218095218096218097218098218099218100218101218102218103218104218105218106218107218108218109218110218111218112218113218114218115218116218117218118218119218120218121218122218123218124218125218126218127218128218129218130218131218132218133218134218135218136218137218138218139218140218141218142218143218144218145218146218147218148218149218150218151218152218153218154218155218156218157218158218159218160218161218162218163218164218165218166218167218168218169218170218171218172218173218174218175218176218177218178218179218180218181218182218183218184218185218186218187218188218189218190218191218192218193218194218195218196218197218198218199218200218201218202218203218204218205218206218207218208218209218210218211218212218213218214218215218216218217218218218219218220218221218222218223218224218225218226218227218228218229218230218231218232218233218234218235218236218237218238218239218240218241218242218243218244218245218246218247218248218249218250218251218252218253218254218255218256218257218258218259218260218261218262218263218264218265218266218267218268218269218270218271218272218273218274218275218276218277218278218279218280218281218282218283218284218285218286218287218288218289218290218291218292218293218294218295218296218297218298218299218300218301218302218303218304218305218306218307218308218309218310218311218312218313218314218315218316218317218318218319218320218321218322218323218324218325218326218327218328218329218330218331218332218333218334218335218336218337218338218339218340218341218342218343218344218345218346218347218348218349218350218351218352218353218354218355218356218357218358218359218360218361218362218363218364218365218366218367218368218369218370218371218372218373218374218375218376218377218378218379218380218381218382218383218384218385218386218387218388218389218390218391218392218393218394218395218396218397218398218399218400218401218402218403218404218405218406218407218408218409218410218411218412218413218414218415218416218417218418218419218420218421218422218423218424218425218426218427218428218429218430218431218432218433218434218435218436218437218438218439218440218441218442218443218444218445218446218447218448218449218450218451218452218453218454218455218456218457218458218459218460218461218462218463218464218465218466218467218468218469218470218471218472218473218474218475218476218477218478218479218480218481218482218483218484218485218486218487218488218489218490218491218492218493218494218495218496218497218498218499218500218501218502218503218504218505218506218507218508218509218510218511218512218513218514218515218516218517218518218519218520218521218522218523218524218525218526218527218528218529218530218531218532218533218534218535218536218537218538218539218540218541218542218543218544218545218546218547218548218549218550218551218552218553218554218555218556218557218558218559218560218561218562218563218564218565218566218567218568218569218570218571218572218573218574218575218576218577218578218579218580218581218582218583218584218585218586218587218588218589218590218591218592218593218594218595218596218597218598218599218600218601218602218603218604218605218606218607218608218609218610218611218612218613218614218615218616218617218618218619218620218621218622218623218624218625218626218627218628218629218630218631218632218633218634218635218636218637218638218639218640218641218642218643218644218645218646218647218648218649218650218651218652218653218654218655218656218657218658218659218660218661218662218663218664218665218666218667218668218669218670218671218672218673218674218675218676218677218678218679218680218681218682218683218684218685218686218687218688218689218690218691218692218693218694218695218696218697218698218699218700218701218702218703218704218705218706218707218708218709218710218711218712218713218714218715218716218717218718218719218720218721218722218723218724218725218726218727218728218729218730218731218732218733218734218735218736218737218738218739218740218741218742218743218744218745218746218747218748218749218750218751218752218753218754218755218756218757218758218759218760218761218762218763218764218765218766218767218768218769218770218771218772218773218774218775218776218777218778218779218780218781218782218783218784218785218786218787218788218789218790218791218792218793218794218795218796218797218798218799218800218801218802218803218804218805218806218807218808218809218810218811218812218813218814218815218816218817218818218819218820218821218822218823218824218825218826218827218828218829218830218831218832218833218834218835218836218837218838218839218840218841218842218843218844218845218846218847218848218849218850218851218852218853218854218855218856218857218858218859218860218861218862218863218864218865218866218867218868218869218870218871218872218873218874218875218876218877218878218879218880218881218882218883218884218885218886218887218888218889218890218891218892218893218894218895218896218897218898218899218900218901218902218903218904218905218906218907218908218909218910218911218912218913218914218915218916218917218918218919218920218921218922218923218924218925218926218927218928218929218930218931218932218933218934218935218936218937218938218939218940218941218942218943218944218945218946218947218948218949218950218951218952218953218954218955218956218957218958218959218960218961218962218963218964218965218966218967218968218969218970218971218972218973218974218975218976218977218978218979218980218981218982218983218984218985218986218987218988218989218990218991218992218993218994218995218996218997218998218999219000219001219002219003219004219005219006219007219008219009219010219011219012219013219014219015219016219017219018219019219020219021219022219023219024219025219026219027219028219029219030219031219032219033219034219035219036219037219038219039219040219041219042219043219044219045219046219047219048219049219050219051219052219053219054219055219056219057219058219059219060219061219062219063219064219065219066219067219068219069219070219071219072219073219074219075219076219077219078219079219080219081219082219083219084219085219086219087219088219089219090219091219092219093219094219095219096219097219098219099219100219101219102219103219104219105219106219107219108219109219110219111219112219113219114219115219116219117219118219119219120219121219122219123219124219125219126219127219128219129219130219131219132219133219134219135219136219137219138219139219140219141219142219143219144219145219146219147219148219149219150219151219152219153219154219155219156219157219158219159219160219161219162219163219164219165219166219167219168219169219170219171219172219173219174219175219176219177219178219179219180219181219182219183219184219185219186219187219188219189219190219191219192219193219194219195219196219197219198219199219200219201219202219203219204219205219206219207219208219209219210219211219212219213219214219215219216219217219218219219219220219221219222219223219224219225219226219227219228219229219230219231219232219233219234219235219236219237219238219239219240219241219242219243219244219245219246219247219248219249219250219251219252219253219254219255219256219257219258219259219260219261219262219263219264219265219266219267219268219269219270219271219272219273219274219275219276219277219278219279219280219281219282219283219284219285219286219287219288219289219290219291219292219293219294219295219296219297219298219299219300219301219302219303219304219305219306219307219308219309219310219311219312219313219314219315219316219317219318219319219320219321219322219323219324219325219326219327219328219329219330219331219332219333219334219335219336219337219338219339219340219341219342219343219344219345219346219347219348219349219350219351219352219353219354219355219356219357219358219359219360219361219362219363219364219365219366219367219368219369219370219371219372219373219374219375219376219377219378219379219380219381219382219383219384219385219386219387219388219389219390219391219392219393219394219395219396219397219398219399219400219401219402219403219404219405219406219407219408219409219410219411219412219413219414219415219416219417219418219419219420219421219422219423219424219425219426219427219428219429219430219431219432219433219434219435219436219437219438219439219440219441219442219443219444219445219446219447219448219449219450219451219452219453219454219455219456219457219458219459219460219461219462219463219464219465219466219467219468219469219470219471219472219473219474219475219476219477219478219479219480219481219482219483219484219485219486219487219488219489219490219491219492219493219494219495219496219497219498219499219500219501219502219503219504219505219506219507219508219509219510219511219512219513219514219515219516219517219518219519219520219521219522219523219524219525219526219527219528219529219530219531219532219533219534219535219536219537219538219539219540219541219542219543219544219545219546219547219548219549219550219551219552219553219554219555219556219557219558219559219560219561219562219563219564219565219566219567219568219569219570219571219572219573219574219575219576219577219578219579219580219581219582219583219584219585219586219587219588219589219590219591219592219593219594219595219596219597219598219599219600219601219602219603219604219605219606219607219608219609219610219611219612219613219614219615219616219617219618219619219620219621219622219623219624219625219626219627219628219629219630219631219632219633219634219635219636219637219638219639219640219641219642219643219644219645219646219647219648219649219650219651219652219653219654219655219656219657219658219659219660219661219662219663219664219665219666219667219668219669219670219671219672219673219674219675219676219677219678219679219680219681219682219683219684219685219686219687219688219689219690219691219692219693219694219695219696219697219698219699219700219701219702219703219704219705219706219707219708219709219710219711219712219713219714219715219716219717219718219719219720219721219722219723219724219725219726219727219728219729219730219731219732219733219734219735219736219737219738219739219740219741219742219743219744219745219746219747219748219749219750219751219752219753219754219755219756219757219758219759219760219761219762219763219764219765219766219767219768219769219770219771219772219773219774219775219776219777219778219779219780219781219782219783219784219785219786219787219788219789219790219791219792219793219794219795219796219797219798219799219800219801219802219803219804219805219806219807219808219809219810219811219812219813219814219815219816219817219818219819219820219821219822219823219824219825219826219827219828219829219830219831219832219833219834219835219836219837219838219839219840219841219842219843219844219845219846219847219848219849219850219851219852219853219854219855219856219857219858219859219860219861219862219863219864219865219866219867219868219869219870219871219872219873219874219875219876219877219878219879219880219881219882219883219884219885219886219887219888219889219890219891219892219893219894219895219896219897219898219899219900219901219902219903219904219905219906219907219908219909219910219911219912219913219914219915219916219917219918219919219920219921219922219923219924219925219926219927219928219929219930219931219932219933219934219935219936219937219938219939219940219941219942219943219944219945219946219947219948219949219950219951219952219953219954219955219956219957219958219959219960219961219962219963219964219965219966219967219968219969219970219971219972219973219974219975219976219977219978219979219980219981219982219983219984219985219986219987219988219989219990219991219992219993219994219995219996219997219998219999220000220001220002220003220004220005220006220007220008220009220010220011220012220013220014220015220016220017220018220019220020220021220022220023220024220025220026220027220028220029220030220031220032220033220034220035220036220037220038220039220040220041220042220043220044220045220046220047220048220049220050220051220052220053220054220055220056220057220058220059220060220061220062220063220064220065220066220067220068220069220070220071220072220073220074220075220076220077220078220079220080220081220082220083220084220085220086220087220088220089220090220091220092220093220094220095220096220097220098220099220100220101220102220103220104220105220106220107220108220109220110220111220112220113220114220115220116220117220118220119220120220121220122220123220124220125220126220127220128220129220130220131220132220133220134220135220136220137220138220139220140220141220142220143220144220145220146220147220148220149220150220151220152220153220154220155220156220157220158220159220160220161220162220163220164220165220166220167220168220169220170220171220172220173220174220175220176220177220178220179220180220181220182220183220184220185220186220187220188220189220190220191220192220193220194220195220196220197220198220199220200220201220202220203220204220205220206220207220208220209220210220211220212220213220214220215220216220217220218220219220220220221220222220223220224220225220226220227220228220229220230220231220232220233220234220235220236220237220238220239220240220241220242220243220244220245220246220247220248220249220250220251220252220253220254220255220256220257220258220259220260220261220262220263220264220265220266220267220268220269220270220271220272220273220274220275220276220277220278220279220280220281220282220283220284220285220286220287220288220289220290220291220292220293220294220295220296220297220298220299220300220301220302220303220304220305220306220307220308220309220310220311220312220313220314220315220316220317220318220319220320220321220322220323220324220325220326220327220328220329220330220331220332220333220334220335220336220337220338220339220340220341220342220343220344220345220346220347220348220349220350220351220352220353220354220355220356220357220358220359220360220361220362220363220364220365220366220367220368220369220370220371220372220373220374220375220376220377220378220379220380220381220382220383220384220385220386220387220388220389220390220391220392220393220394220395220396220397220398220399220400220401220402220403220404220405220406220407220408220409220410220411220412220413220414220415220416220417220418220419220420220421220422220423220424220425220426220427220428220429220430220431220432220433220434220435220436220437220438220439220440220441220442220443220444220445220446220447220448220449220450220451220452220453220454220455220456220457220458220459220460220461220462220463220464220465220466220467220468220469220470220471220472220473220474220475220476220477220478220479220480220481220482220483220484220485220486220487220488220489220490220491220492220493220494220495220496220497220498220499220500220501220502220503220504220505220506220507220508220509220510220511220512220513220514220515220516220517220518220519220520220521220522220523220524220525220526220527220528220529220530220531220532220533220534220535220536220537220538220539220540220541220542220543220544220545220546220547220548220549220550220551220552220553220554220555220556220557220558220559220560220561220562220563220564220565220566220567220568220569220570220571220572220573220574220575220576220577220578220579220580220581220582220583220584220585220586220587220588220589220590220591220592220593220594220595220596220597220598220599220600220601220602220603220604220605220606220607220608220609220610220611220612220613220614220615220616220617220618220619220620220621220622220623220624220625220626220627220628220629220630220631220632220633220634220635220636220637220638220639220640220641220642220643220644220645220646220647220648220649220650220651220652220653220654220655220656220657220658220659220660220661220662220663220664220665220666220667220668220669220670220671220672220673220674220675220676220677220678220679220680220681220682220683220684220685220686220687220688220689220690220691220692220693220694220695220696220697220698220699220700220701220702220703220704220705220706220707220708220709220710220711220712220713220714220715220716220717220718220719220720220721220722220723220724220725220726220727220728220729220730220731220732220733220734220735220736220737220738220739220740220741220742220743220744220745220746220747220748220749220750220751220752220753220754220755220756220757220758220759220760220761220762220763220764220765220766220767220768220769220770220771220772220773220774220775220776220777220778220779220780220781220782220783220784220785220786220787220788220789220790220791220792220793220794220795220796220797220798220799220800220801220802220803220804220805220806220807220808220809220810220811220812220813220814220815220816220817220818220819220820220821220822220823220824220825220826220827220828220829220830220831220832220833220834220835220836220837220838220839220840220841220842220843220844220845220846220847220848220849220850220851220852220853220854220855220856220857220858220859220860220861220862220863220864220865220866220867220868220869220870220871220872220873220874220875220876220877220878220879220880220881220882220883220884220885220886220887220888220889220890220891220892220893220894220895220896220897220898220899220900220901220902220903220904220905220906220907220908220909220910220911220912220913220914220915220916220917220918220919220920220921220922220923220924220925220926220927220928220929220930220931220932220933220934220935220936220937220938220939220940220941220942220943220944220945220946220947220948220949220950220951220952220953220954220955220956220957220958220959220960220961220962220963220964220965220966220967220968220969220970220971220972220973220974220975220976220977220978220979220980220981220982220983220984220985220986220987220988220989220990220991220992220993220994220995220996220997220998220999221000221001221002221003221004221005221006221007221008221009221010221011221012221013221014221015221016221017221018221019221020221021221022221023221024221025221026221027221028221029221030221031221032221033221034221035221036221037221038221039221040221041221042221043221044221045221046221047221048221049221050221051221052221053221054221055221056221057221058221059221060221061221062221063221064221065221066221067221068221069221070221071221072221073221074221075221076221077221078221079221080221081221082221083221084221085221086221087221088221089221090221091221092221093221094221095221096221097221098221099221100221101221102221103221104221105221106221107221108221109221110221111221112221113221114221115221116221117221118221119221120221121221122221123221124221125221126221127221128221129221130221131221132221133221134221135221136221137221138221139221140221141221142221143221144221145221146221147221148221149221150221151221152221153221154221155221156221157221158221159221160221161221162221163221164221165221166221167221168221169221170221171221172221173221174221175221176221177221178221179221180221181221182221183221184221185221186221187221188221189221190221191221192221193221194221195221196221197221198221199221200221201221202221203221204221205221206221207221208221209221210221211221212221213221214221215221216221217221218221219221220221221221222221223221224221225221226221227221228221229221230221231221232221233221234221235221236221237221238221239221240221241221242221243221244221245221246221247221248221249221250221251221252221253221254221255221256221257221258221259221260221261221262221263221264221265221266221267221268221269221270221271221272221273221274221275221276221277221278221279221280221281221282221283221284221285221286221287221288221289221290221291221292221293221294221295221296221297221298221299221300221301221302221303221304221305221306221307221308221309221310221311221312221313221314221315221316221317221318221319221320221321221322221323221324221325221326221327221328221329221330221331221332221333221334221335221336221337221338221339221340221341221342221343221344221345221346221347221348221349221350221351221352221353221354221355221356221357221358221359221360221361221362221363221364221365221366221367221368221369221370221371221372221373221374221375221376221377221378221379221380221381221382221383221384221385221386221387221388221389221390221391221392221393221394221395221396221397221398221399221400221401221402221403221404221405221406221407221408221409221410221411221412221413221414221415221416221417221418221419221420221421221422221423221424221425221426221427221428221429221430221431221432221433221434221435221436221437221438221439221440221441221442221443221444221445221446221447221448221449221450221451221452221453221454221455221456221457221458221459221460221461221462221463221464221465221466221467221468221469221470221471221472221473221474221475221476221477221478221479221480221481221482221483221484221485221486221487221488221489221490221491221492221493221494221495221496221497221498221499221500221501221502221503221504221505221506221507221508221509221510221511221512221513221514221515221516221517221518221519221520221521221522221523221524221525221526221527221528221529221530221531221532221533221534221535221536221537221538221539221540221541221542221543221544221545221546221547221548221549221550221551221552221553221554221555221556221557221558221559221560221561221562221563221564221565221566221567221568221569221570221571221572221573221574221575221576221577221578221579221580221581221582221583221584221585221586221587221588221589221590221591221592221593221594221595221596221597221598221599221600221601221602221603221604221605221606221607221608221609221610221611221612221613221614221615221616221617221618221619221620221621221622221623221624221625221626221627221628221629221630221631221632221633221634221635221636221637221638221639221640221641221642221643221644221645221646221647221648221649221650221651221652221653221654221655221656221657221658221659221660221661221662221663221664221665221666221667221668221669221670221671221672221673221674221675221676221677221678221679221680221681221682221683221684221685221686221687221688221689221690221691221692221693221694221695221696221697221698221699221700221701221702221703221704221705221706221707221708221709221710221711221712221713221714221715221716221717221718221719221720221721221722221723221724221725221726221727221728221729221730221731221732221733221734221735221736221737221738221739221740221741221742221743221744221745221746221747221748221749221750221751221752221753221754221755221756221757221758221759221760221761221762221763221764221765221766221767221768221769221770221771221772221773221774221775221776221777221778221779221780221781221782221783221784221785221786221787221788221789221790221791221792221793221794221795221796221797221798221799221800221801221802221803221804221805221806221807221808221809221810221811221812221813221814221815221816221817221818221819221820221821221822221823221824221825221826221827221828221829221830221831221832221833221834221835221836221837221838221839221840221841221842221843221844221845221846221847221848221849221850221851221852221853221854221855221856221857221858221859221860221861221862221863221864221865221866221867221868221869221870221871221872221873221874221875221876221877221878221879221880221881221882221883221884221885221886221887221888221889221890221891221892221893221894221895221896221897221898221899221900221901221902221903221904221905221906221907221908221909221910221911221912221913221914221915221916221917221918221919221920221921221922221923221924221925221926221927221928221929221930221931221932221933221934221935221936221937221938221939221940221941221942221943221944221945221946221947221948221949221950221951221952221953221954221955221956221957221958221959221960221961221962221963221964221965221966221967221968221969221970221971221972221973221974221975221976221977221978221979221980221981221982221983221984221985221986221987221988221989221990221991221992221993221994221995221996221997221998221999222000222001222002222003222004222005222006222007222008222009222010222011222012222013222014222015222016222017222018222019222020222021222022222023222024222025222026222027222028222029222030222031222032222033222034222035222036222037222038222039222040222041222042222043222044222045222046222047222048222049222050222051222052222053222054222055222056222057222058222059222060222061222062222063222064222065222066222067222068222069222070222071222072222073222074222075222076222077222078222079222080222081222082222083222084222085222086222087222088222089222090222091222092222093222094222095222096222097222098222099222100222101222102222103222104222105222106222107222108222109222110222111222112222113222114222115222116222117222118222119222120222121222122222123222124222125222126222127222128222129222130222131222132222133222134222135222136222137222138222139222140222141222142222143222144222145222146222147222148222149222150222151222152222153222154222155222156222157222158222159222160222161222162222163222164222165222166222167222168222169222170222171222172222173222174222175222176222177222178222179222180222181222182222183222184222185222186222187222188222189222190222191222192222193222194222195222196222197222198222199222200222201222202222203222204222205222206222207222208222209222210222211222212222213222214222215222216222217222218222219222220222221222222222223222224222225222226222227222228222229222230222231222232222233222234222235222236222237222238222239222240222241222242222243222244222245222246222247222248222249222250222251222252222253222254222255222256222257222258222259222260222261222262222263222264222265222266222267222268222269222270222271222272222273222274222275222276222277222278222279222280222281222282222283222284222285222286222287222288222289222290222291222292222293222294222295222296222297222298222299222300222301222302222303222304222305222306222307222308222309222310222311222312222313222314222315222316222317222318222319222320222321222322222323222324222325222326222327222328222329222330222331222332222333222334222335222336222337222338222339222340222341222342222343222344222345222346222347222348222349222350222351222352222353222354222355222356222357222358222359222360222361222362222363222364222365222366222367222368222369222370222371222372222373222374222375222376222377222378222379222380222381222382222383222384222385222386222387222388222389222390222391222392222393222394222395222396222397222398222399222400222401222402222403222404222405222406222407222408222409222410222411222412222413222414222415222416222417222418222419222420222421222422222423222424222425222426222427222428222429222430222431222432222433222434222435222436222437222438222439222440222441222442222443222444222445222446222447222448222449222450222451222452222453222454222455222456222457222458222459222460222461222462222463222464222465222466222467222468222469222470222471222472222473222474222475222476222477222478222479222480222481222482222483222484222485222486222487222488222489222490222491222492222493222494222495222496222497222498222499222500222501222502222503222504222505222506222507222508222509222510222511222512222513222514222515222516222517222518222519222520222521222522222523222524222525222526222527222528222529222530222531222532222533222534222535222536222537222538222539222540222541222542222543222544222545222546222547222548222549222550222551222552222553222554222555222556222557222558222559222560222561222562222563222564222565222566222567222568222569222570222571222572222573222574222575222576222577222578222579222580222581222582222583222584222585222586222587222588222589222590222591222592222593222594222595222596222597222598222599222600222601222602222603222604222605222606222607222608222609222610222611222612222613222614222615222616222617222618222619222620222621222622222623222624222625222626222627222628222629222630222631222632222633222634222635222636222637222638222639222640222641222642222643222644222645222646222647222648222649222650222651222652222653222654222655222656222657222658222659222660222661222662222663222664222665222666222667222668222669222670222671222672222673222674222675222676222677222678222679222680222681222682222683222684222685222686222687222688222689222690222691222692222693222694222695222696222697222698222699222700222701222702222703222704222705222706222707222708222709222710222711222712222713222714222715222716222717222718222719222720222721222722222723222724222725222726222727222728222729222730222731222732222733222734222735222736222737222738222739222740222741222742222743222744222745222746222747222748222749222750222751222752222753222754222755222756222757222758222759222760222761222762222763222764222765222766222767222768222769222770222771222772222773222774222775222776222777222778222779222780222781222782222783222784222785222786222787222788222789222790222791222792222793222794222795222796222797222798222799222800222801222802222803222804222805222806222807222808222809222810222811222812222813222814222815222816222817222818222819222820222821222822222823222824222825222826222827222828222829222830222831222832222833222834222835222836222837222838222839222840222841222842222843222844222845222846222847222848222849222850222851222852222853222854222855222856222857222858222859222860222861222862222863222864222865222866222867222868222869222870222871222872222873222874222875222876222877222878222879222880222881222882222883222884222885222886222887222888222889222890222891222892222893222894222895222896222897222898222899222900222901222902222903222904222905222906222907222908222909222910222911222912222913222914222915222916222917222918222919222920222921222922222923222924222925222926222927222928222929222930222931222932222933222934222935222936222937222938222939222940222941222942222943222944222945222946222947222948222949222950222951222952222953222954222955222956222957222958222959222960222961222962222963222964222965222966222967222968222969222970222971222972222973222974222975222976222977222978222979222980222981222982222983222984222985222986222987222988222989222990222991222992222993222994222995222996222997222998222999223000223001223002223003223004223005223006223007223008223009223010223011223012223013223014223015223016223017223018223019223020223021223022223023223024223025223026223027223028223029223030223031223032223033223034223035223036223037223038223039223040223041223042223043223044223045223046223047223048223049223050223051223052223053223054223055223056223057223058223059223060223061223062223063223064223065223066223067223068223069223070223071223072223073223074223075223076223077223078223079223080223081223082223083223084223085223086223087223088223089223090223091223092223093223094223095223096223097223098223099223100223101223102223103223104223105223106223107223108223109223110223111223112223113223114223115223116223117223118223119223120223121223122223123223124223125223126223127223128223129223130223131223132223133223134223135223136223137223138223139223140223141223142223143223144223145223146223147223148223149223150223151223152223153223154223155223156223157223158223159223160223161223162223163223164223165223166223167223168223169223170223171223172223173223174223175223176223177223178223179223180223181223182223183223184223185223186223187223188223189223190223191223192223193223194223195223196223197223198223199223200223201223202223203223204223205223206223207223208223209223210223211223212223213223214223215223216223217223218223219223220223221223222223223223224223225223226223227223228223229223230223231223232223233223234223235223236223237223238223239223240223241223242223243223244223245223246223247223248223249223250223251223252223253223254223255223256223257223258223259223260223261223262223263223264223265223266223267223268223269223270223271223272223273223274223275223276223277223278223279223280223281223282223283223284223285223286223287223288223289223290223291223292223293223294223295223296223297223298223299223300223301223302223303223304223305223306223307223308223309223310223311223312223313223314223315223316223317223318223319223320223321223322223323223324223325223326223327223328223329223330223331223332223333223334223335223336223337223338223339223340223341223342223343223344223345223346223347223348223349223350223351223352223353223354223355223356223357223358223359223360223361223362223363223364223365223366223367223368223369223370223371223372223373223374223375223376223377223378223379223380223381223382223383223384223385223386223387223388223389223390223391223392223393223394223395223396223397223398223399223400223401223402223403223404223405223406223407223408223409223410223411223412223413223414223415223416223417223418223419223420223421223422223423223424223425223426223427223428223429223430223431223432223433223434223435223436223437223438223439223440223441223442223443223444223445223446223447223448223449223450223451223452223453223454223455223456223457223458223459223460223461223462223463223464223465223466223467223468223469223470223471223472223473223474223475223476223477223478223479223480223481223482223483223484223485223486223487223488223489223490223491223492223493223494223495223496223497223498223499223500223501223502223503223504223505223506223507223508223509223510223511223512223513223514223515223516223517223518223519223520223521223522223523223524223525223526223527223528223529223530223531223532223533223534223535223536223537223538223539223540223541223542223543223544223545223546223547223548223549223550223551223552223553223554223555223556223557223558223559223560223561223562223563223564223565223566223567223568223569223570223571223572223573223574223575223576223577223578223579223580223581223582223583223584223585223586223587223588223589223590223591223592223593223594223595223596223597223598223599223600223601223602223603223604223605223606223607223608223609223610223611223612223613223614223615223616223617223618223619223620223621223622223623223624223625223626223627223628223629223630223631223632223633223634223635223636223637223638223639223640223641223642223643223644223645223646223647223648223649223650223651223652223653223654223655223656223657223658223659223660223661223662223663223664223665223666223667223668223669223670223671223672223673223674223675223676223677223678223679223680223681223682223683223684223685223686223687223688223689223690223691223692223693223694223695223696223697223698223699223700223701223702223703223704223705223706223707223708223709223710223711223712223713223714223715223716223717223718223719223720223721223722223723223724223725223726223727223728223729223730223731223732223733223734223735223736223737223738223739223740223741223742223743223744223745223746223747223748223749223750223751223752223753223754223755223756223757223758223759223760223761223762223763223764223765223766223767223768223769223770223771223772223773223774223775223776223777223778223779223780223781223782223783223784223785223786223787223788223789223790223791223792223793223794223795223796223797223798223799223800223801223802223803223804223805223806223807223808223809223810223811223812223813223814223815223816223817223818223819223820223821223822223823223824223825223826223827223828223829223830223831223832223833223834223835223836223837223838223839223840223841223842223843223844223845223846223847223848223849223850223851223852223853223854223855223856223857223858223859223860223861223862223863223864223865223866223867223868223869223870223871223872223873223874223875223876223877223878223879223880223881223882223883223884223885223886223887223888223889223890223891223892223893223894223895223896223897223898223899223900223901223902223903223904223905223906223907223908223909223910223911223912223913223914223915223916223917223918223919223920223921223922223923223924223925223926223927223928223929223930223931223932223933223934223935223936223937223938223939223940223941223942223943223944223945223946223947223948223949223950223951223952223953223954223955223956223957223958223959223960223961223962223963223964223965223966223967223968223969223970223971223972223973223974223975223976223977223978223979223980223981223982223983223984223985223986223987223988223989223990223991223992223993223994223995223996223997223998223999224000224001224002224003224004224005224006224007224008224009224010224011224012224013224014224015224016224017224018224019224020224021224022224023224024224025224026224027224028224029224030224031224032224033224034224035224036224037224038224039224040224041224042224043224044224045224046224047224048224049224050224051224052224053224054224055224056224057224058224059224060224061224062224063224064224065224066224067224068224069224070224071224072224073224074224075224076224077224078224079224080224081224082224083224084224085224086224087224088224089224090224091224092224093224094224095224096224097224098224099224100224101224102224103224104224105224106224107224108224109224110224111224112224113224114224115224116224117224118224119224120224121224122224123224124224125224126224127224128224129224130224131224132224133224134224135224136224137224138224139224140224141224142224143224144224145224146224147224148224149224150224151224152224153224154224155224156224157224158224159224160224161224162224163224164224165224166224167224168224169224170224171224172224173224174224175224176224177224178224179224180224181224182224183224184224185224186224187224188224189224190224191224192224193224194224195224196224197224198224199224200224201224202224203224204224205224206224207224208224209224210224211224212224213224214224215224216224217224218224219224220224221224222224223224224224225224226224227224228224229224230224231224232224233224234224235224236224237224238224239224240224241224242224243224244224245224246224247224248224249224250224251224252224253224254224255224256224257224258224259224260224261224262224263224264224265224266224267224268224269224270224271224272224273224274224275224276224277224278224279224280224281224282224283224284224285224286224287224288224289224290224291224292224293224294224295224296224297224298224299224300224301224302224303224304224305224306224307224308224309224310224311224312224313224314224315224316224317224318224319224320224321224322224323224324224325224326224327224328224329224330224331224332224333224334224335224336224337224338224339224340224341224342224343224344224345224346224347224348224349224350224351224352224353224354224355224356224357224358224359224360224361224362224363224364224365224366224367224368224369224370224371224372224373224374224375224376224377224378224379224380224381224382224383224384224385224386224387224388224389224390224391224392224393224394224395224396224397224398224399224400224401224402224403224404224405224406224407224408224409224410224411224412224413224414224415224416224417224418224419224420224421224422224423224424224425224426224427224428224429224430224431224432224433224434224435224436224437224438224439224440224441224442224443224444224445224446224447224448224449224450224451224452224453224454224455224456224457224458224459224460224461224462224463224464224465224466224467224468224469224470224471224472224473224474224475224476224477224478224479224480224481224482224483224484224485224486224487224488224489224490224491224492224493224494224495224496224497224498224499224500224501224502224503224504224505224506224507224508224509224510224511224512224513224514224515224516224517224518224519224520224521224522224523224524224525224526224527224528224529224530224531224532224533224534224535224536224537224538224539224540224541224542224543224544224545224546224547224548224549224550224551224552224553224554224555224556224557224558224559224560224561224562224563224564224565224566224567224568224569224570224571224572224573224574224575224576224577224578224579224580224581224582224583224584224585224586224587224588224589224590224591224592224593224594224595224596224597224598224599224600224601224602224603224604224605224606224607224608224609224610224611224612224613224614224615224616224617224618224619224620224621224622224623224624224625224626224627224628224629224630224631224632224633224634224635224636224637224638224639224640224641224642224643224644224645224646224647224648224649224650224651224652224653224654224655224656224657224658224659224660224661224662224663224664224665224666224667224668224669224670224671224672224673224674224675224676224677224678224679224680224681224682224683224684224685224686224687224688224689224690224691224692224693224694224695224696224697224698224699224700224701224702224703224704224705224706224707224708224709224710224711224712224713224714224715224716224717224718224719224720224721224722224723224724224725224726224727224728224729224730224731224732224733224734224735224736224737224738224739224740224741224742224743224744224745224746224747224748224749224750224751224752224753224754224755224756224757224758224759224760224761224762224763224764224765224766224767224768224769224770224771224772224773224774224775224776224777224778224779224780224781224782224783224784224785224786224787224788224789224790224791224792224793224794224795224796224797224798224799224800224801224802224803224804224805224806224807224808224809224810224811224812224813224814224815224816224817224818224819224820224821224822224823224824224825224826224827224828224829224830224831224832224833224834224835224836224837224838224839224840224841224842224843224844224845224846224847224848224849224850224851224852224853224854224855224856224857224858224859224860224861224862224863224864224865224866224867224868224869224870224871224872224873224874224875224876224877224878224879224880224881224882224883224884224885224886224887224888224889224890224891224892224893224894224895224896224897224898224899224900224901224902224903224904224905224906224907224908224909224910224911224912224913224914224915224916224917224918224919224920224921224922224923224924224925224926224927224928224929224930224931224932224933224934224935224936224937224938224939224940224941224942224943224944224945224946224947224948224949224950224951224952224953224954224955224956224957224958224959224960224961224962224963224964224965224966224967224968224969224970224971224972224973224974224975224976224977224978224979224980224981224982224983224984224985224986224987224988224989224990224991224992224993224994224995224996224997224998224999225000225001225002225003225004225005225006225007225008225009225010225011225012225013225014225015225016225017225018225019225020225021225022225023225024225025225026225027225028225029225030225031225032225033225034225035225036225037225038225039225040225041225042225043225044225045225046225047225048225049225050225051225052225053225054225055225056225057225058225059225060225061225062225063225064225065225066225067225068225069225070225071225072225073225074225075225076225077225078225079225080225081225082225083225084225085225086225087225088225089225090225091225092225093225094225095225096225097225098225099225100225101225102225103225104225105225106225107225108225109225110225111225112225113225114225115225116225117225118225119225120225121225122225123225124225125225126225127225128225129225130225131225132225133225134225135225136225137225138225139225140225141225142225143225144225145225146225147225148225149225150225151225152225153225154225155225156225157225158225159225160225161225162225163225164225165225166225167225168225169225170225171225172225173225174225175225176225177225178225179225180225181225182225183225184225185225186225187225188225189225190225191225192225193225194225195225196225197225198225199225200225201225202225203225204225205225206225207225208225209225210225211225212225213225214225215225216225217225218225219225220225221225222225223225224225225225226225227225228225229225230225231225232225233225234225235225236225237225238225239225240225241225242225243225244225245225246225247225248225249225250225251225252225253225254225255225256225257225258225259225260225261225262225263225264225265225266225267225268225269225270225271225272225273225274225275225276225277225278225279225280225281225282225283225284225285225286225287225288225289225290225291225292225293225294225295225296225297225298225299225300225301225302225303225304225305225306225307225308225309225310225311225312225313225314225315225316225317225318225319225320225321225322225323225324225325225326225327225328225329225330225331225332225333225334225335225336225337225338225339225340225341225342225343225344225345225346225347225348225349225350225351225352225353225354225355225356225357225358225359225360225361225362225363225364225365225366225367225368225369225370225371225372225373225374225375225376225377225378225379225380225381225382225383225384225385225386225387225388225389225390225391225392225393225394225395225396225397225398225399225400225401225402225403225404225405225406225407225408225409225410225411225412225413225414225415225416225417225418225419225420225421225422225423225424225425225426225427225428225429225430225431225432225433225434225435225436225437225438225439225440225441225442225443225444225445225446225447225448225449225450225451225452225453225454225455225456225457225458225459225460225461225462225463225464225465225466225467225468225469225470225471225472225473225474225475225476225477225478225479225480225481225482225483225484225485225486225487225488225489225490225491225492225493225494225495225496225497225498225499225500225501225502225503225504225505225506225507225508225509225510225511225512225513225514225515225516225517225518225519225520225521225522225523225524225525225526225527225528225529225530225531225532225533225534225535225536225537225538225539225540225541225542225543225544225545225546225547225548225549225550225551225552225553225554225555225556225557225558225559225560225561225562225563225564225565225566225567225568225569225570225571225572225573225574225575225576225577225578225579225580225581225582225583225584225585225586225587225588225589225590225591225592225593225594225595225596225597225598225599225600225601225602225603225604225605225606225607225608225609225610225611225612225613225614225615225616225617225618225619225620225621225622225623225624225625225626225627225628225629225630225631225632225633225634225635225636225637225638225639225640225641225642225643225644225645225646225647225648225649225650225651225652225653225654225655225656225657225658225659225660225661225662225663225664225665225666225667225668225669225670225671225672225673225674225675225676225677225678225679225680225681225682225683225684225685225686225687225688225689225690225691225692225693225694225695225696225697225698225699225700225701225702225703225704225705225706225707225708225709225710225711225712225713225714225715225716225717225718225719225720225721225722225723225724225725225726225727225728225729225730225731225732225733225734225735225736225737225738225739225740225741225742225743225744225745225746225747225748225749225750225751225752225753225754225755225756225757225758225759225760225761225762225763225764225765225766225767225768225769225770225771225772225773225774225775225776225777225778225779225780225781225782225783225784225785225786225787225788225789225790225791225792225793225794225795225796225797225798225799225800225801225802225803225804225805225806225807225808225809225810225811225812225813225814225815225816225817225818225819225820225821225822225823225824225825225826225827225828225829225830225831225832225833225834225835225836225837225838225839225840225841225842225843225844225845225846225847225848225849225850225851225852225853225854225855225856225857225858225859225860225861225862225863225864225865225866225867225868225869225870225871225872225873225874225875225876225877225878225879225880225881225882225883225884225885225886225887225888225889225890225891225892225893225894225895225896225897225898225899225900225901225902225903225904225905225906225907225908225909225910225911225912225913225914225915225916225917225918225919225920225921225922225923225924225925225926225927225928225929225930225931225932225933225934225935225936225937225938225939225940225941225942225943225944225945225946225947225948225949225950225951225952225953225954225955225956225957225958225959225960225961225962225963225964225965225966225967225968225969225970225971225972225973225974225975225976225977225978225979225980225981225982225983225984225985225986225987225988225989225990225991225992225993225994225995225996225997225998225999226000226001226002226003226004226005226006226007226008226009226010226011226012226013226014226015226016226017226018226019226020226021226022226023226024226025226026226027226028226029226030226031226032226033226034226035226036226037226038226039226040226041226042226043226044226045226046226047226048226049226050226051226052226053226054226055226056226057226058226059226060226061226062226063226064226065226066226067226068226069226070226071226072226073226074226075226076226077226078226079226080226081226082226083226084226085226086226087226088226089226090226091226092226093226094226095226096226097226098226099226100226101226102226103226104226105226106226107226108226109226110226111226112226113226114226115226116226117226118226119226120226121226122226123226124226125226126226127226128226129226130226131226132226133226134226135226136226137226138226139226140226141226142226143226144226145226146226147226148226149226150226151226152226153226154226155226156226157226158226159226160226161226162226163226164226165226166226167226168226169226170226171226172226173226174226175226176226177226178226179226180226181226182226183226184226185226186226187226188226189226190226191226192226193226194226195226196226197226198226199226200226201226202226203226204226205226206226207226208226209226210226211226212226213226214226215226216226217226218226219226220226221226222226223226224226225226226226227226228226229226230226231226232226233226234226235226236226237226238226239226240226241226242226243226244226245226246226247226248226249226250226251226252226253226254226255226256226257226258226259226260226261226262226263226264226265226266226267226268226269226270226271226272226273226274226275226276226277226278226279226280226281226282226283226284226285226286226287226288226289226290226291226292226293226294226295226296226297226298226299226300226301226302226303226304226305226306226307226308226309226310226311226312226313226314226315226316226317226318226319226320226321226322226323226324226325226326226327226328226329226330226331226332226333226334226335226336226337226338226339226340226341226342226343226344226345226346226347226348226349226350226351226352226353226354226355226356226357226358226359226360226361226362226363226364226365226366226367226368226369226370226371226372226373226374226375226376226377226378226379226380226381226382226383226384226385226386226387226388226389226390226391226392226393226394226395226396226397226398226399226400226401226402226403226404226405226406226407226408226409226410226411226412226413226414226415226416226417226418226419226420226421226422226423226424226425226426226427226428226429226430226431226432226433226434226435226436226437226438226439226440226441226442226443226444226445226446226447226448226449226450226451226452226453226454226455226456226457226458226459226460226461226462226463226464226465226466226467226468226469226470226471226472226473226474226475226476226477226478226479226480226481226482226483226484226485226486226487226488226489226490226491226492226493226494226495226496226497226498226499226500226501226502226503226504226505226506226507226508226509226510226511226512226513226514226515226516226517226518226519226520226521226522226523226524226525226526226527226528226529226530226531226532226533226534226535226536226537226538226539226540226541226542226543226544226545226546226547226548226549226550226551226552226553226554226555226556226557226558226559226560226561226562226563226564226565226566226567226568226569226570226571226572226573226574226575226576226577226578226579226580226581226582226583226584226585226586226587226588226589226590226591226592226593226594226595226596226597226598226599226600226601226602226603226604226605226606226607226608226609226610226611226612226613226614226615226616226617226618226619226620226621226622226623226624226625226626226627226628226629226630226631226632226633226634226635226636226637226638226639226640226641226642226643226644226645226646226647226648226649226650226651226652226653226654226655226656226657226658226659226660226661226662226663226664226665226666226667226668226669226670226671226672226673226674226675226676226677226678226679226680226681226682226683226684226685226686226687226688226689226690226691226692226693226694226695226696226697226698226699226700226701226702226703226704226705226706226707226708226709226710226711226712226713226714226715226716226717226718226719226720226721226722226723226724226725226726226727226728226729226730226731226732226733226734226735226736226737226738226739226740226741226742226743226744226745226746226747226748226749226750226751226752226753226754226755226756226757226758226759226760226761226762226763226764226765226766226767226768226769226770226771226772226773226774226775226776226777226778226779226780226781226782226783226784226785226786226787226788226789226790226791226792226793226794226795226796226797226798226799226800226801226802226803226804226805226806226807226808226809226810226811226812226813226814226815226816226817226818226819226820226821226822226823226824226825226826226827226828226829226830226831226832226833226834226835226836226837226838226839226840226841226842226843226844226845226846226847226848226849226850226851226852226853226854226855226856226857226858226859226860226861226862226863226864226865226866226867226868226869226870226871226872226873226874226875226876226877226878226879226880226881226882226883226884226885226886226887226888226889226890226891226892226893226894226895226896226897226898226899226900226901226902226903226904226905226906226907226908226909226910226911226912226913226914226915226916226917226918226919226920226921226922226923226924226925226926226927226928226929226930226931226932226933226934226935226936226937226938226939226940226941226942226943226944226945226946226947226948226949226950226951226952226953226954226955226956226957226958226959226960226961226962226963226964226965226966226967226968226969226970226971226972226973226974226975226976226977226978226979226980226981226982226983226984226985226986226987226988226989226990226991226992226993226994226995226996226997226998226999227000227001227002227003227004227005227006227007227008227009227010227011227012227013227014227015227016227017227018227019227020227021227022227023227024227025227026227027227028227029227030227031227032227033227034227035227036227037227038227039227040227041227042227043227044227045227046227047227048227049227050227051227052227053227054227055227056227057227058227059227060227061227062227063227064227065227066227067227068227069227070227071227072227073227074227075227076227077227078227079227080227081227082227083227084227085227086227087227088227089227090227091227092227093227094227095227096227097227098227099227100227101227102227103227104227105227106227107227108227109227110227111227112227113227114227115227116227117227118227119227120227121227122227123227124227125227126227127227128227129227130227131227132227133227134227135227136227137227138227139227140227141227142227143227144227145227146227147227148227149227150227151227152227153227154227155227156227157227158227159227160227161227162227163227164227165227166227167227168227169227170227171227172227173227174227175227176227177227178227179227180227181227182227183227184227185227186227187227188227189227190227191227192227193227194227195227196227197227198227199227200227201227202227203227204227205227206227207227208227209227210227211227212227213227214227215227216227217227218227219227220227221227222227223227224227225227226227227227228227229227230227231227232227233227234227235227236227237227238227239227240227241227242227243227244227245227246227247227248227249227250227251227252227253227254227255227256227257227258227259227260227261227262227263227264227265227266227267227268227269227270227271227272227273227274227275227276227277227278227279227280227281227282227283227284227285227286227287227288227289227290227291227292227293227294227295227296227297227298227299227300227301227302227303227304227305227306227307227308227309227310227311227312227313227314227315227316227317227318227319227320227321227322227323227324227325227326227327227328227329227330227331227332227333227334227335227336227337227338227339227340227341227342227343227344227345227346227347227348227349227350227351227352227353227354227355227356227357227358227359227360227361227362227363227364227365227366227367227368227369227370227371227372227373227374227375227376227377227378227379227380227381227382227383227384227385227386227387227388227389227390227391227392227393227394227395227396227397227398227399227400227401227402227403227404227405227406227407227408227409227410227411227412227413227414227415227416227417227418227419227420227421227422227423227424227425227426227427227428227429227430227431227432227433227434227435227436227437227438227439227440227441227442227443227444227445227446227447227448227449227450227451227452227453227454227455227456227457227458227459227460227461227462227463227464227465227466227467227468227469227470227471227472227473227474227475227476227477227478227479227480227481227482227483227484227485227486227487227488227489227490227491227492227493227494227495227496227497227498227499227500227501227502227503227504227505227506227507227508227509227510227511227512227513227514227515227516227517227518227519227520227521227522227523227524227525227526227527227528227529227530227531227532227533227534227535227536227537227538227539227540227541227542227543227544227545227546227547227548227549227550227551227552227553227554227555227556227557227558227559227560227561227562227563227564227565227566227567227568227569227570227571227572227573227574227575227576227577227578227579227580227581227582227583227584227585227586227587227588227589227590227591227592227593227594227595227596227597227598227599227600227601227602227603227604227605227606227607227608227609227610227611227612227613227614227615227616227617227618227619227620227621227622227623227624227625227626227627227628227629227630227631227632227633227634227635227636227637227638227639227640227641227642227643227644227645227646227647227648227649227650227651227652227653227654227655227656227657227658227659227660227661227662227663227664227665227666227667227668227669227670227671227672227673227674227675227676227677227678227679227680227681227682227683227684227685227686227687227688227689227690227691227692227693227694227695227696227697227698227699227700227701227702227703227704227705227706227707227708227709227710227711227712227713227714227715227716227717227718227719227720227721227722227723227724227725227726227727227728227729227730227731227732227733227734227735227736227737227738227739227740227741227742227743227744227745227746227747227748227749227750227751227752227753227754227755227756227757227758227759227760227761227762227763227764227765227766227767227768227769227770227771227772227773227774227775227776227777227778227779227780227781227782227783227784227785227786227787227788227789227790227791227792227793227794227795227796227797227798227799227800227801227802227803227804227805227806227807227808227809227810227811227812227813227814227815227816227817227818227819227820227821227822227823227824227825227826227827227828227829227830227831227832227833227834227835227836227837227838227839227840227841227842227843227844227845227846227847227848227849227850227851227852227853227854227855227856227857227858227859227860227861227862227863227864227865227866227867227868227869227870227871227872227873227874227875227876227877227878227879227880227881227882227883227884227885227886227887227888227889227890227891227892227893227894227895227896227897227898227899227900227901227902227903227904227905227906227907227908227909227910227911227912227913227914227915227916227917227918227919227920227921227922227923227924227925227926227927227928227929227930227931227932227933227934227935227936227937227938227939227940227941227942227943227944227945227946227947227948227949227950227951227952227953227954227955227956227957227958227959227960227961227962227963227964227965227966227967227968227969227970227971227972227973227974227975227976227977227978227979227980227981227982227983227984227985227986227987227988227989227990227991227992227993227994227995227996227997227998227999228000228001228002228003228004228005228006228007228008228009228010228011228012228013228014228015228016228017228018228019228020228021228022228023228024228025228026228027228028228029228030228031228032228033228034228035228036228037228038228039228040228041228042228043228044228045228046228047228048228049228050228051228052228053228054228055228056228057228058228059228060228061228062228063228064228065228066228067228068228069228070228071228072228073228074228075228076228077228078228079228080228081228082228083228084228085228086228087228088228089228090228091228092228093228094228095228096228097228098228099228100228101228102228103228104228105228106228107228108228109228110228111228112228113228114228115228116228117228118228119228120228121228122228123228124228125228126228127228128228129228130228131228132228133228134228135228136228137228138228139228140228141228142228143228144228145228146228147228148228149228150228151228152228153228154228155228156228157228158228159228160228161228162228163228164228165228166228167228168228169228170228171228172228173228174228175228176228177228178228179228180228181228182228183228184228185228186228187228188228189228190228191228192228193228194228195228196228197228198228199228200228201228202228203228204228205228206228207228208228209228210228211228212228213228214228215228216228217228218228219228220228221228222228223228224228225228226228227228228228229228230228231228232228233228234228235228236228237228238228239228240228241228242228243228244228245228246228247228248228249228250228251228252228253228254228255228256228257228258228259228260228261228262228263228264228265228266228267228268228269228270228271228272228273228274228275228276228277228278228279228280228281228282228283228284228285228286228287228288228289228290228291228292228293228294228295228296228297228298228299228300228301228302228303228304228305228306228307228308228309228310228311228312228313228314228315228316228317228318228319228320228321228322228323228324228325228326228327228328228329228330228331228332228333228334228335228336228337228338228339228340228341228342228343228344228345228346228347228348228349228350228351228352228353228354228355228356228357228358228359228360228361228362228363228364228365228366228367228368228369228370228371228372228373228374228375228376228377228378228379228380228381228382228383228384228385228386228387228388228389228390228391228392228393228394228395228396228397228398228399228400228401228402228403228404228405228406228407228408228409228410228411228412228413228414228415228416228417228418228419228420228421228422228423228424228425228426228427228428228429228430228431228432228433228434228435228436228437228438228439228440228441228442228443228444228445228446228447228448228449228450228451228452228453228454228455228456228457228458228459228460228461228462228463228464228465228466228467228468228469228470228471228472228473228474228475228476228477228478228479228480228481228482228483228484228485228486228487228488228489228490228491228492228493228494228495228496228497228498228499228500228501228502228503228504228505228506228507228508228509228510228511228512228513228514228515228516228517228518228519228520228521228522228523228524228525228526228527228528228529228530228531228532228533228534228535228536228537228538228539228540228541228542228543228544228545228546228547228548228549228550228551228552228553228554228555228556228557228558228559228560228561228562228563228564228565228566228567228568228569228570228571228572228573228574228575228576228577228578228579228580228581228582228583228584228585228586228587228588228589228590228591228592228593228594228595228596228597228598228599228600228601228602228603228604228605228606228607228608228609228610228611228612228613228614228615228616228617228618228619228620228621228622228623228624228625228626228627228628228629228630228631228632228633228634228635228636228637228638228639228640228641228642228643228644228645228646228647228648228649228650228651228652228653228654228655228656228657228658228659228660228661228662228663228664228665228666228667228668228669228670228671228672228673228674228675228676228677228678228679228680228681228682228683228684228685228686228687228688228689228690228691228692228693228694228695228696228697228698228699228700228701228702228703228704228705228706228707228708228709228710228711228712228713228714228715228716228717228718228719228720228721228722228723228724228725228726228727228728228729228730228731228732228733228734228735228736228737228738228739228740228741228742228743228744228745228746228747228748228749228750228751228752228753228754228755228756228757228758228759228760228761228762228763228764228765228766228767228768228769228770228771228772228773228774228775228776228777228778228779228780228781228782228783228784228785228786228787228788228789228790228791228792228793228794228795228796228797228798228799228800228801228802228803228804228805228806228807228808228809228810228811228812228813228814228815228816228817228818228819228820228821228822228823228824228825228826228827228828228829228830228831228832228833228834228835228836228837228838228839228840228841228842228843228844228845228846228847228848228849228850228851228852228853228854228855228856228857228858228859228860228861228862228863228864228865228866228867228868228869228870228871228872228873228874228875228876228877228878228879228880228881228882228883228884228885228886228887228888228889228890228891228892228893228894228895228896228897228898228899228900228901228902228903228904228905228906228907228908228909228910228911228912228913228914228915228916228917228918228919228920228921228922228923228924228925228926228927228928228929228930228931228932228933228934228935228936228937228938228939228940228941228942228943228944228945228946228947228948228949228950228951228952228953228954228955228956228957228958228959228960228961228962228963228964228965228966228967228968228969228970228971228972228973228974228975228976228977228978228979228980228981228982228983228984228985228986228987228988228989228990228991228992228993228994228995228996228997228998228999229000229001229002229003229004229005229006229007229008229009229010229011229012229013229014229015229016229017229018229019229020229021229022229023229024229025229026229027229028229029229030229031229032229033229034229035229036229037229038229039229040229041229042229043229044229045229046229047229048229049229050229051229052229053229054229055229056229057229058229059229060229061229062229063229064229065229066229067229068229069229070229071229072229073229074229075229076229077229078229079229080229081229082229083229084229085229086229087229088229089229090229091229092229093229094229095229096229097229098229099229100229101229102229103229104229105229106229107229108229109229110229111229112229113229114229115229116229117229118229119229120229121229122229123229124229125229126229127229128229129229130229131229132229133229134229135229136229137229138229139229140229141229142229143229144229145229146229147229148229149229150229151229152229153229154229155229156229157229158229159229160229161229162229163229164229165229166229167229168229169229170229171229172229173229174229175229176229177229178229179229180229181229182229183229184229185229186229187229188229189229190229191229192229193229194229195229196229197229198229199229200229201229202229203229204229205229206229207229208229209229210229211229212229213229214229215229216229217229218229219229220229221229222229223229224229225229226229227229228229229229230229231229232229233229234229235229236229237229238229239229240229241229242229243229244229245229246229247229248229249229250229251229252229253229254229255229256229257229258229259229260229261229262229263229264229265229266229267229268229269229270229271229272229273229274229275229276229277229278229279229280229281229282229283229284229285229286229287229288229289229290229291229292229293229294229295229296229297229298229299229300229301229302229303229304229305229306229307229308229309229310229311229312229313229314229315229316229317229318229319229320229321229322229323229324229325229326229327229328229329229330229331229332229333229334229335229336229337229338229339229340229341229342229343229344229345229346229347229348229349229350229351229352229353229354229355229356229357229358229359229360229361229362229363229364229365229366229367229368229369229370229371229372229373229374229375229376229377229378229379229380229381229382229383229384229385229386229387229388229389229390229391229392229393229394229395229396229397229398229399229400229401229402229403229404229405229406229407229408229409229410229411229412229413229414229415229416229417229418229419229420229421229422229423229424229425229426229427229428229429229430229431229432229433229434229435229436229437229438229439229440229441229442229443229444229445229446229447229448229449229450229451229452229453229454229455229456229457229458229459229460229461229462229463229464229465229466229467229468229469229470229471229472229473229474229475229476229477229478229479229480229481229482229483229484229485229486229487229488229489229490229491229492229493229494229495229496229497229498229499229500229501229502229503229504229505229506229507229508229509229510229511229512229513229514229515229516229517229518229519229520229521229522229523229524229525229526229527229528229529229530229531229532229533229534229535229536229537229538229539229540229541229542229543229544229545229546229547229548229549229550229551229552229553229554229555229556229557229558229559229560229561229562229563229564229565229566229567229568229569229570229571229572229573229574229575229576229577229578229579229580229581229582229583229584229585229586229587229588229589229590229591229592229593229594229595229596229597229598229599229600229601229602229603229604229605229606229607229608229609229610229611229612229613229614229615229616229617229618229619229620229621229622229623229624229625229626229627229628229629229630229631229632229633229634229635229636229637229638229639229640229641229642229643229644229645229646229647229648229649229650229651229652229653229654229655229656229657229658229659229660229661229662229663229664229665229666229667229668229669229670229671229672229673229674229675229676229677229678229679229680229681229682229683229684229685229686229687229688229689229690229691229692229693229694229695229696229697229698229699229700229701229702229703229704229705229706229707229708229709229710229711229712229713229714229715229716229717229718229719229720229721229722229723229724229725229726229727229728229729229730229731229732229733229734229735229736229737229738229739229740229741229742229743229744229745229746229747229748229749229750229751229752229753229754229755229756229757229758229759229760229761229762229763229764229765229766229767229768229769229770229771229772229773229774229775229776229777229778229779229780229781229782229783229784229785229786229787229788229789229790229791229792229793229794229795229796229797229798229799229800229801229802229803229804229805229806229807229808229809229810229811229812229813229814229815229816229817229818229819229820229821229822229823229824229825229826229827229828229829229830229831229832229833229834229835229836229837229838229839229840229841229842229843229844229845229846229847229848229849229850229851229852229853229854229855229856229857229858229859229860229861229862229863229864229865229866229867229868229869229870229871229872229873229874229875229876229877229878229879229880229881229882229883229884229885229886229887229888229889229890229891229892229893229894229895229896229897229898229899229900229901229902229903229904229905229906229907229908229909229910229911229912229913229914229915229916229917229918229919229920229921229922229923229924229925229926229927229928229929229930229931229932229933229934229935229936229937229938229939229940229941229942229943229944229945229946229947229948229949229950229951229952229953229954229955229956229957229958229959229960229961229962229963229964229965229966229967229968229969229970229971229972229973229974229975229976229977229978229979229980229981229982229983229984229985229986229987229988229989229990229991229992229993229994229995229996229997229998229999230000230001230002230003230004230005230006230007230008230009230010230011230012230013230014230015230016230017230018230019230020230021230022230023230024230025230026230027230028230029230030230031230032230033230034230035230036230037230038230039230040230041230042230043230044230045230046230047230048230049230050230051230052230053230054230055230056230057230058230059230060230061230062230063230064230065230066230067230068230069230070230071230072230073230074230075230076230077230078230079230080230081230082230083230084230085230086230087230088230089230090230091230092230093230094230095230096230097230098230099230100230101230102230103230104230105230106230107230108230109230110230111230112230113230114230115230116230117230118230119230120230121230122230123230124230125230126230127230128230129230130230131230132230133230134230135230136230137230138230139230140230141230142230143230144230145230146230147230148230149230150230151230152230153230154230155230156230157230158230159230160230161230162230163230164230165230166230167230168230169230170230171230172230173230174230175230176230177230178230179230180230181230182230183230184230185230186230187230188230189230190230191230192230193230194230195230196230197230198230199230200230201230202230203230204230205230206230207230208230209230210230211230212230213230214230215230216230217230218230219230220230221230222230223230224230225230226230227230228230229230230230231230232230233230234230235230236230237230238230239230240230241230242230243230244230245230246230247230248230249230250230251230252230253230254230255230256230257230258230259230260230261230262230263230264230265230266230267230268230269230270230271230272230273230274230275230276230277230278230279230280230281230282230283230284230285230286230287230288230289230290230291230292230293230294230295230296230297230298230299230300230301230302230303230304230305230306230307230308230309230310230311230312230313230314230315230316230317230318230319230320230321230322230323230324230325230326230327230328230329230330230331230332230333230334230335230336230337230338230339230340230341230342230343230344230345230346230347230348230349230350230351230352230353230354230355230356230357230358230359230360230361230362230363230364230365230366230367230368230369230370230371230372230373230374230375230376230377230378230379230380230381230382230383230384230385230386230387230388230389230390230391230392230393230394230395230396230397230398230399230400230401230402230403230404230405230406230407230408230409230410230411230412230413230414230415230416230417230418230419230420230421230422230423230424230425230426230427230428230429230430230431230432230433230434230435230436230437230438230439230440230441230442230443230444230445230446230447230448230449230450230451230452230453230454230455230456230457230458230459230460230461230462230463230464230465230466230467230468230469230470230471230472230473230474230475230476230477230478230479230480230481230482230483230484230485230486230487230488230489230490230491230492230493230494230495230496230497230498230499230500230501230502230503230504230505230506230507230508230509230510230511230512230513230514230515230516230517230518230519230520230521230522230523230524230525230526230527230528230529230530230531230532230533230534230535230536230537230538230539230540230541230542230543230544230545230546230547230548230549230550230551230552230553230554230555230556230557230558230559230560230561230562230563230564230565230566230567230568230569230570230571230572230573230574230575230576230577230578230579230580230581230582230583230584230585230586230587230588230589230590230591230592230593230594230595230596230597230598230599230600230601230602230603230604230605230606230607230608230609230610230611230612230613230614230615230616230617230618230619230620230621230622230623230624230625230626230627230628230629230630230631230632230633230634230635230636230637230638230639230640230641230642230643230644230645230646230647230648230649230650230651230652230653230654230655230656230657230658230659230660230661230662230663230664230665230666230667230668230669230670230671230672230673230674230675230676230677230678230679230680230681230682230683230684230685230686230687230688230689230690230691230692230693230694230695230696230697230698230699230700230701230702230703230704230705230706230707230708230709230710230711230712230713230714230715230716230717230718230719230720230721230722230723230724230725230726230727230728230729230730230731230732230733230734230735230736230737230738230739230740230741230742230743230744230745230746230747230748230749230750230751230752230753230754230755230756230757230758230759230760230761230762230763230764230765230766230767230768230769230770230771230772230773230774230775230776230777230778230779230780230781230782230783230784230785230786230787230788230789230790230791230792230793230794230795230796230797230798230799230800230801230802230803230804230805230806230807230808230809230810230811230812230813230814230815230816230817230818230819230820230821230822230823230824230825230826230827230828230829230830230831230832230833230834230835230836230837230838230839230840230841230842230843230844230845230846230847230848230849230850230851230852230853230854230855230856230857230858230859230860230861230862230863230864230865230866230867230868230869230870230871230872230873230874230875230876230877230878230879230880230881230882230883230884230885230886230887230888230889230890230891230892230893230894230895230896230897230898230899230900230901230902230903230904230905230906230907230908230909230910230911230912230913230914230915230916230917230918230919230920230921230922230923230924230925230926230927230928230929230930230931230932230933230934230935230936230937230938230939230940230941230942230943230944230945230946230947230948230949230950230951230952230953230954230955230956230957230958230959230960230961230962230963230964230965230966230967230968230969230970230971230972230973230974230975230976230977230978230979230980230981230982230983230984230985230986230987230988230989230990230991230992230993230994230995230996230997230998230999231000231001231002231003231004231005231006231007231008231009231010231011231012231013231014231015231016231017231018231019231020231021231022231023231024231025231026231027231028231029231030231031231032231033231034231035231036231037231038231039231040231041231042231043231044231045231046231047231048231049231050231051231052231053231054231055231056231057231058231059231060231061231062231063231064231065231066231067231068231069231070231071231072231073231074231075231076231077231078231079231080231081231082231083231084231085231086231087231088231089231090231091231092231093231094231095231096231097231098231099231100231101231102231103231104231105231106231107231108231109231110231111231112231113231114231115231116231117231118231119231120231121231122231123231124231125231126231127231128231129231130231131231132231133231134231135231136231137231138231139231140231141231142231143231144231145231146231147231148231149231150231151231152231153231154231155231156231157231158231159231160231161231162231163231164231165231166231167231168231169231170231171231172231173231174231175231176231177231178231179231180231181231182231183231184231185231186231187231188231189231190231191231192231193231194231195231196231197231198231199231200231201231202231203231204231205231206231207231208231209231210231211231212231213231214231215231216231217231218231219231220231221231222231223231224231225231226231227231228231229231230231231231232231233231234231235231236231237231238231239231240231241231242231243231244231245231246231247231248231249231250231251231252231253231254231255231256231257231258231259231260231261231262231263231264231265231266231267231268231269231270231271231272231273231274231275231276231277231278231279231280231281231282231283231284231285231286231287231288231289231290231291231292231293231294231295231296231297231298231299231300231301231302231303231304231305231306231307231308231309231310231311231312231313231314231315231316231317231318231319231320231321231322231323231324231325231326231327231328231329231330231331231332231333231334231335231336231337231338231339231340231341231342231343231344231345231346231347231348231349231350231351231352231353231354231355231356231357231358231359231360231361231362231363231364231365231366231367231368231369231370231371231372231373231374231375231376231377231378231379231380231381231382231383231384231385231386231387231388231389231390231391231392231393231394231395231396231397231398231399231400231401231402231403231404231405231406231407231408231409231410231411231412231413231414231415231416231417231418231419231420231421231422231423231424231425231426231427231428231429231430231431231432231433231434231435231436231437231438231439231440231441231442231443231444231445231446231447231448231449231450231451231452231453231454231455231456231457231458231459231460231461231462231463231464231465231466231467231468231469231470231471231472231473231474231475231476231477231478231479231480231481231482231483231484231485231486231487231488231489231490231491231492231493231494231495231496231497231498231499231500231501231502231503231504231505231506231507231508231509231510231511231512231513231514231515231516231517231518231519231520231521231522231523231524231525231526231527231528231529231530231531231532231533231534231535231536231537231538231539231540231541231542231543231544231545231546231547231548231549231550231551231552231553231554231555231556231557231558231559231560231561231562231563231564231565231566231567231568231569231570231571231572231573231574231575231576231577231578231579231580231581231582231583231584231585231586231587231588231589231590231591231592231593231594231595231596231597231598231599231600231601231602231603231604231605231606231607231608231609231610231611231612231613231614231615231616231617231618231619231620231621231622231623231624231625231626231627231628231629231630231631231632231633231634231635231636231637231638231639231640231641231642231643231644231645231646231647231648231649231650231651231652231653231654231655231656231657231658231659231660231661231662231663231664231665231666231667231668231669231670231671231672231673231674231675231676231677231678231679231680231681231682231683231684231685231686231687231688231689231690231691231692231693231694231695231696231697231698231699231700231701231702231703231704231705231706231707231708231709231710231711231712231713231714231715231716231717231718231719231720231721231722231723231724231725231726231727231728231729231730231731231732231733231734231735231736231737231738231739231740231741231742231743231744231745231746231747231748231749231750231751231752231753231754231755231756231757231758231759231760231761231762231763231764231765231766231767231768231769231770231771231772231773231774231775231776231777231778231779231780231781231782231783231784231785231786231787231788231789231790231791231792231793231794231795231796231797231798231799231800231801231802231803231804231805231806231807231808231809231810231811231812231813231814231815231816231817231818231819231820231821231822231823231824231825231826231827231828231829231830231831231832231833231834231835231836231837231838231839231840231841231842231843231844231845231846231847231848231849231850231851231852231853231854231855231856231857231858231859231860231861231862231863231864231865231866231867231868231869231870231871231872231873231874231875231876231877231878231879231880231881231882231883231884231885231886231887231888231889231890231891231892231893231894231895231896231897231898231899231900231901231902231903231904231905231906231907231908231909231910231911231912231913231914231915231916231917231918231919231920231921231922231923231924231925231926231927231928231929231930231931231932231933231934231935231936231937231938231939231940231941231942231943231944231945231946231947231948231949231950231951231952231953231954231955231956231957231958231959231960231961231962231963231964231965231966231967231968231969231970231971231972231973231974231975231976231977231978231979231980231981231982231983231984231985231986231987231988231989231990231991231992231993231994231995231996231997231998231999232000232001232002232003232004232005232006232007232008232009232010232011232012232013232014232015232016232017232018232019232020232021232022232023232024232025232026232027232028232029232030232031232032232033232034232035232036232037232038232039232040232041232042232043232044232045232046232047232048232049232050232051232052232053232054232055232056232057232058232059232060232061232062232063232064232065232066232067232068232069232070232071232072232073232074232075232076232077232078232079232080232081232082232083232084232085232086232087232088232089232090232091232092232093232094232095232096232097232098232099232100232101232102232103232104232105232106232107232108232109232110232111232112232113232114232115232116232117232118232119232120232121232122232123232124232125232126232127232128232129232130232131232132232133232134232135232136232137232138232139232140232141232142232143232144232145232146232147232148232149232150232151232152232153232154232155232156232157232158232159232160232161232162232163232164232165232166232167232168232169232170232171232172232173232174232175232176232177232178232179232180232181232182232183232184232185232186232187232188232189232190232191232192232193232194232195232196232197232198232199232200232201232202232203232204232205232206232207232208232209232210232211232212232213232214232215232216232217232218232219232220232221232222232223232224232225232226232227232228232229232230232231232232232233232234232235232236232237232238232239232240232241232242232243232244232245232246232247232248232249232250232251232252232253232254232255232256232257232258232259232260232261232262232263232264232265232266232267232268232269232270232271232272232273232274232275232276232277232278232279232280232281232282232283232284232285232286232287232288232289232290232291232292232293232294232295232296232297232298232299232300232301232302232303232304232305232306232307232308232309232310232311232312232313232314232315232316232317232318232319232320232321232322232323232324232325232326232327232328232329232330232331232332232333232334232335232336232337232338232339232340232341232342232343232344232345232346232347232348232349232350232351232352232353232354232355232356232357232358232359232360232361232362232363232364232365232366232367232368232369232370232371232372232373232374232375232376232377232378232379232380232381232382232383232384232385232386232387232388232389232390232391232392232393232394232395232396232397232398232399232400232401232402232403232404232405232406232407232408232409232410232411232412232413232414232415232416232417232418232419232420232421232422232423232424232425232426232427232428232429232430232431232432232433232434232435232436232437232438232439232440232441232442232443232444232445232446232447232448232449232450232451232452232453232454232455232456232457232458232459232460232461232462232463232464232465232466232467232468232469232470232471232472232473232474232475232476232477232478232479232480232481232482232483232484232485232486232487232488232489232490232491232492232493232494232495232496232497232498232499232500232501232502232503232504232505232506232507232508232509232510232511232512232513232514232515232516232517232518232519232520232521232522232523232524232525232526232527232528232529232530232531232532232533232534232535232536232537232538232539232540232541232542232543232544232545232546232547232548232549232550232551232552232553232554232555232556232557232558232559232560232561232562232563232564232565232566232567232568232569232570232571232572232573232574232575232576232577232578232579232580232581232582232583232584232585232586232587232588232589232590232591232592232593232594232595232596232597232598232599232600232601232602232603232604232605232606232607232608232609232610232611232612232613232614232615232616232617232618232619232620232621232622232623232624232625232626232627232628232629232630232631232632232633232634232635232636232637232638232639232640232641232642232643232644232645232646232647232648232649232650232651232652232653232654232655232656232657232658232659232660232661232662232663232664232665232666232667232668232669232670232671232672232673232674232675232676232677232678232679232680232681232682232683232684232685232686232687232688232689232690232691232692232693232694232695232696232697232698232699232700232701232702232703232704232705232706232707232708232709232710232711232712232713232714232715232716232717232718232719232720232721232722232723232724232725232726232727232728232729232730232731232732232733232734232735232736232737232738232739232740232741232742232743232744232745232746232747232748232749232750232751232752232753232754232755232756232757232758232759232760232761232762232763232764232765232766232767232768232769232770232771232772232773232774232775232776232777232778232779232780232781232782232783232784232785232786232787232788232789232790232791232792232793232794232795232796232797232798232799232800232801232802232803232804232805232806232807232808232809232810232811232812232813232814232815232816232817232818232819232820232821232822232823232824232825232826232827232828232829232830232831232832232833232834232835232836232837232838232839232840232841232842232843232844232845232846232847232848232849232850232851232852232853232854232855232856232857232858232859232860232861232862232863232864232865232866232867232868232869232870232871232872232873232874232875232876232877232878232879232880232881232882232883232884232885232886232887232888232889232890232891232892232893232894232895232896232897232898232899232900232901232902232903232904232905232906232907232908232909232910232911232912232913232914232915232916232917232918232919232920232921232922232923232924232925232926232927232928232929232930232931232932232933232934232935232936232937232938232939232940232941232942232943232944232945232946232947232948232949232950232951232952232953232954232955232956232957232958232959232960232961232962232963232964232965232966232967232968232969232970232971232972232973232974232975232976232977232978232979232980232981232982232983232984232985232986232987232988232989232990232991232992232993232994232995232996232997232998232999233000233001233002233003233004233005233006233007233008233009233010233011233012233013233014233015233016233017233018233019233020233021233022233023233024233025233026233027233028233029233030233031233032233033233034233035233036233037233038233039233040233041233042233043233044233045233046233047233048233049233050233051233052233053233054233055233056233057233058233059233060233061233062233063233064233065233066233067233068233069233070233071233072233073233074233075233076233077233078233079233080233081233082233083233084233085233086233087233088233089233090233091233092233093233094233095233096233097233098233099233100233101233102233103233104233105233106233107233108233109233110233111233112233113233114233115233116233117233118233119233120233121233122233123233124233125233126233127233128233129233130233131233132233133233134233135233136233137233138233139233140233141233142233143233144233145233146233147233148233149233150233151233152233153233154233155233156233157233158233159233160233161233162233163233164233165233166233167233168233169233170233171233172233173233174233175233176233177233178233179233180233181233182233183233184233185233186233187233188233189233190233191233192233193233194233195233196233197233198233199233200233201233202233203233204233205233206233207233208233209233210233211233212233213233214233215233216233217233218233219233220233221233222233223233224233225233226233227233228233229233230233231233232233233233234233235233236233237233238233239233240233241233242233243233244233245233246233247233248233249233250233251233252233253233254233255233256233257233258233259233260233261233262233263233264233265233266233267233268233269233270233271233272233273233274233275233276233277233278233279233280233281233282233283233284233285233286233287233288233289233290233291233292233293233294233295233296233297233298233299233300233301233302233303233304233305233306233307233308233309233310233311233312233313233314233315233316233317233318233319233320233321233322233323233324233325233326233327233328233329233330233331233332233333233334233335233336233337233338233339233340233341233342233343233344233345233346233347233348233349233350233351233352233353233354233355233356233357233358233359233360233361233362233363233364233365233366233367233368233369233370233371233372233373233374233375233376233377233378233379233380233381233382233383233384233385233386233387233388233389233390233391233392233393233394233395233396233397233398233399233400233401233402233403233404233405233406233407233408233409233410233411233412233413233414233415233416233417233418233419233420233421233422233423233424233425233426233427233428233429233430233431233432233433233434233435233436233437233438233439233440233441233442233443233444233445233446233447233448233449233450233451233452233453233454233455233456233457233458233459233460233461233462233463233464233465233466233467233468233469233470233471233472233473233474233475233476233477233478233479233480233481233482233483233484233485233486233487233488233489233490233491233492233493233494233495233496233497233498233499233500233501233502233503233504233505233506233507233508233509233510233511233512233513233514233515233516233517233518233519233520233521233522233523233524233525233526233527233528233529233530233531233532233533233534233535233536233537233538233539233540233541233542233543233544233545233546233547233548233549233550233551233552233553233554233555233556233557233558233559233560233561233562233563233564233565233566233567233568233569233570233571233572233573233574233575233576233577233578233579233580233581233582233583233584233585233586233587233588233589233590233591233592233593233594233595233596233597233598233599233600233601233602233603233604233605233606233607233608233609233610233611233612233613233614233615233616233617233618233619233620233621233622233623233624233625233626233627233628233629233630233631233632233633233634233635233636233637233638233639233640233641233642233643233644233645233646233647233648233649233650233651233652233653233654233655233656233657233658233659233660233661233662233663233664233665233666233667233668233669233670233671233672233673233674233675233676233677233678233679233680233681233682233683233684233685233686233687233688233689233690233691233692233693233694233695233696233697233698233699233700233701233702233703233704233705233706233707233708233709233710233711233712233713233714233715233716233717233718233719233720233721233722233723233724233725233726233727233728233729233730233731233732233733233734233735233736233737233738233739233740233741233742233743233744233745233746233747233748233749233750233751233752233753233754233755233756233757233758233759233760233761233762233763233764233765233766233767233768233769233770233771233772233773233774233775233776233777233778233779233780233781233782233783233784233785233786233787233788233789233790233791233792233793233794233795233796233797233798233799233800233801233802233803233804233805233806233807233808233809233810233811233812233813233814233815233816233817233818233819233820233821233822233823233824233825233826233827233828233829233830233831233832233833233834233835233836233837233838233839233840233841233842233843233844233845233846233847233848233849233850233851233852233853233854233855233856233857233858233859233860233861233862233863233864233865233866233867233868233869233870233871233872233873233874233875233876233877233878233879233880233881233882233883233884233885233886233887233888233889233890233891233892233893233894233895233896233897233898233899233900233901233902233903233904233905233906233907233908233909233910233911233912233913233914233915233916233917233918233919233920233921233922233923233924233925233926233927233928233929233930233931233932233933233934233935233936233937233938233939233940233941233942233943233944233945233946233947233948233949233950233951233952233953233954233955233956233957233958233959233960233961233962233963233964233965233966233967233968233969233970233971233972233973233974233975233976233977233978233979233980233981233982233983233984233985233986233987233988233989233990233991233992233993233994233995233996233997233998233999234000234001234002234003234004234005234006234007234008234009234010234011234012234013234014234015234016234017234018234019234020234021234022234023234024234025234026234027234028234029234030234031234032234033234034234035234036234037234038234039234040234041234042234043234044234045234046234047234048234049234050234051234052234053234054234055234056234057234058234059234060234061234062234063234064234065234066234067234068234069234070234071234072234073234074234075234076234077234078234079234080234081234082234083234084234085234086234087234088234089234090234091234092234093234094234095234096234097234098234099234100234101234102234103234104234105234106234107234108234109234110234111234112234113234114234115234116234117234118234119234120234121234122234123234124234125234126234127234128234129234130234131234132234133234134234135234136234137234138234139234140234141234142234143234144234145234146234147234148234149234150234151234152234153234154234155234156234157234158234159234160234161234162234163234164234165234166234167234168234169234170234171234172234173234174234175234176234177234178234179234180234181234182234183234184234185234186234187234188234189234190234191234192234193234194234195234196234197234198234199234200234201234202234203234204234205234206234207234208234209234210234211234212234213234214234215234216234217234218234219234220234221234222234223234224234225234226234227234228234229234230234231234232234233234234234235234236234237234238234239234240234241234242234243234244234245234246234247234248234249234250234251234252234253234254234255234256234257234258234259234260234261234262234263234264234265234266234267234268234269234270234271234272234273234274234275234276234277234278234279234280234281234282234283234284234285234286234287234288234289234290234291234292234293234294234295234296234297234298234299234300234301234302234303234304234305234306234307234308234309234310234311234312234313234314234315234316234317234318234319234320234321234322234323234324234325234326234327234328234329234330234331234332234333234334234335234336234337234338234339234340234341234342234343234344234345234346234347234348234349234350234351234352234353234354234355234356234357234358234359234360234361234362234363234364234365234366234367234368234369234370234371234372234373234374234375234376234377234378234379234380234381234382234383234384234385234386234387234388234389234390234391234392234393234394234395234396234397234398234399234400234401234402234403234404234405234406234407234408234409234410234411234412234413234414234415234416234417234418234419234420234421234422234423234424234425234426234427234428234429234430234431234432234433234434234435234436234437234438234439234440234441234442234443234444234445234446234447234448234449234450234451234452234453234454234455234456234457234458234459234460234461234462234463234464234465234466234467234468234469234470234471234472234473234474234475234476234477234478234479234480234481234482234483234484234485234486234487234488234489234490234491234492234493234494234495234496234497234498234499234500234501234502234503234504234505234506234507234508234509234510234511234512234513234514234515234516234517234518234519234520234521234522234523234524234525234526234527234528234529234530234531234532234533234534234535234536234537234538234539234540234541234542234543234544234545234546234547234548234549234550234551234552234553234554234555234556234557234558234559234560234561234562234563234564234565234566234567234568234569234570234571234572234573234574234575234576234577234578234579234580234581234582234583234584234585234586234587234588234589234590234591234592234593234594234595234596234597234598234599234600234601234602234603234604234605234606234607234608234609234610234611234612234613234614234615234616234617234618234619234620234621234622234623234624234625234626234627234628234629234630234631234632234633234634234635234636234637234638234639234640234641234642234643234644234645234646234647234648234649234650234651234652234653234654234655234656234657234658234659234660234661234662234663234664234665234666234667234668234669234670234671234672234673234674234675234676234677234678234679234680234681234682234683234684234685234686234687234688234689234690234691234692234693234694234695234696234697234698234699234700234701234702234703234704234705234706234707234708234709234710234711234712234713234714234715234716234717234718234719234720234721234722234723234724234725234726234727234728234729234730234731234732234733234734234735234736234737234738234739234740234741234742234743234744234745234746234747234748234749234750234751234752234753234754234755234756234757234758234759234760234761234762234763234764234765234766234767234768234769234770234771234772234773234774234775234776234777234778234779234780234781234782234783234784234785234786234787234788234789234790234791234792234793234794234795234796234797234798234799234800234801234802234803234804234805234806234807234808234809234810234811234812234813234814234815234816234817234818234819234820234821234822234823234824234825234826234827234828234829234830234831234832234833234834234835234836234837234838234839234840234841234842234843234844234845234846234847234848234849234850234851234852234853234854234855234856234857234858234859234860234861234862234863234864234865234866234867234868234869234870234871234872234873234874234875234876234877234878234879234880234881234882234883234884234885234886234887234888234889234890234891234892234893234894234895234896234897234898234899234900234901234902234903234904234905234906234907234908234909234910234911234912234913234914234915234916234917234918234919234920234921234922234923234924234925234926234927234928234929234930234931234932234933234934234935234936234937234938234939234940234941234942234943234944234945234946234947234948234949234950234951234952234953234954234955234956234957234958234959234960234961234962234963234964234965234966234967234968234969234970234971234972234973234974234975234976234977234978234979234980234981234982234983234984234985234986234987234988234989234990234991234992234993234994234995234996234997234998234999235000235001235002235003235004235005235006235007235008235009235010235011235012235013235014235015235016235017235018235019235020235021235022235023235024235025235026235027235028235029235030235031235032235033235034235035235036235037235038235039235040235041235042235043235044235045235046235047235048235049235050235051235052235053235054235055235056235057235058235059235060235061235062235063235064235065235066235067235068235069235070235071235072235073235074235075235076235077235078235079235080235081235082235083235084235085235086235087235088235089235090235091235092235093235094235095235096235097235098235099235100235101235102235103235104235105235106235107235108235109235110235111235112235113235114235115235116235117235118235119235120235121235122235123235124235125235126235127235128235129235130235131235132235133235134235135235136235137235138235139235140235141235142235143235144235145235146235147235148235149235150235151235152235153235154235155235156235157235158235159235160235161235162235163235164235165235166235167235168235169235170235171235172235173235174235175235176235177235178235179235180235181235182235183235184235185235186235187235188235189235190235191235192235193235194235195235196235197235198235199235200235201235202235203235204235205235206235207235208235209235210235211235212235213235214235215235216235217235218235219235220235221235222235223235224235225235226235227235228235229235230235231235232235233235234235235235236235237235238235239235240235241235242235243235244235245235246235247235248235249235250235251235252235253235254235255235256235257235258235259235260235261235262235263235264235265235266235267235268235269235270235271235272235273235274235275235276235277235278235279235280235281235282235283235284235285235286235287235288235289235290235291235292235293235294235295235296235297235298235299235300235301235302235303235304235305235306235307235308235309235310235311235312235313235314235315235316235317235318235319235320235321235322235323235324235325235326235327235328235329235330235331235332235333235334235335235336235337235338235339235340235341235342235343235344235345235346235347235348235349235350235351235352235353235354235355235356235357235358235359235360235361235362235363235364235365235366235367235368235369235370235371235372235373235374235375235376235377235378235379235380235381235382235383235384235385235386235387235388235389235390235391235392235393235394235395235396235397235398235399235400235401235402235403235404235405235406235407235408235409235410235411235412235413235414235415235416235417235418235419235420235421235422235423235424235425235426235427235428235429235430235431235432235433235434235435235436235437235438235439235440235441235442235443235444235445235446235447235448235449235450235451235452235453235454235455235456235457235458235459235460235461235462235463235464235465235466235467235468235469235470235471235472235473235474235475235476235477235478235479235480235481235482235483235484235485235486235487235488235489235490235491235492235493235494235495235496235497235498235499235500235501235502235503235504235505235506235507235508235509235510235511235512235513235514235515235516235517235518235519235520235521235522235523235524235525235526235527235528235529235530235531235532235533235534235535235536235537235538235539235540235541235542235543235544235545235546235547235548235549235550235551235552235553235554235555235556235557235558235559235560235561235562235563235564235565235566235567235568235569235570235571235572235573235574235575235576235577235578235579235580235581235582235583235584235585235586235587235588235589235590235591235592235593235594235595235596235597235598235599235600235601235602235603235604235605235606235607235608235609235610235611235612235613235614235615235616235617235618235619235620235621235622235623235624235625235626235627235628235629235630235631235632235633235634235635235636235637235638235639235640235641235642235643235644235645235646235647235648235649235650235651235652235653235654235655235656235657235658235659235660235661235662235663235664235665235666235667235668235669235670235671235672235673235674235675235676235677235678235679235680235681235682235683235684235685235686235687235688235689235690235691235692235693235694235695235696235697235698235699235700235701235702235703235704235705235706235707235708235709235710235711235712235713235714235715235716235717235718235719235720235721235722235723235724235725235726235727235728235729235730235731235732235733235734235735235736235737235738235739235740235741235742235743235744235745235746235747235748235749235750235751235752235753235754235755235756235757235758235759235760235761235762235763235764235765235766235767235768235769235770235771235772235773235774235775235776235777235778235779235780235781235782235783235784235785235786235787235788235789235790235791235792235793235794235795235796235797235798235799235800235801235802235803235804235805235806235807235808235809235810235811235812235813235814235815235816235817235818235819235820235821235822235823235824235825235826235827235828235829235830235831235832235833235834235835235836235837235838235839235840235841235842235843235844235845235846235847235848235849235850235851235852235853235854235855235856235857235858235859235860235861235862235863235864235865235866235867235868235869235870235871235872235873235874235875235876235877235878235879235880235881235882235883235884235885235886235887235888235889235890235891235892235893235894235895235896235897235898235899235900235901235902235903235904235905235906235907235908235909235910235911235912235913235914235915235916235917235918235919235920235921235922235923235924235925235926235927235928235929235930235931235932235933235934235935235936235937235938235939235940235941235942235943235944235945235946235947235948235949235950235951235952235953235954235955235956235957235958235959235960235961235962235963235964235965235966235967235968235969235970235971235972235973235974235975235976235977235978235979235980235981235982235983235984235985235986235987235988235989235990235991235992235993235994235995235996235997235998235999236000236001236002236003236004236005236006236007236008236009236010236011236012236013236014236015236016236017236018236019236020236021236022236023236024236025236026236027236028236029236030236031236032236033236034236035236036236037236038236039236040236041236042236043236044236045236046236047236048236049236050236051236052236053236054236055236056236057236058236059236060236061236062236063236064236065236066236067236068236069236070236071236072236073236074236075236076236077236078236079236080236081236082236083236084236085236086236087236088236089236090236091236092236093236094236095236096236097236098236099236100236101236102236103236104236105236106236107236108236109236110236111236112236113236114236115236116236117236118236119236120236121236122236123236124236125236126236127236128236129236130236131236132236133236134236135236136236137236138236139236140236141236142236143236144236145236146236147236148236149236150236151236152236153236154236155236156236157236158236159236160236161236162236163236164236165236166236167236168236169236170236171236172236173236174236175236176236177236178236179236180236181236182236183236184236185236186236187236188236189236190236191236192236193236194236195236196236197236198236199236200236201236202236203236204236205236206236207236208236209236210236211236212236213236214236215236216236217236218236219236220236221236222236223236224236225236226236227236228236229236230236231236232236233236234236235236236236237236238236239236240236241236242236243236244236245236246236247236248236249236250236251236252236253236254236255236256236257236258236259236260236261236262236263236264236265236266236267236268236269236270236271236272236273236274236275236276236277236278236279236280236281236282236283236284236285236286236287236288236289236290236291236292236293236294236295236296236297236298236299236300236301236302236303236304236305236306236307236308236309236310236311236312236313236314236315236316236317236318236319236320236321236322236323236324236325236326236327236328236329236330236331236332236333236334236335236336236337236338236339236340236341236342236343236344236345236346236347236348236349236350236351236352236353236354236355236356236357236358236359236360236361236362236363236364236365236366236367236368236369236370236371236372236373236374236375236376236377236378236379236380236381236382236383236384236385236386236387236388236389236390236391236392236393236394236395236396236397236398236399236400236401236402236403236404236405236406236407236408236409236410236411236412236413236414236415236416236417236418236419236420236421236422236423236424236425236426236427236428236429236430236431236432236433236434236435236436236437236438236439236440236441236442236443236444236445236446236447236448236449236450236451236452236453236454236455236456236457236458236459236460236461236462236463236464236465236466236467236468236469236470236471236472236473236474236475236476236477236478236479236480236481236482236483236484236485236486236487236488236489236490236491236492236493236494236495236496236497236498236499236500236501236502236503236504236505236506236507236508236509236510236511236512236513236514236515236516236517236518236519236520236521236522236523236524236525236526236527236528236529236530236531236532236533236534236535236536236537236538236539236540236541236542236543236544236545236546236547236548236549236550236551236552236553236554236555236556236557236558236559236560236561236562236563236564236565236566236567236568236569236570236571236572236573236574236575236576236577236578236579236580236581236582236583236584236585236586236587236588236589236590236591236592236593236594236595236596236597236598236599236600236601236602236603236604236605236606236607236608236609236610236611236612236613236614236615236616236617236618236619236620236621236622236623236624236625236626236627236628236629236630236631236632236633236634236635236636236637236638236639236640236641236642236643236644236645236646236647236648236649236650236651236652236653236654236655236656236657236658236659236660236661236662236663236664236665236666236667236668236669236670236671236672236673236674236675236676236677236678236679236680236681236682236683236684236685236686236687236688236689236690236691236692236693236694236695236696236697236698236699236700236701236702236703236704236705236706236707236708236709236710236711236712236713236714236715236716236717236718236719236720236721236722236723236724236725236726236727236728236729236730236731236732236733236734236735236736236737236738236739236740236741236742236743236744236745236746236747236748236749236750236751236752236753236754236755236756236757236758236759236760236761236762236763236764236765236766236767236768236769236770236771236772236773236774236775236776236777236778236779236780236781236782236783236784236785236786236787236788236789236790236791236792236793236794236795236796236797236798236799236800236801236802236803236804236805236806236807236808236809236810236811236812236813236814236815236816236817236818236819236820236821236822236823236824236825236826236827236828236829236830236831236832236833236834236835236836236837236838236839236840236841236842236843236844236845236846236847236848236849236850236851236852236853236854236855236856236857236858236859236860236861236862236863236864236865236866236867236868236869236870236871236872236873236874236875236876236877236878236879236880236881236882236883236884236885236886236887236888236889236890236891236892236893236894236895236896236897236898236899236900236901236902236903236904236905236906236907236908236909236910236911236912236913236914236915236916236917236918236919236920236921236922236923236924236925236926236927236928236929236930236931236932236933236934236935236936236937236938236939236940236941236942236943236944236945236946236947236948236949236950236951236952236953236954236955236956236957236958236959236960236961236962236963236964236965236966236967236968236969236970236971236972236973236974236975236976236977236978236979236980236981236982236983236984236985236986236987236988236989236990236991236992236993236994236995236996236997236998236999237000237001237002237003237004237005237006237007237008237009237010237011237012237013237014237015237016237017237018237019237020237021237022237023237024237025237026237027237028237029237030237031237032237033237034237035237036237037237038237039237040237041237042237043237044237045237046237047237048237049237050237051237052237053237054237055237056237057237058237059237060237061237062237063237064237065237066237067237068237069237070237071237072237073237074237075237076237077237078237079237080237081237082237083237084237085237086237087237088237089237090237091237092237093237094237095237096237097237098237099237100237101237102237103237104237105237106237107237108237109237110237111237112237113237114237115237116237117237118237119237120237121237122237123237124237125237126237127237128237129237130237131237132237133237134237135237136237137237138237139237140237141237142237143237144237145237146237147237148237149237150237151237152237153237154237155237156237157237158237159237160237161237162237163237164237165237166237167237168237169237170237171237172237173237174237175237176237177237178237179237180237181237182237183237184237185237186237187237188237189237190237191237192237193237194237195237196237197237198237199237200237201237202237203237204237205237206237207237208237209237210237211237212237213237214237215237216237217237218237219237220237221237222237223237224237225237226237227237228237229237230237231237232237233237234237235237236237237237238237239237240237241237242237243237244237245237246237247237248237249237250237251237252237253237254237255237256237257237258237259237260237261237262237263237264237265237266237267237268237269237270237271237272237273237274237275237276237277237278237279237280237281237282237283237284237285237286237287237288237289237290237291237292237293237294237295237296237297237298237299237300237301237302237303237304237305237306237307237308237309237310237311237312237313237314237315237316237317237318237319237320237321237322237323237324237325237326237327237328237329237330237331237332237333237334237335237336237337237338237339237340237341237342237343237344237345237346237347237348237349237350237351237352237353237354237355237356237357237358237359237360237361237362237363237364237365237366237367237368237369237370237371237372237373237374237375237376237377237378237379237380237381237382237383237384237385237386237387237388237389237390237391237392237393237394237395237396237397237398237399237400237401237402237403237404237405237406237407237408237409237410237411237412237413237414237415237416237417237418237419237420237421237422237423237424237425237426237427237428237429237430237431237432237433237434237435237436237437237438237439237440237441237442237443237444237445237446237447237448237449237450237451237452237453237454237455237456237457237458237459237460237461237462237463237464237465237466237467237468237469237470237471237472237473237474237475237476237477237478237479237480237481237482237483237484237485237486237487237488237489237490237491237492237493237494237495237496237497237498237499237500237501237502237503237504237505237506237507237508237509237510237511237512237513237514237515237516237517237518237519237520237521237522237523237524237525237526237527237528237529237530237531237532237533237534237535237536237537237538237539237540237541237542237543237544237545237546237547237548237549237550237551237552237553237554237555237556237557237558237559237560237561237562237563237564237565237566237567237568237569237570237571237572237573237574237575237576237577237578237579237580237581237582237583237584237585237586237587237588237589237590237591237592237593237594237595237596237597237598237599237600237601237602237603237604237605237606237607237608237609237610237611237612237613237614237615237616237617237618237619237620237621237622237623237624237625237626237627237628237629237630237631237632237633237634237635237636237637237638237639237640237641237642237643237644237645237646237647237648237649237650237651237652237653237654237655237656237657237658237659237660237661237662237663237664237665237666237667237668237669237670237671237672237673237674237675237676237677237678237679237680237681237682237683237684237685237686237687237688237689237690237691237692237693237694237695237696237697237698237699237700237701237702237703237704237705237706237707237708237709237710237711237712237713237714237715237716237717237718237719237720237721237722237723237724237725237726237727237728237729237730237731237732237733237734237735237736237737237738237739237740237741237742237743237744237745237746237747237748237749237750237751237752237753237754237755237756237757237758237759237760237761237762237763237764237765237766237767237768237769237770237771237772237773237774237775237776237777237778237779237780237781237782237783237784237785237786237787237788237789237790237791237792237793237794237795237796237797237798237799237800237801237802237803237804237805237806237807237808237809237810237811237812237813237814237815237816237817237818237819237820237821237822237823237824237825237826237827237828237829237830237831237832237833237834237835237836237837237838237839237840237841237842237843237844237845237846237847237848237849237850237851237852237853237854237855237856237857237858237859237860237861237862237863237864237865237866237867237868237869237870237871237872237873237874237875237876237877237878237879237880237881237882237883237884237885237886237887237888237889237890237891237892237893237894237895237896237897237898237899237900237901237902237903237904237905237906237907237908237909237910237911237912237913237914237915237916237917237918237919237920237921237922237923237924237925237926237927237928237929237930237931237932237933237934237935237936237937237938237939237940237941237942237943237944237945237946237947237948237949237950237951237952237953237954237955237956237957237958237959237960237961237962237963237964237965237966237967237968237969237970237971237972237973237974237975237976237977237978237979237980237981237982237983237984237985237986237987237988237989237990237991237992237993237994237995237996237997237998237999238000238001238002238003238004238005238006238007238008238009238010238011238012238013238014238015238016238017238018238019238020238021238022238023238024238025238026238027238028238029238030238031238032238033238034238035238036238037238038238039238040238041238042238043238044238045238046238047238048238049238050238051238052238053238054238055238056238057238058238059238060238061238062238063238064238065238066238067238068238069238070238071238072238073238074238075238076238077238078238079238080238081238082238083238084238085238086238087238088238089238090238091238092238093238094238095238096238097238098238099238100238101238102238103238104238105238106238107238108238109238110238111238112238113238114238115238116238117238118238119238120238121238122238123238124238125238126238127238128238129238130238131238132238133238134238135238136238137238138238139238140238141238142238143238144238145238146238147238148238149238150238151238152238153238154238155238156238157238158238159238160238161238162238163238164238165238166238167238168238169238170238171238172238173238174238175238176238177238178238179238180238181238182238183238184238185238186238187238188238189238190238191238192238193238194238195238196238197238198238199238200238201238202238203238204238205238206238207238208238209238210238211238212238213238214238215238216238217238218238219238220238221238222238223238224238225238226238227238228238229238230238231238232238233238234238235238236238237238238238239238240238241238242238243238244238245238246238247238248238249238250238251238252238253238254238255238256238257238258238259238260238261238262238263238264238265238266238267238268238269238270238271238272238273238274238275238276238277238278238279238280238281238282238283238284238285238286238287238288238289238290238291238292238293238294238295238296238297238298238299238300238301238302238303238304238305238306238307238308238309238310238311238312238313238314238315238316238317238318238319238320238321238322238323238324238325238326238327238328238329238330238331238332238333238334238335238336238337238338238339238340238341238342238343238344238345238346238347238348238349238350238351238352238353238354238355238356238357238358238359238360238361238362238363238364238365238366238367238368238369238370238371238372238373238374238375238376238377238378238379238380238381238382238383238384238385238386238387238388238389238390238391238392238393238394238395238396238397238398238399238400238401238402238403238404238405238406238407238408238409238410238411238412238413238414238415238416238417238418238419238420238421238422238423238424238425238426238427238428238429238430238431238432238433238434238435238436238437238438238439238440238441238442238443238444238445238446238447238448238449238450238451238452238453238454238455238456238457238458238459238460238461238462238463238464238465238466238467238468238469238470238471238472238473238474238475238476238477238478238479238480238481238482238483238484238485238486238487238488238489238490238491238492238493238494238495238496238497238498238499238500238501238502238503238504238505238506238507238508238509238510238511238512238513238514238515238516238517238518238519238520238521238522238523238524238525238526238527238528238529238530238531238532238533238534238535238536238537238538238539238540238541238542238543238544238545238546238547238548238549238550238551238552238553238554238555238556238557238558238559238560238561238562238563238564238565238566238567238568238569238570238571238572238573238574238575238576238577238578238579238580238581238582238583238584238585238586238587238588238589238590238591238592238593238594238595238596238597238598238599238600238601238602238603238604238605238606238607238608238609238610238611238612238613238614238615238616238617238618238619238620238621238622238623238624238625238626238627238628238629238630238631238632238633238634238635238636238637238638238639238640238641238642238643238644238645238646238647238648238649238650238651238652238653238654238655238656238657238658238659238660238661238662238663238664238665238666238667238668238669238670238671238672238673238674238675238676238677238678238679238680238681238682238683238684238685238686238687238688238689238690238691238692238693238694238695238696238697238698238699238700238701238702238703238704238705238706238707238708238709238710238711238712238713238714238715238716238717238718238719238720238721238722238723238724238725238726238727238728238729238730238731238732238733238734238735238736238737238738238739238740238741238742238743238744238745238746238747238748238749238750238751238752238753238754238755238756238757238758238759238760238761238762238763238764238765238766238767238768238769238770238771238772238773238774238775238776238777238778238779238780238781238782238783238784238785238786238787238788238789238790238791238792238793238794238795238796238797238798238799238800238801238802238803238804238805238806238807238808238809238810238811238812238813238814238815238816238817238818238819238820238821238822238823238824238825238826238827238828238829238830238831238832238833238834238835238836238837238838238839238840238841238842238843238844238845238846238847238848238849238850238851238852238853238854238855238856238857238858238859238860238861238862238863238864238865238866238867238868238869238870238871238872238873238874238875238876238877238878238879238880238881238882238883238884238885238886238887238888238889238890238891238892238893238894238895238896238897238898238899238900238901238902238903238904238905238906238907238908238909238910238911238912238913238914238915238916238917238918238919238920238921238922238923238924238925238926238927238928238929238930238931238932238933238934238935238936238937238938238939238940238941238942238943238944238945238946238947238948238949238950238951238952238953238954238955238956238957238958238959238960238961238962238963238964238965238966238967238968238969238970238971238972238973238974238975238976238977238978238979238980238981238982238983238984238985238986238987238988238989238990238991238992238993238994238995238996238997238998238999239000239001239002239003239004239005239006239007239008239009239010239011239012239013239014239015239016239017239018239019239020239021239022239023239024239025239026239027239028239029239030239031239032239033239034239035239036239037239038239039239040239041239042239043239044239045239046239047239048239049239050239051239052239053239054239055239056239057239058239059239060239061239062239063239064239065239066239067239068239069239070239071239072239073239074239075239076239077239078239079239080239081239082239083239084239085239086239087239088239089239090239091239092239093239094239095239096239097239098239099239100239101239102239103239104239105239106239107239108239109239110239111239112239113239114239115239116239117239118239119239120239121239122239123239124239125239126239127239128239129239130239131239132239133239134239135239136239137239138239139239140239141239142239143239144239145239146239147239148239149239150239151239152239153239154239155239156239157239158239159239160239161239162239163239164239165239166239167239168239169239170239171239172239173239174239175239176239177239178239179239180239181239182239183239184239185239186239187239188239189239190239191239192239193239194239195239196239197239198239199239200239201239202239203239204239205239206239207239208239209239210239211239212239213239214239215239216239217239218239219239220239221239222239223239224239225239226239227239228239229239230239231239232239233239234239235239236239237239238239239239240239241239242239243239244239245239246239247239248239249239250239251239252239253239254239255239256239257239258239259239260239261239262239263239264239265239266239267239268239269239270239271239272239273239274239275239276239277239278239279239280239281239282239283239284239285239286239287239288239289239290239291239292239293239294239295239296239297239298239299239300239301239302239303239304239305239306239307239308239309239310239311239312239313239314239315239316239317239318239319239320239321239322239323239324239325239326239327239328239329239330239331239332239333239334239335239336239337239338239339239340239341239342239343239344239345239346239347239348239349239350239351239352239353239354239355239356239357239358239359239360239361239362239363239364239365239366239367239368239369239370239371239372239373239374239375239376239377239378239379239380239381239382239383239384239385239386239387239388239389239390239391239392239393239394239395239396239397239398239399239400239401239402239403239404239405239406239407239408239409239410239411239412239413239414239415239416239417239418239419239420239421239422239423239424239425239426239427239428239429239430239431239432239433239434239435239436239437239438239439239440239441239442239443239444239445239446239447239448239449239450239451239452239453239454239455239456239457239458239459239460239461239462239463239464239465239466239467239468239469239470239471239472239473239474239475239476239477239478239479239480239481239482239483239484239485239486239487239488239489239490239491239492239493239494239495239496239497239498239499239500239501239502239503239504239505239506239507239508239509239510239511239512239513239514239515239516239517239518239519239520239521239522239523239524239525239526239527239528239529239530239531239532239533239534239535239536239537239538239539239540239541239542239543239544239545239546239547239548239549239550239551239552239553239554239555239556239557239558239559239560239561239562239563239564239565239566239567239568239569239570239571239572239573239574239575239576239577239578239579239580239581239582239583239584239585239586239587239588239589239590239591239592239593239594239595239596239597239598239599239600239601239602239603239604239605239606239607239608239609239610239611239612239613239614239615239616239617239618239619239620239621239622239623239624239625239626239627239628239629239630239631239632239633239634239635239636239637239638239639239640239641239642239643239644239645239646239647239648239649239650239651239652239653239654239655239656239657239658239659239660239661239662239663239664239665239666239667239668239669239670239671239672239673239674239675239676239677239678239679239680239681239682239683239684239685239686239687239688239689239690239691239692239693239694239695239696239697239698239699239700239701239702239703239704239705239706239707239708239709239710239711239712239713239714239715239716239717239718239719239720239721239722239723239724239725239726239727239728239729239730239731239732239733239734239735239736239737239738239739239740239741239742239743239744239745239746239747239748239749239750239751239752239753239754239755239756239757239758239759239760239761239762239763239764239765239766239767239768239769239770239771239772239773239774239775239776239777239778239779239780239781239782239783239784239785239786239787239788239789239790239791239792239793239794239795239796239797239798239799239800239801239802239803239804239805239806239807239808239809239810239811239812239813239814239815239816239817239818239819239820239821239822239823239824239825239826239827239828239829239830239831239832239833239834239835239836239837239838239839239840239841239842239843239844239845239846239847239848239849239850239851239852239853239854239855239856239857239858239859239860239861239862239863239864239865239866239867239868239869239870239871239872239873239874239875239876239877239878239879239880239881239882239883239884239885239886239887239888239889239890239891239892239893239894239895239896239897239898239899239900239901239902239903239904239905239906239907239908239909239910239911239912239913239914
  1. diff -Nur linux-3.14.17/arch/arm/boot/dts/clcd-panels.dtsi linux-imx6-3.14/arch/arm/boot/dts/clcd-panels.dtsi
  2. --- linux-3.14.17/arch/arm/boot/dts/clcd-panels.dtsi 1970-01-01 01:00:00.000000000 +0100
  3. +++ linux-imx6-3.14/arch/arm/boot/dts/clcd-panels.dtsi 2014-09-11 18:05:52.586000344 +0200
  4. @@ -0,0 +1,52 @@
  5. +/*
  6. + * ARM Ltd. Versatile Express
  7. + *
  8. + */
  9. +
  10. +/ {
  11. + panels {
  12. + panel@0 {
  13. + compatible = "panel";
  14. + mode = "VGA";
  15. + refresh = <60>;
  16. + xres = <640>;
  17. + yres = <480>;
  18. + pixclock = <39721>;
  19. + left_margin = <40>;
  20. + right_margin = <24>;
  21. + upper_margin = <32>;
  22. + lower_margin = <11>;
  23. + hsync_len = <96>;
  24. + vsync_len = <2>;
  25. + sync = <0>;
  26. + vmode = "FB_VMODE_NONINTERLACED";
  27. +
  28. + tim2 = "TIM2_BCD", "TIM2_IPC";
  29. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  30. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  31. + bpp = <16>;
  32. + };
  33. +
  34. + panel@1 {
  35. + compatible = "panel";
  36. + mode = "XVGA";
  37. + refresh = <60>;
  38. + xres = <1024>;
  39. + yres = <768>;
  40. + pixclock = <15748>;
  41. + left_margin = <152>;
  42. + right_margin = <48>;
  43. + upper_margin = <23>;
  44. + lower_margin = <3>;
  45. + hsync_len = <104>;
  46. + vsync_len = <4>;
  47. + sync = <0>;
  48. + vmode = "FB_VMODE_NONINTERLACED";
  49. +
  50. + tim2 = "TIM2_BCD", "TIM2_IPC";
  51. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  52. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  53. + bpp = <16>;
  54. + };
  55. + };
  56. +};
  57. diff -Nur linux-3.14.17/arch/arm/boot/dts/dra7-evm.dts linux-imx6-3.14/arch/arm/boot/dts/dra7-evm.dts
  58. --- linux-3.14.17/arch/arm/boot/dts/dra7-evm.dts 2014-08-14 03:38:34.000000000 +0200
  59. +++ linux-imx6-3.14/arch/arm/boot/dts/dra7-evm.dts 2014-09-11 18:05:52.590000359 +0200
  60. @@ -182,7 +182,6 @@
  61. regulator-name = "ldo3";
  62. regulator-min-microvolt = <1800000>;
  63. regulator-max-microvolt = <1800000>;
  64. - regulator-always-on;
  65. regulator-boot-on;
  66. };
  67. diff -Nur linux-3.14.17/arch/arm/boot/dts/efm32gg-dk3750.dts linux-imx6-3.14/arch/arm/boot/dts/efm32gg-dk3750.dts
  68. --- linux-3.14.17/arch/arm/boot/dts/efm32gg-dk3750.dts 2014-08-14 03:38:34.000000000 +0200
  69. +++ linux-imx6-3.14/arch/arm/boot/dts/efm32gg-dk3750.dts 2014-09-11 18:05:52.590000359 +0200
  70. @@ -26,7 +26,7 @@
  71. };
  72. i2c@4000a000 {
  73. - location = <3>;
  74. + efm32,location = <3>;
  75. status = "ok";
  76. temp@48 {
  77. diff -Nur linux-3.14.17/arch/arm/boot/dts/hi3620.dtsi linux-imx6-3.14/arch/arm/boot/dts/hi3620.dtsi
  78. --- linux-3.14.17/arch/arm/boot/dts/hi3620.dtsi 2014-08-14 03:38:34.000000000 +0200
  79. +++ linux-imx6-3.14/arch/arm/boot/dts/hi3620.dtsi 2014-09-11 18:05:52.590000359 +0200
  80. @@ -73,7 +73,7 @@
  81. L2: l2-cache {
  82. compatible = "arm,pl310-cache";
  83. - reg = <0x100000 0x100000>;
  84. + reg = <0xfc10000 0x100000>;
  85. interrupts = <0 15 4>;
  86. cache-unified;
  87. cache-level = <2>;
  88. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx23.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx23.dtsi
  89. --- linux-3.14.17/arch/arm/boot/dts/imx23.dtsi 2014-08-14 03:38:34.000000000 +0200
  90. +++ linux-imx6-3.14/arch/arm/boot/dts/imx23.dtsi 2014-09-11 18:05:52.594000374 +0200
  91. @@ -363,7 +363,8 @@
  92. compatible = "fsl,imx23-lcdif";
  93. reg = <0x80030000 2000>;
  94. interrupts = <46 45>;
  95. - clocks = <&clks 38>;
  96. + clocks = <&clks 38>, <&clks 38>;
  97. + clock-names = "pix", "axi";
  98. status = "disabled";
  99. };
  100. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx25.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx25.dtsi
  101. --- linux-3.14.17/arch/arm/boot/dts/imx25.dtsi 2014-08-14 03:38:34.000000000 +0200
  102. +++ linux-imx6-3.14/arch/arm/boot/dts/imx25.dtsi 2014-09-11 18:05:52.594000374 +0200
  103. @@ -13,6 +13,7 @@
  104. / {
  105. aliases {
  106. + ethernet0 = &fec;
  107. gpio0 = &gpio1;
  108. gpio1 = &gpio2;
  109. gpio2 = &gpio3;
  110. @@ -56,6 +57,7 @@
  111. osc {
  112. compatible = "fsl,imx-osc", "fixed-clock";
  113. + #clock-cells = <0>;
  114. clock-frequency = <24000000>;
  115. };
  116. };
  117. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx25-karo-tx25.dts linux-imx6-3.14/arch/arm/boot/dts/imx25-karo-tx25.dts
  118. --- linux-3.14.17/arch/arm/boot/dts/imx25-karo-tx25.dts 2014-08-14 03:38:34.000000000 +0200
  119. +++ linux-imx6-3.14/arch/arm/boot/dts/imx25-karo-tx25.dts 2014-09-11 18:05:52.594000374 +0200
  120. @@ -16,6 +16,10 @@
  121. model = "Ka-Ro TX25";
  122. compatible = "karo,imx25-tx25", "fsl,imx25";
  123. + chosen {
  124. + stdout-path = &uart1;
  125. + };
  126. +
  127. memory {
  128. reg = <0x80000000 0x02000000 0x90000000 0x02000000>;
  129. };
  130. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx27-apf27.dts linux-imx6-3.14/arch/arm/boot/dts/imx27-apf27.dts
  131. --- linux-3.14.17/arch/arm/boot/dts/imx27-apf27.dts 2014-08-14 03:38:34.000000000 +0200
  132. +++ linux-imx6-3.14/arch/arm/boot/dts/imx27-apf27.dts 2014-09-11 18:05:52.594000374 +0200
  133. @@ -29,6 +29,7 @@
  134. osc26m {
  135. compatible = "fsl,imx-osc26m", "fixed-clock";
  136. + #clock-cells = <0>;
  137. clock-frequency = <0>;
  138. };
  139. };
  140. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx27.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx27.dtsi
  141. --- linux-3.14.17/arch/arm/boot/dts/imx27.dtsi 2014-08-14 03:38:34.000000000 +0200
  142. +++ linux-imx6-3.14/arch/arm/boot/dts/imx27.dtsi 2014-09-11 18:05:52.594000374 +0200
  143. @@ -13,6 +13,7 @@
  144. / {
  145. aliases {
  146. + ethernet0 = &fec;
  147. gpio0 = &gpio1;
  148. gpio1 = &gpio2;
  149. gpio2 = &gpio3;
  150. @@ -46,6 +47,7 @@
  151. osc26m {
  152. compatible = "fsl,imx-osc26m", "fixed-clock";
  153. + #clock-cells = <0>;
  154. clock-frequency = <26000000>;
  155. };
  156. };
  157. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts linux-imx6-3.14/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
  158. --- linux-3.14.17/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts 2014-08-14 03:38:34.000000000 +0200
  159. +++ linux-imx6-3.14/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts 2014-09-11 18:05:52.594000374 +0200
  160. @@ -15,6 +15,10 @@
  161. model = "Phytec pca100 rapid development kit";
  162. compatible = "phytec,imx27-pca100-rdk", "phytec,imx27-pca100", "fsl,imx27";
  163. + chosen {
  164. + stdout-path = &uart1;
  165. + };
  166. +
  167. display: display {
  168. model = "Primeview-PD050VL1";
  169. native-mode = <&timing0>;
  170. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx28.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx28.dtsi
  171. --- linux-3.14.17/arch/arm/boot/dts/imx28.dtsi 2014-08-14 03:38:34.000000000 +0200
  172. +++ linux-imx6-3.14/arch/arm/boot/dts/imx28.dtsi 2014-09-11 18:05:52.614000456 +0200
  173. @@ -840,7 +840,8 @@
  174. compatible = "fsl,imx28-lcdif";
  175. reg = <0x80030000 0x2000>;
  176. interrupts = <38>;
  177. - clocks = <&clks 55>;
  178. + clocks = <&clks 55>, <&clks 55>;
  179. + clock-names = "pix", "axi";
  180. dmas = <&dma_apbh 13>;
  181. dma-names = "rx";
  182. status = "disabled";
  183. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx51-babbage.dts linux-imx6-3.14/arch/arm/boot/dts/imx51-babbage.dts
  184. --- linux-3.14.17/arch/arm/boot/dts/imx51-babbage.dts 2014-08-14 03:38:34.000000000 +0200
  185. +++ linux-imx6-3.14/arch/arm/boot/dts/imx51-babbage.dts 2014-09-11 18:05:52.614000456 +0200
  186. @@ -17,6 +17,10 @@
  187. model = "Freescale i.MX51 Babbage Board";
  188. compatible = "fsl,imx51-babbage", "fsl,imx51";
  189. + chosen {
  190. + stdout-path = &uart1;
  191. + };
  192. +
  193. memory {
  194. reg = <0x90000000 0x20000000>;
  195. };
  196. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx51.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx51.dtsi
  197. --- linux-3.14.17/arch/arm/boot/dts/imx51.dtsi 2014-08-14 03:38:34.000000000 +0200
  198. +++ linux-imx6-3.14/arch/arm/boot/dts/imx51.dtsi 2014-09-11 18:05:52.614000456 +0200
  199. @@ -15,6 +15,7 @@
  200. / {
  201. aliases {
  202. + ethernet0 = &fec;
  203. gpio0 = &gpio1;
  204. gpio1 = &gpio2;
  205. gpio2 = &gpio3;
  206. @@ -43,21 +44,25 @@
  207. ckil {
  208. compatible = "fsl,imx-ckil", "fixed-clock";
  209. + #clock-cells = <0>;
  210. clock-frequency = <32768>;
  211. };
  212. ckih1 {
  213. compatible = "fsl,imx-ckih1", "fixed-clock";
  214. + #clock-cells = <0>;
  215. clock-frequency = <0>;
  216. };
  217. ckih2 {
  218. compatible = "fsl,imx-ckih2", "fixed-clock";
  219. + #clock-cells = <0>;
  220. clock-frequency = <0>;
  221. };
  222. osc {
  223. compatible = "fsl,imx-osc", "fixed-clock";
  224. + #clock-cells = <0>;
  225. clock-frequency = <24000000>;
  226. };
  227. };
  228. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx53.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx53.dtsi
  229. --- linux-3.14.17/arch/arm/boot/dts/imx53.dtsi 2014-08-14 03:38:34.000000000 +0200
  230. +++ linux-imx6-3.14/arch/arm/boot/dts/imx53.dtsi 2014-09-11 18:05:52.634000535 +0200
  231. @@ -15,6 +15,7 @@
  232. / {
  233. aliases {
  234. + ethernet0 = &fec;
  235. gpio0 = &gpio1;
  236. gpio1 = &gpio2;
  237. gpio2 = &gpio3;
  238. @@ -59,21 +60,25 @@
  239. ckil {
  240. compatible = "fsl,imx-ckil", "fixed-clock";
  241. + #clock-cells = <0>;
  242. clock-frequency = <32768>;
  243. };
  244. ckih1 {
  245. compatible = "fsl,imx-ckih1", "fixed-clock";
  246. + #clock-cells = <0>;
  247. clock-frequency = <22579200>;
  248. };
  249. ckih2 {
  250. compatible = "fsl,imx-ckih2", "fixed-clock";
  251. + #clock-cells = <0>;
  252. clock-frequency = <0>;
  253. };
  254. osc {
  255. compatible = "fsl,imx-osc", "fixed-clock";
  256. + #clock-cells = <0>;
  257. clock-frequency = <24000000>;
  258. };
  259. };
  260. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx53-mba53.dts linux-imx6-3.14/arch/arm/boot/dts/imx53-mba53.dts
  261. --- linux-3.14.17/arch/arm/boot/dts/imx53-mba53.dts 2014-08-14 03:38:34.000000000 +0200
  262. +++ linux-imx6-3.14/arch/arm/boot/dts/imx53-mba53.dts 2014-09-11 18:05:52.614000456 +0200
  263. @@ -25,6 +25,10 @@
  264. enable-active-low;
  265. };
  266. + chosen {
  267. + stdout-path = &uart2;
  268. + };
  269. +
  270. backlight {
  271. compatible = "pwm-backlight";
  272. pwms = <&pwm2 0 50000>;
  273. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
  274. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts 1970-01-01 01:00:00.000000000 +0100
  275. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts 2014-09-11 18:05:52.634000535 +0200
  276. @@ -0,0 +1,23 @@
  277. +/*
  278. + * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.de>
  279. + *
  280. + * The code contained herein is licensed under the GNU General Public
  281. + * License. You may obtain a copy of the GNU General Public License
  282. + * Version 2 or later at the following locations:
  283. + *
  284. + * http://www.opensource.org/licenses/gpl-license.html
  285. + * http://www.gnu.org/copyleft/gpl.html
  286. + */
  287. +
  288. +#ifndef __DTS_V1__
  289. +#define __DTS_V1__
  290. +/dts-v1/;
  291. +#endif
  292. +
  293. +#include "imx6dl.dtsi"
  294. +#include "imx6qdl-dfi-fs700-m60.dtsi"
  295. +
  296. +/ {
  297. + model = "DFI FS700-M60-6DL i.MX6dl Q7 Board";
  298. + compatible = "dfi,fs700-m60-6dl", "dfi,fs700e-m60", "fsl,imx6dl";
  299. +};
  300. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6dl.dtsi
  301. --- linux-3.14.17/arch/arm/boot/dts/imx6dl.dtsi 2014-08-14 03:38:34.000000000 +0200
  302. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl.dtsi 2014-09-11 18:05:52.634000535 +0200
  303. @@ -8,6 +8,7 @@
  304. *
  305. */
  306. +#include <dt-bindings/interrupt-controller/irq.h>
  307. #include "imx6dl-pinfunc.h"
  308. #include "imx6qdl.dtsi"
  309. @@ -21,6 +22,26 @@
  310. device_type = "cpu";
  311. reg = <0>;
  312. next-level-cache = <&L2>;
  313. + operating-points = <
  314. + /* kHz uV */
  315. + 996000 1275000
  316. + 792000 1175000
  317. + 396000 1075000
  318. + >;
  319. + fsl,soc-operating-points = <
  320. + /* ARM kHz SOC-PU uV */
  321. + 996000 1175000
  322. + 792000 1175000
  323. + 396000 1175000
  324. + >;
  325. + clock-latency = <61036>; /* two CLK32 periods */
  326. + clocks = <&clks 104>, <&clks 6>, <&clks 16>,
  327. + <&clks 17>, <&clks 170>;
  328. + clock-names = "arm", "pll2_pfd2_396m", "step",
  329. + "pll1_sw", "pll1_sys";
  330. + arm-supply = <&reg_arm>;
  331. + pu-supply = <&reg_pu>;
  332. + soc-supply = <&reg_soc>;
  333. };
  334. cpu@1 {
  335. @@ -32,40 +53,124 @@
  336. };
  337. soc {
  338. +
  339. + busfreq { /* BUSFREQ */
  340. + compatible = "fsl,imx6_busfreq";
  341. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  342. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>, <&clks 22> , <&clks 8>;
  343. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  344. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "axi_sel", "pll3_pfd1_540m";
  345. + interrupts = <0 107 0x04>, <0 112 0x4>;
  346. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1";
  347. + fsl,max_ddr_freq = <400000000>;
  348. + };
  349. +
  350. + gpu@00130000 {
  351. + compatible = "fsl,imx6dl-gpu", "fsl,imx6q-gpu";
  352. + reg = <0x00130000 0x4000>, <0x00134000 0x4000>,
  353. + <0x0 0x0>;
  354. + reg-names = "iobase_3d", "iobase_2d",
  355. + "phys_baseaddr";
  356. + interrupts = <0 9 0x04>, <0 10 0x04>;
  357. + interrupt-names = "irq_3d", "irq_2d";
  358. + clocks = <&clks 143>, <&clks 27>,
  359. + <&clks 121>, <&clks 122>,
  360. + <&clks 0>;
  361. + clock-names = "gpu2d_axi_clk", "gpu3d_axi_clk",
  362. + "gpu2d_clk", "gpu3d_clk",
  363. + "gpu3d_shader_clk";
  364. + resets = <&src 0>, <&src 3>;
  365. + reset-names = "gpu3d", "gpu2d";
  366. + pu-supply = <&reg_pu>;
  367. + };
  368. +
  369. ocram: sram@00900000 {
  370. compatible = "mmio-sram";
  371. reg = <0x00900000 0x20000>;
  372. clocks = <&clks 142>;
  373. };
  374. + hdmi_core: hdmi_core@00120000 {
  375. + compatible = "fsl,imx6dl-hdmi-core";
  376. + reg = <0x00120000 0x9000>;
  377. + clocks = <&clks 124>, <&clks 123>;
  378. + clock-names = "hdmi_isfr", "hdmi_iahb";
  379. + status = "disabled";
  380. + };
  381. +
  382. + hdmi_video: hdmi_video@020e0000 {
  383. + compatible = "fsl,imx6dl-hdmi-video";
  384. + reg = <0x020e0000 0x1000>;
  385. + reg-names = "hdmi_gpr";
  386. + interrupts = <0 115 0x04>;
  387. + clocks = <&clks 124>, <&clks 123>;
  388. + clock-names = "hdmi_isfr", "hdmi_iahb";
  389. + status = "disabled";
  390. + };
  391. +
  392. + hdmi_audio: hdmi_audio@00120000 {
  393. + compatible = "fsl,imx6dl-hdmi-audio";
  394. + clocks = <&clks 124>, <&clks 123>;
  395. + clock-names = "hdmi_isfr", "hdmi_iahb";
  396. + dmas = <&sdma 2 23 0>;
  397. + dma-names = "tx";
  398. + status = "disabled";
  399. + };
  400. +
  401. + hdmi_cec: hdmi_cec@00120000 {
  402. + compatible = "fsl,imx6dl-hdmi-cec";
  403. + interrupts = <0 115 0x04>;
  404. + status = "disabled";
  405. + };
  406. +
  407. aips1: aips-bus@02000000 {
  408. + vpu@02040000 {
  409. + iramsize = <0>;
  410. + status = "okay";
  411. + };
  412. +
  413. iomuxc: iomuxc@020e0000 {
  414. compatible = "fsl,imx6dl-iomuxc";
  415. };
  416. pxp: pxp@020f0000 {
  417. + compatible = "fsl,imx6dl-pxp-dma";
  418. reg = <0x020f0000 0x4000>;
  419. - interrupts = <0 98 0x04>;
  420. + interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
  421. + clocks = <&clks 133>;
  422. + clock-names = "pxp-axi";
  423. + status = "disabled";
  424. };
  425. epdc: epdc@020f4000 {
  426. reg = <0x020f4000 0x4000>;
  427. - interrupts = <0 97 0x04>;
  428. + interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
  429. };
  430. lcdif: lcdif@020f8000 {
  431. reg = <0x020f8000 0x4000>;
  432. - interrupts = <0 39 0x04>;
  433. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  434. };
  435. };
  436. aips2: aips-bus@02100000 {
  437. + mipi_dsi: mipi@021e0000 {
  438. + compatible = "fsl,imx6dl-mipi-dsi";
  439. + reg = <0x021e0000 0x4000>;
  440. + interrupts = <0 102 0x04>;
  441. + gpr = <&gpr>;
  442. + clocks = <&clks 138>, <&clks 209>;
  443. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  444. + status = "disabled";
  445. + };
  446. +
  447. i2c4: i2c@021f8000 {
  448. #address-cells = <1>;
  449. #size-cells = <0>;
  450. - compatible = "fsl,imx1-i2c";
  451. + compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  452. reg = <0x021f8000 0x4000>;
  453. - interrupts = <0 35 0x04>;
  454. + interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
  455. + clocks = <&clks 116>;
  456. status = "disabled";
  457. };
  458. };
  459. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-gw51xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw51xx.dts
  460. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-gw51xx.dts 1970-01-01 01:00:00.000000000 +0100
  461. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw51xx.dts 2014-09-11 18:05:52.634000535 +0200
  462. @@ -0,0 +1,19 @@
  463. +/*
  464. + * Copyright 2013 Gateworks Corporation
  465. + *
  466. + * The code contained herein is licensed under the GNU General Public
  467. + * License. You may obtain a copy of the GNU General Public License
  468. + * Version 2 or later at the following locations:
  469. + *
  470. + * http://www.opensource.org/licenses/gpl-license.html
  471. + * http://www.gnu.org/copyleft/gpl.html
  472. + */
  473. +
  474. +/dts-v1/;
  475. +#include "imx6dl.dtsi"
  476. +#include "imx6qdl-gw51xx.dtsi"
  477. +
  478. +/ {
  479. + model = "Gateworks Ventana i.MX6 DualLite GW51XX";
  480. + compatible = "gw,imx6dl-gw51xx", "gw,ventana", "fsl,imx6dl";
  481. +};
  482. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-gw52xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw52xx.dts
  483. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-gw52xx.dts 1970-01-01 01:00:00.000000000 +0100
  484. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw52xx.dts 2014-09-11 18:05:52.634000535 +0200
  485. @@ -0,0 +1,19 @@
  486. +/*
  487. + * Copyright 2013 Gateworks Corporation
  488. + *
  489. + * The code contained herein is licensed under the GNU General Public
  490. + * License. You may obtain a copy of the GNU General Public License
  491. + * Version 2 or later at the following locations:
  492. + *
  493. + * http://www.opensource.org/licenses/gpl-license.html
  494. + * http://www.gnu.org/copyleft/gpl.html
  495. + */
  496. +
  497. +/dts-v1/;
  498. +#include "imx6dl.dtsi"
  499. +#include "imx6qdl-gw52xx.dtsi"
  500. +
  501. +/ {
  502. + model = "Gateworks Ventana i.MX6 DualLite GW52XX";
  503. + compatible = "gw,imx6dl-gw52xx", "gw,ventana", "fsl,imx6dl";
  504. +};
  505. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-gw53xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw53xx.dts
  506. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-gw53xx.dts 1970-01-01 01:00:00.000000000 +0100
  507. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw53xx.dts 2014-09-11 18:05:52.634000535 +0200
  508. @@ -0,0 +1,19 @@
  509. +/*
  510. + * Copyright 2013 Gateworks Corporation
  511. + *
  512. + * The code contained herein is licensed under the GNU General Public
  513. + * License. You may obtain a copy of the GNU General Public License
  514. + * Version 2 or later at the following locations:
  515. + *
  516. + * http://www.opensource.org/licenses/gpl-license.html
  517. + * http://www.gnu.org/copyleft/gpl.html
  518. + */
  519. +
  520. +/dts-v1/;
  521. +#include "imx6dl.dtsi"
  522. +#include "imx6qdl-gw53xx.dtsi"
  523. +
  524. +/ {
  525. + model = "Gateworks Ventana i.MX6 DualLite GW53XX";
  526. + compatible = "gw,imx6dl-gw53xx", "gw,ventana", "fsl,imx6dl";
  527. +};
  528. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-gw54xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw54xx.dts
  529. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-gw54xx.dts 1970-01-01 01:00:00.000000000 +0100
  530. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-gw54xx.dts 2014-09-11 18:05:52.634000535 +0200
  531. @@ -0,0 +1,19 @@
  532. +/*
  533. + * Copyright 2013 Gateworks Corporation
  534. + *
  535. + * The code contained herein is licensed under the GNU General Public
  536. + * License. You may obtain a copy of the GNU General Public License
  537. + * Version 2 or later at the following locations:
  538. + *
  539. + * http://www.opensource.org/licenses/gpl-license.html
  540. + * http://www.gnu.org/copyleft/gpl.html
  541. + */
  542. +
  543. +/dts-v1/;
  544. +#include "imx6dl.dtsi"
  545. +#include "imx6qdl-gw54xx.dtsi"
  546. +
  547. +/ {
  548. + model = "Gateworks Ventana i.MX6 DualLite GW54XX";
  549. + compatible = "gw,imx6dl-gw54xx", "gw,ventana", "fsl,imx6dl";
  550. +};
  551. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-hummingboard.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-hummingboard.dts
  552. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-08-14 03:38:34.000000000 +0200
  553. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-hummingboard.dts 2014-09-11 18:05:52.634000535 +0200
  554. @@ -1,163 +1,13 @@
  555. /*
  556. - * Copyright (C) 2013,2014 Russell King
  557. + * Copyright (C) 2014 Rabeeh Khoury (rabeeh@solid-run.com)
  558. + * Based on work by Russell King
  559. */
  560. /dts-v1/;
  561. #include "imx6dl.dtsi"
  562. -#include "imx6qdl-microsom.dtsi"
  563. -#include "imx6qdl-microsom-ar8035.dtsi"
  564. +#include "imx6qdl-hummingboard.dtsi"
  565. / {
  566. - model = "SolidRun HummingBoard DL/Solo";
  567. - compatible = "solidrun,hummingboard", "fsl,imx6dl";
  568. -
  569. - ir_recv: ir-receiver {
  570. - compatible = "gpio-ir-receiver";
  571. - gpios = <&gpio1 2 1>;
  572. - pinctrl-names = "default";
  573. - pinctrl-0 = <&pinctrl_hummingboard_gpio1_2>;
  574. - };
  575. -
  576. - regulators {
  577. - compatible = "simple-bus";
  578. -
  579. - reg_3p3v: 3p3v {
  580. - compatible = "regulator-fixed";
  581. - regulator-name = "3P3V";
  582. - regulator-min-microvolt = <3300000>;
  583. - regulator-max-microvolt = <3300000>;
  584. - regulator-always-on;
  585. - };
  586. -
  587. - reg_usbh1_vbus: usb-h1-vbus {
  588. - compatible = "regulator-fixed";
  589. - enable-active-high;
  590. - gpio = <&gpio1 0 0>;
  591. - pinctrl-names = "default";
  592. - pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>;
  593. - regulator-name = "usb_h1_vbus";
  594. - regulator-min-microvolt = <5000000>;
  595. - regulator-max-microvolt = <5000000>;
  596. - };
  597. -
  598. - reg_usbotg_vbus: usb-otg-vbus {
  599. - compatible = "regulator-fixed";
  600. - enable-active-high;
  601. - gpio = <&gpio3 22 0>;
  602. - pinctrl-names = "default";
  603. - pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>;
  604. - regulator-name = "usb_otg_vbus";
  605. - regulator-min-microvolt = <5000000>;
  606. - regulator-max-microvolt = <5000000>;
  607. - };
  608. - };
  609. -
  610. - sound-spdif {
  611. - compatible = "fsl,imx-audio-spdif";
  612. - model = "imx-spdif";
  613. - /* IMX6 doesn't implement this yet */
  614. - spdif-controller = <&spdif>;
  615. - spdif-out;
  616. - };
  617. -};
  618. -
  619. -&can1 {
  620. - pinctrl-names = "default";
  621. - pinctrl-0 = <&pinctrl_hummingboard_flexcan1>;
  622. - status = "okay";
  623. -};
  624. -
  625. -&i2c1 {
  626. - pinctrl-names = "default";
  627. - pinctrl-0 = <&pinctrl_hummingboard_i2c1>;
  628. -
  629. - /*
  630. - * Not fitted on Carrier-1 board... yet
  631. - status = "okay";
  632. -
  633. - rtc: pcf8523@68 {
  634. - compatible = "nxp,pcf8523";
  635. - reg = <0x68>;
  636. - };
  637. - */
  638. -};
  639. -
  640. -&iomuxc {
  641. - hummingboard {
  642. - pinctrl_hummingboard_flexcan1: hummingboard-flexcan1 {
  643. - fsl,pins = <
  644. - MX6QDL_PAD_SD3_CLK__FLEXCAN1_RX 0x80000000
  645. - MX6QDL_PAD_SD3_CMD__FLEXCAN1_TX 0x80000000
  646. - >;
  647. - };
  648. -
  649. - pinctrl_hummingboard_gpio1_2: hummingboard-gpio1_2 {
  650. - fsl,pins = <
  651. - MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000
  652. - >;
  653. - };
  654. -
  655. - pinctrl_hummingboard_i2c1: hummingboard-i2c1 {
  656. - fsl,pins = <
  657. - MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  658. - MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  659. - >;
  660. - };
  661. -
  662. - pinctrl_hummingboard_spdif: hummingboard-spdif {
  663. - fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  664. - };
  665. -
  666. - pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus {
  667. - fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  668. - };
  669. -
  670. - pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
  671. - fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  672. - };
  673. -
  674. - pinctrl_hummingboard_usdhc2_aux: hummingboard-usdhc2-aux {
  675. - fsl,pins = <
  676. - MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
  677. - >;
  678. - };
  679. -
  680. - pinctrl_hummingboard_usdhc2: hummingboard-usdhc2 {
  681. - fsl,pins = <
  682. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  683. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  684. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  685. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  686. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  687. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  688. - >;
  689. - };
  690. - };
  691. -};
  692. -
  693. -&spdif {
  694. - pinctrl-names = "default";
  695. - pinctrl-0 = <&pinctrl_hummingboard_spdif>;
  696. - status = "okay";
  697. -};
  698. -
  699. -&usbh1 {
  700. - vbus-supply = <&reg_usbh1_vbus>;
  701. - status = "okay";
  702. -};
  703. -
  704. -&usbotg {
  705. - vbus-supply = <&reg_usbotg_vbus>;
  706. - status = "okay";
  707. -};
  708. -
  709. -&usdhc2 {
  710. - pinctrl-names = "default";
  711. - pinctrl-0 = <
  712. - &pinctrl_hummingboard_usdhc2_aux
  713. - &pinctrl_hummingboard_usdhc2
  714. - >;
  715. - vmmc-supply = <&reg_3p3v>;
  716. - cd-gpios = <&gpio1 4 0>;
  717. - status = "okay";
  718. + model = "SolidRun HummingBoard Solo/DualLite";
  719. + compatible = "solidrun,hummingboard/dl", "fsl,imx6dl";
  720. };
  721. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-nitrogen6x.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-nitrogen6x.dts
  722. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-nitrogen6x.dts 1970-01-01 01:00:00.000000000 +0100
  723. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-nitrogen6x.dts 2014-09-11 18:05:52.634000535 +0200
  724. @@ -0,0 +1,21 @@
  725. +/*
  726. + * Copyright 2013 Boundary Devices, Inc.
  727. + * Copyright 2012 Freescale Semiconductor, Inc.
  728. + * Copyright 2011 Linaro Ltd.
  729. + *
  730. + * The code contained herein is licensed under the GNU General Public
  731. + * License. You may obtain a copy of the GNU General Public License
  732. + * Version 2 or later at the following locations:
  733. + *
  734. + * http://www.opensource.org/licenses/gpl-license.html
  735. + * http://www.gnu.org/copyleft/gpl.html
  736. + */
  737. +
  738. +/dts-v1/;
  739. +#include "imx6dl.dtsi"
  740. +#include "imx6qdl-nitrogen6x.dtsi"
  741. +
  742. +/ {
  743. + model = "Freescale i.MX6 DualLite Nitrogen6x Board";
  744. + compatible = "fsl,imx6dl-nitrogen6x", "fsl,imx6dl";
  745. +};
  746. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts
  747. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts 1970-01-01 01:00:00.000000000 +0100
  748. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pbab01.dts 2014-09-11 18:05:52.634000535 +0200
  749. @@ -0,0 +1,19 @@
  750. +/*
  751. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  752. + *
  753. + * The code contained herein is licensed under the GNU General Public
  754. + * License. You may obtain a copy of the GNU General Public License
  755. + * Version 2 or later at the following locations:
  756. + *
  757. + * http://www.opensource.org/licenses/gpl-license.html
  758. + * http://www.gnu.org/copyleft/gpl.html
  759. + */
  760. +
  761. +/dts-v1/;
  762. +#include "imx6dl-phytec-pfla02.dtsi"
  763. +#include "imx6qdl-phytec-pbab01.dtsi"
  764. +
  765. +/ {
  766. + model = "Phytec phyFLEX-i.MX6 DualLite/Solo Carrier-Board";
  767. + compatible = "phytec,imx6dl-pbab01", "phytec,imx6dl-pfla02", "fsl,imx6dl";
  768. +};
  769. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi
  770. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi 1970-01-01 01:00:00.000000000 +0100
  771. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-phytec-pfla02.dtsi 2014-09-11 18:05:52.634000535 +0200
  772. @@ -0,0 +1,22 @@
  773. +/*
  774. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  775. + *
  776. + * The code contained herein is licensed under the GNU General Public
  777. + * License. You may obtain a copy of the GNU General Public License
  778. + * Version 2 or later at the following locations:
  779. + *
  780. + * http://www.opensource.org/licenses/gpl-license.html
  781. + * http://www.gnu.org/copyleft/gpl.html
  782. + */
  783. +
  784. +#include "imx6dl.dtsi"
  785. +#include "imx6qdl-phytec-pfla02.dtsi"
  786. +
  787. +/ {
  788. + model = "Phytec phyFLEX-i.MX6 DualLite/Solo";
  789. + compatible = "phytec,imx6dl-pfla02", "fsl,imx6dl";
  790. +
  791. + memory {
  792. + reg = <0x10000000 0x20000000>;
  793. + };
  794. +};
  795. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-pinfunc.h linux-imx6-3.14/arch/arm/boot/dts/imx6dl-pinfunc.h
  796. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-pinfunc.h 2014-08-14 03:38:34.000000000 +0200
  797. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-pinfunc.h 2014-09-11 18:05:52.634000535 +0200
  798. @@ -755,6 +755,7 @@
  799. #define MX6QDL_PAD_GPIO_5__I2C3_SCL 0x230 0x600 0x878 0x6 0x2
  800. #define MX6QDL_PAD_GPIO_5__ARM_EVENTI 0x230 0x600 0x000 0x7 0x0
  801. #define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK 0x234 0x604 0x840 0x0 0x1
  802. +#define MX6QDL_PAD_GPIO_6__ENET_IRQ 0x234 0x604 0x03c 0x11 0xff000609
  803. #define MX6QDL_PAD_GPIO_6__I2C3_SDA 0x234 0x604 0x87c 0x2 0x2
  804. #define MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x234 0x604 0x000 0x5 0x0
  805. #define MX6QDL_PAD_GPIO_6__SD2_LCTL 0x234 0x604 0x000 0x6 0x0
  806. @@ -950,6 +951,7 @@
  807. #define MX6QDL_PAD_RGMII_TXC__GPIO6_IO19 0x2d8 0x6c0 0x000 0x5 0x0
  808. #define MX6QDL_PAD_RGMII_TXC__XTALOSC_REF_CLK_24M 0x2d8 0x6c0 0x000 0x7 0x0
  809. #define MX6QDL_PAD_SD1_CLK__SD1_CLK 0x2dc 0x6c4 0x928 0x0 0x1
  810. +#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x2dc 0x6c4 0x000 0x2 0x0
  811. #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN 0x2dc 0x6c4 0x000 0x3 0x0
  812. #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x2dc 0x6c4 0x000 0x5 0x0
  813. #define MX6QDL_PAD_SD1_CMD__SD1_CMD 0x2e0 0x6c8 0x000 0x0 0x0
  814. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-sabreauto.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabreauto.dts
  815. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-sabreauto.dts 2014-08-14 03:38:34.000000000 +0200
  816. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabreauto.dts 2014-09-11 18:05:52.634000535 +0200
  817. @@ -15,3 +15,16 @@
  818. model = "Freescale i.MX6 DualLite/Solo SABRE Automotive Board";
  819. compatible = "fsl,imx6dl-sabreauto", "fsl,imx6dl";
  820. };
  821. +
  822. +&ldb {
  823. + ipu_id = <0>;
  824. + sec_ipu_id = <0>;
  825. +};
  826. +
  827. +&mxcfb1 {
  828. + status = "okay";
  829. +};
  830. +
  831. +&mxcfb2 {
  832. + status = "okay";
  833. +};
  834. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-sabrelite.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabrelite.dts
  835. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-sabrelite.dts 1970-01-01 01:00:00.000000000 +0100
  836. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabrelite.dts 2014-09-11 18:05:52.634000535 +0200
  837. @@ -0,0 +1,20 @@
  838. +/*
  839. + * Copyright 2011 Freescale Semiconductor, Inc.
  840. + * Copyright 2011 Linaro Ltd.
  841. + *
  842. + * The code contained herein is licensed under the GNU General Public
  843. + * License. You may obtain a copy of the GNU General Public License
  844. + * Version 2 or later at the following locations:
  845. + *
  846. + * http://www.opensource.org/licenses/gpl-license.html
  847. + * http://www.gnu.org/copyleft/gpl.html
  848. + */
  849. +
  850. +/dts-v1/;
  851. +#include "imx6dl.dtsi"
  852. +#include "imx6qdl-sabrelite.dtsi"
  853. +
  854. +/ {
  855. + model = "Freescale i.MX6 DualLite SABRE Lite Board";
  856. + compatible = "fsl,imx6dl-sabrelite", "fsl,imx6dl";
  857. +};
  858. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-sabresd.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd.dts
  859. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-sabresd.dts 2014-08-14 03:38:34.000000000 +0200
  860. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd.dts 2014-09-11 18:05:52.634000535 +0200
  861. @@ -15,3 +15,20 @@
  862. model = "Freescale i.MX6 DualLite SABRE Smart Device Board";
  863. compatible = "fsl,imx6dl-sabresd", "fsl,imx6dl";
  864. };
  865. +
  866. +&ldb {
  867. + ipu_id = <0>;
  868. + sec_ipu_id = <0>;
  869. +};
  870. +
  871. +&pxp {
  872. + status = "okay";
  873. +};
  874. +
  875. +&mxcfb1 {
  876. + status = "okay";
  877. +};
  878. +
  879. +&mxcfb2 {
  880. + status = "okay";
  881. +};
  882. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts
  883. --- linux-3.14.17/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts 1970-01-01 01:00:00.000000000 +0100
  884. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6dl-sabresd-hdcp.dts 2014-09-11 18:05:52.634000535 +0200
  885. @@ -0,0 +1,19 @@
  886. +/*
  887. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  888. + *
  889. + * This program is free software; you can redistribute it and/or modify
  890. + * it under the terms of the GNU General Public License version 2 as
  891. + * published by the Free Software Foundation.
  892. + */
  893. +
  894. +#include "imx6dl-sabresd.dts"
  895. +
  896. +&hdmi_video {
  897. + pinctrl-names = "default";
  898. + pinctrl-0 = <&pinctrl_hdmi_hdcp>;
  899. + fsl,hdcp;
  900. +};
  901. +
  902. +&i2c2 {
  903. + status = "disable";
  904. +};
  905. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-arm2.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2.dts
  906. --- linux-3.14.17/arch/arm/boot/dts/imx6q-arm2.dts 2014-08-14 03:38:34.000000000 +0200
  907. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2.dts 2014-09-11 18:05:52.634000535 +0200
  908. @@ -23,14 +23,27 @@
  909. regulators {
  910. compatible = "simple-bus";
  911. + #address-cells = <1>;
  912. + #size-cells = <0>;
  913. - reg_3p3v: 3p3v {
  914. + reg_3p3v: regulator@0 {
  915. compatible = "regulator-fixed";
  916. + reg = <0>;
  917. regulator-name = "3P3V";
  918. regulator-min-microvolt = <3300000>;
  919. regulator-max-microvolt = <3300000>;
  920. regulator-always-on;
  921. };
  922. +
  923. + reg_usb_otg_vbus: regulator@1 {
  924. + compatible = "regulator-fixed";
  925. + reg = <1>;
  926. + regulator-name = "usb_otg_vbus";
  927. + regulator-min-microvolt = <5000000>;
  928. + regulator-max-microvolt = <5000000>;
  929. + gpio = <&gpio3 22 0>;
  930. + enable-active-high;
  931. + };
  932. };
  933. leds {
  934. @@ -46,7 +59,7 @@
  935. &gpmi {
  936. pinctrl-names = "default";
  937. - pinctrl-0 = <&pinctrl_gpmi_nand_1>;
  938. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  939. status = "disabled"; /* gpmi nand conflicts with SD */
  940. };
  941. @@ -54,28 +67,131 @@
  942. pinctrl-names = "default";
  943. pinctrl-0 = <&pinctrl_hog>;
  944. - hog {
  945. + imx6q-arm2 {
  946. pinctrl_hog: hoggrp {
  947. fsl,pins = <
  948. MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x80000000
  949. >;
  950. };
  951. - };
  952. - arm2 {
  953. - pinctrl_usdhc3_arm2: usdhc3grp-arm2 {
  954. + pinctrl_enet: enetgrp {
  955. + fsl,pins = <
  956. + MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  957. + MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  958. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  959. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  960. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  961. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  962. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  963. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  964. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  965. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  966. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  967. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  968. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  969. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  970. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  971. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  972. + >;
  973. + };
  974. +
  975. + pinctrl_gpmi_nand: gpminandgrp {
  976. + fsl,pins = <
  977. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  978. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  979. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  980. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  981. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  982. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  983. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  984. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  985. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  986. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  987. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  988. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  989. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  990. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  991. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  992. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  993. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  994. + >;
  995. + };
  996. +
  997. + pinctrl_uart2: uart2grp {
  998. + fsl,pins = <
  999. + MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1
  1000. + MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1
  1001. + MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
  1002. + MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
  1003. + >;
  1004. + };
  1005. +
  1006. + pinctrl_uart4: uart4grp {
  1007. + fsl,pins = <
  1008. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  1009. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  1010. + >;
  1011. + };
  1012. +
  1013. + pinctrl_usbotg: usbotggrp {
  1014. + fsl,pins = <
  1015. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  1016. + >;
  1017. + };
  1018. +
  1019. + pinctrl_usdhc3: usdhc3grp {
  1020. + fsl,pins = <
  1021. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  1022. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  1023. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  1024. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  1025. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  1026. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  1027. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  1028. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  1029. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  1030. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  1031. + >;
  1032. + };
  1033. +
  1034. + pinctrl_usdhc3_cdwp: usdhc3cdwp {
  1035. fsl,pins = <
  1036. MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
  1037. MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
  1038. >;
  1039. };
  1040. +
  1041. + pinctrl_usdhc4: usdhc4grp {
  1042. + fsl,pins = <
  1043. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  1044. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  1045. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  1046. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  1047. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  1048. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  1049. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  1050. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  1051. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  1052. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  1053. + >;
  1054. + };
  1055. };
  1056. };
  1057. &fec {
  1058. pinctrl-names = "default";
  1059. - pinctrl-0 = <&pinctrl_enet_2>;
  1060. + pinctrl-0 = <&pinctrl_enet>;
  1061. phy-mode = "rgmii";
  1062. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  1063. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  1064. + status = "okay";
  1065. +};
  1066. +
  1067. +&usbotg {
  1068. + vbus-supply = <&reg_usb_otg_vbus>;
  1069. + pinctrl-names = "default";
  1070. + pinctrl-0 = <&pinctrl_usbotg>;
  1071. + disable-over-current;
  1072. status = "okay";
  1073. };
  1074. @@ -84,8 +200,8 @@
  1075. wp-gpios = <&gpio6 14 0>;
  1076. vmmc-supply = <&reg_3p3v>;
  1077. pinctrl-names = "default";
  1078. - pinctrl-0 = <&pinctrl_usdhc3_1
  1079. - &pinctrl_usdhc3_arm2>;
  1080. + pinctrl-0 = <&pinctrl_usdhc3
  1081. + &pinctrl_usdhc3_cdwp>;
  1082. status = "okay";
  1083. };
  1084. @@ -93,13 +209,13 @@
  1085. non-removable;
  1086. vmmc-supply = <&reg_3p3v>;
  1087. pinctrl-names = "default";
  1088. - pinctrl-0 = <&pinctrl_usdhc4_1>;
  1089. + pinctrl-0 = <&pinctrl_usdhc4>;
  1090. status = "okay";
  1091. };
  1092. &uart2 {
  1093. pinctrl-names = "default";
  1094. - pinctrl-0 = <&pinctrl_uart2_2>;
  1095. + pinctrl-0 = <&pinctrl_uart2>;
  1096. fsl,dte-mode;
  1097. fsl,uart-has-rtscts;
  1098. status = "okay";
  1099. @@ -107,6 +223,6 @@
  1100. &uart4 {
  1101. pinctrl-names = "default";
  1102. - pinctrl-0 = <&pinctrl_uart4_1>;
  1103. + pinctrl-0 = <&pinctrl_uart4>;
  1104. status = "okay";
  1105. };
  1106. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-arm2-hsic.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2-hsic.dts
  1107. --- linux-3.14.17/arch/arm/boot/dts/imx6q-arm2-hsic.dts 1970-01-01 01:00:00.000000000 +0100
  1108. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-arm2-hsic.dts 2014-09-11 18:05:52.634000535 +0200
  1109. @@ -0,0 +1,32 @@
  1110. +/*
  1111. + * Copyright 2013 Freescale Semiconductor, Inc.
  1112. + *
  1113. + * The code contained herein is licensed under the GNU General Public
  1114. + * License. You may obtain a copy of the GNU General Public License
  1115. + * Version 2 or later at the following locations:
  1116. + *
  1117. + * http://www.opensource.org/licenses/gpl-license.html
  1118. + * http://www.gnu.org/copyleft/gpl.html
  1119. + */
  1120. +
  1121. +#include "imx6q-arm2.dts"
  1122. +
  1123. +&fec {
  1124. + status = "disabled";
  1125. +};
  1126. +
  1127. +&usbh2 {
  1128. + pinctrl-names = "idle", "active";
  1129. + pinctrl-0 = <&pinctrl_usbh2_1>;
  1130. + pinctrl-1 = <&pinctrl_usbh2_2>;
  1131. + osc-clkgate-delay = <0x3>;
  1132. + status = "okay";
  1133. +};
  1134. +
  1135. +&usbh3 {
  1136. + pinctrl-names = "idle", "active";
  1137. + pinctrl-0 = <&pinctrl_usbh3_1>;
  1138. + pinctrl-1 = <&pinctrl_usbh3_2>;
  1139. + osc-clkgate-delay = <0x3>;
  1140. + status = "okay";
  1141. +};
  1142. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-cm-fx6.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-cm-fx6.dts
  1143. --- linux-3.14.17/arch/arm/boot/dts/imx6q-cm-fx6.dts 1970-01-01 01:00:00.000000000 +0100
  1144. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-cm-fx6.dts 2014-09-11 18:05:52.634000535 +0200
  1145. @@ -0,0 +1,107 @@
  1146. +/*
  1147. + * Copyright 2013 CompuLab Ltd.
  1148. + *
  1149. + * Author: Valentin Raevsky <valentin@compulab.co.il>
  1150. + *
  1151. + * The code contained herein is licensed under the GNU General Public
  1152. + * License. You may obtain a copy of the GNU General Public License
  1153. + * Version 2 or later at the following locations:
  1154. + *
  1155. + * http://www.opensource.org/licenses/gpl-license.html
  1156. + * http://www.gnu.org/copyleft/gpl.html
  1157. + */
  1158. +
  1159. +/dts-v1/;
  1160. +#include "imx6q.dtsi"
  1161. +
  1162. +/ {
  1163. + model = "CompuLab CM-FX6";
  1164. + compatible = "compulab,cm-fx6", "fsl,imx6q";
  1165. +
  1166. + memory {
  1167. + reg = <0x10000000 0x80000000>;
  1168. + };
  1169. +
  1170. + leds {
  1171. + compatible = "gpio-leds";
  1172. +
  1173. + heartbeat-led {
  1174. + label = "Heartbeat";
  1175. + gpios = <&gpio2 31 0>;
  1176. + linux,default-trigger = "heartbeat";
  1177. + };
  1178. + };
  1179. +};
  1180. +
  1181. +&fec {
  1182. + pinctrl-names = "default";
  1183. + pinctrl-0 = <&pinctrl_enet>;
  1184. + phy-mode = "rgmii";
  1185. + status = "okay";
  1186. +};
  1187. +
  1188. +&gpmi {
  1189. + pinctrl-names = "default";
  1190. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  1191. + status = "okay";
  1192. +};
  1193. +
  1194. +&iomuxc {
  1195. + imx6q-cm-fx6 {
  1196. + pinctrl_enet: enetgrp {
  1197. + fsl,pins = <
  1198. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  1199. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  1200. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  1201. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  1202. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  1203. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  1204. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  1205. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  1206. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  1207. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  1208. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  1209. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  1210. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  1211. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  1212. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  1213. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  1214. + >;
  1215. + };
  1216. +
  1217. + pinctrl_gpmi_nand: gpminandgrp {
  1218. + fsl,pins = <
  1219. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  1220. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  1221. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  1222. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  1223. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  1224. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  1225. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  1226. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  1227. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  1228. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  1229. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  1230. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  1231. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  1232. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  1233. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  1234. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  1235. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  1236. + >;
  1237. + };
  1238. +
  1239. + pinctrl_uart4: uart4grp {
  1240. + fsl,pins = <
  1241. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  1242. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  1243. + >;
  1244. + };
  1245. + };
  1246. +};
  1247. +
  1248. +&uart4 {
  1249. + pinctrl-names = "default";
  1250. + pinctrl-0 = <&pinctrl_uart4>;
  1251. + status = "okay";
  1252. +};
  1253. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-cubox-i.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-cubox-i.dts
  1254. --- linux-3.14.17/arch/arm/boot/dts/imx6q-cubox-i.dts 2014-08-14 03:38:34.000000000 +0200
  1255. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-cubox-i.dts 2014-09-11 18:05:52.634000535 +0200
  1256. @@ -13,4 +13,8 @@
  1257. &sata {
  1258. status = "okay";
  1259. + fsl,transmit-level-mV = <1104>;
  1260. + fsl,transmit-boost-mdB = <0>;
  1261. + fsl,transmit-atten-16ths = <9>;
  1262. + fsl,no-spread-spectrum;
  1263. };
  1264. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
  1265. --- linux-3.14.17/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts 1970-01-01 01:00:00.000000000 +0100
  1266. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts 2014-09-11 18:05:52.634000535 +0200
  1267. @@ -0,0 +1,23 @@
  1268. +/*
  1269. + * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.de>
  1270. + *
  1271. + * The code contained herein is licensed under the GNU General Public
  1272. + * License. You may obtain a copy of the GNU General Public License
  1273. + * Version 2 or later at the following locations:
  1274. + *
  1275. + * http://www.opensource.org/licenses/gpl-license.html
  1276. + * http://www.gnu.org/copyleft/gpl.html
  1277. + */
  1278. +
  1279. +#ifndef __DTS_V1__
  1280. +#define __DTS_V1__
  1281. +/dts-v1/;
  1282. +#endif
  1283. +
  1284. +#include "imx6q.dtsi"
  1285. +#include "imx6qdl-dfi-fs700-m60.dtsi"
  1286. +
  1287. +/ {
  1288. + model = "DFI FS700-M60-6QD i.MX6qd Q7 Board";
  1289. + compatible = "dfi,fs700-m60-6qd", "dfi,fs700e-m60", "fsl,imx6q";
  1290. +};
  1291. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi
  1292. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-08-14 03:38:34.000000000 +0200
  1293. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi 2014-09-11 18:05:52.642000568 +0200
  1294. @@ -5,11 +5,33 @@
  1295. #include "imx6qdl-microsom-ar8035.dtsi"
  1296. / {
  1297. + chosen {
  1298. + bootargs = "quiet console=ttymxc0,115200 root=/dev/mmcblk0p2 rw";
  1299. + };
  1300. +
  1301. + aliases {
  1302. + mxcfb0 = &mxcfb1;
  1303. + };
  1304. +
  1305. ir_recv: ir-receiver {
  1306. compatible = "gpio-ir-receiver";
  1307. gpios = <&gpio3 9 1>;
  1308. pinctrl-names = "default";
  1309. pinctrl-0 = <&pinctrl_cubox_i_ir>;
  1310. + linux,rc-map-name = "rc-rc6-mce";
  1311. + };
  1312. +
  1313. + pwmleds {
  1314. + compatible = "pwm-leds";
  1315. + pinctrl-names = "default";
  1316. + pinctrl-0 = <&pinctrl_cubox_i_pwm1>;
  1317. +
  1318. + front {
  1319. + active-low;
  1320. + label = "imx6:red:front";
  1321. + max-brightness = <248>;
  1322. + pwms = <&pwm1 0 50000>;
  1323. + };
  1324. };
  1325. regulators {
  1326. @@ -49,10 +71,62 @@
  1327. sound-spdif {
  1328. compatible = "fsl,imx-audio-spdif";
  1329. model = "imx-spdif";
  1330. - /* IMX6 doesn't implement this yet */
  1331. spdif-controller = <&spdif>;
  1332. spdif-out;
  1333. };
  1334. +
  1335. + sound-hdmi {
  1336. + compatible = "fsl,imx6q-audio-hdmi",
  1337. + "fsl,imx-audio-hdmi";
  1338. + model = "imx-audio-hdmi";
  1339. + hdmi-controller = <&hdmi_audio>;
  1340. + };
  1341. +
  1342. + mxcfb1: fb@0 {
  1343. + compatible = "fsl,mxc_sdc_fb";
  1344. + disp_dev = "hdmi";
  1345. + interface_pix_fmt = "RGB24";
  1346. + mode_str ="1920x1080M@60";
  1347. + default_bpp = <32>;
  1348. + int_clk = <0>;
  1349. + late_init = <0>;
  1350. + status = "okay";
  1351. + };
  1352. +};
  1353. +
  1354. +&hdmi_core {
  1355. + ipu_id = <0>;
  1356. + disp_id = <0>;
  1357. + status = "okay";
  1358. +};
  1359. +
  1360. +&hdmi_video {
  1361. + fsl,phy_reg_vlev = <0x0294>;
  1362. + fsl,phy_reg_cksymtx = <0x800d>;
  1363. + status = "okay";
  1364. +};
  1365. +
  1366. +&hdmi_audio {
  1367. + status = "okay";
  1368. +};
  1369. +
  1370. +&hdmi_cec {
  1371. + pinctrl-names = "default";
  1372. + pinctrl-0 = <&pinctrl_cubox_i_hdmi>;
  1373. + status = "okay";
  1374. +};
  1375. +
  1376. +&i2c2 {
  1377. + clock-frequency = <100000>;
  1378. + pinctrl-names = "default";
  1379. + pinctrl-0 = <&pinctrl_cubox_i_i2c2>;
  1380. +
  1381. + status = "okay";
  1382. +
  1383. + ddc: imx6_hdmi_i2c@50 {
  1384. + compatible = "fsl,imx6-hdmi-i2c";
  1385. + reg = <0x50>;
  1386. + };
  1387. };
  1388. &i2c3 {
  1389. @@ -69,6 +143,19 @@
  1390. &iomuxc {
  1391. cubox_i {
  1392. + pinctrl_cubox_i_hdmi: cubox-i-hdmi {
  1393. + fsl,pins = <
  1394. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  1395. + >;
  1396. + };
  1397. +
  1398. + pinctrl_cubox_i_i2c2: cubox-i-i2c2 {
  1399. + fsl,pins = <
  1400. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  1401. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  1402. + >;
  1403. + };
  1404. +
  1405. pinctrl_cubox_i_i2c3: cubox-i-i2c3 {
  1406. fsl,pins = <
  1407. MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  1408. @@ -82,16 +169,35 @@
  1409. >;
  1410. };
  1411. + pinctrl_cubox_i_pwm1: cubox-i-pwm1-front-led {
  1412. + fsl,pins = <MX6QDL_PAD_DISP0_DAT8__PWM1_OUT 0x1b0b0>;
  1413. + };
  1414. +
  1415. pinctrl_cubox_i_spdif: cubox-i-spdif {
  1416. fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  1417. };
  1418. + pinctrl_cubox_i_usbh1: cubox-i-usbh1 {
  1419. + fsl,pins = <MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0>;
  1420. + };
  1421. +
  1422. pinctrl_cubox_i_usbh1_vbus: cubox-i-usbh1-vbus {
  1423. - fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x4001b0b0>;
  1424. + fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  1425. + };
  1426. +
  1427. + pinctrl_cubox_i_usbotg: cubox-i-usbotg {
  1428. + /*
  1429. + * The Cubox-i pulls ID low, but as it's pointless
  1430. + * leaving it as a pull-up, even if it is just 10uA.
  1431. + */
  1432. + fsl,pins = <
  1433. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059
  1434. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  1435. + >;
  1436. };
  1437. pinctrl_cubox_i_usbotg_vbus: cubox-i-usbotg-vbus {
  1438. - fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x4001b0b0>;
  1439. + fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  1440. };
  1441. pinctrl_cubox_i_usdhc2_aux: cubox-i-usdhc2-aux {
  1442. @@ -111,29 +217,76 @@
  1443. MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  1444. >;
  1445. };
  1446. +
  1447. + pinctrl_cubox_i_usdhc2_100mhz: cubox-i-usdhc2-100mhz {
  1448. + fsl,pins = <
  1449. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170b9
  1450. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100b9
  1451. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  1452. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  1453. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  1454. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130b9
  1455. + >;
  1456. + };
  1457. +
  1458. + pinctrl_cubox_i_usdhc2_200mhz: cubox-i-usdhc2-200mhz {
  1459. + fsl,pins = <
  1460. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x170f9
  1461. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x100f9
  1462. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  1463. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  1464. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  1465. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x130f9
  1466. + >;
  1467. + };
  1468. };
  1469. };
  1470. &spdif {
  1471. pinctrl-names = "default";
  1472. pinctrl-0 = <&pinctrl_cubox_i_spdif>;
  1473. + clocks = <&clks 197>, <&clks 0>,
  1474. + <&clks 197>, <&clks 0>,
  1475. + <&clks 0>, <&clks 0>,
  1476. + <&clks 0>, <&clks 0>,
  1477. + <&clks 0>;
  1478. + clock-names = "core", "rxtx0",
  1479. + "rxtx1", "rxtx2",
  1480. + "rxtx3", "rxtx4",
  1481. + "rxtx5", "rxtx6",
  1482. + "rxtx7";
  1483. status = "okay";
  1484. };
  1485. &usbh1 {
  1486. + pinctrl-names = "default";
  1487. + pinctrl-0 = <&pinctrl_cubox_i_usbh1>;
  1488. vbus-supply = <&reg_usbh1_vbus>;
  1489. status = "okay";
  1490. };
  1491. &usbotg {
  1492. + pinctrl-names = "default";
  1493. + pinctrl-0 = <&pinctrl_cubox_i_usbotg>;
  1494. vbus-supply = <&reg_usbotg_vbus>;
  1495. status = "okay";
  1496. };
  1497. &usdhc2 {
  1498. - pinctrl-names = "default";
  1499. + pinctrl-names = "default", "state_100mhz", "state_200mhz";
  1500. pinctrl-0 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2>;
  1501. + pinctrl-1 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_100mhz>;
  1502. + pinctrl-2 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2_200mhz>;
  1503. vmmc-supply = <&reg_3p3v>;
  1504. cd-gpios = <&gpio1 4 0>;
  1505. + no-1-8-v;
  1506. status = "okay";
  1507. };
  1508. +
  1509. +
  1510. +&gpc {
  1511. + fsl,cpu_pupscr_sw2iso = <0xf>;
  1512. + fsl,cpu_pupscr_sw = <0xf>;
  1513. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  1514. + fsl,cpu_pdnscr_iso = <0x1>;
  1515. +};
  1516. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
  1517. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi 1970-01-01 01:00:00.000000000 +0100
  1518. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi 2014-09-11 18:05:52.642000568 +0200
  1519. @@ -0,0 +1,199 @@
  1520. +/ {
  1521. + regulators {
  1522. + compatible = "simple-bus";
  1523. + #address-cells = <1>;
  1524. + #size-cells = <0>;
  1525. +
  1526. + dummy_reg: regulator@0 {
  1527. + compatible = "regulator-fixed";
  1528. + reg = <0>;
  1529. + regulator-name = "dummy-supply";
  1530. + };
  1531. +
  1532. + reg_usb_otg_vbus: regulator@1 {
  1533. + compatible = "regulator-fixed";
  1534. + reg = <1>;
  1535. + regulator-name = "usb_otg_vbus";
  1536. + regulator-min-microvolt = <5000000>;
  1537. + regulator-max-microvolt = <5000000>;
  1538. + gpio = <&gpio3 22 0>;
  1539. + enable-active-high;
  1540. + };
  1541. + };
  1542. +
  1543. + chosen {
  1544. + stdout-path = &uart1;
  1545. + };
  1546. +};
  1547. +
  1548. +&ecspi3 {
  1549. + fsl,spi-num-chipselects = <1>;
  1550. + cs-gpios = <&gpio4 24 0>;
  1551. + pinctrl-names = "default";
  1552. + pinctrl-0 = <&pinctrl_ecspi3>;
  1553. + status = "okay";
  1554. +
  1555. + flash: m25p80@0 {
  1556. + #address-cells = <1>;
  1557. + #size-cells = <1>;
  1558. + compatible = "sst,sst25vf040b", "m25p80";
  1559. + spi-max-frequency = <20000000>;
  1560. + reg = <0>;
  1561. + };
  1562. +};
  1563. +
  1564. +&fec {
  1565. + pinctrl-names = "default";
  1566. + pinctrl-0 = <&pinctrl_enet>;
  1567. + status = "okay";
  1568. + phy-mode = "rgmii";
  1569. +};
  1570. +
  1571. +&iomuxc {
  1572. + pinctrl-names = "default";
  1573. + pinctrl-0 = <&pinctrl_hog>;
  1574. +
  1575. + imx6qdl-dfi-fs700-m60 {
  1576. + pinctrl_hog: hoggrp {
  1577. + fsl,pins = <
  1578. + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
  1579. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x80000000 /* PMIC irq */
  1580. + MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000 /* MAX11801 irq */
  1581. + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000030b0 /* Backlight enable */
  1582. + >;
  1583. + };
  1584. +
  1585. + pinctrl_enet: enetgrp {
  1586. + fsl,pins = <
  1587. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  1588. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  1589. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  1590. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  1591. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  1592. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  1593. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  1594. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  1595. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  1596. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  1597. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  1598. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  1599. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  1600. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  1601. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  1602. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  1603. + >;
  1604. + };
  1605. +
  1606. + pinctrl_i2c2: i2c2grp {
  1607. + fsl,pins = <
  1608. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  1609. + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  1610. + >;
  1611. + };
  1612. +
  1613. + pinctrl_uart1: uart1grp {
  1614. + fsl,pins = <
  1615. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  1616. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  1617. + >;
  1618. + };
  1619. +
  1620. + pinctrl_usbotg: usbotggrp {
  1621. + fsl,pins = <
  1622. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  1623. + >;
  1624. + };
  1625. +
  1626. + pinctrl_usdhc2: usdhc2grp {
  1627. + fsl,pins = <
  1628. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  1629. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  1630. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  1631. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  1632. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  1633. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  1634. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000 /* card detect */
  1635. + >;
  1636. + };
  1637. +
  1638. + pinctrl_usdhc3: usdhc3grp {
  1639. + fsl,pins = <
  1640. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  1641. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  1642. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  1643. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  1644. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  1645. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  1646. + >;
  1647. + };
  1648. +
  1649. + pinctrl_usdhc4: usdhc4grp {
  1650. + fsl,pins = <
  1651. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  1652. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  1653. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  1654. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  1655. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  1656. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  1657. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  1658. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  1659. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  1660. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  1661. + >;
  1662. + };
  1663. +
  1664. + pinctrl_ecspi3: ecspi3grp {
  1665. + fsl,pins = <
  1666. + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  1667. + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  1668. + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  1669. + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  1670. + >;
  1671. + };
  1672. + };
  1673. +};
  1674. +
  1675. +&i2c2 {
  1676. + pinctrl-names = "default";
  1677. + pinctrl-0 = <&pinctrl_i2c2>;
  1678. + status = "okay";
  1679. +};
  1680. +
  1681. +&uart1 {
  1682. + pinctrl-names = "default";
  1683. + pinctrl-0 = <&pinctrl_uart1>;
  1684. + status = "okay";
  1685. +};
  1686. +
  1687. +&usbh1 {
  1688. + status = "okay";
  1689. +};
  1690. +
  1691. +&usbotg {
  1692. + vbus-supply = <&reg_usb_otg_vbus>;
  1693. + pinctrl-names = "default";
  1694. + pinctrl-0 = <&pinctrl_usbotg>;
  1695. + disable-over-current;
  1696. + dr_mode = "host";
  1697. + status = "okay";
  1698. +};
  1699. +
  1700. +&usdhc2 { /* module slot */
  1701. + pinctrl-names = "default";
  1702. + pinctrl-0 = <&pinctrl_usdhc2>;
  1703. + cd-gpios = <&gpio2 2 0>;
  1704. + status = "okay";
  1705. +};
  1706. +
  1707. +&usdhc3 { /* baseboard slot */
  1708. + pinctrl-names = "default";
  1709. + pinctrl-0 = <&pinctrl_usdhc3>;
  1710. +};
  1711. +
  1712. +&usdhc4 { /* eMMC */
  1713. + pinctrl-names = "default";
  1714. + pinctrl-0 = <&pinctrl_usdhc4>;
  1715. + bus-width = <8>;
  1716. + non-removable;
  1717. + status = "okay";
  1718. +};
  1719. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl.dtsi
  1720. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl.dtsi 2014-08-14 03:38:34.000000000 +0200
  1721. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl.dtsi 2014-09-11 18:05:52.646000583 +0200
  1722. @@ -10,10 +10,16 @@
  1723. * http://www.gnu.org/copyleft/gpl.html
  1724. */
  1725. +#include <dt-bindings/interrupt-controller/arm-gic.h>
  1726. +
  1727. #include "skeleton.dtsi"
  1728. +#include <dt-bindings/gpio/gpio.h>
  1729. / {
  1730. aliases {
  1731. + ethernet0 = &fec;
  1732. + can0 = &can1;
  1733. + can1 = &can2;
  1734. gpio0 = &gpio1;
  1735. gpio1 = &gpio2;
  1736. gpio2 = &gpio3;
  1737. @@ -24,6 +30,11 @@
  1738. i2c0 = &i2c1;
  1739. i2c1 = &i2c2;
  1740. i2c2 = &i2c3;
  1741. + ipu0 = &ipu1;
  1742. + mmc0 = &usdhc1;
  1743. + mmc1 = &usdhc2;
  1744. + mmc2 = &usdhc3;
  1745. + mmc3 = &usdhc4;
  1746. serial0 = &uart1;
  1747. serial1 = &uart2;
  1748. serial2 = &uart3;
  1749. @@ -33,13 +44,13 @@
  1750. spi1 = &ecspi2;
  1751. spi2 = &ecspi3;
  1752. spi3 = &ecspi4;
  1753. + usbphy0 = &usbphy1;
  1754. + usbphy1 = &usbphy2;
  1755. };
  1756. intc: interrupt-controller@00a01000 {
  1757. compatible = "arm,cortex-a9-gic";
  1758. #interrupt-cells = <3>;
  1759. - #address-cells = <1>;
  1760. - #size-cells = <1>;
  1761. interrupt-controller;
  1762. reg = <0x00a01000 0x1000>,
  1763. <0x00a00100 0x100>;
  1764. @@ -51,20 +62,27 @@
  1765. ckil {
  1766. compatible = "fsl,imx-ckil", "fixed-clock";
  1767. + #clock-cells = <0>;
  1768. clock-frequency = <32768>;
  1769. };
  1770. ckih1 {
  1771. compatible = "fsl,imx-ckih1", "fixed-clock";
  1772. + #clock-cells = <0>;
  1773. clock-frequency = <0>;
  1774. };
  1775. osc {
  1776. compatible = "fsl,imx-osc", "fixed-clock";
  1777. + #clock-cells = <0>;
  1778. clock-frequency = <24000000>;
  1779. };
  1780. };
  1781. + pu_dummy: pudummy_reg {
  1782. + compatible = "fsl,imx6-dummy-pureg"; /* only used in ldo-bypass */
  1783. + };
  1784. +
  1785. soc {
  1786. #address-cells = <1>;
  1787. #size-cells = <1>;
  1788. @@ -75,7 +93,10 @@
  1789. dma_apbh: dma-apbh@00110000 {
  1790. compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
  1791. reg = <0x00110000 0x2000>;
  1792. - interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
  1793. + interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1794. + <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1795. + <0 13 IRQ_TYPE_LEVEL_HIGH>,
  1796. + <0 13 IRQ_TYPE_LEVEL_HIGH>;
  1797. interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
  1798. #dma-cells = <1>;
  1799. dma-channels = <4>;
  1800. @@ -88,7 +109,7 @@
  1801. #size-cells = <1>;
  1802. reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
  1803. reg-names = "gpmi-nand", "bch";
  1804. - interrupts = <0 15 0x04>;
  1805. + interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
  1806. interrupt-names = "bch";
  1807. clocks = <&clks 152>, <&clks 153>, <&clks 151>,
  1808. <&clks 150>, <&clks 149>;
  1809. @@ -109,11 +130,13 @@
  1810. L2: l2-cache@00a02000 {
  1811. compatible = "arm,pl310-cache";
  1812. reg = <0x00a02000 0x1000>;
  1813. - interrupts = <0 92 0x04>;
  1814. + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
  1815. cache-unified;
  1816. cache-level = <2>;
  1817. arm,tag-latency = <4 2 3>;
  1818. arm,data-latency = <4 2 3>;
  1819. + arm,dynamic-clk-gating;
  1820. + arm,standby-mode;
  1821. };
  1822. pcie: pcie@0x01000000 {
  1823. @@ -126,15 +149,22 @@
  1824. 0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */
  1825. 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
  1826. num-lanes = <1>;
  1827. - interrupts = <0 123 0x04>;
  1828. - clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
  1829. - clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
  1830. + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
  1831. + interrupt-names = "pme";
  1832. + #interrupt-cells = <1>;
  1833. + interrupt-map-mask = <0 0 0 0x7>;
  1834. + interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
  1835. + <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
  1836. + <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
  1837. + <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
  1838. + clocks = <&clks 144>, <&clks 221>, <&clks 189>, <&clks 187>;
  1839. + clock-names = "pcie_axi", "lvds_gate", "pcie_ref_125m", "sata_ref_100m";
  1840. status = "disabled";
  1841. };
  1842. pmu {
  1843. compatible = "arm,cortex-a9-pmu";
  1844. - interrupts = <0 94 0x04>;
  1845. + interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
  1846. };
  1847. aips-bus@02000000 { /* AIPS1 */
  1848. @@ -154,7 +184,7 @@
  1849. spdif: spdif@02004000 {
  1850. compatible = "fsl,imx35-spdif";
  1851. reg = <0x02004000 0x4000>;
  1852. - interrupts = <0 52 0x04>;
  1853. + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
  1854. dmas = <&sdma 14 18 0>,
  1855. <&sdma 15 18 0>;
  1856. dma-names = "rx", "tx";
  1857. @@ -176,9 +206,11 @@
  1858. #size-cells = <0>;
  1859. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1860. reg = <0x02008000 0x4000>;
  1861. - interrupts = <0 31 0x04>;
  1862. + interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
  1863. clocks = <&clks 112>, <&clks 112>;
  1864. clock-names = "ipg", "per";
  1865. + dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
  1866. + dma-names = "rx", "tx";
  1867. status = "disabled";
  1868. };
  1869. @@ -187,9 +219,11 @@
  1870. #size-cells = <0>;
  1871. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1872. reg = <0x0200c000 0x4000>;
  1873. - interrupts = <0 32 0x04>;
  1874. + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
  1875. clocks = <&clks 113>, <&clks 113>;
  1876. clock-names = "ipg", "per";
  1877. + dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
  1878. + dma-names = "rx", "tx";
  1879. status = "disabled";
  1880. };
  1881. @@ -198,9 +232,11 @@
  1882. #size-cells = <0>;
  1883. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1884. reg = <0x02010000 0x4000>;
  1885. - interrupts = <0 33 0x04>;
  1886. + interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
  1887. clocks = <&clks 114>, <&clks 114>;
  1888. clock-names = "ipg", "per";
  1889. + dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
  1890. + dma-names = "rx", "tx";
  1891. status = "disabled";
  1892. };
  1893. @@ -209,16 +245,18 @@
  1894. #size-cells = <0>;
  1895. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  1896. reg = <0x02014000 0x4000>;
  1897. - interrupts = <0 34 0x04>;
  1898. + interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
  1899. clocks = <&clks 115>, <&clks 115>;
  1900. clock-names = "ipg", "per";
  1901. + dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
  1902. + dma-names = "rx", "tx";
  1903. status = "disabled";
  1904. };
  1905. uart1: serial@02020000 {
  1906. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  1907. reg = <0x02020000 0x4000>;
  1908. - interrupts = <0 26 0x04>;
  1909. + interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
  1910. clocks = <&clks 160>, <&clks 161>;
  1911. clock-names = "ipg", "per";
  1912. dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
  1913. @@ -227,15 +265,23 @@
  1914. };
  1915. esai: esai@02024000 {
  1916. + compatible = "fsl,imx6q-esai";
  1917. reg = <0x02024000 0x4000>;
  1918. - interrupts = <0 51 0x04>;
  1919. + interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
  1920. + clocks = <&clks 118>;
  1921. + fsl,esai-dma-events = <24 23>;
  1922. + fsl,flags = <1>;
  1923. + status = "disabled";
  1924. };
  1925. ssi1: ssi@02028000 {
  1926. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1927. + compatible = "fsl,imx6q-ssi",
  1928. + "fsl,imx51-ssi",
  1929. + "fsl,imx21-ssi";
  1930. reg = <0x02028000 0x4000>;
  1931. - interrupts = <0 46 0x04>;
  1932. - clocks = <&clks 178>;
  1933. + interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
  1934. + clocks = <&clks 178>, <&clks 157>;
  1935. + clock-names = "ipg", "baud";
  1936. dmas = <&sdma 37 1 0>,
  1937. <&sdma 38 1 0>;
  1938. dma-names = "rx", "tx";
  1939. @@ -245,10 +291,13 @@
  1940. };
  1941. ssi2: ssi@0202c000 {
  1942. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1943. + compatible = "fsl,imx6q-ssi",
  1944. + "fsl,imx51-ssi",
  1945. + "fsl,imx21-ssi";
  1946. reg = <0x0202c000 0x4000>;
  1947. - interrupts = <0 47 0x04>;
  1948. - clocks = <&clks 179>;
  1949. + interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
  1950. + clocks = <&clks 179>, <&clks 158>;
  1951. + clock-names = "ipg", "baud";
  1952. dmas = <&sdma 41 1 0>,
  1953. <&sdma 42 1 0>;
  1954. dma-names = "rx", "tx";
  1955. @@ -258,10 +307,13 @@
  1956. };
  1957. ssi3: ssi@02030000 {
  1958. - compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
  1959. + compatible = "fsl,imx6q-ssi",
  1960. + "fsl,imx51-ssi",
  1961. + "fsl,imx21-ssi";
  1962. reg = <0x02030000 0x4000>;
  1963. - interrupts = <0 48 0x04>;
  1964. - clocks = <&clks 180>;
  1965. + interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
  1966. + clocks = <&clks 180>, <&clks 159>;
  1967. + clock-names = "ipg", "baud";
  1968. dmas = <&sdma 45 1 0>,
  1969. <&sdma 46 1 0>;
  1970. dma-names = "rx", "tx";
  1971. @@ -271,8 +323,25 @@
  1972. };
  1973. asrc: asrc@02034000 {
  1974. + compatible = "fsl,imx53-asrc";
  1975. reg = <0x02034000 0x4000>;
  1976. - interrupts = <0 50 0x04>;
  1977. + interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
  1978. + clocks = <&clks 107>, <&clks 156>;
  1979. + clock-names = "core", "dma";
  1980. + dmas = <&sdma 17 20 1>, <&sdma 18 20 1>, <&sdma 19 20 1>,
  1981. + <&sdma 20 20 1>, <&sdma 21 20 1>, <&sdma 22 20 1>;
  1982. + dma-names = "rxa", "rxb", "rxc",
  1983. + "txa", "txb", "txc";
  1984. + status = "okay";
  1985. + };
  1986. +
  1987. + asrc_p2p: asrc_p2p {
  1988. + compatible = "fsl,imx6q-asrc-p2p";
  1989. + fsl,output-rate = <48000>;
  1990. + fsl,output-width = <16>;
  1991. + fsl,asrc-dma-rx-events = <17 18 19>;
  1992. + fsl,asrc-dma-tx-events = <20 21 22>;
  1993. + status = "okay";
  1994. };
  1995. spba@0203c000 {
  1996. @@ -281,8 +350,19 @@
  1997. };
  1998. vpu: vpu@02040000 {
  1999. + compatible = "fsl,imx6-vpu";
  2000. reg = <0x02040000 0x3c000>;
  2001. - interrupts = <0 3 0x04 0 12 0x04>;
  2002. + reg-names = "vpu_regs";
  2003. + interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>,
  2004. + <0 12 IRQ_TYPE_LEVEL_HIGH>;
  2005. + interrupt-names = "vpu_jpu_irq", "vpu_ipi_irq";
  2006. + clocks = <&clks 168>, <&clks 140>, <&clks 142>;
  2007. + clock-names = "vpu_clk", "mmdc_ch0_axi", "ocram";
  2008. + iramsize = <0x21000>;
  2009. + iram = <&ocram>;
  2010. + resets = <&src 1>;
  2011. + pu-supply = <&reg_pu>;
  2012. + status = "disabled";
  2013. };
  2014. aipstz@0207c000 { /* AIPSTZ1 */
  2015. @@ -293,7 +373,7 @@
  2016. #pwm-cells = <2>;
  2017. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2018. reg = <0x02080000 0x4000>;
  2019. - interrupts = <0 83 0x04>;
  2020. + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
  2021. clocks = <&clks 62>, <&clks 145>;
  2022. clock-names = "ipg", "per";
  2023. };
  2024. @@ -302,7 +382,7 @@
  2025. #pwm-cells = <2>;
  2026. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2027. reg = <0x02084000 0x4000>;
  2028. - interrupts = <0 84 0x04>;
  2029. + interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
  2030. clocks = <&clks 62>, <&clks 146>;
  2031. clock-names = "ipg", "per";
  2032. };
  2033. @@ -311,7 +391,7 @@
  2034. #pwm-cells = <2>;
  2035. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2036. reg = <0x02088000 0x4000>;
  2037. - interrupts = <0 85 0x04>;
  2038. + interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
  2039. clocks = <&clks 62>, <&clks 147>;
  2040. clock-names = "ipg", "per";
  2041. };
  2042. @@ -320,7 +400,7 @@
  2043. #pwm-cells = <2>;
  2044. compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
  2045. reg = <0x0208c000 0x4000>;
  2046. - interrupts = <0 86 0x04>;
  2047. + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
  2048. clocks = <&clks 62>, <&clks 148>;
  2049. clock-names = "ipg", "per";
  2050. };
  2051. @@ -328,23 +408,25 @@
  2052. can1: flexcan@02090000 {
  2053. compatible = "fsl,imx6q-flexcan";
  2054. reg = <0x02090000 0x4000>;
  2055. - interrupts = <0 110 0x04>;
  2056. + interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
  2057. clocks = <&clks 108>, <&clks 109>;
  2058. clock-names = "ipg", "per";
  2059. + status = "disabled";
  2060. };
  2061. can2: flexcan@02094000 {
  2062. compatible = "fsl,imx6q-flexcan";
  2063. reg = <0x02094000 0x4000>;
  2064. - interrupts = <0 111 0x04>;
  2065. + interrupts = <0 111 IRQ_TYPE_LEVEL_HIGH>;
  2066. clocks = <&clks 110>, <&clks 111>;
  2067. clock-names = "ipg", "per";
  2068. + status = "disabled";
  2069. };
  2070. gpt: gpt@02098000 {
  2071. compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
  2072. reg = <0x02098000 0x4000>;
  2073. - interrupts = <0 55 0x04>;
  2074. + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
  2075. clocks = <&clks 119>, <&clks 120>;
  2076. clock-names = "ipg", "per";
  2077. };
  2078. @@ -352,7 +434,8 @@
  2079. gpio1: gpio@0209c000 {
  2080. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2081. reg = <0x0209c000 0x4000>;
  2082. - interrupts = <0 66 0x04 0 67 0x04>;
  2083. + interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
  2084. + <0 67 IRQ_TYPE_LEVEL_HIGH>;
  2085. gpio-controller;
  2086. #gpio-cells = <2>;
  2087. interrupt-controller;
  2088. @@ -362,7 +445,8 @@
  2089. gpio2: gpio@020a0000 {
  2090. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2091. reg = <0x020a0000 0x4000>;
  2092. - interrupts = <0 68 0x04 0 69 0x04>;
  2093. + interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
  2094. + <0 69 IRQ_TYPE_LEVEL_HIGH>;
  2095. gpio-controller;
  2096. #gpio-cells = <2>;
  2097. interrupt-controller;
  2098. @@ -372,7 +456,8 @@
  2099. gpio3: gpio@020a4000 {
  2100. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2101. reg = <0x020a4000 0x4000>;
  2102. - interrupts = <0 70 0x04 0 71 0x04>;
  2103. + interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
  2104. + <0 71 IRQ_TYPE_LEVEL_HIGH>;
  2105. gpio-controller;
  2106. #gpio-cells = <2>;
  2107. interrupt-controller;
  2108. @@ -382,7 +467,8 @@
  2109. gpio4: gpio@020a8000 {
  2110. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2111. reg = <0x020a8000 0x4000>;
  2112. - interrupts = <0 72 0x04 0 73 0x04>;
  2113. + interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
  2114. + <0 73 IRQ_TYPE_LEVEL_HIGH>;
  2115. gpio-controller;
  2116. #gpio-cells = <2>;
  2117. interrupt-controller;
  2118. @@ -392,7 +478,8 @@
  2119. gpio5: gpio@020ac000 {
  2120. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2121. reg = <0x020ac000 0x4000>;
  2122. - interrupts = <0 74 0x04 0 75 0x04>;
  2123. + interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
  2124. + <0 75 IRQ_TYPE_LEVEL_HIGH>;
  2125. gpio-controller;
  2126. #gpio-cells = <2>;
  2127. interrupt-controller;
  2128. @@ -402,7 +489,8 @@
  2129. gpio6: gpio@020b0000 {
  2130. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2131. reg = <0x020b0000 0x4000>;
  2132. - interrupts = <0 76 0x04 0 77 0x04>;
  2133. + interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>,
  2134. + <0 77 IRQ_TYPE_LEVEL_HIGH>;
  2135. gpio-controller;
  2136. #gpio-cells = <2>;
  2137. interrupt-controller;
  2138. @@ -412,7 +500,8 @@
  2139. gpio7: gpio@020b4000 {
  2140. compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
  2141. reg = <0x020b4000 0x4000>;
  2142. - interrupts = <0 78 0x04 0 79 0x04>;
  2143. + interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>,
  2144. + <0 79 IRQ_TYPE_LEVEL_HIGH>;
  2145. gpio-controller;
  2146. #gpio-cells = <2>;
  2147. interrupt-controller;
  2148. @@ -421,20 +510,20 @@
  2149. kpp: kpp@020b8000 {
  2150. reg = <0x020b8000 0x4000>;
  2151. - interrupts = <0 82 0x04>;
  2152. + interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
  2153. };
  2154. wdog1: wdog@020bc000 {
  2155. compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
  2156. reg = <0x020bc000 0x4000>;
  2157. - interrupts = <0 80 0x04>;
  2158. + interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
  2159. clocks = <&clks 0>;
  2160. };
  2161. wdog2: wdog@020c0000 {
  2162. compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
  2163. reg = <0x020c0000 0x4000>;
  2164. - interrupts = <0 81 0x04>;
  2165. + interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
  2166. clocks = <&clks 0>;
  2167. status = "disabled";
  2168. };
  2169. @@ -442,14 +531,17 @@
  2170. clks: ccm@020c4000 {
  2171. compatible = "fsl,imx6q-ccm";
  2172. reg = <0x020c4000 0x4000>;
  2173. - interrupts = <0 87 0x04 0 88 0x04>;
  2174. + interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
  2175. + <0 88 IRQ_TYPE_LEVEL_HIGH>;
  2176. #clock-cells = <1>;
  2177. };
  2178. anatop: anatop@020c8000 {
  2179. compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
  2180. reg = <0x020c8000 0x1000>;
  2181. - interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
  2182. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
  2183. + <0 54 IRQ_TYPE_LEVEL_HIGH>,
  2184. + <0 127 IRQ_TYPE_LEVEL_HIGH>;
  2185. regulator-1p1@110 {
  2186. compatible = "fsl,anatop-regulator";
  2187. @@ -495,7 +587,7 @@
  2188. reg_arm: regulator-vddcore@140 {
  2189. compatible = "fsl,anatop-regulator";
  2190. - regulator-name = "cpu";
  2191. + regulator-name = "vddarm";
  2192. regulator-min-microvolt = <725000>;
  2193. regulator-max-microvolt = <1450000>;
  2194. regulator-always-on;
  2195. @@ -515,7 +607,6 @@
  2196. regulator-name = "vddpu";
  2197. regulator-min-microvolt = <725000>;
  2198. regulator-max-microvolt = <1450000>;
  2199. - regulator-always-on;
  2200. anatop-reg-offset = <0x140>;
  2201. anatop-vol-bit-shift = <9>;
  2202. anatop-vol-bit-width = <5>;
  2203. @@ -547,23 +638,38 @@
  2204. tempmon: tempmon {
  2205. compatible = "fsl,imx6q-tempmon";
  2206. - interrupts = <0 49 0x04>;
  2207. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
  2208. fsl,tempmon = <&anatop>;
  2209. fsl,tempmon-data = <&ocotp>;
  2210. + clocks = <&clks 172>;
  2211. };
  2212. usbphy1: usbphy@020c9000 {
  2213. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  2214. reg = <0x020c9000 0x1000>;
  2215. - interrupts = <0 44 0x04>;
  2216. + interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
  2217. clocks = <&clks 182>;
  2218. + fsl,anatop = <&anatop>;
  2219. };
  2220. usbphy2: usbphy@020ca000 {
  2221. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  2222. reg = <0x020ca000 0x1000>;
  2223. - interrupts = <0 45 0x04>;
  2224. + interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
  2225. clocks = <&clks 183>;
  2226. + fsl,anatop = <&anatop>;
  2227. + };
  2228. +
  2229. + usbphy_nop1: usbphy_nop1 {
  2230. + compatible = "usb-nop-xceiv";
  2231. + clocks = <&clks 182>;
  2232. + clock-names = "main_clk";
  2233. + };
  2234. +
  2235. + usbphy_nop2: usbphy_nop2 {
  2236. + compatible = "usb-nop-xceiv";
  2237. + clocks = <&clks 182>;
  2238. + clock-names = "main_clk";
  2239. };
  2240. snvs@020cc000 {
  2241. @@ -575,31 +681,39 @@
  2242. snvs-rtc-lp@34 {
  2243. compatible = "fsl,sec-v4.0-mon-rtc-lp";
  2244. reg = <0x34 0x58>;
  2245. - interrupts = <0 19 0x04 0 20 0x04>;
  2246. + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
  2247. + <0 20 IRQ_TYPE_LEVEL_HIGH>;
  2248. };
  2249. };
  2250. epit1: epit@020d0000 { /* EPIT1 */
  2251. reg = <0x020d0000 0x4000>;
  2252. - interrupts = <0 56 0x04>;
  2253. + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
  2254. };
  2255. epit2: epit@020d4000 { /* EPIT2 */
  2256. reg = <0x020d4000 0x4000>;
  2257. - interrupts = <0 57 0x04>;
  2258. + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
  2259. };
  2260. src: src@020d8000 {
  2261. compatible = "fsl,imx6q-src", "fsl,imx51-src";
  2262. reg = <0x020d8000 0x4000>;
  2263. - interrupts = <0 91 0x04 0 96 0x04>;
  2264. + interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
  2265. + <0 96 IRQ_TYPE_LEVEL_HIGH>;
  2266. #reset-cells = <1>;
  2267. };
  2268. gpc: gpc@020dc000 {
  2269. compatible = "fsl,imx6q-gpc";
  2270. reg = <0x020dc000 0x4000>;
  2271. - interrupts = <0 89 0x04 0 90 0x04>;
  2272. + interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
  2273. + <0 90 IRQ_TYPE_LEVEL_HIGH>;
  2274. + clocks = <&clks 122>, <&clks 74>, <&clks 121>,
  2275. + <&clks 26>, <&clks 143>, <&clks 168>, <&clks 62>;
  2276. + clock-names = "gpu3d_core", "gpu3d_shader", "gpu2d_core",
  2277. + "gpu2d_axi", "openvg_axi", "vpu_axi", "ipg";
  2278. + pu-supply = <&reg_pu>;
  2279. };
  2280. gpr: iomuxc-gpr@020e0000 {
  2281. @@ -610,778 +724,40 @@
  2282. iomuxc: iomuxc@020e0000 {
  2283. compatible = "fsl,imx6dl-iomuxc", "fsl,imx6q-iomuxc";
  2284. reg = <0x020e0000 0x4000>;
  2285. -
  2286. - audmux {
  2287. - pinctrl_audmux_1: audmux-1 {
  2288. - fsl,pins = <
  2289. - MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x80000000
  2290. - MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x80000000
  2291. - MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x80000000
  2292. - MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x80000000
  2293. - >;
  2294. - };
  2295. -
  2296. - pinctrl_audmux_2: audmux-2 {
  2297. - fsl,pins = <
  2298. - MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x80000000
  2299. - MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x80000000
  2300. - MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x80000000
  2301. - MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x80000000
  2302. - >;
  2303. - };
  2304. -
  2305. - pinctrl_audmux_3: audmux-3 {
  2306. - fsl,pins = <
  2307. - MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x80000000
  2308. - MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x80000000
  2309. - MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x80000000
  2310. - >;
  2311. - };
  2312. - };
  2313. -
  2314. - ecspi1 {
  2315. - pinctrl_ecspi1_1: ecspi1grp-1 {
  2316. - fsl,pins = <
  2317. - MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  2318. - MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  2319. - MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  2320. - >;
  2321. - };
  2322. -
  2323. - pinctrl_ecspi1_2: ecspi1grp-2 {
  2324. - fsl,pins = <
  2325. - MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
  2326. - MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
  2327. - MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
  2328. - >;
  2329. - };
  2330. - };
  2331. -
  2332. - ecspi3 {
  2333. - pinctrl_ecspi3_1: ecspi3grp-1 {
  2334. - fsl,pins = <
  2335. - MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  2336. - MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  2337. - MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  2338. - >;
  2339. - };
  2340. - };
  2341. -
  2342. - enet {
  2343. - pinctrl_enet_1: enetgrp-1 {
  2344. - fsl,pins = <
  2345. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  2346. - MX6QDL_PAD_ENET_MDC__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. - MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  2361. - >;
  2362. - };
  2363. -
  2364. - pinctrl_enet_2: enetgrp-2 {
  2365. - fsl,pins = <
  2366. - MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  2367. - MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  2368. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2369. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2370. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2371. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2372. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2373. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2374. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2375. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2376. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2377. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2378. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2379. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2380. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2381. - >;
  2382. - };
  2383. -
  2384. - pinctrl_enet_3: enetgrp-3 {
  2385. - fsl,pins = <
  2386. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  2387. - MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  2388. - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  2389. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  2390. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  2391. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  2392. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  2393. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  2394. - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  2395. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  2396. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  2397. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  2398. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  2399. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  2400. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  2401. - MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
  2402. - >;
  2403. - };
  2404. - };
  2405. -
  2406. - esai {
  2407. - pinctrl_esai_1: esaigrp-1 {
  2408. - fsl,pins = <
  2409. - MX6QDL_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1b030
  2410. - MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  2411. - MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  2412. - MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  2413. - MX6QDL_PAD_ENET_TXD1__ESAI_TX2_RX3 0x1b030
  2414. - MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  2415. - MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  2416. - MX6QDL_PAD_NANDF_CS2__ESAI_TX0 0x1b030
  2417. - MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  2418. - >;
  2419. - };
  2420. -
  2421. - pinctrl_esai_2: esaigrp-2 {
  2422. - fsl,pins = <
  2423. - MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  2424. - MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  2425. - MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  2426. - MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x1b030
  2427. - MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  2428. - MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  2429. - MX6QDL_PAD_GPIO_17__ESAI_TX0 0x1b030
  2430. - MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  2431. - MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1b030
  2432. - MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x1b030
  2433. - >;
  2434. - };
  2435. - };
  2436. -
  2437. - flexcan1 {
  2438. - pinctrl_flexcan1_1: flexcan1grp-1 {
  2439. - fsl,pins = <
  2440. - MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  2441. - MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  2442. - >;
  2443. - };
  2444. -
  2445. - pinctrl_flexcan1_2: flexcan1grp-2 {
  2446. - fsl,pins = <
  2447. - MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x80000000
  2448. - MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  2449. - >;
  2450. - };
  2451. - };
  2452. -
  2453. - flexcan2 {
  2454. - pinctrl_flexcan2_1: flexcan2grp-1 {
  2455. - fsl,pins = <
  2456. - MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x80000000
  2457. - MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x80000000
  2458. - >;
  2459. - };
  2460. - };
  2461. -
  2462. - gpmi-nand {
  2463. - pinctrl_gpmi_nand_1: gpmi-nand-1 {
  2464. - fsl,pins = <
  2465. - MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  2466. - MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  2467. - MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  2468. - MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  2469. - MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  2470. - MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  2471. - MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  2472. - MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  2473. - MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  2474. - MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  2475. - MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  2476. - MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  2477. - MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  2478. - MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  2479. - MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  2480. - MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  2481. - MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  2482. - >;
  2483. - };
  2484. - };
  2485. -
  2486. - hdmi_hdcp {
  2487. - pinctrl_hdmi_hdcp_1: hdmihdcpgrp-1 {
  2488. - fsl,pins = <
  2489. - MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
  2490. - MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  2491. - >;
  2492. - };
  2493. -
  2494. - pinctrl_hdmi_hdcp_2: hdmihdcpgrp-2 {
  2495. - fsl,pins = <
  2496. - MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
  2497. - MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1
  2498. - >;
  2499. - };
  2500. -
  2501. - pinctrl_hdmi_hdcp_3: hdmihdcpgrp-3 {
  2502. - fsl,pins = <
  2503. - MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1
  2504. - MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  2505. - >;
  2506. - };
  2507. - };
  2508. -
  2509. - hdmi_cec {
  2510. - pinctrl_hdmi_cec_1: hdmicecgrp-1 {
  2511. - fsl,pins = <
  2512. - MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x1f8b0
  2513. - >;
  2514. - };
  2515. -
  2516. - pinctrl_hdmi_cec_2: hdmicecgrp-2 {
  2517. - fsl,pins = <
  2518. - MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  2519. - >;
  2520. - };
  2521. - };
  2522. -
  2523. - i2c1 {
  2524. - pinctrl_i2c1_1: i2c1grp-1 {
  2525. - fsl,pins = <
  2526. - MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  2527. - MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  2528. - >;
  2529. - };
  2530. -
  2531. - pinctrl_i2c1_2: i2c1grp-2 {
  2532. - fsl,pins = <
  2533. - MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
  2534. - MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
  2535. - >;
  2536. - };
  2537. - };
  2538. -
  2539. - i2c2 {
  2540. - pinctrl_i2c2_1: i2c2grp-1 {
  2541. - fsl,pins = <
  2542. - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  2543. - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  2544. - >;
  2545. - };
  2546. -
  2547. - pinctrl_i2c2_2: i2c2grp-2 {
  2548. - fsl,pins = <
  2549. - MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  2550. - MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  2551. - >;
  2552. - };
  2553. -
  2554. - pinctrl_i2c2_3: i2c2grp-3 {
  2555. - fsl,pins = <
  2556. - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  2557. - MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  2558. - >;
  2559. - };
  2560. - };
  2561. -
  2562. - i2c3 {
  2563. - pinctrl_i2c3_1: i2c3grp-1 {
  2564. - fsl,pins = <
  2565. - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  2566. - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  2567. - >;
  2568. - };
  2569. -
  2570. - pinctrl_i2c3_2: i2c3grp-2 {
  2571. - fsl,pins = <
  2572. - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  2573. - MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  2574. - >;
  2575. - };
  2576. -
  2577. - pinctrl_i2c3_3: i2c3grp-3 {
  2578. - fsl,pins = <
  2579. - MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
  2580. - MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
  2581. - >;
  2582. - };
  2583. -
  2584. - pinctrl_i2c3_4: i2c3grp-4 {
  2585. - fsl,pins = <
  2586. - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  2587. - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  2588. - >;
  2589. - };
  2590. - };
  2591. -
  2592. - ipu1 {
  2593. - pinctrl_ipu1_1: ipu1grp-1 {
  2594. - fsl,pins = <
  2595. - MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
  2596. - MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
  2597. - MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
  2598. - MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
  2599. - MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000000
  2600. - MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
  2601. - MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
  2602. - MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
  2603. - MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
  2604. - MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
  2605. - MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
  2606. - MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
  2607. - MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
  2608. - MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
  2609. - MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
  2610. - MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
  2611. - MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
  2612. - MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
  2613. - MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
  2614. - MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
  2615. - MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
  2616. - MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
  2617. - MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
  2618. - MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
  2619. - MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
  2620. - MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
  2621. - MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
  2622. - MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
  2623. - MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
  2624. - >;
  2625. - };
  2626. -
  2627. - pinctrl_ipu1_2: ipu1grp-2 { /* parallel camera */
  2628. - fsl,pins = <
  2629. - MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
  2630. - MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
  2631. - MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
  2632. - MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
  2633. - MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
  2634. - MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
  2635. - MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
  2636. - MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
  2637. - MX6QDL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x80000000
  2638. - MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
  2639. - MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
  2640. - MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
  2641. - >;
  2642. - };
  2643. -
  2644. - pinctrl_ipu1_3: ipu1grp-3 { /* parallel port 16-bit */
  2645. - fsl,pins = <
  2646. - MX6QDL_PAD_CSI0_DAT4__IPU1_CSI0_DATA04 0x80000000
  2647. - MX6QDL_PAD_CSI0_DAT5__IPU1_CSI0_DATA05 0x80000000
  2648. - MX6QDL_PAD_CSI0_DAT6__IPU1_CSI0_DATA06 0x80000000
  2649. - MX6QDL_PAD_CSI0_DAT7__IPU1_CSI0_DATA07 0x80000000
  2650. - MX6QDL_PAD_CSI0_DAT8__IPU1_CSI0_DATA08 0x80000000
  2651. - MX6QDL_PAD_CSI0_DAT9__IPU1_CSI0_DATA09 0x80000000
  2652. - MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10 0x80000000
  2653. - MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11 0x80000000
  2654. - MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x80000000
  2655. - MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x80000000
  2656. - MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x80000000
  2657. - MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x80000000
  2658. - MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x80000000
  2659. - MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x80000000
  2660. - MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x80000000
  2661. - MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x80000000
  2662. - MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x80000000
  2663. - MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x80000000
  2664. - MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x80000000
  2665. - >;
  2666. - };
  2667. - };
  2668. -
  2669. - mlb {
  2670. - pinctrl_mlb_1: mlbgrp-1 {
  2671. - fsl,pins = <
  2672. - MX6QDL_PAD_GPIO_3__MLB_CLK 0x71
  2673. - MX6QDL_PAD_GPIO_6__MLB_SIG 0x71
  2674. - MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
  2675. - >;
  2676. - };
  2677. -
  2678. - pinctrl_mlb_2: mlbgrp-2 {
  2679. - fsl,pins = <
  2680. - MX6QDL_PAD_ENET_TXD1__MLB_CLK 0x71
  2681. - MX6QDL_PAD_GPIO_6__MLB_SIG 0x71
  2682. - MX6QDL_PAD_GPIO_2__MLB_DATA 0x71
  2683. - >;
  2684. - };
  2685. - };
  2686. -
  2687. - pwm0 {
  2688. - pinctrl_pwm0_1: pwm0grp-1 {
  2689. - fsl,pins = <
  2690. - MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  2691. - >;
  2692. - };
  2693. - };
  2694. -
  2695. - pwm3 {
  2696. - pinctrl_pwm3_1: pwm3grp-1 {
  2697. - fsl,pins = <
  2698. - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
  2699. - >;
  2700. - };
  2701. - };
  2702. -
  2703. - spdif {
  2704. - pinctrl_spdif_1: spdifgrp-1 {
  2705. - fsl,pins = <
  2706. - MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
  2707. - >;
  2708. - };
  2709. -
  2710. - pinctrl_spdif_2: spdifgrp-2 {
  2711. - fsl,pins = <
  2712. - MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0
  2713. - MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0
  2714. - >;
  2715. - };
  2716. -
  2717. - pinctrl_spdif_3: spdifgrp-3 {
  2718. - fsl,pins = <
  2719. - MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
  2720. - >;
  2721. - };
  2722. - };
  2723. -
  2724. - uart1 {
  2725. - pinctrl_uart1_1: uart1grp-1 {
  2726. - fsl,pins = <
  2727. - MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  2728. - MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  2729. - >;
  2730. - };
  2731. - };
  2732. -
  2733. - uart2 {
  2734. - pinctrl_uart2_1: uart2grp-1 {
  2735. - fsl,pins = <
  2736. - MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  2737. - MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  2738. - >;
  2739. - };
  2740. -
  2741. - pinctrl_uart2_2: uart2grp-2 { /* DTE mode */
  2742. - fsl,pins = <
  2743. - MX6QDL_PAD_EIM_D26__UART2_RX_DATA 0x1b0b1
  2744. - MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1
  2745. - MX6QDL_PAD_EIM_D28__UART2_DTE_CTS_B 0x1b0b1
  2746. - MX6QDL_PAD_EIM_D29__UART2_DTE_RTS_B 0x1b0b1
  2747. - >;
  2748. - };
  2749. - };
  2750. -
  2751. - uart3 {
  2752. - pinctrl_uart3_1: uart3grp-1 {
  2753. - fsl,pins = <
  2754. - MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
  2755. - MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
  2756. - MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1
  2757. - MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  2758. - >;
  2759. - };
  2760. -
  2761. - pinctrl_uart3_2: uart3grp-2 {
  2762. - fsl,pins = <
  2763. - MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  2764. - MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  2765. - MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
  2766. - MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  2767. - >;
  2768. - };
  2769. - };
  2770. -
  2771. - uart4 {
  2772. - pinctrl_uart4_1: uart4grp-1 {
  2773. - fsl,pins = <
  2774. - MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  2775. - MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  2776. - >;
  2777. - };
  2778. - };
  2779. -
  2780. - usbotg {
  2781. - pinctrl_usbotg_1: usbotggrp-1 {
  2782. - fsl,pins = <
  2783. - MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  2784. - >;
  2785. - };
  2786. -
  2787. - pinctrl_usbotg_2: usbotggrp-2 {
  2788. - fsl,pins = <
  2789. - MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  2790. - >;
  2791. - };
  2792. - };
  2793. -
  2794. - usbh2 {
  2795. - pinctrl_usbh2_1: usbh2grp-1 {
  2796. - fsl,pins = <
  2797. - MX6QDL_PAD_RGMII_TXC__USB_H2_DATA 0x40013030
  2798. - MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40013030
  2799. - >;
  2800. - };
  2801. -
  2802. - pinctrl_usbh2_2: usbh2grp-2 {
  2803. - fsl,pins = <
  2804. - MX6QDL_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x40017030
  2805. - >;
  2806. - };
  2807. - };
  2808. -
  2809. - usbh3 {
  2810. - pinctrl_usbh3_1: usbh3grp-1 {
  2811. - fsl,pins = <
  2812. - MX6QDL_PAD_RGMII_RX_CTL__USB_H3_DATA 0x40013030
  2813. - MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40013030
  2814. - >;
  2815. - };
  2816. -
  2817. - pinctrl_usbh3_2: usbh3grp-2 {
  2818. - fsl,pins = <
  2819. - MX6QDL_PAD_RGMII_RXC__USB_H3_STROBE 0x40017030
  2820. - >;
  2821. - };
  2822. - };
  2823. -
  2824. - usdhc1 {
  2825. - pinctrl_usdhc1_1: usdhc1grp-1 {
  2826. - fsl,pins = <
  2827. - MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  2828. - MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  2829. - MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  2830. - MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  2831. - MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  2832. - MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  2833. - MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17059
  2834. - MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17059
  2835. - MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17059
  2836. - MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x17059
  2837. - >;
  2838. - };
  2839. -
  2840. - pinctrl_usdhc1_2: usdhc1grp-2 {
  2841. - fsl,pins = <
  2842. - MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  2843. - MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  2844. - MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  2845. - MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  2846. - MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  2847. - MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  2848. - >;
  2849. - };
  2850. - };
  2851. -
  2852. - usdhc2 {
  2853. - pinctrl_usdhc2_1: usdhc2grp-1 {
  2854. - fsl,pins = <
  2855. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  2856. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  2857. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  2858. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  2859. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  2860. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  2861. - MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
  2862. - MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
  2863. - MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
  2864. - MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
  2865. - >;
  2866. - };
  2867. -
  2868. - pinctrl_usdhc2_2: usdhc2grp-2 {
  2869. - fsl,pins = <
  2870. - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  2871. - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  2872. - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  2873. - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  2874. - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  2875. - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  2876. - >;
  2877. - };
  2878. - };
  2879. -
  2880. - usdhc3 {
  2881. - pinctrl_usdhc3_1: usdhc3grp-1 {
  2882. - fsl,pins = <
  2883. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  2884. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  2885. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  2886. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  2887. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  2888. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  2889. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  2890. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  2891. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  2892. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  2893. - >;
  2894. - };
  2895. -
  2896. - pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz { /* 100Mhz */
  2897. - fsl,pins = <
  2898. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
  2899. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
  2900. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  2901. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  2902. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  2903. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  2904. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
  2905. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
  2906. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
  2907. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
  2908. - >;
  2909. - };
  2910. -
  2911. - pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz { /* 200Mhz */
  2912. - fsl,pins = <
  2913. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
  2914. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
  2915. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  2916. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  2917. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  2918. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  2919. - MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
  2920. - MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
  2921. - MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
  2922. - MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
  2923. - >;
  2924. - };
  2925. -
  2926. - pinctrl_usdhc3_2: usdhc3grp-2 {
  2927. - fsl,pins = <
  2928. - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  2929. - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  2930. - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  2931. - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  2932. - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  2933. - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  2934. - >;
  2935. - };
  2936. - };
  2937. -
  2938. - usdhc4 {
  2939. - pinctrl_usdhc4_1: usdhc4grp-1 {
  2940. - fsl,pins = <
  2941. - MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  2942. - MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  2943. - MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  2944. - MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  2945. - MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  2946. - MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  2947. - MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  2948. - MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  2949. - MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  2950. - MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  2951. - >;
  2952. - };
  2953. -
  2954. - pinctrl_usdhc4_2: usdhc4grp-2 {
  2955. - fsl,pins = <
  2956. - MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  2957. - MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  2958. - MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  2959. - MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  2960. - MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  2961. - MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  2962. - >;
  2963. - };
  2964. - };
  2965. -
  2966. - weim {
  2967. - pinctrl_weim_cs0_1: weim_cs0grp-1 {
  2968. - fsl,pins = <
  2969. - MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
  2970. - >;
  2971. - };
  2972. -
  2973. - pinctrl_weim_nor_1: weim_norgrp-1 {
  2974. - fsl,pins = <
  2975. - MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
  2976. - MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
  2977. - MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
  2978. - /* data */
  2979. - MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
  2980. - MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
  2981. - MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
  2982. - MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
  2983. - MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
  2984. - MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
  2985. - MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
  2986. - MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
  2987. - MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
  2988. - MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
  2989. - MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
  2990. - MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
  2991. - MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
  2992. - MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
  2993. - MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
  2994. - MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
  2995. - /* address */
  2996. - MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
  2997. - MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
  2998. - MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
  2999. - MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
  3000. - MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
  3001. - MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
  3002. - MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
  3003. - MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
  3004. - MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
  3005. - MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
  3006. - MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
  3007. - MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
  3008. - MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
  3009. - MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
  3010. - MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
  3011. - MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
  3012. - MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
  3013. - MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
  3014. - MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
  3015. - MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
  3016. - MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
  3017. - MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
  3018. - MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
  3019. - MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
  3020. - >;
  3021. - };
  3022. - };
  3023. };
  3024. ldb: ldb@020e0008 {
  3025. - #address-cells = <1>;
  3026. - #size-cells = <0>;
  3027. compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
  3028. - gpr = <&gpr>;
  3029. + reg = <0x020e0000 0x4000>;
  3030. + clocks = <&clks 135>, <&clks 136>,
  3031. + <&clks 39>, <&clks 40>,
  3032. + <&clks 41>, <&clks 42>,
  3033. + <&clks 184>, <&clks 185>,
  3034. + <&clks 210>, <&clks 211>,
  3035. + <&clks 212>, <&clks 213>;
  3036. + clock-names = "ldb_di0", "ldb_di1",
  3037. + "ipu1_di0_sel", "ipu1_di1_sel",
  3038. + "ipu2_di0_sel", "ipu2_di1_sel",
  3039. + "di0_div_3_5", "di1_div_3_5",
  3040. + "di0_div_7", "di1_div_7",
  3041. + "di0_div_sel", "di1_div_sel";
  3042. status = "disabled";
  3043. -
  3044. - lvds-channel@0 {
  3045. - reg = <0>;
  3046. - status = "disabled";
  3047. - };
  3048. -
  3049. - lvds-channel@1 {
  3050. - reg = <1>;
  3051. - status = "disabled";
  3052. - };
  3053. };
  3054. dcic1: dcic@020e4000 {
  3055. reg = <0x020e4000 0x4000>;
  3056. - interrupts = <0 124 0x04>;
  3057. + interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
  3058. };
  3059. dcic2: dcic@020e8000 {
  3060. reg = <0x020e8000 0x4000>;
  3061. - interrupts = <0 125 0x04>;
  3062. + interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
  3063. };
  3064. sdma: sdma@020ec000 {
  3065. compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
  3066. reg = <0x020ec000 0x4000>;
  3067. - interrupts = <0 2 0x04>;
  3068. + interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
  3069. clocks = <&clks 155>, <&clks 155>;
  3070. clock-names = "ipg", "ahb";
  3071. #dma-cells = <3>;
  3072. @@ -1396,9 +772,29 @@
  3073. reg = <0x02100000 0x100000>;
  3074. ranges;
  3075. - caam@02100000 {
  3076. - reg = <0x02100000 0x40000>;
  3077. - interrupts = <0 105 0x04 0 106 0x04>;
  3078. + crypto: caam@02100000 {
  3079. + compatible = "fsl,sec-v4.0";
  3080. + #address-cells = <1>;
  3081. + #size-cells = <1>;
  3082. + reg = <0x2100000 0x40000>;
  3083. + ranges = <0 0x2100000 0x40000>;
  3084. + interrupt-parent = <&intc>; /* interrupts = <0 92 0x4>; */
  3085. + clocks = <&clks 214>, <&clks 215>, <&clks 216>, <&clks 196>;
  3086. + clock-names = "caam_mem", "caam_aclk", "caam_ipg", "caam_emi_slow";
  3087. +
  3088. + sec_jr0: jr0@1000 {
  3089. + compatible = "fsl,sec-v4.0-job-ring";
  3090. + reg = <0x1000 0x1000>;
  3091. + interrupt-parent = <&intc>;
  3092. + interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
  3093. + };
  3094. +
  3095. + sec_jr1: jr1@2000 {
  3096. + compatible = "fsl,sec-v4.0-job-ring";
  3097. + reg = <0x2000 0x1000>;
  3098. + interrupt-parent = <&intc>;
  3099. + interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
  3100. + };
  3101. };
  3102. aipstz@0217c000 { /* AIPSTZ2 */
  3103. @@ -1408,7 +804,7 @@
  3104. usbotg: usb@02184000 {
  3105. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3106. reg = <0x02184000 0x200>;
  3107. - interrupts = <0 43 0x04>;
  3108. + interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
  3109. clocks = <&clks 162>;
  3110. fsl,usbphy = <&usbphy1>;
  3111. fsl,usbmisc = <&usbmisc 0>;
  3112. @@ -1418,7 +814,7 @@
  3113. usbh1: usb@02184200 {
  3114. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3115. reg = <0x02184200 0x200>;
  3116. - interrupts = <0 40 0x04>;
  3117. + interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
  3118. clocks = <&clks 162>;
  3119. fsl,usbphy = <&usbphy2>;
  3120. fsl,usbmisc = <&usbmisc 1>;
  3121. @@ -1428,18 +824,24 @@
  3122. usbh2: usb@02184400 {
  3123. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3124. reg = <0x02184400 0x200>;
  3125. - interrupts = <0 41 0x04>;
  3126. + interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
  3127. clocks = <&clks 162>;
  3128. fsl,usbmisc = <&usbmisc 2>;
  3129. + phy_type = "hsic";
  3130. + fsl,usbphy = <&usbphy_nop1>;
  3131. + fsl,anatop = <&anatop>;
  3132. status = "disabled";
  3133. };
  3134. usbh3: usb@02184600 {
  3135. compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
  3136. reg = <0x02184600 0x200>;
  3137. - interrupts = <0 42 0x04>;
  3138. + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
  3139. clocks = <&clks 162>;
  3140. fsl,usbmisc = <&usbmisc 3>;
  3141. + phy_type = "hsic";
  3142. + fsl,usbphy = <&usbphy_nop2>;
  3143. + fsl,anatop = <&anatop>;
  3144. status = "disabled";
  3145. };
  3146. @@ -1453,7 +855,9 @@
  3147. fec: ethernet@02188000 {
  3148. compatible = "fsl,imx6q-fec";
  3149. reg = <0x02188000 0x4000>;
  3150. - interrupts = <0 118 0x04 0 119 0x04>;
  3151. + interrupts-extended =
  3152. + <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
  3153. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  3154. clocks = <&clks 117>, <&clks 117>, <&clks 190>;
  3155. clock-names = "ipg", "ahb", "ptp";
  3156. status = "disabled";
  3157. @@ -1461,13 +865,15 @@
  3158. mlb@0218c000 {
  3159. reg = <0x0218c000 0x4000>;
  3160. - interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
  3161. + interrupts = <0 53 IRQ_TYPE_LEVEL_HIGH>,
  3162. + <0 117 IRQ_TYPE_LEVEL_HIGH>,
  3163. + <0 126 IRQ_TYPE_LEVEL_HIGH>;
  3164. };
  3165. usdhc1: usdhc@02190000 {
  3166. compatible = "fsl,imx6q-usdhc";
  3167. reg = <0x02190000 0x4000>;
  3168. - interrupts = <0 22 0x04>;
  3169. + interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
  3170. clocks = <&clks 163>, <&clks 163>, <&clks 163>;
  3171. clock-names = "ipg", "ahb", "per";
  3172. bus-width = <4>;
  3173. @@ -1477,7 +883,7 @@
  3174. usdhc2: usdhc@02194000 {
  3175. compatible = "fsl,imx6q-usdhc";
  3176. reg = <0x02194000 0x4000>;
  3177. - interrupts = <0 23 0x04>;
  3178. + interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
  3179. clocks = <&clks 164>, <&clks 164>, <&clks 164>;
  3180. clock-names = "ipg", "ahb", "per";
  3181. bus-width = <4>;
  3182. @@ -1487,7 +893,7 @@
  3183. usdhc3: usdhc@02198000 {
  3184. compatible = "fsl,imx6q-usdhc";
  3185. reg = <0x02198000 0x4000>;
  3186. - interrupts = <0 24 0x04>;
  3187. + interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
  3188. clocks = <&clks 165>, <&clks 165>, <&clks 165>;
  3189. clock-names = "ipg", "ahb", "per";
  3190. bus-width = <4>;
  3191. @@ -1497,7 +903,7 @@
  3192. usdhc4: usdhc@0219c000 {
  3193. compatible = "fsl,imx6q-usdhc";
  3194. reg = <0x0219c000 0x4000>;
  3195. - interrupts = <0 25 0x04>;
  3196. + interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
  3197. clocks = <&clks 166>, <&clks 166>, <&clks 166>;
  3198. clock-names = "ipg", "ahb", "per";
  3199. bus-width = <4>;
  3200. @@ -1509,7 +915,7 @@
  3201. #size-cells = <0>;
  3202. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3203. reg = <0x021a0000 0x4000>;
  3204. - interrupts = <0 36 0x04>;
  3205. + interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
  3206. clocks = <&clks 125>;
  3207. status = "disabled";
  3208. };
  3209. @@ -1519,7 +925,7 @@
  3210. #size-cells = <0>;
  3211. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3212. reg = <0x021a4000 0x4000>;
  3213. - interrupts = <0 37 0x04>;
  3214. + interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
  3215. clocks = <&clks 126>;
  3216. status = "disabled";
  3217. };
  3218. @@ -1529,7 +935,7 @@
  3219. #size-cells = <0>;
  3220. compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
  3221. reg = <0x021a8000 0x4000>;
  3222. - interrupts = <0 38 0x04>;
  3223. + interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
  3224. clocks = <&clks 127>;
  3225. status = "disabled";
  3226. };
  3227. @@ -1538,6 +944,11 @@
  3228. reg = <0x021ac000 0x4000>;
  3229. };
  3230. + mmdc0-1@021b0000 { /* MMDC0-1 */
  3231. + compatible = "fsl,imx6q-mmdc-combine";
  3232. + reg = <0x021b0000 0x8000>;
  3233. + };
  3234. +
  3235. mmdc0: mmdc@021b0000 { /* MMDC0 */
  3236. compatible = "fsl,imx6q-mmdc";
  3237. reg = <0x021b0000 0x4000>;
  3238. @@ -1550,23 +961,29 @@
  3239. weim: weim@021b8000 {
  3240. compatible = "fsl,imx6q-weim";
  3241. reg = <0x021b8000 0x4000>;
  3242. - interrupts = <0 14 0x04>;
  3243. + interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
  3244. clocks = <&clks 196>;
  3245. };
  3246. - ocotp: ocotp@021bc000 {
  3247. - compatible = "fsl,imx6q-ocotp", "syscon";
  3248. + ocotp: ocotp-ctrl@021bc000 {
  3249. + compatible = "syscon";
  3250. reg = <0x021bc000 0x4000>;
  3251. };
  3252. + ocotp-fuse@021bc000 {
  3253. + compatible = "fsl,imx6q-ocotp";
  3254. + reg = <0x021bc000 0x4000>;
  3255. + clocks = <&clks 128>;
  3256. + };
  3257. +
  3258. tzasc@021d0000 { /* TZASC1 */
  3259. reg = <0x021d0000 0x4000>;
  3260. - interrupts = <0 108 0x04>;
  3261. + interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
  3262. };
  3263. tzasc@021d4000 { /* TZASC2 */
  3264. reg = <0x021d4000 0x4000>;
  3265. - interrupts = <0 109 0x04>;
  3266. + interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
  3267. };
  3268. audmux: audmux@021d8000 {
  3269. @@ -1575,23 +992,32 @@
  3270. status = "disabled";
  3271. };
  3272. - mipi@021dc000 { /* MIPI-CSI */
  3273. + mipi_csi: mipi_csi@021dc000 {
  3274. + compatible = "fsl,imx6q-mipi-csi2";
  3275. reg = <0x021dc000 0x4000>;
  3276. - };
  3277. -
  3278. - mipi@021e0000 { /* MIPI-DSI */
  3279. - reg = <0x021e0000 0x4000>;
  3280. + interrupts = <0 100 0x04>, <0 101 0x04>;
  3281. + clocks = <&clks 138>, <&clks 53>, <&clks 204>;
  3282. + /* Note: clks 138 is hsi_tx, however, the dphy_c
  3283. + * hsi_tx and pll_refclk use the same clk gate.
  3284. + * In current clk driver, open/close clk gate do
  3285. + * use hsi_tx for a temporary debug purpose.
  3286. + */
  3287. + clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
  3288. + status = "disabled";
  3289. };
  3290. vdoa@021e4000 {
  3291. + compatible = "fsl,imx6q-vdoa";
  3292. reg = <0x021e4000 0x4000>;
  3293. - interrupts = <0 18 0x04>;
  3294. + interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
  3295. + clocks = <&clks 202>;
  3296. + iram = <&ocram>;
  3297. };
  3298. uart2: serial@021e8000 {
  3299. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3300. reg = <0x021e8000 0x4000>;
  3301. - interrupts = <0 27 0x04>;
  3302. + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
  3303. clocks = <&clks 160>, <&clks 161>;
  3304. clock-names = "ipg", "per";
  3305. dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
  3306. @@ -1602,7 +1028,7 @@
  3307. uart3: serial@021ec000 {
  3308. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3309. reg = <0x021ec000 0x4000>;
  3310. - interrupts = <0 28 0x04>;
  3311. + interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
  3312. clocks = <&clks 160>, <&clks 161>;
  3313. clock-names = "ipg", "per";
  3314. dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
  3315. @@ -1613,7 +1039,7 @@
  3316. uart4: serial@021f0000 {
  3317. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3318. reg = <0x021f0000 0x4000>;
  3319. - interrupts = <0 29 0x04>;
  3320. + interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
  3321. clocks = <&clks 160>, <&clks 161>;
  3322. clock-names = "ipg", "per";
  3323. dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
  3324. @@ -1624,7 +1050,7 @@
  3325. uart5: serial@021f4000 {
  3326. compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
  3327. reg = <0x021f4000 0x4000>;
  3328. - interrupts = <0 30 0x04>;
  3329. + interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
  3330. clocks = <&clks 160>, <&clks 161>;
  3331. clock-names = "ipg", "per";
  3332. dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
  3333. @@ -1634,13 +1060,18 @@
  3334. };
  3335. ipu1: ipu@02400000 {
  3336. - #crtc-cells = <1>;
  3337. compatible = "fsl,imx6q-ipu";
  3338. reg = <0x02400000 0x400000>;
  3339. - interrupts = <0 6 0x4 0 5 0x4>;
  3340. - clocks = <&clks 130>, <&clks 131>, <&clks 132>;
  3341. - clock-names = "bus", "di0", "di1";
  3342. + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
  3343. + <0 5 IRQ_TYPE_LEVEL_HIGH>;
  3344. + clocks = <&clks 130>, <&clks 131>, <&clks 132>,
  3345. + <&clks 39>, <&clks 40>,
  3346. + <&clks 135>, <&clks 136>;
  3347. + clock-names = "bus", "di0", "di1",
  3348. + "di0_sel", "di1_sel",
  3349. + "ldb_di0", "ldb_di1";
  3350. resets = <&src 2>;
  3351. + bypass_reset = <0>;
  3352. };
  3353. };
  3354. };
  3355. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
  3356. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  3357. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi 2014-09-11 18:05:52.642000568 +0200
  3358. @@ -0,0 +1,374 @@
  3359. +/*
  3360. + * Copyright 2013 Gateworks Corporation
  3361. + *
  3362. + * The code contained herein is licensed under the GNU General Public
  3363. + * License. You may obtain a copy of the GNU General Public License
  3364. + * Version 2 or later at the following locations:
  3365. + *
  3366. + * http://www.opensource.org/licenses/gpl-license.html
  3367. + * http://www.gnu.org/copyleft/gpl.html
  3368. + */
  3369. +
  3370. +/ {
  3371. + /* these are used by bootloader for disabling nodes */
  3372. + aliases {
  3373. + can0 = &can1;
  3374. + ethernet0 = &fec;
  3375. + led0 = &led0;
  3376. + led1 = &led1;
  3377. + nand = &gpmi;
  3378. + usb0 = &usbh1;
  3379. + usb1 = &usbotg;
  3380. + };
  3381. +
  3382. + chosen {
  3383. + bootargs = "console=ttymxc1,115200";
  3384. + };
  3385. +
  3386. + leds {
  3387. + compatible = "gpio-leds";
  3388. +
  3389. + led0: user1 {
  3390. + label = "user1";
  3391. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  3392. + default-state = "on";
  3393. + linux,default-trigger = "heartbeat";
  3394. + };
  3395. +
  3396. + led1: user2 {
  3397. + label = "user2";
  3398. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  3399. + default-state = "off";
  3400. + };
  3401. + };
  3402. +
  3403. + memory {
  3404. + reg = <0x10000000 0x20000000>;
  3405. + };
  3406. +
  3407. + pps {
  3408. + compatible = "pps-gpio";
  3409. + gpios = <&gpio1 26 0>;
  3410. + status = "okay";
  3411. + };
  3412. +
  3413. + regulators {
  3414. + compatible = "simple-bus";
  3415. + #address-cells = <1>;
  3416. + #size-cells = <0>;
  3417. +
  3418. + reg_3p3v: regulator@0 {
  3419. + compatible = "regulator-fixed";
  3420. + reg = <0>;
  3421. + regulator-name = "3P3V";
  3422. + regulator-min-microvolt = <3300000>;
  3423. + regulator-max-microvolt = <3300000>;
  3424. + regulator-always-on;
  3425. + };
  3426. +
  3427. + reg_5p0v: regulator@1 {
  3428. + compatible = "regulator-fixed";
  3429. + reg = <1>;
  3430. + regulator-name = "5P0V";
  3431. + regulator-min-microvolt = <5000000>;
  3432. + regulator-max-microvolt = <5000000>;
  3433. + regulator-always-on;
  3434. + };
  3435. +
  3436. + reg_usb_otg_vbus: regulator@2 {
  3437. + compatible = "regulator-fixed";
  3438. + reg = <2>;
  3439. + regulator-name = "usb_otg_vbus";
  3440. + regulator-min-microvolt = <5000000>;
  3441. + regulator-max-microvolt = <5000000>;
  3442. + gpio = <&gpio3 22 0>;
  3443. + enable-active-high;
  3444. + };
  3445. + };
  3446. +};
  3447. +
  3448. +&fec {
  3449. + pinctrl-names = "default";
  3450. + pinctrl-0 = <&pinctrl_enet>;
  3451. + phy-mode = "rgmii";
  3452. + phy-reset-gpios = <&gpio1 30 0>;
  3453. + status = "okay";
  3454. +};
  3455. +
  3456. +&gpmi {
  3457. + pinctrl-names = "default";
  3458. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  3459. + status = "okay";
  3460. +};
  3461. +
  3462. +&i2c1 {
  3463. + clock-frequency = <100000>;
  3464. + pinctrl-names = "default";
  3465. + pinctrl-0 = <&pinctrl_i2c1>;
  3466. + status = "okay";
  3467. +
  3468. + eeprom1: eeprom@50 {
  3469. + compatible = "atmel,24c02";
  3470. + reg = <0x50>;
  3471. + pagesize = <16>;
  3472. + };
  3473. +
  3474. + eeprom2: eeprom@51 {
  3475. + compatible = "atmel,24c02";
  3476. + reg = <0x51>;
  3477. + pagesize = <16>;
  3478. + };
  3479. +
  3480. + eeprom3: eeprom@52 {
  3481. + compatible = "atmel,24c02";
  3482. + reg = <0x52>;
  3483. + pagesize = <16>;
  3484. + };
  3485. +
  3486. + eeprom4: eeprom@53 {
  3487. + compatible = "atmel,24c02";
  3488. + reg = <0x53>;
  3489. + pagesize = <16>;
  3490. + };
  3491. +
  3492. + gpio: pca9555@23 {
  3493. + compatible = "nxp,pca9555";
  3494. + reg = <0x23>;
  3495. + gpio-controller;
  3496. + #gpio-cells = <2>;
  3497. + };
  3498. +
  3499. + hwmon: gsc@29 {
  3500. + compatible = "gw,gsp";
  3501. + reg = <0x29>;
  3502. + };
  3503. +
  3504. + rtc: ds1672@68 {
  3505. + compatible = "dallas,ds1672";
  3506. + reg = <0x68>;
  3507. + };
  3508. +};
  3509. +
  3510. +&i2c2 {
  3511. + clock-frequency = <100000>;
  3512. + pinctrl-names = "default";
  3513. + pinctrl-0 = <&pinctrl_i2c2>;
  3514. + status = "okay";
  3515. +
  3516. + pmic: ltc3676@3c {
  3517. + compatible = "ltc,ltc3676";
  3518. + reg = <0x3c>;
  3519. +
  3520. + regulators {
  3521. + sw1_reg: ltc3676__sw1 {
  3522. + regulator-min-microvolt = <1175000>;
  3523. + regulator-max-microvolt = <1175000>;
  3524. + regulator-boot-on;
  3525. + regulator-always-on;
  3526. + };
  3527. +
  3528. + sw2_reg: ltc3676__sw2 {
  3529. + regulator-min-microvolt = <1800000>;
  3530. + regulator-max-microvolt = <1800000>;
  3531. + regulator-boot-on;
  3532. + regulator-always-on;
  3533. + };
  3534. +
  3535. + sw3_reg: ltc3676__sw3 {
  3536. + regulator-min-microvolt = <1175000>;
  3537. + regulator-max-microvolt = <1175000>;
  3538. + regulator-boot-on;
  3539. + regulator-always-on;
  3540. + };
  3541. +
  3542. + sw4_reg: ltc3676__sw4 {
  3543. + regulator-min-microvolt = <1500000>;
  3544. + regulator-max-microvolt = <1500000>;
  3545. + regulator-boot-on;
  3546. + regulator-always-on;
  3547. + };
  3548. +
  3549. + ldo2_reg: ltc3676__ldo2 {
  3550. + regulator-min-microvolt = <2500000>;
  3551. + regulator-max-microvolt = <2500000>;
  3552. + regulator-boot-on;
  3553. + regulator-always-on;
  3554. + };
  3555. +
  3556. + ldo4_reg: ltc3676__ldo4 {
  3557. + regulator-min-microvolt = <3000000>;
  3558. + regulator-max-microvolt = <3000000>;
  3559. + };
  3560. + };
  3561. + };
  3562. +};
  3563. +
  3564. +&i2c3 {
  3565. + clock-frequency = <100000>;
  3566. + pinctrl-names = "default";
  3567. + pinctrl-0 = <&pinctrl_i2c3>;
  3568. + status = "okay";
  3569. +
  3570. + videoin: adv7180@20 {
  3571. + compatible = "adi,adv7180";
  3572. + reg = <0x20>;
  3573. + };
  3574. +};
  3575. +
  3576. +&iomuxc {
  3577. + pinctrl-names = "default";
  3578. + pinctrl-0 = <&pinctrl_hog>;
  3579. +
  3580. + imx6qdl-gw51xx {
  3581. + pinctrl_hog: hoggrp {
  3582. + fsl,pins = <
  3583. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* MEZZ_DIO0 */
  3584. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* MEZZ_DIO1 */
  3585. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  3586. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  3587. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
  3588. + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x80000000 /* PCIE_RST# */
  3589. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  3590. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  3591. + >;
  3592. + };
  3593. +
  3594. + pinctrl_enet: enetgrp {
  3595. + fsl,pins = <
  3596. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  3597. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  3598. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  3599. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  3600. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  3601. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  3602. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  3603. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  3604. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  3605. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  3606. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  3607. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  3608. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  3609. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  3610. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  3611. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  3612. + >;
  3613. + };
  3614. +
  3615. + pinctrl_gpmi_nand: gpminandgrp {
  3616. + fsl,pins = <
  3617. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  3618. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  3619. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  3620. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  3621. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  3622. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  3623. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  3624. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  3625. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  3626. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  3627. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  3628. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  3629. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  3630. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  3631. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  3632. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  3633. + >;
  3634. + };
  3635. +
  3636. + pinctrl_i2c1: i2c1grp {
  3637. + fsl,pins = <
  3638. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  3639. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  3640. + >;
  3641. + };
  3642. +
  3643. + pinctrl_i2c2: i2c2grp {
  3644. + fsl,pins = <
  3645. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  3646. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  3647. + >;
  3648. + };
  3649. +
  3650. + pinctrl_i2c3: i2c3grp {
  3651. + fsl,pins = <
  3652. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  3653. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  3654. + >;
  3655. + };
  3656. +
  3657. + pinctrl_uart1: uart1grp {
  3658. + fsl,pins = <
  3659. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  3660. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  3661. + >;
  3662. + };
  3663. +
  3664. + pinctrl_uart2: uart2grp {
  3665. + fsl,pins = <
  3666. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  3667. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  3668. + >;
  3669. + };
  3670. +
  3671. + pinctrl_uart3: uart3grp {
  3672. + fsl,pins = <
  3673. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  3674. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  3675. + >;
  3676. + };
  3677. +
  3678. + pinctrl_uart5: uart5grp {
  3679. + fsl,pins = <
  3680. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  3681. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  3682. + >;
  3683. + };
  3684. +
  3685. + pinctrl_usbotg: usbotggrp {
  3686. + fsl,pins = <
  3687. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  3688. + >;
  3689. + };
  3690. + };
  3691. +};
  3692. +
  3693. +&pcie {
  3694. + reset-gpio = <&gpio1 0 0>;
  3695. + status = "okay";
  3696. +};
  3697. +
  3698. +&uart1 {
  3699. + pinctrl-names = "default";
  3700. + pinctrl-0 = <&pinctrl_uart1>;
  3701. + status = "okay";
  3702. +};
  3703. +
  3704. +&uart2 {
  3705. + pinctrl-names = "default";
  3706. + pinctrl-0 = <&pinctrl_uart2>;
  3707. + status = "okay";
  3708. +};
  3709. +
  3710. +&uart3 {
  3711. + pinctrl-names = "default";
  3712. + pinctrl-0 = <&pinctrl_uart3>;
  3713. + status = "okay";
  3714. +};
  3715. +
  3716. +&uart5 {
  3717. + pinctrl-names = "default";
  3718. + pinctrl-0 = <&pinctrl_uart5>;
  3719. + status = "okay";
  3720. +};
  3721. +
  3722. +&usbotg {
  3723. + vbus-supply = <&reg_usb_otg_vbus>;
  3724. + pinctrl-names = "default";
  3725. + pinctrl-0 = <&pinctrl_usbotg>;
  3726. + disable-over-current;
  3727. + status = "okay";
  3728. +};
  3729. +
  3730. +&usbh1 {
  3731. + status = "okay";
  3732. +};
  3733. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
  3734. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  3735. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi 2014-09-11 18:05:52.642000568 +0200
  3736. @@ -0,0 +1,527 @@
  3737. +/*
  3738. + * Copyright 2013 Gateworks Corporation
  3739. + *
  3740. + * The code contained herein is licensed under the GNU General Public
  3741. + * License. You may obtain a copy of the GNU General Public License
  3742. + * Version 2 or later at the following locations:
  3743. + *
  3744. + * http://www.opensource.org/licenses/gpl-license.html
  3745. + * http://www.gnu.org/copyleft/gpl.html
  3746. + */
  3747. +
  3748. +/ {
  3749. + /* these are used by bootloader for disabling nodes */
  3750. + aliases {
  3751. + ethernet0 = &fec;
  3752. + led0 = &led0;
  3753. + led1 = &led1;
  3754. + led2 = &led2;
  3755. + nand = &gpmi;
  3756. + ssi0 = &ssi1;
  3757. + usb0 = &usbh1;
  3758. + usb1 = &usbotg;
  3759. + usdhc2 = &usdhc3;
  3760. + };
  3761. +
  3762. + chosen {
  3763. + bootargs = "console=ttymxc1,115200";
  3764. + };
  3765. +
  3766. + backlight {
  3767. + compatible = "pwm-backlight";
  3768. + pwms = <&pwm4 0 5000000>;
  3769. + brightness-levels = <0 4 8 16 32 64 128 255>;
  3770. + default-brightness-level = <7>;
  3771. + };
  3772. +
  3773. + leds {
  3774. + compatible = "gpio-leds";
  3775. +
  3776. + led0: user1 {
  3777. + label = "user1";
  3778. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  3779. + default-state = "on";
  3780. + linux,default-trigger = "heartbeat";
  3781. + };
  3782. +
  3783. + led1: user2 {
  3784. + label = "user2";
  3785. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  3786. + default-state = "off";
  3787. + };
  3788. +
  3789. + led2: user3 {
  3790. + label = "user3";
  3791. + gpios = <&gpio4 15 1>; /* 111 - MX6_LOCLED# */
  3792. + default-state = "off";
  3793. + };
  3794. + };
  3795. +
  3796. + memory {
  3797. + reg = <0x10000000 0x20000000>;
  3798. + };
  3799. +
  3800. + pps {
  3801. + compatible = "pps-gpio";
  3802. + gpios = <&gpio1 26 0>;
  3803. + status = "okay";
  3804. + };
  3805. +
  3806. + regulators {
  3807. + compatible = "simple-bus";
  3808. + #address-cells = <1>;
  3809. + #size-cells = <0>;
  3810. +
  3811. + reg_1p0v: regulator@0 {
  3812. + compatible = "regulator-fixed";
  3813. + reg = <0>;
  3814. + regulator-name = "1P0V";
  3815. + regulator-min-microvolt = <1000000>;
  3816. + regulator-max-microvolt = <1000000>;
  3817. + regulator-always-on;
  3818. + };
  3819. +
  3820. + /* remove this fixed regulator once ltc3676__sw2 driver available */
  3821. + reg_1p8v: regulator@1 {
  3822. + compatible = "regulator-fixed";
  3823. + reg = <1>;
  3824. + regulator-name = "1P8V";
  3825. + regulator-min-microvolt = <1800000>;
  3826. + regulator-max-microvolt = <1800000>;
  3827. + regulator-always-on;
  3828. + };
  3829. +
  3830. + reg_3p3v: regulator@2 {
  3831. + compatible = "regulator-fixed";
  3832. + reg = <2>;
  3833. + regulator-name = "3P3V";
  3834. + regulator-min-microvolt = <3300000>;
  3835. + regulator-max-microvolt = <3300000>;
  3836. + regulator-always-on;
  3837. + };
  3838. +
  3839. + reg_5p0v: regulator@3 {
  3840. + compatible = "regulator-fixed";
  3841. + reg = <3>;
  3842. + regulator-name = "5P0V";
  3843. + regulator-min-microvolt = <5000000>;
  3844. + regulator-max-microvolt = <5000000>;
  3845. + regulator-always-on;
  3846. + };
  3847. +
  3848. + reg_usb_otg_vbus: regulator@4 {
  3849. + compatible = "regulator-fixed";
  3850. + reg = <4>;
  3851. + regulator-name = "usb_otg_vbus";
  3852. + regulator-min-microvolt = <5000000>;
  3853. + regulator-max-microvolt = <5000000>;
  3854. + gpio = <&gpio3 22 0>;
  3855. + enable-active-high;
  3856. + };
  3857. + };
  3858. +
  3859. + sound {
  3860. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  3861. + "fsl,imx-audio-sgtl5000";
  3862. + model = "imx6q-sabrelite-sgtl5000";
  3863. + ssi-controller = <&ssi1>;
  3864. + audio-codec = <&codec>;
  3865. + audio-routing =
  3866. + "MIC_IN", "Mic Jack",
  3867. + "Mic Jack", "Mic Bias",
  3868. + "Headphone Jack", "HP_OUT";
  3869. + mux-int-port = <1>;
  3870. + mux-ext-port = <4>;
  3871. + };
  3872. +};
  3873. +
  3874. +&audmux {
  3875. + pinctrl-names = "default";
  3876. + pinctrl-0 = <&pinctrl_audmux>;
  3877. + status = "okay";
  3878. +};
  3879. +
  3880. +&fec {
  3881. + pinctrl-names = "default";
  3882. + pinctrl-0 = <&pinctrl_enet>;
  3883. + phy-mode = "rgmii";
  3884. + phy-reset-gpios = <&gpio1 30 0>;
  3885. + status = "okay";
  3886. +};
  3887. +
  3888. +&gpmi {
  3889. + pinctrl-names = "default";
  3890. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  3891. + status = "okay";
  3892. +};
  3893. +
  3894. +&i2c1 {
  3895. + clock-frequency = <100000>;
  3896. + pinctrl-names = "default";
  3897. + pinctrl-0 = <&pinctrl_i2c1>;
  3898. + status = "okay";
  3899. +
  3900. + eeprom1: eeprom@50 {
  3901. + compatible = "atmel,24c02";
  3902. + reg = <0x50>;
  3903. + pagesize = <16>;
  3904. + };
  3905. +
  3906. + eeprom2: eeprom@51 {
  3907. + compatible = "atmel,24c02";
  3908. + reg = <0x51>;
  3909. + pagesize = <16>;
  3910. + };
  3911. +
  3912. + eeprom3: eeprom@52 {
  3913. + compatible = "atmel,24c02";
  3914. + reg = <0x52>;
  3915. + pagesize = <16>;
  3916. + };
  3917. +
  3918. + eeprom4: eeprom@53 {
  3919. + compatible = "atmel,24c02";
  3920. + reg = <0x53>;
  3921. + pagesize = <16>;
  3922. + };
  3923. +
  3924. + gpio: pca9555@23 {
  3925. + compatible = "nxp,pca9555";
  3926. + reg = <0x23>;
  3927. + gpio-controller;
  3928. + #gpio-cells = <2>;
  3929. + };
  3930. +
  3931. + hwmon: gsc@29 {
  3932. + compatible = "gw,gsp";
  3933. + reg = <0x29>;
  3934. + };
  3935. +
  3936. + rtc: ds1672@68 {
  3937. + compatible = "dallas,ds1672";
  3938. + reg = <0x68>;
  3939. + };
  3940. +};
  3941. +
  3942. +&i2c2 {
  3943. + clock-frequency = <100000>;
  3944. + pinctrl-names = "default";
  3945. + pinctrl-0 = <&pinctrl_i2c2>;
  3946. + status = "okay";
  3947. +
  3948. + pciswitch: pex8609@3f {
  3949. + compatible = "plx,pex8609";
  3950. + reg = <0x3f>;
  3951. + };
  3952. +
  3953. + pmic: ltc3676@3c {
  3954. + compatible = "ltc,ltc3676";
  3955. + reg = <0x3c>;
  3956. +
  3957. + regulators {
  3958. + sw1_reg: ltc3676__sw1 {
  3959. + regulator-min-microvolt = <1175000>;
  3960. + regulator-max-microvolt = <1175000>;
  3961. + regulator-boot-on;
  3962. + regulator-always-on;
  3963. + };
  3964. +
  3965. + sw2_reg: ltc3676__sw2 {
  3966. + regulator-min-microvolt = <1800000>;
  3967. + regulator-max-microvolt = <1800000>;
  3968. + regulator-boot-on;
  3969. + regulator-always-on;
  3970. + };
  3971. +
  3972. + sw3_reg: ltc3676__sw3 {
  3973. + regulator-min-microvolt = <1175000>;
  3974. + regulator-max-microvolt = <1175000>;
  3975. + regulator-boot-on;
  3976. + regulator-always-on;
  3977. + };
  3978. +
  3979. + sw4_reg: ltc3676__sw4 {
  3980. + regulator-min-microvolt = <1500000>;
  3981. + regulator-max-microvolt = <1500000>;
  3982. + regulator-boot-on;
  3983. + regulator-always-on;
  3984. + };
  3985. +
  3986. + ldo2_reg: ltc3676__ldo2 {
  3987. + regulator-min-microvolt = <2500000>;
  3988. + regulator-max-microvolt = <2500000>;
  3989. + regulator-boot-on;
  3990. + regulator-always-on;
  3991. + };
  3992. +
  3993. + ldo3_reg: ltc3676__ldo3 {
  3994. + regulator-min-microvolt = <1800000>;
  3995. + regulator-max-microvolt = <1800000>;
  3996. + regulator-boot-on;
  3997. + regulator-always-on;
  3998. + };
  3999. +
  4000. + ldo4_reg: ltc3676__ldo4 {
  4001. + regulator-min-microvolt = <3000000>;
  4002. + regulator-max-microvolt = <3000000>;
  4003. + };
  4004. + };
  4005. + };
  4006. +};
  4007. +
  4008. +&i2c3 {
  4009. + clock-frequency = <100000>;
  4010. + pinctrl-names = "default";
  4011. + pinctrl-0 = <&pinctrl_i2c3>;
  4012. + status = "okay";
  4013. +
  4014. + accelerometer: fxos8700@1e {
  4015. + compatible = "fsl,fxos8700";
  4016. + reg = <0x13>;
  4017. + };
  4018. +
  4019. + codec: sgtl5000@0a {
  4020. + compatible = "fsl,sgtl5000";
  4021. + reg = <0x0a>;
  4022. + clocks = <&clks 169>;
  4023. + VDDA-supply = <&reg_1p8v>;
  4024. + VDDIO-supply = <&reg_3p3v>;
  4025. + };
  4026. +
  4027. + touchscreen: egalax_ts@04 {
  4028. + compatible = "eeti,egalax_ts";
  4029. + reg = <0x04>;
  4030. + interrupt-parent = <&gpio7>;
  4031. + interrupts = <12 2>; /* gpio7_12 active low */
  4032. + wakeup-gpios = <&gpio7 12 0>;
  4033. + };
  4034. +
  4035. + videoin: adv7180@20 {
  4036. + compatible = "adi,adv7180";
  4037. + reg = <0x20>;
  4038. + };
  4039. +};
  4040. +
  4041. +&iomuxc {
  4042. + pinctrl-names = "default";
  4043. + pinctrl-0 = <&pinctrl_hog>;
  4044. +
  4045. + imx6qdl-gw52xx {
  4046. + pinctrl_hog: hoggrp {
  4047. + fsl,pins = <
  4048. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* MEZZ_DIO0 */
  4049. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* MEZZ_DIO1 */
  4050. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  4051. + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x80000000 /* VIDDEC_PDN# */
  4052. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* PHY Reset */
  4053. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE_RST# */
  4054. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_PWDN */
  4055. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  4056. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  4057. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* USB_SEL_PCI */
  4058. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  4059. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  4060. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  4061. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  4062. + MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x80000000 /* LVDS_TCH# */
  4063. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 /* SD3_CD# */
  4064. + MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x80000000 /* UART2_EN# */
  4065. + >;
  4066. + };
  4067. +
  4068. + pinctrl_audmux: audmuxgrp {
  4069. + fsl,pins = <
  4070. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  4071. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  4072. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  4073. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  4074. + >;
  4075. + };
  4076. +
  4077. + pinctrl_enet: enetgrp {
  4078. + fsl,pins = <
  4079. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  4080. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  4081. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  4082. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  4083. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  4084. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  4085. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  4086. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  4087. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  4088. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  4089. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  4090. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  4091. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  4092. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  4093. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  4094. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  4095. + >;
  4096. + };
  4097. +
  4098. + pinctrl_gpmi_nand: gpminandgrp {
  4099. + fsl,pins = <
  4100. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  4101. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  4102. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  4103. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  4104. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  4105. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  4106. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  4107. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  4108. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  4109. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  4110. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  4111. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  4112. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  4113. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  4114. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  4115. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  4116. + >;
  4117. + };
  4118. +
  4119. + pinctrl_i2c1: i2c1grp {
  4120. + fsl,pins = <
  4121. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  4122. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  4123. + >;
  4124. + };
  4125. +
  4126. + pinctrl_i2c2: i2c2grp {
  4127. + fsl,pins = <
  4128. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  4129. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  4130. + >;
  4131. + };
  4132. +
  4133. + pinctrl_i2c3: i2c3grp {
  4134. + fsl,pins = <
  4135. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  4136. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  4137. + >;
  4138. + };
  4139. +
  4140. + pinctrl_pwm4: pwm4grp {
  4141. + fsl,pins = <
  4142. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  4143. + >;
  4144. + };
  4145. +
  4146. + pinctrl_uart1: uart1grp {
  4147. + fsl,pins = <
  4148. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  4149. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  4150. + >;
  4151. + };
  4152. +
  4153. + pinctrl_uart2: uart2grp {
  4154. + fsl,pins = <
  4155. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  4156. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  4157. + >;
  4158. + };
  4159. +
  4160. + pinctrl_uart5: uart5grp {
  4161. + fsl,pins = <
  4162. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  4163. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  4164. + >;
  4165. + };
  4166. +
  4167. + pinctrl_usbotg: usbotggrp {
  4168. + fsl,pins = <
  4169. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  4170. + >;
  4171. + };
  4172. +
  4173. + pinctrl_usdhc3: usdhc3grp {
  4174. + fsl,pins = <
  4175. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  4176. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  4177. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  4178. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  4179. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  4180. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  4181. + >;
  4182. + };
  4183. + };
  4184. +};
  4185. +
  4186. +&ldb {
  4187. + status = "okay";
  4188. +
  4189. + lvds-channel@0 {
  4190. + fsl,data-mapping = "spwg";
  4191. + fsl,data-width = <18>;
  4192. + status = "okay";
  4193. +
  4194. + display-timings {
  4195. + native-mode = <&timing0>;
  4196. + timing0: hsd100pxn1 {
  4197. + clock-frequency = <65000000>;
  4198. + hactive = <1024>;
  4199. + vactive = <768>;
  4200. + hback-porch = <220>;
  4201. + hfront-porch = <40>;
  4202. + vback-porch = <21>;
  4203. + vfront-porch = <7>;
  4204. + hsync-len = <60>;
  4205. + vsync-len = <10>;
  4206. + };
  4207. + };
  4208. + };
  4209. +};
  4210. +
  4211. +&pcie {
  4212. + reset-gpio = <&gpio1 29 0>;
  4213. + status = "okay";
  4214. +};
  4215. +
  4216. +&pwm4 {
  4217. + pinctrl-names = "default";
  4218. + pinctrl-0 = <&pinctrl_pwm4>;
  4219. + status = "okay";
  4220. +};
  4221. +
  4222. +&ssi1 {
  4223. + fsl,mode = "i2s-slave";
  4224. + status = "okay";
  4225. +};
  4226. +
  4227. +&uart1 {
  4228. + pinctrl-names = "default";
  4229. + pinctrl-0 = <&pinctrl_uart1>;
  4230. + status = "okay";
  4231. +};
  4232. +
  4233. +&uart2 {
  4234. + pinctrl-names = "default";
  4235. + pinctrl-0 = <&pinctrl_uart2>;
  4236. + status = "okay";
  4237. +};
  4238. +
  4239. +&uart5 {
  4240. + pinctrl-names = "default";
  4241. + pinctrl-0 = <&pinctrl_uart5>;
  4242. + status = "okay";
  4243. +};
  4244. +
  4245. +&usbotg {
  4246. + vbus-supply = <&reg_usb_otg_vbus>;
  4247. + pinctrl-names = "default";
  4248. + pinctrl-0 = <&pinctrl_usbotg>;
  4249. + disable-over-current;
  4250. + status = "okay";
  4251. +};
  4252. +
  4253. +&usbh1 {
  4254. + status = "okay";
  4255. +};
  4256. +
  4257. +&usdhc3 {
  4258. + pinctrl-names = "default";
  4259. + pinctrl-0 = <&pinctrl_usdhc3>;
  4260. + cd-gpios = <&gpio7 0 0>;
  4261. + vmmc-supply = <&reg_3p3v>;
  4262. + status = "okay";
  4263. +};
  4264. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
  4265. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  4266. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi 2014-09-11 18:05:52.642000568 +0200
  4267. @@ -0,0 +1,572 @@
  4268. +/*
  4269. + * Copyright 2013 Gateworks Corporation
  4270. + *
  4271. + * The code contained herein is licensed under the GNU General Public
  4272. + * License. You may obtain a copy of the GNU General Public License
  4273. + * Version 2 or later at the following locations:
  4274. + *
  4275. + * http://www.opensource.org/licenses/gpl-license.html
  4276. + * http://www.gnu.org/copyleft/gpl.html
  4277. + */
  4278. +
  4279. +/ {
  4280. + /* these are used by bootloader for disabling nodes */
  4281. + aliases {
  4282. + can0 = &can1;
  4283. + ethernet0 = &fec;
  4284. + ethernet1 = &eth1;
  4285. + led0 = &led0;
  4286. + led1 = &led1;
  4287. + led2 = &led2;
  4288. + nand = &gpmi;
  4289. + sky2 = &eth1;
  4290. + ssi0 = &ssi1;
  4291. + usb0 = &usbh1;
  4292. + usb1 = &usbotg;
  4293. + usdhc2 = &usdhc3;
  4294. + };
  4295. +
  4296. + chosen {
  4297. + bootargs = "console=ttymxc1,115200";
  4298. + };
  4299. +
  4300. + backlight {
  4301. + compatible = "pwm-backlight";
  4302. + pwms = <&pwm4 0 5000000>;
  4303. + brightness-levels = <0 4 8 16 32 64 128 255>;
  4304. + default-brightness-level = <7>;
  4305. + };
  4306. +
  4307. + leds {
  4308. + compatible = "gpio-leds";
  4309. +
  4310. + led0: user1 {
  4311. + label = "user1";
  4312. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  4313. + default-state = "on";
  4314. + linux,default-trigger = "heartbeat";
  4315. + };
  4316. +
  4317. + led1: user2 {
  4318. + label = "user2";
  4319. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  4320. + default-state = "off";
  4321. + };
  4322. +
  4323. + led2: user3 {
  4324. + label = "user3";
  4325. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  4326. + default-state = "off";
  4327. + };
  4328. + };
  4329. +
  4330. + memory {
  4331. + reg = <0x10000000 0x40000000>;
  4332. + };
  4333. +
  4334. + pps {
  4335. + compatible = "pps-gpio";
  4336. + gpios = <&gpio1 26 0>;
  4337. + status = "okay";
  4338. + };
  4339. +
  4340. + regulators {
  4341. + compatible = "simple-bus";
  4342. + #address-cells = <1>;
  4343. + #size-cells = <0>;
  4344. +
  4345. + reg_1p0v: regulator@0 {
  4346. + compatible = "regulator-fixed";
  4347. + reg = <0>;
  4348. + regulator-name = "1P0V";
  4349. + regulator-min-microvolt = <1000000>;
  4350. + regulator-max-microvolt = <1000000>;
  4351. + regulator-always-on;
  4352. + };
  4353. +
  4354. + /* remove when pmic 1p8 regulator available */
  4355. + reg_1p8v: regulator@1 {
  4356. + compatible = "regulator-fixed";
  4357. + reg = <1>;
  4358. + regulator-name = "1P8V";
  4359. + regulator-min-microvolt = <1800000>;
  4360. + regulator-max-microvolt = <1800000>;
  4361. + regulator-always-on;
  4362. + };
  4363. +
  4364. + reg_3p3v: regulator@2 {
  4365. + compatible = "regulator-fixed";
  4366. + reg = <2>;
  4367. + regulator-name = "3P3V";
  4368. + regulator-min-microvolt = <3300000>;
  4369. + regulator-max-microvolt = <3300000>;
  4370. + regulator-always-on;
  4371. + };
  4372. +
  4373. + reg_usb_h1_vbus: regulator@3 {
  4374. + compatible = "regulator-fixed";
  4375. + reg = <3>;
  4376. + regulator-name = "usb_h1_vbus";
  4377. + regulator-min-microvolt = <5000000>;
  4378. + regulator-max-microvolt = <5000000>;
  4379. + regulator-always-on;
  4380. + };
  4381. +
  4382. + reg_usb_otg_vbus: regulator@4 {
  4383. + compatible = "regulator-fixed";
  4384. + reg = <4>;
  4385. + regulator-name = "usb_otg_vbus";
  4386. + regulator-min-microvolt = <5000000>;
  4387. + regulator-max-microvolt = <5000000>;
  4388. + gpio = <&gpio3 22 0>;
  4389. + enable-active-high;
  4390. + };
  4391. + };
  4392. +
  4393. + sound {
  4394. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  4395. + "fsl,imx-audio-sgtl5000";
  4396. + model = "imx6q-sabrelite-sgtl5000";
  4397. + ssi-controller = <&ssi1>;
  4398. + audio-codec = <&codec>;
  4399. + audio-routing =
  4400. + "MIC_IN", "Mic Jack",
  4401. + "Mic Jack", "Mic Bias",
  4402. + "Headphone Jack", "HP_OUT";
  4403. + mux-int-port = <1>;
  4404. + mux-ext-port = <4>;
  4405. + };
  4406. +};
  4407. +
  4408. +&audmux {
  4409. + pinctrl-names = "default";
  4410. + pinctrl-0 = <&pinctrl_audmux>;
  4411. + status = "okay";
  4412. +};
  4413. +
  4414. +&can1 {
  4415. + pinctrl-names = "default";
  4416. + pinctrl-0 = <&pinctrl_flexcan1>;
  4417. + status = "okay";
  4418. +};
  4419. +
  4420. +&fec {
  4421. + pinctrl-names = "default";
  4422. + pinctrl-0 = <&pinctrl_enet>;
  4423. + phy-mode = "rgmii";
  4424. + phy-reset-gpios = <&gpio1 30 0>;
  4425. + status = "okay";
  4426. +};
  4427. +
  4428. +&gpmi {
  4429. + pinctrl-names = "default";
  4430. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  4431. + status = "okay";
  4432. +};
  4433. +
  4434. +&i2c1 {
  4435. + clock-frequency = <100000>;
  4436. + pinctrl-names = "default";
  4437. + pinctrl-0 = <&pinctrl_i2c1>;
  4438. + status = "okay";
  4439. +
  4440. + eeprom1: eeprom@50 {
  4441. + compatible = "atmel,24c02";
  4442. + reg = <0x50>;
  4443. + pagesize = <16>;
  4444. + };
  4445. +
  4446. + eeprom2: eeprom@51 {
  4447. + compatible = "atmel,24c02";
  4448. + reg = <0x51>;
  4449. + pagesize = <16>;
  4450. + };
  4451. +
  4452. + eeprom3: eeprom@52 {
  4453. + compatible = "atmel,24c02";
  4454. + reg = <0x52>;
  4455. + pagesize = <16>;
  4456. + };
  4457. +
  4458. + eeprom4: eeprom@53 {
  4459. + compatible = "atmel,24c02";
  4460. + reg = <0x53>;
  4461. + pagesize = <16>;
  4462. + };
  4463. +
  4464. + gpio: pca9555@23 {
  4465. + compatible = "nxp,pca9555";
  4466. + reg = <0x23>;
  4467. + gpio-controller;
  4468. + #gpio-cells = <2>;
  4469. + };
  4470. +
  4471. + hwmon: gsc@29 {
  4472. + compatible = "gw,gsp";
  4473. + reg = <0x29>;
  4474. + };
  4475. +
  4476. + rtc: ds1672@68 {
  4477. + compatible = "dallas,ds1672";
  4478. + reg = <0x68>;
  4479. + };
  4480. +};
  4481. +
  4482. +&i2c2 {
  4483. + clock-frequency = <100000>;
  4484. + pinctrl-names = "default";
  4485. + pinctrl-0 = <&pinctrl_i2c2>;
  4486. + status = "okay";
  4487. +
  4488. + pciclkgen: si53156@6b {
  4489. + compatible = "sil,si53156";
  4490. + reg = <0x6b>;
  4491. + };
  4492. +
  4493. + pciswitch: pex8606@3f {
  4494. + compatible = "plx,pex8606";
  4495. + reg = <0x3f>;
  4496. + };
  4497. +
  4498. + pmic: ltc3676@3c {
  4499. + compatible = "ltc,ltc3676";
  4500. + reg = <0x3c>;
  4501. +
  4502. + regulators {
  4503. + /* VDD_SOC */
  4504. + sw1_reg: ltc3676__sw1 {
  4505. + regulator-min-microvolt = <1175000>;
  4506. + regulator-max-microvolt = <1175000>;
  4507. + regulator-boot-on;
  4508. + regulator-always-on;
  4509. + };
  4510. +
  4511. + /* VDD_1P8 */
  4512. + sw2_reg: ltc3676__sw2 {
  4513. + regulator-min-microvolt = <1800000>;
  4514. + regulator-max-microvolt = <1800000>;
  4515. + regulator-boot-on;
  4516. + regulator-always-on;
  4517. + };
  4518. +
  4519. + /* VDD_ARM */
  4520. + sw3_reg: ltc3676__sw3 {
  4521. + regulator-min-microvolt = <1175000>;
  4522. + regulator-max-microvolt = <1175000>;
  4523. + regulator-boot-on;
  4524. + regulator-always-on;
  4525. + };
  4526. +
  4527. + /* VDD_DDR */
  4528. + sw4_reg: ltc3676__sw4 {
  4529. + regulator-min-microvolt = <1500000>;
  4530. + regulator-max-microvolt = <1500000>;
  4531. + regulator-boot-on;
  4532. + regulator-always-on;
  4533. + };
  4534. +
  4535. + /* VDD_2P5 */
  4536. + ldo2_reg: ltc3676__ldo2 {
  4537. + regulator-min-microvolt = <2500000>;
  4538. + regulator-max-microvolt = <2500000>;
  4539. + regulator-boot-on;
  4540. + regulator-always-on;
  4541. + };
  4542. +
  4543. + /* VDD_1P8 */
  4544. + ldo3_reg: ltc3676__ldo3 {
  4545. + regulator-min-microvolt = <1800000>;
  4546. + regulator-max-microvolt = <1800000>;
  4547. + regulator-boot-on;
  4548. + regulator-always-on;
  4549. + };
  4550. +
  4551. + /* VDD_HIGH */
  4552. + ldo4_reg: ltc3676__ldo4 {
  4553. + regulator-min-microvolt = <3000000>;
  4554. + regulator-max-microvolt = <3000000>;
  4555. + };
  4556. + };
  4557. + };
  4558. +};
  4559. +
  4560. +&i2c3 {
  4561. + clock-frequency = <100000>;
  4562. + pinctrl-names = "default";
  4563. + pinctrl-0 = <&pinctrl_i2c3>;
  4564. + status = "okay";
  4565. +
  4566. + accelerometer: fxos8700@1e {
  4567. + compatible = "fsl,fxos8700";
  4568. + reg = <0x1e>;
  4569. + };
  4570. +
  4571. + codec: sgtl5000@0a {
  4572. + compatible = "fsl,sgtl5000";
  4573. + reg = <0x0a>;
  4574. + clocks = <&clks 201>;
  4575. + VDDA-supply = <&reg_1p8v>;
  4576. + VDDIO-supply = <&reg_3p3v>;
  4577. + };
  4578. +
  4579. + hdmiin: adv7611@4c {
  4580. + compatible = "adi,adv7611";
  4581. + reg = <0x4c>;
  4582. + };
  4583. +
  4584. + touchscreen: egalax_ts@04 {
  4585. + compatible = "eeti,egalax_ts";
  4586. + reg = <0x04>;
  4587. + interrupt-parent = <&gpio1>;
  4588. + interrupts = <11 2>; /* gpio1_11 active low */
  4589. + wakeup-gpios = <&gpio1 11 0>;
  4590. + };
  4591. +
  4592. + videoout: adv7393@2a {
  4593. + compatible = "adi,adv7393";
  4594. + reg = <0x2a>;
  4595. + };
  4596. +
  4597. + videoin: adv7180@20 {
  4598. + compatible = "adi,adv7180";
  4599. + reg = <0x20>;
  4600. + };
  4601. +};
  4602. +
  4603. +&iomuxc {
  4604. + pinctrl-names = "default";
  4605. + pinctrl-0 = <&pinctrl_hog>;
  4606. +
  4607. + imx6qdl-gw53xx {
  4608. + pinctrl_hog: hoggrp {
  4609. + fsl,pins = <
  4610. + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x80000000 /* PCIE6EXP_DIO0 */
  4611. + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x80000000 /* PCIE6EXP_DIO1 */
  4612. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  4613. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000 /* GPS_SHDN */
  4614. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  4615. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  4616. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  4617. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  4618. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* CAN_STBY */
  4619. + MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x80000000 /* PMIC_IRQ# */
  4620. + MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x80000000 /* HUB_RST# */
  4621. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* PCIE_WDIS# */
  4622. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x80000000 /* ACCEL_IRQ# */
  4623. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  4624. + MX6QDL_PAD_KEY_COL4__GPIO4_IO14 0x80000000 /* USBOTG_OC# */
  4625. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  4626. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  4627. + MX6QDL_PAD_SD2_CMD__GPIO1_IO11 0x80000000 /* TOUCH_IRQ# */
  4628. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000 /* SD3_DET# */
  4629. + >;
  4630. + };
  4631. +
  4632. + pinctrl_audmux: audmuxgrp {
  4633. + fsl,pins = <
  4634. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  4635. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  4636. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  4637. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  4638. + >;
  4639. + };
  4640. +
  4641. + pinctrl_enet: enetgrp {
  4642. + fsl,pins = <
  4643. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  4644. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  4645. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  4646. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  4647. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  4648. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  4649. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  4650. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  4651. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  4652. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  4653. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  4654. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  4655. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  4656. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  4657. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  4658. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  4659. + >;
  4660. + };
  4661. +
  4662. + pinctrl_flexcan1: flexcan1grp {
  4663. + fsl,pins = <
  4664. + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  4665. + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  4666. + >;
  4667. + };
  4668. +
  4669. + pinctrl_gpmi_nand: gpminandgrp {
  4670. + fsl,pins = <
  4671. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  4672. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  4673. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  4674. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  4675. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  4676. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  4677. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  4678. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  4679. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  4680. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  4681. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  4682. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  4683. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  4684. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  4685. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  4686. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  4687. + >;
  4688. + };
  4689. +
  4690. + pinctrl_i2c1: i2c1grp {
  4691. + fsl,pins = <
  4692. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  4693. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  4694. + >;
  4695. + };
  4696. +
  4697. + pinctrl_i2c2: i2c2grp {
  4698. + fsl,pins = <
  4699. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  4700. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  4701. + >;
  4702. + };
  4703. +
  4704. + pinctrl_i2c3: i2c3grp {
  4705. + fsl,pins = <
  4706. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  4707. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  4708. + >;
  4709. + };
  4710. +
  4711. + pinctrl_pwm4: pwm4grp {
  4712. + fsl,pins = <
  4713. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  4714. + >;
  4715. + };
  4716. +
  4717. + pinctrl_uart1: uart1grp {
  4718. + fsl,pins = <
  4719. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  4720. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  4721. + >;
  4722. + };
  4723. +
  4724. + pinctrl_uart2: uart2grp {
  4725. + fsl,pins = <
  4726. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  4727. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  4728. + >;
  4729. + };
  4730. +
  4731. + pinctrl_uart5: uart5grp {
  4732. + fsl,pins = <
  4733. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  4734. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  4735. + >;
  4736. + };
  4737. +
  4738. + pinctrl_usbotg: usbotggrp {
  4739. + fsl,pins = <
  4740. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  4741. + >;
  4742. + };
  4743. +
  4744. + pinctrl_usdhc3: usdhc3grp {
  4745. + fsl,pins = <
  4746. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  4747. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  4748. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  4749. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  4750. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  4751. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  4752. + >;
  4753. + };
  4754. + };
  4755. +};
  4756. +
  4757. +&ldb {
  4758. + status = "okay";
  4759. +
  4760. + lvds-channel@1 {
  4761. + fsl,data-mapping = "spwg";
  4762. + fsl,data-width = <18>;
  4763. + status = "okay";
  4764. +
  4765. + display-timings {
  4766. + native-mode = <&timing0>;
  4767. + timing0: hsd100pxn1 {
  4768. + clock-frequency = <65000000>;
  4769. + hactive = <1024>;
  4770. + vactive = <768>;
  4771. + hback-porch = <220>;
  4772. + hfront-porch = <40>;
  4773. + vback-porch = <21>;
  4774. + vfront-porch = <7>;
  4775. + hsync-len = <60>;
  4776. + vsync-len = <10>;
  4777. + };
  4778. + };
  4779. + };
  4780. +};
  4781. +
  4782. +&pcie {
  4783. + reset-gpio = <&gpio1 29 0>;
  4784. + status = "okay";
  4785. +
  4786. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  4787. + compatible = "marvell,sky2";
  4788. + };
  4789. +};
  4790. +
  4791. +&pwm4 {
  4792. + pinctrl-names = "default";
  4793. + pinctrl-0 = <&pinctrl_pwm4>;
  4794. + status = "okay";
  4795. +};
  4796. +
  4797. +&ssi1 {
  4798. + fsl,mode = "i2s-slave";
  4799. + status = "okay";
  4800. +};
  4801. +
  4802. +&uart1 {
  4803. + pinctrl-names = "default";
  4804. + pinctrl-0 = <&pinctrl_uart1>;
  4805. + status = "okay";
  4806. +};
  4807. +
  4808. +&uart2 {
  4809. + pinctrl-names = "default";
  4810. + pinctrl-0 = <&pinctrl_uart2>;
  4811. + status = "okay";
  4812. +};
  4813. +
  4814. +&uart5 {
  4815. + pinctrl-names = "default";
  4816. + pinctrl-0 = <&pinctrl_uart5>;
  4817. + status = "okay";
  4818. +};
  4819. +
  4820. +&usbotg {
  4821. + vbus-supply = <&reg_usb_otg_vbus>;
  4822. + pinctrl-names = "default";
  4823. + pinctrl-0 = <&pinctrl_usbotg>;
  4824. + disable-over-current;
  4825. + status = "okay";
  4826. +};
  4827. +
  4828. +&usbh1 {
  4829. + vbus-supply = <&reg_usb_h1_vbus>;
  4830. + status = "okay";
  4831. +};
  4832. +
  4833. +&usdhc3 {
  4834. + pinctrl-names = "default";
  4835. + pinctrl-0 = <&pinctrl_usdhc3>;
  4836. + cd-gpios = <&gpio7 0 0>;
  4837. + vmmc-supply = <&reg_3p3v>;
  4838. + status = "okay";
  4839. +};
  4840. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
  4841. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi 1970-01-01 01:00:00.000000000 +0100
  4842. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi 2014-09-11 18:05:52.642000568 +0200
  4843. @@ -0,0 +1,599 @@
  4844. +/*
  4845. + * Copyright 2013 Gateworks Corporation
  4846. + *
  4847. + * The code contained herein is licensed under the GNU General Public
  4848. + * License. You may obtain a copy of the GNU General Public License
  4849. + * Version 2 or later at the following locations:
  4850. + *
  4851. + * http://www.opensource.org/licenses/gpl-license.html
  4852. + * http://www.gnu.org/copyleft/gpl.html
  4853. + */
  4854. +
  4855. +/ {
  4856. + /* these are used by bootloader for disabling nodes */
  4857. + aliases {
  4858. + can0 = &can1;
  4859. + ethernet0 = &fec;
  4860. + ethernet1 = &eth1;
  4861. + led0 = &led0;
  4862. + led1 = &led1;
  4863. + led2 = &led2;
  4864. + nand = &gpmi;
  4865. + sky2 = &eth1;
  4866. + ssi0 = &ssi1;
  4867. + usb0 = &usbh1;
  4868. + usb1 = &usbotg;
  4869. + usdhc2 = &usdhc3;
  4870. + };
  4871. +
  4872. + chosen {
  4873. + bootargs = "console=ttymxc1,115200";
  4874. + };
  4875. +
  4876. + backlight {
  4877. + compatible = "pwm-backlight";
  4878. + pwms = <&pwm4 0 5000000>;
  4879. + brightness-levels = <0 4 8 16 32 64 128 255>;
  4880. + default-brightness-level = <7>;
  4881. + };
  4882. +
  4883. + leds {
  4884. + compatible = "gpio-leds";
  4885. +
  4886. + led0: user1 {
  4887. + label = "user1";
  4888. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  4889. + default-state = "on";
  4890. + linux,default-trigger = "heartbeat";
  4891. + };
  4892. +
  4893. + led1: user2 {
  4894. + label = "user2";
  4895. + gpios = <&gpio4 7 0>; /* 103 -> MX6_PANLEDR */
  4896. + default-state = "off";
  4897. + };
  4898. +
  4899. + led2: user3 {
  4900. + label = "user3";
  4901. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  4902. + default-state = "off";
  4903. + };
  4904. + };
  4905. +
  4906. + memory {
  4907. + reg = <0x10000000 0x40000000>;
  4908. + };
  4909. +
  4910. + pps {
  4911. + compatible = "pps-gpio";
  4912. + gpios = <&gpio1 26 0>;
  4913. + status = "okay";
  4914. + };
  4915. +
  4916. + regulators {
  4917. + compatible = "simple-bus";
  4918. + #address-cells = <1>;
  4919. + #size-cells = <0>;
  4920. +
  4921. + reg_1p0v: regulator@0 {
  4922. + compatible = "regulator-fixed";
  4923. + reg = <0>;
  4924. + regulator-name = "1P0V";
  4925. + regulator-min-microvolt = <1000000>;
  4926. + regulator-max-microvolt = <1000000>;
  4927. + regulator-always-on;
  4928. + };
  4929. +
  4930. + reg_3p3v: regulator@1 {
  4931. + compatible = "regulator-fixed";
  4932. + reg = <1>;
  4933. + regulator-name = "3P3V";
  4934. + regulator-min-microvolt = <3300000>;
  4935. + regulator-max-microvolt = <3300000>;
  4936. + regulator-always-on;
  4937. + };
  4938. +
  4939. + reg_usb_h1_vbus: regulator@2 {
  4940. + compatible = "regulator-fixed";
  4941. + reg = <2>;
  4942. + regulator-name = "usb_h1_vbus";
  4943. + regulator-min-microvolt = <5000000>;
  4944. + regulator-max-microvolt = <5000000>;
  4945. + regulator-always-on;
  4946. + };
  4947. +
  4948. + reg_usb_otg_vbus: regulator@3 {
  4949. + compatible = "regulator-fixed";
  4950. + reg = <3>;
  4951. + regulator-name = "usb_otg_vbus";
  4952. + regulator-min-microvolt = <5000000>;
  4953. + regulator-max-microvolt = <5000000>;
  4954. + gpio = <&gpio3 22 0>;
  4955. + enable-active-high;
  4956. + };
  4957. + };
  4958. +
  4959. + sound {
  4960. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  4961. + "fsl,imx-audio-sgtl5000";
  4962. + model = "imx6q-sabrelite-sgtl5000";
  4963. + ssi-controller = <&ssi1>;
  4964. + audio-codec = <&codec>;
  4965. + audio-routing =
  4966. + "MIC_IN", "Mic Jack",
  4967. + "Mic Jack", "Mic Bias",
  4968. + "Headphone Jack", "HP_OUT";
  4969. + mux-int-port = <1>;
  4970. + mux-ext-port = <4>;
  4971. + };
  4972. +};
  4973. +
  4974. +&audmux {
  4975. + pinctrl-names = "default";
  4976. + pinctrl-0 = <&pinctrl_audmux>; /* AUD4<->sgtl5000 */
  4977. + status = "okay";
  4978. +};
  4979. +
  4980. +&can1 {
  4981. + pinctrl-names = "default";
  4982. + pinctrl-0 = <&pinctrl_flexcan1>;
  4983. + status = "okay";
  4984. +};
  4985. +
  4986. +&fec {
  4987. + pinctrl-names = "default";
  4988. + pinctrl-0 = <&pinctrl_enet>;
  4989. + phy-mode = "rgmii";
  4990. + phy-reset-gpios = <&gpio1 30 0>;
  4991. + status = "okay";
  4992. +};
  4993. +
  4994. +&gpmi {
  4995. + pinctrl-names = "default";
  4996. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  4997. + status = "okay";
  4998. +};
  4999. +
  5000. +&i2c1 {
  5001. + clock-frequency = <100000>;
  5002. + pinctrl-names = "default";
  5003. + pinctrl-0 = <&pinctrl_i2c1>;
  5004. + status = "okay";
  5005. +
  5006. + eeprom1: eeprom@50 {
  5007. + compatible = "atmel,24c02";
  5008. + reg = <0x50>;
  5009. + pagesize = <16>;
  5010. + };
  5011. +
  5012. + eeprom2: eeprom@51 {
  5013. + compatible = "atmel,24c02";
  5014. + reg = <0x51>;
  5015. + pagesize = <16>;
  5016. + };
  5017. +
  5018. + eeprom3: eeprom@52 {
  5019. + compatible = "atmel,24c02";
  5020. + reg = <0x52>;
  5021. + pagesize = <16>;
  5022. + };
  5023. +
  5024. + eeprom4: eeprom@53 {
  5025. + compatible = "atmel,24c02";
  5026. + reg = <0x53>;
  5027. + pagesize = <16>;
  5028. + };
  5029. +
  5030. + gpio: pca9555@23 {
  5031. + compatible = "nxp,pca9555";
  5032. + reg = <0x23>;
  5033. + gpio-controller;
  5034. + #gpio-cells = <2>;
  5035. + };
  5036. +
  5037. + hwmon: gsc@29 {
  5038. + compatible = "gw,gsp";
  5039. + reg = <0x29>;
  5040. + };
  5041. +
  5042. + rtc: ds1672@68 {
  5043. + compatible = "dallas,ds1672";
  5044. + reg = <0x68>;
  5045. + };
  5046. +};
  5047. +
  5048. +&i2c2 {
  5049. + clock-frequency = <100000>;
  5050. + pinctrl-names = "default";
  5051. + pinctrl-0 = <&pinctrl_i2c2>;
  5052. + status = "okay";
  5053. +
  5054. + pmic: pfuze100@08 {
  5055. + compatible = "fsl,pfuze100";
  5056. + reg = <0x08>;
  5057. +
  5058. + regulators {
  5059. + sw1a_reg: sw1ab {
  5060. + regulator-min-microvolt = <300000>;
  5061. + regulator-max-microvolt = <1875000>;
  5062. + regulator-boot-on;
  5063. + regulator-always-on;
  5064. + regulator-ramp-delay = <6250>;
  5065. + };
  5066. +
  5067. + sw1c_reg: sw1c {
  5068. + regulator-min-microvolt = <300000>;
  5069. + regulator-max-microvolt = <1875000>;
  5070. + regulator-boot-on;
  5071. + regulator-always-on;
  5072. + regulator-ramp-delay = <6250>;
  5073. + };
  5074. +
  5075. + sw2_reg: sw2 {
  5076. + regulator-min-microvolt = <800000>;
  5077. + regulator-max-microvolt = <3950000>;
  5078. + regulator-boot-on;
  5079. + regulator-always-on;
  5080. + };
  5081. +
  5082. + sw3a_reg: sw3a {
  5083. + regulator-min-microvolt = <400000>;
  5084. + regulator-max-microvolt = <1975000>;
  5085. + regulator-boot-on;
  5086. + regulator-always-on;
  5087. + };
  5088. +
  5089. + sw3b_reg: sw3b {
  5090. + regulator-min-microvolt = <400000>;
  5091. + regulator-max-microvolt = <1975000>;
  5092. + regulator-boot-on;
  5093. + regulator-always-on;
  5094. + };
  5095. +
  5096. + sw4_reg: sw4 {
  5097. + regulator-min-microvolt = <800000>;
  5098. + regulator-max-microvolt = <3300000>;
  5099. + };
  5100. +
  5101. + swbst_reg: swbst {
  5102. + regulator-min-microvolt = <5000000>;
  5103. + regulator-max-microvolt = <5150000>;
  5104. + };
  5105. +
  5106. + snvs_reg: vsnvs {
  5107. + regulator-min-microvolt = <1000000>;
  5108. + regulator-max-microvolt = <3000000>;
  5109. + regulator-boot-on;
  5110. + regulator-always-on;
  5111. + };
  5112. +
  5113. + vref_reg: vrefddr {
  5114. + regulator-boot-on;
  5115. + regulator-always-on;
  5116. + };
  5117. +
  5118. + vgen1_reg: vgen1 {
  5119. + regulator-min-microvolt = <800000>;
  5120. + regulator-max-microvolt = <1550000>;
  5121. + };
  5122. +
  5123. + vgen2_reg: vgen2 {
  5124. + regulator-min-microvolt = <800000>;
  5125. + regulator-max-microvolt = <1550000>;
  5126. + };
  5127. +
  5128. + vgen3_reg: vgen3 {
  5129. + regulator-min-microvolt = <1800000>;
  5130. + regulator-max-microvolt = <3300000>;
  5131. + };
  5132. +
  5133. + vgen4_reg: vgen4 {
  5134. + regulator-min-microvolt = <1800000>;
  5135. + regulator-max-microvolt = <3300000>;
  5136. + regulator-always-on;
  5137. + };
  5138. +
  5139. + vgen5_reg: vgen5 {
  5140. + regulator-min-microvolt = <1800000>;
  5141. + regulator-max-microvolt = <3300000>;
  5142. + regulator-always-on;
  5143. + };
  5144. +
  5145. + vgen6_reg: vgen6 {
  5146. + regulator-min-microvolt = <1800000>;
  5147. + regulator-max-microvolt = <3300000>;
  5148. + regulator-always-on;
  5149. + };
  5150. + };
  5151. + };
  5152. +
  5153. + pciswitch: pex8609@3f {
  5154. + compatible = "plx,pex8609";
  5155. + reg = <0x3f>;
  5156. + };
  5157. +
  5158. + pciclkgen: si52147@6b {
  5159. + compatible = "sil,si52147";
  5160. + reg = <0x6b>;
  5161. + };
  5162. +};
  5163. +
  5164. +&i2c3 {
  5165. + clock-frequency = <100000>;
  5166. + pinctrl-names = "default";
  5167. + pinctrl-0 = <&pinctrl_i2c3>;
  5168. + status = "okay";
  5169. +
  5170. + accelerometer: fxos8700@1e {
  5171. + compatible = "fsl,fxos8700";
  5172. + reg = <0x1e>;
  5173. + };
  5174. +
  5175. + codec: sgtl5000@0a {
  5176. + compatible = "fsl,sgtl5000";
  5177. + reg = <0x0a>;
  5178. + clocks = <&clks 201>;
  5179. + VDDA-supply = <&sw4_reg>;
  5180. + VDDIO-supply = <&reg_3p3v>;
  5181. + };
  5182. +
  5183. + hdmiin: adv7611@4c {
  5184. + compatible = "adi,adv7611";
  5185. + reg = <0x4c>;
  5186. + };
  5187. +
  5188. + touchscreen: egalax_ts@04 {
  5189. + compatible = "eeti,egalax_ts";
  5190. + reg = <0x04>;
  5191. + interrupt-parent = <&gpio7>;
  5192. + interrupts = <12 2>; /* gpio7_12 active low */
  5193. + wakeup-gpios = <&gpio7 12 0>;
  5194. + };
  5195. +
  5196. + videoout: adv7393@2a {
  5197. + compatible = "adi,adv7393";
  5198. + reg = <0x2a>;
  5199. + };
  5200. +
  5201. + videoin: adv7180@20 {
  5202. + compatible = "adi,adv7180";
  5203. + reg = <0x20>;
  5204. + };
  5205. +};
  5206. +
  5207. +&iomuxc {
  5208. + pinctrl-names = "default";
  5209. + pinctrl-0 = <&pinctrl_hog>;
  5210. +
  5211. + imx6qdl-gw54xx {
  5212. + pinctrl_hog: hoggrp {
  5213. + fsl,pins = <
  5214. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  5215. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000 /* SPINOR_CS0# */
  5216. + MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x80000000 /* GPS_PPS */
  5217. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  5218. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  5219. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  5220. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000 /* CAN_STBY */
  5221. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  5222. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  5223. + MX6QDL_PAD_KEY_ROW0__GPIO4_IO07 0x80000000 /* user2 led */
  5224. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  5225. + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000 /* USBHUB_RST# */
  5226. + MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x80000000 /* MIPI_DIO */
  5227. + >;
  5228. + };
  5229. +
  5230. + pinctrl_audmux: audmuxgrp {
  5231. + fsl,pins = <
  5232. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  5233. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  5234. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  5235. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  5236. + >;
  5237. + };
  5238. +
  5239. + pinctrl_enet: enetgrp {
  5240. + fsl,pins = <
  5241. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  5242. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  5243. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  5244. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  5245. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  5246. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  5247. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  5248. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  5249. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  5250. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  5251. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  5252. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  5253. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  5254. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  5255. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  5256. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  5257. + >;
  5258. + };
  5259. +
  5260. + pinctrl_flexcan1: flexcan1grp {
  5261. + fsl,pins = <
  5262. + MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x80000000
  5263. + MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX 0x80000000
  5264. + >;
  5265. + };
  5266. +
  5267. + pinctrl_gpmi_nand: gpminandgrp {
  5268. + fsl,pins = <
  5269. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  5270. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  5271. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  5272. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  5273. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  5274. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  5275. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  5276. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  5277. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  5278. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  5279. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  5280. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  5281. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  5282. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  5283. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  5284. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  5285. + >;
  5286. + };
  5287. +
  5288. + pinctrl_i2c1: i2c1grp {
  5289. + fsl,pins = <
  5290. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  5291. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  5292. + >;
  5293. + };
  5294. +
  5295. + pinctrl_i2c2: i2c2grp {
  5296. + fsl,pins = <
  5297. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  5298. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  5299. + >;
  5300. + };
  5301. +
  5302. + pinctrl_i2c3: i2c3grp {
  5303. + fsl,pins = <
  5304. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  5305. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  5306. + >;
  5307. + };
  5308. +
  5309. + pinctrl_pwm4: pwm4grp {
  5310. + fsl,pins = <
  5311. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  5312. + >;
  5313. + };
  5314. +
  5315. + pinctrl_uart1: uart1grp {
  5316. + fsl,pins = <
  5317. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  5318. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  5319. + >;
  5320. + };
  5321. +
  5322. + pinctrl_uart2: uart2grp {
  5323. + fsl,pins = <
  5324. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  5325. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  5326. + >;
  5327. + };
  5328. +
  5329. + pinctrl_uart5: uart5grp {
  5330. + fsl,pins = <
  5331. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  5332. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  5333. + >;
  5334. + };
  5335. +
  5336. + pinctrl_usbotg: usbotggrp {
  5337. + fsl,pins = <
  5338. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  5339. + >;
  5340. + };
  5341. +
  5342. + pinctrl_usdhc3: usdhc3grp {
  5343. + fsl,pins = <
  5344. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  5345. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  5346. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  5347. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  5348. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  5349. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  5350. + >;
  5351. + };
  5352. + };
  5353. +};
  5354. +
  5355. +&ldb {
  5356. + status = "okay";
  5357. +
  5358. + lvds-channel@1 {
  5359. + fsl,data-mapping = "spwg";
  5360. + fsl,data-width = <18>;
  5361. + status = "okay";
  5362. +
  5363. + display-timings {
  5364. + native-mode = <&timing0>;
  5365. + timing0: hsd100pxn1 {
  5366. + clock-frequency = <65000000>;
  5367. + hactive = <1024>;
  5368. + vactive = <768>;
  5369. + hback-porch = <220>;
  5370. + hfront-porch = <40>;
  5371. + vback-porch = <21>;
  5372. + vfront-porch = <7>;
  5373. + hsync-len = <60>;
  5374. + vsync-len = <10>;
  5375. + };
  5376. + };
  5377. + };
  5378. +};
  5379. +
  5380. +&pcie {
  5381. + reset-gpio = <&gpio1 29 0>;
  5382. + status = "okay";
  5383. +
  5384. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  5385. + compatible = "marvell,sky2";
  5386. + };
  5387. +};
  5388. +
  5389. +&pwm4 {
  5390. + pinctrl-names = "default";
  5391. + pinctrl-0 = <&pinctrl_pwm4>;
  5392. + status = "okay";
  5393. +};
  5394. +
  5395. +&ssi1 {
  5396. + fsl,mode = "i2s-slave";
  5397. + status = "okay";
  5398. +};
  5399. +
  5400. +&ssi2 {
  5401. + fsl,mode = "i2s-slave";
  5402. + status = "okay";
  5403. +};
  5404. +
  5405. +&uart1 {
  5406. + pinctrl-names = "default";
  5407. + pinctrl-0 = <&pinctrl_uart1>;
  5408. + status = "okay";
  5409. +};
  5410. +
  5411. +&uart2 {
  5412. + pinctrl-names = "default";
  5413. + pinctrl-0 = <&pinctrl_uart2>;
  5414. + status = "okay";
  5415. +};
  5416. +
  5417. +&uart5 {
  5418. + pinctrl-names = "default";
  5419. + pinctrl-0 = <&pinctrl_uart5>;
  5420. + status = "okay";
  5421. +};
  5422. +
  5423. +&usbotg {
  5424. + vbus-supply = <&reg_usb_otg_vbus>;
  5425. + pinctrl-names = "default";
  5426. + pinctrl-0 = <&pinctrl_usbotg>;
  5427. + disable-over-current;
  5428. + status = "okay";
  5429. +};
  5430. +
  5431. +&usbh1 {
  5432. + vbus-supply = <&reg_usb_h1_vbus>;
  5433. + status = "okay";
  5434. +};
  5435. +
  5436. +&usdhc3 {
  5437. + pinctrl-names = "default";
  5438. + pinctrl-0 = <&pinctrl_usdhc3>;
  5439. + cd-gpios = <&gpio7 0 0>;
  5440. + vmmc-supply = <&reg_3p3v>;
  5441. + status = "okay";
  5442. +};
  5443. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi
  5444. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi 1970-01-01 01:00:00.000000000 +0100
  5445. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi 2014-09-11 18:05:52.642000568 +0200
  5446. @@ -0,0 +1,339 @@
  5447. +/*
  5448. + * Copyright (C) 2013,2014 Russell King
  5449. + */
  5450. +#include "imx6qdl-microsom.dtsi"
  5451. +#include "imx6qdl-microsom-ar8035.dtsi"
  5452. +
  5453. +/ {
  5454. + chosen {
  5455. + bootargs = "quiet console=ttymxc0,115200 root=/dev/mmcblk0p2 rw";
  5456. + };
  5457. +
  5458. + aliases {
  5459. + mxcfb0 = &mxcfb1;
  5460. + };
  5461. +
  5462. + ir_recv: ir-receiver {
  5463. + compatible = "gpio-ir-receiver";
  5464. + gpios = <&gpio3 5 1>;
  5465. + pinctrl-names = "default";
  5466. + pinctrl-0 = <&pinctrl_hummingboard_gpio3_5>;
  5467. + linux,rc-map-name = "rc-rc6-mce";
  5468. + };
  5469. +
  5470. + regulators {
  5471. + compatible = "simple-bus";
  5472. +
  5473. + reg_3p3v: 3p3v {
  5474. + compatible = "regulator-fixed";
  5475. + regulator-name = "3P3V";
  5476. + regulator-min-microvolt = <3300000>;
  5477. + regulator-max-microvolt = <3300000>;
  5478. + regulator-always-on;
  5479. + };
  5480. +
  5481. + reg_usbh1_vbus: usb-h1-vbus {
  5482. + compatible = "regulator-fixed";
  5483. + enable-active-high;
  5484. + gpio = <&gpio1 0 0>;
  5485. + pinctrl-names = "default";
  5486. + pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>;
  5487. + regulator-name = "usb_h1_vbus";
  5488. + regulator-min-microvolt = <5000000>;
  5489. + regulator-max-microvolt = <5000000>;
  5490. + };
  5491. +
  5492. + reg_usbotg_vbus: usb-otg-vbus {
  5493. + compatible = "regulator-fixed";
  5494. + enable-active-high;
  5495. + gpio = <&gpio3 22 0>;
  5496. + pinctrl-names = "default";
  5497. + pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>;
  5498. + regulator-name = "usb_otg_vbus";
  5499. + regulator-min-microvolt = <5000000>;
  5500. + regulator-max-microvolt = <5000000>;
  5501. + };
  5502. + };
  5503. +
  5504. + sound-sgtl5000 {
  5505. + audio-codec = <&sgtl5000>;
  5506. + audio-routing =
  5507. + "MIC_IN", "Mic Jack",
  5508. + "Mic Jack", "Mic Bias",
  5509. + "Headphone Jack", "HP_OUT";
  5510. + compatible = "fsl,imx-audio-sgtl5000";
  5511. + model = "On-board Codec";
  5512. + mux-ext-port = <5>;
  5513. + mux-int-port = <1>;
  5514. + ssi-controller = <&ssi1>;
  5515. + };
  5516. +
  5517. + sound-spdif {
  5518. + compatible = "fsl,imx-audio-spdif";
  5519. + model = "imx-spdif";
  5520. + spdif-controller = <&spdif>;
  5521. + spdif-out;
  5522. + };
  5523. +
  5524. + sound-hdmi {
  5525. + compatible = "fsl,imx6q-audio-hdmi",
  5526. + "fsl,imx-audio-hdmi";
  5527. + model = "imx-audio-hdmi";
  5528. + hdmi-controller = <&hdmi_audio>;
  5529. + };
  5530. +
  5531. + mxcfb1: fb@0 {
  5532. + compatible = "fsl,mxc_sdc_fb";
  5533. + disp_dev = "hdmi";
  5534. + interface_pix_fmt = "RGB24";
  5535. + mode_str ="1920x1080M@60";
  5536. + default_bpp = <32>;
  5537. + int_clk = <0>;
  5538. + late_init = <0>;
  5539. + status = "okay";
  5540. + };
  5541. +};
  5542. +
  5543. +&hdmi_core {
  5544. + ipu_id = <0>;
  5545. + disp_id = <0>;
  5546. + status = "okay";
  5547. +};
  5548. +
  5549. +&hdmi_video {
  5550. + fsl,phy_reg_vlev = <0x0294>;
  5551. + fsl,phy_reg_cksymtx = <0x800d>;
  5552. + status = "okay";
  5553. +};
  5554. +
  5555. +&hdmi_audio {
  5556. + status = "okay";
  5557. +};
  5558. +
  5559. +&hdmi_cec {
  5560. + pinctrl-names = "default";
  5561. + pinctrl-0 = <&pinctrl_hummingboard_hdmi>;
  5562. + status = "okay";
  5563. +};
  5564. +
  5565. +&i2c2 {
  5566. + clock-frequency = <100000>;
  5567. + pinctrl-names = "default";
  5568. + pinctrl-0 = <&pinctrl_hummingboard_i2c2>;
  5569. + status = "okay";
  5570. +
  5571. + ddc: imx6_hdmi_i2c@50 {
  5572. + compatible = "fsl,imx6-hdmi-i2c";
  5573. + reg = <0x50>;
  5574. + };
  5575. +};
  5576. +
  5577. +&audmux {
  5578. + status = "okay";
  5579. +};
  5580. +
  5581. +&can1 {
  5582. + pinctrl-names = "default";
  5583. + status = "okay";
  5584. +};
  5585. +
  5586. +&i2c1 {
  5587. + clock-frequency = <100000>;
  5588. + pinctrl-names = "default";
  5589. + pinctrl-0 = <&pinctrl_hummingboard_i2c1>;
  5590. + status = "okay";
  5591. +
  5592. + /* Pro model */
  5593. + rtc: pcf8523@68 {
  5594. + compatible = "nxp,pcf8523";
  5595. + reg = <0x68>;
  5596. + };
  5597. +
  5598. + /* Pro model */
  5599. + sgtl5000: sgtl5000@0a {
  5600. + clocks = <&clks 201>;
  5601. + compatible = "fsl,sgtl5000";
  5602. + pinctrl-names = "default";
  5603. + pinctrl-0 = <&pinctrl_hummingboard_sgtl5000>;
  5604. + reg = <0x0a>;
  5605. + VDDA-supply = <&reg_3p3v>;
  5606. + VDDIO-supply = <&reg_3p3v>;
  5607. + };
  5608. +};
  5609. +
  5610. +&iomuxc {
  5611. + pinctrl-names = "default";
  5612. + pinctrl-0 = <&pinctrl_hog>;
  5613. + hummingboard {
  5614. + pinctrl_hog: hoggrp {
  5615. + fsl,pins = <
  5616. + /*
  5617. + * 26 pin header GPIO description. The pins
  5618. + * numbering as following -
  5619. + * GPIO number | GPIO (bank,num) | PIN number
  5620. + * ------------+-----------------+------------
  5621. + * gpio1 | (1,1) | IO7
  5622. + * gpio73 | (3,9) | IO11
  5623. + * gpio72 | (3,8) | IO12
  5624. + * gpio71 | (3,7) | IO13
  5625. + * gpio70 | (3,6) | IO15
  5626. + * gpio194 | (7,2) | IO16
  5627. + * gpio195 | (7,3) | IO18
  5628. + * gpio67 | (3,3) | IO22
  5629. + *
  5630. + * Notice the gpioX and GPIO (Y,Z) mapping forumla :
  5631. + * X = (Y-1) * 32 + Z
  5632. + */
  5633. + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x400130b1
  5634. + MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x400130b1
  5635. + MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x400130b1
  5636. + MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x400130b1
  5637. + MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x400130b1
  5638. + MX6QDL_PAD_SD3_CMD__GPIO7_IO02 0x400130b1
  5639. + MX6QDL_PAD_SD3_CLK__GPIO7_IO03 0x400130b1
  5640. + MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x400130b1
  5641. + >;
  5642. + };
  5643. +
  5644. + pinctrl_hummingboard_gpio3_5: hummingboard-gpio3_5 {
  5645. + fsl,pins = <
  5646. + MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x80000000
  5647. + >;
  5648. + };
  5649. +
  5650. + pinctrl_hummingboard_hdmi: hummingboard-hdmi {
  5651. + fsl,pins = <
  5652. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  5653. + >;
  5654. + };
  5655. +
  5656. + pinctrl_hummingboard_i2c1: hummingboard-i2c1 {
  5657. + fsl,pins = <
  5658. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  5659. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  5660. + >;
  5661. + };
  5662. +
  5663. + pinctrl_hummingboard_i2c2: hummingboard-i2c2 {
  5664. + fsl,pins = <
  5665. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  5666. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  5667. + >;
  5668. + };
  5669. +
  5670. + pinctrl_hummingboard_sgtl5000: hummingboard-sgtl5000 {
  5671. + fsl,pins = <
  5672. + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 /*brk*/
  5673. + MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0 /*ok*/
  5674. + MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x110b0 /*brk*/
  5675. + MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0 /*ok*/
  5676. + MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0
  5677. + >;
  5678. + };
  5679. +
  5680. + pinctrl_hummingboard_spdif: hummingboard-spdif {
  5681. + fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>;
  5682. + };
  5683. +
  5684. + pinctrl_hummingboard_usbh1_vbus: hummingboard-usbh1-vbus {
  5685. + fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0>;
  5686. + };
  5687. +
  5688. + pinctrl_hummingboard_usbotg_id: hummingboard-usbotg-id {
  5689. + /*
  5690. + * Similar to pinctrl_usbotg_2, but we want it
  5691. + * pulled down for a fixed host connection.
  5692. + */
  5693. + fsl,pins = <MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x13059>;
  5694. + };
  5695. +
  5696. + pinctrl_hummingboard_usbotg_vbus: hummingboard-usbotg-vbus {
  5697. + fsl,pins = <MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0>;
  5698. + };
  5699. +
  5700. + pinctrl_hummingboard_usdhc2_aux: hummingboard-usdhc2-aux {
  5701. + fsl,pins = <
  5702. + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f071
  5703. + >;
  5704. + };
  5705. +
  5706. + pinctrl_hummingboard_usdhc2: hummingboard-usdhc2 {
  5707. + fsl,pins = <
  5708. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  5709. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  5710. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  5711. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  5712. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  5713. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x13059
  5714. + >;
  5715. + };
  5716. +
  5717. + pinctrl_hummingboard_pcie_reset: hummingboard-pcie-reset {
  5718. + fsl,pins = <
  5719. + MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x80000000
  5720. + >;
  5721. + };
  5722. + };
  5723. +};
  5724. +
  5725. +&spdif {
  5726. + pinctrl-names = "default";
  5727. + pinctrl-0 = <&pinctrl_hummingboard_spdif>;
  5728. + clocks = <&clks 197>, <&clks 0>,
  5729. + <&clks 197>, <&clks 0>,
  5730. + <&clks 0>, <&clks 0>,
  5731. + <&clks 0>, <&clks 0>,
  5732. + <&clks 0>;
  5733. + clock-names = "core", "rxtx0",
  5734. + "rxtx1", "rxtx2",
  5735. + "rxtx3", "rxtx4",
  5736. + "rxtx5", "rxtx6",
  5737. + "rxtx7";
  5738. + status = "okay";
  5739. +};
  5740. +
  5741. +&ssi1 {
  5742. + fsl,mode = "i2s-slave";
  5743. + status = "okay";
  5744. +};
  5745. +
  5746. +&usbh1 {
  5747. + disable-over-current;
  5748. + vbus-supply = <&reg_usbh1_vbus>;
  5749. + status = "okay";
  5750. +};
  5751. +
  5752. +&usbotg {
  5753. + disable-over-current;
  5754. + pinctrl-names = "default";
  5755. + pinctrl-0 = <&pinctrl_hummingboard_usbotg_id>;
  5756. + vbus-supply = <&reg_usbotg_vbus>;
  5757. + status = "okay";
  5758. +};
  5759. +
  5760. +&usdhc2 {
  5761. + pinctrl-names = "default";
  5762. + pinctrl-0 = <
  5763. + &pinctrl_hummingboard_usdhc2_aux
  5764. + &pinctrl_hummingboard_usdhc2
  5765. + >;
  5766. + vmmc-supply = <&reg_3p3v>;
  5767. + cd-gpios = <&gpio1 4 0>;
  5768. + status = "okay";
  5769. +};
  5770. +
  5771. +&gpc {
  5772. + fsl,cpu_pupscr_sw2iso = <0xf>;
  5773. + fsl,cpu_pupscr_sw = <0xf>;
  5774. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  5775. + fsl,cpu_pdnscr_iso = <0x1>;
  5776. +};
  5777. +
  5778. +&pcie {
  5779. + pinctrl-names = "default";
  5780. + pinctrl-0 = <
  5781. + &pinctrl_hummingboard_pcie_reset
  5782. + >;
  5783. + reset-gpio = <&gpio3 4 0>;
  5784. + status = "okay";
  5785. +};
  5786. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi
  5787. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi 2014-08-14 03:38:34.000000000 +0200
  5788. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi 2014-09-11 18:05:52.642000568 +0200
  5789. @@ -17,7 +17,7 @@
  5790. enet {
  5791. pinctrl_microsom_enet_ar8035: microsom-enet-ar8035 {
  5792. fsl,pins = <
  5793. - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  5794. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b8b0
  5795. MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  5796. /* AR8035 reset */
  5797. MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x130b0
  5798. @@ -26,25 +26,25 @@
  5799. /* GPIO16 -> AR8035 25MHz */
  5800. MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000
  5801. MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000
  5802. - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  5803. - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  5804. - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  5805. - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  5806. - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  5807. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030
  5808. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030
  5809. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030
  5810. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030
  5811. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030
  5812. /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */
  5813. MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1
  5814. /* AR8035 pin strapping: IO voltage: pull up */
  5815. - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  5816. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030
  5817. /* AR8035 pin strapping: PHYADDR#0: pull down */
  5818. - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0
  5819. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x13030
  5820. /* AR8035 pin strapping: PHYADDR#1: pull down */
  5821. - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0
  5822. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x13030
  5823. /* AR8035 pin strapping: MODE#1: pull up */
  5824. - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  5825. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030
  5826. /* AR8035 pin strapping: MODE#3: pull up */
  5827. - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  5828. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030
  5829. /* AR8035 pin strapping: MODE#0: pull down */
  5830. - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0
  5831. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x13030
  5832. /*
  5833. * As the RMII pins are also connected to RGMII
  5834. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-microsom.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom.dtsi
  5835. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-microsom.dtsi 2014-08-14 03:38:34.000000000 +0200
  5836. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-microsom.dtsi 2014-09-11 18:05:52.642000568 +0200
  5837. @@ -1,9 +1,69 @@
  5838. /*
  5839. * Copyright (C) 2013,2014 Russell King
  5840. */
  5841. +#include <dt-bindings/gpio/gpio.h>
  5842. +/ {
  5843. + regulators {
  5844. + compatible = "simple-bus";
  5845. +
  5846. + reg_brcm_osc: brcm-osc-reg {
  5847. + compatible = "regulator-fixed";
  5848. + enable-active-high;
  5849. + gpio = <&gpio5 5 0>;
  5850. + pinctrl-names = "default";
  5851. + pinctrl-0 = <&pinctrl_microsom_brcm_osc_reg>;
  5852. + regulator-name = "brcm_osc_reg";
  5853. + regulator-min-microvolt = <3300000>;
  5854. + regulator-max-microvolt = <3300000>;
  5855. + regulator-always-on;
  5856. + regulator-boot-on;
  5857. + };
  5858. +
  5859. + reg_brcm: brcm-reg {
  5860. + compatible = "regulator-fixed";
  5861. + enable-active-high;
  5862. + gpio = <&gpio3 19 0>;
  5863. + pinctrl-names = "default";
  5864. + pinctrl-0 = <&pinctrl_microsom_brcm_reg>;
  5865. + regulator-name = "brcm_reg";
  5866. + regulator-min-microvolt = <3300000>;
  5867. + regulator-max-microvolt = <3300000>;
  5868. + startup-delay-us = <200000>;
  5869. + };
  5870. + };
  5871. +};
  5872. &iomuxc {
  5873. microsom {
  5874. + pinctrl_microsom_brcm_bt: microsom-brcm-bt {
  5875. + fsl,pins = <
  5876. + MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x40013070
  5877. + MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x40013070
  5878. + MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x40013070
  5879. + >;
  5880. + };
  5881. +
  5882. + pinctrl_microsom_brcm_osc_reg: microsom-brcm-osc-reg {
  5883. + fsl,pins = <
  5884. + MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05 0x40013070
  5885. + >;
  5886. + };
  5887. +
  5888. + pinctrl_microsom_brcm_reg: microsom-brcm-reg {
  5889. + fsl,pins = <
  5890. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x40013070
  5891. + >;
  5892. + };
  5893. +
  5894. + pinctrl_microsom_brcm_wifi: microsom-brcm-wifi {
  5895. + fsl,pins = <
  5896. + MX6QDL_PAD_GPIO_8__XTALOSC_REF_CLK_32K 0x1b0b0
  5897. + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x40013070
  5898. + MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x40013070
  5899. + MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x40013070
  5900. + >;
  5901. + };
  5902. +
  5903. pinctrl_microsom_uart1: microsom-uart1 {
  5904. fsl,pins = <
  5905. MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  5906. @@ -11,12 +71,24 @@
  5907. >;
  5908. };
  5909. - pinctrl_microsom_usbotg: microsom-usbotg {
  5910. - /*
  5911. - * Similar to pinctrl_usbotg_2, but we want it
  5912. - * pulled down for a fixed host connection.
  5913. - */
  5914. - fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>;
  5915. + pinctrl_microsom_uart4_1: microsom-uart4 {
  5916. + fsl,pins = <
  5917. + MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
  5918. + MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
  5919. + MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1
  5920. + MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1
  5921. + >;
  5922. + };
  5923. +
  5924. + pinctrl_microsom_usdhc1: microsom-usdhc1 {
  5925. + fsl,pins = <
  5926. + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  5927. + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  5928. + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  5929. + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  5930. + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  5931. + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  5932. + >;
  5933. };
  5934. };
  5935. };
  5936. @@ -27,7 +99,23 @@
  5937. status = "okay";
  5938. };
  5939. -&usbotg {
  5940. +/* UART4 - Connected to optional BRCM Wifi/BT/FM */
  5941. +&uart4 {
  5942. + pinctrl-names = "default";
  5943. + pinctrl-0 = <&pinctrl_microsom_brcm_bt &pinctrl_microsom_uart4_1>;
  5944. + fsl,uart-has-rtscts;
  5945. + status = "okay";
  5946. +};
  5947. +
  5948. +/* USDHC1 - Connected to optional BRCM Wifi/BT/FM */
  5949. +&usdhc1 {
  5950. + card-external-vcc-supply = <&reg_brcm>;
  5951. + card-reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>, <&gpio6 0 GPIO_ACTIVE_LOW>;
  5952. + keep-power-in-suspend;
  5953. + non-removable;
  5954. pinctrl-names = "default";
  5955. - pinctrl-0 = <&pinctrl_microsom_usbotg>;
  5956. + pinctrl-0 = <&pinctrl_microsom_brcm_wifi &pinctrl_microsom_usdhc1>;
  5957. + vmmc-supply = <&reg_brcm>;
  5958. + status = "okay";
  5959. };
  5960. +
  5961. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
  5962. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi 1970-01-01 01:00:00.000000000 +0100
  5963. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi 2014-09-11 18:05:52.642000568 +0200
  5964. @@ -0,0 +1,426 @@
  5965. +/*
  5966. + * Copyright 2013 Boundary Devices, Inc.
  5967. + * Copyright 2011 Freescale Semiconductor, Inc.
  5968. + * Copyright 2011 Linaro Ltd.
  5969. + *
  5970. + * The code contained herein is licensed under the GNU General Public
  5971. + * License. You may obtain a copy of the GNU General Public License
  5972. + * Version 2 or later at the following locations:
  5973. + *
  5974. + * http://www.opensource.org/licenses/gpl-license.html
  5975. + * http://www.gnu.org/copyleft/gpl.html
  5976. + */
  5977. +#include <dt-bindings/gpio/gpio.h>
  5978. +#include <dt-bindings/input/input.h>
  5979. +
  5980. +/ {
  5981. + chosen {
  5982. + stdout-path = &uart2;
  5983. + };
  5984. +
  5985. + memory {
  5986. + reg = <0x10000000 0x40000000>;
  5987. + };
  5988. +
  5989. + regulators {
  5990. + compatible = "simple-bus";
  5991. + #address-cells = <1>;
  5992. + #size-cells = <0>;
  5993. +
  5994. + reg_2p5v: regulator@0 {
  5995. + compatible = "regulator-fixed";
  5996. + reg = <0>;
  5997. + regulator-name = "2P5V";
  5998. + regulator-min-microvolt = <2500000>;
  5999. + regulator-max-microvolt = <2500000>;
  6000. + regulator-always-on;
  6001. + };
  6002. +
  6003. + reg_3p3v: regulator@1 {
  6004. + compatible = "regulator-fixed";
  6005. + reg = <1>;
  6006. + regulator-name = "3P3V";
  6007. + regulator-min-microvolt = <3300000>;
  6008. + regulator-max-microvolt = <3300000>;
  6009. + regulator-always-on;
  6010. + };
  6011. +
  6012. + reg_usb_otg_vbus: regulator@2 {
  6013. + compatible = "regulator-fixed";
  6014. + reg = <2>;
  6015. + regulator-name = "usb_otg_vbus";
  6016. + regulator-min-microvolt = <5000000>;
  6017. + regulator-max-microvolt = <5000000>;
  6018. + gpio = <&gpio3 22 0>;
  6019. + enable-active-high;
  6020. + };
  6021. + };
  6022. +
  6023. + gpio-keys {
  6024. + compatible = "gpio-keys";
  6025. + pinctrl-names = "default";
  6026. + pinctrl-0 = <&pinctrl_gpio_keys>;
  6027. +
  6028. + power {
  6029. + label = "Power Button";
  6030. + gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
  6031. + linux,code = <KEY_POWER>;
  6032. + gpio-key,wakeup;
  6033. + };
  6034. +
  6035. + menu {
  6036. + label = "Menu";
  6037. + gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
  6038. + linux,code = <KEY_MENU>;
  6039. + };
  6040. +
  6041. + home {
  6042. + label = "Home";
  6043. + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
  6044. + linux,code = <KEY_HOME>;
  6045. + };
  6046. +
  6047. + back {
  6048. + label = "Back";
  6049. + gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
  6050. + linux,code = <KEY_BACK>;
  6051. + };
  6052. +
  6053. + volume-up {
  6054. + label = "Volume Up";
  6055. + gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
  6056. + linux,code = <KEY_VOLUMEUP>;
  6057. + };
  6058. +
  6059. + volume-down {
  6060. + label = "Volume Down";
  6061. + gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
  6062. + linux,code = <KEY_VOLUMEDOWN>;
  6063. + };
  6064. + };
  6065. +
  6066. + sound {
  6067. + compatible = "fsl,imx6q-nitrogen6x-sgtl5000",
  6068. + "fsl,imx-audio-sgtl5000";
  6069. + model = "imx6q-nitrogen6x-sgtl5000";
  6070. + ssi-controller = <&ssi1>;
  6071. + audio-codec = <&codec>;
  6072. + audio-routing =
  6073. + "MIC_IN", "Mic Jack",
  6074. + "Mic Jack", "Mic Bias",
  6075. + "Headphone Jack", "HP_OUT";
  6076. + mux-int-port = <1>;
  6077. + mux-ext-port = <3>;
  6078. + };
  6079. +
  6080. + backlight_lcd {
  6081. + compatible = "pwm-backlight";
  6082. + pwms = <&pwm1 0 5000000>;
  6083. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6084. + default-brightness-level = <7>;
  6085. + power-supply = <&reg_3p3v>;
  6086. + status = "okay";
  6087. + };
  6088. +
  6089. + backlight_lvds {
  6090. + compatible = "pwm-backlight";
  6091. + pwms = <&pwm4 0 5000000>;
  6092. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6093. + default-brightness-level = <7>;
  6094. + power-supply = <&reg_3p3v>;
  6095. + status = "okay";
  6096. + };
  6097. +};
  6098. +
  6099. +&audmux {
  6100. + pinctrl-names = "default";
  6101. + pinctrl-0 = <&pinctrl_audmux>;
  6102. + status = "okay";
  6103. +};
  6104. +
  6105. +&ecspi1 {
  6106. + fsl,spi-num-chipselects = <1>;
  6107. + cs-gpios = <&gpio3 19 0>;
  6108. + pinctrl-names = "default";
  6109. + pinctrl-0 = <&pinctrl_ecspi1>;
  6110. + status = "okay";
  6111. +
  6112. + flash: m25p80@0 {
  6113. + compatible = "sst,sst25vf016b";
  6114. + spi-max-frequency = <20000000>;
  6115. + reg = <0>;
  6116. + };
  6117. +};
  6118. +
  6119. +&fec {
  6120. + pinctrl-names = "default";
  6121. + pinctrl-0 = <&pinctrl_enet>;
  6122. + phy-mode = "rgmii";
  6123. + phy-reset-gpios = <&gpio1 27 0>;
  6124. + txen-skew-ps = <0>;
  6125. + txc-skew-ps = <3000>;
  6126. + rxdv-skew-ps = <0>;
  6127. + rxc-skew-ps = <3000>;
  6128. + rxd0-skew-ps = <0>;
  6129. + rxd1-skew-ps = <0>;
  6130. + rxd2-skew-ps = <0>;
  6131. + rxd3-skew-ps = <0>;
  6132. + txd0-skew-ps = <0>;
  6133. + txd1-skew-ps = <0>;
  6134. + txd2-skew-ps = <0>;
  6135. + txd3-skew-ps = <0>;
  6136. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  6137. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  6138. + status = "okay";
  6139. +};
  6140. +
  6141. +&i2c1 {
  6142. + clock-frequency = <100000>;
  6143. + pinctrl-names = "default";
  6144. + pinctrl-0 = <&pinctrl_i2c1>;
  6145. + status = "okay";
  6146. +
  6147. + codec: sgtl5000@0a {
  6148. + compatible = "fsl,sgtl5000";
  6149. + reg = <0x0a>;
  6150. + clocks = <&clks 201>;
  6151. + VDDA-supply = <&reg_2p5v>;
  6152. + VDDIO-supply = <&reg_3p3v>;
  6153. + };
  6154. +};
  6155. +
  6156. +&iomuxc {
  6157. + pinctrl-names = "default";
  6158. + pinctrl-0 = <&pinctrl_hog>;
  6159. +
  6160. + imx6q-nitrogen6x {
  6161. + pinctrl_hog: hoggrp {
  6162. + fsl,pins = <
  6163. + /* SGTL5000 sys_mclk */
  6164. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
  6165. + >;
  6166. + };
  6167. +
  6168. + pinctrl_audmux: audmuxgrp {
  6169. + fsl,pins = <
  6170. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  6171. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  6172. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  6173. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  6174. + >;
  6175. + };
  6176. +
  6177. + pinctrl_ecspi1: ecspi1grp {
  6178. + fsl,pins = <
  6179. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  6180. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  6181. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  6182. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
  6183. + >;
  6184. + };
  6185. +
  6186. + pinctrl_enet: enetgrp {
  6187. + fsl,pins = <
  6188. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
  6189. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
  6190. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
  6191. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
  6192. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
  6193. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
  6194. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
  6195. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
  6196. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
  6197. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  6198. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  6199. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  6200. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  6201. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  6202. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  6203. + /* Phy reset */
  6204. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x000b0
  6205. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  6206. + >;
  6207. + };
  6208. +
  6209. + pinctrl_gpio_keys: gpio_keysgrp {
  6210. + fsl,pins = <
  6211. + /* Power Button */
  6212. + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
  6213. + /* Menu Button */
  6214. + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
  6215. + /* Home Button */
  6216. + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
  6217. + /* Back Button */
  6218. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
  6219. + /* Volume Up Button */
  6220. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
  6221. + /* Volume Down Button */
  6222. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
  6223. + >;
  6224. + };
  6225. +
  6226. + pinctrl_i2c1: i2c1grp {
  6227. + fsl,pins = <
  6228. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  6229. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  6230. + >;
  6231. + };
  6232. +
  6233. + pinctrl_pwm1: pwm1grp {
  6234. + fsl,pins = <
  6235. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  6236. + >;
  6237. + };
  6238. +
  6239. + pinctrl_pwm3: pwm3grp {
  6240. + fsl,pins = <
  6241. + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
  6242. + >;
  6243. + };
  6244. +
  6245. + pinctrl_pwm4: pwm4grp {
  6246. + fsl,pins = <
  6247. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  6248. + >;
  6249. + };
  6250. +
  6251. + pinctrl_uart1: uart1grp {
  6252. + fsl,pins = <
  6253. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  6254. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  6255. + >;
  6256. + };
  6257. +
  6258. + pinctrl_uart2: uart2grp {
  6259. + fsl,pins = <
  6260. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  6261. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  6262. + >;
  6263. + };
  6264. +
  6265. + pinctrl_usbotg: usbotggrp {
  6266. + fsl,pins = <
  6267. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  6268. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  6269. + /* power enable, high active */
  6270. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
  6271. + >;
  6272. + };
  6273. +
  6274. + pinctrl_usdhc3: usdhc3grp {
  6275. + fsl,pins = <
  6276. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  6277. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  6278. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  6279. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  6280. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  6281. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  6282. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
  6283. + >;
  6284. + };
  6285. +
  6286. + pinctrl_usdhc4: usdhc4grp {
  6287. + fsl,pins = <
  6288. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  6289. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  6290. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  6291. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  6292. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  6293. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  6294. + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
  6295. + >;
  6296. + };
  6297. + };
  6298. +};
  6299. +
  6300. +&ldb {
  6301. + status = "okay";
  6302. +
  6303. + lvds-channel@0 {
  6304. + fsl,data-mapping = "spwg";
  6305. + fsl,data-width = <18>;
  6306. + status = "okay";
  6307. +
  6308. + display-timings {
  6309. + native-mode = <&timing0>;
  6310. + timing0: hsd100pxn1 {
  6311. + clock-frequency = <65000000>;
  6312. + hactive = <1024>;
  6313. + vactive = <768>;
  6314. + hback-porch = <220>;
  6315. + hfront-porch = <40>;
  6316. + vback-porch = <21>;
  6317. + vfront-porch = <7>;
  6318. + hsync-len = <60>;
  6319. + vsync-len = <10>;
  6320. + };
  6321. + };
  6322. + };
  6323. +};
  6324. +
  6325. +&pcie {
  6326. + status = "okay";
  6327. +};
  6328. +
  6329. +&pwm1 {
  6330. + pinctrl-names = "default";
  6331. + pinctrl-0 = <&pinctrl_pwm1>;
  6332. + status = "okay";
  6333. +};
  6334. +
  6335. +&pwm3 {
  6336. + pinctrl-names = "default";
  6337. + pinctrl-0 = <&pinctrl_pwm3>;
  6338. + status = "okay";
  6339. +};
  6340. +
  6341. +&pwm4 {
  6342. + pinctrl-names = "default";
  6343. + pinctrl-0 = <&pinctrl_pwm4>;
  6344. + status = "okay";
  6345. +};
  6346. +
  6347. +&ssi1 {
  6348. + fsl,mode = "i2s-slave";
  6349. + status = "okay";
  6350. +};
  6351. +
  6352. +&uart1 {
  6353. + pinctrl-names = "default";
  6354. + pinctrl-0 = <&pinctrl_uart1>;
  6355. + status = "okay";
  6356. +};
  6357. +
  6358. +&uart2 {
  6359. + pinctrl-names = "default";
  6360. + pinctrl-0 = <&pinctrl_uart2>;
  6361. + status = "okay";
  6362. +};
  6363. +
  6364. +&usbh1 {
  6365. + status = "okay";
  6366. +};
  6367. +
  6368. +&usbotg {
  6369. + vbus-supply = <&reg_usb_otg_vbus>;
  6370. + pinctrl-names = "default";
  6371. + pinctrl-0 = <&pinctrl_usbotg>;
  6372. + disable-over-current;
  6373. + status = "okay";
  6374. +};
  6375. +
  6376. +&usdhc3 {
  6377. + pinctrl-names = "default";
  6378. + pinctrl-0 = <&pinctrl_usdhc3>;
  6379. + cd-gpios = <&gpio7 0 0>;
  6380. + vmmc-supply = <&reg_3p3v>;
  6381. + status = "okay";
  6382. +};
  6383. +
  6384. +&usdhc4 {
  6385. + pinctrl-names = "default";
  6386. + pinctrl-0 = <&pinctrl_usdhc4>;
  6387. + cd-gpios = <&gpio2 6 0>;
  6388. + vmmc-supply = <&reg_3p3v>;
  6389. + status = "okay";
  6390. +};
  6391. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
  6392. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi 1970-01-01 01:00:00.000000000 +0100
  6393. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi 2014-09-11 18:05:52.642000568 +0200
  6394. @@ -0,0 +1,98 @@
  6395. +/*
  6396. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  6397. + *
  6398. + * The code contained herein is licensed under the GNU General Public
  6399. + * License. You may obtain a copy of the GNU General Public License
  6400. + * Version 2 or later at the following locations:
  6401. + *
  6402. + * http://www.opensource.org/licenses/gpl-license.html
  6403. + * http://www.gnu.org/copyleft/gpl.html
  6404. + */
  6405. +
  6406. +/ {
  6407. + chosen {
  6408. + linux,stdout-path = &uart4;
  6409. + };
  6410. +};
  6411. +
  6412. +&fec {
  6413. + status = "okay";
  6414. +};
  6415. +
  6416. +&gpmi {
  6417. + status = "okay";
  6418. +};
  6419. +
  6420. +&i2c2 {
  6421. + pinctrl-names = "default";
  6422. + pinctrl-0 = <&pinctrl_i2c2>;
  6423. + clock-frequency = <100000>;
  6424. + status = "okay";
  6425. +
  6426. + tlv320@18 {
  6427. + compatible = "ti,tlv320aic3x";
  6428. + reg = <0x18>;
  6429. + };
  6430. +
  6431. + stmpe@41 {
  6432. + compatible = "st,stmpe811";
  6433. + reg = <0x41>;
  6434. + };
  6435. +
  6436. + rtc@51 {
  6437. + compatible = "nxp,rtc8564";
  6438. + reg = <0x51>;
  6439. + };
  6440. +
  6441. + adc@64 {
  6442. + compatible = "maxim,max1037";
  6443. + reg = <0x64>;
  6444. + };
  6445. +};
  6446. +
  6447. +&i2c3 {
  6448. + pinctrl-names = "default";
  6449. + pinctrl-0 = <&pinctrl_i2c3>;
  6450. + clock-frequency = <100000>;
  6451. + status = "okay";
  6452. +};
  6453. +
  6454. +&uart3 {
  6455. + status = "okay";
  6456. +};
  6457. +
  6458. +&uart4 {
  6459. + status = "okay";
  6460. +};
  6461. +
  6462. +&usbh1 {
  6463. + status = "okay";
  6464. +};
  6465. +
  6466. +&usbotg {
  6467. + status = "okay";
  6468. +};
  6469. +
  6470. +&usdhc2 {
  6471. + status = "okay";
  6472. +};
  6473. +
  6474. +&usdhc3 {
  6475. + status = "okay";
  6476. +};
  6477. +
  6478. +&iomuxc {
  6479. + pinctrl_i2c2: i2c2grp {
  6480. + fsl,pins = <
  6481. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  6482. + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
  6483. + >;
  6484. + };
  6485. +
  6486. + pinctrl_i2c3: i2c3grp {
  6487. + fsl,pins = <
  6488. + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
  6489. + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
  6490. + >;
  6491. + };
  6492. +};
  6493. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
  6494. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi 1970-01-01 01:00:00.000000000 +0100
  6495. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi 2014-09-11 18:05:52.642000568 +0200
  6496. @@ -0,0 +1,356 @@
  6497. +/*
  6498. + * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
  6499. + *
  6500. + * The code contained herein is licensed under the GNU General Public
  6501. + * License. You may obtain a copy of the GNU General Public License
  6502. + * Version 2 or later at the following locations:
  6503. + *
  6504. + * http://www.opensource.org/licenses/gpl-license.html
  6505. + * http://www.gnu.org/copyleft/gpl.html
  6506. + */
  6507. +
  6508. +#include <dt-bindings/gpio/gpio.h>
  6509. +
  6510. +/ {
  6511. + model = "Phytec phyFLEX-i.MX6 Ouad";
  6512. + compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
  6513. +
  6514. + memory {
  6515. + reg = <0x10000000 0x80000000>;
  6516. + };
  6517. +
  6518. + regulators {
  6519. + compatible = "simple-bus";
  6520. + #address-cells = <1>;
  6521. + #size-cells = <0>;
  6522. +
  6523. + reg_usb_otg_vbus: regulator@0 {
  6524. + compatible = "regulator-fixed";
  6525. + reg = <0>;
  6526. + regulator-name = "usb_otg_vbus";
  6527. + regulator-min-microvolt = <5000000>;
  6528. + regulator-max-microvolt = <5000000>;
  6529. + gpio = <&gpio4 15 0>;
  6530. + };
  6531. +
  6532. + reg_usb_h1_vbus: regulator@1 {
  6533. + compatible = "regulator-fixed";
  6534. + reg = <1>;
  6535. + regulator-name = "usb_h1_vbus";
  6536. + regulator-min-microvolt = <5000000>;
  6537. + regulator-max-microvolt = <5000000>;
  6538. + gpio = <&gpio1 0 0>;
  6539. + };
  6540. + };
  6541. +
  6542. + gpio_leds: leds {
  6543. + compatible = "gpio-leds";
  6544. +
  6545. + green {
  6546. + label = "phyflex:green";
  6547. + gpios = <&gpio1 30 0>;
  6548. + };
  6549. +
  6550. + red {
  6551. + label = "phyflex:red";
  6552. + gpios = <&gpio2 31 0>;
  6553. + };
  6554. + };
  6555. +};
  6556. +
  6557. +&ecspi3 {
  6558. + pinctrl-names = "default";
  6559. + pinctrl-0 = <&pinctrl_ecspi3>;
  6560. + status = "okay";
  6561. + fsl,spi-num-chipselects = <1>;
  6562. + cs-gpios = <&gpio4 24 0>;
  6563. +
  6564. + flash@0 {
  6565. + compatible = "m25p80";
  6566. + spi-max-frequency = <20000000>;
  6567. + reg = <0>;
  6568. + };
  6569. +};
  6570. +
  6571. +&i2c1 {
  6572. + pinctrl-names = "default";
  6573. + pinctrl-0 = <&pinctrl_i2c1>;
  6574. + status = "okay";
  6575. +
  6576. + eeprom@50 {
  6577. + compatible = "atmel,24c32";
  6578. + reg = <0x50>;
  6579. + };
  6580. +
  6581. + pmic@58 {
  6582. + compatible = "dialog,da9063";
  6583. + reg = <0x58>;
  6584. + interrupt-parent = <&gpio4>;
  6585. + interrupts = <17 0x8>; /* active-low GPIO4_17 */
  6586. +
  6587. + regulators {
  6588. + vddcore_reg: bcore1 {
  6589. + regulator-min-microvolt = <730000>;
  6590. + regulator-max-microvolt = <1380000>;
  6591. + regulator-always-on;
  6592. + };
  6593. +
  6594. + vddsoc_reg: bcore2 {
  6595. + regulator-min-microvolt = <730000>;
  6596. + regulator-max-microvolt = <1380000>;
  6597. + regulator-always-on;
  6598. + };
  6599. +
  6600. + vdd_ddr3_reg: bpro {
  6601. + regulator-min-microvolt = <1500000>;
  6602. + regulator-max-microvolt = <1500000>;
  6603. + regulator-always-on;
  6604. + };
  6605. +
  6606. + vdd_3v3_reg: bperi {
  6607. + regulator-min-microvolt = <3300000>;
  6608. + regulator-max-microvolt = <3300000>;
  6609. + regulator-always-on;
  6610. + };
  6611. +
  6612. + vdd_buckmem_reg: bmem {
  6613. + regulator-min-microvolt = <3300000>;
  6614. + regulator-max-microvolt = <3300000>;
  6615. + regulator-always-on;
  6616. + };
  6617. +
  6618. + vdd_eth_reg: bio {
  6619. + regulator-min-microvolt = <1200000>;
  6620. + regulator-max-microvolt = <1200000>;
  6621. + regulator-always-on;
  6622. + };
  6623. +
  6624. + vdd_eth_io_reg: ldo4 {
  6625. + regulator-min-microvolt = <2500000>;
  6626. + regulator-max-microvolt = <2500000>;
  6627. + regulator-always-on;
  6628. + };
  6629. +
  6630. + vdd_mx6_snvs_reg: ldo5 {
  6631. + regulator-min-microvolt = <3000000>;
  6632. + regulator-max-microvolt = <3000000>;
  6633. + regulator-always-on;
  6634. + };
  6635. +
  6636. + vdd_3v3_pmic_io_reg: ldo6 {
  6637. + regulator-min-microvolt = <3300000>;
  6638. + regulator-max-microvolt = <3300000>;
  6639. + regulator-always-on;
  6640. + };
  6641. +
  6642. + vdd_sd0_reg: ldo9 {
  6643. + regulator-min-microvolt = <3300000>;
  6644. + regulator-max-microvolt = <3300000>;
  6645. + };
  6646. +
  6647. + vdd_sd1_reg: ldo10 {
  6648. + regulator-min-microvolt = <3300000>;
  6649. + regulator-max-microvolt = <3300000>;
  6650. + };
  6651. +
  6652. + vdd_mx6_high_reg: ldo11 {
  6653. + regulator-min-microvolt = <3000000>;
  6654. + regulator-max-microvolt = <3000000>;
  6655. + regulator-always-on;
  6656. + };
  6657. + };
  6658. + };
  6659. +};
  6660. +
  6661. +&iomuxc {
  6662. + pinctrl-names = "default";
  6663. + pinctrl-0 = <&pinctrl_hog>;
  6664. +
  6665. + imx6q-phytec-pfla02 {
  6666. + pinctrl_hog: hoggrp {
  6667. + fsl,pins = <
  6668. + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  6669. + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  6670. + MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x80000000 /* PMIC interrupt */
  6671. + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x80000000 /* Green LED */
  6672. + MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x80000000 /* Red LED */
  6673. + >;
  6674. + };
  6675. +
  6676. + pinctrl_ecspi3: ecspi3grp {
  6677. + fsl,pins = <
  6678. + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
  6679. + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
  6680. + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
  6681. + >;
  6682. + };
  6683. +
  6684. + pinctrl_enet: enetgrp {
  6685. + fsl,pins = <
  6686. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  6687. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  6688. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  6689. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  6690. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  6691. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  6692. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  6693. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  6694. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  6695. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  6696. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  6697. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  6698. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  6699. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  6700. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  6701. + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
  6702. + >;
  6703. + };
  6704. +
  6705. + pinctrl_gpmi_nand: gpminandgrp {
  6706. + fsl,pins = <
  6707. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  6708. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  6709. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  6710. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  6711. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  6712. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  6713. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  6714. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  6715. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  6716. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  6717. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  6718. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  6719. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  6720. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  6721. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  6722. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  6723. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  6724. + >;
  6725. + };
  6726. +
  6727. + pinctrl_i2c1: i2c1grp {
  6728. + fsl,pins = <
  6729. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  6730. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  6731. + >;
  6732. + };
  6733. +
  6734. + pinctrl_uart3: uart3grp {
  6735. + fsl,pins = <
  6736. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  6737. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  6738. + MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x1b0b1
  6739. + MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x1b0b1
  6740. + >;
  6741. + };
  6742. +
  6743. + pinctrl_uart4: uart4grp {
  6744. + fsl,pins = <
  6745. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  6746. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  6747. + >;
  6748. + };
  6749. +
  6750. + pinctrl_usbh1: usbh1grp {
  6751. + fsl,pins = <
  6752. + MX6QDL_PAD_GPIO_0__USB_H1_PWR 0x80000000
  6753. + >;
  6754. + };
  6755. +
  6756. + pinctrl_usbotg: usbotggrp {
  6757. + fsl,pins = <
  6758. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  6759. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  6760. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000
  6761. + >;
  6762. + };
  6763. +
  6764. + pinctrl_usdhc2: usdhc2grp {
  6765. + fsl,pins = <
  6766. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  6767. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  6768. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  6769. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  6770. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  6771. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  6772. + >;
  6773. + };
  6774. +
  6775. + pinctrl_usdhc3: usdhc3grp {
  6776. + fsl,pins = <
  6777. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  6778. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  6779. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  6780. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  6781. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  6782. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  6783. + >;
  6784. + };
  6785. +
  6786. + pinctrl_usdhc3_cdwp: usdhc3cdwp {
  6787. + fsl,pins = <
  6788. + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
  6789. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  6790. + >;
  6791. + };
  6792. + };
  6793. +};
  6794. +
  6795. +&fec {
  6796. + pinctrl-names = "default";
  6797. + pinctrl-0 = <&pinctrl_enet>;
  6798. + phy-mode = "rgmii";
  6799. + phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
  6800. + status = "disabled";
  6801. +};
  6802. +
  6803. +&gpmi {
  6804. + pinctrl-names = "default";
  6805. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  6806. + nand-on-flash-bbt;
  6807. + status = "disabled";
  6808. +};
  6809. +
  6810. +&uart3 {
  6811. + pinctrl-names = "default";
  6812. + pinctrl-0 = <&pinctrl_uart3>;
  6813. + status = "disabled";
  6814. +};
  6815. +
  6816. +&uart4 {
  6817. + pinctrl-names = "default";
  6818. + pinctrl-0 = <&pinctrl_uart4>;
  6819. + status = "disabled";
  6820. +};
  6821. +
  6822. +&usbh1 {
  6823. + vbus-supply = <&reg_usb_h1_vbus>;
  6824. + pinctrl-names = "default";
  6825. + pinctrl-0 = <&pinctrl_usbh1>;
  6826. + status = "disabled";
  6827. +};
  6828. +
  6829. +&usbotg {
  6830. + vbus-supply = <&reg_usb_otg_vbus>;
  6831. + pinctrl-names = "default";
  6832. + pinctrl-0 = <&pinctrl_usbotg>;
  6833. + disable-over-current;
  6834. + status = "disabled";
  6835. +};
  6836. +
  6837. +&usdhc2 {
  6838. + pinctrl-names = "default";
  6839. + pinctrl-0 = <&pinctrl_usdhc2>;
  6840. + cd-gpios = <&gpio1 4 0>;
  6841. + wp-gpios = <&gpio1 2 0>;
  6842. + status = "disabled";
  6843. +};
  6844. +
  6845. +&usdhc3 {
  6846. + pinctrl-names = "default";
  6847. + pinctrl-0 = <&pinctrl_usdhc3
  6848. + &pinctrl_usdhc3_cdwp>;
  6849. + cd-gpios = <&gpio1 27 0>;
  6850. + wp-gpios = <&gpio1 29 0>;
  6851. + status = "disabled";
  6852. +};
  6853. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
  6854. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi 2014-08-14 03:38:34.000000000 +0200
  6855. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi 2014-09-11 18:05:52.642000568 +0200
  6856. @@ -10,17 +10,146 @@
  6857. * http://www.gnu.org/copyleft/gpl.html
  6858. */
  6859. +#include <dt-bindings/gpio/gpio.h>
  6860. +
  6861. / {
  6862. + aliases {
  6863. + mxcfb0 = &mxcfb1;
  6864. + mxcfb1 = &mxcfb2;
  6865. + mxcfb2 = &mxcfb3;
  6866. + mxcfb3 = &mxcfb4;
  6867. + };
  6868. +
  6869. memory {
  6870. reg = <0x10000000 0x80000000>;
  6871. };
  6872. +
  6873. + leds {
  6874. + compatible = "gpio-leds";
  6875. + pinctrl-names = "default";
  6876. + pinctrl-0 = <&pinctrl_gpio_leds>;
  6877. +
  6878. + user {
  6879. + label = "debug";
  6880. + gpios = <&gpio5 15 GPIO_ACTIVE_HIGH>;
  6881. + };
  6882. + };
  6883. +
  6884. + sound-spdif {
  6885. + compatible = "fsl,imx-audio-spdif",
  6886. + "fsl,imx-sabreauto-spdif";
  6887. + model = "imx-spdif";
  6888. + spdif-controller = <&spdif>;
  6889. + spdif-in;
  6890. + };
  6891. +
  6892. + backlight {
  6893. + compatible = "pwm-backlight";
  6894. + pwms = <&pwm3 0 5000000>;
  6895. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6896. + default-brightness-level = <7>;
  6897. + status = "okay";
  6898. + };
  6899. +
  6900. + max7310_reset: max7310-reset {
  6901. + compatible = "gpio-reset";
  6902. + reset-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
  6903. + reset-delay-us = <1>;
  6904. + #reset-cells = <0>;
  6905. + };
  6906. +
  6907. + mxcfb1: fb@0 {
  6908. + compatible = "fsl,mxc_sdc_fb";
  6909. + disp_dev = "ldb";
  6910. + interface_pix_fmt = "RGB666";
  6911. + mode_str ="LDB-XGA";
  6912. + default_bpp = <16>;
  6913. + int_clk = <0>;
  6914. + late_init = <0>;
  6915. + status = "disabled";
  6916. + };
  6917. +
  6918. + mxcfb2: fb@1 {
  6919. + compatible = "fsl,mxc_sdc_fb";
  6920. + disp_dev = "hdmi";
  6921. + interface_pix_fmt = "RGB24";
  6922. + mode_str ="1920x1080M@60";
  6923. + default_bpp = <24>;
  6924. + int_clk = <0>;
  6925. + late_init = <0>;
  6926. + status = "disabled";
  6927. + };
  6928. +
  6929. + mxcfb3: fb@2 {
  6930. + compatible = "fsl,mxc_sdc_fb";
  6931. + disp_dev = "lcd";
  6932. + interface_pix_fmt = "RGB565";
  6933. + mode_str ="CLAA-WVGA";
  6934. + default_bpp = <16>;
  6935. + int_clk = <0>;
  6936. + late_init = <0>;
  6937. + status = "disabled";
  6938. + };
  6939. +
  6940. + mxcfb4: fb@3 {
  6941. + compatible = "fsl,mxc_sdc_fb";
  6942. + disp_dev = "ldb";
  6943. + interface_pix_fmt = "RGB666";
  6944. + mode_str ="LDB-XGA";
  6945. + default_bpp = <16>;
  6946. + int_clk = <0>;
  6947. + late_init = <0>;
  6948. + status = "disabled";
  6949. + };
  6950. +
  6951. + backlight {
  6952. + compatible = "pwm-backlight";
  6953. + pwms = <&pwm3 0 5000000>;
  6954. + brightness-levels = <0 4 8 16 32 64 128 255>;
  6955. + default-brightness-level = <7>;
  6956. + };
  6957. +
  6958. + regulators {
  6959. + compatible = "simple-bus";
  6960. + reg_audio: cs42888_supply {
  6961. + compatible = "regulator-fixed";
  6962. + regulator-name = "cs42888_supply";
  6963. + regulator-min-microvolt = <3300000>;
  6964. + regulator-max-microvolt = <3300000>;
  6965. + regulator-always-on;
  6966. + };
  6967. + };
  6968. +
  6969. + sound-cs42888 {
  6970. + compatible = "fsl,imx6-sabreauto-cs42888",
  6971. + "fsl,imx-audio-cs42888";
  6972. + model = "imx-cs42888";
  6973. + esai-controller = <&esai>;
  6974. + asrc-controller = <&asrc_p2p>;
  6975. + audio-codec = <&codec>;
  6976. + };
  6977. +
  6978. + sound-hdmi {
  6979. + compatible = "fsl,imx6q-audio-hdmi",
  6980. + "fsl,imx-audio-hdmi";
  6981. + model = "imx-audio-hdmi";
  6982. + hdmi-controller = <&hdmi_audio>;
  6983. + };
  6984. +
  6985. + clocks {
  6986. + codec_osc: anaclk2 {
  6987. + compatible = "fixed-clock";
  6988. + #clock-cells = <0>;
  6989. + clock-frequency = <24576000>;
  6990. + };
  6991. + };
  6992. };
  6993. &ecspi1 {
  6994. fsl,spi-num-chipselects = <1>;
  6995. cs-gpios = <&gpio3 19 0>;
  6996. pinctrl-names = "default";
  6997. - pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_sabreauto>;
  6998. + pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>;
  6999. status = "disabled"; /* pin conflict with WEIM NOR */
  7000. flash: m25p80@0 {
  7001. @@ -34,51 +163,481 @@
  7002. &fec {
  7003. pinctrl-names = "default";
  7004. - pinctrl-0 = <&pinctrl_enet_2>;
  7005. + pinctrl-0 = <&pinctrl_enet>;
  7006. phy-mode = "rgmii";
  7007. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  7008. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  7009. status = "okay";
  7010. };
  7011. &gpmi {
  7012. pinctrl-names = "default";
  7013. - pinctrl-0 = <&pinctrl_gpmi_nand_1>;
  7014. + pinctrl-0 = <&pinctrl_gpmi_nand>;
  7015. + status = "okay";
  7016. +};
  7017. +
  7018. +&i2c2 {
  7019. + clock-frequency = <100000>;
  7020. + pinctrl-names = "default";
  7021. + pinctrl-0 = <&pinctrl_i2c2>;
  7022. + status = "okay";
  7023. +
  7024. + egalax_ts@04 {
  7025. + compatible = "eeti,egalax_ts";
  7026. + reg = <0x04>;
  7027. + interrupt-parent = <&gpio2>;
  7028. + interrupts = <28 2>;
  7029. + wakeup-gpios = <&gpio2 28 0>;
  7030. + };
  7031. +
  7032. + pmic: pfuze100@08 {
  7033. + compatible = "fsl,pfuze100";
  7034. + reg = <0x08>;
  7035. +
  7036. + regulators {
  7037. + sw1a_reg: sw1ab {
  7038. + regulator-min-microvolt = <300000>;
  7039. + regulator-max-microvolt = <1875000>;
  7040. + regulator-boot-on;
  7041. + regulator-always-on;
  7042. + regulator-ramp-delay = <6250>;
  7043. + };
  7044. +
  7045. + sw1c_reg: sw1c {
  7046. + regulator-min-microvolt = <300000>;
  7047. + regulator-max-microvolt = <1875000>;
  7048. + regulator-boot-on;
  7049. + regulator-always-on;
  7050. + regulator-ramp-delay = <6250>;
  7051. + };
  7052. +
  7053. + sw2_reg: sw2 {
  7054. + regulator-min-microvolt = <800000>;
  7055. + regulator-max-microvolt = <3300000>;
  7056. + regulator-boot-on;
  7057. + regulator-always-on;
  7058. + };
  7059. +
  7060. + sw3a_reg: sw3a {
  7061. + regulator-min-microvolt = <400000>;
  7062. + regulator-max-microvolt = <1975000>;
  7063. + regulator-boot-on;
  7064. + regulator-always-on;
  7065. + };
  7066. +
  7067. + sw3b_reg: sw3b {
  7068. + regulator-min-microvolt = <400000>;
  7069. + regulator-max-microvolt = <1975000>;
  7070. + regulator-boot-on;
  7071. + regulator-always-on;
  7072. + };
  7073. +
  7074. + sw4_reg: sw4 {
  7075. + regulator-min-microvolt = <800000>;
  7076. + regulator-max-microvolt = <3300000>;
  7077. + };
  7078. +
  7079. + swbst_reg: swbst {
  7080. + regulator-min-microvolt = <5000000>;
  7081. + regulator-max-microvolt = <5150000>;
  7082. + };
  7083. +
  7084. + snvs_reg: vsnvs {
  7085. + regulator-min-microvolt = <1000000>;
  7086. + regulator-max-microvolt = <3000000>;
  7087. + regulator-boot-on;
  7088. + regulator-always-on;
  7089. + };
  7090. +
  7091. + vref_reg: vrefddr {
  7092. + regulator-boot-on;
  7093. + regulator-always-on;
  7094. + };
  7095. +
  7096. + vgen1_reg: vgen1 {
  7097. + regulator-min-microvolt = <800000>;
  7098. + regulator-max-microvolt = <1550000>;
  7099. + };
  7100. +
  7101. + vgen2_reg: vgen2 {
  7102. + regulator-min-microvolt = <800000>;
  7103. + regulator-max-microvolt = <1550000>;
  7104. + };
  7105. +
  7106. + vgen3_reg: vgen3 {
  7107. + regulator-min-microvolt = <1800000>;
  7108. + regulator-max-microvolt = <3300000>;
  7109. + };
  7110. +
  7111. + vgen4_reg: vgen4 {
  7112. + regulator-min-microvolt = <1800000>;
  7113. + regulator-max-microvolt = <3300000>;
  7114. + regulator-always-on;
  7115. + };
  7116. +
  7117. + vgen5_reg: vgen5 {
  7118. + regulator-min-microvolt = <1800000>;
  7119. + regulator-max-microvolt = <3300000>;
  7120. + regulator-always-on;
  7121. + };
  7122. +
  7123. + vgen6_reg: vgen6 {
  7124. + regulator-min-microvolt = <1800000>;
  7125. + regulator-max-microvolt = <3300000>;
  7126. + regulator-always-on;
  7127. + };
  7128. + };
  7129. + };
  7130. +
  7131. + codec: cs42888@048 {
  7132. + compatible = "cirrus,cs42888";
  7133. + reg = <0x048>;
  7134. + clocks = <&codec_osc 0>;
  7135. + clock-names = "codec_osc";
  7136. + VA-supply = <&reg_audio>;
  7137. + VD-supply = <&reg_audio>;
  7138. + VLS-supply = <&reg_audio>;
  7139. + VLC-supply = <&reg_audio>;
  7140. + };
  7141. +
  7142. + hdmi: edid@50 {
  7143. + compatible = "fsl,imx6-hdmi-i2c";
  7144. + reg = <0x50>;
  7145. + };
  7146. +};
  7147. +
  7148. +&i2c3 {
  7149. + pinctrl-names = "default";
  7150. + pinctrl-0 = <&pinctrl_i2c3>;
  7151. + pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>;
  7152. status = "okay";
  7153. +
  7154. + max7310_a: gpio@30 {
  7155. + compatible = "maxim,max7310";
  7156. + reg = <0x30>;
  7157. + gpio-controller;
  7158. + #gpio-cells = <2>;
  7159. + resets = <&max7310_reset>;
  7160. + };
  7161. +
  7162. + max7310_b: gpio@32 {
  7163. + compatible = "maxim,max7310";
  7164. + reg = <0x32>;
  7165. + gpio-controller;
  7166. + #gpio-cells = <2>;
  7167. + };
  7168. +
  7169. + max7310_c: gpio@34 {
  7170. + compatible = "maxim,max7310";
  7171. + reg = <0x34>;
  7172. + gpio-controller;
  7173. + #gpio-cells = <2>;
  7174. + };
  7175. };
  7176. &iomuxc {
  7177. pinctrl-names = "default";
  7178. pinctrl-0 = <&pinctrl_hog>;
  7179. - hog {
  7180. + imx6qdl-sabreauto {
  7181. pinctrl_hog: hoggrp {
  7182. fsl,pins = <
  7183. MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
  7184. MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x80000000
  7185. + MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x80000000
  7186. + MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x80000000
  7187. MX6QDL_PAD_GPIO_18__SD3_VSELECT 0x17059
  7188. >;
  7189. };
  7190. - };
  7191. - ecspi1 {
  7192. - pinctrl_ecspi1_sabreauto: ecspi1-sabreauto {
  7193. + pinctrl_esai1: esai1grp {
  7194. + fsl,pins = <
  7195. + MX6QDL_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1b030
  7196. + MX6QDL_PAD_ENET_RXD1__ESAI_TX_FS 0x1b030
  7197. + MX6QDL_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1b030
  7198. + MX6QDL_PAD_GPIO_5__ESAI_TX2_RX3 0x1b030
  7199. + MX6QDL_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1b030
  7200. + MX6QDL_PAD_ENET_MDC__ESAI_TX5_RX0 0x1b030
  7201. + MX6QDL_PAD_GPIO_17__ESAI_TX0 0x1b030
  7202. + MX6QDL_PAD_NANDF_CS3__ESAI_TX1 0x1b030
  7203. + MX6QDL_PAD_ENET_MDIO__ESAI_RX_CLK 0x1b030
  7204. + MX6QDL_PAD_GPIO_9__ESAI_RX_FS 0x1b030
  7205. + >;
  7206. + };
  7207. +
  7208. + pinctrl_ecspi1: ecspi1grp {
  7209. + fsl,pins = <
  7210. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  7211. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  7212. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  7213. + >;
  7214. + };
  7215. +
  7216. + pinctrl_ecspi1_cs: ecspi1cs {
  7217. fsl,pins = <
  7218. MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
  7219. >;
  7220. };
  7221. +
  7222. + pinctrl_enet: enetgrp {
  7223. + fsl,pins = <
  7224. + MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
  7225. + MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0
  7226. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  7227. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  7228. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  7229. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  7230. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  7231. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  7232. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  7233. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  7234. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  7235. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  7236. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  7237. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  7238. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  7239. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  7240. + >;
  7241. + };
  7242. +
  7243. + pinctrl_gpio_leds: gpioledsgrp {
  7244. + fsl,pins = <
  7245. + MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15 0x80000000
  7246. + >;
  7247. + };
  7248. +
  7249. + pinctrl_gpmi_nand: gpminandgrp {
  7250. + fsl,pins = <
  7251. + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
  7252. + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
  7253. + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
  7254. + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
  7255. + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
  7256. + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
  7257. + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
  7258. + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
  7259. + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
  7260. + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
  7261. + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
  7262. + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
  7263. + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
  7264. + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
  7265. + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
  7266. + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
  7267. + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
  7268. + >;
  7269. + };
  7270. +
  7271. + pinctrl_hdmi_cec_2: hdmicecgrp-2 {
  7272. + fsl,pins = <
  7273. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  7274. + >;
  7275. + };
  7276. +
  7277. + pinctrl_i2c2: i2c2grp {
  7278. + fsl,pins = <
  7279. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  7280. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  7281. + >;
  7282. + };
  7283. +
  7284. + pinctrl_i2c3: i2c3grp {
  7285. + fsl,pins = <
  7286. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  7287. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  7288. + >;
  7289. + };
  7290. +
  7291. + pinctrl_pwm1: pwm1grp {
  7292. + fsl,pins = <
  7293. + MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
  7294. + >;
  7295. + };
  7296. +
  7297. + pinctrl_spdif: spdifgrp {
  7298. + fsl,pins = <
  7299. + MX6QDL_PAD_KEY_COL3__SPDIF_IN 0x1b0b0
  7300. + >;
  7301. + };
  7302. +
  7303. + pinctrl_uart3: uart3grp {
  7304. + fsl,pins = <
  7305. + MX6QDL_PAD_SD4_CLK__UART3_RX_DATA 0x1b0b1
  7306. + MX6QDL_PAD_SD4_CMD__UART3_TX_DATA 0x1b0b1
  7307. + MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1
  7308. + MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  7309. + >;
  7310. + };
  7311. +
  7312. + pinctrl_uart4: uart4grp {
  7313. + fsl,pins = <
  7314. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  7315. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  7316. + >;
  7317. + };
  7318. +
  7319. + pinctrl_usdhc3: usdhc3grp {
  7320. + fsl,pins = <
  7321. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  7322. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  7323. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  7324. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  7325. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  7326. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  7327. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  7328. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  7329. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  7330. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  7331. + >;
  7332. + };
  7333. +
  7334. + pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
  7335. + fsl,pins = <
  7336. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9
  7337. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9
  7338. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  7339. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  7340. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  7341. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  7342. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
  7343. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
  7344. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
  7345. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
  7346. + >;
  7347. + };
  7348. +
  7349. + pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
  7350. + fsl,pins = <
  7351. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9
  7352. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9
  7353. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  7354. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  7355. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  7356. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  7357. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
  7358. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
  7359. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
  7360. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
  7361. + >;
  7362. + };
  7363. +
  7364. + pinctrl_weim_cs0: weimcs0grp {
  7365. + fsl,pins = <
  7366. + MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1
  7367. + >;
  7368. + };
  7369. +
  7370. + pinctrl_weim_nor: weimnorgrp {
  7371. + fsl,pins = <
  7372. + MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1
  7373. + MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1
  7374. + MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
  7375. + MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
  7376. + MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
  7377. + MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
  7378. + MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
  7379. + MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
  7380. + MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
  7381. + MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
  7382. + MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
  7383. + MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
  7384. + MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
  7385. + MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
  7386. + MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
  7387. + MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
  7388. + MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
  7389. + MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
  7390. + MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
  7391. + MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
  7392. + MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
  7393. + MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
  7394. + MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
  7395. + MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
  7396. + MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
  7397. + MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
  7398. + MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
  7399. + MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1
  7400. + MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1
  7401. + MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1
  7402. + MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1
  7403. + MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1
  7404. + MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1
  7405. + MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1
  7406. + MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1
  7407. + MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1
  7408. + MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1
  7409. + MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1
  7410. + MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1
  7411. + MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1
  7412. + MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1
  7413. + MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1
  7414. + MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1
  7415. + >;
  7416. + };
  7417. + };
  7418. +};
  7419. +
  7420. +&ldb {
  7421. + status = "okay";
  7422. +
  7423. + lvds-channel@0 {
  7424. + fsl,data-mapping = "spwg";
  7425. + fsl,data-width = <18>;
  7426. + status = "okay";
  7427. +
  7428. + display-timings {
  7429. + native-mode = <&timing0>;
  7430. + timing0: hsd100pxn1 {
  7431. + clock-frequency = <65000000>;
  7432. + hactive = <1024>;
  7433. + vactive = <768>;
  7434. + hback-porch = <220>;
  7435. + hfront-porch = <40>;
  7436. + vback-porch = <21>;
  7437. + vfront-porch = <7>;
  7438. + hsync-len = <60>;
  7439. + vsync-len = <10>;
  7440. + };
  7441. + };
  7442. };
  7443. };
  7444. +&pcie {
  7445. + status = "okay";
  7446. +};
  7447. +
  7448. +&pwm3 {
  7449. + pinctrl-names = "default";
  7450. + pinctrl-0 = <&pinctrl_pwm1>;
  7451. + status = "okay";
  7452. +};
  7453. +
  7454. +&spdif {
  7455. + pinctrl-names = "default";
  7456. + pinctrl-0 = <&pinctrl_spdif>;
  7457. + status = "okay";
  7458. +};
  7459. +
  7460. +&uart3 {
  7461. + pinctrl-names = "default";
  7462. + pinctrl-0 = <&pinctrl_uart3>;
  7463. + pinctrl-assert-gpios = <&max7310_b 4 GPIO_ACTIVE_HIGH>, /* CTS */
  7464. + <&max7310_c 3 GPIO_ACTIVE_HIGH>; /* RXD and TXD */
  7465. + fsl,uart-has-rtscts;
  7466. + status = "okay";
  7467. +};
  7468. +
  7469. &uart4 {
  7470. pinctrl-names = "default";
  7471. - pinctrl-0 = <&pinctrl_uart4_1>;
  7472. + pinctrl-0 = <&pinctrl_uart4>;
  7473. status = "okay";
  7474. };
  7475. &usdhc3 {
  7476. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  7477. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  7478. - pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
  7479. - pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
  7480. + pinctrl-0 = <&pinctrl_usdhc3>;
  7481. + pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
  7482. + pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
  7483. cd-gpios = <&gpio6 15 0>;
  7484. wp-gpios = <&gpio1 13 0>;
  7485. status = "okay";
  7486. @@ -86,7 +645,7 @@
  7487. &weim {
  7488. pinctrl-names = "default";
  7489. - pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
  7490. + pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>;
  7491. #address-cells = <2>;
  7492. #size-cells = <1>;
  7493. ranges = <0 0 0x08000000 0x08000000>;
  7494. @@ -102,3 +661,48 @@
  7495. 0x0000c000 0x1404a38e 0x00000000>;
  7496. };
  7497. };
  7498. +
  7499. +&ldb {
  7500. + ipu_id = <1>;
  7501. + disp_id = <0>;
  7502. + ext_ref = <1>;
  7503. + mode = "sep0";
  7504. + sec_ipu_id = <1>;
  7505. + sec_disp_id = <1>;
  7506. + status = "okay";
  7507. +};
  7508. +
  7509. +&esai {
  7510. + pinctrl-names = "default";
  7511. + pinctrl-0 = <&pinctrl_esai1>;
  7512. + status = "okay";
  7513. +};
  7514. +
  7515. +&hdmi_core {
  7516. + ipu_id = <0>;
  7517. + disp_id = <1>;
  7518. + status = "okay";
  7519. +};
  7520. +
  7521. +&hdmi_video {
  7522. + fsl,phy_reg_vlev = <0x0294>;
  7523. + fsl,phy_reg_cksymtx = <0x800d>;
  7524. + status = "okay";
  7525. +};
  7526. +
  7527. +&hdmi_audio {
  7528. + status = "okay";
  7529. +};
  7530. +
  7531. +&hdmi_cec {
  7532. + pinctrl-names = "default";
  7533. + pinctrl-0 = <&pinctrl_hdmi_cec_2>;
  7534. + status = "okay";
  7535. +};
  7536. +
  7537. +&gpc {
  7538. + fsl,cpu_pupscr_sw2iso = <0xf>;
  7539. + fsl,cpu_pupscr_sw = <0xf>;
  7540. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  7541. + fsl,cpu_pdnscr_iso = <0x1>;
  7542. +};
  7543. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
  7544. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi 1970-01-01 01:00:00.000000000 +0100
  7545. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi 2014-09-11 18:05:52.642000568 +0200
  7546. @@ -0,0 +1,427 @@
  7547. +/*
  7548. + * Copyright 2011 Freescale Semiconductor, Inc.
  7549. + * Copyright 2011 Linaro Ltd.
  7550. + *
  7551. + * The code contained herein is licensed under the GNU General Public
  7552. + * License. You may obtain a copy of the GNU General Public License
  7553. + * Version 2 or later at the following locations:
  7554. + *
  7555. + * http://www.opensource.org/licenses/gpl-license.html
  7556. + * http://www.gnu.org/copyleft/gpl.html
  7557. + */
  7558. +#include <dt-bindings/gpio/gpio.h>
  7559. +#include <dt-bindings/input/input.h>
  7560. +
  7561. +/ {
  7562. + chosen {
  7563. + stdout-path = &uart2;
  7564. + };
  7565. +
  7566. + memory {
  7567. + reg = <0x10000000 0x40000000>;
  7568. + };
  7569. +
  7570. + regulators {
  7571. + compatible = "simple-bus";
  7572. + #address-cells = <1>;
  7573. + #size-cells = <0>;
  7574. +
  7575. + reg_2p5v: regulator@0 {
  7576. + compatible = "regulator-fixed";
  7577. + reg = <0>;
  7578. + regulator-name = "2P5V";
  7579. + regulator-min-microvolt = <2500000>;
  7580. + regulator-max-microvolt = <2500000>;
  7581. + regulator-always-on;
  7582. + };
  7583. +
  7584. + reg_3p3v: regulator@1 {
  7585. + compatible = "regulator-fixed";
  7586. + reg = <1>;
  7587. + regulator-name = "3P3V";
  7588. + regulator-min-microvolt = <3300000>;
  7589. + regulator-max-microvolt = <3300000>;
  7590. + regulator-always-on;
  7591. + };
  7592. +
  7593. + reg_usb_otg_vbus: regulator@2 {
  7594. + compatible = "regulator-fixed";
  7595. + reg = <2>;
  7596. + regulator-name = "usb_otg_vbus";
  7597. + regulator-min-microvolt = <5000000>;
  7598. + regulator-max-microvolt = <5000000>;
  7599. + gpio = <&gpio3 22 0>;
  7600. + enable-active-high;
  7601. + };
  7602. + };
  7603. +
  7604. + gpio-keys {
  7605. + compatible = "gpio-keys";
  7606. + pinctrl-names = "default";
  7607. + pinctrl-0 = <&pinctrl_gpio_keys>;
  7608. +
  7609. + power {
  7610. + label = "Power Button";
  7611. + gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
  7612. + linux,code = <KEY_POWER>;
  7613. + gpio-key,wakeup;
  7614. + };
  7615. +
  7616. + menu {
  7617. + label = "Menu";
  7618. + gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
  7619. + linux,code = <KEY_MENU>;
  7620. + };
  7621. +
  7622. + home {
  7623. + label = "Home";
  7624. + gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
  7625. + linux,code = <KEY_HOME>;
  7626. + };
  7627. +
  7628. + back {
  7629. + label = "Back";
  7630. + gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
  7631. + linux,code = <KEY_BACK>;
  7632. + };
  7633. +
  7634. + volume-up {
  7635. + label = "Volume Up";
  7636. + gpios = <&gpio7 13 GPIO_ACTIVE_LOW>;
  7637. + linux,code = <KEY_VOLUMEUP>;
  7638. + };
  7639. +
  7640. + volume-down {
  7641. + label = "Volume Down";
  7642. + gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
  7643. + linux,code = <KEY_VOLUMEDOWN>;
  7644. + };
  7645. + };
  7646. +
  7647. + sound {
  7648. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  7649. + "fsl,imx-audio-sgtl5000";
  7650. + model = "imx6q-sabrelite-sgtl5000";
  7651. + ssi-controller = <&ssi1>;
  7652. + audio-codec = <&codec>;
  7653. + audio-routing =
  7654. + "MIC_IN", "Mic Jack",
  7655. + "Mic Jack", "Mic Bias",
  7656. + "Headphone Jack", "HP_OUT";
  7657. + mux-int-port = <1>;
  7658. + mux-ext-port = <4>;
  7659. + };
  7660. +
  7661. + backlight_lcd {
  7662. + compatible = "pwm-backlight";
  7663. + pwms = <&pwm1 0 5000000>;
  7664. + brightness-levels = <0 4 8 16 32 64 128 255>;
  7665. + default-brightness-level = <7>;
  7666. + power-supply = <&reg_3p3v>;
  7667. + status = "okay";
  7668. + };
  7669. +
  7670. + backlight_lvds {
  7671. + compatible = "pwm-backlight";
  7672. + pwms = <&pwm4 0 5000000>;
  7673. + brightness-levels = <0 4 8 16 32 64 128 255>;
  7674. + default-brightness-level = <7>;
  7675. + power-supply = <&reg_3p3v>;
  7676. + status = "okay";
  7677. + };
  7678. +};
  7679. +
  7680. +&audmux {
  7681. + pinctrl-names = "default";
  7682. + pinctrl-0 = <&pinctrl_audmux>;
  7683. + status = "okay";
  7684. +};
  7685. +
  7686. +&ecspi1 {
  7687. + fsl,spi-num-chipselects = <1>;
  7688. + cs-gpios = <&gpio3 19 0>;
  7689. + pinctrl-names = "default";
  7690. + pinctrl-0 = <&pinctrl_ecspi1>;
  7691. + status = "okay";
  7692. +
  7693. + flash: m25p80@0 {
  7694. + compatible = "sst,sst25vf016b";
  7695. + spi-max-frequency = <20000000>;
  7696. + reg = <0>;
  7697. + };
  7698. +};
  7699. +
  7700. +&fec {
  7701. + pinctrl-names = "default";
  7702. + pinctrl-0 = <&pinctrl_enet>;
  7703. + phy-mode = "rgmii";
  7704. + phy-reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
  7705. + txen-skew-ps = <0>;
  7706. + txc-skew-ps = <3000>;
  7707. + rxdv-skew-ps = <0>;
  7708. + rxc-skew-ps = <3000>;
  7709. + rxd0-skew-ps = <0>;
  7710. + rxd1-skew-ps = <0>;
  7711. + rxd2-skew-ps = <0>;
  7712. + rxd3-skew-ps = <0>;
  7713. + txd0-skew-ps = <0>;
  7714. + txd1-skew-ps = <0>;
  7715. + txd2-skew-ps = <0>;
  7716. + txd3-skew-ps = <0>;
  7717. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  7718. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  7719. + status = "okay";
  7720. +};
  7721. +
  7722. +&i2c1 {
  7723. + clock-frequency = <100000>;
  7724. + pinctrl-names = "default";
  7725. + pinctrl-0 = <&pinctrl_i2c1>;
  7726. + status = "okay";
  7727. +
  7728. + codec: sgtl5000@0a {
  7729. + compatible = "fsl,sgtl5000";
  7730. + reg = <0x0a>;
  7731. + clocks = <&clks 201>;
  7732. + VDDA-supply = <&reg_2p5v>;
  7733. + VDDIO-supply = <&reg_3p3v>;
  7734. + };
  7735. +};
  7736. +
  7737. +&iomuxc {
  7738. + pinctrl-names = "default";
  7739. + pinctrl-0 = <&pinctrl_hog>;
  7740. +
  7741. + imx6q-sabrelite {
  7742. + pinctrl_hog: hoggrp {
  7743. + fsl,pins = <
  7744. + /* SGTL5000 sys_mclk */
  7745. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x030b0
  7746. + >;
  7747. + };
  7748. +
  7749. + pinctrl_audmux: audmuxgrp {
  7750. + fsl,pins = <
  7751. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  7752. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  7753. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  7754. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  7755. + >;
  7756. + };
  7757. +
  7758. + pinctrl_ecspi1: ecspi1grp {
  7759. + fsl,pins = <
  7760. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  7761. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  7762. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  7763. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x000b1 /* CS */
  7764. + >;
  7765. + };
  7766. +
  7767. + pinctrl_enet: enetgrp {
  7768. + fsl,pins = <
  7769. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0
  7770. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0
  7771. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0
  7772. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0
  7773. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0
  7774. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0
  7775. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0
  7776. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0
  7777. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0
  7778. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  7779. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  7780. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  7781. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  7782. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  7783. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  7784. + /* Phy reset */
  7785. + MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x000b0
  7786. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  7787. + >;
  7788. + };
  7789. +
  7790. + pinctrl_gpio_keys: gpio_keysgrp {
  7791. + fsl,pins = <
  7792. + /* Power Button */
  7793. + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
  7794. + /* Menu Button */
  7795. + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
  7796. + /* Home Button */
  7797. + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0
  7798. + /* Back Button */
  7799. + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
  7800. + /* Volume Up Button */
  7801. + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0
  7802. + /* Volume Down Button */
  7803. + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0
  7804. + >;
  7805. + };
  7806. +
  7807. + pinctrl_i2c1: i2c1grp {
  7808. + fsl,pins = <
  7809. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  7810. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  7811. + >;
  7812. + };
  7813. +
  7814. + pinctrl_pwm1: pwm1grp {
  7815. + fsl,pins = <
  7816. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  7817. + >;
  7818. + };
  7819. +
  7820. + pinctrl_pwm3: pwm3grp {
  7821. + fsl,pins = <
  7822. + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1
  7823. + >;
  7824. + };
  7825. +
  7826. + pinctrl_pwm4: pwm4grp {
  7827. + fsl,pins = <
  7828. + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1
  7829. + >;
  7830. + };
  7831. +
  7832. + pinctrl_uart1: uart1grp {
  7833. + fsl,pins = <
  7834. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  7835. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  7836. + >;
  7837. + };
  7838. +
  7839. + pinctrl_uart2: uart2grp {
  7840. + fsl,pins = <
  7841. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  7842. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  7843. + >;
  7844. + };
  7845. +
  7846. + pinctrl_usbotg: usbotggrp {
  7847. + fsl,pins = <
  7848. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  7849. + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0
  7850. + /* power enable, high active */
  7851. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x000b0
  7852. + >;
  7853. + };
  7854. +
  7855. + pinctrl_usdhc3: usdhc3grp {
  7856. + fsl,pins = <
  7857. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  7858. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  7859. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  7860. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  7861. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  7862. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  7863. + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /* CD */
  7864. + MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0 /* WP */
  7865. + >;
  7866. + };
  7867. +
  7868. + pinctrl_usdhc4: usdhc4grp {
  7869. + fsl,pins = <
  7870. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  7871. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  7872. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  7873. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  7874. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  7875. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  7876. + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /* CD */
  7877. + >;
  7878. + };
  7879. + };
  7880. +};
  7881. +
  7882. +&ldb {
  7883. + status = "okay";
  7884. +
  7885. + lvds-channel@0 {
  7886. + fsl,data-mapping = "spwg";
  7887. + fsl,data-width = <18>;
  7888. + status = "okay";
  7889. +
  7890. + display-timings {
  7891. + native-mode = <&timing0>;
  7892. + timing0: hsd100pxn1 {
  7893. + clock-frequency = <65000000>;
  7894. + hactive = <1024>;
  7895. + vactive = <768>;
  7896. + hback-porch = <220>;
  7897. + hfront-porch = <40>;
  7898. + vback-porch = <21>;
  7899. + vfront-porch = <7>;
  7900. + hsync-len = <60>;
  7901. + vsync-len = <10>;
  7902. + };
  7903. + };
  7904. + };
  7905. +};
  7906. +
  7907. +&pcie {
  7908. + status = "okay";
  7909. +};
  7910. +
  7911. +&pwm1 {
  7912. + pinctrl-names = "default";
  7913. + pinctrl-0 = <&pinctrl_pwm1>;
  7914. + status = "okay";
  7915. +};
  7916. +
  7917. +&pwm3 {
  7918. + pinctrl-names = "default";
  7919. + pinctrl-0 = <&pinctrl_pwm3>;
  7920. + status = "okay";
  7921. +};
  7922. +
  7923. +&pwm4 {
  7924. + pinctrl-names = "default";
  7925. + pinctrl-0 = <&pinctrl_pwm4>;
  7926. + status = "okay";
  7927. +};
  7928. +
  7929. +&ssi1 {
  7930. + fsl,mode = "i2s-slave";
  7931. + status = "okay";
  7932. +};
  7933. +
  7934. +&uart1 {
  7935. + pinctrl-names = "default";
  7936. + pinctrl-0 = <&pinctrl_uart1>;
  7937. + status = "okay";
  7938. +};
  7939. +
  7940. +&uart2 {
  7941. + pinctrl-names = "default";
  7942. + pinctrl-0 = <&pinctrl_uart2>;
  7943. + status = "okay";
  7944. +};
  7945. +
  7946. +&usbh1 {
  7947. + status = "okay";
  7948. +};
  7949. +
  7950. +&usbotg {
  7951. + vbus-supply = <&reg_usb_otg_vbus>;
  7952. + pinctrl-names = "default";
  7953. + pinctrl-0 = <&pinctrl_usbotg>;
  7954. + disable-over-current;
  7955. + status = "okay";
  7956. +};
  7957. +
  7958. +&usdhc3 {
  7959. + pinctrl-names = "default";
  7960. + pinctrl-0 = <&pinctrl_usdhc3>;
  7961. + cd-gpios = <&gpio7 0 0>;
  7962. + wp-gpios = <&gpio7 1 0>;
  7963. + vmmc-supply = <&reg_3p3v>;
  7964. + status = "okay";
  7965. +};
  7966. +
  7967. +&usdhc4 {
  7968. + pinctrl-names = "default";
  7969. + pinctrl-0 = <&pinctrl_usdhc4>;
  7970. + cd-gpios = <&gpio2 6 0>;
  7971. + vmmc-supply = <&reg_3p3v>;
  7972. + status = "okay";
  7973. +};
  7974. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-sabresd.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
  7975. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-sabresd.dtsi 2014-08-14 03:38:34.000000000 +0200
  7976. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-sabresd.dtsi 2014-09-11 18:05:52.646000583 +0200
  7977. @@ -10,16 +10,33 @@
  7978. * http://www.gnu.org/copyleft/gpl.html
  7979. */
  7980. +#include <dt-bindings/gpio/gpio.h>
  7981. +#include <dt-bindings/input/input.h>
  7982. +
  7983. / {
  7984. + aliases {
  7985. + mxcfb0 = &mxcfb1;
  7986. + mxcfb1 = &mxcfb2;
  7987. + mxcfb2 = &mxcfb3;
  7988. + mxcfb3 = &mxcfb4;
  7989. + };
  7990. +
  7991. + chosen {
  7992. + stdout-path = &uart1;
  7993. + };
  7994. +
  7995. memory {
  7996. reg = <0x10000000 0x40000000>;
  7997. };
  7998. regulators {
  7999. compatible = "simple-bus";
  8000. + #address-cells = <1>;
  8001. + #size-cells = <0>;
  8002. - reg_usb_otg_vbus: usb_otg_vbus {
  8003. + reg_usb_otg_vbus: regulator@0 {
  8004. compatible = "regulator-fixed";
  8005. + reg = <0>;
  8006. regulator-name = "usb_otg_vbus";
  8007. regulator-min-microvolt = <5000000>;
  8008. regulator-max-microvolt = <5000000>;
  8009. @@ -27,8 +44,9 @@
  8010. enable-active-high;
  8011. };
  8012. - reg_usb_h1_vbus: usb_h1_vbus {
  8013. + reg_usb_h1_vbus: regulator@1 {
  8014. compatible = "regulator-fixed";
  8015. + reg = <1>;
  8016. regulator-name = "usb_h1_vbus";
  8017. regulator-min-microvolt = <5000000>;
  8018. regulator-max-microvolt = <5000000>;
  8019. @@ -36,29 +54,46 @@
  8020. enable-active-high;
  8021. };
  8022. - reg_audio: wm8962_supply {
  8023. + reg_audio: regulator@2 {
  8024. compatible = "regulator-fixed";
  8025. + reg = <2>;
  8026. regulator-name = "wm8962-supply";
  8027. gpio = <&gpio4 10 0>;
  8028. enable-active-high;
  8029. };
  8030. +
  8031. + reg_mipi_dsi_pwr_on: mipi_dsi_pwr_on {
  8032. + compatible = "regulator-fixed";
  8033. + regulator-name = "mipi_dsi_pwr_on";
  8034. + gpio = <&gpio6 14 0>;
  8035. + enable-active-high;
  8036. + };
  8037. };
  8038. gpio-keys {
  8039. compatible = "gpio-keys";
  8040. + pinctrl-names = "default";
  8041. + pinctrl-0 = <&pinctrl_gpio_keys>;
  8042. +
  8043. + power {
  8044. + label = "Power Button";
  8045. + gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
  8046. + gpio-key,wakeup;
  8047. + linux,code = <KEY_POWER>;
  8048. + };
  8049. volume-up {
  8050. label = "Volume Up";
  8051. - gpios = <&gpio1 4 0>;
  8052. + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
  8053. gpio-key,wakeup;
  8054. - linux,code = <115>; /* KEY_VOLUMEUP */
  8055. + linux,code = <KEY_VOLUMEUP>;
  8056. };
  8057. volume-down {
  8058. label = "Volume Down";
  8059. - gpios = <&gpio1 5 0>;
  8060. + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
  8061. gpio-key,wakeup;
  8062. - linux,code = <114>; /* KEY_VOLUMEDOWN */
  8063. + linux,code = <KEY_VOLUMEDOWN>;
  8064. };
  8065. };
  8066. @@ -88,11 +123,107 @@
  8067. default-brightness-level = <7>;
  8068. status = "okay";
  8069. };
  8070. +
  8071. + leds {
  8072. + compatible = "gpio-leds";
  8073. + pinctrl-names = "default";
  8074. + pinctrl-0 = <&pinctrl_gpio_leds>;
  8075. +
  8076. + red {
  8077. + gpios = <&gpio1 2 0>;
  8078. + default-state = "on";
  8079. + };
  8080. + };
  8081. +
  8082. + sound-hdmi {
  8083. + compatible = "fsl,imx6q-audio-hdmi",
  8084. + "fsl,imx-audio-hdmi";
  8085. + model = "imx-audio-hdmi";
  8086. + hdmi-controller = <&hdmi_audio>;
  8087. + };
  8088. +
  8089. + mxcfb1: fb@0 {
  8090. + compatible = "fsl,mxc_sdc_fb";
  8091. + disp_dev = "ldb";
  8092. + interface_pix_fmt = "RGB666";
  8093. + mode_str ="LDB-XGA";
  8094. + default_bpp = <16>;
  8095. + int_clk = <0>;
  8096. + late_init = <0>;
  8097. + status = "disabled";
  8098. + };
  8099. +
  8100. + mxcfb2: fb@1 {
  8101. + compatible = "fsl,mxc_sdc_fb";
  8102. + disp_dev = "hdmi";
  8103. + interface_pix_fmt = "RGB24";
  8104. + mode_str ="1920x1080M@60";
  8105. + default_bpp = <24>;
  8106. + int_clk = <0>;
  8107. + late_init = <0>;
  8108. + status = "disabled";
  8109. + };
  8110. +
  8111. + mxcfb3: fb@2 {
  8112. + compatible = "fsl,mxc_sdc_fb";
  8113. + disp_dev = "lcd";
  8114. + interface_pix_fmt = "RGB565";
  8115. + mode_str ="CLAA-WVGA";
  8116. + default_bpp = <16>;
  8117. + int_clk = <0>;
  8118. + late_init = <0>;
  8119. + status = "disabled";
  8120. + };
  8121. +
  8122. + mxcfb4: fb@3 {
  8123. + compatible = "fsl,mxc_sdc_fb";
  8124. + disp_dev = "ldb";
  8125. + interface_pix_fmt = "RGB666";
  8126. + mode_str ="LDB-XGA";
  8127. + default_bpp = <16>;
  8128. + int_clk = <0>;
  8129. + late_init = <0>;
  8130. + status = "disabled";
  8131. + };
  8132. +
  8133. + lcd@0 {
  8134. + compatible = "fsl,lcd";
  8135. + ipu_id = <0>;
  8136. + disp_id = <0>;
  8137. + default_ifmt = "RGB565";
  8138. + pinctrl-names = "default";
  8139. + pinctrl-0 = <&pinctrl_ipu1>;
  8140. + status = "okay";
  8141. + };
  8142. +
  8143. + backlight {
  8144. + compatible = "pwm-backlight";
  8145. + pwms = <&pwm1 0 5000000>;
  8146. + brightness-levels = <0 4 8 16 32 64 128 255>;
  8147. + default-brightness-level = <7>;
  8148. + };
  8149. +
  8150. + v4l2_out {
  8151. + compatible = "fsl,mxc_v4l2_output";
  8152. + status = "okay";
  8153. + };
  8154. +
  8155. + lvds_cabc_ctrl {
  8156. + lvds0-gpios = <&gpio6 15 0>;
  8157. + lvds1-gpios = <&gpio6 16 0>;
  8158. + };
  8159. +
  8160. + mipi_dsi_reset: mipi-dsi-reset {
  8161. + compatible = "gpio-reset";
  8162. + reset-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
  8163. + reset-delay-us = <50>;
  8164. + #reset-cells = <0>;
  8165. + };
  8166. };
  8167. &audmux {
  8168. pinctrl-names = "default";
  8169. - pinctrl-0 = <&pinctrl_audmux_2>;
  8170. + pinctrl-0 = <&pinctrl_audmux>;
  8171. status = "okay";
  8172. };
  8173. @@ -100,7 +231,7 @@
  8174. fsl,spi-num-chipselects = <1>;
  8175. cs-gpios = <&gpio4 9 0>;
  8176. pinctrl-names = "default";
  8177. - pinctrl-0 = <&pinctrl_ecspi1_2>;
  8178. + pinctrl-0 = <&pinctrl_ecspi1>;
  8179. status = "okay";
  8180. flash: m25p80@0 {
  8181. @@ -114,7 +245,7 @@
  8182. &fec {
  8183. pinctrl-names = "default";
  8184. - pinctrl-0 = <&pinctrl_enet_1>;
  8185. + pinctrl-0 = <&pinctrl_enet>;
  8186. phy-mode = "rgmii";
  8187. phy-reset-gpios = <&gpio1 25 0>;
  8188. status = "okay";
  8189. @@ -123,7 +254,7 @@
  8190. &i2c1 {
  8191. clock-frequency = <100000>;
  8192. pinctrl-names = "default";
  8193. - pinctrl-0 = <&pinctrl_i2c1_2>;
  8194. + pinctrl-0 = <&pinctrl_i2c1>;
  8195. status = "okay";
  8196. codec: wm8962@1a {
  8197. @@ -149,10 +280,121 @@
  8198. };
  8199. };
  8200. +&i2c2 {
  8201. + clock-frequency = <100000>;
  8202. + pinctrl-names = "default";
  8203. + pinctrl-0 = <&pinctrl_i2c2>;
  8204. + status = "okay";
  8205. +
  8206. + hdmi: edid@50 {
  8207. + compatible = "fsl,imx6-hdmi-i2c";
  8208. + reg = <0x50>;
  8209. + };
  8210. +
  8211. + pmic: pfuze100@08 {
  8212. + compatible = "fsl,pfuze100";
  8213. + reg = <0x08>;
  8214. +
  8215. + regulators {
  8216. + sw1a_reg: sw1ab {
  8217. + regulator-min-microvolt = <300000>;
  8218. + regulator-max-microvolt = <1875000>;
  8219. + regulator-boot-on;
  8220. + regulator-always-on;
  8221. + regulator-ramp-delay = <6250>;
  8222. + };
  8223. +
  8224. + sw1c_reg: sw1c {
  8225. + regulator-min-microvolt = <300000>;
  8226. + regulator-max-microvolt = <1875000>;
  8227. + regulator-boot-on;
  8228. + regulator-always-on;
  8229. + regulator-ramp-delay = <6250>;
  8230. + };
  8231. +
  8232. + sw2_reg: sw2 {
  8233. + regulator-min-microvolt = <800000>;
  8234. + regulator-max-microvolt = <3300000>;
  8235. + regulator-boot-on;
  8236. + regulator-always-on;
  8237. + };
  8238. +
  8239. + sw3a_reg: sw3a {
  8240. + regulator-min-microvolt = <400000>;
  8241. + regulator-max-microvolt = <1975000>;
  8242. + regulator-boot-on;
  8243. + regulator-always-on;
  8244. + };
  8245. +
  8246. + sw3b_reg: sw3b {
  8247. + regulator-min-microvolt = <400000>;
  8248. + regulator-max-microvolt = <1975000>;
  8249. + regulator-boot-on;
  8250. + regulator-always-on;
  8251. + };
  8252. +
  8253. + sw4_reg: sw4 {
  8254. + regulator-min-microvolt = <800000>;
  8255. + regulator-max-microvolt = <3300000>;
  8256. + };
  8257. +
  8258. + swbst_reg: swbst {
  8259. + regulator-min-microvolt = <5000000>;
  8260. + regulator-max-microvolt = <5150000>;
  8261. + };
  8262. +
  8263. + snvs_reg: vsnvs {
  8264. + regulator-min-microvolt = <1000000>;
  8265. + regulator-max-microvolt = <3000000>;
  8266. + regulator-boot-on;
  8267. + regulator-always-on;
  8268. + };
  8269. +
  8270. + vref_reg: vrefddr {
  8271. + regulator-boot-on;
  8272. + regulator-always-on;
  8273. + };
  8274. +
  8275. + vgen1_reg: vgen1 {
  8276. + regulator-min-microvolt = <800000>;
  8277. + regulator-max-microvolt = <1550000>;
  8278. + };
  8279. +
  8280. + vgen2_reg: vgen2 {
  8281. + regulator-min-microvolt = <800000>;
  8282. + regulator-max-microvolt = <1550000>;
  8283. + };
  8284. +
  8285. + vgen3_reg: vgen3 {
  8286. + regulator-min-microvolt = <1800000>;
  8287. + regulator-max-microvolt = <3300000>;
  8288. + };
  8289. +
  8290. + vgen4_reg: vgen4 {
  8291. + regulator-min-microvolt = <1800000>;
  8292. + regulator-max-microvolt = <3300000>;
  8293. + regulator-always-on;
  8294. + };
  8295. +
  8296. + vgen5_reg: vgen5 {
  8297. + regulator-min-microvolt = <1800000>;
  8298. + regulator-max-microvolt = <3300000>;
  8299. + regulator-always-on;
  8300. + };
  8301. +
  8302. + vgen6_reg: vgen6 {
  8303. + regulator-min-microvolt = <1800000>;
  8304. + regulator-max-microvolt = <3300000>;
  8305. + regulator-always-on;
  8306. + };
  8307. + };
  8308. + };
  8309. +};
  8310. +
  8311. &i2c3 {
  8312. clock-frequency = <100000>;
  8313. pinctrl-names = "default";
  8314. - pinctrl-0 = <&pinctrl_i2c3_2>;
  8315. + pinctrl-0 = <&pinctrl_i2c3>;
  8316. status = "okay";
  8317. egalax_ts@04 {
  8318. @@ -168,11 +410,9 @@
  8319. pinctrl-names = "default";
  8320. pinctrl-0 = <&pinctrl_hog>;
  8321. - hog {
  8322. + imx6qdl-sabresd {
  8323. pinctrl_hog: hoggrp {
  8324. fsl,pins = <
  8325. - MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x80000000
  8326. - MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000
  8327. MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x80000000
  8328. MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
  8329. MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
  8330. @@ -182,6 +422,202 @@
  8331. MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  8332. MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
  8333. MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
  8334. + MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x80000000
  8335. + MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x80000000
  8336. + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x80000000
  8337. + MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x80000000
  8338. + >;
  8339. + };
  8340. +
  8341. + pinctrl_audmux: audmuxgrp {
  8342. + fsl,pins = <
  8343. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  8344. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  8345. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  8346. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  8347. + >;
  8348. + };
  8349. +
  8350. + pinctrl_ecspi1: ecspi1grp {
  8351. + fsl,pins = <
  8352. + MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1
  8353. + MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1
  8354. + MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1
  8355. + >;
  8356. + };
  8357. +
  8358. + pinctrl_enet: enetgrp {
  8359. + fsl,pins = <
  8360. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  8361. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  8362. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  8363. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  8364. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  8365. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  8366. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  8367. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  8368. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  8369. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  8370. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  8371. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  8372. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  8373. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  8374. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  8375. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  8376. + >;
  8377. + };
  8378. +
  8379. + pinctrl_gpio_keys: gpio_keysgrp {
  8380. + fsl,pins = <
  8381. + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000
  8382. + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x80000000
  8383. + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000
  8384. + >;
  8385. + };
  8386. +
  8387. + pinctrl_hdmi_cec: hdmi_cecgrp {
  8388. + fsl,pins = <
  8389. + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
  8390. + >;
  8391. + };
  8392. +
  8393. + pinctrl_hdmi_hdcp: hdmi_hdcpgrp {
  8394. + fsl,pins = <
  8395. + MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
  8396. + MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
  8397. + >;
  8398. + };
  8399. +
  8400. + pinctrl_i2c1: i2c1grp {
  8401. + fsl,pins = <
  8402. + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
  8403. + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
  8404. + >;
  8405. + };
  8406. +
  8407. + pinctrl_i2c2: i2c2grp {
  8408. + fsl,pins = <
  8409. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  8410. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  8411. + >;
  8412. + };
  8413. +
  8414. + pinctrl_i2c3: i2c3grp {
  8415. + fsl,pins = <
  8416. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  8417. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  8418. + >;
  8419. + };
  8420. +
  8421. + pinctrl_ipu1: ipu1grp {
  8422. + fsl,pins = <
  8423. + MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
  8424. + MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x10
  8425. + MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x10
  8426. + MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x10
  8427. + MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x80000000
  8428. + MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x10
  8429. + MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x10
  8430. + MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x10
  8431. + MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x10
  8432. + MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x10
  8433. + MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x10
  8434. + MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x10
  8435. + MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x10
  8436. + MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x10
  8437. + MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x10
  8438. + MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x10
  8439. + MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x10
  8440. + MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x10
  8441. + MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x10
  8442. + MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x10
  8443. + MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x10
  8444. + MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x10
  8445. + MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x10
  8446. + MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x10
  8447. + MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x10
  8448. + MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x10
  8449. + MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x10
  8450. + MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x10
  8451. + MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x10
  8452. + >;
  8453. + };
  8454. +
  8455. + pinctrl_pcie: pciegrp {
  8456. + fsl,pins = <
  8457. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000
  8458. + >;
  8459. + };
  8460. +
  8461. + pinctrl_pwm1: pwm1grp {
  8462. + fsl,pins = <
  8463. + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
  8464. + >;
  8465. + };
  8466. +
  8467. + pinctrl_uart1: uart1grp {
  8468. + fsl,pins = <
  8469. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  8470. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  8471. + >;
  8472. + };
  8473. +
  8474. + pinctrl_usbotg: usbotggrp {
  8475. + fsl,pins = <
  8476. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  8477. + >;
  8478. + };
  8479. +
  8480. + pinctrl_usdhc2: usdhc2grp {
  8481. + fsl,pins = <
  8482. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  8483. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  8484. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  8485. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  8486. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  8487. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  8488. + MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059
  8489. + MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059
  8490. + MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059
  8491. + MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059
  8492. + >;
  8493. + };
  8494. +
  8495. + pinctrl_usdhc3: usdhc3grp {
  8496. + fsl,pins = <
  8497. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  8498. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  8499. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  8500. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  8501. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  8502. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  8503. + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059
  8504. + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059
  8505. + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059
  8506. + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059
  8507. + >;
  8508. + };
  8509. +
  8510. + pinctrl_usdhc4: usdhc4grp {
  8511. + fsl,pins = <
  8512. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  8513. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  8514. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  8515. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  8516. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  8517. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  8518. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  8519. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  8520. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  8521. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  8522. + >;
  8523. + };
  8524. + };
  8525. +
  8526. + gpio_leds {
  8527. + pinctrl_gpio_leds: gpioledsgrp {
  8528. + fsl,pins = <
  8529. + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x80000000
  8530. >;
  8531. };
  8532. };
  8533. @@ -212,9 +648,33 @@
  8534. };
  8535. };
  8536. +&pcie {
  8537. + pinctrl-names = "default";
  8538. + pinctrl-0 = <&pinctrl_pcie>;
  8539. + reset-gpio = <&gpio7 12 0>;
  8540. + status = "okay";
  8541. +};
  8542. +
  8543. +&pcie {
  8544. + power-on-gpio = <&gpio3 19 0>;
  8545. + reset-gpio = <&gpio7 12 0>;
  8546. + status = "okay";
  8547. +};
  8548. +
  8549. +
  8550. &pwm1 {
  8551. pinctrl-names = "default";
  8552. - pinctrl-0 = <&pinctrl_pwm0_1>;
  8553. + pinctrl-0 = <&pinctrl_pwm1>;
  8554. + status = "okay";
  8555. +};
  8556. +
  8557. +&ldb {
  8558. + ipu_id = <1>;
  8559. + disp_id = <1>;
  8560. + ext_ref = <1>;
  8561. + mode = "sep1";
  8562. + sec_ipu_id = <1>;
  8563. + sec_disp_id = <0>;
  8564. status = "okay";
  8565. };
  8566. @@ -225,7 +685,16 @@
  8567. &uart1 {
  8568. pinctrl-names = "default";
  8569. - pinctrl-0 = <&pinctrl_uart1_1>;
  8570. + pinctrl-0 = <&pinctrl_uart1>;
  8571. + status = "okay";
  8572. +};
  8573. +
  8574. +&mipi_dsi {
  8575. + dev_id = <0>;
  8576. + disp_id = <0>;
  8577. + lcd_panel = "TRULY-WVGA";
  8578. + disp-power-on-supply = <&reg_mipi_dsi_pwr_on>;
  8579. + resets = <&mipi_dsi_reset>;
  8580. status = "okay";
  8581. };
  8582. @@ -237,14 +706,14 @@
  8583. &usbotg {
  8584. vbus-supply = <&reg_usb_otg_vbus>;
  8585. pinctrl-names = "default";
  8586. - pinctrl-0 = <&pinctrl_usbotg_2>;
  8587. + pinctrl-0 = <&pinctrl_usbotg>;
  8588. disable-over-current;
  8589. status = "okay";
  8590. };
  8591. &usdhc2 {
  8592. pinctrl-names = "default";
  8593. - pinctrl-0 = <&pinctrl_usdhc2_1>;
  8594. + pinctrl-0 = <&pinctrl_usdhc2>;
  8595. bus-width = <8>;
  8596. cd-gpios = <&gpio2 2 0>;
  8597. wp-gpios = <&gpio2 3 0>;
  8598. @@ -253,9 +722,47 @@
  8599. &usdhc3 {
  8600. pinctrl-names = "default";
  8601. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  8602. + pinctrl-0 = <&pinctrl_usdhc3>;
  8603. bus-width = <8>;
  8604. cd-gpios = <&gpio2 0 0>;
  8605. wp-gpios = <&gpio2 1 0>;
  8606. status = "okay";
  8607. };
  8608. +
  8609. +&usdhc4 {
  8610. + pinctrl-names = "default";
  8611. + pinctrl-0 = <&pinctrl_usdhc4>;
  8612. + bus-width = <8>;
  8613. + non-removable;
  8614. + no-1-8-v;
  8615. + status = "okay";
  8616. +};
  8617. +
  8618. +&hdmi_core {
  8619. + ipu_id = <0>;
  8620. + disp_id = <0>;
  8621. + status = "okay";
  8622. +};
  8623. +
  8624. +&hdmi_video {
  8625. + fsl,phy_reg_vlev = <0x0294>;
  8626. + fsl,phy_reg_cksymtx = <0x800d>;
  8627. + status = "okay";
  8628. +};
  8629. +
  8630. +&hdmi_audio {
  8631. + status = "okay";
  8632. +};
  8633. +
  8634. +&hdmi_cec {
  8635. + pinctrl-names = "default";
  8636. + pinctrl-0 = <&pinctrl_hdmi_cec>;
  8637. + status = "okay";
  8638. +};
  8639. +
  8640. +&gpc {
  8641. + fsl,cpu_pupscr_sw2iso = <0xf>;
  8642. + fsl,cpu_pupscr_sw = <0xf>;
  8643. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  8644. + fsl,cpu_pdnscr_iso = <0x1>;
  8645. +};
  8646. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6qdl-wandboard.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-wandboard.dtsi
  8647. --- linux-3.14.17/arch/arm/boot/dts/imx6qdl-wandboard.dtsi 2014-08-14 03:38:34.000000000 +0200
  8648. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6qdl-wandboard.dtsi 2014-09-11 18:05:52.646000583 +0200
  8649. @@ -12,17 +12,21 @@
  8650. / {
  8651. regulators {
  8652. compatible = "simple-bus";
  8653. + #address-cells = <1>;
  8654. + #size-cells = <0>;
  8655. - reg_2p5v: 2p5v {
  8656. + reg_2p5v: regulator@0 {
  8657. compatible = "regulator-fixed";
  8658. + reg = <0>;
  8659. regulator-name = "2P5V";
  8660. regulator-min-microvolt = <2500000>;
  8661. regulator-max-microvolt = <2500000>;
  8662. regulator-always-on;
  8663. };
  8664. - reg_3p3v: 3p3v {
  8665. + reg_3p3v: regulator@1 {
  8666. compatible = "regulator-fixed";
  8667. + reg = <1>;
  8668. regulator-name = "3P3V";
  8669. regulator-min-microvolt = <3300000>;
  8670. regulator-max-microvolt = <3300000>;
  8671. @@ -54,14 +58,14 @@
  8672. &audmux {
  8673. pinctrl-names = "default";
  8674. - pinctrl-0 = <&pinctrl_audmux_2>;
  8675. + pinctrl-0 = <&pinctrl_audmux>;
  8676. status = "okay";
  8677. };
  8678. &i2c2 {
  8679. clock-frequency = <100000>;
  8680. pinctrl-names = "default";
  8681. - pinctrl-0 = <&pinctrl_i2c2_2>;
  8682. + pinctrl-0 = <&pinctrl_i2c2>;
  8683. status = "okay";
  8684. codec: sgtl5000@0a {
  8685. @@ -77,7 +81,7 @@
  8686. pinctrl-names = "default";
  8687. pinctrl-0 = <&pinctrl_hog>;
  8688. - hog {
  8689. + imx6qdl-wandboard {
  8690. pinctrl_hog: hoggrp {
  8691. fsl,pins = <
  8692. MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0
  8693. @@ -91,20 +95,121 @@
  8694. MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x80000000
  8695. >;
  8696. };
  8697. +
  8698. + pinctrl_audmux: audmuxgrp {
  8699. + fsl,pins = <
  8700. + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
  8701. + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
  8702. + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0
  8703. + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
  8704. + >;
  8705. + };
  8706. +
  8707. + pinctrl_enet: enetgrp {
  8708. + fsl,pins = <
  8709. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  8710. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  8711. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  8712. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  8713. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  8714. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  8715. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  8716. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  8717. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  8718. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  8719. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  8720. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  8721. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  8722. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  8723. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  8724. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  8725. + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1
  8726. + >;
  8727. + };
  8728. +
  8729. + pinctrl_i2c2: i2c2grp {
  8730. + fsl,pins = <
  8731. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  8732. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  8733. + >;
  8734. + };
  8735. +
  8736. + pinctrl_spdif: spdifgrp {
  8737. + fsl,pins = <
  8738. + MX6QDL_PAD_ENET_RXD0__SPDIF_OUT 0x1b0b0
  8739. + >;
  8740. + };
  8741. +
  8742. + pinctrl_uart1: uart1grp {
  8743. + fsl,pins = <
  8744. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  8745. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  8746. + >;
  8747. + };
  8748. +
  8749. + pinctrl_uart3: uart3grp {
  8750. + fsl,pins = <
  8751. + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
  8752. + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
  8753. + MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1
  8754. + MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1
  8755. + >;
  8756. + };
  8757. +
  8758. + pinctrl_usbotg: usbotggrp {
  8759. + fsl,pins = <
  8760. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  8761. + >;
  8762. + };
  8763. +
  8764. + pinctrl_usdhc1: usdhc1grp {
  8765. + fsl,pins = <
  8766. + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059
  8767. + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059
  8768. + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  8769. + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  8770. + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  8771. + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  8772. + >;
  8773. + };
  8774. +
  8775. + pinctrl_usdhc2: usdhc2grp {
  8776. + fsl,pins = <
  8777. + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
  8778. + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
  8779. + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  8780. + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  8781. + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  8782. + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  8783. + >;
  8784. + };
  8785. +
  8786. + pinctrl_usdhc3: usdhc3grp {
  8787. + fsl,pins = <
  8788. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  8789. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  8790. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  8791. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  8792. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  8793. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  8794. + >;
  8795. + };
  8796. };
  8797. };
  8798. &fec {
  8799. pinctrl-names = "default";
  8800. - pinctrl-0 = <&pinctrl_enet_1>;
  8801. + pinctrl-0 = <&pinctrl_enet>;
  8802. phy-mode = "rgmii";
  8803. phy-reset-gpios = <&gpio3 29 0>;
  8804. + interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
  8805. + <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
  8806. status = "okay";
  8807. };
  8808. &spdif {
  8809. pinctrl-names = "default";
  8810. - pinctrl-0 = <&pinctrl_spdif_3>;
  8811. + pinctrl-0 = <&pinctrl_spdif>;
  8812. status = "okay";
  8813. };
  8814. @@ -115,13 +220,13 @@
  8815. &uart1 {
  8816. pinctrl-names = "default";
  8817. - pinctrl-0 = <&pinctrl_uart1_1>;
  8818. + pinctrl-0 = <&pinctrl_uart1>;
  8819. status = "okay";
  8820. };
  8821. &uart3 {
  8822. pinctrl-names = "default";
  8823. - pinctrl-0 = <&pinctrl_uart3_2>;
  8824. + pinctrl-0 = <&pinctrl_uart3>;
  8825. fsl,uart-has-rtscts;
  8826. status = "okay";
  8827. };
  8828. @@ -132,7 +237,7 @@
  8829. &usbotg {
  8830. pinctrl-names = "default";
  8831. - pinctrl-0 = <&pinctrl_usbotg_1>;
  8832. + pinctrl-0 = <&pinctrl_usbotg>;
  8833. disable-over-current;
  8834. dr_mode = "peripheral";
  8835. status = "okay";
  8836. @@ -140,21 +245,21 @@
  8837. &usdhc1 {
  8838. pinctrl-names = "default";
  8839. - pinctrl-0 = <&pinctrl_usdhc1_2>;
  8840. + pinctrl-0 = <&pinctrl_usdhc1>;
  8841. cd-gpios = <&gpio1 2 0>;
  8842. status = "okay";
  8843. };
  8844. &usdhc2 {
  8845. pinctrl-names = "default";
  8846. - pinctrl-0 = <&pinctrl_usdhc2_2>;
  8847. + pinctrl-0 = <&pinctrl_usdhc2>;
  8848. non-removable;
  8849. status = "okay";
  8850. };
  8851. &usdhc3 {
  8852. pinctrl-names = "default";
  8853. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  8854. + pinctrl-0 = <&pinctrl_usdhc3>;
  8855. cd-gpios = <&gpio3 9 0>;
  8856. status = "okay";
  8857. };
  8858. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
  8859. --- linux-3.14.17/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts 1970-01-01 01:00:00.000000000 +0100
  8860. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts 2014-09-11 18:05:52.634000535 +0200
  8861. @@ -0,0 +1,432 @@
  8862. +/*
  8863. + * Copyright 2013 Data Modul AG
  8864. + *
  8865. + * The code contained herein is licensed under the GNU General Public
  8866. + * License. You may obtain a copy of the GNU General Public License
  8867. + * Version 2 or later at the following locations:
  8868. + *
  8869. + * http://www.opensource.org/licenses/gpl-license.html
  8870. + * http://www.gnu.org/copyleft/gpl.html
  8871. + */
  8872. +
  8873. +/dts-v1/;
  8874. +
  8875. +#include <dt-bindings/gpio/gpio.h>
  8876. +#include "imx6q.dtsi"
  8877. +
  8878. +/ {
  8879. + model = "Data Modul eDM-QMX6 Board";
  8880. + compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q";
  8881. +
  8882. + chosen {
  8883. + stdout-path = &uart2;
  8884. + };
  8885. +
  8886. + aliases {
  8887. + gpio7 = &stmpe_gpio1;
  8888. + gpio8 = &stmpe_gpio2;
  8889. + stmpe-i2c0 = &stmpe1;
  8890. + stmpe-i2c1 = &stmpe2;
  8891. + };
  8892. +
  8893. + memory {
  8894. + reg = <0x10000000 0x80000000>;
  8895. + };
  8896. +
  8897. + regulators {
  8898. + compatible = "simple-bus";
  8899. + #address-cells = <1>;
  8900. + #size-cells = <0>;
  8901. +
  8902. + reg_3p3v: regulator@0 {
  8903. + compatible = "regulator-fixed";
  8904. + reg = <0>;
  8905. + regulator-name = "3P3V";
  8906. + regulator-min-microvolt = <3300000>;
  8907. + regulator-max-microvolt = <3300000>;
  8908. + regulator-always-on;
  8909. + };
  8910. +
  8911. + reg_usb_otg_switch: regulator@1 {
  8912. + compatible = "regulator-fixed";
  8913. + reg = <1>;
  8914. + regulator-name = "usb_otg_switch";
  8915. + regulator-min-microvolt = <5000000>;
  8916. + regulator-max-microvolt = <5000000>;
  8917. + gpio = <&gpio7 12 0>;
  8918. + regulator-boot-on;
  8919. + regulator-always-on;
  8920. + };
  8921. +
  8922. + reg_usb_host1: regulator@2 {
  8923. + compatible = "regulator-fixed";
  8924. + reg = <2>;
  8925. + regulator-name = "usb_host1_en";
  8926. + regulator-min-microvolt = <3300000>;
  8927. + regulator-max-microvolt = <3300000>;
  8928. + gpio = <&gpio3 31 0>;
  8929. + enable-active-high;
  8930. + };
  8931. + };
  8932. +
  8933. + gpio-leds {
  8934. + compatible = "gpio-leds";
  8935. +
  8936. + led-blue {
  8937. + label = "blue";
  8938. + gpios = <&stmpe_gpio1 8 GPIO_ACTIVE_HIGH>;
  8939. + linux,default-trigger = "heartbeat";
  8940. + };
  8941. +
  8942. + led-green {
  8943. + label = "green";
  8944. + gpios = <&stmpe_gpio1 9 GPIO_ACTIVE_HIGH>;
  8945. + };
  8946. +
  8947. + led-pink {
  8948. + label = "pink";
  8949. + gpios = <&stmpe_gpio1 10 GPIO_ACTIVE_HIGH>;
  8950. + };
  8951. +
  8952. + led-red {
  8953. + label = "red";
  8954. + gpios = <&stmpe_gpio1 11 GPIO_ACTIVE_HIGH>;
  8955. + };
  8956. + };
  8957. +};
  8958. +
  8959. +&ecspi5 {
  8960. + pinctrl-names = "default";
  8961. + pinctrl-0 = <&pinctrl_ecspi5>;
  8962. + fsl,spi-num-chipselects = <1>;
  8963. + cs-gpios = <&gpio1 12 0>;
  8964. + status = "okay";
  8965. +
  8966. + flash: m25p80@0 {
  8967. + compatible = "m25p80";
  8968. + spi-max-frequency = <40000000>;
  8969. + reg = <0>;
  8970. + };
  8971. +};
  8972. +
  8973. +&fec {
  8974. + pinctrl-names = "default";
  8975. + pinctrl-0 = <&pinctrl_enet>;
  8976. + phy-mode = "rgmii";
  8977. + phy-reset-gpios = <&gpio3 23 0>;
  8978. + phy-supply = <&vgen2_1v2_eth>;
  8979. + status = "okay";
  8980. +};
  8981. +
  8982. +&i2c2 {
  8983. + clock-frequency = <100000>;
  8984. + pinctrl-names = "default";
  8985. + pinctrl-0 = <&pinctrl_i2c2
  8986. + &pinctrl_stmpe1
  8987. + &pinctrl_stmpe2
  8988. + &pinctrl_pfuze>;
  8989. + status = "okay";
  8990. +
  8991. + pmic: pfuze100@08 {
  8992. + compatible = "fsl,pfuze100";
  8993. + reg = <0x08>;
  8994. + interrupt-parent = <&gpio3>;
  8995. + interrupts = <20 8>;
  8996. +
  8997. + regulators {
  8998. + sw1a_reg: sw1ab {
  8999. + regulator-min-microvolt = <300000>;
  9000. + regulator-max-microvolt = <1875000>;
  9001. + regulator-boot-on;
  9002. + regulator-always-on;
  9003. + };
  9004. +
  9005. + sw1c_reg: sw1c {
  9006. + regulator-min-microvolt = <300000>;
  9007. + regulator-max-microvolt = <1875000>;
  9008. + regulator-boot-on;
  9009. + regulator-always-on;
  9010. + };
  9011. +
  9012. + sw2_reg: sw2 {
  9013. + regulator-min-microvolt = <800000>;
  9014. + regulator-max-microvolt = <3300000>;
  9015. + regulator-boot-on;
  9016. + regulator-always-on;
  9017. + };
  9018. +
  9019. + sw3a_reg: sw3a {
  9020. + regulator-min-microvolt = <400000>;
  9021. + regulator-max-microvolt = <1975000>;
  9022. + regulator-boot-on;
  9023. + regulator-always-on;
  9024. + };
  9025. +
  9026. + sw3b_reg: sw3b {
  9027. + regulator-min-microvolt = <400000>;
  9028. + regulator-max-microvolt = <1975000>;
  9029. + regulator-boot-on;
  9030. + regulator-always-on;
  9031. + };
  9032. +
  9033. + sw4_reg: sw4 {
  9034. + regulator-min-microvolt = <400000>;
  9035. + regulator-max-microvolt = <1975000>;
  9036. + regulator-always-on;
  9037. + };
  9038. +
  9039. + swbst_reg: swbst {
  9040. + regulator-min-microvolt = <5000000>;
  9041. + regulator-max-microvolt = <5150000>;
  9042. + regulator-always-on;
  9043. + };
  9044. +
  9045. + snvs_reg: vsnvs {
  9046. + regulator-min-microvolt = <1000000>;
  9047. + regulator-max-microvolt = <3000000>;
  9048. + regulator-boot-on;
  9049. + regulator-always-on;
  9050. + };
  9051. +
  9052. + vref_reg: vrefddr {
  9053. + regulator-boot-on;
  9054. + regulator-always-on;
  9055. + };
  9056. +
  9057. + vgen1_reg: vgen1 {
  9058. + regulator-min-microvolt = <800000>;
  9059. + regulator-max-microvolt = <1550000>;
  9060. + };
  9061. +
  9062. + vgen2_1v2_eth: vgen2 {
  9063. + regulator-min-microvolt = <800000>;
  9064. + regulator-max-microvolt = <1550000>;
  9065. + };
  9066. +
  9067. + vdd_high_in: vgen3 {
  9068. + regulator-min-microvolt = <1800000>;
  9069. + regulator-max-microvolt = <3300000>;
  9070. + regulator-boot-on;
  9071. + regulator-always-on;
  9072. + };
  9073. +
  9074. + vgen4_reg: vgen4 {
  9075. + regulator-min-microvolt = <1800000>;
  9076. + regulator-max-microvolt = <3300000>;
  9077. + regulator-always-on;
  9078. + };
  9079. +
  9080. + vgen5_reg: vgen5 {
  9081. + regulator-min-microvolt = <1800000>;
  9082. + regulator-max-microvolt = <3300000>;
  9083. + regulator-always-on;
  9084. + };
  9085. +
  9086. + vgen6_reg: vgen6 {
  9087. + regulator-min-microvolt = <1800000>;
  9088. + regulator-max-microvolt = <3300000>;
  9089. + regulator-always-on;
  9090. + };
  9091. + };
  9092. + };
  9093. +
  9094. + stmpe1: stmpe1601@40 {
  9095. + compatible = "st,stmpe1601";
  9096. + reg = <0x40>;
  9097. + interrupts = <30 0>;
  9098. + interrupt-parent = <&gpio3>;
  9099. + vcc-supply = <&sw2_reg>;
  9100. + vio-supply = <&sw2_reg>;
  9101. +
  9102. + stmpe_gpio1: stmpe_gpio {
  9103. + #gpio-cells = <2>;
  9104. + compatible = "st,stmpe-gpio";
  9105. + };
  9106. + };
  9107. +
  9108. + stmpe2: stmpe1601@44 {
  9109. + compatible = "st,stmpe1601";
  9110. + reg = <0x44>;
  9111. + interrupts = <2 0>;
  9112. + interrupt-parent = <&gpio5>;
  9113. + vcc-supply = <&sw2_reg>;
  9114. + vio-supply = <&sw2_reg>;
  9115. +
  9116. + stmpe_gpio2: stmpe_gpio {
  9117. + #gpio-cells = <2>;
  9118. + compatible = "st,stmpe-gpio";
  9119. + };
  9120. + };
  9121. +
  9122. + temp1: ad7414@4c {
  9123. + compatible = "ad,ad7414";
  9124. + reg = <0x4c>;
  9125. + };
  9126. +
  9127. + temp2: ad7414@4d {
  9128. + compatible = "ad,ad7414";
  9129. + reg = <0x4d>;
  9130. + };
  9131. +
  9132. + rtc: m41t62@68 {
  9133. + compatible = "stm,m41t62";
  9134. + reg = <0x68>;
  9135. + };
  9136. +};
  9137. +
  9138. +&iomuxc {
  9139. + pinctrl-names = "default";
  9140. + pinctrl-0 = <&pinctrl_hog>;
  9141. +
  9142. + imx6q-dmo-edmqmx6 {
  9143. + pinctrl_hog: hoggrp {
  9144. + fsl,pins = <
  9145. + MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x80000000
  9146. + MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x80000000
  9147. + >;
  9148. + };
  9149. +
  9150. + pinctrl_ecspi5: ecspi5rp-1 {
  9151. + fsl,pins = <
  9152. + MX6QDL_PAD_SD1_DAT0__ECSPI5_MISO 0x80000000
  9153. + MX6QDL_PAD_SD1_CMD__ECSPI5_MOSI 0x80000000
  9154. + MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x80000000
  9155. + MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x80000000
  9156. + >;
  9157. + };
  9158. +
  9159. + pinctrl_enet: enetgrp {
  9160. + fsl,pins = <
  9161. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  9162. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  9163. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  9164. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  9165. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  9166. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  9167. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  9168. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  9169. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  9170. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  9171. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  9172. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  9173. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  9174. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  9175. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  9176. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  9177. + >;
  9178. + };
  9179. +
  9180. + pinctrl_i2c2: i2c2grp {
  9181. + fsl,pins = <
  9182. + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
  9183. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  9184. + >;
  9185. + };
  9186. +
  9187. + pinctrl_pfuze: pfuze100grp1 {
  9188. + fsl,pins = <
  9189. + MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x80000000
  9190. + >;
  9191. + };
  9192. +
  9193. + pinctrl_stmpe1: stmpe1grp {
  9194. + fsl,pins = <MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x80000000>;
  9195. + };
  9196. +
  9197. + pinctrl_stmpe2: stmpe2grp {
  9198. + fsl,pins = <MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x80000000>;
  9199. + };
  9200. +
  9201. + pinctrl_uart1: uart1grp {
  9202. + fsl,pins = <
  9203. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  9204. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  9205. + >;
  9206. + };
  9207. +
  9208. + pinctrl_uart2: uart2grp {
  9209. + fsl,pins = <
  9210. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  9211. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  9212. + >;
  9213. + };
  9214. +
  9215. + pinctrl_usbotg: usbotggrp {
  9216. + fsl,pins = <
  9217. + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
  9218. + >;
  9219. + };
  9220. +
  9221. + pinctrl_usdhc3: usdhc3grp {
  9222. + fsl,pins = <
  9223. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  9224. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  9225. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  9226. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  9227. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  9228. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  9229. + >;
  9230. + };
  9231. +
  9232. + pinctrl_usdhc4: usdhc4grp {
  9233. + fsl,pins = <
  9234. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  9235. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  9236. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  9237. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  9238. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  9239. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  9240. + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
  9241. + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
  9242. + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
  9243. + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
  9244. + >;
  9245. + };
  9246. + };
  9247. +};
  9248. +
  9249. +&sata {
  9250. + status = "okay";
  9251. +};
  9252. +
  9253. +&uart1 {
  9254. + pinctrl-names = "default";
  9255. + pinctrl-0 = <&pinctrl_uart1>;
  9256. + status = "okay";
  9257. +};
  9258. +
  9259. +&uart2 {
  9260. + pinctrl-names = "default";
  9261. + pinctrl-0 = <&pinctrl_uart2>;
  9262. + status = "okay";
  9263. +};
  9264. +
  9265. +&usbh1 {
  9266. + vbus-supply = <&reg_usb_host1>;
  9267. + disable-over-current;
  9268. + dr_mode = "host";
  9269. + status = "okay";
  9270. +};
  9271. +
  9272. +&usbotg {
  9273. + pinctrl-names = "default";
  9274. + pinctrl-0 = <&pinctrl_usbotg>;
  9275. + disable-over-current;
  9276. + status = "okay";
  9277. +};
  9278. +
  9279. +&usdhc3 {
  9280. + pinctrl-names = "default";
  9281. + pinctrl-0 = <&pinctrl_usdhc3>;
  9282. + vmmc-supply = <&reg_3p3v>;
  9283. + status = "okay";
  9284. +};
  9285. +
  9286. +&usdhc4 {
  9287. + pinctrl-names = "default";
  9288. + pinctrl-0 = <&pinctrl_usdhc4>;
  9289. + vmmc-supply = <&reg_3p3v>;
  9290. + non-removable;
  9291. + bus-width = <8>;
  9292. + status = "okay";
  9293. +};
  9294. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6q.dtsi
  9295. --- linux-3.14.17/arch/arm/boot/dts/imx6q.dtsi 2014-08-14 03:38:34.000000000 +0200
  9296. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q.dtsi 2014-09-11 18:05:52.642000568 +0200
  9297. @@ -8,10 +8,16 @@
  9298. *
  9299. */
  9300. +#include <dt-bindings/interrupt-controller/irq.h>
  9301. #include "imx6q-pinfunc.h"
  9302. #include "imx6qdl.dtsi"
  9303. / {
  9304. + aliases {
  9305. + ipu1 = &ipu2;
  9306. + spi4 = &ecspi5;
  9307. + };
  9308. +
  9309. cpus {
  9310. #address-cells = <1>;
  9311. #size-cells = <0>;
  9312. @@ -25,8 +31,17 @@
  9313. /* kHz uV */
  9314. 1200000 1275000
  9315. 996000 1250000
  9316. + 852000 1250000
  9317. 792000 1150000
  9318. - 396000 950000
  9319. + 396000 975000
  9320. + >;
  9321. + fsl,soc-operating-points = <
  9322. + /* ARM kHz SOC-PU uV */
  9323. + 1200000 1275000
  9324. + 996000 1250000
  9325. + 852000 1250000
  9326. + 792000 1175000
  9327. + 396000 1175000
  9328. >;
  9329. clock-latency = <61036>; /* two CLK32 periods */
  9330. clocks = <&clks 104>, <&clks 6>, <&clks 16>,
  9331. @@ -61,12 +76,77 @@
  9332. };
  9333. soc {
  9334. +
  9335. + busfreq { /* BUSFREQ */
  9336. + compatible = "fsl,imx6_busfreq";
  9337. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  9338. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>;
  9339. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  9340. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc";
  9341. + interrupts = <0 107 0x04>, <0 112 0x4>, <0 113 0x4>, <0 114 0x4>;
  9342. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
  9343. + fsl,max_ddr_freq = <528000000>;
  9344. + };
  9345. +
  9346. + gpu@00130000 {
  9347. + compatible = "fsl,imx6q-gpu";
  9348. + reg = <0x00130000 0x4000>, <0x00134000 0x4000>,
  9349. + <0x02204000 0x4000>, <0x0 0x0>;
  9350. + reg-names = "iobase_3d", "iobase_2d",
  9351. + "iobase_vg", "phys_baseaddr";
  9352. + interrupts = <0 9 0x04>, <0 10 0x04>,<0 11 0x04>;
  9353. + interrupt-names = "irq_3d", "irq_2d", "irq_vg";
  9354. + clocks = <&clks 26>, <&clks 143>,
  9355. + <&clks 27>, <&clks 121>,
  9356. + <&clks 122>, <&clks 74>;
  9357. + clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
  9358. + "gpu3d_axi_clk", "gpu2d_clk",
  9359. + "gpu3d_clk", "gpu3d_shader_clk";
  9360. + resets = <&src 0>, <&src 3>, <&src 3>;
  9361. + reset-names = "gpu3d", "gpu2d", "gpuvg";
  9362. + pu-supply = <&reg_pu>;
  9363. + };
  9364. +
  9365. ocram: sram@00900000 {
  9366. compatible = "mmio-sram";
  9367. reg = <0x00900000 0x40000>;
  9368. clocks = <&clks 142>;
  9369. };
  9370. + hdmi_core: hdmi_core@00120000 {
  9371. + compatible = "fsl,imx6q-hdmi-core";
  9372. + reg = <0x00120000 0x9000>;
  9373. + clocks = <&clks 124>, <&clks 123>;
  9374. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9375. + status = "disabled";
  9376. + };
  9377. +
  9378. + hdmi_video: hdmi_video@020e0000 {
  9379. + compatible = "fsl,imx6q-hdmi-video";
  9380. + reg = <0x020e0000 0x1000>;
  9381. + reg-names = "hdmi_gpr";
  9382. + interrupts = <0 115 0x04>;
  9383. + clocks = <&clks 124>, <&clks 123>;
  9384. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9385. + status = "disabled";
  9386. + };
  9387. +
  9388. + hdmi_audio: hdmi_audio@00120000 {
  9389. + compatible = "fsl,imx6q-hdmi-audio";
  9390. + clocks = <&clks 124>, <&clks 123>;
  9391. + clock-names = "hdmi_isfr", "hdmi_iahb";
  9392. + dmas = <&sdma 2 23 0>;
  9393. + dma-names = "tx";
  9394. + status = "disabled";
  9395. + };
  9396. +
  9397. + hdmi_cec: hdmi_cec@00120000 {
  9398. + compatible = "fsl,imx6q-hdmi-cec";
  9399. + interrupts = <0 115 0x04>;
  9400. + status = "disabled";
  9401. + };
  9402. +
  9403. +
  9404. aips-bus@02000000 { /* AIPS1 */
  9405. spba-bus@02000000 {
  9406. ecspi5: ecspi@02018000 {
  9407. @@ -74,13 +154,17 @@
  9408. #size-cells = <0>;
  9409. compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
  9410. reg = <0x02018000 0x4000>;
  9411. - interrupts = <0 35 0x04>;
  9412. + interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
  9413. clocks = <&clks 116>, <&clks 116>;
  9414. clock-names = "ipg", "per";
  9415. status = "disabled";
  9416. };
  9417. };
  9418. + vpu@02040000 {
  9419. + status = "okay";
  9420. + };
  9421. +
  9422. iomuxc: iomuxc@020e0000 {
  9423. compatible = "fsl,imx6q-iomuxc";
  9424. @@ -122,40 +206,40 @@
  9425. };
  9426. };
  9427. + aips-bus@02100000 { /* AIPS2 */
  9428. + mipi_dsi: mipi@021e0000 {
  9429. + compatible = "fsl,imx6q-mipi-dsi";
  9430. + reg = <0x021e0000 0x4000>;
  9431. + interrupts = <0 102 0x04>;
  9432. + gpr = <&gpr>;
  9433. + clocks = <&clks 138>, <&clks 209>;
  9434. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  9435. + status = "disabled";
  9436. + };
  9437. + };
  9438. +
  9439. sata: sata@02200000 {
  9440. compatible = "fsl,imx6q-ahci";
  9441. reg = <0x02200000 0x4000>;
  9442. - interrupts = <0 39 0x04>;
  9443. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  9444. clocks = <&clks 154>, <&clks 187>, <&clks 105>;
  9445. clock-names = "sata", "sata_ref", "ahb";
  9446. status = "disabled";
  9447. };
  9448. ipu2: ipu@02800000 {
  9449. - #crtc-cells = <1>;
  9450. compatible = "fsl,imx6q-ipu";
  9451. reg = <0x02800000 0x400000>;
  9452. - interrupts = <0 8 0x4 0 7 0x4>;
  9453. - clocks = <&clks 133>, <&clks 134>, <&clks 137>;
  9454. - clock-names = "bus", "di0", "di1";
  9455. + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>,
  9456. + <0 7 IRQ_TYPE_LEVEL_HIGH>;
  9457. + clocks = <&clks 133>, <&clks 134>, <&clks 137>,
  9458. + <&clks 41>, <&clks 42>,
  9459. + <&clks 135>, <&clks 136>;
  9460. + clock-names = "bus", "di0", "di1",
  9461. + "di0_sel", "di1_sel",
  9462. + "ldb_di0", "ldb_di1";
  9463. resets = <&src 4>;
  9464. + bypass_reset = <0>;
  9465. };
  9466. };
  9467. };
  9468. -
  9469. -&ldb {
  9470. - clocks = <&clks 33>, <&clks 34>,
  9471. - <&clks 39>, <&clks 40>, <&clks 41>, <&clks 42>,
  9472. - <&clks 135>, <&clks 136>;
  9473. - clock-names = "di0_pll", "di1_pll",
  9474. - "di0_sel", "di1_sel", "di2_sel", "di3_sel",
  9475. - "di0", "di1";
  9476. -
  9477. - lvds-channel@0 {
  9478. - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
  9479. - };
  9480. -
  9481. - lvds-channel@1 {
  9482. - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
  9483. - };
  9484. -};
  9485. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-gk802.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gk802.dts
  9486. --- linux-3.14.17/arch/arm/boot/dts/imx6q-gk802.dts 1970-01-01 01:00:00.000000000 +0100
  9487. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gk802.dts 2014-09-11 18:05:52.634000535 +0200
  9488. @@ -0,0 +1,229 @@
  9489. +/*
  9490. + * Copyright (C) 2013 Philipp Zabel
  9491. + *
  9492. + * This file is licensed under the terms of the GNU General Public License
  9493. + * version 2. This program is licensed "as is" without any warranty of any
  9494. + * kind, whether express or implied.
  9495. + */
  9496. +
  9497. +/dts-v1/;
  9498. +#include "imx6q.dtsi"
  9499. +
  9500. +/ {
  9501. + model = "Zealz GK802";
  9502. + compatible = "zealz,imx6q-gk802", "fsl,imx6q";
  9503. +
  9504. + aliases {
  9505. + mxcfb0 = &mxcfb1;
  9506. + };
  9507. +
  9508. + chosen {
  9509. + stdout-path = &uart4;
  9510. + };
  9511. +
  9512. + memory {
  9513. + reg = <0x10000000 0x40000000>;
  9514. + };
  9515. +
  9516. + regulators {
  9517. + compatible = "simple-bus";
  9518. + #address-cells = <1>;
  9519. + #size-cells = <0>;
  9520. +
  9521. + reg_3p3v: regulator@0 {
  9522. + compatible = "regulator-fixed";
  9523. + reg = <0>;
  9524. + regulator-name = "3P3V";
  9525. + regulator-min-microvolt = <3300000>;
  9526. + regulator-max-microvolt = <3300000>;
  9527. + regulator-always-on;
  9528. + };
  9529. +
  9530. + reg_usb_h1_vbus: usb_h1_vbus {
  9531. + compatible = "regulator-fixed";
  9532. + regulator-name = "usb_h1_vbus";
  9533. + regulator-min-microvolt = <5000000>;
  9534. + regulator-max-microvolt = <5000000>;
  9535. + gpio = <&gpio2 0 0>;
  9536. + };
  9537. + };
  9538. +
  9539. + gpio-keys {
  9540. + compatible = "gpio-keys";
  9541. +
  9542. + recovery-button {
  9543. + label = "recovery";
  9544. + gpios = <&gpio3 16 1>;
  9545. + linux,code = <0x198>; /* KEY_RESTART */
  9546. + gpio-key,wakeup;
  9547. + };
  9548. +
  9549. + };
  9550. +
  9551. + sound-hdmi {
  9552. + compatible = "fsl,imx6q-audio-hdmi",
  9553. + "fsl,imx-audio-hdmi";
  9554. + model = "imx-audio-hdmi";
  9555. + hdmi-controller = <&hdmi_audio>;
  9556. + };
  9557. +
  9558. + mxcfb1: fb@0 {
  9559. + compatible = "fsl,mxc_sdc_fb";
  9560. + disp_dev = "hdmi";
  9561. + interface_pix_fmt = "RGB24";
  9562. + mode_str ="1920x1080M@60";
  9563. + default_bpp = <32>;
  9564. + int_clk = <0>;
  9565. + late_init = <0>;
  9566. + status = "okay";
  9567. + };
  9568. +};
  9569. +
  9570. +&hdmi_core {
  9571. + ipu_id = <0>;
  9572. + disp_id = <0>;
  9573. + status = "okay";
  9574. +};
  9575. +
  9576. +&hdmi_video {
  9577. + fsl,phy_reg_vlev = <0x0294>;
  9578. + fsl,phy_reg_cksymtx = <0x800d>;
  9579. + status = "okay";
  9580. +};
  9581. +
  9582. +&hdmi_audio {
  9583. + status = "okay";
  9584. +};
  9585. +
  9586. +
  9587. +/* Internal I2C */
  9588. +&i2c2 {
  9589. + pinctrl-names = "default";
  9590. + pinctrl-0 = <&pinctrl_i2c2>;
  9591. + clock-frequency = <100000>;
  9592. + status = "okay";
  9593. +
  9594. + /* SDMC DM2016 1024 bit EEPROM + 128 bit OTP */
  9595. + eeprom: dm2016@51 {
  9596. + compatible = "sdmc,dm2016";
  9597. + reg = <0x51>;
  9598. + };
  9599. +};
  9600. +
  9601. +/* External I2C via HDMI */
  9602. +&i2c3 {
  9603. + pinctrl-names = "default";
  9604. + pinctrl-0 = <&pinctrl_i2c3>;
  9605. + clock-frequency = <100000>;
  9606. + status = "okay";
  9607. +
  9608. + ddc: imx6_hdmi_i2c@50 {
  9609. + compatible = "fsl,imx6-hdmi-i2c";
  9610. + reg = <0x50>;
  9611. + };
  9612. +};
  9613. +
  9614. +&iomuxc {
  9615. + pinctrl-names = "default";
  9616. + pinctrl-0 = <&pinctrl_hog>;
  9617. +
  9618. + imx6q-gk802 {
  9619. + pinctrl_hog: hoggrp {
  9620. + fsl,pins = <
  9621. + /* Recovery button, active-low */
  9622. + MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x100b1
  9623. + /* RTL8192CU enable GPIO, active-low */
  9624. + MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
  9625. + >;
  9626. + };
  9627. +
  9628. + pinctrl_i2c2: i2c2grp {
  9629. + fsl,pins = <
  9630. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  9631. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  9632. + >;
  9633. + };
  9634. +
  9635. + pinctrl_i2c3: i2c3grp {
  9636. + fsl,pins = <
  9637. + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
  9638. + MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1
  9639. + >;
  9640. + };
  9641. +
  9642. + pinctrl_uart4: uart4grp {
  9643. + fsl,pins = <
  9644. + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
  9645. + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
  9646. + >;
  9647. + };
  9648. +
  9649. + pinctrl_usdhc3: usdhc3grp {
  9650. + fsl,pins = <
  9651. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  9652. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  9653. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  9654. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  9655. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  9656. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  9657. + >;
  9658. + };
  9659. +
  9660. + pinctrl_usdhc4: usdhc4grp {
  9661. + fsl,pins = <
  9662. + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
  9663. + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
  9664. + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
  9665. + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
  9666. + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
  9667. + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
  9668. + >;
  9669. + };
  9670. + };
  9671. +};
  9672. +
  9673. +&uart2 {
  9674. + status = "okay";
  9675. +};
  9676. +
  9677. +&uart4 {
  9678. + pinctrl-names = "default";
  9679. + pinctrl-0 = <&pinctrl_uart4>;
  9680. + status = "okay";
  9681. +};
  9682. +
  9683. +/* External USB-A port (USBOTG) */
  9684. +&usbotg {
  9685. + phy_type = "utmi";
  9686. + dr_mode = "host";
  9687. + disable-over-current;
  9688. + status = "okay";
  9689. +};
  9690. +
  9691. +/* Internal USB port (USBH1), connected to RTL8192CU */
  9692. +&usbh1 {
  9693. + phy_type = "utmi";
  9694. + dr_mode = "host";
  9695. + vbus-supply = <&reg_usb_h1_vbus>;
  9696. + disable-over-current;
  9697. + status = "okay";
  9698. +};
  9699. +
  9700. +/* External microSD */
  9701. +&usdhc3 {
  9702. + pinctrl-names = "default";
  9703. + pinctrl-0 = <&pinctrl_usdhc3>;
  9704. + bus-width = <4>;
  9705. + cd-gpios = <&gpio6 11 0>;
  9706. + vmmc-supply = <&reg_3p3v>;
  9707. + status = "okay";
  9708. +};
  9709. +
  9710. +/* Internal microSD */
  9711. +&usdhc4 {
  9712. + pinctrl-names = "default";
  9713. + pinctrl-0 = <&pinctrl_usdhc4>;
  9714. + bus-width = <4>;
  9715. + vmmc-supply = <&reg_3p3v>;
  9716. + status = "okay";
  9717. +};
  9718. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-gw51xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw51xx.dts
  9719. --- linux-3.14.17/arch/arm/boot/dts/imx6q-gw51xx.dts 1970-01-01 01:00:00.000000000 +0100
  9720. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw51xx.dts 2014-09-11 18:05:52.634000535 +0200
  9721. @@ -0,0 +1,19 @@
  9722. +/*
  9723. + * Copyright 2013 Gateworks Corporation
  9724. + *
  9725. + * The code contained herein is licensed under the GNU General Public
  9726. + * License. You may obtain a copy of the GNU General Public License
  9727. + * Version 2 or later at the following locations:
  9728. + *
  9729. + * http://www.opensource.org/licenses/gpl-license.html
  9730. + * http://www.gnu.org/copyleft/gpl.html
  9731. + */
  9732. +
  9733. +/dts-v1/;
  9734. +#include "imx6q.dtsi"
  9735. +#include "imx6qdl-gw54xx.dtsi"
  9736. +
  9737. +/ {
  9738. + model = "Gateworks Ventana i.MX6 Quad GW51XX";
  9739. + compatible = "gw,imx6q-gw51xx", "gw,ventana", "fsl,imx6q";
  9740. +};
  9741. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-gw52xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw52xx.dts
  9742. --- linux-3.14.17/arch/arm/boot/dts/imx6q-gw52xx.dts 1970-01-01 01:00:00.000000000 +0100
  9743. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw52xx.dts 2014-09-11 18:05:52.634000535 +0200
  9744. @@ -0,0 +1,23 @@
  9745. +/*
  9746. + * Copyright 2013 Gateworks Corporation
  9747. + *
  9748. + * The code contained herein is licensed under the GNU General Public
  9749. + * License. You may obtain a copy of the GNU General Public License
  9750. + * Version 2 or later at the following locations:
  9751. + *
  9752. + * http://www.opensource.org/licenses/gpl-license.html
  9753. + * http://www.gnu.org/copyleft/gpl.html
  9754. + */
  9755. +
  9756. +/dts-v1/;
  9757. +#include "imx6q.dtsi"
  9758. +#include "imx6qdl-gw52xx.dtsi"
  9759. +
  9760. +/ {
  9761. + model = "Gateworks Ventana i.MX6 Quad GW52XX";
  9762. + compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q";
  9763. +};
  9764. +
  9765. +&sata {
  9766. + status = "okay";
  9767. +};
  9768. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-gw53xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw53xx.dts
  9769. --- linux-3.14.17/arch/arm/boot/dts/imx6q-gw53xx.dts 1970-01-01 01:00:00.000000000 +0100
  9770. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw53xx.dts 2014-09-11 18:05:52.642000568 +0200
  9771. @@ -0,0 +1,23 @@
  9772. +/*
  9773. + * Copyright 2013 Gateworks Corporation
  9774. + *
  9775. + * The code contained herein is licensed under the GNU General Public
  9776. + * License. You may obtain a copy of the GNU General Public License
  9777. + * Version 2 or later at the following locations:
  9778. + *
  9779. + * http://www.opensource.org/licenses/gpl-license.html
  9780. + * http://www.gnu.org/copyleft/gpl.html
  9781. + */
  9782. +
  9783. +/dts-v1/;
  9784. +#include "imx6q.dtsi"
  9785. +#include "imx6qdl-gw53xx.dtsi"
  9786. +
  9787. +/ {
  9788. + model = "Gateworks Ventana i.MX6 Quad GW53XX";
  9789. + compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q";
  9790. +};
  9791. +
  9792. +&sata {
  9793. + status = "okay";
  9794. +};
  9795. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-gw5400-a.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw5400-a.dts
  9796. --- linux-3.14.17/arch/arm/boot/dts/imx6q-gw5400-a.dts 1970-01-01 01:00:00.000000000 +0100
  9797. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw5400-a.dts 2014-09-11 18:05:52.642000568 +0200
  9798. @@ -0,0 +1,543 @@
  9799. +/*
  9800. + * Copyright 2013 Gateworks Corporation
  9801. + *
  9802. + * The code contained herein is licensed under the GNU General Public
  9803. + * License. You may obtain a copy of the GNU General Public License
  9804. + * Version 2 or later at the following locations:
  9805. + *
  9806. + * http://www.opensource.org/licenses/gpl-license.html
  9807. + * http://www.gnu.org/copyleft/gpl.html
  9808. + */
  9809. +
  9810. +/dts-v1/;
  9811. +#include "imx6q.dtsi"
  9812. +
  9813. +/ {
  9814. + model = "Gateworks Ventana GW5400-A";
  9815. + compatible = "gw,imx6q-gw5400-a", "gw,ventana", "fsl,imx6q";
  9816. +
  9817. + /* these are used by bootloader for disabling nodes */
  9818. + aliases {
  9819. + ethernet0 = &fec;
  9820. + ethernet1 = &eth1;
  9821. + i2c0 = &i2c1;
  9822. + i2c1 = &i2c2;
  9823. + i2c2 = &i2c3;
  9824. + led0 = &led0;
  9825. + led1 = &led1;
  9826. + led2 = &led2;
  9827. + sky2 = &eth1;
  9828. + ssi0 = &ssi1;
  9829. + spi0 = &ecspi1;
  9830. + usb0 = &usbh1;
  9831. + usb1 = &usbotg;
  9832. + usdhc2 = &usdhc3;
  9833. + };
  9834. +
  9835. + chosen {
  9836. + bootargs = "console=ttymxc1,115200";
  9837. + };
  9838. +
  9839. + leds {
  9840. + compatible = "gpio-leds";
  9841. +
  9842. + led0: user1 {
  9843. + label = "user1";
  9844. + gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG */
  9845. + default-state = "on";
  9846. + linux,default-trigger = "heartbeat";
  9847. + };
  9848. +
  9849. + led1: user2 {
  9850. + label = "user2";
  9851. + gpios = <&gpio4 10 0>; /* 106 -> MX6_PANLEDR */
  9852. + default-state = "off";
  9853. + };
  9854. +
  9855. + led2: user3 {
  9856. + label = "user3";
  9857. + gpios = <&gpio4 15 1>; /* 111 -> MX6_LOCLED# */
  9858. + default-state = "off";
  9859. + };
  9860. + };
  9861. +
  9862. + memory {
  9863. + reg = <0x10000000 0x40000000>;
  9864. + };
  9865. +
  9866. + pps {
  9867. + compatible = "pps-gpio";
  9868. + gpios = <&gpio1 5 0>;
  9869. + status = "okay";
  9870. + };
  9871. +
  9872. + regulators {
  9873. + compatible = "simple-bus";
  9874. + #address-cells = <1>;
  9875. + #size-cells = <0>;
  9876. +
  9877. + reg_1p0v: regulator@0 {
  9878. + compatible = "regulator-fixed";
  9879. + reg = <0>;
  9880. + regulator-name = "1P0V";
  9881. + regulator-min-microvolt = <1000000>;
  9882. + regulator-max-microvolt = <1000000>;
  9883. + regulator-always-on;
  9884. + };
  9885. +
  9886. + reg_3p3v: regulator@1 {
  9887. + compatible = "regulator-fixed";
  9888. + reg = <1>;
  9889. + regulator-name = "3P3V";
  9890. + regulator-min-microvolt = <3300000>;
  9891. + regulator-max-microvolt = <3300000>;
  9892. + regulator-always-on;
  9893. + };
  9894. +
  9895. + reg_usb_h1_vbus: regulator@2 {
  9896. + compatible = "regulator-fixed";
  9897. + reg = <2>;
  9898. + regulator-name = "usb_h1_vbus";
  9899. + regulator-min-microvolt = <5000000>;
  9900. + regulator-max-microvolt = <5000000>;
  9901. + regulator-always-on;
  9902. + };
  9903. +
  9904. + reg_usb_otg_vbus: regulator@3 {
  9905. + compatible = "regulator-fixed";
  9906. + reg = <3>;
  9907. + regulator-name = "usb_otg_vbus";
  9908. + regulator-min-microvolt = <5000000>;
  9909. + regulator-max-microvolt = <5000000>;
  9910. + gpio = <&gpio3 22 0>;
  9911. + enable-active-high;
  9912. + };
  9913. + };
  9914. +
  9915. + sound {
  9916. + compatible = "fsl,imx6q-sabrelite-sgtl5000",
  9917. + "fsl,imx-audio-sgtl5000";
  9918. + model = "imx6q-sabrelite-sgtl5000";
  9919. + ssi-controller = <&ssi1>;
  9920. + audio-codec = <&codec>;
  9921. + audio-routing =
  9922. + "MIC_IN", "Mic Jack",
  9923. + "Mic Jack", "Mic Bias",
  9924. + "Headphone Jack", "HP_OUT";
  9925. + mux-int-port = <1>;
  9926. + mux-ext-port = <4>;
  9927. + };
  9928. +};
  9929. +
  9930. +&audmux {
  9931. + pinctrl-names = "default";
  9932. + pinctrl-0 = <&pinctrl_audmux>;
  9933. + status = "okay";
  9934. +};
  9935. +
  9936. +&ecspi1 {
  9937. + fsl,spi-num-chipselects = <1>;
  9938. + cs-gpios = <&gpio3 19 0>;
  9939. + pinctrl-names = "default";
  9940. + pinctrl-0 = <&pinctrl_ecspi1>;
  9941. + status = "okay";
  9942. +
  9943. + flash: m25p80@0 {
  9944. + compatible = "sst,w25q256";
  9945. + spi-max-frequency = <30000000>;
  9946. + reg = <0>;
  9947. + };
  9948. +};
  9949. +
  9950. +&fec {
  9951. + pinctrl-names = "default";
  9952. + pinctrl-0 = <&pinctrl_enet>;
  9953. + phy-mode = "rgmii";
  9954. + phy-reset-gpios = <&gpio1 30 0>;
  9955. + status = "okay";
  9956. +};
  9957. +
  9958. +&i2c1 {
  9959. + clock-frequency = <100000>;
  9960. + pinctrl-names = "default";
  9961. + pinctrl-0 = <&pinctrl_i2c1>;
  9962. + status = "okay";
  9963. +
  9964. + eeprom1: eeprom@50 {
  9965. + compatible = "atmel,24c02";
  9966. + reg = <0x50>;
  9967. + pagesize = <16>;
  9968. + };
  9969. +
  9970. + eeprom2: eeprom@51 {
  9971. + compatible = "atmel,24c02";
  9972. + reg = <0x51>;
  9973. + pagesize = <16>;
  9974. + };
  9975. +
  9976. + eeprom3: eeprom@52 {
  9977. + compatible = "atmel,24c02";
  9978. + reg = <0x52>;
  9979. + pagesize = <16>;
  9980. + };
  9981. +
  9982. + eeprom4: eeprom@53 {
  9983. + compatible = "atmel,24c02";
  9984. + reg = <0x53>;
  9985. + pagesize = <16>;
  9986. + };
  9987. +
  9988. + gpio: pca9555@23 {
  9989. + compatible = "nxp,pca9555";
  9990. + reg = <0x23>;
  9991. + gpio-controller;
  9992. + #gpio-cells = <2>;
  9993. + };
  9994. +
  9995. + hwmon: gsc@29 {
  9996. + compatible = "gw,gsp";
  9997. + reg = <0x29>;
  9998. + };
  9999. +
  10000. + rtc: ds1672@68 {
  10001. + compatible = "dallas,ds1672";
  10002. + reg = <0x68>;
  10003. + };
  10004. +};
  10005. +
  10006. +&i2c2 {
  10007. + clock-frequency = <100000>;
  10008. + pinctrl-names = "default";
  10009. + pinctrl-0 = <&pinctrl_i2c2>;
  10010. + status = "okay";
  10011. +
  10012. + pmic: pfuze100@08 {
  10013. + compatible = "fsl,pfuze100";
  10014. + reg = <0x08>;
  10015. +
  10016. + regulators {
  10017. + sw1a_reg: sw1ab {
  10018. + regulator-min-microvolt = <300000>;
  10019. + regulator-max-microvolt = <1875000>;
  10020. + regulator-boot-on;
  10021. + regulator-always-on;
  10022. + regulator-ramp-delay = <6250>;
  10023. + };
  10024. +
  10025. + sw1c_reg: sw1c {
  10026. + regulator-min-microvolt = <300000>;
  10027. + regulator-max-microvolt = <1875000>;
  10028. + regulator-boot-on;
  10029. + regulator-always-on;
  10030. + regulator-ramp-delay = <6250>;
  10031. + };
  10032. +
  10033. + sw2_reg: sw2 {
  10034. + regulator-min-microvolt = <800000>;
  10035. + regulator-max-microvolt = <3950000>;
  10036. + regulator-boot-on;
  10037. + regulator-always-on;
  10038. + };
  10039. +
  10040. + sw3a_reg: sw3a {
  10041. + regulator-min-microvolt = <400000>;
  10042. + regulator-max-microvolt = <1975000>;
  10043. + regulator-boot-on;
  10044. + regulator-always-on;
  10045. + };
  10046. +
  10047. + sw3b_reg: sw3b {
  10048. + regulator-min-microvolt = <400000>;
  10049. + regulator-max-microvolt = <1975000>;
  10050. + regulator-boot-on;
  10051. + regulator-always-on;
  10052. + };
  10053. +
  10054. + sw4_reg: sw4 {
  10055. + regulator-min-microvolt = <800000>;
  10056. + regulator-max-microvolt = <3300000>;
  10057. + };
  10058. +
  10059. + swbst_reg: swbst {
  10060. + regulator-min-microvolt = <5000000>;
  10061. + regulator-max-microvolt = <5150000>;
  10062. + };
  10063. +
  10064. + snvs_reg: vsnvs {
  10065. + regulator-min-microvolt = <1000000>;
  10066. + regulator-max-microvolt = <3000000>;
  10067. + regulator-boot-on;
  10068. + regulator-always-on;
  10069. + };
  10070. +
  10071. + vref_reg: vrefddr {
  10072. + regulator-boot-on;
  10073. + regulator-always-on;
  10074. + };
  10075. +
  10076. + vgen1_reg: vgen1 {
  10077. + regulator-min-microvolt = <800000>;
  10078. + regulator-max-microvolt = <1550000>;
  10079. + };
  10080. +
  10081. + vgen2_reg: vgen2 {
  10082. + regulator-min-microvolt = <800000>;
  10083. + regulator-max-microvolt = <1550000>;
  10084. + };
  10085. +
  10086. + vgen3_reg: vgen3 {
  10087. + regulator-min-microvolt = <1800000>;
  10088. + regulator-max-microvolt = <3300000>;
  10089. + };
  10090. +
  10091. + vgen4_reg: vgen4 {
  10092. + regulator-min-microvolt = <1800000>;
  10093. + regulator-max-microvolt = <3300000>;
  10094. + regulator-always-on;
  10095. + };
  10096. +
  10097. + vgen5_reg: vgen5 {
  10098. + regulator-min-microvolt = <1800000>;
  10099. + regulator-max-microvolt = <3300000>;
  10100. + regulator-always-on;
  10101. + };
  10102. +
  10103. + vgen6_reg: vgen6 {
  10104. + regulator-min-microvolt = <1800000>;
  10105. + regulator-max-microvolt = <3300000>;
  10106. + regulator-always-on;
  10107. + };
  10108. + };
  10109. + };
  10110. +
  10111. + pciswitch: pex8609@3f {
  10112. + compatible = "plx,pex8609";
  10113. + reg = <0x3f>;
  10114. + };
  10115. +
  10116. + pciclkgen: si52147@6b {
  10117. + compatible = "sil,si52147";
  10118. + reg = <0x6b>;
  10119. + };
  10120. +};
  10121. +
  10122. +&i2c3 {
  10123. + clock-frequency = <100000>;
  10124. + pinctrl-names = "default";
  10125. + pinctrl-0 = <&pinctrl_i2c3>;
  10126. + status = "okay";
  10127. +
  10128. + accelerometer: mma8450@1c {
  10129. + compatible = "fsl,mma8450";
  10130. + reg = <0x1c>;
  10131. + };
  10132. +
  10133. + codec: sgtl5000@0a {
  10134. + compatible = "fsl,sgtl5000";
  10135. + reg = <0x0a>;
  10136. + clocks = <&clks 201>;
  10137. + VDDA-supply = <&sw4_reg>;
  10138. + VDDIO-supply = <&reg_3p3v>;
  10139. + };
  10140. +
  10141. + hdmiin: adv7611@4c {
  10142. + compatible = "adi,adv7611";
  10143. + reg = <0x4c>;
  10144. + };
  10145. +
  10146. + touchscreen: egalax_ts@04 {
  10147. + compatible = "eeti,egalax_ts";
  10148. + reg = <0x04>;
  10149. + interrupt-parent = <&gpio7>;
  10150. + interrupts = <12 2>; /* gpio7_12 active low */
  10151. + wakeup-gpios = <&gpio7 12 0>;
  10152. + };
  10153. +
  10154. + videoout: adv7393@2a {
  10155. + compatible = "adi,adv7393";
  10156. + reg = <0x2a>;
  10157. + };
  10158. +
  10159. + videoin: adv7180@20 {
  10160. + compatible = "adi,adv7180";
  10161. + reg = <0x20>;
  10162. + };
  10163. +};
  10164. +
  10165. +&iomuxc {
  10166. + pinctrl-names = "default";
  10167. + pinctrl-0 = <&pinctrl_hog>;
  10168. +
  10169. + imx6q-gw5400-a {
  10170. + pinctrl_hog: hoggrp {
  10171. + fsl,pins = <
  10172. + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000 /* OTG_PWR_EN */
  10173. + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000 /* SPINOR_CS0# */
  10174. + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000 /* PCIE IRQ */
  10175. + MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 /* PCIE RST */
  10176. + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x000130b0 /* AUD4_MCK */
  10177. + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x80000000 /* GPS_PPS */
  10178. + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 /* TOUCH_IRQ# */
  10179. + MX6QDL_PAD_KEY_COL0__GPIO4_IO06 0x80000000 /* user1 led */
  10180. + MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x80000000 /* user2 led */
  10181. + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x80000000 /* user3 led */
  10182. + MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x80000000 /* USBHUB_RST# */
  10183. + MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x80000000 /* MIPI_DIO */
  10184. + >;
  10185. + };
  10186. +
  10187. + pinctrl_audmux: audmuxgrp {
  10188. + fsl,pins = <
  10189. + MX6QDL_PAD_SD2_DAT0__AUD4_RXD 0x130b0
  10190. + MX6QDL_PAD_SD2_DAT3__AUD4_TXC 0x130b0
  10191. + MX6QDL_PAD_SD2_DAT2__AUD4_TXD 0x110b0
  10192. + MX6QDL_PAD_SD2_DAT1__AUD4_TXFS 0x130b0
  10193. + >;
  10194. + };
  10195. +
  10196. + pinctrl_ecspi1: ecspi1grp {
  10197. + fsl,pins = <
  10198. + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
  10199. + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
  10200. + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
  10201. + >;
  10202. + };
  10203. +
  10204. + pinctrl_enet: enetgrp {
  10205. + fsl,pins = <
  10206. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  10207. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  10208. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  10209. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  10210. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  10211. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  10212. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  10213. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  10214. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  10215. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  10216. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  10217. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  10218. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  10219. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  10220. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  10221. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  10222. + >;
  10223. + };
  10224. +
  10225. + pinctrl_i2c1: i2c1grp {
  10226. + fsl,pins = <
  10227. + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
  10228. + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
  10229. + >;
  10230. + };
  10231. +
  10232. + pinctrl_i2c2: i2c2grp {
  10233. + fsl,pins = <
  10234. + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
  10235. + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
  10236. + >;
  10237. + };
  10238. +
  10239. + pinctrl_i2c3: i2c3grp {
  10240. + fsl,pins = <
  10241. + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
  10242. + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
  10243. + >;
  10244. + };
  10245. +
  10246. + pinctrl_uart1: uart1grp {
  10247. + fsl,pins = <
  10248. + MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
  10249. + MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
  10250. + >;
  10251. + };
  10252. +
  10253. + pinctrl_uart2: uart2grp {
  10254. + fsl,pins = <
  10255. + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
  10256. + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
  10257. + >;
  10258. + };
  10259. +
  10260. + pinctrl_uart5: uart5grp {
  10261. + fsl,pins = <
  10262. + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1
  10263. + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1
  10264. + >;
  10265. + };
  10266. +
  10267. + pinctrl_usbotg: usbotggrp {
  10268. + fsl,pins = <
  10269. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  10270. + >;
  10271. + };
  10272. +
  10273. + pinctrl_usdhc3: usdhc3grp {
  10274. + fsl,pins = <
  10275. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  10276. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  10277. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  10278. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  10279. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  10280. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  10281. + >;
  10282. + };
  10283. + };
  10284. +};
  10285. +
  10286. +&ldb {
  10287. + status = "okay";
  10288. +};
  10289. +
  10290. +&pcie {
  10291. + reset-gpio = <&gpio1 29 0>;
  10292. + status = "okay";
  10293. +
  10294. + eth1: sky2@8 { /* MAC/PHY on bus 8 */
  10295. + compatible = "marvell,sky2";
  10296. + };
  10297. +};
  10298. +
  10299. +&ssi1 {
  10300. + fsl,mode = "i2s-slave";
  10301. + status = "okay";
  10302. +};
  10303. +
  10304. +&uart1 {
  10305. + pinctrl-names = "default";
  10306. + pinctrl-0 = <&pinctrl_uart1>;
  10307. + status = "okay";
  10308. +};
  10309. +
  10310. +&uart2 {
  10311. + pinctrl-names = "default";
  10312. + pinctrl-0 = <&pinctrl_uart2>;
  10313. + status = "okay";
  10314. +};
  10315. +
  10316. +&uart5 {
  10317. + pinctrl-names = "default";
  10318. + pinctrl-0 = <&pinctrl_uart5>;
  10319. + status = "okay";
  10320. +};
  10321. +
  10322. +&usbotg {
  10323. + vbus-supply = <&reg_usb_otg_vbus>;
  10324. + pinctrl-names = "default";
  10325. + pinctrl-0 = <&pinctrl_usbotg>;
  10326. + disable-over-current;
  10327. + status = "okay";
  10328. +};
  10329. +
  10330. +&usbh1 {
  10331. + vbus-supply = <&reg_usb_h1_vbus>;
  10332. + status = "okay";
  10333. +};
  10334. +
  10335. +&usdhc3 {
  10336. + pinctrl-names = "default";
  10337. + pinctrl-0 = <&pinctrl_usdhc3>;
  10338. + cd-gpios = <&gpio7 0 0>;
  10339. + vmmc-supply = <&reg_3p3v>;
  10340. + status = "okay";
  10341. +};
  10342. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-gw54xx.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw54xx.dts
  10343. --- linux-3.14.17/arch/arm/boot/dts/imx6q-gw54xx.dts 1970-01-01 01:00:00.000000000 +0100
  10344. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-gw54xx.dts 2014-09-11 18:05:52.642000568 +0200
  10345. @@ -0,0 +1,23 @@
  10346. +/*
  10347. + * Copyright 2013 Gateworks Corporation
  10348. + *
  10349. + * The code contained herein is licensed under the GNU General Public
  10350. + * License. You may obtain a copy of the GNU General Public License
  10351. + * Version 2 or later at the following locations:
  10352. + *
  10353. + * http://www.opensource.org/licenses/gpl-license.html
  10354. + * http://www.gnu.org/copyleft/gpl.html
  10355. + */
  10356. +
  10357. +/dts-v1/;
  10358. +#include "imx6q.dtsi"
  10359. +#include "imx6qdl-gw54xx.dtsi"
  10360. +
  10361. +/ {
  10362. + model = "Gateworks Ventana i.MX6 Quad GW54XX";
  10363. + compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q";
  10364. +};
  10365. +
  10366. +&sata {
  10367. + status = "okay";
  10368. +};
  10369. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-hummingboard.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-hummingboard.dts
  10370. --- linux-3.14.17/arch/arm/boot/dts/imx6q-hummingboard.dts 1970-01-01 01:00:00.000000000 +0100
  10371. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-hummingboard.dts 2014-09-11 18:05:52.642000568 +0200
  10372. @@ -0,0 +1,21 @@
  10373. +/*
  10374. + * Copyright (C) 2014 Rabeeh Khoury (rabeeh@solid-run.com)
  10375. + * Based on work by Russell King
  10376. + */
  10377. +/dts-v1/;
  10378. +
  10379. +#include "imx6q.dtsi"
  10380. +#include "imx6qdl-hummingboard.dtsi"
  10381. +
  10382. +/ {
  10383. + model = "SolidRun HummingBoard Dual/Quad";
  10384. + compatible = "solidrun,hummingboard/q", "fsl,imx6q";
  10385. +};
  10386. +
  10387. +&sata {
  10388. + status = "okay";
  10389. + fsl,transmit-level-mV = <1104>;
  10390. + fsl,transmit-boost-mdB = <0>;
  10391. + fsl,transmit-atten-16ths = <9>;
  10392. + fsl,no-spread-spectrum;
  10393. +};
  10394. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-nitrogen6x.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-nitrogen6x.dts
  10395. --- linux-3.14.17/arch/arm/boot/dts/imx6q-nitrogen6x.dts 1970-01-01 01:00:00.000000000 +0100
  10396. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-nitrogen6x.dts 2014-09-11 18:05:52.642000568 +0200
  10397. @@ -0,0 +1,25 @@
  10398. +/*
  10399. + * Copyright 2013 Boundary Devices, Inc.
  10400. + * Copyright 2012 Freescale Semiconductor, Inc.
  10401. + * Copyright 2011 Linaro Ltd.
  10402. + *
  10403. + * The code contained herein is licensed under the GNU General Public
  10404. + * License. You may obtain a copy of the GNU General Public License
  10405. + * Version 2 or later at the following locations:
  10406. + *
  10407. + * http://www.opensource.org/licenses/gpl-license.html
  10408. + * http://www.gnu.org/copyleft/gpl.html
  10409. + */
  10410. +
  10411. +/dts-v1/;
  10412. +#include "imx6q.dtsi"
  10413. +#include "imx6qdl-nitrogen6x.dtsi"
  10414. +
  10415. +/ {
  10416. + model = "Freescale i.MX6 Quad Nitrogen6x Board";
  10417. + compatible = "fsl,imx6q-nitrogen6x", "fsl,imx6q";
  10418. +};
  10419. +
  10420. +&sata {
  10421. + status = "okay";
  10422. +};
  10423. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-phytec-pbab01.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
  10424. --- linux-3.14.17/arch/arm/boot/dts/imx6q-phytec-pbab01.dts 2014-08-14 03:38:34.000000000 +0200
  10425. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pbab01.dts 2014-09-11 18:05:52.642000568 +0200
  10426. @@ -11,24 +11,17 @@
  10427. /dts-v1/;
  10428. #include "imx6q-phytec-pfla02.dtsi"
  10429. +#include "imx6qdl-phytec-pbab01.dtsi"
  10430. / {
  10431. model = "Phytec phyFLEX-i.MX6 Quad Carrier-Board";
  10432. compatible = "phytec,imx6q-pbab01", "phytec,imx6q-pfla02", "fsl,imx6q";
  10433. -};
  10434. -
  10435. -&fec {
  10436. - status = "okay";
  10437. -};
  10438. -
  10439. -&uart4 {
  10440. - status = "okay";
  10441. -};
  10442. -&usdhc2 {
  10443. - status = "okay";
  10444. + chosen {
  10445. + stdout-path = &uart4;
  10446. + };
  10447. };
  10448. -&usdhc3 {
  10449. - status = "okay";
  10450. +&sata {
  10451. + status = "okay";
  10452. };
  10453. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
  10454. --- linux-3.14.17/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi 2014-08-14 03:38:34.000000000 +0200
  10455. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi 2014-09-11 18:05:52.642000568 +0200
  10456. @@ -10,171 +10,13 @@
  10457. */
  10458. #include "imx6q.dtsi"
  10459. +#include "imx6qdl-phytec-pfla02.dtsi"
  10460. / {
  10461. - model = "Phytec phyFLEX-i.MX6 Ouad";
  10462. + model = "Phytec phyFLEX-i.MX6 Quad";
  10463. compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
  10464. memory {
  10465. reg = <0x10000000 0x80000000>;
  10466. };
  10467. };
  10468. -
  10469. -&ecspi3 {
  10470. - pinctrl-names = "default";
  10471. - pinctrl-0 = <&pinctrl_ecspi3_1>;
  10472. - status = "okay";
  10473. - fsl,spi-num-chipselects = <1>;
  10474. - cs-gpios = <&gpio4 24 0>;
  10475. -
  10476. - flash@0 {
  10477. - compatible = "m25p80";
  10478. - spi-max-frequency = <20000000>;
  10479. - reg = <0>;
  10480. - };
  10481. -};
  10482. -
  10483. -&i2c1 {
  10484. - pinctrl-names = "default";
  10485. - pinctrl-0 = <&pinctrl_i2c1_1>;
  10486. - status = "okay";
  10487. -
  10488. - eeprom@50 {
  10489. - compatible = "atmel,24c32";
  10490. - reg = <0x50>;
  10491. - };
  10492. -
  10493. - pmic@58 {
  10494. - compatible = "dialog,da9063";
  10495. - reg = <0x58>;
  10496. - interrupt-parent = <&gpio4>;
  10497. - interrupts = <17 0x8>; /* active-low GPIO4_17 */
  10498. -
  10499. - regulators {
  10500. - vddcore_reg: bcore1 {
  10501. - regulator-min-microvolt = <730000>;
  10502. - regulator-max-microvolt = <1380000>;
  10503. - regulator-always-on;
  10504. - };
  10505. -
  10506. - vddsoc_reg: bcore2 {
  10507. - regulator-min-microvolt = <730000>;
  10508. - regulator-max-microvolt = <1380000>;
  10509. - regulator-always-on;
  10510. - };
  10511. -
  10512. - vdd_ddr3_reg: bpro {
  10513. - regulator-min-microvolt = <1500000>;
  10514. - regulator-max-microvolt = <1500000>;
  10515. - regulator-always-on;
  10516. - };
  10517. -
  10518. - vdd_3v3_reg: bperi {
  10519. - regulator-min-microvolt = <3300000>;
  10520. - regulator-max-microvolt = <3300000>;
  10521. - regulator-always-on;
  10522. - };
  10523. -
  10524. - vdd_buckmem_reg: bmem {
  10525. - regulator-min-microvolt = <3300000>;
  10526. - regulator-max-microvolt = <3300000>;
  10527. - regulator-always-on;
  10528. - };
  10529. -
  10530. - vdd_eth_reg: bio {
  10531. - regulator-min-microvolt = <1200000>;
  10532. - regulator-max-microvolt = <1200000>;
  10533. - regulator-always-on;
  10534. - };
  10535. -
  10536. - vdd_eth_io_reg: ldo4 {
  10537. - regulator-min-microvolt = <2500000>;
  10538. - regulator-max-microvolt = <2500000>;
  10539. - regulator-always-on;
  10540. - };
  10541. -
  10542. - vdd_mx6_snvs_reg: ldo5 {
  10543. - regulator-min-microvolt = <3000000>;
  10544. - regulator-max-microvolt = <3000000>;
  10545. - regulator-always-on;
  10546. - };
  10547. -
  10548. - vdd_3v3_pmic_io_reg: ldo6 {
  10549. - regulator-min-microvolt = <3300000>;
  10550. - regulator-max-microvolt = <3300000>;
  10551. - regulator-always-on;
  10552. - };
  10553. -
  10554. - vdd_sd0_reg: ldo9 {
  10555. - regulator-min-microvolt = <3300000>;
  10556. - regulator-max-microvolt = <3300000>;
  10557. - };
  10558. -
  10559. - vdd_sd1_reg: ldo10 {
  10560. - regulator-min-microvolt = <3300000>;
  10561. - regulator-max-microvolt = <3300000>;
  10562. - };
  10563. -
  10564. - vdd_mx6_high_reg: ldo11 {
  10565. - regulator-min-microvolt = <3000000>;
  10566. - regulator-max-microvolt = <3000000>;
  10567. - regulator-always-on;
  10568. - };
  10569. - };
  10570. - };
  10571. -};
  10572. -
  10573. -&iomuxc {
  10574. - pinctrl-names = "default";
  10575. - pinctrl-0 = <&pinctrl_hog>;
  10576. -
  10577. - hog {
  10578. - pinctrl_hog: hoggrp {
  10579. - fsl,pins = <
  10580. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10581. - MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
  10582. - MX6QDL_PAD_DI0_PIN15__GPIO4_IO17 0x80000000 /* PMIC interrupt */
  10583. - >;
  10584. - };
  10585. - };
  10586. -
  10587. - pfla02 {
  10588. - pinctrl_usdhc3_pfla02: usdhc3grp-pfla02 {
  10589. - fsl,pins = <
  10590. - MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
  10591. - MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
  10592. - >;
  10593. - };
  10594. - };
  10595. -};
  10596. -
  10597. -&fec {
  10598. - pinctrl-names = "default";
  10599. - pinctrl-0 = <&pinctrl_enet_3>;
  10600. - phy-mode = "rgmii";
  10601. - phy-reset-gpios = <&gpio3 23 0>;
  10602. - status = "disabled";
  10603. -};
  10604. -
  10605. -&uart4 {
  10606. - pinctrl-names = "default";
  10607. - pinctrl-0 = <&pinctrl_uart4_1>;
  10608. - status = "disabled";
  10609. -};
  10610. -
  10611. -&usdhc2 {
  10612. - pinctrl-names = "default";
  10613. - pinctrl-0 = <&pinctrl_usdhc2_2>;
  10614. - cd-gpios = <&gpio1 4 0>;
  10615. - wp-gpios = <&gpio1 2 0>;
  10616. - status = "disabled";
  10617. -};
  10618. -
  10619. -&usdhc3 {
  10620. - pinctrl-names = "default";
  10621. - pinctrl-0 = <&pinctrl_usdhc3_2
  10622. - &pinctrl_usdhc3_pfla02>;
  10623. - cd-gpios = <&gpio1 27 0>;
  10624. - wp-gpios = <&gpio1 29 0>;
  10625. - status = "disabled";
  10626. -};
  10627. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-pinfunc.h linux-imx6-3.14/arch/arm/boot/dts/imx6q-pinfunc.h
  10628. --- linux-3.14.17/arch/arm/boot/dts/imx6q-pinfunc.h 2014-08-14 03:38:34.000000000 +0200
  10629. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-pinfunc.h 2014-09-11 18:05:52.642000568 +0200
  10630. @@ -673,6 +673,7 @@
  10631. #define MX6QDL_PAD_GPIO_3__USB_H1_OC 0x22c 0x5fc 0x948 0x6 0x1
  10632. #define MX6QDL_PAD_GPIO_3__MLB_CLK 0x22c 0x5fc 0x900 0x7 0x1
  10633. #define MX6QDL_PAD_GPIO_6__ESAI_TX_CLK 0x230 0x600 0x870 0x0 0x1
  10634. +#define MX6QDL_PAD_GPIO_6__ENET_IRQ 0x230 0x600 0x03c 0x11 0xff000609
  10635. #define MX6QDL_PAD_GPIO_6__I2C3_SDA 0x230 0x600 0x8ac 0x2 0x1
  10636. #define MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x230 0x600 0x000 0x5 0x0
  10637. #define MX6QDL_PAD_GPIO_6__SD2_LCTL 0x230 0x600 0x000 0x6 0x0
  10638. @@ -1024,6 +1025,7 @@
  10639. #define MX6QDL_PAD_SD1_DAT2__WDOG1_RESET_B_DEB 0x34c 0x734 0x000 0x6 0x0
  10640. #define MX6QDL_PAD_SD1_CLK__SD1_CLK 0x350 0x738 0x000 0x0 0x0
  10641. #define MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x350 0x738 0x828 0x1 0x0
  10642. +#define MX6QDL_PAD_SD1_CLK__OSC32K_32K_OUT 0x350 0x738 0x000 0x2 0x0
  10643. #define MX6QDL_PAD_SD1_CLK__GPT_CLKIN 0x350 0x738 0x000 0x3 0x0
  10644. #define MX6QDL_PAD_SD1_CLK__GPIO1_IO20 0x350 0x738 0x000 0x5 0x0
  10645. #define MX6QDL_PAD_SD2_CLK__SD2_CLK 0x354 0x73c 0x000 0x0 0x0
  10646. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-sabreauto.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabreauto.dts
  10647. --- linux-3.14.17/arch/arm/boot/dts/imx6q-sabreauto.dts 2014-08-14 03:38:34.000000000 +0200
  10648. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabreauto.dts 2014-09-11 18:05:52.642000568 +0200
  10649. @@ -20,6 +20,22 @@
  10650. compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
  10651. };
  10652. +&mxcfb1 {
  10653. + status = "okay";
  10654. +};
  10655. +
  10656. +&mxcfb2 {
  10657. + status = "okay";
  10658. +};
  10659. +
  10660. +&mxcfb3 {
  10661. + status = "okay";
  10662. +};
  10663. +
  10664. +&mxcfb4 {
  10665. + status = "okay";
  10666. +};
  10667. +
  10668. &sata {
  10669. status = "okay";
  10670. };
  10671. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-sabrelite.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabrelite.dts
  10672. --- linux-3.14.17/arch/arm/boot/dts/imx6q-sabrelite.dts 2014-08-14 03:38:34.000000000 +0200
  10673. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabrelite.dts 2014-09-11 18:05:52.642000568 +0200
  10674. @@ -12,189 +12,13 @@
  10675. /dts-v1/;
  10676. #include "imx6q.dtsi"
  10677. +#include "imx6qdl-sabrelite.dtsi"
  10678. / {
  10679. model = "Freescale i.MX6 Quad SABRE Lite Board";
  10680. compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
  10681. -
  10682. - memory {
  10683. - reg = <0x10000000 0x40000000>;
  10684. - };
  10685. -
  10686. - regulators {
  10687. - compatible = "simple-bus";
  10688. -
  10689. - reg_2p5v: 2p5v {
  10690. - compatible = "regulator-fixed";
  10691. - regulator-name = "2P5V";
  10692. - regulator-min-microvolt = <2500000>;
  10693. - regulator-max-microvolt = <2500000>;
  10694. - regulator-always-on;
  10695. - };
  10696. -
  10697. - reg_3p3v: 3p3v {
  10698. - compatible = "regulator-fixed";
  10699. - regulator-name = "3P3V";
  10700. - regulator-min-microvolt = <3300000>;
  10701. - regulator-max-microvolt = <3300000>;
  10702. - regulator-always-on;
  10703. - };
  10704. -
  10705. - reg_usb_otg_vbus: usb_otg_vbus {
  10706. - compatible = "regulator-fixed";
  10707. - regulator-name = "usb_otg_vbus";
  10708. - regulator-min-microvolt = <5000000>;
  10709. - regulator-max-microvolt = <5000000>;
  10710. - gpio = <&gpio3 22 0>;
  10711. - enable-active-high;
  10712. - };
  10713. - };
  10714. -
  10715. - sound {
  10716. - compatible = "fsl,imx6q-sabrelite-sgtl5000",
  10717. - "fsl,imx-audio-sgtl5000";
  10718. - model = "imx6q-sabrelite-sgtl5000";
  10719. - ssi-controller = <&ssi1>;
  10720. - audio-codec = <&codec>;
  10721. - audio-routing =
  10722. - "MIC_IN", "Mic Jack",
  10723. - "Mic Jack", "Mic Bias",
  10724. - "Headphone Jack", "HP_OUT";
  10725. - mux-int-port = <1>;
  10726. - mux-ext-port = <4>;
  10727. - };
  10728. -};
  10729. -
  10730. -&audmux {
  10731. - status = "okay";
  10732. - pinctrl-names = "default";
  10733. - pinctrl-0 = <&pinctrl_audmux_1>;
  10734. -};
  10735. -
  10736. -&ecspi1 {
  10737. - fsl,spi-num-chipselects = <1>;
  10738. - cs-gpios = <&gpio3 19 0>;
  10739. - pinctrl-names = "default";
  10740. - pinctrl-0 = <&pinctrl_ecspi1_1>;
  10741. - status = "okay";
  10742. -
  10743. - flash: m25p80@0 {
  10744. - compatible = "sst,sst25vf016b";
  10745. - spi-max-frequency = <20000000>;
  10746. - reg = <0>;
  10747. - };
  10748. -};
  10749. -
  10750. -&fec {
  10751. - pinctrl-names = "default";
  10752. - pinctrl-0 = <&pinctrl_enet_1>;
  10753. - phy-mode = "rgmii";
  10754. - phy-reset-gpios = <&gpio3 23 0>;
  10755. - status = "okay";
  10756. -};
  10757. -
  10758. -&i2c1 {
  10759. - status = "okay";
  10760. - clock-frequency = <100000>;
  10761. - pinctrl-names = "default";
  10762. - pinctrl-0 = <&pinctrl_i2c1_1>;
  10763. -
  10764. - codec: sgtl5000@0a {
  10765. - compatible = "fsl,sgtl5000";
  10766. - reg = <0x0a>;
  10767. - clocks = <&clks 201>;
  10768. - VDDA-supply = <&reg_2p5v>;
  10769. - VDDIO-supply = <&reg_3p3v>;
  10770. - };
  10771. -};
  10772. -
  10773. -&iomuxc {
  10774. - pinctrl-names = "default";
  10775. - pinctrl-0 = <&pinctrl_hog>;
  10776. -
  10777. - hog {
  10778. - pinctrl_hog: hoggrp {
  10779. - fsl,pins = <
  10780. - MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x80000000
  10781. - MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x80000000
  10782. - MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x80000000
  10783. - MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x80000000
  10784. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10785. - MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x80000000
  10786. - MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0
  10787. - MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x80000000
  10788. - MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
  10789. - >;
  10790. - };
  10791. - };
  10792. -};
  10793. -
  10794. -&ldb {
  10795. - status = "okay";
  10796. -
  10797. - lvds-channel@0 {
  10798. - fsl,data-mapping = "spwg";
  10799. - fsl,data-width = <18>;
  10800. - status = "okay";
  10801. -
  10802. - display-timings {
  10803. - native-mode = <&timing0>;
  10804. - timing0: hsd100pxn1 {
  10805. - clock-frequency = <65000000>;
  10806. - hactive = <1024>;
  10807. - vactive = <768>;
  10808. - hback-porch = <220>;
  10809. - hfront-porch = <40>;
  10810. - vback-porch = <21>;
  10811. - vfront-porch = <7>;
  10812. - hsync-len = <60>;
  10813. - vsync-len = <10>;
  10814. - };
  10815. - };
  10816. - };
  10817. };
  10818. &sata {
  10819. status = "okay";
  10820. };
  10821. -
  10822. -&ssi1 {
  10823. - fsl,mode = "i2s-slave";
  10824. - status = "okay";
  10825. -};
  10826. -
  10827. -&uart2 {
  10828. - status = "okay";
  10829. - pinctrl-names = "default";
  10830. - pinctrl-0 = <&pinctrl_uart2_1>;
  10831. -};
  10832. -
  10833. -&usbh1 {
  10834. - status = "okay";
  10835. -};
  10836. -
  10837. -&usbotg {
  10838. - vbus-supply = <&reg_usb_otg_vbus>;
  10839. - pinctrl-names = "default";
  10840. - pinctrl-0 = <&pinctrl_usbotg_1>;
  10841. - disable-over-current;
  10842. - status = "okay";
  10843. -};
  10844. -
  10845. -&usdhc3 {
  10846. - pinctrl-names = "default";
  10847. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  10848. - cd-gpios = <&gpio7 0 0>;
  10849. - wp-gpios = <&gpio7 1 0>;
  10850. - vmmc-supply = <&reg_3p3v>;
  10851. - status = "okay";
  10852. -};
  10853. -
  10854. -&usdhc4 {
  10855. - pinctrl-names = "default";
  10856. - pinctrl-0 = <&pinctrl_usdhc4_2>;
  10857. - cd-gpios = <&gpio2 6 0>;
  10858. - wp-gpios = <&gpio2 7 0>;
  10859. - vmmc-supply = <&reg_3p3v>;
  10860. - status = "okay";
  10861. -};
  10862. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-sabresd.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd.dts
  10863. --- linux-3.14.17/arch/arm/boot/dts/imx6q-sabresd.dts 2014-08-14 03:38:34.000000000 +0200
  10864. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd.dts 2014-09-11 18:05:52.642000568 +0200
  10865. @@ -23,3 +23,19 @@
  10866. &sata {
  10867. status = "okay";
  10868. };
  10869. +
  10870. +&mxcfb1 {
  10871. + status = "okay";
  10872. +};
  10873. +
  10874. +&mxcfb2 {
  10875. + status = "okay";
  10876. +};
  10877. +
  10878. +&mxcfb3 {
  10879. + status = "okay";
  10880. +};
  10881. +
  10882. +&mxcfb4 {
  10883. + status = "okay";
  10884. +};
  10885. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts
  10886. --- linux-3.14.17/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts 1970-01-01 01:00:00.000000000 +0100
  10887. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sabresd-hdcp.dts 2014-09-11 18:05:52.642000568 +0200
  10888. @@ -0,0 +1,23 @@
  10889. +/*
  10890. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  10891. + * Copyright 2011 Linaro Ltd.
  10892. + *
  10893. + * The code contained herein is licensed under the GNU General Public
  10894. + * License. You may obtain a copy of the GNU General Public License
  10895. + * Version 2 or later at the following locations:
  10896. + *
  10897. + * http://www.opensource.org/licenses/gpl-license.html
  10898. + * http://www.gnu.org/copyleft/gpl.html
  10899. + */
  10900. +
  10901. +#include "imx6q-sabresd.dts"
  10902. +
  10903. +&hdmi_video {
  10904. + pinctrl-names = "default";
  10905. + pinctrl-0 = <&pinctrl_hdmi_hdcp>;
  10906. + fsl,hdcp;
  10907. +};
  10908. +
  10909. +&i2c2 {
  10910. + status = "disable";
  10911. +};
  10912. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-sbc6x.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-sbc6x.dts
  10913. --- linux-3.14.17/arch/arm/boot/dts/imx6q-sbc6x.dts 2014-08-14 03:38:34.000000000 +0200
  10914. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-sbc6x.dts 2014-09-11 18:05:52.642000568 +0200
  10915. @@ -17,28 +17,78 @@
  10916. };
  10917. };
  10918. +
  10919. &fec {
  10920. pinctrl-names = "default";
  10921. - pinctrl-0 = <&pinctrl_enet_1>;
  10922. + pinctrl-0 = <&pinctrl_enet>;
  10923. phy-mode = "rgmii";
  10924. status = "okay";
  10925. };
  10926. +&iomuxc {
  10927. + imx6q-sbc6x {
  10928. + pinctrl_enet: enetgrp {
  10929. + fsl,pins = <
  10930. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  10931. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  10932. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  10933. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  10934. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  10935. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  10936. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  10937. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  10938. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  10939. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  10940. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  10941. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  10942. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  10943. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  10944. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  10945. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  10946. + >;
  10947. + };
  10948. +
  10949. + pinctrl_uart1: uart1grp {
  10950. + fsl,pins = <
  10951. + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
  10952. + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
  10953. + >;
  10954. + };
  10955. +
  10956. + pinctrl_usbotg: usbotggrp {
  10957. + fsl,pins = <
  10958. + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
  10959. + >;
  10960. + };
  10961. +
  10962. + pinctrl_usdhc3: usdhc3grp {
  10963. + fsl,pins = <
  10964. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  10965. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  10966. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  10967. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  10968. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  10969. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  10970. + >;
  10971. + };
  10972. + };
  10973. +};
  10974. +
  10975. &uart1 {
  10976. pinctrl-names = "default";
  10977. - pinctrl-0 = <&pinctrl_uart1_1>;
  10978. + pinctrl-0 = <&pinctrl_uart1>;
  10979. status = "okay";
  10980. };
  10981. &usbotg {
  10982. pinctrl-names = "default";
  10983. - pinctrl-0 = <&pinctrl_usbotg_1>;
  10984. + pinctrl-0 = <&pinctrl_usbotg>;
  10985. disable-over-current;
  10986. status = "okay";
  10987. };
  10988. &usdhc3 {
  10989. pinctrl-names = "default";
  10990. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  10991. + pinctrl-0 = <&pinctrl_usdhc3>;
  10992. status = "okay";
  10993. };
  10994. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6q-udoo.dts linux-imx6-3.14/arch/arm/boot/dts/imx6q-udoo.dts
  10995. --- linux-3.14.17/arch/arm/boot/dts/imx6q-udoo.dts 2014-08-14 03:38:34.000000000 +0200
  10996. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6q-udoo.dts 2014-09-11 18:05:52.642000568 +0200
  10997. @@ -16,24 +16,78 @@
  10998. model = "Udoo i.MX6 Quad Board";
  10999. compatible = "udoo,imx6q-udoo", "fsl,imx6q";
  11000. + chosen {
  11001. + stdout-path = &uart2;
  11002. + };
  11003. +
  11004. memory {
  11005. reg = <0x10000000 0x40000000>;
  11006. };
  11007. };
  11008. +&fec {
  11009. + pinctrl-names = "default";
  11010. + pinctrl-0 = <&pinctrl_enet>;
  11011. + phy-mode = "rgmii";
  11012. + status = "okay";
  11013. +};
  11014. +
  11015. +&iomuxc {
  11016. + imx6q-udoo {
  11017. + pinctrl_enet: enetgrp {
  11018. + fsl,pins = <
  11019. + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
  11020. + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
  11021. + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
  11022. + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
  11023. + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
  11024. + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
  11025. + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
  11026. + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
  11027. + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
  11028. + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
  11029. + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
  11030. + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
  11031. + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
  11032. + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
  11033. + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
  11034. + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
  11035. + >;
  11036. + };
  11037. +
  11038. + pinctrl_uart2: uart2grp {
  11039. + fsl,pins = <
  11040. + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
  11041. + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
  11042. + >;
  11043. + };
  11044. +
  11045. + pinctrl_usdhc3: usdhc3grp {
  11046. + fsl,pins = <
  11047. + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
  11048. + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
  11049. + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  11050. + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  11051. + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  11052. + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  11053. + >;
  11054. + };
  11055. + };
  11056. +};
  11057. +
  11058. &sata {
  11059. status = "okay";
  11060. };
  11061. &uart2 {
  11062. pinctrl-names = "default";
  11063. - pinctrl-0 = <&pinctrl_uart2_1>;
  11064. + pinctrl-0 = <&pinctrl_uart2>;
  11065. status = "okay";
  11066. };
  11067. &usdhc3 {
  11068. pinctrl-names = "default";
  11069. - pinctrl-0 = <&pinctrl_usdhc3_2>;
  11070. + pinctrl-0 = <&pinctrl_usdhc3>;
  11071. non-removable;
  11072. status = "okay";
  11073. };
  11074. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6sl.dtsi linux-imx6-3.14/arch/arm/boot/dts/imx6sl.dtsi
  11075. --- linux-3.14.17/arch/arm/boot/dts/imx6sl.dtsi 2014-08-14 03:38:34.000000000 +0200
  11076. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6sl.dtsi 2014-09-11 18:05:52.646000583 +0200
  11077. @@ -7,12 +7,14 @@
  11078. *
  11079. */
  11080. +#include <dt-bindings/interrupt-controller/irq.h>
  11081. #include "skeleton.dtsi"
  11082. #include "imx6sl-pinfunc.h"
  11083. #include <dt-bindings/clock/imx6sl-clock.h>
  11084. / {
  11085. aliases {
  11086. + ethernet0 = &fec;
  11087. gpio0 = &gpio1;
  11088. gpio1 = &gpio2;
  11089. gpio2 = &gpio3;
  11090. @@ -27,25 +29,46 @@
  11091. spi1 = &ecspi2;
  11092. spi2 = &ecspi3;
  11093. spi3 = &ecspi4;
  11094. + usbphy0 = &usbphy1;
  11095. + usbphy1 = &usbphy2;
  11096. };
  11097. cpus {
  11098. #address-cells = <1>;
  11099. #size-cells = <0>;
  11100. - cpu@0 {
  11101. + cpu0: cpu@0 {
  11102. compatible = "arm,cortex-a9";
  11103. device_type = "cpu";
  11104. reg = <0x0>;
  11105. next-level-cache = <&L2>;
  11106. + operating-points = <
  11107. + /* kHz uV */
  11108. + 996000 1275000
  11109. + 792000 1175000
  11110. + 396000 975000
  11111. + >;
  11112. + fsl,soc-operating-points = <
  11113. + /* ARM kHz SOC-PU uV */
  11114. + 996000 1225000
  11115. + 792000 1175000
  11116. + 396000 1175000
  11117. + >;
  11118. + clock-latency = <61036>; /* two CLK32 periods */
  11119. + clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
  11120. + <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_CLK_PLL1_SW>,
  11121. + <&clks IMX6SL_CLK_PLL1_SYS>;
  11122. + clock-names = "arm", "pll2_pfd2_396m", "step",
  11123. + "pll1_sw", "pll1_sys";
  11124. + arm-supply = <&reg_arm>;
  11125. + pu-supply = <&reg_pu>;
  11126. + soc-supply = <&reg_soc>;
  11127. };
  11128. };
  11129. intc: interrupt-controller@00a01000 {
  11130. compatible = "arm,cortex-a9-gic";
  11131. #interrupt-cells = <3>;
  11132. - #address-cells = <1>;
  11133. - #size-cells = <1>;
  11134. interrupt-controller;
  11135. reg = <0x00a01000 0x1000>,
  11136. <0x00a00100 0x100>;
  11137. @@ -57,15 +80,21 @@
  11138. ckil {
  11139. compatible = "fixed-clock";
  11140. + #clock-cells = <0>;
  11141. clock-frequency = <32768>;
  11142. };
  11143. osc {
  11144. compatible = "fixed-clock";
  11145. + #clock-cells = <0>;
  11146. clock-frequency = <24000000>;
  11147. };
  11148. };
  11149. + pu_dummy: pudummy_reg {
  11150. + compatible = "fsl,imx6-dummy-pureg"; /* only used in ldo-bypass */
  11151. + };
  11152. +
  11153. soc {
  11154. #address-cells = <1>;
  11155. #size-cells = <1>;
  11156. @@ -73,19 +102,45 @@
  11157. interrupt-parent = <&intc>;
  11158. ranges;
  11159. + ocram: sram@00900000 {
  11160. + compatible = "mmio-sram";
  11161. + reg = <0x00900000 0x20000>;
  11162. + clocks = <&clks IMX6SL_CLK_OCRAM>;
  11163. + };
  11164. +
  11165. + busfreq { /* BUSFREQ */
  11166. + compatible = "fsl,imx6_busfreq";
  11167. + clocks = <&clks IMX6SL_CLK_PLL2_BUS>, <&clks IMX6SL_CLK_PLL2_PFD2>,
  11168. + <&clks IMX6SL_CLK_PLL2_198M>, <&clks IMX6SL_CLK_ARM>,
  11169. + <&clks IMX6SL_CLK_PLL3_USB_OTG>, <&clks IMX6SL_CLK_PERIPH>,
  11170. + <&clks IMX6SL_CLK_PRE_PERIPH_SEL>, <&clks IMX6SL_CLK_PERIPH_CLK2>,
  11171. + <&clks IMX6SL_CLK_PERIPH_CLK2_SEL>, <&clks IMX6SL_CLK_OSC>,
  11172. + <&clks IMX6SL_CLK_PLL1_SYS>, <&clks IMX6SL_CLK_PERIPH2>,
  11173. + <&clks IMX6SL_CLK_AHB>, <&clks IMX6SL_CLK_OCRAM>,
  11174. + <&clks IMX6SL_CLK_PLL1_SW>, <&clks IMX6SL_CLK_PRE_PERIPH2_SEL>,
  11175. + <&clks IMX6SL_CLK_PERIPH2_CLK2_SEL>, <&clks IMX6SL_CLK_PERIPH2_CLK2>,
  11176. + <&clks IMX6SL_CLK_STEP>;
  11177. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  11178. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc", "pll1_sys", "periph2", "ahb", "ocram", "pll1_sw",
  11179. + "periph2_pre", "periph2_clk2_sel", "periph2_clk2", "step";
  11180. + fsl,max_ddr_freq = <400000000>;
  11181. + };
  11182. +
  11183. L2: l2-cache@00a02000 {
  11184. compatible = "arm,pl310-cache";
  11185. reg = <0x00a02000 0x1000>;
  11186. - interrupts = <0 92 0x04>;
  11187. + interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
  11188. cache-unified;
  11189. cache-level = <2>;
  11190. arm,tag-latency = <4 2 3>;
  11191. arm,data-latency = <4 2 3>;
  11192. + arm,dynamic-clk-gating;
  11193. + arm,standby-mode;
  11194. };
  11195. pmu {
  11196. compatible = "arm,cortex-a9-pmu";
  11197. - interrupts = <0 94 0x04>;
  11198. + interrupts = <0 94 IRQ_TYPE_LEVEL_HIGH>;
  11199. };
  11200. aips1: aips-bus@02000000 {
  11201. @@ -104,7 +159,7 @@
  11202. spdif: spdif@02004000 {
  11203. reg = <0x02004000 0x4000>;
  11204. - interrupts = <0 52 0x04>;
  11205. + interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
  11206. };
  11207. ecspi1: ecspi@02008000 {
  11208. @@ -112,7 +167,7 @@
  11209. #size-cells = <0>;
  11210. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11211. reg = <0x02008000 0x4000>;
  11212. - interrupts = <0 31 0x04>;
  11213. + interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
  11214. clocks = <&clks IMX6SL_CLK_ECSPI1>,
  11215. <&clks IMX6SL_CLK_ECSPI1>;
  11216. clock-names = "ipg", "per";
  11217. @@ -124,7 +179,7 @@
  11218. #size-cells = <0>;
  11219. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11220. reg = <0x0200c000 0x4000>;
  11221. - interrupts = <0 32 0x04>;
  11222. + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>;
  11223. clocks = <&clks IMX6SL_CLK_ECSPI2>,
  11224. <&clks IMX6SL_CLK_ECSPI2>;
  11225. clock-names = "ipg", "per";
  11226. @@ -136,7 +191,7 @@
  11227. #size-cells = <0>;
  11228. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11229. reg = <0x02010000 0x4000>;
  11230. - interrupts = <0 33 0x04>;
  11231. + interrupts = <0 33 IRQ_TYPE_LEVEL_HIGH>;
  11232. clocks = <&clks IMX6SL_CLK_ECSPI3>,
  11233. <&clks IMX6SL_CLK_ECSPI3>;
  11234. clock-names = "ipg", "per";
  11235. @@ -148,7 +203,7 @@
  11236. #size-cells = <0>;
  11237. compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
  11238. reg = <0x02014000 0x4000>;
  11239. - interrupts = <0 34 0x04>;
  11240. + interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
  11241. clocks = <&clks IMX6SL_CLK_ECSPI4>,
  11242. <&clks IMX6SL_CLK_ECSPI4>;
  11243. clock-names = "ipg", "per";
  11244. @@ -159,7 +214,7 @@
  11245. compatible = "fsl,imx6sl-uart",
  11246. "fsl,imx6q-uart", "fsl,imx21-uart";
  11247. reg = <0x02018000 0x4000>;
  11248. - interrupts = <0 30 0x04>;
  11249. + interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
  11250. clocks = <&clks IMX6SL_CLK_UART>,
  11251. <&clks IMX6SL_CLK_UART_SERIAL>;
  11252. clock-names = "ipg", "per";
  11253. @@ -172,7 +227,7 @@
  11254. compatible = "fsl,imx6sl-uart",
  11255. "fsl,imx6q-uart", "fsl,imx21-uart";
  11256. reg = <0x02020000 0x4000>;
  11257. - interrupts = <0 26 0x04>;
  11258. + interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
  11259. clocks = <&clks IMX6SL_CLK_UART>,
  11260. <&clks IMX6SL_CLK_UART_SERIAL>;
  11261. clock-names = "ipg", "per";
  11262. @@ -185,7 +240,7 @@
  11263. compatible = "fsl,imx6sl-uart",
  11264. "fsl,imx6q-uart", "fsl,imx21-uart";
  11265. reg = <0x02024000 0x4000>;
  11266. - interrupts = <0 27 0x04>;
  11267. + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
  11268. clocks = <&clks IMX6SL_CLK_UART>,
  11269. <&clks IMX6SL_CLK_UART_SERIAL>;
  11270. clock-names = "ipg", "per";
  11271. @@ -195,9 +250,11 @@
  11272. };
  11273. ssi1: ssi@02028000 {
  11274. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11275. + compatible = "fsl,imx6sl-ssi",
  11276. + "fsl,imx51-ssi",
  11277. + "fsl,imx21-ssi";
  11278. reg = <0x02028000 0x4000>;
  11279. - interrupts = <0 46 0x04>;
  11280. + interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
  11281. clocks = <&clks IMX6SL_CLK_SSI1>;
  11282. dmas = <&sdma 37 1 0>,
  11283. <&sdma 38 1 0>;
  11284. @@ -207,9 +264,11 @@
  11285. };
  11286. ssi2: ssi@0202c000 {
  11287. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11288. + compatible = "fsl,imx6sl-ssi",
  11289. + "fsl,imx51-ssi",
  11290. + "fsl,imx21-ssi";
  11291. reg = <0x0202c000 0x4000>;
  11292. - interrupts = <0 47 0x04>;
  11293. + interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
  11294. clocks = <&clks IMX6SL_CLK_SSI2>;
  11295. dmas = <&sdma 41 1 0>,
  11296. <&sdma 42 1 0>;
  11297. @@ -219,9 +278,11 @@
  11298. };
  11299. ssi3: ssi@02030000 {
  11300. - compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
  11301. + compatible = "fsl,imx6sl-ssi",
  11302. + "fsl,imx51-ssi",
  11303. + "fsl,imx21-ssi";
  11304. reg = <0x02030000 0x4000>;
  11305. - interrupts = <0 48 0x04>;
  11306. + interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
  11307. clocks = <&clks IMX6SL_CLK_SSI3>;
  11308. dmas = <&sdma 45 1 0>,
  11309. <&sdma 46 1 0>;
  11310. @@ -234,7 +295,7 @@
  11311. compatible = "fsl,imx6sl-uart",
  11312. "fsl,imx6q-uart", "fsl,imx21-uart";
  11313. reg = <0x02034000 0x4000>;
  11314. - interrupts = <0 28 0x04>;
  11315. + interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
  11316. clocks = <&clks IMX6SL_CLK_UART>,
  11317. <&clks IMX6SL_CLK_UART_SERIAL>;
  11318. clock-names = "ipg", "per";
  11319. @@ -247,7 +308,7 @@
  11320. compatible = "fsl,imx6sl-uart",
  11321. "fsl,imx6q-uart", "fsl,imx21-uart";
  11322. reg = <0x02038000 0x4000>;
  11323. - interrupts = <0 29 0x04>;
  11324. + interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
  11325. clocks = <&clks IMX6SL_CLK_UART>,
  11326. <&clks IMX6SL_CLK_UART_SERIAL>;
  11327. clock-names = "ipg", "per";
  11328. @@ -261,7 +322,7 @@
  11329. #pwm-cells = <2>;
  11330. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11331. reg = <0x02080000 0x4000>;
  11332. - interrupts = <0 83 0x04>;
  11333. + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;
  11334. clocks = <&clks IMX6SL_CLK_PWM1>,
  11335. <&clks IMX6SL_CLK_PWM1>;
  11336. clock-names = "ipg", "per";
  11337. @@ -271,7 +332,7 @@
  11338. #pwm-cells = <2>;
  11339. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11340. reg = <0x02084000 0x4000>;
  11341. - interrupts = <0 84 0x04>;
  11342. + interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
  11343. clocks = <&clks IMX6SL_CLK_PWM2>,
  11344. <&clks IMX6SL_CLK_PWM2>;
  11345. clock-names = "ipg", "per";
  11346. @@ -281,7 +342,7 @@
  11347. #pwm-cells = <2>;
  11348. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11349. reg = <0x02088000 0x4000>;
  11350. - interrupts = <0 85 0x04>;
  11351. + interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
  11352. clocks = <&clks IMX6SL_CLK_PWM3>,
  11353. <&clks IMX6SL_CLK_PWM3>;
  11354. clock-names = "ipg", "per";
  11355. @@ -291,7 +352,7 @@
  11356. #pwm-cells = <2>;
  11357. compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
  11358. reg = <0x0208c000 0x4000>;
  11359. - interrupts = <0 86 0x04>;
  11360. + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
  11361. clocks = <&clks IMX6SL_CLK_PWM4>,
  11362. <&clks IMX6SL_CLK_PWM4>;
  11363. clock-names = "ipg", "per";
  11364. @@ -300,7 +361,7 @@
  11365. gpt: gpt@02098000 {
  11366. compatible = "fsl,imx6sl-gpt";
  11367. reg = <0x02098000 0x4000>;
  11368. - interrupts = <0 55 0x04>;
  11369. + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
  11370. clocks = <&clks IMX6SL_CLK_GPT>,
  11371. <&clks IMX6SL_CLK_GPT_SERIAL>;
  11372. clock-names = "ipg", "per";
  11373. @@ -309,7 +370,8 @@
  11374. gpio1: gpio@0209c000 {
  11375. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11376. reg = <0x0209c000 0x4000>;
  11377. - interrupts = <0 66 0x04 0 67 0x04>;
  11378. + interrupts = <0 66 IRQ_TYPE_LEVEL_HIGH>,
  11379. + <0 67 IRQ_TYPE_LEVEL_HIGH>;
  11380. gpio-controller;
  11381. #gpio-cells = <2>;
  11382. interrupt-controller;
  11383. @@ -319,7 +381,8 @@
  11384. gpio2: gpio@020a0000 {
  11385. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11386. reg = <0x020a0000 0x4000>;
  11387. - interrupts = <0 68 0x04 0 69 0x04>;
  11388. + interrupts = <0 68 IRQ_TYPE_LEVEL_HIGH>,
  11389. + <0 69 IRQ_TYPE_LEVEL_HIGH>;
  11390. gpio-controller;
  11391. #gpio-cells = <2>;
  11392. interrupt-controller;
  11393. @@ -329,7 +392,8 @@
  11394. gpio3: gpio@020a4000 {
  11395. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11396. reg = <0x020a4000 0x4000>;
  11397. - interrupts = <0 70 0x04 0 71 0x04>;
  11398. + interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>,
  11399. + <0 71 IRQ_TYPE_LEVEL_HIGH>;
  11400. gpio-controller;
  11401. #gpio-cells = <2>;
  11402. interrupt-controller;
  11403. @@ -339,7 +403,8 @@
  11404. gpio4: gpio@020a8000 {
  11405. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11406. reg = <0x020a8000 0x4000>;
  11407. - interrupts = <0 72 0x04 0 73 0x04>;
  11408. + interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>,
  11409. + <0 73 IRQ_TYPE_LEVEL_HIGH>;
  11410. gpio-controller;
  11411. #gpio-cells = <2>;
  11412. interrupt-controller;
  11413. @@ -349,7 +414,8 @@
  11414. gpio5: gpio@020ac000 {
  11415. compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
  11416. reg = <0x020ac000 0x4000>;
  11417. - interrupts = <0 74 0x04 0 75 0x04>;
  11418. + interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>,
  11419. + <0 75 IRQ_TYPE_LEVEL_HIGH>;
  11420. gpio-controller;
  11421. #gpio-cells = <2>;
  11422. interrupt-controller;
  11423. @@ -357,21 +423,23 @@
  11424. };
  11425. kpp: kpp@020b8000 {
  11426. + compatible = "fsl,imx6sl-kpp", "fsl,imx21-kpp";
  11427. reg = <0x020b8000 0x4000>;
  11428. - interrupts = <0 82 0x04>;
  11429. + interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
  11430. + clocks = <&clks IMX6SL_CLK_DUMMY>;
  11431. };
  11432. wdog1: wdog@020bc000 {
  11433. compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
  11434. reg = <0x020bc000 0x4000>;
  11435. - interrupts = <0 80 0x04>;
  11436. + interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
  11437. clocks = <&clks IMX6SL_CLK_DUMMY>;
  11438. };
  11439. wdog2: wdog@020c0000 {
  11440. compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
  11441. reg = <0x020c0000 0x4000>;
  11442. - interrupts = <0 81 0x04>;
  11443. + interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
  11444. clocks = <&clks IMX6SL_CLK_DUMMY>;
  11445. status = "disabled";
  11446. };
  11447. @@ -379,7 +447,8 @@
  11448. clks: ccm@020c4000 {
  11449. compatible = "fsl,imx6sl-ccm";
  11450. reg = <0x020c4000 0x4000>;
  11451. - interrupts = <0 87 0x04 0 88 0x04>;
  11452. + interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>,
  11453. + <0 88 IRQ_TYPE_LEVEL_HIGH>;
  11454. #clock-cells = <1>;
  11455. };
  11456. @@ -388,7 +457,9 @@
  11457. "fsl,imx6q-anatop",
  11458. "syscon", "simple-bus";
  11459. reg = <0x020c8000 0x1000>;
  11460. - interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
  11461. + interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
  11462. + <0 54 IRQ_TYPE_LEVEL_HIGH>,
  11463. + <0 127 IRQ_TYPE_LEVEL_HIGH>;
  11464. regulator-1p1@110 {
  11465. compatible = "fsl,anatop-regulator";
  11466. @@ -434,7 +505,7 @@
  11467. reg_arm: regulator-vddcore@140 {
  11468. compatible = "fsl,anatop-regulator";
  11469. - regulator-name = "cpu";
  11470. + regulator-name = "vddarm";
  11471. regulator-min-microvolt = <725000>;
  11472. regulator-max-microvolt = <1450000>;
  11473. regulator-always-on;
  11474. @@ -454,7 +525,6 @@
  11475. regulator-name = "vddpu";
  11476. regulator-min-microvolt = <725000>;
  11477. regulator-max-microvolt = <1450000>;
  11478. - regulator-always-on;
  11479. anatop-reg-offset = <0x140>;
  11480. anatop-vol-bit-shift = <9>;
  11481. anatop-vol-bit-width = <5>;
  11482. @@ -484,18 +554,34 @@
  11483. };
  11484. };
  11485. + tempmon: tempmon {
  11486. + compatible = "fsl,imx6sl-tempmon", "fsl,imx6q-tempmon";
  11487. + interrupts = <0 49 0x04>;
  11488. + fsl,tempmon = <&anatop>;
  11489. + fsl,tempmon-data = <&ocotp>;
  11490. + clocks = <&clks IMX6SL_CLK_PLL3_USB_OTG>;
  11491. + };
  11492. +
  11493. usbphy1: usbphy@020c9000 {
  11494. compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
  11495. reg = <0x020c9000 0x1000>;
  11496. - interrupts = <0 44 0x04>;
  11497. + interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
  11498. clocks = <&clks IMX6SL_CLK_USBPHY1>;
  11499. + fsl,anatop = <&anatop>;
  11500. };
  11501. usbphy2: usbphy@020ca000 {
  11502. compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
  11503. reg = <0x020ca000 0x1000>;
  11504. - interrupts = <0 45 0x04>;
  11505. + interrupts = <0 45 IRQ_TYPE_LEVEL_HIGH>;
  11506. clocks = <&clks IMX6SL_CLK_USBPHY2>;
  11507. + fsl,anatop = <&anatop>;
  11508. + };
  11509. +
  11510. + usbphy_nop1: usbphy_nop1 {
  11511. + compatible = "usb-nop-xceiv";
  11512. + clocks = <&clks IMX6SL_CLK_USBPHY1>;
  11513. + clock-names = "main_clk";
  11514. };
  11515. snvs@020cc000 {
  11516. @@ -507,271 +593,165 @@
  11517. snvs-rtc-lp@34 {
  11518. compatible = "fsl,sec-v4.0-mon-rtc-lp";
  11519. reg = <0x34 0x58>;
  11520. - interrupts = <0 19 0x04 0 20 0x04>;
  11521. + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
  11522. + <0 20 IRQ_TYPE_LEVEL_HIGH>;
  11523. };
  11524. - };
  11525. -
  11526. - epit1: epit@020d0000 {
  11527. - reg = <0x020d0000 0x4000>;
  11528. - interrupts = <0 56 0x04>;
  11529. - };
  11530. - epit2: epit@020d4000 {
  11531. - reg = <0x020d4000 0x4000>;
  11532. - interrupts = <0 57 0x04>;
  11533. - };
  11534. -
  11535. - src: src@020d8000 {
  11536. - compatible = "fsl,imx6sl-src", "fsl,imx51-src";
  11537. - reg = <0x020d8000 0x4000>;
  11538. - interrupts = <0 91 0x04 0 96 0x04>;
  11539. - #reset-cells = <1>;
  11540. - };
  11541. -
  11542. - gpc: gpc@020dc000 {
  11543. - compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
  11544. - reg = <0x020dc000 0x4000>;
  11545. - interrupts = <0 89 0x04>;
  11546. - };
  11547. -
  11548. - gpr: iomuxc-gpr@020e0000 {
  11549. - compatible = "fsl,imx6sl-iomuxc-gpr",
  11550. - "fsl,imx6q-iomuxc-gpr", "syscon";
  11551. - reg = <0x020e0000 0x38>;
  11552. - };
  11553. -
  11554. - iomuxc: iomuxc@020e0000 {
  11555. - compatible = "fsl,imx6sl-iomuxc";
  11556. - reg = <0x020e0000 0x4000>;
  11557. -
  11558. - ecspi1 {
  11559. - pinctrl_ecspi1_1: ecspi1grp-1 {
  11560. + csi {
  11561. + pinctrl_csi_0: csigrp-0 {
  11562. fsl,pins = <
  11563. - MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
  11564. - MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
  11565. - MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
  11566. + MX6SL_PAD_EPDC_GDRL__CSI_MCLK 0x110b0
  11567. + MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK 0x110b0
  11568. + MX6SL_PAD_EPDC_GDSP__CSI_VSYNC 0x110b0
  11569. + MX6SL_PAD_EPDC_GDOE__CSI_HSYNC 0x110b0
  11570. + MX6SL_PAD_EPDC_SDLE__CSI_DATA09 0x110b0
  11571. + MX6SL_PAD_EPDC_SDCLK__CSI_DATA08 0x110b0
  11572. + MX6SL_PAD_EPDC_D7__CSI_DATA07 0x110b0
  11573. + MX6SL_PAD_EPDC_D6__CSI_DATA06 0x110b0
  11574. + MX6SL_PAD_EPDC_D5__CSI_DATA05 0x110b0
  11575. + MX6SL_PAD_EPDC_D4__CSI_DATA04 0x110b0
  11576. + MX6SL_PAD_EPDC_D3__CSI_DATA03 0x110b0
  11577. + MX6SL_PAD_EPDC_D2__CSI_DATA02 0x110b0
  11578. + MX6SL_PAD_EPDC_D1__CSI_DATA01 0x110b0
  11579. + MX6SL_PAD_EPDC_D0__CSI_DATA00 0x110b0
  11580. + MX6SL_PAD_EPDC_SDSHR__GPIO1_IO26 0x80000000
  11581. + MX6SL_PAD_EPDC_SDOE__GPIO1_IO25 0x80000000
  11582. >;
  11583. };
  11584. };
  11585. - fec {
  11586. - pinctrl_fec_1: fecgrp-1 {
  11587. + i2c1 {
  11588. + pinctrl_i2c1_1: i2c1grp-1 {
  11589. fsl,pins = <
  11590. - MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
  11591. - MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
  11592. - MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
  11593. - MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
  11594. - MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
  11595. - MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
  11596. - MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
  11597. - MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
  11598. - MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
  11599. + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
  11600. + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
  11601. >;
  11602. };
  11603. };
  11604. - uart1 {
  11605. - pinctrl_uart1_1: uart1grp-1 {
  11606. + i2c2 {
  11607. + pinctrl_i2c2_1: i2c2grp-1 {
  11608. fsl,pins = <
  11609. - MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
  11610. - MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
  11611. + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1
  11612. + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001b8b1
  11613. >;
  11614. };
  11615. };
  11616. - usbotg1 {
  11617. - pinctrl_usbotg1_1: usbotg1grp-1 {
  11618. - fsl,pins = <
  11619. - MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
  11620. - >;
  11621. - };
  11622. -
  11623. - pinctrl_usbotg1_2: usbotg1grp-2 {
  11624. + i2c3 {
  11625. + pinctrl_i2c3_1: i2c3grp-1 {
  11626. fsl,pins = <
  11627. - MX6SL_PAD_FEC_RXD0__USB_OTG1_ID 0x17059
  11628. - >;
  11629. - };
  11630. -
  11631. - pinctrl_usbotg1_3: usbotg1grp-3 {
  11632. - fsl,pins = <
  11633. - MX6SL_PAD_LCD_DAT1__USB_OTG1_ID 0x17059
  11634. - >;
  11635. - };
  11636. -
  11637. - pinctrl_usbotg1_4: usbotg1grp-4 {
  11638. - fsl,pins = <
  11639. - MX6SL_PAD_REF_CLK_32K__USB_OTG1_ID 0x17059
  11640. - >;
  11641. - };
  11642. -
  11643. - pinctrl_usbotg1_5: usbotg1grp-5 {
  11644. - fsl,pins = <
  11645. - MX6SL_PAD_SD3_DAT0__USB_OTG1_ID 0x17059
  11646. + MX6SL_PAD_EPDC_SDCE2__I2C3_SCL 0x4001b8b1
  11647. + MX6SL_PAD_EPDC_SDCE3__I2C3_SDA 0x4001b8b1
  11648. >;
  11649. };
  11650. };
  11651. - usbotg2 {
  11652. - pinctrl_usbotg2_1: usbotg2grp-1 {
  11653. - fsl,pins = <
  11654. - MX6SL_PAD_ECSPI1_SCLK__USB_OTG2_OC 0x17059
  11655. - >;
  11656. - };
  11657. -
  11658. - pinctrl_usbotg2_2: usbotg2grp-2 {
  11659. + lcdif {
  11660. + pinctrl_lcdif_dat_0: lcdifdatgrp-0 {
  11661. fsl,pins = <
  11662. - MX6SL_PAD_ECSPI2_SCLK__USB_OTG2_OC 0x17059
  11663. + MX6SL_PAD_LCD_DAT0__LCD_DATA00 0x1b0b0
  11664. + MX6SL_PAD_LCD_DAT1__LCD_DATA01 0x1b0b0
  11665. + MX6SL_PAD_LCD_DAT2__LCD_DATA02 0x1b0b0
  11666. + MX6SL_PAD_LCD_DAT3__LCD_DATA03 0x1b0b0
  11667. + MX6SL_PAD_LCD_DAT4__LCD_DATA04 0x1b0b0
  11668. + MX6SL_PAD_LCD_DAT5__LCD_DATA05 0x1b0b0
  11669. + MX6SL_PAD_LCD_DAT6__LCD_DATA06 0x1b0b0
  11670. + MX6SL_PAD_LCD_DAT7__LCD_DATA07 0x1b0b0
  11671. + MX6SL_PAD_LCD_DAT8__LCD_DATA08 0x1b0b0
  11672. + MX6SL_PAD_LCD_DAT9__LCD_DATA09 0x1b0b0
  11673. + MX6SL_PAD_LCD_DAT10__LCD_DATA10 0x1b0b0
  11674. + MX6SL_PAD_LCD_DAT11__LCD_DATA11 0x1b0b0
  11675. + MX6SL_PAD_LCD_DAT12__LCD_DATA12 0x1b0b0
  11676. + MX6SL_PAD_LCD_DAT13__LCD_DATA13 0x1b0b0
  11677. + MX6SL_PAD_LCD_DAT14__LCD_DATA14 0x1b0b0
  11678. + MX6SL_PAD_LCD_DAT15__LCD_DATA15 0x1b0b0
  11679. + MX6SL_PAD_LCD_DAT16__LCD_DATA16 0x1b0b0
  11680. + MX6SL_PAD_LCD_DAT17__LCD_DATA17 0x1b0b0
  11681. + MX6SL_PAD_LCD_DAT18__LCD_DATA18 0x1b0b0
  11682. + MX6SL_PAD_LCD_DAT19__LCD_DATA19 0x1b0b0
  11683. + MX6SL_PAD_LCD_DAT20__LCD_DATA20 0x1b0b0
  11684. + MX6SL_PAD_LCD_DAT21__LCD_DATA21 0x1b0b0
  11685. + MX6SL_PAD_LCD_DAT22__LCD_DATA22 0x1b0b0
  11686. + MX6SL_PAD_LCD_DAT23__LCD_DATA23 0x1b0b0
  11687. >;
  11688. };
  11689. - pinctrl_usbotg2_3: usbotg2grp-3 {
  11690. + pinctrl_lcdif_ctrl_0: lcdifctrlgrp-0 {
  11691. fsl,pins = <
  11692. - MX6SL_PAD_KEY_ROW5__USB_OTG2_OC 0x17059
  11693. - >;
  11694. - };
  11695. -
  11696. - pinctrl_usbotg2_4: usbotg2grp-4 {
  11697. - fsl,pins = <
  11698. - MX6SL_PAD_SD3_DAT2__USB_OTG2_OC 0x17059
  11699. + MX6SL_PAD_LCD_CLK__LCD_CLK 0x1b0b0
  11700. + MX6SL_PAD_LCD_ENABLE__LCD_ENABLE 0x1b0b0
  11701. + MX6SL_PAD_LCD_HSYNC__LCD_HSYNC 0x1b0b0
  11702. + MX6SL_PAD_LCD_VSYNC__LCD_VSYNC 0x1b0b0
  11703. + MX6SL_PAD_LCD_RESET__LCD_RESET 0x1b0b0
  11704. >;
  11705. };
  11706. };
  11707. - usdhc1 {
  11708. - pinctrl_usdhc1_1: usdhc1grp-1 {
  11709. + pwm1 {
  11710. + pinctrl_pwm1_0: pwm1grp-0 {
  11711. fsl,pins = <
  11712. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
  11713. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
  11714. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  11715. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  11716. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  11717. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  11718. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
  11719. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
  11720. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
  11721. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
  11722. + MX6SL_PAD_PWM1__PWM1_OUT 0x110b0
  11723. >;
  11724. };
  11725. -
  11726. - pinctrl_usdhc1_1_100mhz: usdhc1grp-1-100mhz {
  11727. - fsl,pins = <
  11728. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
  11729. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
  11730. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
  11731. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
  11732. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
  11733. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
  11734. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
  11735. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
  11736. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
  11737. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
  11738. - >;
  11739. - };
  11740. -
  11741. - pinctrl_usdhc1_1_200mhz: usdhc1grp-1-200mhz {
  11742. - fsl,pins = <
  11743. - MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
  11744. - MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
  11745. - MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
  11746. - MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
  11747. - MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
  11748. - MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
  11749. - MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
  11750. - MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
  11751. - MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
  11752. - MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
  11753. - >;
  11754. - };
  11755. -
  11756. -
  11757. };
  11758. + };
  11759. - usdhc2 {
  11760. - pinctrl_usdhc2_1: usdhc2grp-1 {
  11761. - fsl,pins = <
  11762. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059
  11763. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x10059
  11764. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  11765. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  11766. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  11767. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  11768. - >;
  11769. - };
  11770. -
  11771. - pinctrl_usdhc2_1_100mhz: usdhc2grp-1-100mhz {
  11772. - fsl,pins = <
  11773. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9
  11774. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9
  11775. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  11776. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  11777. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  11778. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
  11779. - >;
  11780. - };
  11781. + epit1: epit@020d0000 {
  11782. + reg = <0x020d0000 0x4000>;
  11783. + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
  11784. + };
  11785. - pinctrl_usdhc2_1_200mhz: usdhc2grp-1-200mhz {
  11786. - fsl,pins = <
  11787. - MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9
  11788. - MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9
  11789. - MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  11790. - MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  11791. - MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  11792. - MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
  11793. - >;
  11794. - };
  11795. + epit2: epit@020d4000 {
  11796. + reg = <0x020d4000 0x4000>;
  11797. + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
  11798. + };
  11799. - };
  11800. + src: src@020d8000 {
  11801. + compatible = "fsl,imx6sl-src", "fsl,imx51-src";
  11802. + reg = <0x020d8000 0x4000>;
  11803. + interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>,
  11804. + <0 96 IRQ_TYPE_LEVEL_HIGH>;
  11805. + #reset-cells = <1>;
  11806. + };
  11807. - usdhc3 {
  11808. - pinctrl_usdhc3_1: usdhc3grp-1 {
  11809. - fsl,pins = <
  11810. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
  11811. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
  11812. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  11813. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  11814. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  11815. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  11816. - >;
  11817. - };
  11818. + gpc: gpc@020dc000 {
  11819. + compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
  11820. + reg = <0x020dc000 0x4000>;
  11821. + interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
  11822. + clocks = <&clks IMX6SL_CLK_GPU2D_PODF>, <&clks IMX6SL_CLK_GPU2D_OVG>,
  11823. + <&clks IMX6SL_CLK_IPG>;
  11824. + clock-names = "gpu2d_podf", "gpu2d_ovg", "ipg";
  11825. + pu-supply = <&reg_pu>;
  11826. + };
  11827. - pinctrl_usdhc3_1_100mhz: usdhc3grp-1-100mhz {
  11828. - fsl,pins = <
  11829. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9
  11830. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9
  11831. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  11832. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  11833. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  11834. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  11835. - >;
  11836. - };
  11837. + gpr: iomuxc-gpr@020e0000 {
  11838. + compatible = "fsl,imx6sl-iomuxc-gpr",
  11839. + "fsl,imx6q-iomuxc-gpr", "syscon";
  11840. + reg = <0x020e0000 0x38>;
  11841. + };
  11842. - pinctrl_usdhc3_1_200mhz: usdhc3grp-1-200mhz {
  11843. - fsl,pins = <
  11844. - MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9
  11845. - MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9
  11846. - MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  11847. - MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  11848. - MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  11849. - MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  11850. - >;
  11851. - };
  11852. - };
  11853. + iomuxc: iomuxc@020e0000 {
  11854. + compatible = "fsl,imx6sl-iomuxc";
  11855. + reg = <0x020e0000 0x4000>;
  11856. };
  11857. csi: csi@020e4000 {
  11858. + compatible = "fsl,imx6sl-csi";
  11859. reg = <0x020e4000 0x4000>;
  11860. - interrupts = <0 7 0x04>;
  11861. + interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
  11862. + status = "disabled";
  11863. };
  11864. spdc: spdc@020e8000 {
  11865. reg = <0x020e8000 0x4000>;
  11866. - interrupts = <0 6 0x04>;
  11867. + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
  11868. };
  11869. sdma: sdma@020ec000 {
  11870. compatible = "fsl,imx6sl-sdma", "fsl,imx35-sdma";
  11871. reg = <0x020ec000 0x4000>;
  11872. - interrupts = <0 2 0x04>;
  11873. + interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>;
  11874. clocks = <&clks IMX6SL_CLK_SDMA>,
  11875. <&clks IMX6SL_CLK_SDMA>;
  11876. clock-names = "ipg", "ahb";
  11877. @@ -781,23 +761,32 @@
  11878. };
  11879. pxp: pxp@020f0000 {
  11880. + compatible = "fsl,imx6sl-pxp-dma", "fsl,imx6dl-pxp-dma";
  11881. reg = <0x020f0000 0x4000>;
  11882. - interrupts = <0 98 0x04>;
  11883. + interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
  11884. + clocks = <&clks 111>;
  11885. + clock-names = "pxp-axi";
  11886. + status = "disabled";
  11887. };
  11888. epdc: epdc@020f4000 {
  11889. reg = <0x020f4000 0x4000>;
  11890. - interrupts = <0 97 0x04>;
  11891. + interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
  11892. };
  11893. lcdif: lcdif@020f8000 {
  11894. + compatible = "fsl,imx6sl-lcdif", "fsl,imx28-lcdif";
  11895. reg = <0x020f8000 0x4000>;
  11896. - interrupts = <0 39 0x04>;
  11897. + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
  11898. + clocks = <&clks IMX6SL_CLK_LCDIF_PIX>,
  11899. + <&clks IMX6SL_CLK_LCDIF_AXI>;
  11900. + clock-names = "pix", "axi";
  11901. + status = "disabled";
  11902. };
  11903. dcp: dcp@020fc000 {
  11904. reg = <0x020fc000 0x4000>;
  11905. - interrupts = <0 99 0x04>;
  11906. + interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
  11907. };
  11908. };
  11909. @@ -811,7 +800,7 @@
  11910. usbotg1: usb@02184000 {
  11911. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11912. reg = <0x02184000 0x200>;
  11913. - interrupts = <0 43 0x04>;
  11914. + interrupts = <0 43 IRQ_TYPE_LEVEL_HIGH>;
  11915. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11916. fsl,usbphy = <&usbphy1>;
  11917. fsl,usbmisc = <&usbmisc 0>;
  11918. @@ -821,7 +810,7 @@
  11919. usbotg2: usb@02184200 {
  11920. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11921. reg = <0x02184200 0x200>;
  11922. - interrupts = <0 42 0x04>;
  11923. + interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>;
  11924. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11925. fsl,usbphy = <&usbphy2>;
  11926. fsl,usbmisc = <&usbmisc 1>;
  11927. @@ -831,9 +820,12 @@
  11928. usbh: usb@02184400 {
  11929. compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
  11930. reg = <0x02184400 0x200>;
  11931. - interrupts = <0 40 0x04>;
  11932. + interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
  11933. clocks = <&clks IMX6SL_CLK_USBOH3>;
  11934. fsl,usbmisc = <&usbmisc 2>;
  11935. + phy_type = "hsic";
  11936. + fsl,usbphy = <&usbphy_nop1>;
  11937. + fsl,anatop = <&anatop>;
  11938. status = "disabled";
  11939. };
  11940. @@ -847,7 +839,7 @@
  11941. fec: ethernet@02188000 {
  11942. compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
  11943. reg = <0x02188000 0x4000>;
  11944. - interrupts = <0 114 0x04>;
  11945. + interrupts = <0 114 IRQ_TYPE_LEVEL_HIGH>;
  11946. clocks = <&clks IMX6SL_CLK_ENET_REF>,
  11947. <&clks IMX6SL_CLK_ENET_REF>;
  11948. clock-names = "ipg", "ahb";
  11949. @@ -857,7 +849,7 @@
  11950. usdhc1: usdhc@02190000 {
  11951. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11952. reg = <0x02190000 0x4000>;
  11953. - interrupts = <0 22 0x04>;
  11954. + interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
  11955. clocks = <&clks IMX6SL_CLK_USDHC1>,
  11956. <&clks IMX6SL_CLK_USDHC1>,
  11957. <&clks IMX6SL_CLK_USDHC1>;
  11958. @@ -869,7 +861,7 @@
  11959. usdhc2: usdhc@02194000 {
  11960. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11961. reg = <0x02194000 0x4000>;
  11962. - interrupts = <0 23 0x04>;
  11963. + interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
  11964. clocks = <&clks IMX6SL_CLK_USDHC2>,
  11965. <&clks IMX6SL_CLK_USDHC2>,
  11966. <&clks IMX6SL_CLK_USDHC2>;
  11967. @@ -881,7 +873,7 @@
  11968. usdhc3: usdhc@02198000 {
  11969. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11970. reg = <0x02198000 0x4000>;
  11971. - interrupts = <0 24 0x04>;
  11972. + interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
  11973. clocks = <&clks IMX6SL_CLK_USDHC3>,
  11974. <&clks IMX6SL_CLK_USDHC3>,
  11975. <&clks IMX6SL_CLK_USDHC3>;
  11976. @@ -893,7 +885,7 @@
  11977. usdhc4: usdhc@0219c000 {
  11978. compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
  11979. reg = <0x0219c000 0x4000>;
  11980. - interrupts = <0 25 0x04>;
  11981. + interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
  11982. clocks = <&clks IMX6SL_CLK_USDHC4>,
  11983. <&clks IMX6SL_CLK_USDHC4>,
  11984. <&clks IMX6SL_CLK_USDHC4>;
  11985. @@ -907,7 +899,7 @@
  11986. #size-cells = <0>;
  11987. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  11988. reg = <0x021a0000 0x4000>;
  11989. - interrupts = <0 36 0x04>;
  11990. + interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
  11991. clocks = <&clks IMX6SL_CLK_I2C1>;
  11992. status = "disabled";
  11993. };
  11994. @@ -917,7 +909,7 @@
  11995. #size-cells = <0>;
  11996. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  11997. reg = <0x021a4000 0x4000>;
  11998. - interrupts = <0 37 0x04>;
  11999. + interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
  12000. clocks = <&clks IMX6SL_CLK_I2C2>;
  12001. status = "disabled";
  12002. };
  12003. @@ -927,7 +919,7 @@
  12004. #size-cells = <0>;
  12005. compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
  12006. reg = <0x021a8000 0x4000>;
  12007. - interrupts = <0 38 0x04>;
  12008. + interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
  12009. clocks = <&clks IMX6SL_CLK_I2C3>;
  12010. status = "disabled";
  12011. };
  12012. @@ -939,17 +931,23 @@
  12013. rngb: rngb@021b4000 {
  12014. reg = <0x021b4000 0x4000>;
  12015. - interrupts = <0 5 0x04>;
  12016. + interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
  12017. };
  12018. weim: weim@021b8000 {
  12019. reg = <0x021b8000 0x4000>;
  12020. - interrupts = <0 14 0x04>;
  12021. + interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
  12022. + };
  12023. +
  12024. + ocotp: ocotp-ctrl@021bc000 {
  12025. + compatible = "syscon";
  12026. + reg = <0x021bc000 0x4000>;
  12027. };
  12028. - ocotp: ocotp@021bc000 {
  12029. - compatible = "fsl,imx6sl-ocotp";
  12030. + ocotp-fuse@021bc000 {
  12031. + compatible = "fsl,imx6sl-ocotp", "fsl,imx6q-ocotp";
  12032. reg = <0x021bc000 0x4000>;
  12033. + clocks = <&clks IMX6SL_CLK_OCOTP>;
  12034. };
  12035. audmux: audmux@021d8000 {
  12036. @@ -957,6 +955,25 @@
  12037. reg = <0x021d8000 0x4000>;
  12038. status = "disabled";
  12039. };
  12040. +
  12041. + gpu: gpu@02200000 {
  12042. + compatible = "fsl,imx6sl-gpu", "fsl,imx6q-gpu";
  12043. + reg = <0x02200000 0x4000>, <0x02204000 0x4000>,
  12044. + <0x80000000 0x0>;
  12045. + reg-names = "iobase_2d", "iobase_vg",
  12046. + "phys_baseaddr";
  12047. + interrupts = <0 10 0x04>, <0 11 0x04>;
  12048. + interrupt-names = "irq_2d", "irq_vg";
  12049. + clocks = <&clks IMX6SL_CLK_MMDC_ROOT>,
  12050. + <&clks IMX6SL_CLK_MMDC_ROOT>,
  12051. + <&clks IMX6SL_CLK_GPU2D_OVG>;
  12052. + clock-names = "gpu2d_axi_clk", "openvg_axi_clk",
  12053. + "gpu2d_clk";
  12054. + resets = <&src 3>, <&src 3>;
  12055. + reset-names = "gpu2d", "gpuvg";
  12056. + pu-supply = <&reg_pu>;
  12057. + };
  12058. +
  12059. };
  12060. };
  12061. };
  12062. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6sl-evk-csi.dts linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk-csi.dts
  12063. --- linux-3.14.17/arch/arm/boot/dts/imx6sl-evk-csi.dts 1970-01-01 01:00:00.000000000 +0100
  12064. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk-csi.dts 2014-09-11 18:05:52.646000583 +0200
  12065. @@ -0,0 +1,27 @@
  12066. +/*
  12067. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  12068. + *
  12069. + * This program is free software; you can redistribute it and/or modify
  12070. + * it under the terms of the GNU General Public License version 2 as
  12071. + * published by the Free Software Foundation.
  12072. + */
  12073. +
  12074. +#include "imx6sl-evk.dts"
  12075. +
  12076. +/ {
  12077. + csi_v4l2_cap {
  12078. + status = "okay";
  12079. + };
  12080. +};
  12081. +
  12082. +&csi {
  12083. + status = "okay";
  12084. +};
  12085. +
  12086. +&i2c3 {
  12087. + status = "okay";
  12088. +};
  12089. +
  12090. +&epdc {
  12091. + status = "disabled";
  12092. +};
  12093. diff -Nur linux-3.14.17/arch/arm/boot/dts/imx6sl-evk.dts linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk.dts
  12094. --- linux-3.14.17/arch/arm/boot/dts/imx6sl-evk.dts 2014-08-14 03:38:34.000000000 +0200
  12095. +++ linux-imx6-3.14/arch/arm/boot/dts/imx6sl-evk.dts 2014-09-11 18:05:52.646000583 +0200
  12096. @@ -8,6 +8,8 @@
  12097. /dts-v1/;
  12098. +#include <dt-bindings/gpio/gpio.h>
  12099. +#include <dt-bindings/input/input.h>
  12100. #include "imx6sl.dtsi"
  12101. / {
  12102. @@ -18,11 +20,26 @@
  12103. reg = <0x80000000 0x40000000>;
  12104. };
  12105. + leds {
  12106. + compatible = "gpio-leds";
  12107. + pinctrl-names = "default";
  12108. + pinctrl-0 = <&pinctrl_led>;
  12109. +
  12110. + user {
  12111. + label = "debug";
  12112. + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
  12113. + linux,default-trigger = "heartbeat";
  12114. + };
  12115. + };
  12116. +
  12117. regulators {
  12118. compatible = "simple-bus";
  12119. + #address-cells = <1>;
  12120. + #size-cells = <0>;
  12121. - reg_usb_otg1_vbus: usb_otg1_vbus {
  12122. + reg_usb_otg1_vbus: regulator@0 {
  12123. compatible = "regulator-fixed";
  12124. + reg = <0>;
  12125. regulator-name = "usb_otg1_vbus";
  12126. regulator-min-microvolt = <5000000>;
  12127. regulator-max-microvolt = <5000000>;
  12128. @@ -30,22 +47,63 @@
  12129. enable-active-high;
  12130. };
  12131. - reg_usb_otg2_vbus: usb_otg2_vbus {
  12132. + reg_usb_otg2_vbus: regulator@1 {
  12133. compatible = "regulator-fixed";
  12134. + reg = <1>;
  12135. regulator-name = "usb_otg2_vbus";
  12136. regulator-min-microvolt = <5000000>;
  12137. regulator-max-microvolt = <5000000>;
  12138. gpio = <&gpio4 2 0>;
  12139. enable-active-high;
  12140. };
  12141. +
  12142. + reg_aud3v: regulator@2 {
  12143. + compatible = "regulator-fixed";
  12144. + reg = <2>;
  12145. + regulator-name = "wm8962-supply-3v15";
  12146. + regulator-min-microvolt = <3150000>;
  12147. + regulator-max-microvolt = <3150000>;
  12148. + regulator-boot-on;
  12149. + };
  12150. +
  12151. + reg_aud4v: regulator@3 {
  12152. + compatible = "regulator-fixed";
  12153. + reg = <3>;
  12154. + regulator-name = "wm8962-supply-4v2";
  12155. + regulator-min-microvolt = <4325000>;
  12156. + regulator-max-microvolt = <4325000>;
  12157. + regulator-boot-on;
  12158. + };
  12159. };
  12160. +
  12161. + sound {
  12162. + compatible = "fsl,imx6sl-evk-wm8962", "fsl,imx-audio-wm8962";
  12163. + model = "wm8962-audio";
  12164. + ssi-controller = <&ssi2>;
  12165. + audio-codec = <&codec>;
  12166. + audio-routing =
  12167. + "Headphone Jack", "HPOUTL",
  12168. + "Headphone Jack", "HPOUTR",
  12169. + "Ext Spk", "SPKOUTL",
  12170. + "Ext Spk", "SPKOUTR",
  12171. + "AMIC", "MICBIAS",
  12172. + "IN3R", "AMIC";
  12173. + mux-int-port = <2>;
  12174. + mux-ext-port = <3>;
  12175. + };
  12176. +};
  12177. +
  12178. +&audmux {
  12179. + pinctrl-names = "default";
  12180. + pinctrl-0 = <&pinctrl_audmux3>;
  12181. + status = "okay";
  12182. };
  12183. &ecspi1 {
  12184. fsl,spi-num-chipselects = <1>;
  12185. cs-gpios = <&gpio4 11 0>;
  12186. pinctrl-names = "default";
  12187. - pinctrl-0 = <&pinctrl_ecspi1_1>;
  12188. + pinctrl-0 = <&pinctrl_ecspi1>;
  12189. status = "okay";
  12190. flash: m25p80@0 {
  12191. @@ -57,18 +115,326 @@
  12192. };
  12193. };
  12194. +&csi {
  12195. + status = "okay";
  12196. +};
  12197. +
  12198. +&cpu0 {
  12199. + arm-supply = <&sw1a_reg>;
  12200. + soc-supply = <&sw1c_reg>;
  12201. + pu-supply = <&pu_dummy>; /* use pu_dummy if VDDSOC share with VDDPU */
  12202. +};
  12203. +
  12204. &fec {
  12205. pinctrl-names = "default";
  12206. - pinctrl-0 = <&pinctrl_fec_1>;
  12207. + pinctrl-0 = <&pinctrl_fec>;
  12208. phy-mode = "rmii";
  12209. status = "okay";
  12210. };
  12211. +&i2c1 {
  12212. + clock-frequency = <100000>;
  12213. + pinctrl-names = "default";
  12214. + pinctrl-0 = <&pinctrl_i2c1>;
  12215. + status = "okay";
  12216. +
  12217. + pmic: pfuze100@08 {
  12218. + compatible = "fsl,pfuze100";
  12219. + reg = <0x08>;
  12220. +
  12221. + regulators {
  12222. + sw1a_reg: sw1ab {
  12223. + regulator-min-microvolt = <300000>;
  12224. + regulator-max-microvolt = <1875000>;
  12225. + regulator-boot-on;
  12226. + regulator-always-on;
  12227. + regulator-ramp-delay = <6250>;
  12228. + };
  12229. +
  12230. + sw1c_reg: sw1c {
  12231. + regulator-min-microvolt = <300000>;
  12232. + regulator-max-microvolt = <1875000>;
  12233. + regulator-boot-on;
  12234. + regulator-always-on;
  12235. + regulator-ramp-delay = <6250>;
  12236. + };
  12237. +
  12238. + sw2_reg: sw2 {
  12239. + regulator-min-microvolt = <800000>;
  12240. + regulator-max-microvolt = <3300000>;
  12241. + regulator-boot-on;
  12242. + regulator-always-on;
  12243. + };
  12244. +
  12245. + sw3a_reg: sw3a {
  12246. + regulator-min-microvolt = <400000>;
  12247. + regulator-max-microvolt = <1975000>;
  12248. + regulator-boot-on;
  12249. + regulator-always-on;
  12250. + };
  12251. +
  12252. + sw3b_reg: sw3b {
  12253. + regulator-min-microvolt = <400000>;
  12254. + regulator-max-microvolt = <1975000>;
  12255. + regulator-boot-on;
  12256. + regulator-always-on;
  12257. + };
  12258. +
  12259. + sw4_reg: sw4 {
  12260. + regulator-min-microvolt = <800000>;
  12261. + regulator-max-microvolt = <3300000>;
  12262. + };
  12263. +
  12264. + swbst_reg: swbst {
  12265. + regulator-min-microvolt = <5000000>;
  12266. + regulator-max-microvolt = <5150000>;
  12267. + };
  12268. +
  12269. + snvs_reg: vsnvs {
  12270. + regulator-min-microvolt = <1000000>;
  12271. + regulator-max-microvolt = <3000000>;
  12272. + regulator-boot-on;
  12273. + regulator-always-on;
  12274. + };
  12275. +
  12276. + vref_reg: vrefddr {
  12277. + regulator-boot-on;
  12278. + regulator-always-on;
  12279. + };
  12280. +
  12281. + vgen1_reg: vgen1 {
  12282. + regulator-min-microvolt = <800000>;
  12283. + regulator-max-microvolt = <1550000>;
  12284. + regulator-always-on;
  12285. + };
  12286. +
  12287. + vgen2_reg: vgen2 {
  12288. + regulator-min-microvolt = <800000>;
  12289. + regulator-max-microvolt = <1550000>;
  12290. + };
  12291. +
  12292. + vgen3_reg: vgen3 {
  12293. + regulator-min-microvolt = <1800000>;
  12294. + regulator-max-microvolt = <3300000>;
  12295. + };
  12296. +
  12297. + vgen4_reg: vgen4 {
  12298. + regulator-min-microvolt = <1800000>;
  12299. + regulator-max-microvolt = <3300000>;
  12300. + regulator-always-on;
  12301. + };
  12302. +
  12303. + vgen5_reg: vgen5 {
  12304. + regulator-min-microvolt = <1800000>;
  12305. + regulator-max-microvolt = <3300000>;
  12306. + regulator-always-on;
  12307. + };
  12308. +
  12309. + vgen6_reg: vgen6 {
  12310. + regulator-min-microvolt = <1800000>;
  12311. + regulator-max-microvolt = <3300000>;
  12312. + regulator-always-on;
  12313. + };
  12314. + };
  12315. + };
  12316. +
  12317. + regulators {
  12318. + compatible = "simple-bus";
  12319. +
  12320. + reg_lcd_3v3: lcd-3v3 {
  12321. + compatible = "regulator-fixed";
  12322. + regulator-name = "lcd-3v3";
  12323. + gpio = <&gpio4 3 0>;
  12324. + enable-active-high;
  12325. + };
  12326. + };
  12327. +
  12328. + backlight {
  12329. + compatible = "pwm-backlight";
  12330. + pwms = <&pwm1 0 5000000>;
  12331. + brightness-levels = <0 4 8 16 32 64 128 255>;
  12332. + default-brightness-level = <6>;
  12333. + };
  12334. +
  12335. + csi_v4l2_cap {
  12336. + compatible = "fsl,imx6sl-csi-v4l2";
  12337. + status = "okay";
  12338. + };
  12339. +
  12340. + pxp_v4l2_out {
  12341. + compatible = "fsl,imx6sl-pxp-v4l2";
  12342. + status = "okay";
  12343. + };
  12344. +};
  12345. +
  12346. +&i2c2 {
  12347. + clock-frequency = <100000>;
  12348. + pinctrl-names = "default";
  12349. + pinctrl-0 = <&pinctrl_i2c2>;
  12350. + status = "okay";
  12351. +
  12352. + codec: wm8962@1a {
  12353. + compatible = "wlf,wm8962";
  12354. + reg = <0x1a>;
  12355. + clocks = <&clks IMX6SL_CLK_EXTERN_AUDIO>;
  12356. + DCVDD-supply = <&vgen3_reg>;
  12357. + DBVDD-supply = <&reg_aud3v>;
  12358. + AVDD-supply = <&vgen3_reg>;
  12359. + CPVDD-supply = <&vgen3_reg>;
  12360. + MICVDD-supply = <&reg_aud3v>;
  12361. + PLLVDD-supply = <&vgen3_reg>;
  12362. + SPKVDD1-supply = <&reg_aud4v>;
  12363. + SPKVDD2-supply = <&reg_aud4v>;
  12364. + };
  12365. +};
  12366. +
  12367. +&i2c1 {
  12368. + clock-frequency = <100000>;
  12369. + pinctrl-names = "default";
  12370. + pinctrl-0 = <&pinctrl_i2c1_1>;
  12371. + status = "okay";
  12372. +
  12373. + pmic: pfuze100@08 {
  12374. + compatible = "fsl,pfuze100";
  12375. + reg = <0x08>;
  12376. +
  12377. + regulators {
  12378. + sw1a_reg: sw1ab {
  12379. + regulator-min-microvolt = <300000>;
  12380. + regulator-max-microvolt = <1875000>;
  12381. + regulator-boot-on;
  12382. + regulator-always-on;
  12383. + regulator-ramp-delay = <6250>;
  12384. + };
  12385. +
  12386. + sw1c_reg: sw1c {
  12387. + regulator-min-microvolt = <300000>;
  12388. + regulator-max-microvolt = <1875000>;
  12389. + regulator-boot-on;
  12390. + regulator-always-on;
  12391. + regulator-ramp-delay = <6250>;
  12392. + };
  12393. +
  12394. + sw2_reg: sw2 {
  12395. + regulator-min-microvolt = <800000>;
  12396. + regulator-max-microvolt = <3300000>;
  12397. + regulator-boot-on;
  12398. + regulator-always-on;
  12399. + };
  12400. +
  12401. + sw3a_reg: sw3a {
  12402. + regulator-min-microvolt = <400000>;
  12403. + regulator-max-microvolt = <1975000>;
  12404. + regulator-boot-on;
  12405. + regulator-always-on;
  12406. + };
  12407. +
  12408. + sw3b_reg: sw3b {
  12409. + regulator-min-microvolt = <400000>;
  12410. + regulator-max-microvolt = <1975000>;
  12411. + regulator-boot-on;
  12412. + regulator-always-on;
  12413. + };
  12414. +
  12415. + sw4_reg: sw4 {
  12416. + regulator-min-microvolt = <800000>;
  12417. + regulator-max-microvolt = <3300000>;
  12418. + };
  12419. +
  12420. + swbst_reg: swbst {
  12421. + regulator-min-microvolt = <5000000>;
  12422. + regulator-max-microvolt = <5150000>;
  12423. + };
  12424. +
  12425. + snvs_reg: vsnvs {
  12426. + regulator-min-microvolt = <1000000>;
  12427. + regulator-max-microvolt = <3000000>;
  12428. + regulator-boot-on;
  12429. + regulator-always-on;
  12430. + };
  12431. +
  12432. + vref_reg: vrefddr {
  12433. + regulator-boot-on;
  12434. + regulator-always-on;
  12435. + };
  12436. +
  12437. + vgen1_reg: vgen1 {
  12438. + regulator-min-microvolt = <800000>;
  12439. + regulator-max-microvolt = <1550000>;
  12440. + };
  12441. +
  12442. + vgen2_reg: vgen2 {
  12443. + regulator-min-microvolt = <800000>;
  12444. + regulator-max-microvolt = <1550000>;
  12445. + };
  12446. +
  12447. + vgen3_reg: vgen3 {
  12448. + regulator-min-microvolt = <1800000>;
  12449. + regulator-max-microvolt = <3300000>;
  12450. + regulator-always-on;
  12451. + };
  12452. +
  12453. + vgen4_reg: vgen4 {
  12454. + regulator-min-microvolt = <1800000>;
  12455. + regulator-max-microvolt = <3300000>;
  12456. + regulator-always-on;
  12457. + };
  12458. +
  12459. + vgen5_reg: vgen5 {
  12460. + regulator-min-microvolt = <1800000>;
  12461. + regulator-max-microvolt = <3300000>;
  12462. + regulator-always-on;
  12463. + };
  12464. +
  12465. + vgen6_reg: vgen6 {
  12466. + regulator-min-microvolt = <1800000>;
  12467. + regulator-max-microvolt = <3300000>;
  12468. + regulator-always-on;
  12469. + };
  12470. + };
  12471. + };
  12472. +
  12473. + mma8450@1c {
  12474. + compatible = "fsl,mma8450";
  12475. + reg = <0x1c>;
  12476. + };
  12477. +};
  12478. +
  12479. +&i2c2 {
  12480. + clock-frequency = <100000>;
  12481. + pinctrl-names = "default";
  12482. + pinctrl-0 = <&pinctrl_i2c2_1>;
  12483. + status = "okay";
  12484. +};
  12485. +
  12486. +&i2c3 {
  12487. + clock-frequency = <100000>;
  12488. + pinctrl-names = "default";
  12489. + pinctrl-0 = <&pinctrl_i2c3_1>;
  12490. + status = "okay";
  12491. +
  12492. + ov564x: ov564x@3c {
  12493. + compatible = "ovti,ov564x";
  12494. + reg = <0x3c>;
  12495. + pinctrl-names = "default";
  12496. + pinctrl-0 = <&pinctrl_csi_0>;
  12497. + clocks = <&clks IMX6SL_CLK_CSI>;
  12498. + clock-names = "csi_mclk";
  12499. + AVDD-supply = <&vgen6_reg>; /* 2.8v */
  12500. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  12501. + pwn-gpios = <&gpio1 25 1>;
  12502. + rst-gpios = <&gpio1 26 0>;
  12503. + csi_id = <0>;
  12504. + mclk = <24000000>;
  12505. + mclk_source = <0>;
  12506. + };
  12507. +};
  12508. +
  12509. &iomuxc {
  12510. pinctrl-names = "default";
  12511. pinctrl-0 = <&pinctrl_hog>;
  12512. - hog {
  12513. + imx6sl-evk {
  12514. pinctrl_hog: hoggrp {
  12515. fsl,pins = <
  12516. MX6SL_PAD_KEY_ROW7__GPIO4_IO07 0x17059
  12517. @@ -78,21 +444,270 @@
  12518. MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059
  12519. MX6SL_PAD_KEY_COL4__GPIO4_IO00 0x80000000
  12520. MX6SL_PAD_KEY_COL5__GPIO4_IO02 0x80000000
  12521. + MX6SL_PAD_AUD_MCLK__AUDIO_CLK_OUT 0x4130b0
  12522. + >;
  12523. + };
  12524. +
  12525. + pinctrl_audmux3: audmux3grp {
  12526. + fsl,pins = <
  12527. + MX6SL_PAD_AUD_RXD__AUD3_RXD 0x4130b0
  12528. + MX6SL_PAD_AUD_TXC__AUD3_TXC 0x4130b0
  12529. + MX6SL_PAD_AUD_TXD__AUD3_TXD 0x4110b0
  12530. + MX6SL_PAD_AUD_TXFS__AUD3_TXFS 0x4130b0
  12531. + >;
  12532. + };
  12533. +
  12534. + pinctrl_ecspi1: ecspi1grp {
  12535. + fsl,pins = <
  12536. + MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1
  12537. + MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1
  12538. + MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
  12539. + MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x80000000
  12540. + >;
  12541. + };
  12542. +
  12543. + pinctrl_fec: fecgrp {
  12544. + fsl,pins = <
  12545. + MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0
  12546. + MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0
  12547. + MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV 0x1b0b0
  12548. + MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0 0x1b0b0
  12549. + MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1 0x1b0b0
  12550. + MX6SL_PAD_FEC_TX_EN__FEC_TX_EN 0x1b0b0
  12551. + MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0 0x1b0b0
  12552. + MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1 0x1b0b0
  12553. + MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
  12554. + >;
  12555. + };
  12556. +
  12557. + pinctrl_i2c1: i2c1grp {
  12558. + fsl,pins = <
  12559. + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1
  12560. + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
  12561. + >;
  12562. + };
  12563. +
  12564. +
  12565. + pinctrl_i2c2: i2c2grp {
  12566. + fsl,pins = <
  12567. + MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1
  12568. + MX6SL_PAD_I2C2_SDA__I2C2_SDA 0x4001b8b1
  12569. + >;
  12570. + };
  12571. +
  12572. + pinctrl_led: ledgrp {
  12573. + fsl,pins = <
  12574. + MX6SL_PAD_HSIC_STROBE__GPIO3_IO20 0x17059
  12575. + >;
  12576. + };
  12577. +
  12578. + pinctrl_kpp: kppgrp {
  12579. + fsl,pins = <
  12580. + MX6SL_PAD_KEY_ROW0__KEY_ROW0 0x1b010
  12581. + MX6SL_PAD_KEY_ROW1__KEY_ROW1 0x1b010
  12582. + MX6SL_PAD_KEY_ROW2__KEY_ROW2 0x1b0b0
  12583. + MX6SL_PAD_KEY_COL0__KEY_COL0 0x110b0
  12584. + MX6SL_PAD_KEY_COL1__KEY_COL1 0x110b0
  12585. + MX6SL_PAD_KEY_COL2__KEY_COL2 0x110b0
  12586. + >;
  12587. + };
  12588. +
  12589. + pinctrl_uart1: uart1grp {
  12590. + fsl,pins = <
  12591. + MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
  12592. + MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
  12593. + >;
  12594. + };
  12595. +
  12596. + pinctrl_usbotg1: usbotg1grp {
  12597. + fsl,pins = <
  12598. + MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
  12599. + >;
  12600. + };
  12601. +
  12602. + pinctrl_usdhc1: usdhc1grp {
  12603. + fsl,pins = <
  12604. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x17059
  12605. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x10059
  12606. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
  12607. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
  12608. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
  12609. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
  12610. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
  12611. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
  12612. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
  12613. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
  12614. + >;
  12615. + };
  12616. +
  12617. + pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
  12618. + fsl,pins = <
  12619. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170b9
  12620. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100b9
  12621. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170b9
  12622. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170b9
  12623. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170b9
  12624. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170b9
  12625. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170b9
  12626. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170b9
  12627. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170b9
  12628. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170b9
  12629. + >;
  12630. + };
  12631. +
  12632. + pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
  12633. + fsl,pins = <
  12634. + MX6SL_PAD_SD1_CMD__SD1_CMD 0x170f9
  12635. + MX6SL_PAD_SD1_CLK__SD1_CLK 0x100f9
  12636. + MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
  12637. + MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
  12638. + MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
  12639. + MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
  12640. + MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x170f9
  12641. + MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x170f9
  12642. + MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x170f9
  12643. + MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x170f9
  12644. + >;
  12645. + };
  12646. +
  12647. + pinctrl_usdhc2: usdhc2grp {
  12648. + fsl,pins = <
  12649. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x17059
  12650. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x10059
  12651. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
  12652. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
  12653. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
  12654. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
  12655. + >;
  12656. + };
  12657. +
  12658. + pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
  12659. + fsl,pins = <
  12660. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170b9
  12661. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100b9
  12662. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170b9
  12663. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170b9
  12664. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170b9
  12665. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170b9
  12666. + >;
  12667. + };
  12668. +
  12669. + pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
  12670. + fsl,pins = <
  12671. + MX6SL_PAD_SD2_CMD__SD2_CMD 0x170f9
  12672. + MX6SL_PAD_SD2_CLK__SD2_CLK 0x100f9
  12673. + MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x170f9
  12674. + MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x170f9
  12675. + MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x170f9
  12676. + MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x170f9
  12677. + >;
  12678. + };
  12679. +
  12680. + pinctrl_usdhc3: usdhc3grp {
  12681. + fsl,pins = <
  12682. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x17059
  12683. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x10059
  12684. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
  12685. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
  12686. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
  12687. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
  12688. + >;
  12689. + };
  12690. +
  12691. + pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
  12692. + fsl,pins = <
  12693. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170b9
  12694. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100b9
  12695. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
  12696. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
  12697. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
  12698. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
  12699. + >;
  12700. + };
  12701. +
  12702. + pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
  12703. + fsl,pins = <
  12704. + MX6SL_PAD_SD3_CMD__SD3_CMD 0x170f9
  12705. + MX6SL_PAD_SD3_CLK__SD3_CLK 0x100f9
  12706. + MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
  12707. + MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
  12708. + MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
  12709. + MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
  12710. >;
  12711. };
  12712. };
  12713. };
  12714. +&kpp {
  12715. + pinctrl-names = "default";
  12716. + pinctrl-0 = <&pinctrl_kpp>;
  12717. + linux,keymap = <
  12718. + MATRIX_KEY(0x0, 0x0, KEY_UP) /* ROW0, COL0 */
  12719. + MATRIX_KEY(0x0, 0x1, KEY_DOWN) /* ROW0, COL1 */
  12720. + MATRIX_KEY(0x0, 0x2, KEY_ENTER) /* ROW0, COL2 */
  12721. + MATRIX_KEY(0x1, 0x0, KEY_HOME) /* ROW1, COL0 */
  12722. + MATRIX_KEY(0x1, 0x1, KEY_RIGHT) /* ROW1, COL1 */
  12723. + MATRIX_KEY(0x1, 0x2, KEY_LEFT) /* ROW1, COL2 */
  12724. + MATRIX_KEY(0x2, 0x0, KEY_VOLUMEDOWN) /* ROW2, COL0 */
  12725. + MATRIX_KEY(0x2, 0x1, KEY_VOLUMEUP) /* ROW2, COL1 */
  12726. + >;
  12727. + status = "okay";
  12728. +};
  12729. +
  12730. +&ssi2 {
  12731. + fsl,mode = "i2s-slave";
  12732. + status = "okay";
  12733. +};
  12734. +
  12735. +&lcdif {
  12736. + pinctrl-names = "default";
  12737. + pinctrl-0 = <&pinctrl_lcdif_dat_0
  12738. + &pinctrl_lcdif_ctrl_0>;
  12739. + lcd-supply = <&reg_lcd_3v3>;
  12740. + display = <&display>;
  12741. + status = "okay";
  12742. +
  12743. + display: display {
  12744. + bits-per-pixel = <16>;
  12745. + bus-width = <24>;
  12746. +
  12747. + display-timings {
  12748. + native-mode = <&timing0>;
  12749. + timing0: timing0 {
  12750. + clock-frequency = <33500000>;
  12751. + hactive = <800>;
  12752. + vactive = <480>;
  12753. + hback-porch = <89>;
  12754. + hfront-porch = <164>;
  12755. + vback-porch = <23>;
  12756. + vfront-porch = <10>;
  12757. + hsync-len = <10>;
  12758. + vsync-len = <10>;
  12759. + hsync-active = <0>;
  12760. + vsync-active = <0>;
  12761. + de-active = <1>;
  12762. + pixelclk-active = <0>;
  12763. + };
  12764. + };
  12765. + };
  12766. +};
  12767. +
  12768. +&pwm1 {
  12769. + pinctrl-names = "default";
  12770. + pinctrl-0 = <&pinctrl_pwm1_0>;
  12771. + status = "okay";
  12772. +};
  12773. +
  12774. &uart1 {
  12775. pinctrl-names = "default";
  12776. - pinctrl-0 = <&pinctrl_uart1_1>;
  12777. + pinctrl-0 = <&pinctrl_uart1>;
  12778. status = "okay";
  12779. };
  12780. &usbotg1 {
  12781. vbus-supply = <&reg_usb_otg1_vbus>;
  12782. pinctrl-names = "default";
  12783. - pinctrl-0 = <&pinctrl_usbotg1_1>;
  12784. + pinctrl-0 = <&pinctrl_usbotg1>;
  12785. disable-over-current;
  12786. status = "okay";
  12787. };
  12788. @@ -106,9 +721,9 @@
  12789. &usdhc1 {
  12790. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12791. - pinctrl-0 = <&pinctrl_usdhc1_1>;
  12792. - pinctrl-1 = <&pinctrl_usdhc1_1_100mhz>;
  12793. - pinctrl-2 = <&pinctrl_usdhc1_1_200mhz>;
  12794. + pinctrl-0 = <&pinctrl_usdhc1>;
  12795. + pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
  12796. + pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
  12797. bus-width = <8>;
  12798. cd-gpios = <&gpio4 7 0>;
  12799. wp-gpios = <&gpio4 6 0>;
  12800. @@ -117,9 +732,9 @@
  12801. &usdhc2 {
  12802. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12803. - pinctrl-0 = <&pinctrl_usdhc2_1>;
  12804. - pinctrl-1 = <&pinctrl_usdhc2_1_100mhz>;
  12805. - pinctrl-2 = <&pinctrl_usdhc2_1_200mhz>;
  12806. + pinctrl-0 = <&pinctrl_usdhc2>;
  12807. + pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
  12808. + pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
  12809. cd-gpios = <&gpio5 0 0>;
  12810. wp-gpios = <&gpio4 29 0>;
  12811. status = "okay";
  12812. @@ -127,9 +742,26 @@
  12813. &usdhc3 {
  12814. pinctrl-names = "default", "state_100mhz", "state_200mhz";
  12815. - pinctrl-0 = <&pinctrl_usdhc3_1>;
  12816. - pinctrl-1 = <&pinctrl_usdhc3_1_100mhz>;
  12817. - pinctrl-2 = <&pinctrl_usdhc3_1_200mhz>;
  12818. + pinctrl-0 = <&pinctrl_usdhc3>;
  12819. + pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
  12820. + pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
  12821. cd-gpios = <&gpio3 22 0>;
  12822. status = "okay";
  12823. };
  12824. +
  12825. +&pxp {
  12826. + status = "okay";
  12827. +};
  12828. +
  12829. +&gpc {
  12830. + fsl,cpu_pupscr_sw2iso = <0xf>;
  12831. + fsl,cpu_pupscr_sw = <0xf>;
  12832. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  12833. + fsl,cpu_pdnscr_iso = <0x1>;
  12834. + fsl,ldo-bypass; /* use ldo-bypass, u-boot will check it and configure */
  12835. + pu-supply = <&pu_dummy>; /* ldo-bypass:use pu_dummy if VDDSOC share with VDDPU */
  12836. +};
  12837. +
  12838. +&gpu {
  12839. + pu-supply = <&pu_dummy>; /* ldo-bypass:use pu_dummy if VDDSOC share with VDDPU */
  12840. +};
  12841. diff -Nur linux-3.14.17/arch/arm/boot/dts/Makefile linux-imx6-3.14/arch/arm/boot/dts/Makefile
  12842. --- linux-3.14.17/arch/arm/boot/dts/Makefile 2014-08-14 03:38:34.000000000 +0200
  12843. +++ linux-imx6-3.14/arch/arm/boot/dts/Makefile 2014-09-11 18:05:52.582000327 +0200
  12844. @@ -154,16 +154,37 @@
  12845. imx53-qsb.dtb \
  12846. imx53-smd.dtb \
  12847. imx6dl-cubox-i.dtb \
  12848. + imx6dl-dfi-fs700-m60.dtb \
  12849. + imx6dl-gw51xx.dtb \
  12850. + imx6dl-gw52xx.dtb \
  12851. + imx6dl-gw53xx.dtb \
  12852. + imx6dl-gw54xx.dtb \
  12853. imx6dl-hummingboard.dtb \
  12854. + imx6dl-nitrogen6x.dtb \
  12855. + imx6dl-phytec-pbab01.dtb \
  12856. imx6dl-sabreauto.dtb \
  12857. + imx6dl-sabrelite.dtb \
  12858. imx6dl-sabresd.dtb \
  12859. + imx6dl-sabresd-hdcp.dtb \
  12860. imx6dl-wandboard.dtb \
  12861. imx6q-arm2.dtb \
  12862. + imx6q-cm-fx6.dtb \
  12863. imx6q-cubox-i.dtb \
  12864. + imx6q-hummingboard.dtb \
  12865. + imx6q-dfi-fs700-m60.dtb \
  12866. + imx6q-dmo-edmqmx6.dtb \
  12867. + imx6q-gk802.dtb \
  12868. + imx6q-gw51xx.dtb \
  12869. + imx6q-gw52xx.dtb \
  12870. + imx6q-gw53xx.dtb \
  12871. + imx6q-gw5400-a.dtb \
  12872. + imx6q-gw54xx.dtb \
  12873. + imx6q-nitrogen6x.dtb \
  12874. imx6q-phytec-pbab01.dtb \
  12875. imx6q-sabreauto.dtb \
  12876. imx6q-sabrelite.dtb \
  12877. imx6q-sabresd.dtb \
  12878. + imx6q-sabresd-hdcp.dtb \
  12879. imx6q-sbc6x.dtb \
  12880. imx6q-udoo.dtb \
  12881. imx6q-wandboard.dtb \
  12882. @@ -312,7 +333,14 @@
  12883. dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
  12884. vexpress-v2p-ca9.dtb \
  12885. vexpress-v2p-ca15-tc1.dtb \
  12886. - vexpress-v2p-ca15_a7.dtb
  12887. + vexpress-v2p-ca15_a7.dtb \
  12888. + rtsm_ve-cortex_a9x2.dtb \
  12889. + rtsm_ve-cortex_a9x4.dtb \
  12890. + rtsm_ve-cortex_a15x1.dtb \
  12891. + rtsm_ve-cortex_a15x2.dtb \
  12892. + rtsm_ve-cortex_a15x4.dtb \
  12893. + rtsm_ve-v2p-ca15x1-ca7x1.dtb \
  12894. + rtsm_ve-v2p-ca15x4-ca7x4.dtb
  12895. dtb-$(CONFIG_ARCH_VIRT) += xenvm-4.2.dtb
  12896. dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
  12897. wm8505-ref.dtb \
  12898. diff -Nur linux-3.14.17/arch/arm/boot/dts/marco.dtsi linux-imx6-3.14/arch/arm/boot/dts/marco.dtsi
  12899. --- linux-3.14.17/arch/arm/boot/dts/marco.dtsi 2014-08-14 03:38:34.000000000 +0200
  12900. +++ linux-imx6-3.14/arch/arm/boot/dts/marco.dtsi 2014-09-11 18:05:52.662000648 +0200
  12901. @@ -36,7 +36,7 @@
  12902. ranges = <0x40000000 0x40000000 0xa0000000>;
  12903. l2-cache-controller@c0030000 {
  12904. - compatible = "sirf,marco-pl310-cache", "arm,pl310-cache";
  12905. + compatible = "arm,pl310-cache";
  12906. reg = <0xc0030000 0x1000>;
  12907. interrupts = <0 59 0>;
  12908. arm,tag-latency = <1 1 1>;
  12909. diff -Nur linux-3.14.17/arch/arm/boot/dts/prima2.dtsi linux-imx6-3.14/arch/arm/boot/dts/prima2.dtsi
  12910. --- linux-3.14.17/arch/arm/boot/dts/prima2.dtsi 2014-08-14 03:38:34.000000000 +0200
  12911. +++ linux-imx6-3.14/arch/arm/boot/dts/prima2.dtsi 2014-09-11 18:05:52.686000742 +0200
  12912. @@ -48,7 +48,7 @@
  12913. ranges = <0x40000000 0x40000000 0x80000000>;
  12914. l2-cache-controller@80040000 {
  12915. - compatible = "arm,pl310-cache", "sirf,prima2-pl310-cache";
  12916. + compatible = "arm,pl310-cache";
  12917. reg = <0x80040000 0x1000>;
  12918. interrupts = <59>;
  12919. arm,tag-latency = <1 1 1>;
  12920. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts
  12921. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts 1970-01-01 01:00:00.000000000 +0100
  12922. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x1.dts 2014-09-11 18:05:52.686000742 +0200
  12923. @@ -0,0 +1,159 @@
  12924. +/*
  12925. + * ARM Ltd. Fast Models
  12926. + *
  12927. + * Versatile Express (VE) system model
  12928. + * ARMCortexA15x1CT
  12929. + *
  12930. + * RTSM_VE_Cortex_A15x1.lisa
  12931. + */
  12932. +
  12933. +/dts-v1/;
  12934. +
  12935. +/ {
  12936. + model = "RTSM_VE_CortexA15x1";
  12937. + arm,vexpress,site = <0xf>;
  12938. + compatible = "arm,rtsm_ve,cortex_a15x1", "arm,vexpress";
  12939. + interrupt-parent = <&gic>;
  12940. + #address-cells = <2>;
  12941. + #size-cells = <2>;
  12942. +
  12943. + chosen { };
  12944. +
  12945. + aliases {
  12946. + serial0 = &v2m_serial0;
  12947. + serial1 = &v2m_serial1;
  12948. + serial2 = &v2m_serial2;
  12949. + serial3 = &v2m_serial3;
  12950. + };
  12951. +
  12952. + cpus {
  12953. + #address-cells = <1>;
  12954. + #size-cells = <0>;
  12955. +
  12956. + cpu@0 {
  12957. + device_type = "cpu";
  12958. + compatible = "arm,cortex-a15";
  12959. + reg = <0>;
  12960. + };
  12961. + };
  12962. +
  12963. + memory@80000000 {
  12964. + device_type = "memory";
  12965. + reg = <0 0x80000000 0 0x80000000>;
  12966. + };
  12967. +
  12968. + gic: interrupt-controller@2c001000 {
  12969. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  12970. + #interrupt-cells = <3>;
  12971. + #address-cells = <0>;
  12972. + interrupt-controller;
  12973. + reg = <0 0x2c001000 0 0x1000>,
  12974. + <0 0x2c002000 0 0x1000>,
  12975. + <0 0x2c004000 0 0x2000>,
  12976. + <0 0x2c006000 0 0x2000>;
  12977. + interrupts = <1 9 0xf04>;
  12978. + };
  12979. +
  12980. + timer {
  12981. + compatible = "arm,armv7-timer";
  12982. + interrupts = <1 13 0xf08>,
  12983. + <1 14 0xf08>,
  12984. + <1 11 0xf08>,
  12985. + <1 10 0xf08>;
  12986. + };
  12987. +
  12988. + dcc {
  12989. + compatible = "arm,vexpress,config-bus";
  12990. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  12991. +
  12992. + osc@0 {
  12993. + /* ACLK clock to the AXI master port on the test chip */
  12994. + compatible = "arm,vexpress-osc";
  12995. + arm,vexpress-sysreg,func = <1 0>;
  12996. + freq-range = <30000000 50000000>;
  12997. + #clock-cells = <0>;
  12998. + clock-output-names = "extsaxiclk";
  12999. + };
  13000. +
  13001. + oscclk1: osc@1 {
  13002. + /* Reference clock for the CLCD */
  13003. + compatible = "arm,vexpress-osc";
  13004. + arm,vexpress-sysreg,func = <1 1>;
  13005. + freq-range = <10000000 80000000>;
  13006. + #clock-cells = <0>;
  13007. + clock-output-names = "clcdclk";
  13008. + };
  13009. +
  13010. + smbclk: oscclk2: osc@2 {
  13011. + /* Reference clock for the test chip internal PLLs */
  13012. + compatible = "arm,vexpress-osc";
  13013. + arm,vexpress-sysreg,func = <1 2>;
  13014. + freq-range = <33000000 100000000>;
  13015. + #clock-cells = <0>;
  13016. + clock-output-names = "tcrefclk";
  13017. + };
  13018. + };
  13019. +
  13020. + smb {
  13021. + compatible = "simple-bus";
  13022. +
  13023. + #address-cells = <2>;
  13024. + #size-cells = <1>;
  13025. + ranges = <0 0 0 0x08000000 0x04000000>,
  13026. + <1 0 0 0x14000000 0x04000000>,
  13027. + <2 0 0 0x18000000 0x04000000>,
  13028. + <3 0 0 0x1c000000 0x04000000>,
  13029. + <4 0 0 0x0c000000 0x04000000>,
  13030. + <5 0 0 0x10000000 0x04000000>;
  13031. +
  13032. + #interrupt-cells = <1>;
  13033. + interrupt-map-mask = <0 0 63>;
  13034. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13035. + <0 0 1 &gic 0 1 4>,
  13036. + <0 0 2 &gic 0 2 4>,
  13037. + <0 0 3 &gic 0 3 4>,
  13038. + <0 0 4 &gic 0 4 4>,
  13039. + <0 0 5 &gic 0 5 4>,
  13040. + <0 0 6 &gic 0 6 4>,
  13041. + <0 0 7 &gic 0 7 4>,
  13042. + <0 0 8 &gic 0 8 4>,
  13043. + <0 0 9 &gic 0 9 4>,
  13044. + <0 0 10 &gic 0 10 4>,
  13045. + <0 0 11 &gic 0 11 4>,
  13046. + <0 0 12 &gic 0 12 4>,
  13047. + <0 0 13 &gic 0 13 4>,
  13048. + <0 0 14 &gic 0 14 4>,
  13049. + <0 0 15 &gic 0 15 4>,
  13050. + <0 0 16 &gic 0 16 4>,
  13051. + <0 0 17 &gic 0 17 4>,
  13052. + <0 0 18 &gic 0 18 4>,
  13053. + <0 0 19 &gic 0 19 4>,
  13054. + <0 0 20 &gic 0 20 4>,
  13055. + <0 0 21 &gic 0 21 4>,
  13056. + <0 0 22 &gic 0 22 4>,
  13057. + <0 0 23 &gic 0 23 4>,
  13058. + <0 0 24 &gic 0 24 4>,
  13059. + <0 0 25 &gic 0 25 4>,
  13060. + <0 0 26 &gic 0 26 4>,
  13061. + <0 0 27 &gic 0 27 4>,
  13062. + <0 0 28 &gic 0 28 4>,
  13063. + <0 0 29 &gic 0 29 4>,
  13064. + <0 0 30 &gic 0 30 4>,
  13065. + <0 0 31 &gic 0 31 4>,
  13066. + <0 0 32 &gic 0 32 4>,
  13067. + <0 0 33 &gic 0 33 4>,
  13068. + <0 0 34 &gic 0 34 4>,
  13069. + <0 0 35 &gic 0 35 4>,
  13070. + <0 0 36 &gic 0 36 4>,
  13071. + <0 0 37 &gic 0 37 4>,
  13072. + <0 0 38 &gic 0 38 4>,
  13073. + <0 0 39 &gic 0 39 4>,
  13074. + <0 0 40 &gic 0 40 4>,
  13075. + <0 0 41 &gic 0 41 4>,
  13076. + <0 0 42 &gic 0 42 4>;
  13077. +
  13078. + /include/ "rtsm_ve-motherboard.dtsi"
  13079. + };
  13080. +};
  13081. +
  13082. +/include/ "clcd-panels.dtsi"
  13083. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts
  13084. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts 1970-01-01 01:00:00.000000000 +0100
  13085. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x2.dts 2014-09-11 18:05:52.686000742 +0200
  13086. @@ -0,0 +1,165 @@
  13087. +/*
  13088. + * ARM Ltd. Fast Models
  13089. + *
  13090. + * Versatile Express (VE) system model
  13091. + * ARMCortexA15x2CT
  13092. + *
  13093. + * RTSM_VE_Cortex_A15x2.lisa
  13094. + */
  13095. +
  13096. +/dts-v1/;
  13097. +
  13098. +/ {
  13099. + model = "RTSM_VE_CortexA15x2";
  13100. + arm,vexpress,site = <0xf>;
  13101. + compatible = "arm,rtsm_ve,cortex_a15x2", "arm,vexpress";
  13102. + interrupt-parent = <&gic>;
  13103. + #address-cells = <2>;
  13104. + #size-cells = <2>;
  13105. +
  13106. + chosen { };
  13107. +
  13108. + aliases {
  13109. + serial0 = &v2m_serial0;
  13110. + serial1 = &v2m_serial1;
  13111. + serial2 = &v2m_serial2;
  13112. + serial3 = &v2m_serial3;
  13113. + };
  13114. +
  13115. + cpus {
  13116. + #address-cells = <1>;
  13117. + #size-cells = <0>;
  13118. +
  13119. + cpu@0 {
  13120. + device_type = "cpu";
  13121. + compatible = "arm,cortex-a15";
  13122. + reg = <0>;
  13123. + };
  13124. +
  13125. + cpu@1 {
  13126. + device_type = "cpu";
  13127. + compatible = "arm,cortex-a15";
  13128. + reg = <1>;
  13129. + };
  13130. + };
  13131. +
  13132. + memory@80000000 {
  13133. + device_type = "memory";
  13134. + reg = <0 0x80000000 0 0x80000000>;
  13135. + };
  13136. +
  13137. + gic: interrupt-controller@2c001000 {
  13138. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  13139. + #interrupt-cells = <3>;
  13140. + #address-cells = <0>;
  13141. + interrupt-controller;
  13142. + reg = <0 0x2c001000 0 0x1000>,
  13143. + <0 0x2c002000 0 0x1000>,
  13144. + <0 0x2c004000 0 0x2000>,
  13145. + <0 0x2c006000 0 0x2000>;
  13146. + interrupts = <1 9 0xf04>;
  13147. + };
  13148. +
  13149. + timer {
  13150. + compatible = "arm,armv7-timer";
  13151. + interrupts = <1 13 0xf08>,
  13152. + <1 14 0xf08>,
  13153. + <1 11 0xf08>,
  13154. + <1 10 0xf08>;
  13155. + };
  13156. +
  13157. + dcc {
  13158. + compatible = "arm,vexpress,config-bus";
  13159. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13160. +
  13161. + osc@0 {
  13162. + /* ACLK clock to the AXI master port on the test chip */
  13163. + compatible = "arm,vexpress-osc";
  13164. + arm,vexpress-sysreg,func = <1 0>;
  13165. + freq-range = <30000000 50000000>;
  13166. + #clock-cells = <0>;
  13167. + clock-output-names = "extsaxiclk";
  13168. + };
  13169. +
  13170. + oscclk1: osc@1 {
  13171. + /* Reference clock for the CLCD */
  13172. + compatible = "arm,vexpress-osc";
  13173. + arm,vexpress-sysreg,func = <1 1>;
  13174. + freq-range = <10000000 80000000>;
  13175. + #clock-cells = <0>;
  13176. + clock-output-names = "clcdclk";
  13177. + };
  13178. +
  13179. + smbclk: oscclk2: osc@2 {
  13180. + /* Reference clock for the test chip internal PLLs */
  13181. + compatible = "arm,vexpress-osc";
  13182. + arm,vexpress-sysreg,func = <1 2>;
  13183. + freq-range = <33000000 100000000>;
  13184. + #clock-cells = <0>;
  13185. + clock-output-names = "tcrefclk";
  13186. + };
  13187. + };
  13188. +
  13189. + smb {
  13190. + compatible = "simple-bus";
  13191. +
  13192. + #address-cells = <2>;
  13193. + #size-cells = <1>;
  13194. + ranges = <0 0 0 0x08000000 0x04000000>,
  13195. + <1 0 0 0x14000000 0x04000000>,
  13196. + <2 0 0 0x18000000 0x04000000>,
  13197. + <3 0 0 0x1c000000 0x04000000>,
  13198. + <4 0 0 0x0c000000 0x04000000>,
  13199. + <5 0 0 0x10000000 0x04000000>;
  13200. +
  13201. + #interrupt-cells = <1>;
  13202. + interrupt-map-mask = <0 0 63>;
  13203. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13204. + <0 0 1 &gic 0 1 4>,
  13205. + <0 0 2 &gic 0 2 4>,
  13206. + <0 0 3 &gic 0 3 4>,
  13207. + <0 0 4 &gic 0 4 4>,
  13208. + <0 0 5 &gic 0 5 4>,
  13209. + <0 0 6 &gic 0 6 4>,
  13210. + <0 0 7 &gic 0 7 4>,
  13211. + <0 0 8 &gic 0 8 4>,
  13212. + <0 0 9 &gic 0 9 4>,
  13213. + <0 0 10 &gic 0 10 4>,
  13214. + <0 0 11 &gic 0 11 4>,
  13215. + <0 0 12 &gic 0 12 4>,
  13216. + <0 0 13 &gic 0 13 4>,
  13217. + <0 0 14 &gic 0 14 4>,
  13218. + <0 0 15 &gic 0 15 4>,
  13219. + <0 0 16 &gic 0 16 4>,
  13220. + <0 0 17 &gic 0 17 4>,
  13221. + <0 0 18 &gic 0 18 4>,
  13222. + <0 0 19 &gic 0 19 4>,
  13223. + <0 0 20 &gic 0 20 4>,
  13224. + <0 0 21 &gic 0 21 4>,
  13225. + <0 0 22 &gic 0 22 4>,
  13226. + <0 0 23 &gic 0 23 4>,
  13227. + <0 0 24 &gic 0 24 4>,
  13228. + <0 0 25 &gic 0 25 4>,
  13229. + <0 0 26 &gic 0 26 4>,
  13230. + <0 0 27 &gic 0 27 4>,
  13231. + <0 0 28 &gic 0 28 4>,
  13232. + <0 0 29 &gic 0 29 4>,
  13233. + <0 0 30 &gic 0 30 4>,
  13234. + <0 0 31 &gic 0 31 4>,
  13235. + <0 0 32 &gic 0 32 4>,
  13236. + <0 0 33 &gic 0 33 4>,
  13237. + <0 0 34 &gic 0 34 4>,
  13238. + <0 0 35 &gic 0 35 4>,
  13239. + <0 0 36 &gic 0 36 4>,
  13240. + <0 0 37 &gic 0 37 4>,
  13241. + <0 0 38 &gic 0 38 4>,
  13242. + <0 0 39 &gic 0 39 4>,
  13243. + <0 0 40 &gic 0 40 4>,
  13244. + <0 0 41 &gic 0 41 4>,
  13245. + <0 0 42 &gic 0 42 4>;
  13246. +
  13247. + /include/ "rtsm_ve-motherboard.dtsi"
  13248. + };
  13249. +};
  13250. +
  13251. +/include/ "clcd-panels.dtsi"
  13252. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts
  13253. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts 1970-01-01 01:00:00.000000000 +0100
  13254. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a15x4.dts 2014-09-11 18:05:52.686000742 +0200
  13255. @@ -0,0 +1,177 @@
  13256. +/*
  13257. + * ARM Ltd. Fast Models
  13258. + *
  13259. + * Versatile Express (VE) system model
  13260. + * ARMCortexA15x4CT
  13261. + *
  13262. + * RTSM_VE_Cortex_A15x4.lisa
  13263. + */
  13264. +
  13265. +/dts-v1/;
  13266. +
  13267. +/ {
  13268. + model = "RTSM_VE_CortexA15x4";
  13269. + arm,vexpress,site = <0xf>;
  13270. + compatible = "arm,rtsm_ve,cortex_a15x4", "arm,vexpress";
  13271. + interrupt-parent = <&gic>;
  13272. + #address-cells = <2>;
  13273. + #size-cells = <2>;
  13274. +
  13275. + chosen { };
  13276. +
  13277. + aliases {
  13278. + serial0 = &v2m_serial0;
  13279. + serial1 = &v2m_serial1;
  13280. + serial2 = &v2m_serial2;
  13281. + serial3 = &v2m_serial3;
  13282. + };
  13283. +
  13284. + cpus {
  13285. + #address-cells = <1>;
  13286. + #size-cells = <0>;
  13287. +
  13288. + cpu@0 {
  13289. + device_type = "cpu";
  13290. + compatible = "arm,cortex-a15";
  13291. + reg = <0>;
  13292. + };
  13293. +
  13294. + cpu@1 {
  13295. + device_type = "cpu";
  13296. + compatible = "arm,cortex-a15";
  13297. + reg = <1>;
  13298. + };
  13299. +
  13300. + cpu@2 {
  13301. + device_type = "cpu";
  13302. + compatible = "arm,cortex-a15";
  13303. + reg = <2>;
  13304. + };
  13305. +
  13306. + cpu@3 {
  13307. + device_type = "cpu";
  13308. + compatible = "arm,cortex-a15";
  13309. + reg = <3>;
  13310. + };
  13311. + };
  13312. +
  13313. + memory@80000000 {
  13314. + device_type = "memory";
  13315. + reg = <0 0x80000000 0 0x80000000>;
  13316. + };
  13317. +
  13318. + gic: interrupt-controller@2c001000 {
  13319. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  13320. + #interrupt-cells = <3>;
  13321. + #address-cells = <0>;
  13322. + interrupt-controller;
  13323. + reg = <0 0x2c001000 0 0x1000>,
  13324. + <0 0x2c002000 0 0x1000>,
  13325. + <0 0x2c004000 0 0x2000>,
  13326. + <0 0x2c006000 0 0x2000>;
  13327. + interrupts = <1 9 0xf04>;
  13328. + };
  13329. +
  13330. + timer {
  13331. + compatible = "arm,armv7-timer";
  13332. + interrupts = <1 13 0xf08>,
  13333. + <1 14 0xf08>,
  13334. + <1 11 0xf08>,
  13335. + <1 10 0xf08>;
  13336. + };
  13337. +
  13338. + dcc {
  13339. + compatible = "arm,vexpress,config-bus";
  13340. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13341. +
  13342. + osc@0 {
  13343. + /* ACLK clock to the AXI master port on the test chip */
  13344. + compatible = "arm,vexpress-osc";
  13345. + arm,vexpress-sysreg,func = <1 0>;
  13346. + freq-range = <30000000 50000000>;
  13347. + #clock-cells = <0>;
  13348. + clock-output-names = "extsaxiclk";
  13349. + };
  13350. +
  13351. + oscclk1: osc@1 {
  13352. + /* Reference clock for the CLCD */
  13353. + compatible = "arm,vexpress-osc";
  13354. + arm,vexpress-sysreg,func = <1 1>;
  13355. + freq-range = <10000000 80000000>;
  13356. + #clock-cells = <0>;
  13357. + clock-output-names = "clcdclk";
  13358. + };
  13359. +
  13360. + smbclk: oscclk2: osc@2 {
  13361. + /* Reference clock for the test chip internal PLLs */
  13362. + compatible = "arm,vexpress-osc";
  13363. + arm,vexpress-sysreg,func = <1 2>;
  13364. + freq-range = <33000000 100000000>;
  13365. + #clock-cells = <0>;
  13366. + clock-output-names = "tcrefclk";
  13367. + };
  13368. + };
  13369. +
  13370. + smb {
  13371. + compatible = "simple-bus";
  13372. +
  13373. + #address-cells = <2>;
  13374. + #size-cells = <1>;
  13375. + ranges = <0 0 0 0x08000000 0x04000000>,
  13376. + <1 0 0 0x14000000 0x04000000>,
  13377. + <2 0 0 0x18000000 0x04000000>,
  13378. + <3 0 0 0x1c000000 0x04000000>,
  13379. + <4 0 0 0x0c000000 0x04000000>,
  13380. + <5 0 0 0x10000000 0x04000000>;
  13381. +
  13382. + #interrupt-cells = <1>;
  13383. + interrupt-map-mask = <0 0 63>;
  13384. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13385. + <0 0 1 &gic 0 1 4>,
  13386. + <0 0 2 &gic 0 2 4>,
  13387. + <0 0 3 &gic 0 3 4>,
  13388. + <0 0 4 &gic 0 4 4>,
  13389. + <0 0 5 &gic 0 5 4>,
  13390. + <0 0 6 &gic 0 6 4>,
  13391. + <0 0 7 &gic 0 7 4>,
  13392. + <0 0 8 &gic 0 8 4>,
  13393. + <0 0 9 &gic 0 9 4>,
  13394. + <0 0 10 &gic 0 10 4>,
  13395. + <0 0 11 &gic 0 11 4>,
  13396. + <0 0 12 &gic 0 12 4>,
  13397. + <0 0 13 &gic 0 13 4>,
  13398. + <0 0 14 &gic 0 14 4>,
  13399. + <0 0 15 &gic 0 15 4>,
  13400. + <0 0 16 &gic 0 16 4>,
  13401. + <0 0 17 &gic 0 17 4>,
  13402. + <0 0 18 &gic 0 18 4>,
  13403. + <0 0 19 &gic 0 19 4>,
  13404. + <0 0 20 &gic 0 20 4>,
  13405. + <0 0 21 &gic 0 21 4>,
  13406. + <0 0 22 &gic 0 22 4>,
  13407. + <0 0 23 &gic 0 23 4>,
  13408. + <0 0 24 &gic 0 24 4>,
  13409. + <0 0 25 &gic 0 25 4>,
  13410. + <0 0 26 &gic 0 26 4>,
  13411. + <0 0 27 &gic 0 27 4>,
  13412. + <0 0 28 &gic 0 28 4>,
  13413. + <0 0 29 &gic 0 29 4>,
  13414. + <0 0 30 &gic 0 30 4>,
  13415. + <0 0 31 &gic 0 31 4>,
  13416. + <0 0 32 &gic 0 32 4>,
  13417. + <0 0 33 &gic 0 33 4>,
  13418. + <0 0 34 &gic 0 34 4>,
  13419. + <0 0 35 &gic 0 35 4>,
  13420. + <0 0 36 &gic 0 36 4>,
  13421. + <0 0 37 &gic 0 37 4>,
  13422. + <0 0 38 &gic 0 38 4>,
  13423. + <0 0 39 &gic 0 39 4>,
  13424. + <0 0 40 &gic 0 40 4>,
  13425. + <0 0 41 &gic 0 41 4>,
  13426. + <0 0 42 &gic 0 42 4>;
  13427. +
  13428. + /include/ "rtsm_ve-motherboard.dtsi"
  13429. + };
  13430. +};
  13431. +
  13432. +/include/ "clcd-panels.dtsi"
  13433. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts
  13434. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts 1970-01-01 01:00:00.000000000 +0100
  13435. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x2.dts 2014-09-11 18:05:52.686000742 +0200
  13436. @@ -0,0 +1,171 @@
  13437. +/*
  13438. + * ARM Ltd. Fast Models
  13439. + *
  13440. + * Versatile Express (VE) system model
  13441. + * ARMCortexA9MPx2CT
  13442. + *
  13443. + * RTSM_VE_Cortex_A9x2.lisa
  13444. + */
  13445. +
  13446. +/dts-v1/;
  13447. +
  13448. +/ {
  13449. + model = "RTSM_VE_CortexA9x2";
  13450. + arm,vexpress,site = <0xf>;
  13451. + compatible = "arm,rtsm_ve,cortex_a9x2", "arm,vexpress";
  13452. + interrupt-parent = <&gic>;
  13453. + #address-cells = <1>;
  13454. + #size-cells = <1>;
  13455. +
  13456. + chosen { };
  13457. +
  13458. + aliases {
  13459. + serial0 = &v2m_serial0;
  13460. + serial1 = &v2m_serial1;
  13461. + serial2 = &v2m_serial2;
  13462. + serial3 = &v2m_serial3;
  13463. + };
  13464. +
  13465. + cpus {
  13466. + #address-cells = <1>;
  13467. + #size-cells = <0>;
  13468. +
  13469. + cpu@0 {
  13470. + device_type = "cpu";
  13471. + compatible = "arm,cortex-a9";
  13472. + reg = <0>;
  13473. + };
  13474. +
  13475. + cpu@1 {
  13476. + device_type = "cpu";
  13477. + compatible = "arm,cortex-a9";
  13478. + reg = <1>;
  13479. + };
  13480. + };
  13481. +
  13482. + memory@80000000 {
  13483. + device_type = "memory";
  13484. + reg = <0x80000000 0x80000000>;
  13485. + };
  13486. +
  13487. + scu@2c000000 {
  13488. + compatible = "arm,cortex-a9-scu";
  13489. + reg = <0x2c000000 0x58>;
  13490. + };
  13491. +
  13492. + timer@2c000600 {
  13493. + compatible = "arm,cortex-a9-twd-timer";
  13494. + reg = <0x2c000600 0x20>;
  13495. + interrupts = <1 13 0xf04>;
  13496. + };
  13497. +
  13498. + watchdog@2c000620 {
  13499. + compatible = "arm,cortex-a9-twd-wdt";
  13500. + reg = <0x2c000620 0x20>;
  13501. + interrupts = <1 14 0xf04>;
  13502. + };
  13503. +
  13504. + gic: interrupt-controller@2c001000 {
  13505. + compatible = "arm,cortex-a9-gic";
  13506. + #interrupt-cells = <3>;
  13507. + #address-cells = <0>;
  13508. + interrupt-controller;
  13509. + reg = <0x2c001000 0x1000>,
  13510. + <0x2c000100 0x100>;
  13511. + };
  13512. +
  13513. + dcc {
  13514. + compatible = "arm,vexpress,config-bus";
  13515. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13516. +
  13517. + osc@0 {
  13518. + /* ACLK clock to the AXI master port on the test chip */
  13519. + compatible = "arm,vexpress-osc";
  13520. + arm,vexpress-sysreg,func = <1 0>;
  13521. + freq-range = <30000000 50000000>;
  13522. + #clock-cells = <0>;
  13523. + clock-output-names = "extsaxiclk";
  13524. + };
  13525. +
  13526. + oscclk1: osc@1 {
  13527. + /* Reference clock for the CLCD */
  13528. + compatible = "arm,vexpress-osc";
  13529. + arm,vexpress-sysreg,func = <1 1>;
  13530. + freq-range = <10000000 80000000>;
  13531. + #clock-cells = <0>;
  13532. + clock-output-names = "clcdclk";
  13533. + };
  13534. +
  13535. + smbclk: oscclk2: osc@2 {
  13536. + /* Reference clock for the test chip internal PLLs */
  13537. + compatible = "arm,vexpress-osc";
  13538. + arm,vexpress-sysreg,func = <1 2>;
  13539. + freq-range = <33000000 100000000>;
  13540. + #clock-cells = <0>;
  13541. + clock-output-names = "tcrefclk";
  13542. + };
  13543. + };
  13544. +
  13545. + smb {
  13546. + compatible = "simple-bus";
  13547. +
  13548. + #address-cells = <2>;
  13549. + #size-cells = <1>;
  13550. + ranges = <0 0 0x08000000 0x04000000>,
  13551. + <1 0 0x14000000 0x04000000>,
  13552. + <2 0 0x18000000 0x04000000>,
  13553. + <3 0 0x1c000000 0x04000000>,
  13554. + <4 0 0x0c000000 0x04000000>,
  13555. + <5 0 0x10000000 0x04000000>;
  13556. +
  13557. + #interrupt-cells = <1>;
  13558. + interrupt-map-mask = <0 0 63>;
  13559. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13560. + <0 0 1 &gic 0 1 4>,
  13561. + <0 0 2 &gic 0 2 4>,
  13562. + <0 0 3 &gic 0 3 4>,
  13563. + <0 0 4 &gic 0 4 4>,
  13564. + <0 0 5 &gic 0 5 4>,
  13565. + <0 0 6 &gic 0 6 4>,
  13566. + <0 0 7 &gic 0 7 4>,
  13567. + <0 0 8 &gic 0 8 4>,
  13568. + <0 0 9 &gic 0 9 4>,
  13569. + <0 0 10 &gic 0 10 4>,
  13570. + <0 0 11 &gic 0 11 4>,
  13571. + <0 0 12 &gic 0 12 4>,
  13572. + <0 0 13 &gic 0 13 4>,
  13573. + <0 0 14 &gic 0 14 4>,
  13574. + <0 0 15 &gic 0 15 4>,
  13575. + <0 0 16 &gic 0 16 4>,
  13576. + <0 0 17 &gic 0 17 4>,
  13577. + <0 0 18 &gic 0 18 4>,
  13578. + <0 0 19 &gic 0 19 4>,
  13579. + <0 0 20 &gic 0 20 4>,
  13580. + <0 0 21 &gic 0 21 4>,
  13581. + <0 0 22 &gic 0 22 4>,
  13582. + <0 0 23 &gic 0 23 4>,
  13583. + <0 0 24 &gic 0 24 4>,
  13584. + <0 0 25 &gic 0 25 4>,
  13585. + <0 0 26 &gic 0 26 4>,
  13586. + <0 0 27 &gic 0 27 4>,
  13587. + <0 0 28 &gic 0 28 4>,
  13588. + <0 0 29 &gic 0 29 4>,
  13589. + <0 0 30 &gic 0 30 4>,
  13590. + <0 0 31 &gic 0 31 4>,
  13591. + <0 0 32 &gic 0 32 4>,
  13592. + <0 0 33 &gic 0 33 4>,
  13593. + <0 0 34 &gic 0 34 4>,
  13594. + <0 0 35 &gic 0 35 4>,
  13595. + <0 0 36 &gic 0 36 4>,
  13596. + <0 0 37 &gic 0 37 4>,
  13597. + <0 0 38 &gic 0 38 4>,
  13598. + <0 0 39 &gic 0 39 4>,
  13599. + <0 0 40 &gic 0 40 4>,
  13600. + <0 0 41 &gic 0 41 4>,
  13601. + <0 0 42 &gic 0 42 4>;
  13602. +
  13603. + /include/ "rtsm_ve-motherboard.dtsi"
  13604. + };
  13605. +};
  13606. +
  13607. +/include/ "clcd-panels.dtsi"
  13608. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts
  13609. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts 1970-01-01 01:00:00.000000000 +0100
  13610. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-cortex_a9x4.dts 2014-09-11 18:05:52.686000742 +0200
  13611. @@ -0,0 +1,183 @@
  13612. +/*
  13613. + * ARM Ltd. Fast Models
  13614. + *
  13615. + * Versatile Express (VE) system model
  13616. + * ARMCortexA9MPx4CT
  13617. + *
  13618. + * RTSM_VE_Cortex_A9x4.lisa
  13619. + */
  13620. +
  13621. +/dts-v1/;
  13622. +
  13623. +/ {
  13624. + model = "RTSM_VE_CortexA9x4";
  13625. + arm,vexpress,site = <0xf>;
  13626. + compatible = "arm,rtsm_ve,cortex_a9x4", "arm,vexpress";
  13627. + interrupt-parent = <&gic>;
  13628. + #address-cells = <1>;
  13629. + #size-cells = <1>;
  13630. +
  13631. + chosen { };
  13632. +
  13633. + aliases {
  13634. + serial0 = &v2m_serial0;
  13635. + serial1 = &v2m_serial1;
  13636. + serial2 = &v2m_serial2;
  13637. + serial3 = &v2m_serial3;
  13638. + };
  13639. +
  13640. + cpus {
  13641. + #address-cells = <1>;
  13642. + #size-cells = <0>;
  13643. +
  13644. + cpu@0 {
  13645. + device_type = "cpu";
  13646. + compatible = "arm,cortex-a9";
  13647. + reg = <0>;
  13648. + };
  13649. +
  13650. + cpu@1 {
  13651. + device_type = "cpu";
  13652. + compatible = "arm,cortex-a9";
  13653. + reg = <1>;
  13654. + };
  13655. +
  13656. + cpu@2 {
  13657. + device_type = "cpu";
  13658. + compatible = "arm,cortex-a9";
  13659. + reg = <2>;
  13660. + };
  13661. +
  13662. + cpu@3 {
  13663. + device_type = "cpu";
  13664. + compatible = "arm,cortex-a9";
  13665. + reg = <3>;
  13666. + };
  13667. + };
  13668. +
  13669. + memory@80000000 {
  13670. + device_type = "memory";
  13671. + reg = <0x80000000 0x80000000>;
  13672. + };
  13673. +
  13674. + scu@2c000000 {
  13675. + compatible = "arm,cortex-a9-scu";
  13676. + reg = <0x2c000000 0x58>;
  13677. + };
  13678. +
  13679. + timer@2c000600 {
  13680. + compatible = "arm,cortex-a9-twd-timer";
  13681. + reg = <0x2c000600 0x20>;
  13682. + interrupts = <1 13 0xf04>;
  13683. + };
  13684. +
  13685. + watchdog@2c000620 {
  13686. + compatible = "arm,cortex-a9-twd-wdt";
  13687. + reg = <0x2c000620 0x20>;
  13688. + interrupts = <1 14 0xf04>;
  13689. + };
  13690. +
  13691. + gic: interrupt-controller@2c001000 {
  13692. + compatible = "arm,cortex-a9-gic";
  13693. + #interrupt-cells = <3>;
  13694. + #address-cells = <0>;
  13695. + interrupt-controller;
  13696. + reg = <0x2c001000 0x1000>,
  13697. + <0x2c000100 0x100>;
  13698. + };
  13699. +
  13700. + dcc {
  13701. + compatible = "arm,vexpress,config-bus";
  13702. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  13703. +
  13704. + osc@0 {
  13705. + /* ACLK clock to the AXI master port on the test chip */
  13706. + compatible = "arm,vexpress-osc";
  13707. + arm,vexpress-sysreg,func = <1 0>;
  13708. + freq-range = <30000000 50000000>;
  13709. + #clock-cells = <0>;
  13710. + clock-output-names = "extsaxiclk";
  13711. + };
  13712. +
  13713. + oscclk1: osc@1 {
  13714. + /* Reference clock for the CLCD */
  13715. + compatible = "arm,vexpress-osc";
  13716. + arm,vexpress-sysreg,func = <1 1>;
  13717. + freq-range = <10000000 80000000>;
  13718. + #clock-cells = <0>;
  13719. + clock-output-names = "clcdclk";
  13720. + };
  13721. +
  13722. + smbclk: oscclk2: osc@2 {
  13723. + /* Reference clock for the test chip internal PLLs */
  13724. + compatible = "arm,vexpress-osc";
  13725. + arm,vexpress-sysreg,func = <1 2>;
  13726. + freq-range = <33000000 100000000>;
  13727. + #clock-cells = <0>;
  13728. + clock-output-names = "tcrefclk";
  13729. + };
  13730. + };
  13731. +
  13732. + smb {
  13733. + compatible = "simple-bus";
  13734. +
  13735. + #address-cells = <2>;
  13736. + #size-cells = <1>;
  13737. + ranges = <0 0 0x08000000 0x04000000>,
  13738. + <1 0 0x14000000 0x04000000>,
  13739. + <2 0 0x18000000 0x04000000>,
  13740. + <3 0 0x1c000000 0x04000000>,
  13741. + <4 0 0x0c000000 0x04000000>,
  13742. + <5 0 0x10000000 0x04000000>;
  13743. +
  13744. + #interrupt-cells = <1>;
  13745. + interrupt-map-mask = <0 0 63>;
  13746. + interrupt-map = <0 0 0 &gic 0 0 4>,
  13747. + <0 0 1 &gic 0 1 4>,
  13748. + <0 0 2 &gic 0 2 4>,
  13749. + <0 0 3 &gic 0 3 4>,
  13750. + <0 0 4 &gic 0 4 4>,
  13751. + <0 0 5 &gic 0 5 4>,
  13752. + <0 0 6 &gic 0 6 4>,
  13753. + <0 0 7 &gic 0 7 4>,
  13754. + <0 0 8 &gic 0 8 4>,
  13755. + <0 0 9 &gic 0 9 4>,
  13756. + <0 0 10 &gic 0 10 4>,
  13757. + <0 0 11 &gic 0 11 4>,
  13758. + <0 0 12 &gic 0 12 4>,
  13759. + <0 0 13 &gic 0 13 4>,
  13760. + <0 0 14 &gic 0 14 4>,
  13761. + <0 0 15 &gic 0 15 4>,
  13762. + <0 0 16 &gic 0 16 4>,
  13763. + <0 0 17 &gic 0 17 4>,
  13764. + <0 0 18 &gic 0 18 4>,
  13765. + <0 0 19 &gic 0 19 4>,
  13766. + <0 0 20 &gic 0 20 4>,
  13767. + <0 0 21 &gic 0 21 4>,
  13768. + <0 0 22 &gic 0 22 4>,
  13769. + <0 0 23 &gic 0 23 4>,
  13770. + <0 0 24 &gic 0 24 4>,
  13771. + <0 0 25 &gic 0 25 4>,
  13772. + <0 0 26 &gic 0 26 4>,
  13773. + <0 0 27 &gic 0 27 4>,
  13774. + <0 0 28 &gic 0 28 4>,
  13775. + <0 0 29 &gic 0 29 4>,
  13776. + <0 0 30 &gic 0 30 4>,
  13777. + <0 0 31 &gic 0 31 4>,
  13778. + <0 0 32 &gic 0 32 4>,
  13779. + <0 0 33 &gic 0 33 4>,
  13780. + <0 0 34 &gic 0 34 4>,
  13781. + <0 0 35 &gic 0 35 4>,
  13782. + <0 0 36 &gic 0 36 4>,
  13783. + <0 0 37 &gic 0 37 4>,
  13784. + <0 0 38 &gic 0 38 4>,
  13785. + <0 0 39 &gic 0 39 4>,
  13786. + <0 0 40 &gic 0 40 4>,
  13787. + <0 0 41 &gic 0 41 4>,
  13788. + <0 0 42 &gic 0 42 4>;
  13789. +
  13790. + /include/ "rtsm_ve-motherboard.dtsi"
  13791. + };
  13792. +};
  13793. +
  13794. +/include/ "clcd-panels.dtsi"
  13795. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi
  13796. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi 1970-01-01 01:00:00.000000000 +0100
  13797. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-motherboard.dtsi 2014-09-11 18:05:52.686000742 +0200
  13798. @@ -0,0 +1,231 @@
  13799. +/*
  13800. + * ARM Ltd. Fast Models
  13801. + *
  13802. + * Versatile Express (VE) system model
  13803. + * Motherboard component
  13804. + *
  13805. + * VEMotherBoard.lisa
  13806. + */
  13807. +
  13808. + motherboard {
  13809. + compatible = "arm,vexpress,v2m-p1", "simple-bus";
  13810. + arm,hbi = <0x190>;
  13811. + arm,vexpress,site = <0>;
  13812. + arm,v2m-memory-map = "rs1";
  13813. + #address-cells = <2>; /* SMB chipselect number and offset */
  13814. + #size-cells = <1>;
  13815. + #interrupt-cells = <1>;
  13816. + ranges;
  13817. +
  13818. + flash@0,00000000 {
  13819. + compatible = "arm,vexpress-flash", "cfi-flash";
  13820. + reg = <0 0x00000000 0x04000000>,
  13821. + <4 0x00000000 0x04000000>;
  13822. + bank-width = <4>;
  13823. + };
  13824. +
  13825. + vram@2,00000000 {
  13826. + compatible = "arm,vexpress-vram";
  13827. + reg = <2 0x00000000 0x00800000>;
  13828. + };
  13829. +
  13830. + ethernet@2,02000000 {
  13831. + compatible = "smsc,lan91c111";
  13832. + reg = <2 0x02000000 0x10000>;
  13833. + interrupts = <15>;
  13834. + };
  13835. +
  13836. + iofpga@3,00000000 {
  13837. + compatible = "arm,amba-bus", "simple-bus";
  13838. + #address-cells = <1>;
  13839. + #size-cells = <1>;
  13840. + ranges = <0 3 0 0x200000>;
  13841. +
  13842. + v2m_sysreg: sysreg@010000 {
  13843. + compatible = "arm,vexpress-sysreg";
  13844. + reg = <0x010000 0x1000>;
  13845. + gpio-controller;
  13846. + #gpio-cells = <2>;
  13847. + };
  13848. +
  13849. + v2m_sysctl: sysctl@020000 {
  13850. + compatible = "arm,sp810", "arm,primecell";
  13851. + reg = <0x020000 0x1000>;
  13852. + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
  13853. + clock-names = "refclk", "timclk", "apb_pclk";
  13854. + #clock-cells = <1>;
  13855. + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
  13856. + };
  13857. +
  13858. + aaci@040000 {
  13859. + compatible = "arm,pl041", "arm,primecell";
  13860. + reg = <0x040000 0x1000>;
  13861. + interrupts = <11>;
  13862. + clocks = <&smbclk>;
  13863. + clock-names = "apb_pclk";
  13864. + };
  13865. +
  13866. + mmci@050000 {
  13867. + compatible = "arm,pl180", "arm,primecell";
  13868. + reg = <0x050000 0x1000>;
  13869. + interrupts = <9 10>;
  13870. + cd-gpios = <&v2m_sysreg 0 0>;
  13871. + wp-gpios = <&v2m_sysreg 1 0>;
  13872. + max-frequency = <12000000>;
  13873. + vmmc-supply = <&v2m_fixed_3v3>;
  13874. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13875. + clock-names = "mclk", "apb_pclk";
  13876. + };
  13877. +
  13878. + kmi@060000 {
  13879. + compatible = "arm,pl050", "arm,primecell";
  13880. + reg = <0x060000 0x1000>;
  13881. + interrupts = <12>;
  13882. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13883. + clock-names = "KMIREFCLK", "apb_pclk";
  13884. + };
  13885. +
  13886. + kmi@070000 {
  13887. + compatible = "arm,pl050", "arm,primecell";
  13888. + reg = <0x070000 0x1000>;
  13889. + interrupts = <13>;
  13890. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13891. + clock-names = "KMIREFCLK", "apb_pclk";
  13892. + };
  13893. +
  13894. + v2m_serial0: uart@090000 {
  13895. + compatible = "arm,pl011", "arm,primecell";
  13896. + reg = <0x090000 0x1000>;
  13897. + interrupts = <5>;
  13898. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13899. + clock-names = "uartclk", "apb_pclk";
  13900. + };
  13901. +
  13902. + v2m_serial1: uart@0a0000 {
  13903. + compatible = "arm,pl011", "arm,primecell";
  13904. + reg = <0x0a0000 0x1000>;
  13905. + interrupts = <6>;
  13906. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13907. + clock-names = "uartclk", "apb_pclk";
  13908. + };
  13909. +
  13910. + v2m_serial2: uart@0b0000 {
  13911. + compatible = "arm,pl011", "arm,primecell";
  13912. + reg = <0x0b0000 0x1000>;
  13913. + interrupts = <7>;
  13914. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13915. + clock-names = "uartclk", "apb_pclk";
  13916. + };
  13917. +
  13918. + v2m_serial3: uart@0c0000 {
  13919. + compatible = "arm,pl011", "arm,primecell";
  13920. + reg = <0x0c0000 0x1000>;
  13921. + interrupts = <8>;
  13922. + clocks = <&v2m_clk24mhz>, <&smbclk>;
  13923. + clock-names = "uartclk", "apb_pclk";
  13924. + };
  13925. +
  13926. + wdt@0f0000 {
  13927. + compatible = "arm,sp805", "arm,primecell";
  13928. + reg = <0x0f0000 0x1000>;
  13929. + interrupts = <0>;
  13930. + clocks = <&v2m_refclk32khz>, <&smbclk>;
  13931. + clock-names = "wdogclk", "apb_pclk";
  13932. + };
  13933. +
  13934. + v2m_timer01: timer@110000 {
  13935. + compatible = "arm,sp804", "arm,primecell";
  13936. + reg = <0x110000 0x1000>;
  13937. + interrupts = <2>;
  13938. + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>;
  13939. + clock-names = "timclken1", "timclken2", "apb_pclk";
  13940. + };
  13941. +
  13942. + v2m_timer23: timer@120000 {
  13943. + compatible = "arm,sp804", "arm,primecell";
  13944. + reg = <0x120000 0x1000>;
  13945. + interrupts = <3>;
  13946. + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>;
  13947. + clock-names = "timclken1", "timclken2", "apb_pclk";
  13948. + };
  13949. +
  13950. + rtc@170000 {
  13951. + compatible = "arm,pl031", "arm,primecell";
  13952. + reg = <0x170000 0x1000>;
  13953. + interrupts = <4>;
  13954. + clocks = <&smbclk>;
  13955. + clock-names = "apb_pclk";
  13956. + };
  13957. +
  13958. + clcd@1f0000 {
  13959. + compatible = "arm,pl111", "arm,primecell";
  13960. + reg = <0x1f0000 0x1000>;
  13961. + interrupts = <14>;
  13962. + clocks = <&v2m_oscclk1>, <&smbclk>;
  13963. + clock-names = "v2m:oscclk1", "apb_pclk";
  13964. + mode = "VGA";
  13965. + use_dma = <0>;
  13966. + framebuffer = <0x18000000 0x00180000>;
  13967. + };
  13968. +
  13969. + virtio_block@0130000 {
  13970. + compatible = "virtio,mmio";
  13971. + reg = <0x130000 0x200>;
  13972. + interrupts = <42>;
  13973. + };
  13974. +
  13975. + };
  13976. +
  13977. + v2m_fixed_3v3: fixedregulator@0 {
  13978. + compatible = "regulator-fixed";
  13979. + regulator-name = "3V3";
  13980. + regulator-min-microvolt = <3300000>;
  13981. + regulator-max-microvolt = <3300000>;
  13982. + regulator-always-on;
  13983. + };
  13984. +
  13985. + v2m_clk24mhz: clk24mhz {
  13986. + compatible = "fixed-clock";
  13987. + #clock-cells = <0>;
  13988. + clock-frequency = <24000000>;
  13989. + clock-output-names = "v2m:clk24mhz";
  13990. + };
  13991. +
  13992. + v2m_refclk1mhz: refclk1mhz {
  13993. + compatible = "fixed-clock";
  13994. + #clock-cells = <0>;
  13995. + clock-frequency = <1000000>;
  13996. + clock-output-names = "v2m:refclk1mhz";
  13997. + };
  13998. +
  13999. + v2m_refclk32khz: refclk32khz {
  14000. + compatible = "fixed-clock";
  14001. + #clock-cells = <0>;
  14002. + clock-frequency = <32768>;
  14003. + clock-output-names = "v2m:refclk32khz";
  14004. + };
  14005. +
  14006. + mcc {
  14007. + compatible = "simple-bus";
  14008. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14009. +
  14010. + v2m_oscclk1: osc@1 {
  14011. + /* CLCD clock */
  14012. + compatible = "arm,vexpress-osc";
  14013. + arm,vexpress-sysreg,func = <1 1>;
  14014. + freq-range = <23750000 63500000>;
  14015. + #clock-cells = <0>;
  14016. + clock-output-names = "v2m:oscclk1";
  14017. + };
  14018. +
  14019. + muxfpga@0 {
  14020. + compatible = "arm,vexpress-muxfpga";
  14021. + arm,vexpress-sysreg,func = <7 0>;
  14022. + };
  14023. +
  14024. + shutdown@0 {
  14025. + compatible = "arm,vexpress-shutdown";
  14026. + arm,vexpress-sysreg,func = <8 0>;
  14027. + };
  14028. + };
  14029. + };
  14030. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts
  14031. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts 1970-01-01 01:00:00.000000000 +0100
  14032. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x1-ca7x1.dts 2014-09-11 18:05:52.686000742 +0200
  14033. @@ -0,0 +1,233 @@
  14034. +/*
  14035. + * ARM Ltd. Fast Models
  14036. + *
  14037. + * Versatile Express (VE) system model
  14038. + * ARMCortexA15x4CT
  14039. + * ARMCortexA7x4CT
  14040. + * RTSM_VE_Cortex_A15x1_A7x1.lisa
  14041. + */
  14042. +
  14043. +/dts-v1/;
  14044. +
  14045. +/memreserve/ 0xff000000 0x01000000;
  14046. +
  14047. +/ {
  14048. + model = "RTSM_VE_CortexA15x1-A7x1";
  14049. + arm,vexpress,site = <0xf>;
  14050. + compatible = "arm,rtsm_ve,cortex_a15x1_a7x1", "arm,vexpress";
  14051. + interrupt-parent = <&gic>;
  14052. + #address-cells = <2>;
  14053. + #size-cells = <2>;
  14054. +
  14055. + chosen { };
  14056. +
  14057. + aliases {
  14058. + serial0 = &v2m_serial0;
  14059. + serial1 = &v2m_serial1;
  14060. + serial2 = &v2m_serial2;
  14061. + serial3 = &v2m_serial3;
  14062. + };
  14063. +
  14064. + clusters {
  14065. + #address-cells = <1>;
  14066. + #size-cells = <0>;
  14067. +
  14068. + cluster0: cluster@0 {
  14069. + reg = <0>;
  14070. +// freqs = <500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000>;
  14071. + cores {
  14072. + #address-cells = <1>;
  14073. + #size-cells = <0>;
  14074. +
  14075. + core0: core@0 {
  14076. + reg = <0>;
  14077. + };
  14078. +
  14079. + };
  14080. + };
  14081. +
  14082. + cluster1: cluster@1 {
  14083. + reg = <1>;
  14084. +// freqs = <350000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000>;
  14085. + cores {
  14086. + #address-cells = <1>;
  14087. + #size-cells = <0>;
  14088. +
  14089. + core1: core@0 {
  14090. + reg = <0>;
  14091. + };
  14092. +
  14093. + };
  14094. + };
  14095. + };
  14096. +
  14097. + cpus {
  14098. + #address-cells = <1>;
  14099. + #size-cells = <0>;
  14100. +
  14101. + cpu0: cpu@0 {
  14102. + device_type = "cpu";
  14103. + compatible = "arm,cortex-a15";
  14104. + reg = <0>;
  14105. + cluster = <&cluster0>;
  14106. + core = <&core0>;
  14107. +// clock-frequency = <1000000000>;
  14108. + cci-control-port = <&cci_control1>;
  14109. + };
  14110. +
  14111. + cpu1: cpu@1 {
  14112. + device_type = "cpu";
  14113. + compatible = "arm,cortex-a7";
  14114. + reg = <0x100>;
  14115. + cluster = <&cluster1>;
  14116. + core = <&core1>;
  14117. +// clock-frequency = <800000000>;
  14118. + cci-control-port = <&cci_control2>;
  14119. + };
  14120. + };
  14121. +
  14122. + memory@80000000 {
  14123. + device_type = "memory";
  14124. + reg = <0 0x80000000 0 0x80000000>;
  14125. + };
  14126. +
  14127. + cci@2c090000 {
  14128. + compatible = "arm,cci-400", "arm,cci";
  14129. + #address-cells = <1>;
  14130. + #size-cells = <1>;
  14131. + reg = <0 0x2c090000 0 0x1000>;
  14132. + ranges = <0x0 0x0 0x2c090000 0x10000>;
  14133. +
  14134. + cci_control1: slave-if@4000 {
  14135. + compatible = "arm,cci-400-ctrl-if";
  14136. + interface-type = "ace";
  14137. + reg = <0x4000 0x1000>;
  14138. + };
  14139. +
  14140. + cci_control2: slave-if@5000 {
  14141. + compatible = "arm,cci-400-ctrl-if";
  14142. + interface-type = "ace";
  14143. + reg = <0x5000 0x1000>;
  14144. + };
  14145. + };
  14146. +
  14147. + dcscb@60000000 {
  14148. + compatible = "arm,rtsm,dcscb";
  14149. + reg = <0 0x60000000 0 0x1000>;
  14150. + };
  14151. +
  14152. + gic: interrupt-controller@2c001000 {
  14153. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  14154. + #interrupt-cells = <3>;
  14155. + #address-cells = <0>;
  14156. + interrupt-controller;
  14157. + reg = <0 0x2c001000 0 0x1000>,
  14158. + <0 0x2c002000 0 0x1000>,
  14159. + <0 0x2c004000 0 0x2000>,
  14160. + <0 0x2c006000 0 0x2000>;
  14161. + interrupts = <1 9 0xf04>;
  14162. + };
  14163. +
  14164. + timer {
  14165. + compatible = "arm,armv7-timer";
  14166. + interrupts = <1 13 0xf08>,
  14167. + <1 14 0xf08>,
  14168. + <1 11 0xf08>,
  14169. + <1 10 0xf08>;
  14170. + };
  14171. +
  14172. + dcc {
  14173. + compatible = "arm,vexpress,config-bus";
  14174. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14175. +
  14176. + osc@0 {
  14177. + /* ACLK clock to the AXI master port on the test chip */
  14178. + compatible = "arm,vexpress-osc";
  14179. + arm,vexpress-sysreg,func = <1 0>;
  14180. + freq-range = <30000000 50000000>;
  14181. + #clock-cells = <0>;
  14182. + clock-output-names = "extsaxiclk";
  14183. + };
  14184. +
  14185. + oscclk1: osc@1 {
  14186. + /* Reference clock for the CLCD */
  14187. + compatible = "arm,vexpress-osc";
  14188. + arm,vexpress-sysreg,func = <1 1>;
  14189. + freq-range = <10000000 80000000>;
  14190. + #clock-cells = <0>;
  14191. + clock-output-names = "clcdclk";
  14192. + };
  14193. +
  14194. + smbclk: oscclk2: osc@2 {
  14195. + /* Reference clock for the test chip internal PLLs */
  14196. + compatible = "arm,vexpress-osc";
  14197. + arm,vexpress-sysreg,func = <1 2>;
  14198. + freq-range = <33000000 100000000>;
  14199. + #clock-cells = <0>;
  14200. + clock-output-names = "tcrefclk";
  14201. + };
  14202. + };
  14203. +
  14204. + smb {
  14205. + compatible = "simple-bus";
  14206. +
  14207. + #address-cells = <2>;
  14208. + #size-cells = <1>;
  14209. + ranges = <0 0 0 0x08000000 0x04000000>,
  14210. + <1 0 0 0x14000000 0x04000000>,
  14211. + <2 0 0 0x18000000 0x04000000>,
  14212. + <3 0 0 0x1c000000 0x04000000>,
  14213. + <4 0 0 0x0c000000 0x04000000>,
  14214. + <5 0 0 0x10000000 0x04000000>;
  14215. +
  14216. + #interrupt-cells = <1>;
  14217. + interrupt-map-mask = <0 0 63>;
  14218. + interrupt-map = <0 0 0 &gic 0 0 4>,
  14219. + <0 0 1 &gic 0 1 4>,
  14220. + <0 0 2 &gic 0 2 4>,
  14221. + <0 0 3 &gic 0 3 4>,
  14222. + <0 0 4 &gic 0 4 4>,
  14223. + <0 0 5 &gic 0 5 4>,
  14224. + <0 0 6 &gic 0 6 4>,
  14225. + <0 0 7 &gic 0 7 4>,
  14226. + <0 0 8 &gic 0 8 4>,
  14227. + <0 0 9 &gic 0 9 4>,
  14228. + <0 0 10 &gic 0 10 4>,
  14229. + <0 0 11 &gic 0 11 4>,
  14230. + <0 0 12 &gic 0 12 4>,
  14231. + <0 0 13 &gic 0 13 4>,
  14232. + <0 0 14 &gic 0 14 4>,
  14233. + <0 0 15 &gic 0 15 4>,
  14234. + <0 0 16 &gic 0 16 4>,
  14235. + <0 0 17 &gic 0 17 4>,
  14236. + <0 0 18 &gic 0 18 4>,
  14237. + <0 0 19 &gic 0 19 4>,
  14238. + <0 0 20 &gic 0 20 4>,
  14239. + <0 0 21 &gic 0 21 4>,
  14240. + <0 0 22 &gic 0 22 4>,
  14241. + <0 0 23 &gic 0 23 4>,
  14242. + <0 0 24 &gic 0 24 4>,
  14243. + <0 0 25 &gic 0 25 4>,
  14244. + <0 0 26 &gic 0 26 4>,
  14245. + <0 0 27 &gic 0 27 4>,
  14246. + <0 0 28 &gic 0 28 4>,
  14247. + <0 0 29 &gic 0 29 4>,
  14248. + <0 0 30 &gic 0 30 4>,
  14249. + <0 0 31 &gic 0 31 4>,
  14250. + <0 0 32 &gic 0 32 4>,
  14251. + <0 0 33 &gic 0 33 4>,
  14252. + <0 0 34 &gic 0 34 4>,
  14253. + <0 0 35 &gic 0 35 4>,
  14254. + <0 0 36 &gic 0 36 4>,
  14255. + <0 0 37 &gic 0 37 4>,
  14256. + <0 0 38 &gic 0 38 4>,
  14257. + <0 0 39 &gic 0 39 4>,
  14258. + <0 0 40 &gic 0 40 4>,
  14259. + <0 0 41 &gic 0 41 4>,
  14260. + <0 0 42 &gic 0 42 4>;
  14261. +
  14262. + /include/ "rtsm_ve-motherboard.dtsi"
  14263. + };
  14264. +};
  14265. +
  14266. +/include/ "clcd-panels.dtsi"
  14267. diff -Nur linux-3.14.17/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts
  14268. --- linux-3.14.17/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts 1970-01-01 01:00:00.000000000 +0100
  14269. +++ linux-imx6-3.14/arch/arm/boot/dts/rtsm_ve-v2p-ca15x4-ca7x4.dts 2014-09-11 18:05:52.686000742 +0200
  14270. @@ -0,0 +1,317 @@
  14271. +/*
  14272. + * ARM Ltd. Fast Models
  14273. + *
  14274. + * Versatile Express (VE) system model
  14275. + * ARMCortexA15x4CT
  14276. + * ARMCortexA7x4CT
  14277. + * RTSM_VE_Cortex_A15x4_A7x4.lisa
  14278. + */
  14279. +
  14280. +/dts-v1/;
  14281. +
  14282. +/memreserve/ 0xff000000 0x01000000;
  14283. +
  14284. +/ {
  14285. + model = "RTSM_VE_CortexA15x4-A7x4";
  14286. + arm,vexpress,site = <0xf>;
  14287. + compatible = "arm,rtsm_ve,cortex_a15x4_a7x4", "arm,vexpress";
  14288. + interrupt-parent = <&gic>;
  14289. + #address-cells = <2>;
  14290. + #size-cells = <2>;
  14291. +
  14292. + chosen { };
  14293. +
  14294. + aliases {
  14295. + serial0 = &v2m_serial0;
  14296. + serial1 = &v2m_serial1;
  14297. + serial2 = &v2m_serial2;
  14298. + serial3 = &v2m_serial3;
  14299. + };
  14300. +
  14301. + clusters {
  14302. + #address-cells = <1>;
  14303. + #size-cells = <0>;
  14304. +
  14305. + cluster0: cluster@0 {
  14306. + reg = <0>;
  14307. +// freqs = <500000000 600000000 700000000 800000000 900000000 1000000000 1100000000 1200000000>;
  14308. + cores {
  14309. + #address-cells = <1>;
  14310. + #size-cells = <0>;
  14311. +
  14312. + core0: core@0 {
  14313. + reg = <0>;
  14314. + };
  14315. +
  14316. + core1: core@1 {
  14317. + reg = <1>;
  14318. + };
  14319. +
  14320. + core2: core@2 {
  14321. + reg = <2>;
  14322. + };
  14323. +
  14324. + core3: core@3 {
  14325. + reg = <3>;
  14326. + };
  14327. +
  14328. + };
  14329. + };
  14330. +
  14331. + cluster1: cluster@1 {
  14332. + reg = <1>;
  14333. +// freqs = <350000000 400000000 500000000 600000000 700000000 800000000 900000000 1000000000>;
  14334. + cores {
  14335. + #address-cells = <1>;
  14336. + #size-cells = <0>;
  14337. +
  14338. + core4: core@0 {
  14339. + reg = <0>;
  14340. + };
  14341. +
  14342. + core5: core@1 {
  14343. + reg = <1>;
  14344. + };
  14345. +
  14346. + core6: core@2 {
  14347. + reg = <2>;
  14348. + };
  14349. +
  14350. + core7: core@3 {
  14351. + reg = <3>;
  14352. + };
  14353. +
  14354. + };
  14355. + };
  14356. + };
  14357. +
  14358. + cpus {
  14359. + #address-cells = <1>;
  14360. + #size-cells = <0>;
  14361. +
  14362. + cpu0: cpu@0 {
  14363. + device_type = "cpu";
  14364. + compatible = "arm,cortex-a15";
  14365. + reg = <0>;
  14366. + cluster = <&cluster0>;
  14367. + core = <&core0>;
  14368. +// clock-frequency = <1000000000>;
  14369. + cci-control-port = <&cci_control1>;
  14370. + };
  14371. +
  14372. + cpu1: cpu@1 {
  14373. + device_type = "cpu";
  14374. + compatible = "arm,cortex-a15";
  14375. + reg = <1>;
  14376. + cluster = <&cluster0>;
  14377. + core = <&core1>;
  14378. +// clock-frequency = <1000000000>;
  14379. + cci-control-port = <&cci_control1>;
  14380. + };
  14381. +
  14382. + cpu2: cpu@2 {
  14383. + device_type = "cpu";
  14384. + compatible = "arm,cortex-a15";
  14385. + reg = <2>;
  14386. + cluster = <&cluster0>;
  14387. + core = <&core2>;
  14388. +// clock-frequency = <1000000000>;
  14389. + cci-control-port = <&cci_control1>;
  14390. + };
  14391. +
  14392. + cpu3: cpu@3 {
  14393. + device_type = "cpu";
  14394. + compatible = "arm,cortex-a15";
  14395. + reg = <3>;
  14396. + cluster = <&cluster0>;
  14397. + core = <&core3>;
  14398. +// clock-frequency = <1000000000>;
  14399. + cci-control-port = <&cci_control1>;
  14400. + };
  14401. +
  14402. + cpu4: cpu@4 {
  14403. + device_type = "cpu";
  14404. + compatible = "arm,cortex-a7";
  14405. + reg = <0x100>;
  14406. + cluster = <&cluster1>;
  14407. + core = <&core4>;
  14408. +// clock-frequency = <800000000>;
  14409. + cci-control-port = <&cci_control2>;
  14410. + };
  14411. +
  14412. + cpu5: cpu@5 {
  14413. + device_type = "cpu";
  14414. + compatible = "arm,cortex-a7";
  14415. + reg = <0x101>;
  14416. + cluster = <&cluster1>;
  14417. + core = <&core5>;
  14418. +// clock-frequency = <800000000>;
  14419. + cci-control-port = <&cci_control2>;
  14420. + };
  14421. +
  14422. + cpu6: cpu@6 {
  14423. + device_type = "cpu";
  14424. + compatible = "arm,cortex-a7";
  14425. + reg = <0x102>;
  14426. + cluster = <&cluster1>;
  14427. + core = <&core6>;
  14428. +// clock-frequency = <800000000>;
  14429. + cci-control-port = <&cci_control2>;
  14430. + };
  14431. +
  14432. + cpu7: cpu@7 {
  14433. + device_type = "cpu";
  14434. + compatible = "arm,cortex-a7";
  14435. + reg = <0x103>;
  14436. + cluster = <&cluster1>;
  14437. + core = <&core7>;
  14438. +// clock-frequency = <800000000>;
  14439. + cci-control-port = <&cci_control2>;
  14440. + };
  14441. + };
  14442. +
  14443. + memory@80000000 {
  14444. + device_type = "memory";
  14445. + reg = <0 0x80000000 0 0x80000000>;
  14446. + };
  14447. +
  14448. + cci@2c090000 {
  14449. + compatible = "arm,cci-400", "arm,cci";
  14450. + #address-cells = <1>;
  14451. + #size-cells = <1>;
  14452. + reg = <0 0x2c090000 0 0x1000>;
  14453. + ranges = <0x0 0x0 0x2c090000 0x10000>;
  14454. +
  14455. + cci_control1: slave-if@4000 {
  14456. + compatible = "arm,cci-400-ctrl-if";
  14457. + interface-type = "ace";
  14458. + reg = <0x4000 0x1000>;
  14459. + };
  14460. +
  14461. + cci_control2: slave-if@5000 {
  14462. + compatible = "arm,cci-400-ctrl-if";
  14463. + interface-type = "ace";
  14464. + reg = <0x5000 0x1000>;
  14465. + };
  14466. + };
  14467. +
  14468. + dcscb@60000000 {
  14469. + compatible = "arm,rtsm,dcscb";
  14470. + reg = <0 0x60000000 0 0x1000>;
  14471. + };
  14472. +
  14473. + gic: interrupt-controller@2c001000 {
  14474. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  14475. + #interrupt-cells = <3>;
  14476. + #address-cells = <0>;
  14477. + interrupt-controller;
  14478. + reg = <0 0x2c001000 0 0x1000>,
  14479. + <0 0x2c002000 0 0x1000>,
  14480. + <0 0x2c004000 0 0x2000>,
  14481. + <0 0x2c006000 0 0x2000>;
  14482. + interrupts = <1 9 0xf04>;
  14483. + };
  14484. +
  14485. + timer {
  14486. + compatible = "arm,armv7-timer";
  14487. + interrupts = <1 13 0xf08>,
  14488. + <1 14 0xf08>,
  14489. + <1 11 0xf08>,
  14490. + <1 10 0xf08>;
  14491. + };
  14492. +
  14493. + dcc {
  14494. + compatible = "arm,vexpress,config-bus";
  14495. + arm,vexpress,config-bridge = <&v2m_sysreg>;
  14496. +
  14497. + osc@0 {
  14498. + /* ACLK clock to the AXI master port on the test chip */
  14499. + compatible = "arm,vexpress-osc";
  14500. + arm,vexpress-sysreg,func = <1 0>;
  14501. + freq-range = <30000000 50000000>;
  14502. + #clock-cells = <0>;
  14503. + clock-output-names = "extsaxiclk";
  14504. + };
  14505. +
  14506. + oscclk1: osc@1 {
  14507. + /* Reference clock for the CLCD */
  14508. + compatible = "arm,vexpress-osc";
  14509. + arm,vexpress-sysreg,func = <1 1>;
  14510. + freq-range = <10000000 80000000>;
  14511. + #clock-cells = <0>;
  14512. + clock-output-names = "clcdclk";
  14513. + };
  14514. +
  14515. + smbclk: oscclk2: osc@2 {
  14516. + /* Reference clock for the test chip internal PLLs */
  14517. + compatible = "arm,vexpress-osc";
  14518. + arm,vexpress-sysreg,func = <1 2>;
  14519. + freq-range = <33000000 100000000>;
  14520. + #clock-cells = <0>;
  14521. + clock-output-names = "tcrefclk";
  14522. + };
  14523. + };
  14524. +
  14525. + smb {
  14526. + compatible = "simple-bus";
  14527. +
  14528. + #address-cells = <2>;
  14529. + #size-cells = <1>;
  14530. + ranges = <0 0 0 0x08000000 0x04000000>,
  14531. + <1 0 0 0x14000000 0x04000000>,
  14532. + <2 0 0 0x18000000 0x04000000>,
  14533. + <3 0 0 0x1c000000 0x04000000>,
  14534. + <4 0 0 0x0c000000 0x04000000>,
  14535. + <5 0 0 0x10000000 0x04000000>;
  14536. +
  14537. + #interrupt-cells = <1>;
  14538. + interrupt-map-mask = <0 0 63>;
  14539. + interrupt-map = <0 0 0 &gic 0 0 4>,
  14540. + <0 0 1 &gic 0 1 4>,
  14541. + <0 0 2 &gic 0 2 4>,
  14542. + <0 0 3 &gic 0 3 4>,
  14543. + <0 0 4 &gic 0 4 4>,
  14544. + <0 0 5 &gic 0 5 4>,
  14545. + <0 0 6 &gic 0 6 4>,
  14546. + <0 0 7 &gic 0 7 4>,
  14547. + <0 0 8 &gic 0 8 4>,
  14548. + <0 0 9 &gic 0 9 4>,
  14549. + <0 0 10 &gic 0 10 4>,
  14550. + <0 0 11 &gic 0 11 4>,
  14551. + <0 0 12 &gic 0 12 4>,
  14552. + <0 0 13 &gic 0 13 4>,
  14553. + <0 0 14 &gic 0 14 4>,
  14554. + <0 0 15 &gic 0 15 4>,
  14555. + <0 0 16 &gic 0 16 4>,
  14556. + <0 0 17 &gic 0 17 4>,
  14557. + <0 0 18 &gic 0 18 4>,
  14558. + <0 0 19 &gic 0 19 4>,
  14559. + <0 0 20 &gic 0 20 4>,
  14560. + <0 0 21 &gic 0 21 4>,
  14561. + <0 0 22 &gic 0 22 4>,
  14562. + <0 0 23 &gic 0 23 4>,
  14563. + <0 0 24 &gic 0 24 4>,
  14564. + <0 0 25 &gic 0 25 4>,
  14565. + <0 0 26 &gic 0 26 4>,
  14566. + <0 0 27 &gic 0 27 4>,
  14567. + <0 0 28 &gic 0 28 4>,
  14568. + <0 0 29 &gic 0 29 4>,
  14569. + <0 0 30 &gic 0 30 4>,
  14570. + <0 0 31 &gic 0 31 4>,
  14571. + <0 0 32 &gic 0 32 4>,
  14572. + <0 0 33 &gic 0 33 4>,
  14573. + <0 0 34 &gic 0 34 4>,
  14574. + <0 0 35 &gic 0 35 4>,
  14575. + <0 0 36 &gic 0 36 4>,
  14576. + <0 0 37 &gic 0 37 4>,
  14577. + <0 0 38 &gic 0 38 4>,
  14578. + <0 0 39 &gic 0 39 4>,
  14579. + <0 0 40 &gic 0 40 4>,
  14580. + <0 0 41 &gic 0 41 4>,
  14581. + <0 0 42 &gic 0 42 4>;
  14582. +
  14583. + /include/ "rtsm_ve-motherboard.dtsi"
  14584. + };
  14585. +};
  14586. +
  14587. +/include/ "clcd-panels.dtsi"
  14588. diff -Nur linux-3.14.17/arch/arm/boot/dts/vexpress-v2m.dtsi linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m.dtsi
  14589. --- linux-3.14.17/arch/arm/boot/dts/vexpress-v2m.dtsi 2014-08-14 03:38:34.000000000 +0200
  14590. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m.dtsi 2014-09-11 18:05:52.742000967 +0200
  14591. @@ -227,6 +227,7 @@
  14592. };
  14593. clcd@1f000 {
  14594. + status = "disabled";
  14595. compatible = "arm,pl111", "arm,primecell";
  14596. reg = <0x1f000 0x1000>;
  14597. interrupts = <14>;
  14598. diff -Nur linux-3.14.17/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
  14599. --- linux-3.14.17/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi 2014-08-14 03:38:34.000000000 +0200
  14600. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi 2014-09-11 18:05:52.742000967 +0200
  14601. @@ -228,6 +228,7 @@
  14602. };
  14603. clcd@1f0000 {
  14604. + status = "disabled";
  14605. compatible = "arm,pl111", "arm,primecell";
  14606. reg = <0x1f0000 0x1000>;
  14607. interrupts = <14>;
  14608. diff -Nur linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
  14609. --- linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts 2014-08-14 03:38:34.000000000 +0200
  14610. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts 2014-09-11 18:05:52.742000967 +0200
  14611. @@ -9,6 +9,8 @@
  14612. /dts-v1/;
  14613. +/memreserve/ 0xff000000 0x01000000;
  14614. +
  14615. / {
  14616. model = "V2P-CA15_CA7";
  14617. arm,hbi = <0x249>;
  14618. @@ -29,29 +31,60 @@
  14619. i2c1 = &v2m_i2c_pcie;
  14620. };
  14621. - cpus {
  14622. + clusters {
  14623. #address-cells = <1>;
  14624. #size-cells = <0>;
  14625. - cpu0: cpu@0 {
  14626. - device_type = "cpu";
  14627. - compatible = "arm,cortex-a15";
  14628. + cluster0: cluster@0 {
  14629. reg = <0>;
  14630. - cci-control-port = <&cci_control1>;
  14631. + cores {
  14632. + #address-cells = <1>;
  14633. + #size-cells = <0>;
  14634. +
  14635. + core0: core@0 {
  14636. + reg = <0>;
  14637. + };
  14638. +
  14639. + core1: core@1 {
  14640. + reg = <1>;
  14641. + };
  14642. +
  14643. + };
  14644. };
  14645. - cpu1: cpu@1 {
  14646. - device_type = "cpu";
  14647. - compatible = "arm,cortex-a15";
  14648. + cluster1: cluster@1 {
  14649. reg = <1>;
  14650. - cci-control-port = <&cci_control1>;
  14651. + cores {
  14652. + #address-cells = <1>;
  14653. + #size-cells = <0>;
  14654. +
  14655. + core2: core@0 {
  14656. + reg = <0>;
  14657. + };
  14658. +
  14659. + core3: core@1 {
  14660. + reg = <1>;
  14661. + };
  14662. +
  14663. + core4: core@2 {
  14664. + reg = <2>;
  14665. + };
  14666. + };
  14667. };
  14668. + };
  14669. +
  14670. + cpus {
  14671. + #address-cells = <1>;
  14672. + #size-cells = <0>;
  14673. cpu2: cpu@2 {
  14674. device_type = "cpu";
  14675. compatible = "arm,cortex-a7";
  14676. reg = <0x100>;
  14677. cci-control-port = <&cci_control2>;
  14678. + cluster = <&cluster1>;
  14679. + core = <&core2>;
  14680. + clock-frequency = <800000000>;
  14681. };
  14682. cpu3: cpu@3 {
  14683. @@ -59,6 +92,9 @@
  14684. compatible = "arm,cortex-a7";
  14685. reg = <0x101>;
  14686. cci-control-port = <&cci_control2>;
  14687. + cluster = <&cluster1>;
  14688. + core = <&core3>;
  14689. + clock-frequency = <800000000>;
  14690. };
  14691. cpu4: cpu@4 {
  14692. @@ -66,12 +102,35 @@
  14693. compatible = "arm,cortex-a7";
  14694. reg = <0x102>;
  14695. cci-control-port = <&cci_control2>;
  14696. + cluster = <&cluster1>;
  14697. + core = <&core4>;
  14698. + clock-frequency = <800000000>;
  14699. + };
  14700. +
  14701. + cpu0: cpu@0 {
  14702. + device_type = "cpu";
  14703. + compatible = "arm,cortex-a15";
  14704. + reg = <0>;
  14705. + cci-control-port = <&cci_control1>;
  14706. + cluster = <&cluster0>;
  14707. + core = <&core0>;
  14708. + clock-frequency = <1000000000>;
  14709. + };
  14710. +
  14711. + cpu1: cpu@1 {
  14712. + device_type = "cpu";
  14713. + compatible = "arm,cortex-a15";
  14714. + reg = <1>;
  14715. + cci-control-port = <&cci_control1>;
  14716. + cluster = <&cluster0>;
  14717. + core = <&core1>;
  14718. + clock-frequency = <1000000000>;
  14719. };
  14720. };
  14721. memory@80000000 {
  14722. device_type = "memory";
  14723. - reg = <0 0x80000000 0 0x40000000>;
  14724. + reg = <0 0x80000000 0 0x80000000>;
  14725. };
  14726. wdt@2a490000 {
  14727. @@ -86,6 +145,8 @@
  14728. compatible = "arm,hdlcd";
  14729. reg = <0 0x2b000000 0 0x1000>;
  14730. interrupts = <0 85 4>;
  14731. + mode = "1024x768-16@60";
  14732. + framebuffer = <0 0xff000000 0 0x01000000>;
  14733. clocks = <&oscclk5>;
  14734. clock-names = "pxlclk";
  14735. };
  14736. @@ -127,6 +188,16 @@
  14737. interface-type = "ace";
  14738. reg = <0x5000 0x1000>;
  14739. };
  14740. +
  14741. + pmu@9000 {
  14742. + compatible = "arm,cci-400-pmu";
  14743. + reg = <0x9000 0x5000>;
  14744. + interrupts = <0 101 4>,
  14745. + <0 102 4>,
  14746. + <0 103 4>,
  14747. + <0 104 4>,
  14748. + <0 105 4>;
  14749. + };
  14750. };
  14751. memory-controller@7ffd0000 {
  14752. @@ -164,12 +235,21 @@
  14753. <1 10 0xf08>;
  14754. };
  14755. - pmu {
  14756. + pmu_a15 {
  14757. compatible = "arm,cortex-a15-pmu";
  14758. + cluster = <&cluster0>;
  14759. interrupts = <0 68 4>,
  14760. <0 69 4>;
  14761. };
  14762. + pmu_a7 {
  14763. + compatible = "arm,cortex-a7-pmu";
  14764. + cluster = <&cluster1>;
  14765. + interrupts = <0 128 4>,
  14766. + <0 129 4>,
  14767. + <0 130 4>;
  14768. + };
  14769. +
  14770. oscclk6a: oscclk6a {
  14771. /* Reference 24MHz clock */
  14772. compatible = "fixed-clock";
  14773. @@ -178,6 +258,19 @@
  14774. clock-output-names = "oscclk6a";
  14775. };
  14776. +/* PSCI requires support from firmware and is not present in the normal TC2
  14777. + * distribution, so this node is commented out by default...
  14778. +
  14779. + psci {
  14780. + compatible = "arm,psci";
  14781. + method = "smc";
  14782. + cpu_suspend = <0x80100001>;
  14783. + cpu_off = <0x80100002>;
  14784. + cpu_on = <0x80100003>;
  14785. + migrate = <0x80100004>;
  14786. + };
  14787. +*/
  14788. +
  14789. dcc {
  14790. compatible = "arm,vexpress,config-bus";
  14791. arm,vexpress,config-bridge = <&v2m_sysreg>;
  14792. diff -Nur linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
  14793. --- linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts 2014-08-14 03:38:34.000000000 +0200
  14794. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts 2014-09-11 18:05:52.742000967 +0200
  14795. @@ -9,6 +9,8 @@
  14796. /dts-v1/;
  14797. +/memreserve/ 0xbf000000 0x01000000;
  14798. +
  14799. / {
  14800. model = "V2P-CA15";
  14801. arm,hbi = <0x237>;
  14802. @@ -57,6 +59,8 @@
  14803. interrupts = <0 85 4>;
  14804. clocks = <&oscclk5>;
  14805. clock-names = "pxlclk";
  14806. + mode = "1024x768-16@60";
  14807. + framebuffer = <0 0xbf000000 0 0x01000000>;
  14808. };
  14809. memory-controller@2b0a0000 {
  14810. diff -Nur linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca5s.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
  14811. --- linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca5s.dts 2014-08-14 03:38:34.000000000 +0200
  14812. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca5s.dts 2014-09-11 18:05:52.742000967 +0200
  14813. @@ -9,6 +9,8 @@
  14814. /dts-v1/;
  14815. +/memreserve/ 0xbf000000 0x01000000;
  14816. +
  14817. / {
  14818. model = "V2P-CA5s";
  14819. arm,hbi = <0x225>;
  14820. @@ -59,6 +61,8 @@
  14821. interrupts = <0 85 4>;
  14822. clocks = <&oscclk3>;
  14823. clock-names = "pxlclk";
  14824. + mode = "640x480-16@60";
  14825. + framebuffer = <0xbf000000 0x01000000>;
  14826. };
  14827. memory-controller@2a150000 {
  14828. diff -Nur linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca9.dts linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca9.dts
  14829. --- linux-3.14.17/arch/arm/boot/dts/vexpress-v2p-ca9.dts 2014-08-14 03:38:34.000000000 +0200
  14830. +++ linux-imx6-3.14/arch/arm/boot/dts/vexpress-v2p-ca9.dts 2014-09-11 18:05:52.746000984 +0200
  14831. @@ -9,6 +9,8 @@
  14832. /dts-v1/;
  14833. +/include/ "clcd-panels.dtsi"
  14834. +
  14835. / {
  14836. model = "V2P-CA9";
  14837. arm,hbi = <0x191>;
  14838. @@ -73,6 +75,8 @@
  14839. interrupts = <0 44 4>;
  14840. clocks = <&oscclk1>, <&oscclk2>;
  14841. clock-names = "clcdclk", "apb_pclk";
  14842. + mode = "XVGA";
  14843. + use_dma = <1>;
  14844. };
  14845. memory-controller@100e0000 {
  14846. diff -Nur linux-3.14.17/arch/arm/boot/dts/vf610.dtsi linux-imx6-3.14/arch/arm/boot/dts/vf610.dtsi
  14847. --- linux-3.14.17/arch/arm/boot/dts/vf610.dtsi 2014-08-14 03:38:34.000000000 +0200
  14848. +++ linux-imx6-3.14/arch/arm/boot/dts/vf610.dtsi 2014-09-11 18:05:52.746000984 +0200
  14849. @@ -44,11 +44,13 @@
  14850. sxosc {
  14851. compatible = "fixed-clock";
  14852. + #clock-cells = <0>;
  14853. clock-frequency = <32768>;
  14854. };
  14855. fxosc {
  14856. compatible = "fixed-clock";
  14857. + #clock-cells = <0>;
  14858. clock-frequency = <24000000>;
  14859. };
  14860. };
  14861. diff -Nur linux-3.14.17/arch/arm/boot/dts/vf610-twr.dts linux-imx6-3.14/arch/arm/boot/dts/vf610-twr.dts
  14862. --- linux-3.14.17/arch/arm/boot/dts/vf610-twr.dts 2014-08-14 03:38:34.000000000 +0200
  14863. +++ linux-imx6-3.14/arch/arm/boot/dts/vf610-twr.dts 2014-09-11 18:05:52.746000984 +0200
  14864. @@ -25,11 +25,13 @@
  14865. clocks {
  14866. audio_ext {
  14867. compatible = "fixed-clock";
  14868. + #clock-cells = <0>;
  14869. clock-frequency = <24576000>;
  14870. };
  14871. enet_ext {
  14872. compatible = "fixed-clock";
  14873. + #clock-cells = <0>;
  14874. clock-frequency = <50000000>;
  14875. };
  14876. };
  14877. diff -Nur linux-3.14.17/arch/arm/common/Makefile linux-imx6-3.14/arch/arm/common/Makefile
  14878. --- linux-3.14.17/arch/arm/common/Makefile 2014-08-14 03:38:34.000000000 +0200
  14879. +++ linux-imx6-3.14/arch/arm/common/Makefile 2014-09-11 18:05:52.754001015 +0200
  14880. @@ -13,6 +13,7 @@
  14881. obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
  14882. obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
  14883. obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
  14884. +CFLAGS_REMOVE_mcpm_entry.o = -pg
  14885. AFLAGS_mcpm_head.o := -march=armv7-a
  14886. AFLAGS_vlock.o := -march=armv7-a
  14887. obj-$(CONFIG_TI_PRIV_EDMA) += edma.o
  14888. diff -Nur linux-3.14.17/arch/arm/configs/imx_v6_v7_defconfig linux-imx6-3.14/arch/arm/configs/imx_v6_v7_defconfig
  14889. --- linux-3.14.17/arch/arm/configs/imx_v6_v7_defconfig 2014-08-14 03:38:34.000000000 +0200
  14890. +++ linux-imx6-3.14/arch/arm/configs/imx_v6_v7_defconfig 2014-09-11 18:05:52.798001191 +0200
  14891. @@ -45,6 +45,9 @@
  14892. CONFIG_AEABI=y
  14893. CONFIG_HIGHMEM=y
  14894. CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  14895. +CONFIG_CPU_FREQ=y
  14896. +CONFIG_ARM_IMX6Q_CPUFREQ=y
  14897. +CONFIG_CPU_IDLE=y
  14898. CONFIG_VFP=y
  14899. CONFIG_NEON=y
  14900. CONFIG_BINFMT_MISC=m
  14901. @@ -70,6 +73,8 @@
  14902. CONFIG_DEVTMPFS=y
  14903. CONFIG_DEVTMPFS_MOUNT=y
  14904. # CONFIG_STANDALONE is not set
  14905. +CONFIG_CMA=y
  14906. +CONFIG_CMA_SIZE_MBYTES=256
  14907. CONFIG_IMX_WEIM=y
  14908. CONFIG_CONNECTOR=y
  14909. CONFIG_MTD=y
  14910. @@ -154,7 +159,12 @@
  14911. CONFIG_SPI_IMX=y
  14912. CONFIG_GPIO_SYSFS=y
  14913. CONFIG_GPIO_MC9S08DZ60=y
  14914. +CONFIG_GPIO_PCA953X=y
  14915. # CONFIG_HWMON is not set
  14916. +CONFIG_THERMAL=y
  14917. +CONFIG_CPU_THERMAL=y
  14918. +CONFIG_IMX_THERMAL=y
  14919. +CONFIG_DEVICE_THERMAL=y
  14920. CONFIG_WATCHDOG=y
  14921. CONFIG_IMX2_WDT=y
  14922. CONFIG_MFD_DA9052_I2C=y
  14923. @@ -170,32 +180,44 @@
  14924. CONFIG_REGULATOR_PFUZE100=y
  14925. CONFIG_MEDIA_SUPPORT=y
  14926. CONFIG_MEDIA_CAMERA_SUPPORT=y
  14927. +CONFIG_MEDIA_USB_SUPPORT=y
  14928. +CONFIG_USB_VIDEO_CLASS=m
  14929. CONFIG_MEDIA_RC_SUPPORT=y
  14930. CONFIG_RC_DEVICES=y
  14931. CONFIG_IR_GPIO_CIR=y
  14932. CONFIG_V4L_PLATFORM_DRIVERS=y
  14933. +CONFIG_VIDEO_MXC_OUTPUT=y
  14934. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  14935. CONFIG_SOC_CAMERA=y
  14936. CONFIG_VIDEO_MX3=y
  14937. CONFIG_V4L_MEM2MEM_DRIVERS=y
  14938. CONFIG_VIDEO_CODA=y
  14939. CONFIG_SOC_CAMERA_OV2640=y
  14940. CONFIG_DRM=y
  14941. +CONFIG_DRM_VIVANTE=y
  14942. CONFIG_BACKLIGHT_LCD_SUPPORT=y
  14943. CONFIG_LCD_CLASS_DEVICE=y
  14944. CONFIG_LCD_L4F00242T03=y
  14945. CONFIG_LCD_PLATFORM=y
  14946. CONFIG_BACKLIGHT_CLASS_DEVICE=y
  14947. CONFIG_BACKLIGHT_PWM=y
  14948. +CONFIG_FB_MXC_SYNC_PANEL=y
  14949. +CONFIG_FB_MXC_LDB=y
  14950. +CONFIG_FB_MXC_HDMI=y
  14951. +CONFIG_FB_MXC_MIPI_DSI=y
  14952. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  14953. CONFIG_FRAMEBUFFER_CONSOLE=y
  14954. CONFIG_LOGO=y
  14955. CONFIG_SOUND=y
  14956. CONFIG_SND=y
  14957. +CONFIG_SND_USB_AUDIO=m
  14958. CONFIG_SND_SOC=y
  14959. CONFIG_SND_IMX_SOC=y
  14960. CONFIG_SND_SOC_PHYCORE_AC97=y
  14961. CONFIG_SND_SOC_EUKREA_TLV320=y
  14962. CONFIG_SND_SOC_IMX_WM8962=y
  14963. CONFIG_SND_SOC_IMX_SGTL5000=y
  14964. +CONFIG_SND_SOC_IMX_CS42888=y
  14965. CONFIG_SND_SOC_IMX_SPDIF=y
  14966. CONFIG_SND_SOC_IMX_MC13783=y
  14967. CONFIG_USB=y
  14968. @@ -208,12 +230,18 @@
  14969. CONFIG_NOP_USB_XCEIV=y
  14970. CONFIG_USB_MXS_PHY=y
  14971. CONFIG_USB_GADGET=y
  14972. +CONFIG_USB_ZERO=m
  14973. CONFIG_USB_ETH=m
  14974. CONFIG_USB_MASS_STORAGE=m
  14975. +CONFIG_USB_G_SERIAL=m
  14976. CONFIG_MMC=y
  14977. +CONFIG_MMC_UNSAFE_RESUME=y
  14978. CONFIG_MMC_SDHCI=y
  14979. CONFIG_MMC_SDHCI_PLTFM=y
  14980. CONFIG_MMC_SDHCI_ESDHC_IMX=y
  14981. +CONFIG_MXC_IPU=y
  14982. +CONFIG_MXC_GPU_VIV=y
  14983. +CONFIG_MXC_ASRC=y
  14984. CONFIG_NEW_LEDS=y
  14985. CONFIG_LEDS_CLASS=y
  14986. CONFIG_LEDS_GPIO=y
  14987. @@ -229,16 +257,10 @@
  14988. CONFIG_RTC_DRV_MXC=y
  14989. CONFIG_RTC_DRV_SNVS=y
  14990. CONFIG_DMADEVICES=y
  14991. +CONFIG_MXC_PXP_V2=y
  14992. CONFIG_IMX_SDMA=y
  14993. CONFIG_MXS_DMA=y
  14994. CONFIG_STAGING=y
  14995. -CONFIG_DRM_IMX=y
  14996. -CONFIG_DRM_IMX_FB_HELPER=y
  14997. -CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
  14998. -CONFIG_DRM_IMX_TVE=y
  14999. -CONFIG_DRM_IMX_LDB=y
  15000. -CONFIG_DRM_IMX_IPUV3_CORE=y
  15001. -CONFIG_DRM_IMX_IPUV3=y
  15002. CONFIG_COMMON_CLK_DEBUG=y
  15003. # CONFIG_IOMMU_SUPPORT is not set
  15004. CONFIG_PWM=y
  15005. diff -Nur linux-3.14.17/arch/arm/configs/imx_v7_cbi_hb_base_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_base_defconfig
  15006. --- linux-3.14.17/arch/arm/configs/imx_v7_cbi_hb_base_defconfig 1970-01-01 01:00:00.000000000 +0100
  15007. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_base_defconfig 2014-09-11 18:05:52.798001191 +0200
  15008. @@ -0,0 +1,367 @@
  15009. +# CONFIG_LOCALVERSION_AUTO is not set
  15010. +CONFIG_KERNEL_LZO=y
  15011. +CONFIG_SYSVIPC=y
  15012. +CONFIG_FHANDLE=y
  15013. +CONFIG_NO_HZ=y
  15014. +CONFIG_HIGH_RES_TIMERS=y
  15015. +CONFIG_LOG_BUF_SHIFT=18
  15016. +CONFIG_CGROUPS=y
  15017. +CONFIG_RELAY=y
  15018. +CONFIG_BLK_DEV_INITRD=y
  15019. +CONFIG_EXPERT=y
  15020. +CONFIG_PERF_EVENTS=y
  15021. +CONFIG_CLEANCACHE=y
  15022. +CONFIG_FRONTSWAP=y
  15023. +CONFIG_ZSWAP=y
  15024. +CONFIG_ZSMALLOC=y
  15025. +# CONFIG_SLUB_DEBUG is not set
  15026. +# CONFIG_COMPAT_BRK is not set
  15027. +CONFIG_MODULES=y
  15028. +CONFIG_MODULE_UNLOAD=y
  15029. +CONFIG_MODVERSIONS=y
  15030. +CONFIG_MODULE_SRCVERSION_ALL=y
  15031. +# CONFIG_BLK_DEV_BSG is not set
  15032. +CONFIG_GPIO_PCA953X=y
  15033. +CONFIG_ARCH_MXC=y
  15034. +CONFIG_MXC_DEBUG_BOARD=y
  15035. +CONFIG_SOC_IMX6Q=y
  15036. +CONFIG_SOC_IMX6SL=y
  15037. +# CONFIG_SWP_EMULATE is not set
  15038. +CONFIG_PCI=y
  15039. +CONFIG_PCIE_DW=y
  15040. +CONFIG_PCI_IMX6=y
  15041. +CONFIG_SMP=y
  15042. +CONFIG_VMSPLIT_2G=y
  15043. +CONFIG_PREEMPT_VOLUNTARY=y
  15044. +CONFIG_AEABI=y
  15045. +# CONFIG_OABI_COMPAT is not set
  15046. +CONFIG_HIGHMEM=y
  15047. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  15048. +CONFIG_CPU_FREQ=y
  15049. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  15050. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  15051. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  15052. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  15053. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  15054. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  15055. +CONFIG_ARM_IMX6_CPUFREQ=y
  15056. +CONFIG_CPU_IDLE=y
  15057. +CONFIG_VFP=y
  15058. +CONFIG_VFPv3=y
  15059. +CONFIG_NEON=y
  15060. +CONFIG_KERNEL_MODE_NEON=y
  15061. +CONFIG_BINFMT_MISC=m
  15062. +CONFIG_PM_RUNTIME=y
  15063. +CONFIG_PM_DEBUG=y
  15064. +CONFIG_PM_TEST_SUSPEND=y
  15065. +CONFIG_IOSCHED_BFQ=y
  15066. +CONFIG_CGROUP_BFQIO=y
  15067. +CONFIG_DEFAULT_BFQ=y
  15068. +CONFIG_DEFAULT_IOSCHED="bfq"
  15069. +CONFIG_NET=y
  15070. +CONFIG_PACKET=y
  15071. +CONFIG_UNIX=y
  15072. +CONFIG_INET=y
  15073. +CONFIG_IP_PNP=y
  15074. +CONFIG_IP_PNP_DHCP=y
  15075. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  15076. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  15077. +# CONFIG_INET_XFRM_MODE_BEET is not set
  15078. +# CONFIG_INET_LRO is not set
  15079. +CONFIG_IPV6=y
  15080. +CONFIG_NETFILTER=y
  15081. +CONFIG_VLAN_8021Q=y
  15082. +CONFIG_WIRELESS=y
  15083. +CONFIG_WIRELESS_EXT=y
  15084. +CONFIG_WEXT_CORE=y
  15085. +CONFIG_WEXT_PROC=y
  15086. +CONFIG_WEXT_SPY=y
  15087. +CONFIG_WEXT_PRIV=y
  15088. +CONFIG_CFG80211=y
  15089. +CONFIG_ETHERNET=y
  15090. +# CONFIG_NET_VENDOR_BROADCOM is not set
  15091. +# CONFIG_NET_VENDOR_CIRRUS is not set
  15092. +# CONFIG_NET_VENDOR_FARADAY
  15093. +# CONFIG_NET_VENDOR_INTEL
  15094. +# CONFIG_NET_VENDOR_I825XX
  15095. +# CONFIG_NET_VENDOR_MARVELL
  15096. +# CONFIG_NET_VENDOR_MICROCHIP
  15097. +# CONFIG_NET_VENDOR_MICROCHIP=y
  15098. +# CONFIG_ENC28J60 is not set
  15099. +# CONFIG_NET_VENDOR_NATSEMI=y
  15100. +# CONFIG_NET_VENDOR_8390=y
  15101. +# CONFIG_AX88796 is not set
  15102. +# CONFIG_ETHOC is not set
  15103. +# CONFIG_SH_ETH is not set
  15104. +# CONFIG_NET_VENDOR_SEEQ=y
  15105. +# CONFIG_NET_VENDOR_SMSC=y
  15106. +# CONFIG_SMC91X is not set
  15107. +# CONFIG_SMC911X is not set
  15108. +# CONFIG_SMSC911X is not set
  15109. +# CONFIG_NET_VENDOR_STMICRO=y
  15110. +# CONFIG_STMMAC_ETH is not set
  15111. +# CONFIG_NET_VENDOR_VIA=y
  15112. +# CONFIG_VIA_VELOCITY is not set
  15113. +# CONFIG_NET_VENDOR_WIZNET=y
  15114. +CONFIG_NET_VENDOR_FREESCALE=y
  15115. +CONFIG_FEC=y
  15116. +CONFIG_PHYLIB=y
  15117. +CONFIG_AT803X_PHY=y
  15118. +CONFIG_WLAN=y
  15119. +CONFIG_BRCMUTIL=m
  15120. +CONFIG_BRCMFMAC=m
  15121. +CONFIG_BRCMFMAC_SDIO=y
  15122. +CONFIG_DEVTMPFS=y
  15123. +CONFIG_DEVTMPFS_MOUNT=y
  15124. +# CONFIG_STANDALONE is not set
  15125. +CONFIG_DMA_CMA=y
  15126. +CONFIG_CMA=y
  15127. +CONFIG_CMA_SIZE_MBYTES=256
  15128. +CONFIG_CONNECTOR=y
  15129. +# CONFIG_MTD is not set
  15130. +CONFIG_BLK_DEV_LOOP=y
  15131. +CONFIG_BLK_DEV_RAM=y
  15132. +CONFIG_BLK_DEV_RAM_SIZE=65536
  15133. +# CONFIG_SCSI_PROC_FS is not set
  15134. +CONFIG_BLK_DEV_SD=y
  15135. +CONFIG_SCSI_MULTI_LUN=y
  15136. +CONFIG_SCSI_CONSTANTS=y
  15137. +CONFIG_SCSI_LOGGING=y
  15138. +CONFIG_SCSI_SCAN_ASYNC=y
  15139. +# CONFIG_SCSI_LOWLEVEL is not set
  15140. +CONFIG_ATA=y
  15141. +CONFIG_SATA_AHCI_PLATFORM=y
  15142. +CONFIG_AHCI_IMX=y
  15143. +CONFIG_NETDEVICES=y
  15144. +CONFIG_INPUT_EVDEV=y
  15145. +# CONFIG_INPUT_EVBUG is not set
  15146. +CONFIG_KEYBOARD_GPIO=y
  15147. +CONFIG_KEYBOARD_IMX=y
  15148. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  15149. +# CONFIG_KEYBOARD_ATKBD is not set
  15150. +# CONFIG_MOUSE_PS2 is not set
  15151. +CONFIG_INPUT_MISC=y
  15152. +CONFIG_SERIO_SERPORT=m
  15153. +CONFIG_VT_HW_CONSOLE_BINDING=y
  15154. +# CONFIG_LEGACY_PTYS is not set
  15155. +# CONFIG_DEVKMEM is not set
  15156. +CONFIG_SERIAL_IMX=y
  15157. +CONFIG_SERIAL_IMX_CONSOLE=y
  15158. +CONFIG_SERIAL_FSL_LPUART=y
  15159. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  15160. +CONFIG_FSL_OTP=y
  15161. +CONFIG_GPIO_MXC=y
  15162. +# CONFIG_I2C_COMPAT is not set
  15163. +CONFIG_I2C_CHARDEV=y
  15164. +# CONFIG_I2C_HELPER_AUTO is not set
  15165. +CONFIG_I2C_ALGOPCF=m
  15166. +CONFIG_I2C_ALGOPCA=m
  15167. +CONFIG_I2C_IMX=y
  15168. +CONFIG_SPI=y
  15169. +CONFIG_SPI_IMX=y
  15170. +CONFIG_GPIO_SYSFS=y
  15171. +CONFIG_POWER_SUPPLY=y
  15172. +CONFIG_THERMAL=y
  15173. +CONFIG_CPU_THERMAL=y
  15174. +CONFIG_IMX_THERMAL=y
  15175. +CONFIG_DEVICE_THERMAL=y
  15176. +CONFIG_WATCHDOG=y
  15177. +CONFIG_IMX2_WDT=y
  15178. +CONFIG_MFD_DA9052_I2C=y
  15179. +CONFIG_MFD_MC13XXX_SPI=y
  15180. +CONFIG_MFD_MC13XXX_I2C=y
  15181. +CONFIG_MFD_SI476X_CORE=y
  15182. +CONFIG_REGULATOR=y
  15183. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  15184. +CONFIG_REGULATOR_ANATOP=y
  15185. +CONFIG_REGULATOR_PFUZE100=y
  15186. +CONFIG_MEDIA_SUPPORT=y
  15187. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  15188. +# CONFIG_MEDIA_RADIO_SUPPORT is not set
  15189. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  15190. +# CONFIG_MEDIA_USB_SUPPORT isnot set
  15191. +# CONFIG_USB_VIDEO_CLASS is not set
  15192. +# CONFIG_RADIO_ADAPTERS is not set
  15193. +CONFIG_V4L_PLATFORM_DRIVERS=y
  15194. +CONFIG_VIDEO_MXC_OUTPUT=y
  15195. +CONFIG_VIDEO_MXC_CAPTURE=m
  15196. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  15197. +CONFIG_MXC_CAMERA_OV5640=m
  15198. +CONFIG_MXC_CAMERA_OV5642=m
  15199. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  15200. +CONFIG_MXC_TVIN_ADV7180=m
  15201. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  15202. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  15203. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  15204. +CONFIG_SOC_CAMERA=y
  15205. +CONFIG_SOC_CAMERA_OV2640=y
  15206. +CONFIG_DRM=y
  15207. +CONFIG_DRM_VIVANTE=y
  15208. +CONFIG_FB=y
  15209. +# CONFIG_FB_MX3 is not set
  15210. +CONFIG_FB_MXC_SYNC_PANEL=y
  15211. +CONFIG_FB_MXC_LDB=y
  15212. +CONFIG_FB_MXC_HDMI=y
  15213. +CONFIG_FRAMEBUFFER_CONSOLE=y
  15214. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  15215. +CONFIG_FONTS=y
  15216. +CONFIG_FONT_8x8=y
  15217. +CONFIG_FONT_8x16=y
  15218. +CONFIG_LOGO=y
  15219. +CONFIG_SOUND=y
  15220. +CONFIG_SND=y
  15221. +CONFIG_SND_USB_AUDIO=m
  15222. +CONFIG_SND_SOC=y
  15223. +CONFIG_SND_IMX_SOC=y
  15224. +CONFIG_SND_SOC_IMX_SGTL5000=y
  15225. +CONFIG_SND_SOC_IMX_SPDIF=y
  15226. +CONFIG_SND_SOC_IMX_HDMI=y
  15227. +CONFIG_USB=y
  15228. +CONFIG_USB_EHCI_HCD=y
  15229. +CONFIG_USB_STORAGE=y
  15230. +CONFIG_USB_CHIPIDEA=y
  15231. +CONFIG_USB_CHIPIDEA_UDC=y
  15232. +CONFIG_USB_CHIPIDEA_HOST=y
  15233. +CONFIG_USB_PHY=y
  15234. +CONFIG_NOP_USB_XCEIV=y
  15235. +CONFIG_USB_MXS_PHY=y
  15236. +CONFIG_USB_GADGET=y
  15237. +CONFIG_USB_ZERO=m
  15238. +CONFIG_USB_ETH=m
  15239. +CONFIG_USB_MASS_STORAGE=m
  15240. +CONFIG_USB_G_SERIAL=m
  15241. +CONFIG_MMC=y
  15242. +CONFIG_MMC_UNSAFE_RESUME=y
  15243. +CONFIG_MMC_SDHCI=y
  15244. +CONFIG_MMC_SDHCI_PLTFM=y
  15245. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  15246. +CONFIG_MXC_IPU=y
  15247. +CONFIG_MXC_GPU_VIV=y
  15248. +CONFIG_MXC_ASRC=y
  15249. +CONFIG_MXC_HDMI_CEC=y
  15250. +CONFIG_MXC_MIPI_CSI2=y
  15251. +CONFIG_MXC_MLB150=m
  15252. +CONFIG_NEW_LEDS=y
  15253. +CONFIG_LEDS_CLASS=y
  15254. +CONFIG_LEDS_GPIO=y
  15255. +CONFIG_LEDS_TRIGGERS=y
  15256. +CONFIG_LEDS_TRIGGER_GPIO=y
  15257. +CONFIG_RTC_CLASS=y
  15258. +CONFIG_RTC_DRV_MXC=y
  15259. +CONFIG_RTC_DRV_SNVS=y
  15260. +CONFIG_RTC_DRV_PCF8523=y
  15261. +CONFIG_DMADEVICES=y
  15262. +CONFIG_MXC_PXP_V2=y
  15263. +CONFIG_IMX_SDMA=y
  15264. +CONFIG_MXS_DMA=y
  15265. +CONFIG_SRAM=y
  15266. +CONFIG_STAGING=y
  15267. +CONFIG_COMMON_CLK_DEBUG=y
  15268. +# CONFIG_IOMMU_SUPPORT is not set
  15269. +CONFIG_PWM=y
  15270. +CONFIG_PWM_SYSFS=y
  15271. +CONFIG_PWM_IMX=y
  15272. +CONFIG_IRQCHIP=y
  15273. +CONFIG_ARM_GIC=y
  15274. +# CONFIG_IPACK_BUS is not set
  15275. +CONFIG_ARCH_HAS_RESET_CONTROLLER=y
  15276. +CONFIG_RESET_CONTROLLER=y
  15277. +CONFIG_RESET_GPIO=y
  15278. +CONFIG_EXT4_FS=y
  15279. +CONFIG_EXT4_USE_FOR_EXT23=y
  15280. +CONFIG_EXT4_FS_XATTR=y
  15281. +CONFIG_EXT4_FS_POSIX_ACL=y
  15282. +CONFIG_EXT4_FS_SECURITY=y
  15283. +CONFIG_QUOTA=y
  15284. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  15285. +# CONFIG_PRINT_QUOTA_WARNING is not set
  15286. +CONFIG_AUTOFS4_FS=y
  15287. +CONFIG_FUSE_FS=y
  15288. +CONFIG_ISO9660_FS=m
  15289. +CONFIG_JOLIET=y
  15290. +CONFIG_ZISOFS=y
  15291. +CONFIG_UDF_FS=m
  15292. +CONFIG_MSDOS_FS=m
  15293. +CONFIG_VFAT_FS=y
  15294. +CONFIG_TMPFS=y
  15295. +CONFIG_JFFS2_FS=y
  15296. +CONFIG_UBIFS_FS=y
  15297. +CONFIG_NFS_FS=y
  15298. +CONFIG_NFS_V3_ACL=y
  15299. +CONFIG_NFS_V4=y
  15300. +CONFIG_ROOT_NFS=y
  15301. +CONFIG_NLS_DEFAULT="cp437"
  15302. +CONFIG_NLS_CODEPAGE_437=y
  15303. +CONFIG_NLS_ASCII=y
  15304. +CONFIG_NLS_ISO8859_1=y
  15305. +CONFIG_NLS_ISO8859_15=m
  15306. +CONFIG_NLS_UTF8=y
  15307. +CONFIG_MAGIC_SYSRQ=y
  15308. +# CONFIG_SCHED_DEBUG is not set
  15309. +# CONFIG_DEBUG_BUGVERBOSE is not set
  15310. +# CONFIG_FTRACE is not set
  15311. +CONFIG_SECURITYFS=y
  15312. +CONFIG_CRYPTO_USER=y
  15313. +CONFIG_CRYPTO_TEST=m
  15314. +CONFIG_CRYPTO_CCM=y
  15315. +CONFIG_CRYPTO_GCM=y
  15316. +CONFIG_CRYPTO_CBC=y
  15317. +CONFIG_CRYPTO_CTS=y
  15318. +CONFIG_CRYPTO_ECB=y
  15319. +CONFIG_CRYPTO_LRW=y
  15320. +CONFIG_CRYPTO_XTS=y
  15321. +CONFIG_CRYPTO_MD4=y
  15322. +CONFIG_CRYPTO_MD5=y
  15323. +CONFIG_CRYPTO_MICHAEL_MIC=y
  15324. +CONFIG_CRYPTO_RMD128=y
  15325. +CONFIG_CRYPTO_RMD160=y
  15326. +CONFIG_CRYPTO_RMD256=y
  15327. +CONFIG_CRYPTO_RMD320=y
  15328. +CONFIG_CRYPTO_SHA1=y
  15329. +CONFIG_CRYPTO_SHA256=y
  15330. +CONFIG_CRYPTO_SHA512=y
  15331. +CONFIG_CRYPTO_TGR192=y
  15332. +CONFIG_CRYPTO_WP512=y
  15333. +CONFIG_CRYPTO_BLOWFISH=y
  15334. +CONFIG_CRYPTO_CAMELLIA=y
  15335. +CONFIG_CRYPTO_DES=y
  15336. +CONFIG_CRYPTO_TWOFISH=y
  15337. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  15338. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  15339. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  15340. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  15341. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  15342. +CONFIG_CRYPTO_AES_ARM_BS=y
  15343. +CONFIG_CRC_CCITT=m
  15344. +CONFIG_CRC_T10DIF=y
  15345. +CONFIG_CRC7=m
  15346. +CONFIG_LIBCRC32C=m
  15347. +# CONFIG_MXC_MMA8451 is not set
  15348. +CONFIG_RC_CORE=m
  15349. +CONFIG_RC_DECODERS=y
  15350. +CONFIG_LIRC=m
  15351. +CONFIG_RC_LOOPBACK=m
  15352. +CONFIG_RC_MAP=m
  15353. +CONFIG_RC_DEVICES=y
  15354. +CONFIG_RC_ATI_REMOTE=m
  15355. +CONFIG_IR_NEC_DECODER=m
  15356. +CONFIG_IR_RC5_DECODER=m
  15357. +CONFIG_IR_RC6_DECODER=m
  15358. +CONFIG_IR_JVC_DECODER=m
  15359. +CONFIG_IR_SONY_DECODER=m
  15360. +CONFIG_IR_RC5_SZ_DECODER=m
  15361. +CONFIG_IR_SANYO_DECODER=m
  15362. +CONFIG_IR_MCE_KBD_DECODER=m
  15363. +CONFIG_IR_LIRC_CODEC=m
  15364. +CONFIG_IR_IMON=m
  15365. +CONFIG_IR_MCEUSB=m
  15366. +CONFIG_IR_ITE_CIR=m
  15367. +CONFIG_IR_NUVOTON=m
  15368. +CONFIG_IR_FINTEK=m
  15369. +CONFIG_IR_REDRAT3=m
  15370. +CONFIG_IR_ENE=m
  15371. +CONFIG_IR_STREAMZAP=m
  15372. +CONFIG_IR_WINBOND_CIR=m
  15373. +CONFIG_IR_IGUANA=m
  15374. +CONFIG_IR_TTUSBIR=m
  15375. +CONFIG_IR_GPIO_CIR=m
  15376. diff -Nur linux-3.14.17/arch/arm/configs/imx_v7_cbi_hb_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_defconfig
  15377. --- linux-3.14.17/arch/arm/configs/imx_v7_cbi_hb_defconfig 1970-01-01 01:00:00.000000000 +0100
  15378. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_cbi_hb_defconfig 2014-09-11 18:05:52.798001191 +0200
  15379. @@ -0,0 +1,5138 @@
  15380. +#
  15381. +# Automatically generated make config: don't edit
  15382. +#
  15383. +CONFIG_MMU=y
  15384. +CONFIG_HOTPLUG_CPU=y
  15385. +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set
  15386. +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set
  15387. +CONFIG_LOCALVERSION=""
  15388. +CONFIG_CROSS_COMPILE=""
  15389. +CONFIG_DEFAULT_HOSTNAME="(none)"
  15390. +
  15391. +#
  15392. +# Code maturity level options
  15393. +#
  15394. +CONFIG_EXPERIMENTAL=y
  15395. +CONFIG_HOTPLUG=y
  15396. +CONFIG_UEVENT_HELPER_PATH=""
  15397. +CONFIG_PREVENT_FIRMWARE_BUILD=y
  15398. +
  15399. +CONFIG_BUILD_DOCSRC=y
  15400. +
  15401. +#
  15402. +# General setup
  15403. +#
  15404. +CONFIG_KERNEL_LZO=y
  15405. +# CONFIG_KERNEL_BZIP2 is not set
  15406. +# CONFIG_KERNEL_LZMA is not set
  15407. +CONFIG_SWAP=y
  15408. +CONFIG_BSD_PROCESS_ACCT=y
  15409. +CONFIG_BSD_PROCESS_ACCT_V3=y
  15410. +# CONFIG_COMPILE_TEST is not set
  15411. +CONFIG_TASKSTATS=y
  15412. +CONFIG_TASK_DELAY_ACCT=y
  15413. +CONFIG_TASK_XACCT=y
  15414. +CONFIG_TASK_IO_ACCOUNTING=y
  15415. +CONFIG_SYSCTL=y
  15416. +# CONFIG_IKCONFIG is not set
  15417. +# CONFIG_EMBEDDED is not set
  15418. +CONFIG_KALLSYMS=y
  15419. +CONFIG_KALLSYMS_ALL=y
  15420. +CONFIG_FUTEX=y
  15421. +CONFIG_EPOLL=y
  15422. +CONFIG_IOSCHED_NOOP=y
  15423. +CONFIG_IOSCHED_DEADLINE=y
  15424. +CONFIG_IOSCHED_CFQ=y
  15425. +CONFIG_CFQ_GROUP_IOSCHED=y
  15426. +CONFIG_IOSCHED_BFQ=y
  15427. +CONFIG_CGROUP_BFQIO=y
  15428. +CONFIG_DEFAULT_BFQ=y
  15429. +CONFIG_DEFAULT_IOSCHED="bfq"
  15430. +# CONFIG_CHECKPOINT_RESTORE is not set
  15431. +CONFIG_NAMESPACES=y
  15432. +CONFIG_PID_NS=y
  15433. +CONFIG_UTS_NS=y
  15434. +CONFIG_IPC_NS=y
  15435. +CONFIG_NET_NS=y
  15436. +CONFIG_USER_NS=y
  15437. +# CONFIG_UIDGID_STRICT_TYPE_CHECKS is not set
  15438. +CONFIG_SYSVIPC=y
  15439. +CONFIG_FHANDLE=y
  15440. +CONFIG_NO_HZ=y
  15441. +CONFIG_HIGH_RES_TIMERS=y
  15442. +CONFIG_LOG_BUF_SHIFT=18
  15443. +CONFIG_CGROUPS=y
  15444. +CONFIG_RELAY=y
  15445. +CONFIG_BLK_DEV_INITRD=y
  15446. +CONFIG_EXPERT=y
  15447. +CONFIG_PERF_EVENTS=y
  15448. +# CONFIG_SLUB_DEBUG is not set
  15449. +# CONFIG_COMPAT_BRK is not set
  15450. +CONFIG_MODULES=y
  15451. +CONFIG_MODULE_UNLOAD=y
  15452. +CONFIG_MODVERSIONS=y
  15453. +CONFIG_MODULE_SRCVERSION_ALL=y
  15454. +
  15455. +CONFIG_POSIX_MQUEUE=y
  15456. +CONFIG_PREEMPT_VOLUNTARY=y
  15457. +
  15458. +CONFIG_SLUB=y
  15459. +CONFIG_SLUB_CPU_PARTIAL=y
  15460. +# CONFIG_SLUB_STATS is not set
  15461. +# CONFIG_SLUB_DEBUG_ON is not set
  15462. +
  15463. +# CONFIG_AD525X_DPOT is not set
  15464. +# CONFIG_ATMEL_PWM is not set
  15465. +# CONFIG_IWMC3200TOP is not set
  15466. +# CONFIG_BLK_DEV_BSG is not set
  15467. +
  15468. +# MX6 specific kernel configuration
  15469. +CONFIG_GPIO_PCA953X=y
  15470. +CONFIG_ARCH_MXC=y
  15471. +CONFIG_MXC_DEBUG_BOARD=y
  15472. +CONFIG_SOC_IMX6Q=y
  15473. +CONFIG_SOC_IMX6SL=y
  15474. +# CONFIG_SWP_EMULATE is not set
  15475. +CONFIG_PCI=y
  15476. +CONFIG_PCIE_DW=y
  15477. +CONFIG_PCI_IMX6=y
  15478. +CONFIG_SMP=y
  15479. +CONFIG_VMSPLIT_2G=y
  15480. +CONFIG_AEABI=y
  15481. +# CONFIG_OABI_COMPAT is not set
  15482. +CONFIG_HIGHMEM=y
  15483. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  15484. +CONFIG_CPU_FREQ=y
  15485. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  15486. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  15487. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  15488. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  15489. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  15490. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  15491. +CONFIG_ARM_IMX6_CPUFREQ=y
  15492. +CONFIG_CPU_IDLE=y
  15493. +CONFIG_VFP=y
  15494. +CONFIG_VFPv3=y
  15495. +CONFIG_NEON=y
  15496. +CONFIG_KERNEL_MODE_NEON=y
  15497. +CONFIG_BINFMT_MISC=m
  15498. +CONFIG_PM_RUNTIME=y
  15499. +CONFIG_PM_DEBUG=y
  15500. +CONFIG_PM_TEST_SUSPEND=y
  15501. +CONFIG_NET=y
  15502. +CONFIG_PACKET=y
  15503. +CONFIG_UNIX=y
  15504. +CONFIG_INET=y
  15505. +CONFIG_IP_PNP=y
  15506. +CONFIG_IP_PNP_DHCP=y
  15507. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  15508. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  15509. +# CONFIG_INET_XFRM_MODE_BEET is not set
  15510. +# CONFIG_INET_LRO is not set
  15511. +CONFIG_IPV6=y
  15512. +CONFIG_NETFILTER=y
  15513. +CONFIG_VLAN_8021Q=y
  15514. +CONFIG_WIRELESS=y
  15515. +CONFIG_WIRELESS_EXT=y
  15516. +CONFIG_WEXT_CORE=y
  15517. +CONFIG_WEXT_PROC=y
  15518. +CONFIG_WEXT_SPY=y
  15519. +CONFIG_WEXT_PRIV=y
  15520. +CONFIG_CFG80211=y
  15521. +CONFIG_ETHERNET=y
  15522. +# CONFIG_NET_VENDOR_BROADCOM is not set
  15523. +# CONFIG_NET_VENDOR_CIRRUS is not set
  15524. +# CONFIG_NET_VENDOR_FARADAY
  15525. +# CONFIG_NET_VENDOR_INTEL
  15526. +# CONFIG_NET_VENDOR_I825XX
  15527. +# CONFIG_NET_VENDOR_MARVELL
  15528. +# CONFIG_NET_VENDOR_MICROCHIP
  15529. +# CONFIG_NET_VENDOR_MICROCHIP=y
  15530. +# CONFIG_ENC28J60 is not set
  15531. +# CONFIG_NET_VENDOR_NATSEMI=y
  15532. +# CONFIG_NET_VENDOR_8390=y
  15533. +# CONFIG_AX88796 is not set
  15534. +# CONFIG_ETHOC is not set
  15535. +# CONFIG_SH_ETH is not set
  15536. +# CONFIG_NET_VENDOR_SEEQ=y
  15537. +# CONFIG_NET_VENDOR_SMSC=y
  15538. +# CONFIG_SMC91X is not set
  15539. +# CONFIG_SMC911X is not set
  15540. +# CONFIG_SMSC911X is not set
  15541. +# CONFIG_NET_VENDOR_STMICRO=y
  15542. +# CONFIG_STMMAC_ETH is not set
  15543. +# CONFIG_NET_VENDOR_VIA=y
  15544. +# CONFIG_VIA_VELOCITY is not set
  15545. +# CONFIG_NET_VENDOR_WIZNET=y
  15546. +CONFIG_NET_VENDOR_FREESCALE=y
  15547. +CONFIG_FEC=y
  15548. +CONFIG_PHYLIB=y
  15549. +CONFIG_AT803X_PHY=y
  15550. +CONFIG_WLAN=y
  15551. +CONFIG_BRCMUTIL=m
  15552. +CONFIG_BRCMFMAC=m
  15553. +CONFIG_BRCMFMAC_SDIO=y
  15554. +CONFIG_DEVTMPFS=y
  15555. +CONFIG_DEVTMPFS_MOUNT=y
  15556. +# CONFIG_STANDALONE is not set
  15557. +CONFIG_DMA_CMA=y
  15558. +CONFIG_CMA=y
  15559. +CONFIG_CMA_SIZE_MBYTES=256
  15560. +CONFIG_CONNECTOR=y
  15561. +# CONFIG_MTD is not set
  15562. +CONFIG_BLK_DEV_LOOP=y
  15563. +CONFIG_BLK_DEV_RAM=y
  15564. +CONFIG_BLK_DEV_RAM_SIZE=65536
  15565. +# CONFIG_SCSI_PROC_FS is not set
  15566. +CONFIG_BLK_DEV_SD=y
  15567. +CONFIG_SCSI_MULTI_LUN=y
  15568. +CONFIG_SCSI_CONSTANTS=y
  15569. +CONFIG_SCSI_LOGGING=y
  15570. +CONFIG_SCSI_SCAN_ASYNC=y
  15571. +# CONFIG_SCSI_LOWLEVEL is not set
  15572. +CONFIG_ATA=y
  15573. +CONFIG_SATA_AHCI_PLATFORM=y
  15574. +CONFIG_AHCI_IMX=y
  15575. +CONFIG_NETDEVICES=y
  15576. +CONFIG_INPUT_EVDEV=y
  15577. +# CONFIG_INPUT_EVBUG is not set
  15578. +CONFIG_KEYBOARD_GPIO=y
  15579. +CONFIG_KEYBOARD_IMX=y
  15580. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  15581. +# CONFIG_KEYBOARD_ATKBD is not set
  15582. +# CONFIG_MOUSE_PS2 is not set
  15583. +CONFIG_INPUT_MISC=y
  15584. +CONFIG_SERIO_SERPORT=m
  15585. +CONFIG_VT_HW_CONSOLE_BINDING=y
  15586. +# CONFIG_LEGACY_PTYS is not set
  15587. +# CONFIG_DEVKMEM is not set
  15588. +CONFIG_SERIAL_IMX=y
  15589. +CONFIG_SERIAL_IMX_CONSOLE=y
  15590. +CONFIG_SERIAL_FSL_LPUART=y
  15591. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  15592. +CONFIG_FSL_OTP=y
  15593. +CONFIG_GPIO_MXC=y
  15594. +# CONFIG_I2C_COMPAT is not set
  15595. +CONFIG_I2C_CHARDEV=y
  15596. +# CONFIG_I2C_HELPER_AUTO is not set
  15597. +CONFIG_I2C_ALGOPCF=m
  15598. +CONFIG_I2C_ALGOPCA=m
  15599. +CONFIG_I2C_IMX=y
  15600. +CONFIG_SPI=y
  15601. +CONFIG_SPI_IMX=y
  15602. +CONFIG_GPIO_SYSFS=y
  15603. +CONFIG_POWER_SUPPLY=y
  15604. +CONFIG_THERMAL=y
  15605. +CONFIG_CPU_THERMAL=y
  15606. +CONFIG_IMX_THERMAL=y
  15607. +CONFIG_DEVICE_THERMAL=y
  15608. +CONFIG_WATCHDOG=y
  15609. +CONFIG_IMX2_WDT=y
  15610. +CONFIG_MFD_DA9052_I2C=y
  15611. +CONFIG_MFD_MC13XXX_SPI=y
  15612. +CONFIG_MFD_MC13XXX_I2C=y
  15613. +CONFIG_MFD_SI476X_CORE=y
  15614. +CONFIG_REGULATOR=y
  15615. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  15616. +CONFIG_REGULATOR_ANATOP=y
  15617. +CONFIG_REGULATOR_PFUZE100=y
  15618. +CONFIG_MEDIA_SUPPORT=y
  15619. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  15620. +# CONFIG_MEDIA_RADIO_SUPPORT is not set
  15621. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  15622. +CONFIG_MEDIA_USB_SUPPORT=y
  15623. +CONFIG_USB_VIDEO_CLASS=m
  15624. +# CONFIG_RADIO_ADAPTERS is not set
  15625. +CONFIG_V4L_PLATFORM_DRIVERS=y
  15626. +CONFIG_VIDEO_MXC_OUTPUT=y
  15627. +CONFIG_VIDEO_MXC_CAPTURE=m
  15628. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  15629. +CONFIG_MXC_CAMERA_OV5640=m
  15630. +CONFIG_MXC_CAMERA_OV5642=m
  15631. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  15632. +CONFIG_MXC_TVIN_ADV7180=m
  15633. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  15634. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  15635. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  15636. +CONFIG_SOC_CAMERA=y
  15637. +CONFIG_SOC_CAMERA_OV2640=y
  15638. +CONFIG_DRM=y
  15639. +CONFIG_DRM_VIVANTE=y
  15640. +CONFIG_FB=y
  15641. +# CONFIG_FB_MX3 is not set
  15642. +CONFIG_FB_MXC_SYNC_PANEL=y
  15643. +CONFIG_FB_MXC_LDB=y
  15644. +CONFIG_FB_MXC_HDMI=y
  15645. +CONFIG_FRAMEBUFFER_CONSOLE=y
  15646. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  15647. +CONFIG_FONTS=y
  15648. +CONFIG_FONT_8x8=y
  15649. +CONFIG_FONT_8x16=y
  15650. +CONFIG_LOGO=y
  15651. +CONFIG_SOUND=y
  15652. +CONFIG_SND=y
  15653. +CONFIG_SND_USB_AUDIO=m
  15654. +CONFIG_SND_SOC=y
  15655. +CONFIG_SND_IMX_SOC=y
  15656. +CONFIG_SND_SOC_IMX_SGTL5000=y
  15657. +CONFIG_SND_SOC_IMX_SPDIF=y
  15658. +CONFIG_SND_SOC_IMX_HDMI=y
  15659. +CONFIG_USB=y
  15660. +CONFIG_USB_EHCI_HCD=y
  15661. +CONFIG_USB_STORAGE=y
  15662. +CONFIG_USB_CHIPIDEA=y
  15663. +CONFIG_USB_CHIPIDEA_UDC=y
  15664. +CONFIG_USB_CHIPIDEA_HOST=y
  15665. +CONFIG_USB_PHY=y
  15666. +CONFIG_NOP_USB_XCEIV=y
  15667. +CONFIG_USB_MXS_PHY=y
  15668. +CONFIG_USB_GADGET=y
  15669. +CONFIG_USB_ZERO=m
  15670. +CONFIG_USB_ETH=m
  15671. +CONFIG_USB_MASS_STORAGE=m
  15672. +CONFIG_USB_G_SERIAL=m
  15673. +CONFIG_MMC=y
  15674. +CONFIG_MMC_UNSAFE_RESUME=y
  15675. +CONFIG_MMC_SDHCI=y
  15676. +CONFIG_MMC_SDHCI_PLTFM=y
  15677. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  15678. +CONFIG_MXC_IPU=y
  15679. +CONFIG_MXC_GPU_VIV=y
  15680. +CONFIG_MXC_ASRC=y
  15681. +CONFIG_MXC_HDMI_CEC=y
  15682. +CONFIG_MXC_MIPI_CSI2=y
  15683. +CONFIG_MXC_MLB150=m
  15684. +CONFIG_NEW_LEDS=y
  15685. +CONFIG_LEDS_CLASS=y
  15686. +CONFIG_LEDS_GPIO=y
  15687. +CONFIG_LEDS_TRIGGERS=y
  15688. +CONFIG_LEDS_TRIGGER_GPIO=y
  15689. +CONFIG_RTC_CLASS=y
  15690. +CONFIG_RTC_DRV_MXC=y
  15691. +CONFIG_RTC_DRV_SNVS=y
  15692. +CONFIG_RTC_DRV_PCF8523=y
  15693. +CONFIG_DMADEVICES=y
  15694. +CONFIG_MXC_PXP_V2=y
  15695. +CONFIG_IMX_SDMA=y
  15696. +CONFIG_MXS_DMA=y
  15697. +CONFIG_SRAM=y
  15698. +CONFIG_STAGING=y
  15699. +CONFIG_COMMON_CLK_DEBUG=y
  15700. +# CONFIG_IOMMU_SUPPORT is not set
  15701. +CONFIG_PWM=y
  15702. +CONFIG_PWM_SYSFS=y
  15703. +CONFIG_PWM_IMX=y
  15704. +CONFIG_IRQCHIP=y
  15705. +CONFIG_ARM_GIC=y
  15706. +CONFIG_ARCH_HAS_RESET_CONTROLLER=y
  15707. +CONFIG_RESET_CONTROLLER=y
  15708. +CONFIG_RESET_GPIO=y
  15709. +CONFIG_EXT4_FS=y
  15710. +CONFIG_EXT4_USE_FOR_EXT23=y
  15711. +CONFIG_EXT4_FS_XATTR=y
  15712. +CONFIG_EXT4_FS_POSIX_ACL=y
  15713. +CONFIG_EXT4_FS_SECURITY=y
  15714. +CONFIG_QUOTA=y
  15715. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  15716. +# CONFIG_PRINT_QUOTA_WARNING is not set
  15717. +CONFIG_AUTOFS4_FS=y
  15718. +CONFIG_FUSE_FS=y
  15719. +CONFIG_ISO9660_FS=m
  15720. +CONFIG_JOLIET=y
  15721. +CONFIG_ZISOFS=y
  15722. +CONFIG_UDF_FS=m
  15723. +CONFIG_MSDOS_FS=m
  15724. +CONFIG_VFAT_FS=y
  15725. +CONFIG_TMPFS=y
  15726. +CONFIG_JFFS2_FS=y
  15727. +CONFIG_UBIFS_FS=y
  15728. +CONFIG_NFS_FS=y
  15729. +CONFIG_NFS_V3_ACL=y
  15730. +CONFIG_NFS_V4=y
  15731. +CONFIG_ROOT_NFS=y
  15732. +CONFIG_NLS_DEFAULT="cp437"
  15733. +CONFIG_NLS_CODEPAGE_437=y
  15734. +CONFIG_NLS_ASCII=y
  15735. +CONFIG_NLS_ISO8859_1=y
  15736. +CONFIG_NLS_ISO8859_15=m
  15737. +CONFIG_NLS_UTF8=y
  15738. +CONFIG_MAGIC_SYSRQ=y
  15739. +# CONFIG_SCHED_DEBUG is not set
  15740. +# CONFIG_DEBUG_BUGVERBOSE is not set
  15741. +# CONFIG_FTRACE is not set
  15742. +CONFIG_SECURITYFS=y
  15743. +CONFIG_CRYPTO_USER=y
  15744. +CONFIG_CRYPTO_TEST=m
  15745. +CONFIG_CRYPTO_CCM=y
  15746. +CONFIG_CRYPTO_GCM=y
  15747. +CONFIG_CRYPTO_CBC=y
  15748. +CONFIG_CRYPTO_CTS=y
  15749. +CONFIG_CRYPTO_ECB=y
  15750. +CONFIG_CRYPTO_LRW=y
  15751. +CONFIG_CRYPTO_XTS=y
  15752. +CONFIG_CRYPTO_MD4=y
  15753. +CONFIG_CRYPTO_MD5=y
  15754. +CONFIG_CRYPTO_MICHAEL_MIC=y
  15755. +CONFIG_CRYPTO_RMD128=y
  15756. +CONFIG_CRYPTO_RMD160=y
  15757. +CONFIG_CRYPTO_RMD256=y
  15758. +CONFIG_CRYPTO_RMD320=y
  15759. +CONFIG_CRYPTO_SHA1=y
  15760. +CONFIG_CRYPTO_SHA256=y
  15761. +CONFIG_CRYPTO_SHA512=y
  15762. +CONFIG_CRYPTO_TGR192=y
  15763. +CONFIG_CRYPTO_WP512=y
  15764. +CONFIG_CRYPTO_BLOWFISH=y
  15765. +CONFIG_CRYPTO_CAMELLIA=y
  15766. +CONFIG_CRYPTO_DES=y
  15767. +CONFIG_CRYPTO_TWOFISH=y
  15768. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  15769. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  15770. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  15771. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  15772. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  15773. +CONFIG_CRYPTO_AES_ARM_BS=y
  15774. +CONFIG_CRC_CCITT=m
  15775. +CONFIG_CRC_T10DIF=y
  15776. +CONFIG_CRC7=m
  15777. +CONFIG_LIBCRC32C=m
  15778. +# CONFIG_MXC_MMA8451 is not set
  15779. +
  15780. +#
  15781. +# Loadable module support
  15782. +#
  15783. +# CONFIG_MODULE_FORCE_LOAD is not set
  15784. +# -- MODULE_FORCE_UNLOAD is controlled by config-debug/nodebug
  15785. +
  15786. +# CONFIG_PCI_DEBUG is not set
  15787. +CONFIG_PCI_STUB=y
  15788. +CONFIG_PCI_IOV=y
  15789. +CONFIG_PCI_PRI=y
  15790. +CONFIG_PCI_PASID=y
  15791. +CONFIG_HT_IRQ=y
  15792. +CONFIG_PCI_MSI=y
  15793. +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
  15794. +CONFIG_PCIEPORTBUS=y
  15795. +CONFIG_PCIEAER=y
  15796. +CONFIG_PCIEASPM=y
  15797. +# CONFIG_PCIEASPM_DEBUG is not set
  15798. +CONFIG_PCIE_ECRC=y
  15799. +CONFIG_PCIEAER_INJECT=m
  15800. +CONFIG_HOTPLUG_PCI_PCIE=y
  15801. +CONFIG_HOTPLUG_PCI_FAKE=m
  15802. +
  15803. +# CONFIG_SGI_IOC4 is not set
  15804. +
  15805. +# CONFIG_ISA is not set
  15806. +# CONFIG_SCx200 is not set
  15807. +
  15808. +#
  15809. +# PCMCIA/CardBus support
  15810. +# FIXME: Deprecate Cardbus ?
  15811. +#
  15812. +CONFIG_PCMCIA=y
  15813. +CONFIG_PCMCIA_LOAD_CIS=y
  15814. +# CONFIG_PCMCIA_DEBUG is not set
  15815. +CONFIG_YENTA=m
  15816. +CONFIG_CARDBUS=y
  15817. +CONFIG_I82092=m
  15818. +CONFIG_PD6729=m
  15819. +
  15820. +CONFIG_PCCARD=y
  15821. +CONFIG_SDIO_UART=m
  15822. +# CONFIG_MMC_TEST is not set
  15823. +# CONFIG_MMC_DEBUG is not set
  15824. +# https://lists.fedoraproject.org/pipermail/kernel/2014-February/004889.html
  15825. +# CONFIG_MMC_CLKGATE is not set
  15826. +CONFIG_MMC_BLOCK=y
  15827. +CONFIG_MMC_BLOCK_MINORS=8
  15828. +CONFIG_MMC_BLOCK_BOUNCE=y
  15829. +CONFIG_MMC_SDHCI_PCI=m
  15830. +CONFIG_MMC_SDHCI_ACPI=m
  15831. +CONFIG_MMC_SDRICOH_CS=m
  15832. +CONFIG_MMC_TIFM_SD=m
  15833. +CONFIG_MMC_WBSD=m
  15834. +CONFIG_MMC_VIA_SDMMC=m
  15835. +CONFIG_MMC_CB710=m
  15836. +CONFIG_MMC_RICOH_MMC=y
  15837. +CONFIG_MMC_USHC=m
  15838. +CONFIG_MMC_REALTEK_PCI=m
  15839. +CONFIG_MMC_VUB300=m
  15840. +# CONFIG_MMC_SDHCI_PXAV2 is not set
  15841. +# CONFIG_MMC_SDHCI_PXAV3 is not set
  15842. +# CONFIG_MMC_SDHCI_OF_ARASAN is not set
  15843. +
  15844. +
  15845. +CONFIG_CB710_CORE=m
  15846. +# CONFIG_CB710_DEBUG is not set
  15847. +
  15848. +CONFIG_INFINIBAND=m
  15849. +CONFIG_INFINIBAND_MTHCA=m
  15850. +# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
  15851. +CONFIG_INFINIBAND_IPOIB=m
  15852. +CONFIG_INFINIBAND_IPOIB_DEBUG=y
  15853. +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
  15854. +CONFIG_INFINIBAND_IPOIB_CM=y
  15855. +CONFIG_INFINIBAND_SRP=m
  15856. +CONFIG_INFINIBAND_SRPT=m
  15857. +CONFIG_INFINIBAND_USER_MAD=m
  15858. +CONFIG_INFINIBAND_USER_ACCESS=m
  15859. +# CONFIG_INFINIBAND_EXPERIMENTAL_UVERBS_FLOW_STEERING is not set #staging
  15860. +CONFIG_INFINIBAND_IPATH=m
  15861. +CONFIG_INFINIBAND_ISER=m
  15862. +CONFIG_INFINIBAND_ISERT=m
  15863. +CONFIG_INFINIBAND_AMSO1100=m
  15864. +# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
  15865. +CONFIG_INFINIBAND_CXGB3=m
  15866. +CONFIG_INFINIBAND_CXGB4=m
  15867. +CONFIG_SCSI_CXGB3_ISCSI=m
  15868. +CONFIG_SCSI_CXGB4_ISCSI=m
  15869. +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set
  15870. +CONFIG_MLX4_INFINIBAND=m
  15871. +CONFIG_MLX5_INFINIBAND=m
  15872. +CONFIG_INFINIBAND_NES=m
  15873. +# CONFIG_INFINIBAND_NES_DEBUG is not set
  15874. +CONFIG_INFINIBAND_QIB=m
  15875. +CONFIG_INFINIBAND_QIB_DCA=y
  15876. +# CONFIG_INFINIBAND_OCRDMA is not set
  15877. +# CONFIG_INFINIBAND_USNIC is not set
  15878. +
  15879. +#
  15880. +# Executable file formats
  15881. +#
  15882. +CONFIG_BINFMT_ELF=y
  15883. +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
  15884. +# CONFIG_BINFMT_AOUT is not set
  15885. +CONFIG_BINFMT_SCRIPT=y
  15886. +
  15887. +#
  15888. +# Device Drivers
  15889. +#
  15890. +
  15891. +# CONFIG_COMMON_CLK_SI5351 is not set
  15892. +
  15893. +#
  15894. +# Generic Driver Options
  15895. +#
  15896. +CONFIG_FW_LOADER=y
  15897. +# CONFIG_FIRMWARE_IN_KERNEL is not set
  15898. +CONFIG_EXTRA_FIRMWARE=""
  15899. +
  15900. +# Give this a try in rawhide for now
  15901. +# CONFIG_FW_LOADER_USER_HELPER is not set
  15902. +
  15903. +
  15904. +
  15905. +#
  15906. +# Memory Technology Devices (MTD)
  15907. +#
  15908. +# CONFIG_MTD_TESTS is not set
  15909. +# CONFIG_MTD_REDBOOT_PARTS is not set
  15910. +# CONFIG_MTD_AR7_PARTS is not set
  15911. +# CONFIG_MTD_CMDLINE_PARTS is not set
  15912. +
  15913. +#
  15914. +# User Modules And Translation Layers
  15915. +#
  15916. +# CONFIG_MTD_CHAR is not set
  15917. +# CONFIG_MTD_BLKDEVS is not set
  15918. +# CONFIG_MTD_BLOCK is not set
  15919. +# CONFIG_MTD_BLOCK_RO is not set
  15920. +# CONFIG_FTL is not set
  15921. +# CONFIG_NFTL is not set
  15922. +# CONFIG_INFTL is not set
  15923. +# CONFIG_RFD_FTL is not set
  15924. +# CONFIG_SSFDC is not set
  15925. +# CONFIG_SM_FTL is not set
  15926. +# CONFIG_MTD_OOPS is not set
  15927. +# CONFIG_MTD_SWAP is not set
  15928. +
  15929. +#
  15930. +# RAM/ROM/Flash chip drivers
  15931. +#
  15932. +# CONFIG_MTD_CFI is not set
  15933. +# CONFIG_MTD_JEDECPROBE is not set
  15934. +CONFIG_MTD_MAP_BANK_WIDTH_1=y
  15935. +CONFIG_MTD_MAP_BANK_WIDTH_2=y
  15936. +CONFIG_MTD_MAP_BANK_WIDTH_4=y
  15937. +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
  15938. +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
  15939. +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
  15940. +CONFIG_MTD_CFI_I1=y
  15941. +CONFIG_MTD_CFI_I2=y
  15942. +# CONFIG_MTD_CFI_I4 is not set
  15943. +# CONFIG_MTD_CFI_I8 is not set
  15944. +# CONFIG_MTD_RAM is not set
  15945. +# CONFIG_MTD_ROM is not set
  15946. +# CONFIG_MTD_ABSENT is not set
  15947. +
  15948. +#
  15949. +# Mapping drivers for chip access
  15950. +#
  15951. +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
  15952. +# CONFIG_MTD_TS5500 is not set
  15953. +# CONFIG_MTD_INTEL_VR_NOR is not set
  15954. +# CONFIG_MTD_PLATRAM is not set
  15955. +
  15956. +# Self-contained MTD device drivers
  15957. +# CONFIG_MTD_PMC551 is not set
  15958. +# CONFIG_MTD_SLRAM is not set
  15959. +# CONFIG_MTD_PHRAM is not set
  15960. +# CONFIG_MTD_MTDRAM is not set
  15961. +# CONFIG_MTD_BLOCK2MTD is not set
  15962. +
  15963. +#
  15964. +# Disk-On-Chip Device Drivers
  15965. +#
  15966. +# CONFIG_MTD_DOCG3 is not set
  15967. +# CONFIG_MTD_NAND is not set
  15968. +# CONFIG_MTD_ONENAND is not set
  15969. +# CONFIG_MTD_NAND_VERIFY_WRITE is not set
  15970. +# CONFIG_MTD_NAND_ECC_BCH is not set
  15971. +# CONFIG_MTD_NAND_MUSEUM_IDS is not set
  15972. +# CONFIG_MTD_NAND_DISKONCHIP is not set
  15973. +# CONFIG_MTD_LPDDR is not set
  15974. +CONFIG_MTD_UBI=m
  15975. +CONFIG_MTD_UBI_WL_THRESHOLD=4096
  15976. +CONFIG_MTD_UBI_BEB_LIMIT=20
  15977. +# CONFIG_MTD_UBI_FASTMAP is not set
  15978. +# CONFIG_MTD_UBI_GLUEBI is not set
  15979. +
  15980. +#
  15981. +# Parallel port support
  15982. +#
  15983. +CONFIG_PARPORT=m
  15984. +CONFIG_PARPORT_PC=m
  15985. +CONFIG_PARPORT_SERIAL=m
  15986. +# CONFIG_PARPORT_PC_FIFO is not set
  15987. +# CONFIG_PARPORT_PC_SUPERIO is not set
  15988. +CONFIG_PARPORT_PC_PCMCIA=m
  15989. +CONFIG_PARPORT_1284=y
  15990. +# CONFIG_PARPORT_AX88796 is not set
  15991. +
  15992. +CONFIG_ACPI_PCI_SLOT=y
  15993. +CONFIG_HOTPLUG_PCI_ACPI=y
  15994. +CONFIG_HOTPLUG_PCI_ACPI_IBM=m
  15995. +
  15996. +#
  15997. +# Block devices
  15998. +#
  15999. +CONFIG_BLK_DEV=y
  16000. +CONFIG_BLK_DEV_NULL_BLK=m
  16001. +CONFIG_BLK_DEV_FD=m
  16002. +# CONFIG_PARIDE is not set
  16003. +CONFIG_ZRAM=m
  16004. +# CONFIG_ZRAM_DEBUG is not set
  16005. +CONFIG_ENHANCEIO=m
  16006. +
  16007. +CONFIG_BLK_CPQ_DA=m
  16008. +CONFIG_BLK_CPQ_CISS_DA=m
  16009. +CONFIG_CISS_SCSI_TAPE=y
  16010. +CONFIG_BLK_DEV_DAC960=m
  16011. +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
  16012. +CONFIG_BLK_DEV_DRBD=m
  16013. +CONFIG_BLK_DEV_UMEM=m
  16014. +CONFIG_BLK_DEV_LOOP_MIN_COUNT=0
  16015. +# Fedora 18 util-linux is the last release that supports cryptoloop devices
  16016. +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  16017. +CONFIG_BLK_DEV_NBD=m
  16018. +CONFIG_BLK_DEV_NVME=m
  16019. +CONFIG_BLK_DEV_SKD=m # 64-bit only but easier to put here
  16020. +CONFIG_BLK_DEV_OSD=m
  16021. +CONFIG_BLK_DEV_RAM_COUNT=16
  16022. +CONFIG_BLK_DEV_IO_TRACE=y
  16023. +
  16024. +CONFIG_BLK_DEV_BSGLIB=y
  16025. +CONFIG_BLK_DEV_INTEGRITY=y
  16026. +CONFIG_BLK_DEV_THROTTLING=y
  16027. +# CONFIG_BLK_CMDLINE_PARSER is not set
  16028. +
  16029. +
  16030. +#
  16031. +# ATA/ATAPI/MFM/RLL support
  16032. +#
  16033. +# CONFIG_IDE is not set
  16034. +
  16035. +# CONFIG_BLK_DEV_HD is not set
  16036. +# CONFIG_BLK_DEV_RSXX is not set
  16037. +
  16038. +CONFIG_SCSI_VIRTIO=m
  16039. +CONFIG_VIRTIO_BLK=m
  16040. +CONFIG_VIRTIO_PCI=m
  16041. +CONFIG_VIRTIO_BALLOON=m
  16042. +CONFIG_VIRTIO_MMIO=m
  16043. +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
  16044. +CONFIG_VIRTIO_NET=m
  16045. +CONFIG_HW_RANDOM_VIRTIO=m
  16046. +CONFIG_VIRTIO_CONSOLE=m
  16047. +CONFIG_VHOST_NET=m
  16048. +CONFIG_TCM_VHOST=m
  16049. +CONFIG_VHOST_SCSI=m
  16050. +
  16051. +#
  16052. +# SCSI device support
  16053. +#
  16054. +CONFIG_SCSI=y
  16055. +
  16056. +CONFIG_SCSI_ENCLOSURE=m
  16057. +CONFIG_SCSI_SRP=m
  16058. +CONFIG_SCSI_SRP_ATTRS=m
  16059. +CONFIG_SCSI_TGT=m
  16060. +CONFIG_SCSI_ISCI=m
  16061. +CONFIG_SCSI_CHELSIO_FCOE=m
  16062. +
  16063. +CONFIG_SCSI_DH=y
  16064. +CONFIG_SCSI_DH_RDAC=m
  16065. +CONFIG_SCSI_DH_HP_SW=m
  16066. +CONFIG_SCSI_DH_EMC=m
  16067. +CONFIG_SCSI_DH_ALUA=m
  16068. +
  16069. +#
  16070. +# SCSI support type (disk, tape, CD-ROM)
  16071. +#
  16072. +CONFIG_CHR_DEV_ST=m
  16073. +CONFIG_CHR_DEV_OSST=m
  16074. +CONFIG_BLK_DEV_SR=y
  16075. +CONFIG_BLK_DEV_SR_VENDOR=y
  16076. +CONFIG_CHR_DEV_SG=y
  16077. +CONFIG_CHR_DEV_SCH=m
  16078. +
  16079. +#
  16080. +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
  16081. +#
  16082. +CONFIG_SCSI_SPI_ATTRS=m
  16083. +CONFIG_SCSI_FC_ATTRS=m
  16084. +CONFIG_SCSI_FC_TGT_ATTRS=y
  16085. +CONFIG_SCSI_ISCSI_ATTRS=m
  16086. +CONFIG_SCSI_SAS_ATTRS=m
  16087. +CONFIG_SCSI_SRP_TGT_ATTRS=y
  16088. +CONFIG_SCSI_SAS_LIBSAS=m
  16089. +CONFIG_SCSI_SAS_ATA=y
  16090. +CONFIG_SCSI_SAS_HOST_SMP=y
  16091. +CONFIG_RAID_ATTRS=m
  16092. +
  16093. +CONFIG_ISCSI_TCP=m
  16094. +CONFIG_ISCSI_BOOT_SYSFS=m
  16095. +
  16096. +#
  16097. +# SCSI low-level drivers
  16098. +#
  16099. +CONFIG_BLK_DEV_3W_XXXX_RAID=m
  16100. +CONFIG_SCSI_3W_9XXX=m
  16101. +CONFIG_SCSI_ACARD=m
  16102. +CONFIG_SCSI_AACRAID=m
  16103. +CONFIG_SCSI_AIC7XXX=m
  16104. +# http://lists.fedoraproject.org/pipermail/kernel/2013-February/004102.html
  16105. +# CONFIG_SCSI_AIC7XXX_OLD is not set
  16106. +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4
  16107. +CONFIG_AIC7XXX_RESET_DELAY_MS=15000
  16108. +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
  16109. +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
  16110. +CONFIG_AIC7XXX_DEBUG_MASK=0
  16111. +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
  16112. +CONFIG_SCSI_AIC79XX=m
  16113. +CONFIG_AIC79XX_CMDS_PER_DEVICE=4
  16114. +CONFIG_AIC79XX_RESET_DELAY_MS=15000
  16115. +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
  16116. +# CONFIG_AIC79XX_DEBUG_ENABLE is not set
  16117. +CONFIG_AIC79XX_DEBUG_MASK=0
  16118. +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
  16119. +CONFIG_SCSI_AIC94XX=m
  16120. +# CONFIG_AIC94XX_DEBUG is not set
  16121. +# CONFIG_SCSI_ADVANSYS is not set
  16122. +CONFIG_SCSI_BFA_FC=m
  16123. +CONFIG_MEGARAID_NEWGEN=y
  16124. +CONFIG_MEGARAID_MM=m
  16125. +CONFIG_MEGARAID_MAILBOX=m
  16126. +CONFIG_MEGARAID_LEGACY=m
  16127. +CONFIG_MEGARAID_SAS=m
  16128. +CONFIG_SCSI_ESAS2R=m
  16129. +CONFIG_SCSI_MVSAS=m
  16130. +# CONFIG_SCSI_MVSAS_DEBUG is not set
  16131. +CONFIG_SCSI_MVSAS_TASKLET=y
  16132. +CONFIG_SCSI_MPT2SAS=m
  16133. +CONFIG_SCSI_MPT2SAS_MAX_SGE=128
  16134. +CONFIG_SCSI_MPT2SAS_LOGGING=y
  16135. +CONFIG_SCSI_MPT3SAS=m
  16136. +CONFIG_SCSI_MPT3SAS_MAX_SGE=128
  16137. +CONFIG_SCSI_MPT3SAS_LOGGING=y
  16138. +
  16139. +CONFIG_SCSI_UFSHCD=m
  16140. +CONFIG_SCSI_UFSHCD_PCI=m
  16141. +# CONFIG_SCSI_UFSHCD_PLATFORM is not set
  16142. +
  16143. +CONFIG_SCSI_MVUMI=m
  16144. +
  16145. +CONFIG_SCSI_OSD_INITIATOR=m
  16146. +CONFIG_SCSI_OSD_ULD=m
  16147. +CONFIG_SCSI_OSD_DPRINT_SENSE=1
  16148. +# CONFIG_SCSI_OSD_DEBUG is not set
  16149. +
  16150. +CONFIG_SCSI_BNX2_ISCSI=m
  16151. +CONFIG_SCSI_BNX2X_FCOE=m
  16152. +CONFIG_BE2ISCSI=m
  16153. +CONFIG_SCSI_PMCRAID=m
  16154. +
  16155. +CONFIG_SCSI_HPSA=m
  16156. +CONFIG_SCSI_3W_SAS=m
  16157. +CONFIG_SCSI_PM8001=m
  16158. +CONFIG_VMWARE_PVSCSI=m
  16159. +CONFIG_VMWARE_BALLOON=m
  16160. +
  16161. +CONFIG_SCSI_ARCMSR=m
  16162. +CONFIG_SCSI_BUSLOGIC=m
  16163. +CONFIG_SCSI_INITIO=m
  16164. +CONFIG_SCSI_FLASHPOINT=y
  16165. +CONFIG_SCSI_DMX3191D=m
  16166. +# CONFIG_SCSI_EATA is not set
  16167. +# CONFIG_SCSI_EATA_PIO is not set
  16168. +# CONFIG_SCSI_FUTURE_DOMAIN is not set
  16169. +CONFIG_SCSI_GDTH=m
  16170. +CONFIG_SCSI_HPTIOP=m
  16171. +CONFIG_SCSI_IPS=m
  16172. +CONFIG_SCSI_INIA100=m
  16173. +# CONFIG_SCSI_PPA is not set
  16174. +# CONFIG_SCSI_IMM is not set
  16175. +# CONFIG_SCSI_IZIP_EPP16 is not set
  16176. +# CONFIG_SCSI_IZIP_SLOW_CTR is not set
  16177. +CONFIG_SCSI_STEX=m
  16178. +CONFIG_SCSI_SYM53C8XX_2=m
  16179. +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
  16180. +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
  16181. +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
  16182. +CONFIG_SCSI_SYM53C8XX_MMIO=y
  16183. +CONFIG_SCSI_QLOGIC_1280=m
  16184. +CONFIG_SCSI_DC395x=m
  16185. +# CONFIG_SCSI_NSP32 is not set
  16186. +CONFIG_SCSI_DEBUG=m
  16187. +CONFIG_SCSI_DC390T=m
  16188. +CONFIG_SCSI_QLA_FC=m
  16189. +CONFIG_TCM_QLA2XXX=m
  16190. +CONFIG_SCSI_QLA_ISCSI=m
  16191. +CONFIG_SCSI_IPR=m
  16192. +CONFIG_SCSI_IPR_TRACE=y
  16193. +CONFIG_SCSI_IPR_DUMP=y
  16194. +# CONFIG_SCSI_DPT_I2O is not set
  16195. +CONFIG_SCSI_LPFC=m
  16196. +# CONFIG_SCSI_LPFC_DEBUG_FS is not set
  16197. +
  16198. +# PCMCIA SCSI adapter support
  16199. +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
  16200. +
  16201. +CONFIG_ATA_BMDMA=y
  16202. +CONFIG_ATA_VERBOSE_ERROR=y
  16203. +CONFIG_ATA_SFF=y
  16204. +CONFIG_ATA_PIIX=y
  16205. +# CONFIG_SATA_HIGHBANK is not set
  16206. +CONFIG_ATA_ACPI=y
  16207. +CONFIG_BLK_DEV_SX8=m
  16208. +CONFIG_PDC_ADMA=m
  16209. +CONFIG_SATA_AHCI=y
  16210. +CONFIG_SATA_INIC162X=m
  16211. +CONFIG_SATA_MV=m
  16212. +CONFIG_SATA_NV=m
  16213. +CONFIG_SATA_PMP=y
  16214. +CONFIG_SATA_PROMISE=m
  16215. +CONFIG_SATA_QSTOR=m
  16216. +CONFIG_SATA_RCAR=m
  16217. +CONFIG_SATA_SIL=m
  16218. +CONFIG_SATA_SIL24=m
  16219. +CONFIG_SATA_SIS=m
  16220. +CONFIG_SATA_SVW=m
  16221. +CONFIG_SATA_SX4=m
  16222. +CONFIG_SATA_ULI=m
  16223. +CONFIG_SATA_VIA=m
  16224. +CONFIG_SATA_VITESSE=m
  16225. +# CONFIG_SATA_ZPODD is not set
  16226. +CONFIG_SATA_ACARD_AHCI=m
  16227. +
  16228. +# CONFIG_PATA_LEGACY is not set
  16229. +CONFIG_PATA_ACPI=m
  16230. +CONFIG_PATA_ALI=m
  16231. +CONFIG_PATA_AMD=m
  16232. +CONFIG_PATA_ARASAN_CF=m
  16233. +CONFIG_PATA_ARTOP=m
  16234. +CONFIG_PATA_ATIIXP=m
  16235. +CONFIG_PATA_CMD640_PCI=m
  16236. +CONFIG_PATA_CMD64X=m
  16237. +CONFIG_PATA_CS5520=m
  16238. +CONFIG_PATA_CS5530=m
  16239. +CONFIG_PATA_CS5535=m
  16240. +CONFIG_PATA_CS5536=m
  16241. +CONFIG_PATA_CYPRESS=m
  16242. +CONFIG_PATA_EFAR=m
  16243. +CONFIG_ATA_GENERIC=m
  16244. +CONFIG_PATA_HPT366=m
  16245. +CONFIG_PATA_HPT37X=m
  16246. +CONFIG_PATA_HPT3X2N=m
  16247. +CONFIG_PATA_HPT3X3=m
  16248. +# CONFIG_PATA_HPT3X3_DMA is not set
  16249. +CONFIG_PATA_IT821X=m
  16250. +CONFIG_PATA_IT8213=m
  16251. +CONFIG_PATA_JMICRON=m
  16252. +CONFIG_PATA_NINJA32=m
  16253. +CONFIG_PATA_MARVELL=m
  16254. +CONFIG_PATA_MPIIX=m
  16255. +CONFIG_PATA_NETCELL=m
  16256. +CONFIG_PATA_NS87410=m
  16257. +CONFIG_PATA_NS87415=m
  16258. +CONFIG_PATA_OLDPIIX=m
  16259. +CONFIG_PATA_OPTI=m
  16260. +CONFIG_PATA_OPTIDMA=m
  16261. +CONFIG_PATA_PCMCIA=m
  16262. +CONFIG_PATA_PDC_OLD=m
  16263. +# CONFIG_PATA_RADISYS is not set
  16264. +CONFIG_PATA_RDC=m
  16265. +# CONFIG_PATA_RZ1000 is not set
  16266. +# CONFIG_PATA_SC1200 is not set
  16267. +CONFIG_PATA_SERVERWORKS=m
  16268. +CONFIG_PATA_PDC2027X=m
  16269. +CONFIG_PATA_SCH=m
  16270. +CONFIG_PATA_SIL680=m
  16271. +CONFIG_PATA_SIS=m
  16272. +CONFIG_PATA_TOSHIBA=m
  16273. +CONFIG_PATA_TRIFLEX=m
  16274. +CONFIG_PATA_VIA=m
  16275. +CONFIG_PATA_WINBOND=m
  16276. +CONFIG_PATA_ATP867X=m
  16277. +
  16278. +
  16279. +#
  16280. +# Multi-device support (RAID and LVM)
  16281. +#
  16282. +CONFIG_MD=y
  16283. +CONFIG_BLK_DEV_MD=y
  16284. +CONFIG_MD_AUTODETECT=y
  16285. +CONFIG_MD_FAULTY=m
  16286. +CONFIG_MD_LINEAR=m
  16287. +CONFIG_MD_MULTIPATH=m
  16288. +CONFIG_MD_RAID0=m
  16289. +CONFIG_MD_RAID1=m
  16290. +CONFIG_MD_RAID10=m
  16291. +CONFIG_MD_RAID456=m
  16292. +
  16293. +CONFIG_BCACHE=m
  16294. +# CONFIG_BCACHE_DEBUG is not set
  16295. +# CONFIG_BCACHE_EDEBUG is not set
  16296. +# CONFIG_BCACHE_CLOSURES_DEBUG is not set
  16297. +
  16298. +# CONFIG_MULTICORE_RAID456 is not set
  16299. +CONFIG_ASYNC_RAID6_TEST=m
  16300. +CONFIG_BLK_DEV_DM=y
  16301. +CONFIG_DM_CRYPT=m
  16302. +CONFIG_DM_DEBUG=y
  16303. +CONFIG_DM_DELAY=m
  16304. +CONFIG_DM_MIRROR=y
  16305. +CONFIG_DM_MULTIPATH=m
  16306. +CONFIG_DM_SNAPSHOT=y
  16307. +CONFIG_DM_THIN_PROVISIONING=m
  16308. +CONFIG_DM_CACHE=m
  16309. +CONFIG_DM_CACHE_MQ=m
  16310. +CONFIG_DM_CACHE_CLEANER=m
  16311. +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set
  16312. +# CONFIG_DM_DEBUG_SPACE_MAPS is not set
  16313. +CONFIG_DM_UEVENT=y
  16314. +CONFIG_DM_ZERO=y
  16315. +CONFIG_DM_LOG_USERSPACE=m
  16316. +CONFIG_DM_MULTIPATH_QL=m
  16317. +CONFIG_DM_MULTIPATH_ST=m
  16318. +CONFIG_DM_RAID=m
  16319. +CONFIG_DM_FLAKEY=m
  16320. +CONFIG_DM_VERITY=m
  16321. +CONFIG_DM_SWITCH=m
  16322. +
  16323. +#
  16324. +# Fusion MPT device support
  16325. +#
  16326. +CONFIG_FUSION=y
  16327. +CONFIG_FUSION_SPI=m
  16328. +CONFIG_FUSION_FC=m
  16329. +CONFIG_FUSION_MAX_SGE=40
  16330. +CONFIG_FUSION_CTL=m
  16331. +CONFIG_FUSION_LAN=m
  16332. +CONFIG_FUSION_SAS=m
  16333. +CONFIG_FUSION_LOGGING=y
  16334. +
  16335. +#
  16336. +# IEEE 1394 (FireWire) support (JUJU alternative stack)
  16337. +#
  16338. +CONFIG_FIREWIRE=m
  16339. +CONFIG_FIREWIRE_OHCI=m
  16340. +CONFIG_FIREWIRE_SBP2=m
  16341. +CONFIG_FIREWIRE_NET=m
  16342. +CONFIG_FIREWIRE_OHCI_DEBUG=y
  16343. +CONFIG_FIREWIRE_NOSY=m
  16344. +# CONFIG_FIREWIRE_SERIAL is not set
  16345. +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set
  16346. +
  16347. +#
  16348. +# IEEE 1394 (FireWire) support
  16349. +#
  16350. +
  16351. +#
  16352. +# I2O device support
  16353. +#
  16354. +# CONFIG_I2O is not set
  16355. +# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
  16356. +
  16357. +#
  16358. +# Virtualization support drivers
  16359. +#
  16360. +# CONFIG_VIRT_DRIVERS is not set
  16361. +
  16362. +# Networking support
  16363. +#
  16364. +
  16365. +CONFIG_NET_DMA=y
  16366. +
  16367. +CONFIG_NETLINK_MMAP=y
  16368. +CONFIG_NETLINK_DIAG=m
  16369. +
  16370. +CONFIG_TCP_CONG_ADVANCED=y
  16371. +CONFIG_TCP_CONG_BIC=m
  16372. +CONFIG_TCP_CONG_CUBIC=y
  16373. +CONFIG_TCP_CONG_HTCP=m
  16374. +CONFIG_TCP_CONG_HSTCP=m
  16375. +CONFIG_TCP_CONG_HYBLA=m
  16376. +CONFIG_TCP_CONG_ILLINOIS=m
  16377. +CONFIG_TCP_CONG_LP=m
  16378. +CONFIG_TCP_CONG_SCALABLE=m
  16379. +CONFIG_TCP_CONG_VEGAS=m
  16380. +CONFIG_TCP_CONG_VENO=m
  16381. +CONFIG_TCP_CONG_WESTWOOD=m
  16382. +CONFIG_TCP_CONG_YEAH=m
  16383. +
  16384. +CONFIG_TCP_MD5SIG=y
  16385. +
  16386. +#
  16387. +# Networking options
  16388. +#
  16389. +CONFIG_PACKET_DIAG=m
  16390. +CONFIG_UNIX_DIAG=m
  16391. +CONFIG_NET_KEY=m
  16392. +CONFIG_NET_KEY_MIGRATE=y
  16393. +CONFIG_INET_TUNNEL=m
  16394. +CONFIG_INET_DIAG=m
  16395. +CONFIG_INET_UDP_DIAG=m
  16396. +CONFIG_IP_MULTICAST=y
  16397. +CONFIG_IP_ADVANCED_ROUTER=y
  16398. +CONFIG_IP_FIB_TRIE_STATS=y
  16399. +CONFIG_IP_MULTIPLE_TABLES=y
  16400. +CONFIG_IP_ROUTE_MULTIPATH=y
  16401. +CONFIG_IP_ROUTE_VERBOSE=y
  16402. +CONFIG_IP_NF_SECURITY=m
  16403. +CONFIG_NET_IPIP=m
  16404. +CONFIG_NET_IPGRE_DEMUX=m
  16405. +CONFIG_NET_IPGRE=m
  16406. +CONFIG_NET_IPGRE_BROADCAST=y
  16407. +CONFIG_IP_MROUTE=y
  16408. +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
  16409. +CONFIG_IP_PIMSM_V1=y
  16410. +CONFIG_IP_PIMSM_V2=y
  16411. +CONFIG_ARPD=y
  16412. +CONFIG_SYN_COOKIES=y
  16413. +CONFIG_NET_IPVTI=m
  16414. +CONFIG_INET_AH=m
  16415. +CONFIG_INET_ESP=m
  16416. +CONFIG_INET_IPCOMP=m
  16417. +CONFIG_NETCONSOLE=m
  16418. +CONFIG_NETCONSOLE_DYNAMIC=y
  16419. +CONFIG_NETPOLL_TRAP=y
  16420. +CONFIG_NET_POLL_CONTROLLER=y
  16421. +
  16422. +#
  16423. +# IP: Virtual Server Configuration
  16424. +#
  16425. +CONFIG_IP_VS=m
  16426. +# CONFIG_IP_VS_DEBUG is not set
  16427. +CONFIG_IP_VS_TAB_BITS=12
  16428. +CONFIG_IP_VS_PROTO_TCP=y
  16429. +CONFIG_IP_VS_PROTO_UDP=y
  16430. +CONFIG_IP_VS_PROTO_ESP=y
  16431. +CONFIG_IP_VS_PROTO_AH=y
  16432. +CONFIG_IP_VS_PROTO_SCTP=y
  16433. +CONFIG_IP_VS_IPV6=y
  16434. +CONFIG_IP_VS_RR=m
  16435. +CONFIG_IP_VS_WRR=m
  16436. +CONFIG_IP_VS_LC=m
  16437. +CONFIG_IP_VS_WLC=m
  16438. +CONFIG_IP_VS_LBLC=m
  16439. +CONFIG_IP_VS_LBLCR=m
  16440. +CONFIG_IP_VS_DH=m
  16441. +CONFIG_IP_VS_SH=m
  16442. +CONFIG_IP_VS_SED=m
  16443. +CONFIG_IP_VS_NQ=m
  16444. +
  16445. +#
  16446. +# IPVS SH scheduler
  16447. +#
  16448. +CONFIG_IP_VS_SH_TAB_BITS=8
  16449. +
  16450. +CONFIG_IP_VS_FTP=m
  16451. +CONFIG_IP_VS_PE_SIP=m
  16452. +
  16453. +CONFIG_IPV6_PRIVACY=y
  16454. +CONFIG_IPV6_ROUTER_PREF=y
  16455. +CONFIG_IPV6_ROUTE_INFO=y
  16456. +CONFIG_IPV6_OPTIMISTIC_DAD=y
  16457. +CONFIG_INET6_AH=m
  16458. +CONFIG_INET6_ESP=m
  16459. +CONFIG_INET6_IPCOMP=m
  16460. +CONFIG_IPV6_MIP6=y
  16461. +CONFIG_IPV6_VTI=m
  16462. +CONFIG_IPV6_SIT=m
  16463. +CONFIG_IPV6_SIT_6RD=y
  16464. +CONFIG_IPV6_TUNNEL=m
  16465. +# CONFIG_IPV6_GRE is not set
  16466. +CONFIG_IPV6_SUBTREES=y
  16467. +CONFIG_IPV6_MULTIPLE_TABLES=y
  16468. +CONFIG_IPV6_MROUTE=y
  16469. +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
  16470. +CONFIG_IPV6_PIMSM_V2=y
  16471. +
  16472. +CONFIG_RDS=m
  16473. +# CONFIG_RDS_DEBUG is not set
  16474. +CONFIG_RDS_RDMA=m
  16475. +CONFIG_RDS_TCP=m
  16476. +
  16477. +CONFIG_NET_9P=m
  16478. +CONFIG_NET_9P_VIRTIO=m
  16479. +# CONFIG_NET_9P_DEBUG is not set
  16480. +CONFIG_NET_9P_RDMA=m
  16481. +
  16482. +# CONFIG_DECNET is not set
  16483. +CONFIG_BRIDGE=m
  16484. +CONFIG_BRIDGE_IGMP_SNOOPING=y
  16485. +CONFIG_BRIDGE_VLAN_FILTERING=y
  16486. +
  16487. +# PHY timestamping adds overhead
  16488. +CONFIG_NETWORK_PHY_TIMESTAMPING=y
  16489. +
  16490. +CONFIG_NETFILTER_ADVANCED=y
  16491. +CONFIG_NF_CONNTRACK=m
  16492. +CONFIG_NETFILTER_NETLINK=m
  16493. +CONFIG_NETFILTER_NETLINK_ACCT=m
  16494. +CONFIG_NETFILTER_NETLINK_QUEUE=m
  16495. +CONFIG_NETFILTER_NETLINK_QUEUE_CT=y
  16496. +CONFIG_NETFILTER_NETLINK_LOG=m
  16497. +CONFIG_NETFILTER_TPROXY=m
  16498. +CONFIG_NETFILTER_XTABLES=y
  16499. +CONFIG_NETFILTER_XT_SET=m
  16500. +CONFIG_NETFILTER_XT_MARK=m
  16501. +CONFIG_NETFILTER_XT_CONNMARK=m
  16502. +
  16503. +CONFIG_NETFILTER_XT_TARGET_AUDIT=m
  16504. +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
  16505. +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
  16506. +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
  16507. +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
  16508. +CONFIG_NETFILTER_XT_TARGET_CT=m
  16509. +CONFIG_NETFILTER_XT_TARGET_DSCP=m
  16510. +CONFIG_NETFILTER_XT_TARGET_HMARK=m
  16511. +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
  16512. +CONFIG_NETFILTER_XT_TARGET_LED=m
  16513. +CONFIG_NETFILTER_XT_TARGET_LOG=m
  16514. +CONFIG_NETFILTER_XT_TARGET_MARK=m
  16515. +CONFIG_NETFILTER_XT_TARGET_NFLOG=m
  16516. +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
  16517. +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
  16518. +CONFIG_NETFILTER_XT_TARGET_RATEEST=m
  16519. +CONFIG_NETFILTER_XT_TARGET_SECMARK=m
  16520. +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
  16521. +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
  16522. +CONFIG_NETFILTER_XT_TARGET_TRACE=m
  16523. +CONFIG_NETFILTER_XT_TARGET_TEE=m
  16524. +CONFIG_NETFILTER_XT_TARGET_TPROXY=m
  16525. +
  16526. +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
  16527. +CONFIG_NETFILTER_XT_MATCH_BPF=m
  16528. +CONFIG_NETFILTER_XT_MATCH_CGROUP=m
  16529. +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
  16530. +CONFIG_NETFILTER_XT_MATCH_COMMENT=m
  16531. +CONFIG_NETFILTER_XT_MATCH_CPU=m
  16532. +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
  16533. +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
  16534. +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
  16535. +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
  16536. +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
  16537. +CONFIG_NETFILTER_XT_MATCH_DCCP=m
  16538. +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
  16539. +CONFIG_NETFILTER_XT_MATCH_DSCP=m
  16540. +CONFIG_NETFILTER_XT_MATCH_ECN=m
  16541. +CONFIG_NETFILTER_XT_MATCH_ESP=m
  16542. +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
  16543. +CONFIG_NETFILTER_XT_MATCH_HELPER=m
  16544. +CONFIG_NETFILTER_XT_MATCH_HL=m
  16545. +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
  16546. +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
  16547. +CONFIG_NETFILTER_XT_MATCH_IPVS=m
  16548. +CONFIG_NETFILTER_XT_MATCH_L2TP=m
  16549. +CONFIG_NETFILTER_XT_MATCH_LENGTH=m
  16550. +CONFIG_NETFILTER_XT_MATCH_LIMIT=m
  16551. +CONFIG_NETFILTER_XT_MATCH_MAC=m
  16552. +CONFIG_NETFILTER_XT_MATCH_MARK=m
  16553. +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
  16554. +CONFIG_NETFILTER_XT_MATCH_NFACCT=m
  16555. +CONFIG_NETFILTER_XT_MATCH_OSF=m
  16556. +CONFIG_NETFILTER_XT_MATCH_OWNER=m
  16557. +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
  16558. +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
  16559. +CONFIG_NETFILTER_XT_MATCH_POLICY=m
  16560. +CONFIG_NETFILTER_XT_MATCH_QUOTA=m
  16561. +CONFIG_NETFILTER_XT_MATCH_RATEEST=m
  16562. +CONFIG_NETFILTER_XT_MATCH_REALM=m
  16563. +CONFIG_NETFILTER_XT_MATCH_RECENT=m
  16564. +CONFIG_NETFILTER_XT_MATCH_SCTP=m
  16565. +CONFIG_NETFILTER_XT_MATCH_SOCKET=m
  16566. +CONFIG_NETFILTER_XT_MATCH_STATE=y
  16567. +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
  16568. +CONFIG_NETFILTER_XT_MATCH_STRING=m
  16569. +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
  16570. +CONFIG_NETFILTER_XT_MATCH_TIME=m
  16571. +CONFIG_NETFILTER_XT_MATCH_U32=m
  16572. +
  16573. +# CONFIG_NETFILTER_DEBUG is not set
  16574. +CONFIG_BRIDGE_NETFILTER=y
  16575. +
  16576. +#
  16577. +# IP: Netfilter Configuration
  16578. +#
  16579. +
  16580. +CONFIG_NF_CONNTRACK_MARK=y
  16581. +CONFIG_NF_CONNTRACK_SECMARK=y
  16582. +CONFIG_NF_CONNTRACK_EVENTS=y
  16583. +CONFIG_NF_CONNTRACK_ZONES=y
  16584. +CONFIG_NF_CONNTRACK_PROCFS=y # check if contrack(8) in f17 supports netlink
  16585. +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
  16586. +CONFIG_NF_CONNTRACK_AMANDA=m
  16587. +CONFIG_NF_CONNTRACK_FTP=m
  16588. +CONFIG_NF_CONNTRACK_H323=m
  16589. +CONFIG_NF_CONNTRACK_IRC=m
  16590. +CONFIG_NF_CONNTRACK_NETBIOS_NS=m
  16591. +CONFIG_NF_CONNTRACK_PPTP=m
  16592. +CONFIG_NF_CONNTRACK_SANE=m
  16593. +CONFIG_NF_CONNTRACK_SIP=m
  16594. +CONFIG_NF_CONNTRACK_TFTP=m
  16595. +CONFIG_NF_CONNTRACK_IPV4=y
  16596. +CONFIG_NF_CONNTRACK_IPV6=y
  16597. +# CONFIG_NF_CONNTRACK_TIMEOUT is not set
  16598. +CONFIG_NF_CONNTRACK_TIMESTAMP=y
  16599. +CONFIG_NF_CONNTRACK_SNMP=m
  16600. +CONFIG_NF_NAT=m
  16601. +CONFIG_NF_NAT_SNMP_BASIC=m
  16602. +CONFIG_NF_CT_PROTO_DCCP=m
  16603. +CONFIG_NF_CT_PROTO_SCTP=m
  16604. +CONFIG_NF_CT_NETLINK=m
  16605. +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
  16606. +CONFIG_NF_CT_NETLINK_HELPER=m
  16607. +CONFIG_NF_CT_PROTO_UDPLITE=m
  16608. +
  16609. +CONFIG_IP_NF_MATCH_AH=m
  16610. +CONFIG_IP_NF_MATCH_ECN=m
  16611. +CONFIG_IP_NF_MATCH_RPFILTER=m
  16612. +CONFIG_IP_NF_MATCH_TTL=m
  16613. +CONFIG_IP_NF_TARGET_CLUSTERIP=m
  16614. +CONFIG_IP_NF_TARGET_REDIRECT=m
  16615. +CONFIG_IP_NF_TARGET_NETMAP=m
  16616. +CONFIG_IP_NF_TARGET_ECN=m
  16617. +CONFIG_IP_NF_TARGET_LOG=m
  16618. +CONFIG_IP_NF_TARGET_ULOG=m
  16619. +CONFIG_IP_NF_TARGET_REJECT=y
  16620. +CONFIG_IP_NF_TARGET_SYNPROXY=m
  16621. +CONFIG_IP_NF_TARGET_TTL=m
  16622. +CONFIG_NF_NAT_IPV4=m
  16623. +CONFIG_IP_NF_TARGET_MASQUERADE=m
  16624. +CONFIG_IP_NF_MANGLE=m
  16625. +CONFIG_IP_NF_ARPTABLES=m
  16626. +CONFIG_IP_NF_ARPFILTER=m
  16627. +CONFIG_IP_NF_ARP_MANGLE=m
  16628. +CONFIG_IP_NF_QUEUE=m
  16629. +CONFIG_IP_NF_RAW=m
  16630. +
  16631. +CONFIG_IP_NF_IPTABLES=y
  16632. +CONFIG_IP_NF_FILTER=y
  16633. +
  16634. +#
  16635. +# IPv6: Netfilter Configuration
  16636. +#
  16637. +CONFIG_IP6_NF_FILTER=m
  16638. +CONFIG_IP6_NF_IPTABLES=m
  16639. +CONFIG_IP6_NF_MANGLE=m
  16640. +CONFIG_IP6_NF_MATCH_AH=m
  16641. +CONFIG_IP6_NF_MATCH_EUI64=m
  16642. +CONFIG_IP6_NF_MATCH_FRAG=m
  16643. +CONFIG_IP6_NF_MATCH_HL=m
  16644. +CONFIG_IP6_NF_MATCH_IPV6HEADER=m
  16645. +CONFIG_IP6_NF_MATCH_MH=m
  16646. +CONFIG_IP6_NF_MATCH_RPFILTER=m
  16647. +CONFIG_IP6_NF_MATCH_OPTS=m
  16648. +CONFIG_IP6_NF_MATCH_RT=m
  16649. +CONFIG_IP6_NF_QUEUE=m
  16650. +CONFIG_IP6_NF_RAW=m
  16651. +CONFIG_IP6_NF_SECURITY=m
  16652. +CONFIG_IP6_NF_TARGET_LOG=m
  16653. +CONFIG_IP6_NF_TARGET_REJECT=m
  16654. +CONFIG_IP6_NF_TARGET_SYNPROXY=m
  16655. +CONFIG_IP6_NF_TARGET_HL=m
  16656. +CONFIG_NF_NAT_IPV6=m
  16657. +CONFIG_IP6_NF_TARGET_MASQUERADE=m
  16658. +# CONFIG_IP6_NF_TARGET_NPT is not set
  16659. +
  16660. +# nf_tables support
  16661. +CONFIG_NF_TABLES=m
  16662. +CONFIG_NF_TABLES_INET=m
  16663. +CONFIG_NFT_EXTHDR=m
  16664. +CONFIG_NFT_META=m
  16665. +CONFIG_NFT_CT=m
  16666. +CONFIG_NFT_RBTREE=m
  16667. +CONFIG_NFT_HASH=m
  16668. +CONFIG_NFT_COUNTER=m
  16669. +CONFIG_NFT_LOG=m
  16670. +CONFIG_NFT_LIMIT=m
  16671. +CONFIG_NFT_NAT=m
  16672. +CONFIG_NFT_QUEUE=m
  16673. +CONFIG_NFT_REJECT=m
  16674. +CONFIG_NFT_COMPAT=m
  16675. +
  16676. +CONFIG_NF_TABLES_IPV4=m
  16677. +CONFIG_NFT_REJECT_IPV4=m
  16678. +CONFIG_NFT_CHAIN_ROUTE_IPV4=m
  16679. +CONFIG_NFT_CHAIN_NAT_IPV4=m
  16680. +CONFIG_NF_TABLES_ARP=m
  16681. +
  16682. +CONFIG_NF_TABLES_IPV6=m
  16683. +CONFIG_NFT_CHAIN_ROUTE_IPV6=m
  16684. +CONFIG_NFT_CHAIN_NAT_IPV6=m
  16685. +
  16686. +CONFIG_NF_TABLES_BRIDGE=m
  16687. +#
  16688. +# Bridge: Netfilter Configuration
  16689. +#
  16690. +CONFIG_BRIDGE_NF_EBTABLES=m
  16691. +CONFIG_BRIDGE_EBT_802_3=m
  16692. +CONFIG_BRIDGE_EBT_AMONG=m
  16693. +CONFIG_BRIDGE_EBT_ARP=m
  16694. +CONFIG_BRIDGE_EBT_ARPREPLY=m
  16695. +CONFIG_BRIDGE_EBT_BROUTE=m
  16696. +CONFIG_BRIDGE_EBT_DNAT=m
  16697. +CONFIG_BRIDGE_EBT_IP=m
  16698. +CONFIG_BRIDGE_EBT_IP6=m
  16699. +CONFIG_BRIDGE_EBT_LIMIT=m
  16700. +CONFIG_BRIDGE_EBT_LOG=m
  16701. +CONFIG_BRIDGE_EBT_MARK=m
  16702. +CONFIG_BRIDGE_EBT_MARK_T=m
  16703. +CONFIG_BRIDGE_EBT_NFLOG=m
  16704. +CONFIG_BRIDGE_EBT_PKTTYPE=m
  16705. +CONFIG_BRIDGE_EBT_REDIRECT=m
  16706. +CONFIG_BRIDGE_EBT_SNAT=m
  16707. +CONFIG_BRIDGE_EBT_STP=m
  16708. +CONFIG_BRIDGE_EBT_T_FILTER=m
  16709. +CONFIG_BRIDGE_EBT_T_NAT=m
  16710. +CONFIG_BRIDGE_EBT_ULOG=m
  16711. +CONFIG_BRIDGE_EBT_VLAN=m
  16712. +CONFIG_XFRM=y
  16713. +CONFIG_XFRM_MIGRATE=y
  16714. +CONFIG_XFRM_SUB_POLICY=y
  16715. +CONFIG_XFRM_STATISTICS=y
  16716. +CONFIG_XFRM_USER=y
  16717. +CONFIG_INET6_XFRM_MODE_TRANSPORT=m
  16718. +CONFIG_INET6_XFRM_MODE_TUNNEL=m
  16719. +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
  16720. +CONFIG_INET6_XFRM_MODE_BEET=m
  16721. +
  16722. +CONFIG_IP_SET=m
  16723. +CONFIG_IP_SET_MAX=256
  16724. +CONFIG_IP_SET_BITMAP_IP=m
  16725. +CONFIG_IP_SET_BITMAP_IPMAC=m
  16726. +CONFIG_IP_SET_BITMAP_PORT=m
  16727. +CONFIG_IP_SET_HASH_IP=m
  16728. +CONFIG_IP_SET_HASH_IPPORT=m
  16729. +CONFIG_IP_SET_HASH_IPPORTIP=m
  16730. +CONFIG_IP_SET_HASH_IPPORTNET=m
  16731. +CONFIG_IP_SET_HASH_NETPORTNET=m
  16732. +CONFIG_IP_SET_HASH_NET=m
  16733. +CONFIG_IP_SET_HASH_NETNET=m
  16734. +CONFIG_IP_SET_HASH_NETPORT=m
  16735. +CONFIG_IP_SET_HASH_NETIFACE=m
  16736. +CONFIG_IP_SET_LIST_SET=m
  16737. +
  16738. +#
  16739. +# SCTP Configuration (EXPERIMENTAL)
  16740. +#
  16741. +CONFIG_IP_SCTP=m
  16742. +CONFIG_NET_SCTPPROBE=m
  16743. +# CONFIG_SCTP_DBG_MSG is not set
  16744. +# CONFIG_SCTP_DBG_OBJCNT is not set
  16745. +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1=y
  16746. +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5 is not set
  16747. +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
  16748. +CONFIG_SCTP_COOKIE_HMAC_MD5=y
  16749. +CONFIG_SCTP_COOKIE_HMAC_SHA1=y
  16750. +CONFIG_ATM=m
  16751. +CONFIG_VLAN_8021Q_GVRP=y
  16752. +CONFIG_VLAN_8021Q_MVRP=y
  16753. +CONFIG_LLC=m
  16754. +# CONFIG_LLC2 is not set
  16755. +CONFIG_IPX=m
  16756. +# CONFIG_IPX_INTERN is not set
  16757. +CONFIG_ATALK=m
  16758. +CONFIG_DEV_APPLETALK=m
  16759. +CONFIG_IPDDP=m
  16760. +CONFIG_IPDDP_ENCAP=y
  16761. +CONFIG_IPDDP_DECAP=y
  16762. +# CONFIG_X25 is not set
  16763. +# CONFIG_LAPB is not set
  16764. +# CONFIG_ECONET is not set
  16765. +CONFIG_WAN_ROUTER=m
  16766. +CONFIG_IP_DCCP=m
  16767. +CONFIG_IP_DCCP_CCID2=m
  16768. +# CONFIG_IP_DCCP_CCID2_DEBUG is not set
  16769. +CONFIG_IP_DCCP_CCID3=y
  16770. +# CONFIG_IP_DCCP_CCID3_DEBUG is not set
  16771. +# CONFIG_IP_DCCP_DEBUG is not set
  16772. +# CONFIG_NET_DCCPPROBE is not set
  16773. +
  16774. +#
  16775. +# TIPC Configuration (EXPERIMENTAL)
  16776. +#
  16777. +CONFIG_TIPC=m
  16778. +CONFIG_TIPC_PORTS=8192
  16779. +# CONFIG_TIPC_MEDIA_IB is not set
  16780. +# CONFIG_TIPC_ADVANCED is not set
  16781. +# CONFIG_TIPC_DEBUG is not set
  16782. +
  16783. +CONFIG_NETLABEL=y
  16784. +
  16785. +#
  16786. +# QoS and/or fair queueing
  16787. +#
  16788. +CONFIG_NET_SCHED=y
  16789. +CONFIG_NET_SCH_CBQ=m
  16790. +CONFIG_NET_SCH_DSMARK=m
  16791. +CONFIG_NET_SCH_DRR=m
  16792. +CONFIG_NET_SCH_GRED=m
  16793. +CONFIG_NET_SCH_HFSC=m
  16794. +CONFIG_NET_SCH_HTB=m
  16795. +CONFIG_NET_SCH_INGRESS=m
  16796. +CONFIG_NET_SCH_NETEM=m
  16797. +CONFIG_NET_SCH_PRIO=m
  16798. +CONFIG_NET_SCH_RED=m
  16799. +CONFIG_NET_SCH_SFQ=m
  16800. +CONFIG_NET_SCH_TBF=m
  16801. +CONFIG_NET_SCH_TEQL=m
  16802. +CONFIG_NET_SCH_SFB=m
  16803. +CONFIG_NET_SCH_MQPRIO=m
  16804. +CONFIG_NET_SCH_MULTIQ=m
  16805. +CONFIG_NET_SCH_CHOKE=m
  16806. +CONFIG_NET_SCH_QFQ=m
  16807. +CONFIG_NET_SCH_CODEL=m
  16808. +CONFIG_NET_SCH_FQ_CODEL=m
  16809. +CONFIG_NET_SCH_FQ=m
  16810. +CONFIG_NET_SCH_HHF=m
  16811. +CONFIG_NET_SCH_PIE=m
  16812. +CONFIG_NET_SCH_PLUG=m
  16813. +CONFIG_NET_CLS=y
  16814. +CONFIG_NET_CLS_ACT=y
  16815. +CONFIG_NET_CLS_BASIC=m
  16816. +CONFIG_NET_CLS_CGROUP=y
  16817. +CONFIG_NET_CLS_BPF=m
  16818. +CONFIG_NET_CLS_FLOW=m
  16819. +CONFIG_NET_CLS_FW=m
  16820. +CONFIG_NET_CLS_IND=y
  16821. +CONFIG_NET_CLS_ROUTE4=m
  16822. +CONFIG_NET_CLS_ROUTE=y
  16823. +CONFIG_NET_CLS_RSVP=m
  16824. +CONFIG_NET_CLS_RSVP6=m
  16825. +CONFIG_NET_CLS_TCINDEX=m
  16826. +CONFIG_NET_CLS_U32=m
  16827. +CONFIG_CLS_U32_MARK=y
  16828. +CONFIG_CLS_U32_PERF=y
  16829. +CONFIG_NET_EMATCH=y
  16830. +CONFIG_NET_EMATCH_CMP=m
  16831. +CONFIG_NET_EMATCH_META=m
  16832. +CONFIG_NET_EMATCH_NBYTE=m
  16833. +CONFIG_NET_EMATCH_STACK=32
  16834. +CONFIG_NET_EMATCH_TEXT=m
  16835. +CONFIG_NET_EMATCH_IPSET=m
  16836. +CONFIG_NET_EMATCH_U32=m
  16837. +
  16838. +CONFIG_NET_ACT_CSUM=m
  16839. +CONFIG_NET_ACT_GACT=m
  16840. +CONFIG_GACT_PROB=y
  16841. +CONFIG_NET_ACT_IPT=m
  16842. +CONFIG_NET_ACT_MIRRED=m
  16843. +CONFIG_NET_ACT_NAT=m
  16844. +CONFIG_NET_ACT_PEDIT=m
  16845. +CONFIG_NET_ACT_POLICE=m
  16846. +CONFIG_NET_ACT_SIMP=m
  16847. +CONFIG_NET_ACT_SKBEDIT=m
  16848. +
  16849. +CONFIG_DCB=y
  16850. +CONFIG_DNS_RESOLVER=m
  16851. +CONFIG_BATMAN_ADV=m
  16852. +CONFIG_BATMAN_ADV_BLA=y
  16853. +CONFIG_BATMAN_ADV_DAT=y
  16854. +CONFIG_BATMAN_ADV_NC=y
  16855. +
  16856. +# CONFIG_BATMAN_ADV_DEBUG is not set
  16857. +CONFIG_OPENVSWITCH=m
  16858. +CONFIG_OPENVSWITCH_GRE=y
  16859. +CONFIG_OPENVSWITCH_VXLAN=y
  16860. +CONFIG_VSOCKETS=m
  16861. +
  16862. +
  16863. +#
  16864. +# Network testing
  16865. +#
  16866. +CONFIG_NET_PKTGEN=m
  16867. +# CONFIG_NET_TCPPROBE is not set
  16868. +CONFIG_NET_DROP_MONITOR=y
  16869. +
  16870. +# disable later --kyle
  16871. +
  16872. +#
  16873. +# ARCnet devices
  16874. +#
  16875. +# CONFIG_ARCNET is not set
  16876. +CONFIG_IFB=m
  16877. +CONFIG_NET_TEAM=m
  16878. +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
  16879. +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
  16880. +CONFIG_NET_TEAM_MODE_LOADBALANCE=m
  16881. +CONFIG_NET_TEAM_MODE_BROADCAST=m
  16882. +CONFIG_NET_TEAM_MODE_RANDOM=m
  16883. +CONFIG_DUMMY=m
  16884. +CONFIG_BONDING=m
  16885. +CONFIG_MACVLAN=m
  16886. +CONFIG_MACVTAP=m
  16887. +CONFIG_VXLAN=m
  16888. +CONFIG_EQUALIZER=m
  16889. +CONFIG_TUN=m
  16890. +CONFIG_VETH=m
  16891. +CONFIG_NLMON=m
  16892. +
  16893. +#
  16894. +# ATM
  16895. +#
  16896. +CONFIG_ATM_DRIVERS=y
  16897. +# CONFIG_ATM_DUMMY is not set
  16898. +CONFIG_ATM_CLIP=m
  16899. +CONFIG_ATM_LANE=m
  16900. +CONFIG_ATM_BR2684=m
  16901. +CONFIG_NET_SCH_ATM=m
  16902. +CONFIG_ATM_TCP=m
  16903. +# CONFIG_ATM_LANAI is not set
  16904. +CONFIG_ATM_ENI=m
  16905. +CONFIG_ATM_FIRESTREAM=m
  16906. +# CONFIG_ATM_ZATM is not set
  16907. +# CONFIG_ATM_IDT77252 is not set
  16908. +# CONFIG_ATM_AMBASSADOR is not set
  16909. +# CONFIG_ATM_HORIZON is not set
  16910. +# CONFIG_ATM_FORE200E is not set
  16911. +# CONFIG_ATM_FORE200E_USE_TASKLET is not set
  16912. +CONFIG_ATM_FORE200E_TX_RETRY=16
  16913. +CONFIG_ATM_FORE200E_DEBUG=0
  16914. +
  16915. +CONFIG_ATM_HE=m
  16916. +CONFIG_PPTP=m
  16917. +CONFIG_PPPOATM=m
  16918. +CONFIG_PPPOL2TP=m
  16919. +CONFIG_ATM_NICSTAR=m
  16920. +# CONFIG_ATM_IA is not set
  16921. +# CONFIG_ATM_CLIP_NO_ICMP is not set
  16922. +# CONFIG_ATM_MPOA is not set
  16923. +# CONFIG_ATM_BR2684_IPFILTER is not set
  16924. +# CONFIG_ATM_ENI_DEBUG is not set
  16925. +# CONFIG_ATM_ENI_TUNE_BURST is not set
  16926. +# CONFIG_ATM_ZATM_DEBUG is not set
  16927. +# CONFIG_ATM_IDT77252_DEBUG is not set
  16928. +# CONFIG_ATM_IDT77252_RCV_ALL is not set
  16929. +# CONFIG_ATM_AMBASSADOR_DEBUG is not set
  16930. +# CONFIG_ATM_HORIZON_DEBUG is not set
  16931. +# CONFIG_ATM_HE_USE_SUNI is not set
  16932. +# CONFIG_ATM_NICSTAR_USE_SUNI is not set
  16933. +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
  16934. +# CONFIG_ATM_IA_DEBUG is not set
  16935. +CONFIG_ATM_SOLOS=m
  16936. +
  16937. +CONFIG_L2TP=m
  16938. +CONFIG_L2TP_V3=y
  16939. +CONFIG_L2TP_IP=m
  16940. +CONFIG_L2TP_ETH=m
  16941. +
  16942. +# CONFIG_CAIF is not set
  16943. +
  16944. +CONFIG_RFKILL=m
  16945. +CONFIG_RFKILL_GPIO=m
  16946. +CONFIG_RFKILL_INPUT=y
  16947. +
  16948. +
  16949. +#
  16950. +# Ethernet (10 or 100Mbit)
  16951. +#
  16952. +
  16953. +CONFIG_NET_VENDOR_ADAPTEC=y
  16954. +CONFIG_ADAPTEC_STARFIRE=m
  16955. +
  16956. +CONFIG_NET_VENDOR_ALTEON=y
  16957. +CONFIG_ACENIC=m
  16958. +# CONFIG_ACENIC_OMIT_TIGON_I is not set
  16959. +
  16960. +CONFIG_NET_VENDOR_AMD=y
  16961. +CONFIG_PCNET32=m
  16962. +CONFIG_AMD8111_ETH=m
  16963. +CONFIG_PCMCIA_NMCLAN=m
  16964. +
  16965. +CONFIG_NET_VENDOR_ARC=y
  16966. +CONFIG_ARC_EMAC=m
  16967. +
  16968. +CONFIG_NET_VENDOR_ATHEROS=y
  16969. +CONFIG_ALX=m
  16970. +CONFIG_ATL2=m
  16971. +CONFIG_ATL1=m
  16972. +CONFIG_ATL1C=m
  16973. +CONFIG_ATL1E=m
  16974. +CONFIG_NET_CADENCE=y
  16975. +CONFIG_ARM_AT91_ETHER=m
  16976. +CONFIG_MACB=m
  16977. +
  16978. +CONFIG_NET_VENDOR_BROCADE=y
  16979. +CONFIG_BNA=m
  16980. +CONFIG_NET_CALXEDA_XGMAC=m
  16981. +
  16982. +CONFIG_NET_VENDOR_CHELSIO=y
  16983. +CONFIG_CHELSIO_T1=m
  16984. +CONFIG_CHELSIO_T1_1G=y
  16985. +CONFIG_CHELSIO_T3=m
  16986. +CONFIG_CHELSIO_T4=m
  16987. +CONFIG_CHELSIO_T4VF=m
  16988. +
  16989. +CONFIG_NET_VENDOR_CISCO=y
  16990. +CONFIG_ENIC=m
  16991. +
  16992. +CONFIG_NET_VENDOR_DEC=y
  16993. +#
  16994. +# Tulip family network device support
  16995. +#
  16996. +CONFIG_NET_TULIP=y
  16997. +CONFIG_DE2104X=m
  16998. +CONFIG_DE2104X_DSL=0
  16999. +CONFIG_TULIP=m
  17000. +# CONFIG_TULIP_NAPI is not set
  17001. +# CONFIG_TULIP_MWI is not set
  17002. +CONFIG_TULIP_MMIO=y
  17003. +# CONFIG_NI5010 is not set
  17004. +CONFIG_DE4X5=m
  17005. +CONFIG_WINBOND_840=m
  17006. +CONFIG_DM9102=m
  17007. +CONFIG_PCMCIA_XIRCOM=m
  17008. +CONFIG_ULI526X=m
  17009. +
  17010. +CONFIG_NET_VENDOR_DLINK=y
  17011. +CONFIG_DE600=m
  17012. +CONFIG_DE620=m
  17013. +CONFIG_DL2K=m
  17014. +CONFIG_SUNDANCE=m
  17015. +# CONFIG_SUNDANCE_MMIO is not set
  17016. +
  17017. +CONFIG_NET_VENDOR_EMULEX=y
  17018. +CONFIG_BE2NET=m
  17019. +
  17020. +CONFIG_NET_VENDOR_EXAR=y
  17021. +CONFIG_S2IO=m
  17022. +CONFIG_VXGE=m
  17023. +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
  17024. +
  17025. +# CONFIG_NET_VENDOR_FARADAY is not set
  17026. +# CONFIG_NET_VENDOR_FUJITSU is not set
  17027. +# CONFIG_NET_VENDOR_HP is not set
  17028. +CONFIG_NET_VENDOR_INTEL=y
  17029. +CONFIG_E100=m
  17030. +CONFIG_E1000=m
  17031. +CONFIG_E1000E=m
  17032. +CONFIG_IGB=m
  17033. +CONFIG_IGB_HWMON=y
  17034. +CONFIG_IGB_DCA=y
  17035. +CONFIG_IGB_PTP=y
  17036. +CONFIG_IGBVF=m
  17037. +CONFIG_IXGB=m
  17038. +CONFIG_IXGBEVF=m
  17039. +CONFIG_IXGBE=m
  17040. +CONFIG_IXGBE_DCA=y
  17041. +CONFIG_IXGBE_DCB=y
  17042. +CONFIG_IXGBE_HWMON=y
  17043. +CONFIG_IXGBE_PTP=y
  17044. +CONFIG_I40E=m
  17045. +# CONFIG_I40E_VXLAN is not set
  17046. +# CONFIG_I40E_DCB is not set
  17047. +# CONFIG_I40EVF is not set
  17048. +
  17049. +
  17050. +# CONFIG_NET_VENDOR_I825XX is not set
  17051. +CONFIG_NET_VENDOR_MARVELL=y
  17052. +CONFIG_MVMDIO=m
  17053. +CONFIG_SKGE=m
  17054. +# CONFIG_SKGE_DEBUG is not set
  17055. +CONFIG_SKGE_GENESIS=y
  17056. +CONFIG_SKY2=m
  17057. +# CONFIG_SKY2_DEBUG is not set
  17058. +
  17059. +CONFIG_NET_VENDOR_MICREL=y
  17060. +CONFIG_KSZ884X_PCI=m
  17061. +# CONFIG_KS8842 is not set
  17062. +# CONFIG_KS8851_MLL is not set
  17063. +
  17064. +CONFIG_NET_VENDOR_MYRI=y
  17065. +CONFIG_MYRI10GE=m
  17066. +CONFIG_MYRI10GE_DCA=y
  17067. +
  17068. +CONFIG_NATSEMI=m
  17069. +CONFIG_NS83820=m
  17070. +
  17071. +CONFIG_PCMCIA_AXNET=m
  17072. +CONFIG_NE2K_PCI=m
  17073. +CONFIG_NE3210=m
  17074. +CONFIG_PCMCIA_PCNET=m
  17075. +
  17076. +CONFIG_NET_VENDOR_NVIDIA=y
  17077. +CONFIG_FORCEDETH=m
  17078. +
  17079. +CONFIG_NET_VENDOR_OKI=y
  17080. +# CONFIG_PCH_GBE is not set
  17081. +# CONFIG_PCH_PTP is not set
  17082. +
  17083. +CONFIG_NET_PACKET_ENGINE=y
  17084. +CONFIG_HAMACHI=m
  17085. +CONFIG_YELLOWFIN=m
  17086. +
  17087. +CONFIG_NET_VENDOR_QLOGIC=y
  17088. +CONFIG_QLA3XXX=m
  17089. +CONFIG_QLCNIC=m
  17090. +CONFIG_QLCNIC_SRIOV=y
  17091. +CONFIG_QLCNIC_DCB=y
  17092. +CONFIG_QLGE=m
  17093. +CONFIG_NETXEN_NIC=m
  17094. +
  17095. +CONFIG_NET_VENDOR_REALTEK=y
  17096. +CONFIG_ATP=m
  17097. +CONFIG_8139CP=m
  17098. +CONFIG_8139TOO=m
  17099. +# CONFIG_8139TOO_PIO is not set
  17100. +# CONFIG_8139TOO_TUNE_TWISTER is not set
  17101. +CONFIG_8139TOO_8129=y
  17102. +# CONFIG_8139_OLD_RX_RESET is not set
  17103. +CONFIG_R8169=m
  17104. +
  17105. +
  17106. +CONFIG_NET_VENDOR_RDC=y
  17107. +CONFIG_R6040=m
  17108. +
  17109. +
  17110. +CONFIG_NET_VENDOR_SILAN=y
  17111. +CONFIG_SC92031=m
  17112. +
  17113. +CONFIG_NET_VENDOR_SIS=y
  17114. +CONFIG_SIS900=m
  17115. +CONFIG_SIS190=m
  17116. +
  17117. +CONFIG_PCMCIA_SMC91C92=m
  17118. +CONFIG_EPIC100=m
  17119. +CONFIG_SMSC9420=m
  17120. +
  17121. +# CONFIG_STMMAC_PLATFORM is not set
  17122. +# CONFIG_STMMAC_PCI is not set
  17123. +# CONFIG_STMMAC_DA is not set
  17124. +# CONFIG_STMMAC_DUAL_MAC is not set
  17125. +# CONFIG_STMMAC_TIMER is not set
  17126. +# CONFIG_STMMAC_DEBUG_FS is not set
  17127. +
  17128. +CONFIG_NET_VENDOR_SUN=y
  17129. +CONFIG_HAPPYMEAL=m
  17130. +CONFIG_SUNGEM=m
  17131. +CONFIG_CASSINI=m
  17132. +CONFIG_NIU=m
  17133. +
  17134. +CONFIG_NET_VENDOR_TEHUTI=y
  17135. +CONFIG_TEHUTI=m
  17136. +
  17137. +CONFIG_NET_VENDOR_TI=y
  17138. +CONFIG_TLAN=m
  17139. +
  17140. +CONFIG_VIA_RHINE=m
  17141. +CONFIG_VIA_RHINE_MMIO=y
  17142. +
  17143. +CONFIG_WIZNET_W5100=m
  17144. +CONFIG_WIZNET_W5300=m
  17145. +CONFIG_NET_VENDOR_XIRCOM=y
  17146. +CONFIG_PCMCIA_XIRC2PS=m
  17147. +
  17148. +CONFIG_AMD_PHY=m
  17149. +CONFIG_BROADCOM_PHY=m
  17150. +CONFIG_BCM87XX_PHY=m
  17151. +CONFIG_CICADA_PHY=m
  17152. +CONFIG_DAVICOM_PHY=m
  17153. +CONFIG_DP83640_PHY=m
  17154. +CONFIG_FIXED_PHY=y
  17155. +CONFIG_MDIO_BITBANG=m
  17156. +CONFIG_NATIONAL_PHY=m
  17157. +CONFIG_ICPLUS_PHY=m
  17158. +CONFIG_BCM63XX_PHY=m
  17159. +CONFIG_LSI_ET1011C_PHY=m
  17160. +CONFIG_LXT_PHY=m
  17161. +CONFIG_MARVELL_PHY=m
  17162. +CONFIG_QSEMI_PHY=m
  17163. +CONFIG_REALTEK_PHY=m
  17164. +CONFIG_SMSC_PHY=m
  17165. +CONFIG_STE10XP=m
  17166. +CONFIG_VITESSE_PHY=m
  17167. +CONFIG_MICREL_PHY=m
  17168. +
  17169. +CONFIG_MII=m
  17170. +CONFIG_NET_CORE=y
  17171. +CONFIG_NET_VENDOR_3COM=y
  17172. +CONFIG_VORTEX=m
  17173. +CONFIG_TYPHOON=m
  17174. +CONFIG_DNET=m
  17175. +
  17176. +
  17177. +CONFIG_LNE390=m
  17178. +CONFIG_ES3210=m
  17179. +CONFIG_NET_PCI=y
  17180. +CONFIG_B44=m
  17181. +CONFIG_B44_PCI=y
  17182. +CONFIG_BNX2=m
  17183. +CONFIG_BNX2X=m
  17184. +CONFIG_BNX2X_SRIOV=y
  17185. +CONFIG_CNIC=m
  17186. +CONFIG_FEALNX=m
  17187. +CONFIG_NET_POCKET=y
  17188. +
  17189. +#
  17190. +# Ethernet (1000 Mbit)
  17191. +#
  17192. +CONFIG_TIGON3=m
  17193. +CONFIG_JME=m
  17194. +
  17195. +#
  17196. +# Ethernet (10000 Mbit)
  17197. +#
  17198. +# CONFIG_IP1000 is not set
  17199. +# CONFIG_MLX4_EN is not set
  17200. +# CONFIG_SFC is not set
  17201. +
  17202. +# CONFIG_FDDI is not set
  17203. +# CONFIG_DEFXX is not set
  17204. +# CONFIG_SKFP is not set
  17205. +# CONFIG_HIPPI is not set
  17206. +# CONFIG_PLIP is not set
  17207. +CONFIG_PPP=m
  17208. +CONFIG_PPP_MULTILINK=y
  17209. +CONFIG_PPP_FILTER=y
  17210. +CONFIG_PPP_ASYNC=m
  17211. +CONFIG_PPP_SYNC_TTY=m
  17212. +CONFIG_PPP_DEFLATE=m
  17213. +CONFIG_IPPP_FILTER=y
  17214. +CONFIG_PPP_BSDCOMP=y
  17215. +CONFIG_PPPOE=m
  17216. +CONFIG_PPP_MPPE=m
  17217. +CONFIG_SLIP=m
  17218. +CONFIG_SLIP_COMPRESSED=y
  17219. +CONFIG_SLIP_SMART=y
  17220. +# CONFIG_SLIP_MODE_SLIP6 is not set
  17221. +
  17222. +#
  17223. +# Wireless LAN
  17224. +#
  17225. +#
  17226. +# CONFIG_STRIP is not set
  17227. +# CONFIG_PCMCIA_RAYCS is not set
  17228. +
  17229. +CONFIG_CFG80211_WEXT=y
  17230. +# CONFIG_CFG80211_REG_DEBUG is not set
  17231. +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
  17232. +CONFIG_CFG80211_DEFAULT_PS=y
  17233. +CONFIG_NL80211=y
  17234. +# CONFIG_NL80211_TESTMODE is not set
  17235. +# CONFIG_WIRELESS_EXT_SYSFS is not set
  17236. +CONFIG_LIB80211=m
  17237. +CONFIG_LIB80211_CRYPT_WEP=m
  17238. +CONFIG_LIB80211_CRYPT_CCMP=m
  17239. +CONFIG_LIB80211_CRYPT_TKIP=m
  17240. +# CONFIG_LIB80211_DEBUG is not set
  17241. +
  17242. +CONFIG_MAC80211=m
  17243. +CONFIG_MAC80211_RC_MINSTREL=y
  17244. +# CONFIG_MAC80211_RC_DEFAULT_PID is not set
  17245. +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
  17246. +CONFIG_MAC80211_RC_DEFAULT="minstrel"
  17247. +CONFIG_MAC80211_MESH=y
  17248. +CONFIG_MAC80211_LEDS=y
  17249. +# CONFIG_MAC80211_DEBUG_MENU is not set
  17250. +
  17251. +# CONFIG_WIMAX is not set
  17252. +
  17253. +# CONFIG_ADM8211 is not set
  17254. +CONFIG_ATH_COMMON=m
  17255. +CONFIG_ATH_CARDS=m
  17256. +CONFIG_ATH5K=m
  17257. +CONFIG_ATH5K_DEBUG=y
  17258. +# CONFIG_ATH5K_TRACER is not set
  17259. +CONFIG_ATH6KL=m
  17260. +CONFIG_ATH6KL_DEBUG=y
  17261. +CONFIG_ATH6KL_SDIO=m
  17262. +CONFIG_ATH6KL_USB=m
  17263. +# CONFIG_ATH6KL_TRACING is not set
  17264. +CONFIG_AR5523=m
  17265. +CONFIG_ATH9K=m
  17266. +CONFIG_ATH9K_PCI=y
  17267. +CONFIG_ATH9K_AHB=y
  17268. +# CONFIG_ATH9K_DEBUG is not set
  17269. +# CONFIG_ATH9K_MAC_DEBUG is not set
  17270. +CONFIG_ATH9K_HTC=m
  17271. +CONFIG_ATH9K_BTCOEX_SUPPORT=y
  17272. +# CONFIG_ATH9K_LEGACY_RATE_CONTROL is not set
  17273. +# CONFIG_ATH9K_WOW is not set
  17274. +#
  17275. +CONFIG_ATH10K=m
  17276. +CONFIG_ATH10K_PCI=m
  17277. +# CONFIG_ATH10K_DEBUG is not set
  17278. +# CONFIG_ATH10K_TRACING is not set
  17279. +CONFIG_ATH10K_DEBUGFS=y
  17280. +CONFIG_WCN36XX=m
  17281. +# CONFIG_WCN36XX_DEBUGFS is not set
  17282. +CONFIG_WIL6210=m
  17283. +CONFIG_WIL6210_ISR_COR=y
  17284. +# CONFIG_WIL6210_TRACING is not set
  17285. +CONFIG_CARL9170=m
  17286. +CONFIG_CARL9170_LEDS=y
  17287. +# CONFIG_CARL9170_HWRNG is not set
  17288. +CONFIG_AT76C50X_USB=m
  17289. +# CONFIG_AIRO is not set
  17290. +# CONFIG_AIRO_CS is not set
  17291. +# CONFIG_ATMEL is not set
  17292. +CONFIG_B43=m
  17293. +CONFIG_B43_PCMCIA=y
  17294. +CONFIG_B43_SDIO=y
  17295. +CONFIG_B43_BCMA=y
  17296. +# CONFIG_B43_BCMA_EXTRA is not set
  17297. +CONFIG_B43_BCMA_PIO=y
  17298. +# CONFIG_B43_DEBUG is not set
  17299. +CONFIG_B43_PHY_LP=y
  17300. +CONFIG_B43_PHY_N=y
  17301. +CONFIG_B43_PHY_HT=y
  17302. +# CONFIG_B43_FORCE_PIO is not set
  17303. +CONFIG_B43LEGACY=m
  17304. +# CONFIG_B43LEGACY_DEBUG is not set
  17305. +CONFIG_B43LEGACY_DMA=y
  17306. +CONFIG_B43LEGACY_PIO=y
  17307. +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
  17308. +# CONFIG_B43LEGACY_DMA_MODE is not set
  17309. +# CONFIG_B43LEGACY_PIO_MODE is not set
  17310. +CONFIG_BRCMSMAC=m
  17311. +# CONFIG_BRCMFMAC_SDIO_OOB is not set
  17312. +CONFIG_BRCMFMAC_USB=y
  17313. +# CONFIG_BRCM_TRACING is not set
  17314. +# CONFIG_BRCMISCAN is not set
  17315. +# CONFIG_BRCMDBG is not set
  17316. +CONFIG_HERMES=m
  17317. +CONFIG_HERMES_CACHE_FW_ON_INIT=y
  17318. +# CONFIG_HERMES_PRISM is not set
  17319. +CONFIG_NORTEL_HERMES=m
  17320. +CONFIG_PCI_HERMES=m
  17321. +CONFIG_PLX_HERMES=m
  17322. +CONFIG_PCMCIA_HERMES=m
  17323. +CONFIG_ORINOCO_USB=m
  17324. +# CONFIG_TMD_HERMES is not set
  17325. +# CONFIG_PCMCIA_SPECTRUM is not set
  17326. +CONFIG_CW1200=m
  17327. +CONFIG_CW1200_WLAN_SDIO=m
  17328. +CONFIG_CW1200_WLAN_SPI=m
  17329. +# CONFIG_HOSTAP is not set
  17330. +# CONFIG_IPW2100 is not set
  17331. +# CONFIG_IPW2200 is not set
  17332. +# CONFIG_IPW2100_DEBUG is not set
  17333. +# CONFIG_IPW2200_DEBUG is not set
  17334. +# CONFIG_LIBIPW_DEBUG is not set
  17335. +CONFIG_LIBERTAS=m
  17336. +CONFIG_LIBERTAS_USB=m
  17337. +CONFIG_LIBERTAS_CS=m
  17338. +CONFIG_LIBERTAS_SDIO=m
  17339. +# CONFIG_LIBERTAS_DEBUG is not set
  17340. +# CONFIG_LIBERTAS_THINFIRM is not set
  17341. +CONFIG_LIBERTAS_MESH=y
  17342. +CONFIG_IWLWIFI=m
  17343. +CONFIG_IWLDVM=m
  17344. +CONFIG_IWLMVM=m
  17345. +CONFIG_IWLWIFI_DEBUG=y
  17346. +CONFIG_IWLWIFI_DEVICE_SVTOOL=y
  17347. +# CONFIG_IWLWIFI_EXPERIMENTAL_MFP is not set
  17348. +CONFIG_IWLWIFI_UCODE16=y
  17349. +# CONFIG_IWLWIFI_P2P is not set
  17350. +CONFIG_IWLEGACY=m
  17351. +CONFIG_IWLEGACY_DEBUG=y
  17352. +# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set
  17353. +CONFIG_IWL4965=y
  17354. +CONFIG_IWL3945=m
  17355. +# CONFIG_IWM is not set
  17356. +# CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE is not set
  17357. +CONFIG_MAC80211_HWSIM=m
  17358. +CONFIG_P54_COMMON=m
  17359. +CONFIG_P54_USB=m
  17360. +CONFIG_P54_PCI=m
  17361. +CONFIG_MWL8K=m
  17362. +# CONFIG_PRISM54 is not set
  17363. +# CONFIG_PCMCIA_WL3501 is not set
  17364. +CONFIG_RT2X00=m
  17365. +# CONFIG_RT2X00_DEBUG is not set
  17366. +CONFIG_RT2400PCI=m
  17367. +CONFIG_RT2500PCI=m
  17368. +CONFIG_RT61PCI=m
  17369. +CONFIG_RT2500USB=m
  17370. +CONFIG_RT2800USB=m
  17371. +CONFIG_RT2800USB_RT33XX=y
  17372. +CONFIG_RT2800USB_RT35XX=y
  17373. +CONFIG_RT2800USB_RT3573=y
  17374. +CONFIG_RT2800USB_RT53XX=y
  17375. +CONFIG_RT2800USB_RT55XX=y
  17376. +CONFIG_RT2800USB_UNKNOWN=y
  17377. +CONFIG_RT2800PCI=m
  17378. +CONFIG_RT2800PCI_RT3290=y
  17379. +CONFIG_RT2800PCI_RT33XX=y
  17380. +CONFIG_RT2800PCI_RT35XX=y
  17381. +CONFIG_RT2800PCI_RT53XX=y
  17382. +CONFIG_RT73USB=m
  17383. +CONFIG_RTL8180=m
  17384. +CONFIG_RTL8187=m
  17385. +# CONFIG_USB_ZD1201 is not set
  17386. +# CONFIG_USB_NET_SR9800 is not set
  17387. +CONFIG_USB_NET_RNDIS_WLAN=m
  17388. +CONFIG_USB_NET_KALMIA=m
  17389. +CONFIG_USB_NET_QMI_WWAN=m
  17390. +CONFIG_USB_NET_SMSC75XX=m
  17391. +# CONFIG_WL_TI is not set
  17392. +CONFIG_ZD1211RW=m
  17393. +# CONFIG_ZD1211RW_DEBUG is not set
  17394. +
  17395. +CONFIG_WL12XX=m
  17396. +CONFIG_WL12XX_SPI=m
  17397. +CONFIG_WL12XX_SDIO=m
  17398. +
  17399. +CONFIG_WL1251=m
  17400. +CONFIG_WL1251_SPI=m
  17401. +CONFIG_WL1251_SDIO=m
  17402. +
  17403. +CONFIG_RTL_CARDS=m
  17404. +CONFIG_RTLWIFI=m
  17405. +CONFIG_RTL8192CE=m
  17406. +CONFIG_RTL8192SE=m
  17407. +CONFIG_RTL8192CU=m
  17408. +CONFIG_RTL8192DE=m
  17409. +CONFIG_RTL8723AE=m
  17410. +CONFIG_RTL8188EE=m
  17411. +
  17412. +CONFIG_MWIFIEX=m
  17413. +CONFIG_MWIFIEX_SDIO=m
  17414. +CONFIG_MWIFIEX_PCIE=m
  17415. +CONFIG_MWIFIEX_USB=m
  17416. +
  17417. +#
  17418. +# Token Ring devices
  17419. +#
  17420. +# CONFIG_TR is not set
  17421. +
  17422. +CONFIG_NET_FC=y
  17423. +
  17424. +#
  17425. +# Wan interfaces
  17426. +#
  17427. +# CONFIG_WAN is not set
  17428. +
  17429. +#
  17430. +# PCMCIA network device support
  17431. +#
  17432. +CONFIG_NET_PCMCIA=y
  17433. +CONFIG_PCMCIA_3C589=m
  17434. +CONFIG_PCMCIA_3C574=m
  17435. +CONFIG_PCMCIA_FMVJ18X=m
  17436. +
  17437. +#
  17438. +# Amateur Radio support
  17439. +#
  17440. +CONFIG_HAMRADIO=y
  17441. +CONFIG_AX25=m
  17442. +CONFIG_AX25_DAMA_SLAVE=y
  17443. +
  17444. +# CONFIG_CAN is not set
  17445. +
  17446. +CONFIG_NETROM=m
  17447. +CONFIG_ROSE=m
  17448. +CONFIG_MKISS=m
  17449. +CONFIG_6PACK=m
  17450. +CONFIG_BPQETHER=m
  17451. +CONFIG_BAYCOM_SER_FDX=m
  17452. +CONFIG_BAYCOM_SER_HDX=m
  17453. +CONFIG_BAYCOM_PAR=m
  17454. +CONFIG_BAYCOM_EPP=m
  17455. +CONFIG_YAM=m
  17456. +
  17457. +CONFIG_NFC=m
  17458. +CONFIG_NFC_DIGITAL=m
  17459. +CONFIG_NFC_NCI=m
  17460. +CONFIG_NFC_HCI=m
  17461. +CONFIG_NFC_SHDLC=y
  17462. +CONFIG_NFC_LLCP=y
  17463. +CONFIG_NFC_SIM=m
  17464. +CONFIG_NFC_MRVL=m
  17465. +CONFIG_NFC_MRVL_USB=m
  17466. +
  17467. +#
  17468. +# Near Field Communication (NFC) devices
  17469. +#
  17470. +CONFIG_NFC_PORT100=m
  17471. +CONFIG_NFC_PN544=m
  17472. +CONFIG_NFC_PN544_I2C=m
  17473. +CONFIG_NFC_PN533=m
  17474. +CONFIG_NFC_MICROREAD=m
  17475. +CONFIG_NFC_MICROREAD_I2C=m
  17476. +
  17477. +#
  17478. +# IrDA (infrared) support
  17479. +#
  17480. +CONFIG_IRDA=m
  17481. +# CONFIG_IRDA_DEBUG is not set
  17482. +CONFIG_IRLAN=m
  17483. +CONFIG_IRNET=m
  17484. +CONFIG_IRCOMM=m
  17485. +# CONFIG_IRDA_ULTRA is not set
  17486. +CONFIG_IRDA_CACHE_LAST_LSAP=y
  17487. +CONFIG_IRDA_FAST_RR=y
  17488. +CONFIG_IRTTY_SIR=m
  17489. +CONFIG_DONGLE=y
  17490. +CONFIG_ACTISYS_DONGLE=m
  17491. +CONFIG_ACT200L_DONGLE=m
  17492. +CONFIG_ESI_DONGLE=m
  17493. +CONFIG_GIRBIL_DONGLE=m
  17494. +CONFIG_KINGSUN_DONGLE=m
  17495. +CONFIG_KSDAZZLE_DONGLE=m
  17496. +CONFIG_KS959_DONGLE=m
  17497. +CONFIG_LITELINK_DONGLE=m
  17498. +CONFIG_MA600_DONGLE=m
  17499. +CONFIG_MCP2120_DONGLE=m
  17500. +CONFIG_OLD_BELKIN_DONGLE=m
  17501. +CONFIG_TEKRAM_DONGLE=m
  17502. +CONFIG_TOIM3232_DONGLE=m
  17503. +
  17504. +CONFIG_ALI_FIR=m
  17505. +CONFIG_MCS_FIR=m
  17506. +CONFIG_NSC_FIR=m
  17507. +CONFIG_SIGMATEL_FIR=m
  17508. +CONFIG_SMC_IRCC_FIR=m
  17509. +# CONFIG_TOSHIBA_FIR is not set
  17510. +CONFIG_USB_IRDA=m
  17511. +CONFIG_VLSI_FIR=m
  17512. +CONFIG_VIA_FIR=m
  17513. +CONFIG_WINBOND_FIR=m
  17514. +
  17515. +#
  17516. +# Bluetooth support
  17517. +#
  17518. +CONFIG_BT=m
  17519. +CONFIG_BT_L2CAP=y
  17520. +CONFIG_BT_SCO=y
  17521. +CONFIG_BT_CMTP=m
  17522. +CONFIG_BT_RFCOMM=m
  17523. +CONFIG_BT_RFCOMM_TTY=y
  17524. +CONFIG_BT_BNEP=m
  17525. +CONFIG_BT_BNEP_MC_FILTER=y
  17526. +CONFIG_BT_BNEP_PROTO_FILTER=y
  17527. +CONFIG_BT_HIDP=m
  17528. +
  17529. +#
  17530. +# Bluetooth device drivers
  17531. +#
  17532. +CONFIG_BT_HCIBTUSB=m
  17533. +# Disable the BT_HCIUSB driver.
  17534. +# It sucks more power than BT_HCIBTUSB which has the same functionality.
  17535. +CONFIG_BT_HCIUART=m
  17536. +CONFIG_BT_HCIUART_H4=y
  17537. +CONFIG_BT_HCIUART_BCSP=y
  17538. +CONFIG_BT_HCIUART_ATH3K=y
  17539. +CONFIG_BT_HCIUART_3WIRE=y
  17540. +CONFIG_BT_HCIDTL1=m
  17541. +CONFIG_BT_HCIBT3C=m
  17542. +CONFIG_BT_HCIBLUECARD=m
  17543. +CONFIG_BT_HCIBTUART=m
  17544. +CONFIG_BT_HCIVHCI=m
  17545. +CONFIG_BT_HCIBCM203X=m
  17546. +CONFIG_BT_HCIBFUSB=m
  17547. +CONFIG_BT_HCIBPA10X=m
  17548. +CONFIG_BT_HCIBTSDIO=m
  17549. +CONFIG_BT_HCIUART_LL=y
  17550. +CONFIG_BT_MRVL=m
  17551. +CONFIG_BT_MRVL_SDIO=m
  17552. +CONFIG_BT_ATH3K=m
  17553. +CONFIG_BT_WILINK=m
  17554. +
  17555. +#
  17556. +# ISDN subsystem
  17557. +#
  17558. +CONFIG_ISDN=y
  17559. +CONFIG_MISDN=m
  17560. +CONFIG_MISDN_DSP=m
  17561. +CONFIG_MISDN_L1OIP=m
  17562. +CONFIG_MISDN_AVMFRITZ=m
  17563. +CONFIG_MISDN_SPEEDFAX=m
  17564. +CONFIG_MISDN_INFINEON=m
  17565. +CONFIG_MISDN_W6692=m
  17566. +CONFIG_MISDN_NETJET=m
  17567. +
  17568. +#
  17569. +# mISDN hardware drivers
  17570. +#
  17571. +CONFIG_MISDN_HFCPCI=m
  17572. +CONFIG_MISDN_HFCMULTI=m
  17573. +CONFIG_ISDN_I4L=m
  17574. +CONFIG_ISDN_DRV_AVMB1_B1PCI=m
  17575. +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
  17576. +CONFIG_ISDN_DRV_AVMB1_T1PCI=m
  17577. +CONFIG_ISDN_DRV_AVMB1_C4=m
  17578. +
  17579. +CONFIG_MISDN_HFCUSB=m
  17580. +
  17581. +CONFIG_ISDN_PPP=y
  17582. +CONFIG_ISDN_PPP_VJ=y
  17583. +CONFIG_ISDN_MPP=y
  17584. +# CONFIG_ISDN_PPP_BSDCOMP is not set
  17585. +CONFIG_ISDN_TTY_FAX=y
  17586. +CONFIG_DE_AOC=y
  17587. +
  17588. +CONFIG_ISDN_AUDIO=y
  17589. +
  17590. +CONFIG_ISDN_DRV_HISAX=m
  17591. +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
  17592. +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
  17593. +
  17594. +CONFIG_ISDN_CAPI_CAPIDRV=m
  17595. +CONFIG_ISDN_DIVERSION=m
  17596. +
  17597. +CONFIG_HISAX_EURO=y
  17598. +CONFIG_HISAX_1TR6=y
  17599. +CONFIG_HISAX_NI1=y
  17600. +CONFIG_HISAX_MAX_CARDS=8
  17601. +CONFIG_HISAX_16_3=y
  17602. +CONFIG_HISAX_TELESPCI=y
  17603. +CONFIG_HISAX_S0BOX=y
  17604. +CONFIG_HISAX_FRITZPCI=y
  17605. +CONFIG_HISAX_AVM_A1_PCMCIA=y
  17606. +CONFIG_HISAX_ELSA=y
  17607. +CONFIG_HISAX_DIEHLDIVA=y
  17608. +CONFIG_HISAX_SEDLBAUER=y
  17609. +CONFIG_HISAX_NETJET=y
  17610. +CONFIG_HISAX_NETJET_U=y
  17611. +CONFIG_HISAX_NICCY=y
  17612. +CONFIG_HISAX_BKM_A4T=y
  17613. +CONFIG_HISAX_SCT_QUADRO=y
  17614. +CONFIG_HISAX_GAZEL=y
  17615. +CONFIG_HISAX_HFC_PCI=y
  17616. +CONFIG_HISAX_W6692=y
  17617. +CONFIG_HISAX_HFC_SX=y
  17618. +CONFIG_HISAX_ENTERNOW_PCI=y
  17619. +# CONFIG_HISAX_DEBUG is not set
  17620. +CONFIG_HISAX_AVM_A1_CS=m
  17621. +CONFIG_HISAX_ST5481=m
  17622. +# CONFIG_HISAX_HFCUSB is not set
  17623. +CONFIG_HISAX_FRITZ_PCIPNP=m
  17624. +CONFIG_HISAX_NO_SENDCOMPLETE=y
  17625. +CONFIG_HISAX_NO_LLC=y
  17626. +CONFIG_HISAX_NO_KEYPAD=y
  17627. +CONFIG_HISAX_SEDLBAUER_CS=m
  17628. +CONFIG_HISAX_ELSA_CS=m
  17629. +CONFIG_HISAX_TELES_CS=m
  17630. +CONFIG_HISAX_HFC4S8S=m
  17631. +
  17632. +CONFIG_ISDN_DRV_LOOP=m
  17633. +CONFIG_HYSDN=m
  17634. +CONFIG_HYSDN_CAPI=y
  17635. +
  17636. +
  17637. +#
  17638. +# CAPI subsystem
  17639. +#
  17640. +CONFIG_ISDN_CAPI=m
  17641. +# CONFIG_CAPI_TRACE is not set
  17642. +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
  17643. +CONFIG_ISDN_CAPI_MIDDLEWARE=y
  17644. +CONFIG_ISDN_CAPI_CAPI20=m
  17645. +
  17646. +#
  17647. +# CAPI hardware drivers
  17648. +#
  17649. +
  17650. +#
  17651. +# Active AVM cards
  17652. +#
  17653. +CONFIG_CAPI_AVM=y
  17654. +
  17655. +#
  17656. +# Active Eicon DIVA Server cards
  17657. +#
  17658. +# CONFIG_CAPI_EICON is not set
  17659. +CONFIG_ISDN_DIVAS=m
  17660. +CONFIG_ISDN_DIVAS_BRIPCI=y
  17661. +CONFIG_ISDN_DIVAS_PRIPCI=y
  17662. +CONFIG_ISDN_DIVAS_DIVACAPI=m
  17663. +CONFIG_ISDN_DIVAS_USERIDI=m
  17664. +CONFIG_ISDN_DIVAS_MAINT=m
  17665. +
  17666. +CONFIG_ISDN_DRV_GIGASET=m
  17667. +CONFIG_GIGASET_CAPI=y
  17668. +CONFIG_GIGASET_BASE=m
  17669. +CONFIG_GIGASET_M101=m
  17670. +CONFIG_GIGASET_M105=m
  17671. +# CONFIG_GIGASET_DEBUG is not set
  17672. +
  17673. +#
  17674. +# Telephony Support
  17675. +#
  17676. +# CONFIG_PHONE is not set
  17677. +
  17678. +#
  17679. +# Input device support
  17680. +#
  17681. +CONFIG_INPUT=y
  17682. +CONFIG_INPUT_FF_MEMLESS=m
  17683. +
  17684. +#
  17685. +# Userland interfaces
  17686. +#
  17687. +CONFIG_INPUT_MOUSEDEV=y
  17688. +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
  17689. +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
  17690. +CONFIG_INPUT_JOYDEV=m
  17691. +# CONFIG_INPUT_MATRIXKMAP is not set
  17692. +
  17693. +CONFIG_INPUT_TABLET=y
  17694. +CONFIG_TABLET_USB_ACECAD=m
  17695. +CONFIG_TABLET_USB_AIPTEK=m
  17696. +CONFIG_TABLET_USB_GTCO=m
  17697. +CONFIG_TABLET_USB_HANWANG=m
  17698. +CONFIG_TABLET_USB_KBTAB=m
  17699. +CONFIG_TABLET_USB_WACOM=m
  17700. +
  17701. +CONFIG_INPUT_POWERMATE=m
  17702. +CONFIG_INPUT_YEALINK=m
  17703. +CONFIG_INPUT_CM109=m
  17704. +CONFIG_INPUT_POLLDEV=m
  17705. +CONFIG_INPUT_SPARSEKMAP=m
  17706. +# CONFIG_INPUT_ADXL34X is not set
  17707. +# CONFIG_INPUT_BMA150 is not set
  17708. +# CONFIG_INPUT_IMS_PCU is not set
  17709. +CONFIG_INPUT_CMA3000=m
  17710. +CONFIG_INPUT_CMA3000_I2C=m
  17711. +CONFIG_INPUT_IDEAPAD_SLIDEBAR=m
  17712. +
  17713. +#
  17714. +# Input I/O drivers
  17715. +#
  17716. +CONFIG_GAMEPORT=m
  17717. +CONFIG_GAMEPORT_NS558=m
  17718. +CONFIG_GAMEPORT_L4=m
  17719. +CONFIG_GAMEPORT_EMU10K1=m
  17720. +CONFIG_GAMEPORT_FM801=m
  17721. +CONFIG_SERIO=y
  17722. +CONFIG_SERIO_I8042=y
  17723. +CONFIG_SERIO_RAW=m
  17724. +CONFIG_SERIO_ALTERA_PS2=m
  17725. +# CONFIG_SERIO_PS2MULT is not set
  17726. +CONFIG_SERIO_ARC_PS2=m
  17727. +# CONFIG_SERIO_APBPS2 is not set
  17728. +
  17729. +# CONFIG_SERIO_CT82C710 is not set
  17730. +# CONFIG_SERIO_OLPC_APSP is not set
  17731. +# CONFIG_SERIO_PARKBD is not set
  17732. +# CONFIG_SERIO_PCIPS2 is not set
  17733. +# CONFIG_SERIO_LIBPS2 is not set
  17734. +
  17735. +#
  17736. +# Input Device Drivers
  17737. +#
  17738. +CONFIG_INPUT_KEYBOARD=y
  17739. +# CONFIG_KEYBOARD_SUNKBD is not set
  17740. +# CONFIG_KEYBOARD_SH_KEYSC is not set
  17741. +# CONFIG_KEYBOARD_XTKBD is not set
  17742. +# CONFIG_KEYBOARD_MATRIX is not set
  17743. +# CONFIG_KEYBOARD_NEWTON is not set
  17744. +# CONFIG_KEYBOARD_STOWAWAY is not set
  17745. +# CONFIG_KEYBOARD_LKKBD is not set
  17746. +# CONFIG_KEYBOARD_LM8323 is not set
  17747. +# CONFIG_KEYBOARD_LM8333 is not set
  17748. +# CONFIG_KEYBOARD_MAX7359 is not set
  17749. +# CONFIG_KEYBOARD_ADP5589 is not set
  17750. +# CONFIG_KEYBOARD_MPR121 is not set
  17751. +# CONFIG_KEYBOARD_QT1070 is not set
  17752. +# CONFIG_KEYBOARD_MCS is not set
  17753. +# CONFIG_KEYBOARD_OPENCORES is not set
  17754. +# CONFIG_KEYBOARD_SAMSUNG is not set
  17755. +# CONFIG_KEYBOARD_QT2160 is not set
  17756. +# CONFIG_KEYBOARD_TCA6416 is not set
  17757. +# CONFIG_KEYBOARD_TCA8418 is not set
  17758. +# CONFIG_KEYBOARD_OMAP4 is not set
  17759. +CONFIG_INPUT_MOUSE=y
  17760. +# CONFIG_MOUSE_PS2_TOUCHKIT is not set
  17761. +CONFIG_MOUSE_PS2_ELANTECH=y
  17762. +CONFIG_MOUSE_PS2_SENTELIC=y
  17763. +CONFIG_MOUSE_SERIAL=m
  17764. +CONFIG_MOUSE_VSXXXAA=m
  17765. +CONFIG_MOUSE_APPLETOUCH=m
  17766. +CONFIG_MOUSE_BCM5974=m
  17767. +CONFIG_MOUSE_SYNAPTICS_I2C=m
  17768. +CONFIG_MOUSE_SYNAPTICS_USB=m
  17769. +CONFIG_MOUSE_CYAPA=m
  17770. +CONFIG_INPUT_JOYSTICK=y
  17771. +CONFIG_JOYSTICK_ANALOG=m
  17772. +CONFIG_JOYSTICK_A3D=m
  17773. +CONFIG_JOYSTICK_ADI=m
  17774. +CONFIG_JOYSTICK_COBRA=m
  17775. +CONFIG_JOYSTICK_GF2K=m
  17776. +CONFIG_JOYSTICK_GRIP=m
  17777. +CONFIG_JOYSTICK_GRIP_MP=m
  17778. +CONFIG_JOYSTICK_GUILLEMOT=m
  17779. +CONFIG_JOYSTICK_INTERACT=m
  17780. +CONFIG_JOYSTICK_SIDEWINDER=m
  17781. +CONFIG_JOYSTICK_TMDC=m
  17782. +CONFIG_JOYSTICK_IFORCE=m
  17783. +CONFIG_JOYSTICK_IFORCE_USB=y
  17784. +CONFIG_JOYSTICK_IFORCE_232=y
  17785. +CONFIG_JOYSTICK_WARRIOR=m
  17786. +CONFIG_JOYSTICK_MAGELLAN=m
  17787. +CONFIG_JOYSTICK_SPACEORB=m
  17788. +CONFIG_JOYSTICK_SPACEBALL=m
  17789. +CONFIG_JOYSTICK_STINGER=m
  17790. +CONFIG_JOYSTICK_DB9=m
  17791. +CONFIG_JOYSTICK_GAMECON=m
  17792. +CONFIG_JOYSTICK_TURBOGRAFX=m
  17793. +CONFIG_JOYSTICK_JOYDUMP=m
  17794. +CONFIG_JOYSTICK_TWIDJOY=m
  17795. +CONFIG_JOYSTICK_WALKERA0701=m
  17796. +CONFIG_JOYSTICK_XPAD=m
  17797. +CONFIG_JOYSTICK_XPAD_FF=y
  17798. +CONFIG_JOYSTICK_XPAD_LEDS=y
  17799. +CONFIG_JOYSTICK_ZHENHUA=m
  17800. +# CONFIG_JOYSTICK_AS5011 is not set
  17801. +
  17802. +CONFIG_INPUT_TOUCHSCREEN=y
  17803. +# CONFIG_TOUCHSCREEN_AD7879 is not set
  17804. +CONFIG_TOUCHSCREEN_AD7879_I2C=m
  17805. +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
  17806. +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
  17807. +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
  17808. +CONFIG_TOUCHSCREEN_DYNAPRO=m
  17809. +CONFIG_TOUCHSCREEN_EDT_FT5X06=m
  17810. +CONFIG_TOUCHSCREEN_EETI=m
  17811. +CONFIG_TOUCHSCREEN_EGALAX=m
  17812. +CONFIG_TOUCHSCREEN_ELO=m
  17813. +CONFIG_TOUCHSCREEN_FUJITSU=m
  17814. +CONFIG_TOUCHSCREEN_GUNZE=m
  17815. +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
  17816. +CONFIG_TOUCHSCREEN_INEXIO=m
  17817. +CONFIG_TOUCHSCREEN_ILI210X=m
  17818. +CONFIG_TOUCHSCREEN_MMS114=m
  17819. +CONFIG_TOUCHSCREEN_MTOUCH=m
  17820. +CONFIG_TOUCHSCREEN_MCS5000=m
  17821. +CONFIG_TOUCHSCREEN_MK712=m
  17822. +CONFIG_TOUCHSCREEN_PENMOUNT=m
  17823. +# CONFIG_TOUCHSCREEN_SUR40 is not set
  17824. +# CONFIG_TOUCHSCREEN_TPS6507X is not set
  17825. +CONFIG_TOUCHSCREEN_TSC_SERIO=m
  17826. +CONFIG_TOUCHSCREEN_TSC2007=m
  17827. +CONFIG_TOUCHSCREEN_TOUCHIT213=m
  17828. +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
  17829. +CONFIG_TOUCHSCREEN_TOUCHWIN=m
  17830. +CONFIG_TOUCHSCREEN_PIXCIR=m
  17831. +CONFIG_TOUCHSCREEN_UCB1400=m
  17832. +CONFIG_TOUCHSCREEN_WACOM_W8001=m
  17833. +CONFIG_TOUCHSCREEN_WACOM_I2C=m
  17834. +CONFIG_TOUCHSCREEN_USB_E2I=y
  17835. +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
  17836. +# CONFIG_TOUCHSCREEN_WM97XX is not set
  17837. +CONFIG_TOUCHSCREEN_W90X900=m
  17838. +# CONFIG_TOUCHSCREEN_BU21013 is not set
  17839. +CONFIG_TOUCHSCREEN_ST1232=m
  17840. +CONFIG_TOUCHSCREEN_ATMEL_MXT=m
  17841. +# CONFIG_TOUCHSCREEN_MAX11801 is not set
  17842. +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m
  17843. +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m
  17844. +CONFIG_TOUCHSCREEN_ZFORCE=m
  17845. +
  17846. +CONFIG_INPUT_PCSPKR=m
  17847. +CONFIG_INPUT_RETU_PWRBUTTON=m
  17848. +CONFIG_INPUT_UINPUT=m
  17849. +CONFIG_INPUT_WISTRON_BTNS=m
  17850. +CONFIG_INPUT_ATLAS_BTNS=m
  17851. +
  17852. +CONFIG_INPUT_ATI_REMOTE2=m
  17853. +CONFIG_INPUT_KEYSPAN_REMOTE=m
  17854. +
  17855. +CONFIG_MAC_EMUMOUSEBTN=y
  17856. +
  17857. +CONFIG_INPUT_WM831X_ON=m
  17858. +
  17859. +
  17860. +# CONFIG_INPUT_AD714X is not set
  17861. +# CONFIG_INPUT_PCF8574 is not set
  17862. +CONFIG_INPUT_MMA8450=m
  17863. +CONFIG_INPUT_MPU3050=m
  17864. +CONFIG_INPUT_KXTJ9=m
  17865. +# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set
  17866. +
  17867. +#
  17868. +# Character devices
  17869. +#
  17870. +CONFIG_VT=y
  17871. +CONFIG_VT_CONSOLE=y
  17872. +CONFIG_HW_CONSOLE=y
  17873. +CONFIG_SERIAL_NONSTANDARD=y
  17874. +CONFIG_ROCKETPORT=m
  17875. +CONFIG_SYNCLINK=m
  17876. +CONFIG_SYNCLINKMP=m
  17877. +CONFIG_SYNCLINK_GT=m
  17878. +CONFIG_N_HDLC=m
  17879. +CONFIG_N_GSM=m
  17880. +# CONFIG_TRACE_SINK is not set
  17881. +# CONFIG_STALDRV is not set
  17882. +# CONFIG_DUMMY_IRQ is not set
  17883. +# CONFIG_IBM_ASM is not set
  17884. +CONFIG_TIFM_CORE=m
  17885. +CONFIG_TIFM_7XX1=m
  17886. +CONFIG_TCG_TPM=m
  17887. +CONFIG_TCG_TIS=m
  17888. +# CONFIG_TCG_TIS_I2C_INFINEON is not set
  17889. +# CONFIG_TCG_TIS_I2C_ATMEL is not set
  17890. +# CONFIG_TCG_TIS_I2C_NUVOTON is not set
  17891. +CONFIG_TCG_NSC=m
  17892. +CONFIG_TCG_ATMEL=m
  17893. +# CONFIG_TCG_INFINEON is not set
  17894. +# CONFIG_TCG_ST33_I2C is not set
  17895. +# CONFIG_TCG_XEN is not set
  17896. +CONFIG_TELCLOCK=m
  17897. +
  17898. +#
  17899. +# Serial drivers
  17900. +#
  17901. +CONFIG_SERIAL_8250=y
  17902. +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
  17903. +CONFIG_SERIAL_8250_CONSOLE=y
  17904. +CONFIG_SERIAL_8250_CS=m
  17905. +CONFIG_SERIAL_8250_NR_UARTS=32
  17906. +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
  17907. +CONFIG_SERIAL_8250_EXTENDED=y
  17908. +CONFIG_SERIAL_8250_MANY_PORTS=y
  17909. +CONFIG_SERIAL_8250_SHARE_IRQ=y
  17910. +# CONFIG_SERIAL_8250_DETECT_IRQ is not set
  17911. +CONFIG_SERIAL_8250_RSA=y
  17912. +# CONFIG_SERIAL_8250_DW is not set
  17913. +CONFIG_CYCLADES=m
  17914. +# CONFIG_CYZ_INTR is not set
  17915. +# CONFIG_MOXA_INTELLIO is not set
  17916. +# CONFIG_MOXA_SMARTIO is not set
  17917. +# CONFIG_ISI is not set
  17918. +# CONFIG_RIO is not set
  17919. +CONFIG_SERIAL_JSM=m
  17920. +# CONFIG_SERIAL_SCCNXP is not set
  17921. +# CONFIG_SERIAL_MFD_HSU is not set
  17922. +
  17923. +# CONFIG_SERIAL_ALTERA_JTAGUART is not set
  17924. +# CONFIG_SERIAL_ALTERA_UART is not set
  17925. +
  17926. +#
  17927. +# Non-8250 serial port support
  17928. +#
  17929. +CONFIG_SERIAL_CORE=y
  17930. +CONFIG_SERIAL_CORE_CONSOLE=y
  17931. +# CONFIG_SERIAL_XILINX_PS_UART is not set
  17932. +# CONFIG_SERIAL_TIMBERDALE is not set
  17933. +CONFIG_SERIAL_ARC=m
  17934. +CONFIG_SERIAL_ARC_NR_PORTS=1
  17935. +# CONFIG_SERIAL_RP2 is not set
  17936. +# CONFIG_SERIAL_ST_ASC is not set
  17937. +# CONFIG_SERIAL_PCH_UART is not set
  17938. +
  17939. +CONFIG_UNIX98_PTYS=y
  17940. +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
  17941. +CONFIG_PRINTER=m
  17942. +CONFIG_LP_CONSOLE=y
  17943. +CONFIG_PPDEV=m
  17944. +
  17945. +#
  17946. +# I2C support
  17947. +#
  17948. +CONFIG_I2C=y
  17949. +# CONFIG_I2C_MUX is not set
  17950. +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
  17951. +# CONFIG_I2C_MUX_PCA954x is not set
  17952. +# CONFIG_I2C_MUX_GPIO is not set
  17953. +# CONFIG_I2C_MUX_PCA9541 is not set
  17954. +# CONFIG_I2C_MUX_PINCTRL is not set
  17955. +#
  17956. +
  17957. +#
  17958. +# I2C Algorithms
  17959. +#
  17960. +# CONFIG_I2C_DEBUG_ALGO is not set
  17961. +CONFIG_I2C_ALGOBIT=m
  17962. +
  17963. +#
  17964. +# I2C Hardware Bus support
  17965. +#
  17966. +
  17967. +# CONFIG_I2C_ALI1535 is not set
  17968. +# CONFIG_I2C_ALI1563 is not set
  17969. +# CONFIG_I2C_ALI15X3 is not set
  17970. +# CONFIG_I2C_AMD756 is not set
  17971. +# CONFIG_I2C_AMD756_S4882 is not set
  17972. +# CONFIG_I2C_AMD8111 is not set
  17973. +# CONFIG_I2C_DEBUG_CORE is not set
  17974. +# CONFIG_I2C_DEBUG_BUS is not set
  17975. +# CONFIG_I2C_I801 is not set
  17976. +# CONFIG_I2C_ISCH is not set
  17977. +# CONFIG_I2C_NFORCE2_S4985 is not set
  17978. +# CONFIG_I2C_INTEL_MID is not set
  17979. +# CONFIG_I2C_EG20T is not set
  17980. +# CONFIG_I2C_CBUS_GPIO is not set
  17981. +CONFIG_I2C_VIPERBOARD=m
  17982. +
  17983. +CONFIG_EEPROM_AT24=m
  17984. +CONFIG_EEPROM_LEGACY=m
  17985. +CONFIG_EEPROM_93CX6=m
  17986. +CONFIG_EEPROM_MAX6875=m
  17987. +
  17988. +CONFIG_I2C_NFORCE2=m
  17989. +# CONFIG_I2C_OCORES is not set
  17990. +CONFIG_I2C_PARPORT=m
  17991. +CONFIG_I2C_PARPORT_LIGHT=m
  17992. +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
  17993. +CONFIG_I2C_PASEMI=m
  17994. +CONFIG_I2C_PCA_PLATFORM=m
  17995. +# CONFIG_I2C_PIIX4 is not set
  17996. +# CONFIG_SCx200_ACB is not set
  17997. +# CONFIG_I2C_SIS5595 is not set
  17998. +# CONFIG_I2C_SIS630 is not set
  17999. +# CONFIG_I2C_SIS96X is not set
  18000. +CONFIG_I2C_SIMTEC=m
  18001. +CONFIG_I2C_STUB=m
  18002. +CONFIG_I2C_TINY_USB=m
  18003. +# CONFIG_I2C_TAOS_EVM is not set
  18004. +# CONFIG_I2C_VIA is not set
  18005. +# CONFIG_I2C_VIAPRO is not set
  18006. +# CONFIG_I2C_DESIGNWARE is not set
  18007. +# CONFIG_I2C_XILINX is not set
  18008. +
  18009. +CONFIG_I2C_DIOLAN_U2C=m
  18010. +
  18011. +#
  18012. +# I2C Hardware Sensors Chip support
  18013. +#
  18014. +CONFIG_SENSORS_ATK0110=m
  18015. +CONFIG_SENSORS_ABITUGURU=m
  18016. +CONFIG_SENSORS_ABITUGURU3=m
  18017. +CONFIG_SENSORS_AD7414=m
  18018. +CONFIG_SENSORS_AD7418=m
  18019. +CONFIG_SENSORS_ADM1021=m
  18020. +CONFIG_SENSORS_ADM1025=m
  18021. +CONFIG_SENSORS_ADM1026=m
  18022. +CONFIG_SENSORS_ADM1029=m
  18023. +CONFIG_SENSORS_ADM1031=m
  18024. +CONFIG_SENSORS_ADM9240=m
  18025. +CONFIG_SENSORS_ADT7310=m
  18026. +CONFIG_SENSORS_ADT7410=m
  18027. +CONFIG_SENSORS_ADS7828=m
  18028. +CONFIG_SENSORS_ADT7462=m
  18029. +CONFIG_SENSORS_ADT7470=m
  18030. +CONFIG_SENSORS_ADT7475=m
  18031. +CONFIG_SENSORS_APPLESMC=m
  18032. +CONFIG_SENSORS_ASB100=m
  18033. +CONFIG_SENSORS_ATXP1=m
  18034. +CONFIG_SENSORS_CORETEMP=m
  18035. +CONFIG_SENSORS_DME1737=m
  18036. +CONFIG_SENSORS_DS1621=m
  18037. +# CONFIG_DS1682 is not set
  18038. +CONFIG_SENSORS_F71805F=m
  18039. +CONFIG_SENSORS_F71882FG=m
  18040. +CONFIG_SENSORS_F75375S=m
  18041. +CONFIG_SENSORS_FSCHMD=m
  18042. +CONFIG_SENSORS_G760A=m
  18043. +CONFIG_SENSORS_G762=m
  18044. +CONFIG_SENSORS_GL518SM=m
  18045. +CONFIG_SENSORS_GL520SM=m
  18046. +CONFIG_SENSORS_HDAPS=m
  18047. +# CONFIG_SENSORS_HIH6130 is not set
  18048. +# CONFIG_SENSORS_HTU21 is not set
  18049. +# CONFIG_SENSORS_I5K_AMB is not set
  18050. +# FIXME: IBMAEM x86 only?
  18051. +CONFIG_SENSORS_IBMAEM=m
  18052. +CONFIG_SENSORS_IBMPEX=m
  18053. +# CONFIG_SENSORS_IIO_HWMON is not set
  18054. +CONFIG_SENSORS_IT87=m
  18055. +CONFIG_SENSORS_K8TEMP=m
  18056. +CONFIG_SENSORS_K10TEMP=m
  18057. +CONFIG_SENSORS_LIS3LV02D=m
  18058. +CONFIG_SENSORS_LIS3_SPI=m
  18059. +CONFIG_SENSORS_LIS3_I2C=m
  18060. +CONFIG_SENSORS_LM63=m
  18061. +CONFIG_SENSORS_LM75=m
  18062. +CONFIG_SENSORS_LM77=m
  18063. +CONFIG_SENSORS_LM78=m
  18064. +CONFIG_SENSORS_LM80=m
  18065. +CONFIG_SENSORS_LM83=m
  18066. +CONFIG_SENSORS_LM85=m
  18067. +CONFIG_SENSORS_LM87=m
  18068. +CONFIG_SENSORS_LM90=m
  18069. +CONFIG_SENSORS_LM92=m
  18070. +CONFIG_SENSORS_LM93=m
  18071. +CONFIG_SENSORS_LM95234=m
  18072. +CONFIG_SENSORS_LTC4245=m
  18073. +CONFIG_SENSORS_MAX1619=m
  18074. +CONFIG_SENSORS_MAX6650=m
  18075. +CONFIG_SENSORS_MAX6697=m
  18076. +CONFIG_SENSORS_MCP3021=m
  18077. +CONFIG_SENSORS_NCT6775=m
  18078. +CONFIG_SENSORS_NTC_THERMISTOR=m
  18079. +CONFIG_SENSORS_PC87360=m
  18080. +CONFIG_SENSORS_PC87427=m
  18081. +CONFIG_SENSORS_PCF8591=m
  18082. +CONFIG_SENSORS_SHT15=m
  18083. +CONFIG_SENSORS_SIS5595=m
  18084. +CONFIG_CHARGER_SMB347=m
  18085. +CONFIG_SENSORS_SMSC47M1=m
  18086. +CONFIG_SENSORS_SMSC47M192=m
  18087. +CONFIG_SENSORS_SMSC47B397=m
  18088. +CONFIG_SENSORS_THMC50=m
  18089. +CONFIG_SENSORS_TMP401=m
  18090. +CONFIG_APDS9802ALS=m
  18091. +CONFIG_ISL29020=m
  18092. +CONFIG_ISL29003=m
  18093. +CONFIG_SENSORS_BH1770=m
  18094. +CONFIG_SENSORS_APDS990X=m
  18095. +CONFIG_SENSORS_TSL2550=m
  18096. +CONFIG_SENSORS_VIA686A=m
  18097. +CONFIG_SENSORS_VIA_CPUTEMP=m
  18098. +CONFIG_SENSORS_VT1211=m
  18099. +CONFIG_SENSORS_VT8231=m
  18100. +CONFIG_SENSORS_W83627HF=m
  18101. +CONFIG_SENSORS_W83781D=m
  18102. +CONFIG_SENSORS_W83L785TS=m
  18103. +CONFIG_SENSORS_W83L786NG=m
  18104. +CONFIG_SENSORS_W83627EHF=m
  18105. +CONFIG_SENSORS_W83791D=m
  18106. +CONFIG_SENSORS_W83792D=m
  18107. +CONFIG_SENSORS_W83793=m
  18108. +CONFIG_SENSORS_LTC4215=m
  18109. +CONFIG_SENSORS_LM95241=m
  18110. +CONFIG_SENSORS_LM95245=m
  18111. +CONFIG_SENSORS_TMP421=m
  18112. +CONFIG_SENSORS_WM8350=m
  18113. +CONFIG_SENSORS_WM831X=m
  18114. +CONFIG_SENSORS_LM73=m
  18115. +CONFIG_SENSORS_AMC6821=m
  18116. +CONFIG_SENSORS_INA2XX=m
  18117. +CONFIG_SENSORS_INA209=m
  18118. +CONFIG_SENSORS_ADT7411=m
  18119. +CONFIG_SENSORS_ASC7621=m
  18120. +CONFIG_SENSORS_EMC1403=m
  18121. +CONFIG_SENSORS_TMP102=m
  18122. +CONFIG_SENSORS_LTC4261=m
  18123. +# CONFIG_SENSORS_BH1780 is not set
  18124. +# CONFIG_SENSORS_JC42 is not set
  18125. +# CONFIG_SENSORS_SMM665 is not set
  18126. +# CONFIG_SENSORS_EMC2103 is not set
  18127. +# CONFIG_SENSORS_GPIO_FAN is not set
  18128. +CONFIG_SENSORS_W83795=m
  18129. +# CONFIG_SENSORS_W83795_FANCTRL is not set
  18130. +CONFIG_SENSORS_DS620=m
  18131. +CONFIG_SENSORS_SHT21=m
  18132. +CONFIG_SENSORS_LINEAGE=m
  18133. +CONFIG_SENSORS_LTC4151=m
  18134. +CONFIG_SENSORS_MAX6639=m
  18135. +CONFIG_SENSORS_SCH5627=m
  18136. +CONFIG_SENSORS_SCH5636=m
  18137. +CONFIG_SENSORS_ADS1015=m
  18138. +CONFIG_SENSORS_MAX16065=m
  18139. +CONFIG_SENSORS_MAX6642=m
  18140. +CONFIG_SENSORS_ADM1275=m
  18141. +CONFIG_SENSORS_UCD9000=m
  18142. +CONFIG_SENSORS_UCD9200=m
  18143. +CONFIG_SENSORS_ZL6100=m
  18144. +CONFIG_SENSORS_EMC6W201=m
  18145. +
  18146. +CONFIG_PMBUS=m
  18147. +CONFIG_SENSORS_PMBUS=m
  18148. +CONFIG_SENSORS_MAX16064=m
  18149. +CONFIG_SENSORS_LM25066=m
  18150. +CONFIG_SENSORS_LTC2978=m
  18151. +CONFIG_SENSORS_MAX34440=m
  18152. +CONFIG_SENSORS_MAX8688=m
  18153. +CONFIG_SENSORS_MAX1668=m
  18154. +CONFIG_SENSORS_MAX197=m
  18155. +
  18156. +# Industrial I/O subsystem configuration
  18157. +CONFIG_IIO=m
  18158. +CONFIG_IIO_BUFFER=y
  18159. +CONFIG_IIO_BUFFER_CB=y
  18160. +# CONFIG_IIO_KFIFO_BUF is not set
  18161. +CONFIG_IIO_TRIGGERED_BUFFER=m
  18162. +CONFIG_IIO_TRIGGER=y
  18163. +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
  18164. +CONFIG_IIO_INTERRUPT_TRIGGER=m
  18165. +CONFIG_HID_SENSOR_IIO_COMMON=m
  18166. +CONFIG_HID_SENSOR_IIO_TRIGGER=m
  18167. +CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS=y
  18168. +# CONFIG_IIO_SYSFS_TRIGGER is not set
  18169. +# CONFIG_AD5446 is not set
  18170. +# CONFIG_AD5380 is not set
  18171. +# CONFIG_AD5064 is not set
  18172. +# CONFIG_BMA180 is not set
  18173. +# CONFIG_MAX1363 is not set
  18174. +# CONFIG_MAX517 is not set
  18175. +# CONFIG_MCP4725 is not set
  18176. +# CONFIG_ITG3200 is not set
  18177. +# CONFIG_APDS9300 is not set
  18178. +# CONFIG_CM32181 is not set
  18179. +# CONFIG_CM36651 is not set
  18180. +# CONFIG_GP2AP020A00F is not set
  18181. +# CONFIG_TSL2583 is not set
  18182. +# CONFIG_TSL2x7x is not set
  18183. +# CONFIG_TCS3472 is not set
  18184. +# CONFIG_TSL4531 is not set
  18185. +# CONFIG_NAU7802 is not set
  18186. +# CONFIG_TI_ADC081C is not set
  18187. +# CONFIG_EXYNOS_ADC is not set
  18188. +# CONFIG_VIPERBOARD_ADC is not set
  18189. +# CONFIG_INV_MPU6050_IIO is not set
  18190. +CONFIG_IIO_ST_GYRO_3AXIS=m
  18191. +CONFIG_IIO_ST_MAGN_3AXIS=m
  18192. +CONFIG_IIO_ST_ACCEL_3AXIS=m
  18193. +CONFIG_HID_SENSOR_INCLINOMETER_3D=m
  18194. +# CONFIG_ADJD_S311 is not set
  18195. +# CONFIG_SENSORS_TSL2563 is not set
  18196. +# CONFIG_VCNL4000 is not set
  18197. +# CONFIG_AK8975 is not set
  18198. +# CONFIG_MAG3110 is not set
  18199. +# CONFIG_TMP006 is not set
  18200. +# CONFIG_IIO_ST_PRESS is not set
  18201. +# CONFIG_KXSD9 is not set
  18202. +# CONFIG_AD7266 is not set
  18203. +# CONFIG_AD7298 is not set
  18204. +# CONFIG_AD7476 is not set
  18205. +# CONFIG_AD7791 is not set
  18206. +# CONFIG_AD7793 is not set
  18207. +# CONFIG_AD7887 is not set
  18208. +# CONFIG_AD7923 is not set
  18209. +# CONFIG_MCP320X is not set
  18210. +# CONFIG_MCP3422 is not set
  18211. +# CONFIG_AD8366 is not set
  18212. +# CONFIG_AD5360 is not set
  18213. +# CONFIG_AD5421 is not set
  18214. +# CONFIG_AD5449 is not set
  18215. +# CONFIG_AD5504 is not set
  18216. +# CONFIG_AD5624R_SPI is not set
  18217. +# CONFIG_AD5686 is not set
  18218. +# CONFIG_AD5755 is not set
  18219. +# CONFIG_AD5764 is not set
  18220. +# CONFIG_AD5791 is not set
  18221. +# CONFIG_AD7303 is not set
  18222. +# CONFIG_AD9523 is not set
  18223. +# CONFIG_ADF4350 is not set
  18224. +# CONFIG_ADIS16080 is not set
  18225. +# CONFIG_ADIS16130 is not set
  18226. +# CONFIG_ADIS16136 is not set
  18227. +# CONFIG_ADIS16260 is not set
  18228. +# CONFIG_ADXRS450 is not set
  18229. +# CONFIG_ADIS16400 is not set
  18230. +# CONFIG_ADIS16480 is not set
  18231. +# CONFIG_DHT11 is not set
  18232. +# CONFIG_MPL3115 is not set
  18233. +
  18234. +# staging IIO drivers
  18235. +# CONFIG_AD7291 is not set
  18236. +# CONFIG_AD7606 is not set
  18237. +# CONFIG_AD799X is not set
  18238. +# CONFIG_ADT7316 is not set
  18239. +# CONFIG_AD7150 is not set
  18240. +# CONFIG_AD7152 is not set
  18241. +# CONFIG_AD7746 is not set
  18242. +# CONFIG_AD5933 is not set
  18243. +# CONFIG_ADE7854 is not set
  18244. +# CONFIG_SENSORS_ISL29018 is not set
  18245. +# CONFIG_SENSORS_ISL29028 is not set
  18246. +# CONFIG_SENSORS_HMC5843 is not set
  18247. +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
  18248. +# CONFIG_IIO_SIMPLE_DUMMY is not set
  18249. +# CONFIG_ADIS16201 is not set
  18250. +# CONFIG_ADIS16203 is not set
  18251. +# CONFIG_ADIS16204 is not set
  18252. +# CONFIG_ADIS16209 is not set
  18253. +# CONFIG_ADIS16220 is not set
  18254. +# CONFIG_ADIS16240 is not set
  18255. +# CONFIG_LIS3L02DQ is not set
  18256. +# CONFIG_SCA3000 is not set
  18257. +# CONFIG_AD7780 is not set
  18258. +# CONFIG_AD7816 is not set
  18259. +# CONFIG_AD7192 is not set
  18260. +# CONFIG_AD7280 is not set
  18261. +# CONFIG_AD5930 is not set
  18262. +# CONFIG_AD9832 is not set
  18263. +# CONFIG_AD9834 is not set
  18264. +# CONFIG_AD9850 is not set
  18265. +# CONFIG_AD9852 is not set
  18266. +# CONFIG_AD9910 is not set
  18267. +# CONFIG_AD9951 is not set
  18268. +# CONFIG_ADIS16060 is not set
  18269. +# CONFIG_ADE7753 is not set
  18270. +# CONFIG_ADE7754 is not set
  18271. +# CONFIG_ADE7758 is not set
  18272. +# CONFIG_ADE7759 is not set
  18273. +# CONFIG_AD2S90 is not set
  18274. +# CONFIG_AD2S1200 is not set
  18275. +# CONFIG_AD2S1210 is not set
  18276. +
  18277. +
  18278. +
  18279. +# CONFIG_HMC6352 is not set
  18280. +# CONFIG_BMP085 is not set
  18281. +# CONFIG_BMP085_I2C is not set
  18282. +# CONFIG_PCH_PHUB is not set
  18283. +# CONFIG_USB_SWITCH_FSA9480 is not set
  18284. +
  18285. +CONFIG_W1=m
  18286. +CONFIG_W1_CON=y
  18287. +# CONFIG_W1_MASTER_MATROX is not set
  18288. +CONFIG_W1_MASTER_DS2490=m
  18289. +CONFIG_W1_MASTER_DS2482=m
  18290. +CONFIG_W1_MASTER_DS1WM=m
  18291. +CONFIG_W1_MASTER_GPIO=m
  18292. +# CONFIG_HDQ_MASTER_OMAP is not set
  18293. +CONFIG_W1_SLAVE_THERM=m
  18294. +CONFIG_W1_SLAVE_SMEM=m
  18295. +CONFIG_W1_SLAVE_DS2408=m
  18296. +# CONFIG_W1_SLAVE_DS2408_READBACK is not set
  18297. +CONFIG_W1_SLAVE_DS2413=m
  18298. +CONFIG_W1_SLAVE_DS2423=m
  18299. +CONFIG_W1_SLAVE_DS2431=m
  18300. +CONFIG_W1_SLAVE_DS2433=m
  18301. +CONFIG_W1_SLAVE_DS2433_CRC=y
  18302. +CONFIG_W1_SLAVE_DS2760=m
  18303. +CONFIG_W1_SLAVE_DS2780=m
  18304. +CONFIG_W1_SLAVE_DS2781=m
  18305. +CONFIG_W1_SLAVE_DS28E04=m
  18306. +CONFIG_W1_SLAVE_BQ27000=m
  18307. +
  18308. +#
  18309. +# Mice
  18310. +#
  18311. +
  18312. +#
  18313. +# IPMI
  18314. +#
  18315. +CONFIG_IPMI_HANDLER=m
  18316. +# CONFIG_IPMI_PANIC_EVENT is not set
  18317. +CONFIG_IPMI_DEVICE_INTERFACE=m
  18318. +CONFIG_IPMI_WATCHDOG=m
  18319. +CONFIG_IPMI_SI=m
  18320. +CONFIG_IPMI_POWEROFF=m
  18321. +
  18322. +#
  18323. +# Watchdog Cards
  18324. +#
  18325. +CONFIG_WATCHDOG_CORE=y
  18326. +# CONFIG_WATCHDOG_NOWAYOUT is not set
  18327. +CONFIG_SOFT_WATCHDOG=m
  18328. +CONFIG_WDTPCI=m
  18329. +# CONFIG_ACQUIRE_WDT is not set
  18330. +# CONFIG_ADVANTECH_WDT is not set
  18331. +# CONFIG_EUROTECH_WDT is not set
  18332. +CONFIG_IB700_WDT=m
  18333. +# CONFIG_SCx200_WDT is not set
  18334. +# CONFIG_60XX_WDT is not set
  18335. +CONFIG_W83877F_WDT=m
  18336. +CONFIG_W83627HF_WDT=m
  18337. +CONFIG_MACHZ_WDT=m
  18338. +# CONFIG_SC520_WDT is not set
  18339. +CONFIG_ALIM7101_WDT=m
  18340. +CONFIG_ALIM1535_WDT=m
  18341. +CONFIG_IT87_WDT=m
  18342. +CONFIG_ITCO_WDT=m
  18343. +CONFIG_ITCO_VENDOR_SUPPORT=y
  18344. +# CONFIG_SC1200_WDT is not set
  18345. +# CONFIG_PC87413_WDT is not set
  18346. +# CONFIG_WAFER_WDT is not set
  18347. +# CONFIG_CPU5_WDT is not set
  18348. +CONFIG_I6300ESB_WDT=m
  18349. +CONFIG_IT8712F_WDT=m
  18350. +# CONFIG_SBC8360_WDT is not set
  18351. +# CONFIG_SBC7240_WDT is not set
  18352. +CONFIG_SMSC_SCH311X_WDT=m
  18353. +CONFIG_W83977F_WDT=m
  18354. +CONFIG_PCIPCWATCHDOG=m
  18355. +CONFIG_USBPCWATCHDOG=m
  18356. +# CONFIG_SBC_EPX_C3_WATCHDOG is not set
  18357. +CONFIG_WM8350_WATCHDOG=m
  18358. +CONFIG_WM831X_WATCHDOG=m
  18359. +# CONFIG_MAX63XX_WATCHDOG is not set
  18360. +# CONFIG_DW_WATCHDOG is not set
  18361. +CONFIG_W83697UG_WDT=m
  18362. +# CONFIG_MEN_A21_WDT is not set
  18363. +# CONFIG_GPIO_WATCHDOG is not set
  18364. +
  18365. +CONFIG_HW_RANDOM=y
  18366. +CONFIG_HW_RANDOM_TIMERIOMEM=m
  18367. +CONFIG_HW_RANDOM_TPM=m
  18368. +# CONFIG_HW_RANDOM_ATMEL is not set
  18369. +# CONFIG_HW_RANDOM_EXYNOS is not set
  18370. +# CONFIG_NVRAM is not set
  18371. +# CONFIG_RTC is not set
  18372. +# CONFIG_RTC_DEBUG is not set
  18373. +# CONFIG_GEN_RTC is not set
  18374. +CONFIG_RTC_HCTOSYS=y
  18375. +# CONFIG_RTC_SYSTOHC is not set
  18376. +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
  18377. +CONFIG_RTC_INTF_SYSFS=y
  18378. +CONFIG_RTC_INTF_PROC=y
  18379. +CONFIG_RTC_INTF_DEV=y
  18380. +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
  18381. +CONFIG_RTC_DRV_CMOS=y
  18382. +CONFIG_RTC_DRV_DS1307=m
  18383. +CONFIG_RTC_DRV_DS1511=m
  18384. +CONFIG_RTC_DRV_DS1553=m
  18385. +CONFIG_RTC_DRV_DS1672=m
  18386. +CONFIG_RTC_DRV_DS1742=m
  18387. +CONFIG_RTC_DRV_DS1374=m
  18388. +# CONFIG_RTC_DRV_EP93XX is not set
  18389. +CONFIG_RTC_DRV_FM3130=m
  18390. +CONFIG_RTC_DRV_ISL1208=m
  18391. +CONFIG_RTC_DRV_M41T80=m
  18392. +CONFIG_RTC_DRV_M41T80_WDT=y
  18393. +CONFIG_RTC_DRV_M48T59=m
  18394. +CONFIG_RTC_DRV_MAX6900=m
  18395. +# CONFIG_RTC_DRV_M48T86 is not set
  18396. +CONFIG_RTC_DRV_PCF2127=m
  18397. +CONFIG_RTC_DRV_PCF8563=m
  18398. +CONFIG_RTC_DRV_PCF8583=m
  18399. +CONFIG_RTC_DRV_RS5C372=m
  18400. +# CONFIG_RTC_DRV_SA1100 is not set
  18401. +# CONFIG_RTC_DRV_TEST is not set
  18402. +CONFIG_RTC_DRV_X1205=m
  18403. +CONFIG_RTC_DRV_V3020=m
  18404. +CONFIG_RTC_DRV_DS2404=m
  18405. +CONFIG_RTC_DRV_STK17TA8=m
  18406. +# CONFIG_RTC_DRV_S35390A is not set
  18407. +CONFIG_RTC_DRV_RX8581=m
  18408. +CONFIG_RTC_DRV_RX8025=m
  18409. +CONFIG_RTC_DRV_DS1286=m
  18410. +CONFIG_RTC_DRV_M48T35=m
  18411. +CONFIG_RTC_DRV_BQ4802=m
  18412. +CONFIG_RTC_DRV_WM8350=m
  18413. +# CONFIG_RTC_DRV_AB3100 is not set
  18414. +CONFIG_RTC_DRV_WM831X=m
  18415. +CONFIG_RTC_DRV_BQ32K=m
  18416. +CONFIG_RTC_DRV_MSM6242=m
  18417. +CONFIG_RTC_DRV_RP5C01=m
  18418. +CONFIG_RTC_DRV_EM3027=m
  18419. +CONFIG_RTC_DRV_RV3029C2=m
  18420. +CONFIG_RTC_DRV_PCF50633=m
  18421. +CONFIG_RTC_DRV_DS3232=m
  18422. +CONFIG_RTC_DRV_ISL12022=m
  18423. +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
  18424. +# CONFIG_RTC_DRV_MOXART is not set
  18425. +# CONFIG_RTC_DRV_ISL12057 is not set
  18426. +
  18427. +CONFIG_R3964=m
  18428. +# CONFIG_APPLICOM is not set
  18429. +# CONFIG_SONYPI is not set
  18430. +
  18431. +#
  18432. +# Ftape, the floppy tape device driver
  18433. +#
  18434. +CONFIG_AGP=y
  18435. +CONFIG_AGP_ALI=y
  18436. +CONFIG_AGP_ATI=y
  18437. +CONFIG_AGP_AMD=y
  18438. +CONFIG_AGP_AMD64=y
  18439. +CONFIG_AGP_INTEL=y
  18440. +CONFIG_AGP_NVIDIA=y
  18441. +CONFIG_AGP_SIS=y
  18442. +CONFIG_AGP_SWORKS=y
  18443. +CONFIG_AGP_VIA=y
  18444. +CONFIG_AGP_EFFICEON=y
  18445. +
  18446. +CONFIG_VGA_ARB=y
  18447. +CONFIG_VGA_ARB_MAX_GPUS=16
  18448. +
  18449. +# CONFIG_STUB_POULSBO is not set
  18450. +
  18451. +#
  18452. +# PCMCIA character devices
  18453. +#
  18454. +# CONFIG_SYNCLINK_CS is not set
  18455. +
  18456. +CONFIG_CARDMAN_4000=m
  18457. +CONFIG_CARDMAN_4040=m
  18458. +
  18459. +CONFIG_MWAVE=m
  18460. +CONFIG_RAW_DRIVER=y
  18461. +CONFIG_MAX_RAW_DEVS=8192
  18462. +CONFIG_HANGCHECK_TIMER=m
  18463. +
  18464. +CONFIG_MEDIA_PCI_SUPPORT=y
  18465. +#
  18466. +# Multimedia devices
  18467. +#
  18468. +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
  18469. +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
  18470. +CONFIG_MEDIA_RC_SUPPORT=y
  18471. +CONFIG_MEDIA_CONTROLLER=y
  18472. +CONFIG_VIDEO_DEV=m
  18473. +# CONFIG_VIDEO_ADV_DEBUG is not set
  18474. +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
  18475. +CONFIG_VIDEO_V4L2=y
  18476. +CONFIG_VIDEO_V4L2_SUBDEV_API=y
  18477. +# CONFIG_VIDEO_VIVI is not set
  18478. +# CONFIG_USB_SI4713 is not set
  18479. +# CONFIG_PLATFORM_SI4713 is not set
  18480. +# CONFIG_I2C_SI4713 is not set
  18481. +# CONFIG_USB_RAREMONO is not set
  18482. +
  18483. +#
  18484. +# Video For Linux
  18485. +#
  18486. +
  18487. +#
  18488. +# Video Adapters
  18489. +#
  18490. +CONFIG_V4L_USB_DRIVERS=y
  18491. +CONFIG_VIDEO_CAPTURE_DRIVERS=y
  18492. +CONFIG_V4L_PCI_DRIVERS=y
  18493. +CONFIG_VIDEO_AU0828=m
  18494. +CONFIG_VIDEO_AU0828_V4L2=y
  18495. +CONFIG_VIDEO_BT848=m
  18496. +CONFIG_VIDEO_BT848_DVB=y
  18497. +CONFIG_VIDEO_BWQCAM=m
  18498. +CONFIG_VIDEO_SR030PC30=m
  18499. +CONFIG_VIDEO_NOON010PC30=m
  18500. +CONFIG_VIDEO_CAFE_CCIC=m
  18501. +# CONFIG_VIDEO_CPIA is not set
  18502. +CONFIG_VIDEO_CPIA2=m
  18503. +CONFIG_VIDEO_CQCAM=m
  18504. +CONFIG_VIDEO_CX23885=m
  18505. +CONFIG_MEDIA_ALTERA_CI=m
  18506. +CONFIG_VIDEO_CX18=m
  18507. +CONFIG_VIDEO_CX18_ALSA=m
  18508. +CONFIG_VIDEO_CX88=m
  18509. +CONFIG_VIDEO_CX88_DVB=m
  18510. +CONFIG_VIDEO_CX88_ALSA=m
  18511. +CONFIG_VIDEO_CX88_BLACKBIRD=m
  18512. +CONFIG_VIDEO_CX88_ENABLE_VP3054=y
  18513. +CONFIG_VIDEO_CX88_VP3054=m
  18514. +CONFIG_VIDEO_EM28XX=m
  18515. +CONFIG_VIDEO_EM28XX_V4L2=m
  18516. +CONFIG_VIDEO_EM28XX_ALSA=m
  18517. +CONFIG_VIDEO_EM28XX_DVB=m
  18518. +CONFIG_VIDEO_EM28XX_RC=y
  18519. +CONFIG_VIDEO_CX231XX=m
  18520. +CONFIG_VIDEO_CX231XX_ALSA=m
  18521. +CONFIG_VIDEO_CX231XX_DVB=m
  18522. +CONFIG_VIDEO_CX231XX_RC=y
  18523. +CONFIG_VIDEO_HEXIUM_ORION=m
  18524. +CONFIG_VIDEO_HEXIUM_GEMINI=m
  18525. +CONFIG_VIDEO_IVTV=m
  18526. +# CONFIG_VIDEO_IVTV_ALSA is not set
  18527. +CONFIG_VIDEO_MEYE=m
  18528. +CONFIG_VIDEO_MXB=m
  18529. +CONFIG_VIDEO_PVRUSB2_DVB=y
  18530. +# CONFIG_VIDEO_PMS is not set
  18531. +CONFIG_VIDEO_HDPVR=m
  18532. +CONFIG_VIDEO_SAA6588=m
  18533. +CONFIG_VIDEO_SAA7134=m
  18534. +CONFIG_VIDEO_SAA7134_ALSA=m
  18535. +CONFIG_VIDEO_SAA7134_DVB=m
  18536. +CONFIG_VIDEO_SAA7134_RC=y
  18537. +CONFIG_VIDEO_USBVISION=m
  18538. +CONFIG_VIDEO_STK1160_COMMON=m
  18539. +CONFIG_VIDEO_STK1160=m
  18540. +CONFIG_VIDEO_STK1160_AC97=y
  18541. +CONFIG_VIDEO_W9966=m
  18542. +CONFIG_VIDEO_ZORAN=m
  18543. +CONFIG_VIDEO_ZORAN_AVS6EYES=m
  18544. +CONFIG_VIDEO_ZORAN_BUZ=m
  18545. +CONFIG_VIDEO_ZORAN_DC10=m
  18546. +CONFIG_VIDEO_ZORAN_DC30=m
  18547. +CONFIG_VIDEO_ZORAN_LML33=m
  18548. +CONFIG_VIDEO_ZORAN_LML33R10=m
  18549. +CONFIG_VIDEO_ZORAN_ZR36060=m
  18550. +# CONFIG_V4L_ISA_PARPORT_DRIVERS is not set
  18551. +CONFIG_VIDEO_FB_IVTV=m
  18552. +CONFIG_VIDEO_SAA7164=m
  18553. +CONFIG_VIDEO_TM6000=m
  18554. +CONFIG_VIDEO_TM6000_ALSA=m
  18555. +CONFIG_VIDEO_TM6000_DVB=m
  18556. +CONFIG_VIDEO_TLG2300=m
  18557. +CONFIG_VIDEO_USBTV=m
  18558. +
  18559. +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
  18560. +
  18561. +#
  18562. +# Radio Adapters
  18563. +#
  18564. +CONFIG_RADIO_MAXIRADIO=m
  18565. +CONFIG_RADIO_SHARK=m
  18566. +CONFIG_RADIO_SHARK2=m
  18567. +CONFIG_RADIO_WL1273=m
  18568. +
  18569. +CONFIG_MEDIA_ATTACH=y
  18570. +
  18571. +#
  18572. +# V4L/DVB tuners
  18573. +# Selected automatically by not setting CONFIG_MEDIA_TUNER_CUSTOMISE
  18574. +#
  18575. +# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
  18576. +
  18577. +#
  18578. +# Digital Video Broadcasting Devices
  18579. +#
  18580. +CONFIG_DVB_CAPTURE_DRIVERS=y
  18581. +CONFIG_DVB_CORE=m
  18582. +CONFIG_DVB_NET=y
  18583. +CONFIG_DVB_MAX_ADAPTERS=8
  18584. +CONFIG_DVB_DYNAMIC_MINORS=y
  18585. +
  18586. +#
  18587. +# DVB frontends
  18588. +# Selected automatically by not setting CONFIG_DVB_FE_CUSTOMISE
  18589. +#
  18590. +# CONFIG_DVB_FE_CUSTOMISE is not set
  18591. +
  18592. +#
  18593. +# Supported DVB bridge Modules
  18594. +#
  18595. +CONFIG_DVB_BT8XX=m
  18596. +CONFIG_DVB_BUDGET_CORE=m
  18597. +CONFIG_DVB_PLUTO2=m
  18598. +CONFIG_SMS_SIANO_MDTV=m
  18599. +CONFIG_SMS_SIANO_RC=y
  18600. +# CONFIG_SMS_SIANO_DEBUGFS is not set
  18601. +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
  18602. +CONFIG_SMS_USB_DRV=m
  18603. +CONFIG_SMS_SDIO_DRV=m
  18604. +CONFIG_DVB_TTUSB_DEC=m
  18605. +CONFIG_DVB_USB_DTV5100=m
  18606. +CONFIG_DVB_USB_AF9015=m
  18607. +CONFIG_DVB_USB_ANYSEE=m
  18608. +CONFIG_DVB_USB_DW2102=m
  18609. +CONFIG_DVB_USB_FRIIO=m
  18610. +CONFIG_DVB_USB_EC168=m
  18611. +CONFIG_DVB_USB_PCTV452E=m
  18612. +CONFIG_DVB_USB_IT913X=m
  18613. +CONFIG_DVB_USB_MXL111SF=m
  18614. +CONFIG_DVB_DM1105=m
  18615. +CONFIG_DVB_FIREDTV=m
  18616. +CONFIG_DVB_NGENE=m
  18617. +CONFIG_DVB_DDBRIDGE=m
  18618. +CONFIG_DVB_USB_TECHNISAT_USB2=m
  18619. +CONFIG_DVB_USB_V2=m
  18620. +
  18621. +CONFIG_DVB_AV7110=m
  18622. +CONFIG_DVB_AV7110_OSD=y
  18623. +CONFIG_DVB_BUDGET=m
  18624. +CONFIG_DVB_BUDGET_CI=m
  18625. +CONFIG_DVB_BUDGET_AV=m
  18626. +CONFIG_DVB_BUDGET_PATCH=m
  18627. +
  18628. +CONFIG_DVB_TTUSB_BUDGET=m
  18629. +
  18630. +CONFIG_DVB_USB_CINERGY_T2=m
  18631. +CONFIG_DVB_B2C2_FLEXCOP=m
  18632. +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set
  18633. +
  18634. +CONFIG_DVB_B2C2_FLEXCOP_PCI=m
  18635. +# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set
  18636. +CONFIG_DVB_B2C2_FLEXCOP_USB=m
  18637. +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
  18638. +CONFIG_DVB_USB=m
  18639. +# CONFIG_DVB_USB_DEBUG is not set
  18640. +CONFIG_DVB_USB_A800=m
  18641. +CONFIG_DVB_USB_AF9005=m
  18642. +CONFIG_DVB_USB_AF9005_REMOTE=m
  18643. +CONFIG_DVB_USB_AU6610=m
  18644. +CONFIG_DVB_USB_CXUSB=m
  18645. +CONFIG_DVB_USB_DIBUSB_MB=m
  18646. +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
  18647. +CONFIG_DVB_USB_DIBUSB_MC=m
  18648. +CONFIG_DVB_USB_DIB0700=m
  18649. +CONFIG_DVB_USB_DIGITV=m
  18650. +CONFIG_DVB_USB_DTT200U=m
  18651. +CONFIG_DVB_USB_GL861=m
  18652. +CONFIG_DVB_USB_GP8PSK=m
  18653. +CONFIG_DVB_USB_M920X=m
  18654. +CONFIG_DVB_USB_NOVA_T_USB2=m
  18655. +CONFIG_DVB_USB_CE6230=m
  18656. +CONFIG_DVB_USB_OPERA1=m
  18657. +CONFIG_DVB_USB_TTUSB2=m
  18658. +CONFIG_DVB_USB_UMT_010=m
  18659. +CONFIG_DVB_USB_VP702X=m
  18660. +CONFIG_DVB_USB_VP7045=m
  18661. +CONFIG_DVB_USB_AZ6027=m
  18662. +CONFIG_DVB_USB_AZ6007=m
  18663. +CONFIG_DVB_USB_LME2510=m
  18664. +CONFIG_DVB_USB_RTL28XXU=m
  18665. +CONFIG_DVB_USB_AF9035=m
  18666. +
  18667. +CONFIG_DVB_PT1=m
  18668. +
  18669. +CONFIG_MANTIS_CORE=m
  18670. +CONFIG_DVB_MANTIS=m
  18671. +CONFIG_DVB_HOPPER=m
  18672. +
  18673. +CONFIG_VIDEO_SAA7146=m
  18674. +CONFIG_VIDEO_SAA7146_VV=m
  18675. +CONFIG_VIDEO_TVP5150=m
  18676. +CONFIG_VIDEO_TUNER=m
  18677. +CONFIG_VIDEO_BTCX=m
  18678. +CONFIG_VIDEO_PVRUSB2=m
  18679. +CONFIG_VIDEO_PVRUSB2_SYSFS=y
  18680. +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
  18681. +
  18682. +CONFIG_RC_CORE=m
  18683. +CONFIG_RC_DECODERS=y
  18684. +CONFIG_LIRC=m
  18685. +CONFIG_RC_LOOPBACK=m
  18686. +CONFIG_RC_MAP=m
  18687. +CONFIG_RC_DEVICES=y
  18688. +CONFIG_RC_ATI_REMOTE=m
  18689. +CONFIG_IR_NEC_DECODER=m
  18690. +CONFIG_IR_RC5_DECODER=m
  18691. +CONFIG_IR_RC6_DECODER=m
  18692. +CONFIG_IR_JVC_DECODER=m
  18693. +CONFIG_IR_SONY_DECODER=m
  18694. +CONFIG_IR_RC5_SZ_DECODER=m
  18695. +CONFIG_IR_SANYO_DECODER=m
  18696. +CONFIG_IR_MCE_KBD_DECODER=m
  18697. +CONFIG_IR_LIRC_CODEC=m
  18698. +CONFIG_IR_IMON=m
  18699. +CONFIG_IR_MCEUSB=m
  18700. +CONFIG_IR_ITE_CIR=m
  18701. +CONFIG_IR_NUVOTON=m
  18702. +CONFIG_IR_FINTEK=m
  18703. +CONFIG_IR_REDRAT3=m
  18704. +CONFIG_IR_ENE=m
  18705. +CONFIG_IR_STREAMZAP=m
  18706. +CONFIG_IR_WINBOND_CIR=m
  18707. +CONFIG_IR_IGUANA=m
  18708. +CONFIG_IR_TTUSBIR=m
  18709. +CONFIG_IR_GPIO_CIR=m
  18710. +
  18711. +CONFIG_V4L_MEM2MEM_DRIVERS=y
  18712. +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
  18713. +# CONFIG_VIDEO_SH_VEU is not set
  18714. +# CONFIG_VIDEO_RENESAS_VSP1 is not set
  18715. +# CONFIG_V4L_TEST_DRIVERS is not set
  18716. +
  18717. +# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
  18718. +
  18719. +#
  18720. +# Broadcom Crystal HD video decoder driver
  18721. +#
  18722. +CONFIG_CRYSTALHD=m
  18723. +
  18724. +#
  18725. +# Graphics support
  18726. +#
  18727. +
  18728. +CONFIG_DISPLAY_SUPPORT=m
  18729. +CONFIG_VIDEO_OUTPUT_CONTROL=m
  18730. +
  18731. +#
  18732. +# Console display driver support
  18733. +#
  18734. +CONFIG_VGA_CONSOLE=y
  18735. +CONFIG_VGACON_SOFT_SCROLLBACK=y
  18736. +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
  18737. +CONFIG_DUMMY_CONSOLE=y
  18738. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  18739. +
  18740. +#
  18741. +# Logo configuration
  18742. +#
  18743. +# CONFIG_LOGO_LINUX_MONO is not set
  18744. +# CONFIG_LOGO_LINUX_VGA16 is not set
  18745. +CONFIG_LOGO_LINUX_CLUT224=y
  18746. +
  18747. +#
  18748. +# Sound
  18749. +#
  18750. +
  18751. +#
  18752. +# Advanced Linux Sound Architecture
  18753. +#
  18754. +CONFIG_SOUND_OSS_CORE_PRECLAIM=y
  18755. +# CONFIG_SND_DEBUG_VERBOSE is not set
  18756. +CONFIG_SND_VERBOSE_PROCFS=y
  18757. +CONFIG_SND_SEQUENCER=y
  18758. +CONFIG_SND_HRTIMER=y
  18759. +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
  18760. +CONFIG_SND_SEQ_DUMMY=m
  18761. +CONFIG_SND_SEQUENCER_OSS=y
  18762. +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
  18763. +CONFIG_SND_OSSEMUL=y
  18764. +CONFIG_SND_MIXER_OSS=y
  18765. +CONFIG_SND_PCM_OSS=y
  18766. +CONFIG_SND_PCM_OSS_PLUGINS=y
  18767. +CONFIG_SND_RTCTIMER=y
  18768. +CONFIG_SND_DYNAMIC_MINORS=y
  18769. +CONFIG_SND_MAX_CARDS=32
  18770. +# CONFIG_SND_SUPPORT_OLD_API is not set
  18771. +
  18772. +#
  18773. +# Generic devices
  18774. +#
  18775. +CONFIG_SND_DUMMY=m
  18776. +CONFIG_SND_ALOOP=m
  18777. +CONFIG_SND_VIRMIDI=m
  18778. +CONFIG_SND_MTPAV=m
  18779. +CONFIG_SND_MTS64=m
  18780. +CONFIG_SND_SERIAL_U16550=m
  18781. +CONFIG_SND_MPU401=m
  18782. +CONFIG_SND_PORTMAN2X4=m
  18783. +CONFIG_SND_AC97_POWER_SAVE=y
  18784. +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
  18785. +
  18786. +CONFIG_SND_DRIVERS=y
  18787. +
  18788. +#
  18789. +# ISA devices
  18790. +#
  18791. +CONFIG_SND_AD1889=m
  18792. +
  18793. +#
  18794. +# PCI devices
  18795. +#
  18796. +CONFIG_SND_PCI=y
  18797. +CONFIG_SND_ALI5451=m
  18798. +CONFIG_SND_ALS300=m
  18799. +CONFIG_SND_ALS4000=m
  18800. +CONFIG_SND_ATIIXP=m
  18801. +CONFIG_SND_ATIIXP_MODEM=m
  18802. +CONFIG_SND_AU8810=m
  18803. +CONFIG_SND_AU8820=m
  18804. +CONFIG_SND_AU8830=m
  18805. +# CONFIG_SND_AW2 is not set
  18806. +CONFIG_SND_AZT3328=m
  18807. +CONFIG_SND_BT87X=m
  18808. +# CONFIG_SND_BT87X_OVERCLOCK is not set
  18809. +CONFIG_SND_CA0106=m
  18810. +CONFIG_SND_CMIPCI=m
  18811. +CONFIG_SND_CS46XX=m
  18812. +CONFIG_SND_CS46XX_NEW_DSP=y
  18813. +CONFIG_SND_CS4281=m
  18814. +CONFIG_SND_CS5530=m
  18815. +CONFIG_SND_CS5535AUDIO=m
  18816. +CONFIG_SND_EMU10K1=m
  18817. +CONFIG_SND_EMU10K1X=m
  18818. +CONFIG_SND_ENS1370=m
  18819. +CONFIG_SND_ENS1371=m
  18820. +CONFIG_SND_ES1938=m
  18821. +CONFIG_SND_ES1968=m
  18822. +CONFIG_SND_ES1968_INPUT=y
  18823. +CONFIG_SND_ES1968_RADIO=y
  18824. +CONFIG_SND_FM801=m
  18825. +CONFIG_SND_FM801_TEA575X_BOOL=y
  18826. +CONFIG_SND_CTXFI=m
  18827. +CONFIG_SND_LX6464ES=m
  18828. +CONFIG_SND_HDA_INTEL=y
  18829. +CONFIG_SND_HDA_INPUT_BEEP=y
  18830. +CONFIG_SND_HDA_INPUT_BEEP_MODE=0
  18831. +CONFIG_SND_HDA_INPUT_JACK=y
  18832. +CONFIG_SND_HDA_PATCH_LOADER=y
  18833. +CONFIG_SND_HDA_HWDEP=y
  18834. +CONFIG_SND_HDA_CODEC_REALTEK=y
  18835. +CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS=y
  18836. +CONFIG_SND_HDA_CODEC_CA0110=y
  18837. +CONFIG_SND_HDA_CODEC_ANALOG=y
  18838. +CONFIG_SND_HDA_CODEC_SIGMATEL=y
  18839. +CONFIG_SND_HDA_CODEC_VIA=y
  18840. +CONFIG_SND_HDA_CODEC_CIRRUS=y
  18841. +CONFIG_SND_HDA_CODEC_CONEXANT=y
  18842. +CONFIG_SND_HDA_CODEC_CMEDIA=y
  18843. +CONFIG_SND_HDA_CODEC_SI3054=y
  18844. +CONFIG_SND_HDA_CODEC_HDMI=y
  18845. +CONFIG_SND_HDA_I915=y
  18846. +CONFIG_SND_HDA_CODEC_CA0132=y
  18847. +CONFIG_SND_HDA_CODEC_CA0132_DSP=y
  18848. +CONFIG_SND_HDA_GENERIC=y
  18849. +CONFIG_SND_HDA_POWER_SAVE=y
  18850. +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
  18851. +CONFIG_SND_HDA_RECONFIG=y
  18852. +CONFIG_SND_HDA_PREALLOC_SIZE=4096
  18853. +CONFIG_SND_HDSPM=m
  18854. +CONFIG_SND_ICE1712=m
  18855. +CONFIG_SND_ICE1724=m
  18856. +CONFIG_SND_INTEL8X0=y
  18857. +CONFIG_SND_INTEL8X0M=m
  18858. +CONFIG_SND_KORG1212=m
  18859. +CONFIG_SND_MAESTRO3=m
  18860. +CONFIG_SND_MAESTRO3_INPUT=y
  18861. +CONFIG_SND_MIXART=m
  18862. +CONFIG_SND_NM256=m
  18863. +CONFIG_SND_OXYGEN=m
  18864. +CONFIG_SND_RME32=m
  18865. +CONFIG_SND_PCSP=m
  18866. +CONFIG_SND_PCXHR=m
  18867. +CONFIG_SND_RIPTIDE=m
  18868. +CONFIG_SND_RME96=m
  18869. +CONFIG_SND_RME9652=m
  18870. +CONFIG_SND_SIS7019=m
  18871. +CONFIG_SND_SONICVIBES=m
  18872. +CONFIG_SND_HDSP=m
  18873. +CONFIG_SND_TRIDENT=m
  18874. +CONFIG_SND_VIA82XX=m
  18875. +CONFIG_SND_VIA82XX_MODEM=m
  18876. +CONFIG_SND_VIRTUOSO=m
  18877. +CONFIG_SND_VX222=m
  18878. +CONFIG_SND_YMFPCI=m
  18879. +CONFIG_SND_ASIHPI=m
  18880. +CONFIG_SND_LOLA=m
  18881. +
  18882. +#
  18883. +# ALSA USB devices
  18884. +#
  18885. +CONFIG_SND_USB=y
  18886. +CONFIG_SND_USB_CAIAQ=m
  18887. +CONFIG_SND_USB_CAIAQ_INPUT=y
  18888. +CONFIG_SND_USB_USX2Y=m
  18889. +CONFIG_SND_USB_US122L=m
  18890. +CONFIG_SND_USB_UA101=m
  18891. +CONFIG_SND_USB_6FIRE=m
  18892. +CONFIG_SND_USB_HIFACE=m
  18893. +
  18894. +#
  18895. +# PCMCIA devices
  18896. +#
  18897. +# CONFIG_SND_PCMCIA is not set
  18898. +
  18899. +CONFIG_SND_FIREWIRE=y
  18900. +CONFIG_SND_FIREWIRE_SPEAKERS=m
  18901. +CONFIG_SND_ISIGHT=m
  18902. +CONFIG_SND_SCS1X=m
  18903. +CONFIG_SND_DICE=m
  18904. +
  18905. +#
  18906. +# Open Sound System
  18907. +#
  18908. +# CONFIG_SOUND_PRIME is not set
  18909. +
  18910. +#
  18911. +# USB support
  18912. +#
  18913. +CONFIG_USB_SUPPORT=y
  18914. +# CONFIG_USB_DEBUG is not set
  18915. +
  18916. +# DEPRECATED: See bug 362221. Fix udev.
  18917. +# CONFIG_USB_DEVICE_CLASS is not set
  18918. +
  18919. +
  18920. +#
  18921. +# Miscellaneous USB options
  18922. +#
  18923. +
  18924. +# Deprecated.
  18925. +# CONFIG_USB_DEVICEFS is not set
  18926. +
  18927. +CONFIG_USB_DEFAULT_PERSIST=y
  18928. +# CONFIG_USB_DYNAMIC_MINORS is not set
  18929. +CONFIG_USB_SUSPEND=y
  18930. +
  18931. +#
  18932. +# USB Host Controller Drivers
  18933. +#
  18934. +CONFIG_USB_EHCI_ROOT_HUB_TT=y
  18935. +CONFIG_USB_EHCI_TT_NEWSCHED=y
  18936. +# CONFIG_USB_EHCI_MV is not set
  18937. +# CONFIG_USB_EHCI_HCD_PLATFORM is not set
  18938. +# CONFIG_USB_ISP116X_HCD is not set
  18939. +# CONFIG_USB_ISP1760_HCD is not set
  18940. +CONFIG_USB_ISP1362_HCD=m
  18941. +CONFIG_USB_FUSBH200_HCD=m
  18942. +# CONFIG_USB_FOTG210_HCD is not set
  18943. +# CONFIG_USB_GR_UDC is not set
  18944. +CONFIG_USB_OHCI_HCD=y
  18945. +CONFIG_USB_OHCI_HCD_PCI=y
  18946. +# CONFIG_USB_OHCI_HCD_SSB is not set
  18947. +# CONFIG_USB_HCD_TEST_MODE is not set
  18948. +# CONFIG_USB_OHCI_HCD_PLATFORM is not set
  18949. +CONFIG_USB_UHCI_HCD=y
  18950. +CONFIG_USB_SL811_HCD=m
  18951. +CONFIG_USB_SL811_HCD_ISO=y
  18952. +# CONFIG_USB_SL811_CS is not set
  18953. +# CONFIG_USB_R8A66597_HCD is not set
  18954. +CONFIG_USB_XHCI_HCD=y
  18955. +# CONFIG_USB_XHCI_HCD_DEBUGGING is not set
  18956. +
  18957. +#
  18958. +# USB Device Class drivers
  18959. +#
  18960. +
  18961. +#
  18962. +# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
  18963. +#
  18964. +CONFIG_USB_ACM=m
  18965. +CONFIG_USB_PRINTER=m
  18966. +CONFIG_USB_WDM=m
  18967. +CONFIG_USB_TMC=m
  18968. +# CONFIG_BLK_DEV_UB is not set
  18969. +# CONFIG_USB_STORAGE_DEBUG is not set
  18970. +CONFIG_USB_STORAGE_CYPRESS_ATACB=m
  18971. +CONFIG_USB_STORAGE_DATAFAB=m
  18972. +CONFIG_USB_STORAGE_FREECOM=m
  18973. +CONFIG_USB_STORAGE_ISD200=m
  18974. +CONFIG_USB_STORAGE_SDDR09=m
  18975. +CONFIG_USB_STORAGE_SDDR55=m
  18976. +CONFIG_USB_STORAGE_JUMPSHOT=m
  18977. +CONFIG_USB_STORAGE_USBAT=y
  18978. +CONFIG_USB_STORAGE_ONETOUCH=m
  18979. +CONFIG_USB_STORAGE_ALAUDA=m
  18980. +CONFIG_USB_STORAGE_KARMA=m
  18981. +CONFIG_USB_STORAGE_REALTEK=m
  18982. +CONFIG_REALTEK_AUTOPM=y
  18983. +CONFIG_USB_STORAGE_ENE_UB6250=m
  18984. +# CONFIG_USB_LIBUSUAL is not set
  18985. +# CONFIG_USB_UAS is not set
  18986. +
  18987. +
  18988. +#
  18989. +# USB Human Interface Devices (HID)
  18990. +#
  18991. +CONFIG_USB_HID=y
  18992. +
  18993. +CONFIG_HID_SUPPORT=y
  18994. +
  18995. +CONFIG_HID=y
  18996. +CONFIG_I2C_HID=m
  18997. +CONFIG_HID_BATTERY_STRENGTH=y
  18998. +# debugging default is y upstream now
  18999. +CONFIG_HIDRAW=y
  19000. +CONFIG_UHID=m
  19001. +CONFIG_HID_PID=y
  19002. +CONFIG_LOGITECH_FF=y
  19003. +CONFIG_HID_LOGITECH_DJ=m
  19004. +CONFIG_LOGIWII_FF=y
  19005. +CONFIG_LOGIRUMBLEPAD2_FF=y
  19006. +CONFIG_PANTHERLORD_FF=y
  19007. +CONFIG_THRUSTMASTER_FF=y
  19008. +CONFIG_HID_WACOM=m
  19009. +CONFIG_HID_WACOM_POWER_SUPPLY=y
  19010. +CONFIG_ZEROPLUS_FF=y
  19011. +CONFIG_USB_HIDDEV=y
  19012. +CONFIG_USB_IDMOUSE=m
  19013. +CONFIG_DRAGONRISE_FF=y
  19014. +CONFIG_GREENASIA_FF=y
  19015. +CONFIG_SMARTJOYPLUS_FF=y
  19016. +CONFIG_LOGIG940_FF=y
  19017. +CONFIG_LOGIWHEELS_FF=y
  19018. +CONFIG_HID_MAGICMOUSE=y
  19019. +CONFIG_HID_MULTITOUCH=m
  19020. +CONFIG_HID_NTRIG=y
  19021. +CONFIG_HID_QUANTA=y
  19022. +CONFIG_HID_PRIMAX=m
  19023. +CONFIG_HID_PS3REMOTE=m
  19024. +CONFIG_HID_PRODIKEYS=m
  19025. +CONFIG_HID_DRAGONRISE=m
  19026. +CONFIG_HID_GYRATION=m
  19027. +CONFIG_HID_ICADE=m
  19028. +CONFIG_HID_TWINHAN=m
  19029. +CONFIG_HID_ORTEK=m
  19030. +CONFIG_HID_PANTHERLORD=m
  19031. +CONFIG_HID_PETALYNX=m
  19032. +CONFIG_HID_PICOLCD=m
  19033. +CONFIG_HID_RMI=m
  19034. +CONFIG_HID_ROCCAT=m
  19035. +CONFIG_HID_ROCCAT_KONE=m
  19036. +CONFIG_HID_SAMSUNG=m
  19037. +CONFIG_HID_SONY=m
  19038. +CONFIG_SONY_FF=y
  19039. +CONFIG_HID_SUNPLUS=m
  19040. +CONFIG_HID_STEELSERIES=m
  19041. +CONFIG_HID_GREENASIA=m
  19042. +CONFIG_HID_SMARTJOYPLUS=m
  19043. +CONFIG_HID_TOPSEED=m
  19044. +CONFIG_HID_THINGM=m
  19045. +CONFIG_HID_THRUSTMASTER=m
  19046. +CONFIG_HID_XINMO=m
  19047. +CONFIG_HID_ZEROPLUS=m
  19048. +CONFIG_HID_ZYDACRON=m
  19049. +CONFIG_HID_SENSOR_HUB=m
  19050. +CONFIG_HID_SENSOR_GYRO_3D=m
  19051. +CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
  19052. +CONFIG_HID_SENSOR_ALS=m
  19053. +CONFIG_HID_SENSOR_ACCEL_3D=m
  19054. +CONFIG_HID_EMS_FF=m
  19055. +CONFIG_HID_ELECOM=m
  19056. +CONFIG_HID_ELO=m
  19057. +CONFIG_HID_UCLOGIC=m
  19058. +CONFIG_HID_WALTOP=m
  19059. +CONFIG_HID_ROCCAT_PYRA=m
  19060. +CONFIG_HID_ROCCAT_KONEPLUS=m
  19061. +CONFIG_HID_ACRUX=m
  19062. +CONFIG_HID_ACRUX_FF=y
  19063. +CONFIG_HID_KEYTOUCH=m
  19064. +CONFIG_HID_LCPOWER=m
  19065. +CONFIG_HID_LENOVO_TPKBD=m
  19066. +CONFIG_HID_ROCCAT_ARVO=m
  19067. +CONFIG_HID_ROCCAT_ISKU=m
  19068. +CONFIG_HID_ROCCAT_KOVAPLUS=m
  19069. +CONFIG_HID_HOLTEK=m
  19070. +CONFIG_HOLTEK_FF=y
  19071. +CONFIG_HID_HUION=m
  19072. +CONFIG_HID_SPEEDLINK=m
  19073. +CONFIG_HID_WIIMOTE=m
  19074. +CONFIG_HID_WIIMOTE_EXT=y
  19075. +CONFIG_HID_KYE=m
  19076. +CONFIG_HID_SAITEK=m
  19077. +CONFIG_HID_TIVO=m
  19078. +CONFIG_HID_GENERIC=y
  19079. +CONFIG_HID_AUREAL=m
  19080. +CONFIG_HID_APPLEIR=m
  19081. +
  19082. +
  19083. +#
  19084. +# USB Imaging devices
  19085. +#
  19086. +CONFIG_USB_MDC800=m
  19087. +CONFIG_USB_MICROTEK=m
  19088. +
  19089. +#
  19090. +# USB Multimedia devices
  19091. +#
  19092. +
  19093. +CONFIG_USB_DSBR=m
  19094. +# CONFIG_USB_ET61X251 is not set
  19095. +CONFIG_USB_M5602=m
  19096. +CONFIG_USB_STV06XX=m
  19097. +CONFIG_USB_GSPCA=m
  19098. +CONFIG_USB_GSPCA_MR97310A=m
  19099. +CONFIG_USB_GSPCA_BENQ=m
  19100. +CONFIG_USB_GSPCA_CONEX=m
  19101. +CONFIG_USB_GSPCA_CPIA1=m
  19102. +CONFIG_USB_GSPCA_ETOMS=m
  19103. +CONFIG_USB_GSPCA_FINEPIX=m
  19104. +CONFIG_USB_GSPCA_MARS=m
  19105. +CONFIG_USB_GSPCA_OV519=m
  19106. +CONFIG_USB_GSPCA_OV534=m
  19107. +CONFIG_USB_GSPCA_OV534_9=m
  19108. +CONFIG_USB_GSPCA_PAC207=m
  19109. +CONFIG_USB_GSPCA_PAC7311=m
  19110. +CONFIG_USB_GSPCA_SN9C2028=m
  19111. +CONFIG_USB_GSPCA_SN9C20X=m
  19112. +CONFIG_USB_GSPCA_SONIXB=m
  19113. +CONFIG_USB_GSPCA_SONIXJ=m
  19114. +CONFIG_USB_GSPCA_SPCA500=m
  19115. +CONFIG_USB_GSPCA_SPCA501=m
  19116. +CONFIG_USB_GSPCA_SPCA505=m
  19117. +CONFIG_USB_GSPCA_SPCA506=m
  19118. +CONFIG_USB_GSPCA_SPCA508=m
  19119. +CONFIG_USB_GSPCA_SPCA561=m
  19120. +CONFIG_USB_GSPCA_STK014=m
  19121. +CONFIG_USB_GSPCA_STK1135=m
  19122. +CONFIG_USB_GSPCA_SUNPLUS=m
  19123. +CONFIG_USB_GSPCA_T613=m
  19124. +CONFIG_USB_GSPCA_TOPRO=m
  19125. +CONFIG_USB_GSPCA_TV8532=m
  19126. +CONFIG_USB_GSPCA_VC032X=m
  19127. +CONFIG_USB_GSPCA_ZC3XX=m
  19128. +CONFIG_USB_GSPCA_SQ905=m
  19129. +CONFIG_USB_GSPCA_SQ905C=m
  19130. +CONFIG_USB_GSPCA_PAC7302=m
  19131. +CONFIG_USB_GSPCA_STV0680=m
  19132. +CONFIG_USB_GL860=m
  19133. +CONFIG_USB_GSPCA_JEILINJ=m
  19134. +CONFIG_USB_GSPCA_JL2005BCD=m
  19135. +CONFIG_USB_GSPCA_KONICA=m
  19136. +CONFIG_USB_GSPCA_XIRLINK_CIT=m
  19137. +CONFIG_USB_GSPCA_SPCA1528=m
  19138. +CONFIG_USB_GSPCA_SQ930X=m
  19139. +CONFIG_USB_GSPCA_NW80X=m
  19140. +CONFIG_USB_GSPCA_VICAM=m
  19141. +CONFIG_USB_GSPCA_KINECT=m
  19142. +CONFIG_USB_GSPCA_SE401=m
  19143. +
  19144. +CONFIG_USB_S2255=m
  19145. +# CONFIG_VIDEO_SH_MOBILE_CEU is not set
  19146. +# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set
  19147. +# CONFIG_USB_SN9C102 is not set
  19148. +CONFIG_USB_ZR364XX=m
  19149. +
  19150. +#
  19151. +# USB Network adaptors
  19152. +#
  19153. +CONFIG_USB_CATC=m
  19154. +CONFIG_USB_HSO=m
  19155. +CONFIG_USB_KAWETH=m
  19156. +CONFIG_USB_PEGASUS=m
  19157. +CONFIG_USB_RTL8150=m
  19158. +CONFIG_USB_RTL8152=m
  19159. +CONFIG_USB_USBNET=m
  19160. +CONFIG_USB_SPEEDTOUCH=m
  19161. +CONFIG_USB_NET_AX8817X=m
  19162. +CONFIG_USB_NET_AX88179_178A=m
  19163. +CONFIG_USB_NET_DM9601=m
  19164. +CONFIG_USB_NET_SR9700=m
  19165. +CONFIG_USB_NET_SMSC95XX=m
  19166. +CONFIG_USB_NET_GL620A=m
  19167. +CONFIG_USB_NET_NET1080=m
  19168. +CONFIG_USB_NET_PLUSB=m
  19169. +CONFIG_USB_NET_MCS7830=m
  19170. +CONFIG_USB_NET_RNDIS_HOST=m
  19171. +CONFIG_USB_NET_CDC_SUBSET=m
  19172. +CONFIG_USB_NET_CDC_EEM=m
  19173. +CONFIG_USB_NET_CDC_NCM=m
  19174. +CONFIG_USB_NET_HUAWEI_CDC_NCM=m
  19175. +CONFIG_USB_NET_CDC_MBIM=m
  19176. +CONFIG_USB_NET_ZAURUS=m
  19177. +CONFIG_USB_NET_CX82310_ETH=m
  19178. +CONFIG_USB_NET_INT51X1=m
  19179. +CONFIG_USB_CDC_PHONET=m
  19180. +CONFIG_USB_IPHETH=m
  19181. +CONFIG_USB_SIERRA_NET=m
  19182. +CONFIG_USB_VL600=m
  19183. +
  19184. +#
  19185. +# USB Host-to-Host Cables
  19186. +#
  19187. +CONFIG_USB_AN2720=y
  19188. +CONFIG_USB_BELKIN=y
  19189. +
  19190. +#
  19191. +# Intelligent USB Devices/Gadgets
  19192. +#
  19193. +CONFIG_USB_ARMLINUX=y
  19194. +CONFIG_USB_EPSON2888=y
  19195. +CONFIG_USB_KC2190=y
  19196. +
  19197. +# CONFIG_USB_MUSB_HDRC is not set
  19198. +
  19199. +#
  19200. +# USB port drivers
  19201. +#
  19202. +CONFIG_USB_USS720=m
  19203. +
  19204. +#
  19205. +# USB Serial Converter support
  19206. +#
  19207. +CONFIG_USB_SERIAL=y
  19208. +CONFIG_USB_SERIAL_GENERIC=y
  19209. +CONFIG_USB_SERIAL_SIMPLE=m
  19210. +CONFIG_USB_SERIAL_AIRCABLE=m
  19211. +CONFIG_USB_SERIAL_ARK3116=m
  19212. +CONFIG_USB_SERIAL_BELKIN=m
  19213. +CONFIG_USB_SERIAL_CH341=m
  19214. +CONFIG_USB_SERIAL_CYPRESS_M8=m
  19215. +CONFIG_USB_SERIAL_CYBERJACK=m
  19216. +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
  19217. +CONFIG_USB_SERIAL_CP210X=m
  19218. +CONFIG_USB_SERIAL_QUALCOMM=m
  19219. +CONFIG_USB_SERIAL_SYMBOL=m
  19220. +CONFIG_USB_SERIAL_EDGEPORT=m
  19221. +CONFIG_USB_SERIAL_EDGEPORT_TI=m
  19222. +CONFIG_USB_SERIAL_EMPEG=m
  19223. +# CONFIG_USB_SERIAL_F81232 is not set
  19224. +CONFIG_USB_SERIAL_FTDI_SIO=m
  19225. +CONFIG_USB_SERIAL_FUNSOFT=m
  19226. +CONFIG_USB_SERIAL_GARMIN=m
  19227. +CONFIG_USB_SERIAL_HP4X=m
  19228. +CONFIG_USB_SERIAL_IPAQ=m
  19229. +CONFIG_USB_SERIAL_IPW=m
  19230. +CONFIG_USB_SERIAL_IR=m
  19231. +CONFIG_USB_SERIAL_IUU=m
  19232. +CONFIG_USB_SERIAL_KEYSPAN_PDA=m
  19233. +CONFIG_USB_SERIAL_KEYSPAN=m
  19234. +CONFIG_USB_SERIAL_KEYSPAN_MPR=y
  19235. +CONFIG_USB_SERIAL_KEYSPAN_USA28=y
  19236. +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
  19237. +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
  19238. +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
  19239. +CONFIG_USB_SERIAL_KEYSPAN_USA19=y
  19240. +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
  19241. +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
  19242. +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
  19243. +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
  19244. +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
  19245. +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
  19246. +CONFIG_USB_SERIAL_KLSI=m
  19247. +CONFIG_USB_SERIAL_KOBIL_SCT=m
  19248. +CONFIG_USB_SERIAL_MCT_U232=m
  19249. +# CONFIG_USB_SERIAL_METRO is not set
  19250. +CONFIG_USB_SERIAL_MOS7720=m
  19251. +CONFIG_USB_SERIAL_MOS7715_PARPORT=y
  19252. +# CONFIG_USB_SERIAL_ZIO is not set
  19253. +# CONFIG_USB_SERIAL_WISHBONE is not set
  19254. +# CONFIG_USB_SERIAL_ZTE is not set
  19255. +CONFIG_USB_SERIAL_MOS7840=m
  19256. +CONFIG_USB_SERIAL_MOTOROLA=m
  19257. +# CONFIG_USB_SERIAL_MXUPORT is not set
  19258. +CONFIG_USB_SERIAL_NAVMAN=m
  19259. +CONFIG_USB_SERIAL_OPTION=m
  19260. +CONFIG_USB_SERIAL_OTI6858=m
  19261. +CONFIG_USB_SERIAL_OPTICON=m
  19262. +CONFIG_USB_SERIAL_OMNINET=m
  19263. +CONFIG_USB_SERIAL_PL2303=m
  19264. +# CONFIG_USB_SERIAL_QUATECH2 is not set
  19265. +CONFIG_USB_SERIAL_SAFE=m
  19266. +CONFIG_USB_SERIAL_SAFE_PADDED=y
  19267. +CONFIG_USB_SERIAL_SIERRAWIRELESS=m
  19268. +CONFIG_USB_SERIAL_SIEMENS_MPI=m
  19269. +CONFIG_USB_SERIAL_SPCP8X5=m
  19270. +CONFIG_USB_SERIAL_TI=m
  19271. +CONFIG_USB_SERIAL_VISOR=m
  19272. +CONFIG_USB_SERIAL_WHITEHEAT=m
  19273. +CONFIG_USB_SERIAL_XIRCOM=m
  19274. +CONFIG_USB_SERIAL_QCAUX=m
  19275. +CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
  19276. +CONFIG_USB_SERIAL_XSENS_MT=m
  19277. +CONFIG_USB_SERIAL_DEBUG=m
  19278. +CONFIG_USB_SERIAL_SSU100=m
  19279. +CONFIG_USB_SERIAL_QT2=m
  19280. +CONFIG_USB_SERIAL_FLASHLOADER=m
  19281. +CONFIG_USB_SERIAL_SUUNTO=m
  19282. +CONFIG_USB_SERIAL_CONSOLE=y
  19283. +
  19284. +CONFIG_USB_EZUSB=y
  19285. +CONFIG_USB_EMI62=m
  19286. +CONFIG_USB_LED=m
  19287. +# CONFIG_USB_CYPRESS_CY7C63 is not set
  19288. +
  19289. +#
  19290. +# USB Miscellaneous drivers
  19291. +#
  19292. +
  19293. +CONFIG_USB_ADUTUX=m
  19294. +CONFIG_USB_SEVSEG=m
  19295. +CONFIG_USB_ALI_M5632=y
  19296. +CONFIG_USB_APPLEDISPLAY=m
  19297. +
  19298. +# Physical Layer USB driver
  19299. +# CONFIG_USB_OTG_FSM is not set
  19300. +
  19301. +# CONFIG_GENERIC_PHY is not set
  19302. +# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
  19303. +# CONFIG_PHY_EXYNOS_DP_VIDEO is not set
  19304. +# CONFIG_OMAP_USB2 is not set
  19305. +# CONFIG_OMAP_USB3 is not set
  19306. +# CONFIG_OMAP_CONTROL_USB is not set
  19307. +# CONFIG_AM335X_PHY_USB is not set
  19308. +# CONFIG_SAMSUNG_USBPHY is not set
  19309. +# CONFIG_SAMSUNG_USB2PHY is not set
  19310. +# CONFIG_SAMSUNG_USB3PHY is not set
  19311. +# CONFIG_BCM_KONA_USB2_PHY is not set
  19312. +CONFIG_USB_RCAR_PHY=m
  19313. +CONFIG_USB_ATM=m
  19314. +CONFIG_USB_CXACRU=m
  19315. +# CONFIG_USB_C67X00_HCD is not set
  19316. +# CONFIG_USB_CYTHERM is not set
  19317. +CONFIG_USB_EMI26=m
  19318. +CONFIG_USB_FTDI_ELAN=m
  19319. +CONFIG_USB_FILE_STORAGE=m
  19320. +# CONFIG_USB_FILE_STORAGE_TEST is not set
  19321. +# CONFIG_USB_DWC3 is not set
  19322. +# CONFIG_USB_GADGETFS is not set
  19323. +# CONFIG_USB_OXU210HP_HCD is not set
  19324. +CONFIG_USB_IOWARRIOR=m
  19325. +CONFIG_USB_ISIGHTFW=m
  19326. +CONFIG_USB_YUREX=m
  19327. +CONFIG_USB_EZUSB_FX2=m
  19328. +CONFIG_USB_HSIC_USB3503=m
  19329. +CONFIG_USB_LCD=m
  19330. +CONFIG_USB_LD=m
  19331. +CONFIG_USB_LEGOTOWER=m
  19332. +CONFIG_USB_MON=y
  19333. +CONFIG_USB_PWC=m
  19334. +CONFIG_USB_PWC_INPUT_EVDEV=y
  19335. +# CONFIG_USB_PWC_DEBUG is not set
  19336. +# CONFIG_USB_RIO500 is not set
  19337. +CONFIG_USB_SISUSBVGA=m
  19338. +CONFIG_USB_SISUSBVGA_CON=y
  19339. +CONFIG_RADIO_SI470X=y
  19340. +CONFIG_USB_KEENE=m
  19341. +CONFIG_USB_MA901=m
  19342. +CONFIG_USB_SI470X=m
  19343. +CONFIG_I2C_SI470X=m
  19344. +CONFIG_RADIO_SI4713=m
  19345. +# CONFIG_RADIO_TEF6862 is not set
  19346. +CONFIG_USB_MR800=m
  19347. +CONFIG_USB_STKWEBCAM=m
  19348. +# CONFIG_USB_TEST is not set
  19349. +# CONFIG_USB_EHSET_TEST_FIXTURE is not set
  19350. +CONFIG_USB_TRANCEVIBRATOR=m
  19351. +CONFIG_USB_U132_HCD=m
  19352. +CONFIG_USB_UEAGLEATM=m
  19353. +CONFIG_USB_XUSBATM=m
  19354. +
  19355. +# CONFIG_USB_DWC2 is not set
  19356. +
  19357. +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
  19358. +
  19359. +# CONFIG_USB_ISP1301 is not set
  19360. +
  19361. +# CONFIG_USB_OTG is not set
  19362. +
  19363. +#
  19364. +# Sonics Silicon Backplane
  19365. +#
  19366. +CONFIG_SSB=m
  19367. +CONFIG_SSB_PCIHOST=y
  19368. +CONFIG_SSB_SDIOHOST=y
  19369. +CONFIG_SSB_PCMCIAHOST=y
  19370. +# CONFIG_SSB_SILENT is not set
  19371. +# CONFIG_SSB_DEBUG is not set
  19372. +CONFIG_SSB_DRIVER_PCICORE=y
  19373. +CONFIG_SSB_DRIVER_GPIO=y
  19374. +
  19375. +# Multifunction USB devices
  19376. +# CONFIG_MFD_PCF50633 is not set
  19377. +CONFIG_PCF50633_ADC=m
  19378. +CONFIG_PCF50633_GPIO=m
  19379. +# CONFIG_AB3100_CORE is not set
  19380. +CONFIG_INPUT_PCF50633_PMU=m
  19381. +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
  19382. +
  19383. +CONFIG_MFD_SUPPORT=y
  19384. +CONFIG_MFD_VX855=m
  19385. +CONFIG_MFD_SM501=m
  19386. +CONFIG_MFD_SM501_GPIO=y
  19387. +CONFIG_MFD_RTSX_PCI=m
  19388. +# CONFIG_MFD_TI_AM335X_TSCADC is not set
  19389. +CONFIG_MFD_VIPERBOARD=m
  19390. +# CONFIG_MFD_RETU is not set
  19391. +# CONFIG_MFD_TC6393XB is not set
  19392. +# CONFIG_MFD_WM8400 is not set
  19393. +# CONFIG_MFD_WM8350_I2C is not set
  19394. +# CONFIG_MFD_WM8350 is not set
  19395. +# CONFIG_MFD_WM831X is not set
  19396. +# CONFIG_AB3100_OTP is not set
  19397. +# CONFIG_MFD_TIMBERDALE is not set
  19398. +# CONFIG_MFD_WM8994 is not set
  19399. +# CONFIG_MFD_88PM860X is not set
  19400. +# CONFIG_LPC_SCH is not set
  19401. +# CONFIG_LPC_ICH is not set
  19402. +# CONFIG_HTC_I2CPLD is not set
  19403. +# CONFIG_MFD_MAX8925 is not set
  19404. +# CONFIG_MFD_ASIC3 is not set
  19405. +# CONFIG_MFD_AS3722 is not set
  19406. +# CONFIG_HTC_EGPIO is not set
  19407. +# CONFIG_TPS6507X is not set
  19408. +# CONFIG_ABX500_CORE is not set
  19409. +# CONFIG_MFD_RDC321X is not set
  19410. +# CONFIG_MFD_JANZ_CMODIO is not set
  19411. +# CONFIG_MFD_KEMPLD is not set
  19412. +# CONFIG_MFD_WM831X_I2C is not set
  19413. +# CONFIG_MFD_CS5535 is not set
  19414. +# CONFIG_MFD_STMPE is not set
  19415. +# CONFIG_MFD_MAX8998 is not set
  19416. +# CONFIG_MFD_TPS6586X is not set
  19417. +# CONFIG_MFD_TC3589X is not set
  19418. +# CONFIG_MFD_WL1273_CORE is not set
  19419. +# CONFIG_MFD_TPS65217 is not set
  19420. +# CONFIG_MFD_LM3533 is not set
  19421. +# CONFIG_MFD_ARIZONA is not set
  19422. +# CONFIG_MFD_ARIZONA_I2C is not set
  19423. +# CONFIG_MFD_CROS_EC is not set
  19424. +# CONFIG_MFD_TPS65912 is not set
  19425. +# CONFIG_MFD_SYSCON is not set
  19426. +# CONFIG_MFD_DA9063 is not set
  19427. +# CONFIG_MFD_LP3943 is not set
  19428. +
  19429. +#
  19430. +# File systems
  19431. +#
  19432. +CONFIG_MISC_FILESYSTEMS=y
  19433. +
  19434. +# ext4 is used for ext2 and ext3 filesystems
  19435. +CONFIG_JBD2=y
  19436. +CONFIG_FS_MBCACHE=y
  19437. +CONFIG_REISERFS_FS=m
  19438. +# CONFIG_REISERFS_CHECK is not set
  19439. +CONFIG_REISERFS_PROC_INFO=y
  19440. +CONFIG_REISERFS_FS_XATTR=y
  19441. +CONFIG_REISERFS_FS_POSIX_ACL=y
  19442. +CONFIG_REISERFS_FS_SECURITY=y
  19443. +CONFIG_JFS_FS=m
  19444. +# CONFIG_JFS_DEBUG is not set
  19445. +# CONFIG_JFS_STATISTICS is not set
  19446. +CONFIG_JFS_POSIX_ACL=y
  19447. +CONFIG_JFS_SECURITY=y
  19448. +CONFIG_XFS_FS=m
  19449. +# CONFIG_XFS_DEBUG is not set
  19450. +# CONFIG_XFS_RT is not set
  19451. +CONFIG_XFS_QUOTA=y
  19452. +CONFIG_XFS_POSIX_ACL=y
  19453. +CONFIG_MINIX_FS=m
  19454. +CONFIG_ROMFS_FS=m
  19455. +# CONFIG_QFMT_V1 is not set
  19456. +CONFIG_QFMT_V2=y
  19457. +CONFIG_QUOTACTL=y
  19458. +CONFIG_DNOTIFY=y
  19459. +# Autofsv3 is obsolete.
  19460. +# systemd is dependant upon AUTOFS, so build it in.
  19461. +# CONFIG_EXOFS_FS is not set
  19462. +# CONFIG_EXOFS_DEBUG is not set
  19463. +CONFIG_NILFS2_FS=m
  19464. +# CONFIG_LOGFS is not set
  19465. +CONFIG_CEPH_FS=m
  19466. +CONFIG_CEPH_FSCACHE=y
  19467. +CONFIG_BLK_DEV_RBD=m
  19468. +CONFIG_CEPH_LIB=m
  19469. +CONFIG_CEPH_FS_POSIX_ACL=y
  19470. +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set
  19471. +
  19472. +CONFIG_FSCACHE=m
  19473. +CONFIG_FSCACHE_STATS=y
  19474. +# CONFIG_FSCACHE_HISTOGRAM is not set
  19475. +# CONFIG_FSCACHE_DEBUG is not set
  19476. +CONFIG_FSCACHE_OBJECT_LIST=y
  19477. +
  19478. +CONFIG_CACHEFILES=m
  19479. +# CONFIG_CACHEFILES_DEBUG is not set
  19480. +# CONFIG_CACHEFILES_HISTOGRAM is not set
  19481. +
  19482. +#
  19483. +# CD-ROM/DVD Filesystems
  19484. +#
  19485. +
  19486. +#
  19487. +# DOS/FAT/NT Filesystems
  19488. +#
  19489. +CONFIG_FAT_FS=m
  19490. +CONFIG_FAT_DEFAULT_CODEPAGE=437
  19491. +CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
  19492. +# CONFIG_NTFS_FS is not set
  19493. +
  19494. +#
  19495. +# Pseudo filesystems
  19496. +#
  19497. +CONFIG_PROC_FS=y
  19498. +CONFIG_PROC_KCORE=y
  19499. +CONFIG_PROC_VMCORE=y
  19500. +CONFIG_TMPFS_POSIX_ACL=y
  19501. +CONFIG_TMPFS_XATTR=y
  19502. +CONFIG_HUGETLBFS=y
  19503. +CONFIG_HUGETLB_PAGE=y
  19504. +# CONFIG_DEBUG_FS is not set
  19505. +
  19506. +#
  19507. +# Miscellaneous filesystems
  19508. +#
  19509. +# CONFIG_ADFS_FS is not set
  19510. +CONFIG_AFFS_FS=m
  19511. +CONFIG_ECRYPT_FS=m
  19512. +# CONFIG_ECRYPT_FS_MESSAGING is not set
  19513. +CONFIG_HFS_FS=m
  19514. +CONFIG_HFSPLUS_FS=m
  19515. +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set
  19516. +CONFIG_BEFS_FS=m
  19517. +# CONFIG_BEFS_DEBUG is not set
  19518. +# CONFIG_BFS_FS is not set
  19519. +# CONFIG_EFS_FS is not set
  19520. +
  19521. +CONFIG_CRAMFS=m
  19522. +CONFIG_SQUASHFS=m
  19523. +CONFIG_SQUASHFS_XATTR=y
  19524. +CONFIG_SQUASHFS_LZO=y
  19525. +CONFIG_SQUASHFS_XZ=y
  19526. +CONFIG_SQUASHFS_ZLIB=y
  19527. +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
  19528. +# CONFIG_SQUASHFS_EMBEDDED is not set
  19529. +# CONFIG_VXFS_FS is not set
  19530. +# CONFIG_HPFS_FS is not set
  19531. +# CONFIG_QNX4FS_FS is not set
  19532. +# CONFIG_QNX6FS_FS is not set
  19533. +CONFIG_SYSV_FS=m
  19534. +CONFIG_UFS_FS=m
  19535. +# CONFIG_UFS_FS_WRITE is not set
  19536. +# CONFIG_UFS_DEBUG is not set
  19537. +CONFIG_9P_FS=m
  19538. +CONFIG_9P_FSCACHE=y
  19539. +CONFIG_9P_FS_POSIX_ACL=y
  19540. +CONFIG_9P_FS_SECURITY=y
  19541. +# CONFIG_OMFS_FS is not set
  19542. +CONFIG_CUSE=m
  19543. +# CONFIG_F2FS_FS is not set
  19544. +
  19545. +#
  19546. +# Network File Systems
  19547. +#
  19548. +CONFIG_NETWORK_FILESYSTEMS=y
  19549. +# CONFIG_NFS_V2 is not set
  19550. +CONFIG_NFS_V3=y
  19551. +CONFIG_NFS_SWAP=y
  19552. +CONFIG_NFS_V4_1=y
  19553. +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
  19554. +# CONFIG_NFS_V4_1_MIGRATION is not set
  19555. +CONFIG_NFS_V4_2=y
  19556. +CONFIG_NFSD=m
  19557. +CONFIG_NFSD_V3=y
  19558. +CONFIG_NFSD_V3_ACL=y
  19559. +CONFIG_NFSD_V4=y
  19560. +CONFIG_NFSD_V4_SECURITY_LABEL=y
  19561. +CONFIG_NFS_FSCACHE=y
  19562. +# CONFIG_NFS_USE_LEGACY_DNS is not set
  19563. +CONFIG_PNFS_OBJLAYOUT=m
  19564. +CONFIG_PNFS_BLOCK=m
  19565. +CONFIG_LOCKD=m
  19566. +CONFIG_LOCKD_V4=y
  19567. +CONFIG_EXPORTFS=y
  19568. +CONFIG_SUNRPC=m
  19569. +CONFIG_SUNRPC_GSS=m
  19570. +CONFIG_SUNRPC_XPRT_RDMA=m
  19571. +CONFIG_SUNRPC_DEBUG=y
  19572. +CONFIG_RPCSEC_GSS_KRB5=m
  19573. +CONFIG_CIFS=m
  19574. +CONFIG_CIFS_STATS=y
  19575. +# CONFIG_CIFS_STATS2 is not set
  19576. +CONFIG_CIFS_SMB2=y
  19577. +CONFIG_CIFS_UPCALL=y
  19578. +CONFIG_CIFS_XATTR=y
  19579. +CONFIG_CIFS_POSIX=y
  19580. +CONFIG_CIFS_FSCACHE=y
  19581. +CONFIG_CIFS_ACL=y
  19582. +CONFIG_CIFS_WEAK_PW_HASH=y
  19583. +CONFIG_CIFS_DEBUG=y
  19584. +# CONFIG_CIFS_DEBUG2 is not set
  19585. +CONFIG_CIFS_DFS_UPCALL=y
  19586. +CONFIG_CIFS_NFSD_EXPORT=y
  19587. +CONFIG_NCP_FS=m
  19588. +CONFIG_NCPFS_PACKET_SIGNING=y
  19589. +CONFIG_NCPFS_IOCTL_LOCKING=y
  19590. +CONFIG_NCPFS_STRONG=y
  19591. +CONFIG_NCPFS_NFS_NS=y
  19592. +CONFIG_NCPFS_OS2_NS=y
  19593. +CONFIG_NCPFS_SMALLDOS=y
  19594. +CONFIG_NCPFS_NLS=y
  19595. +CONFIG_NCPFS_EXTRAS=y
  19596. +CONFIG_CODA_FS=m
  19597. +# CONFIG_AFS_FS is not set
  19598. +# CONFIG_AF_RXRPC is not set
  19599. +
  19600. +CONFIG_OCFS2_FS=m
  19601. +# CONFIG_OCFS2_DEBUG_FS is not set
  19602. +# CONFIG_OCFS2_DEBUG_MASKLOG is not set
  19603. +CONFIG_OCFS2_FS_O2CB=m
  19604. +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
  19605. +# CONFIG_OCFS2_FS_STATS is not set
  19606. +
  19607. +CONFIG_BTRFS_FS=m
  19608. +CONFIG_BTRFS_FS_POSIX_ACL=y
  19609. +# Maybe see if we want this on for debug kernels?
  19610. +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
  19611. +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
  19612. +# CONFIG_BTRFS_DEBUG is not set
  19613. +# CONFIG_BTRFS_ASSERT is not set
  19614. +
  19615. +CONFIG_CONFIGFS_FS=y
  19616. +
  19617. +CONFIG_DLM=m
  19618. +CONFIG_DLM_DEBUG=y
  19619. +CONFIG_GFS2_FS=m
  19620. +CONFIG_GFS2_FS_LOCKING_DLM=y
  19621. +
  19622. +
  19623. +CONFIG_UBIFS_FS_XATTR=y
  19624. +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
  19625. +# CONFIG_UBIFS_FS_DEBUG is not set
  19626. +
  19627. +#
  19628. +# Partition Types
  19629. +#
  19630. +CONFIG_PARTITION_ADVANCED=y
  19631. +# CONFIG_ACORN_PARTITION is not set
  19632. +CONFIG_AIX_PARTITION=y
  19633. +CONFIG_AMIGA_PARTITION=y
  19634. +# CONFIG_ATARI_PARTITION is not set
  19635. +CONFIG_BSD_DISKLABEL=y
  19636. +CONFIG_EFI_PARTITION=y
  19637. +CONFIG_KARMA_PARTITION=y
  19638. +CONFIG_LDM_PARTITION=y
  19639. +# CONFIG_LDM_DEBUG is not set
  19640. +CONFIG_MAC_PARTITION=y
  19641. +CONFIG_MSDOS_PARTITION=y
  19642. +CONFIG_MINIX_SUBPARTITION=y
  19643. +CONFIG_OSF_PARTITION=y
  19644. +CONFIG_SGI_PARTITION=y
  19645. +CONFIG_SOLARIS_X86_PARTITION=y
  19646. +CONFIG_SUN_PARTITION=y
  19647. +# CONFIG_SYSV68_PARTITION is not set
  19648. +CONFIG_UNIXWARE_DISKLABEL=y
  19649. +# CONFIG_ULTRIX_PARTITION is not set
  19650. +# CONFIG_CMDLINE_PARTITION is not set
  19651. +
  19652. +CONFIG_NLS=y
  19653. +
  19654. +#
  19655. +# Native Language Support
  19656. +#
  19657. +CONFIG_NLS_CODEPAGE_737=m
  19658. +CONFIG_NLS_CODEPAGE_775=m
  19659. +CONFIG_NLS_CODEPAGE_850=m
  19660. +CONFIG_NLS_CODEPAGE_852=m
  19661. +CONFIG_NLS_CODEPAGE_855=m
  19662. +CONFIG_NLS_CODEPAGE_857=m
  19663. +CONFIG_NLS_CODEPAGE_860=m
  19664. +CONFIG_NLS_CODEPAGE_861=m
  19665. +CONFIG_NLS_CODEPAGE_862=m
  19666. +CONFIG_NLS_CODEPAGE_863=m
  19667. +CONFIG_NLS_CODEPAGE_864=m
  19668. +CONFIG_NLS_CODEPAGE_865=m
  19669. +CONFIG_NLS_CODEPAGE_866=m
  19670. +CONFIG_NLS_CODEPAGE_869=m
  19671. +CONFIG_NLS_CODEPAGE_936=m
  19672. +CONFIG_NLS_CODEPAGE_950=m
  19673. +CONFIG_NLS_CODEPAGE_932=m
  19674. +CONFIG_NLS_CODEPAGE_949=m
  19675. +CONFIG_NLS_CODEPAGE_874=m
  19676. +CONFIG_NLS_ISO8859_8=m
  19677. +CONFIG_NLS_CODEPAGE_1250=m
  19678. +CONFIG_NLS_CODEPAGE_1251=m
  19679. +CONFIG_NLS_ISO8859_2=m
  19680. +CONFIG_NLS_ISO8859_3=m
  19681. +CONFIG_NLS_ISO8859_4=m
  19682. +CONFIG_NLS_ISO8859_5=m
  19683. +CONFIG_NLS_ISO8859_6=m
  19684. +CONFIG_NLS_ISO8859_7=m
  19685. +CONFIG_NLS_ISO8859_9=m
  19686. +CONFIG_NLS_ISO8859_13=m
  19687. +CONFIG_NLS_ISO8859_14=m
  19688. +CONFIG_NLS_KOI8_R=m
  19689. +CONFIG_NLS_KOI8_U=m
  19690. +CONFIG_NLS_MAC_ROMAN=m
  19691. +CONFIG_NLS_MAC_CELTIC=m
  19692. +CONFIG_NLS_MAC_CENTEURO=m
  19693. +CONFIG_NLS_MAC_CROATIAN=m
  19694. +CONFIG_NLS_MAC_CYRILLIC=m
  19695. +CONFIG_NLS_MAC_GAELIC=m
  19696. +CONFIG_NLS_MAC_GREEK=m
  19697. +CONFIG_NLS_MAC_ICELAND=m
  19698. +CONFIG_NLS_MAC_INUIT=m
  19699. +CONFIG_NLS_MAC_ROMANIAN=m
  19700. +CONFIG_NLS_MAC_TURKISH=m
  19701. +
  19702. +#
  19703. +# Profiling support
  19704. +#
  19705. +CONFIG_PROFILING=y
  19706. +CONFIG_OPROFILE=m
  19707. +CONFIG_OPROFILE_EVENT_MULTIPLEX=y
  19708. +
  19709. +#
  19710. +# Kernel hacking
  19711. +#
  19712. +CONFIG_DEBUG_KERNEL=y
  19713. +CONFIG_FRAME_WARN=1024
  19714. +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x0
  19715. +# CONFIG_DEBUG_INFO is not set
  19716. +CONFIG_FRAME_POINTER=y
  19717. +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
  19718. +# CONFIG_DEBUG_DRIVER is not set
  19719. +CONFIG_HEADERS_CHECK=y
  19720. +# CONFIG_LKDTM is not set
  19721. +# CONFIG_NOTIFIER_ERROR_INJECTION is not set
  19722. +# CONFIG_READABLE_ASM is not set
  19723. +
  19724. +# CONFIG_RT_MUTEX_TESTER is not set
  19725. +# CONFIG_DEBUG_LOCKDEP is not set
  19726. +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
  19727. +
  19728. +# DEBUG options that don't get enabled/disabled with 'make debug/release'
  19729. +
  19730. +# This generates a huge amount of dmesg spew
  19731. +# CONFIG_DEBUG_KOBJECT is not set
  19732. +#
  19733. +# This breaks booting until the module patches are in-tree
  19734. +# CONFIG_DEBUG_KOBJECT_RELEASE is not set
  19735. +#
  19736. +#
  19737. +# These debug options are deliberatly left on (even in 'make release' kernels).
  19738. +# They aren't that much of a performance impact, and the value
  19739. +# from getting useful bug-reports makes it worth leaving them on.
  19740. +# CONFIG_DEBUG_HIGHMEM is not set
  19741. +# CONFIG_DEBUG_SHIRQ is not set
  19742. +CONFIG_BOOT_PRINTK_DELAY=y
  19743. +CONFIG_DEBUG_DEVRES=y
  19744. +CONFIG_DEBUG_RODATA_TEST=y
  19745. +CONFIG_DEBUG_NX_TEST=m
  19746. +CONFIG_DEBUG_SET_MODULE_RONX=y
  19747. +CONFIG_DEBUG_BOOT_PARAMS=y
  19748. +# CONFIG_DEBUG_VM is not set
  19749. +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
  19750. +CONFIG_LOCKUP_DETECTOR=y
  19751. +# CONFIG_DEBUG_INFO_REDUCED is not set
  19752. +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
  19753. +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
  19754. +# CONFIG_PANIC_ON_OOPS is not set
  19755. +CONFIG_PANIC_TIMEOUT=0
  19756. +CONFIG_ATOMIC64_SELFTEST=y
  19757. +CONFIG_MEMORY_FAILURE=y
  19758. +CONFIG_HWPOISON_INJECT=m
  19759. +CONFIG_CROSS_MEMORY_ATTACH=y
  19760. +# CONFIG_DEBUG_SECTION_MISMATCH is not set
  19761. +# CONFIG_BACKTRACE_SELF_TEST is not set
  19762. +CONFIG_RESOURCE_COUNTERS=y
  19763. +# CONFIG_DEBUG_VIRTUAL is not set
  19764. +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
  19765. +CONFIG_EARLY_PRINTK_DBGP=y
  19766. +# CONFIG_PAGE_POISONING is not set
  19767. +# CONFIG_CRASH_DUMP is not set
  19768. +# CONFIG_CRASH is not set
  19769. +# CONFIG_GCOV_KERNEL is not set
  19770. +# CONFIG_RAMOOPS is not set
  19771. +
  19772. +
  19773. +#
  19774. +# Security options
  19775. +#
  19776. +CONFIG_SECURITY=y
  19777. +# CONFIG_SECURITY_DMESG_RESTRICT is not set
  19778. +CONFIG_SECURITY_NETWORK=y
  19779. +CONFIG_SECURITY_NETWORK_XFRM=y
  19780. +# CONFIG_SECURITY_PATH is not set
  19781. +CONFIG_SECURITY_SELINUX=y
  19782. +CONFIG_SECURITY_SELINUX_BOOTPARAM=y
  19783. +CONFIG_SECURITY_SELINUX_DISABLE=y
  19784. +CONFIG_SECURITY_SELINUX_DEVELOP=y
  19785. +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
  19786. +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
  19787. +CONFIG_SECURITY_SELINUX_AVC_STATS=y
  19788. +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
  19789. +# CONFIG_SECURITY_SMACK is not set
  19790. +# CONFIG_SECURITY_TOMOYO is not set
  19791. +# CONFIG_SECURITY_APPARMOR is not set
  19792. +# CONFIG_SECURITY_YAMA is not set
  19793. +CONFIG_AUDIT=y
  19794. +CONFIG_AUDITSYSCALL=y
  19795. +# http://lists.fedoraproject.org/pipermail/kernel/2013-February/004125.html
  19796. +CONFIG_AUDIT_LOGINUID_IMMUTABLE=y
  19797. +
  19798. +CONFIG_SECCOMP=y
  19799. +
  19800. +# CONFIG_SSBI is not set
  19801. +
  19802. +#
  19803. +# Cryptographic options
  19804. +#
  19805. +CONFIG_CRYPTO=y
  19806. +CONFIG_CRYPTO_FIPS=y
  19807. +CONFIG_CRYPTO_USER_API_HASH=y
  19808. +CONFIG_CRYPTO_USER_API_SKCIPHER=y
  19809. +CONFIG_CRYPTO_MANAGER=y
  19810. +# Note, CONFIG_CRYPTO_MANAGER_DISABLE_TESTS needs to be unset, or FIPS will be disabled.
  19811. +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
  19812. +CONFIG_CRYPTO_HW=y
  19813. +CONFIG_CRYPTO_BLKCIPHER=y
  19814. +# CONFIG_CRYPTO_CRYPTD is not set
  19815. +CONFIG_CRYPTO_AES=y
  19816. +CONFIG_CRYPTO_ARC4=m
  19817. +CONFIG_CRYPTO_ANUBIS=m
  19818. +CONFIG_CRYPTO_AUTHENC=m
  19819. +CONFIG_CRYPTO_CAST5=m
  19820. +CONFIG_CRYPTO_CAST6=m
  19821. +CONFIG_CRYPTO_CRC32C=y
  19822. +CONFIG_CRYPTO_CRC32=m
  19823. +CONFIG_CRYPTO_CTR=y
  19824. +CONFIG_CRYPTO_DEFLATE=m
  19825. +CONFIG_CRYPTO_FCRYPT=m
  19826. +CONFIG_CRYPTO_GF128MUL=m
  19827. +CONFIG_CRYPTO_CMAC=m
  19828. +CONFIG_CRYPTO_HMAC=y
  19829. +CONFIG_CRYPTO_KHAZAD=m
  19830. +CONFIG_CRYPTO_LZO=m
  19831. +CONFIG_CRYPTO_LZ4=m
  19832. +CONFIG_CRYPTO_LZ4HC=m
  19833. +CONFIG_CRYPTO_NULL=m
  19834. +CONFIG_CRYPTO_PCBC=m
  19835. +CONFIG_CRYPTO_SALSA20=m
  19836. +CONFIG_CRYPTO_SALSA20_586=m
  19837. +CONFIG_CRYPTO_SEED=m
  19838. +CONFIG_CRYPTO_SEQIV=m
  19839. +CONFIG_CRYPTO_SERPENT=m
  19840. +CONFIG_CRYPTO_TEA=m
  19841. +CONFIG_CRYPTO_XCBC=m
  19842. +CONFIG_CRYPTO_VMAC=m
  19843. +CONFIG_CRYPTO_CRC32C_INTEL=m
  19844. +CONFIG_CRYPTO_GHASH=m
  19845. +CONFIG_CRYPTO_DEV_HIFN_795X=m
  19846. +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
  19847. +CONFIG_CRYPTO_PCRYPT=m
  19848. +
  19849. +
  19850. +
  19851. +# Random number generation
  19852. +
  19853. +#
  19854. +# Library routines
  19855. +#
  19856. +CONFIG_CRC16=y
  19857. +CONFIG_CRC32=m
  19858. +# CONFIG_CRC32_SELFTEST is not set
  19859. +CONFIG_CRC_ITU_T=m
  19860. +CONFIG_CRC8=m
  19861. +# CONFIG_RANDOM32_SELFTEST is not set
  19862. +CONFIG_CORDIC=m
  19863. +# CONFIG_DDR is not set
  19864. +
  19865. +CONFIG_CRYPTO_ZLIB=m
  19866. +CONFIG_ZLIB_INFLATE=y
  19867. +CONFIG_ZLIB_DEFLATE=m
  19868. +
  19869. +CONFIG_INITRAMFS_SOURCE=""
  19870. +CONFIG_KEYS=y
  19871. +CONFIG_PERSISTENT_KEYRINGS=y
  19872. +CONFIG_BIG_KEYS=y
  19873. +CONFIG_TRUSTED_KEYS=m
  19874. +CONFIG_ENCRYPTED_KEYS=m
  19875. +CONFIG_KEYS_DEBUG_PROC_KEYS=y
  19876. +CONFIG_CDROM_PKTCDVD=m
  19877. +CONFIG_CDROM_PKTCDVD_BUFFERS=8
  19878. +# CONFIG_CDROM_PKTCDVD_WCACHE is not set
  19879. +
  19880. +CONFIG_ATA_OVER_ETH=m
  19881. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  19882. +CONFIG_BACKLIGHT_CLASS_DEVICE=m
  19883. +# CONFIG_BACKLIGHT_GENERIC is not set
  19884. +CONFIG_BACKLIGHT_PROGEAR=m
  19885. +
  19886. +CONFIG_LCD_CLASS_DEVICE=m
  19887. +CONFIG_LCD_PLATFORM=m
  19888. +
  19889. +CONFIG_FAIR_GROUP_SCHED=y
  19890. +CONFIG_CFS_BANDWIDTH=y
  19891. +CONFIG_SCHED_OMIT_FRAME_POINTER=y
  19892. +CONFIG_RT_GROUP_SCHED=y
  19893. +CONFIG_SCHED_AUTOGROUP=y
  19894. +
  19895. +CONFIG_CPUSETS=y
  19896. +CONFIG_PROC_PID_CPUSET=y
  19897. +
  19898. +# CONFIG_CGROUP_DEBUG is not set
  19899. +CONFIG_CGROUP_CPUACCT=y
  19900. +CONFIG_CGROUP_DEVICE=y
  19901. +CONFIG_CGROUP_FREEZER=y
  19902. +CONFIG_CGROUP_SCHED=y
  19903. +CONFIG_MEMCG=y
  19904. +CONFIG_MEMCG_SWAP=y
  19905. +CONFIG_MEMCG_SWAP_ENABLED=y
  19906. +CONFIG_MEMCG_KMEM=y
  19907. +# CONFIG_CGROUP_HUGETLB is not set
  19908. +CONFIG_CGROUP_PERF=y
  19909. +CONFIG_CGROUP_NET_PRIO=m
  19910. +# CONFIG_CGROUP_NET_CLASSID is not set
  19911. +CONFIG_BLK_CGROUP=y
  19912. +
  19913. +# CONFIG_SYSFS_DEPRECATED is not set
  19914. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  19915. +
  19916. +CONFIG_PRINTK_TIME=y
  19917. +
  19918. +CONFIG_ENABLE_MUST_CHECK=y
  19919. +# CONFIG_ENABLE_WARN_DEPRECATED is not set
  19920. +
  19921. +CONFIG_KEXEC=y
  19922. +
  19923. +CONFIG_HWMON=y
  19924. +# CONFIG_HWMON_DEBUG_CHIP is not set
  19925. +CONFIG_THERMAL_HWMON=y
  19926. +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
  19927. +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
  19928. +CONFIG_THERMAL_GOV_FAIR_SHARE=y
  19929. +# CONFIG_THERMAL_GOV_USER_SPACE is not set
  19930. +CONFIG_THERMAL_GOV_STEP_WISE=y
  19931. +# CONFIG_THERMAL_EMULATION is not set
  19932. +
  19933. +CONFIG_INOTIFY=y
  19934. +CONFIG_INOTIFY_USER=y
  19935. +
  19936. +#
  19937. +# Bus devices
  19938. +#
  19939. +# CONFIG_OMAP_OCP2SCP is not set
  19940. +CONFIG_PROC_EVENTS=y
  19941. +
  19942. +CONFIG_IBMASR=m
  19943. +
  19944. +CONFIG_PM=y
  19945. +CONFIG_PM_STD_PARTITION=""
  19946. +# CONFIG_DPM_WATCHDOG is not set # revisit this in debug
  19947. +CONFIG_PM_TRACE=y
  19948. +CONFIG_PM_TRACE_RTC=y
  19949. +# CONFIG_PM_OPP is not set
  19950. +# CONFIG_PM_AUTOSLEEP is not set
  19951. +# CONFIG_PM_WAKELOCKS is not set
  19952. +CONFIG_HIBERNATION=y
  19953. +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
  19954. +CONFIG_SUSPEND=y
  19955. +
  19956. +CONFIG_CPU_FREQ_TABLE=y
  19957. +CONFIG_CPU_FREQ_STAT=m
  19958. +CONFIG_CPU_FREQ_STAT_DETAILS=y
  19959. +
  19960. +
  19961. +CONFIG_NET_VENDOR_SMC=y
  19962. +# CONFIG_IBMTR is not set
  19963. +# CONFIG_SKISA is not set
  19964. +# CONFIG_PROTEON is not set
  19965. +# CONFIG_SMCTR is not set
  19966. +
  19967. +# CONFIG_MOUSE_ATIXL is not set
  19968. +
  19969. +# CONFIG_MEDIA_PARPORT_SUPPORT is not set
  19970. +
  19971. +CONFIG_RADIO_TEA5764=m
  19972. +CONFIG_RADIO_SAA7706H=m
  19973. +CONFIG_RADIO_CADET=m
  19974. +CONFIG_RADIO_RTRACK=m
  19975. +CONFIG_RADIO_RTRACK2=m
  19976. +CONFIG_RADIO_AZTECH=m
  19977. +CONFIG_RADIO_GEMTEK=m
  19978. +CONFIG_RADIO_SF16FMI=m
  19979. +CONFIG_RADIO_SF16FMR2=m
  19980. +CONFIG_RADIO_TERRATEC=m
  19981. +CONFIG_RADIO_TRUST=m
  19982. +CONFIG_RADIO_TYPHOON=m
  19983. +CONFIG_RADIO_ZOLTRIX=m
  19984. +
  19985. +CONFIG_SND_DARLA20=m
  19986. +CONFIG_SND_GINA20=m
  19987. +CONFIG_SND_LAYLA20=m
  19988. +CONFIG_SND_DARLA24=m
  19989. +CONFIG_SND_GINA24=m
  19990. +CONFIG_SND_LAYLA24=m
  19991. +CONFIG_SND_MONA=m
  19992. +CONFIG_SND_MIA=m
  19993. +CONFIG_SND_ECHO3G=m
  19994. +CONFIG_SND_INDIGO=m
  19995. +CONFIG_SND_INDIGOIO=m
  19996. +CONFIG_SND_INDIGODJ=m
  19997. +CONFIG_SND_INDIGOIOX=m
  19998. +CONFIG_SND_INDIGODJX=m
  19999. +
  20000. +CONFIG_BALLOON_COMPACTION=y
  20001. +CONFIG_COMPACTION=y
  20002. +CONFIG_MIGRATION=y
  20003. +CONFIG_BOUNCE=y
  20004. +# CONFIG_LEDS_AMS_DELTA is not set
  20005. +# CONFIG_LEDS_LOCOMO is not set
  20006. +# CONFIG_LEDS_NET48XX is not set
  20007. +# CONFIG_LEDS_NET5501 is not set
  20008. +# CONFIG_LEDS_PCA9532 is not set
  20009. +# CONFIG_LEDS_PCA955X is not set
  20010. +# CONFIG_LEDS_BD2802 is not set
  20011. +# CONFIG_LEDS_S3C24XX is not set
  20012. +# CONFIG_LEDS_PCA9633 is not set
  20013. +CONFIG_LEDS_DELL_NETBOOKS=m
  20014. +# CONFIG_LEDS_TCA6507 is not set
  20015. +# CONFIG_LEDS_LM355x is not set
  20016. +# CONFIG_LEDS_OT200 is not set
  20017. +# CONFIG_LEDS_PWM is not set
  20018. +# CONFIG_LEDS_LP8501 is not set
  20019. +# CONFIG_LEDS_PCA963X is not set
  20020. +# CONFIG_LEDS_PCA9685 is not set
  20021. +CONFIG_LEDS_TRIGGER_TIMER=m
  20022. +CONFIG_LEDS_TRIGGER_ONESHOT=m
  20023. +CONFIG_LEDS_TRIGGER_IDE_DISK=y
  20024. +CONFIG_LEDS_TRIGGER_HEARTBEAT=m
  20025. +CONFIG_LEDS_TRIGGER_BACKLIGHT=m
  20026. +# CONFIG_LEDS_TRIGGER_CPU is not set
  20027. +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
  20028. +CONFIG_LEDS_TRIGGER_TRANSIENT=m
  20029. +CONFIG_LEDS_TRIGGER_CAMERA=m
  20030. +CONFIG_LEDS_ALIX2=m
  20031. +CONFIG_LEDS_CLEVO_MAIL=m
  20032. +CONFIG_LEDS_INTEL_SS4200=m
  20033. +CONFIG_LEDS_LM3530=m
  20034. +# CONFIG_LEDS_LM3642 is not set
  20035. +CONFIG_LEDS_LM3556=m
  20036. +CONFIG_LEDS_BLINKM=m
  20037. +CONFIG_LEDS_LP3944=m
  20038. +CONFIG_LEDS_LP5521=m
  20039. +CONFIG_LEDS_LP5523=m
  20040. +CONFIG_LEDS_LP5562=m
  20041. +CONFIG_LEDS_LT3593=m
  20042. +CONFIG_LEDS_REGULATOR=m
  20043. +CONFIG_LEDS_WM8350=m
  20044. +CONFIG_LEDS_WM831X_STATUS=m
  20045. +
  20046. +CONFIG_DMA_ENGINE=y
  20047. +CONFIG_DW_DMAC_CORE=m
  20048. +CONFIG_DW_DMAC=m
  20049. +CONFIG_DW_DMAC_PCI=m
  20050. +# CONFIG_DW_DMAC_BIG_ENDIAN_IO is not set
  20051. +# CONFIG_TIMB_DMA is not set
  20052. +# CONFIG_DMATEST is not set
  20053. +CONFIG_ASYNC_TX_DMA=y
  20054. +
  20055. +CONFIG_UNUSED_SYMBOLS=y
  20056. +
  20057. +CONFIG_UPROBE_EVENT=y
  20058. +
  20059. +CONFIG_DYNAMIC_FTRACE=y
  20060. +# CONFIG_IRQSOFF_TRACER is not set
  20061. +CONFIG_SCHED_TRACER=y
  20062. +CONFIG_CONTEXT_SWITCH_TRACER=y
  20063. +CONFIG_TRACER_SNAPSHOT=y
  20064. +# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
  20065. +CONFIG_FTRACE_SYSCALLS=y
  20066. +CONFIG_FTRACE_MCOUNT_RECORD=y
  20067. +# CONFIG_FTRACE_STARTUP_TEST is not set
  20068. +# CONFIG_TRACE_BRANCH_PROFILING is not set
  20069. +CONFIG_FUNCTION_PROFILER=y
  20070. +CONFIG_RING_BUFFER_BENCHMARK=m
  20071. +# CONFIG_RING_BUFFER_STARTUP_TEST is not set
  20072. +# CONFIG_RBTREE_TEST is not set
  20073. +# CONFIG_INTERVAL_TREE_TEST is not set
  20074. +CONFIG_FUNCTION_TRACER=y
  20075. +CONFIG_STACK_TRACER=y
  20076. +# CONFIG_FUNCTION_GRAPH_TRACER is not set
  20077. +
  20078. +CONFIG_KPROBES=y
  20079. +CONFIG_KPROBE_EVENT=y
  20080. +# CONFIG_KPROBES_SANITY_TEST is not set
  20081. +CONFIG_JUMP_LABEL=y
  20082. +CONFIG_OPTPROBES=y
  20083. +
  20084. +CONFIG_HZ_1000=y
  20085. +
  20086. +CONFIG_TIMER_STATS=y
  20087. +CONFIG_PERF_COUNTERS=y
  20088. +
  20089. +# Auxillary displays
  20090. +CONFIG_KS0108=m
  20091. +CONFIG_KS0108_PORT=0x378
  20092. +CONFIG_KS0108_DELAY=2
  20093. +CONFIG_CFAG12864B=y
  20094. +CONFIG_CFAG12864B_RATE=20
  20095. +
  20096. +# CONFIG_PHANTOM is not set
  20097. +
  20098. +# CONFIG_POWER_SUPPLY_DEBUG is not set
  20099. +
  20100. +# CONFIG_TEST_POWER is not set
  20101. +CONFIG_APM_POWER=m
  20102. +# CONFIG_GENERIC_ADC_BATTERY is not set
  20103. +# CONFIG_WM831X_POWER is not set
  20104. +
  20105. +# CONFIG_BATTERY_DS2760 is not set
  20106. +# CONFIG_BATTERY_DS2781 is not set
  20107. +# CONFIG_BATTERY_DS2782 is not set
  20108. +# CONFIG_BATTERY_SBS is not set
  20109. +# CONFIG_BATTERY_BQ20Z75 is not set
  20110. +# CONFIG_BATTERY_DS2780 is not set
  20111. +# CONFIG_BATTERY_BQ27x00 is not set
  20112. +# CONFIG_BATTERY_MAX17040 is not set
  20113. +# CONFIG_BATTERY_MAX17042 is not set
  20114. +# CONFIG_BATTERY_GOLDFISH is not set
  20115. +
  20116. +# CONFIG_CHARGER_ISP1704 is not set
  20117. +# CONFIG_CHARGER_MAX8903 is not set
  20118. +# CONFIG_CHARGER_LP8727 is not set
  20119. +# CONFIG_CHARGER_GPIO is not set
  20120. +# CONFIG_CHARGER_PCF50633 is not set
  20121. +# CONFIG_CHARGER_BQ2415X is not set
  20122. +# CONFIG_CHARGER_BQ24190 is not set
  20123. +# CONFIG_CHARGER_BQ24735 is not set
  20124. +CONFIG_POWER_RESET=y
  20125. +
  20126. +# CONFIG_PDA_POWER is not set
  20127. +
  20128. +CONFIG_AUXDISPLAY=y
  20129. +
  20130. +CONFIG_UIO=m
  20131. +CONFIG_UIO_CIF=m
  20132. +# CONFIG_UIO_PDRV is not set
  20133. +# CONFIG_UIO_PDRV_GENIRQ is not set
  20134. +# CONFIG_UIO_DMEM_GENIRQ is not set
  20135. +CONFIG_UIO_AEC=m
  20136. +CONFIG_UIO_SERCOS3=m
  20137. +CONFIG_UIO_PCI_GENERIC=m
  20138. +# CONFIG_UIO_NETX is not set
  20139. +# CONFIG_UIO_MF624 is not set
  20140. +
  20141. +CONFIG_VFIO=m
  20142. +CONFIG_VFIO_IOMMU_TYPE1=m
  20143. +CONFIG_VFIO_PCI=m
  20144. +
  20145. +
  20146. +# LIRC
  20147. +CONFIG_LIRC_STAGING=y
  20148. +CONFIG_LIRC_BT829=m
  20149. +CONFIG_LIRC_IGORPLUGUSB=m
  20150. +CONFIG_LIRC_IMON=m
  20151. +CONFIG_LIRC_ZILOG=m
  20152. +CONFIG_LIRC_PARALLEL=m
  20153. +CONFIG_LIRC_SERIAL=m
  20154. +CONFIG_LIRC_SERIAL_TRANSMITTER=y
  20155. +CONFIG_LIRC_SASEM=m
  20156. +CONFIG_LIRC_SIR=m
  20157. +CONFIG_LIRC_TTUSBIR=m
  20158. +
  20159. +# CONFIG_SAMPLES is not set
  20160. +
  20161. +
  20162. +CONFIG_NOZOMI=m
  20163. +# CONFIG_TPS65010 is not set
  20164. +
  20165. +CONFIG_INPUT_APANEL=m
  20166. +CONFIG_INPUT_GP2A=m
  20167. +# CONFIG_INPUT_GPIO_TILT_POLLED is not set
  20168. +# CONFIG_INPUT_GPIO_BEEPER is not set
  20169. +
  20170. +# CONFIG_INTEL_MENLOW is not set
  20171. +CONFIG_ENCLOSURE_SERVICES=m
  20172. +CONFIG_IPWIRELESS=m
  20173. +
  20174. +# CONFIG_BLK_DEV_XIP is not set
  20175. +CONFIG_MEMSTICK=m
  20176. +# CONFIG_MEMSTICK_DEBUG is not set
  20177. +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
  20178. +CONFIG_MSPRO_BLOCK=m
  20179. +# CONFIG_MS_BLOCK is not set
  20180. +CONFIG_MEMSTICK_TIFM_MS=m
  20181. +CONFIG_MEMSTICK_JMICRON_38X=m
  20182. +CONFIG_MEMSTICK_R592=m
  20183. +CONFIG_MEMSTICK_REALTEK_PCI=m
  20184. +
  20185. +CONFIG_ACCESSIBILITY=y
  20186. +CONFIG_A11Y_BRAILLE_CONSOLE=y
  20187. +
  20188. +# CONFIG_HTC_PASIC3 is not set
  20189. +
  20190. +# MT9V022_PCA9536_SWITCH is not set
  20191. +
  20192. +CONFIG_OPTIMIZE_INLINING=y
  20193. +
  20194. +# FIXME: This should be x86/ia64 only
  20195. +# CONFIG_HP_ILO is not set
  20196. +
  20197. +CONFIG_GPIOLIB=y
  20198. +# CONFIG_PINCTRL is not set
  20199. +# CONFIG_DEBUG_PINCTRL is not set
  20200. +# CONFIG_PINMUX is not set
  20201. +# CONFIG_PINCONF is not set
  20202. +
  20203. +CONFIG_NET_DSA=m
  20204. +CONFIG_NET_DSA_MV88E6060=m
  20205. +CONFIG_NET_DSA_MV88E6131=m
  20206. +CONFIG_NET_DSA_MV88E6123_61_65=m
  20207. +
  20208. +# Used by Maemo, we don't care.
  20209. +# CONFIG_PHONET is not set
  20210. +
  20211. +# CONFIG_ICS932S401 is not set
  20212. +# CONFIG_ATMEL_SSC is not set
  20213. +
  20214. +# CONFIG_C2PORT is not set
  20215. +
  20216. +# CONFIG_REGULATOR_DEBUG is not set
  20217. +
  20218. +CONFIG_WM8350_POWER=m
  20219. +
  20220. +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
  20221. +
  20222. +CONFIG_USB_WUSB=m
  20223. +CONFIG_USB_WUSB_CBAF=m
  20224. +# CONFIG_USB_WUSB_CBAF_DEBUG is not set
  20225. +CONFIG_USB_WHCI_HCD=m
  20226. +CONFIG_USB_HWA_HCD=m
  20227. +# CONFIG_USB_HCD_BCMA is not set
  20228. +# CONFIG_USB_HCD_SSB is not set
  20229. +
  20230. +CONFIG_UWB=m
  20231. +CONFIG_UWB_HWA=m
  20232. +CONFIG_UWB_WHCI=m
  20233. +CONFIG_UWB_I1480U=m
  20234. +
  20235. +# CONFIG_ANDROID is not set
  20236. +CONFIG_STAGING_MEDIA=y
  20237. +# CONFIG_DVB_AS102 is not set
  20238. +# CONFIG_ET131X is not set
  20239. +# CONFIG_SLICOSS is not set
  20240. +# CONFIG_WLAGS49_H2 is not set
  20241. +# CONFIG_WLAGS49_H25 is not set
  20242. +# CONFIG_VIDEO_DT3155 is not set
  20243. +# CONFIG_TI_ST is not set
  20244. +# CONFIG_FB_XGI is not set
  20245. +# CONFIG_VIDEO_GO7007 is not set
  20246. +# CONFIG_I2C_BCM2048 is not set
  20247. +# CONFIG_VIDEO_TCM825X is not set
  20248. +# CONFIG_VIDEO_OMAP4 is not set
  20249. +# CONFIG_USB_MSI3101 is not set
  20250. +# CONFIG_DT3155 is not set
  20251. +# CONFIG_W35UND is not set
  20252. +# CONFIG_PRISM2_USB is not set
  20253. +# CONFIG_ECHO is not set
  20254. +CONFIG_USB_ATMEL=m
  20255. +# CONFIG_COMEDI is not set
  20256. +# CONFIG_ASUS_OLED is not set
  20257. +# CONFIG_PANEL is not set
  20258. +# CONFIG_TRANZPORT is not set
  20259. +# CONFIG_POHMELFS is not set
  20260. +# CONFIG_IDE_PHISON is not set
  20261. +# CONFIG_LINE6_USB is not set
  20262. +# CONFIG_VME_BUS is not set
  20263. +# CONFIG_RAR_REGISTER is not set
  20264. +# CONFIG_VT6656 is not set
  20265. +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
  20266. +# Larry Finger maintains these (rhbz 913753)
  20267. +CONFIG_RTLLIB=m
  20268. +CONFIG_RTLLIB_CRYPTO_CCMP=m
  20269. +CONFIG_RTLLIB_CRYPTO_TKIP=m
  20270. +CONFIG_RTLLIB_CRYPTO_WEP=m
  20271. +CONFIG_RTL8192E=m
  20272. +# CONFIG_INPUT_GPIO is not set
  20273. +# CONFIG_VIDEO_CX25821 is not set
  20274. +# CONFIG_R8187SE is not set
  20275. +# CONFIG_R8188EU is not set
  20276. +# CONFIG_R8821AE is not set
  20277. +# CONFIG_RTL8192U is not set
  20278. +# CONFIG_FB_SM7XX is not set
  20279. +# CONFIG_SPECTRA is not set
  20280. +# CONFIG_EASYCAP is not set
  20281. +# CONFIG_SOLO6X10 is not set
  20282. +# CONFIG_ACPI_QUICKSTART is not set
  20283. +# CONFIG_LTE_GDM724X is not set
  20284. +CONFIG_R8712U=m # Larry Finger maintains this (rhbz 699618)
  20285. +# CONFIG_R8712_AP is not set
  20286. +# CONFIG_ATH6K_LEGACY is not set
  20287. +# CONFIG_USB_ENESTORAGE is not set
  20288. +# CONFIG_BCM_WIMAX is not set
  20289. +# CONFIG_USB_BTMTK is not set
  20290. +# CONFIG_FT1000 is not set
  20291. +# CONFIG_SPEAKUP is not set
  20292. +# CONFIG_DX_SEP is not set
  20293. +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
  20294. +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
  20295. +# CONFIG_RTS_PSTOR is not set
  20296. +CONFIG_ALTERA_STAPL=m
  20297. +# CONFIG_DVB_CXD2099 is not set
  20298. +# CONFIG_USBIP_CORE is not set
  20299. +# CONFIG_INTEL_MEI is not set
  20300. +# CONFIG_ZCACHE is not set
  20301. +# CONFIG_RTS5139 is not set
  20302. +# CONFIG_NVEC_LEDS is not set
  20303. +# CONFIG_VT6655 is not set
  20304. +# CONFIG_RAMSTER is not set
  20305. +# CONFIG_USB_WPAN_HCD is not set
  20306. +# CONFIG_WIMAX_GDM72XX is not set
  20307. +# CONFIG_IPACK_BUS is not set
  20308. +# CONFIG_CSR_WIFI is not set
  20309. +# CONFIG_ZCACHE2 is not set
  20310. +# CONFIG_NET_VENDOR_SILICOM is not set
  20311. +# CONFIG_SBYPASS is not set
  20312. +# CONFIG_BPCTL is not set
  20313. +# CONFIG_CED1401 is not set
  20314. +# CONFIG_DGRP is not set
  20315. +# CONFIG_SB105X is not set
  20316. +# CONFIG_LUSTRE_FS is not set
  20317. +# CONFIG_XILLYBUS is not set
  20318. +# CONFIG_DGAP is not set
  20319. +# CONFIG_DGNC is not set
  20320. +# CONFIG_RTS5208 is not set
  20321. +# END OF STAGING
  20322. +
  20323. +#
  20324. +# Remoteproc drivers (EXPERIMENTAL)
  20325. +#
  20326. +# CONFIG_STE_MODEM_RPROC is not set
  20327. +
  20328. +CONFIG_LIBFC=m
  20329. +CONFIG_LIBFCOE=m
  20330. +CONFIG_FCOE=m
  20331. +CONFIG_FCOE_FNIC=m
  20332. +
  20333. +
  20334. +# CONFIG_IMA is not set
  20335. +CONFIG_IMA_MEASURE_PCR_IDX=10
  20336. +CONFIG_IMA_AUDIT=y
  20337. +CONFIG_IMA_LSM_RULES=y
  20338. +
  20339. +# CONFIG_EVM is not set
  20340. +# CONFIG_PWM_PCA9685 is not set
  20341. +
  20342. +CONFIG_LSM_MMAP_MIN_ADDR=65536
  20343. +
  20344. +CONFIG_STRIP_ASM_SYMS=y
  20345. +
  20346. +# CONFIG_RCU_FANOUT_EXACT is not set
  20347. +# FIXME: Revisit FAST_NO_HZ after it's fixed
  20348. +# CONFIG_RCU_FAST_NO_HZ is not set
  20349. +# CONFIG_RCU_NOCB_CPU is not set
  20350. +CONFIG_RCU_CPU_STALL_TIMEOUT=60
  20351. +# CONFIG_RCU_TORTURE_TEST is not set
  20352. +# CONFIG_RCU_TRACE is not set
  20353. +# CONFIG_RCU_CPU_STALL_INFO is not set
  20354. +# CONFIG_RCU_USER_QS is not set
  20355. +
  20356. +CONFIG_KSM=y
  20357. +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  20358. +
  20359. +CONFIG_FSNOTIFY=y
  20360. +CONFIG_FANOTIFY=y
  20361. +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
  20362. +
  20363. +CONFIG_IEEE802154=m
  20364. +CONFIG_IEEE802154_6LOWPAN=m
  20365. +CONFIG_IEEE802154_DRIVERS=m
  20366. +CONFIG_IEEE802154_FAKEHARD=m
  20367. +CONFIG_IEEE802154_FAKELB=m
  20368. +
  20369. +CONFIG_MAC802154=m
  20370. +CONFIG_NET_MPLS_GSO=m
  20371. +
  20372. +# CONFIG_HSR is not set
  20373. +
  20374. +# CONFIG_EXTCON is not set
  20375. +# CONFIG_EXTCON_ADC_JACK is not set
  20376. +# CONFIG_MEMORY is not set
  20377. +
  20378. +CONFIG_PPS=m
  20379. +# CONFIG_PPS_CLIENT_KTIMER is not set
  20380. +CONFIG_PPS_CLIENT_LDISC=m
  20381. +# CONFIG_PPS_DEBUG is not set
  20382. +CONFIG_PPS_CLIENT_PARPORT=m
  20383. +CONFIG_PPS_GENERATOR_PARPORT=m
  20384. +CONFIG_PPS_CLIENT_GPIO=m
  20385. +CONFIG_NTP_PPS=y
  20386. +
  20387. +CONFIG_PTP_1588_CLOCK=m
  20388. +CONFIG_PTP_1588_CLOCK_PCH=m
  20389. +
  20390. +CONFIG_CLEANCACHE=y
  20391. +CONFIG_FRONTSWAP=y
  20392. +CONFIG_ZSWAP=y
  20393. +CONFIG_ZSMALLOC=y
  20394. +# CONFIG_PGTABLE_MAPPING is not set
  20395. +
  20396. +# CONFIG_MDIO_GPIO is not set
  20397. +# CONFIG_KEYBOARD_GPIO_POLLED is not set
  20398. +# CONFIG_MOUSE_GPIO is not set
  20399. +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
  20400. +# CONFIG_I2C_DESIGNWARE_PCI is not set
  20401. +# CONFIG_I2C_GPIO is not set
  20402. +# CONFIG_DEBUG_GPIO is not set
  20403. +# CONFIG_GPIO_GENERIC_PLATFORM is not set
  20404. +# CONFIG_GPIO_CS5535 is not set
  20405. +# CONFIG_GPIO_IT8761E is not set
  20406. +# CONFIG SB105x is not set
  20407. +# CONFIG_GPIO_TS5500 is not set
  20408. +CONFIG_GPIO_VIPERBOARD=m
  20409. +# CONFIG_UCB1400_CORE is not set
  20410. +# CONFIG_TPS6105X is not set
  20411. +# CONFIG_RADIO_MIROPCM20 is not set
  20412. +# CONFIG_USB_GPIO_VBUS is not set
  20413. +# CONFIG_GPIO_SCH is not set
  20414. +# CONFIG_GPIO_LANGWELL is not set
  20415. +# CONFIG_GPIO_RDC321X is not set
  20416. +# CONFIG_GPIO_VX855 is not set
  20417. +# CONFIG_GPIO_PCH is not set
  20418. +# CONFIG_GPIO_ML_IOH is not set
  20419. +# CONFIG_GPIO_AMD8111 is not set
  20420. +# CONFIG_GPIO_BT8XX is not set
  20421. +# CONFIG_GPIO_GRGPIO is not set
  20422. +# CONFIG_GPIO_PL061 is not set
  20423. +# CONFIG_GPIO_BCM_KONA is not set
  20424. +# CONFIG_GPIO_SCH311X is not set
  20425. +CONFIG_GPIO_MAX730X=m
  20426. +CONFIG_GPIO_MAX7300=m
  20427. +CONFIG_GPIO_MAX732X=m
  20428. +CONFIG_GPIO_PCF857X=m
  20429. +CONFIG_GPIO_SX150X=y
  20430. +CONFIG_GPIO_ADP5588=m
  20431. +CONFIG_GPIO_ADNP=m
  20432. +CONFIG_GPIO_MAX7301=m
  20433. +CONFIG_GPIO_MCP23S08=m
  20434. +CONFIG_GPIO_MC33880=m
  20435. +CONFIG_GPIO_74X164=m
  20436. +
  20437. +# FIXME: Why?
  20438. +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
  20439. +
  20440. +CONFIG_TEST_KSTRTOX=y
  20441. +CONFIG_XZ_DEC=y
  20442. +CONFIG_XZ_DEC_X86=y
  20443. +CONFIG_XZ_DEC_POWERPC=y
  20444. +# CONFIG_XZ_DEC_IA64 is not set
  20445. +CONFIG_XZ_DEC_ARM=y
  20446. +# CONFIG_XZ_DEC_ARMTHUMB is not set
  20447. +# CONFIG_XZ_DEC_SPARC is not set
  20448. +# CONFIG_XZ_DEC_TEST is not set
  20449. +
  20450. +# CONFIG_POWER_AVS is not set
  20451. +
  20452. +CONFIG_TARGET_CORE=m
  20453. +CONFIG_ISCSI_TARGET=m
  20454. +CONFIG_LOOPBACK_TARGET=m
  20455. +CONFIG_SBP_TARGET=m
  20456. +CONFIG_TCM_IBLOCK=m
  20457. +CONFIG_TCM_FILEIO=m
  20458. +CONFIG_TCM_PSCSI=m
  20459. +CONFIG_TCM_FC=m
  20460. +
  20461. +CONFIG_HWSPINLOCK=m
  20462. +
  20463. +CONFIG_PSTORE=y
  20464. +CONFIG_PSTORE_RAM=m
  20465. +# CONFIG_PSTORE_CONSOLE is not set
  20466. +# CONFIG_PSTORE_FTRACE is not set
  20467. +
  20468. +# CONFIG_TEST_MODULE is not set
  20469. +# CONFIG_TEST_USER_COPY is not set
  20470. +
  20471. +# CONFIG_AVERAGE is not set
  20472. +# CONFIG_VMXNET3 is not set
  20473. +
  20474. +# CONFIG_SIGMA is not set
  20475. +
  20476. +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
  20477. +
  20478. +CONFIG_BCMA=m
  20479. +CONFIG_BCMA_BLOCKIO=y
  20480. +CONFIG_BCMA_HOST_PCI_POSSIBLE=y
  20481. +CONFIG_BCMA_HOST_PCI=y
  20482. +# CONFIG_BCMA_HOST_SOC is not set
  20483. +CONFIG_BCMA_DRIVER_GMAC_CMN=y
  20484. +CONFIG_BCMA_DRIVER_GPIO=y
  20485. +# CONFIG_BCMA_DEBUG is not set
  20486. +
  20487. +# CONFIG_GOOGLE_FIRMWARE is not set
  20488. +# CONFIG_INTEL_MID_PTI is not set
  20489. +
  20490. +# CONFIG_MAILBOX is not set
  20491. +
  20492. +CONFIG_FMC=m
  20493. +CONFIG_FMC_FAKEDEV=m
  20494. +CONFIG_FMC_TRIVIAL=m
  20495. +CONFIG_FMC_WRITE_EEPROM=m
  20496. +CONFIG_FMC_CHARDEV=m
  20497. +
  20498. +# CONFIG_GENWQE is not set
  20499. +
  20500. +# CONFIG_POWERCAP is not set
  20501. +
  20502. +# CONFIG_HSI is not set
  20503. +
  20504. +
  20505. +# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
  20506. +
  20507. +# CONFIG_PM_DEVFREQ is not set
  20508. +# CONFIG_MODULE_SIG is not set
  20509. +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
  20510. +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
  20511. +# CONFIG_MODULE_VERIFY_ELF is not set
  20512. +# CONFIG_CRYPTO_KEY_TYPE is not set
  20513. +# CONFIG_PGP_LIBRARY is not set
  20514. +# CONFIG_PGP_PRELOAD is not set
  20515. +# CONFIG_LOCALVERSION_AUTO is not set
  20516. +CONFIG_PROC_DEVICETREE=y
  20517. +
  20518. diff -Nur linux-3.14.17/arch/arm/configs/imx_v7_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_defconfig
  20519. --- linux-3.14.17/arch/arm/configs/imx_v7_defconfig 1970-01-01 01:00:00.000000000 +0100
  20520. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_defconfig 2014-09-11 18:05:52.798001191 +0200
  20521. @@ -0,0 +1,343 @@
  20522. +# CONFIG_LOCALVERSION_AUTO is not set
  20523. +CONFIG_KERNEL_LZO=y
  20524. +CONFIG_SYSVIPC=y
  20525. +CONFIG_NO_HZ=y
  20526. +CONFIG_HIGH_RES_TIMERS=y
  20527. +CONFIG_LOG_BUF_SHIFT=18
  20528. +CONFIG_CGROUPS=y
  20529. +CONFIG_RELAY=y
  20530. +CONFIG_BLK_DEV_INITRD=y
  20531. +CONFIG_EXPERT=y
  20532. +CONFIG_PERF_EVENTS=y
  20533. +# CONFIG_SLUB_DEBUG is not set
  20534. +# CONFIG_COMPAT_BRK is not set
  20535. +CONFIG_MODULES=y
  20536. +CONFIG_MODULE_UNLOAD=y
  20537. +CONFIG_MODVERSIONS=y
  20538. +CONFIG_MODULE_SRCVERSION_ALL=y
  20539. +# CONFIG_BLK_DEV_BSG is not set
  20540. +CONFIG_GPIO_PCA953X=y
  20541. +CONFIG_ARCH_MXC=y
  20542. +CONFIG_MXC_DEBUG_BOARD=y
  20543. +CONFIG_MACH_IMX51_DT=y
  20544. +CONFIG_MACH_EUKREA_CPUIMX51SD=y
  20545. +CONFIG_SOC_IMX53=y
  20546. +CONFIG_SOC_IMX6Q=y
  20547. +CONFIG_SOC_IMX6SL=y
  20548. +CONFIG_SOC_VF610=y
  20549. +# CONFIG_SWP_EMULATE is not set
  20550. +CONFIG_SMP=y
  20551. +CONFIG_VMSPLIT_2G=y
  20552. +CONFIG_PREEMPT=y
  20553. +CONFIG_AEABI=y
  20554. +# CONFIG_OABI_COMPAT is not set
  20555. +CONFIG_HIGHMEM=y
  20556. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  20557. +CONFIG_CPU_FREQ=y
  20558. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  20559. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  20560. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  20561. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  20562. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  20563. +CONFIG_ARM_IMX6_CPUFREQ=y
  20564. +CONFIG_CPU_IDLE=y
  20565. +CONFIG_VFP=y
  20566. +CONFIG_NEON=y
  20567. +CONFIG_BINFMT_MISC=m
  20568. +CONFIG_PM_RUNTIME=y
  20569. +CONFIG_PM_DEBUG=y
  20570. +CONFIG_PM_TEST_SUSPEND=y
  20571. +CONFIG_NET=y
  20572. +CONFIG_PACKET=y
  20573. +CONFIG_UNIX=y
  20574. +CONFIG_INET=y
  20575. +CONFIG_IP_PNP=y
  20576. +CONFIG_IP_PNP_DHCP=y
  20577. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  20578. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  20579. +# CONFIG_INET_XFRM_MODE_BEET is not set
  20580. +# CONFIG_INET_LRO is not set
  20581. +CONFIG_IPV6=y
  20582. +CONFIG_NETFILTER=y
  20583. +CONFIG_VLAN_8021Q=y
  20584. +# CONFIG_WIRELESS is not set
  20585. +CONFIG_DEVTMPFS=y
  20586. +CONFIG_DEVTMPFS_MOUNT=y
  20587. +# CONFIG_STANDALONE is not set
  20588. +CONFIG_CMA=y
  20589. +CONFIG_CMA_SIZE_MBYTES=320
  20590. +CONFIG_IMX_WEIM=y
  20591. +CONFIG_CONNECTOR=y
  20592. +CONFIG_MTD=y
  20593. +CONFIG_MTD_CMDLINE_PARTS=y
  20594. +CONFIG_MTD_BLOCK=y
  20595. +CONFIG_MTD_CFI=y
  20596. +CONFIG_MTD_JEDECPROBE=y
  20597. +CONFIG_MTD_CFI_INTELEXT=y
  20598. +CONFIG_MTD_CFI_AMDSTD=y
  20599. +CONFIG_MTD_CFI_STAA=y
  20600. +CONFIG_MTD_PHYSMAP_OF=y
  20601. +CONFIG_MTD_DATAFLASH=y
  20602. +CONFIG_MTD_M25P80=y
  20603. +CONFIG_MTD_SST25L=y
  20604. +CONFIG_MTD_NAND=y
  20605. +CONFIG_MTD_NAND_GPMI_NAND=y
  20606. +CONFIG_MTD_NAND_MXC=y
  20607. +CONFIG_MTD_UBI=y
  20608. +CONFIG_BLK_DEV_LOOP=y
  20609. +CONFIG_BLK_DEV_RAM=y
  20610. +CONFIG_BLK_DEV_RAM_SIZE=65536
  20611. +CONFIG_EEPROM_AT24=y
  20612. +CONFIG_EEPROM_AT25=y
  20613. +# CONFIG_SCSI_PROC_FS is not set
  20614. +CONFIG_BLK_DEV_SD=y
  20615. +CONFIG_SCSI_MULTI_LUN=y
  20616. +CONFIG_SCSI_CONSTANTS=y
  20617. +CONFIG_SCSI_LOGGING=y
  20618. +CONFIG_SCSI_SCAN_ASYNC=y
  20619. +# CONFIG_SCSI_LOWLEVEL is not set
  20620. +CONFIG_ATA=y
  20621. +CONFIG_SATA_AHCI_PLATFORM=y
  20622. +CONFIG_AHCI_IMX=y
  20623. +CONFIG_PATA_IMX=y
  20624. +CONFIG_NETDEVICES=y
  20625. +# CONFIG_NET_VENDOR_BROADCOM is not set
  20626. +CONFIG_CS89x0=y
  20627. +CONFIG_CS89x0_PLATFORM=y
  20628. +# CONFIG_NET_VENDOR_FARADAY is not set
  20629. +# CONFIG_NET_VENDOR_INTEL is not set
  20630. +# CONFIG_NET_VENDOR_MARVELL is not set
  20631. +# CONFIG_NET_VENDOR_MICREL is not set
  20632. +# CONFIG_NET_VENDOR_MICROCHIP is not set
  20633. +# CONFIG_NET_VENDOR_NATSEMI is not set
  20634. +# CONFIG_NET_VENDOR_SEEQ is not set
  20635. +CONFIG_SMC91X=y
  20636. +CONFIG_SMC911X=y
  20637. +CONFIG_SMSC911X=y
  20638. +# CONFIG_NET_VENDOR_STMICRO is not set
  20639. +# CONFIG_WLAN is not set
  20640. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  20641. +CONFIG_INPUT_EVDEV=y
  20642. +CONFIG_INPUT_EVBUG=m
  20643. +CONFIG_KEYBOARD_GPIO=y
  20644. +CONFIG_KEYBOARD_IMX=y
  20645. +CONFIG_MOUSE_PS2=m
  20646. +CONFIG_MOUSE_PS2_ELANTECH=y
  20647. +CONFIG_INPUT_TOUCHSCREEN=y
  20648. +CONFIG_TOUCHSCREEN_EGALAX=y
  20649. +CONFIG_TOUCHSCREEN_EGALAX_SINGLE_TOUCH=y
  20650. +CONFIG_TOUCHSCREEN_MAX11801=y
  20651. +CONFIG_TOUCHSCREEN_MC13783=y
  20652. +CONFIG_INPUT_MISC=y
  20653. +CONFIG_INPUT_MMA8450=y
  20654. +CONFIG_INPUT_ISL29023=y
  20655. +CONFIG_SERIO_SERPORT=m
  20656. +CONFIG_VT_HW_CONSOLE_BINDING=y
  20657. +# CONFIG_LEGACY_PTYS is not set
  20658. +# CONFIG_DEVKMEM is not set
  20659. +CONFIG_SERIAL_IMX=y
  20660. +CONFIG_SERIAL_IMX_CONSOLE=y
  20661. +CONFIG_SERIAL_FSL_LPUART=y
  20662. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  20663. +CONFIG_FSL_OTP=y
  20664. +# CONFIG_I2C_COMPAT is not set
  20665. +CONFIG_I2C_CHARDEV=y
  20666. +# CONFIG_I2C_HELPER_AUTO is not set
  20667. +CONFIG_I2C_ALGOPCF=m
  20668. +CONFIG_I2C_ALGOPCA=m
  20669. +CONFIG_I2C_IMX=y
  20670. +CONFIG_SPI=y
  20671. +CONFIG_SPI_IMX=y
  20672. +CONFIG_GPIO_SYSFS=y
  20673. +CONFIG_POWER_SUPPLY=y
  20674. +CONFIG_SABRESD_MAX8903=y
  20675. +CONFIG_IMX6_USB_CHARGER=y
  20676. +CONFIG_SENSORS_MAG3110=y
  20677. +CONFIG_THERMAL=y
  20678. +CONFIG_CPU_THERMAL=y
  20679. +CONFIG_IMX_THERMAL=y
  20680. +CONFIG_DEVICE_THERMAL=y
  20681. +CONFIG_WATCHDOG=y
  20682. +CONFIG_IMX2_WDT=y
  20683. +CONFIG_MFD_DA9052_I2C=y
  20684. +CONFIG_MFD_MC13XXX_SPI=y
  20685. +CONFIG_MFD_MC13XXX_I2C=y
  20686. +CONFIG_MFD_SI476X_CORE=y
  20687. +CONFIG_REGULATOR=y
  20688. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  20689. +CONFIG_REGULATOR_DA9052=y
  20690. +CONFIG_REGULATOR_ANATOP=y
  20691. +CONFIG_REGULATOR_MC13783=y
  20692. +CONFIG_REGULATOR_MC13892=y
  20693. +CONFIG_REGULATOR_PFUZE100=y
  20694. +CONFIG_MEDIA_SUPPORT=y
  20695. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  20696. +CONFIG_MEDIA_RADIO_SUPPORT=y
  20697. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  20698. +CONFIG_MEDIA_USB_SUPPORT=y
  20699. +CONFIG_USB_VIDEO_CLASS=m
  20700. +CONFIG_V4L_PLATFORM_DRIVERS=y
  20701. +CONFIG_VIDEO_MXC_OUTPUT=y
  20702. +CONFIG_VIDEO_MXC_CAPTURE=m
  20703. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  20704. +CONFIG_MXC_CAMERA_OV5640=m
  20705. +CONFIG_MXC_CAMERA_OV5642=m
  20706. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  20707. +CONFIG_MXC_TVIN_ADV7180=m
  20708. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  20709. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  20710. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  20711. +CONFIG_SOC_CAMERA=y
  20712. +CONFIG_VIDEO_MX3=y
  20713. +CONFIG_RADIO_SI476X=y
  20714. +CONFIG_SOC_CAMERA_OV2640=y
  20715. +CONFIG_DRM=y
  20716. +CONFIG_DRM_VIVANTE=y
  20717. +CONFIG_FB=y
  20718. +CONFIG_FB_MXS=y
  20719. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  20720. +CONFIG_LCD_CLASS_DEVICE=y
  20721. +CONFIG_LCD_L4F00242T03=y
  20722. +CONFIG_LCD_PLATFORM=y
  20723. +CONFIG_BACKLIGHT_CLASS_DEVICE=y
  20724. +CONFIG_BACKLIGHT_PWM=y
  20725. +CONFIG_FB_MXC_SYNC_PANEL=y
  20726. +CONFIG_FB_MXC_LDB=y
  20727. +CONFIG_FB_MXC_MIPI_DSI=y
  20728. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  20729. +CONFIG_FB_MXC_HDMI=y
  20730. +CONFIG_FRAMEBUFFER_CONSOLE=y
  20731. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  20732. +CONFIG_FONTS=y
  20733. +CONFIG_FONT_8x8=y
  20734. +CONFIG_FONT_8x16=y
  20735. +CONFIG_LOGO=y
  20736. +CONFIG_SOUND=y
  20737. +CONFIG_SND=y
  20738. +CONFIG_SND_USB_AUDIO=m
  20739. +CONFIG_SND_SOC=y
  20740. +CONFIG_SND_IMX_SOC=y
  20741. +CONFIG_SND_SOC_EUKREA_TLV320=y
  20742. +CONFIG_SND_SOC_IMX_CS42888=y
  20743. +CONFIG_SND_SOC_IMX_WM8962=y
  20744. +CONFIG_SND_SOC_IMX_SGTL5000=y
  20745. +CONFIG_SND_SOC_IMX_SPDIF=y
  20746. +CONFIG_SND_SOC_IMX_MC13783=y
  20747. +CONFIG_SND_SOC_IMX_HDMI=y
  20748. +CONFIG_SND_SOC_IMX_SI476X=y
  20749. +CONFIG_USB=y
  20750. +CONFIG_USB_EHCI_HCD=y
  20751. +CONFIG_USB_STORAGE=y
  20752. +CONFIG_USB_CHIPIDEA=y
  20753. +CONFIG_USB_CHIPIDEA_UDC=y
  20754. +CONFIG_USB_CHIPIDEA_HOST=y
  20755. +CONFIG_USB_PHY=y
  20756. +CONFIG_NOP_USB_XCEIV=y
  20757. +CONFIG_USB_MXS_PHY=y
  20758. +CONFIG_USB_GADGET=y
  20759. +CONFIG_USB_ZERO=m
  20760. +CONFIG_USB_ETH=m
  20761. +CONFIG_USB_MASS_STORAGE=m
  20762. +CONFIG_USB_G_SERIAL=m
  20763. +CONFIG_MMC=y
  20764. +CONFIG_MMC_UNSAFE_RESUME=y
  20765. +CONFIG_MMC_SDHCI=y
  20766. +CONFIG_MMC_SDHCI_PLTFM=y
  20767. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  20768. +CONFIG_MXC_IPU=y
  20769. +CONFIG_MXC_GPU_VIV=y
  20770. +CONFIG_MXC_ASRC=y
  20771. +CONFIG_MXC_MIPI_CSI2=y
  20772. +CONFIG_MXC_MLB150=m
  20773. +CONFIG_NEW_LEDS=y
  20774. +CONFIG_LEDS_CLASS=y
  20775. +CONFIG_LEDS_GPIO=y
  20776. +CONFIG_LEDS_TRIGGERS=y
  20777. +CONFIG_LEDS_TRIGGER_GPIO=y
  20778. +CONFIG_RTC_CLASS=y
  20779. +CONFIG_RTC_INTF_DEV_UIE_EMUL=y
  20780. +CONFIG_RTC_DRV_MC13XXX=y
  20781. +CONFIG_RTC_DRV_MXC=y
  20782. +CONFIG_RTC_DRV_SNVS=y
  20783. +CONFIG_DMADEVICES=y
  20784. +CONFIG_MXC_PXP_V2=y
  20785. +CONFIG_IMX_SDMA=y
  20786. +CONFIG_MXS_DMA=y
  20787. +CONFIG_STAGING=y
  20788. +CONFIG_COMMON_CLK_DEBUG=y
  20789. +# CONFIG_IOMMU_SUPPORT is not set
  20790. +CONFIG_PWM=y
  20791. +CONFIG_PWM_IMX=y
  20792. +CONFIG_EXT2_FS=y
  20793. +CONFIG_EXT2_FS_XATTR=y
  20794. +CONFIG_EXT2_FS_POSIX_ACL=y
  20795. +CONFIG_EXT2_FS_SECURITY=y
  20796. +CONFIG_EXT3_FS=y
  20797. +CONFIG_EXT3_FS_POSIX_ACL=y
  20798. +CONFIG_EXT3_FS_SECURITY=y
  20799. +CONFIG_EXT4_FS=y
  20800. +CONFIG_EXT4_FS_POSIX_ACL=y
  20801. +CONFIG_EXT4_FS_SECURITY=y
  20802. +CONFIG_QUOTA=y
  20803. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  20804. +# CONFIG_PRINT_QUOTA_WARNING is not set
  20805. +CONFIG_AUTOFS4_FS=y
  20806. +CONFIG_FUSE_FS=y
  20807. +CONFIG_ISO9660_FS=m
  20808. +CONFIG_JOLIET=y
  20809. +CONFIG_ZISOFS=y
  20810. +CONFIG_UDF_FS=m
  20811. +CONFIG_MSDOS_FS=m
  20812. +CONFIG_VFAT_FS=y
  20813. +CONFIG_TMPFS=y
  20814. +CONFIG_JFFS2_FS=y
  20815. +CONFIG_UBIFS_FS=y
  20816. +CONFIG_NFS_FS=y
  20817. +CONFIG_NFS_V3_ACL=y
  20818. +CONFIG_NFS_V4=y
  20819. +CONFIG_ROOT_NFS=y
  20820. +CONFIG_NLS_DEFAULT="cp437"
  20821. +CONFIG_NLS_CODEPAGE_437=y
  20822. +CONFIG_NLS_ASCII=y
  20823. +CONFIG_NLS_ISO8859_1=y
  20824. +CONFIG_NLS_ISO8859_15=m
  20825. +CONFIG_NLS_UTF8=y
  20826. +CONFIG_MAGIC_SYSRQ=y
  20827. +# CONFIG_SCHED_DEBUG is not set
  20828. +# CONFIG_DEBUG_BUGVERBOSE is not set
  20829. +# CONFIG_FTRACE is not set
  20830. +CONFIG_SECURITYFS=y
  20831. +CONFIG_CRYPTO_USER=y
  20832. +CONFIG_CRYPTO_TEST=m
  20833. +CONFIG_CRYPTO_CCM=y
  20834. +CONFIG_CRYPTO_GCM=y
  20835. +CONFIG_CRYPTO_CBC=y
  20836. +CONFIG_CRYPTO_CTS=y
  20837. +CONFIG_CRYPTO_ECB=y
  20838. +CONFIG_CRYPTO_LRW=y
  20839. +CONFIG_CRYPTO_XTS=y
  20840. +CONFIG_CRYPTO_MD4=y
  20841. +CONFIG_CRYPTO_MD5=y
  20842. +CONFIG_CRYPTO_MICHAEL_MIC=y
  20843. +CONFIG_CRYPTO_RMD128=y
  20844. +CONFIG_CRYPTO_RMD160=y
  20845. +CONFIG_CRYPTO_RMD256=y
  20846. +CONFIG_CRYPTO_RMD320=y
  20847. +CONFIG_CRYPTO_SHA1=y
  20848. +CONFIG_CRYPTO_SHA256=y
  20849. +CONFIG_CRYPTO_SHA512=y
  20850. +CONFIG_CRYPTO_TGR192=y
  20851. +CONFIG_CRYPTO_WP512=y
  20852. +CONFIG_CRYPTO_BLOWFISH=y
  20853. +CONFIG_CRYPTO_CAMELLIA=y
  20854. +CONFIG_CRYPTO_DES=y
  20855. +CONFIG_CRYPTO_TWOFISH=y
  20856. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  20857. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  20858. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  20859. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  20860. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  20861. +CONFIG_CRC_CCITT=m
  20862. +CONFIG_CRC_T10DIF=y
  20863. +CONFIG_CRC7=m
  20864. +CONFIG_LIBCRC32C=m
  20865. diff -Nur linux-3.14.17/arch/arm/configs/imx_v7_mfg_defconfig linux-imx6-3.14/arch/arm/configs/imx_v7_mfg_defconfig
  20866. --- linux-3.14.17/arch/arm/configs/imx_v7_mfg_defconfig 1970-01-01 01:00:00.000000000 +0100
  20867. +++ linux-imx6-3.14/arch/arm/configs/imx_v7_mfg_defconfig 2014-09-11 18:05:52.798001191 +0200
  20868. @@ -0,0 +1,341 @@
  20869. +CONFIG_KERNEL_LZO=y
  20870. +CONFIG_SYSVIPC=y
  20871. +CONFIG_NO_HZ=y
  20872. +CONFIG_HIGH_RES_TIMERS=y
  20873. +CONFIG_IKCONFIG=y
  20874. +CONFIG_IKCONFIG_PROC=y
  20875. +CONFIG_LOG_BUF_SHIFT=18
  20876. +CONFIG_CGROUPS=y
  20877. +CONFIG_RELAY=y
  20878. +CONFIG_BLK_DEV_INITRD=y
  20879. +CONFIG_EXPERT=y
  20880. +CONFIG_PERF_EVENTS=y
  20881. +# CONFIG_SLUB_DEBUG is not set
  20882. +# CONFIG_COMPAT_BRK is not set
  20883. +CONFIG_MODULES=y
  20884. +CONFIG_MODULE_UNLOAD=y
  20885. +CONFIG_MODVERSIONS=y
  20886. +CONFIG_MODULE_SRCVERSION_ALL=y
  20887. +# CONFIG_BLK_DEV_BSG is not set
  20888. +CONFIG_GPIO_PCA953X=y
  20889. +CONFIG_ARCH_MXC=y
  20890. +CONFIG_MXC_DEBUG_BOARD=y
  20891. +CONFIG_MACH_IMX51_DT=y
  20892. +CONFIG_MACH_EUKREA_CPUIMX51SD=y
  20893. +CONFIG_SOC_IMX53=y
  20894. +CONFIG_SOC_IMX6Q=y
  20895. +CONFIG_SOC_IMX6SL=y
  20896. +CONFIG_SOC_VF610=y
  20897. +# CONFIG_SWP_EMULATE is not set
  20898. +CONFIG_SMP=y
  20899. +CONFIG_VMSPLIT_2G=y
  20900. +CONFIG_PREEMPT_VOLUNTARY=y
  20901. +CONFIG_AEABI=y
  20902. +# CONFIG_OABI_COMPAT is not set
  20903. +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
  20904. +CONFIG_CPU_FREQ=y
  20905. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  20906. +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
  20907. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  20908. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  20909. +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
  20910. +CONFIG_ARM_IMX6_CPUFREQ=y
  20911. +CONFIG_CPU_IDLE=y
  20912. +CONFIG_VFP=y
  20913. +CONFIG_NEON=y
  20914. +CONFIG_BINFMT_MISC=m
  20915. +CONFIG_PM_RUNTIME=y
  20916. +CONFIG_PM_DEBUG=y
  20917. +CONFIG_PM_TEST_SUSPEND=y
  20918. +CONFIG_NET=y
  20919. +CONFIG_PACKET=y
  20920. +CONFIG_UNIX=y
  20921. +CONFIG_INET=y
  20922. +CONFIG_IP_PNP=y
  20923. +CONFIG_IP_PNP_DHCP=y
  20924. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  20925. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  20926. +# CONFIG_INET_XFRM_MODE_BEET is not set
  20927. +# CONFIG_INET_LRO is not set
  20928. +CONFIG_IPV6=y
  20929. +CONFIG_NETFILTER=y
  20930. +CONFIG_VLAN_8021Q=y
  20931. +CONFIG_CFG80211=y
  20932. +CONFIG_CFG80211_WEXT=y
  20933. +CONFIG_MAC80211=y
  20934. +CONFIG_DEVTMPFS=y
  20935. +CONFIG_DEVTMPFS_MOUNT=y
  20936. +# CONFIG_STANDALONE is not set
  20937. +CONFIG_CMA=y
  20938. +CONFIG_CMA_SIZE_MBYTES=320
  20939. +CONFIG_IMX_WEIM=y
  20940. +CONFIG_CONNECTOR=y
  20941. +CONFIG_MTD=y
  20942. +CONFIG_MTD_CMDLINE_PARTS=y
  20943. +CONFIG_MTD_BLOCK=y
  20944. +CONFIG_MTD_CFI=y
  20945. +CONFIG_MTD_JEDECPROBE=y
  20946. +CONFIG_MTD_CFI_INTELEXT=y
  20947. +CONFIG_MTD_CFI_AMDSTD=y
  20948. +CONFIG_MTD_CFI_STAA=y
  20949. +CONFIG_MTD_PHYSMAP_OF=y
  20950. +CONFIG_MTD_DATAFLASH=y
  20951. +CONFIG_MTD_M25P80=y
  20952. +CONFIG_MTD_SST25L=y
  20953. +CONFIG_MTD_NAND=y
  20954. +CONFIG_MTD_NAND_GPMI_NAND=y
  20955. +CONFIG_MTD_NAND_MXC=y
  20956. +CONFIG_MTD_UBI=y
  20957. +CONFIG_BLK_DEV_LOOP=y
  20958. +CONFIG_BLK_DEV_RAM=y
  20959. +CONFIG_BLK_DEV_RAM_SIZE=65536
  20960. +CONFIG_EEPROM_AT24=y
  20961. +CONFIG_EEPROM_AT25=y
  20962. +# CONFIG_SCSI_PROC_FS is not set
  20963. +CONFIG_BLK_DEV_SD=y
  20964. +CONFIG_SCSI_MULTI_LUN=y
  20965. +CONFIG_SCSI_CONSTANTS=y
  20966. +CONFIG_SCSI_LOGGING=y
  20967. +CONFIG_SCSI_SCAN_ASYNC=y
  20968. +# CONFIG_SCSI_LOWLEVEL is not set
  20969. +CONFIG_ATA=y
  20970. +CONFIG_SATA_AHCI_PLATFORM=y
  20971. +CONFIG_AHCI_IMX=y
  20972. +CONFIG_PATA_IMX=y
  20973. +CONFIG_NETDEVICES=y
  20974. +# CONFIG_NET_VENDOR_BROADCOM is not set
  20975. +CONFIG_CS89x0=y
  20976. +CONFIG_CS89x0_PLATFORM=y
  20977. +# CONFIG_NET_VENDOR_FARADAY is not set
  20978. +# CONFIG_NET_VENDOR_INTEL is not set
  20979. +# CONFIG_NET_VENDOR_MARVELL is not set
  20980. +# CONFIG_NET_VENDOR_MICREL is not set
  20981. +# CONFIG_NET_VENDOR_MICROCHIP is not set
  20982. +# CONFIG_NET_VENDOR_NATSEMI is not set
  20983. +# CONFIG_NET_VENDOR_SEEQ is not set
  20984. +CONFIG_SMC91X=y
  20985. +CONFIG_SMC911X=y
  20986. +CONFIG_SMSC911X=y
  20987. +# CONFIG_NET_VENDOR_STMICRO is not set
  20988. +CONFIG_ATH_CARDS=y
  20989. +CONFIG_ATH6KL=m
  20990. +CONFIG_ATH6KL_SDIO=m
  20991. +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
  20992. +CONFIG_INPUT_EVDEV=y
  20993. +CONFIG_INPUT_EVBUG=m
  20994. +CONFIG_KEYBOARD_GPIO=y
  20995. +CONFIG_KEYBOARD_IMX=y
  20996. +CONFIG_MOUSE_PS2=m
  20997. +CONFIG_MOUSE_PS2_ELANTECH=y
  20998. +CONFIG_INPUT_TOUCHSCREEN=y
  20999. +CONFIG_TOUCHSCREEN_EGALAX=y
  21000. +CONFIG_TOUCHSCREEN_ELAN=y
  21001. +CONFIG_TOUCHSCREEN_MAX11801=y
  21002. +CONFIG_TOUCHSCREEN_MC13783=y
  21003. +CONFIG_INPUT_MISC=y
  21004. +CONFIG_INPUT_MMA8450=y
  21005. +CONFIG_INPUT_ISL29023=y
  21006. +CONFIG_SERIO_SERPORT=m
  21007. +CONFIG_VT_HW_CONSOLE_BINDING=y
  21008. +# CONFIG_LEGACY_PTYS is not set
  21009. +# CONFIG_DEVKMEM is not set
  21010. +CONFIG_SERIAL_IMX=y
  21011. +CONFIG_SERIAL_IMX_CONSOLE=y
  21012. +CONFIG_SERIAL_FSL_LPUART=y
  21013. +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
  21014. +CONFIG_FSL_OTP=y
  21015. +# CONFIG_I2C_COMPAT is not set
  21016. +CONFIG_I2C_CHARDEV=y
  21017. +# CONFIG_I2C_HELPER_AUTO is not set
  21018. +CONFIG_I2C_ALGOPCF=m
  21019. +CONFIG_I2C_ALGOPCA=m
  21020. +CONFIG_I2C_IMX=y
  21021. +CONFIG_SPI=y
  21022. +CONFIG_SPI_IMX=y
  21023. +CONFIG_GPIO_SYSFS=y
  21024. +CONFIG_POWER_SUPPLY=y
  21025. +CONFIG_SABRESD_MAX8903=y
  21026. +CONFIG_SENSORS_MAX17135=y
  21027. +CONFIG_SENSORS_MAG3110=y
  21028. +CONFIG_THERMAL=y
  21029. +CONFIG_CPU_THERMAL=y
  21030. +CONFIG_IMX_THERMAL=y
  21031. +CONFIG_DEVICE_THERMAL=y
  21032. +CONFIG_WATCHDOG=y
  21033. +CONFIG_IMX2_WDT=y
  21034. +CONFIG_MFD_DA9052_I2C=y
  21035. +CONFIG_MFD_MC13XXX_SPI=y
  21036. +CONFIG_MFD_MC13XXX_I2C=y
  21037. +CONFIG_MFD_MAX17135=y
  21038. +CONFIG_MFD_SI476X_CORE=y
  21039. +CONFIG_REGULATOR=y
  21040. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  21041. +CONFIG_REGULATOR_DA9052=y
  21042. +CONFIG_REGULATOR_ANATOP=y
  21043. +CONFIG_REGULATOR_MC13783=y
  21044. +CONFIG_REGULATOR_MC13892=y
  21045. +CONFIG_REGULATOR_MAX17135=y
  21046. +CONFIG_REGULATOR_PFUZE100=y
  21047. +CONFIG_MEDIA_SUPPORT=y
  21048. +CONFIG_MEDIA_CAMERA_SUPPORT=y
  21049. +CONFIG_MEDIA_RADIO_SUPPORT=y
  21050. +CONFIG_VIDEO_V4L2_INT_DEVICE=y
  21051. +CONFIG_MEDIA_USB_SUPPORT=y
  21052. +CONFIG_USB_VIDEO_CLASS=m
  21053. +CONFIG_V4L_PLATFORM_DRIVERS=y
  21054. +CONFIG_VIDEO_MXC_OUTPUT=y
  21055. +CONFIG_VIDEO_MXC_CAPTURE=m
  21056. +CONFIG_VIDEO_MXC_CSI_CAMERA=m
  21057. +CONFIG_MXC_CAMERA_OV5640=m
  21058. +CONFIG_MXC_CAMERA_OV5642=m
  21059. +CONFIG_MXC_CAMERA_OV5640_MIPI=m
  21060. +CONFIG_MXC_TVIN_ADV7180=m
  21061. +CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
  21062. +CONFIG_VIDEO_MXC_IPU_OUTPUT=y
  21063. +CONFIG_VIDEO_MXC_PXP_V4L2=y
  21064. +CONFIG_SOC_CAMERA=y
  21065. +CONFIG_VIDEO_MX3=y
  21066. +CONFIG_RADIO_SI476X=y
  21067. +CONFIG_SOC_CAMERA_OV2640=y
  21068. +CONFIG_DRM=y
  21069. +CONFIG_DRM_VIVANTE=y
  21070. +CONFIG_FB=y
  21071. +CONFIG_FB_MXS=y
  21072. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  21073. +CONFIG_LCD_CLASS_DEVICE=y
  21074. +CONFIG_LCD_L4F00242T03=y
  21075. +CONFIG_LCD_PLATFORM=y
  21076. +CONFIG_BACKLIGHT_CLASS_DEVICE=y
  21077. +CONFIG_BACKLIGHT_PWM=y
  21078. +CONFIG_FB_MXC_SYNC_PANEL=y
  21079. +CONFIG_FB_MXC_LDB=y
  21080. +CONFIG_FB_MXC_MIPI_DSI=y
  21081. +CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
  21082. +CONFIG_FB_MXC_HDMI=y
  21083. +CONFIG_FB_MXC_EINK_PANEL=y
  21084. +CONFIG_FB_MXS_SII902X=y
  21085. +CONFIG_FRAMEBUFFER_CONSOLE=y
  21086. +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
  21087. +CONFIG_FONTS=y
  21088. +CONFIG_FONT_8x8=y
  21089. +CONFIG_FONT_8x16=y
  21090. +CONFIG_LOGO=y
  21091. +CONFIG_SOUND=y
  21092. +CONFIG_SND=y
  21093. +CONFIG_SND_USB_AUDIO=m
  21094. +CONFIG_SND_SOC=y
  21095. +CONFIG_SND_IMX_SOC=y
  21096. +CONFIG_SND_SOC_EUKREA_TLV320=y
  21097. +CONFIG_SND_SOC_IMX_CS42888=y
  21098. +CONFIG_SND_SOC_IMX_WM8962=y
  21099. +CONFIG_SND_SOC_IMX_SGTL5000=y
  21100. +CONFIG_SND_SOC_IMX_SPDIF=y
  21101. +CONFIG_SND_SOC_IMX_MC13783=y
  21102. +CONFIG_SND_SOC_IMX_HDMI=y
  21103. +CONFIG_SND_SOC_IMX_SI476X=y
  21104. +CONFIG_USB=y
  21105. +CONFIG_USB_EHCI_HCD=y
  21106. +CONFIG_USB_STORAGE=y
  21107. +CONFIG_USB_CHIPIDEA=y
  21108. +CONFIG_USB_CHIPIDEA_UDC=y
  21109. +CONFIG_USB_CHIPIDEA_HOST=y
  21110. +CONFIG_USB_PHY=y
  21111. +CONFIG_USB_MXS_PHY=y
  21112. +CONFIG_USB_GADGET=y
  21113. +# CONFIG_USB_ZERO is not set
  21114. +# CONFIG_USB_AUDIO is not set
  21115. +# CONFIG_USB_ETH is not set
  21116. +# CONFIG_USB_G_NCM is not set
  21117. +# CONFIG_USB_GADGETFS is not set
  21118. +# CONFIG_USB_FUNCTIONFS is not set
  21119. +CONFIG_USB_MASS_STORAGE=y
  21120. +CONFIG_FSL_UTP=y
  21121. +# CONFIG_USB_G_SERIAL is not set
  21122. +# CONFIG_USB_MIDI_GADGET is not set
  21123. +# CONFIG_USB_G_PRINTER is not set
  21124. +# CONFIG_USB_CDC_COMPOSITE is not set
  21125. +# CONFIG_USB_G_ACM_MS is not set
  21126. +# CONFIG_USB_G_MULTI is not set
  21127. +# CONFIG_USB_G_HID is not set
  21128. +# CONFIG_USB_G_DBGP is not set
  21129. +# CONFIG_USB_G_WEBCAM is not set
  21130. +CONFIG_MMC=y
  21131. +CONFIG_MMC_UNSAFE_RESUME=y
  21132. +CONFIG_MMC_SDHCI=y
  21133. +CONFIG_MMC_SDHCI_PLTFM=y
  21134. +CONFIG_MMC_SDHCI_ESDHC_IMX=y
  21135. +CONFIG_MXC_IPU=y
  21136. +CONFIG_MXC_GPU_VIV=y
  21137. +CONFIG_MXC_ASRC=y
  21138. +CONFIG_MXC_MIPI_CSI2=y
  21139. +CONFIG_NEW_LEDS=y
  21140. +CONFIG_LEDS_CLASS=y
  21141. +CONFIG_RTC_CLASS=y
  21142. +CONFIG_RTC_INTF_DEV_UIE_EMUL=y
  21143. +CONFIG_RTC_DRV_MC13XXX=y
  21144. +CONFIG_RTC_DRV_MXC=y
  21145. +CONFIG_RTC_DRV_SNVS=y
  21146. +CONFIG_DMADEVICES=y
  21147. +CONFIG_MXC_PXP_V2=y
  21148. +CONFIG_IMX_SDMA=y
  21149. +CONFIG_MXS_DMA=y
  21150. +CONFIG_STAGING=y
  21151. +CONFIG_COMMON_CLK_DEBUG=y
  21152. +# CONFIG_IOMMU_SUPPORT is not set
  21153. +CONFIG_PWM=y
  21154. +CONFIG_PWM_IMX=y
  21155. +CONFIG_EXT2_FS=y
  21156. +CONFIG_EXT2_FS_XATTR=y
  21157. +CONFIG_EXT2_FS_POSIX_ACL=y
  21158. +CONFIG_EXT2_FS_SECURITY=y
  21159. +CONFIG_EXT3_FS=y
  21160. +CONFIG_EXT3_FS_POSIX_ACL=y
  21161. +CONFIG_EXT3_FS_SECURITY=y
  21162. +CONFIG_EXT4_FS=y
  21163. +CONFIG_EXT4_FS_POSIX_ACL=y
  21164. +CONFIG_EXT4_FS_SECURITY=y
  21165. +CONFIG_QUOTA=y
  21166. +CONFIG_QUOTA_NETLINK_INTERFACE=y
  21167. +# CONFIG_PRINT_QUOTA_WARNING is not set
  21168. +CONFIG_AUTOFS4_FS=y
  21169. +CONFIG_FUSE_FS=y
  21170. +CONFIG_ISO9660_FS=m
  21171. +CONFIG_JOLIET=y
  21172. +CONFIG_ZISOFS=y
  21173. +CONFIG_UDF_FS=m
  21174. +CONFIG_MSDOS_FS=m
  21175. +CONFIG_VFAT_FS=y
  21176. +CONFIG_TMPFS=y
  21177. +CONFIG_JFFS2_FS=y
  21178. +CONFIG_UBIFS_FS=y
  21179. +CONFIG_NFS_FS=y
  21180. +CONFIG_NFS_V3_ACL=y
  21181. +CONFIG_NFS_V4=y
  21182. +CONFIG_ROOT_NFS=y
  21183. +CONFIG_NLS_DEFAULT="cp437"
  21184. +CONFIG_NLS_CODEPAGE_437=y
  21185. +CONFIG_NLS_ASCII=y
  21186. +CONFIG_NLS_ISO8859_1=y
  21187. +CONFIG_NLS_ISO8859_15=m
  21188. +CONFIG_NLS_UTF8=y
  21189. +CONFIG_MAGIC_SYSRQ=y
  21190. +# CONFIG_SCHED_DEBUG is not set
  21191. +# CONFIG_DEBUG_BUGVERBOSE is not set
  21192. +# CONFIG_FTRACE is not set
  21193. +CONFIG_SECURITYFS=y
  21194. +CONFIG_CRYPTO_USER=y
  21195. +CONFIG_CRYPTO_CCM=y
  21196. +CONFIG_CRYPTO_GCM=y
  21197. +CONFIG_CRYPTO_CBC=y
  21198. +CONFIG_CRYPTO_CTS=y
  21199. +CONFIG_CRYPTO_ECB=y
  21200. +CONFIG_CRYPTO_LRW=y
  21201. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  21202. +CONFIG_CRYPTO_DEV_FSL_CAAM=y
  21203. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
  21204. +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
  21205. +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
  21206. +CONFIG_CRC_CCITT=m
  21207. +CONFIG_CRC_T10DIF=y
  21208. +CONFIG_CRC7=m
  21209. +CONFIG_LIBCRC32C=m
  21210. diff -Nur linux-3.14.17/arch/arm/crypto/aesbs-glue.c linux-imx6-3.14/arch/arm/crypto/aesbs-glue.c
  21211. --- linux-3.14.17/arch/arm/crypto/aesbs-glue.c 2014-08-14 03:38:34.000000000 +0200
  21212. +++ linux-imx6-3.14/arch/arm/crypto/aesbs-glue.c 2014-09-11 18:05:52.806001223 +0200
  21213. @@ -137,7 +137,7 @@
  21214. dst += AES_BLOCK_SIZE;
  21215. } while (--blocks);
  21216. }
  21217. - err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  21218. + err = blkcipher_walk_done(desc, &walk, 0);
  21219. }
  21220. return err;
  21221. }
  21222. @@ -158,7 +158,7 @@
  21223. bsaes_cbc_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
  21224. walk.nbytes, &ctx->dec, walk.iv);
  21225. kernel_neon_end();
  21226. - err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  21227. + err = blkcipher_walk_done(desc, &walk, 0);
  21228. }
  21229. while (walk.nbytes) {
  21230. u32 blocks = walk.nbytes / AES_BLOCK_SIZE;
  21231. @@ -182,7 +182,7 @@
  21232. dst += AES_BLOCK_SIZE;
  21233. src += AES_BLOCK_SIZE;
  21234. } while (--blocks);
  21235. - err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  21236. + err = blkcipher_walk_done(desc, &walk, 0);
  21237. }
  21238. return err;
  21239. }
  21240. @@ -268,7 +268,7 @@
  21241. bsaes_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
  21242. walk.nbytes, &ctx->enc, walk.iv);
  21243. kernel_neon_end();
  21244. - err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  21245. + err = blkcipher_walk_done(desc, &walk, 0);
  21246. }
  21247. return err;
  21248. }
  21249. @@ -292,7 +292,7 @@
  21250. bsaes_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
  21251. walk.nbytes, &ctx->dec, walk.iv);
  21252. kernel_neon_end();
  21253. - err = blkcipher_walk_done(desc, &walk, walk.nbytes % AES_BLOCK_SIZE);
  21254. + err = blkcipher_walk_done(desc, &walk, 0);
  21255. }
  21256. return err;
  21257. }
  21258. diff -Nur linux-3.14.17/arch/arm/include/asm/arch_timer.h linux-imx6-3.14/arch/arm/include/asm/arch_timer.h
  21259. --- linux-3.14.17/arch/arm/include/asm/arch_timer.h 2014-08-14 03:38:34.000000000 +0200
  21260. +++ linux-imx6-3.14/arch/arm/include/asm/arch_timer.h 2014-09-11 18:05:52.810001239 +0200
  21261. @@ -107,7 +107,6 @@
  21262. /* Also disable virtual event stream */
  21263. cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
  21264. | ARCH_TIMER_USR_VT_ACCESS_EN
  21265. - | ARCH_TIMER_VIRT_EVT_EN
  21266. | ARCH_TIMER_USR_VCT_ACCESS_EN
  21267. | ARCH_TIMER_USR_PCT_ACCESS_EN);
  21268. arch_timer_set_cntkctl(cntkctl);
  21269. diff -Nur linux-3.14.17/arch/arm/include/asm/atomic.h linux-imx6-3.14/arch/arm/include/asm/atomic.h
  21270. --- linux-3.14.17/arch/arm/include/asm/atomic.h 2014-08-14 03:38:34.000000000 +0200
  21271. +++ linux-imx6-3.14/arch/arm/include/asm/atomic.h 2014-09-11 18:05:52.810001239 +0200
  21272. @@ -60,6 +60,7 @@
  21273. int result;
  21274. smp_mb();
  21275. + prefetchw(&v->counter);
  21276. __asm__ __volatile__("@ atomic_add_return\n"
  21277. "1: ldrex %0, [%3]\n"
  21278. @@ -99,6 +100,7 @@
  21279. int result;
  21280. smp_mb();
  21281. + prefetchw(&v->counter);
  21282. __asm__ __volatile__("@ atomic_sub_return\n"
  21283. "1: ldrex %0, [%3]\n"
  21284. @@ -121,6 +123,7 @@
  21285. unsigned long res;
  21286. smp_mb();
  21287. + prefetchw(&ptr->counter);
  21288. do {
  21289. __asm__ __volatile__("@ atomic_cmpxchg\n"
  21290. @@ -138,6 +141,33 @@
  21291. return oldval;
  21292. }
  21293. +static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  21294. +{
  21295. + int oldval, newval;
  21296. + unsigned long tmp;
  21297. +
  21298. + smp_mb();
  21299. + prefetchw(&v->counter);
  21300. +
  21301. + __asm__ __volatile__ ("@ atomic_add_unless\n"
  21302. +"1: ldrex %0, [%4]\n"
  21303. +" teq %0, %5\n"
  21304. +" beq 2f\n"
  21305. +" add %1, %0, %6\n"
  21306. +" strex %2, %1, [%4]\n"
  21307. +" teq %2, #0\n"
  21308. +" bne 1b\n"
  21309. +"2:"
  21310. + : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
  21311. + : "r" (&v->counter), "r" (u), "r" (a)
  21312. + : "cc");
  21313. +
  21314. + if (oldval != u)
  21315. + smp_mb();
  21316. +
  21317. + return oldval;
  21318. +}
  21319. +
  21320. #else /* ARM_ARCH_6 */
  21321. #ifdef CONFIG_SMP
  21322. @@ -186,10 +216,6 @@
  21323. return ret;
  21324. }
  21325. -#endif /* __LINUX_ARM_ARCH__ */
  21326. -
  21327. -#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
  21328. -
  21329. static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  21330. {
  21331. int c, old;
  21332. @@ -200,6 +226,10 @@
  21333. return c;
  21334. }
  21335. +#endif /* __LINUX_ARM_ARCH__ */
  21336. +
  21337. +#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
  21338. +
  21339. #define atomic_inc(v) atomic_add(1, v)
  21340. #define atomic_dec(v) atomic_sub(1, v)
  21341. @@ -299,6 +329,7 @@
  21342. unsigned long tmp;
  21343. smp_mb();
  21344. + prefetchw(&v->counter);
  21345. __asm__ __volatile__("@ atomic64_add_return\n"
  21346. "1: ldrexd %0, %H0, [%3]\n"
  21347. @@ -340,6 +371,7 @@
  21348. unsigned long tmp;
  21349. smp_mb();
  21350. + prefetchw(&v->counter);
  21351. __asm__ __volatile__("@ atomic64_sub_return\n"
  21352. "1: ldrexd %0, %H0, [%3]\n"
  21353. @@ -364,6 +396,7 @@
  21354. unsigned long res;
  21355. smp_mb();
  21356. + prefetchw(&ptr->counter);
  21357. do {
  21358. __asm__ __volatile__("@ atomic64_cmpxchg\n"
  21359. @@ -388,6 +421,7 @@
  21360. unsigned long tmp;
  21361. smp_mb();
  21362. + prefetchw(&ptr->counter);
  21363. __asm__ __volatile__("@ atomic64_xchg\n"
  21364. "1: ldrexd %0, %H0, [%3]\n"
  21365. @@ -409,6 +443,7 @@
  21366. unsigned long tmp;
  21367. smp_mb();
  21368. + prefetchw(&v->counter);
  21369. __asm__ __volatile__("@ atomic64_dec_if_positive\n"
  21370. "1: ldrexd %0, %H0, [%3]\n"
  21371. @@ -436,6 +471,7 @@
  21372. int ret = 1;
  21373. smp_mb();
  21374. + prefetchw(&v->counter);
  21375. __asm__ __volatile__("@ atomic64_add_unless\n"
  21376. "1: ldrexd %0, %H0, [%4]\n"
  21377. diff -Nur linux-3.14.17/arch/arm/include/asm/cmpxchg.h linux-imx6-3.14/arch/arm/include/asm/cmpxchg.h
  21378. --- linux-3.14.17/arch/arm/include/asm/cmpxchg.h 2014-08-14 03:38:34.000000000 +0200
  21379. +++ linux-imx6-3.14/arch/arm/include/asm/cmpxchg.h 2014-09-11 18:05:52.810001239 +0200
  21380. @@ -2,6 +2,7 @@
  21381. #define __ASM_ARM_CMPXCHG_H
  21382. #include <linux/irqflags.h>
  21383. +#include <linux/prefetch.h>
  21384. #include <asm/barrier.h>
  21385. #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
  21386. @@ -35,6 +36,7 @@
  21387. #endif
  21388. smp_mb();
  21389. + prefetchw((const void *)ptr);
  21390. switch (size) {
  21391. #if __LINUX_ARM_ARCH__ >= 6
  21392. @@ -138,6 +140,8 @@
  21393. {
  21394. unsigned long oldval, res;
  21395. + prefetchw((const void *)ptr);
  21396. +
  21397. switch (size) {
  21398. #ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
  21399. case 1:
  21400. @@ -230,6 +234,8 @@
  21401. unsigned long long oldval;
  21402. unsigned long res;
  21403. + prefetchw(ptr);
  21404. +
  21405. __asm__ __volatile__(
  21406. "1: ldrexd %1, %H1, [%3]\n"
  21407. " teq %1, %4\n"
  21408. diff -Nur linux-3.14.17/arch/arm/include/asm/ftrace.h linux-imx6-3.14/arch/arm/include/asm/ftrace.h
  21409. --- linux-3.14.17/arch/arm/include/asm/ftrace.h 2014-08-14 03:38:34.000000000 +0200
  21410. +++ linux-imx6-3.14/arch/arm/include/asm/ftrace.h 2014-09-11 18:05:52.810001239 +0200
  21411. @@ -52,15 +52,7 @@
  21412. #endif
  21413. -#define HAVE_ARCH_CALLER_ADDR
  21414. -
  21415. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  21416. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  21417. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  21418. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  21419. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  21420. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  21421. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  21422. +#define ftrace_return_address(n) return_address(n)
  21423. #endif /* ifndef __ASSEMBLY__ */
  21424. diff -Nur linux-3.14.17/arch/arm/include/asm/futex.h linux-imx6-3.14/arch/arm/include/asm/futex.h
  21425. --- linux-3.14.17/arch/arm/include/asm/futex.h 2014-08-14 03:38:34.000000000 +0200
  21426. +++ linux-imx6-3.14/arch/arm/include/asm/futex.h 2014-09-11 18:05:52.810001239 +0200
  21427. @@ -23,6 +23,7 @@
  21428. #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
  21429. smp_mb(); \
  21430. + prefetchw(uaddr); \
  21431. __asm__ __volatile__( \
  21432. "1: ldrex %1, [%3]\n" \
  21433. " " insn "\n" \
  21434. @@ -46,6 +47,8 @@
  21435. return -EFAULT;
  21436. smp_mb();
  21437. + /* Prefetching cannot fault */
  21438. + prefetchw(uaddr);
  21439. __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
  21440. "1: ldrex %1, [%4]\n"
  21441. " teq %1, %2\n"
  21442. diff -Nur linux-3.14.17/arch/arm/include/asm/glue-cache.h linux-imx6-3.14/arch/arm/include/asm/glue-cache.h
  21443. --- linux-3.14.17/arch/arm/include/asm/glue-cache.h 2014-08-14 03:38:34.000000000 +0200
  21444. +++ linux-imx6-3.14/arch/arm/include/asm/glue-cache.h 2014-09-11 18:05:52.810001239 +0200
  21445. @@ -102,19 +102,19 @@
  21446. #endif
  21447. #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
  21448. -# ifdef _CACHE
  21449. +//# ifdef _CACHE
  21450. # define MULTI_CACHE 1
  21451. -# else
  21452. -# define _CACHE v6
  21453. -# endif
  21454. +//# else
  21455. +//# define _CACHE v6
  21456. +//# endif
  21457. #endif
  21458. #if defined(CONFIG_CPU_V7)
  21459. -# ifdef _CACHE
  21460. +//# ifdef _CACHE
  21461. # define MULTI_CACHE 1
  21462. -# else
  21463. -# define _CACHE v7
  21464. -# endif
  21465. +//# else
  21466. +//# define _CACHE v7
  21467. +//# endif
  21468. #endif
  21469. #if defined(CONFIG_CPU_V7M)
  21470. diff -Nur linux-3.14.17/arch/arm/include/asm/hardware/cache-l2x0.h linux-imx6-3.14/arch/arm/include/asm/hardware/cache-l2x0.h
  21471. --- linux-3.14.17/arch/arm/include/asm/hardware/cache-l2x0.h 2014-08-14 03:38:34.000000000 +0200
  21472. +++ linux-imx6-3.14/arch/arm/include/asm/hardware/cache-l2x0.h 2014-09-11 18:05:52.814001255 +0200
  21473. @@ -26,8 +26,8 @@
  21474. #define L2X0_CACHE_TYPE 0x004
  21475. #define L2X0_CTRL 0x100
  21476. #define L2X0_AUX_CTRL 0x104
  21477. -#define L2X0_TAG_LATENCY_CTRL 0x108
  21478. -#define L2X0_DATA_LATENCY_CTRL 0x10C
  21479. +#define L310_TAG_LATENCY_CTRL 0x108
  21480. +#define L310_DATA_LATENCY_CTRL 0x10C
  21481. #define L2X0_EVENT_CNT_CTRL 0x200
  21482. #define L2X0_EVENT_CNT1_CFG 0x204
  21483. #define L2X0_EVENT_CNT0_CFG 0x208
  21484. @@ -54,53 +54,93 @@
  21485. #define L2X0_LOCKDOWN_WAY_D_BASE 0x900
  21486. #define L2X0_LOCKDOWN_WAY_I_BASE 0x904
  21487. #define L2X0_LOCKDOWN_STRIDE 0x08
  21488. -#define L2X0_ADDR_FILTER_START 0xC00
  21489. -#define L2X0_ADDR_FILTER_END 0xC04
  21490. +#define L310_ADDR_FILTER_START 0xC00
  21491. +#define L310_ADDR_FILTER_END 0xC04
  21492. #define L2X0_TEST_OPERATION 0xF00
  21493. #define L2X0_LINE_DATA 0xF10
  21494. #define L2X0_LINE_TAG 0xF30
  21495. #define L2X0_DEBUG_CTRL 0xF40
  21496. -#define L2X0_PREFETCH_CTRL 0xF60
  21497. -#define L2X0_POWER_CTRL 0xF80
  21498. -#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
  21499. -#define L2X0_STNDBY_MODE_EN (1 << 0)
  21500. +#define L310_PREFETCH_CTRL 0xF60
  21501. +#define L310_POWER_CTRL 0xF80
  21502. +#define L310_DYNAMIC_CLK_GATING_EN (1 << 1)
  21503. +#define L310_STNDBY_MODE_EN (1 << 0)
  21504. /* Registers shifts and masks */
  21505. #define L2X0_CACHE_ID_PART_MASK (0xf << 6)
  21506. #define L2X0_CACHE_ID_PART_L210 (1 << 6)
  21507. +#define L2X0_CACHE_ID_PART_L220 (2 << 6)
  21508. #define L2X0_CACHE_ID_PART_L310 (3 << 6)
  21509. #define L2X0_CACHE_ID_RTL_MASK 0x3f
  21510. -#define L2X0_CACHE_ID_RTL_R0P0 0x0
  21511. -#define L2X0_CACHE_ID_RTL_R1P0 0x2
  21512. -#define L2X0_CACHE_ID_RTL_R2P0 0x4
  21513. -#define L2X0_CACHE_ID_RTL_R3P0 0x5
  21514. -#define L2X0_CACHE_ID_RTL_R3P1 0x6
  21515. -#define L2X0_CACHE_ID_RTL_R3P2 0x8
  21516. -
  21517. -#define L2X0_AUX_CTRL_MASK 0xc0000fff
  21518. +#define L210_CACHE_ID_RTL_R0P2_02 0x00
  21519. +#define L210_CACHE_ID_RTL_R0P1 0x01
  21520. +#define L210_CACHE_ID_RTL_R0P2_01 0x02
  21521. +#define L210_CACHE_ID_RTL_R0P3 0x03
  21522. +#define L210_CACHE_ID_RTL_R0P4 0x0b
  21523. +#define L210_CACHE_ID_RTL_R0P5 0x0f
  21524. +#define L220_CACHE_ID_RTL_R1P7_01REL0 0x06
  21525. +#define L310_CACHE_ID_RTL_R0P0 0x00
  21526. +#define L310_CACHE_ID_RTL_R1P0 0x02
  21527. +#define L310_CACHE_ID_RTL_R2P0 0x04
  21528. +#define L310_CACHE_ID_RTL_R3P0 0x05
  21529. +#define L310_CACHE_ID_RTL_R3P1 0x06
  21530. +#define L310_CACHE_ID_RTL_R3P1_50REL0 0x07
  21531. +#define L310_CACHE_ID_RTL_R3P2 0x08
  21532. +#define L310_CACHE_ID_RTL_R3P3 0x09
  21533. +
  21534. +/* L2C auxiliary control register - bits common to L2C-210/220/310 */
  21535. +#define L2C_AUX_CTRL_WAY_SIZE_SHIFT 17
  21536. +#define L2C_AUX_CTRL_WAY_SIZE_MASK (7 << 17)
  21537. +#define L2C_AUX_CTRL_WAY_SIZE(n) ((n) << 17)
  21538. +#define L2C_AUX_CTRL_EVTMON_ENABLE BIT(20)
  21539. +#define L2C_AUX_CTRL_PARITY_ENABLE BIT(21)
  21540. +#define L2C_AUX_CTRL_SHARED_OVERRIDE BIT(22)
  21541. +/* L2C-210/220 common bits */
  21542. #define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
  21543. -#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK 0x7
  21544. +#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK (7 << 0)
  21545. #define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
  21546. -#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (0x7 << 3)
  21547. +#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (7 << 3)
  21548. #define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6
  21549. -#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (0x7 << 6)
  21550. +#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (7 << 6)
  21551. #define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9
  21552. -#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (0x7 << 9)
  21553. -#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
  21554. -#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
  21555. -#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17)
  21556. -#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22
  21557. -#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26
  21558. -#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27
  21559. -#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28
  21560. -#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
  21561. -#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
  21562. -
  21563. -#define L2X0_LATENCY_CTRL_SETUP_SHIFT 0
  21564. -#define L2X0_LATENCY_CTRL_RD_SHIFT 4
  21565. -#define L2X0_LATENCY_CTRL_WR_SHIFT 8
  21566. -
  21567. -#define L2X0_ADDR_FILTER_EN 1
  21568. +#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (7 << 9)
  21569. +#define L2X0_AUX_CTRL_ASSOC_SHIFT 13
  21570. +#define L2X0_AUX_CTRL_ASSOC_MASK (15 << 13)
  21571. +/* L2C-210 specific bits */
  21572. +#define L210_AUX_CTRL_WRAP_DISABLE BIT(12)
  21573. +#define L210_AUX_CTRL_WA_OVERRIDE BIT(23)
  21574. +#define L210_AUX_CTRL_EXCLUSIVE_ABORT BIT(24)
  21575. +/* L2C-220 specific bits */
  21576. +#define L220_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
  21577. +#define L220_AUX_CTRL_FWA_SHIFT 23
  21578. +#define L220_AUX_CTRL_FWA_MASK (3 << 23)
  21579. +#define L220_AUX_CTRL_NS_LOCKDOWN BIT(26)
  21580. +#define L220_AUX_CTRL_NS_INT_CTRL BIT(27)
  21581. +/* L2C-310 specific bits */
  21582. +#define L310_AUX_CTRL_FULL_LINE_ZERO BIT(0) /* R2P0+ */
  21583. +#define L310_AUX_CTRL_HIGHPRIO_SO_DEV BIT(10) /* R2P0+ */
  21584. +#define L310_AUX_CTRL_STORE_LIMITATION BIT(11) /* R2P0+ */
  21585. +#define L310_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
  21586. +#define L310_AUX_CTRL_ASSOCIATIVITY_16 BIT(16)
  21587. +#define L310_AUX_CTRL_CACHE_REPLACE_RR BIT(25) /* R2P0+ */
  21588. +#define L310_AUX_CTRL_NS_LOCKDOWN BIT(26)
  21589. +#define L310_AUX_CTRL_NS_INT_CTRL BIT(27)
  21590. +#define L310_AUX_CTRL_DATA_PREFETCH BIT(28)
  21591. +#define L310_AUX_CTRL_INSTR_PREFETCH BIT(29)
  21592. +#define L310_AUX_CTRL_EARLY_BRESP BIT(30) /* R2P0+ */
  21593. +
  21594. +#define L310_LATENCY_CTRL_SETUP(n) ((n) << 0)
  21595. +#define L310_LATENCY_CTRL_RD(n) ((n) << 4)
  21596. +#define L310_LATENCY_CTRL_WR(n) ((n) << 8)
  21597. +
  21598. +#define L310_ADDR_FILTER_EN 1
  21599. +
  21600. +#define L310_PREFETCH_CTRL_OFFSET_MASK 0x1f
  21601. +#define L310_PREFETCH_CTRL_DBL_LINEFILL_INCR BIT(23)
  21602. +#define L310_PREFETCH_CTRL_PREFETCH_DROP BIT(24)
  21603. +#define L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP BIT(27)
  21604. +#define L310_PREFETCH_CTRL_DATA_PREFETCH BIT(28)
  21605. +#define L310_PREFETCH_CTRL_INSTR_PREFETCH BIT(29)
  21606. +#define L310_PREFETCH_CTRL_DBL_LINEFILL BIT(30)
  21607. #define L2X0_CTRL_EN 1
  21608. diff -Nur linux-3.14.17/arch/arm/include/asm/outercache.h linux-imx6-3.14/arch/arm/include/asm/outercache.h
  21609. --- linux-3.14.17/arch/arm/include/asm/outercache.h 2014-08-14 03:38:34.000000000 +0200
  21610. +++ linux-imx6-3.14/arch/arm/include/asm/outercache.h 2014-09-11 18:05:52.898001590 +0200
  21611. @@ -21,6 +21,7 @@
  21612. #ifndef __ASM_OUTERCACHE_H
  21613. #define __ASM_OUTERCACHE_H
  21614. +#include <linux/bug.h>
  21615. #include <linux/types.h>
  21616. struct outer_cache_fns {
  21617. @@ -28,53 +29,84 @@
  21618. void (*clean_range)(unsigned long, unsigned long);
  21619. void (*flush_range)(unsigned long, unsigned long);
  21620. void (*flush_all)(void);
  21621. - void (*inv_all)(void);
  21622. void (*disable)(void);
  21623. #ifdef CONFIG_OUTER_CACHE_SYNC
  21624. void (*sync)(void);
  21625. #endif
  21626. - void (*set_debug)(unsigned long);
  21627. void (*resume)(void);
  21628. +
  21629. + /* This is an ARM L2C thing */
  21630. + void (*write_sec)(unsigned long, unsigned);
  21631. };
  21632. extern struct outer_cache_fns outer_cache;
  21633. #ifdef CONFIG_OUTER_CACHE
  21634. -
  21635. +/**
  21636. + * outer_inv_range - invalidate range of outer cache lines
  21637. + * @start: starting physical address, inclusive
  21638. + * @end: end physical address, exclusive
  21639. + */
  21640. static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
  21641. {
  21642. if (outer_cache.inv_range)
  21643. outer_cache.inv_range(start, end);
  21644. }
  21645. +
  21646. +/**
  21647. + * outer_clean_range - clean dirty outer cache lines
  21648. + * @start: starting physical address, inclusive
  21649. + * @end: end physical address, exclusive
  21650. + */
  21651. static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
  21652. {
  21653. if (outer_cache.clean_range)
  21654. outer_cache.clean_range(start, end);
  21655. }
  21656. +
  21657. +/**
  21658. + * outer_flush_range - clean and invalidate outer cache lines
  21659. + * @start: starting physical address, inclusive
  21660. + * @end: end physical address, exclusive
  21661. + */
  21662. static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
  21663. {
  21664. if (outer_cache.flush_range)
  21665. outer_cache.flush_range(start, end);
  21666. }
  21667. +/**
  21668. + * outer_flush_all - clean and invalidate all cache lines in the outer cache
  21669. + *
  21670. + * Note: depending on implementation, this may not be atomic - it must
  21671. + * only be called with interrupts disabled and no other active outer
  21672. + * cache masters.
  21673. + *
  21674. + * It is intended that this function is only used by implementations
  21675. + * needing to override the outer_cache.disable() method due to security.
  21676. + * (Some implementations perform this as a clean followed by an invalidate.)
  21677. + */
  21678. static inline void outer_flush_all(void)
  21679. {
  21680. if (outer_cache.flush_all)
  21681. outer_cache.flush_all();
  21682. }
  21683. -static inline void outer_inv_all(void)
  21684. -{
  21685. - if (outer_cache.inv_all)
  21686. - outer_cache.inv_all();
  21687. -}
  21688. -
  21689. -static inline void outer_disable(void)
  21690. -{
  21691. - if (outer_cache.disable)
  21692. - outer_cache.disable();
  21693. -}
  21694. -
  21695. +/**
  21696. + * outer_disable - clean, invalidate and disable the outer cache
  21697. + *
  21698. + * Disable the outer cache, ensuring that any data contained in the outer
  21699. + * cache is pushed out to lower levels of system memory. The note and
  21700. + * conditions above concerning outer_flush_all() applies here.
  21701. + */
  21702. +extern void outer_disable(void);
  21703. +
  21704. +/**
  21705. + * outer_resume - restore the cache configuration and re-enable outer cache
  21706. + *
  21707. + * Restore any configuration that the cache had when previously enabled,
  21708. + * and re-enable the outer cache.
  21709. + */
  21710. static inline void outer_resume(void)
  21711. {
  21712. if (outer_cache.resume)
  21713. @@ -90,13 +122,18 @@
  21714. static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
  21715. { }
  21716. static inline void outer_flush_all(void) { }
  21717. -static inline void outer_inv_all(void) { }
  21718. static inline void outer_disable(void) { }
  21719. static inline void outer_resume(void) { }
  21720. #endif
  21721. #ifdef CONFIG_OUTER_CACHE_SYNC
  21722. +/**
  21723. + * outer_sync - perform a sync point for outer cache
  21724. + *
  21725. + * Ensure that all outer cache operations are complete and any store
  21726. + * buffers are drained.
  21727. + */
  21728. static inline void outer_sync(void)
  21729. {
  21730. if (outer_cache.sync)
  21731. diff -Nur linux-3.14.17/arch/arm/include/asm/pmu.h linux-imx6-3.14/arch/arm/include/asm/pmu.h
  21732. --- linux-3.14.17/arch/arm/include/asm/pmu.h 2014-08-14 03:38:34.000000000 +0200
  21733. +++ linux-imx6-3.14/arch/arm/include/asm/pmu.h 2014-09-11 18:05:52.902001607 +0200
  21734. @@ -62,9 +62,19 @@
  21735. raw_spinlock_t pmu_lock;
  21736. };
  21737. +struct cpupmu_regs {
  21738. + u32 pmc;
  21739. + u32 pmcntenset;
  21740. + u32 pmuseren;
  21741. + u32 pmintenset;
  21742. + u32 pmxevttype[8];
  21743. + u32 pmxevtcnt[8];
  21744. +};
  21745. +
  21746. struct arm_pmu {
  21747. struct pmu pmu;
  21748. cpumask_t active_irqs;
  21749. + cpumask_t valid_cpus;
  21750. char *name;
  21751. irqreturn_t (*handle_irq)(int irq_num, void *dev);
  21752. void (*enable)(struct perf_event *event);
  21753. @@ -81,6 +91,8 @@
  21754. int (*request_irq)(struct arm_pmu *, irq_handler_t handler);
  21755. void (*free_irq)(struct arm_pmu *);
  21756. int (*map_event)(struct perf_event *event);
  21757. + void (*save_regs)(struct arm_pmu *, struct cpupmu_regs *);
  21758. + void (*restore_regs)(struct arm_pmu *, struct cpupmu_regs *);
  21759. int num_events;
  21760. atomic_t active_events;
  21761. struct mutex reserve_mutex;
  21762. diff -Nur linux-3.14.17/arch/arm/include/asm/psci.h linux-imx6-3.14/arch/arm/include/asm/psci.h
  21763. --- linux-3.14.17/arch/arm/include/asm/psci.h 2014-08-14 03:38:34.000000000 +0200
  21764. +++ linux-imx6-3.14/arch/arm/include/asm/psci.h 2014-09-11 18:05:52.902001607 +0200
  21765. @@ -16,6 +16,10 @@
  21766. #define PSCI_POWER_STATE_TYPE_STANDBY 0
  21767. #define PSCI_POWER_STATE_TYPE_POWER_DOWN 1
  21768. +#define PSCI_POWER_STATE_AFFINITY_LEVEL0 0
  21769. +#define PSCI_POWER_STATE_AFFINITY_LEVEL1 1
  21770. +#define PSCI_POWER_STATE_AFFINITY_LEVEL2 2
  21771. +#define PSCI_POWER_STATE_AFFINITY_LEVEL3 3
  21772. struct psci_power_state {
  21773. u16 id;
  21774. @@ -42,4 +46,12 @@
  21775. static inline bool psci_smp_available(void) { return false; }
  21776. #endif
  21777. +#ifdef CONFIG_ARM_PSCI
  21778. +extern int psci_probe(void);
  21779. +#else
  21780. +static inline int psci_probe(void)
  21781. +{
  21782. + return -ENODEV;
  21783. +}
  21784. +#endif
  21785. #endif /* __ASM_ARM_PSCI_H */
  21786. diff -Nur linux-3.14.17/arch/arm/include/asm/topology.h linux-imx6-3.14/arch/arm/include/asm/topology.h
  21787. --- linux-3.14.17/arch/arm/include/asm/topology.h 2014-08-14 03:38:34.000000000 +0200
  21788. +++ linux-imx6-3.14/arch/arm/include/asm/topology.h 2014-09-11 18:05:52.906001623 +0200
  21789. @@ -26,11 +26,14 @@
  21790. void init_cpu_topology(void);
  21791. void store_cpu_topology(unsigned int cpuid);
  21792. const struct cpumask *cpu_coregroup_mask(int cpu);
  21793. +int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask);
  21794. #else
  21795. static inline void init_cpu_topology(void) { }
  21796. static inline void store_cpu_topology(unsigned int cpuid) { }
  21797. +static inline int cluster_to_logical_mask(unsigned int socket_id,
  21798. + cpumask_t *cluster_mask) { return -EINVAL; }
  21799. #endif
  21800. diff -Nur linux-3.14.17/arch/arm/Kconfig linux-imx6-3.14/arch/arm/Kconfig
  21801. --- linux-3.14.17/arch/arm/Kconfig 2014-08-14 03:38:34.000000000 +0200
  21802. +++ linux-imx6-3.14/arch/arm/Kconfig 2014-09-11 18:05:52.578000311 +0200
  21803. @@ -1216,19 +1216,6 @@
  21804. register of the Cortex-A9 which reduces the linefill issuing
  21805. capabilities of the processor.
  21806. -config PL310_ERRATA_588369
  21807. - bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
  21808. - depends on CACHE_L2X0
  21809. - help
  21810. - The PL310 L2 cache controller implements three types of Clean &
  21811. - Invalidate maintenance operations: by Physical Address
  21812. - (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
  21813. - They are architecturally defined to behave as the execution of a
  21814. - clean operation followed immediately by an invalidate operation,
  21815. - both performing to the same memory location. This functionality
  21816. - is not correctly implemented in PL310 as clean lines are not
  21817. - invalidated as a result of these operations.
  21818. -
  21819. config ARM_ERRATA_643719
  21820. bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
  21821. depends on CPU_V7 && SMP
  21822. @@ -1251,17 +1238,6 @@
  21823. tables. The workaround changes the TLB flushing routines to invalidate
  21824. entries regardless of the ASID.
  21825. -config PL310_ERRATA_727915
  21826. - bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
  21827. - depends on CACHE_L2X0
  21828. - help
  21829. - PL310 implements the Clean & Invalidate by Way L2 cache maintenance
  21830. - operation (offset 0x7FC). This operation runs in background so that
  21831. - PL310 can handle normal accesses while it is in progress. Under very
  21832. - rare circumstances, due to this erratum, write data can be lost when
  21833. - PL310 treats a cacheable write transaction during a Clean &
  21834. - Invalidate by Way operation.
  21835. -
  21836. config ARM_ERRATA_743622
  21837. bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
  21838. depends on CPU_V7
  21839. @@ -1287,21 +1263,6 @@
  21840. operation is received by a CPU before the ICIALLUIS has completed,
  21841. potentially leading to corrupted entries in the cache or TLB.
  21842. -config PL310_ERRATA_753970
  21843. - bool "PL310 errata: cache sync operation may be faulty"
  21844. - depends on CACHE_PL310
  21845. - help
  21846. - This option enables the workaround for the 753970 PL310 (r3p0) erratum.
  21847. -
  21848. - Under some condition the effect of cache sync operation on
  21849. - the store buffer still remains when the operation completes.
  21850. - This means that the store buffer is always asked to drain and
  21851. - this prevents it from merging any further writes. The workaround
  21852. - is to replace the normal offset of cache sync operation (0x730)
  21853. - by another offset targeting an unmapped PL310 register 0x740.
  21854. - This has the same effect as the cache sync operation: store buffer
  21855. - drain and waiting for all buffers empty.
  21856. -
  21857. config ARM_ERRATA_754322
  21858. bool "ARM errata: possible faulty MMU translations following an ASID switch"
  21859. depends on CPU_V7
  21860. @@ -1350,18 +1311,6 @@
  21861. relevant cache maintenance functions and sets a specific bit
  21862. in the diagnostic control register of the SCU.
  21863. -config PL310_ERRATA_769419
  21864. - bool "PL310 errata: no automatic Store Buffer drain"
  21865. - depends on CACHE_L2X0
  21866. - help
  21867. - On revisions of the PL310 prior to r3p2, the Store Buffer does
  21868. - not automatically drain. This can cause normal, non-cacheable
  21869. - writes to be retained when the memory system is idle, leading
  21870. - to suboptimal I/O performance for drivers using coherent DMA.
  21871. - This option adds a write barrier to the cpu_idle loop so that,
  21872. - on systems with an outer cache, the store buffer is drained
  21873. - explicitly.
  21874. -
  21875. config ARM_ERRATA_775420
  21876. bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
  21877. depends on CPU_V7
  21878. @@ -1391,6 +1340,29 @@
  21879. loop buffer may deliver incorrect instructions. This
  21880. workaround disables the loop buffer to avoid the erratum.
  21881. +config ARM_ERRATA_794072
  21882. + bool "ARM errata: A short loop including a DMB instruction might cause a denial of service"
  21883. + depends on CPU_V7 && SMP
  21884. + help
  21885. + This option enables the workaround for the 794072 Cortex-A9
  21886. + (all revisions). A processor which continuously executes a short
  21887. + loop containing a DMB instruction might prevent a CP15 operation
  21888. + broadcast by another processor making further progress, causing
  21889. + a denial of service. This erratum can be worked around by setting
  21890. + bit[4] of the undocumented Diagnostic Control Register to 1.
  21891. +
  21892. +config ARM_ERRATA_761320
  21893. + bool "Full cache line writes to the same memory region from at least two processors might deadlock processor"
  21894. + depends on CPU_V7 && SMP
  21895. + help
  21896. + This option enables the workaround for the 761320 Cortex-A9 (r0..r3).
  21897. + Under very rare circumstances, full cache line writes
  21898. + from (at least) 2 processors on cache lines in hazard with
  21899. + other requests may cause arbitration issues in the SCU,
  21900. + leading to processor deadlock. This erratum can be
  21901. + worked around by setting bit[21] of the undocumented
  21902. + Diagnostic Control Register to 1.
  21903. +
  21904. endmenu
  21905. source "arch/arm/common/Kconfig"
  21906. @@ -1835,6 +1807,7 @@
  21907. range 11 64 if ARCH_SHMOBILE_LEGACY
  21908. default "12" if SOC_AM33XX
  21909. default "9" if SA1111 || ARCH_EFM32
  21910. + default "14" if ARCH_MXC
  21911. default "11"
  21912. help
  21913. The kernel memory allocator divides physically contiguous memory
  21914. diff -Nur linux-3.14.17/arch/arm/kernel/perf_event.c linux-imx6-3.14/arch/arm/kernel/perf_event.c
  21915. --- linux-3.14.17/arch/arm/kernel/perf_event.c 2014-08-14 03:38:34.000000000 +0200
  21916. +++ linux-imx6-3.14/arch/arm/kernel/perf_event.c 2014-09-11 18:05:52.950001797 +0200
  21917. @@ -12,6 +12,7 @@
  21918. */
  21919. #define pr_fmt(fmt) "hw perfevents: " fmt
  21920. +#include <linux/cpumask.h>
  21921. #include <linux/kernel.h>
  21922. #include <linux/platform_device.h>
  21923. #include <linux/pm_runtime.h>
  21924. @@ -86,6 +87,9 @@
  21925. return armpmu_map_cache_event(cache_map, config);
  21926. case PERF_TYPE_RAW:
  21927. return armpmu_map_raw_event(raw_event_mask, config);
  21928. + default:
  21929. + if (event->attr.type >= PERF_TYPE_MAX)
  21930. + return armpmu_map_raw_event(raw_event_mask, config);
  21931. }
  21932. return -ENOENT;
  21933. @@ -159,6 +163,8 @@
  21934. struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
  21935. struct hw_perf_event *hwc = &event->hw;
  21936. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21937. + return;
  21938. /*
  21939. * ARM pmu always has to update the counter, so ignore
  21940. * PERF_EF_UPDATE, see comments in armpmu_start().
  21941. @@ -175,6 +181,8 @@
  21942. struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
  21943. struct hw_perf_event *hwc = &event->hw;
  21944. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21945. + return;
  21946. /*
  21947. * ARM pmu always has to reprogram the period, so ignore
  21948. * PERF_EF_RELOAD, see the comment below.
  21949. @@ -202,6 +210,9 @@
  21950. struct hw_perf_event *hwc = &event->hw;
  21951. int idx = hwc->idx;
  21952. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21953. + return;
  21954. +
  21955. armpmu_stop(event, PERF_EF_UPDATE);
  21956. hw_events->events[idx] = NULL;
  21957. clear_bit(idx, hw_events->used_mask);
  21958. @@ -218,6 +229,10 @@
  21959. int idx;
  21960. int err = 0;
  21961. + /* An event following a process won't be stopped earlier */
  21962. + if (!cpumask_test_cpu(smp_processor_id(), &armpmu->valid_cpus))
  21963. + return 0;
  21964. +
  21965. perf_pmu_disable(event->pmu);
  21966. /* If we don't have a space for the counter then finish early. */
  21967. @@ -419,6 +434,10 @@
  21968. int err = 0;
  21969. atomic_t *active_events = &armpmu->active_events;
  21970. + if (event->cpu != -1 &&
  21971. + !cpumask_test_cpu(event->cpu, &armpmu->valid_cpus))
  21972. + return -ENOENT;
  21973. +
  21974. /* does not support taken branch sampling */
  21975. if (has_branch_stack(event))
  21976. return -EOPNOTSUPP;
  21977. diff -Nur linux-3.14.17/arch/arm/kernel/perf_event_cpu.c linux-imx6-3.14/arch/arm/kernel/perf_event_cpu.c
  21978. --- linux-3.14.17/arch/arm/kernel/perf_event_cpu.c 2014-08-14 03:38:34.000000000 +0200
  21979. +++ linux-imx6-3.14/arch/arm/kernel/perf_event_cpu.c 2014-09-11 18:05:52.950001797 +0200
  21980. @@ -19,6 +19,7 @@
  21981. #define pr_fmt(fmt) "CPU PMU: " fmt
  21982. #include <linux/bitmap.h>
  21983. +#include <linux/cpu_pm.h>
  21984. #include <linux/export.h>
  21985. #include <linux/kernel.h>
  21986. #include <linux/of.h>
  21987. @@ -31,33 +32,36 @@
  21988. #include <asm/pmu.h>
  21989. /* Set at runtime when we know what CPU type we are. */
  21990. -static struct arm_pmu *cpu_pmu;
  21991. +static DEFINE_PER_CPU(struct arm_pmu *, cpu_pmu);
  21992. static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
  21993. static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
  21994. static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
  21995. +static DEFINE_PER_CPU(struct cpupmu_regs, cpu_pmu_regs);
  21996. +
  21997. /*
  21998. * Despite the names, these two functions are CPU-specific and are used
  21999. * by the OProfile/perf code.
  22000. */
  22001. const char *perf_pmu_name(void)
  22002. {
  22003. - if (!cpu_pmu)
  22004. + struct arm_pmu *pmu = per_cpu(cpu_pmu, 0);
  22005. + if (!pmu)
  22006. return NULL;
  22007. - return cpu_pmu->name;
  22008. + return pmu->name;
  22009. }
  22010. EXPORT_SYMBOL_GPL(perf_pmu_name);
  22011. int perf_num_counters(void)
  22012. {
  22013. - int max_events = 0;
  22014. + struct arm_pmu *pmu = per_cpu(cpu_pmu, 0);
  22015. - if (cpu_pmu != NULL)
  22016. - max_events = cpu_pmu->num_events;
  22017. + if (!pmu)
  22018. + return 0;
  22019. - return max_events;
  22020. + return pmu->num_events;
  22021. }
  22022. EXPORT_SYMBOL_GPL(perf_num_counters);
  22023. @@ -75,11 +79,13 @@
  22024. {
  22025. int i, irq, irqs;
  22026. struct platform_device *pmu_device = cpu_pmu->plat_device;
  22027. + int cpu = -1;
  22028. irqs = min(pmu_device->num_resources, num_possible_cpus());
  22029. for (i = 0; i < irqs; ++i) {
  22030. - if (!cpumask_test_and_clear_cpu(i, &cpu_pmu->active_irqs))
  22031. + cpu = cpumask_next(cpu, &cpu_pmu->valid_cpus);
  22032. + if (!cpumask_test_and_clear_cpu(cpu, &cpu_pmu->active_irqs))
  22033. continue;
  22034. irq = platform_get_irq(pmu_device, i);
  22035. if (irq >= 0)
  22036. @@ -91,6 +97,7 @@
  22037. {
  22038. int i, err, irq, irqs;
  22039. struct platform_device *pmu_device = cpu_pmu->plat_device;
  22040. + int cpu = -1;
  22041. if (!pmu_device)
  22042. return -ENODEV;
  22043. @@ -103,6 +110,7 @@
  22044. for (i = 0; i < irqs; ++i) {
  22045. err = 0;
  22046. + cpu = cpumask_next(cpu, &cpu_pmu->valid_cpus);
  22047. irq = platform_get_irq(pmu_device, i);
  22048. if (irq < 0)
  22049. continue;
  22050. @@ -112,7 +120,7 @@
  22051. * assume that we're running on a uniprocessor machine and
  22052. * continue. Otherwise, continue without this interrupt.
  22053. */
  22054. - if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) {
  22055. + if (irq_set_affinity(irq, cpumask_of(cpu)) && irqs > 1) {
  22056. pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
  22057. irq, i);
  22058. continue;
  22059. @@ -127,7 +135,7 @@
  22060. return err;
  22061. }
  22062. - cpumask_set_cpu(i, &cpu_pmu->active_irqs);
  22063. + cpumask_set_cpu(cpu, &cpu_pmu->active_irqs);
  22064. }
  22065. return 0;
  22066. @@ -136,7 +144,7 @@
  22067. static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
  22068. {
  22069. int cpu;
  22070. - for_each_possible_cpu(cpu) {
  22071. + for_each_cpu_mask(cpu, cpu_pmu->valid_cpus) {
  22072. struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu);
  22073. events->events = per_cpu(hw_events, cpu);
  22074. events->used_mask = per_cpu(used_mask, cpu);
  22075. @@ -149,7 +157,7 @@
  22076. /* Ensure the PMU has sane values out of reset. */
  22077. if (cpu_pmu->reset)
  22078. - on_each_cpu(cpu_pmu->reset, cpu_pmu, 1);
  22079. + on_each_cpu_mask(&cpu_pmu->valid_cpus, cpu_pmu->reset, cpu_pmu, 1);
  22080. }
  22081. /*
  22082. @@ -161,21 +169,46 @@
  22083. static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
  22084. void *hcpu)
  22085. {
  22086. + struct arm_pmu *pmu = per_cpu(cpu_pmu, (long)hcpu);
  22087. +
  22088. if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
  22089. return NOTIFY_DONE;
  22090. - if (cpu_pmu && cpu_pmu->reset)
  22091. - cpu_pmu->reset(cpu_pmu);
  22092. + if (pmu && pmu->reset)
  22093. + pmu->reset(pmu);
  22094. else
  22095. return NOTIFY_DONE;
  22096. return NOTIFY_OK;
  22097. }
  22098. +static int cpu_pmu_pm_notify(struct notifier_block *b,
  22099. + unsigned long action, void *hcpu)
  22100. +{
  22101. + int cpu = smp_processor_id();
  22102. + struct arm_pmu *pmu = per_cpu(cpu_pmu, cpu);
  22103. + struct cpupmu_regs *pmuregs = &per_cpu(cpu_pmu_regs, cpu);
  22104. +
  22105. + if (!pmu)
  22106. + return NOTIFY_DONE;
  22107. +
  22108. + if (action == CPU_PM_ENTER && pmu->save_regs) {
  22109. + pmu->save_regs(pmu, pmuregs);
  22110. + } else if (action == CPU_PM_EXIT && pmu->restore_regs) {
  22111. + pmu->restore_regs(pmu, pmuregs);
  22112. + }
  22113. +
  22114. + return NOTIFY_OK;
  22115. +}
  22116. +
  22117. static struct notifier_block cpu_pmu_hotplug_notifier = {
  22118. .notifier_call = cpu_pmu_notify,
  22119. };
  22120. +static struct notifier_block cpu_pmu_pm_notifier = {
  22121. + .notifier_call = cpu_pmu_pm_notify,
  22122. +};
  22123. +
  22124. /*
  22125. * PMU platform driver and devicetree bindings.
  22126. */
  22127. @@ -247,6 +280,9 @@
  22128. }
  22129. }
  22130. + /* assume PMU support all the CPUs in this case */
  22131. + cpumask_setall(&pmu->valid_cpus);
  22132. +
  22133. put_cpu();
  22134. return ret;
  22135. }
  22136. @@ -254,15 +290,10 @@
  22137. static int cpu_pmu_device_probe(struct platform_device *pdev)
  22138. {
  22139. const struct of_device_id *of_id;
  22140. - const int (*init_fn)(struct arm_pmu *);
  22141. struct device_node *node = pdev->dev.of_node;
  22142. struct arm_pmu *pmu;
  22143. - int ret = -ENODEV;
  22144. -
  22145. - if (cpu_pmu) {
  22146. - pr_info("attempt to register multiple PMU devices!");
  22147. - return -ENOSPC;
  22148. - }
  22149. + int ret = 0;
  22150. + int cpu;
  22151. pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL);
  22152. if (!pmu) {
  22153. @@ -271,8 +302,28 @@
  22154. }
  22155. if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
  22156. - init_fn = of_id->data;
  22157. - ret = init_fn(pmu);
  22158. + smp_call_func_t init_fn = (smp_call_func_t)of_id->data;
  22159. + struct device_node *ncluster;
  22160. + int cluster = -1;
  22161. + cpumask_t sibling_mask;
  22162. +
  22163. + ncluster = of_parse_phandle(node, "cluster", 0);
  22164. + if (ncluster) {
  22165. + int len;
  22166. + const u32 *hwid;
  22167. + hwid = of_get_property(ncluster, "reg", &len);
  22168. + if (hwid && len == 4)
  22169. + cluster = be32_to_cpup(hwid);
  22170. + }
  22171. + /* set sibling mask to all cpu mask if socket is not specified */
  22172. + if (cluster == -1 ||
  22173. + cluster_to_logical_mask(cluster, &sibling_mask))
  22174. + cpumask_setall(&sibling_mask);
  22175. +
  22176. + smp_call_function_any(&sibling_mask, init_fn, pmu, 1);
  22177. +
  22178. + /* now set the valid_cpus after init */
  22179. + cpumask_copy(&pmu->valid_cpus, &sibling_mask);
  22180. } else {
  22181. ret = probe_current_pmu(pmu);
  22182. }
  22183. @@ -282,10 +333,12 @@
  22184. goto out_free;
  22185. }
  22186. - cpu_pmu = pmu;
  22187. - cpu_pmu->plat_device = pdev;
  22188. - cpu_pmu_init(cpu_pmu);
  22189. - ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW);
  22190. + for_each_cpu_mask(cpu, pmu->valid_cpus)
  22191. + per_cpu(cpu_pmu, cpu) = pmu;
  22192. +
  22193. + pmu->plat_device = pdev;
  22194. + cpu_pmu_init(pmu);
  22195. + ret = armpmu_register(pmu, -1);
  22196. if (!ret)
  22197. return 0;
  22198. @@ -314,9 +367,17 @@
  22199. if (err)
  22200. return err;
  22201. + err = cpu_pm_register_notifier(&cpu_pmu_pm_notifier);
  22202. + if (err) {
  22203. + unregister_cpu_notifier(&cpu_pmu_hotplug_notifier);
  22204. + return err;
  22205. + }
  22206. +
  22207. err = platform_driver_register(&cpu_pmu_driver);
  22208. - if (err)
  22209. + if (err) {
  22210. + cpu_pm_unregister_notifier(&cpu_pmu_pm_notifier);
  22211. unregister_cpu_notifier(&cpu_pmu_hotplug_notifier);
  22212. + }
  22213. return err;
  22214. }
  22215. diff -Nur linux-3.14.17/arch/arm/kernel/perf_event_v7.c linux-imx6-3.14/arch/arm/kernel/perf_event_v7.c
  22216. --- linux-3.14.17/arch/arm/kernel/perf_event_v7.c 2014-08-14 03:38:34.000000000 +0200
  22217. +++ linux-imx6-3.14/arch/arm/kernel/perf_event_v7.c 2014-09-11 18:05:52.950001797 +0200
  22218. @@ -950,6 +950,51 @@
  22219. }
  22220. #endif
  22221. +static void armv7pmu_save_regs(struct arm_pmu *cpu_pmu,
  22222. + struct cpupmu_regs *regs)
  22223. +{
  22224. + unsigned int cnt;
  22225. + asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (regs->pmc));
  22226. + if (!(regs->pmc & ARMV7_PMNC_E))
  22227. + return;
  22228. +
  22229. + asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (regs->pmcntenset));
  22230. + asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r" (regs->pmuseren));
  22231. + asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (regs->pmintenset));
  22232. + asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (regs->pmxevtcnt[0]));
  22233. + for (cnt = ARMV7_IDX_COUNTER0;
  22234. + cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  22235. + armv7_pmnc_select_counter(cnt);
  22236. + asm volatile("mrc p15, 0, %0, c9, c13, 1"
  22237. + : "=r"(regs->pmxevttype[cnt]));
  22238. + asm volatile("mrc p15, 0, %0, c9, c13, 2"
  22239. + : "=r"(regs->pmxevtcnt[cnt]));
  22240. + }
  22241. + return;
  22242. +}
  22243. +
  22244. +static void armv7pmu_restore_regs(struct arm_pmu *cpu_pmu,
  22245. + struct cpupmu_regs *regs)
  22246. +{
  22247. + unsigned int cnt;
  22248. + if (!(regs->pmc & ARMV7_PMNC_E))
  22249. + return;
  22250. +
  22251. + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (regs->pmcntenset));
  22252. + asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (regs->pmuseren));
  22253. + asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (regs->pmintenset));
  22254. + asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (regs->pmxevtcnt[0]));
  22255. + for (cnt = ARMV7_IDX_COUNTER0;
  22256. + cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  22257. + armv7_pmnc_select_counter(cnt);
  22258. + asm volatile("mcr p15, 0, %0, c9, c13, 1"
  22259. + : : "r"(regs->pmxevttype[cnt]));
  22260. + asm volatile("mcr p15, 0, %0, c9, c13, 2"
  22261. + : : "r"(regs->pmxevtcnt[cnt]));
  22262. + }
  22263. + asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (regs->pmc));
  22264. +}
  22265. +
  22266. static void armv7pmu_enable_event(struct perf_event *event)
  22267. {
  22268. unsigned long flags;
  22269. @@ -1223,6 +1268,8 @@
  22270. cpu_pmu->start = armv7pmu_start;
  22271. cpu_pmu->stop = armv7pmu_stop;
  22272. cpu_pmu->reset = armv7pmu_reset;
  22273. + cpu_pmu->save_regs = armv7pmu_save_regs;
  22274. + cpu_pmu->restore_regs = armv7pmu_restore_regs;
  22275. cpu_pmu->max_period = (1LLU << 32) - 1;
  22276. };
  22277. @@ -1240,7 +1287,7 @@
  22278. static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
  22279. {
  22280. armv7pmu_init(cpu_pmu);
  22281. - cpu_pmu->name = "ARMv7 Cortex-A8";
  22282. + cpu_pmu->name = "ARMv7_Cortex_A8";
  22283. cpu_pmu->map_event = armv7_a8_map_event;
  22284. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22285. return 0;
  22286. @@ -1249,7 +1296,7 @@
  22287. static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
  22288. {
  22289. armv7pmu_init(cpu_pmu);
  22290. - cpu_pmu->name = "ARMv7 Cortex-A9";
  22291. + cpu_pmu->name = "ARMv7_Cortex_A9";
  22292. cpu_pmu->map_event = armv7_a9_map_event;
  22293. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22294. return 0;
  22295. @@ -1258,7 +1305,7 @@
  22296. static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
  22297. {
  22298. armv7pmu_init(cpu_pmu);
  22299. - cpu_pmu->name = "ARMv7 Cortex-A5";
  22300. + cpu_pmu->name = "ARMv7_Cortex_A5";
  22301. cpu_pmu->map_event = armv7_a5_map_event;
  22302. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22303. return 0;
  22304. @@ -1267,7 +1314,7 @@
  22305. static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
  22306. {
  22307. armv7pmu_init(cpu_pmu);
  22308. - cpu_pmu->name = "ARMv7 Cortex-A15";
  22309. + cpu_pmu->name = "ARMv7_Cortex_A15";
  22310. cpu_pmu->map_event = armv7_a15_map_event;
  22311. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22312. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  22313. @@ -1277,7 +1324,7 @@
  22314. static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
  22315. {
  22316. armv7pmu_init(cpu_pmu);
  22317. - cpu_pmu->name = "ARMv7 Cortex-A7";
  22318. + cpu_pmu->name = "ARMv7_Cortex_A7";
  22319. cpu_pmu->map_event = armv7_a7_map_event;
  22320. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  22321. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  22322. diff -Nur linux-3.14.17/arch/arm/kernel/process.c linux-imx6-3.14/arch/arm/kernel/process.c
  22323. --- linux-3.14.17/arch/arm/kernel/process.c 2014-08-14 03:38:34.000000000 +0200
  22324. +++ linux-imx6-3.14/arch/arm/kernel/process.c 2014-09-11 18:05:52.950001797 +0200
  22325. @@ -172,8 +172,10 @@
  22326. */
  22327. void arch_cpu_idle(void)
  22328. {
  22329. + idle_notifier_call_chain(IDLE_START);
  22330. if (cpuidle_idle_call())
  22331. default_idle();
  22332. + idle_notifier_call_chain(IDLE_END);
  22333. }
  22334. /*
  22335. diff -Nur linux-3.14.17/arch/arm/kernel/psci.c linux-imx6-3.14/arch/arm/kernel/psci.c
  22336. --- linux-3.14.17/arch/arm/kernel/psci.c 2014-08-14 03:38:34.000000000 +0200
  22337. +++ linux-imx6-3.14/arch/arm/kernel/psci.c 2014-09-11 18:05:52.950001797 +0200
  22338. @@ -42,6 +42,7 @@
  22339. #define PSCI_RET_EOPNOTSUPP -1
  22340. #define PSCI_RET_EINVAL -2
  22341. #define PSCI_RET_EPERM -3
  22342. +#define PSCI_RET_EALREADYON -4
  22343. static int psci_to_linux_errno(int errno)
  22344. {
  22345. @@ -54,6 +55,8 @@
  22346. return -EINVAL;
  22347. case PSCI_RET_EPERM:
  22348. return -EPERM;
  22349. + case PSCI_RET_EALREADYON:
  22350. + return -EAGAIN;
  22351. };
  22352. return -EINVAL;
  22353. @@ -153,7 +156,7 @@
  22354. return psci_to_linux_errno(err);
  22355. }
  22356. -static const struct of_device_id psci_of_match[] __initconst = {
  22357. +static const struct of_device_id psci_of_match[] = {
  22358. { .compatible = "arm,psci", },
  22359. {},
  22360. };
  22361. @@ -208,3 +211,16 @@
  22362. of_node_put(np);
  22363. return;
  22364. }
  22365. +
  22366. +int psci_probe(void)
  22367. +{
  22368. + struct device_node *np;
  22369. + int ret = -ENODEV;
  22370. +
  22371. + np = of_find_matching_node(NULL, psci_of_match);
  22372. + if (np)
  22373. + ret = 0;
  22374. +
  22375. + of_node_put(np);
  22376. + return ret;
  22377. +}
  22378. diff -Nur linux-3.14.17/arch/arm/kernel/setup.c linux-imx6-3.14/arch/arm/kernel/setup.c
  22379. --- linux-3.14.17/arch/arm/kernel/setup.c 2014-08-14 03:38:34.000000000 +0200
  22380. +++ linux-imx6-3.14/arch/arm/kernel/setup.c 2014-09-11 18:05:52.950001797 +0200
  22381. @@ -273,6 +273,19 @@
  22382. int aliasing_icache;
  22383. unsigned int id_reg, num_sets, line_size;
  22384. +#ifdef CONFIG_BIG_LITTLE
  22385. + /*
  22386. + * We expect a combination of Cortex-A15 and Cortex-A7 cores.
  22387. + * A7 = VIPT aliasing I-cache
  22388. + * A15 = PIPT (non-aliasing) I-cache
  22389. + * To cater for this discrepancy, let's assume aliasing I-cache
  22390. + * all the time. This means unneeded extra work on the A15 but
  22391. + * only ptrace is affected which is not performance critical.
  22392. + */
  22393. + if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc0f0)
  22394. + return 1;
  22395. +#endif
  22396. +
  22397. /* PIPT caches never alias. */
  22398. if (icache_is_pipt())
  22399. return 0;
  22400. diff -Nur linux-3.14.17/arch/arm/kernel/topology.c linux-imx6-3.14/arch/arm/kernel/topology.c
  22401. --- linux-3.14.17/arch/arm/kernel/topology.c 2014-08-14 03:38:34.000000000 +0200
  22402. +++ linux-imx6-3.14/arch/arm/kernel/topology.c 2014-09-11 18:05:52.970001878 +0200
  22403. @@ -267,6 +267,33 @@
  22404. }
  22405. /*
  22406. + * cluster_to_logical_mask - return cpu logical mask of CPUs in a cluster
  22407. + * @socket_id: cluster HW identifier
  22408. + * @cluster_mask: the cpumask location to be initialized, modified by the
  22409. + * function only if return value == 0
  22410. + *
  22411. + * Return:
  22412. + *
  22413. + * 0 on success
  22414. + * -EINVAL if cluster_mask is NULL or there is no record matching socket_id
  22415. + */
  22416. +int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask)
  22417. +{
  22418. + int cpu;
  22419. +
  22420. + if (!cluster_mask)
  22421. + return -EINVAL;
  22422. +
  22423. + for_each_online_cpu(cpu)
  22424. + if (socket_id == topology_physical_package_id(cpu)) {
  22425. + cpumask_copy(cluster_mask, topology_core_cpumask(cpu));
  22426. + return 0;
  22427. + }
  22428. +
  22429. + return -EINVAL;
  22430. +}
  22431. +
  22432. +/*
  22433. * init_cpu_topology is called at boot when only one cpu is running
  22434. * which prevent simultaneous write access to cpu_topology array
  22435. */
  22436. diff -Nur linux-3.14.17/arch/arm/lib/bitops.h linux-imx6-3.14/arch/arm/lib/bitops.h
  22437. --- linux-3.14.17/arch/arm/lib/bitops.h 2014-08-14 03:38:34.000000000 +0200
  22438. +++ linux-imx6-3.14/arch/arm/lib/bitops.h 2014-09-11 18:05:52.978001911 +0200
  22439. @@ -37,6 +37,11 @@
  22440. add r1, r1, r0, lsl #2 @ Get word offset
  22441. mov r3, r2, lsl r3 @ create mask
  22442. smp_dmb
  22443. +#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
  22444. + .arch_extension mp
  22445. + ALT_SMP(W(pldw) [r1])
  22446. + ALT_UP(W(nop))
  22447. +#endif
  22448. 1: ldrex r2, [r1]
  22449. ands r0, r2, r3 @ save old value of bit
  22450. \instr r2, r2, r3 @ toggle bit
  22451. diff -Nur linux-3.14.17/arch/arm/mach-berlin/berlin.c linux-imx6-3.14/arch/arm/mach-berlin/berlin.c
  22452. --- linux-3.14.17/arch/arm/mach-berlin/berlin.c 2014-08-14 03:38:34.000000000 +0200
  22453. +++ linux-imx6-3.14/arch/arm/mach-berlin/berlin.c 2014-09-11 18:05:53.170002677 +0200
  22454. @@ -24,7 +24,7 @@
  22455. * with DT probing for L2CCs, berlin_init_machine can be removed.
  22456. * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
  22457. */
  22458. - l2x0_of_init(0x70c00000, 0xfeffffff);
  22459. + l2x0_of_init(0x30c00000, 0xfeffffff);
  22460. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  22461. }
  22462. diff -Nur linux-3.14.17/arch/arm/mach-cns3xxx/core.c linux-imx6-3.14/arch/arm/mach-cns3xxx/core.c
  22463. --- linux-3.14.17/arch/arm/mach-cns3xxx/core.c 2014-08-14 03:38:34.000000000 +0200
  22464. +++ linux-imx6-3.14/arch/arm/mach-cns3xxx/core.c 2014-09-11 18:05:53.178002711 +0200
  22465. @@ -240,9 +240,9 @@
  22466. *
  22467. * 1 cycle of latency for setup, read and write accesses
  22468. */
  22469. - val = readl(base + L2X0_TAG_LATENCY_CTRL);
  22470. + val = readl(base + L310_TAG_LATENCY_CTRL);
  22471. val &= 0xfffff888;
  22472. - writel(val, base + L2X0_TAG_LATENCY_CTRL);
  22473. + writel(val, base + L310_TAG_LATENCY_CTRL);
  22474. /*
  22475. * Data RAM Control register
  22476. @@ -253,12 +253,12 @@
  22477. *
  22478. * 1 cycle of latency for setup, read and write accesses
  22479. */
  22480. - val = readl(base + L2X0_DATA_LATENCY_CTRL);
  22481. + val = readl(base + L310_DATA_LATENCY_CTRL);
  22482. val &= 0xfffff888;
  22483. - writel(val, base + L2X0_DATA_LATENCY_CTRL);
  22484. + writel(val, base + L310_DATA_LATENCY_CTRL);
  22485. /* 32 KiB, 8-way, parity disable */
  22486. - l2x0_init(base, 0x00540000, 0xfe000fff);
  22487. + l2x0_init(base, 0x00500000, 0xfe0f0fff);
  22488. }
  22489. #endif /* CONFIG_CACHE_L2X0 */
  22490. diff -Nur linux-3.14.17/arch/arm/mach-exynos/common.c linux-imx6-3.14/arch/arm/mach-exynos/common.c
  22491. --- linux-3.14.17/arch/arm/mach-exynos/common.c 2014-08-14 03:38:34.000000000 +0200
  22492. +++ linux-imx6-3.14/arch/arm/mach-exynos/common.c 2014-09-11 18:05:53.238002950 +0200
  22493. @@ -45,9 +45,6 @@
  22494. #include "common.h"
  22495. #include "regs-pmu.h"
  22496. -#define L2_AUX_VAL 0x7C470001
  22497. -#define L2_AUX_MASK 0xC200ffff
  22498. -
  22499. static const char name_exynos4210[] = "EXYNOS4210";
  22500. static const char name_exynos4212[] = "EXYNOS4212";
  22501. static const char name_exynos4412[] = "EXYNOS4412";
  22502. @@ -400,7 +397,7 @@
  22503. {
  22504. int ret;
  22505. - ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
  22506. + ret = l2x0_of_init(0x3c400001, 0xc20fffff);
  22507. if (ret)
  22508. return ret;
  22509. diff -Nur linux-3.14.17/arch/arm/mach-highbank/highbank.c linux-imx6-3.14/arch/arm/mach-highbank/highbank.c
  22510. --- linux-3.14.17/arch/arm/mach-highbank/highbank.c 2014-08-14 03:38:34.000000000 +0200
  22511. +++ linux-imx6-3.14/arch/arm/mach-highbank/highbank.c 2014-09-11 18:05:53.274003094 +0200
  22512. @@ -20,7 +20,7 @@
  22513. #include <linux/input.h>
  22514. #include <linux/io.h>
  22515. #include <linux/irqchip.h>
  22516. -#include <linux/mailbox.h>
  22517. +#include <linux/pl320-ipc.h>
  22518. #include <linux/of.h>
  22519. #include <linux/of_irq.h>
  22520. #include <linux/of_platform.h>
  22521. @@ -51,11 +51,13 @@
  22522. }
  22523. -static void highbank_l2x0_disable(void)
  22524. +static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
  22525. {
  22526. - outer_flush_all();
  22527. - /* Disable PL310 L2 Cache controller */
  22528. - highbank_smc1(0x102, 0x0);
  22529. + if (reg == L2X0_CTRL)
  22530. + highbank_smc1(0x102, val);
  22531. + else
  22532. + WARN_ONCE(1, "Highbank L2C310: ignoring write to reg 0x%x\n",
  22533. + reg);
  22534. }
  22535. static void __init highbank_init_irq(void)
  22536. @@ -66,11 +68,9 @@
  22537. highbank_scu_map_io();
  22538. /* Enable PL310 L2 Cache controller */
  22539. - if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
  22540. - of_find_compatible_node(NULL, NULL, "arm,pl310-cache")) {
  22541. - highbank_smc1(0x102, 0x1);
  22542. - l2x0_of_init(0, ~0UL);
  22543. - outer_cache.disable = highbank_l2x0_disable;
  22544. + if (IS_ENABLED(CONFIG_CACHE_L2X0)) {
  22545. + outer_cache.write_sec = highbank_l2c310_write_sec;
  22546. + l2x0_of_init(0, ~0);
  22547. }
  22548. }
  22549. diff -Nur linux-3.14.17/arch/arm/mach-imx/anatop.c linux-imx6-3.14/arch/arm/mach-imx/anatop.c
  22550. --- linux-3.14.17/arch/arm/mach-imx/anatop.c 2014-08-14 03:38:34.000000000 +0200
  22551. +++ linux-imx6-3.14/arch/arm/mach-imx/anatop.c 2014-09-11 18:05:53.278003110 +0200
  22552. @@ -9,6 +9,7 @@
  22553. * http://www.gnu.org/copyleft/gpl.html
  22554. */
  22555. +#include <linux/delay.h>
  22556. #include <linux/err.h>
  22557. #include <linux/io.h>
  22558. #include <linux/of.h>
  22559. @@ -35,6 +36,10 @@
  22560. #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000
  22561. #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000
  22562. +#define ANADIG_REG_TARG_MASK 0x1f
  22563. +#define ANADIG_REG1_TARG_SHIFT 9 /* VDDPU */
  22564. +#define ANADIG_REG2_TARG_SHIFT 18 /* VDDSOC */
  22565. +
  22566. static struct regmap *anatop;
  22567. static void imx_anatop_enable_weak2p5(bool enable)
  22568. @@ -78,6 +83,28 @@
  22569. BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
  22570. }
  22571. +void imx_anatop_pu_enable(bool enable)
  22572. +{
  22573. + u32 val;
  22574. +
  22575. + regmap_read(anatop, ANADIG_REG_CORE, &val);
  22576. + val &= ANADIG_REG_TARG_MASK << ANADIG_REG2_TARG_SHIFT;
  22577. + /*
  22578. + * set pu regulator only in LDO_BYPASS mode(know by VDDSOC reg 0x1f),
  22579. + * else handled by anatop regulator driver.
  22580. + */
  22581. + if (((val >> (ANADIG_REG2_TARG_SHIFT)) & ANADIG_REG_TARG_MASK)
  22582. + == ANADIG_REG_TARG_MASK) {
  22583. + if (enable) {
  22584. + regmap_write(anatop, ANADIG_REG_CORE + REG_SET,
  22585. + ANADIG_REG_TARG_MASK << ANADIG_REG1_TARG_SHIFT);
  22586. + udelay(70); /* bypass need 70us to be stable */
  22587. + } else {
  22588. + regmap_write(anatop, ANADIG_REG_CORE + REG_CLR,
  22589. + ANADIG_REG_TARG_MASK << ANADIG_REG1_TARG_SHIFT);
  22590. + }
  22591. + }
  22592. +}
  22593. void __init imx_init_revision_from_anatop(void)
  22594. {
  22595. struct device_node *np;
  22596. @@ -104,6 +131,15 @@
  22597. case 2:
  22598. revision = IMX_CHIP_REVISION_1_2;
  22599. break;
  22600. + case 3:
  22601. + revision = IMX_CHIP_REVISION_1_3;
  22602. + break;
  22603. + case 4:
  22604. + revision = IMX_CHIP_REVISION_1_4;
  22605. + break;
  22606. + case 5:
  22607. + revision = IMX_CHIP_REVISION_1_5;
  22608. + break;
  22609. default:
  22610. revision = IMX_CHIP_REVISION_UNKNOWN;
  22611. }
  22612. diff -Nur linux-3.14.17/arch/arm/mach-imx/busfreq_ddr3.c linux-imx6-3.14/arch/arm/mach-imx/busfreq_ddr3.c
  22613. --- linux-3.14.17/arch/arm/mach-imx/busfreq_ddr3.c 1970-01-01 01:00:00.000000000 +0100
  22614. +++ linux-imx6-3.14/arch/arm/mach-imx/busfreq_ddr3.c 2014-09-11 18:05:53.278003110 +0200
  22615. @@ -0,0 +1,471 @@
  22616. +/*
  22617. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  22618. + */
  22619. +
  22620. +/*
  22621. + * The code contained herein is licensed under the GNU General Public
  22622. + * License. You may obtain a copy of the GNU General Public License
  22623. + * Version 2 or later at the following locations:
  22624. + *
  22625. + * http://www.opensource.org/licenses/gpl-license.html
  22626. + * http://www.gnu.org/copyleft/gpl.html
  22627. + */
  22628. +
  22629. +/*!
  22630. + * @file busfreq_ddr3.c
  22631. + *
  22632. + * @brief iMX6 DDR3 frequency change specific file.
  22633. + *
  22634. + * @ingroup PM
  22635. + */
  22636. +#include <asm/cacheflush.h>
  22637. +#include <asm/fncpy.h>
  22638. +#include <asm/io.h>
  22639. +#include <asm/mach/map.h>
  22640. +#include <asm/mach-types.h>
  22641. +#include <asm/tlb.h>
  22642. +#include <linux/clk.h>
  22643. +#include <linux/cpumask.h>
  22644. +#include <linux/delay.h>
  22645. +#include <linux/genalloc.h>
  22646. +#include <linux/interrupt.h>
  22647. +#include <linux/irqchip/arm-gic.h>
  22648. +#include <linux/kernel.h>
  22649. +#include <linux/mutex.h>
  22650. +#include <linux/of.h>
  22651. +#include <linux/of_address.h>
  22652. +#include <linux/of_device.h>
  22653. +#include <linux/platform_device.h>
  22654. +#include <linux/proc_fs.h>
  22655. +#include <linux/sched.h>
  22656. +#include <linux/smp.h>
  22657. +
  22658. +#include "hardware.h"
  22659. +
  22660. +/* DDR settings */
  22661. +static unsigned long (*iram_ddr_settings)[2];
  22662. +static unsigned long (*normal_mmdc_settings)[2];
  22663. +static unsigned long (*iram_iomux_settings)[2];
  22664. +static void __iomem *mmdc_base;
  22665. +static void __iomem *iomux_base;
  22666. +static void __iomem *ccm_base;
  22667. +static void __iomem *l2_base;
  22668. +static void __iomem *gic_dist_base;
  22669. +static u32 *irqs_used;
  22670. +
  22671. +static void *ddr_freq_change_iram_base;
  22672. +static int ddr_settings_size;
  22673. +static int iomux_settings_size;
  22674. +static volatile unsigned int cpus_in_wfe;
  22675. +static volatile bool wait_for_ddr_freq_update;
  22676. +static int curr_ddr_rate;
  22677. +
  22678. +void (*mx6_change_ddr_freq)(u32 freq, void *ddr_settings,
  22679. + bool dll_mode, void *iomux_offsets) = NULL;
  22680. +
  22681. +extern unsigned int ddr_med_rate;
  22682. +extern unsigned int ddr_normal_rate;
  22683. +extern int low_bus_freq_mode;
  22684. +extern int audio_bus_freq_mode;
  22685. +extern void mx6_ddr3_freq_change(u32 freq, void *ddr_settings,
  22686. + bool dll_mode, void *iomux_offsets);
  22687. +
  22688. +#define MIN_DLL_ON_FREQ 333000000
  22689. +#define MAX_DLL_OFF_FREQ 125000000
  22690. +#define DDR_FREQ_CHANGE_SIZE 0x2000
  22691. +
  22692. +unsigned long ddr3_dll_mx6q[][2] = {
  22693. + {0x0c, 0x0},
  22694. + {0x10, 0x0},
  22695. + {0x1C, 0x04088032},
  22696. + {0x1C, 0x0408803a},
  22697. + {0x1C, 0x08408030},
  22698. + {0x1C, 0x08408038},
  22699. + {0x818, 0x0},
  22700. +};
  22701. +
  22702. +unsigned long ddr3_calibration[][2] = {
  22703. + {0x83c, 0x0},
  22704. + {0x840, 0x0},
  22705. + {0x483c, 0x0},
  22706. + {0x4840, 0x0},
  22707. + {0x848, 0x0},
  22708. + {0x4848, 0x0},
  22709. + {0x850, 0x0},
  22710. + {0x4850, 0x0},
  22711. +};
  22712. +
  22713. +unsigned long ddr3_dll_mx6dl[][2] = {
  22714. + {0x0c, 0x0},
  22715. + {0x10, 0x0},
  22716. + {0x1C, 0x04008032},
  22717. + {0x1C, 0x0400803a},
  22718. + {0x1C, 0x07208030},
  22719. + {0x1C, 0x07208038},
  22720. + {0x818, 0x0},
  22721. +};
  22722. +
  22723. +unsigned long iomux_offsets_mx6q[][2] = {
  22724. + {0x5A8, 0x0},
  22725. + {0x5B0, 0x0},
  22726. + {0x524, 0x0},
  22727. + {0x51C, 0x0},
  22728. + {0x518, 0x0},
  22729. + {0x50C, 0x0},
  22730. + {0x5B8, 0x0},
  22731. + {0x5C0, 0x0},
  22732. +};
  22733. +
  22734. +unsigned long iomux_offsets_mx6dl[][2] = {
  22735. + {0x4BC, 0x0},
  22736. + {0x4C0, 0x0},
  22737. + {0x4C4, 0x0},
  22738. + {0x4C8, 0x0},
  22739. + {0x4CC, 0x0},
  22740. + {0x4D0, 0x0},
  22741. + {0x4D4, 0x0},
  22742. + {0x4D8, 0x0},
  22743. +};
  22744. +
  22745. +unsigned long ddr3_400[][2] = {
  22746. + {0x83c, 0x42490249},
  22747. + {0x840, 0x02470247},
  22748. + {0x483c, 0x42570257},
  22749. + {0x4840, 0x02400240},
  22750. + {0x848, 0x4039363C},
  22751. + {0x4848, 0x3A39333F},
  22752. + {0x850, 0x38414441},
  22753. + {0x4850, 0x472D4833}
  22754. +};
  22755. +
  22756. +int can_change_ddr_freq(void)
  22757. +{
  22758. + return 1;
  22759. +}
  22760. +
  22761. +/*
  22762. + * each active core apart from the one changing
  22763. + * the DDR frequency will execute this function.
  22764. + * the rest of the cores have to remain in WFE
  22765. + * state until the frequency is changed.
  22766. + */
  22767. +irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
  22768. +{
  22769. + u32 me = smp_processor_id();
  22770. +
  22771. + *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
  22772. +
  22773. + while (wait_for_ddr_freq_update)
  22774. + wfe();
  22775. +
  22776. + *((char *)(&cpus_in_wfe) + (u8)me) = 0;
  22777. +
  22778. + return IRQ_HANDLED;
  22779. +}
  22780. +
  22781. +/* change the DDR frequency. */
  22782. +int update_ddr_freq(int ddr_rate)
  22783. +{
  22784. + int i, j;
  22785. + unsigned int reg;
  22786. + bool dll_off = false;
  22787. + unsigned int online_cpus = 0;
  22788. + int cpu = 0;
  22789. + int me;
  22790. +
  22791. + if (!can_change_ddr_freq())
  22792. + return -1;
  22793. +
  22794. + if (ddr_rate == curr_ddr_rate)
  22795. + return 0;
  22796. +
  22797. + pr_debug("Bus freq set to %d start...\n", ddr_rate);
  22798. +
  22799. + if (low_bus_freq_mode || audio_bus_freq_mode)
  22800. + dll_off = true;
  22801. +
  22802. + iram_ddr_settings[0][0] = ddr_settings_size;
  22803. + iram_iomux_settings[0][0] = iomux_settings_size;
  22804. + if (ddr_rate == ddr_med_rate && cpu_is_imx6q()) {
  22805. + for (i = 0; i < ARRAY_SIZE(ddr3_dll_mx6q); i++) {
  22806. + iram_ddr_settings[i + 1][0] =
  22807. + normal_mmdc_settings[i][0];
  22808. + iram_ddr_settings[i + 1][1] =
  22809. + normal_mmdc_settings[i][1];
  22810. + }
  22811. + for (j = 0, i = ARRAY_SIZE(ddr3_dll_mx6q);
  22812. + i < iram_ddr_settings[0][0]; j++, i++) {
  22813. + iram_ddr_settings[i + 1][0] =
  22814. + ddr3_400[j][0];
  22815. + iram_ddr_settings[i + 1][1] =
  22816. + ddr3_400[j][1];
  22817. + }
  22818. + } else if (ddr_rate == ddr_normal_rate) {
  22819. + for (i = 0; i < iram_ddr_settings[0][0]; i++) {
  22820. + iram_ddr_settings[i + 1][0] =
  22821. + normal_mmdc_settings[i][0];
  22822. + iram_ddr_settings[i + 1][1] =
  22823. + normal_mmdc_settings[i][1];
  22824. + }
  22825. + }
  22826. +
  22827. + /* ensure that all Cores are in WFE. */
  22828. + local_irq_disable();
  22829. +
  22830. + me = smp_processor_id();
  22831. +
  22832. + *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
  22833. + wait_for_ddr_freq_update = true;
  22834. + for_each_online_cpu(cpu) {
  22835. + *((char *)(&online_cpus) + (u8)cpu) = 0xff;
  22836. + if (cpu != me) {
  22837. + /* set the interrupt to be pending in the GIC. */
  22838. + reg = 1 << (irqs_used[cpu] % 32);
  22839. + writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET
  22840. + + (irqs_used[cpu] / 32) * 4);
  22841. + }
  22842. + }
  22843. + while (cpus_in_wfe != online_cpus)
  22844. + udelay(5);
  22845. +
  22846. + /*
  22847. + * Flush the TLB, to ensure no TLB maintenance occurs
  22848. + * when DDR is in self-refresh.
  22849. + */
  22850. + local_flush_tlb_all();
  22851. + /* Now we can change the DDR frequency. */
  22852. + mx6_change_ddr_freq(ddr_rate, iram_ddr_settings,
  22853. + dll_off, iram_iomux_settings);
  22854. +
  22855. + curr_ddr_rate = ddr_rate;
  22856. +
  22857. + /* DDR frequency change is done . */
  22858. + wait_for_ddr_freq_update = false;
  22859. +
  22860. + /* wake up all the cores. */
  22861. + sev();
  22862. +
  22863. + *((char *)(&cpus_in_wfe) + (u8)me) = 0;
  22864. +
  22865. + local_irq_enable();
  22866. +
  22867. + pr_debug("Bus freq set to %d done!\n", ddr_rate);
  22868. +
  22869. + return 0;
  22870. +}
  22871. +
  22872. +int init_mmdc_ddr3_settings(struct platform_device *busfreq_pdev)
  22873. +{
  22874. + struct device *dev = &busfreq_pdev->dev;
  22875. + struct platform_device *ocram_dev;
  22876. + unsigned int iram_paddr;
  22877. + int i, err;
  22878. + u32 cpu;
  22879. + struct device_node *node;
  22880. + struct gen_pool *iram_pool;
  22881. +
  22882. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-mmdc-combine");
  22883. + if (!node) {
  22884. + pr_err("failed to find imx6q-mmdc device tree data!\n");
  22885. + return -EINVAL;
  22886. + }
  22887. + mmdc_base = of_iomap(node, 0);
  22888. + WARN(!mmdc_base, "unable to map mmdc registers\n");
  22889. +
  22890. + node = NULL;
  22891. + if (cpu_is_imx6q())
  22892. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-iomuxc");
  22893. + if (cpu_is_imx6dl())
  22894. + node = of_find_compatible_node(NULL, NULL,
  22895. + "fsl,imx6dl-iomuxc");
  22896. + if (!node) {
  22897. + pr_err("failed to find imx6q-iomux device tree data!\n");
  22898. + return -EINVAL;
  22899. + }
  22900. + iomux_base = of_iomap(node, 0);
  22901. + WARN(!iomux_base, "unable to map iomux registers\n");
  22902. +
  22903. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
  22904. + if (!node) {
  22905. + pr_err("failed to find imx6q-ccm device tree data!\n");
  22906. + return -EINVAL;
  22907. + }
  22908. + ccm_base = of_iomap(node, 0);
  22909. + WARN(!ccm_base, "unable to map mmdc registers\n");
  22910. +
  22911. + node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
  22912. + if (!node) {
  22913. + pr_err("failed to find imx6q-pl310-cache device tree data!\n");
  22914. + return -EINVAL;
  22915. + }
  22916. + l2_base = of_iomap(node, 0);
  22917. + WARN(!ccm_base, "unable to map mmdc registers\n");
  22918. +
  22919. + node = NULL;
  22920. + node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
  22921. + if (!node) {
  22922. + pr_err("failed to find imx6q-a9-gic device tree data!\n");
  22923. + return -EINVAL;
  22924. + }
  22925. + gic_dist_base = of_iomap(node, 0);
  22926. + WARN(!gic_dist_base, "unable to map gic dist registers\n");
  22927. +
  22928. + if (cpu_is_imx6q())
  22929. + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6q) +
  22930. + ARRAY_SIZE(ddr3_calibration);
  22931. + if (cpu_is_imx6dl())
  22932. + ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6dl) +
  22933. + ARRAY_SIZE(ddr3_calibration);
  22934. +
  22935. + normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL);
  22936. + if (cpu_is_imx6q()) {
  22937. + memcpy(normal_mmdc_settings, ddr3_dll_mx6q,
  22938. + sizeof(ddr3_dll_mx6q));
  22939. + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6q)),
  22940. + ddr3_calibration, sizeof(ddr3_calibration));
  22941. + }
  22942. + if (cpu_is_imx6dl()) {
  22943. + memcpy(normal_mmdc_settings, ddr3_dll_mx6dl,
  22944. + sizeof(ddr3_dll_mx6dl));
  22945. + memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6dl)),
  22946. + ddr3_calibration, sizeof(ddr3_calibration));
  22947. + }
  22948. + /* store the original DDR settings at boot. */
  22949. + for (i = 0; i < ddr_settings_size; i++) {
  22950. + /*
  22951. + * writes via command mode register cannot be read back.
  22952. + * hence hardcode them in the initial static array.
  22953. + * this may require modification on a per customer basis.
  22954. + */
  22955. + if (normal_mmdc_settings[i][0] != 0x1C)
  22956. + normal_mmdc_settings[i][1] =
  22957. + readl_relaxed(mmdc_base
  22958. + + normal_mmdc_settings[i][0]);
  22959. + }
  22960. +
  22961. + irqs_used = devm_kzalloc(dev, sizeof(u32) * num_present_cpus(),
  22962. + GFP_KERNEL);
  22963. +
  22964. + for_each_online_cpu(cpu) {
  22965. + int irq;
  22966. +
  22967. + /*
  22968. + * set up a reserved interrupt to get all
  22969. + * the active cores into a WFE state
  22970. + * before changing the DDR frequency.
  22971. + */
  22972. + irq = platform_get_irq(busfreq_pdev, cpu);
  22973. + err = request_irq(irq, wait_in_wfe_irq,
  22974. + IRQF_PERCPU, "mmdc_1", NULL);
  22975. + if (err) {
  22976. + dev_err(dev,
  22977. + "Busfreq:request_irq failed %d, err = %d\n",
  22978. + irq, err);
  22979. + return err;
  22980. + }
  22981. + err = irq_set_affinity(irq, cpumask_of(cpu));
  22982. + if (err) {
  22983. + dev_err(dev,
  22984. + "Busfreq: Cannot set irq affinity irq=%d,\n",
  22985. + irq);
  22986. + return err;
  22987. + }
  22988. + irqs_used[cpu] = irq;
  22989. + }
  22990. +
  22991. + node = NULL;
  22992. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  22993. + if (!node) {
  22994. + dev_err(dev, "%s: failed to find ocram node\n",
  22995. + __func__);
  22996. + return -EINVAL;
  22997. + }
  22998. +
  22999. + ocram_dev = of_find_device_by_node(node);
  23000. + if (!ocram_dev) {
  23001. + dev_err(dev, "failed to find ocram device!\n");
  23002. + return -EINVAL;
  23003. + }
  23004. +
  23005. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  23006. + if (!iram_pool) {
  23007. + dev_err(dev, "iram pool unavailable!\n");
  23008. + return -EINVAL;
  23009. + }
  23010. +
  23011. + iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q);
  23012. + iram_iomux_settings = gen_pool_alloc(iram_pool,
  23013. + (iomux_settings_size * 8) + 8);
  23014. + if (!iram_iomux_settings) {
  23015. + dev_err(dev, "unable to alloc iram for IOMUX settings!\n");
  23016. + return -ENOMEM;
  23017. + }
  23018. +
  23019. + /*
  23020. + * Allocate extra space to store the number of entries in the
  23021. + * ddr_settings plus 4 extra regsiter information that needs
  23022. + * to be passed to the frequency change code.
  23023. + * sizeof(iram_ddr_settings) = sizeof(ddr_settings) +
  23024. + * entries in ddr_settings + 16.
  23025. + * The last 4 enties store the addresses of the registers:
  23026. + * CCM_BASE_ADDR
  23027. + * MMDC_BASE_ADDR
  23028. + * IOMUX_BASE_ADDR
  23029. + * L2X0_BASE_ADDR
  23030. + */
  23031. + iram_ddr_settings = gen_pool_alloc(iram_pool,
  23032. + (ddr_settings_size * 8) + 8 + 32);
  23033. + if (!iram_ddr_settings) {
  23034. + dev_err(dev, "unable to alloc iram for ddr settings!\n");
  23035. + return -ENOMEM;
  23036. + }
  23037. + i = ddr_settings_size + 1;
  23038. + iram_ddr_settings[i][0] = (unsigned long)mmdc_base;
  23039. + iram_ddr_settings[i+1][0] = (unsigned long)ccm_base;
  23040. + iram_ddr_settings[i+2][0] = (unsigned long)iomux_base;
  23041. + iram_ddr_settings[i+3][0] = (unsigned long)l2_base;
  23042. +
  23043. + if (cpu_is_imx6q()) {
  23044. + /* store the IOMUX settings at boot. */
  23045. + for (i = 0; i < iomux_settings_size; i++) {
  23046. + iomux_offsets_mx6q[i][1] =
  23047. + readl_relaxed(iomux_base +
  23048. + iomux_offsets_mx6q[i][0]);
  23049. + iram_iomux_settings[i+1][0] = iomux_offsets_mx6q[i][0];
  23050. + iram_iomux_settings[i+1][1] = iomux_offsets_mx6q[i][1];
  23051. + }
  23052. + }
  23053. +
  23054. + if (cpu_is_imx6dl()) {
  23055. + for (i = 0; i < iomux_settings_size; i++) {
  23056. + iomux_offsets_mx6dl[i][1] =
  23057. + readl_relaxed(iomux_base +
  23058. + iomux_offsets_mx6dl[i][0]);
  23059. + iram_iomux_settings[i+1][0] = iomux_offsets_mx6dl[i][0];
  23060. + iram_iomux_settings[i+1][1] = iomux_offsets_mx6dl[i][1];
  23061. + }
  23062. + }
  23063. +
  23064. + ddr_freq_change_iram_base = gen_pool_alloc(iram_pool,
  23065. + DDR_FREQ_CHANGE_SIZE);
  23066. + if (!ddr_freq_change_iram_base) {
  23067. + dev_err(dev, "Cannot alloc iram for ddr freq change code!\n");
  23068. + return -ENOMEM;
  23069. + }
  23070. +
  23071. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  23072. + (unsigned long)ddr_freq_change_iram_base);
  23073. + /*
  23074. + * Need to remap the area here since we want
  23075. + * the memory region to be executable.
  23076. + */
  23077. + ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
  23078. + DDR_FREQ_CHANGE_SIZE,
  23079. + MT_MEMORY_RWX_NONCACHED);
  23080. + mx6_change_ddr_freq = (void *)fncpy(ddr_freq_change_iram_base,
  23081. + &mx6_ddr3_freq_change, DDR_FREQ_CHANGE_SIZE);
  23082. +
  23083. + curr_ddr_rate = ddr_normal_rate;
  23084. +
  23085. + return 0;
  23086. +}
  23087. diff -Nur linux-3.14.17/arch/arm/mach-imx/busfreq-imx6.c linux-imx6-3.14/arch/arm/mach-imx/busfreq-imx6.c
  23088. --- linux-3.14.17/arch/arm/mach-imx/busfreq-imx6.c 1970-01-01 01:00:00.000000000 +0100
  23089. +++ linux-imx6-3.14/arch/arm/mach-imx/busfreq-imx6.c 2014-09-11 18:05:53.278003110 +0200
  23090. @@ -0,0 +1,952 @@
  23091. +/*
  23092. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  23093. + *
  23094. + * This program is free software; you can redistribute it and/or modify
  23095. + * it under the terms of the GNU General Public License as published by
  23096. + * the Free Software Foundation; either version 2 of the License, or
  23097. + * (at your option) any later version.
  23098. +
  23099. + * This program is distributed in the hope that it will be useful,
  23100. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23101. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23102. + * GNU General Public License for more details.
  23103. +
  23104. + * You should have received a copy of the GNU General Public License along
  23105. + * with this program; if not, write to the Free Software Foundation, Inc.,
  23106. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23107. + */
  23108. +
  23109. +/*!
  23110. + * @file busfreq-imx6.c
  23111. + *
  23112. + * @brief A common API for the Freescale Semiconductor iMX6 Busfreq API
  23113. + *
  23114. + * The APIs are for setting bus frequency to different values based on the
  23115. + * highest freqeuncy requested.
  23116. + *
  23117. + * @ingroup PM
  23118. + */
  23119. +
  23120. +#include <asm/cacheflush.h>
  23121. +#include <asm/io.h>
  23122. +#include <asm/mach/map.h>
  23123. +#include <asm/mach-types.h>
  23124. +#include <asm/tlb.h>
  23125. +#include <linux/busfreq-imx6.h>
  23126. +#include <linux/clk.h>
  23127. +#include <linux/clk-provider.h>
  23128. +#include <linux/delay.h>
  23129. +#include <linux/module.h>
  23130. +#include <linux/mutex.h>
  23131. +#include <linux/of.h>
  23132. +#include <linux/platform_device.h>
  23133. +#include <linux/proc_fs.h>
  23134. +#include <linux/reboot.h>
  23135. +#include <linux/regulator/consumer.h>
  23136. +#include <linux/sched.h>
  23137. +#include <linux/suspend.h>
  23138. +#include "hardware.h"
  23139. +
  23140. +#define LPAPM_CLK 24000000
  23141. +#define DDR3_AUDIO_CLK 50000000
  23142. +#define LPDDR2_AUDIO_CLK 100000000
  23143. +
  23144. +int high_bus_freq_mode;
  23145. +int med_bus_freq_mode;
  23146. +int audio_bus_freq_mode;
  23147. +int low_bus_freq_mode;
  23148. +int ultra_low_bus_freq_mode;
  23149. +unsigned int ddr_med_rate;
  23150. +unsigned int ddr_normal_rate;
  23151. +
  23152. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23153. +static int bus_freq_scaling_initialized;
  23154. +static struct device *busfreq_dev;
  23155. +static int busfreq_suspended;
  23156. +static u32 org_arm_rate;
  23157. +static int bus_freq_scaling_is_active;
  23158. +static int high_bus_count, med_bus_count, audio_bus_count, low_bus_count;
  23159. +static unsigned int ddr_low_rate;
  23160. +
  23161. +extern int init_mmdc_lpddr2_settings(struct platform_device *dev);
  23162. +extern int init_mmdc_ddr3_settings(struct platform_device *dev);
  23163. +extern int update_ddr_freq(int ddr_rate);
  23164. +extern int update_lpddr2_freq(int ddr_rate);
  23165. +
  23166. +DEFINE_MUTEX(bus_freq_mutex);
  23167. +static DEFINE_SPINLOCK(freq_lock);
  23168. +
  23169. +static struct clk *pll2_400;
  23170. +static struct clk *periph_clk;
  23171. +static struct clk *periph_pre_clk;
  23172. +static struct clk *periph_clk2_sel;
  23173. +static struct clk *periph_clk2;
  23174. +static struct clk *osc_clk;
  23175. +static struct clk *cpu_clk;
  23176. +static struct clk *pll3;
  23177. +static struct clk *pll2;
  23178. +static struct clk *pll2_200;
  23179. +static struct clk *pll1_sys;
  23180. +static struct clk *periph2_clk;
  23181. +static struct clk *ocram_clk;
  23182. +static struct clk *ahb_clk;
  23183. +static struct clk *pll1_sw_clk;
  23184. +static struct clk *periph2_pre_clk;
  23185. +static struct clk *periph2_clk2_sel;
  23186. +static struct clk *periph2_clk2;
  23187. +static struct clk *step_clk;
  23188. +static struct clk *axi_sel_clk;
  23189. +static struct clk *pll3_pfd1_540m;
  23190. +
  23191. +static u32 pll2_org_rate;
  23192. +static struct delayed_work low_bus_freq_handler;
  23193. +static struct delayed_work bus_freq_daemon;
  23194. +
  23195. +static void enter_lpm_imx6sl(void)
  23196. +{
  23197. + unsigned long flags;
  23198. +
  23199. + if (high_bus_freq_mode) {
  23200. + pll2_org_rate = clk_get_rate(pll2);
  23201. + /* Set periph_clk to be sourced from OSC_CLK */
  23202. + clk_set_parent(periph_clk2_sel, osc_clk);
  23203. + clk_set_parent(periph_clk, periph_clk2);
  23204. + /* Ensure AHB/AXI clks are at 24MHz. */
  23205. + clk_set_rate(ahb_clk, LPAPM_CLK);
  23206. + clk_set_rate(ocram_clk, LPAPM_CLK);
  23207. + }
  23208. + if (audio_bus_count) {
  23209. + /* Set AHB to 8MHz to lower pwer.*/
  23210. + clk_set_rate(ahb_clk, LPAPM_CLK / 3);
  23211. +
  23212. + /* Set up DDR to 100MHz. */
  23213. + spin_lock_irqsave(&freq_lock, flags);
  23214. + update_lpddr2_freq(LPDDR2_AUDIO_CLK);
  23215. + spin_unlock_irqrestore(&freq_lock, flags);
  23216. +
  23217. + /* Fix the clock tree in kernel */
  23218. + clk_set_rate(pll2, pll2_org_rate);
  23219. + clk_set_parent(periph2_pre_clk, pll2_200);
  23220. + clk_set_parent(periph2_clk, periph2_pre_clk);
  23221. +
  23222. + if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
  23223. + /*
  23224. + * Swtich ARM to run off PLL2_PFD2_400MHz
  23225. + * since DDR is anyway at 100MHz.
  23226. + */
  23227. + clk_set_parent(step_clk, pll2_400);
  23228. + clk_set_parent(pll1_sw_clk, step_clk);
  23229. + /*
  23230. + * Ensure that the clock will be
  23231. + * at original speed.
  23232. + */
  23233. + clk_set_rate(cpu_clk, org_arm_rate);
  23234. + }
  23235. + low_bus_freq_mode = 0;
  23236. + ultra_low_bus_freq_mode = 0;
  23237. + audio_bus_freq_mode = 1;
  23238. + } else {
  23239. + u32 arm_div, pll1_rate;
  23240. + org_arm_rate = clk_get_rate(cpu_clk);
  23241. + if (low_bus_freq_mode && low_bus_count == 0) {
  23242. + /*
  23243. + * We are already in DDR @ 24MHz state, but
  23244. + * no one but ARM needs the DDR. In this case,
  23245. + * we can lower the DDR freq to 1MHz when ARM
  23246. + * enters WFI in this state. Keep track of this state.
  23247. + */
  23248. + ultra_low_bus_freq_mode = 1;
  23249. + low_bus_freq_mode = 0;
  23250. + audio_bus_freq_mode = 0;
  23251. + } else {
  23252. + if (!ultra_low_bus_freq_mode && !low_bus_freq_mode) {
  23253. + /*
  23254. + * Set DDR to 24MHz.
  23255. + * Since we are going to bypass PLL2,
  23256. + * we need to move ARM clk off PLL2_PFD2
  23257. + * to PLL1. Make sure the PLL1 is running
  23258. + * at the lowest possible freq.
  23259. + */
  23260. + clk_set_rate(pll1_sys,
  23261. + clk_round_rate(pll1_sys, org_arm_rate));
  23262. + pll1_rate = clk_get_rate(pll1_sys);
  23263. + arm_div = pll1_rate / org_arm_rate + 1;
  23264. + /*
  23265. + * Ensure ARM CLK is lower before
  23266. + * changing the parent.
  23267. + */
  23268. + clk_set_rate(cpu_clk, org_arm_rate / arm_div);
  23269. + /* Now set the ARM clk parent to PLL1_SYS. */
  23270. + clk_set_parent(pll1_sw_clk, pll1_sys);
  23271. +
  23272. + /*
  23273. + * Set STEP_CLK back to OSC to save power and
  23274. + * also to maintain the parent.The WFI iram code
  23275. + * will switch step_clk to osc, but the clock API
  23276. + * is not aware of the change and when a new request
  23277. + * to change the step_clk parent to pll2_pfd2_400M
  23278. + * is requested sometime later, the change is ignored.
  23279. + */
  23280. + clk_set_parent(step_clk, osc_clk);
  23281. + /* Now set DDR to 24MHz. */
  23282. + spin_lock_irqsave(&freq_lock, flags);
  23283. + update_lpddr2_freq(LPAPM_CLK);
  23284. + spin_unlock_irqrestore(&freq_lock, flags);
  23285. +
  23286. + /*
  23287. + * Fix the clock tree in kernel.
  23288. + * Make sure PLL2 rate is updated as it gets
  23289. + * bypassed in the DDR freq change code.
  23290. + */
  23291. + clk_set_rate(pll2, LPAPM_CLK);
  23292. + clk_set_parent(periph2_clk2_sel, pll2);
  23293. + clk_set_parent(periph2_clk, periph2_clk2_sel);
  23294. +
  23295. + }
  23296. + if (low_bus_count == 0) {
  23297. + ultra_low_bus_freq_mode = 1;
  23298. + low_bus_freq_mode = 0;
  23299. + } else {
  23300. + ultra_low_bus_freq_mode = 0;
  23301. + low_bus_freq_mode = 1;
  23302. + }
  23303. + audio_bus_freq_mode = 0;
  23304. + }
  23305. + }
  23306. +}
  23307. +
  23308. +static void exit_lpm_imx6sl(void)
  23309. +{
  23310. + unsigned long flags;
  23311. +
  23312. + spin_lock_irqsave(&freq_lock, flags);
  23313. + /* Change DDR freq in IRAM. */
  23314. + update_lpddr2_freq(ddr_normal_rate);
  23315. + spin_unlock_irqrestore(&freq_lock, flags);
  23316. +
  23317. + /*
  23318. + * Fix the clock tree in kernel.
  23319. + * Make sure PLL2 rate is updated as it gets
  23320. + * un-bypassed in the DDR freq change code.
  23321. + */
  23322. + clk_set_rate(pll2, pll2_org_rate);
  23323. + clk_set_parent(periph2_pre_clk, pll2_400);
  23324. + clk_set_parent(periph2_clk, periph2_pre_clk);
  23325. +
  23326. + /* Ensure that periph_clk is sourced from PLL2_400. */
  23327. + clk_set_parent(periph_pre_clk, pll2_400);
  23328. + /*
  23329. + * Before switching the perhiph_clk, ensure that the
  23330. + * AHB/AXI will not be too fast.
  23331. + */
  23332. + clk_set_rate(ahb_clk, LPAPM_CLK / 3);
  23333. + clk_set_rate(ocram_clk, LPAPM_CLK / 2);
  23334. + clk_set_parent(periph_clk, periph_pre_clk);
  23335. +
  23336. + if (low_bus_freq_mode || ultra_low_bus_freq_mode) {
  23337. + /* Move ARM from PLL1_SW_CLK to PLL2_400. */
  23338. + clk_set_parent(step_clk, pll2_400);
  23339. + clk_set_parent(pll1_sw_clk, step_clk);
  23340. + clk_set_rate(cpu_clk, org_arm_rate);
  23341. + ultra_low_bus_freq_mode = 0;
  23342. + }
  23343. +}
  23344. +
  23345. +int reduce_bus_freq(void)
  23346. +{
  23347. + int ret = 0;
  23348. + clk_prepare_enable(pll3);
  23349. + if (cpu_is_imx6sl())
  23350. + enter_lpm_imx6sl();
  23351. + else {
  23352. + if (cpu_is_imx6dl() && (clk_get_parent(axi_sel_clk)
  23353. + != periph_clk))
  23354. + /* Set axi to periph_clk */
  23355. + clk_set_parent(axi_sel_clk, periph_clk);
  23356. +
  23357. + if (audio_bus_count) {
  23358. + /* Need to ensure that PLL2_PFD_400M is kept ON. */
  23359. + clk_prepare_enable(pll2_400);
  23360. + update_ddr_freq(DDR3_AUDIO_CLK);
  23361. + /* Make sure periph clk's parent also got updated */
  23362. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23363. + if (ret)
  23364. + dev_WARN(busfreq_dev,
  23365. + "%s: %d: clk set parent fail!\n",
  23366. + __func__, __LINE__);
  23367. + ret = clk_set_parent(periph_pre_clk, pll2_200);
  23368. + if (ret)
  23369. + dev_WARN(busfreq_dev,
  23370. + "%s: %d: clk set parent fail!\n",
  23371. + __func__, __LINE__);
  23372. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23373. + if (ret)
  23374. + dev_WARN(busfreq_dev,
  23375. + "%s: %d: clk set parent fail!\n",
  23376. + __func__, __LINE__);
  23377. + audio_bus_freq_mode = 1;
  23378. + low_bus_freq_mode = 0;
  23379. + } else {
  23380. + update_ddr_freq(LPAPM_CLK);
  23381. + /* Make sure periph clk's parent also got updated */
  23382. + ret = clk_set_parent(periph_clk2_sel, osc_clk);
  23383. + if (ret)
  23384. + dev_WARN(busfreq_dev,
  23385. + "%s: %d: clk set parent fail!\n",
  23386. + __func__, __LINE__);
  23387. + /* Set periph_clk parent to OSC via periph_clk2_sel */
  23388. + ret = clk_set_parent(periph_clk, periph_clk2);
  23389. + if (ret)
  23390. + dev_WARN(busfreq_dev,
  23391. + "%s: %d: clk set parent fail!\n",
  23392. + __func__, __LINE__);
  23393. + if (audio_bus_freq_mode)
  23394. + clk_disable_unprepare(pll2_400);
  23395. + low_bus_freq_mode = 1;
  23396. + audio_bus_freq_mode = 0;
  23397. + }
  23398. + }
  23399. + clk_disable_unprepare(pll3);
  23400. +
  23401. + med_bus_freq_mode = 0;
  23402. + high_bus_freq_mode = 0;
  23403. +
  23404. + if (audio_bus_freq_mode)
  23405. + dev_dbg(busfreq_dev, "Bus freq set to audio mode. Count:\
  23406. + high %d, med %d, audio %d\n",
  23407. + high_bus_count, med_bus_count, audio_bus_count);
  23408. + if (low_bus_freq_mode)
  23409. + dev_dbg(busfreq_dev, "Bus freq set to low mode. Count:\
  23410. + high %d, med %d, audio %d\n",
  23411. + high_bus_count, med_bus_count, audio_bus_count);
  23412. +
  23413. + return ret;
  23414. +}
  23415. +
  23416. +static void reduce_bus_freq_handler(struct work_struct *work)
  23417. +{
  23418. + mutex_lock(&bus_freq_mutex);
  23419. +
  23420. + reduce_bus_freq();
  23421. +
  23422. + mutex_unlock(&bus_freq_mutex);
  23423. +}
  23424. +
  23425. +/*
  23426. + * Set the DDR, AHB to 24MHz.
  23427. + * This mode will be activated only when none of the modules that
  23428. + * need a higher DDR or AHB frequency are active.
  23429. + */
  23430. +int set_low_bus_freq(void)
  23431. +{
  23432. + if (busfreq_suspended)
  23433. + return 0;
  23434. +
  23435. + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
  23436. + return 0;
  23437. +
  23438. + /*
  23439. + * Check to see if we need to got from
  23440. + * low bus freq mode to audio bus freq mode.
  23441. + * If so, the change needs to be done immediately.
  23442. + */
  23443. + if (audio_bus_count && (low_bus_freq_mode || ultra_low_bus_freq_mode))
  23444. + reduce_bus_freq();
  23445. + else
  23446. + /*
  23447. + * Don't lower the frequency immediately. Instead
  23448. + * scheduled a delayed work and drop the freq if
  23449. + * the conditions still remain the same.
  23450. + */
  23451. + schedule_delayed_work(&low_bus_freq_handler,
  23452. + usecs_to_jiffies(3000000));
  23453. + return 0;
  23454. +}
  23455. +
  23456. +/*
  23457. + * Set the DDR to either 528MHz or 400MHz for iMX6qd
  23458. + * or 400MHz for iMX6dl.
  23459. + */
  23460. +int set_high_bus_freq(int high_bus_freq)
  23461. +{
  23462. + int ret = 0;
  23463. + struct clk *periph_clk_parent;
  23464. +
  23465. + if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
  23466. + cancel_delayed_work_sync(&low_bus_freq_handler);
  23467. +
  23468. + if (busfreq_suspended)
  23469. + return 0;
  23470. +
  23471. + if (cpu_is_imx6q())
  23472. + periph_clk_parent = pll2;
  23473. + else
  23474. + periph_clk_parent = pll2_400;
  23475. +
  23476. + if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
  23477. + return 0;
  23478. +
  23479. + if (high_bus_freq_mode)
  23480. + return 0;
  23481. +
  23482. + /* medium bus freq is only supported for MX6DQ */
  23483. + if (med_bus_freq_mode && !high_bus_freq)
  23484. + return 0;
  23485. +
  23486. + clk_prepare_enable(pll3);
  23487. + if (cpu_is_imx6sl())
  23488. + exit_lpm_imx6sl();
  23489. + else {
  23490. + if (high_bus_freq) {
  23491. + update_ddr_freq(ddr_normal_rate);
  23492. + /* Make sure periph clk's parent also got updated */
  23493. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23494. + if (ret)
  23495. + dev_WARN(busfreq_dev,
  23496. + "%s: %d: clk set parent fail!\n",
  23497. + __func__, __LINE__);
  23498. + ret = clk_set_parent(periph_pre_clk, periph_clk_parent);
  23499. + if (ret)
  23500. + dev_WARN(busfreq_dev,
  23501. + "%s: %d: clk set parent fail!\n",
  23502. + __func__, __LINE__);
  23503. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23504. + if (ret)
  23505. + dev_WARN(busfreq_dev,
  23506. + "%s: %d: clk set parent fail!\n",
  23507. + __func__, __LINE__);
  23508. + if (cpu_is_imx6dl() && (clk_get_parent(axi_sel_clk)
  23509. + != pll3_pfd1_540m))
  23510. + /* Set axi to pll3_pfd1_540m */
  23511. + clk_set_parent(axi_sel_clk, pll3_pfd1_540m);
  23512. + } else {
  23513. + update_ddr_freq(ddr_med_rate);
  23514. + /* Make sure periph clk's parent also got updated */
  23515. + ret = clk_set_parent(periph_clk2_sel, pll3);
  23516. + if (ret)
  23517. + dev_WARN(busfreq_dev,
  23518. + "%s: %d: clk set parent fail!\n",
  23519. + __func__, __LINE__);
  23520. + ret = clk_set_parent(periph_pre_clk, pll2_400);
  23521. + if (ret)
  23522. + dev_WARN(busfreq_dev,
  23523. + "%s: %d: clk set parent fail!\n",
  23524. + __func__, __LINE__);
  23525. + ret = clk_set_parent(periph_clk, periph_pre_clk);
  23526. + if (ret)
  23527. + dev_WARN(busfreq_dev,
  23528. + "%s: %d: clk set parent fail!\n",
  23529. + __func__, __LINE__);
  23530. + }
  23531. + if (audio_bus_freq_mode)
  23532. + clk_disable_unprepare(pll2_400);
  23533. + }
  23534. +
  23535. + high_bus_freq_mode = 1;
  23536. + med_bus_freq_mode = 0;
  23537. + low_bus_freq_mode = 0;
  23538. + audio_bus_freq_mode = 0;
  23539. +
  23540. + clk_disable_unprepare(pll3);
  23541. +
  23542. + if (high_bus_freq_mode)
  23543. + dev_dbg(busfreq_dev, "Bus freq set to high mode. Count:\
  23544. + high %d, med %d, audio %d\n",
  23545. + high_bus_count, med_bus_count, audio_bus_count);
  23546. + if (med_bus_freq_mode)
  23547. + dev_dbg(busfreq_dev, "Bus freq set to med mode. Count:\
  23548. + high %d, med %d, audio %d\n",
  23549. + high_bus_count, med_bus_count, audio_bus_count);
  23550. +
  23551. + return 0;
  23552. +}
  23553. +#endif
  23554. +
  23555. +void request_bus_freq(enum bus_freq_mode mode)
  23556. +{
  23557. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23558. + mutex_lock(&bus_freq_mutex);
  23559. +
  23560. + if (mode == BUS_FREQ_HIGH)
  23561. + high_bus_count++;
  23562. + else if (mode == BUS_FREQ_MED)
  23563. + med_bus_count++;
  23564. + else if (mode == BUS_FREQ_AUDIO)
  23565. + audio_bus_count++;
  23566. + else if (mode == BUS_FREQ_LOW)
  23567. + low_bus_count++;
  23568. +
  23569. + if (busfreq_suspended || !bus_freq_scaling_initialized ||
  23570. + !bus_freq_scaling_is_active) {
  23571. + mutex_unlock(&bus_freq_mutex);
  23572. + return;
  23573. + }
  23574. + cancel_delayed_work_sync(&low_bus_freq_handler);
  23575. +
  23576. + if (cpu_is_imx6dl()) {
  23577. + /* No support for medium setpoint on MX6DL. */
  23578. + if (mode == BUS_FREQ_MED) {
  23579. + high_bus_count++;
  23580. + mode = BUS_FREQ_HIGH;
  23581. + }
  23582. + }
  23583. +
  23584. + if ((mode == BUS_FREQ_HIGH) && (!high_bus_freq_mode)) {
  23585. + set_high_bus_freq(1);
  23586. + mutex_unlock(&bus_freq_mutex);
  23587. + return;
  23588. + }
  23589. +
  23590. + if ((mode == BUS_FREQ_MED) && (!high_bus_freq_mode) &&
  23591. + (!med_bus_freq_mode)) {
  23592. + set_high_bus_freq(0);
  23593. + mutex_unlock(&bus_freq_mutex);
  23594. + return;
  23595. + }
  23596. + if ((mode == BUS_FREQ_AUDIO) && (!high_bus_freq_mode) &&
  23597. + (!med_bus_freq_mode) && (!audio_bus_freq_mode)) {
  23598. + set_low_bus_freq();
  23599. + mutex_unlock(&bus_freq_mutex);
  23600. + return;
  23601. + }
  23602. + mutex_unlock(&bus_freq_mutex);
  23603. +#endif
  23604. + return;
  23605. +}
  23606. +EXPORT_SYMBOL(request_bus_freq);
  23607. +
  23608. +void release_bus_freq(enum bus_freq_mode mode)
  23609. +{
  23610. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23611. + mutex_lock(&bus_freq_mutex);
  23612. +
  23613. + if (mode == BUS_FREQ_HIGH) {
  23614. + if (high_bus_count == 0) {
  23615. + dev_err(busfreq_dev, "high bus count mismatch!\n");
  23616. + dump_stack();
  23617. + mutex_unlock(&bus_freq_mutex);
  23618. + return;
  23619. + }
  23620. + high_bus_count--;
  23621. + } else if (mode == BUS_FREQ_MED) {
  23622. + if (med_bus_count == 0) {
  23623. + dev_err(busfreq_dev, "med bus count mismatch!\n");
  23624. + dump_stack();
  23625. + mutex_unlock(&bus_freq_mutex);
  23626. + return;
  23627. + }
  23628. + med_bus_count--;
  23629. + } else if (mode == BUS_FREQ_AUDIO) {
  23630. + if (audio_bus_count == 0) {
  23631. + dev_err(busfreq_dev, "audio bus count mismatch!\n");
  23632. + dump_stack();
  23633. + mutex_unlock(&bus_freq_mutex);
  23634. + return;
  23635. + }
  23636. + audio_bus_count--;
  23637. + } else if (mode == BUS_FREQ_LOW) {
  23638. + if (low_bus_count == 0) {
  23639. + dev_err(busfreq_dev, "low bus count mismatch!\n");
  23640. + dump_stack();
  23641. + mutex_unlock(&bus_freq_mutex);
  23642. + return;
  23643. + }
  23644. + low_bus_count--;
  23645. + }
  23646. +
  23647. + if (busfreq_suspended || !bus_freq_scaling_initialized ||
  23648. + !bus_freq_scaling_is_active) {
  23649. + mutex_unlock(&bus_freq_mutex);
  23650. + return;
  23651. + }
  23652. +
  23653. + if (cpu_is_imx6dl()) {
  23654. + /* No support for medium setpoint on MX6DL. */
  23655. + if (mode == BUS_FREQ_MED) {
  23656. + high_bus_count--;
  23657. + mode = BUS_FREQ_HIGH;
  23658. + }
  23659. + }
  23660. +
  23661. + if ((!audio_bus_freq_mode) && (high_bus_count == 0) &&
  23662. + (med_bus_count == 0) && (audio_bus_count != 0)) {
  23663. + set_low_bus_freq();
  23664. + mutex_unlock(&bus_freq_mutex);
  23665. + return;
  23666. + }
  23667. + if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
  23668. + (med_bus_count == 0) && (audio_bus_count == 0) &&
  23669. + (low_bus_count != 0)) {
  23670. + set_low_bus_freq();
  23671. + mutex_unlock(&bus_freq_mutex);
  23672. + return;
  23673. + }
  23674. + if ((!ultra_low_bus_freq_mode) && (high_bus_count == 0) &&
  23675. + (med_bus_count == 0) && (audio_bus_count == 0) &&
  23676. + (low_bus_count == 0)) {
  23677. + set_low_bus_freq();
  23678. + mutex_unlock(&bus_freq_mutex);
  23679. + return;
  23680. + }
  23681. +
  23682. + mutex_unlock(&bus_freq_mutex);
  23683. +#endif
  23684. + return;
  23685. +}
  23686. +EXPORT_SYMBOL(release_bus_freq);
  23687. +
  23688. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23689. +static void bus_freq_daemon_handler(struct work_struct *work)
  23690. +{
  23691. + mutex_lock(&bus_freq_mutex);
  23692. + if ((!low_bus_freq_mode) && (high_bus_count == 0) &&
  23693. + (med_bus_count == 0) && (audio_bus_count == 0))
  23694. + set_low_bus_freq();
  23695. + mutex_unlock(&bus_freq_mutex);
  23696. +}
  23697. +
  23698. +static ssize_t bus_freq_scaling_enable_show(struct device *dev,
  23699. + struct device_attribute *attr, char *buf)
  23700. +{
  23701. + if (bus_freq_scaling_is_active)
  23702. + return sprintf(buf, "Bus frequency scaling is enabled\n");
  23703. + else
  23704. + return sprintf(buf, "Bus frequency scaling is disabled\n");
  23705. +}
  23706. +
  23707. +static ssize_t bus_freq_scaling_enable_store(struct device *dev,
  23708. + struct device_attribute *attr,
  23709. + const char *buf, size_t size)
  23710. +{
  23711. + if (strncmp(buf, "1", 1) == 0) {
  23712. + bus_freq_scaling_is_active = 1;
  23713. + set_high_bus_freq(1);
  23714. + /*
  23715. + * We set bus freq to highest at the beginning,
  23716. + * so we use this daemon thread to make sure system
  23717. + * can enter low bus mode if
  23718. + * there is no high bus request pending
  23719. + */
  23720. + schedule_delayed_work(&bus_freq_daemon,
  23721. + usecs_to_jiffies(5000000));
  23722. + } else if (strncmp(buf, "0", 1) == 0) {
  23723. + if (bus_freq_scaling_is_active)
  23724. + set_high_bus_freq(1);
  23725. + bus_freq_scaling_is_active = 0;
  23726. + }
  23727. + return size;
  23728. +}
  23729. +
  23730. +static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
  23731. + void *dummy)
  23732. +{
  23733. + mutex_lock(&bus_freq_mutex);
  23734. +
  23735. + if (event == PM_SUSPEND_PREPARE) {
  23736. + high_bus_count++;
  23737. + set_high_bus_freq(1);
  23738. + busfreq_suspended = 1;
  23739. + } else if (event == PM_POST_SUSPEND) {
  23740. + busfreq_suspended = 0;
  23741. + high_bus_count--;
  23742. + schedule_delayed_work(&bus_freq_daemon,
  23743. + usecs_to_jiffies(5000000));
  23744. + }
  23745. +
  23746. + mutex_unlock(&bus_freq_mutex);
  23747. +
  23748. + return NOTIFY_OK;
  23749. +}
  23750. +
  23751. +static int busfreq_reboot_notifier_event(struct notifier_block *this,
  23752. + unsigned long event, void *ptr)
  23753. +{
  23754. + /* System is rebooting. Set the system into high_bus_freq_mode. */
  23755. + request_bus_freq(BUS_FREQ_HIGH);
  23756. +
  23757. + return 0;
  23758. +}
  23759. +
  23760. +static struct notifier_block imx_bus_freq_pm_notifier = {
  23761. + .notifier_call = bus_freq_pm_notify,
  23762. +};
  23763. +
  23764. +static struct notifier_block imx_busfreq_reboot_notifier = {
  23765. + .notifier_call = busfreq_reboot_notifier_event,
  23766. +};
  23767. +
  23768. +
  23769. +static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
  23770. + bus_freq_scaling_enable_store);
  23771. +#endif
  23772. +
  23773. +/*!
  23774. + * This is the probe routine for the bus frequency driver.
  23775. + *
  23776. + * @param pdev The platform device structure
  23777. + *
  23778. + * @return The function returns 0 on success
  23779. + *
  23780. + */
  23781. +
  23782. +static int busfreq_probe(struct platform_device *pdev)
  23783. +{
  23784. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23785. + u32 err;
  23786. +
  23787. + busfreq_dev = &pdev->dev;
  23788. +
  23789. + pll2_400 = devm_clk_get(&pdev->dev, "pll2_pfd2_396m");
  23790. + if (IS_ERR(pll2_400)) {
  23791. + dev_err(busfreq_dev, "%s: failed to get pll2_pfd2_396m\n",
  23792. + __func__);
  23793. + return PTR_ERR(pll2_400);
  23794. + }
  23795. +
  23796. + pll2_200 = devm_clk_get(&pdev->dev, "pll2_198m");
  23797. + if (IS_ERR(pll2_200)) {
  23798. + dev_err(busfreq_dev, "%s: failed to get pll2_198m\n",
  23799. + __func__);
  23800. + return PTR_ERR(pll2_200);
  23801. + }
  23802. +
  23803. + pll2 = devm_clk_get(&pdev->dev, "pll2_bus");
  23804. + if (IS_ERR(pll2)) {
  23805. + dev_err(busfreq_dev, "%s: failed to get pll2_bus\n",
  23806. + __func__);
  23807. + return PTR_ERR(pll2);
  23808. + }
  23809. +
  23810. + cpu_clk = devm_clk_get(&pdev->dev, "arm");
  23811. + if (IS_ERR(cpu_clk)) {
  23812. + dev_err(busfreq_dev, "%s: failed to get cpu_clk\n",
  23813. + __func__);
  23814. + return PTR_ERR(cpu_clk);
  23815. + }
  23816. +
  23817. + pll3 = devm_clk_get(&pdev->dev, "pll3_usb_otg");
  23818. + if (IS_ERR(pll3)) {
  23819. + dev_err(busfreq_dev, "%s: failed to get pll3_usb_otg\n",
  23820. + __func__);
  23821. + return PTR_ERR(pll3);
  23822. + }
  23823. +
  23824. + periph_clk = devm_clk_get(&pdev->dev, "periph");
  23825. + if (IS_ERR(periph_clk)) {
  23826. + dev_err(busfreq_dev, "%s: failed to get periph\n",
  23827. + __func__);
  23828. + return PTR_ERR(periph_clk);
  23829. + }
  23830. +
  23831. + periph_pre_clk = devm_clk_get(&pdev->dev, "periph_pre");
  23832. + if (IS_ERR(periph_pre_clk)) {
  23833. + dev_err(busfreq_dev, "%s: failed to get periph_pre\n",
  23834. + __func__);
  23835. + return PTR_ERR(periph_pre_clk);
  23836. + }
  23837. +
  23838. + periph_clk2 = devm_clk_get(&pdev->dev, "periph_clk2");
  23839. + if (IS_ERR(periph_clk2)) {
  23840. + dev_err(busfreq_dev, "%s: failed to get periph_clk2\n",
  23841. + __func__);
  23842. + return PTR_ERR(periph_clk2);
  23843. + }
  23844. +
  23845. + periph_clk2_sel = devm_clk_get(&pdev->dev, "periph_clk2_sel");
  23846. + if (IS_ERR(periph_clk2_sel)) {
  23847. + dev_err(busfreq_dev, "%s: failed to get periph_clk2_sel\n",
  23848. + __func__);
  23849. + return PTR_ERR(periph_clk2_sel);
  23850. + }
  23851. +
  23852. + osc_clk = devm_clk_get(&pdev->dev, "osc");
  23853. + if (IS_ERR(osc_clk)) {
  23854. + dev_err(busfreq_dev, "%s: failed to get osc_clk\n",
  23855. + __func__);
  23856. + return PTR_ERR(osc_clk);
  23857. + }
  23858. +
  23859. + if (cpu_is_imx6dl()) {
  23860. + axi_sel_clk = devm_clk_get(&pdev->dev, "axi_sel");
  23861. + if (IS_ERR(axi_sel_clk)) {
  23862. + dev_err(busfreq_dev, "%s: failed to get axi_sel_clk\n",
  23863. + __func__);
  23864. + return PTR_ERR(axi_sel_clk);
  23865. + }
  23866. +
  23867. + pll3_pfd1_540m = devm_clk_get(&pdev->dev, "pll3_pfd1_540m");
  23868. + if (IS_ERR(pll3_pfd1_540m)) {
  23869. + dev_err(busfreq_dev,
  23870. + "%s: failed to get pll3_pfd1_540m\n", __func__);
  23871. + return PTR_ERR(pll3_pfd1_540m);
  23872. + }
  23873. + }
  23874. +
  23875. + if (cpu_is_imx6sl()) {
  23876. + pll1_sys = devm_clk_get(&pdev->dev, "pll1_sys");
  23877. + if (IS_ERR(pll1_sys)) {
  23878. + dev_err(busfreq_dev, "%s: failed to get pll1_sys\n",
  23879. + __func__);
  23880. + return PTR_ERR(pll1_sys);
  23881. + }
  23882. +
  23883. + ahb_clk = devm_clk_get(&pdev->dev, "ahb");
  23884. + if (IS_ERR(ahb_clk)) {
  23885. + dev_err(busfreq_dev, "%s: failed to get ahb_clk\n",
  23886. + __func__);
  23887. + return PTR_ERR(ahb_clk);
  23888. + }
  23889. +
  23890. + ocram_clk = devm_clk_get(&pdev->dev, "ocram");
  23891. + if (IS_ERR(ocram_clk)) {
  23892. + dev_err(busfreq_dev, "%s: failed to get ocram_clk\n",
  23893. + __func__);
  23894. + return PTR_ERR(ocram_clk);
  23895. + }
  23896. +
  23897. + pll1_sw_clk = devm_clk_get(&pdev->dev, "pll1_sw");
  23898. + if (IS_ERR(pll1_sw_clk)) {
  23899. + dev_err(busfreq_dev, "%s: failed to get pll1_sw_clk\n",
  23900. + __func__);
  23901. + return PTR_ERR(pll1_sw_clk);
  23902. + }
  23903. +
  23904. + periph2_clk = devm_clk_get(&pdev->dev, "periph2");
  23905. + if (IS_ERR(periph2_clk)) {
  23906. + dev_err(busfreq_dev, "%s: failed to get periph2\n",
  23907. + __func__);
  23908. + return PTR_ERR(periph2_clk);
  23909. + }
  23910. +
  23911. + periph2_pre_clk = devm_clk_get(&pdev->dev, "periph2_pre");
  23912. + if (IS_ERR(periph2_pre_clk)) {
  23913. + dev_err(busfreq_dev,
  23914. + "%s: failed to get periph2_pre_clk\n",
  23915. + __func__);
  23916. + return PTR_ERR(periph2_pre_clk);
  23917. + }
  23918. +
  23919. + periph2_clk2 = devm_clk_get(&pdev->dev, "periph2_clk2");
  23920. + if (IS_ERR(periph2_clk2)) {
  23921. + dev_err(busfreq_dev,
  23922. + "%s: failed to get periph2_clk2\n",
  23923. + __func__);
  23924. + return PTR_ERR(periph2_clk2);
  23925. + }
  23926. +
  23927. + periph2_clk2_sel = devm_clk_get(&pdev->dev, "periph2_clk2_sel");
  23928. + if (IS_ERR(periph2_clk2_sel)) {
  23929. + dev_err(busfreq_dev,
  23930. + "%s: failed to get periph2_clk2_sel\n",
  23931. + __func__);
  23932. + return PTR_ERR(periph2_clk2_sel);
  23933. + }
  23934. +
  23935. + step_clk = devm_clk_get(&pdev->dev, "step");
  23936. + if (IS_ERR(step_clk)) {
  23937. + dev_err(busfreq_dev,
  23938. + "%s: failed to get step_clk\n",
  23939. + __func__);
  23940. + return PTR_ERR(periph2_clk2_sel);
  23941. + }
  23942. +
  23943. + }
  23944. +
  23945. + err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
  23946. + if (err) {
  23947. + dev_err(busfreq_dev,
  23948. + "Unable to register sysdev entry for BUSFREQ");
  23949. + return err;
  23950. + }
  23951. +
  23952. + if (of_property_read_u32(pdev->dev.of_node, "fsl,max_ddr_freq",
  23953. + &ddr_normal_rate)) {
  23954. + dev_err(busfreq_dev, "max_ddr_freq entry missing\n");
  23955. + return -EINVAL;
  23956. + }
  23957. +#endif
  23958. +
  23959. + high_bus_freq_mode = 1;
  23960. + med_bus_freq_mode = 0;
  23961. + low_bus_freq_mode = 0;
  23962. + audio_bus_freq_mode = 0;
  23963. + ultra_low_bus_freq_mode = 0;
  23964. +
  23965. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  23966. + bus_freq_scaling_is_active = 1;
  23967. + bus_freq_scaling_initialized = 1;
  23968. +
  23969. + ddr_low_rate = LPAPM_CLK;
  23970. + if (cpu_is_imx6q()) {
  23971. + if (of_property_read_u32(pdev->dev.of_node, "fsl,med_ddr_freq",
  23972. + &ddr_med_rate)) {
  23973. + dev_info(busfreq_dev,
  23974. + "DDR medium rate not supported.\n");
  23975. + ddr_med_rate = ddr_normal_rate;
  23976. + }
  23977. + }
  23978. +
  23979. + INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
  23980. + INIT_DELAYED_WORK(&bus_freq_daemon, bus_freq_daemon_handler);
  23981. + register_pm_notifier(&imx_bus_freq_pm_notifier);
  23982. + register_reboot_notifier(&imx_busfreq_reboot_notifier);
  23983. +
  23984. + if (cpu_is_imx6sl())
  23985. + err = init_mmdc_lpddr2_settings(pdev);
  23986. + else
  23987. + err = init_mmdc_ddr3_settings(pdev);
  23988. + if (err) {
  23989. + dev_err(busfreq_dev, "Busfreq init of MMDC failed\n");
  23990. + return err;
  23991. + }
  23992. +#endif
  23993. + return 0;
  23994. +}
  23995. +
  23996. +static const struct of_device_id imx6_busfreq_ids[] = {
  23997. + { .compatible = "fsl,imx6_busfreq", },
  23998. + { /* sentinel */ }
  23999. +};
  24000. +
  24001. +static struct platform_driver busfreq_driver = {
  24002. + .driver = {
  24003. + .name = "imx6_busfreq",
  24004. + .owner = THIS_MODULE,
  24005. + .of_match_table = imx6_busfreq_ids,
  24006. + },
  24007. + .probe = busfreq_probe,
  24008. +};
  24009. +
  24010. +/*!
  24011. + * Initialise the busfreq_driver.
  24012. + *
  24013. + * @return The function always returns 0.
  24014. + */
  24015. +
  24016. +static int __init busfreq_init(void)
  24017. +{
  24018. + if (platform_driver_register(&busfreq_driver) != 0)
  24019. + return -ENODEV;
  24020. +
  24021. + printk(KERN_INFO "Bus freq driver module loaded\n");
  24022. +
  24023. + return 0;
  24024. +}
  24025. +
  24026. +static void __exit busfreq_cleanup(void)
  24027. +{
  24028. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  24029. + sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
  24030. +
  24031. + bus_freq_scaling_initialized = 0;
  24032. +#endif
  24033. + /* Unregister the device structure */
  24034. + platform_driver_unregister(&busfreq_driver);
  24035. +}
  24036. +
  24037. +module_init(busfreq_init);
  24038. +module_exit(busfreq_cleanup);
  24039. +
  24040. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  24041. +MODULE_DESCRIPTION("BusFreq driver");
  24042. +MODULE_LICENSE("GPL");
  24043. diff -Nur linux-3.14.17/arch/arm/mach-imx/busfreq_lpddr2.c linux-imx6-3.14/arch/arm/mach-imx/busfreq_lpddr2.c
  24044. --- linux-3.14.17/arch/arm/mach-imx/busfreq_lpddr2.c 1970-01-01 01:00:00.000000000 +0100
  24045. +++ linux-imx6-3.14/arch/arm/mach-imx/busfreq_lpddr2.c 2014-09-11 18:05:53.278003110 +0200
  24046. @@ -0,0 +1,183 @@
  24047. +/*
  24048. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  24049. + */
  24050. +
  24051. +/*
  24052. + * The code contained herein is licensed under the GNU General Public
  24053. + * License. You may obtain a copy of the GNU General Public License
  24054. + * Version 2 or later at the following locations:
  24055. + *
  24056. + * http://www.opensource.org/licenses/gpl-license.html
  24057. + * http://www.gnu.org/copyleft/gpl.html
  24058. + */
  24059. +
  24060. +/*!
  24061. + * @file busfreq_lpddr2.c
  24062. + *
  24063. + * @brief iMX6 LPDDR2 frequency change specific file.
  24064. + *
  24065. + * @ingroup PM
  24066. + */
  24067. +#include <asm/cacheflush.h>
  24068. +#include <asm/fncpy.h>
  24069. +#include <asm/io.h>
  24070. +#include <asm/mach/map.h>
  24071. +#include <asm/mach-types.h>
  24072. +#include <asm/tlb.h>
  24073. +#include <linux/clk.h>
  24074. +#include <linux/cpumask.h>
  24075. +#include <linux/delay.h>
  24076. +#include <linux/genalloc.h>
  24077. +#include <linux/interrupt.h>
  24078. +#include <linux/irqchip/arm-gic.h>
  24079. +#include <linux/kernel.h>
  24080. +#include <linux/mutex.h>
  24081. +#include <linux/of.h>
  24082. +#include <linux/of_address.h>
  24083. +#include <linux/of_device.h>
  24084. +#include <linux/platform_device.h>
  24085. +#include <linux/proc_fs.h>
  24086. +#include <linux/sched.h>
  24087. +#include <linux/smp.h>
  24088. +
  24089. +#include "hardware.h"
  24090. +
  24091. +/* DDR settings */
  24092. +static void __iomem *mmdc_base;
  24093. +static void __iomem *anatop_base;
  24094. +static void __iomem *ccm_base;
  24095. +static void __iomem *l2_base;
  24096. +static struct device *busfreq_dev;
  24097. +static void *ddr_freq_change_iram_base;
  24098. +static int curr_ddr_rate;
  24099. +
  24100. +unsigned long reg_addrs[4];
  24101. +
  24102. +void (*mx6_change_lpddr2_freq)(u32 ddr_freq, int bus_freq_mode,
  24103. + void *iram_addr) = NULL;
  24104. +
  24105. +extern unsigned int ddr_normal_rate;
  24106. +extern int low_bus_freq_mode;
  24107. +extern int ultra_low_bus_freq_mode;
  24108. +extern void mx6_lpddr2_freq_change(u32 freq, int bus_freq_mode,
  24109. + void *iram_addr);
  24110. +
  24111. +
  24112. +#define LPDDR2_FREQ_CHANGE_SIZE 0x1000
  24113. +
  24114. +
  24115. +/* change the DDR frequency. */
  24116. +int update_lpddr2_freq(int ddr_rate)
  24117. +{
  24118. + if (ddr_rate == curr_ddr_rate)
  24119. + return 0;
  24120. +
  24121. + dev_dbg(busfreq_dev, "\nBus freq set to %d start...\n", ddr_rate);
  24122. +
  24123. + /*
  24124. + * Flush the TLB, to ensure no TLB maintenance occurs
  24125. + * when DDR is in self-refresh.
  24126. + */
  24127. + local_flush_tlb_all();
  24128. + /* Now change DDR frequency. */
  24129. + mx6_change_lpddr2_freq(ddr_rate,
  24130. + (low_bus_freq_mode | ultra_low_bus_freq_mode),
  24131. + reg_addrs);
  24132. +
  24133. + curr_ddr_rate = ddr_rate;
  24134. +
  24135. + dev_dbg(busfreq_dev, "\nBus freq set to %d done...\n", ddr_rate);
  24136. +
  24137. + return 0;
  24138. +}
  24139. +
  24140. +int init_mmdc_lpddr2_settings(struct platform_device *busfreq_pdev)
  24141. +{
  24142. + struct platform_device *ocram_dev;
  24143. + unsigned int iram_paddr;
  24144. + struct device_node *node;
  24145. + struct gen_pool *iram_pool;
  24146. +
  24147. + busfreq_dev = &busfreq_pdev->dev;
  24148. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-mmdc");
  24149. + if (!node) {
  24150. + printk(KERN_ERR "failed to find imx6sl-mmdc device tree data!\n");
  24151. + return -EINVAL;
  24152. + }
  24153. + mmdc_base = of_iomap(node, 0);
  24154. + WARN(!mmdc_base, "unable to map mmdc registers\n");
  24155. +
  24156. + node = NULL;
  24157. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-ccm");
  24158. + if (!node) {
  24159. + printk(KERN_ERR "failed to find imx6sl-ccm device tree data!\n");
  24160. + return -EINVAL;
  24161. + }
  24162. + ccm_base = of_iomap(node, 0);
  24163. + WARN(!ccm_base, "unable to map ccm registers\n");
  24164. +
  24165. + node = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
  24166. + if (!node) {
  24167. + printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
  24168. + return -EINVAL;
  24169. + }
  24170. + l2_base = of_iomap(node, 0);
  24171. + WARN(!l2_base, "unable to map PL310 registers\n");
  24172. +
  24173. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
  24174. + if (!node) {
  24175. + printk(KERN_ERR "failed to find imx6sl-pl310-cache device tree data!\n");
  24176. + return -EINVAL;
  24177. + }
  24178. + anatop_base = of_iomap(node, 0);
  24179. + WARN(!anatop_base, "unable to map anatop registers\n");
  24180. +
  24181. + node = NULL;
  24182. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  24183. + if (!node) {
  24184. + dev_err(busfreq_dev, "%s: failed to find ocram node\n",
  24185. + __func__);
  24186. + return -EINVAL;
  24187. + }
  24188. +
  24189. + ocram_dev = of_find_device_by_node(node);
  24190. + if (!ocram_dev) {
  24191. + dev_err(busfreq_dev, "failed to find ocram device!\n");
  24192. + return -EINVAL;
  24193. + }
  24194. +
  24195. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  24196. + if (!iram_pool) {
  24197. + dev_err(busfreq_dev, "iram pool unavailable!\n");
  24198. + return -EINVAL;
  24199. + }
  24200. +
  24201. + reg_addrs[0] = (unsigned long)anatop_base;
  24202. + reg_addrs[1] = (unsigned long)ccm_base;
  24203. + reg_addrs[2] = (unsigned long)mmdc_base;
  24204. + reg_addrs[3] = (unsigned long)l2_base;
  24205. +
  24206. + ddr_freq_change_iram_base = (void *)gen_pool_alloc(iram_pool,
  24207. + LPDDR2_FREQ_CHANGE_SIZE);
  24208. + if (!ddr_freq_change_iram_base) {
  24209. + dev_err(busfreq_dev,
  24210. + "Cannot alloc iram for ddr freq change code!\n");
  24211. + return -ENOMEM;
  24212. + }
  24213. +
  24214. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  24215. + (unsigned long)ddr_freq_change_iram_base);
  24216. + /*
  24217. + * Need to remap the area here since we want
  24218. + * the memory region to be executable.
  24219. + */
  24220. + ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
  24221. + LPDDR2_FREQ_CHANGE_SIZE,
  24222. + MT_MEMORY_RWX_NONCACHED);
  24223. + mx6_change_lpddr2_freq = (void *)fncpy(ddr_freq_change_iram_base,
  24224. + &mx6_lpddr2_freq_change, LPDDR2_FREQ_CHANGE_SIZE);
  24225. +
  24226. + curr_ddr_rate = ddr_normal_rate;
  24227. +
  24228. + return 0;
  24229. +}
  24230. diff -Nur linux-3.14.17/arch/arm/mach-imx/clk.h linux-imx6-3.14/arch/arm/mach-imx/clk.h
  24231. --- linux-3.14.17/arch/arm/mach-imx/clk.h 2014-08-14 03:38:34.000000000 +0200
  24232. +++ linux-imx6-3.14/arch/arm/mach-imx/clk.h 2014-09-11 18:05:53.302003205 +0200
  24233. @@ -23,7 +23,8 @@
  24234. };
  24235. struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
  24236. - const char *parent_name, void __iomem *base, u32 div_mask);
  24237. + const char *parent_name, void __iomem *base,
  24238. + u32 div_mask, bool always_on);
  24239. struct clk *clk_register_gate2(struct device *dev, const char *name,
  24240. const char *parent_name, unsigned long flags,
  24241. diff -Nur linux-3.14.17/arch/arm/mach-imx/clk-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/clk-imx6q.c
  24242. --- linux-3.14.17/arch/arm/mach-imx/clk-imx6q.c 2014-08-14 03:38:34.000000000 +0200
  24243. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-imx6q.c 2014-09-11 18:05:53.278003110 +0200
  24244. @@ -1,5 +1,5 @@
  24245. /*
  24246. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  24247. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  24248. * Copyright 2011 Linaro Ltd.
  24249. *
  24250. * The code contained herein is licensed under the GNU General Public
  24251. @@ -24,6 +24,8 @@
  24252. #include "common.h"
  24253. #include "hardware.h"
  24254. +#define CCM_CCGR_OFFSET(index) (index * 2)
  24255. +
  24256. static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
  24257. static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
  24258. static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
  24259. @@ -39,6 +41,8 @@
  24260. static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };
  24261. static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
  24262. static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };
  24263. +static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", };
  24264. +static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", };
  24265. 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", };
  24266. static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
  24267. static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
  24268. @@ -72,6 +76,10 @@
  24269. "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref",
  24270. "pcie_ref", "sata_ref",
  24271. };
  24272. +static const char *pll_av_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", };
  24273. +static void __iomem *anatop_base;
  24274. +static void __iomem *ccm_base;
  24275. +
  24276. enum mx6q_clks {
  24277. dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
  24278. @@ -88,11 +96,11 @@
  24279. periph_clk2, periph2_clk2, ipg, ipg_per, esai_pred, esai_podf,
  24280. asrc_pred, asrc_podf, spdif_pred, spdif_podf, can_root, ecspi_root,
  24281. gpu2d_core_podf, gpu3d_core_podf, gpu3d_shader, ipu1_podf, ipu2_podf,
  24282. - ldb_di0_podf, ldb_di1_podf, ipu1_di0_pre, ipu1_di1_pre, ipu2_di0_pre,
  24283. - ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf, ssi2_pred, ssi2_podf,
  24284. - ssi3_pred, ssi3_podf, uart_serial_podf, usdhc1_podf, usdhc2_podf,
  24285. - usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf, emi_podf,
  24286. - emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
  24287. + ldb_di0_podf_unused, ldb_di1_podf_unused, ipu1_di0_pre, ipu1_di1_pre,
  24288. + ipu2_di0_pre, ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf,
  24289. + ssi2_pred, ssi2_podf, ssi3_pred, ssi3_podf, uart_serial_podf,
  24290. + usdhc1_podf, usdhc2_podf, usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf,
  24291. + emi_podf, emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
  24292. mmdc_ch1_axi_podf, arm, ahb, apbh_dma, asrc, can1_ipg, can1_serial,
  24293. can2_ipg, can2_serial, ecspi1, ecspi2, ecspi3, ecspi4, ecspi5, enet,
  24294. esai, gpt_ipg, gpt_ipg_per, gpu2d_core, gpu3d_core, hdmi_iahb,
  24295. @@ -107,7 +115,10 @@
  24296. sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
  24297. usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
  24298. spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div,
  24299. - lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max
  24300. + lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, gpt_3m, video_27m,
  24301. + ldb_di0_div_7, ldb_di1_div_7, ldb_di0_div_sel, ldb_di1_div_sel,
  24302. + caam_mem, caam_aclk, caam_ipg, epit1, epit2, tzasc2, lvds1_in, lvds1_out,
  24303. + pll4_sel, lvds2_in, lvds2_out, anaclk1, anaclk2, clk_max
  24304. };
  24305. static struct clk *clk[clk_max];
  24306. @@ -140,20 +151,131 @@
  24307. { /* sentinel */ }
  24308. };
  24309. +static void init_ldb_clks(enum mx6q_clks new_parent)
  24310. +{
  24311. + u32 reg;
  24312. +
  24313. + /*
  24314. + * Need to follow a strict procedure when changing the LDB
  24315. + * clock, else we can introduce a glitch. Things to keep in
  24316. + * mind:
  24317. + * 1. The current and new parent clocks must be disabled.
  24318. + * 2. The default clock for ldb_dio_clk is mmdc_ch1 which has
  24319. + * no CG bit.
  24320. + * 3. In the RTL implementation of the LDB_DI_CLK_SEL mux
  24321. + * the top four options are in one mux and the PLL3 option along
  24322. + * with another option is in the second mux. There is third mux
  24323. + * used to decide between the first and second mux.
  24324. + * The code below switches the parent to the bottom mux first
  24325. + * and then manipulates the top mux. This ensures that no glitch
  24326. + * will enter the divider.
  24327. + *
  24328. + * Need to disable MMDC_CH1 clock manually as there is no CG bit
  24329. + * for this clock. The only way to disable this clock is to move
  24330. + * it topll3_sw_clk and then to disable pll3_sw_clk
  24331. + * Make sure periph2_clk2_sel is set to pll3_sw_clk
  24332. + */
  24333. + reg = readl_relaxed(ccm_base + 0x18);
  24334. + reg &= ~(1 << 20);
  24335. + writel_relaxed(reg, ccm_base + 0x18);
  24336. +
  24337. + /*
  24338. + * Set MMDC_CH1 mask bit.
  24339. + */
  24340. + reg = readl_relaxed(ccm_base + 0x4);
  24341. + reg |= 1 << 16;
  24342. + writel_relaxed(reg, ccm_base + 0x4);
  24343. +
  24344. + /*
  24345. + * Set the periph2_clk_sel to the top mux so that
  24346. + * mmdc_ch1 is from pll3_sw_clk.
  24347. + */
  24348. + reg = readl_relaxed(ccm_base + 0x14);
  24349. + reg |= 1 << 26;
  24350. + writel_relaxed(reg, ccm_base + 0x14);
  24351. +
  24352. + /*
  24353. + * Wait for the clock switch.
  24354. + */
  24355. + while (readl_relaxed(ccm_base + 0x48))
  24356. + ;
  24357. +
  24358. + /*
  24359. + * Disable pll3_sw_clk by selecting the bypass clock source.
  24360. + */
  24361. + reg = readl_relaxed(ccm_base + 0xc);
  24362. + reg |= 1 << 0;
  24363. + writel_relaxed(reg, ccm_base + 0xc);
  24364. +
  24365. + /*
  24366. + * Set the ldb_di0_clk and ldb_di1_clk to 111b.
  24367. + */
  24368. + reg = readl_relaxed(ccm_base + 0x2c);
  24369. + reg |= ((7 << 9) | (7 << 12));
  24370. + writel_relaxed(reg, ccm_base + 0x2c);
  24371. +
  24372. + /*
  24373. + * Set the ldb_di0_clk and ldb_di1_clk to 100b.
  24374. + */
  24375. + reg = readl_relaxed(ccm_base + 0x2c);
  24376. + reg &= ~((7 << 9) | (7 << 12));
  24377. + reg |= ((4 << 9) | (4 << 12));
  24378. + writel_relaxed(reg, ccm_base + 0x2c);
  24379. +
  24380. + /*
  24381. + * Perform the LDB parent clock switch.
  24382. + */
  24383. + clk_set_parent(clk[ldb_di0_sel], clk[new_parent]);
  24384. + clk_set_parent(clk[ldb_di1_sel], clk[new_parent]);
  24385. +
  24386. + /*
  24387. + * Unbypass pll3_sw_clk.
  24388. + */
  24389. + reg = readl_relaxed(ccm_base + 0xc);
  24390. + reg &= ~(1 << 0);
  24391. + writel_relaxed(reg, ccm_base + 0xc);
  24392. +
  24393. + /*
  24394. + * Set the periph2_clk_sel back to the bottom mux so that
  24395. + * mmdc_ch1 is from its original parent.
  24396. + */
  24397. + reg = readl_relaxed(ccm_base + 0x14);
  24398. + reg &= ~(1 << 26);
  24399. + writel_relaxed(reg, ccm_base + 0x14);
  24400. +
  24401. + /*
  24402. + * Wait for the clock switch.
  24403. + */
  24404. + while (readl_relaxed(ccm_base + 0x48))
  24405. + ;
  24406. +
  24407. + /*
  24408. + * Clear MMDC_CH1 mask bit.
  24409. + */
  24410. + reg = readl_relaxed(ccm_base + 0x4);
  24411. + reg &= ~(1 << 16);
  24412. + writel_relaxed(reg, ccm_base + 0x4);
  24413. +
  24414. +}
  24415. +
  24416. static void __init imx6q_clocks_init(struct device_node *ccm_node)
  24417. {
  24418. struct device_node *np;
  24419. void __iomem *base;
  24420. int i, irq;
  24421. int ret;
  24422. + u32 reg;
  24423. clk[dummy] = imx_clk_fixed("dummy", 0);
  24424. clk[ckil] = imx_obtain_fixed_clock("ckil", 0);
  24425. clk[ckih] = imx_obtain_fixed_clock("ckih1", 0);
  24426. clk[osc] = imx_obtain_fixed_clock("osc", 0);
  24427. + /* Clock source from external clock via ANACLK1/2 PADs */
  24428. + clk[anaclk1] = imx_obtain_fixed_clock("anaclk1", 0);
  24429. + clk[anaclk2] = imx_obtain_fixed_clock("anaclk2", 0);
  24430. np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
  24431. - base = of_iomap(np, 0);
  24432. + anatop_base = base = of_iomap(np, 0);
  24433. WARN_ON(!base);
  24434. /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */
  24435. @@ -165,13 +287,18 @@
  24436. };
  24437. /* type name parent_name base div_mask */
  24438. - clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
  24439. - clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
  24440. - clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
  24441. - clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
  24442. - clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
  24443. - clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
  24444. - clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
  24445. + clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f, false);
  24446. + clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1, false);
  24447. + clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3, false);
  24448. + clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "pll4_sel", base + 0x70, 0x7f, false);
  24449. + clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f, false);
  24450. + clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3, false);
  24451. + clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3, false);
  24452. +
  24453. + /* name reg shift width parent_names num_parents */
  24454. + clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24455. + clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24456. + clk[pll4_sel] = imx_clk_mux("pll4_sel", base + 0x70, 14, 2, pll_av_sels, ARRAY_SIZE(pll_av_sels));
  24457. /*
  24458. * Bit 20 is the reserved and read-only bit, we do this only for:
  24459. @@ -191,6 +318,11 @@
  24460. clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
  24461. clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
  24462. + /* NOTICE: The gate of the lvds1/2 in/out is used to select the clk direction */
  24463. + clk[lvds1_in] = imx_clk_gate("lvds1_in", "anaclk1", base + 0x160, 12);
  24464. + clk[lvds2_in] = imx_clk_gate("lvds2_in", "anaclk2", base + 0x160, 13);
  24465. + clk[lvds1_out] = imx_clk_gate("lvds1_out", "lvds1_sel", base + 0x160, 10);
  24466. + clk[lvds2_out] = imx_clk_gate("lvds2_out", "lvds2_sel", base + 0x160, 11);
  24467. clk[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
  24468. clk[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
  24469. @@ -199,18 +331,6 @@
  24470. base + 0xe0, 0, 2, 0, clk_enet_ref_table,
  24471. &imx_ccm_lock);
  24472. - clk[lvds1_sel] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24473. - clk[lvds2_sel] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
  24474. -
  24475. - /*
  24476. - * lvds1_gate and lvds2_gate are pseudo-gates. Both can be
  24477. - * independently configured as clock inputs or outputs. We treat
  24478. - * the "output_enable" bit as a gate, even though it's really just
  24479. - * enabling clock output.
  24480. - */
  24481. - clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10);
  24482. - clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11);
  24483. -
  24484. /* name parent_name reg idx */
  24485. clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
  24486. clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
  24487. @@ -226,6 +346,8 @@
  24488. clk[pll3_80m] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24489. clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24490. clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
  24491. + clk[gpt_3m] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
  24492. + clk[video_27m] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20);
  24493. 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);
  24494. 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);
  24495. @@ -233,7 +355,7 @@
  24496. 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);
  24497. np = ccm_node;
  24498. - base = of_iomap(np, 0);
  24499. + ccm_base = base = of_iomap(np, 0);
  24500. WARN_ON(!base);
  24501. imx6q_pm_set_ccm_base(base);
  24502. @@ -258,14 +380,16 @@
  24503. clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
  24504. 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);
  24505. 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);
  24506. - 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));
  24507. - 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));
  24508. - 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));
  24509. - 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));
  24510. - clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
  24511. - clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
  24512. - clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
  24513. - clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
  24514. + 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);
  24515. + 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);
  24516. + 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);
  24517. + 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);
  24518. + 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);
  24519. + 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);
  24520. + 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);
  24521. + 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);
  24522. + 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);
  24523. + 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);
  24524. clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
  24525. clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
  24526. clk[ssi1_sel] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
  24527. @@ -307,9 +431,9 @@
  24528. clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
  24529. clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
  24530. clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
  24531. - clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
  24532. + clk[ldb_di0_div_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7);
  24533. clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
  24534. - clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0);
  24535. + clk[ldb_di1_div_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7);
  24536. clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
  24537. clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
  24538. clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
  24539. @@ -344,6 +468,9 @@
  24540. /* name parent_name reg shift */
  24541. clk[apbh_dma] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4);
  24542. clk[asrc] = imx_clk_gate2("asrc", "asrc_podf", base + 0x68, 6);
  24543. + clk[caam_mem] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8);
  24544. + clk[caam_aclk] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10);
  24545. + clk[caam_ipg] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12);
  24546. clk[can1_ipg] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
  24547. clk[can1_serial] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
  24548. clk[can2_ipg] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
  24549. @@ -354,6 +481,8 @@
  24550. clk[ecspi4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
  24551. clk[ecspi5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
  24552. clk[enet] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
  24553. + clk[epit1] = imx_clk_gate2("epit1", "ipg", base + 0x6c, 12);
  24554. + clk[epit2] = imx_clk_gate2("epit2", "ipg", base + 0x6c, 14);
  24555. clk[esai] = imx_clk_gate2("esai", "esai_podf", base + 0x6c, 16);
  24556. clk[gpt_ipg] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
  24557. clk[gpt_ipg_per] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
  24558. @@ -373,15 +502,16 @@
  24559. clk[i2c3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
  24560. clk[iim] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
  24561. clk[enfc] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
  24562. + clk[tzasc2] = imx_clk_gate2("tzasc2", "mmdc_ch0_axi_podf", base + 0x70, 24);
  24563. clk[vdoa] = imx_clk_gate2("vdoa", "vdo_axi", base + 0x70, 26);
  24564. clk[ipu1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0);
  24565. clk[ipu1_di0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2);
  24566. clk[ipu1_di1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
  24567. clk[ipu2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
  24568. clk[ipu2_di0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
  24569. - clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
  24570. - clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
  24571. clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
  24572. + clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12);
  24573. + clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_div_sel", base + 0x74, 14);
  24574. clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16);
  24575. if (cpu_is_imx6dl())
  24576. /*
  24577. @@ -413,6 +543,9 @@
  24578. clk[ssi1_ipg] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18);
  24579. clk[ssi2_ipg] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20);
  24580. clk[ssi3_ipg] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22);
  24581. + clk[ssi1] = imx_clk_gate2("ssi1", "ssi1_podf", base + 0x7c, 18);
  24582. + clk[ssi2] = imx_clk_gate2("ssi2", "ssi2_podf", base + 0x7c, 20);
  24583. + clk[ssi3] = imx_clk_gate2("ssi3", "ssi3_podf", base + 0x7c, 22);
  24584. clk[uart_ipg] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
  24585. clk[uart_serial] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
  24586. clk[usboh3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
  24587. @@ -431,25 +564,79 @@
  24588. pr_err("i.MX6q clk %d: register failed with %ld\n",
  24589. i, PTR_ERR(clk[i]));
  24590. + /* Initialize clock gate status */
  24591. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24592. + 3 << CCM_CCGR_OFFSET(1) |
  24593. + 3 << CCM_CCGR_OFFSET(0), base + 0x68);
  24594. + if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
  24595. + writel_relaxed(3 << CCM_CCGR_OFFSET(11) |
  24596. + 3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24597. + else
  24598. + writel_relaxed(3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24599. + writel_relaxed(1 << CCM_CCGR_OFFSET(12) |
  24600. + 3 << CCM_CCGR_OFFSET(11) |
  24601. + 3 << CCM_CCGR_OFFSET(10) |
  24602. + 3 << CCM_CCGR_OFFSET(9) |
  24603. + 3 << CCM_CCGR_OFFSET(8), base + 0x70);
  24604. + writel_relaxed(3 << CCM_CCGR_OFFSET(14) |
  24605. + 1 << CCM_CCGR_OFFSET(13) |
  24606. + 3 << CCM_CCGR_OFFSET(12) |
  24607. + 1 << CCM_CCGR_OFFSET(11) |
  24608. + 3 << CCM_CCGR_OFFSET(10), base + 0x74);
  24609. + writel_relaxed(3 << CCM_CCGR_OFFSET(7) |
  24610. + 3 << CCM_CCGR_OFFSET(6) |
  24611. + 3 << CCM_CCGR_OFFSET(4), base + 0x78);
  24612. + writel_relaxed(1 << CCM_CCGR_OFFSET(0), base + 0x7c);
  24613. + writel_relaxed(0, base + 0x80);
  24614. +
  24615. + /* Make sure PFDs are disabled at boot. */
  24616. + reg = readl_relaxed(anatop_base + 0x100);
  24617. + /* Cannot disable pll2_pfd2_396M, as it is the MMDC clock in iMX6DL */
  24618. + if (cpu_is_imx6dl())
  24619. + reg |= 0x80008080;
  24620. + else
  24621. + reg |= 0x80808080;
  24622. + writel_relaxed(reg, anatop_base + 0x100);
  24623. +
  24624. + /* Disable PLL3 PFDs. */
  24625. + reg = readl_relaxed(anatop_base + 0xF0);
  24626. + reg |= 0x80808080;
  24627. + writel_relaxed(reg, anatop_base + 0xF0);
  24628. +
  24629. + /* Make sure PLLs is disabled */
  24630. + reg = readl_relaxed(anatop_base + 0xA0);
  24631. + reg &= ~(1 << 13);
  24632. + writel_relaxed(reg, anatop_base + 0xA0);
  24633. +
  24634. clk_data.clks = clk;
  24635. clk_data.clk_num = ARRAY_SIZE(clk);
  24636. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  24637. clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
  24638. clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
  24639. + clk_register_clkdev(clk[gpt_3m], "gpt_3m", "imx-gpt.0");
  24640. clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
  24641. clk_register_clkdev(clk[ahb], "ahb", NULL);
  24642. clk_register_clkdev(clk[cko1], "cko1", NULL);
  24643. clk_register_clkdev(clk[arm], NULL, "cpu0");
  24644. - clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
  24645. - clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
  24646. + clk_register_clkdev(clk[pll4_audio_div], "pll4_audio_div", NULL);
  24647. + clk_register_clkdev(clk[pll4_sel], "pll4_sel", NULL);
  24648. + clk_register_clkdev(clk[lvds2_in], "lvds2_in", NULL);
  24649. + clk_register_clkdev(clk[esai], "esai", NULL);
  24650. - if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) ||
  24651. - cpu_is_imx6dl()) {
  24652. - clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
  24653. - clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]);
  24654. + if (cpu_is_imx6dl()) {
  24655. + clk_set_parent(clk[ipu1_sel], clk[pll3_pfd1_540m]);
  24656. }
  24657. + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
  24658. + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
  24659. + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
  24660. + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
  24661. + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
  24662. + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
  24663. + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
  24664. + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
  24665. +
  24666. /*
  24667. * The gpmi needs 100MHz frequency in the EDO/Sync mode,
  24668. * We can not get the 100MHz from the pll2_pfd0_352m.
  24669. @@ -457,6 +644,19 @@
  24670. */
  24671. clk_set_parent(clk[enfc_sel], clk[pll2_pfd2_396m]);
  24672. + /* Set the parent clks of PCIe lvds1 and pcie_axi to be sata ref, axi */
  24673. + if (clk_set_parent(clk[lvds1_sel], clk[sata_ref]))
  24674. + pr_err("Failed to set PCIe bus parent clk.\n");
  24675. + if (clk_set_parent(clk[pcie_axi_sel], clk[axi]))
  24676. + pr_err("Failed to set PCIe parent clk.\n");
  24677. +
  24678. + /* gpu clock initilazation */
  24679. + clk_set_parent(clk[gpu3d_shader_sel], clk[pll2_pfd1_594m]);
  24680. + clk_set_rate(clk[gpu3d_shader], 594000000);
  24681. + clk_set_parent(clk[gpu3d_core_sel], clk[mmdc_ch0_axi]);
  24682. + clk_set_rate(clk[gpu3d_core], 528000000);
  24683. + clk_set_parent(clk[gpu2d_core_sel], clk[pll3_usb_otg]);
  24684. +
  24685. for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
  24686. clk_prepare_enable(clk[clks_init_on[i]]);
  24687. @@ -465,6 +665,25 @@
  24688. clk_prepare_enable(clk[usbphy2_gate]);
  24689. }
  24690. + /* ipu clock initialization */
  24691. + init_ldb_clks(pll2_pfd0_352m);
  24692. + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]);
  24693. + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]);
  24694. + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]);
  24695. + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]);
  24696. + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]);
  24697. + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]);
  24698. + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]);
  24699. + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]);
  24700. + if (cpu_is_imx6dl()) {
  24701. + clk_set_rate(clk[pll3_pfd1_540m], 540000000);
  24702. + clk_set_parent(clk[ipu1_sel], clk[pll3_pfd1_540m]);
  24703. + clk_set_parent(clk[axi_sel], clk[pll3_pfd1_540m]);
  24704. + } else if (cpu_is_imx6q()) {
  24705. + clk_set_parent(clk[ipu1_sel], clk[mmdc_ch0_axi]);
  24706. + clk_set_parent(clk[ipu2_sel], clk[mmdc_ch0_axi]);
  24707. + }
  24708. +
  24709. /*
  24710. * Let's initially set up CLKO with OSC24M, since this configuration
  24711. * is widely used by imx6q board designs to clock audio codec.
  24712. @@ -482,6 +701,18 @@
  24713. if (IS_ENABLED(CONFIG_PCI_IMX6))
  24714. clk_set_parent(clk[lvds1_sel], clk[sata_ref]);
  24715. + /* Audio clocks */
  24716. + clk_set_parent(clk[ssi1_sel], clk[pll4_audio_div]);
  24717. + clk_set_parent(clk[ssi2_sel], clk[pll4_audio_div]);
  24718. + clk_set_parent(clk[ssi3_sel], clk[pll4_audio_div]);
  24719. + clk_set_parent(clk[esai_sel], clk[pll4_audio_div]);
  24720. + clk_set_parent(clk[spdif_sel], clk[pll3_pfd3_454m]);
  24721. + clk_set_parent(clk[asrc_sel], clk[pll3_usb_otg]);
  24722. + clk_set_rate(clk[asrc_sel], 7500000);
  24723. +
  24724. + /* Set pll4_audio to a value that can derive 5K-88.2KHz and 8K-96KHz */
  24725. + clk_set_rate(clk[pll4_audio_div], 541900800);
  24726. +
  24727. /* Set initial power mode */
  24728. imx6q_set_lpm(WAIT_CLOCKED);
  24729. diff -Nur linux-3.14.17/arch/arm/mach-imx/clk-imx6sl.c linux-imx6-3.14/arch/arm/mach-imx/clk-imx6sl.c
  24730. --- linux-3.14.17/arch/arm/mach-imx/clk-imx6sl.c 2014-08-14 03:38:34.000000000 +0200
  24731. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-imx6sl.c 2014-09-11 18:05:53.278003110 +0200
  24732. @@ -7,9 +7,29 @@
  24733. *
  24734. */
  24735. +#define CCM_CCDR_OFFSET 0x4
  24736. +#define ANATOP_PLL_USB1 0x10
  24737. +#define ANATOP_PLL_USB2 0x20
  24738. +#define ANATOP_PLL_ENET 0xE0
  24739. +#define ANATOP_PLL_BYPASS_OFFSET (1 << 16)
  24740. +#define ANATOP_PLL_ENABLE_OFFSET (1 << 13)
  24741. +#define ANATOP_PLL_POWER_OFFSET (1 << 12)
  24742. +#define ANATOP_PFD_480n_OFFSET 0xf0
  24743. +#define ANATOP_PFD_528n_OFFSET 0x100
  24744. +#define PFD0_CLKGATE (1 << 7)
  24745. +#define PFD1_CLK_GATE (1 << 15)
  24746. +#define PFD2_CLK_GATE (1 << 23)
  24747. +#define PFD3_CLK_GATE (1 << 31)
  24748. +#define CCDR_CH0_HS_BYP 17
  24749. +#define OSC_RATE 24000000
  24750. +
  24751. +#define CCM_CCGR_OFFSET(index) (index * 2)
  24752. +
  24753. #include <linux/clk.h>
  24754. #include <linux/clkdev.h>
  24755. #include <linux/err.h>
  24756. +#include <linux/init.h>
  24757. +#include <linux/io.h>
  24758. #include <linux/of.h>
  24759. #include <linux/of_address.h>
  24760. #include <linux/of_irq.h>
  24761. @@ -18,6 +38,7 @@
  24762. #include "clk.h"
  24763. #include "common.h"
  24764. +static bool uart_from_osc;
  24765. static const char const *step_sels[] = { "osc", "pll2_pfd2", };
  24766. static const char const *pll1_sw_sels[] = { "pll1_sys", "step", };
  24767. static const char const *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", };
  24768. @@ -25,8 +46,8 @@
  24769. static const char const *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
  24770. static const char const *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
  24771. static const char const *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
  24772. -static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", };
  24773. -static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", };
  24774. +static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2", };
  24775. +static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2", };
  24776. static const char const *csi_lcdif_sels[] = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
  24777. static const char const *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
  24778. static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", };
  24779. @@ -38,7 +59,7 @@
  24780. static const char const *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
  24781. static const char const *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
  24782. static const char const *ecspi_sels[] = { "pll3_60m", "osc", };
  24783. -static const char const *uart_sels[] = { "pll3_80m", "osc", };
  24784. +static const char const *uart_sels[] = { "pll3_80m", "uart_osc_4M", };
  24785. static struct clk_div_table clk_enet_ref_table[] = {
  24786. { .val = 0, .div = 20, },
  24787. @@ -65,6 +86,80 @@
  24788. static struct clk *clks[IMX6SL_CLK_END];
  24789. static struct clk_onecell_data clk_data;
  24790. +static u32 cur_arm_podf;
  24791. +static u32 pll1_org_rate;
  24792. +
  24793. +extern int low_bus_freq_mode;
  24794. +extern int audio_bus_freq_mode;
  24795. +
  24796. +/*
  24797. + * On MX6SL, need to ensure that the ARM:IPG clock ratio is maintained
  24798. + * within 12:5 when the clocks to ARM are gated when the SOC enters
  24799. + * WAIT mode. This is necessary to avoid WAIT mode issue (an early
  24800. + * interrupt waking up the ARM).
  24801. + * This function will set the ARM clk to max value within the 12:5 limit.
  24802. + */
  24803. +void imx6sl_set_wait_clk(bool enter)
  24804. +{
  24805. + u32 parent_rate;
  24806. +
  24807. + if (enter) {
  24808. + u32 wait_podf;
  24809. + u32 new_parent_rate = OSC_RATE;
  24810. + u32 ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]);
  24811. + u32 max_arm_wait_clk = (12 * ipg_rate) / 5;
  24812. + parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24813. + cur_arm_podf = parent_rate / clk_get_rate(clks[IMX6SL_CLK_ARM]);
  24814. + if (low_bus_freq_mode) {
  24815. + /*
  24816. + * IPG clk is at 12MHz at this point, we can only run
  24817. + * ARM at a max of 28.8MHz. So we need to set ARM
  24818. + * to run from the 24MHz OSC, as there is no way to
  24819. + * get 28.8MHz when ARM is sourced from PLL1.
  24820. + */
  24821. + clk_set_parent(clks[IMX6SL_CLK_STEP],
  24822. + clks[IMX6SL_CLK_OSC]);
  24823. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW],
  24824. + clks[IMX6SL_CLK_STEP]);
  24825. + } else if (audio_bus_freq_mode) {
  24826. + /*
  24827. + * In this mode ARM is from PLL2_PFD2 (396MHz),
  24828. + * but IPG is at 12MHz. Need to switch ARM to run
  24829. + * from the bypassed PLL1 clocks so that we can run
  24830. + * ARM at 24MHz.
  24831. + */
  24832. + pll1_org_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SYS]);
  24833. + /* Ensure PLL1 is at 24MHz. */
  24834. + clk_set_rate(clks[IMX6SL_CLK_PLL1_SYS], OSC_RATE);
  24835. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW], clks[IMX6SL_CLK_PLL1_SYS]);
  24836. + } else
  24837. + new_parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24838. + wait_podf = (new_parent_rate + max_arm_wait_clk - 1) /
  24839. + max_arm_wait_clk;
  24840. +
  24841. + clk_set_rate(clks[IMX6SL_CLK_ARM], new_parent_rate / wait_podf);
  24842. + } else {
  24843. + if (low_bus_freq_mode)
  24844. + /* Move ARM back to PLL1. */
  24845. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW],
  24846. + clks[IMX6SL_CLK_PLL1_SYS]);
  24847. + else if (audio_bus_freq_mode) {
  24848. + /* Move ARM back to PLL2_PFD2 via STEP_CLK. */
  24849. + clk_set_parent(clks[IMX6SL_CLK_PLL1_SW], clks[IMX6SL_CLK_STEP]);
  24850. + clk_set_rate(clks[IMX6SL_CLK_PLL1_SYS], pll1_org_rate);
  24851. + }
  24852. + parent_rate = clk_get_rate(clks[IMX6SL_CLK_PLL1_SW]);
  24853. + clk_set_rate(clks[IMX6SL_CLK_ARM], parent_rate / cur_arm_podf);
  24854. + }
  24855. +}
  24856. +
  24857. +static int __init setup_uart_clk(char *uart_rate)
  24858. +{
  24859. + uart_from_osc = true;
  24860. + return 1;
  24861. +}
  24862. +
  24863. +__setup("uart_at_4M", setup_uart_clk);
  24864. static void __init imx6sl_clocks_init(struct device_node *ccm_node)
  24865. {
  24866. @@ -72,6 +167,8 @@
  24867. void __iomem *base;
  24868. int irq;
  24869. int i;
  24870. + int ret;
  24871. + u32 reg;
  24872. clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
  24873. clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
  24874. @@ -82,13 +179,18 @@
  24875. WARN_ON(!base);
  24876. /* type name parent base div_mask */
  24877. - clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
  24878. - clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
  24879. - clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
  24880. - clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
  24881. - clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
  24882. - clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
  24883. - clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3);
  24884. + clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f, true);
  24885. + clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1, true);
  24886. + clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3, false);
  24887. + clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f, false);
  24888. + clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f, false);
  24889. + clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3, false);
  24890. + clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3, false);
  24891. +
  24892. + /* Ensure the AHB clk is at 132MHz. */
  24893. + ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
  24894. + if (ret)
  24895. + pr_warn("%s: failed to set AHB clock rate %d\n", __func__, ret);
  24896. /*
  24897. * usbphy1 and usbphy2 are implemented as dummy gates using reserve
  24898. @@ -118,11 +220,36 @@
  24899. clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2);
  24900. clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3);
  24901. - /* name parent_name mult div */
  24902. - clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
  24903. - clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
  24904. - clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24905. - clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24906. + /* name parent_name mult div */
  24907. + clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
  24908. + clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
  24909. + clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
  24910. + clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
  24911. + clks[IMX6SL_CLK_UART_OSC_4M] = imx_clk_fixed_factor("uart_osc_4M", "osc", 1, 6);
  24912. +
  24913. + /* Ensure all PFDs but PLL2_PFD2 are disabled. */
  24914. + reg = readl_relaxed(base + ANATOP_PFD_480n_OFFSET);
  24915. + reg |= (PFD0_CLKGATE | PFD1_CLK_GATE | PFD2_CLK_GATE | PFD3_CLK_GATE);
  24916. + writel_relaxed(reg, base + ANATOP_PFD_480n_OFFSET);
  24917. + reg = readl_relaxed(base + ANATOP_PFD_528n_OFFSET);
  24918. + reg |= (PFD0_CLKGATE | PFD1_CLK_GATE);
  24919. + writel_relaxed(reg, base + ANATOP_PFD_528n_OFFSET);
  24920. +
  24921. + /* Ensure Unused PLLs are disabled. */
  24922. + reg = readl_relaxed(base + ANATOP_PLL_USB1);
  24923. + reg |= ANATOP_PLL_BYPASS_OFFSET;
  24924. + reg &= ~(ANATOP_PLL_ENABLE_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24925. + writel_relaxed(reg, base + ANATOP_PLL_USB1);
  24926. +
  24927. + reg = readl_relaxed(base + ANATOP_PLL_USB2);
  24928. + reg |= ANATOP_PLL_BYPASS_OFFSET;
  24929. + reg &= ~(ANATOP_PLL_ENABLE_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24930. + writel_relaxed(reg, base + ANATOP_PLL_USB2);
  24931. +
  24932. + reg = readl_relaxed(base + ANATOP_PLL_ENET);
  24933. + reg |= (ANATOP_PLL_BYPASS_OFFSET | ANATOP_PLL_POWER_OFFSET);
  24934. + reg &= ~ANATOP_PLL_ENABLE_OFFSET;
  24935. + writel_relaxed(reg, base + ANATOP_PLL_ENET);
  24936. np = ccm_node;
  24937. base = of_iomap(np, 0);
  24938. @@ -158,7 +285,7 @@
  24939. clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
  24940. clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24941. clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24942. - clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
  24943. + 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);
  24944. clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
  24945. clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
  24946. @@ -168,8 +295,8 @@
  24947. /* name parent_name reg shift width */
  24948. clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
  24949. - clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
  24950. - clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
  24951. + clks[IMX6SL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
  24952. + clks[IMX6SL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
  24953. clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
  24954. clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
  24955. clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
  24956. @@ -251,6 +378,25 @@
  24957. pr_err("i.MX6SL clk %d: register failed with %ld\n",
  24958. i, PTR_ERR(clks[i]));
  24959. + /* Initialize clock gate status */
  24960. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24961. + 3 << CCM_CCGR_OFFSET(1) |
  24962. + 3 << CCM_CCGR_OFFSET(0), base + 0x68);
  24963. + writel_relaxed(3 << CCM_CCGR_OFFSET(10), base + 0x6c);
  24964. + writel_relaxed(1 << CCM_CCGR_OFFSET(11) |
  24965. + 3 << CCM_CCGR_OFFSET(10) |
  24966. + 3 << CCM_CCGR_OFFSET(9) |
  24967. + 3 << CCM_CCGR_OFFSET(8), base + 0x70);
  24968. + writel_relaxed(3 << CCM_CCGR_OFFSET(14) |
  24969. + 3 << CCM_CCGR_OFFSET(13) |
  24970. + 3 << CCM_CCGR_OFFSET(12) |
  24971. + 3 << CCM_CCGR_OFFSET(11) |
  24972. + 3 << CCM_CCGR_OFFSET(10), base + 0x74);
  24973. + writel_relaxed(3 << CCM_CCGR_OFFSET(7) |
  24974. + 3 << CCM_CCGR_OFFSET(4), base + 0x78);
  24975. + writel_relaxed(1 << CCM_CCGR_OFFSET(0), base + 0x7c);
  24976. + writel_relaxed(0, base + 0x80);
  24977. +
  24978. clk_data.clks = clks;
  24979. clk_data.clk_num = ARRAY_SIZE(clks);
  24980. of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
  24981. @@ -258,17 +404,58 @@
  24982. clk_register_clkdev(clks[IMX6SL_CLK_GPT], "ipg", "imx-gpt.0");
  24983. clk_register_clkdev(clks[IMX6SL_CLK_GPT_SERIAL], "per", "imx-gpt.0");
  24984. + /*
  24985. + * Make sure the ARM clk is enabled to maintain the correct usecount
  24986. + * and enabling/disabling of parent PLLs.
  24987. + */
  24988. + ret = clk_prepare_enable(clks[IMX6SL_CLK_ARM]);
  24989. + if (ret)
  24990. + pr_warn("%s: failed to enable ARM core clock %d\n",
  24991. + __func__, ret);
  24992. +
  24993. + /*
  24994. + * Make sure the MMDC clk is enabled to maintain the correct usecount
  24995. + * and enabling/disabling of parent PLLs.
  24996. + */
  24997. + ret = clk_prepare_enable(clks[IMX6SL_CLK_MMDC_ROOT]);
  24998. + if (ret)
  24999. + pr_warn("%s: failed to enable MMDC clock %d\n",
  25000. + __func__, ret);
  25001. +
  25002. if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
  25003. clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
  25004. clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
  25005. }
  25006. + clk_set_parent(clks[IMX6SL_CLK_GPU2D_OVG_SEL],
  25007. + clks[IMX6SL_CLK_PLL2_BUS]);
  25008. + clk_set_parent(clks[IMX6SL_CLK_GPU2D_SEL], clks[IMX6SL_CLK_PLL2_BUS]);
  25009. +
  25010. /* Audio-related clocks configuration */
  25011. clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]);
  25012. + /* set extern_audio to be sourced from PLL4/audio PLL */
  25013. + clk_set_parent(clks[IMX6SL_CLK_EXTERN_AUDIO_SEL], clks[IMX6SL_CLK_PLL4_AUDIO_DIV]);
  25014. + /* set extern_audio to 24MHz */
  25015. + clk_set_rate(clks[IMX6SL_CLK_PLL4_AUDIO], 24000000);
  25016. + clk_set_rate(clks[IMX6SL_CLK_EXTERN_AUDIO], 24000000);
  25017. +
  25018. + /* set SSI2 parent to PLL4 */
  25019. + clk_set_parent(clks[IMX6SL_CLK_SSI2_SEL], clks[IMX6SL_CLK_PLL4_AUDIO_DIV]);
  25020. + clk_set_rate(clks[IMX6SL_CLK_SSI2], 24000000);
  25021. +
  25022. /* Set initial power mode */
  25023. imx6q_set_lpm(WAIT_CLOCKED);
  25024. + /* Ensure that CH0 handshake is bypassed. */
  25025. + reg = readl_relaxed(base + CCM_CCDR_OFFSET);
  25026. + reg |= 1 << CCDR_CH0_HS_BYP;
  25027. + writel_relaxed(reg, base + CCM_CCDR_OFFSET);
  25028. +
  25029. + /* Set the UART parent if needed. */
  25030. + if (uart_from_osc)
  25031. + ret = clk_set_parent(clks[IMX6SL_CLK_UART_SEL], clks[IMX6SL_CLK_UART_OSC_4M]);
  25032. +
  25033. np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt");
  25034. base = of_iomap(np, 0);
  25035. WARN_ON(!base);
  25036. diff -Nur linux-3.14.17/arch/arm/mach-imx/clk-pfd.c linux-imx6-3.14/arch/arm/mach-imx/clk-pfd.c
  25037. --- linux-3.14.17/arch/arm/mach-imx/clk-pfd.c 2014-08-14 03:38:34.000000000 +0200
  25038. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-pfd.c 2014-09-11 18:05:53.282003126 +0200
  25039. @@ -1,5 +1,5 @@
  25040. /*
  25041. - * Copyright 2012 Freescale Semiconductor, Inc.
  25042. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  25043. * Copyright 2012 Linaro Ltd.
  25044. *
  25045. * The code contained herein is licensed under the GNU General Public
  25046. @@ -17,6 +17,8 @@
  25047. #include <linux/err.h>
  25048. #include "clk.h"
  25049. +#define BYPASS_RATE 24000000
  25050. +
  25051. /**
  25052. * struct clk_pfd - IMX PFD clock
  25053. * @clk_hw: clock source
  25054. @@ -62,9 +64,14 @@
  25055. u64 tmp = parent_rate;
  25056. u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
  25057. - tmp *= 18;
  25058. - do_div(tmp, frac);
  25059. -
  25060. + /*
  25061. + * If the parent PLL is in bypass state, the PFDs
  25062. + * are also in bypass state.
  25063. + */
  25064. + if (tmp != BYPASS_RATE) {
  25065. + tmp *= 18;
  25066. + do_div(tmp, frac);
  25067. + }
  25068. return tmp;
  25069. }
  25070. @@ -74,17 +81,22 @@
  25071. u64 tmp = *prate;
  25072. u8 frac;
  25073. - tmp = tmp * 18 + rate / 2;
  25074. - do_div(tmp, rate);
  25075. - frac = tmp;
  25076. - if (frac < 12)
  25077. - frac = 12;
  25078. - else if (frac > 35)
  25079. - frac = 35;
  25080. - tmp = *prate;
  25081. - tmp *= 18;
  25082. - do_div(tmp, frac);
  25083. -
  25084. + /*
  25085. + * If the parent PLL is in bypass state, the PFDs
  25086. + * are also in bypass state.
  25087. + */
  25088. + if (tmp != BYPASS_RATE) {
  25089. + tmp = tmp * 18 + rate / 2;
  25090. + do_div(tmp, rate);
  25091. + frac = tmp;
  25092. + if (frac < 12)
  25093. + frac = 12;
  25094. + else if (frac > 35)
  25095. + frac = 35;
  25096. + tmp = *prate;
  25097. + tmp *= 18;
  25098. + do_div(tmp, frac);
  25099. + }
  25100. return tmp;
  25101. }
  25102. @@ -95,6 +107,9 @@
  25103. u64 tmp = parent_rate;
  25104. u8 frac;
  25105. + if (tmp == BYPASS_RATE)
  25106. + return 0;
  25107. +
  25108. tmp = tmp * 18 + rate / 2;
  25109. do_div(tmp, rate);
  25110. frac = tmp;
  25111. diff -Nur linux-3.14.17/arch/arm/mach-imx/clk-pllv3.c linux-imx6-3.14/arch/arm/mach-imx/clk-pllv3.c
  25112. --- linux-3.14.17/arch/arm/mach-imx/clk-pllv3.c 2014-08-14 03:38:34.000000000 +0200
  25113. +++ linux-imx6-3.14/arch/arm/mach-imx/clk-pllv3.c 2014-09-11 18:05:53.302003205 +0200
  25114. @@ -26,12 +26,15 @@
  25115. #define BM_PLL_ENABLE (0x1 << 13)
  25116. #define BM_PLL_BYPASS (0x1 << 16)
  25117. #define BM_PLL_LOCK (0x1 << 31)
  25118. +#define BYPASS_RATE 24000000
  25119. +#define BYPASS_MASK 0x10000
  25120. /**
  25121. * struct clk_pllv3 - IMX PLL clock version 3
  25122. * @clk_hw: clock source
  25123. * @base: base address of PLL registers
  25124. * @powerup_set: set POWER bit to power up the PLL
  25125. + * @always_on : Leave the PLL powered up all the time.
  25126. * @div_mask: mask of divider bits
  25127. *
  25128. * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
  25129. @@ -41,7 +44,9 @@
  25130. struct clk_hw hw;
  25131. void __iomem *base;
  25132. bool powerup_set;
  25133. + bool always_on;
  25134. u32 div_mask;
  25135. + u32 rate_req;
  25136. };
  25137. #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
  25138. @@ -61,54 +66,53 @@
  25139. break;
  25140. if (time_after(jiffies, timeout))
  25141. break;
  25142. - usleep_range(50, 500);
  25143. + udelay(100);
  25144. } while (1);
  25145. return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT;
  25146. }
  25147. -static int clk_pllv3_prepare(struct clk_hw *hw)
  25148. +static int clk_pllv3_power_up_down(struct clk_hw *hw, bool enable)
  25149. {
  25150. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25151. - u32 val;
  25152. - int ret;
  25153. -
  25154. - val = readl_relaxed(pll->base);
  25155. - if (pll->powerup_set)
  25156. - val |= BM_PLL_POWER;
  25157. - else
  25158. - val &= ~BM_PLL_POWER;
  25159. - writel_relaxed(val, pll->base);
  25160. -
  25161. - ret = clk_pllv3_wait_lock(pll);
  25162. - if (ret)
  25163. - return ret;
  25164. + u32 val, ret = 0;
  25165. - val = readl_relaxed(pll->base);
  25166. - val &= ~BM_PLL_BYPASS;
  25167. - writel_relaxed(val, pll->base);
  25168. -
  25169. - return 0;
  25170. -}
  25171. + if (enable) {
  25172. + val = readl_relaxed(pll->base);
  25173. + val &= ~BM_PLL_BYPASS;
  25174. + if (pll->powerup_set)
  25175. + val |= BM_PLL_POWER;
  25176. + else
  25177. + val &= ~BM_PLL_POWER;
  25178. + writel_relaxed(val, pll->base);
  25179. +
  25180. + ret = clk_pllv3_wait_lock(pll);
  25181. + } else {
  25182. + val = readl_relaxed(pll->base);
  25183. + val |= BM_PLL_BYPASS;
  25184. + if (pll->powerup_set)
  25185. + val &= ~BM_PLL_POWER;
  25186. + else
  25187. + val |= BM_PLL_POWER;
  25188. + writel_relaxed(val, pll->base);
  25189. + }
  25190. -static void clk_pllv3_unprepare(struct clk_hw *hw)
  25191. -{
  25192. - struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25193. - u32 val;
  25194. + if (!ret) {
  25195. + val = readl_relaxed(pll->base);
  25196. + val &= ~BM_PLL_BYPASS;
  25197. + writel_relaxed(val, pll->base);
  25198. + }
  25199. - val = readl_relaxed(pll->base);
  25200. - val |= BM_PLL_BYPASS;
  25201. - if (pll->powerup_set)
  25202. - val &= ~BM_PLL_POWER;
  25203. - else
  25204. - val |= BM_PLL_POWER;
  25205. - writel_relaxed(val, pll->base);
  25206. + return ret;
  25207. }
  25208. static int clk_pllv3_enable(struct clk_hw *hw)
  25209. {
  25210. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25211. u32 val;
  25212. +
  25213. + if (pll->rate_req != BYPASS_RATE)
  25214. + clk_pllv3_power_up_down(hw, true);
  25215. val = readl_relaxed(pll->base);
  25216. val |= BM_PLL_ENABLE;
  25217. @@ -123,8 +127,12 @@
  25218. u32 val;
  25219. val = readl_relaxed(pll->base);
  25220. - val &= ~BM_PLL_ENABLE;
  25221. + if (!pll->always_on)
  25222. + val &= ~BM_PLL_ENABLE;
  25223. writel_relaxed(val, pll->base);
  25224. +
  25225. + if (pll->rate_req != BYPASS_RATE)
  25226. + clk_pllv3_power_up_down(hw, false);
  25227. }
  25228. static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
  25229. @@ -132,8 +140,15 @@
  25230. {
  25231. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25232. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25233. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25234. + u32 rate;
  25235. +
  25236. + if (pll->rate_req == BYPASS_RATE && bypass)
  25237. + rate = BYPASS_RATE;
  25238. + else
  25239. + rate = (div == 1) ? parent_rate * 22 : parent_rate * 20;
  25240. - return (div == 1) ? parent_rate * 22 : parent_rate * 20;
  25241. + return rate;
  25242. }
  25243. static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
  25244. @@ -141,6 +156,10 @@
  25245. {
  25246. unsigned long parent_rate = *prate;
  25247. + /* If the PLL is bypassed, its rate is 24MHz. */
  25248. + if (rate == BYPASS_RATE)
  25249. + return BYPASS_RATE;
  25250. +
  25251. return (rate >= parent_rate * 22) ? parent_rate * 22 :
  25252. parent_rate * 20;
  25253. }
  25254. @@ -151,6 +170,22 @@
  25255. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25256. u32 val, div;
  25257. + pll->rate_req = rate;
  25258. + val = readl_relaxed(pll->base);
  25259. +
  25260. + /* If the PLL is bypassed, its rate is 24MHz. */
  25261. + if (rate == BYPASS_RATE) {
  25262. + /* Set the bypass bit. */
  25263. + val |= BM_PLL_BYPASS;
  25264. + /* Power down the PLL. */
  25265. + if (pll->powerup_set)
  25266. + val &= ~BM_PLL_POWER;
  25267. + else
  25268. + val |= BM_PLL_POWER;
  25269. + writel_relaxed(val, pll->base);
  25270. +
  25271. + return 0;
  25272. + }
  25273. if (rate == parent_rate * 22)
  25274. div = 1;
  25275. else if (rate == parent_rate * 20)
  25276. @@ -167,8 +202,6 @@
  25277. }
  25278. static const struct clk_ops clk_pllv3_ops = {
  25279. - .prepare = clk_pllv3_prepare,
  25280. - .unprepare = clk_pllv3_unprepare,
  25281. .enable = clk_pllv3_enable,
  25282. .disable = clk_pllv3_disable,
  25283. .recalc_rate = clk_pllv3_recalc_rate,
  25284. @@ -181,6 +214,10 @@
  25285. {
  25286. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25287. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25288. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25289. +
  25290. + if (pll->rate_req == BYPASS_RATE && bypass)
  25291. + return BYPASS_RATE;
  25292. return parent_rate * div / 2;
  25293. }
  25294. @@ -193,6 +230,9 @@
  25295. unsigned long max_rate = parent_rate * 108 / 2;
  25296. u32 div;
  25297. + if (rate == BYPASS_RATE)
  25298. + return BYPASS_RATE;
  25299. +
  25300. if (rate > max_rate)
  25301. rate = max_rate;
  25302. else if (rate < min_rate)
  25303. @@ -210,9 +250,26 @@
  25304. unsigned long max_rate = parent_rate * 108 / 2;
  25305. u32 val, div;
  25306. - if (rate < min_rate || rate > max_rate)
  25307. + if (rate != BYPASS_RATE && (rate < min_rate || rate > max_rate))
  25308. return -EINVAL;
  25309. + pll->rate_req = rate;
  25310. + val = readl_relaxed(pll->base);
  25311. +
  25312. + if (rate == BYPASS_RATE) {
  25313. + /*
  25314. + * Set the PLL in bypass mode if rate requested is
  25315. + * BYPASS_RATE.
  25316. + */
  25317. + val |= BM_PLL_BYPASS;
  25318. + /* Power down the PLL. */
  25319. + if (pll->powerup_set)
  25320. + val &= ~BM_PLL_POWER;
  25321. + else
  25322. + val |= BM_PLL_POWER;
  25323. + writel_relaxed(val, pll->base);
  25324. + return 0;
  25325. + }
  25326. div = rate * 2 / parent_rate;
  25327. val = readl_relaxed(pll->base);
  25328. val &= ~pll->div_mask;
  25329. @@ -223,8 +280,6 @@
  25330. }
  25331. static const struct clk_ops clk_pllv3_sys_ops = {
  25332. - .prepare = clk_pllv3_prepare,
  25333. - .unprepare = clk_pllv3_unprepare,
  25334. .enable = clk_pllv3_enable,
  25335. .disable = clk_pllv3_disable,
  25336. .recalc_rate = clk_pllv3_sys_recalc_rate,
  25337. @@ -239,6 +294,10 @@
  25338. u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
  25339. u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
  25340. u32 div = readl_relaxed(pll->base) & pll->div_mask;
  25341. + u32 bypass = readl_relaxed(pll->base) & BYPASS_MASK;
  25342. +
  25343. + if (pll->rate_req == BYPASS_RATE && bypass)
  25344. + return BYPASS_RATE;
  25345. return (parent_rate * div) + ((parent_rate / mfd) * mfn);
  25346. }
  25347. @@ -253,6 +312,9 @@
  25348. u32 mfn, mfd = 1000000;
  25349. s64 temp64;
  25350. + if (rate == BYPASS_RATE)
  25351. + return BYPASS_RATE;
  25352. +
  25353. if (rate > max_rate)
  25354. rate = max_rate;
  25355. else if (rate < min_rate)
  25356. @@ -273,13 +335,36 @@
  25357. struct clk_pllv3 *pll = to_clk_pllv3(hw);
  25358. unsigned long min_rate = parent_rate * 27;
  25359. unsigned long max_rate = parent_rate * 54;
  25360. - u32 val, div;
  25361. + u32 val, newval, div;
  25362. u32 mfn, mfd = 1000000;
  25363. s64 temp64;
  25364. + int ret;
  25365. - if (rate < min_rate || rate > max_rate)
  25366. + if (rate != BYPASS_RATE && (rate < min_rate || rate > max_rate))
  25367. return -EINVAL;
  25368. + pll->rate_req = rate;
  25369. + val = readl_relaxed(pll->base);
  25370. +
  25371. + if (rate == BYPASS_RATE) {
  25372. + /*
  25373. + * Set the PLL in bypass mode if rate requested is
  25374. + * BYPASS_RATE.
  25375. + */
  25376. + /* Bypass the PLL */
  25377. + val |= BM_PLL_BYPASS;
  25378. + /* Power down the PLL. */
  25379. + if (pll->powerup_set)
  25380. + val &= ~BM_PLL_POWER;
  25381. + else
  25382. + val |= BM_PLL_POWER;
  25383. + writel_relaxed(val, pll->base);
  25384. + return 0;
  25385. + }
  25386. + /* Else clear the bypass bit. */
  25387. + val &= ~BM_PLL_BYPASS;
  25388. + writel_relaxed(val, pll->base);
  25389. +
  25390. div = rate / parent_rate;
  25391. temp64 = (u64) (rate - div * parent_rate);
  25392. temp64 *= mfd;
  25393. @@ -287,18 +372,30 @@
  25394. mfn = temp64;
  25395. val = readl_relaxed(pll->base);
  25396. - val &= ~pll->div_mask;
  25397. - val |= div;
  25398. - writel_relaxed(val, pll->base);
  25399. +
  25400. + /* set the PLL into bypass mode */
  25401. + newval = val | BM_PLL_BYPASS;
  25402. + writel_relaxed(newval, pll->base);
  25403. +
  25404. + /* configure the new frequency */
  25405. + newval &= ~pll->div_mask;
  25406. + newval |= div;
  25407. + writel_relaxed(newval, pll->base);
  25408. writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
  25409. - writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
  25410. + writel(mfd, pll->base + PLL_DENOM_OFFSET);
  25411. - return clk_pllv3_wait_lock(pll);
  25412. + ret = clk_pllv3_wait_lock(pll);
  25413. + if (ret == 0 && val & BM_PLL_POWER) {
  25414. + /* only if it locked can we switch back to the PLL */
  25415. + newval &= ~BM_PLL_BYPASS;
  25416. + newval |= val & BM_PLL_BYPASS;
  25417. + writel(newval, pll->base);
  25418. + }
  25419. +
  25420. + return ret;
  25421. }
  25422. static const struct clk_ops clk_pllv3_av_ops = {
  25423. - .prepare = clk_pllv3_prepare,
  25424. - .unprepare = clk_pllv3_unprepare,
  25425. .enable = clk_pllv3_enable,
  25426. .disable = clk_pllv3_disable,
  25427. .recalc_rate = clk_pllv3_av_recalc_rate,
  25428. @@ -313,8 +410,6 @@
  25429. }
  25430. static const struct clk_ops clk_pllv3_enet_ops = {
  25431. - .prepare = clk_pllv3_prepare,
  25432. - .unprepare = clk_pllv3_unprepare,
  25433. .enable = clk_pllv3_enable,
  25434. .disable = clk_pllv3_disable,
  25435. .recalc_rate = clk_pllv3_enet_recalc_rate,
  25436. @@ -322,7 +417,7 @@
  25437. struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
  25438. const char *parent_name, void __iomem *base,
  25439. - u32 div_mask)
  25440. + u32 div_mask, bool always_on)
  25441. {
  25442. struct clk_pllv3 *pll;
  25443. const struct clk_ops *ops;
  25444. @@ -352,6 +447,7 @@
  25445. }
  25446. pll->base = base;
  25447. pll->div_mask = div_mask;
  25448. + pll->always_on = always_on;
  25449. init.name = name;
  25450. init.ops = ops;
  25451. diff -Nur linux-3.14.17/arch/arm/mach-imx/common.h linux-imx6-3.14/arch/arm/mach-imx/common.h
  25452. --- linux-3.14.17/arch/arm/mach-imx/common.h 2014-08-14 03:38:34.000000000 +0200
  25453. +++ linux-imx6-3.14/arch/arm/mach-imx/common.h 2014-09-11 18:05:53.302003205 +0200
  25454. @@ -1,5 +1,5 @@
  25455. /*
  25456. - * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  25457. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  25458. */
  25459. /*
  25460. @@ -116,7 +116,6 @@
  25461. void imx_set_cpu_jump(int cpu, void *jump_addr);
  25462. u32 imx_get_cpu_arg(int cpu);
  25463. void imx_set_cpu_arg(int cpu, u32 arg);
  25464. -void v7_cpu_resume(void);
  25465. #ifdef CONFIG_SMP
  25466. void v7_secondary_startup(void);
  25467. void imx_scu_map_io(void);
  25468. @@ -129,7 +128,7 @@
  25469. #endif
  25470. void imx_src_init(void);
  25471. void imx_gpc_init(void);
  25472. -void imx_gpc_pre_suspend(void);
  25473. +void imx_gpc_pre_suspend(bool arm_power_off);
  25474. void imx_gpc_post_resume(void);
  25475. void imx_gpc_mask_all(void);
  25476. void imx_gpc_restore_all(void);
  25477. @@ -138,14 +137,28 @@
  25478. void imx_anatop_init(void);
  25479. void imx_anatop_pre_suspend(void);
  25480. void imx_anatop_post_resume(void);
  25481. +void imx_anatop_pu_enable(bool enable);
  25482. int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
  25483. -void imx6q_set_chicken_bit(void);
  25484. +void imx6q_set_cache_lpm_in_wait(bool enable);
  25485. +void imx6sl_set_wait_clk(bool enter);
  25486. +void imx6_enet_mac_init(const char *compatible);
  25487. void imx_cpu_die(unsigned int cpu);
  25488. int imx_cpu_kill(unsigned int cpu);
  25489. +#ifdef CONFIG_SUSPEND
  25490. +void v7_cpu_resume(void);
  25491. +void imx6_suspend(void __iomem *ocram_vbase);
  25492. +#else
  25493. +static inline void v7_cpu_resume(void) {}
  25494. +static inline void imx6_suspend(void __iomem *ocram_vbase) {}
  25495. +#endif
  25496. +
  25497. void imx6q_pm_init(void);
  25498. +void imx6dl_pm_init(void);
  25499. +void imx6sl_pm_init(void);
  25500. void imx6q_pm_set_ccm_base(void __iomem *base);
  25501. +
  25502. #ifdef CONFIG_PM
  25503. void imx5_pm_init(void);
  25504. #else
  25505. diff -Nur linux-3.14.17/arch/arm/mach-imx/cpuidle.h linux-imx6-3.14/arch/arm/mach-imx/cpuidle.h
  25506. --- linux-3.14.17/arch/arm/mach-imx/cpuidle.h 2014-08-14 03:38:34.000000000 +0200
  25507. +++ linux-imx6-3.14/arch/arm/mach-imx/cpuidle.h 2014-09-11 18:05:53.306003222 +0200
  25508. @@ -1,5 +1,5 @@
  25509. /*
  25510. - * Copyright 2012 Freescale Semiconductor, Inc.
  25511. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  25512. * Copyright 2012 Linaro Ltd.
  25513. *
  25514. * The code contained herein is licensed under the GNU General Public
  25515. @@ -13,6 +13,7 @@
  25516. #ifdef CONFIG_CPU_IDLE
  25517. extern int imx5_cpuidle_init(void);
  25518. extern int imx6q_cpuidle_init(void);
  25519. +extern int imx6sl_cpuidle_init(void);
  25520. #else
  25521. static inline int imx5_cpuidle_init(void)
  25522. {
  25523. @@ -22,4 +23,8 @@
  25524. {
  25525. return 0;
  25526. }
  25527. +static inline int imx6sl_cpuidle_init(void)
  25528. +{
  25529. + return 0;
  25530. +}
  25531. #endif
  25532. diff -Nur linux-3.14.17/arch/arm/mach-imx/cpuidle-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6q.c
  25533. --- linux-3.14.17/arch/arm/mach-imx/cpuidle-imx6q.c 2014-08-14 03:38:34.000000000 +0200
  25534. +++ linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6q.c 2014-09-11 18:05:53.302003205 +0200
  25535. @@ -1,5 +1,5 @@
  25536. /*
  25537. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  25538. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  25539. *
  25540. * This program is free software; you can redistribute it and/or modify
  25541. * it under the terms of the GNU General Public License version 2 as
  25542. @@ -68,8 +68,8 @@
  25543. /* Need to enable SCU standby for entering WAIT modes */
  25544. imx_scu_standby_enable();
  25545. - /* Set chicken bit to get a reliable WAIT mode support */
  25546. - imx6q_set_chicken_bit();
  25547. + /* Set cache lpm bit for reliable WAIT mode support */
  25548. + imx6q_set_cache_lpm_in_wait(true);
  25549. return cpuidle_register(&imx6q_cpuidle_driver, NULL);
  25550. }
  25551. diff -Nur linux-3.14.17/arch/arm/mach-imx/cpuidle-imx6sl.c linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6sl.c
  25552. --- linux-3.14.17/arch/arm/mach-imx/cpuidle-imx6sl.c 1970-01-01 01:00:00.000000000 +0100
  25553. +++ linux-imx6-3.14/arch/arm/mach-imx/cpuidle-imx6sl.c 2014-09-11 18:05:53.306003222 +0200
  25554. @@ -0,0 +1,149 @@
  25555. +/*
  25556. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  25557. + *
  25558. + * This program is free software; you can redistribute it and/or modify
  25559. + * it under the terms of the GNU General Public License version 2 as
  25560. + * published by the Free Software Foundation.
  25561. + */
  25562. +
  25563. +#include <linux/cpuidle.h>
  25564. +#include <linux/genalloc.h>
  25565. +#include <linux/module.h>
  25566. +#include <linux/of.h>
  25567. +#include <linux/of_address.h>
  25568. +#include <linux/of_device.h>
  25569. +#include <asm/cpuidle.h>
  25570. +#include <asm/fncpy.h>
  25571. +#include <asm/mach/map.h>
  25572. +#include <asm/proc-fns.h>
  25573. +#include <asm/tlb.h>
  25574. +
  25575. +#include "common.h"
  25576. +#include "cpuidle.h"
  25577. +
  25578. +extern u32 audio_bus_freq_mode;
  25579. +extern u32 ultra_low_bus_freq_mode;
  25580. +extern unsigned long reg_addrs[];
  25581. +extern void imx6sl_low_power_wfi(void);
  25582. +
  25583. +static void __iomem *iomux_base;
  25584. +static void *wfi_iram_base;
  25585. +
  25586. +void (*imx6sl_wfi_in_iram_fn)(void *wfi_iram_base,
  25587. + void *iomux_addr, void *regs_addr, u32 audio_mode) = NULL;
  25588. +
  25589. +#define WFI_IN_IRAM_SIZE 0x1000
  25590. +
  25591. +static int imx6sl_enter_wait(struct cpuidle_device *dev,
  25592. + struct cpuidle_driver *drv, int index)
  25593. +{
  25594. + imx6q_set_lpm(WAIT_UNCLOCKED);
  25595. +#ifdef CONFIG_ARM_IMX6_CPUFREQ
  25596. + if (ultra_low_bus_freq_mode || audio_bus_freq_mode) {
  25597. + /*
  25598. + * Flush the TLB, to ensure no TLB maintenance occurs
  25599. + * when DDR is in self-refresh.
  25600. + */
  25601. + local_flush_tlb_all();
  25602. + /*
  25603. + * Run WFI code from IRAM.
  25604. + * Drop the DDR freq to 1MHz and AHB to 3MHz
  25605. + * Also float DDR IO pads.
  25606. + */
  25607. + imx6sl_wfi_in_iram_fn(wfi_iram_base, iomux_base, reg_addrs, audio_bus_freq_mode);
  25608. + }
  25609. + else
  25610. +#endif
  25611. + {
  25612. + imx6sl_set_wait_clk(true);
  25613. + cpu_do_idle();
  25614. + imx6sl_set_wait_clk(false);
  25615. + }
  25616. + imx6q_set_lpm(WAIT_CLOCKED);
  25617. +
  25618. + return index;
  25619. +}
  25620. +
  25621. +static struct cpuidle_driver imx6sl_cpuidle_driver = {
  25622. + .name = "imx6sl_cpuidle",
  25623. + .owner = THIS_MODULE,
  25624. + .states = {
  25625. + /* WFI */
  25626. + ARM_CPUIDLE_WFI_STATE,
  25627. + /* WAIT */
  25628. + {
  25629. + .exit_latency = 50,
  25630. + .target_residency = 75,
  25631. + .flags = CPUIDLE_FLAG_TIME_VALID |
  25632. + CPUIDLE_FLAG_TIMER_STOP,
  25633. + .enter = imx6sl_enter_wait,
  25634. + .name = "WAIT",
  25635. + .desc = "Clock off",
  25636. + },
  25637. + },
  25638. + .state_count = 2,
  25639. + .safe_state_index = 0,
  25640. +};
  25641. +
  25642. +int __init imx6sl_cpuidle_init(void)
  25643. +{
  25644. + struct platform_device *ocram_dev;
  25645. + unsigned int iram_paddr;
  25646. + struct device_node *node;
  25647. + struct gen_pool *iram_pool;
  25648. +
  25649. + node = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-iomuxc");
  25650. + if (!node) {
  25651. + pr_err("failed to find imx6sl-iomuxc device tree data!\n");
  25652. + return -EINVAL;
  25653. + }
  25654. + iomux_base = of_iomap(node, 0);
  25655. + WARN(!iomux_base, "unable to map iomux registers\n");
  25656. +
  25657. + node = NULL;
  25658. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  25659. + if (!node) {
  25660. + pr_err("%s: failed to find ocram node\n",
  25661. + __func__);
  25662. + return -EINVAL;
  25663. + }
  25664. +
  25665. + ocram_dev = of_find_device_by_node(node);
  25666. + if (!ocram_dev) {
  25667. + pr_err("failed to find ocram device!\n");
  25668. + return -EINVAL;
  25669. + }
  25670. +
  25671. + iram_pool = dev_get_gen_pool(&ocram_dev->dev);
  25672. + if (!iram_pool) {
  25673. + pr_err("iram pool unavailable!\n");
  25674. + return -EINVAL;
  25675. + }
  25676. + /*
  25677. + * Allocate IRAM memory when ARM executes WFI in
  25678. + * ultra_low_power_mode.
  25679. + */
  25680. + wfi_iram_base = (void *)gen_pool_alloc(iram_pool,
  25681. + WFI_IN_IRAM_SIZE);
  25682. + if (!wfi_iram_base) {
  25683. + pr_err("Cannot alloc iram for wfi code!\n");
  25684. + return -ENOMEM;
  25685. + }
  25686. +
  25687. + iram_paddr = gen_pool_virt_to_phys(iram_pool,
  25688. + (unsigned long)wfi_iram_base);
  25689. + /*
  25690. + * Need to remap the area here since we want
  25691. + * the memory region to be executable.
  25692. + */
  25693. + wfi_iram_base = __arm_ioremap(iram_paddr,
  25694. + WFI_IN_IRAM_SIZE,
  25695. + MT_MEMORY_RWX_NONCACHED);
  25696. + if (!wfi_iram_base)
  25697. + pr_err("wfi_ram_base NOT remapped\n");
  25698. +
  25699. + imx6sl_wfi_in_iram_fn = (void *)fncpy(wfi_iram_base,
  25700. + &imx6sl_low_power_wfi, WFI_IN_IRAM_SIZE);
  25701. +
  25702. + return cpuidle_register(&imx6sl_cpuidle_driver, NULL);
  25703. +}
  25704. diff -Nur linux-3.14.17/arch/arm/mach-imx/ddr3_freq_imx6.S linux-imx6-3.14/arch/arm/mach-imx/ddr3_freq_imx6.S
  25705. --- linux-3.14.17/arch/arm/mach-imx/ddr3_freq_imx6.S 1970-01-01 01:00:00.000000000 +0100
  25706. +++ linux-imx6-3.14/arch/arm/mach-imx/ddr3_freq_imx6.S 2014-09-11 18:05:53.306003222 +0200
  25707. @@ -0,0 +1,893 @@
  25708. +/*
  25709. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  25710. + *
  25711. + * This program is free software; you can redistribute it and/or modify
  25712. + * it under the terms of the GNU General Public License as published by
  25713. + * the Free Software Foundation; either version 2 of the License, or
  25714. + * (at your option) any later version.
  25715. +
  25716. + * This program is distributed in the hope that it will be useful,
  25717. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25718. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25719. + * GNU General Public License for more details.
  25720. +
  25721. + * You should have received a copy of the GNU General Public License along
  25722. + * with this program; if not, write to the Free Software Foundation, Inc.,
  25723. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  25724. + */
  25725. +
  25726. +#include <linux/linkage.h>
  25727. +
  25728. +#define MMDC0_MDPDC 0x4
  25729. +#define MMDC0_MDCF0 0x0c
  25730. +#define MMDC0_MDCF1 0x10
  25731. +#define MMDC0_MDMISC 0x18
  25732. +#define MMDC0_MDSCR 0x1c
  25733. +#define MMDC0_MAPSR 0x404
  25734. +#define MMDC0_MADPCR0 0x410
  25735. +#define MMDC0_MPZQHWCTRL 0x800
  25736. +#define MMDC1_MPZQHWCTRL 0x4800
  25737. +#define MMDC0_MPODTCTRL 0x818
  25738. +#define MMDC1_MPODTCTRL 0x4818
  25739. +#define MMDC0_MPDGCTRL0 0x83c
  25740. +#define MMDC1_MPDGCTRL0 0x483c
  25741. +#define MMDC0_MPMUR0 0x8b8
  25742. +#define MMDC1_MPMUR0 0x48b8
  25743. +
  25744. +#define CCM_CBCDR 0x14
  25745. +#define CCM_CBCMR 0x18
  25746. +#define CCM_CSCMR1 0x1c
  25747. +#define CCM_CDHIPR 0x48
  25748. +
  25749. +#define L2_CACHE_SYNC 0x730
  25750. +
  25751. + .align 3
  25752. +
  25753. + .macro switch_to_528MHz
  25754. +
  25755. + /* check if periph_clk_sel is already set */
  25756. + ldr r0, [r6, #CCM_CBCDR]
  25757. + and r0, r0, #(1 << 25)
  25758. + cmp r0, #(1 << 25)
  25759. + beq set_ahb_podf_before_switch
  25760. +
  25761. + /* change periph_clk to be sourced from pll3_clk. */
  25762. + ldr r0, [r6, #CCM_CBCMR]
  25763. + bic r0, r0, #(3 << 12)
  25764. + str r0, [r6, #CCM_CBCMR]
  25765. +
  25766. + ldr r0, [r6, #CCM_CBCDR]
  25767. + bic r0, r0, #(0x38 << 20)
  25768. + str r0, [r6, #CCM_CBCDR]
  25769. +
  25770. + /*
  25771. + * set the AHB dividers before the switch,
  25772. + * don't change AXI clock divider,
  25773. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25774. + */
  25775. + ldr r0, [r6, #CCM_CBCDR]
  25776. + ldr r2, =0x3f1f00
  25777. + bic r0, r0, r2
  25778. + orr r0, r0, #0xd00
  25779. + orr r0, r0, #(1 << 16)
  25780. + str r0, [r6, #CCM_CBCDR]
  25781. +
  25782. +wait_div_update528:
  25783. + ldr r0, [r6, #CCM_CDHIPR]
  25784. + cmp r0, #0
  25785. + bne wait_div_update528
  25786. +
  25787. + /* now switch periph_clk to pll3_main_clk. */
  25788. + ldr r0, [r6, #CCM_CBCDR]
  25789. + orr r0, r0, #(1 << 25)
  25790. + str r0, [r6, #CCM_CBCDR]
  25791. +
  25792. +periph_clk_switch3:
  25793. + ldr r0, [r6, #CCM_CDHIPR]
  25794. + cmp r0, #0
  25795. + bne periph_clk_switch3
  25796. +
  25797. + b switch_pre_periph_clk_528
  25798. +
  25799. +set_ahb_podf_before_switch:
  25800. + /*
  25801. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25802. + */
  25803. + ldr r0, [r6, #CCM_CBCDR]
  25804. + ldr r2, =0x3f1f00
  25805. + bic r0, r0, r2
  25806. + orr r0, r0, #0xd00
  25807. + orr r0, r0, #(1 << 16)
  25808. + str r0, [r6, #CCM_CBCDR]
  25809. +
  25810. +wait_div_update528_1:
  25811. + ldr r0, [r6, #CCM_CDHIPR]
  25812. + cmp r0, #0
  25813. + bne wait_div_update528_1
  25814. +
  25815. +switch_pre_periph_clk_528:
  25816. +
  25817. + /* now switch pre_periph_clk to PLL2_528MHz. */
  25818. + ldr r0, [r6, #CCM_CBCMR]
  25819. + bic r0, r0, #(0xc << 16)
  25820. + str r0, [r6, #CCM_CBCMR]
  25821. +
  25822. + /* now switch periph_clk back. */
  25823. + ldr r0, [r6, #CCM_CBCDR]
  25824. + bic r0, r0, #(1 << 25)
  25825. + str r0, [r6, #CCM_CBCDR]
  25826. +
  25827. +periph_clk_switch4:
  25828. + ldr r0, [r6, #CCM_CDHIPR]
  25829. + cmp r0, #0
  25830. + bne periph_clk_switch4
  25831. +
  25832. + .endm
  25833. +
  25834. + .macro switch_to_400MHz
  25835. +
  25836. + /* check if periph_clk_sel is already set. */
  25837. + ldr r0, [r6, #CCM_CBCDR]
  25838. + and r0, r0, #(1 << 25)
  25839. + cmp r0, #(1 << 25)
  25840. + beq set_ahb_podf_before_switch1
  25841. +
  25842. + /* change periph_clk to be sourced from pll3_clk. */
  25843. + ldr r0, [r6, #CCM_CBCMR]
  25844. + bic r0, r0, #(3 << 12)
  25845. + str r0, [r6, #CCM_CBCMR]
  25846. +
  25847. + ldr r0, [r6, #CCM_CBCDR]
  25848. + bic r0, r0, #(0x38 << 24)
  25849. + str r0, [r6, #CCM_CBCDR]
  25850. +
  25851. + /* now switch periph_clk to pll3_main_clk. */
  25852. + ldr r0, [r6, #CCM_CBCDR]
  25853. + orr r0, r0, #(1 << 25)
  25854. + str r0, [r6, #CCM_CBCDR]
  25855. +
  25856. +periph_clk_switch5:
  25857. + ldr r0, [r6, #CCM_CDHIPR]
  25858. + cmp r0, #0
  25859. + bne periph_clk_switch5
  25860. +
  25861. + b switch_pre_periph_clk_400
  25862. +
  25863. +set_ahb_podf_before_switch1:
  25864. + /*
  25865. + * set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4,
  25866. + */
  25867. + ldr r0, [r6, #CCM_CBCDR]
  25868. + ldr r2, =0x3f1f00
  25869. + bic r0, r0, r2
  25870. + orr r0, r0, #(0x9 << 8)
  25871. + orr r0, r0, #(1 << 16)
  25872. + str r0, [r6, #CCM_CBCDR]
  25873. +
  25874. +wait_div_update400_1:
  25875. + ldr r0, [r6, #CCM_CDHIPR]
  25876. + cmp r0, #0
  25877. + bne wait_div_update400_1
  25878. +
  25879. +switch_pre_periph_clk_400:
  25880. +
  25881. + /* now switch pre_periph_clk to PFD_400MHz. */
  25882. + ldr r0, [r6, #CCM_CBCMR]
  25883. + bic r0, r0, #(0xc << 16)
  25884. + orr r0, r0, #(0x4 << 16)
  25885. + str r0, [r6, #CCM_CBCMR]
  25886. +
  25887. + /* now switch periph_clk back. */
  25888. + ldr r0, [r6, #CCM_CBCDR]
  25889. + bic r0, r0, #(1 << 25)
  25890. + str r0, [r6, #CCM_CBCDR]
  25891. +
  25892. +periph_clk_switch6:
  25893. + ldr r0, [r6, #CCM_CDHIPR]
  25894. + cmp r0, #0
  25895. + bne periph_clk_switch6
  25896. +
  25897. + /*
  25898. + * change AHB divider so that we are at 400/3=133MHz.
  25899. + * don't change AXI clock divider.
  25900. + * set the MMDC_DIV=1, AXI_DIV=2, AHB_DIV=3,
  25901. + */
  25902. + ldr r0, [r6, #CCM_CBCDR]
  25903. + ldr r2, =0x3f1f00
  25904. + bic r0, r0, r2
  25905. + orr r0, r0, #(0x9 << 8)
  25906. + orr r0, r0, #(1 << 16)
  25907. + str r0, [r6, #CCM_CBCDR]
  25908. +
  25909. +wait_div_update400_2:
  25910. + ldr r0, [r6, #CCM_CDHIPR]
  25911. + cmp r0, #0
  25912. + bne wait_div_update400_2
  25913. +
  25914. + .endm
  25915. +
  25916. + .macro switch_to_50MHz
  25917. +
  25918. + /* check if periph_clk_sel is already set. */
  25919. + ldr r0, [r6, #CCM_CBCDR]
  25920. + and r0, r0, #(1 << 25)
  25921. + cmp r0, #(1 << 25)
  25922. + beq switch_pre_periph_clk_50
  25923. +
  25924. + /*
  25925. + * set the periph_clk to be sourced from PLL2_PFD_200M
  25926. + * change periph_clk to be sourced from pll3_clk.
  25927. + * ensure PLL3 is the source and set the divider to 1.
  25928. + */
  25929. + ldr r0, [r6, #CCM_CBCMR]
  25930. + bic r0, r0, #(0x3 << 12)
  25931. + str r0, [r6, #CCM_CBCMR]
  25932. +
  25933. + ldr r0, [r6, #CCM_CBCDR]
  25934. + bic r0, r0, #(0x38 << 24)
  25935. + str r0, [r6, #CCM_CBCDR]
  25936. +
  25937. + /* now switch periph_clk to pll3_main_clk. */
  25938. + ldr r0, [r6, #CCM_CBCDR]
  25939. + orr r0, r0, #(1 << 25)
  25940. + str r0, [r6, #CCM_CBCDR]
  25941. +
  25942. +periph_clk_switch_50:
  25943. + ldr r0, [r6, #CCM_CDHIPR]
  25944. + cmp r0, #0
  25945. + bne periph_clk_switch_50
  25946. +
  25947. +switch_pre_periph_clk_50:
  25948. +
  25949. + /* now switch pre_periph_clk to PFD_200MHz. */
  25950. + ldr r0, [r6, #CCM_CBCMR]
  25951. + orr r0, r0, #(0xc << 16)
  25952. + str r0, [r6, #CCM_CBCMR]
  25953. +
  25954. + /*
  25955. + * set the MMDC_DIV=4, AXI_DIV = 4, AHB_DIV=8,
  25956. + */
  25957. + ldr r0, [r6, #CCM_CBCDR]
  25958. + ldr r2, =0x3f1f00
  25959. + bic r0, r0, r2
  25960. + orr r0, r0, #(0x18 << 16)
  25961. + orr r0, r0, #(0x3 << 16)
  25962. +
  25963. + /*
  25964. + * if changing AHB divider remember to change
  25965. + * the IPGPER divider too below.
  25966. + */
  25967. + orr r0, r0, #0x1d00
  25968. + str r0, [r6, #CCM_CBCDR]
  25969. +
  25970. +wait_div_update_50:
  25971. + ldr r0, [r6, #CCM_CDHIPR]
  25972. + cmp r0, #0
  25973. + bne wait_div_update_50
  25974. +
  25975. + /* now switch periph_clk back. */
  25976. + ldr r0, [r6, #CCM_CBCDR]
  25977. + bic r0, r0, #(1 << 25)
  25978. + str r0, [r6, #CCM_CBCDR]
  25979. +
  25980. +periph_clk_switch2:
  25981. + ldr r0, [r6, #CCM_CDHIPR]
  25982. + cmp r0, #0
  25983. + bne periph_clk_switch2
  25984. +
  25985. + .endm
  25986. +
  25987. + .macro switch_to_24MHz
  25988. + /*
  25989. + * change the freq now try setting DDR to 24MHz.
  25990. + * source it from the periph_clk2 ensure the
  25991. + * periph_clk2 is sourced from 24MHz and the
  25992. + * divider is 1.
  25993. + */
  25994. +
  25995. + ldr r0, [r6, #CCM_CBCMR]
  25996. + bic r0, r0, #(0x3 << 12)
  25997. + orr r0, r0, #(1 << 12)
  25998. + str r0, [r6, #CCM_CBCMR]
  25999. +
  26000. + ldr r0, [r6, #CCM_CBCDR]
  26001. + bic r0, r0, #(0x38 << 24)
  26002. + str r0, [r6, #CCM_CBCDR]
  26003. +
  26004. + /* now switch periph_clk to 24MHz. */
  26005. + ldr r0, [r6, #CCM_CBCDR]
  26006. + orr r0, r0, #(1 << 25)
  26007. + str r0, [r6, #CCM_CBCDR]
  26008. +
  26009. +periph_clk_switch1:
  26010. + ldr r0, [r6, #CCM_CDHIPR]
  26011. + cmp r0, #0
  26012. + bne periph_clk_switch1
  26013. +
  26014. + /* change all the dividers to 1. */
  26015. + ldr r0, [r6, #CCM_CBCDR]
  26016. + ldr r2, =0x3f1f00
  26017. + bic r0, r0, r2
  26018. + orr r0, r0, #(1 << 8)
  26019. + str r0, [r6, #CCM_CBCDR]
  26020. +
  26021. + /* Wait for the divider to change. */
  26022. +wait_div_update:
  26023. + ldr r0, [r6, #CCM_CDHIPR]
  26024. + cmp r0, #0
  26025. + bne wait_div_update
  26026. +
  26027. + .endm
  26028. +
  26029. +/*
  26030. + * mx6_ddr3_freq_change
  26031. + *
  26032. + * idle the processor (eg, wait for interrupt).
  26033. + * make sure DDR is in self-refresh.
  26034. + * IRQs are already disabled.
  26035. + */
  26036. +ENTRY(mx6_ddr3_freq_change)
  26037. +
  26038. + stmfd sp!, {r4-r12}
  26039. +
  26040. + /*
  26041. + * r5 -> mmdc_base
  26042. + * r6 -> ccm_base
  26043. + * r7 -> iomux_base
  26044. + * r12 -> l2_base
  26045. + */
  26046. + mov r4, r0
  26047. + mov r8, r1
  26048. + mov r9, r2
  26049. + mov r11, r3
  26050. +
  26051. + /*
  26052. + * Get the addresses of the registers.
  26053. + * They are last few entries in the
  26054. + * ddr_settings parameter.
  26055. + * The first entry contains the count,
  26056. + * and each entry is 2 words.
  26057. + */
  26058. + ldr r0, [r1]
  26059. + add r0, r0, #1
  26060. + lsl r0, r0, #3
  26061. + add r1, r0, r1
  26062. + /* mmdc_base. */
  26063. + ldr r5, [r1]
  26064. + add r1, #8
  26065. + /* ccm_base */
  26066. + ldr r6, [r1]
  26067. + add r1, #8
  26068. + /*iomux_base */
  26069. + ldr r7, [r1]
  26070. + add r1, #8
  26071. + /*l2_base */
  26072. + ldr r12, [r1]
  26073. +
  26074. +ddr_freq_change:
  26075. + /*
  26076. + * make sure no TLB miss will occur when
  26077. + * the DDR is in self refresh. invalidate
  26078. + * TLB single entry to ensure that the
  26079. + * address is not already in the TLB.
  26080. + */
  26081. +
  26082. + adr r10, ddr_freq_change
  26083. +
  26084. + ldr r2, [r6]
  26085. + ldr r2, [r5]
  26086. + ldr r2, [r7]
  26087. + ldr r2, [r8]
  26088. + ldr r2, [r10]
  26089. + ldr r2, [r11]
  26090. + ldr r2, [r12]
  26091. +
  26092. +#ifdef CONFIG_CACHE_L2X0
  26093. + /*
  26094. + * Make sure the L2 buffers are drained.
  26095. + * Sync operation on L2 drains the buffers.
  26096. + */
  26097. + mov r1, #0x0
  26098. + str r1, [r12, #L2_CACHE_SYNC]
  26099. +#endif
  26100. +
  26101. + /* disable automatic power saving. */
  26102. + ldr r0, [r5, #MMDC0_MAPSR]
  26103. + orr r0, r0, #0x01
  26104. + str r0, [r5, #MMDC0_MAPSR]
  26105. +
  26106. + /* disable MMDC power down timer. */
  26107. + ldr r0, [r5, #MMDC0_MDPDC]
  26108. + bic r0, r0, #(0xff << 8)
  26109. + str r0, [r5, #MMDC0_MDPDC]
  26110. +
  26111. + /* delay for a while */
  26112. + ldr r1, =4
  26113. +delay1:
  26114. + ldr r2, =0
  26115. +cont1:
  26116. + ldr r0, [r5, r2]
  26117. + add r2, r2, #4
  26118. + cmp r2, #16
  26119. + bne cont1
  26120. + sub r1, r1, #1
  26121. + cmp r1, #0
  26122. + bgt delay1
  26123. +
  26124. + /* set CON_REG */
  26125. + ldr r0, =0x8000
  26126. + str r0, [r5, #MMDC0_MDSCR]
  26127. +poll_conreq_set_1:
  26128. + ldr r0, [r5, #MMDC0_MDSCR]
  26129. + and r0, r0, #(0x4 << 12)
  26130. + cmp r0, #(0x4 << 12)
  26131. + bne poll_conreq_set_1
  26132. +
  26133. + ldr r0, =0x00008010
  26134. + str r0, [r5, #MMDC0_MDSCR]
  26135. + ldr r0, =0x00008018
  26136. + str r0, [r5, #MMDC0_MDSCR]
  26137. +
  26138. + /*
  26139. + * if requested frequency is greater than
  26140. + * 300MHz go to DLL on mode.
  26141. + */
  26142. + ldr r1, =300000000
  26143. + cmp r4, r1
  26144. + bge dll_on_mode
  26145. +
  26146. +dll_off_mode:
  26147. +
  26148. + /* if DLL is currently on, turn it off. */
  26149. + cmp r9, #1
  26150. + beq continue_dll_off_1
  26151. +
  26152. + ldr r0, =0x00018031
  26153. + str r0, [r5, #MMDC0_MDSCR]
  26154. +
  26155. + ldr r0, =0x00018039
  26156. + str r0, [r5, #MMDC0_MDSCR]
  26157. +
  26158. + ldr r1, =10
  26159. +delay1a:
  26160. + ldr r2, =0
  26161. +cont1a:
  26162. + ldr r0, [r5, r2]
  26163. + add r2, r2, #4
  26164. + cmp r2, #16
  26165. + bne cont1a
  26166. + sub r1, r1, #1
  26167. + cmp r1, #0
  26168. + bgt delay1a
  26169. +
  26170. +continue_dll_off_1:
  26171. + /* set DVFS - enter self refresh mode */
  26172. + ldr r0, [r5, #MMDC0_MAPSR]
  26173. + orr r0, r0, #(1 << 21)
  26174. + str r0, [r5, #MMDC0_MAPSR]
  26175. +
  26176. + /* de-assert con_req */
  26177. + mov r0, #0x0
  26178. + str r0, [r5, #MMDC0_MDSCR]
  26179. +
  26180. +poll_dvfs_set_1:
  26181. + ldr r0, [r5, #MMDC0_MAPSR]
  26182. + and r0, r0, #(1 << 25)
  26183. + cmp r0, #(1 << 25)
  26184. + bne poll_dvfs_set_1
  26185. +
  26186. + ldr r1, =24000000
  26187. + cmp r4, r1
  26188. + beq switch_freq_24
  26189. +
  26190. + switch_to_50MHz
  26191. + b continue_dll_off_2
  26192. +
  26193. +switch_freq_24:
  26194. + switch_to_24MHz
  26195. +
  26196. +continue_dll_off_2:
  26197. +
  26198. + /* set SBS - block ddr accesses */
  26199. + ldr r0, [r5, #MMDC0_MADPCR0]
  26200. + orr r0, r0, #(1 << 8)
  26201. + str r0, [r5, #MMDC0_MADPCR0]
  26202. +
  26203. + /* clear DVFS - exit from self refresh mode */
  26204. + ldr r0, [r5, #MMDC0_MAPSR]
  26205. + bic r0, r0, #(1 << 21)
  26206. + str r0, [r5, #MMDC0_MAPSR]
  26207. +
  26208. +poll_dvfs_clear_1:
  26209. + ldr r0, [r5, #MMDC0_MAPSR]
  26210. + and r0, r0, #(1 << 25)
  26211. + cmp r0, #(1 << 25)
  26212. + beq poll_dvfs_clear_1
  26213. +
  26214. + /* if DLL was previously on, continue DLL off routine. */
  26215. + cmp r9, #1
  26216. + beq continue_dll_off_3
  26217. +
  26218. + ldr r0, =0x00018031
  26219. + str r0, [r5, #MMDC0_MDSCR]
  26220. +
  26221. + ldr r0, =0x00018039
  26222. + str r0, [r5, #MMDC0_MDSCR]
  26223. +
  26224. + ldr r0, =0x08208030
  26225. + str r0, [r5, #MMDC0_MDSCR]
  26226. +
  26227. + ldr r0, =0x08208038
  26228. + str r0, [r5, #MMDC0_MDSCR]
  26229. +
  26230. + ldr r0, =0x00088032
  26231. + str r0, [r5, #MMDC0_MDSCR]
  26232. +
  26233. + ldr r0, =0x0008803A
  26234. + str r0, [r5, #MMDC0_MDSCR]
  26235. +
  26236. + /* delay for a while. */
  26237. + ldr r1, =4
  26238. +delay_1:
  26239. + ldr r2, =0
  26240. +cont_1:
  26241. + ldr r0, [r5, r2]
  26242. + add r2, r2, #4
  26243. + cmp r2, #16
  26244. + bne cont_1
  26245. + sub r1, r1, #1
  26246. + cmp r1, #0
  26247. + bgt delay_1
  26248. +
  26249. + ldr r0, [r5, #MMDC0_MDCF0]
  26250. + bic r0, r0, #0xf
  26251. + orr r0, r0, #0x3
  26252. + str r0, [r5, #MMDC0_MDCF0]
  26253. +
  26254. + ldr r0, [r5, #MMDC0_MDCF1]
  26255. + bic r0, r0, #0x7
  26256. + orr r0, r0, #0x4
  26257. + str r0, [r5, #MMDC0_MDCF1]
  26258. +
  26259. + ldr r0, =0x00091680
  26260. + str r0, [r5, #MMDC0_MDMISC]
  26261. +
  26262. + /* enable dqs pull down in the IOMUX. */
  26263. + ldr r1, [r11]
  26264. + add r11, r11, #8
  26265. + ldr r2, =0x3028
  26266. +update_iomux:
  26267. + ldr r0, [r11, #0x0]
  26268. + ldr r3, [r7, r0]
  26269. + bic r3, r3, r2
  26270. + orr r3, r3, #(0x3 << 12)
  26271. + orr r3, r3, #0x28
  26272. + str r3, [r7, r0]
  26273. + add r11, r11, #8
  26274. + sub r1, r1, #1
  26275. + cmp r1, #0
  26276. + bgt update_iomux
  26277. +
  26278. + /* ODT disabled. */
  26279. + ldr r0, =0x0
  26280. + ldr r2, =MMDC0_MPODTCTRL
  26281. + str r0, [r5, r2]
  26282. + ldr r2, =MMDC1_MPODTCTRL
  26283. + str r0, [r5, r2]
  26284. +
  26285. + /* DQS gating disabled. */
  26286. + ldr r2, =MMDC0_MPDGCTRL0
  26287. + ldr r0, [r5, r2]
  26288. + orr r0, r0, #(1 << 29)
  26289. + str r0, [r5, r2]
  26290. +
  26291. + ldr r2, =MMDC1_MPDGCTRL0
  26292. + ldr r0, [r5, r2]
  26293. + orr r0, r0, #(0x1 << 29)
  26294. + str r0, [r5, r2]
  26295. +
  26296. + /* MMDC0_MAPSR adopt power down enable. */
  26297. + ldr r0, [r5, #MMDC0_MAPSR]
  26298. + bic r0, r0, #0x01
  26299. + str r0, [r5, #MMDC0_MAPSR]
  26300. +
  26301. + /* frc_msr + mu bypass */
  26302. + ldr r0, =0x00000060
  26303. + str r0, [r5, #MMDC0_MPMUR0]
  26304. + ldr r2, =MMDC1_MPMUR0
  26305. + str r0, [r5, r2]
  26306. + ldr r0, =0x00000460
  26307. + str r0, [r5, #MMDC0_MPMUR0]
  26308. + ldr r2, =MMDC1_MPMUR0
  26309. + str r0, [r5, r2]
  26310. + ldr r0, =0x00000c60
  26311. + str r0, [r5, #MMDC0_MPMUR0]
  26312. + ldr r2, =MMDC1_MPMUR0
  26313. + str r0, [r5, r2]
  26314. +
  26315. +continue_dll_off_3:
  26316. + /* clear SBS - unblock accesses to DDR. */
  26317. + ldr r0, [r5, #MMDC0_MADPCR0]
  26318. + bic r0, r0, #(0x1 << 8)
  26319. + str r0, [r5, #MMDC0_MADPCR0]
  26320. +
  26321. + mov r0, #0x0
  26322. + str r0, [r5, #MMDC0_MDSCR]
  26323. +poll_conreq_clear_1:
  26324. + ldr r0, [r5, #MMDC0_MDSCR]
  26325. + and r0, r0, #(0x4 << 12)
  26326. + cmp r0, #(0x4 << 12)
  26327. + beq poll_conreq_clear_1
  26328. +
  26329. + b done
  26330. +
  26331. +dll_on_mode:
  26332. + /* assert DVFS - enter self refresh mode. */
  26333. + ldr r0, [r5, #MMDC0_MAPSR]
  26334. + orr r0, r0, #(1 << 21)
  26335. + str r0, [r5, #MMDC0_MAPSR]
  26336. +
  26337. + /* de-assert CON_REQ. */
  26338. + mov r0, #0x0
  26339. + str r0, [r5, #MMDC0_MDSCR]
  26340. +
  26341. + /* poll DVFS ack. */
  26342. +poll_dvfs_set_2:
  26343. + ldr r0, [r5, #MMDC0_MAPSR]
  26344. + and r0, r0, #(1 << 25)
  26345. + cmp r0, #(1 << 25)
  26346. + bne poll_dvfs_set_2
  26347. +
  26348. + ldr r1, =528000000
  26349. + cmp r4, r1
  26350. + beq switch_freq_528
  26351. +
  26352. + switch_to_400MHz
  26353. +
  26354. + b continue_dll_on
  26355. +
  26356. +switch_freq_528:
  26357. + switch_to_528MHz
  26358. +
  26359. +continue_dll_on:
  26360. +
  26361. + /* set SBS step-by-step mode. */
  26362. + ldr r0, [r5, #MMDC0_MADPCR0]
  26363. + orr r0, r0, #( 1 << 8)
  26364. + str r0, [r5, #MMDC0_MADPCR0]
  26365. +
  26366. + /* clear DVFS - exit self refresh mode. */
  26367. + ldr r0, [r5, #MMDC0_MAPSR]
  26368. + bic r0, r0, #(1 << 21)
  26369. + str r0, [r5, #MMDC0_MAPSR]
  26370. +
  26371. +poll_dvfs_clear_2:
  26372. + ldr r0, [r5, #MMDC0_MAPSR]
  26373. + and r0, r0, #(1 << 25)
  26374. + cmp r0, #(1 << 25)
  26375. + beq poll_dvfs_clear_2
  26376. +
  26377. + /* if DLL is currently off, turn it back on. */
  26378. + cmp r9, #0
  26379. + beq update_calibration_only
  26380. +
  26381. + ldr r0, =0xa5390003
  26382. + str r0, [r5, #MMDC0_MPZQHWCTRL]
  26383. + ldr r2, =MMDC1_MPZQHWCTRL
  26384. + str r0, [r5, r2]
  26385. +
  26386. + /* enable DQS gating. */
  26387. + ldr r2, =MMDC0_MPDGCTRL0
  26388. + ldr r0, [r5, r2]
  26389. + bic r0, r0, #(1 << 29)
  26390. + str r0, [r5, r2]
  26391. +
  26392. + ldr r2, =MMDC1_MPDGCTRL0
  26393. + ldr r0, [r5, r2]
  26394. + bic r0, r0, #(1 << 29)
  26395. + str r0, [r5, r2]
  26396. +
  26397. + /* force measure. */
  26398. + ldr r0, =0x00000800
  26399. + str r0, [r5, #MMDC0_MPMUR0]
  26400. + ldr r2, =MMDC1_MPMUR0
  26401. + str r0, [r5, r2]
  26402. +
  26403. + /* delay for while. */
  26404. + ldr r1, =4
  26405. +delay5:
  26406. + ldr r2, =0
  26407. +cont5:
  26408. + ldr r0, [r5, r2]
  26409. + add r2, r2, #4
  26410. + cmp r2, #16
  26411. + bne cont5
  26412. + sub r1, r1, #1
  26413. + cmp r1, #0
  26414. + bgt delay5
  26415. +
  26416. + /* disable dqs pull down in the IOMUX. */
  26417. + ldr r1, [r11]
  26418. + add r11, r11, #8
  26419. +update_iomux1:
  26420. + ldr r0, [r11, #0x0]
  26421. + ldr r3, [r11, #0x4]
  26422. + str r3, [r7, r0]
  26423. + add r11, r11, #8
  26424. + sub r1, r1, #1
  26425. + cmp r1, #0
  26426. + bgt update_iomux1
  26427. +
  26428. + /* config MMDC timings to 528MHz. */
  26429. + ldr r9, [r8]
  26430. + add r8, r8, #8
  26431. + ldr r0, [r8, #0x0]
  26432. + ldr r3, [r8, #0x4]
  26433. + str r3, [r5, r0]
  26434. + add r8, r8, #8
  26435. +
  26436. + ldr r0, [r8, #0x0]
  26437. + ldr r3, [r8, #0x4]
  26438. + str r3, [r5, r0]
  26439. + add r8, r8, #8
  26440. +
  26441. + /* update MISC register: WALAT, RALAT */
  26442. + ldr r0, =0x00081740
  26443. + str r0, [r5, #MMDC0_MDMISC]
  26444. +
  26445. + /* configure ddr devices to dll on, odt. */
  26446. + ldr r0, =0x00028031
  26447. + str r0, [r5, #MMDC0_MDSCR]
  26448. +
  26449. + ldr r0, =0x00028039
  26450. + str r0, [r5, #MMDC0_MDSCR]
  26451. +
  26452. + /* delay for while. */
  26453. + ldr r1, =4
  26454. +delay7:
  26455. + ldr r2, =0
  26456. +cont7:
  26457. + ldr r0, [r5, r2]
  26458. + add r2, r2, #4
  26459. + cmp r2, #16
  26460. + bne cont7
  26461. + sub r1, r1, #1
  26462. + cmp r1, #0
  26463. + bgt delay7
  26464. +
  26465. + /* reset dll. */
  26466. + ldr r0, =0x09208030
  26467. + str r0, [r5, #MMDC0_MDSCR]
  26468. +
  26469. + ldr r0, =0x09208038
  26470. + str r0, [r5, #MMDC0_MDSCR]
  26471. +
  26472. + /* delay for while. */
  26473. + ldr r1, =100
  26474. +delay8:
  26475. + ldr r2, =0
  26476. +cont8:
  26477. + ldr r0, [r5, r2]
  26478. + add r2, r2, #4
  26479. + cmp r2, #16
  26480. + bne cont8
  26481. + sub r1, r1, #1
  26482. + cmp r1, #0
  26483. + bgt delay8
  26484. +
  26485. + ldr r0, [r8, #0x0]
  26486. + ldr r3, [r8, #0x4]
  26487. + str r3, [r5, r0]
  26488. + add r8, r8, #8
  26489. +
  26490. + ldr r0, [r8, #0x0]
  26491. + ldr r3, [r8, #0x4]
  26492. + str r3, [r5, r0]
  26493. + add r8, r8, #8
  26494. +
  26495. + ldr r0, =0x00428031
  26496. + str r0, [r5, #MMDC0_MDSCR]
  26497. +
  26498. + ldr r0, =0x00428039
  26499. + str r0, [r5, #MMDC0_MDSCR]
  26500. +
  26501. + ldr r0, [r8, #0x0]
  26502. + ldr r3, [r8, #0x4]
  26503. + str r3, [r5, r0]
  26504. + add r8, r8, #8
  26505. +
  26506. + ldr r0, [r8, #0x0]
  26507. + ldr r3, [r8, #0x4]
  26508. + str r3, [r5, r0]
  26509. + add r8, r8, #8
  26510. +
  26511. + /* issue a zq command. */
  26512. + ldr r0, =0x04008040
  26513. + str r0, [r5, #MMDC0_MDSCR]
  26514. +
  26515. + ldr r0, =0x04008048
  26516. + str r0, [r5, #MMDC0_MDSCR]
  26517. +
  26518. + /* MMDC ODT enable. */
  26519. + ldr r0, [r8, #0x0]
  26520. + ldr r3, [r8, #0x4]
  26521. + str r3, [r5, r0]
  26522. + add r8, r8, #8
  26523. +
  26524. + ldr r2, =0x4818
  26525. + str r0, [r5, r2]
  26526. +
  26527. + /* delay for while. */
  26528. + ldr r1, =40
  26529. +delay15:
  26530. + ldr r2, =0
  26531. +cont15:
  26532. + ldr r0, [r5, r2]
  26533. + add r2, r2, #4
  26534. + cmp r2, #16
  26535. + bne cont15
  26536. + sub r1, r1, #1
  26537. + cmp r1, #0
  26538. + bgt delay15
  26539. +
  26540. + /* MMDC0_MAPSR adopt power down enable. */
  26541. + ldr r0, [r5, #MMDC0_MAPSR]
  26542. + bic r0, r0, #0x01
  26543. + str r0, [r5, #MMDC0_MAPSR]
  26544. +
  26545. + /* enable MMDC power down timer. */
  26546. + ldr r0, [r5, #MMDC0_MDPDC]
  26547. + orr r0, r0, #(0x55 << 8)
  26548. + str r0, [r5, #MMDC0_MDPDC]
  26549. +
  26550. + b update_calibration
  26551. +
  26552. +update_calibration_only:
  26553. + ldr r1, [r8]
  26554. + sub r1, r1, #7
  26555. + add r8, r8, #64
  26556. + b update_calib
  26557. +
  26558. +update_calibration:
  26559. + /* write the new calibration values. */
  26560. + mov r1, r9
  26561. + sub r1, r1, #7
  26562. +
  26563. +update_calib:
  26564. + ldr r0, [r8, #0x0]
  26565. + ldr r3, [r8, #0x4]
  26566. + str r3, [r5, r0]
  26567. + add r8, r8, #8
  26568. + sub r1, r1, #1
  26569. + cmp r1, #0
  26570. + bgt update_calib
  26571. +
  26572. + /* perform a force measurement. */
  26573. + ldr r0, =0x800
  26574. + str r0, [r5, #MMDC0_MPMUR0]
  26575. + ldr r2, =MMDC1_MPMUR0
  26576. + str r0, [r5, r2]
  26577. +
  26578. + /* clear SBS - unblock DDR accesses. */
  26579. + ldr r0, [r5, #MMDC0_MADPCR0]
  26580. + bic r0, r0, #(1 << 8)
  26581. + str r0, [r5, #MMDC0_MADPCR0]
  26582. +
  26583. + mov r0, #0x0
  26584. + str r0, [r5, #MMDC0_MDSCR]
  26585. +poll_conreq_clear_2:
  26586. + ldr r0, [r5, #MMDC0_MDSCR]
  26587. + and r0, r0, #(0x4 << 12)
  26588. + cmp r0, #(0x4 << 12)
  26589. + beq poll_conreq_clear_2
  26590. +
  26591. +done:
  26592. + /* restore registers */
  26593. +
  26594. + ldmfd sp!, {r4-r12}
  26595. + mov pc, lr
  26596. +
  26597. + .type mx6_do_ddr3_freq_change, #object
  26598. +ENTRY(mx6_do_ddr_freq_change)
  26599. + .word mx6_ddr3_freq_change
  26600. + .size mx6_ddr3_freq_change, . - mx6_ddr3_freq_change
  26601. diff -Nur linux-3.14.17/arch/arm/mach-imx/gpc.c linux-imx6-3.14/arch/arm/mach-imx/gpc.c
  26602. --- linux-3.14.17/arch/arm/mach-imx/gpc.c 2014-08-14 03:38:34.000000000 +0200
  26603. +++ linux-imx6-3.14/arch/arm/mach-imx/gpc.c 2014-09-11 18:05:53.346003382 +0200
  26604. @@ -10,30 +10,69 @@
  26605. * http://www.gnu.org/copyleft/gpl.html
  26606. */
  26607. +#include <linux/clk.h>
  26608. +#include <linux/delay.h>
  26609. #include <linux/io.h>
  26610. #include <linux/irq.h>
  26611. +#include <linux/module.h>
  26612. #include <linux/of.h>
  26613. #include <linux/of_address.h>
  26614. #include <linux/of_irq.h>
  26615. +#include <linux/platform_device.h>
  26616. #include <linux/irqchip/arm-gic.h>
  26617. +#include <linux/regulator/consumer.h>
  26618. +#include <linux/regulator/driver.h>
  26619. +#include <linux/regulator/machine.h>
  26620. #include "common.h"
  26621. +#include "hardware.h"
  26622. #define GPC_IMR1 0x008
  26623. #define GPC_PGC_CPU_PDN 0x2a0
  26624. +#define GPC_PGC_GPU_PDN 0x260
  26625. +#define GPC_PGC_GPU_PUPSCR 0x264
  26626. +#define GPC_PGC_GPU_PDNSCR 0x268
  26627. +#define GPC_PGC_GPU_SW_SHIFT 0
  26628. +#define GPC_PGC_GPU_SW_MASK 0x3f
  26629. +#define GPC_PGC_GPU_SW2ISO_SHIFT 8
  26630. +#define GPC_PGC_GPU_SW2ISO_MASK 0x3f
  26631. +#define GPC_PGC_CPU_PUPSCR 0x2a4
  26632. +#define GPC_PGC_CPU_PDNSCR 0x2a8
  26633. +#define GPC_PGC_CPU_SW_SHIFT 0
  26634. +#define GPC_PGC_CPU_SW_MASK 0x3f
  26635. +#define GPC_PGC_CPU_SW2ISO_SHIFT 8
  26636. +#define GPC_PGC_CPU_SW2ISO_MASK 0x3f
  26637. +#define GPC_CNTR 0x0
  26638. +#define GPC_CNTR_PU_UP_REQ_SHIFT 0x1
  26639. +#define GPC_CNTR_PU_DOWN_REQ_SHIFT 0x0
  26640. #define IMR_NUM 4
  26641. static void __iomem *gpc_base;
  26642. static u32 gpc_wake_irqs[IMR_NUM];
  26643. static u32 gpc_saved_imrs[IMR_NUM];
  26644. +static struct clk *gpu3d_clk, *gpu3d_shader_clk, *gpu2d_clk, *gpu2d_axi_clk;
  26645. +static struct clk *openvg_axi_clk, *vpu_clk, *ipg_clk;
  26646. +static struct device *gpc_dev;
  26647. +struct regulator *pu_reg;
  26648. +struct notifier_block nb;
  26649. +static struct regulator_dev *pu_dummy_regulator_rdev;
  26650. +static struct regulator_init_data pu_dummy_initdata = {
  26651. + .constraints = {
  26652. + .max_uV = 1450000, /* allign with real max of anatop */
  26653. + .valid_ops_mask = REGULATOR_CHANGE_STATUS |
  26654. + REGULATOR_CHANGE_VOLTAGE,
  26655. + },
  26656. +};
  26657. +static int pu_dummy_enable;
  26658. -void imx_gpc_pre_suspend(void)
  26659. +void imx_gpc_pre_suspend(bool arm_power_off)
  26660. {
  26661. void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
  26662. int i;
  26663. - /* Tell GPC to power off ARM core when suspend */
  26664. - writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
  26665. + if (arm_power_off)
  26666. + /* Tell GPC to power off ARM core when suspend */
  26667. + writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
  26668. for (i = 0; i < IMR_NUM; i++) {
  26669. gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
  26670. @@ -120,10 +159,119 @@
  26671. writel_relaxed(val, reg);
  26672. }
  26673. +static void imx_pu_clk(bool enable)
  26674. +{
  26675. + if (enable) {
  26676. + if (cpu_is_imx6sl()) {
  26677. + clk_prepare_enable(gpu2d_clk);
  26678. + clk_prepare_enable(openvg_axi_clk);
  26679. + } else {
  26680. + clk_prepare_enable(vpu_clk);
  26681. + clk_prepare_enable(gpu3d_clk);
  26682. + clk_prepare_enable(gpu3d_shader_clk);
  26683. + clk_prepare_enable(gpu2d_clk);
  26684. + clk_prepare_enable(gpu2d_axi_clk);
  26685. + clk_prepare_enable(openvg_axi_clk);
  26686. + }
  26687. + } else {
  26688. + if (cpu_is_imx6sl()) {
  26689. + clk_disable_unprepare(gpu2d_clk);
  26690. + clk_disable_unprepare(openvg_axi_clk);
  26691. + } else {
  26692. + clk_disable_unprepare(openvg_axi_clk);
  26693. + clk_disable_unprepare(gpu2d_axi_clk);
  26694. + clk_disable_unprepare(gpu2d_clk);
  26695. + clk_disable_unprepare(gpu3d_shader_clk);
  26696. + clk_disable_unprepare(gpu3d_clk);
  26697. + clk_disable_unprepare(vpu_clk);
  26698. + }
  26699. + }
  26700. +}
  26701. +
  26702. +static void imx_gpc_pu_enable(bool enable)
  26703. +{
  26704. + u32 rate, delay_us;
  26705. + u32 gpu_pupscr_sw2iso, gpu_pdnscr_iso2sw;
  26706. + u32 gpu_pupscr_sw, gpu_pdnscr_iso;
  26707. +
  26708. + /* get ipg clk rate for PGC delay */
  26709. + rate = clk_get_rate(ipg_clk);
  26710. +
  26711. + if (enable) {
  26712. + imx_anatop_pu_enable(true);
  26713. + /*
  26714. + * need to add necessary delay between powering up PU LDO and
  26715. + * disabling PU isolation in PGC, the counter of PU isolation
  26716. + * is based on ipg clk.
  26717. + */
  26718. + gpu_pupscr_sw2iso = (readl_relaxed(gpc_base +
  26719. + GPC_PGC_GPU_PUPSCR) >> GPC_PGC_GPU_SW2ISO_SHIFT)
  26720. + & GPC_PGC_GPU_SW2ISO_MASK;
  26721. + gpu_pupscr_sw = (readl_relaxed(gpc_base +
  26722. + GPC_PGC_GPU_PUPSCR) >> GPC_PGC_GPU_SW_SHIFT)
  26723. + & GPC_PGC_GPU_SW_MASK;
  26724. + delay_us = (gpu_pupscr_sw2iso + gpu_pupscr_sw) * 1000000
  26725. + / rate + 1;
  26726. + udelay(delay_us);
  26727. +
  26728. + imx_pu_clk(true);
  26729. + writel_relaxed(1, gpc_base + GPC_PGC_GPU_PDN);
  26730. + writel_relaxed(1 << GPC_CNTR_PU_UP_REQ_SHIFT,
  26731. + gpc_base + GPC_CNTR);
  26732. + while (readl_relaxed(gpc_base + GPC_CNTR) &
  26733. + (1 << GPC_CNTR_PU_UP_REQ_SHIFT))
  26734. + ;
  26735. + imx_pu_clk(false);
  26736. + } else {
  26737. + writel_relaxed(1, gpc_base + GPC_PGC_GPU_PDN);
  26738. + writel_relaxed(1 << GPC_CNTR_PU_DOWN_REQ_SHIFT,
  26739. + gpc_base + GPC_CNTR);
  26740. + while (readl_relaxed(gpc_base + GPC_CNTR) &
  26741. + (1 << GPC_CNTR_PU_DOWN_REQ_SHIFT))
  26742. + ;
  26743. + /*
  26744. + * need to add necessary delay between enabling PU isolation
  26745. + * in PGC and powering down PU LDO , the counter of PU isolation
  26746. + * is based on ipg clk.
  26747. + */
  26748. + gpu_pdnscr_iso2sw = (readl_relaxed(gpc_base +
  26749. + GPC_PGC_GPU_PDNSCR) >> GPC_PGC_GPU_SW2ISO_SHIFT)
  26750. + & GPC_PGC_GPU_SW2ISO_MASK;
  26751. + gpu_pdnscr_iso = (readl_relaxed(gpc_base +
  26752. + GPC_PGC_GPU_PDNSCR) >> GPC_PGC_GPU_SW_SHIFT)
  26753. + & GPC_PGC_GPU_SW_MASK;
  26754. + delay_us = (gpu_pdnscr_iso2sw + gpu_pdnscr_iso) * 1000000
  26755. + / rate + 1;
  26756. + udelay(delay_us);
  26757. + imx_anatop_pu_enable(false);
  26758. + }
  26759. +}
  26760. +
  26761. +static int imx_gpc_regulator_notify(struct notifier_block *nb,
  26762. + unsigned long event,
  26763. + void *ignored)
  26764. +{
  26765. + switch (event) {
  26766. + case REGULATOR_EVENT_PRE_DISABLE:
  26767. + imx_gpc_pu_enable(false);
  26768. + break;
  26769. + case REGULATOR_EVENT_ENABLE:
  26770. + imx_gpc_pu_enable(true);
  26771. + break;
  26772. + default:
  26773. + break;
  26774. + }
  26775. +
  26776. + return NOTIFY_OK;
  26777. +}
  26778. +
  26779. void __init imx_gpc_init(void)
  26780. {
  26781. struct device_node *np;
  26782. int i;
  26783. + u32 val;
  26784. + u32 cpu_pupscr_sw2iso, cpu_pupscr_sw;
  26785. + u32 cpu_pdnscr_iso2sw, cpu_pdnscr_iso;
  26786. np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
  26787. gpc_base = of_iomap(np, 0);
  26788. @@ -137,4 +285,190 @@
  26789. gic_arch_extn.irq_mask = imx_gpc_irq_mask;
  26790. gic_arch_extn.irq_unmask = imx_gpc_irq_unmask;
  26791. gic_arch_extn.irq_set_wake = imx_gpc_irq_set_wake;
  26792. +
  26793. + /*
  26794. + * If there are CPU isolation timing settings in dts,
  26795. + * update them according to dts, otherwise, keep them
  26796. + * with default value in registers.
  26797. + */
  26798. + cpu_pupscr_sw2iso = cpu_pupscr_sw =
  26799. + cpu_pdnscr_iso2sw = cpu_pdnscr_iso = 0;
  26800. +
  26801. + /* Read CPU isolation setting for GPC */
  26802. + of_property_read_u32(np, "fsl,cpu_pupscr_sw2iso", &cpu_pupscr_sw2iso);
  26803. + of_property_read_u32(np, "fsl,cpu_pupscr_sw", &cpu_pupscr_sw);
  26804. + of_property_read_u32(np, "fsl,cpu_pdnscr_iso2sw", &cpu_pdnscr_iso2sw);
  26805. + of_property_read_u32(np, "fsl,cpu_pdnscr_iso", &cpu_pdnscr_iso);
  26806. +
  26807. + /* Update CPU PUPSCR timing if it is defined in dts */
  26808. + val = readl_relaxed(gpc_base + GPC_PGC_CPU_PUPSCR);
  26809. + if (cpu_pupscr_sw2iso)
  26810. + val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
  26811. + if (cpu_pupscr_sw)
  26812. + val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
  26813. + val |= cpu_pupscr_sw2iso << GPC_PGC_CPU_SW2ISO_SHIFT;
  26814. + val |= cpu_pupscr_sw << GPC_PGC_CPU_SW_SHIFT;
  26815. + writel_relaxed(val, gpc_base + GPC_PGC_CPU_PUPSCR);
  26816. +
  26817. + /* Update CPU PDNSCR timing if it is defined in dts */
  26818. + val = readl_relaxed(gpc_base + GPC_PGC_CPU_PDNSCR);
  26819. + if (cpu_pdnscr_iso2sw)
  26820. + val &= ~(GPC_PGC_CPU_SW2ISO_MASK << GPC_PGC_CPU_SW2ISO_SHIFT);
  26821. + if (cpu_pdnscr_iso)
  26822. + val &= ~(GPC_PGC_CPU_SW_MASK << GPC_PGC_CPU_SW_SHIFT);
  26823. + val |= cpu_pdnscr_iso2sw << GPC_PGC_CPU_SW2ISO_SHIFT;
  26824. + val |= cpu_pdnscr_iso << GPC_PGC_CPU_SW_SHIFT;
  26825. + writel_relaxed(val, gpc_base + GPC_PGC_CPU_PDNSCR);
  26826. +}
  26827. +
  26828. +static int imx_pureg_set_voltage(struct regulator_dev *reg, int min_uV,
  26829. + int max_uV, unsigned *selector)
  26830. +{
  26831. + return 0;
  26832. +}
  26833. +
  26834. +static int imx_pureg_enable(struct regulator_dev *rdev)
  26835. +{
  26836. + pu_dummy_enable = 1;
  26837. +
  26838. + return 0;
  26839. +}
  26840. +
  26841. +static int imx_pureg_disable(struct regulator_dev *rdev)
  26842. +{
  26843. + pu_dummy_enable = 0;
  26844. +
  26845. + return 0;
  26846. }
  26847. +
  26848. +static int imx_pureg_is_enable(struct regulator_dev *rdev)
  26849. +{
  26850. + return pu_dummy_enable;
  26851. +}
  26852. +
  26853. +static int imx_pureg_list_voltage(struct regulator_dev *rdev,
  26854. + unsigned int selector)
  26855. +{
  26856. + return 0;
  26857. +}
  26858. +
  26859. +static struct regulator_ops pu_dummy_ops = {
  26860. + .set_voltage = imx_pureg_set_voltage,
  26861. + .enable = imx_pureg_enable,
  26862. + .disable = imx_pureg_disable,
  26863. + .is_enabled = imx_pureg_is_enable,
  26864. + .list_voltage = imx_pureg_list_voltage,
  26865. +};
  26866. +
  26867. +static struct regulator_desc pu_dummy_desc = {
  26868. + .name = "pureg-dummy",
  26869. + .id = -1,
  26870. + .type = REGULATOR_VOLTAGE,
  26871. + .owner = THIS_MODULE,
  26872. + .ops = &pu_dummy_ops,
  26873. +};
  26874. +
  26875. +static int pu_dummy_probe(struct platform_device *pdev)
  26876. +{
  26877. + struct regulator_config config = { };
  26878. + int ret;
  26879. +
  26880. + config.dev = &pdev->dev;
  26881. + config.init_data = &pu_dummy_initdata;
  26882. + config.of_node = pdev->dev.of_node;
  26883. +
  26884. + pu_dummy_regulator_rdev = regulator_register(&pu_dummy_desc, &config);
  26885. + if (IS_ERR(pu_dummy_regulator_rdev)) {
  26886. + ret = PTR_ERR(pu_dummy_regulator_rdev);
  26887. + dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
  26888. + return ret;
  26889. + }
  26890. +
  26891. + return 0;
  26892. +}
  26893. +
  26894. +static const struct of_device_id imx_pudummy_ids[] = {
  26895. + { .compatible = "fsl,imx6-dummy-pureg" },
  26896. +};
  26897. +MODULE_DEVICE_TABLE(of, imx_pudummy_ids);
  26898. +
  26899. +static struct platform_driver pu_dummy_driver = {
  26900. + .probe = pu_dummy_probe,
  26901. + .driver = {
  26902. + .name = "pu-dummy",
  26903. + .owner = THIS_MODULE,
  26904. + .of_match_table = imx_pudummy_ids,
  26905. + },
  26906. +};
  26907. +
  26908. +static int imx_gpc_probe(struct platform_device *pdev)
  26909. +{
  26910. + int ret;
  26911. +
  26912. + gpc_dev = &pdev->dev;
  26913. +
  26914. + pu_reg = devm_regulator_get(gpc_dev, "pu");
  26915. + if (IS_ERR(pu_reg)) {
  26916. + ret = PTR_ERR(pu_reg);
  26917. + dev_info(gpc_dev, "pu regulator not ready.\n");
  26918. + return ret;
  26919. + }
  26920. + nb.notifier_call = &imx_gpc_regulator_notify;
  26921. +
  26922. + /* Get gpu&vpu clk for power up PU by GPC */
  26923. + if (cpu_is_imx6sl()) {
  26924. + gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_podf");
  26925. + openvg_axi_clk = devm_clk_get(gpc_dev, "gpu2d_ovg");
  26926. + ipg_clk = devm_clk_get(gpc_dev, "ipg");
  26927. + if (IS_ERR(gpu2d_clk) || IS_ERR(openvg_axi_clk)
  26928. + || IS_ERR(ipg_clk)) {
  26929. + dev_err(gpc_dev, "failed to get clk!\n");
  26930. + return -ENOENT;
  26931. + }
  26932. + } else {
  26933. + gpu3d_clk = devm_clk_get(gpc_dev, "gpu3d_core");
  26934. + gpu3d_shader_clk = devm_clk_get(gpc_dev, "gpu3d_shader");
  26935. + gpu2d_clk = devm_clk_get(gpc_dev, "gpu2d_core");
  26936. + gpu2d_axi_clk = devm_clk_get(gpc_dev, "gpu2d_axi");
  26937. + openvg_axi_clk = devm_clk_get(gpc_dev, "openvg_axi");
  26938. + vpu_clk = devm_clk_get(gpc_dev, "vpu_axi");
  26939. + ipg_clk = devm_clk_get(gpc_dev, "ipg");
  26940. + if (IS_ERR(gpu3d_clk) || IS_ERR(gpu3d_shader_clk)
  26941. + || IS_ERR(gpu2d_clk) || IS_ERR(gpu2d_axi_clk)
  26942. + || IS_ERR(openvg_axi_clk) || IS_ERR(vpu_clk)
  26943. + || IS_ERR(ipg_clk)) {
  26944. + dev_err(gpc_dev, "failed to get clk!\n");
  26945. + return -ENOENT;
  26946. + }
  26947. + }
  26948. +
  26949. + ret = regulator_register_notifier(pu_reg, &nb);
  26950. + if (ret) {
  26951. + dev_err(gpc_dev,
  26952. + "regulator notifier request failed\n");
  26953. + return ret;
  26954. + }
  26955. +
  26956. + return 0;
  26957. +}
  26958. +
  26959. +static const struct of_device_id imx_gpc_ids[] = {
  26960. + { .compatible = "fsl,imx6q-gpc" },
  26961. +};
  26962. +MODULE_DEVICE_TABLE(of, imx_gpc_ids);
  26963. +
  26964. +static struct platform_driver imx_gpc_platdrv = {
  26965. + .driver = {
  26966. + .name = "imx-gpc",
  26967. + .owner = THIS_MODULE,
  26968. + .of_match_table = imx_gpc_ids,
  26969. + },
  26970. + .probe = imx_gpc_probe,
  26971. +};
  26972. +module_platform_driver(imx_gpc_platdrv);
  26973. +
  26974. +module_platform_driver(pu_dummy_driver);
  26975. +
  26976. +MODULE_AUTHOR("Anson Huang <b20788@freescale.com>");
  26977. +MODULE_DESCRIPTION("Freescale i.MX GPC driver");
  26978. +MODULE_LICENSE("GPL");
  26979. diff -Nur linux-3.14.17/arch/arm/mach-imx/hardware.h linux-imx6-3.14/arch/arm/mach-imx/hardware.h
  26980. --- linux-3.14.17/arch/arm/mach-imx/hardware.h 2014-08-14 03:38:34.000000000 +0200
  26981. +++ linux-imx6-3.14/arch/arm/mach-imx/hardware.h 2014-09-11 18:05:53.346003382 +0200
  26982. @@ -1,5 +1,5 @@
  26983. /*
  26984. - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  26985. + * Copyright 2004-2007, 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  26986. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  26987. *
  26988. * This program is free software; you can redistribute it and/or
  26989. @@ -20,7 +20,9 @@
  26990. #ifndef __ASM_ARCH_MXC_HARDWARE_H__
  26991. #define __ASM_ARCH_MXC_HARDWARE_H__
  26992. +#ifndef __ASSEMBLY__
  26993. #include <asm/io.h>
  26994. +#endif
  26995. #include <asm/sizes.h>
  26996. #define addr_in_module(addr, mod) \
  26997. diff -Nur linux-3.14.17/arch/arm/mach-imx/headsmp.S linux-imx6-3.14/arch/arm/mach-imx/headsmp.S
  26998. --- linux-3.14.17/arch/arm/mach-imx/headsmp.S 2014-08-14 03:38:34.000000000 +0200
  26999. +++ linux-imx6-3.14/arch/arm/mach-imx/headsmp.S 2014-09-11 18:05:53.346003382 +0200
  27000. @@ -12,8 +12,6 @@
  27001. #include <linux/linkage.h>
  27002. #include <linux/init.h>
  27003. -#include <asm/asm-offsets.h>
  27004. -#include <asm/hardware/cache-l2x0.h>
  27005. .section ".text.head", "ax"
  27006. @@ -35,37 +33,3 @@
  27007. b secondary_startup
  27008. ENDPROC(v7_secondary_startup)
  27009. #endif
  27010. -
  27011. -#ifdef CONFIG_ARM_CPU_SUSPEND
  27012. -/*
  27013. - * The following code must assume it is running from physical address
  27014. - * where absolute virtual addresses to the data section have to be
  27015. - * turned into relative ones.
  27016. - */
  27017. -
  27018. -#ifdef CONFIG_CACHE_L2X0
  27019. - .macro pl310_resume
  27020. - adr r0, l2x0_saved_regs_offset
  27021. - ldr r2, [r0]
  27022. - add r2, r2, r0
  27023. - ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
  27024. - ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value
  27025. - str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl
  27026. - mov r1, #0x1
  27027. - str r1, [r0, #L2X0_CTRL] @ re-enable L2
  27028. - .endm
  27029. -
  27030. -l2x0_saved_regs_offset:
  27031. - .word l2x0_saved_regs - .
  27032. -
  27033. -#else
  27034. - .macro pl310_resume
  27035. - .endm
  27036. -#endif
  27037. -
  27038. -ENTRY(v7_cpu_resume)
  27039. - bl v7_invalidate_l1
  27040. - pl310_resume
  27041. - b cpu_resume
  27042. -ENDPROC(v7_cpu_resume)
  27043. -#endif
  27044. diff -Nur linux-3.14.17/arch/arm/mach-imx/imx6sl_wfi.S linux-imx6-3.14/arch/arm/mach-imx/imx6sl_wfi.S
  27045. --- linux-3.14.17/arch/arm/mach-imx/imx6sl_wfi.S 1970-01-01 01:00:00.000000000 +0100
  27046. +++ linux-imx6-3.14/arch/arm/mach-imx/imx6sl_wfi.S 2014-09-11 18:05:53.346003382 +0200
  27047. @@ -0,0 +1,639 @@
  27048. +/*
  27049. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  27050. + *
  27051. + * This program is free software; you can redistribute it and/or modify
  27052. + * it under the terms of the GNU General Public License as published by
  27053. + * the Free Software Foundation; either version 2 of the License, or
  27054. + * (at your option) any later version.
  27055. +
  27056. + * This program is distributed in the hope that it will be useful,
  27057. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27058. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27059. + * GNU General Public License for more details.
  27060. +
  27061. + * You should have received a copy of the GNU General Public License along
  27062. + * with this program; if not, write to the Free Software Foundation, Inc.,
  27063. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27064. + */
  27065. +
  27066. +#include <linux/linkage.h>
  27067. +#define IRAM_WAIT_SIZE (1 << 11)
  27068. +
  27069. + .macro sl_ddr_io_save
  27070. +
  27071. + ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
  27072. + ldr r5, [r1, #0x310] /* DRAM_DQM1 */
  27073. + ldr r6, [r1, #0x314] /* DRAM_DQM2 */
  27074. + ldr r7, [r1, #0x318] /* DRAM_DQM3 */
  27075. + stmfd r9!, {r4-r7}
  27076. +
  27077. + ldr r4, [r1, #0x5c4] /* GPR_B0DS */
  27078. + ldr r5, [r1, #0x5cc] /* GPR_B1DS */
  27079. + ldr r6, [r1, #0x5d4] /* GPR_B2DS */
  27080. + ldr r7, [r1, #0x5d8] /* GPR_B3DS */
  27081. + stmfd r9!, {r4-r7}
  27082. +
  27083. + ldr r4, [r1, #0x300] /* DRAM_CAS */
  27084. + ldr r5, [r1, #0x31c] /* DRAM_RAS */
  27085. + ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
  27086. + ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
  27087. + stmfd r9!, {r4-r7}
  27088. +
  27089. + ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27090. + ldr r5, [r1, #0x5c0] /* DDRMODE */
  27091. + ldr r6, [r1, #0x33c] /* DRAM_SODT0*/
  27092. + ldr r7, [r1, #0x340] /* DRAM_SODT1*/
  27093. + stmfd r9!, {r4-r7}
  27094. +
  27095. + ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27096. + ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
  27097. + ldr r6, [r1, #0x320] /* DRAM_RESET */
  27098. + stmfd r9!, {r4-r6}
  27099. +
  27100. + .endm
  27101. +
  27102. + .macro sl_ddr_io_restore
  27103. +
  27104. + /*
  27105. + * r9 points to IRAM stack.
  27106. + * r1 points to IOMUX base address.
  27107. + * r8 points to MMDC base address.
  27108. + */
  27109. + ldmea r9!, {r4-r7}
  27110. + str r4, [r1, #0x30c] /* DRAM_DQM0 */
  27111. + str r5, [r1, #0x310] /* DRAM_DQM1 */
  27112. + str r6, [r1, #0x314] /* DRAM_DQM2 */
  27113. + str r7, [r1, #0x318] /* DRAM_DQM3 */
  27114. +
  27115. + ldmea r9!, {r4-r7}
  27116. + str r4, [r1, #0x5c4] /* GPR_B0DS */
  27117. + str r5, [r1, #0x5cc] /* GPR_B1DS */
  27118. + str r6, [r1, #0x5d4] /* GPR_B2DS */
  27119. + str r7, [r1, #0x5d8] /* GPR_B3DS */
  27120. +
  27121. + ldmea r9!, {r4-r7}
  27122. + str r4, [r1, #0x300] /* DRAM_CAS */
  27123. + str r5, [r1, #0x31c] /* DRAM_RAS */
  27124. + str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
  27125. + str r7, [r1, #0x5ac] /* GPR_ADDS*/
  27126. +
  27127. + ldmea r9!, {r4-r7}
  27128. + str r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27129. + str r5, [r1, #0x5c0] /* DDRMODE */
  27130. + str r6, [r1, #0x33c] /* DRAM_SODT0*/
  27131. + str r7, [r1, #0x340] /* DRAM_SODT1*/
  27132. +
  27133. + ldmea r9!, {r4-r6}
  27134. + str r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27135. + str r5, [r1, #0x334] /* DRAM_SDCKE1 */
  27136. + str r6, [r1, #0x320] /* DRAM_RESET */
  27137. +
  27138. + /*
  27139. + * Need to reset the FIFO to avoid MMDC lockup
  27140. + * caused because of floating/changing the
  27141. + * configuration of many DDR IO pads.
  27142. + */
  27143. + ldr r7, =0x83c
  27144. + ldr r6, [r8, r7]
  27145. + orr r6, r6, #0x80000000
  27146. + str r6, [r8, r7]
  27147. +fifo_reset1_wait:
  27148. + ldr r6, [r8, r7]
  27149. + and r6, r6, #0x80000000
  27150. + cmp r6, #0
  27151. + bne fifo_reset1_wait
  27152. +
  27153. + /* reset FIFO a second time */
  27154. + ldr r6, [r8, r7]
  27155. + orr r6, r6, #0x80000000
  27156. + str r6, [r8, r7]
  27157. +fifo_reset2_wait:
  27158. + ldr r6, [r8, r7]
  27159. + and r6, r6, #0x80000000
  27160. + cmp r6, #0
  27161. + bne fifo_reset2_wait
  27162. +
  27163. + .endm
  27164. +
  27165. + .macro sl_ddr_io_set_lpm
  27166. +
  27167. + mov r4, #0
  27168. + str r4, [r1, #0x30c] /* DRAM_DQM0 */
  27169. + str r4, [r1, #0x310] /* DRAM_DQM1 */
  27170. + str r4, [r1, #0x314] /* DRAM_DQM2 */
  27171. + str r4, [r1, #0x318] /* DRAM_DQM3 */
  27172. +
  27173. + str r4, [r1, #0x5c4] /* GPR_B0DS */
  27174. + str r4, [r1, #0x5cc] /* GPR_B1DS */
  27175. + str r4, [r1, #0x5d4] /* GPR_B2DS */
  27176. + str r4, [r1, #0x5d8] /* GPR_B3DS */
  27177. +
  27178. + str r4, [r1, #0x300] /* DRAM_CAS */
  27179. + str r4, [r1, #0x31c] /* DRAM_RAS */
  27180. + str r4, [r1, #0x338] /* DRAM_SDCLK_0 */
  27181. + str r4, [r1, #0x5ac] /* GPR_ADDS*/
  27182. +
  27183. + str r4, [r1, #0x5b0] /* DDRMODE_CTL */
  27184. + str r4, [r1, #0x5c0] /* DDRMODE */
  27185. + str r4, [r1, #0x33c] /* DRAM_SODT0*/
  27186. + str r4, [r1, #0x340] /* DRAM_SODT1*/
  27187. +
  27188. + mov r4, #0x80000
  27189. + str r4, [r1, #0x320] /* DRAM_RESET */
  27190. + mov r4, #0x1000
  27191. + str r4, [r1, #0x330] /* DRAM_SDCKE0 */
  27192. + str r4, [r1, #0x334] /* DRAM_SDCKE1 */
  27193. +
  27194. + .endm
  27195. +
  27196. +/*
  27197. + * imx6sl_low_power_wfi
  27198. + *
  27199. + * Idle the processor (eg, wait for interrupt).
  27200. + * Make sure DDR is in self-refresh.
  27201. + * IRQs are already disabled.
  27202. + * r0: WFI IRAMcode base address.
  27203. + * r1: IOMUX base address
  27204. + * r2: Base address of CCM, ANATOP and MMDC
  27205. + * r3: 1 if in audio_bus_freq_mode
  27206. + */
  27207. + .align 3
  27208. +ENTRY(imx6sl_low_power_wfi)
  27209. +
  27210. + push {r4-r11}
  27211. +
  27212. +mx6sl_lpm_wfi:
  27213. + /* Store audio_bus_freq_mode */
  27214. + mov r11, r3
  27215. +
  27216. + mov r4,r2
  27217. + /* Get the IRAM data storage address. */
  27218. + mov r10, r0
  27219. + mov r9, r0 /* get suspend_iram_base */
  27220. + add r9, r9, #IRAM_WAIT_SIZE
  27221. +
  27222. + /* Anatop Base address in r3. */
  27223. + ldr r3, [r4]
  27224. + /* CCM Base Address in r2 */
  27225. + ldr r2, [r4, #0x4]
  27226. + /* MMDC Base Address in r8 */
  27227. + ldr r8, [r4, #0x8]
  27228. + /* L2 Base Address in r7 */
  27229. + ldr r7, [r4, #0xC]
  27230. +
  27231. + ldr r6, [r8]
  27232. + ldr r6, [r3]
  27233. + ldr r6, [r2]
  27234. + ldr r6, [r1]
  27235. +
  27236. + /* Store the original ARM PODF. */
  27237. + ldr r0, [r2, #0x10]
  27238. +
  27239. + /* Drain all the L1 buffers. */
  27240. + dsb
  27241. +
  27242. +#ifdef CONFIG_CACHE_L2X0
  27243. + /*
  27244. + * Need to make sure the buffers in L2 are drained.
  27245. + * Performing a sync operation does this.
  27246. + */
  27247. + mov r6, #0x0
  27248. + str r6, [r7, #0x730]
  27249. +#endif
  27250. +
  27251. + /*
  27252. + * The second dsb might be needed to keep cache sync (device write)
  27253. + * ordering with the memory accesses before it.
  27254. + */
  27255. + dsb
  27256. + isb
  27257. +
  27258. + /* Save the DDR IO state. */
  27259. + sl_ddr_io_save
  27260. +
  27261. + /* Disable Automatic power savings. */
  27262. + ldr r6, [r8, #0x404]
  27263. + orr r6, r6, #0x01
  27264. + str r6, [r8, #0x404]
  27265. +
  27266. + /* Make the DDR explicitly enter self-refresh. */
  27267. + ldr r6, [r8, #0x404]
  27268. + orr r6, r6, #0x200000
  27269. + str r6, [r8, #0x404]
  27270. +
  27271. +poll_dvfs_set_1:
  27272. + ldr r6, [r8, #0x404]
  27273. + and r6, r6, #0x2000000
  27274. + cmp r6, #0x2000000
  27275. + bne poll_dvfs_set_1
  27276. +
  27277. + /* set SBS step-by-step mode */
  27278. + ldr r6, [r8, #0x410]
  27279. + orr r6, r6, #0x100
  27280. + str r6, [r8, #0x410]
  27281. +
  27282. + cmp r11, #1
  27283. + beq audio_mode
  27284. + /*
  27285. + * Now set DDR rate to 1MHz.
  27286. + * DDR is from bypassed PLL2 on periph2_clk2 path.
  27287. + * Set the periph2_clk2_podf to divide by 8.
  27288. + */
  27289. + ldr r6, [r2, #0x14]
  27290. + orr r6, r6, #0x07
  27291. + str r6, [r2, #0x14]
  27292. +
  27293. + /* Now set MMDC PODF to divide by 3. */
  27294. + ldr r6, [r2, #0x14]
  27295. + bic r6, r6, #0x38
  27296. + orr r6, r6, #0x10
  27297. + str r6, [r2, #0x14]
  27298. + b mmdc_podf
  27299. +
  27300. +audio_mode:
  27301. + /* MMDC is from PLL2_200M.
  27302. + * Set the mmdc_podf to div by 8.
  27303. + */
  27304. + ldr r6, [r2, #0x14]
  27305. + orr r6, r6, #0x38
  27306. + str r6, [r2, #0x14]
  27307. +
  27308. + /* Loop till podf is accepted. */
  27309. +mmdc_podf:
  27310. + ldr r6, [r2, #0x48]
  27311. + cmp r6, #0x0
  27312. + bne mmdc_podf
  27313. +
  27314. + /* Set the DDR IO in LPM state. */
  27315. + sl_ddr_io_set_lpm
  27316. +
  27317. + cmp r11, #1
  27318. + beq do_audio_arm_clk
  27319. +
  27320. + /*
  27321. + * Check if none of the PLLs are
  27322. + * locked, except PLL1 which will get
  27323. + * bypassed below.
  27324. + * We should not be here if PLL2 is not
  27325. + * bypassed.
  27326. + */
  27327. + ldr r7, =1
  27328. + /* USB1 PLL3 */
  27329. + ldr r6, [r3, #0x10]
  27330. + and r6, r6, #0x80000000
  27331. + cmp r6, #0x80000000
  27332. + beq no_analog_saving
  27333. +
  27334. + /* USB2 PLL7 */
  27335. + ldr r6, [r3, #0x20]
  27336. + and r6, r6, #0x80000000
  27337. + cmp r6, #0x80000000
  27338. + beq no_analog_saving
  27339. +
  27340. + /* Audio PLL4 */
  27341. + ldr r6, [r3, #0x70]
  27342. + and r6, r6, #0x80000000
  27343. + cmp r6, #0x80000000
  27344. + beq no_analog_saving
  27345. +
  27346. + /* Video PLL5 */
  27347. + ldr r6, [r3, #0xA0]
  27348. + and r6, r6, #0x80000000
  27349. + cmp r6, #0x80000000
  27350. + beq no_analog_saving
  27351. +
  27352. + /* ENET PLL8 */
  27353. + ldr r6, [r3, #0xE0]
  27354. + and r6, r6, #0x80000000
  27355. + cmp r6, #0x80000000
  27356. + beq no_analog_saving
  27357. +
  27358. + b cont
  27359. +
  27360. +no_analog_saving:
  27361. + ldr r7, =0
  27362. +
  27363. +cont:
  27364. + /* Set the AHB to 3MHz. AXI to 3MHz. */
  27365. + ldr r9, [r2, #0x14]
  27366. + mov r6, r9
  27367. + orr r6, r6, #0x1c00
  27368. + orr r6, r6, #0x70000
  27369. + str r6, [r2, #0x14]
  27370. +
  27371. + /* Loop till podf is accepted. */
  27372. +ahb_podf:
  27373. + ldr r6, [r2, #0x48]
  27374. + cmp r6, #0x0
  27375. + bne podf_loop
  27376. +
  27377. + /*
  27378. + * Now set ARM to 24MHz.
  27379. + * Move ARM to be sourced from STEP_CLK
  27380. + * after setting STEP_CLK to 24MHz.
  27381. + */
  27382. + ldr r6, [r2, #0xc]
  27383. + bic r6, r6, #0x100
  27384. + str r6, [r2, #0x0c]
  27385. + /* Now PLL1_SW_CLK to step_clk. */
  27386. + ldr r6, [r2, #0x0c]
  27387. + orr r6, r6, #0x4
  27388. + str r6, [r2, #0x0c]
  27389. +
  27390. + /* Bypass PLL1 and power it down. */
  27391. + ldr r6, =(1 << 16)
  27392. + orr r6, r6, #0x1000
  27393. + str r6, [r3, #0x04]
  27394. +
  27395. + /*
  27396. + * Set the ARM PODF to divide by 8.
  27397. + * IPG is at 1.5MHz here, we need ARM to
  27398. + * run at the 12:5 ratio (WAIT mode issue).
  27399. + */
  27400. + ldr r6, =0x7
  27401. + str r6, [r2, #0x10]
  27402. +
  27403. + /* Loop till podf is accepted. */
  27404. +podf_loop:
  27405. + ldr r6, [r2, #0x48]
  27406. + cmp r6, #0x0
  27407. + bne podf_loop
  27408. +
  27409. + /*
  27410. + * Check if we can save some
  27411. + * power in the Analog section.
  27412. + */
  27413. + cmp r7, #0x1
  27414. + bne do_wfi
  27415. +
  27416. + /* Disable 1p1 brown out. */
  27417. + ldr r6, [r3, #0x110]
  27418. + bic r6, r6, #0x2
  27419. + str r6, [r3, #0x110]
  27420. +
  27421. + /* Enable the weak 2P5 */
  27422. + ldr r6, [r3, #0x130]
  27423. + orr r6, r6, #0x40000
  27424. + str r6, [r3, #0x130]
  27425. +
  27426. + /* Disable main 2p5. */
  27427. + ldr r6, [r3, #0x130]
  27428. + bic r6, r6, #0x1
  27429. + str r6, [r3, #0x130]
  27430. +
  27431. + /*
  27432. + * Set the OSC bias current to -37.5%
  27433. + * to drop the power on VDDHIGH.
  27434. + */
  27435. + ldr r6, [r3, #0x150]
  27436. + orr r6, r6, #0xC000
  27437. + str r6, [r3, #0x150]
  27438. +
  27439. + /* Enable low power bandgap */
  27440. + ldr r6, [r3, #0x260]
  27441. + orr r6, r6, #0x20
  27442. + str r6, [r3, #0x260]
  27443. +
  27444. + /*
  27445. + * Turn off the bias current
  27446. + * from the regular bandgap.
  27447. + */
  27448. + ldr r6, [r3, #0x260]
  27449. + orr r6, r6, #0x80
  27450. + str r6, [r3, #0x260]
  27451. +
  27452. + /*
  27453. + * Clear the REFTOP_SELFBIASOFF,
  27454. + * self-bias circuit of the band gap.
  27455. + * Per RM, should be cleared when
  27456. + * band gap is powered down.
  27457. + */
  27458. + ldr r6, [r3, #0x150]
  27459. + bic r6, r6, #0x8
  27460. + str r6, [r3, #0x150]
  27461. +
  27462. + /* Power down the regular bandgap. */
  27463. + ldr r6, [r3, #0x150]
  27464. + orr r6, r6, #0x1
  27465. + str r6, [r3, #0x150]
  27466. +
  27467. + b do_wfi
  27468. +
  27469. +do_audio_arm_clk:
  27470. + /*
  27471. + * ARM is from PLL2_PFD2_400M here.
  27472. + * Switch ARM to bypassed PLL1.
  27473. + */
  27474. + ldr r6, [r2, #0xC]
  27475. + bic r6, r6, #0x4
  27476. + str r6, [r2, #0xC]
  27477. +
  27478. + /*
  27479. + * Set the ARM_PODF to divide by 2
  27480. + * as IPG is at 4MHz, we cannot run
  27481. + * ARM_CLK above 9.6MHz when
  27482. + * system enters WAIT mode.
  27483. + */
  27484. + ldr r6, =0x2
  27485. + str r6, [r2, #0x10]
  27486. +
  27487. + /* Loop till podf is accepted. */
  27488. +podf_loop_audio:
  27489. + ldr r6, [r2, #0x48]
  27490. + cmp r6, #0x0
  27491. + bne podf_loop_audio
  27492. +
  27493. +do_wfi:
  27494. + /* Now do WFI. */
  27495. + wfi
  27496. +
  27497. + /* Set original ARM PODF back. */
  27498. + str r0, [r2, #0x10]
  27499. +
  27500. + /* Loop till podf is accepted. */
  27501. +podf_loop1:
  27502. + ldr r6, [r2, #0x48]
  27503. + cmp r6, #0x0
  27504. + bne podf_loop1
  27505. +
  27506. + cmp r11, #1
  27507. + beq audio_arm_clk_restore
  27508. +
  27509. + /*
  27510. + * Check if powered down
  27511. + * analog components.
  27512. + */
  27513. + cmp r7, #0x1
  27514. + bne skip_analog_restore
  27515. +
  27516. + /* Power up the regular bandgap. */
  27517. + ldr r6, [r3, #0x150]
  27518. + bic r6, r6, #0x1
  27519. + str r6, [r3, #0x150]
  27520. +
  27521. + /*
  27522. + * Turn on the bias current
  27523. + * from the regular bandgap.
  27524. + */
  27525. + ldr r6, [r3, #0x260]
  27526. + bic r6, r6, #0x80
  27527. + str r6, [r3, #0x260]
  27528. +
  27529. + /* Disable the low power bandgap */
  27530. + ldr r6, [r3, #0x260]
  27531. + bic r6, r6, #0x20
  27532. + str r6, [r3, #0x260]
  27533. +
  27534. + /*
  27535. + * Set the OSC bias current to max
  27536. + * value for normal operation.
  27537. + */
  27538. + ldr r6, [r3, #0x150]
  27539. + bic r6, r6, #0xC000
  27540. + str r6, [r3, #0x150]
  27541. +
  27542. + /* Enable main 2p5. */
  27543. + ldr r6, [r3, #0x130]
  27544. + orr r6, r6, #0x1
  27545. + str r6, [r3, #0x130]
  27546. +
  27547. + /* Ensure the 2P5 is up. */
  27548. +loop_2p5:
  27549. + ldr r6, [r3, #0x130]
  27550. + and r6, r6, #0x20000
  27551. + cmp r6, #0x20000
  27552. + bne loop_2p5
  27553. +
  27554. + /* Disable the weak 2P5 */
  27555. + ldr r6, [r3, #0x130]
  27556. + bic r6, r6, #0x40000
  27557. + str r6, [r3, #0x130]
  27558. +
  27559. + /* Enable 1p1 brown out. */
  27560. + ldr r6, [r3, #0x110]
  27561. + orr r6, r6, #0x2
  27562. + str r6, [r3, #0x110]
  27563. +
  27564. +skip_analog_restore:
  27565. +
  27566. + /* Power up PLL1 and un-bypass it. */
  27567. + ldr r6, =(1 << 12)
  27568. + str r6, [r3, #0x08]
  27569. +
  27570. + /* Wait for PLL1 to relock. */
  27571. +wait_for_pll_lock:
  27572. + ldr r6, [r3, #0x0]
  27573. + and r6, r6, #0x80000000
  27574. + cmp r6, #0x80000000
  27575. + bne wait_for_pll_lock
  27576. +
  27577. + ldr r6, =(1 << 16)
  27578. + str r6, [r3, #0x08]
  27579. +
  27580. + /* Set PLL1_sw_clk back to PLL1. */
  27581. + ldr r6, [r2, #0x0c]
  27582. + bic r6, r6, #0x4
  27583. + str r6, [r2, #0xc]
  27584. +
  27585. + /* Restore AHB/AXI back. */
  27586. + str r9, [r2, #0x14]
  27587. +
  27588. + /* Loop till podf is accepted. */
  27589. +ahb_podf1:
  27590. + ldr r6, [r2, #0x48]
  27591. + cmp r6, #0x0
  27592. + bne podf_loop1
  27593. +
  27594. + b wfi_restore
  27595. +
  27596. + audio_arm_clk_restore:
  27597. + /* Move ARM back to PLL2_PFD2_400M */
  27598. + ldr r6, [r2, #0xC]
  27599. + orr r6, r6, #0x4
  27600. + str r6, [r2, #0xC]
  27601. +
  27602. +wfi_restore:
  27603. + /* get suspend_iram_base */
  27604. + mov r9, r10
  27605. + add r9, r9, #IRAM_WAIT_SIZE
  27606. +
  27607. + /* Restore the DDR IO before exiting self-refresh. */
  27608. + sl_ddr_io_restore
  27609. +
  27610. + /*
  27611. + * Set MMDC back to 24MHz.
  27612. + * Set periph2_clk2_podf to divide by 1
  27613. + * Now set MMDC PODF to divide by 1.
  27614. + */
  27615. + ldr r6, [r2, #0x14]
  27616. + bic r6, r6, #0x3f
  27617. + str r6, [r2, #0x14]
  27618. +
  27619. +mmdc_podf1:
  27620. + ldr r6, [r2, #0x48]
  27621. + cmp r6, #0x0
  27622. + bne mmdc_podf1
  27623. +
  27624. + /* clear DVFS - exit from self refresh mode */
  27625. + ldr r6, [r8, #0x404]
  27626. + bic r6, r6, #0x200000
  27627. + str r6, [r8, #0x404]
  27628. +
  27629. +poll_dvfs_clear_1:
  27630. + ldr r6, [r8, #0x404]
  27631. + and r6, r6, #0x2000000
  27632. + cmp r6, #0x2000000
  27633. + beq poll_dvfs_clear_1
  27634. +
  27635. + /*
  27636. + * Add these nops so that the
  27637. + * prefetcher will not try to get
  27638. + * any instructions from DDR.
  27639. + * The prefetch depth is about 23
  27640. + * on A9, so adding 25 nops.
  27641. + */
  27642. + nop
  27643. + nop
  27644. + nop
  27645. + nop
  27646. + nop
  27647. +
  27648. + nop
  27649. + nop
  27650. + nop
  27651. + nop
  27652. + nop
  27653. +
  27654. + nop
  27655. + nop
  27656. + nop
  27657. + nop
  27658. + nop
  27659. +
  27660. + nop
  27661. + nop
  27662. + nop
  27663. + nop
  27664. + nop
  27665. +
  27666. + nop
  27667. + nop
  27668. + nop
  27669. + nop
  27670. + nop
  27671. +
  27672. + /* Enable Automatic power savings. */
  27673. + ldr r6, [r8, #0x404]
  27674. + bic r6, r6, #0x01
  27675. + str r6, [r8, #0x404]
  27676. +
  27677. + /* clear SBS - unblock DDR accesses */
  27678. + ldr r6, [r8, #0x410]
  27679. + bic r6, r6, #0x100
  27680. + str r6, [r8, #0x410]
  27681. +
  27682. +
  27683. + pop {r4-r11}
  27684. +
  27685. + /* Restore registers */
  27686. + mov pc, lr
  27687. diff -Nur linux-3.14.17/arch/arm/mach-imx/Kconfig linux-imx6-3.14/arch/arm/mach-imx/Kconfig
  27688. --- linux-3.14.17/arch/arm/mach-imx/Kconfig 2014-08-14 03:38:34.000000000 +0200
  27689. +++ linux-imx6-3.14/arch/arm/mach-imx/Kconfig 2014-09-11 18:05:53.278003110 +0200
  27690. @@ -1,5 +1,6 @@
  27691. config ARCH_MXC
  27692. bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
  27693. + select ARCH_HAS_RESET_CONTROLLER
  27694. select ARCH_REQUIRE_GPIOLIB
  27695. select ARM_CPU_SUSPEND if PM
  27696. select ARM_PATCH_PHYS_VIRT
  27697. @@ -13,6 +14,7 @@
  27698. select PINCTRL
  27699. select SOC_BUS
  27700. select SPARSE_IRQ
  27701. + select SRAM
  27702. select USE_OF
  27703. help
  27704. Support for Freescale MXC/iMX-based family of processors
  27705. @@ -63,7 +65,6 @@
  27706. config HAVE_IMX_SRC
  27707. def_bool y if SMP
  27708. - select ARCH_HAS_RESET_CONTROLLER
  27709. config IMX_HAVE_IOMUX_V1
  27710. bool
  27711. @@ -791,6 +792,8 @@
  27712. select ARM_ERRATA_754322
  27713. select ARM_ERRATA_764369 if SMP
  27714. select ARM_ERRATA_775420
  27715. + select ARM_ERRATA_794072 if SMP
  27716. + select ARM_ERRATA_761320 if SMP
  27717. select ARM_GIC
  27718. select CPU_V7
  27719. select HAVE_ARM_SCU if SMP
  27720. @@ -803,11 +806,13 @@
  27721. select MFD_SYSCON
  27722. select MIGHT_HAVE_PCI
  27723. select PCI_DOMAINS if PCI
  27724. + select ARCH_SUPPORTS_MSI
  27725. select PINCTRL_IMX6Q
  27726. select PL310_ERRATA_588369 if CACHE_PL310
  27727. select PL310_ERRATA_727915 if CACHE_PL310
  27728. select PL310_ERRATA_769419 if CACHE_PL310
  27729. select PM_OPP if PM
  27730. + select ZONE_DMA
  27731. help
  27732. This enables support for Freescale i.MX6 Quad processor.
  27733. diff -Nur linux-3.14.17/arch/arm/mach-imx/lpddr2_freq_imx6.S linux-imx6-3.14/arch/arm/mach-imx/lpddr2_freq_imx6.S
  27734. --- linux-3.14.17/arch/arm/mach-imx/lpddr2_freq_imx6.S 1970-01-01 01:00:00.000000000 +0100
  27735. +++ linux-imx6-3.14/arch/arm/mach-imx/lpddr2_freq_imx6.S 2014-09-11 18:05:53.378003511 +0200
  27736. @@ -0,0 +1,484 @@
  27737. +/*
  27738. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  27739. + *
  27740. + * This program is free software; you can redistribute it and/or modify
  27741. + * it under the terms of the GNU General Public License as published by
  27742. + * the Free Software Foundation; either version 2 of the License, or
  27743. + * (at your option) any later version.
  27744. +
  27745. + * This program is distributed in the hope that it will be useful,
  27746. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27747. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27748. + * GNU General Public License for more details.
  27749. +
  27750. + * You should have received a copy of the GNU General Public License along
  27751. + * with this program; if not, write to the Free Software Foundation, Inc.,
  27752. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27753. + */
  27754. +
  27755. +#include <linux/linkage.h>
  27756. +
  27757. + .macro mx6sl_switch_to_24MHz
  27758. +
  27759. + /*
  27760. + * Set MMDC clock to be sourced from PLL3.
  27761. + * Ensure first periph2_clk2 is sourced from PLL3.
  27762. + * Set the PERIPH2_CLK2_PODF to divide by 2.
  27763. + */
  27764. + ldr r6, [r2, #0x14]
  27765. + bic r6, r6, #0x7
  27766. + orr r6, r6, #0x1
  27767. + str r6, [r2, #0x14]
  27768. +
  27769. + /* Select PLL3 to source MMDC. */
  27770. + ldr r6, [r2, #0x18]
  27771. + bic r6, r6, #0x100000
  27772. + str r6, [r2, #0x18]
  27773. +
  27774. + /* Swtich periph2_clk_sel to run from PLL3. */
  27775. + ldr r6, [r2, #0x14]
  27776. + orr r6, r6, #0x4000000
  27777. + str r6, [r2, #0x14]
  27778. +
  27779. +periph2_clk_switch1:
  27780. + ldr r6, [r2, #0x48]
  27781. + cmp r6, #0
  27782. + bne periph2_clk_switch1
  27783. +
  27784. + /*
  27785. + * Need to clock gate the 528 PFDs before
  27786. + * powering down PLL2.
  27787. + * Only the PLL2_PFD2_400M should be ON
  27788. + * at this time, so only clock gate that one.
  27789. + */
  27790. + ldr r6, [r3, #0x100]
  27791. + orr r6, r6, #0x800000
  27792. + str r6, [r3, #0x100]
  27793. +
  27794. + /*
  27795. + * Set PLL2 to bypass state. We should be here
  27796. + * only if MMDC is not sourced from PLL2.
  27797. + */
  27798. + ldr r6, [r3, #0x30]
  27799. + orr r6, r6, #0x10000
  27800. + str r6, [r3, #0x30]
  27801. +
  27802. + ldr r6, [r3, #0x30]
  27803. + orr r6, r6, #0x1000
  27804. + str r6, [r3, #0x30]
  27805. +
  27806. + /* Ensure pre_periph2_clk_mux is set to pll2 */
  27807. + ldr r6, [r2, #0x18]
  27808. + bic r6, r6, #0x600000
  27809. + str r6, [r2, #0x18]
  27810. +
  27811. + /* Set MMDC clock to be sourced from the bypassed PLL2. */
  27812. + ldr r6, [r2, #0x14]
  27813. + bic r6, r6, #0x4000000
  27814. + str r6, [r2, #0x14]
  27815. +
  27816. +periph2_clk_switch2:
  27817. + ldr r6, [r2, #0x48]
  27818. + cmp r6, #0
  27819. + bne periph2_clk_switch2
  27820. +
  27821. + /*
  27822. + * Now move MMDC back to periph2_clk2 source.
  27823. + * after selecting PLL2 as the option.
  27824. + * Select PLL2 as the source.
  27825. + */
  27826. + ldr r6, [r2, #0x18]
  27827. + orr r6, r6, #0x100000
  27828. + str r6, [r2, #0x18]
  27829. +
  27830. + /* set periph2_clk2_podf to divide by 1. */
  27831. + ldr r6, [r2, #0x14]
  27832. + bic r6, r6, #0x7
  27833. + str r6, [r2, #0x14]
  27834. +
  27835. + /* Now move periph2_clk to periph2_clk2 source */
  27836. + ldr r6, [r2, #0x14]
  27837. + orr r6, r6, #0x4000000
  27838. + str r6, [r2, #0x14]
  27839. +
  27840. +periph2_clk_switch3:
  27841. + ldr r6, [r2, #0x48]
  27842. + cmp r6, #0
  27843. + bne periph2_clk_switch3
  27844. +
  27845. + /* Now set the MMDC PODF back to 1.*/
  27846. + ldr r6, [r2, #0x14]
  27847. + bic r6, r6, #0x38
  27848. + str r6, [r2, #0x14]
  27849. +
  27850. +mmdc_podf0:
  27851. + ldr r6, [r2, #0x48]
  27852. + cmp r6, #0
  27853. + bne mmdc_podf0
  27854. +
  27855. + .endm
  27856. +
  27857. + .macro ddr_switch_400MHz
  27858. +
  27859. + /* Set MMDC divider first, in case PLL3 is at 480MHz. */
  27860. + ldr r6, [r3, #0x10]
  27861. + and r6, r6, #0x10000
  27862. + cmp r6, #0x10000
  27863. + beq pll3_in_bypass
  27864. +
  27865. + /* Set MMDC divder to divide by 2. */
  27866. + ldr r6, [r2, #0x14]
  27867. + bic r6, r6, #0x38
  27868. + orr r6, r6, #0x8
  27869. + str r6, [r2, #0x14]
  27870. +
  27871. +mmdc_podf:
  27872. + ldr r6, [r2, #0x48]
  27873. + cmp r6, #0
  27874. + bne mmdc_podf
  27875. +
  27876. +pll3_in_bypass:
  27877. + /*
  27878. + * Check if we are switching between
  27879. + * 400Mhz <-> 100MHz.If so, we should
  27880. + * try to source MMDC from PLL2_200M.
  27881. + */
  27882. + cmp r1, #0
  27883. + beq not_low_bus_freq
  27884. +
  27885. + /* Ensure that MMDC is sourced from PLL2 mux first. */
  27886. + ldr r6, [r2, #0x14]
  27887. + bic r6, r6, #0x4000000
  27888. + str r6, [r2, #0x14]
  27889. +
  27890. +periph2_clk_switch4:
  27891. + ldr r6, [r2, #0x48]
  27892. + cmp r6, #0
  27893. + bne periph2_clk_switch4
  27894. +
  27895. +not_low_bus_freq:
  27896. + /* Now ensure periph2_clk2_sel mux is set to PLL3 */
  27897. + ldr r6, [r2, #0x18]
  27898. + bic r6, r6, #0x100000
  27899. + str r6, [r2, #0x18]
  27900. +
  27901. + /* Now switch MMDC to PLL3. */
  27902. + ldr r6, [r2, #0x14]
  27903. + orr r6, r6, #0x4000000
  27904. + str r6, [r2, #0x14]
  27905. +
  27906. +periph2_clk_switch5:
  27907. + ldr r6, [r2, #0x48]
  27908. + cmp r6, #0
  27909. + bne periph2_clk_switch5
  27910. +
  27911. + /*
  27912. + * Check if PLL2 is already unlocked.
  27913. + * If so do nothing with PLL2.
  27914. + */
  27915. + cmp r1, #0
  27916. + beq pll2_already_on
  27917. +
  27918. + /* Now power up PLL2 and unbypass it. */
  27919. + ldr r6, [r3, #0x30]
  27920. + bic r6, r6, #0x1000
  27921. + str r6, [r3, #0x30]
  27922. +
  27923. + /* Make sure PLL2 has locked.*/
  27924. +wait_for_pll_lock:
  27925. + ldr r6, [r3, #0x30]
  27926. + and r6, r6, #0x80000000
  27927. + cmp r6, #0x80000000
  27928. + bne wait_for_pll_lock
  27929. +
  27930. + ldr r6, [r3, #0x30]
  27931. + bic r6, r6, #0x10000
  27932. + str r6, [r3, #0x30]
  27933. +
  27934. + /*
  27935. + * Need to enable the 528 PFDs after
  27936. + * powering up PLL2.
  27937. + * Only the PLL2_PFD2_400M should be ON
  27938. + * as it feeds the MMDC. Rest should have
  27939. + * been managed by clock code.
  27940. + */
  27941. + ldr r6, [r3, #0x100]
  27942. + bic r6, r6, #0x800000
  27943. + str r6, [r3, #0x100]
  27944. +
  27945. +pll2_already_on:
  27946. + /*
  27947. + * Now switch MMDC clk back to pll2_mux option.
  27948. + * Ensure pre_periph2_clk2 is set to pll2_pfd_400M.
  27949. + * If switching to audio DDR freq, set the
  27950. + * pre_periph2_clk2 to PLL2_PFD_200M
  27951. + */
  27952. + ldr r6, =400000000
  27953. + cmp r6, r0
  27954. + bne use_pll2_pfd_200M
  27955. +
  27956. + ldr r6, [r2, #0x18]
  27957. + bic r6, r6, #0x600000
  27958. + orr r6, r6, #0x200000
  27959. + str r6, [r2, #0x18]
  27960. + ldr r6, =400000000
  27961. + b cont2
  27962. +
  27963. +use_pll2_pfd_200M:
  27964. + ldr r6, [r2, #0x18]
  27965. + orr r6, r6, #0x600000
  27966. + str r6, [r2, #0x18]
  27967. + ldr r6, =200000000
  27968. +
  27969. +cont2:
  27970. + ldr r4, [r2, #0x14]
  27971. + bic r4, r4, #0x4000000
  27972. + str r4, [r2, #0x14]
  27973. +
  27974. +periph2_clk_switch6:
  27975. + ldr r4, [r2, #0x48]
  27976. + cmp r4, #0
  27977. + bne periph2_clk_switch6
  27978. +
  27979. +change_divider_only:
  27980. + /*
  27981. + * Calculate the MMDC divider
  27982. + * based on the requested freq.
  27983. + */
  27984. + ldr r4, =0
  27985. +Loop2:
  27986. + sub r6, r6, r0
  27987. + cmp r6, r0
  27988. + blt Div_Found
  27989. + add r4, r4, #1
  27990. + bgt Loop2
  27991. +
  27992. + /* Shift divider into correct offset. */
  27993. + lsl r4, r4, #3
  27994. +Div_Found:
  27995. + /* Set the MMDC PODF. */
  27996. + ldr r6, [r2, #0x14]
  27997. + bic r6, r6, #0x38
  27998. + orr r6, r6, r4
  27999. + str r6, [r2, #0x14]
  28000. +
  28001. +mmdc_podf1:
  28002. + ldr r6, [r2, #0x48]
  28003. + cmp r6, #0
  28004. + bne mmdc_podf1
  28005. +
  28006. + .endm
  28007. +
  28008. + .macro mmdc_clk_lower_100MHz
  28009. +
  28010. + /*
  28011. + * Prior to reducing the DDR frequency (at 528/400 MHz),
  28012. + * read the Measure unit count bits (MU_UNIT_DEL_NUM)
  28013. + */
  28014. + ldr r5, =0x8B8
  28015. + ldr r6, [r8, r5]
  28016. + /* Original MU unit count */
  28017. + mov r6, r6, LSR #16
  28018. + ldr r4, =0x3FF
  28019. + and r6, r6, r4
  28020. + /* Original MU unit count * 2 */
  28021. + mov r7, r6, LSL #1
  28022. + /*
  28023. + * Bypass the automatic measure unit when below 100 MHz
  28024. + * by setting the Measure unit bypass enable bit (MU_BYP_EN)
  28025. + */
  28026. + ldr r6, [r8, r5]
  28027. + orr r6, r6, #0x400
  28028. + str r6, [r8, r5]
  28029. + /*
  28030. + * Double the measure count value read in step 1 and program it in the
  28031. + * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
  28032. + * Register for the reduced frequency operation below 100 MHz
  28033. + */
  28034. + ldr r6, [r8, r5]
  28035. + ldr r4, =0x3FF
  28036. + bic r6, r6, r4
  28037. + orr r6, r6, r7
  28038. + str r6, [r8, r5]
  28039. + /* Now perform a Force Measurement. */
  28040. + ldr r6, [r8, r5]
  28041. + orr r6, r6, #0x800
  28042. + str r6, [r8, r5]
  28043. + /* Wait for FRC_MSR to clear. */
  28044. +force_measure:
  28045. + ldr r6, [r8, r5]
  28046. + and r6, r6, #0x800
  28047. + cmp r6, #0x0
  28048. + bne force_measure
  28049. +
  28050. + .endm
  28051. +
  28052. + .macro mmdc_clk_above_100MHz
  28053. +
  28054. + /* Make sure that the PHY measurement unit is NOT in bypass mode */
  28055. + ldr r5, =0x8B8
  28056. + ldr r6, [r8, r5]
  28057. + bic r6, r6, #0x400
  28058. + str r6, [r8, r5]
  28059. + /* Now perform a Force Measurement. */
  28060. + ldr r6, [r8, r5]
  28061. + orr r6, r6, #0x800
  28062. + str r6, [r8, r5]
  28063. + /* Wait for FRC_MSR to clear. */
  28064. +force_measure1:
  28065. + ldr r6, [r8, r5]
  28066. + and r6, r6, #0x800
  28067. + cmp r6, #0x0
  28068. + bne force_measure1
  28069. + .endm
  28070. +
  28071. +/*
  28072. + * mx6_lpddr2_freq_change
  28073. + *
  28074. + * Make sure DDR is in self-refresh.
  28075. + * IRQs are already disabled.
  28076. + * r0 : DDR freq.
  28077. + * r1: low_bus_freq_mode flag
  28078. + * r2: Pointer to array containing addresses of registers.
  28079. + */
  28080. + .align 3
  28081. +ENTRY(mx6_lpddr2_freq_change)
  28082. +
  28083. + push {r4-r10}
  28084. +
  28085. + mov r4, r2
  28086. + ldr r3, [r4] @ANATOP_BASE_ADDR
  28087. + ldr r2, [r4, #0x4] @CCM_BASE_ADDR
  28088. + ldr r8, [r4, #0x8] @MMDC_P0_BASE_ADDR
  28089. + ldr r7, [r4, #0xC] @L2_BASE_ADDR
  28090. +
  28091. +lpddr2_freq_change:
  28092. + adr r9, lpddr2_freq_change
  28093. +
  28094. + /* Prime all TLB entries. */
  28095. + ldr r6, [r9]
  28096. + ldr r6, [r8]
  28097. + ldr r6, [r3]
  28098. + ldr r6, [r2]
  28099. +
  28100. + /* Drain all the L1 buffers. */
  28101. + dsb
  28102. +
  28103. +#ifdef CONFIG_CACHE_L2X0
  28104. + /*
  28105. + * Need to make sure the buffers in L2 are drained.
  28106. + * Performing a sync operation does this.
  28107. + */
  28108. + mov r6, #0x0
  28109. + str r6, [r7, #0x730]
  28110. +#endif
  28111. +
  28112. + /*
  28113. + * The second dsb might be needed to keep cache sync (device write)
  28114. + * ordering with the memory accesses before it.
  28115. + */
  28116. + dsb
  28117. + isb
  28118. +
  28119. + /* Disable Automatic power savings. */
  28120. + ldr r6, [r8, #0x404]
  28121. + orr r6, r6, #0x01
  28122. + str r6, [r8, #0x404]
  28123. +
  28124. + /* MMDC0_MDPDC disable power down timer */
  28125. + ldr r6, [r8, #0x4]
  28126. + bic r6, r6, #0xff00
  28127. + str r6, [r8, #0x4]
  28128. +
  28129. + /* Delay for a while */
  28130. + ldr r10, =10
  28131. +delay1:
  28132. + ldr r7, =0
  28133. +cont1:
  28134. + ldr r6, [r8, r7]
  28135. + add r7, r7, #4
  28136. + cmp r7, #16
  28137. + bne cont1
  28138. + sub r10, r10, #1
  28139. + cmp r10, #0
  28140. + bgt delay1
  28141. +
  28142. + /* Make the DDR explicitly enter self-refresh. */
  28143. + ldr r6, [r8, #0x404]
  28144. + orr r6, r6, #0x200000
  28145. + str r6, [r8, #0x404]
  28146. +
  28147. +poll_dvfs_set_1:
  28148. + ldr r6, [r8, #0x404]
  28149. + and r6, r6, #0x2000000
  28150. + cmp r6, #0x2000000
  28151. + bne poll_dvfs_set_1
  28152. +
  28153. + /* set SBS step-by-step mode */
  28154. + ldr r6, [r8, #0x410]
  28155. + orr r6, r6, #0x100
  28156. + str r6, [r8, #0x410]
  28157. +
  28158. + ldr r10, =100000000
  28159. + cmp r0, r10
  28160. + bgt set_ddr_mu_above_100
  28161. + mmdc_clk_lower_100MHz
  28162. +
  28163. +set_ddr_mu_above_100:
  28164. + ldr r10, =24000000
  28165. + cmp r0, r10
  28166. + beq set_to_24MHz
  28167. +
  28168. + ddr_switch_400MHz
  28169. +
  28170. + ldr r10,=100000000
  28171. + cmp r0, r10
  28172. + blt done
  28173. + mmdc_clk_above_100MHz
  28174. +
  28175. + b done
  28176. +
  28177. +set_to_24MHz:
  28178. + mx6sl_switch_to_24MHz
  28179. +
  28180. +done:
  28181. + /* clear DVFS - exit from self refresh mode */
  28182. + ldr r6, [r8, #0x404]
  28183. + bic r6, r6, #0x200000
  28184. + str r6, [r8, #0x404]
  28185. +
  28186. +poll_dvfs_clear_1:
  28187. + ldr r6, [r8, #0x404]
  28188. + and r6, r6, #0x2000000
  28189. + cmp r6, #0x2000000
  28190. + beq poll_dvfs_clear_1
  28191. +
  28192. + /* Enable Automatic power savings. */
  28193. + ldr r6, [r8, #0x404]
  28194. + bic r6, r6, #0x01
  28195. + str r6, [r8, #0x404]
  28196. +
  28197. + ldr r10, =24000000
  28198. + cmp r0, r10
  28199. + beq skip_power_down
  28200. +
  28201. + /* Enable MMDC power down timer. */
  28202. + ldr r6, [r8, #0x4]
  28203. + orr r6, r6, #0x5500
  28204. + str r6, [r8, #0x4]
  28205. +
  28206. +skip_power_down:
  28207. + /* clear SBS - unblock DDR accesses */
  28208. + ldr r6, [r8, #0x410]
  28209. + bic r6, r6, #0x100
  28210. + str r6, [r8, #0x410]
  28211. +
  28212. + pop {r4-r10}
  28213. +
  28214. + /* Restore registers */
  28215. + mov pc, lr
  28216. +
  28217. + .type mx6_lpddr2_do_iram, #object
  28218. +ENTRY(mx6_lpddr2_do_iram)
  28219. + .word mx6_lpddr2_freq_change
  28220. + .size mx6_lpddr2_freq_change, . - mx6_lpddr2_freq_change
  28221. diff -Nur linux-3.14.17/arch/arm/mach-imx/mach-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/mach-imx6q.c
  28222. --- linux-3.14.17/arch/arm/mach-imx/mach-imx6q.c 2014-08-14 03:38:34.000000000 +0200
  28223. +++ linux-imx6-3.14/arch/arm/mach-imx/mach-imx6q.c 2014-09-11 18:05:53.382003527 +0200
  28224. @@ -1,5 +1,5 @@
  28225. /*
  28226. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  28227. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  28228. * Copyright 2011 Linaro Ltd.
  28229. *
  28230. * The code contained herein is licensed under the GNU General Public
  28231. @@ -15,6 +15,7 @@
  28232. #include <linux/cpu.h>
  28233. #include <linux/delay.h>
  28234. #include <linux/export.h>
  28235. +#include <linux/gpio.h>
  28236. #include <linux/init.h>
  28237. #include <linux/io.h>
  28238. #include <linux/irq.h>
  28239. @@ -22,15 +23,18 @@
  28240. #include <linux/of.h>
  28241. #include <linux/of_address.h>
  28242. #include <linux/of_irq.h>
  28243. +#include <linux/of_gpio.h>
  28244. #include <linux/of_platform.h>
  28245. #include <linux/pm_opp.h>
  28246. #include <linux/pci.h>
  28247. #include <linux/phy.h>
  28248. +#include <linux/pm_opp.h>
  28249. #include <linux/reboot.h>
  28250. #include <linux/regmap.h>
  28251. #include <linux/micrel_phy.h>
  28252. #include <linux/mfd/syscon.h>
  28253. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28254. +#include <linux/of_net.h>
  28255. #include <asm/mach/arch.h>
  28256. #include <asm/mach/map.h>
  28257. #include <asm/system_misc.h>
  28258. @@ -194,6 +198,101 @@
  28259. }
  28260. +static void __init imx6q_csi_mux_init(void)
  28261. +{
  28262. + /*
  28263. + * MX6Q SabreSD board:
  28264. + * IPU1 CSI0 connects to parallel interface.
  28265. + * Set GPR1 bit 19 to 0x1.
  28266. + *
  28267. + * MX6DL SabreSD board:
  28268. + * IPU1 CSI0 connects to parallel interface.
  28269. + * Set GPR13 bit 0-2 to 0x4.
  28270. + * IPU1 CSI1 connects to MIPI CSI2 virtual channel 1.
  28271. + * Set GPR13 bit 3-5 to 0x1.
  28272. + */
  28273. + struct regmap *gpr;
  28274. +
  28275. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28276. + if (!IS_ERR(gpr)) {
  28277. + if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
  28278. + of_machine_is_compatible("fsl,imx6q-sabreauto"))
  28279. + regmap_update_bits(gpr, IOMUXC_GPR1, 1 << 19, 1 << 19);
  28280. + else if (of_machine_is_compatible("fsl,imx6dl-sabresd") ||
  28281. + of_machine_is_compatible("fsl,imx6dl-sabreauto"))
  28282. + regmap_update_bits(gpr, IOMUXC_GPR13, 0x3F, 0x0C);
  28283. + } else {
  28284. + pr_err("%s(): failed to find fsl,imx6q-iomux-gpr regmap\n",
  28285. + __func__);
  28286. + }
  28287. +}
  28288. +
  28289. +#define OCOTP_MACn(n) (0x00000620 + (n) * 0x10)
  28290. +void __init imx6_enet_mac_init(const char *compatible)
  28291. +{
  28292. + struct device_node *ocotp_np, *enet_np;
  28293. + void __iomem *base;
  28294. + struct property *newmac;
  28295. + u32 macaddr_low, macaddr_high;
  28296. + u8 *macaddr;
  28297. +
  28298. + enet_np = of_find_compatible_node(NULL, NULL, compatible);
  28299. + if (!enet_np)
  28300. + return;
  28301. +
  28302. + if (of_get_mac_address(enet_np))
  28303. + goto put_enet_node;
  28304. +
  28305. + ocotp_np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
  28306. + if (!ocotp_np) {
  28307. + pr_warn("failed to find ocotp node\n");
  28308. + goto put_enet_node;
  28309. + }
  28310. +
  28311. + base = of_iomap(ocotp_np, 0);
  28312. + if (!base) {
  28313. + pr_warn("failed to map ocotp\n");
  28314. + goto put_ocotp_node;
  28315. + }
  28316. +
  28317. + macaddr_high = readl_relaxed(base + OCOTP_MACn(0));
  28318. + macaddr_low = readl_relaxed(base + OCOTP_MACn(1));
  28319. +
  28320. + newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
  28321. + if (!newmac)
  28322. + goto put_ocotp_node;
  28323. +
  28324. + newmac->value = newmac + 1;
  28325. + newmac->length = 6;
  28326. + newmac->name = kstrdup("local-mac-address", GFP_KERNEL);
  28327. + if (!newmac->name) {
  28328. + kfree(newmac);
  28329. + goto put_ocotp_node;
  28330. + }
  28331. +
  28332. + macaddr = newmac->value;
  28333. + macaddr[5] = macaddr_high & 0xff;
  28334. + macaddr[4] = (macaddr_high >> 8) & 0xff;
  28335. + macaddr[3] = (macaddr_high >> 16) & 0xff;
  28336. + macaddr[2] = (macaddr_high >> 24) & 0xff;
  28337. + macaddr[1] = macaddr_low & 0xff;
  28338. + macaddr[0] = (macaddr_low >> 8) & 0xff;
  28339. +
  28340. + of_update_property(enet_np, newmac);
  28341. +
  28342. +put_ocotp_node:
  28343. + of_node_put(ocotp_np);
  28344. +put_enet_node:
  28345. + of_node_put(enet_np);
  28346. +}
  28347. +
  28348. +static inline void imx6q_enet_init(void)
  28349. +{
  28350. + imx6_enet_mac_init("fsl,imx6q-fec");
  28351. + imx6q_enet_phy_init();
  28352. + imx6q_1588_init();
  28353. +}
  28354. +
  28355. static void __init imx6q_init_machine(void)
  28356. {
  28357. struct device *parent;
  28358. @@ -207,20 +306,22 @@
  28359. if (parent == NULL)
  28360. pr_warn("failed to initialize soc device\n");
  28361. - imx6q_enet_phy_init();
  28362. -
  28363. of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
  28364. + imx6q_enet_init();
  28365. imx_anatop_init();
  28366. - imx6q_pm_init();
  28367. - imx6q_1588_init();
  28368. + cpu_is_imx6q() ? imx6q_pm_init() : imx6dl_pm_init();
  28369. + imx6q_csi_mux_init();
  28370. }
  28371. #define OCOTP_CFG3 0x440
  28372. #define OCOTP_CFG3_SPEED_SHIFT 16
  28373. #define OCOTP_CFG3_SPEED_1P2GHZ 0x3
  28374. +#define OCOTP_CFG3_SPEED_1GHZ 0x2
  28375. +#define OCOTP_CFG3_SPEED_850MHZ 0x1
  28376. +#define OCOTP_CFG3_SPEED_800MHZ 0x0
  28377. -static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
  28378. +static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
  28379. {
  28380. struct device_node *np;
  28381. void __iomem *base;
  28382. @@ -238,11 +339,31 @@
  28383. goto put_node;
  28384. }
  28385. + /*
  28386. + * SPEED_GRADING[1:0] defines the max speed of ARM:
  28387. + * 2b'11: 1200000000Hz; -- i.MX6Q only.
  28388. + * 2b'10: 1000000000Hz;
  28389. + * 2b'01: 850000000Hz; -- i.MX6Q Only, exclusive with 1GHz.
  28390. + * 2b'00: 800000000Hz;
  28391. + * We need to set the max speed of ARM according to fuse map.
  28392. + */
  28393. +
  28394. val = readl_relaxed(base + OCOTP_CFG3);
  28395. val >>= OCOTP_CFG3_SPEED_SHIFT;
  28396. - if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
  28397. - if (dev_pm_opp_disable(cpu_dev, 1200000000))
  28398. - pr_warn("failed to disable 1.2 GHz OPP\n");
  28399. + if (cpu_is_imx6q()) {
  28400. + if ((val & 0x3) < OCOTP_CFG3_SPEED_1P2GHZ)
  28401. + if (dev_pm_opp_disable(cpu_dev, 1200000000))
  28402. + pr_warn("failed to disable 1.2 GHz OPP\n");
  28403. + }
  28404. + if ((val & 0x3) < OCOTP_CFG3_SPEED_1GHZ)
  28405. + if (dev_pm_opp_disable(cpu_dev, 996000000))
  28406. + pr_warn("failed to disable 1 GHz OPP\n");
  28407. + if (cpu_is_imx6q()) {
  28408. + if ((val & 0x3) < OCOTP_CFG3_SPEED_850MHZ ||
  28409. + (val & 0x3) == OCOTP_CFG3_SPEED_1GHZ)
  28410. + if (dev_pm_opp_disable(cpu_dev, 852000000))
  28411. + pr_warn("failed to disable 850 MHz OPP\n");
  28412. + }
  28413. put_node:
  28414. of_node_put(np);
  28415. @@ -268,29 +389,70 @@
  28416. goto put_node;
  28417. }
  28418. - imx6q_opp_check_1p2ghz(cpu_dev);
  28419. + imx6q_opp_check_speed_grading(cpu_dev);
  28420. put_node:
  28421. of_node_put(np);
  28422. }
  28423. +#define ESAI_AUDIO_MCLK 24576000
  28424. +
  28425. +static void __init imx6q_audio_lvds2_init(void)
  28426. +{
  28427. + struct clk *pll4_sel, *lvds2_in, *pll4_audio_div, *esai;
  28428. +
  28429. + pll4_audio_div = clk_get_sys(NULL, "pll4_audio_div");
  28430. + pll4_sel = clk_get_sys(NULL, "pll4_sel");
  28431. + lvds2_in = clk_get_sys(NULL, "lvds2_in");
  28432. + esai = clk_get_sys(NULL, "esai");
  28433. + if (IS_ERR(pll4_audio_div) || IS_ERR(pll4_sel) ||
  28434. + IS_ERR(lvds2_in) || IS_ERR(esai))
  28435. + return;
  28436. +
  28437. + if (clk_get_rate(lvds2_in) != ESAI_AUDIO_MCLK)
  28438. + return;
  28439. +
  28440. + clk_set_parent(pll4_sel, lvds2_in);
  28441. + clk_set_rate(pll4_audio_div, 786432000);
  28442. + clk_set_rate(esai, ESAI_AUDIO_MCLK);
  28443. +}
  28444. +
  28445. static struct platform_device imx6q_cpufreq_pdev = {
  28446. - .name = "imx6q-cpufreq",
  28447. + .name = "imx6-cpufreq",
  28448. };
  28449. static void __init imx6q_init_late(void)
  28450. {
  28451. + struct regmap *gpr;
  28452. +
  28453. + /*
  28454. + * Need to force IOMUXC irq pending to meet CCM low power mode
  28455. + * restriction, this is recommended by hardware team.
  28456. + */
  28457. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28458. + if (!IS_ERR(gpr))
  28459. + regmap_update_bits(gpr, IOMUXC_GPR1,
  28460. + IMX6Q_GPR1_GINT_MASK,
  28461. + IMX6Q_GPR1_GINT_ASSERT);
  28462. +
  28463. /*
  28464. * WAIT mode is broken on TO 1.0 and 1.1, so there is no point
  28465. * to run cpuidle on them.
  28466. */
  28467. - if (imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
  28468. + if ((cpu_is_imx6q() && imx_get_soc_revision() > IMX_CHIP_REVISION_1_1)
  28469. + || (cpu_is_imx6dl() && imx_get_soc_revision() >
  28470. + IMX_CHIP_REVISION_1_0))
  28471. imx6q_cpuidle_init();
  28472. - if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
  28473. + if (IS_ENABLED(CONFIG_ARM_IMX6_CPUFREQ)) {
  28474. imx6q_opp_init();
  28475. platform_device_register(&imx6q_cpufreq_pdev);
  28476. }
  28477. +
  28478. + if (of_machine_is_compatible("fsl,imx6q-sabreauto")
  28479. + || of_machine_is_compatible("fsl,imx6dl-sabreauto")) {
  28480. + imx6q_audio_lvds2_init();
  28481. + }
  28482. }
  28483. static void __init imx6q_map_io(void)
  28484. @@ -315,6 +477,12 @@
  28485. };
  28486. DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)")
  28487. + /*
  28488. + * i.MX6Q/DL maps system memory at 0x10000000 (offset 256MiB), and
  28489. + * GPU has a limit on physical address that it accesses, which must
  28490. + * be below 2GiB.
  28491. + */
  28492. + .dma_zone_size = (SZ_2G - SZ_256M),
  28493. .smp = smp_ops(imx_smp_ops),
  28494. .map_io = imx6q_map_io,
  28495. .init_irq = imx6q_init_irq,
  28496. diff -Nur linux-3.14.17/arch/arm/mach-imx/mach-imx6sl.c linux-imx6-3.14/arch/arm/mach-imx/mach-imx6sl.c
  28497. --- linux-3.14.17/arch/arm/mach-imx/mach-imx6sl.c 2014-08-14 03:38:34.000000000 +0200
  28498. +++ linux-imx6-3.14/arch/arm/mach-imx/mach-imx6sl.c 2014-09-11 18:05:53.382003527 +0200
  28499. @@ -17,8 +17,9 @@
  28500. #include <asm/mach/map.h>
  28501. #include "common.h"
  28502. +#include "cpuidle.h"
  28503. -static void __init imx6sl_fec_init(void)
  28504. +static void __init imx6sl_fec_clk_init(void)
  28505. {
  28506. struct regmap *gpr;
  28507. @@ -34,8 +35,17 @@
  28508. }
  28509. }
  28510. +static inline void imx6sl_fec_init(void)
  28511. +{
  28512. + imx6sl_fec_clk_init();
  28513. + imx6_enet_mac_init("fsl,imx6sl-fec");
  28514. +}
  28515. +
  28516. static void __init imx6sl_init_late(void)
  28517. {
  28518. + /* Init CPUIDLE */
  28519. + imx6sl_cpuidle_init();
  28520. +
  28521. /* imx6sl reuses imx6q cpufreq driver */
  28522. if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
  28523. platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
  28524. @@ -55,8 +65,7 @@
  28525. imx6sl_fec_init();
  28526. imx_anatop_init();
  28527. - /* Reuse imx6q pm code */
  28528. - imx6q_pm_init();
  28529. + imx6sl_pm_init();
  28530. }
  28531. static void __init imx6sl_init_irq(void)
  28532. diff -Nur linux-3.14.17/arch/arm/mach-imx/mach-vf610.c linux-imx6-3.14/arch/arm/mach-imx/mach-vf610.c
  28533. --- linux-3.14.17/arch/arm/mach-imx/mach-vf610.c 2014-08-14 03:38:34.000000000 +0200
  28534. +++ linux-imx6-3.14/arch/arm/mach-imx/mach-vf610.c 2014-09-11 18:05:53.386003542 +0200
  28535. @@ -22,7 +22,7 @@
  28536. static void __init vf610_init_irq(void)
  28537. {
  28538. - l2x0_of_init(0, ~0UL);
  28539. + l2x0_of_init(0, ~0);
  28540. irqchip_init();
  28541. }
  28542. diff -Nur linux-3.14.17/arch/arm/mach-imx/Makefile linux-imx6-3.14/arch/arm/mach-imx/Makefile
  28543. --- linux-3.14.17/arch/arm/mach-imx/Makefile 2014-08-14 03:38:34.000000000 +0200
  28544. +++ linux-imx6-3.14/arch/arm/mach-imx/Makefile 2014-09-11 18:05:53.278003110 +0200
  28545. @@ -30,6 +30,7 @@
  28546. ifeq ($(CONFIG_CPU_IDLE),y)
  28547. obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
  28548. obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
  28549. +obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
  28550. endif
  28551. ifdef CONFIG_SND_IMX_SOC
  28552. @@ -101,9 +102,18 @@
  28553. obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
  28554. obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
  28555. -obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
  28556. -# i.MX6SL reuses i.MX6Q code
  28557. -obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o
  28558. +AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
  28559. +obj-$(CONFIG_PM) += suspend-imx6.o pm-imx6.o headsmp.o
  28560. +
  28561. +obj-y += busfreq-imx6.o
  28562. +ifeq ($(CONFIG_ARM_IMX6_CPUFREQ),y)
  28563. +obj-$(CONFIG_SOC_IMX6Q) += ddr3_freq_imx6.o busfreq_ddr3.o
  28564. +obj-$(CONFIG_SOC_IMX6SL) += lpddr2_freq_imx6.o busfreq_lpddr2.o
  28565. +endif
  28566. +ifeq ($(CONFIG_CPU_IDLE), y)
  28567. +obj-$(CONFIG_SOC_IMX6SL) += imx6sl_wfi.o
  28568. +endif
  28569. +
  28570. # i.MX5 based machines
  28571. obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o
  28572. diff -Nur linux-3.14.17/arch/arm/mach-imx/mx6.h linux-imx6-3.14/arch/arm/mach-imx/mx6.h
  28573. --- linux-3.14.17/arch/arm/mach-imx/mx6.h 1970-01-01 01:00:00.000000000 +0100
  28574. +++ linux-imx6-3.14/arch/arm/mach-imx/mx6.h 2014-09-11 18:05:53.394003573 +0200
  28575. @@ -0,0 +1,35 @@
  28576. +/*
  28577. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  28578. + */
  28579. +
  28580. +/*
  28581. + * This program is free software; you can redistribute it and/or modify
  28582. + * it under the terms of the GNU General Public License version 2 as
  28583. + * published by the Free Software Foundation.
  28584. + */
  28585. +
  28586. +#ifndef __ASM_ARCH_MXC_IOMAP_H__
  28587. +#define __ASM_ARCH_MXC_IOMAP_H__
  28588. +
  28589. +#define MX6Q_IO_P2V(x) IMX_IO_P2V(x)
  28590. +#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x))
  28591. +
  28592. +#define MX6Q_L2_BASE_ADDR 0x00a02000
  28593. +#define MX6Q_L2_SIZE 0x1000
  28594. +#define MX6Q_IOMUXC_BASE_ADDR 0x020e0000
  28595. +#define MX6Q_IOMUXC_SIZE 0x4000
  28596. +#define MX6Q_SRC_BASE_ADDR 0x020d8000
  28597. +#define MX6Q_SRC_SIZE 0x4000
  28598. +#define MX6Q_CCM_BASE_ADDR 0x020c4000
  28599. +#define MX6Q_CCM_SIZE 0x4000
  28600. +#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
  28601. +#define MX6Q_ANATOP_SIZE 0x1000
  28602. +#define MX6Q_GPC_BASE_ADDR 0x020dc000
  28603. +#define MX6Q_GPC_SIZE 0x4000
  28604. +#define MX6Q_MMDC_P0_BASE_ADDR 0x021b0000
  28605. +#define MX6Q_MMDC_P0_SIZE 0x4000
  28606. +#define MX6Q_MMDC_P1_BASE_ADDR 0x021b4000
  28607. +#define MX6Q_MMDC_P1_SIZE 0x4000
  28608. +
  28609. +#define MX6_SUSPEND_IRAM_SIZE 0x1000
  28610. +#endif
  28611. diff -Nur linux-3.14.17/arch/arm/mach-imx/mxc.h linux-imx6-3.14/arch/arm/mach-imx/mxc.h
  28612. --- linux-3.14.17/arch/arm/mach-imx/mxc.h 2014-08-14 03:38:34.000000000 +0200
  28613. +++ linux-imx6-3.14/arch/arm/mach-imx/mxc.h 2014-09-11 18:05:53.394003573 +0200
  28614. @@ -42,6 +42,8 @@
  28615. #define IMX_CHIP_REVISION_1_1 0x11
  28616. #define IMX_CHIP_REVISION_1_2 0x12
  28617. #define IMX_CHIP_REVISION_1_3 0x13
  28618. +#define IMX_CHIP_REVISION_1_4 0x14
  28619. +#define IMX_CHIP_REVISION_1_5 0x15
  28620. #define IMX_CHIP_REVISION_2_0 0x20
  28621. #define IMX_CHIP_REVISION_2_1 0x21
  28622. #define IMX_CHIP_REVISION_2_2 0x22
  28623. @@ -177,6 +179,7 @@
  28624. extern struct cpu_op *(*get_cpu_op)(int *op);
  28625. #endif
  28626. +#define cpu_is_imx6() (cpu_is_imx6q() || cpu_is_imx6dl() || cpu_is_imx6sl())
  28627. #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35())
  28628. #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
  28629. diff -Nur linux-3.14.17/arch/arm/mach-imx/pm-imx6.c linux-imx6-3.14/arch/arm/mach-imx/pm-imx6.c
  28630. --- linux-3.14.17/arch/arm/mach-imx/pm-imx6.c 1970-01-01 01:00:00.000000000 +0100
  28631. +++ linux-imx6-3.14/arch/arm/mach-imx/pm-imx6.c 2014-09-11 18:05:53.394003573 +0200
  28632. @@ -0,0 +1,580 @@
  28633. +/*
  28634. + * Copyright 2011-2014 Freescale Semiconductor, Inc.
  28635. + * Copyright 2011 Linaro Ltd.
  28636. + *
  28637. + * The code contained herein is licensed under the GNU General Public
  28638. + * License. You may obtain a copy of the GNU General Public License
  28639. + * Version 2 or later at the following locations:
  28640. + *
  28641. + * http://www.opensource.org/licenses/gpl-license.html
  28642. + * http://www.gnu.org/copyleft/gpl.html
  28643. + */
  28644. +
  28645. +#include <linux/delay.h>
  28646. +#include <linux/init.h>
  28647. +#include <linux/io.h>
  28648. +#include <linux/irq.h>
  28649. +#include <linux/genalloc.h>
  28650. +#include <linux/mfd/syscon.h>
  28651. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28652. +#include <linux/of.h>
  28653. +#include <linux/of_address.h>
  28654. +#include <linux/of_platform.h>
  28655. +#include <linux/regmap.h>
  28656. +#include <linux/suspend.h>
  28657. +#include <linux/regmap.h>
  28658. +#include <linux/mfd/syscon.h>
  28659. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  28660. +#include <asm/cacheflush.h>
  28661. +#include <asm/fncpy.h>
  28662. +#include <asm/proc-fns.h>
  28663. +#include <asm/suspend.h>
  28664. +#include <asm/tlb.h>
  28665. +
  28666. +#include "common.h"
  28667. +#include "hardware.h"
  28668. +
  28669. +#define CCR 0x0
  28670. +#define BM_CCR_WB_COUNT (0x7 << 16)
  28671. +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
  28672. +#define BM_CCR_RBC_EN (0x1 << 27)
  28673. +
  28674. +#define CLPCR 0x54
  28675. +#define BP_CLPCR_LPM 0
  28676. +#define BM_CLPCR_LPM (0x3 << 0)
  28677. +#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
  28678. +#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
  28679. +#define BM_CLPCR_SBYOS (0x1 << 6)
  28680. +#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
  28681. +#define BM_CLPCR_VSTBY (0x1 << 8)
  28682. +#define BP_CLPCR_STBY_COUNT 9
  28683. +#define BM_CLPCR_STBY_COUNT (0x3 << 9)
  28684. +#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
  28685. +#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
  28686. +#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
  28687. +#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
  28688. +#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
  28689. +#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
  28690. +#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
  28691. +#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
  28692. +#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
  28693. +#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
  28694. +#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
  28695. +
  28696. +#define CGPR 0x64
  28697. +#define BM_CGPR_INT_MEM_CLK_LPM (0x1 << 17)
  28698. +
  28699. +#define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
  28700. +#define MX6_MAX_MMDC_IO_NUM 33
  28701. +
  28702. +static void __iomem *ccm_base;
  28703. +static void __iomem *suspend_ocram_base;
  28704. +static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
  28705. +
  28706. +/*
  28707. + * suspend ocram space layout:
  28708. + * ======================== high address ======================
  28709. + * .
  28710. + * .
  28711. + * .
  28712. + * ^
  28713. + * ^
  28714. + * ^
  28715. + * imx6_suspend code
  28716. + * PM_INFO structure(imx6_cpu_pm_info)
  28717. + * ======================== low address =======================
  28718. + */
  28719. +
  28720. +struct imx6_pm_base {
  28721. + phys_addr_t pbase;
  28722. + void __iomem *vbase;
  28723. +};
  28724. +
  28725. +struct imx6_pm_socdata {
  28726. + u32 cpu_type;
  28727. + const char *mmdc_compat;
  28728. + const char *src_compat;
  28729. + const char *iomuxc_compat;
  28730. + const char *gpc_compat;
  28731. + const u32 mmdc_io_num;
  28732. + const u32 *mmdc_io_offset;
  28733. +};
  28734. +
  28735. +static const u32 imx6q_mmdc_io_offset[] __initconst = {
  28736. + 0x5ac, 0x5b4, 0x528, 0x520, /* DQM0 ~ DQM3 */
  28737. + 0x514, 0x510, 0x5bc, 0x5c4, /* DQM4 ~ DQM7 */
  28738. + 0x56c, 0x578, 0x588, 0x594, /* CAS, RAS, SDCLK_0, SDCLK_1 */
  28739. + 0x5a8, 0x5b0, 0x524, 0x51c, /* SDQS0 ~ SDQS3 */
  28740. + 0x518, 0x50c, 0x5b8, 0x5c0, /* SDQS4 ~ SDQS7 */
  28741. + 0x784, 0x788, 0x794, 0x79c, /* GPR_B0DS ~ GPR_B3DS */
  28742. + 0x7a0, 0x7a4, 0x7a8, 0x748, /* GPR_B4DS ~ GPR_B7DS */
  28743. + 0x59c, 0x5a0, 0x750, 0x774, /* SODT0, SODT1, MODE_CTL, MODE */
  28744. + 0x74c, /* GPR_ADDS */
  28745. +};
  28746. +
  28747. +static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
  28748. + .cpu_type = MXC_CPU_IMX6Q,
  28749. + .mmdc_compat = "fsl,imx6q-mmdc",
  28750. + .src_compat = "fsl,imx6q-src",
  28751. + .iomuxc_compat = "fsl,imx6q-iomuxc",
  28752. + .gpc_compat = "fsl,imx6q-gpc",
  28753. + .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
  28754. + .mmdc_io_offset = imx6q_mmdc_io_offset,
  28755. +};
  28756. +
  28757. +/*
  28758. + * This structure is for passing necessary data for low level ocram
  28759. + * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
  28760. + * definition is changed, the offset definition in
  28761. + * arch/arm/mach-imx/suspend-imx6.S must be also changed accordingly,
  28762. + * otherwise, the suspend to ocram function will be broken!
  28763. + */
  28764. +struct imx6_cpu_pm_info {
  28765. + phys_addr_t pbase; /* The physical address of pm_info. */
  28766. + phys_addr_t resume_addr; /* The physical resume address for asm code */
  28767. + u32 cpu_type;
  28768. + u32 pm_info_size; /* Size of pm_info. */
  28769. + struct imx6_pm_base mmdc_base;
  28770. + struct imx6_pm_base src_base;
  28771. + struct imx6_pm_base iomuxc_base;
  28772. + struct imx6_pm_base ccm_base;
  28773. + struct imx6_pm_base gpc_base;
  28774. + struct imx6_pm_base l2_base;
  28775. + u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
  28776. + u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
  28777. +} __aligned(8);
  28778. +
  28779. +void imx6q_set_cache_lpm_in_wait(bool enable)
  28780. +{
  28781. + if ((cpu_is_imx6q() && imx_get_soc_revision() >
  28782. + IMX_CHIP_REVISION_1_1) ||
  28783. + (cpu_is_imx6dl() && imx_get_soc_revision() >
  28784. + IMX_CHIP_REVISION_1_0)) {
  28785. + u32 val;
  28786. +
  28787. + val = readl_relaxed(ccm_base + CGPR);
  28788. + if (enable)
  28789. + val |= BM_CGPR_INT_MEM_CLK_LPM;
  28790. + else
  28791. + val &= ~BM_CGPR_INT_MEM_CLK_LPM;
  28792. + writel_relaxed(val, ccm_base + CGPR);
  28793. + }
  28794. +}
  28795. +
  28796. +static void imx6q_enable_rbc(bool enable)
  28797. +{
  28798. + u32 val;
  28799. +
  28800. + /*
  28801. + * need to mask all interrupts in GPC before
  28802. + * operating RBC configurations
  28803. + */
  28804. + imx_gpc_mask_all();
  28805. +
  28806. + /* configure RBC enable bit */
  28807. + val = readl_relaxed(ccm_base + CCR);
  28808. + val &= ~BM_CCR_RBC_EN;
  28809. + val |= enable ? BM_CCR_RBC_EN : 0;
  28810. + writel_relaxed(val, ccm_base + CCR);
  28811. +
  28812. + /* configure RBC count */
  28813. + val = readl_relaxed(ccm_base + CCR);
  28814. + val &= ~BM_CCR_RBC_BYPASS_COUNT;
  28815. + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
  28816. + writel(val, ccm_base + CCR);
  28817. +
  28818. + /*
  28819. + * need to delay at least 2 cycles of CKIL(32K)
  28820. + * due to hardware design requirement, which is
  28821. + * ~61us, here we use 65us for safe
  28822. + */
  28823. + udelay(65);
  28824. +
  28825. + /* restore GPC interrupt mask settings */
  28826. + imx_gpc_restore_all();
  28827. +}
  28828. +
  28829. +static void imx6q_enable_wb(bool enable)
  28830. +{
  28831. + u32 val;
  28832. +
  28833. + /* configure well bias enable bit */
  28834. + val = readl_relaxed(ccm_base + CLPCR);
  28835. + val &= ~BM_CLPCR_WB_PER_AT_LPM;
  28836. + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
  28837. + writel_relaxed(val, ccm_base + CLPCR);
  28838. +
  28839. + /* configure well bias count */
  28840. + val = readl_relaxed(ccm_base + CCR);
  28841. + val &= ~BM_CCR_WB_COUNT;
  28842. + val |= enable ? BM_CCR_WB_COUNT : 0;
  28843. + writel_relaxed(val, ccm_base + CCR);
  28844. +}
  28845. +
  28846. +int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
  28847. +{
  28848. + struct irq_desc *iomuxc_irq_desc;
  28849. + u32 val = readl_relaxed(ccm_base + CLPCR);
  28850. +
  28851. + val &= ~BM_CLPCR_LPM;
  28852. + switch (mode) {
  28853. + case WAIT_CLOCKED:
  28854. + break;
  28855. + case WAIT_UNCLOCKED:
  28856. + val |= 0x1 << BP_CLPCR_LPM;
  28857. + val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
  28858. + val &= ~BM_CLPCR_VSTBY;
  28859. + val &= ~BM_CLPCR_SBYOS;
  28860. + if (cpu_is_imx6sl())
  28861. + val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  28862. + else
  28863. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28864. + break;
  28865. + case STOP_POWER_ON:
  28866. + val |= 0x2 << BP_CLPCR_LPM;
  28867. + val &= ~BM_CLPCR_VSTBY;
  28868. + val &= ~BM_CLPCR_SBYOS;
  28869. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28870. + break;
  28871. + case WAIT_UNCLOCKED_POWER_OFF:
  28872. + val |= 0x1 << BP_CLPCR_LPM;
  28873. + val &= ~BM_CLPCR_VSTBY;
  28874. + val &= ~BM_CLPCR_SBYOS;
  28875. + break;
  28876. + case STOP_POWER_OFF:
  28877. + val |= 0x2 << BP_CLPCR_LPM;
  28878. + val |= 0x3 << BP_CLPCR_STBY_COUNT;
  28879. + val |= BM_CLPCR_VSTBY;
  28880. + val |= BM_CLPCR_SBYOS;
  28881. + if (cpu_is_imx6sl()) {
  28882. + val |= BM_CLPCR_BYPASS_PMIC_READY;
  28883. + val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  28884. + } else {
  28885. + val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  28886. + }
  28887. + break;
  28888. + default:
  28889. + return -EINVAL;
  28890. + }
  28891. +
  28892. + /*
  28893. + * ERR007265: CCM: When improper low-power sequence is used,
  28894. + * the SoC enters low power mode before the ARM core executes WFI.
  28895. + *
  28896. + * Software workaround:
  28897. + * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
  28898. + * by setting IOMUX_GPR1_GINT.
  28899. + * 2) Software should then unmask IRQ #32 in GPC before setting CCM
  28900. + * Low-Power mode.
  28901. + * 3) Software should mask IRQ #32 right after CCM Low-Power mode
  28902. + * is set (set bits 0-1 of CCM_CLPCR).
  28903. + */
  28904. + iomuxc_irq_desc = irq_to_desc(32);
  28905. + imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
  28906. + writel_relaxed(val, ccm_base + CLPCR);
  28907. + imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
  28908. +
  28909. + return 0;
  28910. +}
  28911. +
  28912. +static int imx6q_suspend_finish(unsigned long val)
  28913. +{
  28914. + if (!imx6_suspend_in_ocram_fn) {
  28915. + cpu_do_idle();
  28916. + } else {
  28917. + /*
  28918. + * call low level suspend function in ocram,
  28919. + * as we need to float DDR IO.
  28920. + */
  28921. + local_flush_tlb_all();
  28922. + imx6_suspend_in_ocram_fn(suspend_ocram_base);
  28923. + }
  28924. +
  28925. + return 0;
  28926. +}
  28927. +
  28928. +static int imx6q_pm_enter(suspend_state_t state)
  28929. +{
  28930. + struct regmap *g;
  28931. +
  28932. + /*
  28933. + * L2 can exit by 'reset' or Inband beacon (from remote EP)
  28934. + * toggling phy_powerdown has same effect as 'inband beacon'
  28935. + * So, toggle bit18 of GPR1, used as a workaround of errata
  28936. + * "PCIe PCIe does not support L2 Power Down"
  28937. + */
  28938. + if (IS_ENABLED(CONFIG_PCI_IMX6)) {
  28939. + g = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  28940. + if (IS_ERR(g)) {
  28941. + pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
  28942. + return PTR_ERR(g);
  28943. + }
  28944. + regmap_update_bits(g, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD,
  28945. + IMX6Q_GPR1_PCIE_TEST_PD);
  28946. + }
  28947. +
  28948. + switch (state) {
  28949. + case PM_SUSPEND_STANDBY:
  28950. + imx6q_set_lpm(STOP_POWER_ON);
  28951. + imx6q_set_cache_lpm_in_wait(true);
  28952. + imx_gpc_pre_suspend(false);
  28953. + if (cpu_is_imx6sl())
  28954. + imx6sl_set_wait_clk(true);
  28955. + /* Zzz ... */
  28956. + cpu_do_idle();
  28957. + if (cpu_is_imx6sl())
  28958. + imx6sl_set_wait_clk(false);
  28959. + imx_gpc_post_resume();
  28960. + imx6q_set_lpm(WAIT_CLOCKED);
  28961. + break;
  28962. + case PM_SUSPEND_MEM:
  28963. + imx6q_set_cache_lpm_in_wait(false);
  28964. + imx6q_set_lpm(STOP_POWER_OFF);
  28965. + imx6q_enable_wb(true);
  28966. + /*
  28967. + * For suspend into ocram, asm code already take care of
  28968. + * RBC setting, so we do NOT need to do that here.
  28969. + */
  28970. + if (!imx6_suspend_in_ocram_fn)
  28971. + imx6q_enable_rbc(true);
  28972. + imx_gpc_pre_suspend(true);
  28973. + imx_anatop_pre_suspend();
  28974. + imx_set_cpu_jump(0, v7_cpu_resume);
  28975. + /* Zzz ... */
  28976. + cpu_suspend(0, imx6q_suspend_finish);
  28977. + if (cpu_is_imx6q() || cpu_is_imx6dl())
  28978. + imx_smp_prepare();
  28979. + imx_anatop_post_resume();
  28980. + imx_gpc_post_resume();
  28981. + imx6q_enable_wb(false);
  28982. + imx6q_set_lpm(WAIT_CLOCKED);
  28983. + break;
  28984. + default:
  28985. + return -EINVAL;
  28986. + }
  28987. +
  28988. + /*
  28989. + * L2 can exit by 'reset' or Inband beacon (from remote EP)
  28990. + * toggling phy_powerdown has same effect as 'inband beacon'
  28991. + * So, toggle bit18 of GPR1, used as a workaround of errata
  28992. + * "PCIe PCIe does not support L2 Power Down"
  28993. + */
  28994. + if (IS_ENABLED(CONFIG_PCI_IMX6)) {
  28995. + regmap_update_bits(g, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD,
  28996. + !IMX6Q_GPR1_PCIE_TEST_PD);
  28997. + }
  28998. +
  28999. + return 0;
  29000. +}
  29001. +
  29002. +static int imx6q_pm_valid(suspend_state_t state)
  29003. +{
  29004. + return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
  29005. +}
  29006. +
  29007. +static const struct platform_suspend_ops imx6q_pm_ops = {
  29008. + .enter = imx6q_pm_enter,
  29009. + .valid = imx6q_pm_valid,
  29010. +};
  29011. +
  29012. +void __init imx6q_pm_set_ccm_base(void __iomem *base)
  29013. +{
  29014. + ccm_base = base;
  29015. +}
  29016. +
  29017. +static int __init imx6_pm_get_base(struct imx6_pm_base *base,
  29018. + const char *compat)
  29019. +{
  29020. + struct device_node *node;
  29021. + struct resource res;
  29022. + int ret = 0;
  29023. +
  29024. + node = of_find_compatible_node(NULL, NULL, compat);
  29025. + if (!node) {
  29026. + ret = -ENODEV;
  29027. + goto out;
  29028. + }
  29029. +
  29030. + ret = of_address_to_resource(node, 0, &res);
  29031. + if (ret)
  29032. + goto put_node;
  29033. +
  29034. + base->pbase = res.start;
  29035. + base->vbase = ioremap(res.start, resource_size(&res));
  29036. + if (!base->vbase)
  29037. + ret = -ENOMEM;
  29038. +
  29039. +put_node:
  29040. + of_node_put(node);
  29041. +out:
  29042. + return ret;
  29043. +}
  29044. +
  29045. +static int __init imx6q_ocram_suspend_init(const struct imx6_pm_socdata
  29046. + *socdata)
  29047. +{
  29048. + phys_addr_t ocram_pbase;
  29049. + struct device_node *node;
  29050. + struct platform_device *pdev;
  29051. + struct imx6_cpu_pm_info *pm_info;
  29052. + struct gen_pool *ocram_pool;
  29053. + unsigned long ocram_base;
  29054. + int i, ret = 0;
  29055. + const u32 *mmdc_offset_array;
  29056. +
  29057. + if (!socdata) {
  29058. + pr_warn("%s: invalid argument!\n", __func__);
  29059. + return -EINVAL;
  29060. + }
  29061. +
  29062. + node = of_find_compatible_node(NULL, NULL, "mmio-sram");
  29063. + if (!node) {
  29064. + pr_warn("%s: failed to find ocram node!\n", __func__);
  29065. + return -ENODEV;
  29066. + }
  29067. +
  29068. + pdev = of_find_device_by_node(node);
  29069. + if (!pdev) {
  29070. + pr_warn("%s: failed to find ocram device!\n", __func__);
  29071. + ret = -ENODEV;
  29072. + goto put_node;
  29073. + }
  29074. +
  29075. + ocram_pool = dev_get_gen_pool(&pdev->dev);
  29076. + if (!ocram_pool) {
  29077. + pr_warn("%s: ocram pool unavailable!\n", __func__);
  29078. + ret = -ENODEV;
  29079. + goto put_node;
  29080. + }
  29081. +
  29082. + ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE);
  29083. + if (!ocram_base) {
  29084. + pr_warn("%s: unable to alloc ocram!\n", __func__);
  29085. + ret = -ENOMEM;
  29086. + goto put_node;
  29087. + }
  29088. +
  29089. + ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base);
  29090. +
  29091. + suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
  29092. + MX6Q_SUSPEND_OCRAM_SIZE, false);
  29093. +
  29094. + pm_info = suspend_ocram_base;
  29095. + pm_info->pbase = ocram_pbase;
  29096. + pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
  29097. + pm_info->pm_info_size = sizeof(*pm_info);
  29098. +
  29099. + /*
  29100. + * ccm physical address is not used by asm code currently,
  29101. + * so get ccm virtual address directly, as we already have
  29102. + * it from ccm driver.
  29103. + */
  29104. + pm_info->ccm_base.vbase = ccm_base;
  29105. +
  29106. + ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat);
  29107. + if (ret) {
  29108. + pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret);
  29109. + goto put_node;
  29110. + }
  29111. +
  29112. + ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat);
  29113. + if (ret) {
  29114. + pr_warn("%s: failed to get src base %d!\n", __func__, ret);
  29115. + goto src_map_failed;
  29116. + }
  29117. +
  29118. + ret = imx6_pm_get_base(&pm_info->iomuxc_base, socdata->iomuxc_compat);
  29119. + if (ret) {
  29120. + pr_warn("%s: failed to get iomuxc base %d!\n", __func__, ret);
  29121. + goto iomuxc_map_failed;
  29122. + }
  29123. +
  29124. + ret = imx6_pm_get_base(&pm_info->gpc_base, socdata->gpc_compat);
  29125. + if (ret) {
  29126. + pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
  29127. + goto gpc_map_failed;
  29128. + }
  29129. +
  29130. + ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
  29131. + if (ret) {
  29132. + pr_warn("%s: failed to get pl310-cache base %d!\n",
  29133. + __func__, ret);
  29134. + goto pl310_cache_map_failed;
  29135. + }
  29136. +
  29137. + pm_info->cpu_type = socdata->cpu_type;
  29138. + pm_info->mmdc_io_num = socdata->mmdc_io_num;
  29139. + mmdc_offset_array = socdata->mmdc_io_offset;
  29140. +
  29141. + for (i = 0; i < pm_info->mmdc_io_num; i++) {
  29142. + pm_info->mmdc_io_val[i][0] =
  29143. + mmdc_offset_array[i];
  29144. + pm_info->mmdc_io_val[i][1] =
  29145. + readl_relaxed(pm_info->iomuxc_base.vbase +
  29146. + mmdc_offset_array[i]);
  29147. + }
  29148. +
  29149. + imx6_suspend_in_ocram_fn = fncpy(
  29150. + suspend_ocram_base + sizeof(*pm_info),
  29151. + &imx6_suspend,
  29152. + MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
  29153. +
  29154. + goto put_node;
  29155. +
  29156. +pl310_cache_map_failed:
  29157. + iounmap(&pm_info->gpc_base.vbase);
  29158. +gpc_map_failed:
  29159. + iounmap(&pm_info->iomuxc_base.vbase);
  29160. +iomuxc_map_failed:
  29161. + iounmap(&pm_info->src_base.vbase);
  29162. +src_map_failed:
  29163. + iounmap(&pm_info->mmdc_base.vbase);
  29164. +put_node:
  29165. + of_node_put(node);
  29166. +
  29167. + return ret;
  29168. +}
  29169. +
  29170. +static void __init imx6_pm_common_init(const struct imx6_pm_socdata
  29171. + *socdata)
  29172. +{
  29173. + struct regmap *gpr;
  29174. + int ret;
  29175. +
  29176. + WARN_ON(!ccm_base);
  29177. +
  29178. + ret = imx6q_ocram_suspend_init(socdata);
  29179. + if (ret)
  29180. + pr_warn("%s: failed to initialize ocram suspend %d!\n",
  29181. + __func__, ret);
  29182. +
  29183. + /*
  29184. + * This is for SW workaround step #1 of ERR007265, see comments
  29185. + * in imx6q_set_lpm for details of this errata.
  29186. + * Force IOMUXC irq pending, so that the interrupt to GPC can be
  29187. + * used to deassert dsm_request signal when the signal gets
  29188. + * asserted unexpectedly.
  29189. + */
  29190. + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  29191. + if (!IS_ERR(gpr))
  29192. + regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT_MASK,
  29193. + IMX6Q_GPR1_GINT_MASK);
  29194. +
  29195. +
  29196. + suspend_set_ops(&imx6q_pm_ops);
  29197. +}
  29198. +
  29199. +void __init imx6q_pm_init(void)
  29200. +{
  29201. + imx6_pm_common_init(&imx6q_pm_data);
  29202. +}
  29203. +
  29204. +void __init imx6dl_pm_init(void)
  29205. +{
  29206. + imx6_pm_common_init(NULL);
  29207. +}
  29208. +
  29209. +void __init imx6sl_pm_init(void)
  29210. +{
  29211. + imx6_pm_common_init(NULL);
  29212. +}
  29213. diff -Nur linux-3.14.17/arch/arm/mach-imx/pm-imx6q.c linux-imx6-3.14/arch/arm/mach-imx/pm-imx6q.c
  29214. --- linux-3.14.17/arch/arm/mach-imx/pm-imx6q.c 2014-08-14 03:38:34.000000000 +0200
  29215. +++ linux-imx6-3.14/arch/arm/mach-imx/pm-imx6q.c 1970-01-01 01:00:00.000000000 +0100
  29216. @@ -1,241 +0,0 @@
  29217. -/*
  29218. - * Copyright 2011-2013 Freescale Semiconductor, Inc.
  29219. - * Copyright 2011 Linaro Ltd.
  29220. - *
  29221. - * The code contained herein is licensed under the GNU General Public
  29222. - * License. You may obtain a copy of the GNU General Public License
  29223. - * Version 2 or later at the following locations:
  29224. - *
  29225. - * http://www.opensource.org/licenses/gpl-license.html
  29226. - * http://www.gnu.org/copyleft/gpl.html
  29227. - */
  29228. -
  29229. -#include <linux/delay.h>
  29230. -#include <linux/init.h>
  29231. -#include <linux/io.h>
  29232. -#include <linux/irq.h>
  29233. -#include <linux/mfd/syscon.h>
  29234. -#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  29235. -#include <linux/of.h>
  29236. -#include <linux/of_address.h>
  29237. -#include <linux/regmap.h>
  29238. -#include <linux/suspend.h>
  29239. -#include <asm/cacheflush.h>
  29240. -#include <asm/proc-fns.h>
  29241. -#include <asm/suspend.h>
  29242. -#include <asm/hardware/cache-l2x0.h>
  29243. -
  29244. -#include "common.h"
  29245. -#include "hardware.h"
  29246. -
  29247. -#define CCR 0x0
  29248. -#define BM_CCR_WB_COUNT (0x7 << 16)
  29249. -#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21)
  29250. -#define BM_CCR_RBC_EN (0x1 << 27)
  29251. -
  29252. -#define CLPCR 0x54
  29253. -#define BP_CLPCR_LPM 0
  29254. -#define BM_CLPCR_LPM (0x3 << 0)
  29255. -#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
  29256. -#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
  29257. -#define BM_CLPCR_SBYOS (0x1 << 6)
  29258. -#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
  29259. -#define BM_CLPCR_VSTBY (0x1 << 8)
  29260. -#define BP_CLPCR_STBY_COUNT 9
  29261. -#define BM_CLPCR_STBY_COUNT (0x3 << 9)
  29262. -#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
  29263. -#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
  29264. -#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
  29265. -#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
  29266. -#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
  29267. -#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
  29268. -#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
  29269. -#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
  29270. -#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
  29271. -#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
  29272. -#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
  29273. -
  29274. -#define CGPR 0x64
  29275. -#define BM_CGPR_CHICKEN_BIT (0x1 << 17)
  29276. -
  29277. -static void __iomem *ccm_base;
  29278. -
  29279. -void imx6q_set_chicken_bit(void)
  29280. -{
  29281. - u32 val = readl_relaxed(ccm_base + CGPR);
  29282. -
  29283. - val |= BM_CGPR_CHICKEN_BIT;
  29284. - writel_relaxed(val, ccm_base + CGPR);
  29285. -}
  29286. -
  29287. -static void imx6q_enable_rbc(bool enable)
  29288. -{
  29289. - u32 val;
  29290. -
  29291. - /*
  29292. - * need to mask all interrupts in GPC before
  29293. - * operating RBC configurations
  29294. - */
  29295. - imx_gpc_mask_all();
  29296. -
  29297. - /* configure RBC enable bit */
  29298. - val = readl_relaxed(ccm_base + CCR);
  29299. - val &= ~BM_CCR_RBC_EN;
  29300. - val |= enable ? BM_CCR_RBC_EN : 0;
  29301. - writel_relaxed(val, ccm_base + CCR);
  29302. -
  29303. - /* configure RBC count */
  29304. - val = readl_relaxed(ccm_base + CCR);
  29305. - val &= ~BM_CCR_RBC_BYPASS_COUNT;
  29306. - val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0;
  29307. - writel(val, ccm_base + CCR);
  29308. -
  29309. - /*
  29310. - * need to delay at least 2 cycles of CKIL(32K)
  29311. - * due to hardware design requirement, which is
  29312. - * ~61us, here we use 65us for safe
  29313. - */
  29314. - udelay(65);
  29315. -
  29316. - /* restore GPC interrupt mask settings */
  29317. - imx_gpc_restore_all();
  29318. -}
  29319. -
  29320. -static void imx6q_enable_wb(bool enable)
  29321. -{
  29322. - u32 val;
  29323. -
  29324. - /* configure well bias enable bit */
  29325. - val = readl_relaxed(ccm_base + CLPCR);
  29326. - val &= ~BM_CLPCR_WB_PER_AT_LPM;
  29327. - val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0;
  29328. - writel_relaxed(val, ccm_base + CLPCR);
  29329. -
  29330. - /* configure well bias count */
  29331. - val = readl_relaxed(ccm_base + CCR);
  29332. - val &= ~BM_CCR_WB_COUNT;
  29333. - val |= enable ? BM_CCR_WB_COUNT : 0;
  29334. - writel_relaxed(val, ccm_base + CCR);
  29335. -}
  29336. -
  29337. -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
  29338. -{
  29339. - struct irq_desc *iomuxc_irq_desc;
  29340. - u32 val = readl_relaxed(ccm_base + CLPCR);
  29341. -
  29342. - val &= ~BM_CLPCR_LPM;
  29343. - switch (mode) {
  29344. - case WAIT_CLOCKED:
  29345. - break;
  29346. - case WAIT_UNCLOCKED:
  29347. - val |= 0x1 << BP_CLPCR_LPM;
  29348. - val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
  29349. - break;
  29350. - case STOP_POWER_ON:
  29351. - val |= 0x2 << BP_CLPCR_LPM;
  29352. - break;
  29353. - case WAIT_UNCLOCKED_POWER_OFF:
  29354. - val |= 0x1 << BP_CLPCR_LPM;
  29355. - val &= ~BM_CLPCR_VSTBY;
  29356. - val &= ~BM_CLPCR_SBYOS;
  29357. - break;
  29358. - case STOP_POWER_OFF:
  29359. - val |= 0x2 << BP_CLPCR_LPM;
  29360. - val |= 0x3 << BP_CLPCR_STBY_COUNT;
  29361. - val |= BM_CLPCR_VSTBY;
  29362. - val |= BM_CLPCR_SBYOS;
  29363. - if (cpu_is_imx6sl()) {
  29364. - val |= BM_CLPCR_BYPASS_PMIC_READY;
  29365. - val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
  29366. - } else {
  29367. - val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
  29368. - }
  29369. - break;
  29370. - default:
  29371. - return -EINVAL;
  29372. - }
  29373. -
  29374. - /*
  29375. - * ERR007265: CCM: When improper low-power sequence is used,
  29376. - * the SoC enters low power mode before the ARM core executes WFI.
  29377. - *
  29378. - * Software workaround:
  29379. - * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
  29380. - * by setting IOMUX_GPR1_GINT.
  29381. - * 2) Software should then unmask IRQ #32 in GPC before setting CCM
  29382. - * Low-Power mode.
  29383. - * 3) Software should mask IRQ #32 right after CCM Low-Power mode
  29384. - * is set (set bits 0-1 of CCM_CLPCR).
  29385. - */
  29386. - iomuxc_irq_desc = irq_to_desc(32);
  29387. - imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data);
  29388. - writel_relaxed(val, ccm_base + CLPCR);
  29389. - imx_gpc_irq_mask(&iomuxc_irq_desc->irq_data);
  29390. -
  29391. - return 0;
  29392. -}
  29393. -
  29394. -static int imx6q_suspend_finish(unsigned long val)
  29395. -{
  29396. - cpu_do_idle();
  29397. - return 0;
  29398. -}
  29399. -
  29400. -static int imx6q_pm_enter(suspend_state_t state)
  29401. -{
  29402. - switch (state) {
  29403. - case PM_SUSPEND_MEM:
  29404. - imx6q_set_lpm(STOP_POWER_OFF);
  29405. - imx6q_enable_wb(true);
  29406. - imx6q_enable_rbc(true);
  29407. - imx_gpc_pre_suspend();
  29408. - imx_anatop_pre_suspend();
  29409. - imx_set_cpu_jump(0, v7_cpu_resume);
  29410. - /* Zzz ... */
  29411. - cpu_suspend(0, imx6q_suspend_finish);
  29412. - if (cpu_is_imx6q() || cpu_is_imx6dl())
  29413. - imx_smp_prepare();
  29414. - imx_anatop_post_resume();
  29415. - imx_gpc_post_resume();
  29416. - imx6q_enable_rbc(false);
  29417. - imx6q_enable_wb(false);
  29418. - imx6q_set_lpm(WAIT_CLOCKED);
  29419. - break;
  29420. - default:
  29421. - return -EINVAL;
  29422. - }
  29423. -
  29424. - return 0;
  29425. -}
  29426. -
  29427. -static const struct platform_suspend_ops imx6q_pm_ops = {
  29428. - .enter = imx6q_pm_enter,
  29429. - .valid = suspend_valid_only_mem,
  29430. -};
  29431. -
  29432. -void __init imx6q_pm_set_ccm_base(void __iomem *base)
  29433. -{
  29434. - ccm_base = base;
  29435. -}
  29436. -
  29437. -void __init imx6q_pm_init(void)
  29438. -{
  29439. - struct regmap *gpr;
  29440. -
  29441. - WARN_ON(!ccm_base);
  29442. -
  29443. - /*
  29444. - * This is for SW workaround step #1 of ERR007265, see comments
  29445. - * in imx6q_set_lpm for details of this errata.
  29446. - * Force IOMUXC irq pending, so that the interrupt to GPC can be
  29447. - * used to deassert dsm_request signal when the signal gets
  29448. - * asserted unexpectedly.
  29449. - */
  29450. - gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  29451. - if (!IS_ERR(gpr))
  29452. - regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
  29453. - IMX6Q_GPR1_GINT);
  29454. -
  29455. -
  29456. - suspend_set_ops(&imx6q_pm_ops);
  29457. -}
  29458. diff -Nur linux-3.14.17/arch/arm/mach-imx/suspend-imx6.S linux-imx6-3.14/arch/arm/mach-imx/suspend-imx6.S
  29459. --- linux-3.14.17/arch/arm/mach-imx/suspend-imx6.S 1970-01-01 01:00:00.000000000 +0100
  29460. +++ linux-imx6-3.14/arch/arm/mach-imx/suspend-imx6.S 2014-09-11 18:05:53.394003573 +0200
  29461. @@ -0,0 +1,306 @@
  29462. +/*
  29463. + * Copyright 2014 Freescale Semiconductor, Inc.
  29464. + *
  29465. + * The code contained herein is licensed under the GNU General Public
  29466. + * License. You may obtain a copy of the GNU General Public License
  29467. + * Version 2 or later at the following locations:
  29468. + *
  29469. + * http://www.opensource.org/licenses/gpl-license.html
  29470. + * http://www.gnu.org/copyleft/gpl.html
  29471. + */
  29472. +
  29473. +#include <linux/linkage.h>
  29474. +#include <asm/asm-offsets.h>
  29475. +#include <asm/hardware/cache-l2x0.h>
  29476. +#include "hardware.h"
  29477. +
  29478. +/*
  29479. + * ==================== low level suspend ====================
  29480. + *
  29481. + * Better to follow below rules to use ARM registers:
  29482. + * r0: pm_info structure address;
  29483. + * r1 ~ r4: for saving pm_info members;
  29484. + * r5 ~ r10: free registers;
  29485. + * r11: io base address.
  29486. + *
  29487. + * suspend ocram space layout:
  29488. + * ======================== high address ======================
  29489. + * .
  29490. + * .
  29491. + * .
  29492. + * ^
  29493. + * ^
  29494. + * ^
  29495. + * imx6_suspend code
  29496. + * PM_INFO structure(imx6_cpu_pm_info)
  29497. + * ======================== low address =======================
  29498. + */
  29499. +
  29500. +/*
  29501. + * Below offsets are based on struct imx6_cpu_pm_info
  29502. + * which defined in arch/arm/mach-imx/pm-imx6q.c, this
  29503. + * structure contains necessary pm info for low level
  29504. + * suspend related code.
  29505. + */
  29506. +#define PM_INFO_PBASE_OFFSET 0x0
  29507. +#define PM_INFO_RESUME_ADDR_OFFSET 0x4
  29508. +#define PM_INFO_CPU_TYPE_OFFSET 0x8
  29509. +#define PM_INFO_PM_INFO_SIZE_OFFSET 0xC
  29510. +#define PM_INFO_MX6Q_MMDC_P_OFFSET 0x10
  29511. +#define PM_INFO_MX6Q_MMDC_V_OFFSET 0x14
  29512. +#define PM_INFO_MX6Q_SRC_P_OFFSET 0x18
  29513. +#define PM_INFO_MX6Q_SRC_V_OFFSET 0x1C
  29514. +#define PM_INFO_MX6Q_IOMUXC_P_OFFSET 0x20
  29515. +#define PM_INFO_MX6Q_IOMUXC_V_OFFSET 0x24
  29516. +#define PM_INFO_MX6Q_CCM_P_OFFSET 0x28
  29517. +#define PM_INFO_MX6Q_CCM_V_OFFSET 0x2C
  29518. +#define PM_INFO_MX6Q_GPC_P_OFFSET 0x30
  29519. +#define PM_INFO_MX6Q_GPC_V_OFFSET 0x34
  29520. +#define PM_INFO_MX6Q_L2_P_OFFSET 0x38
  29521. +#define PM_INFO_MX6Q_L2_V_OFFSET 0x3C
  29522. +#define PM_INFO_MMDC_IO_NUM_OFFSET 0x40
  29523. +#define PM_INFO_MMDC_IO_VAL_OFFSET 0x44
  29524. +
  29525. +#define MX6Q_SRC_GPR1 0x20
  29526. +#define MX6Q_SRC_GPR2 0x24
  29527. +#define MX6Q_MMDC_MAPSR 0x404
  29528. +#define MX6Q_GPC_IMR1 0x08
  29529. +#define MX6Q_GPC_IMR2 0x0c
  29530. +#define MX6Q_GPC_IMR3 0x10
  29531. +#define MX6Q_GPC_IMR4 0x14
  29532. +#define MX6Q_CCM_CCR 0x0
  29533. +
  29534. + .align 3
  29535. +
  29536. + .macro sync_l2_cache
  29537. +
  29538. + /* sync L2 cache to drain L2's buffers to DRAM. */
  29539. +#ifdef CONFIG_CACHE_L2X0
  29540. + ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
  29541. + mov r6, #0x0
  29542. + str r6, [r11, #L2X0_CACHE_SYNC]
  29543. +1:
  29544. + ldr r6, [r11, #L2X0_CACHE_SYNC]
  29545. + ands r6, r6, #0x1
  29546. + bne 1b
  29547. +#endif
  29548. +
  29549. + .endm
  29550. +
  29551. + .macro resume_mmdc
  29552. +
  29553. + /* restore MMDC IO */
  29554. + cmp r5, #0x0
  29555. + ldreq r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29556. + ldrne r11, [r0, #PM_INFO_MX6Q_IOMUXC_P_OFFSET]
  29557. +
  29558. + ldr r6, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
  29559. + ldr r7, =PM_INFO_MMDC_IO_VAL_OFFSET
  29560. + add r7, r7, r0
  29561. +1:
  29562. + ldr r8, [r7], #0x4
  29563. + ldr r9, [r7], #0x4
  29564. + str r9, [r11, r8]
  29565. + subs r6, r6, #0x1
  29566. + bne 1b
  29567. +
  29568. + cmp r5, #0x0
  29569. + ldreq r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
  29570. + ldrne r11, [r0, #PM_INFO_MX6Q_MMDC_P_OFFSET]
  29571. +
  29572. + /* let DDR out of self-refresh */
  29573. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29574. + bic r7, r7, #(1 << 21)
  29575. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29576. +2:
  29577. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29578. + ands r7, r7, #(1 << 25)
  29579. + bne 2b
  29580. +
  29581. + /* enable DDR auto power saving */
  29582. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29583. + bic r7, r7, #0x1
  29584. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29585. +
  29586. + .endm
  29587. +
  29588. +ENTRY(imx6_suspend)
  29589. + ldr r1, [r0, #PM_INFO_PBASE_OFFSET]
  29590. + ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
  29591. + ldr r3, [r0, #PM_INFO_CPU_TYPE_OFFSET]
  29592. + ldr r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
  29593. +
  29594. + /*
  29595. + * counting the resume address in iram
  29596. + * to set it in SRC register.
  29597. + */
  29598. + ldr r6, =imx6_suspend
  29599. + ldr r7, =resume
  29600. + sub r7, r7, r6
  29601. + add r8, r1, r4
  29602. + add r9, r8, r7
  29603. +
  29604. + /*
  29605. + * make sure TLB contain the addr we want,
  29606. + * as we will access them after MMDC IO floated.
  29607. + */
  29608. +
  29609. + ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
  29610. + ldr r6, [r11, #0x0]
  29611. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29612. + ldr r6, [r11, #0x0]
  29613. + ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29614. + ldr r6, [r11, #0x0]
  29615. +
  29616. + /* use r11 to store the IO address */
  29617. + ldr r11, [r0, #PM_INFO_MX6Q_SRC_V_OFFSET]
  29618. + /* store physical resume addr and pm_info address. */
  29619. + str r9, [r11, #MX6Q_SRC_GPR1]
  29620. + str r1, [r11, #MX6Q_SRC_GPR2]
  29621. +
  29622. + /* need to sync L2 cache before DSM. */
  29623. + sync_l2_cache
  29624. +
  29625. + ldr r11, [r0, #PM_INFO_MX6Q_MMDC_V_OFFSET]
  29626. + /*
  29627. + * put DDR explicitly into self-refresh and
  29628. + * disable automatic power savings.
  29629. + */
  29630. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29631. + orr r7, r7, #0x1
  29632. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29633. +
  29634. + /* make the DDR explicitly enter self-refresh. */
  29635. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29636. + orr r7, r7, #(1 << 21)
  29637. + str r7, [r11, #MX6Q_MMDC_MAPSR]
  29638. +
  29639. +poll_dvfs_set:
  29640. + ldr r7, [r11, #MX6Q_MMDC_MAPSR]
  29641. + ands r7, r7, #(1 << 25)
  29642. + beq poll_dvfs_set
  29643. +
  29644. + ldr r11, [r0, #PM_INFO_MX6Q_IOMUXC_V_OFFSET]
  29645. + ldr r6, =0x0
  29646. + ldr r7, [r0, #PM_INFO_MMDC_IO_NUM_OFFSET]
  29647. + ldr r8, =PM_INFO_MMDC_IO_VAL_OFFSET
  29648. + add r8, r8, r0
  29649. +set_mmdc_io_lpm:
  29650. + ldr r9, [r8], #0x8
  29651. + str r6, [r11, r9]
  29652. + subs r7, r7, #0x1
  29653. + bne set_mmdc_io_lpm
  29654. +
  29655. + /*
  29656. + * mask all GPC interrupts before
  29657. + * enabling the RBC counters to
  29658. + * avoid the counter starting too
  29659. + * early if an interupt is already
  29660. + * pending.
  29661. + */
  29662. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29663. + ldr r6, [r11, #MX6Q_GPC_IMR1]
  29664. + ldr r7, [r11, #MX6Q_GPC_IMR2]
  29665. + ldr r8, [r11, #MX6Q_GPC_IMR3]
  29666. + ldr r9, [r11, #MX6Q_GPC_IMR4]
  29667. +
  29668. + ldr r10, =0xffffffff
  29669. + str r10, [r11, #MX6Q_GPC_IMR1]
  29670. + str r10, [r11, #MX6Q_GPC_IMR2]
  29671. + str r10, [r11, #MX6Q_GPC_IMR3]
  29672. + str r10, [r11, #MX6Q_GPC_IMR4]
  29673. +
  29674. + /*
  29675. + * enable the RBC bypass counter here
  29676. + * to hold off the interrupts. RBC counter
  29677. + * = 32 (1ms), Minimum RBC delay should be
  29678. + * 400us for the analog LDOs to power down.
  29679. + */
  29680. + ldr r11, [r0, #PM_INFO_MX6Q_CCM_V_OFFSET]
  29681. + ldr r10, [r11, #MX6Q_CCM_CCR]
  29682. + bic r10, r10, #(0x3f << 21)
  29683. + orr r10, r10, #(0x20 << 21)
  29684. + str r10, [r11, #MX6Q_CCM_CCR]
  29685. +
  29686. + /* enable the counter. */
  29687. + ldr r10, [r11, #MX6Q_CCM_CCR]
  29688. + orr r10, r10, #(0x1 << 27)
  29689. + str r10, [r11, #MX6Q_CCM_CCR]
  29690. +
  29691. + /* unmask all the GPC interrupts. */
  29692. + ldr r11, [r0, #PM_INFO_MX6Q_GPC_V_OFFSET]
  29693. + str r6, [r11, #MX6Q_GPC_IMR1]
  29694. + str r7, [r11, #MX6Q_GPC_IMR2]
  29695. + str r8, [r11, #MX6Q_GPC_IMR3]
  29696. + str r9, [r11, #MX6Q_GPC_IMR4]
  29697. +
  29698. + /*
  29699. + * now delay for a short while (3usec)
  29700. + * ARM is at 1GHz at this point
  29701. + * so a short loop should be enough.
  29702. + * this delay is required to ensure that
  29703. + * the RBC counter can start counting in
  29704. + * case an interrupt is already pending
  29705. + * or in case an interrupt arrives just
  29706. + * as ARM is about to assert DSM_request.
  29707. + */
  29708. + ldr r6, =2000
  29709. +rbc_loop:
  29710. + subs r6, r6, #0x1
  29711. + bne rbc_loop
  29712. +
  29713. + /* Zzz, enter stop mode */
  29714. + wfi
  29715. + nop
  29716. + nop
  29717. + nop
  29718. + nop
  29719. +
  29720. + /*
  29721. + * run to here means there is pending
  29722. + * wakeup source, system should auto
  29723. + * resume, we need to restore MMDC IO first
  29724. + */
  29725. + mov r5, #0x0
  29726. + resume_mmdc
  29727. +
  29728. + /* return to suspend finish */
  29729. + mov pc, lr
  29730. +
  29731. +resume:
  29732. + /* invalidate L1 I-cache first */
  29733. + mov r6, #0x0
  29734. + mcr p15, 0, r6, c7, c5, 0
  29735. + mcr p15, 0, r6, c7, c5, 6
  29736. + /* enable the Icache and branch prediction */
  29737. + mov r6, #0x1800
  29738. + mcr p15, 0, r6, c1, c0, 0
  29739. + isb
  29740. +
  29741. + /* get physical resume address from pm_info. */
  29742. + ldr lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
  29743. + /* clear core0's entry and parameter */
  29744. + ldr r11, [r0, #PM_INFO_MX6Q_SRC_P_OFFSET]
  29745. + mov r7, #0x0
  29746. + str r7, [r11, #MX6Q_SRC_GPR1]
  29747. + str r7, [r11, #MX6Q_SRC_GPR2]
  29748. +
  29749. + mov r5, #0x1
  29750. + resume_mmdc
  29751. +
  29752. + mov pc, lr
  29753. +ENDPROC(imx6_suspend)
  29754. +
  29755. +/*
  29756. + * The following code must assume it is running from physical address
  29757. + * where absolute virtual addresses to the data section have to be
  29758. + * turned into relative ones.
  29759. + */
  29760. +
  29761. +ENTRY(v7_cpu_resume)
  29762. + bl v7_invalidate_l1
  29763. +#ifdef CONFIG_CACHE_L2X0
  29764. + bl l2c310_early_resume
  29765. +#endif
  29766. + b cpu_resume
  29767. +ENDPROC(v7_cpu_resume)
  29768. diff -Nur linux-3.14.17/arch/arm/mach-imx/system.c linux-imx6-3.14/arch/arm/mach-imx/system.c
  29769. --- linux-3.14.17/arch/arm/mach-imx/system.c 2014-08-14 03:38:34.000000000 +0200
  29770. +++ linux-imx6-3.14/arch/arm/mach-imx/system.c 2014-09-11 18:05:53.394003573 +0200
  29771. @@ -34,6 +34,7 @@
  29772. static void __iomem *wdog_base;
  29773. static struct clk *wdog_clk;
  29774. +static u32 wdog_source = 1; /* use WDOG1 default */
  29775. /*
  29776. * Reset the system. It is called by machine_restart().
  29777. @@ -47,6 +48,15 @@
  29778. if (cpu_is_mx1())
  29779. wcr_enable = (1 << 0);
  29780. + /*
  29781. + * Some i.MX6 boards use WDOG2 to reset external pmic in bypass mode,
  29782. + * so do WDOG2 reset here. Do not set SRS, since we will
  29783. + * trigger external POR later. Use WDOG1 to reset in ldo-enable
  29784. + * mode. You can set it by "fsl,wdog-reset" in dts.
  29785. + */
  29786. + else if (wdog_source == 2 && (cpu_is_imx6q() || cpu_is_imx6dl() ||
  29787. + cpu_is_imx6sl()))
  29788. + wcr_enable = 0x14;
  29789. else
  29790. wcr_enable = (1 << 2);
  29791. @@ -90,12 +100,29 @@
  29792. void __init mxc_arch_reset_init_dt(void)
  29793. {
  29794. - struct device_node *np;
  29795. + struct device_node *np = NULL;
  29796. +
  29797. + if (cpu_is_imx6q() || cpu_is_imx6dl())
  29798. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc");
  29799. + else if (cpu_is_imx6sl())
  29800. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpc");
  29801. +
  29802. + if (np)
  29803. + of_property_read_u32(np, "fsl,wdog-reset", &wdog_source);
  29804. + pr_info("Use WDOG%d as reset source\n", wdog_source);
  29805. np = of_find_compatible_node(NULL, NULL, "fsl,imx21-wdt");
  29806. wdog_base = of_iomap(np, 0);
  29807. WARN_ON(!wdog_base);
  29808. + /* Some i.MX6 boards use WDOG2 to reset board in ldo-bypass mode */
  29809. + if (wdog_source == 2 && (cpu_is_imx6q() || cpu_is_imx6dl() ||
  29810. + cpu_is_imx6sl())) {
  29811. + np = of_find_compatible_node(np, NULL, "fsl,imx21-wdt");
  29812. + wdog_base = of_iomap(np, 0);
  29813. + WARN_ON(!wdog_base);
  29814. + }
  29815. +
  29816. wdog_clk = of_clk_get(np, 0);
  29817. if (IS_ERR(wdog_clk)) {
  29818. pr_warn("%s: failed to get wdog clock\n", __func__);
  29819. @@ -124,7 +151,7 @@
  29820. }
  29821. /* Configure the L2 PREFETCH and POWER registers */
  29822. - val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
  29823. + val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL);
  29824. val |= 0x70800000;
  29825. /*
  29826. * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
  29827. @@ -137,14 +164,12 @@
  29828. */
  29829. if (cpu_is_imx6q())
  29830. val &= ~(1 << 30 | 1 << 23);
  29831. - writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
  29832. - val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
  29833. - writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
  29834. + writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL);
  29835. iounmap(l2x0_base);
  29836. of_node_put(np);
  29837. out:
  29838. - l2x0_of_init(0, ~0UL);
  29839. + l2x0_of_init(0, ~0);
  29840. }
  29841. #endif
  29842. diff -Nur linux-3.14.17/arch/arm/mach-imx/time.c linux-imx6-3.14/arch/arm/mach-imx/time.c
  29843. --- linux-3.14.17/arch/arm/mach-imx/time.c 2014-08-14 03:38:34.000000000 +0200
  29844. +++ linux-imx6-3.14/arch/arm/mach-imx/time.c 2014-09-11 18:05:53.394003573 +0200
  29845. @@ -60,7 +60,11 @@
  29846. #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
  29847. #define V2_TCTL_CLK_IPG (1 << 6)
  29848. #define V2_TCTL_CLK_PER (2 << 6)
  29849. +#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
  29850. +#define V2_TCTL_CLK_OSC (7 << 6)
  29851. +#define V2_TCTL_24MEN (1 << 10)
  29852. #define V2_TCTL_FRR (1 << 9)
  29853. +#define V2_TPRER_PRE24M 12
  29854. #define V2_IR 0x0c
  29855. #define V2_TSTAT 0x08
  29856. #define V2_TSTAT_OF1 (1 << 0)
  29857. @@ -277,11 +281,20 @@
  29858. void __init mxc_timer_init(void __iomem *base, int irq)
  29859. {
  29860. - uint32_t tctl_val;
  29861. + uint32_t tctl_val, tprer_val;
  29862. struct clk *timer_clk;
  29863. struct clk *timer_ipg_clk;
  29864. - timer_clk = clk_get_sys("imx-gpt.0", "per");
  29865. + /*
  29866. + * gpt clk source from 24M OSC on imx6q > TO1.0 and
  29867. + * imx6dl, others from per clk.
  29868. + */
  29869. + if ((cpu_is_imx6q() && imx_get_soc_revision() > IMX_CHIP_REVISION_1_0)
  29870. + || cpu_is_imx6dl())
  29871. + timer_clk = clk_get_sys("imx-gpt.0", "gpt_3m");
  29872. + else
  29873. + timer_clk = clk_get_sys("imx-gpt.0", "per");
  29874. +
  29875. if (IS_ERR(timer_clk)) {
  29876. pr_err("i.MX timer: unable to get clk\n");
  29877. return;
  29878. @@ -302,10 +315,24 @@
  29879. __raw_writel(0, timer_base + MXC_TCTL);
  29880. __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
  29881. - if (timer_is_v2())
  29882. - tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29883. - else
  29884. + if (timer_is_v2()) {
  29885. + if ((cpu_is_imx6q() && imx_get_soc_revision() >
  29886. + IMX_CHIP_REVISION_1_0) || cpu_is_imx6dl()) {
  29887. + tctl_val = V2_TCTL_CLK_OSC_DIV8 | V2_TCTL_FRR |
  29888. + V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29889. + if (cpu_is_imx6dl()) {
  29890. + /* 24 / 8 = 3 MHz */
  29891. + tprer_val = 7 << V2_TPRER_PRE24M;
  29892. + __raw_writel(tprer_val, timer_base + MXC_TPRER);
  29893. + tctl_val |= V2_TCTL_24MEN;
  29894. + }
  29895. + } else {
  29896. + tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR |
  29897. + V2_TCTL_WAITEN | MXC_TCTL_TEN;
  29898. + }
  29899. + } else {
  29900. tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
  29901. + }
  29902. __raw_writel(tctl_val, timer_base + MXC_TCTL);
  29903. diff -Nur linux-3.14.17/arch/arm/mach-nomadik/cpu-8815.c linux-imx6-3.14/arch/arm/mach-nomadik/cpu-8815.c
  29904. --- linux-3.14.17/arch/arm/mach-nomadik/cpu-8815.c 2014-08-14 03:38:34.000000000 +0200
  29905. +++ linux-imx6-3.14/arch/arm/mach-nomadik/cpu-8815.c 2014-09-11 18:05:53.698004788 +0200
  29906. @@ -147,7 +147,7 @@
  29907. {
  29908. #ifdef CONFIG_CACHE_L2X0
  29909. /* At full speed latency must be >=2, so 0x249 in low bits */
  29910. - l2x0_of_init(0x00730249, 0xfe000fff);
  29911. + l2x0_of_init(0x00700249, 0xfe0fefff);
  29912. #endif
  29913. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  29914. }
  29915. diff -Nur linux-3.14.17/arch/arm/mach-omap2/common.h linux-imx6-3.14/arch/arm/mach-omap2/common.h
  29916. --- linux-3.14.17/arch/arm/mach-omap2/common.h 2014-08-14 03:38:34.000000000 +0200
  29917. +++ linux-imx6-3.14/arch/arm/mach-omap2/common.h 2014-09-11 18:05:53.814005253 +0200
  29918. @@ -91,6 +91,7 @@
  29919. extern void omap3_secure_sync32k_timer_init(void);
  29920. extern void omap3_gptimer_timer_init(void);
  29921. extern void omap4_local_timer_init(void);
  29922. +int omap_l2_cache_init(void);
  29923. extern void omap5_realtime_timer_init(void);
  29924. void omap2420_init_early(void);
  29925. diff -Nur linux-3.14.17/arch/arm/mach-omap2/io.c linux-imx6-3.14/arch/arm/mach-omap2/io.c
  29926. --- linux-3.14.17/arch/arm/mach-omap2/io.c 2014-08-14 03:38:34.000000000 +0200
  29927. +++ linux-imx6-3.14/arch/arm/mach-omap2/io.c 2014-09-11 18:05:53.862005446 +0200
  29928. @@ -608,6 +608,7 @@
  29929. am43xx_clockdomains_init();
  29930. am43xx_hwmod_init();
  29931. omap_hwmod_init_postsetup();
  29932. + omap_l2_cache_init();
  29933. omap_clk_soc_init = am43xx_dt_clk_init;
  29934. }
  29935. @@ -639,6 +640,7 @@
  29936. omap44xx_clockdomains_init();
  29937. omap44xx_hwmod_init();
  29938. omap_hwmod_init_postsetup();
  29939. + omap_l2_cache_init();
  29940. omap_clk_soc_init = omap4xxx_dt_clk_init;
  29941. }
  29942. diff -Nur linux-3.14.17/arch/arm/mach-omap2/Kconfig linux-imx6-3.14/arch/arm/mach-omap2/Kconfig
  29943. --- linux-3.14.17/arch/arm/mach-omap2/Kconfig 2014-08-14 03:38:34.000000000 +0200
  29944. +++ linux-imx6-3.14/arch/arm/mach-omap2/Kconfig 2014-09-11 18:05:53.730004917 +0200
  29945. @@ -78,6 +78,7 @@
  29946. select MULTI_IRQ_HANDLER
  29947. select ARM_GIC
  29948. select MACH_OMAP_GENERIC
  29949. + select MIGHT_HAVE_CACHE_L2X0
  29950. config SOC_DRA7XX
  29951. bool "TI DRA7XX"
  29952. diff -Nur linux-3.14.17/arch/arm/mach-omap2/omap4-common.c linux-imx6-3.14/arch/arm/mach-omap2/omap4-common.c
  29953. --- linux-3.14.17/arch/arm/mach-omap2/omap4-common.c 2014-08-14 03:38:34.000000000 +0200
  29954. +++ linux-imx6-3.14/arch/arm/mach-omap2/omap4-common.c 2014-09-11 18:05:53.870005477 +0200
  29955. @@ -166,75 +166,57 @@
  29956. return l2cache_base;
  29957. }
  29958. -static void omap4_l2x0_disable(void)
  29959. +static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
  29960. {
  29961. - outer_flush_all();
  29962. - /* Disable PL310 L2 Cache controller */
  29963. - omap_smc1(0x102, 0x0);
  29964. -}
  29965. + unsigned smc_op;
  29966. -static void omap4_l2x0_set_debug(unsigned long val)
  29967. -{
  29968. - /* Program PL310 L2 Cache controller debug register */
  29969. - omap_smc1(0x100, val);
  29970. + switch (reg) {
  29971. + case L2X0_CTRL:
  29972. + smc_op = OMAP4_MON_L2X0_CTRL_INDEX;
  29973. + break;
  29974. +
  29975. + case L2X0_AUX_CTRL:
  29976. + smc_op = OMAP4_MON_L2X0_AUXCTRL_INDEX;
  29977. + break;
  29978. +
  29979. + case L2X0_DEBUG_CTRL:
  29980. + smc_op = OMAP4_MON_L2X0_DBG_CTRL_INDEX;
  29981. + break;
  29982. +
  29983. + case L310_PREFETCH_CTRL:
  29984. + smc_op = OMAP4_MON_L2X0_PREFETCH_INDEX;
  29985. + break;
  29986. +
  29987. + default:
  29988. + WARN_ONCE(1, "OMAP L2C310: ignoring write to reg 0x%x\n", reg);
  29989. + return;
  29990. + }
  29991. +
  29992. + omap_smc1(smc_op, val);
  29993. }
  29994. -static int __init omap_l2_cache_init(void)
  29995. +int __init omap_l2_cache_init(void)
  29996. {
  29997. - u32 aux_ctrl = 0;
  29998. -
  29999. - /*
  30000. - * To avoid code running on other OMAPs in
  30001. - * multi-omap builds
  30002. - */
  30003. - if (!cpu_is_omap44xx())
  30004. - return -ENODEV;
  30005. + u32 aux_ctrl;
  30006. /* Static mapping, never released */
  30007. l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
  30008. if (WARN_ON(!l2cache_base))
  30009. return -ENOMEM;
  30010. - /*
  30011. - * 16-way associativity, parity disabled
  30012. - * Way size - 32KB (es1.0)
  30013. - * Way size - 64KB (es2.0 +)
  30014. - */
  30015. - aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
  30016. - (0x1 << 25) |
  30017. - (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
  30018. - (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
  30019. -
  30020. - if (omap_rev() == OMAP4430_REV_ES1_0) {
  30021. - aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
  30022. - } else {
  30023. - aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
  30024. - (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
  30025. - (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
  30026. - (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
  30027. - (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
  30028. - }
  30029. - if (omap_rev() != OMAP4430_REV_ES1_0)
  30030. - omap_smc1(0x109, aux_ctrl);
  30031. -
  30032. - /* Enable PL310 L2 Cache controller */
  30033. - omap_smc1(0x102, 0x1);
  30034. + /* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */
  30035. + aux_ctrl = L2C_AUX_CTRL_SHARED_OVERRIDE |
  30036. + L310_AUX_CTRL_DATA_PREFETCH |
  30037. + L310_AUX_CTRL_INSTR_PREFETCH;
  30038. + outer_cache.write_sec = omap4_l2c310_write_sec;
  30039. if (of_have_populated_dt())
  30040. - l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
  30041. + l2x0_of_init(aux_ctrl, 0xcf9fffff);
  30042. else
  30043. - l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
  30044. -
  30045. - /*
  30046. - * Override default outer_cache.disable with a OMAP4
  30047. - * specific one
  30048. - */
  30049. - outer_cache.disable = omap4_l2x0_disable;
  30050. - outer_cache.set_debug = omap4_l2x0_set_debug;
  30051. + l2x0_init(l2cache_base, aux_ctrl, 0xcf9fffff);
  30052. return 0;
  30053. }
  30054. -omap_early_initcall(omap_l2_cache_init);
  30055. #endif
  30056. void __iomem *omap4_get_sar_ram_base(void)
  30057. diff -Nur linux-3.14.17/arch/arm/mach-omap2/omap-mpuss-lowpower.c linux-imx6-3.14/arch/arm/mach-omap2/omap-mpuss-lowpower.c
  30058. --- linux-3.14.17/arch/arm/mach-omap2/omap-mpuss-lowpower.c 2014-08-14 03:38:34.000000000 +0200
  30059. +++ linux-imx6-3.14/arch/arm/mach-omap2/omap-mpuss-lowpower.c 2014-09-11 18:05:53.866005462 +0200
  30060. @@ -187,19 +187,15 @@
  30061. * in every restore MPUSS OFF path.
  30062. */
  30063. #ifdef CONFIG_CACHE_L2X0
  30064. -static void save_l2x0_context(void)
  30065. +static void __init save_l2x0_context(void)
  30066. {
  30067. - u32 val;
  30068. - void __iomem *l2x0_base = omap4_get_l2cache_base();
  30069. - if (l2x0_base) {
  30070. - val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
  30071. - __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
  30072. - val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
  30073. - __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
  30074. - }
  30075. + __raw_writel(l2x0_saved_regs.aux_ctrl,
  30076. + sar_base + L2X0_AUXCTRL_OFFSET);
  30077. + __raw_writel(l2x0_saved_regs.prefetch_ctrl,
  30078. + sar_base + L2X0_PREFETCH_CTRL_OFFSET);
  30079. }
  30080. #else
  30081. -static void save_l2x0_context(void)
  30082. +static void __init save_l2x0_context(void)
  30083. {}
  30084. #endif
  30085. diff -Nur linux-3.14.17/arch/arm/mach-prima2/l2x0.c linux-imx6-3.14/arch/arm/mach-prima2/l2x0.c
  30086. --- linux-3.14.17/arch/arm/mach-prima2/l2x0.c 2014-08-14 03:38:34.000000000 +0200
  30087. +++ linux-imx6-3.14/arch/arm/mach-prima2/l2x0.c 2014-09-11 18:05:53.898005589 +0200
  30088. @@ -8,43 +8,10 @@
  30089. #include <linux/init.h>
  30090. #include <linux/kernel.h>
  30091. -#include <linux/of.h>
  30092. #include <asm/hardware/cache-l2x0.h>
  30093. -struct l2x0_aux
  30094. -{
  30095. - u32 val;
  30096. - u32 mask;
  30097. -};
  30098. -
  30099. -static struct l2x0_aux prima2_l2x0_aux __initconst = {
  30100. - .val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT,
  30101. - .mask = 0,
  30102. -};
  30103. -
  30104. -static struct l2x0_aux marco_l2x0_aux __initconst = {
  30105. - .val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
  30106. - (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT),
  30107. - .mask = L2X0_AUX_CTRL_MASK,
  30108. -};
  30109. -
  30110. -static struct of_device_id sirf_l2x0_ids[] __initconst = {
  30111. - { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, },
  30112. - { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, },
  30113. - {},
  30114. -};
  30115. -
  30116. static int __init sirfsoc_l2x0_init(void)
  30117. {
  30118. - struct device_node *np;
  30119. - const struct l2x0_aux *aux;
  30120. -
  30121. - np = of_find_matching_node(NULL, sirf_l2x0_ids);
  30122. - if (np) {
  30123. - aux = of_match_node(sirf_l2x0_ids, np)->data;
  30124. - return l2x0_of_init(aux->val, aux->mask);
  30125. - }
  30126. -
  30127. - return 0;
  30128. + return l2x0_of_init(0, ~0);
  30129. }
  30130. early_initcall(sirfsoc_l2x0_init);
  30131. diff -Nur linux-3.14.17/arch/arm/mach-prima2/pm.c linux-imx6-3.14/arch/arm/mach-prima2/pm.c
  30132. --- linux-3.14.17/arch/arm/mach-prima2/pm.c 2014-08-14 03:38:34.000000000 +0200
  30133. +++ linux-imx6-3.14/arch/arm/mach-prima2/pm.c 2014-09-11 18:05:53.898005589 +0200
  30134. @@ -71,7 +71,6 @@
  30135. case PM_SUSPEND_MEM:
  30136. sirfsoc_pre_suspend_power_off();
  30137. - outer_flush_all();
  30138. outer_disable();
  30139. /* go zzz */
  30140. cpu_suspend(0, sirfsoc_finish_suspend);
  30141. diff -Nur linux-3.14.17/arch/arm/mach-realview/realview_eb.c linux-imx6-3.14/arch/arm/mach-realview/realview_eb.c
  30142. --- linux-3.14.17/arch/arm/mach-realview/realview_eb.c 2014-08-14 03:38:34.000000000 +0200
  30143. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_eb.c 2014-09-11 18:05:53.954005813 +0200
  30144. @@ -442,8 +442,13 @@
  30145. realview_eb11mp_fixup();
  30146. #ifdef CONFIG_CACHE_L2X0
  30147. - /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
  30148. - * Bits: .... ...0 0111 1001 0000 .... .... .... */
  30149. + /*
  30150. + * The PL220 needs to be manually configured as the hardware
  30151. + * doesn't report the correct sizes.
  30152. + * 1MB (128KB/way), 8-way associativity, event monitor and
  30153. + * parity enabled, ignore share bit, no force write allocate
  30154. + * Bits: .... ...0 0111 1001 0000 .... .... ....
  30155. + */
  30156. l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
  30157. #endif
  30158. platform_device_register(&pmu_device);
  30159. diff -Nur linux-3.14.17/arch/arm/mach-realview/realview_pb1176.c linux-imx6-3.14/arch/arm/mach-realview/realview_pb1176.c
  30160. --- linux-3.14.17/arch/arm/mach-realview/realview_pb1176.c 2014-08-14 03:38:34.000000000 +0200
  30161. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_pb1176.c 2014-09-11 18:05:53.954005813 +0200
  30162. @@ -355,7 +355,13 @@
  30163. int i;
  30164. #ifdef CONFIG_CACHE_L2X0
  30165. - /* 128Kb (16Kb/way) 8-way associativity. evmon/parity/share enabled. */
  30166. + /*
  30167. + * The PL220 needs to be manually configured as the hardware
  30168. + * doesn't report the correct sizes.
  30169. + * 128kB (16kB/way), 8-way associativity, event monitor and
  30170. + * parity enabled, ignore share bit, no force write allocate
  30171. + * Bits: .... ...0 0111 0011 0000 .... .... ....
  30172. + */
  30173. l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff);
  30174. #endif
  30175. diff -Nur linux-3.14.17/arch/arm/mach-realview/realview_pb11mp.c linux-imx6-3.14/arch/arm/mach-realview/realview_pb11mp.c
  30176. --- linux-3.14.17/arch/arm/mach-realview/realview_pb11mp.c 2014-08-14 03:38:34.000000000 +0200
  30177. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_pb11mp.c 2014-09-11 18:05:53.954005813 +0200
  30178. @@ -337,8 +337,13 @@
  30179. int i;
  30180. #ifdef CONFIG_CACHE_L2X0
  30181. - /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
  30182. - * Bits: .... ...0 0111 1001 0000 .... .... .... */
  30183. + /*
  30184. + * The PL220 needs to be manually configured as the hardware
  30185. + * doesn't report the correct sizes.
  30186. + * 1MB (128KB/way), 8-way associativity, event monitor and
  30187. + * parity enabled, ignore share bit, no force write allocate
  30188. + * Bits: .... ...0 0111 1001 0000 .... .... ....
  30189. + */
  30190. l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
  30191. #endif
  30192. diff -Nur linux-3.14.17/arch/arm/mach-realview/realview_pbx.c linux-imx6-3.14/arch/arm/mach-realview/realview_pbx.c
  30193. --- linux-3.14.17/arch/arm/mach-realview/realview_pbx.c 2014-08-14 03:38:34.000000000 +0200
  30194. +++ linux-imx6-3.14/arch/arm/mach-realview/realview_pbx.c 2014-09-11 18:05:53.958005828 +0200
  30195. @@ -370,8 +370,8 @@
  30196. __io_address(REALVIEW_PBX_TILE_L220_BASE);
  30197. /* set RAM latencies to 1 cycle for eASIC */
  30198. - writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
  30199. - writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
  30200. + writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
  30201. + writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
  30202. /* 16KB way size, 8-way associativity, parity disabled
  30203. * Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
  30204. diff -Nur linux-3.14.17/arch/arm/mach-rockchip/rockchip.c linux-imx6-3.14/arch/arm/mach-rockchip/rockchip.c
  30205. --- linux-3.14.17/arch/arm/mach-rockchip/rockchip.c 2014-08-14 03:38:34.000000000 +0200
  30206. +++ linux-imx6-3.14/arch/arm/mach-rockchip/rockchip.c 2014-09-11 18:05:53.962005845 +0200
  30207. @@ -25,7 +25,7 @@
  30208. static void __init rockchip_dt_init(void)
  30209. {
  30210. - l2x0_of_init(0, ~0UL);
  30211. + l2x0_of_init(0, ~0);
  30212. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  30213. }
  30214. diff -Nur linux-3.14.17/arch/arm/mach-shmobile/board-armadillo800eva.c linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva.c
  30215. --- linux-3.14.17/arch/arm/mach-shmobile/board-armadillo800eva.c 2014-08-14 03:38:34.000000000 +0200
  30216. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva.c 2014-09-11 18:05:54.134006532 +0200
  30217. @@ -1270,8 +1270,8 @@
  30218. #ifdef CONFIG_CACHE_L2X0
  30219. - /* Early BRESP enable, Shared attribute override enable, 32K*8way */
  30220. - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
  30221. + /* Shared attribute override enable, 32K*8way */
  30222. + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
  30223. #endif
  30224. i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
  30225. diff -Nur linux-3.14.17/arch/arm/mach-shmobile/board-armadillo800eva-reference.c linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva-reference.c
  30226. --- linux-3.14.17/arch/arm/mach-shmobile/board-armadillo800eva-reference.c 2014-08-14 03:38:34.000000000 +0200
  30227. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-armadillo800eva-reference.c 2014-09-11 18:05:54.134006532 +0200
  30228. @@ -164,8 +164,8 @@
  30229. r8a7740_meram_workaround();
  30230. #ifdef CONFIG_CACHE_L2X0
  30231. - /* Early BRESP enable, Shared attribute override enable, 32K*8way */
  30232. - l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
  30233. + /* Shared attribute override enable, 32K*8way */
  30234. + l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
  30235. #endif
  30236. r8a7740_add_standard_devices_dt();
  30237. diff -Nur linux-3.14.17/arch/arm/mach-shmobile/board-kzm9g.c linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g.c
  30238. --- linux-3.14.17/arch/arm/mach-shmobile/board-kzm9g.c 2014-08-14 03:38:34.000000000 +0200
  30239. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g.c 2014-09-11 18:05:54.138006549 +0200
  30240. @@ -878,8 +878,8 @@
  30241. gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */
  30242. #ifdef CONFIG_CACHE_L2X0
  30243. - /* Early BRESP enable, Shared attribute override enable, 64K*8way */
  30244. - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
  30245. + /* Shared attribute override enable, 64K*8way */
  30246. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30247. #endif
  30248. i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
  30249. diff -Nur linux-3.14.17/arch/arm/mach-shmobile/board-kzm9g-reference.c linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g-reference.c
  30250. --- linux-3.14.17/arch/arm/mach-shmobile/board-kzm9g-reference.c 2014-08-14 03:38:34.000000000 +0200
  30251. +++ linux-imx6-3.14/arch/arm/mach-shmobile/board-kzm9g-reference.c 2014-09-11 18:05:54.138006549 +0200
  30252. @@ -36,8 +36,8 @@
  30253. sh73a0_add_standard_devices_dt();
  30254. #ifdef CONFIG_CACHE_L2X0
  30255. - /* Early BRESP enable, Shared attribute override enable, 64K*8way */
  30256. - l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
  30257. + /* Shared attribute override enable, 64K*8way */
  30258. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30259. #endif
  30260. }
  30261. diff -Nur linux-3.14.17/arch/arm/mach-shmobile/setup-r8a7778.c linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7778.c
  30262. --- linux-3.14.17/arch/arm/mach-shmobile/setup-r8a7778.c 2014-08-14 03:38:34.000000000 +0200
  30263. +++ linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7778.c 2014-09-11 18:05:54.142006566 +0200
  30264. @@ -298,10 +298,10 @@
  30265. void __iomem *base = ioremap_nocache(0xf0100000, 0x1000);
  30266. if (base) {
  30267. /*
  30268. - * Early BRESP enable, Shared attribute override enable, 64K*16way
  30269. + * Shared attribute override enable, 64K*16way
  30270. * don't call iounmap(base)
  30271. */
  30272. - l2x0_init(base, 0x40470000, 0x82000fff);
  30273. + l2x0_init(base, 0x00400000, 0xc20f0fff);
  30274. }
  30275. #endif
  30276. diff -Nur linux-3.14.17/arch/arm/mach-shmobile/setup-r8a7779.c linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7779.c
  30277. --- linux-3.14.17/arch/arm/mach-shmobile/setup-r8a7779.c 2014-08-14 03:38:34.000000000 +0200
  30278. +++ linux-imx6-3.14/arch/arm/mach-shmobile/setup-r8a7779.c 2014-09-11 18:05:54.142006566 +0200
  30279. @@ -700,8 +700,8 @@
  30280. void __init r8a7779_add_standard_devices(void)
  30281. {
  30282. #ifdef CONFIG_CACHE_L2X0
  30283. - /* Early BRESP enable, Shared attribute override enable, 64K*16way */
  30284. - l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff);
  30285. + /* Shared attribute override enable, 64K*16way */
  30286. + l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
  30287. #endif
  30288. r8a7779_pm_init();
  30289. diff -Nur linux-3.14.17/arch/arm/mach-socfpga/socfpga.c linux-imx6-3.14/arch/arm/mach-socfpga/socfpga.c
  30290. --- linux-3.14.17/arch/arm/mach-socfpga/socfpga.c 2014-08-14 03:38:34.000000000 +0200
  30291. +++ linux-imx6-3.14/arch/arm/mach-socfpga/socfpga.c 2014-09-11 18:05:54.146006581 +0200
  30292. @@ -104,7 +104,7 @@
  30293. static void __init socfpga_cyclone5_init(void)
  30294. {
  30295. - l2x0_of_init(0, ~0UL);
  30296. + l2x0_of_init(0, ~0);
  30297. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  30298. socfpga_init_clocks();
  30299. }
  30300. diff -Nur linux-3.14.17/arch/arm/mach-spear/platsmp.c linux-imx6-3.14/arch/arm/mach-spear/platsmp.c
  30301. --- linux-3.14.17/arch/arm/mach-spear/platsmp.c 2014-08-14 03:38:34.000000000 +0200
  30302. +++ linux-imx6-3.14/arch/arm/mach-spear/platsmp.c 2014-09-11 18:05:54.150006596 +0200
  30303. @@ -20,6 +20,18 @@
  30304. #include <mach/spear.h>
  30305. #include "generic.h"
  30306. +/*
  30307. + * Write pen_release in a way that is guaranteed to be visible to all
  30308. + * observers, irrespective of whether they're taking part in coherency
  30309. + * or not. This is necessary for the hotplug code to work reliably.
  30310. + */
  30311. +static void write_pen_release(int val)
  30312. +{
  30313. + pen_release = val;
  30314. + smp_wmb();
  30315. + sync_cache_w(&pen_release);
  30316. +}
  30317. +
  30318. static DEFINE_SPINLOCK(boot_lock);
  30319. static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
  30320. @@ -30,8 +42,7 @@
  30321. * let the primary processor know we're out of the
  30322. * pen, then head off into the C entry point
  30323. */
  30324. - pen_release = -1;
  30325. - smp_wmb();
  30326. + write_pen_release(-1);
  30327. /*
  30328. * Synchronise with the boot thread.
  30329. @@ -58,9 +69,7 @@
  30330. * Note that "pen_release" is the hardware CPU ID, whereas
  30331. * "cpu" is Linux's internal ID.
  30332. */
  30333. - pen_release = cpu;
  30334. - flush_cache_all();
  30335. - outer_flush_all();
  30336. + write_pen_release(cpu);
  30337. timeout = jiffies + (1 * HZ);
  30338. while (time_before(jiffies, timeout)) {
  30339. diff -Nur linux-3.14.17/arch/arm/mach-spear/spear13xx.c linux-imx6-3.14/arch/arm/mach-spear/spear13xx.c
  30340. --- linux-3.14.17/arch/arm/mach-spear/spear13xx.c 2014-08-14 03:38:34.000000000 +0200
  30341. +++ linux-imx6-3.14/arch/arm/mach-spear/spear13xx.c 2014-09-11 18:05:54.150006596 +0200
  30342. @@ -38,15 +38,15 @@
  30343. if (!IS_ENABLED(CONFIG_CACHE_L2X0))
  30344. return;
  30345. - writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
  30346. + writel_relaxed(0x06, VA_L2CC_BASE + L310_PREFETCH_CTRL);
  30347. /*
  30348. * Program following latencies in order to make
  30349. * SPEAr1340 work at 600 MHz
  30350. */
  30351. - writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
  30352. - writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
  30353. - l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
  30354. + writel_relaxed(0x221, VA_L2CC_BASE + L310_TAG_LATENCY_CTRL);
  30355. + writel_relaxed(0x441, VA_L2CC_BASE + L310_DATA_LATENCY_CTRL);
  30356. + l2x0_init(VA_L2CC_BASE, 0x30a00001, 0xfe0fffff);
  30357. }
  30358. /*
  30359. diff -Nur linux-3.14.17/arch/arm/mach-sti/board-dt.c linux-imx6-3.14/arch/arm/mach-sti/board-dt.c
  30360. --- linux-3.14.17/arch/arm/mach-sti/board-dt.c 2014-08-14 03:38:34.000000000 +0200
  30361. +++ linux-imx6-3.14/arch/arm/mach-sti/board-dt.c 2014-09-11 18:05:54.178006708 +0200
  30362. @@ -16,15 +16,9 @@
  30363. void __init stih41x_l2x0_init(void)
  30364. {
  30365. - u32 way_size = 0x4;
  30366. - u32 aux_ctrl;
  30367. - /* may be this can be encoded in macros like BIT*() */
  30368. - aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
  30369. - (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
  30370. - (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
  30371. - (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30372. -
  30373. - l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
  30374. + l2x0_of_init(L2C_AUX_CTRL_SHARED_OVERRIDE |
  30375. + L310_AUX_CTRL_DATA_PREFETCH |
  30376. + L310_AUX_CTRL_INSTR_PREFETCH, 0xc00f0fff);
  30377. }
  30378. static void __init stih41x_machine_init(void)
  30379. diff -Nur linux-3.14.17/arch/arm/mach-tegra/pm.h linux-imx6-3.14/arch/arm/mach-tegra/pm.h
  30380. --- linux-3.14.17/arch/arm/mach-tegra/pm.h 2014-08-14 03:38:34.000000000 +0200
  30381. +++ linux-imx6-3.14/arch/arm/mach-tegra/pm.h 2014-09-11 18:05:54.206006821 +0200
  30382. @@ -35,8 +35,6 @@
  30383. void tegra30_lp1_iram_hook(void);
  30384. void tegra30_sleep_core_init(void);
  30385. -extern unsigned long l2x0_saved_regs_addr;
  30386. -
  30387. void tegra_clear_cpu_in_lp2(void);
  30388. bool tegra_set_cpu_in_lp2(void);
  30389. diff -Nur linux-3.14.17/arch/arm/mach-tegra/reset-handler.S linux-imx6-3.14/arch/arm/mach-tegra/reset-handler.S
  30390. --- linux-3.14.17/arch/arm/mach-tegra/reset-handler.S 2014-08-14 03:38:34.000000000 +0200
  30391. +++ linux-imx6-3.14/arch/arm/mach-tegra/reset-handler.S 2014-09-11 18:05:54.206006821 +0200
  30392. @@ -19,7 +19,6 @@
  30393. #include <asm/cache.h>
  30394. #include <asm/asm-offsets.h>
  30395. -#include <asm/hardware/cache-l2x0.h>
  30396. #include "flowctrl.h"
  30397. #include "fuse.h"
  30398. @@ -78,8 +77,10 @@
  30399. str r1, [r0]
  30400. #endif
  30401. +#ifdef CONFIG_CACHE_L2X0
  30402. /* L2 cache resume & re-enable */
  30403. - l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
  30404. + bl l2c310_early_resume
  30405. +#endif
  30406. end_ca9_scu_l2_resume:
  30407. mov32 r9, 0xc0f
  30408. cmp r8, r9
  30409. @@ -89,12 +90,6 @@
  30410. ENDPROC(tegra_resume)
  30411. #endif
  30412. -#ifdef CONFIG_CACHE_L2X0
  30413. - .globl l2x0_saved_regs_addr
  30414. -l2x0_saved_regs_addr:
  30415. - .long 0
  30416. -#endif
  30417. -
  30418. .align L1_CACHE_SHIFT
  30419. ENTRY(__tegra_cpu_reset_handler_start)
  30420. diff -Nur linux-3.14.17/arch/arm/mach-tegra/sleep.h linux-imx6-3.14/arch/arm/mach-tegra/sleep.h
  30421. --- linux-3.14.17/arch/arm/mach-tegra/sleep.h 2014-08-14 03:38:34.000000000 +0200
  30422. +++ linux-imx6-3.14/arch/arm/mach-tegra/sleep.h 2014-09-11 18:05:54.218006868 +0200
  30423. @@ -120,37 +120,6 @@
  30424. mov \tmp1, \tmp1, lsr #8
  30425. .endm
  30426. -/* Macro to resume & re-enable L2 cache */
  30427. -#ifndef L2X0_CTRL_EN
  30428. -#define L2X0_CTRL_EN 1
  30429. -#endif
  30430. -
  30431. -#ifdef CONFIG_CACHE_L2X0
  30432. -.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
  30433. - W(adr) \tmp1, \phys_l2x0_saved_regs
  30434. - ldr \tmp1, [\tmp1]
  30435. - ldr \tmp2, [\tmp1, #L2X0_R_PHY_BASE]
  30436. - ldr \tmp3, [\tmp2, #L2X0_CTRL]
  30437. - tst \tmp3, #L2X0_CTRL_EN
  30438. - bne exit_l2_resume
  30439. - ldr \tmp3, [\tmp1, #L2X0_R_TAG_LATENCY]
  30440. - str \tmp3, [\tmp2, #L2X0_TAG_LATENCY_CTRL]
  30441. - ldr \tmp3, [\tmp1, #L2X0_R_DATA_LATENCY]
  30442. - str \tmp3, [\tmp2, #L2X0_DATA_LATENCY_CTRL]
  30443. - ldr \tmp3, [\tmp1, #L2X0_R_PREFETCH_CTRL]
  30444. - str \tmp3, [\tmp2, #L2X0_PREFETCH_CTRL]
  30445. - ldr \tmp3, [\tmp1, #L2X0_R_PWR_CTRL]
  30446. - str \tmp3, [\tmp2, #L2X0_POWER_CTRL]
  30447. - ldr \tmp3, [\tmp1, #L2X0_R_AUX_CTRL]
  30448. - str \tmp3, [\tmp2, #L2X0_AUX_CTRL]
  30449. - mov \tmp3, #L2X0_CTRL_EN
  30450. - str \tmp3, [\tmp2, #L2X0_CTRL]
  30451. -exit_l2_resume:
  30452. -.endm
  30453. -#else /* CONFIG_CACHE_L2X0 */
  30454. -.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
  30455. -.endm
  30456. -#endif /* CONFIG_CACHE_L2X0 */
  30457. #else
  30458. void tegra_pen_lock(void);
  30459. void tegra_pen_unlock(void);
  30460. diff -Nur linux-3.14.17/arch/arm/mach-tegra/tegra.c linux-imx6-3.14/arch/arm/mach-tegra/tegra.c
  30461. --- linux-3.14.17/arch/arm/mach-tegra/tegra.c 2014-08-14 03:38:34.000000000 +0200
  30462. +++ linux-imx6-3.14/arch/arm/mach-tegra/tegra.c 2014-09-11 18:05:54.218006868 +0200
  30463. @@ -73,27 +73,7 @@
  30464. static void __init tegra_init_cache(void)
  30465. {
  30466. #ifdef CONFIG_CACHE_L2X0
  30467. - static const struct of_device_id pl310_ids[] __initconst = {
  30468. - { .compatible = "arm,pl310-cache", },
  30469. - {}
  30470. - };
  30471. -
  30472. - struct device_node *np;
  30473. - int ret;
  30474. - void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
  30475. - u32 aux_ctrl, cache_type;
  30476. -
  30477. - np = of_find_matching_node(NULL, pl310_ids);
  30478. - if (!np)
  30479. - return;
  30480. -
  30481. - cache_type = readl(p + L2X0_CACHE_TYPE);
  30482. - aux_ctrl = (cache_type & 0x700) << (17-8);
  30483. - aux_ctrl |= 0x7C400001;
  30484. -
  30485. - ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
  30486. - if (!ret)
  30487. - l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
  30488. + l2x0_of_init(0x3c400001, 0xc20fc3fe);
  30489. #endif
  30490. }
  30491. diff -Nur linux-3.14.17/arch/arm/mach-ux500/board-mop500-audio.c linux-imx6-3.14/arch/arm/mach-ux500/board-mop500-audio.c
  30492. --- linux-3.14.17/arch/arm/mach-ux500/board-mop500-audio.c 2014-08-14 03:38:34.000000000 +0200
  30493. +++ linux-imx6-3.14/arch/arm/mach-ux500/board-mop500-audio.c 2014-09-11 18:05:54.230006916 +0200
  30494. @@ -9,7 +9,6 @@
  30495. #include <linux/gpio.h>
  30496. #include <linux/platform_data/dma-ste-dma40.h>
  30497. -#include "irqs.h"
  30498. #include <linux/platform_data/asoc-ux500-msp.h>
  30499. #include "ste-dma40-db8500.h"
  30500. diff -Nur linux-3.14.17/arch/arm/mach-ux500/cache-l2x0.c linux-imx6-3.14/arch/arm/mach-ux500/cache-l2x0.c
  30501. --- linux-3.14.17/arch/arm/mach-ux500/cache-l2x0.c 2014-08-14 03:38:34.000000000 +0200
  30502. +++ linux-imx6-3.14/arch/arm/mach-ux500/cache-l2x0.c 2014-09-11 18:05:54.230006916 +0200
  30503. @@ -35,10 +35,16 @@
  30504. return 0;
  30505. }
  30506. -static int __init ux500_l2x0_init(void)
  30507. +static void ux500_l2c310_write_sec(unsigned long val, unsigned reg)
  30508. {
  30509. - u32 aux_val = 0x3e000000;
  30510. + /*
  30511. + * We can't write to secure registers as we are in non-secure
  30512. + * mode, until we have some SMI service available.
  30513. + */
  30514. +}
  30515. +static int __init ux500_l2x0_init(void)
  30516. +{
  30517. if (cpu_is_u8500_family() || cpu_is_ux540_family())
  30518. l2x0_base = __io_address(U8500_L2CC_BASE);
  30519. else
  30520. @@ -48,28 +54,12 @@
  30521. /* Unlock before init */
  30522. ux500_l2x0_unlock();
  30523. - /* DBx540's L2 has 128KB way size */
  30524. - if (cpu_is_ux540_family())
  30525. - /* 128KB way size */
  30526. - aux_val |= (0x4 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30527. - else
  30528. - /* 64KB way size */
  30529. - aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
  30530. + outer_cache.write_sec = ux500_l2c310_write_sec;
  30531. - /* 64KB way size, 8 way associativity, force WA */
  30532. if (of_have_populated_dt())
  30533. - l2x0_of_init(aux_val, 0xc0000fff);
  30534. + l2x0_of_init(0, ~0);
  30535. else
  30536. - l2x0_init(l2x0_base, aux_val, 0xc0000fff);
  30537. -
  30538. - /*
  30539. - * We can't disable l2 as we are in non secure mode, currently
  30540. - * this seems be called only during kexec path. So let's
  30541. - * override outer.disable with nasty assignment until we have
  30542. - * some SMI service available.
  30543. - */
  30544. - outer_cache.disable = NULL;
  30545. - outer_cache.set_debug = NULL;
  30546. + l2x0_init(l2x0_base, 0, ~0);
  30547. return 0;
  30548. }
  30549. diff -Nur linux-3.14.17/arch/arm/mach-ux500/cpu-db8500.c linux-imx6-3.14/arch/arm/mach-ux500/cpu-db8500.c
  30550. --- linux-3.14.17/arch/arm/mach-ux500/cpu-db8500.c 2014-08-14 03:38:34.000000000 +0200
  30551. +++ linux-imx6-3.14/arch/arm/mach-ux500/cpu-db8500.c 2014-09-11 18:05:54.230006916 +0200
  30552. @@ -27,7 +27,6 @@
  30553. #include <asm/mach/map.h>
  30554. #include "setup.h"
  30555. -#include "irqs.h"
  30556. #include "board-mop500-regulators.h"
  30557. #include "board-mop500.h"
  30558. @@ -35,14 +34,11 @@
  30559. #include "id.h"
  30560. struct ab8500_platform_data ab8500_platdata = {
  30561. - .irq_base = MOP500_AB8500_IRQ_BASE,
  30562. .regulator = &ab8500_regulator_plat_data,
  30563. };
  30564. struct prcmu_pdata db8500_prcmu_pdata = {
  30565. .ab_platdata = &ab8500_platdata,
  30566. - .ab_irq = IRQ_DB8500_AB8500,
  30567. - .irq_base = IRQ_PRCMU_BASE,
  30568. .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET,
  30569. .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET,
  30570. };
  30571. diff -Nur linux-3.14.17/arch/arm/mach-ux500/irqs-board-mop500.h linux-imx6-3.14/arch/arm/mach-ux500/irqs-board-mop500.h
  30572. --- linux-3.14.17/arch/arm/mach-ux500/irqs-board-mop500.h 2014-08-14 03:38:34.000000000 +0200
  30573. +++ linux-imx6-3.14/arch/arm/mach-ux500/irqs-board-mop500.h 1970-01-01 01:00:00.000000000 +0100
  30574. @@ -1,55 +0,0 @@
  30575. -/*
  30576. - * Copyright (C) ST-Ericsson SA 2010
  30577. - *
  30578. - * Author: Rabin Vincent <rabin.vincent@stericsson.com>
  30579. - * License terms: GNU General Public License (GPL) version 2
  30580. - */
  30581. -
  30582. -#ifndef __MACH_IRQS_BOARD_MOP500_H
  30583. -#define __MACH_IRQS_BOARD_MOP500_H
  30584. -
  30585. -/* Number of AB8500 irqs is taken from header file */
  30586. -#include <linux/mfd/abx500/ab8500.h>
  30587. -
  30588. -#define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START
  30589. -#define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \
  30590. - + AB8500_MAX_NR_IRQS)
  30591. -
  30592. -/* TC35892 */
  30593. -#define TC35892_NR_INTERNAL_IRQS 8
  30594. -#define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x))
  30595. -#define TC35892_NR_GPIOS 24
  30596. -#define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS)
  30597. -
  30598. -#define MOP500_EGPIO_NR_IRQS TC35892_NR_IRQS
  30599. -
  30600. -#define MOP500_EGPIO_IRQ_BASE MOP500_AB8500_IRQ_END
  30601. -#define MOP500_EGPIO_IRQ_END (MOP500_EGPIO_IRQ_BASE \
  30602. - + MOP500_EGPIO_NR_IRQS)
  30603. -/* STMPE1601 irqs */
  30604. -#define STMPE_NR_INTERNAL_IRQS 9
  30605. -#define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x))
  30606. -#define STMPE_NR_GPIOS 24
  30607. -#define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS)
  30608. -
  30609. -#define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END
  30610. -#define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x))
  30611. -
  30612. -#define MOP500_STMPE1601_IRQ_END \
  30613. - MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
  30614. -
  30615. -#define MOP500_NR_IRQS MOP500_STMPE1601_IRQ_END
  30616. -
  30617. -#define MOP500_IRQ_END MOP500_NR_IRQS
  30618. -
  30619. -/*
  30620. - * We may have several boards, but only one will run at a
  30621. - * time, so the one with most IRQs will bump this ahead,
  30622. - * but the IRQ_BOARD_START remains the same for either board.
  30623. - */
  30624. -#if MOP500_IRQ_END > IRQ_BOARD_END
  30625. -#undef IRQ_BOARD_END
  30626. -#define IRQ_BOARD_END MOP500_IRQ_END
  30627. -#endif
  30628. -
  30629. -#endif
  30630. diff -Nur linux-3.14.17/arch/arm/mach-ux500/irqs-db8500.h linux-imx6-3.14/arch/arm/mach-ux500/irqs-db8500.h
  30631. --- linux-3.14.17/arch/arm/mach-ux500/irqs-db8500.h 2014-08-14 03:38:34.000000000 +0200
  30632. +++ linux-imx6-3.14/arch/arm/mach-ux500/irqs-db8500.h 1970-01-01 01:00:00.000000000 +0100
  30633. @@ -1,125 +0,0 @@
  30634. -/*
  30635. - * Copyright (C) ST-Ericsson SA 2010
  30636. - *
  30637. - * Author: Rabin Vincent <rabin.vincent@stericsson.com>
  30638. - * License terms: GNU General Public License (GPL) version 2
  30639. - */
  30640. -
  30641. -#ifndef __MACH_IRQS_DB8500_H
  30642. -#define __MACH_IRQS_DB8500_H
  30643. -
  30644. -#define IRQ_DB8500_MTU0 (IRQ_SHPI_START + 4)
  30645. -#define IRQ_DB8500_SPI2 (IRQ_SHPI_START + 6)
  30646. -#define IRQ_DB8500_PMU (IRQ_SHPI_START + 7)
  30647. -#define IRQ_DB8500_SPI0 (IRQ_SHPI_START + 8)
  30648. -#define IRQ_DB8500_RTT (IRQ_SHPI_START + 9)
  30649. -#define IRQ_DB8500_PKA (IRQ_SHPI_START + 10)
  30650. -#define IRQ_DB8500_UART0 (IRQ_SHPI_START + 11)
  30651. -#define IRQ_DB8500_I2C3 (IRQ_SHPI_START + 12)
  30652. -#define IRQ_DB8500_L2CC (IRQ_SHPI_START + 13)
  30653. -#define IRQ_DB8500_SSP0 (IRQ_SHPI_START + 14)
  30654. -#define IRQ_DB8500_CRYP1 (IRQ_SHPI_START + 15)
  30655. -#define IRQ_DB8500_MSP1_RX (IRQ_SHPI_START + 16)
  30656. -#define IRQ_DB8500_MTU1 (IRQ_SHPI_START + 17)
  30657. -#define IRQ_DB8500_RTC (IRQ_SHPI_START + 18)
  30658. -#define IRQ_DB8500_UART1 (IRQ_SHPI_START + 19)
  30659. -#define IRQ_DB8500_USB_WAKEUP (IRQ_SHPI_START + 20)
  30660. -#define IRQ_DB8500_I2C0 (IRQ_SHPI_START + 21)
  30661. -#define IRQ_DB8500_I2C1 (IRQ_SHPI_START + 22)
  30662. -#define IRQ_DB8500_USBOTG (IRQ_SHPI_START + 23)
  30663. -#define IRQ_DB8500_DMA_SECURE (IRQ_SHPI_START + 24)
  30664. -#define IRQ_DB8500_DMA (IRQ_SHPI_START + 25)
  30665. -#define IRQ_DB8500_UART2 (IRQ_SHPI_START + 26)
  30666. -#define IRQ_DB8500_ICN_PMU1 (IRQ_SHPI_START + 27)
  30667. -#define IRQ_DB8500_ICN_PMU2 (IRQ_SHPI_START + 28)
  30668. -#define IRQ_DB8500_HSIR_EXCEP (IRQ_SHPI_START + 29)
  30669. -#define IRQ_DB8500_MSP0 (IRQ_SHPI_START + 31)
  30670. -#define IRQ_DB8500_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32)
  30671. -#define IRQ_DB8500_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33)
  30672. -#define IRQ_DB8500_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34)
  30673. -#define IRQ_DB8500_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35)
  30674. -#define IRQ_DB8500_HSIR_CH4_OVRRUN (IRQ_SHPI_START + 36)
  30675. -#define IRQ_DB8500_HSIR_CH5_OVRRUN (IRQ_SHPI_START + 37)
  30676. -#define IRQ_DB8500_HSIR_CH6_OVRRUN (IRQ_SHPI_START + 38)
  30677. -#define IRQ_DB8500_HSIR_CH7_OVRRUN (IRQ_SHPI_START + 39)
  30678. -#define IRQ_DB8500_AB8500 (IRQ_SHPI_START + 40)
  30679. -#define IRQ_DB8500_SDMMC2 (IRQ_SHPI_START + 41)
  30680. -#define IRQ_DB8500_SIA (IRQ_SHPI_START + 42)
  30681. -#define IRQ_DB8500_SIA2 (IRQ_SHPI_START + 43)
  30682. -#define IRQ_DB8500_SVA (IRQ_SHPI_START + 44)
  30683. -#define IRQ_DB8500_SVA2 (IRQ_SHPI_START + 45)
  30684. -#define IRQ_DB8500_PRCMU0 (IRQ_SHPI_START + 46)
  30685. -#define IRQ_DB8500_PRCMU1 (IRQ_SHPI_START + 47)
  30686. -#define IRQ_DB8500_DISP (IRQ_SHPI_START + 48)
  30687. -#define IRQ_DB8500_SPI3 (IRQ_SHPI_START + 49)
  30688. -#define IRQ_DB8500_SDMMC1 (IRQ_SHPI_START + 50)
  30689. -#define IRQ_DB8500_I2C4 (IRQ_SHPI_START + 51)
  30690. -#define IRQ_DB8500_SSP1 (IRQ_SHPI_START + 52)
  30691. -#define IRQ_DB8500_SKE (IRQ_SHPI_START + 53)
  30692. -#define IRQ_DB8500_KB (IRQ_SHPI_START + 54)
  30693. -#define IRQ_DB8500_I2C2 (IRQ_SHPI_START + 55)
  30694. -#define IRQ_DB8500_B2R2 (IRQ_SHPI_START + 56)
  30695. -#define IRQ_DB8500_CRYP0 (IRQ_SHPI_START + 57)
  30696. -#define IRQ_DB8500_SDMMC3 (IRQ_SHPI_START + 59)
  30697. -#define IRQ_DB8500_SDMMC0 (IRQ_SHPI_START + 60)
  30698. -#define IRQ_DB8500_HSEM (IRQ_SHPI_START + 61)
  30699. -#define IRQ_DB8500_MSP1 (IRQ_SHPI_START + 62)
  30700. -#define IRQ_DB8500_SBAG (IRQ_SHPI_START + 63)
  30701. -#define IRQ_DB8500_SPI1 (IRQ_SHPI_START + 96)
  30702. -#define IRQ_DB8500_SRPTIMER (IRQ_SHPI_START + 97)
  30703. -#define IRQ_DB8500_MSP2 (IRQ_SHPI_START + 98)
  30704. -#define IRQ_DB8500_SDMMC4 (IRQ_SHPI_START + 99)
  30705. -#define IRQ_DB8500_SDMMC5 (IRQ_SHPI_START + 100)
  30706. -#define IRQ_DB8500_HSIRD0 (IRQ_SHPI_START + 104)
  30707. -#define IRQ_DB8500_HSIRD1 (IRQ_SHPI_START + 105)
  30708. -#define IRQ_DB8500_HSITD0 (IRQ_SHPI_START + 106)
  30709. -#define IRQ_DB8500_HSITD1 (IRQ_SHPI_START + 107)
  30710. -#define IRQ_DB8500_CTI0 (IRQ_SHPI_START + 108)
  30711. -#define IRQ_DB8500_CTI1 (IRQ_SHPI_START + 109)
  30712. -#define IRQ_DB8500_ICN_ERR (IRQ_SHPI_START + 110)
  30713. -#define IRQ_DB8500_MALI_PPMMU (IRQ_SHPI_START + 112)
  30714. -#define IRQ_DB8500_MALI_PP (IRQ_SHPI_START + 113)
  30715. -#define IRQ_DB8500_MALI_GPMMU (IRQ_SHPI_START + 114)
  30716. -#define IRQ_DB8500_MALI_GP (IRQ_SHPI_START + 115)
  30717. -#define IRQ_DB8500_MALI (IRQ_SHPI_START + 116)
  30718. -#define IRQ_DB8500_PRCMU_SEM (IRQ_SHPI_START + 118)
  30719. -#define IRQ_DB8500_GPIO0 (IRQ_SHPI_START + 119)
  30720. -#define IRQ_DB8500_GPIO1 (IRQ_SHPI_START + 120)
  30721. -#define IRQ_DB8500_GPIO2 (IRQ_SHPI_START + 121)
  30722. -#define IRQ_DB8500_GPIO3 (IRQ_SHPI_START + 122)
  30723. -#define IRQ_DB8500_GPIO4 (IRQ_SHPI_START + 123)
  30724. -#define IRQ_DB8500_GPIO5 (IRQ_SHPI_START + 124)
  30725. -#define IRQ_DB8500_GPIO6 (IRQ_SHPI_START + 125)
  30726. -#define IRQ_DB8500_GPIO7 (IRQ_SHPI_START + 126)
  30727. -#define IRQ_DB8500_GPIO8 (IRQ_SHPI_START + 127)
  30728. -
  30729. -#define IRQ_CA_WAKE_REQ_ED (IRQ_SHPI_START + 71)
  30730. -#define IRQ_AC_READ_NOTIFICATION_0_ED (IRQ_SHPI_START + 66)
  30731. -#define IRQ_AC_READ_NOTIFICATION_1_ED (IRQ_SHPI_START + 64)
  30732. -#define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED (IRQ_SHPI_START + 67)
  30733. -#define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED (IRQ_SHPI_START + 65)
  30734. -
  30735. -#define IRQ_CA_WAKE_REQ_V1 (IRQ_SHPI_START + 83)
  30736. -#define IRQ_AC_READ_NOTIFICATION_0_V1 (IRQ_SHPI_START + 78)
  30737. -#define IRQ_AC_READ_NOTIFICATION_1_V1 (IRQ_SHPI_START + 76)
  30738. -#define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1 (IRQ_SHPI_START + 79)
  30739. -#define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1 (IRQ_SHPI_START + 77)
  30740. -
  30741. -#ifdef CONFIG_UX500_SOC_DB8500
  30742. -
  30743. -/* Virtual interrupts corresponding to the PRCMU wakeups. */
  30744. -#define IRQ_PRCMU_BASE IRQ_SOC_START
  30745. -#define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23)
  30746. -
  30747. -/*
  30748. - * We may have several SoCs, but only one will run at a
  30749. - * time, so the one with most IRQs will bump this ahead,
  30750. - * but the IRQ_SOC_START remains the same for either SoC.
  30751. - */
  30752. -#if IRQ_SOC_END < IRQ_PRCMU_END
  30753. -#undef IRQ_SOC_END
  30754. -#define IRQ_SOC_END IRQ_PRCMU_END
  30755. -#endif
  30756. -
  30757. -#endif /* CONFIG_UX500_SOC_DB8500 */
  30758. -#endif
  30759. diff -Nur linux-3.14.17/arch/arm/mach-ux500/irqs.h linux-imx6-3.14/arch/arm/mach-ux500/irqs.h
  30760. --- linux-3.14.17/arch/arm/mach-ux500/irqs.h 2014-08-14 03:38:34.000000000 +0200
  30761. +++ linux-imx6-3.14/arch/arm/mach-ux500/irqs.h 1970-01-01 01:00:00.000000000 +0100
  30762. @@ -1,49 +0,0 @@
  30763. -/*
  30764. - * Copyright (C) 2008 STMicroelectronics
  30765. - * Copyright (C) 2009 ST-Ericsson.
  30766. - *
  30767. - * This program is free software; you can redistribute it and/or modify
  30768. - * it under the terms of the GNU General Public License as published by
  30769. - * the Free Software Foundation; either version 2 of the License, or
  30770. - * (at your option) any later version.
  30771. - */
  30772. -#ifndef ASM_ARCH_IRQS_H
  30773. -#define ASM_ARCH_IRQS_H
  30774. -
  30775. -#define IRQ_LOCALTIMER 29
  30776. -#define IRQ_LOCALWDOG 30
  30777. -
  30778. -/* Shared Peripheral Interrupt (SHPI) */
  30779. -#define IRQ_SHPI_START 32
  30780. -
  30781. -/*
  30782. - * MTU0 preserved for now until plat-nomadik is taught not to use it. Don't
  30783. - * add any other IRQs here, use the irqs-dbx500.h files.
  30784. - */
  30785. -#define IRQ_MTU0 (IRQ_SHPI_START + 4)
  30786. -
  30787. -#define DBX500_NR_INTERNAL_IRQS 166
  30788. -
  30789. -/* After chip-specific IRQ numbers we have the GPIO ones */
  30790. -#define NOMADIK_NR_GPIO 288
  30791. -#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS)
  30792. -#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - DBX500_NR_INTERNAL_IRQS)
  30793. -#define IRQ_GPIO_END NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
  30794. -
  30795. -#define IRQ_SOC_START IRQ_GPIO_END
  30796. -/* This will be overridden by SoC-specific irq headers */
  30797. -#define IRQ_SOC_END IRQ_SOC_START
  30798. -
  30799. -#include "irqs-db8500.h"
  30800. -
  30801. -#define IRQ_BOARD_START IRQ_SOC_END
  30802. -/* This will be overridden by board-specific irq headers */
  30803. -#define IRQ_BOARD_END IRQ_BOARD_START
  30804. -
  30805. -#ifdef CONFIG_MACH_MOP500
  30806. -#include "irqs-board-mop500.h"
  30807. -#endif
  30808. -
  30809. -#define UX500_NR_IRQS IRQ_BOARD_END
  30810. -
  30811. -#endif /* ASM_ARCH_IRQS_H */
  30812. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/ct-ca9x4.c linux-imx6-3.14/arch/arm/mach-vexpress/ct-ca9x4.c
  30813. --- linux-3.14.17/arch/arm/mach-vexpress/ct-ca9x4.c 2014-08-14 03:38:34.000000000 +0200
  30814. +++ linux-imx6-3.14/arch/arm/mach-vexpress/ct-ca9x4.c 2014-09-11 18:05:54.266007061 +0200
  30815. @@ -45,6 +45,23 @@
  30816. iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
  30817. }
  30818. +static void __init ca9x4_l2_init(void)
  30819. +{
  30820. +#ifdef CONFIG_CACHE_L2X0
  30821. + void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
  30822. +
  30823. + if (l2x0_base) {
  30824. + /* set RAM latencies to 1 cycle for this core tile. */
  30825. + writel(0, l2x0_base + L310_TAG_LATENCY_CTRL);
  30826. + writel(0, l2x0_base + L310_DATA_LATENCY_CTRL);
  30827. +
  30828. + l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
  30829. + } else {
  30830. + pr_err("L2C: unable to map L2 cache controller\n");
  30831. + }
  30832. +#endif
  30833. +}
  30834. +
  30835. #ifdef CONFIG_HAVE_ARM_TWD
  30836. static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
  30837. @@ -63,6 +80,7 @@
  30838. gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
  30839. ioremap(A9_MPCORE_GIC_CPU, SZ_256));
  30840. ca9x4_twd_init();
  30841. + ca9x4_l2_init();
  30842. }
  30843. static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
  30844. @@ -141,16 +159,6 @@
  30845. {
  30846. int i;
  30847. -#ifdef CONFIG_CACHE_L2X0
  30848. - void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
  30849. -
  30850. - /* set RAM latencies to 1 cycle for this core tile. */
  30851. - writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
  30852. - writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
  30853. -
  30854. - l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
  30855. -#endif
  30856. -
  30857. for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
  30858. amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
  30859. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/dcscb.c linux-imx6-3.14/arch/arm/mach-vexpress/dcscb.c
  30860. --- linux-3.14.17/arch/arm/mach-vexpress/dcscb.c 2014-08-14 03:38:34.000000000 +0200
  30861. +++ linux-imx6-3.14/arch/arm/mach-vexpress/dcscb.c 2014-09-11 18:05:54.266007061 +0200
  30862. @@ -23,6 +23,7 @@
  30863. #include <asm/cacheflush.h>
  30864. #include <asm/cputype.h>
  30865. #include <asm/cp15.h>
  30866. +#include <asm/psci.h>
  30867. #define RST_HOLD0 0x0
  30868. @@ -193,6 +194,12 @@
  30869. unsigned int cfg;
  30870. int ret;
  30871. + ret = psci_probe();
  30872. + if (!ret) {
  30873. + pr_debug("psci found. Aborting native init\n");
  30874. + return -ENODEV;
  30875. + }
  30876. +
  30877. if (!cci_probed())
  30878. return -ENODEV;
  30879. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/Kconfig linux-imx6-3.14/arch/arm/mach-vexpress/Kconfig
  30880. --- linux-3.14.17/arch/arm/mach-vexpress/Kconfig 2014-08-14 03:38:34.000000000 +0200
  30881. +++ linux-imx6-3.14/arch/arm/mach-vexpress/Kconfig 2014-09-11 18:05:54.266007061 +0200
  30882. @@ -55,6 +55,7 @@
  30883. config ARCH_VEXPRESS_CA9X4
  30884. bool "Versatile Express Cortex-A9x4 tile"
  30885. + select ARM_ERRATA_643719
  30886. config ARCH_VEXPRESS_DCSCB
  30887. bool "Dual Cluster System Control Block (DCSCB) support"
  30888. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/Makefile linux-imx6-3.14/arch/arm/mach-vexpress/Makefile
  30889. --- linux-3.14.17/arch/arm/mach-vexpress/Makefile 2014-08-14 03:38:34.000000000 +0200
  30890. +++ linux-imx6-3.14/arch/arm/mach-vexpress/Makefile 2014-09-11 18:05:54.266007061 +0200
  30891. @@ -8,8 +8,15 @@
  30892. obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
  30893. obj-$(CONFIG_ARCH_VEXPRESS_DCSCB) += dcscb.o dcscb_setup.o
  30894. CFLAGS_dcscb.o += -march=armv7-a
  30895. +CFLAGS_REMOVE_dcscb.o = -pg
  30896. obj-$(CONFIG_ARCH_VEXPRESS_SPC) += spc.o
  30897. +CFLAGS_REMOVE_spc.o = -pg
  30898. obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
  30899. CFLAGS_tc2_pm.o += -march=armv7-a
  30900. +CFLAGS_REMOVE_tc2_pm.o = -pg
  30901. +ifeq ($(CONFIG_ARCH_VEXPRESS_TC2_PM),y)
  30902. +obj-$(CONFIG_ARM_PSCI) += tc2_pm_psci.o
  30903. +CFLAGS_REMOVE_tc2_pm_psci.o = -pg
  30904. +endif
  30905. obj-$(CONFIG_SMP) += platsmp.o
  30906. obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
  30907. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/spc.c linux-imx6-3.14/arch/arm/mach-vexpress/spc.c
  30908. --- linux-3.14.17/arch/arm/mach-vexpress/spc.c 2014-08-14 03:38:34.000000000 +0200
  30909. +++ linux-imx6-3.14/arch/arm/mach-vexpress/spc.c 2014-09-11 18:05:54.270007076 +0200
  30910. @@ -392,7 +392,7 @@
  30911. * +--------------------------+
  30912. * | 31 20 | 19 0 |
  30913. * +--------------------------+
  30914. - * | u_volt | freq(kHz) |
  30915. + * | m_volt | freq(kHz) |
  30916. * +--------------------------+
  30917. */
  30918. #define MULT_FACTOR 20
  30919. @@ -414,7 +414,7 @@
  30920. ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
  30921. if (!ret) {
  30922. opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
  30923. - opps->u_volt = data >> VOLT_SHIFT;
  30924. + opps->u_volt = (data >> VOLT_SHIFT) * 1000;
  30925. } else {
  30926. break;
  30927. }
  30928. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/tc2_pm.c linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm.c
  30929. --- linux-3.14.17/arch/arm/mach-vexpress/tc2_pm.c 2014-08-14 03:38:34.000000000 +0200
  30930. +++ linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm.c 2014-09-11 18:05:54.270007076 +0200
  30931. @@ -27,6 +27,7 @@
  30932. #include <asm/cacheflush.h>
  30933. #include <asm/cputype.h>
  30934. #include <asm/cp15.h>
  30935. +#include <asm/psci.h>
  30936. #include <linux/arm-cci.h>
  30937. @@ -329,6 +330,12 @@
  30938. u32 a15_cluster_id, a7_cluster_id, sys_info;
  30939. struct device_node *np;
  30940. + ret = psci_probe();
  30941. + if (!ret) {
  30942. + pr_debug("psci found. Aborting native init\n");
  30943. + return -ENODEV;
  30944. + }
  30945. +
  30946. /*
  30947. * The power management-related features are hidden behind
  30948. * SCC registers. We need to extract runtime information like
  30949. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/tc2_pm_psci.c linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm_psci.c
  30950. --- linux-3.14.17/arch/arm/mach-vexpress/tc2_pm_psci.c 1970-01-01 01:00:00.000000000 +0100
  30951. +++ linux-imx6-3.14/arch/arm/mach-vexpress/tc2_pm_psci.c 2014-09-11 18:05:54.270007076 +0200
  30952. @@ -0,0 +1,173 @@
  30953. +/*
  30954. + * arch/arm/mach-vexpress/tc2_pm_psci.c - TC2 PSCI support
  30955. + *
  30956. + * Created by: Achin Gupta, December 2012
  30957. + * Copyright: (C) 2012 ARM Limited
  30958. + *
  30959. + * Some portions of this file were originally written by Nicolas Pitre
  30960. + * Copyright: (C) 2012 Linaro Limited
  30961. + *
  30962. + * This program is free software; you can redistribute it and/or modify
  30963. + * it under the terms of the GNU General Public License version 2 as
  30964. + * published by the Free Software Foundation.
  30965. + */
  30966. +
  30967. +#include <linux/init.h>
  30968. +#include <linux/kernel.h>
  30969. +#include <linux/of.h>
  30970. +#include <linux/spinlock.h>
  30971. +#include <linux/errno.h>
  30972. +
  30973. +#include <asm/mcpm.h>
  30974. +#include <asm/proc-fns.h>
  30975. +#include <asm/cacheflush.h>
  30976. +#include <asm/psci.h>
  30977. +#include <asm/atomic.h>
  30978. +#include <asm/cputype.h>
  30979. +#include <asm/cp15.h>
  30980. +
  30981. +#include <mach/motherboard.h>
  30982. +
  30983. +#include <linux/vexpress.h>
  30984. +
  30985. +/*
  30986. + * Platform specific state id understood by the firmware and used to
  30987. + * program the power controller
  30988. + */
  30989. +#define PSCI_POWER_STATE_ID 0
  30990. +
  30991. +#define TC2_CLUSTERS 2
  30992. +#define TC2_MAX_CPUS_PER_CLUSTER 3
  30993. +
  30994. +static atomic_t tc2_pm_use_count[TC2_MAX_CPUS_PER_CLUSTER][TC2_CLUSTERS];
  30995. +
  30996. +static int tc2_pm_psci_power_up(unsigned int cpu, unsigned int cluster)
  30997. +{
  30998. + unsigned int mpidr = (cluster << 8) | cpu;
  30999. + int ret = 0;
  31000. +
  31001. + BUG_ON(!psci_ops.cpu_on);
  31002. +
  31003. + switch (atomic_inc_return(&tc2_pm_use_count[cpu][cluster])) {
  31004. + case 1:
  31005. + /*
  31006. + * This is a request to power up a cpu that linux thinks has
  31007. + * been powered down. Retries are needed if the firmware has
  31008. + * seen the power down request as yet.
  31009. + */
  31010. + do
  31011. + ret = psci_ops.cpu_on(mpidr,
  31012. + virt_to_phys(mcpm_entry_point));
  31013. + while (ret == -EAGAIN);
  31014. +
  31015. + return ret;
  31016. + case 2:
  31017. + /* This power up request has overtaken a power down request */
  31018. + return ret;
  31019. + default:
  31020. + /* Any other value is a bug */
  31021. + BUG();
  31022. + }
  31023. +}
  31024. +
  31025. +static void tc2_pm_psci_power_down(void)
  31026. +{
  31027. + struct psci_power_state power_state;
  31028. + unsigned int mpidr, cpu, cluster;
  31029. +
  31030. + mpidr = read_cpuid_mpidr();
  31031. + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  31032. + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  31033. +
  31034. + BUG_ON(!psci_ops.cpu_off);
  31035. +
  31036. + switch (atomic_dec_return(&tc2_pm_use_count[cpu][cluster])) {
  31037. + case 1:
  31038. + /*
  31039. + * Overtaken by a power up. Flush caches, exit coherency,
  31040. + * return & fake a reset
  31041. + */
  31042. + set_cr(get_cr() & ~CR_C);
  31043. +
  31044. + flush_cache_louis();
  31045. +
  31046. + asm volatile ("clrex");
  31047. + set_auxcr(get_auxcr() & ~(1 << 6));
  31048. +
  31049. + return;
  31050. + case 0:
  31051. + /* A normal request to possibly power down the cluster */
  31052. + power_state.id = PSCI_POWER_STATE_ID;
  31053. + power_state.type = PSCI_POWER_STATE_TYPE_POWER_DOWN;
  31054. + power_state.affinity_level = PSCI_POWER_STATE_AFFINITY_LEVEL1;
  31055. +
  31056. + psci_ops.cpu_off(power_state);
  31057. +
  31058. + /* On success this function never returns */
  31059. + default:
  31060. + /* Any other value is a bug */
  31061. + BUG();
  31062. + }
  31063. +}
  31064. +
  31065. +static void tc2_pm_psci_suspend(u64 unused)
  31066. +{
  31067. + struct psci_power_state power_state;
  31068. +
  31069. + BUG_ON(!psci_ops.cpu_suspend);
  31070. +
  31071. + /* On TC2 always attempt to power down the cluster */
  31072. + power_state.id = PSCI_POWER_STATE_ID;
  31073. + power_state.type = PSCI_POWER_STATE_TYPE_POWER_DOWN;
  31074. + power_state.affinity_level = PSCI_POWER_STATE_AFFINITY_LEVEL1;
  31075. +
  31076. + psci_ops.cpu_suspend(power_state, virt_to_phys(mcpm_entry_point));
  31077. +
  31078. + /* On success this function never returns */
  31079. + BUG();
  31080. +}
  31081. +
  31082. +static const struct mcpm_platform_ops tc2_pm_power_ops = {
  31083. + .power_up = tc2_pm_psci_power_up,
  31084. + .power_down = tc2_pm_psci_power_down,
  31085. + .suspend = tc2_pm_psci_suspend,
  31086. +};
  31087. +
  31088. +static void __init tc2_pm_usage_count_init(void)
  31089. +{
  31090. + unsigned int mpidr, cpu, cluster;
  31091. +
  31092. + mpidr = read_cpuid_mpidr();
  31093. + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  31094. + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  31095. +
  31096. + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
  31097. + BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
  31098. +
  31099. + atomic_set(&tc2_pm_use_count[cpu][cluster], 1);
  31100. +}
  31101. +
  31102. +static int __init tc2_pm_psci_init(void)
  31103. +{
  31104. + int ret;
  31105. +
  31106. + ret = psci_probe();
  31107. + if (ret) {
  31108. + pr_debug("psci not found. Aborting psci init\n");
  31109. + return -ENODEV;
  31110. + }
  31111. +
  31112. + if (!of_machine_is_compatible("arm,vexpress,v2p-ca15_a7"))
  31113. + return -ENODEV;
  31114. +
  31115. + tc2_pm_usage_count_init();
  31116. +
  31117. + ret = mcpm_platform_register(&tc2_pm_power_ops);
  31118. + if (!ret)
  31119. + ret = mcpm_sync_init(NULL);
  31120. + if (!ret)
  31121. + pr_info("TC2 power management using PSCI initialized\n");
  31122. + return ret;
  31123. +}
  31124. +
  31125. +early_initcall(tc2_pm_psci_init);
  31126. diff -Nur linux-3.14.17/arch/arm/mach-vexpress/v2m.c linux-imx6-3.14/arch/arm/mach-vexpress/v2m.c
  31127. --- linux-3.14.17/arch/arm/mach-vexpress/v2m.c 2014-08-14 03:38:34.000000000 +0200
  31128. +++ linux-imx6-3.14/arch/arm/mach-vexpress/v2m.c 2014-09-11 18:05:54.270007076 +0200
  31129. @@ -7,6 +7,7 @@
  31130. #include <linux/io.h>
  31131. #include <linux/smp.h>
  31132. #include <linux/init.h>
  31133. +#include <linux/memblock.h>
  31134. #include <linux/of_address.h>
  31135. #include <linux/of_fdt.h>
  31136. #include <linux/of_irq.h>
  31137. @@ -369,6 +370,31 @@
  31138. .init_machine = v2m_init,
  31139. MACHINE_END
  31140. +static void __init v2m_dt_hdlcd_init(void)
  31141. +{
  31142. + struct device_node *node;
  31143. + int len, na, ns;
  31144. + const __be32 *prop;
  31145. + phys_addr_t fb_base, fb_size;
  31146. +
  31147. + node = of_find_compatible_node(NULL, NULL, "arm,hdlcd");
  31148. + if (!node)
  31149. + return;
  31150. +
  31151. + na = of_n_addr_cells(node);
  31152. + ns = of_n_size_cells(node);
  31153. +
  31154. + prop = of_get_property(node, "framebuffer", &len);
  31155. + if (WARN_ON(!prop || len < (na + ns) * sizeof(*prop)))
  31156. + return;
  31157. +
  31158. + fb_base = of_read_number(prop, na);
  31159. + fb_size = of_read_number(prop + na, ns);
  31160. +
  31161. + if (WARN_ON(memblock_remove(fb_base, fb_size)))
  31162. + return;
  31163. +};
  31164. +
  31165. static struct map_desc v2m_rs1_io_desc __initdata = {
  31166. .virtual = V2M_PERIPH,
  31167. .pfn = __phys_to_pfn(0x1c000000),
  31168. @@ -421,6 +447,8 @@
  31169. }
  31170. versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
  31171. +
  31172. + v2m_dt_hdlcd_init();
  31173. }
  31174. static const struct of_device_id v2m_dt_bus_match[] __initconst = {
  31175. diff -Nur linux-3.14.17/arch/arm/mach-zynq/common.c linux-imx6-3.14/arch/arm/mach-zynq/common.c
  31176. --- linux-3.14.17/arch/arm/mach-zynq/common.c 2014-08-14 03:38:34.000000000 +0200
  31177. +++ linux-imx6-3.14/arch/arm/mach-zynq/common.c 2014-09-11 18:05:54.274007092 +0200
  31178. @@ -67,7 +67,7 @@
  31179. /*
  31180. * 64KB way size, 8-way associativity, parity disabled
  31181. */
  31182. - l2x0_of_init(0x02060000, 0xF0F0FFFF);
  31183. + l2x0_of_init(0x02000000, 0xf0ffffff);
  31184. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  31185. diff -Nur linux-3.14.17/arch/arm/mm/cache-feroceon-l2.c linux-imx6-3.14/arch/arm/mm/cache-feroceon-l2.c
  31186. --- linux-3.14.17/arch/arm/mm/cache-feroceon-l2.c 2014-08-14 03:38:34.000000000 +0200
  31187. +++ linux-imx6-3.14/arch/arm/mm/cache-feroceon-l2.c 2014-09-11 18:05:54.278007108 +0200
  31188. @@ -343,7 +343,6 @@
  31189. outer_cache.inv_range = feroceon_l2_inv_range;
  31190. outer_cache.clean_range = feroceon_l2_clean_range;
  31191. outer_cache.flush_range = feroceon_l2_flush_range;
  31192. - outer_cache.inv_all = l2_inv_all;
  31193. enable_l2();
  31194. diff -Nur linux-3.14.17/arch/arm/mm/cache-l2x0.c linux-imx6-3.14/arch/arm/mm/cache-l2x0.c
  31195. --- linux-3.14.17/arch/arm/mm/cache-l2x0.c 2014-08-14 03:38:34.000000000 +0200
  31196. +++ linux-imx6-3.14/arch/arm/mm/cache-l2x0.c 2014-09-11 18:05:54.278007108 +0200
  31197. @@ -16,18 +16,33 @@
  31198. * along with this program; if not, write to the Free Software
  31199. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  31200. */
  31201. +#include <linux/cpu.h>
  31202. #include <linux/err.h>
  31203. #include <linux/init.h>
  31204. +#include <linux/smp.h>
  31205. #include <linux/spinlock.h>
  31206. #include <linux/io.h>
  31207. #include <linux/of.h>
  31208. #include <linux/of_address.h>
  31209. #include <asm/cacheflush.h>
  31210. +#include <asm/cp15.h>
  31211. +#include <asm/cputype.h>
  31212. #include <asm/hardware/cache-l2x0.h>
  31213. #include "cache-tauros3.h"
  31214. #include "cache-aurora-l2.h"
  31215. +struct l2c_init_data {
  31216. + const char *type;
  31217. + unsigned way_size_0;
  31218. + unsigned num_lock;
  31219. + void (*of_parse)(const struct device_node *, u32 *, u32 *);
  31220. + void (*enable)(void __iomem *, u32, unsigned);
  31221. + void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
  31222. + void (*save)(void __iomem *);
  31223. + struct outer_cache_fns outer_cache;
  31224. +};
  31225. +
  31226. #define CACHE_LINE_SIZE 32
  31227. static void __iomem *l2x0_base;
  31228. @@ -36,96 +51,116 @@
  31229. static u32 l2x0_size;
  31230. static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
  31231. -/* Aurora don't have the cache ID register available, so we have to
  31232. - * pass it though the device tree */
  31233. -static u32 cache_id_part_number_from_dt;
  31234. -
  31235. struct l2x0_regs l2x0_saved_regs;
  31236. -struct l2x0_of_data {
  31237. - void (*setup)(const struct device_node *, u32 *, u32 *);
  31238. - void (*save)(void);
  31239. - struct outer_cache_fns outer_cache;
  31240. -};
  31241. -
  31242. -static bool of_init = false;
  31243. -
  31244. -static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
  31245. +/*
  31246. + * Common code for all cache controllers.
  31247. + */
  31248. +static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
  31249. {
  31250. /* wait for cache operation by line or way to complete */
  31251. while (readl_relaxed(reg) & mask)
  31252. cpu_relax();
  31253. }
  31254. -#ifdef CONFIG_CACHE_PL310
  31255. -static inline void cache_wait(void __iomem *reg, unsigned long mask)
  31256. +/*
  31257. + * By default, we write directly to secure registers. Platforms must
  31258. + * override this if they are running non-secure.
  31259. + */
  31260. +static void l2c_write_sec(unsigned long val, void __iomem *base, unsigned reg)
  31261. {
  31262. - /* cache operations by line are atomic on PL310 */
  31263. + if (val == readl_relaxed(base + reg))
  31264. + return;
  31265. + if (outer_cache.write_sec)
  31266. + outer_cache.write_sec(val, reg);
  31267. + else
  31268. + writel_relaxed(val, base + reg);
  31269. }
  31270. -#else
  31271. -#define cache_wait cache_wait_way
  31272. -#endif
  31273. -static inline void cache_sync(void)
  31274. +/*
  31275. + * This should only be called when we have a requirement that the
  31276. + * register be written due to a work-around, as platforms running
  31277. + * in non-secure mode may not be able to access this register.
  31278. + */
  31279. +static inline void l2c_set_debug(void __iomem *base, unsigned long val)
  31280. {
  31281. - void __iomem *base = l2x0_base;
  31282. -
  31283. - writel_relaxed(0, base + sync_reg_offset);
  31284. - cache_wait(base + L2X0_CACHE_SYNC, 1);
  31285. + l2c_write_sec(val, base, L2X0_DEBUG_CTRL);
  31286. }
  31287. -static inline void l2x0_clean_line(unsigned long addr)
  31288. +static void __l2c_op_way(void __iomem *reg)
  31289. {
  31290. - void __iomem *base = l2x0_base;
  31291. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31292. - writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
  31293. + writel_relaxed(l2x0_way_mask, reg);
  31294. + l2c_wait_mask(reg, l2x0_way_mask);
  31295. }
  31296. -static inline void l2x0_inv_line(unsigned long addr)
  31297. +static inline void l2c_unlock(void __iomem *base, unsigned num)
  31298. {
  31299. - void __iomem *base = l2x0_base;
  31300. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31301. - writel_relaxed(addr, base + L2X0_INV_LINE_PA);
  31302. + unsigned i;
  31303. +
  31304. + for (i = 0; i < num; i++) {
  31305. + writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_D_BASE +
  31306. + i * L2X0_LOCKDOWN_STRIDE);
  31307. + writel_relaxed(0, base + L2X0_LOCKDOWN_WAY_I_BASE +
  31308. + i * L2X0_LOCKDOWN_STRIDE);
  31309. + }
  31310. }
  31311. -#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
  31312. -static inline void debug_writel(unsigned long val)
  31313. +/*
  31314. + * Enable the L2 cache controller. This function must only be
  31315. + * called when the cache controller is known to be disabled.
  31316. + */
  31317. +static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31318. {
  31319. - if (outer_cache.set_debug)
  31320. - outer_cache.set_debug(val);
  31321. + unsigned long flags;
  31322. +
  31323. + l2c_write_sec(aux, base, L2X0_AUX_CTRL);
  31324. +
  31325. + l2c_unlock(base, num_lock);
  31326. +
  31327. + local_irq_save(flags);
  31328. + __l2c_op_way(base + L2X0_INV_WAY);
  31329. + writel_relaxed(0, base + sync_reg_offset);
  31330. + l2c_wait_mask(base + sync_reg_offset, 1);
  31331. + local_irq_restore(flags);
  31332. +
  31333. + l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL);
  31334. }
  31335. -static void pl310_set_debug(unsigned long val)
  31336. +static void l2c_disable(void)
  31337. {
  31338. - writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
  31339. + void __iomem *base = l2x0_base;
  31340. +
  31341. + outer_cache.flush_all();
  31342. + l2c_write_sec(0, base, L2X0_CTRL);
  31343. + dsb(st);
  31344. }
  31345. -#else
  31346. -/* Optimised out for non-errata case */
  31347. -static inline void debug_writel(unsigned long val)
  31348. +
  31349. +#ifdef CONFIG_CACHE_PL310
  31350. +static inline void cache_wait(void __iomem *reg, unsigned long mask)
  31351. {
  31352. + /* cache operations by line are atomic on PL310 */
  31353. }
  31354. -
  31355. -#define pl310_set_debug NULL
  31356. +#else
  31357. +#define cache_wait l2c_wait_mask
  31358. #endif
  31359. -#ifdef CONFIG_PL310_ERRATA_588369
  31360. -static inline void l2x0_flush_line(unsigned long addr)
  31361. +static inline void cache_sync(void)
  31362. {
  31363. void __iomem *base = l2x0_base;
  31364. - /* Clean by PA followed by Invalidate by PA */
  31365. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31366. - writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
  31367. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31368. - writel_relaxed(addr, base + L2X0_INV_LINE_PA);
  31369. + writel_relaxed(0, base + sync_reg_offset);
  31370. + cache_wait(base + L2X0_CACHE_SYNC, 1);
  31371. }
  31372. -#else
  31373. -static inline void l2x0_flush_line(unsigned long addr)
  31374. +#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
  31375. +static inline void debug_writel(unsigned long val)
  31376. +{
  31377. + l2c_set_debug(l2x0_base, val);
  31378. +}
  31379. +#else
  31380. +/* Optimised out for non-errata case */
  31381. +static inline void debug_writel(unsigned long val)
  31382. {
  31383. - void __iomem *base = l2x0_base;
  31384. - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31385. - writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
  31386. }
  31387. #endif
  31388. @@ -141,8 +176,7 @@
  31389. static void __l2x0_flush_all(void)
  31390. {
  31391. debug_writel(0x03);
  31392. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
  31393. - cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
  31394. + __l2c_op_way(l2x0_base + L2X0_CLEAN_INV_WAY);
  31395. cache_sync();
  31396. debug_writel(0x00);
  31397. }
  31398. @@ -157,274 +191,882 @@
  31399. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31400. }
  31401. -static void l2x0_clean_all(void)
  31402. +static void l2x0_disable(void)
  31403. {
  31404. unsigned long flags;
  31405. - /* clean all ways */
  31406. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31407. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
  31408. - cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
  31409. - cache_sync();
  31410. + __l2x0_flush_all();
  31411. + l2c_write_sec(0, l2x0_base, L2X0_CTRL);
  31412. + dsb(st);
  31413. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31414. }
  31415. -static void l2x0_inv_all(void)
  31416. +static void l2c_save(void __iomem *base)
  31417. {
  31418. - unsigned long flags;
  31419. + l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  31420. +}
  31421. - /* invalidate all ways */
  31422. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31423. - /* Invalidating when L2 is enabled is a nono */
  31424. - BUG_ON(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN);
  31425. - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
  31426. - cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
  31427. - cache_sync();
  31428. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31429. +/*
  31430. + * L2C-210 specific code.
  31431. + *
  31432. + * The L2C-2x0 PA, set/way and sync operations are atomic, but we must
  31433. + * ensure that no background operation is running. The way operations
  31434. + * are all background tasks.
  31435. + *
  31436. + * While a background operation is in progress, any new operation is
  31437. + * ignored (unspecified whether this causes an error.) Thankfully, not
  31438. + * used on SMP.
  31439. + *
  31440. + * Never has a different sync register other than L2X0_CACHE_SYNC, but
  31441. + * we use sync_reg_offset here so we can share some of this with L2C-310.
  31442. + */
  31443. +static void __l2c210_cache_sync(void __iomem *base)
  31444. +{
  31445. + writel_relaxed(0, base + sync_reg_offset);
  31446. }
  31447. -static void l2x0_inv_range(unsigned long start, unsigned long end)
  31448. +static void __l2c210_op_pa_range(void __iomem *reg, unsigned long start,
  31449. + unsigned long end)
  31450. +{
  31451. + while (start < end) {
  31452. + writel_relaxed(start, reg);
  31453. + start += CACHE_LINE_SIZE;
  31454. + }
  31455. +}
  31456. +
  31457. +static void l2c210_inv_range(unsigned long start, unsigned long end)
  31458. {
  31459. void __iomem *base = l2x0_base;
  31460. - unsigned long flags;
  31461. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31462. if (start & (CACHE_LINE_SIZE - 1)) {
  31463. start &= ~(CACHE_LINE_SIZE - 1);
  31464. - debug_writel(0x03);
  31465. - l2x0_flush_line(start);
  31466. - debug_writel(0x00);
  31467. + writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
  31468. start += CACHE_LINE_SIZE;
  31469. }
  31470. if (end & (CACHE_LINE_SIZE - 1)) {
  31471. end &= ~(CACHE_LINE_SIZE - 1);
  31472. - debug_writel(0x03);
  31473. - l2x0_flush_line(end);
  31474. - debug_writel(0x00);
  31475. + writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
  31476. }
  31477. + __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
  31478. + __l2c210_cache_sync(base);
  31479. +}
  31480. +
  31481. +static void l2c210_clean_range(unsigned long start, unsigned long end)
  31482. +{
  31483. + void __iomem *base = l2x0_base;
  31484. +
  31485. + start &= ~(CACHE_LINE_SIZE - 1);
  31486. + __l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
  31487. + __l2c210_cache_sync(base);
  31488. +}
  31489. +
  31490. +static void l2c210_flush_range(unsigned long start, unsigned long end)
  31491. +{
  31492. + void __iomem *base = l2x0_base;
  31493. +
  31494. + start &= ~(CACHE_LINE_SIZE - 1);
  31495. + __l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
  31496. + __l2c210_cache_sync(base);
  31497. +}
  31498. +
  31499. +static void l2c210_flush_all(void)
  31500. +{
  31501. + void __iomem *base = l2x0_base;
  31502. +
  31503. + BUG_ON(!irqs_disabled());
  31504. +
  31505. + __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
  31506. + __l2c210_cache_sync(base);
  31507. +}
  31508. +
  31509. +static void l2c210_sync(void)
  31510. +{
  31511. + __l2c210_cache_sync(l2x0_base);
  31512. +}
  31513. +
  31514. +static void l2c210_resume(void)
  31515. +{
  31516. + void __iomem *base = l2x0_base;
  31517. +
  31518. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
  31519. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 1);
  31520. +}
  31521. +
  31522. +static const struct l2c_init_data l2c210_data __initconst = {
  31523. + .type = "L2C-210",
  31524. + .way_size_0 = SZ_8K,
  31525. + .num_lock = 1,
  31526. + .enable = l2c_enable,
  31527. + .save = l2c_save,
  31528. + .outer_cache = {
  31529. + .inv_range = l2c210_inv_range,
  31530. + .clean_range = l2c210_clean_range,
  31531. + .flush_range = l2c210_flush_range,
  31532. + .flush_all = l2c210_flush_all,
  31533. + .disable = l2c_disable,
  31534. + .sync = l2c210_sync,
  31535. + .resume = l2c210_resume,
  31536. + },
  31537. +};
  31538. +
  31539. +/*
  31540. + * L2C-220 specific code.
  31541. + *
  31542. + * All operations are background operations: they have to be waited for.
  31543. + * Conflicting requests generate a slave error (which will cause an
  31544. + * imprecise abort.) Never uses sync_reg_offset, so we hard-code the
  31545. + * sync register here.
  31546. + *
  31547. + * However, we can re-use the l2c210_resume call.
  31548. + */
  31549. +static inline void __l2c220_cache_sync(void __iomem *base)
  31550. +{
  31551. + writel_relaxed(0, base + L2X0_CACHE_SYNC);
  31552. + l2c_wait_mask(base + L2X0_CACHE_SYNC, 1);
  31553. +}
  31554. +
  31555. +static void l2c220_op_way(void __iomem *base, unsigned reg)
  31556. +{
  31557. + unsigned long flags;
  31558. +
  31559. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31560. + __l2c_op_way(base + reg);
  31561. + __l2c220_cache_sync(base);
  31562. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31563. +}
  31564. +
  31565. +static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
  31566. + unsigned long end, unsigned long flags)
  31567. +{
  31568. + raw_spinlock_t *lock = &l2x0_lock;
  31569. +
  31570. while (start < end) {
  31571. unsigned long blk_end = start + min(end - start, 4096UL);
  31572. while (start < blk_end) {
  31573. - l2x0_inv_line(start);
  31574. + l2c_wait_mask(reg, 1);
  31575. + writel_relaxed(start, reg);
  31576. start += CACHE_LINE_SIZE;
  31577. }
  31578. if (blk_end < end) {
  31579. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31580. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31581. + raw_spin_unlock_irqrestore(lock, flags);
  31582. + raw_spin_lock_irqsave(lock, flags);
  31583. }
  31584. }
  31585. - cache_wait(base + L2X0_INV_LINE_PA, 1);
  31586. - cache_sync();
  31587. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31588. +
  31589. + return flags;
  31590. }
  31591. -static void l2x0_clean_range(unsigned long start, unsigned long end)
  31592. +static void l2c220_inv_range(unsigned long start, unsigned long end)
  31593. {
  31594. void __iomem *base = l2x0_base;
  31595. unsigned long flags;
  31596. - if ((end - start) >= l2x0_size) {
  31597. - l2x0_clean_all();
  31598. - return;
  31599. - }
  31600. -
  31601. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31602. - start &= ~(CACHE_LINE_SIZE - 1);
  31603. - while (start < end) {
  31604. - unsigned long blk_end = start + min(end - start, 4096UL);
  31605. -
  31606. - while (start < blk_end) {
  31607. - l2x0_clean_line(start);
  31608. + if ((start | end) & (CACHE_LINE_SIZE - 1)) {
  31609. + if (start & (CACHE_LINE_SIZE - 1)) {
  31610. + start &= ~(CACHE_LINE_SIZE - 1);
  31611. + writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
  31612. start += CACHE_LINE_SIZE;
  31613. }
  31614. - if (blk_end < end) {
  31615. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31616. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31617. + if (end & (CACHE_LINE_SIZE - 1)) {
  31618. + end &= ~(CACHE_LINE_SIZE - 1);
  31619. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31620. + writel_relaxed(end, base + L2X0_CLEAN_INV_LINE_PA);
  31621. }
  31622. }
  31623. - cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
  31624. - cache_sync();
  31625. +
  31626. + flags = l2c220_op_pa_range(base + L2X0_INV_LINE_PA,
  31627. + start, end, flags);
  31628. + l2c_wait_mask(base + L2X0_INV_LINE_PA, 1);
  31629. + __l2c220_cache_sync(base);
  31630. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31631. }
  31632. -static void l2x0_flush_range(unsigned long start, unsigned long end)
  31633. +static void l2c220_clean_range(unsigned long start, unsigned long end)
  31634. {
  31635. void __iomem *base = l2x0_base;
  31636. unsigned long flags;
  31637. + start &= ~(CACHE_LINE_SIZE - 1);
  31638. if ((end - start) >= l2x0_size) {
  31639. - l2x0_flush_all();
  31640. + l2c220_op_way(base, L2X0_CLEAN_WAY);
  31641. return;
  31642. }
  31643. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31644. + flags = l2c220_op_pa_range(base + L2X0_CLEAN_LINE_PA,
  31645. + start, end, flags);
  31646. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31647. + __l2c220_cache_sync(base);
  31648. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31649. +}
  31650. +
  31651. +static void l2c220_flush_range(unsigned long start, unsigned long end)
  31652. +{
  31653. + void __iomem *base = l2x0_base;
  31654. + unsigned long flags;
  31655. +
  31656. start &= ~(CACHE_LINE_SIZE - 1);
  31657. + if ((end - start) >= l2x0_size) {
  31658. + l2c220_op_way(base, L2X0_CLEAN_INV_WAY);
  31659. + return;
  31660. + }
  31661. +
  31662. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31663. + flags = l2c220_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA,
  31664. + start, end, flags);
  31665. + l2c_wait_mask(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31666. + __l2c220_cache_sync(base);
  31667. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31668. +}
  31669. +
  31670. +static void l2c220_flush_all(void)
  31671. +{
  31672. + l2c220_op_way(l2x0_base, L2X0_CLEAN_INV_WAY);
  31673. +}
  31674. +
  31675. +static void l2c220_sync(void)
  31676. +{
  31677. + unsigned long flags;
  31678. +
  31679. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31680. + __l2c220_cache_sync(l2x0_base);
  31681. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31682. +}
  31683. +
  31684. +static void l2c220_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31685. +{
  31686. + /*
  31687. + * Always enable non-secure access to the lockdown registers -
  31688. + * we write to them as part of the L2C enable sequence so they
  31689. + * need to be accessible.
  31690. + */
  31691. + aux |= L220_AUX_CTRL_NS_LOCKDOWN;
  31692. +
  31693. + l2c_enable(base, aux, num_lock);
  31694. +}
  31695. +
  31696. +static const struct l2c_init_data l2c220_data = {
  31697. + .type = "L2C-220",
  31698. + .way_size_0 = SZ_8K,
  31699. + .num_lock = 1,
  31700. + .enable = l2c220_enable,
  31701. + .save = l2c_save,
  31702. + .outer_cache = {
  31703. + .inv_range = l2c220_inv_range,
  31704. + .clean_range = l2c220_clean_range,
  31705. + .flush_range = l2c220_flush_range,
  31706. + .flush_all = l2c220_flush_all,
  31707. + .disable = l2c_disable,
  31708. + .sync = l2c220_sync,
  31709. + .resume = l2c210_resume,
  31710. + },
  31711. +};
  31712. +
  31713. +/*
  31714. + * L2C-310 specific code.
  31715. + *
  31716. + * Very similar to L2C-210, the PA, set/way and sync operations are atomic,
  31717. + * and the way operations are all background tasks. However, issuing an
  31718. + * operation while a background operation is in progress results in a
  31719. + * SLVERR response. We can reuse:
  31720. + *
  31721. + * __l2c210_cache_sync (using sync_reg_offset)
  31722. + * l2c210_sync
  31723. + * l2c210_inv_range (if 588369 is not applicable)
  31724. + * l2c210_clean_range
  31725. + * l2c210_flush_range (if 588369 is not applicable)
  31726. + * l2c210_flush_all (if 727915 is not applicable)
  31727. + *
  31728. + * Errata:
  31729. + * 588369: PL310 R0P0->R1P0, fixed R2P0.
  31730. + * Affects: all clean+invalidate operations
  31731. + * clean and invalidate skips the invalidate step, so we need to issue
  31732. + * separate operations. We also require the above debug workaround
  31733. + * enclosing this code fragment on affected parts. On unaffected parts,
  31734. + * we must not use this workaround without the debug register writes
  31735. + * to avoid exposing a problem similar to 727915.
  31736. + *
  31737. + * 727915: PL310 R2P0->R3P0, fixed R3P1.
  31738. + * Affects: clean+invalidate by way
  31739. + * clean and invalidate by way runs in the background, and a store can
  31740. + * hit the line between the clean operation and invalidate operation,
  31741. + * resulting in the store being lost.
  31742. + *
  31743. + * 752271: PL310 R3P0->R3P1-50REL0, fixed R3P2.
  31744. + * Affects: 8x64-bit (double fill) line fetches
  31745. + * double fill line fetches can fail to cause dirty data to be evicted
  31746. + * from the cache before the new data overwrites the second line.
  31747. + *
  31748. + * 753970: PL310 R3P0, fixed R3P1.
  31749. + * Affects: sync
  31750. + * prevents merging writes after the sync operation, until another L2C
  31751. + * operation is performed (or a number of other conditions.)
  31752. + *
  31753. + * 769419: PL310 R0P0->R3P1, fixed R3P2.
  31754. + * Affects: store buffer
  31755. + * store buffer is not automatically drained.
  31756. + */
  31757. +static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
  31758. +{
  31759. + void __iomem *base = l2x0_base;
  31760. +
  31761. + if ((start | end) & (CACHE_LINE_SIZE - 1)) {
  31762. + unsigned long flags;
  31763. +
  31764. + /* Erratum 588369 for both clean+invalidate operations */
  31765. + raw_spin_lock_irqsave(&l2x0_lock, flags);
  31766. + l2c_set_debug(base, 0x03);
  31767. +
  31768. + if (start & (CACHE_LINE_SIZE - 1)) {
  31769. + start &= ~(CACHE_LINE_SIZE - 1);
  31770. + writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
  31771. + writel_relaxed(start, base + L2X0_INV_LINE_PA);
  31772. + start += CACHE_LINE_SIZE;
  31773. + }
  31774. +
  31775. + if (end & (CACHE_LINE_SIZE - 1)) {
  31776. + end &= ~(CACHE_LINE_SIZE - 1);
  31777. + writel_relaxed(end, base + L2X0_CLEAN_LINE_PA);
  31778. + writel_relaxed(end, base + L2X0_INV_LINE_PA);
  31779. + }
  31780. +
  31781. + l2c_set_debug(base, 0x00);
  31782. + raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31783. + }
  31784. +
  31785. + __l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
  31786. + __l2c210_cache_sync(base);
  31787. +}
  31788. +
  31789. +static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
  31790. +{
  31791. + raw_spinlock_t *lock = &l2x0_lock;
  31792. + unsigned long flags;
  31793. + void __iomem *base = l2x0_base;
  31794. +
  31795. + raw_spin_lock_irqsave(lock, flags);
  31796. while (start < end) {
  31797. unsigned long blk_end = start + min(end - start, 4096UL);
  31798. - debug_writel(0x03);
  31799. + l2c_set_debug(base, 0x03);
  31800. while (start < blk_end) {
  31801. - l2x0_flush_line(start);
  31802. + writel_relaxed(start, base + L2X0_CLEAN_LINE_PA);
  31803. + writel_relaxed(start, base + L2X0_INV_LINE_PA);
  31804. start += CACHE_LINE_SIZE;
  31805. }
  31806. - debug_writel(0x00);
  31807. + l2c_set_debug(base, 0x00);
  31808. if (blk_end < end) {
  31809. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31810. - raw_spin_lock_irqsave(&l2x0_lock, flags);
  31811. + raw_spin_unlock_irqrestore(lock, flags);
  31812. + raw_spin_lock_irqsave(lock, flags);
  31813. }
  31814. }
  31815. - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
  31816. - cache_sync();
  31817. - raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31818. + raw_spin_unlock_irqrestore(lock, flags);
  31819. + __l2c210_cache_sync(base);
  31820. }
  31821. -static void l2x0_disable(void)
  31822. +static void l2c310_flush_all_erratum(void)
  31823. {
  31824. + void __iomem *base = l2x0_base;
  31825. unsigned long flags;
  31826. raw_spin_lock_irqsave(&l2x0_lock, flags);
  31827. - __l2x0_flush_all();
  31828. - writel_relaxed(0, l2x0_base + L2X0_CTRL);
  31829. - dsb(st);
  31830. + l2c_set_debug(base, 0x03);
  31831. + __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
  31832. + l2c_set_debug(base, 0x00);
  31833. + __l2c210_cache_sync(base);
  31834. raw_spin_unlock_irqrestore(&l2x0_lock, flags);
  31835. }
  31836. -static void l2x0_unlock(u32 cache_id)
  31837. +static void __init l2c310_save(void __iomem *base)
  31838. {
  31839. - int lockregs;
  31840. - int i;
  31841. + unsigned revision;
  31842. - switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  31843. - case L2X0_CACHE_ID_PART_L310:
  31844. - lockregs = 8;
  31845. - break;
  31846. - case AURORA_CACHE_ID:
  31847. - lockregs = 4;
  31848. + l2c_save(base);
  31849. +
  31850. + l2x0_saved_regs.tag_latency = readl_relaxed(base +
  31851. + L310_TAG_LATENCY_CTRL);
  31852. + l2x0_saved_regs.data_latency = readl_relaxed(base +
  31853. + L310_DATA_LATENCY_CTRL);
  31854. + l2x0_saved_regs.filter_end = readl_relaxed(base +
  31855. + L310_ADDR_FILTER_END);
  31856. + l2x0_saved_regs.filter_start = readl_relaxed(base +
  31857. + L310_ADDR_FILTER_START);
  31858. +
  31859. + revision = readl_relaxed(base + L2X0_CACHE_ID) &
  31860. + L2X0_CACHE_ID_RTL_MASK;
  31861. +
  31862. + /* From r2p0, there is Prefetch offset/control register */
  31863. + if (revision >= L310_CACHE_ID_RTL_R2P0)
  31864. + l2x0_saved_regs.prefetch_ctrl = readl_relaxed(base +
  31865. + L310_PREFETCH_CTRL);
  31866. +
  31867. + /* From r3p0, there is Power control register */
  31868. + if (revision >= L310_CACHE_ID_RTL_R3P0)
  31869. + l2x0_saved_regs.pwr_ctrl = readl_relaxed(base +
  31870. + L310_POWER_CTRL);
  31871. +}
  31872. +
  31873. +static void l2c310_resume(void)
  31874. +{
  31875. + void __iomem *base = l2x0_base;
  31876. +
  31877. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  31878. + unsigned revision;
  31879. +
  31880. + /* restore pl310 setup */
  31881. + writel_relaxed(l2x0_saved_regs.tag_latency,
  31882. + base + L310_TAG_LATENCY_CTRL);
  31883. + writel_relaxed(l2x0_saved_regs.data_latency,
  31884. + base + L310_DATA_LATENCY_CTRL);
  31885. + writel_relaxed(l2x0_saved_regs.filter_end,
  31886. + base + L310_ADDR_FILTER_END);
  31887. + writel_relaxed(l2x0_saved_regs.filter_start,
  31888. + base + L310_ADDR_FILTER_START);
  31889. +
  31890. + revision = readl_relaxed(base + L2X0_CACHE_ID) &
  31891. + L2X0_CACHE_ID_RTL_MASK;
  31892. +
  31893. + if (revision >= L310_CACHE_ID_RTL_R2P0)
  31894. + l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
  31895. + L310_PREFETCH_CTRL);
  31896. + if (revision >= L310_CACHE_ID_RTL_R3P0)
  31897. + l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
  31898. + L310_POWER_CTRL);
  31899. +
  31900. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
  31901. +
  31902. + /* Re-enable full-line-of-zeros for Cortex-A9 */
  31903. + if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
  31904. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31905. + }
  31906. +}
  31907. +
  31908. +static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
  31909. +{
  31910. + switch (act & ~CPU_TASKS_FROZEN) {
  31911. + case CPU_STARTING:
  31912. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31913. break;
  31914. - default:
  31915. - /* L210 and unknown types */
  31916. - lockregs = 1;
  31917. + case CPU_DYING:
  31918. + set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
  31919. break;
  31920. }
  31921. + return NOTIFY_OK;
  31922. +}
  31923. - for (i = 0; i < lockregs; i++) {
  31924. - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
  31925. - i * L2X0_LOCKDOWN_STRIDE);
  31926. - writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
  31927. - i * L2X0_LOCKDOWN_STRIDE);
  31928. +static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
  31929. +{
  31930. + unsigned rev = readl_relaxed(base + L2X0_CACHE_ID) & L2X0_CACHE_ID_PART_MASK;
  31931. + bool cortex_a9 = read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9;
  31932. +
  31933. + if (rev >= L310_CACHE_ID_RTL_R2P0) {
  31934. + if (cortex_a9) {
  31935. + aux |= L310_AUX_CTRL_EARLY_BRESP;
  31936. + pr_info("L2C-310 enabling early BRESP for Cortex-A9\n");
  31937. + } else if (aux & L310_AUX_CTRL_EARLY_BRESP) {
  31938. + pr_warn("L2C-310 early BRESP only supported with Cortex-A9\n");
  31939. + aux &= ~L310_AUX_CTRL_EARLY_BRESP;
  31940. + }
  31941. + }
  31942. +
  31943. + if (cortex_a9) {
  31944. + u32 aux_cur = readl_relaxed(base + L2X0_AUX_CTRL);
  31945. + u32 acr = get_auxcr();
  31946. +
  31947. + pr_debug("Cortex-A9 ACR=0x%08x\n", acr);
  31948. +
  31949. + if (acr & BIT(3) && !(aux_cur & L310_AUX_CTRL_FULL_LINE_ZERO))
  31950. + pr_err("L2C-310: full line of zeros enabled in Cortex-A9 but not L2C-310 - invalid\n");
  31951. +
  31952. + if (aux & L310_AUX_CTRL_FULL_LINE_ZERO && !(acr & BIT(3)))
  31953. + pr_err("L2C-310: enabling full line of zeros but not enabled in Cortex-A9\n");
  31954. +
  31955. + if (!(aux & L310_AUX_CTRL_FULL_LINE_ZERO) && !outer_cache.write_sec) {
  31956. + aux |= L310_AUX_CTRL_FULL_LINE_ZERO;
  31957. + pr_info("L2C-310 full line of zeros enabled for Cortex-A9\n");
  31958. + }
  31959. + } else if (aux & (L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP)) {
  31960. + pr_err("L2C-310: disabling Cortex-A9 specific feature bits\n");
  31961. + aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP);
  31962. + }
  31963. +
  31964. + if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) {
  31965. + u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL);
  31966. +
  31967. + pr_info("L2C-310 %s%s prefetch enabled, offset %u lines\n",
  31968. + aux & L310_AUX_CTRL_INSTR_PREFETCH ? "I" : "",
  31969. + aux & L310_AUX_CTRL_DATA_PREFETCH ? "D" : "",
  31970. + 1 + (prefetch & L310_PREFETCH_CTRL_OFFSET_MASK));
  31971. + }
  31972. +
  31973. + /* r3p0 or later has power control register */
  31974. + if (rev >= L310_CACHE_ID_RTL_R3P0) {
  31975. + u32 power_ctrl;
  31976. +
  31977. + l2c_write_sec(L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN,
  31978. + base, L310_POWER_CTRL);
  31979. + power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
  31980. + pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
  31981. + power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
  31982. + power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
  31983. + }
  31984. +
  31985. + /*
  31986. + * Always enable non-secure access to the lockdown registers -
  31987. + * we write to them as part of the L2C enable sequence so they
  31988. + * need to be accessible.
  31989. + */
  31990. + aux |= L310_AUX_CTRL_NS_LOCKDOWN;
  31991. +
  31992. + l2c_enable(base, aux, num_lock);
  31993. +
  31994. + if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
  31995. + set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
  31996. + cpu_notifier(l2c310_cpu_enable_flz, 0);
  31997. }
  31998. }
  31999. -void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
  32000. +static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
  32001. + struct outer_cache_fns *fns)
  32002. {
  32003. - u32 aux;
  32004. - u32 cache_id;
  32005. - u32 way_size = 0;
  32006. - int ways;
  32007. - int way_size_shift = L2X0_WAY_SIZE_SHIFT;
  32008. - const char *type;
  32009. + unsigned revision = cache_id & L2X0_CACHE_ID_RTL_MASK;
  32010. + const char *errata[8];
  32011. + unsigned n = 0;
  32012. - l2x0_base = base;
  32013. - if (cache_id_part_number_from_dt)
  32014. - cache_id = cache_id_part_number_from_dt;
  32015. - else
  32016. - cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
  32017. - aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32018. + if (IS_ENABLED(CONFIG_PL310_ERRATA_588369) &&
  32019. + revision < L310_CACHE_ID_RTL_R2P0 &&
  32020. + /* For bcm compatibility */
  32021. + fns->inv_range == l2c210_inv_range) {
  32022. + fns->inv_range = l2c310_inv_range_erratum;
  32023. + fns->flush_range = l2c310_flush_range_erratum;
  32024. + errata[n++] = "588369";
  32025. + }
  32026. +
  32027. + if (IS_ENABLED(CONFIG_PL310_ERRATA_727915) &&
  32028. + revision >= L310_CACHE_ID_RTL_R2P0 &&
  32029. + revision < L310_CACHE_ID_RTL_R3P1) {
  32030. + fns->flush_all = l2c310_flush_all_erratum;
  32031. + errata[n++] = "727915";
  32032. + }
  32033. +
  32034. + if (revision >= L310_CACHE_ID_RTL_R3P0 &&
  32035. + revision < L310_CACHE_ID_RTL_R3P2) {
  32036. + u32 val = readl_relaxed(base + L310_PREFETCH_CTRL);
  32037. + /* I don't think bit23 is required here... but iMX6 does so */
  32038. + if (val & (BIT(30) | BIT(23))) {
  32039. + val &= ~(BIT(30) | BIT(23));
  32040. + l2c_write_sec(val, base, L310_PREFETCH_CTRL);
  32041. + errata[n++] = "752271";
  32042. + }
  32043. + }
  32044. +
  32045. + if (IS_ENABLED(CONFIG_PL310_ERRATA_753970) &&
  32046. + revision == L310_CACHE_ID_RTL_R3P0) {
  32047. + sync_reg_offset = L2X0_DUMMY_REG;
  32048. + errata[n++] = "753970";
  32049. + }
  32050. +
  32051. + if (IS_ENABLED(CONFIG_PL310_ERRATA_769419))
  32052. + errata[n++] = "769419";
  32053. +
  32054. + if (n) {
  32055. + unsigned i;
  32056. +
  32057. + pr_info("L2C-310 errat%s", n > 1 ? "a" : "um");
  32058. + for (i = 0; i < n; i++)
  32059. + pr_cont(" %s", errata[i]);
  32060. + pr_cont(" enabled\n");
  32061. + }
  32062. +}
  32063. +
  32064. +static void l2c310_disable(void)
  32065. +{
  32066. + /*
  32067. + * If full-line-of-zeros is enabled, we must first disable it in the
  32068. + * Cortex-A9 auxiliary control register before disabling the L2 cache.
  32069. + */
  32070. + if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
  32071. + set_auxcr(get_auxcr() & ~(BIT(3) | BIT(2) | BIT(1)));
  32072. + l2c_disable();
  32073. +}
  32074. +
  32075. +static const struct l2c_init_data l2c310_init_fns __initconst = {
  32076. + .type = "L2C-310",
  32077. + .way_size_0 = SZ_8K,
  32078. + .num_lock = 8,
  32079. + .enable = l2c310_enable,
  32080. + .fixup = l2c310_fixup,
  32081. + .save = l2c310_save,
  32082. + .outer_cache = {
  32083. + .inv_range = l2c210_inv_range,
  32084. + .clean_range = l2c210_clean_range,
  32085. + .flush_range = l2c210_flush_range,
  32086. + .flush_all = l2c210_flush_all,
  32087. + .disable = l2c310_disable,
  32088. + .sync = l2c210_sync,
  32089. + .resume = l2c310_resume,
  32090. + },
  32091. +};
  32092. +
  32093. +static void __init __l2c_init(const struct l2c_init_data *data,
  32094. + u32 aux_val, u32 aux_mask, u32 cache_id)
  32095. +{
  32096. + struct outer_cache_fns fns;
  32097. + unsigned way_size_bits, ways;
  32098. + u32 aux, old_aux;
  32099. +
  32100. + /*
  32101. + * Sanity check the aux values. aux_mask is the bits we preserve
  32102. + * from reading the hardware register, and aux_val is the bits we
  32103. + * set.
  32104. + */
  32105. + if (aux_val & aux_mask)
  32106. + pr_alert("L2C: platform provided aux values permit register corruption.\n");
  32107. +
  32108. + old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32109. aux &= aux_mask;
  32110. aux |= aux_val;
  32111. + if (old_aux != aux)
  32112. + pr_warn("L2C: DT/platform modifies aux control register: 0x%08x -> 0x%08x\n",
  32113. + old_aux, aux);
  32114. +
  32115. /* Determine the number of ways */
  32116. switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  32117. case L2X0_CACHE_ID_PART_L310:
  32118. + if ((aux_val | ~aux_mask) & (L2C_AUX_CTRL_WAY_SIZE_MASK | L310_AUX_CTRL_ASSOCIATIVITY_16))
  32119. + pr_warn("L2C: DT/platform tries to modify or specify cache size\n");
  32120. if (aux & (1 << 16))
  32121. ways = 16;
  32122. else
  32123. ways = 8;
  32124. - type = "L310";
  32125. -#ifdef CONFIG_PL310_ERRATA_753970
  32126. - /* Unmapped register. */
  32127. - sync_reg_offset = L2X0_DUMMY_REG;
  32128. -#endif
  32129. - if ((cache_id & L2X0_CACHE_ID_RTL_MASK) <= L2X0_CACHE_ID_RTL_R3P0)
  32130. - outer_cache.set_debug = pl310_set_debug;
  32131. break;
  32132. +
  32133. case L2X0_CACHE_ID_PART_L210:
  32134. + case L2X0_CACHE_ID_PART_L220:
  32135. ways = (aux >> 13) & 0xf;
  32136. - type = "L210";
  32137. break;
  32138. case AURORA_CACHE_ID:
  32139. - sync_reg_offset = AURORA_SYNC_REG;
  32140. ways = (aux >> 13) & 0xf;
  32141. ways = 2 << ((ways + 1) >> 2);
  32142. - way_size_shift = AURORA_WAY_SIZE_SHIFT;
  32143. - type = "Aurora";
  32144. break;
  32145. +
  32146. default:
  32147. /* Assume unknown chips have 8 ways */
  32148. ways = 8;
  32149. - type = "L2x0 series";
  32150. break;
  32151. }
  32152. l2x0_way_mask = (1 << ways) - 1;
  32153. /*
  32154. - * L2 cache Size = Way size * Number of ways
  32155. + * way_size_0 is the size that a way_size value of zero would be
  32156. + * given the calculation: way_size = way_size_0 << way_size_bits.
  32157. + * So, if way_size_bits=0 is reserved, but way_size_bits=1 is 16k,
  32158. + * then way_size_0 would be 8k.
  32159. + *
  32160. + * L2 cache size = number of ways * way size.
  32161. + */
  32162. + way_size_bits = (aux & L2C_AUX_CTRL_WAY_SIZE_MASK) >>
  32163. + L2C_AUX_CTRL_WAY_SIZE_SHIFT;
  32164. + l2x0_size = ways * (data->way_size_0 << way_size_bits);
  32165. +
  32166. + fns = data->outer_cache;
  32167. + fns.write_sec = outer_cache.write_sec;
  32168. + if (data->fixup)
  32169. + data->fixup(l2x0_base, cache_id, &fns);
  32170. +
  32171. + /*
  32172. + * Check if l2x0 controller is already enabled. If we are booting
  32173. + * in non-secure mode accessing the below registers will fault.
  32174. */
  32175. - way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
  32176. - way_size = 1 << (way_size + way_size_shift);
  32177. + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
  32178. + data->enable(l2x0_base, aux, data->num_lock);
  32179. - l2x0_size = ways * way_size * SZ_1K;
  32180. + outer_cache = fns;
  32181. /*
  32182. - * Check if l2x0 controller is already enabled.
  32183. - * If you are booting from non-secure mode
  32184. - * accessing the below registers will fault.
  32185. + * It is strange to save the register state before initialisation,
  32186. + * but hey, this is what the DT implementations decided to do.
  32187. */
  32188. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32189. - /* Make sure that I&D is not locked down when starting */
  32190. - l2x0_unlock(cache_id);
  32191. + if (data->save)
  32192. + data->save(l2x0_base);
  32193. +
  32194. + /* Re-read it in case some bits are reserved. */
  32195. + aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32196. +
  32197. + pr_info("%s cache controller enabled, %d ways, %d kB\n",
  32198. + data->type, ways, l2x0_size >> 10);
  32199. + pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
  32200. + data->type, cache_id, aux);
  32201. +}
  32202. - /* l2x0 controller is disabled */
  32203. - writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
  32204. +void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
  32205. +{
  32206. + const struct l2c_init_data *data;
  32207. + u32 cache_id;
  32208. - l2x0_inv_all();
  32209. + l2x0_base = base;
  32210. - /* enable L2X0 */
  32211. - writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
  32212. + cache_id = readl_relaxed(base + L2X0_CACHE_ID);
  32213. +
  32214. + switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
  32215. + default:
  32216. + case L2X0_CACHE_ID_PART_L210:
  32217. + data = &l2c210_data;
  32218. + break;
  32219. +
  32220. + case L2X0_CACHE_ID_PART_L220:
  32221. + data = &l2c220_data;
  32222. + break;
  32223. +
  32224. + case L2X0_CACHE_ID_PART_L310:
  32225. + data = &l2c310_init_fns;
  32226. + break;
  32227. }
  32228. - /* Re-read it in case some bits are reserved. */
  32229. - aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32230. + __l2c_init(data, aux_val, aux_mask, cache_id);
  32231. +}
  32232. +
  32233. +#ifdef CONFIG_OF
  32234. +static int l2_wt_override;
  32235. +
  32236. +/* Aurora don't have the cache ID register available, so we have to
  32237. + * pass it though the device tree */
  32238. +static u32 cache_id_part_number_from_dt;
  32239. +
  32240. +static void __init l2x0_of_parse(const struct device_node *np,
  32241. + u32 *aux_val, u32 *aux_mask)
  32242. +{
  32243. + u32 data[2] = { 0, 0 };
  32244. + u32 tag = 0;
  32245. + u32 dirty = 0;
  32246. + u32 val = 0, mask = 0;
  32247. +
  32248. + of_property_read_u32(np, "arm,tag-latency", &tag);
  32249. + if (tag) {
  32250. + mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
  32251. + val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
  32252. + }
  32253. +
  32254. + of_property_read_u32_array(np, "arm,data-latency",
  32255. + data, ARRAY_SIZE(data));
  32256. + if (data[0] && data[1]) {
  32257. + mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
  32258. + L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
  32259. + val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
  32260. + ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
  32261. + }
  32262. +
  32263. + of_property_read_u32(np, "arm,dirty-latency", &dirty);
  32264. + if (dirty) {
  32265. + mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
  32266. + val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
  32267. + }
  32268. - /* Save the value for resuming. */
  32269. - l2x0_saved_regs.aux_ctrl = aux;
  32270. + *aux_val &= ~mask;
  32271. + *aux_val |= val;
  32272. + *aux_mask &= ~mask;
  32273. +}
  32274. +
  32275. +static const struct l2c_init_data of_l2c210_data __initconst = {
  32276. + .type = "L2C-210",
  32277. + .way_size_0 = SZ_8K,
  32278. + .num_lock = 1,
  32279. + .of_parse = l2x0_of_parse,
  32280. + .enable = l2c_enable,
  32281. + .save = l2c_save,
  32282. + .outer_cache = {
  32283. + .inv_range = l2c210_inv_range,
  32284. + .clean_range = l2c210_clean_range,
  32285. + .flush_range = l2c210_flush_range,
  32286. + .flush_all = l2c210_flush_all,
  32287. + .disable = l2c_disable,
  32288. + .sync = l2c210_sync,
  32289. + .resume = l2c210_resume,
  32290. + },
  32291. +};
  32292. +
  32293. +static const struct l2c_init_data of_l2c220_data __initconst = {
  32294. + .type = "L2C-220",
  32295. + .way_size_0 = SZ_8K,
  32296. + .num_lock = 1,
  32297. + .of_parse = l2x0_of_parse,
  32298. + .enable = l2c220_enable,
  32299. + .save = l2c_save,
  32300. + .outer_cache = {
  32301. + .inv_range = l2c220_inv_range,
  32302. + .clean_range = l2c220_clean_range,
  32303. + .flush_range = l2c220_flush_range,
  32304. + .flush_all = l2c220_flush_all,
  32305. + .disable = l2c_disable,
  32306. + .sync = l2c220_sync,
  32307. + .resume = l2c210_resume,
  32308. + },
  32309. +};
  32310. +
  32311. +static void __init l2c310_of_parse(const struct device_node *np,
  32312. + u32 *aux_val, u32 *aux_mask)
  32313. +{
  32314. + u32 data[3] = { 0, 0, 0 };
  32315. + u32 tag[3] = { 0, 0, 0 };
  32316. + u32 filter[2] = { 0, 0 };
  32317. +
  32318. + of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
  32319. + if (tag[0] && tag[1] && tag[2])
  32320. + writel_relaxed(
  32321. + L310_LATENCY_CTRL_RD(tag[0] - 1) |
  32322. + L310_LATENCY_CTRL_WR(tag[1] - 1) |
  32323. + L310_LATENCY_CTRL_SETUP(tag[2] - 1),
  32324. + l2x0_base + L310_TAG_LATENCY_CTRL);
  32325. +
  32326. + of_property_read_u32_array(np, "arm,data-latency",
  32327. + data, ARRAY_SIZE(data));
  32328. + if (data[0] && data[1] && data[2])
  32329. + writel_relaxed(
  32330. + L310_LATENCY_CTRL_RD(data[0] - 1) |
  32331. + L310_LATENCY_CTRL_WR(data[1] - 1) |
  32332. + L310_LATENCY_CTRL_SETUP(data[2] - 1),
  32333. + l2x0_base + L310_DATA_LATENCY_CTRL);
  32334. - if (!of_init) {
  32335. - outer_cache.inv_range = l2x0_inv_range;
  32336. - outer_cache.clean_range = l2x0_clean_range;
  32337. - outer_cache.flush_range = l2x0_flush_range;
  32338. - outer_cache.sync = l2x0_cache_sync;
  32339. - outer_cache.flush_all = l2x0_flush_all;
  32340. - outer_cache.inv_all = l2x0_inv_all;
  32341. - outer_cache.disable = l2x0_disable;
  32342. - }
  32343. -
  32344. - pr_info("%s cache controller enabled\n", type);
  32345. - pr_info("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d kB\n",
  32346. - ways, cache_id, aux, l2x0_size >> 10);
  32347. + of_property_read_u32_array(np, "arm,filter-ranges",
  32348. + filter, ARRAY_SIZE(filter));
  32349. + if (filter[1]) {
  32350. + writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
  32351. + l2x0_base + L310_ADDR_FILTER_END);
  32352. + writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN,
  32353. + l2x0_base + L310_ADDR_FILTER_START);
  32354. + }
  32355. }
  32356. -#ifdef CONFIG_OF
  32357. -static int l2_wt_override;
  32358. +static const struct l2c_init_data of_l2c310_data __initconst = {
  32359. + .type = "L2C-310",
  32360. + .way_size_0 = SZ_8K,
  32361. + .num_lock = 8,
  32362. + .of_parse = l2c310_of_parse,
  32363. + .enable = l2c310_enable,
  32364. + .fixup = l2c310_fixup,
  32365. + .save = l2c310_save,
  32366. + .outer_cache = {
  32367. + .inv_range = l2c210_inv_range,
  32368. + .clean_range = l2c210_clean_range,
  32369. + .flush_range = l2c210_flush_range,
  32370. + .flush_all = l2c210_flush_all,
  32371. + .disable = l2c310_disable,
  32372. + .sync = l2c210_sync,
  32373. + .resume = l2c310_resume,
  32374. + },
  32375. +};
  32376. /*
  32377. * Note that the end addresses passed to Linux primitives are
  32378. @@ -524,6 +1166,100 @@
  32379. }
  32380. }
  32381. +static void aurora_save(void __iomem *base)
  32382. +{
  32383. + l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
  32384. + l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
  32385. +}
  32386. +
  32387. +static void aurora_resume(void)
  32388. +{
  32389. + void __iomem *base = l2x0_base;
  32390. +
  32391. + if (!(readl(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32392. + writel_relaxed(l2x0_saved_regs.aux_ctrl, base + L2X0_AUX_CTRL);
  32393. + writel_relaxed(l2x0_saved_regs.ctrl, base + L2X0_CTRL);
  32394. + }
  32395. +}
  32396. +
  32397. +/*
  32398. + * For Aurora cache in no outer mode, enable via the CP15 coprocessor
  32399. + * broadcasting of cache commands to L2.
  32400. + */
  32401. +static void __init aurora_enable_no_outer(void __iomem *base, u32 aux,
  32402. + unsigned num_lock)
  32403. +{
  32404. + u32 u;
  32405. +
  32406. + asm volatile("mrc p15, 1, %0, c15, c2, 0" : "=r" (u));
  32407. + u |= AURORA_CTRL_FW; /* Set the FW bit */
  32408. + asm volatile("mcr p15, 1, %0, c15, c2, 0" : : "r" (u));
  32409. +
  32410. + isb();
  32411. +
  32412. + l2c_enable(base, aux, num_lock);
  32413. +}
  32414. +
  32415. +static void __init aurora_fixup(void __iomem *base, u32 cache_id,
  32416. + struct outer_cache_fns *fns)
  32417. +{
  32418. + sync_reg_offset = AURORA_SYNC_REG;
  32419. +}
  32420. +
  32421. +static void __init aurora_of_parse(const struct device_node *np,
  32422. + u32 *aux_val, u32 *aux_mask)
  32423. +{
  32424. + u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
  32425. + u32 mask = AURORA_ACR_REPLACEMENT_MASK;
  32426. +
  32427. + of_property_read_u32(np, "cache-id-part",
  32428. + &cache_id_part_number_from_dt);
  32429. +
  32430. + /* Determine and save the write policy */
  32431. + l2_wt_override = of_property_read_bool(np, "wt-override");
  32432. +
  32433. + if (l2_wt_override) {
  32434. + val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
  32435. + mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
  32436. + }
  32437. +
  32438. + *aux_val &= ~mask;
  32439. + *aux_val |= val;
  32440. + *aux_mask &= ~mask;
  32441. +}
  32442. +
  32443. +static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
  32444. + .type = "Aurora",
  32445. + .way_size_0 = SZ_4K,
  32446. + .num_lock = 4,
  32447. + .of_parse = aurora_of_parse,
  32448. + .enable = l2c_enable,
  32449. + .fixup = aurora_fixup,
  32450. + .save = aurora_save,
  32451. + .outer_cache = {
  32452. + .inv_range = aurora_inv_range,
  32453. + .clean_range = aurora_clean_range,
  32454. + .flush_range = aurora_flush_range,
  32455. + .flush_all = l2x0_flush_all,
  32456. + .disable = l2x0_disable,
  32457. + .sync = l2x0_cache_sync,
  32458. + .resume = aurora_resume,
  32459. + },
  32460. +};
  32461. +
  32462. +static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
  32463. + .type = "Aurora",
  32464. + .way_size_0 = SZ_4K,
  32465. + .num_lock = 4,
  32466. + .of_parse = aurora_of_parse,
  32467. + .enable = aurora_enable_no_outer,
  32468. + .fixup = aurora_fixup,
  32469. + .save = aurora_save,
  32470. + .outer_cache = {
  32471. + .resume = aurora_resume,
  32472. + },
  32473. +};
  32474. +
  32475. /*
  32476. * For certain Broadcom SoCs, depending on the address range, different offsets
  32477. * need to be added to the address before passing it to L2 for
  32478. @@ -588,16 +1324,16 @@
  32479. /* normal case, no cross section between start and end */
  32480. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32481. - l2x0_inv_range(new_start, new_end);
  32482. + l2c210_inv_range(new_start, new_end);
  32483. return;
  32484. }
  32485. /* They cross sections, so it can only be a cross from section
  32486. * 2 to section 3
  32487. */
  32488. - l2x0_inv_range(new_start,
  32489. + l2c210_inv_range(new_start,
  32490. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32491. - l2x0_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32492. + l2c210_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32493. new_end);
  32494. }
  32495. @@ -610,26 +1346,21 @@
  32496. if (unlikely(end <= start))
  32497. return;
  32498. - if ((end - start) >= l2x0_size) {
  32499. - l2x0_clean_all();
  32500. - return;
  32501. - }
  32502. -
  32503. new_start = bcm_l2_phys_addr(start);
  32504. new_end = bcm_l2_phys_addr(end);
  32505. /* normal case, no cross section between start and end */
  32506. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32507. - l2x0_clean_range(new_start, new_end);
  32508. + l2c210_clean_range(new_start, new_end);
  32509. return;
  32510. }
  32511. /* They cross sections, so it can only be a cross from section
  32512. * 2 to section 3
  32513. */
  32514. - l2x0_clean_range(new_start,
  32515. + l2c210_clean_range(new_start,
  32516. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32517. - l2x0_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32518. + l2c210_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32519. new_end);
  32520. }
  32521. @@ -643,7 +1374,7 @@
  32522. return;
  32523. if ((end - start) >= l2x0_size) {
  32524. - l2x0_flush_all();
  32525. + outer_cache.flush_all();
  32526. return;
  32527. }
  32528. @@ -652,283 +1383,67 @@
  32529. /* normal case, no cross section between start and end */
  32530. if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
  32531. - l2x0_flush_range(new_start, new_end);
  32532. + l2c210_flush_range(new_start, new_end);
  32533. return;
  32534. }
  32535. /* They cross sections, so it can only be a cross from section
  32536. * 2 to section 3
  32537. */
  32538. - l2x0_flush_range(new_start,
  32539. + l2c210_flush_range(new_start,
  32540. bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
  32541. - l2x0_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32542. + l2c210_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
  32543. new_end);
  32544. }
  32545. -static void __init l2x0_of_setup(const struct device_node *np,
  32546. - u32 *aux_val, u32 *aux_mask)
  32547. -{
  32548. - u32 data[2] = { 0, 0 };
  32549. - u32 tag = 0;
  32550. - u32 dirty = 0;
  32551. - u32 val = 0, mask = 0;
  32552. -
  32553. - of_property_read_u32(np, "arm,tag-latency", &tag);
  32554. - if (tag) {
  32555. - mask |= L2X0_AUX_CTRL_TAG_LATENCY_MASK;
  32556. - val |= (tag - 1) << L2X0_AUX_CTRL_TAG_LATENCY_SHIFT;
  32557. - }
  32558. -
  32559. - of_property_read_u32_array(np, "arm,data-latency",
  32560. - data, ARRAY_SIZE(data));
  32561. - if (data[0] && data[1]) {
  32562. - mask |= L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK |
  32563. - L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK;
  32564. - val |= ((data[0] - 1) << L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT) |
  32565. - ((data[1] - 1) << L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT);
  32566. - }
  32567. -
  32568. - of_property_read_u32(np, "arm,dirty-latency", &dirty);
  32569. - if (dirty) {
  32570. - mask |= L2X0_AUX_CTRL_DIRTY_LATENCY_MASK;
  32571. - val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT;
  32572. - }
  32573. -
  32574. - *aux_val &= ~mask;
  32575. - *aux_val |= val;
  32576. - *aux_mask &= ~mask;
  32577. -}
  32578. -
  32579. -static void __init pl310_of_setup(const struct device_node *np,
  32580. - u32 *aux_val, u32 *aux_mask)
  32581. -{
  32582. - u32 data[3] = { 0, 0, 0 };
  32583. - u32 tag[3] = { 0, 0, 0 };
  32584. - u32 filter[2] = { 0, 0 };
  32585. -
  32586. - of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
  32587. - if (tag[0] && tag[1] && tag[2])
  32588. - writel_relaxed(
  32589. - ((tag[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
  32590. - ((tag[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
  32591. - ((tag[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
  32592. - l2x0_base + L2X0_TAG_LATENCY_CTRL);
  32593. -
  32594. - of_property_read_u32_array(np, "arm,data-latency",
  32595. - data, ARRAY_SIZE(data));
  32596. - if (data[0] && data[1] && data[2])
  32597. - writel_relaxed(
  32598. - ((data[0] - 1) << L2X0_LATENCY_CTRL_RD_SHIFT) |
  32599. - ((data[1] - 1) << L2X0_LATENCY_CTRL_WR_SHIFT) |
  32600. - ((data[2] - 1) << L2X0_LATENCY_CTRL_SETUP_SHIFT),
  32601. - l2x0_base + L2X0_DATA_LATENCY_CTRL);
  32602. -
  32603. - of_property_read_u32_array(np, "arm,filter-ranges",
  32604. - filter, ARRAY_SIZE(filter));
  32605. - if (filter[1]) {
  32606. - writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
  32607. - l2x0_base + L2X0_ADDR_FILTER_END);
  32608. - writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L2X0_ADDR_FILTER_EN,
  32609. - l2x0_base + L2X0_ADDR_FILTER_START);
  32610. - }
  32611. -}
  32612. -
  32613. -static void __init pl310_save(void)
  32614. -{
  32615. - u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
  32616. - L2X0_CACHE_ID_RTL_MASK;
  32617. -
  32618. - l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base +
  32619. - L2X0_TAG_LATENCY_CTRL);
  32620. - l2x0_saved_regs.data_latency = readl_relaxed(l2x0_base +
  32621. - L2X0_DATA_LATENCY_CTRL);
  32622. - l2x0_saved_regs.filter_end = readl_relaxed(l2x0_base +
  32623. - L2X0_ADDR_FILTER_END);
  32624. - l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base +
  32625. - L2X0_ADDR_FILTER_START);
  32626. -
  32627. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
  32628. - /*
  32629. - * From r2p0, there is Prefetch offset/control register
  32630. - */
  32631. - l2x0_saved_regs.prefetch_ctrl = readl_relaxed(l2x0_base +
  32632. - L2X0_PREFETCH_CTRL);
  32633. - /*
  32634. - * From r3p0, there is Power control register
  32635. - */
  32636. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
  32637. - l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base +
  32638. - L2X0_POWER_CTRL);
  32639. - }
  32640. -}
  32641. +/* Broadcom L2C-310 start from ARMs R3P2 or later, and require no fixups */
  32642. +static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
  32643. + .type = "BCM-L2C-310",
  32644. + .way_size_0 = SZ_8K,
  32645. + .num_lock = 8,
  32646. + .of_parse = l2c310_of_parse,
  32647. + .enable = l2c310_enable,
  32648. + .save = l2c310_save,
  32649. + .outer_cache = {
  32650. + .inv_range = bcm_inv_range,
  32651. + .clean_range = bcm_clean_range,
  32652. + .flush_range = bcm_flush_range,
  32653. + .flush_all = l2c210_flush_all,
  32654. + .disable = l2c310_disable,
  32655. + .sync = l2c210_sync,
  32656. + .resume = l2c310_resume,
  32657. + },
  32658. +};
  32659. -static void aurora_save(void)
  32660. +static void __init tauros3_save(void __iomem *base)
  32661. {
  32662. - l2x0_saved_regs.ctrl = readl_relaxed(l2x0_base + L2X0_CTRL);
  32663. - l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32664. -}
  32665. + l2c_save(base);
  32666. -static void __init tauros3_save(void)
  32667. -{
  32668. l2x0_saved_regs.aux2_ctrl =
  32669. - readl_relaxed(l2x0_base + TAUROS3_AUX2_CTRL);
  32670. + readl_relaxed(base + TAUROS3_AUX2_CTRL);
  32671. l2x0_saved_regs.prefetch_ctrl =
  32672. - readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
  32673. -}
  32674. -
  32675. -static void l2x0_resume(void)
  32676. -{
  32677. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32678. - /* restore aux ctrl and enable l2 */
  32679. - l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
  32680. -
  32681. - writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base +
  32682. - L2X0_AUX_CTRL);
  32683. -
  32684. - l2x0_inv_all();
  32685. -
  32686. - writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
  32687. - }
  32688. -}
  32689. -
  32690. -static void pl310_resume(void)
  32691. -{
  32692. - u32 l2x0_revision;
  32693. -
  32694. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32695. - /* restore pl310 setup */
  32696. - writel_relaxed(l2x0_saved_regs.tag_latency,
  32697. - l2x0_base + L2X0_TAG_LATENCY_CTRL);
  32698. - writel_relaxed(l2x0_saved_regs.data_latency,
  32699. - l2x0_base + L2X0_DATA_LATENCY_CTRL);
  32700. - writel_relaxed(l2x0_saved_regs.filter_end,
  32701. - l2x0_base + L2X0_ADDR_FILTER_END);
  32702. - writel_relaxed(l2x0_saved_regs.filter_start,
  32703. - l2x0_base + L2X0_ADDR_FILTER_START);
  32704. -
  32705. - l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
  32706. - L2X0_CACHE_ID_RTL_MASK;
  32707. -
  32708. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) {
  32709. - writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
  32710. - l2x0_base + L2X0_PREFETCH_CTRL);
  32711. - if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0)
  32712. - writel_relaxed(l2x0_saved_regs.pwr_ctrl,
  32713. - l2x0_base + L2X0_POWER_CTRL);
  32714. - }
  32715. - }
  32716. -
  32717. - l2x0_resume();
  32718. -}
  32719. -
  32720. -static void aurora_resume(void)
  32721. -{
  32722. - if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32723. - writel_relaxed(l2x0_saved_regs.aux_ctrl,
  32724. - l2x0_base + L2X0_AUX_CTRL);
  32725. - writel_relaxed(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
  32726. - }
  32727. + readl_relaxed(base + L310_PREFETCH_CTRL);
  32728. }
  32729. static void tauros3_resume(void)
  32730. {
  32731. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32732. + void __iomem *base = l2x0_base;
  32733. +
  32734. + if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32735. writel_relaxed(l2x0_saved_regs.aux2_ctrl,
  32736. - l2x0_base + TAUROS3_AUX2_CTRL);
  32737. + base + TAUROS3_AUX2_CTRL);
  32738. writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
  32739. - l2x0_base + L2X0_PREFETCH_CTRL);
  32740. - }
  32741. -
  32742. - l2x0_resume();
  32743. -}
  32744. -
  32745. -static void __init aurora_broadcast_l2_commands(void)
  32746. -{
  32747. - __u32 u;
  32748. - /* Enable Broadcasting of cache commands to L2*/
  32749. - __asm__ __volatile__("mrc p15, 1, %0, c15, c2, 0" : "=r"(u));
  32750. - u |= AURORA_CTRL_FW; /* Set the FW bit */
  32751. - __asm__ __volatile__("mcr p15, 1, %0, c15, c2, 0\n" : : "r"(u));
  32752. - isb();
  32753. -}
  32754. -
  32755. -static void __init aurora_of_setup(const struct device_node *np,
  32756. - u32 *aux_val, u32 *aux_mask)
  32757. -{
  32758. - u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
  32759. - u32 mask = AURORA_ACR_REPLACEMENT_MASK;
  32760. + base + L310_PREFETCH_CTRL);
  32761. - of_property_read_u32(np, "cache-id-part",
  32762. - &cache_id_part_number_from_dt);
  32763. -
  32764. - /* Determine and save the write policy */
  32765. - l2_wt_override = of_property_read_bool(np, "wt-override");
  32766. -
  32767. - if (l2_wt_override) {
  32768. - val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
  32769. - mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
  32770. + l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
  32771. }
  32772. -
  32773. - *aux_val &= ~mask;
  32774. - *aux_val |= val;
  32775. - *aux_mask &= ~mask;
  32776. }
  32777. -static const struct l2x0_of_data pl310_data = {
  32778. - .setup = pl310_of_setup,
  32779. - .save = pl310_save,
  32780. - .outer_cache = {
  32781. - .resume = pl310_resume,
  32782. - .inv_range = l2x0_inv_range,
  32783. - .clean_range = l2x0_clean_range,
  32784. - .flush_range = l2x0_flush_range,
  32785. - .sync = l2x0_cache_sync,
  32786. - .flush_all = l2x0_flush_all,
  32787. - .inv_all = l2x0_inv_all,
  32788. - .disable = l2x0_disable,
  32789. - },
  32790. -};
  32791. -
  32792. -static const struct l2x0_of_data l2x0_data = {
  32793. - .setup = l2x0_of_setup,
  32794. - .save = NULL,
  32795. - .outer_cache = {
  32796. - .resume = l2x0_resume,
  32797. - .inv_range = l2x0_inv_range,
  32798. - .clean_range = l2x0_clean_range,
  32799. - .flush_range = l2x0_flush_range,
  32800. - .sync = l2x0_cache_sync,
  32801. - .flush_all = l2x0_flush_all,
  32802. - .inv_all = l2x0_inv_all,
  32803. - .disable = l2x0_disable,
  32804. - },
  32805. -};
  32806. -
  32807. -static const struct l2x0_of_data aurora_with_outer_data = {
  32808. - .setup = aurora_of_setup,
  32809. - .save = aurora_save,
  32810. - .outer_cache = {
  32811. - .resume = aurora_resume,
  32812. - .inv_range = aurora_inv_range,
  32813. - .clean_range = aurora_clean_range,
  32814. - .flush_range = aurora_flush_range,
  32815. - .sync = l2x0_cache_sync,
  32816. - .flush_all = l2x0_flush_all,
  32817. - .inv_all = l2x0_inv_all,
  32818. - .disable = l2x0_disable,
  32819. - },
  32820. -};
  32821. -
  32822. -static const struct l2x0_of_data aurora_no_outer_data = {
  32823. - .setup = aurora_of_setup,
  32824. - .save = aurora_save,
  32825. - .outer_cache = {
  32826. - .resume = aurora_resume,
  32827. - },
  32828. -};
  32829. -
  32830. -static const struct l2x0_of_data tauros3_data = {
  32831. - .setup = NULL,
  32832. +static const struct l2c_init_data of_tauros3_data __initconst = {
  32833. + .type = "Tauros3",
  32834. + .way_size_0 = SZ_8K,
  32835. + .num_lock = 8,
  32836. + .enable = l2c_enable,
  32837. .save = tauros3_save,
  32838. /* Tauros3 broadcasts L1 cache operations to L2 */
  32839. .outer_cache = {
  32840. @@ -936,43 +1451,26 @@
  32841. },
  32842. };
  32843. -static const struct l2x0_of_data bcm_l2x0_data = {
  32844. - .setup = pl310_of_setup,
  32845. - .save = pl310_save,
  32846. - .outer_cache = {
  32847. - .resume = pl310_resume,
  32848. - .inv_range = bcm_inv_range,
  32849. - .clean_range = bcm_clean_range,
  32850. - .flush_range = bcm_flush_range,
  32851. - .sync = l2x0_cache_sync,
  32852. - .flush_all = l2x0_flush_all,
  32853. - .inv_all = l2x0_inv_all,
  32854. - .disable = l2x0_disable,
  32855. - },
  32856. -};
  32857. -
  32858. +#define L2C_ID(name, fns) { .compatible = name, .data = (void *)&fns }
  32859. static const struct of_device_id l2x0_ids[] __initconst = {
  32860. - { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
  32861. - { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
  32862. - { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
  32863. - { .compatible = "bcm,bcm11351-a2-pl310-cache", /* deprecated name */
  32864. - .data = (void *)&bcm_l2x0_data},
  32865. - { .compatible = "brcm,bcm11351-a2-pl310-cache",
  32866. - .data = (void *)&bcm_l2x0_data},
  32867. - { .compatible = "marvell,aurora-outer-cache",
  32868. - .data = (void *)&aurora_with_outer_data},
  32869. - { .compatible = "marvell,aurora-system-cache",
  32870. - .data = (void *)&aurora_no_outer_data},
  32871. - { .compatible = "marvell,tauros3-cache",
  32872. - .data = (void *)&tauros3_data },
  32873. + L2C_ID("arm,l210-cache", of_l2c210_data),
  32874. + L2C_ID("arm,l220-cache", of_l2c220_data),
  32875. + L2C_ID("arm,pl310-cache", of_l2c310_data),
  32876. + L2C_ID("brcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
  32877. + L2C_ID("marvell,aurora-outer-cache", of_aurora_with_outer_data),
  32878. + L2C_ID("marvell,aurora-system-cache", of_aurora_no_outer_data),
  32879. + L2C_ID("marvell,tauros3-cache", of_tauros3_data),
  32880. + /* Deprecated IDs */
  32881. + L2C_ID("bcm,bcm11351-a2-pl310-cache", of_bcm_l2x0_data),
  32882. {}
  32883. };
  32884. int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
  32885. {
  32886. + const struct l2c_init_data *data;
  32887. struct device_node *np;
  32888. - const struct l2x0_of_data *data;
  32889. struct resource res;
  32890. + u32 cache_id, old_aux;
  32891. np = of_find_matching_node(NULL, l2x0_ids);
  32892. if (!np)
  32893. @@ -989,23 +1487,29 @@
  32894. data = of_match_node(l2x0_ids, np)->data;
  32895. - /* L2 configuration can only be changed if the cache is disabled */
  32896. - if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  32897. - if (data->setup)
  32898. - data->setup(np, &aux_val, &aux_mask);
  32899. -
  32900. - /* For aurora cache in no outer mode select the
  32901. - * correct mode using the coprocessor*/
  32902. - if (data == &aurora_no_outer_data)
  32903. - aurora_broadcast_l2_commands();
  32904. + old_aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
  32905. + if (old_aux != ((old_aux & aux_mask) | aux_val)) {
  32906. + pr_warn("L2C: platform modifies aux control register: 0x%08x -> 0x%08x\n",
  32907. + old_aux, (old_aux & aux_mask) | aux_val);
  32908. + } else if (aux_mask != ~0U && aux_val != 0) {
  32909. + pr_alert("L2C: platform provided aux values match the hardware, so have no effect. Please remove them.\n");
  32910. }
  32911. - if (data->save)
  32912. - data->save();
  32913. + /* All L2 caches are unified, so this property should be specified */
  32914. + if (!of_property_read_bool(np, "cache-unified"))
  32915. + pr_err("L2C: device tree omits to specify unified cache\n");
  32916. +
  32917. + /* L2 configuration can only be changed if the cache is disabled */
  32918. + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
  32919. + if (data->of_parse)
  32920. + data->of_parse(np, &aux_val, &aux_mask);
  32921. +
  32922. + if (cache_id_part_number_from_dt)
  32923. + cache_id = cache_id_part_number_from_dt;
  32924. + else
  32925. + cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
  32926. - of_init = true;
  32927. - memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache));
  32928. - l2x0_init(l2x0_base, aux_val, aux_mask);
  32929. + __l2c_init(data, aux_val, aux_mask, cache_id);
  32930. return 0;
  32931. }
  32932. diff -Nur linux-3.14.17/arch/arm/mm/dma-mapping.c linux-imx6-3.14/arch/arm/mm/dma-mapping.c
  32933. --- linux-3.14.17/arch/arm/mm/dma-mapping.c 2014-08-14 03:38:34.000000000 +0200
  32934. +++ linux-imx6-3.14/arch/arm/mm/dma-mapping.c 2014-09-11 18:05:54.278007108 +0200
  32935. @@ -26,6 +26,7 @@
  32936. #include <linux/io.h>
  32937. #include <linux/vmalloc.h>
  32938. #include <linux/sizes.h>
  32939. +#include <linux/cma.h>
  32940. #include <asm/memory.h>
  32941. #include <asm/highmem.h>
  32942. diff -Nur linux-3.14.17/arch/arm/mm/fault.c linux-imx6-3.14/arch/arm/mm/fault.c
  32943. --- linux-3.14.17/arch/arm/mm/fault.c 2014-08-14 03:38:34.000000000 +0200
  32944. +++ linux-imx6-3.14/arch/arm/mm/fault.c 2014-09-11 18:05:54.278007108 +0200
  32945. @@ -449,8 +449,16 @@
  32946. if (pud_none(*pud_k))
  32947. goto bad_area;
  32948. - if (!pud_present(*pud))
  32949. + if (!pud_present(*pud)) {
  32950. set_pud(pud, *pud_k);
  32951. + /*
  32952. + * There is a small window during free_pgtables() where the
  32953. + * user *pud entry is 0 but the TLB has not been invalidated
  32954. + * and we get a level 2 (pmd) translation fault caused by the
  32955. + * intermediate TLB caching of the old level 1 (pud) entry.
  32956. + */
  32957. + flush_tlb_kernel_page(addr);
  32958. + }
  32959. pmd = pmd_offset(pud, addr);
  32960. pmd_k = pmd_offset(pud_k, addr);
  32961. @@ -473,8 +481,9 @@
  32962. #endif
  32963. if (pmd_none(pmd_k[index]))
  32964. goto bad_area;
  32965. + if (!pmd_present(pmd[index]))
  32966. + copy_pmd(pmd, pmd_k);
  32967. - copy_pmd(pmd, pmd_k);
  32968. return 0;
  32969. bad_area:
  32970. diff -Nur linux-3.14.17/arch/arm/mm/idmap.c linux-imx6-3.14/arch/arm/mm/idmap.c
  32971. --- linux-3.14.17/arch/arm/mm/idmap.c 2014-08-14 03:38:34.000000000 +0200
  32972. +++ linux-imx6-3.14/arch/arm/mm/idmap.c 2014-09-11 18:05:54.282007125 +0200
  32973. @@ -25,13 +25,6 @@
  32974. pr_warning("Failed to allocate identity pmd.\n");
  32975. return;
  32976. }
  32977. - /*
  32978. - * Copy the original PMD to ensure that the PMD entries for
  32979. - * the kernel image are preserved.
  32980. - */
  32981. - if (!pud_none(*pud))
  32982. - memcpy(pmd, pmd_offset(pud, 0),
  32983. - PTRS_PER_PMD * sizeof(pmd_t));
  32984. pud_populate(&init_mm, pud, pmd);
  32985. pmd += pmd_index(addr);
  32986. } else
  32987. diff -Nur linux-3.14.17/arch/arm/mm/init.c linux-imx6-3.14/arch/arm/mm/init.c
  32988. --- linux-3.14.17/arch/arm/mm/init.c 2014-08-14 03:38:34.000000000 +0200
  32989. +++ linux-imx6-3.14/arch/arm/mm/init.c 2014-09-11 18:05:54.282007125 +0200
  32990. @@ -327,7 +327,7 @@
  32991. * reserve memory for DMA contigouos allocations,
  32992. * must come from DMA area inside low memory
  32993. */
  32994. - dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));
  32995. + dma_contiguous_reserve(arm_dma_limit);
  32996. arm_memblock_steal_permitted = false;
  32997. memblock_dump_all();
  32998. diff -Nur linux-3.14.17/arch/arm/mm/Kconfig linux-imx6-3.14/arch/arm/mm/Kconfig
  32999. --- linux-3.14.17/arch/arm/mm/Kconfig 2014-08-14 03:38:34.000000000 +0200
  33000. +++ linux-imx6-3.14/arch/arm/mm/Kconfig 2014-09-11 18:05:54.274007092 +0200
  33001. @@ -897,6 +897,57 @@
  33002. This option enables optimisations for the PL310 cache
  33003. controller.
  33004. +config PL310_ERRATA_588369
  33005. + bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
  33006. + depends on CACHE_L2X0
  33007. + help
  33008. + The PL310 L2 cache controller implements three types of Clean &
  33009. + Invalidate maintenance operations: by Physical Address
  33010. + (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
  33011. + They are architecturally defined to behave as the execution of a
  33012. + clean operation followed immediately by an invalidate operation,
  33013. + both performing to the same memory location. This functionality
  33014. + is not correctly implemented in PL310 as clean lines are not
  33015. + invalidated as a result of these operations.
  33016. +
  33017. +config PL310_ERRATA_727915
  33018. + bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
  33019. + depends on CACHE_L2X0
  33020. + help
  33021. + PL310 implements the Clean & Invalidate by Way L2 cache maintenance
  33022. + operation (offset 0x7FC). This operation runs in background so that
  33023. + PL310 can handle normal accesses while it is in progress. Under very
  33024. + rare circumstances, due to this erratum, write data can be lost when
  33025. + PL310 treats a cacheable write transaction during a Clean &
  33026. + Invalidate by Way operation.
  33027. +
  33028. +config PL310_ERRATA_753970
  33029. + bool "PL310 errata: cache sync operation may be faulty"
  33030. + depends on CACHE_PL310
  33031. + help
  33032. + This option enables the workaround for the 753970 PL310 (r3p0) erratum.
  33033. +
  33034. + Under some condition the effect of cache sync operation on
  33035. + the store buffer still remains when the operation completes.
  33036. + This means that the store buffer is always asked to drain and
  33037. + this prevents it from merging any further writes. The workaround
  33038. + is to replace the normal offset of cache sync operation (0x730)
  33039. + by another offset targeting an unmapped PL310 register 0x740.
  33040. + This has the same effect as the cache sync operation: store buffer
  33041. + drain and waiting for all buffers empty.
  33042. +
  33043. +config PL310_ERRATA_769419
  33044. + bool "PL310 errata: no automatic Store Buffer drain"
  33045. + depends on CACHE_L2X0
  33046. + help
  33047. + On revisions of the PL310 prior to r3p2, the Store Buffer does
  33048. + not automatically drain. This can cause normal, non-cacheable
  33049. + writes to be retained when the memory system is idle, leading
  33050. + to suboptimal I/O performance for drivers using coherent DMA.
  33051. + This option adds a write barrier to the cpu_idle loop so that,
  33052. + on systems with an outer cache, the store buffer is drained
  33053. + explicitly.
  33054. +
  33055. config CACHE_TAUROS2
  33056. bool "Enable the Tauros2 L2 cache controller"
  33057. depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
  33058. diff -Nur linux-3.14.17/arch/arm/mm/l2c-common.c linux-imx6-3.14/arch/arm/mm/l2c-common.c
  33059. --- linux-3.14.17/arch/arm/mm/l2c-common.c 1970-01-01 01:00:00.000000000 +0100
  33060. +++ linux-imx6-3.14/arch/arm/mm/l2c-common.c 2014-09-11 18:05:54.282007125 +0200
  33061. @@ -0,0 +1,20 @@
  33062. +/*
  33063. + * Copyright (C) 2010 ARM Ltd.
  33064. + * Written by Catalin Marinas <catalin.marinas@arm.com>
  33065. + *
  33066. + * This program is free software; you can redistribute it and/or modify
  33067. + * it under the terms of the GNU General Public License version 2 as
  33068. + * published by the Free Software Foundation.
  33069. + */
  33070. +#include <linux/bug.h>
  33071. +#include <linux/smp.h>
  33072. +#include <asm/outercache.h>
  33073. +
  33074. +void outer_disable(void)
  33075. +{
  33076. + WARN_ON(!irqs_disabled());
  33077. + WARN_ON(num_online_cpus() > 1);
  33078. +
  33079. + if (outer_cache.disable)
  33080. + outer_cache.disable();
  33081. +}
  33082. diff -Nur linux-3.14.17/arch/arm/mm/l2c-l2x0-resume.S linux-imx6-3.14/arch/arm/mm/l2c-l2x0-resume.S
  33083. --- linux-3.14.17/arch/arm/mm/l2c-l2x0-resume.S 1970-01-01 01:00:00.000000000 +0100
  33084. +++ linux-imx6-3.14/arch/arm/mm/l2c-l2x0-resume.S 2014-09-11 18:05:54.282007125 +0200
  33085. @@ -0,0 +1,58 @@
  33086. +/*
  33087. + * L2C-310 early resume code. This can be used by platforms to restore
  33088. + * the settings of their L2 cache controller before restoring the
  33089. + * processor state.
  33090. + *
  33091. + * This code can only be used to if you are running in the secure world.
  33092. + */
  33093. +#include <linux/linkage.h>
  33094. +#include <asm/hardware/cache-l2x0.h>
  33095. +
  33096. + .text
  33097. +
  33098. +ENTRY(l2c310_early_resume)
  33099. + adr r0, 1f
  33100. + ldr r2, [r0]
  33101. + add r0, r2, r0
  33102. +
  33103. + ldmia r0, {r1, r2, r3, r4, r5, r6, r7, r8}
  33104. + @ r1 = phys address of L2C-310 controller
  33105. + @ r2 = aux_ctrl
  33106. + @ r3 = tag_latency
  33107. + @ r4 = data_latency
  33108. + @ r5 = filter_start
  33109. + @ r6 = filter_end
  33110. + @ r7 = prefetch_ctrl
  33111. + @ r8 = pwr_ctrl
  33112. +
  33113. + @ Check that the address has been initialised
  33114. + teq r1, #0
  33115. + moveq pc, lr
  33116. +
  33117. + @ The prefetch and power control registers are revision dependent
  33118. + @ and can be written whether or not the L2 cache is enabled
  33119. + ldr r0, [r1, #L2X0_CACHE_ID]
  33120. + and r0, r0, #L2X0_CACHE_ID_RTL_MASK
  33121. + cmp r0, #L310_CACHE_ID_RTL_R2P0
  33122. + strcs r7, [r1, #L310_PREFETCH_CTRL]
  33123. + cmp r0, #L310_CACHE_ID_RTL_R3P0
  33124. + strcs r8, [r1, #L310_POWER_CTRL]
  33125. +
  33126. + @ Don't setup the L2 cache if it is already enabled
  33127. + ldr r0, [r1, #L2X0_CTRL]
  33128. + tst r0, #L2X0_CTRL_EN
  33129. + movne pc, lr
  33130. +
  33131. + str r3, [r1, #L310_TAG_LATENCY_CTRL]
  33132. + str r4, [r1, #L310_DATA_LATENCY_CTRL]
  33133. + str r6, [r1, #L310_ADDR_FILTER_END]
  33134. + str r5, [r1, #L310_ADDR_FILTER_START]
  33135. +
  33136. + str r2, [r1, #L2X0_AUX_CTRL]
  33137. + mov r9, #L2X0_CTRL_EN
  33138. + str r9, [r1, #L2X0_CTRL]
  33139. + mov pc, lr
  33140. +ENDPROC(l2c310_early_resume)
  33141. +
  33142. + .align
  33143. +1: .long l2x0_saved_regs - .
  33144. diff -Nur linux-3.14.17/arch/arm/mm/Makefile linux-imx6-3.14/arch/arm/mm/Makefile
  33145. --- linux-3.14.17/arch/arm/mm/Makefile 2014-08-14 03:38:34.000000000 +0200
  33146. +++ linux-imx6-3.14/arch/arm/mm/Makefile 2014-09-11 18:05:54.274007092 +0200
  33147. @@ -95,7 +95,8 @@
  33148. AFLAGS_proc-v6.o :=-Wa,-march=armv6
  33149. AFLAGS_proc-v7.o :=-Wa,-march=armv7-a
  33150. +obj-$(CONFIG_OUTER_CACHE) += l2c-common.o
  33151. obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
  33152. -obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
  33153. +obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o l2c-l2x0-resume.o
  33154. obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o
  33155. obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o
  33156. diff -Nur linux-3.14.17/arch/arm/mm/mmu.c linux-imx6-3.14/arch/arm/mm/mmu.c
  33157. --- linux-3.14.17/arch/arm/mm/mmu.c 2014-08-14 03:38:34.000000000 +0200
  33158. +++ linux-imx6-3.14/arch/arm/mm/mmu.c 2014-09-11 18:05:54.282007125 +0200
  33159. @@ -1436,8 +1436,8 @@
  33160. return;
  33161. /* remap kernel code and data */
  33162. - map_start = init_mm.start_code & PMD_MASK;
  33163. - map_end = ALIGN(init_mm.brk, PMD_SIZE);
  33164. + map_start = init_mm.start_code;
  33165. + map_end = init_mm.brk;
  33166. /* get a handle on things... */
  33167. pgd0 = pgd_offset_k(0);
  33168. @@ -1472,7 +1472,7 @@
  33169. }
  33170. /* remap pmds for kernel mapping */
  33171. - phys = __pa(map_start);
  33172. + phys = __pa(map_start) & PMD_MASK;
  33173. do {
  33174. *pmdk++ = __pmd(phys | pmdprot);
  33175. phys += PMD_SIZE;
  33176. diff -Nur linux-3.14.17/arch/arm/mm/proc-v7.S linux-imx6-3.14/arch/arm/mm/proc-v7.S
  33177. --- linux-3.14.17/arch/arm/mm/proc-v7.S 2014-08-14 03:38:34.000000000 +0200
  33178. +++ linux-imx6-3.14/arch/arm/mm/proc-v7.S 2014-09-11 18:05:54.286007140 +0200
  33179. @@ -336,6 +336,17 @@
  33180. mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33181. 1:
  33182. #endif
  33183. +#ifdef CONFIG_ARM_ERRATA_794072
  33184. + mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
  33185. + orr r10, r10, #1 << 4 @ set bit #4
  33186. + mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33187. +#endif
  33188. +#ifdef CONFIG_ARM_ERRATA_761320
  33189. + cmp r6, #0x40 @ present prior to r4p0
  33190. + mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
  33191. + orrlt r10, r10, #1 << 21 @ set bit #21
  33192. + mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
  33193. +#endif
  33194. /* Cortex-A15 Errata */
  33195. 3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
  33196. diff -Nur linux-3.14.17/arch/arm64/boot/dts/apm-mustang.dts linux-imx6-3.14/arch/arm64/boot/dts/apm-mustang.dts
  33197. --- linux-3.14.17/arch/arm64/boot/dts/apm-mustang.dts 2014-08-14 03:38:34.000000000 +0200
  33198. +++ linux-imx6-3.14/arch/arm64/boot/dts/apm-mustang.dts 2014-09-11 18:05:54.354007412 +0200
  33199. @@ -24,3 +24,7 @@
  33200. reg = < 0x1 0x00000000 0x0 0x80000000 >; /* Updated by bootloader */
  33201. };
  33202. };
  33203. +
  33204. +&serial0 {
  33205. + status = "ok";
  33206. +};
  33207. diff -Nur linux-3.14.17/arch/arm64/boot/dts/apm-storm.dtsi linux-imx6-3.14/arch/arm64/boot/dts/apm-storm.dtsi
  33208. --- linux-3.14.17/arch/arm64/boot/dts/apm-storm.dtsi 2014-08-14 03:38:34.000000000 +0200
  33209. +++ linux-imx6-3.14/arch/arm64/boot/dts/apm-storm.dtsi 2014-09-11 18:05:54.354007412 +0200
  33210. @@ -176,16 +176,226 @@
  33211. reg-names = "csr-reg";
  33212. clock-output-names = "eth8clk";
  33213. };
  33214. +
  33215. + sataphy1clk: sataphy1clk@1f21c000 {
  33216. + compatible = "apm,xgene-device-clock";
  33217. + #clock-cells = <1>;
  33218. + clocks = <&socplldiv2 0>;
  33219. + reg = <0x0 0x1f21c000 0x0 0x1000>;
  33220. + reg-names = "csr-reg";
  33221. + clock-output-names = "sataphy1clk";
  33222. + status = "disabled";
  33223. + csr-offset = <0x4>;
  33224. + csr-mask = <0x00>;
  33225. + enable-offset = <0x0>;
  33226. + enable-mask = <0x06>;
  33227. + };
  33228. +
  33229. + sataphy2clk: sataphy1clk@1f22c000 {
  33230. + compatible = "apm,xgene-device-clock";
  33231. + #clock-cells = <1>;
  33232. + clocks = <&socplldiv2 0>;
  33233. + reg = <0x0 0x1f22c000 0x0 0x1000>;
  33234. + reg-names = "csr-reg";
  33235. + clock-output-names = "sataphy2clk";
  33236. + status = "ok";
  33237. + csr-offset = <0x4>;
  33238. + csr-mask = <0x3a>;
  33239. + enable-offset = <0x0>;
  33240. + enable-mask = <0x06>;
  33241. + };
  33242. +
  33243. + sataphy3clk: sataphy1clk@1f23c000 {
  33244. + compatible = "apm,xgene-device-clock";
  33245. + #clock-cells = <1>;
  33246. + clocks = <&socplldiv2 0>;
  33247. + reg = <0x0 0x1f23c000 0x0 0x1000>;
  33248. + reg-names = "csr-reg";
  33249. + clock-output-names = "sataphy3clk";
  33250. + status = "ok";
  33251. + csr-offset = <0x4>;
  33252. + csr-mask = <0x3a>;
  33253. + enable-offset = <0x0>;
  33254. + enable-mask = <0x06>;
  33255. + };
  33256. +
  33257. + sata01clk: sata01clk@1f21c000 {
  33258. + compatible = "apm,xgene-device-clock";
  33259. + #clock-cells = <1>;
  33260. + clocks = <&socplldiv2 0>;
  33261. + reg = <0x0 0x1f21c000 0x0 0x1000>;
  33262. + reg-names = "csr-reg";
  33263. + clock-output-names = "sata01clk";
  33264. + csr-offset = <0x4>;
  33265. + csr-mask = <0x05>;
  33266. + enable-offset = <0x0>;
  33267. + enable-mask = <0x39>;
  33268. + };
  33269. +
  33270. + sata23clk: sata23clk@1f22c000 {
  33271. + compatible = "apm,xgene-device-clock";
  33272. + #clock-cells = <1>;
  33273. + clocks = <&socplldiv2 0>;
  33274. + reg = <0x0 0x1f22c000 0x0 0x1000>;
  33275. + reg-names = "csr-reg";
  33276. + clock-output-names = "sata23clk";
  33277. + csr-offset = <0x4>;
  33278. + csr-mask = <0x05>;
  33279. + enable-offset = <0x0>;
  33280. + enable-mask = <0x39>;
  33281. + };
  33282. +
  33283. + sata45clk: sata45clk@1f23c000 {
  33284. + compatible = "apm,xgene-device-clock";
  33285. + #clock-cells = <1>;
  33286. + clocks = <&socplldiv2 0>;
  33287. + reg = <0x0 0x1f23c000 0x0 0x1000>;
  33288. + reg-names = "csr-reg";
  33289. + clock-output-names = "sata45clk";
  33290. + csr-offset = <0x4>;
  33291. + csr-mask = <0x05>;
  33292. + enable-offset = <0x0>;
  33293. + enable-mask = <0x39>;
  33294. + };
  33295. +
  33296. + rtcclk: rtcclk@17000000 {
  33297. + compatible = "apm,xgene-device-clock";
  33298. + #clock-cells = <1>;
  33299. + clocks = <&socplldiv2 0>;
  33300. + reg = <0x0 0x17000000 0x0 0x2000>;
  33301. + reg-names = "csr-reg";
  33302. + csr-offset = <0xc>;
  33303. + csr-mask = <0x2>;
  33304. + enable-offset = <0x10>;
  33305. + enable-mask = <0x2>;
  33306. + clock-output-names = "rtcclk";
  33307. + };
  33308. };
  33309. serial0: serial@1c020000 {
  33310. + status = "disabled";
  33311. device_type = "serial";
  33312. - compatible = "ns16550";
  33313. + compatible = "ns16550a";
  33314. reg = <0 0x1c020000 0x0 0x1000>;
  33315. reg-shift = <2>;
  33316. clock-frequency = <10000000>; /* Updated by bootloader */
  33317. interrupt-parent = <&gic>;
  33318. interrupts = <0x0 0x4c 0x4>;
  33319. };
  33320. +
  33321. + serial1: serial@1c021000 {
  33322. + status = "disabled";
  33323. + device_type = "serial";
  33324. + compatible = "ns16550a";
  33325. + reg = <0 0x1c021000 0x0 0x1000>;
  33326. + reg-shift = <2>;
  33327. + clock-frequency = <10000000>; /* Updated by bootloader */
  33328. + interrupt-parent = <&gic>;
  33329. + interrupts = <0x0 0x4d 0x4>;
  33330. + };
  33331. +
  33332. + serial2: serial@1c022000 {
  33333. + status = "disabled";
  33334. + device_type = "serial";
  33335. + compatible = "ns16550a";
  33336. + reg = <0 0x1c022000 0x0 0x1000>;
  33337. + reg-shift = <2>;
  33338. + clock-frequency = <10000000>; /* Updated by bootloader */
  33339. + interrupt-parent = <&gic>;
  33340. + interrupts = <0x0 0x4e 0x4>;
  33341. + };
  33342. +
  33343. + serial3: serial@1c023000 {
  33344. + status = "disabled";
  33345. + device_type = "serial";
  33346. + compatible = "ns16550a";
  33347. + reg = <0 0x1c023000 0x0 0x1000>;
  33348. + reg-shift = <2>;
  33349. + clock-frequency = <10000000>; /* Updated by bootloader */
  33350. + interrupt-parent = <&gic>;
  33351. + interrupts = <0x0 0x4f 0x4>;
  33352. + };
  33353. +
  33354. + phy1: phy@1f21a000 {
  33355. + compatible = "apm,xgene-phy";
  33356. + reg = <0x0 0x1f21a000 0x0 0x100>;
  33357. + #phy-cells = <1>;
  33358. + clocks = <&sataphy1clk 0>;
  33359. + status = "disabled";
  33360. + apm,tx-boost-gain = <30 30 30 30 30 30>;
  33361. + apm,tx-eye-tuning = <2 10 10 2 10 10>;
  33362. + };
  33363. +
  33364. + phy2: phy@1f22a000 {
  33365. + compatible = "apm,xgene-phy";
  33366. + reg = <0x0 0x1f22a000 0x0 0x100>;
  33367. + #phy-cells = <1>;
  33368. + clocks = <&sataphy2clk 0>;
  33369. + status = "ok";
  33370. + apm,tx-boost-gain = <30 30 30 30 30 30>;
  33371. + apm,tx-eye-tuning = <1 10 10 2 10 10>;
  33372. + };
  33373. +
  33374. + phy3: phy@1f23a000 {
  33375. + compatible = "apm,xgene-phy";
  33376. + reg = <0x0 0x1f23a000 0x0 0x100>;
  33377. + #phy-cells = <1>;
  33378. + clocks = <&sataphy3clk 0>;
  33379. + status = "ok";
  33380. + apm,tx-boost-gain = <31 31 31 31 31 31>;
  33381. + apm,tx-eye-tuning = <2 10 10 2 10 10>;
  33382. + };
  33383. +
  33384. + sata1: sata@1a000000 {
  33385. + compatible = "apm,xgene-ahci";
  33386. + reg = <0x0 0x1a000000 0x0 0x1000>,
  33387. + <0x0 0x1f210000 0x0 0x1000>,
  33388. + <0x0 0x1f21d000 0x0 0x1000>,
  33389. + <0x0 0x1f21e000 0x0 0x1000>,
  33390. + <0x0 0x1f217000 0x0 0x1000>;
  33391. + interrupts = <0x0 0x86 0x4>;
  33392. + dma-coherent;
  33393. + status = "disabled";
  33394. + clocks = <&sata01clk 0>;
  33395. + phys = <&phy1 0>;
  33396. + phy-names = "sata-phy";
  33397. + };
  33398. +
  33399. + sata2: sata@1a400000 {
  33400. + compatible = "apm,xgene-ahci";
  33401. + reg = <0x0 0x1a400000 0x0 0x1000>,
  33402. + <0x0 0x1f220000 0x0 0x1000>,
  33403. + <0x0 0x1f22d000 0x0 0x1000>,
  33404. + <0x0 0x1f22e000 0x0 0x1000>,
  33405. + <0x0 0x1f227000 0x0 0x1000>;
  33406. + interrupts = <0x0 0x87 0x4>;
  33407. + dma-coherent;
  33408. + status = "ok";
  33409. + clocks = <&sata23clk 0>;
  33410. + phys = <&phy2 0>;
  33411. + phy-names = "sata-phy";
  33412. + };
  33413. +
  33414. + sata3: sata@1a800000 {
  33415. + compatible = "apm,xgene-ahci";
  33416. + reg = <0x0 0x1a800000 0x0 0x1000>,
  33417. + <0x0 0x1f230000 0x0 0x1000>,
  33418. + <0x0 0x1f23d000 0x0 0x1000>,
  33419. + <0x0 0x1f23e000 0x0 0x1000>;
  33420. + interrupts = <0x0 0x88 0x4>;
  33421. + dma-coherent;
  33422. + status = "ok";
  33423. + clocks = <&sata45clk 0>;
  33424. + phys = <&phy3 0>;
  33425. + phy-names = "sata-phy";
  33426. + };
  33427. +
  33428. + rtc: rtc@10510000 {
  33429. + compatible = "apm,xgene-rtc";
  33430. + reg = <0x0 0x10510000 0x0 0x400>;
  33431. + interrupts = <0x0 0x46 0x4>;
  33432. + #clock-cells = <1>;
  33433. + clocks = <&rtcclk 0>;
  33434. + };
  33435. };
  33436. };
  33437. diff -Nur linux-3.14.17/arch/arm64/boot/dts/clcd-panels.dtsi linux-imx6-3.14/arch/arm64/boot/dts/clcd-panels.dtsi
  33438. --- linux-3.14.17/arch/arm64/boot/dts/clcd-panels.dtsi 1970-01-01 01:00:00.000000000 +0100
  33439. +++ linux-imx6-3.14/arch/arm64/boot/dts/clcd-panels.dtsi 2014-09-11 18:05:54.354007412 +0200
  33440. @@ -0,0 +1,52 @@
  33441. +/*
  33442. + * ARM Ltd. Versatile Express
  33443. + *
  33444. + */
  33445. +
  33446. +/ {
  33447. + panels {
  33448. + panel@0 {
  33449. + compatible = "panel";
  33450. + mode = "VGA";
  33451. + refresh = <60>;
  33452. + xres = <640>;
  33453. + yres = <480>;
  33454. + pixclock = <39721>;
  33455. + left_margin = <40>;
  33456. + right_margin = <24>;
  33457. + upper_margin = <32>;
  33458. + lower_margin = <11>;
  33459. + hsync_len = <96>;
  33460. + vsync_len = <2>;
  33461. + sync = <0>;
  33462. + vmode = "FB_VMODE_NONINTERLACED";
  33463. +
  33464. + tim2 = "TIM2_BCD", "TIM2_IPC";
  33465. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  33466. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  33467. + bpp = <16>;
  33468. + };
  33469. +
  33470. + panel@1 {
  33471. + compatible = "panel";
  33472. + mode = "XVGA";
  33473. + refresh = <60>;
  33474. + xres = <1024>;
  33475. + yres = <768>;
  33476. + pixclock = <15748>;
  33477. + left_margin = <152>;
  33478. + right_margin = <48>;
  33479. + upper_margin = <23>;
  33480. + lower_margin = <3>;
  33481. + hsync_len = <104>;
  33482. + vsync_len = <4>;
  33483. + sync = <0>;
  33484. + vmode = "FB_VMODE_NONINTERLACED";
  33485. +
  33486. + tim2 = "TIM2_BCD", "TIM2_IPC";
  33487. + cntl = "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
  33488. + caps = "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
  33489. + bpp = <16>;
  33490. + };
  33491. + };
  33492. +};
  33493. diff -Nur linux-3.14.17/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts linux-imx6-3.14/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts
  33494. --- linux-3.14.17/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts 1970-01-01 01:00:00.000000000 +0100
  33495. +++ linux-imx6-3.14/arch/arm64/boot/dts/fvp-base-gicv2-psci.dts 2014-09-11 18:05:54.354007412 +0200
  33496. @@ -0,0 +1,266 @@
  33497. +/*
  33498. + * Copyright (c) 2013, ARM Limited. All rights reserved.
  33499. + *
  33500. + * Redistribution and use in source and binary forms, with or without
  33501. + * modification, are permitted provided that the following conditions are met:
  33502. + *
  33503. + * Redistributions of source code must retain the above copyright notice, this
  33504. + * list of conditions and the following disclaimer.
  33505. + *
  33506. + * Redistributions in binary form must reproduce the above copyright notice,
  33507. + * this list of conditions and the following disclaimer in the documentation
  33508. + * and/or other materials provided with the distribution.
  33509. + *
  33510. + * Neither the name of ARM nor the names of its contributors may be used
  33511. + * to endorse or promote products derived from this software without specific
  33512. + * prior written permission.
  33513. + *
  33514. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33515. + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33516. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33517. + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  33518. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33519. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33520. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33521. + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33522. + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33523. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33524. + * POSSIBILITY OF SUCH DAMAGE.
  33525. + */
  33526. +
  33527. +/dts-v1/;
  33528. +
  33529. +/memreserve/ 0x80000000 0x00010000;
  33530. +
  33531. +/ {
  33532. +};
  33533. +
  33534. +/ {
  33535. + model = "FVP Base";
  33536. + compatible = "arm,vfp-base", "arm,vexpress";
  33537. + interrupt-parent = <&gic>;
  33538. + #address-cells = <2>;
  33539. + #size-cells = <2>;
  33540. +
  33541. + chosen { };
  33542. +
  33543. + aliases {
  33544. + serial0 = &v2m_serial0;
  33545. + serial1 = &v2m_serial1;
  33546. + serial2 = &v2m_serial2;
  33547. + serial3 = &v2m_serial3;
  33548. + };
  33549. +
  33550. + psci {
  33551. + compatible = "arm,psci";
  33552. + method = "smc";
  33553. + cpu_suspend = <0xc4000001>;
  33554. + cpu_off = <0x84000002>;
  33555. + cpu_on = <0xc4000003>;
  33556. + };
  33557. +
  33558. + cpus {
  33559. + #address-cells = <2>;
  33560. + #size-cells = <0>;
  33561. +
  33562. + big0: cpu@0 {
  33563. + device_type = "cpu";
  33564. + compatible = "arm,cortex-a57", "arm,armv8";
  33565. + reg = <0x0 0x0>;
  33566. + enable-method = "psci";
  33567. + clock-frequency = <1000000>;
  33568. + };
  33569. + big1: cpu@1 {
  33570. + device_type = "cpu";
  33571. + compatible = "arm,cortex-a57", "arm,armv8";
  33572. + reg = <0x0 0x1>;
  33573. + enable-method = "psci";
  33574. + clock-frequency = <1000000>;
  33575. + };
  33576. + big2: cpu@2 {
  33577. + device_type = "cpu";
  33578. + compatible = "arm,cortex-a57", "arm,armv8";
  33579. + reg = <0x0 0x2>;
  33580. + enable-method = "psci";
  33581. + clock-frequency = <1000000>;
  33582. + };
  33583. + big3: cpu@3 {
  33584. + device_type = "cpu";
  33585. + compatible = "arm,cortex-a57", "arm,armv8";
  33586. + reg = <0x0 0x3>;
  33587. + enable-method = "psci";
  33588. + clock-frequency = <1000000>;
  33589. + };
  33590. + little0: cpu@100 {
  33591. + device_type = "cpu";
  33592. + compatible = "arm,cortex-a53", "arm,armv8";
  33593. + reg = <0x0 0x100>;
  33594. + enable-method = "psci";
  33595. + clock-frequency = <1000000>;
  33596. + };
  33597. + little1: cpu@101 {
  33598. + device_type = "cpu";
  33599. + compatible = "arm,cortex-a53", "arm,armv8";
  33600. + reg = <0x0 0x101>;
  33601. + enable-method = "psci";
  33602. + clock-frequency = <1000000>;
  33603. + };
  33604. + little2: cpu@102 {
  33605. + device_type = "cpu";
  33606. + compatible = "arm,cortex-a53", "arm,armv8";
  33607. + reg = <0x0 0x102>;
  33608. + enable-method = "psci";
  33609. + clock-frequency = <1000000>;
  33610. + };
  33611. + little3: cpu@103 {
  33612. + device_type = "cpu";
  33613. + compatible = "arm,cortex-a53", "arm,armv8";
  33614. + reg = <0x0 0x103>;
  33615. + enable-method = "psci";
  33616. + clock-frequency = <1000000>;
  33617. + };
  33618. +
  33619. + cpu-map {
  33620. + cluster0 {
  33621. + core0 {
  33622. + cpu = <&big0>;
  33623. + };
  33624. + core1 {
  33625. + cpu = <&big1>;
  33626. + };
  33627. + core2 {
  33628. + cpu = <&big2>;
  33629. + };
  33630. + core3 {
  33631. + cpu = <&big3>;
  33632. + };
  33633. + };
  33634. + cluster1 {
  33635. + core0 {
  33636. + cpu = <&little0>;
  33637. + };
  33638. + core1 {
  33639. + cpu = <&little1>;
  33640. + };
  33641. + core2 {
  33642. + cpu = <&little2>;
  33643. + };
  33644. + core3 {
  33645. + cpu = <&little3>;
  33646. + };
  33647. + };
  33648. + };
  33649. + };
  33650. +
  33651. + memory@80000000 {
  33652. + device_type = "memory";
  33653. + reg = <0x00000000 0x80000000 0 0x80000000>,
  33654. + <0x00000008 0x80000000 0 0x80000000>;
  33655. + };
  33656. +
  33657. + gic: interrupt-controller@2f000000 {
  33658. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  33659. + #interrupt-cells = <3>;
  33660. + #address-cells = <0>;
  33661. + interrupt-controller;
  33662. + reg = <0x0 0x2f000000 0 0x10000>,
  33663. + <0x0 0x2c000000 0 0x2000>,
  33664. + <0x0 0x2c010000 0 0x2000>,
  33665. + <0x0 0x2c02F000 0 0x2000>;
  33666. + interrupts = <1 9 0xf04>;
  33667. + };
  33668. +
  33669. + timer {
  33670. + compatible = "arm,armv8-timer";
  33671. + interrupts = <1 13 0xff01>,
  33672. + <1 14 0xff01>,
  33673. + <1 11 0xff01>,
  33674. + <1 10 0xff01>;
  33675. + clock-frequency = <100000000>;
  33676. + };
  33677. +
  33678. + timer@2a810000 {
  33679. + compatible = "arm,armv7-timer-mem";
  33680. + reg = <0x0 0x2a810000 0x0 0x10000>;
  33681. + clock-frequency = <100000000>;
  33682. + #address-cells = <2>;
  33683. + #size-cells = <2>;
  33684. + ranges;
  33685. + frame@2a820000 {
  33686. + frame-number = <0>;
  33687. + interrupts = <0 25 4>;
  33688. + reg = <0x0 0x2a820000 0x0 0x10000>;
  33689. + };
  33690. + };
  33691. +
  33692. + pmu {
  33693. + compatible = "arm,armv8-pmuv3";
  33694. + interrupts = <0 60 4>,
  33695. + <0 61 4>,
  33696. + <0 62 4>,
  33697. + <0 63 4>;
  33698. + };
  33699. +
  33700. + smb {
  33701. + compatible = "simple-bus";
  33702. +
  33703. + #address-cells = <2>;
  33704. + #size-cells = <1>;
  33705. + ranges = <0 0 0 0x08000000 0x04000000>,
  33706. + <1 0 0 0x14000000 0x04000000>,
  33707. + <2 0 0 0x18000000 0x04000000>,
  33708. + <3 0 0 0x1c000000 0x04000000>,
  33709. + <4 0 0 0x0c000000 0x04000000>,
  33710. + <5 0 0 0x10000000 0x04000000>;
  33711. +
  33712. + #interrupt-cells = <1>;
  33713. + interrupt-map-mask = <0 0 63>;
  33714. + interrupt-map = <0 0 0 &gic 0 0 4>,
  33715. + <0 0 1 &gic 0 1 4>,
  33716. + <0 0 2 &gic 0 2 4>,
  33717. + <0 0 3 &gic 0 3 4>,
  33718. + <0 0 4 &gic 0 4 4>,
  33719. + <0 0 5 &gic 0 5 4>,
  33720. + <0 0 6 &gic 0 6 4>,
  33721. + <0 0 7 &gic 0 7 4>,
  33722. + <0 0 8 &gic 0 8 4>,
  33723. + <0 0 9 &gic 0 9 4>,
  33724. + <0 0 10 &gic 0 10 4>,
  33725. + <0 0 11 &gic 0 11 4>,
  33726. + <0 0 12 &gic 0 12 4>,
  33727. + <0 0 13 &gic 0 13 4>,
  33728. + <0 0 14 &gic 0 14 4>,
  33729. + <0 0 15 &gic 0 15 4>,
  33730. + <0 0 16 &gic 0 16 4>,
  33731. + <0 0 17 &gic 0 17 4>,
  33732. + <0 0 18 &gic 0 18 4>,
  33733. + <0 0 19 &gic 0 19 4>,
  33734. + <0 0 20 &gic 0 20 4>,
  33735. + <0 0 21 &gic 0 21 4>,
  33736. + <0 0 22 &gic 0 22 4>,
  33737. + <0 0 23 &gic 0 23 4>,
  33738. + <0 0 24 &gic 0 24 4>,
  33739. + <0 0 25 &gic 0 25 4>,
  33740. + <0 0 26 &gic 0 26 4>,
  33741. + <0 0 27 &gic 0 27 4>,
  33742. + <0 0 28 &gic 0 28 4>,
  33743. + <0 0 29 &gic 0 29 4>,
  33744. + <0 0 30 &gic 0 30 4>,
  33745. + <0 0 31 &gic 0 31 4>,
  33746. + <0 0 32 &gic 0 32 4>,
  33747. + <0 0 33 &gic 0 33 4>,
  33748. + <0 0 34 &gic 0 34 4>,
  33749. + <0 0 35 &gic 0 35 4>,
  33750. + <0 0 36 &gic 0 36 4>,
  33751. + <0 0 37 &gic 0 37 4>,
  33752. + <0 0 38 &gic 0 38 4>,
  33753. + <0 0 39 &gic 0 39 4>,
  33754. + <0 0 40 &gic 0 40 4>,
  33755. + <0 0 41 &gic 0 41 4>,
  33756. + <0 0 42 &gic 0 42 4>;
  33757. +
  33758. + /include/ "rtsm_ve-motherboard.dtsi"
  33759. + };
  33760. +};
  33761. +
  33762. +/include/ "clcd-panels.dtsi"
  33763. diff -Nur linux-3.14.17/arch/arm64/boot/dts/juno.dts linux-imx6-3.14/arch/arm64/boot/dts/juno.dts
  33764. --- linux-3.14.17/arch/arm64/boot/dts/juno.dts 1970-01-01 01:00:00.000000000 +0100
  33765. +++ linux-imx6-3.14/arch/arm64/boot/dts/juno.dts 2014-09-11 18:05:54.354007412 +0200
  33766. @@ -0,0 +1,498 @@
  33767. +/*
  33768. + * ARM Ltd. Juno Plaform
  33769. + *
  33770. + * Fast Models FVP v2 support
  33771. + */
  33772. +
  33773. +/dts-v1/;
  33774. +
  33775. +#include <dt-bindings/interrupt-controller/arm-gic.h>
  33776. +
  33777. +/ {
  33778. + model = "Juno";
  33779. + compatible = "arm,juno", "arm,vexpress";
  33780. + interrupt-parent = <&gic>;
  33781. + #address-cells = <2>;
  33782. + #size-cells = <2>;
  33783. +
  33784. + aliases {
  33785. + serial0 = &soc_uart0;
  33786. + };
  33787. +
  33788. + cpus {
  33789. + #address-cells = <2>;
  33790. + #size-cells = <0>;
  33791. +
  33792. + cpu@100 {
  33793. + device_type = "cpu";
  33794. + compatible = "arm,cortex-a53","arm,armv8";
  33795. + reg = <0x0 0x100>;
  33796. + enable-method = "psci";
  33797. + };
  33798. +
  33799. + cpu@101 {
  33800. + device_type = "cpu";
  33801. + compatible = "arm,cortex-a53","arm,armv8";
  33802. + reg = <0x0 0x101>;
  33803. + enable-method = "psci";
  33804. + };
  33805. +
  33806. + cpu@102 {
  33807. + device_type = "cpu";
  33808. + compatible = "arm,cortex-a53","arm,armv8";
  33809. + reg = <0x0 0x102>;
  33810. + enable-method = "psci";
  33811. + };
  33812. +
  33813. + cpu@103 {
  33814. + device_type = "cpu";
  33815. + compatible = "arm,cortex-a53","arm,armv8";
  33816. + reg = <0x0 0x103>;
  33817. + enable-method = "psci";
  33818. + };
  33819. +
  33820. + cpu@0 {
  33821. + device_type = "cpu";
  33822. + compatible = "arm,cortex-a57","arm,armv8";
  33823. + reg = <0x0 0x0>;
  33824. + enable-method = "psci";
  33825. + };
  33826. +
  33827. + cpu@1 {
  33828. + device_type = "cpu";
  33829. + compatible = "arm,cortex-a57","arm,armv8";
  33830. + reg = <0x0 0x1>;
  33831. + enable-method = "psci";
  33832. + };
  33833. + };
  33834. +
  33835. + memory@80000000 {
  33836. + device_type = "memory";
  33837. + reg = <0x00000000 0x80000000 0x0 0x80000000>,
  33838. + <0x00000008 0x80000000 0x1 0x80000000>;
  33839. + };
  33840. +
  33841. + /* memory@14000000 {
  33842. + device_type = "memory";
  33843. + reg = <0x00000000 0x14000000 0x0 0x02000000>;
  33844. + }; */
  33845. +
  33846. + gic: interrupt-controller@2c001000 {
  33847. + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
  33848. + #interrupt-cells = <3>;
  33849. + #address-cells = <0>;
  33850. + interrupt-controller;
  33851. + reg = <0x0 0x2c010000 0 0x1000>,
  33852. + <0x0 0x2c02f000 0 0x1000>,
  33853. + <0x0 0x2c04f000 0 0x2000>,
  33854. + <0x0 0x2c06f000 0 0x2000>;
  33855. + interrupts = <GIC_PPI 9 0xf04>;
  33856. + };
  33857. +
  33858. + msi0: msi@2c1c0000 {
  33859. + compatible = "arm,gic-msi";
  33860. + reg = <0x0 0x2c1c0000 0 0x10000
  33861. + 0x0 0x2c1d0000 0 0x10000
  33862. + 0x0 0x2c1e0000 0 0x10000
  33863. + 0x0 0x2c1f0000 0 0x10000>;
  33864. + };
  33865. +
  33866. + timer {
  33867. + compatible = "arm,armv8-timer";
  33868. + interrupts = <GIC_PPI 13 0xff01>,
  33869. + <GIC_PPI 14 0xff01>,
  33870. + <GIC_PPI 11 0xff01>,
  33871. + <GIC_PPI 10 0xff01>;
  33872. + };
  33873. +
  33874. + pmu {
  33875. + compatible = "arm,armv8-pmuv3";
  33876. + interrupts = <GIC_SPI 60 4>,
  33877. + <GIC_SPI 61 4>,
  33878. + <GIC_SPI 62 4>,
  33879. + <GIC_SPI 63 4>;
  33880. + };
  33881. +
  33882. + psci {
  33883. + compatible = "arm,psci";
  33884. + method = "smc";
  33885. + cpu_suspend = <0xC4000001>;
  33886. + cpu_off = <0x84000002>;
  33887. + cpu_on = <0xC4000003>;
  33888. + migrate = <0xC4000005>;
  33889. + };
  33890. +
  33891. + pci0: pci@30000000 {
  33892. + compatible = "arm,pcie-xr3";
  33893. + device_type = "pci";
  33894. + reg = <0 0x7ff30000 0 0x1000
  33895. + 0 0x7ff20000 0 0x10000
  33896. + 0 0x40000000 0 0x10000000>;
  33897. + bus-range = <0 255>;
  33898. + #address-cells = <3>;
  33899. + #size-cells = <2>;
  33900. + ranges = <0x01000000 0x0 0x00000000 0x00 0x5ff00000 0x0 0x00100000
  33901. + 0x02000000 0x0 0x00000000 0x40 0x00000000 0x0 0x80000000
  33902. + 0x42000000 0x0 0x80000000 0x40 0x80000000 0x0 0x80000000>;
  33903. + #interrupt-cells = <1>;
  33904. + interrupt-map-mask = <0 0 0 7>;
  33905. + interrupt-map = <0 0 0 1 &gic 0 136 4
  33906. + 0 0 0 2 &gic 0 137 4
  33907. + 0 0 0 3 &gic 0 138 4
  33908. + 0 0 0 4 &gic 0 139 4>;
  33909. + };
  33910. +
  33911. + scpi: scpi@2b1f0000 {
  33912. + compatible = "arm,scpi-mhu";
  33913. + reg = <0x0 0x2b1f0000 0x0 0x10000>, /* MHU registers */
  33914. + <0x0 0x2e000000 0x0 0x10000>; /* Payload area */
  33915. + interrupts = <0 36 4>, /* low priority interrupt */
  33916. + <0 35 4>, /* high priority interrupt */
  33917. + <0 37 4>; /* secure channel interrupt */
  33918. + #clock-cells = <1>;
  33919. + clock-output-names = "a57", "a53", "gpu", "hdlcd0", "hdlcd1";
  33920. + };
  33921. +
  33922. + hdlcd0_osc: scpi_osc@3 {
  33923. + compatible = "arm,scpi-osc";
  33924. + #clock-cells = <0>;
  33925. + clocks = <&scpi 3>;
  33926. + frequency-range = <23000000 210000000>;
  33927. + clock-output-names = "pxlclk0";
  33928. + };
  33929. +
  33930. + hdlcd1_osc: scpi_osc@4 {
  33931. + compatible = "arm,scpi-osc";
  33932. + #clock-cells = <0>;
  33933. + clocks = <&scpi 4>;
  33934. + frequency-range = <23000000 210000000>;
  33935. + clock-output-names = "pxlclk1";
  33936. + };
  33937. +
  33938. + soc_uartclk: refclk72738khz {
  33939. + compatible = "fixed-clock";
  33940. + #clock-cells = <0>;
  33941. + clock-frequency = <7273800>;
  33942. + clock-output-names = "juno:uartclk";
  33943. + };
  33944. +
  33945. + soc_refclk24mhz: clk24mhz {
  33946. + compatible = "fixed-clock";
  33947. + #clock-cells = <0>;
  33948. + clock-frequency = <24000000>;
  33949. + clock-output-names = "juno:clk24mhz";
  33950. + };
  33951. +
  33952. + mb_eth25mhz: clk25mhz {
  33953. + compatible = "fixed-clock";
  33954. + #clock-cells = <0>;
  33955. + clock-frequency = <25000000>;
  33956. + clock-output-names = "ethclk25mhz";
  33957. + };
  33958. +
  33959. + soc_usb48mhz: clk48mhz {
  33960. + compatible = "fixed-clock";
  33961. + #clock-cells = <0>;
  33962. + clock-frequency = <48000000>;
  33963. + clock-output-names = "clk48mhz";
  33964. + };
  33965. +
  33966. + soc_smc50mhz: clk50mhz {
  33967. + compatible = "fixed-clock";
  33968. + #clock-cells = <0>;
  33969. + clock-frequency = <50000000>;
  33970. + clock-output-names = "smc_clk";
  33971. + };
  33972. +
  33973. + soc_refclk100mhz: refclk100mhz {
  33974. + compatible = "fixed-clock";
  33975. + #clock-cells = <0>;
  33976. + clock-frequency = <100000000>;
  33977. + clock-output-names = "apb_pclk";
  33978. + };
  33979. +
  33980. + soc_faxiclk: refclk533mhz {
  33981. + compatible = "fixed-clock";
  33982. + #clock-cells = <0>;
  33983. + clock-frequency = <533000000>;
  33984. + clock-output-names = "faxi_clk";
  33985. + };
  33986. +
  33987. + soc_fixed_3v3: fixedregulator@0 {
  33988. + compatible = "regulator-fixed";
  33989. + regulator-name = "3V3";
  33990. + regulator-min-microvolt = <3300000>;
  33991. + regulator-max-microvolt = <3300000>;
  33992. + regulator-always-on;
  33993. + };
  33994. +
  33995. + memory-controller@7ffd0000 {
  33996. + compatible = "arm,pl354", "arm,primecell";
  33997. + reg = <0 0x7ffd0000 0 0x1000>;
  33998. + interrupts = <0 86 4>,
  33999. + <0 87 4>;
  34000. + clocks = <&soc_smc50mhz>;
  34001. + clock-names = "apb_pclk";
  34002. + chip5-memwidth = <16>;
  34003. + };
  34004. +
  34005. + dma0: dma@0x7ff00000 {
  34006. + compatible = "arm,pl330", "arm,primecell";
  34007. + reg = <0x0 0x7ff00000 0 0x1000>;
  34008. + interrupts = <0 95 4>,
  34009. + <0 88 4>,
  34010. + <0 89 4>,
  34011. + <0 90 4>,
  34012. + <0 91 4>,
  34013. + <0 108 4>,
  34014. + <0 109 4>,
  34015. + <0 110 4>,
  34016. + <0 111 4>;
  34017. + #dma-cells = <1>;
  34018. + #dma-channels = <8>;
  34019. + #dma-requests = <32>;
  34020. + clocks = <&soc_faxiclk>;
  34021. + clock-names = "apb_pclk";
  34022. + };
  34023. +
  34024. + soc_uart0: uart@7ff80000 {
  34025. + compatible = "arm,pl011", "arm,primecell";
  34026. + reg = <0x0 0x7ff80000 0x0 0x1000>;
  34027. + interrupts = <0 83 4>;
  34028. + clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
  34029. + clock-names = "uartclk", "apb_pclk";
  34030. + dmas = <&dma0 1
  34031. + &dma0 2>;
  34032. + dma-names = "rx", "tx";
  34033. + };
  34034. +
  34035. + /* this UART is reserved for secure software.
  34036. + soc_uart1: uart@7ff70000 {
  34037. + compatible = "arm,pl011", "arm,primecell";
  34038. + reg = <0x0 0x7ff70000 0x0 0x1000>;
  34039. + interrupts = <0 84 4>;
  34040. + clocks = <&soc_uartclk>, <&soc_refclk100mhz>;
  34041. + clock-names = "uartclk", "apb_pclk";
  34042. + }; */
  34043. +
  34044. + ulpi_phy: phy@0 {
  34045. + compatible = "phy-ulpi-generic";
  34046. + reg = <0x0 0x94 0x0 0x4>;
  34047. + phy-id = <0>;
  34048. + };
  34049. +
  34050. + ehci@7ffc0000 {
  34051. + compatible = "snps,ehci-h20ahb";
  34052. + /* compatible = "arm,h20ahb-ehci"; */
  34053. + reg = <0x0 0x7ffc0000 0x0 0x10000>;
  34054. + interrupts = <0 117 4>;
  34055. + clocks = <&soc_usb48mhz>;
  34056. + clock-names = "otg";
  34057. + phys = <&ulpi_phy>;
  34058. + };
  34059. +
  34060. + ohci@0x7ffb0000 {
  34061. + compatible = "generic-ohci";
  34062. + reg = <0x0 0x7ffb0000 0x0 0x10000>;
  34063. + interrupts = <0 116 4>;
  34064. + clocks = <&soc_usb48mhz>;
  34065. + clock-names = "otg";
  34066. + };
  34067. +
  34068. + i2c@0x7ffa0000 {
  34069. + #address-cells = <1>;
  34070. + #size-cells = <0>;
  34071. + compatible = "snps,designware-i2c";
  34072. + reg = <0x0 0x7ffa0000 0x0 0x1000>;
  34073. + interrupts = <0 104 4>;
  34074. + clock-frequency = <400000>;
  34075. + i2c-sda-hold-time-ns = <500>;
  34076. + clocks = <&soc_smc50mhz>;
  34077. +
  34078. + dvi0: dvi-transmitter@70 {
  34079. + compatible = "nxp,tda998x";
  34080. + reg = <0x70>;
  34081. + };
  34082. +
  34083. + dvi1: dvi-transmitter@71 {
  34084. + compatible = "nxp,tda998x";
  34085. + reg = <0x71>;
  34086. + };
  34087. + };
  34088. +
  34089. + /* mmci@1c050000 {
  34090. + compatible = "arm,pl180", "arm,primecell";
  34091. + reg = <0x0 0x1c050000 0x0 0x1000>;
  34092. + interrupts = <0 73 4>,
  34093. + <0 74 4>;
  34094. + max-frequency = <12000000>;
  34095. + vmmc-supply = <&soc_fixed_3v3>;
  34096. + clocks = <&soc_refclk24mhz>, <&soc_refclk100mhz>;
  34097. + clock-names = "mclk", "apb_pclk";
  34098. + }; */
  34099. +
  34100. + hdlcd@7ff60000 {
  34101. + compatible = "arm,hdlcd";
  34102. + reg = <0 0x7ff60000 0 0x1000>;
  34103. + interrupts = <0 85 4>;
  34104. + clocks = <&hdlcd0_osc>;
  34105. + clock-names = "pxlclk";
  34106. + i2c-slave = <&dvi0>;
  34107. +
  34108. + /* display-timings {
  34109. + native-mode = <&timing0>;
  34110. + timing0: timing@0 {
  34111. + /* 1024 x 768 framebufer, standard VGA timings * /
  34112. + clock-frequency = <65000>;
  34113. + hactive = <1024>;
  34114. + vactive = <768>;
  34115. + hfront-porch = <24>;
  34116. + hback-porch = <160>;
  34117. + hsync-len = <136>;
  34118. + vfront-porch = <3>;
  34119. + vback-porch = <29>;
  34120. + vsync-len = <6>;
  34121. + };
  34122. + }; */
  34123. + };
  34124. +
  34125. + hdlcd@7ff50000 {
  34126. + compatible = "arm,hdlcd";
  34127. + reg = <0 0x7ff50000 0 0x1000>;
  34128. + interrupts = <0 93 4>;
  34129. + clocks = <&hdlcd1_osc>;
  34130. + clock-names = "pxlclk";
  34131. + i2c-slave = <&dvi1>;
  34132. +
  34133. + display-timings {
  34134. + native-mode = <&timing1>;
  34135. + timing1: timing@1 {
  34136. + /* 1024 x 768 framebufer, standard VGA timings */
  34137. + clock-frequency = <65000>;
  34138. + hactive = <1024>;
  34139. + vactive = <768>;
  34140. + hfront-porch = <24>;
  34141. + hback-porch = <160>;
  34142. + hsync-len = <136>;
  34143. + vfront-porch = <3>;
  34144. + vback-porch = <29>;
  34145. + vsync-len = <6>;
  34146. + };
  34147. + };
  34148. + };
  34149. +
  34150. + smb {
  34151. + compatible = "simple-bus";
  34152. + #address-cells = <2>;
  34153. + #size-cells = <1>;
  34154. + ranges = <0 0 0 0x08000000 0x04000000>,
  34155. + <1 0 0 0x14000000 0x04000000>,
  34156. + <2 0 0 0x18000000 0x04000000>,
  34157. + <3 0 0 0x1c000000 0x04000000>,
  34158. + <4 0 0 0x0c000000 0x04000000>,
  34159. + <5 0 0 0x10000000 0x04000000>;
  34160. +
  34161. + #interrupt-cells = <1>;
  34162. + interrupt-map-mask = <0 0 15>;
  34163. + interrupt-map = <0 0 0 &gic 0 68 4>,
  34164. + <0 0 1 &gic 0 69 4>,
  34165. + <0 0 2 &gic 0 70 4>,
  34166. + <0 0 3 &gic 0 160 4>,
  34167. + <0 0 4 &gic 0 161 4>,
  34168. + <0 0 5 &gic 0 162 4>,
  34169. + <0 0 6 &gic 0 163 4>,
  34170. + <0 0 7 &gic 0 164 4>,
  34171. + <0 0 8 &gic 0 165 4>,
  34172. + <0 0 9 &gic 0 166 4>,
  34173. + <0 0 10 &gic 0 167 4>,
  34174. + <0 0 11 &gic 0 168 4>,
  34175. + <0 0 12 &gic 0 169 4>;
  34176. +
  34177. + motherboard {
  34178. + model = "V2M-Juno";
  34179. + arm,hbi = <0x252>;
  34180. + arm,vexpress,site = <0>;
  34181. + arm,v2m-memory-map = "rs1";
  34182. + compatible = "arm,vexpress,v2p-p1", "simple-bus";
  34183. + #address-cells = <2>; /* SMB chipselect number and offset */
  34184. + #size-cells = <1>;
  34185. + #interrupt-cells = <1>;
  34186. + ranges;
  34187. +
  34188. + usb@5,00000000 {
  34189. + compatible = "nxp,usb-isp1763";
  34190. + reg = <5 0x00000000 0x20000>;
  34191. + bus-width = <16>;
  34192. + interrupts = <4>;
  34193. + };
  34194. +
  34195. + ethernet@2,00000000 {
  34196. + compatible = "smsc,lan9118", "smsc,lan9115";
  34197. + reg = <2 0x00000000 0x10000>;
  34198. + interrupts = <3>;
  34199. + phy-mode = "mii";
  34200. + reg-io-width = <4>;
  34201. + smsc,irq-active-high;
  34202. + smsc,irq-push-pull;
  34203. + clocks = <&mb_eth25mhz>;
  34204. + vdd33a-supply = <&soc_fixed_3v3>; /* change this */
  34205. + vddvario-supply = <&soc_fixed_3v3>; /* and this */
  34206. + };
  34207. +
  34208. + iofpga@3,00000000 {
  34209. + compatible = "arm,amba-bus", "simple-bus";
  34210. + #address-cells = <1>;
  34211. + #size-cells = <1>;
  34212. + ranges = <0 3 0 0x200000>;
  34213. +
  34214. + kmi@060000 {
  34215. + compatible = "arm,pl050", "arm,primecell";
  34216. + reg = <0x060000 0x1000>;
  34217. + interrupts = <8>;
  34218. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34219. + clock-names = "KMIREFCLK", "apb_pclk";
  34220. + };
  34221. +
  34222. + kmi@070000 {
  34223. + compatible = "arm,pl050", "arm,primecell";
  34224. + reg = <0x070000 0x1000>;
  34225. + interrupts = <8>;
  34226. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34227. + clock-names = "KMIREFCLK", "apb_pclk";
  34228. + };
  34229. +
  34230. + wdt@0f0000 {
  34231. + compatible = "arm,sp805", "arm,primecell";
  34232. + reg = <0x0f0000 0x10000>;
  34233. + interrupts = <7>;
  34234. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34235. + clock-names = "wdogclk", "apb_pclk";
  34236. + };
  34237. +
  34238. + v2m_timer01: timer@110000 {
  34239. + compatible = "arm,sp804", "arm,primecell";
  34240. + reg = <0x110000 0x10000>;
  34241. + interrupts = <9>;
  34242. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34243. + clock-names = "timclken1", "apb_pclk";
  34244. + };
  34245. +
  34246. + v2m_timer23: timer@120000 {
  34247. + compatible = "arm,sp804", "arm,primecell";
  34248. + reg = <0x120000 0x10000>;
  34249. + interrupts = <9>;
  34250. + clocks = <&soc_refclk24mhz>, <&soc_smc50mhz>;
  34251. + clock-names = "timclken1", "apb_pclk";
  34252. + };
  34253. +
  34254. + rtc@170000 {
  34255. + compatible = "arm,pl031", "arm,primecell";
  34256. + reg = <0x170000 0x10000>;
  34257. + interrupts = <0>;
  34258. + clocks = <&soc_smc50mhz>;
  34259. + clock-names = "apb_pclk";
  34260. + };
  34261. + };
  34262. + };
  34263. + };
  34264. +};
  34265. diff -Nur linux-3.14.17/arch/arm64/boot/dts/Makefile linux-imx6-3.14/arch/arm64/boot/dts/Makefile
  34266. --- linux-3.14.17/arch/arm64/boot/dts/Makefile 2014-08-14 03:38:34.000000000 +0200
  34267. +++ linux-imx6-3.14/arch/arm64/boot/dts/Makefile 2014-09-11 18:05:54.354007412 +0200
  34268. @@ -1,5 +1,7 @@
  34269. -dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb
  34270. +dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb \
  34271. + fvp-base-gicv2-psci.dtb
  34272. dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb
  34273. +dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb
  34274. targets += dtbs
  34275. targets += $(dtb-y)
  34276. diff -Nur linux-3.14.17/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts
  34277. --- linux-3.14.17/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts 2014-08-14 03:38:34.000000000 +0200
  34278. +++ linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-aemv8a.dts 2014-09-11 18:05:54.354007412 +0200
  34279. @@ -157,3 +157,5 @@
  34280. /include/ "rtsm_ve-motherboard.dtsi"
  34281. };
  34282. };
  34283. +
  34284. +/include/ "clcd-panels.dtsi"
  34285. diff -Nur linux-3.14.17/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi
  34286. --- linux-3.14.17/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi 2014-08-14 03:38:34.000000000 +0200
  34287. +++ linux-imx6-3.14/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi 2014-09-11 18:05:54.354007412 +0200
  34288. @@ -182,6 +182,9 @@
  34289. interrupts = <14>;
  34290. clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
  34291. clock-names = "clcdclk", "apb_pclk";
  34292. + mode = "XVGA";
  34293. + use_dma = <0>;
  34294. + framebuffer = <0x18000000 0x00180000>;
  34295. };
  34296. virtio_block@0130000 {
  34297. diff -Nur linux-3.14.17/arch/arm64/crypto/aes-ce-ccm-core.S linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-core.S
  34298. --- linux-3.14.17/arch/arm64/crypto/aes-ce-ccm-core.S 1970-01-01 01:00:00.000000000 +0100
  34299. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-core.S 2014-09-11 18:05:54.354007412 +0200
  34300. @@ -0,0 +1,222 @@
  34301. +/*
  34302. + * aesce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions
  34303. + *
  34304. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34305. + *
  34306. + * This program is free software; you can redistribute it and/or modify
  34307. + * it under the terms of the GNU General Public License version 2 as
  34308. + * published by the Free Software Foundation.
  34309. + */
  34310. +
  34311. +#include <linux/linkage.h>
  34312. +
  34313. + .text
  34314. + .arch armv8-a+crypto
  34315. +
  34316. + /*
  34317. + * void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
  34318. + * u32 *macp, u8 const rk[], u32 rounds);
  34319. + */
  34320. +ENTRY(ce_aes_ccm_auth_data)
  34321. + ldr w8, [x3] /* leftover from prev round? */
  34322. + ld1 {v0.2d}, [x0] /* load mac */
  34323. + cbz w8, 1f
  34324. + sub w8, w8, #16
  34325. + eor v1.16b, v1.16b, v1.16b
  34326. +0: ldrb w7, [x1], #1 /* get 1 byte of input */
  34327. + subs w2, w2, #1
  34328. + add w8, w8, #1
  34329. + ins v1.b[0], w7
  34330. + ext v1.16b, v1.16b, v1.16b, #1 /* rotate in the input bytes */
  34331. + beq 8f /* out of input? */
  34332. + cbnz w8, 0b
  34333. + eor v0.16b, v0.16b, v1.16b
  34334. +1: ld1 {v3.2d}, [x4] /* load first round key */
  34335. + prfm pldl1strm, [x1]
  34336. + cmp w5, #12 /* which key size? */
  34337. + add x6, x4, #16
  34338. + sub w7, w5, #2 /* modified # of rounds */
  34339. + bmi 2f
  34340. + bne 5f
  34341. + mov v5.16b, v3.16b
  34342. + b 4f
  34343. +2: mov v4.16b, v3.16b
  34344. + ld1 {v5.2d}, [x6], #16 /* load 2nd round key */
  34345. +3: aese v0.16b, v4.16b
  34346. + aesmc v0.16b, v0.16b
  34347. +4: ld1 {v3.2d}, [x6], #16 /* load next round key */
  34348. + aese v0.16b, v5.16b
  34349. + aesmc v0.16b, v0.16b
  34350. +5: ld1 {v4.2d}, [x6], #16 /* load next round key */
  34351. + subs w7, w7, #3
  34352. + aese v0.16b, v3.16b
  34353. + aesmc v0.16b, v0.16b
  34354. + ld1 {v5.2d}, [x6], #16 /* load next round key */
  34355. + bpl 3b
  34356. + aese v0.16b, v4.16b
  34357. + subs w2, w2, #16 /* last data? */
  34358. + eor v0.16b, v0.16b, v5.16b /* final round */
  34359. + bmi 6f
  34360. + ld1 {v1.16b}, [x1], #16 /* load next input block */
  34361. + eor v0.16b, v0.16b, v1.16b /* xor with mac */
  34362. + bne 1b
  34363. +6: st1 {v0.2d}, [x0] /* store mac */
  34364. + beq 10f
  34365. + adds w2, w2, #16
  34366. + beq 10f
  34367. + mov w8, w2
  34368. +7: ldrb w7, [x1], #1
  34369. + umov w6, v0.b[0]
  34370. + eor w6, w6, w7
  34371. + strb w6, [x0], #1
  34372. + subs w2, w2, #1
  34373. + beq 10f
  34374. + ext v0.16b, v0.16b, v0.16b, #1 /* rotate out the mac bytes */
  34375. + b 7b
  34376. +8: mov w7, w8
  34377. + add w8, w8, #16
  34378. +9: ext v1.16b, v1.16b, v1.16b, #1
  34379. + adds w7, w7, #1
  34380. + bne 9b
  34381. + eor v0.16b, v0.16b, v1.16b
  34382. + st1 {v0.2d}, [x0]
  34383. +10: str w8, [x3]
  34384. + ret
  34385. +ENDPROC(ce_aes_ccm_auth_data)
  34386. +
  34387. + /*
  34388. + * void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u8 const rk[],
  34389. + * u32 rounds);
  34390. + */
  34391. +ENTRY(ce_aes_ccm_final)
  34392. + ld1 {v3.2d}, [x2], #16 /* load first round key */
  34393. + ld1 {v0.2d}, [x0] /* load mac */
  34394. + cmp w3, #12 /* which key size? */
  34395. + sub w3, w3, #2 /* modified # of rounds */
  34396. + ld1 {v1.2d}, [x1] /* load 1st ctriv */
  34397. + bmi 0f
  34398. + bne 3f
  34399. + mov v5.16b, v3.16b
  34400. + b 2f
  34401. +0: mov v4.16b, v3.16b
  34402. +1: ld1 {v5.2d}, [x2], #16 /* load next round key */
  34403. + aese v0.16b, v4.16b
  34404. + aese v1.16b, v4.16b
  34405. + aesmc v0.16b, v0.16b
  34406. + aesmc v1.16b, v1.16b
  34407. +2: ld1 {v3.2d}, [x2], #16 /* load next round key */
  34408. + aese v0.16b, v5.16b
  34409. + aese v1.16b, v5.16b
  34410. + aesmc v0.16b, v0.16b
  34411. + aesmc v1.16b, v1.16b
  34412. +3: ld1 {v4.2d}, [x2], #16 /* load next round key */
  34413. + subs w3, w3, #3
  34414. + aese v0.16b, v3.16b
  34415. + aese v1.16b, v3.16b
  34416. + aesmc v0.16b, v0.16b
  34417. + aesmc v1.16b, v1.16b
  34418. + bpl 1b
  34419. + aese v0.16b, v4.16b
  34420. + aese v1.16b, v4.16b
  34421. + /* final round key cancels out */
  34422. + eor v0.16b, v0.16b, v1.16b /* en-/decrypt the mac */
  34423. + st1 {v0.2d}, [x0] /* store result */
  34424. + ret
  34425. +ENDPROC(ce_aes_ccm_final)
  34426. +
  34427. + .macro aes_ccm_do_crypt,enc
  34428. + ldr x8, [x6, #8] /* load lower ctr */
  34429. + ld1 {v0.2d}, [x5] /* load mac */
  34430. + rev x8, x8 /* keep swabbed ctr in reg */
  34431. +0: /* outer loop */
  34432. + ld1 {v1.1d}, [x6] /* load upper ctr */
  34433. + prfm pldl1strm, [x1]
  34434. + add x8, x8, #1
  34435. + rev x9, x8
  34436. + cmp w4, #12 /* which key size? */
  34437. + sub w7, w4, #2 /* get modified # of rounds */
  34438. + ins v1.d[1], x9 /* no carry in lower ctr */
  34439. + ld1 {v3.2d}, [x3] /* load first round key */
  34440. + add x10, x3, #16
  34441. + bmi 1f
  34442. + bne 4f
  34443. + mov v5.16b, v3.16b
  34444. + b 3f
  34445. +1: mov v4.16b, v3.16b
  34446. + ld1 {v5.2d}, [x10], #16 /* load 2nd round key */
  34447. +2: /* inner loop: 3 rounds, 2x interleaved */
  34448. + aese v0.16b, v4.16b
  34449. + aese v1.16b, v4.16b
  34450. + aesmc v0.16b, v0.16b
  34451. + aesmc v1.16b, v1.16b
  34452. +3: ld1 {v3.2d}, [x10], #16 /* load next round key */
  34453. + aese v0.16b, v5.16b
  34454. + aese v1.16b, v5.16b
  34455. + aesmc v0.16b, v0.16b
  34456. + aesmc v1.16b, v1.16b
  34457. +4: ld1 {v4.2d}, [x10], #16 /* load next round key */
  34458. + subs w7, w7, #3
  34459. + aese v0.16b, v3.16b
  34460. + aese v1.16b, v3.16b
  34461. + aesmc v0.16b, v0.16b
  34462. + aesmc v1.16b, v1.16b
  34463. + ld1 {v5.2d}, [x10], #16 /* load next round key */
  34464. + bpl 2b
  34465. + aese v0.16b, v4.16b
  34466. + aese v1.16b, v4.16b
  34467. + subs w2, w2, #16
  34468. + bmi 6f /* partial block? */
  34469. + ld1 {v2.16b}, [x1], #16 /* load next input block */
  34470. + .if \enc == 1
  34471. + eor v2.16b, v2.16b, v5.16b /* final round enc+mac */
  34472. + eor v1.16b, v1.16b, v2.16b /* xor with crypted ctr */
  34473. + .else
  34474. + eor v2.16b, v2.16b, v1.16b /* xor with crypted ctr */
  34475. + eor v1.16b, v2.16b, v5.16b /* final round enc */
  34476. + .endif
  34477. + eor v0.16b, v0.16b, v2.16b /* xor mac with pt ^ rk[last] */
  34478. + st1 {v1.16b}, [x0], #16 /* write output block */
  34479. + bne 0b
  34480. + rev x8, x8
  34481. + st1 {v0.2d}, [x5] /* store mac */
  34482. + str x8, [x6, #8] /* store lsb end of ctr (BE) */
  34483. +5: ret
  34484. +
  34485. +6: eor v0.16b, v0.16b, v5.16b /* final round mac */
  34486. + eor v1.16b, v1.16b, v5.16b /* final round enc */
  34487. + st1 {v0.2d}, [x5] /* store mac */
  34488. + add w2, w2, #16 /* process partial tail block */
  34489. +7: ldrb w9, [x1], #1 /* get 1 byte of input */
  34490. + umov w6, v1.b[0] /* get top crypted ctr byte */
  34491. + umov w7, v0.b[0] /* get top mac byte */
  34492. + .if \enc == 1
  34493. + eor w7, w7, w9
  34494. + eor w9, w9, w6
  34495. + .else
  34496. + eor w9, w9, w6
  34497. + eor w7, w7, w9
  34498. + .endif
  34499. + strb w9, [x0], #1 /* store out byte */
  34500. + strb w7, [x5], #1 /* store mac byte */
  34501. + subs w2, w2, #1
  34502. + beq 5b
  34503. + ext v0.16b, v0.16b, v0.16b, #1 /* shift out mac byte */
  34504. + ext v1.16b, v1.16b, v1.16b, #1 /* shift out ctr byte */
  34505. + b 7b
  34506. + .endm
  34507. +
  34508. + /*
  34509. + * void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
  34510. + * u8 const rk[], u32 rounds, u8 mac[],
  34511. + * u8 ctr[]);
  34512. + * void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
  34513. + * u8 const rk[], u32 rounds, u8 mac[],
  34514. + * u8 ctr[]);
  34515. + */
  34516. +ENTRY(ce_aes_ccm_encrypt)
  34517. + aes_ccm_do_crypt 1
  34518. +ENDPROC(ce_aes_ccm_encrypt)
  34519. +
  34520. +ENTRY(ce_aes_ccm_decrypt)
  34521. + aes_ccm_do_crypt 0
  34522. +ENDPROC(ce_aes_ccm_decrypt)
  34523. diff -Nur linux-3.14.17/arch/arm64/crypto/aes-ce-ccm-glue.c linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-glue.c
  34524. --- linux-3.14.17/arch/arm64/crypto/aes-ce-ccm-glue.c 1970-01-01 01:00:00.000000000 +0100
  34525. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce-ccm-glue.c 2014-09-11 18:05:54.354007412 +0200
  34526. @@ -0,0 +1,297 @@
  34527. +/*
  34528. + * aes-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions
  34529. + *
  34530. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34531. + *
  34532. + * This program is free software; you can redistribute it and/or modify
  34533. + * it under the terms of the GNU General Public License version 2 as
  34534. + * published by the Free Software Foundation.
  34535. + */
  34536. +
  34537. +#include <asm/neon.h>
  34538. +#include <asm/unaligned.h>
  34539. +#include <crypto/aes.h>
  34540. +#include <crypto/algapi.h>
  34541. +#include <crypto/scatterwalk.h>
  34542. +#include <linux/crypto.h>
  34543. +#include <linux/module.h>
  34544. +
  34545. +static int num_rounds(struct crypto_aes_ctx *ctx)
  34546. +{
  34547. + /*
  34548. + * # of rounds specified by AES:
  34549. + * 128 bit key 10 rounds
  34550. + * 192 bit key 12 rounds
  34551. + * 256 bit key 14 rounds
  34552. + * => n byte key => 6 + (n/4) rounds
  34553. + */
  34554. + return 6 + ctx->key_length / 4;
  34555. +}
  34556. +
  34557. +asmlinkage void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
  34558. + u32 *macp, u32 const rk[], u32 rounds);
  34559. +
  34560. +asmlinkage void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
  34561. + u32 const rk[], u32 rounds, u8 mac[],
  34562. + u8 ctr[]);
  34563. +
  34564. +asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
  34565. + u32 const rk[], u32 rounds, u8 mac[],
  34566. + u8 ctr[]);
  34567. +
  34568. +asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[],
  34569. + u32 rounds);
  34570. +
  34571. +static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key,
  34572. + unsigned int key_len)
  34573. +{
  34574. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(tfm);
  34575. + int ret;
  34576. +
  34577. + ret = crypto_aes_expand_key(ctx, in_key, key_len);
  34578. + if (!ret)
  34579. + return 0;
  34580. +
  34581. + tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  34582. + return -EINVAL;
  34583. +}
  34584. +
  34585. +static int ccm_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
  34586. +{
  34587. + if ((authsize & 1) || authsize < 4)
  34588. + return -EINVAL;
  34589. + return 0;
  34590. +}
  34591. +
  34592. +static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
  34593. +{
  34594. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34595. + __be32 *n = (__be32 *)&maciv[AES_BLOCK_SIZE - 8];
  34596. + u32 l = req->iv[0] + 1;
  34597. +
  34598. + /* verify that CCM dimension 'L' is set correctly in the IV */
  34599. + if (l < 2 || l > 8)
  34600. + return -EINVAL;
  34601. +
  34602. + /* verify that msglen can in fact be represented in L bytes */
  34603. + if (l < 4 && msglen >> (8 * l))
  34604. + return -EOVERFLOW;
  34605. +
  34606. + /*
  34607. + * Even if the CCM spec allows L values of up to 8, the Linux cryptoapi
  34608. + * uses a u32 type to represent msglen so the top 4 bytes are always 0.
  34609. + */
  34610. + n[0] = 0;
  34611. + n[1] = cpu_to_be32(msglen);
  34612. +
  34613. + memcpy(maciv, req->iv, AES_BLOCK_SIZE - l);
  34614. +
  34615. + /*
  34616. + * Meaning of byte 0 according to CCM spec (RFC 3610/NIST 800-38C)
  34617. + * - bits 0..2 : max # of bytes required to represent msglen, minus 1
  34618. + * (already set by caller)
  34619. + * - bits 3..5 : size of auth tag (1 => 4 bytes, 2 => 6 bytes, etc)
  34620. + * - bit 6 : indicates presence of authenticate-only data
  34621. + */
  34622. + maciv[0] |= (crypto_aead_authsize(aead) - 2) << 2;
  34623. + if (req->assoclen)
  34624. + maciv[0] |= 0x40;
  34625. +
  34626. + memset(&req->iv[AES_BLOCK_SIZE - l], 0, l);
  34627. + return 0;
  34628. +}
  34629. +
  34630. +static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
  34631. +{
  34632. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34633. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34634. + struct __packed { __be16 l; __be32 h; u16 len; } ltag;
  34635. + struct scatter_walk walk;
  34636. + u32 len = req->assoclen;
  34637. + u32 macp = 0;
  34638. +
  34639. + /* prepend the AAD with a length tag */
  34640. + if (len < 0xff00) {
  34641. + ltag.l = cpu_to_be16(len);
  34642. + ltag.len = 2;
  34643. + } else {
  34644. + ltag.l = cpu_to_be16(0xfffe);
  34645. + put_unaligned_be32(len, &ltag.h);
  34646. + ltag.len = 6;
  34647. + }
  34648. +
  34649. + ce_aes_ccm_auth_data(mac, (u8 *)&ltag, ltag.len, &macp, ctx->key_enc,
  34650. + num_rounds(ctx));
  34651. + scatterwalk_start(&walk, req->assoc);
  34652. +
  34653. + do {
  34654. + u32 n = scatterwalk_clamp(&walk, len);
  34655. + u8 *p;
  34656. +
  34657. + if (!n) {
  34658. + scatterwalk_start(&walk, sg_next(walk.sg));
  34659. + n = scatterwalk_clamp(&walk, len);
  34660. + }
  34661. + p = scatterwalk_map(&walk);
  34662. + ce_aes_ccm_auth_data(mac, p, n, &macp, ctx->key_enc,
  34663. + num_rounds(ctx));
  34664. + len -= n;
  34665. +
  34666. + scatterwalk_unmap(p);
  34667. + scatterwalk_advance(&walk, n);
  34668. + scatterwalk_done(&walk, 0, len);
  34669. + } while (len);
  34670. +}
  34671. +
  34672. +static int ccm_encrypt(struct aead_request *req)
  34673. +{
  34674. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34675. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34676. + struct blkcipher_desc desc = { .info = req->iv };
  34677. + struct blkcipher_walk walk;
  34678. + u8 __aligned(8) mac[AES_BLOCK_SIZE];
  34679. + u8 buf[AES_BLOCK_SIZE];
  34680. + u32 len = req->cryptlen;
  34681. + int err;
  34682. +
  34683. + err = ccm_init_mac(req, mac, len);
  34684. + if (err)
  34685. + return err;
  34686. +
  34687. + kernel_neon_begin_partial(6);
  34688. +
  34689. + if (req->assoclen)
  34690. + ccm_calculate_auth_mac(req, mac);
  34691. +
  34692. + /* preserve the original iv for the final round */
  34693. + memcpy(buf, req->iv, AES_BLOCK_SIZE);
  34694. +
  34695. + blkcipher_walk_init(&walk, req->dst, req->src, len);
  34696. + err = blkcipher_aead_walk_virt_block(&desc, &walk, aead,
  34697. + AES_BLOCK_SIZE);
  34698. +
  34699. + while (walk.nbytes) {
  34700. + u32 tail = walk.nbytes % AES_BLOCK_SIZE;
  34701. +
  34702. + if (walk.nbytes == len)
  34703. + tail = 0;
  34704. +
  34705. + ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  34706. + walk.nbytes - tail, ctx->key_enc,
  34707. + num_rounds(ctx), mac, walk.iv);
  34708. +
  34709. + len -= walk.nbytes - tail;
  34710. + err = blkcipher_walk_done(&desc, &walk, tail);
  34711. + }
  34712. + if (!err)
  34713. + ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
  34714. +
  34715. + kernel_neon_end();
  34716. +
  34717. + if (err)
  34718. + return err;
  34719. +
  34720. + /* copy authtag to end of dst */
  34721. + scatterwalk_map_and_copy(mac, req->dst, req->cryptlen,
  34722. + crypto_aead_authsize(aead), 1);
  34723. +
  34724. + return 0;
  34725. +}
  34726. +
  34727. +static int ccm_decrypt(struct aead_request *req)
  34728. +{
  34729. + struct crypto_aead *aead = crypto_aead_reqtfm(req);
  34730. + struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
  34731. + unsigned int authsize = crypto_aead_authsize(aead);
  34732. + struct blkcipher_desc desc = { .info = req->iv };
  34733. + struct blkcipher_walk walk;
  34734. + u8 __aligned(8) mac[AES_BLOCK_SIZE];
  34735. + u8 buf[AES_BLOCK_SIZE];
  34736. + u32 len = req->cryptlen - authsize;
  34737. + int err;
  34738. +
  34739. + err = ccm_init_mac(req, mac, len);
  34740. + if (err)
  34741. + return err;
  34742. +
  34743. + kernel_neon_begin_partial(6);
  34744. +
  34745. + if (req->assoclen)
  34746. + ccm_calculate_auth_mac(req, mac);
  34747. +
  34748. + /* preserve the original iv for the final round */
  34749. + memcpy(buf, req->iv, AES_BLOCK_SIZE);
  34750. +
  34751. + blkcipher_walk_init(&walk, req->dst, req->src, len);
  34752. + err = blkcipher_aead_walk_virt_block(&desc, &walk, aead,
  34753. + AES_BLOCK_SIZE);
  34754. +
  34755. + while (walk.nbytes) {
  34756. + u32 tail = walk.nbytes % AES_BLOCK_SIZE;
  34757. +
  34758. + if (walk.nbytes == len)
  34759. + tail = 0;
  34760. +
  34761. + ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  34762. + walk.nbytes - tail, ctx->key_enc,
  34763. + num_rounds(ctx), mac, walk.iv);
  34764. +
  34765. + len -= walk.nbytes - tail;
  34766. + err = blkcipher_walk_done(&desc, &walk, tail);
  34767. + }
  34768. + if (!err)
  34769. + ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
  34770. +
  34771. + kernel_neon_end();
  34772. +
  34773. + if (err)
  34774. + return err;
  34775. +
  34776. + /* compare calculated auth tag with the stored one */
  34777. + scatterwalk_map_and_copy(buf, req->src, req->cryptlen - authsize,
  34778. + authsize, 0);
  34779. +
  34780. + if (memcmp(mac, buf, authsize))
  34781. + return -EBADMSG;
  34782. + return 0;
  34783. +}
  34784. +
  34785. +static struct crypto_alg ccm_aes_alg = {
  34786. + .cra_name = "ccm(aes)",
  34787. + .cra_driver_name = "ccm-aes-ce",
  34788. + .cra_priority = 300,
  34789. + .cra_flags = CRYPTO_ALG_TYPE_AEAD,
  34790. + .cra_blocksize = 1,
  34791. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  34792. + .cra_alignmask = 7,
  34793. + .cra_type = &crypto_aead_type,
  34794. + .cra_module = THIS_MODULE,
  34795. + .cra_aead = {
  34796. + .ivsize = AES_BLOCK_SIZE,
  34797. + .maxauthsize = AES_BLOCK_SIZE,
  34798. + .setkey = ccm_setkey,
  34799. + .setauthsize = ccm_setauthsize,
  34800. + .encrypt = ccm_encrypt,
  34801. + .decrypt = ccm_decrypt,
  34802. + }
  34803. +};
  34804. +
  34805. +static int __init aes_mod_init(void)
  34806. +{
  34807. + if (!(elf_hwcap & HWCAP_AES))
  34808. + return -ENODEV;
  34809. + return crypto_register_alg(&ccm_aes_alg);
  34810. +}
  34811. +
  34812. +static void __exit aes_mod_exit(void)
  34813. +{
  34814. + crypto_unregister_alg(&ccm_aes_alg);
  34815. +}
  34816. +
  34817. +module_init(aes_mod_init);
  34818. +module_exit(aes_mod_exit);
  34819. +
  34820. +MODULE_DESCRIPTION("Synchronous AES in CCM mode using ARMv8 Crypto Extensions");
  34821. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  34822. +MODULE_LICENSE("GPL v2");
  34823. +MODULE_ALIAS("ccm(aes)");
  34824. diff -Nur linux-3.14.17/arch/arm64/crypto/aes-ce-cipher.c linux-imx6-3.14/arch/arm64/crypto/aes-ce-cipher.c
  34825. --- linux-3.14.17/arch/arm64/crypto/aes-ce-cipher.c 1970-01-01 01:00:00.000000000 +0100
  34826. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce-cipher.c 2014-09-11 18:05:54.354007412 +0200
  34827. @@ -0,0 +1,155 @@
  34828. +/*
  34829. + * aes-ce-cipher.c - core AES cipher using ARMv8 Crypto Extensions
  34830. + *
  34831. + * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  34832. + *
  34833. + * This program is free software; you can redistribute it and/or modify
  34834. + * it under the terms of the GNU General Public License version 2 as
  34835. + * published by the Free Software Foundation.
  34836. + */
  34837. +
  34838. +#include <asm/neon.h>
  34839. +#include <crypto/aes.h>
  34840. +#include <linux/cpufeature.h>
  34841. +#include <linux/crypto.h>
  34842. +#include <linux/module.h>
  34843. +
  34844. +MODULE_DESCRIPTION("Synchronous AES cipher using ARMv8 Crypto Extensions");
  34845. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  34846. +MODULE_LICENSE("GPL v2");
  34847. +
  34848. +struct aes_block {
  34849. + u8 b[AES_BLOCK_SIZE];
  34850. +};
  34851. +
  34852. +static int num_rounds(struct crypto_aes_ctx *ctx)
  34853. +{
  34854. + /*
  34855. + * # of rounds specified by AES:
  34856. + * 128 bit key 10 rounds
  34857. + * 192 bit key 12 rounds
  34858. + * 256 bit key 14 rounds
  34859. + * => n byte key => 6 + (n/4) rounds
  34860. + */
  34861. + return 6 + ctx->key_length / 4;
  34862. +}
  34863. +
  34864. +static void aes_cipher_encrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[])
  34865. +{
  34866. + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  34867. + struct aes_block *out = (struct aes_block *)dst;
  34868. + struct aes_block const *in = (struct aes_block *)src;
  34869. + void *dummy0;
  34870. + int dummy1;
  34871. +
  34872. + kernel_neon_begin_partial(4);
  34873. +
  34874. + __asm__(" ld1 {v0.16b}, %[in] ;"
  34875. + " ld1 {v1.2d}, [%[key]], #16 ;"
  34876. + " cmp %w[rounds], #10 ;"
  34877. + " bmi 0f ;"
  34878. + " bne 3f ;"
  34879. + " mov v3.16b, v1.16b ;"
  34880. + " b 2f ;"
  34881. + "0: mov v2.16b, v1.16b ;"
  34882. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34883. + "1: aese v0.16b, v2.16b ;"
  34884. + " aesmc v0.16b, v0.16b ;"
  34885. + "2: ld1 {v1.2d}, [%[key]], #16 ;"
  34886. + " aese v0.16b, v3.16b ;"
  34887. + " aesmc v0.16b, v0.16b ;"
  34888. + "3: ld1 {v2.2d}, [%[key]], #16 ;"
  34889. + " subs %w[rounds], %w[rounds], #3 ;"
  34890. + " aese v0.16b, v1.16b ;"
  34891. + " aesmc v0.16b, v0.16b ;"
  34892. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34893. + " bpl 1b ;"
  34894. + " aese v0.16b, v2.16b ;"
  34895. + " eor v0.16b, v0.16b, v3.16b ;"
  34896. + " st1 {v0.16b}, %[out] ;"
  34897. +
  34898. + : [out] "=Q"(*out),
  34899. + [key] "=r"(dummy0),
  34900. + [rounds] "=r"(dummy1)
  34901. + : [in] "Q"(*in),
  34902. + "1"(ctx->key_enc),
  34903. + "2"(num_rounds(ctx) - 2)
  34904. + : "cc");
  34905. +
  34906. + kernel_neon_end();
  34907. +}
  34908. +
  34909. +static void aes_cipher_decrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[])
  34910. +{
  34911. + struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
  34912. + struct aes_block *out = (struct aes_block *)dst;
  34913. + struct aes_block const *in = (struct aes_block *)src;
  34914. + void *dummy0;
  34915. + int dummy1;
  34916. +
  34917. + kernel_neon_begin_partial(4);
  34918. +
  34919. + __asm__(" ld1 {v0.16b}, %[in] ;"
  34920. + " ld1 {v1.2d}, [%[key]], #16 ;"
  34921. + " cmp %w[rounds], #10 ;"
  34922. + " bmi 0f ;"
  34923. + " bne 3f ;"
  34924. + " mov v3.16b, v1.16b ;"
  34925. + " b 2f ;"
  34926. + "0: mov v2.16b, v1.16b ;"
  34927. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34928. + "1: aesd v0.16b, v2.16b ;"
  34929. + " aesimc v0.16b, v0.16b ;"
  34930. + "2: ld1 {v1.2d}, [%[key]], #16 ;"
  34931. + " aesd v0.16b, v3.16b ;"
  34932. + " aesimc v0.16b, v0.16b ;"
  34933. + "3: ld1 {v2.2d}, [%[key]], #16 ;"
  34934. + " subs %w[rounds], %w[rounds], #3 ;"
  34935. + " aesd v0.16b, v1.16b ;"
  34936. + " aesimc v0.16b, v0.16b ;"
  34937. + " ld1 {v3.2d}, [%[key]], #16 ;"
  34938. + " bpl 1b ;"
  34939. + " aesd v0.16b, v2.16b ;"
  34940. + " eor v0.16b, v0.16b, v3.16b ;"
  34941. + " st1 {v0.16b}, %[out] ;"
  34942. +
  34943. + : [out] "=Q"(*out),
  34944. + [key] "=r"(dummy0),
  34945. + [rounds] "=r"(dummy1)
  34946. + : [in] "Q"(*in),
  34947. + "1"(ctx->key_dec),
  34948. + "2"(num_rounds(ctx) - 2)
  34949. + : "cc");
  34950. +
  34951. + kernel_neon_end();
  34952. +}
  34953. +
  34954. +static struct crypto_alg aes_alg = {
  34955. + .cra_name = "aes",
  34956. + .cra_driver_name = "aes-ce",
  34957. + .cra_priority = 300,
  34958. + .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
  34959. + .cra_blocksize = AES_BLOCK_SIZE,
  34960. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  34961. + .cra_module = THIS_MODULE,
  34962. + .cra_cipher = {
  34963. + .cia_min_keysize = AES_MIN_KEY_SIZE,
  34964. + .cia_max_keysize = AES_MAX_KEY_SIZE,
  34965. + .cia_setkey = crypto_aes_set_key,
  34966. + .cia_encrypt = aes_cipher_encrypt,
  34967. + .cia_decrypt = aes_cipher_decrypt
  34968. + }
  34969. +};
  34970. +
  34971. +static int __init aes_mod_init(void)
  34972. +{
  34973. + return crypto_register_alg(&aes_alg);
  34974. +}
  34975. +
  34976. +static void __exit aes_mod_exit(void)
  34977. +{
  34978. + crypto_unregister_alg(&aes_alg);
  34979. +}
  34980. +
  34981. +module_cpu_feature_match(AES, aes_mod_init);
  34982. +module_exit(aes_mod_exit);
  34983. diff -Nur linux-3.14.17/arch/arm64/crypto/aes-ce.S linux-imx6-3.14/arch/arm64/crypto/aes-ce.S
  34984. --- linux-3.14.17/arch/arm64/crypto/aes-ce.S 1970-01-01 01:00:00.000000000 +0100
  34985. +++ linux-imx6-3.14/arch/arm64/crypto/aes-ce.S 2014-09-11 18:05:54.354007412 +0200
  34986. @@ -0,0 +1,133 @@
  34987. +/*
  34988. + * linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with
  34989. + * Crypto Extensions
  34990. + *
  34991. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  34992. + *
  34993. + * This program is free software; you can redistribute it and/or modify
  34994. + * it under the terms of the GNU General Public License version 2 as
  34995. + * published by the Free Software Foundation.
  34996. + */
  34997. +
  34998. +#include <linux/linkage.h>
  34999. +
  35000. +#define AES_ENTRY(func) ENTRY(ce_ ## func)
  35001. +#define AES_ENDPROC(func) ENDPROC(ce_ ## func)
  35002. +
  35003. + .arch armv8-a+crypto
  35004. +
  35005. + /* preload all round keys */
  35006. + .macro load_round_keys, rounds, rk
  35007. + cmp \rounds, #12
  35008. + blo 2222f /* 128 bits */
  35009. + beq 1111f /* 192 bits */
  35010. + ld1 {v17.16b-v18.16b}, [\rk], #32
  35011. +1111: ld1 {v19.16b-v20.16b}, [\rk], #32
  35012. +2222: ld1 {v21.16b-v24.16b}, [\rk], #64
  35013. + ld1 {v25.16b-v28.16b}, [\rk], #64
  35014. + ld1 {v29.16b-v31.16b}, [\rk]
  35015. + .endm
  35016. +
  35017. + /* prepare for encryption with key in rk[] */
  35018. + .macro enc_prepare, rounds, rk, ignore
  35019. + load_round_keys \rounds, \rk
  35020. + .endm
  35021. +
  35022. + /* prepare for encryption (again) but with new key in rk[] */
  35023. + .macro enc_switch_key, rounds, rk, ignore
  35024. + load_round_keys \rounds, \rk
  35025. + .endm
  35026. +
  35027. + /* prepare for decryption with key in rk[] */
  35028. + .macro dec_prepare, rounds, rk, ignore
  35029. + load_round_keys \rounds, \rk
  35030. + .endm
  35031. +
  35032. + .macro do_enc_Nx, de, mc, k, i0, i1, i2, i3
  35033. + aes\de \i0\().16b, \k\().16b
  35034. + .ifnb \i1
  35035. + aes\de \i1\().16b, \k\().16b
  35036. + .ifnb \i3
  35037. + aes\de \i2\().16b, \k\().16b
  35038. + aes\de \i3\().16b, \k\().16b
  35039. + .endif
  35040. + .endif
  35041. + aes\mc \i0\().16b, \i0\().16b
  35042. + .ifnb \i1
  35043. + aes\mc \i1\().16b, \i1\().16b
  35044. + .ifnb \i3
  35045. + aes\mc \i2\().16b, \i2\().16b
  35046. + aes\mc \i3\().16b, \i3\().16b
  35047. + .endif
  35048. + .endif
  35049. + .endm
  35050. +
  35051. + /* up to 4 interleaved encryption rounds with the same round key */
  35052. + .macro round_Nx, enc, k, i0, i1, i2, i3
  35053. + .ifc \enc, e
  35054. + do_enc_Nx e, mc, \k, \i0, \i1, \i2, \i3
  35055. + .else
  35056. + do_enc_Nx d, imc, \k, \i0, \i1, \i2, \i3
  35057. + .endif
  35058. + .endm
  35059. +
  35060. + /* up to 4 interleaved final rounds */
  35061. + .macro fin_round_Nx, de, k, k2, i0, i1, i2, i3
  35062. + aes\de \i0\().16b, \k\().16b
  35063. + .ifnb \i1
  35064. + aes\de \i1\().16b, \k\().16b
  35065. + .ifnb \i3
  35066. + aes\de \i2\().16b, \k\().16b
  35067. + aes\de \i3\().16b, \k\().16b
  35068. + .endif
  35069. + .endif
  35070. + eor \i0\().16b, \i0\().16b, \k2\().16b
  35071. + .ifnb \i1
  35072. + eor \i1\().16b, \i1\().16b, \k2\().16b
  35073. + .ifnb \i3
  35074. + eor \i2\().16b, \i2\().16b, \k2\().16b
  35075. + eor \i3\().16b, \i3\().16b, \k2\().16b
  35076. + .endif
  35077. + .endif
  35078. + .endm
  35079. +
  35080. + /* up to 4 interleaved blocks */
  35081. + .macro do_block_Nx, enc, rounds, i0, i1, i2, i3
  35082. + cmp \rounds, #12
  35083. + blo 2222f /* 128 bits */
  35084. + beq 1111f /* 192 bits */
  35085. + round_Nx \enc, v17, \i0, \i1, \i2, \i3
  35086. + round_Nx \enc, v18, \i0, \i1, \i2, \i3
  35087. +1111: round_Nx \enc, v19, \i0, \i1, \i2, \i3
  35088. + round_Nx \enc, v20, \i0, \i1, \i2, \i3
  35089. +2222: .irp key, v21, v22, v23, v24, v25, v26, v27, v28, v29
  35090. + round_Nx \enc, \key, \i0, \i1, \i2, \i3
  35091. + .endr
  35092. + fin_round_Nx \enc, v30, v31, \i0, \i1, \i2, \i3
  35093. + .endm
  35094. +
  35095. + .macro encrypt_block, in, rounds, t0, t1, t2
  35096. + do_block_Nx e, \rounds, \in
  35097. + .endm
  35098. +
  35099. + .macro encrypt_block2x, i0, i1, rounds, t0, t1, t2
  35100. + do_block_Nx e, \rounds, \i0, \i1
  35101. + .endm
  35102. +
  35103. + .macro encrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
  35104. + do_block_Nx e, \rounds, \i0, \i1, \i2, \i3
  35105. + .endm
  35106. +
  35107. + .macro decrypt_block, in, rounds, t0, t1, t2
  35108. + do_block_Nx d, \rounds, \in
  35109. + .endm
  35110. +
  35111. + .macro decrypt_block2x, i0, i1, rounds, t0, t1, t2
  35112. + do_block_Nx d, \rounds, \i0, \i1
  35113. + .endm
  35114. +
  35115. + .macro decrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
  35116. + do_block_Nx d, \rounds, \i0, \i1, \i2, \i3
  35117. + .endm
  35118. +
  35119. +#include "aes-modes.S"
  35120. diff -Nur linux-3.14.17/arch/arm64/crypto/aes-glue.c linux-imx6-3.14/arch/arm64/crypto/aes-glue.c
  35121. --- linux-3.14.17/arch/arm64/crypto/aes-glue.c 1970-01-01 01:00:00.000000000 +0100
  35122. +++ linux-imx6-3.14/arch/arm64/crypto/aes-glue.c 2014-09-11 18:05:54.354007412 +0200
  35123. @@ -0,0 +1,446 @@
  35124. +/*
  35125. + * linux/arch/arm64/crypto/aes-glue.c - wrapper code for ARMv8 AES
  35126. + *
  35127. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  35128. + *
  35129. + * This program is free software; you can redistribute it and/or modify
  35130. + * it under the terms of the GNU General Public License version 2 as
  35131. + * published by the Free Software Foundation.
  35132. + */
  35133. +
  35134. +#include <asm/neon.h>
  35135. +#include <asm/hwcap.h>
  35136. +#include <crypto/aes.h>
  35137. +#include <crypto/ablk_helper.h>
  35138. +#include <crypto/algapi.h>
  35139. +#include <linux/module.h>
  35140. +#include <linux/cpufeature.h>
  35141. +
  35142. +#ifdef USE_V8_CRYPTO_EXTENSIONS
  35143. +#define MODE "ce"
  35144. +#define PRIO 300
  35145. +#define aes_ecb_encrypt ce_aes_ecb_encrypt
  35146. +#define aes_ecb_decrypt ce_aes_ecb_decrypt
  35147. +#define aes_cbc_encrypt ce_aes_cbc_encrypt
  35148. +#define aes_cbc_decrypt ce_aes_cbc_decrypt
  35149. +#define aes_ctr_encrypt ce_aes_ctr_encrypt
  35150. +#define aes_xts_encrypt ce_aes_xts_encrypt
  35151. +#define aes_xts_decrypt ce_aes_xts_decrypt
  35152. +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
  35153. +#else
  35154. +#define MODE "neon"
  35155. +#define PRIO 200
  35156. +#define aes_ecb_encrypt neon_aes_ecb_encrypt
  35157. +#define aes_ecb_decrypt neon_aes_ecb_decrypt
  35158. +#define aes_cbc_encrypt neon_aes_cbc_encrypt
  35159. +#define aes_cbc_decrypt neon_aes_cbc_decrypt
  35160. +#define aes_ctr_encrypt neon_aes_ctr_encrypt
  35161. +#define aes_xts_encrypt neon_aes_xts_encrypt
  35162. +#define aes_xts_decrypt neon_aes_xts_decrypt
  35163. +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 NEON");
  35164. +MODULE_ALIAS("ecb(aes)");
  35165. +MODULE_ALIAS("cbc(aes)");
  35166. +MODULE_ALIAS("ctr(aes)");
  35167. +MODULE_ALIAS("xts(aes)");
  35168. +#endif
  35169. +
  35170. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  35171. +MODULE_LICENSE("GPL v2");
  35172. +
  35173. +/* defined in aes-modes.S */
  35174. +asmlinkage void aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35175. + int rounds, int blocks, int first);
  35176. +asmlinkage void aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[],
  35177. + int rounds, int blocks, int first);
  35178. +
  35179. +asmlinkage void aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35180. + int rounds, int blocks, u8 iv[], int first);
  35181. +asmlinkage void aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
  35182. + int rounds, int blocks, u8 iv[], int first);
  35183. +
  35184. +asmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
  35185. + int rounds, int blocks, u8 ctr[], int first);
  35186. +
  35187. +asmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[],
  35188. + int rounds, int blocks, u8 const rk2[], u8 iv[],
  35189. + int first);
  35190. +asmlinkage void aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[],
  35191. + int rounds, int blocks, u8 const rk2[], u8 iv[],
  35192. + int first);
  35193. +
  35194. +struct crypto_aes_xts_ctx {
  35195. + struct crypto_aes_ctx key1;
  35196. + struct crypto_aes_ctx __aligned(8) key2;
  35197. +};
  35198. +
  35199. +static int xts_set_key(struct crypto_tfm *tfm, const u8 *in_key,
  35200. + unsigned int key_len)
  35201. +{
  35202. + struct crypto_aes_xts_ctx *ctx = crypto_tfm_ctx(tfm);
  35203. + int ret;
  35204. +
  35205. + ret = crypto_aes_expand_key(&ctx->key1, in_key, key_len / 2);
  35206. + if (!ret)
  35207. + ret = crypto_aes_expand_key(&ctx->key2, &in_key[key_len / 2],
  35208. + key_len / 2);
  35209. + if (!ret)
  35210. + return 0;
  35211. +
  35212. + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
  35213. + return -EINVAL;
  35214. +}
  35215. +
  35216. +static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35217. + struct scatterlist *src, unsigned int nbytes)
  35218. +{
  35219. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35220. + int err, first, rounds = 6 + ctx->key_length / 4;
  35221. + struct blkcipher_walk walk;
  35222. + unsigned int blocks;
  35223. +
  35224. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35225. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35226. + err = blkcipher_walk_virt(desc, &walk);
  35227. +
  35228. + kernel_neon_begin();
  35229. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35230. + aes_ecb_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35231. + (u8 *)ctx->key_enc, rounds, blocks, first);
  35232. + err = blkcipher_walk_done(desc, &walk, 0);
  35233. + }
  35234. + kernel_neon_end();
  35235. + return err;
  35236. +}
  35237. +
  35238. +static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35239. + struct scatterlist *src, unsigned int nbytes)
  35240. +{
  35241. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35242. + int err, first, rounds = 6 + ctx->key_length / 4;
  35243. + struct blkcipher_walk walk;
  35244. + unsigned int blocks;
  35245. +
  35246. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35247. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35248. + err = blkcipher_walk_virt(desc, &walk);
  35249. +
  35250. + kernel_neon_begin();
  35251. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35252. + aes_ecb_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35253. + (u8 *)ctx->key_dec, rounds, blocks, first);
  35254. + err = blkcipher_walk_done(desc, &walk, 0);
  35255. + }
  35256. + kernel_neon_end();
  35257. + return err;
  35258. +}
  35259. +
  35260. +static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35261. + struct scatterlist *src, unsigned int nbytes)
  35262. +{
  35263. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35264. + int err, first, rounds = 6 + ctx->key_length / 4;
  35265. + struct blkcipher_walk walk;
  35266. + unsigned int blocks;
  35267. +
  35268. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35269. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35270. + err = blkcipher_walk_virt(desc, &walk);
  35271. +
  35272. + kernel_neon_begin();
  35273. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35274. + aes_cbc_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35275. + (u8 *)ctx->key_enc, rounds, blocks, walk.iv,
  35276. + first);
  35277. + err = blkcipher_walk_done(desc, &walk, 0);
  35278. + }
  35279. + kernel_neon_end();
  35280. + return err;
  35281. +}
  35282. +
  35283. +static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35284. + struct scatterlist *src, unsigned int nbytes)
  35285. +{
  35286. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35287. + int err, first, rounds = 6 + ctx->key_length / 4;
  35288. + struct blkcipher_walk walk;
  35289. + unsigned int blocks;
  35290. +
  35291. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35292. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35293. + err = blkcipher_walk_virt(desc, &walk);
  35294. +
  35295. + kernel_neon_begin();
  35296. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35297. + aes_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35298. + (u8 *)ctx->key_dec, rounds, blocks, walk.iv,
  35299. + first);
  35300. + err = blkcipher_walk_done(desc, &walk, 0);
  35301. + }
  35302. + kernel_neon_end();
  35303. + return err;
  35304. +}
  35305. +
  35306. +static int ctr_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35307. + struct scatterlist *src, unsigned int nbytes)
  35308. +{
  35309. + struct crypto_aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35310. + int err, first, rounds = 6 + ctx->key_length / 4;
  35311. + struct blkcipher_walk walk;
  35312. + int blocks;
  35313. +
  35314. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35315. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35316. + err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE);
  35317. +
  35318. + first = 1;
  35319. + kernel_neon_begin();
  35320. + while ((blocks = (walk.nbytes / AES_BLOCK_SIZE))) {
  35321. + aes_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35322. + (u8 *)ctx->key_enc, rounds, blocks, walk.iv,
  35323. + first);
  35324. + first = 0;
  35325. + nbytes -= blocks * AES_BLOCK_SIZE;
  35326. + if (nbytes && nbytes == walk.nbytes % AES_BLOCK_SIZE)
  35327. + break;
  35328. + err = blkcipher_walk_done(desc, &walk,
  35329. + walk.nbytes % AES_BLOCK_SIZE);
  35330. + }
  35331. + if (nbytes) {
  35332. + u8 *tdst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
  35333. + u8 *tsrc = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
  35334. + u8 __aligned(8) tail[AES_BLOCK_SIZE];
  35335. +
  35336. + /*
  35337. + * Minimum alignment is 8 bytes, so if nbytes is <= 8, we need
  35338. + * to tell aes_ctr_encrypt() to only read half a block.
  35339. + */
  35340. + blocks = (nbytes <= 8) ? -1 : 1;
  35341. +
  35342. + aes_ctr_encrypt(tail, tsrc, (u8 *)ctx->key_enc, rounds,
  35343. + blocks, walk.iv, first);
  35344. + memcpy(tdst, tail, nbytes);
  35345. + err = blkcipher_walk_done(desc, &walk, 0);
  35346. + }
  35347. + kernel_neon_end();
  35348. +
  35349. + return err;
  35350. +}
  35351. +
  35352. +static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35353. + struct scatterlist *src, unsigned int nbytes)
  35354. +{
  35355. + struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35356. + int err, first, rounds = 6 + ctx->key1.key_length / 4;
  35357. + struct blkcipher_walk walk;
  35358. + unsigned int blocks;
  35359. +
  35360. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35361. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35362. + err = blkcipher_walk_virt(desc, &walk);
  35363. +
  35364. + kernel_neon_begin();
  35365. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35366. + aes_xts_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35367. + (u8 *)ctx->key1.key_enc, rounds, blocks,
  35368. + (u8 *)ctx->key2.key_enc, walk.iv, first);
  35369. + err = blkcipher_walk_done(desc, &walk, 0);
  35370. + }
  35371. + kernel_neon_end();
  35372. +
  35373. + return err;
  35374. +}
  35375. +
  35376. +static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
  35377. + struct scatterlist *src, unsigned int nbytes)
  35378. +{
  35379. + struct crypto_aes_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
  35380. + int err, first, rounds = 6 + ctx->key1.key_length / 4;
  35381. + struct blkcipher_walk walk;
  35382. + unsigned int blocks;
  35383. +
  35384. + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  35385. + blkcipher_walk_init(&walk, dst, src, nbytes);
  35386. + err = blkcipher_walk_virt(desc, &walk);
  35387. +
  35388. + kernel_neon_begin();
  35389. + for (first = 1; (blocks = (walk.nbytes / AES_BLOCK_SIZE)); first = 0) {
  35390. + aes_xts_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
  35391. + (u8 *)ctx->key1.key_dec, rounds, blocks,
  35392. + (u8 *)ctx->key2.key_enc, walk.iv, first);
  35393. + err = blkcipher_walk_done(desc, &walk, 0);
  35394. + }
  35395. + kernel_neon_end();
  35396. +
  35397. + return err;
  35398. +}
  35399. +
  35400. +static struct crypto_alg aes_algs[] = { {
  35401. + .cra_name = "__ecb-aes-" MODE,
  35402. + .cra_driver_name = "__driver-ecb-aes-" MODE,
  35403. + .cra_priority = 0,
  35404. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35405. + .cra_blocksize = AES_BLOCK_SIZE,
  35406. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35407. + .cra_alignmask = 7,
  35408. + .cra_type = &crypto_blkcipher_type,
  35409. + .cra_module = THIS_MODULE,
  35410. + .cra_blkcipher = {
  35411. + .min_keysize = AES_MIN_KEY_SIZE,
  35412. + .max_keysize = AES_MAX_KEY_SIZE,
  35413. + .ivsize = AES_BLOCK_SIZE,
  35414. + .setkey = crypto_aes_set_key,
  35415. + .encrypt = ecb_encrypt,
  35416. + .decrypt = ecb_decrypt,
  35417. + },
  35418. +}, {
  35419. + .cra_name = "__cbc-aes-" MODE,
  35420. + .cra_driver_name = "__driver-cbc-aes-" MODE,
  35421. + .cra_priority = 0,
  35422. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35423. + .cra_blocksize = AES_BLOCK_SIZE,
  35424. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35425. + .cra_alignmask = 7,
  35426. + .cra_type = &crypto_blkcipher_type,
  35427. + .cra_module = THIS_MODULE,
  35428. + .cra_blkcipher = {
  35429. + .min_keysize = AES_MIN_KEY_SIZE,
  35430. + .max_keysize = AES_MAX_KEY_SIZE,
  35431. + .ivsize = AES_BLOCK_SIZE,
  35432. + .setkey = crypto_aes_set_key,
  35433. + .encrypt = cbc_encrypt,
  35434. + .decrypt = cbc_decrypt,
  35435. + },
  35436. +}, {
  35437. + .cra_name = "__ctr-aes-" MODE,
  35438. + .cra_driver_name = "__driver-ctr-aes-" MODE,
  35439. + .cra_priority = 0,
  35440. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35441. + .cra_blocksize = 1,
  35442. + .cra_ctxsize = sizeof(struct crypto_aes_ctx),
  35443. + .cra_alignmask = 7,
  35444. + .cra_type = &crypto_blkcipher_type,
  35445. + .cra_module = THIS_MODULE,
  35446. + .cra_blkcipher = {
  35447. + .min_keysize = AES_MIN_KEY_SIZE,
  35448. + .max_keysize = AES_MAX_KEY_SIZE,
  35449. + .ivsize = AES_BLOCK_SIZE,
  35450. + .setkey = crypto_aes_set_key,
  35451. + .encrypt = ctr_encrypt,
  35452. + .decrypt = ctr_encrypt,
  35453. + },
  35454. +}, {
  35455. + .cra_name = "__xts-aes-" MODE,
  35456. + .cra_driver_name = "__driver-xts-aes-" MODE,
  35457. + .cra_priority = 0,
  35458. + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
  35459. + .cra_blocksize = AES_BLOCK_SIZE,
  35460. + .cra_ctxsize = sizeof(struct crypto_aes_xts_ctx),
  35461. + .cra_alignmask = 7,
  35462. + .cra_type = &crypto_blkcipher_type,
  35463. + .cra_module = THIS_MODULE,
  35464. + .cra_blkcipher = {
  35465. + .min_keysize = 2 * AES_MIN_KEY_SIZE,
  35466. + .max_keysize = 2 * AES_MAX_KEY_SIZE,
  35467. + .ivsize = AES_BLOCK_SIZE,
  35468. + .setkey = xts_set_key,
  35469. + .encrypt = xts_encrypt,
  35470. + .decrypt = xts_decrypt,
  35471. + },
  35472. +}, {
  35473. + .cra_name = "ecb(aes)",
  35474. + .cra_driver_name = "ecb-aes-" MODE,
  35475. + .cra_priority = PRIO,
  35476. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35477. + .cra_blocksize = AES_BLOCK_SIZE,
  35478. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35479. + .cra_alignmask = 7,
  35480. + .cra_type = &crypto_ablkcipher_type,
  35481. + .cra_module = THIS_MODULE,
  35482. + .cra_init = ablk_init,
  35483. + .cra_exit = ablk_exit,
  35484. + .cra_ablkcipher = {
  35485. + .min_keysize = AES_MIN_KEY_SIZE,
  35486. + .max_keysize = AES_MAX_KEY_SIZE,
  35487. + .ivsize = AES_BLOCK_SIZE,
  35488. + .setkey = ablk_set_key,
  35489. + .encrypt = ablk_encrypt,
  35490. + .decrypt = ablk_decrypt,
  35491. + }
  35492. +}, {
  35493. + .cra_name = "cbc(aes)",
  35494. + .cra_driver_name = "cbc-aes-" MODE,
  35495. + .cra_priority = PRIO,
  35496. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35497. + .cra_blocksize = AES_BLOCK_SIZE,
  35498. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35499. + .cra_alignmask = 7,
  35500. + .cra_type = &crypto_ablkcipher_type,
  35501. + .cra_module = THIS_MODULE,
  35502. + .cra_init = ablk_init,
  35503. + .cra_exit = ablk_exit,
  35504. + .cra_ablkcipher = {
  35505. + .min_keysize = AES_MIN_KEY_SIZE,
  35506. + .max_keysize = AES_MAX_KEY_SIZE,
  35507. + .ivsize = AES_BLOCK_SIZE,
  35508. + .setkey = ablk_set_key,
  35509. + .encrypt = ablk_encrypt,
  35510. + .decrypt = ablk_decrypt,
  35511. + }
  35512. +}, {
  35513. + .cra_name = "ctr(aes)",
  35514. + .cra_driver_name = "ctr-aes-" MODE,
  35515. + .cra_priority = PRIO,
  35516. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35517. + .cra_blocksize = 1,
  35518. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35519. + .cra_alignmask = 7,
  35520. + .cra_type = &crypto_ablkcipher_type,
  35521. + .cra_module = THIS_MODULE,
  35522. + .cra_init = ablk_init,
  35523. + .cra_exit = ablk_exit,
  35524. + .cra_ablkcipher = {
  35525. + .min_keysize = AES_MIN_KEY_SIZE,
  35526. + .max_keysize = AES_MAX_KEY_SIZE,
  35527. + .ivsize = AES_BLOCK_SIZE,
  35528. + .setkey = ablk_set_key,
  35529. + .encrypt = ablk_encrypt,
  35530. + .decrypt = ablk_decrypt,
  35531. + }
  35532. +}, {
  35533. + .cra_name = "xts(aes)",
  35534. + .cra_driver_name = "xts-aes-" MODE,
  35535. + .cra_priority = PRIO,
  35536. + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
  35537. + .cra_blocksize = AES_BLOCK_SIZE,
  35538. + .cra_ctxsize = sizeof(struct async_helper_ctx),
  35539. + .cra_alignmask = 7,
  35540. + .cra_type = &crypto_ablkcipher_type,
  35541. + .cra_module = THIS_MODULE,
  35542. + .cra_init = ablk_init,
  35543. + .cra_exit = ablk_exit,
  35544. + .cra_ablkcipher = {
  35545. + .min_keysize = 2 * AES_MIN_KEY_SIZE,
  35546. + .max_keysize = 2 * AES_MAX_KEY_SIZE,
  35547. + .ivsize = AES_BLOCK_SIZE,
  35548. + .setkey = ablk_set_key,
  35549. + .encrypt = ablk_encrypt,
  35550. + .decrypt = ablk_decrypt,
  35551. + }
  35552. +} };
  35553. +
  35554. +static int __init aes_init(void)
  35555. +{
  35556. + return crypto_register_algs(aes_algs, ARRAY_SIZE(aes_algs));
  35557. +}
  35558. +
  35559. +static void __exit aes_exit(void)
  35560. +{
  35561. + crypto_unregister_algs(aes_algs, ARRAY_SIZE(aes_algs));
  35562. +}
  35563. +
  35564. +#ifdef USE_V8_CRYPTO_EXTENSIONS
  35565. +module_cpu_feature_match(AES, aes_init);
  35566. +#else
  35567. +module_init(aes_init);
  35568. +#endif
  35569. +module_exit(aes_exit);
  35570. diff -Nur linux-3.14.17/arch/arm64/crypto/aes-modes.S linux-imx6-3.14/arch/arm64/crypto/aes-modes.S
  35571. --- linux-3.14.17/arch/arm64/crypto/aes-modes.S 1970-01-01 01:00:00.000000000 +0100
  35572. +++ linux-imx6-3.14/arch/arm64/crypto/aes-modes.S 2014-09-11 18:05:54.354007412 +0200
  35573. @@ -0,0 +1,532 @@
  35574. +/*
  35575. + * linux/arch/arm64/crypto/aes-modes.S - chaining mode wrappers for AES
  35576. + *
  35577. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  35578. + *
  35579. + * This program is free software; you can redistribute it and/or modify
  35580. + * it under the terms of the GNU General Public License version 2 as
  35581. + * published by the Free Software Foundation.
  35582. + */
  35583. +
  35584. +/* included by aes-ce.S and aes-neon.S */
  35585. +
  35586. + .text
  35587. + .align 4
  35588. +
  35589. +/*
  35590. + * There are several ways to instantiate this code:
  35591. + * - no interleave, all inline
  35592. + * - 2-way interleave, 2x calls out of line (-DINTERLEAVE=2)
  35593. + * - 2-way interleave, all inline (-DINTERLEAVE=2 -DINTERLEAVE_INLINE)
  35594. + * - 4-way interleave, 4x calls out of line (-DINTERLEAVE=4)
  35595. + * - 4-way interleave, all inline (-DINTERLEAVE=4 -DINTERLEAVE_INLINE)
  35596. + *
  35597. + * Macros imported by this code:
  35598. + * - enc_prepare - setup NEON registers for encryption
  35599. + * - dec_prepare - setup NEON registers for decryption
  35600. + * - enc_switch_key - change to new key after having prepared for encryption
  35601. + * - encrypt_block - encrypt a single block
  35602. + * - decrypt block - decrypt a single block
  35603. + * - encrypt_block2x - encrypt 2 blocks in parallel (if INTERLEAVE == 2)
  35604. + * - decrypt_block2x - decrypt 2 blocks in parallel (if INTERLEAVE == 2)
  35605. + * - encrypt_block4x - encrypt 4 blocks in parallel (if INTERLEAVE == 4)
  35606. + * - decrypt_block4x - decrypt 4 blocks in parallel (if INTERLEAVE == 4)
  35607. + */
  35608. +
  35609. +#if defined(INTERLEAVE) && !defined(INTERLEAVE_INLINE)
  35610. +#define FRAME_PUSH stp x29, x30, [sp,#-16]! ; mov x29, sp
  35611. +#define FRAME_POP ldp x29, x30, [sp],#16
  35612. +
  35613. +#if INTERLEAVE == 2
  35614. +
  35615. +aes_encrypt_block2x:
  35616. + encrypt_block2x v0, v1, w3, x2, x6, w7
  35617. + ret
  35618. +ENDPROC(aes_encrypt_block2x)
  35619. +
  35620. +aes_decrypt_block2x:
  35621. + decrypt_block2x v0, v1, w3, x2, x6, w7
  35622. + ret
  35623. +ENDPROC(aes_decrypt_block2x)
  35624. +
  35625. +#elif INTERLEAVE == 4
  35626. +
  35627. +aes_encrypt_block4x:
  35628. + encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35629. + ret
  35630. +ENDPROC(aes_encrypt_block4x)
  35631. +
  35632. +aes_decrypt_block4x:
  35633. + decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35634. + ret
  35635. +ENDPROC(aes_decrypt_block4x)
  35636. +
  35637. +#else
  35638. +#error INTERLEAVE should equal 2 or 4
  35639. +#endif
  35640. +
  35641. + .macro do_encrypt_block2x
  35642. + bl aes_encrypt_block2x
  35643. + .endm
  35644. +
  35645. + .macro do_decrypt_block2x
  35646. + bl aes_decrypt_block2x
  35647. + .endm
  35648. +
  35649. + .macro do_encrypt_block4x
  35650. + bl aes_encrypt_block4x
  35651. + .endm
  35652. +
  35653. + .macro do_decrypt_block4x
  35654. + bl aes_decrypt_block4x
  35655. + .endm
  35656. +
  35657. +#else
  35658. +#define FRAME_PUSH
  35659. +#define FRAME_POP
  35660. +
  35661. + .macro do_encrypt_block2x
  35662. + encrypt_block2x v0, v1, w3, x2, x6, w7
  35663. + .endm
  35664. +
  35665. + .macro do_decrypt_block2x
  35666. + decrypt_block2x v0, v1, w3, x2, x6, w7
  35667. + .endm
  35668. +
  35669. + .macro do_encrypt_block4x
  35670. + encrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35671. + .endm
  35672. +
  35673. + .macro do_decrypt_block4x
  35674. + decrypt_block4x v0, v1, v2, v3, w3, x2, x6, w7
  35675. + .endm
  35676. +
  35677. +#endif
  35678. +
  35679. + /*
  35680. + * aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35681. + * int blocks, int first)
  35682. + * aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35683. + * int blocks, int first)
  35684. + */
  35685. +
  35686. +AES_ENTRY(aes_ecb_encrypt)
  35687. + FRAME_PUSH
  35688. + cbz w5, .LecbencloopNx
  35689. +
  35690. + enc_prepare w3, x2, x5
  35691. +
  35692. +.LecbencloopNx:
  35693. +#if INTERLEAVE >= 2
  35694. + subs w4, w4, #INTERLEAVE
  35695. + bmi .Lecbenc1x
  35696. +#if INTERLEAVE == 2
  35697. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 pt blocks */
  35698. + do_encrypt_block2x
  35699. + st1 {v0.16b-v1.16b}, [x0], #32
  35700. +#else
  35701. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  35702. + do_encrypt_block4x
  35703. + st1 {v0.16b-v3.16b}, [x0], #64
  35704. +#endif
  35705. + b .LecbencloopNx
  35706. +.Lecbenc1x:
  35707. + adds w4, w4, #INTERLEAVE
  35708. + beq .Lecbencout
  35709. +#endif
  35710. +.Lecbencloop:
  35711. + ld1 {v0.16b}, [x1], #16 /* get next pt block */
  35712. + encrypt_block v0, w3, x2, x5, w6
  35713. + st1 {v0.16b}, [x0], #16
  35714. + subs w4, w4, #1
  35715. + bne .Lecbencloop
  35716. +.Lecbencout:
  35717. + FRAME_POP
  35718. + ret
  35719. +AES_ENDPROC(aes_ecb_encrypt)
  35720. +
  35721. +
  35722. +AES_ENTRY(aes_ecb_decrypt)
  35723. + FRAME_PUSH
  35724. + cbz w5, .LecbdecloopNx
  35725. +
  35726. + dec_prepare w3, x2, x5
  35727. +
  35728. +.LecbdecloopNx:
  35729. +#if INTERLEAVE >= 2
  35730. + subs w4, w4, #INTERLEAVE
  35731. + bmi .Lecbdec1x
  35732. +#if INTERLEAVE == 2
  35733. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35734. + do_decrypt_block2x
  35735. + st1 {v0.16b-v1.16b}, [x0], #32
  35736. +#else
  35737. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35738. + do_decrypt_block4x
  35739. + st1 {v0.16b-v3.16b}, [x0], #64
  35740. +#endif
  35741. + b .LecbdecloopNx
  35742. +.Lecbdec1x:
  35743. + adds w4, w4, #INTERLEAVE
  35744. + beq .Lecbdecout
  35745. +#endif
  35746. +.Lecbdecloop:
  35747. + ld1 {v0.16b}, [x1], #16 /* get next ct block */
  35748. + decrypt_block v0, w3, x2, x5, w6
  35749. + st1 {v0.16b}, [x0], #16
  35750. + subs w4, w4, #1
  35751. + bne .Lecbdecloop
  35752. +.Lecbdecout:
  35753. + FRAME_POP
  35754. + ret
  35755. +AES_ENDPROC(aes_ecb_decrypt)
  35756. +
  35757. +
  35758. + /*
  35759. + * aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35760. + * int blocks, u8 iv[], int first)
  35761. + * aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35762. + * int blocks, u8 iv[], int first)
  35763. + */
  35764. +
  35765. +AES_ENTRY(aes_cbc_encrypt)
  35766. + cbz w6, .Lcbcencloop
  35767. +
  35768. + ld1 {v0.16b}, [x5] /* get iv */
  35769. + enc_prepare w3, x2, x5
  35770. +
  35771. +.Lcbcencloop:
  35772. + ld1 {v1.16b}, [x1], #16 /* get next pt block */
  35773. + eor v0.16b, v0.16b, v1.16b /* ..and xor with iv */
  35774. + encrypt_block v0, w3, x2, x5, w6
  35775. + st1 {v0.16b}, [x0], #16
  35776. + subs w4, w4, #1
  35777. + bne .Lcbcencloop
  35778. + ret
  35779. +AES_ENDPROC(aes_cbc_encrypt)
  35780. +
  35781. +
  35782. +AES_ENTRY(aes_cbc_decrypt)
  35783. + FRAME_PUSH
  35784. + cbz w6, .LcbcdecloopNx
  35785. +
  35786. + ld1 {v7.16b}, [x5] /* get iv */
  35787. + dec_prepare w3, x2, x5
  35788. +
  35789. +.LcbcdecloopNx:
  35790. +#if INTERLEAVE >= 2
  35791. + subs w4, w4, #INTERLEAVE
  35792. + bmi .Lcbcdec1x
  35793. +#if INTERLEAVE == 2
  35794. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  35795. + mov v2.16b, v0.16b
  35796. + mov v3.16b, v1.16b
  35797. + do_decrypt_block2x
  35798. + eor v0.16b, v0.16b, v7.16b
  35799. + eor v1.16b, v1.16b, v2.16b
  35800. + mov v7.16b, v3.16b
  35801. + st1 {v0.16b-v1.16b}, [x0], #32
  35802. +#else
  35803. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  35804. + mov v4.16b, v0.16b
  35805. + mov v5.16b, v1.16b
  35806. + mov v6.16b, v2.16b
  35807. + do_decrypt_block4x
  35808. + sub x1, x1, #16
  35809. + eor v0.16b, v0.16b, v7.16b
  35810. + eor v1.16b, v1.16b, v4.16b
  35811. + ld1 {v7.16b}, [x1], #16 /* reload 1 ct block */
  35812. + eor v2.16b, v2.16b, v5.16b
  35813. + eor v3.16b, v3.16b, v6.16b
  35814. + st1 {v0.16b-v3.16b}, [x0], #64
  35815. +#endif
  35816. + b .LcbcdecloopNx
  35817. +.Lcbcdec1x:
  35818. + adds w4, w4, #INTERLEAVE
  35819. + beq .Lcbcdecout
  35820. +#endif
  35821. +.Lcbcdecloop:
  35822. + ld1 {v1.16b}, [x1], #16 /* get next ct block */
  35823. + mov v0.16b, v1.16b /* ...and copy to v0 */
  35824. + decrypt_block v0, w3, x2, x5, w6
  35825. + eor v0.16b, v0.16b, v7.16b /* xor with iv => pt */
  35826. + mov v7.16b, v1.16b /* ct is next iv */
  35827. + st1 {v0.16b}, [x0], #16
  35828. + subs w4, w4, #1
  35829. + bne .Lcbcdecloop
  35830. +.Lcbcdecout:
  35831. + FRAME_POP
  35832. + ret
  35833. +AES_ENDPROC(aes_cbc_decrypt)
  35834. +
  35835. +
  35836. + /*
  35837. + * aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
  35838. + * int blocks, u8 ctr[], int first)
  35839. + */
  35840. +
  35841. +AES_ENTRY(aes_ctr_encrypt)
  35842. + FRAME_PUSH
  35843. + cbnz w6, .Lctrfirst /* 1st time around? */
  35844. + umov x5, v4.d[1] /* keep swabbed ctr in reg */
  35845. + rev x5, x5
  35846. +#if INTERLEAVE >= 2
  35847. + cmn w5, w4 /* 32 bit overflow? */
  35848. + bcs .Lctrinc
  35849. + add x5, x5, #1 /* increment BE ctr */
  35850. + b .LctrincNx
  35851. +#else
  35852. + b .Lctrinc
  35853. +#endif
  35854. +.Lctrfirst:
  35855. + enc_prepare w3, x2, x6
  35856. + ld1 {v4.16b}, [x5]
  35857. + umov x5, v4.d[1] /* keep swabbed ctr in reg */
  35858. + rev x5, x5
  35859. +#if INTERLEAVE >= 2
  35860. + cmn w5, w4 /* 32 bit overflow? */
  35861. + bcs .Lctrloop
  35862. +.LctrloopNx:
  35863. + subs w4, w4, #INTERLEAVE
  35864. + bmi .Lctr1x
  35865. +#if INTERLEAVE == 2
  35866. + mov v0.8b, v4.8b
  35867. + mov v1.8b, v4.8b
  35868. + rev x7, x5
  35869. + add x5, x5, #1
  35870. + ins v0.d[1], x7
  35871. + rev x7, x5
  35872. + add x5, x5, #1
  35873. + ins v1.d[1], x7
  35874. + ld1 {v2.16b-v3.16b}, [x1], #32 /* get 2 input blocks */
  35875. + do_encrypt_block2x
  35876. + eor v0.16b, v0.16b, v2.16b
  35877. + eor v1.16b, v1.16b, v3.16b
  35878. + st1 {v0.16b-v1.16b}, [x0], #32
  35879. +#else
  35880. + ldr q8, =0x30000000200000001 /* addends 1,2,3[,0] */
  35881. + dup v7.4s, w5
  35882. + mov v0.16b, v4.16b
  35883. + add v7.4s, v7.4s, v8.4s
  35884. + mov v1.16b, v4.16b
  35885. + rev32 v8.16b, v7.16b
  35886. + mov v2.16b, v4.16b
  35887. + mov v3.16b, v4.16b
  35888. + mov v1.s[3], v8.s[0]
  35889. + mov v2.s[3], v8.s[1]
  35890. + mov v3.s[3], v8.s[2]
  35891. + ld1 {v5.16b-v7.16b}, [x1], #48 /* get 3 input blocks */
  35892. + do_encrypt_block4x
  35893. + eor v0.16b, v5.16b, v0.16b
  35894. + ld1 {v5.16b}, [x1], #16 /* get 1 input block */
  35895. + eor v1.16b, v6.16b, v1.16b
  35896. + eor v2.16b, v7.16b, v2.16b
  35897. + eor v3.16b, v5.16b, v3.16b
  35898. + st1 {v0.16b-v3.16b}, [x0], #64
  35899. + add x5, x5, #INTERLEAVE
  35900. +#endif
  35901. + cbz w4, .LctroutNx
  35902. +.LctrincNx:
  35903. + rev x7, x5
  35904. + ins v4.d[1], x7
  35905. + b .LctrloopNx
  35906. +.LctroutNx:
  35907. + sub x5, x5, #1
  35908. + rev x7, x5
  35909. + ins v4.d[1], x7
  35910. + b .Lctrout
  35911. +.Lctr1x:
  35912. + adds w4, w4, #INTERLEAVE
  35913. + beq .Lctrout
  35914. +#endif
  35915. +.Lctrloop:
  35916. + mov v0.16b, v4.16b
  35917. + encrypt_block v0, w3, x2, x6, w7
  35918. + subs w4, w4, #1
  35919. + bmi .Lctrhalfblock /* blocks < 0 means 1/2 block */
  35920. + ld1 {v3.16b}, [x1], #16
  35921. + eor v3.16b, v0.16b, v3.16b
  35922. + st1 {v3.16b}, [x0], #16
  35923. + beq .Lctrout
  35924. +.Lctrinc:
  35925. + adds x5, x5, #1 /* increment BE ctr */
  35926. + rev x7, x5
  35927. + ins v4.d[1], x7
  35928. + bcc .Lctrloop /* no overflow? */
  35929. + umov x7, v4.d[0] /* load upper word of ctr */
  35930. + rev x7, x7 /* ... to handle the carry */
  35931. + add x7, x7, #1
  35932. + rev x7, x7
  35933. + ins v4.d[0], x7
  35934. + b .Lctrloop
  35935. +.Lctrhalfblock:
  35936. + ld1 {v3.8b}, [x1]
  35937. + eor v3.8b, v0.8b, v3.8b
  35938. + st1 {v3.8b}, [x0]
  35939. +.Lctrout:
  35940. + FRAME_POP
  35941. + ret
  35942. +AES_ENDPROC(aes_ctr_encrypt)
  35943. + .ltorg
  35944. +
  35945. +
  35946. + /*
  35947. + * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  35948. + * int blocks, u8 const rk2[], u8 iv[], int first)
  35949. + * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
  35950. + * int blocks, u8 const rk2[], u8 iv[], int first)
  35951. + */
  35952. +
  35953. + .macro next_tweak, out, in, const, tmp
  35954. + sshr \tmp\().2d, \in\().2d, #63
  35955. + and \tmp\().16b, \tmp\().16b, \const\().16b
  35956. + add \out\().2d, \in\().2d, \in\().2d
  35957. + ext \tmp\().16b, \tmp\().16b, \tmp\().16b, #8
  35958. + eor \out\().16b, \out\().16b, \tmp\().16b
  35959. + .endm
  35960. +
  35961. +.Lxts_mul_x:
  35962. + .word 1, 0, 0x87, 0
  35963. +
  35964. +AES_ENTRY(aes_xts_encrypt)
  35965. + FRAME_PUSH
  35966. + cbz w7, .LxtsencloopNx
  35967. +
  35968. + ld1 {v4.16b}, [x6]
  35969. + enc_prepare w3, x5, x6
  35970. + encrypt_block v4, w3, x5, x6, w7 /* first tweak */
  35971. + enc_switch_key w3, x2, x6
  35972. + ldr q7, .Lxts_mul_x
  35973. + b .LxtsencNx
  35974. +
  35975. +.LxtsencloopNx:
  35976. + ldr q7, .Lxts_mul_x
  35977. + next_tweak v4, v4, v7, v8
  35978. +.LxtsencNx:
  35979. +#if INTERLEAVE >= 2
  35980. + subs w4, w4, #INTERLEAVE
  35981. + bmi .Lxtsenc1x
  35982. +#if INTERLEAVE == 2
  35983. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 pt blocks */
  35984. + next_tweak v5, v4, v7, v8
  35985. + eor v0.16b, v0.16b, v4.16b
  35986. + eor v1.16b, v1.16b, v5.16b
  35987. + do_encrypt_block2x
  35988. + eor v0.16b, v0.16b, v4.16b
  35989. + eor v1.16b, v1.16b, v5.16b
  35990. + st1 {v0.16b-v1.16b}, [x0], #32
  35991. + cbz w4, .LxtsencoutNx
  35992. + next_tweak v4, v5, v7, v8
  35993. + b .LxtsencNx
  35994. +.LxtsencoutNx:
  35995. + mov v4.16b, v5.16b
  35996. + b .Lxtsencout
  35997. +#else
  35998. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 pt blocks */
  35999. + next_tweak v5, v4, v7, v8
  36000. + eor v0.16b, v0.16b, v4.16b
  36001. + next_tweak v6, v5, v7, v8
  36002. + eor v1.16b, v1.16b, v5.16b
  36003. + eor v2.16b, v2.16b, v6.16b
  36004. + next_tweak v7, v6, v7, v8
  36005. + eor v3.16b, v3.16b, v7.16b
  36006. + do_encrypt_block4x
  36007. + eor v3.16b, v3.16b, v7.16b
  36008. + eor v0.16b, v0.16b, v4.16b
  36009. + eor v1.16b, v1.16b, v5.16b
  36010. + eor v2.16b, v2.16b, v6.16b
  36011. + st1 {v0.16b-v3.16b}, [x0], #64
  36012. + mov v4.16b, v7.16b
  36013. + cbz w4, .Lxtsencout
  36014. + b .LxtsencloopNx
  36015. +#endif
  36016. +.Lxtsenc1x:
  36017. + adds w4, w4, #INTERLEAVE
  36018. + beq .Lxtsencout
  36019. +#endif
  36020. +.Lxtsencloop:
  36021. + ld1 {v1.16b}, [x1], #16
  36022. + eor v0.16b, v1.16b, v4.16b
  36023. + encrypt_block v0, w3, x2, x6, w7
  36024. + eor v0.16b, v0.16b, v4.16b
  36025. + st1 {v0.16b}, [x0], #16
  36026. + subs w4, w4, #1
  36027. + beq .Lxtsencout
  36028. + next_tweak v4, v4, v7, v8
  36029. + b .Lxtsencloop
  36030. +.Lxtsencout:
  36031. + FRAME_POP
  36032. + ret
  36033. +AES_ENDPROC(aes_xts_encrypt)
  36034. +
  36035. +
  36036. +AES_ENTRY(aes_xts_decrypt)
  36037. + FRAME_PUSH
  36038. + cbz w7, .LxtsdecloopNx
  36039. +
  36040. + ld1 {v4.16b}, [x6]
  36041. + enc_prepare w3, x5, x6
  36042. + encrypt_block v4, w3, x5, x6, w7 /* first tweak */
  36043. + dec_prepare w3, x2, x6
  36044. + ldr q7, .Lxts_mul_x
  36045. + b .LxtsdecNx
  36046. +
  36047. +.LxtsdecloopNx:
  36048. + ldr q7, .Lxts_mul_x
  36049. + next_tweak v4, v4, v7, v8
  36050. +.LxtsdecNx:
  36051. +#if INTERLEAVE >= 2
  36052. + subs w4, w4, #INTERLEAVE
  36053. + bmi .Lxtsdec1x
  36054. +#if INTERLEAVE == 2
  36055. + ld1 {v0.16b-v1.16b}, [x1], #32 /* get 2 ct blocks */
  36056. + next_tweak v5, v4, v7, v8
  36057. + eor v0.16b, v0.16b, v4.16b
  36058. + eor v1.16b, v1.16b, v5.16b
  36059. + do_decrypt_block2x
  36060. + eor v0.16b, v0.16b, v4.16b
  36061. + eor v1.16b, v1.16b, v5.16b
  36062. + st1 {v0.16b-v1.16b}, [x0], #32
  36063. + cbz w4, .LxtsdecoutNx
  36064. + next_tweak v4, v5, v7, v8
  36065. + b .LxtsdecNx
  36066. +.LxtsdecoutNx:
  36067. + mov v4.16b, v5.16b
  36068. + b .Lxtsdecout
  36069. +#else
  36070. + ld1 {v0.16b-v3.16b}, [x1], #64 /* get 4 ct blocks */
  36071. + next_tweak v5, v4, v7, v8
  36072. + eor v0.16b, v0.16b, v4.16b
  36073. + next_tweak v6, v5, v7, v8
  36074. + eor v1.16b, v1.16b, v5.16b
  36075. + eor v2.16b, v2.16b, v6.16b
  36076. + next_tweak v7, v6, v7, v8
  36077. + eor v3.16b, v3.16b, v7.16b
  36078. + do_decrypt_block4x
  36079. + eor v3.16b, v3.16b, v7.16b
  36080. + eor v0.16b, v0.16b, v4.16b
  36081. + eor v1.16b, v1.16b, v5.16b
  36082. + eor v2.16b, v2.16b, v6.16b
  36083. + st1 {v0.16b-v3.16b}, [x0], #64
  36084. + mov v4.16b, v7.16b
  36085. + cbz w4, .Lxtsdecout
  36086. + b .LxtsdecloopNx
  36087. +#endif
  36088. +.Lxtsdec1x:
  36089. + adds w4, w4, #INTERLEAVE
  36090. + beq .Lxtsdecout
  36091. +#endif
  36092. +.Lxtsdecloop:
  36093. + ld1 {v1.16b}, [x1], #16
  36094. + eor v0.16b, v1.16b, v4.16b
  36095. + decrypt_block v0, w3, x2, x6, w7
  36096. + eor v0.16b, v0.16b, v4.16b
  36097. + st1 {v0.16b}, [x0], #16
  36098. + subs w4, w4, #1
  36099. + beq .Lxtsdecout
  36100. + next_tweak v4, v4, v7, v8
  36101. + b .Lxtsdecloop
  36102. +.Lxtsdecout:
  36103. + FRAME_POP
  36104. + ret
  36105. +AES_ENDPROC(aes_xts_decrypt)
  36106. diff -Nur linux-3.14.17/arch/arm64/crypto/aes-neon.S linux-imx6-3.14/arch/arm64/crypto/aes-neon.S
  36107. --- linux-3.14.17/arch/arm64/crypto/aes-neon.S 1970-01-01 01:00:00.000000000 +0100
  36108. +++ linux-imx6-3.14/arch/arm64/crypto/aes-neon.S 2014-09-11 18:05:54.394007574 +0200
  36109. @@ -0,0 +1,382 @@
  36110. +/*
  36111. + * linux/arch/arm64/crypto/aes-neon.S - AES cipher for ARMv8 NEON
  36112. + *
  36113. + * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  36114. + *
  36115. + * This program is free software; you can redistribute it and/or modify
  36116. + * it under the terms of the GNU General Public License version 2 as
  36117. + * published by the Free Software Foundation.
  36118. + */
  36119. +
  36120. +#include <linux/linkage.h>
  36121. +
  36122. +#define AES_ENTRY(func) ENTRY(neon_ ## func)
  36123. +#define AES_ENDPROC(func) ENDPROC(neon_ ## func)
  36124. +
  36125. + /* multiply by polynomial 'x' in GF(2^8) */
  36126. + .macro mul_by_x, out, in, temp, const
  36127. + sshr \temp, \in, #7
  36128. + add \out, \in, \in
  36129. + and \temp, \temp, \const
  36130. + eor \out, \out, \temp
  36131. + .endm
  36132. +
  36133. + /* preload the entire Sbox */
  36134. + .macro prepare, sbox, shiftrows, temp
  36135. + adr \temp, \sbox
  36136. + movi v12.16b, #0x40
  36137. + ldr q13, \shiftrows
  36138. + movi v14.16b, #0x1b
  36139. + ld1 {v16.16b-v19.16b}, [\temp], #64
  36140. + ld1 {v20.16b-v23.16b}, [\temp], #64
  36141. + ld1 {v24.16b-v27.16b}, [\temp], #64
  36142. + ld1 {v28.16b-v31.16b}, [\temp]
  36143. + .endm
  36144. +
  36145. + /* do preload for encryption */
  36146. + .macro enc_prepare, ignore0, ignore1, temp
  36147. + prepare .LForward_Sbox, .LForward_ShiftRows, \temp
  36148. + .endm
  36149. +
  36150. + .macro enc_switch_key, ignore0, ignore1, temp
  36151. + /* do nothing */
  36152. + .endm
  36153. +
  36154. + /* do preload for decryption */
  36155. + .macro dec_prepare, ignore0, ignore1, temp
  36156. + prepare .LReverse_Sbox, .LReverse_ShiftRows, \temp
  36157. + .endm
  36158. +
  36159. + /* apply SubBytes transformation using the the preloaded Sbox */
  36160. + .macro sub_bytes, in
  36161. + sub v9.16b, \in\().16b, v12.16b
  36162. + tbl \in\().16b, {v16.16b-v19.16b}, \in\().16b
  36163. + sub v10.16b, v9.16b, v12.16b
  36164. + tbx \in\().16b, {v20.16b-v23.16b}, v9.16b
  36165. + sub v11.16b, v10.16b, v12.16b
  36166. + tbx \in\().16b, {v24.16b-v27.16b}, v10.16b
  36167. + tbx \in\().16b, {v28.16b-v31.16b}, v11.16b
  36168. + .endm
  36169. +
  36170. + /* apply MixColumns transformation */
  36171. + .macro mix_columns, in
  36172. + mul_by_x v10.16b, \in\().16b, v9.16b, v14.16b
  36173. + rev32 v8.8h, \in\().8h
  36174. + eor \in\().16b, v10.16b, \in\().16b
  36175. + shl v9.4s, v8.4s, #24
  36176. + shl v11.4s, \in\().4s, #24
  36177. + sri v9.4s, v8.4s, #8
  36178. + sri v11.4s, \in\().4s, #8
  36179. + eor v9.16b, v9.16b, v8.16b
  36180. + eor v10.16b, v10.16b, v9.16b
  36181. + eor \in\().16b, v10.16b, v11.16b
  36182. + .endm
  36183. +
  36184. + /* Inverse MixColumns: pre-multiply by { 5, 0, 4, 0 } */
  36185. + .macro inv_mix_columns, in
  36186. + mul_by_x v11.16b, \in\().16b, v10.16b, v14.16b
  36187. + mul_by_x v11.16b, v11.16b, v10.16b, v14.16b
  36188. + eor \in\().16b, \in\().16b, v11.16b
  36189. + rev32 v11.8h, v11.8h
  36190. + eor \in\().16b, \in\().16b, v11.16b
  36191. + mix_columns \in
  36192. + .endm
  36193. +
  36194. + .macro do_block, enc, in, rounds, rk, rkp, i
  36195. + ld1 {v15.16b}, [\rk]
  36196. + add \rkp, \rk, #16
  36197. + mov \i, \rounds
  36198. +1111: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
  36199. + tbl \in\().16b, {\in\().16b}, v13.16b /* ShiftRows */
  36200. + sub_bytes \in
  36201. + ld1 {v15.16b}, [\rkp], #16
  36202. + subs \i, \i, #1
  36203. + beq 2222f
  36204. + .if \enc == 1
  36205. + mix_columns \in
  36206. + .else
  36207. + inv_mix_columns \in
  36208. + .endif
  36209. + b 1111b
  36210. +2222: eor \in\().16b, \in\().16b, v15.16b /* ^round key */
  36211. + .endm
  36212. +
  36213. + .macro encrypt_block, in, rounds, rk, rkp, i
  36214. + do_block 1, \in, \rounds, \rk, \rkp, \i
  36215. + .endm
  36216. +
  36217. + .macro decrypt_block, in, rounds, rk, rkp, i
  36218. + do_block 0, \in, \rounds, \rk, \rkp, \i
  36219. + .endm
  36220. +
  36221. + /*
  36222. + * Interleaved versions: functionally equivalent to the
  36223. + * ones above, but applied to 2 or 4 AES states in parallel.
  36224. + */
  36225. +
  36226. + .macro sub_bytes_2x, in0, in1
  36227. + sub v8.16b, \in0\().16b, v12.16b
  36228. + sub v9.16b, \in1\().16b, v12.16b
  36229. + tbl \in0\().16b, {v16.16b-v19.16b}, \in0\().16b
  36230. + tbl \in1\().16b, {v16.16b-v19.16b}, \in1\().16b
  36231. + sub v10.16b, v8.16b, v12.16b
  36232. + sub v11.16b, v9.16b, v12.16b
  36233. + tbx \in0\().16b, {v20.16b-v23.16b}, v8.16b
  36234. + tbx \in1\().16b, {v20.16b-v23.16b}, v9.16b
  36235. + sub v8.16b, v10.16b, v12.16b
  36236. + sub v9.16b, v11.16b, v12.16b
  36237. + tbx \in0\().16b, {v24.16b-v27.16b}, v10.16b
  36238. + tbx \in1\().16b, {v24.16b-v27.16b}, v11.16b
  36239. + tbx \in0\().16b, {v28.16b-v31.16b}, v8.16b
  36240. + tbx \in1\().16b, {v28.16b-v31.16b}, v9.16b
  36241. + .endm
  36242. +
  36243. + .macro sub_bytes_4x, in0, in1, in2, in3
  36244. + sub v8.16b, \in0\().16b, v12.16b
  36245. + tbl \in0\().16b, {v16.16b-v19.16b}, \in0\().16b
  36246. + sub v9.16b, \in1\().16b, v12.16b
  36247. + tbl \in1\().16b, {v16.16b-v19.16b}, \in1\().16b
  36248. + sub v10.16b, \in2\().16b, v12.16b
  36249. + tbl \in2\().16b, {v16.16b-v19.16b}, \in2\().16b
  36250. + sub v11.16b, \in3\().16b, v12.16b
  36251. + tbl \in3\().16b, {v16.16b-v19.16b}, \in3\().16b
  36252. + tbx \in0\().16b, {v20.16b-v23.16b}, v8.16b
  36253. + tbx \in1\().16b, {v20.16b-v23.16b}, v9.16b
  36254. + sub v8.16b, v8.16b, v12.16b
  36255. + tbx \in2\().16b, {v20.16b-v23.16b}, v10.16b
  36256. + sub v9.16b, v9.16b, v12.16b
  36257. + tbx \in3\().16b, {v20.16b-v23.16b}, v11.16b
  36258. + sub v10.16b, v10.16b, v12.16b
  36259. + tbx \in0\().16b, {v24.16b-v27.16b}, v8.16b
  36260. + sub v11.16b, v11.16b, v12.16b
  36261. + tbx \in1\().16b, {v24.16b-v27.16b}, v9.16b
  36262. + sub v8.16b, v8.16b, v12.16b
  36263. + tbx \in2\().16b, {v24.16b-v27.16b}, v10.16b
  36264. + sub v9.16b, v9.16b, v12.16b
  36265. + tbx \in3\().16b, {v24.16b-v27.16b}, v11.16b
  36266. + sub v10.16b, v10.16b, v12.16b
  36267. + tbx \in0\().16b, {v28.16b-v31.16b}, v8.16b
  36268. + sub v11.16b, v11.16b, v12.16b
  36269. + tbx \in1\().16b, {v28.16b-v31.16b}, v9.16b
  36270. + tbx \in2\().16b, {v28.16b-v31.16b}, v10.16b
  36271. + tbx \in3\().16b, {v28.16b-v31.16b}, v11.16b
  36272. + .endm
  36273. +
  36274. + .macro mul_by_x_2x, out0, out1, in0, in1, tmp0, tmp1, const
  36275. + sshr \tmp0\().16b, \in0\().16b, #7
  36276. + add \out0\().16b, \in0\().16b, \in0\().16b
  36277. + sshr \tmp1\().16b, \in1\().16b, #7
  36278. + and \tmp0\().16b, \tmp0\().16b, \const\().16b
  36279. + add \out1\().16b, \in1\().16b, \in1\().16b
  36280. + and \tmp1\().16b, \tmp1\().16b, \const\().16b
  36281. + eor \out0\().16b, \out0\().16b, \tmp0\().16b
  36282. + eor \out1\().16b, \out1\().16b, \tmp1\().16b
  36283. + .endm
  36284. +
  36285. + .macro mix_columns_2x, in0, in1
  36286. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36287. + rev32 v10.8h, \in0\().8h
  36288. + rev32 v11.8h, \in1\().8h
  36289. + eor \in0\().16b, v8.16b, \in0\().16b
  36290. + eor \in1\().16b, v9.16b, \in1\().16b
  36291. + shl v12.4s, v10.4s, #24
  36292. + shl v13.4s, v11.4s, #24
  36293. + eor v8.16b, v8.16b, v10.16b
  36294. + sri v12.4s, v10.4s, #8
  36295. + shl v10.4s, \in0\().4s, #24
  36296. + eor v9.16b, v9.16b, v11.16b
  36297. + sri v13.4s, v11.4s, #8
  36298. + shl v11.4s, \in1\().4s, #24
  36299. + sri v10.4s, \in0\().4s, #8
  36300. + eor \in0\().16b, v8.16b, v12.16b
  36301. + sri v11.4s, \in1\().4s, #8
  36302. + eor \in1\().16b, v9.16b, v13.16b
  36303. + eor \in0\().16b, v10.16b, \in0\().16b
  36304. + eor \in1\().16b, v11.16b, \in1\().16b
  36305. + .endm
  36306. +
  36307. + .macro inv_mix_cols_2x, in0, in1
  36308. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36309. + mul_by_x_2x v8, v9, v8, v9, v10, v11, v14
  36310. + eor \in0\().16b, \in0\().16b, v8.16b
  36311. + eor \in1\().16b, \in1\().16b, v9.16b
  36312. + rev32 v8.8h, v8.8h
  36313. + rev32 v9.8h, v9.8h
  36314. + eor \in0\().16b, \in0\().16b, v8.16b
  36315. + eor \in1\().16b, \in1\().16b, v9.16b
  36316. + mix_columns_2x \in0, \in1
  36317. + .endm
  36318. +
  36319. + .macro inv_mix_cols_4x, in0, in1, in2, in3
  36320. + mul_by_x_2x v8, v9, \in0, \in1, v10, v11, v14
  36321. + mul_by_x_2x v10, v11, \in2, \in3, v12, v13, v14
  36322. + mul_by_x_2x v8, v9, v8, v9, v12, v13, v14
  36323. + mul_by_x_2x v10, v11, v10, v11, v12, v13, v14
  36324. + eor \in0\().16b, \in0\().16b, v8.16b
  36325. + eor \in1\().16b, \in1\().16b, v9.16b
  36326. + eor \in2\().16b, \in2\().16b, v10.16b
  36327. + eor \in3\().16b, \in3\().16b, v11.16b
  36328. + rev32 v8.8h, v8.8h
  36329. + rev32 v9.8h, v9.8h
  36330. + rev32 v10.8h, v10.8h
  36331. + rev32 v11.8h, v11.8h
  36332. + eor \in0\().16b, \in0\().16b, v8.16b
  36333. + eor \in1\().16b, \in1\().16b, v9.16b
  36334. + eor \in2\().16b, \in2\().16b, v10.16b
  36335. + eor \in3\().16b, \in3\().16b, v11.16b
  36336. + mix_columns_2x \in0, \in1
  36337. + mix_columns_2x \in2, \in3
  36338. + .endm
  36339. +
  36340. + .macro do_block_2x, enc, in0, in1 rounds, rk, rkp, i
  36341. + ld1 {v15.16b}, [\rk]
  36342. + add \rkp, \rk, #16
  36343. + mov \i, \rounds
  36344. +1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36345. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36346. + sub_bytes_2x \in0, \in1
  36347. + tbl \in0\().16b, {\in0\().16b}, v13.16b /* ShiftRows */
  36348. + tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */
  36349. + ld1 {v15.16b}, [\rkp], #16
  36350. + subs \i, \i, #1
  36351. + beq 2222f
  36352. + .if \enc == 1
  36353. + mix_columns_2x \in0, \in1
  36354. + ldr q13, .LForward_ShiftRows
  36355. + .else
  36356. + inv_mix_cols_2x \in0, \in1
  36357. + ldr q13, .LReverse_ShiftRows
  36358. + .endif
  36359. + movi v12.16b, #0x40
  36360. + b 1111b
  36361. +2222: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36362. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36363. + .endm
  36364. +
  36365. + .macro do_block_4x, enc, in0, in1, in2, in3, rounds, rk, rkp, i
  36366. + ld1 {v15.16b}, [\rk]
  36367. + add \rkp, \rk, #16
  36368. + mov \i, \rounds
  36369. +1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36370. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36371. + eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
  36372. + eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
  36373. + sub_bytes_4x \in0, \in1, \in2, \in3
  36374. + tbl \in0\().16b, {\in0\().16b}, v13.16b /* ShiftRows */
  36375. + tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */
  36376. + tbl \in2\().16b, {\in2\().16b}, v13.16b /* ShiftRows */
  36377. + tbl \in3\().16b, {\in3\().16b}, v13.16b /* ShiftRows */
  36378. + ld1 {v15.16b}, [\rkp], #16
  36379. + subs \i, \i, #1
  36380. + beq 2222f
  36381. + .if \enc == 1
  36382. + mix_columns_2x \in0, \in1
  36383. + mix_columns_2x \in2, \in3
  36384. + ldr q13, .LForward_ShiftRows
  36385. + .else
  36386. + inv_mix_cols_4x \in0, \in1, \in2, \in3
  36387. + ldr q13, .LReverse_ShiftRows
  36388. + .endif
  36389. + movi v12.16b, #0x40
  36390. + b 1111b
  36391. +2222: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */
  36392. + eor \in1\().16b, \in1\().16b, v15.16b /* ^round key */
  36393. + eor \in2\().16b, \in2\().16b, v15.16b /* ^round key */
  36394. + eor \in3\().16b, \in3\().16b, v15.16b /* ^round key */
  36395. + .endm
  36396. +
  36397. + .macro encrypt_block2x, in0, in1, rounds, rk, rkp, i
  36398. + do_block_2x 1, \in0, \in1, \rounds, \rk, \rkp, \i
  36399. + .endm
  36400. +
  36401. + .macro decrypt_block2x, in0, in1, rounds, rk, rkp, i
  36402. + do_block_2x 0, \in0, \in1, \rounds, \rk, \rkp, \i
  36403. + .endm
  36404. +
  36405. + .macro encrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
  36406. + do_block_4x 1, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
  36407. + .endm
  36408. +
  36409. + .macro decrypt_block4x, in0, in1, in2, in3, rounds, rk, rkp, i
  36410. + do_block_4x 0, \in0, \in1, \in2, \in3, \rounds, \rk, \rkp, \i
  36411. + .endm
  36412. +
  36413. +#include "aes-modes.S"
  36414. +
  36415. + .text
  36416. + .align 4
  36417. +.LForward_ShiftRows:
  36418. + .byte 0x0, 0x5, 0xa, 0xf, 0x4, 0x9, 0xe, 0x3
  36419. + .byte 0x8, 0xd, 0x2, 0x7, 0xc, 0x1, 0x6, 0xb
  36420. +
  36421. +.LReverse_ShiftRows:
  36422. + .byte 0x0, 0xd, 0xa, 0x7, 0x4, 0x1, 0xe, 0xb
  36423. + .byte 0x8, 0x5, 0x2, 0xf, 0xc, 0x9, 0x6, 0x3
  36424. +
  36425. +.LForward_Sbox:
  36426. + .byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
  36427. + .byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
  36428. + .byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
  36429. + .byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
  36430. + .byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
  36431. + .byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
  36432. + .byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
  36433. + .byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
  36434. + .byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
  36435. + .byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
  36436. + .byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
  36437. + .byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
  36438. + .byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
  36439. + .byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
  36440. + .byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
  36441. + .byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
  36442. + .byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
  36443. + .byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
  36444. + .byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
  36445. + .byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
  36446. + .byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
  36447. + .byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
  36448. + .byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
  36449. + .byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
  36450. + .byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
  36451. + .byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
  36452. + .byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
  36453. + .byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
  36454. + .byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
  36455. + .byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
  36456. + .byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
  36457. + .byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
  36458. +
  36459. +.LReverse_Sbox:
  36460. + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
  36461. + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
  36462. + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
  36463. + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
  36464. + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
  36465. + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
  36466. + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
  36467. + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
  36468. + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
  36469. + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
  36470. + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
  36471. + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
  36472. + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
  36473. + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
  36474. + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
  36475. + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
  36476. + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
  36477. + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
  36478. + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
  36479. + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
  36480. + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
  36481. + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
  36482. + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
  36483. + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
  36484. + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
  36485. + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
  36486. + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
  36487. + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
  36488. + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
  36489. + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
  36490. + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
  36491. + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
  36492. diff -Nur linux-3.14.17/arch/arm64/crypto/ghash-ce-core.S linux-imx6-3.14/arch/arm64/crypto/ghash-ce-core.S
  36493. --- linux-3.14.17/arch/arm64/crypto/ghash-ce-core.S 1970-01-01 01:00:00.000000000 +0100
  36494. +++ linux-imx6-3.14/arch/arm64/crypto/ghash-ce-core.S 2014-09-11 18:05:54.394007574 +0200
  36495. @@ -0,0 +1,79 @@
  36496. +/*
  36497. + * Accelerated GHASH implementation with ARMv8 PMULL instructions.
  36498. + *
  36499. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  36500. + *
  36501. + * This program is free software; you can redistribute it and/or modify it
  36502. + * under the terms of the GNU General Public License version 2 as published
  36503. + * by the Free Software Foundation.
  36504. + */
  36505. +
  36506. +#include <linux/linkage.h>
  36507. +#include <asm/assembler.h>
  36508. +
  36509. + SHASH .req v0
  36510. + SHASH2 .req v1
  36511. + T1 .req v2
  36512. + T2 .req v3
  36513. + MASK .req v4
  36514. + XL .req v5
  36515. + XM .req v6
  36516. + XH .req v7
  36517. + IN1 .req v7
  36518. +
  36519. + .text
  36520. + .arch armv8-a+crypto
  36521. +
  36522. + /*
  36523. + * void pmull_ghash_update(int blocks, u64 dg[], const char *src,
  36524. + * struct ghash_key const *k, const char *head)
  36525. + */
  36526. +ENTRY(pmull_ghash_update)
  36527. + ld1 {SHASH.16b}, [x3]
  36528. + ld1 {XL.16b}, [x1]
  36529. + movi MASK.16b, #0xe1
  36530. + ext SHASH2.16b, SHASH.16b, SHASH.16b, #8
  36531. + shl MASK.2d, MASK.2d, #57
  36532. + eor SHASH2.16b, SHASH2.16b, SHASH.16b
  36533. +
  36534. + /* do the head block first, if supplied */
  36535. + cbz x4, 0f
  36536. + ld1 {T1.2d}, [x4]
  36537. + b 1f
  36538. +
  36539. +0: ld1 {T1.2d}, [x2], #16
  36540. + sub w0, w0, #1
  36541. +
  36542. +1: /* multiply XL by SHASH in GF(2^128) */
  36543. +CPU_LE( rev64 T1.16b, T1.16b )
  36544. +
  36545. + ext T2.16b, XL.16b, XL.16b, #8
  36546. + ext IN1.16b, T1.16b, T1.16b, #8
  36547. + eor T1.16b, T1.16b, T2.16b
  36548. + eor XL.16b, XL.16b, IN1.16b
  36549. +
  36550. + pmull2 XH.1q, SHASH.2d, XL.2d // a1 * b1
  36551. + eor T1.16b, T1.16b, XL.16b
  36552. + pmull XL.1q, SHASH.1d, XL.1d // a0 * b0
  36553. + pmull XM.1q, SHASH2.1d, T1.1d // (a1 + a0)(b1 + b0)
  36554. +
  36555. + ext T1.16b, XL.16b, XH.16b, #8
  36556. + eor T2.16b, XL.16b, XH.16b
  36557. + eor XM.16b, XM.16b, T1.16b
  36558. + eor XM.16b, XM.16b, T2.16b
  36559. + pmull T2.1q, XL.1d, MASK.1d
  36560. +
  36561. + mov XH.d[0], XM.d[1]
  36562. + mov XM.d[1], XL.d[0]
  36563. +
  36564. + eor XL.16b, XM.16b, T2.16b
  36565. + ext T2.16b, XL.16b, XL.16b, #8
  36566. + pmull XL.1q, XL.1d, MASK.1d
  36567. + eor T2.16b, T2.16b, XH.16b
  36568. + eor XL.16b, XL.16b, T2.16b
  36569. +
  36570. + cbnz w0, 0b
  36571. +
  36572. + st1 {XL.16b}, [x1]
  36573. + ret
  36574. +ENDPROC(pmull_ghash_update)
  36575. diff -Nur linux-3.14.17/arch/arm64/crypto/ghash-ce-glue.c linux-imx6-3.14/arch/arm64/crypto/ghash-ce-glue.c
  36576. --- linux-3.14.17/arch/arm64/crypto/ghash-ce-glue.c 1970-01-01 01:00:00.000000000 +0100
  36577. +++ linux-imx6-3.14/arch/arm64/crypto/ghash-ce-glue.c 2014-09-11 18:05:54.394007574 +0200
  36578. @@ -0,0 +1,156 @@
  36579. +/*
  36580. + * Accelerated GHASH implementation with ARMv8 PMULL instructions.
  36581. + *
  36582. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  36583. + *
  36584. + * This program is free software; you can redistribute it and/or modify it
  36585. + * under the terms of the GNU General Public License version 2 as published
  36586. + * by the Free Software Foundation.
  36587. + */
  36588. +
  36589. +#include <asm/neon.h>
  36590. +#include <asm/unaligned.h>
  36591. +#include <crypto/internal/hash.h>
  36592. +#include <linux/cpufeature.h>
  36593. +#include <linux/crypto.h>
  36594. +#include <linux/module.h>
  36595. +
  36596. +MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions");
  36597. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  36598. +MODULE_LICENSE("GPL v2");
  36599. +
  36600. +#define GHASH_BLOCK_SIZE 16
  36601. +#define GHASH_DIGEST_SIZE 16
  36602. +
  36603. +struct ghash_key {
  36604. + u64 a;
  36605. + u64 b;
  36606. +};
  36607. +
  36608. +struct ghash_desc_ctx {
  36609. + u64 digest[GHASH_DIGEST_SIZE/sizeof(u64)];
  36610. + u8 buf[GHASH_BLOCK_SIZE];
  36611. + u32 count;
  36612. +};
  36613. +
  36614. +asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src,
  36615. + struct ghash_key const *k, const char *head);
  36616. +
  36617. +static int ghash_init(struct shash_desc *desc)
  36618. +{
  36619. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36620. +
  36621. + *ctx = (struct ghash_desc_ctx){};
  36622. + return 0;
  36623. +}
  36624. +
  36625. +static int ghash_update(struct shash_desc *desc, const u8 *src,
  36626. + unsigned int len)
  36627. +{
  36628. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36629. + unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
  36630. +
  36631. + ctx->count += len;
  36632. +
  36633. + if ((partial + len) >= GHASH_BLOCK_SIZE) {
  36634. + struct ghash_key *key = crypto_shash_ctx(desc->tfm);
  36635. + int blocks;
  36636. +
  36637. + if (partial) {
  36638. + int p = GHASH_BLOCK_SIZE - partial;
  36639. +
  36640. + memcpy(ctx->buf + partial, src, p);
  36641. + src += p;
  36642. + len -= p;
  36643. + }
  36644. +
  36645. + blocks = len / GHASH_BLOCK_SIZE;
  36646. + len %= GHASH_BLOCK_SIZE;
  36647. +
  36648. + kernel_neon_begin_partial(8);
  36649. + pmull_ghash_update(blocks, ctx->digest, src, key,
  36650. + partial ? ctx->buf : NULL);
  36651. + kernel_neon_end();
  36652. + src += blocks * GHASH_BLOCK_SIZE;
  36653. + partial = 0;
  36654. + }
  36655. + if (len)
  36656. + memcpy(ctx->buf + partial, src, len);
  36657. + return 0;
  36658. +}
  36659. +
  36660. +static int ghash_final(struct shash_desc *desc, u8 *dst)
  36661. +{
  36662. + struct ghash_desc_ctx *ctx = shash_desc_ctx(desc);
  36663. + unsigned int partial = ctx->count % GHASH_BLOCK_SIZE;
  36664. +
  36665. + if (partial) {
  36666. + struct ghash_key *key = crypto_shash_ctx(desc->tfm);
  36667. +
  36668. + memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial);
  36669. +
  36670. + kernel_neon_begin_partial(8);
  36671. + pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL);
  36672. + kernel_neon_end();
  36673. + }
  36674. + put_unaligned_be64(ctx->digest[1], dst);
  36675. + put_unaligned_be64(ctx->digest[0], dst + 8);
  36676. +
  36677. + *ctx = (struct ghash_desc_ctx){};
  36678. + return 0;
  36679. +}
  36680. +
  36681. +static int ghash_setkey(struct crypto_shash *tfm,
  36682. + const u8 *inkey, unsigned int keylen)
  36683. +{
  36684. + struct ghash_key *key = crypto_shash_ctx(tfm);
  36685. + u64 a, b;
  36686. +
  36687. + if (keylen != GHASH_BLOCK_SIZE) {
  36688. + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
  36689. + return -EINVAL;
  36690. + }
  36691. +
  36692. + /* perform multiplication by 'x' in GF(2^128) */
  36693. + b = get_unaligned_be64(inkey);
  36694. + a = get_unaligned_be64(inkey + 8);
  36695. +
  36696. + key->a = (a << 1) | (b >> 63);
  36697. + key->b = (b << 1) | (a >> 63);
  36698. +
  36699. + if (b >> 63)
  36700. + key->b ^= 0xc200000000000000UL;
  36701. +
  36702. + return 0;
  36703. +}
  36704. +
  36705. +static struct shash_alg ghash_alg = {
  36706. + .digestsize = GHASH_DIGEST_SIZE,
  36707. + .init = ghash_init,
  36708. + .update = ghash_update,
  36709. + .final = ghash_final,
  36710. + .setkey = ghash_setkey,
  36711. + .descsize = sizeof(struct ghash_desc_ctx),
  36712. + .base = {
  36713. + .cra_name = "ghash",
  36714. + .cra_driver_name = "ghash-ce",
  36715. + .cra_priority = 200,
  36716. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  36717. + .cra_blocksize = GHASH_BLOCK_SIZE,
  36718. + .cra_ctxsize = sizeof(struct ghash_key),
  36719. + .cra_module = THIS_MODULE,
  36720. + },
  36721. +};
  36722. +
  36723. +static int __init ghash_ce_mod_init(void)
  36724. +{
  36725. + return crypto_register_shash(&ghash_alg);
  36726. +}
  36727. +
  36728. +static void __exit ghash_ce_mod_exit(void)
  36729. +{
  36730. + crypto_unregister_shash(&ghash_alg);
  36731. +}
  36732. +
  36733. +module_cpu_feature_match(PMULL, ghash_ce_mod_init);
  36734. +module_exit(ghash_ce_mod_exit);
  36735. diff -Nur linux-3.14.17/arch/arm64/crypto/Kconfig linux-imx6-3.14/arch/arm64/crypto/Kconfig
  36736. --- linux-3.14.17/arch/arm64/crypto/Kconfig 1970-01-01 01:00:00.000000000 +0100
  36737. +++ linux-imx6-3.14/arch/arm64/crypto/Kconfig 2014-09-11 18:05:54.354007412 +0200
  36738. @@ -0,0 +1,53 @@
  36739. +
  36740. +menuconfig ARM64_CRYPTO
  36741. + bool "ARM64 Accelerated Cryptographic Algorithms"
  36742. + depends on ARM64
  36743. + help
  36744. + Say Y here to choose from a selection of cryptographic algorithms
  36745. + implemented using ARM64 specific CPU features or instructions.
  36746. +
  36747. +if ARM64_CRYPTO
  36748. +
  36749. +config CRYPTO_SHA1_ARM64_CE
  36750. + tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)"
  36751. + depends on ARM64 && KERNEL_MODE_NEON
  36752. + select CRYPTO_HASH
  36753. +
  36754. +config CRYPTO_SHA2_ARM64_CE
  36755. + tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)"
  36756. + depends on ARM64 && KERNEL_MODE_NEON
  36757. + select CRYPTO_HASH
  36758. +
  36759. +config CRYPTO_GHASH_ARM64_CE
  36760. + tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions"
  36761. + depends on ARM64 && KERNEL_MODE_NEON
  36762. + select CRYPTO_HASH
  36763. +
  36764. +config CRYPTO_AES_ARM64_CE
  36765. + tristate "AES core cipher using ARMv8 Crypto Extensions"
  36766. + depends on ARM64 && KERNEL_MODE_NEON
  36767. + select CRYPTO_ALGAPI
  36768. + select CRYPTO_AES
  36769. +
  36770. +config CRYPTO_AES_ARM64_CE_CCM
  36771. + tristate "AES in CCM mode using ARMv8 Crypto Extensions"
  36772. + depends on ARM64 && KERNEL_MODE_NEON
  36773. + select CRYPTO_ALGAPI
  36774. + select CRYPTO_AES
  36775. + select CRYPTO_AEAD
  36776. +
  36777. +config CRYPTO_AES_ARM64_CE_BLK
  36778. + tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions"
  36779. + depends on ARM64 && KERNEL_MODE_NEON
  36780. + select CRYPTO_BLKCIPHER
  36781. + select CRYPTO_AES
  36782. + select CRYPTO_ABLK_HELPER
  36783. +
  36784. +config CRYPTO_AES_ARM64_NEON_BLK
  36785. + tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions"
  36786. + depends on ARM64 && KERNEL_MODE_NEON
  36787. + select CRYPTO_BLKCIPHER
  36788. + select CRYPTO_AES
  36789. + select CRYPTO_ABLK_HELPER
  36790. +
  36791. +endif
  36792. diff -Nur linux-3.14.17/arch/arm64/crypto/Makefile linux-imx6-3.14/arch/arm64/crypto/Makefile
  36793. --- linux-3.14.17/arch/arm64/crypto/Makefile 1970-01-01 01:00:00.000000000 +0100
  36794. +++ linux-imx6-3.14/arch/arm64/crypto/Makefile 2014-09-11 18:05:54.354007412 +0200
  36795. @@ -0,0 +1,38 @@
  36796. +#
  36797. +# linux/arch/arm64/crypto/Makefile
  36798. +#
  36799. +# Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36800. +#
  36801. +# This program is free software; you can redistribute it and/or modify
  36802. +# it under the terms of the GNU General Public License version 2 as
  36803. +# published by the Free Software Foundation.
  36804. +#
  36805. +
  36806. +obj-$(CONFIG_CRYPTO_SHA1_ARM64_CE) += sha1-ce.o
  36807. +sha1-ce-y := sha1-ce-glue.o sha1-ce-core.o
  36808. +
  36809. +obj-$(CONFIG_CRYPTO_SHA2_ARM64_CE) += sha2-ce.o
  36810. +sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
  36811. +
  36812. +obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o
  36813. +ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
  36814. +
  36815. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o
  36816. +CFLAGS_aes-ce-cipher.o += -march=armv8-a+crypto
  36817. +
  36818. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE_CCM) += aes-ce-ccm.o
  36819. +aes-ce-ccm-y := aes-ce-ccm-glue.o aes-ce-ccm-core.o
  36820. +
  36821. +obj-$(CONFIG_CRYPTO_AES_ARM64_CE_BLK) += aes-ce-blk.o
  36822. +aes-ce-blk-y := aes-glue-ce.o aes-ce.o
  36823. +
  36824. +obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
  36825. +aes-neon-blk-y := aes-glue-neon.o aes-neon.o
  36826. +
  36827. +AFLAGS_aes-ce.o := -DINTERLEAVE=2 -DINTERLEAVE_INLINE
  36828. +AFLAGS_aes-neon.o := -DINTERLEAVE=4
  36829. +
  36830. +CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS
  36831. +
  36832. +$(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE
  36833. + $(call if_changed_dep,cc_o_c)
  36834. diff -Nur linux-3.14.17/arch/arm64/crypto/sha1-ce-core.S linux-imx6-3.14/arch/arm64/crypto/sha1-ce-core.S
  36835. --- linux-3.14.17/arch/arm64/crypto/sha1-ce-core.S 1970-01-01 01:00:00.000000000 +0100
  36836. +++ linux-imx6-3.14/arch/arm64/crypto/sha1-ce-core.S 2014-09-11 18:05:54.394007574 +0200
  36837. @@ -0,0 +1,153 @@
  36838. +/*
  36839. + * sha1-ce-core.S - SHA-1 secure hash using ARMv8 Crypto Extensions
  36840. + *
  36841. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36842. + *
  36843. + * This program is free software; you can redistribute it and/or modify
  36844. + * it under the terms of the GNU General Public License version 2 as
  36845. + * published by the Free Software Foundation.
  36846. + */
  36847. +
  36848. +#include <linux/linkage.h>
  36849. +#include <asm/assembler.h>
  36850. +
  36851. + .text
  36852. + .arch armv8-a+crypto
  36853. +
  36854. + k0 .req v0
  36855. + k1 .req v1
  36856. + k2 .req v2
  36857. + k3 .req v3
  36858. +
  36859. + t0 .req v4
  36860. + t1 .req v5
  36861. +
  36862. + dga .req q6
  36863. + dgav .req v6
  36864. + dgb .req s7
  36865. + dgbv .req v7
  36866. +
  36867. + dg0q .req q12
  36868. + dg0s .req s12
  36869. + dg0v .req v12
  36870. + dg1s .req s13
  36871. + dg1v .req v13
  36872. + dg2s .req s14
  36873. +
  36874. + .macro add_only, op, ev, rc, s0, dg1
  36875. + .ifc \ev, ev
  36876. + add t1.4s, v\s0\().4s, \rc\().4s
  36877. + sha1h dg2s, dg0s
  36878. + .ifnb \dg1
  36879. + sha1\op dg0q, \dg1, t0.4s
  36880. + .else
  36881. + sha1\op dg0q, dg1s, t0.4s
  36882. + .endif
  36883. + .else
  36884. + .ifnb \s0
  36885. + add t0.4s, v\s0\().4s, \rc\().4s
  36886. + .endif
  36887. + sha1h dg1s, dg0s
  36888. + sha1\op dg0q, dg2s, t1.4s
  36889. + .endif
  36890. + .endm
  36891. +
  36892. + .macro add_update, op, ev, rc, s0, s1, s2, s3, dg1
  36893. + sha1su0 v\s0\().4s, v\s1\().4s, v\s2\().4s
  36894. + add_only \op, \ev, \rc, \s1, \dg1
  36895. + sha1su1 v\s0\().4s, v\s3\().4s
  36896. + .endm
  36897. +
  36898. + /*
  36899. + * The SHA1 round constants
  36900. + */
  36901. + .align 4
  36902. +.Lsha1_rcon:
  36903. + .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
  36904. +
  36905. + /*
  36906. + * void sha1_ce_transform(int blocks, u8 const *src, u32 *state,
  36907. + * u8 *head, long bytes)
  36908. + */
  36909. +ENTRY(sha1_ce_transform)
  36910. + /* load round constants */
  36911. + adr x6, .Lsha1_rcon
  36912. + ld1r {k0.4s}, [x6], #4
  36913. + ld1r {k1.4s}, [x6], #4
  36914. + ld1r {k2.4s}, [x6], #4
  36915. + ld1r {k3.4s}, [x6]
  36916. +
  36917. + /* load state */
  36918. + ldr dga, [x2]
  36919. + ldr dgb, [x2, #16]
  36920. +
  36921. + /* load partial state (if supplied) */
  36922. + cbz x3, 0f
  36923. + ld1 {v8.4s-v11.4s}, [x3]
  36924. + b 1f
  36925. +
  36926. + /* load input */
  36927. +0: ld1 {v8.4s-v11.4s}, [x1], #64
  36928. + sub w0, w0, #1
  36929. +
  36930. +1:
  36931. +CPU_LE( rev32 v8.16b, v8.16b )
  36932. +CPU_LE( rev32 v9.16b, v9.16b )
  36933. +CPU_LE( rev32 v10.16b, v10.16b )
  36934. +CPU_LE( rev32 v11.16b, v11.16b )
  36935. +
  36936. +2: add t0.4s, v8.4s, k0.4s
  36937. + mov dg0v.16b, dgav.16b
  36938. +
  36939. + add_update c, ev, k0, 8, 9, 10, 11, dgb
  36940. + add_update c, od, k0, 9, 10, 11, 8
  36941. + add_update c, ev, k0, 10, 11, 8, 9
  36942. + add_update c, od, k0, 11, 8, 9, 10
  36943. + add_update c, ev, k1, 8, 9, 10, 11
  36944. +
  36945. + add_update p, od, k1, 9, 10, 11, 8
  36946. + add_update p, ev, k1, 10, 11, 8, 9
  36947. + add_update p, od, k1, 11, 8, 9, 10
  36948. + add_update p, ev, k1, 8, 9, 10, 11
  36949. + add_update p, od, k2, 9, 10, 11, 8
  36950. +
  36951. + add_update m, ev, k2, 10, 11, 8, 9
  36952. + add_update m, od, k2, 11, 8, 9, 10
  36953. + add_update m, ev, k2, 8, 9, 10, 11
  36954. + add_update m, od, k2, 9, 10, 11, 8
  36955. + add_update m, ev, k3, 10, 11, 8, 9
  36956. +
  36957. + add_update p, od, k3, 11, 8, 9, 10
  36958. + add_only p, ev, k3, 9
  36959. + add_only p, od, k3, 10
  36960. + add_only p, ev, k3, 11
  36961. + add_only p, od
  36962. +
  36963. + /* update state */
  36964. + add dgbv.2s, dgbv.2s, dg1v.2s
  36965. + add dgav.4s, dgav.4s, dg0v.4s
  36966. +
  36967. + cbnz w0, 0b
  36968. +
  36969. + /*
  36970. + * Final block: add padding and total bit count.
  36971. + * Skip if we have no total byte count in x4. In that case, the input
  36972. + * size was not a round multiple of the block size, and the padding is
  36973. + * handled by the C code.
  36974. + */
  36975. + cbz x4, 3f
  36976. + movi v9.2d, #0
  36977. + mov x8, #0x80000000
  36978. + movi v10.2d, #0
  36979. + ror x7, x4, #29 // ror(lsl(x4, 3), 32)
  36980. + fmov d8, x8
  36981. + mov x4, #0
  36982. + mov v11.d[0], xzr
  36983. + mov v11.d[1], x7
  36984. + b 2b
  36985. +
  36986. + /* store new state */
  36987. +3: str dga, [x2]
  36988. + str dgb, [x2, #16]
  36989. + ret
  36990. +ENDPROC(sha1_ce_transform)
  36991. diff -Nur linux-3.14.17/arch/arm64/crypto/sha1-ce-glue.c linux-imx6-3.14/arch/arm64/crypto/sha1-ce-glue.c
  36992. --- linux-3.14.17/arch/arm64/crypto/sha1-ce-glue.c 1970-01-01 01:00:00.000000000 +0100
  36993. +++ linux-imx6-3.14/arch/arm64/crypto/sha1-ce-glue.c 2014-09-11 18:05:54.394007574 +0200
  36994. @@ -0,0 +1,174 @@
  36995. +/*
  36996. + * sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions
  36997. + *
  36998. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  36999. + *
  37000. + * This program is free software; you can redistribute it and/or modify
  37001. + * it under the terms of the GNU General Public License version 2 as
  37002. + * published by the Free Software Foundation.
  37003. + */
  37004. +
  37005. +#include <asm/neon.h>
  37006. +#include <asm/unaligned.h>
  37007. +#include <crypto/internal/hash.h>
  37008. +#include <crypto/sha.h>
  37009. +#include <linux/cpufeature.h>
  37010. +#include <linux/crypto.h>
  37011. +#include <linux/module.h>
  37012. +
  37013. +MODULE_DESCRIPTION("SHA1 secure hash using ARMv8 Crypto Extensions");
  37014. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  37015. +MODULE_LICENSE("GPL v2");
  37016. +
  37017. +asmlinkage void sha1_ce_transform(int blocks, u8 const *src, u32 *state,
  37018. + u8 *head, long bytes);
  37019. +
  37020. +static int sha1_init(struct shash_desc *desc)
  37021. +{
  37022. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37023. +
  37024. + *sctx = (struct sha1_state){
  37025. + .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
  37026. + };
  37027. + return 0;
  37028. +}
  37029. +
  37030. +static int sha1_update(struct shash_desc *desc, const u8 *data,
  37031. + unsigned int len)
  37032. +{
  37033. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37034. + unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
  37035. +
  37036. + sctx->count += len;
  37037. +
  37038. + if ((partial + len) >= SHA1_BLOCK_SIZE) {
  37039. + int blocks;
  37040. +
  37041. + if (partial) {
  37042. + int p = SHA1_BLOCK_SIZE - partial;
  37043. +
  37044. + memcpy(sctx->buffer + partial, data, p);
  37045. + data += p;
  37046. + len -= p;
  37047. + }
  37048. +
  37049. + blocks = len / SHA1_BLOCK_SIZE;
  37050. + len %= SHA1_BLOCK_SIZE;
  37051. +
  37052. + kernel_neon_begin_partial(16);
  37053. + sha1_ce_transform(blocks, data, sctx->state,
  37054. + partial ? sctx->buffer : NULL, 0);
  37055. + kernel_neon_end();
  37056. +
  37057. + data += blocks * SHA1_BLOCK_SIZE;
  37058. + partial = 0;
  37059. + }
  37060. + if (len)
  37061. + memcpy(sctx->buffer + partial, data, len);
  37062. + return 0;
  37063. +}
  37064. +
  37065. +static int sha1_final(struct shash_desc *desc, u8 *out)
  37066. +{
  37067. + static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
  37068. +
  37069. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37070. + __be64 bits = cpu_to_be64(sctx->count << 3);
  37071. + __be32 *dst = (__be32 *)out;
  37072. + int i;
  37073. +
  37074. + u32 padlen = SHA1_BLOCK_SIZE
  37075. + - ((sctx->count + sizeof(bits)) % SHA1_BLOCK_SIZE);
  37076. +
  37077. + sha1_update(desc, padding, padlen);
  37078. + sha1_update(desc, (const u8 *)&bits, sizeof(bits));
  37079. +
  37080. + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
  37081. + put_unaligned_be32(sctx->state[i], dst++);
  37082. +
  37083. + *sctx = (struct sha1_state){};
  37084. + return 0;
  37085. +}
  37086. +
  37087. +static int sha1_finup(struct shash_desc *desc, const u8 *data,
  37088. + unsigned int len, u8 *out)
  37089. +{
  37090. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37091. + __be32 *dst = (__be32 *)out;
  37092. + int blocks;
  37093. + int i;
  37094. +
  37095. + if (sctx->count || !len || (len % SHA1_BLOCK_SIZE)) {
  37096. + sha1_update(desc, data, len);
  37097. + return sha1_final(desc, out);
  37098. + }
  37099. +
  37100. + /*
  37101. + * Use a fast path if the input is a multiple of 64 bytes. In
  37102. + * this case, there is no need to copy data around, and we can
  37103. + * perform the entire digest calculation in a single invocation
  37104. + * of sha1_ce_transform()
  37105. + */
  37106. + blocks = len / SHA1_BLOCK_SIZE;
  37107. +
  37108. + kernel_neon_begin_partial(16);
  37109. + sha1_ce_transform(blocks, data, sctx->state, NULL, len);
  37110. + kernel_neon_end();
  37111. +
  37112. + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
  37113. + put_unaligned_be32(sctx->state[i], dst++);
  37114. +
  37115. + *sctx = (struct sha1_state){};
  37116. + return 0;
  37117. +}
  37118. +
  37119. +static int sha1_export(struct shash_desc *desc, void *out)
  37120. +{
  37121. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37122. + struct sha1_state *dst = out;
  37123. +
  37124. + *dst = *sctx;
  37125. + return 0;
  37126. +}
  37127. +
  37128. +static int sha1_import(struct shash_desc *desc, const void *in)
  37129. +{
  37130. + struct sha1_state *sctx = shash_desc_ctx(desc);
  37131. + struct sha1_state const *src = in;
  37132. +
  37133. + *sctx = *src;
  37134. + return 0;
  37135. +}
  37136. +
  37137. +static struct shash_alg alg = {
  37138. + .init = sha1_init,
  37139. + .update = sha1_update,
  37140. + .final = sha1_final,
  37141. + .finup = sha1_finup,
  37142. + .export = sha1_export,
  37143. + .import = sha1_import,
  37144. + .descsize = sizeof(struct sha1_state),
  37145. + .digestsize = SHA1_DIGEST_SIZE,
  37146. + .statesize = sizeof(struct sha1_state),
  37147. + .base = {
  37148. + .cra_name = "sha1",
  37149. + .cra_driver_name = "sha1-ce",
  37150. + .cra_priority = 200,
  37151. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37152. + .cra_blocksize = SHA1_BLOCK_SIZE,
  37153. + .cra_module = THIS_MODULE,
  37154. + }
  37155. +};
  37156. +
  37157. +static int __init sha1_ce_mod_init(void)
  37158. +{
  37159. + return crypto_register_shash(&alg);
  37160. +}
  37161. +
  37162. +static void __exit sha1_ce_mod_fini(void)
  37163. +{
  37164. + crypto_unregister_shash(&alg);
  37165. +}
  37166. +
  37167. +module_cpu_feature_match(SHA1, sha1_ce_mod_init);
  37168. +module_exit(sha1_ce_mod_fini);
  37169. diff -Nur linux-3.14.17/arch/arm64/crypto/sha2-ce-core.S linux-imx6-3.14/arch/arm64/crypto/sha2-ce-core.S
  37170. --- linux-3.14.17/arch/arm64/crypto/sha2-ce-core.S 1970-01-01 01:00:00.000000000 +0100
  37171. +++ linux-imx6-3.14/arch/arm64/crypto/sha2-ce-core.S 2014-09-11 18:05:54.394007574 +0200
  37172. @@ -0,0 +1,156 @@
  37173. +/*
  37174. + * sha2-ce-core.S - core SHA-224/SHA-256 transform using v8 Crypto Extensions
  37175. + *
  37176. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  37177. + *
  37178. + * This program is free software; you can redistribute it and/or modify
  37179. + * it under the terms of the GNU General Public License version 2 as
  37180. + * published by the Free Software Foundation.
  37181. + */
  37182. +
  37183. +#include <linux/linkage.h>
  37184. +#include <asm/assembler.h>
  37185. +
  37186. + .text
  37187. + .arch armv8-a+crypto
  37188. +
  37189. + dga .req q20
  37190. + dgav .req v20
  37191. + dgb .req q21
  37192. + dgbv .req v21
  37193. +
  37194. + t0 .req v22
  37195. + t1 .req v23
  37196. +
  37197. + dg0q .req q24
  37198. + dg0v .req v24
  37199. + dg1q .req q25
  37200. + dg1v .req v25
  37201. + dg2q .req q26
  37202. + dg2v .req v26
  37203. +
  37204. + .macro add_only, ev, rc, s0
  37205. + mov dg2v.16b, dg0v.16b
  37206. + .ifeq \ev
  37207. + add t1.4s, v\s0\().4s, \rc\().4s
  37208. + sha256h dg0q, dg1q, t0.4s
  37209. + sha256h2 dg1q, dg2q, t0.4s
  37210. + .else
  37211. + .ifnb \s0
  37212. + add t0.4s, v\s0\().4s, \rc\().4s
  37213. + .endif
  37214. + sha256h dg0q, dg1q, t1.4s
  37215. + sha256h2 dg1q, dg2q, t1.4s
  37216. + .endif
  37217. + .endm
  37218. +
  37219. + .macro add_update, ev, rc, s0, s1, s2, s3
  37220. + sha256su0 v\s0\().4s, v\s1\().4s
  37221. + add_only \ev, \rc, \s1
  37222. + sha256su1 v\s0\().4s, v\s2\().4s, v\s3\().4s
  37223. + .endm
  37224. +
  37225. + /*
  37226. + * The SHA-256 round constants
  37227. + */
  37228. + .align 4
  37229. +.Lsha2_rcon:
  37230. + .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
  37231. + .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
  37232. + .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
  37233. + .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
  37234. + .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
  37235. + .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
  37236. + .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
  37237. + .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
  37238. + .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
  37239. + .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
  37240. + .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
  37241. + .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
  37242. + .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
  37243. + .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
  37244. + .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
  37245. + .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  37246. +
  37247. + /*
  37248. + * void sha2_ce_transform(int blocks, u8 const *src, u32 *state,
  37249. + * u8 *head, long bytes)
  37250. + */
  37251. +ENTRY(sha2_ce_transform)
  37252. + /* load round constants */
  37253. + adr x8, .Lsha2_rcon
  37254. + ld1 { v0.4s- v3.4s}, [x8], #64
  37255. + ld1 { v4.4s- v7.4s}, [x8], #64
  37256. + ld1 { v8.4s-v11.4s}, [x8], #64
  37257. + ld1 {v12.4s-v15.4s}, [x8]
  37258. +
  37259. + /* load state */
  37260. + ldp dga, dgb, [x2]
  37261. +
  37262. + /* load partial input (if supplied) */
  37263. + cbz x3, 0f
  37264. + ld1 {v16.4s-v19.4s}, [x3]
  37265. + b 1f
  37266. +
  37267. + /* load input */
  37268. +0: ld1 {v16.4s-v19.4s}, [x1], #64
  37269. + sub w0, w0, #1
  37270. +
  37271. +1:
  37272. +CPU_LE( rev32 v16.16b, v16.16b )
  37273. +CPU_LE( rev32 v17.16b, v17.16b )
  37274. +CPU_LE( rev32 v18.16b, v18.16b )
  37275. +CPU_LE( rev32 v19.16b, v19.16b )
  37276. +
  37277. +2: add t0.4s, v16.4s, v0.4s
  37278. + mov dg0v.16b, dgav.16b
  37279. + mov dg1v.16b, dgbv.16b
  37280. +
  37281. + add_update 0, v1, 16, 17, 18, 19
  37282. + add_update 1, v2, 17, 18, 19, 16
  37283. + add_update 0, v3, 18, 19, 16, 17
  37284. + add_update 1, v4, 19, 16, 17, 18
  37285. +
  37286. + add_update 0, v5, 16, 17, 18, 19
  37287. + add_update 1, v6, 17, 18, 19, 16
  37288. + add_update 0, v7, 18, 19, 16, 17
  37289. + add_update 1, v8, 19, 16, 17, 18
  37290. +
  37291. + add_update 0, v9, 16, 17, 18, 19
  37292. + add_update 1, v10, 17, 18, 19, 16
  37293. + add_update 0, v11, 18, 19, 16, 17
  37294. + add_update 1, v12, 19, 16, 17, 18
  37295. +
  37296. + add_only 0, v13, 17
  37297. + add_only 1, v14, 18
  37298. + add_only 0, v15, 19
  37299. + add_only 1
  37300. +
  37301. + /* update state */
  37302. + add dgav.4s, dgav.4s, dg0v.4s
  37303. + add dgbv.4s, dgbv.4s, dg1v.4s
  37304. +
  37305. + /* handled all input blocks? */
  37306. + cbnz w0, 0b
  37307. +
  37308. + /*
  37309. + * Final block: add padding and total bit count.
  37310. + * Skip if we have no total byte count in x4. In that case, the input
  37311. + * size was not a round multiple of the block size, and the padding is
  37312. + * handled by the C code.
  37313. + */
  37314. + cbz x4, 3f
  37315. + movi v17.2d, #0
  37316. + mov x8, #0x80000000
  37317. + movi v18.2d, #0
  37318. + ror x7, x4, #29 // ror(lsl(x4, 3), 32)
  37319. + fmov d16, x8
  37320. + mov x4, #0
  37321. + mov v19.d[0], xzr
  37322. + mov v19.d[1], x7
  37323. + b 2b
  37324. +
  37325. + /* store new state */
  37326. +3: stp dga, dgb, [x2]
  37327. + ret
  37328. +ENDPROC(sha2_ce_transform)
  37329. diff -Nur linux-3.14.17/arch/arm64/crypto/sha2-ce-glue.c linux-imx6-3.14/arch/arm64/crypto/sha2-ce-glue.c
  37330. --- linux-3.14.17/arch/arm64/crypto/sha2-ce-glue.c 1970-01-01 01:00:00.000000000 +0100
  37331. +++ linux-imx6-3.14/arch/arm64/crypto/sha2-ce-glue.c 2014-09-11 18:05:54.394007574 +0200
  37332. @@ -0,0 +1,255 @@
  37333. +/*
  37334. + * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions
  37335. + *
  37336. + * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
  37337. + *
  37338. + * This program is free software; you can redistribute it and/or modify
  37339. + * it under the terms of the GNU General Public License version 2 as
  37340. + * published by the Free Software Foundation.
  37341. + */
  37342. +
  37343. +#include <asm/neon.h>
  37344. +#include <asm/unaligned.h>
  37345. +#include <crypto/internal/hash.h>
  37346. +#include <crypto/sha.h>
  37347. +#include <linux/cpufeature.h>
  37348. +#include <linux/crypto.h>
  37349. +#include <linux/module.h>
  37350. +
  37351. +MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions");
  37352. +MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
  37353. +MODULE_LICENSE("GPL v2");
  37354. +
  37355. +asmlinkage int sha2_ce_transform(int blocks, u8 const *src, u32 *state,
  37356. + u8 *head, long bytes);
  37357. +
  37358. +static int sha224_init(struct shash_desc *desc)
  37359. +{
  37360. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37361. +
  37362. + *sctx = (struct sha256_state){
  37363. + .state = {
  37364. + SHA224_H0, SHA224_H1, SHA224_H2, SHA224_H3,
  37365. + SHA224_H4, SHA224_H5, SHA224_H6, SHA224_H7,
  37366. + }
  37367. + };
  37368. + return 0;
  37369. +}
  37370. +
  37371. +static int sha256_init(struct shash_desc *desc)
  37372. +{
  37373. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37374. +
  37375. + *sctx = (struct sha256_state){
  37376. + .state = {
  37377. + SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
  37378. + SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7,
  37379. + }
  37380. + };
  37381. + return 0;
  37382. +}
  37383. +
  37384. +static int sha2_update(struct shash_desc *desc, const u8 *data,
  37385. + unsigned int len)
  37386. +{
  37387. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37388. + unsigned int partial = sctx->count % SHA256_BLOCK_SIZE;
  37389. +
  37390. + sctx->count += len;
  37391. +
  37392. + if ((partial + len) >= SHA256_BLOCK_SIZE) {
  37393. + int blocks;
  37394. +
  37395. + if (partial) {
  37396. + int p = SHA256_BLOCK_SIZE - partial;
  37397. +
  37398. + memcpy(sctx->buf + partial, data, p);
  37399. + data += p;
  37400. + len -= p;
  37401. + }
  37402. +
  37403. + blocks = len / SHA256_BLOCK_SIZE;
  37404. + len %= SHA256_BLOCK_SIZE;
  37405. +
  37406. + kernel_neon_begin_partial(28);
  37407. + sha2_ce_transform(blocks, data, sctx->state,
  37408. + partial ? sctx->buf : NULL, 0);
  37409. + kernel_neon_end();
  37410. +
  37411. + data += blocks * SHA256_BLOCK_SIZE;
  37412. + partial = 0;
  37413. + }
  37414. + if (len)
  37415. + memcpy(sctx->buf + partial, data, len);
  37416. + return 0;
  37417. +}
  37418. +
  37419. +static void sha2_final(struct shash_desc *desc)
  37420. +{
  37421. + static const u8 padding[SHA256_BLOCK_SIZE] = { 0x80, };
  37422. +
  37423. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37424. + __be64 bits = cpu_to_be64(sctx->count << 3);
  37425. + u32 padlen = SHA256_BLOCK_SIZE
  37426. + - ((sctx->count + sizeof(bits)) % SHA256_BLOCK_SIZE);
  37427. +
  37428. + sha2_update(desc, padding, padlen);
  37429. + sha2_update(desc, (const u8 *)&bits, sizeof(bits));
  37430. +}
  37431. +
  37432. +static int sha224_final(struct shash_desc *desc, u8 *out)
  37433. +{
  37434. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37435. + __be32 *dst = (__be32 *)out;
  37436. + int i;
  37437. +
  37438. + sha2_final(desc);
  37439. +
  37440. + for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(__be32); i++)
  37441. + put_unaligned_be32(sctx->state[i], dst++);
  37442. +
  37443. + *sctx = (struct sha256_state){};
  37444. + return 0;
  37445. +}
  37446. +
  37447. +static int sha256_final(struct shash_desc *desc, u8 *out)
  37448. +{
  37449. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37450. + __be32 *dst = (__be32 *)out;
  37451. + int i;
  37452. +
  37453. + sha2_final(desc);
  37454. +
  37455. + for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(__be32); i++)
  37456. + put_unaligned_be32(sctx->state[i], dst++);
  37457. +
  37458. + *sctx = (struct sha256_state){};
  37459. + return 0;
  37460. +}
  37461. +
  37462. +static void sha2_finup(struct shash_desc *desc, const u8 *data,
  37463. + unsigned int len)
  37464. +{
  37465. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37466. + int blocks;
  37467. +
  37468. + if (sctx->count || !len || (len % SHA256_BLOCK_SIZE)) {
  37469. + sha2_update(desc, data, len);
  37470. + sha2_final(desc);
  37471. + return;
  37472. + }
  37473. +
  37474. + /*
  37475. + * Use a fast path if the input is a multiple of 64 bytes. In
  37476. + * this case, there is no need to copy data around, and we can
  37477. + * perform the entire digest calculation in a single invocation
  37478. + * of sha2_ce_transform()
  37479. + */
  37480. + blocks = len / SHA256_BLOCK_SIZE;
  37481. +
  37482. + kernel_neon_begin_partial(28);
  37483. + sha2_ce_transform(blocks, data, sctx->state, NULL, len);
  37484. + kernel_neon_end();
  37485. + data += blocks * SHA256_BLOCK_SIZE;
  37486. +}
  37487. +
  37488. +static int sha224_finup(struct shash_desc *desc, const u8 *data,
  37489. + unsigned int len, u8 *out)
  37490. +{
  37491. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37492. + __be32 *dst = (__be32 *)out;
  37493. + int i;
  37494. +
  37495. + sha2_finup(desc, data, len);
  37496. +
  37497. + for (i = 0; i < SHA224_DIGEST_SIZE / sizeof(__be32); i++)
  37498. + put_unaligned_be32(sctx->state[i], dst++);
  37499. +
  37500. + *sctx = (struct sha256_state){};
  37501. + return 0;
  37502. +}
  37503. +
  37504. +static int sha256_finup(struct shash_desc *desc, const u8 *data,
  37505. + unsigned int len, u8 *out)
  37506. +{
  37507. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37508. + __be32 *dst = (__be32 *)out;
  37509. + int i;
  37510. +
  37511. + sha2_finup(desc, data, len);
  37512. +
  37513. + for (i = 0; i < SHA256_DIGEST_SIZE / sizeof(__be32); i++)
  37514. + put_unaligned_be32(sctx->state[i], dst++);
  37515. +
  37516. + *sctx = (struct sha256_state){};
  37517. + return 0;
  37518. +}
  37519. +
  37520. +static int sha2_export(struct shash_desc *desc, void *out)
  37521. +{
  37522. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37523. + struct sha256_state *dst = out;
  37524. +
  37525. + *dst = *sctx;
  37526. + return 0;
  37527. +}
  37528. +
  37529. +static int sha2_import(struct shash_desc *desc, const void *in)
  37530. +{
  37531. + struct sha256_state *sctx = shash_desc_ctx(desc);
  37532. + struct sha256_state const *src = in;
  37533. +
  37534. + *sctx = *src;
  37535. + return 0;
  37536. +}
  37537. +
  37538. +static struct shash_alg algs[] = { {
  37539. + .init = sha224_init,
  37540. + .update = sha2_update,
  37541. + .final = sha224_final,
  37542. + .finup = sha224_finup,
  37543. + .export = sha2_export,
  37544. + .import = sha2_import,
  37545. + .descsize = sizeof(struct sha256_state),
  37546. + .digestsize = SHA224_DIGEST_SIZE,
  37547. + .statesize = sizeof(struct sha256_state),
  37548. + .base = {
  37549. + .cra_name = "sha224",
  37550. + .cra_driver_name = "sha224-ce",
  37551. + .cra_priority = 200,
  37552. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37553. + .cra_blocksize = SHA256_BLOCK_SIZE,
  37554. + .cra_module = THIS_MODULE,
  37555. + }
  37556. +}, {
  37557. + .init = sha256_init,
  37558. + .update = sha2_update,
  37559. + .final = sha256_final,
  37560. + .finup = sha256_finup,
  37561. + .export = sha2_export,
  37562. + .import = sha2_import,
  37563. + .descsize = sizeof(struct sha256_state),
  37564. + .digestsize = SHA256_DIGEST_SIZE,
  37565. + .statesize = sizeof(struct sha256_state),
  37566. + .base = {
  37567. + .cra_name = "sha256",
  37568. + .cra_driver_name = "sha256-ce",
  37569. + .cra_priority = 200,
  37570. + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  37571. + .cra_blocksize = SHA256_BLOCK_SIZE,
  37572. + .cra_module = THIS_MODULE,
  37573. + }
  37574. +} };
  37575. +
  37576. +static int __init sha2_ce_mod_init(void)
  37577. +{
  37578. + return crypto_register_shashes(algs, ARRAY_SIZE(algs));
  37579. +}
  37580. +
  37581. +static void __exit sha2_ce_mod_fini(void)
  37582. +{
  37583. + crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
  37584. +}
  37585. +
  37586. +module_cpu_feature_match(SHA2, sha2_ce_mod_init);
  37587. +module_exit(sha2_ce_mod_fini);
  37588. diff -Nur linux-3.14.17/arch/arm64/include/asm/bL_switcher.h linux-imx6-3.14/arch/arm64/include/asm/bL_switcher.h
  37589. --- linux-3.14.17/arch/arm64/include/asm/bL_switcher.h 1970-01-01 01:00:00.000000000 +0100
  37590. +++ linux-imx6-3.14/arch/arm64/include/asm/bL_switcher.h 2014-09-11 18:05:54.398007590 +0200
  37591. @@ -0,0 +1,54 @@
  37592. +/*
  37593. + * Based on the stubs for the ARM implementation which is:
  37594. + *
  37595. + * Created by: Nicolas Pitre, April 2012
  37596. + * Copyright: (C) 2012-2013 Linaro Limited
  37597. + *
  37598. + * This program is free software; you can redistribute it and/or modify
  37599. + * it under the terms of the GNU General Public License version 2 as
  37600. + * published by the Free Software Foundation.
  37601. + */
  37602. +
  37603. +#ifndef ASM_BL_SWITCHER_H
  37604. +#define ASM_BL_SWITCHER_H
  37605. +
  37606. +#include <linux/notifier.h>
  37607. +#include <linux/types.h>
  37608. +
  37609. +typedef void (*bL_switch_completion_handler)(void *cookie);
  37610. +
  37611. +static inline int bL_switch_request(unsigned int cpu,
  37612. + unsigned int new_cluster_id)
  37613. +{
  37614. + return -ENOTSUPP;
  37615. +}
  37616. +
  37617. +/*
  37618. + * Register here to be notified about runtime enabling/disabling of
  37619. + * the switcher.
  37620. + *
  37621. + * The notifier chain is called with the switcher activation lock held:
  37622. + * the switcher will not be enabled or disabled during callbacks.
  37623. + * Callbacks must not call bL_switcher_{get,put}_enabled().
  37624. + */
  37625. +#define BL_NOTIFY_PRE_ENABLE 0
  37626. +#define BL_NOTIFY_POST_ENABLE 1
  37627. +#define BL_NOTIFY_PRE_DISABLE 2
  37628. +#define BL_NOTIFY_POST_DISABLE 3
  37629. +
  37630. +static inline int bL_switcher_register_notifier(struct notifier_block *nb)
  37631. +{
  37632. + return 0;
  37633. +}
  37634. +
  37635. +static inline int bL_switcher_unregister_notifier(struct notifier_block *nb)
  37636. +{
  37637. + return 0;
  37638. +}
  37639. +
  37640. +static inline bool bL_switcher_get_enabled(void) { return false; }
  37641. +static inline void bL_switcher_put_enabled(void) { }
  37642. +static inline int bL_switcher_trace_trigger(void) { return 0; }
  37643. +static inline int bL_switcher_get_logical_index(u32 mpidr) { return -EUNATCH; }
  37644. +
  37645. +#endif
  37646. diff -Nur linux-3.14.17/arch/arm64/include/asm/cacheflush.h linux-imx6-3.14/arch/arm64/include/asm/cacheflush.h
  37647. --- linux-3.14.17/arch/arm64/include/asm/cacheflush.h 2014-08-14 03:38:34.000000000 +0200
  37648. +++ linux-imx6-3.14/arch/arm64/include/asm/cacheflush.h 2014-09-11 18:05:54.398007590 +0200
  37649. @@ -85,6 +85,13 @@
  37650. }
  37651. /*
  37652. + * Cache maintenance functions used by the DMA API. No to be used directly.
  37653. + */
  37654. +extern void __dma_map_area(const void *, size_t, int);
  37655. +extern void __dma_unmap_area(const void *, size_t, int);
  37656. +extern void __dma_flush_range(const void *, const void *);
  37657. +
  37658. +/*
  37659. * Copy user data from/to a page which is mapped into a different
  37660. * processes address space. Really, we want to allow our "user
  37661. * space" model to handle this.
  37662. diff -Nur linux-3.14.17/arch/arm64/include/asm/compat.h linux-imx6-3.14/arch/arm64/include/asm/compat.h
  37663. --- linux-3.14.17/arch/arm64/include/asm/compat.h 2014-08-14 03:38:34.000000000 +0200
  37664. +++ linux-imx6-3.14/arch/arm64/include/asm/compat.h 2014-09-11 18:05:54.398007590 +0200
  37665. @@ -228,7 +228,7 @@
  37666. return (u32)(unsigned long)uptr;
  37667. }
  37668. -#define compat_user_stack_pointer() (current_pt_regs()->compat_sp)
  37669. +#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs()))
  37670. static inline void __user *arch_compat_alloc_user_space(long len)
  37671. {
  37672. @@ -305,11 +305,6 @@
  37673. #else /* !CONFIG_COMPAT */
  37674. -static inline int is_compat_task(void)
  37675. -{
  37676. - return 0;
  37677. -}
  37678. -
  37679. static inline int is_compat_thread(struct thread_info *thread)
  37680. {
  37681. return 0;
  37682. diff -Nur linux-3.14.17/arch/arm64/include/asm/cpufeature.h linux-imx6-3.14/arch/arm64/include/asm/cpufeature.h
  37683. --- linux-3.14.17/arch/arm64/include/asm/cpufeature.h 1970-01-01 01:00:00.000000000 +0100
  37684. +++ linux-imx6-3.14/arch/arm64/include/asm/cpufeature.h 2014-09-11 18:05:54.398007590 +0200
  37685. @@ -0,0 +1,29 @@
  37686. +/*
  37687. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  37688. + *
  37689. + * This program is free software; you can redistribute it and/or modify
  37690. + * it under the terms of the GNU General Public License version 2 as
  37691. + * published by the Free Software Foundation.
  37692. + */
  37693. +
  37694. +#ifndef __ASM_CPUFEATURE_H
  37695. +#define __ASM_CPUFEATURE_H
  37696. +
  37697. +#include <asm/hwcap.h>
  37698. +
  37699. +/*
  37700. + * In the arm64 world (as in the ARM world), elf_hwcap is used both internally
  37701. + * in the kernel and for user space to keep track of which optional features
  37702. + * are supported by the current system. So let's map feature 'x' to HWCAP_x.
  37703. + * Note that HWCAP_x constants are bit fields so we need to take the log.
  37704. + */
  37705. +
  37706. +#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap))
  37707. +#define cpu_feature(x) ilog2(HWCAP_ ## x)
  37708. +
  37709. +static inline bool cpu_have_feature(unsigned int num)
  37710. +{
  37711. + return elf_hwcap & (1UL << num);
  37712. +}
  37713. +
  37714. +#endif
  37715. diff -Nur linux-3.14.17/arch/arm64/include/asm/debug-monitors.h linux-imx6-3.14/arch/arm64/include/asm/debug-monitors.h
  37716. --- linux-3.14.17/arch/arm64/include/asm/debug-monitors.h 2014-08-14 03:38:34.000000000 +0200
  37717. +++ linux-imx6-3.14/arch/arm64/include/asm/debug-monitors.h 2014-09-11 18:05:54.398007590 +0200
  37718. @@ -26,6 +26,53 @@
  37719. #define DBG_ESR_EVT_HWWP 0x2
  37720. #define DBG_ESR_EVT_BRK 0x6
  37721. +/*
  37722. + * Break point instruction encoding
  37723. + */
  37724. +#define BREAK_INSTR_SIZE 4
  37725. +
  37726. +/*
  37727. + * ESR values expected for dynamic and compile time BRK instruction
  37728. + */
  37729. +#define DBG_ESR_VAL_BRK(x) (0xf2000000 | ((x) & 0xfffff))
  37730. +
  37731. +/*
  37732. + * #imm16 values used for BRK instruction generation
  37733. + * Allowed values for kgbd are 0x400 - 0x7ff
  37734. + * 0x400: for dynamic BRK instruction
  37735. + * 0x401: for compile time BRK instruction
  37736. + */
  37737. +#define KGDB_DYN_DGB_BRK_IMM 0x400
  37738. +#define KDBG_COMPILED_DBG_BRK_IMM 0x401
  37739. +
  37740. +/*
  37741. + * BRK instruction encoding
  37742. + * The #imm16 value should be placed at bits[20:5] within BRK ins
  37743. + */
  37744. +#define AARCH64_BREAK_MON 0xd4200000
  37745. +
  37746. +/*
  37747. + * Extract byte from BRK instruction
  37748. + */
  37749. +#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \
  37750. + ((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff)
  37751. +
  37752. +/*
  37753. + * Extract byte from BRK #imm16
  37754. + */
  37755. +#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \
  37756. + (((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff)
  37757. +
  37758. +#define KGDB_DYN_DGB_BRK_BYTE(x) \
  37759. + (KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x))
  37760. +
  37761. +#define KGDB_DYN_BRK_INS_BYTE0 KGDB_DYN_DGB_BRK_BYTE(0)
  37762. +#define KGDB_DYN_BRK_INS_BYTE1 KGDB_DYN_DGB_BRK_BYTE(1)
  37763. +#define KGDB_DYN_BRK_INS_BYTE2 KGDB_DYN_DGB_BRK_BYTE(2)
  37764. +#define KGDB_DYN_BRK_INS_BYTE3 KGDB_DYN_DGB_BRK_BYTE(3)
  37765. +
  37766. +#define CACHE_FLUSH_IS_SAFE 1
  37767. +
  37768. enum debug_el {
  37769. DBG_ACTIVE_EL0 = 0,
  37770. DBG_ACTIVE_EL1,
  37771. @@ -43,23 +90,6 @@
  37772. #ifndef __ASSEMBLY__
  37773. struct task_struct;
  37774. -#define local_dbg_save(flags) \
  37775. - do { \
  37776. - typecheck(unsigned long, flags); \
  37777. - asm volatile( \
  37778. - "mrs %0, daif // local_dbg_save\n" \
  37779. - "msr daifset, #8" \
  37780. - : "=r" (flags) : : "memory"); \
  37781. - } while (0)
  37782. -
  37783. -#define local_dbg_restore(flags) \
  37784. - do { \
  37785. - typecheck(unsigned long, flags); \
  37786. - asm volatile( \
  37787. - "msr daif, %0 // local_dbg_restore\n" \
  37788. - : : "r" (flags) : "memory"); \
  37789. - } while (0)
  37790. -
  37791. #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
  37792. #define DBG_HOOK_HANDLED 0
  37793. diff -Nur linux-3.14.17/arch/arm64/include/asm/dma-mapping.h linux-imx6-3.14/arch/arm64/include/asm/dma-mapping.h
  37794. --- linux-3.14.17/arch/arm64/include/asm/dma-mapping.h 2014-08-14 03:38:34.000000000 +0200
  37795. +++ linux-imx6-3.14/arch/arm64/include/asm/dma-mapping.h 2014-09-11 18:05:54.398007590 +0200
  37796. @@ -28,6 +28,8 @@
  37797. #define DMA_ERROR_CODE (~(dma_addr_t)0)
  37798. extern struct dma_map_ops *dma_ops;
  37799. +extern struct dma_map_ops coherent_swiotlb_dma_ops;
  37800. +extern struct dma_map_ops noncoherent_swiotlb_dma_ops;
  37801. static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
  37802. {
  37803. @@ -45,6 +47,11 @@
  37804. return __generic_dma_ops(dev);
  37805. }
  37806. +static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
  37807. +{
  37808. + dev->archdata.dma_ops = ops;
  37809. +}
  37810. +
  37811. #include <asm-generic/dma-mapping-common.h>
  37812. static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
  37813. diff -Nur linux-3.14.17/arch/arm64/include/asm/ftrace.h linux-imx6-3.14/arch/arm64/include/asm/ftrace.h
  37814. --- linux-3.14.17/arch/arm64/include/asm/ftrace.h 1970-01-01 01:00:00.000000000 +0100
  37815. +++ linux-imx6-3.14/arch/arm64/include/asm/ftrace.h 2014-09-11 18:05:54.402007605 +0200
  37816. @@ -0,0 +1,59 @@
  37817. +/*
  37818. + * arch/arm64/include/asm/ftrace.h
  37819. + *
  37820. + * Copyright (C) 2013 Linaro Limited
  37821. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  37822. + *
  37823. + * This program is free software; you can redistribute it and/or modify
  37824. + * it under the terms of the GNU General Public License version 2 as
  37825. + * published by the Free Software Foundation.
  37826. + */
  37827. +#ifndef __ASM_FTRACE_H
  37828. +#define __ASM_FTRACE_H
  37829. +
  37830. +#include <asm/insn.h>
  37831. +
  37832. +#define MCOUNT_ADDR ((unsigned long)_mcount)
  37833. +#define MCOUNT_INSN_SIZE AARCH64_INSN_SIZE
  37834. +
  37835. +#ifndef __ASSEMBLY__
  37836. +#include <linux/compat.h>
  37837. +
  37838. +extern void _mcount(unsigned long);
  37839. +extern void *return_address(unsigned int);
  37840. +
  37841. +struct dyn_arch_ftrace {
  37842. + /* No extra data needed for arm64 */
  37843. +};
  37844. +
  37845. +extern unsigned long ftrace_graph_call;
  37846. +
  37847. +static inline unsigned long ftrace_call_adjust(unsigned long addr)
  37848. +{
  37849. + /*
  37850. + * addr is the address of the mcount call instruction.
  37851. + * recordmcount does the necessary offset calculation.
  37852. + */
  37853. + return addr;
  37854. +}
  37855. +
  37856. +#define ftrace_return_address(n) return_address(n)
  37857. +
  37858. +/*
  37859. + * Because AArch32 mode does not share the same syscall table with AArch64,
  37860. + * tracing compat syscalls may result in reporting bogus syscalls or even
  37861. + * hang-up, so just do not trace them.
  37862. + * See kernel/trace/trace_syscalls.c
  37863. + *
  37864. + * x86 code says:
  37865. + * If the user realy wants these, then they should use the
  37866. + * raw syscall tracepoints with filtering.
  37867. + */
  37868. +#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
  37869. +static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
  37870. +{
  37871. + return is_compat_task();
  37872. +}
  37873. +#endif /* ifndef __ASSEMBLY__ */
  37874. +
  37875. +#endif /* __ASM_FTRACE_H */
  37876. diff -Nur linux-3.14.17/arch/arm64/include/asm/hwcap.h linux-imx6-3.14/arch/arm64/include/asm/hwcap.h
  37877. --- linux-3.14.17/arch/arm64/include/asm/hwcap.h 2014-08-14 03:38:34.000000000 +0200
  37878. +++ linux-imx6-3.14/arch/arm64/include/asm/hwcap.h 2014-09-11 18:05:54.402007605 +0200
  37879. @@ -32,6 +32,12 @@
  37880. #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT)
  37881. #define COMPAT_HWCAP_EVTSTRM (1 << 21)
  37882. +#define COMPAT_HWCAP2_AES (1 << 0)
  37883. +#define COMPAT_HWCAP2_PMULL (1 << 1)
  37884. +#define COMPAT_HWCAP2_SHA1 (1 << 2)
  37885. +#define COMPAT_HWCAP2_SHA2 (1 << 3)
  37886. +#define COMPAT_HWCAP2_CRC32 (1 << 4)
  37887. +
  37888. #ifndef __ASSEMBLY__
  37889. /*
  37890. * This yields a mask that user programs can use to figure out what
  37891. @@ -41,7 +47,8 @@
  37892. #ifdef CONFIG_COMPAT
  37893. #define COMPAT_ELF_HWCAP (compat_elf_hwcap)
  37894. -extern unsigned int compat_elf_hwcap;
  37895. +#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2)
  37896. +extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
  37897. #endif
  37898. extern unsigned long elf_hwcap;
  37899. diff -Nur linux-3.14.17/arch/arm64/include/asm/insn.h linux-imx6-3.14/arch/arm64/include/asm/insn.h
  37900. --- linux-3.14.17/arch/arm64/include/asm/insn.h 2014-08-14 03:38:34.000000000 +0200
  37901. +++ linux-imx6-3.14/arch/arm64/include/asm/insn.h 2014-09-11 18:05:54.402007605 +0200
  37902. @@ -16,11 +16,14 @@
  37903. */
  37904. #ifndef __ASM_INSN_H
  37905. #define __ASM_INSN_H
  37906. +
  37907. #include <linux/types.h>
  37908. /* A64 instructions are always 32 bits. */
  37909. #define AARCH64_INSN_SIZE 4
  37910. +#ifndef __ASSEMBLY__
  37911. +
  37912. /*
  37913. * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
  37914. * Section C3.1 "A64 instruction index by encoding":
  37915. @@ -105,4 +108,6 @@
  37916. int aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt);
  37917. int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
  37918. +#endif /* __ASSEMBLY__ */
  37919. +
  37920. #endif /* __ASM_INSN_H */
  37921. diff -Nur linux-3.14.17/arch/arm64/include/asm/irqflags.h linux-imx6-3.14/arch/arm64/include/asm/irqflags.h
  37922. --- linux-3.14.17/arch/arm64/include/asm/irqflags.h 2014-08-14 03:38:34.000000000 +0200
  37923. +++ linux-imx6-3.14/arch/arm64/include/asm/irqflags.h 2014-09-11 18:05:54.402007605 +0200
  37924. @@ -90,5 +90,28 @@
  37925. return flags & PSR_I_BIT;
  37926. }
  37927. +/*
  37928. + * save and restore debug state
  37929. + */
  37930. +#define local_dbg_save(flags) \
  37931. + do { \
  37932. + typecheck(unsigned long, flags); \
  37933. + asm volatile( \
  37934. + "mrs %0, daif // local_dbg_save\n" \
  37935. + "msr daifset, #8" \
  37936. + : "=r" (flags) : : "memory"); \
  37937. + } while (0)
  37938. +
  37939. +#define local_dbg_restore(flags) \
  37940. + do { \
  37941. + typecheck(unsigned long, flags); \
  37942. + asm volatile( \
  37943. + "msr daif, %0 // local_dbg_restore\n" \
  37944. + : : "r" (flags) : "memory"); \
  37945. + } while (0)
  37946. +
  37947. +#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory")
  37948. +#define local_dbg_disable() asm("msr daifset, #8" : : : "memory")
  37949. +
  37950. #endif
  37951. #endif
  37952. diff -Nur linux-3.14.17/arch/arm64/include/asm/Kbuild linux-imx6-3.14/arch/arm64/include/asm/Kbuild
  37953. --- linux-3.14.17/arch/arm64/include/asm/Kbuild 2014-08-14 03:38:34.000000000 +0200
  37954. +++ linux-imx6-3.14/arch/arm64/include/asm/Kbuild 2014-09-11 18:05:54.394007574 +0200
  37955. @@ -35,6 +35,7 @@
  37956. generic-y += sembuf.h
  37957. generic-y += serial.h
  37958. generic-y += shmbuf.h
  37959. +generic-y += simd.h
  37960. generic-y += sizes.h
  37961. generic-y += socket.h
  37962. generic-y += sockios.h
  37963. diff -Nur linux-3.14.17/arch/arm64/include/asm/kgdb.h linux-imx6-3.14/arch/arm64/include/asm/kgdb.h
  37964. --- linux-3.14.17/arch/arm64/include/asm/kgdb.h 1970-01-01 01:00:00.000000000 +0100
  37965. +++ linux-imx6-3.14/arch/arm64/include/asm/kgdb.h 2014-09-11 18:05:54.402007605 +0200
  37966. @@ -0,0 +1,84 @@
  37967. +/*
  37968. + * AArch64 KGDB support
  37969. + *
  37970. + * Based on arch/arm/include/kgdb.h
  37971. + *
  37972. + * Copyright (C) 2013 Cavium Inc.
  37973. + * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
  37974. + *
  37975. + * This program is free software; you can redistribute it and/or modify
  37976. + * it under the terms of the GNU General Public License version 2 as
  37977. + * published by the Free Software Foundation.
  37978. + *
  37979. + * This program is distributed in the hope that it will be useful,
  37980. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37981. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  37982. + * GNU General Public License for more details.
  37983. + *
  37984. + * You should have received a copy of the GNU General Public License
  37985. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  37986. + */
  37987. +
  37988. +#ifndef __ARM_KGDB_H
  37989. +#define __ARM_KGDB_H
  37990. +
  37991. +#include <linux/ptrace.h>
  37992. +#include <asm/debug-monitors.h>
  37993. +
  37994. +#ifndef __ASSEMBLY__
  37995. +
  37996. +static inline void arch_kgdb_breakpoint(void)
  37997. +{
  37998. + asm ("brk %0" : : "I" (KDBG_COMPILED_DBG_BRK_IMM));
  37999. +}
  38000. +
  38001. +extern void kgdb_handle_bus_error(void);
  38002. +extern int kgdb_fault_expected;
  38003. +
  38004. +#endif /* !__ASSEMBLY__ */
  38005. +
  38006. +/*
  38007. + * gdb is expecting the following registers layout.
  38008. + *
  38009. + * General purpose regs:
  38010. + * r0-r30: 64 bit
  38011. + * sp,pc : 64 bit
  38012. + * pstate : 64 bit
  38013. + * Total: 34
  38014. + * FPU regs:
  38015. + * f0-f31: 128 bit
  38016. + * Total: 32
  38017. + * Extra regs
  38018. + * fpsr & fpcr: 32 bit
  38019. + * Total: 2
  38020. + *
  38021. + */
  38022. +
  38023. +#define _GP_REGS 34
  38024. +#define _FP_REGS 32
  38025. +#define _EXTRA_REGS 2
  38026. +/*
  38027. + * general purpose registers size in bytes.
  38028. + * pstate is only 4 bytes. subtract 4 bytes
  38029. + */
  38030. +#define GP_REG_BYTES (_GP_REGS * 8)
  38031. +#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
  38032. +
  38033. +/*
  38034. + * Size of I/O buffer for gdb packet.
  38035. + * considering to hold all register contents, size is set
  38036. + */
  38037. +
  38038. +#define BUFMAX 2048
  38039. +
  38040. +/*
  38041. + * Number of bytes required for gdb_regs buffer.
  38042. + * _GP_REGS: 8 bytes, _FP_REGS: 16 bytes and _EXTRA_REGS: 4 bytes each
  38043. + * GDB fails to connect for size beyond this with error
  38044. + * "'g' packet reply is too long"
  38045. + */
  38046. +
  38047. +#define NUMREGBYTES ((_GP_REGS * 8) + (_FP_REGS * 16) + \
  38048. + (_EXTRA_REGS * 4))
  38049. +
  38050. +#endif /* __ASM_KGDB_H */
  38051. diff -Nur linux-3.14.17/arch/arm64/include/asm/page.h linux-imx6-3.14/arch/arm64/include/asm/page.h
  38052. --- linux-3.14.17/arch/arm64/include/asm/page.h 2014-08-14 03:38:34.000000000 +0200
  38053. +++ linux-imx6-3.14/arch/arm64/include/asm/page.h 2014-09-11 18:05:54.402007605 +0200
  38054. @@ -31,6 +31,15 @@
  38055. /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
  38056. #define __HAVE_ARCH_GATE_AREA 1
  38057. +/*
  38058. + * The idmap and swapper page tables need some space reserved in the kernel
  38059. + * image. The idmap only requires a pgd and a next level table to (section) map
  38060. + * the kernel, while the swapper also maps the FDT and requires an additional
  38061. + * table to map an early UART. See __create_page_tables for more information.
  38062. + */
  38063. +#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  38064. +#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  38065. +
  38066. #ifndef __ASSEMBLY__
  38067. #ifdef CONFIG_ARM64_64K_PAGES
  38068. diff -Nur linux-3.14.17/arch/arm64/include/asm/pgtable.h linux-imx6-3.14/arch/arm64/include/asm/pgtable.h
  38069. --- linux-3.14.17/arch/arm64/include/asm/pgtable.h 2014-08-14 03:38:34.000000000 +0200
  38070. +++ linux-imx6-3.14/arch/arm64/include/asm/pgtable.h 2014-09-11 18:05:54.446007779 +0200
  38071. @@ -227,36 +227,36 @@
  38072. #define __HAVE_ARCH_PTE_SPECIAL
  38073. -/*
  38074. - * Software PMD bits for THP
  38075. - */
  38076. +static inline pte_t pmd_pte(pmd_t pmd)
  38077. +{
  38078. + return __pte(pmd_val(pmd));
  38079. +}
  38080. -#define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
  38081. -#define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 57)
  38082. +static inline pmd_t pte_pmd(pte_t pte)
  38083. +{
  38084. + return __pmd(pte_val(pte));
  38085. +}
  38086. /*
  38087. * THP definitions.
  38088. */
  38089. -#define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF)
  38090. -
  38091. -#define __HAVE_ARCH_PMD_WRITE
  38092. -#define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY))
  38093. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  38094. #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
  38095. -#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
  38096. +#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
  38097. #endif
  38098. -#define PMD_BIT_FUNC(fn,op) \
  38099. -static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
  38100. +#define pmd_young(pmd) pte_young(pmd_pte(pmd))
  38101. +#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
  38102. +#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
  38103. +#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
  38104. +#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
  38105. +#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
  38106. +#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
  38107. +#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) &= ~PMD_TYPE_MASK))
  38108. -PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY);
  38109. -PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
  38110. -PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
  38111. -PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY);
  38112. -PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY);
  38113. -PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
  38114. -PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
  38115. +#define __HAVE_ARCH_PMD_WRITE
  38116. +#define pmd_write(pmd) pte_write(pmd_pte(pmd))
  38117. #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
  38118. @@ -266,16 +266,7 @@
  38119. #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
  38120. -static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
  38121. -{
  38122. - const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
  38123. - PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
  38124. - PMD_SECT_VALID;
  38125. - pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
  38126. - return pmd;
  38127. -}
  38128. -
  38129. -#define set_pmd_at(mm, addr, pmdp, pmd) set_pmd(pmdp, pmd)
  38130. +#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
  38131. static inline int has_transparent_hugepage(void)
  38132. {
  38133. @@ -383,12 +374,14 @@
  38134. return pte;
  38135. }
  38136. +static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
  38137. +{
  38138. + return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
  38139. +}
  38140. +
  38141. extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  38142. extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
  38143. -#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  38144. -#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  38145. -
  38146. /*
  38147. * Encode and decode a swap entry:
  38148. * bits 0-1: present (must be zero)
  38149. diff -Nur linux-3.14.17/arch/arm64/include/asm/ptrace.h linux-imx6-3.14/arch/arm64/include/asm/ptrace.h
  38150. --- linux-3.14.17/arch/arm64/include/asm/ptrace.h 2014-08-14 03:38:34.000000000 +0200
  38151. +++ linux-imx6-3.14/arch/arm64/include/asm/ptrace.h 2014-09-11 18:05:54.446007779 +0200
  38152. @@ -68,6 +68,7 @@
  38153. /* Architecturally defined mapping between AArch32 and AArch64 registers */
  38154. #define compat_usr(x) regs[(x)]
  38155. +#define compat_fp regs[11]
  38156. #define compat_sp regs[13]
  38157. #define compat_lr regs[14]
  38158. #define compat_sp_hyp regs[15]
  38159. @@ -132,7 +133,12 @@
  38160. (!((regs)->pstate & PSR_F_BIT))
  38161. #define user_stack_pointer(regs) \
  38162. - ((regs)->sp)
  38163. + (!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp)
  38164. +
  38165. +static inline unsigned long regs_return_value(struct pt_regs *regs)
  38166. +{
  38167. + return regs->regs[0];
  38168. +}
  38169. /*
  38170. * Are the current registers suitable for user mode? (used to maintain
  38171. @@ -164,7 +170,7 @@
  38172. return 0;
  38173. }
  38174. -#define instruction_pointer(regs) (regs)->pc
  38175. +#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
  38176. #ifdef CONFIG_SMP
  38177. extern unsigned long profile_pc(struct pt_regs *regs);
  38178. diff -Nur linux-3.14.17/arch/arm64/include/asm/syscall.h linux-imx6-3.14/arch/arm64/include/asm/syscall.h
  38179. --- linux-3.14.17/arch/arm64/include/asm/syscall.h 2014-08-14 03:38:34.000000000 +0200
  38180. +++ linux-imx6-3.14/arch/arm64/include/asm/syscall.h 2014-09-11 18:05:54.450007796 +0200
  38181. @@ -18,6 +18,7 @@
  38182. #include <linux/err.h>
  38183. +extern const void *sys_call_table[];
  38184. static inline int syscall_get_nr(struct task_struct *task,
  38185. struct pt_regs *regs)
  38186. diff -Nur linux-3.14.17/arch/arm64/include/asm/thread_info.h linux-imx6-3.14/arch/arm64/include/asm/thread_info.h
  38187. --- linux-3.14.17/arch/arm64/include/asm/thread_info.h 2014-08-14 03:38:34.000000000 +0200
  38188. +++ linux-imx6-3.14/arch/arm64/include/asm/thread_info.h 2014-09-11 18:05:54.450007796 +0200
  38189. @@ -91,6 +91,9 @@
  38190. /*
  38191. * thread information flags:
  38192. * TIF_SYSCALL_TRACE - syscall trace active
  38193. + * TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
  38194. + * TIF_SYSCALL_AUDIT - syscall auditing
  38195. + * TIF_SECOMP - syscall secure computing
  38196. * TIF_SIGPENDING - signal pending
  38197. * TIF_NEED_RESCHED - rescheduling necessary
  38198. * TIF_NOTIFY_RESUME - callback before returning to user
  38199. @@ -101,6 +104,9 @@
  38200. #define TIF_NEED_RESCHED 1
  38201. #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
  38202. #define TIF_SYSCALL_TRACE 8
  38203. +#define TIF_SYSCALL_AUDIT 9
  38204. +#define TIF_SYSCALL_TRACEPOINT 10
  38205. +#define TIF_SECCOMP 11
  38206. #define TIF_POLLING_NRFLAG 16
  38207. #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
  38208. #define TIF_FREEZE 19
  38209. @@ -112,10 +118,17 @@
  38210. #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
  38211. #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
  38212. #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
  38213. +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
  38214. +#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
  38215. +#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
  38216. +#define _TIF_SECCOMP (1 << TIF_SECCOMP)
  38217. #define _TIF_32BIT (1 << TIF_32BIT)
  38218. #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
  38219. _TIF_NOTIFY_RESUME)
  38220. +#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
  38221. + _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
  38222. +
  38223. #endif /* __KERNEL__ */
  38224. #endif /* __ASM_THREAD_INFO_H */
  38225. diff -Nur linux-3.14.17/arch/arm64/include/asm/topology.h linux-imx6-3.14/arch/arm64/include/asm/topology.h
  38226. --- linux-3.14.17/arch/arm64/include/asm/topology.h 1970-01-01 01:00:00.000000000 +0100
  38227. +++ linux-imx6-3.14/arch/arm64/include/asm/topology.h 2014-09-11 18:05:54.450007796 +0200
  38228. @@ -0,0 +1,70 @@
  38229. +#ifndef __ASM_TOPOLOGY_H
  38230. +#define __ASM_TOPOLOGY_H
  38231. +
  38232. +#ifdef CONFIG_SMP
  38233. +
  38234. +#include <linux/cpumask.h>
  38235. +
  38236. +struct cpu_topology {
  38237. + int thread_id;
  38238. + int core_id;
  38239. + int cluster_id;
  38240. + cpumask_t thread_sibling;
  38241. + cpumask_t core_sibling;
  38242. +};
  38243. +
  38244. +extern struct cpu_topology cpu_topology[NR_CPUS];
  38245. +
  38246. +#define topology_physical_package_id(cpu) (cpu_topology[cpu].cluster_id)
  38247. +#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
  38248. +#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
  38249. +#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
  38250. +
  38251. +#define mc_capable() (cpu_topology[0].cluster_id != -1)
  38252. +#define smt_capable() (cpu_topology[0].thread_id != -1)
  38253. +
  38254. +void init_cpu_topology(void);
  38255. +void store_cpu_topology(unsigned int cpuid);
  38256. +const struct cpumask *cpu_coregroup_mask(int cpu);
  38257. +
  38258. +#ifdef CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE
  38259. +/* Common values for CPUs */
  38260. +#ifndef SD_CPU_INIT
  38261. +#define SD_CPU_INIT (struct sched_domain) { \
  38262. + .min_interval = 1, \
  38263. + .max_interval = 4, \
  38264. + .busy_factor = 64, \
  38265. + .imbalance_pct = 125, \
  38266. + .cache_nice_tries = 1, \
  38267. + .busy_idx = 2, \
  38268. + .idle_idx = 1, \
  38269. + .newidle_idx = 0, \
  38270. + .wake_idx = 0, \
  38271. + .forkexec_idx = 0, \
  38272. + \
  38273. + .flags = 0*SD_LOAD_BALANCE \
  38274. + | 1*SD_BALANCE_NEWIDLE \
  38275. + | 1*SD_BALANCE_EXEC \
  38276. + | 1*SD_BALANCE_FORK \
  38277. + | 0*SD_BALANCE_WAKE \
  38278. + | 1*SD_WAKE_AFFINE \
  38279. + | 0*SD_SHARE_CPUPOWER \
  38280. + | 0*SD_SHARE_PKG_RESOURCES \
  38281. + | 0*SD_SERIALIZE \
  38282. + , \
  38283. + .last_balance = jiffies, \
  38284. + .balance_interval = 1, \
  38285. +}
  38286. +#endif
  38287. +#endif /* CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE */
  38288. +
  38289. +#else
  38290. +
  38291. +static inline void init_cpu_topology(void) { }
  38292. +static inline void store_cpu_topology(unsigned int cpuid) { }
  38293. +
  38294. +#endif
  38295. +
  38296. +#include <asm-generic/topology.h>
  38297. +
  38298. +#endif /* _ASM_ARM_TOPOLOGY_H */
  38299. diff -Nur linux-3.14.17/arch/arm64/include/asm/unistd.h linux-imx6-3.14/arch/arm64/include/asm/unistd.h
  38300. --- linux-3.14.17/arch/arm64/include/asm/unistd.h 2014-08-14 03:38:34.000000000 +0200
  38301. +++ linux-imx6-3.14/arch/arm64/include/asm/unistd.h 2014-09-11 18:05:54.450007796 +0200
  38302. @@ -28,3 +28,5 @@
  38303. #endif
  38304. #define __ARCH_WANT_SYS_CLONE
  38305. #include <uapi/asm/unistd.h>
  38306. +
  38307. +#define NR_syscalls (__NR_syscalls)
  38308. diff -Nur linux-3.14.17/arch/arm64/include/uapi/asm/Kbuild linux-imx6-3.14/arch/arm64/include/uapi/asm/Kbuild
  38309. --- linux-3.14.17/arch/arm64/include/uapi/asm/Kbuild 2014-08-14 03:38:34.000000000 +0200
  38310. +++ linux-imx6-3.14/arch/arm64/include/uapi/asm/Kbuild 2014-09-11 18:05:54.458007828 +0200
  38311. @@ -9,6 +9,7 @@
  38312. header-y += fcntl.h
  38313. header-y += hwcap.h
  38314. header-y += kvm_para.h
  38315. +header-y += perf_regs.h
  38316. header-y += param.h
  38317. header-y += ptrace.h
  38318. header-y += setup.h
  38319. diff -Nur linux-3.14.17/arch/arm64/include/uapi/asm/perf_regs.h linux-imx6-3.14/arch/arm64/include/uapi/asm/perf_regs.h
  38320. --- linux-3.14.17/arch/arm64/include/uapi/asm/perf_regs.h 1970-01-01 01:00:00.000000000 +0100
  38321. +++ linux-imx6-3.14/arch/arm64/include/uapi/asm/perf_regs.h 2014-09-11 18:05:54.458007828 +0200
  38322. @@ -0,0 +1,40 @@
  38323. +#ifndef _ASM_ARM64_PERF_REGS_H
  38324. +#define _ASM_ARM64_PERF_REGS_H
  38325. +
  38326. +enum perf_event_arm_regs {
  38327. + PERF_REG_ARM64_X0,
  38328. + PERF_REG_ARM64_X1,
  38329. + PERF_REG_ARM64_X2,
  38330. + PERF_REG_ARM64_X3,
  38331. + PERF_REG_ARM64_X4,
  38332. + PERF_REG_ARM64_X5,
  38333. + PERF_REG_ARM64_X6,
  38334. + PERF_REG_ARM64_X7,
  38335. + PERF_REG_ARM64_X8,
  38336. + PERF_REG_ARM64_X9,
  38337. + PERF_REG_ARM64_X10,
  38338. + PERF_REG_ARM64_X11,
  38339. + PERF_REG_ARM64_X12,
  38340. + PERF_REG_ARM64_X13,
  38341. + PERF_REG_ARM64_X14,
  38342. + PERF_REG_ARM64_X15,
  38343. + PERF_REG_ARM64_X16,
  38344. + PERF_REG_ARM64_X17,
  38345. + PERF_REG_ARM64_X18,
  38346. + PERF_REG_ARM64_X19,
  38347. + PERF_REG_ARM64_X20,
  38348. + PERF_REG_ARM64_X21,
  38349. + PERF_REG_ARM64_X22,
  38350. + PERF_REG_ARM64_X23,
  38351. + PERF_REG_ARM64_X24,
  38352. + PERF_REG_ARM64_X25,
  38353. + PERF_REG_ARM64_X26,
  38354. + PERF_REG_ARM64_X27,
  38355. + PERF_REG_ARM64_X28,
  38356. + PERF_REG_ARM64_X29,
  38357. + PERF_REG_ARM64_LR,
  38358. + PERF_REG_ARM64_SP,
  38359. + PERF_REG_ARM64_PC,
  38360. + PERF_REG_ARM64_MAX,
  38361. +};
  38362. +#endif /* _ASM_ARM64_PERF_REGS_H */
  38363. diff -Nur linux-3.14.17/arch/arm64/Kconfig linux-imx6-3.14/arch/arm64/Kconfig
  38364. --- linux-3.14.17/arch/arm64/Kconfig 2014-08-14 03:38:34.000000000 +0200
  38365. +++ linux-imx6-3.14/arch/arm64/Kconfig 2014-09-11 18:05:54.354007412 +0200
  38366. @@ -4,6 +4,7 @@
  38367. select ARCH_USE_CMPXCHG_LOCKREF
  38368. select ARCH_SUPPORTS_ATOMIC_RMW
  38369. select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
  38370. + select ARCH_HAS_OPP
  38371. select ARCH_WANT_OPTIONAL_GPIOLIB
  38372. select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
  38373. select ARCH_WANT_FRAME_POINTERS
  38374. @@ -17,6 +18,7 @@
  38375. select DCACHE_WORD_ACCESS
  38376. select GENERIC_CLOCKEVENTS
  38377. select GENERIC_CLOCKEVENTS_BROADCAST if SMP
  38378. + select GENERIC_CPU_AUTOPROBE
  38379. select GENERIC_IOMAP
  38380. select GENERIC_IRQ_PROBE
  38381. select GENERIC_IRQ_SHOW
  38382. @@ -27,18 +29,27 @@
  38383. select GENERIC_TIME_VSYSCALL
  38384. select HARDIRQS_SW_RESEND
  38385. select HAVE_ARCH_JUMP_LABEL
  38386. + select HAVE_ARCH_KGDB
  38387. select HAVE_ARCH_TRACEHOOK
  38388. + select HAVE_C_RECORDMCOUNT
  38389. select HAVE_DEBUG_BUGVERBOSE
  38390. select HAVE_DEBUG_KMEMLEAK
  38391. select HAVE_DMA_API_DEBUG
  38392. select HAVE_DMA_ATTRS
  38393. select HAVE_DMA_CONTIGUOUS
  38394. select HAVE_EFFICIENT_UNALIGNED_ACCESS
  38395. + select HAVE_DYNAMIC_FTRACE
  38396. + select HAVE_FTRACE_MCOUNT_RECORD
  38397. + select HAVE_FUNCTION_TRACER
  38398. + select HAVE_FUNCTION_GRAPH_TRACER
  38399. select HAVE_GENERIC_DMA_COHERENT
  38400. select HAVE_HW_BREAKPOINT if PERF_EVENTS
  38401. select HAVE_MEMBLOCK
  38402. select HAVE_PATA_PLATFORM
  38403. select HAVE_PERF_EVENTS
  38404. + select HAVE_PERF_REGS
  38405. + select HAVE_PERF_USER_STACK_DUMP
  38406. + select HAVE_SYSCALL_TRACEPOINTS
  38407. select IRQ_DOMAIN
  38408. select MODULES_USE_ELF_RELA
  38409. select NO_BOOTMEM
  38410. @@ -86,7 +97,7 @@
  38411. config GENERIC_CALIBRATE_DELAY
  38412. def_bool y
  38413. -config ZONE_DMA32
  38414. +config ZONE_DMA
  38415. def_bool y
  38416. config ARCH_DMA_ADDR_T_64BIT
  38417. @@ -165,6 +176,134 @@
  38418. If you don't know what to do here, say N.
  38419. +config SCHED_MC
  38420. + bool "Multi-core scheduler support"
  38421. + depends on SMP
  38422. + help
  38423. + Multi-core scheduler support improves the CPU scheduler's decision
  38424. + making when dealing with multi-core CPU chips at a cost of slightly
  38425. + increased overhead in some places. If unsure say N here.
  38426. +
  38427. +config SCHED_SMT
  38428. + bool "SMT scheduler support"
  38429. + depends on SMP
  38430. + help
  38431. + Improves the CPU scheduler's decision making when dealing with
  38432. + MultiThreading at a cost of slightly increased overhead in some
  38433. + places. If unsure say N here.
  38434. +
  38435. +config SCHED_MC
  38436. + bool "Multi-core scheduler support"
  38437. + depends on ARM_CPU_TOPOLOGY
  38438. + help
  38439. + Multi-core scheduler support improves the CPU scheduler's decision
  38440. + making when dealing with multi-core CPU chips at a cost of slightly
  38441. + increased overhead in some places. If unsure say N here.
  38442. +
  38443. +config SCHED_SMT
  38444. + bool "SMT scheduler support"
  38445. + depends on ARM_CPU_TOPOLOGY
  38446. + help
  38447. + Improves the CPU scheduler's decision making when dealing with
  38448. + MultiThreading at a cost of slightly increased overhead in some
  38449. + places. If unsure say N here.
  38450. +
  38451. +config DISABLE_CPU_SCHED_DOMAIN_BALANCE
  38452. + bool "(EXPERIMENTAL) Disable CPU level scheduler load-balancing"
  38453. + help
  38454. + Disables scheduler load-balancing at CPU sched domain level.
  38455. +
  38456. +config SCHED_HMP
  38457. + bool "(EXPERIMENTAL) Heterogenous multiprocessor scheduling"
  38458. + depends on DISABLE_CPU_SCHED_DOMAIN_BALANCE && SCHED_MC && FAIR_GROUP_SCHED && !SCHED_AUTOGROUP
  38459. + help
  38460. + Experimental scheduler optimizations for heterogeneous platforms.
  38461. + Attempts to introspectively select task affinity to optimize power
  38462. + and performance. Basic support for multiple (>2) cpu types is in place,
  38463. + but it has only been tested with two types of cpus.
  38464. + There is currently no support for migration of task groups, hence
  38465. + !SCHED_AUTOGROUP. Furthermore, normal load-balancing must be disabled
  38466. + between cpus of different type (DISABLE_CPU_SCHED_DOMAIN_BALANCE).
  38467. +
  38468. +config SCHED_HMP_PRIO_FILTER
  38469. + bool "(EXPERIMENTAL) Filter HMP migrations by task priority"
  38470. + depends on SCHED_HMP
  38471. + help
  38472. + Enables task priority based HMP migration filter. Any task with
  38473. + a NICE value above the threshold will always be on low-power cpus
  38474. + with less compute capacity.
  38475. +
  38476. +config SCHED_HMP_PRIO_FILTER_VAL
  38477. + int "NICE priority threshold"
  38478. + default 5
  38479. + depends on SCHED_HMP_PRIO_FILTER
  38480. +
  38481. +config HMP_FAST_CPU_MASK
  38482. + string "HMP scheduler fast CPU mask"
  38483. + depends on SCHED_HMP
  38484. + help
  38485. + Leave empty to use device tree information.
  38486. + Specify the cpuids of the fast CPUs in the system as a list string,
  38487. + e.g. cpuid 0+1 should be specified as 0-1.
  38488. +
  38489. +config HMP_SLOW_CPU_MASK
  38490. + string "HMP scheduler slow CPU mask"
  38491. + depends on SCHED_HMP
  38492. + help
  38493. + Leave empty to use device tree information.
  38494. + Specify the cpuids of the slow CPUs in the system as a list string,
  38495. + e.g. cpuid 0+1 should be specified as 0-1.
  38496. +
  38497. +config HMP_VARIABLE_SCALE
  38498. + bool "Allows changing the load tracking scale through sysfs"
  38499. + depends on SCHED_HMP
  38500. + help
  38501. + When turned on, this option exports the thresholds and load average
  38502. + period value for the load tracking patches through sysfs.
  38503. + The values can be modified to change the rate of load accumulation
  38504. + and the thresholds used for HMP migration.
  38505. + The load_avg_period_ms is the time in ms to reach a load average of
  38506. + 0.5 for an idle task of 0 load average ratio that start a busy loop.
  38507. + The up_threshold and down_threshold is the value to go to a faster
  38508. + CPU or to go back to a slower cpu.
  38509. + The {up,down}_threshold are devided by 1024 before being compared
  38510. + to the load average.
  38511. + For examples, with load_avg_period_ms = 128 and up_threshold = 512,
  38512. + a running task with a load of 0 will be migrated to a bigger CPU after
  38513. + 128ms, because after 128ms its load_avg_ratio is 0.5 and the real
  38514. + up_threshold is 0.5.
  38515. + This patch has the same behavior as changing the Y of the load
  38516. + average computation to
  38517. + (1002/1024)^(LOAD_AVG_PERIOD/load_avg_period_ms)
  38518. + but it remove intermadiate overflows in computation.
  38519. +
  38520. +config HMP_FREQUENCY_INVARIANT_SCALE
  38521. + bool "(EXPERIMENTAL) Frequency-Invariant Tracked Load for HMP"
  38522. + depends on HMP_VARIABLE_SCALE && CPU_FREQ
  38523. + help
  38524. + Scales the current load contribution in line with the frequency
  38525. + of the CPU that the task was executed on.
  38526. + In this version, we use a simple linear scale derived from the
  38527. + maximum frequency reported by CPUFreq.
  38528. + Restricting tracked load to be scaled by the CPU's frequency
  38529. + represents the consumption of possible compute capacity
  38530. + (rather than consumption of actual instantaneous capacity as
  38531. + normal) and allows the HMP migration's simple threshold
  38532. + migration strategy to interact more predictably with CPUFreq's
  38533. + asynchronous compute capacity changes.
  38534. +
  38535. +config SCHED_HMP_LITTLE_PACKING
  38536. + bool "Small task packing for HMP"
  38537. + depends on SCHED_HMP
  38538. + default n
  38539. + help
  38540. + Allows the HMP Scheduler to pack small tasks into CPUs in the
  38541. + smallest HMP domain.
  38542. + Controlled by two sysfs files in sys/kernel/hmp.
  38543. + packing_enable: 1 to enable, 0 to disable packing. Default 1.
  38544. + packing_limit: runqueue load ratio where a RQ is considered
  38545. + to be full. Default is NICE_0_LOAD * 9/8.
  38546. +
  38547. config NR_CPUS
  38548. int "Maximum number of CPUs (2-32)"
  38549. range 2 32
  38550. @@ -317,5 +456,8 @@
  38551. source "security/Kconfig"
  38552. source "crypto/Kconfig"
  38553. +if CRYPTO
  38554. +source "arch/arm64/crypto/Kconfig"
  38555. +endif
  38556. source "lib/Kconfig"
  38557. diff -Nur linux-3.14.17/arch/arm64/kernel/arm64ksyms.c linux-imx6-3.14/arch/arm64/kernel/arm64ksyms.c
  38558. --- linux-3.14.17/arch/arm64/kernel/arm64ksyms.c 2014-08-14 03:38:34.000000000 +0200
  38559. +++ linux-imx6-3.14/arch/arm64/kernel/arm64ksyms.c 2014-09-11 18:05:54.458007828 +0200
  38560. @@ -56,3 +56,7 @@
  38561. EXPORT_SYMBOL(test_and_clear_bit);
  38562. EXPORT_SYMBOL(change_bit);
  38563. EXPORT_SYMBOL(test_and_change_bit);
  38564. +
  38565. +#ifdef CONFIG_FUNCTION_TRACER
  38566. +EXPORT_SYMBOL(_mcount);
  38567. +#endif
  38568. diff -Nur linux-3.14.17/arch/arm64/kernel/debug-monitors.c linux-imx6-3.14/arch/arm64/kernel/debug-monitors.c
  38569. --- linux-3.14.17/arch/arm64/kernel/debug-monitors.c 2014-08-14 03:38:34.000000000 +0200
  38570. +++ linux-imx6-3.14/arch/arm64/kernel/debug-monitors.c 2014-09-11 18:05:54.458007828 +0200
  38571. @@ -138,6 +138,7 @@
  38572. {
  38573. asm volatile("msr oslar_el1, %0" : : "r" (0));
  38574. isb();
  38575. + local_dbg_enable();
  38576. }
  38577. static int os_lock_notify(struct notifier_block *self,
  38578. @@ -314,9 +315,6 @@
  38579. if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED)
  38580. return 0;
  38581. - pr_warn("unexpected brk exception at %lx, esr=0x%x\n",
  38582. - (long)instruction_pointer(regs), esr);
  38583. -
  38584. if (!user_mode(regs))
  38585. return -EFAULT;
  38586. diff -Nur linux-3.14.17/arch/arm64/kernel/entry-ftrace.S linux-imx6-3.14/arch/arm64/kernel/entry-ftrace.S
  38587. --- linux-3.14.17/arch/arm64/kernel/entry-ftrace.S 1970-01-01 01:00:00.000000000 +0100
  38588. +++ linux-imx6-3.14/arch/arm64/kernel/entry-ftrace.S 2014-09-11 18:05:54.462007844 +0200
  38589. @@ -0,0 +1,218 @@
  38590. +/*
  38591. + * arch/arm64/kernel/entry-ftrace.S
  38592. + *
  38593. + * Copyright (C) 2013 Linaro Limited
  38594. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  38595. + *
  38596. + * This program is free software; you can redistribute it and/or modify
  38597. + * it under the terms of the GNU General Public License version 2 as
  38598. + * published by the Free Software Foundation.
  38599. + */
  38600. +
  38601. +#include <linux/linkage.h>
  38602. +#include <asm/ftrace.h>
  38603. +#include <asm/insn.h>
  38604. +
  38605. +/*
  38606. + * Gcc with -pg will put the following code in the beginning of each function:
  38607. + * mov x0, x30
  38608. + * bl _mcount
  38609. + * [function's body ...]
  38610. + * "bl _mcount" may be replaced to "bl ftrace_caller" or NOP if dynamic
  38611. + * ftrace is enabled.
  38612. + *
  38613. + * Please note that x0 as an argument will not be used here because we can
  38614. + * get lr(x30) of instrumented function at any time by winding up call stack
  38615. + * as long as the kernel is compiled without -fomit-frame-pointer.
  38616. + * (or CONFIG_FRAME_POINTER, this is forced on arm64)
  38617. + *
  38618. + * stack layout after mcount_enter in _mcount():
  38619. + *
  38620. + * current sp/fp => 0:+-----+
  38621. + * in _mcount() | x29 | -> instrumented function's fp
  38622. + * +-----+
  38623. + * | x30 | -> _mcount()'s lr (= instrumented function's pc)
  38624. + * old sp => +16:+-----+
  38625. + * when instrumented | |
  38626. + * function calls | ... |
  38627. + * _mcount() | |
  38628. + * | |
  38629. + * instrumented => +xx:+-----+
  38630. + * function's fp | x29 | -> parent's fp
  38631. + * +-----+
  38632. + * | x30 | -> instrumented function's lr (= parent's pc)
  38633. + * +-----+
  38634. + * | ... |
  38635. + */
  38636. +
  38637. + .macro mcount_enter
  38638. + stp x29, x30, [sp, #-16]!
  38639. + mov x29, sp
  38640. + .endm
  38641. +
  38642. + .macro mcount_exit
  38643. + ldp x29, x30, [sp], #16
  38644. + ret
  38645. + .endm
  38646. +
  38647. + .macro mcount_adjust_addr rd, rn
  38648. + sub \rd, \rn, #AARCH64_INSN_SIZE
  38649. + .endm
  38650. +
  38651. + /* for instrumented function's parent */
  38652. + .macro mcount_get_parent_fp reg
  38653. + ldr \reg, [x29]
  38654. + ldr \reg, [\reg]
  38655. + .endm
  38656. +
  38657. + /* for instrumented function */
  38658. + .macro mcount_get_pc0 reg
  38659. + mcount_adjust_addr \reg, x30
  38660. + .endm
  38661. +
  38662. + .macro mcount_get_pc reg
  38663. + ldr \reg, [x29, #8]
  38664. + mcount_adjust_addr \reg, \reg
  38665. + .endm
  38666. +
  38667. + .macro mcount_get_lr reg
  38668. + ldr \reg, [x29]
  38669. + ldr \reg, [\reg, #8]
  38670. + mcount_adjust_addr \reg, \reg
  38671. + .endm
  38672. +
  38673. + .macro mcount_get_lr_addr reg
  38674. + ldr \reg, [x29]
  38675. + add \reg, \reg, #8
  38676. + .endm
  38677. +
  38678. +#ifndef CONFIG_DYNAMIC_FTRACE
  38679. +/*
  38680. + * void _mcount(unsigned long return_address)
  38681. + * @return_address: return address to instrumented function
  38682. + *
  38683. + * This function makes calls, if enabled, to:
  38684. + * - tracer function to probe instrumented function's entry,
  38685. + * - ftrace_graph_caller to set up an exit hook
  38686. + */
  38687. +ENTRY(_mcount)
  38688. +#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
  38689. + ldr x0, =ftrace_trace_stop
  38690. + ldr x0, [x0] // if ftrace_trace_stop
  38691. + ret // return;
  38692. +#endif
  38693. + mcount_enter
  38694. +
  38695. + ldr x0, =ftrace_trace_function
  38696. + ldr x2, [x0]
  38697. + adr x0, ftrace_stub
  38698. + cmp x0, x2 // if (ftrace_trace_function
  38699. + b.eq skip_ftrace_call // != ftrace_stub) {
  38700. +
  38701. + mcount_get_pc x0 // function's pc
  38702. + mcount_get_lr x1 // function's lr (= parent's pc)
  38703. + blr x2 // (*ftrace_trace_function)(pc, lr);
  38704. +
  38705. +#ifndef CONFIG_FUNCTION_GRAPH_TRACER
  38706. +skip_ftrace_call: // return;
  38707. + mcount_exit // }
  38708. +#else
  38709. + mcount_exit // return;
  38710. + // }
  38711. +skip_ftrace_call:
  38712. + ldr x1, =ftrace_graph_return
  38713. + ldr x2, [x1] // if ((ftrace_graph_return
  38714. + cmp x0, x2 // != ftrace_stub)
  38715. + b.ne ftrace_graph_caller
  38716. +
  38717. + ldr x1, =ftrace_graph_entry // || (ftrace_graph_entry
  38718. + ldr x2, [x1] // != ftrace_graph_entry_stub))
  38719. + ldr x0, =ftrace_graph_entry_stub
  38720. + cmp x0, x2
  38721. + b.ne ftrace_graph_caller // ftrace_graph_caller();
  38722. +
  38723. + mcount_exit
  38724. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38725. +ENDPROC(_mcount)
  38726. +
  38727. +#else /* CONFIG_DYNAMIC_FTRACE */
  38728. +/*
  38729. + * _mcount() is used to build the kernel with -pg option, but all the branch
  38730. + * instructions to _mcount() are replaced to NOP initially at kernel start up,
  38731. + * and later on, NOP to branch to ftrace_caller() when enabled or branch to
  38732. + * NOP when disabled per-function base.
  38733. + */
  38734. +ENTRY(_mcount)
  38735. + ret
  38736. +ENDPROC(_mcount)
  38737. +
  38738. +/*
  38739. + * void ftrace_caller(unsigned long return_address)
  38740. + * @return_address: return address to instrumented function
  38741. + *
  38742. + * This function is a counterpart of _mcount() in 'static' ftrace, and
  38743. + * makes calls to:
  38744. + * - tracer function to probe instrumented function's entry,
  38745. + * - ftrace_graph_caller to set up an exit hook
  38746. + */
  38747. +ENTRY(ftrace_caller)
  38748. + mcount_enter
  38749. +
  38750. + mcount_get_pc0 x0 // function's pc
  38751. + mcount_get_lr x1 // function's lr
  38752. +
  38753. + .global ftrace_call
  38754. +ftrace_call: // tracer(pc, lr);
  38755. + nop // This will be replaced with "bl xxx"
  38756. + // where xxx can be any kind of tracer.
  38757. +
  38758. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38759. + .global ftrace_graph_call
  38760. +ftrace_graph_call: // ftrace_graph_caller();
  38761. + nop // If enabled, this will be replaced
  38762. + // "b ftrace_graph_caller"
  38763. +#endif
  38764. +
  38765. + mcount_exit
  38766. +ENDPROC(ftrace_caller)
  38767. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38768. +
  38769. +ENTRY(ftrace_stub)
  38770. + ret
  38771. +ENDPROC(ftrace_stub)
  38772. +
  38773. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38774. +/*
  38775. + * void ftrace_graph_caller(void)
  38776. + *
  38777. + * Called from _mcount() or ftrace_caller() when function_graph tracer is
  38778. + * selected.
  38779. + * This function w/ prepare_ftrace_return() fakes link register's value on
  38780. + * the call stack in order to intercept instrumented function's return path
  38781. + * and run return_to_handler() later on its exit.
  38782. + */
  38783. +ENTRY(ftrace_graph_caller)
  38784. + mcount_get_lr_addr x0 // pointer to function's saved lr
  38785. + mcount_get_pc x1 // function's pc
  38786. + mcount_get_parent_fp x2 // parent's fp
  38787. + bl prepare_ftrace_return // prepare_ftrace_return(&lr, pc, fp)
  38788. +
  38789. + mcount_exit
  38790. +ENDPROC(ftrace_graph_caller)
  38791. +
  38792. +/*
  38793. + * void return_to_handler(void)
  38794. + *
  38795. + * Run ftrace_return_to_handler() before going back to parent.
  38796. + * @fp is checked against the value passed by ftrace_graph_caller()
  38797. + * only when CONFIG_FUNCTION_GRAPH_FP_TEST is enabled.
  38798. + */
  38799. +ENTRY(return_to_handler)
  38800. + str x0, [sp, #-16]!
  38801. + mov x0, x29 // parent's fp
  38802. + bl ftrace_return_to_handler// addr = ftrace_return_to_hander(fp);
  38803. + mov x30, x0 // restore the original return address
  38804. + ldr x0, [sp], #16
  38805. + ret
  38806. +END(return_to_handler)
  38807. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  38808. diff -Nur linux-3.14.17/arch/arm64/kernel/entry.S linux-imx6-3.14/arch/arm64/kernel/entry.S
  38809. --- linux-3.14.17/arch/arm64/kernel/entry.S 2014-08-14 03:38:34.000000000 +0200
  38810. +++ linux-imx6-3.14/arch/arm64/kernel/entry.S 2014-09-11 18:05:54.462007844 +0200
  38811. @@ -630,8 +630,9 @@
  38812. enable_irq
  38813. get_thread_info tsk
  38814. - ldr x16, [tsk, #TI_FLAGS] // check for syscall tracing
  38815. - tbnz x16, #TIF_SYSCALL_TRACE, __sys_trace // are we tracing syscalls?
  38816. + ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
  38817. + tst x16, #_TIF_SYSCALL_WORK
  38818. + b.ne __sys_trace
  38819. adr lr, ret_fast_syscall // return address
  38820. cmp scno, sc_nr // check upper syscall limit
  38821. b.hs ni_sys
  38822. @@ -647,9 +648,8 @@
  38823. * switches, and waiting for our parent to respond.
  38824. */
  38825. __sys_trace:
  38826. - mov x1, sp
  38827. - mov w0, #0 // trace entry
  38828. - bl syscall_trace
  38829. + mov x0, sp
  38830. + bl syscall_trace_enter
  38831. adr lr, __sys_trace_return // return address
  38832. uxtw scno, w0 // syscall number (possibly new)
  38833. mov x1, sp // pointer to regs
  38834. @@ -664,9 +664,8 @@
  38835. __sys_trace_return:
  38836. str x0, [sp] // save returned x0
  38837. - mov x1, sp
  38838. - mov w0, #1 // trace exit
  38839. - bl syscall_trace
  38840. + mov x0, sp
  38841. + bl syscall_trace_exit
  38842. b ret_to_user
  38843. /*
  38844. diff -Nur linux-3.14.17/arch/arm64/kernel/ftrace.c linux-imx6-3.14/arch/arm64/kernel/ftrace.c
  38845. --- linux-3.14.17/arch/arm64/kernel/ftrace.c 1970-01-01 01:00:00.000000000 +0100
  38846. +++ linux-imx6-3.14/arch/arm64/kernel/ftrace.c 2014-09-11 18:05:54.462007844 +0200
  38847. @@ -0,0 +1,177 @@
  38848. +/*
  38849. + * arch/arm64/kernel/ftrace.c
  38850. + *
  38851. + * Copyright (C) 2013 Linaro Limited
  38852. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  38853. + *
  38854. + * This program is free software; you can redistribute it and/or modify
  38855. + * it under the terms of the GNU General Public License version 2 as
  38856. + * published by the Free Software Foundation.
  38857. + */
  38858. +
  38859. +#include <linux/ftrace.h>
  38860. +#include <linux/swab.h>
  38861. +#include <linux/uaccess.h>
  38862. +
  38863. +#include <asm/cacheflush.h>
  38864. +#include <asm/ftrace.h>
  38865. +#include <asm/insn.h>
  38866. +
  38867. +#ifdef CONFIG_DYNAMIC_FTRACE
  38868. +/*
  38869. + * Replace a single instruction, which may be a branch or NOP.
  38870. + * If @validate == true, a replaced instruction is checked against 'old'.
  38871. + */
  38872. +static int ftrace_modify_code(unsigned long pc, u32 old, u32 new,
  38873. + bool validate)
  38874. +{
  38875. + u32 replaced;
  38876. +
  38877. + /*
  38878. + * Note:
  38879. + * Due to modules and __init, code can disappear and change,
  38880. + * we need to protect against faulting as well as code changing.
  38881. + * We do this by aarch64_insn_*() which use the probe_kernel_*().
  38882. + *
  38883. + * No lock is held here because all the modifications are run
  38884. + * through stop_machine().
  38885. + */
  38886. + if (validate) {
  38887. + if (aarch64_insn_read((void *)pc, &replaced))
  38888. + return -EFAULT;
  38889. +
  38890. + if (replaced != old)
  38891. + return -EINVAL;
  38892. + }
  38893. + if (aarch64_insn_patch_text_nosync((void *)pc, new))
  38894. + return -EPERM;
  38895. +
  38896. + return 0;
  38897. +}
  38898. +
  38899. +/*
  38900. + * Replace tracer function in ftrace_caller()
  38901. + */
  38902. +int ftrace_update_ftrace_func(ftrace_func_t func)
  38903. +{
  38904. + unsigned long pc;
  38905. + u32 new;
  38906. +
  38907. + pc = (unsigned long)&ftrace_call;
  38908. + new = aarch64_insn_gen_branch_imm(pc, (unsigned long)func, true);
  38909. +
  38910. + return ftrace_modify_code(pc, 0, new, false);
  38911. +}
  38912. +
  38913. +/*
  38914. + * Turn on the call to ftrace_caller() in instrumented function
  38915. + */
  38916. +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  38917. +{
  38918. + unsigned long pc = rec->ip;
  38919. + u32 old, new;
  38920. +
  38921. + old = aarch64_insn_gen_nop();
  38922. + new = aarch64_insn_gen_branch_imm(pc, addr, true);
  38923. +
  38924. + return ftrace_modify_code(pc, old, new, true);
  38925. +}
  38926. +
  38927. +/*
  38928. + * Turn off the call to ftrace_caller() in instrumented function
  38929. + */
  38930. +int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
  38931. + unsigned long addr)
  38932. +{
  38933. + unsigned long pc = rec->ip;
  38934. + u32 old, new;
  38935. +
  38936. + old = aarch64_insn_gen_branch_imm(pc, addr, true);
  38937. + new = aarch64_insn_gen_nop();
  38938. +
  38939. + return ftrace_modify_code(pc, old, new, true);
  38940. +}
  38941. +
  38942. +int __init ftrace_dyn_arch_init(void *data)
  38943. +{
  38944. + *(unsigned long *)data = 0;
  38945. + return 0;
  38946. +}
  38947. +#endif /* CONFIG_DYNAMIC_FTRACE */
  38948. +
  38949. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  38950. +/*
  38951. + * function_graph tracer expects ftrace_return_to_handler() to be called
  38952. + * on the way back to parent. For this purpose, this function is called
  38953. + * in _mcount() or ftrace_caller() to replace return address (*parent) on
  38954. + * the call stack to return_to_handler.
  38955. + *
  38956. + * Note that @frame_pointer is used only for sanity check later.
  38957. + */
  38958. +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
  38959. + unsigned long frame_pointer)
  38960. +{
  38961. + unsigned long return_hooker = (unsigned long)&return_to_handler;
  38962. + unsigned long old;
  38963. + struct ftrace_graph_ent trace;
  38964. + int err;
  38965. +
  38966. + if (unlikely(atomic_read(&current->tracing_graph_pause)))
  38967. + return;
  38968. +
  38969. + /*
  38970. + * Note:
  38971. + * No protection against faulting at *parent, which may be seen
  38972. + * on other archs. It's unlikely on AArch64.
  38973. + */
  38974. + old = *parent;
  38975. + *parent = return_hooker;
  38976. +
  38977. + trace.func = self_addr;
  38978. + trace.depth = current->curr_ret_stack + 1;
  38979. +
  38980. + /* Only trace if the calling function expects to */
  38981. + if (!ftrace_graph_entry(&trace)) {
  38982. + *parent = old;
  38983. + return;
  38984. + }
  38985. +
  38986. + err = ftrace_push_return_trace(old, self_addr, &trace.depth,
  38987. + frame_pointer);
  38988. + if (err == -EBUSY) {
  38989. + *parent = old;
  38990. + return;
  38991. + }
  38992. +}
  38993. +
  38994. +#ifdef CONFIG_DYNAMIC_FTRACE
  38995. +/*
  38996. + * Turn on/off the call to ftrace_graph_caller() in ftrace_caller()
  38997. + * depending on @enable.
  38998. + */
  38999. +static int ftrace_modify_graph_caller(bool enable)
  39000. +{
  39001. + unsigned long pc = (unsigned long)&ftrace_graph_call;
  39002. + u32 branch, nop;
  39003. +
  39004. + branch = aarch64_insn_gen_branch_imm(pc,
  39005. + (unsigned long)ftrace_graph_caller, false);
  39006. + nop = aarch64_insn_gen_nop();
  39007. +
  39008. + if (enable)
  39009. + return ftrace_modify_code(pc, nop, branch, true);
  39010. + else
  39011. + return ftrace_modify_code(pc, branch, nop, true);
  39012. +}
  39013. +
  39014. +int ftrace_enable_ftrace_graph_caller(void)
  39015. +{
  39016. + return ftrace_modify_graph_caller(true);
  39017. +}
  39018. +
  39019. +int ftrace_disable_ftrace_graph_caller(void)
  39020. +{
  39021. + return ftrace_modify_graph_caller(false);
  39022. +}
  39023. +#endif /* CONFIG_DYNAMIC_FTRACE */
  39024. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  39025. diff -Nur linux-3.14.17/arch/arm64/kernel/head.S linux-imx6-3.14/arch/arm64/kernel/head.S
  39026. --- linux-3.14.17/arch/arm64/kernel/head.S 2014-08-14 03:38:34.000000000 +0200
  39027. +++ linux-imx6-3.14/arch/arm64/kernel/head.S 2014-09-11 18:05:54.462007844 +0200
  39028. @@ -26,6 +26,7 @@
  39029. #include <asm/assembler.h>
  39030. #include <asm/ptrace.h>
  39031. #include <asm/asm-offsets.h>
  39032. +#include <asm/cache.h>
  39033. #include <asm/cputype.h>
  39034. #include <asm/memory.h>
  39035. #include <asm/thread_info.h>
  39036. @@ -34,29 +35,17 @@
  39037. #include <asm/page.h>
  39038. #include <asm/virt.h>
  39039. -/*
  39040. - * swapper_pg_dir is the virtual address of the initial page table. We place
  39041. - * the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has
  39042. - * 2 pages and is placed below swapper_pg_dir.
  39043. - */
  39044. #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
  39045. #if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000
  39046. #error KERNEL_RAM_VADDR must start at 0xXXX80000
  39047. #endif
  39048. -#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE)
  39049. -#define IDMAP_DIR_SIZE (2 * PAGE_SIZE)
  39050. -
  39051. - .globl swapper_pg_dir
  39052. - .equ swapper_pg_dir, KERNEL_RAM_VADDR - SWAPPER_DIR_SIZE
  39053. -
  39054. - .globl idmap_pg_dir
  39055. - .equ idmap_pg_dir, swapper_pg_dir - IDMAP_DIR_SIZE
  39056. -
  39057. - .macro pgtbl, ttb0, ttb1, phys
  39058. - add \ttb1, \phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE
  39059. - sub \ttb0, \ttb1, #IDMAP_DIR_SIZE
  39060. + .macro pgtbl, ttb0, ttb1, virt_to_phys
  39061. + ldr \ttb1, =swapper_pg_dir
  39062. + ldr \ttb0, =idmap_pg_dir
  39063. + add \ttb1, \ttb1, \virt_to_phys
  39064. + add \ttb0, \ttb0, \virt_to_phys
  39065. .endm
  39066. #ifdef CONFIG_ARM64_64K_PAGES
  39067. @@ -229,7 +218,11 @@
  39068. cmp w20, #BOOT_CPU_MODE_EL2
  39069. b.ne 1f
  39070. add x1, x1, #4
  39071. -1: str w20, [x1] // This CPU has booted in EL1
  39072. +1: dc cvac, x1 // Clean potentially dirty cache line
  39073. + dsb sy
  39074. + str w20, [x1] // This CPU has booted in EL1
  39075. + dc civac, x1 // Clean&invalidate potentially stale cache line
  39076. + dsb sy
  39077. ret
  39078. ENDPROC(set_cpu_boot_mode_flag)
  39079. @@ -240,8 +233,9 @@
  39080. * This is not in .bss, because we set it sufficiently early that the boot-time
  39081. * zeroing of .bss would clobber it.
  39082. */
  39083. - .pushsection .data
  39084. + .pushsection .data..cacheline_aligned
  39085. ENTRY(__boot_cpu_mode)
  39086. + .align L1_CACHE_SHIFT
  39087. .long BOOT_CPU_MODE_EL2
  39088. .long 0
  39089. .popsection
  39090. @@ -298,7 +292,7 @@
  39091. mov x23, x0 // x23=current cpu_table
  39092. cbz x23, __error_p // invalid processor (x23=0)?
  39093. - pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1
  39094. + pgtbl x25, x26, x28 // x25=TTBR0, x26=TTBR1
  39095. ldr x12, [x23, #CPU_INFO_SETUP]
  39096. add x12, x12, x28 // __virt_to_phys
  39097. blr x12 // initialise processor
  39098. @@ -340,8 +334,13 @@
  39099. * x27 = *virtual* address to jump to upon completion
  39100. *
  39101. * other registers depend on the function called upon completion
  39102. + *
  39103. + * We align the entire function to the smallest power of two larger than it to
  39104. + * ensure it fits within a single block map entry. Otherwise were PHYS_OFFSET
  39105. + * close to the end of a 512MB or 1GB block we might require an additional
  39106. + * table to map the entire function.
  39107. */
  39108. - .align 6
  39109. + .align 4
  39110. __turn_mmu_on:
  39111. msr sctlr_el1, x0
  39112. isb
  39113. @@ -384,26 +383,18 @@
  39114. * Preserves: tbl, flags
  39115. * Corrupts: phys, start, end, pstate
  39116. */
  39117. - .macro create_block_map, tbl, flags, phys, start, end, idmap=0
  39118. + .macro create_block_map, tbl, flags, phys, start, end
  39119. lsr \phys, \phys, #BLOCK_SHIFT
  39120. - .if \idmap
  39121. - and \start, \phys, #PTRS_PER_PTE - 1 // table index
  39122. - .else
  39123. lsr \start, \start, #BLOCK_SHIFT
  39124. and \start, \start, #PTRS_PER_PTE - 1 // table index
  39125. - .endif
  39126. orr \phys, \flags, \phys, lsl #BLOCK_SHIFT // table entry
  39127. - .ifnc \start,\end
  39128. lsr \end, \end, #BLOCK_SHIFT
  39129. and \end, \end, #PTRS_PER_PTE - 1 // table end index
  39130. - .endif
  39131. 9999: str \phys, [\tbl, \start, lsl #3] // store the entry
  39132. - .ifnc \start,\end
  39133. add \start, \start, #1 // next entry
  39134. add \phys, \phys, #BLOCK_SIZE // next block
  39135. cmp \start, \end
  39136. b.ls 9999b
  39137. - .endif
  39138. .endm
  39139. /*
  39140. @@ -415,7 +406,16 @@
  39141. * - UART mapping if CONFIG_EARLY_PRINTK is enabled (TTBR1)
  39142. */
  39143. __create_page_tables:
  39144. - pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses
  39145. + pgtbl x25, x26, x28 // idmap_pg_dir and swapper_pg_dir addresses
  39146. + mov x27, lr
  39147. +
  39148. + /*
  39149. + * Invalidate the idmap and swapper page tables to avoid potential
  39150. + * dirty cache lines being evicted.
  39151. + */
  39152. + mov x0, x25
  39153. + add x1, x26, #SWAPPER_DIR_SIZE
  39154. + bl __inval_cache_range
  39155. /*
  39156. * Clear the idmap and swapper page tables.
  39157. @@ -435,9 +435,13 @@
  39158. * Create the identity mapping.
  39159. */
  39160. add x0, x25, #PAGE_SIZE // section table address
  39161. - adr x3, __turn_mmu_on // virtual/physical address
  39162. + ldr x3, =KERNEL_START
  39163. + add x3, x3, x28 // __pa(KERNEL_START)
  39164. create_pgd_entry x25, x0, x3, x5, x6
  39165. - create_block_map x0, x7, x3, x5, x5, idmap=1
  39166. + ldr x6, =KERNEL_END
  39167. + mov x5, x3 // __pa(KERNEL_START)
  39168. + add x6, x6, x28 // __pa(KERNEL_END)
  39169. + create_block_map x0, x7, x3, x5, x6
  39170. /*
  39171. * Map the kernel image (starting with PHYS_OFFSET).
  39172. @@ -445,7 +449,7 @@
  39173. add x0, x26, #PAGE_SIZE // section table address
  39174. mov x5, #PAGE_OFFSET
  39175. create_pgd_entry x26, x0, x5, x3, x6
  39176. - ldr x6, =KERNEL_END - 1
  39177. + ldr x6, =KERNEL_END
  39178. mov x3, x24 // phys offset
  39179. create_block_map x0, x7, x3, x5, x6
  39180. @@ -474,6 +478,17 @@
  39181. add x0, x26, #2 * PAGE_SIZE // section table address
  39182. create_pgd_entry x26, x0, x5, x6, x7
  39183. #endif
  39184. +
  39185. + /*
  39186. + * Since the page tables have been populated with non-cacheable
  39187. + * accesses (MMU disabled), invalidate the idmap and swapper page
  39188. + * tables again to remove any speculatively loaded cache lines.
  39189. + */
  39190. + mov x0, x25
  39191. + add x1, x26, #SWAPPER_DIR_SIZE
  39192. + bl __inval_cache_range
  39193. +
  39194. + mov lr, x27
  39195. ret
  39196. ENDPROC(__create_page_tables)
  39197. .ltorg
  39198. @@ -483,7 +498,7 @@
  39199. __switch_data:
  39200. .quad __mmap_switched
  39201. .quad __bss_start // x6
  39202. - .quad _end // x7
  39203. + .quad __bss_stop // x7
  39204. .quad processor_id // x4
  39205. .quad __fdt_pointer // x5
  39206. .quad memstart_addr // x6
  39207. diff -Nur linux-3.14.17/arch/arm64/kernel/hw_breakpoint.c linux-imx6-3.14/arch/arm64/kernel/hw_breakpoint.c
  39208. --- linux-3.14.17/arch/arm64/kernel/hw_breakpoint.c 2014-08-14 03:38:34.000000000 +0200
  39209. +++ linux-imx6-3.14/arch/arm64/kernel/hw_breakpoint.c 2014-09-11 18:05:54.462007844 +0200
  39210. @@ -20,6 +20,7 @@
  39211. #define pr_fmt(fmt) "hw-breakpoint: " fmt
  39212. +#include <linux/compat.h>
  39213. #include <linux/cpu_pm.h>
  39214. #include <linux/errno.h>
  39215. #include <linux/hw_breakpoint.h>
  39216. @@ -27,7 +28,6 @@
  39217. #include <linux/ptrace.h>
  39218. #include <linux/smp.h>
  39219. -#include <asm/compat.h>
  39220. #include <asm/current.h>
  39221. #include <asm/debug-monitors.h>
  39222. #include <asm/hw_breakpoint.h>
  39223. diff -Nur linux-3.14.17/arch/arm64/kernel/kgdb.c linux-imx6-3.14/arch/arm64/kernel/kgdb.c
  39224. --- linux-3.14.17/arch/arm64/kernel/kgdb.c 1970-01-01 01:00:00.000000000 +0100
  39225. +++ linux-imx6-3.14/arch/arm64/kernel/kgdb.c 2014-09-11 18:05:54.470007876 +0200
  39226. @@ -0,0 +1,336 @@
  39227. +/*
  39228. + * AArch64 KGDB support
  39229. + *
  39230. + * Based on arch/arm/kernel/kgdb.c
  39231. + *
  39232. + * Copyright (C) 2013 Cavium Inc.
  39233. + * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>
  39234. + *
  39235. + * This program is free software; you can redistribute it and/or modify
  39236. + * it under the terms of the GNU General Public License version 2 as
  39237. + * published by the Free Software Foundation.
  39238. + *
  39239. + * This program is distributed in the hope that it will be useful,
  39240. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  39241. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39242. + * GNU General Public License for more details.
  39243. + *
  39244. + * You should have received a copy of the GNU General Public License
  39245. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39246. + */
  39247. +
  39248. +#include <linux/irq.h>
  39249. +#include <linux/kdebug.h>
  39250. +#include <linux/kgdb.h>
  39251. +#include <asm/traps.h>
  39252. +
  39253. +struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
  39254. + { "x0", 8, offsetof(struct pt_regs, regs[0])},
  39255. + { "x1", 8, offsetof(struct pt_regs, regs[1])},
  39256. + { "x2", 8, offsetof(struct pt_regs, regs[2])},
  39257. + { "x3", 8, offsetof(struct pt_regs, regs[3])},
  39258. + { "x4", 8, offsetof(struct pt_regs, regs[4])},
  39259. + { "x5", 8, offsetof(struct pt_regs, regs[5])},
  39260. + { "x6", 8, offsetof(struct pt_regs, regs[6])},
  39261. + { "x7", 8, offsetof(struct pt_regs, regs[7])},
  39262. + { "x8", 8, offsetof(struct pt_regs, regs[8])},
  39263. + { "x9", 8, offsetof(struct pt_regs, regs[9])},
  39264. + { "x10", 8, offsetof(struct pt_regs, regs[10])},
  39265. + { "x11", 8, offsetof(struct pt_regs, regs[11])},
  39266. + { "x12", 8, offsetof(struct pt_regs, regs[12])},
  39267. + { "x13", 8, offsetof(struct pt_regs, regs[13])},
  39268. + { "x14", 8, offsetof(struct pt_regs, regs[14])},
  39269. + { "x15", 8, offsetof(struct pt_regs, regs[15])},
  39270. + { "x16", 8, offsetof(struct pt_regs, regs[16])},
  39271. + { "x17", 8, offsetof(struct pt_regs, regs[17])},
  39272. + { "x18", 8, offsetof(struct pt_regs, regs[18])},
  39273. + { "x19", 8, offsetof(struct pt_regs, regs[19])},
  39274. + { "x20", 8, offsetof(struct pt_regs, regs[20])},
  39275. + { "x21", 8, offsetof(struct pt_regs, regs[21])},
  39276. + { "x22", 8, offsetof(struct pt_regs, regs[22])},
  39277. + { "x23", 8, offsetof(struct pt_regs, regs[23])},
  39278. + { "x24", 8, offsetof(struct pt_regs, regs[24])},
  39279. + { "x25", 8, offsetof(struct pt_regs, regs[25])},
  39280. + { "x26", 8, offsetof(struct pt_regs, regs[26])},
  39281. + { "x27", 8, offsetof(struct pt_regs, regs[27])},
  39282. + { "x28", 8, offsetof(struct pt_regs, regs[28])},
  39283. + { "x29", 8, offsetof(struct pt_regs, regs[29])},
  39284. + { "x30", 8, offsetof(struct pt_regs, regs[30])},
  39285. + { "sp", 8, offsetof(struct pt_regs, sp)},
  39286. + { "pc", 8, offsetof(struct pt_regs, pc)},
  39287. + { "pstate", 8, offsetof(struct pt_regs, pstate)},
  39288. + { "v0", 16, -1 },
  39289. + { "v1", 16, -1 },
  39290. + { "v2", 16, -1 },
  39291. + { "v3", 16, -1 },
  39292. + { "v4", 16, -1 },
  39293. + { "v5", 16, -1 },
  39294. + { "v6", 16, -1 },
  39295. + { "v7", 16, -1 },
  39296. + { "v8", 16, -1 },
  39297. + { "v9", 16, -1 },
  39298. + { "v10", 16, -1 },
  39299. + { "v11", 16, -1 },
  39300. + { "v12", 16, -1 },
  39301. + { "v13", 16, -1 },
  39302. + { "v14", 16, -1 },
  39303. + { "v15", 16, -1 },
  39304. + { "v16", 16, -1 },
  39305. + { "v17", 16, -1 },
  39306. + { "v18", 16, -1 },
  39307. + { "v19", 16, -1 },
  39308. + { "v20", 16, -1 },
  39309. + { "v21", 16, -1 },
  39310. + { "v22", 16, -1 },
  39311. + { "v23", 16, -1 },
  39312. + { "v24", 16, -1 },
  39313. + { "v25", 16, -1 },
  39314. + { "v26", 16, -1 },
  39315. + { "v27", 16, -1 },
  39316. + { "v28", 16, -1 },
  39317. + { "v29", 16, -1 },
  39318. + { "v30", 16, -1 },
  39319. + { "v31", 16, -1 },
  39320. + { "fpsr", 4, -1 },
  39321. + { "fpcr", 4, -1 },
  39322. +};
  39323. +
  39324. +char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
  39325. +{
  39326. + if (regno >= DBG_MAX_REG_NUM || regno < 0)
  39327. + return NULL;
  39328. +
  39329. + if (dbg_reg_def[regno].offset != -1)
  39330. + memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
  39331. + dbg_reg_def[regno].size);
  39332. + else
  39333. + memset(mem, 0, dbg_reg_def[regno].size);
  39334. + return dbg_reg_def[regno].name;
  39335. +}
  39336. +
  39337. +int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
  39338. +{
  39339. + if (regno >= DBG_MAX_REG_NUM || regno < 0)
  39340. + return -EINVAL;
  39341. +
  39342. + if (dbg_reg_def[regno].offset != -1)
  39343. + memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
  39344. + dbg_reg_def[regno].size);
  39345. + return 0;
  39346. +}
  39347. +
  39348. +void
  39349. +sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
  39350. +{
  39351. + struct pt_regs *thread_regs;
  39352. +
  39353. + /* Initialize to zero */
  39354. + memset((char *)gdb_regs, 0, NUMREGBYTES);
  39355. + thread_regs = task_pt_regs(task);
  39356. + memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES);
  39357. +}
  39358. +
  39359. +void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
  39360. +{
  39361. + regs->pc = pc;
  39362. +}
  39363. +
  39364. +static int compiled_break;
  39365. +
  39366. +static void kgdb_arch_update_addr(struct pt_regs *regs,
  39367. + char *remcom_in_buffer)
  39368. +{
  39369. + unsigned long addr;
  39370. + char *ptr;
  39371. +
  39372. + ptr = &remcom_in_buffer[1];
  39373. + if (kgdb_hex2long(&ptr, &addr))
  39374. + kgdb_arch_set_pc(regs, addr);
  39375. + else if (compiled_break == 1)
  39376. + kgdb_arch_set_pc(regs, regs->pc + 4);
  39377. +
  39378. + compiled_break = 0;
  39379. +}
  39380. +
  39381. +int kgdb_arch_handle_exception(int exception_vector, int signo,
  39382. + int err_code, char *remcom_in_buffer,
  39383. + char *remcom_out_buffer,
  39384. + struct pt_regs *linux_regs)
  39385. +{
  39386. + int err;
  39387. +
  39388. + switch (remcom_in_buffer[0]) {
  39389. + case 'D':
  39390. + case 'k':
  39391. + /*
  39392. + * Packet D (Detach), k (kill). No special handling
  39393. + * is required here. Handle same as c packet.
  39394. + */
  39395. + case 'c':
  39396. + /*
  39397. + * Packet c (Continue) to continue executing.
  39398. + * Set pc to required address.
  39399. + * Try to read optional parameter and set pc.
  39400. + * If this was a compiled breakpoint, we need to move
  39401. + * to the next instruction else we will just breakpoint
  39402. + * over and over again.
  39403. + */
  39404. + kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
  39405. + atomic_set(&kgdb_cpu_doing_single_step, -1);
  39406. + kgdb_single_step = 0;
  39407. +
  39408. + /*
  39409. + * Received continue command, disable single step
  39410. + */
  39411. + if (kernel_active_single_step())
  39412. + kernel_disable_single_step();
  39413. +
  39414. + err = 0;
  39415. + break;
  39416. + case 's':
  39417. + /*
  39418. + * Update step address value with address passed
  39419. + * with step packet.
  39420. + * On debug exception return PC is copied to ELR
  39421. + * So just update PC.
  39422. + * If no step address is passed, resume from the address
  39423. + * pointed by PC. Do not update PC
  39424. + */
  39425. + kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
  39426. + atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
  39427. + kgdb_single_step = 1;
  39428. +
  39429. + /*
  39430. + * Enable single step handling
  39431. + */
  39432. + if (!kernel_active_single_step())
  39433. + kernel_enable_single_step(linux_regs);
  39434. + err = 0;
  39435. + break;
  39436. + default:
  39437. + err = -1;
  39438. + }
  39439. + return err;
  39440. +}
  39441. +
  39442. +static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr)
  39443. +{
  39444. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39445. + return 0;
  39446. +}
  39447. +
  39448. +static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
  39449. +{
  39450. + compiled_break = 1;
  39451. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39452. +
  39453. + return 0;
  39454. +}
  39455. +
  39456. +static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
  39457. +{
  39458. + kgdb_handle_exception(1, SIGTRAP, 0, regs);
  39459. + return 0;
  39460. +}
  39461. +
  39462. +static struct break_hook kgdb_brkpt_hook = {
  39463. + .esr_mask = 0xffffffff,
  39464. + .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
  39465. + .fn = kgdb_brk_fn
  39466. +};
  39467. +
  39468. +static struct break_hook kgdb_compiled_brkpt_hook = {
  39469. + .esr_mask = 0xffffffff,
  39470. + .esr_val = DBG_ESR_VAL_BRK(KDBG_COMPILED_DBG_BRK_IMM),
  39471. + .fn = kgdb_compiled_brk_fn
  39472. +};
  39473. +
  39474. +static struct step_hook kgdb_step_hook = {
  39475. + .fn = kgdb_step_brk_fn
  39476. +};
  39477. +
  39478. +static void kgdb_call_nmi_hook(void *ignored)
  39479. +{
  39480. + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
  39481. +}
  39482. +
  39483. +void kgdb_roundup_cpus(unsigned long flags)
  39484. +{
  39485. + local_irq_enable();
  39486. + smp_call_function(kgdb_call_nmi_hook, NULL, 0);
  39487. + local_irq_disable();
  39488. +}
  39489. +
  39490. +static int __kgdb_notify(struct die_args *args, unsigned long cmd)
  39491. +{
  39492. + struct pt_regs *regs = args->regs;
  39493. +
  39494. + if (kgdb_handle_exception(1, args->signr, cmd, regs))
  39495. + return NOTIFY_DONE;
  39496. + return NOTIFY_STOP;
  39497. +}
  39498. +
  39499. +static int
  39500. +kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
  39501. +{
  39502. + unsigned long flags;
  39503. + int ret;
  39504. +
  39505. + local_irq_save(flags);
  39506. + ret = __kgdb_notify(ptr, cmd);
  39507. + local_irq_restore(flags);
  39508. +
  39509. + return ret;
  39510. +}
  39511. +
  39512. +static struct notifier_block kgdb_notifier = {
  39513. + .notifier_call = kgdb_notify,
  39514. + /*
  39515. + * Want to be lowest priority
  39516. + */
  39517. + .priority = -INT_MAX,
  39518. +};
  39519. +
  39520. +/*
  39521. + * kgdb_arch_init - Perform any architecture specific initalization.
  39522. + * This function will handle the initalization of any architecture
  39523. + * specific callbacks.
  39524. + */
  39525. +int kgdb_arch_init(void)
  39526. +{
  39527. + int ret = register_die_notifier(&kgdb_notifier);
  39528. +
  39529. + if (ret != 0)
  39530. + return ret;
  39531. +
  39532. + register_break_hook(&kgdb_brkpt_hook);
  39533. + register_break_hook(&kgdb_compiled_brkpt_hook);
  39534. + register_step_hook(&kgdb_step_hook);
  39535. + return 0;
  39536. +}
  39537. +
  39538. +/*
  39539. + * kgdb_arch_exit - Perform any architecture specific uninitalization.
  39540. + * This function will handle the uninitalization of any architecture
  39541. + * specific callbacks, for dynamic registration and unregistration.
  39542. + */
  39543. +void kgdb_arch_exit(void)
  39544. +{
  39545. + unregister_break_hook(&kgdb_brkpt_hook);
  39546. + unregister_break_hook(&kgdb_compiled_brkpt_hook);
  39547. + unregister_step_hook(&kgdb_step_hook);
  39548. + unregister_die_notifier(&kgdb_notifier);
  39549. +}
  39550. +
  39551. +/*
  39552. + * ARM instructions are always in LE.
  39553. + * Break instruction is encoded in LE format
  39554. + */
  39555. +struct kgdb_arch arch_kgdb_ops = {
  39556. + .gdb_bpt_instr = {
  39557. + KGDB_DYN_BRK_INS_BYTE0,
  39558. + KGDB_DYN_BRK_INS_BYTE1,
  39559. + KGDB_DYN_BRK_INS_BYTE2,
  39560. + KGDB_DYN_BRK_INS_BYTE3,
  39561. + }
  39562. +};
  39563. diff -Nur linux-3.14.17/arch/arm64/kernel/Makefile linux-imx6-3.14/arch/arm64/kernel/Makefile
  39564. --- linux-3.14.17/arch/arm64/kernel/Makefile 2014-08-14 03:38:34.000000000 +0200
  39565. +++ linux-imx6-3.14/arch/arm64/kernel/Makefile 2014-09-11 18:05:54.458007828 +0200
  39566. @@ -5,21 +5,29 @@
  39567. CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
  39568. AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
  39569. +CFLAGS_REMOVE_ftrace.o = -pg
  39570. +CFLAGS_REMOVE_insn.o = -pg
  39571. +CFLAGS_REMOVE_return_address.o = -pg
  39572. +
  39573. # Object file lists.
  39574. arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
  39575. entry-fpsimd.o process.o ptrace.o setup.o signal.o \
  39576. sys.o stacktrace.o time.o traps.o io.o vdso.o \
  39577. - hyp-stub.o psci.o cpu_ops.o insn.o
  39578. + hyp-stub.o psci.o cpu_ops.o insn.o return_address.o
  39579. arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
  39580. sys_compat.o
  39581. +arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
  39582. arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
  39583. +arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o
  39584. arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o
  39585. +arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
  39586. arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
  39587. -arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
  39588. +arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
  39589. arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  39590. arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o
  39591. arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
  39592. +arm64-obj-$(CONFIG_KGDB) += kgdb.o
  39593. obj-y += $(arm64-obj-y) vdso/
  39594. obj-m += $(arm64-obj-m)
  39595. diff -Nur linux-3.14.17/arch/arm64/kernel/perf_event.c linux-imx6-3.14/arch/arm64/kernel/perf_event.c
  39596. --- linux-3.14.17/arch/arm64/kernel/perf_event.c 2014-08-14 03:38:34.000000000 +0200
  39597. +++ linux-imx6-3.14/arch/arm64/kernel/perf_event.c 2014-09-11 18:05:54.474007892 +0200
  39598. @@ -1348,8 +1348,8 @@
  39599. * Callchain handling code.
  39600. */
  39601. struct frame_tail {
  39602. - struct frame_tail __user *fp;
  39603. - unsigned long lr;
  39604. + struct frame_tail __user *fp;
  39605. + unsigned long lr;
  39606. } __attribute__((packed));
  39607. /*
  39608. @@ -1386,22 +1386,84 @@
  39609. return buftail.fp;
  39610. }
  39611. +#ifdef CONFIG_COMPAT
  39612. +/*
  39613. + * The registers we're interested in are at the end of the variable
  39614. + * length saved register structure. The fp points at the end of this
  39615. + * structure so the address of this struct is:
  39616. + * (struct compat_frame_tail *)(xxx->fp)-1
  39617. + *
  39618. + * This code has been adapted from the ARM OProfile support.
  39619. + */
  39620. +struct compat_frame_tail {
  39621. + compat_uptr_t fp; /* a (struct compat_frame_tail *) in compat mode */
  39622. + u32 sp;
  39623. + u32 lr;
  39624. +} __attribute__((packed));
  39625. +
  39626. +static struct compat_frame_tail __user *
  39627. +compat_user_backtrace(struct compat_frame_tail __user *tail,
  39628. + struct perf_callchain_entry *entry)
  39629. +{
  39630. + struct compat_frame_tail buftail;
  39631. + unsigned long err;
  39632. +
  39633. + /* Also check accessibility of one struct frame_tail beyond */
  39634. + if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
  39635. + return NULL;
  39636. +
  39637. + pagefault_disable();
  39638. + err = __copy_from_user_inatomic(&buftail, tail, sizeof(buftail));
  39639. + pagefault_enable();
  39640. +
  39641. + if (err)
  39642. + return NULL;
  39643. +
  39644. + perf_callchain_store(entry, buftail.lr);
  39645. +
  39646. + /*
  39647. + * Frame pointers should strictly progress back up the stack
  39648. + * (towards higher addresses).
  39649. + */
  39650. + if (tail + 1 >= (struct compat_frame_tail __user *)
  39651. + compat_ptr(buftail.fp))
  39652. + return NULL;
  39653. +
  39654. + return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1;
  39655. +}
  39656. +#endif /* CONFIG_COMPAT */
  39657. +
  39658. void perf_callchain_user(struct perf_callchain_entry *entry,
  39659. struct pt_regs *regs)
  39660. {
  39661. - struct frame_tail __user *tail;
  39662. -
  39663. if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
  39664. /* We don't support guest os callchain now */
  39665. return;
  39666. }
  39667. perf_callchain_store(entry, regs->pc);
  39668. - tail = (struct frame_tail __user *)regs->regs[29];
  39669. - while (entry->nr < PERF_MAX_STACK_DEPTH &&
  39670. - tail && !((unsigned long)tail & 0xf))
  39671. - tail = user_backtrace(tail, entry);
  39672. + if (!compat_user_mode(regs)) {
  39673. + /* AARCH64 mode */
  39674. + struct frame_tail __user *tail;
  39675. +
  39676. + tail = (struct frame_tail __user *)regs->regs[29];
  39677. +
  39678. + while (entry->nr < PERF_MAX_STACK_DEPTH &&
  39679. + tail && !((unsigned long)tail & 0xf))
  39680. + tail = user_backtrace(tail, entry);
  39681. + } else {
  39682. +#ifdef CONFIG_COMPAT
  39683. + /* AARCH32 compat mode */
  39684. + struct compat_frame_tail __user *tail;
  39685. +
  39686. + tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
  39687. +
  39688. + while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
  39689. + tail && !((unsigned long)tail & 0x3))
  39690. + tail = compat_user_backtrace(tail, entry);
  39691. +#endif
  39692. + }
  39693. }
  39694. /*
  39695. @@ -1429,6 +1491,7 @@
  39696. frame.fp = regs->regs[29];
  39697. frame.sp = regs->sp;
  39698. frame.pc = regs->pc;
  39699. +
  39700. walk_stackframe(&frame, callchain_trace, entry);
  39701. }
  39702. diff -Nur linux-3.14.17/arch/arm64/kernel/perf_regs.c linux-imx6-3.14/arch/arm64/kernel/perf_regs.c
  39703. --- linux-3.14.17/arch/arm64/kernel/perf_regs.c 1970-01-01 01:00:00.000000000 +0100
  39704. +++ linux-imx6-3.14/arch/arm64/kernel/perf_regs.c 2014-09-11 18:05:54.474007892 +0200
  39705. @@ -0,0 +1,46 @@
  39706. +#include <linux/errno.h>
  39707. +#include <linux/kernel.h>
  39708. +#include <linux/perf_event.h>
  39709. +#include <linux/bug.h>
  39710. +
  39711. +#include <asm/compat.h>
  39712. +#include <asm/perf_regs.h>
  39713. +#include <asm/ptrace.h>
  39714. +
  39715. +u64 perf_reg_value(struct pt_regs *regs, int idx)
  39716. +{
  39717. + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX))
  39718. + return 0;
  39719. +
  39720. + /*
  39721. + * Compat (i.e. 32 bit) mode:
  39722. + * - PC has been set in the pt_regs struct in kernel_entry,
  39723. + * - Handle SP and LR here.
  39724. + */
  39725. + if (compat_user_mode(regs)) {
  39726. + if ((u32)idx == PERF_REG_ARM64_SP)
  39727. + return regs->compat_sp;
  39728. + if ((u32)idx == PERF_REG_ARM64_LR)
  39729. + return regs->compat_lr;
  39730. + }
  39731. +
  39732. + return regs->regs[idx];
  39733. +}
  39734. +
  39735. +#define REG_RESERVED (~((1ULL << PERF_REG_ARM64_MAX) - 1))
  39736. +
  39737. +int perf_reg_validate(u64 mask)
  39738. +{
  39739. + if (!mask || mask & REG_RESERVED)
  39740. + return -EINVAL;
  39741. +
  39742. + return 0;
  39743. +}
  39744. +
  39745. +u64 perf_reg_abi(struct task_struct *task)
  39746. +{
  39747. + if (is_compat_thread(task_thread_info(task)))
  39748. + return PERF_SAMPLE_REGS_ABI_32;
  39749. + else
  39750. + return PERF_SAMPLE_REGS_ABI_64;
  39751. +}
  39752. diff -Nur linux-3.14.17/arch/arm64/kernel/process.c linux-imx6-3.14/arch/arm64/kernel/process.c
  39753. --- linux-3.14.17/arch/arm64/kernel/process.c 2014-08-14 03:38:34.000000000 +0200
  39754. +++ linux-imx6-3.14/arch/arm64/kernel/process.c 2014-09-11 18:05:54.474007892 +0200
  39755. @@ -20,6 +20,7 @@
  39756. #include <stdarg.h>
  39757. +#include <linux/compat.h>
  39758. #include <linux/export.h>
  39759. #include <linux/sched.h>
  39760. #include <linux/kernel.h>
  39761. diff -Nur linux-3.14.17/arch/arm64/kernel/ptrace.c linux-imx6-3.14/arch/arm64/kernel/ptrace.c
  39762. --- linux-3.14.17/arch/arm64/kernel/ptrace.c 2014-08-14 03:38:34.000000000 +0200
  39763. +++ linux-imx6-3.14/arch/arm64/kernel/ptrace.c 2014-09-11 18:05:54.474007892 +0200
  39764. @@ -19,6 +19,7 @@
  39765. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39766. */
  39767. +#include <linux/compat.h>
  39768. #include <linux/kernel.h>
  39769. #include <linux/sched.h>
  39770. #include <linux/mm.h>
  39771. @@ -41,6 +42,9 @@
  39772. #include <asm/traps.h>
  39773. #include <asm/system_misc.h>
  39774. +#define CREATE_TRACE_POINTS
  39775. +#include <trace/events/syscalls.h>
  39776. +
  39777. /*
  39778. * TODO: does not yet catch signals sent when the child dies.
  39779. * in exit.c or in signal.c.
  39780. @@ -1072,35 +1076,49 @@
  39781. return ptrace_request(child, request, addr, data);
  39782. }
  39783. -asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
  39784. +enum ptrace_syscall_dir {
  39785. + PTRACE_SYSCALL_ENTER = 0,
  39786. + PTRACE_SYSCALL_EXIT,
  39787. +};
  39788. +
  39789. +static void tracehook_report_syscall(struct pt_regs *regs,
  39790. + enum ptrace_syscall_dir dir)
  39791. {
  39792. + int regno;
  39793. unsigned long saved_reg;
  39794. - if (!test_thread_flag(TIF_SYSCALL_TRACE))
  39795. - return regs->syscallno;
  39796. -
  39797. - if (is_compat_task()) {
  39798. - /* AArch32 uses ip (r12) for scratch */
  39799. - saved_reg = regs->regs[12];
  39800. - regs->regs[12] = dir;
  39801. - } else {
  39802. - /*
  39803. - * Save X7. X7 is used to denote syscall entry/exit:
  39804. - * X7 = 0 -> entry, = 1 -> exit
  39805. - */
  39806. - saved_reg = regs->regs[7];
  39807. - regs->regs[7] = dir;
  39808. - }
  39809. + /*
  39810. + * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
  39811. + * used to denote syscall entry/exit:
  39812. + */
  39813. + regno = (is_compat_task() ? 12 : 7);
  39814. + saved_reg = regs->regs[regno];
  39815. + regs->regs[regno] = dir;
  39816. - if (dir)
  39817. + if (dir == PTRACE_SYSCALL_EXIT)
  39818. tracehook_report_syscall_exit(regs, 0);
  39819. else if (tracehook_report_syscall_entry(regs))
  39820. regs->syscallno = ~0UL;
  39821. - if (is_compat_task())
  39822. - regs->regs[12] = saved_reg;
  39823. - else
  39824. - regs->regs[7] = saved_reg;
  39825. + regs->regs[regno] = saved_reg;
  39826. +}
  39827. +
  39828. +asmlinkage int syscall_trace_enter(struct pt_regs *regs)
  39829. +{
  39830. + if (test_thread_flag(TIF_SYSCALL_TRACE))
  39831. + tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
  39832. +
  39833. + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
  39834. + trace_sys_enter(regs, regs->syscallno);
  39835. return regs->syscallno;
  39836. }
  39837. +
  39838. +asmlinkage void syscall_trace_exit(struct pt_regs *regs)
  39839. +{
  39840. + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
  39841. + trace_sys_exit(regs, regs_return_value(regs));
  39842. +
  39843. + if (test_thread_flag(TIF_SYSCALL_TRACE))
  39844. + tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
  39845. +}
  39846. diff -Nur linux-3.14.17/arch/arm64/kernel/return_address.c linux-imx6-3.14/arch/arm64/kernel/return_address.c
  39847. --- linux-3.14.17/arch/arm64/kernel/return_address.c 1970-01-01 01:00:00.000000000 +0100
  39848. +++ linux-imx6-3.14/arch/arm64/kernel/return_address.c 2014-09-11 18:05:54.474007892 +0200
  39849. @@ -0,0 +1,55 @@
  39850. +/*
  39851. + * arch/arm64/kernel/return_address.c
  39852. + *
  39853. + * Copyright (C) 2013 Linaro Limited
  39854. + * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  39855. + *
  39856. + * This program is free software; you can redistribute it and/or modify
  39857. + * it under the terms of the GNU General Public License version 2 as
  39858. + * published by the Free Software Foundation.
  39859. + */
  39860. +
  39861. +#include <linux/export.h>
  39862. +#include <linux/ftrace.h>
  39863. +
  39864. +#include <asm/stacktrace.h>
  39865. +
  39866. +struct return_address_data {
  39867. + unsigned int level;
  39868. + void *addr;
  39869. +};
  39870. +
  39871. +static int save_return_addr(struct stackframe *frame, void *d)
  39872. +{
  39873. + struct return_address_data *data = d;
  39874. +
  39875. + if (!data->level) {
  39876. + data->addr = (void *)frame->pc;
  39877. + return 1;
  39878. + } else {
  39879. + --data->level;
  39880. + return 0;
  39881. + }
  39882. +}
  39883. +
  39884. +void *return_address(unsigned int level)
  39885. +{
  39886. + struct return_address_data data;
  39887. + struct stackframe frame;
  39888. + register unsigned long current_sp asm ("sp");
  39889. +
  39890. + data.level = level + 2;
  39891. + data.addr = NULL;
  39892. +
  39893. + frame.fp = (unsigned long)__builtin_frame_address(0);
  39894. + frame.sp = current_sp;
  39895. + frame.pc = (unsigned long)return_address; /* dummy */
  39896. +
  39897. + walk_stackframe(&frame, save_return_addr, &data);
  39898. +
  39899. + if (!data.level)
  39900. + return data.addr;
  39901. + else
  39902. + return NULL;
  39903. +}
  39904. +EXPORT_SYMBOL_GPL(return_address);
  39905. diff -Nur linux-3.14.17/arch/arm64/kernel/setup.c linux-imx6-3.14/arch/arm64/kernel/setup.c
  39906. --- linux-3.14.17/arch/arm64/kernel/setup.c 2014-08-14 03:38:34.000000000 +0200
  39907. +++ linux-imx6-3.14/arch/arm64/kernel/setup.c 2014-09-11 18:05:54.474007892 +0200
  39908. @@ -69,6 +69,7 @@
  39909. COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\
  39910. COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV)
  39911. unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT;
  39912. +unsigned int compat_elf_hwcap2 __read_mostly;
  39913. #endif
  39914. static const char *cpu_name;
  39915. @@ -242,6 +243,38 @@
  39916. block = (features >> 16) & 0xf;
  39917. if (block && !(block & 0x8))
  39918. elf_hwcap |= HWCAP_CRC32;
  39919. +
  39920. +#ifdef CONFIG_COMPAT
  39921. + /*
  39922. + * ID_ISAR5_EL1 carries similar information as above, but pertaining to
  39923. + * the Aarch32 32-bit execution state.
  39924. + */
  39925. + features = read_cpuid(ID_ISAR5_EL1);
  39926. + block = (features >> 4) & 0xf;
  39927. + if (!(block & 0x8)) {
  39928. + switch (block) {
  39929. + default:
  39930. + case 2:
  39931. + compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL;
  39932. + case 1:
  39933. + compat_elf_hwcap2 |= COMPAT_HWCAP2_AES;
  39934. + case 0:
  39935. + break;
  39936. + }
  39937. + }
  39938. +
  39939. + block = (features >> 8) & 0xf;
  39940. + if (block && !(block & 0x8))
  39941. + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
  39942. +
  39943. + block = (features >> 12) & 0xf;
  39944. + if (block && !(block & 0x8))
  39945. + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
  39946. +
  39947. + block = (features >> 16) & 0xf;
  39948. + if (block && !(block & 0x8))
  39949. + compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
  39950. +#endif
  39951. }
  39952. static void __init setup_machine_fdt(phys_addr_t dt_phys)
  39953. @@ -360,7 +393,7 @@
  39954. of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  39955. return 0;
  39956. }
  39957. -arch_initcall(arm64_device_init);
  39958. +arch_initcall_sync(arm64_device_init);
  39959. static DEFINE_PER_CPU(struct cpu, cpu_data);
  39960. diff -Nur linux-3.14.17/arch/arm64/kernel/signal.c linux-imx6-3.14/arch/arm64/kernel/signal.c
  39961. --- linux-3.14.17/arch/arm64/kernel/signal.c 2014-08-14 03:38:34.000000000 +0200
  39962. +++ linux-imx6-3.14/arch/arm64/kernel/signal.c 2014-09-11 18:05:54.474007892 +0200
  39963. @@ -17,6 +17,7 @@
  39964. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  39965. */
  39966. +#include <linux/compat.h>
  39967. #include <linux/errno.h>
  39968. #include <linux/signal.h>
  39969. #include <linux/personality.h>
  39970. @@ -25,7 +26,6 @@
  39971. #include <linux/tracehook.h>
  39972. #include <linux/ratelimit.h>
  39973. -#include <asm/compat.h>
  39974. #include <asm/debug-monitors.h>
  39975. #include <asm/elf.h>
  39976. #include <asm/cacheflush.h>
  39977. diff -Nur linux-3.14.17/arch/arm64/kernel/smp.c linux-imx6-3.14/arch/arm64/kernel/smp.c
  39978. --- linux-3.14.17/arch/arm64/kernel/smp.c 2014-08-14 03:38:34.000000000 +0200
  39979. +++ linux-imx6-3.14/arch/arm64/kernel/smp.c 2014-09-11 18:05:54.474007892 +0200
  39980. @@ -114,6 +114,11 @@
  39981. return ret;
  39982. }
  39983. +static void smp_store_cpu_info(unsigned int cpuid)
  39984. +{
  39985. + store_cpu_topology(cpuid);
  39986. +}
  39987. +
  39988. /*
  39989. * This is the secondary CPU boot entry. We're using this CPUs
  39990. * idle thread stack, but a set of temporary page tables.
  39991. @@ -152,6 +157,8 @@
  39992. */
  39993. notify_cpu_starting(cpu);
  39994. + smp_store_cpu_info(cpu);
  39995. +
  39996. /*
  39997. * OK, now it's safe to let the boot CPU continue. Wait for
  39998. * the CPU migration code to notice that the CPU is online
  39999. @@ -390,6 +397,10 @@
  40000. int err;
  40001. unsigned int cpu, ncores = num_possible_cpus();
  40002. + init_cpu_topology();
  40003. +
  40004. + smp_store_cpu_info(smp_processor_id());
  40005. +
  40006. /*
  40007. * are we trying to boot more cores than exist?
  40008. */
  40009. diff -Nur linux-3.14.17/arch/arm64/kernel/stacktrace.c linux-imx6-3.14/arch/arm64/kernel/stacktrace.c
  40010. --- linux-3.14.17/arch/arm64/kernel/stacktrace.c 2014-08-14 03:38:34.000000000 +0200
  40011. +++ linux-imx6-3.14/arch/arm64/kernel/stacktrace.c 2014-09-11 18:05:54.474007892 +0200
  40012. @@ -35,7 +35,7 @@
  40013. * ldp x29, x30, [sp]
  40014. * add sp, sp, #0x10
  40015. */
  40016. -int unwind_frame(struct stackframe *frame)
  40017. +int notrace unwind_frame(struct stackframe *frame)
  40018. {
  40019. unsigned long high, low;
  40020. unsigned long fp = frame->fp;
  40021. diff -Nur linux-3.14.17/arch/arm64/kernel/topology.c linux-imx6-3.14/arch/arm64/kernel/topology.c
  40022. --- linux-3.14.17/arch/arm64/kernel/topology.c 1970-01-01 01:00:00.000000000 +0100
  40023. +++ linux-imx6-3.14/arch/arm64/kernel/topology.c 2014-09-11 18:05:54.478007908 +0200
  40024. @@ -0,0 +1,558 @@
  40025. +/*
  40026. + * arch/arm64/kernel/topology.c
  40027. + *
  40028. + * Copyright (C) 2011,2013,2014 Linaro Limited.
  40029. + *
  40030. + * Based on the arm32 version written by Vincent Guittot in turn based on
  40031. + * arch/sh/kernel/topology.c
  40032. + *
  40033. + * This file is subject to the terms and conditions of the GNU General Public
  40034. + * License. See the file "COPYING" in the main directory of this archive
  40035. + * for more details.
  40036. + */
  40037. +
  40038. +#include <linux/cpu.h>
  40039. +#include <linux/cpumask.h>
  40040. +#include <linux/init.h>
  40041. +#include <linux/percpu.h>
  40042. +#include <linux/node.h>
  40043. +#include <linux/nodemask.h>
  40044. +#include <linux/of.h>
  40045. +#include <linux/sched.h>
  40046. +#include <linux/slab.h>
  40047. +
  40048. +#include <asm/topology.h>
  40049. +
  40050. +/*
  40051. + * cpu power table
  40052. + * This per cpu data structure describes the relative capacity of each core.
  40053. + * On a heteregenous system, cores don't have the same computation capacity
  40054. + * and we reflect that difference in the cpu_power field so the scheduler can
  40055. + * take this difference into account during load balance. A per cpu structure
  40056. + * is preferred because each CPU updates its own cpu_power field during the
  40057. + * load balance except for idle cores. One idle core is selected to run the
  40058. + * rebalance_domains for all idle cores and the cpu_power can be updated
  40059. + * during this sequence.
  40060. + */
  40061. +static DEFINE_PER_CPU(unsigned long, cpu_scale);
  40062. +
  40063. +unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
  40064. +{
  40065. + return per_cpu(cpu_scale, cpu);
  40066. +}
  40067. +
  40068. +static void set_power_scale(unsigned int cpu, unsigned long power)
  40069. +{
  40070. + per_cpu(cpu_scale, cpu) = power;
  40071. +}
  40072. +
  40073. +static int __init get_cpu_for_node(struct device_node *node)
  40074. +{
  40075. + struct device_node *cpu_node;
  40076. + int cpu;
  40077. +
  40078. + cpu_node = of_parse_phandle(node, "cpu", 0);
  40079. + if (!cpu_node)
  40080. + return -1;
  40081. +
  40082. + for_each_possible_cpu(cpu) {
  40083. + if (of_get_cpu_node(cpu, NULL) == cpu_node) {
  40084. + of_node_put(cpu_node);
  40085. + return cpu;
  40086. + }
  40087. + }
  40088. +
  40089. + pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
  40090. +
  40091. + of_node_put(cpu_node);
  40092. + return -1;
  40093. +}
  40094. +
  40095. +static int __init parse_core(struct device_node *core, int cluster_id,
  40096. + int core_id)
  40097. +{
  40098. + char name[10];
  40099. + bool leaf = true;
  40100. + int i = 0;
  40101. + int cpu;
  40102. + struct device_node *t;
  40103. +
  40104. + do {
  40105. + snprintf(name, sizeof(name), "thread%d", i);
  40106. + t = of_get_child_by_name(core, name);
  40107. + if (t) {
  40108. + leaf = false;
  40109. + cpu = get_cpu_for_node(t);
  40110. + if (cpu >= 0) {
  40111. + cpu_topology[cpu].cluster_id = cluster_id;
  40112. + cpu_topology[cpu].core_id = core_id;
  40113. + cpu_topology[cpu].thread_id = i;
  40114. + } else {
  40115. + pr_err("%s: Can't get CPU for thread\n",
  40116. + t->full_name);
  40117. + of_node_put(t);
  40118. + return -EINVAL;
  40119. + }
  40120. + of_node_put(t);
  40121. + }
  40122. + i++;
  40123. + } while (t);
  40124. +
  40125. + cpu = get_cpu_for_node(core);
  40126. + if (cpu >= 0) {
  40127. + if (!leaf) {
  40128. + pr_err("%s: Core has both threads and CPU\n",
  40129. + core->full_name);
  40130. + return -EINVAL;
  40131. + }
  40132. +
  40133. + cpu_topology[cpu].cluster_id = cluster_id;
  40134. + cpu_topology[cpu].core_id = core_id;
  40135. + } else if (leaf) {
  40136. + pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
  40137. + return -EINVAL;
  40138. + }
  40139. +
  40140. + return 0;
  40141. +}
  40142. +
  40143. +static int __init parse_cluster(struct device_node *cluster, int depth)
  40144. +{
  40145. + char name[10];
  40146. + bool leaf = true;
  40147. + bool has_cores = false;
  40148. + struct device_node *c;
  40149. + static int cluster_id __initdata;
  40150. + int core_id = 0;
  40151. + int i, ret;
  40152. +
  40153. + /*
  40154. + * First check for child clusters; we currently ignore any
  40155. + * information about the nesting of clusters and present the
  40156. + * scheduler with a flat list of them.
  40157. + */
  40158. + i = 0;
  40159. + do {
  40160. + snprintf(name, sizeof(name), "cluster%d", i);
  40161. + c = of_get_child_by_name(cluster, name);
  40162. + if (c) {
  40163. + leaf = false;
  40164. + ret = parse_cluster(c, depth + 1);
  40165. + of_node_put(c);
  40166. + if (ret != 0)
  40167. + return ret;
  40168. + }
  40169. + i++;
  40170. + } while (c);
  40171. +
  40172. + /* Now check for cores */
  40173. + i = 0;
  40174. + do {
  40175. + snprintf(name, sizeof(name), "core%d", i);
  40176. + c = of_get_child_by_name(cluster, name);
  40177. + if (c) {
  40178. + has_cores = true;
  40179. +
  40180. + if (depth == 0) {
  40181. + pr_err("%s: cpu-map children should be clusters\n",
  40182. + c->full_name);
  40183. + of_node_put(c);
  40184. + return -EINVAL;
  40185. + }
  40186. +
  40187. + if (leaf) {
  40188. + ret = parse_core(c, cluster_id, core_id++);
  40189. + } else {
  40190. + pr_err("%s: Non-leaf cluster with core %s\n",
  40191. + cluster->full_name, name);
  40192. + ret = -EINVAL;
  40193. + }
  40194. +
  40195. + of_node_put(c);
  40196. + if (ret != 0)
  40197. + return ret;
  40198. + }
  40199. + i++;
  40200. + } while (c);
  40201. +
  40202. + if (leaf && !has_cores)
  40203. + pr_warn("%s: empty cluster\n", cluster->full_name);
  40204. +
  40205. + if (leaf)
  40206. + cluster_id++;
  40207. +
  40208. + return 0;
  40209. +}
  40210. +
  40211. +struct cpu_efficiency {
  40212. + const char *compatible;
  40213. + unsigned long efficiency;
  40214. +};
  40215. +
  40216. +/*
  40217. + * Table of relative efficiency of each processors
  40218. + * The efficiency value must fit in 20bit and the final
  40219. + * cpu_scale value must be in the range
  40220. + * 0 < cpu_scale < 3*SCHED_POWER_SCALE/2
  40221. + * in order to return at most 1 when DIV_ROUND_CLOSEST
  40222. + * is used to compute the capacity of a CPU.
  40223. + * Processors that are not defined in the table,
  40224. + * use the default SCHED_POWER_SCALE value for cpu_scale.
  40225. + */
  40226. +static const struct cpu_efficiency table_efficiency[] = {
  40227. + { "arm,cortex-a57", 3891 },
  40228. + { "arm,cortex-a53", 2048 },
  40229. + { NULL, },
  40230. +};
  40231. +
  40232. +static unsigned long *__cpu_capacity;
  40233. +#define cpu_capacity(cpu) __cpu_capacity[cpu]
  40234. +
  40235. +static unsigned long middle_capacity = 1;
  40236. +
  40237. +/*
  40238. + * Iterate all CPUs' descriptor in DT and compute the efficiency
  40239. + * (as per table_efficiency). Also calculate a middle efficiency
  40240. + * as close as possible to (max{eff_i} - min{eff_i}) / 2
  40241. + * This is later used to scale the cpu_power field such that an
  40242. + * 'average' CPU is of middle power. Also see the comments near
  40243. + * table_efficiency[] and update_cpu_power().
  40244. + */
  40245. +static int __init parse_dt_topology(void)
  40246. +{
  40247. + struct device_node *cn, *map;
  40248. + int ret = 0;
  40249. + int cpu;
  40250. +
  40251. + cn = of_find_node_by_path("/cpus");
  40252. + if (!cn) {
  40253. + pr_err("No CPU information found in DT\n");
  40254. + return 0;
  40255. + }
  40256. +
  40257. + /*
  40258. + * When topology is provided cpu-map is essentially a root
  40259. + * cluster with restricted subnodes.
  40260. + */
  40261. + map = of_get_child_by_name(cn, "cpu-map");
  40262. + if (!map)
  40263. + goto out;
  40264. +
  40265. + ret = parse_cluster(map, 0);
  40266. + if (ret != 0)
  40267. + goto out_map;
  40268. +
  40269. + /*
  40270. + * Check that all cores are in the topology; the SMP code will
  40271. + * only mark cores described in the DT as possible.
  40272. + */
  40273. + for_each_possible_cpu(cpu) {
  40274. + if (cpu_topology[cpu].cluster_id == -1) {
  40275. + pr_err("CPU%d: No topology information specified\n",
  40276. + cpu);
  40277. + ret = -EINVAL;
  40278. + }
  40279. + }
  40280. +
  40281. +out_map:
  40282. + of_node_put(map);
  40283. +out:
  40284. + of_node_put(cn);
  40285. + return ret;
  40286. +}
  40287. +
  40288. +static void __init parse_dt_cpu_power(void)
  40289. +{
  40290. + const struct cpu_efficiency *cpu_eff;
  40291. + struct device_node *cn;
  40292. + unsigned long min_capacity = ULONG_MAX;
  40293. + unsigned long max_capacity = 0;
  40294. + unsigned long capacity = 0;
  40295. + int cpu;
  40296. +
  40297. + __cpu_capacity = kcalloc(nr_cpu_ids, sizeof(*__cpu_capacity),
  40298. + GFP_NOWAIT);
  40299. +
  40300. + for_each_possible_cpu(cpu) {
  40301. + const u32 *rate;
  40302. + int len;
  40303. +
  40304. + /* Too early to use cpu->of_node */
  40305. + cn = of_get_cpu_node(cpu, NULL);
  40306. + if (!cn) {
  40307. + pr_err("Missing device node for CPU %d\n", cpu);
  40308. + continue;
  40309. + }
  40310. +
  40311. + for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
  40312. + if (of_device_is_compatible(cn, cpu_eff->compatible))
  40313. + break;
  40314. +
  40315. + if (cpu_eff->compatible == NULL) {
  40316. + pr_warn("%s: Unknown CPU type\n", cn->full_name);
  40317. + continue;
  40318. + }
  40319. +
  40320. + rate = of_get_property(cn, "clock-frequency", &len);
  40321. + if (!rate || len != 4) {
  40322. + pr_err("%s: Missing clock-frequency property\n",
  40323. + cn->full_name);
  40324. + continue;
  40325. + }
  40326. +
  40327. + capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
  40328. +
  40329. + /* Save min capacity of the system */
  40330. + if (capacity < min_capacity)
  40331. + min_capacity = capacity;
  40332. +
  40333. + /* Save max capacity of the system */
  40334. + if (capacity > max_capacity)
  40335. + max_capacity = capacity;
  40336. +
  40337. + cpu_capacity(cpu) = capacity;
  40338. + }
  40339. +
  40340. + /* If min and max capacities are equal we bypass the update of the
  40341. + * cpu_scale because all CPUs have the same capacity. Otherwise, we
  40342. + * compute a middle_capacity factor that will ensure that the capacity
  40343. + * of an 'average' CPU of the system will be as close as possible to
  40344. + * SCHED_POWER_SCALE, which is the default value, but with the
  40345. + * constraint explained near table_efficiency[].
  40346. + */
  40347. + if (min_capacity == max_capacity)
  40348. + return;
  40349. + else if (4 * max_capacity < (3 * (max_capacity + min_capacity)))
  40350. + middle_capacity = (min_capacity + max_capacity)
  40351. + >> (SCHED_POWER_SHIFT+1);
  40352. + else
  40353. + middle_capacity = ((max_capacity / 3)
  40354. + >> (SCHED_POWER_SHIFT-1)) + 1;
  40355. +}
  40356. +
  40357. +/*
  40358. + * Look for a customed capacity of a CPU in the cpu_topo_data table during the
  40359. + * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
  40360. + * function returns directly for SMP system.
  40361. + */
  40362. +static void update_cpu_power(unsigned int cpu)
  40363. +{
  40364. + if (!cpu_capacity(cpu))
  40365. + return;
  40366. +
  40367. + set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
  40368. +
  40369. + pr_info("CPU%u: update cpu_power %lu\n",
  40370. + cpu, arch_scale_freq_power(NULL, cpu));
  40371. +}
  40372. +
  40373. +/*
  40374. + * cpu topology table
  40375. + */
  40376. +struct cpu_topology cpu_topology[NR_CPUS];
  40377. +EXPORT_SYMBOL_GPL(cpu_topology);
  40378. +
  40379. +const struct cpumask *cpu_coregroup_mask(int cpu)
  40380. +{
  40381. + return &cpu_topology[cpu].core_sibling;
  40382. +}
  40383. +
  40384. +static void update_siblings_masks(unsigned int cpuid)
  40385. +{
  40386. + struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
  40387. + int cpu;
  40388. +
  40389. + if (cpuid_topo->cluster_id == -1) {
  40390. + /*
  40391. + * DT does not contain topology information for this cpu.
  40392. + */
  40393. + pr_debug("CPU%u: No topology information configured\n", cpuid);
  40394. + return;
  40395. + }
  40396. +
  40397. + /* update core and thread sibling masks */
  40398. + for_each_possible_cpu(cpu) {
  40399. + cpu_topo = &cpu_topology[cpu];
  40400. +
  40401. + if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
  40402. + continue;
  40403. +
  40404. + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
  40405. + if (cpu != cpuid)
  40406. + cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
  40407. +
  40408. + if (cpuid_topo->core_id != cpu_topo->core_id)
  40409. + continue;
  40410. +
  40411. + cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
  40412. + if (cpu != cpuid)
  40413. + cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
  40414. + }
  40415. +}
  40416. +
  40417. +void store_cpu_topology(unsigned int cpuid)
  40418. +{
  40419. + update_siblings_masks(cpuid);
  40420. + update_cpu_power(cpuid);
  40421. +}
  40422. +
  40423. +#ifdef CONFIG_SCHED_HMP
  40424. +
  40425. +/*
  40426. + * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
  40427. + * - mpidr: MPIDR[23:0] to be used for the look-up
  40428. + *
  40429. + * Returns the cpu logical index or -EINVAL on look-up error
  40430. + */
  40431. +static inline int get_logical_index(u32 mpidr)
  40432. +{
  40433. + int cpu;
  40434. + for (cpu = 0; cpu < nr_cpu_ids; cpu++)
  40435. + if (cpu_logical_map(cpu) == mpidr)
  40436. + return cpu;
  40437. + return -EINVAL;
  40438. +}
  40439. +
  40440. +static const char * const little_cores[] = {
  40441. + "arm,cortex-a53",
  40442. + NULL,
  40443. +};
  40444. +
  40445. +static bool is_little_cpu(struct device_node *cn)
  40446. +{
  40447. + const char * const *lc;
  40448. + for (lc = little_cores; *lc; lc++)
  40449. + if (of_device_is_compatible(cn, *lc))
  40450. + return true;
  40451. + return false;
  40452. +}
  40453. +
  40454. +void __init arch_get_fast_and_slow_cpus(struct cpumask *fast,
  40455. + struct cpumask *slow)
  40456. +{
  40457. + struct device_node *cn = NULL;
  40458. + int cpu;
  40459. +
  40460. + cpumask_clear(fast);
  40461. + cpumask_clear(slow);
  40462. +
  40463. + /*
  40464. + * Use the config options if they are given. This helps testing
  40465. + * HMP scheduling on systems without a big.LITTLE architecture.
  40466. + */
  40467. + if (strlen(CONFIG_HMP_FAST_CPU_MASK) && strlen(CONFIG_HMP_SLOW_CPU_MASK)) {
  40468. + if (cpulist_parse(CONFIG_HMP_FAST_CPU_MASK, fast))
  40469. + WARN(1, "Failed to parse HMP fast cpu mask!\n");
  40470. + if (cpulist_parse(CONFIG_HMP_SLOW_CPU_MASK, slow))
  40471. + WARN(1, "Failed to parse HMP slow cpu mask!\n");
  40472. + return;
  40473. + }
  40474. +
  40475. + /*
  40476. + * Else, parse device tree for little cores.
  40477. + */
  40478. + while ((cn = of_find_node_by_type(cn, "cpu"))) {
  40479. +
  40480. + const u32 *mpidr;
  40481. + int len;
  40482. +
  40483. + mpidr = of_get_property(cn, "reg", &len);
  40484. + if (!mpidr || len != 8) {
  40485. + pr_err("%s missing reg property\n", cn->full_name);
  40486. + continue;
  40487. + }
  40488. +
  40489. + cpu = get_logical_index(be32_to_cpup(mpidr+1));
  40490. + if (cpu == -EINVAL) {
  40491. + pr_err("couldn't get logical index for mpidr %x\n",
  40492. + be32_to_cpup(mpidr+1));
  40493. + break;
  40494. + }
  40495. +
  40496. + if (is_little_cpu(cn))
  40497. + cpumask_set_cpu(cpu, slow);
  40498. + else
  40499. + cpumask_set_cpu(cpu, fast);
  40500. + }
  40501. +
  40502. + if (!cpumask_empty(fast) && !cpumask_empty(slow))
  40503. + return;
  40504. +
  40505. + /*
  40506. + * We didn't find both big and little cores so let's call all cores
  40507. + * fast as this will keep the system running, with all cores being
  40508. + * treated equal.
  40509. + */
  40510. + cpumask_setall(fast);
  40511. + cpumask_clear(slow);
  40512. +}
  40513. +
  40514. +struct cpumask hmp_slow_cpu_mask;
  40515. +
  40516. +void __init arch_get_hmp_domains(struct list_head *hmp_domains_list)
  40517. +{
  40518. + struct cpumask hmp_fast_cpu_mask;
  40519. + struct hmp_domain *domain;
  40520. +
  40521. + arch_get_fast_and_slow_cpus(&hmp_fast_cpu_mask, &hmp_slow_cpu_mask);
  40522. +
  40523. + /*
  40524. + * Initialize hmp_domains
  40525. + * Must be ordered with respect to compute capacity.
  40526. + * Fastest domain at head of list.
  40527. + */
  40528. + if(!cpumask_empty(&hmp_slow_cpu_mask)) {
  40529. + domain = (struct hmp_domain *)
  40530. + kmalloc(sizeof(struct hmp_domain), GFP_KERNEL);
  40531. + cpumask_copy(&domain->possible_cpus, &hmp_slow_cpu_mask);
  40532. + cpumask_and(&domain->cpus, cpu_online_mask, &domain->possible_cpus);
  40533. + list_add(&domain->hmp_domains, hmp_domains_list);
  40534. + }
  40535. + domain = (struct hmp_domain *)
  40536. + kmalloc(sizeof(struct hmp_domain), GFP_KERNEL);
  40537. + cpumask_copy(&domain->possible_cpus, &hmp_fast_cpu_mask);
  40538. + cpumask_and(&domain->cpus, cpu_online_mask, &domain->possible_cpus);
  40539. + list_add(&domain->hmp_domains, hmp_domains_list);
  40540. +}
  40541. +#endif /* CONFIG_SCHED_HMP */
  40542. +
  40543. +static void __init reset_cpu_topology(void)
  40544. +{
  40545. + unsigned int cpu;
  40546. +
  40547. + for_each_possible_cpu(cpu) {
  40548. + struct cpu_topology *cpu_topo = &cpu_topology[cpu];
  40549. +
  40550. + cpu_topo->thread_id = -1;
  40551. + cpu_topo->core_id = 0;
  40552. + cpu_topo->cluster_id = -1;
  40553. +
  40554. + cpumask_clear(&cpu_topo->core_sibling);
  40555. + cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
  40556. + cpumask_clear(&cpu_topo->thread_sibling);
  40557. + cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
  40558. + }
  40559. +}
  40560. +
  40561. +static void __init reset_cpu_power(void)
  40562. +{
  40563. + unsigned int cpu;
  40564. +
  40565. + for_each_possible_cpu(cpu)
  40566. + set_power_scale(cpu, SCHED_POWER_SCALE);
  40567. +}
  40568. +
  40569. +void __init init_cpu_topology(void)
  40570. +{
  40571. + reset_cpu_topology();
  40572. +
  40573. + /*
  40574. + * Discard anything that was parsed if we hit an error so we
  40575. + * don't use partial information.
  40576. + */
  40577. + if (parse_dt_topology())
  40578. + reset_cpu_topology();
  40579. +
  40580. + reset_cpu_power();
  40581. + parse_dt_cpu_power();
  40582. +}
  40583. diff -Nur linux-3.14.17/arch/arm64/kernel/vdso/Makefile linux-imx6-3.14/arch/arm64/kernel/vdso/Makefile
  40584. --- linux-3.14.17/arch/arm64/kernel/vdso/Makefile 2014-08-14 03:38:34.000000000 +0200
  40585. +++ linux-imx6-3.14/arch/arm64/kernel/vdso/Makefile 2014-09-11 18:05:54.478007908 +0200
  40586. @@ -47,9 +47,9 @@
  40587. $(call if_changed_dep,vdsoas)
  40588. # Actual build commands
  40589. -quiet_cmd_vdsold = VDSOL $@
  40590. +quiet_cmd_vdsold = VDSOL $@
  40591. cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@
  40592. -quiet_cmd_vdsoas = VDSOA $@
  40593. +quiet_cmd_vdsoas = VDSOA $@
  40594. cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
  40595. # Install commands for the unstripped file
  40596. diff -Nur linux-3.14.17/arch/arm64/kernel/vdso.c linux-imx6-3.14/arch/arm64/kernel/vdso.c
  40597. --- linux-3.14.17/arch/arm64/kernel/vdso.c 2014-08-14 03:38:34.000000000 +0200
  40598. +++ linux-imx6-3.14/arch/arm64/kernel/vdso.c 2014-09-11 18:05:54.478007908 +0200
  40599. @@ -156,11 +156,12 @@
  40600. int uses_interp)
  40601. {
  40602. struct mm_struct *mm = current->mm;
  40603. - unsigned long vdso_base, vdso_mapping_len;
  40604. + unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
  40605. int ret;
  40606. + vdso_text_len = vdso_pages << PAGE_SHIFT;
  40607. /* Be sure to map the data page */
  40608. - vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
  40609. + vdso_mapping_len = vdso_text_len + PAGE_SIZE;
  40610. down_write(&mm->mmap_sem);
  40611. vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
  40612. @@ -170,35 +171,52 @@
  40613. }
  40614. mm->context.vdso = (void *)vdso_base;
  40615. - ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
  40616. + ret = install_special_mapping(mm, vdso_base, vdso_text_len,
  40617. VM_READ|VM_EXEC|
  40618. VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
  40619. vdso_pagelist);
  40620. - if (ret) {
  40621. - mm->context.vdso = NULL;
  40622. + if (ret)
  40623. + goto up_fail;
  40624. +
  40625. + vdso_base += vdso_text_len;
  40626. + ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
  40627. + VM_READ|VM_MAYREAD,
  40628. + vdso_pagelist + vdso_pages);
  40629. + if (ret)
  40630. goto up_fail;
  40631. - }
  40632. -up_fail:
  40633. up_write(&mm->mmap_sem);
  40634. + return 0;
  40635. +up_fail:
  40636. + mm->context.vdso = NULL;
  40637. + up_write(&mm->mmap_sem);
  40638. return ret;
  40639. }
  40640. const char *arch_vma_name(struct vm_area_struct *vma)
  40641. {
  40642. + unsigned long vdso_text;
  40643. +
  40644. + if (!vma->vm_mm)
  40645. + return NULL;
  40646. +
  40647. + vdso_text = (unsigned long)vma->vm_mm->context.vdso;
  40648. +
  40649. /*
  40650. * We can re-use the vdso pointer in mm_context_t for identifying
  40651. * the vectors page for compat applications. The vDSO will always
  40652. * sit above TASK_UNMAPPED_BASE and so we don't need to worry about
  40653. * it conflicting with the vectors base.
  40654. */
  40655. - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) {
  40656. + if (vma->vm_start == vdso_text) {
  40657. #ifdef CONFIG_COMPAT
  40658. if (vma->vm_start == AARCH32_VECTORS_BASE)
  40659. return "[vectors]";
  40660. #endif
  40661. return "[vdso]";
  40662. + } else if (vma->vm_start == (vdso_text + (vdso_pages << PAGE_SHIFT))) {
  40663. + return "[vvar]";
  40664. }
  40665. return NULL;
  40666. diff -Nur linux-3.14.17/arch/arm64/kernel/vmlinux.lds.S linux-imx6-3.14/arch/arm64/kernel/vmlinux.lds.S
  40667. --- linux-3.14.17/arch/arm64/kernel/vmlinux.lds.S 2014-08-14 03:38:34.000000000 +0200
  40668. +++ linux-imx6-3.14/arch/arm64/kernel/vmlinux.lds.S 2014-09-11 18:05:54.478007908 +0200
  40669. @@ -104,6 +104,13 @@
  40670. _edata = .;
  40671. BSS_SECTION(0, 0, 0)
  40672. +
  40673. + . = ALIGN(PAGE_SIZE);
  40674. + idmap_pg_dir = .;
  40675. + . += IDMAP_DIR_SIZE;
  40676. + swapper_pg_dir = .;
  40677. + . += SWAPPER_DIR_SIZE;
  40678. +
  40679. _end = .;
  40680. STABS_DEBUG
  40681. diff -Nur linux-3.14.17/arch/arm64/Makefile linux-imx6-3.14/arch/arm64/Makefile
  40682. --- linux-3.14.17/arch/arm64/Makefile 2014-08-14 03:38:34.000000000 +0200
  40683. +++ linux-imx6-3.14/arch/arm64/Makefile 2014-09-11 18:05:54.354007412 +0200
  40684. @@ -45,6 +45,7 @@
  40685. core-y += arch/arm64/kernel/ arch/arm64/mm/
  40686. core-$(CONFIG_KVM) += arch/arm64/kvm/
  40687. core-$(CONFIG_XEN) += arch/arm64/xen/
  40688. +core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
  40689. libs-y := arch/arm64/lib/ $(libs-y)
  40690. libs-y += $(LIBGCC)
  40691. diff -Nur linux-3.14.17/arch/arm64/mm/cache.S linux-imx6-3.14/arch/arm64/mm/cache.S
  40692. --- linux-3.14.17/arch/arm64/mm/cache.S 2014-08-14 03:38:34.000000000 +0200
  40693. +++ linux-imx6-3.14/arch/arm64/mm/cache.S 2014-09-11 18:05:54.486007940 +0200
  40694. @@ -30,7 +30,7 @@
  40695. *
  40696. * Corrupted registers: x0-x7, x9-x11
  40697. */
  40698. -ENTRY(__flush_dcache_all)
  40699. +__flush_dcache_all:
  40700. dsb sy // ensure ordering with previous memory accesses
  40701. mrs x0, clidr_el1 // read clidr
  40702. and x3, x0, #0x7000000 // extract loc from clidr
  40703. @@ -166,3 +166,97 @@
  40704. dsb sy
  40705. ret
  40706. ENDPROC(__flush_dcache_area)
  40707. +
  40708. +/*
  40709. + * __inval_cache_range(start, end)
  40710. + * - start - start address of region
  40711. + * - end - end address of region
  40712. + */
  40713. +ENTRY(__inval_cache_range)
  40714. + /* FALLTHROUGH */
  40715. +
  40716. +/*
  40717. + * __dma_inv_range(start, end)
  40718. + * - start - virtual start address of region
  40719. + * - end - virtual end address of region
  40720. + */
  40721. +__dma_inv_range:
  40722. + dcache_line_size x2, x3
  40723. + sub x3, x2, #1
  40724. + tst x1, x3 // end cache line aligned?
  40725. + bic x1, x1, x3
  40726. + b.eq 1f
  40727. + dc civac, x1 // clean & invalidate D / U line
  40728. +1: tst x0, x3 // start cache line aligned?
  40729. + bic x0, x0, x3
  40730. + b.eq 2f
  40731. + dc civac, x0 // clean & invalidate D / U line
  40732. + b 3f
  40733. +2: dc ivac, x0 // invalidate D / U line
  40734. +3: add x0, x0, x2
  40735. + cmp x0, x1
  40736. + b.lo 2b
  40737. + dsb sy
  40738. + ret
  40739. +ENDPROC(__inval_cache_range)
  40740. +ENDPROC(__dma_inv_range)
  40741. +
  40742. +/*
  40743. + * __dma_clean_range(start, end)
  40744. + * - start - virtual start address of region
  40745. + * - end - virtual end address of region
  40746. + */
  40747. +__dma_clean_range:
  40748. + dcache_line_size x2, x3
  40749. + sub x3, x2, #1
  40750. + bic x0, x0, x3
  40751. +1: dc cvac, x0 // clean D / U line
  40752. + add x0, x0, x2
  40753. + cmp x0, x1
  40754. + b.lo 1b
  40755. + dsb sy
  40756. + ret
  40757. +ENDPROC(__dma_clean_range)
  40758. +
  40759. +/*
  40760. + * __dma_flush_range(start, end)
  40761. + * - start - virtual start address of region
  40762. + * - end - virtual end address of region
  40763. + */
  40764. +ENTRY(__dma_flush_range)
  40765. + dcache_line_size x2, x3
  40766. + sub x3, x2, #1
  40767. + bic x0, x0, x3
  40768. +1: dc civac, x0 // clean & invalidate D / U line
  40769. + add x0, x0, x2
  40770. + cmp x0, x1
  40771. + b.lo 1b
  40772. + dsb sy
  40773. + ret
  40774. +ENDPROC(__dma_flush_range)
  40775. +
  40776. +/*
  40777. + * __dma_map_area(start, size, dir)
  40778. + * - start - kernel virtual start address
  40779. + * - size - size of region
  40780. + * - dir - DMA direction
  40781. + */
  40782. +ENTRY(__dma_map_area)
  40783. + add x1, x1, x0
  40784. + cmp w2, #DMA_FROM_DEVICE
  40785. + b.eq __dma_inv_range
  40786. + b __dma_clean_range
  40787. +ENDPROC(__dma_map_area)
  40788. +
  40789. +/*
  40790. + * __dma_unmap_area(start, size, dir)
  40791. + * - start - kernel virtual start address
  40792. + * - size - size of region
  40793. + * - dir - DMA direction
  40794. + */
  40795. +ENTRY(__dma_unmap_area)
  40796. + add x1, x1, x0
  40797. + cmp w2, #DMA_TO_DEVICE
  40798. + b.ne __dma_inv_range
  40799. + ret
  40800. +ENDPROC(__dma_unmap_area)
  40801. diff -Nur linux-3.14.17/arch/arm64/mm/copypage.c linux-imx6-3.14/arch/arm64/mm/copypage.c
  40802. --- linux-3.14.17/arch/arm64/mm/copypage.c 2014-08-14 03:38:34.000000000 +0200
  40803. +++ linux-imx6-3.14/arch/arm64/mm/copypage.c 2014-09-11 18:05:54.486007940 +0200
  40804. @@ -27,8 +27,10 @@
  40805. copy_page(kto, kfrom);
  40806. __flush_dcache_area(kto, PAGE_SIZE);
  40807. }
  40808. +EXPORT_SYMBOL_GPL(__cpu_copy_user_page);
  40809. void __cpu_clear_user_page(void *kaddr, unsigned long vaddr)
  40810. {
  40811. clear_page(kaddr);
  40812. }
  40813. +EXPORT_SYMBOL_GPL(__cpu_clear_user_page);
  40814. diff -Nur linux-3.14.17/arch/arm64/mm/dma-mapping.c linux-imx6-3.14/arch/arm64/mm/dma-mapping.c
  40815. --- linux-3.14.17/arch/arm64/mm/dma-mapping.c 2014-08-14 03:38:34.000000000 +0200
  40816. +++ linux-imx6-3.14/arch/arm64/mm/dma-mapping.c 2014-09-11 18:05:54.486007940 +0200
  40817. @@ -22,26 +22,39 @@
  40818. #include <linux/slab.h>
  40819. #include <linux/dma-mapping.h>
  40820. #include <linux/dma-contiguous.h>
  40821. +#include <linux/of.h>
  40822. +#include <linux/platform_device.h>
  40823. #include <linux/vmalloc.h>
  40824. #include <linux/swiotlb.h>
  40825. +#include <linux/amba/bus.h>
  40826. #include <asm/cacheflush.h>
  40827. struct dma_map_ops *dma_ops;
  40828. EXPORT_SYMBOL(dma_ops);
  40829. -static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size,
  40830. - dma_addr_t *dma_handle, gfp_t flags,
  40831. - struct dma_attrs *attrs)
  40832. +static pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot,
  40833. + bool coherent)
  40834. +{
  40835. + if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
  40836. + return pgprot_writecombine(prot);
  40837. + else if (!coherent)
  40838. + return pgprot_dmacoherent(prot);
  40839. + return prot;
  40840. +}
  40841. +
  40842. +static void *__dma_alloc_coherent(struct device *dev, size_t size,
  40843. + dma_addr_t *dma_handle, gfp_t flags,
  40844. + struct dma_attrs *attrs)
  40845. {
  40846. if (dev == NULL) {
  40847. WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
  40848. return NULL;
  40849. }
  40850. - if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
  40851. + if (IS_ENABLED(CONFIG_ZONE_DMA) &&
  40852. dev->coherent_dma_mask <= DMA_BIT_MASK(32))
  40853. - flags |= GFP_DMA32;
  40854. + flags |= GFP_DMA;
  40855. if (IS_ENABLED(CONFIG_DMA_CMA)) {
  40856. struct page *page;
  40857. @@ -58,9 +71,9 @@
  40858. }
  40859. }
  40860. -static void arm64_swiotlb_free_coherent(struct device *dev, size_t size,
  40861. - void *vaddr, dma_addr_t dma_handle,
  40862. - struct dma_attrs *attrs)
  40863. +static void __dma_free_coherent(struct device *dev, size_t size,
  40864. + void *vaddr, dma_addr_t dma_handle,
  40865. + struct dma_attrs *attrs)
  40866. {
  40867. if (dev == NULL) {
  40868. WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
  40869. @@ -78,9 +91,212 @@
  40870. }
  40871. }
  40872. -static struct dma_map_ops arm64_swiotlb_dma_ops = {
  40873. - .alloc = arm64_swiotlb_alloc_coherent,
  40874. - .free = arm64_swiotlb_free_coherent,
  40875. +static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
  40876. + dma_addr_t *dma_handle, gfp_t flags,
  40877. + struct dma_attrs *attrs)
  40878. +{
  40879. + struct page *page, **map;
  40880. + void *ptr, *coherent_ptr;
  40881. + int order, i;
  40882. +
  40883. + size = PAGE_ALIGN(size);
  40884. + order = get_order(size);
  40885. +
  40886. + ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
  40887. + if (!ptr)
  40888. + goto no_mem;
  40889. + map = kmalloc(sizeof(struct page *) << order, flags & ~GFP_DMA);
  40890. + if (!map)
  40891. + goto no_map;
  40892. +
  40893. + /* remove any dirty cache lines on the kernel alias */
  40894. + __dma_flush_range(ptr, ptr + size);
  40895. +
  40896. + /* create a coherent mapping */
  40897. + page = virt_to_page(ptr);
  40898. + for (i = 0; i < (size >> PAGE_SHIFT); i++)
  40899. + map[i] = page + i;
  40900. + coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP,
  40901. + __get_dma_pgprot(attrs, pgprot_default, false));
  40902. + kfree(map);
  40903. + if (!coherent_ptr)
  40904. + goto no_map;
  40905. +
  40906. + return coherent_ptr;
  40907. +
  40908. +no_map:
  40909. + __dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
  40910. +no_mem:
  40911. + *dma_handle = ~0;
  40912. + return NULL;
  40913. +}
  40914. +
  40915. +static void __dma_free_noncoherent(struct device *dev, size_t size,
  40916. + void *vaddr, dma_addr_t dma_handle,
  40917. + struct dma_attrs *attrs)
  40918. +{
  40919. + void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
  40920. +
  40921. + vunmap(vaddr);
  40922. + __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
  40923. +}
  40924. +
  40925. +static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
  40926. + unsigned long offset, size_t size,
  40927. + enum dma_data_direction dir,
  40928. + struct dma_attrs *attrs)
  40929. +{
  40930. + dma_addr_t dev_addr;
  40931. +
  40932. + dev_addr = swiotlb_map_page(dev, page, offset, size, dir, attrs);
  40933. + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40934. +
  40935. + return dev_addr;
  40936. +}
  40937. +
  40938. +
  40939. +static void __swiotlb_unmap_page(struct device *dev, dma_addr_t dev_addr,
  40940. + size_t size, enum dma_data_direction dir,
  40941. + struct dma_attrs *attrs)
  40942. +{
  40943. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40944. + swiotlb_unmap_page(dev, dev_addr, size, dir, attrs);
  40945. +}
  40946. +
  40947. +static int __swiotlb_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
  40948. + int nelems, enum dma_data_direction dir,
  40949. + struct dma_attrs *attrs)
  40950. +{
  40951. + struct scatterlist *sg;
  40952. + int i, ret;
  40953. +
  40954. + ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs);
  40955. + for_each_sg(sgl, sg, ret, i)
  40956. + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40957. + sg->length, dir);
  40958. +
  40959. + return ret;
  40960. +}
  40961. +
  40962. +static void __swiotlb_unmap_sg_attrs(struct device *dev,
  40963. + struct scatterlist *sgl, int nelems,
  40964. + enum dma_data_direction dir,
  40965. + struct dma_attrs *attrs)
  40966. +{
  40967. + struct scatterlist *sg;
  40968. + int i;
  40969. +
  40970. + for_each_sg(sgl, sg, nelems, i)
  40971. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  40972. + sg->length, dir);
  40973. + swiotlb_unmap_sg_attrs(dev, sgl, nelems, dir, attrs);
  40974. +}
  40975. +
  40976. +static void __swiotlb_sync_single_for_cpu(struct device *dev,
  40977. + dma_addr_t dev_addr, size_t size,
  40978. + enum dma_data_direction dir)
  40979. +{
  40980. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40981. + swiotlb_sync_single_for_cpu(dev, dev_addr, size, dir);
  40982. +}
  40983. +
  40984. +static void __swiotlb_sync_single_for_device(struct device *dev,
  40985. + dma_addr_t dev_addr, size_t size,
  40986. + enum dma_data_direction dir)
  40987. +{
  40988. + swiotlb_sync_single_for_device(dev, dev_addr, size, dir);
  40989. + __dma_map_area(phys_to_virt(dma_to_phys(dev, dev_addr)), size, dir);
  40990. +}
  40991. +
  40992. +static void __swiotlb_sync_sg_for_cpu(struct device *dev,
  40993. + struct scatterlist *sgl, int nelems,
  40994. + enum dma_data_direction dir)
  40995. +{
  40996. + struct scatterlist *sg;
  40997. + int i;
  40998. +
  40999. + for_each_sg(sgl, sg, nelems, i)
  41000. + __dma_unmap_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  41001. + sg->length, dir);
  41002. + swiotlb_sync_sg_for_cpu(dev, sgl, nelems, dir);
  41003. +}
  41004. +
  41005. +static void __swiotlb_sync_sg_for_device(struct device *dev,
  41006. + struct scatterlist *sgl, int nelems,
  41007. + enum dma_data_direction dir)
  41008. +{
  41009. + struct scatterlist *sg;
  41010. + int i;
  41011. +
  41012. + swiotlb_sync_sg_for_device(dev, sgl, nelems, dir);
  41013. + for_each_sg(sgl, sg, nelems, i)
  41014. + __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
  41015. + sg->length, dir);
  41016. +}
  41017. +
  41018. +/* vma->vm_page_prot must be set appropriately before calling this function */
  41019. +static int __dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
  41020. + void *cpu_addr, dma_addr_t dma_addr, size_t size)
  41021. +{
  41022. + int ret = -ENXIO;
  41023. + unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >>
  41024. + PAGE_SHIFT;
  41025. + unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
  41026. + unsigned long pfn = dma_to_phys(dev, dma_addr) >> PAGE_SHIFT;
  41027. + unsigned long off = vma->vm_pgoff;
  41028. +
  41029. + if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
  41030. + return ret;
  41031. +
  41032. + if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
  41033. + ret = remap_pfn_range(vma, vma->vm_start,
  41034. + pfn + off,
  41035. + vma->vm_end - vma->vm_start,
  41036. + vma->vm_page_prot);
  41037. + }
  41038. +
  41039. + return ret;
  41040. +}
  41041. +
  41042. +static int __swiotlb_mmap_noncoherent(struct device *dev,
  41043. + struct vm_area_struct *vma,
  41044. + void *cpu_addr, dma_addr_t dma_addr, size_t size,
  41045. + struct dma_attrs *attrs)
  41046. +{
  41047. + vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, false);
  41048. + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
  41049. +}
  41050. +
  41051. +static int __swiotlb_mmap_coherent(struct device *dev,
  41052. + struct vm_area_struct *vma,
  41053. + void *cpu_addr, dma_addr_t dma_addr, size_t size,
  41054. + struct dma_attrs *attrs)
  41055. +{
  41056. + /* Just use whatever page_prot attributes were specified */
  41057. + return __dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
  41058. +}
  41059. +
  41060. +struct dma_map_ops noncoherent_swiotlb_dma_ops = {
  41061. + .alloc = __dma_alloc_noncoherent,
  41062. + .free = __dma_free_noncoherent,
  41063. + .mmap = __swiotlb_mmap_noncoherent,
  41064. + .map_page = __swiotlb_map_page,
  41065. + .unmap_page = __swiotlb_unmap_page,
  41066. + .map_sg = __swiotlb_map_sg_attrs,
  41067. + .unmap_sg = __swiotlb_unmap_sg_attrs,
  41068. + .sync_single_for_cpu = __swiotlb_sync_single_for_cpu,
  41069. + .sync_single_for_device = __swiotlb_sync_single_for_device,
  41070. + .sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu,
  41071. + .sync_sg_for_device = __swiotlb_sync_sg_for_device,
  41072. + .dma_supported = swiotlb_dma_supported,
  41073. + .mapping_error = swiotlb_dma_mapping_error,
  41074. +};
  41075. +EXPORT_SYMBOL(noncoherent_swiotlb_dma_ops);
  41076. +
  41077. +struct dma_map_ops coherent_swiotlb_dma_ops = {
  41078. + .alloc = __dma_alloc_coherent,
  41079. + .free = __dma_free_coherent,
  41080. + .mmap = __swiotlb_mmap_coherent,
  41081. .map_page = swiotlb_map_page,
  41082. .unmap_page = swiotlb_unmap_page,
  41083. .map_sg = swiotlb_map_sg_attrs,
  41084. @@ -92,12 +308,47 @@
  41085. .dma_supported = swiotlb_dma_supported,
  41086. .mapping_error = swiotlb_dma_mapping_error,
  41087. };
  41088. +EXPORT_SYMBOL(coherent_swiotlb_dma_ops);
  41089. -void __init arm64_swiotlb_init(void)
  41090. +static int dma_bus_notifier(struct notifier_block *nb,
  41091. + unsigned long event, void *_dev)
  41092. {
  41093. - dma_ops = &arm64_swiotlb_dma_ops;
  41094. - swiotlb_init(1);
  41095. + struct device *dev = _dev;
  41096. +
  41097. + if (event != BUS_NOTIFY_ADD_DEVICE)
  41098. + return NOTIFY_DONE;
  41099. +
  41100. + if (of_property_read_bool(dev->of_node, "dma-coherent"))
  41101. + set_dma_ops(dev, &coherent_swiotlb_dma_ops);
  41102. +
  41103. + return NOTIFY_OK;
  41104. +}
  41105. +
  41106. +static struct notifier_block platform_bus_nb = {
  41107. + .notifier_call = dma_bus_notifier,
  41108. +};
  41109. +
  41110. +static struct notifier_block amba_bus_nb = {
  41111. + .notifier_call = dma_bus_notifier,
  41112. +};
  41113. +
  41114. +extern int swiotlb_late_init_with_default_size(size_t default_size);
  41115. +
  41116. +static int __init swiotlb_late_init(void)
  41117. +{
  41118. + size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT);
  41119. +
  41120. + /*
  41121. + * These must be registered before of_platform_populate().
  41122. + */
  41123. + bus_register_notifier(&platform_bus_type, &platform_bus_nb);
  41124. + bus_register_notifier(&amba_bustype, &amba_bus_nb);
  41125. +
  41126. + dma_ops = &noncoherent_swiotlb_dma_ops;
  41127. +
  41128. + return swiotlb_late_init_with_default_size(swiotlb_size);
  41129. }
  41130. +arch_initcall(swiotlb_late_init);
  41131. #define PREALLOC_DMA_DEBUG_ENTRIES 4096
  41132. diff -Nur linux-3.14.17/arch/arm64/mm/init.c linux-imx6-3.14/arch/arm64/mm/init.c
  41133. --- linux-3.14.17/arch/arm64/mm/init.c 2014-08-14 03:38:34.000000000 +0200
  41134. +++ linux-imx6-3.14/arch/arm64/mm/init.c 2014-09-11 18:05:54.486007940 +0200
  41135. @@ -30,6 +30,7 @@
  41136. #include <linux/memblock.h>
  41137. #include <linux/sort.h>
  41138. #include <linux/of_fdt.h>
  41139. +#include <linux/dma-mapping.h>
  41140. #include <linux/dma-contiguous.h>
  41141. #include <asm/sections.h>
  41142. @@ -59,22 +60,22 @@
  41143. early_param("initrd", early_initrd);
  41144. #endif
  41145. -#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)
  41146. -
  41147. static void __init zone_sizes_init(unsigned long min, unsigned long max)
  41148. {
  41149. struct memblock_region *reg;
  41150. unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
  41151. - unsigned long max_dma32 = min;
  41152. + unsigned long max_dma = min;
  41153. memset(zone_size, 0, sizeof(zone_size));
  41154. -#ifdef CONFIG_ZONE_DMA32
  41155. /* 4GB maximum for 32-bit only capable devices */
  41156. - max_dma32 = max(min, min(max, MAX_DMA32_PFN));
  41157. - zone_size[ZONE_DMA32] = max_dma32 - min;
  41158. -#endif
  41159. - zone_size[ZONE_NORMAL] = max - max_dma32;
  41160. + if (IS_ENABLED(CONFIG_ZONE_DMA)) {
  41161. + unsigned long max_dma_phys =
  41162. + (unsigned long)dma_to_phys(NULL, DMA_BIT_MASK(32) + 1);
  41163. + max_dma = max(min, min(max, max_dma_phys >> PAGE_SHIFT));
  41164. + zone_size[ZONE_DMA] = max_dma - min;
  41165. + }
  41166. + zone_size[ZONE_NORMAL] = max - max_dma;
  41167. memcpy(zhole_size, zone_size, sizeof(zhole_size));
  41168. @@ -84,15 +85,15 @@
  41169. if (start >= max)
  41170. continue;
  41171. -#ifdef CONFIG_ZONE_DMA32
  41172. - if (start < max_dma32) {
  41173. - unsigned long dma_end = min(end, max_dma32);
  41174. - zhole_size[ZONE_DMA32] -= dma_end - start;
  41175. +
  41176. + if (IS_ENABLED(CONFIG_ZONE_DMA) && start < max_dma) {
  41177. + unsigned long dma_end = min(end, max_dma);
  41178. + zhole_size[ZONE_DMA] -= dma_end - start;
  41179. }
  41180. -#endif
  41181. - if (end > max_dma32) {
  41182. +
  41183. + if (end > max_dma) {
  41184. unsigned long normal_end = min(end, max);
  41185. - unsigned long normal_start = max(start, max_dma32);
  41186. + unsigned long normal_start = max(start, max_dma);
  41187. zhole_size[ZONE_NORMAL] -= normal_end - normal_start;
  41188. }
  41189. }
  41190. @@ -127,20 +128,16 @@
  41191. {
  41192. u64 *reserve_map, base, size;
  41193. - /* Register the kernel text, kernel data and initrd with memblock */
  41194. + /*
  41195. + * Register the kernel text, kernel data, initrd, and initial
  41196. + * pagetables with memblock.
  41197. + */
  41198. memblock_reserve(__pa(_text), _end - _text);
  41199. #ifdef CONFIG_BLK_DEV_INITRD
  41200. if (initrd_start)
  41201. memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
  41202. #endif
  41203. - /*
  41204. - * Reserve the page tables. These are already in use,
  41205. - * and can only be in node 0.
  41206. - */
  41207. - memblock_reserve(__pa(swapper_pg_dir), SWAPPER_DIR_SIZE);
  41208. - memblock_reserve(__pa(idmap_pg_dir), IDMAP_DIR_SIZE);
  41209. -
  41210. /* Reserve the dtb region */
  41211. memblock_reserve(virt_to_phys(initial_boot_params),
  41212. be32_to_cpu(initial_boot_params->totalsize));
  41213. @@ -261,8 +258,6 @@
  41214. */
  41215. void __init mem_init(void)
  41216. {
  41217. - arm64_swiotlb_init();
  41218. -
  41219. max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
  41220. #ifndef CONFIG_SPARSEMEM_VMEMMAP
  41221. diff -Nur linux-3.14.17/arch/arm64/mm/proc.S linux-imx6-3.14/arch/arm64/mm/proc.S
  41222. --- linux-3.14.17/arch/arm64/mm/proc.S 2014-08-14 03:38:34.000000000 +0200
  41223. +++ linux-imx6-3.14/arch/arm64/mm/proc.S 2014-09-11 18:05:54.490007955 +0200
  41224. @@ -173,12 +173,6 @@
  41225. * value of the SCTLR_EL1 register.
  41226. */
  41227. ENTRY(__cpu_setup)
  41228. - /*
  41229. - * Preserve the link register across the function call.
  41230. - */
  41231. - mov x28, lr
  41232. - bl __flush_dcache_all
  41233. - mov lr, x28
  41234. ic iallu // I+BTB cache invalidate
  41235. tlbi vmalle1is // invalidate I + D TLBs
  41236. dsb sy
  41237. diff -Nur linux-3.14.17/arch/avr32/kernel/cpu.c linux-imx6-3.14/arch/avr32/kernel/cpu.c
  41238. --- linux-3.14.17/arch/avr32/kernel/cpu.c 2014-08-14 03:38:34.000000000 +0200
  41239. +++ linux-imx6-3.14/arch/avr32/kernel/cpu.c 2014-09-11 18:05:54.514008051 +0200
  41240. @@ -39,10 +39,12 @@
  41241. size_t count)
  41242. {
  41243. unsigned long val;
  41244. - char *endp;
  41245. + int ret;
  41246. - val = simple_strtoul(buf, &endp, 0);
  41247. - if (endp == buf || val > 0x3f)
  41248. + ret = kstrtoul(buf, 0, &val);
  41249. + if (ret)
  41250. + return ret;
  41251. + if (val > 0x3f)
  41252. return -EINVAL;
  41253. val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff);
  41254. sysreg_write(PCCR, val);
  41255. @@ -61,11 +63,11 @@
  41256. const char *buf, size_t count)
  41257. {
  41258. unsigned long val;
  41259. - char *endp;
  41260. + int ret;
  41261. - val = simple_strtoul(buf, &endp, 0);
  41262. - if (endp == buf)
  41263. - return -EINVAL;
  41264. + ret = kstrtoul(buf, 0, &val);
  41265. + if (ret)
  41266. + return ret;
  41267. sysreg_write(PCNT0, val);
  41268. return count;
  41269. @@ -84,10 +86,12 @@
  41270. size_t count)
  41271. {
  41272. unsigned long val;
  41273. - char *endp;
  41274. + int ret;
  41275. - val = simple_strtoul(buf, &endp, 0);
  41276. - if (endp == buf || val > 0x3f)
  41277. + ret = kstrtoul(buf, 0, &val);
  41278. + if (ret)
  41279. + return ret;
  41280. + if (val > 0x3f)
  41281. return -EINVAL;
  41282. val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff);
  41283. sysreg_write(PCCR, val);
  41284. @@ -106,11 +110,11 @@
  41285. size_t count)
  41286. {
  41287. unsigned long val;
  41288. - char *endp;
  41289. + int ret;
  41290. - val = simple_strtoul(buf, &endp, 0);
  41291. - if (endp == buf)
  41292. - return -EINVAL;
  41293. + ret = kstrtoul(buf, 0, &val);
  41294. + if (ret)
  41295. + return ret;
  41296. sysreg_write(PCNT1, val);
  41297. return count;
  41298. @@ -129,11 +133,11 @@
  41299. size_t count)
  41300. {
  41301. unsigned long val;
  41302. - char *endp;
  41303. + int ret;
  41304. - val = simple_strtoul(buf, &endp, 0);
  41305. - if (endp == buf)
  41306. - return -EINVAL;
  41307. + ret = kstrtoul(buf, 0, &val);
  41308. + if (ret)
  41309. + return ret;
  41310. sysreg_write(PCCNT, val);
  41311. return count;
  41312. @@ -152,11 +156,11 @@
  41313. size_t count)
  41314. {
  41315. unsigned long pccr, val;
  41316. - char *endp;
  41317. + int ret;
  41318. - val = simple_strtoul(buf, &endp, 0);
  41319. - if (endp == buf)
  41320. - return -EINVAL;
  41321. + ret = kstrtoul(buf, 0, &val);
  41322. + if (ret)
  41323. + return ret;
  41324. if (val)
  41325. val = 1;
  41326. diff -Nur linux-3.14.17/arch/blackfin/include/asm/ftrace.h linux-imx6-3.14/arch/blackfin/include/asm/ftrace.h
  41327. --- linux-3.14.17/arch/blackfin/include/asm/ftrace.h 2014-08-14 03:38:34.000000000 +0200
  41328. +++ linux-imx6-3.14/arch/blackfin/include/asm/ftrace.h 2014-09-11 18:05:54.538008148 +0200
  41329. @@ -66,16 +66,7 @@
  41330. #endif /* CONFIG_FRAME_POINTER */
  41331. -#define HAVE_ARCH_CALLER_ADDR
  41332. -
  41333. -/* inline function or macro may lead to unexpected result */
  41334. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41335. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  41336. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  41337. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  41338. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  41339. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  41340. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  41341. +#define ftrace_return_address(n) return_address(n)
  41342. #endif /* __ASSEMBLY__ */
  41343. diff -Nur linux-3.14.17/arch/hexagon/include/asm/elf.h linux-imx6-3.14/arch/hexagon/include/asm/elf.h
  41344. --- linux-3.14.17/arch/hexagon/include/asm/elf.h 2014-08-14 03:38:34.000000000 +0200
  41345. +++ linux-imx6-3.14/arch/hexagon/include/asm/elf.h 2014-09-11 18:05:55.318011266 +0200
  41346. @@ -1,7 +1,7 @@
  41347. /*
  41348. * ELF definitions for the Hexagon architecture
  41349. *
  41350. - * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
  41351. + * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  41352. *
  41353. * This program is free software; you can redistribute it and/or modify
  41354. * it under the terms of the GNU General Public License version 2 and
  41355. diff -Nur linux-3.14.17/arch/parisc/include/asm/ftrace.h linux-imx6-3.14/arch/parisc/include/asm/ftrace.h
  41356. --- linux-3.14.17/arch/parisc/include/asm/ftrace.h 2014-08-14 03:38:34.000000000 +0200
  41357. +++ linux-imx6-3.14/arch/parisc/include/asm/ftrace.h 2014-09-11 18:05:56.270015072 +0200
  41358. @@ -24,15 +24,7 @@
  41359. extern unsigned long return_address(unsigned int);
  41360. -#define HAVE_ARCH_CALLER_ADDR
  41361. -
  41362. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41363. -#define CALLER_ADDR1 return_address(1)
  41364. -#define CALLER_ADDR2 return_address(2)
  41365. -#define CALLER_ADDR3 return_address(3)
  41366. -#define CALLER_ADDR4 return_address(4)
  41367. -#define CALLER_ADDR5 return_address(5)
  41368. -#define CALLER_ADDR6 return_address(6)
  41369. +#define ftrace_return_address(n) return_address(n)
  41370. #endif /* __ASSEMBLY__ */
  41371. diff -Nur linux-3.14.17/arch/parisc/include/uapi/asm/signal.h linux-imx6-3.14/arch/parisc/include/uapi/asm/signal.h
  41372. --- linux-3.14.17/arch/parisc/include/uapi/asm/signal.h 2014-08-14 03:38:34.000000000 +0200
  41373. +++ linux-imx6-3.14/arch/parisc/include/uapi/asm/signal.h 2014-09-11 18:05:56.278015104 +0200
  41374. @@ -69,6 +69,8 @@
  41375. #define SA_NOMASK SA_NODEFER
  41376. #define SA_ONESHOT SA_RESETHAND
  41377. +#define SA_RESTORER 0x04000000 /* obsolete -- ignored */
  41378. +
  41379. #define MINSIGSTKSZ 2048
  41380. #define SIGSTKSZ 8192
  41381. diff -Nur linux-3.14.17/arch/s390/include/asm/cio.h linux-imx6-3.14/arch/s390/include/asm/cio.h
  41382. --- linux-3.14.17/arch/s390/include/asm/cio.h 2014-08-14 03:38:34.000000000 +0200
  41383. +++ linux-imx6-3.14/arch/s390/include/asm/cio.h 2014-09-11 18:05:56.974017886 +0200
  41384. @@ -199,7 +199,7 @@
  41385. /**
  41386. * struct irb - interruption response block
  41387. * @scsw: subchannel status word
  41388. - * @esw: extened status word
  41389. + * @esw: extended status word
  41390. * @ecw: extended control word
  41391. *
  41392. * The irb that is handed to the device driver when an interrupt occurs. For
  41393. diff -Nur linux-3.14.17/arch/s390/kernel/ptrace.c linux-imx6-3.14/arch/s390/kernel/ptrace.c
  41394. --- linux-3.14.17/arch/s390/kernel/ptrace.c 2014-08-14 03:38:34.000000000 +0200
  41395. +++ linux-imx6-3.14/arch/s390/kernel/ptrace.c 2014-09-11 18:05:57.078018301 +0200
  41396. @@ -323,14 +323,9 @@
  41397. unsigned long mask = PSW_MASK_USER;
  41398. mask |= is_ri_task(child) ? PSW_MASK_RI : 0;
  41399. - if ((data ^ PSW_USER_BITS) & ~mask)
  41400. - /* Invalid psw mask. */
  41401. - return -EINVAL;
  41402. - if ((data & PSW_MASK_ASC) == PSW_ASC_HOME)
  41403. - /* Invalid address-space-control bits */
  41404. + if ((data & ~mask) != PSW_USER_BITS)
  41405. return -EINVAL;
  41406. if ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))
  41407. - /* Invalid addressing mode bits */
  41408. return -EINVAL;
  41409. }
  41410. *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
  41411. @@ -666,12 +661,9 @@
  41412. mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
  41413. /* Build a 64 bit psw mask from 31 bit mask. */
  41414. - if ((tmp ^ PSW32_USER_BITS) & ~mask)
  41415. + if ((tmp & ~mask) != PSW32_USER_BITS)
  41416. /* Invalid psw mask. */
  41417. return -EINVAL;
  41418. - if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME)
  41419. - /* Invalid address-space-control bits */
  41420. - return -EINVAL;
  41421. regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
  41422. (regs->psw.mask & PSW_MASK_BA) |
  41423. (__u64)(tmp & mask) << 32;
  41424. diff -Nur linux-3.14.17/arch/sh/include/asm/ftrace.h linux-imx6-3.14/arch/sh/include/asm/ftrace.h
  41425. --- linux-3.14.17/arch/sh/include/asm/ftrace.h 2014-08-14 03:38:34.000000000 +0200
  41426. +++ linux-imx6-3.14/arch/sh/include/asm/ftrace.h 2014-09-11 18:05:57.446019771 +0200
  41427. @@ -40,15 +40,7 @@
  41428. /* arch/sh/kernel/return_address.c */
  41429. extern void *return_address(unsigned int);
  41430. -#define HAVE_ARCH_CALLER_ADDR
  41431. -
  41432. -#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  41433. -#define CALLER_ADDR1 ((unsigned long)return_address(1))
  41434. -#define CALLER_ADDR2 ((unsigned long)return_address(2))
  41435. -#define CALLER_ADDR3 ((unsigned long)return_address(3))
  41436. -#define CALLER_ADDR4 ((unsigned long)return_address(4))
  41437. -#define CALLER_ADDR5 ((unsigned long)return_address(5))
  41438. -#define CALLER_ADDR6 ((unsigned long)return_address(6))
  41439. +#define ftrace_return_address(n) return_address(n)
  41440. #endif /* __ASSEMBLY__ */
  41441. diff -Nur linux-3.14.17/arch/sparc/include/asm/pgtable_64.h linux-imx6-3.14/arch/sparc/include/asm/pgtable_64.h
  41442. --- linux-3.14.17/arch/sparc/include/asm/pgtable_64.h 2014-08-14 03:38:34.000000000 +0200
  41443. +++ linux-imx6-3.14/arch/sparc/include/asm/pgtable_64.h 2014-09-11 18:05:57.682020716 +0200
  41444. @@ -24,8 +24,7 @@
  41445. /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).
  41446. * The page copy blockops can use 0x6000000 to 0x8000000.
  41447. - * The 8K TSB is mapped in the 0x8000000 to 0x8400000 range.
  41448. - * The 4M TSB is mapped in the 0x8400000 to 0x8800000 range.
  41449. + * The TSB is mapped in the 0x8000000 to 0xa000000 range.
  41450. * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
  41451. * The vmalloc area spans 0x100000000 to 0x200000000.
  41452. * Since modules need to be in the lowest 32-bits of the address space,
  41453. @@ -34,8 +33,7 @@
  41454. * 0x400000000.
  41455. */
  41456. #define TLBTEMP_BASE _AC(0x0000000006000000,UL)
  41457. -#define TSBMAP_8K_BASE _AC(0x0000000008000000,UL)
  41458. -#define TSBMAP_4M_BASE _AC(0x0000000008400000,UL)
  41459. +#define TSBMAP_BASE _AC(0x0000000008000000,UL)
  41460. #define MODULES_VADDR _AC(0x0000000010000000,UL)
  41461. #define MODULES_LEN _AC(0x00000000e0000000,UL)
  41462. #define MODULES_END _AC(0x00000000f0000000,UL)
  41463. @@ -73,23 +71,6 @@
  41464. #include <linux/sched.h>
  41465. -extern unsigned long sparc64_valid_addr_bitmap[];
  41466. -
  41467. -/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  41468. -static inline bool __kern_addr_valid(unsigned long paddr)
  41469. -{
  41470. - if ((paddr >> MAX_PHYS_ADDRESS_BITS) != 0UL)
  41471. - return false;
  41472. - return test_bit(paddr >> ILOG2_4MB, sparc64_valid_addr_bitmap);
  41473. -}
  41474. -
  41475. -static inline bool kern_addr_valid(unsigned long addr)
  41476. -{
  41477. - unsigned long paddr = __pa(addr);
  41478. -
  41479. - return __kern_addr_valid(paddr);
  41480. -}
  41481. -
  41482. /* Entries per page directory level. */
  41483. #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3))
  41484. #define PTRS_PER_PMD (1UL << PMD_BITS)
  41485. @@ -98,12 +79,9 @@
  41486. /* Kernel has a separate 44bit address space. */
  41487. #define FIRST_USER_ADDRESS 0
  41488. -#define pmd_ERROR(e) \
  41489. - pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \
  41490. - __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0))
  41491. -#define pgd_ERROR(e) \
  41492. - pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \
  41493. - __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0))
  41494. +#define pte_ERROR(e) __builtin_trap()
  41495. +#define pmd_ERROR(e) __builtin_trap()
  41496. +#define pgd_ERROR(e) __builtin_trap()
  41497. #endif /* !(__ASSEMBLY__) */
  41498. @@ -280,8 +258,8 @@
  41499. {
  41500. unsigned long mask, tmp;
  41501. - /* SUN4U: 0x630107ffffffec38 (negated == 0x9cfef800000013c7)
  41502. - * SUN4V: 0x33ffffffffffee07 (negated == 0xcc000000000011f8)
  41503. + /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347)
  41504. + * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8)
  41505. *
  41506. * Even if we use negation tricks the result is still a 6
  41507. * instruction sequence, so don't try to play fancy and just
  41508. @@ -311,10 +289,10 @@
  41509. " .previous\n"
  41510. : "=r" (mask), "=r" (tmp)
  41511. : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
  41512. - _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
  41513. + _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
  41514. _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
  41515. "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
  41516. - _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V |
  41517. + _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
  41518. _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));
  41519. return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
  41520. @@ -655,7 +633,7 @@
  41521. {
  41522. pte_t pte = __pte(pmd_val(pmd));
  41523. - return pte_val(pte) & _PAGE_PMD_HUGE;
  41524. + return (pte_val(pte) & _PAGE_PMD_HUGE) && pte_present(pte);
  41525. }
  41526. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  41527. @@ -741,6 +719,20 @@
  41528. return __pmd(pte_val(pte));
  41529. }
  41530. +static inline pmd_t pmd_mknotpresent(pmd_t pmd)
  41531. +{
  41532. + unsigned long mask;
  41533. +
  41534. + if (tlb_type == hypervisor)
  41535. + mask = _PAGE_PRESENT_4V;
  41536. + else
  41537. + mask = _PAGE_PRESENT_4U;
  41538. +
  41539. + pmd_val(pmd) &= ~mask;
  41540. +
  41541. + return pmd;
  41542. +}
  41543. +
  41544. static inline pmd_t pmd_mksplitting(pmd_t pmd)
  41545. {
  41546. pte_t pte = __pte(pmd_val(pmd));
  41547. @@ -765,20 +757,6 @@
  41548. #define pmd_none(pmd) (!pmd_val(pmd))
  41549. -/* pmd_bad() is only called on non-trans-huge PMDs. Our encoding is
  41550. - * very simple, it's just the physical address. PTE tables are of
  41551. - * size PAGE_SIZE so make sure the sub-PAGE_SIZE bits are clear and
  41552. - * the top bits outside of the range of any physical address size we
  41553. - * support are clear as well. We also validate the physical itself.
  41554. - */
  41555. -#define pmd_bad(pmd) ((pmd_val(pmd) & ~PAGE_MASK) || \
  41556. - !__kern_addr_valid(pmd_val(pmd)))
  41557. -
  41558. -#define pud_none(pud) (!pud_val(pud))
  41559. -
  41560. -#define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \
  41561. - !__kern_addr_valid(pud_val(pud)))
  41562. -
  41563. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  41564. extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
  41565. pmd_t *pmdp, pmd_t pmd);
  41566. @@ -812,7 +790,10 @@
  41567. #define pud_page_vaddr(pud) \
  41568. ((unsigned long) __va(pud_val(pud)))
  41569. #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud))
  41570. +#define pmd_bad(pmd) (0)
  41571. #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
  41572. +#define pud_none(pud) (!pud_val(pud))
  41573. +#define pud_bad(pud) (0)
  41574. #define pud_present(pud) (pud_val(pud) != 0U)
  41575. #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
  41576. @@ -912,10 +893,6 @@
  41577. extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
  41578. pmd_t *pmd);
  41579. -#define __HAVE_ARCH_PMDP_INVALIDATE
  41580. -extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
  41581. - pmd_t *pmdp);
  41582. -
  41583. #define __HAVE_ARCH_PGTABLE_DEPOSIT
  41584. extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
  41585. pgtable_t pgtable);
  41586. @@ -942,6 +919,18 @@
  41587. extern pte_t pgoff_to_pte(unsigned long);
  41588. #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL)
  41589. +extern unsigned long sparc64_valid_addr_bitmap[];
  41590. +
  41591. +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  41592. +static inline bool kern_addr_valid(unsigned long addr)
  41593. +{
  41594. + unsigned long paddr = __pa(addr);
  41595. +
  41596. + if ((paddr >> 41UL) != 0UL)
  41597. + return false;
  41598. + return test_bit(paddr >> 22, sparc64_valid_addr_bitmap);
  41599. +}
  41600. +
  41601. extern int page_in_phys_avail(unsigned long paddr);
  41602. /*
  41603. diff -Nur linux-3.14.17/arch/sparc/include/asm/tlbflush_64.h linux-imx6-3.14/arch/sparc/include/asm/tlbflush_64.h
  41604. --- linux-3.14.17/arch/sparc/include/asm/tlbflush_64.h 2014-08-14 03:38:34.000000000 +0200
  41605. +++ linux-imx6-3.14/arch/sparc/include/asm/tlbflush_64.h 2014-09-11 18:05:57.694020763 +0200
  41606. @@ -34,8 +34,6 @@
  41607. {
  41608. }
  41609. -void flush_tlb_kernel_range(unsigned long start, unsigned long end);
  41610. -
  41611. #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
  41612. extern void flush_tlb_pending(void);
  41613. @@ -50,6 +48,11 @@
  41614. #ifndef CONFIG_SMP
  41615. +#define flush_tlb_kernel_range(start,end) \
  41616. +do { flush_tsb_kernel_range(start,end); \
  41617. + __flush_tlb_kernel_range(start,end); \
  41618. +} while (0)
  41619. +
  41620. static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
  41621. {
  41622. __flush_tlb_page(CTX_HWBITS(mm->context), vaddr);
  41623. @@ -60,6 +63,11 @@
  41624. extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
  41625. extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
  41626. +#define flush_tlb_kernel_range(start, end) \
  41627. +do { flush_tsb_kernel_range(start,end); \
  41628. + smp_flush_tlb_kernel_range(start, end); \
  41629. +} while (0)
  41630. +
  41631. #define global_flush_tlb_page(mm, vaddr) \
  41632. smp_flush_tlb_page(mm, vaddr)
  41633. diff -Nur linux-3.14.17/arch/sparc/include/asm/tsb.h linux-imx6-3.14/arch/sparc/include/asm/tsb.h
  41634. --- linux-3.14.17/arch/sparc/include/asm/tsb.h 2014-08-14 03:38:34.000000000 +0200
  41635. +++ linux-imx6-3.14/arch/sparc/include/asm/tsb.h 2014-09-11 18:05:57.694020763 +0200
  41636. @@ -171,8 +171,7 @@
  41637. andcc REG1, REG2, %g0; \
  41638. be,pt %xcc, 700f; \
  41639. sethi %hi(4 * 1024 * 1024), REG2; \
  41640. - brgez,pn REG1, FAIL_LABEL; \
  41641. - andn REG1, REG2, REG1; \
  41642. + andn REG1, REG2, REG1; \
  41643. and VADDR, REG2, REG2; \
  41644. brlz,pt REG1, PTE_LABEL; \
  41645. or REG1, REG2, REG1; \
  41646. diff -Nur linux-3.14.17/arch/sparc/kernel/head_64.S linux-imx6-3.14/arch/sparc/kernel/head_64.S
  41647. --- linux-3.14.17/arch/sparc/kernel/head_64.S 2014-08-14 03:38:34.000000000 +0200
  41648. +++ linux-imx6-3.14/arch/sparc/kernel/head_64.S 2014-09-11 18:05:57.710020827 +0200
  41649. @@ -282,8 +282,8 @@
  41650. stx %l2, [%l4 + 0x0]
  41651. ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low
  41652. /* 4MB align */
  41653. - srlx %l3, ILOG2_4MB, %l3
  41654. - sllx %l3, ILOG2_4MB, %l3
  41655. + srlx %l3, 22, %l3
  41656. + sllx %l3, 22, %l3
  41657. stx %l3, [%l4 + 0x8]
  41658. /* Leave service as-is, "call-method" */
  41659. diff -Nur linux-3.14.17/arch/sparc/kernel/ktlb.S linux-imx6-3.14/arch/sparc/kernel/ktlb.S
  41660. --- linux-3.14.17/arch/sparc/kernel/ktlb.S 2014-08-14 03:38:34.000000000 +0200
  41661. +++ linux-imx6-3.14/arch/sparc/kernel/ktlb.S 2014-09-11 18:05:57.714020844 +0200
  41662. @@ -277,7 +277,7 @@
  41663. #ifdef CONFIG_SPARSEMEM_VMEMMAP
  41664. kvmap_vmemmap:
  41665. sub %g4, %g5, %g5
  41666. - srlx %g5, ILOG2_4MB, %g5
  41667. + srlx %g5, 22, %g5
  41668. sethi %hi(vmemmap_table), %g1
  41669. sllx %g5, 3, %g5
  41670. or %g1, %lo(vmemmap_table), %g1
  41671. diff -Nur linux-3.14.17/arch/sparc/kernel/ldc.c linux-imx6-3.14/arch/sparc/kernel/ldc.c
  41672. --- linux-3.14.17/arch/sparc/kernel/ldc.c 2014-08-14 03:38:34.000000000 +0200
  41673. +++ linux-imx6-3.14/arch/sparc/kernel/ldc.c 2014-09-11 18:05:57.714020844 +0200
  41674. @@ -1336,7 +1336,7 @@
  41675. if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) ||
  41676. !(lp->flags & LDC_FLAG_REGISTERED_QUEUES) ||
  41677. lp->hs_state != LDC_HS_OPEN)
  41678. - err = ((lp->hs_state > LDC_HS_OPEN) ? 0 : -EINVAL);
  41679. + err = -EINVAL;
  41680. else
  41681. err = start_handshake(lp);
  41682. diff -Nur linux-3.14.17/arch/sparc/kernel/smp_64.c linux-imx6-3.14/arch/sparc/kernel/smp_64.c
  41683. --- linux-3.14.17/arch/sparc/kernel/smp_64.c 2014-08-14 03:38:34.000000000 +0200
  41684. +++ linux-imx6-3.14/arch/sparc/kernel/smp_64.c 2014-09-11 18:05:57.754021003 +0200
  41685. @@ -151,7 +151,7 @@
  41686. #define NUM_ROUNDS 64 /* magic value */
  41687. #define NUM_ITERS 5 /* likewise */
  41688. -static DEFINE_RAW_SPINLOCK(itc_sync_lock);
  41689. +static DEFINE_SPINLOCK(itc_sync_lock);
  41690. static unsigned long go[SLAVE + 1];
  41691. #define DEBUG_TICK_SYNC 0
  41692. @@ -259,7 +259,7 @@
  41693. go[MASTER] = 0;
  41694. membar_safe("#StoreLoad");
  41695. - raw_spin_lock_irqsave(&itc_sync_lock, flags);
  41696. + spin_lock_irqsave(&itc_sync_lock, flags);
  41697. {
  41698. for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) {
  41699. while (!go[MASTER])
  41700. @@ -270,7 +270,7 @@
  41701. membar_safe("#StoreLoad");
  41702. }
  41703. }
  41704. - raw_spin_unlock_irqrestore(&itc_sync_lock, flags);
  41705. + spin_unlock_irqrestore(&itc_sync_lock, flags);
  41706. }
  41707. #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
  41708. diff -Nur linux-3.14.17/arch/sparc/kernel/sys32.S linux-imx6-3.14/arch/sparc/kernel/sys32.S
  41709. --- linux-3.14.17/arch/sparc/kernel/sys32.S 2014-08-14 03:38:34.000000000 +0200
  41710. +++ linux-imx6-3.14/arch/sparc/kernel/sys32.S 2014-09-11 18:05:57.766021051 +0200
  41711. @@ -44,7 +44,7 @@
  41712. SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
  41713. SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
  41714. SIGN1(sys32_select, compat_sys_select, %o0)
  41715. -SIGN1(sys32_futex, compat_sys_futex, %o1)
  41716. +SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
  41717. SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
  41718. SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0)
  41719. SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0)
  41720. diff -Nur linux-3.14.17/arch/sparc/kernel/unaligned_64.c linux-imx6-3.14/arch/sparc/kernel/unaligned_64.c
  41721. --- linux-3.14.17/arch/sparc/kernel/unaligned_64.c 2014-08-14 03:38:34.000000000 +0200
  41722. +++ linux-imx6-3.14/arch/sparc/kernel/unaligned_64.c 2014-09-11 18:05:57.774021083 +0200
  41723. @@ -166,23 +166,17 @@
  41724. unsigned long compute_effective_address(struct pt_regs *regs,
  41725. unsigned int insn, unsigned int rd)
  41726. {
  41727. - int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
  41728. unsigned int rs1 = (insn >> 14) & 0x1f;
  41729. unsigned int rs2 = insn & 0x1f;
  41730. - unsigned long addr;
  41731. + int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
  41732. if (insn & 0x2000) {
  41733. maybe_flush_windows(rs1, 0, rd, from_kernel);
  41734. - addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
  41735. + return (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
  41736. } else {
  41737. maybe_flush_windows(rs1, rs2, rd, from_kernel);
  41738. - addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
  41739. + return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
  41740. }
  41741. -
  41742. - if (!from_kernel && test_thread_flag(TIF_32BIT))
  41743. - addr &= 0xffffffff;
  41744. -
  41745. - return addr;
  41746. }
  41747. /* This is just to make gcc think die_if_kernel does return... */
  41748. diff -Nur linux-3.14.17/arch/sparc/lib/NG2memcpy.S linux-imx6-3.14/arch/sparc/lib/NG2memcpy.S
  41749. --- linux-3.14.17/arch/sparc/lib/NG2memcpy.S 2014-08-14 03:38:34.000000000 +0200
  41750. +++ linux-imx6-3.14/arch/sparc/lib/NG2memcpy.S 2014-09-11 18:05:57.814021242 +0200
  41751. @@ -236,7 +236,6 @@
  41752. */
  41753. VISEntryHalf
  41754. - membar #Sync
  41755. alignaddr %o1, %g0, %g0
  41756. add %o1, (64 - 1), %o4
  41757. diff -Nur linux-3.14.17/arch/sparc/math-emu/math_32.c linux-imx6-3.14/arch/sparc/math-emu/math_32.c
  41758. --- linux-3.14.17/arch/sparc/math-emu/math_32.c 2014-08-14 03:38:34.000000000 +0200
  41759. +++ linux-imx6-3.14/arch/sparc/math-emu/math_32.c 2014-09-11 18:05:57.866021451 +0200
  41760. @@ -499,7 +499,7 @@
  41761. case 0: fsr = *pfsr;
  41762. if (IR == -1) IR = 2;
  41763. /* fcc is always fcc0 */
  41764. - fsr &= ~0xc00; fsr |= (IR << 10);
  41765. + fsr &= ~0xc00; fsr |= (IR << 10); break;
  41766. *pfsr = fsr;
  41767. break;
  41768. case 1: rd->s = IR; break;
  41769. diff -Nur linux-3.14.17/arch/sparc/mm/fault_64.c linux-imx6-3.14/arch/sparc/mm/fault_64.c
  41770. --- linux-3.14.17/arch/sparc/mm/fault_64.c 2014-08-14 03:38:34.000000000 +0200
  41771. +++ linux-imx6-3.14/arch/sparc/mm/fault_64.c 2014-09-11 18:05:57.866021451 +0200
  41772. @@ -96,51 +96,38 @@
  41773. pte_t *ptep, pte;
  41774. unsigned long pa;
  41775. u32 insn = 0;
  41776. + unsigned long pstate;
  41777. - if (pgd_none(*pgdp) || unlikely(pgd_bad(*pgdp)))
  41778. - goto out;
  41779. + if (pgd_none(*pgdp))
  41780. + goto outret;
  41781. pudp = pud_offset(pgdp, tpc);
  41782. - if (pud_none(*pudp) || unlikely(pud_bad(*pudp)))
  41783. - goto out;
  41784. + if (pud_none(*pudp))
  41785. + goto outret;
  41786. + pmdp = pmd_offset(pudp, tpc);
  41787. + if (pmd_none(*pmdp))
  41788. + goto outret;
  41789. /* This disables preemption for us as well. */
  41790. - local_irq_disable();
  41791. + __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
  41792. + __asm__ __volatile__("wrpr %0, %1, %%pstate"
  41793. + : : "r" (pstate), "i" (PSTATE_IE));
  41794. + ptep = pte_offset_map(pmdp, tpc);
  41795. + pte = *ptep;
  41796. + if (!pte_present(pte))
  41797. + goto out;
  41798. - pmdp = pmd_offset(pudp, tpc);
  41799. - if (pmd_none(*pmdp) || unlikely(pmd_bad(*pmdp)))
  41800. - goto out_irq_enable;
  41801. + pa = (pte_pfn(pte) << PAGE_SHIFT);
  41802. + pa += (tpc & ~PAGE_MASK);
  41803. +
  41804. + /* Use phys bypass so we don't pollute dtlb/dcache. */
  41805. + __asm__ __volatile__("lduwa [%1] %2, %0"
  41806. + : "=r" (insn)
  41807. + : "r" (pa), "i" (ASI_PHYS_USE_EC));
  41808. -#ifdef CONFIG_TRANSPARENT_HUGEPAGE
  41809. - if (pmd_trans_huge(*pmdp)) {
  41810. - if (pmd_trans_splitting(*pmdp))
  41811. - goto out_irq_enable;
  41812. -
  41813. - pa = pmd_pfn(*pmdp) << PAGE_SHIFT;
  41814. - pa += tpc & ~HPAGE_MASK;
  41815. -
  41816. - /* Use phys bypass so we don't pollute dtlb/dcache. */
  41817. - __asm__ __volatile__("lduwa [%1] %2, %0"
  41818. - : "=r" (insn)
  41819. - : "r" (pa), "i" (ASI_PHYS_USE_EC));
  41820. - } else
  41821. -#endif
  41822. - {
  41823. - ptep = pte_offset_map(pmdp, tpc);
  41824. - pte = *ptep;
  41825. - if (pte_present(pte)) {
  41826. - pa = (pte_pfn(pte) << PAGE_SHIFT);
  41827. - pa += (tpc & ~PAGE_MASK);
  41828. -
  41829. - /* Use phys bypass so we don't pollute dtlb/dcache. */
  41830. - __asm__ __volatile__("lduwa [%1] %2, %0"
  41831. - : "=r" (insn)
  41832. - : "r" (pa), "i" (ASI_PHYS_USE_EC));
  41833. - }
  41834. - pte_unmap(ptep);
  41835. - }
  41836. -out_irq_enable:
  41837. - local_irq_enable();
  41838. out:
  41839. + pte_unmap(ptep);
  41840. + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
  41841. +outret:
  41842. return insn;
  41843. }
  41844. @@ -166,8 +153,7 @@
  41845. }
  41846. static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
  41847. - unsigned long fault_addr, unsigned int insn,
  41848. - int fault_code)
  41849. + unsigned int insn, int fault_code)
  41850. {
  41851. unsigned long addr;
  41852. siginfo_t info;
  41853. @@ -175,18 +161,10 @@
  41854. info.si_code = code;
  41855. info.si_signo = sig;
  41856. info.si_errno = 0;
  41857. - if (fault_code & FAULT_CODE_ITLB) {
  41858. + if (fault_code & FAULT_CODE_ITLB)
  41859. addr = regs->tpc;
  41860. - } else {
  41861. - /* If we were able to probe the faulting instruction, use it
  41862. - * to compute a precise fault address. Otherwise use the fault
  41863. - * time provided address which may only have page granularity.
  41864. - */
  41865. - if (insn)
  41866. - addr = compute_effective_address(regs, insn, 0);
  41867. - else
  41868. - addr = fault_addr;
  41869. - }
  41870. + else
  41871. + addr = compute_effective_address(regs, insn, 0);
  41872. info.si_addr = (void __user *) addr;
  41873. info.si_trapno = 0;
  41874. @@ -261,7 +239,7 @@
  41875. /* The si_code was set to make clear whether
  41876. * this was a SEGV_MAPERR or SEGV_ACCERR fault.
  41877. */
  41878. - do_fault_siginfo(si_code, SIGSEGV, regs, address, insn, fault_code);
  41879. + do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code);
  41880. return;
  41881. }
  41882. @@ -281,6 +259,18 @@
  41883. show_regs(regs);
  41884. }
  41885. +static void noinline __kprobes bogus_32bit_fault_address(struct pt_regs *regs,
  41886. + unsigned long addr)
  41887. +{
  41888. + static int times;
  41889. +
  41890. + if (times++ < 10)
  41891. + printk(KERN_ERR "FAULT[%s:%d]: 32-bit process "
  41892. + "reports 64-bit fault address [%lx]\n",
  41893. + current->comm, current->pid, addr);
  41894. + show_regs(regs);
  41895. +}
  41896. +
  41897. asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
  41898. {
  41899. enum ctx_state prev_state = exception_enter();
  41900. @@ -310,8 +300,10 @@
  41901. goto intr_or_no_mm;
  41902. }
  41903. }
  41904. - if (unlikely((address >> 32) != 0))
  41905. + if (unlikely((address >> 32) != 0)) {
  41906. + bogus_32bit_fault_address(regs, address);
  41907. goto intr_or_no_mm;
  41908. + }
  41909. }
  41910. if (regs->tstate & TSTATE_PRIV) {
  41911. @@ -533,7 +525,7 @@
  41912. * Send a sigbus, regardless of whether we were in kernel
  41913. * or user mode.
  41914. */
  41915. - do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, address, insn, fault_code);
  41916. + do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code);
  41917. /* Kernel mode? Handle exceptions or die */
  41918. if (regs->tstate & TSTATE_PRIV)
  41919. diff -Nur linux-3.14.17/arch/sparc/mm/gup.c linux-imx6-3.14/arch/sparc/mm/gup.c
  41920. --- linux-3.14.17/arch/sparc/mm/gup.c 2014-08-14 03:38:34.000000000 +0200
  41921. +++ linux-imx6-3.14/arch/sparc/mm/gup.c 2014-09-11 18:05:57.866021451 +0200
  41922. @@ -73,7 +73,7 @@
  41923. struct page *head, *page, *tail;
  41924. int refs;
  41925. - if (!(pmd_val(pmd) & _PAGE_VALID))
  41926. + if (!pmd_large(pmd))
  41927. return 0;
  41928. if (write && !pmd_write(pmd))
  41929. diff -Nur linux-3.14.17/arch/sparc/mm/init_64.c linux-imx6-3.14/arch/sparc/mm/init_64.c
  41930. --- linux-3.14.17/arch/sparc/mm/init_64.c 2014-08-14 03:38:34.000000000 +0200
  41931. +++ linux-imx6-3.14/arch/sparc/mm/init_64.c 2014-09-11 18:05:57.870021467 +0200
  41932. @@ -350,10 +350,6 @@
  41933. mm = vma->vm_mm;
  41934. - /* Don't insert a non-valid PTE into the TSB, we'll deadlock. */
  41935. - if (!pte_accessible(mm, pte))
  41936. - return;
  41937. -
  41938. spin_lock_irqsave(&mm->context.lock, flags);
  41939. #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
  41940. @@ -592,7 +588,7 @@
  41941. int i, tlb_ent = sparc64_highest_locked_tlbent();
  41942. tte_vaddr = (unsigned long) KERNBASE;
  41943. - phys_page = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB;
  41944. + phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
  41945. tte_data = kern_large_tte(phys_page);
  41946. kern_locked_tte_data = tte_data;
  41947. @@ -1885,7 +1881,7 @@
  41948. BUILD_BUG_ON(NR_CPUS > 4096);
  41949. - kern_base = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB;
  41950. + kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
  41951. kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
  41952. /* Invalidate both kernel TSBs. */
  41953. @@ -1941,7 +1937,7 @@
  41954. shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE);
  41955. real_end = (unsigned long)_end;
  41956. - num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << ILOG2_4MB);
  41957. + num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << 22);
  41958. printk("Kernel: Using %d locked TLB entries for main kernel image.\n",
  41959. num_kernel_image_mappings);
  41960. @@ -2098,7 +2094,7 @@
  41961. if (new_start <= old_start &&
  41962. new_end >= (old_start + PAGE_SIZE)) {
  41963. - set_bit(old_start >> ILOG2_4MB, bitmap);
  41964. + set_bit(old_start >> 22, bitmap);
  41965. goto do_next_page;
  41966. }
  41967. }
  41968. @@ -2147,7 +2143,7 @@
  41969. addr = PAGE_OFFSET + kern_base;
  41970. last = PAGE_ALIGN(kern_size) + addr;
  41971. while (addr < last) {
  41972. - set_bit(__pa(addr) >> ILOG2_4MB, sparc64_valid_addr_bitmap);
  41973. + set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap);
  41974. addr += PAGE_SIZE;
  41975. }
  41976. @@ -2271,7 +2267,7 @@
  41977. void *block;
  41978. if (!(*vmem_pp & _PAGE_VALID)) {
  41979. - block = vmemmap_alloc_block(1UL << ILOG2_4MB, node);
  41980. + block = vmemmap_alloc_block(1UL << 22, node);
  41981. if (!block)
  41982. return -ENOMEM;
  41983. @@ -2618,10 +2614,6 @@
  41984. pte = pmd_val(entry);
  41985. - /* Don't insert a non-valid PMD into the TSB, we'll deadlock. */
  41986. - if (!(pte & _PAGE_VALID))
  41987. - return;
  41988. -
  41989. /* We are fabricating 8MB pages using 4MB real hw pages. */
  41990. pte |= (addr & (1UL << REAL_HPAGE_SHIFT));
  41991. @@ -2702,26 +2694,3 @@
  41992. }
  41993. }
  41994. #endif
  41995. -
  41996. -#ifdef CONFIG_SMP
  41997. -#define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range
  41998. -#else
  41999. -#define do_flush_tlb_kernel_range __flush_tlb_kernel_range
  42000. -#endif
  42001. -
  42002. -void flush_tlb_kernel_range(unsigned long start, unsigned long end)
  42003. -{
  42004. - if (start < HI_OBP_ADDRESS && end > LOW_OBP_ADDRESS) {
  42005. - if (start < LOW_OBP_ADDRESS) {
  42006. - flush_tsb_kernel_range(start, LOW_OBP_ADDRESS);
  42007. - do_flush_tlb_kernel_range(start, LOW_OBP_ADDRESS);
  42008. - }
  42009. - if (end > HI_OBP_ADDRESS) {
  42010. - flush_tsb_kernel_range(end, HI_OBP_ADDRESS);
  42011. - do_flush_tlb_kernel_range(end, HI_OBP_ADDRESS);
  42012. - }
  42013. - } else {
  42014. - flush_tsb_kernel_range(start, end);
  42015. - do_flush_tlb_kernel_range(start, end);
  42016. - }
  42017. -}
  42018. diff -Nur linux-3.14.17/arch/sparc/mm/tlb.c linux-imx6-3.14/arch/sparc/mm/tlb.c
  42019. --- linux-3.14.17/arch/sparc/mm/tlb.c 2014-08-14 03:38:34.000000000 +0200
  42020. +++ linux-imx6-3.14/arch/sparc/mm/tlb.c 2014-09-11 18:05:57.870021467 +0200
  42021. @@ -134,7 +134,7 @@
  42022. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  42023. static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
  42024. - pmd_t pmd)
  42025. + pmd_t pmd, bool exec)
  42026. {
  42027. unsigned long end;
  42028. pte_t *pte;
  42029. @@ -142,11 +142,8 @@
  42030. pte = pte_offset_map(&pmd, vaddr);
  42031. end = vaddr + HPAGE_SIZE;
  42032. while (vaddr < end) {
  42033. - if (pte_val(*pte) & _PAGE_VALID) {
  42034. - bool exec = pte_exec(*pte);
  42035. -
  42036. + if (pte_val(*pte) & _PAGE_VALID)
  42037. tlb_batch_add_one(mm, vaddr, exec);
  42038. - }
  42039. pte++;
  42040. vaddr += PAGE_SIZE;
  42041. }
  42042. @@ -180,30 +177,19 @@
  42043. }
  42044. if (!pmd_none(orig)) {
  42045. + pte_t orig_pte = __pte(pmd_val(orig));
  42046. + bool exec = pte_exec(orig_pte);
  42047. +
  42048. addr &= HPAGE_MASK;
  42049. if (pmd_trans_huge(orig)) {
  42050. - pte_t orig_pte = __pte(pmd_val(orig));
  42051. - bool exec = pte_exec(orig_pte);
  42052. -
  42053. tlb_batch_add_one(mm, addr, exec);
  42054. tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
  42055. } else {
  42056. - tlb_batch_pmd_scan(mm, addr, orig);
  42057. + tlb_batch_pmd_scan(mm, addr, orig, exec);
  42058. }
  42059. }
  42060. }
  42061. -void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
  42062. - pmd_t *pmdp)
  42063. -{
  42064. - pmd_t entry = *pmdp;
  42065. -
  42066. - pmd_val(entry) &= ~_PAGE_VALID;
  42067. -
  42068. - set_pmd_at(vma->vm_mm, address, pmdp, entry);
  42069. - flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
  42070. -}
  42071. -
  42072. void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
  42073. pgtable_t pgtable)
  42074. {
  42075. diff -Nur linux-3.14.17/arch/sparc/mm/tsb.c linux-imx6-3.14/arch/sparc/mm/tsb.c
  42076. --- linux-3.14.17/arch/sparc/mm/tsb.c 2014-08-14 03:38:34.000000000 +0200
  42077. +++ linux-imx6-3.14/arch/sparc/mm/tsb.c 2014-09-11 18:05:57.870021467 +0200
  42078. @@ -133,19 +133,7 @@
  42079. mm->context.tsb_block[tsb_idx].tsb_nentries =
  42080. tsb_bytes / sizeof(struct tsb);
  42081. - switch (tsb_idx) {
  42082. - case MM_TSB_BASE:
  42083. - base = TSBMAP_8K_BASE;
  42084. - break;
  42085. -#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
  42086. - case MM_TSB_HUGE:
  42087. - base = TSBMAP_4M_BASE;
  42088. - break;
  42089. -#endif
  42090. - default:
  42091. - BUG();
  42092. - }
  42093. -
  42094. + base = TSBMAP_BASE;
  42095. tte = pgprot_val(PAGE_KERNEL_LOCKED);
  42096. tsb_paddr = __pa(mm->context.tsb_block[tsb_idx].tsb);
  42097. BUG_ON(tsb_paddr & (tsb_bytes - 1UL));
  42098. diff -Nur linux-3.14.17/arch/x86/boot/header.S linux-imx6-3.14/arch/x86/boot/header.S
  42099. --- linux-3.14.17/arch/x86/boot/header.S 2014-08-14 03:38:34.000000000 +0200
  42100. +++ linux-imx6-3.14/arch/x86/boot/header.S 2014-09-11 18:05:58.266023049 +0200
  42101. @@ -91,9 +91,10 @@
  42102. .section ".bsdata", "a"
  42103. bugger_off_msg:
  42104. - .ascii "Use a boot loader.\r\n"
  42105. + .ascii "Direct floppy boot is not supported. "
  42106. + .ascii "Use a boot loader program instead.\r\n"
  42107. .ascii "\n"
  42108. - .ascii "Remove disk and press any key to reboot...\r\n"
  42109. + .ascii "Remove disk and press any key to reboot ...\r\n"
  42110. .byte 0
  42111. #ifdef CONFIG_EFI_STUB
  42112. @@ -107,7 +108,7 @@
  42113. #else
  42114. .word 0x8664 # x86-64
  42115. #endif
  42116. - .word 4 # nr_sections
  42117. + .word 3 # nr_sections
  42118. .long 0 # TimeDateStamp
  42119. .long 0 # PointerToSymbolTable
  42120. .long 1 # NumberOfSymbols
  42121. @@ -249,25 +250,6 @@
  42122. .word 0 # NumberOfLineNumbers
  42123. .long 0x60500020 # Characteristics (section flags)
  42124. - #
  42125. - # The offset & size fields are filled in by build.c.
  42126. - #
  42127. - .ascii ".bss"
  42128. - .byte 0
  42129. - .byte 0
  42130. - .byte 0
  42131. - .byte 0
  42132. - .long 0
  42133. - .long 0x0
  42134. - .long 0 # Size of initialized data
  42135. - # on disk
  42136. - .long 0x0
  42137. - .long 0 # PointerToRelocations
  42138. - .long 0 # PointerToLineNumbers
  42139. - .word 0 # NumberOfRelocations
  42140. - .word 0 # NumberOfLineNumbers
  42141. - .long 0xc8000080 # Characteristics (section flags)
  42142. -
  42143. #endif /* CONFIG_EFI_STUB */
  42144. # Kernel attributes; used by setup. This is part 1 of the
  42145. diff -Nur linux-3.14.17/arch/x86/boot/tools/build.c linux-imx6-3.14/arch/x86/boot/tools/build.c
  42146. --- linux-3.14.17/arch/x86/boot/tools/build.c 2014-08-14 03:38:34.000000000 +0200
  42147. +++ linux-imx6-3.14/arch/x86/boot/tools/build.c 2014-09-11 18:05:58.326023289 +0200
  42148. @@ -142,7 +142,7 @@
  42149. #ifdef CONFIG_EFI_STUB
  42150. -static void update_pecoff_section_header_fields(char *section_name, u32 vma, u32 size, u32 datasz, u32 offset)
  42151. +static void update_pecoff_section_header(char *section_name, u32 offset, u32 size)
  42152. {
  42153. unsigned int pe_header;
  42154. unsigned short num_sections;
  42155. @@ -163,10 +163,10 @@
  42156. put_unaligned_le32(size, section + 0x8);
  42157. /* section header vma field */
  42158. - put_unaligned_le32(vma, section + 0xc);
  42159. + put_unaligned_le32(offset, section + 0xc);
  42160. /* section header 'size of initialised data' field */
  42161. - put_unaligned_le32(datasz, section + 0x10);
  42162. + put_unaligned_le32(size, section + 0x10);
  42163. /* section header 'file offset' field */
  42164. put_unaligned_le32(offset, section + 0x14);
  42165. @@ -178,11 +178,6 @@
  42166. }
  42167. }
  42168. -static void update_pecoff_section_header(char *section_name, u32 offset, u32 size)
  42169. -{
  42170. - update_pecoff_section_header_fields(section_name, offset, size, size, offset);
  42171. -}
  42172. -
  42173. static void update_pecoff_setup_and_reloc(unsigned int size)
  42174. {
  42175. u32 setup_offset = 0x200;
  42176. @@ -207,6 +202,9 @@
  42177. pe_header = get_unaligned_le32(&buf[0x3c]);
  42178. + /* Size of image */
  42179. + put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
  42180. +
  42181. /*
  42182. * Size of code: Subtract the size of the first sector (512 bytes)
  42183. * which includes the header.
  42184. @@ -221,22 +219,6 @@
  42185. update_pecoff_section_header(".text", text_start, text_sz);
  42186. }
  42187. -static void update_pecoff_bss(unsigned int file_sz, unsigned int init_sz)
  42188. -{
  42189. - unsigned int pe_header;
  42190. - unsigned int bss_sz = init_sz - file_sz;
  42191. -
  42192. - pe_header = get_unaligned_le32(&buf[0x3c]);
  42193. -
  42194. - /* Size of uninitialized data */
  42195. - put_unaligned_le32(bss_sz, &buf[pe_header + 0x24]);
  42196. -
  42197. - /* Size of image */
  42198. - put_unaligned_le32(init_sz, &buf[pe_header + 0x50]);
  42199. -
  42200. - update_pecoff_section_header_fields(".bss", file_sz, bss_sz, 0, 0);
  42201. -}
  42202. -
  42203. #endif /* CONFIG_EFI_STUB */
  42204. @@ -288,9 +270,6 @@
  42205. int fd;
  42206. void *kernel;
  42207. u32 crc = 0xffffffffUL;
  42208. -#ifdef CONFIG_EFI_STUB
  42209. - unsigned int init_sz;
  42210. -#endif
  42211. /* Defaults for old kernel */
  42212. #ifdef CONFIG_X86_32
  42213. @@ -364,9 +343,7 @@
  42214. put_unaligned_le32(sys_size, &buf[0x1f4]);
  42215. #ifdef CONFIG_EFI_STUB
  42216. - update_pecoff_text(setup_sectors * 512, i + (sys_size * 16));
  42217. - init_sz = get_unaligned_le32(&buf[0x260]);
  42218. - update_pecoff_bss(i + (sys_size * 16), init_sz);
  42219. + update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
  42220. #ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
  42221. efi_stub_entry -= 0x200;
  42222. diff -Nur linux-3.14.17/arch/x86/include/asm/espfix.h linux-imx6-3.14/arch/x86/include/asm/espfix.h
  42223. --- linux-3.14.17/arch/x86/include/asm/espfix.h 2014-08-14 03:38:34.000000000 +0200
  42224. +++ linux-imx6-3.14/arch/x86/include/asm/espfix.h 1970-01-01 01:00:00.000000000 +0100
  42225. @@ -1,16 +0,0 @@
  42226. -#ifndef _ASM_X86_ESPFIX_H
  42227. -#define _ASM_X86_ESPFIX_H
  42228. -
  42229. -#ifdef CONFIG_X86_64
  42230. -
  42231. -#include <asm/percpu.h>
  42232. -
  42233. -DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
  42234. -DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr);
  42235. -
  42236. -extern void init_espfix_bsp(void);
  42237. -extern void init_espfix_ap(void);
  42238. -
  42239. -#endif /* CONFIG_X86_64 */
  42240. -
  42241. -#endif /* _ASM_X86_ESPFIX_H */
  42242. diff -Nur linux-3.14.17/arch/x86/include/asm/irqflags.h linux-imx6-3.14/arch/x86/include/asm/irqflags.h
  42243. --- linux-3.14.17/arch/x86/include/asm/irqflags.h 2014-08-14 03:38:34.000000000 +0200
  42244. +++ linux-imx6-3.14/arch/x86/include/asm/irqflags.h 2014-09-11 18:05:58.386023528 +0200
  42245. @@ -129,7 +129,7 @@
  42246. #define PARAVIRT_ADJUST_EXCEPTION_FRAME /* */
  42247. -#define INTERRUPT_RETURN jmp native_iret
  42248. +#define INTERRUPT_RETURN iretq
  42249. #define USERGS_SYSRET64 \
  42250. swapgs; \
  42251. sysretq;
  42252. diff -Nur linux-3.14.17/arch/x86/include/asm/pgtable_64_types.h linux-imx6-3.14/arch/x86/include/asm/pgtable_64_types.h
  42253. --- linux-3.14.17/arch/x86/include/asm/pgtable_64_types.h 2014-08-14 03:38:34.000000000 +0200
  42254. +++ linux-imx6-3.14/arch/x86/include/asm/pgtable_64_types.h 2014-09-11 18:05:58.390023544 +0200
  42255. @@ -61,8 +61,6 @@
  42256. #define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
  42257. #define MODULES_END _AC(0xffffffffff000000, UL)
  42258. #define MODULES_LEN (MODULES_END - MODULES_VADDR)
  42259. -#define ESPFIX_PGD_ENTRY _AC(-2, UL)
  42260. -#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
  42261. #define EARLY_DYNAMIC_PAGE_TABLES 64
  42262. diff -Nur linux-3.14.17/arch/x86/include/asm/setup.h linux-imx6-3.14/arch/x86/include/asm/setup.h
  42263. --- linux-3.14.17/arch/x86/include/asm/setup.h 2014-08-14 03:38:34.000000000 +0200
  42264. +++ linux-imx6-3.14/arch/x86/include/asm/setup.h 2014-09-11 18:05:58.414023641 +0200
  42265. @@ -65,8 +65,6 @@
  42266. #ifndef _SETUP
  42267. -#include <asm/espfix.h>
  42268. -
  42269. /*
  42270. * This is set up by the setup-routine at boot-time
  42271. */
  42272. diff -Nur linux-3.14.17/arch/x86/Kconfig linux-imx6-3.14/arch/x86/Kconfig
  42273. --- linux-3.14.17/arch/x86/Kconfig 2014-08-14 03:38:34.000000000 +0200
  42274. +++ linux-imx6-3.14/arch/x86/Kconfig 2014-09-11 18:05:58.262023032 +0200
  42275. @@ -966,27 +966,10 @@
  42276. default y
  42277. depends on X86_32
  42278. ---help---
  42279. - This option is required by programs like DOSEMU to run
  42280. - 16-bit real mode legacy code on x86 processors. It also may
  42281. - be needed by software like XFree86 to initialize some video
  42282. - cards via BIOS. Disabling this option saves about 6K.
  42283. -
  42284. -config X86_16BIT
  42285. - bool "Enable support for 16-bit segments" if EXPERT
  42286. - default y
  42287. - ---help---
  42288. - This option is required by programs like Wine to run 16-bit
  42289. - protected mode legacy code on x86 processors. Disabling
  42290. - this option saves about 300 bytes on i386, or around 6K text
  42291. - plus 16K runtime memory on x86-64,
  42292. -
  42293. -config X86_ESPFIX32
  42294. - def_bool y
  42295. - depends on X86_16BIT && X86_32
  42296. -
  42297. -config X86_ESPFIX64
  42298. - def_bool y
  42299. - depends on X86_16BIT && X86_64
  42300. + This option is required by programs like DOSEMU to run 16-bit legacy
  42301. + code on X86 processors. It also may be needed by software like
  42302. + XFree86 to initialize some video cards via BIOS. Disabling this
  42303. + option saves about 6k.
  42304. config TOSHIBA
  42305. tristate "Toshiba Laptop support"
  42306. diff -Nur linux-3.14.17/arch/x86/kernel/entry_32.S linux-imx6-3.14/arch/x86/kernel/entry_32.S
  42307. --- linux-3.14.17/arch/x86/kernel/entry_32.S 2014-08-14 03:38:34.000000000 +0200
  42308. +++ linux-imx6-3.14/arch/x86/kernel/entry_32.S 2014-09-11 18:05:58.538024137 +0200
  42309. @@ -433,8 +433,8 @@
  42310. cmpl $(NR_syscalls), %eax
  42311. jae sysenter_badsys
  42312. call *sys_call_table(,%eax,4)
  42313. -sysenter_after_call:
  42314. movl %eax,PT_EAX(%esp)
  42315. +sysenter_after_call:
  42316. LOCKDEP_SYS_EXIT
  42317. DISABLE_INTERRUPTS(CLBR_ANY)
  42318. TRACE_IRQS_OFF
  42319. @@ -514,7 +514,6 @@
  42320. jae syscall_badsys
  42321. syscall_call:
  42322. call *sys_call_table(,%eax,4)
  42323. -syscall_after_call:
  42324. movl %eax,PT_EAX(%esp) # store the return value
  42325. syscall_exit:
  42326. LOCKDEP_SYS_EXIT
  42327. @@ -529,7 +528,6 @@
  42328. restore_all:
  42329. TRACE_IRQS_IRET
  42330. restore_all_notrace:
  42331. -#ifdef CONFIG_X86_ESPFIX32
  42332. movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
  42333. # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
  42334. # are returning to the kernel.
  42335. @@ -540,7 +538,6 @@
  42336. cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
  42337. CFI_REMEMBER_STATE
  42338. je ldt_ss # returning to user-space with LDT SS
  42339. -#endif
  42340. restore_nocheck:
  42341. RESTORE_REGS 4 # skip orig_eax/error_code
  42342. irq_return:
  42343. @@ -553,7 +550,6 @@
  42344. .previous
  42345. _ASM_EXTABLE(irq_return,iret_exc)
  42346. -#ifdef CONFIG_X86_ESPFIX32
  42347. CFI_RESTORE_STATE
  42348. ldt_ss:
  42349. #ifdef CONFIG_PARAVIRT
  42350. @@ -597,7 +593,6 @@
  42351. lss (%esp), %esp /* switch to espfix segment */
  42352. CFI_ADJUST_CFA_OFFSET -8
  42353. jmp restore_nocheck
  42354. -#endif
  42355. CFI_ENDPROC
  42356. ENDPROC(system_call)
  42357. @@ -688,12 +683,12 @@
  42358. END(syscall_fault)
  42359. syscall_badsys:
  42360. - movl $-ENOSYS,%eax
  42361. - jmp syscall_after_call
  42362. + movl $-ENOSYS,PT_EAX(%esp)
  42363. + jmp syscall_exit
  42364. END(syscall_badsys)
  42365. sysenter_badsys:
  42366. - movl $-ENOSYS,%eax
  42367. + movl $-ENOSYS,PT_EAX(%esp)
  42368. jmp sysenter_after_call
  42369. END(syscall_badsys)
  42370. CFI_ENDPROC
  42371. @@ -710,7 +705,6 @@
  42372. * the high word of the segment base from the GDT and swiches to the
  42373. * normal stack and adjusts ESP with the matching offset.
  42374. */
  42375. -#ifdef CONFIG_X86_ESPFIX32
  42376. /* fixup the stack */
  42377. mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
  42378. mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
  42379. @@ -720,10 +714,8 @@
  42380. pushl_cfi %eax
  42381. lss (%esp), %esp /* switch to the normal stack segment */
  42382. CFI_ADJUST_CFA_OFFSET -8
  42383. -#endif
  42384. .endm
  42385. .macro UNWIND_ESPFIX_STACK
  42386. -#ifdef CONFIG_X86_ESPFIX32
  42387. movl %ss, %eax
  42388. /* see if on espfix stack */
  42389. cmpw $__ESPFIX_SS, %ax
  42390. @@ -734,7 +726,6 @@
  42391. /* switch to normal stack */
  42392. FIXUP_ESPFIX_STACK
  42393. 27:
  42394. -#endif
  42395. .endm
  42396. /*
  42397. @@ -1365,13 +1356,11 @@
  42398. ENTRY(nmi)
  42399. RING0_INT_FRAME
  42400. ASM_CLAC
  42401. -#ifdef CONFIG_X86_ESPFIX32
  42402. pushl_cfi %eax
  42403. movl %ss, %eax
  42404. cmpw $__ESPFIX_SS, %ax
  42405. popl_cfi %eax
  42406. je nmi_espfix_stack
  42407. -#endif
  42408. cmpl $ia32_sysenter_target,(%esp)
  42409. je nmi_stack_fixup
  42410. pushl_cfi %eax
  42411. @@ -1411,7 +1400,6 @@
  42412. FIX_STACK 24, nmi_stack_correct, 1
  42413. jmp nmi_stack_correct
  42414. -#ifdef CONFIG_X86_ESPFIX32
  42415. nmi_espfix_stack:
  42416. /* We have a RING0_INT_FRAME here.
  42417. *
  42418. @@ -1433,7 +1421,6 @@
  42419. lss 12+4(%esp), %esp # back to espfix stack
  42420. CFI_ADJUST_CFA_OFFSET -24
  42421. jmp irq_return
  42422. -#endif
  42423. CFI_ENDPROC
  42424. END(nmi)
  42425. diff -Nur linux-3.14.17/arch/x86/kernel/entry_64.S linux-imx6-3.14/arch/x86/kernel/entry_64.S
  42426. --- linux-3.14.17/arch/x86/kernel/entry_64.S 2014-08-14 03:38:34.000000000 +0200
  42427. +++ linux-imx6-3.14/arch/x86/kernel/entry_64.S 2014-09-11 18:05:58.538024137 +0200
  42428. @@ -58,7 +58,6 @@
  42429. #include <asm/asm.h>
  42430. #include <asm/context_tracking.h>
  42431. #include <asm/smap.h>
  42432. -#include <asm/pgtable_types.h>
  42433. #include <linux/err.h>
  42434. /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
  42435. @@ -1042,45 +1041,12 @@
  42436. irq_return:
  42437. INTERRUPT_RETURN
  42438. + _ASM_EXTABLE(irq_return, bad_iret)
  42439. +#ifdef CONFIG_PARAVIRT
  42440. ENTRY(native_iret)
  42441. - /*
  42442. - * Are we returning to a stack segment from the LDT? Note: in
  42443. - * 64-bit mode SS:RSP on the exception stack is always valid.
  42444. - */
  42445. -#ifdef CONFIG_X86_ESPFIX64
  42446. - testb $4,(SS-RIP)(%rsp)
  42447. - jnz native_irq_return_ldt
  42448. -#endif
  42449. -
  42450. -native_irq_return_iret:
  42451. iretq
  42452. - _ASM_EXTABLE(native_irq_return_iret, bad_iret)
  42453. -
  42454. -#ifdef CONFIG_X86_ESPFIX64
  42455. -native_irq_return_ldt:
  42456. - pushq_cfi %rax
  42457. - pushq_cfi %rdi
  42458. - SWAPGS
  42459. - movq PER_CPU_VAR(espfix_waddr),%rdi
  42460. - movq %rax,(0*8)(%rdi) /* RAX */
  42461. - movq (2*8)(%rsp),%rax /* RIP */
  42462. - movq %rax,(1*8)(%rdi)
  42463. - movq (3*8)(%rsp),%rax /* CS */
  42464. - movq %rax,(2*8)(%rdi)
  42465. - movq (4*8)(%rsp),%rax /* RFLAGS */
  42466. - movq %rax,(3*8)(%rdi)
  42467. - movq (6*8)(%rsp),%rax /* SS */
  42468. - movq %rax,(5*8)(%rdi)
  42469. - movq (5*8)(%rsp),%rax /* RSP */
  42470. - movq %rax,(4*8)(%rdi)
  42471. - andl $0xffff0000,%eax
  42472. - popq_cfi %rdi
  42473. - orq PER_CPU_VAR(espfix_stack),%rax
  42474. - SWAPGS
  42475. - movq %rax,%rsp
  42476. - popq_cfi %rax
  42477. - jmp native_irq_return_iret
  42478. + _ASM_EXTABLE(native_iret, bad_iret)
  42479. #endif
  42480. .section .fixup,"ax"
  42481. @@ -1144,40 +1110,9 @@
  42482. call preempt_schedule_irq
  42483. jmp exit_intr
  42484. #endif
  42485. - CFI_ENDPROC
  42486. -END(common_interrupt)
  42487. - /*
  42488. - * If IRET takes a fault on the espfix stack, then we
  42489. - * end up promoting it to a doublefault. In that case,
  42490. - * modify the stack to make it look like we just entered
  42491. - * the #GP handler from user space, similar to bad_iret.
  42492. - */
  42493. -#ifdef CONFIG_X86_ESPFIX64
  42494. - ALIGN
  42495. -__do_double_fault:
  42496. - XCPT_FRAME 1 RDI+8
  42497. - movq RSP(%rdi),%rax /* Trap on the espfix stack? */
  42498. - sarq $PGDIR_SHIFT,%rax
  42499. - cmpl $ESPFIX_PGD_ENTRY,%eax
  42500. - jne do_double_fault /* No, just deliver the fault */
  42501. - cmpl $__KERNEL_CS,CS(%rdi)
  42502. - jne do_double_fault
  42503. - movq RIP(%rdi),%rax
  42504. - cmpq $native_irq_return_iret,%rax
  42505. - jne do_double_fault /* This shouldn't happen... */
  42506. - movq PER_CPU_VAR(kernel_stack),%rax
  42507. - subq $(6*8-KERNEL_STACK_OFFSET),%rax /* Reset to original stack */
  42508. - movq %rax,RSP(%rdi)
  42509. - movq $0,(%rax) /* Missing (lost) #GP error code */
  42510. - movq $general_protection,RIP(%rdi)
  42511. - retq
  42512. CFI_ENDPROC
  42513. -END(__do_double_fault)
  42514. -#else
  42515. -# define __do_double_fault do_double_fault
  42516. -#endif
  42517. -
  42518. +END(common_interrupt)
  42519. /*
  42520. * End of kprobes section
  42521. */
  42522. @@ -1379,7 +1314,7 @@
  42523. zeroentry bounds do_bounds
  42524. zeroentry invalid_op do_invalid_op
  42525. zeroentry device_not_available do_device_not_available
  42526. -paranoiderrorentry double_fault __do_double_fault
  42527. +paranoiderrorentry double_fault do_double_fault
  42528. zeroentry coprocessor_segment_overrun do_coprocessor_segment_overrun
  42529. errorentry invalid_TSS do_invalid_TSS
  42530. errorentry segment_not_present do_segment_not_present
  42531. @@ -1666,7 +1601,7 @@
  42532. */
  42533. error_kernelspace:
  42534. incl %ebx
  42535. - leaq native_irq_return_iret(%rip),%rcx
  42536. + leaq irq_return(%rip),%rcx
  42537. cmpq %rcx,RIP+8(%rsp)
  42538. je error_swapgs
  42539. movl %ecx,%eax /* zero extend */
  42540. diff -Nur linux-3.14.17/arch/x86/kernel/espfix_64.c linux-imx6-3.14/arch/x86/kernel/espfix_64.c
  42541. --- linux-3.14.17/arch/x86/kernel/espfix_64.c 2014-08-14 03:38:34.000000000 +0200
  42542. +++ linux-imx6-3.14/arch/x86/kernel/espfix_64.c 1970-01-01 01:00:00.000000000 +0100
  42543. @@ -1,208 +0,0 @@
  42544. -/* ----------------------------------------------------------------------- *
  42545. - *
  42546. - * Copyright 2014 Intel Corporation; author: H. Peter Anvin
  42547. - *
  42548. - * This program is free software; you can redistribute it and/or modify it
  42549. - * under the terms and conditions of the GNU General Public License,
  42550. - * version 2, as published by the Free Software Foundation.
  42551. - *
  42552. - * This program is distributed in the hope it will be useful, but WITHOUT
  42553. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  42554. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  42555. - * more details.
  42556. - *
  42557. - * ----------------------------------------------------------------------- */
  42558. -
  42559. -/*
  42560. - * The IRET instruction, when returning to a 16-bit segment, only
  42561. - * restores the bottom 16 bits of the user space stack pointer. This
  42562. - * causes some 16-bit software to break, but it also leaks kernel state
  42563. - * to user space.
  42564. - *
  42565. - * This works around this by creating percpu "ministacks", each of which
  42566. - * is mapped 2^16 times 64K apart. When we detect that the return SS is
  42567. - * on the LDT, we copy the IRET frame to the ministack and use the
  42568. - * relevant alias to return to userspace. The ministacks are mapped
  42569. - * readonly, so if the IRET fault we promote #GP to #DF which is an IST
  42570. - * vector and thus has its own stack; we then do the fixup in the #DF
  42571. - * handler.
  42572. - *
  42573. - * This file sets up the ministacks and the related page tables. The
  42574. - * actual ministack invocation is in entry_64.S.
  42575. - */
  42576. -
  42577. -#include <linux/init.h>
  42578. -#include <linux/init_task.h>
  42579. -#include <linux/kernel.h>
  42580. -#include <linux/percpu.h>
  42581. -#include <linux/gfp.h>
  42582. -#include <linux/random.h>
  42583. -#include <asm/pgtable.h>
  42584. -#include <asm/pgalloc.h>
  42585. -#include <asm/setup.h>
  42586. -#include <asm/espfix.h>
  42587. -
  42588. -/*
  42589. - * Note: we only need 6*8 = 48 bytes for the espfix stack, but round
  42590. - * it up to a cache line to avoid unnecessary sharing.
  42591. - */
  42592. -#define ESPFIX_STACK_SIZE (8*8UL)
  42593. -#define ESPFIX_STACKS_PER_PAGE (PAGE_SIZE/ESPFIX_STACK_SIZE)
  42594. -
  42595. -/* There is address space for how many espfix pages? */
  42596. -#define ESPFIX_PAGE_SPACE (1UL << (PGDIR_SHIFT-PAGE_SHIFT-16))
  42597. -
  42598. -#define ESPFIX_MAX_CPUS (ESPFIX_STACKS_PER_PAGE * ESPFIX_PAGE_SPACE)
  42599. -#if CONFIG_NR_CPUS > ESPFIX_MAX_CPUS
  42600. -# error "Need more than one PGD for the ESPFIX hack"
  42601. -#endif
  42602. -
  42603. -#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
  42604. -
  42605. -/* This contains the *bottom* address of the espfix stack */
  42606. -DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
  42607. -DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr);
  42608. -
  42609. -/* Initialization mutex - should this be a spinlock? */
  42610. -static DEFINE_MUTEX(espfix_init_mutex);
  42611. -
  42612. -/* Page allocation bitmap - each page serves ESPFIX_STACKS_PER_PAGE CPUs */
  42613. -#define ESPFIX_MAX_PAGES DIV_ROUND_UP(CONFIG_NR_CPUS, ESPFIX_STACKS_PER_PAGE)
  42614. -static void *espfix_pages[ESPFIX_MAX_PAGES];
  42615. -
  42616. -static __page_aligned_bss pud_t espfix_pud_page[PTRS_PER_PUD]
  42617. - __aligned(PAGE_SIZE);
  42618. -
  42619. -static unsigned int page_random, slot_random;
  42620. -
  42621. -/*
  42622. - * This returns the bottom address of the espfix stack for a specific CPU.
  42623. - * The math allows for a non-power-of-two ESPFIX_STACK_SIZE, in which case
  42624. - * we have to account for some amount of padding at the end of each page.
  42625. - */
  42626. -static inline unsigned long espfix_base_addr(unsigned int cpu)
  42627. -{
  42628. - unsigned long page, slot;
  42629. - unsigned long addr;
  42630. -
  42631. - page = (cpu / ESPFIX_STACKS_PER_PAGE) ^ page_random;
  42632. - slot = (cpu + slot_random) % ESPFIX_STACKS_PER_PAGE;
  42633. - addr = (page << PAGE_SHIFT) + (slot * ESPFIX_STACK_SIZE);
  42634. - addr = (addr & 0xffffUL) | ((addr & ~0xffffUL) << 16);
  42635. - addr += ESPFIX_BASE_ADDR;
  42636. - return addr;
  42637. -}
  42638. -
  42639. -#define PTE_STRIDE (65536/PAGE_SIZE)
  42640. -#define ESPFIX_PTE_CLONES (PTRS_PER_PTE/PTE_STRIDE)
  42641. -#define ESPFIX_PMD_CLONES PTRS_PER_PMD
  42642. -#define ESPFIX_PUD_CLONES (65536/(ESPFIX_PTE_CLONES*ESPFIX_PMD_CLONES))
  42643. -
  42644. -#define PGTABLE_PROT ((_KERNPG_TABLE & ~_PAGE_RW) | _PAGE_NX)
  42645. -
  42646. -static void init_espfix_random(void)
  42647. -{
  42648. - unsigned long rand;
  42649. -
  42650. - /*
  42651. - * This is run before the entropy pools are initialized,
  42652. - * but this is hopefully better than nothing.
  42653. - */
  42654. - if (!arch_get_random_long(&rand)) {
  42655. - /* The constant is an arbitrary large prime */
  42656. - rdtscll(rand);
  42657. - rand *= 0xc345c6b72fd16123UL;
  42658. - }
  42659. -
  42660. - slot_random = rand % ESPFIX_STACKS_PER_PAGE;
  42661. - page_random = (rand / ESPFIX_STACKS_PER_PAGE)
  42662. - & (ESPFIX_PAGE_SPACE - 1);
  42663. -}
  42664. -
  42665. -void __init init_espfix_bsp(void)
  42666. -{
  42667. - pgd_t *pgd_p;
  42668. - pteval_t ptemask;
  42669. -
  42670. - ptemask = __supported_pte_mask;
  42671. -
  42672. - /* Install the espfix pud into the kernel page directory */
  42673. - pgd_p = &init_level4_pgt[pgd_index(ESPFIX_BASE_ADDR)];
  42674. - pgd_populate(&init_mm, pgd_p, (pud_t *)espfix_pud_page);
  42675. -
  42676. - /* Randomize the locations */
  42677. - init_espfix_random();
  42678. -
  42679. - /* The rest is the same as for any other processor */
  42680. - init_espfix_ap();
  42681. -}
  42682. -
  42683. -void init_espfix_ap(void)
  42684. -{
  42685. - unsigned int cpu, page;
  42686. - unsigned long addr;
  42687. - pud_t pud, *pud_p;
  42688. - pmd_t pmd, *pmd_p;
  42689. - pte_t pte, *pte_p;
  42690. - int n;
  42691. - void *stack_page;
  42692. - pteval_t ptemask;
  42693. -
  42694. - /* We only have to do this once... */
  42695. - if (likely(this_cpu_read(espfix_stack)))
  42696. - return; /* Already initialized */
  42697. -
  42698. - cpu = smp_processor_id();
  42699. - addr = espfix_base_addr(cpu);
  42700. - page = cpu/ESPFIX_STACKS_PER_PAGE;
  42701. -
  42702. - /* Did another CPU already set this up? */
  42703. - stack_page = ACCESS_ONCE(espfix_pages[page]);
  42704. - if (likely(stack_page))
  42705. - goto done;
  42706. -
  42707. - mutex_lock(&espfix_init_mutex);
  42708. -
  42709. - /* Did we race on the lock? */
  42710. - stack_page = ACCESS_ONCE(espfix_pages[page]);
  42711. - if (stack_page)
  42712. - goto unlock_done;
  42713. -
  42714. - ptemask = __supported_pte_mask;
  42715. -
  42716. - pud_p = &espfix_pud_page[pud_index(addr)];
  42717. - pud = *pud_p;
  42718. - if (!pud_present(pud)) {
  42719. - pmd_p = (pmd_t *)__get_free_page(PGALLOC_GFP);
  42720. - pud = __pud(__pa(pmd_p) | (PGTABLE_PROT & ptemask));
  42721. - paravirt_alloc_pmd(&init_mm, __pa(pmd_p) >> PAGE_SHIFT);
  42722. - for (n = 0; n < ESPFIX_PUD_CLONES; n++)
  42723. - set_pud(&pud_p[n], pud);
  42724. - }
  42725. -
  42726. - pmd_p = pmd_offset(&pud, addr);
  42727. - pmd = *pmd_p;
  42728. - if (!pmd_present(pmd)) {
  42729. - pte_p = (pte_t *)__get_free_page(PGALLOC_GFP);
  42730. - pmd = __pmd(__pa(pte_p) | (PGTABLE_PROT & ptemask));
  42731. - paravirt_alloc_pte(&init_mm, __pa(pte_p) >> PAGE_SHIFT);
  42732. - for (n = 0; n < ESPFIX_PMD_CLONES; n++)
  42733. - set_pmd(&pmd_p[n], pmd);
  42734. - }
  42735. -
  42736. - pte_p = pte_offset_kernel(&pmd, addr);
  42737. - stack_page = (void *)__get_free_page(GFP_KERNEL);
  42738. - pte = __pte(__pa(stack_page) | (__PAGE_KERNEL_RO & ptemask));
  42739. - for (n = 0; n < ESPFIX_PTE_CLONES; n++)
  42740. - set_pte(&pte_p[n*PTE_STRIDE], pte);
  42741. -
  42742. - /* Job is done for this CPU and any CPU which shares this page */
  42743. - ACCESS_ONCE(espfix_pages[page]) = stack_page;
  42744. -
  42745. -unlock_done:
  42746. - mutex_unlock(&espfix_init_mutex);
  42747. -done:
  42748. - this_cpu_write(espfix_stack, addr);
  42749. - this_cpu_write(espfix_waddr, (unsigned long)stack_page
  42750. - + (addr & ~PAGE_MASK));
  42751. -}
  42752. diff -Nur linux-3.14.17/arch/x86/kernel/ldt.c linux-imx6-3.14/arch/x86/kernel/ldt.c
  42753. --- linux-3.14.17/arch/x86/kernel/ldt.c 2014-08-14 03:38:34.000000000 +0200
  42754. +++ linux-imx6-3.14/arch/x86/kernel/ldt.c 2014-09-11 18:05:58.546024168 +0200
  42755. @@ -20,6 +20,8 @@
  42756. #include <asm/mmu_context.h>
  42757. #include <asm/syscalls.h>
  42758. +int sysctl_ldt16 = 0;
  42759. +
  42760. #ifdef CONFIG_SMP
  42761. static void flush_ldt(void *current_mm)
  42762. {
  42763. @@ -229,10 +231,16 @@
  42764. }
  42765. }
  42766. - if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) {
  42767. + /*
  42768. + * On x86-64 we do not support 16-bit segments due to
  42769. + * IRET leaking the high bits of the kernel stack address.
  42770. + */
  42771. +#ifdef CONFIG_X86_64
  42772. + if (!ldt_info.seg_32bit && !sysctl_ldt16) {
  42773. error = -EINVAL;
  42774. goto out_unlock;
  42775. }
  42776. +#endif
  42777. fill_ldt(&ldt, &ldt_info);
  42778. if (oldmode)
  42779. diff -Nur linux-3.14.17/arch/x86/kernel/Makefile linux-imx6-3.14/arch/x86/kernel/Makefile
  42780. --- linux-3.14.17/arch/x86/kernel/Makefile 2014-08-14 03:38:34.000000000 +0200
  42781. +++ linux-imx6-3.14/arch/x86/kernel/Makefile 2014-09-11 18:05:58.478023896 +0200
  42782. @@ -29,7 +29,6 @@
  42783. obj-y += syscall_$(BITS).o
  42784. obj-$(CONFIG_X86_64) += vsyscall_64.o
  42785. obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
  42786. -obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
  42787. obj-$(CONFIG_SYSFS) += ksysfs.o
  42788. obj-y += bootflag.o e820.o
  42789. obj-y += pci-dma.o quirks.o topology.o kdebugfs.o
  42790. diff -Nur linux-3.14.17/arch/x86/kernel/paravirt_patch_64.c linux-imx6-3.14/arch/x86/kernel/paravirt_patch_64.c
  42791. --- linux-3.14.17/arch/x86/kernel/paravirt_patch_64.c 2014-08-14 03:38:34.000000000 +0200
  42792. +++ linux-imx6-3.14/arch/x86/kernel/paravirt_patch_64.c 2014-09-11 18:05:58.546024168 +0200
  42793. @@ -6,6 +6,7 @@
  42794. DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
  42795. DEF_NATIVE(pv_irq_ops, restore_fl, "pushq %rdi; popfq");
  42796. DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax");
  42797. +DEF_NATIVE(pv_cpu_ops, iret, "iretq");
  42798. DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax");
  42799. DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax");
  42800. DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3");
  42801. @@ -49,6 +50,7 @@
  42802. PATCH_SITE(pv_irq_ops, save_fl);
  42803. PATCH_SITE(pv_irq_ops, irq_enable);
  42804. PATCH_SITE(pv_irq_ops, irq_disable);
  42805. + PATCH_SITE(pv_cpu_ops, iret);
  42806. PATCH_SITE(pv_cpu_ops, irq_enable_sysexit);
  42807. PATCH_SITE(pv_cpu_ops, usergs_sysret32);
  42808. PATCH_SITE(pv_cpu_ops, usergs_sysret64);
  42809. diff -Nur linux-3.14.17/arch/x86/kernel/setup.c linux-imx6-3.14/arch/x86/kernel/setup.c
  42810. --- linux-3.14.17/arch/x86/kernel/setup.c 2014-08-14 03:38:34.000000000 +0200
  42811. +++ linux-imx6-3.14/arch/x86/kernel/setup.c 2014-09-11 18:05:58.578024296 +0200
  42812. @@ -1120,7 +1120,7 @@
  42813. setup_real_mode();
  42814. memblock_set_current_limit(get_max_mapped());
  42815. - dma_contiguous_reserve(0);
  42816. + dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT);
  42817. /*
  42818. * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
  42819. diff -Nur linux-3.14.17/arch/x86/kernel/smpboot.c linux-imx6-3.14/arch/x86/kernel/smpboot.c
  42820. --- linux-3.14.17/arch/x86/kernel/smpboot.c 2014-08-14 03:38:34.000000000 +0200
  42821. +++ linux-imx6-3.14/arch/x86/kernel/smpboot.c 2014-09-11 18:05:58.582024312 +0200
  42822. @@ -243,13 +243,6 @@
  42823. check_tsc_sync_target();
  42824. /*
  42825. - * Enable the espfix hack for this CPU
  42826. - */
  42827. -#ifdef CONFIG_X86_ESPFIX64
  42828. - init_espfix_ap();
  42829. -#endif
  42830. -
  42831. - /*
  42832. * We need to hold vector_lock so there the set of online cpus
  42833. * does not change while we are assigning vectors to cpus. Holding
  42834. * this lock ensures we don't half assign or remove an irq from a cpu.
  42835. diff -Nur linux-3.14.17/arch/x86/mm/dump_pagetables.c linux-imx6-3.14/arch/x86/mm/dump_pagetables.c
  42836. --- linux-3.14.17/arch/x86/mm/dump_pagetables.c 2014-08-14 03:38:34.000000000 +0200
  42837. +++ linux-imx6-3.14/arch/x86/mm/dump_pagetables.c 2014-09-11 18:05:58.694024760 +0200
  42838. @@ -30,13 +30,11 @@
  42839. unsigned long start_address;
  42840. unsigned long current_address;
  42841. const struct addr_marker *marker;
  42842. - unsigned long lines;
  42843. };
  42844. struct addr_marker {
  42845. unsigned long start_address;
  42846. const char *name;
  42847. - unsigned long max_lines;
  42848. };
  42849. /* indices for address_markers; keep sync'd w/ address_markers below */
  42850. @@ -47,7 +45,6 @@
  42851. LOW_KERNEL_NR,
  42852. VMALLOC_START_NR,
  42853. VMEMMAP_START_NR,
  42854. - ESPFIX_START_NR,
  42855. HIGH_KERNEL_NR,
  42856. MODULES_VADDR_NR,
  42857. MODULES_END_NR,
  42858. @@ -70,7 +67,6 @@
  42859. { PAGE_OFFSET, "Low Kernel Mapping" },
  42860. { VMALLOC_START, "vmalloc() Area" },
  42861. { VMEMMAP_START, "Vmemmap" },
  42862. - { ESPFIX_BASE_ADDR, "ESPfix Area", 16 },
  42863. { __START_KERNEL_map, "High Kernel Mapping" },
  42864. { MODULES_VADDR, "Modules" },
  42865. { MODULES_END, "End Modules" },
  42866. @@ -167,7 +163,7 @@
  42867. pgprot_t new_prot, int level)
  42868. {
  42869. pgprotval_t prot, cur;
  42870. - static const char units[] = "BKMGTPE";
  42871. + static const char units[] = "KMGTPE";
  42872. /*
  42873. * If we have a "break" in the series, we need to flush the state that
  42874. @@ -182,7 +178,6 @@
  42875. st->current_prot = new_prot;
  42876. st->level = level;
  42877. st->marker = address_markers;
  42878. - st->lines = 0;
  42879. seq_printf(m, "---[ %s ]---\n", st->marker->name);
  42880. } else if (prot != cur || level != st->level ||
  42881. st->current_address >= st->marker[1].start_address) {
  42882. @@ -193,21 +188,17 @@
  42883. /*
  42884. * Now print the actual finished series
  42885. */
  42886. - if (!st->marker->max_lines ||
  42887. - st->lines < st->marker->max_lines) {
  42888. - seq_printf(m, "0x%0*lx-0x%0*lx ",
  42889. - width, st->start_address,
  42890. - width, st->current_address);
  42891. -
  42892. - delta = (st->current_address - st->start_address) >> 10;
  42893. - while (!(delta & 1023) && unit[1]) {
  42894. - delta >>= 10;
  42895. - unit++;
  42896. - }
  42897. - seq_printf(m, "%9lu%c ", delta, *unit);
  42898. - printk_prot(m, st->current_prot, st->level);
  42899. + seq_printf(m, "0x%0*lx-0x%0*lx ",
  42900. + width, st->start_address,
  42901. + width, st->current_address);
  42902. +
  42903. + delta = (st->current_address - st->start_address) >> 10;
  42904. + while (!(delta & 1023) && unit[1]) {
  42905. + delta >>= 10;
  42906. + unit++;
  42907. }
  42908. - st->lines++;
  42909. + seq_printf(m, "%9lu%c ", delta, *unit);
  42910. + printk_prot(m, st->current_prot, st->level);
  42911. /*
  42912. * We print markers for special areas of address space,
  42913. diff -Nur linux-3.14.17/arch/x86/vdso/vdso32-setup.c linux-imx6-3.14/arch/x86/vdso/vdso32-setup.c
  42914. --- linux-3.14.17/arch/x86/vdso/vdso32-setup.c 2014-08-14 03:38:34.000000000 +0200
  42915. +++ linux-imx6-3.14/arch/x86/vdso/vdso32-setup.c 2014-09-11 18:05:58.862025430 +0200
  42916. @@ -41,6 +41,7 @@
  42917. #ifdef CONFIG_X86_64
  42918. #define vdso_enabled sysctl_vsyscall32
  42919. #define arch_setup_additional_pages syscall32_setup_pages
  42920. +extern int sysctl_ldt16;
  42921. #endif
  42922. /*
  42923. @@ -379,6 +380,13 @@
  42924. .maxlen = sizeof(int),
  42925. .mode = 0644,
  42926. .proc_handler = proc_dointvec
  42927. + },
  42928. + {
  42929. + .procname = "ldt16",
  42930. + .data = &sysctl_ldt16,
  42931. + .maxlen = sizeof(int),
  42932. + .mode = 0644,
  42933. + .proc_handler = proc_dointvec
  42934. },
  42935. {}
  42936. };
  42937. diff -Nur linux-3.14.17/arch/x86/xen/setup.c linux-imx6-3.14/arch/x86/xen/setup.c
  42938. --- linux-3.14.17/arch/x86/xen/setup.c 2014-08-14 03:38:34.000000000 +0200
  42939. +++ linux-imx6-3.14/arch/x86/xen/setup.c 2014-09-11 18:05:58.890025543 +0200
  42940. @@ -574,7 +574,13 @@
  42941. }
  42942. #endif /* CONFIG_X86_64 */
  42943. }
  42944. -
  42945. +void xen_enable_nmi(void)
  42946. +{
  42947. +#ifdef CONFIG_X86_64
  42948. + if (register_callback(CALLBACKTYPE_nmi, (char *)nmi))
  42949. + BUG();
  42950. +#endif
  42951. +}
  42952. void __init xen_pvmmu_arch_setup(void)
  42953. {
  42954. HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
  42955. @@ -589,6 +595,7 @@
  42956. xen_enable_sysenter();
  42957. xen_enable_syscall();
  42958. + xen_enable_nmi();
  42959. }
  42960. /* This function is not called for HVM domains */
  42961. diff -Nur linux-3.14.17/arch/xtensa/kernel/vectors.S linux-imx6-3.14/arch/xtensa/kernel/vectors.S
  42962. --- linux-3.14.17/arch/xtensa/kernel/vectors.S 2014-08-14 03:38:34.000000000 +0200
  42963. +++ linux-imx6-3.14/arch/xtensa/kernel/vectors.S 2014-09-11 18:05:59.070026262 +0200
  42964. @@ -376,42 +376,38 @@
  42965. beqz a2, 1f # if at start of vector, don't restore
  42966. addi a0, a0, -128
  42967. - bbsi.l a0, 8, 1f # don't restore except for overflow 8 and 12
  42968. -
  42969. - /*
  42970. - * This fixup handler is for the extremely unlikely case where the
  42971. - * overflow handler's reference thru a0 gets a hardware TLB refill
  42972. - * that bumps out the (distinct, aliasing) TLB entry that mapped its
  42973. - * prior references thru a9/a13, and where our reference now thru
  42974. - * a9/a13 gets a 2nd-level miss exception (not hardware TLB refill).
  42975. - */
  42976. - movi a2, window_overflow_restore_a0_fixup
  42977. - s32i a2, a3, EXC_TABLE_FIXUP
  42978. - l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
  42979. - xsr a3, excsave1
  42980. -
  42981. - bbsi.l a0, 7, 2f
  42982. + bbsi a0, 8, 1f # don't restore except for overflow 8 and 12
  42983. + bbsi a0, 7, 2f
  42984. /*
  42985. * Restore a0 as saved by _WindowOverflow8().
  42986. + *
  42987. + * FIXME: we really need a fixup handler for this L32E,
  42988. + * for the extremely unlikely case where the overflow handler's
  42989. + * reference thru a0 gets a hardware TLB refill that bumps out
  42990. + * the (distinct, aliasing) TLB entry that mapped its prior
  42991. + * references thru a9, and where our reference now thru a9
  42992. + * gets a 2nd-level miss exception (not hardware TLB refill).
  42993. */
  42994. - l32e a0, a9, -16
  42995. - wsr a0, depc # replace the saved a0
  42996. - j 3f
  42997. + l32e a2, a9, -16
  42998. + wsr a2, depc # replace the saved a0
  42999. + j 1f
  43000. 2:
  43001. /*
  43002. * Restore a0 as saved by _WindowOverflow12().
  43003. + *
  43004. + * FIXME: we really need a fixup handler for this L32E,
  43005. + * for the extremely unlikely case where the overflow handler's
  43006. + * reference thru a0 gets a hardware TLB refill that bumps out
  43007. + * the (distinct, aliasing) TLB entry that mapped its prior
  43008. + * references thru a13, and where our reference now thru a13
  43009. + * gets a 2nd-level miss exception (not hardware TLB refill).
  43010. */
  43011. - l32e a0, a13, -16
  43012. - wsr a0, depc # replace the saved a0
  43013. -3:
  43014. - xsr a3, excsave1
  43015. - movi a0, 0
  43016. - s32i a0, a3, EXC_TABLE_FIXUP
  43017. - s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
  43018. + l32e a2, a13, -16
  43019. + wsr a2, depc # replace the saved a0
  43020. 1:
  43021. /*
  43022. * Restore WindowBase while leaving all address registers restored.
  43023. @@ -453,7 +449,6 @@
  43024. s32i a0, a2, PT_DEPC
  43025. -_DoubleExceptionVector_handle_exception:
  43026. addx4 a0, a0, a3
  43027. l32i a0, a0, EXC_TABLE_FAST_USER
  43028. xsr a3, excsave1
  43029. @@ -469,120 +464,11 @@
  43030. rotw -3
  43031. j 1b
  43032. + .end literal_prefix
  43033. ENDPROC(_DoubleExceptionVector)
  43034. /*
  43035. - * Fixup handler for TLB miss in double exception handler for window owerflow.
  43036. - * We get here with windowbase set to the window that was being spilled and
  43037. - * a0 trashed. a0 bit 7 determines if this is a call8 (bit clear) or call12
  43038. - * (bit set) window.
  43039. - *
  43040. - * We do the following here:
  43041. - * - go to the original window retaining a0 value;
  43042. - * - set up exception stack to return back to appropriate a0 restore code
  43043. - * (we'll need to rotate window back and there's no place to save this
  43044. - * information, use different return address for that);
  43045. - * - handle the exception;
  43046. - * - go to the window that was being spilled;
  43047. - * - set up window_overflow_restore_a0_fixup as a fixup routine;
  43048. - * - reload a0;
  43049. - * - restore the original window;
  43050. - * - reset the default fixup routine;
  43051. - * - return to user. By the time we get to this fixup handler all information
  43052. - * about the conditions of the original double exception that happened in
  43053. - * the window overflow handler is lost, so we just return to userspace to
  43054. - * retry overflow from start.
  43055. - *
  43056. - * a0: value of depc, original value in depc
  43057. - * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
  43058. - * a3: exctable, original value in excsave1
  43059. - */
  43060. -
  43061. -ENTRY(window_overflow_restore_a0_fixup)
  43062. -
  43063. - rsr a0, ps
  43064. - extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH
  43065. - rsr a2, windowbase
  43066. - sub a0, a2, a0
  43067. - extui a0, a0, 0, 3
  43068. - l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
  43069. - xsr a3, excsave1
  43070. -
  43071. - _beqi a0, 1, .Lhandle_1
  43072. - _beqi a0, 3, .Lhandle_3
  43073. -
  43074. - .macro overflow_fixup_handle_exception_pane n
  43075. -
  43076. - rsr a0, depc
  43077. - rotw -\n
  43078. -
  43079. - xsr a3, excsave1
  43080. - wsr a2, depc
  43081. - l32i a2, a3, EXC_TABLE_KSTK
  43082. - s32i a0, a2, PT_AREG0
  43083. -
  43084. - movi a0, .Lrestore_\n
  43085. - s32i a0, a2, PT_DEPC
  43086. - rsr a0, exccause
  43087. - j _DoubleExceptionVector_handle_exception
  43088. -
  43089. - .endm
  43090. -
  43091. - overflow_fixup_handle_exception_pane 2
  43092. -.Lhandle_1:
  43093. - overflow_fixup_handle_exception_pane 1
  43094. -.Lhandle_3:
  43095. - overflow_fixup_handle_exception_pane 3
  43096. -
  43097. - .macro overflow_fixup_restore_a0_pane n
  43098. -
  43099. - rotw \n
  43100. - /* Need to preserve a0 value here to be able to handle exception
  43101. - * that may occur on a0 reload from stack. It may occur because
  43102. - * TLB miss handler may not be atomic and pointer to page table
  43103. - * may be lost before we get here. There are no free registers,
  43104. - * so we need to use EXC_TABLE_DOUBLE_SAVE area.
  43105. - */
  43106. - xsr a3, excsave1
  43107. - s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
  43108. - movi a2, window_overflow_restore_a0_fixup
  43109. - s32i a2, a3, EXC_TABLE_FIXUP
  43110. - l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
  43111. - xsr a3, excsave1
  43112. - bbsi.l a0, 7, 1f
  43113. - l32e a0, a9, -16
  43114. - j 2f
  43115. -1:
  43116. - l32e a0, a13, -16
  43117. -2:
  43118. - rotw -\n
  43119. -
  43120. - .endm
  43121. -
  43122. -.Lrestore_2:
  43123. - overflow_fixup_restore_a0_pane 2
  43124. -
  43125. -.Lset_default_fixup:
  43126. - xsr a3, excsave1
  43127. - s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
  43128. - movi a2, 0
  43129. - s32i a2, a3, EXC_TABLE_FIXUP
  43130. - l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
  43131. - xsr a3, excsave1
  43132. - rfe
  43133. -
  43134. -.Lrestore_1:
  43135. - overflow_fixup_restore_a0_pane 1
  43136. - j .Lset_default_fixup
  43137. -.Lrestore_3:
  43138. - overflow_fixup_restore_a0_pane 3
  43139. - j .Lset_default_fixup
  43140. -
  43141. -ENDPROC(window_overflow_restore_a0_fixup)
  43142. -
  43143. - .end literal_prefix
  43144. -/*
  43145. * Debug interrupt vector
  43146. *
  43147. * There is not much space here, so simply jump to another handler.
  43148. diff -Nur linux-3.14.17/arch/xtensa/kernel/vmlinux.lds.S linux-imx6-3.14/arch/xtensa/kernel/vmlinux.lds.S
  43149. --- linux-3.14.17/arch/xtensa/kernel/vmlinux.lds.S 2014-08-14 03:38:34.000000000 +0200
  43150. +++ linux-imx6-3.14/arch/xtensa/kernel/vmlinux.lds.S 2014-09-11 18:05:59.070026262 +0200
  43151. @@ -269,13 +269,13 @@
  43152. .UserExceptionVector.literal)
  43153. SECTION_VECTOR (_DoubleExceptionVector_literal,
  43154. .DoubleExceptionVector.literal,
  43155. - DOUBLEEXC_VECTOR_VADDR - 40,
  43156. + DOUBLEEXC_VECTOR_VADDR - 16,
  43157. SIZEOF(.UserExceptionVector.text),
  43158. .UserExceptionVector.text)
  43159. SECTION_VECTOR (_DoubleExceptionVector_text,
  43160. .DoubleExceptionVector.text,
  43161. DOUBLEEXC_VECTOR_VADDR,
  43162. - 40,
  43163. + 32,
  43164. .DoubleExceptionVector.literal)
  43165. . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
  43166. diff -Nur linux-3.14.17/block/bfq-cgroup.c linux-imx6-3.14/block/bfq-cgroup.c
  43167. --- linux-3.14.17/block/bfq-cgroup.c 1970-01-01 01:00:00.000000000 +0100
  43168. +++ linux-imx6-3.14/block/bfq-cgroup.c 2014-09-11 18:05:59.118026454 +0200
  43169. @@ -0,0 +1,932 @@
  43170. +/*
  43171. + * BFQ: CGROUPS support.
  43172. + *
  43173. + * Based on ideas and code from CFQ:
  43174. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  43175. + *
  43176. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  43177. + * Paolo Valente <paolo.valente@unimore.it>
  43178. + *
  43179. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  43180. + *
  43181. + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
  43182. + * file.
  43183. + */
  43184. +
  43185. +#ifdef CONFIG_CGROUP_BFQIO
  43186. +
  43187. +static DEFINE_MUTEX(bfqio_mutex);
  43188. +
  43189. +static bool bfqio_is_removed(struct bfqio_cgroup *bgrp)
  43190. +{
  43191. + return bgrp ? !bgrp->online : false;
  43192. +}
  43193. +
  43194. +static struct bfqio_cgroup bfqio_root_cgroup = {
  43195. + .weight = BFQ_DEFAULT_GRP_WEIGHT,
  43196. + .ioprio = BFQ_DEFAULT_GRP_IOPRIO,
  43197. + .ioprio_class = BFQ_DEFAULT_GRP_CLASS,
  43198. +};
  43199. +
  43200. +static inline void bfq_init_entity(struct bfq_entity *entity,
  43201. + struct bfq_group *bfqg)
  43202. +{
  43203. + entity->weight = entity->new_weight;
  43204. + entity->orig_weight = entity->new_weight;
  43205. + entity->ioprio = entity->new_ioprio;
  43206. + entity->ioprio_class = entity->new_ioprio_class;
  43207. + entity->parent = bfqg->my_entity;
  43208. + entity->sched_data = &bfqg->sched_data;
  43209. +}
  43210. +
  43211. +static struct bfqio_cgroup *css_to_bfqio(struct cgroup_subsys_state *css)
  43212. +{
  43213. + return css ? container_of(css, struct bfqio_cgroup, css) : NULL;
  43214. +}
  43215. +
  43216. +/*
  43217. + * Search the bfq_group for bfqd into the hash table (by now only a list)
  43218. + * of bgrp. Must be called under rcu_read_lock().
  43219. + */
  43220. +static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp,
  43221. + struct bfq_data *bfqd)
  43222. +{
  43223. + struct bfq_group *bfqg;
  43224. + void *key;
  43225. +
  43226. + hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) {
  43227. + key = rcu_dereference(bfqg->bfqd);
  43228. + if (key == bfqd)
  43229. + return bfqg;
  43230. + }
  43231. +
  43232. + return NULL;
  43233. +}
  43234. +
  43235. +static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp,
  43236. + struct bfq_group *bfqg)
  43237. +{
  43238. + struct bfq_entity *entity = &bfqg->entity;
  43239. +
  43240. + /*
  43241. + * If the weight of the entity has never been set via the sysfs
  43242. + * interface, then bgrp->weight == 0. In this case we initialize
  43243. + * the weight from the current ioprio value. Otherwise, the group
  43244. + * weight, if set, has priority over the ioprio value.
  43245. + */
  43246. + if (bgrp->weight == 0) {
  43247. + entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio);
  43248. + entity->new_ioprio = bgrp->ioprio;
  43249. + } else {
  43250. + entity->new_weight = bgrp->weight;
  43251. + entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight);
  43252. + }
  43253. + entity->orig_weight = entity->weight = entity->new_weight;
  43254. + entity->ioprio = entity->new_ioprio;
  43255. + entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class;
  43256. + entity->my_sched_data = &bfqg->sched_data;
  43257. + bfqg->active_entities = 0;
  43258. +}
  43259. +
  43260. +static inline void bfq_group_set_parent(struct bfq_group *bfqg,
  43261. + struct bfq_group *parent)
  43262. +{
  43263. + struct bfq_entity *entity;
  43264. +
  43265. + BUG_ON(parent == NULL);
  43266. + BUG_ON(bfqg == NULL);
  43267. +
  43268. + entity = &bfqg->entity;
  43269. + entity->parent = parent->my_entity;
  43270. + entity->sched_data = &parent->sched_data;
  43271. +}
  43272. +
  43273. +/**
  43274. + * bfq_group_chain_alloc - allocate a chain of groups.
  43275. + * @bfqd: queue descriptor.
  43276. + * @css: the leaf cgroup_subsys_state this chain starts from.
  43277. + *
  43278. + * Allocate a chain of groups starting from the one belonging to
  43279. + * @cgroup up to the root cgroup. Stop if a cgroup on the chain
  43280. + * to the root has already an allocated group on @bfqd.
  43281. + */
  43282. +static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd,
  43283. + struct cgroup_subsys_state *css)
  43284. +{
  43285. + struct bfqio_cgroup *bgrp;
  43286. + struct bfq_group *bfqg, *prev = NULL, *leaf = NULL;
  43287. +
  43288. + for (; css != NULL; css = css->parent) {
  43289. + bgrp = css_to_bfqio(css);
  43290. +
  43291. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  43292. + if (bfqg != NULL) {
  43293. + /*
  43294. + * All the cgroups in the path from there to the
  43295. + * root must have a bfq_group for bfqd, so we don't
  43296. + * need any more allocations.
  43297. + */
  43298. + break;
  43299. + }
  43300. +
  43301. + bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC);
  43302. + if (bfqg == NULL)
  43303. + goto cleanup;
  43304. +
  43305. + bfq_group_init_entity(bgrp, bfqg);
  43306. + bfqg->my_entity = &bfqg->entity;
  43307. +
  43308. + if (leaf == NULL) {
  43309. + leaf = bfqg;
  43310. + prev = leaf;
  43311. + } else {
  43312. + bfq_group_set_parent(prev, bfqg);
  43313. + /*
  43314. + * Build a list of allocated nodes using the bfqd
  43315. + * filed, that is still unused and will be
  43316. + * initialized only after the node will be
  43317. + * connected.
  43318. + */
  43319. + prev->bfqd = bfqg;
  43320. + prev = bfqg;
  43321. + }
  43322. + }
  43323. +
  43324. + return leaf;
  43325. +
  43326. +cleanup:
  43327. + while (leaf != NULL) {
  43328. + prev = leaf;
  43329. + leaf = leaf->bfqd;
  43330. + kfree(prev);
  43331. + }
  43332. +
  43333. + return NULL;
  43334. +}
  43335. +
  43336. +/**
  43337. + * bfq_group_chain_link - link an allocated group chain to a cgroup
  43338. + * hierarchy.
  43339. + * @bfqd: the queue descriptor.
  43340. + * @css: the leaf cgroup_subsys_state to start from.
  43341. + * @leaf: the leaf group (to be associated to @cgroup).
  43342. + *
  43343. + * Try to link a chain of groups to a cgroup hierarchy, connecting the
  43344. + * nodes bottom-up, so we can be sure that when we find a cgroup in the
  43345. + * hierarchy that already as a group associated to @bfqd all the nodes
  43346. + * in the path to the root cgroup have one too.
  43347. + *
  43348. + * On locking: the queue lock protects the hierarchy (there is a hierarchy
  43349. + * per device) while the bfqio_cgroup lock protects the list of groups
  43350. + * belonging to the same cgroup.
  43351. + */
  43352. +static void bfq_group_chain_link(struct bfq_data *bfqd,
  43353. + struct cgroup_subsys_state *css,
  43354. + struct bfq_group *leaf)
  43355. +{
  43356. + struct bfqio_cgroup *bgrp;
  43357. + struct bfq_group *bfqg, *next, *prev = NULL;
  43358. + unsigned long flags;
  43359. +
  43360. + assert_spin_locked(bfqd->queue->queue_lock);
  43361. +
  43362. + for (; css != NULL && leaf != NULL; css = css->parent) {
  43363. + bgrp = css_to_bfqio(css);
  43364. + next = leaf->bfqd;
  43365. +
  43366. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  43367. + BUG_ON(bfqg != NULL);
  43368. +
  43369. + spin_lock_irqsave(&bgrp->lock, flags);
  43370. +
  43371. + rcu_assign_pointer(leaf->bfqd, bfqd);
  43372. + hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data);
  43373. + hlist_add_head(&leaf->bfqd_node, &bfqd->group_list);
  43374. +
  43375. + spin_unlock_irqrestore(&bgrp->lock, flags);
  43376. +
  43377. + prev = leaf;
  43378. + leaf = next;
  43379. + }
  43380. +
  43381. + BUG_ON(css == NULL && leaf != NULL);
  43382. + if (css != NULL && prev != NULL) {
  43383. + bgrp = css_to_bfqio(css);
  43384. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  43385. + bfq_group_set_parent(prev, bfqg);
  43386. + }
  43387. +}
  43388. +
  43389. +/**
  43390. + * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup.
  43391. + * @bfqd: queue descriptor.
  43392. + * @cgroup: cgroup being searched for.
  43393. + *
  43394. + * Return a group associated to @bfqd in @cgroup, allocating one if
  43395. + * necessary. When a group is returned all the cgroups in the path
  43396. + * to the root have a group associated to @bfqd.
  43397. + *
  43398. + * If the allocation fails, return the root group: this breaks guarantees
  43399. + * but is a safe fallback. If this loss becomes a problem it can be
  43400. + * mitigated using the equivalent weight (given by the product of the
  43401. + * weights of the groups in the path from @group to the root) in the
  43402. + * root scheduler.
  43403. + *
  43404. + * We allocate all the missing nodes in the path from the leaf cgroup
  43405. + * to the root and we connect the nodes only after all the allocations
  43406. + * have been successful.
  43407. + */
  43408. +static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
  43409. + struct cgroup_subsys_state *css)
  43410. +{
  43411. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  43412. + struct bfq_group *bfqg;
  43413. +
  43414. + bfqg = bfqio_lookup_group(bgrp, bfqd);
  43415. + if (bfqg != NULL)
  43416. + return bfqg;
  43417. +
  43418. + bfqg = bfq_group_chain_alloc(bfqd, css);
  43419. + if (bfqg != NULL)
  43420. + bfq_group_chain_link(bfqd, css, bfqg);
  43421. + else
  43422. + bfqg = bfqd->root_group;
  43423. +
  43424. + return bfqg;
  43425. +}
  43426. +
  43427. +/**
  43428. + * bfq_bfqq_move - migrate @bfqq to @bfqg.
  43429. + * @bfqd: queue descriptor.
  43430. + * @bfqq: the queue to move.
  43431. + * @entity: @bfqq's entity.
  43432. + * @bfqg: the group to move to.
  43433. + *
  43434. + * Move @bfqq to @bfqg, deactivating it from its old group and reactivating
  43435. + * it on the new one. Avoid putting the entity on the old group idle tree.
  43436. + *
  43437. + * Must be called under the queue lock; the cgroup owning @bfqg must
  43438. + * not disappear (by now this just means that we are called under
  43439. + * rcu_read_lock()).
  43440. + */
  43441. +static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  43442. + struct bfq_entity *entity, struct bfq_group *bfqg)
  43443. +{
  43444. + int busy, resume;
  43445. +
  43446. + busy = bfq_bfqq_busy(bfqq);
  43447. + resume = !RB_EMPTY_ROOT(&bfqq->sort_list);
  43448. +
  43449. + BUG_ON(resume && !entity->on_st);
  43450. + BUG_ON(busy && !resume && entity->on_st &&
  43451. + bfqq != bfqd->in_service_queue);
  43452. +
  43453. + if (busy) {
  43454. + BUG_ON(atomic_read(&bfqq->ref) < 2);
  43455. +
  43456. + if (!resume)
  43457. + bfq_del_bfqq_busy(bfqd, bfqq, 0);
  43458. + else
  43459. + bfq_deactivate_bfqq(bfqd, bfqq, 0);
  43460. + } else if (entity->on_st)
  43461. + bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
  43462. +
  43463. + /*
  43464. + * Here we use a reference to bfqg. We don't need a refcounter
  43465. + * as the cgroup reference will not be dropped, so that its
  43466. + * destroy() callback will not be invoked.
  43467. + */
  43468. + entity->parent = bfqg->my_entity;
  43469. + entity->sched_data = &bfqg->sched_data;
  43470. +
  43471. + if (busy && resume)
  43472. + bfq_activate_bfqq(bfqd, bfqq);
  43473. +
  43474. + if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver)
  43475. + bfq_schedule_dispatch(bfqd);
  43476. +}
  43477. +
  43478. +/**
  43479. + * __bfq_bic_change_cgroup - move @bic to @cgroup.
  43480. + * @bfqd: the queue descriptor.
  43481. + * @bic: the bic to move.
  43482. + * @cgroup: the cgroup to move to.
  43483. + *
  43484. + * Move bic to cgroup, assuming that bfqd->queue is locked; the caller
  43485. + * has to make sure that the reference to cgroup is valid across the call.
  43486. + *
  43487. + * NOTE: an alternative approach might have been to store the current
  43488. + * cgroup in bfqq and getting a reference to it, reducing the lookup
  43489. + * time here, at the price of slightly more complex code.
  43490. + */
  43491. +static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
  43492. + struct bfq_io_cq *bic,
  43493. + struct cgroup_subsys_state *css)
  43494. +{
  43495. + struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
  43496. + struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
  43497. + struct bfq_entity *entity;
  43498. + struct bfq_group *bfqg;
  43499. + struct bfqio_cgroup *bgrp;
  43500. +
  43501. + bgrp = css_to_bfqio(css);
  43502. +
  43503. + bfqg = bfq_find_alloc_group(bfqd, css);
  43504. + if (async_bfqq != NULL) {
  43505. + entity = &async_bfqq->entity;
  43506. +
  43507. + if (entity->sched_data != &bfqg->sched_data) {
  43508. + bic_set_bfqq(bic, NULL, 0);
  43509. + bfq_log_bfqq(bfqd, async_bfqq,
  43510. + "bic_change_group: %p %d",
  43511. + async_bfqq, atomic_read(&async_bfqq->ref));
  43512. + bfq_put_queue(async_bfqq);
  43513. + }
  43514. + }
  43515. +
  43516. + if (sync_bfqq != NULL) {
  43517. + entity = &sync_bfqq->entity;
  43518. + if (entity->sched_data != &bfqg->sched_data)
  43519. + bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg);
  43520. + }
  43521. +
  43522. + return bfqg;
  43523. +}
  43524. +
  43525. +/**
  43526. + * bfq_bic_change_cgroup - move @bic to @cgroup.
  43527. + * @bic: the bic being migrated.
  43528. + * @cgroup: the destination cgroup.
  43529. + *
  43530. + * When the task owning @bic is moved to @cgroup, @bic is immediately
  43531. + * moved into its new parent group.
  43532. + */
  43533. +static void bfq_bic_change_cgroup(struct bfq_io_cq *bic,
  43534. + struct cgroup_subsys_state *css)
  43535. +{
  43536. + struct bfq_data *bfqd;
  43537. + unsigned long uninitialized_var(flags);
  43538. +
  43539. + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
  43540. + &flags);
  43541. + if (bfqd != NULL) {
  43542. + __bfq_bic_change_cgroup(bfqd, bic, css);
  43543. + bfq_put_bfqd_unlock(bfqd, &flags);
  43544. + }
  43545. +}
  43546. +
  43547. +/**
  43548. + * bfq_bic_update_cgroup - update the cgroup of @bic.
  43549. + * @bic: the @bic to update.
  43550. + *
  43551. + * Make sure that @bic is enqueued in the cgroup of the current task.
  43552. + * We need this in addition to moving bics during the cgroup attach
  43553. + * phase because the task owning @bic could be at its first disk
  43554. + * access or we may end up in the root cgroup as the result of a
  43555. + * memory allocation failure and here we try to move to the right
  43556. + * group.
  43557. + *
  43558. + * Must be called under the queue lock. It is safe to use the returned
  43559. + * value even after the rcu_read_unlock() as the migration/destruction
  43560. + * paths act under the queue lock too. IOW it is impossible to race with
  43561. + * group migration/destruction and end up with an invalid group as:
  43562. + * a) here cgroup has not yet been destroyed, nor its destroy callback
  43563. + * has started execution, as current holds a reference to it,
  43564. + * b) if it is destroyed after rcu_read_unlock() [after current is
  43565. + * migrated to a different cgroup] its attach() callback will have
  43566. + * taken care of remove all the references to the old cgroup data.
  43567. + */
  43568. +static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic)
  43569. +{
  43570. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  43571. + struct bfq_group *bfqg;
  43572. + struct cgroup_subsys_state *css;
  43573. +
  43574. + BUG_ON(bfqd == NULL);
  43575. +
  43576. + rcu_read_lock();
  43577. + css = task_css(current, bfqio_subsys_id);
  43578. + bfqg = __bfq_bic_change_cgroup(bfqd, bic, css);
  43579. + rcu_read_unlock();
  43580. +
  43581. + return bfqg;
  43582. +}
  43583. +
  43584. +/**
  43585. + * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st.
  43586. + * @st: the service tree being flushed.
  43587. + */
  43588. +static inline void bfq_flush_idle_tree(struct bfq_service_tree *st)
  43589. +{
  43590. + struct bfq_entity *entity = st->first_idle;
  43591. +
  43592. + for (; entity != NULL; entity = st->first_idle)
  43593. + __bfq_deactivate_entity(entity, 0);
  43594. +}
  43595. +
  43596. +/**
  43597. + * bfq_reparent_leaf_entity - move leaf entity to the root_group.
  43598. + * @bfqd: the device data structure with the root group.
  43599. + * @entity: the entity to move.
  43600. + */
  43601. +static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
  43602. + struct bfq_entity *entity)
  43603. +{
  43604. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  43605. +
  43606. + BUG_ON(bfqq == NULL);
  43607. + bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group);
  43608. + return;
  43609. +}
  43610. +
  43611. +/**
  43612. + * bfq_reparent_active_entities - move to the root group all active
  43613. + * entities.
  43614. + * @bfqd: the device data structure with the root group.
  43615. + * @bfqg: the group to move from.
  43616. + * @st: the service tree with the entities.
  43617. + *
  43618. + * Needs queue_lock to be taken and reference to be valid over the call.
  43619. + */
  43620. +static inline void bfq_reparent_active_entities(struct bfq_data *bfqd,
  43621. + struct bfq_group *bfqg,
  43622. + struct bfq_service_tree *st)
  43623. +{
  43624. + struct rb_root *active = &st->active;
  43625. + struct bfq_entity *entity = NULL;
  43626. +
  43627. + if (!RB_EMPTY_ROOT(&st->active))
  43628. + entity = bfq_entity_of(rb_first(active));
  43629. +
  43630. + for (; entity != NULL; entity = bfq_entity_of(rb_first(active)))
  43631. + bfq_reparent_leaf_entity(bfqd, entity);
  43632. +
  43633. + if (bfqg->sched_data.in_service_entity != NULL)
  43634. + bfq_reparent_leaf_entity(bfqd,
  43635. + bfqg->sched_data.in_service_entity);
  43636. +
  43637. + return;
  43638. +}
  43639. +
  43640. +/**
  43641. + * bfq_destroy_group - destroy @bfqg.
  43642. + * @bgrp: the bfqio_cgroup containing @bfqg.
  43643. + * @bfqg: the group being destroyed.
  43644. + *
  43645. + * Destroy @bfqg, making sure that it is not referenced from its parent.
  43646. + */
  43647. +static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg)
  43648. +{
  43649. + struct bfq_data *bfqd;
  43650. + struct bfq_service_tree *st;
  43651. + struct bfq_entity *entity = bfqg->my_entity;
  43652. + unsigned long uninitialized_var(flags);
  43653. + int i;
  43654. +
  43655. + hlist_del(&bfqg->group_node);
  43656. +
  43657. + /*
  43658. + * Empty all service_trees belonging to this group before
  43659. + * deactivating the group itself.
  43660. + */
  43661. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) {
  43662. + st = bfqg->sched_data.service_tree + i;
  43663. +
  43664. + /*
  43665. + * The idle tree may still contain bfq_queues belonging
  43666. + * to exited task because they never migrated to a different
  43667. + * cgroup from the one being destroyed now. No one else
  43668. + * can access them so it's safe to act without any lock.
  43669. + */
  43670. + bfq_flush_idle_tree(st);
  43671. +
  43672. + /*
  43673. + * It may happen that some queues are still active
  43674. + * (busy) upon group destruction (if the corresponding
  43675. + * processes have been forced to terminate). We move
  43676. + * all the leaf entities corresponding to these queues
  43677. + * to the root_group.
  43678. + * Also, it may happen that the group has an entity
  43679. + * in service, which is disconnected from the active
  43680. + * tree: it must be moved, too.
  43681. + * There is no need to put the sync queues, as the
  43682. + * scheduler has taken no reference.
  43683. + */
  43684. + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags);
  43685. + if (bfqd != NULL) {
  43686. + bfq_reparent_active_entities(bfqd, bfqg, st);
  43687. + bfq_put_bfqd_unlock(bfqd, &flags);
  43688. + }
  43689. + BUG_ON(!RB_EMPTY_ROOT(&st->active));
  43690. + BUG_ON(!RB_EMPTY_ROOT(&st->idle));
  43691. + }
  43692. + BUG_ON(bfqg->sched_data.next_in_service != NULL);
  43693. + BUG_ON(bfqg->sched_data.in_service_entity != NULL);
  43694. +
  43695. + /*
  43696. + * We may race with device destruction, take extra care when
  43697. + * dereferencing bfqg->bfqd.
  43698. + */
  43699. + bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags);
  43700. + if (bfqd != NULL) {
  43701. + hlist_del(&bfqg->bfqd_node);
  43702. + __bfq_deactivate_entity(entity, 0);
  43703. + bfq_put_async_queues(bfqd, bfqg);
  43704. + bfq_put_bfqd_unlock(bfqd, &flags);
  43705. + }
  43706. + BUG_ON(entity->tree != NULL);
  43707. +
  43708. + /*
  43709. + * No need to defer the kfree() to the end of the RCU grace
  43710. + * period: we are called from the destroy() callback of our
  43711. + * cgroup, so we can be sure that no one is a) still using
  43712. + * this cgroup or b) doing lookups in it.
  43713. + */
  43714. + kfree(bfqg);
  43715. +}
  43716. +
  43717. +static void bfq_end_wr_async(struct bfq_data *bfqd)
  43718. +{
  43719. + struct hlist_node *tmp;
  43720. + struct bfq_group *bfqg;
  43721. +
  43722. + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node)
  43723. + bfq_end_wr_async_queues(bfqd, bfqg);
  43724. + bfq_end_wr_async_queues(bfqd, bfqd->root_group);
  43725. +}
  43726. +
  43727. +/**
  43728. + * bfq_disconnect_groups - disconnect @bfqd from all its groups.
  43729. + * @bfqd: the device descriptor being exited.
  43730. + *
  43731. + * When the device exits we just make sure that no lookup can return
  43732. + * the now unused group structures. They will be deallocated on cgroup
  43733. + * destruction.
  43734. + */
  43735. +static void bfq_disconnect_groups(struct bfq_data *bfqd)
  43736. +{
  43737. + struct hlist_node *tmp;
  43738. + struct bfq_group *bfqg;
  43739. +
  43740. + bfq_log(bfqd, "disconnect_groups beginning");
  43741. + hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) {
  43742. + hlist_del(&bfqg->bfqd_node);
  43743. +
  43744. + __bfq_deactivate_entity(bfqg->my_entity, 0);
  43745. +
  43746. + /*
  43747. + * Don't remove from the group hash, just set an
  43748. + * invalid key. No lookups can race with the
  43749. + * assignment as bfqd is being destroyed; this
  43750. + * implies also that new elements cannot be added
  43751. + * to the list.
  43752. + */
  43753. + rcu_assign_pointer(bfqg->bfqd, NULL);
  43754. +
  43755. + bfq_log(bfqd, "disconnect_groups: put async for group %p",
  43756. + bfqg);
  43757. + bfq_put_async_queues(bfqd, bfqg);
  43758. + }
  43759. +}
  43760. +
  43761. +static inline void bfq_free_root_group(struct bfq_data *bfqd)
  43762. +{
  43763. + struct bfqio_cgroup *bgrp = &bfqio_root_cgroup;
  43764. + struct bfq_group *bfqg = bfqd->root_group;
  43765. +
  43766. + bfq_put_async_queues(bfqd, bfqg);
  43767. +
  43768. + spin_lock_irq(&bgrp->lock);
  43769. + hlist_del_rcu(&bfqg->group_node);
  43770. + spin_unlock_irq(&bgrp->lock);
  43771. +
  43772. + /*
  43773. + * No need to synchronize_rcu() here: since the device is gone
  43774. + * there cannot be any read-side access to its root_group.
  43775. + */
  43776. + kfree(bfqg);
  43777. +}
  43778. +
  43779. +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node)
  43780. +{
  43781. + struct bfq_group *bfqg;
  43782. + struct bfqio_cgroup *bgrp;
  43783. + int i;
  43784. +
  43785. + bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node);
  43786. + if (bfqg == NULL)
  43787. + return NULL;
  43788. +
  43789. + bfqg->entity.parent = NULL;
  43790. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
  43791. + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
  43792. +
  43793. + bgrp = &bfqio_root_cgroup;
  43794. + spin_lock_irq(&bgrp->lock);
  43795. + rcu_assign_pointer(bfqg->bfqd, bfqd);
  43796. + hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data);
  43797. + spin_unlock_irq(&bgrp->lock);
  43798. +
  43799. + return bfqg;
  43800. +}
  43801. +
  43802. +#define SHOW_FUNCTION(__VAR) \
  43803. +static u64 bfqio_cgroup_##__VAR##_read(struct cgroup_subsys_state *css, \
  43804. + struct cftype *cftype) \
  43805. +{ \
  43806. + struct bfqio_cgroup *bgrp = css_to_bfqio(css); \
  43807. + u64 ret = -ENODEV; \
  43808. + \
  43809. + mutex_lock(&bfqio_mutex); \
  43810. + if (bfqio_is_removed(bgrp)) \
  43811. + goto out_unlock; \
  43812. + \
  43813. + spin_lock_irq(&bgrp->lock); \
  43814. + ret = bgrp->__VAR; \
  43815. + spin_unlock_irq(&bgrp->lock); \
  43816. + \
  43817. +out_unlock: \
  43818. + mutex_unlock(&bfqio_mutex); \
  43819. + return ret; \
  43820. +}
  43821. +
  43822. +SHOW_FUNCTION(weight);
  43823. +SHOW_FUNCTION(ioprio);
  43824. +SHOW_FUNCTION(ioprio_class);
  43825. +#undef SHOW_FUNCTION
  43826. +
  43827. +#define STORE_FUNCTION(__VAR, __MIN, __MAX) \
  43828. +static int bfqio_cgroup_##__VAR##_write(struct cgroup_subsys_state *css,\
  43829. + struct cftype *cftype, \
  43830. + u64 val) \
  43831. +{ \
  43832. + struct bfqio_cgroup *bgrp = css_to_bfqio(css); \
  43833. + struct bfq_group *bfqg; \
  43834. + int ret = -EINVAL; \
  43835. + \
  43836. + if (val < (__MIN) || val > (__MAX)) \
  43837. + return ret; \
  43838. + \
  43839. + ret = -ENODEV; \
  43840. + mutex_lock(&bfqio_mutex); \
  43841. + if (bfqio_is_removed(bgrp)) \
  43842. + goto out_unlock; \
  43843. + ret = 0; \
  43844. + \
  43845. + spin_lock_irq(&bgrp->lock); \
  43846. + bgrp->__VAR = (unsigned short)val; \
  43847. + hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \
  43848. + /* \
  43849. + * Setting the ioprio_changed flag of the entity \
  43850. + * to 1 with new_##__VAR == ##__VAR would re-set \
  43851. + * the value of the weight to its ioprio mapping. \
  43852. + * Set the flag only if necessary. \
  43853. + */ \
  43854. + if ((unsigned short)val != bfqg->entity.new_##__VAR) { \
  43855. + bfqg->entity.new_##__VAR = (unsigned short)val; \
  43856. + /* \
  43857. + * Make sure that the above new value has been \
  43858. + * stored in bfqg->entity.new_##__VAR before \
  43859. + * setting the ioprio_changed flag. In fact, \
  43860. + * this flag may be read asynchronously (in \
  43861. + * critical sections protected by a different \
  43862. + * lock than that held here), and finding this \
  43863. + * flag set may cause the execution of the code \
  43864. + * for updating parameters whose value may \
  43865. + * depend also on bfqg->entity.new_##__VAR (in \
  43866. + * __bfq_entity_update_weight_prio). \
  43867. + * This barrier makes sure that the new value \
  43868. + * of bfqg->entity.new_##__VAR is correctly \
  43869. + * seen in that code. \
  43870. + */ \
  43871. + smp_wmb(); \
  43872. + bfqg->entity.ioprio_changed = 1; \
  43873. + } \
  43874. + } \
  43875. + spin_unlock_irq(&bgrp->lock); \
  43876. + \
  43877. +out_unlock: \
  43878. + mutex_unlock(&bfqio_mutex); \
  43879. + return ret; \
  43880. +}
  43881. +
  43882. +STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT);
  43883. +STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1);
  43884. +STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE);
  43885. +#undef STORE_FUNCTION
  43886. +
  43887. +static struct cftype bfqio_files[] = {
  43888. + {
  43889. + .name = "weight",
  43890. + .read_u64 = bfqio_cgroup_weight_read,
  43891. + .write_u64 = bfqio_cgroup_weight_write,
  43892. + },
  43893. + {
  43894. + .name = "ioprio",
  43895. + .read_u64 = bfqio_cgroup_ioprio_read,
  43896. + .write_u64 = bfqio_cgroup_ioprio_write,
  43897. + },
  43898. + {
  43899. + .name = "ioprio_class",
  43900. + .read_u64 = bfqio_cgroup_ioprio_class_read,
  43901. + .write_u64 = bfqio_cgroup_ioprio_class_write,
  43902. + },
  43903. + { }, /* terminate */
  43904. +};
  43905. +
  43906. +static struct cgroup_subsys_state *bfqio_create(struct cgroup_subsys_state
  43907. + *parent_css)
  43908. +{
  43909. + struct bfqio_cgroup *bgrp;
  43910. +
  43911. + if (parent_css != NULL) {
  43912. + bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL);
  43913. + if (bgrp == NULL)
  43914. + return ERR_PTR(-ENOMEM);
  43915. + } else
  43916. + bgrp = &bfqio_root_cgroup;
  43917. +
  43918. + spin_lock_init(&bgrp->lock);
  43919. + INIT_HLIST_HEAD(&bgrp->group_data);
  43920. + bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO;
  43921. + bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS;
  43922. +
  43923. + return &bgrp->css;
  43924. +}
  43925. +
  43926. +/*
  43927. + * We cannot support shared io contexts, as we have no means to support
  43928. + * two tasks with the same ioc in two different groups without major rework
  43929. + * of the main bic/bfqq data structures. By now we allow a task to change
  43930. + * its cgroup only if it's the only owner of its ioc; the drawback of this
  43931. + * behavior is that a group containing a task that forked using CLONE_IO
  43932. + * will not be destroyed until the tasks sharing the ioc die.
  43933. + */
  43934. +static int bfqio_can_attach(struct cgroup_subsys_state *css,
  43935. + struct cgroup_taskset *tset)
  43936. +{
  43937. + struct task_struct *task;
  43938. + struct io_context *ioc;
  43939. + int ret = 0;
  43940. +
  43941. + cgroup_taskset_for_each(task, css, tset) {
  43942. + /*
  43943. + * task_lock() is needed to avoid races with
  43944. + * exit_io_context()
  43945. + */
  43946. + task_lock(task);
  43947. + ioc = task->io_context;
  43948. + if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1)
  43949. + /*
  43950. + * ioc == NULL means that the task is either too
  43951. + * young or exiting: if it has still no ioc the
  43952. + * ioc can't be shared, if the task is exiting the
  43953. + * attach will fail anyway, no matter what we
  43954. + * return here.
  43955. + */
  43956. + ret = -EINVAL;
  43957. + task_unlock(task);
  43958. + if (ret)
  43959. + break;
  43960. + }
  43961. +
  43962. + return ret;
  43963. +}
  43964. +
  43965. +static void bfqio_attach(struct cgroup_subsys_state *css,
  43966. + struct cgroup_taskset *tset)
  43967. +{
  43968. + struct task_struct *task;
  43969. + struct io_context *ioc;
  43970. + struct io_cq *icq;
  43971. +
  43972. + /*
  43973. + * IMPORTANT NOTE: The move of more than one process at a time to a
  43974. + * new group has not yet been tested.
  43975. + */
  43976. + cgroup_taskset_for_each(task, css, tset) {
  43977. + ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE);
  43978. + if (ioc) {
  43979. + /*
  43980. + * Handle cgroup change here.
  43981. + */
  43982. + rcu_read_lock();
  43983. + hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node)
  43984. + if (!strncmp(
  43985. + icq->q->elevator->type->elevator_name,
  43986. + "bfq", ELV_NAME_MAX))
  43987. + bfq_bic_change_cgroup(icq_to_bic(icq),
  43988. + css);
  43989. + rcu_read_unlock();
  43990. + put_io_context(ioc);
  43991. + }
  43992. + }
  43993. +}
  43994. +
  43995. +static void bfqio_destroy(struct cgroup_subsys_state *css)
  43996. +{
  43997. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  43998. + struct hlist_node *tmp;
  43999. + struct bfq_group *bfqg;
  44000. +
  44001. + /*
  44002. + * Since we are destroying the cgroup, there are no more tasks
  44003. + * referencing it, and all the RCU grace periods that may have
  44004. + * referenced it are ended (as the destruction of the parent
  44005. + * cgroup is RCU-safe); bgrp->group_data will not be accessed by
  44006. + * anything else and we don't need any synchronization.
  44007. + */
  44008. + hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node)
  44009. + bfq_destroy_group(bgrp, bfqg);
  44010. +
  44011. + BUG_ON(!hlist_empty(&bgrp->group_data));
  44012. +
  44013. + kfree(bgrp);
  44014. +}
  44015. +
  44016. +static int bfqio_css_online(struct cgroup_subsys_state *css)
  44017. +{
  44018. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  44019. +
  44020. + mutex_lock(&bfqio_mutex);
  44021. + bgrp->online = true;
  44022. + mutex_unlock(&bfqio_mutex);
  44023. +
  44024. + return 0;
  44025. +}
  44026. +
  44027. +static void bfqio_css_offline(struct cgroup_subsys_state *css)
  44028. +{
  44029. + struct bfqio_cgroup *bgrp = css_to_bfqio(css);
  44030. +
  44031. + mutex_lock(&bfqio_mutex);
  44032. + bgrp->online = false;
  44033. + mutex_unlock(&bfqio_mutex);
  44034. +}
  44035. +
  44036. +struct cgroup_subsys bfqio_subsys = {
  44037. + .name = "bfqio",
  44038. + .css_alloc = bfqio_create,
  44039. + .css_online = bfqio_css_online,
  44040. + .css_offline = bfqio_css_offline,
  44041. + .can_attach = bfqio_can_attach,
  44042. + .attach = bfqio_attach,
  44043. + .css_free = bfqio_destroy,
  44044. + .subsys_id = bfqio_subsys_id,
  44045. + .base_cftypes = bfqio_files,
  44046. +};
  44047. +#else
  44048. +static inline void bfq_init_entity(struct bfq_entity *entity,
  44049. + struct bfq_group *bfqg)
  44050. +{
  44051. + entity->weight = entity->new_weight;
  44052. + entity->orig_weight = entity->new_weight;
  44053. + entity->ioprio = entity->new_ioprio;
  44054. + entity->ioprio_class = entity->new_ioprio_class;
  44055. + entity->sched_data = &bfqg->sched_data;
  44056. +}
  44057. +
  44058. +static inline struct bfq_group *
  44059. +bfq_bic_update_cgroup(struct bfq_io_cq *bic)
  44060. +{
  44061. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  44062. + return bfqd->root_group;
  44063. +}
  44064. +
  44065. +static inline void bfq_bfqq_move(struct bfq_data *bfqd,
  44066. + struct bfq_queue *bfqq,
  44067. + struct bfq_entity *entity,
  44068. + struct bfq_group *bfqg)
  44069. +{
  44070. +}
  44071. +
  44072. +static void bfq_end_wr_async(struct bfq_data *bfqd)
  44073. +{
  44074. + bfq_end_wr_async_queues(bfqd, bfqd->root_group);
  44075. +}
  44076. +
  44077. +static inline void bfq_disconnect_groups(struct bfq_data *bfqd)
  44078. +{
  44079. + bfq_put_async_queues(bfqd, bfqd->root_group);
  44080. +}
  44081. +
  44082. +static inline void bfq_free_root_group(struct bfq_data *bfqd)
  44083. +{
  44084. + kfree(bfqd->root_group);
  44085. +}
  44086. +
  44087. +static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node)
  44088. +{
  44089. + struct bfq_group *bfqg;
  44090. + int i;
  44091. +
  44092. + bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node);
  44093. + if (bfqg == NULL)
  44094. + return NULL;
  44095. +
  44096. + for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
  44097. + bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
  44098. +
  44099. + return bfqg;
  44100. +}
  44101. +#endif
  44102. diff -Nur linux-3.14.17/block/bfq.h linux-imx6-3.14/block/bfq.h
  44103. --- linux-3.14.17/block/bfq.h 1970-01-01 01:00:00.000000000 +0100
  44104. +++ linux-imx6-3.14/block/bfq.h 2014-09-11 18:05:59.118026454 +0200
  44105. @@ -0,0 +1,770 @@
  44106. +/*
  44107. + * BFQ-v7r5 for 3.14.0: data structures and common functions prototypes.
  44108. + *
  44109. + * Based on ideas and code from CFQ:
  44110. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  44111. + *
  44112. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  44113. + * Paolo Valente <paolo.valente@unimore.it>
  44114. + *
  44115. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  44116. + */
  44117. +
  44118. +#ifndef _BFQ_H
  44119. +#define _BFQ_H
  44120. +
  44121. +#include <linux/blktrace_api.h>
  44122. +#include <linux/hrtimer.h>
  44123. +#include <linux/ioprio.h>
  44124. +#include <linux/rbtree.h>
  44125. +
  44126. +#define BFQ_IOPRIO_CLASSES 3
  44127. +#define BFQ_CL_IDLE_TIMEOUT (HZ/5)
  44128. +
  44129. +#define BFQ_MIN_WEIGHT 1
  44130. +#define BFQ_MAX_WEIGHT 1000
  44131. +
  44132. +#define BFQ_DEFAULT_GRP_WEIGHT 10
  44133. +#define BFQ_DEFAULT_GRP_IOPRIO 0
  44134. +#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE
  44135. +
  44136. +struct bfq_entity;
  44137. +
  44138. +/**
  44139. + * struct bfq_service_tree - per ioprio_class service tree.
  44140. + * @active: tree for active entities (i.e., those backlogged).
  44141. + * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i).
  44142. + * @first_idle: idle entity with minimum F_i.
  44143. + * @last_idle: idle entity with maximum F_i.
  44144. + * @vtime: scheduler virtual time.
  44145. + * @wsum: scheduler weight sum; active and idle entities contribute to it.
  44146. + *
  44147. + * Each service tree represents a B-WF2Q+ scheduler on its own. Each
  44148. + * ioprio_class has its own independent scheduler, and so its own
  44149. + * bfq_service_tree. All the fields are protected by the queue lock
  44150. + * of the containing bfqd.
  44151. + */
  44152. +struct bfq_service_tree {
  44153. + struct rb_root active;
  44154. + struct rb_root idle;
  44155. +
  44156. + struct bfq_entity *first_idle;
  44157. + struct bfq_entity *last_idle;
  44158. +
  44159. + u64 vtime;
  44160. + unsigned long wsum;
  44161. +};
  44162. +
  44163. +/**
  44164. + * struct bfq_sched_data - multi-class scheduler.
  44165. + * @in_service_entity: entity in service.
  44166. + * @next_in_service: head-of-the-line entity in the scheduler.
  44167. + * @service_tree: array of service trees, one per ioprio_class.
  44168. + *
  44169. + * bfq_sched_data is the basic scheduler queue. It supports three
  44170. + * ioprio_classes, and can be used either as a toplevel queue or as
  44171. + * an intermediate queue on a hierarchical setup.
  44172. + * @next_in_service points to the active entity of the sched_data
  44173. + * service trees that will be scheduled next.
  44174. + *
  44175. + * The supported ioprio_classes are the same as in CFQ, in descending
  44176. + * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE.
  44177. + * Requests from higher priority queues are served before all the
  44178. + * requests from lower priority queues; among requests of the same
  44179. + * queue requests are served according to B-WF2Q+.
  44180. + * All the fields are protected by the queue lock of the containing bfqd.
  44181. + */
  44182. +struct bfq_sched_data {
  44183. + struct bfq_entity *in_service_entity;
  44184. + struct bfq_entity *next_in_service;
  44185. + struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES];
  44186. +};
  44187. +
  44188. +/**
  44189. + * struct bfq_weight_counter - counter of the number of all active entities
  44190. + * with a given weight.
  44191. + * @weight: weight of the entities that this counter refers to.
  44192. + * @num_active: number of active entities with this weight.
  44193. + * @weights_node: weights tree member (see bfq_data's @queue_weights_tree
  44194. + * and @group_weights_tree).
  44195. + */
  44196. +struct bfq_weight_counter {
  44197. + short int weight;
  44198. + unsigned int num_active;
  44199. + struct rb_node weights_node;
  44200. +};
  44201. +
  44202. +/**
  44203. + * struct bfq_entity - schedulable entity.
  44204. + * @rb_node: service_tree member.
  44205. + * @weight_counter: pointer to the weight counter associated with this entity.
  44206. + * @on_st: flag, true if the entity is on a tree (either the active or
  44207. + * the idle one of its service_tree).
  44208. + * @finish: B-WF2Q+ finish timestamp (aka F_i).
  44209. + * @start: B-WF2Q+ start timestamp (aka S_i).
  44210. + * @tree: tree the entity is enqueued into; %NULL if not on a tree.
  44211. + * @min_start: minimum start time of the (active) subtree rooted at
  44212. + * this entity; used for O(log N) lookups into active trees.
  44213. + * @service: service received during the last round of service.
  44214. + * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight.
  44215. + * @weight: weight of the queue
  44216. + * @parent: parent entity, for hierarchical scheduling.
  44217. + * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the
  44218. + * associated scheduler queue, %NULL on leaf nodes.
  44219. + * @sched_data: the scheduler queue this entity belongs to.
  44220. + * @ioprio: the ioprio in use.
  44221. + * @new_weight: when a weight change is requested, the new weight value.
  44222. + * @orig_weight: original weight, used to implement weight boosting
  44223. + * @new_ioprio: when an ioprio change is requested, the new ioprio value.
  44224. + * @ioprio_class: the ioprio_class in use.
  44225. + * @new_ioprio_class: when an ioprio_class change is requested, the new
  44226. + * ioprio_class value.
  44227. + * @ioprio_changed: flag, true when the user requested a weight, ioprio or
  44228. + * ioprio_class change.
  44229. + *
  44230. + * A bfq_entity is used to represent either a bfq_queue (leaf node in the
  44231. + * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each
  44232. + * entity belongs to the sched_data of the parent group in the cgroup
  44233. + * hierarchy. Non-leaf entities have also their own sched_data, stored
  44234. + * in @my_sched_data.
  44235. + *
  44236. + * Each entity stores independently its priority values; this would
  44237. + * allow different weights on different devices, but this
  44238. + * functionality is not exported to userspace by now. Priorities and
  44239. + * weights are updated lazily, first storing the new values into the
  44240. + * new_* fields, then setting the @ioprio_changed flag. As soon as
  44241. + * there is a transition in the entity state that allows the priority
  44242. + * update to take place the effective and the requested priority
  44243. + * values are synchronized.
  44244. + *
  44245. + * Unless cgroups are used, the weight value is calculated from the
  44246. + * ioprio to export the same interface as CFQ. When dealing with
  44247. + * ``well-behaved'' queues (i.e., queues that do not spend too much
  44248. + * time to consume their budget and have true sequential behavior, and
  44249. + * when there are no external factors breaking anticipation) the
  44250. + * relative weights at each level of the cgroups hierarchy should be
  44251. + * guaranteed. All the fields are protected by the queue lock of the
  44252. + * containing bfqd.
  44253. + */
  44254. +struct bfq_entity {
  44255. + struct rb_node rb_node;
  44256. + struct bfq_weight_counter *weight_counter;
  44257. +
  44258. + int on_st;
  44259. +
  44260. + u64 finish;
  44261. + u64 start;
  44262. +
  44263. + struct rb_root *tree;
  44264. +
  44265. + u64 min_start;
  44266. +
  44267. + unsigned long service, budget;
  44268. + unsigned short weight, new_weight;
  44269. + unsigned short orig_weight;
  44270. +
  44271. + struct bfq_entity *parent;
  44272. +
  44273. + struct bfq_sched_data *my_sched_data;
  44274. + struct bfq_sched_data *sched_data;
  44275. +
  44276. + unsigned short ioprio, new_ioprio;
  44277. + unsigned short ioprio_class, new_ioprio_class;
  44278. +
  44279. + int ioprio_changed;
  44280. +};
  44281. +
  44282. +struct bfq_group;
  44283. +
  44284. +/**
  44285. + * struct bfq_queue - leaf schedulable entity.
  44286. + * @ref: reference counter.
  44287. + * @bfqd: parent bfq_data.
  44288. + * @new_bfqq: shared bfq_queue if queue is cooperating with
  44289. + * one or more other queues.
  44290. + * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree).
  44291. + * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree).
  44292. + * @sort_list: sorted list of pending requests.
  44293. + * @next_rq: if fifo isn't expired, next request to serve.
  44294. + * @queued: nr of requests queued in @sort_list.
  44295. + * @allocated: currently allocated requests.
  44296. + * @meta_pending: pending metadata requests.
  44297. + * @fifo: fifo list of requests in sort_list.
  44298. + * @entity: entity representing this queue in the scheduler.
  44299. + * @max_budget: maximum budget allowed from the feedback mechanism.
  44300. + * @budget_timeout: budget expiration (in jiffies).
  44301. + * @dispatched: number of requests on the dispatch list or inside driver.
  44302. + * @flags: status flags.
  44303. + * @bfqq_list: node for active/idle bfqq list inside our bfqd.
  44304. + * @seek_samples: number of seeks sampled
  44305. + * @seek_total: sum of the distances of the seeks sampled
  44306. + * @seek_mean: mean seek distance
  44307. + * @last_request_pos: position of the last request enqueued
  44308. + * @requests_within_timer: number of consecutive pairs of request completion
  44309. + * and arrival, such that the queue becomes idle
  44310. + * after the completion, but the next request arrives
  44311. + * within an idle time slice; used only if the queue's
  44312. + * IO_bound has been cleared.
  44313. + * @pid: pid of the process owning the queue, used for logging purposes.
  44314. + * @last_wr_start_finish: start time of the current weight-raising period if
  44315. + * the @bfq-queue is being weight-raised, otherwise
  44316. + * finish time of the last weight-raising period
  44317. + * @wr_cur_max_time: current max raising time for this queue
  44318. + * @soft_rt_next_start: minimum time instant such that, only if a new
  44319. + * request is enqueued after this time instant in an
  44320. + * idle @bfq_queue with no outstanding requests, then
  44321. + * the task associated with the queue it is deemed as
  44322. + * soft real-time (see the comments to the function
  44323. + * bfq_bfqq_softrt_next_start())
  44324. + * @last_idle_bklogged: time of the last transition of the @bfq_queue from
  44325. + * idle to backlogged
  44326. + * @service_from_backlogged: cumulative service received from the @bfq_queue
  44327. + * since the last transition from idle to
  44328. + * backlogged
  44329. + * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the
  44330. + * queue is shared
  44331. + *
  44332. + * A bfq_queue is a leaf request queue; it can be associated with an
  44333. + * io_context or more, if it is async or shared between cooperating
  44334. + * processes. @cgroup holds a reference to the cgroup, to be sure that it
  44335. + * does not disappear while a bfqq still references it (mostly to avoid
  44336. + * races between request issuing and task migration followed by cgroup
  44337. + * destruction).
  44338. + * All the fields are protected by the queue lock of the containing bfqd.
  44339. + */
  44340. +struct bfq_queue {
  44341. + atomic_t ref;
  44342. + struct bfq_data *bfqd;
  44343. +
  44344. + /* fields for cooperating queues handling */
  44345. + struct bfq_queue *new_bfqq;
  44346. + struct rb_node pos_node;
  44347. + struct rb_root *pos_root;
  44348. +
  44349. + struct rb_root sort_list;
  44350. + struct request *next_rq;
  44351. + int queued[2];
  44352. + int allocated[2];
  44353. + int meta_pending;
  44354. + struct list_head fifo;
  44355. +
  44356. + struct bfq_entity entity;
  44357. +
  44358. + unsigned long max_budget;
  44359. + unsigned long budget_timeout;
  44360. +
  44361. + int dispatched;
  44362. +
  44363. + unsigned int flags;
  44364. +
  44365. + struct list_head bfqq_list;
  44366. +
  44367. + unsigned int seek_samples;
  44368. + u64 seek_total;
  44369. + sector_t seek_mean;
  44370. + sector_t last_request_pos;
  44371. +
  44372. + unsigned int requests_within_timer;
  44373. +
  44374. + pid_t pid;
  44375. + struct bfq_io_cq *bic;
  44376. +
  44377. + /* weight-raising fields */
  44378. + unsigned long wr_cur_max_time;
  44379. + unsigned long soft_rt_next_start;
  44380. + unsigned long last_wr_start_finish;
  44381. + unsigned int wr_coeff;
  44382. + unsigned long last_idle_bklogged;
  44383. + unsigned long service_from_backlogged;
  44384. +};
  44385. +
  44386. +/**
  44387. + * struct bfq_ttime - per process thinktime stats.
  44388. + * @ttime_total: total process thinktime
  44389. + * @ttime_samples: number of thinktime samples
  44390. + * @ttime_mean: average process thinktime
  44391. + */
  44392. +struct bfq_ttime {
  44393. + unsigned long last_end_request;
  44394. +
  44395. + unsigned long ttime_total;
  44396. + unsigned long ttime_samples;
  44397. + unsigned long ttime_mean;
  44398. +};
  44399. +
  44400. +/**
  44401. + * struct bfq_io_cq - per (request_queue, io_context) structure.
  44402. + * @icq: associated io_cq structure
  44403. + * @bfqq: array of two process queues, the sync and the async
  44404. + * @ttime: associated @bfq_ttime struct
  44405. + * @wr_time_left: snapshot of the time left before weight raising ends
  44406. + * for the sync queue associated to this process; this
  44407. + * snapshot is taken to remember this value while the weight
  44408. + * raising is suspended because the queue is merged with a
  44409. + * shared queue, and is used to set @raising_cur_max_time
  44410. + * when the queue is split from the shared queue and its
  44411. + * weight is raised again
  44412. + * @saved_idle_window: same purpose as the previous field for the idle
  44413. + * window
  44414. + * @saved_IO_bound: same purpose as the previous two fields for the I/O
  44415. + * bound classification of a queue
  44416. + * @cooperations: counter of consecutive successful queue merges underwent
  44417. + * by any of the process' @bfq_queues
  44418. + * @failed_cooperations: counter of consecutive failed queue merges of any
  44419. + * of the process' @bfq_queues
  44420. + */
  44421. +struct bfq_io_cq {
  44422. + struct io_cq icq; /* must be the first member */
  44423. + struct bfq_queue *bfqq[2];
  44424. + struct bfq_ttime ttime;
  44425. + int ioprio;
  44426. +
  44427. + unsigned int wr_time_left;
  44428. + unsigned int saved_idle_window;
  44429. + unsigned int saved_IO_bound;
  44430. +
  44431. + unsigned int cooperations;
  44432. + unsigned int failed_cooperations;
  44433. +};
  44434. +
  44435. +enum bfq_device_speed {
  44436. + BFQ_BFQD_FAST,
  44437. + BFQ_BFQD_SLOW,
  44438. +};
  44439. +
  44440. +/**
  44441. + * struct bfq_data - per device data structure.
  44442. + * @queue: request queue for the managed device.
  44443. + * @root_group: root bfq_group for the device.
  44444. + * @rq_pos_tree: rbtree sorted by next_request position, used when
  44445. + * determining if two or more queues have interleaving
  44446. + * requests (see bfq_close_cooperator()).
  44447. + * @active_numerous_groups: number of bfq_groups containing more than one
  44448. + * active @bfq_entity.
  44449. + * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by
  44450. + * weight. Used to keep track of whether all @bfq_queues
  44451. + * have the same weight. The tree contains one counter
  44452. + * for each distinct weight associated to some active
  44453. + * and not weight-raised @bfq_queue (see the comments to
  44454. + * the functions bfq_weights_tree_[add|remove] for
  44455. + * further details).
  44456. + * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted
  44457. + * by weight. Used to keep track of whether all
  44458. + * @bfq_groups have the same weight. The tree contains
  44459. + * one counter for each distinct weight associated to
  44460. + * some active @bfq_group (see the comments to the
  44461. + * functions bfq_weights_tree_[add|remove] for further
  44462. + * details).
  44463. + * @busy_queues: number of bfq_queues containing requests (including the
  44464. + * queue in service, even if it is idling).
  44465. + * @busy_in_flight_queues: number of @bfq_queues containing pending or
  44466. + * in-flight requests, plus the @bfq_queue in
  44467. + * service, even if idle but waiting for the
  44468. + * possible arrival of its next sync request. This
  44469. + * field is updated only if the device is rotational,
  44470. + * but used only if the device is also NCQ-capable.
  44471. + * The reason why the field is updated also for non-
  44472. + * NCQ-capable rotational devices is related to the
  44473. + * fact that the value of @hw_tag may be set also
  44474. + * later than when busy_in_flight_queues may need to
  44475. + * be incremented for the first time(s). Taking also
  44476. + * this possibility into account, to avoid unbalanced
  44477. + * increments/decrements, would imply more overhead
  44478. + * than just updating busy_in_flight_queues
  44479. + * regardless of the value of @hw_tag.
  44480. + * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues
  44481. + * (that is, seeky queues that expired
  44482. + * for budget timeout at least once)
  44483. + * containing pending or in-flight
  44484. + * requests, including the in-service
  44485. + * @bfq_queue if constantly seeky. This
  44486. + * field is updated only if the device
  44487. + * is rotational, but used only if the
  44488. + * device is also NCQ-capable (see the
  44489. + * comments to @busy_in_flight_queues).
  44490. + * @wr_busy_queues: number of weight-raised busy @bfq_queues.
  44491. + * @queued: number of queued requests.
  44492. + * @rq_in_driver: number of requests dispatched and waiting for completion.
  44493. + * @sync_flight: number of sync requests in the driver.
  44494. + * @max_rq_in_driver: max number of reqs in driver in the last
  44495. + * @hw_tag_samples completed requests.
  44496. + * @hw_tag_samples: nr of samples used to calculate hw_tag.
  44497. + * @hw_tag: flag set to one if the driver is showing a queueing behavior.
  44498. + * @budgets_assigned: number of budgets assigned.
  44499. + * @idle_slice_timer: timer set when idling for the next sequential request
  44500. + * from the queue in service.
  44501. + * @unplug_work: delayed work to restart dispatching on the request queue.
  44502. + * @in_service_queue: bfq_queue in service.
  44503. + * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue.
  44504. + * @last_position: on-disk position of the last served request.
  44505. + * @last_budget_start: beginning of the last budget.
  44506. + * @last_idling_start: beginning of the last idle slice.
  44507. + * @peak_rate: peak transfer rate observed for a budget.
  44508. + * @peak_rate_samples: number of samples used to calculate @peak_rate.
  44509. + * @bfq_max_budget: maximum budget allotted to a bfq_queue before
  44510. + * rescheduling.
  44511. + * @group_list: list of all the bfq_groups active on the device.
  44512. + * @active_list: list of all the bfq_queues active on the device.
  44513. + * @idle_list: list of all the bfq_queues idle on the device.
  44514. + * @bfq_quantum: max number of requests dispatched per dispatch round.
  44515. + * @bfq_fifo_expire: timeout for async/sync requests; when it expires
  44516. + * requests are served in fifo order.
  44517. + * @bfq_back_penalty: weight of backward seeks wrt forward ones.
  44518. + * @bfq_back_max: maximum allowed backward seek.
  44519. + * @bfq_slice_idle: maximum idling time.
  44520. + * @bfq_user_max_budget: user-configured max budget value
  44521. + * (0 for auto-tuning).
  44522. + * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to
  44523. + * async queues.
  44524. + * @bfq_timeout: timeout for bfq_queues to consume their budget; used to
  44525. + * to prevent seeky queues to impose long latencies to well
  44526. + * behaved ones (this also implies that seeky queues cannot
  44527. + * receive guarantees in the service domain; after a timeout
  44528. + * they are charged for the whole allocated budget, to try
  44529. + * to preserve a behavior reasonably fair among them, but
  44530. + * without service-domain guarantees).
  44531. + * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is
  44532. + * no more granted any weight-raising.
  44533. + * @bfq_failed_cooperations: number of consecutive failed cooperation
  44534. + * chances after which weight-raising is restored
  44535. + * to a queue subject to more than bfq_coop_thresh
  44536. + * queue merges.
  44537. + * @bfq_requests_within_timer: number of consecutive requests that must be
  44538. + * issued within the idle time slice to set
  44539. + * again idling to a queue which was marked as
  44540. + * non-I/O-bound (see the definition of the
  44541. + * IO_bound flag for further details).
  44542. + * @bfq_wr_coeff: Maximum factor by which the weight of a weight-raised
  44543. + * queue is multiplied
  44544. + * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies)
  44545. + * @bfq_wr_rt_max_time: maximum duration for soft real-time processes
  44546. + * @bfq_wr_min_idle_time: minimum idle period after which weight-raising
  44547. + * may be reactivated for a queue (in jiffies)
  44548. + * @bfq_wr_min_inter_arr_async: minimum period between request arrivals
  44549. + * after which weight-raising may be
  44550. + * reactivated for an already busy queue
  44551. + * (in jiffies)
  44552. + * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue,
  44553. + * sectors per seconds
  44554. + * @RT_prod: cached value of the product R*T used for computing the maximum
  44555. + * duration of the weight raising automatically
  44556. + * @device_speed: device-speed class for the low-latency heuristic
  44557. + * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions
  44558. + *
  44559. + * All the fields are protected by the @queue lock.
  44560. + */
  44561. +struct bfq_data {
  44562. + struct request_queue *queue;
  44563. +
  44564. + struct bfq_group *root_group;
  44565. + struct rb_root rq_pos_tree;
  44566. +
  44567. +#ifdef CONFIG_CGROUP_BFQIO
  44568. + int active_numerous_groups;
  44569. +#endif
  44570. +
  44571. + struct rb_root queue_weights_tree;
  44572. + struct rb_root group_weights_tree;
  44573. +
  44574. + int busy_queues;
  44575. + int busy_in_flight_queues;
  44576. + int const_seeky_busy_in_flight_queues;
  44577. + int wr_busy_queues;
  44578. + int queued;
  44579. + int rq_in_driver;
  44580. + int sync_flight;
  44581. +
  44582. + int max_rq_in_driver;
  44583. + int hw_tag_samples;
  44584. + int hw_tag;
  44585. +
  44586. + int budgets_assigned;
  44587. +
  44588. + struct timer_list idle_slice_timer;
  44589. + struct work_struct unplug_work;
  44590. +
  44591. + struct bfq_queue *in_service_queue;
  44592. + struct bfq_io_cq *in_service_bic;
  44593. +
  44594. + sector_t last_position;
  44595. +
  44596. + ktime_t last_budget_start;
  44597. + ktime_t last_idling_start;
  44598. + int peak_rate_samples;
  44599. + u64 peak_rate;
  44600. + unsigned long bfq_max_budget;
  44601. +
  44602. + struct hlist_head group_list;
  44603. + struct list_head active_list;
  44604. + struct list_head idle_list;
  44605. +
  44606. + unsigned int bfq_quantum;
  44607. + unsigned int bfq_fifo_expire[2];
  44608. + unsigned int bfq_back_penalty;
  44609. + unsigned int bfq_back_max;
  44610. + unsigned int bfq_slice_idle;
  44611. + u64 bfq_class_idle_last_service;
  44612. +
  44613. + unsigned int bfq_user_max_budget;
  44614. + unsigned int bfq_max_budget_async_rq;
  44615. + unsigned int bfq_timeout[2];
  44616. +
  44617. + unsigned int bfq_coop_thresh;
  44618. + unsigned int bfq_failed_cooperations;
  44619. + unsigned int bfq_requests_within_timer;
  44620. +
  44621. + bool low_latency;
  44622. +
  44623. + /* parameters of the low_latency heuristics */
  44624. + unsigned int bfq_wr_coeff;
  44625. + unsigned int bfq_wr_max_time;
  44626. + unsigned int bfq_wr_rt_max_time;
  44627. + unsigned int bfq_wr_min_idle_time;
  44628. + unsigned long bfq_wr_min_inter_arr_async;
  44629. + unsigned int bfq_wr_max_softrt_rate;
  44630. + u64 RT_prod;
  44631. + enum bfq_device_speed device_speed;
  44632. +
  44633. + struct bfq_queue oom_bfqq;
  44634. +};
  44635. +
  44636. +enum bfqq_state_flags {
  44637. + BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */
  44638. + BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */
  44639. + BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */
  44640. + BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */
  44641. + BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */
  44642. + BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */
  44643. + BFQ_BFQQ_FLAG_sync, /* synchronous queue */
  44644. + BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */
  44645. + BFQ_BFQQ_FLAG_IO_bound, /*
  44646. + * bfqq has timed-out at least once
  44647. + * having consumed at most 2/10 of
  44648. + * its budget
  44649. + */
  44650. + BFQ_BFQQ_FLAG_constantly_seeky, /*
  44651. + * bfqq has proved to be slow and
  44652. + * seeky until budget timeout
  44653. + */
  44654. + BFQ_BFQQ_FLAG_softrt_update, /*
  44655. + * may need softrt-next-start
  44656. + * update
  44657. + */
  44658. + BFQ_BFQQ_FLAG_coop, /* bfqq is shared */
  44659. + BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be split */
  44660. + BFQ_BFQQ_FLAG_just_split, /* queue has just been split */
  44661. +};
  44662. +
  44663. +#define BFQ_BFQQ_FNS(name) \
  44664. +static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \
  44665. +{ \
  44666. + (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \
  44667. +} \
  44668. +static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \
  44669. +{ \
  44670. + (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \
  44671. +} \
  44672. +static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \
  44673. +{ \
  44674. + return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \
  44675. +}
  44676. +
  44677. +BFQ_BFQQ_FNS(busy);
  44678. +BFQ_BFQQ_FNS(wait_request);
  44679. +BFQ_BFQQ_FNS(must_alloc);
  44680. +BFQ_BFQQ_FNS(fifo_expire);
  44681. +BFQ_BFQQ_FNS(idle_window);
  44682. +BFQ_BFQQ_FNS(prio_changed);
  44683. +BFQ_BFQQ_FNS(sync);
  44684. +BFQ_BFQQ_FNS(budget_new);
  44685. +BFQ_BFQQ_FNS(IO_bound);
  44686. +BFQ_BFQQ_FNS(constantly_seeky);
  44687. +BFQ_BFQQ_FNS(coop);
  44688. +BFQ_BFQQ_FNS(split_coop);
  44689. +BFQ_BFQQ_FNS(just_split);
  44690. +BFQ_BFQQ_FNS(softrt_update);
  44691. +#undef BFQ_BFQQ_FNS
  44692. +
  44693. +/* Logging facilities. */
  44694. +#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \
  44695. + blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args)
  44696. +
  44697. +#define bfq_log(bfqd, fmt, args...) \
  44698. + blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args)
  44699. +
  44700. +/* Expiration reasons. */
  44701. +enum bfqq_expiration {
  44702. + BFQ_BFQQ_TOO_IDLE = 0, /*
  44703. + * queue has been idling for
  44704. + * too long
  44705. + */
  44706. + BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */
  44707. + BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */
  44708. + BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */
  44709. +};
  44710. +
  44711. +#ifdef CONFIG_CGROUP_BFQIO
  44712. +/**
  44713. + * struct bfq_group - per (device, cgroup) data structure.
  44714. + * @entity: schedulable entity to insert into the parent group sched_data.
  44715. + * @sched_data: own sched_data, to contain child entities (they may be
  44716. + * both bfq_queues and bfq_groups).
  44717. + * @group_node: node to be inserted into the bfqio_cgroup->group_data
  44718. + * list of the containing cgroup's bfqio_cgroup.
  44719. + * @bfqd_node: node to be inserted into the @bfqd->group_list list
  44720. + * of the groups active on the same device; used for cleanup.
  44721. + * @bfqd: the bfq_data for the device this group acts upon.
  44722. + * @async_bfqq: array of async queues for all the tasks belonging to
  44723. + * the group, one queue per ioprio value per ioprio_class,
  44724. + * except for the idle class that has only one queue.
  44725. + * @async_idle_bfqq: async queue for the idle class (ioprio is ignored).
  44726. + * @my_entity: pointer to @entity, %NULL for the toplevel group; used
  44727. + * to avoid too many special cases during group creation/
  44728. + * migration.
  44729. + * @active_entities: number of active entities belonging to the group;
  44730. + * unused for the root group. Used to know whether there
  44731. + * are groups with more than one active @bfq_entity
  44732. + * (see the comments to the function
  44733. + * bfq_bfqq_must_not_expire()).
  44734. + *
  44735. + * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup
  44736. + * there is a set of bfq_groups, each one collecting the lower-level
  44737. + * entities belonging to the group that are acting on the same device.
  44738. + *
  44739. + * Locking works as follows:
  44740. + * o @group_node is protected by the bfqio_cgroup lock, and is accessed
  44741. + * via RCU from its readers.
  44742. + * o @bfqd is protected by the queue lock, RCU is used to access it
  44743. + * from the readers.
  44744. + * o All the other fields are protected by the @bfqd queue lock.
  44745. + */
  44746. +struct bfq_group {
  44747. + struct bfq_entity entity;
  44748. + struct bfq_sched_data sched_data;
  44749. +
  44750. + struct hlist_node group_node;
  44751. + struct hlist_node bfqd_node;
  44752. +
  44753. + void *bfqd;
  44754. +
  44755. + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
  44756. + struct bfq_queue *async_idle_bfqq;
  44757. +
  44758. + struct bfq_entity *my_entity;
  44759. +
  44760. + int active_entities;
  44761. +};
  44762. +
  44763. +/**
  44764. + * struct bfqio_cgroup - bfq cgroup data structure.
  44765. + * @css: subsystem state for bfq in the containing cgroup.
  44766. + * @online: flag marked when the subsystem is inserted.
  44767. + * @weight: cgroup weight.
  44768. + * @ioprio: cgroup ioprio.
  44769. + * @ioprio_class: cgroup ioprio_class.
  44770. + * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data.
  44771. + * @group_data: list containing the bfq_group belonging to this cgroup.
  44772. + *
  44773. + * @group_data is accessed using RCU, with @lock protecting the updates,
  44774. + * @ioprio and @ioprio_class are protected by @lock.
  44775. + */
  44776. +struct bfqio_cgroup {
  44777. + struct cgroup_subsys_state css;
  44778. + bool online;
  44779. +
  44780. + unsigned short weight, ioprio, ioprio_class;
  44781. +
  44782. + spinlock_t lock;
  44783. + struct hlist_head group_data;
  44784. +};
  44785. +#else
  44786. +struct bfq_group {
  44787. + struct bfq_sched_data sched_data;
  44788. +
  44789. + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
  44790. + struct bfq_queue *async_idle_bfqq;
  44791. +};
  44792. +#endif
  44793. +
  44794. +static inline struct bfq_service_tree *
  44795. +bfq_entity_service_tree(struct bfq_entity *entity)
  44796. +{
  44797. + struct bfq_sched_data *sched_data = entity->sched_data;
  44798. + unsigned int idx = entity->ioprio_class - 1;
  44799. +
  44800. + BUG_ON(idx >= BFQ_IOPRIO_CLASSES);
  44801. + BUG_ON(sched_data == NULL);
  44802. +
  44803. + return sched_data->service_tree + idx;
  44804. +}
  44805. +
  44806. +static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic,
  44807. + int is_sync)
  44808. +{
  44809. + return bic->bfqq[!!is_sync];
  44810. +}
  44811. +
  44812. +static inline void bic_set_bfqq(struct bfq_io_cq *bic,
  44813. + struct bfq_queue *bfqq, int is_sync)
  44814. +{
  44815. + bic->bfqq[!!is_sync] = bfqq;
  44816. +}
  44817. +
  44818. +static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic)
  44819. +{
  44820. + return bic->icq.q->elevator->elevator_data;
  44821. +}
  44822. +
  44823. +/**
  44824. + * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer.
  44825. + * @ptr: a pointer to a bfqd.
  44826. + * @flags: storage for the flags to be saved.
  44827. + *
  44828. + * This function allows bfqg->bfqd to be protected by the
  44829. + * queue lock of the bfqd they reference; the pointer is dereferenced
  44830. + * under RCU, so the storage for bfqd is assured to be safe as long
  44831. + * as the RCU read side critical section does not end. After the
  44832. + * bfqd->queue->queue_lock is taken the pointer is rechecked, to be
  44833. + * sure that no other writer accessed it. If we raced with a writer,
  44834. + * the function returns NULL, with the queue unlocked, otherwise it
  44835. + * returns the dereferenced pointer, with the queue locked.
  44836. + */
  44837. +static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr,
  44838. + unsigned long *flags)
  44839. +{
  44840. + struct bfq_data *bfqd;
  44841. +
  44842. + rcu_read_lock();
  44843. + bfqd = rcu_dereference(*(struct bfq_data **)ptr);
  44844. +
  44845. + if (bfqd != NULL) {
  44846. + spin_lock_irqsave(bfqd->queue->queue_lock, *flags);
  44847. + if (*ptr == bfqd)
  44848. + goto out;
  44849. + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
  44850. + }
  44851. +
  44852. + bfqd = NULL;
  44853. +out:
  44854. + rcu_read_unlock();
  44855. + return bfqd;
  44856. +}
  44857. +
  44858. +static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd,
  44859. + unsigned long *flags)
  44860. +{
  44861. + spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
  44862. +}
  44863. +
  44864. +static void bfq_changed_ioprio(struct bfq_io_cq *bic);
  44865. +static void bfq_put_queue(struct bfq_queue *bfqq);
  44866. +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq);
  44867. +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
  44868. + struct bfq_group *bfqg, int is_sync,
  44869. + struct bfq_io_cq *bic, gfp_t gfp_mask);
  44870. +static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
  44871. + struct bfq_group *bfqg);
  44872. +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
  44873. +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
  44874. +
  44875. +#endif /* _BFQ_H */
  44876. diff -Nur linux-3.14.17/block/bfq-ioc.c linux-imx6-3.14/block/bfq-ioc.c
  44877. --- linux-3.14.17/block/bfq-ioc.c 1970-01-01 01:00:00.000000000 +0100
  44878. +++ linux-imx6-3.14/block/bfq-ioc.c 2014-09-11 18:05:59.118026454 +0200
  44879. @@ -0,0 +1,36 @@
  44880. +/*
  44881. + * BFQ: I/O context handling.
  44882. + *
  44883. + * Based on ideas and code from CFQ:
  44884. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  44885. + *
  44886. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  44887. + * Paolo Valente <paolo.valente@unimore.it>
  44888. + *
  44889. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  44890. + */
  44891. +
  44892. +/**
  44893. + * icq_to_bic - convert iocontext queue structure to bfq_io_cq.
  44894. + * @icq: the iocontext queue.
  44895. + */
  44896. +static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq)
  44897. +{
  44898. + /* bic->icq is the first member, %NULL will convert to %NULL */
  44899. + return container_of(icq, struct bfq_io_cq, icq);
  44900. +}
  44901. +
  44902. +/**
  44903. + * bfq_bic_lookup - search into @ioc a bic associated to @bfqd.
  44904. + * @bfqd: the lookup key.
  44905. + * @ioc: the io_context of the process doing I/O.
  44906. + *
  44907. + * Queue lock must be held.
  44908. + */
  44909. +static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd,
  44910. + struct io_context *ioc)
  44911. +{
  44912. + if (ioc)
  44913. + return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue));
  44914. + return NULL;
  44915. +}
  44916. diff -Nur linux-3.14.17/block/bfq-iosched.c linux-imx6-3.14/block/bfq-iosched.c
  44917. --- linux-3.14.17/block/bfq-iosched.c 1970-01-01 01:00:00.000000000 +0100
  44918. +++ linux-imx6-3.14/block/bfq-iosched.c 2014-09-11 18:05:59.118026454 +0200
  44919. @@ -0,0 +1,3919 @@
  44920. +/*
  44921. + * Budget Fair Queueing (BFQ) disk scheduler.
  44922. + *
  44923. + * Based on ideas and code from CFQ:
  44924. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  44925. + *
  44926. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  44927. + * Paolo Valente <paolo.valente@unimore.it>
  44928. + *
  44929. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  44930. + *
  44931. + * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
  44932. + * file.
  44933. + *
  44934. + * BFQ is a proportional-share storage-I/O scheduling algorithm based on
  44935. + * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets,
  44936. + * measured in number of sectors, to processes instead of time slices. The
  44937. + * device is not granted to the in-service process for a given time slice,
  44938. + * but until it has exhausted its assigned budget. This change from the time
  44939. + * to the service domain allows BFQ to distribute the device throughput
  44940. + * among processes as desired, without any distortion due to ZBR, workload
  44941. + * fluctuations or other factors. BFQ uses an ad hoc internal scheduler,
  44942. + * called B-WF2Q+, to schedule processes according to their budgets. More
  44943. + * precisely, BFQ schedules queues associated to processes. Thanks to the
  44944. + * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to
  44945. + * I/O-bound processes issuing sequential requests (to boost the
  44946. + * throughput), and yet guarantee a low latency to interactive and soft
  44947. + * real-time applications.
  44948. + *
  44949. + * BFQ is described in [1], where also a reference to the initial, more
  44950. + * theoretical paper on BFQ can be found. The interested reader can find
  44951. + * in the latter paper full details on the main algorithm, as well as
  44952. + * formulas of the guarantees and formal proofs of all the properties.
  44953. + * With respect to the version of BFQ presented in these papers, this
  44954. + * implementation adds a few more heuristics, such as the one that
  44955. + * guarantees a low latency to soft real-time applications, and a
  44956. + * hierarchical extension based on H-WF2Q+.
  44957. + *
  44958. + * B-WF2Q+ is based on WF2Q+, that is described in [2], together with
  44959. + * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N)
  44960. + * complexity derives from the one introduced with EEVDF in [3].
  44961. + *
  44962. + * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness
  44963. + * with the BFQ Disk I/O Scheduler'',
  44964. + * Proceedings of the 5th Annual International Systems and Storage
  44965. + * Conference (SYSTOR '12), June 2012.
  44966. + *
  44967. + * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf
  44968. + *
  44969. + * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing
  44970. + * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689,
  44971. + * Oct 1997.
  44972. + *
  44973. + * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz
  44974. + *
  44975. + * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline
  44976. + * First: A Flexible and Accurate Mechanism for Proportional Share
  44977. + * Resource Allocation,'' technical report.
  44978. + *
  44979. + * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf
  44980. + */
  44981. +#include <linux/module.h>
  44982. +#include <linux/slab.h>
  44983. +#include <linux/blkdev.h>
  44984. +#include <linux/cgroup.h>
  44985. +#include <linux/elevator.h>
  44986. +#include <linux/jiffies.h>
  44987. +#include <linux/rbtree.h>
  44988. +#include <linux/ioprio.h>
  44989. +#include "bfq.h"
  44990. +#include "blk.h"
  44991. +
  44992. +/* Max number of dispatches in one round of service. */
  44993. +static const int bfq_quantum = 4;
  44994. +
  44995. +/* Expiration time of sync (0) and async (1) requests, in jiffies. */
  44996. +static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
  44997. +
  44998. +/* Maximum backwards seek, in KiB. */
  44999. +static const int bfq_back_max = 16 * 1024;
  45000. +
  45001. +/* Penalty of a backwards seek, in number of sectors. */
  45002. +static const int bfq_back_penalty = 2;
  45003. +
  45004. +/* Idling period duration, in jiffies. */
  45005. +static int bfq_slice_idle = HZ / 125;
  45006. +
  45007. +/* Default maximum budget values, in sectors and number of requests. */
  45008. +static const int bfq_default_max_budget = 16 * 1024;
  45009. +static const int bfq_max_budget_async_rq = 4;
  45010. +
  45011. +/*
  45012. + * Async to sync throughput distribution is controlled as follows:
  45013. + * when an async request is served, the entity is charged the number
  45014. + * of sectors of the request, multiplied by the factor below
  45015. + */
  45016. +static const int bfq_async_charge_factor = 10;
  45017. +
  45018. +/* Default timeout values, in jiffies, approximating CFQ defaults. */
  45019. +static const int bfq_timeout_sync = HZ / 8;
  45020. +static int bfq_timeout_async = HZ / 25;
  45021. +
  45022. +struct kmem_cache *bfq_pool;
  45023. +
  45024. +/* Below this threshold (in ms), we consider thinktime immediate. */
  45025. +#define BFQ_MIN_TT 2
  45026. +
  45027. +/* hw_tag detection: parallel requests threshold and min samples needed. */
  45028. +#define BFQ_HW_QUEUE_THRESHOLD 4
  45029. +#define BFQ_HW_QUEUE_SAMPLES 32
  45030. +
  45031. +#define BFQQ_SEEK_THR (sector_t)(8 * 1024)
  45032. +#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR)
  45033. +
  45034. +/* Min samples used for peak rate estimation (for autotuning). */
  45035. +#define BFQ_PEAK_RATE_SAMPLES 32
  45036. +
  45037. +/* Shift used for peak rate fixed precision calculations. */
  45038. +#define BFQ_RATE_SHIFT 16
  45039. +
  45040. +/*
  45041. + * By default, BFQ computes the duration of the weight raising for
  45042. + * interactive applications automatically, using the following formula:
  45043. + * duration = (R / r) * T, where r is the peak rate of the device, and
  45044. + * R and T are two reference parameters.
  45045. + * In particular, R is the peak rate of the reference device (see below),
  45046. + * and T is a reference time: given the systems that are likely to be
  45047. + * installed on the reference device according to its speed class, T is
  45048. + * about the maximum time needed, under BFQ and while reading two files in
  45049. + * parallel, to load typical large applications on these systems.
  45050. + * In practice, the slower/faster the device at hand is, the more/less it
  45051. + * takes to load applications with respect to the reference device.
  45052. + * Accordingly, the longer/shorter BFQ grants weight raising to interactive
  45053. + * applications.
  45054. + *
  45055. + * BFQ uses four different reference pairs (R, T), depending on:
  45056. + * . whether the device is rotational or non-rotational;
  45057. + * . whether the device is slow, such as old or portable HDDs, as well as
  45058. + * SD cards, or fast, such as newer HDDs and SSDs.
  45059. + *
  45060. + * The device's speed class is dynamically (re)detected in
  45061. + * bfq_update_peak_rate() every time the estimated peak rate is updated.
  45062. + *
  45063. + * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0]
  45064. + * are the reference values for a slow/fast rotational device, whereas
  45065. + * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for
  45066. + * a slow/fast non-rotational device. Finally, device_speed_thresh are the
  45067. + * thresholds used to switch between speed classes.
  45068. + * Both the reference peak rates and the thresholds are measured in
  45069. + * sectors/usec, left-shifted by BFQ_RATE_SHIFT.
  45070. + */
  45071. +static int R_slow[2] = {1536, 10752};
  45072. +static int R_fast[2] = {17415, 34791};
  45073. +/*
  45074. + * To improve readability, a conversion function is used to initialize the
  45075. + * following arrays, which entails that they can be initialized only in a
  45076. + * function.
  45077. + */
  45078. +static int T_slow[2];
  45079. +static int T_fast[2];
  45080. +static int device_speed_thresh[2];
  45081. +
  45082. +#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \
  45083. + { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 })
  45084. +
  45085. +#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0])
  45086. +#define RQ_BFQQ(rq) ((rq)->elv.priv[1])
  45087. +
  45088. +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd);
  45089. +
  45090. +#include "bfq-ioc.c"
  45091. +#include "bfq-sched.c"
  45092. +#include "bfq-cgroup.c"
  45093. +
  45094. +#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\
  45095. + IOPRIO_CLASS_IDLE)
  45096. +#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\
  45097. + IOPRIO_CLASS_RT)
  45098. +
  45099. +#define bfq_sample_valid(samples) ((samples) > 80)
  45100. +
  45101. +/*
  45102. + * We regard a request as SYNC, if either it's a read or has the SYNC bit
  45103. + * set (in which case it could also be a direct WRITE).
  45104. + */
  45105. +static inline int bfq_bio_sync(struct bio *bio)
  45106. +{
  45107. + if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC))
  45108. + return 1;
  45109. +
  45110. + return 0;
  45111. +}
  45112. +
  45113. +/*
  45114. + * Scheduler run of queue, if there are requests pending and no one in the
  45115. + * driver that will restart queueing.
  45116. + */
  45117. +static inline void bfq_schedule_dispatch(struct bfq_data *bfqd)
  45118. +{
  45119. + if (bfqd->queued != 0) {
  45120. + bfq_log(bfqd, "schedule dispatch");
  45121. + kblockd_schedule_work(bfqd->queue, &bfqd->unplug_work);
  45122. + }
  45123. +}
  45124. +
  45125. +/*
  45126. + * Lifted from AS - choose which of rq1 and rq2 that is best served now.
  45127. + * We choose the request that is closesr to the head right now. Distance
  45128. + * behind the head is penalized and only allowed to a certain extent.
  45129. + */
  45130. +static struct request *bfq_choose_req(struct bfq_data *bfqd,
  45131. + struct request *rq1,
  45132. + struct request *rq2,
  45133. + sector_t last)
  45134. +{
  45135. + sector_t s1, s2, d1 = 0, d2 = 0;
  45136. + unsigned long back_max;
  45137. +#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */
  45138. +#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */
  45139. + unsigned wrap = 0; /* bit mask: requests behind the disk head? */
  45140. +
  45141. + if (rq1 == NULL || rq1 == rq2)
  45142. + return rq2;
  45143. + if (rq2 == NULL)
  45144. + return rq1;
  45145. +
  45146. + if (rq_is_sync(rq1) && !rq_is_sync(rq2))
  45147. + return rq1;
  45148. + else if (rq_is_sync(rq2) && !rq_is_sync(rq1))
  45149. + return rq2;
  45150. + if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META))
  45151. + return rq1;
  45152. + else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META))
  45153. + return rq2;
  45154. +
  45155. + s1 = blk_rq_pos(rq1);
  45156. + s2 = blk_rq_pos(rq2);
  45157. +
  45158. + /*
  45159. + * By definition, 1KiB is 2 sectors.
  45160. + */
  45161. + back_max = bfqd->bfq_back_max * 2;
  45162. +
  45163. + /*
  45164. + * Strict one way elevator _except_ in the case where we allow
  45165. + * short backward seeks which are biased as twice the cost of a
  45166. + * similar forward seek.
  45167. + */
  45168. + if (s1 >= last)
  45169. + d1 = s1 - last;
  45170. + else if (s1 + back_max >= last)
  45171. + d1 = (last - s1) * bfqd->bfq_back_penalty;
  45172. + else
  45173. + wrap |= BFQ_RQ1_WRAP;
  45174. +
  45175. + if (s2 >= last)
  45176. + d2 = s2 - last;
  45177. + else if (s2 + back_max >= last)
  45178. + d2 = (last - s2) * bfqd->bfq_back_penalty;
  45179. + else
  45180. + wrap |= BFQ_RQ2_WRAP;
  45181. +
  45182. + /* Found required data */
  45183. +
  45184. + /*
  45185. + * By doing switch() on the bit mask "wrap" we avoid having to
  45186. + * check two variables for all permutations: --> faster!
  45187. + */
  45188. + switch (wrap) {
  45189. + case 0: /* common case for CFQ: rq1 and rq2 not wrapped */
  45190. + if (d1 < d2)
  45191. + return rq1;
  45192. + else if (d2 < d1)
  45193. + return rq2;
  45194. + else {
  45195. + if (s1 >= s2)
  45196. + return rq1;
  45197. + else
  45198. + return rq2;
  45199. + }
  45200. +
  45201. + case BFQ_RQ2_WRAP:
  45202. + return rq1;
  45203. + case BFQ_RQ1_WRAP:
  45204. + return rq2;
  45205. + case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */
  45206. + default:
  45207. + /*
  45208. + * Since both rqs are wrapped,
  45209. + * start with the one that's further behind head
  45210. + * (--> only *one* back seek required),
  45211. + * since back seek takes more time than forward.
  45212. + */
  45213. + if (s1 <= s2)
  45214. + return rq1;
  45215. + else
  45216. + return rq2;
  45217. + }
  45218. +}
  45219. +
  45220. +static struct bfq_queue *
  45221. +bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root,
  45222. + sector_t sector, struct rb_node **ret_parent,
  45223. + struct rb_node ***rb_link)
  45224. +{
  45225. + struct rb_node **p, *parent;
  45226. + struct bfq_queue *bfqq = NULL;
  45227. +
  45228. + parent = NULL;
  45229. + p = &root->rb_node;
  45230. + while (*p) {
  45231. + struct rb_node **n;
  45232. +
  45233. + parent = *p;
  45234. + bfqq = rb_entry(parent, struct bfq_queue, pos_node);
  45235. +
  45236. + /*
  45237. + * Sort strictly based on sector. Smallest to the left,
  45238. + * largest to the right.
  45239. + */
  45240. + if (sector > blk_rq_pos(bfqq->next_rq))
  45241. + n = &(*p)->rb_right;
  45242. + else if (sector < blk_rq_pos(bfqq->next_rq))
  45243. + n = &(*p)->rb_left;
  45244. + else
  45245. + break;
  45246. + p = n;
  45247. + bfqq = NULL;
  45248. + }
  45249. +
  45250. + *ret_parent = parent;
  45251. + if (rb_link)
  45252. + *rb_link = p;
  45253. +
  45254. + bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d",
  45255. + (long long unsigned)sector,
  45256. + bfqq != NULL ? bfqq->pid : 0);
  45257. +
  45258. + return bfqq;
  45259. +}
  45260. +
  45261. +static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  45262. +{
  45263. + struct rb_node **p, *parent;
  45264. + struct bfq_queue *__bfqq;
  45265. +
  45266. + if (bfqq->pos_root != NULL) {
  45267. + rb_erase(&bfqq->pos_node, bfqq->pos_root);
  45268. + bfqq->pos_root = NULL;
  45269. + }
  45270. +
  45271. + if (bfq_class_idle(bfqq))
  45272. + return;
  45273. + if (!bfqq->next_rq)
  45274. + return;
  45275. +
  45276. + bfqq->pos_root = &bfqd->rq_pos_tree;
  45277. + __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root,
  45278. + blk_rq_pos(bfqq->next_rq), &parent, &p);
  45279. + if (__bfqq == NULL) {
  45280. + rb_link_node(&bfqq->pos_node, parent, p);
  45281. + rb_insert_color(&bfqq->pos_node, bfqq->pos_root);
  45282. + } else
  45283. + bfqq->pos_root = NULL;
  45284. +}
  45285. +
  45286. +/*
  45287. + * Tell whether there are active queues or groups with differentiated weights.
  45288. + */
  45289. +static inline bool bfq_differentiated_weights(struct bfq_data *bfqd)
  45290. +{
  45291. + BUG_ON(!bfqd->hw_tag);
  45292. + /*
  45293. + * For weights to differ, at least one of the trees must contain
  45294. + * at least two nodes.
  45295. + */
  45296. + return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) &&
  45297. + (bfqd->queue_weights_tree.rb_node->rb_left ||
  45298. + bfqd->queue_weights_tree.rb_node->rb_right)
  45299. +#ifdef CONFIG_CGROUP_BFQIO
  45300. + ) ||
  45301. + (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) &&
  45302. + (bfqd->group_weights_tree.rb_node->rb_left ||
  45303. + bfqd->group_weights_tree.rb_node->rb_right)
  45304. +#endif
  45305. + );
  45306. +}
  45307. +
  45308. +/*
  45309. + * If the weight-counter tree passed as input contains no counter for
  45310. + * the weight of the input entity, then add that counter; otherwise just
  45311. + * increment the existing counter.
  45312. + *
  45313. + * Note that weight-counter trees contain few nodes in mostly symmetric
  45314. + * scenarios. For example, if all queues have the same weight, then the
  45315. + * weight-counter tree for the queues may contain at most one node.
  45316. + * This holds even if low_latency is on, because weight-raised queues
  45317. + * are not inserted in the tree.
  45318. + * In most scenarios, the rate at which nodes are created/destroyed
  45319. + * should be low too.
  45320. + */
  45321. +static void bfq_weights_tree_add(struct bfq_data *bfqd,
  45322. + struct bfq_entity *entity,
  45323. + struct rb_root *root)
  45324. +{
  45325. + struct rb_node **new = &(root->rb_node), *parent = NULL;
  45326. +
  45327. + /*
  45328. + * Do not insert if:
  45329. + * - the device does not support queueing;
  45330. + * - the entity is already associated with a counter, which happens if:
  45331. + * 1) the entity is associated with a queue, 2) a request arrival
  45332. + * has caused the queue to become both non-weight-raised, and hence
  45333. + * change its weight, and backlogged; in this respect, each
  45334. + * of the two events causes an invocation of this function,
  45335. + * 3) this is the invocation of this function caused by the second
  45336. + * event. This second invocation is actually useless, and we handle
  45337. + * this fact by exiting immediately. More efficient or clearer
  45338. + * solutions might possibly be adopted.
  45339. + */
  45340. + if (!bfqd->hw_tag || entity->weight_counter)
  45341. + return;
  45342. +
  45343. + while (*new) {
  45344. + struct bfq_weight_counter *__counter = container_of(*new,
  45345. + struct bfq_weight_counter,
  45346. + weights_node);
  45347. + parent = *new;
  45348. +
  45349. + if (entity->weight == __counter->weight) {
  45350. + entity->weight_counter = __counter;
  45351. + goto inc_counter;
  45352. + }
  45353. + if (entity->weight < __counter->weight)
  45354. + new = &((*new)->rb_left);
  45355. + else
  45356. + new = &((*new)->rb_right);
  45357. + }
  45358. +
  45359. + entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
  45360. + GFP_ATOMIC);
  45361. + entity->weight_counter->weight = entity->weight;
  45362. + rb_link_node(&entity->weight_counter->weights_node, parent, new);
  45363. + rb_insert_color(&entity->weight_counter->weights_node, root);
  45364. +
  45365. +inc_counter:
  45366. + entity->weight_counter->num_active++;
  45367. +}
  45368. +
  45369. +/*
  45370. + * Decrement the weight counter associated with the entity, and, if the
  45371. + * counter reaches 0, remove the counter from the tree.
  45372. + * See the comments to the function bfq_weights_tree_add() for considerations
  45373. + * about overhead.
  45374. + */
  45375. +static void bfq_weights_tree_remove(struct bfq_data *bfqd,
  45376. + struct bfq_entity *entity,
  45377. + struct rb_root *root)
  45378. +{
  45379. + /*
  45380. + * Check whether the entity is actually associated with a counter.
  45381. + * In fact, the device may not be considered NCQ-capable for a while,
  45382. + * which implies that no insertion in the weight trees is performed,
  45383. + * after which the device may start to be deemed NCQ-capable, and hence
  45384. + * this function may start to be invoked. This may cause the function
  45385. + * to be invoked for entities that are not associated with any counter.
  45386. + */
  45387. + if (!entity->weight_counter)
  45388. + return;
  45389. +
  45390. + BUG_ON(RB_EMPTY_ROOT(root));
  45391. + BUG_ON(entity->weight_counter->weight != entity->weight);
  45392. +
  45393. + BUG_ON(!entity->weight_counter->num_active);
  45394. + entity->weight_counter->num_active--;
  45395. + if (entity->weight_counter->num_active > 0)
  45396. + goto reset_entity_pointer;
  45397. +
  45398. + rb_erase(&entity->weight_counter->weights_node, root);
  45399. + kfree(entity->weight_counter);
  45400. +
  45401. +reset_entity_pointer:
  45402. + entity->weight_counter = NULL;
  45403. +}
  45404. +
  45405. +static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
  45406. + struct bfq_queue *bfqq,
  45407. + struct request *last)
  45408. +{
  45409. + struct rb_node *rbnext = rb_next(&last->rb_node);
  45410. + struct rb_node *rbprev = rb_prev(&last->rb_node);
  45411. + struct request *next = NULL, *prev = NULL;
  45412. +
  45413. + BUG_ON(RB_EMPTY_NODE(&last->rb_node));
  45414. +
  45415. + if (rbprev != NULL)
  45416. + prev = rb_entry_rq(rbprev);
  45417. +
  45418. + if (rbnext != NULL)
  45419. + next = rb_entry_rq(rbnext);
  45420. + else {
  45421. + rbnext = rb_first(&bfqq->sort_list);
  45422. + if (rbnext && rbnext != &last->rb_node)
  45423. + next = rb_entry_rq(rbnext);
  45424. + }
  45425. +
  45426. + return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last));
  45427. +}
  45428. +
  45429. +/* see the definition of bfq_async_charge_factor for details */
  45430. +static inline unsigned long bfq_serv_to_charge(struct request *rq,
  45431. + struct bfq_queue *bfqq)
  45432. +{
  45433. + return blk_rq_sectors(rq) *
  45434. + (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) *
  45435. + bfq_async_charge_factor));
  45436. +}
  45437. +
  45438. +/**
  45439. + * bfq_updated_next_req - update the queue after a new next_rq selection.
  45440. + * @bfqd: the device data the queue belongs to.
  45441. + * @bfqq: the queue to update.
  45442. + *
  45443. + * If the first request of a queue changes we make sure that the queue
  45444. + * has enough budget to serve at least its first request (if the
  45445. + * request has grown). We do this because if the queue has not enough
  45446. + * budget for its first request, it has to go through two dispatch
  45447. + * rounds to actually get it dispatched.
  45448. + */
  45449. +static void bfq_updated_next_req(struct bfq_data *bfqd,
  45450. + struct bfq_queue *bfqq)
  45451. +{
  45452. + struct bfq_entity *entity = &bfqq->entity;
  45453. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  45454. + struct request *next_rq = bfqq->next_rq;
  45455. + unsigned long new_budget;
  45456. +
  45457. + if (next_rq == NULL)
  45458. + return;
  45459. +
  45460. + if (bfqq == bfqd->in_service_queue)
  45461. + /*
  45462. + * In order not to break guarantees, budgets cannot be
  45463. + * changed after an entity has been selected.
  45464. + */
  45465. + return;
  45466. +
  45467. + BUG_ON(entity->tree != &st->active);
  45468. + BUG_ON(entity == entity->sched_data->in_service_entity);
  45469. +
  45470. + new_budget = max_t(unsigned long, bfqq->max_budget,
  45471. + bfq_serv_to_charge(next_rq, bfqq));
  45472. + if (entity->budget != new_budget) {
  45473. + entity->budget = new_budget;
  45474. + bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu",
  45475. + new_budget);
  45476. + bfq_activate_bfqq(bfqd, bfqq);
  45477. + }
  45478. +}
  45479. +
  45480. +static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd)
  45481. +{
  45482. + u64 dur;
  45483. +
  45484. + if (bfqd->bfq_wr_max_time > 0)
  45485. + return bfqd->bfq_wr_max_time;
  45486. +
  45487. + dur = bfqd->RT_prod;
  45488. + do_div(dur, bfqd->peak_rate);
  45489. +
  45490. + return dur;
  45491. +}
  45492. +
  45493. +static inline unsigned
  45494. +bfq_bfqq_cooperations(struct bfq_queue *bfqq)
  45495. +{
  45496. + return bfqq->bic ? bfqq->bic->cooperations : 0;
  45497. +}
  45498. +
  45499. +static inline void
  45500. +bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
  45501. +{
  45502. + if (bic->saved_idle_window)
  45503. + bfq_mark_bfqq_idle_window(bfqq);
  45504. + else
  45505. + bfq_clear_bfqq_idle_window(bfqq);
  45506. + if (bic->saved_IO_bound)
  45507. + bfq_mark_bfqq_IO_bound(bfqq);
  45508. + else
  45509. + bfq_clear_bfqq_IO_bound(bfqq);
  45510. + if (bic->wr_time_left && bfqq->bfqd->low_latency &&
  45511. + bic->cooperations < bfqq->bfqd->bfq_coop_thresh) {
  45512. + /*
  45513. + * Start a weight raising period with the duration given by
  45514. + * the raising_time_left snapshot.
  45515. + */
  45516. + if (bfq_bfqq_busy(bfqq))
  45517. + bfqq->bfqd->wr_busy_queues++;
  45518. + bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff;
  45519. + bfqq->wr_cur_max_time = bic->wr_time_left;
  45520. + bfqq->last_wr_start_finish = jiffies;
  45521. + bfqq->entity.ioprio_changed = 1;
  45522. + }
  45523. + /*
  45524. + * Clear wr_time_left to prevent bfq_bfqq_save_state() from
  45525. + * getting confused about the queue's need of a weight-raising
  45526. + * period.
  45527. + */
  45528. + bic->wr_time_left = 0;
  45529. +}
  45530. +
  45531. +/*
  45532. + * Must be called with the queue_lock held.
  45533. + */
  45534. +static int bfqq_process_refs(struct bfq_queue *bfqq)
  45535. +{
  45536. + int process_refs, io_refs;
  45537. +
  45538. + io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE];
  45539. + process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st;
  45540. + BUG_ON(process_refs < 0);
  45541. + return process_refs;
  45542. +}
  45543. +
  45544. +static void bfq_add_request(struct request *rq)
  45545. +{
  45546. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  45547. + struct bfq_entity *entity = &bfqq->entity;
  45548. + struct bfq_data *bfqd = bfqq->bfqd;
  45549. + struct request *next_rq, *prev;
  45550. + unsigned long old_wr_coeff = bfqq->wr_coeff;
  45551. + int idle_for_long_time = 0;
  45552. +
  45553. + bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq));
  45554. + bfqq->queued[rq_is_sync(rq)]++;
  45555. + bfqd->queued++;
  45556. +
  45557. + elv_rb_add(&bfqq->sort_list, rq);
  45558. +
  45559. + /*
  45560. + * Check if this request is a better next-serve candidate.
  45561. + */
  45562. + prev = bfqq->next_rq;
  45563. + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position);
  45564. + BUG_ON(next_rq == NULL);
  45565. + bfqq->next_rq = next_rq;
  45566. +
  45567. + /*
  45568. + * Adjust priority tree position, if next_rq changes.
  45569. + */
  45570. + if (prev != bfqq->next_rq)
  45571. + bfq_rq_pos_tree_add(bfqd, bfqq);
  45572. +
  45573. + if (!bfq_bfqq_busy(bfqq)) {
  45574. + int soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
  45575. + bfq_bfqq_cooperations(bfqq) < bfqd->bfq_coop_thresh &&
  45576. + time_is_before_jiffies(bfqq->soft_rt_next_start);
  45577. + idle_for_long_time = bfq_bfqq_cooperations(bfqq) <
  45578. + bfqd->bfq_coop_thresh &&
  45579. + time_is_before_jiffies(
  45580. + bfqq->budget_timeout +
  45581. + bfqd->bfq_wr_min_idle_time);
  45582. + entity->budget = max_t(unsigned long, bfqq->max_budget,
  45583. + bfq_serv_to_charge(next_rq, bfqq));
  45584. +
  45585. + if (!bfq_bfqq_IO_bound(bfqq)) {
  45586. + if (time_before(jiffies,
  45587. + RQ_BIC(rq)->ttime.last_end_request +
  45588. + bfqd->bfq_slice_idle)) {
  45589. + bfqq->requests_within_timer++;
  45590. + if (bfqq->requests_within_timer >=
  45591. + bfqd->bfq_requests_within_timer)
  45592. + bfq_mark_bfqq_IO_bound(bfqq);
  45593. + } else
  45594. + bfqq->requests_within_timer = 0;
  45595. + }
  45596. +
  45597. + if (!bfqd->low_latency)
  45598. + goto add_bfqq_busy;
  45599. +
  45600. + if (bfq_bfqq_just_split(bfqq))
  45601. + goto set_ioprio_changed;
  45602. +
  45603. + /*
  45604. + * If the queue:
  45605. + * - is not being boosted,
  45606. + * - has been idle for enough time,
  45607. + * - is not a sync queue or is linked to a bfq_io_cq (it is
  45608. + * shared "for its nature" or it is not shared and its
  45609. + * requests have not been redirected to a shared queue)
  45610. + * start a weight-raising period.
  45611. + */
  45612. + if (old_wr_coeff == 1 && (idle_for_long_time || soft_rt) &&
  45613. + (!bfq_bfqq_sync(bfqq) || bfqq->bic != NULL)) {
  45614. + bfqq->wr_coeff = bfqd->bfq_wr_coeff;
  45615. + if (idle_for_long_time)
  45616. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  45617. + else
  45618. + bfqq->wr_cur_max_time =
  45619. + bfqd->bfq_wr_rt_max_time;
  45620. + bfq_log_bfqq(bfqd, bfqq,
  45621. + "wrais starting at %lu, rais_max_time %u",
  45622. + jiffies,
  45623. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  45624. + } else if (old_wr_coeff > 1) {
  45625. + if (idle_for_long_time)
  45626. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  45627. + else if (bfq_bfqq_cooperations(bfqq) >=
  45628. + bfqd->bfq_coop_thresh ||
  45629. + (bfqq->wr_cur_max_time ==
  45630. + bfqd->bfq_wr_rt_max_time &&
  45631. + !soft_rt)) {
  45632. + bfqq->wr_coeff = 1;
  45633. + bfq_log_bfqq(bfqd, bfqq,
  45634. + "wrais ending at %lu, rais_max_time %u",
  45635. + jiffies,
  45636. + jiffies_to_msecs(bfqq->
  45637. + wr_cur_max_time));
  45638. + } else if (time_before(
  45639. + bfqq->last_wr_start_finish +
  45640. + bfqq->wr_cur_max_time,
  45641. + jiffies +
  45642. + bfqd->bfq_wr_rt_max_time) &&
  45643. + soft_rt) {
  45644. + /*
  45645. + *
  45646. + * The remaining weight-raising time is lower
  45647. + * than bfqd->bfq_wr_rt_max_time, which means
  45648. + * that the application is enjoying weight
  45649. + * raising either because deemed soft-rt in
  45650. + * the near past, or because deemed interactive
  45651. + * a long ago.
  45652. + * In both cases, resetting now the current
  45653. + * remaining weight-raising time for the
  45654. + * application to the weight-raising duration
  45655. + * for soft rt applications would not cause any
  45656. + * latency increase for the application (as the
  45657. + * new duration would be higher than the
  45658. + * remaining time).
  45659. + *
  45660. + * In addition, the application is now meeting
  45661. + * the requirements for being deemed soft rt.
  45662. + * In the end we can correctly and safely
  45663. + * (re)charge the weight-raising duration for
  45664. + * the application with the weight-raising
  45665. + * duration for soft rt applications.
  45666. + *
  45667. + * In particular, doing this recharge now, i.e.,
  45668. + * before the weight-raising period for the
  45669. + * application finishes, reduces the probability
  45670. + * of the following negative scenario:
  45671. + * 1) the weight of a soft rt application is
  45672. + * raised at startup (as for any newly
  45673. + * created application),
  45674. + * 2) since the application is not interactive,
  45675. + * at a certain time weight-raising is
  45676. + * stopped for the application,
  45677. + * 3) at that time the application happens to
  45678. + * still have pending requests, and hence
  45679. + * is destined to not have a chance to be
  45680. + * deemed soft rt before these requests are
  45681. + * completed (see the comments to the
  45682. + * function bfq_bfqq_softrt_next_start()
  45683. + * for details on soft rt detection),
  45684. + * 4) these pending requests experience a high
  45685. + * latency because the application is not
  45686. + * weight-raised while they are pending.
  45687. + */
  45688. + bfqq->last_wr_start_finish = jiffies;
  45689. + bfqq->wr_cur_max_time =
  45690. + bfqd->bfq_wr_rt_max_time;
  45691. + }
  45692. + }
  45693. +set_ioprio_changed:
  45694. + if (old_wr_coeff != bfqq->wr_coeff)
  45695. + entity->ioprio_changed = 1;
  45696. +add_bfqq_busy:
  45697. + bfqq->last_idle_bklogged = jiffies;
  45698. + bfqq->service_from_backlogged = 0;
  45699. + bfq_clear_bfqq_softrt_update(bfqq);
  45700. + bfq_add_bfqq_busy(bfqd, bfqq);
  45701. + } else {
  45702. + if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) &&
  45703. + time_is_before_jiffies(
  45704. + bfqq->last_wr_start_finish +
  45705. + bfqd->bfq_wr_min_inter_arr_async)) {
  45706. + bfqq->wr_coeff = bfqd->bfq_wr_coeff;
  45707. + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
  45708. +
  45709. + bfqd->wr_busy_queues++;
  45710. + entity->ioprio_changed = 1;
  45711. + bfq_log_bfqq(bfqd, bfqq,
  45712. + "non-idle wrais starting at %lu, rais_max_time %u",
  45713. + jiffies,
  45714. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  45715. + }
  45716. + if (prev != bfqq->next_rq)
  45717. + bfq_updated_next_req(bfqd, bfqq);
  45718. + }
  45719. +
  45720. + if (bfqd->low_latency &&
  45721. + (old_wr_coeff == 1 || bfqq->wr_coeff == 1 ||
  45722. + idle_for_long_time))
  45723. + bfqq->last_wr_start_finish = jiffies;
  45724. +}
  45725. +
  45726. +static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd,
  45727. + struct bio *bio)
  45728. +{
  45729. + struct task_struct *tsk = current;
  45730. + struct bfq_io_cq *bic;
  45731. + struct bfq_queue *bfqq;
  45732. +
  45733. + bic = bfq_bic_lookup(bfqd, tsk->io_context);
  45734. + if (bic == NULL)
  45735. + return NULL;
  45736. +
  45737. + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
  45738. + if (bfqq != NULL)
  45739. + return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio));
  45740. +
  45741. + return NULL;
  45742. +}
  45743. +
  45744. +static void bfq_activate_request(struct request_queue *q, struct request *rq)
  45745. +{
  45746. + struct bfq_data *bfqd = q->elevator->elevator_data;
  45747. +
  45748. + bfqd->rq_in_driver++;
  45749. + bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
  45750. + bfq_log(bfqd, "activate_request: new bfqd->last_position %llu",
  45751. + (long long unsigned)bfqd->last_position);
  45752. +}
  45753. +
  45754. +static inline void bfq_deactivate_request(struct request_queue *q,
  45755. + struct request *rq)
  45756. +{
  45757. + struct bfq_data *bfqd = q->elevator->elevator_data;
  45758. +
  45759. + BUG_ON(bfqd->rq_in_driver == 0);
  45760. + bfqd->rq_in_driver--;
  45761. +}
  45762. +
  45763. +static void bfq_remove_request(struct request *rq)
  45764. +{
  45765. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  45766. + struct bfq_data *bfqd = bfqq->bfqd;
  45767. + const int sync = rq_is_sync(rq);
  45768. +
  45769. + if (bfqq->next_rq == rq) {
  45770. + bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq);
  45771. + bfq_updated_next_req(bfqd, bfqq);
  45772. + }
  45773. +
  45774. + list_del_init(&rq->queuelist);
  45775. + BUG_ON(bfqq->queued[sync] == 0);
  45776. + bfqq->queued[sync]--;
  45777. + bfqd->queued--;
  45778. + elv_rb_del(&bfqq->sort_list, rq);
  45779. +
  45780. + if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
  45781. + if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue)
  45782. + bfq_del_bfqq_busy(bfqd, bfqq, 1);
  45783. + /*
  45784. + * Remove queue from request-position tree as it is empty.
  45785. + */
  45786. + if (bfqq->pos_root != NULL) {
  45787. + rb_erase(&bfqq->pos_node, bfqq->pos_root);
  45788. + bfqq->pos_root = NULL;
  45789. + }
  45790. + }
  45791. +
  45792. + if (rq->cmd_flags & REQ_META) {
  45793. + BUG_ON(bfqq->meta_pending == 0);
  45794. + bfqq->meta_pending--;
  45795. + }
  45796. +}
  45797. +
  45798. +static int bfq_merge(struct request_queue *q, struct request **req,
  45799. + struct bio *bio)
  45800. +{
  45801. + struct bfq_data *bfqd = q->elevator->elevator_data;
  45802. + struct request *__rq;
  45803. +
  45804. + __rq = bfq_find_rq_fmerge(bfqd, bio);
  45805. + if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) {
  45806. + *req = __rq;
  45807. + return ELEVATOR_FRONT_MERGE;
  45808. + }
  45809. +
  45810. + return ELEVATOR_NO_MERGE;
  45811. +}
  45812. +
  45813. +static void bfq_merged_request(struct request_queue *q, struct request *req,
  45814. + int type)
  45815. +{
  45816. + if (type == ELEVATOR_FRONT_MERGE &&
  45817. + rb_prev(&req->rb_node) &&
  45818. + blk_rq_pos(req) <
  45819. + blk_rq_pos(container_of(rb_prev(&req->rb_node),
  45820. + struct request, rb_node))) {
  45821. + struct bfq_queue *bfqq = RQ_BFQQ(req);
  45822. + struct bfq_data *bfqd = bfqq->bfqd;
  45823. + struct request *prev, *next_rq;
  45824. +
  45825. + /* Reposition request in its sort_list */
  45826. + elv_rb_del(&bfqq->sort_list, req);
  45827. + elv_rb_add(&bfqq->sort_list, req);
  45828. + /* Choose next request to be served for bfqq */
  45829. + prev = bfqq->next_rq;
  45830. + next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req,
  45831. + bfqd->last_position);
  45832. + BUG_ON(next_rq == NULL);
  45833. + bfqq->next_rq = next_rq;
  45834. + /*
  45835. + * If next_rq changes, update both the queue's budget to
  45836. + * fit the new request and the queue's position in its
  45837. + * rq_pos_tree.
  45838. + */
  45839. + if (prev != bfqq->next_rq) {
  45840. + bfq_updated_next_req(bfqd, bfqq);
  45841. + bfq_rq_pos_tree_add(bfqd, bfqq);
  45842. + }
  45843. + }
  45844. +}
  45845. +
  45846. +static void bfq_merged_requests(struct request_queue *q, struct request *rq,
  45847. + struct request *next)
  45848. +{
  45849. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  45850. +
  45851. + /*
  45852. + * Reposition in fifo if next is older than rq.
  45853. + */
  45854. + if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
  45855. + time_before(rq_fifo_time(next), rq_fifo_time(rq))) {
  45856. + list_move(&rq->queuelist, &next->queuelist);
  45857. + rq_set_fifo_time(rq, rq_fifo_time(next));
  45858. + }
  45859. +
  45860. + if (bfqq->next_rq == next)
  45861. + bfqq->next_rq = rq;
  45862. +
  45863. + bfq_remove_request(next);
  45864. +}
  45865. +
  45866. +/* Must be called with bfqq != NULL */
  45867. +static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq)
  45868. +{
  45869. + BUG_ON(bfqq == NULL);
  45870. + if (bfq_bfqq_busy(bfqq))
  45871. + bfqq->bfqd->wr_busy_queues--;
  45872. + bfqq->wr_coeff = 1;
  45873. + bfqq->wr_cur_max_time = 0;
  45874. + /* Trigger a weight change on the next activation of the queue */
  45875. + bfqq->entity.ioprio_changed = 1;
  45876. +}
  45877. +
  45878. +static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
  45879. + struct bfq_group *bfqg)
  45880. +{
  45881. + int i, j;
  45882. +
  45883. + for (i = 0; i < 2; i++)
  45884. + for (j = 0; j < IOPRIO_BE_NR; j++)
  45885. + if (bfqg->async_bfqq[i][j] != NULL)
  45886. + bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]);
  45887. + if (bfqg->async_idle_bfqq != NULL)
  45888. + bfq_bfqq_end_wr(bfqg->async_idle_bfqq);
  45889. +}
  45890. +
  45891. +static void bfq_end_wr(struct bfq_data *bfqd)
  45892. +{
  45893. + struct bfq_queue *bfqq;
  45894. +
  45895. + spin_lock_irq(bfqd->queue->queue_lock);
  45896. +
  45897. + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list)
  45898. + bfq_bfqq_end_wr(bfqq);
  45899. + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list)
  45900. + bfq_bfqq_end_wr(bfqq);
  45901. + bfq_end_wr_async(bfqd);
  45902. +
  45903. + spin_unlock_irq(bfqd->queue->queue_lock);
  45904. +}
  45905. +
  45906. +static inline sector_t bfq_io_struct_pos(void *io_struct, bool request)
  45907. +{
  45908. + if (request)
  45909. + return blk_rq_pos(io_struct);
  45910. + else
  45911. + return ((struct bio *)io_struct)->bi_iter.bi_sector;
  45912. +}
  45913. +
  45914. +static inline sector_t bfq_dist_from(sector_t pos1,
  45915. + sector_t pos2)
  45916. +{
  45917. + if (pos1 >= pos2)
  45918. + return pos1 - pos2;
  45919. + else
  45920. + return pos2 - pos1;
  45921. +}
  45922. +
  45923. +static inline int bfq_rq_close_to_sector(void *io_struct, bool request,
  45924. + sector_t sector)
  45925. +{
  45926. + return bfq_dist_from(bfq_io_struct_pos(io_struct, request), sector) <=
  45927. + BFQQ_SEEK_THR;
  45928. +}
  45929. +
  45930. +static struct bfq_queue *bfqq_close(struct bfq_data *bfqd, sector_t sector)
  45931. +{
  45932. + struct rb_root *root = &bfqd->rq_pos_tree;
  45933. + struct rb_node *parent, *node;
  45934. + struct bfq_queue *__bfqq;
  45935. +
  45936. + if (RB_EMPTY_ROOT(root))
  45937. + return NULL;
  45938. +
  45939. + /*
  45940. + * First, if we find a request starting at the end of the last
  45941. + * request, choose it.
  45942. + */
  45943. + __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL);
  45944. + if (__bfqq != NULL)
  45945. + return __bfqq;
  45946. +
  45947. + /*
  45948. + * If the exact sector wasn't found, the parent of the NULL leaf
  45949. + * will contain the closest sector (rq_pos_tree sorted by
  45950. + * next_request position).
  45951. + */
  45952. + __bfqq = rb_entry(parent, struct bfq_queue, pos_node);
  45953. + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
  45954. + return __bfqq;
  45955. +
  45956. + if (blk_rq_pos(__bfqq->next_rq) < sector)
  45957. + node = rb_next(&__bfqq->pos_node);
  45958. + else
  45959. + node = rb_prev(&__bfqq->pos_node);
  45960. + if (node == NULL)
  45961. + return NULL;
  45962. +
  45963. + __bfqq = rb_entry(node, struct bfq_queue, pos_node);
  45964. + if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
  45965. + return __bfqq;
  45966. +
  45967. + return NULL;
  45968. +}
  45969. +
  45970. +/*
  45971. + * bfqd - obvious
  45972. + * cur_bfqq - passed in so that we don't decide that the current queue
  45973. + * is closely cooperating with itself
  45974. + * sector - used as a reference point to search for a close queue
  45975. + */
  45976. +static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd,
  45977. + struct bfq_queue *cur_bfqq,
  45978. + sector_t sector)
  45979. +{
  45980. + struct bfq_queue *bfqq;
  45981. +
  45982. + if (bfq_class_idle(cur_bfqq))
  45983. + return NULL;
  45984. + if (!bfq_bfqq_sync(cur_bfqq))
  45985. + return NULL;
  45986. + if (BFQQ_SEEKY(cur_bfqq))
  45987. + return NULL;
  45988. +
  45989. + /* If device has only one backlogged bfq_queue, don't search. */
  45990. + if (bfqd->busy_queues == 1)
  45991. + return NULL;
  45992. +
  45993. + /*
  45994. + * We should notice if some of the queues are cooperating, e.g.
  45995. + * working closely on the same area of the disk. In that case,
  45996. + * we can group them together and don't waste time idling.
  45997. + */
  45998. + bfqq = bfqq_close(bfqd, sector);
  45999. + if (bfqq == NULL || bfqq == cur_bfqq)
  46000. + return NULL;
  46001. +
  46002. + /*
  46003. + * Do not merge queues from different bfq_groups.
  46004. + */
  46005. + if (bfqq->entity.parent != cur_bfqq->entity.parent)
  46006. + return NULL;
  46007. +
  46008. + /*
  46009. + * It only makes sense to merge sync queues.
  46010. + */
  46011. + if (!bfq_bfqq_sync(bfqq))
  46012. + return NULL;
  46013. + if (BFQQ_SEEKY(bfqq))
  46014. + return NULL;
  46015. +
  46016. + /*
  46017. + * Do not merge queues of different priority classes.
  46018. + */
  46019. + if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq))
  46020. + return NULL;
  46021. +
  46022. + return bfqq;
  46023. +}
  46024. +
  46025. +static struct bfq_queue *
  46026. +bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
  46027. +{
  46028. + int process_refs, new_process_refs;
  46029. + struct bfq_queue *__bfqq;
  46030. +
  46031. + /*
  46032. + * If there are no process references on the new_bfqq, then it is
  46033. + * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain
  46034. + * may have dropped their last reference (not just their last process
  46035. + * reference).
  46036. + */
  46037. + if (!bfqq_process_refs(new_bfqq))
  46038. + return NULL;
  46039. +
  46040. + /* Avoid a circular list and skip interim queue merges. */
  46041. + while ((__bfqq = new_bfqq->new_bfqq)) {
  46042. + if (__bfqq == bfqq)
  46043. + return NULL;
  46044. + new_bfqq = __bfqq;
  46045. + }
  46046. +
  46047. + process_refs = bfqq_process_refs(bfqq);
  46048. + new_process_refs = bfqq_process_refs(new_bfqq);
  46049. + /*
  46050. + * If the process for the bfqq has gone away, there is no
  46051. + * sense in merging the queues.
  46052. + */
  46053. + if (process_refs == 0 || new_process_refs == 0)
  46054. + return NULL;
  46055. +
  46056. + bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d",
  46057. + new_bfqq->pid);
  46058. +
  46059. + /*
  46060. + * Merging is just a redirection: the requests of the process
  46061. + * owning one of the two queues are redirected to the other queue.
  46062. + * The latter queue, in its turn, is set as shared if this is the
  46063. + * first time that the requests of some process are redirected to
  46064. + * it.
  46065. + *
  46066. + * We redirect bfqq to new_bfqq and not the opposite, because we
  46067. + * are in the context of the process owning bfqq, hence we have
  46068. + * the io_cq of this process. So we can immediately configure this
  46069. + * io_cq to redirect the requests of the process to new_bfqq.
  46070. + *
  46071. + * NOTE, even if new_bfqq coincides with the in-service queue, the
  46072. + * io_cq of new_bfqq is not available, because, if the in-service
  46073. + * queue is shared, bfqd->in_service_bic may not point to the
  46074. + * io_cq of the in-service queue.
  46075. + * Redirecting the requests of the process owning bfqq to the
  46076. + * currently in-service queue is in any case the best option, as
  46077. + * we feed the in-service queue with new requests close to the
  46078. + * last request served and, by doing so, hopefully increase the
  46079. + * throughput.
  46080. + */
  46081. + bfqq->new_bfqq = new_bfqq;
  46082. + atomic_add(process_refs, &new_bfqq->ref);
  46083. + return new_bfqq;
  46084. +}
  46085. +
  46086. +/*
  46087. + * Attempt to schedule a merge of bfqq with the currently in-service queue
  46088. + * or with a close queue among the scheduled queues.
  46089. + * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue
  46090. + * structure otherwise.
  46091. + */
  46092. +static struct bfq_queue *
  46093. +bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  46094. + void *io_struct, bool request)
  46095. +{
  46096. + struct bfq_queue *in_service_bfqq, *new_bfqq;
  46097. +
  46098. + if (bfqq->new_bfqq)
  46099. + return bfqq->new_bfqq;
  46100. +
  46101. + if (!io_struct)
  46102. + return NULL;
  46103. +
  46104. + in_service_bfqq = bfqd->in_service_queue;
  46105. +
  46106. + if (in_service_bfqq == NULL || in_service_bfqq == bfqq ||
  46107. + !bfqd->in_service_bic)
  46108. + goto check_scheduled;
  46109. +
  46110. + if (bfq_class_idle(in_service_bfqq) || bfq_class_idle(bfqq))
  46111. + goto check_scheduled;
  46112. +
  46113. + if (bfq_class_rt(in_service_bfqq) != bfq_class_rt(bfqq))
  46114. + goto check_scheduled;
  46115. +
  46116. + if (in_service_bfqq->entity.parent != bfqq->entity.parent)
  46117. + goto check_scheduled;
  46118. +
  46119. + if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
  46120. + bfq_bfqq_sync(in_service_bfqq) && bfq_bfqq_sync(bfqq)) {
  46121. + new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq);
  46122. + if (new_bfqq != NULL)
  46123. + return new_bfqq; /* Merge with in-service queue */
  46124. + }
  46125. +
  46126. + /*
  46127. + * Check whether there is a cooperator among currently scheduled
  46128. + * queues. The only thing we need is that the bio/request is not
  46129. + * NULL, as we need it to establish whether a cooperator exists.
  46130. + */
  46131. +check_scheduled:
  46132. + new_bfqq = bfq_close_cooperator(bfqd, bfqq,
  46133. + bfq_io_struct_pos(io_struct, request));
  46134. + if (new_bfqq)
  46135. + return bfq_setup_merge(bfqq, new_bfqq);
  46136. +
  46137. + return NULL;
  46138. +}
  46139. +
  46140. +static inline void
  46141. +bfq_bfqq_save_state(struct bfq_queue *bfqq)
  46142. +{
  46143. + /*
  46144. + * If bfqq->bic == NULL, the queue is already shared or its requests
  46145. + * have already been redirected to a shared queue; both idle window
  46146. + * and weight raising state have already been saved. Do nothing.
  46147. + */
  46148. + if (bfqq->bic == NULL)
  46149. + return;
  46150. + if (bfqq->bic->wr_time_left)
  46151. + /*
  46152. + * This is the queue of a just-started process, and would
  46153. + * deserve weight raising: we set wr_time_left to the full
  46154. + * weight-raising duration to trigger weight-raising when
  46155. + * and if the queue is split and the first request of the
  46156. + * queue is enqueued.
  46157. + */
  46158. + bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd);
  46159. + else if (bfqq->wr_coeff > 1) {
  46160. + unsigned long wr_duration =
  46161. + jiffies - bfqq->last_wr_start_finish;
  46162. + /*
  46163. + * It may happen that a queue's weight raising period lasts
  46164. + * longer than its wr_cur_max_time, as weight raising is
  46165. + * handled only when a request is enqueued or dispatched (it
  46166. + * does not use any timer). If the weight raising period is
  46167. + * about to end, don't save it.
  46168. + */
  46169. + if (bfqq->wr_cur_max_time <= wr_duration)
  46170. + bfqq->bic->wr_time_left = 0;
  46171. + else
  46172. + bfqq->bic->wr_time_left =
  46173. + bfqq->wr_cur_max_time - wr_duration;
  46174. + /*
  46175. + * The bfq_queue is becoming shared or the requests of the
  46176. + * process owning the queue are being redirected to a shared
  46177. + * queue. Stop the weight raising period of the queue, as in
  46178. + * both cases it should not be owned by an interactive or
  46179. + * soft real-time application.
  46180. + */
  46181. + bfq_bfqq_end_wr(bfqq);
  46182. + } else
  46183. + bfqq->bic->wr_time_left = 0;
  46184. + bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq);
  46185. + bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
  46186. + bfqq->bic->cooperations++;
  46187. + bfqq->bic->failed_cooperations = 0;
  46188. +}
  46189. +
  46190. +static inline void
  46191. +bfq_get_bic_reference(struct bfq_queue *bfqq)
  46192. +{
  46193. + /*
  46194. + * If bfqq->bic has a non-NULL value, the bic to which it belongs
  46195. + * is about to begin using a shared bfq_queue.
  46196. + */
  46197. + if (bfqq->bic)
  46198. + atomic_long_inc(&bfqq->bic->icq.ioc->refcount);
  46199. +}
  46200. +
  46201. +static void
  46202. +bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
  46203. + struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
  46204. +{
  46205. + bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu",
  46206. + (long unsigned)new_bfqq->pid);
  46207. + /* Save weight raising and idle window of the merged queues */
  46208. + bfq_bfqq_save_state(bfqq);
  46209. + bfq_bfqq_save_state(new_bfqq);
  46210. + if (bfq_bfqq_IO_bound(bfqq))
  46211. + bfq_mark_bfqq_IO_bound(new_bfqq);
  46212. + bfq_clear_bfqq_IO_bound(bfqq);
  46213. + /*
  46214. + * Grab a reference to the bic, to prevent it from being destroyed
  46215. + * before being possibly touched by a bfq_split_bfqq().
  46216. + */
  46217. + bfq_get_bic_reference(bfqq);
  46218. + bfq_get_bic_reference(new_bfqq);
  46219. + /*
  46220. + * Merge queues (that is, let bic redirect its requests to new_bfqq)
  46221. + */
  46222. + bic_set_bfqq(bic, new_bfqq, 1);
  46223. + bfq_mark_bfqq_coop(new_bfqq);
  46224. + /*
  46225. + * new_bfqq now belongs to at least two bics (it is a shared queue):
  46226. + * set new_bfqq->bic to NULL. bfqq either:
  46227. + * - does not belong to any bic any more, and hence bfqq->bic must
  46228. + * be set to NULL, or
  46229. + * - is a queue whose owning bics have already been redirected to a
  46230. + * different queue, hence the queue is destined to not belong to
  46231. + * any bic soon and bfqq->bic is already NULL (therefore the next
  46232. + * assignment causes no harm).
  46233. + */
  46234. + new_bfqq->bic = NULL;
  46235. + bfqq->bic = NULL;
  46236. + bfq_put_queue(bfqq);
  46237. +}
  46238. +
  46239. +static inline void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq)
  46240. +{
  46241. + struct bfq_io_cq *bic = bfqq->bic;
  46242. + struct bfq_data *bfqd = bfqq->bfqd;
  46243. +
  46244. + if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) {
  46245. + bic->failed_cooperations++;
  46246. + if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations)
  46247. + bic->cooperations = 0;
  46248. + }
  46249. +}
  46250. +
  46251. +static int bfq_allow_merge(struct request_queue *q, struct request *rq,
  46252. + struct bio *bio)
  46253. +{
  46254. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46255. + struct bfq_io_cq *bic;
  46256. + struct bfq_queue *bfqq, *new_bfqq;
  46257. +
  46258. + /*
  46259. + * Disallow merge of a sync bio into an async request.
  46260. + */
  46261. + if (bfq_bio_sync(bio) && !rq_is_sync(rq))
  46262. + return 0;
  46263. +
  46264. + /*
  46265. + * Lookup the bfqq that this bio will be queued with. Allow
  46266. + * merge only if rq is queued there.
  46267. + * Queue lock is held here.
  46268. + */
  46269. + bic = bfq_bic_lookup(bfqd, current->io_context);
  46270. + if (bic == NULL)
  46271. + return 0;
  46272. +
  46273. + bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
  46274. + /*
  46275. + * We take advantage of this function to perform an early merge
  46276. + * of the queues of possible cooperating processes.
  46277. + */
  46278. + if (bfqq != NULL) {
  46279. + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false);
  46280. + if (new_bfqq != NULL) {
  46281. + bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq);
  46282. + /*
  46283. + * If we get here, the bio will be queued in the
  46284. + * shared queue, i.e., new_bfqq, so use new_bfqq
  46285. + * to decide whether bio and rq can be merged.
  46286. + */
  46287. + bfqq = new_bfqq;
  46288. + } else
  46289. + bfq_bfqq_increase_failed_cooperations(bfqq);
  46290. + }
  46291. +
  46292. + return bfqq == RQ_BFQQ(rq);
  46293. +}
  46294. +
  46295. +static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
  46296. + struct bfq_queue *bfqq)
  46297. +{
  46298. + if (bfqq != NULL) {
  46299. + bfq_mark_bfqq_must_alloc(bfqq);
  46300. + bfq_mark_bfqq_budget_new(bfqq);
  46301. + bfq_clear_bfqq_fifo_expire(bfqq);
  46302. +
  46303. + bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8;
  46304. +
  46305. + bfq_log_bfqq(bfqd, bfqq,
  46306. + "set_in_service_queue, cur-budget = %lu",
  46307. + bfqq->entity.budget);
  46308. + }
  46309. +
  46310. + bfqd->in_service_queue = bfqq;
  46311. +}
  46312. +
  46313. +/*
  46314. + * Get and set a new queue for service.
  46315. + */
  46316. +static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd)
  46317. +{
  46318. + struct bfq_queue *bfqq = bfq_get_next_queue(bfqd);
  46319. +
  46320. + __bfq_set_in_service_queue(bfqd, bfqq);
  46321. + return bfqq;
  46322. +}
  46323. +
  46324. +/*
  46325. + * If enough samples have been computed, return the current max budget
  46326. + * stored in bfqd, which is dynamically updated according to the
  46327. + * estimated disk peak rate; otherwise return the default max budget
  46328. + */
  46329. +static inline unsigned long bfq_max_budget(struct bfq_data *bfqd)
  46330. +{
  46331. + if (bfqd->budgets_assigned < 194)
  46332. + return bfq_default_max_budget;
  46333. + else
  46334. + return bfqd->bfq_max_budget;
  46335. +}
  46336. +
  46337. +/*
  46338. + * Return min budget, which is a fraction of the current or default
  46339. + * max budget (trying with 1/32)
  46340. + */
  46341. +static inline unsigned long bfq_min_budget(struct bfq_data *bfqd)
  46342. +{
  46343. + if (bfqd->budgets_assigned < 194)
  46344. + return bfq_default_max_budget / 32;
  46345. + else
  46346. + return bfqd->bfq_max_budget / 32;
  46347. +}
  46348. +
  46349. +static void bfq_arm_slice_timer(struct bfq_data *bfqd)
  46350. +{
  46351. + struct bfq_queue *bfqq = bfqd->in_service_queue;
  46352. + struct bfq_io_cq *bic;
  46353. + unsigned long sl;
  46354. +
  46355. + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
  46356. +
  46357. + /* Processes have exited, don't wait. */
  46358. + bic = bfqd->in_service_bic;
  46359. + if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0)
  46360. + return;
  46361. +
  46362. + bfq_mark_bfqq_wait_request(bfqq);
  46363. +
  46364. + /*
  46365. + * We don't want to idle for seeks, but we do want to allow
  46366. + * fair distribution of slice time for a process doing back-to-back
  46367. + * seeks. So allow a little bit of time for him to submit a new rq.
  46368. + *
  46369. + * To prevent processes with (partly) seeky workloads from
  46370. + * being too ill-treated, grant them a small fraction of the
  46371. + * assigned budget before reducing the waiting time to
  46372. + * BFQ_MIN_TT. This happened to help reduce latency.
  46373. + */
  46374. + sl = bfqd->bfq_slice_idle;
  46375. + /*
  46376. + * Unless the queue is being weight-raised, grant only minimum idle
  46377. + * time if the queue either has been seeky for long enough or has
  46378. + * already proved to be constantly seeky.
  46379. + */
  46380. + if (bfq_sample_valid(bfqq->seek_samples) &&
  46381. + ((BFQQ_SEEKY(bfqq) && bfqq->entity.service >
  46382. + bfq_max_budget(bfqq->bfqd) / 8) ||
  46383. + bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1)
  46384. + sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT));
  46385. + else if (bfqq->wr_coeff > 1)
  46386. + sl = sl * 3;
  46387. + bfqd->last_idling_start = ktime_get();
  46388. + mod_timer(&bfqd->idle_slice_timer, jiffies + sl);
  46389. + bfq_log(bfqd, "arm idle: %u/%u ms",
  46390. + jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle));
  46391. +}
  46392. +
  46393. +/*
  46394. + * Set the maximum time for the in-service queue to consume its
  46395. + * budget. This prevents seeky processes from lowering the disk
  46396. + * throughput (always guaranteed with a time slice scheme as in CFQ).
  46397. + */
  46398. +static void bfq_set_budget_timeout(struct bfq_data *bfqd)
  46399. +{
  46400. + struct bfq_queue *bfqq = bfqd->in_service_queue;
  46401. + unsigned int timeout_coeff;
  46402. + if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time)
  46403. + timeout_coeff = 1;
  46404. + else
  46405. + timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight;
  46406. +
  46407. + bfqd->last_budget_start = ktime_get();
  46408. +
  46409. + bfq_clear_bfqq_budget_new(bfqq);
  46410. + bfqq->budget_timeout = jiffies +
  46411. + bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff;
  46412. +
  46413. + bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u",
  46414. + jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] *
  46415. + timeout_coeff));
  46416. +}
  46417. +
  46418. +/*
  46419. + * Move request from internal lists to the request queue dispatch list.
  46420. + */
  46421. +static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
  46422. +{
  46423. + struct bfq_data *bfqd = q->elevator->elevator_data;
  46424. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  46425. +
  46426. + /*
  46427. + * For consistency, the next instruction should have been executed
  46428. + * after removing the request from the queue and dispatching it.
  46429. + * We execute instead this instruction before bfq_remove_request()
  46430. + * (and hence introduce a temporary inconsistency), for efficiency.
  46431. + * In fact, in a forced_dispatch, this prevents two counters related
  46432. + * to bfqq->dispatched to risk to be uselessly decremented if bfqq
  46433. + * is not in service, and then to be incremented again after
  46434. + * incrementing bfqq->dispatched.
  46435. + */
  46436. + bfqq->dispatched++;
  46437. + bfq_remove_request(rq);
  46438. + elv_dispatch_sort(q, rq);
  46439. +
  46440. + if (bfq_bfqq_sync(bfqq))
  46441. + bfqd->sync_flight++;
  46442. +}
  46443. +
  46444. +/*
  46445. + * Return expired entry, or NULL to just start from scratch in rbtree.
  46446. + */
  46447. +static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
  46448. +{
  46449. + struct request *rq = NULL;
  46450. +
  46451. + if (bfq_bfqq_fifo_expire(bfqq))
  46452. + return NULL;
  46453. +
  46454. + bfq_mark_bfqq_fifo_expire(bfqq);
  46455. +
  46456. + if (list_empty(&bfqq->fifo))
  46457. + return NULL;
  46458. +
  46459. + rq = rq_entry_fifo(bfqq->fifo.next);
  46460. +
  46461. + if (time_before(jiffies, rq_fifo_time(rq)))
  46462. + return NULL;
  46463. +
  46464. + return rq;
  46465. +}
  46466. +
  46467. +static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq)
  46468. +{
  46469. + struct bfq_entity *entity = &bfqq->entity;
  46470. + return entity->budget - entity->service;
  46471. +}
  46472. +
  46473. +static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  46474. +{
  46475. + BUG_ON(bfqq != bfqd->in_service_queue);
  46476. +
  46477. + __bfq_bfqd_reset_in_service(bfqd);
  46478. +
  46479. + /*
  46480. + * If this bfqq is shared between multiple processes, check
  46481. + * to make sure that those processes are still issuing I/Os
  46482. + * within the mean seek distance. If not, it may be time to
  46483. + * break the queues apart again.
  46484. + */
  46485. + if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq))
  46486. + bfq_mark_bfqq_split_coop(bfqq);
  46487. +
  46488. + if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
  46489. + /*
  46490. + * Overloading budget_timeout field to store the time
  46491. + * at which the queue remains with no backlog; used by
  46492. + * the weight-raising mechanism.
  46493. + */
  46494. + bfqq->budget_timeout = jiffies;
  46495. + bfq_del_bfqq_busy(bfqd, bfqq, 1);
  46496. + } else {
  46497. + bfq_activate_bfqq(bfqd, bfqq);
  46498. + /*
  46499. + * Resort priority tree of potential close cooperators.
  46500. + */
  46501. + bfq_rq_pos_tree_add(bfqd, bfqq);
  46502. + }
  46503. +}
  46504. +
  46505. +/**
  46506. + * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior.
  46507. + * @bfqd: device data.
  46508. + * @bfqq: queue to update.
  46509. + * @reason: reason for expiration.
  46510. + *
  46511. + * Handle the feedback on @bfqq budget. See the body for detailed
  46512. + * comments.
  46513. + */
  46514. +static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
  46515. + struct bfq_queue *bfqq,
  46516. + enum bfqq_expiration reason)
  46517. +{
  46518. + struct request *next_rq;
  46519. + unsigned long budget, min_budget;
  46520. +
  46521. + budget = bfqq->max_budget;
  46522. + min_budget = bfq_min_budget(bfqd);
  46523. +
  46524. + BUG_ON(bfqq != bfqd->in_service_queue);
  46525. +
  46526. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu",
  46527. + bfqq->entity.budget, bfq_bfqq_budget_left(bfqq));
  46528. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu",
  46529. + budget, bfq_min_budget(bfqd));
  46530. + bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d",
  46531. + bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue));
  46532. +
  46533. + if (bfq_bfqq_sync(bfqq)) {
  46534. + switch (reason) {
  46535. + /*
  46536. + * Caveat: in all the following cases we trade latency
  46537. + * for throughput.
  46538. + */
  46539. + case BFQ_BFQQ_TOO_IDLE:
  46540. + /*
  46541. + * This is the only case where we may reduce
  46542. + * the budget: if there is no request of the
  46543. + * process still waiting for completion, then
  46544. + * we assume (tentatively) that the timer has
  46545. + * expired because the batch of requests of
  46546. + * the process could have been served with a
  46547. + * smaller budget. Hence, betting that
  46548. + * process will behave in the same way when it
  46549. + * becomes backlogged again, we reduce its
  46550. + * next budget. As long as we guess right,
  46551. + * this budget cut reduces the latency
  46552. + * experienced by the process.
  46553. + *
  46554. + * However, if there are still outstanding
  46555. + * requests, then the process may have not yet
  46556. + * issued its next request just because it is
  46557. + * still waiting for the completion of some of
  46558. + * the still outstanding ones. So in this
  46559. + * subcase we do not reduce its budget, on the
  46560. + * contrary we increase it to possibly boost
  46561. + * the throughput, as discussed in the
  46562. + * comments to the BUDGET_TIMEOUT case.
  46563. + */
  46564. + if (bfqq->dispatched > 0) /* still outstanding reqs */
  46565. + budget = min(budget * 2, bfqd->bfq_max_budget);
  46566. + else {
  46567. + if (budget > 5 * min_budget)
  46568. + budget -= 4 * min_budget;
  46569. + else
  46570. + budget = min_budget;
  46571. + }
  46572. + break;
  46573. + case BFQ_BFQQ_BUDGET_TIMEOUT:
  46574. + /*
  46575. + * We double the budget here because: 1) it
  46576. + * gives the chance to boost the throughput if
  46577. + * this is not a seeky process (which may have
  46578. + * bumped into this timeout because of, e.g.,
  46579. + * ZBR), 2) together with charge_full_budget
  46580. + * it helps give seeky processes higher
  46581. + * timestamps, and hence be served less
  46582. + * frequently.
  46583. + */
  46584. + budget = min(budget * 2, bfqd->bfq_max_budget);
  46585. + break;
  46586. + case BFQ_BFQQ_BUDGET_EXHAUSTED:
  46587. + /*
  46588. + * The process still has backlog, and did not
  46589. + * let either the budget timeout or the disk
  46590. + * idling timeout expire. Hence it is not
  46591. + * seeky, has a short thinktime and may be
  46592. + * happy with a higher budget too. So
  46593. + * definitely increase the budget of this good
  46594. + * candidate to boost the disk throughput.
  46595. + */
  46596. + budget = min(budget * 4, bfqd->bfq_max_budget);
  46597. + break;
  46598. + case BFQ_BFQQ_NO_MORE_REQUESTS:
  46599. + /*
  46600. + * Leave the budget unchanged.
  46601. + */
  46602. + default:
  46603. + return;
  46604. + }
  46605. + } else /* async queue */
  46606. + /* async queues get always the maximum possible budget
  46607. + * (their ability to dispatch is limited by
  46608. + * @bfqd->bfq_max_budget_async_rq).
  46609. + */
  46610. + budget = bfqd->bfq_max_budget;
  46611. +
  46612. + bfqq->max_budget = budget;
  46613. +
  46614. + if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 &&
  46615. + bfqq->max_budget > bfqd->bfq_max_budget)
  46616. + bfqq->max_budget = bfqd->bfq_max_budget;
  46617. +
  46618. + /*
  46619. + * Make sure that we have enough budget for the next request.
  46620. + * Since the finish time of the bfqq must be kept in sync with
  46621. + * the budget, be sure to call __bfq_bfqq_expire() after the
  46622. + * update.
  46623. + */
  46624. + next_rq = bfqq->next_rq;
  46625. + if (next_rq != NULL)
  46626. + bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget,
  46627. + bfq_serv_to_charge(next_rq, bfqq));
  46628. + else
  46629. + bfqq->entity.budget = bfqq->max_budget;
  46630. +
  46631. + bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu",
  46632. + next_rq != NULL ? blk_rq_sectors(next_rq) : 0,
  46633. + bfqq->entity.budget);
  46634. +}
  46635. +
  46636. +static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout)
  46637. +{
  46638. + unsigned long max_budget;
  46639. +
  46640. + /*
  46641. + * The max_budget calculated when autotuning is equal to the
  46642. + * amount of sectors transfered in timeout_sync at the
  46643. + * estimated peak rate.
  46644. + */
  46645. + max_budget = (unsigned long)(peak_rate * 1000 *
  46646. + timeout >> BFQ_RATE_SHIFT);
  46647. +
  46648. + return max_budget;
  46649. +}
  46650. +
  46651. +/*
  46652. + * In addition to updating the peak rate, checks whether the process
  46653. + * is "slow", and returns 1 if so. This slow flag is used, in addition
  46654. + * to the budget timeout, to reduce the amount of service provided to
  46655. + * seeky processes, and hence reduce their chances to lower the
  46656. + * throughput. See the code for more details.
  46657. + */
  46658. +static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  46659. + int compensate, enum bfqq_expiration reason)
  46660. +{
  46661. + u64 bw, usecs, expected, timeout;
  46662. + ktime_t delta;
  46663. + int update = 0;
  46664. +
  46665. + if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq))
  46666. + return 0;
  46667. +
  46668. + if (compensate)
  46669. + delta = bfqd->last_idling_start;
  46670. + else
  46671. + delta = ktime_get();
  46672. + delta = ktime_sub(delta, bfqd->last_budget_start);
  46673. + usecs = ktime_to_us(delta);
  46674. +
  46675. + /* Don't trust short/unrealistic values. */
  46676. + if (usecs < 100 || usecs >= LONG_MAX)
  46677. + return 0;
  46678. +
  46679. + /*
  46680. + * Calculate the bandwidth for the last slice. We use a 64 bit
  46681. + * value to store the peak rate, in sectors per usec in fixed
  46682. + * point math. We do so to have enough precision in the estimate
  46683. + * and to avoid overflows.
  46684. + */
  46685. + bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT;
  46686. + do_div(bw, (unsigned long)usecs);
  46687. +
  46688. + timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
  46689. +
  46690. + /*
  46691. + * Use only long (> 20ms) intervals to filter out spikes for
  46692. + * the peak rate estimation.
  46693. + */
  46694. + if (usecs > 20000) {
  46695. + if (bw > bfqd->peak_rate ||
  46696. + (!BFQQ_SEEKY(bfqq) &&
  46697. + reason == BFQ_BFQQ_BUDGET_TIMEOUT)) {
  46698. + bfq_log(bfqd, "measured bw =%llu", bw);
  46699. + /*
  46700. + * To smooth oscillations use a low-pass filter with
  46701. + * alpha=7/8, i.e.,
  46702. + * new_rate = (7/8) * old_rate + (1/8) * bw
  46703. + */
  46704. + do_div(bw, 8);
  46705. + if (bw == 0)
  46706. + return 0;
  46707. + bfqd->peak_rate *= 7;
  46708. + do_div(bfqd->peak_rate, 8);
  46709. + bfqd->peak_rate += bw;
  46710. + update = 1;
  46711. + bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate);
  46712. + }
  46713. +
  46714. + update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1;
  46715. +
  46716. + if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES)
  46717. + bfqd->peak_rate_samples++;
  46718. +
  46719. + if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES &&
  46720. + update) {
  46721. + int dev_type = blk_queue_nonrot(bfqd->queue);
  46722. + if (bfqd->bfq_user_max_budget == 0) {
  46723. + bfqd->bfq_max_budget =
  46724. + bfq_calc_max_budget(bfqd->peak_rate,
  46725. + timeout);
  46726. + bfq_log(bfqd, "new max_budget=%lu",
  46727. + bfqd->bfq_max_budget);
  46728. + }
  46729. + if (bfqd->device_speed == BFQ_BFQD_FAST &&
  46730. + bfqd->peak_rate < device_speed_thresh[dev_type]) {
  46731. + bfqd->device_speed = BFQ_BFQD_SLOW;
  46732. + bfqd->RT_prod = R_slow[dev_type] *
  46733. + T_slow[dev_type];
  46734. + } else if (bfqd->device_speed == BFQ_BFQD_SLOW &&
  46735. + bfqd->peak_rate > device_speed_thresh[dev_type]) {
  46736. + bfqd->device_speed = BFQ_BFQD_FAST;
  46737. + bfqd->RT_prod = R_fast[dev_type] *
  46738. + T_fast[dev_type];
  46739. + }
  46740. + }
  46741. + }
  46742. +
  46743. + /*
  46744. + * If the process has been served for a too short time
  46745. + * interval to let its possible sequential accesses prevail on
  46746. + * the initial seek time needed to move the disk head on the
  46747. + * first sector it requested, then give the process a chance
  46748. + * and for the moment return false.
  46749. + */
  46750. + if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8)
  46751. + return 0;
  46752. +
  46753. + /*
  46754. + * A process is considered ``slow'' (i.e., seeky, so that we
  46755. + * cannot treat it fairly in the service domain, as it would
  46756. + * slow down too much the other processes) if, when a slice
  46757. + * ends for whatever reason, it has received service at a
  46758. + * rate that would not be high enough to complete the budget
  46759. + * before the budget timeout expiration.
  46760. + */
  46761. + expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT;
  46762. +
  46763. + /*
  46764. + * Caveat: processes doing IO in the slower disk zones will
  46765. + * tend to be slow(er) even if not seeky. And the estimated
  46766. + * peak rate will actually be an average over the disk
  46767. + * surface. Hence, to not be too harsh with unlucky processes,
  46768. + * we keep a budget/3 margin of safety before declaring a
  46769. + * process slow.
  46770. + */
  46771. + return expected > (4 * bfqq->entity.budget) / 3;
  46772. +}
  46773. +
  46774. +/*
  46775. + * To be deemed as soft real-time, an application must meet two
  46776. + * requirements. First, the application must not require an average
  46777. + * bandwidth higher than the approximate bandwidth required to playback or
  46778. + * record a compressed high-definition video.
  46779. + * The next function is invoked on the completion of the last request of a
  46780. + * batch, to compute the next-start time instant, soft_rt_next_start, such
  46781. + * that, if the next request of the application does not arrive before
  46782. + * soft_rt_next_start, then the above requirement on the bandwidth is met.
  46783. + *
  46784. + * The second requirement is that the request pattern of the application is
  46785. + * isochronous, i.e., that, after issuing a request or a batch of requests,
  46786. + * the application stops issuing new requests until all its pending requests
  46787. + * have been completed. After that, the application may issue a new batch,
  46788. + * and so on.
  46789. + * For this reason the next function is invoked to compute
  46790. + * soft_rt_next_start only for applications that meet this requirement,
  46791. + * whereas soft_rt_next_start is set to infinity for applications that do
  46792. + * not.
  46793. + *
  46794. + * Unfortunately, even a greedy application may happen to behave in an
  46795. + * isochronous way if the CPU load is high. In fact, the application may
  46796. + * stop issuing requests while the CPUs are busy serving other processes,
  46797. + * then restart, then stop again for a while, and so on. In addition, if
  46798. + * the disk achieves a low enough throughput with the request pattern
  46799. + * issued by the application (e.g., because the request pattern is random
  46800. + * and/or the device is slow), then the application may meet the above
  46801. + * bandwidth requirement too. To prevent such a greedy application to be
  46802. + * deemed as soft real-time, a further rule is used in the computation of
  46803. + * soft_rt_next_start: soft_rt_next_start must be higher than the current
  46804. + * time plus the maximum time for which the arrival of a request is waited
  46805. + * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle.
  46806. + * This filters out greedy applications, as the latter issue instead their
  46807. + * next request as soon as possible after the last one has been completed
  46808. + * (in contrast, when a batch of requests is completed, a soft real-time
  46809. + * application spends some time processing data).
  46810. + *
  46811. + * Unfortunately, the last filter may easily generate false positives if
  46812. + * only bfqd->bfq_slice_idle is used as a reference time interval and one
  46813. + * or both the following cases occur:
  46814. + * 1) HZ is so low that the duration of a jiffy is comparable to or higher
  46815. + * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with
  46816. + * HZ=100.
  46817. + * 2) jiffies, instead of increasing at a constant rate, may stop increasing
  46818. + * for a while, then suddenly 'jump' by several units to recover the lost
  46819. + * increments. This seems to happen, e.g., inside virtual machines.
  46820. + * To address this issue, we do not use as a reference time interval just
  46821. + * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In
  46822. + * particular we add the minimum number of jiffies for which the filter
  46823. + * seems to be quite precise also in embedded systems and KVM/QEMU virtual
  46824. + * machines.
  46825. + */
  46826. +static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
  46827. + struct bfq_queue *bfqq)
  46828. +{
  46829. + return max(bfqq->last_idle_bklogged +
  46830. + HZ * bfqq->service_from_backlogged /
  46831. + bfqd->bfq_wr_max_softrt_rate,
  46832. + jiffies + bfqq->bfqd->bfq_slice_idle + 4);
  46833. +}
  46834. +
  46835. +/*
  46836. + * Return the largest-possible time instant such that, for as long as possible,
  46837. + * the current time will be lower than this time instant according to the macro
  46838. + * time_is_before_jiffies().
  46839. + */
  46840. +static inline unsigned long bfq_infinity_from_now(unsigned long now)
  46841. +{
  46842. + return now + ULONG_MAX / 2;
  46843. +}
  46844. +
  46845. +/**
  46846. + * bfq_bfqq_expire - expire a queue.
  46847. + * @bfqd: device owning the queue.
  46848. + * @bfqq: the queue to expire.
  46849. + * @compensate: if true, compensate for the time spent idling.
  46850. + * @reason: the reason causing the expiration.
  46851. + *
  46852. + *
  46853. + * If the process associated to the queue is slow (i.e., seeky), or in
  46854. + * case of budget timeout, or, finally, if it is async, we
  46855. + * artificially charge it an entire budget (independently of the
  46856. + * actual service it received). As a consequence, the queue will get
  46857. + * higher timestamps than the correct ones upon reactivation, and
  46858. + * hence it will be rescheduled as if it had received more service
  46859. + * than what it actually received. In the end, this class of processes
  46860. + * will receive less service in proportion to how slowly they consume
  46861. + * their budgets (and hence how seriously they tend to lower the
  46862. + * throughput).
  46863. + *
  46864. + * In contrast, when a queue expires because it has been idling for
  46865. + * too much or because it exhausted its budget, we do not touch the
  46866. + * amount of service it has received. Hence when the queue will be
  46867. + * reactivated and its timestamps updated, the latter will be in sync
  46868. + * with the actual service received by the queue until expiration.
  46869. + *
  46870. + * Charging a full budget to the first type of queues and the exact
  46871. + * service to the others has the effect of using the WF2Q+ policy to
  46872. + * schedule the former on a timeslice basis, without violating the
  46873. + * service domain guarantees of the latter.
  46874. + */
  46875. +static void bfq_bfqq_expire(struct bfq_data *bfqd,
  46876. + struct bfq_queue *bfqq,
  46877. + int compensate,
  46878. + enum bfqq_expiration reason)
  46879. +{
  46880. + int slow;
  46881. + BUG_ON(bfqq != bfqd->in_service_queue);
  46882. +
  46883. + /* Update disk peak rate for autotuning and check whether the
  46884. + * process is slow (see bfq_update_peak_rate).
  46885. + */
  46886. + slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason);
  46887. +
  46888. + /*
  46889. + * As above explained, 'punish' slow (i.e., seeky), timed-out
  46890. + * and async queues, to favor sequential sync workloads.
  46891. + *
  46892. + * Processes doing I/O in the slower disk zones will tend to be
  46893. + * slow(er) even if not seeky. Hence, since the estimated peak
  46894. + * rate is actually an average over the disk surface, these
  46895. + * processes may timeout just for bad luck. To avoid punishing
  46896. + * them we do not charge a full budget to a process that
  46897. + * succeeded in consuming at least 2/3 of its budget.
  46898. + */
  46899. + if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
  46900. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3))
  46901. + bfq_bfqq_charge_full_budget(bfqq);
  46902. +
  46903. + bfqq->service_from_backlogged += bfqq->entity.service;
  46904. +
  46905. + if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
  46906. + !bfq_bfqq_constantly_seeky(bfqq)) {
  46907. + bfq_mark_bfqq_constantly_seeky(bfqq);
  46908. + if (!blk_queue_nonrot(bfqd->queue))
  46909. + bfqd->const_seeky_busy_in_flight_queues++;
  46910. + }
  46911. +
  46912. + if (reason == BFQ_BFQQ_TOO_IDLE &&
  46913. + bfqq->entity.service <= 2 * bfqq->entity.budget / 10 )
  46914. + bfq_clear_bfqq_IO_bound(bfqq);
  46915. +
  46916. + if (bfqd->low_latency && bfqq->wr_coeff == 1)
  46917. + bfqq->last_wr_start_finish = jiffies;
  46918. +
  46919. + if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 &&
  46920. + RB_EMPTY_ROOT(&bfqq->sort_list)) {
  46921. + /*
  46922. + * If we get here, and there are no outstanding requests,
  46923. + * then the request pattern is isochronous (see the comments
  46924. + * to the function bfq_bfqq_softrt_next_start()). Hence we
  46925. + * can compute soft_rt_next_start. If, instead, the queue
  46926. + * still has outstanding requests, then we have to wait
  46927. + * for the completion of all the outstanding requests to
  46928. + * discover whether the request pattern is actually
  46929. + * isochronous.
  46930. + */
  46931. + if (bfqq->dispatched == 0)
  46932. + bfqq->soft_rt_next_start =
  46933. + bfq_bfqq_softrt_next_start(bfqd, bfqq);
  46934. + else {
  46935. + /*
  46936. + * The application is still waiting for the
  46937. + * completion of one or more requests:
  46938. + * prevent it from possibly being incorrectly
  46939. + * deemed as soft real-time by setting its
  46940. + * soft_rt_next_start to infinity. In fact,
  46941. + * without this assignment, the application
  46942. + * would be incorrectly deemed as soft
  46943. + * real-time if:
  46944. + * 1) it issued a new request before the
  46945. + * completion of all its in-flight
  46946. + * requests, and
  46947. + * 2) at that time, its soft_rt_next_start
  46948. + * happened to be in the past.
  46949. + */
  46950. + bfqq->soft_rt_next_start =
  46951. + bfq_infinity_from_now(jiffies);
  46952. + /*
  46953. + * Schedule an update of soft_rt_next_start to when
  46954. + * the task may be discovered to be isochronous.
  46955. + */
  46956. + bfq_mark_bfqq_softrt_update(bfqq);
  46957. + }
  46958. + }
  46959. +
  46960. + bfq_log_bfqq(bfqd, bfqq,
  46961. + "expire (%d, slow %d, num_disp %d, idle_win %d)", reason,
  46962. + slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq));
  46963. +
  46964. + /*
  46965. + * Increase, decrease or leave budget unchanged according to
  46966. + * reason.
  46967. + */
  46968. + __bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
  46969. + __bfq_bfqq_expire(bfqd, bfqq);
  46970. +}
  46971. +
  46972. +/*
  46973. + * Budget timeout is not implemented through a dedicated timer, but
  46974. + * just checked on request arrivals and completions, as well as on
  46975. + * idle timer expirations.
  46976. + */
  46977. +static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq)
  46978. +{
  46979. + if (bfq_bfqq_budget_new(bfqq) ||
  46980. + time_before(jiffies, bfqq->budget_timeout))
  46981. + return 0;
  46982. + return 1;
  46983. +}
  46984. +
  46985. +/*
  46986. + * If we expire a queue that is waiting for the arrival of a new
  46987. + * request, we may prevent the fictitious timestamp back-shifting that
  46988. + * allows the guarantees of the queue to be preserved (see [1] for
  46989. + * this tricky aspect). Hence we return true only if this condition
  46990. + * does not hold, or if the queue is slow enough to deserve only to be
  46991. + * kicked off for preserving a high throughput.
  46992. +*/
  46993. +static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
  46994. +{
  46995. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  46996. + "may_budget_timeout: wait_request %d left %d timeout %d",
  46997. + bfq_bfqq_wait_request(bfqq),
  46998. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3,
  46999. + bfq_bfqq_budget_timeout(bfqq));
  47000. +
  47001. + return (!bfq_bfqq_wait_request(bfqq) ||
  47002. + bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)
  47003. + &&
  47004. + bfq_bfqq_budget_timeout(bfqq);
  47005. +}
  47006. +
  47007. +/*
  47008. + * Device idling is allowed only for the queues for which this function
  47009. + * returns true. For this reason, the return value of this function plays a
  47010. + * critical role for both throughput boosting and service guarantees. The
  47011. + * return value is computed through a logical expression. In this rather
  47012. + * long comment, we try to briefly describe all the details and motivations
  47013. + * behind the components of this logical expression.
  47014. + *
  47015. + * First, the expression may be true only for sync queues. Besides, if
  47016. + * bfqq is also being weight-raised, then the expression always evaluates
  47017. + * to true, as device idling is instrumental for preserving low-latency
  47018. + * guarantees (see [1]). Otherwise, the expression evaluates to true only
  47019. + * if bfqq has a non-null idle window and at least one of the following
  47020. + * two conditions holds. The first condition is that the device is not
  47021. + * performing NCQ, because idling the device most certainly boosts the
  47022. + * throughput if this condition holds and bfqq has been granted a non-null
  47023. + * idle window. The second compound condition is made of the logical AND of
  47024. + * two components.
  47025. + *
  47026. + * The first component is true only if there is no weight-raised busy
  47027. + * queue. This guarantees that the device is not idled for a sync non-
  47028. + * weight-raised queue when there are busy weight-raised queues. The former
  47029. + * is then expired immediately if empty. Combined with the timestamping
  47030. + * rules of BFQ (see [1] for details), this causes sync non-weight-raised
  47031. + * queues to get a lower number of requests served, and hence to ask for a
  47032. + * lower number of requests from the request pool, before the busy weight-
  47033. + * raised queues get served again.
  47034. + *
  47035. + * This is beneficial for the processes associated with weight-raised
  47036. + * queues, when the request pool is saturated (e.g., in the presence of
  47037. + * write hogs). In fact, if the processes associated with the other queues
  47038. + * ask for requests at a lower rate, then weight-raised processes have a
  47039. + * higher probability to get a request from the pool immediately (or at
  47040. + * least soon) when they need one. Hence they have a higher probability to
  47041. + * actually get a fraction of the disk throughput proportional to their
  47042. + * high weight. This is especially true with NCQ-capable drives, which
  47043. + * enqueue several requests in advance and further reorder internally-
  47044. + * queued requests.
  47045. + *
  47046. + * In the end, mistreating non-weight-raised queues when there are busy
  47047. + * weight-raised queues seems to mitigate starvation problems in the
  47048. + * presence of heavy write workloads and NCQ, and hence to guarantee a
  47049. + * higher application and system responsiveness in these hostile scenarios.
  47050. + *
  47051. + * If the first component of the compound condition is instead true, i.e.,
  47052. + * there is no weight-raised busy queue, then the second component of the
  47053. + * compound condition takes into account service-guarantee and throughput
  47054. + * issues related to NCQ (recall that the compound condition is evaluated
  47055. + * only if the device is detected as supporting NCQ).
  47056. + *
  47057. + * As for service guarantees, allowing the drive to enqueue more than one
  47058. + * request at a time, and hence delegating de facto final scheduling
  47059. + * decisions to the drive's internal scheduler, causes loss of control on
  47060. + * the actual request service order. In this respect, when the drive is
  47061. + * allowed to enqueue more than one request at a time, the service
  47062. + * distribution enforced by the drive's internal scheduler is likely to
  47063. + * coincide with the desired device-throughput distribution only in the
  47064. + * following, perfectly symmetric, scenario:
  47065. + * 1) all active queues have the same weight,
  47066. + * 2) all active groups at the same level in the groups tree have the same
  47067. + * weight,
  47068. + * 3) all active groups at the same level in the groups tree have the same
  47069. + * number of children.
  47070. + *
  47071. + * Even in such a scenario, sequential I/O may still receive a preferential
  47072. + * treatment, but this is not likely to be a big issue with flash-based
  47073. + * devices, because of their non-dramatic loss of throughput with random
  47074. + * I/O. Things do differ with HDDs, for which additional care is taken, as
  47075. + * explained after completing the discussion for flash-based devices.
  47076. + *
  47077. + * Unfortunately, keeping the necessary state for evaluating exactly the
  47078. + * above symmetry conditions would be quite complex and time-consuming.
  47079. + * Therefore BFQ evaluates instead the following stronger sub-conditions,
  47080. + * for which it is much easier to maintain the needed state:
  47081. + * 1) all active queues have the same weight,
  47082. + * 2) all active groups have the same weight,
  47083. + * 3) all active groups have at most one active child each.
  47084. + * In particular, the last two conditions are always true if hierarchical
  47085. + * support and the cgroups interface are not enabled, hence no state needs
  47086. + * to be maintained in this case.
  47087. + *
  47088. + * According to the above considerations, the second component of the
  47089. + * compound condition evaluates to true if any of the above symmetry
  47090. + * sub-condition does not hold, or the device is not flash-based. Therefore,
  47091. + * if also the first component is true, then idling is allowed for a sync
  47092. + * queue. These are the only sub-conditions considered if the device is
  47093. + * flash-based, as, for such a device, it is sensible to force idling only
  47094. + * for service-guarantee issues. In fact, as for throughput, idling
  47095. + * NCQ-capable flash-based devices would not boost the throughput even
  47096. + * with sequential I/O; rather it would lower the throughput in proportion
  47097. + * to how fast the device is. In the end, (only) if all the three
  47098. + * sub-conditions hold and the device is flash-based, the compound
  47099. + * condition evaluates to false and therefore no idling is performed.
  47100. + *
  47101. + * As already said, things change with a rotational device, where idling
  47102. + * boosts the throughput with sequential I/O (even with NCQ). Hence, for
  47103. + * such a device the second component of the compound condition evaluates
  47104. + * to true also if the following additional sub-condition does not hold:
  47105. + * the queue is constantly seeky. Unfortunately, this different behavior
  47106. + * with respect to flash-based devices causes an additional asymmetry: if
  47107. + * some sync queues enjoy idling and some other sync queues do not, then
  47108. + * the latter get a low share of the device throughput, simply because the
  47109. + * former get many requests served after being set as in service, whereas
  47110. + * the latter do not. As a consequence, to guarantee the desired throughput
  47111. + * distribution, on HDDs the compound expression evaluates to true (and
  47112. + * hence device idling is performed) also if the following last symmetry
  47113. + * condition does not hold: no other queue is benefiting from idling. Also
  47114. + * this last condition is actually replaced with a simpler-to-maintain and
  47115. + * stronger condition: there is no busy queue which is not constantly seeky
  47116. + * (and hence may also benefit from idling).
  47117. + *
  47118. + * To sum up, when all the required symmetry and throughput-boosting
  47119. + * sub-conditions hold, the second component of the compound condition
  47120. + * evaluates to false, and hence no idling is performed. This helps to
  47121. + * keep the drives' internal queues full on NCQ-capable devices, and hence
  47122. + * to boost the throughput, without causing 'almost' any loss of service
  47123. + * guarantees. The 'almost' follows from the fact that, if the internal
  47124. + * queue of one such device is filled while all the sub-conditions hold,
  47125. + * but at some point in time some sub-condition stops to hold, then it may
  47126. + * become impossible to let requests be served in the new desired order
  47127. + * until all the requests already queued in the device have been served.
  47128. + */
  47129. +static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq)
  47130. +{
  47131. + struct bfq_data *bfqd = bfqq->bfqd;
  47132. +#ifdef CONFIG_CGROUP_BFQIO
  47133. +#define symmetric_scenario (!bfqd->active_numerous_groups && \
  47134. + !bfq_differentiated_weights(bfqd))
  47135. +#else
  47136. +#define symmetric_scenario (!bfq_differentiated_weights(bfqd))
  47137. +#endif
  47138. +#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \
  47139. + bfqd->busy_in_flight_queues == \
  47140. + bfqd->const_seeky_busy_in_flight_queues)
  47141. +/*
  47142. + * Condition for expiring a non-weight-raised queue (and hence not idling
  47143. + * the device).
  47144. + */
  47145. +#define cond_for_expiring_non_wr (bfqd->hw_tag && \
  47146. + (bfqd->wr_busy_queues > 0 || \
  47147. + (symmetric_scenario && \
  47148. + (blk_queue_nonrot(bfqd->queue) || \
  47149. + cond_for_seeky_on_ncq_hdd))))
  47150. +
  47151. + return bfq_bfqq_sync(bfqq) &&
  47152. + (bfq_bfqq_IO_bound(bfqq) || bfqq->wr_coeff > 1) &&
  47153. + (bfqq->wr_coeff > 1 ||
  47154. + (bfq_bfqq_idle_window(bfqq) &&
  47155. + !cond_for_expiring_non_wr)
  47156. + );
  47157. +}
  47158. +
  47159. +/*
  47160. + * If the in-service queue is empty but sync, and the function
  47161. + * bfq_bfqq_must_not_expire returns true, then:
  47162. + * 1) the queue must remain in service and cannot be expired, and
  47163. + * 2) the disk must be idled to wait for the possible arrival of a new
  47164. + * request for the queue.
  47165. + * See the comments to the function bfq_bfqq_must_not_expire for the reasons
  47166. + * why performing device idling is the best choice to boost the throughput
  47167. + * and preserve service guarantees when bfq_bfqq_must_not_expire itself
  47168. + * returns true.
  47169. + */
  47170. +static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq)
  47171. +{
  47172. + struct bfq_data *bfqd = bfqq->bfqd;
  47173. +
  47174. + return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 &&
  47175. + bfq_bfqq_must_not_expire(bfqq);
  47176. +}
  47177. +
  47178. +/*
  47179. + * Select a queue for service. If we have a current queue in service,
  47180. + * check whether to continue servicing it, or retrieve and set a new one.
  47181. + */
  47182. +static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
  47183. +{
  47184. + struct bfq_queue *bfqq;
  47185. + struct request *next_rq;
  47186. + enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT;
  47187. +
  47188. + bfqq = bfqd->in_service_queue;
  47189. + if (bfqq == NULL)
  47190. + goto new_queue;
  47191. +
  47192. + bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue");
  47193. +
  47194. + if (bfq_may_expire_for_budg_timeout(bfqq) &&
  47195. + !timer_pending(&bfqd->idle_slice_timer) &&
  47196. + !bfq_bfqq_must_idle(bfqq))
  47197. + goto expire;
  47198. +
  47199. + next_rq = bfqq->next_rq;
  47200. + /*
  47201. + * If bfqq has requests queued and it has enough budget left to
  47202. + * serve them, keep the queue, otherwise expire it.
  47203. + */
  47204. + if (next_rq != NULL) {
  47205. + if (bfq_serv_to_charge(next_rq, bfqq) >
  47206. + bfq_bfqq_budget_left(bfqq)) {
  47207. + reason = BFQ_BFQQ_BUDGET_EXHAUSTED;
  47208. + goto expire;
  47209. + } else {
  47210. + /*
  47211. + * The idle timer may be pending because we may
  47212. + * not disable disk idling even when a new request
  47213. + * arrives.
  47214. + */
  47215. + if (timer_pending(&bfqd->idle_slice_timer)) {
  47216. + /*
  47217. + * If we get here: 1) at least a new request
  47218. + * has arrived but we have not disabled the
  47219. + * timer because the request was too small,
  47220. + * 2) then the block layer has unplugged
  47221. + * the device, causing the dispatch to be
  47222. + * invoked.
  47223. + *
  47224. + * Since the device is unplugged, now the
  47225. + * requests are probably large enough to
  47226. + * provide a reasonable throughput.
  47227. + * So we disable idling.
  47228. + */
  47229. + bfq_clear_bfqq_wait_request(bfqq);
  47230. + del_timer(&bfqd->idle_slice_timer);
  47231. + }
  47232. + goto keep_queue;
  47233. + }
  47234. + }
  47235. +
  47236. + /*
  47237. + * No requests pending. If the in-service queue still has requests
  47238. + * in flight (possibly waiting for a completion) or is idling for a
  47239. + * new request, then keep it.
  47240. + */
  47241. + if (timer_pending(&bfqd->idle_slice_timer) ||
  47242. + (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq))) {
  47243. + bfqq = NULL;
  47244. + goto keep_queue;
  47245. + }
  47246. +
  47247. + reason = BFQ_BFQQ_NO_MORE_REQUESTS;
  47248. +expire:
  47249. + bfq_bfqq_expire(bfqd, bfqq, 0, reason);
  47250. +new_queue:
  47251. + bfqq = bfq_set_in_service_queue(bfqd);
  47252. + bfq_log(bfqd, "select_queue: new queue %d returned",
  47253. + bfqq != NULL ? bfqq->pid : 0);
  47254. +keep_queue:
  47255. + return bfqq;
  47256. +}
  47257. +
  47258. +static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  47259. +{
  47260. + struct bfq_entity *entity = &bfqq->entity;
  47261. + if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */
  47262. + bfq_log_bfqq(bfqd, bfqq,
  47263. + "raising period dur %u/%u msec, old coeff %u, w %d(%d)",
  47264. + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
  47265. + jiffies_to_msecs(bfqq->wr_cur_max_time),
  47266. + bfqq->wr_coeff,
  47267. + bfqq->entity.weight, bfqq->entity.orig_weight);
  47268. +
  47269. + BUG_ON(bfqq != bfqd->in_service_queue && entity->weight !=
  47270. + entity->orig_weight * bfqq->wr_coeff);
  47271. + if (entity->ioprio_changed)
  47272. + bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change");
  47273. +
  47274. + /*
  47275. + * If too much time has elapsed from the beginning
  47276. + * of this weight-raising period, or the queue has
  47277. + * exceeded the acceptable number of cooperations,
  47278. + * stop it.
  47279. + */
  47280. + if (bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh ||
  47281. + time_is_before_jiffies(bfqq->last_wr_start_finish +
  47282. + bfqq->wr_cur_max_time)) {
  47283. + bfqq->last_wr_start_finish = jiffies;
  47284. + bfq_log_bfqq(bfqd, bfqq,
  47285. + "wrais ending at %lu, rais_max_time %u",
  47286. + bfqq->last_wr_start_finish,
  47287. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  47288. + bfq_bfqq_end_wr(bfqq);
  47289. + }
  47290. + }
  47291. + /* Update weight both if it must be raised and if it must be lowered */
  47292. + if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1))
  47293. + __bfq_entity_update_weight_prio(
  47294. + bfq_entity_service_tree(entity),
  47295. + entity);
  47296. +}
  47297. +
  47298. +/*
  47299. + * Dispatch one request from bfqq, moving it to the request queue
  47300. + * dispatch list.
  47301. + */
  47302. +static int bfq_dispatch_request(struct bfq_data *bfqd,
  47303. + struct bfq_queue *bfqq)
  47304. +{
  47305. + int dispatched = 0;
  47306. + struct request *rq;
  47307. + unsigned long service_to_charge;
  47308. +
  47309. + BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
  47310. +
  47311. + /* Follow expired path, else get first next available. */
  47312. + rq = bfq_check_fifo(bfqq);
  47313. + if (rq == NULL)
  47314. + rq = bfqq->next_rq;
  47315. + service_to_charge = bfq_serv_to_charge(rq, bfqq);
  47316. +
  47317. + if (service_to_charge > bfq_bfqq_budget_left(bfqq)) {
  47318. + /*
  47319. + * This may happen if the next rq is chosen in fifo order
  47320. + * instead of sector order. The budget is properly
  47321. + * dimensioned to be always sufficient to serve the next
  47322. + * request only if it is chosen in sector order. The reason
  47323. + * is that it would be quite inefficient and little useful
  47324. + * to always make sure that the budget is large enough to
  47325. + * serve even the possible next rq in fifo order.
  47326. + * In fact, requests are seldom served in fifo order.
  47327. + *
  47328. + * Expire the queue for budget exhaustion, and make sure
  47329. + * that the next act_budget is enough to serve the next
  47330. + * request, even if it comes from the fifo expired path.
  47331. + */
  47332. + bfqq->next_rq = rq;
  47333. + /*
  47334. + * Since this dispatch is failed, make sure that
  47335. + * a new one will be performed
  47336. + */
  47337. + if (!bfqd->rq_in_driver)
  47338. + bfq_schedule_dispatch(bfqd);
  47339. + goto expire;
  47340. + }
  47341. +
  47342. + /* Finally, insert request into driver dispatch list. */
  47343. + bfq_bfqq_served(bfqq, service_to_charge);
  47344. + bfq_dispatch_insert(bfqd->queue, rq);
  47345. +
  47346. + bfq_update_wr_data(bfqd, bfqq);
  47347. +
  47348. + bfq_log_bfqq(bfqd, bfqq,
  47349. + "dispatched %u sec req (%llu), budg left %lu",
  47350. + blk_rq_sectors(rq),
  47351. + (long long unsigned)blk_rq_pos(rq),
  47352. + bfq_bfqq_budget_left(bfqq));
  47353. +
  47354. + dispatched++;
  47355. +
  47356. + if (bfqd->in_service_bic == NULL) {
  47357. + atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount);
  47358. + bfqd->in_service_bic = RQ_BIC(rq);
  47359. + }
  47360. +
  47361. + if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) &&
  47362. + dispatched >= bfqd->bfq_max_budget_async_rq) ||
  47363. + bfq_class_idle(bfqq)))
  47364. + goto expire;
  47365. +
  47366. + return dispatched;
  47367. +
  47368. +expire:
  47369. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED);
  47370. + return dispatched;
  47371. +}
  47372. +
  47373. +static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq)
  47374. +{
  47375. + int dispatched = 0;
  47376. +
  47377. + while (bfqq->next_rq != NULL) {
  47378. + bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq);
  47379. + dispatched++;
  47380. + }
  47381. +
  47382. + BUG_ON(!list_empty(&bfqq->fifo));
  47383. + return dispatched;
  47384. +}
  47385. +
  47386. +/*
  47387. + * Drain our current requests.
  47388. + * Used for barriers and when switching io schedulers on-the-fly.
  47389. + */
  47390. +static int bfq_forced_dispatch(struct bfq_data *bfqd)
  47391. +{
  47392. + struct bfq_queue *bfqq, *n;
  47393. + struct bfq_service_tree *st;
  47394. + int dispatched = 0;
  47395. +
  47396. + bfqq = bfqd->in_service_queue;
  47397. + if (bfqq != NULL)
  47398. + __bfq_bfqq_expire(bfqd, bfqq);
  47399. +
  47400. + /*
  47401. + * Loop through classes, and be careful to leave the scheduler
  47402. + * in a consistent state, as feedback mechanisms and vtime
  47403. + * updates cannot be disabled during the process.
  47404. + */
  47405. + list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) {
  47406. + st = bfq_entity_service_tree(&bfqq->entity);
  47407. +
  47408. + dispatched += __bfq_forced_dispatch_bfqq(bfqq);
  47409. + bfqq->max_budget = bfq_max_budget(bfqd);
  47410. +
  47411. + bfq_forget_idle(st);
  47412. + }
  47413. +
  47414. + BUG_ON(bfqd->busy_queues != 0);
  47415. +
  47416. + return dispatched;
  47417. +}
  47418. +
  47419. +static int bfq_dispatch_requests(struct request_queue *q, int force)
  47420. +{
  47421. + struct bfq_data *bfqd = q->elevator->elevator_data;
  47422. + struct bfq_queue *bfqq;
  47423. + int max_dispatch;
  47424. +
  47425. + bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues);
  47426. + if (bfqd->busy_queues == 0)
  47427. + return 0;
  47428. +
  47429. + if (unlikely(force))
  47430. + return bfq_forced_dispatch(bfqd);
  47431. +
  47432. + bfqq = bfq_select_queue(bfqd);
  47433. + if (bfqq == NULL)
  47434. + return 0;
  47435. +
  47436. + max_dispatch = bfqd->bfq_quantum;
  47437. + if (bfq_class_idle(bfqq))
  47438. + max_dispatch = 1;
  47439. +
  47440. + if (!bfq_bfqq_sync(bfqq))
  47441. + max_dispatch = bfqd->bfq_max_budget_async_rq;
  47442. +
  47443. + if (bfqq->dispatched >= max_dispatch) {
  47444. + if (bfqd->busy_queues > 1)
  47445. + return 0;
  47446. + if (bfqq->dispatched >= 4 * max_dispatch)
  47447. + return 0;
  47448. + }
  47449. +
  47450. + if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq))
  47451. + return 0;
  47452. +
  47453. + bfq_clear_bfqq_wait_request(bfqq);
  47454. + BUG_ON(timer_pending(&bfqd->idle_slice_timer));
  47455. +
  47456. + if (!bfq_dispatch_request(bfqd, bfqq))
  47457. + return 0;
  47458. +
  47459. + bfq_log_bfqq(bfqd, bfqq, "dispatched one request of %d (max_disp %d)",
  47460. + bfqq->pid, max_dispatch);
  47461. +
  47462. + return 1;
  47463. +}
  47464. +
  47465. +/*
  47466. + * Task holds one reference to the queue, dropped when task exits. Each rq
  47467. + * in-flight on this queue also holds a reference, dropped when rq is freed.
  47468. + *
  47469. + * Queue lock must be held here.
  47470. + */
  47471. +static void bfq_put_queue(struct bfq_queue *bfqq)
  47472. +{
  47473. + struct bfq_data *bfqd = bfqq->bfqd;
  47474. +
  47475. + BUG_ON(atomic_read(&bfqq->ref) <= 0);
  47476. +
  47477. + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq,
  47478. + atomic_read(&bfqq->ref));
  47479. + if (!atomic_dec_and_test(&bfqq->ref))
  47480. + return;
  47481. +
  47482. + BUG_ON(rb_first(&bfqq->sort_list) != NULL);
  47483. + BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0);
  47484. + BUG_ON(bfqq->entity.tree != NULL);
  47485. + BUG_ON(bfq_bfqq_busy(bfqq));
  47486. + BUG_ON(bfqd->in_service_queue == bfqq);
  47487. +
  47488. + bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq);
  47489. +
  47490. + kmem_cache_free(bfq_pool, bfqq);
  47491. +}
  47492. +
  47493. +static void bfq_put_cooperator(struct bfq_queue *bfqq)
  47494. +{
  47495. + struct bfq_queue *__bfqq, *next;
  47496. +
  47497. + /*
  47498. + * If this queue was scheduled to merge with another queue, be
  47499. + * sure to drop the reference taken on that queue (and others in
  47500. + * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs.
  47501. + */
  47502. + __bfqq = bfqq->new_bfqq;
  47503. + while (__bfqq) {
  47504. + if (__bfqq == bfqq)
  47505. + break;
  47506. + next = __bfqq->new_bfqq;
  47507. + bfq_put_queue(__bfqq);
  47508. + __bfqq = next;
  47509. + }
  47510. +}
  47511. +
  47512. +static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  47513. +{
  47514. + if (bfqq == bfqd->in_service_queue) {
  47515. + __bfq_bfqq_expire(bfqd, bfqq);
  47516. + bfq_schedule_dispatch(bfqd);
  47517. + }
  47518. +
  47519. + bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq,
  47520. + atomic_read(&bfqq->ref));
  47521. +
  47522. + bfq_put_cooperator(bfqq);
  47523. +
  47524. + bfq_put_queue(bfqq);
  47525. +}
  47526. +
  47527. +static inline void bfq_init_icq(struct io_cq *icq)
  47528. +{
  47529. + struct bfq_io_cq *bic = icq_to_bic(icq);
  47530. +
  47531. + bic->ttime.last_end_request = jiffies;
  47532. + /*
  47533. + * A newly created bic indicates that the process has just
  47534. + * started doing I/O, and is probably mapping into memory its
  47535. + * executable and libraries: it definitely needs weight raising.
  47536. + * There is however the possibility that the process performs,
  47537. + * for a while, I/O close to some other process. EQM intercepts
  47538. + * this behavior and may merge the queue corresponding to the
  47539. + * process with some other queue, BEFORE the weight of the queue
  47540. + * is raised. Merged queues are not weight-raised (they are assumed
  47541. + * to belong to processes that benefit only from high throughput).
  47542. + * If the merge is basically the consequence of an accident, then
  47543. + * the queue will be split soon and will get back its old weight.
  47544. + * It is then important to write down somewhere that this queue
  47545. + * does need weight raising, even if it did not make it to get its
  47546. + * weight raised before being merged. To this purpose, we overload
  47547. + * the field raising_time_left and assign 1 to it, to mark the queue
  47548. + * as needing weight raising.
  47549. + */
  47550. + bic->wr_time_left = 1;
  47551. +}
  47552. +
  47553. +static void bfq_exit_icq(struct io_cq *icq)
  47554. +{
  47555. + struct bfq_io_cq *bic = icq_to_bic(icq);
  47556. + struct bfq_data *bfqd = bic_to_bfqd(bic);
  47557. +
  47558. + if (bic->bfqq[BLK_RW_ASYNC]) {
  47559. + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]);
  47560. + bic->bfqq[BLK_RW_ASYNC] = NULL;
  47561. + }
  47562. +
  47563. + if (bic->bfqq[BLK_RW_SYNC]) {
  47564. + /*
  47565. + * If the bic is using a shared queue, put the reference
  47566. + * taken on the io_context when the bic started using a
  47567. + * shared bfq_queue.
  47568. + */
  47569. + if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC]))
  47570. + put_io_context(icq->ioc);
  47571. + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]);
  47572. + bic->bfqq[BLK_RW_SYNC] = NULL;
  47573. + }
  47574. +}
  47575. +
  47576. +/*
  47577. + * Update the entity prio values; note that the new values will not
  47578. + * be used until the next (re)activation.
  47579. + */
  47580. +static void bfq_init_prio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
  47581. +{
  47582. + struct task_struct *tsk = current;
  47583. + int ioprio_class;
  47584. +
  47585. + if (!bfq_bfqq_prio_changed(bfqq))
  47586. + return;
  47587. +
  47588. + ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
  47589. + switch (ioprio_class) {
  47590. + default:
  47591. + dev_err(bfqq->bfqd->queue->backing_dev_info.dev,
  47592. + "bfq: bad prio %x\n", ioprio_class);
  47593. + case IOPRIO_CLASS_NONE:
  47594. + /*
  47595. + * No prio set, inherit CPU scheduling settings.
  47596. + */
  47597. + bfqq->entity.new_ioprio = task_nice_ioprio(tsk);
  47598. + bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk);
  47599. + break;
  47600. + case IOPRIO_CLASS_RT:
  47601. + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  47602. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT;
  47603. + break;
  47604. + case IOPRIO_CLASS_BE:
  47605. + bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  47606. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE;
  47607. + break;
  47608. + case IOPRIO_CLASS_IDLE:
  47609. + bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE;
  47610. + bfqq->entity.new_ioprio = 7;
  47611. + bfq_clear_bfqq_idle_window(bfqq);
  47612. + break;
  47613. + }
  47614. +
  47615. + bfqq->entity.ioprio_changed = 1;
  47616. +
  47617. + bfq_clear_bfqq_prio_changed(bfqq);
  47618. +}
  47619. +
  47620. +static void bfq_changed_ioprio(struct bfq_io_cq *bic)
  47621. +{
  47622. + struct bfq_data *bfqd;
  47623. + struct bfq_queue *bfqq, *new_bfqq;
  47624. + struct bfq_group *bfqg;
  47625. + unsigned long uninitialized_var(flags);
  47626. + int ioprio = bic->icq.ioc->ioprio;
  47627. +
  47628. + bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
  47629. + &flags);
  47630. + /*
  47631. + * This condition may trigger on a newly created bic, be sure to
  47632. + * drop the lock before returning.
  47633. + */
  47634. + if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio))
  47635. + goto out;
  47636. +
  47637. + bfqq = bic->bfqq[BLK_RW_ASYNC];
  47638. + if (bfqq != NULL) {
  47639. + bfqg = container_of(bfqq->entity.sched_data, struct bfq_group,
  47640. + sched_data);
  47641. + new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic,
  47642. + GFP_ATOMIC);
  47643. + if (new_bfqq != NULL) {
  47644. + bic->bfqq[BLK_RW_ASYNC] = new_bfqq;
  47645. + bfq_log_bfqq(bfqd, bfqq,
  47646. + "changed_ioprio: bfqq %p %d",
  47647. + bfqq, atomic_read(&bfqq->ref));
  47648. + bfq_put_queue(bfqq);
  47649. + }
  47650. + }
  47651. +
  47652. + bfqq = bic->bfqq[BLK_RW_SYNC];
  47653. + if (bfqq != NULL)
  47654. + bfq_mark_bfqq_prio_changed(bfqq);
  47655. +
  47656. + bic->ioprio = ioprio;
  47657. +
  47658. +out:
  47659. + bfq_put_bfqd_unlock(bfqd, &flags);
  47660. +}
  47661. +
  47662. +static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  47663. + pid_t pid, int is_sync)
  47664. +{
  47665. + RB_CLEAR_NODE(&bfqq->entity.rb_node);
  47666. + INIT_LIST_HEAD(&bfqq->fifo);
  47667. +
  47668. + atomic_set(&bfqq->ref, 0);
  47669. + bfqq->bfqd = bfqd;
  47670. +
  47671. + bfq_mark_bfqq_prio_changed(bfqq);
  47672. +
  47673. + if (is_sync) {
  47674. + if (!bfq_class_idle(bfqq))
  47675. + bfq_mark_bfqq_idle_window(bfqq);
  47676. + bfq_mark_bfqq_sync(bfqq);
  47677. + }
  47678. + bfq_mark_bfqq_IO_bound(bfqq);
  47679. +
  47680. + /* Tentative initial value to trade off between thr and lat */
  47681. + bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3;
  47682. + bfqq->pid = pid;
  47683. +
  47684. + bfqq->wr_coeff = 1;
  47685. + bfqq->last_wr_start_finish = 0;
  47686. + /*
  47687. + * Set to the value for which bfqq will not be deemed as
  47688. + * soft rt when it becomes backlogged.
  47689. + */
  47690. + bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies);
  47691. +}
  47692. +
  47693. +static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd,
  47694. + struct bfq_group *bfqg,
  47695. + int is_sync,
  47696. + struct bfq_io_cq *bic,
  47697. + gfp_t gfp_mask)
  47698. +{
  47699. + struct bfq_queue *bfqq, *new_bfqq = NULL;
  47700. +
  47701. +retry:
  47702. + /* bic always exists here */
  47703. + bfqq = bic_to_bfqq(bic, is_sync);
  47704. +
  47705. + /*
  47706. + * Always try a new alloc if we fall back to the OOM bfqq
  47707. + * originally, since it should just be a temporary situation.
  47708. + */
  47709. + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) {
  47710. + bfqq = NULL;
  47711. + if (new_bfqq != NULL) {
  47712. + bfqq = new_bfqq;
  47713. + new_bfqq = NULL;
  47714. + } else if (gfp_mask & __GFP_WAIT) {
  47715. + spin_unlock_irq(bfqd->queue->queue_lock);
  47716. + new_bfqq = kmem_cache_alloc_node(bfq_pool,
  47717. + gfp_mask | __GFP_ZERO,
  47718. + bfqd->queue->node);
  47719. + spin_lock_irq(bfqd->queue->queue_lock);
  47720. + if (new_bfqq != NULL)
  47721. + goto retry;
  47722. + } else {
  47723. + bfqq = kmem_cache_alloc_node(bfq_pool,
  47724. + gfp_mask | __GFP_ZERO,
  47725. + bfqd->queue->node);
  47726. + }
  47727. +
  47728. + if (bfqq != NULL) {
  47729. + bfq_init_bfqq(bfqd, bfqq, current->pid, is_sync);
  47730. + bfq_log_bfqq(bfqd, bfqq, "allocated");
  47731. + } else {
  47732. + bfqq = &bfqd->oom_bfqq;
  47733. + bfq_log_bfqq(bfqd, bfqq, "using oom bfqq");
  47734. + }
  47735. +
  47736. + bfq_init_prio_data(bfqq, bic);
  47737. + bfq_init_entity(&bfqq->entity, bfqg);
  47738. + }
  47739. +
  47740. + if (new_bfqq != NULL)
  47741. + kmem_cache_free(bfq_pool, new_bfqq);
  47742. +
  47743. + return bfqq;
  47744. +}
  47745. +
  47746. +static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
  47747. + struct bfq_group *bfqg,
  47748. + int ioprio_class, int ioprio)
  47749. +{
  47750. + switch (ioprio_class) {
  47751. + case IOPRIO_CLASS_RT:
  47752. + return &bfqg->async_bfqq[0][ioprio];
  47753. + case IOPRIO_CLASS_NONE:
  47754. + ioprio = IOPRIO_NORM;
  47755. + /* fall through */
  47756. + case IOPRIO_CLASS_BE:
  47757. + return &bfqg->async_bfqq[1][ioprio];
  47758. + case IOPRIO_CLASS_IDLE:
  47759. + return &bfqg->async_idle_bfqq;
  47760. + default:
  47761. + BUG();
  47762. + }
  47763. +}
  47764. +
  47765. +static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
  47766. + struct bfq_group *bfqg, int is_sync,
  47767. + struct bfq_io_cq *bic, gfp_t gfp_mask)
  47768. +{
  47769. + const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
  47770. + const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
  47771. + struct bfq_queue **async_bfqq = NULL;
  47772. + struct bfq_queue *bfqq = NULL;
  47773. +
  47774. + if (!is_sync) {
  47775. + async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class,
  47776. + ioprio);
  47777. + bfqq = *async_bfqq;
  47778. + }
  47779. +
  47780. + if (bfqq == NULL)
  47781. + bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask);
  47782. +
  47783. + /*
  47784. + * Pin the queue now that it's allocated, scheduler exit will
  47785. + * prune it.
  47786. + */
  47787. + if (!is_sync && *async_bfqq == NULL) {
  47788. + atomic_inc(&bfqq->ref);
  47789. + bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
  47790. + bfqq, atomic_read(&bfqq->ref));
  47791. + *async_bfqq = bfqq;
  47792. + }
  47793. +
  47794. + atomic_inc(&bfqq->ref);
  47795. + bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq,
  47796. + atomic_read(&bfqq->ref));
  47797. + return bfqq;
  47798. +}
  47799. +
  47800. +static void bfq_update_io_thinktime(struct bfq_data *bfqd,
  47801. + struct bfq_io_cq *bic)
  47802. +{
  47803. + unsigned long elapsed = jiffies - bic->ttime.last_end_request;
  47804. + unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle);
  47805. +
  47806. + bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8;
  47807. + bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8;
  47808. + bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) /
  47809. + bic->ttime.ttime_samples;
  47810. +}
  47811. +
  47812. +static void bfq_update_io_seektime(struct bfq_data *bfqd,
  47813. + struct bfq_queue *bfqq,
  47814. + struct request *rq)
  47815. +{
  47816. + sector_t sdist;
  47817. + u64 total;
  47818. +
  47819. + if (bfqq->last_request_pos < blk_rq_pos(rq))
  47820. + sdist = blk_rq_pos(rq) - bfqq->last_request_pos;
  47821. + else
  47822. + sdist = bfqq->last_request_pos - blk_rq_pos(rq);
  47823. +
  47824. + /*
  47825. + * Don't allow the seek distance to get too large from the
  47826. + * odd fragment, pagein, etc.
  47827. + */
  47828. + if (bfqq->seek_samples == 0) /* first request, not really a seek */
  47829. + sdist = 0;
  47830. + else if (bfqq->seek_samples <= 60) /* second & third seek */
  47831. + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024);
  47832. + else
  47833. + sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64);
  47834. +
  47835. + bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8;
  47836. + bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8;
  47837. + total = bfqq->seek_total + (bfqq->seek_samples/2);
  47838. + do_div(total, bfqq->seek_samples);
  47839. + bfqq->seek_mean = (sector_t)total;
  47840. +
  47841. + bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist,
  47842. + (u64)bfqq->seek_mean);
  47843. +}
  47844. +
  47845. +/*
  47846. + * Disable idle window if the process thinks too long or seeks so much that
  47847. + * it doesn't matter.
  47848. + */
  47849. +static void bfq_update_idle_window(struct bfq_data *bfqd,
  47850. + struct bfq_queue *bfqq,
  47851. + struct bfq_io_cq *bic)
  47852. +{
  47853. + int enable_idle;
  47854. +
  47855. + /* Don't idle for async or idle io prio class. */
  47856. + if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq))
  47857. + return;
  47858. +
  47859. + /* Idle window just restored, statistics are meaningless. */
  47860. + if (bfq_bfqq_just_split(bfqq))
  47861. + return;
  47862. +
  47863. + enable_idle = bfq_bfqq_idle_window(bfqq);
  47864. +
  47865. + if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
  47866. + bfqd->bfq_slice_idle == 0 ||
  47867. + (bfqd->hw_tag && BFQQ_SEEKY(bfqq) &&
  47868. + bfqq->wr_coeff == 1))
  47869. + enable_idle = 0;
  47870. + else if (bfq_sample_valid(bic->ttime.ttime_samples)) {
  47871. + if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle &&
  47872. + bfqq->wr_coeff == 1)
  47873. + enable_idle = 0;
  47874. + else
  47875. + enable_idle = 1;
  47876. + }
  47877. + bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d",
  47878. + enable_idle);
  47879. +
  47880. + if (enable_idle)
  47881. + bfq_mark_bfqq_idle_window(bfqq);
  47882. + else
  47883. + bfq_clear_bfqq_idle_window(bfqq);
  47884. +}
  47885. +
  47886. +/*
  47887. + * Called when a new fs request (rq) is added to bfqq. Check if there's
  47888. + * something we should do about it.
  47889. + */
  47890. +static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  47891. + struct request *rq)
  47892. +{
  47893. + struct bfq_io_cq *bic = RQ_BIC(rq);
  47894. +
  47895. + if (rq->cmd_flags & REQ_META)
  47896. + bfqq->meta_pending++;
  47897. +
  47898. + bfq_update_io_thinktime(bfqd, bic);
  47899. + bfq_update_io_seektime(bfqd, bfqq, rq);
  47900. + if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) {
  47901. + bfq_clear_bfqq_constantly_seeky(bfqq);
  47902. + if (!blk_queue_nonrot(bfqd->queue)) {
  47903. + BUG_ON(!bfqd->const_seeky_busy_in_flight_queues);
  47904. + bfqd->const_seeky_busy_in_flight_queues--;
  47905. + }
  47906. + }
  47907. + if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
  47908. + !BFQQ_SEEKY(bfqq))
  47909. + bfq_update_idle_window(bfqd, bfqq, bic);
  47910. + bfq_clear_bfqq_just_split(bfqq);
  47911. +
  47912. + bfq_log_bfqq(bfqd, bfqq,
  47913. + "rq_enqueued: idle_window=%d (seeky %d, mean %llu)",
  47914. + bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq),
  47915. + (long long unsigned)bfqq->seek_mean);
  47916. +
  47917. + bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
  47918. +
  47919. + if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) {
  47920. + int small_req = bfqq->queued[rq_is_sync(rq)] == 1 &&
  47921. + blk_rq_sectors(rq) < 32;
  47922. + int budget_timeout = bfq_bfqq_budget_timeout(bfqq);
  47923. +
  47924. + /*
  47925. + * There is just this request queued: if the request
  47926. + * is small and the queue is not to be expired, then
  47927. + * just exit.
  47928. + *
  47929. + * In this way, if the disk is being idled to wait for
  47930. + * a new request from the in-service queue, we avoid
  47931. + * unplugging the device and committing the disk to serve
  47932. + * just a small request. On the contrary, we wait for
  47933. + * the block layer to decide when to unplug the device:
  47934. + * hopefully, new requests will be merged to this one
  47935. + * quickly, then the device will be unplugged and
  47936. + * larger requests will be dispatched.
  47937. + */
  47938. + if (small_req && !budget_timeout)
  47939. + return;
  47940. +
  47941. + /*
  47942. + * A large enough request arrived, or the queue is to
  47943. + * be expired: in both cases disk idling is to be
  47944. + * stopped, so clear wait_request flag and reset
  47945. + * timer.
  47946. + */
  47947. + bfq_clear_bfqq_wait_request(bfqq);
  47948. + del_timer(&bfqd->idle_slice_timer);
  47949. +
  47950. + /*
  47951. + * The queue is not empty, because a new request just
  47952. + * arrived. Hence we can safely expire the queue, in
  47953. + * case of budget timeout, without risking that the
  47954. + * timestamps of the queue are not updated correctly.
  47955. + * See [1] for more details.
  47956. + */
  47957. + if (budget_timeout)
  47958. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT);
  47959. +
  47960. + /*
  47961. + * Let the request rip immediately, or let a new queue be
  47962. + * selected if bfqq has just been expired.
  47963. + */
  47964. + __blk_run_queue(bfqd->queue);
  47965. + }
  47966. +}
  47967. +
  47968. +static void bfq_insert_request(struct request_queue *q, struct request *rq)
  47969. +{
  47970. + struct bfq_data *bfqd = q->elevator->elevator_data;
  47971. + struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq;
  47972. +
  47973. + assert_spin_locked(bfqd->queue->queue_lock);
  47974. +
  47975. + /*
  47976. + * An unplug may trigger a requeue of a request from the device
  47977. + * driver: make sure we are in process context while trying to
  47978. + * merge two bfq_queues.
  47979. + */
  47980. + if (!in_interrupt()) {
  47981. + new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true);
  47982. + if (new_bfqq != NULL) {
  47983. + if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq)
  47984. + new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1);
  47985. + /*
  47986. + * Release the request's reference to the old bfqq
  47987. + * and make sure one is taken to the shared queue.
  47988. + */
  47989. + new_bfqq->allocated[rq_data_dir(rq)]++;
  47990. + bfqq->allocated[rq_data_dir(rq)]--;
  47991. + atomic_inc(&new_bfqq->ref);
  47992. + bfq_put_queue(bfqq);
  47993. + if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
  47994. + bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
  47995. + bfqq, new_bfqq);
  47996. + rq->elv.priv[1] = new_bfqq;
  47997. + bfqq = new_bfqq;
  47998. + } else
  47999. + bfq_bfqq_increase_failed_cooperations(bfqq);
  48000. + }
  48001. +
  48002. + bfq_init_prio_data(bfqq, RQ_BIC(rq));
  48003. +
  48004. + bfq_add_request(rq);
  48005. +
  48006. + /*
  48007. + * Here a newly-created bfq_queue has already started a weight-raising
  48008. + * period: clear raising_time_left to prevent bfq_bfqq_save_state()
  48009. + * from assigning it a full weight-raising period. See the detailed
  48010. + * comments about this field in bfq_init_icq().
  48011. + */
  48012. + if (bfqq->bic != NULL)
  48013. + bfqq->bic->wr_time_left = 0;
  48014. + rq_set_fifo_time(rq, jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]);
  48015. + list_add_tail(&rq->queuelist, &bfqq->fifo);
  48016. +
  48017. + bfq_rq_enqueued(bfqd, bfqq, rq);
  48018. +}
  48019. +
  48020. +static void bfq_update_hw_tag(struct bfq_data *bfqd)
  48021. +{
  48022. + bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver,
  48023. + bfqd->rq_in_driver);
  48024. +
  48025. + if (bfqd->hw_tag == 1)
  48026. + return;
  48027. +
  48028. + /*
  48029. + * This sample is valid if the number of outstanding requests
  48030. + * is large enough to allow a queueing behavior. Note that the
  48031. + * sum is not exact, as it's not taking into account deactivated
  48032. + * requests.
  48033. + */
  48034. + if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD)
  48035. + return;
  48036. +
  48037. + if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES)
  48038. + return;
  48039. +
  48040. + bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD;
  48041. + bfqd->max_rq_in_driver = 0;
  48042. + bfqd->hw_tag_samples = 0;
  48043. +}
  48044. +
  48045. +static void bfq_completed_request(struct request_queue *q, struct request *rq)
  48046. +{
  48047. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  48048. + struct bfq_data *bfqd = bfqq->bfqd;
  48049. + bool sync = bfq_bfqq_sync(bfqq);
  48050. +
  48051. + bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)",
  48052. + blk_rq_sectors(rq), sync);
  48053. +
  48054. + bfq_update_hw_tag(bfqd);
  48055. +
  48056. + BUG_ON(!bfqd->rq_in_driver);
  48057. + BUG_ON(!bfqq->dispatched);
  48058. + bfqd->rq_in_driver--;
  48059. + bfqq->dispatched--;
  48060. +
  48061. + if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) {
  48062. + bfq_weights_tree_remove(bfqd, &bfqq->entity,
  48063. + &bfqd->queue_weights_tree);
  48064. + if (!blk_queue_nonrot(bfqd->queue)) {
  48065. + BUG_ON(!bfqd->busy_in_flight_queues);
  48066. + bfqd->busy_in_flight_queues--;
  48067. + if (bfq_bfqq_constantly_seeky(bfqq)) {
  48068. + BUG_ON(!bfqd->
  48069. + const_seeky_busy_in_flight_queues);
  48070. + bfqd->const_seeky_busy_in_flight_queues--;
  48071. + }
  48072. + }
  48073. + }
  48074. +
  48075. + if (sync) {
  48076. + bfqd->sync_flight--;
  48077. + RQ_BIC(rq)->ttime.last_end_request = jiffies;
  48078. + }
  48079. +
  48080. + /*
  48081. + * If we are waiting to discover whether the request pattern of the
  48082. + * task associated with the queue is actually isochronous, and
  48083. + * both requisites for this condition to hold are satisfied, then
  48084. + * compute soft_rt_next_start (see the comments to the function
  48085. + * bfq_bfqq_softrt_next_start()).
  48086. + */
  48087. + if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 &&
  48088. + RB_EMPTY_ROOT(&bfqq->sort_list))
  48089. + bfqq->soft_rt_next_start =
  48090. + bfq_bfqq_softrt_next_start(bfqd, bfqq);
  48091. +
  48092. + /*
  48093. + * If this is the in-service queue, check if it needs to be expired,
  48094. + * or if we want to idle in case it has no pending requests.
  48095. + */
  48096. + if (bfqd->in_service_queue == bfqq) {
  48097. + if (bfq_bfqq_budget_new(bfqq))
  48098. + bfq_set_budget_timeout(bfqd);
  48099. +
  48100. + if (bfq_bfqq_must_idle(bfqq)) {
  48101. + bfq_arm_slice_timer(bfqd);
  48102. + goto out;
  48103. + } else if (bfq_may_expire_for_budg_timeout(bfqq))
  48104. + bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT);
  48105. + else if (RB_EMPTY_ROOT(&bfqq->sort_list) &&
  48106. + (bfqq->dispatched == 0 ||
  48107. + !bfq_bfqq_must_not_expire(bfqq)))
  48108. + bfq_bfqq_expire(bfqd, bfqq, 0,
  48109. + BFQ_BFQQ_NO_MORE_REQUESTS);
  48110. + }
  48111. +
  48112. + if (!bfqd->rq_in_driver)
  48113. + bfq_schedule_dispatch(bfqd);
  48114. +
  48115. +out:
  48116. + return;
  48117. +}
  48118. +
  48119. +static inline int __bfq_may_queue(struct bfq_queue *bfqq)
  48120. +{
  48121. + if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) {
  48122. + bfq_clear_bfqq_must_alloc(bfqq);
  48123. + return ELV_MQUEUE_MUST;
  48124. + }
  48125. +
  48126. + return ELV_MQUEUE_MAY;
  48127. +}
  48128. +
  48129. +static int bfq_may_queue(struct request_queue *q, int rw)
  48130. +{
  48131. + struct bfq_data *bfqd = q->elevator->elevator_data;
  48132. + struct task_struct *tsk = current;
  48133. + struct bfq_io_cq *bic;
  48134. + struct bfq_queue *bfqq;
  48135. +
  48136. + /*
  48137. + * Don't force setup of a queue from here, as a call to may_queue
  48138. + * does not necessarily imply that a request actually will be
  48139. + * queued. So just lookup a possibly existing queue, or return
  48140. + * 'may queue' if that fails.
  48141. + */
  48142. + bic = bfq_bic_lookup(bfqd, tsk->io_context);
  48143. + if (bic == NULL)
  48144. + return ELV_MQUEUE_MAY;
  48145. +
  48146. + bfqq = bic_to_bfqq(bic, rw_is_sync(rw));
  48147. + if (bfqq != NULL) {
  48148. + bfq_init_prio_data(bfqq, bic);
  48149. +
  48150. + return __bfq_may_queue(bfqq);
  48151. + }
  48152. +
  48153. + return ELV_MQUEUE_MAY;
  48154. +}
  48155. +
  48156. +/*
  48157. + * Queue lock held here.
  48158. + */
  48159. +static void bfq_put_request(struct request *rq)
  48160. +{
  48161. + struct bfq_queue *bfqq = RQ_BFQQ(rq);
  48162. +
  48163. + if (bfqq != NULL) {
  48164. + const int rw = rq_data_dir(rq);
  48165. +
  48166. + BUG_ON(!bfqq->allocated[rw]);
  48167. + bfqq->allocated[rw]--;
  48168. +
  48169. + rq->elv.priv[0] = NULL;
  48170. + rq->elv.priv[1] = NULL;
  48171. +
  48172. + bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d",
  48173. + bfqq, atomic_read(&bfqq->ref));
  48174. + bfq_put_queue(bfqq);
  48175. + }
  48176. +}
  48177. +
  48178. +/*
  48179. + * Returns NULL if a new bfqq should be allocated, or the old bfqq if this
  48180. + * was the last process referring to said bfqq.
  48181. + */
  48182. +static struct bfq_queue *
  48183. +bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
  48184. +{
  48185. + bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
  48186. +
  48187. + put_io_context(bic->icq.ioc);
  48188. +
  48189. + if (bfqq_process_refs(bfqq) == 1) {
  48190. + bfqq->pid = current->pid;
  48191. + bfq_clear_bfqq_coop(bfqq);
  48192. + bfq_clear_bfqq_split_coop(bfqq);
  48193. + return bfqq;
  48194. + }
  48195. +
  48196. + bic_set_bfqq(bic, NULL, 1);
  48197. +
  48198. + bfq_put_cooperator(bfqq);
  48199. +
  48200. + bfq_put_queue(bfqq);
  48201. + return NULL;
  48202. +}
  48203. +
  48204. +/*
  48205. + * Allocate bfq data structures associated with this request.
  48206. + */
  48207. +static int bfq_set_request(struct request_queue *q, struct request *rq,
  48208. + struct bio *bio, gfp_t gfp_mask)
  48209. +{
  48210. + struct bfq_data *bfqd = q->elevator->elevator_data;
  48211. + struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq);
  48212. + const int rw = rq_data_dir(rq);
  48213. + const int is_sync = rq_is_sync(rq);
  48214. + struct bfq_queue *bfqq;
  48215. + struct bfq_group *bfqg;
  48216. + unsigned long flags;
  48217. + bool split = false;
  48218. +
  48219. + might_sleep_if(gfp_mask & __GFP_WAIT);
  48220. +
  48221. + bfq_changed_ioprio(bic);
  48222. +
  48223. + spin_lock_irqsave(q->queue_lock, flags);
  48224. +
  48225. + if (bic == NULL)
  48226. + goto queue_fail;
  48227. +
  48228. + bfqg = bfq_bic_update_cgroup(bic);
  48229. +
  48230. +new_queue:
  48231. + bfqq = bic_to_bfqq(bic, is_sync);
  48232. + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) {
  48233. + bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask);
  48234. + bic_set_bfqq(bic, bfqq, is_sync);
  48235. + } else {
  48236. + /* If the queue was seeky for too long, break it apart. */
  48237. + if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) {
  48238. + bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq");
  48239. + bfqq = bfq_split_bfqq(bic, bfqq);
  48240. + split = true;
  48241. + if (!bfqq)
  48242. + goto new_queue;
  48243. + }
  48244. + }
  48245. +
  48246. + bfqq->allocated[rw]++;
  48247. + atomic_inc(&bfqq->ref);
  48248. + bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq,
  48249. + atomic_read(&bfqq->ref));
  48250. +
  48251. + rq->elv.priv[0] = bic;
  48252. + rq->elv.priv[1] = bfqq;
  48253. +
  48254. + /*
  48255. + * If a bfq_queue has only one process reference, it is owned
  48256. + * by only one bfq_io_cq: we can set the bic field of the
  48257. + * bfq_queue to the address of that structure. Also, if the
  48258. + * queue has just been split, mark a flag so that the
  48259. + * information is available to the other scheduler hooks.
  48260. + */
  48261. + if (bfqq_process_refs(bfqq) == 1) {
  48262. + bfqq->bic = bic;
  48263. + if (split) {
  48264. + bfq_mark_bfqq_just_split(bfqq);
  48265. + /*
  48266. + * If the queue has just been split from a shared
  48267. + * queue, restore the idle window and the possible
  48268. + * weight raising period.
  48269. + */
  48270. + bfq_bfqq_resume_state(bfqq, bic);
  48271. + }
  48272. + }
  48273. +
  48274. + spin_unlock_irqrestore(q->queue_lock, flags);
  48275. +
  48276. + return 0;
  48277. +
  48278. +queue_fail:
  48279. + bfq_schedule_dispatch(bfqd);
  48280. + spin_unlock_irqrestore(q->queue_lock, flags);
  48281. +
  48282. + return 1;
  48283. +}
  48284. +
  48285. +static void bfq_kick_queue(struct work_struct *work)
  48286. +{
  48287. + struct bfq_data *bfqd =
  48288. + container_of(work, struct bfq_data, unplug_work);
  48289. + struct request_queue *q = bfqd->queue;
  48290. +
  48291. + spin_lock_irq(q->queue_lock);
  48292. + __blk_run_queue(q);
  48293. + spin_unlock_irq(q->queue_lock);
  48294. +}
  48295. +
  48296. +/*
  48297. + * Handler of the expiration of the timer running if the in-service queue
  48298. + * is idling inside its time slice.
  48299. + */
  48300. +static void bfq_idle_slice_timer(unsigned long data)
  48301. +{
  48302. + struct bfq_data *bfqd = (struct bfq_data *)data;
  48303. + struct bfq_queue *bfqq;
  48304. + unsigned long flags;
  48305. + enum bfqq_expiration reason;
  48306. +
  48307. + spin_lock_irqsave(bfqd->queue->queue_lock, flags);
  48308. +
  48309. + bfqq = bfqd->in_service_queue;
  48310. + /*
  48311. + * Theoretical race here: the in-service queue can be NULL or
  48312. + * different from the queue that was idling if the timer handler
  48313. + * spins on the queue_lock and a new request arrives for the
  48314. + * current queue and there is a full dispatch cycle that changes
  48315. + * the in-service queue. This can hardly happen, but in the worst
  48316. + * case we just expire a queue too early.
  48317. + */
  48318. + if (bfqq != NULL) {
  48319. + bfq_log_bfqq(bfqd, bfqq, "slice_timer expired");
  48320. + if (bfq_bfqq_budget_timeout(bfqq))
  48321. + /*
  48322. + * Also here the queue can be safely expired
  48323. + * for budget timeout without wasting
  48324. + * guarantees
  48325. + */
  48326. + reason = BFQ_BFQQ_BUDGET_TIMEOUT;
  48327. + else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0)
  48328. + /*
  48329. + * The queue may not be empty upon timer expiration,
  48330. + * because we may not disable the timer when the
  48331. + * first request of the in-service queue arrives
  48332. + * during disk idling.
  48333. + */
  48334. + reason = BFQ_BFQQ_TOO_IDLE;
  48335. + else
  48336. + goto schedule_dispatch;
  48337. +
  48338. + bfq_bfqq_expire(bfqd, bfqq, 1, reason);
  48339. + }
  48340. +
  48341. +schedule_dispatch:
  48342. + bfq_schedule_dispatch(bfqd);
  48343. +
  48344. + spin_unlock_irqrestore(bfqd->queue->queue_lock, flags);
  48345. +}
  48346. +
  48347. +static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
  48348. +{
  48349. + del_timer_sync(&bfqd->idle_slice_timer);
  48350. + cancel_work_sync(&bfqd->unplug_work);
  48351. +}
  48352. +
  48353. +static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd,
  48354. + struct bfq_queue **bfqq_ptr)
  48355. +{
  48356. + struct bfq_group *root_group = bfqd->root_group;
  48357. + struct bfq_queue *bfqq = *bfqq_ptr;
  48358. +
  48359. + bfq_log(bfqd, "put_async_bfqq: %p", bfqq);
  48360. + if (bfqq != NULL) {
  48361. + bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group);
  48362. + bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d",
  48363. + bfqq, atomic_read(&bfqq->ref));
  48364. + bfq_put_queue(bfqq);
  48365. + *bfqq_ptr = NULL;
  48366. + }
  48367. +}
  48368. +
  48369. +/*
  48370. + * Release all the bfqg references to its async queues. If we are
  48371. + * deallocating the group these queues may still contain requests, so
  48372. + * we reparent them to the root cgroup (i.e., the only one that will
  48373. + * exist for sure until all the requests on a device are gone).
  48374. + */
  48375. +static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
  48376. +{
  48377. + int i, j;
  48378. +
  48379. + for (i = 0; i < 2; i++)
  48380. + for (j = 0; j < IOPRIO_BE_NR; j++)
  48381. + __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]);
  48382. +
  48383. + __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
  48384. +}
  48385. +
  48386. +static void bfq_exit_queue(struct elevator_queue *e)
  48387. +{
  48388. + struct bfq_data *bfqd = e->elevator_data;
  48389. + struct request_queue *q = bfqd->queue;
  48390. + struct bfq_queue *bfqq, *n;
  48391. +
  48392. + bfq_shutdown_timer_wq(bfqd);
  48393. +
  48394. + spin_lock_irq(q->queue_lock);
  48395. +
  48396. + BUG_ON(bfqd->in_service_queue != NULL);
  48397. + list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list)
  48398. + bfq_deactivate_bfqq(bfqd, bfqq, 0);
  48399. +
  48400. + bfq_disconnect_groups(bfqd);
  48401. + spin_unlock_irq(q->queue_lock);
  48402. +
  48403. + bfq_shutdown_timer_wq(bfqd);
  48404. +
  48405. + synchronize_rcu();
  48406. +
  48407. + BUG_ON(timer_pending(&bfqd->idle_slice_timer));
  48408. +
  48409. + bfq_free_root_group(bfqd);
  48410. + kfree(bfqd);
  48411. +}
  48412. +
  48413. +static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
  48414. +{
  48415. + struct bfq_group *bfqg;
  48416. + struct bfq_data *bfqd;
  48417. + struct elevator_queue *eq;
  48418. +
  48419. + eq = elevator_alloc(q, e);
  48420. + if (eq == NULL)
  48421. + return -ENOMEM;
  48422. +
  48423. + bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node);
  48424. + if (bfqd == NULL) {
  48425. + kobject_put(&eq->kobj);
  48426. + return -ENOMEM;
  48427. + }
  48428. + eq->elevator_data = bfqd;
  48429. +
  48430. + /*
  48431. + * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues.
  48432. + * Grab a permanent reference to it, so that the normal code flow
  48433. + * will not attempt to free it.
  48434. + */
  48435. + bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, 1, 0);
  48436. + atomic_inc(&bfqd->oom_bfqq.ref);
  48437. +
  48438. + bfqd->queue = q;
  48439. +
  48440. + spin_lock_irq(q->queue_lock);
  48441. + q->elevator = eq;
  48442. + spin_unlock_irq(q->queue_lock);
  48443. +
  48444. + bfqg = bfq_alloc_root_group(bfqd, q->node);
  48445. + if (bfqg == NULL) {
  48446. + kfree(bfqd);
  48447. + kobject_put(&eq->kobj);
  48448. + return -ENOMEM;
  48449. + }
  48450. +
  48451. + bfqd->root_group = bfqg;
  48452. +#ifdef CONFIG_CGROUP_BFQIO
  48453. + bfqd->active_numerous_groups = 0;
  48454. +#endif
  48455. +
  48456. + init_timer(&bfqd->idle_slice_timer);
  48457. + bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
  48458. + bfqd->idle_slice_timer.data = (unsigned long)bfqd;
  48459. +
  48460. + bfqd->rq_pos_tree = RB_ROOT;
  48461. + bfqd->queue_weights_tree = RB_ROOT;
  48462. + bfqd->group_weights_tree = RB_ROOT;
  48463. +
  48464. + INIT_WORK(&bfqd->unplug_work, bfq_kick_queue);
  48465. +
  48466. + INIT_LIST_HEAD(&bfqd->active_list);
  48467. + INIT_LIST_HEAD(&bfqd->idle_list);
  48468. +
  48469. + bfqd->hw_tag = -1;
  48470. +
  48471. + bfqd->bfq_max_budget = bfq_default_max_budget;
  48472. +
  48473. + bfqd->bfq_quantum = bfq_quantum;
  48474. + bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0];
  48475. + bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1];
  48476. + bfqd->bfq_back_max = bfq_back_max;
  48477. + bfqd->bfq_back_penalty = bfq_back_penalty;
  48478. + bfqd->bfq_slice_idle = bfq_slice_idle;
  48479. + bfqd->bfq_class_idle_last_service = 0;
  48480. + bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq;
  48481. + bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async;
  48482. + bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync;
  48483. +
  48484. + bfqd->bfq_coop_thresh = 2;
  48485. + bfqd->bfq_failed_cooperations = 7000;
  48486. + bfqd->bfq_requests_within_timer = 120;
  48487. +
  48488. + bfqd->low_latency = true;
  48489. +
  48490. + bfqd->bfq_wr_coeff = 20;
  48491. + bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300);
  48492. + bfqd->bfq_wr_max_time = 0;
  48493. + bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000);
  48494. + bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500);
  48495. + bfqd->bfq_wr_max_softrt_rate = 7000; /*
  48496. + * Approximate rate required
  48497. + * to playback or record a
  48498. + * high-definition compressed
  48499. + * video.
  48500. + */
  48501. + bfqd->wr_busy_queues = 0;
  48502. + bfqd->busy_in_flight_queues = 0;
  48503. + bfqd->const_seeky_busy_in_flight_queues = 0;
  48504. +
  48505. + /*
  48506. + * Begin by assuming, optimistically, that the device peak rate is
  48507. + * equal to the highest reference rate.
  48508. + */
  48509. + bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] *
  48510. + T_fast[blk_queue_nonrot(bfqd->queue)];
  48511. + bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)];
  48512. + bfqd->device_speed = BFQ_BFQD_FAST;
  48513. +
  48514. + return 0;
  48515. +}
  48516. +
  48517. +static void bfq_slab_kill(void)
  48518. +{
  48519. + if (bfq_pool != NULL)
  48520. + kmem_cache_destroy(bfq_pool);
  48521. +}
  48522. +
  48523. +static int __init bfq_slab_setup(void)
  48524. +{
  48525. + bfq_pool = KMEM_CACHE(bfq_queue, 0);
  48526. + if (bfq_pool == NULL)
  48527. + return -ENOMEM;
  48528. + return 0;
  48529. +}
  48530. +
  48531. +static ssize_t bfq_var_show(unsigned int var, char *page)
  48532. +{
  48533. + return sprintf(page, "%d\n", var);
  48534. +}
  48535. +
  48536. +static ssize_t bfq_var_store(unsigned long *var, const char *page,
  48537. + size_t count)
  48538. +{
  48539. + unsigned long new_val;
  48540. + int ret = kstrtoul(page, 10, &new_val);
  48541. +
  48542. + if (ret == 0)
  48543. + *var = new_val;
  48544. +
  48545. + return count;
  48546. +}
  48547. +
  48548. +static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page)
  48549. +{
  48550. + struct bfq_data *bfqd = e->elevator_data;
  48551. + return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ?
  48552. + jiffies_to_msecs(bfqd->bfq_wr_max_time) :
  48553. + jiffies_to_msecs(bfq_wr_duration(bfqd)));
  48554. +}
  48555. +
  48556. +static ssize_t bfq_weights_show(struct elevator_queue *e, char *page)
  48557. +{
  48558. + struct bfq_queue *bfqq;
  48559. + struct bfq_data *bfqd = e->elevator_data;
  48560. + ssize_t num_char = 0;
  48561. +
  48562. + num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n",
  48563. + bfqd->queued);
  48564. +
  48565. + spin_lock_irq(bfqd->queue->queue_lock);
  48566. +
  48567. + num_char += sprintf(page + num_char, "Active:\n");
  48568. + list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) {
  48569. + num_char += sprintf(page + num_char,
  48570. + "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n",
  48571. + bfqq->pid,
  48572. + bfqq->entity.weight,
  48573. + bfqq->queued[0],
  48574. + bfqq->queued[1],
  48575. + jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
  48576. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  48577. + }
  48578. +
  48579. + num_char += sprintf(page + num_char, "Idle:\n");
  48580. + list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) {
  48581. + num_char += sprintf(page + num_char,
  48582. + "pid%d: weight %hu, dur %d/%u\n",
  48583. + bfqq->pid,
  48584. + bfqq->entity.weight,
  48585. + jiffies_to_msecs(jiffies -
  48586. + bfqq->last_wr_start_finish),
  48587. + jiffies_to_msecs(bfqq->wr_cur_max_time));
  48588. + }
  48589. +
  48590. + spin_unlock_irq(bfqd->queue->queue_lock);
  48591. +
  48592. + return num_char;
  48593. +}
  48594. +
  48595. +#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
  48596. +static ssize_t __FUNC(struct elevator_queue *e, char *page) \
  48597. +{ \
  48598. + struct bfq_data *bfqd = e->elevator_data; \
  48599. + unsigned int __data = __VAR; \
  48600. + if (__CONV) \
  48601. + __data = jiffies_to_msecs(__data); \
  48602. + return bfq_var_show(__data, (page)); \
  48603. +}
  48604. +SHOW_FUNCTION(bfq_quantum_show, bfqd->bfq_quantum, 0);
  48605. +SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1);
  48606. +SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1);
  48607. +SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0);
  48608. +SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0);
  48609. +SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1);
  48610. +SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0);
  48611. +SHOW_FUNCTION(bfq_max_budget_async_rq_show,
  48612. + bfqd->bfq_max_budget_async_rq, 0);
  48613. +SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1);
  48614. +SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1);
  48615. +SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0);
  48616. +SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0);
  48617. +SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1);
  48618. +SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1);
  48619. +SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async,
  48620. + 1);
  48621. +SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0);
  48622. +#undef SHOW_FUNCTION
  48623. +
  48624. +#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
  48625. +static ssize_t \
  48626. +__FUNC(struct elevator_queue *e, const char *page, size_t count) \
  48627. +{ \
  48628. + struct bfq_data *bfqd = e->elevator_data; \
  48629. + unsigned long uninitialized_var(__data); \
  48630. + int ret = bfq_var_store(&__data, (page), count); \
  48631. + if (__data < (MIN)) \
  48632. + __data = (MIN); \
  48633. + else if (__data > (MAX)) \
  48634. + __data = (MAX); \
  48635. + if (__CONV) \
  48636. + *(__PTR) = msecs_to_jiffies(__data); \
  48637. + else \
  48638. + *(__PTR) = __data; \
  48639. + return ret; \
  48640. +}
  48641. +STORE_FUNCTION(bfq_quantum_store, &bfqd->bfq_quantum, 1, INT_MAX, 0);
  48642. +STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
  48643. + INT_MAX, 1);
  48644. +STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1,
  48645. + INT_MAX, 1);
  48646. +STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0);
  48647. +STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1,
  48648. + INT_MAX, 0);
  48649. +STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1);
  48650. +STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq,
  48651. + 1, INT_MAX, 0);
  48652. +STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0,
  48653. + INT_MAX, 1);
  48654. +STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0);
  48655. +STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1);
  48656. +STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX,
  48657. + 1);
  48658. +STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0,
  48659. + INT_MAX, 1);
  48660. +STORE_FUNCTION(bfq_wr_min_inter_arr_async_store,
  48661. + &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1);
  48662. +STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0,
  48663. + INT_MAX, 0);
  48664. +#undef STORE_FUNCTION
  48665. +
  48666. +/* do nothing for the moment */
  48667. +static ssize_t bfq_weights_store(struct elevator_queue *e,
  48668. + const char *page, size_t count)
  48669. +{
  48670. + return count;
  48671. +}
  48672. +
  48673. +static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd)
  48674. +{
  48675. + u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
  48676. +
  48677. + if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES)
  48678. + return bfq_calc_max_budget(bfqd->peak_rate, timeout);
  48679. + else
  48680. + return bfq_default_max_budget;
  48681. +}
  48682. +
  48683. +static ssize_t bfq_max_budget_store(struct elevator_queue *e,
  48684. + const char *page, size_t count)
  48685. +{
  48686. + struct bfq_data *bfqd = e->elevator_data;
  48687. + unsigned long uninitialized_var(__data);
  48688. + int ret = bfq_var_store(&__data, (page), count);
  48689. +
  48690. + if (__data == 0)
  48691. + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
  48692. + else {
  48693. + if (__data > INT_MAX)
  48694. + __data = INT_MAX;
  48695. + bfqd->bfq_max_budget = __data;
  48696. + }
  48697. +
  48698. + bfqd->bfq_user_max_budget = __data;
  48699. +
  48700. + return ret;
  48701. +}
  48702. +
  48703. +static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
  48704. + const char *page, size_t count)
  48705. +{
  48706. + struct bfq_data *bfqd = e->elevator_data;
  48707. + unsigned long uninitialized_var(__data);
  48708. + int ret = bfq_var_store(&__data, (page), count);
  48709. +
  48710. + if (__data < 1)
  48711. + __data = 1;
  48712. + else if (__data > INT_MAX)
  48713. + __data = INT_MAX;
  48714. +
  48715. + bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data);
  48716. + if (bfqd->bfq_user_max_budget == 0)
  48717. + bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
  48718. +
  48719. + return ret;
  48720. +}
  48721. +
  48722. +static ssize_t bfq_low_latency_store(struct elevator_queue *e,
  48723. + const char *page, size_t count)
  48724. +{
  48725. + struct bfq_data *bfqd = e->elevator_data;
  48726. + unsigned long uninitialized_var(__data);
  48727. + int ret = bfq_var_store(&__data, (page), count);
  48728. +
  48729. + if (__data > 1)
  48730. + __data = 1;
  48731. + if (__data == 0 && bfqd->low_latency != 0)
  48732. + bfq_end_wr(bfqd);
  48733. + bfqd->low_latency = __data;
  48734. +
  48735. + return ret;
  48736. +}
  48737. +
  48738. +#define BFQ_ATTR(name) \
  48739. + __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store)
  48740. +
  48741. +static struct elv_fs_entry bfq_attrs[] = {
  48742. + BFQ_ATTR(quantum),
  48743. + BFQ_ATTR(fifo_expire_sync),
  48744. + BFQ_ATTR(fifo_expire_async),
  48745. + BFQ_ATTR(back_seek_max),
  48746. + BFQ_ATTR(back_seek_penalty),
  48747. + BFQ_ATTR(slice_idle),
  48748. + BFQ_ATTR(max_budget),
  48749. + BFQ_ATTR(max_budget_async_rq),
  48750. + BFQ_ATTR(timeout_sync),
  48751. + BFQ_ATTR(timeout_async),
  48752. + BFQ_ATTR(low_latency),
  48753. + BFQ_ATTR(wr_coeff),
  48754. + BFQ_ATTR(wr_max_time),
  48755. + BFQ_ATTR(wr_rt_max_time),
  48756. + BFQ_ATTR(wr_min_idle_time),
  48757. + BFQ_ATTR(wr_min_inter_arr_async),
  48758. + BFQ_ATTR(wr_max_softrt_rate),
  48759. + BFQ_ATTR(weights),
  48760. + __ATTR_NULL
  48761. +};
  48762. +
  48763. +static struct elevator_type iosched_bfq = {
  48764. + .ops = {
  48765. + .elevator_merge_fn = bfq_merge,
  48766. + .elevator_merged_fn = bfq_merged_request,
  48767. + .elevator_merge_req_fn = bfq_merged_requests,
  48768. + .elevator_allow_merge_fn = bfq_allow_merge,
  48769. + .elevator_dispatch_fn = bfq_dispatch_requests,
  48770. + .elevator_add_req_fn = bfq_insert_request,
  48771. + .elevator_activate_req_fn = bfq_activate_request,
  48772. + .elevator_deactivate_req_fn = bfq_deactivate_request,
  48773. + .elevator_completed_req_fn = bfq_completed_request,
  48774. + .elevator_former_req_fn = elv_rb_former_request,
  48775. + .elevator_latter_req_fn = elv_rb_latter_request,
  48776. + .elevator_init_icq_fn = bfq_init_icq,
  48777. + .elevator_exit_icq_fn = bfq_exit_icq,
  48778. + .elevator_set_req_fn = bfq_set_request,
  48779. + .elevator_put_req_fn = bfq_put_request,
  48780. + .elevator_may_queue_fn = bfq_may_queue,
  48781. + .elevator_init_fn = bfq_init_queue,
  48782. + .elevator_exit_fn = bfq_exit_queue,
  48783. + },
  48784. + .icq_size = sizeof(struct bfq_io_cq),
  48785. + .icq_align = __alignof__(struct bfq_io_cq),
  48786. + .elevator_attrs = bfq_attrs,
  48787. + .elevator_name = "bfq",
  48788. + .elevator_owner = THIS_MODULE,
  48789. +};
  48790. +
  48791. +static int __init bfq_init(void)
  48792. +{
  48793. + /*
  48794. + * Can be 0 on HZ < 1000 setups.
  48795. + */
  48796. + if (bfq_slice_idle == 0)
  48797. + bfq_slice_idle = 1;
  48798. +
  48799. + if (bfq_timeout_async == 0)
  48800. + bfq_timeout_async = 1;
  48801. +
  48802. + if (bfq_slab_setup())
  48803. + return -ENOMEM;
  48804. +
  48805. + /*
  48806. + * Times to load large popular applications for the typical systems
  48807. + * installed on the reference devices (see the comments before the
  48808. + * definitions of the two arrays).
  48809. + */
  48810. + T_slow[0] = msecs_to_jiffies(2600);
  48811. + T_slow[1] = msecs_to_jiffies(1000);
  48812. + T_fast[0] = msecs_to_jiffies(5500);
  48813. + T_fast[1] = msecs_to_jiffies(2000);
  48814. +
  48815. + /*
  48816. + * Thresholds that determine the switch between speed classes (see
  48817. + * the comments before the definition of the array).
  48818. + */
  48819. + device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2;
  48820. + device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2;
  48821. +
  48822. + elv_register(&iosched_bfq);
  48823. + pr_info("BFQ I/O-scheduler version: v7r5");
  48824. +
  48825. + return 0;
  48826. +}
  48827. +
  48828. +static void __exit bfq_exit(void)
  48829. +{
  48830. + elv_unregister(&iosched_bfq);
  48831. + bfq_slab_kill();
  48832. +}
  48833. +
  48834. +module_init(bfq_init);
  48835. +module_exit(bfq_exit);
  48836. +
  48837. +MODULE_AUTHOR("Fabio Checconi, Paolo Valente");
  48838. +MODULE_LICENSE("GPL");
  48839. diff -Nur linux-3.14.17/block/bfq-sched.c linux-imx6-3.14/block/bfq-sched.c
  48840. --- linux-3.14.17/block/bfq-sched.c 1970-01-01 01:00:00.000000000 +0100
  48841. +++ linux-imx6-3.14/block/bfq-sched.c 2014-09-11 18:05:59.118026454 +0200
  48842. @@ -0,0 +1,1179 @@
  48843. +/*
  48844. + * BFQ: Hierarchical B-WF2Q+ scheduler.
  48845. + *
  48846. + * Based on ideas and code from CFQ:
  48847. + * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
  48848. + *
  48849. + * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
  48850. + * Paolo Valente <paolo.valente@unimore.it>
  48851. + *
  48852. + * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
  48853. + */
  48854. +
  48855. +#ifdef CONFIG_CGROUP_BFQIO
  48856. +#define for_each_entity(entity) \
  48857. + for (; entity != NULL; entity = entity->parent)
  48858. +
  48859. +#define for_each_entity_safe(entity, parent) \
  48860. + for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
  48861. +
  48862. +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
  48863. + int extract,
  48864. + struct bfq_data *bfqd);
  48865. +
  48866. +static inline void bfq_update_budget(struct bfq_entity *next_in_service)
  48867. +{
  48868. + struct bfq_entity *bfqg_entity;
  48869. + struct bfq_group *bfqg;
  48870. + struct bfq_sched_data *group_sd;
  48871. +
  48872. + BUG_ON(next_in_service == NULL);
  48873. +
  48874. + group_sd = next_in_service->sched_data;
  48875. +
  48876. + bfqg = container_of(group_sd, struct bfq_group, sched_data);
  48877. + /*
  48878. + * bfq_group's my_entity field is not NULL only if the group
  48879. + * is not the root group. We must not touch the root entity
  48880. + * as it must never become an in-service entity.
  48881. + */
  48882. + bfqg_entity = bfqg->my_entity;
  48883. + if (bfqg_entity != NULL)
  48884. + bfqg_entity->budget = next_in_service->budget;
  48885. +}
  48886. +
  48887. +static int bfq_update_next_in_service(struct bfq_sched_data *sd)
  48888. +{
  48889. + struct bfq_entity *next_in_service;
  48890. +
  48891. + if (sd->in_service_entity != NULL)
  48892. + /* will update/requeue at the end of service */
  48893. + return 0;
  48894. +
  48895. + /*
  48896. + * NOTE: this can be improved in many ways, such as returning
  48897. + * 1 (and thus propagating upwards the update) only when the
  48898. + * budget changes, or caching the bfqq that will be scheduled
  48899. + * next from this subtree. By now we worry more about
  48900. + * correctness than about performance...
  48901. + */
  48902. + next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
  48903. + sd->next_in_service = next_in_service;
  48904. +
  48905. + if (next_in_service != NULL)
  48906. + bfq_update_budget(next_in_service);
  48907. +
  48908. + return 1;
  48909. +}
  48910. +
  48911. +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd,
  48912. + struct bfq_entity *entity)
  48913. +{
  48914. + BUG_ON(sd->next_in_service != entity);
  48915. +}
  48916. +#else
  48917. +#define for_each_entity(entity) \
  48918. + for (; entity != NULL; entity = NULL)
  48919. +
  48920. +#define for_each_entity_safe(entity, parent) \
  48921. + for (parent = NULL; entity != NULL; entity = parent)
  48922. +
  48923. +static inline int bfq_update_next_in_service(struct bfq_sched_data *sd)
  48924. +{
  48925. + return 0;
  48926. +}
  48927. +
  48928. +static inline void bfq_check_next_in_service(struct bfq_sched_data *sd,
  48929. + struct bfq_entity *entity)
  48930. +{
  48931. +}
  48932. +
  48933. +static inline void bfq_update_budget(struct bfq_entity *next_in_service)
  48934. +{
  48935. +}
  48936. +#endif
  48937. +
  48938. +/*
  48939. + * Shift for timestamp calculations. This actually limits the maximum
  48940. + * service allowed in one timestamp delta (small shift values increase it),
  48941. + * the maximum total weight that can be used for the queues in the system
  48942. + * (big shift values increase it), and the period of virtual time
  48943. + * wraparounds.
  48944. + */
  48945. +#define WFQ_SERVICE_SHIFT 22
  48946. +
  48947. +/**
  48948. + * bfq_gt - compare two timestamps.
  48949. + * @a: first ts.
  48950. + * @b: second ts.
  48951. + *
  48952. + * Return @a > @b, dealing with wrapping correctly.
  48953. + */
  48954. +static inline int bfq_gt(u64 a, u64 b)
  48955. +{
  48956. + return (s64)(a - b) > 0;
  48957. +}
  48958. +
  48959. +static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
  48960. +{
  48961. + struct bfq_queue *bfqq = NULL;
  48962. +
  48963. + BUG_ON(entity == NULL);
  48964. +
  48965. + if (entity->my_sched_data == NULL)
  48966. + bfqq = container_of(entity, struct bfq_queue, entity);
  48967. +
  48968. + return bfqq;
  48969. +}
  48970. +
  48971. +
  48972. +/**
  48973. + * bfq_delta - map service into the virtual time domain.
  48974. + * @service: amount of service.
  48975. + * @weight: scale factor (weight of an entity or weight sum).
  48976. + */
  48977. +static inline u64 bfq_delta(unsigned long service,
  48978. + unsigned long weight)
  48979. +{
  48980. + u64 d = (u64)service << WFQ_SERVICE_SHIFT;
  48981. +
  48982. + do_div(d, weight);
  48983. + return d;
  48984. +}
  48985. +
  48986. +/**
  48987. + * bfq_calc_finish - assign the finish time to an entity.
  48988. + * @entity: the entity to act upon.
  48989. + * @service: the service to be charged to the entity.
  48990. + */
  48991. +static inline void bfq_calc_finish(struct bfq_entity *entity,
  48992. + unsigned long service)
  48993. +{
  48994. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  48995. +
  48996. + BUG_ON(entity->weight == 0);
  48997. +
  48998. + entity->finish = entity->start +
  48999. + bfq_delta(service, entity->weight);
  49000. +
  49001. + if (bfqq != NULL) {
  49002. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  49003. + "calc_finish: serv %lu, w %d",
  49004. + service, entity->weight);
  49005. + bfq_log_bfqq(bfqq->bfqd, bfqq,
  49006. + "calc_finish: start %llu, finish %llu, delta %llu",
  49007. + entity->start, entity->finish,
  49008. + bfq_delta(service, entity->weight));
  49009. + }
  49010. +}
  49011. +
  49012. +/**
  49013. + * bfq_entity_of - get an entity from a node.
  49014. + * @node: the node field of the entity.
  49015. + *
  49016. + * Convert a node pointer to the relative entity. This is used only
  49017. + * to simplify the logic of some functions and not as the generic
  49018. + * conversion mechanism because, e.g., in the tree walking functions,
  49019. + * the check for a %NULL value would be redundant.
  49020. + */
  49021. +static inline struct bfq_entity *bfq_entity_of(struct rb_node *node)
  49022. +{
  49023. + struct bfq_entity *entity = NULL;
  49024. +
  49025. + if (node != NULL)
  49026. + entity = rb_entry(node, struct bfq_entity, rb_node);
  49027. +
  49028. + return entity;
  49029. +}
  49030. +
  49031. +/**
  49032. + * bfq_extract - remove an entity from a tree.
  49033. + * @root: the tree root.
  49034. + * @entity: the entity to remove.
  49035. + */
  49036. +static inline void bfq_extract(struct rb_root *root,
  49037. + struct bfq_entity *entity)
  49038. +{
  49039. + BUG_ON(entity->tree != root);
  49040. +
  49041. + entity->tree = NULL;
  49042. + rb_erase(&entity->rb_node, root);
  49043. +}
  49044. +
  49045. +/**
  49046. + * bfq_idle_extract - extract an entity from the idle tree.
  49047. + * @st: the service tree of the owning @entity.
  49048. + * @entity: the entity being removed.
  49049. + */
  49050. +static void bfq_idle_extract(struct bfq_service_tree *st,
  49051. + struct bfq_entity *entity)
  49052. +{
  49053. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  49054. + struct rb_node *next;
  49055. +
  49056. + BUG_ON(entity->tree != &st->idle);
  49057. +
  49058. + if (entity == st->first_idle) {
  49059. + next = rb_next(&entity->rb_node);
  49060. + st->first_idle = bfq_entity_of(next);
  49061. + }
  49062. +
  49063. + if (entity == st->last_idle) {
  49064. + next = rb_prev(&entity->rb_node);
  49065. + st->last_idle = bfq_entity_of(next);
  49066. + }
  49067. +
  49068. + bfq_extract(&st->idle, entity);
  49069. +
  49070. + if (bfqq != NULL)
  49071. + list_del(&bfqq->bfqq_list);
  49072. +}
  49073. +
  49074. +/**
  49075. + * bfq_insert - generic tree insertion.
  49076. + * @root: tree root.
  49077. + * @entity: entity to insert.
  49078. + *
  49079. + * This is used for the idle and the active tree, since they are both
  49080. + * ordered by finish time.
  49081. + */
  49082. +static void bfq_insert(struct rb_root *root, struct bfq_entity *entity)
  49083. +{
  49084. + struct bfq_entity *entry;
  49085. + struct rb_node **node = &root->rb_node;
  49086. + struct rb_node *parent = NULL;
  49087. +
  49088. + BUG_ON(entity->tree != NULL);
  49089. +
  49090. + while (*node != NULL) {
  49091. + parent = *node;
  49092. + entry = rb_entry(parent, struct bfq_entity, rb_node);
  49093. +
  49094. + if (bfq_gt(entry->finish, entity->finish))
  49095. + node = &parent->rb_left;
  49096. + else
  49097. + node = &parent->rb_right;
  49098. + }
  49099. +
  49100. + rb_link_node(&entity->rb_node, parent, node);
  49101. + rb_insert_color(&entity->rb_node, root);
  49102. +
  49103. + entity->tree = root;
  49104. +}
  49105. +
  49106. +/**
  49107. + * bfq_update_min - update the min_start field of a entity.
  49108. + * @entity: the entity to update.
  49109. + * @node: one of its children.
  49110. + *
  49111. + * This function is called when @entity may store an invalid value for
  49112. + * min_start due to updates to the active tree. The function assumes
  49113. + * that the subtree rooted at @node (which may be its left or its right
  49114. + * child) has a valid min_start value.
  49115. + */
  49116. +static inline void bfq_update_min(struct bfq_entity *entity,
  49117. + struct rb_node *node)
  49118. +{
  49119. + struct bfq_entity *child;
  49120. +
  49121. + if (node != NULL) {
  49122. + child = rb_entry(node, struct bfq_entity, rb_node);
  49123. + if (bfq_gt(entity->min_start, child->min_start))
  49124. + entity->min_start = child->min_start;
  49125. + }
  49126. +}
  49127. +
  49128. +/**
  49129. + * bfq_update_active_node - recalculate min_start.
  49130. + * @node: the node to update.
  49131. + *
  49132. + * @node may have changed position or one of its children may have moved,
  49133. + * this function updates its min_start value. The left and right subtrees
  49134. + * are assumed to hold a correct min_start value.
  49135. + */
  49136. +static inline void bfq_update_active_node(struct rb_node *node)
  49137. +{
  49138. + struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node);
  49139. +
  49140. + entity->min_start = entity->start;
  49141. + bfq_update_min(entity, node->rb_right);
  49142. + bfq_update_min(entity, node->rb_left);
  49143. +}
  49144. +
  49145. +/**
  49146. + * bfq_update_active_tree - update min_start for the whole active tree.
  49147. + * @node: the starting node.
  49148. + *
  49149. + * @node must be the deepest modified node after an update. This function
  49150. + * updates its min_start using the values held by its children, assuming
  49151. + * that they did not change, and then updates all the nodes that may have
  49152. + * changed in the path to the root. The only nodes that may have changed
  49153. + * are the ones in the path or their siblings.
  49154. + */
  49155. +static void bfq_update_active_tree(struct rb_node *node)
  49156. +{
  49157. + struct rb_node *parent;
  49158. +
  49159. +up:
  49160. + bfq_update_active_node(node);
  49161. +
  49162. + parent = rb_parent(node);
  49163. + if (parent == NULL)
  49164. + return;
  49165. +
  49166. + if (node == parent->rb_left && parent->rb_right != NULL)
  49167. + bfq_update_active_node(parent->rb_right);
  49168. + else if (parent->rb_left != NULL)
  49169. + bfq_update_active_node(parent->rb_left);
  49170. +
  49171. + node = parent;
  49172. + goto up;
  49173. +}
  49174. +
  49175. +static void bfq_weights_tree_add(struct bfq_data *bfqd,
  49176. + struct bfq_entity *entity,
  49177. + struct rb_root *root);
  49178. +
  49179. +static void bfq_weights_tree_remove(struct bfq_data *bfqd,
  49180. + struct bfq_entity *entity,
  49181. + struct rb_root *root);
  49182. +
  49183. +
  49184. +/**
  49185. + * bfq_active_insert - insert an entity in the active tree of its
  49186. + * group/device.
  49187. + * @st: the service tree of the entity.
  49188. + * @entity: the entity being inserted.
  49189. + *
  49190. + * The active tree is ordered by finish time, but an extra key is kept
  49191. + * per each node, containing the minimum value for the start times of
  49192. + * its children (and the node itself), so it's possible to search for
  49193. + * the eligible node with the lowest finish time in logarithmic time.
  49194. + */
  49195. +static void bfq_active_insert(struct bfq_service_tree *st,
  49196. + struct bfq_entity *entity)
  49197. +{
  49198. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  49199. + struct rb_node *node = &entity->rb_node;
  49200. +#ifdef CONFIG_CGROUP_BFQIO
  49201. + struct bfq_sched_data *sd = NULL;
  49202. + struct bfq_group *bfqg = NULL;
  49203. + struct bfq_data *bfqd = NULL;
  49204. +#endif
  49205. +
  49206. + bfq_insert(&st->active, entity);
  49207. +
  49208. + if (node->rb_left != NULL)
  49209. + node = node->rb_left;
  49210. + else if (node->rb_right != NULL)
  49211. + node = node->rb_right;
  49212. +
  49213. + bfq_update_active_tree(node);
  49214. +
  49215. +#ifdef CONFIG_CGROUP_BFQIO
  49216. + sd = entity->sched_data;
  49217. + bfqg = container_of(sd, struct bfq_group, sched_data);
  49218. + BUG_ON(!bfqg);
  49219. + bfqd = (struct bfq_data *)bfqg->bfqd;
  49220. +#endif
  49221. + if (bfqq != NULL)
  49222. + list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list);
  49223. +#ifdef CONFIG_CGROUP_BFQIO
  49224. + else { /* bfq_group */
  49225. + BUG_ON(!bfqd);
  49226. + bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree);
  49227. + }
  49228. + if (bfqg != bfqd->root_group) {
  49229. + BUG_ON(!bfqg);
  49230. + BUG_ON(!bfqd);
  49231. + bfqg->active_entities++;
  49232. + if (bfqg->active_entities == 2)
  49233. + bfqd->active_numerous_groups++;
  49234. + }
  49235. +#endif
  49236. +}
  49237. +
  49238. +/**
  49239. + * bfq_ioprio_to_weight - calc a weight from an ioprio.
  49240. + * @ioprio: the ioprio value to convert.
  49241. + */
  49242. +static inline unsigned short bfq_ioprio_to_weight(int ioprio)
  49243. +{
  49244. + BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR);
  49245. + return IOPRIO_BE_NR - ioprio;
  49246. +}
  49247. +
  49248. +/**
  49249. + * bfq_weight_to_ioprio - calc an ioprio from a weight.
  49250. + * @weight: the weight value to convert.
  49251. + *
  49252. + * To preserve as mush as possible the old only-ioprio user interface,
  49253. + * 0 is used as an escape ioprio value for weights (numerically) equal or
  49254. + * larger than IOPRIO_BE_NR
  49255. + */
  49256. +static inline unsigned short bfq_weight_to_ioprio(int weight)
  49257. +{
  49258. + BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT);
  49259. + return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight;
  49260. +}
  49261. +
  49262. +static inline void bfq_get_entity(struct bfq_entity *entity)
  49263. +{
  49264. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  49265. +
  49266. + if (bfqq != NULL) {
  49267. + atomic_inc(&bfqq->ref);
  49268. + bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
  49269. + bfqq, atomic_read(&bfqq->ref));
  49270. + }
  49271. +}
  49272. +
  49273. +/**
  49274. + * bfq_find_deepest - find the deepest node that an extraction can modify.
  49275. + * @node: the node being removed.
  49276. + *
  49277. + * Do the first step of an extraction in an rb tree, looking for the
  49278. + * node that will replace @node, and returning the deepest node that
  49279. + * the following modifications to the tree can touch. If @node is the
  49280. + * last node in the tree return %NULL.
  49281. + */
  49282. +static struct rb_node *bfq_find_deepest(struct rb_node *node)
  49283. +{
  49284. + struct rb_node *deepest;
  49285. +
  49286. + if (node->rb_right == NULL && node->rb_left == NULL)
  49287. + deepest = rb_parent(node);
  49288. + else if (node->rb_right == NULL)
  49289. + deepest = node->rb_left;
  49290. + else if (node->rb_left == NULL)
  49291. + deepest = node->rb_right;
  49292. + else {
  49293. + deepest = rb_next(node);
  49294. + if (deepest->rb_right != NULL)
  49295. + deepest = deepest->rb_right;
  49296. + else if (rb_parent(deepest) != node)
  49297. + deepest = rb_parent(deepest);
  49298. + }
  49299. +
  49300. + return deepest;
  49301. +}
  49302. +
  49303. +/**
  49304. + * bfq_active_extract - remove an entity from the active tree.
  49305. + * @st: the service_tree containing the tree.
  49306. + * @entity: the entity being removed.
  49307. + */
  49308. +static void bfq_active_extract(struct bfq_service_tree *st,
  49309. + struct bfq_entity *entity)
  49310. +{
  49311. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  49312. + struct rb_node *node;
  49313. +#ifdef CONFIG_CGROUP_BFQIO
  49314. + struct bfq_sched_data *sd = NULL;
  49315. + struct bfq_group *bfqg = NULL;
  49316. + struct bfq_data *bfqd = NULL;
  49317. +#endif
  49318. +
  49319. + node = bfq_find_deepest(&entity->rb_node);
  49320. + bfq_extract(&st->active, entity);
  49321. +
  49322. + if (node != NULL)
  49323. + bfq_update_active_tree(node);
  49324. +
  49325. +#ifdef CONFIG_CGROUP_BFQIO
  49326. + sd = entity->sched_data;
  49327. + bfqg = container_of(sd, struct bfq_group, sched_data);
  49328. + BUG_ON(!bfqg);
  49329. + bfqd = (struct bfq_data *)bfqg->bfqd;
  49330. +#endif
  49331. + if (bfqq != NULL)
  49332. + list_del(&bfqq->bfqq_list);
  49333. +#ifdef CONFIG_CGROUP_BFQIO
  49334. + else { /* bfq_group */
  49335. + BUG_ON(!bfqd);
  49336. + bfq_weights_tree_remove(bfqd, entity,
  49337. + &bfqd->group_weights_tree);
  49338. + }
  49339. + if (bfqg != bfqd->root_group) {
  49340. + BUG_ON(!bfqg);
  49341. + BUG_ON(!bfqd);
  49342. + BUG_ON(!bfqg->active_entities);
  49343. + bfqg->active_entities--;
  49344. + if (bfqg->active_entities == 1) {
  49345. + BUG_ON(!bfqd->active_numerous_groups);
  49346. + bfqd->active_numerous_groups--;
  49347. + }
  49348. + }
  49349. +#endif
  49350. +}
  49351. +
  49352. +/**
  49353. + * bfq_idle_insert - insert an entity into the idle tree.
  49354. + * @st: the service tree containing the tree.
  49355. + * @entity: the entity to insert.
  49356. + */
  49357. +static void bfq_idle_insert(struct bfq_service_tree *st,
  49358. + struct bfq_entity *entity)
  49359. +{
  49360. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  49361. + struct bfq_entity *first_idle = st->first_idle;
  49362. + struct bfq_entity *last_idle = st->last_idle;
  49363. +
  49364. + if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish))
  49365. + st->first_idle = entity;
  49366. + if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish))
  49367. + st->last_idle = entity;
  49368. +
  49369. + bfq_insert(&st->idle, entity);
  49370. +
  49371. + if (bfqq != NULL)
  49372. + list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list);
  49373. +}
  49374. +
  49375. +/**
  49376. + * bfq_forget_entity - remove an entity from the wfq trees.
  49377. + * @st: the service tree.
  49378. + * @entity: the entity being removed.
  49379. + *
  49380. + * Update the device status and forget everything about @entity, putting
  49381. + * the device reference to it, if it is a queue. Entities belonging to
  49382. + * groups are not refcounted.
  49383. + */
  49384. +static void bfq_forget_entity(struct bfq_service_tree *st,
  49385. + struct bfq_entity *entity)
  49386. +{
  49387. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  49388. + struct bfq_sched_data *sd;
  49389. +
  49390. + BUG_ON(!entity->on_st);
  49391. +
  49392. + entity->on_st = 0;
  49393. + st->wsum -= entity->weight;
  49394. + if (bfqq != NULL) {
  49395. + sd = entity->sched_data;
  49396. + bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
  49397. + bfqq, atomic_read(&bfqq->ref));
  49398. + bfq_put_queue(bfqq);
  49399. + }
  49400. +}
  49401. +
  49402. +/**
  49403. + * bfq_put_idle_entity - release the idle tree ref of an entity.
  49404. + * @st: service tree for the entity.
  49405. + * @entity: the entity being released.
  49406. + */
  49407. +static void bfq_put_idle_entity(struct bfq_service_tree *st,
  49408. + struct bfq_entity *entity)
  49409. +{
  49410. + bfq_idle_extract(st, entity);
  49411. + bfq_forget_entity(st, entity);
  49412. +}
  49413. +
  49414. +/**
  49415. + * bfq_forget_idle - update the idle tree if necessary.
  49416. + * @st: the service tree to act upon.
  49417. + *
  49418. + * To preserve the global O(log N) complexity we only remove one entry here;
  49419. + * as the idle tree will not grow indefinitely this can be done safely.
  49420. + */
  49421. +static void bfq_forget_idle(struct bfq_service_tree *st)
  49422. +{
  49423. + struct bfq_entity *first_idle = st->first_idle;
  49424. + struct bfq_entity *last_idle = st->last_idle;
  49425. +
  49426. + if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL &&
  49427. + !bfq_gt(last_idle->finish, st->vtime)) {
  49428. + /*
  49429. + * Forget the whole idle tree, increasing the vtime past
  49430. + * the last finish time of idle entities.
  49431. + */
  49432. + st->vtime = last_idle->finish;
  49433. + }
  49434. +
  49435. + if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime))
  49436. + bfq_put_idle_entity(st, first_idle);
  49437. +}
  49438. +
  49439. +static struct bfq_service_tree *
  49440. +__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
  49441. + struct bfq_entity *entity)
  49442. +{
  49443. + struct bfq_service_tree *new_st = old_st;
  49444. +
  49445. + if (entity->ioprio_changed) {
  49446. + struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
  49447. + unsigned short prev_weight, new_weight;
  49448. + struct bfq_data *bfqd = NULL;
  49449. + struct rb_root *root;
  49450. +#ifdef CONFIG_CGROUP_BFQIO
  49451. + struct bfq_sched_data *sd;
  49452. + struct bfq_group *bfqg;
  49453. +#endif
  49454. +
  49455. + if (bfqq != NULL)
  49456. + bfqd = bfqq->bfqd;
  49457. +#ifdef CONFIG_CGROUP_BFQIO
  49458. + else {
  49459. + sd = entity->my_sched_data;
  49460. + bfqg = container_of(sd, struct bfq_group, sched_data);
  49461. + BUG_ON(!bfqg);
  49462. + bfqd = (struct bfq_data *)bfqg->bfqd;
  49463. + BUG_ON(!bfqd);
  49464. + }
  49465. +#endif
  49466. +
  49467. + BUG_ON(old_st->wsum < entity->weight);
  49468. + old_st->wsum -= entity->weight;
  49469. +
  49470. + if (entity->new_weight != entity->orig_weight) {
  49471. + entity->orig_weight = entity->new_weight;
  49472. + entity->ioprio =
  49473. + bfq_weight_to_ioprio(entity->orig_weight);
  49474. + } else if (entity->new_ioprio != entity->ioprio) {
  49475. + entity->ioprio = entity->new_ioprio;
  49476. + entity->orig_weight =
  49477. + bfq_ioprio_to_weight(entity->ioprio);
  49478. + } else
  49479. + entity->new_weight = entity->orig_weight =
  49480. + bfq_ioprio_to_weight(entity->ioprio);
  49481. +
  49482. + entity->ioprio_class = entity->new_ioprio_class;
  49483. + entity->ioprio_changed = 0;
  49484. +
  49485. + /*
  49486. + * NOTE: here we may be changing the weight too early,
  49487. + * this will cause unfairness. The correct approach
  49488. + * would have required additional complexity to defer
  49489. + * weight changes to the proper time instants (i.e.,
  49490. + * when entity->finish <= old_st->vtime).
  49491. + */
  49492. + new_st = bfq_entity_service_tree(entity);
  49493. +
  49494. + prev_weight = entity->weight;
  49495. + new_weight = entity->orig_weight *
  49496. + (bfqq != NULL ? bfqq->wr_coeff : 1);
  49497. + /*
  49498. + * If the weight of the entity changes, remove the entity
  49499. + * from its old weight counter (if there is a counter
  49500. + * associated with the entity), and add it to the counter
  49501. + * associated with its new weight.
  49502. + */
  49503. + if (prev_weight != new_weight) {
  49504. + root = bfqq ? &bfqd->queue_weights_tree :
  49505. + &bfqd->group_weights_tree;
  49506. + bfq_weights_tree_remove(bfqd, entity, root);
  49507. + }
  49508. + entity->weight = new_weight;
  49509. + /*
  49510. + * Add the entity to its weights tree only if it is
  49511. + * not associated with a weight-raised queue.
  49512. + */
  49513. + if (prev_weight != new_weight &&
  49514. + (bfqq ? bfqq->wr_coeff == 1 : 1))
  49515. + /* If we get here, root has been initialized. */
  49516. + bfq_weights_tree_add(bfqd, entity, root);
  49517. +
  49518. + new_st->wsum += entity->weight;
  49519. +
  49520. + if (new_st != old_st)
  49521. + entity->start = new_st->vtime;
  49522. + }
  49523. +
  49524. + return new_st;
  49525. +}
  49526. +
  49527. +/**
  49528. + * bfq_bfqq_served - update the scheduler status after selection for
  49529. + * service.
  49530. + * @bfqq: the queue being served.
  49531. + * @served: bytes to transfer.
  49532. + *
  49533. + * NOTE: this can be optimized, as the timestamps of upper level entities
  49534. + * are synchronized every time a new bfqq is selected for service. By now,
  49535. + * we keep it to better check consistency.
  49536. + */
  49537. +static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served)
  49538. +{
  49539. + struct bfq_entity *entity = &bfqq->entity;
  49540. + struct bfq_service_tree *st;
  49541. +
  49542. + for_each_entity(entity) {
  49543. + st = bfq_entity_service_tree(entity);
  49544. +
  49545. + entity->service += served;
  49546. + BUG_ON(entity->service > entity->budget);
  49547. + BUG_ON(st->wsum == 0);
  49548. +
  49549. + st->vtime += bfq_delta(served, st->wsum);
  49550. + bfq_forget_idle(st);
  49551. + }
  49552. + bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served);
  49553. +}
  49554. +
  49555. +/**
  49556. + * bfq_bfqq_charge_full_budget - set the service to the entity budget.
  49557. + * @bfqq: the queue that needs a service update.
  49558. + *
  49559. + * When it's not possible to be fair in the service domain, because
  49560. + * a queue is not consuming its budget fast enough (the meaning of
  49561. + * fast depends on the timeout parameter), we charge it a full
  49562. + * budget. In this way we should obtain a sort of time-domain
  49563. + * fairness among all the seeky/slow queues.
  49564. + */
  49565. +static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq)
  49566. +{
  49567. + struct bfq_entity *entity = &bfqq->entity;
  49568. +
  49569. + bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
  49570. +
  49571. + bfq_bfqq_served(bfqq, entity->budget - entity->service);
  49572. +}
  49573. +
  49574. +/**
  49575. + * __bfq_activate_entity - activate an entity.
  49576. + * @entity: the entity being activated.
  49577. + *
  49578. + * Called whenever an entity is activated, i.e., it is not active and one
  49579. + * of its children receives a new request, or has to be reactivated due to
  49580. + * budget exhaustion. It uses the current budget of the entity (and the
  49581. + * service received if @entity is active) of the queue to calculate its
  49582. + * timestamps.
  49583. + */
  49584. +static void __bfq_activate_entity(struct bfq_entity *entity)
  49585. +{
  49586. + struct bfq_sched_data *sd = entity->sched_data;
  49587. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  49588. +
  49589. + if (entity == sd->in_service_entity) {
  49590. + BUG_ON(entity->tree != NULL);
  49591. + /*
  49592. + * If we are requeueing the current entity we have
  49593. + * to take care of not charging to it service it has
  49594. + * not received.
  49595. + */
  49596. + bfq_calc_finish(entity, entity->service);
  49597. + entity->start = entity->finish;
  49598. + sd->in_service_entity = NULL;
  49599. + } else if (entity->tree == &st->active) {
  49600. + /*
  49601. + * Requeueing an entity due to a change of some
  49602. + * next_in_service entity below it. We reuse the
  49603. + * old start time.
  49604. + */
  49605. + bfq_active_extract(st, entity);
  49606. + } else if (entity->tree == &st->idle) {
  49607. + /*
  49608. + * Must be on the idle tree, bfq_idle_extract() will
  49609. + * check for that.
  49610. + */
  49611. + bfq_idle_extract(st, entity);
  49612. + entity->start = bfq_gt(st->vtime, entity->finish) ?
  49613. + st->vtime : entity->finish;
  49614. + } else {
  49615. + /*
  49616. + * The finish time of the entity may be invalid, and
  49617. + * it is in the past for sure, otherwise the queue
  49618. + * would have been on the idle tree.
  49619. + */
  49620. + entity->start = st->vtime;
  49621. + st->wsum += entity->weight;
  49622. + bfq_get_entity(entity);
  49623. +
  49624. + BUG_ON(entity->on_st);
  49625. + entity->on_st = 1;
  49626. + }
  49627. +
  49628. + st = __bfq_entity_update_weight_prio(st, entity);
  49629. + bfq_calc_finish(entity, entity->budget);
  49630. + bfq_active_insert(st, entity);
  49631. +}
  49632. +
  49633. +/**
  49634. + * bfq_activate_entity - activate an entity and its ancestors if necessary.
  49635. + * @entity: the entity to activate.
  49636. + *
  49637. + * Activate @entity and all the entities on the path from it to the root.
  49638. + */
  49639. +static void bfq_activate_entity(struct bfq_entity *entity)
  49640. +{
  49641. + struct bfq_sched_data *sd;
  49642. +
  49643. + for_each_entity(entity) {
  49644. + __bfq_activate_entity(entity);
  49645. +
  49646. + sd = entity->sched_data;
  49647. + if (!bfq_update_next_in_service(sd))
  49648. + /*
  49649. + * No need to propagate the activation to the
  49650. + * upper entities, as they will be updated when
  49651. + * the in-service entity is rescheduled.
  49652. + */
  49653. + break;
  49654. + }
  49655. +}
  49656. +
  49657. +/**
  49658. + * __bfq_deactivate_entity - deactivate an entity from its service tree.
  49659. + * @entity: the entity to deactivate.
  49660. + * @requeue: if false, the entity will not be put into the idle tree.
  49661. + *
  49662. + * Deactivate an entity, independently from its previous state. If the
  49663. + * entity was not on a service tree just return, otherwise if it is on
  49664. + * any scheduler tree, extract it from that tree, and if necessary
  49665. + * and if the caller did not specify @requeue, put it on the idle tree.
  49666. + *
  49667. + * Return %1 if the caller should update the entity hierarchy, i.e.,
  49668. + * if the entity was in service or if it was the next_in_service for
  49669. + * its sched_data; return %0 otherwise.
  49670. + */
  49671. +static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
  49672. +{
  49673. + struct bfq_sched_data *sd = entity->sched_data;
  49674. + struct bfq_service_tree *st = bfq_entity_service_tree(entity);
  49675. + int was_in_service = entity == sd->in_service_entity;
  49676. + int ret = 0;
  49677. +
  49678. + if (!entity->on_st)
  49679. + return 0;
  49680. +
  49681. + BUG_ON(was_in_service && entity->tree != NULL);
  49682. +
  49683. + if (was_in_service) {
  49684. + bfq_calc_finish(entity, entity->service);
  49685. + sd->in_service_entity = NULL;
  49686. + } else if (entity->tree == &st->active)
  49687. + bfq_active_extract(st, entity);
  49688. + else if (entity->tree == &st->idle)
  49689. + bfq_idle_extract(st, entity);
  49690. + else if (entity->tree != NULL)
  49691. + BUG();
  49692. +
  49693. + if (was_in_service || sd->next_in_service == entity)
  49694. + ret = bfq_update_next_in_service(sd);
  49695. +
  49696. + if (!requeue || !bfq_gt(entity->finish, st->vtime))
  49697. + bfq_forget_entity(st, entity);
  49698. + else
  49699. + bfq_idle_insert(st, entity);
  49700. +
  49701. + BUG_ON(sd->in_service_entity == entity);
  49702. + BUG_ON(sd->next_in_service == entity);
  49703. +
  49704. + return ret;
  49705. +}
  49706. +
  49707. +/**
  49708. + * bfq_deactivate_entity - deactivate an entity.
  49709. + * @entity: the entity to deactivate.
  49710. + * @requeue: true if the entity can be put on the idle tree
  49711. + */
  49712. +static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
  49713. +{
  49714. + struct bfq_sched_data *sd;
  49715. + struct bfq_entity *parent;
  49716. +
  49717. + for_each_entity_safe(entity, parent) {
  49718. + sd = entity->sched_data;
  49719. +
  49720. + if (!__bfq_deactivate_entity(entity, requeue))
  49721. + /*
  49722. + * The parent entity is still backlogged, and
  49723. + * we don't need to update it as it is still
  49724. + * in service.
  49725. + */
  49726. + break;
  49727. +
  49728. + if (sd->next_in_service != NULL)
  49729. + /*
  49730. + * The parent entity is still backlogged and
  49731. + * the budgets on the path towards the root
  49732. + * need to be updated.
  49733. + */
  49734. + goto update;
  49735. +
  49736. + /*
  49737. + * If we reach there the parent is no more backlogged and
  49738. + * we want to propagate the dequeue upwards.
  49739. + */
  49740. + requeue = 1;
  49741. + }
  49742. +
  49743. + return;
  49744. +
  49745. +update:
  49746. + entity = parent;
  49747. + for_each_entity(entity) {
  49748. + __bfq_activate_entity(entity);
  49749. +
  49750. + sd = entity->sched_data;
  49751. + if (!bfq_update_next_in_service(sd))
  49752. + break;
  49753. + }
  49754. +}
  49755. +
  49756. +/**
  49757. + * bfq_update_vtime - update vtime if necessary.
  49758. + * @st: the service tree to act upon.
  49759. + *
  49760. + * If necessary update the service tree vtime to have at least one
  49761. + * eligible entity, skipping to its start time. Assumes that the
  49762. + * active tree of the device is not empty.
  49763. + *
  49764. + * NOTE: this hierarchical implementation updates vtimes quite often,
  49765. + * we may end up with reactivated processes getting timestamps after a
  49766. + * vtime skip done because we needed a ->first_active entity on some
  49767. + * intermediate node.
  49768. + */
  49769. +static void bfq_update_vtime(struct bfq_service_tree *st)
  49770. +{
  49771. + struct bfq_entity *entry;
  49772. + struct rb_node *node = st->active.rb_node;
  49773. +
  49774. + entry = rb_entry(node, struct bfq_entity, rb_node);
  49775. + if (bfq_gt(entry->min_start, st->vtime)) {
  49776. + st->vtime = entry->min_start;
  49777. + bfq_forget_idle(st);
  49778. + }
  49779. +}
  49780. +
  49781. +/**
  49782. + * bfq_first_active_entity - find the eligible entity with
  49783. + * the smallest finish time
  49784. + * @st: the service tree to select from.
  49785. + *
  49786. + * This function searches the first schedulable entity, starting from the
  49787. + * root of the tree and going on the left every time on this side there is
  49788. + * a subtree with at least one eligible (start >= vtime) entity. The path on
  49789. + * the right is followed only if a) the left subtree contains no eligible
  49790. + * entities and b) no eligible entity has been found yet.
  49791. + */
  49792. +static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
  49793. +{
  49794. + struct bfq_entity *entry, *first = NULL;
  49795. + struct rb_node *node = st->active.rb_node;
  49796. +
  49797. + while (node != NULL) {
  49798. + entry = rb_entry(node, struct bfq_entity, rb_node);
  49799. +left:
  49800. + if (!bfq_gt(entry->start, st->vtime))
  49801. + first = entry;
  49802. +
  49803. + BUG_ON(bfq_gt(entry->min_start, st->vtime));
  49804. +
  49805. + if (node->rb_left != NULL) {
  49806. + entry = rb_entry(node->rb_left,
  49807. + struct bfq_entity, rb_node);
  49808. + if (!bfq_gt(entry->min_start, st->vtime)) {
  49809. + node = node->rb_left;
  49810. + goto left;
  49811. + }
  49812. + }
  49813. + if (first != NULL)
  49814. + break;
  49815. + node = node->rb_right;
  49816. + }
  49817. +
  49818. + BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active));
  49819. + return first;
  49820. +}
  49821. +
  49822. +/**
  49823. + * __bfq_lookup_next_entity - return the first eligible entity in @st.
  49824. + * @st: the service tree.
  49825. + *
  49826. + * Update the virtual time in @st and return the first eligible entity
  49827. + * it contains.
  49828. + */
  49829. +static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
  49830. + bool force)
  49831. +{
  49832. + struct bfq_entity *entity, *new_next_in_service = NULL;
  49833. +
  49834. + if (RB_EMPTY_ROOT(&st->active))
  49835. + return NULL;
  49836. +
  49837. + bfq_update_vtime(st);
  49838. + entity = bfq_first_active_entity(st);
  49839. + BUG_ON(bfq_gt(entity->start, st->vtime));
  49840. +
  49841. + /*
  49842. + * If the chosen entity does not match with the sched_data's
  49843. + * next_in_service and we are forcedly serving the IDLE priority
  49844. + * class tree, bubble up budget update.
  49845. + */
  49846. + if (unlikely(force && entity != entity->sched_data->next_in_service)) {
  49847. + new_next_in_service = entity;
  49848. + for_each_entity(new_next_in_service)
  49849. + bfq_update_budget(new_next_in_service);
  49850. + }
  49851. +
  49852. + return entity;
  49853. +}
  49854. +
  49855. +/**
  49856. + * bfq_lookup_next_entity - return the first eligible entity in @sd.
  49857. + * @sd: the sched_data.
  49858. + * @extract: if true the returned entity will be also extracted from @sd.
  49859. + *
  49860. + * NOTE: since we cache the next_in_service entity at each level of the
  49861. + * hierarchy, the complexity of the lookup can be decreased with
  49862. + * absolutely no effort just returning the cached next_in_service value;
  49863. + * we prefer to do full lookups to test the consistency of * the data
  49864. + * structures.
  49865. + */
  49866. +static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
  49867. + int extract,
  49868. + struct bfq_data *bfqd)
  49869. +{
  49870. + struct bfq_service_tree *st = sd->service_tree;
  49871. + struct bfq_entity *entity;
  49872. + int i = 0;
  49873. +
  49874. + BUG_ON(sd->in_service_entity != NULL);
  49875. +
  49876. + if (bfqd != NULL &&
  49877. + jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) {
  49878. + entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1,
  49879. + true);
  49880. + if (entity != NULL) {
  49881. + i = BFQ_IOPRIO_CLASSES - 1;
  49882. + bfqd->bfq_class_idle_last_service = jiffies;
  49883. + sd->next_in_service = entity;
  49884. + }
  49885. + }
  49886. + for (; i < BFQ_IOPRIO_CLASSES; i++) {
  49887. + entity = __bfq_lookup_next_entity(st + i, false);
  49888. + if (entity != NULL) {
  49889. + if (extract) {
  49890. + bfq_check_next_in_service(sd, entity);
  49891. + bfq_active_extract(st + i, entity);
  49892. + sd->in_service_entity = entity;
  49893. + sd->next_in_service = NULL;
  49894. + }
  49895. + break;
  49896. + }
  49897. + }
  49898. +
  49899. + return entity;
  49900. +}
  49901. +
  49902. +/*
  49903. + * Get next queue for service.
  49904. + */
  49905. +static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
  49906. +{
  49907. + struct bfq_entity *entity = NULL;
  49908. + struct bfq_sched_data *sd;
  49909. + struct bfq_queue *bfqq;
  49910. +
  49911. + BUG_ON(bfqd->in_service_queue != NULL);
  49912. +
  49913. + if (bfqd->busy_queues == 0)
  49914. + return NULL;
  49915. +
  49916. + sd = &bfqd->root_group->sched_data;
  49917. + for (; sd != NULL; sd = entity->my_sched_data) {
  49918. + entity = bfq_lookup_next_entity(sd, 1, bfqd);
  49919. + BUG_ON(entity == NULL);
  49920. + entity->service = 0;
  49921. + }
  49922. +
  49923. + bfqq = bfq_entity_to_bfqq(entity);
  49924. + BUG_ON(bfqq == NULL);
  49925. +
  49926. + return bfqq;
  49927. +}
  49928. +
  49929. +static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
  49930. +{
  49931. + if (bfqd->in_service_bic != NULL) {
  49932. + put_io_context(bfqd->in_service_bic->icq.ioc);
  49933. + bfqd->in_service_bic = NULL;
  49934. + }
  49935. +
  49936. + bfqd->in_service_queue = NULL;
  49937. + del_timer(&bfqd->idle_slice_timer);
  49938. +}
  49939. +
  49940. +static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  49941. + int requeue)
  49942. +{
  49943. + struct bfq_entity *entity = &bfqq->entity;
  49944. +
  49945. + if (bfqq == bfqd->in_service_queue)
  49946. + __bfq_bfqd_reset_in_service(bfqd);
  49947. +
  49948. + bfq_deactivate_entity(entity, requeue);
  49949. +}
  49950. +
  49951. +static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  49952. +{
  49953. + struct bfq_entity *entity = &bfqq->entity;
  49954. +
  49955. + bfq_activate_entity(entity);
  49956. +}
  49957. +
  49958. +/*
  49959. + * Called when the bfqq no longer has requests pending, remove it from
  49960. + * the service tree.
  49961. + */
  49962. +static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
  49963. + int requeue)
  49964. +{
  49965. + BUG_ON(!bfq_bfqq_busy(bfqq));
  49966. + BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
  49967. +
  49968. + bfq_log_bfqq(bfqd, bfqq, "del from busy");
  49969. +
  49970. + bfq_clear_bfqq_busy(bfqq);
  49971. +
  49972. + BUG_ON(bfqd->busy_queues == 0);
  49973. + bfqd->busy_queues--;
  49974. +
  49975. + if (!bfqq->dispatched) {
  49976. + bfq_weights_tree_remove(bfqd, &bfqq->entity,
  49977. + &bfqd->queue_weights_tree);
  49978. + if (!blk_queue_nonrot(bfqd->queue)) {
  49979. + BUG_ON(!bfqd->busy_in_flight_queues);
  49980. + bfqd->busy_in_flight_queues--;
  49981. + if (bfq_bfqq_constantly_seeky(bfqq)) {
  49982. + BUG_ON(!bfqd->
  49983. + const_seeky_busy_in_flight_queues);
  49984. + bfqd->const_seeky_busy_in_flight_queues--;
  49985. + }
  49986. + }
  49987. + }
  49988. + if (bfqq->wr_coeff > 1)
  49989. + bfqd->wr_busy_queues--;
  49990. +
  49991. + bfq_deactivate_bfqq(bfqd, bfqq, requeue);
  49992. +}
  49993. +
  49994. +/*
  49995. + * Called when an inactive queue receives a new request.
  49996. + */
  49997. +static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
  49998. +{
  49999. + BUG_ON(bfq_bfqq_busy(bfqq));
  50000. + BUG_ON(bfqq == bfqd->in_service_queue);
  50001. +
  50002. + bfq_log_bfqq(bfqd, bfqq, "add to busy");
  50003. +
  50004. + bfq_activate_bfqq(bfqd, bfqq);
  50005. +
  50006. + bfq_mark_bfqq_busy(bfqq);
  50007. + bfqd->busy_queues++;
  50008. +
  50009. + if (!bfqq->dispatched) {
  50010. + if (bfqq->wr_coeff == 1)
  50011. + bfq_weights_tree_add(bfqd, &bfqq->entity,
  50012. + &bfqd->queue_weights_tree);
  50013. + if (!blk_queue_nonrot(bfqd->queue)) {
  50014. + bfqd->busy_in_flight_queues++;
  50015. + if (bfq_bfqq_constantly_seeky(bfqq))
  50016. + bfqd->const_seeky_busy_in_flight_queues++;
  50017. + }
  50018. + }
  50019. + if (bfqq->wr_coeff > 1)
  50020. + bfqd->wr_busy_queues++;
  50021. +}
  50022. diff -Nur linux-3.14.17/block/blk-cgroup.c linux-imx6-3.14/block/blk-cgroup.c
  50023. --- linux-3.14.17/block/blk-cgroup.c 2014-08-14 03:38:34.000000000 +0200
  50024. +++ linux-imx6-3.14/block/blk-cgroup.c 2014-09-11 18:05:59.118026454 +0200
  50025. @@ -859,13 +859,6 @@
  50026. {
  50027. lockdep_assert_held(q->queue_lock);
  50028. - /*
  50029. - * @q could be exiting and already have destroyed all blkgs as
  50030. - * indicated by NULL root_blkg. If so, don't confuse policies.
  50031. - */
  50032. - if (!q->root_blkg)
  50033. - return;
  50034. -
  50035. blk_throtl_drain(q);
  50036. }
  50037. diff -Nur linux-3.14.17/block/blk-core.c linux-imx6-3.14/block/blk-core.c
  50038. --- linux-3.14.17/block/blk-core.c 2014-08-14 03:38:34.000000000 +0200
  50039. +++ linux-imx6-3.14/block/blk-core.c 2014-09-11 18:05:59.122026470 +0200
  50040. @@ -1928,7 +1928,7 @@
  50041. * in some cases below, so export this function.
  50042. * Request stacking drivers like request-based dm may change the queue
  50043. * limits while requests are in the queue (e.g. dm's table swapping).
  50044. - * Such request stacking drivers should check those requests agaist
  50045. + * Such request stacking drivers should check those requests against
  50046. * the new queue limits again when they dispatch those requests,
  50047. * although such checkings are also done against the old queue limits
  50048. * when submitting requests.
  50049. diff -Nur linux-3.14.17/block/blk-map.c linux-imx6-3.14/block/blk-map.c
  50050. --- linux-3.14.17/block/blk-map.c 2014-08-14 03:38:34.000000000 +0200
  50051. +++ linux-imx6-3.14/block/blk-map.c 2014-09-11 18:05:59.122026470 +0200
  50052. @@ -285,7 +285,7 @@
  50053. *
  50054. * Description:
  50055. * Data will be mapped directly if possible. Otherwise a bounce
  50056. - * buffer is used. Can be called multple times to append multple
  50057. + * buffer is used. Can be called multiple times to append multiple
  50058. * buffers.
  50059. */
  50060. int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf,
  50061. diff -Nur linux-3.14.17/block/blk-tag.c linux-imx6-3.14/block/blk-tag.c
  50062. --- linux-3.14.17/block/blk-tag.c 2014-08-14 03:38:34.000000000 +0200
  50063. +++ linux-imx6-3.14/block/blk-tag.c 2014-09-11 18:05:59.122026470 +0200
  50064. @@ -27,15 +27,18 @@
  50065. EXPORT_SYMBOL(blk_queue_find_tag);
  50066. /**
  50067. - * blk_free_tags - release a given set of tag maintenance info
  50068. + * __blk_free_tags - release a given set of tag maintenance info
  50069. * @bqt: the tag map to free
  50070. *
  50071. - * Drop the reference count on @bqt and frees it when the last reference
  50072. - * is dropped.
  50073. + * Tries to free the specified @bqt. Returns true if it was
  50074. + * actually freed and false if there are still references using it
  50075. */
  50076. -void blk_free_tags(struct blk_queue_tag *bqt)
  50077. +static int __blk_free_tags(struct blk_queue_tag *bqt)
  50078. {
  50079. - if (atomic_dec_and_test(&bqt->refcnt)) {
  50080. + int retval;
  50081. +
  50082. + retval = atomic_dec_and_test(&bqt->refcnt);
  50083. + if (retval) {
  50084. BUG_ON(find_first_bit(bqt->tag_map, bqt->max_depth) <
  50085. bqt->max_depth);
  50086. @@ -47,8 +50,9 @@
  50087. kfree(bqt);
  50088. }
  50089. +
  50090. + return retval;
  50091. }
  50092. -EXPORT_SYMBOL(blk_free_tags);
  50093. /**
  50094. * __blk_queue_free_tags - release tag maintenance info
  50095. @@ -65,13 +69,28 @@
  50096. if (!bqt)
  50097. return;
  50098. - blk_free_tags(bqt);
  50099. + __blk_free_tags(bqt);
  50100. q->queue_tags = NULL;
  50101. queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q);
  50102. }
  50103. /**
  50104. + * blk_free_tags - release a given set of tag maintenance info
  50105. + * @bqt: the tag map to free
  50106. + *
  50107. + * For externally managed @bqt frees the map. Callers of this
  50108. + * function must guarantee to have released all the queues that
  50109. + * might have been using this tag map.
  50110. + */
  50111. +void blk_free_tags(struct blk_queue_tag *bqt)
  50112. +{
  50113. + if (unlikely(!__blk_free_tags(bqt)))
  50114. + BUG();
  50115. +}
  50116. +EXPORT_SYMBOL(blk_free_tags);
  50117. +
  50118. +/**
  50119. * blk_queue_free_tags - release tag maintenance info
  50120. * @q: the request queue for the device
  50121. *
  50122. diff -Nur linux-3.14.17/block/compat_ioctl.c linux-imx6-3.14/block/compat_ioctl.c
  50123. --- linux-3.14.17/block/compat_ioctl.c 2014-08-14 03:38:34.000000000 +0200
  50124. +++ linux-imx6-3.14/block/compat_ioctl.c 2014-09-11 18:05:59.126026486 +0200
  50125. @@ -690,7 +690,6 @@
  50126. case BLKROSET:
  50127. case BLKDISCARD:
  50128. case BLKSECDISCARD:
  50129. - case BLKZEROOUT:
  50130. /*
  50131. * the ones below are implemented in blkdev_locked_ioctl,
  50132. * but we call blkdev_ioctl, which gets the lock for us
  50133. diff -Nur linux-3.14.17/block/Kconfig.iosched linux-imx6-3.14/block/Kconfig.iosched
  50134. --- linux-3.14.17/block/Kconfig.iosched 2014-08-14 03:38:34.000000000 +0200
  50135. +++ linux-imx6-3.14/block/Kconfig.iosched 2014-09-11 18:05:59.118026454 +0200
  50136. @@ -39,6 +39,27 @@
  50137. ---help---
  50138. Enable group IO scheduling in CFQ.
  50139. +config IOSCHED_BFQ
  50140. + tristate "BFQ I/O scheduler"
  50141. + default n
  50142. + ---help---
  50143. + The BFQ I/O scheduler tries to distribute bandwidth among
  50144. + all processes according to their weights.
  50145. + It aims at distributing the bandwidth as desired, independently of
  50146. + the disk parameters and with any workload. It also tries to
  50147. + guarantee low latency to interactive and soft real-time
  50148. + applications. If compiled built-in (saying Y here), BFQ can
  50149. + be configured to support hierarchical scheduling.
  50150. +
  50151. +config CGROUP_BFQIO
  50152. + bool "BFQ hierarchical scheduling support"
  50153. + depends on CGROUPS && IOSCHED_BFQ=y
  50154. + default n
  50155. + ---help---
  50156. + Enable hierarchical scheduling in BFQ, using the cgroups
  50157. + filesystem interface. The name of the subsystem will be
  50158. + bfqio.
  50159. +
  50160. choice
  50161. prompt "Default I/O scheduler"
  50162. default DEFAULT_CFQ
  50163. @@ -52,6 +73,16 @@
  50164. config DEFAULT_CFQ
  50165. bool "CFQ" if IOSCHED_CFQ=y
  50166. + config DEFAULT_BFQ
  50167. + bool "BFQ" if IOSCHED_BFQ=y
  50168. + help
  50169. + Selects BFQ as the default I/O scheduler which will be
  50170. + used by default for all block devices.
  50171. + The BFQ I/O scheduler aims at distributing the bandwidth
  50172. + as desired, independently of the disk parameters and with
  50173. + any workload. It also tries to guarantee low latency to
  50174. + interactive and soft real-time applications.
  50175. +
  50176. config DEFAULT_NOOP
  50177. bool "No-op"
  50178. @@ -61,6 +92,7 @@
  50179. string
  50180. default "deadline" if DEFAULT_DEADLINE
  50181. default "cfq" if DEFAULT_CFQ
  50182. + default "bfq" if DEFAULT_BFQ
  50183. default "noop" if DEFAULT_NOOP
  50184. endmenu
  50185. diff -Nur linux-3.14.17/block/Makefile linux-imx6-3.14/block/Makefile
  50186. --- linux-3.14.17/block/Makefile 2014-08-14 03:38:34.000000000 +0200
  50187. +++ linux-imx6-3.14/block/Makefile 2014-09-11 18:05:59.118026454 +0200
  50188. @@ -16,6 +16,7 @@
  50189. obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
  50190. obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
  50191. obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
  50192. +obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o
  50193. obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o
  50194. obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o
  50195. diff -Nur linux-3.14.17/crypto/af_alg.c linux-imx6-3.14/crypto/af_alg.c
  50196. --- linux-3.14.17/crypto/af_alg.c 2014-08-14 03:38:34.000000000 +0200
  50197. +++ linux-imx6-3.14/crypto/af_alg.c 2014-09-11 18:05:59.134026519 +0200
  50198. @@ -21,7 +21,6 @@
  50199. #include <linux/module.h>
  50200. #include <linux/net.h>
  50201. #include <linux/rwsem.h>
  50202. -#include <linux/security.h>
  50203. struct alg_type_list {
  50204. const struct af_alg_type *type;
  50205. @@ -244,7 +243,6 @@
  50206. sock_init_data(newsock, sk2);
  50207. sock_graft(sk2, newsock);
  50208. - security_sk_clone(sk, sk2);
  50209. err = type->accept(ask->private, sk2);
  50210. if (err) {
  50211. diff -Nur linux-3.14.17/crypto/blkcipher.c linux-imx6-3.14/crypto/blkcipher.c
  50212. --- linux-3.14.17/crypto/blkcipher.c 2014-08-14 03:38:34.000000000 +0200
  50213. +++ linux-imx6-3.14/crypto/blkcipher.c 2014-09-11 18:05:59.150026582 +0200
  50214. @@ -70,14 +70,12 @@
  50215. return max(start, end_page);
  50216. }
  50217. -static inline unsigned int blkcipher_done_slow(struct crypto_blkcipher *tfm,
  50218. - struct blkcipher_walk *walk,
  50219. +static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk,
  50220. unsigned int bsize)
  50221. {
  50222. u8 *addr;
  50223. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  50224. - addr = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
  50225. + addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
  50226. addr = blkcipher_get_spot(addr, bsize);
  50227. scatterwalk_copychunks(addr, &walk->out, bsize, 1);
  50228. return bsize;
  50229. @@ -105,7 +103,6 @@
  50230. int blkcipher_walk_done(struct blkcipher_desc *desc,
  50231. struct blkcipher_walk *walk, int err)
  50232. {
  50233. - struct crypto_blkcipher *tfm = desc->tfm;
  50234. unsigned int nbytes = 0;
  50235. if (likely(err >= 0)) {
  50236. @@ -117,7 +114,7 @@
  50237. err = -EINVAL;
  50238. goto err;
  50239. } else
  50240. - n = blkcipher_done_slow(tfm, walk, n);
  50241. + n = blkcipher_done_slow(walk, n);
  50242. nbytes = walk->total - n;
  50243. err = 0;
  50244. @@ -136,7 +133,7 @@
  50245. }
  50246. if (walk->iv != desc->info)
  50247. - memcpy(desc->info, walk->iv, crypto_blkcipher_ivsize(tfm));
  50248. + memcpy(desc->info, walk->iv, walk->ivsize);
  50249. if (walk->buffer != walk->page)
  50250. kfree(walk->buffer);
  50251. if (walk->page)
  50252. @@ -226,22 +223,20 @@
  50253. static int blkcipher_walk_next(struct blkcipher_desc *desc,
  50254. struct blkcipher_walk *walk)
  50255. {
  50256. - struct crypto_blkcipher *tfm = desc->tfm;
  50257. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  50258. unsigned int bsize;
  50259. unsigned int n;
  50260. int err;
  50261. n = walk->total;
  50262. - if (unlikely(n < crypto_blkcipher_blocksize(tfm))) {
  50263. + if (unlikely(n < walk->cipher_blocksize)) {
  50264. desc->flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
  50265. return blkcipher_walk_done(desc, walk, -EINVAL);
  50266. }
  50267. walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
  50268. BLKCIPHER_WALK_DIFF);
  50269. - if (!scatterwalk_aligned(&walk->in, alignmask) ||
  50270. - !scatterwalk_aligned(&walk->out, alignmask)) {
  50271. + if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
  50272. + !scatterwalk_aligned(&walk->out, walk->alignmask)) {
  50273. walk->flags |= BLKCIPHER_WALK_COPY;
  50274. if (!walk->page) {
  50275. walk->page = (void *)__get_free_page(GFP_ATOMIC);
  50276. @@ -250,12 +245,12 @@
  50277. }
  50278. }
  50279. - bsize = min(walk->blocksize, n);
  50280. + bsize = min(walk->walk_blocksize, n);
  50281. n = scatterwalk_clamp(&walk->in, n);
  50282. n = scatterwalk_clamp(&walk->out, n);
  50283. if (unlikely(n < bsize)) {
  50284. - err = blkcipher_next_slow(desc, walk, bsize, alignmask);
  50285. + err = blkcipher_next_slow(desc, walk, bsize, walk->alignmask);
  50286. goto set_phys_lowmem;
  50287. }
  50288. @@ -277,28 +272,26 @@
  50289. return err;
  50290. }
  50291. -static inline int blkcipher_copy_iv(struct blkcipher_walk *walk,
  50292. - struct crypto_blkcipher *tfm,
  50293. - unsigned int alignmask)
  50294. -{
  50295. - unsigned bs = walk->blocksize;
  50296. - unsigned int ivsize = crypto_blkcipher_ivsize(tfm);
  50297. - unsigned aligned_bs = ALIGN(bs, alignmask + 1);
  50298. - unsigned int size = aligned_bs * 2 + ivsize + max(aligned_bs, ivsize) -
  50299. - (alignmask + 1);
  50300. +static inline int blkcipher_copy_iv(struct blkcipher_walk *walk)
  50301. +{
  50302. + unsigned bs = walk->walk_blocksize;
  50303. + unsigned aligned_bs = ALIGN(bs, walk->alignmask + 1);
  50304. + unsigned int size = aligned_bs * 2 +
  50305. + walk->ivsize + max(aligned_bs, walk->ivsize) -
  50306. + (walk->alignmask + 1);
  50307. u8 *iv;
  50308. - size += alignmask & ~(crypto_tfm_ctx_alignment() - 1);
  50309. + size += walk->alignmask & ~(crypto_tfm_ctx_alignment() - 1);
  50310. walk->buffer = kmalloc(size, GFP_ATOMIC);
  50311. if (!walk->buffer)
  50312. return -ENOMEM;
  50313. - iv = (u8 *)ALIGN((unsigned long)walk->buffer, alignmask + 1);
  50314. + iv = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
  50315. iv = blkcipher_get_spot(iv, bs) + aligned_bs;
  50316. iv = blkcipher_get_spot(iv, bs) + aligned_bs;
  50317. - iv = blkcipher_get_spot(iv, ivsize);
  50318. + iv = blkcipher_get_spot(iv, walk->ivsize);
  50319. - walk->iv = memcpy(iv, walk->iv, ivsize);
  50320. + walk->iv = memcpy(iv, walk->iv, walk->ivsize);
  50321. return 0;
  50322. }
  50323. @@ -306,7 +299,10 @@
  50324. struct blkcipher_walk *walk)
  50325. {
  50326. walk->flags &= ~BLKCIPHER_WALK_PHYS;
  50327. - walk->blocksize = crypto_blkcipher_blocksize(desc->tfm);
  50328. + walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  50329. + walk->cipher_blocksize = walk->walk_blocksize;
  50330. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  50331. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  50332. return blkcipher_walk_first(desc, walk);
  50333. }
  50334. EXPORT_SYMBOL_GPL(blkcipher_walk_virt);
  50335. @@ -315,7 +311,10 @@
  50336. struct blkcipher_walk *walk)
  50337. {
  50338. walk->flags |= BLKCIPHER_WALK_PHYS;
  50339. - walk->blocksize = crypto_blkcipher_blocksize(desc->tfm);
  50340. + walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  50341. + walk->cipher_blocksize = walk->walk_blocksize;
  50342. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  50343. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  50344. return blkcipher_walk_first(desc, walk);
  50345. }
  50346. EXPORT_SYMBOL_GPL(blkcipher_walk_phys);
  50347. @@ -323,9 +322,6 @@
  50348. static int blkcipher_walk_first(struct blkcipher_desc *desc,
  50349. struct blkcipher_walk *walk)
  50350. {
  50351. - struct crypto_blkcipher *tfm = desc->tfm;
  50352. - unsigned int alignmask = crypto_blkcipher_alignmask(tfm);
  50353. -
  50354. if (WARN_ON_ONCE(in_irq()))
  50355. return -EDEADLK;
  50356. @@ -335,8 +331,8 @@
  50357. walk->buffer = NULL;
  50358. walk->iv = desc->info;
  50359. - if (unlikely(((unsigned long)walk->iv & alignmask))) {
  50360. - int err = blkcipher_copy_iv(walk, tfm, alignmask);
  50361. + if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
  50362. + int err = blkcipher_copy_iv(walk);
  50363. if (err)
  50364. return err;
  50365. }
  50366. @@ -353,11 +349,28 @@
  50367. unsigned int blocksize)
  50368. {
  50369. walk->flags &= ~BLKCIPHER_WALK_PHYS;
  50370. - walk->blocksize = blocksize;
  50371. + walk->walk_blocksize = blocksize;
  50372. + walk->cipher_blocksize = crypto_blkcipher_blocksize(desc->tfm);
  50373. + walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
  50374. + walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
  50375. return blkcipher_walk_first(desc, walk);
  50376. }
  50377. EXPORT_SYMBOL_GPL(blkcipher_walk_virt_block);
  50378. +int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
  50379. + struct blkcipher_walk *walk,
  50380. + struct crypto_aead *tfm,
  50381. + unsigned int blocksize)
  50382. +{
  50383. + walk->flags &= ~BLKCIPHER_WALK_PHYS;
  50384. + walk->walk_blocksize = blocksize;
  50385. + walk->cipher_blocksize = crypto_aead_blocksize(tfm);
  50386. + walk->ivsize = crypto_aead_ivsize(tfm);
  50387. + walk->alignmask = crypto_aead_alignmask(tfm);
  50388. + return blkcipher_walk_first(desc, walk);
  50389. +}
  50390. +EXPORT_SYMBOL_GPL(blkcipher_aead_walk_virt_block);
  50391. +
  50392. static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
  50393. unsigned int keylen)
  50394. {
  50395. diff -Nur linux-3.14.17/crypto/tcrypt.c linux-imx6-3.14/crypto/tcrypt.c
  50396. --- linux-3.14.17/crypto/tcrypt.c 2014-08-14 03:38:34.000000000 +0200
  50397. +++ linux-imx6-3.14/crypto/tcrypt.c 2014-09-11 18:05:59.186026726 +0200
  50398. @@ -33,6 +33,7 @@
  50399. #include <linux/jiffies.h>
  50400. #include <linux/timex.h>
  50401. #include <linux/interrupt.h>
  50402. +#include <linux/sched.h>
  50403. #include "tcrypt.h"
  50404. #include "internal.h"
  50405. @@ -447,6 +448,7 @@
  50406. goto out;
  50407. }
  50408. + schedule();
  50409. printk("test %u (%d bit key, %d byte blocks): ", i,
  50410. *keysize * 8, *b_size);
  50411. @@ -713,6 +715,7 @@
  50412. if (speed[i].klen)
  50413. crypto_hash_setkey(tfm, tvmem[0], speed[i].klen);
  50414. + schedule();
  50415. printk(KERN_INFO "test%3u "
  50416. "(%5u byte blocks,%5u bytes per update,%4u updates): ",
  50417. i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
  50418. @@ -953,6 +956,7 @@
  50419. break;
  50420. }
  50421. + schedule();
  50422. pr_info("test%3u "
  50423. "(%5u byte blocks,%5u bytes per update,%4u updates): ",
  50424. i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
  50425. @@ -1118,6 +1122,7 @@
  50426. goto out_free_req;
  50427. }
  50428. + schedule();
  50429. pr_info("test %u (%d bit key, %d byte blocks): ", i,
  50430. *keysize * 8, *b_size);
  50431. @@ -1199,6 +1204,7 @@
  50432. printk("alg %s ", *name);
  50433. printk(crypto_has_alg(*name, 0, 0) ?
  50434. "found\n" : "not found\n");
  50435. + schedule();
  50436. name++;
  50437. }
  50438. }
  50439. diff -Nur linux-3.14.17/Documentation/ABI/testing/sysfs-class-net-statistics linux-imx6-3.14/Documentation/ABI/testing/sysfs-class-net-statistics
  50440. --- linux-3.14.17/Documentation/ABI/testing/sysfs-class-net-statistics 1970-01-01 01:00:00.000000000 +0100
  50441. +++ linux-imx6-3.14/Documentation/ABI/testing/sysfs-class-net-statistics 2014-09-11 18:05:51.685996745 +0200
  50442. @@ -0,0 +1,201 @@
  50443. +What: /sys/class/<iface>/statistics/collisions
  50444. +Date: April 2005
  50445. +KernelVersion: 2.6.12
  50446. +Contact: netdev@vger.kernel.org
  50447. +Description:
  50448. + Indicates the number of collisions seen by this network device.
  50449. + This value might not be relevant with all MAC layers.
  50450. +
  50451. +What: /sys/class/<iface>/statistics/multicast
  50452. +Date: April 2005
  50453. +KernelVersion: 2.6.12
  50454. +Contact: netdev@vger.kernel.org
  50455. +Description:
  50456. + Indicates the number of multicast packets received by this
  50457. + network device.
  50458. +
  50459. +What: /sys/class/<iface>/statistics/rx_bytes
  50460. +Date: April 2005
  50461. +KernelVersion: 2.6.12
  50462. +Contact: netdev@vger.kernel.org
  50463. +Description:
  50464. + Indicates the number of bytes received by this network device.
  50465. + See the network driver for the exact meaning of when this
  50466. + value is incremented.
  50467. +
  50468. +What: /sys/class/<iface>/statistics/rx_compressed
  50469. +Date: April 2005
  50470. +KernelVersion: 2.6.12
  50471. +Contact: netdev@vger.kernel.org
  50472. +Description:
  50473. + Indicates the number of compressed packets received by this
  50474. + network device. This value might only be relevant for interfaces
  50475. + that support packet compression (e.g: PPP).
  50476. +
  50477. +What: /sys/class/<iface>/statistics/rx_crc_errors
  50478. +Date: April 2005
  50479. +KernelVersion: 2.6.12
  50480. +Contact: netdev@vger.kernel.org
  50481. +Description:
  50482. + Indicates the number of packets received with a CRC (FCS) error
  50483. + by this network device. Note that the specific meaning might
  50484. + depend on the MAC layer used by the interface.
  50485. +
  50486. +What: /sys/class/<iface>/statistics/rx_dropped
  50487. +Date: April 2005
  50488. +KernelVersion: 2.6.12
  50489. +Contact: netdev@vger.kernel.org
  50490. +Description:
  50491. + Indicates the number of packets received by the network device
  50492. + but dropped, that are not forwarded to the upper layers for
  50493. + packet processing. See the network driver for the exact
  50494. + meaning of this value.
  50495. +
  50496. +What: /sys/class/<iface>/statistics/rx_fifo_errors
  50497. +Date: April 2005
  50498. +KernelVersion: 2.6.12
  50499. +Contact: netdev@vger.kernel.org
  50500. +Description:
  50501. + Indicates the number of receive FIFO errors seen by this
  50502. + network device. See the network driver for the exact
  50503. + meaning of this value.
  50504. +
  50505. +What: /sys/class/<iface>/statistics/rx_frame_errors
  50506. +Date: April 2005
  50507. +KernelVersion: 2.6.12
  50508. +Contact: netdev@vger.kernel.org
  50509. +Description:
  50510. + Indicates the number of received frames with error, such as
  50511. + alignment errors. Note that the specific meaning depends on
  50512. + on the MAC layer protocol used. See the network driver for
  50513. + the exact meaning of this value.
  50514. +
  50515. +What: /sys/class/<iface>/statistics/rx_length_errors
  50516. +Date: April 2005
  50517. +KernelVersion: 2.6.12
  50518. +Contact: netdev@vger.kernel.org
  50519. +Description:
  50520. + Indicates the number of received error packet with a length
  50521. + error, oversized or undersized. See the network driver for the
  50522. + exact meaning of this value.
  50523. +
  50524. +What: /sys/class/<iface>/statistics/rx_missed_errors
  50525. +Date: April 2005
  50526. +KernelVersion: 2.6.12
  50527. +Contact: netdev@vger.kernel.org
  50528. +Description:
  50529. + Indicates the number of received packets that have been missed
  50530. + due to lack of capacity in the receive side. See the network
  50531. + driver for the exact meaning of this value.
  50532. +
  50533. +What: /sys/class/<iface>/statistics/rx_over_errors
  50534. +Date: April 2005
  50535. +KernelVersion: 2.6.12
  50536. +Contact: netdev@vger.kernel.org
  50537. +Description:
  50538. + Indicates the number of received packets that are oversized
  50539. + compared to what the network device is configured to accept
  50540. + (e.g: larger than MTU). See the network driver for the exact
  50541. + meaning of this value.
  50542. +
  50543. +What: /sys/class/<iface>/statistics/rx_packets
  50544. +Date: April 2005
  50545. +KernelVersion: 2.6.12
  50546. +Contact: netdev@vger.kernel.org
  50547. +Description:
  50548. + Indicates the total number of good packets received by this
  50549. + network device.
  50550. +
  50551. +What: /sys/class/<iface>/statistics/tx_aborted_errors
  50552. +Date: April 2005
  50553. +KernelVersion: 2.6.12
  50554. +Contact: netdev@vger.kernel.org
  50555. +Description:
  50556. + Indicates the number of packets that have been aborted
  50557. + during transmission by a network device (e.g: because of
  50558. + a medium collision). See the network driver for the exact
  50559. + meaning of this value.
  50560. +
  50561. +What: /sys/class/<iface>/statistics/tx_bytes
  50562. +Date: April 2005
  50563. +KernelVersion: 2.6.12
  50564. +Contact: netdev@vger.kernel.org
  50565. +Description:
  50566. + Indicates the number of bytes transmitted by a network
  50567. + device. See the network driver for the exact meaning of this
  50568. + value, in particular whether this accounts for all successfully
  50569. + transmitted packets or all packets that have been queued for
  50570. + transmission.
  50571. +
  50572. +What: /sys/class/<iface>/statistics/tx_carrier_errors
  50573. +Date: April 2005
  50574. +KernelVersion: 2.6.12
  50575. +Contact: netdev@vger.kernel.org
  50576. +Description:
  50577. + Indicates the number of packets that could not be transmitted
  50578. + because of carrier errors (e.g: physical link down). See the
  50579. + network driver for the exact meaning of this value.
  50580. +
  50581. +What: /sys/class/<iface>/statistics/tx_compressed
  50582. +Date: April 2005
  50583. +KernelVersion: 2.6.12
  50584. +Contact: netdev@vger.kernel.org
  50585. +Description:
  50586. + Indicates the number of transmitted compressed packets. Note
  50587. + this might only be relevant for devices that support
  50588. + compression (e.g: PPP).
  50589. +
  50590. +What: /sys/class/<iface>/statistics/tx_dropped
  50591. +Date: April 2005
  50592. +KernelVersion: 2.6.12
  50593. +Contact: netdev@vger.kernel.org
  50594. +Description:
  50595. + Indicates the number of packets dropped during transmission.
  50596. + See the driver for the exact reasons as to why the packets were
  50597. + dropped.
  50598. +
  50599. +What: /sys/class/<iface>/statistics/tx_errors
  50600. +Date: April 2005
  50601. +KernelVersion: 2.6.12
  50602. +Contact: netdev@vger.kernel.org
  50603. +Description:
  50604. + Indicates the number of packets in error during transmission by
  50605. + a network device. See the driver for the exact reasons as to
  50606. + why the packets were dropped.
  50607. +
  50608. +What: /sys/class/<iface>/statistics/tx_fifo_errors
  50609. +Date: April 2005
  50610. +KernelVersion: 2.6.12
  50611. +Contact: netdev@vger.kernel.org
  50612. +Description:
  50613. + Indicates the number of packets having caused a transmit
  50614. + FIFO error. See the driver for the exact reasons as to why the
  50615. + packets were dropped.
  50616. +
  50617. +What: /sys/class/<iface>/statistics/tx_heartbeat_errors
  50618. +Date: April 2005
  50619. +KernelVersion: 2.6.12
  50620. +Contact: netdev@vger.kernel.org
  50621. +Description:
  50622. + Indicates the number of packets transmitted that have been
  50623. + reported as heartbeat errors. See the driver for the exact
  50624. + reasons as to why the packets were dropped.
  50625. +
  50626. +What: /sys/class/<iface>/statistics/tx_packets
  50627. +Date: April 2005
  50628. +KernelVersion: 2.6.12
  50629. +Contact: netdev@vger.kernel.org
  50630. +Description:
  50631. + Indicates the number of packets transmitted by a network
  50632. + device. See the driver for whether this reports the number of all
  50633. + attempted or successful transmissions.
  50634. +
  50635. +What: /sys/class/<iface>/statistics/tx_window_errors
  50636. +Date: April 2005
  50637. +KernelVersion: 2.6.12
  50638. +Contact: netdev@vger.kernel.org
  50639. +Description:
  50640. + Indicates the number of packets not successfully transmitted
  50641. + due to a window collision. The specific meaning depends on the
  50642. + MAC layer used. On Ethernet this is usually used to report
  50643. + late collisions errors.
  50644. diff -Nur linux-3.14.17/Documentation/arm64/booting.txt linux-imx6-3.14/Documentation/arm64/booting.txt
  50645. --- linux-3.14.17/Documentation/arm64/booting.txt 2014-08-14 03:38:34.000000000 +0200
  50646. +++ linux-imx6-3.14/Documentation/arm64/booting.txt 2014-09-11 18:05:51.793997177 +0200
  50647. @@ -111,8 +111,14 @@
  50648. - Caches, MMUs
  50649. The MMU must be off.
  50650. Instruction cache may be on or off.
  50651. - Data cache must be off and invalidated.
  50652. - External caches (if present) must be configured and disabled.
  50653. + The address range corresponding to the loaded kernel image must be
  50654. + cleaned to the PoC. In the presence of a system cache or other
  50655. + coherent masters with caches enabled, this will typically require
  50656. + cache maintenance by VA rather than set/way operations.
  50657. + System caches which respect the architected cache maintenance by VA
  50658. + operations must be configured and may be enabled.
  50659. + System caches which do not respect architected cache maintenance by VA
  50660. + operations (not recommended) must be configured and disabled.
  50661. - Architected timers
  50662. CNTFRQ must be programmed with the timer frequency and CNTVOFF must
  50663. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt
  50664. --- linux-3.14.17/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt 1970-01-01 01:00:00.000000000 +0100
  50665. +++ linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/busfreq-imx6.txt 2014-09-11 18:05:51.825997304 +0200
  50666. @@ -0,0 +1,64 @@
  50667. +Freescale Busfreq driver
  50668. +
  50669. +It is a generic driver that manages the frequency of the DDR, AHB and AXI buses in the iMX6x architecture.
  50670. +It works for both SMP and UP systems and for both DDR3 and LPDDR2 memory types.
  50671. +
  50672. +Required properties are listed below:
  50673. +- compatible: should be "fsl,imx6_busfreq"
  50674. +- clocks: Lists the various clocks used by the busfreq driver
  50675. +- interrupts - Lists the interrupts used by the busfreq driver. This is needed only for SMP architecutre.
  50676. +- fsl,max_ddr_freq - The max ddr freq for this chip
  50677. +
  50678. +Examples:
  50679. +For SOC imx6q.dtsi:
  50680. + busfreq { /* BUSFREQ */
  50681. + compatible = "fsl,imx6_busfreq";
  50682. + clocks = <&clks 171>, <&clks 6>, <&clks 11>, <&clks 104>, <&clks 172>, <&clks 58>,
  50683. + <&clks 18>, <&clks 60>, <&clks 20>, <&clks 3>;
  50684. + clock-names = "pll2_bus", "pll2_pfd2_396m", "pll2_198m", "arm", "pll3_usb_otg", "periph",
  50685. + "periph_pre", "periph_clk2", "periph_clk2_sel", "osc";
  50686. + interrupts = <0 107 0x04>, <0 112 0x4>, <0 113 0x4>, <0 114 0x4>;
  50687. + interrupt-names = "irq_busfreq_0", "irq_busfreq_1", "irq_busfreq_2", "irq_busfreq_3";
  50688. + fsl,max_ddr_freq = <528000000>;
  50689. + };
  50690. +
  50691. +The Freescale Busfreq driver supports the following setpoints for the DDR freq:
  50692. +enum bus_freq_mode {
  50693. + BUS_FREQ_HIGH, -> The max freq the SOC supports
  50694. + BUS_FREQ_MED, -> Medium setpoint (ex 400MHz for DDR3 when the max is 528MHz)
  50695. + BUS_FREQ_AUDIO, -> Audio playback freq (50MHz)
  50696. + BUS_FREQ_LOW, -> Low power IDLE freq (24MHz)
  50697. +};
  50698. +
  50699. +Currently the Freescale Busfreq driver implementation requires drivers to call the following APIs:
  50700. +1. request_bus_freq(enum bus_freq_mode):
  50701. + The driver is requesting the system and ddr freq to be set to the requested value. The driver should call this
  50702. + API before it even enables its clocks.
  50703. +
  50704. +2. release_bus_freq(enum bus_freq_mode):
  50705. + The driver no longer needs the system and ddr freq at the required value. The driver should call this API after
  50706. + its work is done and it has disabled its clocks.
  50707. +
  50708. +Examples:
  50709. +In the IPU driver, the requesting and releasing of the required bus frequency is tied into the runtime PM implementation:
  50710. +
  50711. +int ipu_runtime_suspend(struct device *dev)
  50712. +{
  50713. + release_bus_freq(BUS_FREQ_HIGH);
  50714. + dev_dbg(dev, "ipu busfreq high release.\n");
  50715. +
  50716. + return 0;
  50717. +}
  50718. +
  50719. +int ipu_runtime_resume(struct device *dev)
  50720. +{
  50721. + request_bus_freq(BUS_FREQ_HIGH);
  50722. + dev_dbg(dev, "ipu busfreq high requst.\n");
  50723. +
  50724. + return 0;
  50725. +}
  50726. +
  50727. +static const struct dev_pm_ops ipu_pm_ops = {
  50728. + SET_RUNTIME_PM_OPS(ipu_runtime_suspend, ipu_runtime_resume, NULL)
  50729. + SET_SYSTEM_SLEEP_PM_OPS(ipu_suspend, ipu_resume)
  50730. +};
  50731. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/arm/imx/gpc.txt linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/gpc.txt
  50732. --- linux-3.14.17/Documentation/devicetree/bindings/arm/imx/gpc.txt 1970-01-01 01:00:00.000000000 +0100
  50733. +++ linux-imx6-3.14/Documentation/devicetree/bindings/arm/imx/gpc.txt 2014-09-11 18:05:51.825997304 +0200
  50734. @@ -0,0 +1,20 @@
  50735. +Freescale imx GPC bindings
  50736. +
  50737. +Optional properties:
  50738. +- fsl,cpu_pupscr_sw2iso: for powering up CPU, number of 32K clock cycle PGC will wait before negating isolation signal.
  50739. +- fsl,cpu_pupscr_sw: for powering up CPU, number of 32K clock cycle PGC will wait before asserting isolation signal.
  50740. +- fsl,cpu_pdnscr_iso2sw: for powering down CPU, number of ipg clock cycle PGC will wait before negating isolation signal.
  50741. +- fsl,cpu_pdnscr_iso: for powering down CPU, number of ipg clock cycle PGC will wait before asserting isolation signal.
  50742. +
  50743. +These properties are for adjusting the GPC PGC CPU power up/down setting, if there is no such property in dts, then default
  50744. +value in GPC PGC registers will be used.
  50745. +
  50746. +
  50747. +Example:
  50748. +
  50749. + &gpc {
  50750. + fsl,cpu_pupscr_sw2iso = <0xf>;
  50751. + fsl,cpu_pupscr_sw = <0xf>;
  50752. + fsl,cpu_pdnscr_iso2sw = <0x1>;
  50753. + fsl,cpu_pdnscr_iso = <0x1>;
  50754. + };
  50755. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/arm/pmu.txt linux-imx6-3.14/Documentation/devicetree/bindings/arm/pmu.txt
  50756. --- linux-3.14.17/Documentation/devicetree/bindings/arm/pmu.txt 2014-08-14 03:38:34.000000000 +0200
  50757. +++ linux-imx6-3.14/Documentation/devicetree/bindings/arm/pmu.txt 2014-09-11 18:05:51.825997304 +0200
  50758. @@ -17,6 +17,9 @@
  50759. "arm,arm1176-pmu"
  50760. "arm,arm1136-pmu"
  50761. - interrupts : 1 combined interrupt or 1 per core.
  50762. +- cluster : a phandle to the cluster to which it belongs
  50763. + If there are more than one cluster with same CPU type
  50764. + then there should be separate PMU nodes per cluster.
  50765. Example:
  50766. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/ata/ahci-platform.txt linux-imx6-3.14/Documentation/devicetree/bindings/ata/ahci-platform.txt
  50767. --- linux-3.14.17/Documentation/devicetree/bindings/ata/ahci-platform.txt 2014-08-14 03:38:34.000000000 +0200
  50768. +++ linux-imx6-3.14/Documentation/devicetree/bindings/ata/ahci-platform.txt 2014-09-11 18:05:51.833997337 +0200
  50769. @@ -4,12 +4,19 @@
  50770. Each SATA controller should have its own node.
  50771. Required properties:
  50772. -- compatible : compatible list, contains "snps,spear-ahci"
  50773. +- compatible : compatible list, contains "snps,spear-ahci",
  50774. + "fsl,imx53-ahci" or "fsl,imx6q-ahci"
  50775. - interrupts : <interrupt mapping for SATA IRQ>
  50776. - reg : <registers mapping>
  50777. Optional properties:
  50778. - dma-coherent : Present if dma operations are coherent
  50779. +- clocks : a list of phandle + clock specifier pairs
  50780. +- target-supply : regulator for SATA target power
  50781. +
  50782. +"fsl,imx53-ahci", "fsl,imx6q-ahci" required properties:
  50783. +- clocks : must contain the sata, sata_ref and ahb clocks
  50784. +- clock-names : must contain "ahb" for the ahb clock
  50785. Example:
  50786. sata@ffe08000 {
  50787. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/clock/imx6q-clock.txt linux-imx6-3.14/Documentation/devicetree/bindings/clock/imx6q-clock.txt
  50788. --- linux-3.14.17/Documentation/devicetree/bindings/clock/imx6q-clock.txt 2014-08-14 03:38:34.000000000 +0200
  50789. +++ linux-imx6-3.14/Documentation/devicetree/bindings/clock/imx6q-clock.txt 2014-09-11 18:05:51.837997352 +0200
  50790. @@ -89,8 +89,6 @@
  50791. gpu3d_shader 74
  50792. ipu1_podf 75
  50793. ipu2_podf 76
  50794. - ldb_di0_podf 77
  50795. - ldb_di1_podf 78
  50796. ipu1_di0_pre 79
  50797. ipu1_di1_pre 80
  50798. ipu2_di0_pre 81
  50799. @@ -220,6 +218,20 @@
  50800. lvds2_sel 205
  50801. lvds1_gate 206
  50802. lvds2_gate 207
  50803. + gpt_3m 208
  50804. + video_27m 209
  50805. + ldb_di0_div_7 210
  50806. + ldb_di1_div_7 211
  50807. + ldb_di0_div_sel 212
  50808. + ldb_di1_div_sel 213
  50809. + caam_mem 214
  50810. + caam_aclk 215
  50811. + caam_ipg 216
  50812. + epit1 217
  50813. + epit2 218
  50814. + tzasc2 219
  50815. + lvds1_in 220
  50816. + lvds1_out 221
  50817. Examples:
  50818. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt linux-imx6-3.14/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
  50819. --- linux-3.14.17/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt 2014-08-14 03:38:34.000000000 +0200
  50820. +++ linux-imx6-3.14/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt 2014-09-11 18:05:51.845997384 +0200
  50821. @@ -47,6 +47,7 @@
  50822. 20 ASRC
  50823. 21 ESAI
  50824. 22 SSI Dual FIFO (needs firmware ver >= 2)
  50825. + 23 HDMI Audio
  50826. The third cell specifies the transfer priority as below.
  50827. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt linux-imx6-3.14/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
  50828. --- linux-3.14.17/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt 1970-01-01 01:00:00.000000000 +0100
  50829. +++ linux-imx6-3.14/Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt 2014-09-11 18:05:51.845997384 +0200
  50830. @@ -0,0 +1,146 @@
  50831. +* FSL IPUv3 Display/FB
  50832. +
  50833. +The FSL IPUv3 is Image Processing Unit version 3, a part of video and graphics
  50834. +subsystem in an application processor. The goal of the IPU is to provide
  50835. +comprehensive support for the flow of data from an image sensor or/and to a
  50836. +display device.
  50837. +
  50838. +Two IPU units are on the imx6q SOC while only one IPU unit on the imx6dl SOC.
  50839. +Each IPU unit has two display interfaces.
  50840. +
  50841. +For LDB/LVDS panel, there are two LVDS channels(LVDS0 and LVDS1) which can
  50842. +transfer video data, these two channels can be used as
  50843. +split/dual/single/separate mode.
  50844. +-split mode means display data from DI0 or DI1 will send to both channels
  50845. + LVDS0+LVDS1.
  50846. +-dual mode means display data from DI0 or DI1 will be duplicated on LVDS0
  50847. + and LVDS1, it said, LVDS0 and LVDS1 has the same content.
  50848. +-single mode means only work for DI0/DI1->LVDS0 or DI0/DI1->LVDS1.
  50849. +-separate mode means you can make DI0/DI1->LVDS0 and DI0/DI1->LVDS1 work
  50850. + at the same time.
  50851. + "ldb=spl0/1" -- split mode on DI0/1
  50852. + "ldb=dul0/1" -- dual mode on DI0/1
  50853. + "ldb=sin0/1" -- single mode on LVDS0/1
  50854. + "ldb=sep0/1" -- separate mode begin from LVDS0/1
  50855. +
  50856. +Required properties for IPU:
  50857. +- bypass_reset :Bypass reset to avoid display channel being.
  50858. + stopped by probe since it may start to work in bootloader: 0 or 1.
  50859. +- compatible : should be "fsl,imx6q-ipu".
  50860. +- reg : the register address range.
  50861. +- interrupts : the error and sync interrupts request.
  50862. +- clocks : the clock sources that it depends on.
  50863. +- clock-names: the related clock names.
  50864. +- resets : IPU reset specifier. See reset.txt and fsl,imx-src.txt in
  50865. + Documentation/devicetree/bindings/reset/ for details.
  50866. +
  50867. +Required properties for fb:
  50868. +- compatible : should be "fsl,mxc_sdc_fb".
  50869. +- disp_dev : display device: "ldb", "lcd", "hdmi", "mipi_dsi".
  50870. +- mode_str : video mode string: "LDB-XGA" or "LDB-1080P60" for ldb,
  50871. + "CLAA-WVGA" for lcd, "TRULY-WVGA" for TRULY mipi_dsi lcd panel,
  50872. + "1920x1080M@60" for hdmi.
  50873. +- default_bpp : default bits per pixel: 8/16/24/32
  50874. +- int_clk : use internal clock as pixel clock: 0 or 1
  50875. +- late_init : to avoid display channel being re-initialized
  50876. + as we've probably setup the channel in bootloader: 0 or 1
  50877. +- interface_pix_fmt : display interface pixel format as below:
  50878. + RGB666 IPU_PIX_FMT_RGB666
  50879. + RGB565 IPU_PIX_FMT_RGB565
  50880. + RGB24 IPU_PIX_FMT_RGB24
  50881. + BGR24 IPU_PIX_FMT_BGR24
  50882. + GBR24 IPU_PIX_FMT_GBR24
  50883. + YUV444 IPU_PIX_FMT_YUV444
  50884. + LVDS666 IPU_PIX_FMT_LVDS666
  50885. + YUYV IPU_PIX_FMT_YUYV
  50886. + UYVY IPU_PIX_FMT_UYVY
  50887. + YVYV IPU_PIX_FMT_YVYU
  50888. + VYUY IPU_PIX_FMT_VYUY
  50889. +
  50890. +Required properties for display:
  50891. +- compatible : should be "fsl,lcd" for lcd panel, "fsl,imx6q-ldb" for ldb
  50892. +- reg : the register address range if necessary to have.
  50893. +- interrupts : the error and sync interrupts if necessary to have.
  50894. +- clocks : the clock sources that it depends on if necessary to have.
  50895. +- clock-names: the related clock names if necessary to have.
  50896. +- ipu_id : ipu id for the first display device: 0 or 1
  50897. +- disp_id : display interface id for the first display interface: 0 or 1
  50898. +- default_ifmt : save as above display interface pixel format for lcd
  50899. +- pinctrl-names : should be "default"
  50900. +- pinctrl-0 : should be pinctrl_ipu1_1 or pinctrl_ipu2_1, which depends on the
  50901. + IPU connected.
  50902. +- sec_ipu_id : secondary ipu id for the second display device(ldb only): 0 or 1
  50903. +- sec_disp_id : secondary display interface id for the second display
  50904. + device(ldb only): 0 or 1
  50905. +- ext_ref : reference resistor select for ldb only: 0 or 1
  50906. +- mode : ldb mode as below:
  50907. + spl0 LDB_SPL_DI0
  50908. + spl1 LDB_SPL_DI1
  50909. + dul0 LDB_DUL_DI0
  50910. + dul1 LDB_DUL_DI1
  50911. + sin0 LDB_SIN0
  50912. + sin1 LDB_SIN1
  50913. + sep0 LDB_SEP0
  50914. + sep1 LDB_SEP1
  50915. +- gpr : the mux controller for the display engine's display interfaces and the display encoder
  50916. + (only valid for mipi dsi now).
  50917. +- disp-power-on-supply : the regulator to control display panel's power.
  50918. + (only valid for mipi dsi now).
  50919. +- resets : the gpio pin to reset the display device(only valid for mipi display panel now).
  50920. +- lcd_panel : the video mode name for the display device(only valid for mipi display panel now).
  50921. +- dev_id : the display engine's identity within the system, which intends to replace ipu_id
  50922. + (only valid for mipi dsi now).
  50923. +
  50924. +Example for IPU:
  50925. + ipu1: ipu@02400000 {
  50926. + compatible = "fsl,imx6q-ipu";
  50927. + reg = <0x02400000 0x400000>;
  50928. + interrupts = <0 6 0x4 0 5 0x4>;
  50929. + clocks = <&clks 130>, <&clks 131>, <&clks 132>,
  50930. + <&clks 39>, <&clks 40>,
  50931. + <&clks 135>, <&clks 136>;
  50932. + clock-names = "bus", "di0", "di1",
  50933. + "di0_sel", "di1_sel",
  50934. + "ldb_di0", "ldb_di1";
  50935. + resets = <&src 2>;
  50936. + bypass_reset = <0>;
  50937. + };
  50938. +
  50939. +Example for fb:
  50940. + fb0 {
  50941. + compatible = "fsl,mxc_sdc_fb";
  50942. + disp_dev = "ldb";
  50943. + interface_pix_fmt = "RGB666";
  50944. + mode_str ="LDB-XGA";
  50945. + default_bpp = <16>;
  50946. + int_clk = <0>;
  50947. + late_init = <0>;
  50948. + status = "okay";
  50949. + };
  50950. +
  50951. +Example for ldb display:
  50952. + ldb@020e0000 {
  50953. + ipu_id = <1>;
  50954. + disp_id = <0>;
  50955. + ext_ref = <1>;
  50956. + mode = "sep0";
  50957. + sec_ipu_id = <1>;
  50958. + sec_disp_id = <1>;
  50959. + status = "okay";
  50960. + };
  50961. +
  50962. +Example for mipi dsi display:
  50963. + mipi_dsi: mipi@021e0000 {
  50964. + compatible = "fsl,imx6q-mipi-dsi";
  50965. + reg = <0x021e0000 0x4000>;
  50966. + interrupts = <0 102 0x04>;
  50967. + gpr = <&gpr>;
  50968. + clocks = <&clks 138>, <&clks 204>;
  50969. + clock-names = "mipi_pllref_clk", "mipi_cfg_clk";
  50970. + dev_id = <0>;
  50971. + disp_id = <0>;
  50972. + lcd_panel = "TRULY-WVGA";
  50973. + disp-power-on-supply = <&reg_mipi_dsi_pwr_on>
  50974. + resets = <&mipi_dsi_reset>;
  50975. + status = "okay";
  50976. + };
  50977. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/leds/leds-pwm.txt linux-imx6-3.14/Documentation/devicetree/bindings/leds/leds-pwm.txt
  50978. --- linux-3.14.17/Documentation/devicetree/bindings/leds/leds-pwm.txt 2014-08-14 03:38:34.000000000 +0200
  50979. +++ linux-imx6-3.14/Documentation/devicetree/bindings/leds/leds-pwm.txt 2014-09-11 18:05:51.857997433 +0200
  50980. @@ -13,6 +13,8 @@
  50981. For the pwms and pwm-names property please refer to:
  50982. Documentation/devicetree/bindings/pwm/pwm.txt
  50983. - max-brightness : Maximum brightness possible for the LED
  50984. +- active-low : (optional) For PWMs where the LED is wired to supply
  50985. + rather than ground.
  50986. - label : (optional)
  50987. see Documentation/devicetree/bindings/leds/common.txt
  50988. - linux,default-trigger : (optional)
  50989. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/mailbox/mailbox.txt linux-imx6-3.14/Documentation/devicetree/bindings/mailbox/mailbox.txt
  50990. --- linux-3.14.17/Documentation/devicetree/bindings/mailbox/mailbox.txt 1970-01-01 01:00:00.000000000 +0100
  50991. +++ linux-imx6-3.14/Documentation/devicetree/bindings/mailbox/mailbox.txt 2014-09-11 18:05:51.857997433 +0200
  50992. @@ -0,0 +1,33 @@
  50993. +* Generic Mailbox Controller and client driver bindings
  50994. +
  50995. +Generic binding to provide a way for Mailbox controller drivers to
  50996. +assign appropriate mailbox channel to client drivers.
  50997. +
  50998. +* Mailbox Controller
  50999. +
  51000. +Required property:
  51001. +- #mbox-cells: Must be at least 1. Number of cells in a mailbox
  51002. + specifier.
  51003. +
  51004. +Example:
  51005. + mailbox: mailbox {
  51006. + ...
  51007. + #mbox-cells = <1>;
  51008. + };
  51009. +
  51010. +
  51011. +* Mailbox Client
  51012. +
  51013. +Required property:
  51014. +- mbox: List of phandle and mailbox channel specifier.
  51015. +
  51016. +- mbox-names: List of identifier strings for each mailbox channel
  51017. + required by the client.
  51018. +
  51019. +Example:
  51020. + pwr_cntrl: power {
  51021. + ...
  51022. + mbox-names = "pwr-ctrl", "rpc";
  51023. + mbox = <&mailbox 0
  51024. + &mailbox 1>;
  51025. + };
  51026. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/mlb/mlb150.txt linux-imx6-3.14/Documentation/devicetree/bindings/mlb/mlb150.txt
  51027. --- linux-3.14.17/Documentation/devicetree/bindings/mlb/mlb150.txt 1970-01-01 01:00:00.000000000 +0100
  51028. +++ linux-imx6-3.14/Documentation/devicetree/bindings/mlb/mlb150.txt 2014-09-11 18:05:51.865997464 +0200
  51029. @@ -0,0 +1,22 @@
  51030. +* Freescale Media Local Bus Host Controller (MLB) for i.MX6Q/DL
  51031. +
  51032. +The Media Local Bus Host Controller on Freescale i.MX family
  51033. +provides an interface for MOST network.
  51034. +
  51035. +Required properties:
  51036. +- compatible : Should be "fsl,<chip>-mlb150"
  51037. +- reg : Should contain mlb registers location and length
  51038. +- interrupts : Should contain mlb interrupt
  51039. +- clocks: Should contain the mlb clock sources
  51040. +- clock-names: Should be the names of mlb clock sources
  51041. +- iram : phandle pointing to the SRAM device node
  51042. +
  51043. +Examples:
  51044. +mlb@0218c000 {
  51045. + compatible = "fsl,imx6q-mlb150";
  51046. + reg = <0x0218c000 0x4000>;
  51047. + interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
  51048. + clocks = <&clks 139>, <&clks 175>;
  51049. + clock-names = "mlb", "pll8_mlb";
  51050. + iram = <&ocram>;
  51051. +};
  51052. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/mmc/mmc.txt linux-imx6-3.14/Documentation/devicetree/bindings/mmc/mmc.txt
  51053. --- linux-3.14.17/Documentation/devicetree/bindings/mmc/mmc.txt 2014-08-14 03:38:34.000000000 +0200
  51054. +++ linux-imx6-3.14/Documentation/devicetree/bindings/mmc/mmc.txt 2014-09-11 18:05:51.865997464 +0200
  51055. @@ -5,6 +5,8 @@
  51056. Interpreted by the OF core:
  51057. - reg: Registers location and length.
  51058. - interrupts: Interrupts used by the MMC controller.
  51059. +- clocks: Clocks needed for the host controller, if any.
  51060. +- clock-names: Goes with clocks above.
  51061. Card detection:
  51062. If no property below is supplied, host native card detect is used.
  51063. @@ -30,6 +32,15 @@
  51064. - cap-sdio-irq: enable SDIO IRQ signalling on this interface
  51065. - full-pwr-cycle: full power cycle of the card is supported
  51066. +Card power and reset control:
  51067. +The following properties can be specified for cases where the MMC
  51068. +peripheral needs additional reset, regulator and clock lines. It is for
  51069. +example common for WiFi/BT adapters to have these separate from the main
  51070. +MMC bus:
  51071. + - card-reset-gpios: Specify GPIOs for card reset (reset active low)
  51072. + - card-external-vcc-supply: Regulator to drive (independent) card VCC
  51073. + - clock with name "card_ext_clock": External clock provided to the card
  51074. +
  51075. *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
  51076. polarity properties, we have to fix the meaning of the "normal" and "inverted"
  51077. line levels. We choose to follow the SDHCI standard, which specifies both those
  51078. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt linux-imx6-3.14/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
  51079. --- linux-3.14.17/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 2014-08-14 03:38:34.000000000 +0200
  51080. +++ linux-imx6-3.14/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt 2014-09-11 18:05:51.905997624 +0200
  51081. @@ -71,6 +71,13 @@
  51082. name for integer state ID 0, list entry 1 for state ID 1, and
  51083. so on.
  51084. +pinctrl-assert-gpios:
  51085. + List of phandles, each pointing at a GPIO which is used by some
  51086. + board design to steer pins between two peripherals on the board.
  51087. + It plays like a board level pin multiplexer to choose different
  51088. + functions for given pins by pulling up/down the GPIOs. See
  51089. + bindings/gpio/gpio.txt for details of how to specify GPIO.
  51090. +
  51091. For example:
  51092. /* For a client device requiring named states */
  51093. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/reset/gpio-reset.txt linux-imx6-3.14/Documentation/devicetree/bindings/reset/gpio-reset.txt
  51094. --- linux-3.14.17/Documentation/devicetree/bindings/reset/gpio-reset.txt 1970-01-01 01:00:00.000000000 +0100
  51095. +++ linux-imx6-3.14/Documentation/devicetree/bindings/reset/gpio-reset.txt 2014-09-11 18:05:51.929997720 +0200
  51096. @@ -0,0 +1,35 @@
  51097. +GPIO reset controller
  51098. +=====================
  51099. +
  51100. +A GPIO reset controller controls a single GPIO that is connected to the reset
  51101. +pin of a peripheral IC. Please also refer to reset.txt in this directory for
  51102. +common reset controller binding usage.
  51103. +
  51104. +Required properties:
  51105. +- compatible: Should be "gpio-reset"
  51106. +- reset-gpios: A gpio used as reset line. The gpio specifier for this property
  51107. + depends on the gpio controller that provides the gpio.
  51108. +- #reset-cells: 0, see below
  51109. +
  51110. +Optional properties:
  51111. +- reset-delay-us: delay in microseconds. The gpio reset line will be asserted for
  51112. + this duration to reset.
  51113. +- initially-in-reset: boolean. If not set, the initial state should be a
  51114. + deasserted reset line. If this property exists, the
  51115. + reset line should be kept in reset.
  51116. +
  51117. +example:
  51118. +
  51119. +sii902x_reset: gpio-reset {
  51120. + compatible = "gpio-reset";
  51121. + reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
  51122. + reset-delay-us = <10000>;
  51123. + initially-in-reset;
  51124. + #reset-cells = <0>;
  51125. +};
  51126. +
  51127. +/* Device with nRESET pin connected to GPIO5_0 */
  51128. +sii902x@39 {
  51129. + /* ... */
  51130. + resets = <&sii902x_reset>; /* active-low GPIO5_0, 10 ms delay */
  51131. +};
  51132. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/sound/cs42888.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/cs42888.txt
  51133. --- linux-3.14.17/Documentation/devicetree/bindings/sound/cs42888.txt 1970-01-01 01:00:00.000000000 +0100
  51134. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/cs42888.txt 2014-09-11 18:05:51.937997752 +0200
  51135. @@ -0,0 +1,29 @@
  51136. +CS42888 audio CODEC
  51137. +
  51138. +This device supports I2C only.
  51139. +
  51140. +Required properties:
  51141. +
  51142. + - compatible: "cirrus,cs42888"
  51143. + - reg: the I2C address of the device.
  51144. + - clocks: Phandle to the clock node.
  51145. + - clock-names: Contains name for each entry in clocks.
  51146. + "codec_osc" : the external oscillator.
  51147. + "esai" : the hckt clock from esai.
  51148. + - <name>-supply: Phandle to the regulator <name>.
  51149. +
  51150. +Note: cs42888 needs a regulators node and a clocks node.
  51151. +
  51152. +Example:
  51153. +In this case, the clock is external oscillator.
  51154. +
  51155. +codec: cs42888@48 {
  51156. + compatible = "cirrus,cs42888";
  51157. + reg = <0x048>;
  51158. + clocks = <&codec_osc 0>;
  51159. + clock-names = "codec_osc";
  51160. + VA-supply = <&reg_audio>;
  51161. + VD-supply = <&reg_audio>;
  51162. + VLS-supply = <&reg_audio>;
  51163. + VLC-supply = <&reg_audio>;
  51164. +};
  51165. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt
  51166. --- linux-3.14.17/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt 1970-01-01 01:00:00.000000000 +0100
  51167. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/fsl-asrc-p2p.txt 2014-09-11 18:05:51.937997752 +0200
  51168. @@ -0,0 +1,23 @@
  51169. +* Freescale Asynchronous Sample Rate Converter (ASRC)
  51170. +
  51171. +This document is for asrc p2p node. p2p is one of asrc mode. asrc p2p depend on
  51172. +MXC_ASRC.
  51173. +
  51174. +Required properties:
  51175. + - compatible: Should be "fsl,<chip>-asrc-p2p".
  51176. + - fsl,output-rate: the output rate of asrc p2p. which can be <32000> to <192000>,
  51177. + - fsl,output-width: the output width of asrc p2p. which can be <16>, <24>.
  51178. + - fsl,asrc-dma-rx-events: The rx dma event of the asrc, <a b c> corresponding
  51179. + to 3 pair of asrc.
  51180. + - fsl,asrc-dma-tx-events: The tx dma event of the esai, <a b c> corresponding
  51181. + to 3 pair of asrc.
  51182. +
  51183. +Example:
  51184. +asrc_p2p: asrc_p2p {
  51185. + compatible = "fsl,imx6q-asrc-p2p";
  51186. + fsl,output-rate = <48000>;
  51187. + fsl,output-width = <16>;
  51188. + fsl,asrc-dma-rx-events = <17 18 19>;
  51189. + fsl,asrc-dma-tx-events = <20 21 22>;
  51190. + status = "okay";
  51191. +};
  51192. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt
  51193. --- linux-3.14.17/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt 1970-01-01 01:00:00.000000000 +0100
  51194. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-cs42888.txt 2014-09-11 18:05:51.937997752 +0200
  51195. @@ -0,0 +1,25 @@
  51196. +Freescale i.MX audio complex with CS42888 codec
  51197. +
  51198. +Required properties:
  51199. +- compatible : "fsl,imx-audio-cs42888"
  51200. +- model : The user-visible name of this sound complex
  51201. +- esai-controller : The phandle of the i.MX SSI controller
  51202. +- audio-codec : The phandle of the CS42888 audio codec
  51203. +
  51204. +Optional properties:
  51205. +- asrc-controller : The phandle of the i.MX ASRC controller
  51206. +- audio-routing : A list of the connections between audio components.
  51207. + Each entry is a pair of strings, the first being the connection's sink,
  51208. + the second being the connection's source. Valid names could be power
  51209. + supplies, CS42888 pins, and the jacks on the board:
  51210. +
  51211. +Example:
  51212. +
  51213. +sound {
  51214. + compatible = "fsl,imx6q-sabresd-wm8962",
  51215. + "fsl,imx-audio-wm8962";
  51216. + model = "cs42888-audio";
  51217. + esai-controller = <&esai>;
  51218. + asrc-controller = <&asrc_p2p>;
  51219. + audio-codec = <&codec>;
  51220. +};
  51221. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
  51222. --- linux-3.14.17/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt 2014-08-14 03:38:34.000000000 +0200
  51223. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt 2014-09-11 18:05:51.937997752 +0200
  51224. @@ -24,6 +24,12 @@
  51225. Note: The AUDMUX port numbering should start at 1, which is consistent with
  51226. hardware manual.
  51227. +Optional properties:
  51228. +- hp-det-gpios : The gpio pin to detect plug in/out event that happens to
  51229. + Headphone jack.
  51230. +- mic-det-gpios: The gpio pin to detect plug in/out event that happens to
  51231. + Microphone jack.
  51232. +
  51233. Example:
  51234. sound {
  51235. @@ -43,4 +49,6 @@
  51236. "DMICDAT", "DMIC";
  51237. mux-int-port = <2>;
  51238. mux-ext-port = <3>;
  51239. + hp-det-gpios = <&gpio7 8 1>;
  51240. + mic-det-gpios = <&gpio1 9 1>;
  51241. };
  51242. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/sound/wm8962.txt linux-imx6-3.14/Documentation/devicetree/bindings/sound/wm8962.txt
  51243. --- linux-3.14.17/Documentation/devicetree/bindings/sound/wm8962.txt 2014-08-14 03:38:34.000000000 +0200
  51244. +++ linux-imx6-3.14/Documentation/devicetree/bindings/sound/wm8962.txt 2014-09-11 18:05:51.949997800 +0200
  51245. @@ -13,6 +13,14 @@
  51246. of R51 (Class D Control 2) gets set, indicating that the speaker is
  51247. in mono mode.
  51248. + - amic-mono: This is a boolean property. If present, indicating that the
  51249. + analog micphone is hardware mono input, the driver would enable monomix
  51250. + for it.
  51251. +
  51252. + - dmic-mono: This is a boolean property. If present, indicating that the
  51253. + digital micphone is hardware mono input, the driver would enable monomix
  51254. + for it.
  51255. +
  51256. - mic-cfg : Default register value for R48 (Additional Control 4).
  51257. If absent, the default should be the register default.
  51258. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/usb/mxs-phy.txt linux-imx6-3.14/Documentation/devicetree/bindings/usb/mxs-phy.txt
  51259. --- linux-3.14.17/Documentation/devicetree/bindings/usb/mxs-phy.txt 2014-08-14 03:38:34.000000000 +0200
  51260. +++ linux-imx6-3.14/Documentation/devicetree/bindings/usb/mxs-phy.txt 2014-09-11 18:05:51.977997912 +0200
  51261. @@ -1,13 +1,16 @@
  51262. * Freescale MXS USB Phy Device
  51263. Required properties:
  51264. -- compatible: Should be "fsl,imx23-usbphy"
  51265. +- compatible: "fsl,imx23-usbphy" for imx23 and imx28, "fsl,imx6q-usbphy"
  51266. +for imx6dq and imx6dl, "fsl,imx6sl-usbphy" for imx6sl
  51267. - reg: Should contain registers location and length
  51268. - interrupts: Should contain phy interrupt
  51269. +- fsl,anatop: phandle for anatop register, it is only for imx6 SoC series
  51270. Example:
  51271. usbphy1: usbphy@020c9000 {
  51272. compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
  51273. reg = <0x020c9000 0x1000>;
  51274. interrupts = <0 44 0x04>;
  51275. + fsl,anatop = <&anatop>;
  51276. };
  51277. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt
  51278. --- linux-3.14.17/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt 1970-01-01 01:00:00.000000000 +0100
  51279. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,csi-v4l2-capture.txt 2014-09-11 18:05:51.981997928 +0200
  51280. @@ -0,0 +1,61 @@
  51281. +* Freescale CMOS Sensor Interface (CSI) V4L2 Capture
  51282. +
  51283. +Required properties for CSI
  51284. +- compatible: "fsl,<soc>-csi". Supported chip includes imx6sl
  51285. +- reg: Address and length of the register set for CSI
  51286. +- interrupts: Should contain CSI interrupts
  51287. +
  51288. +Required properties for v4l2_capture
  51289. +- compatible: should be "fsl,<soc>-csi-v4l2", supported socs include imx6sl
  51290. +
  51291. +Required properties for sensor
  51292. +- compatible: "<vendor>,<sensor>"
  51293. + please check the supported sensor in the Supported Sensor fields.
  51294. +- reg: sensor I2C slave address
  51295. +- pinctrl-names: should be "default" for parallel sensor
  51296. +- pinctrl-0: should depend on the connection between sensor and i.MX
  51297. + connection between sensor and i.MX could be only legacy parallel on i.MX6SL
  51298. +- clocks: should be the clock source provided to sensor.
  51299. +- clock-names: should be "csi_mclk"
  51300. +- AVDD-supply: set according to the board.
  51301. +- DVDD-supply: set according to the board.
  51302. +- pwn-gpios: set according to the board.
  51303. +- rst-gpios: set according to the board.
  51304. +- csi_id: csi id for v4l2 capture device
  51305. + should be 0 for i.MX6SL
  51306. +- mclk: should the value of mclk clock send out the sensor. unit is Hz.
  51307. +- mclk_source: should be 0 for i.MX6SL
  51308. +
  51309. +Supported Sensor
  51310. +- ovti, ov5640
  51311. +
  51312. +Example for CSI:
  51313. + csi: csi@020e4000 {
  51314. + compatible = "fsl,imx6sl-csi";
  51315. + reg = <0x020e4000 0x4000>;
  51316. + interrupts = <0 7 0x04>;
  51317. + status = "disabled";
  51318. + };
  51319. +
  51320. +Examples for v4l2_capture:
  51321. + csi_v4l2_cap {
  51322. + compatible = "fsl,imx6q-v4l2-capture";
  51323. + status = "okay";
  51324. + };
  51325. +
  51326. +Examples for sensors:
  51327. + ov564x: ov564x@3c {
  51328. + compatible = "ovti,ov564x";
  51329. + reg = <0x3c>;
  51330. + pinctrl-names = "default";
  51331. + pinctrl-0 = <&pinctrl_csi_0>;
  51332. + clocks = <&clks IMX6SL_CLK_CSI>;
  51333. + clock-names = "csi_mclk";
  51334. + AVDD-supply = <&vgen6_reg>; /* 2.8v */
  51335. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  51336. + pwn-gpios = <&gpio1 25 1>;
  51337. + rst-gpios = <&gpio1 26 0>;
  51338. + csi_id = <0>;
  51339. + mclk = <24000000>;
  51340. + mclk_source = <0>;
  51341. + };
  51342. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt
  51343. --- linux-3.14.17/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt 1970-01-01 01:00:00.000000000 +0100
  51344. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,mipi-csi2.txt 2014-09-11 18:05:51.981997928 +0200
  51345. @@ -0,0 +1,42 @@
  51346. +* Freescale MIPI CSI2 Controller for i.MX6DQ/i.MX6SDL
  51347. +
  51348. +Required properties for mipi csi2 controller:
  51349. +- compatible: should be "fsl,imx6q-mipi-csi2"
  51350. +- reg: <base addr, range> contains mipi csi2 register base address and range
  51351. +- interrupts: <type num flag> where type is a interrupt type, num is the
  51352. + interrupt number and flag is a field that level/trigger information for
  51353. + the interrupt.
  51354. +- clocks: the clock sources that mipi csi2 depends on.
  51355. +- clock-names: the name is related to the clock source one by one.
  51356. +- status: should be set to "disable".
  51357. +
  51358. +Required properties for mipi csi2 on specified board:
  51359. +- ipu_id: ipu id which mipi csi2 connected to.
  51360. + should be 0 or 1 for i.MX6DQ; should be 0 for i.MX6SDL
  51361. +- csi_id: csi id which mipi csi2 connected to.
  51362. + should be 0 or 1 for i.MX6DQ/i.MX6SDL
  51363. +- v_channel: virtual channel which send to MIPI CSI2 controller
  51364. + should keep consistent with the input MIPI signal.
  51365. +- lanes: data lanes of input MIPI signal. The maximum data lanes is 4.
  51366. + should keep consistent with the input MIPI signal.
  51367. +- status: should be set to "okay".
  51368. +
  51369. +Examples:
  51370. +for SOC imx6qdl.dtsi:
  51371. + mipi_csi@021dc000 {
  51372. + compatible = "fsl,imx6q-mipi-csi2";
  51373. + reg = <0x021dc000 0x4000>;
  51374. + interrupts = <0 100 0x04>, <0 101 0x04>;
  51375. + clocks = <&clks 138>, <&clks 53>, <&clks 204>;
  51376. + clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
  51377. + status = "disabled";
  51378. + };
  51379. +
  51380. +for board imx6qdl-sabresd.dtsi:
  51381. + mipi_csi@021dc000 {
  51382. + status = "okay";
  51383. + ipu_id = <0>;
  51384. + csi_id = <1>;
  51385. + v_channel = <0>;
  51386. + lanes = <2>;
  51387. + };
  51388. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/video/fsl,pxp.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,pxp.txt
  51389. --- linux-3.14.17/Documentation/devicetree/bindings/video/fsl,pxp.txt 1970-01-01 01:00:00.000000000 +0100
  51390. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,pxp.txt 2014-09-11 18:05:51.981997928 +0200
  51391. @@ -0,0 +1,30 @@
  51392. +* Freescale PxP Controller for i.MX6DL, i.MX6SL
  51393. +
  51394. +Required properties for PxP controller:
  51395. +- compatible: should be "fsl,<soc>-pxp-dma"
  51396. +- reg: <base addr, range> contains pxp register base address and range
  51397. +- interrupts: <type num flag> where type is an interrupt type, num is the
  51398. + interrupt number and flag is a field that level/trigger information for
  51399. + the interrupt.
  51400. +- clocks: the clock sources that pxp depends on.
  51401. +- clock-names: the name is related to the clock source
  51402. +
  51403. +Required properties for pxp on specified board:
  51404. +- status: should be set to "okay" if want to use PxP
  51405. +
  51406. +Examples:
  51407. +for SOC imx6dl.dtsi:
  51408. + pxp@020f0000 {
  51409. + compatible = "fsl,imx6dl-pxp-dma";
  51410. + reg = <0x020f0000 0x4000>;
  51411. + interrupts = <0 98 0x04>;
  51412. + clocks = <&clks 133>;
  51413. + clock-names = "pxp-axi";
  51414. + status = "disabled";
  51415. + };
  51416. +
  51417. +
  51418. +for board imx6dl-sabresd.dts:
  51419. + &pxp {
  51420. + status = "okay";
  51421. + };
  51422. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt
  51423. --- linux-3.14.17/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt 1970-01-01 01:00:00.000000000 +0100
  51424. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/fsl,v4l2-capture.txt 2014-09-11 18:05:51.981997928 +0200
  51425. @@ -0,0 +1,102 @@
  51426. +* Freescale V4L2 Capture for i.MX6DQ/i.MX6SDL
  51427. +
  51428. +Required board properties for IPUv3 capture:
  51429. +- clocks: should include the clock provided by i.MX6 to sensor
  51430. +- clock-names: sensor clock's name should be "ipux_csiy"
  51431. + x should be 1 or 2 for i.MX6DQ; should be 1 for i.MX6SDL
  51432. + y is 0 or 1 for i.MX6DQ/i.MX6SDL
  51433. +Note: other detailed information for IPUv3, please refer to
  51434. +Documentation/devicetree/bindings/fb/fsl_ipuv3_fb.txt
  51435. +
  51436. +Required properties for v4l2_capture
  51437. +- compatible: should be "fsl,imx6q-v4l2-capture"
  51438. +- ipu_id: ipu id for v4l2 capture device
  51439. + should be 0 or 1 for i.MX6DQ; should be 0 for i.MX6SDL
  51440. +- csi_id: csi id for v4l2 capture device
  51441. + should be 0 or 1 for i.MX6DQ/i.MX6SDL
  51442. +- mclk_source: should be 0 or 1. two mclk sources at most now
  51443. +- status: should be set to "okay" to enable this device
  51444. +
  51445. +Required properties for sensor
  51446. +- compatible: "<vendor>,<sensor>"
  51447. + please check the supported sensor in the Supported Sensor fields.
  51448. +- reg: sensor I2C slave address
  51449. +- pinctrl-names: should be "default" for parallel sensor
  51450. +- pinctrl-0: should depend on the connection between sensor and i.MX
  51451. + connection between sensor and i.MX could be MIPI-CSI2 or legacy parallel
  51452. +- clocks: should be the clock source provided to sensor.
  51453. +- clock-names: should be "csi_mclk"
  51454. +- DOVDD-supply: set according to the board.
  51455. +- AVDD-supply: set according to the board.
  51456. +- DVDD-supply: set according to the board.
  51457. +- pwn-gpios: set according to the board.
  51458. +- rst-gpios: set according to the board.
  51459. +- csi_id: csi id for v4l2 capture device
  51460. + should be 0 or 1 for i.MX6DQ/i.MX6SDL.
  51461. +- mclk: should the value of mclk clock send out the sensor. unit is Hz.
  51462. +- mclk_source: should be 0 or 1 and should be the same as the setting in
  51463. + v4l2_capture.
  51464. +- cvbs: 1 for CVBS input, 0 YPbPr input. This property is only needed for
  51465. + adv7180 tv decoder.
  51466. +
  51467. +Supported Sensor
  51468. +- ov5640
  51469. +- ov5642
  51470. +- ov5640_mipi
  51471. +- adv7180
  51472. +
  51473. +
  51474. +Example for IPUv3 including capture settings on imx6q-sabresd.dts:
  51475. + ipu1: ipu@02400000 { /* IPU1 */
  51476. + compatible = "fsl,imx6q-ipuv3";
  51477. + reg = <0x02400000 0x400000>;
  51478. + interrupts = <0 5 0x04>, < 0 6 0x04>;
  51479. + clocks = <&clks 130>, <&clks 131>, <&clks 132>, <&clks 39>, <&clks 40>, <&clks 169>;
  51480. + clock-names = "ipu1", "ipu1_di0", "ipu1_di1", "ipu1_di0_sel", "ipu1_di1_sel", "ipu1_csi0";
  51481. + status = "disabled";
  51482. + };
  51483. +
  51484. +Examples for v4l2_capture:
  51485. + v4l2_cap {
  51486. + compatible = "fsl,imx6q-v4l2-capture";
  51487. + ipu_id = <0>;
  51488. + csi_id = <0>;
  51489. + mclk_source = <0>;
  51490. + status = "okay";
  51491. + };
  51492. +
  51493. +Examples for sensors:
  51494. + ov5642: ov5642@3c {
  51495. + compatible = "ovti,ov5642";
  51496. + reg = <0x3c>;
  51497. + pinctrl-names = "default";
  51498. + pinctrl-0 = <&pinctrl_ipu1_2>;
  51499. + clocks = <&clks 201>;
  51500. + clock-names = "csi_mclk";
  51501. + DOVDD-supply = <&vgen4_reg>; /* 1.8v */
  51502. + AVDD-supply = <&vgen3_reg>; /* 2.8v, on rev C board is VGEN3 */
  51503. + DVDD-supply = <&vgen2_reg>; /* 1.5v*/
  51504. + pwn-gpios = <&gpio1 16 1>; /* active low: SD1_DAT0 */
  51505. + rst-gpios = <&gpio1 17 0>; /* active high: SD1_DAT1 */
  51506. + csi_id = <0>;
  51507. + mclk = <24000000>;
  51508. + mclk_source = <0>;
  51509. + };
  51510. +
  51511. + adv7180: adv7180@21 {
  51512. + compatible = "adv,adv7180";
  51513. + reg = <0x21>;
  51514. + pinctrl-names = "default";
  51515. + pinctrl-0 = <&pinctrl_ipu1_3>;
  51516. + clocks = <&clks 201>;
  51517. + clock-names = "csi_mclk";
  51518. + DOVDD-supply = <&reg_3p3v>; /* 3.3v, enabled via 2.8 VGEN6 */
  51519. + AVDD-supply = <&reg_3p3v>; /* 1.8v */
  51520. + DVDD-supply = <&reg_3p3v>; /* 1.8v */
  51521. + PVDD-supply = <&reg_3p3v>; /* 1.8v */
  51522. + pwn-gpios = <&max7310_b 2 0>;
  51523. + csi_id = <0>;
  51524. + mclk = <24000000>;
  51525. + mclk_source = <0>;
  51526. + cvbs = <1>;
  51527. + };
  51528. diff -Nur linux-3.14.17/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt linux-imx6-3.14/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt
  51529. --- linux-3.14.17/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt 1970-01-01 01:00:00.000000000 +0100
  51530. +++ linux-imx6-3.14/Documentation/devicetree/bindings/video/mxc_hdmi_video.txt 2014-09-11 18:05:51.981997928 +0200
  51531. @@ -0,0 +1,20 @@
  51532. +Device-Tree bindings for hdmi video driver
  51533. +
  51534. +Required properties:
  51535. +- compatible: value should be "fsl,imx6q-hdmi-video".
  51536. +- fsl,hdcp: define the property in dts, hdmi driver will initalize for hdcp,
  51537. + otherwise hdcp function will not supported.
  51538. +- fsl,phy_reg_vlev: hdmi phy register,Voltage Level Control Register offset 0x0e,
  51539. + adjust hdmi phy signal voltage level.
  51540. +- fsl,phy_reg_cksymtx: hdmi phy register, clock symbol and transmitter control
  51541. + register offset 0x09, adjust hdmi signal pre-emphasis.
  51542. +
  51543. +Example:
  51544. +
  51545. + hdmi_video {
  51546. + compatible = "fsl,imx6q-hdmi-video";
  51547. + fsl,hdcp;
  51548. + fsl,phy_reg_vlev = <0x0294>;
  51549. + fsl,phy_reg_cksymtx = <0x800d>;
  51550. + };
  51551. +
  51552. diff -Nur linux-3.14.17/Documentation/filesystems/hfsplus.txt linux-imx6-3.14/Documentation/filesystems/hfsplus.txt
  51553. --- linux-3.14.17/Documentation/filesystems/hfsplus.txt 2014-08-14 03:38:34.000000000 +0200
  51554. +++ linux-imx6-3.14/Documentation/filesystems/hfsplus.txt 2014-09-11 18:05:52.081998328 +0200
  51555. @@ -56,4 +56,4 @@
  51556. kernel source: <file:fs/hfsplus>
  51557. -Apple Technote 1150 http://developer.apple.com/technotes/tn/tn1150.html
  51558. +Apple Technote 1150 https://developer.apple.com/legacy/library/technotes/tn/tn1150.html
  51559. diff -Nur linux-3.14.17/Documentation/kernel-parameters.txt linux-imx6-3.14/Documentation/kernel-parameters.txt
  51560. --- linux-3.14.17/Documentation/kernel-parameters.txt 2014-08-14 03:38:34.000000000 +0200
  51561. +++ linux-imx6-3.14/Documentation/kernel-parameters.txt 2014-09-11 18:05:52.177998711 +0200
  51562. @@ -603,8 +603,11 @@
  51563. Also note the kernel might malfunction if you disable
  51564. some critical bits.
  51565. - cma=nn[MG] [ARM,KNL]
  51566. - Sets the size of kernel global memory area for contiguous
  51567. + cma=nn[MG]@[start[MG][-end[MG]]]
  51568. + [ARM,X86,KNL]
  51569. + Sets the size of kernel global memory area for
  51570. + contiguous memory allocations and optionally the
  51571. + placement constraint by the physical address range of
  51572. memory allocations. For more information, see
  51573. include/linux/dma-contiguous.h
  51574. diff -Nur linux-3.14.17/Documentation/networking/gianfar.txt linux-imx6-3.14/Documentation/networking/gianfar.txt
  51575. --- linux-3.14.17/Documentation/networking/gianfar.txt 2014-08-14 03:38:34.000000000 +0200
  51576. +++ linux-imx6-3.14/Documentation/networking/gianfar.txt 2014-09-11 18:05:52.233998935 +0200
  51577. @@ -1,38 +1,8 @@
  51578. The Gianfar Ethernet Driver
  51579. -Sysfs File description
  51580. Author: Andy Fleming <afleming@freescale.com>
  51581. Updated: 2005-07-28
  51582. -SYSFS
  51583. -
  51584. -Several of the features of the gianfar driver are controlled
  51585. -through sysfs files. These are:
  51586. -
  51587. -bd_stash:
  51588. -To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
  51589. -bd_stash, echo 'off' or '0' to disable
  51590. -
  51591. -rx_stash_len:
  51592. -To stash the first n bytes of the packet in L2, echo the number
  51593. -of bytes to buf_stash_len. echo 0 to disable.
  51594. -
  51595. -WARNING: You could really screw these up if you set them too low or high!
  51596. -fifo_threshold:
  51597. -To change the number of bytes the controller needs in the
  51598. -fifo before it starts transmission, echo the number of bytes to
  51599. -fifo_thresh. Range should be 0-511.
  51600. -
  51601. -fifo_starve:
  51602. -When the FIFO has less than this many bytes during a transmit, it
  51603. -enters starve mode, and increases the priority of TX memory
  51604. -transactions. To change, echo the number of bytes to
  51605. -fifo_starve. Range should be 0-511.
  51606. -
  51607. -fifo_starve_off:
  51608. -Once in starve mode, the FIFO remains there until it has this
  51609. -many bytes. To change, echo the number of bytes to
  51610. -fifo_starve_off. Range should be 0-511.
  51611. CHECKSUM OFFLOADING
  51612. diff -Nur linux-3.14.17/Documentation/x86/x86_64/mm.txt linux-imx6-3.14/Documentation/x86/x86_64/mm.txt
  51613. --- linux-3.14.17/Documentation/x86/x86_64/mm.txt 2014-08-14 03:38:34.000000000 +0200
  51614. +++ linux-imx6-3.14/Documentation/x86/x86_64/mm.txt 2014-09-11 18:05:52.449999800 +0200
  51615. @@ -12,8 +12,6 @@
  51616. ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
  51617. ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
  51618. ... unused hole ...
  51619. -ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
  51620. -... unused hole ...
  51621. ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
  51622. ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space
  51623. ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
  51624. diff -Nur linux-3.14.17/drivers/ata/acard-ahci.c linux-imx6-3.14/drivers/ata/acard-ahci.c
  51625. --- linux-3.14.17/drivers/ata/acard-ahci.c 2014-08-14 03:38:34.000000000 +0200
  51626. +++ linux-imx6-3.14/drivers/ata/acard-ahci.c 2014-09-11 18:05:59.410027622 +0200
  51627. @@ -36,7 +36,6 @@
  51628. #include <linux/kernel.h>
  51629. #include <linux/module.h>
  51630. #include <linux/pci.h>
  51631. -#include <linux/init.h>
  51632. #include <linux/blkdev.h>
  51633. #include <linux/delay.h>
  51634. #include <linux/interrupt.h>
  51635. diff -Nur linux-3.14.17/drivers/ata/ahci.c linux-imx6-3.14/drivers/ata/ahci.c
  51636. --- linux-3.14.17/drivers/ata/ahci.c 2014-08-14 03:38:34.000000000 +0200
  51637. +++ linux-imx6-3.14/drivers/ata/ahci.c 2014-09-11 18:05:59.410027622 +0200
  51638. @@ -35,7 +35,6 @@
  51639. #include <linux/kernel.h>
  51640. #include <linux/module.h>
  51641. #include <linux/pci.h>
  51642. -#include <linux/init.h>
  51643. #include <linux/blkdev.h>
  51644. #include <linux/delay.h>
  51645. #include <linux/interrupt.h>
  51646. @@ -457,7 +456,6 @@
  51647. /* Promise */
  51648. { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */
  51649. - { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */
  51650. /* Asmedia */
  51651. { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */
  51652. @@ -583,6 +581,7 @@
  51653. unsigned long deadline)
  51654. {
  51655. struct ata_port *ap = link->ap;
  51656. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51657. bool online;
  51658. int rc;
  51659. @@ -593,7 +592,7 @@
  51660. rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  51661. deadline, &online, NULL);
  51662. - ahci_start_engine(ap);
  51663. + hpriv->start_engine(ap);
  51664. DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
  51665. @@ -608,6 +607,7 @@
  51666. {
  51667. struct ata_port *ap = link->ap;
  51668. struct ahci_port_priv *pp = ap->private_data;
  51669. + struct ahci_host_priv *hpriv = ap->host->private_data;
  51670. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  51671. struct ata_taskfile tf;
  51672. bool online;
  51673. @@ -623,7 +623,7 @@
  51674. rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  51675. deadline, &online, NULL);
  51676. - ahci_start_engine(ap);
  51677. + hpriv->start_engine(ap);
  51678. /* The pseudo configuration device on SIMG4726 attached to
  51679. * ASUS P5W-DH Deluxe doesn't send signature FIS after
  51680. @@ -1119,6 +1119,17 @@
  51681. return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
  51682. }
  51683. +static bool ahci_broken_devslp(struct pci_dev *pdev)
  51684. +{
  51685. + /* device with broken DEVSLP but still showing SDS capability */
  51686. + static const struct pci_device_id ids[] = {
  51687. + { PCI_VDEVICE(INTEL, 0x0f23)}, /* Valleyview SoC */
  51688. + {}
  51689. + };
  51690. +
  51691. + return pci_match_id(ids, pdev);
  51692. +}
  51693. +
  51694. #ifdef CONFIG_ATA_ACPI
  51695. static void ahci_gtf_filter_workaround(struct ata_host *host)
  51696. {
  51697. @@ -1370,6 +1381,10 @@
  51698. hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
  51699. + /* must set flag prior to save config in order to take effect */
  51700. + if (ahci_broken_devslp(pdev))
  51701. + hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
  51702. +
  51703. /* save initial config */
  51704. ahci_pci_save_initial_config(pdev, hpriv);
  51705. diff -Nur linux-3.14.17/drivers/ata/ahci.h linux-imx6-3.14/drivers/ata/ahci.h
  51706. --- linux-3.14.17/drivers/ata/ahci.h 2014-08-14 03:38:34.000000000 +0200
  51707. +++ linux-imx6-3.14/drivers/ata/ahci.h 2014-09-11 18:05:59.414027637 +0200
  51708. @@ -37,6 +37,8 @@
  51709. #include <linux/clk.h>
  51710. #include <linux/libata.h>
  51711. +#include <linux/phy/phy.h>
  51712. +#include <linux/regulator/consumer.h>
  51713. /* Enclosure Management Control */
  51714. #define EM_CTRL_MSG_TYPE 0x000f0000
  51715. @@ -51,6 +53,7 @@
  51716. enum {
  51717. AHCI_MAX_PORTS = 32,
  51718. + AHCI_MAX_CLKS = 3,
  51719. AHCI_MAX_SG = 168, /* hardware max is 64K */
  51720. AHCI_DMA_BOUNDARY = 0xffffffff,
  51721. AHCI_MAX_CMDS = 32,
  51722. @@ -233,6 +236,8 @@
  51723. port start (wait until
  51724. error-handling stage) */
  51725. AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */
  51726. + AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */
  51727. + AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */
  51728. /* ap->flags bits */
  51729. @@ -322,8 +327,17 @@
  51730. u32 em_loc; /* enclosure management location */
  51731. u32 em_buf_sz; /* EM buffer size in byte */
  51732. u32 em_msg_type; /* EM message type */
  51733. - struct clk *clk; /* Only for platforms supporting clk */
  51734. + bool got_runtime_pm; /* Did we do pm_runtime_get? */
  51735. + struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
  51736. + struct regulator *target_pwr; /* Optional */
  51737. + struct phy *phy; /* If platform uses phy */
  51738. void *plat_data; /* Other platform data */
  51739. + /*
  51740. + * Optional ahci_start_engine override, if not set this gets set to the
  51741. + * default ahci_start_engine during ahci_save_initial_config, this can
  51742. + * be overridden anytime before the host is activated.
  51743. + */
  51744. + void (*start_engine)(struct ata_port *ap);
  51745. };
  51746. extern int ahci_ignore_sss;
  51747. diff -Nur linux-3.14.17/drivers/ata/ahci_imx.c linux-imx6-3.14/drivers/ata/ahci_imx.c
  51748. --- linux-3.14.17/drivers/ata/ahci_imx.c 2014-08-14 03:38:34.000000000 +0200
  51749. +++ linux-imx6-3.14/drivers/ata/ahci_imx.c 2014-09-11 18:05:59.414027637 +0200
  51750. @@ -26,12 +26,29 @@
  51751. #include <linux/mfd/syscon.h>
  51752. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  51753. #include <linux/libata.h>
  51754. +#include <linux/busfreq-imx6.h>
  51755. #include "ahci.h"
  51756. enum {
  51757. - PORT_PHY_CTL = 0x178, /* Port0 PHY Control */
  51758. - PORT_PHY_CTL_PDDQ_LOC = 0x100000, /* PORT_PHY_CTL bits */
  51759. - HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
  51760. + /* Timer 1-ms Register */
  51761. + IMX_TIMER1MS = 0x00e0,
  51762. + /* Port0 PHY Control Register */
  51763. + IMX_P0PHYCR = 0x0178,
  51764. + IMX_P0PHYCR_TEST_PDDQ = 1 << 20,
  51765. + IMX_P0PHYCR_CR_READ = 1 << 19,
  51766. + IMX_P0PHYCR_CR_WRITE = 1 << 18,
  51767. + IMX_P0PHYCR_CR_CAP_DATA = 1 << 17,
  51768. + IMX_P0PHYCR_CR_CAP_ADDR = 1 << 16,
  51769. + /* Port0 PHY Status Register */
  51770. + IMX_P0PHYSR = 0x017c,
  51771. + IMX_P0PHYSR_CR_ACK = 1 << 18,
  51772. + IMX_P0PHYSR_CR_DATA_OUT = 0xffff << 0,
  51773. + /* Lane0 Output Status Register */
  51774. + IMX_LANE0_OUT_STAT = 0x2003,
  51775. + IMX_LANE0_OUT_STAT_RX_PLL_STATE = 1 << 1,
  51776. + /* Clock Reset Register */
  51777. + IMX_CLOCK_RESET = 0x7f3f,
  51778. + IMX_CLOCK_RESET_RESET = 1 << 0,
  51779. };
  51780. enum ahci_imx_type {
  51781. @@ -42,62 +59,230 @@
  51782. struct imx_ahci_priv {
  51783. struct platform_device *ahci_pdev;
  51784. enum ahci_imx_type type;
  51785. -
  51786. - /* i.MX53 clock */
  51787. - struct clk *sata_gate_clk;
  51788. - /* Common clock */
  51789. - struct clk *sata_ref_clk;
  51790. struct clk *ahb_clk;
  51791. -
  51792. struct regmap *gpr;
  51793. bool no_device;
  51794. bool first_time;
  51795. + u32 phy_params;
  51796. };
  51797. static int ahci_imx_hotplug;
  51798. module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
  51799. MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
  51800. -static int imx_sata_clock_enable(struct device *dev)
  51801. +static void ahci_imx_host_stop(struct ata_host *host);
  51802. +
  51803. +static int imx_phy_crbit_assert(void __iomem *mmio, u32 bit, bool assert)
  51804. +{
  51805. + int timeout = 10;
  51806. + u32 crval;
  51807. + u32 srval;
  51808. +
  51809. + /* Assert or deassert the bit */
  51810. + crval = readl(mmio + IMX_P0PHYCR);
  51811. + if (assert)
  51812. + crval |= bit;
  51813. + else
  51814. + crval &= ~bit;
  51815. + writel(crval, mmio + IMX_P0PHYCR);
  51816. +
  51817. + /* Wait for the cr_ack signal */
  51818. + do {
  51819. + srval = readl(mmio + IMX_P0PHYSR);
  51820. + if ((assert ? srval : ~srval) & IMX_P0PHYSR_CR_ACK)
  51821. + break;
  51822. + usleep_range(100, 200);
  51823. + } while (--timeout);
  51824. +
  51825. + return timeout ? 0 : -ETIMEDOUT;
  51826. +}
  51827. +
  51828. +static int imx_phy_reg_addressing(u16 addr, void __iomem *mmio)
  51829. {
  51830. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  51831. + u32 crval = addr;
  51832. int ret;
  51833. - if (imxpriv->type == AHCI_IMX53) {
  51834. - ret = clk_prepare_enable(imxpriv->sata_gate_clk);
  51835. - if (ret < 0) {
  51836. - dev_err(dev, "prepare-enable sata_gate clock err:%d\n",
  51837. - ret);
  51838. - return ret;
  51839. - }
  51840. + /* Supply the address on cr_data_in */
  51841. + writel(crval, mmio + IMX_P0PHYCR);
  51842. +
  51843. + /* Assert the cr_cap_addr signal */
  51844. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, true);
  51845. + if (ret)
  51846. + return ret;
  51847. +
  51848. + /* Deassert cr_cap_addr */
  51849. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_ADDR, false);
  51850. + if (ret)
  51851. + return ret;
  51852. +
  51853. + return 0;
  51854. +}
  51855. +
  51856. +static int imx_phy_reg_write(u16 val, void __iomem *mmio)
  51857. +{
  51858. + u32 crval = val;
  51859. + int ret;
  51860. +
  51861. + /* Supply the data on cr_data_in */
  51862. + writel(crval, mmio + IMX_P0PHYCR);
  51863. +
  51864. + /* Assert the cr_cap_data signal */
  51865. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, true);
  51866. + if (ret)
  51867. + return ret;
  51868. +
  51869. + /* Deassert cr_cap_data */
  51870. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_CAP_DATA, false);
  51871. + if (ret)
  51872. + return ret;
  51873. +
  51874. + if (val & IMX_CLOCK_RESET_RESET) {
  51875. + /*
  51876. + * In case we're resetting the phy, it's unable to acknowledge,
  51877. + * so we return immediately here.
  51878. + */
  51879. + crval |= IMX_P0PHYCR_CR_WRITE;
  51880. + writel(crval, mmio + IMX_P0PHYCR);
  51881. + goto out;
  51882. }
  51883. - ret = clk_prepare_enable(imxpriv->sata_ref_clk);
  51884. - if (ret < 0) {
  51885. - dev_err(dev, "prepare-enable sata_ref clock err:%d\n",
  51886. - ret);
  51887. - goto clk_err;
  51888. + /* Assert the cr_write signal */
  51889. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, true);
  51890. + if (ret)
  51891. + return ret;
  51892. +
  51893. + /* Deassert cr_write */
  51894. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_WRITE, false);
  51895. + if (ret)
  51896. + return ret;
  51897. +
  51898. +out:
  51899. + return 0;
  51900. +}
  51901. +
  51902. +static int imx_phy_reg_read(u16 *val, void __iomem *mmio)
  51903. +{
  51904. + int ret;
  51905. +
  51906. + /* Assert the cr_read signal */
  51907. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, true);
  51908. + if (ret)
  51909. + return ret;
  51910. +
  51911. + /* Capture the data from cr_data_out[] */
  51912. + *val = readl(mmio + IMX_P0PHYSR) & IMX_P0PHYSR_CR_DATA_OUT;
  51913. +
  51914. + /* Deassert cr_read */
  51915. + ret = imx_phy_crbit_assert(mmio, IMX_P0PHYCR_CR_READ, false);
  51916. + if (ret)
  51917. + return ret;
  51918. +
  51919. + return 0;
  51920. +}
  51921. +
  51922. +static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
  51923. +{
  51924. + void __iomem *mmio = hpriv->mmio;
  51925. + int timeout = 10;
  51926. + u16 val;
  51927. + int ret;
  51928. +
  51929. + /* Reset SATA PHY by setting RESET bit of PHY register CLOCK_RESET */
  51930. + ret = imx_phy_reg_addressing(IMX_CLOCK_RESET, mmio);
  51931. + if (ret)
  51932. + return ret;
  51933. + ret = imx_phy_reg_write(IMX_CLOCK_RESET_RESET, mmio);
  51934. + if (ret)
  51935. + return ret;
  51936. +
  51937. + /* Wait for PHY RX_PLL to be stable */
  51938. + do {
  51939. + usleep_range(100, 200);
  51940. + ret = imx_phy_reg_addressing(IMX_LANE0_OUT_STAT, mmio);
  51941. + if (ret)
  51942. + return ret;
  51943. + ret = imx_phy_reg_read(&val, mmio);
  51944. + if (ret)
  51945. + return ret;
  51946. + if (val & IMX_LANE0_OUT_STAT_RX_PLL_STATE)
  51947. + break;
  51948. + } while (--timeout);
  51949. +
  51950. + return timeout ? 0 : -ETIMEDOUT;
  51951. +}
  51952. +
  51953. +static int imx_sata_enable(struct ahci_host_priv *hpriv)
  51954. +{
  51955. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  51956. + struct device *dev = &imxpriv->ahci_pdev->dev;
  51957. + int ret;
  51958. +
  51959. + if (imxpriv->no_device)
  51960. + return 0;
  51961. +
  51962. + if (hpriv->target_pwr) {
  51963. + ret = regulator_enable(hpriv->target_pwr);
  51964. + if (ret)
  51965. + return ret;
  51966. }
  51967. + request_bus_freq(BUS_FREQ_HIGH);
  51968. +
  51969. + ret = ahci_platform_enable_clks(hpriv);
  51970. + if (ret < 0)
  51971. + goto disable_regulator;
  51972. +
  51973. if (imxpriv->type == AHCI_IMX6Q) {
  51974. + /*
  51975. + * set PHY Paremeters, two steps to configure the GPR13,
  51976. + * one write for rest of parameters, mask of first write
  51977. + * is 0x07ffffff, and the other one write for setting
  51978. + * the mpll_clk_en.
  51979. + */
  51980. + regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  51981. + IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
  51982. + IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
  51983. + IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
  51984. + IMX6Q_GPR13_SATA_SPD_MODE_MASK |
  51985. + IMX6Q_GPR13_SATA_MPLL_SS_EN |
  51986. + IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
  51987. + IMX6Q_GPR13_SATA_TX_BOOST_MASK |
  51988. + IMX6Q_GPR13_SATA_TX_LVL_MASK |
  51989. + IMX6Q_GPR13_SATA_MPLL_CLK_EN |
  51990. + IMX6Q_GPR13_SATA_TX_EDGE_RATE,
  51991. + imxpriv->phy_params);
  51992. regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  51993. IMX6Q_GPR13_SATA_MPLL_CLK_EN,
  51994. IMX6Q_GPR13_SATA_MPLL_CLK_EN);
  51995. +
  51996. + usleep_range(100, 200);
  51997. +
  51998. + ret = imx_sata_phy_reset(hpriv);
  51999. + if (ret) {
  52000. + dev_err(dev, "failed to reset phy: %d\n", ret);
  52001. + goto disable_regulator;
  52002. + }
  52003. }
  52004. usleep_range(1000, 2000);
  52005. return 0;
  52006. -clk_err:
  52007. - if (imxpriv->type == AHCI_IMX53)
  52008. - clk_disable_unprepare(imxpriv->sata_gate_clk);
  52009. +disable_regulator:
  52010. + release_bus_freq(BUS_FREQ_HIGH);
  52011. +
  52012. + if (hpriv->target_pwr)
  52013. + regulator_disable(hpriv->target_pwr);
  52014. +
  52015. return ret;
  52016. }
  52017. -static void imx_sata_clock_disable(struct device *dev)
  52018. +static void imx_sata_disable(struct ahci_host_priv *hpriv)
  52019. {
  52020. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  52021. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  52022. +
  52023. + if (imxpriv->no_device)
  52024. + return;
  52025. if (imxpriv->type == AHCI_IMX6Q) {
  52026. regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  52027. @@ -105,10 +290,12 @@
  52028. !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
  52029. }
  52030. - clk_disable_unprepare(imxpriv->sata_ref_clk);
  52031. + ahci_platform_disable_clks(hpriv);
  52032. - if (imxpriv->type == AHCI_IMX53)
  52033. - clk_disable_unprepare(imxpriv->sata_gate_clk);
  52034. + release_bus_freq(BUS_FREQ_HIGH);
  52035. +
  52036. + if (hpriv->target_pwr)
  52037. + regulator_disable(hpriv->target_pwr);
  52038. }
  52039. static void ahci_imx_error_handler(struct ata_port *ap)
  52040. @@ -118,7 +305,7 @@
  52041. struct ata_host *host = dev_get_drvdata(ap->dev);
  52042. struct ahci_host_priv *hpriv = host->private_data;
  52043. void __iomem *mmio = hpriv->mmio;
  52044. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
  52045. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  52046. ahci_error_handler(ap);
  52047. @@ -134,17 +321,23 @@
  52048. * without full reset once the pddq mode is enabled making it
  52049. * impossible to use as part of libata LPM.
  52050. */
  52051. - reg_val = readl(mmio + PORT_PHY_CTL);
  52052. - writel(reg_val | PORT_PHY_CTL_PDDQ_LOC, mmio + PORT_PHY_CTL);
  52053. - imx_sata_clock_disable(ap->dev);
  52054. + reg_val = readl(mmio + IMX_P0PHYCR);
  52055. + writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR);
  52056. + imx_sata_disable(hpriv);
  52057. imxpriv->no_device = true;
  52058. +
  52059. + dev_info(ap->dev, "no device found, disabling link.\n");
  52060. + dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX
  52061. + ".hotplug=1 to enable hotplug\n");
  52062. }
  52063. static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
  52064. unsigned long deadline)
  52065. {
  52066. struct ata_port *ap = link->ap;
  52067. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
  52068. + struct ata_host *host = dev_get_drvdata(ap->dev);
  52069. + struct ahci_host_priv *hpriv = host->private_data;
  52070. + struct imx_ahci_priv *imxpriv = hpriv->plat_data;
  52071. int ret = -EIO;
  52072. if (imxpriv->type == AHCI_IMX53)
  52073. @@ -156,7 +349,8 @@
  52074. }
  52075. static struct ata_port_operations ahci_imx_ops = {
  52076. - .inherits = &ahci_platform_ops,
  52077. + .inherits = &ahci_ops,
  52078. + .host_stop = ahci_imx_host_stop,
  52079. .error_handler = ahci_imx_error_handler,
  52080. .softreset = ahci_imx_softreset,
  52081. };
  52082. @@ -168,234 +362,306 @@
  52083. .port_ops = &ahci_imx_ops,
  52084. };
  52085. -static int imx_sata_init(struct device *dev, void __iomem *mmio)
  52086. -{
  52087. - int ret = 0;
  52088. - unsigned int reg_val;
  52089. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  52090. -
  52091. - ret = imx_sata_clock_enable(dev);
  52092. - if (ret < 0)
  52093. - return ret;
  52094. +static const struct of_device_id imx_ahci_of_match[] = {
  52095. + { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
  52096. + { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
  52097. + {},
  52098. +};
  52099. +MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
  52100. - /*
  52101. - * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
  52102. - * and IP vendor specific register HOST_TIMER1MS.
  52103. - * Configure CAP_SSS (support stagered spin up).
  52104. - * Implement the port0.
  52105. - * Get the ahb clock rate, and configure the TIMER1MS register.
  52106. - */
  52107. - reg_val = readl(mmio + HOST_CAP);
  52108. - if (!(reg_val & HOST_CAP_SSS)) {
  52109. - reg_val |= HOST_CAP_SSS;
  52110. - writel(reg_val, mmio + HOST_CAP);
  52111. - }
  52112. - reg_val = readl(mmio + HOST_PORTS_IMPL);
  52113. - if (!(reg_val & 0x1)) {
  52114. - reg_val |= 0x1;
  52115. - writel(reg_val, mmio + HOST_PORTS_IMPL);
  52116. - }
  52117. +struct reg_value {
  52118. + u32 of_value;
  52119. + u32 reg_value;
  52120. +};
  52121. - reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
  52122. - writel(reg_val, mmio + HOST_TIMER1MS);
  52123. +struct reg_property {
  52124. + const char *name;
  52125. + const struct reg_value *values;
  52126. + size_t num_values;
  52127. + u32 def_value;
  52128. + u32 set_value;
  52129. +};
  52130. - return 0;
  52131. -}
  52132. +static const struct reg_value gpr13_tx_level[] = {
  52133. + { 937, IMX6Q_GPR13_SATA_TX_LVL_0_937_V },
  52134. + { 947, IMX6Q_GPR13_SATA_TX_LVL_0_947_V },
  52135. + { 957, IMX6Q_GPR13_SATA_TX_LVL_0_957_V },
  52136. + { 966, IMX6Q_GPR13_SATA_TX_LVL_0_966_V },
  52137. + { 976, IMX6Q_GPR13_SATA_TX_LVL_0_976_V },
  52138. + { 986, IMX6Q_GPR13_SATA_TX_LVL_0_986_V },
  52139. + { 996, IMX6Q_GPR13_SATA_TX_LVL_0_996_V },
  52140. + { 1005, IMX6Q_GPR13_SATA_TX_LVL_1_005_V },
  52141. + { 1015, IMX6Q_GPR13_SATA_TX_LVL_1_015_V },
  52142. + { 1025, IMX6Q_GPR13_SATA_TX_LVL_1_025_V },
  52143. + { 1035, IMX6Q_GPR13_SATA_TX_LVL_1_035_V },
  52144. + { 1045, IMX6Q_GPR13_SATA_TX_LVL_1_045_V },
  52145. + { 1054, IMX6Q_GPR13_SATA_TX_LVL_1_054_V },
  52146. + { 1064, IMX6Q_GPR13_SATA_TX_LVL_1_064_V },
  52147. + { 1074, IMX6Q_GPR13_SATA_TX_LVL_1_074_V },
  52148. + { 1084, IMX6Q_GPR13_SATA_TX_LVL_1_084_V },
  52149. + { 1094, IMX6Q_GPR13_SATA_TX_LVL_1_094_V },
  52150. + { 1104, IMX6Q_GPR13_SATA_TX_LVL_1_104_V },
  52151. + { 1113, IMX6Q_GPR13_SATA_TX_LVL_1_113_V },
  52152. + { 1123, IMX6Q_GPR13_SATA_TX_LVL_1_123_V },
  52153. + { 1133, IMX6Q_GPR13_SATA_TX_LVL_1_133_V },
  52154. + { 1143, IMX6Q_GPR13_SATA_TX_LVL_1_143_V },
  52155. + { 1152, IMX6Q_GPR13_SATA_TX_LVL_1_152_V },
  52156. + { 1162, IMX6Q_GPR13_SATA_TX_LVL_1_162_V },
  52157. + { 1172, IMX6Q_GPR13_SATA_TX_LVL_1_172_V },
  52158. + { 1182, IMX6Q_GPR13_SATA_TX_LVL_1_182_V },
  52159. + { 1191, IMX6Q_GPR13_SATA_TX_LVL_1_191_V },
  52160. + { 1201, IMX6Q_GPR13_SATA_TX_LVL_1_201_V },
  52161. + { 1211, IMX6Q_GPR13_SATA_TX_LVL_1_211_V },
  52162. + { 1221, IMX6Q_GPR13_SATA_TX_LVL_1_221_V },
  52163. + { 1230, IMX6Q_GPR13_SATA_TX_LVL_1_230_V },
  52164. + { 1240, IMX6Q_GPR13_SATA_TX_LVL_1_240_V }
  52165. +};
  52166. -static void imx_sata_exit(struct device *dev)
  52167. -{
  52168. - imx_sata_clock_disable(dev);
  52169. -}
  52170. +static const struct reg_value gpr13_tx_boost[] = {
  52171. + { 0, IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB },
  52172. + { 370, IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB },
  52173. + { 740, IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB },
  52174. + { 1110, IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB },
  52175. + { 1480, IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB },
  52176. + { 1850, IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB },
  52177. + { 2220, IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB },
  52178. + { 2590, IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB },
  52179. + { 2960, IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB },
  52180. + { 3330, IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB },
  52181. + { 3700, IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB },
  52182. + { 4070, IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB },
  52183. + { 4440, IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB },
  52184. + { 4810, IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB },
  52185. + { 5280, IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB },
  52186. + { 5750, IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB }
  52187. +};
  52188. -static int imx_ahci_suspend(struct device *dev)
  52189. -{
  52190. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  52191. +static const struct reg_value gpr13_tx_atten[] = {
  52192. + { 8, IMX6Q_GPR13_SATA_TX_ATTEN_8_16 },
  52193. + { 9, IMX6Q_GPR13_SATA_TX_ATTEN_9_16 },
  52194. + { 10, IMX6Q_GPR13_SATA_TX_ATTEN_10_16 },
  52195. + { 12, IMX6Q_GPR13_SATA_TX_ATTEN_12_16 },
  52196. + { 14, IMX6Q_GPR13_SATA_TX_ATTEN_14_16 },
  52197. + { 16, IMX6Q_GPR13_SATA_TX_ATTEN_16_16 },
  52198. +};
  52199. - /*
  52200. - * If no_device is set, The CLKs had been gated off in the
  52201. - * initialization so don't do it again here.
  52202. - */
  52203. - if (!imxpriv->no_device)
  52204. - imx_sata_clock_disable(dev);
  52205. +static const struct reg_value gpr13_rx_eq[] = {
  52206. + { 500, IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB },
  52207. + { 1000, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB },
  52208. + { 1500, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB },
  52209. + { 2000, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB },
  52210. + { 2500, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB },
  52211. + { 3000, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB },
  52212. + { 3500, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB },
  52213. + { 4000, IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB },
  52214. +};
  52215. - return 0;
  52216. -}
  52217. +static const struct reg_property gpr13_props[] = {
  52218. + {
  52219. + .name = "fsl,transmit-level-mV",
  52220. + .values = gpr13_tx_level,
  52221. + .num_values = ARRAY_SIZE(gpr13_tx_level),
  52222. + .def_value = IMX6Q_GPR13_SATA_TX_LVL_1_025_V,
  52223. + }, {
  52224. + .name = "fsl,transmit-boost-mdB",
  52225. + .values = gpr13_tx_boost,
  52226. + .num_values = ARRAY_SIZE(gpr13_tx_boost),
  52227. + .def_value = IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB,
  52228. + }, {
  52229. + .name = "fsl,transmit-atten-16ths",
  52230. + .values = gpr13_tx_atten,
  52231. + .num_values = ARRAY_SIZE(gpr13_tx_atten),
  52232. + .def_value = IMX6Q_GPR13_SATA_TX_ATTEN_9_16,
  52233. + }, {
  52234. + .name = "fsl,receive-eq-mdB",
  52235. + .values = gpr13_rx_eq,
  52236. + .num_values = ARRAY_SIZE(gpr13_rx_eq),
  52237. + .def_value = IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB,
  52238. + }, {
  52239. + .name = "fsl,no-spread-spectrum",
  52240. + .def_value = IMX6Q_GPR13_SATA_MPLL_SS_EN,
  52241. + .set_value = 0,
  52242. + },
  52243. +};
  52244. -static int imx_ahci_resume(struct device *dev)
  52245. +static u32 imx_ahci_parse_props(struct device *dev,
  52246. + const struct reg_property *prop, size_t num)
  52247. {
  52248. - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
  52249. - int ret = 0;
  52250. -
  52251. - if (!imxpriv->no_device)
  52252. - ret = imx_sata_clock_enable(dev);
  52253. + struct device_node *np = dev->of_node;
  52254. + u32 reg_value = 0;
  52255. + int i, j;
  52256. +
  52257. + for (i = 0; i < num; i++, prop++) {
  52258. + u32 of_val;
  52259. +
  52260. + if (prop->num_values == 0) {
  52261. + if (of_property_read_bool(np, prop->name))
  52262. + reg_value |= prop->set_value;
  52263. + else
  52264. + reg_value |= prop->def_value;
  52265. + continue;
  52266. + }
  52267. - return ret;
  52268. -}
  52269. + if (of_property_read_u32(np, prop->name, &of_val)) {
  52270. + dev_info(dev, "%s not specified, using %08x\n",
  52271. + prop->name, prop->def_value);
  52272. + reg_value |= prop->def_value;
  52273. + continue;
  52274. + }
  52275. -static struct ahci_platform_data imx_sata_pdata = {
  52276. - .init = imx_sata_init,
  52277. - .exit = imx_sata_exit,
  52278. - .ata_port_info = &ahci_imx_port_info,
  52279. - .suspend = imx_ahci_suspend,
  52280. - .resume = imx_ahci_resume,
  52281. + for (j = 0; j < prop->num_values; j++) {
  52282. + if (prop->values[j].of_value == of_val) {
  52283. + dev_info(dev, "%s value %u, using %08x\n",
  52284. + prop->name, of_val, prop->values[j].reg_value);
  52285. + reg_value |= prop->values[j].reg_value;
  52286. + break;
  52287. + }
  52288. + }
  52289. -};
  52290. + if (j == prop->num_values) {
  52291. + dev_err(dev, "DT property %s is not a valid value\n",
  52292. + prop->name);
  52293. + reg_value |= prop->def_value;
  52294. + }
  52295. + }
  52296. -static const struct of_device_id imx_ahci_of_match[] = {
  52297. - { .compatible = "fsl,imx53-ahci", .data = (void *)AHCI_IMX53 },
  52298. - { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q },
  52299. - {},
  52300. -};
  52301. -MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
  52302. + return reg_value;
  52303. +}
  52304. static int imx_ahci_probe(struct platform_device *pdev)
  52305. {
  52306. struct device *dev = &pdev->dev;
  52307. - struct resource *mem, *irq, res[2];
  52308. const struct of_device_id *of_id;
  52309. - enum ahci_imx_type type;
  52310. - const struct ahci_platform_data *pdata = NULL;
  52311. + struct ahci_host_priv *hpriv;
  52312. struct imx_ahci_priv *imxpriv;
  52313. - struct device *ahci_dev;
  52314. - struct platform_device *ahci_pdev;
  52315. + unsigned int reg_val;
  52316. int ret;
  52317. of_id = of_match_device(imx_ahci_of_match, dev);
  52318. if (!of_id)
  52319. return -EINVAL;
  52320. - type = (enum ahci_imx_type)of_id->data;
  52321. - pdata = &imx_sata_pdata;
  52322. -
  52323. imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
  52324. - if (!imxpriv) {
  52325. - dev_err(dev, "can't alloc ahci_host_priv\n");
  52326. + if (!imxpriv)
  52327. return -ENOMEM;
  52328. - }
  52329. -
  52330. - ahci_pdev = platform_device_alloc("ahci", -1);
  52331. - if (!ahci_pdev)
  52332. - return -ENODEV;
  52333. -
  52334. - ahci_dev = &ahci_pdev->dev;
  52335. - ahci_dev->parent = dev;
  52336. + imxpriv->ahci_pdev = pdev;
  52337. imxpriv->no_device = false;
  52338. imxpriv->first_time = true;
  52339. - imxpriv->type = type;
  52340. -
  52341. + imxpriv->type = (enum ahci_imx_type)of_id->data;
  52342. imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
  52343. if (IS_ERR(imxpriv->ahb_clk)) {
  52344. dev_err(dev, "can't get ahb clock.\n");
  52345. - ret = PTR_ERR(imxpriv->ahb_clk);
  52346. - goto err_out;
  52347. - }
  52348. -
  52349. - if (type == AHCI_IMX53) {
  52350. - imxpriv->sata_gate_clk = devm_clk_get(dev, "sata_gate");
  52351. - if (IS_ERR(imxpriv->sata_gate_clk)) {
  52352. - dev_err(dev, "can't get sata_gate clock.\n");
  52353. - ret = PTR_ERR(imxpriv->sata_gate_clk);
  52354. - goto err_out;
  52355. - }
  52356. - }
  52357. -
  52358. - imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
  52359. - if (IS_ERR(imxpriv->sata_ref_clk)) {
  52360. - dev_err(dev, "can't get sata_ref clock.\n");
  52361. - ret = PTR_ERR(imxpriv->sata_ref_clk);
  52362. - goto err_out;
  52363. + return PTR_ERR(imxpriv->ahb_clk);
  52364. }
  52365. - imxpriv->ahci_pdev = ahci_pdev;
  52366. - platform_set_drvdata(pdev, imxpriv);
  52367. -
  52368. - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  52369. - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  52370. - if (!mem || !irq) {
  52371. - dev_err(dev, "no mmio/irq resource\n");
  52372. - ret = -ENOMEM;
  52373. - goto err_out;
  52374. - }
  52375. -
  52376. - res[0] = *mem;
  52377. - res[1] = *irq;
  52378. -
  52379. - ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32);
  52380. - ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
  52381. - ahci_dev->of_node = dev->of_node;
  52382. + if (imxpriv->type == AHCI_IMX6Q) {
  52383. + u32 reg_value;
  52384. - if (type == AHCI_IMX6Q) {
  52385. imxpriv->gpr = syscon_regmap_lookup_by_compatible(
  52386. "fsl,imx6q-iomuxc-gpr");
  52387. if (IS_ERR(imxpriv->gpr)) {
  52388. dev_err(dev,
  52389. "failed to find fsl,imx6q-iomux-gpr regmap\n");
  52390. - ret = PTR_ERR(imxpriv->gpr);
  52391. - goto err_out;
  52392. + return PTR_ERR(imxpriv->gpr);
  52393. }
  52394. - /*
  52395. - * Set PHY Paremeters, two steps to configure the GPR13,
  52396. - * one write for rest of parameters, mask of first write
  52397. - * is 0x07fffffe, and the other one write for setting
  52398. - * the mpll_clk_en happens in imx_sata_clock_enable().
  52399. - */
  52400. - regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
  52401. - IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK |
  52402. - IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK |
  52403. - IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK |
  52404. - IMX6Q_GPR13_SATA_SPD_MODE_MASK |
  52405. - IMX6Q_GPR13_SATA_MPLL_SS_EN |
  52406. - IMX6Q_GPR13_SATA_TX_ATTEN_MASK |
  52407. - IMX6Q_GPR13_SATA_TX_BOOST_MASK |
  52408. - IMX6Q_GPR13_SATA_TX_LVL_MASK |
  52409. - IMX6Q_GPR13_SATA_MPLL_CLK_EN |
  52410. - IMX6Q_GPR13_SATA_TX_EDGE_RATE,
  52411. - IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB |
  52412. + reg_value = imx_ahci_parse_props(dev, gpr13_props,
  52413. + ARRAY_SIZE(gpr13_props));
  52414. +
  52415. + imxpriv->phy_params =
  52416. IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
  52417. IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
  52418. IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
  52419. - IMX6Q_GPR13_SATA_MPLL_SS_EN |
  52420. - IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
  52421. - IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
  52422. - IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
  52423. + reg_value;
  52424. }
  52425. - ret = platform_device_add_resources(ahci_pdev, res, 2);
  52426. + hpriv = ahci_platform_get_resources(pdev);
  52427. + if (IS_ERR(hpriv))
  52428. + return PTR_ERR(hpriv);
  52429. +
  52430. + hpriv->plat_data = imxpriv;
  52431. +
  52432. + ret = imx_sata_enable(hpriv);
  52433. if (ret)
  52434. - goto err_out;
  52435. + return ret;
  52436. - ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
  52437. + /*
  52438. + * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
  52439. + * and IP vendor specific register IMX_TIMER1MS.
  52440. + * Configure CAP_SSS (support stagered spin up).
  52441. + * Implement the port0.
  52442. + * Get the ahb clock rate, and configure the TIMER1MS register.
  52443. + */
  52444. + reg_val = readl(hpriv->mmio + HOST_CAP);
  52445. + if (!(reg_val & HOST_CAP_SSS)) {
  52446. + reg_val |= HOST_CAP_SSS;
  52447. + writel(reg_val, hpriv->mmio + HOST_CAP);
  52448. + }
  52449. + reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL);
  52450. + if (!(reg_val & 0x1)) {
  52451. + reg_val |= 0x1;
  52452. + writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
  52453. + }
  52454. +
  52455. + reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
  52456. + writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
  52457. +
  52458. + ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
  52459. + 0, 0, 0);
  52460. if (ret)
  52461. - goto err_out;
  52462. + imx_sata_disable(hpriv);
  52463. +
  52464. + return ret;
  52465. +}
  52466. - ret = platform_device_add(ahci_pdev);
  52467. - if (ret) {
  52468. -err_out:
  52469. - platform_device_put(ahci_pdev);
  52470. +static void ahci_imx_host_stop(struct ata_host *host)
  52471. +{
  52472. + struct ahci_host_priv *hpriv = host->private_data;
  52473. +
  52474. + imx_sata_disable(hpriv);
  52475. +}
  52476. +
  52477. +#ifdef CONFIG_PM_SLEEP
  52478. +static int imx_ahci_suspend(struct device *dev)
  52479. +{
  52480. + struct ata_host *host = dev_get_drvdata(dev);
  52481. + struct ahci_host_priv *hpriv = host->private_data;
  52482. + int ret;
  52483. +
  52484. + ret = ahci_platform_suspend_host(dev);
  52485. + if (ret)
  52486. return ret;
  52487. - }
  52488. +
  52489. + imx_sata_disable(hpriv);
  52490. return 0;
  52491. }
  52492. -static int imx_ahci_remove(struct platform_device *pdev)
  52493. +static int imx_ahci_resume(struct device *dev)
  52494. {
  52495. - struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev);
  52496. - struct platform_device *ahci_pdev = imxpriv->ahci_pdev;
  52497. + struct ata_host *host = dev_get_drvdata(dev);
  52498. + struct ahci_host_priv *hpriv = host->private_data;
  52499. + int ret;
  52500. - platform_device_unregister(ahci_pdev);
  52501. - return 0;
  52502. + ret = imx_sata_enable(hpriv);
  52503. + if (ret)
  52504. + return ret;
  52505. +
  52506. + return ahci_platform_resume_host(dev);
  52507. }
  52508. +#endif
  52509. +
  52510. +static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
  52511. static struct platform_driver imx_ahci_driver = {
  52512. .probe = imx_ahci_probe,
  52513. - .remove = imx_ahci_remove,
  52514. + .remove = ata_platform_remove_one,
  52515. .driver = {
  52516. .name = "ahci-imx",
  52517. .owner = THIS_MODULE,
  52518. .of_match_table = imx_ahci_of_match,
  52519. + .pm = &ahci_imx_pm_ops,
  52520. },
  52521. };
  52522. module_platform_driver(imx_ahci_driver);
  52523. diff -Nur linux-3.14.17/drivers/ata/ahci_platform.c linux-imx6-3.14/drivers/ata/ahci_platform.c
  52524. --- linux-3.14.17/drivers/ata/ahci_platform.c 2014-08-14 03:38:34.000000000 +0200
  52525. +++ linux-imx6-3.14/drivers/ata/ahci_platform.c 2014-09-11 18:05:59.414027637 +0200
  52526. @@ -12,135 +12,36 @@
  52527. * any later version.
  52528. */
  52529. -#include <linux/clk.h>
  52530. #include <linux/kernel.h>
  52531. -#include <linux/gfp.h>
  52532. #include <linux/module.h>
  52533. #include <linux/pm.h>
  52534. -#include <linux/init.h>
  52535. -#include <linux/interrupt.h>
  52536. #include <linux/device.h>
  52537. #include <linux/platform_device.h>
  52538. #include <linux/libata.h>
  52539. #include <linux/ahci_platform.h>
  52540. #include "ahci.h"
  52541. -static void ahci_host_stop(struct ata_host *host);
  52542. -
  52543. -enum ahci_type {
  52544. - AHCI, /* standard platform ahci */
  52545. - IMX53_AHCI, /* ahci on i.mx53 */
  52546. - STRICT_AHCI, /* delayed DMA engine start */
  52547. -};
  52548. -
  52549. -static struct platform_device_id ahci_devtype[] = {
  52550. - {
  52551. - .name = "ahci",
  52552. - .driver_data = AHCI,
  52553. - }, {
  52554. - .name = "imx53-ahci",
  52555. - .driver_data = IMX53_AHCI,
  52556. - }, {
  52557. - .name = "strict-ahci",
  52558. - .driver_data = STRICT_AHCI,
  52559. - }, {
  52560. - /* sentinel */
  52561. - }
  52562. -};
  52563. -MODULE_DEVICE_TABLE(platform, ahci_devtype);
  52564. -
  52565. -struct ata_port_operations ahci_platform_ops = {
  52566. - .inherits = &ahci_ops,
  52567. - .host_stop = ahci_host_stop,
  52568. -};
  52569. -EXPORT_SYMBOL_GPL(ahci_platform_ops);
  52570. -
  52571. -static struct ata_port_operations ahci_platform_retry_srst_ops = {
  52572. - .inherits = &ahci_pmp_retry_srst_ops,
  52573. - .host_stop = ahci_host_stop,
  52574. -};
  52575. -
  52576. -static const struct ata_port_info ahci_port_info[] = {
  52577. - /* by features */
  52578. - [AHCI] = {
  52579. - .flags = AHCI_FLAG_COMMON,
  52580. - .pio_mask = ATA_PIO4,
  52581. - .udma_mask = ATA_UDMA6,
  52582. - .port_ops = &ahci_platform_ops,
  52583. - },
  52584. - [IMX53_AHCI] = {
  52585. - .flags = AHCI_FLAG_COMMON,
  52586. - .pio_mask = ATA_PIO4,
  52587. - .udma_mask = ATA_UDMA6,
  52588. - .port_ops = &ahci_platform_retry_srst_ops,
  52589. - },
  52590. - [STRICT_AHCI] = {
  52591. - AHCI_HFLAGS (AHCI_HFLAG_DELAY_ENGINE),
  52592. - .flags = AHCI_FLAG_COMMON,
  52593. - .pio_mask = ATA_PIO4,
  52594. - .udma_mask = ATA_UDMA6,
  52595. - .port_ops = &ahci_platform_ops,
  52596. - },
  52597. -};
  52598. -
  52599. -static struct scsi_host_template ahci_platform_sht = {
  52600. - AHCI_SHT("ahci_platform"),
  52601. +static const struct ata_port_info ahci_port_info = {
  52602. + .flags = AHCI_FLAG_COMMON,
  52603. + .pio_mask = ATA_PIO4,
  52604. + .udma_mask = ATA_UDMA6,
  52605. + .port_ops = &ahci_platform_ops,
  52606. };
  52607. static int ahci_probe(struct platform_device *pdev)
  52608. {
  52609. struct device *dev = &pdev->dev;
  52610. struct ahci_platform_data *pdata = dev_get_platdata(dev);
  52611. - const struct platform_device_id *id = platform_get_device_id(pdev);
  52612. - struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
  52613. - const struct ata_port_info *ppi[] = { &pi, NULL };
  52614. struct ahci_host_priv *hpriv;
  52615. - struct ata_host *host;
  52616. - struct resource *mem;
  52617. - int irq;
  52618. - int n_ports;
  52619. - int i;
  52620. int rc;
  52621. - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  52622. - if (!mem) {
  52623. - dev_err(dev, "no mmio space\n");
  52624. - return -EINVAL;
  52625. - }
  52626. -
  52627. - irq = platform_get_irq(pdev, 0);
  52628. - if (irq <= 0) {
  52629. - dev_err(dev, "no irq\n");
  52630. - return -EINVAL;
  52631. - }
  52632. -
  52633. - if (pdata && pdata->ata_port_info)
  52634. - pi = *pdata->ata_port_info;
  52635. -
  52636. - hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
  52637. - if (!hpriv) {
  52638. - dev_err(dev, "can't alloc ahci_host_priv\n");
  52639. - return -ENOMEM;
  52640. - }
  52641. -
  52642. - hpriv->flags |= (unsigned long)pi.private_data;
  52643. + hpriv = ahci_platform_get_resources(pdev);
  52644. + if (IS_ERR(hpriv))
  52645. + return PTR_ERR(hpriv);
  52646. - hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
  52647. - if (!hpriv->mmio) {
  52648. - dev_err(dev, "can't map %pR\n", mem);
  52649. - return -ENOMEM;
  52650. - }
  52651. -
  52652. - hpriv->clk = clk_get(dev, NULL);
  52653. - if (IS_ERR(hpriv->clk)) {
  52654. - dev_err(dev, "can't get clock\n");
  52655. - } else {
  52656. - rc = clk_prepare_enable(hpriv->clk);
  52657. - if (rc) {
  52658. - dev_err(dev, "clock prepare enable failed");
  52659. - goto free_clk;
  52660. - }
  52661. - }
  52662. + rc = ahci_platform_enable_resources(hpriv);
  52663. + if (rc)
  52664. + return rc;
  52665. /*
  52666. * Some platforms might need to prepare for mmio region access,
  52667. @@ -151,69 +52,10 @@
  52668. if (pdata && pdata->init) {
  52669. rc = pdata->init(dev, hpriv->mmio);
  52670. if (rc)
  52671. - goto disable_unprepare_clk;
  52672. - }
  52673. -
  52674. - ahci_save_initial_config(dev, hpriv,
  52675. - pdata ? pdata->force_port_map : 0,
  52676. - pdata ? pdata->mask_port_map : 0);
  52677. -
  52678. - /* prepare host */
  52679. - if (hpriv->cap & HOST_CAP_NCQ)
  52680. - pi.flags |= ATA_FLAG_NCQ;
  52681. -
  52682. - if (hpriv->cap & HOST_CAP_PMP)
  52683. - pi.flags |= ATA_FLAG_PMP;
  52684. -
  52685. - ahci_set_em_messages(hpriv, &pi);
  52686. -
  52687. - /* CAP.NP sometimes indicate the index of the last enabled
  52688. - * port, at other times, that of the last possible port, so
  52689. - * determining the maximum port number requires looking at
  52690. - * both CAP.NP and port_map.
  52691. - */
  52692. - n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
  52693. -
  52694. - host = ata_host_alloc_pinfo(dev, ppi, n_ports);
  52695. - if (!host) {
  52696. - rc = -ENOMEM;
  52697. - goto pdata_exit;
  52698. + goto disable_resources;
  52699. }
  52700. - host->private_data = hpriv;
  52701. -
  52702. - if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
  52703. - host->flags |= ATA_HOST_PARALLEL_SCAN;
  52704. - else
  52705. - dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
  52706. -
  52707. - if (pi.flags & ATA_FLAG_EM)
  52708. - ahci_reset_em(host);
  52709. -
  52710. - for (i = 0; i < host->n_ports; i++) {
  52711. - struct ata_port *ap = host->ports[i];
  52712. -
  52713. - ata_port_desc(ap, "mmio %pR", mem);
  52714. - ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
  52715. -
  52716. - /* set enclosure management message type */
  52717. - if (ap->flags & ATA_FLAG_EM)
  52718. - ap->em_message_type = hpriv->em_msg_type;
  52719. -
  52720. - /* disabled/not-implemented port */
  52721. - if (!(hpriv->port_map & (1 << i)))
  52722. - ap->ops = &ata_dummy_port_ops;
  52723. - }
  52724. -
  52725. - rc = ahci_reset_controller(host);
  52726. - if (rc)
  52727. - goto pdata_exit;
  52728. -
  52729. - ahci_init_controller(host);
  52730. - ahci_print_info(host, "platform");
  52731. -
  52732. - rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
  52733. - &ahci_platform_sht);
  52734. + rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info, 0, 0, 0);
  52735. if (rc)
  52736. goto pdata_exit;
  52737. @@ -221,115 +63,19 @@
  52738. pdata_exit:
  52739. if (pdata && pdata->exit)
  52740. pdata->exit(dev);
  52741. -disable_unprepare_clk:
  52742. - if (!IS_ERR(hpriv->clk))
  52743. - clk_disable_unprepare(hpriv->clk);
  52744. -free_clk:
  52745. - if (!IS_ERR(hpriv->clk))
  52746. - clk_put(hpriv->clk);
  52747. - return rc;
  52748. -}
  52749. -
  52750. -static void ahci_host_stop(struct ata_host *host)
  52751. -{
  52752. - struct device *dev = host->dev;
  52753. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  52754. - struct ahci_host_priv *hpriv = host->private_data;
  52755. -
  52756. - if (pdata && pdata->exit)
  52757. - pdata->exit(dev);
  52758. -
  52759. - if (!IS_ERR(hpriv->clk)) {
  52760. - clk_disable_unprepare(hpriv->clk);
  52761. - clk_put(hpriv->clk);
  52762. - }
  52763. -}
  52764. -
  52765. -#ifdef CONFIG_PM_SLEEP
  52766. -static int ahci_suspend(struct device *dev)
  52767. -{
  52768. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  52769. - struct ata_host *host = dev_get_drvdata(dev);
  52770. - struct ahci_host_priv *hpriv = host->private_data;
  52771. - void __iomem *mmio = hpriv->mmio;
  52772. - u32 ctl;
  52773. - int rc;
  52774. -
  52775. - if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
  52776. - dev_err(dev, "firmware update required for suspend/resume\n");
  52777. - return -EIO;
  52778. - }
  52779. -
  52780. - /*
  52781. - * AHCI spec rev1.1 section 8.3.3:
  52782. - * Software must disable interrupts prior to requesting a
  52783. - * transition of the HBA to D3 state.
  52784. - */
  52785. - ctl = readl(mmio + HOST_CTL);
  52786. - ctl &= ~HOST_IRQ_EN;
  52787. - writel(ctl, mmio + HOST_CTL);
  52788. - readl(mmio + HOST_CTL); /* flush */
  52789. -
  52790. - rc = ata_host_suspend(host, PMSG_SUSPEND);
  52791. - if (rc)
  52792. - return rc;
  52793. -
  52794. - if (pdata && pdata->suspend)
  52795. - return pdata->suspend(dev);
  52796. -
  52797. - if (!IS_ERR(hpriv->clk))
  52798. - clk_disable_unprepare(hpriv->clk);
  52799. -
  52800. - return 0;
  52801. -}
  52802. -
  52803. -static int ahci_resume(struct device *dev)
  52804. -{
  52805. - struct ahci_platform_data *pdata = dev_get_platdata(dev);
  52806. - struct ata_host *host = dev_get_drvdata(dev);
  52807. - struct ahci_host_priv *hpriv = host->private_data;
  52808. - int rc;
  52809. -
  52810. - if (!IS_ERR(hpriv->clk)) {
  52811. - rc = clk_prepare_enable(hpriv->clk);
  52812. - if (rc) {
  52813. - dev_err(dev, "clock prepare enable failed");
  52814. - return rc;
  52815. - }
  52816. - }
  52817. -
  52818. - if (pdata && pdata->resume) {
  52819. - rc = pdata->resume(dev);
  52820. - if (rc)
  52821. - goto disable_unprepare_clk;
  52822. - }
  52823. -
  52824. - if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
  52825. - rc = ahci_reset_controller(host);
  52826. - if (rc)
  52827. - goto disable_unprepare_clk;
  52828. -
  52829. - ahci_init_controller(host);
  52830. - }
  52831. -
  52832. - ata_host_resume(host);
  52833. -
  52834. - return 0;
  52835. -
  52836. -disable_unprepare_clk:
  52837. - if (!IS_ERR(hpriv->clk))
  52838. - clk_disable_unprepare(hpriv->clk);
  52839. -
  52840. +disable_resources:
  52841. + ahci_platform_disable_resources(hpriv);
  52842. return rc;
  52843. }
  52844. -#endif
  52845. -static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
  52846. +static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
  52847. + ahci_platform_resume);
  52848. static const struct of_device_id ahci_of_match[] = {
  52849. { .compatible = "snps,spear-ahci", },
  52850. { .compatible = "snps,exynos5440-ahci", },
  52851. { .compatible = "ibm,476gtr-ahci", },
  52852. + { .compatible = "snps,dwc-ahci", },
  52853. {},
  52854. };
  52855. MODULE_DEVICE_TABLE(of, ahci_of_match);
  52856. @@ -343,7 +89,6 @@
  52857. .of_match_table = ahci_of_match,
  52858. .pm = &ahci_pm_ops,
  52859. },
  52860. - .id_table = ahci_devtype,
  52861. };
  52862. module_platform_driver(ahci_driver);
  52863. diff -Nur linux-3.14.17/drivers/ata/ata_generic.c linux-imx6-3.14/drivers/ata/ata_generic.c
  52864. --- linux-3.14.17/drivers/ata/ata_generic.c 2014-08-14 03:38:34.000000000 +0200
  52865. +++ linux-imx6-3.14/drivers/ata/ata_generic.c 2014-09-11 18:05:59.414027637 +0200
  52866. @@ -19,7 +19,6 @@
  52867. #include <linux/kernel.h>
  52868. #include <linux/module.h>
  52869. #include <linux/pci.h>
  52870. -#include <linux/init.h>
  52871. #include <linux/blkdev.h>
  52872. #include <linux/delay.h>
  52873. #include <scsi/scsi_host.h>
  52874. diff -Nur linux-3.14.17/drivers/ata/Kconfig linux-imx6-3.14/drivers/ata/Kconfig
  52875. --- linux-3.14.17/drivers/ata/Kconfig 2014-08-14 03:38:34.000000000 +0200
  52876. +++ linux-imx6-3.14/drivers/ata/Kconfig 2014-09-11 18:05:59.410027622 +0200
  52877. @@ -99,7 +99,7 @@
  52878. config AHCI_IMX
  52879. tristate "Freescale i.MX AHCI SATA support"
  52880. - depends on SATA_AHCI_PLATFORM && MFD_SYSCON
  52881. + depends on MFD_SYSCON
  52882. help
  52883. This option enables support for the Freescale i.MX SoC's
  52884. onboard AHCI SATA.
  52885. diff -Nur linux-3.14.17/drivers/ata/libahci.c linux-imx6-3.14/drivers/ata/libahci.c
  52886. --- linux-3.14.17/drivers/ata/libahci.c 2014-08-14 03:38:34.000000000 +0200
  52887. +++ linux-imx6-3.14/drivers/ata/libahci.c 2014-09-11 18:05:59.414027637 +0200
  52888. @@ -35,7 +35,6 @@
  52889. #include <linux/kernel.h>
  52890. #include <linux/gfp.h>
  52891. #include <linux/module.h>
  52892. -#include <linux/init.h>
  52893. #include <linux/blkdev.h>
  52894. #include <linux/delay.h>
  52895. #include <linux/interrupt.h>
  52896. @@ -394,6 +393,9 @@
  52897. *
  52898. * If inconsistent, config values are fixed up by this function.
  52899. *
  52900. + * If it is not set already this function sets hpriv->start_engine to
  52901. + * ahci_start_engine.
  52902. + *
  52903. * LOCKING:
  52904. * None.
  52905. */
  52906. @@ -450,11 +452,23 @@
  52907. cap &= ~HOST_CAP_SNTF;
  52908. }
  52909. + if ((cap2 & HOST_CAP2_SDS) && (hpriv->flags & AHCI_HFLAG_NO_DEVSLP)) {
  52910. + dev_info(dev,
  52911. + "controller can't do DEVSLP, turning off\n");
  52912. + cap2 &= ~HOST_CAP2_SDS;
  52913. + cap2 &= ~HOST_CAP2_SADM;
  52914. + }
  52915. +
  52916. if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) {
  52917. dev_info(dev, "controller can do FBS, turning on CAP_FBS\n");
  52918. cap |= HOST_CAP_FBS;
  52919. }
  52920. + if ((cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_NO_FBS)) {
  52921. + dev_info(dev, "controller can't do FBS, turning off CAP_FBS\n");
  52922. + cap &= ~HOST_CAP_FBS;
  52923. + }
  52924. +
  52925. if (force_port_map && port_map != force_port_map) {
  52926. dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
  52927. port_map, force_port_map);
  52928. @@ -500,6 +514,9 @@
  52929. hpriv->cap = cap;
  52930. hpriv->cap2 = cap2;
  52931. hpriv->port_map = port_map;
  52932. +
  52933. + if (!hpriv->start_engine)
  52934. + hpriv->start_engine = ahci_start_engine;
  52935. }
  52936. EXPORT_SYMBOL_GPL(ahci_save_initial_config);
  52937. @@ -766,7 +783,7 @@
  52938. /* enable DMA */
  52939. if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE))
  52940. - ahci_start_engine(ap);
  52941. + hpriv->start_engine(ap);
  52942. /* turn on LEDs */
  52943. if (ap->flags & ATA_FLAG_EM) {
  52944. @@ -1234,7 +1251,7 @@
  52945. /* restart engine */
  52946. out_restart:
  52947. - ahci_start_engine(ap);
  52948. + hpriv->start_engine(ap);
  52949. return rc;
  52950. }
  52951. EXPORT_SYMBOL_GPL(ahci_kick_engine);
  52952. @@ -1426,6 +1443,7 @@
  52953. const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
  52954. struct ata_port *ap = link->ap;
  52955. struct ahci_port_priv *pp = ap->private_data;
  52956. + struct ahci_host_priv *hpriv = ap->host->private_data;
  52957. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  52958. struct ata_taskfile tf;
  52959. bool online;
  52960. @@ -1443,7 +1461,7 @@
  52961. rc = sata_link_hardreset(link, timing, deadline, &online,
  52962. ahci_check_ready);
  52963. - ahci_start_engine(ap);
  52964. + hpriv->start_engine(ap);
  52965. if (online)
  52966. *class = ahci_dev_classify(ap);
  52967. @@ -2007,10 +2025,12 @@
  52968. void ahci_error_handler(struct ata_port *ap)
  52969. {
  52970. + struct ahci_host_priv *hpriv = ap->host->private_data;
  52971. +
  52972. if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
  52973. /* restart engine */
  52974. ahci_stop_engine(ap);
  52975. - ahci_start_engine(ap);
  52976. + hpriv->start_engine(ap);
  52977. }
  52978. sata_pmp_error_handler(ap);
  52979. @@ -2031,6 +2051,7 @@
  52980. static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
  52981. {
  52982. + struct ahci_host_priv *hpriv = ap->host->private_data;
  52983. void __iomem *port_mmio = ahci_port_base(ap);
  52984. struct ata_device *dev = ap->link.device;
  52985. u32 devslp, dm, dito, mdat, deto;
  52986. @@ -2094,7 +2115,7 @@
  52987. PORT_DEVSLP_ADSE);
  52988. writel(devslp, port_mmio + PORT_DEVSLP);
  52989. - ahci_start_engine(ap);
  52990. + hpriv->start_engine(ap);
  52991. /* enable device sleep feature for the drive */
  52992. err_mask = ata_dev_set_feature(dev,
  52993. @@ -2106,6 +2127,7 @@
  52994. static void ahci_enable_fbs(struct ata_port *ap)
  52995. {
  52996. + struct ahci_host_priv *hpriv = ap->host->private_data;
  52997. struct ahci_port_priv *pp = ap->private_data;
  52998. void __iomem *port_mmio = ahci_port_base(ap);
  52999. u32 fbs;
  53000. @@ -2134,11 +2156,12 @@
  53001. } else
  53002. dev_err(ap->host->dev, "Failed to enable FBS\n");
  53003. - ahci_start_engine(ap);
  53004. + hpriv->start_engine(ap);
  53005. }
  53006. static void ahci_disable_fbs(struct ata_port *ap)
  53007. {
  53008. + struct ahci_host_priv *hpriv = ap->host->private_data;
  53009. struct ahci_port_priv *pp = ap->private_data;
  53010. void __iomem *port_mmio = ahci_port_base(ap);
  53011. u32 fbs;
  53012. @@ -2166,7 +2189,7 @@
  53013. pp->fbs_enabled = false;
  53014. }
  53015. - ahci_start_engine(ap);
  53016. + hpriv->start_engine(ap);
  53017. }
  53018. static void ahci_pmp_attach(struct ata_port *ap)
  53019. diff -Nur linux-3.14.17/drivers/ata/libahci_platform.c linux-imx6-3.14/drivers/ata/libahci_platform.c
  53020. --- linux-3.14.17/drivers/ata/libahci_platform.c 1970-01-01 01:00:00.000000000 +0100
  53021. +++ linux-imx6-3.14/drivers/ata/libahci_platform.c 2014-09-11 18:05:59.414027637 +0200
  53022. @@ -0,0 +1,544 @@
  53023. +/*
  53024. + * AHCI SATA platform library
  53025. + *
  53026. + * Copyright 2004-2005 Red Hat, Inc.
  53027. + * Jeff Garzik <jgarzik@pobox.com>
  53028. + * Copyright 2010 MontaVista Software, LLC.
  53029. + * Anton Vorontsov <avorontsov@ru.mvista.com>
  53030. + *
  53031. + * This program is free software; you can redistribute it and/or modify
  53032. + * it under the terms of the GNU General Public License as published by
  53033. + * the Free Software Foundation; either version 2, or (at your option)
  53034. + * any later version.
  53035. + */
  53036. +
  53037. +#include <linux/clk.h>
  53038. +#include <linux/kernel.h>
  53039. +#include <linux/gfp.h>
  53040. +#include <linux/module.h>
  53041. +#include <linux/pm.h>
  53042. +#include <linux/interrupt.h>
  53043. +#include <linux/device.h>
  53044. +#include <linux/platform_device.h>
  53045. +#include <linux/libata.h>
  53046. +#include <linux/ahci_platform.h>
  53047. +#include <linux/phy/phy.h>
  53048. +#include <linux/pm_runtime.h>
  53049. +#include "ahci.h"
  53050. +
  53051. +static void ahci_host_stop(struct ata_host *host);
  53052. +
  53053. +struct ata_port_operations ahci_platform_ops = {
  53054. + .inherits = &ahci_ops,
  53055. + .host_stop = ahci_host_stop,
  53056. +};
  53057. +EXPORT_SYMBOL_GPL(ahci_platform_ops);
  53058. +
  53059. +static struct scsi_host_template ahci_platform_sht = {
  53060. + AHCI_SHT("ahci_platform"),
  53061. +};
  53062. +
  53063. +/**
  53064. + * ahci_platform_enable_clks - Enable platform clocks
  53065. + * @hpriv: host private area to store config values
  53066. + *
  53067. + * This function enables all the clks found in hpriv->clks, starting at
  53068. + * index 0. If any clk fails to enable it disables all the clks already
  53069. + * enabled in reverse order, and then returns an error.
  53070. + *
  53071. + * RETURNS:
  53072. + * 0 on success otherwise a negative error code
  53073. + */
  53074. +int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
  53075. +{
  53076. + int c, rc;
  53077. +
  53078. + for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
  53079. + rc = clk_prepare_enable(hpriv->clks[c]);
  53080. + if (rc)
  53081. + goto disable_unprepare_clk;
  53082. + }
  53083. + return 0;
  53084. +
  53085. +disable_unprepare_clk:
  53086. + while (--c >= 0)
  53087. + clk_disable_unprepare(hpriv->clks[c]);
  53088. + return rc;
  53089. +}
  53090. +EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
  53091. +
  53092. +/**
  53093. + * ahci_platform_disable_clks - Disable platform clocks
  53094. + * @hpriv: host private area to store config values
  53095. + *
  53096. + * This function disables all the clks found in hpriv->clks, in reverse
  53097. + * order of ahci_platform_enable_clks (starting at the end of the array).
  53098. + */
  53099. +void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
  53100. +{
  53101. + int c;
  53102. +
  53103. + for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
  53104. + if (hpriv->clks[c])
  53105. + clk_disable_unprepare(hpriv->clks[c]);
  53106. +}
  53107. +EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
  53108. +
  53109. +/**
  53110. + * ahci_platform_enable_resources - Enable platform resources
  53111. + * @hpriv: host private area to store config values
  53112. + *
  53113. + * This function enables all ahci_platform managed resources in the
  53114. + * following order:
  53115. + * 1) Regulator
  53116. + * 2) Clocks (through ahci_platform_enable_clks)
  53117. + * 3) Phy
  53118. + *
  53119. + * If resource enabling fails at any point the previous enabled resources
  53120. + * are disabled in reverse order.
  53121. + *
  53122. + * RETURNS:
  53123. + * 0 on success otherwise a negative error code
  53124. + */
  53125. +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
  53126. +{
  53127. + int rc;
  53128. +
  53129. + if (hpriv->target_pwr) {
  53130. + rc = regulator_enable(hpriv->target_pwr);
  53131. + if (rc)
  53132. + return rc;
  53133. + }
  53134. +
  53135. + rc = ahci_platform_enable_clks(hpriv);
  53136. + if (rc)
  53137. + goto disable_regulator;
  53138. +
  53139. + if (hpriv->phy) {
  53140. + rc = phy_init(hpriv->phy);
  53141. + if (rc)
  53142. + goto disable_clks;
  53143. +
  53144. + rc = phy_power_on(hpriv->phy);
  53145. + if (rc) {
  53146. + phy_exit(hpriv->phy);
  53147. + goto disable_clks;
  53148. + }
  53149. + }
  53150. +
  53151. + return 0;
  53152. +
  53153. +disable_clks:
  53154. + ahci_platform_disable_clks(hpriv);
  53155. +
  53156. +disable_regulator:
  53157. + if (hpriv->target_pwr)
  53158. + regulator_disable(hpriv->target_pwr);
  53159. + return rc;
  53160. +}
  53161. +EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
  53162. +
  53163. +/**
  53164. + * ahci_platform_disable_resources - Disable platform resources
  53165. + * @hpriv: host private area to store config values
  53166. + *
  53167. + * This function disables all ahci_platform managed resources in the
  53168. + * following order:
  53169. + * 1) Phy
  53170. + * 2) Clocks (through ahci_platform_disable_clks)
  53171. + * 3) Regulator
  53172. + */
  53173. +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
  53174. +{
  53175. + if (hpriv->phy) {
  53176. + phy_power_off(hpriv->phy);
  53177. + phy_exit(hpriv->phy);
  53178. + }
  53179. +
  53180. + ahci_platform_disable_clks(hpriv);
  53181. +
  53182. + if (hpriv->target_pwr)
  53183. + regulator_disable(hpriv->target_pwr);
  53184. +}
  53185. +EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
  53186. +
  53187. +static void ahci_platform_put_resources(struct device *dev, void *res)
  53188. +{
  53189. + struct ahci_host_priv *hpriv = res;
  53190. + int c;
  53191. +
  53192. + if (hpriv->got_runtime_pm) {
  53193. + pm_runtime_put_sync(dev);
  53194. + pm_runtime_disable(dev);
  53195. + }
  53196. +
  53197. + for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
  53198. + clk_put(hpriv->clks[c]);
  53199. +}
  53200. +
  53201. +/**
  53202. + * ahci_platform_get_resources - Get platform resources
  53203. + * @pdev: platform device to get resources for
  53204. + *
  53205. + * This function allocates an ahci_host_priv struct, and gets the following
  53206. + * resources, storing a reference to them inside the returned struct:
  53207. + *
  53208. + * 1) mmio registers (IORESOURCE_MEM 0, mandatory)
  53209. + * 2) regulator for controlling the targets power (optional)
  53210. + * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
  53211. + * or for non devicetree enabled platforms a single clock
  53212. + * 4) phy (optional)
  53213. + *
  53214. + * RETURNS:
  53215. + * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
  53216. + */
  53217. +struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
  53218. +{
  53219. + struct device *dev = &pdev->dev;
  53220. + struct ahci_host_priv *hpriv;
  53221. + struct clk *clk;
  53222. + int i, rc = -ENOMEM;
  53223. +
  53224. + if (!devres_open_group(dev, NULL, GFP_KERNEL))
  53225. + return ERR_PTR(-ENOMEM);
  53226. +
  53227. + hpriv = devres_alloc(ahci_platform_put_resources, sizeof(*hpriv),
  53228. + GFP_KERNEL);
  53229. + if (!hpriv)
  53230. + goto err_out;
  53231. +
  53232. + devres_add(dev, hpriv);
  53233. +
  53234. + hpriv->mmio = devm_ioremap_resource(dev,
  53235. + platform_get_resource(pdev, IORESOURCE_MEM, 0));
  53236. + if (IS_ERR(hpriv->mmio)) {
  53237. + dev_err(dev, "no mmio space\n");
  53238. + rc = PTR_ERR(hpriv->mmio);
  53239. + goto err_out;
  53240. + }
  53241. +
  53242. + hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
  53243. + if (IS_ERR(hpriv->target_pwr)) {
  53244. + rc = PTR_ERR(hpriv->target_pwr);
  53245. + if (rc == -EPROBE_DEFER)
  53246. + goto err_out;
  53247. + hpriv->target_pwr = NULL;
  53248. + }
  53249. +
  53250. + for (i = 0; i < AHCI_MAX_CLKS; i++) {
  53251. + /*
  53252. + * For now we must use clk_get(dev, NULL) for the first clock,
  53253. + * because some platforms (da850, spear13xx) are not yet
  53254. + * converted to use devicetree for clocks. For new platforms
  53255. + * this is equivalent to of_clk_get(dev->of_node, 0).
  53256. + */
  53257. + if (i == 0)
  53258. + clk = clk_get(dev, NULL);
  53259. + else
  53260. + clk = of_clk_get(dev->of_node, i);
  53261. +
  53262. + if (IS_ERR(clk)) {
  53263. + rc = PTR_ERR(clk);
  53264. + if (rc == -EPROBE_DEFER)
  53265. + goto err_out;
  53266. + break;
  53267. + }
  53268. + hpriv->clks[i] = clk;
  53269. + }
  53270. +
  53271. + hpriv->phy = devm_phy_get(dev, "sata-phy");
  53272. + if (IS_ERR(hpriv->phy)) {
  53273. + rc = PTR_ERR(hpriv->phy);
  53274. + switch (rc) {
  53275. + case -ENODEV:
  53276. + case -ENOSYS:
  53277. + /* continue normally */
  53278. + hpriv->phy = NULL;
  53279. + break;
  53280. +
  53281. + case -EPROBE_DEFER:
  53282. + goto err_out;
  53283. +
  53284. + default:
  53285. + dev_err(dev, "couldn't get sata-phy\n");
  53286. + goto err_out;
  53287. + }
  53288. + }
  53289. +
  53290. + pm_runtime_enable(dev);
  53291. + pm_runtime_get_sync(dev);
  53292. + hpriv->got_runtime_pm = true;
  53293. +
  53294. + devres_remove_group(dev, NULL);
  53295. + return hpriv;
  53296. +
  53297. +err_out:
  53298. + devres_release_group(dev, NULL);
  53299. + return ERR_PTR(rc);
  53300. +}
  53301. +EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
  53302. +
  53303. +/**
  53304. + * ahci_platform_init_host - Bring up an ahci-platform host
  53305. + * @pdev: platform device pointer for the host
  53306. + * @hpriv: ahci-host private data for the host
  53307. + * @pi_template: template for the ata_port_info to use
  53308. + * @host_flags: ahci host flags used in ahci_host_priv
  53309. + * @force_port_map: param passed to ahci_save_initial_config
  53310. + * @mask_port_map: param passed to ahci_save_initial_config
  53311. + *
  53312. + * This function does all the usual steps needed to bring up an
  53313. + * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
  53314. + * must be initialized / enabled before calling this.
  53315. + *
  53316. + * RETURNS:
  53317. + * 0 on success otherwise a negative error code
  53318. + */
  53319. +int ahci_platform_init_host(struct platform_device *pdev,
  53320. + struct ahci_host_priv *hpriv,
  53321. + const struct ata_port_info *pi_template,
  53322. + unsigned long host_flags,
  53323. + unsigned int force_port_map,
  53324. + unsigned int mask_port_map)
  53325. +{
  53326. + struct device *dev = &pdev->dev;
  53327. + struct ata_port_info pi = *pi_template;
  53328. + const struct ata_port_info *ppi[] = { &pi, NULL };
  53329. + struct ata_host *host;
  53330. + int i, irq, n_ports, rc;
  53331. +
  53332. + irq = platform_get_irq(pdev, 0);
  53333. + if (irq <= 0) {
  53334. + dev_err(dev, "no irq\n");
  53335. + return -EINVAL;
  53336. + }
  53337. +
  53338. + /* prepare host */
  53339. + pi.private_data = (void *)host_flags;
  53340. + hpriv->flags |= host_flags;
  53341. +
  53342. + ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
  53343. +
  53344. + if (hpriv->cap & HOST_CAP_NCQ)
  53345. + pi.flags |= ATA_FLAG_NCQ;
  53346. +
  53347. + if (hpriv->cap & HOST_CAP_PMP)
  53348. + pi.flags |= ATA_FLAG_PMP;
  53349. +
  53350. + ahci_set_em_messages(hpriv, &pi);
  53351. +
  53352. + /* CAP.NP sometimes indicate the index of the last enabled
  53353. + * port, at other times, that of the last possible port, so
  53354. + * determining the maximum port number requires looking at
  53355. + * both CAP.NP and port_map.
  53356. + */
  53357. + n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
  53358. +
  53359. + host = ata_host_alloc_pinfo(dev, ppi, n_ports);
  53360. + if (!host)
  53361. + return -ENOMEM;
  53362. +
  53363. + host->private_data = hpriv;
  53364. +
  53365. + if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
  53366. + host->flags |= ATA_HOST_PARALLEL_SCAN;
  53367. + else
  53368. + dev_info(dev, "SSS flag set, parallel bus scan disabled\n");
  53369. +
  53370. + if (pi.flags & ATA_FLAG_EM)
  53371. + ahci_reset_em(host);
  53372. +
  53373. + for (i = 0; i < host->n_ports; i++) {
  53374. + struct ata_port *ap = host->ports[i];
  53375. +
  53376. + ata_port_desc(ap, "mmio %pR",
  53377. + platform_get_resource(pdev, IORESOURCE_MEM, 0));
  53378. + ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
  53379. +
  53380. + /* set enclosure management message type */
  53381. + if (ap->flags & ATA_FLAG_EM)
  53382. + ap->em_message_type = hpriv->em_msg_type;
  53383. +
  53384. + /* disabled/not-implemented port */
  53385. + if (!(hpriv->port_map & (1 << i)))
  53386. + ap->ops = &ata_dummy_port_ops;
  53387. + }
  53388. +
  53389. + rc = ahci_reset_controller(host);
  53390. + if (rc)
  53391. + return rc;
  53392. +
  53393. + ahci_init_controller(host);
  53394. + ahci_print_info(host, "platform");
  53395. +
  53396. + return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
  53397. + &ahci_platform_sht);
  53398. +}
  53399. +EXPORT_SYMBOL_GPL(ahci_platform_init_host);
  53400. +
  53401. +static void ahci_host_stop(struct ata_host *host)
  53402. +{
  53403. + struct device *dev = host->dev;
  53404. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  53405. + struct ahci_host_priv *hpriv = host->private_data;
  53406. +
  53407. + if (pdata && pdata->exit)
  53408. + pdata->exit(dev);
  53409. +
  53410. + ahci_platform_disable_resources(hpriv);
  53411. +}
  53412. +
  53413. +#ifdef CONFIG_PM_SLEEP
  53414. +/**
  53415. + * ahci_platform_suspend_host - Suspend an ahci-platform host
  53416. + * @dev: device pointer for the host
  53417. + *
  53418. + * This function does all the usual steps needed to suspend an
  53419. + * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
  53420. + * must be disabled after calling this.
  53421. + *
  53422. + * RETURNS:
  53423. + * 0 on success otherwise a negative error code
  53424. + */
  53425. +int ahci_platform_suspend_host(struct device *dev)
  53426. +{
  53427. + struct ata_host *host = dev_get_drvdata(dev);
  53428. + struct ahci_host_priv *hpriv = host->private_data;
  53429. + void __iomem *mmio = hpriv->mmio;
  53430. + u32 ctl;
  53431. +
  53432. + if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
  53433. + dev_err(dev, "firmware update required for suspend/resume\n");
  53434. + return -EIO;
  53435. + }
  53436. +
  53437. + /*
  53438. + * AHCI spec rev1.1 section 8.3.3:
  53439. + * Software must disable interrupts prior to requesting a
  53440. + * transition of the HBA to D3 state.
  53441. + */
  53442. + ctl = readl(mmio + HOST_CTL);
  53443. + ctl &= ~HOST_IRQ_EN;
  53444. + writel(ctl, mmio + HOST_CTL);
  53445. + readl(mmio + HOST_CTL); /* flush */
  53446. +
  53447. + return ata_host_suspend(host, PMSG_SUSPEND);
  53448. +}
  53449. +EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
  53450. +
  53451. +/**
  53452. + * ahci_platform_resume_host - Resume an ahci-platform host
  53453. + * @dev: device pointer for the host
  53454. + *
  53455. + * This function does all the usual steps needed to resume an ahci-platform
  53456. + * host, note any necessary resources (ie clks, phy, etc.) must be
  53457. + * initialized / enabled before calling this.
  53458. + *
  53459. + * RETURNS:
  53460. + * 0 on success otherwise a negative error code
  53461. + */
  53462. +int ahci_platform_resume_host(struct device *dev)
  53463. +{
  53464. + struct ata_host *host = dev_get_drvdata(dev);
  53465. + int rc;
  53466. +
  53467. + if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
  53468. + rc = ahci_reset_controller(host);
  53469. + if (rc)
  53470. + return rc;
  53471. +
  53472. + ahci_init_controller(host);
  53473. + }
  53474. +
  53475. + ata_host_resume(host);
  53476. +
  53477. + return 0;
  53478. +}
  53479. +EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
  53480. +
  53481. +/**
  53482. + * ahci_platform_suspend - Suspend an ahci-platform device
  53483. + * @dev: the platform device to suspend
  53484. + *
  53485. + * This function suspends the host associated with the device, followed by
  53486. + * disabling all the resources of the device.
  53487. + *
  53488. + * RETURNS:
  53489. + * 0 on success otherwise a negative error code
  53490. + */
  53491. +int ahci_platform_suspend(struct device *dev)
  53492. +{
  53493. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  53494. + struct ata_host *host = dev_get_drvdata(dev);
  53495. + struct ahci_host_priv *hpriv = host->private_data;
  53496. + int rc;
  53497. +
  53498. + rc = ahci_platform_suspend_host(dev);
  53499. + if (rc)
  53500. + return rc;
  53501. +
  53502. + if (pdata && pdata->suspend) {
  53503. + rc = pdata->suspend(dev);
  53504. + if (rc)
  53505. + goto resume_host;
  53506. + }
  53507. +
  53508. + ahci_platform_disable_resources(hpriv);
  53509. +
  53510. + return 0;
  53511. +
  53512. +resume_host:
  53513. + ahci_platform_resume_host(dev);
  53514. + return rc;
  53515. +}
  53516. +EXPORT_SYMBOL_GPL(ahci_platform_suspend);
  53517. +
  53518. +/**
  53519. + * ahci_platform_resume - Resume an ahci-platform device
  53520. + * @dev: the platform device to resume
  53521. + *
  53522. + * This function enables all the resources of the device followed by
  53523. + * resuming the host associated with the device.
  53524. + *
  53525. + * RETURNS:
  53526. + * 0 on success otherwise a negative error code
  53527. + */
  53528. +int ahci_platform_resume(struct device *dev)
  53529. +{
  53530. + struct ahci_platform_data *pdata = dev_get_platdata(dev);
  53531. + struct ata_host *host = dev_get_drvdata(dev);
  53532. + struct ahci_host_priv *hpriv = host->private_data;
  53533. + int rc;
  53534. +
  53535. + rc = ahci_platform_enable_resources(hpriv);
  53536. + if (rc)
  53537. + return rc;
  53538. +
  53539. + if (pdata && pdata->resume) {
  53540. + rc = pdata->resume(dev);
  53541. + if (rc)
  53542. + goto disable_resources;
  53543. + }
  53544. +
  53545. + rc = ahci_platform_resume_host(dev);
  53546. + if (rc)
  53547. + goto disable_resources;
  53548. +
  53549. + /* We resumed so update PM runtime state */
  53550. + pm_runtime_disable(dev);
  53551. + pm_runtime_set_active(dev);
  53552. + pm_runtime_enable(dev);
  53553. +
  53554. + return 0;
  53555. +
  53556. +disable_resources:
  53557. + ahci_platform_disable_resources(hpriv);
  53558. +
  53559. + return rc;
  53560. +}
  53561. +EXPORT_SYMBOL_GPL(ahci_platform_resume);
  53562. +#endif
  53563. +
  53564. +MODULE_DESCRIPTION("AHCI SATA platform library");
  53565. +MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
  53566. +MODULE_LICENSE("GPL");
  53567. diff -Nur linux-3.14.17/drivers/ata/libata-core.c linux-imx6-3.14/drivers/ata/libata-core.c
  53568. --- linux-3.14.17/drivers/ata/libata-core.c 2014-08-14 03:38:34.000000000 +0200
  53569. +++ linux-imx6-3.14/drivers/ata/libata-core.c 2014-09-11 18:05:59.418027652 +0200
  53570. @@ -1524,7 +1524,7 @@
  53571. * @dev: Device to which the command is sent
  53572. * @tf: Taskfile registers for the command and the result
  53573. * @cdb: CDB for packet command
  53574. - * @dma_dir: Data tranfer direction of the command
  53575. + * @dma_dir: Data transfer direction of the command
  53576. * @sgl: sg list for the data buffer of the command
  53577. * @n_elem: Number of sg entries
  53578. * @timeout: Timeout in msecs (0 for default)
  53579. @@ -1712,7 +1712,7 @@
  53580. * @dev: Device to which the command is sent
  53581. * @tf: Taskfile registers for the command and the result
  53582. * @cdb: CDB for packet command
  53583. - * @dma_dir: Data tranfer direction of the command
  53584. + * @dma_dir: Data transfer direction of the command
  53585. * @buf: Data buffer of the command
  53586. * @buflen: Length of data buffer
  53587. * @timeout: Timeout in msecs (0 for default)
  53588. @@ -4787,10 +4787,6 @@
  53589. * ata_qc_new - Request an available ATA command, for queueing
  53590. * @ap: target port
  53591. *
  53592. - * Some ATA host controllers may implement a queue depth which is less
  53593. - * than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond
  53594. - * the hardware limitation.
  53595. - *
  53596. * LOCKING:
  53597. * None.
  53598. */
  53599. @@ -4798,15 +4794,14 @@
  53600. static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
  53601. {
  53602. struct ata_queued_cmd *qc = NULL;
  53603. - unsigned int max_queue = ap->host->n_tags;
  53604. unsigned int i, tag;
  53605. /* no command while frozen */
  53606. if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
  53607. return NULL;
  53608. - for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
  53609. - tag = tag < max_queue ? tag : 0;
  53610. + for (i = 0; i < ATA_MAX_QUEUE; i++) {
  53611. + tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
  53612. /* the last tag is reserved for internal command. */
  53613. if (tag == ATA_TAG_INTERNAL)
  53614. @@ -6108,7 +6103,6 @@
  53615. {
  53616. spin_lock_init(&host->lock);
  53617. mutex_init(&host->eh_mutex);
  53618. - host->n_tags = ATA_MAX_QUEUE - 1;
  53619. host->dev = dev;
  53620. host->ops = ops;
  53621. }
  53622. @@ -6190,8 +6184,6 @@
  53623. {
  53624. int i, rc;
  53625. - host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1);
  53626. -
  53627. /* host must have been started */
  53628. if (!(host->flags & ATA_HOST_STARTED)) {
  53629. dev_err(host->dev, "BUG: trying to register unstarted host\n");
  53630. diff -Nur linux-3.14.17/drivers/ata/Makefile linux-imx6-3.14/drivers/ata/Makefile
  53631. --- linux-3.14.17/drivers/ata/Makefile 2014-08-14 03:38:34.000000000 +0200
  53632. +++ linux-imx6-3.14/drivers/ata/Makefile 2014-09-11 18:05:59.410027622 +0200
  53633. @@ -4,13 +4,13 @@
  53634. # non-SFF interface
  53635. obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o
  53636. obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
  53637. -obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
  53638. +obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o
  53639. obj-$(CONFIG_SATA_FSL) += sata_fsl.o
  53640. obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
  53641. obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
  53642. obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
  53643. obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
  53644. -obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
  53645. +obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
  53646. # SFF w/ custom DMA
  53647. obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
  53648. diff -Nur linux-3.14.17/drivers/ata/pata_acpi.c linux-imx6-3.14/drivers/ata/pata_acpi.c
  53649. --- linux-3.14.17/drivers/ata/pata_acpi.c 2014-08-14 03:38:34.000000000 +0200
  53650. +++ linux-imx6-3.14/drivers/ata/pata_acpi.c 2014-09-11 18:05:59.422027668 +0200
  53651. @@ -7,7 +7,6 @@
  53652. #include <linux/kernel.h>
  53653. #include <linux/module.h>
  53654. #include <linux/pci.h>
  53655. -#include <linux/init.h>
  53656. #include <linux/blkdev.h>
  53657. #include <linux/delay.h>
  53658. #include <linux/device.h>
  53659. diff -Nur linux-3.14.17/drivers/ata/pata_amd.c linux-imx6-3.14/drivers/ata/pata_amd.c
  53660. --- linux-3.14.17/drivers/ata/pata_amd.c 2014-08-14 03:38:34.000000000 +0200
  53661. +++ linux-imx6-3.14/drivers/ata/pata_amd.c 2014-09-11 18:05:59.422027668 +0200
  53662. @@ -17,7 +17,6 @@
  53663. #include <linux/kernel.h>
  53664. #include <linux/module.h>
  53665. #include <linux/pci.h>
  53666. -#include <linux/init.h>
  53667. #include <linux/blkdev.h>
  53668. #include <linux/delay.h>
  53669. #include <scsi/scsi_host.h>
  53670. diff -Nur linux-3.14.17/drivers/ata/pata_artop.c linux-imx6-3.14/drivers/ata/pata_artop.c
  53671. --- linux-3.14.17/drivers/ata/pata_artop.c 2014-08-14 03:38:34.000000000 +0200
  53672. +++ linux-imx6-3.14/drivers/ata/pata_artop.c 2014-09-11 18:05:59.422027668 +0200
  53673. @@ -19,7 +19,6 @@
  53674. #include <linux/kernel.h>
  53675. #include <linux/module.h>
  53676. #include <linux/pci.h>
  53677. -#include <linux/init.h>
  53678. #include <linux/blkdev.h>
  53679. #include <linux/delay.h>
  53680. #include <linux/device.h>
  53681. diff -Nur linux-3.14.17/drivers/ata/pata_at91.c linux-imx6-3.14/drivers/ata/pata_at91.c
  53682. --- linux-3.14.17/drivers/ata/pata_at91.c 2014-08-14 03:38:34.000000000 +0200
  53683. +++ linux-imx6-3.14/drivers/ata/pata_at91.c 2014-09-11 18:05:59.422027668 +0200
  53684. @@ -18,7 +18,6 @@
  53685. #include <linux/kernel.h>
  53686. #include <linux/module.h>
  53687. -#include <linux/init.h>
  53688. #include <linux/blkdev.h>
  53689. #include <linux/gfp.h>
  53690. #include <scsi/scsi_host.h>
  53691. diff -Nur linux-3.14.17/drivers/ata/pata_atiixp.c linux-imx6-3.14/drivers/ata/pata_atiixp.c
  53692. --- linux-3.14.17/drivers/ata/pata_atiixp.c 2014-08-14 03:38:34.000000000 +0200
  53693. +++ linux-imx6-3.14/drivers/ata/pata_atiixp.c 2014-09-11 18:05:59.422027668 +0200
  53694. @@ -15,7 +15,6 @@
  53695. #include <linux/kernel.h>
  53696. #include <linux/module.h>
  53697. #include <linux/pci.h>
  53698. -#include <linux/init.h>
  53699. #include <linux/blkdev.h>
  53700. #include <linux/delay.h>
  53701. #include <scsi/scsi_host.h>
  53702. diff -Nur linux-3.14.17/drivers/ata/pata_atp867x.c linux-imx6-3.14/drivers/ata/pata_atp867x.c
  53703. --- linux-3.14.17/drivers/ata/pata_atp867x.c 2014-08-14 03:38:34.000000000 +0200
  53704. +++ linux-imx6-3.14/drivers/ata/pata_atp867x.c 2014-09-11 18:05:59.422027668 +0200
  53705. @@ -29,7 +29,6 @@
  53706. #include <linux/kernel.h>
  53707. #include <linux/module.h>
  53708. #include <linux/pci.h>
  53709. -#include <linux/init.h>
  53710. #include <linux/blkdev.h>
  53711. #include <linux/delay.h>
  53712. #include <linux/device.h>
  53713. diff -Nur linux-3.14.17/drivers/ata/pata_cmd640.c linux-imx6-3.14/drivers/ata/pata_cmd640.c
  53714. --- linux-3.14.17/drivers/ata/pata_cmd640.c 2014-08-14 03:38:34.000000000 +0200
  53715. +++ linux-imx6-3.14/drivers/ata/pata_cmd640.c 2014-09-11 18:05:59.422027668 +0200
  53716. @@ -15,7 +15,6 @@
  53717. #include <linux/kernel.h>
  53718. #include <linux/module.h>
  53719. #include <linux/pci.h>
  53720. -#include <linux/init.h>
  53721. #include <linux/blkdev.h>
  53722. #include <linux/delay.h>
  53723. #include <linux/gfp.h>
  53724. diff -Nur linux-3.14.17/drivers/ata/pata_cmd64x.c linux-imx6-3.14/drivers/ata/pata_cmd64x.c
  53725. --- linux-3.14.17/drivers/ata/pata_cmd64x.c 2014-08-14 03:38:34.000000000 +0200
  53726. +++ linux-imx6-3.14/drivers/ata/pata_cmd64x.c 2014-09-11 18:05:59.422027668 +0200
  53727. @@ -26,7 +26,6 @@
  53728. #include <linux/kernel.h>
  53729. #include <linux/module.h>
  53730. #include <linux/pci.h>
  53731. -#include <linux/init.h>
  53732. #include <linux/blkdev.h>
  53733. #include <linux/delay.h>
  53734. #include <scsi/scsi_host.h>
  53735. diff -Nur linux-3.14.17/drivers/ata/pata_cs5520.c linux-imx6-3.14/drivers/ata/pata_cs5520.c
  53736. --- linux-3.14.17/drivers/ata/pata_cs5520.c 2014-08-14 03:38:34.000000000 +0200
  53737. +++ linux-imx6-3.14/drivers/ata/pata_cs5520.c 2014-09-11 18:05:59.422027668 +0200
  53738. @@ -34,7 +34,6 @@
  53739. #include <linux/kernel.h>
  53740. #include <linux/module.h>
  53741. #include <linux/pci.h>
  53742. -#include <linux/init.h>
  53743. #include <linux/blkdev.h>
  53744. #include <linux/delay.h>
  53745. #include <scsi/scsi_host.h>
  53746. diff -Nur linux-3.14.17/drivers/ata/pata_cs5530.c linux-imx6-3.14/drivers/ata/pata_cs5530.c
  53747. --- linux-3.14.17/drivers/ata/pata_cs5530.c 2014-08-14 03:38:34.000000000 +0200
  53748. +++ linux-imx6-3.14/drivers/ata/pata_cs5530.c 2014-09-11 18:05:59.422027668 +0200
  53749. @@ -26,7 +26,6 @@
  53750. #include <linux/kernel.h>
  53751. #include <linux/module.h>
  53752. #include <linux/pci.h>
  53753. -#include <linux/init.h>
  53754. #include <linux/blkdev.h>
  53755. #include <linux/delay.h>
  53756. #include <scsi/scsi_host.h>
  53757. diff -Nur linux-3.14.17/drivers/ata/pata_cs5535.c linux-imx6-3.14/drivers/ata/pata_cs5535.c
  53758. --- linux-3.14.17/drivers/ata/pata_cs5535.c 2014-08-14 03:38:34.000000000 +0200
  53759. +++ linux-imx6-3.14/drivers/ata/pata_cs5535.c 2014-09-11 18:05:59.422027668 +0200
  53760. @@ -31,7 +31,6 @@
  53761. #include <linux/kernel.h>
  53762. #include <linux/module.h>
  53763. #include <linux/pci.h>
  53764. -#include <linux/init.h>
  53765. #include <linux/blkdev.h>
  53766. #include <linux/delay.h>
  53767. #include <scsi/scsi_host.h>
  53768. diff -Nur linux-3.14.17/drivers/ata/pata_cs5536.c linux-imx6-3.14/drivers/ata/pata_cs5536.c
  53769. --- linux-3.14.17/drivers/ata/pata_cs5536.c 2014-08-14 03:38:34.000000000 +0200
  53770. +++ linux-imx6-3.14/drivers/ata/pata_cs5536.c 2014-09-11 18:05:59.422027668 +0200
  53771. @@ -33,7 +33,6 @@
  53772. #include <linux/kernel.h>
  53773. #include <linux/module.h>
  53774. #include <linux/pci.h>
  53775. -#include <linux/init.h>
  53776. #include <linux/blkdev.h>
  53777. #include <linux/delay.h>
  53778. #include <linux/libata.h>
  53779. diff -Nur linux-3.14.17/drivers/ata/pata_cypress.c linux-imx6-3.14/drivers/ata/pata_cypress.c
  53780. --- linux-3.14.17/drivers/ata/pata_cypress.c 2014-08-14 03:38:34.000000000 +0200
  53781. +++ linux-imx6-3.14/drivers/ata/pata_cypress.c 2014-09-11 18:05:59.422027668 +0200
  53782. @@ -11,7 +11,6 @@
  53783. #include <linux/kernel.h>
  53784. #include <linux/module.h>
  53785. #include <linux/pci.h>
  53786. -#include <linux/init.h>
  53787. #include <linux/blkdev.h>
  53788. #include <linux/delay.h>
  53789. #include <scsi/scsi_host.h>
  53790. diff -Nur linux-3.14.17/drivers/ata/pata_efar.c linux-imx6-3.14/drivers/ata/pata_efar.c
  53791. --- linux-3.14.17/drivers/ata/pata_efar.c 2014-08-14 03:38:34.000000000 +0200
  53792. +++ linux-imx6-3.14/drivers/ata/pata_efar.c 2014-09-11 18:05:59.426027685 +0200
  53793. @@ -14,7 +14,6 @@
  53794. #include <linux/kernel.h>
  53795. #include <linux/module.h>
  53796. #include <linux/pci.h>
  53797. -#include <linux/init.h>
  53798. #include <linux/blkdev.h>
  53799. #include <linux/delay.h>
  53800. #include <linux/device.h>
  53801. diff -Nur linux-3.14.17/drivers/ata/pata_ep93xx.c linux-imx6-3.14/drivers/ata/pata_ep93xx.c
  53802. --- linux-3.14.17/drivers/ata/pata_ep93xx.c 2014-08-14 03:38:34.000000000 +0200
  53803. +++ linux-imx6-3.14/drivers/ata/pata_ep93xx.c 2014-09-11 18:05:59.426027685 +0200
  53804. @@ -34,7 +34,6 @@
  53805. #include <linux/err.h>
  53806. #include <linux/kernel.h>
  53807. #include <linux/module.h>
  53808. -#include <linux/init.h>
  53809. #include <linux/blkdev.h>
  53810. #include <scsi/scsi_host.h>
  53811. #include <linux/ata.h>
  53812. diff -Nur linux-3.14.17/drivers/ata/pata_hpt366.c linux-imx6-3.14/drivers/ata/pata_hpt366.c
  53813. --- linux-3.14.17/drivers/ata/pata_hpt366.c 2014-08-14 03:38:34.000000000 +0200
  53814. +++ linux-imx6-3.14/drivers/ata/pata_hpt366.c 2014-09-11 18:05:59.426027685 +0200
  53815. @@ -19,7 +19,6 @@
  53816. #include <linux/kernel.h>
  53817. #include <linux/module.h>
  53818. #include <linux/pci.h>
  53819. -#include <linux/init.h>
  53820. #include <linux/blkdev.h>
  53821. #include <linux/delay.h>
  53822. #include <scsi/scsi_host.h>
  53823. diff -Nur linux-3.14.17/drivers/ata/pata_hpt37x.c linux-imx6-3.14/drivers/ata/pata_hpt37x.c
  53824. --- linux-3.14.17/drivers/ata/pata_hpt37x.c 2014-08-14 03:38:34.000000000 +0200
  53825. +++ linux-imx6-3.14/drivers/ata/pata_hpt37x.c 2014-09-11 18:05:59.426027685 +0200
  53826. @@ -19,7 +19,6 @@
  53827. #include <linux/kernel.h>
  53828. #include <linux/module.h>
  53829. #include <linux/pci.h>
  53830. -#include <linux/init.h>
  53831. #include <linux/blkdev.h>
  53832. #include <linux/delay.h>
  53833. #include <scsi/scsi_host.h>
  53834. diff -Nur linux-3.14.17/drivers/ata/pata_hpt3x2n.c linux-imx6-3.14/drivers/ata/pata_hpt3x2n.c
  53835. --- linux-3.14.17/drivers/ata/pata_hpt3x2n.c 2014-08-14 03:38:34.000000000 +0200
  53836. +++ linux-imx6-3.14/drivers/ata/pata_hpt3x2n.c 2014-09-11 18:05:59.426027685 +0200
  53837. @@ -20,7 +20,6 @@
  53838. #include <linux/kernel.h>
  53839. #include <linux/module.h>
  53840. #include <linux/pci.h>
  53841. -#include <linux/init.h>
  53842. #include <linux/blkdev.h>
  53843. #include <linux/delay.h>
  53844. #include <scsi/scsi_host.h>
  53845. diff -Nur linux-3.14.17/drivers/ata/pata_hpt3x3.c linux-imx6-3.14/drivers/ata/pata_hpt3x3.c
  53846. --- linux-3.14.17/drivers/ata/pata_hpt3x3.c 2014-08-14 03:38:34.000000000 +0200
  53847. +++ linux-imx6-3.14/drivers/ata/pata_hpt3x3.c 2014-09-11 18:05:59.426027685 +0200
  53848. @@ -16,7 +16,6 @@
  53849. #include <linux/kernel.h>
  53850. #include <linux/module.h>
  53851. #include <linux/pci.h>
  53852. -#include <linux/init.h>
  53853. #include <linux/blkdev.h>
  53854. #include <linux/delay.h>
  53855. #include <scsi/scsi_host.h>
  53856. diff -Nur linux-3.14.17/drivers/ata/pata_imx.c linux-imx6-3.14/drivers/ata/pata_imx.c
  53857. --- linux-3.14.17/drivers/ata/pata_imx.c 2014-08-14 03:38:34.000000000 +0200
  53858. +++ linux-imx6-3.14/drivers/ata/pata_imx.c 2014-09-11 18:05:59.426027685 +0200
  53859. @@ -15,7 +15,6 @@
  53860. */
  53861. #include <linux/kernel.h>
  53862. #include <linux/module.h>
  53863. -#include <linux/init.h>
  53864. #include <linux/blkdev.h>
  53865. #include <scsi/scsi_host.h>
  53866. #include <linux/ata.h>
  53867. diff -Nur linux-3.14.17/drivers/ata/pata_it8213.c linux-imx6-3.14/drivers/ata/pata_it8213.c
  53868. --- linux-3.14.17/drivers/ata/pata_it8213.c 2014-08-14 03:38:34.000000000 +0200
  53869. +++ linux-imx6-3.14/drivers/ata/pata_it8213.c 2014-09-11 18:05:59.426027685 +0200
  53870. @@ -10,7 +10,6 @@
  53871. #include <linux/kernel.h>
  53872. #include <linux/module.h>
  53873. #include <linux/pci.h>
  53874. -#include <linux/init.h>
  53875. #include <linux/blkdev.h>
  53876. #include <linux/delay.h>
  53877. #include <linux/device.h>
  53878. diff -Nur linux-3.14.17/drivers/ata/pata_it821x.c linux-imx6-3.14/drivers/ata/pata_it821x.c
  53879. --- linux-3.14.17/drivers/ata/pata_it821x.c 2014-08-14 03:38:34.000000000 +0200
  53880. +++ linux-imx6-3.14/drivers/ata/pata_it821x.c 2014-09-11 18:05:59.426027685 +0200
  53881. @@ -72,7 +72,6 @@
  53882. #include <linux/kernel.h>
  53883. #include <linux/module.h>
  53884. #include <linux/pci.h>
  53885. -#include <linux/init.h>
  53886. #include <linux/blkdev.h>
  53887. #include <linux/delay.h>
  53888. #include <linux/slab.h>
  53889. diff -Nur linux-3.14.17/drivers/ata/pata_jmicron.c linux-imx6-3.14/drivers/ata/pata_jmicron.c
  53890. --- linux-3.14.17/drivers/ata/pata_jmicron.c 2014-08-14 03:38:34.000000000 +0200
  53891. +++ linux-imx6-3.14/drivers/ata/pata_jmicron.c 2014-09-11 18:05:59.426027685 +0200
  53892. @@ -10,7 +10,6 @@
  53893. #include <linux/kernel.h>
  53894. #include <linux/module.h>
  53895. #include <linux/pci.h>
  53896. -#include <linux/init.h>
  53897. #include <linux/blkdev.h>
  53898. #include <linux/delay.h>
  53899. #include <linux/device.h>
  53900. diff -Nur linux-3.14.17/drivers/ata/pata_marvell.c linux-imx6-3.14/drivers/ata/pata_marvell.c
  53901. --- linux-3.14.17/drivers/ata/pata_marvell.c 2014-08-14 03:38:34.000000000 +0200
  53902. +++ linux-imx6-3.14/drivers/ata/pata_marvell.c 2014-09-11 18:05:59.430027701 +0200
  53903. @@ -11,7 +11,6 @@
  53904. #include <linux/kernel.h>
  53905. #include <linux/module.h>
  53906. #include <linux/pci.h>
  53907. -#include <linux/init.h>
  53908. #include <linux/blkdev.h>
  53909. #include <linux/delay.h>
  53910. #include <linux/device.h>
  53911. diff -Nur linux-3.14.17/drivers/ata/pata_mpiix.c linux-imx6-3.14/drivers/ata/pata_mpiix.c
  53912. --- linux-3.14.17/drivers/ata/pata_mpiix.c 2014-08-14 03:38:34.000000000 +0200
  53913. +++ linux-imx6-3.14/drivers/ata/pata_mpiix.c 2014-09-11 18:05:59.430027701 +0200
  53914. @@ -28,7 +28,6 @@
  53915. #include <linux/kernel.h>
  53916. #include <linux/module.h>
  53917. #include <linux/pci.h>
  53918. -#include <linux/init.h>
  53919. #include <linux/blkdev.h>
  53920. #include <linux/delay.h>
  53921. #include <scsi/scsi_host.h>
  53922. diff -Nur linux-3.14.17/drivers/ata/pata_netcell.c linux-imx6-3.14/drivers/ata/pata_netcell.c
  53923. --- linux-3.14.17/drivers/ata/pata_netcell.c 2014-08-14 03:38:34.000000000 +0200
  53924. +++ linux-imx6-3.14/drivers/ata/pata_netcell.c 2014-09-11 18:05:59.430027701 +0200
  53925. @@ -7,7 +7,6 @@
  53926. #include <linux/kernel.h>
  53927. #include <linux/module.h>
  53928. #include <linux/pci.h>
  53929. -#include <linux/init.h>
  53930. #include <linux/blkdev.h>
  53931. #include <linux/delay.h>
  53932. #include <linux/device.h>
  53933. diff -Nur linux-3.14.17/drivers/ata/pata_ninja32.c linux-imx6-3.14/drivers/ata/pata_ninja32.c
  53934. --- linux-3.14.17/drivers/ata/pata_ninja32.c 2014-08-14 03:38:34.000000000 +0200
  53935. +++ linux-imx6-3.14/drivers/ata/pata_ninja32.c 2014-09-11 18:05:59.430027701 +0200
  53936. @@ -37,7 +37,6 @@
  53937. #include <linux/kernel.h>
  53938. #include <linux/module.h>
  53939. #include <linux/pci.h>
  53940. -#include <linux/init.h>
  53941. #include <linux/blkdev.h>
  53942. #include <linux/delay.h>
  53943. #include <scsi/scsi_host.h>
  53944. diff -Nur linux-3.14.17/drivers/ata/pata_ns87410.c linux-imx6-3.14/drivers/ata/pata_ns87410.c
  53945. --- linux-3.14.17/drivers/ata/pata_ns87410.c 2014-08-14 03:38:34.000000000 +0200
  53946. +++ linux-imx6-3.14/drivers/ata/pata_ns87410.c 2014-09-11 18:05:59.430027701 +0200
  53947. @@ -20,7 +20,6 @@
  53948. #include <linux/kernel.h>
  53949. #include <linux/module.h>
  53950. #include <linux/pci.h>
  53951. -#include <linux/init.h>
  53952. #include <linux/blkdev.h>
  53953. #include <linux/delay.h>
  53954. #include <scsi/scsi_host.h>
  53955. diff -Nur linux-3.14.17/drivers/ata/pata_ns87415.c linux-imx6-3.14/drivers/ata/pata_ns87415.c
  53956. --- linux-3.14.17/drivers/ata/pata_ns87415.c 2014-08-14 03:38:34.000000000 +0200
  53957. +++ linux-imx6-3.14/drivers/ata/pata_ns87415.c 2014-09-11 18:05:59.430027701 +0200
  53958. @@ -25,7 +25,6 @@
  53959. #include <linux/kernel.h>
  53960. #include <linux/module.h>
  53961. #include <linux/pci.h>
  53962. -#include <linux/init.h>
  53963. #include <linux/blkdev.h>
  53964. #include <linux/delay.h>
  53965. #include <linux/device.h>
  53966. diff -Nur linux-3.14.17/drivers/ata/pata_oldpiix.c linux-imx6-3.14/drivers/ata/pata_oldpiix.c
  53967. --- linux-3.14.17/drivers/ata/pata_oldpiix.c 2014-08-14 03:38:34.000000000 +0200
  53968. +++ linux-imx6-3.14/drivers/ata/pata_oldpiix.c 2014-09-11 18:05:59.430027701 +0200
  53969. @@ -16,7 +16,6 @@
  53970. #include <linux/kernel.h>
  53971. #include <linux/module.h>
  53972. #include <linux/pci.h>
  53973. -#include <linux/init.h>
  53974. #include <linux/blkdev.h>
  53975. #include <linux/delay.h>
  53976. #include <linux/device.h>
  53977. diff -Nur linux-3.14.17/drivers/ata/pata_opti.c linux-imx6-3.14/drivers/ata/pata_opti.c
  53978. --- linux-3.14.17/drivers/ata/pata_opti.c 2014-08-14 03:38:34.000000000 +0200
  53979. +++ linux-imx6-3.14/drivers/ata/pata_opti.c 2014-09-11 18:05:59.430027701 +0200
  53980. @@ -26,7 +26,6 @@
  53981. #include <linux/kernel.h>
  53982. #include <linux/module.h>
  53983. #include <linux/pci.h>
  53984. -#include <linux/init.h>
  53985. #include <linux/blkdev.h>
  53986. #include <linux/delay.h>
  53987. #include <scsi/scsi_host.h>
  53988. diff -Nur linux-3.14.17/drivers/ata/pata_optidma.c linux-imx6-3.14/drivers/ata/pata_optidma.c
  53989. --- linux-3.14.17/drivers/ata/pata_optidma.c 2014-08-14 03:38:34.000000000 +0200
  53990. +++ linux-imx6-3.14/drivers/ata/pata_optidma.c 2014-09-11 18:05:59.430027701 +0200
  53991. @@ -25,7 +25,6 @@
  53992. #include <linux/kernel.h>
  53993. #include <linux/module.h>
  53994. #include <linux/pci.h>
  53995. -#include <linux/init.h>
  53996. #include <linux/blkdev.h>
  53997. #include <linux/delay.h>
  53998. #include <scsi/scsi_host.h>
  53999. diff -Nur linux-3.14.17/drivers/ata/pata_pcmcia.c linux-imx6-3.14/drivers/ata/pata_pcmcia.c
  54000. --- linux-3.14.17/drivers/ata/pata_pcmcia.c 2014-08-14 03:38:34.000000000 +0200
  54001. +++ linux-imx6-3.14/drivers/ata/pata_pcmcia.c 2014-09-11 18:05:59.430027701 +0200
  54002. @@ -26,7 +26,6 @@
  54003. #include <linux/kernel.h>
  54004. #include <linux/module.h>
  54005. -#include <linux/init.h>
  54006. #include <linux/blkdev.h>
  54007. #include <linux/delay.h>
  54008. #include <linux/slab.h>
  54009. diff -Nur linux-3.14.17/drivers/ata/pata_pdc2027x.c linux-imx6-3.14/drivers/ata/pata_pdc2027x.c
  54010. --- linux-3.14.17/drivers/ata/pata_pdc2027x.c 2014-08-14 03:38:34.000000000 +0200
  54011. +++ linux-imx6-3.14/drivers/ata/pata_pdc2027x.c 2014-09-11 18:05:59.430027701 +0200
  54012. @@ -25,7 +25,6 @@
  54013. #include <linux/kernel.h>
  54014. #include <linux/module.h>
  54015. #include <linux/pci.h>
  54016. -#include <linux/init.h>
  54017. #include <linux/blkdev.h>
  54018. #include <linux/delay.h>
  54019. #include <linux/device.h>
  54020. diff -Nur linux-3.14.17/drivers/ata/pata_pdc202xx_old.c linux-imx6-3.14/drivers/ata/pata_pdc202xx_old.c
  54021. --- linux-3.14.17/drivers/ata/pata_pdc202xx_old.c 2014-08-14 03:38:34.000000000 +0200
  54022. +++ linux-imx6-3.14/drivers/ata/pata_pdc202xx_old.c 2014-09-11 18:05:59.430027701 +0200
  54023. @@ -15,7 +15,6 @@
  54024. #include <linux/kernel.h>
  54025. #include <linux/module.h>
  54026. #include <linux/pci.h>
  54027. -#include <linux/init.h>
  54028. #include <linux/blkdev.h>
  54029. #include <linux/delay.h>
  54030. #include <scsi/scsi_host.h>
  54031. diff -Nur linux-3.14.17/drivers/ata/pata_piccolo.c linux-imx6-3.14/drivers/ata/pata_piccolo.c
  54032. --- linux-3.14.17/drivers/ata/pata_piccolo.c 2014-08-14 03:38:34.000000000 +0200
  54033. +++ linux-imx6-3.14/drivers/ata/pata_piccolo.c 2014-09-11 18:05:59.430027701 +0200
  54034. @@ -18,7 +18,6 @@
  54035. #include <linux/kernel.h>
  54036. #include <linux/module.h>
  54037. #include <linux/pci.h>
  54038. -#include <linux/init.h>
  54039. #include <linux/blkdev.h>
  54040. #include <linux/delay.h>
  54041. #include <scsi/scsi_host.h>
  54042. diff -Nur linux-3.14.17/drivers/ata/pata_platform.c linux-imx6-3.14/drivers/ata/pata_platform.c
  54043. --- linux-3.14.17/drivers/ata/pata_platform.c 2014-08-14 03:38:34.000000000 +0200
  54044. +++ linux-imx6-3.14/drivers/ata/pata_platform.c 2014-09-11 18:05:59.430027701 +0200
  54045. @@ -13,7 +13,6 @@
  54046. */
  54047. #include <linux/kernel.h>
  54048. #include <linux/module.h>
  54049. -#include <linux/init.h>
  54050. #include <linux/blkdev.h>
  54051. #include <scsi/scsi_host.h>
  54052. #include <linux/ata.h>
  54053. diff -Nur linux-3.14.17/drivers/ata/pata_pxa.c linux-imx6-3.14/drivers/ata/pata_pxa.c
  54054. --- linux-3.14.17/drivers/ata/pata_pxa.c 2014-08-14 03:38:34.000000000 +0200
  54055. +++ linux-imx6-3.14/drivers/ata/pata_pxa.c 2014-09-11 18:05:59.430027701 +0200
  54056. @@ -20,7 +20,6 @@
  54057. #include <linux/kernel.h>
  54058. #include <linux/module.h>
  54059. -#include <linux/init.h>
  54060. #include <linux/blkdev.h>
  54061. #include <linux/ata.h>
  54062. #include <linux/libata.h>
  54063. diff -Nur linux-3.14.17/drivers/ata/pata_radisys.c linux-imx6-3.14/drivers/ata/pata_radisys.c
  54064. --- linux-3.14.17/drivers/ata/pata_radisys.c 2014-08-14 03:38:34.000000000 +0200
  54065. +++ linux-imx6-3.14/drivers/ata/pata_radisys.c 2014-09-11 18:05:59.430027701 +0200
  54066. @@ -15,7 +15,6 @@
  54067. #include <linux/kernel.h>
  54068. #include <linux/module.h>
  54069. #include <linux/pci.h>
  54070. -#include <linux/init.h>
  54071. #include <linux/blkdev.h>
  54072. #include <linux/delay.h>
  54073. #include <linux/device.h>
  54074. diff -Nur linux-3.14.17/drivers/ata/pata_rdc.c linux-imx6-3.14/drivers/ata/pata_rdc.c
  54075. --- linux-3.14.17/drivers/ata/pata_rdc.c 2014-08-14 03:38:34.000000000 +0200
  54076. +++ linux-imx6-3.14/drivers/ata/pata_rdc.c 2014-09-11 18:05:59.430027701 +0200
  54077. @@ -24,7 +24,6 @@
  54078. #include <linux/kernel.h>
  54079. #include <linux/module.h>
  54080. #include <linux/pci.h>
  54081. -#include <linux/init.h>
  54082. #include <linux/blkdev.h>
  54083. #include <linux/delay.h>
  54084. #include <linux/device.h>
  54085. diff -Nur linux-3.14.17/drivers/ata/pata_rz1000.c linux-imx6-3.14/drivers/ata/pata_rz1000.c
  54086. --- linux-3.14.17/drivers/ata/pata_rz1000.c 2014-08-14 03:38:34.000000000 +0200
  54087. +++ linux-imx6-3.14/drivers/ata/pata_rz1000.c 2014-09-11 18:05:59.430027701 +0200
  54088. @@ -14,7 +14,6 @@
  54089. #include <linux/kernel.h>
  54090. #include <linux/module.h>
  54091. #include <linux/pci.h>
  54092. -#include <linux/init.h>
  54093. #include <linux/blkdev.h>
  54094. #include <linux/delay.h>
  54095. #include <scsi/scsi_host.h>
  54096. diff -Nur linux-3.14.17/drivers/ata/pata_sc1200.c linux-imx6-3.14/drivers/ata/pata_sc1200.c
  54097. --- linux-3.14.17/drivers/ata/pata_sc1200.c 2014-08-14 03:38:34.000000000 +0200
  54098. +++ linux-imx6-3.14/drivers/ata/pata_sc1200.c 2014-09-11 18:05:59.434027716 +0200
  54099. @@ -32,7 +32,6 @@
  54100. #include <linux/kernel.h>
  54101. #include <linux/module.h>
  54102. #include <linux/pci.h>
  54103. -#include <linux/init.h>
  54104. #include <linux/blkdev.h>
  54105. #include <linux/delay.h>
  54106. #include <scsi/scsi_host.h>
  54107. diff -Nur linux-3.14.17/drivers/ata/pata_scc.c linux-imx6-3.14/drivers/ata/pata_scc.c
  54108. --- linux-3.14.17/drivers/ata/pata_scc.c 2014-08-14 03:38:34.000000000 +0200
  54109. +++ linux-imx6-3.14/drivers/ata/pata_scc.c 2014-09-11 18:05:59.434027716 +0200
  54110. @@ -35,7 +35,6 @@
  54111. #include <linux/kernel.h>
  54112. #include <linux/module.h>
  54113. #include <linux/pci.h>
  54114. -#include <linux/init.h>
  54115. #include <linux/blkdev.h>
  54116. #include <linux/delay.h>
  54117. #include <linux/device.h>
  54118. diff -Nur linux-3.14.17/drivers/ata/pata_sch.c linux-imx6-3.14/drivers/ata/pata_sch.c
  54119. --- linux-3.14.17/drivers/ata/pata_sch.c 2014-08-14 03:38:34.000000000 +0200
  54120. +++ linux-imx6-3.14/drivers/ata/pata_sch.c 2014-09-11 18:05:59.434027716 +0200
  54121. @@ -27,7 +27,6 @@
  54122. #include <linux/kernel.h>
  54123. #include <linux/module.h>
  54124. #include <linux/pci.h>
  54125. -#include <linux/init.h>
  54126. #include <linux/blkdev.h>
  54127. #include <linux/delay.h>
  54128. #include <linux/device.h>
  54129. diff -Nur linux-3.14.17/drivers/ata/pata_serverworks.c linux-imx6-3.14/drivers/ata/pata_serverworks.c
  54130. --- linux-3.14.17/drivers/ata/pata_serverworks.c 2014-08-14 03:38:34.000000000 +0200
  54131. +++ linux-imx6-3.14/drivers/ata/pata_serverworks.c 2014-09-11 18:05:59.434027716 +0200
  54132. @@ -34,7 +34,6 @@
  54133. #include <linux/kernel.h>
  54134. #include <linux/module.h>
  54135. #include <linux/pci.h>
  54136. -#include <linux/init.h>
  54137. #include <linux/blkdev.h>
  54138. #include <linux/delay.h>
  54139. #include <scsi/scsi_host.h>
  54140. diff -Nur linux-3.14.17/drivers/ata/pata_sil680.c linux-imx6-3.14/drivers/ata/pata_sil680.c
  54141. --- linux-3.14.17/drivers/ata/pata_sil680.c 2014-08-14 03:38:34.000000000 +0200
  54142. +++ linux-imx6-3.14/drivers/ata/pata_sil680.c 2014-09-11 18:05:59.434027716 +0200
  54143. @@ -25,7 +25,6 @@
  54144. #include <linux/kernel.h>
  54145. #include <linux/module.h>
  54146. #include <linux/pci.h>
  54147. -#include <linux/init.h>
  54148. #include <linux/blkdev.h>
  54149. #include <linux/delay.h>
  54150. #include <scsi/scsi_host.h>
  54151. diff -Nur linux-3.14.17/drivers/ata/pata_sis.c linux-imx6-3.14/drivers/ata/pata_sis.c
  54152. --- linux-3.14.17/drivers/ata/pata_sis.c 2014-08-14 03:38:34.000000000 +0200
  54153. +++ linux-imx6-3.14/drivers/ata/pata_sis.c 2014-09-11 18:05:59.434027716 +0200
  54154. @@ -26,7 +26,6 @@
  54155. #include <linux/kernel.h>
  54156. #include <linux/module.h>
  54157. #include <linux/pci.h>
  54158. -#include <linux/init.h>
  54159. #include <linux/blkdev.h>
  54160. #include <linux/delay.h>
  54161. #include <linux/device.h>
  54162. diff -Nur linux-3.14.17/drivers/ata/pata_sl82c105.c linux-imx6-3.14/drivers/ata/pata_sl82c105.c
  54163. --- linux-3.14.17/drivers/ata/pata_sl82c105.c 2014-08-14 03:38:34.000000000 +0200
  54164. +++ linux-imx6-3.14/drivers/ata/pata_sl82c105.c 2014-09-11 18:05:59.434027716 +0200
  54165. @@ -19,7 +19,6 @@
  54166. #include <linux/kernel.h>
  54167. #include <linux/module.h>
  54168. #include <linux/pci.h>
  54169. -#include <linux/init.h>
  54170. #include <linux/blkdev.h>
  54171. #include <linux/delay.h>
  54172. #include <scsi/scsi_host.h>
  54173. diff -Nur linux-3.14.17/drivers/ata/pata_triflex.c linux-imx6-3.14/drivers/ata/pata_triflex.c
  54174. --- linux-3.14.17/drivers/ata/pata_triflex.c 2014-08-14 03:38:34.000000000 +0200
  54175. +++ linux-imx6-3.14/drivers/ata/pata_triflex.c 2014-09-11 18:05:59.434027716 +0200
  54176. @@ -36,7 +36,6 @@
  54177. #include <linux/kernel.h>
  54178. #include <linux/module.h>
  54179. #include <linux/pci.h>
  54180. -#include <linux/init.h>
  54181. #include <linux/blkdev.h>
  54182. #include <linux/delay.h>
  54183. #include <scsi/scsi_host.h>
  54184. diff -Nur linux-3.14.17/drivers/ata/pata_via.c linux-imx6-3.14/drivers/ata/pata_via.c
  54185. --- linux-3.14.17/drivers/ata/pata_via.c 2014-08-14 03:38:34.000000000 +0200
  54186. +++ linux-imx6-3.14/drivers/ata/pata_via.c 2014-09-11 18:05:59.434027716 +0200
  54187. @@ -55,7 +55,6 @@
  54188. #include <linux/kernel.h>
  54189. #include <linux/module.h>
  54190. #include <linux/pci.h>
  54191. -#include <linux/init.h>
  54192. #include <linux/blkdev.h>
  54193. #include <linux/delay.h>
  54194. #include <linux/gfp.h>
  54195. diff -Nur linux-3.14.17/drivers/ata/pdc_adma.c linux-imx6-3.14/drivers/ata/pdc_adma.c
  54196. --- linux-3.14.17/drivers/ata/pdc_adma.c 2014-08-14 03:38:34.000000000 +0200
  54197. +++ linux-imx6-3.14/drivers/ata/pdc_adma.c 2014-09-11 18:05:59.434027716 +0200
  54198. @@ -36,7 +36,6 @@
  54199. #include <linux/module.h>
  54200. #include <linux/gfp.h>
  54201. #include <linux/pci.h>
  54202. -#include <linux/init.h>
  54203. #include <linux/blkdev.h>
  54204. #include <linux/delay.h>
  54205. #include <linux/interrupt.h>
  54206. diff -Nur linux-3.14.17/drivers/ata/sata_dwc_460ex.c linux-imx6-3.14/drivers/ata/sata_dwc_460ex.c
  54207. --- linux-3.14.17/drivers/ata/sata_dwc_460ex.c 2014-08-14 03:38:34.000000000 +0200
  54208. +++ linux-imx6-3.14/drivers/ata/sata_dwc_460ex.c 2014-09-11 18:05:59.434027716 +0200
  54209. @@ -29,7 +29,6 @@
  54210. #include <linux/kernel.h>
  54211. #include <linux/module.h>
  54212. -#include <linux/init.h>
  54213. #include <linux/device.h>
  54214. #include <linux/of_address.h>
  54215. #include <linux/of_irq.h>
  54216. diff -Nur linux-3.14.17/drivers/ata/sata_highbank.c linux-imx6-3.14/drivers/ata/sata_highbank.c
  54217. --- linux-3.14.17/drivers/ata/sata_highbank.c 2014-08-14 03:38:34.000000000 +0200
  54218. +++ linux-imx6-3.14/drivers/ata/sata_highbank.c 2014-09-11 18:05:59.434027716 +0200
  54219. @@ -19,7 +19,6 @@
  54220. #include <linux/kernel.h>
  54221. #include <linux/gfp.h>
  54222. #include <linux/module.h>
  54223. -#include <linux/init.h>
  54224. #include <linux/types.h>
  54225. #include <linux/err.h>
  54226. #include <linux/io.h>
  54227. @@ -403,6 +402,7 @@
  54228. static const unsigned long timing[] = { 5, 100, 500};
  54229. struct ata_port *ap = link->ap;
  54230. struct ahci_port_priv *pp = ap->private_data;
  54231. + struct ahci_host_priv *hpriv = ap->host->private_data;
  54232. u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  54233. struct ata_taskfile tf;
  54234. bool online;
  54235. @@ -431,7 +431,7 @@
  54236. break;
  54237. } while (!online && retry--);
  54238. - ahci_start_engine(ap);
  54239. + hpriv->start_engine(ap);
  54240. if (online)
  54241. *class = ahci_dev_classify(ap);
  54242. diff -Nur linux-3.14.17/drivers/ata/sata_nv.c linux-imx6-3.14/drivers/ata/sata_nv.c
  54243. --- linux-3.14.17/drivers/ata/sata_nv.c 2014-08-14 03:38:34.000000000 +0200
  54244. +++ linux-imx6-3.14/drivers/ata/sata_nv.c 2014-09-11 18:05:59.438027733 +0200
  54245. @@ -40,7 +40,6 @@
  54246. #include <linux/module.h>
  54247. #include <linux/gfp.h>
  54248. #include <linux/pci.h>
  54249. -#include <linux/init.h>
  54250. #include <linux/blkdev.h>
  54251. #include <linux/delay.h>
  54252. #include <linux/interrupt.h>
  54253. diff -Nur linux-3.14.17/drivers/ata/sata_promise.c linux-imx6-3.14/drivers/ata/sata_promise.c
  54254. --- linux-3.14.17/drivers/ata/sata_promise.c 2014-08-14 03:38:34.000000000 +0200
  54255. +++ linux-imx6-3.14/drivers/ata/sata_promise.c 2014-09-11 18:05:59.438027733 +0200
  54256. @@ -35,7 +35,6 @@
  54257. #include <linux/module.h>
  54258. #include <linux/gfp.h>
  54259. #include <linux/pci.h>
  54260. -#include <linux/init.h>
  54261. #include <linux/blkdev.h>
  54262. #include <linux/delay.h>
  54263. #include <linux/interrupt.h>
  54264. diff -Nur linux-3.14.17/drivers/ata/sata_qstor.c linux-imx6-3.14/drivers/ata/sata_qstor.c
  54265. --- linux-3.14.17/drivers/ata/sata_qstor.c 2014-08-14 03:38:34.000000000 +0200
  54266. +++ linux-imx6-3.14/drivers/ata/sata_qstor.c 2014-09-11 18:05:59.438027733 +0200
  54267. @@ -31,7 +31,6 @@
  54268. #include <linux/module.h>
  54269. #include <linux/gfp.h>
  54270. #include <linux/pci.h>
  54271. -#include <linux/init.h>
  54272. #include <linux/blkdev.h>
  54273. #include <linux/delay.h>
  54274. #include <linux/interrupt.h>
  54275. diff -Nur linux-3.14.17/drivers/ata/sata_sil.c linux-imx6-3.14/drivers/ata/sata_sil.c
  54276. --- linux-3.14.17/drivers/ata/sata_sil.c 2014-08-14 03:38:34.000000000 +0200
  54277. +++ linux-imx6-3.14/drivers/ata/sata_sil.c 2014-09-11 18:05:59.438027733 +0200
  54278. @@ -37,7 +37,6 @@
  54279. #include <linux/kernel.h>
  54280. #include <linux/module.h>
  54281. #include <linux/pci.h>
  54282. -#include <linux/init.h>
  54283. #include <linux/blkdev.h>
  54284. #include <linux/delay.h>
  54285. #include <linux/interrupt.h>
  54286. diff -Nur linux-3.14.17/drivers/ata/sata_sis.c linux-imx6-3.14/drivers/ata/sata_sis.c
  54287. --- linux-3.14.17/drivers/ata/sata_sis.c 2014-08-14 03:38:34.000000000 +0200
  54288. +++ linux-imx6-3.14/drivers/ata/sata_sis.c 2014-09-11 18:05:59.438027733 +0200
  54289. @@ -33,7 +33,6 @@
  54290. #include <linux/kernel.h>
  54291. #include <linux/module.h>
  54292. #include <linux/pci.h>
  54293. -#include <linux/init.h>
  54294. #include <linux/blkdev.h>
  54295. #include <linux/delay.h>
  54296. #include <linux/interrupt.h>
  54297. diff -Nur linux-3.14.17/drivers/ata/sata_svw.c linux-imx6-3.14/drivers/ata/sata_svw.c
  54298. --- linux-3.14.17/drivers/ata/sata_svw.c 2014-08-14 03:38:34.000000000 +0200
  54299. +++ linux-imx6-3.14/drivers/ata/sata_svw.c 2014-09-11 18:05:59.438027733 +0200
  54300. @@ -39,7 +39,6 @@
  54301. #include <linux/kernel.h>
  54302. #include <linux/module.h>
  54303. #include <linux/pci.h>
  54304. -#include <linux/init.h>
  54305. #include <linux/blkdev.h>
  54306. #include <linux/delay.h>
  54307. #include <linux/interrupt.h>
  54308. diff -Nur linux-3.14.17/drivers/ata/sata_sx4.c linux-imx6-3.14/drivers/ata/sata_sx4.c
  54309. --- linux-3.14.17/drivers/ata/sata_sx4.c 2014-08-14 03:38:34.000000000 +0200
  54310. +++ linux-imx6-3.14/drivers/ata/sata_sx4.c 2014-09-11 18:05:59.438027733 +0200
  54311. @@ -82,7 +82,6 @@
  54312. #include <linux/module.h>
  54313. #include <linux/pci.h>
  54314. #include <linux/slab.h>
  54315. -#include <linux/init.h>
  54316. #include <linux/blkdev.h>
  54317. #include <linux/delay.h>
  54318. #include <linux/interrupt.h>
  54319. diff -Nur linux-3.14.17/drivers/ata/sata_uli.c linux-imx6-3.14/drivers/ata/sata_uli.c
  54320. --- linux-3.14.17/drivers/ata/sata_uli.c 2014-08-14 03:38:34.000000000 +0200
  54321. +++ linux-imx6-3.14/drivers/ata/sata_uli.c 2014-09-11 18:05:59.438027733 +0200
  54322. @@ -28,7 +28,6 @@
  54323. #include <linux/module.h>
  54324. #include <linux/gfp.h>
  54325. #include <linux/pci.h>
  54326. -#include <linux/init.h>
  54327. #include <linux/blkdev.h>
  54328. #include <linux/delay.h>
  54329. #include <linux/interrupt.h>
  54330. diff -Nur linux-3.14.17/drivers/ata/sata_via.c linux-imx6-3.14/drivers/ata/sata_via.c
  54331. --- linux-3.14.17/drivers/ata/sata_via.c 2014-08-14 03:38:34.000000000 +0200
  54332. +++ linux-imx6-3.14/drivers/ata/sata_via.c 2014-09-11 18:05:59.438027733 +0200
  54333. @@ -36,7 +36,6 @@
  54334. #include <linux/kernel.h>
  54335. #include <linux/module.h>
  54336. #include <linux/pci.h>
  54337. -#include <linux/init.h>
  54338. #include <linux/blkdev.h>
  54339. #include <linux/delay.h>
  54340. #include <linux/device.h>
  54341. diff -Nur linux-3.14.17/drivers/ata/sata_vsc.c linux-imx6-3.14/drivers/ata/sata_vsc.c
  54342. --- linux-3.14.17/drivers/ata/sata_vsc.c 2014-08-14 03:38:34.000000000 +0200
  54343. +++ linux-imx6-3.14/drivers/ata/sata_vsc.c 2014-09-11 18:05:59.438027733 +0200
  54344. @@ -37,7 +37,6 @@
  54345. #include <linux/kernel.h>
  54346. #include <linux/module.h>
  54347. #include <linux/pci.h>
  54348. -#include <linux/init.h>
  54349. #include <linux/blkdev.h>
  54350. #include <linux/delay.h>
  54351. #include <linux/interrupt.h>
  54352. diff -Nur linux-3.14.17/drivers/base/bus.c linux-imx6-3.14/drivers/base/bus.c
  54353. --- linux-3.14.17/drivers/base/bus.c 2014-08-14 03:38:34.000000000 +0200
  54354. +++ linux-imx6-3.14/drivers/base/bus.c 2014-09-11 18:05:59.498027972 +0200
  54355. @@ -1218,7 +1218,7 @@
  54356. * with the name of the subsystem. The root device can carry subsystem-
  54357. * wide attributes. All registered devices are below this single root
  54358. * device and are named after the subsystem with a simple enumeration
  54359. - * number appended. The registered devices are not explicitely named;
  54360. + * number appended. The registered devices are not explicitly named;
  54361. * only 'id' in the device needs to be set.
  54362. *
  54363. * Do not use this interface for anything new, it exists for compatibility
  54364. diff -Nur linux-3.14.17/drivers/base/cpu.c linux-imx6-3.14/drivers/base/cpu.c
  54365. --- linux-3.14.17/drivers/base/cpu.c 2014-08-14 03:38:34.000000000 +0200
  54366. +++ linux-imx6-3.14/drivers/base/cpu.c 2014-09-11 18:05:59.522028069 +0200
  54367. @@ -15,6 +15,7 @@
  54368. #include <linux/percpu.h>
  54369. #include <linux/acpi.h>
  54370. #include <linux/of.h>
  54371. +#include <linux/cpufeature.h>
  54372. #include "base.h"
  54373. @@ -286,6 +287,45 @@
  54374. */
  54375. }
  54376. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  54377. +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
  54378. +static ssize_t print_cpu_modalias(struct device *dev,
  54379. + struct device_attribute *attr,
  54380. + char *buf)
  54381. +{
  54382. + ssize_t n;
  54383. + u32 i;
  54384. +
  54385. + n = sprintf(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
  54386. + CPU_FEATURE_TYPEVAL);
  54387. +
  54388. + for (i = 0; i < MAX_CPU_FEATURES; i++)
  54389. + if (cpu_have_feature(i)) {
  54390. + if (PAGE_SIZE < n + sizeof(",XXXX\n")) {
  54391. + WARN(1, "CPU features overflow page\n");
  54392. + break;
  54393. + }
  54394. + n += sprintf(&buf[n], ",%04X", i);
  54395. + }
  54396. + buf[n++] = '\n';
  54397. + return n;
  54398. +}
  54399. +#else
  54400. +#define print_cpu_modalias arch_print_cpu_modalias
  54401. +#endif
  54402. +
  54403. +static int cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
  54404. +{
  54405. + char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
  54406. + if (buf) {
  54407. + print_cpu_modalias(NULL, NULL, buf);
  54408. + add_uevent_var(env, "MODALIAS=%s", buf);
  54409. + kfree(buf);
  54410. + }
  54411. + return 0;
  54412. +}
  54413. +#endif
  54414. +
  54415. /*
  54416. * register_cpu - Setup a sysfs device for a CPU.
  54417. * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
  54418. @@ -306,8 +346,8 @@
  54419. cpu->dev.offline_disabled = !cpu->hotpluggable;
  54420. cpu->dev.offline = !cpu_online(num);
  54421. cpu->dev.of_node = of_get_cpu_node(num, NULL);
  54422. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  54423. - cpu->dev.bus->uevent = arch_cpu_uevent;
  54424. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  54425. + cpu->dev.bus->uevent = cpu_uevent;
  54426. #endif
  54427. cpu->dev.groups = common_cpu_attr_groups;
  54428. if (cpu->hotpluggable)
  54429. @@ -330,8 +370,8 @@
  54430. }
  54431. EXPORT_SYMBOL_GPL(get_cpu_device);
  54432. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  54433. -static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
  54434. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  54435. +static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
  54436. #endif
  54437. static struct attribute *cpu_root_attrs[] = {
  54438. @@ -344,7 +384,7 @@
  54439. &cpu_attrs[2].attr.attr,
  54440. &dev_attr_kernel_max.attr,
  54441. &dev_attr_offline.attr,
  54442. -#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
  54443. +#ifdef CONFIG_HAVE_CPU_AUTOPROBE
  54444. &dev_attr_modalias.attr,
  54445. #endif
  54446. NULL
  54447. diff -Nur linux-3.14.17/drivers/base/dma-buf.c linux-imx6-3.14/drivers/base/dma-buf.c
  54448. --- linux-3.14.17/drivers/base/dma-buf.c 2014-08-14 03:38:34.000000000 +0200
  54449. +++ linux-imx6-3.14/drivers/base/dma-buf.c 2014-09-11 18:05:59.522028069 +0200
  54450. @@ -251,9 +251,8 @@
  54451. * @dmabuf: [in] buffer to attach device to.
  54452. * @dev: [in] device to be attached.
  54453. *
  54454. - * Returns struct dma_buf_attachment * for this attachment; may return negative
  54455. - * error codes.
  54456. - *
  54457. + * Returns struct dma_buf_attachment * for this attachment; returns ERR_PTR on
  54458. + * error.
  54459. */
  54460. struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
  54461. struct device *dev)
  54462. @@ -319,9 +318,8 @@
  54463. * @attach: [in] attachment whose scatterlist is to be returned
  54464. * @direction: [in] direction of DMA transfer
  54465. *
  54466. - * Returns sg_table containing the scatterlist to be returned; may return NULL
  54467. - * or ERR_PTR.
  54468. - *
  54469. + * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
  54470. + * on error.
  54471. */
  54472. struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
  54473. enum dma_data_direction direction)
  54474. @@ -334,6 +332,8 @@
  54475. return ERR_PTR(-EINVAL);
  54476. sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
  54477. + if (!sg_table)
  54478. + sg_table = ERR_PTR(-ENOMEM);
  54479. return sg_table;
  54480. }
  54481. @@ -544,6 +544,8 @@
  54482. * These calls are optional in drivers. The intended use for them
  54483. * is for mapping objects linear in kernel space for high use objects.
  54484. * Please attempt to use kmap/kunmap before thinking about these interfaces.
  54485. + *
  54486. + * Returns NULL on error.
  54487. */
  54488. void *dma_buf_vmap(struct dma_buf *dmabuf)
  54489. {
  54490. @@ -566,7 +568,9 @@
  54491. BUG_ON(dmabuf->vmap_ptr);
  54492. ptr = dmabuf->ops->vmap(dmabuf);
  54493. - if (IS_ERR_OR_NULL(ptr))
  54494. + if (WARN_ON_ONCE(IS_ERR(ptr)))
  54495. + ptr = NULL;
  54496. + if (!ptr)
  54497. goto out_unlock;
  54498. dmabuf->vmap_ptr = ptr;
  54499. diff -Nur linux-3.14.17/drivers/base/dma-contiguous.c linux-imx6-3.14/drivers/base/dma-contiguous.c
  54500. --- linux-3.14.17/drivers/base/dma-contiguous.c 2014-08-14 03:38:34.000000000 +0200
  54501. +++ linux-imx6-3.14/drivers/base/dma-contiguous.c 2014-09-11 18:05:59.522028069 +0200
  54502. @@ -24,22 +24,9 @@
  54503. #include <linux/memblock.h>
  54504. #include <linux/err.h>
  54505. -#include <linux/mm.h>
  54506. -#include <linux/mutex.h>
  54507. -#include <linux/page-isolation.h>
  54508. #include <linux/sizes.h>
  54509. -#include <linux/slab.h>
  54510. -#include <linux/swap.h>
  54511. -#include <linux/mm_types.h>
  54512. #include <linux/dma-contiguous.h>
  54513. -
  54514. -struct cma {
  54515. - unsigned long base_pfn;
  54516. - unsigned long count;
  54517. - unsigned long *bitmap;
  54518. -};
  54519. -
  54520. -struct cma *dma_contiguous_default_area;
  54521. +#include <linux/cma.h>
  54522. #ifdef CONFIG_CMA_SIZE_MBYTES
  54523. #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
  54524. @@ -47,6 +34,8 @@
  54525. #define CMA_SIZE_MBYTES 0
  54526. #endif
  54527. +struct cma *dma_contiguous_default_area;
  54528. +
  54529. /*
  54530. * Default global CMA area size can be defined in kernel's .config.
  54531. * This is useful mainly for distro maintainers to create a kernel
  54532. @@ -59,11 +48,22 @@
  54533. */
  54534. static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M;
  54535. static phys_addr_t size_cmdline = -1;
  54536. +static phys_addr_t base_cmdline;
  54537. +static phys_addr_t limit_cmdline;
  54538. static int __init early_cma(char *p)
  54539. {
  54540. pr_debug("%s(%s)\n", __func__, p);
  54541. size_cmdline = memparse(p, &p);
  54542. + if (*p != '@')
  54543. + return 0;
  54544. + base_cmdline = memparse(p + 1, &p);
  54545. + if (*p != '-') {
  54546. + limit_cmdline = base_cmdline + size_cmdline;
  54547. + return 0;
  54548. + }
  54549. + limit_cmdline = memparse(p + 1, &p);
  54550. +
  54551. return 0;
  54552. }
  54553. early_param("cma", early_cma);
  54554. @@ -107,11 +107,18 @@
  54555. void __init dma_contiguous_reserve(phys_addr_t limit)
  54556. {
  54557. phys_addr_t selected_size = 0;
  54558. + phys_addr_t selected_base = 0;
  54559. + phys_addr_t selected_limit = limit;
  54560. + bool fixed = false;
  54561. pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
  54562. if (size_cmdline != -1) {
  54563. selected_size = size_cmdline;
  54564. + selected_base = base_cmdline;
  54565. + selected_limit = min_not_zero(limit_cmdline, limit);
  54566. + if (base_cmdline + size_cmdline == limit_cmdline)
  54567. + fixed = true;
  54568. } else {
  54569. #ifdef CONFIG_CMA_SIZE_SEL_MBYTES
  54570. selected_size = size_bytes;
  54571. @@ -128,68 +135,12 @@
  54572. pr_debug("%s: reserving %ld MiB for global area\n", __func__,
  54573. (unsigned long)selected_size / SZ_1M);
  54574. - dma_contiguous_reserve_area(selected_size, 0, limit,
  54575. - &dma_contiguous_default_area);
  54576. - }
  54577. -};
  54578. -
  54579. -static DEFINE_MUTEX(cma_mutex);
  54580. -
  54581. -static int __init cma_activate_area(struct cma *cma)
  54582. -{
  54583. - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long);
  54584. - unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
  54585. - unsigned i = cma->count >> pageblock_order;
  54586. - struct zone *zone;
  54587. -
  54588. - cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
  54589. -
  54590. - if (!cma->bitmap)
  54591. - return -ENOMEM;
  54592. -
  54593. - WARN_ON_ONCE(!pfn_valid(pfn));
  54594. - zone = page_zone(pfn_to_page(pfn));
  54595. -
  54596. - do {
  54597. - unsigned j;
  54598. - base_pfn = pfn;
  54599. - for (j = pageblock_nr_pages; j; --j, pfn++) {
  54600. - WARN_ON_ONCE(!pfn_valid(pfn));
  54601. - /*
  54602. - * alloc_contig_range requires the pfn range
  54603. - * specified to be in the same zone. Make this
  54604. - * simple by forcing the entire CMA resv range
  54605. - * to be in the same zone.
  54606. - */
  54607. - if (page_zone(pfn_to_page(pfn)) != zone)
  54608. - goto err;
  54609. - }
  54610. - init_cma_reserved_pageblock(pfn_to_page(base_pfn));
  54611. - } while (--i);
  54612. -
  54613. - return 0;
  54614. -
  54615. -err:
  54616. - kfree(cma->bitmap);
  54617. - return -EINVAL;
  54618. -}
  54619. -
  54620. -static struct cma cma_areas[MAX_CMA_AREAS];
  54621. -static unsigned cma_area_count;
  54622. -
  54623. -static int __init cma_init_reserved_areas(void)
  54624. -{
  54625. - int i;
  54626. -
  54627. - for (i = 0; i < cma_area_count; i++) {
  54628. - int ret = cma_activate_area(&cma_areas[i]);
  54629. - if (ret)
  54630. - return ret;
  54631. + dma_contiguous_reserve_area(selected_size, selected_base,
  54632. + selected_limit,
  54633. + &dma_contiguous_default_area,
  54634. + fixed);
  54635. }
  54636. -
  54637. - return 0;
  54638. }
  54639. -core_initcall(cma_init_reserved_areas);
  54640. /**
  54641. * dma_contiguous_reserve_area() - reserve custom contiguous area
  54642. @@ -197,78 +148,32 @@
  54643. * @base: Base address of the reserved area optional, use 0 for any
  54644. * @limit: End address of the reserved memory (optional, 0 for any).
  54645. * @res_cma: Pointer to store the created cma region.
  54646. + * @fixed: hint about where to place the reserved area
  54647. *
  54648. * This function reserves memory from early allocator. It should be
  54649. * called by arch specific code once the early allocator (memblock or bootmem)
  54650. * has been activated and all other subsystems have already allocated/reserved
  54651. * memory. This function allows to create custom reserved areas for specific
  54652. * devices.
  54653. + *
  54654. + * If @fixed is true, reserve contiguous area at exactly @base. If false,
  54655. + * reserve in range from @base to @limit.
  54656. */
  54657. int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  54658. - phys_addr_t limit, struct cma **res_cma)
  54659. + phys_addr_t limit, struct cma **res_cma,
  54660. + bool fixed)
  54661. {
  54662. - struct cma *cma = &cma_areas[cma_area_count];
  54663. - phys_addr_t alignment;
  54664. - int ret = 0;
  54665. -
  54666. - pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
  54667. - (unsigned long)size, (unsigned long)base,
  54668. - (unsigned long)limit);
  54669. -
  54670. - /* Sanity checks */
  54671. - if (cma_area_count == ARRAY_SIZE(cma_areas)) {
  54672. - pr_err("Not enough slots for CMA reserved regions!\n");
  54673. - return -ENOSPC;
  54674. - }
  54675. -
  54676. - if (!size)
  54677. - return -EINVAL;
  54678. -
  54679. - /* Sanitise input arguments */
  54680. - alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
  54681. - base = ALIGN(base, alignment);
  54682. - size = ALIGN(size, alignment);
  54683. - limit &= ~(alignment - 1);
  54684. -
  54685. - /* Reserve memory */
  54686. - if (base) {
  54687. - if (memblock_is_region_reserved(base, size) ||
  54688. - memblock_reserve(base, size) < 0) {
  54689. - ret = -EBUSY;
  54690. - goto err;
  54691. - }
  54692. - } else {
  54693. - /*
  54694. - * Use __memblock_alloc_base() since
  54695. - * memblock_alloc_base() panic()s.
  54696. - */
  54697. - phys_addr_t addr = __memblock_alloc_base(size, alignment, limit);
  54698. - if (!addr) {
  54699. - ret = -ENOMEM;
  54700. - goto err;
  54701. - } else {
  54702. - base = addr;
  54703. - }
  54704. - }
  54705. -
  54706. - /*
  54707. - * Each reserved area must be initialised later, when more kernel
  54708. - * subsystems (like slab allocator) are available.
  54709. - */
  54710. - cma->base_pfn = PFN_DOWN(base);
  54711. - cma->count = size >> PAGE_SHIFT;
  54712. - *res_cma = cma;
  54713. - cma_area_count++;
  54714. + int ret;
  54715. - pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
  54716. - (unsigned long)base);
  54717. + ret = cma_declare_contiguous(base, size, limit, 0, 0, fixed, res_cma);
  54718. + if (ret)
  54719. + return ret;
  54720. /* Architecture specific contiguous memory fixup. */
  54721. - dma_contiguous_early_fixup(base, size);
  54722. + dma_contiguous_early_fixup(cma_get_base(*res_cma),
  54723. + cma_get_size(*res_cma));
  54724. +
  54725. return 0;
  54726. -err:
  54727. - pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
  54728. - return ret;
  54729. }
  54730. /**
  54731. @@ -279,57 +184,16 @@
  54732. *
  54733. * This function allocates memory buffer for specified device. It uses
  54734. * device specific contiguous memory area if available or the default
  54735. - * global one. Requires architecture specific get_dev_cma_area() helper
  54736. + * global one. Requires architecture specific dev_get_cma_area() helper
  54737. * function.
  54738. */
  54739. struct page *dma_alloc_from_contiguous(struct device *dev, int count,
  54740. unsigned int align)
  54741. {
  54742. - unsigned long mask, pfn, pageno, start = 0;
  54743. - struct cma *cma = dev_get_cma_area(dev);
  54744. - struct page *page = NULL;
  54745. - int ret;
  54746. -
  54747. - if (!cma || !cma->count)
  54748. - return NULL;
  54749. -
  54750. if (align > CONFIG_CMA_ALIGNMENT)
  54751. align = CONFIG_CMA_ALIGNMENT;
  54752. - pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
  54753. - count, align);
  54754. -
  54755. - if (!count)
  54756. - return NULL;
  54757. -
  54758. - mask = (1 << align) - 1;
  54759. -
  54760. - mutex_lock(&cma_mutex);
  54761. -
  54762. - for (;;) {
  54763. - pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
  54764. - start, count, mask);
  54765. - if (pageno >= cma->count)
  54766. - break;
  54767. -
  54768. - pfn = cma->base_pfn + pageno;
  54769. - ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
  54770. - if (ret == 0) {
  54771. - bitmap_set(cma->bitmap, pageno, count);
  54772. - page = pfn_to_page(pfn);
  54773. - break;
  54774. - } else if (ret != -EBUSY) {
  54775. - break;
  54776. - }
  54777. - pr_debug("%s(): memory range at %p is busy, retrying\n",
  54778. - __func__, pfn_to_page(pfn));
  54779. - /* try again with a bit different memory target */
  54780. - start = pageno + mask + 1;
  54781. - }
  54782. -
  54783. - mutex_unlock(&cma_mutex);
  54784. - pr_debug("%s(): returned %p\n", __func__, page);
  54785. - return page;
  54786. + return cma_alloc(dev_get_cma_area(dev), count, align);
  54787. }
  54788. /**
  54789. @@ -345,25 +209,5 @@
  54790. bool dma_release_from_contiguous(struct device *dev, struct page *pages,
  54791. int count)
  54792. {
  54793. - struct cma *cma = dev_get_cma_area(dev);
  54794. - unsigned long pfn;
  54795. -
  54796. - if (!cma || !pages)
  54797. - return false;
  54798. -
  54799. - pr_debug("%s(page %p)\n", __func__, (void *)pages);
  54800. -
  54801. - pfn = page_to_pfn(pages);
  54802. -
  54803. - if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
  54804. - return false;
  54805. -
  54806. - VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
  54807. -
  54808. - mutex_lock(&cma_mutex);
  54809. - bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
  54810. - free_contig_range(pfn, count);
  54811. - mutex_unlock(&cma_mutex);
  54812. -
  54813. - return true;
  54814. + return cma_release(dev_get_cma_area(dev), pages, count);
  54815. }
  54816. diff -Nur linux-3.14.17/drivers/base/Kconfig linux-imx6-3.14/drivers/base/Kconfig
  54817. --- linux-3.14.17/drivers/base/Kconfig 2014-08-14 03:38:34.000000000 +0200
  54818. +++ linux-imx6-3.14/drivers/base/Kconfig 2014-09-11 18:05:59.498027972 +0200
  54819. @@ -185,6 +185,14 @@
  54820. bool
  54821. default n
  54822. +config HAVE_CPU_AUTOPROBE
  54823. + def_bool ARCH_HAS_CPU_AUTOPROBE
  54824. +
  54825. +config GENERIC_CPU_AUTOPROBE
  54826. + bool
  54827. + depends on !ARCH_HAS_CPU_AUTOPROBE
  54828. + select HAVE_CPU_AUTOPROBE
  54829. +
  54830. config SOC_BUS
  54831. bool
  54832. @@ -266,16 +274,6 @@
  54833. If unsure, leave the default value "8".
  54834. -config CMA_AREAS
  54835. - int "Maximum count of the CMA device-private areas"
  54836. - default 7
  54837. - help
  54838. - CMA allows to create CMA areas for particular devices. This parameter
  54839. - sets the maximum number of such device private CMA areas in the
  54840. - system.
  54841. -
  54842. - If unsure, leave the default value "7".
  54843. -
  54844. endif
  54845. endmenu
  54846. diff -Nur linux-3.14.17/drivers/base/platform.c linux-imx6-3.14/drivers/base/platform.c
  54847. --- linux-3.14.17/drivers/base/platform.c 2014-08-14 03:38:34.000000000 +0200
  54848. +++ linux-imx6-3.14/drivers/base/platform.c 2014-09-11 18:05:59.526028085 +0200
  54849. @@ -89,13 +89,8 @@
  54850. return dev->archdata.irqs[num];
  54851. #else
  54852. struct resource *r;
  54853. - if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
  54854. - int ret;
  54855. -
  54856. - ret = of_irq_get(dev->dev.of_node, num);
  54857. - if (ret >= 0 || ret == -EPROBE_DEFER)
  54858. - return ret;
  54859. - }
  54860. + if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node)
  54861. + return of_irq_get(dev->dev.of_node, num);
  54862. r = platform_get_resource(dev, IORESOURCE_IRQ, num);
  54863. diff -Nur linux-3.14.17/drivers/bus/arm-cci.c linux-imx6-3.14/drivers/bus/arm-cci.c
  54864. --- linux-3.14.17/drivers/bus/arm-cci.c 2014-08-14 03:38:34.000000000 +0200
  54865. +++ linux-imx6-3.14/drivers/bus/arm-cci.c 2014-09-11 18:05:59.666028644 +0200
  54866. @@ -26,6 +26,7 @@
  54867. #include <asm/cacheflush.h>
  54868. #include <asm/irq_regs.h>
  54869. +#include <asm/psci.h>
  54870. #include <asm/pmu.h>
  54871. #include <asm/smp_plat.h>
  54872. @@ -544,6 +545,7 @@
  54873. cci_pmu->plat_device = pdev;
  54874. cci_pmu->num_events = pmu_get_max_counters();
  54875. + cpumask_setall(&cci_pmu->valid_cpus);
  54876. return armpmu_register(cci_pmu, -1);
  54877. }
  54878. @@ -969,6 +971,11 @@
  54879. const char *match_str;
  54880. bool is_ace;
  54881. + if (psci_probe() == 0) {
  54882. + pr_debug("psci found. Aborting cci probe\n");
  54883. + return -ENODEV;
  54884. + }
  54885. +
  54886. np = of_find_matching_node(NULL, arm_cci_matches);
  54887. if (!np)
  54888. return -ENODEV;
  54889. diff -Nur linux-3.14.17/drivers/char/fsl_otp.c linux-imx6-3.14/drivers/char/fsl_otp.c
  54890. --- linux-3.14.17/drivers/char/fsl_otp.c 1970-01-01 01:00:00.000000000 +0100
  54891. +++ linux-imx6-3.14/drivers/char/fsl_otp.c 2014-09-11 18:05:59.682028708 +0200
  54892. @@ -0,0 +1,299 @@
  54893. +/*
  54894. + * Freescale On-Chip OTP driver
  54895. + *
  54896. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  54897. + *
  54898. + * This program is free software; you can redistribute it and/or modify
  54899. + * it under the terms of the GNU General Public License as published by
  54900. + * the Free Software Foundation; either version 2 of the License, or
  54901. + * (at your option) any later version.
  54902. + *
  54903. + * This program is distributed in the hope that it will be useful,
  54904. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  54905. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  54906. + * GNU General Public License for more details.
  54907. + *
  54908. + * You should have received a copy of the GNU General Public License
  54909. + * along with this program; if not, write to the Free Software
  54910. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  54911. + */
  54912. +
  54913. +#include <linux/clk.h>
  54914. +#include <linux/delay.h>
  54915. +#include <linux/err.h>
  54916. +#include <linux/init.h>
  54917. +#include <linux/io.h>
  54918. +#include <linux/kobject.h>
  54919. +#include <linux/module.h>
  54920. +#include <linux/mutex.h>
  54921. +#include <linux/of.h>
  54922. +#include <linux/platform_device.h>
  54923. +#include <linux/slab.h>
  54924. +#include <linux/sysfs.h>
  54925. +
  54926. +#define HW_OCOTP_CTRL 0x00000000
  54927. +#define HW_OCOTP_CTRL_SET 0x00000004
  54928. +#define BP_OCOTP_CTRL_WR_UNLOCK 16
  54929. +#define BM_OCOTP_CTRL_WR_UNLOCK 0xFFFF0000
  54930. +#define BM_OCOTP_CTRL_RELOAD_SHADOWS 0x00000400
  54931. +#define BM_OCOTP_CTRL_ERROR 0x00000200
  54932. +#define BM_OCOTP_CTRL_BUSY 0x00000100
  54933. +#define BP_OCOTP_CTRL_ADDR 0
  54934. +#define BM_OCOTP_CTRL_ADDR 0x0000007F
  54935. +
  54936. +#define HW_OCOTP_TIMING 0x00000010
  54937. +#define BP_OCOTP_TIMING_STROBE_READ 16
  54938. +#define BM_OCOTP_TIMING_STROBE_READ 0x003F0000
  54939. +#define BP_OCOTP_TIMING_RELAX 12
  54940. +#define BM_OCOTP_TIMING_RELAX 0x0000F000
  54941. +#define BP_OCOTP_TIMING_STROBE_PROG 0
  54942. +#define BM_OCOTP_TIMING_STROBE_PROG 0x00000FFF
  54943. +
  54944. +#define HW_OCOTP_DATA 0x00000020
  54945. +
  54946. +#define HW_OCOTP_CUST_N(n) (0x00000400 + (n) * 0x10)
  54947. +#define BF(value, field) (((value) << BP_##field) & BM_##field)
  54948. +
  54949. +#define DEF_RELAX 20 /* > 16.5ns */
  54950. +
  54951. +#define BANK(a, b, c, d, e, f, g, h) { \
  54952. + "HW_OCOTP_"#a, "HW_OCOTP_"#b, "HW_OCOTP_"#c, "HW_OCOTP_"#d, \
  54953. + "HW_OCOTP_"#e, "HW_OCOTP_"#f, "HW_OCOTP_"#g, "HW_OCOTP_"#h, \
  54954. +}
  54955. +
  54956. +static const char *imx6q_otp_desc[16][8] = {
  54957. + BANK(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
  54958. + BANK(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
  54959. + BANK(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
  54960. + BANK(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
  54961. + BANK(RESP0, HSJC_RESP1, MAC0, MAC1, HDCP_KSV0, HDCP_KSV1, GP1, GP2),
  54962. + BANK(DTCP_KEY0, DTCP_KEY1, DTCP_KEY2, DTCP_KEY3, DTCP_KEY4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
  54963. + BANK(HDCP_KEY0, HDCP_KEY1, HDCP_KEY2, HDCP_KEY3, HDCP_KEY4, HDCP_KEY5, HDCP_KEY6, HDCP_KEY7),
  54964. + BANK(HDCP_KEY8, HDCP_KEY9, HDCP_KEY10, HDCP_KEY11, HDCP_KEY12, HDCP_KEY13, HDCP_KEY14, HDCP_KEY15),
  54965. + BANK(HDCP_KEY16, HDCP_KEY17, HDCP_KEY18, HDCP_KEY19, HDCP_KEY20, HDCP_KEY21, HDCP_KEY22, HDCP_KEY23),
  54966. + BANK(HDCP_KEY24, HDCP_KEY25, HDCP_KEY26, HDCP_KEY27, HDCP_KEY28, HDCP_KEY29, HDCP_KEY30, HDCP_KEY31),
  54967. + BANK(HDCP_KEY32, HDCP_KEY33, HDCP_KEY34, HDCP_KEY35, HDCP_KEY36, HDCP_KEY37, HDCP_KEY38, HDCP_KEY39),
  54968. + BANK(HDCP_KEY40, HDCP_KEY41, HDCP_KEY42, HDCP_KEY43, HDCP_KEY44, HDCP_KEY45, HDCP_KEY46, HDCP_KEY47),
  54969. + BANK(HDCP_KEY48, HDCP_KEY49, HDCP_KEY50, HDCP_KEY51, HDCP_KEY52, HDCP_KEY53, HDCP_KEY54, HDCP_KEY55),
  54970. + BANK(HDCP_KEY56, HDCP_KEY57, HDCP_KEY58, HDCP_KEY59, HDCP_KEY60, HDCP_KEY61, HDCP_KEY62, HDCP_KEY63),
  54971. + BANK(HDCP_KEY64, HDCP_KEY65, HDCP_KEY66, HDCP_KEY67, HDCP_KEY68, HDCP_KEY69, HDCP_KEY70, HDCP_KEY71),
  54972. + BANK(CRC0, CRC1, CRC2, CRC3, CRC4, CRC5, CRC6, CRC7),
  54973. +};
  54974. +
  54975. +static DEFINE_MUTEX(otp_mutex);
  54976. +static void __iomem *otp_base;
  54977. +static struct clk *otp_clk;
  54978. +struct kobject *otp_kobj;
  54979. +struct kobj_attribute *otp_kattr;
  54980. +struct attribute_group *otp_attr_group;
  54981. +
  54982. +static void set_otp_timing(void)
  54983. +{
  54984. + unsigned long clk_rate = 0;
  54985. + unsigned long strobe_read, relex, strobe_prog;
  54986. + u32 timing = 0;
  54987. +
  54988. + clk_rate = clk_get_rate(otp_clk);
  54989. +
  54990. + /* do optimization for too many zeros */
  54991. + relex = clk_rate / (1000000000 / DEF_RELAX) - 1;
  54992. + strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
  54993. + strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
  54994. +
  54995. + timing = BF(relex, OCOTP_TIMING_RELAX);
  54996. + timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
  54997. + timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
  54998. +
  54999. + __raw_writel(timing, otp_base + HW_OCOTP_TIMING);
  55000. +}
  55001. +
  55002. +static int otp_wait_busy(u32 flags)
  55003. +{
  55004. + int count;
  55005. + u32 c;
  55006. +
  55007. + for (count = 10000; count >= 0; count--) {
  55008. + c = __raw_readl(otp_base + HW_OCOTP_CTRL);
  55009. + if (!(c & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR | flags)))
  55010. + break;
  55011. + cpu_relax();
  55012. + }
  55013. +
  55014. + if (count < 0)
  55015. + return -ETIMEDOUT;
  55016. +
  55017. + return 0;
  55018. +}
  55019. +
  55020. +static ssize_t fsl_otp_show(struct kobject *kobj, struct kobj_attribute *attr,
  55021. + char *buf)
  55022. +{
  55023. + unsigned int index = attr - otp_kattr;
  55024. + u32 value = 0;
  55025. + int ret;
  55026. +
  55027. + ret = clk_prepare_enable(otp_clk);
  55028. + if (ret)
  55029. + return 0;
  55030. +
  55031. + mutex_lock(&otp_mutex);
  55032. +
  55033. + set_otp_timing();
  55034. + ret = otp_wait_busy(0);
  55035. + if (ret)
  55036. + goto out;
  55037. +
  55038. + value = __raw_readl(otp_base + HW_OCOTP_CUST_N(index));
  55039. +
  55040. +out:
  55041. + mutex_unlock(&otp_mutex);
  55042. + clk_disable_unprepare(otp_clk);
  55043. + return ret ? 0 : sprintf(buf, "0x%x\n", value);
  55044. +}
  55045. +
  55046. +static int otp_write_bits(int addr, u32 data, u32 magic)
  55047. +{
  55048. + u32 c; /* for control register */
  55049. +
  55050. + /* init the control register */
  55051. + c = __raw_readl(otp_base + HW_OCOTP_CTRL);
  55052. + c &= ~BM_OCOTP_CTRL_ADDR;
  55053. + c |= BF(addr, OCOTP_CTRL_ADDR);
  55054. + c |= BF(magic, OCOTP_CTRL_WR_UNLOCK);
  55055. + __raw_writel(c, otp_base + HW_OCOTP_CTRL);
  55056. +
  55057. + /* init the data register */
  55058. + __raw_writel(data, otp_base + HW_OCOTP_DATA);
  55059. + otp_wait_busy(0);
  55060. +
  55061. + mdelay(2); /* Write Postamble */
  55062. +
  55063. + return 0;
  55064. +}
  55065. +
  55066. +static ssize_t fsl_otp_store(struct kobject *kobj, struct kobj_attribute *attr,
  55067. + const char *buf, size_t count)
  55068. +{
  55069. + unsigned int index = attr - otp_kattr;
  55070. + u32 value;
  55071. + int ret;
  55072. +
  55073. + sscanf(buf, "0x%x", &value);
  55074. +
  55075. + ret = clk_prepare_enable(otp_clk);
  55076. + if (ret)
  55077. + return 0;
  55078. +
  55079. + mutex_lock(&otp_mutex);
  55080. +
  55081. + set_otp_timing();
  55082. + ret = otp_wait_busy(0);
  55083. + if (ret)
  55084. + goto out;
  55085. +
  55086. + otp_write_bits(index, value, 0x3e77);
  55087. +
  55088. + /* Reload all the shadow registers */
  55089. + __raw_writel(BM_OCOTP_CTRL_RELOAD_SHADOWS,
  55090. + otp_base + HW_OCOTP_CTRL_SET);
  55091. + udelay(1);
  55092. + otp_wait_busy(BM_OCOTP_CTRL_RELOAD_SHADOWS);
  55093. +
  55094. +out:
  55095. + mutex_unlock(&otp_mutex);
  55096. + clk_disable_unprepare(otp_clk);
  55097. + return ret ? 0 : count;
  55098. +}
  55099. +
  55100. +static int fsl_otp_probe(struct platform_device *pdev)
  55101. +{
  55102. + struct resource *res;
  55103. + struct attribute **attrs;
  55104. + const char **desc;
  55105. + int i, num;
  55106. + int ret;
  55107. +
  55108. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  55109. + otp_base = devm_ioremap_resource(&pdev->dev, res);
  55110. + if (IS_ERR(otp_base)) {
  55111. + ret = PTR_ERR(otp_base);
  55112. + dev_err(&pdev->dev, "failed to ioremap resource: %d\n", ret);
  55113. + return ret;
  55114. + }
  55115. +
  55116. + otp_clk = devm_clk_get(&pdev->dev, NULL);
  55117. + if (IS_ERR(otp_clk)) {
  55118. + ret = PTR_ERR(otp_clk);
  55119. + dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
  55120. + return ret;
  55121. + }
  55122. +
  55123. + desc = (const char **) imx6q_otp_desc;
  55124. + num = sizeof(imx6q_otp_desc) / sizeof(void *);
  55125. +
  55126. + /* The last one is NULL, which is used to detect the end */
  55127. + attrs = devm_kzalloc(&pdev->dev, (num + 1) * sizeof(*attrs),
  55128. + GFP_KERNEL);
  55129. + otp_kattr = devm_kzalloc(&pdev->dev, num * sizeof(*otp_kattr),
  55130. + GFP_KERNEL);
  55131. + otp_attr_group = devm_kzalloc(&pdev->dev, sizeof(*otp_attr_group),
  55132. + GFP_KERNEL);
  55133. + if (!attrs || !otp_kattr || !otp_attr_group)
  55134. + return -ENOMEM;
  55135. +
  55136. + for (i = 0; i < num; i++) {
  55137. + sysfs_attr_init(&otp_kattr[i].attr);
  55138. + otp_kattr[i].attr.name = desc[i];
  55139. + otp_kattr[i].attr.mode = 0600;
  55140. + otp_kattr[i].show = fsl_otp_show;
  55141. + otp_kattr[i].store = fsl_otp_store;
  55142. + attrs[i] = &otp_kattr[i].attr;
  55143. + }
  55144. + otp_attr_group->attrs = attrs;
  55145. +
  55146. + otp_kobj = kobject_create_and_add("fsl_otp", NULL);
  55147. + if (!otp_kobj) {
  55148. + dev_err(&pdev->dev, "failed to add kobject\n");
  55149. + return -ENOMEM;
  55150. + }
  55151. +
  55152. + ret = sysfs_create_group(otp_kobj, otp_attr_group);
  55153. + if (ret) {
  55154. + dev_err(&pdev->dev, "failed to create sysfs group: %d\n", ret);
  55155. + kobject_put(otp_kobj);
  55156. + return ret;
  55157. + }
  55158. +
  55159. + mutex_init(&otp_mutex);
  55160. +
  55161. + return 0;
  55162. +}
  55163. +
  55164. +static int fsl_otp_remove(struct platform_device *pdev)
  55165. +{
  55166. + sysfs_remove_group(otp_kobj, otp_attr_group);
  55167. + kobject_put(otp_kobj);
  55168. +
  55169. + return 0;
  55170. +}
  55171. +
  55172. +static const struct of_device_id fsl_otp_dt_ids[] = {
  55173. + { .compatible = "fsl,imx6q-ocotp", },
  55174. + { /* sentinel */ }
  55175. +};
  55176. +MODULE_DEVICE_TABLE(of, fsl_otp_dt_ids);
  55177. +
  55178. +static struct platform_driver fsl_otp_driver = {
  55179. + .driver = {
  55180. + .name = "imx-ocotp",
  55181. + .owner = THIS_MODULE,
  55182. + .of_match_table = fsl_otp_dt_ids,
  55183. + },
  55184. + .probe = fsl_otp_probe,
  55185. + .remove = fsl_otp_remove,
  55186. +};
  55187. +module_platform_driver(fsl_otp_driver);
  55188. +
  55189. +MODULE_LICENSE("GPL");
  55190. +MODULE_AUTHOR("Huang Shijie <b32955@freescale.com>");
  55191. +MODULE_DESCRIPTION("Freescale i.MX OCOTP driver");
  55192. diff -Nur linux-3.14.17/drivers/char/Kconfig linux-imx6-3.14/drivers/char/Kconfig
  55193. --- linux-3.14.17/drivers/char/Kconfig 2014-08-14 03:38:34.000000000 +0200
  55194. +++ linux-imx6-3.14/drivers/char/Kconfig 2014-09-11 18:05:59.670028659 +0200
  55195. @@ -82,6 +82,21 @@
  55196. If unsure, say N.
  55197. +config FSL_OTP
  55198. + tristate "Freescale On-Chip OTP Memory Support"
  55199. + depends on HAS_IOMEM && OF
  55200. + help
  55201. + If you say Y here, you will get support for a character device
  55202. + interface into the One Time Programmable memory pages that are
  55203. + stored on the some Freescale i.MX processors. This will not get
  55204. + you access to the secure memory pages however. You will need to
  55205. + write your own secure code and reader for that.
  55206. +
  55207. + To compile this driver as a module, choose M here: the module
  55208. + will be called fsl_otp.
  55209. +
  55210. + If unsure, it is safe to say Y.
  55211. +
  55212. config PRINTER
  55213. tristate "Parallel printer support"
  55214. depends on PARPORT
  55215. diff -Nur linux-3.14.17/drivers/char/Makefile linux-imx6-3.14/drivers/char/Makefile
  55216. --- linux-3.14.17/drivers/char/Makefile 2014-08-14 03:38:34.000000000 +0200
  55217. +++ linux-imx6-3.14/drivers/char/Makefile 2014-09-11 18:05:59.670028659 +0200
  55218. @@ -16,6 +16,7 @@
  55219. obj-$(CONFIG_IBM_BSR) += bsr.o
  55220. obj-$(CONFIG_SGI_MBCS) += mbcs.o
  55221. obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
  55222. +obj-$(CONFIG_FSL_OTP) += fsl_otp.o
  55223. obj-$(CONFIG_PRINTER) += lp.o
  55224. diff -Nur linux-3.14.17/drivers/clk/clk.c linux-imx6-3.14/drivers/clk/clk.c
  55225. --- linux-3.14.17/drivers/clk/clk.c 2014-08-14 03:38:34.000000000 +0200
  55226. +++ linux-imx6-3.14/drivers/clk/clk.c 2014-09-11 18:05:59.854029395 +0200
  55227. @@ -1702,6 +1702,7 @@
  55228. */
  55229. int clk_set_parent(struct clk *clk, struct clk *parent)
  55230. {
  55231. + struct clk *child;
  55232. int ret = 0;
  55233. int p_index = 0;
  55234. unsigned long p_rate = 0;
  55235. @@ -1728,6 +1729,18 @@
  55236. goto out;
  55237. }
  55238. + /* check two consecutive basic mux clocks */
  55239. + if (clk->flags & CLK_IS_BASIC_MUX) {
  55240. + hlist_for_each_entry(child, &clk->children, child_node) {
  55241. + if (child->flags & CLK_IS_BASIC_MUX) {
  55242. + pr_err("%s: failed to switch parent of %s due to child mux %s\n",
  55243. + __func__, clk->name, child->name);
  55244. + ret = -EBUSY;
  55245. + goto out;
  55246. + }
  55247. + }
  55248. + }
  55249. +
  55250. /* try finding the new parent index */
  55251. if (parent) {
  55252. p_index = clk_fetch_parent_index(clk, parent);
  55253. diff -Nur linux-3.14.17/drivers/clk/clk-mux.c linux-imx6-3.14/drivers/clk/clk-mux.c
  55254. --- linux-3.14.17/drivers/clk/clk-mux.c 2014-08-14 03:38:34.000000000 +0200
  55255. +++ linux-imx6-3.14/drivers/clk/clk-mux.c 2014-09-11 18:05:59.826029283 +0200
  55256. @@ -143,7 +143,7 @@
  55257. init.ops = &clk_mux_ro_ops;
  55258. else
  55259. init.ops = &clk_mux_ops;
  55260. - init.flags = flags | CLK_IS_BASIC;
  55261. + init.flags = flags | CLK_IS_BASIC | CLK_IS_BASIC_MUX;
  55262. init.parent_names = parent_names;
  55263. init.num_parents = num_parents;
  55264. diff -Nur linux-3.14.17/drivers/cpufreq/cpufreq.c linux-imx6-3.14/drivers/cpufreq/cpufreq.c
  55265. --- linux-3.14.17/drivers/cpufreq/cpufreq.c 2014-08-14 03:38:34.000000000 +0200
  55266. +++ linux-imx6-3.14/drivers/cpufreq/cpufreq.c 2014-09-11 18:05:59.998029971 +0200
  55267. @@ -1089,12 +1089,10 @@
  55268. * the creation of a brand new one. So we need to perform this update
  55269. * by invoking update_policy_cpu().
  55270. */
  55271. - if (frozen && cpu != policy->cpu) {
  55272. + if (frozen && cpu != policy->cpu)
  55273. update_policy_cpu(policy, cpu);
  55274. - WARN_ON(kobject_move(&policy->kobj, &dev->kobj));
  55275. - } else {
  55276. + else
  55277. policy->cpu = cpu;
  55278. - }
  55279. policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
  55280. cpumask_copy(policy->cpus, cpumask_of(cpu));
  55281. diff -Nur linux-3.14.17/drivers/cpufreq/cpufreq_interactive.c linux-imx6-3.14/drivers/cpufreq/cpufreq_interactive.c
  55282. --- linux-3.14.17/drivers/cpufreq/cpufreq_interactive.c 1970-01-01 01:00:00.000000000 +0100
  55283. +++ linux-imx6-3.14/drivers/cpufreq/cpufreq_interactive.c 2014-09-11 18:05:59.998029971 +0200
  55284. @@ -0,0 +1,1349 @@
  55285. +/*
  55286. + * drivers/cpufreq/cpufreq_interactive.c
  55287. + *
  55288. + * Copyright (C) 2010 Google, Inc.
  55289. + *
  55290. + * This software is licensed under the terms of the GNU General Public
  55291. + * License version 2, as published by the Free Software Foundation, and
  55292. + * may be copied, distributed, and modified under those terms.
  55293. + *
  55294. + * This program is distributed in the hope that it will be useful,
  55295. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  55296. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  55297. + * GNU General Public License for more details.
  55298. + *
  55299. + * Author: Mike Chan (mike@android.com)
  55300. + *
  55301. + */
  55302. +
  55303. +#include <linux/cpu.h>
  55304. +#include <linux/cpumask.h>
  55305. +#include <linux/cpufreq.h>
  55306. +#include <linux/module.h>
  55307. +#include <linux/moduleparam.h>
  55308. +#include <linux/rwsem.h>
  55309. +#include <linux/sched.h>
  55310. +#include <linux/sched/rt.h>
  55311. +#include <linux/tick.h>
  55312. +#include <linux/time.h>
  55313. +#include <linux/timer.h>
  55314. +#include <linux/workqueue.h>
  55315. +#include <linux/kthread.h>
  55316. +#include <linux/slab.h>
  55317. +
  55318. +#define CREATE_TRACE_POINTS
  55319. +#include <trace/events/cpufreq_interactive.h>
  55320. +
  55321. +struct cpufreq_interactive_cpuinfo {
  55322. + struct timer_list cpu_timer;
  55323. + struct timer_list cpu_slack_timer;
  55324. + spinlock_t load_lock; /* protects the next 4 fields */
  55325. + u64 time_in_idle;
  55326. + u64 time_in_idle_timestamp;
  55327. + u64 cputime_speedadj;
  55328. + u64 cputime_speedadj_timestamp;
  55329. + struct cpufreq_policy *policy;
  55330. + struct cpufreq_frequency_table *freq_table;
  55331. + unsigned int target_freq;
  55332. + unsigned int floor_freq;
  55333. + u64 floor_validate_time;
  55334. + u64 hispeed_validate_time;
  55335. + struct rw_semaphore enable_sem;
  55336. + int governor_enabled;
  55337. +};
  55338. +
  55339. +static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo);
  55340. +
  55341. +/* realtime thread handles frequency scaling */
  55342. +static struct task_struct *speedchange_task;
  55343. +static cpumask_t speedchange_cpumask;
  55344. +static spinlock_t speedchange_cpumask_lock;
  55345. +static struct mutex gov_lock;
  55346. +
  55347. +/* Target load. Lower values result in higher CPU speeds. */
  55348. +#define DEFAULT_TARGET_LOAD 90
  55349. +static unsigned int default_target_loads[] = {DEFAULT_TARGET_LOAD};
  55350. +
  55351. +#define DEFAULT_TIMER_RATE (20 * USEC_PER_MSEC)
  55352. +#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE
  55353. +static unsigned int default_above_hispeed_delay[] = {
  55354. + DEFAULT_ABOVE_HISPEED_DELAY };
  55355. +
  55356. +struct cpufreq_interactive_tunables {
  55357. + int usage_count;
  55358. + /* Hi speed to bump to from lo speed when load burst (default max) */
  55359. + unsigned int hispeed_freq;
  55360. + /* Go to hi speed when CPU load at or above this value. */
  55361. +#define DEFAULT_GO_HISPEED_LOAD 99
  55362. + unsigned long go_hispeed_load;
  55363. + /* Target load. Lower values result in higher CPU speeds. */
  55364. + spinlock_t target_loads_lock;
  55365. + unsigned int *target_loads;
  55366. + int ntarget_loads;
  55367. + /*
  55368. + * The minimum amount of time to spend at a frequency before we can ramp
  55369. + * down.
  55370. + */
  55371. +#define DEFAULT_MIN_SAMPLE_TIME (80 * USEC_PER_MSEC)
  55372. + unsigned long min_sample_time;
  55373. + /*
  55374. + * The sample rate of the timer used to increase frequency
  55375. + */
  55376. + unsigned long timer_rate;
  55377. + /*
  55378. + * Wait this long before raising speed above hispeed, by default a
  55379. + * single timer interval.
  55380. + */
  55381. + spinlock_t above_hispeed_delay_lock;
  55382. + unsigned int *above_hispeed_delay;
  55383. + int nabove_hispeed_delay;
  55384. + /* Non-zero means indefinite speed boost active */
  55385. + int boost_val;
  55386. + /* Duration of a boot pulse in usecs */
  55387. + int boostpulse_duration_val;
  55388. + /* End time of boost pulse in ktime converted to usecs */
  55389. + u64 boostpulse_endtime;
  55390. + /*
  55391. + * Max additional time to wait in idle, beyond timer_rate, at speeds
  55392. + * above minimum before wakeup to reduce speed, or -1 if unnecessary.
  55393. + */
  55394. +#define DEFAULT_TIMER_SLACK (4 * DEFAULT_TIMER_RATE)
  55395. + int timer_slack_val;
  55396. + bool io_is_busy;
  55397. +};
  55398. +
  55399. +/* For cases where we have single governor instance for system */
  55400. +struct cpufreq_interactive_tunables *common_tunables;
  55401. +
  55402. +static struct attribute_group *get_sysfs_attr(void);
  55403. +
  55404. +static void cpufreq_interactive_timer_resched(
  55405. + struct cpufreq_interactive_cpuinfo *pcpu)
  55406. +{
  55407. + struct cpufreq_interactive_tunables *tunables =
  55408. + pcpu->policy->governor_data;
  55409. + unsigned long expires;
  55410. + unsigned long flags;
  55411. +
  55412. + spin_lock_irqsave(&pcpu->load_lock, flags);
  55413. + pcpu->time_in_idle =
  55414. + get_cpu_idle_time(smp_processor_id(),
  55415. + &pcpu->time_in_idle_timestamp,
  55416. + tunables->io_is_busy);
  55417. + pcpu->cputime_speedadj = 0;
  55418. + pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
  55419. + expires = jiffies + usecs_to_jiffies(tunables->timer_rate);
  55420. + mod_timer_pinned(&pcpu->cpu_timer, expires);
  55421. +
  55422. + if (tunables->timer_slack_val >= 0 &&
  55423. + pcpu->target_freq > pcpu->policy->min) {
  55424. + expires += usecs_to_jiffies(tunables->timer_slack_val);
  55425. + mod_timer_pinned(&pcpu->cpu_slack_timer, expires);
  55426. + }
  55427. +
  55428. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  55429. +}
  55430. +
  55431. +/* The caller shall take enable_sem write semaphore to avoid any timer race.
  55432. + * The cpu_timer and cpu_slack_timer must be deactivated when calling this
  55433. + * function.
  55434. + */
  55435. +static void cpufreq_interactive_timer_start(
  55436. + struct cpufreq_interactive_tunables *tunables, int cpu)
  55437. +{
  55438. + struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
  55439. + unsigned long expires = jiffies +
  55440. + usecs_to_jiffies(tunables->timer_rate);
  55441. + unsigned long flags;
  55442. +
  55443. + pcpu->cpu_timer.expires = expires;
  55444. + add_timer_on(&pcpu->cpu_timer, cpu);
  55445. + if (tunables->timer_slack_val >= 0 &&
  55446. + pcpu->target_freq > pcpu->policy->min) {
  55447. + expires += usecs_to_jiffies(tunables->timer_slack_val);
  55448. + pcpu->cpu_slack_timer.expires = expires;
  55449. + add_timer_on(&pcpu->cpu_slack_timer, cpu);
  55450. + }
  55451. +
  55452. + spin_lock_irqsave(&pcpu->load_lock, flags);
  55453. + pcpu->time_in_idle =
  55454. + get_cpu_idle_time(cpu, &pcpu->time_in_idle_timestamp,
  55455. + tunables->io_is_busy);
  55456. + pcpu->cputime_speedadj = 0;
  55457. + pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
  55458. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  55459. +}
  55460. +
  55461. +static unsigned int freq_to_above_hispeed_delay(
  55462. + struct cpufreq_interactive_tunables *tunables,
  55463. + unsigned int freq)
  55464. +{
  55465. + int i;
  55466. + unsigned int ret;
  55467. + unsigned long flags;
  55468. +
  55469. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  55470. +
  55471. + for (i = 0; i < tunables->nabove_hispeed_delay - 1 &&
  55472. + freq >= tunables->above_hispeed_delay[i+1]; i += 2)
  55473. + ;
  55474. +
  55475. + ret = tunables->above_hispeed_delay[i];
  55476. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  55477. + return ret;
  55478. +}
  55479. +
  55480. +static unsigned int freq_to_targetload(
  55481. + struct cpufreq_interactive_tunables *tunables, unsigned int freq)
  55482. +{
  55483. + int i;
  55484. + unsigned int ret;
  55485. + unsigned long flags;
  55486. +
  55487. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  55488. +
  55489. + for (i = 0; i < tunables->ntarget_loads - 1 &&
  55490. + freq >= tunables->target_loads[i+1]; i += 2)
  55491. + ;
  55492. +
  55493. + ret = tunables->target_loads[i];
  55494. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  55495. + return ret;
  55496. +}
  55497. +
  55498. +/*
  55499. + * If increasing frequencies never map to a lower target load then
  55500. + * choose_freq() will find the minimum frequency that does not exceed its
  55501. + * target load given the current load.
  55502. + */
  55503. +static unsigned int choose_freq(struct cpufreq_interactive_cpuinfo *pcpu,
  55504. + unsigned int loadadjfreq)
  55505. +{
  55506. + unsigned int freq = pcpu->policy->cur;
  55507. + unsigned int prevfreq, freqmin, freqmax;
  55508. + unsigned int tl;
  55509. + int index;
  55510. +
  55511. + freqmin = 0;
  55512. + freqmax = UINT_MAX;
  55513. +
  55514. + do {
  55515. + prevfreq = freq;
  55516. + tl = freq_to_targetload(pcpu->policy->governor_data, freq);
  55517. +
  55518. + /*
  55519. + * Find the lowest frequency where the computed load is less
  55520. + * than or equal to the target load.
  55521. + */
  55522. +
  55523. + if (cpufreq_frequency_table_target(
  55524. + pcpu->policy, pcpu->freq_table, loadadjfreq / tl,
  55525. + CPUFREQ_RELATION_L, &index))
  55526. + break;
  55527. + freq = pcpu->freq_table[index].frequency;
  55528. +
  55529. + if (freq > prevfreq) {
  55530. + /* The previous frequency is too low. */
  55531. + freqmin = prevfreq;
  55532. +
  55533. + if (freq >= freqmax) {
  55534. + /*
  55535. + * Find the highest frequency that is less
  55536. + * than freqmax.
  55537. + */
  55538. + if (cpufreq_frequency_table_target(
  55539. + pcpu->policy, pcpu->freq_table,
  55540. + freqmax - 1, CPUFREQ_RELATION_H,
  55541. + &index))
  55542. + break;
  55543. + freq = pcpu->freq_table[index].frequency;
  55544. +
  55545. + if (freq == freqmin) {
  55546. + /*
  55547. + * The first frequency below freqmax
  55548. + * has already been found to be too
  55549. + * low. freqmax is the lowest speed
  55550. + * we found that is fast enough.
  55551. + */
  55552. + freq = freqmax;
  55553. + break;
  55554. + }
  55555. + }
  55556. + } else if (freq < prevfreq) {
  55557. + /* The previous frequency is high enough. */
  55558. + freqmax = prevfreq;
  55559. +
  55560. + if (freq <= freqmin) {
  55561. + /*
  55562. + * Find the lowest frequency that is higher
  55563. + * than freqmin.
  55564. + */
  55565. + if (cpufreq_frequency_table_target(
  55566. + pcpu->policy, pcpu->freq_table,
  55567. + freqmin + 1, CPUFREQ_RELATION_L,
  55568. + &index))
  55569. + break;
  55570. + freq = pcpu->freq_table[index].frequency;
  55571. +
  55572. + /*
  55573. + * If freqmax is the first frequency above
  55574. + * freqmin then we have already found that
  55575. + * this speed is fast enough.
  55576. + */
  55577. + if (freq == freqmax)
  55578. + break;
  55579. + }
  55580. + }
  55581. +
  55582. + /* If same frequency chosen as previous then done. */
  55583. + } while (freq != prevfreq);
  55584. +
  55585. + return freq;
  55586. +}
  55587. +
  55588. +static u64 update_load(int cpu)
  55589. +{
  55590. + struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
  55591. + struct cpufreq_interactive_tunables *tunables =
  55592. + pcpu->policy->governor_data;
  55593. + u64 now;
  55594. + u64 now_idle;
  55595. + unsigned int delta_idle;
  55596. + unsigned int delta_time;
  55597. + u64 active_time;
  55598. +
  55599. + now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy);
  55600. + delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle);
  55601. + delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp);
  55602. +
  55603. + if (delta_time <= delta_idle)
  55604. + active_time = 0;
  55605. + else
  55606. + active_time = delta_time - delta_idle;
  55607. +
  55608. + pcpu->cputime_speedadj += active_time * pcpu->policy->cur;
  55609. +
  55610. + pcpu->time_in_idle = now_idle;
  55611. + pcpu->time_in_idle_timestamp = now;
  55612. + return now;
  55613. +}
  55614. +
  55615. +static void cpufreq_interactive_timer(unsigned long data)
  55616. +{
  55617. + u64 now;
  55618. + unsigned int delta_time;
  55619. + u64 cputime_speedadj;
  55620. + int cpu_load;
  55621. + struct cpufreq_interactive_cpuinfo *pcpu =
  55622. + &per_cpu(cpuinfo, data);
  55623. + struct cpufreq_interactive_tunables *tunables =
  55624. + pcpu->policy->governor_data;
  55625. + unsigned int new_freq;
  55626. + unsigned int loadadjfreq;
  55627. + unsigned int index;
  55628. + unsigned long flags;
  55629. + bool boosted;
  55630. +
  55631. + if (!down_read_trylock(&pcpu->enable_sem))
  55632. + return;
  55633. + if (!pcpu->governor_enabled)
  55634. + goto exit;
  55635. +
  55636. + spin_lock_irqsave(&pcpu->load_lock, flags);
  55637. + now = update_load(data);
  55638. + delta_time = (unsigned int)(now - pcpu->cputime_speedadj_timestamp);
  55639. + cputime_speedadj = pcpu->cputime_speedadj;
  55640. + spin_unlock_irqrestore(&pcpu->load_lock, flags);
  55641. +
  55642. + if (WARN_ON_ONCE(!delta_time))
  55643. + goto rearm;
  55644. +
  55645. + do_div(cputime_speedadj, delta_time);
  55646. + loadadjfreq = (unsigned int)cputime_speedadj * 100;
  55647. + cpu_load = loadadjfreq / pcpu->target_freq;
  55648. + boosted = tunables->boost_val || now < tunables->boostpulse_endtime;
  55649. +
  55650. + if (cpu_load >= tunables->go_hispeed_load || boosted) {
  55651. + if (pcpu->target_freq < tunables->hispeed_freq) {
  55652. + new_freq = tunables->hispeed_freq;
  55653. + } else {
  55654. + new_freq = choose_freq(pcpu, loadadjfreq);
  55655. +
  55656. + if (new_freq < tunables->hispeed_freq)
  55657. + new_freq = tunables->hispeed_freq;
  55658. + }
  55659. + } else {
  55660. + new_freq = choose_freq(pcpu, loadadjfreq);
  55661. + }
  55662. +
  55663. + if (pcpu->target_freq >= tunables->hispeed_freq &&
  55664. + new_freq > pcpu->target_freq &&
  55665. + now - pcpu->hispeed_validate_time <
  55666. + freq_to_above_hispeed_delay(tunables, pcpu->target_freq)) {
  55667. + trace_cpufreq_interactive_notyet(
  55668. + data, cpu_load, pcpu->target_freq,
  55669. + pcpu->policy->cur, new_freq);
  55670. + goto rearm;
  55671. + }
  55672. +
  55673. + pcpu->hispeed_validate_time = now;
  55674. +
  55675. + if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
  55676. + new_freq, CPUFREQ_RELATION_L,
  55677. + &index))
  55678. + goto rearm;
  55679. +
  55680. + new_freq = pcpu->freq_table[index].frequency;
  55681. +
  55682. + /*
  55683. + * Do not scale below floor_freq unless we have been at or above the
  55684. + * floor frequency for the minimum sample time since last validated.
  55685. + */
  55686. + if (new_freq < pcpu->floor_freq) {
  55687. + if (now - pcpu->floor_validate_time <
  55688. + tunables->min_sample_time) {
  55689. + trace_cpufreq_interactive_notyet(
  55690. + data, cpu_load, pcpu->target_freq,
  55691. + pcpu->policy->cur, new_freq);
  55692. + goto rearm;
  55693. + }
  55694. + }
  55695. +
  55696. + /*
  55697. + * Update the timestamp for checking whether speed has been held at
  55698. + * or above the selected frequency for a minimum of min_sample_time,
  55699. + * if not boosted to hispeed_freq. If boosted to hispeed_freq then we
  55700. + * allow the speed to drop as soon as the boostpulse duration expires
  55701. + * (or the indefinite boost is turned off).
  55702. + */
  55703. +
  55704. + if (!boosted || new_freq > tunables->hispeed_freq) {
  55705. + pcpu->floor_freq = new_freq;
  55706. + pcpu->floor_validate_time = now;
  55707. + }
  55708. +
  55709. + if (pcpu->target_freq == new_freq) {
  55710. + trace_cpufreq_interactive_already(
  55711. + data, cpu_load, pcpu->target_freq,
  55712. + pcpu->policy->cur, new_freq);
  55713. + goto rearm_if_notmax;
  55714. + }
  55715. +
  55716. + trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq,
  55717. + pcpu->policy->cur, new_freq);
  55718. +
  55719. + pcpu->target_freq = new_freq;
  55720. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  55721. + cpumask_set_cpu(data, &speedchange_cpumask);
  55722. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  55723. + wake_up_process(speedchange_task);
  55724. +
  55725. +rearm_if_notmax:
  55726. + /*
  55727. + * Already set max speed and don't see a need to change that,
  55728. + * wait until next idle to re-evaluate, don't need timer.
  55729. + */
  55730. + if (pcpu->target_freq == pcpu->policy->max)
  55731. + goto exit;
  55732. +
  55733. +rearm:
  55734. + if (!timer_pending(&pcpu->cpu_timer))
  55735. + cpufreq_interactive_timer_resched(pcpu);
  55736. +
  55737. +exit:
  55738. + up_read(&pcpu->enable_sem);
  55739. + return;
  55740. +}
  55741. +
  55742. +static void cpufreq_interactive_idle_start(void)
  55743. +{
  55744. + struct cpufreq_interactive_cpuinfo *pcpu =
  55745. + &per_cpu(cpuinfo, smp_processor_id());
  55746. + int pending;
  55747. +
  55748. + if (!down_read_trylock(&pcpu->enable_sem))
  55749. + return;
  55750. + if (!pcpu->governor_enabled) {
  55751. + up_read(&pcpu->enable_sem);
  55752. + return;
  55753. + }
  55754. +
  55755. + pending = timer_pending(&pcpu->cpu_timer);
  55756. +
  55757. + if (pcpu->target_freq != pcpu->policy->min) {
  55758. + /*
  55759. + * Entering idle while not at lowest speed. On some
  55760. + * platforms this can hold the other CPU(s) at that speed
  55761. + * even though the CPU is idle. Set a timer to re-evaluate
  55762. + * speed so this idle CPU doesn't hold the other CPUs above
  55763. + * min indefinitely. This should probably be a quirk of
  55764. + * the CPUFreq driver.
  55765. + */
  55766. + if (!pending)
  55767. + cpufreq_interactive_timer_resched(pcpu);
  55768. + }
  55769. +
  55770. + up_read(&pcpu->enable_sem);
  55771. +}
  55772. +
  55773. +static void cpufreq_interactive_idle_end(void)
  55774. +{
  55775. + struct cpufreq_interactive_cpuinfo *pcpu =
  55776. + &per_cpu(cpuinfo, smp_processor_id());
  55777. +
  55778. + if (!down_read_trylock(&pcpu->enable_sem))
  55779. + return;
  55780. + if (!pcpu->governor_enabled) {
  55781. + up_read(&pcpu->enable_sem);
  55782. + return;
  55783. + }
  55784. +
  55785. + /* Arm the timer for 1-2 ticks later if not already. */
  55786. + if (!timer_pending(&pcpu->cpu_timer)) {
  55787. + cpufreq_interactive_timer_resched(pcpu);
  55788. + } else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) {
  55789. + del_timer(&pcpu->cpu_timer);
  55790. + del_timer(&pcpu->cpu_slack_timer);
  55791. + cpufreq_interactive_timer(smp_processor_id());
  55792. + }
  55793. +
  55794. + up_read(&pcpu->enable_sem);
  55795. +}
  55796. +
  55797. +static int cpufreq_interactive_speedchange_task(void *data)
  55798. +{
  55799. + unsigned int cpu;
  55800. + cpumask_t tmp_mask;
  55801. + unsigned long flags;
  55802. + struct cpufreq_interactive_cpuinfo *pcpu;
  55803. +
  55804. + while (1) {
  55805. + set_current_state(TASK_INTERRUPTIBLE);
  55806. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  55807. +
  55808. + if (cpumask_empty(&speedchange_cpumask)) {
  55809. + spin_unlock_irqrestore(&speedchange_cpumask_lock,
  55810. + flags);
  55811. + schedule();
  55812. +
  55813. + if (kthread_should_stop())
  55814. + break;
  55815. +
  55816. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  55817. + }
  55818. +
  55819. + set_current_state(TASK_RUNNING);
  55820. + tmp_mask = speedchange_cpumask;
  55821. + cpumask_clear(&speedchange_cpumask);
  55822. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  55823. +
  55824. + for_each_cpu(cpu, &tmp_mask) {
  55825. + unsigned int j;
  55826. + unsigned int max_freq = 0;
  55827. +
  55828. + pcpu = &per_cpu(cpuinfo, cpu);
  55829. + if (!down_read_trylock(&pcpu->enable_sem))
  55830. + continue;
  55831. + if (!pcpu->governor_enabled) {
  55832. + up_read(&pcpu->enable_sem);
  55833. + continue;
  55834. + }
  55835. +
  55836. + for_each_cpu(j, pcpu->policy->cpus) {
  55837. + struct cpufreq_interactive_cpuinfo *pjcpu =
  55838. + &per_cpu(cpuinfo, j);
  55839. +
  55840. + if (pjcpu->target_freq > max_freq)
  55841. + max_freq = pjcpu->target_freq;
  55842. + }
  55843. +
  55844. + if (max_freq != pcpu->policy->cur)
  55845. + __cpufreq_driver_target(pcpu->policy,
  55846. + max_freq,
  55847. + CPUFREQ_RELATION_H);
  55848. + trace_cpufreq_interactive_setspeed(cpu,
  55849. + pcpu->target_freq,
  55850. + pcpu->policy->cur);
  55851. +
  55852. + up_read(&pcpu->enable_sem);
  55853. + }
  55854. + }
  55855. +
  55856. + return 0;
  55857. +}
  55858. +
  55859. +static void cpufreq_interactive_boost(void)
  55860. +{
  55861. + int i;
  55862. + int anyboost = 0;
  55863. + unsigned long flags;
  55864. + struct cpufreq_interactive_cpuinfo *pcpu;
  55865. + struct cpufreq_interactive_tunables *tunables;
  55866. +
  55867. + spin_lock_irqsave(&speedchange_cpumask_lock, flags);
  55868. +
  55869. + for_each_online_cpu(i) {
  55870. + pcpu = &per_cpu(cpuinfo, i);
  55871. + tunables = pcpu->policy->governor_data;
  55872. +
  55873. + if (pcpu->target_freq < tunables->hispeed_freq) {
  55874. + pcpu->target_freq = tunables->hispeed_freq;
  55875. + cpumask_set_cpu(i, &speedchange_cpumask);
  55876. + pcpu->hispeed_validate_time =
  55877. + ktime_to_us(ktime_get());
  55878. + anyboost = 1;
  55879. + }
  55880. +
  55881. + /*
  55882. + * Set floor freq and (re)start timer for when last
  55883. + * validated.
  55884. + */
  55885. +
  55886. + pcpu->floor_freq = tunables->hispeed_freq;
  55887. + pcpu->floor_validate_time = ktime_to_us(ktime_get());
  55888. + }
  55889. +
  55890. + spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
  55891. +
  55892. + if (anyboost)
  55893. + wake_up_process(speedchange_task);
  55894. +}
  55895. +
  55896. +static int cpufreq_interactive_notifier(
  55897. + struct notifier_block *nb, unsigned long val, void *data)
  55898. +{
  55899. + struct cpufreq_freqs *freq = data;
  55900. + struct cpufreq_interactive_cpuinfo *pcpu;
  55901. + int cpu;
  55902. + unsigned long flags;
  55903. +
  55904. + if (val == CPUFREQ_POSTCHANGE) {
  55905. + pcpu = &per_cpu(cpuinfo, freq->cpu);
  55906. + if (!down_read_trylock(&pcpu->enable_sem))
  55907. + return 0;
  55908. + if (!pcpu->governor_enabled) {
  55909. + up_read(&pcpu->enable_sem);
  55910. + return 0;
  55911. + }
  55912. +
  55913. + for_each_cpu(cpu, pcpu->policy->cpus) {
  55914. + struct cpufreq_interactive_cpuinfo *pjcpu =
  55915. + &per_cpu(cpuinfo, cpu);
  55916. + if (cpu != freq->cpu) {
  55917. + if (!down_read_trylock(&pjcpu->enable_sem))
  55918. + continue;
  55919. + if (!pjcpu->governor_enabled) {
  55920. + up_read(&pjcpu->enable_sem);
  55921. + continue;
  55922. + }
  55923. + }
  55924. + spin_lock_irqsave(&pjcpu->load_lock, flags);
  55925. + update_load(cpu);
  55926. + spin_unlock_irqrestore(&pjcpu->load_lock, flags);
  55927. + if (cpu != freq->cpu)
  55928. + up_read(&pjcpu->enable_sem);
  55929. + }
  55930. +
  55931. + up_read(&pcpu->enable_sem);
  55932. + }
  55933. + return 0;
  55934. +}
  55935. +
  55936. +static struct notifier_block cpufreq_notifier_block = {
  55937. + .notifier_call = cpufreq_interactive_notifier,
  55938. +};
  55939. +
  55940. +static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
  55941. +{
  55942. + const char *cp;
  55943. + int i;
  55944. + int ntokens = 1;
  55945. + unsigned int *tokenized_data;
  55946. + int err = -EINVAL;
  55947. +
  55948. + cp = buf;
  55949. + while ((cp = strpbrk(cp + 1, " :")))
  55950. + ntokens++;
  55951. +
  55952. + if (!(ntokens & 0x1))
  55953. + goto err;
  55954. +
  55955. + tokenized_data = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL);
  55956. + if (!tokenized_data) {
  55957. + err = -ENOMEM;
  55958. + goto err;
  55959. + }
  55960. +
  55961. + cp = buf;
  55962. + i = 0;
  55963. + while (i < ntokens) {
  55964. + if (sscanf(cp, "%u", &tokenized_data[i++]) != 1)
  55965. + goto err_kfree;
  55966. +
  55967. + cp = strpbrk(cp, " :");
  55968. + if (!cp)
  55969. + break;
  55970. + cp++;
  55971. + }
  55972. +
  55973. + if (i != ntokens)
  55974. + goto err_kfree;
  55975. +
  55976. + *num_tokens = ntokens;
  55977. + return tokenized_data;
  55978. +
  55979. +err_kfree:
  55980. + kfree(tokenized_data);
  55981. +err:
  55982. + return ERR_PTR(err);
  55983. +}
  55984. +
  55985. +static ssize_t show_target_loads(
  55986. + struct cpufreq_interactive_tunables *tunables,
  55987. + char *buf)
  55988. +{
  55989. + int i;
  55990. + ssize_t ret = 0;
  55991. + unsigned long flags;
  55992. +
  55993. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  55994. +
  55995. + for (i = 0; i < tunables->ntarget_loads; i++)
  55996. + ret += sprintf(buf + ret, "%u%s", tunables->target_loads[i],
  55997. + i & 0x1 ? ":" : " ");
  55998. +
  55999. + sprintf(buf + ret - 1, "\n");
  56000. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  56001. + return ret;
  56002. +}
  56003. +
  56004. +static ssize_t store_target_loads(
  56005. + struct cpufreq_interactive_tunables *tunables,
  56006. + const char *buf, size_t count)
  56007. +{
  56008. + int ntokens;
  56009. + unsigned int *new_target_loads = NULL;
  56010. + unsigned long flags;
  56011. +
  56012. + new_target_loads = get_tokenized_data(buf, &ntokens);
  56013. + if (IS_ERR(new_target_loads))
  56014. + return PTR_RET(new_target_loads);
  56015. +
  56016. + spin_lock_irqsave(&tunables->target_loads_lock, flags);
  56017. + if (tunables->target_loads != default_target_loads)
  56018. + kfree(tunables->target_loads);
  56019. + tunables->target_loads = new_target_loads;
  56020. + tunables->ntarget_loads = ntokens;
  56021. + spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
  56022. + return count;
  56023. +}
  56024. +
  56025. +static ssize_t show_above_hispeed_delay(
  56026. + struct cpufreq_interactive_tunables *tunables, char *buf)
  56027. +{
  56028. + int i;
  56029. + ssize_t ret = 0;
  56030. + unsigned long flags;
  56031. +
  56032. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  56033. +
  56034. + for (i = 0; i < tunables->nabove_hispeed_delay; i++)
  56035. + ret += sprintf(buf + ret, "%u%s",
  56036. + tunables->above_hispeed_delay[i],
  56037. + i & 0x1 ? ":" : " ");
  56038. +
  56039. + sprintf(buf + ret - 1, "\n");
  56040. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  56041. + return ret;
  56042. +}
  56043. +
  56044. +static ssize_t store_above_hispeed_delay(
  56045. + struct cpufreq_interactive_tunables *tunables,
  56046. + const char *buf, size_t count)
  56047. +{
  56048. + int ntokens;
  56049. + unsigned int *new_above_hispeed_delay = NULL;
  56050. + unsigned long flags;
  56051. +
  56052. + new_above_hispeed_delay = get_tokenized_data(buf, &ntokens);
  56053. + if (IS_ERR(new_above_hispeed_delay))
  56054. + return PTR_RET(new_above_hispeed_delay);
  56055. +
  56056. + spin_lock_irqsave(&tunables->above_hispeed_delay_lock, flags);
  56057. + if (tunables->above_hispeed_delay != default_above_hispeed_delay)
  56058. + kfree(tunables->above_hispeed_delay);
  56059. + tunables->above_hispeed_delay = new_above_hispeed_delay;
  56060. + tunables->nabove_hispeed_delay = ntokens;
  56061. + spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
  56062. + return count;
  56063. +
  56064. +}
  56065. +
  56066. +static ssize_t show_hispeed_freq(struct cpufreq_interactive_tunables *tunables,
  56067. + char *buf)
  56068. +{
  56069. + return sprintf(buf, "%u\n", tunables->hispeed_freq);
  56070. +}
  56071. +
  56072. +static ssize_t store_hispeed_freq(struct cpufreq_interactive_tunables *tunables,
  56073. + const char *buf, size_t count)
  56074. +{
  56075. + int ret;
  56076. + long unsigned int val;
  56077. +
  56078. + ret = strict_strtoul(buf, 0, &val);
  56079. + if (ret < 0)
  56080. + return ret;
  56081. + tunables->hispeed_freq = val;
  56082. + return count;
  56083. +}
  56084. +
  56085. +static ssize_t show_go_hispeed_load(struct cpufreq_interactive_tunables
  56086. + *tunables, char *buf)
  56087. +{
  56088. + return sprintf(buf, "%lu\n", tunables->go_hispeed_load);
  56089. +}
  56090. +
  56091. +static ssize_t store_go_hispeed_load(struct cpufreq_interactive_tunables
  56092. + *tunables, const char *buf, size_t count)
  56093. +{
  56094. + int ret;
  56095. + unsigned long val;
  56096. +
  56097. + ret = strict_strtoul(buf, 0, &val);
  56098. + if (ret < 0)
  56099. + return ret;
  56100. + tunables->go_hispeed_load = val;
  56101. + return count;
  56102. +}
  56103. +
  56104. +static ssize_t show_min_sample_time(struct cpufreq_interactive_tunables
  56105. + *tunables, char *buf)
  56106. +{
  56107. + return sprintf(buf, "%lu\n", tunables->min_sample_time);
  56108. +}
  56109. +
  56110. +static ssize_t store_min_sample_time(struct cpufreq_interactive_tunables
  56111. + *tunables, const char *buf, size_t count)
  56112. +{
  56113. + int ret;
  56114. + unsigned long val;
  56115. +
  56116. + ret = strict_strtoul(buf, 0, &val);
  56117. + if (ret < 0)
  56118. + return ret;
  56119. + tunables->min_sample_time = val;
  56120. + return count;
  56121. +}
  56122. +
  56123. +static ssize_t show_timer_rate(struct cpufreq_interactive_tunables *tunables,
  56124. + char *buf)
  56125. +{
  56126. + return sprintf(buf, "%lu\n", tunables->timer_rate);
  56127. +}
  56128. +
  56129. +static ssize_t store_timer_rate(struct cpufreq_interactive_tunables *tunables,
  56130. + const char *buf, size_t count)
  56131. +{
  56132. + int ret;
  56133. + unsigned long val;
  56134. +
  56135. + ret = strict_strtoul(buf, 0, &val);
  56136. + if (ret < 0)
  56137. + return ret;
  56138. + tunables->timer_rate = val;
  56139. + return count;
  56140. +}
  56141. +
  56142. +static ssize_t show_timer_slack(struct cpufreq_interactive_tunables *tunables,
  56143. + char *buf)
  56144. +{
  56145. + return sprintf(buf, "%d\n", tunables->timer_slack_val);
  56146. +}
  56147. +
  56148. +static ssize_t store_timer_slack(struct cpufreq_interactive_tunables *tunables,
  56149. + const char *buf, size_t count)
  56150. +{
  56151. + int ret;
  56152. + unsigned long val;
  56153. +
  56154. + ret = kstrtol(buf, 10, &val);
  56155. + if (ret < 0)
  56156. + return ret;
  56157. +
  56158. + tunables->timer_slack_val = val;
  56159. + return count;
  56160. +}
  56161. +
  56162. +static ssize_t show_boost(struct cpufreq_interactive_tunables *tunables,
  56163. + char *buf)
  56164. +{
  56165. + return sprintf(buf, "%d\n", tunables->boost_val);
  56166. +}
  56167. +
  56168. +static ssize_t store_boost(struct cpufreq_interactive_tunables *tunables,
  56169. + const char *buf, size_t count)
  56170. +{
  56171. + int ret;
  56172. + unsigned long val;
  56173. +
  56174. + ret = kstrtoul(buf, 0, &val);
  56175. + if (ret < 0)
  56176. + return ret;
  56177. +
  56178. + tunables->boost_val = val;
  56179. +
  56180. + if (tunables->boost_val) {
  56181. + trace_cpufreq_interactive_boost("on");
  56182. + cpufreq_interactive_boost();
  56183. + } else {
  56184. + trace_cpufreq_interactive_unboost("off");
  56185. + }
  56186. +
  56187. + return count;
  56188. +}
  56189. +
  56190. +static ssize_t store_boostpulse(struct cpufreq_interactive_tunables *tunables,
  56191. + const char *buf, size_t count)
  56192. +{
  56193. + int ret;
  56194. + unsigned long val;
  56195. +
  56196. + ret = kstrtoul(buf, 0, &val);
  56197. + if (ret < 0)
  56198. + return ret;
  56199. +
  56200. + tunables->boostpulse_endtime = ktime_to_us(ktime_get()) +
  56201. + tunables->boostpulse_duration_val;
  56202. + trace_cpufreq_interactive_boost("pulse");
  56203. + cpufreq_interactive_boost();
  56204. + return count;
  56205. +}
  56206. +
  56207. +static ssize_t show_boostpulse_duration(struct cpufreq_interactive_tunables
  56208. + *tunables, char *buf)
  56209. +{
  56210. + return sprintf(buf, "%d\n", tunables->boostpulse_duration_val);
  56211. +}
  56212. +
  56213. +static ssize_t store_boostpulse_duration(struct cpufreq_interactive_tunables
  56214. + *tunables, const char *buf, size_t count)
  56215. +{
  56216. + int ret;
  56217. + unsigned long val;
  56218. +
  56219. + ret = kstrtoul(buf, 0, &val);
  56220. + if (ret < 0)
  56221. + return ret;
  56222. +
  56223. + tunables->boostpulse_duration_val = val;
  56224. + return count;
  56225. +}
  56226. +
  56227. +static ssize_t show_io_is_busy(struct cpufreq_interactive_tunables *tunables,
  56228. + char *buf)
  56229. +{
  56230. + return sprintf(buf, "%u\n", tunables->io_is_busy);
  56231. +}
  56232. +
  56233. +static ssize_t store_io_is_busy(struct cpufreq_interactive_tunables *tunables,
  56234. + const char *buf, size_t count)
  56235. +{
  56236. + int ret;
  56237. + unsigned long val;
  56238. +
  56239. + ret = kstrtoul(buf, 0, &val);
  56240. + if (ret < 0)
  56241. + return ret;
  56242. + tunables->io_is_busy = val;
  56243. + return count;
  56244. +}
  56245. +
  56246. +/*
  56247. + * Create show/store routines
  56248. + * - sys: One governor instance for complete SYSTEM
  56249. + * - pol: One governor instance per struct cpufreq_policy
  56250. + */
  56251. +#define show_gov_pol_sys(file_name) \
  56252. +static ssize_t show_##file_name##_gov_sys \
  56253. +(struct kobject *kobj, struct attribute *attr, char *buf) \
  56254. +{ \
  56255. + return show_##file_name(common_tunables, buf); \
  56256. +} \
  56257. + \
  56258. +static ssize_t show_##file_name##_gov_pol \
  56259. +(struct cpufreq_policy *policy, char *buf) \
  56260. +{ \
  56261. + return show_##file_name(policy->governor_data, buf); \
  56262. +}
  56263. +
  56264. +#define store_gov_pol_sys(file_name) \
  56265. +static ssize_t store_##file_name##_gov_sys \
  56266. +(struct kobject *kobj, struct attribute *attr, const char *buf, \
  56267. + size_t count) \
  56268. +{ \
  56269. + return store_##file_name(common_tunables, buf, count); \
  56270. +} \
  56271. + \
  56272. +static ssize_t store_##file_name##_gov_pol \
  56273. +(struct cpufreq_policy *policy, const char *buf, size_t count) \
  56274. +{ \
  56275. + return store_##file_name(policy->governor_data, buf, count); \
  56276. +}
  56277. +
  56278. +#define show_store_gov_pol_sys(file_name) \
  56279. +show_gov_pol_sys(file_name); \
  56280. +store_gov_pol_sys(file_name)
  56281. +
  56282. +show_store_gov_pol_sys(target_loads);
  56283. +show_store_gov_pol_sys(above_hispeed_delay);
  56284. +show_store_gov_pol_sys(hispeed_freq);
  56285. +show_store_gov_pol_sys(go_hispeed_load);
  56286. +show_store_gov_pol_sys(min_sample_time);
  56287. +show_store_gov_pol_sys(timer_rate);
  56288. +show_store_gov_pol_sys(timer_slack);
  56289. +show_store_gov_pol_sys(boost);
  56290. +store_gov_pol_sys(boostpulse);
  56291. +show_store_gov_pol_sys(boostpulse_duration);
  56292. +show_store_gov_pol_sys(io_is_busy);
  56293. +
  56294. +#define gov_sys_attr_rw(_name) \
  56295. +static struct global_attr _name##_gov_sys = \
  56296. +__ATTR(_name, 0644, show_##_name##_gov_sys, store_##_name##_gov_sys)
  56297. +
  56298. +#define gov_pol_attr_rw(_name) \
  56299. +static struct freq_attr _name##_gov_pol = \
  56300. +__ATTR(_name, 0644, show_##_name##_gov_pol, store_##_name##_gov_pol)
  56301. +
  56302. +#define gov_sys_pol_attr_rw(_name) \
  56303. + gov_sys_attr_rw(_name); \
  56304. + gov_pol_attr_rw(_name)
  56305. +
  56306. +gov_sys_pol_attr_rw(target_loads);
  56307. +gov_sys_pol_attr_rw(above_hispeed_delay);
  56308. +gov_sys_pol_attr_rw(hispeed_freq);
  56309. +gov_sys_pol_attr_rw(go_hispeed_load);
  56310. +gov_sys_pol_attr_rw(min_sample_time);
  56311. +gov_sys_pol_attr_rw(timer_rate);
  56312. +gov_sys_pol_attr_rw(timer_slack);
  56313. +gov_sys_pol_attr_rw(boost);
  56314. +gov_sys_pol_attr_rw(boostpulse_duration);
  56315. +gov_sys_pol_attr_rw(io_is_busy);
  56316. +
  56317. +static struct global_attr boostpulse_gov_sys =
  56318. + __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_sys);
  56319. +
  56320. +static struct freq_attr boostpulse_gov_pol =
  56321. + __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_pol);
  56322. +
  56323. +/* One Governor instance for entire system */
  56324. +static struct attribute *interactive_attributes_gov_sys[] = {
  56325. + &target_loads_gov_sys.attr,
  56326. + &above_hispeed_delay_gov_sys.attr,
  56327. + &hispeed_freq_gov_sys.attr,
  56328. + &go_hispeed_load_gov_sys.attr,
  56329. + &min_sample_time_gov_sys.attr,
  56330. + &timer_rate_gov_sys.attr,
  56331. + &timer_slack_gov_sys.attr,
  56332. + &boost_gov_sys.attr,
  56333. + &boostpulse_gov_sys.attr,
  56334. + &boostpulse_duration_gov_sys.attr,
  56335. + &io_is_busy_gov_sys.attr,
  56336. + NULL,
  56337. +};
  56338. +
  56339. +static struct attribute_group interactive_attr_group_gov_sys = {
  56340. + .attrs = interactive_attributes_gov_sys,
  56341. + .name = "interactive",
  56342. +};
  56343. +
  56344. +/* Per policy governor instance */
  56345. +static struct attribute *interactive_attributes_gov_pol[] = {
  56346. + &target_loads_gov_pol.attr,
  56347. + &above_hispeed_delay_gov_pol.attr,
  56348. + &hispeed_freq_gov_pol.attr,
  56349. + &go_hispeed_load_gov_pol.attr,
  56350. + &min_sample_time_gov_pol.attr,
  56351. + &timer_rate_gov_pol.attr,
  56352. + &timer_slack_gov_pol.attr,
  56353. + &boost_gov_pol.attr,
  56354. + &boostpulse_gov_pol.attr,
  56355. + &boostpulse_duration_gov_pol.attr,
  56356. + &io_is_busy_gov_pol.attr,
  56357. + NULL,
  56358. +};
  56359. +
  56360. +static struct attribute_group interactive_attr_group_gov_pol = {
  56361. + .attrs = interactive_attributes_gov_pol,
  56362. + .name = "interactive",
  56363. +};
  56364. +
  56365. +static struct attribute_group *get_sysfs_attr(void)
  56366. +{
  56367. + if (have_governor_per_policy())
  56368. + return &interactive_attr_group_gov_pol;
  56369. + else
  56370. + return &interactive_attr_group_gov_sys;
  56371. +}
  56372. +
  56373. +static int cpufreq_interactive_idle_notifier(struct notifier_block *nb,
  56374. + unsigned long val,
  56375. + void *data)
  56376. +{
  56377. + switch (val) {
  56378. + case IDLE_START:
  56379. + cpufreq_interactive_idle_start();
  56380. + break;
  56381. + case IDLE_END:
  56382. + cpufreq_interactive_idle_end();
  56383. + break;
  56384. + }
  56385. +
  56386. + return 0;
  56387. +}
  56388. +
  56389. +static struct notifier_block cpufreq_interactive_idle_nb = {
  56390. + .notifier_call = cpufreq_interactive_idle_notifier,
  56391. +};
  56392. +
  56393. +static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
  56394. + unsigned int event)
  56395. +{
  56396. + int rc;
  56397. + unsigned int j;
  56398. + struct cpufreq_interactive_cpuinfo *pcpu;
  56399. + struct cpufreq_frequency_table *freq_table;
  56400. + struct cpufreq_interactive_tunables *tunables;
  56401. +
  56402. + if (have_governor_per_policy())
  56403. + tunables = policy->governor_data;
  56404. + else
  56405. + tunables = common_tunables;
  56406. +
  56407. + WARN_ON(!tunables && (event != CPUFREQ_GOV_POLICY_INIT));
  56408. +
  56409. + switch (event) {
  56410. + case CPUFREQ_GOV_POLICY_INIT:
  56411. + if (have_governor_per_policy()) {
  56412. + WARN_ON(tunables);
  56413. + } else if (tunables) {
  56414. + tunables->usage_count++;
  56415. + policy->governor_data = tunables;
  56416. + return 0;
  56417. + }
  56418. +
  56419. + tunables = kzalloc(sizeof(*tunables), GFP_KERNEL);
  56420. + if (!tunables) {
  56421. + pr_err("%s: POLICY_INIT: kzalloc failed\n", __func__);
  56422. + return -ENOMEM;
  56423. + }
  56424. +
  56425. + tunables->usage_count = 1;
  56426. + tunables->above_hispeed_delay = default_above_hispeed_delay;
  56427. + tunables->nabove_hispeed_delay =
  56428. + ARRAY_SIZE(default_above_hispeed_delay);
  56429. + tunables->go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
  56430. + tunables->target_loads = default_target_loads;
  56431. + tunables->ntarget_loads = ARRAY_SIZE(default_target_loads);
  56432. + tunables->min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
  56433. + tunables->timer_rate = DEFAULT_TIMER_RATE;
  56434. + tunables->boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME;
  56435. + tunables->timer_slack_val = DEFAULT_TIMER_SLACK;
  56436. +
  56437. + spin_lock_init(&tunables->target_loads_lock);
  56438. + spin_lock_init(&tunables->above_hispeed_delay_lock);
  56439. +
  56440. + policy->governor_data = tunables;
  56441. + if (!have_governor_per_policy()) {
  56442. + common_tunables = tunables;
  56443. + WARN_ON(cpufreq_get_global_kobject());
  56444. + }
  56445. +
  56446. + rc = sysfs_create_group(get_governor_parent_kobj(policy),
  56447. + get_sysfs_attr());
  56448. + if (rc) {
  56449. + kfree(tunables);
  56450. + policy->governor_data = NULL;
  56451. + if (!have_governor_per_policy())
  56452. + common_tunables = NULL;
  56453. + return rc;
  56454. + }
  56455. +
  56456. + if (!policy->governor->initialized) {
  56457. + idle_notifier_register(&cpufreq_interactive_idle_nb);
  56458. + cpufreq_register_notifier(&cpufreq_notifier_block,
  56459. + CPUFREQ_TRANSITION_NOTIFIER);
  56460. + }
  56461. +
  56462. + break;
  56463. +
  56464. + case CPUFREQ_GOV_POLICY_EXIT:
  56465. + if (!--tunables->usage_count) {
  56466. + sysfs_remove_group(get_governor_parent_kobj(policy),
  56467. + get_sysfs_attr());
  56468. +
  56469. + if (!have_governor_per_policy())
  56470. + cpufreq_put_global_kobject();
  56471. +
  56472. + if (policy->governor->initialized == 1) {
  56473. + cpufreq_unregister_notifier(&cpufreq_notifier_block,
  56474. + CPUFREQ_TRANSITION_NOTIFIER);
  56475. + idle_notifier_unregister(&cpufreq_interactive_idle_nb);
  56476. + }
  56477. +
  56478. + kfree(tunables);
  56479. + common_tunables = NULL;
  56480. + }
  56481. +
  56482. + policy->governor_data = NULL;
  56483. + break;
  56484. +
  56485. + case CPUFREQ_GOV_START:
  56486. + mutex_lock(&gov_lock);
  56487. +
  56488. + freq_table = cpufreq_frequency_get_table(policy->cpu);
  56489. + if (!tunables->hispeed_freq)
  56490. + tunables->hispeed_freq = policy->max;
  56491. +
  56492. + for_each_cpu(j, policy->cpus) {
  56493. + pcpu = &per_cpu(cpuinfo, j);
  56494. + pcpu->policy = policy;
  56495. + pcpu->target_freq = policy->cur;
  56496. + pcpu->freq_table = freq_table;
  56497. + pcpu->floor_freq = pcpu->target_freq;
  56498. + pcpu->floor_validate_time =
  56499. + ktime_to_us(ktime_get());
  56500. + pcpu->hispeed_validate_time =
  56501. + pcpu->floor_validate_time;
  56502. + down_write(&pcpu->enable_sem);
  56503. + del_timer_sync(&pcpu->cpu_timer);
  56504. + del_timer_sync(&pcpu->cpu_slack_timer);
  56505. + cpufreq_interactive_timer_start(tunables, j);
  56506. + pcpu->governor_enabled = 1;
  56507. + up_write(&pcpu->enable_sem);
  56508. + }
  56509. +
  56510. + mutex_unlock(&gov_lock);
  56511. + break;
  56512. +
  56513. + case CPUFREQ_GOV_STOP:
  56514. + mutex_lock(&gov_lock);
  56515. + for_each_cpu(j, policy->cpus) {
  56516. + pcpu = &per_cpu(cpuinfo, j);
  56517. + down_write(&pcpu->enable_sem);
  56518. + pcpu->governor_enabled = 0;
  56519. + del_timer_sync(&pcpu->cpu_timer);
  56520. + del_timer_sync(&pcpu->cpu_slack_timer);
  56521. + up_write(&pcpu->enable_sem);
  56522. + }
  56523. +
  56524. + mutex_unlock(&gov_lock);
  56525. + break;
  56526. +
  56527. + case CPUFREQ_GOV_LIMITS:
  56528. + if (policy->max < policy->cur)
  56529. + __cpufreq_driver_target(policy,
  56530. + policy->max, CPUFREQ_RELATION_H);
  56531. + else if (policy->min > policy->cur)
  56532. + __cpufreq_driver_target(policy,
  56533. + policy->min, CPUFREQ_RELATION_L);
  56534. + for_each_cpu(j, policy->cpus) {
  56535. + pcpu = &per_cpu(cpuinfo, j);
  56536. +
  56537. + /* hold write semaphore to avoid race */
  56538. + down_write(&pcpu->enable_sem);
  56539. + if (pcpu->governor_enabled == 0) {
  56540. + up_write(&pcpu->enable_sem);
  56541. + continue;
  56542. + }
  56543. +
  56544. + /* update target_freq firstly */
  56545. + if (policy->max < pcpu->target_freq)
  56546. + pcpu->target_freq = policy->max;
  56547. + else if (policy->min > pcpu->target_freq)
  56548. + pcpu->target_freq = policy->min;
  56549. +
  56550. + /* Reschedule timer.
  56551. + * Delete the timers, else the timer callback may
  56552. + * return without re-arm the timer when failed
  56553. + * acquire the semaphore. This race may cause timer
  56554. + * stopped unexpectedly.
  56555. + */
  56556. + del_timer_sync(&pcpu->cpu_timer);
  56557. + del_timer_sync(&pcpu->cpu_slack_timer);
  56558. + cpufreq_interactive_timer_start(tunables, j);
  56559. + up_write(&pcpu->enable_sem);
  56560. + }
  56561. + break;
  56562. + }
  56563. + return 0;
  56564. +}
  56565. +
  56566. +#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  56567. +static
  56568. +#endif
  56569. +struct cpufreq_governor cpufreq_gov_interactive = {
  56570. + .name = "interactive",
  56571. + .governor = cpufreq_governor_interactive,
  56572. + .max_transition_latency = 10000000,
  56573. + .owner = THIS_MODULE,
  56574. +};
  56575. +
  56576. +static void cpufreq_interactive_nop_timer(unsigned long data)
  56577. +{
  56578. +}
  56579. +
  56580. +static int __init cpufreq_interactive_init(void)
  56581. +{
  56582. + unsigned int i;
  56583. + struct cpufreq_interactive_cpuinfo *pcpu;
  56584. + struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
  56585. +
  56586. + /* Initalize per-cpu timers */
  56587. + for_each_possible_cpu(i) {
  56588. + pcpu = &per_cpu(cpuinfo, i);
  56589. + init_timer_deferrable(&pcpu->cpu_timer);
  56590. + pcpu->cpu_timer.function = cpufreq_interactive_timer;
  56591. + pcpu->cpu_timer.data = i;
  56592. + init_timer(&pcpu->cpu_slack_timer);
  56593. + pcpu->cpu_slack_timer.function = cpufreq_interactive_nop_timer;
  56594. + spin_lock_init(&pcpu->load_lock);
  56595. + init_rwsem(&pcpu->enable_sem);
  56596. + }
  56597. +
  56598. + spin_lock_init(&speedchange_cpumask_lock);
  56599. + mutex_init(&gov_lock);
  56600. + speedchange_task =
  56601. + kthread_create(cpufreq_interactive_speedchange_task, NULL,
  56602. + "cfinteractive");
  56603. + if (IS_ERR(speedchange_task))
  56604. + return PTR_ERR(speedchange_task);
  56605. +
  56606. + sched_setscheduler_nocheck(speedchange_task, SCHED_FIFO, &param);
  56607. + get_task_struct(speedchange_task);
  56608. +
  56609. + /* NB: wake up so the thread does not look hung to the freezer */
  56610. + wake_up_process(speedchange_task);
  56611. +
  56612. + return cpufreq_register_governor(&cpufreq_gov_interactive);
  56613. +}
  56614. +
  56615. +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  56616. +fs_initcall(cpufreq_interactive_init);
  56617. +#else
  56618. +module_init(cpufreq_interactive_init);
  56619. +#endif
  56620. +
  56621. +static void __exit cpufreq_interactive_exit(void)
  56622. +{
  56623. + cpufreq_unregister_governor(&cpufreq_gov_interactive);
  56624. + kthread_stop(speedchange_task);
  56625. + put_task_struct(speedchange_task);
  56626. +}
  56627. +
  56628. +module_exit(cpufreq_interactive_exit);
  56629. +
  56630. +MODULE_AUTHOR("Mike Chan <mike@android.com>");
  56631. +MODULE_DESCRIPTION("'cpufreq_interactive' - A cpufreq governor for "
  56632. + "Latency sensitive workloads");
  56633. +MODULE_LICENSE("GPL");
  56634. diff -Nur linux-3.14.17/drivers/cpufreq/highbank-cpufreq.c linux-imx6-3.14/drivers/cpufreq/highbank-cpufreq.c
  56635. --- linux-3.14.17/drivers/cpufreq/highbank-cpufreq.c 2014-08-14 03:38:34.000000000 +0200
  56636. +++ linux-imx6-3.14/drivers/cpufreq/highbank-cpufreq.c 2014-09-11 18:06:00.006030002 +0200
  56637. @@ -19,7 +19,7 @@
  56638. #include <linux/cpu.h>
  56639. #include <linux/err.h>
  56640. #include <linux/of.h>
  56641. -#include <linux/mailbox.h>
  56642. +#include <linux/pl320-ipc.h>
  56643. #include <linux/platform_device.h>
  56644. #define HB_CPUFREQ_CHANGE_NOTE 0x80000001
  56645. diff -Nur linux-3.14.17/drivers/cpufreq/imx6-cpufreq.c linux-imx6-3.14/drivers/cpufreq/imx6-cpufreq.c
  56646. --- linux-3.14.17/drivers/cpufreq/imx6-cpufreq.c 1970-01-01 01:00:00.000000000 +0100
  56647. +++ linux-imx6-3.14/drivers/cpufreq/imx6-cpufreq.c 2014-09-11 18:06:00.006030002 +0200
  56648. @@ -0,0 +1,393 @@
  56649. +/*
  56650. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  56651. + *
  56652. + * This program is free software; you can redistribute it and/or modify
  56653. + * it under the terms of the GNU General Public License version 2 as
  56654. + * published by the Free Software Foundation.
  56655. + */
  56656. +
  56657. +#include <linux/busfreq-imx6.h>
  56658. +#include <linux/clk.h>
  56659. +#include <linux/cpu.h>
  56660. +#include <linux/cpufreq.h>
  56661. +#include <linux/delay.h>
  56662. +#include <linux/err.h>
  56663. +#include <linux/module.h>
  56664. +#include <linux/of.h>
  56665. +#include <linux/pm_opp.h>
  56666. +#include <linux/platform_device.h>
  56667. +#include <linux/regulator/consumer.h>
  56668. +#include <linux/suspend.h>
  56669. +
  56670. +#define PU_SOC_VOLTAGE_NORMAL 1250000
  56671. +#define PU_SOC_VOLTAGE_HIGH 1275000
  56672. +#define FREQ_1P2_GHZ 1200000000
  56673. +
  56674. +static struct regulator *arm_reg;
  56675. +static struct regulator *pu_reg;
  56676. +static struct regulator *soc_reg;
  56677. +
  56678. +static struct clk *arm_clk;
  56679. +static struct clk *pll1_sys_clk;
  56680. +static struct clk *pll1_sw_clk;
  56681. +static struct clk *step_clk;
  56682. +static struct clk *pll2_pfd2_396m_clk;
  56683. +
  56684. +static struct device *cpu_dev;
  56685. +static struct cpufreq_frequency_table *freq_table;
  56686. +static unsigned int transition_latency;
  56687. +static struct mutex set_cpufreq_lock;
  56688. +
  56689. +static u32 *imx6_soc_volt;
  56690. +static u32 soc_opp_count;
  56691. +
  56692. +static int imx6_set_target(struct cpufreq_policy *policy, unsigned int index)
  56693. +{
  56694. + struct dev_pm_opp *opp;
  56695. + unsigned long freq_hz, volt, volt_old;
  56696. + unsigned int old_freq, new_freq;
  56697. + int ret;
  56698. +
  56699. + mutex_lock(&set_cpufreq_lock);
  56700. +
  56701. + new_freq = freq_table[index].frequency;
  56702. + freq_hz = new_freq * 1000;
  56703. + old_freq = clk_get_rate(arm_clk) / 1000;
  56704. +
  56705. + rcu_read_lock();
  56706. + opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  56707. + if (IS_ERR(opp)) {
  56708. + rcu_read_unlock();
  56709. + dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
  56710. + ret = PTR_ERR(opp);
  56711. + goto unlock;
  56712. + }
  56713. +
  56714. + volt = dev_pm_opp_get_voltage(opp);
  56715. + rcu_read_unlock();
  56716. + volt_old = regulator_get_voltage(arm_reg);
  56717. +
  56718. + dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
  56719. + old_freq / 1000, volt_old / 1000,
  56720. + new_freq / 1000, volt / 1000);
  56721. +
  56722. + /*
  56723. + * CPU freq is increasing, so need to ensure
  56724. + * that bus frequency is increased too.
  56725. + */
  56726. + if (old_freq == freq_table[0].frequency)
  56727. + request_bus_freq(BUS_FREQ_HIGH);
  56728. +
  56729. + /* scaling up? scale voltage before frequency */
  56730. + if (new_freq > old_freq) {
  56731. + if (regulator_is_enabled(pu_reg)) {
  56732. + ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  56733. + if (ret) {
  56734. + dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
  56735. + goto unlock;
  56736. + }
  56737. + }
  56738. + ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  56739. + if (ret) {
  56740. + dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
  56741. + goto unlock;
  56742. + }
  56743. + ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  56744. + if (ret) {
  56745. + dev_err(cpu_dev,
  56746. + "failed to scale vddarm up: %d\n", ret);
  56747. + goto unlock;
  56748. + }
  56749. + }
  56750. +
  56751. + /*
  56752. + * The setpoints are selected per PLL/PDF frequencies, so we need to
  56753. + * reprogram PLL for frequency scaling. The procedure of reprogramming
  56754. + * PLL1 is as below.
  56755. + *
  56756. + * - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
  56757. + * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
  56758. + * - Disable pll2_pfd2_396m_clk
  56759. + */
  56760. + clk_set_parent(step_clk, pll2_pfd2_396m_clk);
  56761. + clk_set_parent(pll1_sw_clk, step_clk);
  56762. + if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
  56763. + clk_set_rate(pll1_sys_clk, new_freq * 1000);
  56764. + clk_set_parent(pll1_sw_clk, pll1_sys_clk);
  56765. + }
  56766. +
  56767. + /* Ensure the arm clock divider is what we expect */
  56768. + ret = clk_set_rate(arm_clk, new_freq * 1000);
  56769. + if (ret) {
  56770. + dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
  56771. + regulator_set_voltage_tol(arm_reg, volt_old, 0);
  56772. + goto unlock;
  56773. + }
  56774. +
  56775. + /* scaling down? scale voltage after frequency */
  56776. + if (new_freq < old_freq) {
  56777. + ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  56778. + if (ret) {
  56779. + dev_warn(cpu_dev,
  56780. + "failed to scale vddarm down: %d\n", ret);
  56781. + ret = 0;
  56782. + }
  56783. + ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  56784. + if (ret) {
  56785. + dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
  56786. + ret = 0;
  56787. + }
  56788. + if (regulator_is_enabled(pu_reg)) {
  56789. + ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  56790. + if (ret) {
  56791. + dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
  56792. + ret = 0;
  56793. + }
  56794. + }
  56795. + }
  56796. +
  56797. + if (policy->cur == freq_table[0].frequency)
  56798. + release_bus_freq(BUS_FREQ_HIGH);
  56799. +
  56800. +unlock:
  56801. + mutex_unlock(&set_cpufreq_lock);
  56802. + return ret;
  56803. +}
  56804. +
  56805. +static int imx6_cpufreq_init(struct cpufreq_policy *policy)
  56806. +{
  56807. + policy->clk = arm_clk;
  56808. +
  56809. + if (policy->cur > freq_table[0].frequency)
  56810. + request_bus_freq(BUS_FREQ_HIGH);
  56811. +
  56812. + return cpufreq_generic_init(policy, freq_table, transition_latency);
  56813. +}
  56814. +
  56815. +static struct cpufreq_driver imx6_cpufreq_driver = {
  56816. + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
  56817. + .verify = cpufreq_generic_frequency_table_verify,
  56818. + .target_index = imx6_set_target,
  56819. + .get = cpufreq_generic_get,
  56820. + .init = imx6_cpufreq_init,
  56821. + .exit = cpufreq_generic_exit,
  56822. + .name = "imx6-cpufreq",
  56823. + .attr = cpufreq_generic_attr,
  56824. +};
  56825. +
  56826. +static int imx6_cpufreq_pm_notify(struct notifier_block *nb,
  56827. + unsigned long event, void *dummy)
  56828. +{
  56829. + struct cpufreq_policy *data = cpufreq_cpu_get(0);
  56830. + static u32 cpufreq_policy_min_pre_suspend;
  56831. +
  56832. + /*
  56833. + * During suspend/resume, When cpufreq driver try to increase
  56834. + * voltage/freq, it needs to control I2C/SPI to communicate
  56835. + * with external PMIC to adjust voltage, but these I2C/SPI
  56836. + * devices may be already suspended, to avoid such scenario,
  56837. + * we just increase cpufreq to highest setpoint before suspend.
  56838. + */
  56839. + switch (event) {
  56840. + case PM_SUSPEND_PREPARE:
  56841. + cpufreq_policy_min_pre_suspend = data->user_policy.min;
  56842. + data->user_policy.min = data->user_policy.max;
  56843. + break;
  56844. + case PM_POST_SUSPEND:
  56845. + data->user_policy.min = cpufreq_policy_min_pre_suspend;
  56846. + break;
  56847. + default:
  56848. + break;
  56849. + }
  56850. +
  56851. + cpufreq_update_policy(0);
  56852. +
  56853. + return NOTIFY_OK;
  56854. +}
  56855. +
  56856. +static struct notifier_block imx6_cpufreq_pm_notifier = {
  56857. + .notifier_call = imx6_cpufreq_pm_notify,
  56858. +};
  56859. +
  56860. +static int imx6_cpufreq_probe(struct platform_device *pdev)
  56861. +{
  56862. + struct device_node *np;
  56863. + struct dev_pm_opp *opp;
  56864. + unsigned long min_volt, max_volt;
  56865. + int num, ret;
  56866. + const struct property *prop;
  56867. + const __be32 *val;
  56868. + u32 nr, i, j;
  56869. +
  56870. + cpu_dev = get_cpu_device(0);
  56871. + if (!cpu_dev) {
  56872. + pr_err("failed to get cpu0 device\n");
  56873. + return -ENODEV;
  56874. + }
  56875. +
  56876. + np = of_node_get(cpu_dev->of_node);
  56877. + if (!np) {
  56878. + dev_err(cpu_dev, "failed to find cpu0 node\n");
  56879. + return -ENOENT;
  56880. + }
  56881. +
  56882. + arm_clk = devm_clk_get(cpu_dev, "arm");
  56883. + pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
  56884. + pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
  56885. + step_clk = devm_clk_get(cpu_dev, "step");
  56886. + pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
  56887. + if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
  56888. + IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
  56889. + dev_err(cpu_dev, "failed to get clocks\n");
  56890. + ret = -ENOENT;
  56891. + goto put_node;
  56892. + }
  56893. +
  56894. + arm_reg = devm_regulator_get(cpu_dev, "arm");
  56895. + pu_reg = devm_regulator_get(cpu_dev, "pu");
  56896. + soc_reg = devm_regulator_get(cpu_dev, "soc");
  56897. + if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
  56898. + dev_err(cpu_dev, "failed to get regulators\n");
  56899. + ret = -ENOENT;
  56900. + goto put_node;
  56901. + }
  56902. +
  56903. + /*
  56904. + * We expect an OPP table supplied by platform.
  56905. + * Just, incase the platform did not supply the OPP
  56906. + * table, it will try to get it.
  56907. + */
  56908. + num = dev_pm_opp_get_opp_count(cpu_dev);
  56909. + if (num < 0) {
  56910. + ret = of_init_opp_table(cpu_dev);
  56911. + if (ret < 0) {
  56912. + dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
  56913. + goto put_node;
  56914. + }
  56915. +
  56916. + num = dev_pm_opp_get_opp_count(cpu_dev);
  56917. + if (num < 0) {
  56918. + ret = num;
  56919. + dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
  56920. + goto put_node;
  56921. + }
  56922. + }
  56923. +
  56924. + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
  56925. + if (ret) {
  56926. + dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
  56927. + goto put_node;
  56928. + }
  56929. +
  56930. + /* Make imx6_soc_volt array's size same as arm opp number */
  56931. + imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
  56932. + if (imx6_soc_volt == NULL) {
  56933. + ret = -ENOMEM;
  56934. + goto free_freq_table;
  56935. + }
  56936. +
  56937. + prop = of_find_property(np, "fsl,soc-operating-points", NULL);
  56938. + if (!prop || !prop->value)
  56939. + goto soc_opp_out;
  56940. +
  56941. + /*
  56942. + * Each OPP is a set of tuples consisting of frequency and
  56943. + * voltage like <freq-kHz vol-uV>.
  56944. + */
  56945. + nr = prop->length / sizeof(u32);
  56946. + if (nr % 2 || (nr / 2) < num)
  56947. + goto soc_opp_out;
  56948. +
  56949. + for (j = 0; j < num; j++) {
  56950. + val = prop->value;
  56951. + for (i = 0; i < nr / 2; i++) {
  56952. + unsigned long freq = be32_to_cpup(val++);
  56953. + unsigned long volt = be32_to_cpup(val++);
  56954. + if (freq_table[j].frequency == freq) {
  56955. + imx6_soc_volt[soc_opp_count++] = volt;
  56956. + break;
  56957. + }
  56958. + }
  56959. + }
  56960. +
  56961. +soc_opp_out:
  56962. + /* use fixed soc opp volt if no valid soc opp info found in dtb */
  56963. + if (soc_opp_count != num) {
  56964. + dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
  56965. + for (j = 0; j < num; j++)
  56966. + imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
  56967. + if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
  56968. + imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
  56969. + }
  56970. +
  56971. + if (of_property_read_u32(np, "clock-latency", &transition_latency))
  56972. + transition_latency = CPUFREQ_ETERNAL;
  56973. +
  56974. + /*
  56975. + * Calculate the ramp time for max voltage change in the
  56976. + * VDDSOC and VDDPU regulators.
  56977. + */
  56978. + ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  56979. + if (ret > 0)
  56980. + transition_latency += ret * 1000;
  56981. + ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  56982. + if (ret > 0)
  56983. + transition_latency += ret * 1000;
  56984. +
  56985. + /*
  56986. + * OPP is maintained in order of increasing frequency, and
  56987. + * freq_table initialised from OPP is therefore sorted in the
  56988. + * same order.
  56989. + */
  56990. + rcu_read_lock();
  56991. + opp = dev_pm_opp_find_freq_exact(cpu_dev,
  56992. + freq_table[0].frequency * 1000, true);
  56993. + min_volt = dev_pm_opp_get_voltage(opp);
  56994. + opp = dev_pm_opp_find_freq_exact(cpu_dev,
  56995. + freq_table[--num].frequency * 1000, true);
  56996. + max_volt = dev_pm_opp_get_voltage(opp);
  56997. + rcu_read_unlock();
  56998. + ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
  56999. + if (ret > 0)
  57000. + transition_latency += ret * 1000;
  57001. +
  57002. + mutex_init(&set_cpufreq_lock);
  57003. + register_pm_notifier(&imx6_cpufreq_pm_notifier);
  57004. +
  57005. + ret = cpufreq_register_driver(&imx6_cpufreq_driver);
  57006. + if (ret) {
  57007. + dev_err(cpu_dev, "failed register driver: %d\n", ret);
  57008. + goto free_freq_table;
  57009. + }
  57010. +
  57011. + of_node_put(np);
  57012. + return 0;
  57013. +
  57014. +free_freq_table:
  57015. + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  57016. +put_node:
  57017. + of_node_put(np);
  57018. + return ret;
  57019. +}
  57020. +
  57021. +static int imx6_cpufreq_remove(struct platform_device *pdev)
  57022. +{
  57023. + cpufreq_unregister_driver(&imx6_cpufreq_driver);
  57024. + dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  57025. +
  57026. + return 0;
  57027. +}
  57028. +
  57029. +static struct platform_driver imx6_cpufreq_platdrv = {
  57030. + .driver = {
  57031. + .name = "imx6-cpufreq",
  57032. + .owner = THIS_MODULE,
  57033. + },
  57034. + .probe = imx6_cpufreq_probe,
  57035. + .remove = imx6_cpufreq_remove,
  57036. +};
  57037. +module_platform_driver(imx6_cpufreq_platdrv);
  57038. +
  57039. +MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
  57040. +MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
  57041. +MODULE_LICENSE("GPL");
  57042. diff -Nur linux-3.14.17/drivers/cpufreq/imx6q-cpufreq.c linux-imx6-3.14/drivers/cpufreq/imx6q-cpufreq.c
  57043. --- linux-3.14.17/drivers/cpufreq/imx6q-cpufreq.c 2014-08-14 03:38:34.000000000 +0200
  57044. +++ linux-imx6-3.14/drivers/cpufreq/imx6q-cpufreq.c 1970-01-01 01:00:00.000000000 +0100
  57045. @@ -1,330 +0,0 @@
  57046. -/*
  57047. - * Copyright (C) 2013 Freescale Semiconductor, Inc.
  57048. - *
  57049. - * This program is free software; you can redistribute it and/or modify
  57050. - * it under the terms of the GNU General Public License version 2 as
  57051. - * published by the Free Software Foundation.
  57052. - */
  57053. -
  57054. -#include <linux/clk.h>
  57055. -#include <linux/cpu.h>
  57056. -#include <linux/cpufreq.h>
  57057. -#include <linux/delay.h>
  57058. -#include <linux/err.h>
  57059. -#include <linux/module.h>
  57060. -#include <linux/of.h>
  57061. -#include <linux/pm_opp.h>
  57062. -#include <linux/platform_device.h>
  57063. -#include <linux/regulator/consumer.h>
  57064. -
  57065. -#define PU_SOC_VOLTAGE_NORMAL 1250000
  57066. -#define PU_SOC_VOLTAGE_HIGH 1275000
  57067. -#define FREQ_1P2_GHZ 1200000000
  57068. -
  57069. -static struct regulator *arm_reg;
  57070. -static struct regulator *pu_reg;
  57071. -static struct regulator *soc_reg;
  57072. -
  57073. -static struct clk *arm_clk;
  57074. -static struct clk *pll1_sys_clk;
  57075. -static struct clk *pll1_sw_clk;
  57076. -static struct clk *step_clk;
  57077. -static struct clk *pll2_pfd2_396m_clk;
  57078. -
  57079. -static struct device *cpu_dev;
  57080. -static struct cpufreq_frequency_table *freq_table;
  57081. -static unsigned int transition_latency;
  57082. -
  57083. -static u32 *imx6_soc_volt;
  57084. -static u32 soc_opp_count;
  57085. -
  57086. -static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
  57087. -{
  57088. - struct dev_pm_opp *opp;
  57089. - unsigned long freq_hz, volt, volt_old;
  57090. - unsigned int old_freq, new_freq;
  57091. - int ret;
  57092. -
  57093. - new_freq = freq_table[index].frequency;
  57094. - freq_hz = new_freq * 1000;
  57095. - old_freq = clk_get_rate(arm_clk) / 1000;
  57096. -
  57097. - rcu_read_lock();
  57098. - opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  57099. - if (IS_ERR(opp)) {
  57100. - rcu_read_unlock();
  57101. - dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
  57102. - return PTR_ERR(opp);
  57103. - }
  57104. -
  57105. - volt = dev_pm_opp_get_voltage(opp);
  57106. - rcu_read_unlock();
  57107. - volt_old = regulator_get_voltage(arm_reg);
  57108. -
  57109. - dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
  57110. - old_freq / 1000, volt_old / 1000,
  57111. - new_freq / 1000, volt / 1000);
  57112. -
  57113. - /* scaling up? scale voltage before frequency */
  57114. - if (new_freq > old_freq) {
  57115. - ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  57116. - if (ret) {
  57117. - dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
  57118. - return ret;
  57119. - }
  57120. - ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  57121. - if (ret) {
  57122. - dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
  57123. - return ret;
  57124. - }
  57125. - ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  57126. - if (ret) {
  57127. - dev_err(cpu_dev,
  57128. - "failed to scale vddarm up: %d\n", ret);
  57129. - return ret;
  57130. - }
  57131. - }
  57132. -
  57133. - /*
  57134. - * The setpoints are selected per PLL/PDF frequencies, so we need to
  57135. - * reprogram PLL for frequency scaling. The procedure of reprogramming
  57136. - * PLL1 is as below.
  57137. - *
  57138. - * - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
  57139. - * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it
  57140. - * - Disable pll2_pfd2_396m_clk
  57141. - */
  57142. - clk_set_parent(step_clk, pll2_pfd2_396m_clk);
  57143. - clk_set_parent(pll1_sw_clk, step_clk);
  57144. - if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
  57145. - clk_set_rate(pll1_sys_clk, new_freq * 1000);
  57146. - clk_set_parent(pll1_sw_clk, pll1_sys_clk);
  57147. - }
  57148. -
  57149. - /* Ensure the arm clock divider is what we expect */
  57150. - ret = clk_set_rate(arm_clk, new_freq * 1000);
  57151. - if (ret) {
  57152. - dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
  57153. - regulator_set_voltage_tol(arm_reg, volt_old, 0);
  57154. - return ret;
  57155. - }
  57156. -
  57157. - /* scaling down? scale voltage after frequency */
  57158. - if (new_freq < old_freq) {
  57159. - ret = regulator_set_voltage_tol(arm_reg, volt, 0);
  57160. - if (ret) {
  57161. - dev_warn(cpu_dev,
  57162. - "failed to scale vddarm down: %d\n", ret);
  57163. - ret = 0;
  57164. - }
  57165. - ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
  57166. - if (ret) {
  57167. - dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
  57168. - ret = 0;
  57169. - }
  57170. - ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
  57171. - if (ret) {
  57172. - dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
  57173. - ret = 0;
  57174. - }
  57175. - }
  57176. -
  57177. - return 0;
  57178. -}
  57179. -
  57180. -static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
  57181. -{
  57182. - policy->clk = arm_clk;
  57183. - return cpufreq_generic_init(policy, freq_table, transition_latency);
  57184. -}
  57185. -
  57186. -static struct cpufreq_driver imx6q_cpufreq_driver = {
  57187. - .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
  57188. - .verify = cpufreq_generic_frequency_table_verify,
  57189. - .target_index = imx6q_set_target,
  57190. - .get = cpufreq_generic_get,
  57191. - .init = imx6q_cpufreq_init,
  57192. - .exit = cpufreq_generic_exit,
  57193. - .name = "imx6q-cpufreq",
  57194. - .attr = cpufreq_generic_attr,
  57195. -};
  57196. -
  57197. -static int imx6q_cpufreq_probe(struct platform_device *pdev)
  57198. -{
  57199. - struct device_node *np;
  57200. - struct dev_pm_opp *opp;
  57201. - unsigned long min_volt, max_volt;
  57202. - int num, ret;
  57203. - const struct property *prop;
  57204. - const __be32 *val;
  57205. - u32 nr, i, j;
  57206. -
  57207. - cpu_dev = get_cpu_device(0);
  57208. - if (!cpu_dev) {
  57209. - pr_err("failed to get cpu0 device\n");
  57210. - return -ENODEV;
  57211. - }
  57212. -
  57213. - np = of_node_get(cpu_dev->of_node);
  57214. - if (!np) {
  57215. - dev_err(cpu_dev, "failed to find cpu0 node\n");
  57216. - return -ENOENT;
  57217. - }
  57218. -
  57219. - arm_clk = devm_clk_get(cpu_dev, "arm");
  57220. - pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
  57221. - pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
  57222. - step_clk = devm_clk_get(cpu_dev, "step");
  57223. - pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
  57224. - if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
  57225. - IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
  57226. - dev_err(cpu_dev, "failed to get clocks\n");
  57227. - ret = -ENOENT;
  57228. - goto put_node;
  57229. - }
  57230. -
  57231. - arm_reg = devm_regulator_get(cpu_dev, "arm");
  57232. - pu_reg = devm_regulator_get(cpu_dev, "pu");
  57233. - soc_reg = devm_regulator_get(cpu_dev, "soc");
  57234. - if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
  57235. - dev_err(cpu_dev, "failed to get regulators\n");
  57236. - ret = -ENOENT;
  57237. - goto put_node;
  57238. - }
  57239. -
  57240. - /*
  57241. - * We expect an OPP table supplied by platform.
  57242. - * Just, incase the platform did not supply the OPP
  57243. - * table, it will try to get it.
  57244. - */
  57245. - num = dev_pm_opp_get_opp_count(cpu_dev);
  57246. - if (num < 0) {
  57247. - ret = of_init_opp_table(cpu_dev);
  57248. - if (ret < 0) {
  57249. - dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
  57250. - goto put_node;
  57251. - }
  57252. -
  57253. - num = dev_pm_opp_get_opp_count(cpu_dev);
  57254. - if (num < 0) {
  57255. - ret = num;
  57256. - dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
  57257. - goto put_node;
  57258. - }
  57259. - }
  57260. -
  57261. - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
  57262. - if (ret) {
  57263. - dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
  57264. - goto put_node;
  57265. - }
  57266. -
  57267. - /* Make imx6_soc_volt array's size same as arm opp number */
  57268. - imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
  57269. - if (imx6_soc_volt == NULL) {
  57270. - ret = -ENOMEM;
  57271. - goto free_freq_table;
  57272. - }
  57273. -
  57274. - prop = of_find_property(np, "fsl,soc-operating-points", NULL);
  57275. - if (!prop || !prop->value)
  57276. - goto soc_opp_out;
  57277. -
  57278. - /*
  57279. - * Each OPP is a set of tuples consisting of frequency and
  57280. - * voltage like <freq-kHz vol-uV>.
  57281. - */
  57282. - nr = prop->length / sizeof(u32);
  57283. - if (nr % 2 || (nr / 2) < num)
  57284. - goto soc_opp_out;
  57285. -
  57286. - for (j = 0; j < num; j++) {
  57287. - val = prop->value;
  57288. - for (i = 0; i < nr / 2; i++) {
  57289. - unsigned long freq = be32_to_cpup(val++);
  57290. - unsigned long volt = be32_to_cpup(val++);
  57291. - if (freq_table[j].frequency == freq) {
  57292. - imx6_soc_volt[soc_opp_count++] = volt;
  57293. - break;
  57294. - }
  57295. - }
  57296. - }
  57297. -
  57298. -soc_opp_out:
  57299. - /* use fixed soc opp volt if no valid soc opp info found in dtb */
  57300. - if (soc_opp_count != num) {
  57301. - dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
  57302. - for (j = 0; j < num; j++)
  57303. - imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
  57304. - if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
  57305. - imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
  57306. - }
  57307. -
  57308. - if (of_property_read_u32(np, "clock-latency", &transition_latency))
  57309. - transition_latency = CPUFREQ_ETERNAL;
  57310. -
  57311. - /*
  57312. - * Calculate the ramp time for max voltage change in the
  57313. - * VDDSOC and VDDPU regulators.
  57314. - */
  57315. - ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  57316. - if (ret > 0)
  57317. - transition_latency += ret * 1000;
  57318. - ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
  57319. - if (ret > 0)
  57320. - transition_latency += ret * 1000;
  57321. -
  57322. - /*
  57323. - * OPP is maintained in order of increasing frequency, and
  57324. - * freq_table initialised from OPP is therefore sorted in the
  57325. - * same order.
  57326. - */
  57327. - rcu_read_lock();
  57328. - opp = dev_pm_opp_find_freq_exact(cpu_dev,
  57329. - freq_table[0].frequency * 1000, true);
  57330. - min_volt = dev_pm_opp_get_voltage(opp);
  57331. - opp = dev_pm_opp_find_freq_exact(cpu_dev,
  57332. - freq_table[--num].frequency * 1000, true);
  57333. - max_volt = dev_pm_opp_get_voltage(opp);
  57334. - rcu_read_unlock();
  57335. - ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt);
  57336. - if (ret > 0)
  57337. - transition_latency += ret * 1000;
  57338. -
  57339. - ret = cpufreq_register_driver(&imx6q_cpufreq_driver);
  57340. - if (ret) {
  57341. - dev_err(cpu_dev, "failed register driver: %d\n", ret);
  57342. - goto free_freq_table;
  57343. - }
  57344. -
  57345. - of_node_put(np);
  57346. - return 0;
  57347. -
  57348. -free_freq_table:
  57349. - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  57350. -put_node:
  57351. - of_node_put(np);
  57352. - return ret;
  57353. -}
  57354. -
  57355. -static int imx6q_cpufreq_remove(struct platform_device *pdev)
  57356. -{
  57357. - cpufreq_unregister_driver(&imx6q_cpufreq_driver);
  57358. - dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
  57359. -
  57360. - return 0;
  57361. -}
  57362. -
  57363. -static struct platform_driver imx6q_cpufreq_platdrv = {
  57364. - .driver = {
  57365. - .name = "imx6q-cpufreq",
  57366. - .owner = THIS_MODULE,
  57367. - },
  57368. - .probe = imx6q_cpufreq_probe,
  57369. - .remove = imx6q_cpufreq_remove,
  57370. -};
  57371. -module_platform_driver(imx6q_cpufreq_platdrv);
  57372. -
  57373. -MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
  57374. -MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
  57375. -MODULE_LICENSE("GPL");
  57376. diff -Nur linux-3.14.17/drivers/cpufreq/Kconfig linux-imx6-3.14/drivers/cpufreq/Kconfig
  57377. --- linux-3.14.17/drivers/cpufreq/Kconfig 2014-08-14 03:38:34.000000000 +0200
  57378. +++ linux-imx6-3.14/drivers/cpufreq/Kconfig 2014-09-11 18:05:59.970029858 +0200
  57379. @@ -91,6 +91,15 @@
  57380. governor. If unsure have a look at the help section of the
  57381. driver. Fallback governor will be the performance governor.
  57382. +config CPU_FREQ_DEFAULT_GOV_INTERACTIVE
  57383. + bool "interactive"
  57384. + select CPU_FREQ_GOV_INTERACTIVE
  57385. + help
  57386. + Use the CPUFreq governor 'interactive' as default. This allows
  57387. + you to get a full dynamic cpu frequency capable system by simply
  57388. + loading your cpufreq low-level hardware driver, using the
  57389. + 'interactive' governor for latency-sensitive workloads.
  57390. +
  57391. config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
  57392. bool "conservative"
  57393. select CPU_FREQ_GOV_CONSERVATIVE
  57394. @@ -157,6 +166,24 @@
  57395. For details, take a look at linux/Documentation/cpu-freq.
  57396. + If in doubt, say N.
  57397. +
  57398. +config CPU_FREQ_GOV_INTERACTIVE
  57399. + tristate "'interactive' cpufreq policy governor"
  57400. + default n
  57401. + help
  57402. + 'interactive' - This driver adds a dynamic cpufreq policy governor
  57403. + designed for latency-sensitive workloads.
  57404. +
  57405. + This governor attempts to reduce the latency of clock
  57406. + increases so that the system is more responsive to
  57407. + interactive workloads.
  57408. +
  57409. + To compile this driver as a module, choose M here: the
  57410. + module will be called cpufreq_interactive.
  57411. +
  57412. + For details, take a look at linux/Documentation/cpu-freq.
  57413. +
  57414. If in doubt, say N.
  57415. config CPU_FREQ_GOV_CONSERVATIVE
  57416. diff -Nur linux-3.14.17/drivers/cpufreq/Kconfig.arm linux-imx6-3.14/drivers/cpufreq/Kconfig.arm
  57417. --- linux-3.14.17/drivers/cpufreq/Kconfig.arm 2014-08-14 03:38:34.000000000 +0200
  57418. +++ linux-imx6-3.14/drivers/cpufreq/Kconfig.arm 2014-09-11 18:05:59.970029858 +0200
  57419. @@ -4,7 +4,8 @@
  57420. config ARM_BIG_LITTLE_CPUFREQ
  57421. tristate "Generic ARM big LITTLE CPUfreq driver"
  57422. - depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK
  57423. + depends on (BIG_LITTLE && ARM_CPU_TOPOLOGY) || (ARM64 && SMP)
  57424. + depends on HAVE_CLK
  57425. select PM_OPP
  57426. help
  57427. This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
  57428. @@ -95,7 +96,7 @@
  57429. If in doubt, say N.
  57430. -config ARM_IMX6Q_CPUFREQ
  57431. +config ARM_IMX6_CPUFREQ
  57432. tristate "Freescale i.MX6 cpufreq support"
  57433. depends on ARCH_MXC
  57434. depends on REGULATOR_ANATOP
  57435. diff -Nur linux-3.14.17/drivers/cpufreq/Makefile linux-imx6-3.14/drivers/cpufreq/Makefile
  57436. --- linux-3.14.17/drivers/cpufreq/Makefile 2014-08-14 03:38:34.000000000 +0200
  57437. +++ linux-imx6-3.14/drivers/cpufreq/Makefile 2014-09-11 18:05:59.970029858 +0200
  57438. @@ -8,6 +8,7 @@
  57439. obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
  57440. obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
  57441. obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
  57442. +obj-$(CONFIG_CPU_FREQ_GOV_INTERACTIVE) += cpufreq_interactive.o
  57443. obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
  57444. obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
  57445. @@ -55,7 +56,7 @@
  57446. obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
  57447. obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ) += exynos5440-cpufreq.o
  57448. obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
  57449. -obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
  57450. +obj-$(CONFIG_ARM_IMX6_CPUFREQ) += imx6-cpufreq.o
  57451. obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
  57452. obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
  57453. obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
  57454. diff -Nur linux-3.14.17/drivers/crypto/caam/secvio.c linux-imx6-3.14/drivers/crypto/caam/secvio.c
  57455. --- linux-3.14.17/drivers/crypto/caam/secvio.c 1970-01-01 01:00:00.000000000 +0100
  57456. +++ linux-imx6-3.14/drivers/crypto/caam/secvio.c 2014-09-11 18:06:00.054030194 +0200
  57457. @@ -0,0 +1,335 @@
  57458. +
  57459. +/*
  57460. + * CAAM/SEC 4.x Security Violation Handler
  57461. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  57462. + */
  57463. +
  57464. +#include "compat.h"
  57465. +#include "intern.h"
  57466. +#include "secvio.h"
  57467. +#include "regs.h"
  57468. +
  57469. +/*
  57470. + * These names are associated with each violation handler.
  57471. + * The source names were taken from MX6, and are based on recommendations
  57472. + * for most common SoCs.
  57473. + */
  57474. +static const u8 *violation_src_name[] = {
  57475. + "CAAM Security Violation",
  57476. + "JTAG Alarm",
  57477. + "Watchdog",
  57478. + "(reserved)",
  57479. + "External Boot",
  57480. + "Tamper Detect",
  57481. +};
  57482. +
  57483. +/* Top-level security violation interrupt */
  57484. +static irqreturn_t caam_secvio_interrupt(int irq, void *snvsdev)
  57485. +{
  57486. + struct device *dev = snvsdev;
  57487. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  57488. + u32 irqstate;
  57489. +
  57490. + /* Check the HP secvio status register */
  57491. + irqstate = rd_reg32(&svpriv->svregs->hp.secvio_status) |
  57492. + HP_SECVIOST_SECVIOMASK;
  57493. +
  57494. + if (!irqstate)
  57495. + return IRQ_NONE;
  57496. +
  57497. + /* Mask out one or more causes for deferred service */
  57498. + clrbits32(&svpriv->svregs->hp.secvio_int_ctl, irqstate);
  57499. +
  57500. + /* Now ACK causes */
  57501. + setbits32(&svpriv->svregs->hp.secvio_status, irqstate);
  57502. +
  57503. + /* And run deferred service */
  57504. + preempt_disable();
  57505. + tasklet_schedule(&svpriv->irqtask[smp_processor_id()]);
  57506. + preempt_enable();
  57507. +
  57508. + return IRQ_HANDLED;
  57509. +}
  57510. +
  57511. +/* Deferred service handler. Tasklet arg is simply the SNVS dev */
  57512. +static void caam_secvio_dispatch(unsigned long indev)
  57513. +{
  57514. + struct device *dev = (struct device *)indev;
  57515. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  57516. + unsigned long flags, cause;
  57517. + int i;
  57518. +
  57519. +
  57520. + /*
  57521. + * Capture the interrupt cause, using masked interrupts as
  57522. + * identification. This only works if all are enabled; if
  57523. + * this changes in the future, a "cause queue" will have to
  57524. + * be built
  57525. + */
  57526. + cause = rd_reg32(&svpriv->svregs->hp.secvio_int_ctl) &
  57527. + (HP_SECVIO_INTEN_SRC5 | HP_SECVIO_INTEN_SRC4 |
  57528. + HP_SECVIO_INTEN_SRC3 | HP_SECVIO_INTEN_SRC2 |
  57529. + HP_SECVIO_INTEN_SRC1 | HP_SECVIO_INTEN_SRC0);
  57530. +
  57531. + /* Look through causes, call each handler if exists */
  57532. + for (i = 0; i < MAX_SECVIO_SOURCES; i++)
  57533. + if (cause & (1 << i)) {
  57534. + spin_lock_irqsave(&svpriv->svlock, flags);
  57535. + svpriv->intsrc[i].handler(dev, i,
  57536. + svpriv->intsrc[i].ext);
  57537. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  57538. + };
  57539. +
  57540. + /* Re-enable now-serviced interrupts */
  57541. + setbits32(&svpriv->svregs->hp.secvio_int_ctl, cause);
  57542. +}
  57543. +
  57544. +/*
  57545. + * Default cause handler, used in lieu of an application-defined handler.
  57546. + * All it does at this time is print a console message. It could force a halt.
  57547. + */
  57548. +static void caam_secvio_default(struct device *dev, u32 cause, void *ext)
  57549. +{
  57550. + struct caam_drv_private_secvio *svpriv = dev_get_drvdata(dev);
  57551. +
  57552. + dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n",
  57553. + cause, svpriv->intsrc[cause].intname);
  57554. +}
  57555. +
  57556. +/*
  57557. + * Install an application-defined handler for a specified cause
  57558. + * Arguments:
  57559. + * - dev points to SNVS-owning device
  57560. + * - cause interrupt source cause
  57561. + * - handler application-defined handler, gets called with dev
  57562. + * source cause, and locally-defined handler argument
  57563. + * - cause_description points to a string to override the default cause
  57564. + * name, this can be used as an alternate for error
  57565. + * messages and such. If left NULL, the default
  57566. + * description string is used.
  57567. + * - ext pointer to any extra data needed by the handler.
  57568. + */
  57569. +int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
  57570. + void (*handler)(struct device *dev, u32 cause,
  57571. + void *ext),
  57572. + u8 *cause_description, void *ext)
  57573. +{
  57574. + unsigned long flags;
  57575. + struct caam_drv_private_secvio *svpriv;
  57576. +
  57577. + svpriv = dev_get_drvdata(dev);
  57578. +
  57579. + if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5))
  57580. + return -EINVAL;
  57581. +
  57582. + spin_lock_irqsave(&svpriv->svlock, flags);
  57583. + svpriv->intsrc[cause].handler = handler;
  57584. + if (cause_description != NULL)
  57585. + svpriv->intsrc[cause].intname = cause_description;
  57586. + if (ext != NULL)
  57587. + svpriv->intsrc[cause].ext = ext;
  57588. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  57589. +
  57590. + return 0;
  57591. +}
  57592. +EXPORT_SYMBOL(caam_secvio_install_handler);
  57593. +
  57594. +/*
  57595. + * Remove an application-defined handler for a specified cause (and, by
  57596. + * implication, restore the "default".
  57597. + * Arguments:
  57598. + * - dev points to SNVS-owning device
  57599. + * - cause interrupt source cause
  57600. + */
  57601. +int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause)
  57602. +{
  57603. + unsigned long flags;
  57604. + struct caam_drv_private_secvio *svpriv;
  57605. +
  57606. + svpriv = dev_get_drvdata(dev);
  57607. +
  57608. + if (cause > SECVIO_CAUSE_SOURCE_5)
  57609. + return -EINVAL;
  57610. +
  57611. + spin_lock_irqsave(&svpriv->svlock, flags);
  57612. + svpriv->intsrc[cause].intname = violation_src_name[cause];
  57613. + svpriv->intsrc[cause].handler = caam_secvio_default;
  57614. + svpriv->intsrc[cause].ext = NULL;
  57615. + spin_unlock_irqrestore(&svpriv->svlock, flags);
  57616. + return 0;
  57617. +}
  57618. +EXPORT_SYMBOL(caam_secvio_remove_handler);
  57619. +
  57620. +int caam_secvio_startup(struct platform_device *pdev)
  57621. +{
  57622. + struct device *ctrldev, *svdev;
  57623. + struct caam_drv_private *ctrlpriv;
  57624. + struct caam_drv_private_secvio *svpriv;
  57625. + struct platform_device *svpdev;
  57626. + struct device_node *np;
  57627. + const void *prop;
  57628. + int i, error, secvio_inten_src;
  57629. +
  57630. + ctrldev = &pdev->dev;
  57631. + ctrlpriv = dev_get_drvdata(ctrldev);
  57632. + /*
  57633. + * Set up the private block for secure memory
  57634. + * Only one instance is possible
  57635. + */
  57636. + svpriv = kzalloc(sizeof(struct caam_drv_private_secvio), GFP_KERNEL);
  57637. + if (svpriv == NULL) {
  57638. + dev_err(ctrldev, "can't alloc private mem for secvio\n");
  57639. + return -ENOMEM;
  57640. + }
  57641. + svpriv->parentdev = ctrldev;
  57642. +
  57643. + /* Create the security violation dev */
  57644. +#ifdef CONFIG_OF
  57645. +
  57646. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio");
  57647. + if (!np)
  57648. + return -ENODEV;
  57649. +
  57650. + ctrlpriv->secvio_irq = of_irq_to_resource(np, 0, NULL);
  57651. +
  57652. + prop = of_get_property(np, "secvio_src", NULL);
  57653. + if (prop)
  57654. + secvio_inten_src = of_read_ulong(prop, 1);
  57655. + else
  57656. + secvio_inten_src = HP_SECVIO_INTEN_ALL;
  57657. +
  57658. + printk(KERN_ERR "secvio_inten_src = %x\n", secvio_inten_src);
  57659. +
  57660. + svpdev = of_platform_device_create(np, NULL, ctrldev);
  57661. + if (!svpdev)
  57662. + return -ENODEV;
  57663. +
  57664. +#else
  57665. + svpdev = platform_device_register_data(ctrldev, "caam_secvio", 0,
  57666. + svpriv,
  57667. + sizeof(struct caam_drv_private_secvio));
  57668. +
  57669. + secvio_inten_src = HP_SECVIO_INTEN_ALL;
  57670. +#endif
  57671. + if (svpdev == NULL) {
  57672. + kfree(svpriv);
  57673. + return -EINVAL;
  57674. + }
  57675. + svdev = &svpdev->dev;
  57676. + dev_set_drvdata(svdev, svpriv);
  57677. + ctrlpriv->secviodev = svdev;
  57678. + svpriv->svregs = ctrlpriv->snvs;
  57679. +
  57680. + /*
  57681. + * Now we have all the dev data set up. Init interrupt
  57682. + * source descriptions
  57683. + */
  57684. + for (i = 0; i < MAX_SECVIO_SOURCES; i++) {
  57685. + svpriv->intsrc[i].intname = violation_src_name[i];
  57686. + svpriv->intsrc[i].handler = caam_secvio_default;
  57687. + }
  57688. +
  57689. + /* Connect main handler */
  57690. + for_each_possible_cpu(i)
  57691. + tasklet_init(&svpriv->irqtask[i], caam_secvio_dispatch,
  57692. + (unsigned long)svdev);
  57693. +
  57694. + error = request_irq(ctrlpriv->secvio_irq, caam_secvio_interrupt,
  57695. + IRQF_SHARED, "caam_secvio", svdev);
  57696. + if (error) {
  57697. + dev_err(svdev, "can't connect secvio interrupt\n");
  57698. + irq_dispose_mapping(ctrlpriv->secvio_irq);
  57699. + ctrlpriv->secvio_irq = 0;
  57700. + return -EINVAL;
  57701. + }
  57702. +
  57703. + /* Enable all sources */
  57704. + wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, secvio_inten_src);
  57705. +
  57706. + dev_info(svdev, "security violation service handlers armed\n");
  57707. +
  57708. + return 0;
  57709. +}
  57710. +
  57711. +void caam_secvio_shutdown(struct platform_device *pdev)
  57712. +{
  57713. + struct device *ctrldev, *svdev;
  57714. + struct caam_drv_private *priv;
  57715. + struct caam_drv_private_secvio *svpriv;
  57716. + int i;
  57717. +
  57718. + ctrldev = &pdev->dev;
  57719. + priv = dev_get_drvdata(ctrldev);
  57720. + svdev = priv->secviodev;
  57721. + svpriv = dev_get_drvdata(svdev);
  57722. +
  57723. + /* Shut off all sources */
  57724. +
  57725. + wr_reg32(&svpriv->svregs->hp.secvio_int_ctl, 0);
  57726. +
  57727. + /* Remove tasklets and release interrupt */
  57728. + for_each_possible_cpu(i)
  57729. + tasklet_kill(&svpriv->irqtask[i]);
  57730. +
  57731. + free_irq(priv->secvio_irq, svdev);
  57732. +
  57733. + kfree(svpriv);
  57734. +}
  57735. +
  57736. +
  57737. +#ifdef CONFIG_OF
  57738. +static void __exit caam_secvio_exit(void)
  57739. +{
  57740. + struct device_node *dev_node;
  57741. + struct platform_device *pdev;
  57742. +
  57743. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  57744. + if (!dev_node) {
  57745. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  57746. + if (!dev_node)
  57747. + return;
  57748. + }
  57749. +
  57750. + pdev = of_find_device_by_node(dev_node);
  57751. + if (!pdev)
  57752. + return;
  57753. +
  57754. + of_node_get(dev_node);
  57755. +
  57756. + caam_secvio_shutdown(pdev);
  57757. +
  57758. +}
  57759. +
  57760. +static int __init caam_secvio_init(void)
  57761. +{
  57762. + struct device_node *dev_node;
  57763. + struct platform_device *pdev;
  57764. +
  57765. + /*
  57766. + * Do of_find_compatible_node() then of_find_device_by_node()
  57767. + * once a functional device tree is available
  57768. + */
  57769. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  57770. + if (!dev_node) {
  57771. + dev_node = of_find_compatible_node(NULL, NULL,
  57772. + "arm,imx6-caam-secvio");
  57773. + if (!dev_node)
  57774. + return -ENODEV;
  57775. + }
  57776. +
  57777. + pdev = of_find_device_by_node(dev_node);
  57778. + if (!pdev)
  57779. + return -ENODEV;
  57780. +
  57781. + of_node_put(dev_node);
  57782. +
  57783. + return caam_secvio_startup(pdev);
  57784. +}
  57785. +
  57786. +module_init(caam_secvio_init);
  57787. +module_exit(caam_secvio_exit);
  57788. +
  57789. +MODULE_LICENSE("Dual BSD/GPL");
  57790. +MODULE_DESCRIPTION("FSL CAAM/SNVS Security Violation Handler");
  57791. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  57792. +#endif
  57793. diff -Nur linux-3.14.17/drivers/crypto/caam/secvio.h linux-imx6-3.14/drivers/crypto/caam/secvio.h
  57794. --- linux-3.14.17/drivers/crypto/caam/secvio.h 1970-01-01 01:00:00.000000000 +0100
  57795. +++ linux-imx6-3.14/drivers/crypto/caam/secvio.h 2014-09-11 18:06:00.062030226 +0200
  57796. @@ -0,0 +1,64 @@
  57797. +
  57798. +/*
  57799. + * CAAM Security Violation Handler
  57800. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  57801. + */
  57802. +
  57803. +#ifndef SECVIO_H
  57804. +#define SECVIO_H
  57805. +
  57806. +#include "snvsregs.h"
  57807. +
  57808. +
  57809. +/*
  57810. + * Defines the published interfaces to install/remove application-specified
  57811. + * handlers for catching violations
  57812. + */
  57813. +
  57814. +#define MAX_SECVIO_SOURCES 6
  57815. +
  57816. +/* these are the untranslated causes */
  57817. +enum secvio_cause {
  57818. + SECVIO_CAUSE_SOURCE_0,
  57819. + SECVIO_CAUSE_SOURCE_1,
  57820. + SECVIO_CAUSE_SOURCE_2,
  57821. + SECVIO_CAUSE_SOURCE_3,
  57822. + SECVIO_CAUSE_SOURCE_4,
  57823. + SECVIO_CAUSE_SOURCE_5
  57824. +};
  57825. +
  57826. +/* These are common "recommended" cause definitions for most devices */
  57827. +#define SECVIO_CAUSE_CAAM_VIOLATION SECVIO_CAUSE_SOURCE_0
  57828. +#define SECVIO_CAUSE JTAG_ALARM SECVIO_CAUSE_SOURCE_1
  57829. +#define SECVIO_CAUSE_WATCHDOG SECVIO_CAUSE_SOURCE_2
  57830. +#define SECVIO_CAUSE_EXTERNAL_BOOT SECVIO_CAUSE_SOURCE_4
  57831. +#define SECVIO_CAUSE_TAMPER_DETECT SECVIO_CAUSE_SOURCE_5
  57832. +
  57833. +int caam_secvio_install_handler(struct device *dev, enum secvio_cause cause,
  57834. + void (*handler)(struct device *dev, u32 cause,
  57835. + void *ext),
  57836. + u8 *cause_description, void *ext);
  57837. +int caam_secvio_remove_handler(struct device *dev, enum secvio_cause cause);
  57838. +
  57839. +/*
  57840. + * Private data definitions for the secvio "driver"
  57841. + */
  57842. +
  57843. +struct secvio_int_src {
  57844. + const u8 *intname; /* Points to a descriptive name for source */
  57845. + void *ext; /* Extended data to pass to the handler */
  57846. + void (*handler)(struct device *dev, u32 cause, void *ext);
  57847. +};
  57848. +
  57849. +struct caam_drv_private_secvio {
  57850. + struct device *parentdev; /* points back to the controller */
  57851. + spinlock_t svlock ____cacheline_aligned;
  57852. + struct tasklet_struct irqtask[NR_CPUS];
  57853. + struct snvs_full __iomem *svregs; /* both HP and LP domains */
  57854. +
  57855. + /* Registered handlers for each violation */
  57856. + struct secvio_int_src intsrc[MAX_SECVIO_SOURCES];
  57857. +
  57858. +};
  57859. +
  57860. +#endif /* SECVIO_H */
  57861. diff -Nur linux-3.14.17/drivers/crypto/caam/sm.h linux-imx6-3.14/drivers/crypto/caam/sm.h
  57862. --- linux-3.14.17/drivers/crypto/caam/sm.h 1970-01-01 01:00:00.000000000 +0100
  57863. +++ linux-imx6-3.14/drivers/crypto/caam/sm.h 2014-09-11 18:06:00.066030242 +0200
  57864. @@ -0,0 +1,88 @@
  57865. +
  57866. +/*
  57867. + * CAAM Secure Memory/Keywrap API Definitions
  57868. + * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
  57869. + */
  57870. +
  57871. +#ifndef SM_H
  57872. +#define SM_H
  57873. +
  57874. +
  57875. +/* Storage access permissions */
  57876. +#define SM_PERM_READ 0x01
  57877. +#define SM_PERM_WRITE 0x02
  57878. +#define SM_PERM_BLOB 0x03
  57879. +
  57880. +
  57881. +/* Keystore maintenance functions */
  57882. +void sm_init_keystore(struct device *dev);
  57883. +u32 sm_detect_keystore_units(struct device *dev);
  57884. +int sm_establish_keystore(struct device *dev, u32 unit);
  57885. +void sm_release_keystore(struct device *dev, u32 unit);
  57886. +void caam_sm_shutdown(struct platform_device *pdev);
  57887. +int caam_sm_example_init(struct platform_device *pdev);
  57888. +
  57889. +/* Keystore accessor functions */
  57890. +extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size,
  57891. + u32 *slot);
  57892. +extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot);
  57893. +extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
  57894. + const u8 *key_data, u32 key_length);
  57895. +extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
  57896. + u32 key_length, u8 *key_data);
  57897. +extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit,
  57898. + u32 inslot, u32 outslot, u16 secretlen,
  57899. + u8 *keymod, u16 keymodlen);
  57900. +extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit,
  57901. + u32 inslot, u32 outslot, u16 secretlen,
  57902. + u8 *keymod, u16 keymodlen);
  57903. +
  57904. +/* Data structure to hold per-slot information */
  57905. +struct keystore_data_slot_info {
  57906. + u8 allocated; /* Track slot assignments */
  57907. + u32 key_length; /* Size of the key */
  57908. +};
  57909. +
  57910. +/* Data structure to hold keystore information */
  57911. +struct keystore_data {
  57912. + void *base_address; /* Base of the Secure Partition */
  57913. + u32 slot_count; /* Number of slots in the keystore */
  57914. + struct keystore_data_slot_info *slot; /* Per-slot information */
  57915. +};
  57916. +
  57917. +/* store the detected attributes of a secure memory page */
  57918. +struct sm_page_descriptor {
  57919. + u16 phys_pagenum; /* may be discontiguous */
  57920. + u16 own_part; /* Owning partition */
  57921. + void *pg_base; /* Calculated virtual address */
  57922. + struct keystore_data *ksdata;
  57923. +};
  57924. +
  57925. +struct caam_drv_private_sm {
  57926. + struct device *parentdev; /* this ends up as the controller */
  57927. + struct device *smringdev; /* ring that owns this instance */
  57928. + spinlock_t kslock ____cacheline_aligned;
  57929. +
  57930. + /* Default parameters for geometry */
  57931. + u32 max_pages; /* maximum pages this instance can support */
  57932. + u32 top_partition; /* highest partition number in this instance */
  57933. + u32 top_page; /* highest page number in this instance */
  57934. + u32 page_size; /* page size */
  57935. + u32 slot_size; /* selected size of each storage block */
  57936. +
  57937. + /* Partition/Page Allocation Map */
  57938. + u32 localpages; /* Number of pages we can access */
  57939. + struct sm_page_descriptor *pagedesc; /* Allocated per-page */
  57940. +
  57941. + /* Installed handlers for keystore access */
  57942. + int (*data_init)(struct device *dev, u32 unit);
  57943. + void (*data_cleanup)(struct device *dev, u32 unit);
  57944. + int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot);
  57945. + int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot);
  57946. + void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle);
  57947. + u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle);
  57948. + u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle);
  57949. + u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle);
  57950. +};
  57951. +
  57952. +#endif /* SM_H */
  57953. diff -Nur linux-3.14.17/drivers/crypto/caam/sm_store.c linux-imx6-3.14/drivers/crypto/caam/sm_store.c
  57954. --- linux-3.14.17/drivers/crypto/caam/sm_store.c 1970-01-01 01:00:00.000000000 +0100
  57955. +++ linux-imx6-3.14/drivers/crypto/caam/sm_store.c 2014-09-11 18:06:00.066030242 +0200
  57956. @@ -0,0 +1,896 @@
  57957. +
  57958. +/*
  57959. + * CAAM Secure Memory Storage Interface
  57960. + * Copyright (C) 2008-2013 Freescale Semiconductor, Inc.
  57961. + *
  57962. + * Loosely based on the SHW Keystore API for SCC/SCC2
  57963. + * Experimental implementation and NOT intended for upstream use. Expect
  57964. + * this interface to be amended significantly in the future once it becomes
  57965. + * integrated into live applications.
  57966. + *
  57967. + * Known issues:
  57968. + *
  57969. + * - Executes one instance of an secure memory "driver". This is tied to the
  57970. + * fact that job rings can't run as standalone instances in the present
  57971. + * configuration.
  57972. + *
  57973. + * - It does not expose a userspace interface. The value of a userspace
  57974. + * interface for access to secrets is a point for further architectural
  57975. + * discussion.
  57976. + *
  57977. + * - Partition/permission management is not part of this interface. It
  57978. + * depends on some level of "knowledge" agreed upon between bootloader,
  57979. + * provisioning applications, and OS-hosted software (which uses this
  57980. + * driver).
  57981. + *
  57982. + * - No means of identifying the location or purpose of secrets managed by
  57983. + * this interface exists; "slot location" and format of a given secret
  57984. + * needs to be agreed upon between bootloader, provisioner, and OS-hosted
  57985. + * application.
  57986. + */
  57987. +
  57988. +#include "compat.h"
  57989. +#include "regs.h"
  57990. +#include "jr.h"
  57991. +#include "desc.h"
  57992. +#include "intern.h"
  57993. +#include "error.h"
  57994. +#include "sm.h"
  57995. +
  57996. +#ifdef SM_DEBUG_CONT
  57997. +void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc)
  57998. +{
  57999. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58000. + u32 i, *smdata;
  58001. +
  58002. + dev_info(dev, "physical page %d content at 0x%08x\n",
  58003. + pgdesc->phys_pagenum, pgdesc->pg_base);
  58004. + smdata = pgdesc->pg_base;
  58005. + for (i = 0; i < (smpriv->page_size / sizeof(u32)); i += 4)
  58006. + dev_info(dev, "[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
  58007. + (u32)&smdata[i], smdata[i], smdata[i+1], smdata[i+2],
  58008. + smdata[i+3]);
  58009. +}
  58010. +#endif
  58011. +
  58012. +/*
  58013. + * Construct a secure memory blob encapsulation job descriptor
  58014. + *
  58015. + * - desc pointer to hold new (to be allocated) pointer to the generated
  58016. + * descriptor for later use. Calling thread can kfree the
  58017. + * descriptor after execution.
  58018. + * - keymod Physical pointer to key modifier (contiguous piece).
  58019. + * - keymodsz Size of key modifier in bytes (should normally be 8).
  58020. + * - secretbuf Physical pointer (within an accessible secure memory page)
  58021. + * of the secret to be encapsulated.
  58022. + * - outbuf Physical pointer (within an accessible secure memory page)
  58023. + * of the encapsulated output. This will be larger than the
  58024. + * input secret because of the added encapsulation data.
  58025. + * - secretsz Size of input secret, in bytes.
  58026. + * - auth If nonzero, use AES-CCM for encapsulation, else use ECB
  58027. + *
  58028. + * Note: this uses 32-bit pointers at present
  58029. + */
  58030. +#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */
  58031. +static int blob_encap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
  58032. + dma_addr_t secretbuf, dma_addr_t outbuf,
  58033. + u16 secretsz, bool auth)
  58034. +{
  58035. + u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
  58036. + u16 dsize, idx;
  58037. +
  58038. + memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
  58039. + idx = 1;
  58040. +
  58041. + /* Load key modifier */
  58042. + tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
  58043. + ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
  58044. + (keymodsz & LDST_LEN_MASK);
  58045. +
  58046. + tmpdesc[idx++] = (u32)keymod;
  58047. +
  58048. + /* Encapsulate to secure memory */
  58049. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | secretsz;
  58050. + tmpdesc[idx++] = (u32)secretbuf;
  58051. +
  58052. + /* Add space for BKEK and MAC tag */
  58053. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | (secretsz + (32 + 16));
  58054. +
  58055. + tmpdesc[idx++] = (u32)outbuf;
  58056. + tmpdesc[idx] = CMD_OPERATION | OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
  58057. + OP_PCL_BLOB_PTXT_SECMEM;
  58058. + if (auth)
  58059. + tmpdesc[idx] |= OP_PCL_BLOB_EKT;
  58060. +
  58061. + idx++;
  58062. + tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
  58063. + dsize = idx * sizeof(u32);
  58064. +
  58065. + tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
  58066. + if (tdesc == NULL)
  58067. + return 0;
  58068. +
  58069. + memcpy(tdesc, tmpdesc, dsize);
  58070. + *desc = tdesc;
  58071. + return dsize;
  58072. +}
  58073. +
  58074. +/*
  58075. + * Construct a secure memory blob decapsulation job descriptor
  58076. + *
  58077. + * - desc pointer to hold new (to be allocated) pointer to the generated
  58078. + * descriptor for later use. Calling thread can kfree the
  58079. + * descriptor after execution.
  58080. + * - keymod Physical pointer to key modifier (contiguous piece).
  58081. + * - keymodsz Size of key modifier in bytes (should normally be 16).
  58082. + * - blobbuf Physical pointer (within an accessible secure memory page)
  58083. + * of the blob to be decapsulated.
  58084. + * - outbuf Physical pointer (within an accessible secure memory page)
  58085. + * of the decapsulated output.
  58086. + * - secretsz Size of input blob, in bytes.
  58087. + * - auth If nonzero, assume AES-CCM for decapsulation, else use ECB
  58088. + *
  58089. + * Note: this uses 32-bit pointers at present
  58090. + */
  58091. +static int blob_decap_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,
  58092. + dma_addr_t blobbuf, dma_addr_t outbuf,
  58093. + u16 blobsz, bool auth)
  58094. +{
  58095. + u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
  58096. + u16 dsize, idx;
  58097. +
  58098. + memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
  58099. + idx = 1;
  58100. +
  58101. + /* Load key modifier */
  58102. + tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |
  58103. + ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |
  58104. + (keymodsz & LDST_LEN_MASK);
  58105. +
  58106. + tmpdesc[idx++] = (u32)keymod;
  58107. +
  58108. + /* Compensate BKEK + MAC tag */
  58109. + tmpdesc[idx++] = CMD_SEQ_IN_PTR | (blobsz + 32 + 16);
  58110. +
  58111. + tmpdesc[idx++] = (u32)blobbuf;
  58112. + tmpdesc[idx++] = CMD_SEQ_OUT_PTR | blobsz;
  58113. + tmpdesc[idx++] = (u32)outbuf;
  58114. +
  58115. + /* Decapsulate from secure memory partition to black blob */
  58116. + tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB |
  58117. + OP_PCL_BLOB_PTXT_SECMEM | OP_PCL_BLOB_BLACK;
  58118. + if (auth)
  58119. + tmpdesc[idx] |= OP_PCL_BLOB_EKT;
  58120. +
  58121. + idx++;
  58122. + tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
  58123. + dsize = idx * sizeof(u32);
  58124. +
  58125. + tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
  58126. + if (tdesc == NULL)
  58127. + return 0;
  58128. +
  58129. + memcpy(tdesc, tmpdesc, dsize);
  58130. + *desc = tdesc;
  58131. + return dsize;
  58132. +}
  58133. +
  58134. +/*
  58135. + * Pseudo-synchronous ring access functions for carrying out key
  58136. + * encapsulation and decapsulation
  58137. + */
  58138. +
  58139. +struct sm_key_job_result {
  58140. + int error;
  58141. + struct completion completion;
  58142. +};
  58143. +
  58144. +void sm_key_job_done(struct device *dev, u32 *desc, u32 err, void *context)
  58145. +{
  58146. + struct sm_key_job_result *res = context;
  58147. +
  58148. + res->error = err; /* save off the error for postprocessing */
  58149. + complete(&res->completion); /* mark us complete */
  58150. +}
  58151. +
  58152. +static int sm_key_job(struct device *ksdev, u32 *jobdesc)
  58153. +{
  58154. + struct sm_key_job_result testres;
  58155. + struct caam_drv_private_sm *kspriv;
  58156. + int rtn = 0;
  58157. +
  58158. + kspriv = dev_get_drvdata(ksdev);
  58159. +
  58160. + init_completion(&testres.completion);
  58161. +
  58162. + rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, sm_key_job_done,
  58163. + &testres);
  58164. + if (!rtn) {
  58165. + wait_for_completion_interruptible(&testres.completion);
  58166. + rtn = testres.error;
  58167. + }
  58168. + return rtn;
  58169. +}
  58170. +
  58171. +/*
  58172. + * Following section establishes the default methods for keystore access
  58173. + * They are NOT intended for use external to this module
  58174. + *
  58175. + * In the present version, these are the only means for the higher-level
  58176. + * interface to deal with the mechanics of accessing the phyiscal keystore
  58177. + */
  58178. +
  58179. +
  58180. +int slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
  58181. +{
  58182. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58183. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  58184. + u32 i;
  58185. +#ifdef SM_DEBUG
  58186. + dev_info(dev, "slot_alloc(): requesting slot for %d bytes\n", size);
  58187. +#endif
  58188. +
  58189. + if (size > smpriv->slot_size)
  58190. + return -EKEYREJECTED;
  58191. +
  58192. + for (i = 0; i < ksdata->slot_count; i++) {
  58193. + if (ksdata->slot[i].allocated == 0) {
  58194. + ksdata->slot[i].allocated = 1;
  58195. + (*slot) = i;
  58196. +#ifdef SM_DEBUG
  58197. + dev_info(dev, "slot_alloc(): new slot %d allocated\n",
  58198. + *slot);
  58199. +#endif
  58200. + return 0;
  58201. + }
  58202. + }
  58203. +
  58204. + return -ENOSPC;
  58205. +}
  58206. +EXPORT_SYMBOL(slot_alloc);
  58207. +
  58208. +int slot_dealloc(struct device *dev, u32 unit, u32 slot)
  58209. +{
  58210. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58211. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  58212. + u8 __iomem *slotdata;
  58213. +
  58214. +#ifdef SM_DEBUG
  58215. + dev_info(dev, "slot_dealloc(): releasing slot %d\n", slot);
  58216. +#endif
  58217. + if (slot >= ksdata->slot_count)
  58218. + return -EINVAL;
  58219. + slotdata = ksdata->base_address + slot * smpriv->slot_size;
  58220. +
  58221. + if (ksdata->slot[slot].allocated == 1) {
  58222. + /* Forcibly overwrite the data from the keystore */
  58223. + memset(ksdata->base_address + slot * smpriv->slot_size, 0,
  58224. + smpriv->slot_size);
  58225. +
  58226. + ksdata->slot[slot].allocated = 0;
  58227. +#ifdef SM_DEBUG
  58228. + dev_info(dev, "slot_dealloc(): slot %d released\n", slot);
  58229. +#endif
  58230. + return 0;
  58231. + }
  58232. +
  58233. + return -EINVAL;
  58234. +}
  58235. +EXPORT_SYMBOL(slot_dealloc);
  58236. +
  58237. +void *slot_get_address(struct device *dev, u32 unit, u32 slot)
  58238. +{
  58239. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58240. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  58241. +
  58242. + if (slot >= ksdata->slot_count)
  58243. + return NULL;
  58244. +
  58245. +#ifdef SM_DEBUG
  58246. + dev_info(dev, "slot_get_address(): slot %d is 0x%08x\n", slot,
  58247. + (u32)ksdata->base_address + slot * smpriv->slot_size);
  58248. +#endif
  58249. +
  58250. + return ksdata->base_address + slot * smpriv->slot_size;
  58251. +}
  58252. +
  58253. +u32 slot_get_base(struct device *dev, u32 unit, u32 slot)
  58254. +{
  58255. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58256. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  58257. +
  58258. + /*
  58259. + * There could potentially be more than one secure partition object
  58260. + * associated with this keystore. For now, there is just one.
  58261. + */
  58262. +
  58263. + (void)slot;
  58264. +
  58265. +#ifdef SM_DEBUG
  58266. + dev_info(dev, "slot_get_base(): slot %d = 0x%08x\n",
  58267. + slot, (u32)ksdata->base_address);
  58268. +#endif
  58269. +
  58270. + return (u32)(ksdata->base_address);
  58271. +}
  58272. +
  58273. +u32 slot_get_offset(struct device *dev, u32 unit, u32 slot)
  58274. +{
  58275. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58276. + struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata;
  58277. +
  58278. + if (slot >= ksdata->slot_count)
  58279. + return -EINVAL;
  58280. +
  58281. +#ifdef SM_DEBUG
  58282. + dev_info(dev, "slot_get_offset(): slot %d = %d\n", slot,
  58283. + slot * smpriv->slot_size);
  58284. +#endif
  58285. +
  58286. + return slot * smpriv->slot_size;
  58287. +}
  58288. +
  58289. +u32 slot_get_slot_size(struct device *dev, u32 unit, u32 slot)
  58290. +{
  58291. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58292. +
  58293. +
  58294. +#ifdef SM_DEBUG
  58295. + dev_info(dev, "slot_get_slot_size(): slot %d = %d\n", slot,
  58296. + smpriv->slot_size);
  58297. +#endif
  58298. + /* All slots are the same size in the default implementation */
  58299. + return smpriv->slot_size;
  58300. +}
  58301. +
  58302. +
  58303. +
  58304. +int kso_init_data(struct device *dev, u32 unit)
  58305. +{
  58306. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58307. + int retval = -EINVAL;
  58308. + struct keystore_data *keystore_data = NULL;
  58309. + u32 slot_count;
  58310. + u32 keystore_data_size;
  58311. +
  58312. + /*
  58313. + * Calculate the required size of the keystore data structure, based
  58314. + * on the number of keys that can fit in the partition.
  58315. + */
  58316. + slot_count = smpriv->page_size / smpriv->slot_size;
  58317. +#ifdef SM_DEBUG
  58318. + dev_info(dev, "kso_init_data: %d slots initializing\n", slot_count);
  58319. +#endif
  58320. +
  58321. + keystore_data_size = sizeof(struct keystore_data) +
  58322. + slot_count *
  58323. + sizeof(struct keystore_data_slot_info);
  58324. +
  58325. + keystore_data = kzalloc(keystore_data_size, GFP_KERNEL);
  58326. +
  58327. + if (keystore_data == NULL) {
  58328. + retval = -ENOSPC;
  58329. + goto out;
  58330. + }
  58331. +
  58332. +#ifdef SM_DEBUG
  58333. + dev_info(dev, "kso_init_data: keystore data size = %d\n",
  58334. + keystore_data_size);
  58335. +#endif
  58336. +
  58337. + /*
  58338. + * Place the slot information structure directly after the keystore data
  58339. + * structure.
  58340. + */
  58341. + keystore_data->slot = (struct keystore_data_slot_info *)
  58342. + (keystore_data + 1);
  58343. + keystore_data->slot_count = slot_count;
  58344. +
  58345. + smpriv->pagedesc[unit].ksdata = keystore_data;
  58346. + smpriv->pagedesc[unit].ksdata->base_address =
  58347. + smpriv->pagedesc[unit].pg_base;
  58348. +
  58349. + retval = 0;
  58350. +
  58351. +out:
  58352. + if (retval != 0)
  58353. + if (keystore_data != NULL)
  58354. + kfree(keystore_data);
  58355. +
  58356. +
  58357. + return retval;
  58358. +}
  58359. +
  58360. +void kso_cleanup_data(struct device *dev, u32 unit)
  58361. +{
  58362. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58363. + struct keystore_data *keystore_data = NULL;
  58364. +
  58365. + if (smpriv->pagedesc[unit].ksdata != NULL)
  58366. + keystore_data = smpriv->pagedesc[unit].ksdata;
  58367. +
  58368. + /* Release the allocated keystore management data */
  58369. + kfree(smpriv->pagedesc[unit].ksdata);
  58370. +
  58371. + return;
  58372. +}
  58373. +
  58374. +
  58375. +
  58376. +/*
  58377. + * Keystore management section
  58378. + */
  58379. +
  58380. +void sm_init_keystore(struct device *dev)
  58381. +{
  58382. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58383. +
  58384. + smpriv->data_init = kso_init_data;
  58385. + smpriv->data_cleanup = kso_cleanup_data;
  58386. + smpriv->slot_alloc = slot_alloc;
  58387. + smpriv->slot_dealloc = slot_dealloc;
  58388. + smpriv->slot_get_address = slot_get_address;
  58389. + smpriv->slot_get_base = slot_get_base;
  58390. + smpriv->slot_get_offset = slot_get_offset;
  58391. + smpriv->slot_get_slot_size = slot_get_slot_size;
  58392. +#ifdef SM_DEBUG
  58393. + dev_info(dev, "sm_init_keystore(): handlers installed\n");
  58394. +#endif
  58395. +}
  58396. +EXPORT_SYMBOL(sm_init_keystore);
  58397. +
  58398. +/* Return available pages/units */
  58399. +u32 sm_detect_keystore_units(struct device *dev)
  58400. +{
  58401. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58402. +
  58403. + return smpriv->localpages;
  58404. +}
  58405. +EXPORT_SYMBOL(sm_detect_keystore_units);
  58406. +
  58407. +/*
  58408. + * Do any keystore specific initializations
  58409. + */
  58410. +int sm_establish_keystore(struct device *dev, u32 unit)
  58411. +{
  58412. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58413. +
  58414. +#ifdef SM_DEBUG
  58415. + dev_info(dev, "sm_establish_keystore(): unit %d initializing\n", unit);
  58416. +#endif
  58417. +
  58418. + if (smpriv->data_init == NULL)
  58419. + return -EINVAL;
  58420. +
  58421. + /* Call the data_init function for any user setup */
  58422. + return smpriv->data_init(dev, unit);
  58423. +}
  58424. +EXPORT_SYMBOL(sm_establish_keystore);
  58425. +
  58426. +void sm_release_keystore(struct device *dev, u32 unit)
  58427. +{
  58428. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58429. +
  58430. +#ifdef SM_DEBUG
  58431. + dev_info(dev, "sm_establish_keystore(): unit %d releasing\n", unit);
  58432. +#endif
  58433. + if ((smpriv != NULL) && (smpriv->data_cleanup != NULL))
  58434. + smpriv->data_cleanup(dev, unit);
  58435. +
  58436. + return;
  58437. +}
  58438. +EXPORT_SYMBOL(sm_release_keystore);
  58439. +
  58440. +/*
  58441. + * Subsequent interfacce (sm_keystore_*) forms the accessor interfacce to
  58442. + * the keystore
  58443. + */
  58444. +int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot)
  58445. +{
  58446. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58447. + int retval = -EINVAL;
  58448. +
  58449. + spin_lock(&smpriv->kslock);
  58450. +
  58451. + if ((smpriv->slot_alloc == NULL) ||
  58452. + (smpriv->pagedesc[unit].ksdata == NULL))
  58453. + goto out;
  58454. +
  58455. + retval = smpriv->slot_alloc(dev, unit, size, slot);
  58456. +
  58457. +out:
  58458. + spin_unlock(&smpriv->kslock);
  58459. + return retval;
  58460. +}
  58461. +EXPORT_SYMBOL(sm_keystore_slot_alloc);
  58462. +
  58463. +int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot)
  58464. +{
  58465. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58466. + int retval = -EINVAL;
  58467. +
  58468. + spin_lock(&smpriv->kslock);
  58469. +
  58470. + if ((smpriv->slot_alloc == NULL) ||
  58471. + (smpriv->pagedesc[unit].ksdata == NULL))
  58472. + goto out;
  58473. +
  58474. + retval = smpriv->slot_dealloc(dev, unit, slot);
  58475. +out:
  58476. + spin_unlock(&smpriv->kslock);
  58477. + return retval;
  58478. +}
  58479. +EXPORT_SYMBOL(sm_keystore_slot_dealloc);
  58480. +
  58481. +int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
  58482. + const u8 *key_data, u32 key_length)
  58483. +{
  58484. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58485. + int retval = -EINVAL;
  58486. + u32 slot_size;
  58487. + u32 i;
  58488. + u8 __iomem *slot_location;
  58489. +
  58490. + spin_lock(&smpriv->kslock);
  58491. +
  58492. + slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
  58493. +
  58494. + if (key_length > slot_size) {
  58495. + retval = -EFBIG;
  58496. + goto out;
  58497. + }
  58498. +
  58499. + slot_location = smpriv->slot_get_address(dev, unit, slot);
  58500. +
  58501. + for (i = 0; i < key_length; i++)
  58502. + slot_location[i] = key_data[i];
  58503. +
  58504. + retval = 0;
  58505. +
  58506. +out:
  58507. + spin_unlock(&smpriv->kslock);
  58508. + return retval;
  58509. +}
  58510. +EXPORT_SYMBOL(sm_keystore_slot_load);
  58511. +
  58512. +int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
  58513. + u32 key_length, u8 *key_data)
  58514. +{
  58515. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58516. + int retval = -EINVAL;
  58517. + u8 __iomem *slot_addr;
  58518. + u32 slot_size;
  58519. +
  58520. + spin_lock(&smpriv->kslock);
  58521. +
  58522. + slot_addr = smpriv->slot_get_address(dev, unit, slot);
  58523. + slot_size = smpriv->slot_get_slot_size(dev, unit, slot);
  58524. +
  58525. + if (key_length > slot_size) {
  58526. + retval = -EKEYREJECTED;
  58527. + goto out;
  58528. + }
  58529. +
  58530. + memcpy(key_data, slot_addr, key_length);
  58531. + retval = 0;
  58532. +
  58533. +out:
  58534. + spin_unlock(&smpriv->kslock);
  58535. + return retval;
  58536. +}
  58537. +EXPORT_SYMBOL(sm_keystore_slot_read);
  58538. +
  58539. +int sm_keystore_slot_encapsulate(struct device *dev, u32 unit, u32 inslot,
  58540. + u32 outslot, u16 secretlen, u8 *keymod,
  58541. + u16 keymodlen)
  58542. +{
  58543. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58544. + int retval = 0;
  58545. + u32 slot_length, dsize, jstat;
  58546. + u32 __iomem *encapdesc = NULL;
  58547. + u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
  58548. + dma_addr_t keymod_dma;
  58549. +
  58550. + /* Ensure that the full blob will fit in the key slot */
  58551. + slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
  58552. + if ((secretlen + 48) > slot_length)
  58553. + goto out;
  58554. +
  58555. + /* Get the base addresses of both keystore slots */
  58556. + inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
  58557. + outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
  58558. +
  58559. + /* Build the key modifier */
  58560. + lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
  58561. + memcpy(lkeymod, keymod, keymodlen);
  58562. + keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
  58563. + dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  58564. +
  58565. + /* Build the encapsulation job descriptor */
  58566. + dsize = blob_encap_desc(&encapdesc, keymod_dma, keymodlen,
  58567. + __pa(inpslotaddr), __pa(outslotaddr),
  58568. + secretlen, 0);
  58569. + if (!dsize) {
  58570. + dev_err(dev, "can't alloc an encap descriptor\n");
  58571. + retval = -ENOMEM;
  58572. + goto out;
  58573. + }
  58574. + jstat = sm_key_job(dev, encapdesc);
  58575. +
  58576. + dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  58577. + kfree(encapdesc);
  58578. +
  58579. +out:
  58580. + return retval;
  58581. +
  58582. +}
  58583. +EXPORT_SYMBOL(sm_keystore_slot_encapsulate);
  58584. +
  58585. +int sm_keystore_slot_decapsulate(struct device *dev, u32 unit, u32 inslot,
  58586. + u32 outslot, u16 secretlen, u8 *keymod,
  58587. + u16 keymodlen)
  58588. +{
  58589. + struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
  58590. + int retval = 0;
  58591. + u32 slot_length, dsize, jstat;
  58592. + u32 __iomem *decapdesc = NULL;
  58593. + u8 __iomem *lkeymod, *inpslotaddr, *outslotaddr;
  58594. + dma_addr_t keymod_dma;
  58595. +
  58596. + /* Ensure that the decap data will fit in the key slot */
  58597. + slot_length = smpriv->slot_get_slot_size(dev, unit, outslot);
  58598. + if (secretlen > slot_length)
  58599. + goto out;
  58600. +
  58601. + /* Get the base addresses of both keystore slots */
  58602. + inpslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, inslot);
  58603. + outslotaddr = (u8 *)smpriv->slot_get_address(dev, unit, outslot);
  58604. +
  58605. + /* Build the key modifier */
  58606. + lkeymod = kmalloc(keymodlen, GFP_KERNEL | GFP_DMA);
  58607. + memcpy(lkeymod, keymod, keymodlen);
  58608. + keymod_dma = dma_map_single(dev, lkeymod, keymodlen, DMA_TO_DEVICE);
  58609. + dma_sync_single_for_device(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  58610. +
  58611. + /* Build the decapsulation job descriptor */
  58612. + dsize = blob_decap_desc(&decapdesc, keymod_dma, keymodlen,
  58613. + __pa(inpslotaddr), __pa(outslotaddr),
  58614. + secretlen, 0);
  58615. + if (!dsize) {
  58616. + dev_err(dev, "can't alloc a decap descriptor\n");
  58617. + retval = -ENOMEM;
  58618. + goto out;
  58619. + }
  58620. + jstat = sm_key_job(dev, decapdesc);
  58621. +
  58622. + dma_unmap_single(dev, keymod_dma, keymodlen, DMA_TO_DEVICE);
  58623. + kfree(decapdesc);
  58624. +
  58625. +out:
  58626. + return retval;
  58627. +
  58628. +}
  58629. +EXPORT_SYMBOL(sm_keystore_slot_decapsulate);
  58630. +
  58631. +
  58632. +/*
  58633. + * Initialization/shutdown subsystem
  58634. + * Assumes statically-invoked startup/shutdown from the controller driver
  58635. + * for the present time, to be reworked when a device tree becomes
  58636. + * available. This code will not modularize in present form.
  58637. + *
  58638. + * Also, simply uses ring 0 for execution at the present
  58639. + */
  58640. +
  58641. +int caam_sm_startup(struct platform_device *pdev)
  58642. +{
  58643. + struct device *ctrldev, *smdev;
  58644. + struct caam_drv_private *ctrlpriv;
  58645. + struct caam_drv_private_sm *smpriv;
  58646. + struct caam_drv_private_jr *jrpriv; /* need this for reg page */
  58647. + struct platform_device *sm_pdev;
  58648. + struct sm_page_descriptor *lpagedesc;
  58649. + u32 page, pgstat, lpagect, detectedpage;
  58650. +
  58651. + struct device_node *np;
  58652. + ctrldev = &pdev->dev;
  58653. + ctrlpriv = dev_get_drvdata(ctrldev);
  58654. +
  58655. + /*
  58656. + * Set up the private block for secure memory
  58657. + * Only one instance is possible
  58658. + */
  58659. + smpriv = kzalloc(sizeof(struct caam_drv_private_sm), GFP_KERNEL);
  58660. + if (smpriv == NULL) {
  58661. + dev_err(ctrldev, "can't alloc private mem for secure memory\n");
  58662. + return -ENOMEM;
  58663. + }
  58664. + smpriv->parentdev = ctrldev; /* copy of parent dev is handy */
  58665. +
  58666. + /* Create the dev */
  58667. +#ifdef CONFIG_OF
  58668. + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
  58669. + sm_pdev = of_platform_device_create(np, "caam_sm", ctrldev);
  58670. +#else
  58671. + sm_pdev = platform_device_register_data(ctrldev, "caam_sm", 0,
  58672. + smpriv,
  58673. + sizeof(struct caam_drv_private_sm));
  58674. +#endif
  58675. + if (sm_pdev == NULL) {
  58676. + kfree(smpriv);
  58677. + return -EINVAL;
  58678. + }
  58679. + smdev = &sm_pdev->dev;
  58680. + dev_set_drvdata(smdev, smpriv);
  58681. + ctrlpriv->smdev = smdev;
  58682. +
  58683. + /*
  58684. + * Collect configuration limit data for reference
  58685. + * This batch comes from the partition data/vid registers in perfmon
  58686. + */
  58687. + smpriv->max_pages = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  58688. + & SMPART_MAX_NUMPG_MASK) >>
  58689. + SMPART_MAX_NUMPG_SHIFT) + 1;
  58690. + smpriv->top_partition = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  58691. + & SMPART_MAX_PNUM_MASK) >>
  58692. + SMPART_MAX_PNUM_SHIFT) + 1;
  58693. + smpriv->top_page = ((rd_reg32(&ctrlpriv->ctrl->perfmon.smpart)
  58694. + & SMPART_MAX_PG_MASK) >> SMPART_MAX_PG_SHIFT) + 1;
  58695. + smpriv->page_size = 1024 << ((rd_reg32(&ctrlpriv->ctrl->perfmon.smvid)
  58696. + & SMVID_PG_SIZE_MASK) >> SMVID_PG_SIZE_SHIFT);
  58697. + smpriv->slot_size = 1 << CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE;
  58698. +
  58699. +#ifdef SM_DEBUG
  58700. + dev_info(smdev, "max pages = %d, top partition = %d\n",
  58701. + smpriv->max_pages, smpriv->top_partition);
  58702. + dev_info(smdev, "top page = %d, page size = %d (total = %d)\n",
  58703. + smpriv->top_page, smpriv->page_size,
  58704. + smpriv->top_page * smpriv->page_size);
  58705. + dev_info(smdev, "selected slot size = %d\n", smpriv->slot_size);
  58706. +#endif
  58707. +
  58708. + /*
  58709. + * Now probe for partitions/pages to which we have access. Note that
  58710. + * these have likely been set up by a bootloader or platform
  58711. + * provisioning application, so we have to assume that we "inherit"
  58712. + * a configuration and work within the constraints of what it might be.
  58713. + *
  58714. + * Assume use of the zeroth ring in the present iteration (until
  58715. + * we can divorce the controller and ring drivers, and then assign
  58716. + * an SM instance to any ring instance).
  58717. + */
  58718. + smpriv->smringdev = ctrlpriv->jrdev[0];
  58719. + jrpriv = dev_get_drvdata(smpriv->smringdev);
  58720. + lpagect = 0;
  58721. + lpagedesc = kzalloc(sizeof(struct sm_page_descriptor)
  58722. + * smpriv->max_pages, GFP_KERNEL);
  58723. + if (lpagedesc == NULL) {
  58724. + kfree(smpriv);
  58725. + return -ENOMEM;
  58726. + }
  58727. +
  58728. + for (page = 0; page < smpriv->max_pages; page++) {
  58729. + wr_reg32(&jrpriv->rregs->sm_cmd,
  58730. + ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) |
  58731. + (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK));
  58732. + pgstat = rd_reg32(&jrpriv->rregs->sm_status);
  58733. + if (((pgstat & SMCS_PGWON_MASK) >> SMCS_PGOWN_SHIFT)
  58734. + == SMCS_PGOWN_OWNED) { /* our page? */
  58735. + lpagedesc[page].phys_pagenum =
  58736. + (pgstat & SMCS_PAGE_MASK) >> SMCS_PAGE_SHIFT;
  58737. + lpagedesc[page].own_part =
  58738. + (pgstat & SMCS_PART_SHIFT) >> SMCS_PART_MASK;
  58739. + lpagedesc[page].pg_base = ctrlpriv->sm_base +
  58740. + ((smpriv->page_size * page) / sizeof(u32));
  58741. + lpagect++;
  58742. +#ifdef SM_DEBUG
  58743. + dev_info(smdev,
  58744. + "physical page %d, owning partition = %d\n",
  58745. + lpagedesc[page].phys_pagenum,
  58746. + lpagedesc[page].own_part);
  58747. +#endif
  58748. + }
  58749. + }
  58750. +
  58751. + smpriv->pagedesc = kzalloc(sizeof(struct sm_page_descriptor) * lpagect,
  58752. + GFP_KERNEL);
  58753. + if (smpriv->pagedesc == NULL) {
  58754. + kfree(lpagedesc);
  58755. + kfree(smpriv);
  58756. + return -ENOMEM;
  58757. + }
  58758. + smpriv->localpages = lpagect;
  58759. +
  58760. + detectedpage = 0;
  58761. + for (page = 0; page < smpriv->max_pages; page++) {
  58762. + if (lpagedesc[page].pg_base != NULL) { /* e.g. live entry */
  58763. + memcpy(&smpriv->pagedesc[detectedpage],
  58764. + &lpagedesc[page],
  58765. + sizeof(struct sm_page_descriptor));
  58766. +#ifdef SM_DEBUG_CONT
  58767. + sm_show_page(smdev, &smpriv->pagedesc[detectedpage]);
  58768. +#endif
  58769. + detectedpage++;
  58770. + }
  58771. + }
  58772. +
  58773. + kfree(lpagedesc);
  58774. +
  58775. + sm_init_keystore(smdev);
  58776. +
  58777. + return 0;
  58778. +}
  58779. +
  58780. +void caam_sm_shutdown(struct platform_device *pdev)
  58781. +{
  58782. + struct device *ctrldev, *smdev;
  58783. + struct caam_drv_private *priv;
  58784. + struct caam_drv_private_sm *smpriv;
  58785. +
  58786. + ctrldev = &pdev->dev;
  58787. + priv = dev_get_drvdata(ctrldev);
  58788. + smdev = priv->smdev;
  58789. + smpriv = dev_get_drvdata(smdev);
  58790. +
  58791. + kfree(smpriv->pagedesc);
  58792. + kfree(smpriv);
  58793. +}
  58794. +EXPORT_SYMBOL(caam_sm_shutdown);
  58795. +#ifdef CONFIG_OF
  58796. +static void __exit caam_sm_exit(void)
  58797. +{
  58798. + struct device_node *dev_node;
  58799. + struct platform_device *pdev;
  58800. +
  58801. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  58802. + if (!dev_node) {
  58803. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  58804. + if (!dev_node)
  58805. + return;
  58806. + }
  58807. +
  58808. + pdev = of_find_device_by_node(dev_node);
  58809. + if (!pdev)
  58810. + return;
  58811. +
  58812. + of_node_put(dev_node);
  58813. +
  58814. + caam_sm_shutdown(pdev);
  58815. +
  58816. + return;
  58817. +}
  58818. +
  58819. +static int __init caam_sm_init(void)
  58820. +{
  58821. + struct device_node *dev_node;
  58822. + struct platform_device *pdev;
  58823. +
  58824. + /*
  58825. + * Do of_find_compatible_node() then of_find_device_by_node()
  58826. + * once a functional device tree is available
  58827. + */
  58828. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  58829. + if (!dev_node) {
  58830. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  58831. + if (!dev_node)
  58832. + return -ENODEV;
  58833. + }
  58834. +
  58835. + pdev = of_find_device_by_node(dev_node);
  58836. + if (!pdev)
  58837. + return -ENODEV;
  58838. +
  58839. + of_node_get(dev_node);
  58840. +
  58841. + caam_sm_startup(pdev);
  58842. +
  58843. + return 0;
  58844. +}
  58845. +
  58846. +module_init(caam_sm_init);
  58847. +module_exit(caam_sm_exit);
  58848. +
  58849. +MODULE_LICENSE("Dual BSD/GPL");
  58850. +MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore");
  58851. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  58852. +#endif
  58853. diff -Nur linux-3.14.17/drivers/crypto/caam/sm_test.c linux-imx6-3.14/drivers/crypto/caam/sm_test.c
  58854. --- linux-3.14.17/drivers/crypto/caam/sm_test.c 1970-01-01 01:00:00.000000000 +0100
  58855. +++ linux-imx6-3.14/drivers/crypto/caam/sm_test.c 2014-09-11 18:06:00.066030242 +0200
  58856. @@ -0,0 +1,844 @@
  58857. +/*
  58858. + * Secure Memory / Keystore Exemplification Module
  58859. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  58860. + *
  58861. + * Serves as a functional example, and as a self-contained unit test for
  58862. + * the functionality contained in sm_store.c.
  58863. + *
  58864. + * The example function, caam_sm_example_init(), runs a thread that:
  58865. + *
  58866. + * - initializes a set of fixed keys
  58867. + * - stores one copy in clear buffers
  58868. + * - stores them again in secure memory
  58869. + * - extracts stored keys back out for use
  58870. + * - intializes 3 data buffers for a test:
  58871. + * (1) containing cleartext
  58872. + * (2) to hold ciphertext encrypted with an extracted black key
  58873. + * (3) to hold extracted cleartext decrypted with an equivalent clear key
  58874. + *
  58875. + * The function then builds simple job descriptors that reference the key
  58876. + * material and buffers as initialized, and executes an encryption job
  58877. + * with a black key, and a decryption job using a the same key held in the
  58878. + * clear. The output of the decryption job is compared to the original
  58879. + * cleartext; if they don't compare correctly, one can assume a key problem
  58880. + * exists, where the function will exit with an error.
  58881. + *
  58882. + * This module can use a substantial amount of refactoring, which may occur
  58883. + * after the API gets some mileage. Furthermore, expect this module to
  58884. + * eventually disappear once the API is integrated into "real" software.
  58885. + */
  58886. +
  58887. +#include "compat.h"
  58888. +#include "intern.h"
  58889. +#include "desc.h"
  58890. +#include "error.h"
  58891. +#include "jr.h"
  58892. +#include "sm.h"
  58893. +
  58894. +static u8 skeymod[] = {
  58895. + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
  58896. + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
  58897. +};
  58898. +static u8 symkey[] = {
  58899. + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  58900. + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  58901. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  58902. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  58903. +};
  58904. +
  58905. +static u8 symdata[] = {
  58906. + 0x00, 0x01, 0x02, 0x03, 0x04, 0x0f, 0x06, 0x07,
  58907. + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  58908. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  58909. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  58910. + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  58911. + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  58912. + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  58913. + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  58914. + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  58915. + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  58916. + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  58917. + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  58918. + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  58919. + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
  58920. + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
  58921. + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  58922. + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  58923. + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  58924. + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  58925. + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  58926. + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  58927. + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  58928. + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  58929. + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  58930. + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  58931. + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  58932. + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  58933. + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  58934. + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  58935. + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  58936. + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  58937. + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  58938. +};
  58939. +
  58940. +static int mk_job_desc(u32 *desc, dma_addr_t key, u16 keysz, dma_addr_t indata,
  58941. + dma_addr_t outdata, u16 sz, u32 cipherdir, u32 keymode)
  58942. +{
  58943. + desc[1] = CMD_KEY | CLASS_1 | (keysz & KEY_LENGTH_MASK) | keymode;
  58944. + desc[2] = (u32)key;
  58945. + desc[3] = CMD_OPERATION | OP_TYPE_CLASS1_ALG | OP_ALG_AAI_ECB |
  58946. + cipherdir;
  58947. + desc[4] = CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 |
  58948. + FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1 | sz;
  58949. + desc[5] = (u32)indata;
  58950. + desc[6] = CMD_FIFO_STORE | FIFOST_TYPE_MESSAGE_DATA | sz;
  58951. + desc[7] = (u32)outdata;
  58952. +
  58953. + desc[0] = CMD_DESC_HDR | HDR_ONE | (8 & HDR_DESCLEN_MASK);
  58954. + return 8 * sizeof(u32);
  58955. +}
  58956. +
  58957. +struct exec_test_result {
  58958. + int error;
  58959. + struct completion completion;
  58960. +};
  58961. +
  58962. +void exec_test_done(struct device *dev, u32 *desc, u32 err, void *context)
  58963. +{
  58964. + struct exec_test_result *res = context;
  58965. +
  58966. + if (err) {
  58967. + char tmp[CAAM_ERROR_STR_MAX];
  58968. + dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
  58969. + }
  58970. +
  58971. + res->error = err;
  58972. + complete(&res->completion);
  58973. +}
  58974. +
  58975. +static int exec_test_job(struct device *ksdev, u32 *jobdesc)
  58976. +{
  58977. + struct exec_test_result testres;
  58978. + struct caam_drv_private_sm *kspriv;
  58979. + int rtn = 0;
  58980. +
  58981. + kspriv = dev_get_drvdata(ksdev);
  58982. +
  58983. + init_completion(&testres.completion);
  58984. +
  58985. + rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, exec_test_done,
  58986. + &testres);
  58987. + if (!rtn) {
  58988. + wait_for_completion_interruptible(&testres.completion);
  58989. + rtn = testres.error;
  58990. + }
  58991. + return rtn;
  58992. +}
  58993. +
  58994. +
  58995. +int caam_sm_example_init(struct platform_device *pdev)
  58996. +{
  58997. + struct device *ctrldev, *ksdev;
  58998. + struct caam_drv_private *ctrlpriv;
  58999. + struct caam_drv_private_sm *kspriv;
  59000. + u32 unit, units, jdescsz;
  59001. + int stat, jstat, rtnval = 0;
  59002. + u8 __iomem *syminp, *symint, *symout = NULL;
  59003. + dma_addr_t syminp_dma, symint_dma, symout_dma;
  59004. + u8 __iomem *black_key_des, *black_key_aes128;
  59005. + u8 __iomem *black_key_aes256;
  59006. + dma_addr_t black_key_des_dma, black_key_aes128_dma;
  59007. + dma_addr_t black_key_aes256_dma;
  59008. + u8 __iomem *clear_key_des, *clear_key_aes128, *clear_key_aes256;
  59009. + dma_addr_t clear_key_des_dma, clear_key_aes128_dma;
  59010. + dma_addr_t clear_key_aes256_dma;
  59011. + u32 __iomem *jdesc;
  59012. + u32 keyslot_des, keyslot_aes128, keyslot_aes256 = 0;
  59013. +
  59014. + jdesc = NULL;
  59015. + black_key_des = black_key_aes128 = black_key_aes256 = NULL;
  59016. + clear_key_des = clear_key_aes128 = clear_key_aes256 = NULL;
  59017. +
  59018. + /* We can lose this cruft once we can get a pdev by name */
  59019. + ctrldev = &pdev->dev;
  59020. + ctrlpriv = dev_get_drvdata(ctrldev);
  59021. + ksdev = ctrlpriv->smdev;
  59022. + kspriv = dev_get_drvdata(ksdev);
  59023. + if (kspriv == NULL)
  59024. + return -ENODEV;
  59025. +
  59026. + /* Now that we have the dev for the single SM instance, connect */
  59027. +#ifdef SM_TEST_DETAIL
  59028. + dev_info(ksdev, "caam_sm_test_init() running\n");
  59029. +#endif
  59030. + /* Probe to see what keystores are available to us */
  59031. + units = sm_detect_keystore_units(ksdev);
  59032. + if (!units)
  59033. + dev_err(ksdev, "caam_sm_test: no keystore units available\n");
  59034. +
  59035. + /*
  59036. + * MX6 bootloader stores some stuff in unit 0, so let's
  59037. + * use 1 or above
  59038. + */
  59039. + if (units < 2) {
  59040. + dev_err(ksdev, "caam_sm_test: insufficient keystore units\n");
  59041. + return -ENODEV;
  59042. + }
  59043. + unit = 1;
  59044. +
  59045. +#ifdef SM_TEST_DETAIL
  59046. + dev_info(ksdev, "caam_sm_test: %d keystore units available\n", units);
  59047. +#endif
  59048. +
  59049. + /* Initialize/Establish Keystore */
  59050. + sm_establish_keystore(ksdev, unit); /* Initalize store in #1 */
  59051. +
  59052. + /*
  59053. + * Top of main test thread
  59054. + */
  59055. +
  59056. + /* Allocate test data blocks (input, intermediate, output) */
  59057. + syminp = kmalloc(256, GFP_KERNEL | GFP_DMA);
  59058. + symint = kmalloc(256, GFP_KERNEL | GFP_DMA);
  59059. + symout = kmalloc(256, GFP_KERNEL | GFP_DMA);
  59060. + if ((syminp == NULL) || (symint == NULL) || (symout == NULL)) {
  59061. + rtnval = -ENOMEM;
  59062. + dev_err(ksdev, "caam_sm_test: can't get test data buffers\n");
  59063. + goto freemem;
  59064. + }
  59065. +
  59066. + /* Allocate storage for 3 black keys: encapsulated 8, 16, 32 */
  59067. + black_key_des = kmalloc(16, GFP_KERNEL | GFP_DMA); /* padded to 16... */
  59068. + black_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  59069. + black_key_aes256 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  59070. + if ((black_key_des == NULL) || (black_key_aes128 == NULL) ||
  59071. + (black_key_aes256 == NULL)) {
  59072. + rtnval = -ENOMEM;
  59073. + dev_err(ksdev, "caam_sm_test: can't black key buffers\n");
  59074. + goto freemem;
  59075. + }
  59076. +
  59077. + clear_key_des = kmalloc(8, GFP_KERNEL | GFP_DMA);
  59078. + clear_key_aes128 = kmalloc(16, GFP_KERNEL | GFP_DMA);
  59079. + clear_key_aes256 = kmalloc(32, GFP_KERNEL | GFP_DMA);
  59080. + if ((clear_key_des == NULL) || (clear_key_aes128 == NULL) ||
  59081. + (clear_key_aes256 == NULL)) {
  59082. + rtnval = -ENOMEM;
  59083. + dev_err(ksdev, "caam_sm_test: can't get clear key buffers\n");
  59084. + goto freemem;
  59085. + }
  59086. +
  59087. + /* Allocate storage for job descriptor */
  59088. + jdesc = kmalloc(8 * sizeof(u32), GFP_KERNEL | GFP_DMA);
  59089. + if (jdesc == NULL) {
  59090. + rtnval = -ENOMEM;
  59091. + dev_err(ksdev, "caam_sm_test: can't get descriptor buffers\n");
  59092. + goto freemem;
  59093. + }
  59094. +
  59095. +#ifdef SM_TEST_DETAIL
  59096. + dev_info(ksdev, "caam_sm_test: all buffers allocated\n");
  59097. +#endif
  59098. +
  59099. + /* Load up input data block, clear outputs */
  59100. + memcpy(syminp, symdata, 256);
  59101. + memset(symint, 0, 256);
  59102. + memset(symout, 0, 256);
  59103. +#ifdef SM_TEST_DETAIL
  59104. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59105. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59106. + syminp[0], syminp[1], syminp[2], syminp[3],
  59107. + syminp[4], syminp[5], syminp[6], syminp[7]);
  59108. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59109. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59110. + symint[0], symint[1], symint[2], symint[3],
  59111. + symint[4], symint[5], symint[6], symint[7]);
  59112. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59113. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59114. + symout[0], symout[1], symout[2], symout[3],
  59115. + symout[4], symout[5], symout[6], symout[7]);
  59116. +
  59117. + dev_info(ksdev, "caam_sm_test: data buffers initialized\n");
  59118. +#endif
  59119. +
  59120. + /* Load up clear keys */
  59121. + memcpy(clear_key_des, symkey, 8);
  59122. + memcpy(clear_key_aes128, symkey, 16);
  59123. + memcpy(clear_key_aes256, symkey, 32);
  59124. +
  59125. +#ifdef SM_TEST_DETAIL
  59126. + dev_info(ksdev, "caam_sm_test: all clear keys loaded\n");
  59127. +#endif
  59128. +
  59129. + /*
  59130. + * Place clear keys in keystore.
  59131. + * All the interesting stuff happens here.
  59132. + */
  59133. + /* 8 bit DES key */
  59134. + stat = sm_keystore_slot_alloc(ksdev, unit, 8, &keyslot_des);
  59135. + if (stat)
  59136. + goto freemem;
  59137. +#ifdef SM_TEST_DETAIL
  59138. + dev_info(ksdev, "caam_sm_test: 8 byte key slot in %d\n", keyslot_des);
  59139. +#endif
  59140. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_des, clear_key_des,
  59141. + 8);
  59142. + if (stat) {
  59143. +#ifdef SM_TEST_DETAIL
  59144. + dev_info(ksdev, "caam_sm_test: can't load 8 byte key in %d\n",
  59145. + keyslot_des);
  59146. +#endif
  59147. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  59148. + goto freemem;
  59149. + }
  59150. +
  59151. + /* 16 bit AES key */
  59152. + stat = sm_keystore_slot_alloc(ksdev, unit, 16, &keyslot_aes128);
  59153. + if (stat) {
  59154. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  59155. + goto freemem;
  59156. + }
  59157. +#ifdef SM_TEST_DETAIL
  59158. + dev_info(ksdev, "caam_sm_test: 16 byte key slot in %d\n",
  59159. + keyslot_aes128);
  59160. +#endif
  59161. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes128,
  59162. + clear_key_aes128, 16);
  59163. + if (stat) {
  59164. +#ifdef SM_TEST_DETAIL
  59165. + dev_info(ksdev, "caam_sm_test: can't load 16 byte key in %d\n",
  59166. + keyslot_aes128);
  59167. +#endif
  59168. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  59169. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  59170. + goto freemem;
  59171. + }
  59172. +
  59173. + /* 32 bit AES key */
  59174. + stat = sm_keystore_slot_alloc(ksdev, unit, 32, &keyslot_aes256);
  59175. + if (stat) {
  59176. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  59177. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  59178. + goto freemem;
  59179. + }
  59180. +#ifdef SM_TEST_DETAIL
  59181. + dev_info(ksdev, "caam_sm_test: 32 byte key slot in %d\n",
  59182. + keyslot_aes256);
  59183. +#endif
  59184. + stat = sm_keystore_slot_load(ksdev, unit, keyslot_aes256,
  59185. + clear_key_aes256, 32);
  59186. + if (stat) {
  59187. +#ifdef SM_TEST_DETAIL
  59188. + dev_info(ksdev, "caam_sm_test: can't load 32 byte key in %d\n",
  59189. + keyslot_aes128);
  59190. +#endif
  59191. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
  59192. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  59193. + sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  59194. + goto freemem;
  59195. + }
  59196. +
  59197. + /* Encapsulate all keys as SM blobs */
  59198. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_des,
  59199. + keyslot_des, 8, skeymod, 8);
  59200. + if (stat) {
  59201. + dev_info(ksdev, "caam_sm_test: can't encapsulate DES key\n");
  59202. + goto freekeys;
  59203. + }
  59204. +
  59205. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes128,
  59206. + keyslot_aes128, 16, skeymod, 8);
  59207. + if (stat) {
  59208. + dev_info(ksdev, "caam_sm_test: can't encapsulate AES128 key\n");
  59209. + goto freekeys;
  59210. + }
  59211. +
  59212. + stat = sm_keystore_slot_encapsulate(ksdev, unit, keyslot_aes256,
  59213. + keyslot_aes256, 32, skeymod, 8);
  59214. + if (stat) {
  59215. + dev_info(ksdev, "caam_sm_test: can't encapsulate AES256 key\n");
  59216. + goto freekeys;
  59217. + }
  59218. +
  59219. + /* Now decapsulate as black key blobs */
  59220. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_des,
  59221. + keyslot_des, 8, skeymod, 8);
  59222. + if (stat) {
  59223. + dev_info(ksdev, "caam_sm_test: can't decapsulate DES key\n");
  59224. + goto freekeys;
  59225. + }
  59226. +
  59227. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes128,
  59228. + keyslot_aes128, 16, skeymod, 8);
  59229. + if (stat) {
  59230. + dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
  59231. + goto freekeys;
  59232. + }
  59233. +
  59234. + stat = sm_keystore_slot_decapsulate(ksdev, unit, keyslot_aes256,
  59235. + keyslot_aes256, 32, skeymod, 8);
  59236. + if (stat) {
  59237. + dev_info(ksdev, "caam_sm_test: can't decapsulate AES128 key\n");
  59238. + goto freekeys;
  59239. + }
  59240. +
  59241. + /* Extract 8/16/32 byte black keys */
  59242. + sm_keystore_slot_read(ksdev, unit, keyslot_des, 8, black_key_des);
  59243. + sm_keystore_slot_read(ksdev, unit, keyslot_aes128, 16,
  59244. + black_key_aes128);
  59245. + sm_keystore_slot_read(ksdev, unit, keyslot_aes256, 32,
  59246. + black_key_aes256);
  59247. +
  59248. +#ifdef SM_TEST_DETAIL
  59249. + dev_info(ksdev, "caam_sm_test: all black keys extracted\n");
  59250. +#endif
  59251. +
  59252. + /* DES encrypt using 8 byte black key */
  59253. + black_key_des_dma = dma_map_single(ksdev, black_key_des, 8,
  59254. + DMA_TO_DEVICE);
  59255. + dma_sync_single_for_device(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
  59256. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  59257. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  59258. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  59259. +
  59260. + jdescsz = mk_job_desc(jdesc, black_key_des_dma, 8, syminp_dma,
  59261. + symint_dma, 256,
  59262. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_DES, 0);
  59263. +
  59264. +#ifdef SM_TEST_DETAIL
  59265. + dev_info(ksdev, "jobdesc:\n");
  59266. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  59267. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  59268. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  59269. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  59270. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  59271. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  59272. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  59273. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  59274. +#endif
  59275. +
  59276. + jstat = exec_test_job(ksdev, jdesc);
  59277. +
  59278. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  59279. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  59280. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  59281. + dma_unmap_single(ksdev, black_key_des_dma, 8, DMA_TO_DEVICE);
  59282. +
  59283. +#ifdef SM_TEST_DETAIL
  59284. + dev_info(ksdev, "input block:\n");
  59285. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59286. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59287. + syminp[0], syminp[1], syminp[2], syminp[3],
  59288. + syminp[4], syminp[5], syminp[6], syminp[7]);
  59289. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59290. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59291. + syminp[8], syminp[9], syminp[10], syminp[11],
  59292. + syminp[12], syminp[13], syminp[14], syminp[15]);
  59293. + dev_info(ksdev, "intermediate block:\n");
  59294. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59295. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59296. + symint[0], symint[1], symint[2], symint[3],
  59297. + symint[4], symint[5], symint[6], symint[7]);
  59298. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59299. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59300. + symint[8], symint[9], symint[10], symint[11],
  59301. + symint[12], symint[13], symint[14], symint[15]);
  59302. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 8 byte key\n");
  59303. +#endif
  59304. +
  59305. + /* DES decrypt using 8 byte clear key */
  59306. + clear_key_des_dma = dma_map_single(ksdev, clear_key_des, 8,
  59307. + DMA_TO_DEVICE);
  59308. + dma_sync_single_for_device(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
  59309. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  59310. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  59311. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  59312. +
  59313. + jdescsz = mk_job_desc(jdesc, clear_key_des_dma, 8, symint_dma,
  59314. + symout_dma, 256,
  59315. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_DES, 0);
  59316. +
  59317. +#ifdef SM_TEST_DETAIL
  59318. + dev_info(ksdev, "jobdesc:\n");
  59319. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  59320. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  59321. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  59322. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  59323. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  59324. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  59325. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  59326. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  59327. +#endif
  59328. +
  59329. + jstat = exec_test_job(ksdev, jdesc);
  59330. +
  59331. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  59332. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  59333. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  59334. + dma_unmap_single(ksdev, clear_key_des_dma, 8, DMA_TO_DEVICE);
  59335. +
  59336. +#ifdef SM_TEST_DETAIL
  59337. + dev_info(ksdev, "intermediate block:\n");
  59338. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59339. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59340. + symint[0], symint[1], symint[2], symint[3],
  59341. + symint[4], symint[5], symint[6], symint[7]);
  59342. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59343. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59344. + symint[8], symint[9], symint[10], symint[11],
  59345. + symint[12], symint[13], symint[14], symint[15]);
  59346. + dev_info(ksdev, "decrypted block:\n");
  59347. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59348. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59349. + symout[0], symout[1], symout[2], symout[3],
  59350. + symout[4], symout[5], symout[6], symout[7]);
  59351. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59352. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59353. + symout[8], symout[9], symout[10], symout[11],
  59354. + symout[12], symout[13], symout[14], symout[15]);
  59355. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 8 byte key\n");
  59356. +#endif
  59357. +
  59358. + /* Check result */
  59359. + if (memcmp(symout, syminp, 256)) {
  59360. + dev_info(ksdev, "caam_sm_test: 8-byte key test mismatch\n");
  59361. + rtnval = -1;
  59362. + goto freekeys;
  59363. + } else
  59364. + dev_info(ksdev, "caam_sm_test: 8-byte key test match OK\n");
  59365. +
  59366. + /* AES-128 encrypt using 16 byte black key */
  59367. + black_key_aes128_dma = dma_map_single(ksdev, black_key_aes128, 16,
  59368. + DMA_TO_DEVICE);
  59369. + dma_sync_single_for_device(ksdev, black_key_aes128_dma, 16,
  59370. + DMA_TO_DEVICE);
  59371. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  59372. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  59373. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  59374. +
  59375. + jdescsz = mk_job_desc(jdesc, black_key_aes128_dma, 16, syminp_dma,
  59376. + symint_dma, 256,
  59377. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
  59378. +
  59379. +#ifdef SM_TEST_DETAIL
  59380. + dev_info(ksdev, "jobdesc:\n");
  59381. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  59382. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  59383. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  59384. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  59385. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  59386. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  59387. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  59388. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  59389. +#endif
  59390. +
  59391. + jstat = exec_test_job(ksdev, jdesc);
  59392. +
  59393. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  59394. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  59395. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  59396. + dma_unmap_single(ksdev, black_key_aes128_dma, 16, DMA_TO_DEVICE);
  59397. +
  59398. +#ifdef SM_TEST_DETAIL
  59399. + dev_info(ksdev, "input block:\n");
  59400. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59401. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59402. + syminp[0], syminp[1], syminp[2], syminp[3],
  59403. + syminp[4], syminp[5], syminp[6], syminp[7]);
  59404. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59405. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59406. + syminp[8], syminp[9], syminp[10], syminp[11],
  59407. + syminp[12], syminp[13], syminp[14], syminp[15]);
  59408. + dev_info(ksdev, "intermediate block:\n");
  59409. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59410. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59411. + symint[0], symint[1], symint[2], symint[3],
  59412. + symint[4], symint[5], symint[6], symint[7]);
  59413. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59414. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59415. + symint[8], symint[9], symint[10], symint[11],
  59416. + symint[12], symint[13], symint[14], symint[15]);
  59417. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 16 byte key\n");
  59418. +#endif
  59419. +
  59420. + /* AES-128 decrypt using 16 byte clear key */
  59421. + clear_key_aes128_dma = dma_map_single(ksdev, clear_key_aes128, 16,
  59422. + DMA_TO_DEVICE);
  59423. + dma_sync_single_for_device(ksdev, clear_key_aes128_dma, 16,
  59424. + DMA_TO_DEVICE);
  59425. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  59426. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  59427. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  59428. +
  59429. + jdescsz = mk_job_desc(jdesc, clear_key_aes128_dma, 16, symint_dma,
  59430. + symout_dma, 256,
  59431. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
  59432. +
  59433. +#ifdef SM_TEST_DETAIL
  59434. + dev_info(ksdev, "jobdesc:\n");
  59435. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  59436. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  59437. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  59438. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  59439. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  59440. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  59441. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  59442. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  59443. +#endif
  59444. + jstat = exec_test_job(ksdev, jdesc);
  59445. +
  59446. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  59447. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  59448. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  59449. + dma_unmap_single(ksdev, clear_key_aes128_dma, 16, DMA_TO_DEVICE);
  59450. +
  59451. +#ifdef SM_TEST_DETAIL
  59452. + dev_info(ksdev, "intermediate block:\n");
  59453. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59454. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59455. + symint[0], symint[1], symint[2], symint[3],
  59456. + symint[4], symint[5], symint[6], symint[7]);
  59457. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59458. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59459. + symint[8], symint[9], symint[10], symint[11],
  59460. + symint[12], symint[13], symint[14], symint[15]);
  59461. + dev_info(ksdev, "decrypted block:\n");
  59462. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59463. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59464. + symout[0], symout[1], symout[2], symout[3],
  59465. + symout[4], symout[5], symout[6], symout[7]);
  59466. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59467. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59468. + symout[8], symout[9], symout[10], symout[11],
  59469. + symout[12], symout[13], symout[14], symout[15]);
  59470. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 16 byte key\n");
  59471. +#endif
  59472. +
  59473. + /* Check result */
  59474. + if (memcmp(symout, syminp, 256)) {
  59475. + dev_info(ksdev, "caam_sm_test: 16-byte key test mismatch\n");
  59476. + rtnval = -1;
  59477. + goto freekeys;
  59478. + } else
  59479. + dev_info(ksdev, "caam_sm_test: 16-byte key test match OK\n");
  59480. +
  59481. + /* AES-256 encrypt using 32 byte black key */
  59482. + black_key_aes256_dma = dma_map_single(ksdev, black_key_aes256, 32,
  59483. + DMA_TO_DEVICE);
  59484. + dma_sync_single_for_device(ksdev, black_key_aes256_dma, 32,
  59485. + DMA_TO_DEVICE);
  59486. + syminp_dma = dma_map_single(ksdev, syminp, 256, DMA_TO_DEVICE);
  59487. + dma_sync_single_for_device(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  59488. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_FROM_DEVICE);
  59489. +
  59490. + jdescsz = mk_job_desc(jdesc, black_key_aes256_dma, 32, syminp_dma,
  59491. + symint_dma, 256,
  59492. + OP_ALG_ENCRYPT | OP_ALG_ALGSEL_AES, 0);
  59493. +
  59494. +#ifdef SM_TEST_DETAIL
  59495. + dev_info(ksdev, "jobdesc:\n");
  59496. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  59497. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  59498. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  59499. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  59500. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  59501. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  59502. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  59503. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  59504. +#endif
  59505. +
  59506. + jstat = exec_test_job(ksdev, jdesc);
  59507. +
  59508. + dma_sync_single_for_cpu(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  59509. + dma_unmap_single(ksdev, symint_dma, 256, DMA_FROM_DEVICE);
  59510. + dma_unmap_single(ksdev, syminp_dma, 256, DMA_TO_DEVICE);
  59511. + dma_unmap_single(ksdev, black_key_aes256_dma, 32, DMA_TO_DEVICE);
  59512. +
  59513. +#ifdef SM_TEST_DETAIL
  59514. + dev_info(ksdev, "input block:\n");
  59515. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59516. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59517. + syminp[0], syminp[1], syminp[2], syminp[3],
  59518. + syminp[4], syminp[5], syminp[6], syminp[7]);
  59519. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59520. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59521. + syminp[8], syminp[9], syminp[10], syminp[11],
  59522. + syminp[12], syminp[13], syminp[14], syminp[15]);
  59523. + dev_info(ksdev, "intermediate block:\n");
  59524. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59525. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59526. + symint[0], symint[1], symint[2], symint[3],
  59527. + symint[4], symint[5], symint[6], symint[7]);
  59528. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59529. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59530. + symint[8], symint[9], symint[10], symint[11],
  59531. + symint[12], symint[13], symint[14], symint[15]);
  59532. + dev_info(ksdev, "caam_sm_test: encrypt cycle with 32 byte key\n");
  59533. +#endif
  59534. +
  59535. + /* AES-256 decrypt using 32-byte black key */
  59536. + clear_key_aes256_dma = dma_map_single(ksdev, clear_key_aes256, 32,
  59537. + DMA_TO_DEVICE);
  59538. + dma_sync_single_for_device(ksdev, clear_key_aes256_dma, 32,
  59539. + DMA_TO_DEVICE);
  59540. + symint_dma = dma_map_single(ksdev, symint, 256, DMA_TO_DEVICE);
  59541. + dma_sync_single_for_device(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  59542. + symout_dma = dma_map_single(ksdev, symout, 256, DMA_FROM_DEVICE);
  59543. +
  59544. + jdescsz = mk_job_desc(jdesc, clear_key_aes256_dma, 32, symint_dma,
  59545. + symout_dma, 256,
  59546. + OP_ALG_DECRYPT | OP_ALG_ALGSEL_AES, 0);
  59547. +
  59548. +#ifdef SM_TEST_DETAIL
  59549. + dev_info(ksdev, "jobdesc:\n");
  59550. + dev_info(ksdev, "0x%08x\n", jdesc[0]);
  59551. + dev_info(ksdev, "0x%08x\n", jdesc[1]);
  59552. + dev_info(ksdev, "0x%08x\n", jdesc[2]);
  59553. + dev_info(ksdev, "0x%08x\n", jdesc[3]);
  59554. + dev_info(ksdev, "0x%08x\n", jdesc[4]);
  59555. + dev_info(ksdev, "0x%08x\n", jdesc[5]);
  59556. + dev_info(ksdev, "0x%08x\n", jdesc[6]);
  59557. + dev_info(ksdev, "0x%08x\n", jdesc[7]);
  59558. +#endif
  59559. +
  59560. + jstat = exec_test_job(ksdev, jdesc);
  59561. +
  59562. + dma_sync_single_for_cpu(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  59563. + dma_unmap_single(ksdev, symout_dma, 256, DMA_FROM_DEVICE);
  59564. + dma_unmap_single(ksdev, symint_dma, 256, DMA_TO_DEVICE);
  59565. + dma_unmap_single(ksdev, clear_key_aes256_dma, 32, DMA_TO_DEVICE);
  59566. +
  59567. +#ifdef SM_TEST_DETAIL
  59568. + dev_info(ksdev, "intermediate block:\n");
  59569. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59570. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59571. + symint[0], symint[1], symint[2], symint[3],
  59572. + symint[4], symint[5], symint[6], symint[7]);
  59573. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59574. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59575. + symint[8], symint[9], symint[10], symint[11],
  59576. + symint[12], symint[13], symint[14], symint[15]);
  59577. + dev_info(ksdev, "decrypted block:\n");
  59578. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59579. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59580. + symout[0], symout[1], symout[2], symout[3],
  59581. + symout[4], symout[5], symout[6], symout[7]);
  59582. + dev_info(ksdev, "0x%02x 0x%02x 0x%02x 0x%02x " \
  59583. + "0x%02x 0x%02x 0x%02x 0x%02x\n",
  59584. + symout[8], symout[9], symout[10], symout[11],
  59585. + symout[12], symout[13], symout[14], symout[15]);
  59586. + dev_info(ksdev, "caam_sm_test: decrypt cycle with 32 byte key\n");
  59587. +#endif
  59588. +
  59589. + /* Check result */
  59590. + if (memcmp(symout, syminp, 256)) {
  59591. + dev_info(ksdev, "caam_sm_test: 32-byte key test mismatch\n");
  59592. + rtnval = -1;
  59593. + goto freekeys;
  59594. + } else
  59595. + dev_info(ksdev, "caam_sm_test: 32-byte key test match OK\n");
  59596. +
  59597. +
  59598. + /* Remove 8/16/32 byte keys from keystore */
  59599. +freekeys:
  59600. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_des);
  59601. + if (stat)
  59602. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  59603. + keyslot_des);
  59604. +
  59605. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes128);
  59606. + if (stat)
  59607. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  59608. + keyslot_aes128);
  59609. +
  59610. + stat = sm_keystore_slot_dealloc(ksdev, unit, keyslot_aes256);
  59611. + if (stat)
  59612. + dev_info(ksdev, "caam_sm_test: can't release slot %d\n",
  59613. + keyslot_aes256);
  59614. +
  59615. +
  59616. + /* Free resources */
  59617. +freemem:
  59618. +#ifdef SM_TEST_DETAIL
  59619. + dev_info(ksdev, "caam_sm_test: cleaning up\n");
  59620. +#endif
  59621. + kfree(syminp);
  59622. + kfree(symint);
  59623. + kfree(symout);
  59624. + kfree(clear_key_des);
  59625. + kfree(clear_key_aes128);
  59626. + kfree(clear_key_aes256);
  59627. + kfree(black_key_des);
  59628. + kfree(black_key_aes128);
  59629. + kfree(black_key_aes256);
  59630. + kfree(jdesc);
  59631. +
  59632. + /* Disconnect from keystore and leave */
  59633. + sm_release_keystore(ksdev, unit);
  59634. +
  59635. + return rtnval;
  59636. +}
  59637. +EXPORT_SYMBOL(caam_sm_example_init);
  59638. +
  59639. +void caam_sm_example_shutdown(void)
  59640. +{
  59641. + /* unused in present version */
  59642. + struct device_node *dev_node;
  59643. + struct platform_device *pdev;
  59644. +
  59645. + /*
  59646. + * Do of_find_compatible_node() then of_find_device_by_node()
  59647. + * once a functional device tree is available
  59648. + */
  59649. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  59650. + if (!dev_node) {
  59651. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  59652. + if (!dev_node)
  59653. + return;
  59654. + }
  59655. +
  59656. + pdev = of_find_device_by_node(dev_node);
  59657. + if (!pdev)
  59658. + return;
  59659. +
  59660. + of_node_get(dev_node);
  59661. +
  59662. +}
  59663. +
  59664. +static int __init caam_sm_test_init(void)
  59665. +{
  59666. + struct device_node *dev_node;
  59667. + struct platform_device *pdev;
  59668. +
  59669. + /*
  59670. + * Do of_find_compatible_node() then of_find_device_by_node()
  59671. + * once a functional device tree is available
  59672. + */
  59673. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
  59674. + if (!dev_node) {
  59675. + dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
  59676. + if (!dev_node)
  59677. + return -ENODEV;
  59678. + }
  59679. +
  59680. + pdev = of_find_device_by_node(dev_node);
  59681. + if (!pdev)
  59682. + return -ENODEV;
  59683. +
  59684. + of_node_put(dev_node);
  59685. +
  59686. + caam_sm_example_init(pdev);
  59687. +
  59688. + return 0;
  59689. +}
  59690. +
  59691. +
  59692. +/* Module-based initialization needs to wait for dev tree */
  59693. +#ifdef CONFIG_OF
  59694. +module_init(caam_sm_test_init);
  59695. +module_exit(caam_sm_example_shutdown);
  59696. +
  59697. +MODULE_LICENSE("Dual BSD/GPL");
  59698. +MODULE_DESCRIPTION("FSL CAAM Keystore Usage Example");
  59699. +MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD");
  59700. +#endif
  59701. diff -Nur linux-3.14.17/drivers/crypto/caam/snvsregs.h linux-imx6-3.14/drivers/crypto/caam/snvsregs.h
  59702. --- linux-3.14.17/drivers/crypto/caam/snvsregs.h 1970-01-01 01:00:00.000000000 +0100
  59703. +++ linux-imx6-3.14/drivers/crypto/caam/snvsregs.h 2014-09-11 18:06:00.066030242 +0200
  59704. @@ -0,0 +1,237 @@
  59705. +/*
  59706. + * SNVS hardware register-level view
  59707. + *
  59708. + * Copyright (C) 2013 Freescale Semiconductor, Inc., All Rights Reserved
  59709. + */
  59710. +
  59711. +#ifndef SNVSREGS_H
  59712. +#define SNVSREGS_H
  59713. +
  59714. +#include <linux/types.h>
  59715. +#include <linux/io.h>
  59716. +
  59717. +/*
  59718. + * SNVS High Power Domain
  59719. + * Includes security violations, HA counter, RTC, alarm
  59720. + */
  59721. +struct snvs_hp {
  59722. + u32 lock;
  59723. + u32 cmd;
  59724. + u32 ctl;
  59725. + u32 secvio_int_en; /* Security Violation Interrupt Enable */
  59726. + u32 secvio_int_ctl; /* Security Violation Interrupt Control */
  59727. + u32 status;
  59728. + u32 secvio_status; /* Security Violation Status */
  59729. + u32 ha_counteriv; /* High Assurance Counter IV */
  59730. + u32 ha_counter; /* High Assurance Counter */
  59731. + u32 rtc_msb; /* Real Time Clock/Counter MSB */
  59732. + u32 rtc_lsb; /* Real Time Counter LSB */
  59733. + u32 time_alarm_msb; /* Time Alarm MSB */
  59734. + u32 time_alarm_lsb; /* Time Alarm LSB */
  59735. +};
  59736. +
  59737. +#define HP_LOCK_HAC_LCK 0x00040000
  59738. +#define HP_LOCK_HPSICR_LCK 0x00020000
  59739. +#define HP_LOCK_HPSVCR_LCK 0x00010000
  59740. +#define HP_LOCK_MKEYSEL_LCK 0x00000200
  59741. +#define HP_LOCK_TAMPCFG_LCK 0x00000100
  59742. +#define HP_LOCK_TAMPFLT_LCK 0x00000080
  59743. +#define HP_LOCK_SECVIO_LCK 0x00000040
  59744. +#define HP_LOCK_GENP_LCK 0x00000020
  59745. +#define HP_LOCK_MONOCTR_LCK 0x00000010
  59746. +#define HP_LOCK_CALIB_LCK 0x00000008
  59747. +#define HP_LOCK_SRTC_LCK 0x00000004
  59748. +#define HP_LOCK_ZMK_RD_LCK 0x00000002
  59749. +#define HP_LOCK_ZMK_WT_LCK 0x00000001
  59750. +
  59751. +#define HP_CMD_NONPRIV_AXS 0x80000000
  59752. +#define HP_CMD_HAC_STOP 0x00080000
  59753. +#define HP_CMD_HAC_CLEAR 0x00040000
  59754. +#define HP_CMD_HAC_LOAD 0x00020000
  59755. +#define HP_CMD_HAC_CFG_EN 0x00010000
  59756. +#define HP_CMD_SNVS_MSTR_KEY 0x00002000
  59757. +#define HP_CMD_PROG_ZMK 0x00001000
  59758. +#define HP_CMD_SW_LPSV 0x00000400
  59759. +#define HP_CMD_SW_FSV 0x00000200
  59760. +#define HP_CMD_SW_SV 0x00000100
  59761. +#define HP_CMD_LP_SWR_DIS 0x00000020
  59762. +#define HP_CMD_LP_SWR 0x00000010
  59763. +#define HP_CMD_SSM_SFNS_DIS 0x00000004
  59764. +#define HP_CMD_SSM_ST_DIS 0x00000002
  59765. +#define HP_CMD_SMM_ST 0x00000001
  59766. +
  59767. +#define HP_CTL_TIME_SYNC 0x00010000
  59768. +#define HP_CTL_CAL_VAL_SHIFT 10
  59769. +#define HP_CTL_CAL_VAL_MASK (0x1f << HP_CTL_CALIB_SHIFT)
  59770. +#define HP_CTL_CALIB_EN 0x00000100
  59771. +#define HP_CTL_PI_FREQ_SHIFT 4
  59772. +#define HP_CTL_PI_FREQ_MASK (0xf << HP_CTL_PI_FREQ_SHIFT)
  59773. +#define HP_CTL_PI_EN 0x00000008
  59774. +#define HP_CTL_TIMEALARM_EN 0x00000002
  59775. +#define HP_CTL_RTC_EN 0x00000001
  59776. +
  59777. +#define HP_SECVIO_INTEN_EN 0x10000000
  59778. +#define HP_SECVIO_INTEN_SRC5 0x00000020
  59779. +#define HP_SECVIO_INTEN_SRC4 0x00000010
  59780. +#define HP_SECVIO_INTEN_SRC3 0x00000008
  59781. +#define HP_SECVIO_INTEN_SRC2 0x00000004
  59782. +#define HP_SECVIO_INTEN_SRC1 0x00000002
  59783. +#define HP_SECVIO_INTEN_SRC0 0x00000001
  59784. +#define HP_SECVIO_INTEN_ALL 0x8000003f
  59785. +
  59786. +#define HP_SECVIO_ICTL_CFG_SHIFT 30
  59787. +#define HP_SECVIO_ICTL_CFG_MASK (0x3 << HP_SECVIO_ICTL_CFG_SHIFT)
  59788. +#define HP_SECVIO_ICTL_CFG5_SHIFT 5
  59789. +#define HP_SECVIO_ICTL_CFG5_MASK (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT)
  59790. +#define HP_SECVIO_ICTL_CFG_DISABLE 0
  59791. +#define HP_SECVIO_ICTL_CFG_NONFATAL 1
  59792. +#define HP_SECVIO_ICTL_CFG_FATAL 2
  59793. +#define HP_SECVIO_ICTL_CFG4_FATAL 0x00000010
  59794. +#define HP_SECVIO_ICTL_CFG3_FATAL 0x00000008
  59795. +#define HP_SECVIO_ICTL_CFG2_FATAL 0x00000004
  59796. +#define HP_SECVIO_ICTL_CFG1_FATAL 0x00000002
  59797. +#define HP_SECVIO_ICTL_CFG0_FATAL 0x00000001
  59798. +
  59799. +#define HP_STATUS_ZMK_ZERO 0x80000000
  59800. +#define HP_STATUS_OTPMK_ZERO 0x08000000
  59801. +#define HP_STATUS_OTPMK_SYN_SHIFT 16
  59802. +#define HP_STATUS_OTPMK_SYN_MASK (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT)
  59803. +#define HP_STATUS_SSM_ST_SHIFT 8
  59804. +#define HP_STATUS_SSM_ST_MASK (0xf << HP_STATUS_SSM_ST_SHIFT)
  59805. +#define HP_STATUS_SSM_ST_INIT 0
  59806. +#define HP_STATUS_SSM_ST_HARDFAIL 1
  59807. +#define HP_STATUS_SSM_ST_SOFTFAIL 3
  59808. +#define HP_STATUS_SSM_ST_INITINT 8
  59809. +#define HP_STATUS_SSM_ST_CHECK 9
  59810. +#define HP_STATUS_SSM_ST_NONSECURE 11
  59811. +#define HP_STATUS_SSM_ST_TRUSTED 13
  59812. +#define HP_STATUS_SSM_ST_SECURE 15
  59813. +
  59814. +#define HP_SECVIOST_ZMK_ECC_FAIL 0x08000000 /* write to clear */
  59815. +#define HP_SECVIOST_ZMK_SYN_SHIFT 16
  59816. +#define HP_SECVIOST_ZMK_SYN_MASK (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT)
  59817. +#define HP_SECVIOST_SECVIO5 0x00000020
  59818. +#define HP_SECVIOST_SECVIO4 0x00000010
  59819. +#define HP_SECVIOST_SECVIO3 0x00000008
  59820. +#define HP_SECVIOST_SECVIO2 0x00000004
  59821. +#define HP_SECVIOST_SECVIO1 0x00000002
  59822. +#define HP_SECVIOST_SECVIO0 0x00000001
  59823. +#define HP_SECVIOST_SECVIOMASK 0x0000003f
  59824. +
  59825. +/*
  59826. + * SNVS Low Power Domain
  59827. + * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK
  59828. + */
  59829. +struct snvs_lp {
  59830. + u32 lock;
  59831. + u32 ctl;
  59832. + u32 mstr_key_ctl; /* Master Key Control */
  59833. + u32 secvio_ctl; /* Security Violation Control */
  59834. + u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration */
  59835. + u32 tamper_det_cfg; /* Tamper Detectors Configuration */
  59836. + u32 status;
  59837. + u32 srtc_msb; /* Secure Real Time Clock/Counter MSB */
  59838. + u32 srtc_lsb; /* Secure Real Time Clock/Counter LSB */
  59839. + u32 time_alarm; /* Time Alarm */
  59840. + u32 smc_msb; /* Secure Monotonic Counter MSB */
  59841. + u32 smc_lsb; /* Secure Monotonic Counter LSB */
  59842. + u32 pwr_glitch_det; /* Power Glitch Detector */
  59843. + u32 gen_purpose;
  59844. + u32 zmk[8]; /* Zeroizable Master Key */
  59845. +};
  59846. +
  59847. +#define LP_LOCK_MKEYSEL_LCK 0x00000200
  59848. +#define LP_LOCK_TAMPDET_LCK 0x00000100
  59849. +#define LP_LOCK_TAMPFLT_LCK 0x00000080
  59850. +#define LP_LOCK_SECVIO_LCK 0x00000040
  59851. +#define LP_LOCK_GENP_LCK 0x00000020
  59852. +#define LP_LOCK_MONOCTR_LCK 0x00000010
  59853. +#define LP_LOCK_CALIB_LCK 0x00000008
  59854. +#define LP_LOCK_SRTC_LCK 0x00000004
  59855. +#define LP_LOCK_ZMK_RD_LCK 0x00000002
  59856. +#define LP_LOCK_ZMK_WT_LCK 0x00000001
  59857. +
  59858. +#define LP_CTL_CAL_VAL_SHIFT 10
  59859. +#define LP_CTL_CAL_VAL_MASK (0x1f << LP_CTL_CAL_VAL_SHIFT)
  59860. +#define LP_CTL_CALIB_EN 0x00000100
  59861. +#define LP_CTL_SRTC_INVAL_EN 0x00000010
  59862. +#define LP_CTL_WAKE_INT_EN 0x00000008
  59863. +#define LP_CTL_MONOCTR_EN 0x00000004
  59864. +#define LP_CTL_TIMEALARM_EN 0x00000002
  59865. +#define LP_CTL_SRTC_EN 0x00000001
  59866. +
  59867. +#define LP_MKEYCTL_ZMKECC_SHIFT 8
  59868. +#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT)
  59869. +#define LP_MKEYCTL_ZMKECC_EN 0x00000010
  59870. +#define LP_MKEYCTL_ZMKECC_VAL 0x00000008
  59871. +#define LP_MKEYCTL_ZMKECC_PROG 0x00000004
  59872. +#define LP_MKEYCTL_MKSEL_SHIFT 0
  59873. +#define LP_MKEYCTL_MKSEL_MASK (3 << LP_MKEYCTL_MKSEL_SHIFT)
  59874. +#define LP_MKEYCTL_MK_OTP 0
  59875. +#define LP_MKEYCTL_MK_ZMK 2
  59876. +#define LP_MKEYCTL_MK_COMB 3
  59877. +
  59878. +#define LP_SECVIO_CTL_SRC5 0x20
  59879. +#define LP_SECVIO_CTL_SRC4 0x10
  59880. +#define LP_SECVIO_CTL_SRC3 0x08
  59881. +#define LP_SECVIO_CTL_SRC2 0x04
  59882. +#define LP_SECVIO_CTL_SRC1 0x02
  59883. +#define LP_SECVIO_CTL_SRC0 0x01
  59884. +
  59885. +#define LP_TAMPFILT_EXT2_EN 0x80000000
  59886. +#define LP_TAMPFILT_EXT2_SHIFT 24
  59887. +#define LP_TAMPFILT_EXT2_MASK (0x1f << LP_TAMPFILT_EXT2_SHIFT)
  59888. +#define LP_TAMPFILT_EXT1_EN 0x00800000
  59889. +#define LP_TAMPFILT_EXT1_SHIFT 16
  59890. +#define LP_TAMPFILT_EXT1_MASK (0x1f << LP_TAMPFILT_EXT1_SHIFT)
  59891. +#define LP_TAMPFILT_WM_EN 0x00000080
  59892. +#define LP_TAMPFILT_WM_SHIFT 0
  59893. +#define LP_TAMPFILT_WM_MASK (0x1f << LP_TAMPFILT_WM_SHIFT)
  59894. +
  59895. +#define LP_TAMPDET_OSC_BPS 0x10000000
  59896. +#define LP_TAMPDET_VRC_SHIFT 24
  59897. +#define LP_TAMPDET_VRC_MASK (3 << LP_TAMPFILT_VRC_SHIFT)
  59898. +#define LP_TAMPDET_HTDC_SHIFT 20
  59899. +#define LP_TAMPDET_HTDC_MASK (3 << LP_TAMPFILT_HTDC_SHIFT)
  59900. +#define LP_TAMPDET_LTDC_SHIFT 16
  59901. +#define LP_TAMPDET_LTDC_MASK (3 << LP_TAMPFILT_LTDC_SHIFT)
  59902. +#define LP_TAMPDET_POR_OBS 0x00008000
  59903. +#define LP_TAMPDET_PFD_OBS 0x00004000
  59904. +#define LP_TAMPDET_ET2_EN 0x00000400
  59905. +#define LP_TAMPDET_ET1_EN 0x00000200
  59906. +#define LP_TAMPDET_WMT2_EN 0x00000100
  59907. +#define LP_TAMPDET_WMT1_EN 0x00000080
  59908. +#define LP_TAMPDET_VT_EN 0x00000040
  59909. +#define LP_TAMPDET_TT_EN 0x00000020
  59910. +#define LP_TAMPDET_CT_EN 0x00000010
  59911. +#define LP_TAMPDET_MCR_EN 0x00000004
  59912. +#define LP_TAMPDET_SRTCR_EN 0x00000002
  59913. +
  59914. +#define LP_STATUS_SECURE
  59915. +#define LP_STATUS_NONSECURE
  59916. +#define LP_STATUS_SCANEXIT 0x00100000 /* all write 1 clear here on */
  59917. +#define LP_STATUS_EXT_SECVIO 0x00010000
  59918. +#define LP_STATUS_ET2 0x00000400
  59919. +#define LP_STATUS_ET1 0x00000200
  59920. +#define LP_STATUS_WMT2 0x00000100
  59921. +#define LP_STATUS_WMT1 0x00000080
  59922. +#define LP_STATUS_VTD 0x00000040
  59923. +#define LP_STATUS_TTD 0x00000020
  59924. +#define LP_STATUS_CTD 0x00000010
  59925. +#define LP_STATUS_PGD 0x00000008
  59926. +#define LP_STATUS_MCR 0x00000004
  59927. +#define LP_STATUS_SRTCR 0x00000002
  59928. +#define LP_STATUS_LPTA 0x00000001
  59929. +
  59930. +/* Full SNVS register page, including version/options */
  59931. +struct snvs_full {
  59932. + struct snvs_hp hp;
  59933. + struct snvs_lp lp;
  59934. + u32 rsvd[731]; /* deadspace 0x08c-0xbf7 */
  59935. +
  59936. + /* Version / Revision / Option ID space - end of register page */
  59937. + u32 vid; /* 0xbf8 HP Version ID (VID 1) */
  59938. + u32 opt_rev; /* 0xbfc HP Options / Revision (VID 2) */
  59939. +};
  59940. +
  59941. +#endif /* SNVSREGS_H */
  59942. diff -Nur linux-3.14.17/drivers/dma/imx-sdma.c linux-imx6-3.14/drivers/dma/imx-sdma.c
  59943. --- linux-3.14.17/drivers/dma/imx-sdma.c 2014-08-14 03:38:34.000000000 +0200
  59944. +++ linux-imx6-3.14/drivers/dma/imx-sdma.c 2014-09-11 18:06:00.162030626 +0200
  59945. @@ -29,6 +29,7 @@
  59946. #include <linux/semaphore.h>
  59947. #include <linux/spinlock.h>
  59948. #include <linux/device.h>
  59949. +#include <linux/genalloc.h>
  59950. #include <linux/dma-mapping.h>
  59951. #include <linux/firmware.h>
  59952. #include <linux/slab.h>
  59953. @@ -232,6 +233,14 @@
  59954. struct sdma_engine;
  59955. +enum sdma_mode {
  59956. + SDMA_MODE_INVALID = 0,
  59957. + SDMA_MODE_LOOP,
  59958. + SDMA_MODE_NORMAL,
  59959. + SDMA_MODE_P2P,
  59960. + SDMA_MODE_NO_BD,
  59961. +};
  59962. +
  59963. /**
  59964. * struct sdma_channel - housekeeping for a SDMA channel
  59965. *
  59966. @@ -244,6 +253,7 @@
  59967. * @word_size peripheral access size
  59968. * @buf_tail ID of the buffer that was processed
  59969. * @num_bd max NUM_BD. number of descriptors currently handling
  59970. + * @bd_iram flag indicating the memory location of buffer descriptor
  59971. */
  59972. struct sdma_channel {
  59973. struct sdma_engine *sdma;
  59974. @@ -255,14 +265,19 @@
  59975. enum dma_slave_buswidth word_size;
  59976. unsigned int buf_tail;
  59977. unsigned int num_bd;
  59978. + unsigned int period_len;
  59979. struct sdma_buffer_descriptor *bd;
  59980. dma_addr_t bd_phys;
  59981. + bool bd_iram;
  59982. unsigned int pc_from_device, pc_to_device;
  59983. - unsigned long flags;
  59984. - dma_addr_t per_address;
  59985. + unsigned int device_to_device;
  59986. + unsigned int other_script;
  59987. + enum sdma_mode mode;
  59988. + dma_addr_t per_address, per_address2;
  59989. unsigned long event_mask[2];
  59990. unsigned long watermark_level;
  59991. u32 shp_addr, per_addr;
  59992. + u32 data_addr1, data_addr2;
  59993. struct dma_chan chan;
  59994. spinlock_t lock;
  59995. struct dma_async_tx_descriptor desc;
  59996. @@ -272,8 +287,6 @@
  59997. struct tasklet_struct tasklet;
  59998. };
  59999. -#define IMX_DMA_SG_LOOP BIT(0)
  60000. -
  60001. #define MAX_DMA_CHANNELS 32
  60002. #define MXC_SDMA_DEFAULT_PRIORITY 1
  60003. #define MXC_SDMA_MIN_PRIORITY 1
  60004. @@ -325,6 +338,7 @@
  60005. spinlock_t channel_0_lock;
  60006. u32 script_number;
  60007. struct sdma_script_start_addrs *script_addrs;
  60008. + struct gen_pool *iram_pool;
  60009. const struct sdma_driver_data *drvdata;
  60010. };
  60011. @@ -540,12 +554,14 @@
  60012. dma_addr_t buf_phys;
  60013. int ret;
  60014. unsigned long flags;
  60015. + bool use_iram = true;
  60016. - buf_virt = dma_alloc_coherent(NULL,
  60017. - size,
  60018. - &buf_phys, GFP_KERNEL);
  60019. + buf_virt = gen_pool_dma_alloc(sdma->iram_pool, size, &buf_phys);
  60020. if (!buf_virt) {
  60021. - return -ENOMEM;
  60022. + use_iram = false;
  60023. + buf_virt = dma_alloc_coherent(NULL, size, &buf_phys, GFP_KERNEL);
  60024. + if (!buf_virt)
  60025. + return -ENOMEM;
  60026. }
  60027. spin_lock_irqsave(&sdma->channel_0_lock, flags);
  60028. @@ -562,7 +578,10 @@
  60029. spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
  60030. - dma_free_coherent(NULL, size, buf_virt, buf_phys);
  60031. + if (use_iram)
  60032. + gen_pool_free(sdma->iram_pool, (unsigned long)buf_virt, size);
  60033. + else
  60034. + dma_free_coherent(NULL, size, buf_virt, buf_phys);
  60035. return ret;
  60036. }
  60037. @@ -593,6 +612,12 @@
  60038. static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
  60039. {
  60040. + if (sdmac->desc.callback)
  60041. + sdmac->desc.callback(sdmac->desc.callback_param);
  60042. +}
  60043. +
  60044. +static void sdma_update_channel_loop(struct sdma_channel *sdmac)
  60045. +{
  60046. struct sdma_buffer_descriptor *bd;
  60047. /*
  60048. @@ -607,15 +632,10 @@
  60049. if (bd->mode.status & BD_RROR)
  60050. sdmac->status = DMA_ERROR;
  60051. - else
  60052. - sdmac->status = DMA_IN_PROGRESS;
  60053. bd->mode.status |= BD_DONE;
  60054. sdmac->buf_tail++;
  60055. sdmac->buf_tail %= sdmac->num_bd;
  60056. -
  60057. - if (sdmac->desc.callback)
  60058. - sdmac->desc.callback(sdmac->desc.callback_param);
  60059. }
  60060. }
  60061. @@ -647,14 +667,31 @@
  60062. sdmac->desc.callback(sdmac->desc.callback_param);
  60063. }
  60064. +static void sdma_handle_other_intr(struct sdma_channel *sdmac)
  60065. +{
  60066. + if (sdmac->desc.callback)
  60067. + sdmac->desc.callback(sdmac->desc.callback_param);
  60068. +}
  60069. +
  60070. static void sdma_tasklet(unsigned long data)
  60071. {
  60072. struct sdma_channel *sdmac = (struct sdma_channel *) data;
  60073. + struct sdma_engine *sdma = sdmac->sdma;
  60074. - if (sdmac->flags & IMX_DMA_SG_LOOP)
  60075. + switch (sdmac->mode) {
  60076. + case SDMA_MODE_LOOP:
  60077. sdma_handle_channel_loop(sdmac);
  60078. - else
  60079. + break;
  60080. + case SDMA_MODE_NORMAL:
  60081. mxc_sdma_handle_channel_normal(sdmac);
  60082. + break;
  60083. + case SDMA_MODE_NO_BD:
  60084. + sdma_handle_other_intr(sdmac);
  60085. + break;
  60086. + default:
  60087. + dev_err(sdma->dev, "invalid SDMA MODE!\n");
  60088. + break;
  60089. + }
  60090. }
  60091. static irqreturn_t sdma_int_handler(int irq, void *dev_id)
  60092. @@ -671,6 +708,9 @@
  60093. int channel = fls(stat) - 1;
  60094. struct sdma_channel *sdmac = &sdma->channel[channel];
  60095. + if (sdmac->mode & SDMA_MODE_LOOP)
  60096. + sdma_update_channel_loop(sdmac);
  60097. +
  60098. tasklet_schedule(&sdmac->tasklet);
  60099. __clear_bit(channel, &stat);
  60100. @@ -692,9 +732,12 @@
  60101. * two peripherals or memory-to-memory transfers
  60102. */
  60103. int per_2_per = 0, emi_2_emi = 0;
  60104. + int other = 0;
  60105. sdmac->pc_from_device = 0;
  60106. sdmac->pc_to_device = 0;
  60107. + sdmac->device_to_device = 0;
  60108. + sdmac->other_script = 0;
  60109. switch (peripheral_type) {
  60110. case IMX_DMATYPE_MEMORY:
  60111. @@ -740,8 +783,8 @@
  60112. emi_2_per = sdma->script_addrs->mcu_2_shp_addr;
  60113. break;
  60114. case IMX_DMATYPE_ASRC:
  60115. - per_2_emi = sdma->script_addrs->asrc_2_mcu_addr;
  60116. - emi_2_per = sdma->script_addrs->asrc_2_mcu_addr;
  60117. + per_2_emi = sdma->script_addrs->shp_2_mcu_addr;
  60118. + emi_2_per = sdma->script_addrs->mcu_2_shp_addr;
  60119. per_2_per = sdma->script_addrs->per_2_per_addr;
  60120. break;
  60121. case IMX_DMATYPE_MSHC:
  60122. @@ -758,12 +801,17 @@
  60123. case IMX_DMATYPE_IPU_MEMORY:
  60124. emi_2_per = sdma->script_addrs->ext_mem_2_ipu_addr;
  60125. break;
  60126. + case IMX_DMATYPE_HDMI:
  60127. + other = sdma->script_addrs->hdmi_dma_addr;
  60128. + break;
  60129. default:
  60130. break;
  60131. }
  60132. sdmac->pc_from_device = per_2_emi;
  60133. sdmac->pc_to_device = emi_2_per;
  60134. + sdmac->device_to_device = per_2_per;
  60135. + sdmac->other_script = other;
  60136. }
  60137. static int sdma_load_context(struct sdma_channel *sdmac)
  60138. @@ -776,11 +824,14 @@
  60139. int ret;
  60140. unsigned long flags;
  60141. - if (sdmac->direction == DMA_DEV_TO_MEM) {
  60142. + if (sdmac->direction == DMA_DEV_TO_MEM)
  60143. load_address = sdmac->pc_from_device;
  60144. - } else {
  60145. + else if (sdmac->direction == DMA_DEV_TO_DEV)
  60146. + load_address = sdmac->device_to_device;
  60147. + else if (sdmac->direction == DMA_MEM_TO_DEV)
  60148. load_address = sdmac->pc_to_device;
  60149. - }
  60150. + else
  60151. + load_address = sdmac->other_script;
  60152. if (load_address < 0)
  60153. return load_address;
  60154. @@ -800,11 +851,16 @@
  60155. /* Send by context the event mask,base address for peripheral
  60156. * and watermark level
  60157. */
  60158. - context->gReg[0] = sdmac->event_mask[1];
  60159. - context->gReg[1] = sdmac->event_mask[0];
  60160. - context->gReg[2] = sdmac->per_addr;
  60161. - context->gReg[6] = sdmac->shp_addr;
  60162. - context->gReg[7] = sdmac->watermark_level;
  60163. + if (sdmac->peripheral_type == IMX_DMATYPE_HDMI) {
  60164. + context->gReg[4] = sdmac->data_addr1;
  60165. + context->gReg[6] = sdmac->data_addr2;
  60166. + } else {
  60167. + context->gReg[0] = sdmac->event_mask[1];
  60168. + context->gReg[1] = sdmac->event_mask[0];
  60169. + context->gReg[2] = sdmac->per_addr;
  60170. + context->gReg[6] = sdmac->shp_addr;
  60171. + context->gReg[7] = sdmac->watermark_level;
  60172. + }
  60173. bd0->mode.command = C0_SETDM;
  60174. bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
  60175. @@ -829,6 +885,7 @@
  60176. static int sdma_config_channel(struct sdma_channel *sdmac)
  60177. {
  60178. + struct imx_dma_data *data = sdmac->chan.private;
  60179. int ret;
  60180. sdma_disable_channel(sdmac);
  60181. @@ -837,12 +894,19 @@
  60182. sdmac->event_mask[1] = 0;
  60183. sdmac->shp_addr = 0;
  60184. sdmac->per_addr = 0;
  60185. + sdmac->data_addr1 = 0;
  60186. + sdmac->data_addr2 = 0;
  60187. if (sdmac->event_id0) {
  60188. if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
  60189. return -EINVAL;
  60190. sdma_event_enable(sdmac, sdmac->event_id0);
  60191. }
  60192. + if (sdmac->event_id1) {
  60193. + if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
  60194. + return -EINVAL;
  60195. + sdma_event_enable(sdmac, sdmac->event_id1);
  60196. + }
  60197. switch (sdmac->peripheral_type) {
  60198. case IMX_DMATYPE_DSP:
  60199. @@ -862,19 +926,75 @@
  60200. (sdmac->peripheral_type != IMX_DMATYPE_DSP)) {
  60201. /* Handle multiple event channels differently */
  60202. if (sdmac->event_id1) {
  60203. - sdmac->event_mask[1] = BIT(sdmac->event_id1 % 32);
  60204. - if (sdmac->event_id1 > 31)
  60205. - __set_bit(31, &sdmac->watermark_level);
  60206. - sdmac->event_mask[0] = BIT(sdmac->event_id0 % 32);
  60207. - if (sdmac->event_id0 > 31)
  60208. - __set_bit(30, &sdmac->watermark_level);
  60209. + if (sdmac->event_id0 > 31) {
  60210. + sdmac->event_mask[0] |= 0;
  60211. + __set_bit(28, &sdmac->watermark_level);
  60212. + sdmac->event_mask[1] |=
  60213. + BIT(sdmac->event_id0 % 32);
  60214. + } else {
  60215. + sdmac->event_mask[1] |= 0;
  60216. + sdmac->event_mask[0] |=
  60217. + BIT(sdmac->event_id0 % 32);
  60218. + }
  60219. + if (sdmac->event_id1 > 31) {
  60220. + sdmac->event_mask[0] |= 0;
  60221. + __set_bit(29, &sdmac->watermark_level);
  60222. + sdmac->event_mask[1] |=
  60223. + BIT(sdmac->event_id1 % 32);
  60224. + } else {
  60225. + sdmac->event_mask[1] |= 0;
  60226. + sdmac->event_mask[0] |=
  60227. + BIT(sdmac->event_id1 % 32);
  60228. + }
  60229. + /* BIT 11:
  60230. + * 1 : Source on SPBA
  60231. + * 0 : Source on AIPS
  60232. + */
  60233. + __set_bit(11, &sdmac->watermark_level);
  60234. + /* BIT 12:
  60235. + * 1 : Destination on SPBA
  60236. + * 0 : Destination on AIPS
  60237. + */
  60238. + __set_bit(12, &sdmac->watermark_level);
  60239. + __set_bit(31, &sdmac->watermark_level);
  60240. + /* BIT 31:
  60241. + * 1 : Amount of samples to be transferred is
  60242. + * unknown and script will keep on transferring
  60243. + * samples as long as both events are detected
  60244. + * and script must be manually stopped by the
  60245. + * application.
  60246. + * 0 : The amount of samples to be is equal to
  60247. + * the count field of mode word
  60248. + * */
  60249. + __set_bit(25, &sdmac->watermark_level);
  60250. + __clear_bit(24, &sdmac->watermark_level);
  60251. } else {
  60252. - __set_bit(sdmac->event_id0, sdmac->event_mask);
  60253. + if (sdmac->event_id0 > 31) {
  60254. + sdmac->event_mask[0] = 0;
  60255. + sdmac->event_mask[1] |=
  60256. + BIT(sdmac->event_id0 % 32);
  60257. + } else {
  60258. + sdmac->event_mask[0] |=
  60259. + BIT(sdmac->event_id0 % 32);
  60260. + sdmac->event_mask[1] = 0;
  60261. + }
  60262. }
  60263. /* Watermark Level */
  60264. sdmac->watermark_level |= sdmac->watermark_level;
  60265. /* Address */
  60266. - sdmac->shp_addr = sdmac->per_address;
  60267. + if (sdmac->direction == DMA_DEV_TO_DEV) {
  60268. + sdmac->shp_addr = sdmac->per_address2;
  60269. + sdmac->per_addr = sdmac->per_address;
  60270. + } else if (sdmac->direction == DMA_TRANS_NONE) {
  60271. + if (sdmac->peripheral_type != IMX_DMATYPE_HDMI ||
  60272. + !data->data_addr1 || !data->data_addr2)
  60273. + return -EINVAL;
  60274. + sdmac->data_addr1 = *(u32 *)data->data_addr1;
  60275. + sdmac->data_addr2 = *(u32 *)data->data_addr2;
  60276. + sdmac->watermark_level = 0;
  60277. + } else {
  60278. + sdmac->shp_addr = sdmac->per_address;
  60279. + }
  60280. } else {
  60281. sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */
  60282. }
  60283. @@ -906,10 +1026,15 @@
  60284. int channel = sdmac->channel;
  60285. int ret = -EBUSY;
  60286. - sdmac->bd = dma_alloc_coherent(NULL, PAGE_SIZE, &sdmac->bd_phys, GFP_KERNEL);
  60287. + sdmac->bd_iram = true;
  60288. + sdmac->bd = gen_pool_dma_alloc(sdma->iram_pool, PAGE_SIZE, &sdmac->bd_phys);
  60289. if (!sdmac->bd) {
  60290. - ret = -ENOMEM;
  60291. - goto out;
  60292. + sdmac->bd_iram = false;
  60293. + sdmac->bd = dma_alloc_coherent(NULL, PAGE_SIZE, &sdmac->bd_phys, GFP_KERNEL);
  60294. + if (!sdmac->bd) {
  60295. + ret = -ENOMEM;
  60296. + goto out;
  60297. + }
  60298. }
  60299. memset(sdmac->bd, 0, PAGE_SIZE);
  60300. @@ -967,7 +1092,8 @@
  60301. }
  60302. sdmac->peripheral_type = data->peripheral_type;
  60303. - sdmac->event_id0 = data->dma_request;
  60304. + sdmac->event_id0 = data->dma_request0;
  60305. + sdmac->event_id1 = data->dma_request1;
  60306. clk_enable(sdmac->sdma->clk_ipg);
  60307. clk_enable(sdmac->sdma->clk_ahb);
  60308. @@ -985,6 +1111,9 @@
  60309. /* txd.flags will be overwritten in prep funcs */
  60310. sdmac->desc.flags = DMA_CTRL_ACK;
  60311. + /* Set SDMA channel mode to unvalid to avoid misconfig */
  60312. + sdmac->mode = SDMA_MODE_INVALID;
  60313. +
  60314. return 0;
  60315. }
  60316. @@ -1005,7 +1134,10 @@
  60317. sdma_set_channel_priority(sdmac, 0);
  60318. - dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
  60319. + if (sdmac->bd_iram)
  60320. + gen_pool_free(sdma->iram_pool, (unsigned long)sdmac->bd, PAGE_SIZE);
  60321. + else
  60322. + dma_free_coherent(NULL, PAGE_SIZE, sdmac->bd, sdmac->bd_phys);
  60323. clk_disable(sdma->clk_ipg);
  60324. clk_disable(sdma->clk_ahb);
  60325. @@ -1026,7 +1158,7 @@
  60326. return NULL;
  60327. sdmac->status = DMA_IN_PROGRESS;
  60328. - sdmac->flags = 0;
  60329. + sdmac->mode = SDMA_MODE_NORMAL;
  60330. sdmac->buf_tail = 0;
  60331. @@ -1119,9 +1251,9 @@
  60332. {
  60333. struct sdma_channel *sdmac = to_sdma_chan(chan);
  60334. struct sdma_engine *sdma = sdmac->sdma;
  60335. - int num_periods = buf_len / period_len;
  60336. int channel = sdmac->channel;
  60337. int ret, i = 0, buf = 0;
  60338. + int num_periods;
  60339. dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
  60340. @@ -1131,13 +1263,35 @@
  60341. sdmac->status = DMA_IN_PROGRESS;
  60342. sdmac->buf_tail = 0;
  60343. + sdmac->period_len = period_len;
  60344. - sdmac->flags |= IMX_DMA_SG_LOOP;
  60345. sdmac->direction = direction;
  60346. +
  60347. + switch (sdmac->direction) {
  60348. + case DMA_DEV_TO_DEV:
  60349. + sdmac->mode = SDMA_MODE_P2P;
  60350. + break;
  60351. + case DMA_TRANS_NONE:
  60352. + sdmac->mode = SDMA_MODE_NO_BD;
  60353. + break;
  60354. + case DMA_MEM_TO_DEV:
  60355. + case DMA_DEV_TO_MEM:
  60356. + sdmac->mode = SDMA_MODE_LOOP;
  60357. + break;
  60358. + default:
  60359. + dev_err(sdma->dev, "invalid SDMA direction %d\n", direction);
  60360. + return NULL;
  60361. + }
  60362. +
  60363. ret = sdma_load_context(sdmac);
  60364. if (ret)
  60365. goto err_out;
  60366. + if (period_len)
  60367. + num_periods = buf_len / period_len;
  60368. + else
  60369. + return &sdmac->desc;
  60370. +
  60371. if (num_periods > NUM_BD) {
  60372. dev_err(sdma->dev, "SDMA channel %d: maximum number of sg exceeded: %d > %d\n",
  60373. channel, num_periods, NUM_BD);
  60374. @@ -1202,18 +1356,31 @@
  60375. sdma_disable_channel(sdmac);
  60376. return 0;
  60377. case DMA_SLAVE_CONFIG:
  60378. - if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
  60379. + if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) {
  60380. + sdmac->per_address = dmaengine_cfg->src_addr;
  60381. + sdmac->per_address2 = dmaengine_cfg->dst_addr;
  60382. + sdmac->watermark_level = 0;
  60383. + sdmac->watermark_level |=
  60384. + dmaengine_cfg->src_maxburst;
  60385. + sdmac->watermark_level |=
  60386. + dmaengine_cfg->dst_maxburst << 16;
  60387. + sdmac->word_size = dmaengine_cfg->dst_addr_width;
  60388. + } else if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
  60389. sdmac->per_address = dmaengine_cfg->src_addr;
  60390. sdmac->watermark_level = dmaengine_cfg->src_maxburst *
  60391. dmaengine_cfg->src_addr_width;
  60392. sdmac->word_size = dmaengine_cfg->src_addr_width;
  60393. - } else {
  60394. + } else if (dmaengine_cfg->direction == DMA_MEM_TO_DEV) {
  60395. sdmac->per_address = dmaengine_cfg->dst_addr;
  60396. sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
  60397. dmaengine_cfg->dst_addr_width;
  60398. sdmac->word_size = dmaengine_cfg->dst_addr_width;
  60399. }
  60400. sdmac->direction = dmaengine_cfg->direction;
  60401. + if (dmaengine_cfg->dma_request0)
  60402. + sdmac->event_id0 = dmaengine_cfg->dma_request0;
  60403. + if (dmaengine_cfg->dma_request1)
  60404. + sdmac->event_id1 = dmaengine_cfg->dma_request1;
  60405. return sdma_config_channel(sdmac);
  60406. default:
  60407. return -ENOSYS;
  60408. @@ -1227,9 +1394,15 @@
  60409. struct dma_tx_state *txstate)
  60410. {
  60411. struct sdma_channel *sdmac = to_sdma_chan(chan);
  60412. + u32 residue;
  60413. +
  60414. + if (sdmac->mode & SDMA_MODE_LOOP)
  60415. + residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
  60416. + else
  60417. + residue = sdmac->chn_count - sdmac->chn_real_count;
  60418. dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,
  60419. - sdmac->chn_count - sdmac->chn_real_count);
  60420. + residue);
  60421. return sdmac->status;
  60422. }
  60423. @@ -1285,7 +1458,10 @@
  60424. goto err_firmware;
  60425. switch (header->version_major) {
  60426. case 1:
  60427. - sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
  60428. + if (header->version_minor > 0)
  60429. + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
  60430. + else
  60431. + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
  60432. break;
  60433. case 2:
  60434. sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
  60435. @@ -1331,7 +1507,7 @@
  60436. static int __init sdma_init(struct sdma_engine *sdma)
  60437. {
  60438. - int i, ret;
  60439. + int i, ret, ccbsize;
  60440. dma_addr_t ccb_phys;
  60441. clk_enable(sdma->clk_ipg);
  60442. @@ -1340,14 +1516,17 @@
  60443. /* Be sure SDMA has not started yet */
  60444. writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
  60445. - sdma->channel_control = dma_alloc_coherent(NULL,
  60446. - MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) +
  60447. - sizeof(struct sdma_context_data),
  60448. - &ccb_phys, GFP_KERNEL);
  60449. + ccbsize = MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control)
  60450. + + sizeof(struct sdma_context_data);
  60451. + sdma->channel_control = gen_pool_dma_alloc(sdma->iram_pool, ccbsize, &ccb_phys);
  60452. if (!sdma->channel_control) {
  60453. - ret = -ENOMEM;
  60454. - goto err_dma_alloc;
  60455. + sdma->channel_control = dma_alloc_coherent(NULL, ccbsize,
  60456. + &ccb_phys, GFP_KERNEL);
  60457. + if (!sdma->channel_control) {
  60458. + ret = -ENOMEM;
  60459. + goto err_dma_alloc;
  60460. + }
  60461. }
  60462. sdma->context = (void *)sdma->channel_control +
  60463. @@ -1422,9 +1601,10 @@
  60464. if (dma_spec->args_count != 3)
  60465. return NULL;
  60466. - data.dma_request = dma_spec->args[0];
  60467. + data.dma_request0 = dma_spec->args[0];
  60468. data.peripheral_type = dma_spec->args[1];
  60469. data.priority = dma_spec->args[2];
  60470. + data.dma_request1 = 0;
  60471. return dma_request_channel(mask, sdma_filter_fn, &data);
  60472. }
  60473. @@ -1542,6 +1722,11 @@
  60474. &sdma->dma_device.channels);
  60475. }
  60476. + if (np)
  60477. + sdma->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  60478. + if (!sdma->iram_pool)
  60479. + dev_warn(&pdev->dev, "no iram assigned, using external mem\n");
  60480. +
  60481. ret = sdma_init(sdma);
  60482. if (ret)
  60483. goto err_init;
  60484. diff -Nur linux-3.14.17/drivers/dma/Kconfig linux-imx6-3.14/drivers/dma/Kconfig
  60485. --- linux-3.14.17/drivers/dma/Kconfig 2014-08-14 03:38:34.000000000 +0200
  60486. +++ linux-imx6-3.14/drivers/dma/Kconfig 2014-09-11 18:06:00.122030466 +0200
  60487. @@ -137,6 +137,19 @@
  60488. To avoid bloating the irq_desc[] array we allocate a sufficient
  60489. number of IRQ slots and map them dynamically to specific sources.
  60490. +config MXC_PXP_V2
  60491. + bool "MXC PxP V2 support"
  60492. + depends on ARM
  60493. + select DMA_ENGINE
  60494. + help
  60495. + Support the PxP (Pixel Pipeline) on i.MX6 DualLite and i.MX6 SoloLite.
  60496. + If unsure, select N.
  60497. +
  60498. +config MXC_PXP_CLIENT_DEVICE
  60499. + bool "MXC PxP Client Device"
  60500. + default y
  60501. + depends on MXC_PXP_V2
  60502. +
  60503. config TXX9_DMAC
  60504. tristate "Toshiba TXx9 SoC DMA support"
  60505. depends on MACH_TX49XX || MACH_TX39XX
  60506. diff -Nur linux-3.14.17/drivers/dma/Makefile linux-imx6-3.14/drivers/dma/Makefile
  60507. --- linux-3.14.17/drivers/dma/Makefile 2014-08-14 03:38:34.000000000 +0200
  60508. +++ linux-imx6-3.14/drivers/dma/Makefile 2014-09-11 18:06:00.122030466 +0200
  60509. @@ -18,6 +18,7 @@
  60510. obj-$(CONFIG_DW_DMAC_CORE) += dw/
  60511. obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
  60512. obj-$(CONFIG_MX3_IPU) += ipu/
  60513. +obj-$(CONFIG_MXC_PXP_V2) += pxp/
  60514. obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
  60515. obj-$(CONFIG_SH_DMAE_BASE) += sh/
  60516. obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
  60517. diff -Nur linux-3.14.17/drivers/dma/pxp/Makefile linux-imx6-3.14/drivers/dma/pxp/Makefile
  60518. --- linux-3.14.17/drivers/dma/pxp/Makefile 1970-01-01 01:00:00.000000000 +0100
  60519. +++ linux-imx6-3.14/drivers/dma/pxp/Makefile 2014-09-11 18:06:00.198030770 +0200
  60520. @@ -0,0 +1,2 @@
  60521. +obj-$(CONFIG_MXC_PXP_V2) += pxp_dma_v2.o
  60522. +obj-$(CONFIG_MXC_PXP_CLIENT_DEVICE) += pxp_device.o
  60523. diff -Nur linux-3.14.17/drivers/dma/pxp/pxp_device.c linux-imx6-3.14/drivers/dma/pxp/pxp_device.c
  60524. --- linux-3.14.17/drivers/dma/pxp/pxp_device.c 1970-01-01 01:00:00.000000000 +0100
  60525. +++ linux-imx6-3.14/drivers/dma/pxp/pxp_device.c 2014-09-11 18:06:00.198030770 +0200
  60526. @@ -0,0 +1,765 @@
  60527. +/*
  60528. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  60529. + *
  60530. + * This program is free software; you can redistribute it and/or modify
  60531. + * it under the terms of the GNU General Public License as published by
  60532. + * the Free Software Foundation; either version 2 of the License, or
  60533. + * (at your option) any later version.
  60534. + *
  60535. + * This program is distributed in the hope that it will be useful,
  60536. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  60537. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  60538. + * GNU General Public License for more details.
  60539. + *
  60540. + * You should have received a copy of the GNU General Public License
  60541. + * along with this program; if not, write to the Free Software
  60542. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  60543. + *
  60544. + */
  60545. +#include <linux/interrupt.h>
  60546. +#include <linux/miscdevice.h>
  60547. +#include <linux/platform_device.h>
  60548. +#include <linux/fs.h>
  60549. +#include <linux/slab.h>
  60550. +#include <linux/uaccess.h>
  60551. +#include <linux/delay.h>
  60552. +#include <linux/dmaengine.h>
  60553. +#include <linux/dma-mapping.h>
  60554. +#include <linux/sched.h>
  60555. +#include <linux/module.h>
  60556. +#include <linux/pxp_device.h>
  60557. +#include <linux/atomic.h>
  60558. +#include <linux/platform_data/dma-imx.h>
  60559. +
  60560. +#define BUFFER_HASH_ORDER 4
  60561. +
  60562. +static struct pxp_buffer_hash bufhash;
  60563. +static struct pxp_irq_info irq_info[NR_PXP_VIRT_CHANNEL];
  60564. +
  60565. +static int pxp_ht_create(struct pxp_buffer_hash *hash, int order)
  60566. +{
  60567. + unsigned long i;
  60568. + unsigned long table_size;
  60569. +
  60570. + table_size = 1U << order;
  60571. +
  60572. + hash->order = order;
  60573. + hash->hash_table = kmalloc(sizeof(*hash->hash_table) * table_size, GFP_KERNEL);
  60574. +
  60575. + if (!hash->hash_table) {
  60576. + pr_err("%s: Out of memory for hash table\n", __func__);
  60577. + return -ENOMEM;
  60578. + }
  60579. +
  60580. + for (i = 0; i < table_size; i++)
  60581. + INIT_HLIST_HEAD(&hash->hash_table[i]);
  60582. +
  60583. + return 0;
  60584. +}
  60585. +
  60586. +static int pxp_ht_insert_item(struct pxp_buffer_hash *hash,
  60587. + struct pxp_buf_obj *new)
  60588. +{
  60589. + unsigned long hashkey;
  60590. + struct hlist_head *h_list;
  60591. +
  60592. + hashkey = hash_long(new->offset >> PAGE_SHIFT, hash->order);
  60593. + h_list = &hash->hash_table[hashkey];
  60594. +
  60595. + spin_lock(&hash->hash_lock);
  60596. + hlist_add_head_rcu(&new->item, h_list);
  60597. + spin_unlock(&hash->hash_lock);
  60598. +
  60599. + return 0;
  60600. +}
  60601. +
  60602. +static int pxp_ht_remove_item(struct pxp_buffer_hash *hash,
  60603. + struct pxp_buf_obj *obj)
  60604. +{
  60605. + spin_lock(&hash->hash_lock);
  60606. + hlist_del_init_rcu(&obj->item);
  60607. + spin_unlock(&hash->hash_lock);
  60608. + return 0;
  60609. +}
  60610. +
  60611. +static struct hlist_node *pxp_ht_find_key(struct pxp_buffer_hash *hash,
  60612. + unsigned long key)
  60613. +{
  60614. + struct pxp_buf_obj *entry;
  60615. + struct hlist_head *h_list;
  60616. + unsigned long hashkey;
  60617. +
  60618. + hashkey = hash_long(key, hash->order);
  60619. + h_list = &hash->hash_table[hashkey];
  60620. +
  60621. + hlist_for_each_entry_rcu(entry, h_list, item) {
  60622. + if (entry->offset >> PAGE_SHIFT == key)
  60623. + return &entry->item;
  60624. + }
  60625. +
  60626. + return NULL;
  60627. +}
  60628. +
  60629. +static void pxp_ht_destroy(struct pxp_buffer_hash *hash)
  60630. +{
  60631. + kfree(hash->hash_table);
  60632. + hash->hash_table = NULL;
  60633. +}
  60634. +
  60635. +static int pxp_buffer_handle_create(struct pxp_file *file_priv,
  60636. + struct pxp_buf_obj *obj,
  60637. + uint32_t *handlep)
  60638. +{
  60639. + int ret;
  60640. +
  60641. + idr_preload(GFP_KERNEL);
  60642. + spin_lock(&file_priv->buffer_lock);
  60643. +
  60644. + ret = idr_alloc(&file_priv->buffer_idr, obj, 1, 0, GFP_NOWAIT);
  60645. +
  60646. + spin_unlock(&file_priv->buffer_lock);
  60647. + idr_preload_end();
  60648. +
  60649. + if (ret < 0)
  60650. + return ret;
  60651. +
  60652. + *handlep = ret;
  60653. +
  60654. + return 0;
  60655. +}
  60656. +
  60657. +static struct pxp_buf_obj *
  60658. +pxp_buffer_object_lookup(struct pxp_file *file_priv,
  60659. + uint32_t handle)
  60660. +{
  60661. + struct pxp_buf_obj *obj;
  60662. +
  60663. + spin_lock(&file_priv->buffer_lock);
  60664. +
  60665. + obj = idr_find(&file_priv->buffer_idr, handle);
  60666. + if (!obj) {
  60667. + spin_unlock(&file_priv->buffer_lock);
  60668. + return NULL;
  60669. + }
  60670. +
  60671. + spin_unlock(&file_priv->buffer_lock);
  60672. +
  60673. + return obj;
  60674. +}
  60675. +
  60676. +static int pxp_buffer_handle_delete(struct pxp_file *file_priv,
  60677. + uint32_t handle)
  60678. +{
  60679. + struct pxp_buf_obj *obj;
  60680. +
  60681. + spin_lock(&file_priv->buffer_lock);
  60682. +
  60683. + obj = idr_find(&file_priv->buffer_idr, handle);
  60684. + if (!obj) {
  60685. + spin_unlock(&file_priv->buffer_lock);
  60686. + return -EINVAL;
  60687. + }
  60688. +
  60689. + idr_remove(&file_priv->buffer_idr, handle);
  60690. + spin_unlock(&file_priv->buffer_lock);
  60691. +
  60692. + return 0;
  60693. +}
  60694. +
  60695. +static int pxp_channel_handle_create(struct pxp_file *file_priv,
  60696. + struct pxp_chan_obj *obj,
  60697. + uint32_t *handlep)
  60698. +{
  60699. + int ret;
  60700. +
  60701. + idr_preload(GFP_KERNEL);
  60702. + spin_lock(&file_priv->channel_lock);
  60703. +
  60704. + ret = idr_alloc(&file_priv->channel_idr, obj, 0, 0, GFP_NOWAIT);
  60705. +
  60706. + spin_unlock(&file_priv->channel_lock);
  60707. + idr_preload_end();
  60708. +
  60709. + if (ret < 0)
  60710. + return ret;
  60711. +
  60712. + *handlep = ret;
  60713. +
  60714. + return 0;
  60715. +}
  60716. +
  60717. +static struct pxp_chan_obj *
  60718. +pxp_channel_object_lookup(struct pxp_file *file_priv,
  60719. + uint32_t handle)
  60720. +{
  60721. + struct pxp_chan_obj *obj;
  60722. +
  60723. + spin_lock(&file_priv->channel_lock);
  60724. +
  60725. + obj = idr_find(&file_priv->channel_idr, handle);
  60726. + if (!obj) {
  60727. + spin_unlock(&file_priv->channel_lock);
  60728. + return NULL;
  60729. + }
  60730. +
  60731. + spin_unlock(&file_priv->channel_lock);
  60732. +
  60733. + return obj;
  60734. +}
  60735. +
  60736. +static int pxp_channel_handle_delete(struct pxp_file *file_priv,
  60737. + uint32_t handle)
  60738. +{
  60739. + struct pxp_chan_obj *obj;
  60740. +
  60741. + spin_lock(&file_priv->channel_lock);
  60742. +
  60743. + obj = idr_find(&file_priv->channel_idr, handle);
  60744. + if (!obj) {
  60745. + spin_unlock(&file_priv->channel_lock);
  60746. + return -EINVAL;
  60747. + }
  60748. +
  60749. + idr_remove(&file_priv->channel_idr, handle);
  60750. + spin_unlock(&file_priv->channel_lock);
  60751. +
  60752. + return 0;
  60753. +}
  60754. +
  60755. +static int pxp_alloc_dma_buffer(struct pxp_buf_obj *obj)
  60756. +{
  60757. + obj->virtual = dma_alloc_coherent(NULL, PAGE_ALIGN(obj->size),
  60758. + (dma_addr_t *) (&obj->offset),
  60759. + GFP_DMA | GFP_KERNEL);
  60760. + pr_debug("[ALLOC] mem alloc phys_addr = 0x%lx\n", obj->offset);
  60761. +
  60762. + if (obj->virtual == NULL) {
  60763. + printk(KERN_ERR "Physical memory allocation error!\n");
  60764. + return -1;
  60765. + }
  60766. +
  60767. + return 0;
  60768. +}
  60769. +
  60770. +static void pxp_free_dma_buffer(struct pxp_buf_obj *obj)
  60771. +{
  60772. + if (obj->virtual != NULL) {
  60773. + dma_free_coherent(0, PAGE_ALIGN(obj->size),
  60774. + obj->virtual, (dma_addr_t)obj->offset);
  60775. + }
  60776. +}
  60777. +
  60778. +static int
  60779. +pxp_buffer_object_free(int id, void *ptr, void *data)
  60780. +{
  60781. + struct pxp_file *file_priv = data;
  60782. + struct pxp_buf_obj *obj = ptr;
  60783. + int ret;
  60784. +
  60785. + ret = pxp_buffer_handle_delete(file_priv, obj->handle);
  60786. + if (ret < 0)
  60787. + return ret;
  60788. +
  60789. + pxp_ht_remove_item(&bufhash, obj);
  60790. + pxp_free_dma_buffer(obj);
  60791. + kfree(obj);
  60792. +
  60793. + return 0;
  60794. +}
  60795. +
  60796. +static int
  60797. +pxp_channel_object_free(int id, void *ptr, void *data)
  60798. +{
  60799. + struct pxp_file *file_priv = data;
  60800. + struct pxp_chan_obj *obj = ptr;
  60801. + int chan_id;
  60802. +
  60803. + chan_id = obj->chan->chan_id;
  60804. + wait_event(irq_info[chan_id].waitq,
  60805. + atomic_read(&irq_info[chan_id].irq_pending) == 0);
  60806. +
  60807. + pxp_channel_handle_delete(file_priv, obj->handle);
  60808. + dma_release_channel(obj->chan);
  60809. + kfree(obj);
  60810. +
  60811. + return 0;
  60812. +}
  60813. +
  60814. +static void pxp_free_buffers(struct pxp_file *file_priv)
  60815. +{
  60816. + idr_for_each(&file_priv->buffer_idr,
  60817. + &pxp_buffer_object_free, file_priv);
  60818. + idr_destroy(&file_priv->buffer_idr);
  60819. +}
  60820. +
  60821. +static void pxp_free_channels(struct pxp_file *file_priv)
  60822. +{
  60823. + idr_for_each(&file_priv->channel_idr,
  60824. + &pxp_channel_object_free, file_priv);
  60825. + idr_destroy(&file_priv->channel_idr);
  60826. +}
  60827. +
  60828. +/* Callback function triggered after PxP receives an EOF interrupt */
  60829. +static void pxp_dma_done(void *arg)
  60830. +{
  60831. + struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
  60832. + struct dma_chan *chan = tx_desc->txd.chan;
  60833. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  60834. + int chan_id = pxp_chan->dma_chan.chan_id;
  60835. +
  60836. + pr_debug("DMA Done ISR, chan_id %d\n", chan_id);
  60837. +
  60838. + atomic_dec(&irq_info[chan_id].irq_pending);
  60839. + irq_info[chan_id].hist_status = tx_desc->hist_status;
  60840. +
  60841. + wake_up(&(irq_info[chan_id].waitq));
  60842. +}
  60843. +
  60844. +static int pxp_ioc_config_chan(struct pxp_file *priv, unsigned long arg)
  60845. +{
  60846. + struct scatterlist sg[3];
  60847. + struct pxp_tx_desc *desc;
  60848. + struct dma_async_tx_descriptor *txd;
  60849. + struct pxp_config_data pxp_conf;
  60850. + dma_cookie_t cookie;
  60851. + int handle, chan_id;
  60852. + int i, length, ret;
  60853. + struct dma_chan *chan;
  60854. + struct pxp_chan_obj *obj;
  60855. +
  60856. + ret = copy_from_user(&pxp_conf,
  60857. + (struct pxp_config_data *)arg,
  60858. + sizeof(struct pxp_config_data));
  60859. + if (ret)
  60860. + return -EFAULT;
  60861. +
  60862. + handle = pxp_conf.handle;
  60863. + obj = pxp_channel_object_lookup(priv, handle);
  60864. + if (!obj)
  60865. + return -EINVAL;
  60866. + chan = obj->chan;
  60867. + chan_id = chan->chan_id;
  60868. +
  60869. + sg_init_table(sg, 3);
  60870. +
  60871. + txd = chan->device->device_prep_slave_sg(chan,
  60872. + sg, 3,
  60873. + DMA_TO_DEVICE,
  60874. + DMA_PREP_INTERRUPT,
  60875. + NULL);
  60876. + if (!txd) {
  60877. + pr_err("Error preparing a DMA transaction descriptor.\n");
  60878. + return -EIO;
  60879. + }
  60880. +
  60881. + txd->callback_param = txd;
  60882. + txd->callback = pxp_dma_done;
  60883. +
  60884. + desc = to_tx_desc(txd);
  60885. +
  60886. + length = desc->len;
  60887. + for (i = 0; i < length; i++) {
  60888. + if (i == 0) { /* S0 */
  60889. + memcpy(&desc->proc_data,
  60890. + &pxp_conf.proc_data,
  60891. + sizeof(struct pxp_proc_data));
  60892. + memcpy(&desc->layer_param.s0_param,
  60893. + &pxp_conf.s0_param,
  60894. + sizeof(struct pxp_layer_param));
  60895. + } else if (i == 1) { /* Output */
  60896. + memcpy(&desc->layer_param.out_param,
  60897. + &pxp_conf.out_param,
  60898. + sizeof(struct pxp_layer_param));
  60899. + } else {
  60900. + /* OverLay */
  60901. + memcpy(&desc->layer_param.ol_param,
  60902. + &pxp_conf.ol_param,
  60903. + sizeof(struct pxp_layer_param));
  60904. + }
  60905. +
  60906. + desc = desc->next;
  60907. + }
  60908. +
  60909. + cookie = txd->tx_submit(txd);
  60910. + if (cookie < 0) {
  60911. + pr_err("Error tx_submit\n");
  60912. + return -EIO;
  60913. + }
  60914. +
  60915. + atomic_inc(&irq_info[chan_id].irq_pending);
  60916. +
  60917. + return 0;
  60918. +}
  60919. +
  60920. +static int pxp_device_open(struct inode *inode, struct file *filp)
  60921. +{
  60922. + struct pxp_file *priv;
  60923. +
  60924. + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  60925. +
  60926. + if (!priv)
  60927. + return -ENOMEM;
  60928. +
  60929. + filp->private_data = priv;
  60930. + priv->filp = filp;
  60931. +
  60932. + idr_init(&priv->buffer_idr);
  60933. + spin_lock_init(&priv->buffer_lock);
  60934. +
  60935. + idr_init(&priv->channel_idr);
  60936. + spin_lock_init(&priv->channel_lock);
  60937. +
  60938. + return 0;
  60939. +}
  60940. +
  60941. +static int pxp_device_release(struct inode *inode, struct file *filp)
  60942. +{
  60943. + struct pxp_file *priv = filp->private_data;
  60944. +
  60945. + if (priv) {
  60946. + pxp_free_channels(priv);
  60947. + pxp_free_buffers(priv);
  60948. + kfree(priv);
  60949. + filp->private_data = NULL;
  60950. + }
  60951. +
  60952. + return 0;
  60953. +}
  60954. +
  60955. +static int pxp_device_mmap(struct file *file, struct vm_area_struct *vma)
  60956. +{
  60957. + int request_size;
  60958. + struct hlist_node *node;
  60959. + struct pxp_buf_obj *obj;
  60960. +
  60961. + request_size = vma->vm_end - vma->vm_start;
  60962. +
  60963. + pr_debug("start=0x%x, pgoff=0x%x, size=0x%x\n",
  60964. + (unsigned int)(vma->vm_start), (unsigned int)(vma->vm_pgoff),
  60965. + request_size);
  60966. +
  60967. + node = pxp_ht_find_key(&bufhash, vma->vm_pgoff);
  60968. + if (!node)
  60969. + return -EINVAL;
  60970. +
  60971. + obj = list_entry(node, struct pxp_buf_obj, item);
  60972. + if (obj->offset + (obj->size >> PAGE_SHIFT) <
  60973. + (vma->vm_pgoff + vma_pages(vma)))
  60974. + return -ENOMEM;
  60975. +
  60976. + switch (obj->mem_type) {
  60977. + case MEMORY_TYPE_UNCACHED:
  60978. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  60979. + break;
  60980. + case MEMORY_TYPE_WC:
  60981. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  60982. + break;
  60983. + case MEMORY_TYPE_CACHED:
  60984. + break;
  60985. + default:
  60986. + pr_err("%s: invalid memory type!\n", __func__);
  60987. + return -EINVAL;
  60988. + }
  60989. +
  60990. + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  60991. + request_size, vma->vm_page_prot) ? -EAGAIN : 0;
  60992. +}
  60993. +
  60994. +static bool chan_filter(struct dma_chan *chan, void *arg)
  60995. +{
  60996. + if (imx_dma_is_pxp(chan))
  60997. + return true;
  60998. + else
  60999. + return false;
  61000. +}
  61001. +
  61002. +static long pxp_device_ioctl(struct file *filp,
  61003. + unsigned int cmd, unsigned long arg)
  61004. +{
  61005. + int ret = 0;
  61006. + struct pxp_file *file_priv = filp->private_data;
  61007. +
  61008. + switch (cmd) {
  61009. + case PXP_IOC_GET_CHAN:
  61010. + {
  61011. + int ret;
  61012. + struct dma_chan *chan = NULL;
  61013. + dma_cap_mask_t mask;
  61014. + struct pxp_chan_obj *obj = NULL;
  61015. +
  61016. + pr_debug("drv: PXP_IOC_GET_CHAN Line %d\n", __LINE__);
  61017. +
  61018. + dma_cap_zero(mask);
  61019. + dma_cap_set(DMA_SLAVE, mask);
  61020. + dma_cap_set(DMA_PRIVATE, mask);
  61021. +
  61022. + chan = dma_request_channel(mask, chan_filter, NULL);
  61023. + if (!chan) {
  61024. + pr_err("Unsccessfully received channel!\n");
  61025. + return -EBUSY;
  61026. + }
  61027. +
  61028. + pr_debug("Successfully received channel."
  61029. + "chan_id %d\n", chan->chan_id);
  61030. +
  61031. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  61032. + if (!obj) {
  61033. + dma_release_channel(chan);
  61034. + return -ENOMEM;
  61035. + }
  61036. + obj->chan = chan;
  61037. +
  61038. + ret = pxp_channel_handle_create(file_priv, obj,
  61039. + &obj->handle);
  61040. + if (ret) {
  61041. + dma_release_channel(chan);
  61042. + kfree(obj);
  61043. + return ret;
  61044. + }
  61045. +
  61046. + init_waitqueue_head(&(irq_info[chan->chan_id].waitq));
  61047. + if (put_user(obj->handle, (u32 __user *) arg)) {
  61048. + pxp_channel_handle_delete(file_priv, obj->handle);
  61049. + dma_release_channel(chan);
  61050. + kfree(obj);
  61051. + return -EFAULT;
  61052. + }
  61053. +
  61054. + break;
  61055. + }
  61056. + case PXP_IOC_PUT_CHAN:
  61057. + {
  61058. + int handle;
  61059. + struct pxp_chan_obj *obj;
  61060. +
  61061. + if (get_user(handle, (u32 __user *) arg))
  61062. + return -EFAULT;
  61063. +
  61064. + pr_debug("%d release handle %d\n", __LINE__, handle);
  61065. +
  61066. + obj = pxp_channel_object_lookup(file_priv, handle);
  61067. + if (!obj)
  61068. + return -EINVAL;
  61069. +
  61070. + pxp_channel_handle_delete(file_priv, obj->handle);
  61071. + dma_release_channel(obj->chan);
  61072. + kfree(obj);
  61073. +
  61074. + break;
  61075. + }
  61076. + case PXP_IOC_CONFIG_CHAN:
  61077. + {
  61078. + int ret;
  61079. +
  61080. + ret = pxp_ioc_config_chan(file_priv, arg);
  61081. + if (ret)
  61082. + return ret;
  61083. +
  61084. + break;
  61085. + }
  61086. + case PXP_IOC_START_CHAN:
  61087. + {
  61088. + int handle;
  61089. + struct pxp_chan_obj *obj = NULL;
  61090. +
  61091. + if (get_user(handle, (u32 __user *) arg))
  61092. + return -EFAULT;
  61093. +
  61094. + obj = pxp_channel_object_lookup(file_priv, handle);
  61095. + if (!obj)
  61096. + return -EINVAL;
  61097. +
  61098. + dma_async_issue_pending(obj->chan);
  61099. +
  61100. + break;
  61101. + }
  61102. + case PXP_IOC_GET_PHYMEM:
  61103. + {
  61104. + struct pxp_mem_desc buffer;
  61105. + struct pxp_buf_obj *obj;
  61106. +
  61107. + ret = copy_from_user(&buffer,
  61108. + (struct pxp_mem_desc *)arg,
  61109. + sizeof(struct pxp_mem_desc));
  61110. + if (ret)
  61111. + return -EFAULT;
  61112. +
  61113. + pr_debug("[ALLOC] mem alloc size = 0x%x\n",
  61114. + buffer.size);
  61115. +
  61116. + obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  61117. + if (!obj)
  61118. + return -ENOMEM;
  61119. + obj->size = buffer.size;
  61120. + obj->mem_type = buffer.mtype;
  61121. +
  61122. + ret = pxp_alloc_dma_buffer(obj);
  61123. + if (ret == -1) {
  61124. + printk(KERN_ERR
  61125. + "Physical memory allocation error!\n");
  61126. + kfree(obj);
  61127. + return ret;
  61128. + }
  61129. +
  61130. + ret = pxp_buffer_handle_create(file_priv, obj, &obj->handle);
  61131. + if (ret) {
  61132. + pxp_free_dma_buffer(obj);
  61133. + kfree(obj);
  61134. + return ret;
  61135. + }
  61136. + buffer.handle = obj->handle;
  61137. + buffer.phys_addr = obj->offset;
  61138. +
  61139. + ret = copy_to_user((void __user *)arg, &buffer,
  61140. + sizeof(struct pxp_mem_desc));
  61141. + if (ret) {
  61142. + pxp_buffer_handle_delete(file_priv, buffer.handle);
  61143. + pxp_free_dma_buffer(obj);
  61144. + kfree(obj);
  61145. + return -EFAULT;
  61146. + }
  61147. +
  61148. + pxp_ht_insert_item(&bufhash, obj);
  61149. +
  61150. + break;
  61151. + }
  61152. + case PXP_IOC_PUT_PHYMEM:
  61153. + {
  61154. + struct pxp_mem_desc pxp_mem;
  61155. + struct pxp_buf_obj *obj;
  61156. +
  61157. + ret = copy_from_user(&pxp_mem,
  61158. + (struct pxp_mem_desc *)arg,
  61159. + sizeof(struct pxp_mem_desc));
  61160. + if (ret)
  61161. + return -EACCES;
  61162. +
  61163. + obj = pxp_buffer_object_lookup(file_priv, pxp_mem.handle);
  61164. + if (!obj)
  61165. + return -EINVAL;
  61166. +
  61167. + ret = pxp_buffer_handle_delete(file_priv, obj->handle);
  61168. + if (ret)
  61169. + return ret;
  61170. +
  61171. + pxp_ht_remove_item(&bufhash, obj);
  61172. + pxp_free_dma_buffer(obj);
  61173. + kfree(obj);
  61174. +
  61175. + break;
  61176. + }
  61177. + case PXP_IOC_FLUSH_PHYMEM:
  61178. + {
  61179. + int ret;
  61180. + struct pxp_mem_flush flush;
  61181. + struct pxp_buf_obj *obj;
  61182. +
  61183. + ret = copy_from_user(&flush,
  61184. + (struct pxp_mem_flush *)arg,
  61185. + sizeof(struct pxp_mem_flush));
  61186. + if (ret)
  61187. + return -EACCES;
  61188. +
  61189. + obj = pxp_buffer_object_lookup(file_priv, flush.handle);
  61190. + if (!obj)
  61191. + return -EINVAL;
  61192. +
  61193. + switch (flush.type) {
  61194. + case CACHE_CLEAN:
  61195. + dma_sync_single_for_device(NULL, obj->offset,
  61196. + obj->size, DMA_TO_DEVICE);
  61197. + break;
  61198. + case CACHE_INVALIDATE:
  61199. + dma_sync_single_for_device(NULL, obj->offset,
  61200. + obj->size, DMA_FROM_DEVICE);
  61201. + break;
  61202. + case CACHE_FLUSH:
  61203. + dma_sync_single_for_device(NULL, obj->offset,
  61204. + obj->size, DMA_TO_DEVICE);
  61205. + dma_sync_single_for_device(NULL, obj->offset,
  61206. + obj->size, DMA_FROM_DEVICE);
  61207. + break;
  61208. + default:
  61209. + pr_err("%s: invalid cache flush type\n", __func__);
  61210. + return -EINVAL;
  61211. + }
  61212. +
  61213. + break;
  61214. + }
  61215. + case PXP_IOC_WAIT4CMPLT:
  61216. + {
  61217. + struct pxp_chan_handle chan_handle;
  61218. + int ret, chan_id, handle;
  61219. + struct pxp_chan_obj *obj = NULL;
  61220. +
  61221. + ret = copy_from_user(&chan_handle,
  61222. + (struct pxp_chan_handle *)arg,
  61223. + sizeof(struct pxp_chan_handle));
  61224. + if (ret)
  61225. + return -EFAULT;
  61226. +
  61227. + handle = chan_handle.handle;
  61228. + obj = pxp_channel_object_lookup(file_priv, handle);
  61229. + if (!obj)
  61230. + return -EINVAL;
  61231. + chan_id = obj->chan->chan_id;
  61232. +
  61233. + ret = wait_event_interruptible
  61234. + (irq_info[chan_id].waitq,
  61235. + (atomic_read(&irq_info[chan_id].irq_pending) == 0));
  61236. + if (ret < 0) {
  61237. + printk(KERN_WARNING
  61238. + "WAIT4CMPLT: signal received.\n");
  61239. + return -ERESTARTSYS;
  61240. + }
  61241. +
  61242. + chan_handle.hist_status = irq_info[chan_id].hist_status;
  61243. + ret = copy_to_user((struct pxp_chan_handle *)arg,
  61244. + &chan_handle,
  61245. + sizeof(struct pxp_chan_handle));
  61246. + if (ret)
  61247. + return -EFAULT;
  61248. + break;
  61249. + }
  61250. + default:
  61251. + break;
  61252. + }
  61253. +
  61254. + return 0;
  61255. +}
  61256. +
  61257. +static const struct file_operations pxp_device_fops = {
  61258. + .open = pxp_device_open,
  61259. + .release = pxp_device_release,
  61260. + .unlocked_ioctl = pxp_device_ioctl,
  61261. + .mmap = pxp_device_mmap,
  61262. +};
  61263. +
  61264. +static struct miscdevice pxp_device_miscdev = {
  61265. + .minor = MISC_DYNAMIC_MINOR,
  61266. + .name = "pxp_device",
  61267. + .fops = &pxp_device_fops,
  61268. +};
  61269. +
  61270. +int register_pxp_device(void)
  61271. +{
  61272. + int ret;
  61273. +
  61274. + ret = misc_register(&pxp_device_miscdev);
  61275. + if (ret)
  61276. + return ret;
  61277. +
  61278. + ret = pxp_ht_create(&bufhash, BUFFER_HASH_ORDER);
  61279. + if (ret)
  61280. + return ret;
  61281. + spin_lock_init(&(bufhash.hash_lock));
  61282. +
  61283. + pr_debug("PxP_Device registered Successfully\n");
  61284. + return 0;
  61285. +}
  61286. +
  61287. +void unregister_pxp_device(void)
  61288. +{
  61289. + pxp_ht_destroy(&bufhash);
  61290. + misc_deregister(&pxp_device_miscdev);
  61291. +}
  61292. diff -Nur linux-3.14.17/drivers/dma/pxp/pxp_dma_v2.c linux-imx6-3.14/drivers/dma/pxp/pxp_dma_v2.c
  61293. --- linux-3.14.17/drivers/dma/pxp/pxp_dma_v2.c 1970-01-01 01:00:00.000000000 +0100
  61294. +++ linux-imx6-3.14/drivers/dma/pxp/pxp_dma_v2.c 2014-09-11 18:06:00.198030770 +0200
  61295. @@ -0,0 +1,1854 @@
  61296. +/*
  61297. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
  61298. + *
  61299. + * This program is free software; you can redistribute it and/or modify
  61300. + * it under the terms of the GNU General Public License as published by
  61301. + * the Free Software Foundation; either version 2 of the License, or
  61302. + * (at your option) any later version.
  61303. + *
  61304. + * This program is distributed in the hope that it will be useful,
  61305. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  61306. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  61307. + * GNU General Public License for more details.
  61308. + *
  61309. + * You should have received a copy of the GNU General Public License
  61310. + * along with this program; if not, write to the Free Software
  61311. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  61312. + *
  61313. + */
  61314. +/*
  61315. + * Based on STMP378X PxP driver
  61316. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  61317. + */
  61318. +
  61319. +#include <linux/dma-mapping.h>
  61320. +#include <linux/init.h>
  61321. +#include <linux/interrupt.h>
  61322. +#include <linux/io.h>
  61323. +#include <linux/kernel.h>
  61324. +#include <linux/module.h>
  61325. +#include <linux/mutex.h>
  61326. +#include <linux/platform_device.h>
  61327. +#include <linux/slab.h>
  61328. +#include <linux/vmalloc.h>
  61329. +#include <linux/dmaengine.h>
  61330. +#include <linux/pxp_dma.h>
  61331. +#include <linux/timer.h>
  61332. +#include <linux/clk.h>
  61333. +#include <linux/workqueue.h>
  61334. +#include <linux/sched.h>
  61335. +#include <linux/of.h>
  61336. +#include <linux/kthread.h>
  61337. +
  61338. +#include "regs-pxp_v2.h"
  61339. +
  61340. +#define PXP_DOWNSCALE_THRESHOLD 0x4000
  61341. +
  61342. +static LIST_HEAD(head);
  61343. +static int timeout_in_ms = 600;
  61344. +static unsigned int block_size;
  61345. +static struct kmem_cache *tx_desc_cache;
  61346. +
  61347. +struct pxp_dma {
  61348. + struct dma_device dma;
  61349. +};
  61350. +
  61351. +struct pxps {
  61352. + struct platform_device *pdev;
  61353. + struct clk *clk;
  61354. + void __iomem *base;
  61355. + int irq; /* PXP IRQ to the CPU */
  61356. +
  61357. + spinlock_t lock;
  61358. + struct mutex clk_mutex;
  61359. + int clk_stat;
  61360. +#define CLK_STAT_OFF 0
  61361. +#define CLK_STAT_ON 1
  61362. + int pxp_ongoing;
  61363. + int lut_state;
  61364. +
  61365. + struct device *dev;
  61366. + struct pxp_dma pxp_dma;
  61367. + struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
  61368. + struct work_struct work;
  61369. +
  61370. + /* describes most recent processing configuration */
  61371. + struct pxp_config_data pxp_conf_state;
  61372. +
  61373. + /* to turn clock off when pxp is inactive */
  61374. + struct timer_list clk_timer;
  61375. +
  61376. + /* for pxp config dispatch asynchronously*/
  61377. + struct task_struct *dispatch;
  61378. + wait_queue_head_t thread_waitq;
  61379. + struct completion complete;
  61380. +};
  61381. +
  61382. +#define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
  61383. +#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
  61384. +#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
  61385. +#define to_pxp(id) container_of(id, struct pxps, pxp_dma)
  61386. +
  61387. +#define PXP_DEF_BUFS 2
  61388. +#define PXP_MIN_PIX 8
  61389. +
  61390. +static uint32_t pxp_s0_formats[] = {
  61391. + PXP_PIX_FMT_RGB32,
  61392. + PXP_PIX_FMT_RGB565,
  61393. + PXP_PIX_FMT_RGB555,
  61394. + PXP_PIX_FMT_YUV420P,
  61395. + PXP_PIX_FMT_YUV422P,
  61396. +};
  61397. +
  61398. +/*
  61399. + * PXP common functions
  61400. + */
  61401. +static void dump_pxp_reg(struct pxps *pxp)
  61402. +{
  61403. + dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
  61404. + __raw_readl(pxp->base + HW_PXP_CTRL));
  61405. + dev_dbg(pxp->dev, "PXP_STAT 0x%x",
  61406. + __raw_readl(pxp->base + HW_PXP_STAT));
  61407. + dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
  61408. + __raw_readl(pxp->base + HW_PXP_OUT_CTRL));
  61409. + dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
  61410. + __raw_readl(pxp->base + HW_PXP_OUT_BUF));
  61411. + dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
  61412. + __raw_readl(pxp->base + HW_PXP_OUT_BUF2));
  61413. + dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
  61414. + __raw_readl(pxp->base + HW_PXP_OUT_PITCH));
  61415. + dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
  61416. + __raw_readl(pxp->base + HW_PXP_OUT_LRC));
  61417. + dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
  61418. + __raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
  61419. + dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
  61420. + __raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
  61421. + dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
  61422. + __raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
  61423. + dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
  61424. + __raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
  61425. + dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
  61426. + __raw_readl(pxp->base + HW_PXP_PS_CTRL));
  61427. + dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
  61428. + __raw_readl(pxp->base + HW_PXP_PS_BUF));
  61429. + dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
  61430. + __raw_readl(pxp->base + HW_PXP_PS_UBUF));
  61431. + dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
  61432. + __raw_readl(pxp->base + HW_PXP_PS_VBUF));
  61433. + dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
  61434. + __raw_readl(pxp->base + HW_PXP_PS_PITCH));
  61435. + dev_dbg(pxp->dev, "PXP_PS_BACKGROUND 0x%x",
  61436. + __raw_readl(pxp->base + HW_PXP_PS_BACKGROUND));
  61437. + dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
  61438. + __raw_readl(pxp->base + HW_PXP_PS_SCALE));
  61439. + dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
  61440. + __raw_readl(pxp->base + HW_PXP_PS_OFFSET));
  61441. + dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW 0x%x",
  61442. + __raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW));
  61443. + dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
  61444. + __raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH));
  61445. + dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
  61446. + __raw_readl(pxp->base + HW_PXP_AS_CTRL));
  61447. + dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
  61448. + __raw_readl(pxp->base + HW_PXP_AS_BUF));
  61449. + dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
  61450. + __raw_readl(pxp->base + HW_PXP_AS_PITCH));
  61451. + dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
  61452. + __raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW));
  61453. + dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
  61454. + __raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH));
  61455. + dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
  61456. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
  61457. + dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
  61458. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
  61459. + dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
  61460. + __raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
  61461. + dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
  61462. + __raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
  61463. + dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
  61464. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
  61465. + dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
  61466. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
  61467. + dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
  61468. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
  61469. + dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
  61470. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
  61471. + dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
  61472. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
  61473. + dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
  61474. + __raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
  61475. + dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
  61476. + __raw_readl(pxp->base + HW_PXP_LUT_CTRL));
  61477. + dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
  61478. + __raw_readl(pxp->base + HW_PXP_LUT_ADDR));
  61479. + dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
  61480. + __raw_readl(pxp->base + HW_PXP_LUT_DATA));
  61481. + dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
  61482. + __raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
  61483. + dev_dbg(pxp->dev, "PXP_CFA 0x%x",
  61484. + __raw_readl(pxp->base + HW_PXP_CFA));
  61485. + dev_dbg(pxp->dev, "PXP_HIST_CTRL 0x%x",
  61486. + __raw_readl(pxp->base + HW_PXP_HIST_CTRL));
  61487. + dev_dbg(pxp->dev, "PXP_HIST2_PARAM 0x%x",
  61488. + __raw_readl(pxp->base + HW_PXP_HIST2_PARAM));
  61489. + dev_dbg(pxp->dev, "PXP_HIST4_PARAM 0x%x",
  61490. + __raw_readl(pxp->base + HW_PXP_HIST4_PARAM));
  61491. + dev_dbg(pxp->dev, "PXP_HIST8_PARAM0 0x%x",
  61492. + __raw_readl(pxp->base + HW_PXP_HIST8_PARAM0));
  61493. + dev_dbg(pxp->dev, "PXP_HIST8_PARAM1 0x%x",
  61494. + __raw_readl(pxp->base + HW_PXP_HIST8_PARAM1));
  61495. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM0 0x%x",
  61496. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM0));
  61497. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM1 0x%x",
  61498. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM1));
  61499. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM2 0x%x",
  61500. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM2));
  61501. + dev_dbg(pxp->dev, "PXP_HIST16_PARAM3 0x%x",
  61502. + __raw_readl(pxp->base + HW_PXP_HIST16_PARAM3));
  61503. + dev_dbg(pxp->dev, "PXP_POWER 0x%x",
  61504. + __raw_readl(pxp->base + HW_PXP_POWER));
  61505. + dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
  61506. + __raw_readl(pxp->base + HW_PXP_NEXT));
  61507. + dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
  61508. + __raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
  61509. + dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
  61510. + __raw_readl(pxp->base + HW_PXP_DEBUG));
  61511. + dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
  61512. + __raw_readl(pxp->base + HW_PXP_VERSION));
  61513. +}
  61514. +
  61515. +static bool is_yuv(u32 pix_fmt)
  61516. +{
  61517. + if ((pix_fmt == PXP_PIX_FMT_YUYV) |
  61518. + (pix_fmt == PXP_PIX_FMT_UYVY) |
  61519. + (pix_fmt == PXP_PIX_FMT_YVYU) |
  61520. + (pix_fmt == PXP_PIX_FMT_VYUY) |
  61521. + (pix_fmt == PXP_PIX_FMT_Y41P) |
  61522. + (pix_fmt == PXP_PIX_FMT_YUV444) |
  61523. + (pix_fmt == PXP_PIX_FMT_NV12) |
  61524. + (pix_fmt == PXP_PIX_FMT_NV16) |
  61525. + (pix_fmt == PXP_PIX_FMT_NV61) |
  61526. + (pix_fmt == PXP_PIX_FMT_GREY) |
  61527. + (pix_fmt == PXP_PIX_FMT_GY04) |
  61528. + (pix_fmt == PXP_PIX_FMT_YVU410P) |
  61529. + (pix_fmt == PXP_PIX_FMT_YUV410P) |
  61530. + (pix_fmt == PXP_PIX_FMT_YVU420P) |
  61531. + (pix_fmt == PXP_PIX_FMT_YUV420P) |
  61532. + (pix_fmt == PXP_PIX_FMT_YUV420P2) |
  61533. + (pix_fmt == PXP_PIX_FMT_YVU422P) |
  61534. + (pix_fmt == PXP_PIX_FMT_YUV422P)) {
  61535. + return true;
  61536. + } else {
  61537. + return false;
  61538. + }
  61539. +}
  61540. +
  61541. +static void pxp_set_ctrl(struct pxps *pxp)
  61542. +{
  61543. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61544. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  61545. + u32 ctrl;
  61546. + u32 fmt_ctrl;
  61547. + int need_swap = 0; /* to support YUYV and YVYU formats */
  61548. +
  61549. + /* Configure S0 input format */
  61550. + switch (pxp_conf->s0_param.pixel_fmt) {
  61551. + case PXP_PIX_FMT_RGB32:
  61552. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
  61553. + break;
  61554. + case PXP_PIX_FMT_RGB565:
  61555. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
  61556. + break;
  61557. + case PXP_PIX_FMT_RGB555:
  61558. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
  61559. + break;
  61560. + case PXP_PIX_FMT_YUV420P:
  61561. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  61562. + break;
  61563. + case PXP_PIX_FMT_YVU420P:
  61564. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
  61565. + break;
  61566. + case PXP_PIX_FMT_GREY:
  61567. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
  61568. + break;
  61569. + case PXP_PIX_FMT_GY04:
  61570. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y4;
  61571. + break;
  61572. + case PXP_PIX_FMT_YUV422P:
  61573. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
  61574. + break;
  61575. + case PXP_PIX_FMT_UYVY:
  61576. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  61577. + break;
  61578. + case PXP_PIX_FMT_YUYV:
  61579. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
  61580. + need_swap = 1;
  61581. + break;
  61582. + case PXP_PIX_FMT_VYUY:
  61583. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  61584. + break;
  61585. + case PXP_PIX_FMT_YVYU:
  61586. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
  61587. + need_swap = 1;
  61588. + break;
  61589. + case PXP_PIX_FMT_NV12:
  61590. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P420;
  61591. + break;
  61592. + case PXP_PIX_FMT_NV21:
  61593. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P420;
  61594. + break;
  61595. + case PXP_PIX_FMT_NV16:
  61596. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P422;
  61597. + break;
  61598. + case PXP_PIX_FMT_NV61:
  61599. + fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P422;
  61600. + break;
  61601. + default:
  61602. + fmt_ctrl = 0;
  61603. + }
  61604. +
  61605. + ctrl = BF_PXP_PS_CTRL_FORMAT(fmt_ctrl) | BF_PXP_PS_CTRL_SWAP(need_swap);
  61606. + __raw_writel(ctrl, pxp->base + HW_PXP_PS_CTRL_SET);
  61607. +
  61608. + /* Configure output format based on out_channel format */
  61609. + switch (pxp_conf->out_param.pixel_fmt) {
  61610. + case PXP_PIX_FMT_RGB32:
  61611. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
  61612. + break;
  61613. + case PXP_PIX_FMT_BGRA32:
  61614. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
  61615. + break;
  61616. + case PXP_PIX_FMT_RGB24:
  61617. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888P;
  61618. + break;
  61619. + case PXP_PIX_FMT_RGB565:
  61620. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
  61621. + break;
  61622. + case PXP_PIX_FMT_RGB555:
  61623. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
  61624. + break;
  61625. + case PXP_PIX_FMT_GREY:
  61626. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
  61627. + break;
  61628. + case PXP_PIX_FMT_GY04:
  61629. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y4;
  61630. + break;
  61631. + case PXP_PIX_FMT_UYVY:
  61632. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
  61633. + break;
  61634. + case PXP_PIX_FMT_VYUY:
  61635. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
  61636. + break;
  61637. + case PXP_PIX_FMT_NV12:
  61638. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
  61639. + break;
  61640. + case PXP_PIX_FMT_NV21:
  61641. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
  61642. + break;
  61643. + case PXP_PIX_FMT_NV16:
  61644. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
  61645. + break;
  61646. + case PXP_PIX_FMT_NV61:
  61647. + fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
  61648. + break;
  61649. + default:
  61650. + fmt_ctrl = 0;
  61651. + }
  61652. +
  61653. + ctrl = BF_PXP_OUT_CTRL_FORMAT(fmt_ctrl);
  61654. + __raw_writel(ctrl, pxp->base + HW_PXP_OUT_CTRL);
  61655. +
  61656. + ctrl = 0;
  61657. + if (proc_data->scaling)
  61658. + ;
  61659. + if (proc_data->vflip)
  61660. + ctrl |= BM_PXP_CTRL_VFLIP;
  61661. + if (proc_data->hflip)
  61662. + ctrl |= BM_PXP_CTRL_HFLIP;
  61663. + if (proc_data->rotate) {
  61664. + ctrl |= BF_PXP_CTRL_ROTATE(proc_data->rotate / 90);
  61665. + if (proc_data->rot_pos)
  61666. + ctrl |= BM_PXP_CTRL_ROT_POS;
  61667. + }
  61668. +
  61669. + /* In default, the block size is set to 8x8
  61670. + * But block size can be set to 16x16 due to
  61671. + * blocksize variable modification
  61672. + */
  61673. + ctrl |= block_size << 23;
  61674. +
  61675. + __raw_writel(ctrl, pxp->base + HW_PXP_CTRL);
  61676. +}
  61677. +
  61678. +static int pxp_start(struct pxps *pxp)
  61679. +{
  61680. + __raw_writel(BM_PXP_CTRL_IRQ_ENABLE, pxp->base + HW_PXP_CTRL_SET);
  61681. + __raw_writel(BM_PXP_CTRL_ENABLE, pxp->base + HW_PXP_CTRL_SET);
  61682. + dump_pxp_reg(pxp);
  61683. +
  61684. + return 0;
  61685. +}
  61686. +
  61687. +static void pxp_set_outbuf(struct pxps *pxp)
  61688. +{
  61689. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61690. + struct pxp_layer_param *out_params = &pxp_conf->out_param;
  61691. +
  61692. + __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
  61693. +
  61694. + __raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) |
  61695. + BF_PXP_OUT_LRC_Y(out_params->height - 1),
  61696. + pxp->base + HW_PXP_OUT_LRC);
  61697. +
  61698. + if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) {
  61699. + __raw_writel(out_params->stride * 3,
  61700. + pxp->base + HW_PXP_OUT_PITCH);
  61701. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_BGRA32 ||
  61702. + out_params->pixel_fmt == PXP_PIX_FMT_RGB32) {
  61703. + __raw_writel(out_params->stride << 2,
  61704. + pxp->base + HW_PXP_OUT_PITCH);
  61705. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_RGB565) {
  61706. + __raw_writel(out_params->stride << 1,
  61707. + pxp->base + HW_PXP_OUT_PITCH);
  61708. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  61709. + (out_params->pixel_fmt == PXP_PIX_FMT_VYUY)) {
  61710. + __raw_writel(out_params->stride << 1,
  61711. + pxp->base + HW_PXP_OUT_PITCH);
  61712. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  61713. + out_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  61714. + out_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  61715. + out_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  61716. + out_params->pixel_fmt == PXP_PIX_FMT_NV61) {
  61717. + __raw_writel(out_params->stride,
  61718. + pxp->base + HW_PXP_OUT_PITCH);
  61719. + } else if (out_params->pixel_fmt == PXP_PIX_FMT_GY04) {
  61720. + __raw_writel(out_params->stride >> 1,
  61721. + pxp->base + HW_PXP_OUT_PITCH);
  61722. + } else {
  61723. + __raw_writel(0, pxp->base + HW_PXP_OUT_PITCH);
  61724. + }
  61725. +
  61726. + /* set global alpha if necessary */
  61727. + if (out_params->global_alpha_enable) {
  61728. + __raw_writel(out_params->global_alpha << 24,
  61729. + pxp->base + HW_PXP_OUT_CTRL_SET);
  61730. + __raw_writel(BM_PXP_OUT_CTRL_ALPHA_OUTPUT,
  61731. + pxp->base + HW_PXP_OUT_CTRL_SET);
  61732. + }
  61733. +}
  61734. +
  61735. +static void pxp_set_s0colorkey(struct pxps *pxp)
  61736. +{
  61737. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61738. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  61739. +
  61740. + /* Low and high are set equal. V4L does not allow a chromakey range */
  61741. + if (s0_params->color_key_enable == 0 || s0_params->color_key == -1) {
  61742. + /* disable color key */
  61743. + __raw_writel(0xFFFFFF, pxp->base + HW_PXP_PS_CLRKEYLOW);
  61744. + __raw_writel(0, pxp->base + HW_PXP_PS_CLRKEYHIGH);
  61745. + } else {
  61746. + __raw_writel(s0_params->color_key,
  61747. + pxp->base + HW_PXP_PS_CLRKEYLOW);
  61748. + __raw_writel(s0_params->color_key,
  61749. + pxp->base + HW_PXP_PS_CLRKEYHIGH);
  61750. + }
  61751. +}
  61752. +
  61753. +static void pxp_set_olcolorkey(int layer_no, struct pxps *pxp)
  61754. +{
  61755. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61756. + struct pxp_layer_param *ol_params = &pxp_conf->ol_param[layer_no];
  61757. +
  61758. + /* Low and high are set equal. V4L does not allow a chromakey range */
  61759. + if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
  61760. + __raw_writel(ol_params->color_key,
  61761. + pxp->base + HW_PXP_AS_CLRKEYLOW);
  61762. + __raw_writel(ol_params->color_key,
  61763. + pxp->base + HW_PXP_AS_CLRKEYHIGH);
  61764. + } else {
  61765. + /* disable color key */
  61766. + __raw_writel(0xFFFFFF, pxp->base + HW_PXP_AS_CLRKEYLOW);
  61767. + __raw_writel(0, pxp->base + HW_PXP_AS_CLRKEYHIGH);
  61768. + }
  61769. +}
  61770. +
  61771. +static void pxp_set_oln(int layer_no, struct pxps *pxp)
  61772. +{
  61773. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61774. + struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  61775. + dma_addr_t phys_addr = olparams_data->paddr;
  61776. + u32 pitch = olparams_data->stride ? olparams_data->stride :
  61777. + olparams_data->width;
  61778. +
  61779. + __raw_writel(phys_addr, pxp->base + HW_PXP_AS_BUF);
  61780. +
  61781. + /* Fixme */
  61782. + if (olparams_data->width == 0 && olparams_data->height == 0) {
  61783. + __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_AS_ULC);
  61784. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_LRC);
  61785. + } else {
  61786. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_ULC);
  61787. + if (pxp_conf->proc_data.rotate == 90 ||
  61788. + pxp_conf->proc_data.rotate == 270) {
  61789. + if (pxp_conf->proc_data.rot_pos == 1) {
  61790. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->height - 1) |
  61791. + BF_PXP_OUT_AS_LRC_Y(olparams_data->width - 1),
  61792. + pxp->base + HW_PXP_OUT_AS_LRC);
  61793. + } else {
  61794. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
  61795. + BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
  61796. + pxp->base + HW_PXP_OUT_AS_LRC);
  61797. + }
  61798. + } else {
  61799. + __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
  61800. + BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
  61801. + pxp->base + HW_PXP_OUT_AS_LRC);
  61802. + }
  61803. + }
  61804. +
  61805. + if ((olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) |
  61806. + (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32)) {
  61807. + __raw_writel(pitch << 2,
  61808. + pxp->base + HW_PXP_AS_PITCH);
  61809. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
  61810. + __raw_writel(pitch << 1,
  61811. + pxp->base + HW_PXP_AS_PITCH);
  61812. + } else {
  61813. + __raw_writel(0, pxp->base + HW_PXP_AS_PITCH);
  61814. + }
  61815. +}
  61816. +
  61817. +static void pxp_set_olparam(int layer_no, struct pxps *pxp)
  61818. +{
  61819. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61820. + struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
  61821. + u32 olparam;
  61822. +
  61823. + olparam = BF_PXP_AS_CTRL_ALPHA(olparams_data->global_alpha);
  61824. + if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32) {
  61825. + olparam |=
  61826. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB888);
  61827. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) {
  61828. + olparam |=
  61829. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__ARGB8888);
  61830. + if (!olparams_data->combine_enable) {
  61831. + olparam |=
  61832. + BF_PXP_AS_CTRL_ALPHA_CTRL
  61833. + (BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs);
  61834. + olparam |= 0x3 << 16;
  61835. + }
  61836. + } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
  61837. + olparam |=
  61838. + BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB565);
  61839. + }
  61840. + if (olparams_data->global_alpha_enable) {
  61841. + if (olparams_data->global_override) {
  61842. + olparam |=
  61843. + BF_PXP_AS_CTRL_ALPHA_CTRL
  61844. + (BV_PXP_AS_CTRL_ALPHA_CTRL__Override);
  61845. + } else {
  61846. + olparam |=
  61847. + BF_PXP_AS_CTRL_ALPHA_CTRL
  61848. + (BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply);
  61849. + }
  61850. + if (olparams_data->alpha_invert)
  61851. + olparam |= BM_PXP_AS_CTRL_ALPHA_INVERT;
  61852. + }
  61853. + if (olparams_data->color_key_enable)
  61854. + olparam |= BM_PXP_AS_CTRL_ENABLE_COLORKEY;
  61855. +
  61856. + __raw_writel(olparam, pxp->base + HW_PXP_AS_CTRL);
  61857. +}
  61858. +
  61859. +static void pxp_set_s0param(struct pxps *pxp)
  61860. +{
  61861. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61862. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  61863. + u32 s0param;
  61864. +
  61865. + /* contains the coordinate for the PS in the OUTPUT buffer. */
  61866. + if ((pxp_conf->s0_param).width == 0 &&
  61867. + (pxp_conf->s0_param).height == 0) {
  61868. + __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_PS_ULC);
  61869. + __raw_writel(0x0, pxp->base + HW_PXP_OUT_PS_LRC);
  61870. + } else {
  61871. + s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left);
  61872. + s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top);
  61873. + __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC);
  61874. + s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left +
  61875. + proc_data->drect.width - 1);
  61876. + s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top +
  61877. + proc_data->drect.height - 1);
  61878. + __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC);
  61879. + }
  61880. +}
  61881. +
  61882. +/* crop behavior is re-designed in h/w. */
  61883. +static void pxp_set_s0crop(struct pxps *pxp)
  61884. +{
  61885. + /*
  61886. + * place-holder, it's implemented in other functions in this driver.
  61887. + * Refer to "Clipping source images" section in RM for detail.
  61888. + */
  61889. +}
  61890. +
  61891. +static int pxp_set_scaling(struct pxps *pxp)
  61892. +{
  61893. + int ret = 0;
  61894. + u32 xscale, yscale, s0scale;
  61895. + u32 decx, decy, xdec = 0, ydec = 0;
  61896. + struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
  61897. +
  61898. + if (((proc_data->srect.width == proc_data->drect.width) &&
  61899. + (proc_data->srect.height == proc_data->drect.height)) ||
  61900. + ((proc_data->srect.width == 0) && (proc_data->srect.height == 0))) {
  61901. + proc_data->scaling = 0;
  61902. + __raw_writel(0x10001000, pxp->base + HW_PXP_PS_SCALE);
  61903. + __raw_writel(0, pxp->base + HW_PXP_PS_CTRL);
  61904. + goto out;
  61905. + }
  61906. +
  61907. + proc_data->scaling = 1;
  61908. + decx = proc_data->srect.width / proc_data->drect.width;
  61909. + decy = proc_data->srect.height / proc_data->drect.height;
  61910. + if (decx > 0) {
  61911. + if (decx >= 2 && decx < 4) {
  61912. + decx = 2;
  61913. + xdec = 1;
  61914. + } else if (decx >= 4 && decx < 8) {
  61915. + decx = 4;
  61916. + xdec = 2;
  61917. + } else if (decx >= 8) {
  61918. + decx = 8;
  61919. + xdec = 3;
  61920. + }
  61921. + xscale = proc_data->srect.width * 0x1000 /
  61922. + (proc_data->drect.width * decx);
  61923. + } else
  61924. + xscale = proc_data->srect.width * 0x1000 /
  61925. + proc_data->drect.width;
  61926. + if (decy > 0) {
  61927. + if (decy >= 2 && decy < 4) {
  61928. + decy = 2;
  61929. + ydec = 1;
  61930. + } else if (decy >= 4 && decy < 8) {
  61931. + decy = 4;
  61932. + ydec = 2;
  61933. + } else if (decy >= 8) {
  61934. + decy = 8;
  61935. + ydec = 3;
  61936. + }
  61937. + yscale = proc_data->srect.height * 0x1000 /
  61938. + (proc_data->drect.height * decy);
  61939. + } else
  61940. + yscale = proc_data->srect.height * 0x1000 /
  61941. + proc_data->drect.height;
  61942. +
  61943. + __raw_writel((xdec << 10) | (ydec << 8), pxp->base + HW_PXP_PS_CTRL);
  61944. +
  61945. + if (xscale > PXP_DOWNSCALE_THRESHOLD)
  61946. + xscale = PXP_DOWNSCALE_THRESHOLD;
  61947. + if (yscale > PXP_DOWNSCALE_THRESHOLD)
  61948. + yscale = PXP_DOWNSCALE_THRESHOLD;
  61949. + s0scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
  61950. + BF_PXP_PS_SCALE_XSCALE(xscale);
  61951. + __raw_writel(s0scale, pxp->base + HW_PXP_PS_SCALE);
  61952. +
  61953. +out:
  61954. + pxp_set_ctrl(pxp);
  61955. +
  61956. + return ret;
  61957. +}
  61958. +
  61959. +static void pxp_set_bg(struct pxps *pxp)
  61960. +{
  61961. + __raw_writel(pxp->pxp_conf_state.proc_data.bgcolor,
  61962. + pxp->base + HW_PXP_PS_BACKGROUND);
  61963. +}
  61964. +
  61965. +static void pxp_set_lut(struct pxps *pxp)
  61966. +{
  61967. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  61968. + int lut_op = pxp_conf->proc_data.lut_transform;
  61969. + u32 reg_val;
  61970. + int i;
  61971. + bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
  61972. + u8 *cmap = pxp_conf->proc_data.lut_map;
  61973. + u32 entry_src;
  61974. + u32 pix_val;
  61975. + u8 entry[4];
  61976. +
  61977. + /*
  61978. + * If LUT already configured as needed, return...
  61979. + * Unless CMAP is needed and it has been updated.
  61980. + */
  61981. + if ((pxp->lut_state == lut_op) &&
  61982. + !(use_cmap && pxp_conf->proc_data.lut_map_updated))
  61983. + return;
  61984. +
  61985. + if (lut_op == PXP_LUT_NONE) {
  61986. + __raw_writel(BM_PXP_LUT_CTRL_BYPASS,
  61987. + pxp->base + HW_PXP_LUT_CTRL);
  61988. + } else if (((lut_op & PXP_LUT_INVERT) != 0)
  61989. + && ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
  61990. + /* Fill out LUT table with inverted monochromized values */
  61991. +
  61992. + /* clear bypass bit, set lookup mode & out mode */
  61993. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  61994. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  61995. + BF_PXP_LUT_CTRL_OUT_MODE
  61996. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  61997. + pxp->base + HW_PXP_LUT_CTRL);
  61998. +
  61999. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  62000. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  62001. +
  62002. + /* LUT address pointer auto-increments after each data write */
  62003. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  62004. + for (i = 0; i < 4; i++) {
  62005. + entry_src = use_cmap ?
  62006. + cmap[pix_val + i] : pix_val + i;
  62007. + entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
  62008. + }
  62009. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  62010. + (entry[1] << 8) | entry[0];
  62011. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  62012. + }
  62013. + } else if ((lut_op & PXP_LUT_INVERT) != 0) {
  62014. + /* Fill out LUT table with 8-bit inverted values */
  62015. +
  62016. + /* clear bypass bit, set lookup mode & out mode */
  62017. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  62018. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  62019. + BF_PXP_LUT_CTRL_OUT_MODE
  62020. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  62021. + pxp->base + HW_PXP_LUT_CTRL);
  62022. +
  62023. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  62024. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  62025. +
  62026. + /* LUT address pointer auto-increments after each data write */
  62027. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  62028. + for (i = 0; i < 4; i++) {
  62029. + entry_src = use_cmap ?
  62030. + cmap[pix_val + i] : pix_val + i;
  62031. + entry[i] = ~entry_src & 0xFF;
  62032. + }
  62033. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  62034. + (entry[1] << 8) | entry[0];
  62035. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  62036. + }
  62037. + } else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
  62038. + /* Fill out LUT table with 8-bit monochromized values */
  62039. +
  62040. + /* clear bypass bit, set lookup mode & out mode */
  62041. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  62042. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  62043. + BF_PXP_LUT_CTRL_OUT_MODE
  62044. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  62045. + pxp->base + HW_PXP_LUT_CTRL);
  62046. +
  62047. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  62048. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  62049. +
  62050. + /* LUT address pointer auto-increments after each data write */
  62051. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  62052. + for (i = 0; i < 4; i++) {
  62053. + entry_src = use_cmap ?
  62054. + cmap[pix_val + i] : pix_val + i;
  62055. + entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
  62056. + }
  62057. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  62058. + (entry[1] << 8) | entry[0];
  62059. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  62060. + }
  62061. + } else if (use_cmap) {
  62062. + /* Fill out LUT table using colormap values */
  62063. +
  62064. + /* clear bypass bit, set lookup mode & out mode */
  62065. + __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
  62066. + (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
  62067. + BF_PXP_LUT_CTRL_OUT_MODE
  62068. + (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
  62069. + pxp->base + HW_PXP_LUT_CTRL);
  62070. +
  62071. + /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
  62072. + __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
  62073. +
  62074. + /* LUT address pointer auto-increments after each data write */
  62075. + for (pix_val = 0; pix_val < 256; pix_val += 4) {
  62076. + for (i = 0; i < 4; i++)
  62077. + entry[i] = cmap[pix_val + i];
  62078. + reg_val = (entry[3] << 24) | (entry[2] << 16) |
  62079. + (entry[1] << 8) | entry[0];
  62080. + __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
  62081. + }
  62082. + }
  62083. +
  62084. + pxp->lut_state = lut_op;
  62085. +}
  62086. +
  62087. +static void pxp_set_csc(struct pxps *pxp)
  62088. +{
  62089. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  62090. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  62091. + struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
  62092. + struct pxp_layer_param *out_params = &pxp_conf->out_param;
  62093. +
  62094. + bool input_is_YUV = is_yuv(s0_params->pixel_fmt);
  62095. + bool output_is_YUV = is_yuv(out_params->pixel_fmt);
  62096. +
  62097. + if (input_is_YUV && output_is_YUV) {
  62098. + /*
  62099. + * Input = YUV, Output = YUV
  62100. + * No CSC unless we need to do combining
  62101. + */
  62102. + if (ol_params->combine_enable) {
  62103. + /* Must convert to RGB for combining with RGB overlay */
  62104. +
  62105. + /* CSC1 - YUV->RGB */
  62106. + __raw_writel(0x04030000, pxp->base + HW_PXP_CSC1_COEF0);
  62107. + __raw_writel(0x01230208, pxp->base + HW_PXP_CSC1_COEF1);
  62108. + __raw_writel(0x076b079c, pxp->base + HW_PXP_CSC1_COEF2);
  62109. +
  62110. + /* CSC2 - RGB->YUV */
  62111. + __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  62112. + __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  62113. + __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  62114. + __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  62115. + __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  62116. + __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  62117. + __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  62118. + } else {
  62119. + /* Input & Output both YUV, so bypass both CSCs */
  62120. +
  62121. + /* CSC1 - Bypass */
  62122. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  62123. +
  62124. + /* CSC2 - Bypass */
  62125. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  62126. + }
  62127. + } else if (input_is_YUV && !output_is_YUV) {
  62128. + /*
  62129. + * Input = YUV, Output = RGB
  62130. + * Use CSC1 to convert to RGB
  62131. + */
  62132. +
  62133. + /* CSC1 - YUV->RGB */
  62134. + __raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
  62135. + __raw_writel(0x01980204, pxp->base + HW_PXP_CSC1_COEF1);
  62136. + __raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
  62137. +
  62138. + /* CSC2 - Bypass */
  62139. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  62140. + } else if (!input_is_YUV && output_is_YUV) {
  62141. + /*
  62142. + * Input = RGB, Output = YUV
  62143. + * Use CSC2 to convert to YUV
  62144. + */
  62145. +
  62146. + /* CSC1 - Bypass */
  62147. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  62148. +
  62149. + /* CSC2 - RGB->YUV */
  62150. + __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
  62151. + __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
  62152. + __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
  62153. + __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
  62154. + __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
  62155. + __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
  62156. + __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
  62157. + } else {
  62158. + /*
  62159. + * Input = RGB, Output = RGB
  62160. + * Input & Output both RGB, so bypass both CSCs
  62161. + */
  62162. +
  62163. + /* CSC1 - Bypass */
  62164. + __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
  62165. +
  62166. + /* CSC2 - Bypass */
  62167. + __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
  62168. + }
  62169. +
  62170. + /* YCrCb colorspace */
  62171. + /* Not sure when we use this...no YCrCb formats are defined for PxP */
  62172. + /*
  62173. + __raw_writel(0x84ab01f0, HW_PXP_CSCCOEFF0_ADDR);
  62174. + __raw_writel(0x01230204, HW_PXP_CSCCOEFF1_ADDR);
  62175. + __raw_writel(0x0730079c, HW_PXP_CSCCOEFF2_ADDR);
  62176. + */
  62177. +
  62178. +}
  62179. +
  62180. +static void pxp_set_s0buf(struct pxps *pxp)
  62181. +{
  62182. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  62183. + struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
  62184. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  62185. + dma_addr_t Y, U, V;
  62186. + dma_addr_t Y1, U1, V1;
  62187. + u32 offset, bpp = 1;
  62188. + u32 pitch = s0_params->stride ? s0_params->stride :
  62189. + s0_params->width;
  62190. +
  62191. + Y = s0_params->paddr;
  62192. +
  62193. + if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
  62194. + bpp = 2;
  62195. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
  62196. + bpp = 4;
  62197. + offset = (proc_data->srect.top * s0_params->width +
  62198. + proc_data->srect.left) * bpp;
  62199. + /* clipping or cropping */
  62200. + Y1 = Y + offset;
  62201. + __raw_writel(Y1, pxp->base + HW_PXP_PS_BUF);
  62202. + if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) ||
  62203. + (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) ||
  62204. + (s0_params->pixel_fmt == PXP_PIX_FMT_GREY) ||
  62205. + (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)) {
  62206. + /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */
  62207. + int s = 2;
  62208. + if (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)
  62209. + s = 1;
  62210. +
  62211. + offset = proc_data->srect.top * s0_params->width / 4 +
  62212. + proc_data->srect.left / 2;
  62213. + U = Y + (s0_params->width * s0_params->height);
  62214. + U1 = U + offset;
  62215. + V = U + ((s0_params->width * s0_params->height) >> s);
  62216. + V1 = V + offset;
  62217. + if (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) {
  62218. + __raw_writel(V1, pxp->base + HW_PXP_PS_UBUF);
  62219. + __raw_writel(U1, pxp->base + HW_PXP_PS_VBUF);
  62220. + } else {
  62221. + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  62222. + __raw_writel(V1, pxp->base + HW_PXP_PS_VBUF);
  62223. + }
  62224. + } else if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
  62225. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
  62226. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  62227. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
  62228. + int s = 2;
  62229. + if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
  62230. + (s0_params->pixel_fmt == PXP_PIX_FMT_NV61))
  62231. + s = 1;
  62232. +
  62233. + offset = (proc_data->srect.top * s0_params->width +
  62234. + proc_data->srect.left) / s;
  62235. + U = Y + (s0_params->width * s0_params->height);
  62236. + U1 = U + offset;
  62237. +
  62238. + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
  62239. + }
  62240. +
  62241. + /* TODO: only support RGB565, Y8, Y4, YUV420 */
  62242. + if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY ||
  62243. + s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P ||
  62244. + s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P ||
  62245. + s0_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
  62246. + s0_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
  62247. + s0_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
  62248. + s0_params->pixel_fmt == PXP_PIX_FMT_NV61 ||
  62249. + s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P) {
  62250. + __raw_writel(pitch, pxp->base + HW_PXP_PS_PITCH);
  62251. + }
  62252. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_GY04)
  62253. + __raw_writel(pitch >> 1,
  62254. + pxp->base + HW_PXP_PS_PITCH);
  62255. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
  62256. + __raw_writel(pitch << 2,
  62257. + pxp->base + HW_PXP_PS_PITCH);
  62258. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
  62259. + s0_params->pixel_fmt == PXP_PIX_FMT_YUYV ||
  62260. + s0_params->pixel_fmt == PXP_PIX_FMT_VYUY ||
  62261. + s0_params->pixel_fmt == PXP_PIX_FMT_YVYU)
  62262. + __raw_writel(pitch << 1,
  62263. + pxp->base + HW_PXP_PS_PITCH);
  62264. + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
  62265. + __raw_writel(pitch << 1,
  62266. + pxp->base + HW_PXP_PS_PITCH);
  62267. + else
  62268. + __raw_writel(0, pxp->base + HW_PXP_PS_PITCH);
  62269. +}
  62270. +
  62271. +/**
  62272. + * pxp_config() - configure PxP for a processing task
  62273. + * @pxps: PXP context.
  62274. + * @pxp_chan: PXP channel.
  62275. + * @return: 0 on success or negative error code on failure.
  62276. + */
  62277. +static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
  62278. +{
  62279. + struct pxp_config_data *pxp_conf_data = &pxp->pxp_conf_state;
  62280. + int ol_nr;
  62281. + int i;
  62282. +
  62283. + /* Configure PxP regs */
  62284. + pxp_set_ctrl(pxp);
  62285. + pxp_set_s0param(pxp);
  62286. + pxp_set_s0crop(pxp);
  62287. + pxp_set_scaling(pxp);
  62288. + ol_nr = pxp_conf_data->layer_nr - 2;
  62289. + while (ol_nr > 0) {
  62290. + i = pxp_conf_data->layer_nr - 2 - ol_nr;
  62291. + pxp_set_oln(i, pxp);
  62292. + pxp_set_olparam(i, pxp);
  62293. + /* only the color key in higher overlay will take effect. */
  62294. + pxp_set_olcolorkey(i, pxp);
  62295. + ol_nr--;
  62296. + }
  62297. + pxp_set_s0colorkey(pxp);
  62298. + pxp_set_csc(pxp);
  62299. + pxp_set_bg(pxp);
  62300. + pxp_set_lut(pxp);
  62301. +
  62302. + pxp_set_s0buf(pxp);
  62303. + pxp_set_outbuf(pxp);
  62304. +
  62305. + return 0;
  62306. +}
  62307. +
  62308. +static void pxp_clk_enable(struct pxps *pxp)
  62309. +{
  62310. + mutex_lock(&pxp->clk_mutex);
  62311. +
  62312. + if (pxp->clk_stat == CLK_STAT_ON) {
  62313. + mutex_unlock(&pxp->clk_mutex);
  62314. + return;
  62315. + }
  62316. +
  62317. + clk_prepare_enable(pxp->clk);
  62318. + pxp->clk_stat = CLK_STAT_ON;
  62319. +
  62320. + mutex_unlock(&pxp->clk_mutex);
  62321. +}
  62322. +
  62323. +static void pxp_clk_disable(struct pxps *pxp)
  62324. +{
  62325. + unsigned long flags;
  62326. +
  62327. + mutex_lock(&pxp->clk_mutex);
  62328. +
  62329. + if (pxp->clk_stat == CLK_STAT_OFF) {
  62330. + mutex_unlock(&pxp->clk_mutex);
  62331. + return;
  62332. + }
  62333. +
  62334. + spin_lock_irqsave(&pxp->lock, flags);
  62335. + if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
  62336. + spin_unlock_irqrestore(&pxp->lock, flags);
  62337. + clk_disable_unprepare(pxp->clk);
  62338. + pxp->clk_stat = CLK_STAT_OFF;
  62339. + } else
  62340. + spin_unlock_irqrestore(&pxp->lock, flags);
  62341. +
  62342. + mutex_unlock(&pxp->clk_mutex);
  62343. +}
  62344. +
  62345. +static inline void clkoff_callback(struct work_struct *w)
  62346. +{
  62347. + struct pxps *pxp = container_of(w, struct pxps, work);
  62348. +
  62349. + pxp_clk_disable(pxp);
  62350. +}
  62351. +
  62352. +static void pxp_clkoff_timer(unsigned long arg)
  62353. +{
  62354. + struct pxps *pxp = (struct pxps *)arg;
  62355. +
  62356. + if ((pxp->pxp_ongoing == 0) && list_empty(&head))
  62357. + schedule_work(&pxp->work);
  62358. + else
  62359. + mod_timer(&pxp->clk_timer,
  62360. + jiffies + msecs_to_jiffies(timeout_in_ms));
  62361. +}
  62362. +
  62363. +static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
  62364. +{
  62365. + return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
  62366. +}
  62367. +
  62368. +/* called with pxp_chan->lock held */
  62369. +static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
  62370. +{
  62371. + struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
  62372. + struct pxps *pxp = to_pxp(pxp_dma);
  62373. + struct pxp_tx_desc *desc;
  62374. + struct pxp_tx_desc *child;
  62375. + int i = 0;
  62376. +
  62377. + /* S0 */
  62378. + desc = list_first_entry(&head, struct pxp_tx_desc, list);
  62379. + memcpy(&pxp->pxp_conf_state.s0_param,
  62380. + &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
  62381. + memcpy(&pxp->pxp_conf_state.proc_data,
  62382. + &desc->proc_data, sizeof(struct pxp_proc_data));
  62383. +
  62384. + /* Save PxP configuration */
  62385. + list_for_each_entry(child, &desc->tx_list, list) {
  62386. + if (i == 0) { /* Output */
  62387. + memcpy(&pxp->pxp_conf_state.out_param,
  62388. + &child->layer_param.out_param,
  62389. + sizeof(struct pxp_layer_param));
  62390. + } else { /* Overlay */
  62391. + memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
  62392. + &child->layer_param.ol_param,
  62393. + sizeof(struct pxp_layer_param));
  62394. + }
  62395. +
  62396. + i++;
  62397. + }
  62398. + pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
  62399. + pxp->pxp_conf_state.s0_param.width,
  62400. + pxp->pxp_conf_state.s0_param.height,
  62401. + pxp->pxp_conf_state.s0_param.paddr);
  62402. + pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
  62403. + pxp->pxp_conf_state.out_param.width,
  62404. + pxp->pxp_conf_state.out_param.height,
  62405. + pxp->pxp_conf_state.out_param.paddr);
  62406. +}
  62407. +
  62408. +static void pxpdma_dostart_work(struct pxps *pxp)
  62409. +{
  62410. + struct pxp_channel *pxp_chan = NULL;
  62411. + unsigned long flags;
  62412. + struct pxp_tx_desc *desc = NULL;
  62413. +
  62414. + spin_lock_irqsave(&pxp->lock, flags);
  62415. +
  62416. + desc = list_entry(head.next, struct pxp_tx_desc, list);
  62417. + pxp_chan = to_pxp_channel(desc->txd.chan);
  62418. +
  62419. + __pxpdma_dostart(pxp_chan);
  62420. +
  62421. + /* Configure PxP */
  62422. + pxp_config(pxp, pxp_chan);
  62423. +
  62424. + pxp_start(pxp);
  62425. +
  62426. + spin_unlock_irqrestore(&pxp->lock, flags);
  62427. +}
  62428. +
  62429. +static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct pxps *pxp)
  62430. +{
  62431. + unsigned long flags;
  62432. + struct pxp_tx_desc *desc = NULL;
  62433. +
  62434. + do {
  62435. + desc = pxpdma_first_queued(pxp_chan);
  62436. + spin_lock_irqsave(&pxp->lock, flags);
  62437. + list_move_tail(&desc->list, &head);
  62438. + spin_unlock_irqrestore(&pxp->lock, flags);
  62439. + } while (!list_empty(&pxp_chan->queue));
  62440. +}
  62441. +
  62442. +static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
  62443. +{
  62444. + struct pxp_tx_desc *desc = to_tx_desc(tx);
  62445. + struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
  62446. + dma_cookie_t cookie;
  62447. +
  62448. + dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
  62449. +
  62450. + /* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
  62451. + spin_lock(&pxp_chan->lock);
  62452. +
  62453. + cookie = pxp_chan->dma_chan.cookie;
  62454. +
  62455. + if (++cookie < 0)
  62456. + cookie = 1;
  62457. +
  62458. + /* from dmaengine.h: "last cookie value returned to client" */
  62459. + pxp_chan->dma_chan.cookie = cookie;
  62460. + tx->cookie = cookie;
  62461. +
  62462. + /* Here we add the tx descriptor to our PxP task queue. */
  62463. + list_add_tail(&desc->list, &pxp_chan->queue);
  62464. +
  62465. + spin_unlock(&pxp_chan->lock);
  62466. +
  62467. + dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
  62468. +
  62469. + return cookie;
  62470. +}
  62471. +
  62472. +/**
  62473. + * pxp_init_channel() - initialize a PXP channel.
  62474. + * @pxp_dma: PXP DMA context.
  62475. + * @pchan: pointer to the channel object.
  62476. + * @return 0 on success or negative error code on failure.
  62477. + */
  62478. +static int pxp_init_channel(struct pxp_dma *pxp_dma,
  62479. + struct pxp_channel *pxp_chan)
  62480. +{
  62481. + int ret = 0;
  62482. +
  62483. + /*
  62484. + * We are using _virtual_ channel here.
  62485. + * Each channel contains all parameters of corresponding layers
  62486. + * for one transaction; each layer is represented as one descriptor
  62487. + * (i.e., pxp_tx_desc) here.
  62488. + */
  62489. +
  62490. + INIT_LIST_HEAD(&pxp_chan->queue);
  62491. +
  62492. + return ret;
  62493. +}
  62494. +
  62495. +static irqreturn_t pxp_irq(int irq, void *dev_id)
  62496. +{
  62497. + struct pxps *pxp = dev_id;
  62498. + struct pxp_channel *pxp_chan;
  62499. + struct pxp_tx_desc *desc;
  62500. + struct pxp_tx_desc *child, *_child;
  62501. + dma_async_tx_callback callback;
  62502. + void *callback_param;
  62503. + unsigned long flags;
  62504. + u32 hist_status;
  62505. +
  62506. + dump_pxp_reg(pxp);
  62507. +
  62508. + hist_status =
  62509. + __raw_readl(pxp->base + HW_PXP_HIST_CTRL) & BM_PXP_HIST_CTRL_STATUS;
  62510. +
  62511. + __raw_writel(BM_PXP_STAT_IRQ, pxp->base + HW_PXP_STAT_CLR);
  62512. +
  62513. + spin_lock_irqsave(&pxp->lock, flags);
  62514. +
  62515. + if (list_empty(&head)) {
  62516. + pxp->pxp_ongoing = 0;
  62517. + spin_unlock_irqrestore(&pxp->lock, flags);
  62518. + return IRQ_NONE;
  62519. + }
  62520. +
  62521. + /* Get descriptor and call callback */
  62522. + desc = list_entry(head.next, struct pxp_tx_desc, list);
  62523. + pxp_chan = to_pxp_channel(desc->txd.chan);
  62524. +
  62525. + pxp_chan->completed = desc->txd.cookie;
  62526. +
  62527. + callback = desc->txd.callback;
  62528. + callback_param = desc->txd.callback_param;
  62529. +
  62530. + /* Send histogram status back to caller */
  62531. + desc->hist_status = hist_status;
  62532. +
  62533. + if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
  62534. + callback(callback_param);
  62535. +
  62536. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  62537. +
  62538. + list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
  62539. + list_del_init(&child->list);
  62540. + kmem_cache_free(tx_desc_cache, (void *)child);
  62541. + }
  62542. + list_del_init(&desc->list);
  62543. + kmem_cache_free(tx_desc_cache, (void *)desc);
  62544. +
  62545. + complete(&pxp->complete);
  62546. + pxp->pxp_ongoing = 0;
  62547. + mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
  62548. +
  62549. + spin_unlock_irqrestore(&pxp->lock, flags);
  62550. +
  62551. + return IRQ_HANDLED;
  62552. +}
  62553. +
  62554. +/* allocate/free dma tx descriptor dynamically*/
  62555. +static struct pxp_tx_desc *pxpdma_desc_alloc(struct pxp_channel *pxp_chan)
  62556. +{
  62557. + struct pxp_tx_desc *desc = NULL;
  62558. + struct dma_async_tx_descriptor *txd = NULL;
  62559. +
  62560. + desc = kmem_cache_alloc(tx_desc_cache, GFP_KERNEL | __GFP_ZERO);
  62561. + if (desc == NULL)
  62562. + return NULL;
  62563. +
  62564. + INIT_LIST_HEAD(&desc->list);
  62565. + INIT_LIST_HEAD(&desc->tx_list);
  62566. + txd = &desc->txd;
  62567. + dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
  62568. + txd->tx_submit = pxp_tx_submit;
  62569. +
  62570. + return desc;
  62571. +}
  62572. +
  62573. +/* Allocate and initialise a transfer descriptor. */
  62574. +static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
  62575. + struct scatterlist
  62576. + *sgl,
  62577. + unsigned int sg_len,
  62578. + enum
  62579. + dma_transfer_direction
  62580. + direction,
  62581. + unsigned long tx_flags,
  62582. + void *context)
  62583. +{
  62584. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  62585. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  62586. + struct pxps *pxp = to_pxp(pxp_dma);
  62587. + struct pxp_tx_desc *desc = NULL;
  62588. + struct pxp_tx_desc *first = NULL, *prev = NULL;
  62589. + struct scatterlist *sg;
  62590. + dma_addr_t phys_addr;
  62591. + int i;
  62592. +
  62593. + if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
  62594. + dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
  62595. + direction);
  62596. + return NULL;
  62597. + }
  62598. +
  62599. + if (unlikely(sg_len < 2))
  62600. + return NULL;
  62601. +
  62602. + for_each_sg(sgl, sg, sg_len, i) {
  62603. + desc = pxpdma_desc_alloc(pxp_chan);
  62604. + if (!desc) {
  62605. + dev_err(chan->device->dev, "no enough memory to allocate tx descriptor\n");
  62606. + return NULL;
  62607. + }
  62608. +
  62609. + phys_addr = sg_dma_address(sg);
  62610. +
  62611. + if (!first) {
  62612. + first = desc;
  62613. +
  62614. + desc->layer_param.s0_param.paddr = phys_addr;
  62615. + } else {
  62616. + list_add_tail(&desc->list, &first->tx_list);
  62617. + prev->next = desc;
  62618. + desc->next = NULL;
  62619. +
  62620. + if (i == 1)
  62621. + desc->layer_param.out_param.paddr = phys_addr;
  62622. + else
  62623. + desc->layer_param.ol_param.paddr = phys_addr;
  62624. + }
  62625. +
  62626. + prev = desc;
  62627. + }
  62628. +
  62629. + pxp->pxp_conf_state.layer_nr = sg_len;
  62630. + first->txd.flags = tx_flags;
  62631. + first->len = sg_len;
  62632. + pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
  62633. + __func__, __LINE__, first, first->len, first->txd.flags);
  62634. +
  62635. + return &first->txd;
  62636. +}
  62637. +
  62638. +static void pxp_issue_pending(struct dma_chan *chan)
  62639. +{
  62640. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  62641. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  62642. + struct pxps *pxp = to_pxp(pxp_dma);
  62643. +
  62644. + spin_lock(&pxp_chan->lock);
  62645. +
  62646. + if (list_empty(&pxp_chan->queue)) {
  62647. + spin_unlock(&pxp_chan->lock);
  62648. + return;
  62649. + }
  62650. +
  62651. + pxpdma_dequeue(pxp_chan, pxp);
  62652. + pxp_chan->status = PXP_CHANNEL_READY;
  62653. +
  62654. + spin_unlock(&pxp_chan->lock);
  62655. +
  62656. + pxp_clk_enable(pxp);
  62657. + wake_up_interruptible(&pxp->thread_waitq);
  62658. +}
  62659. +
  62660. +static void __pxp_terminate_all(struct dma_chan *chan)
  62661. +{
  62662. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  62663. +
  62664. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  62665. +}
  62666. +
  62667. +static int pxp_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
  62668. + unsigned long arg)
  62669. +{
  62670. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  62671. +
  62672. + /* Only supports DMA_TERMINATE_ALL */
  62673. + if (cmd != DMA_TERMINATE_ALL)
  62674. + return -ENXIO;
  62675. +
  62676. + spin_lock(&pxp_chan->lock);
  62677. + __pxp_terminate_all(chan);
  62678. + spin_unlock(&pxp_chan->lock);
  62679. +
  62680. + return 0;
  62681. +}
  62682. +
  62683. +static int pxp_alloc_chan_resources(struct dma_chan *chan)
  62684. +{
  62685. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  62686. + struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
  62687. + int ret;
  62688. +
  62689. + /* dmaengine.c now guarantees to only offer free channels */
  62690. + BUG_ON(chan->client_count > 1);
  62691. + WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
  62692. +
  62693. + chan->cookie = 1;
  62694. + pxp_chan->completed = -ENXIO;
  62695. +
  62696. + pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
  62697. + ret = pxp_init_channel(pxp_dma, pxp_chan);
  62698. + if (ret < 0)
  62699. + goto err_chan;
  62700. +
  62701. + pxp_chan->status = PXP_CHANNEL_INITIALIZED;
  62702. +
  62703. + dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
  62704. + chan->chan_id, pxp_chan->eof_irq);
  62705. +
  62706. + return ret;
  62707. +
  62708. +err_chan:
  62709. + return ret;
  62710. +}
  62711. +
  62712. +static void pxp_free_chan_resources(struct dma_chan *chan)
  62713. +{
  62714. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  62715. +
  62716. + spin_lock(&pxp_chan->lock);
  62717. +
  62718. + __pxp_terminate_all(chan);
  62719. +
  62720. + pxp_chan->status = PXP_CHANNEL_FREE;
  62721. +
  62722. + spin_unlock(&pxp_chan->lock);
  62723. +}
  62724. +
  62725. +static enum dma_status pxp_tx_status(struct dma_chan *chan,
  62726. + dma_cookie_t cookie,
  62727. + struct dma_tx_state *txstate)
  62728. +{
  62729. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  62730. +
  62731. + if (cookie != chan->cookie)
  62732. + return DMA_ERROR;
  62733. +
  62734. + if (txstate) {
  62735. + txstate->last = pxp_chan->completed;
  62736. + txstate->used = chan->cookie;
  62737. + txstate->residue = 0;
  62738. + }
  62739. + return DMA_COMPLETE;
  62740. +}
  62741. +
  62742. +static int pxp_hw_init(struct pxps *pxp)
  62743. +{
  62744. + struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
  62745. + struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
  62746. + u32 reg_val;
  62747. +
  62748. + /* Pull PxP out of reset */
  62749. + __raw_writel(0, pxp->base + HW_PXP_CTRL);
  62750. +
  62751. + /* Config defaults */
  62752. +
  62753. + /* Initialize non-channel-specific PxP parameters */
  62754. + proc_data->drect.left = proc_data->srect.left = 0;
  62755. + proc_data->drect.top = proc_data->srect.top = 0;
  62756. + proc_data->drect.width = proc_data->srect.width = 0;
  62757. + proc_data->drect.height = proc_data->srect.height = 0;
  62758. + proc_data->scaling = 0;
  62759. + proc_data->hflip = 0;
  62760. + proc_data->vflip = 0;
  62761. + proc_data->rotate = 0;
  62762. + proc_data->bgcolor = 0;
  62763. +
  62764. + /* Initialize S0 channel parameters */
  62765. + pxp_conf->s0_param.pixel_fmt = pxp_s0_formats[0];
  62766. + pxp_conf->s0_param.width = 0;
  62767. + pxp_conf->s0_param.height = 0;
  62768. + pxp_conf->s0_param.color_key = -1;
  62769. + pxp_conf->s0_param.color_key_enable = false;
  62770. +
  62771. + /* Initialize OL channel parameters */
  62772. + pxp_conf->ol_param[0].combine_enable = false;
  62773. + pxp_conf->ol_param[0].width = 0;
  62774. + pxp_conf->ol_param[0].height = 0;
  62775. + pxp_conf->ol_param[0].pixel_fmt = PXP_PIX_FMT_RGB565;
  62776. + pxp_conf->ol_param[0].color_key_enable = false;
  62777. + pxp_conf->ol_param[0].color_key = -1;
  62778. + pxp_conf->ol_param[0].global_alpha_enable = false;
  62779. + pxp_conf->ol_param[0].global_alpha = 0;
  62780. + pxp_conf->ol_param[0].local_alpha_enable = false;
  62781. +
  62782. + /* Initialize Output channel parameters */
  62783. + pxp_conf->out_param.width = 0;
  62784. + pxp_conf->out_param.height = 0;
  62785. + pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
  62786. +
  62787. + proc_data->overlay_state = 0;
  62788. +
  62789. + /* Write default h/w config */
  62790. + pxp_set_ctrl(pxp);
  62791. + pxp_set_s0param(pxp);
  62792. + pxp_set_s0crop(pxp);
  62793. + /*
  62794. + * simply program the ULC to a higher value than the LRC
  62795. + * to avoid any AS pixels to show up in the output buffer.
  62796. + */
  62797. + __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_OUT_AS_ULC);
  62798. + pxp_set_olparam(0, pxp);
  62799. + pxp_set_olcolorkey(0, pxp);
  62800. +
  62801. + pxp_set_s0colorkey(pxp);
  62802. + pxp_set_csc(pxp);
  62803. + pxp_set_bg(pxp);
  62804. + pxp_set_lut(pxp);
  62805. +
  62806. + /* One-time histogram configuration */
  62807. + reg_val =
  62808. + BF_PXP_HIST_CTRL_PANEL_MODE(BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16);
  62809. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST_CTRL);
  62810. +
  62811. + reg_val = BF_PXP_HIST2_PARAM_VALUE0(0x00) |
  62812. + BF_PXP_HIST2_PARAM_VALUE1(0x00F);
  62813. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST2_PARAM);
  62814. +
  62815. + reg_val = BF_PXP_HIST4_PARAM_VALUE0(0x00) |
  62816. + BF_PXP_HIST4_PARAM_VALUE1(0x05) |
  62817. + BF_PXP_HIST4_PARAM_VALUE2(0x0A) | BF_PXP_HIST4_PARAM_VALUE3(0x0F);
  62818. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST4_PARAM);
  62819. +
  62820. + reg_val = BF_PXP_HIST8_PARAM0_VALUE0(0x00) |
  62821. + BF_PXP_HIST8_PARAM0_VALUE1(0x02) |
  62822. + BF_PXP_HIST8_PARAM0_VALUE2(0x04) | BF_PXP_HIST8_PARAM0_VALUE3(0x06);
  62823. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM0);
  62824. + reg_val = BF_PXP_HIST8_PARAM1_VALUE4(0x09) |
  62825. + BF_PXP_HIST8_PARAM1_VALUE5(0x0B) |
  62826. + BF_PXP_HIST8_PARAM1_VALUE6(0x0D) | BF_PXP_HIST8_PARAM1_VALUE7(0x0F);
  62827. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM1);
  62828. +
  62829. + reg_val = BF_PXP_HIST16_PARAM0_VALUE0(0x00) |
  62830. + BF_PXP_HIST16_PARAM0_VALUE1(0x01) |
  62831. + BF_PXP_HIST16_PARAM0_VALUE2(0x02) |
  62832. + BF_PXP_HIST16_PARAM0_VALUE3(0x03);
  62833. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM0);
  62834. + reg_val = BF_PXP_HIST16_PARAM1_VALUE4(0x04) |
  62835. + BF_PXP_HIST16_PARAM1_VALUE5(0x05) |
  62836. + BF_PXP_HIST16_PARAM1_VALUE6(0x06) |
  62837. + BF_PXP_HIST16_PARAM1_VALUE7(0x07);
  62838. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM1);
  62839. + reg_val = BF_PXP_HIST16_PARAM2_VALUE8(0x08) |
  62840. + BF_PXP_HIST16_PARAM2_VALUE9(0x09) |
  62841. + BF_PXP_HIST16_PARAM2_VALUE10(0x0A) |
  62842. + BF_PXP_HIST16_PARAM2_VALUE11(0x0B);
  62843. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM2);
  62844. + reg_val = BF_PXP_HIST16_PARAM3_VALUE12(0x0C) |
  62845. + BF_PXP_HIST16_PARAM3_VALUE13(0x0D) |
  62846. + BF_PXP_HIST16_PARAM3_VALUE14(0x0E) |
  62847. + BF_PXP_HIST16_PARAM3_VALUE15(0x0F);
  62848. + __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM3);
  62849. +
  62850. + return 0;
  62851. +}
  62852. +
  62853. +static int pxp_dma_init(struct pxps *pxp)
  62854. +{
  62855. + struct pxp_dma *pxp_dma = &pxp->pxp_dma;
  62856. + struct dma_device *dma = &pxp_dma->dma;
  62857. + int i;
  62858. +
  62859. + dma_cap_set(DMA_SLAVE, dma->cap_mask);
  62860. + dma_cap_set(DMA_PRIVATE, dma->cap_mask);
  62861. +
  62862. + /* Compulsory common fields */
  62863. + dma->dev = pxp->dev;
  62864. + dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
  62865. + dma->device_free_chan_resources = pxp_free_chan_resources;
  62866. + dma->device_tx_status = pxp_tx_status;
  62867. + dma->device_issue_pending = pxp_issue_pending;
  62868. +
  62869. + /* Compulsory for DMA_SLAVE fields */
  62870. + dma->device_prep_slave_sg = pxp_prep_slave_sg;
  62871. + dma->device_control = pxp_control;
  62872. +
  62873. + /* Initialize PxP Channels */
  62874. + INIT_LIST_HEAD(&dma->channels);
  62875. + for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
  62876. + struct pxp_channel *pxp_chan = pxp->channel + i;
  62877. + struct dma_chan *dma_chan = &pxp_chan->dma_chan;
  62878. +
  62879. + spin_lock_init(&pxp_chan->lock);
  62880. +
  62881. + /* Only one EOF IRQ for PxP, shared by all channels */
  62882. + pxp_chan->eof_irq = pxp->irq;
  62883. + pxp_chan->status = PXP_CHANNEL_FREE;
  62884. + pxp_chan->completed = -ENXIO;
  62885. + snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
  62886. + "PXP EOF %d", i);
  62887. +
  62888. + dma_chan->device = &pxp_dma->dma;
  62889. + dma_chan->cookie = 1;
  62890. + dma_chan->chan_id = i;
  62891. + list_add_tail(&dma_chan->device_node, &dma->channels);
  62892. + }
  62893. +
  62894. + return dma_async_device_register(&pxp_dma->dma);
  62895. +}
  62896. +
  62897. +static ssize_t clk_off_timeout_show(struct device *dev,
  62898. + struct device_attribute *attr, char *buf)
  62899. +{
  62900. + return sprintf(buf, "%d\n", timeout_in_ms);
  62901. +}
  62902. +
  62903. +static ssize_t clk_off_timeout_store(struct device *dev,
  62904. + struct device_attribute *attr,
  62905. + const char *buf, size_t count)
  62906. +{
  62907. + int val;
  62908. + if (sscanf(buf, "%d", &val) > 0) {
  62909. + timeout_in_ms = val;
  62910. + return count;
  62911. + }
  62912. + return -EINVAL;
  62913. +}
  62914. +
  62915. +static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
  62916. + clk_off_timeout_store);
  62917. +
  62918. +static ssize_t block_size_show(struct device *dev,
  62919. + struct device_attribute *attr,
  62920. + char *buf)
  62921. +{
  62922. + return sprintf(buf, "%d\n", block_size);
  62923. +}
  62924. +
  62925. +static ssize_t block_size_store(struct device *dev,
  62926. + struct device_attribute *attr,
  62927. + const char *buf, size_t count)
  62928. +{
  62929. + char **last = NULL;
  62930. +
  62931. + block_size = simple_strtoul(buf, last, 0);
  62932. + if (block_size > 1)
  62933. + block_size = 1;
  62934. +
  62935. + return count;
  62936. +}
  62937. +static DEVICE_ATTR(block_size, S_IWUSR | S_IRUGO,
  62938. + block_size_show, block_size_store);
  62939. +
  62940. +static const struct of_device_id imx_pxpdma_dt_ids[] = {
  62941. + { .compatible = "fsl,imx6dl-pxp-dma", },
  62942. + { /* sentinel */ }
  62943. +};
  62944. +MODULE_DEVICE_TABLE(of, imx_pxpdma_dt_ids);
  62945. +
  62946. +static int has_pending_task(struct pxps *pxp, struct pxp_channel *task)
  62947. +{
  62948. + int found;
  62949. + unsigned long flags;
  62950. +
  62951. + spin_lock_irqsave(&pxp->lock, flags);
  62952. + found = !list_empty(&head);
  62953. + spin_unlock_irqrestore(&pxp->lock, flags);
  62954. +
  62955. + return found;
  62956. +}
  62957. +
  62958. +static int pxp_dispatch_thread(void *argv)
  62959. +{
  62960. + struct pxps *pxp = (struct pxps *)argv;
  62961. + struct pxp_channel *pending = NULL;
  62962. + unsigned long flags;
  62963. +
  62964. + while (!kthread_should_stop()) {
  62965. + int ret;
  62966. + ret = wait_event_interruptible(pxp->thread_waitq,
  62967. + has_pending_task(pxp, pending));
  62968. + if (signal_pending(current))
  62969. + continue;
  62970. +
  62971. + if (kthread_should_stop())
  62972. + break;
  62973. +
  62974. + spin_lock_irqsave(&pxp->lock, flags);
  62975. + pxp->pxp_ongoing = 1;
  62976. + spin_unlock_irqrestore(&pxp->lock, flags);
  62977. + init_completion(&pxp->complete);
  62978. + pxpdma_dostart_work(pxp);
  62979. + ret = wait_for_completion_timeout(&pxp->complete, 2 * HZ);
  62980. + if (ret == 0) {
  62981. + printk(KERN_EMERG "%s: task is timeout\n\n", __func__);
  62982. + break;
  62983. + }
  62984. + }
  62985. +
  62986. + return 0;
  62987. +}
  62988. +
  62989. +static int pxp_probe(struct platform_device *pdev)
  62990. +{
  62991. + struct pxps *pxp;
  62992. + struct resource *res;
  62993. + int irq;
  62994. + int err = 0;
  62995. +
  62996. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  62997. + irq = platform_get_irq(pdev, 0);
  62998. + if (!res || irq < 0) {
  62999. + err = -ENODEV;
  63000. + goto exit;
  63001. + }
  63002. +
  63003. + pxp = devm_kzalloc(&pdev->dev, sizeof(*pxp), GFP_KERNEL);
  63004. + if (!pxp) {
  63005. + dev_err(&pdev->dev, "failed to allocate control object\n");
  63006. + err = -ENOMEM;
  63007. + goto exit;
  63008. + }
  63009. +
  63010. + pxp->dev = &pdev->dev;
  63011. +
  63012. + platform_set_drvdata(pdev, pxp);
  63013. + pxp->irq = irq;
  63014. +
  63015. + pxp->pxp_ongoing = 0;
  63016. + pxp->lut_state = 0;
  63017. +
  63018. + spin_lock_init(&pxp->lock);
  63019. + mutex_init(&pxp->clk_mutex);
  63020. +
  63021. + pxp->base = devm_request_and_ioremap(&pdev->dev, res);
  63022. + if (pxp->base == NULL) {
  63023. + dev_err(&pdev->dev, "Couldn't ioremap regs\n");
  63024. + err = -ENODEV;
  63025. + goto exit;
  63026. + }
  63027. +
  63028. + pxp->pdev = pdev;
  63029. +
  63030. + pxp->clk = devm_clk_get(&pdev->dev, "pxp-axi");
  63031. + clk_prepare_enable(pxp->clk);
  63032. +
  63033. + err = pxp_hw_init(pxp);
  63034. + clk_disable_unprepare(pxp->clk);
  63035. + if (err) {
  63036. + dev_err(&pdev->dev, "failed to initialize hardware\n");
  63037. + goto exit;
  63038. + }
  63039. +
  63040. + err = devm_request_irq(&pdev->dev, pxp->irq, pxp_irq, 0,
  63041. + "pxp-dmaengine", pxp);
  63042. + if (err)
  63043. + goto exit;
  63044. + /* Initialize DMA engine */
  63045. + err = pxp_dma_init(pxp);
  63046. + if (err < 0)
  63047. + goto exit;
  63048. +
  63049. + if (device_create_file(&pdev->dev, &dev_attr_clk_off_timeout)) {
  63050. + dev_err(&pdev->dev,
  63051. + "Unable to create file from clk_off_timeout\n");
  63052. + goto exit;
  63053. + }
  63054. +
  63055. + device_create_file(&pdev->dev, &dev_attr_block_size);
  63056. + dump_pxp_reg(pxp);
  63057. +
  63058. + INIT_WORK(&pxp->work, clkoff_callback);
  63059. + init_timer(&pxp->clk_timer);
  63060. + pxp->clk_timer.function = pxp_clkoff_timer;
  63061. + pxp->clk_timer.data = (unsigned long)pxp;
  63062. +
  63063. + /* allocate a kernel thread to dispatch pxp conf */
  63064. + pxp->dispatch = kthread_run(pxp_dispatch_thread, pxp, "pxp_dispatch");
  63065. + if (IS_ERR(pxp->dispatch)) {
  63066. + err = PTR_ERR(pxp->dispatch);
  63067. + goto exit;
  63068. + }
  63069. + init_waitqueue_head(&pxp->thread_waitq);
  63070. + tx_desc_cache = kmem_cache_create("tx_desc", sizeof(struct pxp_tx_desc),
  63071. + 0, SLAB_HWCACHE_ALIGN, NULL);
  63072. + if (!tx_desc_cache) {
  63073. + err = -ENOMEM;
  63074. + goto exit;
  63075. + }
  63076. +
  63077. + register_pxp_device();
  63078. +
  63079. +exit:
  63080. + if (err)
  63081. + dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe()\n");
  63082. + return err;
  63083. +}
  63084. +
  63085. +static int pxp_remove(struct platform_device *pdev)
  63086. +{
  63087. + struct pxps *pxp = platform_get_drvdata(pdev);
  63088. +
  63089. + unregister_pxp_device();
  63090. + kmem_cache_destroy(tx_desc_cache);
  63091. + kthread_stop(pxp->dispatch);
  63092. + cancel_work_sync(&pxp->work);
  63093. + del_timer_sync(&pxp->clk_timer);
  63094. + clk_disable_unprepare(pxp->clk);
  63095. + device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
  63096. + device_remove_file(&pdev->dev, &dev_attr_block_size);
  63097. + dma_async_device_unregister(&(pxp->pxp_dma.dma));
  63098. +
  63099. + return 0;
  63100. +}
  63101. +
  63102. +#ifdef CONFIG_PM
  63103. +static int pxp_suspend(struct platform_device *pdev, pm_message_t state)
  63104. +{
  63105. + struct pxps *pxp = platform_get_drvdata(pdev);
  63106. +
  63107. + pxp_clk_enable(pxp);
  63108. + while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
  63109. + ;
  63110. +
  63111. + __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
  63112. + pxp_clk_disable(pxp);
  63113. +
  63114. + return 0;
  63115. +}
  63116. +
  63117. +static int pxp_resume(struct platform_device *pdev)
  63118. +{
  63119. + struct pxps *pxp = platform_get_drvdata(pdev);
  63120. +
  63121. + pxp_clk_enable(pxp);
  63122. + /* Pull PxP out of reset */
  63123. + __raw_writel(0, pxp->base + HW_PXP_CTRL);
  63124. + pxp_clk_disable(pxp);
  63125. +
  63126. + return 0;
  63127. +}
  63128. +#else
  63129. +#define pxp_suspend NULL
  63130. +#define pxp_resume NULL
  63131. +#endif
  63132. +
  63133. +static struct platform_driver pxp_driver = {
  63134. + .driver = {
  63135. + .name = "imx-pxp",
  63136. + .of_match_table = of_match_ptr(imx_pxpdma_dt_ids),
  63137. + },
  63138. + .probe = pxp_probe,
  63139. + .remove = pxp_remove,
  63140. + .suspend = pxp_suspend,
  63141. + .resume = pxp_resume,
  63142. +};
  63143. +
  63144. +module_platform_driver(pxp_driver);
  63145. +
  63146. +
  63147. +MODULE_DESCRIPTION("i.MX PxP driver");
  63148. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  63149. +MODULE_LICENSE("GPL");
  63150. diff -Nur linux-3.14.17/drivers/dma/pxp/regs-pxp_v2.h linux-imx6-3.14/drivers/dma/pxp/regs-pxp_v2.h
  63151. --- linux-3.14.17/drivers/dma/pxp/regs-pxp_v2.h 1970-01-01 01:00:00.000000000 +0100
  63152. +++ linux-imx6-3.14/drivers/dma/pxp/regs-pxp_v2.h 2014-09-11 18:06:00.198030770 +0200
  63153. @@ -0,0 +1,1152 @@
  63154. +/*
  63155. + * Freescale PXP Register Definitions
  63156. + *
  63157. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  63158. + *
  63159. + * This program is free software; you can redistribute it and/or modify
  63160. + * it under the terms of the GNU General Public License as published by
  63161. + * the Free Software Foundation; either version 2 of the License, or
  63162. + * (at your option) any later version.
  63163. + *
  63164. + * This program is distributed in the hope that it will be useful,
  63165. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  63166. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  63167. + * GNU General Public License for more details.
  63168. + *
  63169. + * You should have received a copy of the GNU General Public License
  63170. + * along with this program; if not, write to the Free Software
  63171. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  63172. + *
  63173. + * This file is created by xml file. Don't Edit it.
  63174. + *
  63175. + * Xml Revision: 1.29
  63176. + * Template revision: 1.3
  63177. + */
  63178. +
  63179. +#ifndef __ARCH_ARM___PXP_H
  63180. +#define __ARCH_ARM___PXP_H
  63181. +
  63182. +#define HW_PXP_CTRL (0x00000000)
  63183. +#define HW_PXP_CTRL_SET (0x00000004)
  63184. +#define HW_PXP_CTRL_CLR (0x00000008)
  63185. +#define HW_PXP_CTRL_TOG (0x0000000c)
  63186. +
  63187. +#define BM_PXP_CTRL_SFTRST 0x80000000
  63188. +#define BM_PXP_CTRL_CLKGATE 0x40000000
  63189. +#define BM_PXP_CTRL_RSVD4 0x20000000
  63190. +#define BM_PXP_CTRL_EN_REPEAT 0x10000000
  63191. +#define BP_PXP_CTRL_RSVD3 26
  63192. +#define BM_PXP_CTRL_RSVD3 0x0C000000
  63193. +#define BF_PXP_CTRL_RSVD3(v) \
  63194. + (((v) << 26) & BM_PXP_CTRL_RSVD3)
  63195. +#define BP_PXP_CTRL_INTERLACED_INPUT 24
  63196. +#define BM_PXP_CTRL_INTERLACED_INPUT 0x03000000
  63197. +#define BF_PXP_CTRL_INTERLACED_INPUT(v) \
  63198. + (((v) << 24) & BM_PXP_CTRL_INTERLACED_INPUT)
  63199. +#define BV_PXP_CTRL_INTERLACED_INPUT__PROGRESSIVE 0x0
  63200. +#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD0 0x2
  63201. +#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD1 0x3
  63202. +#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000
  63203. +#define BV_PXP_CTRL_BLOCK_SIZE__8X8 0x0
  63204. +#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1
  63205. +#define BM_PXP_CTRL_ROT_POS 0x00400000
  63206. +#define BM_PXP_CTRL_IN_PLACE 0x00200000
  63207. +#define BP_PXP_CTRL_RSVD1 12
  63208. +#define BM_PXP_CTRL_RSVD1 0x001FF000
  63209. +#define BF_PXP_CTRL_RSVD1(v) \
  63210. + (((v) << 12) & BM_PXP_CTRL_RSVD1)
  63211. +#define BM_PXP_CTRL_VFLIP 0x00000800
  63212. +#define BM_PXP_CTRL_HFLIP 0x00000400
  63213. +#define BP_PXP_CTRL_ROTATE 8
  63214. +#define BM_PXP_CTRL_ROTATE 0x00000300
  63215. +#define BF_PXP_CTRL_ROTATE(v) \
  63216. + (((v) << 8) & BM_PXP_CTRL_ROTATE)
  63217. +#define BV_PXP_CTRL_ROTATE__ROT_0 0x0
  63218. +#define BV_PXP_CTRL_ROTATE__ROT_90 0x1
  63219. +#define BV_PXP_CTRL_ROTATE__ROT_180 0x2
  63220. +#define BV_PXP_CTRL_ROTATE__ROT_270 0x3
  63221. +#define BP_PXP_CTRL_RSVD0 5
  63222. +#define BM_PXP_CTRL_RSVD0 0x000000E0
  63223. +#define BF_PXP_CTRL_RSVD0(v) \
  63224. + (((v) << 5) & BM_PXP_CTRL_RSVD0)
  63225. +#define BM_PXP_CTRL_ENABLE_LCD_HANDSHAKE 0x00000010
  63226. +#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008
  63227. +#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004
  63228. +#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002
  63229. +#define BM_PXP_CTRL_ENABLE 0x00000001
  63230. +
  63231. +#define HW_PXP_STAT (0x00000010)
  63232. +#define HW_PXP_STAT_SET (0x00000014)
  63233. +#define HW_PXP_STAT_CLR (0x00000018)
  63234. +#define HW_PXP_STAT_TOG (0x0000001c)
  63235. +
  63236. +#define BP_PXP_STAT_BLOCKX 24
  63237. +#define BM_PXP_STAT_BLOCKX 0xFF000000
  63238. +#define BF_PXP_STAT_BLOCKX(v) \
  63239. + (((v) << 24) & BM_PXP_STAT_BLOCKX)
  63240. +#define BP_PXP_STAT_BLOCKY 16
  63241. +#define BM_PXP_STAT_BLOCKY 0x00FF0000
  63242. +#define BF_PXP_STAT_BLOCKY(v) \
  63243. + (((v) << 16) & BM_PXP_STAT_BLOCKY)
  63244. +#define BP_PXP_STAT_RSVD2 9
  63245. +#define BM_PXP_STAT_RSVD2 0x0000FE00
  63246. +#define BF_PXP_STAT_RSVD2(v) \
  63247. + (((v) << 9) & BM_PXP_STAT_RSVD2)
  63248. +#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100
  63249. +#define BP_PXP_STAT_AXI_ERROR_ID 4
  63250. +#define BM_PXP_STAT_AXI_ERROR_ID 0x000000F0
  63251. +#define BF_PXP_STAT_AXI_ERROR_ID(v) \
  63252. + (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID)
  63253. +#define BM_PXP_STAT_NEXT_IRQ 0x00000008
  63254. +#define BM_PXP_STAT_AXI_READ_ERROR 0x00000004
  63255. +#define BM_PXP_STAT_AXI_WRITE_ERROR 0x00000002
  63256. +#define BM_PXP_STAT_IRQ 0x00000001
  63257. +
  63258. +#define HW_PXP_OUT_CTRL (0x00000020)
  63259. +#define HW_PXP_OUT_CTRL_SET (0x00000024)
  63260. +#define HW_PXP_OUT_CTRL_CLR (0x00000028)
  63261. +#define HW_PXP_OUT_CTRL_TOG (0x0000002c)
  63262. +
  63263. +#define BP_PXP_OUT_CTRL_ALPHA 24
  63264. +#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000
  63265. +#define BF_PXP_OUT_CTRL_ALPHA(v) \
  63266. + (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA)
  63267. +#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000
  63268. +#define BP_PXP_OUT_CTRL_RSVD1 10
  63269. +#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00
  63270. +#define BF_PXP_OUT_CTRL_RSVD1(v) \
  63271. + (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1)
  63272. +#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT 8
  63273. +#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300
  63274. +#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v) \
  63275. + (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT)
  63276. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0
  63277. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0 0x1
  63278. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1 0x2
  63279. +#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED 0x3
  63280. +#define BP_PXP_OUT_CTRL_RSVD0 5
  63281. +#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0
  63282. +#define BF_PXP_OUT_CTRL_RSVD0(v) \
  63283. + (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0)
  63284. +#define BP_PXP_OUT_CTRL_FORMAT 0
  63285. +#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F
  63286. +#define BF_PXP_OUT_CTRL_FORMAT(v) \
  63287. + (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT)
  63288. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888 0x0
  63289. +#define BV_PXP_OUT_CTRL_FORMAT__RGB888 0x4
  63290. +#define BV_PXP_OUT_CTRL_FORMAT__RGB888P 0x5
  63291. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555 0x8
  63292. +#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444 0x9
  63293. +#define BV_PXP_OUT_CTRL_FORMAT__RGB555 0xC
  63294. +#define BV_PXP_OUT_CTRL_FORMAT__RGB444 0xD
  63295. +#define BV_PXP_OUT_CTRL_FORMAT__RGB565 0xE
  63296. +#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444 0x10
  63297. +#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12
  63298. +#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13
  63299. +#define BV_PXP_OUT_CTRL_FORMAT__Y8 0x14
  63300. +#define BV_PXP_OUT_CTRL_FORMAT__Y4 0x15
  63301. +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422 0x18
  63302. +#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420 0x19
  63303. +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422 0x1A
  63304. +#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420 0x1B
  63305. +
  63306. +#define HW_PXP_OUT_BUF (0x00000030)
  63307. +
  63308. +#define BP_PXP_OUT_BUF_ADDR 0
  63309. +#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF
  63310. +#define BF_PXP_OUT_BUF_ADDR(v) (v)
  63311. +
  63312. +#define HW_PXP_OUT_BUF2 (0x00000040)
  63313. +
  63314. +#define BP_PXP_OUT_BUF2_ADDR 0
  63315. +#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF
  63316. +#define BF_PXP_OUT_BUF2_ADDR(v) (v)
  63317. +
  63318. +#define HW_PXP_OUT_PITCH (0x00000050)
  63319. +
  63320. +#define BP_PXP_OUT_PITCH_RSVD 16
  63321. +#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000
  63322. +#define BF_PXP_OUT_PITCH_RSVD(v) \
  63323. + (((v) << 16) & BM_PXP_OUT_PITCH_RSVD)
  63324. +#define BP_PXP_OUT_PITCH_PITCH 0
  63325. +#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF
  63326. +#define BF_PXP_OUT_PITCH_PITCH(v) \
  63327. + (((v) << 0) & BM_PXP_OUT_PITCH_PITCH)
  63328. +
  63329. +#define HW_PXP_OUT_LRC (0x00000060)
  63330. +
  63331. +#define BP_PXP_OUT_LRC_RSVD1 30
  63332. +#define BM_PXP_OUT_LRC_RSVD1 0xC0000000
  63333. +#define BF_PXP_OUT_LRC_RSVD1(v) \
  63334. + (((v) << 30) & BM_PXP_OUT_LRC_RSVD1)
  63335. +#define BP_PXP_OUT_LRC_X 16
  63336. +#define BM_PXP_OUT_LRC_X 0x3FFF0000
  63337. +#define BF_PXP_OUT_LRC_X(v) \
  63338. + (((v) << 16) & BM_PXP_OUT_LRC_X)
  63339. +#define BP_PXP_OUT_LRC_RSVD0 14
  63340. +#define BM_PXP_OUT_LRC_RSVD0 0x0000C000
  63341. +#define BF_PXP_OUT_LRC_RSVD0(v) \
  63342. + (((v) << 14) & BM_PXP_OUT_LRC_RSVD0)
  63343. +#define BP_PXP_OUT_LRC_Y 0
  63344. +#define BM_PXP_OUT_LRC_Y 0x00003FFF
  63345. +#define BF_PXP_OUT_LRC_Y(v) \
  63346. + (((v) << 0) & BM_PXP_OUT_LRC_Y)
  63347. +
  63348. +#define HW_PXP_OUT_PS_ULC (0x00000070)
  63349. +
  63350. +#define BP_PXP_OUT_PS_ULC_RSVD1 30
  63351. +#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000
  63352. +#define BF_PXP_OUT_PS_ULC_RSVD1(v) \
  63353. + (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1)
  63354. +#define BP_PXP_OUT_PS_ULC_X 16
  63355. +#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000
  63356. +#define BF_PXP_OUT_PS_ULC_X(v) \
  63357. + (((v) << 16) & BM_PXP_OUT_PS_ULC_X)
  63358. +#define BP_PXP_OUT_PS_ULC_RSVD0 14
  63359. +#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000
  63360. +#define BF_PXP_OUT_PS_ULC_RSVD0(v) \
  63361. + (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0)
  63362. +#define BP_PXP_OUT_PS_ULC_Y 0
  63363. +#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF
  63364. +#define BF_PXP_OUT_PS_ULC_Y(v) \
  63365. + (((v) << 0) & BM_PXP_OUT_PS_ULC_Y)
  63366. +
  63367. +#define HW_PXP_OUT_PS_LRC (0x00000080)
  63368. +
  63369. +#define BP_PXP_OUT_PS_LRC_RSVD1 30
  63370. +#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000
  63371. +#define BF_PXP_OUT_PS_LRC_RSVD1(v) \
  63372. + (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1)
  63373. +#define BP_PXP_OUT_PS_LRC_X 16
  63374. +#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000
  63375. +#define BF_PXP_OUT_PS_LRC_X(v) \
  63376. + (((v) << 16) & BM_PXP_OUT_PS_LRC_X)
  63377. +#define BP_PXP_OUT_PS_LRC_RSVD0 14
  63378. +#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000
  63379. +#define BF_PXP_OUT_PS_LRC_RSVD0(v) \
  63380. + (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0)
  63381. +#define BP_PXP_OUT_PS_LRC_Y 0
  63382. +#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF
  63383. +#define BF_PXP_OUT_PS_LRC_Y(v) \
  63384. + (((v) << 0) & BM_PXP_OUT_PS_LRC_Y)
  63385. +
  63386. +#define HW_PXP_OUT_AS_ULC (0x00000090)
  63387. +
  63388. +#define BP_PXP_OUT_AS_ULC_RSVD1 30
  63389. +#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000
  63390. +#define BF_PXP_OUT_AS_ULC_RSVD1(v) \
  63391. + (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1)
  63392. +#define BP_PXP_OUT_AS_ULC_X 16
  63393. +#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000
  63394. +#define BF_PXP_OUT_AS_ULC_X(v) \
  63395. + (((v) << 16) & BM_PXP_OUT_AS_ULC_X)
  63396. +#define BP_PXP_OUT_AS_ULC_RSVD0 14
  63397. +#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000
  63398. +#define BF_PXP_OUT_AS_ULC_RSVD0(v) \
  63399. + (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0)
  63400. +#define BP_PXP_OUT_AS_ULC_Y 0
  63401. +#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF
  63402. +#define BF_PXP_OUT_AS_ULC_Y(v) \
  63403. + (((v) << 0) & BM_PXP_OUT_AS_ULC_Y)
  63404. +
  63405. +#define HW_PXP_OUT_AS_LRC (0x000000a0)
  63406. +
  63407. +#define BP_PXP_OUT_AS_LRC_RSVD1 30
  63408. +#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000
  63409. +#define BF_PXP_OUT_AS_LRC_RSVD1(v) \
  63410. + (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1)
  63411. +#define BP_PXP_OUT_AS_LRC_X 16
  63412. +#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000
  63413. +#define BF_PXP_OUT_AS_LRC_X(v) \
  63414. + (((v) << 16) & BM_PXP_OUT_AS_LRC_X)
  63415. +#define BP_PXP_OUT_AS_LRC_RSVD0 14
  63416. +#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000
  63417. +#define BF_PXP_OUT_AS_LRC_RSVD0(v) \
  63418. + (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0)
  63419. +#define BP_PXP_OUT_AS_LRC_Y 0
  63420. +#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF
  63421. +#define BF_PXP_OUT_AS_LRC_Y(v) \
  63422. + (((v) << 0) & BM_PXP_OUT_AS_LRC_Y)
  63423. +
  63424. +#define HW_PXP_PS_CTRL (0x000000b0)
  63425. +#define HW_PXP_PS_CTRL_SET (0x000000b4)
  63426. +#define HW_PXP_PS_CTRL_CLR (0x000000b8)
  63427. +#define HW_PXP_PS_CTRL_TOG (0x000000bc)
  63428. +
  63429. +#define BP_PXP_PS_CTRL_RSVD1 12
  63430. +#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000
  63431. +#define BF_PXP_PS_CTRL_RSVD1(v) \
  63432. + (((v) << 12) & BM_PXP_PS_CTRL_RSVD1)
  63433. +#define BP_PXP_PS_CTRL_DECX 10
  63434. +#define BM_PXP_PS_CTRL_DECX 0x00000C00
  63435. +#define BF_PXP_PS_CTRL_DECX(v) \
  63436. + (((v) << 10) & BM_PXP_PS_CTRL_DECX)
  63437. +#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0
  63438. +#define BV_PXP_PS_CTRL_DECX__DECX2 0x1
  63439. +#define BV_PXP_PS_CTRL_DECX__DECX4 0x2
  63440. +#define BV_PXP_PS_CTRL_DECX__DECX8 0x3
  63441. +#define BP_PXP_PS_CTRL_DECY 8
  63442. +#define BM_PXP_PS_CTRL_DECY 0x00000300
  63443. +#define BF_PXP_PS_CTRL_DECY(v) \
  63444. + (((v) << 8) & BM_PXP_PS_CTRL_DECY)
  63445. +#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0
  63446. +#define BV_PXP_PS_CTRL_DECY__DECY2 0x1
  63447. +#define BV_PXP_PS_CTRL_DECY__DECY4 0x2
  63448. +#define BV_PXP_PS_CTRL_DECY__DECY8 0x3
  63449. +#define BP_PXP_PS_CTRL_SWAP 5
  63450. +#define BM_PXP_PS_CTRL_SWAP 0x000000E0
  63451. +#define BF_PXP_PS_CTRL_SWAP(v) \
  63452. + (((v) << 5) & BM_PXP_PS_CTRL_SWAP)
  63453. +#define BP_PXP_PS_CTRL_FORMAT 0
  63454. +#define BM_PXP_PS_CTRL_FORMAT 0x0000001F
  63455. +#define BF_PXP_PS_CTRL_FORMAT(v) \
  63456. + (((v) << 0) & BM_PXP_PS_CTRL_FORMAT)
  63457. +#define BV_PXP_PS_CTRL_FORMAT__RGB888 0x4
  63458. +#define BV_PXP_PS_CTRL_FORMAT__RGB555 0xC
  63459. +#define BV_PXP_PS_CTRL_FORMAT__RGB444 0xD
  63460. +#define BV_PXP_PS_CTRL_FORMAT__RGB565 0xE
  63461. +#define BV_PXP_PS_CTRL_FORMAT__YUV1P444 0x10
  63462. +#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12
  63463. +#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13
  63464. +#define BV_PXP_PS_CTRL_FORMAT__Y8 0x14
  63465. +#define BV_PXP_PS_CTRL_FORMAT__Y4 0x15
  63466. +#define BV_PXP_PS_CTRL_FORMAT__YUV2P422 0x18
  63467. +#define BV_PXP_PS_CTRL_FORMAT__YUV2P420 0x19
  63468. +#define BV_PXP_PS_CTRL_FORMAT__YVU2P422 0x1A
  63469. +#define BV_PXP_PS_CTRL_FORMAT__YVU2P420 0x1B
  63470. +#define BV_PXP_PS_CTRL_FORMAT__YUV422 0x1E
  63471. +#define BV_PXP_PS_CTRL_FORMAT__YUV420 0x1F
  63472. +
  63473. +#define HW_PXP_PS_BUF (0x000000c0)
  63474. +
  63475. +#define BP_PXP_PS_BUF_ADDR 0
  63476. +#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF
  63477. +#define BF_PXP_PS_BUF_ADDR(v) (v)
  63478. +
  63479. +#define HW_PXP_PS_UBUF (0x000000d0)
  63480. +
  63481. +#define BP_PXP_PS_UBUF_ADDR 0
  63482. +#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF
  63483. +#define BF_PXP_PS_UBUF_ADDR(v) (v)
  63484. +
  63485. +#define HW_PXP_PS_VBUF (0x000000e0)
  63486. +
  63487. +#define BP_PXP_PS_VBUF_ADDR 0
  63488. +#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF
  63489. +#define BF_PXP_PS_VBUF_ADDR(v) (v)
  63490. +
  63491. +#define HW_PXP_PS_PITCH (0x000000f0)
  63492. +
  63493. +#define BP_PXP_PS_PITCH_RSVD 16
  63494. +#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000
  63495. +#define BF_PXP_PS_PITCH_RSVD(v) \
  63496. + (((v) << 16) & BM_PXP_PS_PITCH_RSVD)
  63497. +#define BP_PXP_PS_PITCH_PITCH 0
  63498. +#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF
  63499. +#define BF_PXP_PS_PITCH_PITCH(v) \
  63500. + (((v) << 0) & BM_PXP_PS_PITCH_PITCH)
  63501. +
  63502. +#define HW_PXP_PS_BACKGROUND (0x00000100)
  63503. +
  63504. +#define BP_PXP_PS_BACKGROUND_RSVD 24
  63505. +#define BM_PXP_PS_BACKGROUND_RSVD 0xFF000000
  63506. +#define BF_PXP_PS_BACKGROUND_RSVD(v) \
  63507. + (((v) << 24) & BM_PXP_PS_BACKGROUND_RSVD)
  63508. +#define BP_PXP_PS_BACKGROUND_COLOR 0
  63509. +#define BM_PXP_PS_BACKGROUND_COLOR 0x00FFFFFF
  63510. +#define BF_PXP_PS_BACKGROUND_COLOR(v) \
  63511. + (((v) << 0) & BM_PXP_PS_BACKGROUND_COLOR)
  63512. +
  63513. +#define HW_PXP_PS_SCALE (0x00000110)
  63514. +
  63515. +#define BM_PXP_PS_SCALE_RSVD2 0x80000000
  63516. +#define BP_PXP_PS_SCALE_YSCALE 16
  63517. +#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000
  63518. +#define BF_PXP_PS_SCALE_YSCALE(v) \
  63519. + (((v) << 16) & BM_PXP_PS_SCALE_YSCALE)
  63520. +#define BM_PXP_PS_SCALE_RSVD1 0x00008000
  63521. +#define BP_PXP_PS_SCALE_XSCALE 0
  63522. +#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF
  63523. +#define BF_PXP_PS_SCALE_XSCALE(v) \
  63524. + (((v) << 0) & BM_PXP_PS_SCALE_XSCALE)
  63525. +
  63526. +#define HW_PXP_PS_OFFSET (0x00000120)
  63527. +
  63528. +#define BP_PXP_PS_OFFSET_RSVD2 28
  63529. +#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000
  63530. +#define BF_PXP_PS_OFFSET_RSVD2(v) \
  63531. + (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2)
  63532. +#define BP_PXP_PS_OFFSET_YOFFSET 16
  63533. +#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000
  63534. +#define BF_PXP_PS_OFFSET_YOFFSET(v) \
  63535. + (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET)
  63536. +#define BP_PXP_PS_OFFSET_RSVD1 12
  63537. +#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000
  63538. +#define BF_PXP_PS_OFFSET_RSVD1(v) \
  63539. + (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1)
  63540. +#define BP_PXP_PS_OFFSET_XOFFSET 0
  63541. +#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF
  63542. +#define BF_PXP_PS_OFFSET_XOFFSET(v) \
  63543. + (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET)
  63544. +
  63545. +#define HW_PXP_PS_CLRKEYLOW (0x00000130)
  63546. +
  63547. +#define BP_PXP_PS_CLRKEYLOW_RSVD1 24
  63548. +#define BM_PXP_PS_CLRKEYLOW_RSVD1 0xFF000000
  63549. +#define BF_PXP_PS_CLRKEYLOW_RSVD1(v) \
  63550. + (((v) << 24) & BM_PXP_PS_CLRKEYLOW_RSVD1)
  63551. +#define BP_PXP_PS_CLRKEYLOW_PIXEL 0
  63552. +#define BM_PXP_PS_CLRKEYLOW_PIXEL 0x00FFFFFF
  63553. +#define BF_PXP_PS_CLRKEYLOW_PIXEL(v) \
  63554. + (((v) << 0) & BM_PXP_PS_CLRKEYLOW_PIXEL)
  63555. +
  63556. +#define HW_PXP_PS_CLRKEYHIGH (0x00000140)
  63557. +
  63558. +#define BP_PXP_PS_CLRKEYHIGH_RSVD1 24
  63559. +#define BM_PXP_PS_CLRKEYHIGH_RSVD1 0xFF000000
  63560. +#define BF_PXP_PS_CLRKEYHIGH_RSVD1(v) \
  63561. + (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_RSVD1)
  63562. +#define BP_PXP_PS_CLRKEYHIGH_PIXEL 0
  63563. +#define BM_PXP_PS_CLRKEYHIGH_PIXEL 0x00FFFFFF
  63564. +#define BF_PXP_PS_CLRKEYHIGH_PIXEL(v) \
  63565. + (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_PIXEL)
  63566. +
  63567. +#define HW_PXP_AS_CTRL (0x00000150)
  63568. +
  63569. +#define BP_PXP_AS_CTRL_RSVD1 21
  63570. +#define BM_PXP_AS_CTRL_RSVD1 0xFFE00000
  63571. +#define BF_PXP_AS_CTRL_RSVD1(v) \
  63572. + (((v) << 21) & BM_PXP_AS_CTRL_RSVD1)
  63573. +#define BM_PXP_AS_CTRL_ALPHA_INVERT 0x00100000
  63574. +#define BP_PXP_AS_CTRL_ROP 16
  63575. +#define BM_PXP_AS_CTRL_ROP 0x000F0000
  63576. +#define BF_PXP_AS_CTRL_ROP(v) \
  63577. + (((v) << 16) & BM_PXP_AS_CTRL_ROP)
  63578. +#define BV_PXP_AS_CTRL_ROP__MASKAS 0x0
  63579. +#define BV_PXP_AS_CTRL_ROP__MASKNOTAS 0x1
  63580. +#define BV_PXP_AS_CTRL_ROP__MASKASNOT 0x2
  63581. +#define BV_PXP_AS_CTRL_ROP__MERGEAS 0x3
  63582. +#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4
  63583. +#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5
  63584. +#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS 0x6
  63585. +#define BV_PXP_AS_CTRL_ROP__NOT 0x7
  63586. +#define BV_PXP_AS_CTRL_ROP__NOTMASKAS 0x8
  63587. +#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9
  63588. +#define BV_PXP_AS_CTRL_ROP__XORAS 0xA
  63589. +#define BV_PXP_AS_CTRL_ROP__NOTXORAS 0xB
  63590. +#define BP_PXP_AS_CTRL_ALPHA 8
  63591. +#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00
  63592. +#define BF_PXP_AS_CTRL_ALPHA(v) \
  63593. + (((v) << 8) & BM_PXP_AS_CTRL_ALPHA)
  63594. +#define BP_PXP_AS_CTRL_FORMAT 4
  63595. +#define BM_PXP_AS_CTRL_FORMAT 0x000000F0
  63596. +#define BF_PXP_AS_CTRL_FORMAT(v) \
  63597. + (((v) << 4) & BM_PXP_AS_CTRL_FORMAT)
  63598. +#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0
  63599. +#define BV_PXP_AS_CTRL_FORMAT__RGB888 0x4
  63600. +#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8
  63601. +#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9
  63602. +#define BV_PXP_AS_CTRL_FORMAT__RGB555 0xC
  63603. +#define BV_PXP_AS_CTRL_FORMAT__RGB444 0xD
  63604. +#define BV_PXP_AS_CTRL_FORMAT__RGB565 0xE
  63605. +#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008
  63606. +#define BP_PXP_AS_CTRL_ALPHA_CTRL 1
  63607. +#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006
  63608. +#define BF_PXP_AS_CTRL_ALPHA_CTRL(v) \
  63609. + (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL)
  63610. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0
  63611. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1
  63612. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2
  63613. +#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs 0x3
  63614. +#define BM_PXP_AS_CTRL_RSVD0 0x00000001
  63615. +
  63616. +#define HW_PXP_AS_BUF (0x00000160)
  63617. +
  63618. +#define BP_PXP_AS_BUF_ADDR 0
  63619. +#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF
  63620. +#define BF_PXP_AS_BUF_ADDR(v) (v)
  63621. +
  63622. +#define HW_PXP_AS_PITCH (0x00000170)
  63623. +
  63624. +#define BP_PXP_AS_PITCH_RSVD 16
  63625. +#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000
  63626. +#define BF_PXP_AS_PITCH_RSVD(v) \
  63627. + (((v) << 16) & BM_PXP_AS_PITCH_RSVD)
  63628. +#define BP_PXP_AS_PITCH_PITCH 0
  63629. +#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF
  63630. +#define BF_PXP_AS_PITCH_PITCH(v) \
  63631. + (((v) << 0) & BM_PXP_AS_PITCH_PITCH)
  63632. +
  63633. +#define HW_PXP_AS_CLRKEYLOW (0x00000180)
  63634. +
  63635. +#define BP_PXP_AS_CLRKEYLOW_RSVD1 24
  63636. +#define BM_PXP_AS_CLRKEYLOW_RSVD1 0xFF000000
  63637. +#define BF_PXP_AS_CLRKEYLOW_RSVD1(v) \
  63638. + (((v) << 24) & BM_PXP_AS_CLRKEYLOW_RSVD1)
  63639. +#define BP_PXP_AS_CLRKEYLOW_PIXEL 0
  63640. +#define BM_PXP_AS_CLRKEYLOW_PIXEL 0x00FFFFFF
  63641. +#define BF_PXP_AS_CLRKEYLOW_PIXEL(v) \
  63642. + (((v) << 0) & BM_PXP_AS_CLRKEYLOW_PIXEL)
  63643. +
  63644. +#define HW_PXP_AS_CLRKEYHIGH (0x00000190)
  63645. +
  63646. +#define BP_PXP_AS_CLRKEYHIGH_RSVD1 24
  63647. +#define BM_PXP_AS_CLRKEYHIGH_RSVD1 0xFF000000
  63648. +#define BF_PXP_AS_CLRKEYHIGH_RSVD1(v) \
  63649. + (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_RSVD1)
  63650. +#define BP_PXP_AS_CLRKEYHIGH_PIXEL 0
  63651. +#define BM_PXP_AS_CLRKEYHIGH_PIXEL 0x00FFFFFF
  63652. +#define BF_PXP_AS_CLRKEYHIGH_PIXEL(v) \
  63653. + (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_PIXEL)
  63654. +
  63655. +#define HW_PXP_CSC1_COEF0 (0x000001a0)
  63656. +
  63657. +#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000
  63658. +#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000
  63659. +#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000
  63660. +#define BP_PXP_CSC1_COEF0_C0 18
  63661. +#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000
  63662. +#define BF_PXP_CSC1_COEF0_C0(v) \
  63663. + (((v) << 18) & BM_PXP_CSC1_COEF0_C0)
  63664. +#define BP_PXP_CSC1_COEF0_UV_OFFSET 9
  63665. +#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00
  63666. +#define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \
  63667. + (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET)
  63668. +#define BP_PXP_CSC1_COEF0_Y_OFFSET 0
  63669. +#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF
  63670. +#define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \
  63671. + (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET)
  63672. +
  63673. +#define HW_PXP_CSC1_COEF1 (0x000001b0)
  63674. +
  63675. +#define BP_PXP_CSC1_COEF1_RSVD1 27
  63676. +#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000
  63677. +#define BF_PXP_CSC1_COEF1_RSVD1(v) \
  63678. + (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1)
  63679. +#define BP_PXP_CSC1_COEF1_C1 16
  63680. +#define BM_PXP_CSC1_COEF1_C1 0x07FF0000
  63681. +#define BF_PXP_CSC1_COEF1_C1(v) \
  63682. + (((v) << 16) & BM_PXP_CSC1_COEF1_C1)
  63683. +#define BP_PXP_CSC1_COEF1_RSVD0 11
  63684. +#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800
  63685. +#define BF_PXP_CSC1_COEF1_RSVD0(v) \
  63686. + (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0)
  63687. +#define BP_PXP_CSC1_COEF1_C4 0
  63688. +#define BM_PXP_CSC1_COEF1_C4 0x000007FF
  63689. +#define BF_PXP_CSC1_COEF1_C4(v) \
  63690. + (((v) << 0) & BM_PXP_CSC1_COEF1_C4)
  63691. +
  63692. +#define HW_PXP_CSC1_COEF2 (0x000001c0)
  63693. +
  63694. +#define BP_PXP_CSC1_COEF2_RSVD1 27
  63695. +#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000
  63696. +#define BF_PXP_CSC1_COEF2_RSVD1(v) \
  63697. + (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1)
  63698. +#define BP_PXP_CSC1_COEF2_C2 16
  63699. +#define BM_PXP_CSC1_COEF2_C2 0x07FF0000
  63700. +#define BF_PXP_CSC1_COEF2_C2(v) \
  63701. + (((v) << 16) & BM_PXP_CSC1_COEF2_C2)
  63702. +#define BP_PXP_CSC1_COEF2_RSVD0 11
  63703. +#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800
  63704. +#define BF_PXP_CSC1_COEF2_RSVD0(v) \
  63705. + (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0)
  63706. +#define BP_PXP_CSC1_COEF2_C3 0
  63707. +#define BM_PXP_CSC1_COEF2_C3 0x000007FF
  63708. +#define BF_PXP_CSC1_COEF2_C3(v) \
  63709. + (((v) << 0) & BM_PXP_CSC1_COEF2_C3)
  63710. +
  63711. +#define HW_PXP_CSC2_CTRL (0x000001d0)
  63712. +
  63713. +#define BP_PXP_CSC2_CTRL_RSVD 3
  63714. +#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8
  63715. +#define BF_PXP_CSC2_CTRL_RSVD(v) \
  63716. + (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD)
  63717. +#define BP_PXP_CSC2_CTRL_CSC_MODE 1
  63718. +#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006
  63719. +#define BF_PXP_CSC2_CTRL_CSC_MODE(v) \
  63720. + (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE)
  63721. +#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB 0x0
  63722. +#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1
  63723. +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV 0x2
  63724. +#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3
  63725. +#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001
  63726. +
  63727. +#define HW_PXP_CSC2_COEF0 (0x000001e0)
  63728. +
  63729. +#define BP_PXP_CSC2_COEF0_RSVD1 27
  63730. +#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000
  63731. +#define BF_PXP_CSC2_COEF0_RSVD1(v) \
  63732. + (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1)
  63733. +#define BP_PXP_CSC2_COEF0_A2 16
  63734. +#define BM_PXP_CSC2_COEF0_A2 0x07FF0000
  63735. +#define BF_PXP_CSC2_COEF0_A2(v) \
  63736. + (((v) << 16) & BM_PXP_CSC2_COEF0_A2)
  63737. +#define BP_PXP_CSC2_COEF0_RSVD0 11
  63738. +#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800
  63739. +#define BF_PXP_CSC2_COEF0_RSVD0(v) \
  63740. + (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0)
  63741. +#define BP_PXP_CSC2_COEF0_A1 0
  63742. +#define BM_PXP_CSC2_COEF0_A1 0x000007FF
  63743. +#define BF_PXP_CSC2_COEF0_A1(v) \
  63744. + (((v) << 0) & BM_PXP_CSC2_COEF0_A1)
  63745. +
  63746. +#define HW_PXP_CSC2_COEF1 (0x000001f0)
  63747. +
  63748. +#define BP_PXP_CSC2_COEF1_RSVD1 27
  63749. +#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000
  63750. +#define BF_PXP_CSC2_COEF1_RSVD1(v) \
  63751. + (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1)
  63752. +#define BP_PXP_CSC2_COEF1_B1 16
  63753. +#define BM_PXP_CSC2_COEF1_B1 0x07FF0000
  63754. +#define BF_PXP_CSC2_COEF1_B1(v) \
  63755. + (((v) << 16) & BM_PXP_CSC2_COEF1_B1)
  63756. +#define BP_PXP_CSC2_COEF1_RSVD0 11
  63757. +#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800
  63758. +#define BF_PXP_CSC2_COEF1_RSVD0(v) \
  63759. + (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0)
  63760. +#define BP_PXP_CSC2_COEF1_A3 0
  63761. +#define BM_PXP_CSC2_COEF1_A3 0x000007FF
  63762. +#define BF_PXP_CSC2_COEF1_A3(v) \
  63763. + (((v) << 0) & BM_PXP_CSC2_COEF1_A3)
  63764. +
  63765. +#define HW_PXP_CSC2_COEF2 (0x00000200)
  63766. +
  63767. +#define BP_PXP_CSC2_COEF2_RSVD1 27
  63768. +#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000
  63769. +#define BF_PXP_CSC2_COEF2_RSVD1(v) \
  63770. + (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1)
  63771. +#define BP_PXP_CSC2_COEF2_B3 16
  63772. +#define BM_PXP_CSC2_COEF2_B3 0x07FF0000
  63773. +#define BF_PXP_CSC2_COEF2_B3(v) \
  63774. + (((v) << 16) & BM_PXP_CSC2_COEF2_B3)
  63775. +#define BP_PXP_CSC2_COEF2_RSVD0 11
  63776. +#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800
  63777. +#define BF_PXP_CSC2_COEF2_RSVD0(v) \
  63778. + (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0)
  63779. +#define BP_PXP_CSC2_COEF2_B2 0
  63780. +#define BM_PXP_CSC2_COEF2_B2 0x000007FF
  63781. +#define BF_PXP_CSC2_COEF2_B2(v) \
  63782. + (((v) << 0) & BM_PXP_CSC2_COEF2_B2)
  63783. +
  63784. +#define HW_PXP_CSC2_COEF3 (0x00000210)
  63785. +
  63786. +#define BP_PXP_CSC2_COEF3_RSVD1 27
  63787. +#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000
  63788. +#define BF_PXP_CSC2_COEF3_RSVD1(v) \
  63789. + (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1)
  63790. +#define BP_PXP_CSC2_COEF3_C2 16
  63791. +#define BM_PXP_CSC2_COEF3_C2 0x07FF0000
  63792. +#define BF_PXP_CSC2_COEF3_C2(v) \
  63793. + (((v) << 16) & BM_PXP_CSC2_COEF3_C2)
  63794. +#define BP_PXP_CSC2_COEF3_RSVD0 11
  63795. +#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800
  63796. +#define BF_PXP_CSC2_COEF3_RSVD0(v) \
  63797. + (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0)
  63798. +#define BP_PXP_CSC2_COEF3_C1 0
  63799. +#define BM_PXP_CSC2_COEF3_C1 0x000007FF
  63800. +#define BF_PXP_CSC2_COEF3_C1(v) \
  63801. + (((v) << 0) & BM_PXP_CSC2_COEF3_C1)
  63802. +
  63803. +#define HW_PXP_CSC2_COEF4 (0x00000220)
  63804. +
  63805. +#define BP_PXP_CSC2_COEF4_RSVD1 25
  63806. +#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000
  63807. +#define BF_PXP_CSC2_COEF4_RSVD1(v) \
  63808. + (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1)
  63809. +#define BP_PXP_CSC2_COEF4_D1 16
  63810. +#define BM_PXP_CSC2_COEF4_D1 0x01FF0000
  63811. +#define BF_PXP_CSC2_COEF4_D1(v) \
  63812. + (((v) << 16) & BM_PXP_CSC2_COEF4_D1)
  63813. +#define BP_PXP_CSC2_COEF4_RSVD0 11
  63814. +#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800
  63815. +#define BF_PXP_CSC2_COEF4_RSVD0(v) \
  63816. + (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0)
  63817. +#define BP_PXP_CSC2_COEF4_C3 0
  63818. +#define BM_PXP_CSC2_COEF4_C3 0x000007FF
  63819. +#define BF_PXP_CSC2_COEF4_C3(v) \
  63820. + (((v) << 0) & BM_PXP_CSC2_COEF4_C3)
  63821. +
  63822. +#define HW_PXP_CSC2_COEF5 (0x00000230)
  63823. +
  63824. +#define BP_PXP_CSC2_COEF5_RSVD1 25
  63825. +#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000
  63826. +#define BF_PXP_CSC2_COEF5_RSVD1(v) \
  63827. + (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1)
  63828. +#define BP_PXP_CSC2_COEF5_D3 16
  63829. +#define BM_PXP_CSC2_COEF5_D3 0x01FF0000
  63830. +#define BF_PXP_CSC2_COEF5_D3(v) \
  63831. + (((v) << 16) & BM_PXP_CSC2_COEF5_D3)
  63832. +#define BP_PXP_CSC2_COEF5_RSVD0 9
  63833. +#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00
  63834. +#define BF_PXP_CSC2_COEF5_RSVD0(v) \
  63835. + (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0)
  63836. +#define BP_PXP_CSC2_COEF5_D2 0
  63837. +#define BM_PXP_CSC2_COEF5_D2 0x000001FF
  63838. +#define BF_PXP_CSC2_COEF5_D2(v) \
  63839. + (((v) << 0) & BM_PXP_CSC2_COEF5_D2)
  63840. +
  63841. +#define HW_PXP_LUT_CTRL (0x00000240)
  63842. +
  63843. +#define BM_PXP_LUT_CTRL_BYPASS 0x80000000
  63844. +#define BP_PXP_LUT_CTRL_RSVD3 26
  63845. +#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000
  63846. +#define BF_PXP_LUT_CTRL_RSVD3(v) \
  63847. + (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3)
  63848. +#define BP_PXP_LUT_CTRL_LOOKUP_MODE 24
  63849. +#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000
  63850. +#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v) \
  63851. + (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE)
  63852. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565 0x0
  63853. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8 0x1
  63854. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2
  63855. +#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3
  63856. +#define BP_PXP_LUT_CTRL_RSVD2 18
  63857. +#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000
  63858. +#define BF_PXP_LUT_CTRL_RSVD2(v) \
  63859. + (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2)
  63860. +#define BP_PXP_LUT_CTRL_OUT_MODE 16
  63861. +#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000
  63862. +#define BF_PXP_LUT_CTRL_OUT_MODE(v) \
  63863. + (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE)
  63864. +#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED 0x0
  63865. +#define BV_PXP_LUT_CTRL_OUT_MODE__Y8 0x1
  63866. +#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2
  63867. +#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888 0x3
  63868. +#define BP_PXP_LUT_CTRL_RSVD1 11
  63869. +#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800
  63870. +#define BF_PXP_LUT_CTRL_RSVD1(v) \
  63871. + (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1)
  63872. +#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400
  63873. +#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200
  63874. +#define BM_PXP_LUT_CTRL_INVALID 0x00000100
  63875. +#define BP_PXP_LUT_CTRL_RSVD0 1
  63876. +#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE
  63877. +#define BF_PXP_LUT_CTRL_RSVD0(v) \
  63878. + (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0)
  63879. +#define BM_PXP_LUT_CTRL_DMA_START 0x00000001
  63880. +
  63881. +#define HW_PXP_LUT_ADDR (0x00000250)
  63882. +
  63883. +#define BM_PXP_LUT_ADDR_RSVD2 0x80000000
  63884. +#define BP_PXP_LUT_ADDR_NUM_BYTES 16
  63885. +#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000
  63886. +#define BF_PXP_LUT_ADDR_NUM_BYTES(v) \
  63887. + (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES)
  63888. +#define BP_PXP_LUT_ADDR_RSVD1 14
  63889. +#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000
  63890. +#define BF_PXP_LUT_ADDR_RSVD1(v) \
  63891. + (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1)
  63892. +#define BP_PXP_LUT_ADDR_ADDR 0
  63893. +#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF
  63894. +#define BF_PXP_LUT_ADDR_ADDR(v) \
  63895. + (((v) << 0) & BM_PXP_LUT_ADDR_ADDR)
  63896. +
  63897. +#define HW_PXP_LUT_DATA (0x00000260)
  63898. +
  63899. +#define BP_PXP_LUT_DATA_DATA 0
  63900. +#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF
  63901. +#define BF_PXP_LUT_DATA_DATA(v) (v)
  63902. +
  63903. +#define HW_PXP_LUT_EXTMEM (0x00000270)
  63904. +
  63905. +#define BP_PXP_LUT_EXTMEM_ADDR 0
  63906. +#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF
  63907. +#define BF_PXP_LUT_EXTMEM_ADDR(v) (v)
  63908. +
  63909. +#define HW_PXP_CFA (0x00000280)
  63910. +
  63911. +#define BP_PXP_CFA_DATA 0
  63912. +#define BM_PXP_CFA_DATA 0xFFFFFFFF
  63913. +#define BF_PXP_CFA_DATA(v) (v)
  63914. +
  63915. +#define HW_PXP_HIST_CTRL (0x00000290)
  63916. +
  63917. +#define BP_PXP_HIST_CTRL_RSVD 6
  63918. +#define BM_PXP_HIST_CTRL_RSVD 0xFFFFFFC0
  63919. +#define BF_PXP_HIST_CTRL_RSVD(v) \
  63920. + (((v) << 6) & BM_PXP_HIST_CTRL_RSVD)
  63921. +#define BP_PXP_HIST_CTRL_PANEL_MODE 4
  63922. +#define BM_PXP_HIST_CTRL_PANEL_MODE 0x00000030
  63923. +#define BF_PXP_HIST_CTRL_PANEL_MODE(v) \
  63924. + (((v) << 4) & BM_PXP_HIST_CTRL_PANEL_MODE)
  63925. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY4 0x0
  63926. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY8 0x1
  63927. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16 0x2
  63928. +#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY32 0x3
  63929. +#define BP_PXP_HIST_CTRL_STATUS 0
  63930. +#define BM_PXP_HIST_CTRL_STATUS 0x0000000F
  63931. +#define BF_PXP_HIST_CTRL_STATUS(v) \
  63932. + (((v) << 0) & BM_PXP_HIST_CTRL_STATUS)
  63933. +
  63934. +#define HW_PXP_HIST2_PARAM (0x000002a0)
  63935. +
  63936. +#define BP_PXP_HIST2_PARAM_RSVD 16
  63937. +#define BM_PXP_HIST2_PARAM_RSVD 0xFFFF0000
  63938. +#define BF_PXP_HIST2_PARAM_RSVD(v) \
  63939. + (((v) << 16) & BM_PXP_HIST2_PARAM_RSVD)
  63940. +#define BP_PXP_HIST2_PARAM_RSVD1 13
  63941. +#define BM_PXP_HIST2_PARAM_RSVD1 0x0000E000
  63942. +#define BF_PXP_HIST2_PARAM_RSVD1(v) \
  63943. + (((v) << 13) & BM_PXP_HIST2_PARAM_RSVD1)
  63944. +#define BP_PXP_HIST2_PARAM_VALUE1 8
  63945. +#define BM_PXP_HIST2_PARAM_VALUE1 0x00001F00
  63946. +#define BF_PXP_HIST2_PARAM_VALUE1(v) \
  63947. + (((v) << 8) & BM_PXP_HIST2_PARAM_VALUE1)
  63948. +#define BP_PXP_HIST2_PARAM_RSVD0 5
  63949. +#define BM_PXP_HIST2_PARAM_RSVD0 0x000000E0
  63950. +#define BF_PXP_HIST2_PARAM_RSVD0(v) \
  63951. + (((v) << 5) & BM_PXP_HIST2_PARAM_RSVD0)
  63952. +#define BP_PXP_HIST2_PARAM_VALUE0 0
  63953. +#define BM_PXP_HIST2_PARAM_VALUE0 0x0000001F
  63954. +#define BF_PXP_HIST2_PARAM_VALUE0(v) \
  63955. + (((v) << 0) & BM_PXP_HIST2_PARAM_VALUE0)
  63956. +
  63957. +#define HW_PXP_HIST4_PARAM (0x000002b0)
  63958. +
  63959. +#define BP_PXP_HIST4_PARAM_RSVD3 29
  63960. +#define BM_PXP_HIST4_PARAM_RSVD3 0xE0000000
  63961. +#define BF_PXP_HIST4_PARAM_RSVD3(v) \
  63962. + (((v) << 29) & BM_PXP_HIST4_PARAM_RSVD3)
  63963. +#define BP_PXP_HIST4_PARAM_VALUE3 24
  63964. +#define BM_PXP_HIST4_PARAM_VALUE3 0x1F000000
  63965. +#define BF_PXP_HIST4_PARAM_VALUE3(v) \
  63966. + (((v) << 24) & BM_PXP_HIST4_PARAM_VALUE3)
  63967. +#define BP_PXP_HIST4_PARAM_RSVD2 21
  63968. +#define BM_PXP_HIST4_PARAM_RSVD2 0x00E00000
  63969. +#define BF_PXP_HIST4_PARAM_RSVD2(v) \
  63970. + (((v) << 21) & BM_PXP_HIST4_PARAM_RSVD2)
  63971. +#define BP_PXP_HIST4_PARAM_VALUE2 16
  63972. +#define BM_PXP_HIST4_PARAM_VALUE2 0x001F0000
  63973. +#define BF_PXP_HIST4_PARAM_VALUE2(v) \
  63974. + (((v) << 16) & BM_PXP_HIST4_PARAM_VALUE2)
  63975. +#define BP_PXP_HIST4_PARAM_RSVD1 13
  63976. +#define BM_PXP_HIST4_PARAM_RSVD1 0x0000E000
  63977. +#define BF_PXP_HIST4_PARAM_RSVD1(v) \
  63978. + (((v) << 13) & BM_PXP_HIST4_PARAM_RSVD1)
  63979. +#define BP_PXP_HIST4_PARAM_VALUE1 8
  63980. +#define BM_PXP_HIST4_PARAM_VALUE1 0x00001F00
  63981. +#define BF_PXP_HIST4_PARAM_VALUE1(v) \
  63982. + (((v) << 8) & BM_PXP_HIST4_PARAM_VALUE1)
  63983. +#define BP_PXP_HIST4_PARAM_RSVD0 5
  63984. +#define BM_PXP_HIST4_PARAM_RSVD0 0x000000E0
  63985. +#define BF_PXP_HIST4_PARAM_RSVD0(v) \
  63986. + (((v) << 5) & BM_PXP_HIST4_PARAM_RSVD0)
  63987. +#define BP_PXP_HIST4_PARAM_VALUE0 0
  63988. +#define BM_PXP_HIST4_PARAM_VALUE0 0x0000001F
  63989. +#define BF_PXP_HIST4_PARAM_VALUE0(v) \
  63990. + (((v) << 0) & BM_PXP_HIST4_PARAM_VALUE0)
  63991. +
  63992. +#define HW_PXP_HIST8_PARAM0 (0x000002c0)
  63993. +
  63994. +#define BP_PXP_HIST8_PARAM0_RSVD3 29
  63995. +#define BM_PXP_HIST8_PARAM0_RSVD3 0xE0000000
  63996. +#define BF_PXP_HIST8_PARAM0_RSVD3(v) \
  63997. + (((v) << 29) & BM_PXP_HIST8_PARAM0_RSVD3)
  63998. +#define BP_PXP_HIST8_PARAM0_VALUE3 24
  63999. +#define BM_PXP_HIST8_PARAM0_VALUE3 0x1F000000
  64000. +#define BF_PXP_HIST8_PARAM0_VALUE3(v) \
  64001. + (((v) << 24) & BM_PXP_HIST8_PARAM0_VALUE3)
  64002. +#define BP_PXP_HIST8_PARAM0_RSVD2 21
  64003. +#define BM_PXP_HIST8_PARAM0_RSVD2 0x00E00000
  64004. +#define BF_PXP_HIST8_PARAM0_RSVD2(v) \
  64005. + (((v) << 21) & BM_PXP_HIST8_PARAM0_RSVD2)
  64006. +#define BP_PXP_HIST8_PARAM0_VALUE2 16
  64007. +#define BM_PXP_HIST8_PARAM0_VALUE2 0x001F0000
  64008. +#define BF_PXP_HIST8_PARAM0_VALUE2(v) \
  64009. + (((v) << 16) & BM_PXP_HIST8_PARAM0_VALUE2)
  64010. +#define BP_PXP_HIST8_PARAM0_RSVD1 13
  64011. +#define BM_PXP_HIST8_PARAM0_RSVD1 0x0000E000
  64012. +#define BF_PXP_HIST8_PARAM0_RSVD1(v) \
  64013. + (((v) << 13) & BM_PXP_HIST8_PARAM0_RSVD1)
  64014. +#define BP_PXP_HIST8_PARAM0_VALUE1 8
  64015. +#define BM_PXP_HIST8_PARAM0_VALUE1 0x00001F00
  64016. +#define BF_PXP_HIST8_PARAM0_VALUE1(v) \
  64017. + (((v) << 8) & BM_PXP_HIST8_PARAM0_VALUE1)
  64018. +#define BP_PXP_HIST8_PARAM0_RSVD0 5
  64019. +#define BM_PXP_HIST8_PARAM0_RSVD0 0x000000E0
  64020. +#define BF_PXP_HIST8_PARAM0_RSVD0(v) \
  64021. + (((v) << 5) & BM_PXP_HIST8_PARAM0_RSVD0)
  64022. +#define BP_PXP_HIST8_PARAM0_VALUE0 0
  64023. +#define BM_PXP_HIST8_PARAM0_VALUE0 0x0000001F
  64024. +#define BF_PXP_HIST8_PARAM0_VALUE0(v) \
  64025. + (((v) << 0) & BM_PXP_HIST8_PARAM0_VALUE0)
  64026. +
  64027. +#define HW_PXP_HIST8_PARAM1 (0x000002d0)
  64028. +
  64029. +#define BP_PXP_HIST8_PARAM1_RSVD7 29
  64030. +#define BM_PXP_HIST8_PARAM1_RSVD7 0xE0000000
  64031. +#define BF_PXP_HIST8_PARAM1_RSVD7(v) \
  64032. + (((v) << 29) & BM_PXP_HIST8_PARAM1_RSVD7)
  64033. +#define BP_PXP_HIST8_PARAM1_VALUE7 24
  64034. +#define BM_PXP_HIST8_PARAM1_VALUE7 0x1F000000
  64035. +#define BF_PXP_HIST8_PARAM1_VALUE7(v) \
  64036. + (((v) << 24) & BM_PXP_HIST8_PARAM1_VALUE7)
  64037. +#define BP_PXP_HIST8_PARAM1_RSVD6 21
  64038. +#define BM_PXP_HIST8_PARAM1_RSVD6 0x00E00000
  64039. +#define BF_PXP_HIST8_PARAM1_RSVD6(v) \
  64040. + (((v) << 21) & BM_PXP_HIST8_PARAM1_RSVD6)
  64041. +#define BP_PXP_HIST8_PARAM1_VALUE6 16
  64042. +#define BM_PXP_HIST8_PARAM1_VALUE6 0x001F0000
  64043. +#define BF_PXP_HIST8_PARAM1_VALUE6(v) \
  64044. + (((v) << 16) & BM_PXP_HIST8_PARAM1_VALUE6)
  64045. +#define BP_PXP_HIST8_PARAM1_RSVD5 13
  64046. +#define BM_PXP_HIST8_PARAM1_RSVD5 0x0000E000
  64047. +#define BF_PXP_HIST8_PARAM1_RSVD5(v) \
  64048. + (((v) << 13) & BM_PXP_HIST8_PARAM1_RSVD5)
  64049. +#define BP_PXP_HIST8_PARAM1_VALUE5 8
  64050. +#define BM_PXP_HIST8_PARAM1_VALUE5 0x00001F00
  64051. +#define BF_PXP_HIST8_PARAM1_VALUE5(v) \
  64052. + (((v) << 8) & BM_PXP_HIST8_PARAM1_VALUE5)
  64053. +#define BP_PXP_HIST8_PARAM1_RSVD4 5
  64054. +#define BM_PXP_HIST8_PARAM1_RSVD4 0x000000E0
  64055. +#define BF_PXP_HIST8_PARAM1_RSVD4(v) \
  64056. + (((v) << 5) & BM_PXP_HIST8_PARAM1_RSVD4)
  64057. +#define BP_PXP_HIST8_PARAM1_VALUE4 0
  64058. +#define BM_PXP_HIST8_PARAM1_VALUE4 0x0000001F
  64059. +#define BF_PXP_HIST8_PARAM1_VALUE4(v) \
  64060. + (((v) << 0) & BM_PXP_HIST8_PARAM1_VALUE4)
  64061. +
  64062. +#define HW_PXP_HIST16_PARAM0 (0x000002e0)
  64063. +
  64064. +#define BP_PXP_HIST16_PARAM0_RSVD3 29
  64065. +#define BM_PXP_HIST16_PARAM0_RSVD3 0xE0000000
  64066. +#define BF_PXP_HIST16_PARAM0_RSVD3(v) \
  64067. + (((v) << 29) & BM_PXP_HIST16_PARAM0_RSVD3)
  64068. +#define BP_PXP_HIST16_PARAM0_VALUE3 24
  64069. +#define BM_PXP_HIST16_PARAM0_VALUE3 0x1F000000
  64070. +#define BF_PXP_HIST16_PARAM0_VALUE3(v) \
  64071. + (((v) << 24) & BM_PXP_HIST16_PARAM0_VALUE3)
  64072. +#define BP_PXP_HIST16_PARAM0_RSVD2 21
  64073. +#define BM_PXP_HIST16_PARAM0_RSVD2 0x00E00000
  64074. +#define BF_PXP_HIST16_PARAM0_RSVD2(v) \
  64075. + (((v) << 21) & BM_PXP_HIST16_PARAM0_RSVD2)
  64076. +#define BP_PXP_HIST16_PARAM0_VALUE2 16
  64077. +#define BM_PXP_HIST16_PARAM0_VALUE2 0x001F0000
  64078. +#define BF_PXP_HIST16_PARAM0_VALUE2(v) \
  64079. + (((v) << 16) & BM_PXP_HIST16_PARAM0_VALUE2)
  64080. +#define BP_PXP_HIST16_PARAM0_RSVD1 13
  64081. +#define BM_PXP_HIST16_PARAM0_RSVD1 0x0000E000
  64082. +#define BF_PXP_HIST16_PARAM0_RSVD1(v) \
  64083. + (((v) << 13) & BM_PXP_HIST16_PARAM0_RSVD1)
  64084. +#define BP_PXP_HIST16_PARAM0_VALUE1 8
  64085. +#define BM_PXP_HIST16_PARAM0_VALUE1 0x00001F00
  64086. +#define BF_PXP_HIST16_PARAM0_VALUE1(v) \
  64087. + (((v) << 8) & BM_PXP_HIST16_PARAM0_VALUE1)
  64088. +#define BP_PXP_HIST16_PARAM0_RSVD0 5
  64089. +#define BM_PXP_HIST16_PARAM0_RSVD0 0x000000E0
  64090. +#define BF_PXP_HIST16_PARAM0_RSVD0(v) \
  64091. + (((v) << 5) & BM_PXP_HIST16_PARAM0_RSVD0)
  64092. +#define BP_PXP_HIST16_PARAM0_VALUE0 0
  64093. +#define BM_PXP_HIST16_PARAM0_VALUE0 0x0000001F
  64094. +#define BF_PXP_HIST16_PARAM0_VALUE0(v) \
  64095. + (((v) << 0) & BM_PXP_HIST16_PARAM0_VALUE0)
  64096. +
  64097. +#define HW_PXP_HIST16_PARAM1 (0x000002f0)
  64098. +
  64099. +#define BP_PXP_HIST16_PARAM1_RSVD7 29
  64100. +#define BM_PXP_HIST16_PARAM1_RSVD7 0xE0000000
  64101. +#define BF_PXP_HIST16_PARAM1_RSVD7(v) \
  64102. + (((v) << 29) & BM_PXP_HIST16_PARAM1_RSVD7)
  64103. +#define BP_PXP_HIST16_PARAM1_VALUE7 24
  64104. +#define BM_PXP_HIST16_PARAM1_VALUE7 0x1F000000
  64105. +#define BF_PXP_HIST16_PARAM1_VALUE7(v) \
  64106. + (((v) << 24) & BM_PXP_HIST16_PARAM1_VALUE7)
  64107. +#define BP_PXP_HIST16_PARAM1_RSVD6 21
  64108. +#define BM_PXP_HIST16_PARAM1_RSVD6 0x00E00000
  64109. +#define BF_PXP_HIST16_PARAM1_RSVD6(v) \
  64110. + (((v) << 21) & BM_PXP_HIST16_PARAM1_RSVD6)
  64111. +#define BP_PXP_HIST16_PARAM1_VALUE6 16
  64112. +#define BM_PXP_HIST16_PARAM1_VALUE6 0x001F0000
  64113. +#define BF_PXP_HIST16_PARAM1_VALUE6(v) \
  64114. + (((v) << 16) & BM_PXP_HIST16_PARAM1_VALUE6)
  64115. +#define BP_PXP_HIST16_PARAM1_RSVD5 13
  64116. +#define BM_PXP_HIST16_PARAM1_RSVD5 0x0000E000
  64117. +#define BF_PXP_HIST16_PARAM1_RSVD5(v) \
  64118. + (((v) << 13) & BM_PXP_HIST16_PARAM1_RSVD5)
  64119. +#define BP_PXP_HIST16_PARAM1_VALUE5 8
  64120. +#define BM_PXP_HIST16_PARAM1_VALUE5 0x00001F00
  64121. +#define BF_PXP_HIST16_PARAM1_VALUE5(v) \
  64122. + (((v) << 8) & BM_PXP_HIST16_PARAM1_VALUE5)
  64123. +#define BP_PXP_HIST16_PARAM1_RSVD4 5
  64124. +#define BM_PXP_HIST16_PARAM1_RSVD4 0x000000E0
  64125. +#define BF_PXP_HIST16_PARAM1_RSVD4(v) \
  64126. + (((v) << 5) & BM_PXP_HIST16_PARAM1_RSVD4)
  64127. +#define BP_PXP_HIST16_PARAM1_VALUE4 0
  64128. +#define BM_PXP_HIST16_PARAM1_VALUE4 0x0000001F
  64129. +#define BF_PXP_HIST16_PARAM1_VALUE4(v) \
  64130. + (((v) << 0) & BM_PXP_HIST16_PARAM1_VALUE4)
  64131. +
  64132. +#define HW_PXP_HIST16_PARAM2 (0x00000300)
  64133. +
  64134. +#define BP_PXP_HIST16_PARAM2_RSVD11 29
  64135. +#define BM_PXP_HIST16_PARAM2_RSVD11 0xE0000000
  64136. +#define BF_PXP_HIST16_PARAM2_RSVD11(v) \
  64137. + (((v) << 29) & BM_PXP_HIST16_PARAM2_RSVD11)
  64138. +#define BP_PXP_HIST16_PARAM2_VALUE11 24
  64139. +#define BM_PXP_HIST16_PARAM2_VALUE11 0x1F000000
  64140. +#define BF_PXP_HIST16_PARAM2_VALUE11(v) \
  64141. + (((v) << 24) & BM_PXP_HIST16_PARAM2_VALUE11)
  64142. +#define BP_PXP_HIST16_PARAM2_RSVD10 21
  64143. +#define BM_PXP_HIST16_PARAM2_RSVD10 0x00E00000
  64144. +#define BF_PXP_HIST16_PARAM2_RSVD10(v) \
  64145. + (((v) << 21) & BM_PXP_HIST16_PARAM2_RSVD10)
  64146. +#define BP_PXP_HIST16_PARAM2_VALUE10 16
  64147. +#define BM_PXP_HIST16_PARAM2_VALUE10 0x001F0000
  64148. +#define BF_PXP_HIST16_PARAM2_VALUE10(v) \
  64149. + (((v) << 16) & BM_PXP_HIST16_PARAM2_VALUE10)
  64150. +#define BP_PXP_HIST16_PARAM2_RSVD9 13
  64151. +#define BM_PXP_HIST16_PARAM2_RSVD9 0x0000E000
  64152. +#define BF_PXP_HIST16_PARAM2_RSVD9(v) \
  64153. + (((v) << 13) & BM_PXP_HIST16_PARAM2_RSVD9)
  64154. +#define BP_PXP_HIST16_PARAM2_VALUE9 8
  64155. +#define BM_PXP_HIST16_PARAM2_VALUE9 0x00001F00
  64156. +#define BF_PXP_HIST16_PARAM2_VALUE9(v) \
  64157. + (((v) << 8) & BM_PXP_HIST16_PARAM2_VALUE9)
  64158. +#define BP_PXP_HIST16_PARAM2_RSVD8 5
  64159. +#define BM_PXP_HIST16_PARAM2_RSVD8 0x000000E0
  64160. +#define BF_PXP_HIST16_PARAM2_RSVD8(v) \
  64161. + (((v) << 5) & BM_PXP_HIST16_PARAM2_RSVD8)
  64162. +#define BP_PXP_HIST16_PARAM2_VALUE8 0
  64163. +#define BM_PXP_HIST16_PARAM2_VALUE8 0x0000001F
  64164. +#define BF_PXP_HIST16_PARAM2_VALUE8(v) \
  64165. + (((v) << 0) & BM_PXP_HIST16_PARAM2_VALUE8)
  64166. +
  64167. +#define HW_PXP_HIST16_PARAM3 (0x00000310)
  64168. +
  64169. +#define BP_PXP_HIST16_PARAM3_RSVD15 29
  64170. +#define BM_PXP_HIST16_PARAM3_RSVD15 0xE0000000
  64171. +#define BF_PXP_HIST16_PARAM3_RSVD15(v) \
  64172. + (((v) << 29) & BM_PXP_HIST16_PARAM3_RSVD15)
  64173. +#define BP_PXP_HIST16_PARAM3_VALUE15 24
  64174. +#define BM_PXP_HIST16_PARAM3_VALUE15 0x1F000000
  64175. +#define BF_PXP_HIST16_PARAM3_VALUE15(v) \
  64176. + (((v) << 24) & BM_PXP_HIST16_PARAM3_VALUE15)
  64177. +#define BP_PXP_HIST16_PARAM3_RSVD14 21
  64178. +#define BM_PXP_HIST16_PARAM3_RSVD14 0x00E00000
  64179. +#define BF_PXP_HIST16_PARAM3_RSVD14(v) \
  64180. + (((v) << 21) & BM_PXP_HIST16_PARAM3_RSVD14)
  64181. +#define BP_PXP_HIST16_PARAM3_VALUE14 16
  64182. +#define BM_PXP_HIST16_PARAM3_VALUE14 0x001F0000
  64183. +#define BF_PXP_HIST16_PARAM3_VALUE14(v) \
  64184. + (((v) << 16) & BM_PXP_HIST16_PARAM3_VALUE14)
  64185. +#define BP_PXP_HIST16_PARAM3_RSVD13 13
  64186. +#define BM_PXP_HIST16_PARAM3_RSVD13 0x0000E000
  64187. +#define BF_PXP_HIST16_PARAM3_RSVD13(v) \
  64188. + (((v) << 13) & BM_PXP_HIST16_PARAM3_RSVD13)
  64189. +#define BP_PXP_HIST16_PARAM3_VALUE13 8
  64190. +#define BM_PXP_HIST16_PARAM3_VALUE13 0x00001F00
  64191. +#define BF_PXP_HIST16_PARAM3_VALUE13(v) \
  64192. + (((v) << 8) & BM_PXP_HIST16_PARAM3_VALUE13)
  64193. +#define BP_PXP_HIST16_PARAM3_RSVD12 5
  64194. +#define BM_PXP_HIST16_PARAM3_RSVD12 0x000000E0
  64195. +#define BF_PXP_HIST16_PARAM3_RSVD12(v) \
  64196. + (((v) << 5) & BM_PXP_HIST16_PARAM3_RSVD12)
  64197. +#define BP_PXP_HIST16_PARAM3_VALUE12 0
  64198. +#define BM_PXP_HIST16_PARAM3_VALUE12 0x0000001F
  64199. +#define BF_PXP_HIST16_PARAM3_VALUE12(v) \
  64200. + (((v) << 0) & BM_PXP_HIST16_PARAM3_VALUE12)
  64201. +
  64202. +#define HW_PXP_POWER (0x00000320)
  64203. +
  64204. +#define BP_PXP_POWER_CTRL 12
  64205. +#define BM_PXP_POWER_CTRL 0xFFFFF000
  64206. +#define BF_PXP_POWER_CTRL(v) \
  64207. + (((v) << 12) & BM_PXP_POWER_CTRL)
  64208. +#define BP_PXP_POWER_ROT_MEM_LP_STATE 9
  64209. +#define BM_PXP_POWER_ROT_MEM_LP_STATE 0x00000E00
  64210. +#define BF_PXP_POWER_ROT_MEM_LP_STATE(v) \
  64211. + (((v) << 9) & BM_PXP_POWER_ROT_MEM_LP_STATE)
  64212. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__NONE 0x0
  64213. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__LS 0x1
  64214. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__DS 0x2
  64215. +#define BV_PXP_POWER_ROT_MEM_LP_STATE__SD 0x4
  64216. +#define BP_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 6
  64217. +#define BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 0x000001C0
  64218. +#define BF_PXP_POWER_LUT_LP_STATE_WAY1_BANKN(v) \
  64219. + (((v) << 6) & BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN)
  64220. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__NONE 0x0
  64221. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__LS 0x1
  64222. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__DS 0x2
  64223. +#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__SD 0x4
  64224. +#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 3
  64225. +#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 0x00000038
  64226. +#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANKN(v) \
  64227. + (((v) << 3) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN)
  64228. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__NONE 0x0
  64229. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__LS 0x1
  64230. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__DS 0x2
  64231. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__SD 0x4
  64232. +#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0
  64233. +#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0x00000007
  64234. +#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANK0(v) \
  64235. + (((v) << 0) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0)
  64236. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__NONE 0x0
  64237. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__LS 0x1
  64238. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__DS 0x2
  64239. +#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__SD 0x4
  64240. +
  64241. +#define HW_PXP_NEXT (0x00000400)
  64242. +
  64243. +#define BP_PXP_NEXT_POINTER 2
  64244. +#define BM_PXP_NEXT_POINTER 0xFFFFFFFC
  64245. +#define BF_PXP_NEXT_POINTER(v) \
  64246. + (((v) << 2) & BM_PXP_NEXT_POINTER)
  64247. +#define BM_PXP_NEXT_RSVD 0x00000002
  64248. +#define BM_PXP_NEXT_ENABLED 0x00000001
  64249. +
  64250. +#define HW_PXP_DEBUGCTRL (0x00000410)
  64251. +
  64252. +#define BP_PXP_DEBUGCTRL_RSVD 12
  64253. +#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000
  64254. +#define BF_PXP_DEBUGCTRL_RSVD(v) \
  64255. + (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD)
  64256. +#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 8
  64257. +#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00
  64258. +#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v) \
  64259. + (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT)
  64260. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE 0x0
  64261. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1
  64262. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT 0x2
  64263. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT 0x4
  64264. +#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT 0x8
  64265. +#define BP_PXP_DEBUGCTRL_SELECT 0
  64266. +#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF
  64267. +#define BF_PXP_DEBUGCTRL_SELECT(v) \
  64268. + (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT)
  64269. +#define BV_PXP_DEBUGCTRL_SELECT__NONE 0x0
  64270. +#define BV_PXP_DEBUGCTRL_SELECT__CTRL 0x1
  64271. +#define BV_PXP_DEBUGCTRL_SELECT__PSBUF 0x2
  64272. +#define BV_PXP_DEBUGCTRL_SELECT__PSBAX 0x3
  64273. +#define BV_PXP_DEBUGCTRL_SELECT__PSBAY 0x4
  64274. +#define BV_PXP_DEBUGCTRL_SELECT__ASBUF 0x5
  64275. +#define BV_PXP_DEBUGCTRL_SELECT__ROTATION 0x6
  64276. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0 0x7
  64277. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1 0x8
  64278. +#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2 0x9
  64279. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT 0x10
  64280. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS 0x11
  64281. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT 0x12
  64282. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT 0x13
  64283. +#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14
  64284. +
  64285. +#define HW_PXP_DEBUG (0x00000420)
  64286. +
  64287. +#define BP_PXP_DEBUG_DATA 0
  64288. +#define BM_PXP_DEBUG_DATA 0xFFFFFFFF
  64289. +#define BF_PXP_DEBUG_DATA(v) (v)
  64290. +
  64291. +#define HW_PXP_VERSION (0x00000430)
  64292. +
  64293. +#define BP_PXP_VERSION_MAJOR 24
  64294. +#define BM_PXP_VERSION_MAJOR 0xFF000000
  64295. +#define BF_PXP_VERSION_MAJOR(v) \
  64296. + (((v) << 24) & BM_PXP_VERSION_MAJOR)
  64297. +#define BP_PXP_VERSION_MINOR 16
  64298. +#define BM_PXP_VERSION_MINOR 0x00FF0000
  64299. +#define BF_PXP_VERSION_MINOR(v) \
  64300. + (((v) << 16) & BM_PXP_VERSION_MINOR)
  64301. +#define BP_PXP_VERSION_STEP 0
  64302. +#define BM_PXP_VERSION_STEP 0x0000FFFF
  64303. +#define BF_PXP_VERSION_STEP(v) \
  64304. + (((v) << 0) & BM_PXP_VERSION_STEP)
  64305. +#endif /* __ARCH_ARM___PXP_H */
  64306. diff -Nur linux-3.14.17/drivers/gpio/gpio-pca953x.c linux-imx6-3.14/drivers/gpio/gpio-pca953x.c
  64307. --- linux-3.14.17/drivers/gpio/gpio-pca953x.c 2014-08-14 03:38:34.000000000 +0200
  64308. +++ linux-imx6-3.14/drivers/gpio/gpio-pca953x.c 2014-09-11 18:06:00.354031392 +0200
  64309. @@ -19,6 +19,7 @@
  64310. #include <linux/irqdomain.h>
  64311. #include <linux/i2c.h>
  64312. #include <linux/platform_data/pca953x.h>
  64313. +#include <linux/reset.h>
  64314. #include <linux/slab.h>
  64315. #ifdef CONFIG_OF_GPIO
  64316. #include <linux/of_platform.h>
  64317. @@ -741,6 +742,10 @@
  64318. mutex_init(&chip->i2c_lock);
  64319. + ret = device_reset(&client->dev);
  64320. + if (ret == -ENODEV)
  64321. + return -EPROBE_DEFER;
  64322. +
  64323. /* initialize cached registers from their original values.
  64324. * we can't share this chip with another i2c master.
  64325. */
  64326. diff -Nur linux-3.14.17/drivers/gpu/drm/drm_crtc_helper.c linux-imx6-3.14/drivers/gpu/drm/drm_crtc_helper.c
  64327. --- linux-3.14.17/drivers/gpu/drm/drm_crtc_helper.c 2014-08-14 03:38:34.000000000 +0200
  64328. +++ linux-imx6-3.14/drivers/gpu/drm/drm_crtc_helper.c 2014-09-11 18:06:00.478031888 +0200
  64329. @@ -564,7 +564,7 @@
  64330. * Caller must hold mode config lock.
  64331. *
  64332. * Setup a new configuration, provided by the upper layers (either an ioctl call
  64333. - * from userspace or internally e.g. from the fbdev suppport code) in @set, and
  64334. + * from userspace or internally e.g. from the fbdev support code) in @set, and
  64335. * enable it. This is the main helper functions for drivers that implement
  64336. * kernel mode setting with the crtc helper functions and the assorted
  64337. * ->prepare(), ->modeset() and ->commit() helper callbacks.
  64338. diff -Nur linux-3.14.17/drivers/gpu/drm/drm_prime.c linux-imx6-3.14/drivers/gpu/drm/drm_prime.c
  64339. --- linux-3.14.17/drivers/gpu/drm/drm_prime.c 2014-08-14 03:38:34.000000000 +0200
  64340. +++ linux-imx6-3.14/drivers/gpu/drm/drm_prime.c 2014-09-11 18:06:00.494031953 +0200
  64341. @@ -471,7 +471,7 @@
  64342. get_dma_buf(dma_buf);
  64343. sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
  64344. - if (IS_ERR_OR_NULL(sgt)) {
  64345. + if (IS_ERR(sgt)) {
  64346. ret = PTR_ERR(sgt);
  64347. goto fail_detach;
  64348. }
  64349. diff -Nur linux-3.14.17/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c linux-imx6-3.14/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
  64350. --- linux-3.14.17/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 2014-08-14 03:38:34.000000000 +0200
  64351. +++ linux-imx6-3.14/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 2014-09-11 18:06:00.498031968 +0200
  64352. @@ -224,7 +224,7 @@
  64353. get_dma_buf(dma_buf);
  64354. sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
  64355. - if (IS_ERR_OR_NULL(sgt)) {
  64356. + if (IS_ERR(sgt)) {
  64357. ret = PTR_ERR(sgt);
  64358. goto err_buf_detach;
  64359. }
  64360. diff -Nur linux-3.14.17/drivers/gpu/drm/Kconfig linux-imx6-3.14/drivers/gpu/drm/Kconfig
  64361. --- linux-3.14.17/drivers/gpu/drm/Kconfig 2014-08-14 03:38:34.000000000 +0200
  64362. +++ linux-imx6-3.14/drivers/gpu/drm/Kconfig 2014-09-11 18:06:00.394031553 +0200
  64363. @@ -166,6 +166,13 @@
  64364. Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
  64365. chipset. If M is selected the module will be called savage.
  64366. +config DRM_VIVANTE
  64367. + tristate "Vivante GCCore"
  64368. + depends on DRM
  64369. + help
  64370. + Choose this option if you have a Vivante graphics card.
  64371. + If M is selected, the module will be called vivante.
  64372. +
  64373. source "drivers/gpu/drm/exynos/Kconfig"
  64374. source "drivers/gpu/drm/vmwgfx/Kconfig"
  64375. diff -Nur linux-3.14.17/drivers/gpu/drm/Makefile linux-imx6-3.14/drivers/gpu/drm/Makefile
  64376. --- linux-3.14.17/drivers/gpu/drm/Makefile 2014-08-14 03:38:34.000000000 +0200
  64377. +++ linux-imx6-3.14/drivers/gpu/drm/Makefile 2014-09-11 18:06:00.394031553 +0200
  64378. @@ -1,3 +1,24 @@
  64379. +##############################################################################
  64380. +#
  64381. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  64382. +#
  64383. +# This program is free software; you can redistribute it and/or modify
  64384. +# it under the terms of the GNU General Public License as published by
  64385. +# the Free Software Foundation; either version 2 of the license, or
  64386. +# (at your option) any later version.
  64387. +#
  64388. +# This program is distributed in the hope that it will be useful,
  64389. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  64390. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64391. +# GNU General Public License for more details.
  64392. +#
  64393. +# You should have received a copy of the GNU General Public License
  64394. +# along with this program; if not write to the Free Software
  64395. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  64396. +#
  64397. +##############################################################################
  64398. +
  64399. +
  64400. #
  64401. # Makefile for the drm device driver. This driver provides support for the
  64402. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
  64403. @@ -35,6 +56,7 @@
  64404. obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
  64405. obj-$(CONFIG_DRM_USB) += drm_usb.o
  64406. obj-$(CONFIG_DRM_TTM) += ttm/
  64407. +obj-$(CONFIG_DRM_VIVANTE) += vivante/
  64408. obj-$(CONFIG_DRM_TDFX) += tdfx/
  64409. obj-$(CONFIG_DRM_R128) += r128/
  64410. obj-$(CONFIG_DRM_RADEON)+= radeon/
  64411. diff -Nur linux-3.14.17/drivers/gpu/drm/radeon/cik.c linux-imx6-3.14/drivers/gpu/drm/radeon/cik.c
  64412. --- linux-3.14.17/drivers/gpu/drm/radeon/cik.c 2014-08-14 03:38:34.000000000 +0200
  64413. +++ linux-imx6-3.14/drivers/gpu/drm/radeon/cik.c 2014-09-11 18:06:00.878033486 +0200
  64414. @@ -2219,7 +2219,6 @@
  64415. gb_tile_moden = 0;
  64416. break;
  64417. }
  64418. - rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
  64419. WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
  64420. }
  64421. } else if (num_pipe_configs == 8) {
  64422. @@ -7271,7 +7270,6 @@
  64423. tmp = RREG32(IH_RB_CNTL);
  64424. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  64425. WREG32(IH_RB_CNTL, tmp);
  64426. - wptr &= ~RB_OVERFLOW;
  64427. }
  64428. return (wptr & rdev->ih.ptr_mask);
  64429. }
  64430. diff -Nur linux-3.14.17/drivers/gpu/drm/radeon/evergreen.c linux-imx6-3.14/drivers/gpu/drm/radeon/evergreen.c
  64431. --- linux-3.14.17/drivers/gpu/drm/radeon/evergreen.c 2014-08-14 03:38:34.000000000 +0200
  64432. +++ linux-imx6-3.14/drivers/gpu/drm/radeon/evergreen.c 2014-09-11 18:06:00.882033502 +0200
  64433. @@ -4763,7 +4763,6 @@
  64434. tmp = RREG32(IH_RB_CNTL);
  64435. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  64436. WREG32(IH_RB_CNTL, tmp);
  64437. - wptr &= ~RB_OVERFLOW;
  64438. }
  64439. return (wptr & rdev->ih.ptr_mask);
  64440. }
  64441. diff -Nur linux-3.14.17/drivers/gpu/drm/radeon/r600.c linux-imx6-3.14/drivers/gpu/drm/radeon/r600.c
  64442. --- linux-3.14.17/drivers/gpu/drm/radeon/r600.c 2014-08-14 03:38:34.000000000 +0200
  64443. +++ linux-imx6-3.14/drivers/gpu/drm/radeon/r600.c 2014-09-11 18:06:00.890033535 +0200
  64444. @@ -3795,7 +3795,6 @@
  64445. tmp = RREG32(IH_RB_CNTL);
  64446. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  64447. WREG32(IH_RB_CNTL, tmp);
  64448. - wptr &= ~RB_OVERFLOW;
  64449. }
  64450. return (wptr & rdev->ih.ptr_mask);
  64451. }
  64452. diff -Nur linux-3.14.17/drivers/gpu/drm/radeon/si.c linux-imx6-3.14/drivers/gpu/drm/radeon/si.c
  64453. --- linux-3.14.17/drivers/gpu/drm/radeon/si.c 2014-08-14 03:38:34.000000000 +0200
  64454. +++ linux-imx6-3.14/drivers/gpu/drm/radeon/si.c 2014-09-11 18:06:00.910033615 +0200
  64455. @@ -6098,7 +6098,6 @@
  64456. tmp = RREG32(IH_RB_CNTL);
  64457. tmp |= IH_WPTR_OVERFLOW_CLEAR;
  64458. WREG32(IH_RB_CNTL, tmp);
  64459. - wptr &= ~RB_OVERFLOW;
  64460. }
  64461. return (wptr & rdev->ih.ptr_mask);
  64462. }
  64463. diff -Nur linux-3.14.17/drivers/gpu/drm/vivante/Makefile linux-imx6-3.14/drivers/gpu/drm/vivante/Makefile
  64464. --- linux-3.14.17/drivers/gpu/drm/vivante/Makefile 1970-01-01 01:00:00.000000000 +0100
  64465. +++ linux-imx6-3.14/drivers/gpu/drm/vivante/Makefile 2014-09-11 18:06:00.966033837 +0200
  64466. @@ -0,0 +1,29 @@
  64467. +##############################################################################
  64468. +#
  64469. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  64470. +#
  64471. +# This program is free software; you can redistribute it and/or modify
  64472. +# it under the terms of the GNU General Public License as published by
  64473. +# the Free Software Foundation; either version 2 of the license, or
  64474. +# (at your option) any later version.
  64475. +#
  64476. +# This program is distributed in the hope that it will be useful,
  64477. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  64478. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64479. +# GNU General Public License for more details.
  64480. +#
  64481. +# You should have received a copy of the GNU General Public License
  64482. +# along with this program; if not write to the Free Software
  64483. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  64484. +#
  64485. +##############################################################################
  64486. +
  64487. +
  64488. +#
  64489. +# Makefile for the drm device driver. This driver provides support for the
  64490. +# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
  64491. +
  64492. +ccflags-y := -Iinclude/drm
  64493. +vivante-y := vivante_drv.o
  64494. +
  64495. +obj-$(CONFIG_DRM_VIVANTE) += vivante.o
  64496. diff -Nur linux-3.14.17/drivers/gpu/drm/vivante/vivante_drv.c linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.c
  64497. --- linux-3.14.17/drivers/gpu/drm/vivante/vivante_drv.c 1970-01-01 01:00:00.000000000 +0100
  64498. +++ linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.c 2014-09-11 18:06:00.966033837 +0200
  64499. @@ -0,0 +1,108 @@
  64500. +/****************************************************************************
  64501. +*
  64502. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  64503. +*
  64504. +* This program is free software; you can redistribute it and/or modify
  64505. +* it under the terms of the GNU General Public License as published by
  64506. +* the Free Software Foundation; either version 2 of the license, or
  64507. +* (at your option) any later version.
  64508. +*
  64509. +* This program is distributed in the hope that it will be useful,
  64510. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  64511. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64512. +* GNU General Public License for more details.
  64513. +*
  64514. +* You should have received a copy of the GNU General Public License
  64515. +* along with this program; if not write to the Free Software
  64516. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  64517. +*
  64518. +*****************************************************************************/
  64519. +
  64520. +
  64521. +/* vivante_drv.c -- vivante driver -*- linux-c -*-
  64522. + *
  64523. + *
  64524. + * Permission is hereby granted, free of charge, to any person obtaining a
  64525. + * copy of this software and associated documentation files (the "Software"),
  64526. + * to deal in the Software without restriction, including without limitation
  64527. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  64528. + * and/or sell copies of the Software, and to permit persons to whom the
  64529. + * Software is furnished to do so, subject to the following conditions:
  64530. + *
  64531. + * The above copyright notice and this permission notice (including the next
  64532. + * paragraph) shall be included in all copies or substantial portions of the
  64533. + * Software.
  64534. + *
  64535. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  64536. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  64537. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  64538. + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  64539. + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  64540. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  64541. + * DEALINGS IN THE SOFTWARE.
  64542. + *
  64543. + * Authors:
  64544. + * Rickard E. (Rik) Faith <faith@valinux.com>
  64545. + * Daryll Strauss <daryll@valinux.com>
  64546. + * Gareth Hughes <gareth@valinux.com>
  64547. + */
  64548. +
  64549. +#include <linux/version.h>
  64550. +#include <linux/module.h>
  64551. +
  64552. +#include "drmP.h"
  64553. +#include "vivante_drv.h"
  64554. +
  64555. +#include "drm_pciids.h"
  64556. +
  64557. +static char platformdevicename[] = "Vivante GCCore";
  64558. +static struct platform_device *pplatformdev;
  64559. +
  64560. +static const struct file_operations viv_driver_fops = {
  64561. + .owner = THIS_MODULE,
  64562. + .open = drm_open,
  64563. + .release = drm_release,
  64564. + .unlocked_ioctl = drm_ioctl,
  64565. + .mmap = drm_mmap,
  64566. + .poll = drm_poll,
  64567. + .llseek = noop_llseek,
  64568. +};
  64569. +
  64570. +static struct drm_driver driver = {
  64571. + .fops = &viv_driver_fops,
  64572. + .name = DRIVER_NAME,
  64573. + .desc = DRIVER_DESC,
  64574. + .date = DRIVER_DATE,
  64575. + .major = DRIVER_MAJOR,
  64576. + .minor = DRIVER_MINOR,
  64577. + .patchlevel = DRIVER_PATCHLEVEL,
  64578. +};
  64579. +
  64580. +static int __init vivante_init(void)
  64581. +{
  64582. + int retcode;
  64583. +
  64584. + pplatformdev = platform_device_register_simple(platformdevicename,
  64585. + -1, NULL, 0);
  64586. + if (pplatformdev == NULL)
  64587. + printk(KERN_ERR"Platform device is null\n");
  64588. +
  64589. + retcode = drm_platform_init(&driver, pplatformdev);
  64590. +
  64591. + return retcode;
  64592. +}
  64593. +
  64594. +static void __exit vivante_exit(void)
  64595. +{
  64596. + if (pplatformdev) {
  64597. + platform_device_unregister(pplatformdev);
  64598. + pplatformdev = NULL;
  64599. + }
  64600. +}
  64601. +
  64602. +module_init(vivante_init);
  64603. +module_exit(vivante_exit);
  64604. +
  64605. +MODULE_AUTHOR(DRIVER_AUTHOR);
  64606. +MODULE_DESCRIPTION(DRIVER_DESC);
  64607. +MODULE_LICENSE("GPL and additional rights");
  64608. diff -Nur linux-3.14.17/drivers/gpu/drm/vivante/vivante_drv.h linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.h
  64609. --- linux-3.14.17/drivers/gpu/drm/vivante/vivante_drv.h 1970-01-01 01:00:00.000000000 +0100
  64610. +++ linux-imx6-3.14/drivers/gpu/drm/vivante/vivante_drv.h 2014-09-11 18:06:00.966033837 +0200
  64611. @@ -0,0 +1,66 @@
  64612. +/****************************************************************************
  64613. +*
  64614. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  64615. +*
  64616. +* This program is free software; you can redistribute it and/or modify
  64617. +* it under the terms of the GNU General Public License as published by
  64618. +* the Free Software Foundation; either version 2 of the license, or
  64619. +* (at your option) any later version.
  64620. +*
  64621. +* This program is distributed in the hope that it will be useful,
  64622. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  64623. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64624. +* GNU General Public License for more details.
  64625. +*
  64626. +* You should have received a copy of the GNU General Public License
  64627. +* along with this program; if not write to the Free Software
  64628. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  64629. +*
  64630. +*****************************************************************************/
  64631. +
  64632. +
  64633. +/* vivante_drv.h -- Vivante DRM template customization -*- linux-c -*-
  64634. + * Created: Wed Feb 14 12:32:32 2012 by John Zhao
  64635. + */
  64636. +/*
  64637. + *
  64638. + * Permission is hereby granted, free of charge, to any person obtaining a
  64639. + * copy of this software and associated documentation files (the "Software"),
  64640. + * to deal in the Software without restriction, including without limitation
  64641. + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  64642. + * and/or sell copies of the Software, and to permit persons to whom the
  64643. + * Software is furnished to do so, subject to the following conditions:
  64644. + *
  64645. + * The above copyright notice and this permission notice (including the next
  64646. + * paragraph) shall be included in all copies or substantial portions of the
  64647. + * Software.
  64648. + *
  64649. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  64650. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  64651. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  64652. + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  64653. + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  64654. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  64655. + * OTHER DEALINGS IN THE SOFTWARE.
  64656. + *
  64657. + * Authors:
  64658. + * Gareth Hughes <gareth@valinux.com>
  64659. + */
  64660. +
  64661. +#ifndef __VIVANTE_DRV_H__
  64662. +#define __VIVANTE_DRV_H__
  64663. +
  64664. +/* General customization:
  64665. + */
  64666. +
  64667. +#define DRIVER_AUTHOR "Vivante Inc."
  64668. +
  64669. +#define DRIVER_NAME "vivante"
  64670. +#define DRIVER_DESC "Vivante GCCore"
  64671. +#define DRIVER_DATE "20120216"
  64672. +
  64673. +#define DRIVER_MAJOR 1
  64674. +#define DRIVER_MINOR 0
  64675. +#define DRIVER_PATCHLEVEL 0
  64676. +
  64677. +#endif
  64678. diff -Nur linux-3.14.17/drivers/hwmon/Kconfig linux-imx6-3.14/drivers/hwmon/Kconfig
  64679. --- linux-3.14.17/drivers/hwmon/Kconfig 2014-08-14 03:38:34.000000000 +0200
  64680. +++ linux-imx6-3.14/drivers/hwmon/Kconfig 2014-09-11 18:06:01.102034382 +0200
  64681. @@ -1584,4 +1584,19 @@
  64682. endif # ACPI
  64683. +config SENSORS_MAG3110
  64684. + tristate "Freescale MAG3110 e-compass sensor"
  64685. + depends on I2C && SYSFS
  64686. + help
  64687. + If you say yes here you get support for the Freescale MAG3110
  64688. + e-compass sensor.
  64689. + This driver can also be built as a module. If so, the module
  64690. + will be called mag3110.
  64691. +
  64692. +config MXC_MMA8451
  64693. + tristate "MMA8451 device driver"
  64694. + depends on I2C
  64695. + depends on INPUT_POLLDEV
  64696. + default y
  64697. +
  64698. endif # HWMON
  64699. diff -Nur linux-3.14.17/drivers/hwmon/mag3110.c linux-imx6-3.14/drivers/hwmon/mag3110.c
  64700. --- linux-3.14.17/drivers/hwmon/mag3110.c 1970-01-01 01:00:00.000000000 +0100
  64701. +++ linux-imx6-3.14/drivers/hwmon/mag3110.c 2014-09-11 18:06:01.178034686 +0200
  64702. @@ -0,0 +1,611 @@
  64703. +/*
  64704. + *
  64705. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  64706. + *
  64707. + * This program is free software; you can redistribute it and/or modify
  64708. + * it under the terms of the GNU General Public License as published by
  64709. + * the Free Software Foundation; either version 2 of the License, or
  64710. + * (at your option) any later version.
  64711. +
  64712. + * This program is distributed in the hope that it will be useful,
  64713. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  64714. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64715. + * GNU General Public License for more details.
  64716. +
  64717. + * You should have received a copy of the GNU General Public License along
  64718. + * with this program; if not, write to the Free Software Foundation, Inc.,
  64719. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  64720. + */
  64721. +
  64722. +#include <linux/module.h>
  64723. +#include <linux/kernel.h>
  64724. +#include <linux/slab.h>
  64725. +#include <linux/interrupt.h>
  64726. +#include <linux/delay.h>
  64727. +#include <linux/i2c.h>
  64728. +#include <linux/irq.h>
  64729. +#include <linux/platform_device.h>
  64730. +#include <linux/input-polldev.h>
  64731. +#include <linux/hwmon.h>
  64732. +#include <linux/input.h>
  64733. +#include <linux/wait.h>
  64734. +#include <linux/workqueue.h>
  64735. +#include <linux/of.h>
  64736. +#include <linux/regulator/consumer.h>
  64737. +
  64738. +#define MAG3110_DRV_NAME "mag3110"
  64739. +#define MAG3110_ID 0xC4
  64740. +#define MAG3110_XYZ_DATA_LEN 6
  64741. +#define MAG3110_STATUS_ZYXDR 0x08
  64742. +
  64743. +#define MAG3110_AC_MASK (0x01)
  64744. +#define MAG3110_AC_OFFSET 0
  64745. +#define MAG3110_DR_MODE_MASK (0x7 << 5)
  64746. +#define MAG3110_DR_MODE_OFFSET 5
  64747. +#define MAG3110_IRQ_USED 0
  64748. +
  64749. +#define POLL_INTERVAL_MAX 500
  64750. +#define POLL_INTERVAL 100
  64751. +#define INT_TIMEOUT 1000
  64752. +#define DEFAULT_POSITION 2
  64753. +/* register enum for mag3110 registers */
  64754. +enum {
  64755. + MAG3110_DR_STATUS = 0x00,
  64756. + MAG3110_OUT_X_MSB,
  64757. + MAG3110_OUT_X_LSB,
  64758. + MAG3110_OUT_Y_MSB,
  64759. + MAG3110_OUT_Y_LSB,
  64760. + MAG3110_OUT_Z_MSB,
  64761. + MAG3110_OUT_Z_LSB,
  64762. + MAG3110_WHO_AM_I,
  64763. +
  64764. + MAG3110_OFF_X_MSB,
  64765. + MAG3110_OFF_X_LSB,
  64766. + MAG3110_OFF_Y_MSB,
  64767. + MAG3110_OFF_Y_LSB,
  64768. + MAG3110_OFF_Z_MSB,
  64769. + MAG3110_OFF_Z_LSB,
  64770. +
  64771. + MAG3110_DIE_TEMP,
  64772. +
  64773. + MAG3110_CTRL_REG1 = 0x10,
  64774. + MAG3110_CTRL_REG2,
  64775. +};
  64776. +enum {
  64777. + MAG_STANDBY,
  64778. + MAG_ACTIVED
  64779. +};
  64780. +struct mag3110_data {
  64781. + struct i2c_client *client;
  64782. + struct input_polled_dev *poll_dev;
  64783. + struct device *hwmon_dev;
  64784. + wait_queue_head_t waitq;
  64785. + bool data_ready;
  64786. + u8 ctl_reg1;
  64787. + int active;
  64788. + int position;
  64789. +};
  64790. +static short MAGHAL[8][3][3] = {
  64791. + { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
  64792. + { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
  64793. + { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
  64794. + { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
  64795. +
  64796. + { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
  64797. + { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
  64798. + { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
  64799. + { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
  64800. +};
  64801. +
  64802. +static struct mag3110_data *mag3110_pdata;
  64803. +/*!
  64804. + * This function do one mag3110 register read.
  64805. + */
  64806. +static DEFINE_MUTEX(mag3110_lock);
  64807. +static int mag3110_adjust_position(short *x, short *y, short *z)
  64808. +{
  64809. + short rawdata[3], data[3];
  64810. + int i, j;
  64811. + int position = mag3110_pdata->position;
  64812. + if (position < 0 || position > 7)
  64813. + position = 0;
  64814. + rawdata[0] = *x;
  64815. + rawdata[1] = *y;
  64816. + rawdata[2] = *z;
  64817. + for (i = 0; i < 3; i++) {
  64818. + data[i] = 0;
  64819. + for (j = 0; j < 3; j++)
  64820. + data[i] += rawdata[j] * MAGHAL[position][i][j];
  64821. + }
  64822. + *x = data[0];
  64823. + *y = data[1];
  64824. + *z = data[2];
  64825. + return 0;
  64826. +}
  64827. +
  64828. +static int mag3110_read_reg(struct i2c_client *client, u8 reg)
  64829. +{
  64830. + return i2c_smbus_read_byte_data(client, reg);
  64831. +}
  64832. +
  64833. +/*!
  64834. + * This function do one mag3110 register write.
  64835. + */
  64836. +static int mag3110_write_reg(struct i2c_client *client, u8 reg, char value)
  64837. +{
  64838. + int ret;
  64839. +
  64840. + ret = i2c_smbus_write_byte_data(client, reg, value);
  64841. + if (ret < 0)
  64842. + dev_err(&client->dev, "i2c write failed\n");
  64843. + return ret;
  64844. +}
  64845. +
  64846. +/*!
  64847. + * This function do multiple mag3110 registers read.
  64848. + */
  64849. +static int mag3110_read_block_data(struct i2c_client *client, u8 reg,
  64850. + int count, u8 *addr)
  64851. +{
  64852. + if (i2c_smbus_read_i2c_block_data(client, reg, count, addr) < count) {
  64853. + dev_err(&client->dev, "i2c block read failed\n");
  64854. + return -1;
  64855. + }
  64856. +
  64857. + return count;
  64858. +}
  64859. +
  64860. +/*
  64861. + * Initialization function
  64862. + */
  64863. +static int mag3110_init_client(struct i2c_client *client)
  64864. +{
  64865. + int val, ret;
  64866. +
  64867. + /* enable automatic resets */
  64868. + val = 0x80;
  64869. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG2, val);
  64870. +
  64871. + /* set default data rate to 10HZ */
  64872. + val = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  64873. + val |= (0x0 << MAG3110_DR_MODE_OFFSET);
  64874. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, val);
  64875. +
  64876. + return ret;
  64877. +}
  64878. +
  64879. +/***************************************************************
  64880. +*
  64881. +* read sensor data from mag3110
  64882. +*
  64883. +***************************************************************/
  64884. +static int mag3110_read_data(short *x, short *y, short *z)
  64885. +{
  64886. + struct mag3110_data *data;
  64887. + int retry = 3;
  64888. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  64889. + int result;
  64890. + if (!mag3110_pdata || mag3110_pdata->active == MAG_STANDBY)
  64891. + return -EINVAL;
  64892. +
  64893. + data = mag3110_pdata;
  64894. +#if MAG3110_IRQ_USED
  64895. + if (!wait_event_interruptible_timeout
  64896. + (data->waitq, data->data_ready != 0,
  64897. + msecs_to_jiffies(INT_TIMEOUT))) {
  64898. + dev_dbg(&data->client->dev, "interrupt not received\n");
  64899. + return -ETIME;
  64900. + }
  64901. +#else
  64902. + do {
  64903. + msleep(1);
  64904. + result = i2c_smbus_read_byte_data(data->client,
  64905. + MAG3110_DR_STATUS);
  64906. + retry--;
  64907. + } while (!(result & MAG3110_STATUS_ZYXDR) && retry > 0);
  64908. + /* Clear data_ready flag after data is read out */
  64909. + if (retry == 0)
  64910. + return -EINVAL;
  64911. +#endif
  64912. +
  64913. + data->data_ready = 0;
  64914. +
  64915. + if (mag3110_read_block_data(data->client,
  64916. + MAG3110_OUT_X_MSB, MAG3110_XYZ_DATA_LEN,
  64917. + tmp_data) < 0)
  64918. + return -1;
  64919. +
  64920. + *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
  64921. + *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
  64922. + *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
  64923. +
  64924. + return 0;
  64925. +}
  64926. +
  64927. +static void report_abs(void)
  64928. +{
  64929. + struct input_dev *idev;
  64930. + short x, y, z;
  64931. +
  64932. + mutex_lock(&mag3110_lock);
  64933. + if (mag3110_read_data(&x, &y, &z) != 0)
  64934. + goto out;
  64935. + mag3110_adjust_position(&x, &y, &z);
  64936. + idev = mag3110_pdata->poll_dev->input;
  64937. + input_report_abs(idev, ABS_X, x);
  64938. + input_report_abs(idev, ABS_Y, y);
  64939. + input_report_abs(idev, ABS_Z, z);
  64940. + input_sync(idev);
  64941. +out:
  64942. + mutex_unlock(&mag3110_lock);
  64943. +}
  64944. +
  64945. +static void mag3110_dev_poll(struct input_polled_dev *dev)
  64946. +{
  64947. + report_abs();
  64948. +}
  64949. +
  64950. +#if MAG3110_IRQ_USED
  64951. +static irqreturn_t mag3110_irq_handler(int irq, void *dev_id)
  64952. +{
  64953. + mag3110_pdata->data_ready = 1;
  64954. + wake_up_interruptible(&mag3110_pdata->waitq);
  64955. +
  64956. + return IRQ_HANDLED;
  64957. +}
  64958. +#endif
  64959. +static ssize_t mag3110_enable_show(struct device *dev,
  64960. + struct device_attribute *attr, char *buf)
  64961. +{
  64962. + struct i2c_client *client;
  64963. + int val;
  64964. + mutex_lock(&mag3110_lock);
  64965. + client = mag3110_pdata->client;
  64966. + val = mag3110_read_reg(client, MAG3110_CTRL_REG1) & MAG3110_AC_MASK;
  64967. +
  64968. + mutex_unlock(&mag3110_lock);
  64969. + return sprintf(buf, "%d\n", val);
  64970. +}
  64971. +
  64972. +static ssize_t mag3110_enable_store(struct device *dev,
  64973. + struct device_attribute *attr,
  64974. + const char *buf, size_t count)
  64975. +{
  64976. + struct i2c_client *client;
  64977. + int reg, ret;
  64978. + long enable;
  64979. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  64980. +
  64981. + ret = strict_strtol(buf, 10, &enable);
  64982. + if (ret) {
  64983. + dev_err(dev, "string to long error\n");
  64984. + return ret;
  64985. + }
  64986. +
  64987. + mutex_lock(&mag3110_lock);
  64988. + client = mag3110_pdata->client;
  64989. + reg = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  64990. + if (enable && mag3110_pdata->active == MAG_STANDBY) {
  64991. + reg |= MAG3110_AC_MASK;
  64992. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  64993. + if (!ret)
  64994. + mag3110_pdata->active = MAG_ACTIVED;
  64995. + } else if (!enable && mag3110_pdata->active == MAG_ACTIVED) {
  64996. + reg &= ~MAG3110_AC_MASK;
  64997. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  64998. + if (!ret)
  64999. + mag3110_pdata->active = MAG_STANDBY;
  65000. + }
  65001. +
  65002. + if (mag3110_pdata->active == MAG_ACTIVED) {
  65003. + msleep(100);
  65004. + /* Read out MSB data to clear interrupt flag automatically */
  65005. + mag3110_read_block_data(client, MAG3110_OUT_X_MSB,
  65006. + MAG3110_XYZ_DATA_LEN, tmp_data);
  65007. + }
  65008. + mutex_unlock(&mag3110_lock);
  65009. + return count;
  65010. +}
  65011. +
  65012. +static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
  65013. + mag3110_enable_show, mag3110_enable_store);
  65014. +
  65015. +static ssize_t mag3110_dr_mode_show(struct device *dev,
  65016. + struct device_attribute *attr, char *buf)
  65017. +{
  65018. + struct i2c_client *client;
  65019. + int val;
  65020. +
  65021. + client = mag3110_pdata->client;
  65022. + val = (mag3110_read_reg(client, MAG3110_CTRL_REG1)
  65023. + & MAG3110_DR_MODE_MASK) >> MAG3110_DR_MODE_OFFSET;
  65024. +
  65025. + return sprintf(buf, "%d\n", val);
  65026. +}
  65027. +
  65028. +static ssize_t mag3110_dr_mode_store(struct device *dev,
  65029. + struct device_attribute *attr,
  65030. + const char *buf, size_t count)
  65031. +{
  65032. + struct i2c_client *client;
  65033. + int reg, ret;
  65034. + unsigned long val;
  65035. +
  65036. + /* This must be done when mag3110 is disabled */
  65037. + if ((strict_strtoul(buf, 10, &val) < 0) || (val > 7))
  65038. + return -EINVAL;
  65039. +
  65040. + client = mag3110_pdata->client;
  65041. + reg = mag3110_read_reg(client, MAG3110_CTRL_REG1) &
  65042. + ~MAG3110_DR_MODE_MASK;
  65043. + reg |= (val << MAG3110_DR_MODE_OFFSET);
  65044. + /* MAG3110_CTRL_REG1 bit 5-7: data rate mode */
  65045. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1, reg);
  65046. + if (ret < 0)
  65047. + return ret;
  65048. +
  65049. + return count;
  65050. +}
  65051. +
  65052. +static DEVICE_ATTR(dr_mode, S_IWUSR | S_IRUGO,
  65053. + mag3110_dr_mode_show, mag3110_dr_mode_store);
  65054. +
  65055. +static ssize_t mag3110_position_show(struct device *dev,
  65056. + struct device_attribute *attr, char *buf)
  65057. +{
  65058. + int val;
  65059. + mutex_lock(&mag3110_lock);
  65060. + val = mag3110_pdata->position;
  65061. + mutex_unlock(&mag3110_lock);
  65062. + return sprintf(buf, "%d\n", val);
  65063. +}
  65064. +
  65065. +static ssize_t mag3110_position_store(struct device *dev,
  65066. + struct device_attribute *attr,
  65067. + const char *buf, size_t count)
  65068. +{
  65069. + long position;
  65070. + int ret;
  65071. + ret = strict_strtol(buf, 10, &position);
  65072. + if (ret) {
  65073. + dev_err(dev, "string to long error\n");
  65074. + return ret;
  65075. + }
  65076. +
  65077. + mutex_lock(&mag3110_lock);
  65078. + mag3110_pdata->position = (int)position;
  65079. + mutex_unlock(&mag3110_lock);
  65080. + return count;
  65081. +}
  65082. +
  65083. +static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
  65084. + mag3110_position_show, mag3110_position_store);
  65085. +
  65086. +static struct attribute *mag3110_attributes[] = {
  65087. + &dev_attr_enable.attr,
  65088. + &dev_attr_dr_mode.attr,
  65089. + &dev_attr_position.attr,
  65090. + NULL
  65091. +};
  65092. +
  65093. +static const struct attribute_group mag3110_attr_group = {
  65094. + .attrs = mag3110_attributes,
  65095. +};
  65096. +
  65097. +static int mag3110_probe(struct i2c_client *client,
  65098. + const struct i2c_device_id *id)
  65099. +{
  65100. + struct i2c_adapter *adapter;
  65101. + struct input_dev *idev;
  65102. + struct mag3110_data *data;
  65103. + int ret = 0;
  65104. + struct regulator *vdd, *vdd_io;
  65105. + u32 pos = 0;
  65106. + struct device_node *of_node = client->dev.of_node;
  65107. + vdd = NULL;
  65108. + vdd_io = NULL;
  65109. +
  65110. + vdd = devm_regulator_get(&client->dev, "vdd");
  65111. + if (!IS_ERR(vdd)) {
  65112. + ret = regulator_enable(vdd);
  65113. + if (ret) {
  65114. + dev_err(&client->dev, "vdd set voltage error\n");
  65115. + return ret;
  65116. + }
  65117. + }
  65118. +
  65119. + vdd_io = devm_regulator_get(&client->dev, "vddio");
  65120. + if (!IS_ERR(vdd_io)) {
  65121. + ret = regulator_enable(vdd_io);
  65122. + if (ret) {
  65123. + dev_err(&client->dev, "vddio set voltage error\n");
  65124. + return ret;
  65125. + }
  65126. + }
  65127. +
  65128. + adapter = to_i2c_adapter(client->dev.parent);
  65129. + if (!i2c_check_functionality(adapter,
  65130. + I2C_FUNC_SMBUS_BYTE |
  65131. + I2C_FUNC_SMBUS_BYTE_DATA |
  65132. + I2C_FUNC_SMBUS_I2C_BLOCK))
  65133. + return -EIO;
  65134. +
  65135. + dev_info(&client->dev, "check mag3110 chip ID\n");
  65136. + ret = mag3110_read_reg(client, MAG3110_WHO_AM_I);
  65137. +
  65138. + if (MAG3110_ID != ret) {
  65139. + dev_err(&client->dev,
  65140. + "read chip ID 0x%x is not equal to 0x%x!\n", ret,
  65141. + MAG3110_ID);
  65142. + return -EINVAL;
  65143. + }
  65144. + data = kzalloc(sizeof(struct mag3110_data), GFP_KERNEL);
  65145. + if (!data)
  65146. + return -ENOMEM;
  65147. + data->client = client;
  65148. + i2c_set_clientdata(client, data);
  65149. + /* Init queue */
  65150. + init_waitqueue_head(&data->waitq);
  65151. +
  65152. + data->hwmon_dev = hwmon_device_register(&client->dev);
  65153. + if (IS_ERR(data->hwmon_dev)) {
  65154. + dev_err(&client->dev, "hwmon register failed!\n");
  65155. + ret = PTR_ERR(data->hwmon_dev);
  65156. + goto error_rm_dev_sysfs;
  65157. + }
  65158. +
  65159. + /*input poll device register */
  65160. + data->poll_dev = input_allocate_polled_device();
  65161. + if (!data->poll_dev) {
  65162. + dev_err(&client->dev, "alloc poll device failed!\n");
  65163. + ret = -ENOMEM;
  65164. + goto error_rm_hwmon_dev;
  65165. + }
  65166. + data->poll_dev->poll = mag3110_dev_poll;
  65167. + data->poll_dev->poll_interval = POLL_INTERVAL;
  65168. + data->poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
  65169. + idev = data->poll_dev->input;
  65170. + idev->name = MAG3110_DRV_NAME;
  65171. + idev->id.bustype = BUS_I2C;
  65172. + idev->evbit[0] = BIT_MASK(EV_ABS);
  65173. + input_set_abs_params(idev, ABS_X, -15000, 15000, 0, 0);
  65174. + input_set_abs_params(idev, ABS_Y, -15000, 15000, 0, 0);
  65175. + input_set_abs_params(idev, ABS_Z, -15000, 15000, 0, 0);
  65176. + ret = input_register_polled_device(data->poll_dev);
  65177. + if (ret) {
  65178. + dev_err(&client->dev, "register poll device failed!\n");
  65179. + goto error_free_poll_dev;
  65180. + }
  65181. +
  65182. + /*create device group in sysfs as user interface */
  65183. + ret = sysfs_create_group(&idev->dev.kobj, &mag3110_attr_group);
  65184. + if (ret) {
  65185. + dev_err(&client->dev, "create device file failed!\n");
  65186. + ret = -EINVAL;
  65187. + goto error_rm_poll_dev;
  65188. + }
  65189. + /* set irq type to edge rising */
  65190. +#if MAG3110_IRQ_USED
  65191. + ret = request_irq(client->irq, mag3110_irq_handler,
  65192. + IRQF_TRIGGER_RISING, client->dev.driver->name, idev);
  65193. + if (ret < 0) {
  65194. + dev_err(&client->dev, "failed to register irq %d!\n",
  65195. + client->irq);
  65196. + goto error_rm_dev_sysfs;
  65197. + }
  65198. +#endif
  65199. + /* Initialize mag3110 chip */
  65200. + mag3110_init_client(client);
  65201. + mag3110_pdata = data;
  65202. + mag3110_pdata->active = MAG_STANDBY;
  65203. + ret = of_property_read_u32(of_node, "position", &pos);
  65204. + if (ret)
  65205. + pos = DEFAULT_POSITION;
  65206. + mag3110_pdata->position = (int)pos;
  65207. + dev_info(&client->dev, "mag3110 is probed\n");
  65208. + return 0;
  65209. +error_rm_dev_sysfs:
  65210. + sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
  65211. +error_rm_poll_dev:
  65212. + input_unregister_polled_device(data->poll_dev);
  65213. +error_free_poll_dev:
  65214. + input_free_polled_device(data->poll_dev);
  65215. +error_rm_hwmon_dev:
  65216. + hwmon_device_unregister(data->hwmon_dev);
  65217. +
  65218. + kfree(data);
  65219. + mag3110_pdata = NULL;
  65220. +
  65221. + return ret;
  65222. +}
  65223. +
  65224. +static int mag3110_remove(struct i2c_client *client)
  65225. +{
  65226. + struct mag3110_data *data;
  65227. + int ret;
  65228. +
  65229. + data = i2c_get_clientdata(client);
  65230. +
  65231. + data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  65232. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  65233. + data->ctl_reg1 & ~MAG3110_AC_MASK);
  65234. +
  65235. + free_irq(client->irq, data);
  65236. + input_unregister_polled_device(data->poll_dev);
  65237. + input_free_polled_device(data->poll_dev);
  65238. + hwmon_device_unregister(data->hwmon_dev);
  65239. + sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
  65240. + kfree(data);
  65241. + mag3110_pdata = NULL;
  65242. +
  65243. + return ret;
  65244. +}
  65245. +
  65246. +#ifdef CONFIG_PM
  65247. +static int mag3110_suspend(struct i2c_client *client, pm_message_t mesg)
  65248. +{
  65249. + int ret = 0;
  65250. + struct mag3110_data *data = i2c_get_clientdata(client);
  65251. + if (data->active == MAG_ACTIVED) {
  65252. + data->ctl_reg1 = mag3110_read_reg(client, MAG3110_CTRL_REG1);
  65253. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  65254. + data->ctl_reg1 & ~MAG3110_AC_MASK);
  65255. + }
  65256. + return ret;
  65257. +}
  65258. +
  65259. +static int mag3110_resume(struct i2c_client *client)
  65260. +{
  65261. + int ret = 0;
  65262. + u8 tmp_data[MAG3110_XYZ_DATA_LEN];
  65263. + struct mag3110_data *data = i2c_get_clientdata(client);
  65264. + if (data->active == MAG_ACTIVED) {
  65265. + ret = mag3110_write_reg(client, MAG3110_CTRL_REG1,
  65266. + data->ctl_reg1);
  65267. +
  65268. + if (data->ctl_reg1 & MAG3110_AC_MASK) {
  65269. + /* Read out MSB data to clear interrupt
  65270. + flag automatically */
  65271. + mag3110_read_block_data(client, MAG3110_OUT_X_MSB,
  65272. + MAG3110_XYZ_DATA_LEN, tmp_data);
  65273. + }
  65274. + }
  65275. + return ret;
  65276. +}
  65277. +
  65278. +#else
  65279. +#define mag3110_suspend NULL
  65280. +#define mag3110_resume NULL
  65281. +#endif /* CONFIG_PM */
  65282. +
  65283. +static const struct i2c_device_id mag3110_id[] = {
  65284. + {MAG3110_DRV_NAME, 0},
  65285. + {}
  65286. +};
  65287. +
  65288. +MODULE_DEVICE_TABLE(i2c, mag3110_id);
  65289. +static struct i2c_driver mag3110_driver = {
  65290. + .driver = {.name = MAG3110_DRV_NAME,
  65291. + .owner = THIS_MODULE,},
  65292. + .suspend = mag3110_suspend,
  65293. + .resume = mag3110_resume,
  65294. + .probe = mag3110_probe,
  65295. + .remove = mag3110_remove,
  65296. + .id_table = mag3110_id,
  65297. +};
  65298. +
  65299. +static int __init mag3110_init(void)
  65300. +{
  65301. + return i2c_add_driver(&mag3110_driver);
  65302. +}
  65303. +
  65304. +static void __exit mag3110_exit(void)
  65305. +{
  65306. + i2c_del_driver(&mag3110_driver);
  65307. +}
  65308. +
  65309. +module_init(mag3110_init);
  65310. +module_exit(mag3110_exit);
  65311. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  65312. +MODULE_DESCRIPTION("Freescale mag3110 3-axis magnetometer driver");
  65313. +MODULE_LICENSE("GPL");
  65314. diff -Nur linux-3.14.17/drivers/hwmon/Makefile linux-imx6-3.14/drivers/hwmon/Makefile
  65315. --- linux-3.14.17/drivers/hwmon/Makefile 2014-08-14 03:38:34.000000000 +0200
  65316. +++ linux-imx6-3.14/drivers/hwmon/Makefile 2014-09-11 18:06:01.102034382 +0200
  65317. @@ -142,6 +142,8 @@
  65318. obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
  65319. obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
  65320. obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
  65321. +obj-$(CONFIG_SENSORS_MAG3110) += mag3110.o
  65322. +obj-$(CONFIG_MXC_MMA8451) += mxc_mma8451.o
  65323. obj-$(CONFIG_PMBUS) += pmbus/
  65324. diff -Nur linux-3.14.17/drivers/hwmon/mxc_mma8451.c linux-imx6-3.14/drivers/hwmon/mxc_mma8451.c
  65325. --- linux-3.14.17/drivers/hwmon/mxc_mma8451.c 1970-01-01 01:00:00.000000000 +0100
  65326. +++ linux-imx6-3.14/drivers/hwmon/mxc_mma8451.c 2014-09-11 18:06:01.178034686 +0200
  65327. @@ -0,0 +1,598 @@
  65328. +/*
  65329. + * mma8451.c - Linux kernel modules for 3-Axis Orientation/Motion
  65330. + * Detection Sensor
  65331. + *
  65332. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  65333. + *
  65334. + * This program is free software; you can redistribute it and/or modify
  65335. + * it under the terms of the GNU General Public License as published by
  65336. + * the Free Software Foundation; either version 2 of the License, or
  65337. + * (at your option) any later version.
  65338. + *
  65339. + * This program is distributed in the hope that it will be useful,
  65340. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  65341. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  65342. + * GNU General Public License for more details.
  65343. + *
  65344. + * You should have received a copy of the GNU General Public License
  65345. + * along with this program; if not, write to the Free Software
  65346. + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  65347. + */
  65348. +
  65349. +#include <linux/module.h>
  65350. +#include <linux/init.h>
  65351. +#include <linux/slab.h>
  65352. +#include <linux/i2c.h>
  65353. +#include <linux/pm.h>
  65354. +#include <linux/mutex.h>
  65355. +#include <linux/delay.h>
  65356. +#include <linux/interrupt.h>
  65357. +#include <linux/irq.h>
  65358. +#include <linux/hwmon-sysfs.h>
  65359. +#include <linux/err.h>
  65360. +#include <linux/hwmon.h>
  65361. +#include <linux/input-polldev.h>
  65362. +#include <linux/of.h>
  65363. +#include <linux/regulator/consumer.h>
  65364. +
  65365. +#define MMA8451_I2C_ADDR 0x1C
  65366. +#define MMA8451_ID 0x1A
  65367. +#define MMA8452_ID 0x2A
  65368. +#define MMA8453_ID 0x3A
  65369. +
  65370. +#define POLL_INTERVAL_MIN 1
  65371. +#define POLL_INTERVAL_MAX 500
  65372. +#define POLL_INTERVAL 100 /* msecs */
  65373. +#define INPUT_FUZZ 32
  65374. +#define INPUT_FLAT 32
  65375. +#define MODE_CHANGE_DELAY_MS 100
  65376. +
  65377. +#define MMA8451_STATUS_ZYXDR 0x08
  65378. +#define MMA8451_BUF_SIZE 7
  65379. +#define DEFAULT_POSITION 0
  65380. +
  65381. +/* register enum for mma8451 registers */
  65382. +enum {
  65383. + MMA8451_STATUS = 0x00,
  65384. + MMA8451_OUT_X_MSB,
  65385. + MMA8451_OUT_X_LSB,
  65386. + MMA8451_OUT_Y_MSB,
  65387. + MMA8451_OUT_Y_LSB,
  65388. + MMA8451_OUT_Z_MSB,
  65389. + MMA8451_OUT_Z_LSB,
  65390. +
  65391. + MMA8451_F_SETUP = 0x09,
  65392. + MMA8451_TRIG_CFG,
  65393. + MMA8451_SYSMOD,
  65394. + MMA8451_INT_SOURCE,
  65395. + MMA8451_WHO_AM_I,
  65396. + MMA8451_XYZ_DATA_CFG,
  65397. + MMA8451_HP_FILTER_CUTOFF,
  65398. +
  65399. + MMA8451_PL_STATUS,
  65400. + MMA8451_PL_CFG,
  65401. + MMA8451_PL_COUNT,
  65402. + MMA8451_PL_BF_ZCOMP,
  65403. + MMA8451_P_L_THS_REG,
  65404. +
  65405. + MMA8451_FF_MT_CFG,
  65406. + MMA8451_FF_MT_SRC,
  65407. + MMA8451_FF_MT_THS,
  65408. + MMA8451_FF_MT_COUNT,
  65409. +
  65410. + MMA8451_TRANSIENT_CFG = 0x1D,
  65411. + MMA8451_TRANSIENT_SRC,
  65412. + MMA8451_TRANSIENT_THS,
  65413. + MMA8451_TRANSIENT_COUNT,
  65414. +
  65415. + MMA8451_PULSE_CFG,
  65416. + MMA8451_PULSE_SRC,
  65417. + MMA8451_PULSE_THSX,
  65418. + MMA8451_PULSE_THSY,
  65419. + MMA8451_PULSE_THSZ,
  65420. + MMA8451_PULSE_TMLT,
  65421. + MMA8451_PULSE_LTCY,
  65422. + MMA8451_PULSE_WIND,
  65423. +
  65424. + MMA8451_ASLP_COUNT,
  65425. + MMA8451_CTRL_REG1,
  65426. + MMA8451_CTRL_REG2,
  65427. + MMA8451_CTRL_REG3,
  65428. + MMA8451_CTRL_REG4,
  65429. + MMA8451_CTRL_REG5,
  65430. +
  65431. + MMA8451_OFF_X,
  65432. + MMA8451_OFF_Y,
  65433. + MMA8451_OFF_Z,
  65434. +
  65435. + MMA8451_REG_END,
  65436. +};
  65437. +
  65438. +/* The sensitivity is represented in counts/g. In 2g mode the
  65439. +sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
  65440. +counts/g and in 8g mode the sensitivity is 256 counts/g.
  65441. + */
  65442. +enum {
  65443. + MODE_2G = 0,
  65444. + MODE_4G,
  65445. + MODE_8G,
  65446. +};
  65447. +
  65448. +enum {
  65449. + MMA_STANDBY = 0,
  65450. + MMA_ACTIVED,
  65451. +};
  65452. +
  65453. +/* mma8451 status */
  65454. +struct mma8451_status {
  65455. + u8 mode;
  65456. + u8 ctl_reg1;
  65457. + int active;
  65458. + int position;
  65459. +};
  65460. +
  65461. +static struct mma8451_status mma_status;
  65462. +static struct input_polled_dev *mma8451_idev;
  65463. +static struct device *hwmon_dev;
  65464. +static struct i2c_client *mma8451_i2c_client;
  65465. +
  65466. +static int senstive_mode = MODE_2G;
  65467. +static int ACCHAL[8][3][3] = {
  65468. + { {0, -1, 0}, {1, 0, 0}, {0, 0, 1} },
  65469. + { {-1, 0, 0}, {0, -1, 0}, {0, 0, 1} },
  65470. + { {0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
  65471. + { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} },
  65472. +
  65473. + { {0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
  65474. + { {-1, 0, 0}, {0, 1, 0}, {0, 0, -1} },
  65475. + { {0, 1, 0}, {1, 0, 0}, {0, 0, -1} },
  65476. + { {1, 0, 0}, {0, -1, 0}, {0, 0, -1} },
  65477. +};
  65478. +
  65479. +static DEFINE_MUTEX(mma8451_lock);
  65480. +static int mma8451_adjust_position(short *x, short *y, short *z)
  65481. +{
  65482. + short rawdata[3], data[3];
  65483. + int i, j;
  65484. + int position = mma_status.position;
  65485. + if (position < 0 || position > 7)
  65486. + position = 0;
  65487. + rawdata[0] = *x;
  65488. + rawdata[1] = *y;
  65489. + rawdata[2] = *z;
  65490. + for (i = 0; i < 3; i++) {
  65491. + data[i] = 0;
  65492. + for (j = 0; j < 3; j++)
  65493. + data[i] += rawdata[j] * ACCHAL[position][i][j];
  65494. + }
  65495. + *x = data[0];
  65496. + *y = data[1];
  65497. + *z = data[2];
  65498. + return 0;
  65499. +}
  65500. +
  65501. +static int mma8451_change_mode(struct i2c_client *client, int mode)
  65502. +{
  65503. + int result;
  65504. +
  65505. + mma_status.ctl_reg1 = 0;
  65506. + result = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 0);
  65507. + if (result < 0)
  65508. + goto out;
  65509. + mma_status.active = MMA_STANDBY;
  65510. +
  65511. + result = i2c_smbus_write_byte_data(client, MMA8451_XYZ_DATA_CFG,
  65512. + mode);
  65513. + if (result < 0)
  65514. + goto out;
  65515. + mdelay(MODE_CHANGE_DELAY_MS);
  65516. + mma_status.mode = mode;
  65517. +
  65518. + return 0;
  65519. +out:
  65520. + dev_err(&client->dev, "error when init mma8451:(%d)", result);
  65521. + return result;
  65522. +}
  65523. +
  65524. +static int mma8451_read_data(short *x, short *y, short *z)
  65525. +{
  65526. + u8 tmp_data[MMA8451_BUF_SIZE];
  65527. + int ret;
  65528. +
  65529. + ret = i2c_smbus_read_i2c_block_data(mma8451_i2c_client,
  65530. + MMA8451_OUT_X_MSB, 7, tmp_data);
  65531. + if (ret < MMA8451_BUF_SIZE) {
  65532. + dev_err(&mma8451_i2c_client->dev, "i2c block read failed\n");
  65533. + return -EIO;
  65534. + }
  65535. +
  65536. + *x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
  65537. + *y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
  65538. + *z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
  65539. + return 0;
  65540. +}
  65541. +
  65542. +static void report_abs(void)
  65543. +{
  65544. + short x, y, z;
  65545. + int result;
  65546. + int retry = 3;
  65547. +
  65548. + mutex_lock(&mma8451_lock);
  65549. + if (mma_status.active == MMA_STANDBY)
  65550. + goto out;
  65551. + /* wait for the data ready */
  65552. + do {
  65553. + result = i2c_smbus_read_byte_data(mma8451_i2c_client,
  65554. + MMA8451_STATUS);
  65555. + retry--;
  65556. + msleep(1);
  65557. + } while (!(result & MMA8451_STATUS_ZYXDR) && retry > 0);
  65558. + if (retry == 0)
  65559. + goto out;
  65560. + if (mma8451_read_data(&x, &y, &z) != 0)
  65561. + goto out;
  65562. + mma8451_adjust_position(&x, &y, &z);
  65563. + input_report_abs(mma8451_idev->input, ABS_X, x);
  65564. + input_report_abs(mma8451_idev->input, ABS_Y, y);
  65565. + input_report_abs(mma8451_idev->input, ABS_Z, z);
  65566. + input_sync(mma8451_idev->input);
  65567. +out:
  65568. + mutex_unlock(&mma8451_lock);
  65569. +}
  65570. +
  65571. +static void mma8451_dev_poll(struct input_polled_dev *dev)
  65572. +{
  65573. + report_abs();
  65574. +}
  65575. +
  65576. +static ssize_t mma8451_enable_show(struct device *dev,
  65577. + struct device_attribute *attr, char *buf)
  65578. +{
  65579. + struct i2c_client *client;
  65580. + u8 val;
  65581. + int enable;
  65582. +
  65583. + mutex_lock(&mma8451_lock);
  65584. + client = mma8451_i2c_client;
  65585. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  65586. + if ((val & 0x01) && mma_status.active == MMA_ACTIVED)
  65587. + enable = 1;
  65588. + else
  65589. + enable = 0;
  65590. + mutex_unlock(&mma8451_lock);
  65591. + return sprintf(buf, "%d\n", enable);
  65592. +}
  65593. +
  65594. +static ssize_t mma8451_enable_store(struct device *dev,
  65595. + struct device_attribute *attr,
  65596. + const char *buf, size_t count)
  65597. +{
  65598. + struct i2c_client *client;
  65599. + int ret;
  65600. + unsigned long enable;
  65601. + u8 val = 0;
  65602. +
  65603. + ret = strict_strtoul(buf, 10, &enable);
  65604. + if (ret) {
  65605. + dev_err(dev, "string transform error\n");
  65606. + return ret;
  65607. + }
  65608. +
  65609. + mutex_lock(&mma8451_lock);
  65610. + client = mma8451_i2c_client;
  65611. + enable = (enable > 0) ? 1 : 0;
  65612. + if (enable && mma_status.active == MMA_STANDBY) {
  65613. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  65614. + ret =
  65615. + i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  65616. + val | 0x01);
  65617. + if (!ret)
  65618. + mma_status.active = MMA_ACTIVED;
  65619. +
  65620. + } else if (enable == 0 && mma_status.active == MMA_ACTIVED) {
  65621. + val = i2c_smbus_read_byte_data(client, MMA8451_CTRL_REG1);
  65622. + ret =
  65623. + i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  65624. + val & 0xFE);
  65625. + if (!ret)
  65626. + mma_status.active = MMA_STANDBY;
  65627. +
  65628. + }
  65629. + mutex_unlock(&mma8451_lock);
  65630. + return count;
  65631. +}
  65632. +
  65633. +static ssize_t mma8451_position_show(struct device *dev,
  65634. + struct device_attribute *attr, char *buf)
  65635. +{
  65636. + int position = 0;
  65637. + mutex_lock(&mma8451_lock);
  65638. + position = mma_status.position;
  65639. + mutex_unlock(&mma8451_lock);
  65640. + return sprintf(buf, "%d\n", position);
  65641. +}
  65642. +
  65643. +static ssize_t mma8451_position_store(struct device *dev,
  65644. + struct device_attribute *attr,
  65645. + const char *buf, size_t count)
  65646. +{
  65647. + unsigned long position;
  65648. + int ret;
  65649. + ret = strict_strtoul(buf, 10, &position);
  65650. + if (ret) {
  65651. + dev_err(dev, "string transform error\n");
  65652. + return ret;
  65653. + }
  65654. +
  65655. + mutex_lock(&mma8451_lock);
  65656. + mma_status.position = (int)position;
  65657. + mutex_unlock(&mma8451_lock);
  65658. + return count;
  65659. +}
  65660. +
  65661. +static ssize_t mma8451_scalemode_show(struct device *dev,
  65662. + struct device_attribute *attr,
  65663. + char *buf)
  65664. +{
  65665. + int mode = 0;
  65666. + mutex_lock(&mma8451_lock);
  65667. + mode = (int)mma_status.mode;
  65668. + mutex_unlock(&mma8451_lock);
  65669. +
  65670. + return sprintf(buf, "%d\n", mode);
  65671. +}
  65672. +
  65673. +static ssize_t mma8451_scalemode_store(struct device *dev,
  65674. + struct device_attribute *attr,
  65675. + const char *buf, size_t count)
  65676. +{
  65677. + unsigned long mode;
  65678. + int ret, active_save;
  65679. + struct i2c_client *client = mma8451_i2c_client;
  65680. +
  65681. + ret = strict_strtoul(buf, 10, &mode);
  65682. + if (ret) {
  65683. + dev_err(dev, "string transform error\n");
  65684. + goto out;
  65685. + }
  65686. +
  65687. + if (mode > MODE_8G) {
  65688. + dev_warn(dev, "not supported mode\n");
  65689. + ret = count;
  65690. + goto out;
  65691. + }
  65692. +
  65693. + mutex_lock(&mma8451_lock);
  65694. + if (mode == mma_status.mode) {
  65695. + ret = count;
  65696. + goto out_unlock;
  65697. + }
  65698. +
  65699. + active_save = mma_status.active;
  65700. + ret = mma8451_change_mode(client, mode);
  65701. + if (ret)
  65702. + goto out_unlock;
  65703. +
  65704. + if (active_save == MMA_ACTIVED) {
  65705. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1, 1);
  65706. +
  65707. + if (ret)
  65708. + goto out_unlock;
  65709. + mma_status.active = active_save;
  65710. + }
  65711. +
  65712. +out_unlock:
  65713. + mutex_unlock(&mma8451_lock);
  65714. +out:
  65715. + return ret;
  65716. +}
  65717. +
  65718. +static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
  65719. + mma8451_enable_show, mma8451_enable_store);
  65720. +static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
  65721. + mma8451_position_show, mma8451_position_store);
  65722. +static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
  65723. + mma8451_scalemode_show, mma8451_scalemode_store);
  65724. +
  65725. +static struct attribute *mma8451_attributes[] = {
  65726. + &dev_attr_enable.attr,
  65727. + &dev_attr_position.attr,
  65728. + &dev_attr_scalemode.attr,
  65729. + NULL
  65730. +};
  65731. +
  65732. +static const struct attribute_group mma8451_attr_group = {
  65733. + .attrs = mma8451_attributes,
  65734. +};
  65735. +
  65736. +static int mma8451_probe(struct i2c_client *client,
  65737. + const struct i2c_device_id *id)
  65738. +{
  65739. + int result, client_id;
  65740. + struct input_dev *idev;
  65741. + struct i2c_adapter *adapter;
  65742. + u32 pos;
  65743. + struct device_node *of_node = client->dev.of_node;
  65744. + struct regulator *vdd, *vdd_io;
  65745. +
  65746. + mma8451_i2c_client = client;
  65747. +
  65748. + vdd = devm_regulator_get(&client->dev, "vdd");
  65749. + if (!IS_ERR(vdd)) {
  65750. + result = regulator_enable(vdd);
  65751. + if (result) {
  65752. + dev_err(&client->dev, "vdd set voltage error\n");
  65753. + return result;
  65754. + }
  65755. + }
  65756. +
  65757. + vdd_io = devm_regulator_get(&client->dev, "vddio");
  65758. + if (!IS_ERR(vdd_io)) {
  65759. + result = regulator_enable(vdd_io);
  65760. + if (result) {
  65761. + dev_err(&client->dev, "vddio set voltage error\n");
  65762. + return result;
  65763. + }
  65764. + }
  65765. +
  65766. + adapter = to_i2c_adapter(client->dev.parent);
  65767. + result = i2c_check_functionality(adapter,
  65768. + I2C_FUNC_SMBUS_BYTE |
  65769. + I2C_FUNC_SMBUS_BYTE_DATA);
  65770. + if (!result)
  65771. + goto err_out;
  65772. +
  65773. + client_id = i2c_smbus_read_byte_data(client, MMA8451_WHO_AM_I);
  65774. + if (client_id != MMA8451_ID && client_id != MMA8452_ID
  65775. + && client_id != MMA8453_ID) {
  65776. + dev_err(&client->dev,
  65777. + "read chip ID 0x%x is not equal to 0x%x or 0x%x!\n",
  65778. + result, MMA8451_ID, MMA8452_ID);
  65779. + result = -EINVAL;
  65780. + goto err_out;
  65781. + }
  65782. +
  65783. + /* Initialize the MMA8451 chip */
  65784. + result = mma8451_change_mode(client, senstive_mode);
  65785. + if (result) {
  65786. + dev_err(&client->dev,
  65787. + "error when init mma8451 chip:(%d)\n", result);
  65788. + goto err_out;
  65789. + }
  65790. +
  65791. + hwmon_dev = hwmon_device_register(&client->dev);
  65792. + if (!hwmon_dev) {
  65793. + result = -ENOMEM;
  65794. + dev_err(&client->dev, "error when register hwmon device\n");
  65795. + goto err_out;
  65796. + }
  65797. +
  65798. + mma8451_idev = input_allocate_polled_device();
  65799. + if (!mma8451_idev) {
  65800. + result = -ENOMEM;
  65801. + dev_err(&client->dev, "alloc poll device failed!\n");
  65802. + goto err_alloc_poll_device;
  65803. + }
  65804. + mma8451_idev->poll = mma8451_dev_poll;
  65805. + mma8451_idev->poll_interval = POLL_INTERVAL;
  65806. + mma8451_idev->poll_interval_min = POLL_INTERVAL_MIN;
  65807. + mma8451_idev->poll_interval_max = POLL_INTERVAL_MAX;
  65808. + idev = mma8451_idev->input;
  65809. + idev->name = "mma845x";
  65810. + idev->id.bustype = BUS_I2C;
  65811. + idev->evbit[0] = BIT_MASK(EV_ABS);
  65812. +
  65813. + input_set_abs_params(idev, ABS_X, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  65814. + input_set_abs_params(idev, ABS_Y, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  65815. + input_set_abs_params(idev, ABS_Z, -8192, 8191, INPUT_FUZZ, INPUT_FLAT);
  65816. +
  65817. + result = input_register_polled_device(mma8451_idev);
  65818. + if (result) {
  65819. + dev_err(&client->dev, "register poll device failed!\n");
  65820. + goto err_register_polled_device;
  65821. + }
  65822. + result = sysfs_create_group(&idev->dev.kobj, &mma8451_attr_group);
  65823. + if (result) {
  65824. + dev_err(&client->dev, "create device file failed!\n");
  65825. + result = -EINVAL;
  65826. + goto err_register_polled_device;
  65827. + }
  65828. +
  65829. + result = of_property_read_u32(of_node, "position", &pos);
  65830. + if (result)
  65831. + pos = DEFAULT_POSITION;
  65832. + mma_status.position = (int)pos;
  65833. +
  65834. + return 0;
  65835. +err_register_polled_device:
  65836. + input_free_polled_device(mma8451_idev);
  65837. +err_alloc_poll_device:
  65838. + hwmon_device_unregister(&client->dev);
  65839. +err_out:
  65840. + return result;
  65841. +}
  65842. +
  65843. +static int mma8451_stop_chip(struct i2c_client *client)
  65844. +{
  65845. + int ret = 0;
  65846. + if (mma_status.active == MMA_ACTIVED) {
  65847. + mma_status.ctl_reg1 = i2c_smbus_read_byte_data(client,
  65848. + MMA8451_CTRL_REG1);
  65849. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  65850. + mma_status.ctl_reg1 & 0xFE);
  65851. + }
  65852. + return ret;
  65853. +}
  65854. +
  65855. +static int mma8451_remove(struct i2c_client *client)
  65856. +{
  65857. + int ret;
  65858. + ret = mma8451_stop_chip(client);
  65859. + hwmon_device_unregister(hwmon_dev);
  65860. +
  65861. + return ret;
  65862. +}
  65863. +
  65864. +#ifdef CONFIG_PM_SLEEP
  65865. +static int mma8451_suspend(struct device *dev)
  65866. +{
  65867. + struct i2c_client *client = to_i2c_client(dev);
  65868. +
  65869. + return mma8451_stop_chip(client);
  65870. +}
  65871. +
  65872. +static int mma8451_resume(struct device *dev)
  65873. +{
  65874. + int ret = 0;
  65875. + struct i2c_client *client = to_i2c_client(dev);
  65876. + if (mma_status.active == MMA_ACTIVED)
  65877. + ret = i2c_smbus_write_byte_data(client, MMA8451_CTRL_REG1,
  65878. + mma_status.ctl_reg1);
  65879. + return ret;
  65880. +
  65881. +}
  65882. +#endif
  65883. +
  65884. +static const struct i2c_device_id mma8451_id[] = {
  65885. + {"mma8451", 0},
  65886. +};
  65887. +
  65888. +MODULE_DEVICE_TABLE(i2c, mma8451_id);
  65889. +
  65890. +static SIMPLE_DEV_PM_OPS(mma8451_pm_ops, mma8451_suspend, mma8451_resume);
  65891. +static struct i2c_driver mma8451_driver = {
  65892. + .driver = {
  65893. + .name = "mma8451",
  65894. + .owner = THIS_MODULE,
  65895. + .pm = &mma8451_pm_ops,
  65896. + },
  65897. + .probe = mma8451_probe,
  65898. + .remove = mma8451_remove,
  65899. + .id_table = mma8451_id,
  65900. +};
  65901. +
  65902. +static int __init mma8451_init(void)
  65903. +{
  65904. + /* register driver */
  65905. + int res;
  65906. +
  65907. + res = i2c_add_driver(&mma8451_driver);
  65908. + if (res < 0) {
  65909. + printk(KERN_INFO "add mma8451 i2c driver failed\n");
  65910. + return -ENODEV;
  65911. + }
  65912. + return res;
  65913. +}
  65914. +
  65915. +static void __exit mma8451_exit(void)
  65916. +{
  65917. + i2c_del_driver(&mma8451_driver);
  65918. +}
  65919. +
  65920. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  65921. +MODULE_DESCRIPTION("MMA8451 3-Axis Orientation/Motion Detection Sensor driver");
  65922. +MODULE_LICENSE("GPL");
  65923. +
  65924. +module_init(mma8451_init);
  65925. +module_exit(mma8451_exit);
  65926. diff -Nur linux-3.14.17/drivers/hwmon/smsc47m192.c linux-imx6-3.14/drivers/hwmon/smsc47m192.c
  65927. --- linux-3.14.17/drivers/hwmon/smsc47m192.c 2014-08-14 03:38:34.000000000 +0200
  65928. +++ linux-imx6-3.14/drivers/hwmon/smsc47m192.c 2014-09-11 18:06:01.198034765 +0200
  65929. @@ -86,7 +86,7 @@
  65930. */
  65931. static inline s8 TEMP_TO_REG(int val)
  65932. {
  65933. - return SCALE(clamp_val(val, -128000, 127000), 1, 1000);
  65934. + return clamp_val(SCALE(val, 1, 1000), -128000, 127000);
  65935. }
  65936. static inline int TEMP_FROM_REG(s8 val)
  65937. @@ -384,8 +384,6 @@
  65938. err = kstrtoul(buf, 10, &val);
  65939. if (err)
  65940. return err;
  65941. - if (val > 255)
  65942. - return -EINVAL;
  65943. data->vrm = val;
  65944. return count;
  65945. diff -Nur linux-3.14.17/drivers/i2c/busses/i2c-imx.c linux-imx6-3.14/drivers/i2c/busses/i2c-imx.c
  65946. --- linux-3.14.17/drivers/i2c/busses/i2c-imx.c 2014-08-14 03:38:34.000000000 +0200
  65947. +++ linux-imx6-3.14/drivers/i2c/busses/i2c-imx.c 2014-09-11 18:06:01.214034829 +0200
  65948. @@ -184,6 +184,9 @@
  65949. int stopped;
  65950. unsigned int ifdr; /* IMX_I2C_IFDR */
  65951. const struct imx_i2c_hwdata *hwdata;
  65952. +
  65953. + unsigned int cur_clk;
  65954. + unsigned int bitrate;
  65955. };
  65956. static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
  65957. @@ -305,6 +308,51 @@
  65958. return 0;
  65959. }
  65960. +static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx)
  65961. +{
  65962. + struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
  65963. + unsigned ndivs = i2c_imx->hwdata->ndivs;
  65964. + unsigned int i2c_clk_rate;
  65965. + unsigned int div;
  65966. + int i;
  65967. +
  65968. + /* Divider value calculation */
  65969. + i2c_clk_rate = clk_get_rate(i2c_imx->clk);
  65970. + if (i2c_imx->cur_clk == i2c_clk_rate)
  65971. + return;
  65972. + else
  65973. + i2c_imx->cur_clk = i2c_clk_rate;
  65974. +
  65975. + div = (i2c_clk_rate + i2c_imx->bitrate - 1) / i2c_imx->bitrate;
  65976. + if (div < i2c_clk_div[0].div)
  65977. + i = 0;
  65978. + else if (div > i2c_clk_div[ndivs - 1].div)
  65979. + i = ndivs - 1;
  65980. + else
  65981. + for (i = 0; i2c_clk_div[i].div < div; i++)
  65982. + ;
  65983. +
  65984. + /* Store divider value */
  65985. + i2c_imx->ifdr = imx_i2c_clk_div[i].val;
  65986. +
  65987. + /*
  65988. + * There dummy delay is calculated.
  65989. + * It should be about one I2C clock period long.
  65990. + * This delay is used in I2C bus disable function
  65991. + * to fix chip hardware bug.
  65992. + */
  65993. + i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
  65994. + + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
  65995. +
  65996. + /* dev_dbg() can't be used, because adapter is not yet registered */
  65997. +#ifdef CONFIG_I2C_DEBUG_BUS
  65998. + dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
  65999. + __func__, i2c_clk_rate, div);
  66000. + dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
  66001. + __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
  66002. +#endif
  66003. +}
  66004. +
  66005. static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
  66006. {
  66007. unsigned int temp = 0;
  66008. @@ -312,6 +360,7 @@
  66009. dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
  66010. + i2c_imx_set_clk(i2c_imx);
  66011. result = clk_prepare_enable(i2c_imx->clk);
  66012. if (result)
  66013. return result;
  66014. @@ -367,45 +416,6 @@
  66015. clk_disable_unprepare(i2c_imx->clk);
  66016. }
  66017. -static void i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
  66018. - unsigned int rate)
  66019. -{
  66020. - struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
  66021. - unsigned int i2c_clk_rate;
  66022. - unsigned int div;
  66023. - int i;
  66024. -
  66025. - /* Divider value calculation */
  66026. - i2c_clk_rate = clk_get_rate(i2c_imx->clk);
  66027. - div = (i2c_clk_rate + rate - 1) / rate;
  66028. - if (div < i2c_clk_div[0].div)
  66029. - i = 0;
  66030. - else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div)
  66031. - i = i2c_imx->hwdata->ndivs - 1;
  66032. - else
  66033. - for (i = 0; i2c_clk_div[i].div < div; i++);
  66034. -
  66035. - /* Store divider value */
  66036. - i2c_imx->ifdr = i2c_clk_div[i].val;
  66037. -
  66038. - /*
  66039. - * There dummy delay is calculated.
  66040. - * It should be about one I2C clock period long.
  66041. - * This delay is used in I2C bus disable function
  66042. - * to fix chip hardware bug.
  66043. - */
  66044. - i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
  66045. - + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
  66046. -
  66047. - /* dev_dbg() can't be used, because adapter is not yet registered */
  66048. -#ifdef CONFIG_I2C_DEBUG_BUS
  66049. - dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
  66050. - __func__, i2c_clk_rate, div);
  66051. - dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
  66052. - __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
  66053. -#endif
  66054. -}
  66055. -
  66056. static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
  66057. {
  66058. struct imx_i2c_struct *i2c_imx = dev_id;
  66059. @@ -600,7 +610,6 @@
  66060. struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
  66061. void __iomem *base;
  66062. int irq, ret;
  66063. - u32 bitrate;
  66064. dev_dbg(&pdev->dev, "<%s>\n", __func__);
  66065. @@ -664,12 +673,12 @@
  66066. i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);
  66067. /* Set up clock divider */
  66068. - bitrate = IMX_I2C_BIT_RATE;
  66069. + i2c_imx->bitrate = IMX_I2C_BIT_RATE;
  66070. ret = of_property_read_u32(pdev->dev.of_node,
  66071. - "clock-frequency", &bitrate);
  66072. + "clock-frequency", &i2c_imx->bitrate);
  66073. if (ret < 0 && pdata && pdata->bitrate)
  66074. - bitrate = pdata->bitrate;
  66075. - i2c_imx_set_clk(i2c_imx, bitrate);
  66076. + i2c_imx->bitrate = pdata->bitrate;
  66077. + i2c_imx_set_clk(i2c_imx);
  66078. /* Set up chip registers to defaults */
  66079. imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
  66080. diff -Nur linux-3.14.17/drivers/iio/accel/bma180.c linux-imx6-3.14/drivers/iio/accel/bma180.c
  66081. --- linux-3.14.17/drivers/iio/accel/bma180.c 2014-08-14 03:38:34.000000000 +0200
  66082. +++ linux-imx6-3.14/drivers/iio/accel/bma180.c 2014-09-11 18:06:01.246034957 +0200
  66083. @@ -68,13 +68,13 @@
  66084. /* Defaults values */
  66085. #define BMA180_DEF_PMODE 0
  66086. #define BMA180_DEF_BW 20
  66087. -#define BMA180_DEF_SCALE 2452
  66088. +#define BMA180_DEF_SCALE 250
  66089. /* Available values for sysfs */
  66090. #define BMA180_FLP_FREQ_AVAILABLE \
  66091. "10 20 40 75 150 300"
  66092. #define BMA180_SCALE_AVAILABLE \
  66093. - "0.001275 0.001863 0.002452 0.003727 0.004903 0.009709 0.019417"
  66094. + "0.000130 0.000190 0.000250 0.000380 0.000500 0.000990 0.001980"
  66095. struct bma180_data {
  66096. struct i2c_client *client;
  66097. @@ -94,7 +94,7 @@
  66098. };
  66099. static int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
  66100. -static int scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
  66101. +static int scale_table[] = { 130, 190, 250, 380, 500, 990, 1980 };
  66102. static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
  66103. {
  66104. @@ -376,8 +376,6 @@
  66105. mutex_unlock(&data->mutex);
  66106. return ret;
  66107. case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
  66108. - if (val2)
  66109. - return -EINVAL;
  66110. mutex_lock(&data->mutex);
  66111. ret = bma180_set_bw(data, val);
  66112. mutex_unlock(&data->mutex);
  66113. diff -Nur linux-3.14.17/drivers/iio/industrialio-buffer.c linux-imx6-3.14/drivers/iio/industrialio-buffer.c
  66114. --- linux-3.14.17/drivers/iio/industrialio-buffer.c 2014-08-14 03:38:34.000000000 +0200
  66115. +++ linux-imx6-3.14/drivers/iio/industrialio-buffer.c 2014-09-11 18:06:01.286035116 +0200
  66116. @@ -953,7 +953,7 @@
  66117. /* Now we have the two masks, work from least sig and build up sizes */
  66118. for_each_set_bit(out_ind,
  66119. - buffer->scan_mask,
  66120. + indio_dev->active_scan_mask,
  66121. indio_dev->masklength) {
  66122. in_ind = find_next_bit(indio_dev->active_scan_mask,
  66123. indio_dev->masklength,
  66124. diff -Nur linux-3.14.17/drivers/input/input.c linux-imx6-3.14/drivers/input/input.c
  66125. --- linux-3.14.17/drivers/input/input.c 2014-08-14 03:38:34.000000000 +0200
  66126. +++ linux-imx6-3.14/drivers/input/input.c 2014-09-11 18:06:01.434035708 +0200
  66127. @@ -257,10 +257,9 @@
  66128. }
  66129. static int input_get_disposition(struct input_dev *dev,
  66130. - unsigned int type, unsigned int code, int *pval)
  66131. + unsigned int type, unsigned int code, int value)
  66132. {
  66133. int disposition = INPUT_IGNORE_EVENT;
  66134. - int value = *pval;
  66135. switch (type) {
  66136. @@ -358,7 +357,6 @@
  66137. break;
  66138. }
  66139. - *pval = value;
  66140. return disposition;
  66141. }
  66142. @@ -367,7 +365,7 @@
  66143. {
  66144. int disposition;
  66145. - disposition = input_get_disposition(dev, type, code, &value);
  66146. + disposition = input_get_disposition(dev, type, code, value);
  66147. if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
  66148. dev->event(dev, type, code, value);
  66149. diff -Nur linux-3.14.17/drivers/input/keyboard/gpio_keys.c linux-imx6-3.14/drivers/input/keyboard/gpio_keys.c
  66150. --- linux-3.14.17/drivers/input/keyboard/gpio_keys.c 2014-08-14 03:38:34.000000000 +0200
  66151. +++ linux-imx6-3.14/drivers/input/keyboard/gpio_keys.c 2014-09-11 18:06:01.486035915 +0200
  66152. @@ -3,6 +3,7 @@
  66153. *
  66154. * Copyright 2005 Phil Blundell
  66155. * Copyright 2010, 2011 David Jander <david@protonic.nl>
  66156. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  66157. *
  66158. * This program is free software; you can redistribute it and/or modify
  66159. * it under the terms of the GNU General Public License version 2 as
  66160. @@ -473,6 +474,8 @@
  66161. isr = gpio_keys_gpio_isr;
  66162. irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
  66163. + if (bdata->button->wakeup)
  66164. + irqflags |= IRQF_NO_SUSPEND;
  66165. } else {
  66166. if (!button->irq) {
  66167. diff -Nur linux-3.14.17/drivers/input/keyboard/imx_keypad.c linux-imx6-3.14/drivers/input/keyboard/imx_keypad.c
  66168. --- linux-3.14.17/drivers/input/keyboard/imx_keypad.c 2014-08-14 03:38:34.000000000 +0200
  66169. +++ linux-imx6-3.14/drivers/input/keyboard/imx_keypad.c 2014-09-11 18:06:01.486035915 +0200
  66170. @@ -1,6 +1,7 @@
  66171. /*
  66172. * Driver for the IMX keypad port.
  66173. * Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
  66174. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  66175. *
  66176. * This program is free software; you can redistribute it and/or modify
  66177. * it under the terms of the GNU General Public License version 2 as
  66178. @@ -548,6 +549,8 @@
  66179. if (device_may_wakeup(&pdev->dev))
  66180. enable_irq_wake(kbd->irq);
  66181. + else
  66182. + pinctrl_pm_select_sleep_state(dev);
  66183. return 0;
  66184. }
  66185. @@ -561,6 +564,8 @@
  66186. if (device_may_wakeup(&pdev->dev))
  66187. disable_irq_wake(kbd->irq);
  66188. + else
  66189. + pinctrl_pm_select_default_state(dev);
  66190. mutex_lock(&input_dev->mutex);
  66191. diff -Nur linux-3.14.17/drivers/input/misc/mma8450.c linux-imx6-3.14/drivers/input/misc/mma8450.c
  66192. --- linux-3.14.17/drivers/input/misc/mma8450.c 2014-08-14 03:38:34.000000000 +0200
  66193. +++ linux-imx6-3.14/drivers/input/misc/mma8450.c 2014-09-11 18:06:01.498035963 +0200
  66194. @@ -1,7 +1,7 @@
  66195. /*
  66196. * Driver for Freescale's 3-Axis Accelerometer MMA8450
  66197. *
  66198. - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  66199. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  66200. *
  66201. * This program is free software; you can redistribute it and/or modify
  66202. * it under the terms of the GNU General Public License as published by
  66203. @@ -25,6 +25,7 @@
  66204. #include <linux/i2c.h>
  66205. #include <linux/input-polldev.h>
  66206. #include <linux/of_device.h>
  66207. +#include <linux/mutex.h>
  66208. #define MMA8450_DRV_NAME "mma8450"
  66209. @@ -51,11 +52,22 @@
  66210. #define MMA8450_CTRL_REG1 0x38
  66211. #define MMA8450_CTRL_REG2 0x39
  66212. +#define MMA8450_ID 0xC6
  66213. +#define MMA8450_WHO_AM_I 0x0F
  66214. +
  66215. +enum {
  66216. + MODE_STANDBY = 0,
  66217. + MODE_2G,
  66218. + MODE_4G,
  66219. + MODE_8G,
  66220. +};
  66221. /* mma8450 status */
  66222. struct mma8450 {
  66223. struct i2c_client *client;
  66224. struct input_polled_dev *idev;
  66225. + struct mutex mma8450_lock;
  66226. + u8 mode;
  66227. };
  66228. static int mma8450_read(struct mma8450 *m, unsigned off)
  66229. @@ -112,16 +124,19 @@
  66230. int ret;
  66231. u8 buf[6];
  66232. - ret = mma8450_read(m, MMA8450_STATUS);
  66233. - if (ret < 0)
  66234. - return;
  66235. + mutex_lock(&m->mma8450_lock);
  66236. - if (!(ret & MMA8450_STATUS_ZXYDR))
  66237. + ret = mma8450_read(m, MMA8450_STATUS);
  66238. + if (ret < 0 || !(ret & MMA8450_STATUS_ZXYDR)) {
  66239. + mutex_unlock(&m->mma8450_lock);
  66240. return;
  66241. + }
  66242. ret = mma8450_read_block(m, MMA8450_OUT_X_LSB, buf, sizeof(buf));
  66243. - if (ret < 0)
  66244. + if (ret < 0) {
  66245. + mutex_unlock(&m->mma8450_lock);
  66246. return;
  66247. + }
  66248. x = ((int)(s8)buf[1] << 4) | (buf[0] & 0xf);
  66249. y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
  66250. @@ -131,10 +146,12 @@
  66251. input_report_abs(dev->input, ABS_Y, y);
  66252. input_report_abs(dev->input, ABS_Z, z);
  66253. input_sync(dev->input);
  66254. +
  66255. + mutex_unlock(&m->mma8450_lock);
  66256. }
  66257. /* Initialize the MMA8450 chip */
  66258. -static void mma8450_open(struct input_polled_dev *dev)
  66259. +static s32 mma8450_open(struct input_polled_dev *dev)
  66260. {
  66261. struct mma8450 *m = dev->private;
  66262. int err;
  66263. @@ -142,18 +159,20 @@
  66264. /* enable all events from X/Y/Z, no FIFO */
  66265. err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07);
  66266. if (err)
  66267. - return;
  66268. + return err;
  66269. /*
  66270. * Sleep mode poll rate - 50Hz
  66271. * System output data rate - 400Hz
  66272. - * Full scale selection - Active, +/- 2G
  66273. + * Standby mode
  66274. */
  66275. - err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01);
  66276. - if (err < 0)
  66277. - return;
  66278. -
  66279. + err = mma8450_write(m, MMA8450_CTRL_REG1, MODE_STANDBY);
  66280. + if (err)
  66281. + return err;
  66282. + m->mode = MODE_STANDBY;
  66283. msleep(MODE_CHANGE_DELAY_MS);
  66284. +
  66285. + return 0;
  66286. }
  66287. static void mma8450_close(struct input_polled_dev *dev)
  66288. @@ -164,6 +183,76 @@
  66289. mma8450_write(m, MMA8450_CTRL_REG2, 0x01);
  66290. }
  66291. +static ssize_t mma8450_scalemode_show(struct device *dev,
  66292. + struct device_attribute *attr,
  66293. + char *buf)
  66294. +{
  66295. + int mode = 0;
  66296. + struct mma8450 *m;
  66297. + struct i2c_client *client = to_i2c_client(dev);
  66298. +
  66299. + m = i2c_get_clientdata(client);
  66300. +
  66301. + mutex_lock(&m->mma8450_lock);
  66302. + mode = (int)m->mode;
  66303. + mutex_unlock(&m->mma8450_lock);
  66304. +
  66305. + return sprintf(buf, "%d\n", mode);
  66306. +}
  66307. +
  66308. +static ssize_t mma8450_scalemode_store(struct device *dev,
  66309. + struct device_attribute *attr,
  66310. + const char *buf, size_t count)
  66311. +{
  66312. + unsigned long mode;
  66313. + int ret;
  66314. + struct mma8450 *m = NULL;
  66315. + struct i2c_client *client = to_i2c_client(dev);
  66316. +
  66317. + ret = strict_strtoul(buf, 10, &mode);
  66318. + if (ret) {
  66319. + dev_err(dev, "string transform error\n");
  66320. + return ret;
  66321. + }
  66322. +
  66323. + if (mode > MODE_8G) {
  66324. + dev_warn(dev, "not supported mode %d\n", (int)mode);
  66325. + return count;
  66326. + }
  66327. +
  66328. + m = i2c_get_clientdata(client);
  66329. +
  66330. + mutex_lock(&m->mma8450_lock);
  66331. + if (mode == m->mode) {
  66332. + mutex_unlock(&m->mma8450_lock);
  66333. + return count;
  66334. + }
  66335. +
  66336. + ret = mma8450_write(m, MMA8450_CTRL_REG1, mode);
  66337. + if (ret < 0) {
  66338. + mutex_unlock(&m->mma8450_lock);
  66339. + return ret;
  66340. + }
  66341. +
  66342. + msleep(MODE_CHANGE_DELAY_MS);
  66343. + m->mode = (u8)mode;
  66344. + mutex_unlock(&m->mma8450_lock);
  66345. +
  66346. + return count;
  66347. +}
  66348. +
  66349. +static DEVICE_ATTR(scalemode, S_IWUSR | S_IRUGO,
  66350. + mma8450_scalemode_show, mma8450_scalemode_store);
  66351. +
  66352. +static struct attribute *mma8450_attributes[] = {
  66353. + &dev_attr_scalemode.attr,
  66354. + NULL
  66355. +};
  66356. +
  66357. +static const struct attribute_group mma8450_attr_group = {
  66358. + .attrs = mma8450_attributes,
  66359. +};
  66360. +
  66361. /*
  66362. * I2C init/probing/exit functions
  66363. */
  66364. @@ -172,7 +261,25 @@
  66365. {
  66366. struct input_polled_dev *idev;
  66367. struct mma8450 *m;
  66368. - int err;
  66369. + int err, client_id;
  66370. + struct i2c_adapter *adapter = NULL;
  66371. +
  66372. + adapter = to_i2c_adapter(c->dev.parent);
  66373. + err = i2c_check_functionality(adapter,
  66374. + I2C_FUNC_SMBUS_BYTE |
  66375. + I2C_FUNC_SMBUS_BYTE_DATA);
  66376. + if (!err)
  66377. + goto err_out;
  66378. +
  66379. + client_id = i2c_smbus_read_byte_data(c, MMA8450_WHO_AM_I);
  66380. +
  66381. + if (MMA8450_ID != client_id) {
  66382. + dev_err(&c->dev,
  66383. + "read chip ID 0x%x is not equal to 0x%x!\n", client_id,
  66384. + MMA8450_ID);
  66385. + err = -EINVAL;
  66386. + goto err_out;
  66387. + }
  66388. m = kzalloc(sizeof(struct mma8450), GFP_KERNEL);
  66389. idev = input_allocate_polled_device();
  66390. @@ -183,6 +290,7 @@
  66391. m->client = c;
  66392. m->idev = idev;
  66393. + i2c_set_clientdata(c, m);
  66394. idev->private = m;
  66395. idev->input->name = MMA8450_DRV_NAME;
  66396. @@ -190,8 +298,6 @@
  66397. idev->poll = mma8450_poll;
  66398. idev->poll_interval = POLL_INTERVAL;
  66399. idev->poll_interval_max = POLL_INTERVAL_MAX;
  66400. - idev->open = mma8450_open;
  66401. - idev->close = mma8450_close;
  66402. __set_bit(EV_ABS, idev->input->evbit);
  66403. input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32);
  66404. @@ -206,11 +312,32 @@
  66405. i2c_set_clientdata(c, m);
  66406. + mutex_init(&m->mma8450_lock);
  66407. +
  66408. + err = mma8450_open(idev);
  66409. + if (err) {
  66410. + dev_err(&c->dev, "failed to initialize mma8450\n");
  66411. + goto err_unreg_dev;
  66412. + }
  66413. +
  66414. + err = sysfs_create_group(&c->dev.kobj, &mma8450_attr_group);
  66415. + if (err) {
  66416. + dev_err(&c->dev, "create device file failed!\n");
  66417. + err = -EINVAL;
  66418. + goto err_close;
  66419. + }
  66420. +
  66421. return 0;
  66422. +err_close:
  66423. + mma8450_close(idev);
  66424. +err_unreg_dev:
  66425. + mutex_destroy(&m->mma8450_lock);
  66426. + input_unregister_polled_device(idev);
  66427. err_free_mem:
  66428. input_free_polled_device(idev);
  66429. kfree(m);
  66430. +err_out:
  66431. return err;
  66432. }
  66433. @@ -219,6 +346,9 @@
  66434. struct mma8450 *m = i2c_get_clientdata(c);
  66435. struct input_polled_dev *idev = m->idev;
  66436. + sysfs_remove_group(&c->dev.kobj, &mma8450_attr_group);
  66437. + mma8450_close(idev);
  66438. + mutex_destroy(&m->mma8450_lock);
  66439. input_unregister_polled_device(idev);
  66440. input_free_polled_device(idev);
  66441. kfree(m);
  66442. diff -Nur linux-3.14.17/drivers/input/mouse/synaptics.c linux-imx6-3.14/drivers/input/mouse/synaptics.c
  66443. --- linux-3.14.17/drivers/input/mouse/synaptics.c 2014-08-14 03:38:34.000000000 +0200
  66444. +++ linux-imx6-3.14/drivers/input/mouse/synaptics.c 2014-09-11 18:06:01.526036075 +0200
  66445. @@ -132,8 +132,7 @@
  66446. 1232, 5710, 1156, 4696
  66447. },
  66448. {
  66449. - (const char * const []){"LEN0034", "LEN0036", "LEN2002",
  66450. - "LEN2004", NULL},
  66451. + (const char * const []){"LEN0034", "LEN0036", "LEN2004", NULL},
  66452. 1024, 5112, 2024, 4832
  66453. },
  66454. {
  66455. @@ -169,7 +168,7 @@
  66456. "LEN0049",
  66457. "LEN2000",
  66458. "LEN2001", /* Edge E431 */
  66459. - "LEN2002", /* Edge E531 */
  66460. + "LEN2002",
  66461. "LEN2003",
  66462. "LEN2004", /* L440 */
  66463. "LEN2005",
  66464. diff -Nur linux-3.14.17/drivers/input/sparse-keymap.c linux-imx6-3.14/drivers/input/sparse-keymap.c
  66465. --- linux-3.14.17/drivers/input/sparse-keymap.c 2014-08-14 03:38:34.000000000 +0200
  66466. +++ linux-imx6-3.14/drivers/input/sparse-keymap.c 2014-09-11 18:06:01.554036186 +0200
  66467. @@ -236,7 +236,7 @@
  66468. * in an input device that was set up by sparse_keymap_setup().
  66469. * NOTE: It is safe to cal this function while input device is
  66470. * still registered (however the drivers should care not to try to
  66471. - * use freed keymap and thus have to shut off interrups/polling
  66472. + * use freed keymap and thus have to shut off interrupts/polling
  66473. * before freeing the keymap).
  66474. */
  66475. void sparse_keymap_free(struct input_dev *dev)
  66476. diff -Nur linux-3.14.17/drivers/Kconfig linux-imx6-3.14/drivers/Kconfig
  66477. --- linux-3.14.17/drivers/Kconfig 2014-08-14 03:38:34.000000000 +0200
  66478. +++ linux-imx6-3.14/drivers/Kconfig 2014-09-11 18:05:59.194026757 +0200
  66479. @@ -96,6 +96,8 @@
  66480. source "drivers/memstick/Kconfig"
  66481. +source "drivers/mxc/Kconfig"
  66482. +
  66483. source "drivers/leds/Kconfig"
  66484. source "drivers/accessibility/Kconfig"
  66485. diff -Nur linux-3.14.17/drivers/leds/leds-gpio.c linux-imx6-3.14/drivers/leds/leds-gpio.c
  66486. --- linux-3.14.17/drivers/leds/leds-gpio.c 2014-08-14 03:38:34.000000000 +0200
  66487. +++ linux-imx6-3.14/drivers/leds/leds-gpio.c 2014-09-11 18:06:01.842037338 +0200
  66488. @@ -3,7 +3,7 @@
  66489. *
  66490. * Copyright (C) 2007 8D Technologies inc.
  66491. * Raphael Assenat <raph@8d.com>
  66492. - * Copyright (C) 2008 Freescale Semiconductor, Inc.
  66493. + * Copyright (C) 2008, 2014 Freescale Semiconductor, Inc.
  66494. *
  66495. * This program is free software; you can redistribute it and/or modify
  66496. * it under the terms of the GNU General Public License version 2 as
  66497. @@ -203,6 +203,8 @@
  66498. else
  66499. led.default_state = LEDS_GPIO_DEFSTATE_OFF;
  66500. }
  66501. + if (of_get_property(child, "retain-state-suspended", NULL))
  66502. + led.retain_state_suspended = 1;
  66503. ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
  66504. &pdev->dev, NULL);
  66505. diff -Nur linux-3.14.17/drivers/leds/leds-pwm.c linux-imx6-3.14/drivers/leds/leds-pwm.c
  66506. --- linux-3.14.17/drivers/leds/leds-pwm.c 2014-08-14 03:38:34.000000000 +0200
  66507. +++ linux-imx6-3.14/drivers/leds/leds-pwm.c 2014-09-11 18:06:01.846037353 +0200
  66508. @@ -70,6 +70,10 @@
  66509. duty *= brightness;
  66510. do_div(duty, max);
  66511. +
  66512. + if (led_dat->active_low)
  66513. + duty = led_dat->period - duty;
  66514. +
  66515. led_dat->duty = duty;
  66516. if (led_dat->can_sleep)
  66517. @@ -93,55 +97,75 @@
  66518. }
  66519. }
  66520. -static int led_pwm_create_of(struct platform_device *pdev,
  66521. - struct led_pwm_priv *priv)
  66522. +static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
  66523. + struct led_pwm *led, struct device_node *child)
  66524. {
  66525. - struct device_node *child;
  66526. + struct led_pwm_data *led_data = &priv->leds[priv->num_leds];
  66527. int ret;
  66528. - for_each_child_of_node(pdev->dev.of_node, child) {
  66529. - struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
  66530. + led_data->active_low = led->active_low;
  66531. + led_data->period = led->pwm_period_ns;
  66532. + led_data->cdev.name = led->name;
  66533. + led_data->cdev.default_trigger = led->default_trigger;
  66534. + led_data->cdev.brightness_set = led_pwm_set;
  66535. + led_data->cdev.brightness = LED_OFF;
  66536. + led_data->cdev.max_brightness = led->max_brightness;
  66537. + led_data->cdev.flags = LED_CORE_SUSPENDRESUME;
  66538. +
  66539. + if (child)
  66540. + led_data->pwm = devm_of_pwm_get(dev, child, NULL);
  66541. + else
  66542. + led_data->pwm = devm_pwm_get(dev, led->name);
  66543. + if (IS_ERR(led_data->pwm)) {
  66544. + ret = PTR_ERR(led_data->pwm);
  66545. + dev_err(dev, "unable to request PWM for %s: %d\n",
  66546. + led->name, ret);
  66547. + return ret;
  66548. + }
  66549. - led_dat->cdev.name = of_get_property(child, "label",
  66550. - NULL) ? : child->name;
  66551. + if (child)
  66552. + led_data->period = pwm_get_period(led_data->pwm);
  66553. - led_dat->pwm = devm_of_pwm_get(&pdev->dev, child, NULL);
  66554. - if (IS_ERR(led_dat->pwm)) {
  66555. - dev_err(&pdev->dev, "unable to request PWM for %s\n",
  66556. - led_dat->cdev.name);
  66557. - ret = PTR_ERR(led_dat->pwm);
  66558. - goto err;
  66559. - }
  66560. - /* Get the period from PWM core when n*/
  66561. - led_dat->period = pwm_get_period(led_dat->pwm);
  66562. + led_data->can_sleep = pwm_can_sleep(led_data->pwm);
  66563. + if (led_data->can_sleep)
  66564. + INIT_WORK(&led_data->work, led_pwm_work);
  66565. - led_dat->cdev.default_trigger = of_get_property(child,
  66566. + ret = led_classdev_register(dev, &led_data->cdev);
  66567. + if (ret == 0) {
  66568. + priv->num_leds++;
  66569. + } else {
  66570. + dev_err(dev, "failed to register PWM led for %s: %d\n",
  66571. + led->name, ret);
  66572. + }
  66573. +
  66574. + return ret;
  66575. +}
  66576. +
  66577. +static int led_pwm_create_of(struct device *dev, struct led_pwm_priv *priv)
  66578. +{
  66579. + struct device_node *child;
  66580. + struct led_pwm led;
  66581. + int ret = 0;
  66582. +
  66583. + memset(&led, 0, sizeof(led));
  66584. +
  66585. + for_each_child_of_node(dev->of_node, child) {
  66586. + led.name = of_get_property(child, "label", NULL) ? :
  66587. + child->name;
  66588. +
  66589. + led.default_trigger = of_get_property(child,
  66590. "linux,default-trigger", NULL);
  66591. + led.active_low = of_property_read_bool(child, "active-low");
  66592. of_property_read_u32(child, "max-brightness",
  66593. - &led_dat->cdev.max_brightness);
  66594. + &led.max_brightness);
  66595. - led_dat->cdev.brightness_set = led_pwm_set;
  66596. - led_dat->cdev.brightness = LED_OFF;
  66597. - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  66598. -
  66599. - led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
  66600. - if (led_dat->can_sleep)
  66601. - INIT_WORK(&led_dat->work, led_pwm_work);
  66602. -
  66603. - ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
  66604. - if (ret < 0) {
  66605. - dev_err(&pdev->dev, "failed to register for %s\n",
  66606. - led_dat->cdev.name);
  66607. + ret = led_pwm_add(dev, priv, &led, child);
  66608. + if (ret) {
  66609. of_node_put(child);
  66610. - goto err;
  66611. + break;
  66612. }
  66613. - priv->num_leds++;
  66614. }
  66615. - return 0;
  66616. -err:
  66617. - led_pwm_cleanup(priv);
  66618. -
  66619. return ret;
  66620. }
  66621. @@ -167,51 +191,23 @@
  66622. if (pdata) {
  66623. for (i = 0; i < count; i++) {
  66624. - struct led_pwm *cur_led = &pdata->leds[i];
  66625. - struct led_pwm_data *led_dat = &priv->leds[i];
  66626. -
  66627. - led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
  66628. - if (IS_ERR(led_dat->pwm)) {
  66629. - ret = PTR_ERR(led_dat->pwm);
  66630. - dev_err(&pdev->dev,
  66631. - "unable to request PWM for %s\n",
  66632. - cur_led->name);
  66633. - goto err;
  66634. - }
  66635. -
  66636. - led_dat->cdev.name = cur_led->name;
  66637. - led_dat->cdev.default_trigger = cur_led->default_trigger;
  66638. - led_dat->active_low = cur_led->active_low;
  66639. - led_dat->period = cur_led->pwm_period_ns;
  66640. - led_dat->cdev.brightness_set = led_pwm_set;
  66641. - led_dat->cdev.brightness = LED_OFF;
  66642. - led_dat->cdev.max_brightness = cur_led->max_brightness;
  66643. - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
  66644. -
  66645. - led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
  66646. - if (led_dat->can_sleep)
  66647. - INIT_WORK(&led_dat->work, led_pwm_work);
  66648. -
  66649. - ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
  66650. - if (ret < 0)
  66651. - goto err;
  66652. + ret = led_pwm_add(&pdev->dev, priv, &pdata->leds[i],
  66653. + NULL);
  66654. + if (ret)
  66655. + break;
  66656. }
  66657. - priv->num_leds = count;
  66658. } else {
  66659. - ret = led_pwm_create_of(pdev, priv);
  66660. - if (ret)
  66661. - return ret;
  66662. + ret = led_pwm_create_of(&pdev->dev, priv);
  66663. + }
  66664. +
  66665. + if (ret) {
  66666. + led_pwm_cleanup(priv);
  66667. + return ret;
  66668. }
  66669. platform_set_drvdata(pdev, priv);
  66670. return 0;
  66671. -
  66672. -err:
  66673. - priv->num_leds = i;
  66674. - led_pwm_cleanup(priv);
  66675. -
  66676. - return ret;
  66677. }
  66678. static int led_pwm_remove(struct platform_device *pdev)
  66679. diff -Nur linux-3.14.17/drivers/mailbox/mailbox.c linux-imx6-3.14/drivers/mailbox/mailbox.c
  66680. --- linux-3.14.17/drivers/mailbox/mailbox.c 1970-01-01 01:00:00.000000000 +0100
  66681. +++ linux-imx6-3.14/drivers/mailbox/mailbox.c 2014-09-11 18:06:01.890037529 +0200
  66682. @@ -0,0 +1,488 @@
  66683. +/*
  66684. + * Mailbox: Common code for Mailbox controllers and users
  66685. + *
  66686. + * Copyright (C) 2014 Linaro Ltd.
  66687. + * Author: Jassi Brar <jassisinghbrar@gmail.com>
  66688. + *
  66689. + * This program is free software; you can redistribute it and/or modify
  66690. + * it under the terms of the GNU General Public License version 2 as
  66691. + * published by the Free Software Foundation.
  66692. + */
  66693. +
  66694. +#include <linux/interrupt.h>
  66695. +#include <linux/spinlock.h>
  66696. +#include <linux/mutex.h>
  66697. +#include <linux/delay.h>
  66698. +#include <linux/slab.h>
  66699. +#include <linux/err.h>
  66700. +#include <linux/module.h>
  66701. +#include <linux/device.h>
  66702. +#include <linux/mailbox_client.h>
  66703. +#include <linux/mailbox_controller.h>
  66704. +
  66705. +#define TXDONE_BY_IRQ (1 << 0) /* controller has remote RTR irq */
  66706. +#define TXDONE_BY_POLL (1 << 1) /* controller can read status of last TX */
  66707. +#define TXDONE_BY_ACK (1 << 2) /* S/W ACK recevied by Client ticks the TX */
  66708. +
  66709. +static LIST_HEAD(mbox_cons);
  66710. +static DEFINE_MUTEX(con_mutex);
  66711. +
  66712. +static int _add_to_rbuf(struct mbox_chan *chan, void *mssg)
  66713. +{
  66714. + int idx;
  66715. + unsigned long flags;
  66716. +
  66717. + spin_lock_irqsave(&chan->lock, flags);
  66718. +
  66719. + /* See if there is any space left */
  66720. + if (chan->msg_count == MBOX_TX_QUEUE_LEN) {
  66721. + spin_unlock_irqrestore(&chan->lock, flags);
  66722. + return -ENOMEM;
  66723. + }
  66724. +
  66725. + idx = chan->msg_free;
  66726. + chan->msg_data[idx] = mssg;
  66727. + chan->msg_count++;
  66728. +
  66729. + if (idx == MBOX_TX_QUEUE_LEN - 1)
  66730. + chan->msg_free = 0;
  66731. + else
  66732. + chan->msg_free++;
  66733. +
  66734. + spin_unlock_irqrestore(&chan->lock, flags);
  66735. +
  66736. + return idx;
  66737. +}
  66738. +
  66739. +static void _msg_submit(struct mbox_chan *chan)
  66740. +{
  66741. + unsigned count, idx;
  66742. + unsigned long flags;
  66743. + void *data;
  66744. + int err;
  66745. +
  66746. + spin_lock_irqsave(&chan->lock, flags);
  66747. +
  66748. + if (!chan->msg_count || chan->active_req) {
  66749. + spin_unlock_irqrestore(&chan->lock, flags);
  66750. + return;
  66751. + }
  66752. +
  66753. + count = chan->msg_count;
  66754. + idx = chan->msg_free;
  66755. + if (idx >= count)
  66756. + idx -= count;
  66757. + else
  66758. + idx += MBOX_TX_QUEUE_LEN - count;
  66759. +
  66760. + data = chan->msg_data[idx];
  66761. +
  66762. + /* Try to submit a message to the MBOX controller */
  66763. + err = chan->mbox->ops->send_data(chan, data);
  66764. + if (!err) {
  66765. + chan->active_req = data;
  66766. + chan->msg_count--;
  66767. + }
  66768. +
  66769. + spin_unlock_irqrestore(&chan->lock, flags);
  66770. +}
  66771. +
  66772. +static void tx_tick(struct mbox_chan *chan, int r)
  66773. +{
  66774. + unsigned long flags;
  66775. + void *mssg;
  66776. +
  66777. + spin_lock_irqsave(&chan->lock, flags);
  66778. + mssg = chan->active_req;
  66779. + chan->active_req = NULL;
  66780. + spin_unlock_irqrestore(&chan->lock, flags);
  66781. +
  66782. + /* Submit next message */
  66783. + _msg_submit(chan);
  66784. +
  66785. + /* Notify the client */
  66786. + if (chan->cl->tx_block)
  66787. + complete(&chan->tx_complete);
  66788. + else if (mssg && chan->cl->tx_done)
  66789. + chan->cl->tx_done(chan->cl, mssg, r);
  66790. +}
  66791. +
  66792. +static void poll_txdone(unsigned long data)
  66793. +{
  66794. + struct mbox_controller *mbox = (struct mbox_controller *)data;
  66795. + bool txdone, resched = false;
  66796. + int i;
  66797. +
  66798. + for (i = 0; i < mbox->num_chans; i++) {
  66799. + struct mbox_chan *chan = &mbox->chans[i];
  66800. +
  66801. + if (chan->active_req && chan->cl) {
  66802. + resched = true;
  66803. + txdone = chan->mbox->ops->last_tx_done(chan);
  66804. + if (txdone)
  66805. + tx_tick(chan, 0);
  66806. + }
  66807. + }
  66808. +
  66809. + if (resched)
  66810. + mod_timer(&mbox->poll,
  66811. + jiffies + msecs_to_jiffies(mbox->period));
  66812. +}
  66813. +
  66814. +/**
  66815. + * mbox_chan_received_data - A way for controller driver to push data
  66816. + * received from remote to the upper layer.
  66817. + * @chan: Pointer to the mailbox channel on which RX happened.
  66818. + * @data: Client specific message typecasted as void *
  66819. + *
  66820. + * After startup and before shutdown any data received on the chan
  66821. + * is passed on to the API via atomic mbox_chan_received_data().
  66822. + * The controller should ACK the RX only after this call returns.
  66823. + */
  66824. +void mbox_chan_received_data(struct mbox_chan *chan, void *mssg)
  66825. +{
  66826. + /* No buffering the received data */
  66827. + if (chan->cl->rx_callback)
  66828. + chan->cl->rx_callback(chan->cl, mssg);
  66829. +}
  66830. +EXPORT_SYMBOL_GPL(mbox_chan_received_data);
  66831. +
  66832. +/**
  66833. + * mbox_chan_txdone - A way for controller driver to notify the
  66834. + * framework that the last TX has completed.
  66835. + * @chan: Pointer to the mailbox chan on which TX happened.
  66836. + * @r: Status of last TX - OK or ERROR
  66837. + *
  66838. + * The controller that has IRQ for TX ACK calls this atomic API
  66839. + * to tick the TX state machine. It works only if txdone_irq
  66840. + * is set by the controller.
  66841. + */
  66842. +void mbox_chan_txdone(struct mbox_chan *chan, int r)
  66843. +{
  66844. + if (unlikely(!(chan->txdone_method & TXDONE_BY_IRQ))) {
  66845. + pr_err("Controller can't run the TX ticker\n");
  66846. + return;
  66847. + }
  66848. +
  66849. + tx_tick(chan, r);
  66850. +}
  66851. +EXPORT_SYMBOL_GPL(mbox_chan_txdone);
  66852. +
  66853. +/**
  66854. + * mbox_client_txdone - The way for a client to run the TX state machine.
  66855. + * @chan: Mailbox channel assigned to this client.
  66856. + * @r: Success status of last transmission.
  66857. + *
  66858. + * The client/protocol had received some 'ACK' packet and it notifies
  66859. + * the API that the last packet was sent successfully. This only works
  66860. + * if the controller can't sense TX-Done.
  66861. + */
  66862. +void mbox_client_txdone(struct mbox_chan *chan, int r)
  66863. +{
  66864. + if (unlikely(!(chan->txdone_method & TXDONE_BY_ACK))) {
  66865. + pr_err("Client can't run the TX ticker\n");
  66866. + return;
  66867. + }
  66868. +
  66869. + tx_tick(chan, r);
  66870. +}
  66871. +EXPORT_SYMBOL_GPL(mbox_client_txdone);
  66872. +
  66873. +/**
  66874. + * mbox_client_peek_data - A way for client driver to pull data
  66875. + * received from remote by the controller.
  66876. + * @chan: Mailbox channel assigned to this client.
  66877. + *
  66878. + * A poke to controller driver for any received data.
  66879. + * The data is actually passed onto client via the
  66880. + * mbox_chan_received_data()
  66881. + * The call can be made from atomic context, so the controller's
  66882. + * implementation of peek_data() must not sleep.
  66883. + *
  66884. + * Return: True, if controller has, and is going to push after this,
  66885. + * some data.
  66886. + * False, if controller doesn't have any data to be read.
  66887. + */
  66888. +bool mbox_client_peek_data(struct mbox_chan *chan)
  66889. +{
  66890. + if (chan->mbox->ops->peek_data)
  66891. + return chan->mbox->ops->peek_data(chan);
  66892. +
  66893. + return false;
  66894. +}
  66895. +EXPORT_SYMBOL_GPL(mbox_client_peek_data);
  66896. +
  66897. +/**
  66898. + * mbox_send_message - For client to submit a message to be
  66899. + * sent to the remote.
  66900. + * @chan: Mailbox channel assigned to this client.
  66901. + * @mssg: Client specific message typecasted.
  66902. + *
  66903. + * For client to submit data to the controller destined for a remote
  66904. + * processor. If the client had set 'tx_block', the call will return
  66905. + * either when the remote receives the data or when 'tx_tout' millisecs
  66906. + * run out.
  66907. + * In non-blocking mode, the requests are buffered by the API and a
  66908. + * non-negative token is returned for each queued request. If the request
  66909. + * is not queued, a negative token is returned. Upon failure or successful
  66910. + * TX, the API calls 'tx_done' from atomic context, from which the client
  66911. + * could submit yet another request.
  66912. + * In blocking mode, 'tx_done' is not called, effectively making the
  66913. + * queue length 1.
  66914. + * The pointer to message should be preserved until it is sent
  66915. + * over the chan, i.e, tx_done() is made.
  66916. + * This function could be called from atomic context as it simply
  66917. + * queues the data and returns a token against the request.
  66918. + *
  66919. + * Return: Non-negative integer for successful submission (non-blocking mode)
  66920. + * or transmission over chan (blocking mode).
  66921. + * Negative value denotes failure.
  66922. + */
  66923. +int mbox_send_message(struct mbox_chan *chan, void *mssg)
  66924. +{
  66925. + int t;
  66926. +
  66927. + if (!chan || !chan->cl)
  66928. + return -EINVAL;
  66929. +
  66930. + t = _add_to_rbuf(chan, mssg);
  66931. + if (t < 0) {
  66932. + pr_err("Try increasing MBOX_TX_QUEUE_LEN\n");
  66933. + return t;
  66934. + }
  66935. +
  66936. + _msg_submit(chan);
  66937. +
  66938. + reinit_completion(&chan->tx_complete);
  66939. +
  66940. + if (chan->txdone_method == TXDONE_BY_POLL)
  66941. + poll_txdone((unsigned long)chan->mbox);
  66942. +
  66943. + if (chan->cl->tx_block && chan->active_req) {
  66944. + unsigned long wait;
  66945. + int ret;
  66946. +
  66947. + if (!chan->cl->tx_tout) /* wait for ever */
  66948. + wait = msecs_to_jiffies(3600000);
  66949. + else
  66950. + wait = msecs_to_jiffies(chan->cl->tx_tout);
  66951. +
  66952. + ret = wait_for_completion_timeout(&chan->tx_complete, wait);
  66953. + if (ret == 0) {
  66954. + t = -EIO;
  66955. + tx_tick(chan, -EIO);
  66956. + }
  66957. + }
  66958. +
  66959. + return t;
  66960. +}
  66961. +EXPORT_SYMBOL_GPL(mbox_send_message);
  66962. +
  66963. +/**
  66964. + * mbox_request_channel - Request a mailbox channel.
  66965. + * @cl: Identity of the client requesting the channel.
  66966. + *
  66967. + * The Client specifies its requirements and capabilities while asking for
  66968. + * a mailbox channel. It can't be called from atomic context.
  66969. + * The channel is exclusively allocated and can't be used by another
  66970. + * client before the owner calls mbox_free_channel.
  66971. + * After assignment, any packet received on this channel will be
  66972. + * handed over to the client via the 'rx_callback'.
  66973. + * The framework holds reference to the client, so the mbox_client
  66974. + * structure shouldn't be modified until the mbox_free_channel returns.
  66975. + *
  66976. + * Return: Pointer to the channel assigned to the client if successful.
  66977. + * ERR_PTR for request failure.
  66978. + */
  66979. +struct mbox_chan *mbox_request_channel(struct mbox_client *cl)
  66980. +{
  66981. + struct device *dev = cl->dev;
  66982. + struct mbox_controller *mbox;
  66983. + struct of_phandle_args spec;
  66984. + struct mbox_chan *chan;
  66985. + unsigned long flags;
  66986. + int count, i, ret;
  66987. +
  66988. + if (!dev || !dev->of_node) {
  66989. + pr_err("%s: No owner device node\n", __func__);
  66990. + return ERR_PTR(-ENODEV);
  66991. + }
  66992. +
  66993. + count = of_property_count_strings(dev->of_node, "mbox-names");
  66994. + if (count < 0) {
  66995. + pr_err("%s: mbox-names property of node '%s' missing\n",
  66996. + __func__, dev->of_node->full_name);
  66997. + return ERR_PTR(-ENODEV);
  66998. + }
  66999. +
  67000. + mutex_lock(&con_mutex);
  67001. +
  67002. + ret = -ENODEV;
  67003. + for (i = 0; i < count; i++) {
  67004. + const char *s;
  67005. +
  67006. + if (of_property_read_string_index(dev->of_node,
  67007. + "mbox-names", i, &s))
  67008. + continue;
  67009. +
  67010. + if (strcmp(cl->chan_name, s))
  67011. + continue;
  67012. +
  67013. + if (of_parse_phandle_with_args(dev->of_node,
  67014. + "mbox", "#mbox-cells", i, &spec))
  67015. + continue;
  67016. +
  67017. + chan = NULL;
  67018. + list_for_each_entry(mbox, &mbox_cons, node)
  67019. + if (mbox->dev->of_node == spec.np) {
  67020. + chan = mbox->of_xlate(mbox, &spec);
  67021. + break;
  67022. + }
  67023. +
  67024. + of_node_put(spec.np);
  67025. +
  67026. + if (!chan)
  67027. + continue;
  67028. +
  67029. + ret = -EBUSY;
  67030. + if (!chan->cl && try_module_get(mbox->dev->driver->owner))
  67031. + break;
  67032. + }
  67033. +
  67034. + if (i == count) {
  67035. + mutex_unlock(&con_mutex);
  67036. + return ERR_PTR(ret);
  67037. + }
  67038. +
  67039. + spin_lock_irqsave(&chan->lock, flags);
  67040. + chan->msg_free = 0;
  67041. + chan->msg_count = 0;
  67042. + chan->active_req = NULL;
  67043. + chan->cl = cl;
  67044. + init_completion(&chan->tx_complete);
  67045. +
  67046. + if (chan->txdone_method == TXDONE_BY_POLL
  67047. + && cl->knows_txdone)
  67048. + chan->txdone_method |= TXDONE_BY_ACK;
  67049. + spin_unlock_irqrestore(&chan->lock, flags);
  67050. +
  67051. + ret = chan->mbox->ops->startup(chan);
  67052. + if (ret) {
  67053. + pr_err("Unable to startup the chan (%d)\n", ret);
  67054. + mbox_free_channel(chan);
  67055. + chan = ERR_PTR(ret);
  67056. + }
  67057. +
  67058. + mutex_unlock(&con_mutex);
  67059. + return chan;
  67060. +}
  67061. +EXPORT_SYMBOL_GPL(mbox_request_channel);
  67062. +
  67063. +/**
  67064. + * mbox_free_channel - The client relinquishes control of a mailbox
  67065. + * channel by this call.
  67066. + * @chan: The mailbox channel to be freed.
  67067. + */
  67068. +void mbox_free_channel(struct mbox_chan *chan)
  67069. +{
  67070. + unsigned long flags;
  67071. +
  67072. + if (!chan || !chan->cl)
  67073. + return;
  67074. +
  67075. + chan->mbox->ops->shutdown(chan);
  67076. +
  67077. + /* The queued TX requests are simply aborted, no callbacks are made */
  67078. + spin_lock_irqsave(&chan->lock, flags);
  67079. + chan->cl = NULL;
  67080. + chan->active_req = NULL;
  67081. + if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
  67082. + chan->txdone_method = TXDONE_BY_POLL;
  67083. +
  67084. + module_put(chan->mbox->dev->driver->owner);
  67085. + spin_unlock_irqrestore(&chan->lock, flags);
  67086. +}
  67087. +EXPORT_SYMBOL_GPL(mbox_free_channel);
  67088. +
  67089. +static struct mbox_chan *
  67090. +of_mbox_index_xlate(struct mbox_controller *mbox,
  67091. + const struct of_phandle_args *sp)
  67092. +{
  67093. + int ind = sp->args[0];
  67094. +
  67095. + if (ind >= mbox->num_chans)
  67096. + return NULL;
  67097. +
  67098. + return &mbox->chans[ind];
  67099. +}
  67100. +
  67101. +/**
  67102. + * mbox_controller_register - Register the mailbox controller
  67103. + * @mbox: Pointer to the mailbox controller.
  67104. + *
  67105. + * The controller driver registers its communication chans
  67106. + */
  67107. +int mbox_controller_register(struct mbox_controller *mbox)
  67108. +{
  67109. + int i, txdone;
  67110. +
  67111. + /* Sanity check */
  67112. + if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans)
  67113. + return -EINVAL;
  67114. +
  67115. + if (mbox->txdone_irq)
  67116. + txdone = TXDONE_BY_IRQ;
  67117. + else if (mbox->txdone_poll)
  67118. + txdone = TXDONE_BY_POLL;
  67119. + else /* It has to be ACK then */
  67120. + txdone = TXDONE_BY_ACK;
  67121. +
  67122. + if (txdone == TXDONE_BY_POLL) {
  67123. + mbox->poll.function = &poll_txdone;
  67124. + mbox->poll.data = (unsigned long)mbox;
  67125. + init_timer(&mbox->poll);
  67126. + }
  67127. +
  67128. + for (i = 0; i < mbox->num_chans; i++) {
  67129. + struct mbox_chan *chan = &mbox->chans[i];
  67130. + chan->cl = NULL;
  67131. + chan->mbox = mbox;
  67132. + chan->txdone_method = txdone;
  67133. + spin_lock_init(&chan->lock);
  67134. + }
  67135. +
  67136. + if (!mbox->of_xlate)
  67137. + mbox->of_xlate = of_mbox_index_xlate;
  67138. +
  67139. + mutex_lock(&con_mutex);
  67140. + list_add_tail(&mbox->node, &mbox_cons);
  67141. + mutex_unlock(&con_mutex);
  67142. +
  67143. + return 0;
  67144. +}
  67145. +EXPORT_SYMBOL_GPL(mbox_controller_register);
  67146. +
  67147. +/**
  67148. + * mbox_controller_unregister - UnRegister the mailbox controller
  67149. + * @mbox: Pointer to the mailbox controller.
  67150. + */
  67151. +void mbox_controller_unregister(struct mbox_controller *mbox)
  67152. +{
  67153. + int i;
  67154. +
  67155. + if (!mbox)
  67156. + return;
  67157. +
  67158. + mutex_lock(&con_mutex);
  67159. +
  67160. + list_del(&mbox->node);
  67161. +
  67162. + for (i = 0; i < mbox->num_chans; i++)
  67163. + mbox_free_channel(&mbox->chans[i]);
  67164. +
  67165. + if (mbox->txdone_poll)
  67166. + del_timer_sync(&mbox->poll);
  67167. +
  67168. + mutex_unlock(&con_mutex);
  67169. +}
  67170. +EXPORT_SYMBOL_GPL(mbox_controller_unregister);
  67171. diff -Nur linux-3.14.17/drivers/mailbox/Makefile linux-imx6-3.14/drivers/mailbox/Makefile
  67172. --- linux-3.14.17/drivers/mailbox/Makefile 2014-08-14 03:38:34.000000000 +0200
  67173. +++ linux-imx6-3.14/drivers/mailbox/Makefile 2014-09-11 18:06:01.890037529 +0200
  67174. @@ -1,3 +1,7 @@
  67175. +# Generic MAILBOX API
  67176. +
  67177. +obj-$(CONFIG_MAILBOX) += mailbox.o
  67178. +
  67179. obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
  67180. obj-$(CONFIG_OMAP_MBOX) += omap-mailbox.o
  67181. diff -Nur linux-3.14.17/drivers/mailbox/pl320-ipc.c linux-imx6-3.14/drivers/mailbox/pl320-ipc.c
  67182. --- linux-3.14.17/drivers/mailbox/pl320-ipc.c 2014-08-14 03:38:34.000000000 +0200
  67183. +++ linux-imx6-3.14/drivers/mailbox/pl320-ipc.c 2014-09-11 18:06:01.890037529 +0200
  67184. @@ -26,7 +26,7 @@
  67185. #include <linux/device.h>
  67186. #include <linux/amba/bus.h>
  67187. -#include <linux/mailbox.h>
  67188. +#include <linux/pl320-ipc.h>
  67189. #define IPCMxSOURCE(m) ((m) * 0x40)
  67190. #define IPCMxDSET(m) (((m) * 0x40) + 0x004)
  67191. diff -Nur linux-3.14.17/drivers/Makefile linux-imx6-3.14/drivers/Makefile
  67192. --- linux-3.14.17/drivers/Makefile 2014-08-14 03:38:34.000000000 +0200
  67193. +++ linux-imx6-3.14/drivers/Makefile 2014-09-11 18:05:59.194026757 +0200
  67194. @@ -111,6 +111,7 @@
  67195. obj-$(CONFIG_CPU_FREQ) += cpufreq/
  67196. obj-$(CONFIG_CPU_IDLE) += cpuidle/
  67197. obj-y += mmc/
  67198. +obj-$(CONFIG_ARCH_MXC) += mxc/
  67199. obj-$(CONFIG_MEMSTICK) += memstick/
  67200. obj-y += leds/
  67201. obj-$(CONFIG_INFINIBAND) += infiniband/
  67202. diff -Nur linux-3.14.17/drivers/md/dm-bufio.c linux-imx6-3.14/drivers/md/dm-bufio.c
  67203. --- linux-3.14.17/drivers/md/dm-bufio.c 2014-08-14 03:38:34.000000000 +0200
  67204. +++ linux-imx6-3.14/drivers/md/dm-bufio.c 2014-09-11 18:06:01.898037562 +0200
  67205. @@ -1541,7 +1541,7 @@
  67206. BUG_ON(block_size < 1 << SECTOR_SHIFT ||
  67207. (block_size & (block_size - 1)));
  67208. - c = kzalloc(sizeof(*c), GFP_KERNEL);
  67209. + c = kmalloc(sizeof(*c), GFP_KERNEL);
  67210. if (!c) {
  67211. r = -ENOMEM;
  67212. goto bad_client;
  67213. diff -Nur linux-3.14.17/drivers/md/dm-cache-target.c linux-imx6-3.14/drivers/md/dm-cache-target.c
  67214. --- linux-3.14.17/drivers/md/dm-cache-target.c 2014-08-14 03:38:34.000000000 +0200
  67215. +++ linux-imx6-3.14/drivers/md/dm-cache-target.c 2014-09-11 18:06:01.902037577 +0200
  67216. @@ -231,7 +231,7 @@
  67217. /*
  67218. * cache_size entries, dirty if set
  67219. */
  67220. - atomic_t nr_dirty;
  67221. + dm_cblock_t nr_dirty;
  67222. unsigned long *dirty_bitset;
  67223. /*
  67224. @@ -493,7 +493,7 @@
  67225. static void set_dirty(struct cache *cache, dm_oblock_t oblock, dm_cblock_t cblock)
  67226. {
  67227. if (!test_and_set_bit(from_cblock(cblock), cache->dirty_bitset)) {
  67228. - atomic_inc(&cache->nr_dirty);
  67229. + cache->nr_dirty = to_cblock(from_cblock(cache->nr_dirty) + 1);
  67230. policy_set_dirty(cache->policy, oblock);
  67231. }
  67232. }
  67233. @@ -502,7 +502,8 @@
  67234. {
  67235. if (test_and_clear_bit(from_cblock(cblock), cache->dirty_bitset)) {
  67236. policy_clear_dirty(cache->policy, oblock);
  67237. - if (atomic_dec_return(&cache->nr_dirty) == 0)
  67238. + cache->nr_dirty = to_cblock(from_cblock(cache->nr_dirty) - 1);
  67239. + if (!from_cblock(cache->nr_dirty))
  67240. dm_table_event(cache->ti->table);
  67241. }
  67242. }
  67243. @@ -2285,7 +2286,7 @@
  67244. atomic_set(&cache->quiescing_ack, 0);
  67245. r = -ENOMEM;
  67246. - atomic_set(&cache->nr_dirty, 0);
  67247. + cache->nr_dirty = 0;
  67248. cache->dirty_bitset = alloc_bitset(from_cblock(cache->cache_size));
  67249. if (!cache->dirty_bitset) {
  67250. *error = "could not allocate dirty bitset";
  67251. @@ -2827,7 +2828,7 @@
  67252. residency = policy_residency(cache->policy);
  67253. - DMEMIT("%u %llu/%llu %u %llu/%llu %u %u %u %u %u %u %lu ",
  67254. + DMEMIT("%u %llu/%llu %u %llu/%llu %u %u %u %u %u %u %llu ",
  67255. (unsigned)(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT),
  67256. (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata),
  67257. (unsigned long long)nr_blocks_metadata,
  67258. @@ -2840,7 +2841,7 @@
  67259. (unsigned) atomic_read(&cache->stats.write_miss),
  67260. (unsigned) atomic_read(&cache->stats.demotion),
  67261. (unsigned) atomic_read(&cache->stats.promotion),
  67262. - (unsigned long) atomic_read(&cache->nr_dirty));
  67263. + (unsigned long long) from_cblock(cache->nr_dirty));
  67264. if (writethrough_mode(&cache->features))
  67265. DMEMIT("1 writethrough ");
  67266. diff -Nur linux-3.14.17/drivers/media/dvb-frontends/tda10071.c linux-imx6-3.14/drivers/media/dvb-frontends/tda10071.c
  67267. --- linux-3.14.17/drivers/media/dvb-frontends/tda10071.c 2014-08-14 03:38:34.000000000 +0200
  67268. +++ linux-imx6-3.14/drivers/media/dvb-frontends/tda10071.c 2014-09-11 18:06:02.026038073 +0200
  67269. @@ -667,7 +667,6 @@
  67270. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  67271. int ret, i;
  67272. u8 mode, rolloff, pilot, inversion, div;
  67273. - fe_modulation_t modulation;
  67274. dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \
  67275. "frequency=%d symbol_rate=%d inversion=%d pilot=%d " \
  67276. @@ -702,13 +701,10 @@
  67277. switch (c->delivery_system) {
  67278. case SYS_DVBS:
  67279. - modulation = QPSK;
  67280. rolloff = 0;
  67281. pilot = 2;
  67282. break;
  67283. case SYS_DVBS2:
  67284. - modulation = c->modulation;
  67285. -
  67286. switch (c->rolloff) {
  67287. case ROLLOFF_20:
  67288. rolloff = 2;
  67289. @@ -753,7 +749,7 @@
  67290. for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
  67291. if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
  67292. - modulation == TDA10071_MODCOD[i].modulation &&
  67293. + c->modulation == TDA10071_MODCOD[i].modulation &&
  67294. c->fec_inner == TDA10071_MODCOD[i].fec) {
  67295. mode = TDA10071_MODCOD[i].val;
  67296. dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
  67297. diff -Nur linux-3.14.17/drivers/media/platform/Kconfig linux-imx6-3.14/drivers/media/platform/Kconfig
  67298. --- linux-3.14.17/drivers/media/platform/Kconfig 2014-08-14 03:38:34.000000000 +0200
  67299. +++ linux-imx6-3.14/drivers/media/platform/Kconfig 2014-09-11 18:06:02.238038919 +0200
  67300. @@ -115,6 +115,21 @@
  67301. To compile this driver as a module, choose M here: the module
  67302. will be called s3c-camif.
  67303. +config VIDEO_MXC_OUTPUT
  67304. + tristate "MXC Video For Linux Video Output"
  67305. + depends on VIDEO_DEV && ARCH_MXC && FB_MXC
  67306. + select VIDEOBUF_DMA_CONTIG
  67307. + ---help---
  67308. + This is the video4linux2 output driver based on MXC module.
  67309. +
  67310. +config VIDEO_MXC_CAPTURE
  67311. + tristate "MXC Video For Linux Video Capture"
  67312. + depends on VIDEO_V4L2 && VIDEO_V4L2_INT_DEVICE
  67313. + ---help---
  67314. + This is the video4linux2 capture driver based on i.MX video-in module.
  67315. +
  67316. +source "drivers/media/platform/mxc/capture/Kconfig"
  67317. +source "drivers/media/platform/mxc/output/Kconfig"
  67318. source "drivers/media/platform/soc_camera/Kconfig"
  67319. source "drivers/media/platform/exynos4-is/Kconfig"
  67320. source "drivers/media/platform/s5p-tv/Kconfig"
  67321. diff -Nur linux-3.14.17/drivers/media/platform/Makefile linux-imx6-3.14/drivers/media/platform/Makefile
  67322. --- linux-3.14.17/drivers/media/platform/Makefile 2014-08-14 03:38:34.000000000 +0200
  67323. +++ linux-imx6-3.14/drivers/media/platform/Makefile 2014-09-11 18:06:02.238038919 +0200
  67324. @@ -51,4 +51,7 @@
  67325. obj-$(CONFIG_ARCH_OMAP) += omap/
  67326. +obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc/capture/
  67327. +obj-$(CONFIG_VIDEO_MXC_OUTPUT) += mxc/output/
  67328. +
  67329. ccflags-y += -I$(srctree)/drivers/media/i2c
  67330. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/adv7180.c linux-imx6-3.14/drivers/media/platform/mxc/capture/adv7180.c
  67331. --- linux-3.14.17/drivers/media/platform/mxc/capture/adv7180.c 1970-01-01 01:00:00.000000000 +0100
  67332. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/adv7180.c 2014-09-11 18:06:02.254038983 +0200
  67333. @@ -0,0 +1,1344 @@
  67334. +/*
  67335. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  67336. + */
  67337. +
  67338. +/*
  67339. + * The code contained herein is licensed under the GNU General Public
  67340. + * License. You may obtain a copy of the GNU General Public License
  67341. + * Version 2 or later at the following locations:
  67342. + *
  67343. + * http://www.opensource.org/licenses/gpl-license.html
  67344. + * http://www.gnu.org/copyleft/gpl.html
  67345. + */
  67346. +
  67347. +/*!
  67348. + * @file adv7180.c
  67349. + *
  67350. + * @brief Analog Device ADV7180 video decoder functions
  67351. + *
  67352. + * @ingroup Camera
  67353. + */
  67354. +
  67355. +#include <linux/clk.h>
  67356. +#include <linux/delay.h>
  67357. +#include <linux/device.h>
  67358. +#include <linux/i2c.h>
  67359. +#include <linux/init.h>
  67360. +#include <linux/module.h>
  67361. +#include <linux/of_device.h>
  67362. +#include <linux/of_gpio.h>
  67363. +#include <linux/pinctrl/consumer.h>
  67364. +#include <linux/regulator/consumer.h>
  67365. +#include <media/v4l2-chip-ident.h>
  67366. +#include <media/v4l2-int-device.h>
  67367. +#include "mxc_v4l2_capture.h"
  67368. +
  67369. +#define ADV7180_VOLTAGE_ANALOG 1800000
  67370. +#define ADV7180_VOLTAGE_DIGITAL_CORE 1800000
  67371. +#define ADV7180_VOLTAGE_DIGITAL_IO 3300000
  67372. +#define ADV7180_VOLTAGE_PLL 1800000
  67373. +
  67374. +static struct regulator *dvddio_regulator;
  67375. +static struct regulator *dvdd_regulator;
  67376. +static struct regulator *avdd_regulator;
  67377. +static struct regulator *pvdd_regulator;
  67378. +static int pwn_gpio;
  67379. +
  67380. +static int adv7180_probe(struct i2c_client *adapter,
  67381. + const struct i2c_device_id *id);
  67382. +static int adv7180_detach(struct i2c_client *client);
  67383. +
  67384. +static const struct i2c_device_id adv7180_id[] = {
  67385. + {"adv7180", 0},
  67386. + {},
  67387. +};
  67388. +
  67389. +MODULE_DEVICE_TABLE(i2c, adv7180_id);
  67390. +
  67391. +static struct i2c_driver adv7180_i2c_driver = {
  67392. + .driver = {
  67393. + .owner = THIS_MODULE,
  67394. + .name = "adv7180",
  67395. + },
  67396. + .probe = adv7180_probe,
  67397. + .remove = adv7180_detach,
  67398. + .id_table = adv7180_id,
  67399. +};
  67400. +
  67401. +/*!
  67402. + * Maintains the information on the current state of the sensor.
  67403. + */
  67404. +struct sensor {
  67405. + struct sensor_data sen;
  67406. + v4l2_std_id std_id;
  67407. +} adv7180_data;
  67408. +
  67409. +
  67410. +/*! List of input video formats supported. The video formats is corresponding
  67411. + * with v4l2 id in video_fmt_t
  67412. + */
  67413. +typedef enum {
  67414. + ADV7180_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
  67415. + ADV7180_PAL, /*!< (B, G, H, I, N)PAL video signal. */
  67416. + ADV7180_NOT_LOCKED, /*!< Not locked on a signal. */
  67417. +} video_fmt_idx;
  67418. +
  67419. +/*! Number of video standards supported (including 'not locked' signal). */
  67420. +#define ADV7180_STD_MAX (ADV7180_PAL + 1)
  67421. +
  67422. +/*! Video format structure. */
  67423. +typedef struct {
  67424. + int v4l2_id; /*!< Video for linux ID. */
  67425. + char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
  67426. + u16 raw_width; /*!< Raw width. */
  67427. + u16 raw_height; /*!< Raw height. */
  67428. + u16 active_width; /*!< Active width. */
  67429. + u16 active_height; /*!< Active height. */
  67430. +} video_fmt_t;
  67431. +
  67432. +/*! Description of video formats supported.
  67433. + *
  67434. + * PAL: raw=720x625, active=720x576.
  67435. + * NTSC: raw=720x525, active=720x480.
  67436. + */
  67437. +static video_fmt_t video_fmts[] = {
  67438. + { /*! NTSC */
  67439. + .v4l2_id = V4L2_STD_NTSC,
  67440. + .name = "NTSC",
  67441. + .raw_width = 720, /* SENS_FRM_WIDTH */
  67442. + .raw_height = 525, /* SENS_FRM_HEIGHT */
  67443. + .active_width = 720, /* ACT_FRM_WIDTH plus 1 */
  67444. + .active_height = 480, /* ACT_FRM_WIDTH plus 1 */
  67445. + },
  67446. + { /*! (B, G, H, I, N) PAL */
  67447. + .v4l2_id = V4L2_STD_PAL,
  67448. + .name = "PAL",
  67449. + .raw_width = 720,
  67450. + .raw_height = 625,
  67451. + .active_width = 720,
  67452. + .active_height = 576,
  67453. + },
  67454. + { /*! Unlocked standard */
  67455. + .v4l2_id = V4L2_STD_ALL,
  67456. + .name = "Autodetect",
  67457. + .raw_width = 720,
  67458. + .raw_height = 625,
  67459. + .active_width = 720,
  67460. + .active_height = 576,
  67461. + },
  67462. +};
  67463. +
  67464. +/*!* Standard index of ADV7180. */
  67465. +static video_fmt_idx video_idx = ADV7180_PAL;
  67466. +
  67467. +/*! @brief This mutex is used to provide mutual exclusion.
  67468. + *
  67469. + * Create a mutex that can be used to provide mutually exclusive
  67470. + * read/write access to the globally accessible data structures
  67471. + * and variables that were defined above.
  67472. + */
  67473. +static DEFINE_MUTEX(mutex);
  67474. +
  67475. +#define IF_NAME "adv7180"
  67476. +#define ADV7180_INPUT_CTL 0x00 /* Input Control */
  67477. +#define ADV7180_STATUS_1 0x10 /* Status #1 */
  67478. +#define ADV7180_BRIGHTNESS 0x0a /* Brightness */
  67479. +#define ADV7180_IDENT 0x11 /* IDENT */
  67480. +#define ADV7180_VSYNC_FIELD_CTL_1 0x31 /* VSYNC Field Control #1 */
  67481. +#define ADV7180_MANUAL_WIN_CTL 0x3d /* Manual Window Control */
  67482. +#define ADV7180_SD_SATURATION_CB 0xe3 /* SD Saturation Cb */
  67483. +#define ADV7180_SD_SATURATION_CR 0xe4 /* SD Saturation Cr */
  67484. +#define ADV7180_PWR_MNG 0x0f /* Power Management */
  67485. +
  67486. +/* supported controls */
  67487. +/* This hasn't been fully implemented yet.
  67488. + * This is how it should work, though. */
  67489. +static struct v4l2_queryctrl adv7180_qctrl[] = {
  67490. + {
  67491. + .id = V4L2_CID_BRIGHTNESS,
  67492. + .type = V4L2_CTRL_TYPE_INTEGER,
  67493. + .name = "Brightness",
  67494. + .minimum = 0, /* check this value */
  67495. + .maximum = 255, /* check this value */
  67496. + .step = 1, /* check this value */
  67497. + .default_value = 127, /* check this value */
  67498. + .flags = 0,
  67499. + }, {
  67500. + .id = V4L2_CID_SATURATION,
  67501. + .type = V4L2_CTRL_TYPE_INTEGER,
  67502. + .name = "Saturation",
  67503. + .minimum = 0, /* check this value */
  67504. + .maximum = 255, /* check this value */
  67505. + .step = 0x1, /* check this value */
  67506. + .default_value = 127, /* check this value */
  67507. + .flags = 0,
  67508. + }
  67509. +};
  67510. +
  67511. +static inline void adv7180_power_down(int enable)
  67512. +{
  67513. + gpio_set_value_cansleep(pwn_gpio, !enable);
  67514. + msleep(2);
  67515. +}
  67516. +
  67517. +static int adv7180_regulator_enable(struct device *dev)
  67518. +{
  67519. + int ret = 0;
  67520. +
  67521. + dvddio_regulator = devm_regulator_get(dev, "DOVDD");
  67522. +
  67523. + if (!IS_ERR(dvddio_regulator)) {
  67524. + regulator_set_voltage(dvddio_regulator,
  67525. + ADV7180_VOLTAGE_DIGITAL_IO,
  67526. + ADV7180_VOLTAGE_DIGITAL_IO);
  67527. + ret = regulator_enable(dvddio_regulator);
  67528. + if (ret) {
  67529. + dev_err(dev, "set io voltage failed\n");
  67530. + return ret;
  67531. + } else {
  67532. + dev_dbg(dev, "set io voltage ok\n");
  67533. + }
  67534. + } else {
  67535. + dev_warn(dev, "cannot get io voltage\n");
  67536. + }
  67537. +
  67538. + dvdd_regulator = devm_regulator_get(dev, "DVDD");
  67539. + if (!IS_ERR(dvdd_regulator)) {
  67540. + regulator_set_voltage(dvdd_regulator,
  67541. + ADV7180_VOLTAGE_DIGITAL_CORE,
  67542. + ADV7180_VOLTAGE_DIGITAL_CORE);
  67543. + ret = regulator_enable(dvdd_regulator);
  67544. + if (ret) {
  67545. + dev_err(dev, "set core voltage failed\n");
  67546. + return ret;
  67547. + } else {
  67548. + dev_dbg(dev, "set core voltage ok\n");
  67549. + }
  67550. + } else {
  67551. + dev_warn(dev, "cannot get core voltage\n");
  67552. + }
  67553. +
  67554. + avdd_regulator = devm_regulator_get(dev, "AVDD");
  67555. + if (!IS_ERR(avdd_regulator)) {
  67556. + regulator_set_voltage(avdd_regulator,
  67557. + ADV7180_VOLTAGE_ANALOG,
  67558. + ADV7180_VOLTAGE_ANALOG);
  67559. + ret = regulator_enable(avdd_regulator);
  67560. + if (ret) {
  67561. + dev_err(dev, "set analog voltage failed\n");
  67562. + return ret;
  67563. + } else {
  67564. + dev_dbg(dev, "set analog voltage ok\n");
  67565. + }
  67566. + } else {
  67567. + dev_warn(dev, "cannot get analog voltage\n");
  67568. + }
  67569. +
  67570. + pvdd_regulator = devm_regulator_get(dev, "PVDD");
  67571. + if (!IS_ERR(pvdd_regulator)) {
  67572. + regulator_set_voltage(pvdd_regulator,
  67573. + ADV7180_VOLTAGE_PLL,
  67574. + ADV7180_VOLTAGE_PLL);
  67575. + ret = regulator_enable(pvdd_regulator);
  67576. + if (ret) {
  67577. + dev_err(dev, "set pll voltage failed\n");
  67578. + return ret;
  67579. + } else {
  67580. + dev_dbg(dev, "set pll voltage ok\n");
  67581. + }
  67582. + } else {
  67583. + dev_warn(dev, "cannot get pll voltage\n");
  67584. + }
  67585. +
  67586. + return ret;
  67587. +}
  67588. +
  67589. +
  67590. +/***********************************************************************
  67591. + * I2C transfert.
  67592. + ***********************************************************************/
  67593. +
  67594. +/*! Read one register from a ADV7180 i2c slave device.
  67595. + *
  67596. + * @param *reg register in the device we wish to access.
  67597. + *
  67598. + * @return 0 if success, an error code otherwise.
  67599. + */
  67600. +static inline int adv7180_read(u8 reg)
  67601. +{
  67602. + int val;
  67603. +
  67604. + val = i2c_smbus_read_byte_data(adv7180_data.sen.i2c_client, reg);
  67605. + if (val < 0) {
  67606. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67607. + "%s:read reg error: reg=%2x\n", __func__, reg);
  67608. + return -1;
  67609. + }
  67610. + return val;
  67611. +}
  67612. +
  67613. +/*! Write one register of a ADV7180 i2c slave device.
  67614. + *
  67615. + * @param *reg register in the device we wish to access.
  67616. + *
  67617. + * @return 0 if success, an error code otherwise.
  67618. + */
  67619. +static int adv7180_write_reg(u8 reg, u8 val)
  67620. +{
  67621. + s32 ret;
  67622. +
  67623. + ret = i2c_smbus_write_byte_data(adv7180_data.sen.i2c_client, reg, val);
  67624. + if (ret < 0) {
  67625. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67626. + "%s:write reg error:reg=%2x,val=%2x\n", __func__,
  67627. + reg, val);
  67628. + return -1;
  67629. + }
  67630. + return 0;
  67631. +}
  67632. +
  67633. +/***********************************************************************
  67634. + * mxc_v4l2_capture interface.
  67635. + ***********************************************************************/
  67636. +
  67637. +/*!
  67638. + * Return attributes of current video standard.
  67639. + * Since this device autodetects the current standard, this function also
  67640. + * sets the values that need to be changed if the standard changes.
  67641. + * There is no set std equivalent function.
  67642. + *
  67643. + * @return None.
  67644. + */
  67645. +static void adv7180_get_std(v4l2_std_id *std)
  67646. +{
  67647. + int tmp;
  67648. + int idx;
  67649. +
  67650. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_get_std\n");
  67651. +
  67652. + /* Read the AD_RESULT to get the detect output video standard */
  67653. + tmp = adv7180_read(ADV7180_STATUS_1) & 0x70;
  67654. +
  67655. + mutex_lock(&mutex);
  67656. + if (tmp == 0x40) {
  67657. + /* PAL */
  67658. + *std = V4L2_STD_PAL;
  67659. + idx = ADV7180_PAL;
  67660. + } else if (tmp == 0) {
  67661. + /*NTSC*/
  67662. + *std = V4L2_STD_NTSC;
  67663. + idx = ADV7180_NTSC;
  67664. + } else {
  67665. + *std = V4L2_STD_ALL;
  67666. + idx = ADV7180_NOT_LOCKED;
  67667. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67668. + "Got invalid video standard!\n");
  67669. + }
  67670. + mutex_unlock(&mutex);
  67671. +
  67672. + /* This assumes autodetect which this device uses. */
  67673. + if (*std != adv7180_data.std_id) {
  67674. + video_idx = idx;
  67675. + adv7180_data.std_id = *std;
  67676. + adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
  67677. + adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
  67678. + }
  67679. +}
  67680. +
  67681. +/***********************************************************************
  67682. + * IOCTL Functions from v4l2_int_ioctl_desc.
  67683. + ***********************************************************************/
  67684. +
  67685. +/*!
  67686. + * ioctl_g_ifparm - V4L2 sensor interface handler for vidioc_int_g_ifparm_num
  67687. + * s: pointer to standard V4L2 device structure
  67688. + * p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
  67689. + *
  67690. + * Gets slave interface parameters.
  67691. + * Calculates the required xclk value to support the requested
  67692. + * clock parameters in p. This value is returned in the p
  67693. + * parameter.
  67694. + *
  67695. + * vidioc_int_g_ifparm returns platform-specific information about the
  67696. + * interface settings used by the sensor.
  67697. + *
  67698. + * Called on open.
  67699. + */
  67700. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  67701. +{
  67702. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
  67703. +
  67704. + if (s == NULL) {
  67705. + pr_err(" ERROR!! no slave device set!\n");
  67706. + return -1;
  67707. + }
  67708. +
  67709. + /* Initialize structure to 0s then set any non-0 values. */
  67710. + memset(p, 0, sizeof(*p));
  67711. + p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
  67712. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  67713. + p->u.bt656.nobt_hs_inv = 1;
  67714. + p->u.bt656.bt_sync_correct = 1;
  67715. +
  67716. + /* ADV7180 has a dedicated clock so no clock settings needed. */
  67717. +
  67718. + return 0;
  67719. +}
  67720. +
  67721. +/*!
  67722. + * Sets the camera power.
  67723. + *
  67724. + * s pointer to the camera device
  67725. + * on if 1, power is to be turned on. 0 means power is to be turned off
  67726. + *
  67727. + * ioctl_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
  67728. + * @s: pointer to standard V4L2 device structure
  67729. + * @on: power state to which device is to be set
  67730. + *
  67731. + * Sets devices power state to requrested state, if possible.
  67732. + * This is called on open, close, suspend and resume.
  67733. + */
  67734. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  67735. +{
  67736. + struct sensor *sensor = s->priv;
  67737. +
  67738. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_s_power\n");
  67739. +
  67740. + if (on && !sensor->sen.on) {
  67741. + if (adv7180_write_reg(ADV7180_PWR_MNG, 0x04) != 0)
  67742. + return -EIO;
  67743. +
  67744. + /*
  67745. + * FIXME:Additional 400ms to wait the chip to be stable?
  67746. + * This is a workaround for preview scrolling issue.
  67747. + */
  67748. + msleep(400);
  67749. + } else if (!on && sensor->sen.on) {
  67750. + if (adv7180_write_reg(ADV7180_PWR_MNG, 0x24) != 0)
  67751. + return -EIO;
  67752. + }
  67753. +
  67754. + sensor->sen.on = on;
  67755. +
  67756. + return 0;
  67757. +}
  67758. +
  67759. +/*!
  67760. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  67761. + * @s: pointer to standard V4L2 device structure
  67762. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  67763. + *
  67764. + * Returns the sensor's video CAPTURE parameters.
  67765. + */
  67766. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  67767. +{
  67768. + struct sensor *sensor = s->priv;
  67769. + struct v4l2_captureparm *cparm = &a->parm.capture;
  67770. +
  67771. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_parm\n");
  67772. +
  67773. + switch (a->type) {
  67774. + /* These are all the possible cases. */
  67775. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  67776. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  67777. + memset(a, 0, sizeof(*a));
  67778. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  67779. + cparm->capability = sensor->sen.streamcap.capability;
  67780. + cparm->timeperframe = sensor->sen.streamcap.timeperframe;
  67781. + cparm->capturemode = sensor->sen.streamcap.capturemode;
  67782. + break;
  67783. +
  67784. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  67785. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  67786. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  67787. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  67788. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  67789. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  67790. + break;
  67791. +
  67792. + default:
  67793. + pr_debug("ioctl_g_parm:type is unknown %d\n", a->type);
  67794. + break;
  67795. + }
  67796. +
  67797. + return 0;
  67798. +}
  67799. +
  67800. +/*!
  67801. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  67802. + * @s: pointer to standard V4L2 device structure
  67803. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  67804. + *
  67805. + * Configures the sensor to use the input parameters, if possible. If
  67806. + * not possible, reverts to the old parameters and returns the
  67807. + * appropriate error code.
  67808. + *
  67809. + * This driver cannot change these settings.
  67810. + */
  67811. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  67812. +{
  67813. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_parm\n");
  67814. +
  67815. + switch (a->type) {
  67816. + /* These are all the possible cases. */
  67817. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  67818. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  67819. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  67820. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  67821. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  67822. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  67823. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  67824. + break;
  67825. +
  67826. + default:
  67827. + pr_debug(" type is unknown - %d\n", a->type);
  67828. + break;
  67829. + }
  67830. +
  67831. + return 0;
  67832. +}
  67833. +
  67834. +/*!
  67835. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  67836. + * @s: pointer to standard V4L2 device structure
  67837. + * @f: pointer to standard V4L2 v4l2_format structure
  67838. + *
  67839. + * Returns the sensor's current pixel format in the v4l2_format
  67840. + * parameter.
  67841. + */
  67842. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  67843. +{
  67844. + struct sensor *sensor = s->priv;
  67845. +
  67846. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_fmt_cap\n");
  67847. +
  67848. + switch (f->type) {
  67849. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  67850. + pr_debug(" Returning size of %dx%d\n",
  67851. + sensor->sen.pix.width, sensor->sen.pix.height);
  67852. + f->fmt.pix = sensor->sen.pix;
  67853. + break;
  67854. +
  67855. + case V4L2_BUF_TYPE_PRIVATE: {
  67856. + v4l2_std_id std;
  67857. + adv7180_get_std(&std);
  67858. + f->fmt.pix.pixelformat = (u32)std;
  67859. + }
  67860. + break;
  67861. +
  67862. + default:
  67863. + f->fmt.pix = sensor->sen.pix;
  67864. + break;
  67865. + }
  67866. +
  67867. + return 0;
  67868. +}
  67869. +
  67870. +/*!
  67871. + * ioctl_queryctrl - V4L2 sensor interface handler for VIDIOC_QUERYCTRL ioctl
  67872. + * @s: pointer to standard V4L2 device structure
  67873. + * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
  67874. + *
  67875. + * If the requested control is supported, returns the control information
  67876. + * from the video_control[] array. Otherwise, returns -EINVAL if the
  67877. + * control is not supported.
  67878. + */
  67879. +static int ioctl_queryctrl(struct v4l2_int_device *s,
  67880. + struct v4l2_queryctrl *qc)
  67881. +{
  67882. + int i;
  67883. +
  67884. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_queryctrl\n");
  67885. +
  67886. + for (i = 0; i < ARRAY_SIZE(adv7180_qctrl); i++)
  67887. + if (qc->id && qc->id == adv7180_qctrl[i].id) {
  67888. + memcpy(qc, &(adv7180_qctrl[i]),
  67889. + sizeof(*qc));
  67890. + return 0;
  67891. + }
  67892. +
  67893. + return -EINVAL;
  67894. +}
  67895. +
  67896. +/*!
  67897. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  67898. + * @s: pointer to standard V4L2 device structure
  67899. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  67900. + *
  67901. + * If the requested control is supported, returns the control's current
  67902. + * value from the video_control[] array. Otherwise, returns -EINVAL
  67903. + * if the control is not supported.
  67904. + */
  67905. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  67906. +{
  67907. + int ret = 0;
  67908. + int sat = 0;
  67909. +
  67910. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_ctrl\n");
  67911. +
  67912. + switch (vc->id) {
  67913. + case V4L2_CID_BRIGHTNESS:
  67914. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67915. + " V4L2_CID_BRIGHTNESS\n");
  67916. + adv7180_data.sen.brightness = adv7180_read(ADV7180_BRIGHTNESS);
  67917. + vc->value = adv7180_data.sen.brightness;
  67918. + break;
  67919. + case V4L2_CID_CONTRAST:
  67920. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67921. + " V4L2_CID_CONTRAST\n");
  67922. + vc->value = adv7180_data.sen.contrast;
  67923. + break;
  67924. + case V4L2_CID_SATURATION:
  67925. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67926. + " V4L2_CID_SATURATION\n");
  67927. + sat = adv7180_read(ADV7180_SD_SATURATION_CB);
  67928. + adv7180_data.sen.saturation = sat;
  67929. + vc->value = adv7180_data.sen.saturation;
  67930. + break;
  67931. + case V4L2_CID_HUE:
  67932. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67933. + " V4L2_CID_HUE\n");
  67934. + vc->value = adv7180_data.sen.hue;
  67935. + break;
  67936. + case V4L2_CID_AUTO_WHITE_BALANCE:
  67937. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67938. + " V4L2_CID_AUTO_WHITE_BALANCE\n");
  67939. + break;
  67940. + case V4L2_CID_DO_WHITE_BALANCE:
  67941. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67942. + " V4L2_CID_DO_WHITE_BALANCE\n");
  67943. + break;
  67944. + case V4L2_CID_RED_BALANCE:
  67945. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67946. + " V4L2_CID_RED_BALANCE\n");
  67947. + vc->value = adv7180_data.sen.red;
  67948. + break;
  67949. + case V4L2_CID_BLUE_BALANCE:
  67950. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67951. + " V4L2_CID_BLUE_BALANCE\n");
  67952. + vc->value = adv7180_data.sen.blue;
  67953. + break;
  67954. + case V4L2_CID_GAMMA:
  67955. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67956. + " V4L2_CID_GAMMA\n");
  67957. + break;
  67958. + case V4L2_CID_EXPOSURE:
  67959. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67960. + " V4L2_CID_EXPOSURE\n");
  67961. + vc->value = adv7180_data.sen.ae_mode;
  67962. + break;
  67963. + case V4L2_CID_AUTOGAIN:
  67964. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67965. + " V4L2_CID_AUTOGAIN\n");
  67966. + break;
  67967. + case V4L2_CID_GAIN:
  67968. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67969. + " V4L2_CID_GAIN\n");
  67970. + break;
  67971. + case V4L2_CID_HFLIP:
  67972. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67973. + " V4L2_CID_HFLIP\n");
  67974. + break;
  67975. + case V4L2_CID_VFLIP:
  67976. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67977. + " V4L2_CID_VFLIP\n");
  67978. + break;
  67979. + default:
  67980. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  67981. + " Default case\n");
  67982. + vc->value = 0;
  67983. + ret = -EPERM;
  67984. + break;
  67985. + }
  67986. +
  67987. + return ret;
  67988. +}
  67989. +
  67990. +/*!
  67991. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  67992. + * @s: pointer to standard V4L2 device structure
  67993. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  67994. + *
  67995. + * If the requested control is supported, sets the control's current
  67996. + * value in HW (and updates the video_control[] array). Otherwise,
  67997. + * returns -EINVAL if the control is not supported.
  67998. + */
  67999. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  68000. +{
  68001. + int retval = 0;
  68002. + u8 tmp;
  68003. +
  68004. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_ctrl\n");
  68005. +
  68006. + switch (vc->id) {
  68007. + case V4L2_CID_BRIGHTNESS:
  68008. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68009. + " V4L2_CID_BRIGHTNESS\n");
  68010. + tmp = vc->value;
  68011. + adv7180_write_reg(ADV7180_BRIGHTNESS, tmp);
  68012. + adv7180_data.sen.brightness = vc->value;
  68013. + break;
  68014. + case V4L2_CID_CONTRAST:
  68015. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68016. + " V4L2_CID_CONTRAST\n");
  68017. + break;
  68018. + case V4L2_CID_SATURATION:
  68019. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68020. + " V4L2_CID_SATURATION\n");
  68021. + tmp = vc->value;
  68022. + adv7180_write_reg(ADV7180_SD_SATURATION_CB, tmp);
  68023. + adv7180_write_reg(ADV7180_SD_SATURATION_CR, tmp);
  68024. + adv7180_data.sen.saturation = vc->value;
  68025. + break;
  68026. + case V4L2_CID_HUE:
  68027. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68028. + " V4L2_CID_HUE\n");
  68029. + break;
  68030. + case V4L2_CID_AUTO_WHITE_BALANCE:
  68031. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68032. + " V4L2_CID_AUTO_WHITE_BALANCE\n");
  68033. + break;
  68034. + case V4L2_CID_DO_WHITE_BALANCE:
  68035. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68036. + " V4L2_CID_DO_WHITE_BALANCE\n");
  68037. + break;
  68038. + case V4L2_CID_RED_BALANCE:
  68039. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68040. + " V4L2_CID_RED_BALANCE\n");
  68041. + break;
  68042. + case V4L2_CID_BLUE_BALANCE:
  68043. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68044. + " V4L2_CID_BLUE_BALANCE\n");
  68045. + break;
  68046. + case V4L2_CID_GAMMA:
  68047. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68048. + " V4L2_CID_GAMMA\n");
  68049. + break;
  68050. + case V4L2_CID_EXPOSURE:
  68051. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68052. + " V4L2_CID_EXPOSURE\n");
  68053. + break;
  68054. + case V4L2_CID_AUTOGAIN:
  68055. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68056. + " V4L2_CID_AUTOGAIN\n");
  68057. + break;
  68058. + case V4L2_CID_GAIN:
  68059. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68060. + " V4L2_CID_GAIN\n");
  68061. + break;
  68062. + case V4L2_CID_HFLIP:
  68063. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68064. + " V4L2_CID_HFLIP\n");
  68065. + break;
  68066. + case V4L2_CID_VFLIP:
  68067. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68068. + " V4L2_CID_VFLIP\n");
  68069. + break;
  68070. + default:
  68071. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68072. + " Default case\n");
  68073. + retval = -EPERM;
  68074. + break;
  68075. + }
  68076. +
  68077. + return retval;
  68078. +}
  68079. +
  68080. +/*!
  68081. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  68082. + * VIDIOC_ENUM_FRAMESIZES ioctl
  68083. + * @s: pointer to standard V4L2 device structure
  68084. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  68085. + *
  68086. + * Return 0 if successful, otherwise -EINVAL.
  68087. + */
  68088. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  68089. + struct v4l2_frmsizeenum *fsize)
  68090. +{
  68091. + if (fsize->index >= 1)
  68092. + return -EINVAL;
  68093. +
  68094. + fsize->discrete.width = video_fmts[video_idx].active_width;
  68095. + fsize->discrete.height = video_fmts[video_idx].active_height;
  68096. +
  68097. + return 0;
  68098. +}
  68099. +
  68100. +/*!
  68101. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  68102. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  68103. + * @s: pointer to standard V4L2 device structure
  68104. + * @id: pointer to int
  68105. + *
  68106. + * Return 0.
  68107. + */
  68108. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  68109. +{
  68110. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  68111. + V4L2_CHIP_MATCH_I2C_DRIVER;
  68112. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
  68113. + "adv7180_decoder");
  68114. + ((struct v4l2_dbg_chip_ident *)id)->ident = V4L2_IDENT_ADV7180;
  68115. +
  68116. + return 0;
  68117. +}
  68118. +
  68119. +/*!
  68120. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  68121. + * @s: pointer to standard V4L2 device structure
  68122. + */
  68123. +static int ioctl_init(struct v4l2_int_device *s)
  68124. +{
  68125. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_init\n");
  68126. + return 0;
  68127. +}
  68128. +
  68129. +/*!
  68130. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  68131. + * @s: pointer to standard V4L2 device structure
  68132. + *
  68133. + * Initialise the device when slave attaches to the master.
  68134. + */
  68135. +static int ioctl_dev_init(struct v4l2_int_device *s)
  68136. +{
  68137. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_dev_init\n");
  68138. + return 0;
  68139. +}
  68140. +
  68141. +/*!
  68142. + * This structure defines all the ioctls for this module.
  68143. + */
  68144. +static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = {
  68145. +
  68146. + {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*)ioctl_dev_init},
  68147. +
  68148. + /*!
  68149. + * Delinitialise the dev. at slave detach.
  68150. + * The complement of ioctl_dev_init.
  68151. + */
  68152. +/* {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func *)ioctl_dev_exit}, */
  68153. +
  68154. + {vidioc_int_s_power_num, (v4l2_int_ioctl_func*)ioctl_s_power},
  68155. + {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*)ioctl_g_ifparm},
  68156. +/* {vidioc_int_g_needs_reset_num,
  68157. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
  68158. +/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
  68159. + {vidioc_int_init_num, (v4l2_int_ioctl_func*)ioctl_init},
  68160. +
  68161. + /*!
  68162. + * VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
  68163. + */
  68164. +/* {vidioc_int_enum_fmt_cap_num,
  68165. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
  68166. +
  68167. + /*!
  68168. + * VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.
  68169. + * This ioctl is used to negotiate the image capture size and
  68170. + * pixel format without actually making it take effect.
  68171. + */
  68172. +/* {vidioc_int_try_fmt_cap_num,
  68173. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
  68174. +
  68175. + {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func*)ioctl_g_fmt_cap},
  68176. +
  68177. + /*!
  68178. + * If the requested format is supported, configures the HW to use that
  68179. + * format, returns error code if format not supported or HW can't be
  68180. + * correctly configured.
  68181. + */
  68182. +/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */
  68183. +
  68184. + {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm},
  68185. + {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
  68186. + {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func*)ioctl_queryctrl},
  68187. + {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
  68188. + {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
  68189. + {vidioc_int_enum_framesizes_num,
  68190. + (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
  68191. + {vidioc_int_g_chip_ident_num,
  68192. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident},
  68193. +};
  68194. +
  68195. +static struct v4l2_int_slave adv7180_slave = {
  68196. + .ioctls = adv7180_ioctl_desc,
  68197. + .num_ioctls = ARRAY_SIZE(adv7180_ioctl_desc),
  68198. +};
  68199. +
  68200. +static struct v4l2_int_device adv7180_int_device = {
  68201. + .module = THIS_MODULE,
  68202. + .name = "adv7180",
  68203. + .type = v4l2_int_type_slave,
  68204. + .u = {
  68205. + .slave = &adv7180_slave,
  68206. + },
  68207. +};
  68208. +
  68209. +
  68210. +/***********************************************************************
  68211. + * I2C client and driver.
  68212. + ***********************************************************************/
  68213. +
  68214. +/*! ADV7180 Reset function.
  68215. + *
  68216. + * @return None.
  68217. + */
  68218. +static void adv7180_hard_reset(bool cvbs)
  68219. +{
  68220. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68221. + "In adv7180:adv7180_hard_reset\n");
  68222. +
  68223. + if (cvbs) {
  68224. + /* Set CVBS input on AIN1 */
  68225. + adv7180_write_reg(ADV7180_INPUT_CTL, 0x00);
  68226. + } else {
  68227. + /*
  68228. + * Set YPbPr input on AIN1,4,5 and normal
  68229. + * operations(autodection of all stds).
  68230. + */
  68231. + adv7180_write_reg(ADV7180_INPUT_CTL, 0x09);
  68232. + }
  68233. +
  68234. + /* Datasheet recommends */
  68235. + adv7180_write_reg(0x01, 0xc8);
  68236. + adv7180_write_reg(0x02, 0x04);
  68237. + adv7180_write_reg(0x03, 0x00);
  68238. + adv7180_write_reg(0x04, 0x45);
  68239. + adv7180_write_reg(0x05, 0x00);
  68240. + adv7180_write_reg(0x06, 0x02);
  68241. + adv7180_write_reg(0x07, 0x7F);
  68242. + adv7180_write_reg(0x08, 0x80);
  68243. + adv7180_write_reg(0x0A, 0x00);
  68244. + adv7180_write_reg(0x0B, 0x00);
  68245. + adv7180_write_reg(0x0C, 0x36);
  68246. + adv7180_write_reg(0x0D, 0x7C);
  68247. + adv7180_write_reg(0x0E, 0x00);
  68248. + adv7180_write_reg(0x0F, 0x00);
  68249. + adv7180_write_reg(0x13, 0x00);
  68250. + adv7180_write_reg(0x14, 0x12);
  68251. + adv7180_write_reg(0x15, 0x00);
  68252. + adv7180_write_reg(0x16, 0x00);
  68253. + adv7180_write_reg(0x17, 0x01);
  68254. + adv7180_write_reg(0x18, 0x93);
  68255. + adv7180_write_reg(0xF1, 0x19);
  68256. + adv7180_write_reg(0x1A, 0x00);
  68257. + adv7180_write_reg(0x1B, 0x00);
  68258. + adv7180_write_reg(0x1C, 0x00);
  68259. + adv7180_write_reg(0x1D, 0x40);
  68260. + adv7180_write_reg(0x1E, 0x00);
  68261. + adv7180_write_reg(0x1F, 0x00);
  68262. + adv7180_write_reg(0x20, 0x00);
  68263. + adv7180_write_reg(0x21, 0x00);
  68264. + adv7180_write_reg(0x22, 0x00);
  68265. + adv7180_write_reg(0x23, 0xC0);
  68266. + adv7180_write_reg(0x24, 0x00);
  68267. + adv7180_write_reg(0x25, 0x00);
  68268. + adv7180_write_reg(0x26, 0x00);
  68269. + adv7180_write_reg(0x27, 0x58);
  68270. + adv7180_write_reg(0x28, 0x00);
  68271. + adv7180_write_reg(0x29, 0x00);
  68272. + adv7180_write_reg(0x2A, 0x00);
  68273. + adv7180_write_reg(0x2B, 0xE1);
  68274. + adv7180_write_reg(0x2C, 0xAE);
  68275. + adv7180_write_reg(0x2D, 0xF4);
  68276. + adv7180_write_reg(0x2E, 0x00);
  68277. + adv7180_write_reg(0x2F, 0xF0);
  68278. + adv7180_write_reg(0x30, 0x00);
  68279. + adv7180_write_reg(0x31, 0x12);
  68280. + adv7180_write_reg(0x32, 0x41);
  68281. + adv7180_write_reg(0x33, 0x84);
  68282. + adv7180_write_reg(0x34, 0x00);
  68283. + adv7180_write_reg(0x35, 0x02);
  68284. + adv7180_write_reg(0x36, 0x00);
  68285. + adv7180_write_reg(0x37, 0x01);
  68286. + adv7180_write_reg(0x38, 0x80);
  68287. + adv7180_write_reg(0x39, 0xC0);
  68288. + adv7180_write_reg(0x3A, 0x10);
  68289. + adv7180_write_reg(0x3B, 0x05);
  68290. + adv7180_write_reg(0x3C, 0x58);
  68291. + adv7180_write_reg(0x3D, 0xB2);
  68292. + adv7180_write_reg(0x3E, 0x64);
  68293. + adv7180_write_reg(0x3F, 0xE4);
  68294. + adv7180_write_reg(0x40, 0x90);
  68295. + adv7180_write_reg(0x41, 0x01);
  68296. + adv7180_write_reg(0x42, 0x7E);
  68297. + adv7180_write_reg(0x43, 0xA4);
  68298. + adv7180_write_reg(0x44, 0xFF);
  68299. + adv7180_write_reg(0x45, 0xB6);
  68300. + adv7180_write_reg(0x46, 0x12);
  68301. + adv7180_write_reg(0x48, 0x00);
  68302. + adv7180_write_reg(0x49, 0x00);
  68303. + adv7180_write_reg(0x4A, 0x00);
  68304. + adv7180_write_reg(0x4B, 0x00);
  68305. + adv7180_write_reg(0x4C, 0x00);
  68306. + adv7180_write_reg(0x4D, 0xEF);
  68307. + adv7180_write_reg(0x4E, 0x08);
  68308. + adv7180_write_reg(0x4F, 0x08);
  68309. + adv7180_write_reg(0x50, 0x08);
  68310. + adv7180_write_reg(0x51, 0x24);
  68311. + adv7180_write_reg(0x52, 0x0B);
  68312. + adv7180_write_reg(0x53, 0x4E);
  68313. + adv7180_write_reg(0x54, 0x80);
  68314. + adv7180_write_reg(0x55, 0x00);
  68315. + adv7180_write_reg(0x56, 0x10);
  68316. + adv7180_write_reg(0x57, 0x00);
  68317. + adv7180_write_reg(0x58, 0x00);
  68318. + adv7180_write_reg(0x59, 0x00);
  68319. + adv7180_write_reg(0x5A, 0x00);
  68320. + adv7180_write_reg(0x5B, 0x00);
  68321. + adv7180_write_reg(0x5C, 0x00);
  68322. + adv7180_write_reg(0x5D, 0x00);
  68323. + adv7180_write_reg(0x5E, 0x00);
  68324. + adv7180_write_reg(0x5F, 0x00);
  68325. + adv7180_write_reg(0x60, 0x00);
  68326. + adv7180_write_reg(0x61, 0x00);
  68327. + adv7180_write_reg(0x62, 0x20);
  68328. + adv7180_write_reg(0x63, 0x00);
  68329. + adv7180_write_reg(0x64, 0x00);
  68330. + adv7180_write_reg(0x65, 0x00);
  68331. + adv7180_write_reg(0x66, 0x00);
  68332. + adv7180_write_reg(0x67, 0x03);
  68333. + adv7180_write_reg(0x68, 0x01);
  68334. + adv7180_write_reg(0x69, 0x00);
  68335. + adv7180_write_reg(0x6A, 0x00);
  68336. + adv7180_write_reg(0x6B, 0xC0);
  68337. + adv7180_write_reg(0x6C, 0x00);
  68338. + adv7180_write_reg(0x6D, 0x00);
  68339. + adv7180_write_reg(0x6E, 0x00);
  68340. + adv7180_write_reg(0x6F, 0x00);
  68341. + adv7180_write_reg(0x70, 0x00);
  68342. + adv7180_write_reg(0x71, 0x00);
  68343. + adv7180_write_reg(0x72, 0x00);
  68344. + adv7180_write_reg(0x73, 0x10);
  68345. + adv7180_write_reg(0x74, 0x04);
  68346. + adv7180_write_reg(0x75, 0x01);
  68347. + adv7180_write_reg(0x76, 0x00);
  68348. + adv7180_write_reg(0x77, 0x3F);
  68349. + adv7180_write_reg(0x78, 0xFF);
  68350. + adv7180_write_reg(0x79, 0xFF);
  68351. + adv7180_write_reg(0x7A, 0xFF);
  68352. + adv7180_write_reg(0x7B, 0x1E);
  68353. + adv7180_write_reg(0x7C, 0xC0);
  68354. + adv7180_write_reg(0x7D, 0x00);
  68355. + adv7180_write_reg(0x7E, 0x00);
  68356. + adv7180_write_reg(0x7F, 0x00);
  68357. + adv7180_write_reg(0x80, 0x00);
  68358. + adv7180_write_reg(0x81, 0xC0);
  68359. + adv7180_write_reg(0x82, 0x04);
  68360. + adv7180_write_reg(0x83, 0x00);
  68361. + adv7180_write_reg(0x84, 0x0C);
  68362. + adv7180_write_reg(0x85, 0x02);
  68363. + adv7180_write_reg(0x86, 0x03);
  68364. + adv7180_write_reg(0x87, 0x63);
  68365. + adv7180_write_reg(0x88, 0x5A);
  68366. + adv7180_write_reg(0x89, 0x08);
  68367. + adv7180_write_reg(0x8A, 0x10);
  68368. + adv7180_write_reg(0x8B, 0x00);
  68369. + adv7180_write_reg(0x8C, 0x40);
  68370. + adv7180_write_reg(0x8D, 0x00);
  68371. + adv7180_write_reg(0x8E, 0x40);
  68372. + adv7180_write_reg(0x8F, 0x00);
  68373. + adv7180_write_reg(0x90, 0x00);
  68374. + adv7180_write_reg(0x91, 0x50);
  68375. + adv7180_write_reg(0x92, 0x00);
  68376. + adv7180_write_reg(0x93, 0x00);
  68377. + adv7180_write_reg(0x94, 0x00);
  68378. + adv7180_write_reg(0x95, 0x00);
  68379. + adv7180_write_reg(0x96, 0x00);
  68380. + adv7180_write_reg(0x97, 0xF0);
  68381. + adv7180_write_reg(0x98, 0x00);
  68382. + adv7180_write_reg(0x99, 0x00);
  68383. + adv7180_write_reg(0x9A, 0x00);
  68384. + adv7180_write_reg(0x9B, 0x00);
  68385. + adv7180_write_reg(0x9C, 0x00);
  68386. + adv7180_write_reg(0x9D, 0x00);
  68387. + adv7180_write_reg(0x9E, 0x00);
  68388. + adv7180_write_reg(0x9F, 0x00);
  68389. + adv7180_write_reg(0xA0, 0x00);
  68390. + adv7180_write_reg(0xA1, 0x00);
  68391. + adv7180_write_reg(0xA2, 0x00);
  68392. + adv7180_write_reg(0xA3, 0x00);
  68393. + adv7180_write_reg(0xA4, 0x00);
  68394. + adv7180_write_reg(0xA5, 0x00);
  68395. + adv7180_write_reg(0xA6, 0x00);
  68396. + adv7180_write_reg(0xA7, 0x00);
  68397. + adv7180_write_reg(0xA8, 0x00);
  68398. + adv7180_write_reg(0xA9, 0x00);
  68399. + adv7180_write_reg(0xAA, 0x00);
  68400. + adv7180_write_reg(0xAB, 0x00);
  68401. + adv7180_write_reg(0xAC, 0x00);
  68402. + adv7180_write_reg(0xAD, 0x00);
  68403. + adv7180_write_reg(0xAE, 0x60);
  68404. + adv7180_write_reg(0xAF, 0x00);
  68405. + adv7180_write_reg(0xB0, 0x00);
  68406. + adv7180_write_reg(0xB1, 0x60);
  68407. + adv7180_write_reg(0xB2, 0x1C);
  68408. + adv7180_write_reg(0xB3, 0x54);
  68409. + adv7180_write_reg(0xB4, 0x00);
  68410. + adv7180_write_reg(0xB5, 0x00);
  68411. + adv7180_write_reg(0xB6, 0x00);
  68412. + adv7180_write_reg(0xB7, 0x13);
  68413. + adv7180_write_reg(0xB8, 0x03);
  68414. + adv7180_write_reg(0xB9, 0x33);
  68415. + adv7180_write_reg(0xBF, 0x02);
  68416. + adv7180_write_reg(0xC0, 0x00);
  68417. + adv7180_write_reg(0xC1, 0x00);
  68418. + adv7180_write_reg(0xC2, 0x00);
  68419. + adv7180_write_reg(0xC3, 0x00);
  68420. + adv7180_write_reg(0xC4, 0x00);
  68421. + adv7180_write_reg(0xC5, 0x81);
  68422. + adv7180_write_reg(0xC6, 0x00);
  68423. + adv7180_write_reg(0xC7, 0x00);
  68424. + adv7180_write_reg(0xC8, 0x00);
  68425. + adv7180_write_reg(0xC9, 0x04);
  68426. + adv7180_write_reg(0xCC, 0x69);
  68427. + adv7180_write_reg(0xCD, 0x00);
  68428. + adv7180_write_reg(0xCE, 0x01);
  68429. + adv7180_write_reg(0xCF, 0xB4);
  68430. + adv7180_write_reg(0xD0, 0x00);
  68431. + adv7180_write_reg(0xD1, 0x10);
  68432. + adv7180_write_reg(0xD2, 0xFF);
  68433. + adv7180_write_reg(0xD3, 0xFF);
  68434. + adv7180_write_reg(0xD4, 0x7F);
  68435. + adv7180_write_reg(0xD5, 0x7F);
  68436. + adv7180_write_reg(0xD6, 0x3E);
  68437. + adv7180_write_reg(0xD7, 0x08);
  68438. + adv7180_write_reg(0xD8, 0x3C);
  68439. + adv7180_write_reg(0xD9, 0x08);
  68440. + adv7180_write_reg(0xDA, 0x3C);
  68441. + adv7180_write_reg(0xDB, 0x9B);
  68442. + adv7180_write_reg(0xDC, 0xAC);
  68443. + adv7180_write_reg(0xDD, 0x4C);
  68444. + adv7180_write_reg(0xDE, 0x00);
  68445. + adv7180_write_reg(0xDF, 0x00);
  68446. + adv7180_write_reg(0xE0, 0x14);
  68447. + adv7180_write_reg(0xE1, 0x80);
  68448. + adv7180_write_reg(0xE2, 0x80);
  68449. + adv7180_write_reg(0xE3, 0x80);
  68450. + adv7180_write_reg(0xE4, 0x80);
  68451. + adv7180_write_reg(0xE5, 0x25);
  68452. + adv7180_write_reg(0xE6, 0x44);
  68453. + adv7180_write_reg(0xE7, 0x63);
  68454. + adv7180_write_reg(0xE8, 0x65);
  68455. + adv7180_write_reg(0xE9, 0x14);
  68456. + adv7180_write_reg(0xEA, 0x63);
  68457. + adv7180_write_reg(0xEB, 0x55);
  68458. + adv7180_write_reg(0xEC, 0x55);
  68459. + adv7180_write_reg(0xEE, 0x00);
  68460. + adv7180_write_reg(0xEF, 0x4A);
  68461. + adv7180_write_reg(0xF0, 0x44);
  68462. + adv7180_write_reg(0xF1, 0x0C);
  68463. + adv7180_write_reg(0xF2, 0x32);
  68464. + adv7180_write_reg(0xF3, 0x00);
  68465. + adv7180_write_reg(0xF4, 0x3F);
  68466. + adv7180_write_reg(0xF5, 0xE0);
  68467. + adv7180_write_reg(0xF6, 0x69);
  68468. + adv7180_write_reg(0xF7, 0x10);
  68469. + adv7180_write_reg(0xF8, 0x00);
  68470. + adv7180_write_reg(0xF9, 0x03);
  68471. + adv7180_write_reg(0xFA, 0xFA);
  68472. + adv7180_write_reg(0xFB, 0x40);
  68473. +}
  68474. +
  68475. +/*! ADV7180 I2C attach function.
  68476. + *
  68477. + * @param *adapter struct i2c_adapter *.
  68478. + *
  68479. + * @return Error code indicating success or failure.
  68480. + */
  68481. +
  68482. +/*!
  68483. + * ADV7180 I2C probe function.
  68484. + * Function set in i2c_driver struct.
  68485. + * Called by insmod.
  68486. + *
  68487. + * @param *adapter I2C adapter descriptor.
  68488. + *
  68489. + * @return Error code indicating success or failure.
  68490. + */
  68491. +static int adv7180_probe(struct i2c_client *client,
  68492. + const struct i2c_device_id *id)
  68493. +{
  68494. + int rev_id;
  68495. + int ret = 0;
  68496. + u32 cvbs = true;
  68497. + struct pinctrl *pinctrl;
  68498. + struct device *dev = &client->dev;
  68499. +
  68500. + printk(KERN_ERR"DBG sensor data is at %p\n", &adv7180_data);
  68501. +
  68502. + /* ov5640 pinctrl */
  68503. + pinctrl = devm_pinctrl_get_select_default(dev);
  68504. + if (IS_ERR(pinctrl)) {
  68505. + dev_err(dev, "setup pinctrl failed\n");
  68506. + return PTR_ERR(pinctrl);
  68507. + }
  68508. +
  68509. + /* request power down pin */
  68510. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  68511. + if (!gpio_is_valid(pwn_gpio)) {
  68512. + dev_err(dev, "no sensor pwdn pin available\n");
  68513. + return -ENODEV;
  68514. + }
  68515. + ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  68516. + "adv7180_pwdn");
  68517. + if (ret < 0) {
  68518. + dev_err(dev, "no power pin available!\n");
  68519. + return ret;
  68520. + }
  68521. +
  68522. + adv7180_regulator_enable(dev);
  68523. +
  68524. + adv7180_power_down(0);
  68525. +
  68526. + msleep(1);
  68527. +
  68528. + /* Set initial values for the sensor struct. */
  68529. + memset(&adv7180_data, 0, sizeof(adv7180_data));
  68530. + adv7180_data.sen.i2c_client = client;
  68531. + adv7180_data.sen.streamcap.timeperframe.denominator = 30;
  68532. + adv7180_data.sen.streamcap.timeperframe.numerator = 1;
  68533. + adv7180_data.std_id = V4L2_STD_ALL;
  68534. + video_idx = ADV7180_NOT_LOCKED;
  68535. + adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
  68536. + adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
  68537. + adv7180_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
  68538. + adv7180_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
  68539. + adv7180_data.sen.on = true;
  68540. +
  68541. + adv7180_data.sen.sensor_clk = devm_clk_get(dev, "csi_mclk");
  68542. + if (IS_ERR(adv7180_data.sen.sensor_clk)) {
  68543. + dev_err(dev, "get mclk failed\n");
  68544. + return PTR_ERR(adv7180_data.sen.sensor_clk);
  68545. + }
  68546. +
  68547. + ret = of_property_read_u32(dev->of_node, "mclk",
  68548. + &adv7180_data.sen.mclk);
  68549. + if (ret) {
  68550. + dev_err(dev, "mclk frequency is invalid\n");
  68551. + return ret;
  68552. + }
  68553. +
  68554. + ret = of_property_read_u32(
  68555. + dev->of_node, "mclk_source",
  68556. + (u32 *) &(adv7180_data.sen.mclk_source));
  68557. + if (ret) {
  68558. + dev_err(dev, "mclk_source invalid\n");
  68559. + return ret;
  68560. + }
  68561. +
  68562. + ret = of_property_read_u32(dev->of_node, "csi_id",
  68563. + &(adv7180_data.sen.csi));
  68564. + if (ret) {
  68565. + dev_err(dev, "csi_id invalid\n");
  68566. + return ret;
  68567. + }
  68568. +
  68569. + clk_prepare_enable(adv7180_data.sen.sensor_clk);
  68570. +
  68571. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68572. + "%s:adv7180 probe i2c address is 0x%02X\n",
  68573. + __func__, adv7180_data.sen.i2c_client->addr);
  68574. +
  68575. + /*! Read the revision ID of the tvin chip */
  68576. + rev_id = adv7180_read(ADV7180_IDENT);
  68577. + dev_dbg(dev,
  68578. + "%s:Analog Device adv7%2X0 detected!\n", __func__,
  68579. + rev_id);
  68580. +
  68581. + ret = of_property_read_u32(dev->of_node, "cvbs", &(cvbs));
  68582. + if (ret) {
  68583. + dev_err(dev, "cvbs setting is not found\n");
  68584. + cvbs = true;
  68585. + }
  68586. +
  68587. + /*! ADV7180 initialization. */
  68588. + adv7180_hard_reset(cvbs);
  68589. +
  68590. + pr_debug(" type is %d (expect %d)\n",
  68591. + adv7180_int_device.type, v4l2_int_type_slave);
  68592. + pr_debug(" num ioctls is %d\n",
  68593. + adv7180_int_device.u.slave->num_ioctls);
  68594. +
  68595. + /* This function attaches this structure to the /dev/video0 device.
  68596. + * The pointer in priv points to the adv7180_data structure here.*/
  68597. + adv7180_int_device.priv = &adv7180_data;
  68598. + ret = v4l2_int_device_register(&adv7180_int_device);
  68599. +
  68600. + clk_disable_unprepare(adv7180_data.sen.sensor_clk);
  68601. +
  68602. + return ret;
  68603. +}
  68604. +
  68605. +/*!
  68606. + * ADV7180 I2C detach function.
  68607. + * Called on rmmod.
  68608. + *
  68609. + * @param *client struct i2c_client*.
  68610. + *
  68611. + * @return Error code indicating success or failure.
  68612. + */
  68613. +static int adv7180_detach(struct i2c_client *client)
  68614. +{
  68615. + dev_dbg(&adv7180_data.sen.i2c_client->dev,
  68616. + "%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
  68617. + __func__, IF_NAME, client->addr << 1, client->adapter->name);
  68618. +
  68619. + /* Power down via i2c */
  68620. + adv7180_write_reg(ADV7180_PWR_MNG, 0x24);
  68621. +
  68622. + if (dvddio_regulator)
  68623. + regulator_disable(dvddio_regulator);
  68624. +
  68625. + if (dvdd_regulator)
  68626. + regulator_disable(dvdd_regulator);
  68627. +
  68628. + if (avdd_regulator)
  68629. + regulator_disable(avdd_regulator);
  68630. +
  68631. + if (pvdd_regulator)
  68632. + regulator_disable(pvdd_regulator);
  68633. +
  68634. + v4l2_int_device_unregister(&adv7180_int_device);
  68635. +
  68636. + return 0;
  68637. +}
  68638. +
  68639. +/*!
  68640. + * ADV7180 init function.
  68641. + * Called on insmod.
  68642. + *
  68643. + * @return Error code indicating success or failure.
  68644. + */
  68645. +static __init int adv7180_init(void)
  68646. +{
  68647. + u8 err = 0;
  68648. +
  68649. + pr_debug("In adv7180_init\n");
  68650. +
  68651. + /* Tells the i2c driver what functions to call for this driver. */
  68652. + err = i2c_add_driver(&adv7180_i2c_driver);
  68653. + if (err != 0)
  68654. + pr_err("%s:driver registration failed, error=%d\n",
  68655. + __func__, err);
  68656. +
  68657. + return err;
  68658. +}
  68659. +
  68660. +/*!
  68661. + * ADV7180 cleanup function.
  68662. + * Called on rmmod.
  68663. + *
  68664. + * @return Error code indicating success or failure.
  68665. + */
  68666. +static void __exit adv7180_clean(void)
  68667. +{
  68668. + dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_clean\n");
  68669. + i2c_del_driver(&adv7180_i2c_driver);
  68670. +}
  68671. +
  68672. +module_init(adv7180_init);
  68673. +module_exit(adv7180_clean);
  68674. +
  68675. +MODULE_AUTHOR("Freescale Semiconductor");
  68676. +MODULE_DESCRIPTION("Anolog Device ADV7180 video decoder driver");
  68677. +MODULE_LICENSE("GPL");
  68678. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/csi_v4l2_capture.c linux-imx6-3.14/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
  68679. --- linux-3.14.17/drivers/media/platform/mxc/capture/csi_v4l2_capture.c 1970-01-01 01:00:00.000000000 +0100
  68680. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/csi_v4l2_capture.c 2014-09-11 18:06:02.254038983 +0200
  68681. @@ -0,0 +1,2047 @@
  68682. +/*
  68683. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  68684. + */
  68685. +
  68686. +/*
  68687. + * The code contained herein is licensed under the GNU General Public
  68688. + * License. You may obtain a copy of the GNU General Public License
  68689. + * Version 2 or later at the following locations:
  68690. + *
  68691. + * http://www.opensource.org/licenses/gpl-license.html
  68692. + * http://www.gnu.org/copyleft/gpl.html
  68693. + */
  68694. +
  68695. +/*!
  68696. + * @file drivers/media/video/mxc/capture/csi_v4l2_capture.c
  68697. + * This file is derived from mxc_v4l2_capture.c
  68698. + *
  68699. + * @brief Video For Linux 2 capture driver
  68700. + *
  68701. + * @ingroup MXC_V4L2_CAPTURE
  68702. + */
  68703. +#include <linux/version.h>
  68704. +#include <linux/module.h>
  68705. +#include <linux/init.h>
  68706. +#include <linux/platform_device.h>
  68707. +#include <linux/fs.h>
  68708. +#include <linux/slab.h>
  68709. +#include <linux/ctype.h>
  68710. +#include <linux/clk.h>
  68711. +#include <linux/io.h>
  68712. +#include <linux/semaphore.h>
  68713. +#include <linux/pagemap.h>
  68714. +#include <linux/vmalloc.h>
  68715. +#include <linux/types.h>
  68716. +#include <linux/fb.h>
  68717. +#include <linux/mxcfb.h>
  68718. +#include <linux/dma-mapping.h>
  68719. +#include <media/v4l2-ioctl.h>
  68720. +#include <media/v4l2-int-device.h>
  68721. +#include <media/v4l2-chip-ident.h>
  68722. +#include "mxc_v4l2_capture.h"
  68723. +#include "fsl_csi.h"
  68724. +
  68725. +static int video_nr = -1;
  68726. +static cam_data *g_cam;
  68727. +static int req_buf_number;
  68728. +
  68729. +static int csi_v4l2_master_attach(struct v4l2_int_device *slave);
  68730. +static void csi_v4l2_master_detach(struct v4l2_int_device *slave);
  68731. +static u8 camera_power(cam_data *cam, bool cameraOn);
  68732. +struct v4l2_crop crop_current;
  68733. +struct v4l2_window win_current;
  68734. +
  68735. +/*! Information about this driver. */
  68736. +static struct v4l2_int_master csi_v4l2_master = {
  68737. + .attach = csi_v4l2_master_attach,
  68738. + .detach = csi_v4l2_master_detach,
  68739. +};
  68740. +
  68741. +static struct v4l2_int_device csi_v4l2_int_device = {
  68742. + .module = THIS_MODULE,
  68743. + .name = "csi_v4l2_cap",
  68744. + .type = v4l2_int_type_master,
  68745. + .u = {
  68746. + .master = &csi_v4l2_master,
  68747. + },
  68748. +};
  68749. +
  68750. +static struct v4l2_queryctrl pxp_controls[] = {
  68751. + {
  68752. + .id = V4L2_CID_HFLIP,
  68753. + .type = V4L2_CTRL_TYPE_BOOLEAN,
  68754. + .name = "Horizontal Flip",
  68755. + .minimum = 0,
  68756. + .maximum = 1,
  68757. + .step = 1,
  68758. + .default_value = 0,
  68759. + .flags = 0,
  68760. + }, {
  68761. + .id = V4L2_CID_VFLIP,
  68762. + .type = V4L2_CTRL_TYPE_BOOLEAN,
  68763. + .name = "Vertical Flip",
  68764. + .minimum = 0,
  68765. + .maximum = 1,
  68766. + .step = 1,
  68767. + .default_value = 0,
  68768. + .flags = 0,
  68769. + }, {
  68770. + .id = V4L2_CID_PRIVATE_BASE,
  68771. + .type = V4L2_CTRL_TYPE_INTEGER,
  68772. + .name = "Rotation",
  68773. + .minimum = 0,
  68774. + .maximum = 270,
  68775. + .step = 90,
  68776. + .default_value = 0,
  68777. + .flags = 0,
  68778. + },
  68779. +};
  68780. +
  68781. +/* Callback function triggered after PxP receives an EOF interrupt */
  68782. +static void pxp_dma_done(void *arg)
  68783. +{
  68784. + struct pxp_tx_desc *tx_desc = to_tx_desc(arg);
  68785. + struct dma_chan *chan = tx_desc->txd.chan;
  68786. + struct pxp_channel *pxp_chan = to_pxp_channel(chan);
  68787. + cam_data *cam = pxp_chan->client;
  68788. +
  68789. + /* This call will signal wait_for_completion_timeout() */
  68790. + complete(&cam->pxp_tx_cmpl);
  68791. +}
  68792. +
  68793. +static bool chan_filter(struct dma_chan *chan, void *arg)
  68794. +{
  68795. + if (imx_dma_is_pxp(chan))
  68796. + return true;
  68797. + else
  68798. + return false;
  68799. +}
  68800. +
  68801. +/* Function to request PXP DMA channel */
  68802. +static int pxp_chan_init(cam_data *cam)
  68803. +{
  68804. + dma_cap_mask_t mask;
  68805. + struct dma_chan *chan;
  68806. +
  68807. + /* Request a free channel */
  68808. + dma_cap_zero(mask);
  68809. + dma_cap_set(DMA_SLAVE, mask);
  68810. + dma_cap_set(DMA_PRIVATE, mask);
  68811. + chan = dma_request_channel(mask, chan_filter, NULL);
  68812. + if (!chan) {
  68813. + pr_err("Unsuccessfully request channel!\n");
  68814. + return -EBUSY;
  68815. + }
  68816. +
  68817. + cam->pxp_chan = to_pxp_channel(chan);
  68818. + cam->pxp_chan->client = cam;
  68819. +
  68820. + init_completion(&cam->pxp_tx_cmpl);
  68821. +
  68822. + return 0;
  68823. +}
  68824. +
  68825. +/*
  68826. + * Function to call PxP DMA driver and send our new V4L2 buffer
  68827. + * through the PxP.
  68828. + * Note: This is a blocking call, so upon return the PxP tx should be complete.
  68829. + */
  68830. +static int pxp_process_update(cam_data *cam)
  68831. +{
  68832. + dma_cookie_t cookie;
  68833. + struct scatterlist *sg = cam->sg;
  68834. + struct dma_chan *dma_chan;
  68835. + struct pxp_tx_desc *desc;
  68836. + struct dma_async_tx_descriptor *txd;
  68837. + struct pxp_config_data *pxp_conf = &cam->pxp_conf;
  68838. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  68839. + int i, ret;
  68840. + int length;
  68841. +
  68842. + pr_debug("Starting PxP Send Buffer\n");
  68843. +
  68844. + /* First, check to see that we have acquired a PxP Channel object */
  68845. + if (cam->pxp_chan == NULL) {
  68846. + /*
  68847. + * PxP Channel has not yet been created and initialized,
  68848. + * so let's go ahead and try
  68849. + */
  68850. + ret = pxp_chan_init(cam);
  68851. + if (ret) {
  68852. + /*
  68853. + * PxP channel init failed, and we can't use the
  68854. + * PxP until the PxP DMA driver has loaded, so we abort
  68855. + */
  68856. + pr_err("PxP chan init failed\n");
  68857. + return -ENODEV;
  68858. + }
  68859. + }
  68860. +
  68861. + /*
  68862. + * Init completion, so that we can be properly informed of
  68863. + * the completion of the PxP task when it is done.
  68864. + */
  68865. + init_completion(&cam->pxp_tx_cmpl);
  68866. +
  68867. + dma_chan = &cam->pxp_chan->dma_chan;
  68868. +
  68869. + txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg, 2,
  68870. + DMA_TO_DEVICE,
  68871. + DMA_PREP_INTERRUPT,
  68872. + NULL);
  68873. + if (!txd) {
  68874. + pr_err("Error preparing a DMA transaction descriptor.\n");
  68875. + return -EIO;
  68876. + }
  68877. +
  68878. + txd->callback_param = txd;
  68879. + txd->callback = pxp_dma_done;
  68880. +
  68881. + /*
  68882. + * Configure PxP for processing of new v4l2 buf
  68883. + */
  68884. + pxp_conf->s0_param.pixel_fmt = PXP_PIX_FMT_UYVY;
  68885. + pxp_conf->s0_param.color_key = -1;
  68886. + pxp_conf->s0_param.color_key_enable = false;
  68887. + pxp_conf->s0_param.width = cam->v2f.fmt.pix.width;
  68888. + pxp_conf->s0_param.height = cam->v2f.fmt.pix.height;
  68889. +
  68890. + pxp_conf->ol_param[0].combine_enable = false;
  68891. +
  68892. + proc_data->srect.top = 0;
  68893. + proc_data->srect.left = 0;
  68894. + proc_data->srect.width = pxp_conf->s0_param.width;
  68895. + proc_data->srect.height = pxp_conf->s0_param.height;
  68896. +
  68897. + if (crop_current.c.top != 0)
  68898. + proc_data->srect.top = crop_current.c.top;
  68899. + if (crop_current.c.left != 0)
  68900. + proc_data->srect.left = crop_current.c.left;
  68901. + if (crop_current.c.width != 0)
  68902. + proc_data->srect.width = crop_current.c.width;
  68903. + if (crop_current.c.height != 0)
  68904. + proc_data->srect.height = crop_current.c.height;
  68905. +
  68906. + proc_data->drect.left = 0;
  68907. + proc_data->drect.top = 0;
  68908. + proc_data->drect.width = proc_data->srect.width;
  68909. + proc_data->drect.height = proc_data->srect.height;
  68910. +
  68911. + if (win_current.w.left != 0)
  68912. + proc_data->drect.left = win_current.w.left;
  68913. + if (win_current.w.top != 0)
  68914. + proc_data->drect.top = win_current.w.top;
  68915. + if (win_current.w.width != 0)
  68916. + proc_data->drect.width = win_current.w.width;
  68917. + if (win_current.w.height != 0)
  68918. + proc_data->drect.height = win_current.w.height;
  68919. +
  68920. + pr_debug("srect l: %d, t: %d, w: %d, h: %d; "
  68921. + "drect l: %d, t: %d, w: %d, h: %d\n",
  68922. + proc_data->srect.left, proc_data->srect.top,
  68923. + proc_data->srect.width, proc_data->srect.height,
  68924. + proc_data->drect.left, proc_data->drect.top,
  68925. + proc_data->drect.width, proc_data->drect.height);
  68926. +
  68927. + pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
  68928. + pxp_conf->out_param.width = proc_data->drect.width;
  68929. + pxp_conf->out_param.height = proc_data->drect.height;
  68930. +
  68931. + if (cam->rotation % 180)
  68932. + pxp_conf->out_param.stride = pxp_conf->out_param.height;
  68933. + else
  68934. + pxp_conf->out_param.stride = pxp_conf->out_param.width;
  68935. +
  68936. + desc = to_tx_desc(txd);
  68937. + length = desc->len;
  68938. + for (i = 0; i < length; i++) {
  68939. + if (i == 0) {/* S0 */
  68940. + memcpy(&desc->proc_data, proc_data,
  68941. + sizeof(struct pxp_proc_data));
  68942. + pxp_conf->s0_param.paddr = sg_dma_address(&sg[0]);
  68943. + memcpy(&desc->layer_param.s0_param, &pxp_conf->s0_param,
  68944. + sizeof(struct pxp_layer_param));
  68945. + } else if (i == 1) {
  68946. + pxp_conf->out_param.paddr = sg_dma_address(&sg[1]);
  68947. + memcpy(&desc->layer_param.out_param,
  68948. + &pxp_conf->out_param,
  68949. + sizeof(struct pxp_layer_param));
  68950. + }
  68951. +
  68952. + desc = desc->next;
  68953. + }
  68954. +
  68955. + /* Submitting our TX starts the PxP processing task */
  68956. + cookie = txd->tx_submit(txd);
  68957. + if (cookie < 0) {
  68958. + pr_err("Error sending FB through PxP\n");
  68959. + return -EIO;
  68960. + }
  68961. +
  68962. + cam->txd = txd;
  68963. +
  68964. + /* trigger PxP */
  68965. + dma_async_issue_pending(dma_chan);
  68966. +
  68967. + return 0;
  68968. +}
  68969. +
  68970. +static int pxp_complete_update(cam_data *cam)
  68971. +{
  68972. + int ret;
  68973. + /*
  68974. + * Wait for completion event, which will be set
  68975. + * through our TX callback function.
  68976. + */
  68977. + ret = wait_for_completion_timeout(&cam->pxp_tx_cmpl, HZ / 10);
  68978. + if (ret <= 0) {
  68979. + pr_warning("PxP operation failed due to %s\n",
  68980. + ret < 0 ? "user interrupt" : "timeout");
  68981. + dma_release_channel(&cam->pxp_chan->dma_chan);
  68982. + cam->pxp_chan = NULL;
  68983. + return ret ? : -ETIMEDOUT;
  68984. + }
  68985. +
  68986. + dma_release_channel(&cam->pxp_chan->dma_chan);
  68987. + cam->pxp_chan = NULL;
  68988. +
  68989. + pr_debug("TX completed\n");
  68990. +
  68991. + return 0;
  68992. +}
  68993. +
  68994. +/*!
  68995. + * Camera V4l2 callback function.
  68996. + *
  68997. + * @param mask u32
  68998. + * @param dev void device structure
  68999. + *
  69000. + * @return none
  69001. + */
  69002. +static void camera_callback(u32 mask, void *dev)
  69003. +{
  69004. + struct mxc_v4l_frame *done_frame;
  69005. + struct mxc_v4l_frame *ready_frame;
  69006. + cam_data *cam;
  69007. +
  69008. + cam = (cam_data *) dev;
  69009. + if (cam == NULL)
  69010. + return;
  69011. +
  69012. + spin_lock(&cam->queue_int_lock);
  69013. + spin_lock(&cam->dqueue_int_lock);
  69014. + if (!list_empty(&cam->working_q)) {
  69015. + done_frame = list_entry(cam->working_q.next,
  69016. + struct mxc_v4l_frame, queue);
  69017. +
  69018. + if (done_frame->csi_buf_num != cam->ping_pong_csi)
  69019. + goto next;
  69020. +
  69021. + if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  69022. + done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
  69023. + done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  69024. +
  69025. + /* Added to the done queue */
  69026. + list_del(cam->working_q.next);
  69027. + list_add_tail(&done_frame->queue, &cam->done_q);
  69028. + cam->enc_counter++;
  69029. + wake_up_interruptible(&cam->enc_queue);
  69030. + } else {
  69031. + pr_err("ERROR: v4l2 capture: %s: "
  69032. + "buffer not queued\n", __func__);
  69033. + }
  69034. + }
  69035. +
  69036. +next:
  69037. + if (!list_empty(&cam->ready_q)) {
  69038. + ready_frame = list_entry(cam->ready_q.next,
  69039. + struct mxc_v4l_frame, queue);
  69040. + list_del(cam->ready_q.next);
  69041. + list_add_tail(&ready_frame->queue, &cam->working_q);
  69042. +
  69043. + __raw_writel(ready_frame->paddress,
  69044. + cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
  69045. + CSI_CSIDMASA_FB2);
  69046. + ready_frame->csi_buf_num = cam->ping_pong_csi;
  69047. + } else {
  69048. + __raw_writel(cam->dummy_frame.paddress,
  69049. + cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
  69050. + CSI_CSIDMASA_FB2);
  69051. + }
  69052. + spin_unlock(&cam->dqueue_int_lock);
  69053. + spin_unlock(&cam->queue_int_lock);
  69054. +
  69055. + return;
  69056. +}
  69057. +
  69058. +/*!
  69059. + * Make csi ready for capture image.
  69060. + *
  69061. + * @param cam structure cam_data *
  69062. + *
  69063. + * @return status 0 success
  69064. + */
  69065. +static int csi_cap_image(cam_data *cam)
  69066. +{
  69067. + unsigned int value;
  69068. +
  69069. + value = __raw_readl(CSI_CSICR3);
  69070. + __raw_writel(value | BIT_FRMCNT_RST, CSI_CSICR3);
  69071. + value = __raw_readl(CSI_CSISR);
  69072. + __raw_writel(value, CSI_CSISR);
  69073. +
  69074. + return 0;
  69075. +}
  69076. +
  69077. +/***************************************************************************
  69078. + * Functions for handling Frame buffers.
  69079. + **************************************************************************/
  69080. +
  69081. +/*!
  69082. + * Free frame buffers
  69083. + *
  69084. + * @param cam Structure cam_data *
  69085. + *
  69086. + * @return status 0 success.
  69087. + */
  69088. +static int csi_free_frame_buf(cam_data *cam)
  69089. +{
  69090. + int i;
  69091. +
  69092. + pr_debug("MVC: In %s\n", __func__);
  69093. +
  69094. + for (i = 0; i < FRAME_NUM; i++) {
  69095. + if (cam->frame[i].vaddress != 0) {
  69096. + dma_free_coherent(0, cam->frame[i].buffer.length,
  69097. + cam->frame[i].vaddress,
  69098. + cam->frame[i].paddress);
  69099. + cam->frame[i].vaddress = 0;
  69100. + }
  69101. + }
  69102. +
  69103. + if (cam->dummy_frame.vaddress != 0) {
  69104. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  69105. + cam->dummy_frame.vaddress,
  69106. + cam->dummy_frame.paddress);
  69107. + cam->dummy_frame.vaddress = 0;
  69108. + }
  69109. +
  69110. + return 0;
  69111. +}
  69112. +
  69113. +/*!
  69114. + * Allocate frame buffers
  69115. + *
  69116. + * @param cam Structure cam_data *
  69117. + * @param count int number of buffer need to allocated
  69118. + *
  69119. + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
  69120. + */
  69121. +static int csi_allocate_frame_buf(cam_data *cam, int count)
  69122. +{
  69123. + int i;
  69124. +
  69125. + pr_debug("In MVC:%s- size=%d\n",
  69126. + __func__, cam->v2f.fmt.pix.sizeimage);
  69127. + for (i = 0; i < count; i++) {
  69128. + cam->frame[i].vaddress = dma_alloc_coherent(0, PAGE_ALIGN
  69129. + (cam->v2f.fmt.
  69130. + pix.sizeimage),
  69131. + &cam->frame[i].
  69132. + paddress,
  69133. + GFP_DMA |
  69134. + GFP_KERNEL);
  69135. + if (cam->frame[i].vaddress == 0) {
  69136. + pr_err("ERROR: v4l2 capture: "
  69137. + "%s failed.\n", __func__);
  69138. + csi_free_frame_buf(cam);
  69139. + return -ENOBUFS;
  69140. + }
  69141. + cam->frame[i].buffer.index = i;
  69142. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  69143. + cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  69144. + cam->frame[i].buffer.length = cam->v2f.fmt.pix.sizeimage;
  69145. + cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
  69146. + cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
  69147. + cam->frame[i].index = i;
  69148. + cam->frame[i].csi_buf_num = 0;
  69149. + }
  69150. +
  69151. + return 0;
  69152. +}
  69153. +
  69154. +/*!
  69155. + * Free frame buffers status
  69156. + *
  69157. + * @param cam Structure cam_data *
  69158. + *
  69159. + * @return none
  69160. + */
  69161. +static void csi_free_frames(cam_data *cam)
  69162. +{
  69163. + int i;
  69164. +
  69165. + pr_debug("In MVC: %s\n", __func__);
  69166. +
  69167. + for (i = 0; i < FRAME_NUM; i++)
  69168. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  69169. +
  69170. + cam->enc_counter = 0;
  69171. + INIT_LIST_HEAD(&cam->ready_q);
  69172. + INIT_LIST_HEAD(&cam->working_q);
  69173. + INIT_LIST_HEAD(&cam->done_q);
  69174. +
  69175. + return;
  69176. +}
  69177. +
  69178. +/*!
  69179. + * Return the buffer status
  69180. + *
  69181. + * @param cam Structure cam_data *
  69182. + * @param buf Structure v4l2_buffer *
  69183. + *
  69184. + * @return status 0 success, EINVAL failed.
  69185. + */
  69186. +static int csi_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
  69187. +{
  69188. + pr_debug("In MVC: %s\n", __func__);
  69189. +
  69190. + if (buf->index < 0 || buf->index >= FRAME_NUM) {
  69191. + pr_err("ERROR: v4l2 capture: %s buffers "
  69192. + "not allocated\n", __func__);
  69193. + return -EINVAL;
  69194. + }
  69195. +
  69196. + memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
  69197. +
  69198. + return 0;
  69199. +}
  69200. +
  69201. +static int csi_v4l2_release_bufs(cam_data *cam)
  69202. +{
  69203. + pr_debug("In MVC:csi_v4l2_release_bufs\n");
  69204. + return 0;
  69205. +}
  69206. +
  69207. +static int csi_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
  69208. +{
  69209. + pr_debug("In MVC:csi_v4l2_prepare_bufs\n");
  69210. +
  69211. + if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
  69212. + cam->v2f.fmt.pix.sizeimage) {
  69213. + pr_err("ERROR: v4l2 capture: csi_v4l2_prepare_bufs buffers "
  69214. + "not allocated,index=%d, length=%d\n", buf->index,
  69215. + buf->length);
  69216. + return -EINVAL;
  69217. + }
  69218. +
  69219. + cam->frame[buf->index].buffer.index = buf->index;
  69220. + cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  69221. + cam->frame[buf->index].buffer.length = buf->length;
  69222. + cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
  69223. + = buf->m.offset;
  69224. + cam->frame[buf->index].buffer.type = buf->type;
  69225. + cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
  69226. + cam->frame[buf->index].index = buf->index;
  69227. +
  69228. + return 0;
  69229. +}
  69230. +
  69231. +/*!
  69232. + * Indicates whether the palette is supported.
  69233. + *
  69234. + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_UYVY or V4L2_PIX_FMT_YUV420
  69235. + *
  69236. + * @return 0 if failed
  69237. + */
  69238. +static inline int valid_mode(u32 palette)
  69239. +{
  69240. + return (palette == V4L2_PIX_FMT_RGB565) ||
  69241. + (palette == V4L2_PIX_FMT_YUYV) ||
  69242. + (palette == V4L2_PIX_FMT_UYVY) || (palette == V4L2_PIX_FMT_YUV420);
  69243. +}
  69244. +
  69245. +/*!
  69246. + * Start stream I/O
  69247. + *
  69248. + * @param cam structure cam_data *
  69249. + *
  69250. + * @return status 0 Success
  69251. + */
  69252. +static int csi_streamon(cam_data *cam)
  69253. +{
  69254. + struct mxc_v4l_frame *frame;
  69255. + unsigned long flags;
  69256. + unsigned long val;
  69257. + int timeout, timeout2;
  69258. +
  69259. + pr_debug("In MVC: %s\n", __func__);
  69260. +
  69261. + if (NULL == cam) {
  69262. + pr_err("ERROR: v4l2 capture: %s cam parameter is NULL\n",
  69263. + __func__);
  69264. + return -1;
  69265. + }
  69266. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  69267. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  69268. + &cam->dummy_frame.paddress,
  69269. + GFP_DMA | GFP_KERNEL);
  69270. + if (cam->dummy_frame.vaddress == 0) {
  69271. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  69272. + "failed.\n");
  69273. + return -ENOBUFS;
  69274. + }
  69275. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  69276. + cam->dummy_frame.buffer.length = cam->v2f.fmt.pix.sizeimage;
  69277. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  69278. +
  69279. + spin_lock_irqsave(&cam->queue_int_lock, flags);
  69280. + /* move the frame from readyq to workingq */
  69281. + if (list_empty(&cam->ready_q)) {
  69282. + pr_err("ERROR: v4l2 capture: %s: "
  69283. + "ready_q queue empty\n", __func__);
  69284. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  69285. + return -1;
  69286. + }
  69287. + frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  69288. + list_del(cam->ready_q.next);
  69289. + list_add_tail(&frame->queue, &cam->working_q);
  69290. + __raw_writel(frame->paddress, CSI_CSIDMASA_FB1);
  69291. + frame->csi_buf_num = 1;
  69292. +
  69293. + if (list_empty(&cam->ready_q)) {
  69294. + pr_err("ERROR: v4l2 capture: %s: "
  69295. + "ready_q queue empty\n", __func__);
  69296. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  69297. + return -1;
  69298. + }
  69299. + frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  69300. + list_del(cam->ready_q.next);
  69301. + list_add_tail(&frame->queue, &cam->working_q);
  69302. + __raw_writel(frame->paddress, CSI_CSIDMASA_FB2);
  69303. + frame->csi_buf_num = 2;
  69304. + spin_unlock_irqrestore(&cam->queue_int_lock, flags);
  69305. +
  69306. + cam->capture_pid = current->pid;
  69307. + cam->capture_on = true;
  69308. + csi_cap_image(cam);
  69309. +
  69310. + local_irq_save(flags);
  69311. + for (timeout = 1000000; timeout > 0; timeout--) {
  69312. + if (__raw_readl(CSI_CSISR) & BIT_SOF_INT) {
  69313. + val = __raw_readl(CSI_CSICR3);
  69314. + __raw_writel(val | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  69315. + for (timeout2 = 1000000; timeout2 > 0; timeout2--) {
  69316. + if (__raw_readl(CSI_CSICR3) &
  69317. + BIT_DMA_REFLASH_RFF)
  69318. + cpu_relax();
  69319. + else
  69320. + break;
  69321. + }
  69322. + if (timeout2 <= 0) {
  69323. + pr_err("timeout when wait for reflash done.\n");
  69324. + local_irq_restore(flags);
  69325. + return -ETIME;
  69326. + }
  69327. +
  69328. + csi_dmareq_rff_enable();
  69329. + csi_enable_int(1);
  69330. + break;
  69331. + } else
  69332. + cpu_relax();
  69333. + }
  69334. + if (timeout <= 0) {
  69335. + pr_err("timeout when wait for SOF\n");
  69336. + local_irq_restore(flags);
  69337. + return -ETIME;
  69338. + }
  69339. + local_irq_restore(flags);
  69340. +
  69341. + return 0;
  69342. +}
  69343. +
  69344. +/*!
  69345. + * Stop stream I/O
  69346. + *
  69347. + * @param cam structure cam_data *
  69348. + *
  69349. + * @return status 0 Success
  69350. + */
  69351. +static int csi_streamoff(cam_data *cam)
  69352. +{
  69353. + pr_debug("In MVC: %s\n", __func__);
  69354. +
  69355. + if (cam->capture_on == false)
  69356. + return 0;
  69357. +
  69358. + csi_dmareq_rff_disable();
  69359. + csi_disable_int();
  69360. + cam->capture_on = false;
  69361. +
  69362. + /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
  69363. + __raw_writel(0, CSI_CSIDMASA_FB1);
  69364. + __raw_writel(0, CSI_CSIDMASA_FB2);
  69365. +
  69366. + csi_free_frames(cam);
  69367. + csi_free_frame_buf(cam);
  69368. +
  69369. + return 0;
  69370. +}
  69371. +
  69372. +/*!
  69373. + * start the viewfinder job
  69374. + *
  69375. + * @param cam structure cam_data *
  69376. + *
  69377. + * @return status 0 Success
  69378. + */
  69379. +static int start_preview(cam_data *cam)
  69380. +{
  69381. + unsigned long fb_addr = (unsigned long)cam->v4l2_fb.base;
  69382. +
  69383. + __raw_writel(fb_addr, CSI_CSIDMASA_FB1);
  69384. + __raw_writel(fb_addr, CSI_CSIDMASA_FB2);
  69385. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  69386. +
  69387. + csi_enable_int(0);
  69388. +
  69389. + return 0;
  69390. +}
  69391. +
  69392. +/*!
  69393. + * shut down the viewfinder job
  69394. + *
  69395. + * @param cam structure cam_data *
  69396. + *
  69397. + * @return status 0 Success
  69398. + */
  69399. +static int stop_preview(cam_data *cam)
  69400. +{
  69401. + csi_disable_int();
  69402. +
  69403. + /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
  69404. + __raw_writel(0, CSI_CSIDMASA_FB1);
  69405. + __raw_writel(0, CSI_CSIDMASA_FB2);
  69406. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  69407. +
  69408. + return 0;
  69409. +}
  69410. +
  69411. +/***************************************************************************
  69412. + * VIDIOC Functions.
  69413. + **************************************************************************/
  69414. +
  69415. +/*!
  69416. + *
  69417. + * @param cam structure cam_data *
  69418. + *
  69419. + * @param f structure v4l2_format *
  69420. + *
  69421. + * @return status 0 success, EINVAL failed
  69422. + */
  69423. +static int csi_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
  69424. +{
  69425. + int retval = 0;
  69426. +
  69427. + switch (f->type) {
  69428. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  69429. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  69430. + f->fmt.pix = cam->v2f.fmt.pix;
  69431. + break;
  69432. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  69433. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  69434. + f->fmt.win = cam->win;
  69435. + break;
  69436. + default:
  69437. + pr_debug(" type is invalid\n");
  69438. + retval = -EINVAL;
  69439. + }
  69440. +
  69441. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  69442. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  69443. +
  69444. + return retval;
  69445. +}
  69446. +
  69447. +/*!
  69448. + * V4L2 - csi_v4l2_s_fmt function
  69449. + *
  69450. + * @param cam structure cam_data *
  69451. + *
  69452. + * @param f structure v4l2_format *
  69453. + *
  69454. + * @return status 0 success, EINVAL failed
  69455. + */
  69456. +static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
  69457. +{
  69458. + int retval = 0;
  69459. + int size = 0;
  69460. + int bytesperline = 0;
  69461. + int *width, *height;
  69462. +
  69463. + pr_debug("In MVC: %s\n", __func__);
  69464. +
  69465. + switch (f->type) {
  69466. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  69467. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  69468. + if (!valid_mode(f->fmt.pix.pixelformat)) {
  69469. + pr_err("ERROR: v4l2 capture: %s: format "
  69470. + "not supported\n", __func__);
  69471. + return -EINVAL;
  69472. + }
  69473. +
  69474. + /* Handle case where size requested is larger than cuurent
  69475. + * camera setting. */
  69476. + if ((f->fmt.pix.width > cam->crop_bounds.width)
  69477. + || (f->fmt.pix.height > cam->crop_bounds.height)) {
  69478. + /* Need the logic here, calling vidioc_s_param if
  69479. + * camera can change. */
  69480. + pr_debug("csi_v4l2_s_fmt size changed\n");
  69481. + }
  69482. + if (cam->rotation % 180) {
  69483. + height = &f->fmt.pix.width;
  69484. + width = &f->fmt.pix.height;
  69485. + } else {
  69486. + width = &f->fmt.pix.width;
  69487. + height = &f->fmt.pix.height;
  69488. + }
  69489. +
  69490. + if ((cam->crop_bounds.width / *width > 8) ||
  69491. + ((cam->crop_bounds.width / *width == 8) &&
  69492. + (cam->crop_bounds.width % *width))) {
  69493. + *width = cam->crop_bounds.width / 8;
  69494. + if (*width % 8)
  69495. + *width += 8 - *width % 8;
  69496. + pr_err("ERROR: v4l2 capture: width exceeds limit "
  69497. + "resize to %d.\n", *width);
  69498. + }
  69499. +
  69500. + if ((cam->crop_bounds.height / *height > 8) ||
  69501. + ((cam->crop_bounds.height / *height == 8) &&
  69502. + (cam->crop_bounds.height % *height))) {
  69503. + *height = cam->crop_bounds.height / 8;
  69504. + if (*height % 8)
  69505. + *height += 8 - *height % 8;
  69506. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  69507. + "resize to %d.\n", *height);
  69508. + }
  69509. +
  69510. + switch (f->fmt.pix.pixelformat) {
  69511. + case V4L2_PIX_FMT_RGB565:
  69512. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  69513. + csi_init_format(V4L2_PIX_FMT_UYVY);
  69514. + csi_set_16bit_imagpara(f->fmt.pix.width,
  69515. + f->fmt.pix.height);
  69516. + bytesperline = f->fmt.pix.width * 2;
  69517. + break;
  69518. + case V4L2_PIX_FMT_UYVY:
  69519. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  69520. + csi_init_format(f->fmt.pix.pixelformat);
  69521. + csi_set_16bit_imagpara(f->fmt.pix.width,
  69522. + f->fmt.pix.height);
  69523. + bytesperline = f->fmt.pix.width * 2;
  69524. + break;
  69525. + case V4L2_PIX_FMT_YUYV:
  69526. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  69527. + csi_init_format(f->fmt.pix.pixelformat);
  69528. + csi_set_16bit_imagpara(f->fmt.pix.width,
  69529. + f->fmt.pix.height);
  69530. + bytesperline = f->fmt.pix.width * 2;
  69531. + break;
  69532. + case V4L2_PIX_FMT_YUV420:
  69533. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  69534. + csi_set_12bit_imagpara(f->fmt.pix.width,
  69535. + f->fmt.pix.height);
  69536. + bytesperline = f->fmt.pix.width;
  69537. + break;
  69538. + case V4L2_PIX_FMT_YUV422P:
  69539. + case V4L2_PIX_FMT_RGB24:
  69540. + case V4L2_PIX_FMT_BGR24:
  69541. + case V4L2_PIX_FMT_BGR32:
  69542. + case V4L2_PIX_FMT_RGB32:
  69543. + case V4L2_PIX_FMT_NV12:
  69544. + default:
  69545. + pr_debug(" case not supported\n");
  69546. + break;
  69547. + }
  69548. +
  69549. + if (f->fmt.pix.bytesperline < bytesperline)
  69550. + f->fmt.pix.bytesperline = bytesperline;
  69551. + else
  69552. + bytesperline = f->fmt.pix.bytesperline;
  69553. +
  69554. + if (f->fmt.pix.sizeimage < size)
  69555. + f->fmt.pix.sizeimage = size;
  69556. + else
  69557. + size = f->fmt.pix.sizeimage;
  69558. +
  69559. + cam->v2f.fmt.pix = f->fmt.pix;
  69560. +
  69561. + if (cam->v2f.fmt.pix.priv != 0) {
  69562. + if (copy_from_user(&cam->offset,
  69563. + (void *)cam->v2f.fmt.pix.priv,
  69564. + sizeof(cam->offset))) {
  69565. + retval = -EFAULT;
  69566. + break;
  69567. + }
  69568. + }
  69569. + break;
  69570. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  69571. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  69572. + cam->win = f->fmt.win;
  69573. + win_current = f->fmt.win;
  69574. + size = win_current.w.width * win_current.w.height * 2;
  69575. + if (cam->v2f.fmt.pix.sizeimage < size)
  69576. + cam->v2f.fmt.pix.sizeimage = size;
  69577. +
  69578. + break;
  69579. + default:
  69580. + retval = -EINVAL;
  69581. + }
  69582. +
  69583. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  69584. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  69585. +
  69586. + return retval;
  69587. +}
  69588. +
  69589. +/*!
  69590. + * V4L2 - csi_v4l2_s_param function
  69591. + * Allows setting of capturemode and frame rate.
  69592. + *
  69593. + * @param cam structure cam_data *
  69594. + * @param parm structure v4l2_streamparm *
  69595. + *
  69596. + * @return status 0 success, EINVAL failed
  69597. + */
  69598. +static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
  69599. +{
  69600. + struct v4l2_ifparm ifparm;
  69601. + struct v4l2_format cam_fmt;
  69602. + struct v4l2_streamparm currentparm;
  69603. + int err = 0;
  69604. +
  69605. + pr_debug("In %s\n", __func__);
  69606. +
  69607. + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  69608. + pr_err(KERN_ERR "%s invalid type\n", __func__);
  69609. + return -EINVAL;
  69610. + }
  69611. +
  69612. + /* Stop the viewfinder */
  69613. + if (cam->overlay_on == true)
  69614. + stop_preview(cam);
  69615. +
  69616. + currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  69617. +
  69618. + /* First check that this device can support the changes requested. */
  69619. + err = vidioc_int_g_parm(cam->sensor, &currentparm);
  69620. + if (err) {
  69621. + pr_err("%s: vidioc_int_g_parm returned an error %d\n",
  69622. + __func__, err);
  69623. + goto exit;
  69624. + }
  69625. +
  69626. + pr_debug(" Current capabilities are %x\n",
  69627. + currentparm.parm.capture.capability);
  69628. + pr_debug(" Current capturemode is %d change to %d\n",
  69629. + currentparm.parm.capture.capturemode,
  69630. + parm->parm.capture.capturemode);
  69631. + pr_debug(" Current framerate is %d change to %d\n",
  69632. + currentparm.parm.capture.timeperframe.denominator,
  69633. + parm->parm.capture.timeperframe.denominator);
  69634. +
  69635. + err = vidioc_int_s_parm(cam->sensor, parm);
  69636. + if (err) {
  69637. + pr_err("%s: vidioc_int_s_parm returned an error %d\n",
  69638. + __func__, err);
  69639. + goto exit;
  69640. + }
  69641. +
  69642. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  69643. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  69644. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  69645. + pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
  69646. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  69647. +
  69648. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  69649. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  69650. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  69651. + cam->crop_current.width = cam->crop_bounds.width;
  69652. + cam->crop_current.height = cam->crop_bounds.height;
  69653. +
  69654. +exit:
  69655. + return err;
  69656. +}
  69657. +
  69658. +static int pxp_set_cstate(cam_data *cam, struct v4l2_control *vc)
  69659. +{
  69660. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  69661. +
  69662. + if (vc->id == V4L2_CID_HFLIP) {
  69663. + proc_data->hflip = vc->value;
  69664. + } else if (vc->id == V4L2_CID_VFLIP) {
  69665. + proc_data->vflip = vc->value;
  69666. + } else if (vc->id == V4L2_CID_PRIVATE_BASE) {
  69667. + if (vc->value % 90)
  69668. + return -ERANGE;
  69669. + proc_data->rotate = vc->value;
  69670. + cam->rotation = vc->value;
  69671. + }
  69672. +
  69673. + return 0;
  69674. +}
  69675. +
  69676. +static int pxp_get_cstate(cam_data *cam, struct v4l2_control *vc)
  69677. +{
  69678. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  69679. +
  69680. + if (vc->id == V4L2_CID_HFLIP)
  69681. + vc->value = proc_data->hflip;
  69682. + else if (vc->id == V4L2_CID_VFLIP)
  69683. + vc->value = proc_data->vflip;
  69684. + else if (vc->id == V4L2_CID_PRIVATE_BASE)
  69685. + vc->value = proc_data->rotate;
  69686. +
  69687. + return 0;
  69688. +}
  69689. +
  69690. +
  69691. +/*!
  69692. + * Dequeue one V4L capture buffer
  69693. + *
  69694. + * @param cam structure cam_data *
  69695. + * @param buf structure v4l2_buffer *
  69696. + *
  69697. + * @return status 0 success, EINVAL invalid frame number
  69698. + * ETIME timeout, ERESTARTSYS interrupted by user
  69699. + */
  69700. +static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
  69701. +{
  69702. + int retval = 0;
  69703. + struct mxc_v4l_frame *frame;
  69704. + unsigned long lock_flags;
  69705. +
  69706. + if (!wait_event_interruptible_timeout(cam->enc_queue,
  69707. + cam->enc_counter != 0, 10 * HZ)) {
  69708. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
  69709. + "enc_counter %x\n", cam->enc_counter);
  69710. + return -ETIME;
  69711. + } else if (signal_pending(current)) {
  69712. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
  69713. + "interrupt received\n");
  69714. + return -ERESTARTSYS;
  69715. + }
  69716. +
  69717. + if (down_interruptible(&cam->busy_lock))
  69718. + return -EBUSY;
  69719. +
  69720. + spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
  69721. +
  69722. + if (list_empty(&cam->done_q)) {
  69723. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  69724. + up(&cam->busy_lock);
  69725. + return -EINVAL;
  69726. + }
  69727. +
  69728. + cam->enc_counter--;
  69729. +
  69730. + frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
  69731. + list_del(cam->done_q.next);
  69732. +
  69733. + if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
  69734. + frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
  69735. + } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  69736. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  69737. + "Buffer not filled.\n");
  69738. + frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  69739. + retval = -EINVAL;
  69740. + } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
  69741. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  69742. + "Buffer not queued.\n");
  69743. + retval = -EINVAL;
  69744. + }
  69745. +
  69746. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  69747. +
  69748. + buf->bytesused = cam->v2f.fmt.pix.sizeimage;
  69749. + buf->index = frame->index;
  69750. + buf->flags = frame->buffer.flags;
  69751. + buf->m = cam->frame[frame->index].buffer.m;
  69752. +
  69753. + /*
  69754. + * Note:
  69755. + * If want to do preview on LCD, use PxP CSC to convert from UYVY
  69756. + * to RGB565; but for encoding, usually we don't use RGB format.
  69757. + */
  69758. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
  69759. + sg_dma_address(&cam->sg[0]) = buf->m.offset;
  69760. + sg_dma_address(&cam->sg[1]) =
  69761. + cam->frame[req_buf_number].paddress;
  69762. + retval = pxp_process_update(cam);
  69763. + if (retval) {
  69764. + pr_err("Unable to submit PxP update task.\n");
  69765. + return retval;
  69766. + }
  69767. + pxp_complete_update(cam);
  69768. + if (cam->frame[buf->index].vaddress)
  69769. + memcpy(cam->frame[buf->index].vaddress,
  69770. + cam->frame[req_buf_number].vaddress,
  69771. + cam->v2f.fmt.pix.sizeimage);
  69772. + }
  69773. + up(&cam->busy_lock);
  69774. +
  69775. + return retval;
  69776. +}
  69777. +
  69778. +/*!
  69779. + * V4L interface - open function
  69780. + *
  69781. + * @param file structure file *
  69782. + *
  69783. + * @return status 0 success, ENODEV invalid device instance,
  69784. + * ENODEV timeout, ERESTARTSYS interrupted by user
  69785. + */
  69786. +static int csi_v4l_open(struct file *file)
  69787. +{
  69788. + struct v4l2_ifparm ifparm;
  69789. + struct v4l2_format cam_fmt;
  69790. + struct video_device *dev = video_devdata(file);
  69791. + cam_data *cam = video_get_drvdata(dev);
  69792. + struct sensor_data *sensor;
  69793. + int err = 0;
  69794. +
  69795. + pr_debug(" device name is %s\n", dev->name);
  69796. +
  69797. + if (!cam) {
  69798. + pr_err("%s: Internal error, cam_data not found!\n", __func__);
  69799. + return -EBADF;
  69800. + }
  69801. +
  69802. + if (!cam->sensor) {
  69803. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  69804. + return -EBADF;
  69805. + }
  69806. +
  69807. + sensor = cam->sensor->priv;
  69808. + if (!sensor) {
  69809. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  69810. + return -EBADF;
  69811. + }
  69812. +
  69813. + down(&cam->busy_lock);
  69814. + err = 0;
  69815. + if (signal_pending(current))
  69816. + goto oops;
  69817. +
  69818. + if (cam->open_count++ == 0) {
  69819. + wait_event_interruptible(cam->power_queue,
  69820. + cam->low_power == false);
  69821. +
  69822. + cam->enc_counter = 0;
  69823. + INIT_LIST_HEAD(&cam->ready_q);
  69824. + INIT_LIST_HEAD(&cam->working_q);
  69825. + INIT_LIST_HEAD(&cam->done_q);
  69826. +
  69827. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  69828. +
  69829. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  69830. + clk_prepare_enable(sensor->sensor_clk);
  69831. + vidioc_int_s_power(cam->sensor, 1);
  69832. + vidioc_int_init(cam->sensor);
  69833. + vidioc_int_dev_init(cam->sensor);
  69834. + }
  69835. +
  69836. + file->private_data = dev;
  69837. +
  69838. +oops:
  69839. + up(&cam->busy_lock);
  69840. + return err;
  69841. +}
  69842. +
  69843. +/*!
  69844. + * V4L interface - close function
  69845. + *
  69846. + * @param file struct file *
  69847. + *
  69848. + * @return 0 success
  69849. + */
  69850. +static int csi_v4l_close(struct file *file)
  69851. +{
  69852. + struct video_device *dev = video_devdata(file);
  69853. + int err = 0;
  69854. + cam_data *cam = video_get_drvdata(dev);
  69855. + struct sensor_data *sensor;
  69856. +
  69857. + pr_debug("In MVC:%s\n", __func__);
  69858. +
  69859. + if (!cam) {
  69860. + pr_err("%s: Internal error, cam_data not found!\n", __func__);
  69861. + return -EBADF;
  69862. + }
  69863. +
  69864. + if (!cam->sensor) {
  69865. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  69866. + return -EBADF;
  69867. + }
  69868. +
  69869. + sensor = cam->sensor->priv;
  69870. + if (!sensor) {
  69871. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  69872. + return -EBADF;
  69873. + }
  69874. +
  69875. + /* for the case somebody hit the ctrl C */
  69876. + if (cam->overlay_pid == current->pid) {
  69877. + err = stop_preview(cam);
  69878. + cam->overlay_on = false;
  69879. + }
  69880. +
  69881. + if (--cam->open_count == 0) {
  69882. + wait_event_interruptible(cam->power_queue,
  69883. + cam->low_power == false);
  69884. + file->private_data = NULL;
  69885. + vidioc_int_s_power(cam->sensor, 0);
  69886. + clk_disable_unprepare(sensor->sensor_clk);
  69887. + }
  69888. +
  69889. + return err;
  69890. +}
  69891. +
  69892. +/*
  69893. + * V4L interface - read function
  69894. + *
  69895. + * @param file struct file *
  69896. + * @param read buf char *
  69897. + * @param count size_t
  69898. + * @param ppos structure loff_t *
  69899. + *
  69900. + * @return bytes read
  69901. + */
  69902. +static ssize_t csi_v4l_read(struct file *file, char *buf, size_t count,
  69903. + loff_t *ppos)
  69904. +{
  69905. + int err = 0;
  69906. + struct video_device *dev = video_devdata(file);
  69907. + cam_data *cam = video_get_drvdata(dev);
  69908. +
  69909. + if (down_interruptible(&cam->busy_lock))
  69910. + return -EINTR;
  69911. +
  69912. + /* Stop the viewfinder */
  69913. + if (cam->overlay_on == true)
  69914. + stop_preview(cam);
  69915. +
  69916. + if (cam->still_buf_vaddr == NULL) {
  69917. + cam->still_buf_vaddr = dma_alloc_coherent(0,
  69918. + PAGE_ALIGN
  69919. + (cam->v2f.fmt.
  69920. + pix.sizeimage),
  69921. + &cam->
  69922. + still_buf[0],
  69923. + GFP_DMA | GFP_KERNEL);
  69924. + if (cam->still_buf_vaddr == NULL) {
  69925. + pr_err("alloc dma memory failed\n");
  69926. + return -ENOMEM;
  69927. + }
  69928. + cam->still_counter = 0;
  69929. + __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB2);
  69930. + __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB1);
  69931. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
  69932. + CSI_CSICR3);
  69933. + __raw_writel(__raw_readl(CSI_CSISR), CSI_CSISR);
  69934. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST,
  69935. + CSI_CSICR3);
  69936. + csi_enable_int(1);
  69937. + }
  69938. +
  69939. + wait_event_interruptible(cam->still_queue, cam->still_counter);
  69940. + csi_disable_int();
  69941. + err = copy_to_user(buf, cam->still_buf_vaddr,
  69942. + cam->v2f.fmt.pix.sizeimage);
  69943. +
  69944. + if (cam->still_buf_vaddr != NULL) {
  69945. + dma_free_coherent(0, PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  69946. + cam->still_buf_vaddr, cam->still_buf[0]);
  69947. + cam->still_buf[0] = 0;
  69948. + cam->still_buf_vaddr = NULL;
  69949. + }
  69950. +
  69951. + if (cam->overlay_on == true)
  69952. + start_preview(cam);
  69953. +
  69954. + up(&cam->busy_lock);
  69955. + if (err < 0)
  69956. + return err;
  69957. +
  69958. + return cam->v2f.fmt.pix.sizeimage - err;
  69959. +}
  69960. +
  69961. +/*!
  69962. + * V4L interface - ioctl function
  69963. + *
  69964. + * @param file struct file*
  69965. + *
  69966. + * @param ioctlnr unsigned int
  69967. + *
  69968. + * @param arg void*
  69969. + *
  69970. + * @return 0 success, ENODEV for invalid device instance,
  69971. + * -1 for other errors.
  69972. + */
  69973. +static long csi_v4l_do_ioctl(struct file *file,
  69974. + unsigned int ioctlnr, void *arg)
  69975. +{
  69976. + struct video_device *dev = video_devdata(file);
  69977. + cam_data *cam = video_get_drvdata(dev);
  69978. + int retval = 0;
  69979. + unsigned long lock_flags;
  69980. +
  69981. + pr_debug("In MVC: %s, %x\n", __func__, ioctlnr);
  69982. + wait_event_interruptible(cam->power_queue, cam->low_power == false);
  69983. + /* make this _really_ smp-safe */
  69984. + if (ioctlnr != VIDIOC_DQBUF)
  69985. + if (down_interruptible(&cam->busy_lock))
  69986. + return -EBUSY;
  69987. +
  69988. + switch (ioctlnr) {
  69989. + /*!
  69990. + * V4l2 VIDIOC_G_FMT ioctl
  69991. + */
  69992. + case VIDIOC_G_FMT:{
  69993. + struct v4l2_format *gf = arg;
  69994. + pr_debug(" case VIDIOC_G_FMT\n");
  69995. + retval = csi_v4l2_g_fmt(cam, gf);
  69996. + break;
  69997. + }
  69998. +
  69999. + /*!
  70000. + * V4l2 VIDIOC_S_FMT ioctl
  70001. + */
  70002. + case VIDIOC_S_FMT:{
  70003. + struct v4l2_format *sf = arg;
  70004. + pr_debug(" case VIDIOC_S_FMT\n");
  70005. + retval = csi_v4l2_s_fmt(cam, sf);
  70006. + vidioc_int_s_fmt_cap(cam->sensor, sf);
  70007. + break;
  70008. + }
  70009. +
  70010. + /*!
  70011. + * V4l2 VIDIOC_OVERLAY ioctl
  70012. + */
  70013. + case VIDIOC_OVERLAY:{
  70014. + int *on = arg;
  70015. + pr_debug(" case VIDIOC_OVERLAY\n");
  70016. + if (*on) {
  70017. + cam->overlay_on = true;
  70018. + cam->overlay_pid = current->pid;
  70019. + start_preview(cam);
  70020. + }
  70021. + if (!*on) {
  70022. + stop_preview(cam);
  70023. + cam->overlay_on = false;
  70024. + }
  70025. + break;
  70026. + }
  70027. +
  70028. + /*!
  70029. + * V4l2 VIDIOC_G_FBUF ioctl
  70030. + */
  70031. + case VIDIOC_G_FBUF:{
  70032. + struct v4l2_framebuffer *fb = arg;
  70033. + *fb = cam->v4l2_fb;
  70034. + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
  70035. + break;
  70036. + }
  70037. +
  70038. + /*!
  70039. + * V4l2 VIDIOC_S_FBUF ioctl
  70040. + */
  70041. + case VIDIOC_S_FBUF:{
  70042. + struct v4l2_framebuffer *fb = arg;
  70043. + cam->v4l2_fb = *fb;
  70044. + break;
  70045. + }
  70046. +
  70047. + case VIDIOC_G_PARM:{
  70048. + struct v4l2_streamparm *parm = arg;
  70049. + pr_debug(" case VIDIOC_G_PARM\n");
  70050. + vidioc_int_g_parm(cam->sensor, parm);
  70051. + break;
  70052. + }
  70053. +
  70054. + case VIDIOC_S_PARM:{
  70055. + struct v4l2_streamparm *parm = arg;
  70056. + pr_debug(" case VIDIOC_S_PARM\n");
  70057. + retval = csi_v4l2_s_param(cam, parm);
  70058. + break;
  70059. + }
  70060. +
  70061. + case VIDIOC_QUERYCAP:{
  70062. + struct v4l2_capability *cap = arg;
  70063. + pr_debug(" case VIDIOC_QUERYCAP\n");
  70064. + strcpy(cap->driver, "csi_v4l2");
  70065. + cap->version = KERNEL_VERSION(0, 1, 11);
  70066. + cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
  70067. + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
  70068. + V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_READWRITE;
  70069. + cap->card[0] = '\0';
  70070. + cap->bus_info[0] = '\0';
  70071. + break;
  70072. + }
  70073. +
  70074. + case VIDIOC_CROPCAP:
  70075. + {
  70076. + struct v4l2_cropcap *cap = arg;
  70077. +
  70078. + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  70079. + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  70080. + retval = -EINVAL;
  70081. + break;
  70082. + }
  70083. + cap->bounds = cam->crop_bounds;
  70084. + cap->defrect = cam->crop_defrect;
  70085. + break;
  70086. + }
  70087. + case VIDIOC_S_CROP:
  70088. + {
  70089. + struct v4l2_crop *crop = arg;
  70090. + struct v4l2_rect *b = &cam->crop_bounds;
  70091. +
  70092. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  70093. + retval = -EINVAL;
  70094. + break;
  70095. + }
  70096. +
  70097. + crop->c.top = (crop->c.top < b->top) ? b->top
  70098. + : crop->c.top;
  70099. + if (crop->c.top > b->top + b->height)
  70100. + crop->c.top = b->top + b->height - 1;
  70101. + if (crop->c.height > b->top + b->height - crop->c.top)
  70102. + crop->c.height =
  70103. + b->top + b->height - crop->c.top;
  70104. +
  70105. + crop->c.left = (crop->c.left < b->left) ? b->left
  70106. + : crop->c.left;
  70107. + if (crop->c.left > b->left + b->width)
  70108. + crop->c.left = b->left + b->width - 1;
  70109. + if (crop->c.width > b->left - crop->c.left + b->width)
  70110. + crop->c.width =
  70111. + b->left - crop->c.left + b->width;
  70112. +
  70113. + crop->c.width -= crop->c.width % 8;
  70114. + crop->c.height -= crop->c.height % 8;
  70115. +
  70116. + crop_current.c = crop->c;
  70117. +
  70118. + break;
  70119. + }
  70120. + case VIDIOC_G_CROP:
  70121. + {
  70122. + struct v4l2_crop *crop = arg;
  70123. +
  70124. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  70125. + retval = -EINVAL;
  70126. + break;
  70127. + }
  70128. + crop->c = crop_current.c;
  70129. +
  70130. + break;
  70131. +
  70132. + }
  70133. + case VIDIOC_REQBUFS: {
  70134. + struct v4l2_requestbuffers *req = arg;
  70135. + pr_debug(" case VIDIOC_REQBUFS\n");
  70136. +
  70137. + if (req->count > FRAME_NUM) {
  70138. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  70139. + "not enough buffers\n");
  70140. + req->count = FRAME_NUM;
  70141. + }
  70142. +
  70143. + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  70144. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  70145. + "wrong buffer type\n");
  70146. + retval = -EINVAL;
  70147. + break;
  70148. + }
  70149. +
  70150. + csi_streamoff(cam);
  70151. + if (req->memory & V4L2_MEMORY_MMAP) {
  70152. + csi_free_frame_buf(cam);
  70153. + retval = csi_allocate_frame_buf(cam, req->count + 1);
  70154. + req_buf_number = req->count;
  70155. + }
  70156. + break;
  70157. + }
  70158. +
  70159. + case VIDIOC_QUERYBUF: {
  70160. + struct v4l2_buffer *buf = arg;
  70161. + int index = buf->index;
  70162. + pr_debug(" case VIDIOC_QUERYBUF\n");
  70163. +
  70164. + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  70165. + retval = -EINVAL;
  70166. + break;
  70167. + }
  70168. +
  70169. + if (buf->memory & V4L2_MEMORY_MMAP) {
  70170. + memset(buf, 0, sizeof(buf));
  70171. + buf->index = index;
  70172. + }
  70173. +
  70174. + down(&cam->param_lock);
  70175. + if (buf->memory & V4L2_MEMORY_USERPTR) {
  70176. + csi_v4l2_release_bufs(cam);
  70177. + retval = csi_v4l2_prepare_bufs(cam, buf);
  70178. + }
  70179. + if (buf->memory & V4L2_MEMORY_MMAP)
  70180. + retval = csi_v4l2_buffer_status(cam, buf);
  70181. + up(&cam->param_lock);
  70182. + break;
  70183. + }
  70184. +
  70185. + case VIDIOC_QBUF: {
  70186. + struct v4l2_buffer *buf = arg;
  70187. + int index = buf->index;
  70188. + pr_debug(" case VIDIOC_QBUF\n");
  70189. +
  70190. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  70191. + cam->frame[index].buffer.m.offset = buf->m.offset;
  70192. + if ((cam->frame[index].buffer.flags & 0x7) ==
  70193. + V4L2_BUF_FLAG_MAPPED) {
  70194. + cam->frame[index].buffer.flags |= V4L2_BUF_FLAG_QUEUED;
  70195. + list_add_tail(&cam->frame[index].queue, &cam->ready_q);
  70196. + } else if (cam->frame[index].buffer.flags &
  70197. + V4L2_BUF_FLAG_QUEUED) {
  70198. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  70199. + "buffer already queued\n");
  70200. + retval = -EINVAL;
  70201. + } else if (cam->frame[index].buffer.
  70202. + flags & V4L2_BUF_FLAG_DONE) {
  70203. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  70204. + "overwrite done buffer.\n");
  70205. + cam->frame[index].buffer.flags &=
  70206. + ~V4L2_BUF_FLAG_DONE;
  70207. + cam->frame[index].buffer.flags |=
  70208. + V4L2_BUF_FLAG_QUEUED;
  70209. + retval = -EINVAL;
  70210. + }
  70211. + buf->flags = cam->frame[index].buffer.flags;
  70212. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  70213. +
  70214. + break;
  70215. + }
  70216. +
  70217. + case VIDIOC_DQBUF: {
  70218. + struct v4l2_buffer *buf = arg;
  70219. + pr_debug(" case VIDIOC_DQBUF\n");
  70220. +
  70221. + retval = csi_v4l_dqueue(cam, buf);
  70222. +
  70223. + break;
  70224. + }
  70225. +
  70226. + case VIDIOC_STREAMON: {
  70227. + pr_debug(" case VIDIOC_STREAMON\n");
  70228. + retval = csi_streamon(cam);
  70229. + break;
  70230. + }
  70231. +
  70232. + case VIDIOC_STREAMOFF: {
  70233. + pr_debug(" case VIDIOC_STREAMOFF\n");
  70234. + retval = csi_streamoff(cam);
  70235. + break;
  70236. + }
  70237. + case VIDIOC_ENUM_FMT: {
  70238. + struct v4l2_fmtdesc *fmt = arg;
  70239. + if (cam->sensor)
  70240. + retval = vidioc_int_enum_fmt_cap(cam->sensor, fmt);
  70241. + else {
  70242. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  70243. + retval = -ENODEV;
  70244. + }
  70245. + break;
  70246. + }
  70247. + case VIDIOC_ENUM_FRAMESIZES: {
  70248. + struct v4l2_frmsizeenum *fsize = arg;
  70249. + if (cam->sensor)
  70250. + retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
  70251. + else {
  70252. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  70253. + retval = -ENODEV;
  70254. + }
  70255. + break;
  70256. + }
  70257. + case VIDIOC_ENUM_FRAMEINTERVALS: {
  70258. + struct v4l2_frmivalenum *fival = arg;
  70259. + if (cam->sensor)
  70260. + retval = vidioc_int_enum_frameintervals(cam->sensor,
  70261. + fival);
  70262. + else {
  70263. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  70264. + retval = -ENODEV;
  70265. + }
  70266. + break;
  70267. + }
  70268. + case VIDIOC_DBG_G_CHIP_IDENT: {
  70269. + struct v4l2_dbg_chip_ident *p = arg;
  70270. + p->ident = V4L2_IDENT_NONE;
  70271. + p->revision = 0;
  70272. + if (cam->sensor)
  70273. + retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
  70274. + else {
  70275. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  70276. + retval = -ENODEV;
  70277. + }
  70278. + break;
  70279. + }
  70280. +
  70281. + case VIDIOC_S_CTRL:
  70282. + {
  70283. + struct v4l2_control *vc = arg;
  70284. + int i;
  70285. +
  70286. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  70287. + if (vc->id == pxp_controls[i].id) {
  70288. + if (vc->value < pxp_controls[i].minimum ||
  70289. + vc->value > pxp_controls[i].maximum) {
  70290. + retval = -ERANGE;
  70291. + break;
  70292. + }
  70293. + retval = pxp_set_cstate(cam, vc);
  70294. + break;
  70295. + }
  70296. +
  70297. + if (i >= ARRAY_SIZE(pxp_controls))
  70298. + retval = -EINVAL;
  70299. + break;
  70300. +
  70301. + }
  70302. + case VIDIOC_G_CTRL:
  70303. + {
  70304. + struct v4l2_control *vc = arg;
  70305. + int i;
  70306. +
  70307. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  70308. + if (vc->id == pxp_controls[i].id) {
  70309. + retval = pxp_get_cstate(cam, vc);
  70310. + break;
  70311. + }
  70312. +
  70313. + if (i >= ARRAY_SIZE(pxp_controls))
  70314. + retval = -EINVAL;
  70315. + break;
  70316. + }
  70317. + case VIDIOC_QUERYCTRL:
  70318. + {
  70319. + struct v4l2_queryctrl *qc = arg;
  70320. + int i;
  70321. +
  70322. + for (i = 0; i < ARRAY_SIZE(pxp_controls); i++)
  70323. + if (qc->id && qc->id == pxp_controls[i].id) {
  70324. + memcpy(qc, &(pxp_controls[i]), sizeof(*qc));
  70325. + break;
  70326. + }
  70327. +
  70328. + if (i >= ARRAY_SIZE(pxp_controls))
  70329. + retval = -EINVAL;
  70330. + break;
  70331. + }
  70332. + case VIDIOC_G_STD:
  70333. + case VIDIOC_G_OUTPUT:
  70334. + case VIDIOC_S_OUTPUT:
  70335. + case VIDIOC_ENUMSTD:
  70336. + case VIDIOC_S_STD:
  70337. + case VIDIOC_TRY_FMT:
  70338. + case VIDIOC_ENUMINPUT:
  70339. + case VIDIOC_G_INPUT:
  70340. + case VIDIOC_S_INPUT:
  70341. + case VIDIOC_G_TUNER:
  70342. + case VIDIOC_S_TUNER:
  70343. + case VIDIOC_G_FREQUENCY:
  70344. + case VIDIOC_S_FREQUENCY:
  70345. + case VIDIOC_ENUMOUTPUT:
  70346. + default:
  70347. + pr_debug(" case not supported\n");
  70348. + retval = -EINVAL;
  70349. + break;
  70350. + }
  70351. +
  70352. + if (ioctlnr != VIDIOC_DQBUF)
  70353. + up(&cam->busy_lock);
  70354. + return retval;
  70355. +}
  70356. +
  70357. +/*
  70358. + * V4L interface - ioctl function
  70359. + *
  70360. + * @return None
  70361. + */
  70362. +static long csi_v4l_ioctl(struct file *file,
  70363. + unsigned int cmd, unsigned long arg)
  70364. +{
  70365. + return video_usercopy(file, cmd, arg, csi_v4l_do_ioctl);
  70366. +}
  70367. +
  70368. +/*!
  70369. + * V4L interface - mmap function
  70370. + *
  70371. + * @param file structure file *
  70372. + *
  70373. + * @param vma structure vm_area_struct *
  70374. + *
  70375. + * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
  70376. + */
  70377. +static int csi_mmap(struct file *file, struct vm_area_struct *vma)
  70378. +{
  70379. + struct video_device *dev = video_devdata(file);
  70380. + unsigned long size;
  70381. + int res = 0;
  70382. + cam_data *cam = video_get_drvdata(dev);
  70383. +
  70384. + pr_debug("%s\n", __func__);
  70385. + pr_debug("\npgoff=0x%lx, start=0x%lx, end=0x%lx\n",
  70386. + vma->vm_pgoff, vma->vm_start, vma->vm_end);
  70387. +
  70388. + /* make this _really_ smp-safe */
  70389. + if (down_interruptible(&cam->busy_lock))
  70390. + return -EINTR;
  70391. +
  70392. + size = vma->vm_end - vma->vm_start;
  70393. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  70394. +
  70395. + if (remap_pfn_range(vma, vma->vm_start,
  70396. + vma->vm_pgoff, size, vma->vm_page_prot)) {
  70397. + pr_err("ERROR: v4l2 capture: %s : "
  70398. + "remap_pfn_range failed\n", __func__);
  70399. + res = -ENOBUFS;
  70400. + goto csi_mmap_exit;
  70401. + }
  70402. +
  70403. + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
  70404. +
  70405. +csi_mmap_exit:
  70406. + up(&cam->busy_lock);
  70407. + return res;
  70408. +}
  70409. +
  70410. +/*!
  70411. + * This structure defines the functions to be called in this driver.
  70412. + */
  70413. +static struct v4l2_file_operations csi_v4l_fops = {
  70414. + .owner = THIS_MODULE,
  70415. + .open = csi_v4l_open,
  70416. + .release = csi_v4l_close,
  70417. + .read = csi_v4l_read,
  70418. + .ioctl = csi_v4l_ioctl,
  70419. + .mmap = csi_mmap,
  70420. +};
  70421. +
  70422. +static struct video_device csi_v4l_template = {
  70423. + .name = "Mx25 Camera",
  70424. + .fops = &csi_v4l_fops,
  70425. + .release = video_device_release,
  70426. +};
  70427. +
  70428. +/*!
  70429. + * initialize cam_data structure
  70430. + *
  70431. + * @param cam structure cam_data *
  70432. + *
  70433. + * @return status 0 Success
  70434. + */
  70435. +static void init_camera_struct(cam_data *cam)
  70436. +{
  70437. + struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
  70438. + pr_debug("In MVC: %s\n", __func__);
  70439. +
  70440. + proc_data->hflip = 0;
  70441. + proc_data->vflip = 0;
  70442. + proc_data->rotate = 0;
  70443. + proc_data->bgcolor = 0;
  70444. +
  70445. + /* Default everything to 0 */
  70446. + memset(cam, 0, sizeof(cam_data));
  70447. +
  70448. + sema_init(&cam->param_lock, 1);
  70449. + sema_init(&cam->busy_lock, 1);
  70450. +
  70451. + cam->video_dev = video_device_alloc();
  70452. + if (cam->video_dev == NULL)
  70453. + return;
  70454. +
  70455. + *(cam->video_dev) = csi_v4l_template;
  70456. +
  70457. + video_set_drvdata(cam->video_dev, cam);
  70458. + cam->video_dev->minor = -1;
  70459. +
  70460. + init_waitqueue_head(&cam->enc_queue);
  70461. + init_waitqueue_head(&cam->still_queue);
  70462. +
  70463. + cam->streamparm.parm.capture.capturemode = 0;
  70464. +
  70465. + cam->standard.index = 0;
  70466. + cam->standard.id = V4L2_STD_UNKNOWN;
  70467. + cam->standard.frameperiod.denominator = 30;
  70468. + cam->standard.frameperiod.numerator = 1;
  70469. + cam->standard.framelines = 480;
  70470. + cam->standard_autodetect = true;
  70471. + cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  70472. + cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
  70473. + cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
  70474. + cam->overlay_on = false;
  70475. + cam->capture_on = false;
  70476. + cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
  70477. +
  70478. + cam->v2f.fmt.pix.sizeimage = 480 * 640 * 2;
  70479. + cam->v2f.fmt.pix.bytesperline = 640 * 2;
  70480. + cam->v2f.fmt.pix.width = 640;
  70481. + cam->v2f.fmt.pix.height = 480;
  70482. + cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  70483. + cam->win.w.width = 160;
  70484. + cam->win.w.height = 160;
  70485. + cam->win.w.left = 0;
  70486. + cam->win.w.top = 0;
  70487. + cam->still_counter = 0;
  70488. + /* setup cropping */
  70489. + cam->crop_bounds.left = 0;
  70490. + cam->crop_bounds.width = 640;
  70491. + cam->crop_bounds.top = 0;
  70492. + cam->crop_bounds.height = 480;
  70493. + cam->crop_current = cam->crop_defrect = cam->crop_bounds;
  70494. +
  70495. + cam->enc_callback = camera_callback;
  70496. + csi_start_callback(cam);
  70497. + init_waitqueue_head(&cam->power_queue);
  70498. + spin_lock_init(&cam->queue_int_lock);
  70499. + spin_lock_init(&cam->dqueue_int_lock);
  70500. +}
  70501. +
  70502. +/*!
  70503. + * camera_power function
  70504. + * Turns Sensor power On/Off
  70505. + *
  70506. + * @param cam cam data struct
  70507. + * @param cameraOn true to turn camera on, false to turn off power.
  70508. + *
  70509. + * @return status
  70510. + */
  70511. +static u8 camera_power(cam_data *cam, bool cameraOn)
  70512. +{
  70513. + pr_debug("In MVC: %s on=%d\n", __func__, cameraOn);
  70514. +
  70515. + if (cameraOn == true) {
  70516. + vidioc_int_s_power(cam->sensor, 1);
  70517. + } else {
  70518. + vidioc_int_s_power(cam->sensor, 0);
  70519. + }
  70520. + return 0;
  70521. +}
  70522. +
  70523. +static const struct of_device_id imx_csi_v4l2_dt_ids[] = {
  70524. + { .compatible = "fsl,imx6sl-csi-v4l2", },
  70525. + { /* sentinel */ }
  70526. +};
  70527. +MODULE_DEVICE_TABLE(of, imx_csi_v4l2_dt_ids);
  70528. +
  70529. +static int csi_v4l2_probe(struct platform_device *pdev)
  70530. +{
  70531. + struct scatterlist *sg;
  70532. + u8 err = 0;
  70533. +
  70534. + /* Create g_cam and initialize it. */
  70535. + g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
  70536. + if (g_cam == NULL) {
  70537. + pr_err("ERROR: v4l2 capture: failed to register camera\n");
  70538. + err = -ENOMEM;
  70539. + goto out;
  70540. + }
  70541. + memset(&crop_current, 0, sizeof(crop_current));
  70542. + memset(&win_current, 0, sizeof(win_current));
  70543. + init_camera_struct(g_cam);
  70544. + platform_set_drvdata(pdev, (void *)g_cam);
  70545. +
  70546. + /* Set up the v4l2 device and register it */
  70547. + csi_v4l2_int_device.priv = g_cam;
  70548. + /* This function contains a bug that won't let this be rmmod'd. */
  70549. + v4l2_int_device_register(&csi_v4l2_int_device);
  70550. +
  70551. + /* register v4l video device */
  70552. + if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
  70553. + == -1) {
  70554. + kfree(g_cam);
  70555. + g_cam = NULL;
  70556. + pr_err("ERROR: v4l2 capture: video_register_device failed\n");
  70557. + err = -ENODEV;
  70558. + goto out;
  70559. + }
  70560. + pr_debug(" Video device registered: %s #%d\n",
  70561. + g_cam->video_dev->name, g_cam->video_dev->minor);
  70562. +
  70563. + g_cam->pxp_chan = NULL;
  70564. + /* Initialize Scatter-gather list containing 2 buffer addresses. */
  70565. + sg = g_cam->sg;
  70566. + sg_init_table(sg, 2);
  70567. +
  70568. +out:
  70569. + return err;
  70570. +}
  70571. +
  70572. +static int csi_v4l2_remove(struct platform_device *pdev)
  70573. +{
  70574. + if (g_cam->open_count) {
  70575. + pr_err("ERROR: v4l2 capture:camera open "
  70576. + "-- setting ops to NULL\n");
  70577. + } else {
  70578. + pr_info("V4L2 freeing image input device\n");
  70579. + v4l2_int_device_unregister(&csi_v4l2_int_device);
  70580. + csi_stop_callback(g_cam);
  70581. + video_unregister_device(g_cam->video_dev);
  70582. + platform_set_drvdata(pdev, NULL);
  70583. +
  70584. + kfree(g_cam);
  70585. + g_cam = NULL;
  70586. + }
  70587. +
  70588. + return 0;
  70589. +}
  70590. +
  70591. +/*!
  70592. + * This function is called to put the sensor in a low power state.
  70593. + * Refer to the document driver-model/driver.txt in the kernel source tree
  70594. + * for more information.
  70595. + *
  70596. + * @param pdev the device structure used to give information on which I2C
  70597. + * to suspend
  70598. + * @param state the power state the device is entering
  70599. + *
  70600. + * @return The function returns 0 on success and -1 on failure.
  70601. + */
  70602. +static int csi_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
  70603. +{
  70604. + cam_data *cam = platform_get_drvdata(pdev);
  70605. +
  70606. + pr_debug("In MVC: %s\n", __func__);
  70607. +
  70608. + if (cam == NULL)
  70609. + return -1;
  70610. +
  70611. + cam->low_power = true;
  70612. +
  70613. + if (cam->overlay_on == true)
  70614. + stop_preview(cam);
  70615. +
  70616. + if (cam->capture_on == true || cam->overlay_on == true)
  70617. + camera_power(cam, false);
  70618. +
  70619. + return 0;
  70620. +}
  70621. +
  70622. +/*!
  70623. + * This function is called to bring the sensor back from a low power state.
  70624. + * Refer to the document driver-model/driver.txt in the kernel source tree
  70625. + * for more information.
  70626. + *
  70627. + * @param pdev the device structure
  70628. + *
  70629. + * @return The function returns 0 on success and -1 on failure
  70630. + */
  70631. +static int csi_v4l2_resume(struct platform_device *pdev)
  70632. +{
  70633. + cam_data *cam = platform_get_drvdata(pdev);
  70634. +
  70635. + pr_debug("In MVC: %s\n", __func__);
  70636. +
  70637. + if (cam == NULL)
  70638. + return -1;
  70639. +
  70640. + cam->low_power = false;
  70641. + wake_up_interruptible(&cam->power_queue);
  70642. + if (cam->capture_on == true || cam->overlay_on == true)
  70643. + camera_power(cam, true);
  70644. +
  70645. + if (cam->overlay_on == true)
  70646. + start_preview(cam);
  70647. +
  70648. + return 0;
  70649. +}
  70650. +
  70651. +/*!
  70652. + * This structure contains pointers to the power management callback functions.
  70653. + */
  70654. +static struct platform_driver csi_v4l2_driver = {
  70655. + .driver = {
  70656. + .name = "csi_v4l2",
  70657. + .of_match_table = of_match_ptr(imx_csi_v4l2_dt_ids),
  70658. + },
  70659. + .probe = csi_v4l2_probe,
  70660. + .remove = csi_v4l2_remove,
  70661. +#ifdef CONFIG_PM
  70662. + .suspend = csi_v4l2_suspend,
  70663. + .resume = csi_v4l2_resume,
  70664. +#endif
  70665. + .shutdown = NULL,
  70666. +};
  70667. +
  70668. +/*!
  70669. + * Initializes the camera driver.
  70670. + */
  70671. +static int csi_v4l2_master_attach(struct v4l2_int_device *slave)
  70672. +{
  70673. + cam_data *cam = slave->u.slave->master->priv;
  70674. + struct v4l2_format cam_fmt;
  70675. +
  70676. + pr_debug("In MVC: %s\n", __func__);
  70677. + pr_debug(" slave.name = %s\n", slave->name);
  70678. + pr_debug(" master.name = %s\n", slave->u.slave->master->name);
  70679. +
  70680. + cam->sensor = slave;
  70681. + if (slave == NULL) {
  70682. + pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
  70683. + return -1;
  70684. + }
  70685. +
  70686. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  70687. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  70688. +
  70689. + /* Used to detect TV in (type 1) vs. camera (type 0) */
  70690. + cam->device_type = cam_fmt.fmt.pix.priv;
  70691. +
  70692. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  70693. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  70694. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  70695. +
  70696. + /* This also is the max crop size for this device. */
  70697. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  70698. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  70699. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  70700. +
  70701. + /* At this point, this is also the current image size. */
  70702. + cam->crop_current.top = cam->crop_current.left = 0;
  70703. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  70704. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  70705. +
  70706. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  70707. + __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  70708. +
  70709. + return 0;
  70710. +}
  70711. +
  70712. +/*!
  70713. + * Disconnects the camera driver.
  70714. + */
  70715. +static void csi_v4l2_master_detach(struct v4l2_int_device *slave)
  70716. +{
  70717. + pr_debug("In MVC: %s\n", __func__);
  70718. +
  70719. + vidioc_int_dev_exit(slave);
  70720. +}
  70721. +
  70722. +module_platform_driver(csi_v4l2_driver);
  70723. +
  70724. +module_param(video_nr, int, 0444);
  70725. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  70726. +MODULE_DESCRIPTION("V4L2 capture driver for Mx25 based cameras");
  70727. +MODULE_LICENSE("GPL");
  70728. +MODULE_SUPPORTED_DEVICE("video");
  70729. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/fsl_csi.c linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.c
  70730. --- linux-3.14.17/drivers/media/platform/mxc/capture/fsl_csi.c 1970-01-01 01:00:00.000000000 +0100
  70731. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.c 2014-09-11 18:06:02.254038983 +0200
  70732. @@ -0,0 +1,302 @@
  70733. +/*
  70734. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  70735. + */
  70736. +
  70737. +/*
  70738. + * The code contained herein is licensed under the GNU General Public
  70739. + * License. You may obtain a copy of the GNU General Public License
  70740. + * Version 2 or later at the following locations:
  70741. + *
  70742. + * http://www.opensource.org/licenses/gpl-license.html
  70743. + * http://www.gnu.org/copyleft/gpl.html
  70744. + */
  70745. +
  70746. +/*!
  70747. + * @file fsl_csi.c, this file is derived from mx27_csi.c
  70748. + *
  70749. + * @brief mx25 CMOS Sensor interface functions
  70750. + *
  70751. + * @ingroup CSI
  70752. + */
  70753. +#include <linux/types.h>
  70754. +#include <linux/init.h>
  70755. +#include <linux/platform_device.h>
  70756. +#include <linux/device.h>
  70757. +#include <linux/err.h>
  70758. +#include <linux/interrupt.h>
  70759. +#include <linux/spinlock.h>
  70760. +#include <linux/module.h>
  70761. +#include <linux/clk.h>
  70762. +#include <linux/of.h>
  70763. +#include <linux/sched.h>
  70764. +
  70765. +#include "mxc_v4l2_capture.h"
  70766. +#include "fsl_csi.h"
  70767. +
  70768. +void __iomem *csi_regbase;
  70769. +EXPORT_SYMBOL(csi_regbase);
  70770. +static int irq_nr;
  70771. +static csi_irq_callback_t g_callback;
  70772. +static void *g_callback_data;
  70773. +
  70774. +static irqreturn_t csi_irq_handler(int irq, void *data)
  70775. +{
  70776. + cam_data *cam = (cam_data *) data;
  70777. + unsigned long status = __raw_readl(CSI_CSISR);
  70778. +
  70779. + __raw_writel(status, CSI_CSISR);
  70780. +
  70781. + if (status & BIT_HRESP_ERR_INT)
  70782. + pr_warning("Hresponse error is detected.\n");
  70783. +
  70784. + if (status & BIT_DMA_TSF_DONE_FB1) {
  70785. + if (cam->capture_on) {
  70786. + spin_lock(&cam->queue_int_lock);
  70787. + cam->ping_pong_csi = 1;
  70788. + spin_unlock(&cam->queue_int_lock);
  70789. + cam->enc_callback(0, cam);
  70790. + } else {
  70791. + cam->still_counter++;
  70792. + wake_up_interruptible(&cam->still_queue);
  70793. + }
  70794. + }
  70795. +
  70796. + if (status & BIT_DMA_TSF_DONE_FB2) {
  70797. + if (cam->capture_on) {
  70798. + spin_lock(&cam->queue_int_lock);
  70799. + cam->ping_pong_csi = 2;
  70800. + spin_unlock(&cam->queue_int_lock);
  70801. + cam->enc_callback(0, cam);
  70802. + } else {
  70803. + cam->still_counter++;
  70804. + wake_up_interruptible(&cam->still_queue);
  70805. + }
  70806. + }
  70807. +
  70808. + if (g_callback)
  70809. + g_callback(g_callback_data, status);
  70810. +
  70811. + pr_debug("CSI status = 0x%08lX\n", status);
  70812. +
  70813. + return IRQ_HANDLED;
  70814. +}
  70815. +
  70816. +static void csihw_reset_frame_count(void)
  70817. +{
  70818. + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST, CSI_CSICR3);
  70819. +}
  70820. +
  70821. +static void csihw_reset(void)
  70822. +{
  70823. + csihw_reset_frame_count();
  70824. + __raw_writel(CSICR1_RESET_VAL, CSI_CSICR1);
  70825. + __raw_writel(CSICR2_RESET_VAL, CSI_CSICR2);
  70826. + __raw_writel(CSICR3_RESET_VAL, CSI_CSICR3);
  70827. +}
  70828. +
  70829. +/*!
  70830. + * csi_init_interface
  70831. + * Init csi interface
  70832. + */
  70833. +void csi_init_interface(void)
  70834. +{
  70835. + unsigned int val = 0;
  70836. + unsigned int imag_para;
  70837. +
  70838. + val |= BIT_SOF_POL;
  70839. + val |= BIT_REDGE;
  70840. + val |= BIT_GCLK_MODE;
  70841. + val |= BIT_HSYNC_POL;
  70842. + val |= BIT_PACK_DIR;
  70843. + val |= BIT_FCC;
  70844. + val |= BIT_SWAP16_EN;
  70845. + val |= 1 << SHIFT_MCLKDIV;
  70846. + val |= BIT_MCLKEN;
  70847. + __raw_writel(val, CSI_CSICR1);
  70848. +
  70849. + imag_para = (640 << 16) | 960;
  70850. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  70851. +
  70852. + val = 0x1010;
  70853. + val |= BIT_DMA_REFLASH_RFF;
  70854. + __raw_writel(val, CSI_CSICR3);
  70855. +}
  70856. +EXPORT_SYMBOL(csi_init_interface);
  70857. +
  70858. +void csi_init_format(int fmt)
  70859. +{
  70860. + unsigned int val;
  70861. +
  70862. + val = __raw_readl(CSI_CSICR1);
  70863. + if (fmt == V4L2_PIX_FMT_YUYV) {
  70864. + val &= ~BIT_PACK_DIR;
  70865. + val &= ~BIT_SWAP16_EN;
  70866. + } else if (fmt == V4L2_PIX_FMT_UYVY) {
  70867. + val |= BIT_PACK_DIR;
  70868. + val |= BIT_SWAP16_EN;
  70869. + } else
  70870. + pr_warning("unsupported format, old format remains.\n");
  70871. +
  70872. + __raw_writel(val, CSI_CSICR1);
  70873. +}
  70874. +EXPORT_SYMBOL(csi_init_format);
  70875. +
  70876. +/*!
  70877. + * csi_read_mclk_flag
  70878. + *
  70879. + * @return gcsi_mclk_source
  70880. + */
  70881. +int csi_read_mclk_flag(void)
  70882. +{
  70883. + return 0;
  70884. +}
  70885. +EXPORT_SYMBOL(csi_read_mclk_flag);
  70886. +
  70887. +void csi_start_callback(void *data)
  70888. +{
  70889. + cam_data *cam = (cam_data *) data;
  70890. +
  70891. + if (request_irq(irq_nr, csi_irq_handler, 0, "csi", cam) < 0)
  70892. + pr_debug("CSI error: irq request fail\n");
  70893. +
  70894. +}
  70895. +EXPORT_SYMBOL(csi_start_callback);
  70896. +
  70897. +void csi_stop_callback(void *data)
  70898. +{
  70899. + cam_data *cam = (cam_data *) data;
  70900. +
  70901. + free_irq(irq_nr, cam);
  70902. +}
  70903. +EXPORT_SYMBOL(csi_stop_callback);
  70904. +
  70905. +void csi_enable_int(int arg)
  70906. +{
  70907. + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  70908. +
  70909. + cr1 |= BIT_SOF_INTEN;
  70910. + if (arg == 1) {
  70911. + /* still capture needs DMA intterrupt */
  70912. + cr1 |= BIT_FB1_DMA_DONE_INTEN;
  70913. + cr1 |= BIT_FB2_DMA_DONE_INTEN;
  70914. + }
  70915. + __raw_writel(cr1, CSI_CSICR1);
  70916. +}
  70917. +EXPORT_SYMBOL(csi_enable_int);
  70918. +
  70919. +void csi_disable_int(void)
  70920. +{
  70921. + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  70922. +
  70923. + cr1 &= ~BIT_SOF_INTEN;
  70924. + cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
  70925. + cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
  70926. + __raw_writel(cr1, CSI_CSICR1);
  70927. +}
  70928. +EXPORT_SYMBOL(csi_disable_int);
  70929. +
  70930. +void csi_set_16bit_imagpara(int width, int height)
  70931. +{
  70932. + int imag_para = 0;
  70933. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  70934. +
  70935. + imag_para = (width << 16) | (height * 2);
  70936. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  70937. +
  70938. + /* reflash the embeded DMA controller */
  70939. + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  70940. +}
  70941. +EXPORT_SYMBOL(csi_set_16bit_imagpara);
  70942. +
  70943. +void csi_set_12bit_imagpara(int width, int height)
  70944. +{
  70945. + int imag_para = 0;
  70946. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  70947. +
  70948. + imag_para = (width << 16) | (height * 3 / 2);
  70949. + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  70950. +
  70951. + /* reflash the embeded DMA controller */
  70952. + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  70953. +}
  70954. +EXPORT_SYMBOL(csi_set_12bit_imagpara);
  70955. +
  70956. +void csi_dmareq_rff_enable(void)
  70957. +{
  70958. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  70959. +
  70960. + cr3 |= BIT_DMA_REQ_EN_RFF;
  70961. + cr3 |= BIT_HRESP_ERR_EN;
  70962. + __raw_writel(cr3, CSI_CSICR3);
  70963. +}
  70964. +EXPORT_SYMBOL(csi_dmareq_rff_enable);
  70965. +
  70966. +void csi_dmareq_rff_disable(void)
  70967. +{
  70968. + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  70969. +
  70970. + cr3 &= ~BIT_DMA_REQ_EN_RFF;
  70971. + cr3 &= ~BIT_HRESP_ERR_EN;
  70972. + __raw_writel(cr3, CSI_CSICR3);
  70973. +}
  70974. +EXPORT_SYMBOL(csi_dmareq_rff_disable);
  70975. +
  70976. +static const struct of_device_id fsl_csi_dt_ids[] = {
  70977. + { .compatible = "fsl,imx6sl-csi", },
  70978. + { /* sentinel */ }
  70979. +};
  70980. +MODULE_DEVICE_TABLE(of, fsl_csi_dt_ids);
  70981. +
  70982. +static int csi_probe(struct platform_device *pdev)
  70983. +{
  70984. + int ret = 0;
  70985. + struct resource *res;
  70986. +
  70987. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  70988. + if (!res) {
  70989. + dev_err(&pdev->dev, "No csi irq found.\n");
  70990. + ret = -ENODEV;
  70991. + goto err;
  70992. + }
  70993. + irq_nr = res->start;
  70994. +
  70995. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  70996. + if (!res) {
  70997. + dev_err(&pdev->dev, "No csi base address found.\n");
  70998. + ret = -ENODEV;
  70999. + goto err;
  71000. + }
  71001. + csi_regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
  71002. + if (!csi_regbase) {
  71003. + dev_err(&pdev->dev, "ioremap failed with csi base\n");
  71004. + ret = -ENOMEM;
  71005. + goto err;
  71006. + }
  71007. +
  71008. + csihw_reset();
  71009. + csi_init_interface();
  71010. + csi_dmareq_rff_disable();
  71011. +
  71012. +err:
  71013. + return ret;
  71014. +}
  71015. +
  71016. +static int csi_remove(struct platform_device *pdev)
  71017. +{
  71018. + return 0;
  71019. +}
  71020. +
  71021. +static struct platform_driver csi_driver = {
  71022. + .driver = {
  71023. + .name = "fsl_csi",
  71024. + .of_match_table = of_match_ptr(fsl_csi_dt_ids),
  71025. + },
  71026. + .probe = csi_probe,
  71027. + .remove = csi_remove,
  71028. +};
  71029. +
  71030. +module_platform_driver(csi_driver);
  71031. +
  71032. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  71033. +MODULE_DESCRIPTION("fsl CSI driver");
  71034. +MODULE_LICENSE("GPL");
  71035. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/fsl_csi.h linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.h
  71036. --- linux-3.14.17/drivers/media/platform/mxc/capture/fsl_csi.h 1970-01-01 01:00:00.000000000 +0100
  71037. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/fsl_csi.h 2014-09-11 18:06:02.254038983 +0200
  71038. @@ -0,0 +1,198 @@
  71039. +/*
  71040. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  71041. + */
  71042. +
  71043. +/*
  71044. + * The code contained herein is licensed under the GNU General Public
  71045. + * License. You may obtain a copy of the GNU General Public License
  71046. + * Version 2 or later at the following locations:
  71047. + *
  71048. + * http://www.opensource.org/licenses/gpl-license.html
  71049. + * http://www.gnu.org/copyleft/gpl.html
  71050. + */
  71051. +
  71052. +/*!
  71053. + * @file fsl_csi.h
  71054. + *
  71055. + * @brief mx25 CMOS Sensor interface functions
  71056. + *
  71057. + * @ingroup CSI
  71058. + */
  71059. +
  71060. +#ifndef MX25_CSI_H
  71061. +#define MX25_CSI_H
  71062. +
  71063. +#include <linux/io.h>
  71064. +
  71065. +/* reset values */
  71066. +#define CSICR1_RESET_VAL 0x40000800
  71067. +#define CSICR2_RESET_VAL 0x0
  71068. +#define CSICR3_RESET_VAL 0x0
  71069. +
  71070. +/* csi control reg 1 */
  71071. +#define BIT_SWAP16_EN (0x1 << 31)
  71072. +#define BIT_EXT_VSYNC (0x1 << 30)
  71073. +#define BIT_EOF_INT_EN (0x1 << 29)
  71074. +#define BIT_PRP_IF_EN (0x1 << 28)
  71075. +#define BIT_CCIR_MODE (0x1 << 27)
  71076. +#define BIT_COF_INT_EN (0x1 << 26)
  71077. +#define BIT_SF_OR_INTEN (0x1 << 25)
  71078. +#define BIT_RF_OR_INTEN (0x1 << 24)
  71079. +#define BIT_SFF_DMA_DONE_INTEN (0x1 << 22)
  71080. +#define BIT_STATFF_INTEN (0x1 << 21)
  71081. +#define BIT_FB2_DMA_DONE_INTEN (0x1 << 20)
  71082. +#define BIT_FB1_DMA_DONE_INTEN (0x1 << 19)
  71083. +#define BIT_RXFF_INTEN (0x1 << 18)
  71084. +#define BIT_SOF_POL (0x1 << 17)
  71085. +#define BIT_SOF_INTEN (0x1 << 16)
  71086. +#define BIT_MCLKDIV (0xF << 12)
  71087. +#define BIT_HSYNC_POL (0x1 << 11)
  71088. +#define BIT_CCIR_EN (0x1 << 10)
  71089. +#define BIT_MCLKEN (0x1 << 9)
  71090. +#define BIT_FCC (0x1 << 8)
  71091. +#define BIT_PACK_DIR (0x1 << 7)
  71092. +#define BIT_CLR_STATFIFO (0x1 << 6)
  71093. +#define BIT_CLR_RXFIFO (0x1 << 5)
  71094. +#define BIT_GCLK_MODE (0x1 << 4)
  71095. +#define BIT_INV_DATA (0x1 << 3)
  71096. +#define BIT_INV_PCLK (0x1 << 2)
  71097. +#define BIT_REDGE (0x1 << 1)
  71098. +#define BIT_PIXEL_BIT (0x1 << 0)
  71099. +
  71100. +#define SHIFT_MCLKDIV 12
  71101. +
  71102. +/* control reg 3 */
  71103. +#define BIT_FRMCNT (0xFFFF << 16)
  71104. +#define BIT_FRMCNT_RST (0x1 << 15)
  71105. +#define BIT_DMA_REFLASH_RFF (0x1 << 14)
  71106. +#define BIT_DMA_REFLASH_SFF (0x1 << 13)
  71107. +#define BIT_DMA_REQ_EN_RFF (0x1 << 12)
  71108. +#define BIT_DMA_REQ_EN_SFF (0x1 << 11)
  71109. +#define BIT_STATFF_LEVEL (0x7 << 8)
  71110. +#define BIT_HRESP_ERR_EN (0x1 << 7)
  71111. +#define BIT_RXFF_LEVEL (0x7 << 4)
  71112. +#define BIT_TWO_8BIT_SENSOR (0x1 << 3)
  71113. +#define BIT_ZERO_PACK_EN (0x1 << 2)
  71114. +#define BIT_ECC_INT_EN (0x1 << 1)
  71115. +#define BIT_ECC_AUTO_EN (0x1 << 0)
  71116. +
  71117. +#define SHIFT_FRMCNT 16
  71118. +
  71119. +/* csi status reg */
  71120. +#define BIT_SFF_OR_INT (0x1 << 25)
  71121. +#define BIT_RFF_OR_INT (0x1 << 24)
  71122. +#define BIT_DMA_TSF_DONE_SFF (0x1 << 22)
  71123. +#define BIT_STATFF_INT (0x1 << 21)
  71124. +#define BIT_DMA_TSF_DONE_FB2 (0x1 << 20)
  71125. +#define BIT_DMA_TSF_DONE_FB1 (0x1 << 19)
  71126. +#define BIT_RXFF_INT (0x1 << 18)
  71127. +#define BIT_EOF_INT (0x1 << 17)
  71128. +#define BIT_SOF_INT (0x1 << 16)
  71129. +#define BIT_F2_INT (0x1 << 15)
  71130. +#define BIT_F1_INT (0x1 << 14)
  71131. +#define BIT_COF_INT (0x1 << 13)
  71132. +#define BIT_HRESP_ERR_INT (0x1 << 7)
  71133. +#define BIT_ECC_INT (0x1 << 1)
  71134. +#define BIT_DRDY (0x1 << 0)
  71135. +
  71136. +#define CSI_MCLK_VF 1
  71137. +#define CSI_MCLK_ENC 2
  71138. +#define CSI_MCLK_RAW 4
  71139. +#define CSI_MCLK_I2C 8
  71140. +#endif
  71141. +
  71142. +extern void __iomem *csi_regbase;
  71143. +#define CSI_CSICR1 (csi_regbase)
  71144. +#define CSI_CSICR2 (csi_regbase + 0x4)
  71145. +#define CSI_CSICR3 (csi_regbase + 0x8)
  71146. +#define CSI_STATFIFO (csi_regbase + 0xC)
  71147. +#define CSI_CSIRXFIFO (csi_regbase + 0x10)
  71148. +#define CSI_CSIRXCNT (csi_regbase + 0x14)
  71149. +#define CSI_CSISR (csi_regbase + 0x18)
  71150. +
  71151. +#define CSI_CSIDBG (csi_regbase + 0x1C)
  71152. +#define CSI_CSIDMASA_STATFIFO (csi_regbase + 0x20)
  71153. +#define CSI_CSIDMATS_STATFIFO (csi_regbase + 0x24)
  71154. +#define CSI_CSIDMASA_FB1 (csi_regbase + 0x28)
  71155. +#define CSI_CSIDMASA_FB2 (csi_regbase + 0x2C)
  71156. +#define CSI_CSIFBUF_PARA (csi_regbase + 0x30)
  71157. +#define CSI_CSIIMAG_PARA (csi_regbase + 0x34)
  71158. +
  71159. +static inline void csi_clear_status(unsigned long status)
  71160. +{
  71161. + __raw_writel(status, CSI_CSISR);
  71162. +}
  71163. +
  71164. +struct csi_signal_cfg_t {
  71165. + unsigned data_width:3;
  71166. + unsigned clk_mode:2;
  71167. + unsigned ext_vsync:1;
  71168. + unsigned Vsync_pol:1;
  71169. + unsigned Hsync_pol:1;
  71170. + unsigned pixclk_pol:1;
  71171. + unsigned data_pol:1;
  71172. + unsigned sens_clksrc:1;
  71173. +};
  71174. +
  71175. +struct csi_config_t {
  71176. + /* control reg 1 */
  71177. + unsigned int swap16_en:1;
  71178. + unsigned int ext_vsync:1;
  71179. + unsigned int eof_int_en:1;
  71180. + unsigned int prp_if_en:1;
  71181. + unsigned int ccir_mode:1;
  71182. + unsigned int cof_int_en:1;
  71183. + unsigned int sf_or_inten:1;
  71184. + unsigned int rf_or_inten:1;
  71185. + unsigned int sff_dma_done_inten:1;
  71186. + unsigned int statff_inten:1;
  71187. + unsigned int fb2_dma_done_inten:1;
  71188. + unsigned int fb1_dma_done_inten:1;
  71189. + unsigned int rxff_inten:1;
  71190. + unsigned int sof_pol:1;
  71191. + unsigned int sof_inten:1;
  71192. + unsigned int mclkdiv:4;
  71193. + unsigned int hsync_pol:1;
  71194. + unsigned int ccir_en:1;
  71195. + unsigned int mclken:1;
  71196. + unsigned int fcc:1;
  71197. + unsigned int pack_dir:1;
  71198. + unsigned int gclk_mode:1;
  71199. + unsigned int inv_data:1;
  71200. + unsigned int inv_pclk:1;
  71201. + unsigned int redge:1;
  71202. + unsigned int pixel_bit:1;
  71203. +
  71204. + /* control reg 3 */
  71205. + unsigned int frmcnt:16;
  71206. + unsigned int frame_reset:1;
  71207. + unsigned int dma_reflash_rff:1;
  71208. + unsigned int dma_reflash_sff:1;
  71209. + unsigned int dma_req_en_rff:1;
  71210. + unsigned int dma_req_en_sff:1;
  71211. + unsigned int statff_level:3;
  71212. + unsigned int hresp_err_en:1;
  71213. + unsigned int rxff_level:3;
  71214. + unsigned int two_8bit_sensor:1;
  71215. + unsigned int zero_pack_en:1;
  71216. + unsigned int ecc_int_en:1;
  71217. + unsigned int ecc_auto_en:1;
  71218. + /* fifo counter */
  71219. + unsigned int rxcnt;
  71220. +};
  71221. +
  71222. +typedef void (*csi_irq_callback_t) (void *data, unsigned long status);
  71223. +
  71224. +void csi_init_interface(void);
  71225. +void csi_init_format(int fmt);
  71226. +void csi_set_16bit_imagpara(int width, int height);
  71227. +void csi_set_12bit_imagpara(int width, int height);
  71228. +int csi_read_mclk_flag(void);
  71229. +void csi_start_callback(void *data);
  71230. +void csi_stop_callback(void *data);
  71231. +void csi_enable_int(int arg);
  71232. +void csi_disable_int(void);
  71233. +void csi_mclk_enable(void);
  71234. +void csi_mclk_disable(void);
  71235. +void csi_dmareq_rff_enable(void);
  71236. +void csi_dmareq_rff_disable(void);
  71237. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c
  71238. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c 1970-01-01 01:00:00.000000000 +0100
  71239. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_bg_overlay_sdc.c 2014-09-11 18:06:02.254038983 +0200
  71240. @@ -0,0 +1,546 @@
  71241. +
  71242. +/*
  71243. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  71244. + */
  71245. +
  71246. +/*
  71247. + * The code contained herein is licensed under the GNU General Public
  71248. + * License. You may obtain a copy of the GNU General Public License
  71249. + * Version 2 or later at the following locations:
  71250. + *
  71251. + * http://www.opensource.org/licenses/gpl-license.html
  71252. + * http://www.gnu.org/copyleft/gpl.html
  71253. + */
  71254. +
  71255. +/*!
  71256. + * @file ipu_bg_overlay_sdc_bg.c
  71257. + *
  71258. + * @brief IPU Use case for PRP-VF back-ground
  71259. + *
  71260. + * @ingroup IPU
  71261. + */
  71262. +#include <linux/module.h>
  71263. +#include <linux/dma-mapping.h>
  71264. +#include <linux/fb.h>
  71265. +#include <linux/ipu.h>
  71266. +#include <linux/mipi_csi2.h>
  71267. +#include "mxc_v4l2_capture.h"
  71268. +#include "ipu_prp_sw.h"
  71269. +
  71270. +static int csi_buffer_num;
  71271. +static u32 bpp, csi_mem_bufsize = 3;
  71272. +static u32 out_format;
  71273. +static struct ipu_soc *disp_ipu;
  71274. +static u32 offset;
  71275. +
  71276. +static void csi_buf_work_func(struct work_struct *work)
  71277. +{
  71278. + int err = 0;
  71279. + cam_data *cam =
  71280. + container_of(work, struct _cam_data, csi_work_struct);
  71281. +
  71282. + struct ipu_task task;
  71283. + memset(&task, 0, sizeof(task));
  71284. +
  71285. + if (csi_buffer_num)
  71286. + task.input.paddr = cam->vf_bufs[0];
  71287. + else
  71288. + task.input.paddr = cam->vf_bufs[1];
  71289. + task.input.width = cam->crop_current.width;
  71290. + task.input.height = cam->crop_current.height;
  71291. + task.input.format = IPU_PIX_FMT_UYVY;
  71292. +
  71293. + task.output.paddr = offset;
  71294. + task.output.width = cam->overlay_fb->var.xres;
  71295. + task.output.height = cam->overlay_fb->var.yres;
  71296. + task.output.format = out_format;
  71297. + task.output.rotate = cam->rotation;
  71298. + task.output.crop.pos.x = cam->win.w.left;
  71299. + task.output.crop.pos.y = cam->win.w.top;
  71300. + if (cam->win.w.width > 1024 || cam->win.w.height > 1024) {
  71301. + task.output.crop.w = cam->overlay_fb->var.xres;
  71302. + task.output.crop.h = cam->overlay_fb->var.yres;
  71303. + } else {
  71304. + task.output.crop.w = cam->win.w.width;
  71305. + task.output.crop.h = cam->win.w.height;
  71306. + }
  71307. +again:
  71308. + err = ipu_check_task(&task);
  71309. + if (err != IPU_CHECK_OK) {
  71310. + if (err > IPU_CHECK_ERR_MIN) {
  71311. + if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
  71312. + task.input.crop.w -= 8;
  71313. + goto again;
  71314. + }
  71315. + if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
  71316. + task.input.crop.h -= 8;
  71317. + goto again;
  71318. + }
  71319. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  71320. + task.output.width -= 8;
  71321. + task.output.crop.w = task.output.width;
  71322. + goto again;
  71323. + }
  71324. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  71325. + task.output.height -= 8;
  71326. + task.output.crop.h = task.output.height;
  71327. + goto again;
  71328. + }
  71329. + printk(KERN_ERR "check ipu taks fail\n");
  71330. + return;
  71331. + }
  71332. + printk(KERN_ERR "check ipu taks fail\n");
  71333. + return;
  71334. + }
  71335. + err = ipu_queue_task(&task);
  71336. + if (err < 0)
  71337. + printk(KERN_ERR "queue ipu task error\n");
  71338. +}
  71339. +
  71340. +static void get_disp_ipu(cam_data *cam)
  71341. +{
  71342. + if (cam->output > 2)
  71343. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  71344. + else
  71345. + disp_ipu = ipu_get_soc(0);
  71346. +}
  71347. +
  71348. +
  71349. +/*!
  71350. + * csi ENC callback function.
  71351. + *
  71352. + * @param irq int irq line
  71353. + * @param dev_id void * device id
  71354. + *
  71355. + * @return status IRQ_HANDLED for handled
  71356. + */
  71357. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  71358. +{
  71359. + cam_data *cam = (cam_data *) dev_id;
  71360. +
  71361. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, csi_buffer_num);
  71362. + schedule_work(&cam->csi_work_struct);
  71363. + csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
  71364. + return IRQ_HANDLED;
  71365. +}
  71366. +
  71367. +static int csi_enc_setup(cam_data *cam)
  71368. +{
  71369. + ipu_channel_params_t params;
  71370. + u32 pixel_fmt;
  71371. + int err = 0, sensor_protocol = 0;
  71372. +#ifdef CONFIG_MXC_MIPI_CSI2
  71373. + void *mipi_csi2_info;
  71374. + int ipu_id;
  71375. + int csi_id;
  71376. +#endif
  71377. +
  71378. + if (!cam) {
  71379. + printk(KERN_ERR "cam private is NULL\n");
  71380. + return -ENXIO;
  71381. + }
  71382. +
  71383. + memset(&params, 0, sizeof(ipu_channel_params_t));
  71384. + params.csi_mem.csi = cam->csi;
  71385. +
  71386. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  71387. + switch (sensor_protocol) {
  71388. + case IPU_CSI_CLK_MODE_GATED_CLK:
  71389. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  71390. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  71391. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  71392. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  71393. + params.csi_mem.interlaced = false;
  71394. + break;
  71395. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  71396. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  71397. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  71398. + params.csi_mem.interlaced = true;
  71399. + break;
  71400. + default:
  71401. + printk(KERN_ERR "sensor protocol unsupported\n");
  71402. + return -EINVAL;
  71403. + }
  71404. +
  71405. +#ifdef CONFIG_MXC_MIPI_CSI2
  71406. + mipi_csi2_info = mipi_csi2_get_info();
  71407. +
  71408. + if (mipi_csi2_info) {
  71409. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71410. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71411. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71412. +
  71413. + if (cam->ipu == ipu_get_soc(ipu_id)
  71414. + && cam->csi == csi_id) {
  71415. + params.csi_mem.mipi_en = true;
  71416. + params.csi_mem.mipi_vc =
  71417. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  71418. + params.csi_mem.mipi_id =
  71419. + mipi_csi2_get_datatype(mipi_csi2_info);
  71420. +
  71421. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  71422. + } else {
  71423. + params.csi_mem.mipi_en = false;
  71424. + params.csi_mem.mipi_vc = 0;
  71425. + params.csi_mem.mipi_id = 0;
  71426. + }
  71427. + } else {
  71428. + params.csi_mem.mipi_en = false;
  71429. + params.csi_mem.mipi_vc = 0;
  71430. + params.csi_mem.mipi_id = 0;
  71431. + }
  71432. + }
  71433. +#endif
  71434. +
  71435. + if (cam->vf_bufs_vaddr[0]) {
  71436. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71437. + cam->vf_bufs_vaddr[0],
  71438. + (dma_addr_t) cam->vf_bufs[0]);
  71439. + }
  71440. + if (cam->vf_bufs_vaddr[1]) {
  71441. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71442. + cam->vf_bufs_vaddr[1],
  71443. + (dma_addr_t) cam->vf_bufs[1]);
  71444. + }
  71445. + csi_mem_bufsize =
  71446. + cam->crop_current.width * cam->crop_current.height * 2;
  71447. + cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
  71448. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  71449. + cam->vf_bufs_size[0],
  71450. + (dma_addr_t *) &
  71451. + cam->vf_bufs[0],
  71452. + GFP_DMA |
  71453. + GFP_KERNEL);
  71454. + if (cam->vf_bufs_vaddr[0] == NULL) {
  71455. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71456. + err = -ENOMEM;
  71457. + goto out_2;
  71458. + }
  71459. + cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
  71460. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  71461. + cam->vf_bufs_size[1],
  71462. + (dma_addr_t *) &
  71463. + cam->vf_bufs[1],
  71464. + GFP_DMA |
  71465. + GFP_KERNEL);
  71466. + if (cam->vf_bufs_vaddr[1] == NULL) {
  71467. + printk(KERN_ERR "Error to allocate vf buffer\n");
  71468. + err = -ENOMEM;
  71469. + goto out_1;
  71470. + }
  71471. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  71472. +
  71473. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  71474. + if (err != 0) {
  71475. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  71476. + goto out_1;
  71477. + }
  71478. +
  71479. + pixel_fmt = IPU_PIX_FMT_UYVY;
  71480. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  71481. + pixel_fmt, cam->crop_current.width,
  71482. + cam->crop_current.height,
  71483. + cam->crop_current.width, IPU_ROTATE_NONE,
  71484. + cam->vf_bufs[0], cam->vf_bufs[1], 0,
  71485. + cam->offset.u_offset, cam->offset.u_offset);
  71486. + if (err != 0) {
  71487. + printk(KERN_ERR "CSI_MEM output buffer\n");
  71488. + goto out_1;
  71489. + }
  71490. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  71491. + if (err < 0) {
  71492. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  71493. + goto out_1;
  71494. + }
  71495. +
  71496. + csi_buffer_num = 0;
  71497. +
  71498. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  71499. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 1);
  71500. + return err;
  71501. +out_1:
  71502. + if (cam->vf_bufs_vaddr[0]) {
  71503. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71504. + cam->vf_bufs_vaddr[0],
  71505. + (dma_addr_t) cam->vf_bufs[0]);
  71506. + cam->vf_bufs_vaddr[0] = NULL;
  71507. + cam->vf_bufs[0] = 0;
  71508. + }
  71509. + if (cam->vf_bufs_vaddr[1]) {
  71510. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71511. + cam->vf_bufs_vaddr[1],
  71512. + (dma_addr_t) cam->vf_bufs[1]);
  71513. + cam->vf_bufs_vaddr[1] = NULL;
  71514. + cam->vf_bufs[1] = 0;
  71515. + }
  71516. +out_2:
  71517. + return err;
  71518. +}
  71519. +
  71520. +/*!
  71521. + * Enable encoder task
  71522. + * @param private struct cam_data * mxc capture instance
  71523. + *
  71524. + * @return status
  71525. + */
  71526. +static int csi_enc_enabling_tasks(void *private)
  71527. +{
  71528. + cam_data *cam = (cam_data *) private;
  71529. + int err = 0;
  71530. +
  71531. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  71532. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  71533. + csi_enc_callback, 0, "Mxc Camera", cam);
  71534. + if (err != 0) {
  71535. + printk(KERN_ERR "Error registering CSI0_OUT_EOF irq\n");
  71536. + return err;
  71537. + }
  71538. +
  71539. + INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
  71540. +
  71541. + err = csi_enc_setup(cam);
  71542. + if (err != 0) {
  71543. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  71544. + goto out1;
  71545. + }
  71546. +
  71547. + return err;
  71548. +out1:
  71549. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  71550. + return err;
  71551. +}
  71552. +
  71553. +/*!
  71554. + * bg_overlay_start - start the overlay task
  71555. + *
  71556. + * @param private cam_data * mxc v4l2 main structure
  71557. + *
  71558. + */
  71559. +static int bg_overlay_start(void *private)
  71560. +{
  71561. + cam_data *cam = (cam_data *) private;
  71562. + int err = 0;
  71563. +
  71564. + if (!cam) {
  71565. + printk(KERN_ERR "private is NULL\n");
  71566. + return -EIO;
  71567. + }
  71568. +
  71569. + if (cam->overlay_active == true) {
  71570. + pr_debug("already start.\n");
  71571. + return 0;
  71572. + }
  71573. +
  71574. + get_disp_ipu(cam);
  71575. +
  71576. + out_format = cam->v4l2_fb.fmt.pixelformat;
  71577. + if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
  71578. + bpp = 3, csi_mem_bufsize = 3;
  71579. + pr_info("BGR24\n");
  71580. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
  71581. + bpp = 2, csi_mem_bufsize = 2;
  71582. + pr_info("RGB565\n");
  71583. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
  71584. + bpp = 4, csi_mem_bufsize = 4;
  71585. + pr_info("BGR32\n");
  71586. + } else {
  71587. + printk(KERN_ERR
  71588. + "unsupported fix format from the framebuffer.\n");
  71589. + return -EINVAL;
  71590. + }
  71591. +
  71592. + offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
  71593. + csi_mem_bufsize * cam->win.w.left;
  71594. +
  71595. + if (cam->v4l2_fb.base == 0)
  71596. + printk(KERN_ERR "invalid frame buffer address.\n");
  71597. + else
  71598. + offset += (u32) cam->v4l2_fb.base;
  71599. +
  71600. + csi_mem_bufsize = cam->win.w.width * cam->win.w.height
  71601. + * csi_mem_bufsize;
  71602. +
  71603. + err = csi_enc_enabling_tasks(cam);
  71604. + if (err != 0) {
  71605. + printk(KERN_ERR "Error csi enc enable fail\n");
  71606. + return err;
  71607. + }
  71608. +
  71609. + cam->overlay_active = true;
  71610. + return err;
  71611. +}
  71612. +
  71613. +/*!
  71614. + * bg_overlay_stop - stop the overlay task
  71615. + *
  71616. + * @param private cam_data * mxc v4l2 main structure
  71617. + *
  71618. + */
  71619. +static int bg_overlay_stop(void *private)
  71620. +{
  71621. + int err = 0;
  71622. + cam_data *cam = (cam_data *) private;
  71623. +#ifdef CONFIG_MXC_MIPI_CSI2
  71624. + void *mipi_csi2_info;
  71625. + int ipu_id;
  71626. + int csi_id;
  71627. +#endif
  71628. +
  71629. + if (cam->overlay_active == false)
  71630. + return 0;
  71631. +
  71632. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  71633. +
  71634. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  71635. +
  71636. + csi_buffer_num = 0;
  71637. +
  71638. +#ifdef CONFIG_MXC_MIPI_CSI2
  71639. + mipi_csi2_info = mipi_csi2_get_info();
  71640. +
  71641. + if (mipi_csi2_info) {
  71642. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71643. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71644. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71645. +
  71646. + if (cam->ipu == ipu_get_soc(ipu_id)
  71647. + && cam->csi == csi_id)
  71648. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  71649. + }
  71650. + }
  71651. +#endif
  71652. +
  71653. + flush_work(&cam->csi_work_struct);
  71654. + cancel_work_sync(&cam->csi_work_struct);
  71655. +
  71656. + if (cam->vf_bufs_vaddr[0]) {
  71657. + dma_free_coherent(0, cam->vf_bufs_size[0],
  71658. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  71659. + cam->vf_bufs_vaddr[0] = NULL;
  71660. + cam->vf_bufs[0] = 0;
  71661. + }
  71662. + if (cam->vf_bufs_vaddr[1]) {
  71663. + dma_free_coherent(0, cam->vf_bufs_size[1],
  71664. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  71665. + cam->vf_bufs_vaddr[1] = NULL;
  71666. + cam->vf_bufs[1] = 0;
  71667. + }
  71668. + if (cam->rot_vf_bufs_vaddr[0]) {
  71669. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  71670. + cam->rot_vf_bufs_vaddr[0],
  71671. + cam->rot_vf_bufs[0]);
  71672. + cam->rot_vf_bufs_vaddr[0] = NULL;
  71673. + cam->rot_vf_bufs[0] = 0;
  71674. + }
  71675. + if (cam->rot_vf_bufs_vaddr[1]) {
  71676. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  71677. + cam->rot_vf_bufs_vaddr[1],
  71678. + cam->rot_vf_bufs[1]);
  71679. + cam->rot_vf_bufs_vaddr[1] = NULL;
  71680. + cam->rot_vf_bufs[1] = 0;
  71681. + }
  71682. +
  71683. + cam->overlay_active = false;
  71684. + return err;
  71685. +}
  71686. +
  71687. +/*!
  71688. + * Enable csi
  71689. + * @param private struct cam_data * mxc capture instance
  71690. + *
  71691. + * @return status
  71692. + */
  71693. +static int bg_overlay_enable_csi(void *private)
  71694. +{
  71695. + cam_data *cam = (cam_data *) private;
  71696. +
  71697. + return ipu_enable_csi(cam->ipu, cam->csi);
  71698. +}
  71699. +
  71700. +/*!
  71701. + * Disable csi
  71702. + * @param private struct cam_data * mxc capture instance
  71703. + *
  71704. + * @return status
  71705. + */
  71706. +static int bg_overlay_disable_csi(void *private)
  71707. +{
  71708. + cam_data *cam = (cam_data *) private;
  71709. +
  71710. + /* free csi eof irq firstly.
  71711. + * when disable csi, wait for idmac eof.
  71712. + * it requests eof irq again */
  71713. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  71714. +
  71715. + return ipu_disable_csi(cam->ipu, cam->csi);
  71716. +}
  71717. +
  71718. +/*!
  71719. + * function to select bg as the working path
  71720. + *
  71721. + * @param private cam_data * mxc v4l2 main structure
  71722. + *
  71723. + * @return status
  71724. + */
  71725. +int bg_overlay_sdc_select(void *private)
  71726. +{
  71727. + cam_data *cam = (cam_data *) private;
  71728. +
  71729. + if (cam) {
  71730. + cam->vf_start_sdc = bg_overlay_start;
  71731. + cam->vf_stop_sdc = bg_overlay_stop;
  71732. + cam->vf_enable_csi = bg_overlay_enable_csi;
  71733. + cam->vf_disable_csi = bg_overlay_disable_csi;
  71734. + cam->overlay_active = false;
  71735. + }
  71736. +
  71737. + return 0;
  71738. +}
  71739. +EXPORT_SYMBOL(bg_overlay_sdc_select);
  71740. +
  71741. +/*!
  71742. + * function to de-select bg as the working path
  71743. + *
  71744. + * @param private cam_data * mxc v4l2 main structure
  71745. + *
  71746. + * @return status
  71747. + */
  71748. +int bg_overlay_sdc_deselect(void *private)
  71749. +{
  71750. + cam_data *cam = (cam_data *) private;
  71751. +
  71752. + if (cam) {
  71753. + cam->vf_start_sdc = NULL;
  71754. + cam->vf_stop_sdc = NULL;
  71755. + cam->vf_enable_csi = NULL;
  71756. + cam->vf_disable_csi = NULL;
  71757. + }
  71758. + return 0;
  71759. +}
  71760. +EXPORT_SYMBOL(bg_overlay_sdc_deselect);
  71761. +
  71762. +/*!
  71763. + * Init background overlay task.
  71764. + *
  71765. + * @return Error code indicating success or failure
  71766. + */
  71767. +__init int bg_overlay_sdc_init(void)
  71768. +{
  71769. + return 0;
  71770. +}
  71771. +
  71772. +/*!
  71773. + * Deinit background overlay task.
  71774. + *
  71775. + * @return Error code indicating success or failure
  71776. + */
  71777. +void __exit bg_overlay_sdc_exit(void)
  71778. +{
  71779. +}
  71780. +
  71781. +module_init(bg_overlay_sdc_init);
  71782. +module_exit(bg_overlay_sdc_exit);
  71783. +
  71784. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  71785. +MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
  71786. +MODULE_LICENSE("GPL");
  71787. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ipu_csi_enc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_csi_enc.c
  71788. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_csi_enc.c 1970-01-01 01:00:00.000000000 +0100
  71789. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_csi_enc.c 2014-09-11 18:06:02.254038983 +0200
  71790. @@ -0,0 +1,418 @@
  71791. +/*
  71792. + * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  71793. + */
  71794. +
  71795. +/*
  71796. + * The code contained herein is licensed under the GNU General Public
  71797. + * License. You may obtain a copy of the GNU General Public License
  71798. + * Version 2 or later at the following locations:
  71799. + *
  71800. + * http://www.opensource.org/licenses/gpl-license.html
  71801. + * http://www.gnu.org/copyleft/gpl.html
  71802. + */
  71803. +
  71804. +/*!
  71805. + * @file ipu_csi_enc.c
  71806. + *
  71807. + * @brief CSI Use case for video capture
  71808. + *
  71809. + * @ingroup IPU
  71810. + */
  71811. +
  71812. +#include <linux/module.h>
  71813. +#include <linux/platform_device.h>
  71814. +#include <linux/dma-mapping.h>
  71815. +#include <linux/ipu.h>
  71816. +#include <linux/mipi_csi2.h>
  71817. +#include "mxc_v4l2_capture.h"
  71818. +#include "ipu_prp_sw.h"
  71819. +
  71820. +#ifdef CAMERA_DBG
  71821. + #define CAMERA_TRACE(x) (printk)x
  71822. +#else
  71823. + #define CAMERA_TRACE(x)
  71824. +#endif
  71825. +
  71826. +/*
  71827. + * Function definitions
  71828. + */
  71829. +
  71830. +/*!
  71831. + * csi ENC callback function.
  71832. + *
  71833. + * @param irq int irq line
  71834. + * @param dev_id void * device id
  71835. + *
  71836. + * @return status IRQ_HANDLED for handled
  71837. + */
  71838. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  71839. +{
  71840. + cam_data *cam = (cam_data *) dev_id;
  71841. +
  71842. + if (cam->enc_callback == NULL)
  71843. + return IRQ_HANDLED;
  71844. +
  71845. + cam->enc_callback(irq, dev_id);
  71846. + return IRQ_HANDLED;
  71847. +}
  71848. +
  71849. +/*!
  71850. + * CSI ENC enable channel setup function
  71851. + *
  71852. + * @param cam struct cam_data * mxc capture instance
  71853. + *
  71854. + * @return status
  71855. + */
  71856. +static int csi_enc_setup(cam_data *cam)
  71857. +{
  71858. + ipu_channel_params_t params;
  71859. + u32 pixel_fmt;
  71860. + int err = 0, sensor_protocol = 0;
  71861. + dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
  71862. +#ifdef CONFIG_MXC_MIPI_CSI2
  71863. + void *mipi_csi2_info;
  71864. + int ipu_id;
  71865. + int csi_id;
  71866. +#endif
  71867. +
  71868. + CAMERA_TRACE("In csi_enc_setup\n");
  71869. + if (!cam) {
  71870. + printk(KERN_ERR "cam private is NULL\n");
  71871. + return -ENXIO;
  71872. + }
  71873. +
  71874. + memset(&params, 0, sizeof(ipu_channel_params_t));
  71875. + params.csi_mem.csi = cam->csi;
  71876. +
  71877. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  71878. + switch (sensor_protocol) {
  71879. + case IPU_CSI_CLK_MODE_GATED_CLK:
  71880. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  71881. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  71882. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  71883. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  71884. + params.csi_mem.interlaced = false;
  71885. + break;
  71886. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  71887. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  71888. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  71889. + params.csi_mem.interlaced = true;
  71890. + break;
  71891. + default:
  71892. + printk(KERN_ERR "sensor protocol unsupported\n");
  71893. + return -EINVAL;
  71894. + }
  71895. +
  71896. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
  71897. + pixel_fmt = IPU_PIX_FMT_YUV420P;
  71898. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420)
  71899. + pixel_fmt = IPU_PIX_FMT_YVU420P;
  71900. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
  71901. + pixel_fmt = IPU_PIX_FMT_YUV422P;
  71902. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  71903. + pixel_fmt = IPU_PIX_FMT_UYVY;
  71904. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
  71905. + pixel_fmt = IPU_PIX_FMT_YUYV;
  71906. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
  71907. + pixel_fmt = IPU_PIX_FMT_NV12;
  71908. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
  71909. + pixel_fmt = IPU_PIX_FMT_BGR24;
  71910. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
  71911. + pixel_fmt = IPU_PIX_FMT_RGB24;
  71912. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  71913. + pixel_fmt = IPU_PIX_FMT_RGB565;
  71914. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
  71915. + pixel_fmt = IPU_PIX_FMT_BGR32;
  71916. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
  71917. + pixel_fmt = IPU_PIX_FMT_RGB32;
  71918. + else {
  71919. + printk(KERN_ERR "format not supported\n");
  71920. + return -EINVAL;
  71921. + }
  71922. +
  71923. +#ifdef CONFIG_MXC_MIPI_CSI2
  71924. + mipi_csi2_info = mipi_csi2_get_info();
  71925. +
  71926. + if (mipi_csi2_info) {
  71927. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  71928. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  71929. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  71930. +
  71931. + if (cam->ipu == ipu_get_soc(ipu_id)
  71932. + && cam->csi == csi_id) {
  71933. + params.csi_mem.mipi_en = true;
  71934. + params.csi_mem.mipi_vc =
  71935. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  71936. + params.csi_mem.mipi_id =
  71937. + mipi_csi2_get_datatype(mipi_csi2_info);
  71938. +
  71939. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  71940. + } else {
  71941. + params.csi_mem.mipi_en = false;
  71942. + params.csi_mem.mipi_vc = 0;
  71943. + params.csi_mem.mipi_id = 0;
  71944. + }
  71945. + } else {
  71946. + params.csi_mem.mipi_en = false;
  71947. + params.csi_mem.mipi_vc = 0;
  71948. + params.csi_mem.mipi_id = 0;
  71949. + }
  71950. + }
  71951. +#endif
  71952. +
  71953. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  71954. + if (err != 0) {
  71955. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  71956. + return err;
  71957. + }
  71958. +
  71959. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  71960. + pixel_fmt, cam->v2f.fmt.pix.width,
  71961. + cam->v2f.fmt.pix.height,
  71962. + cam->v2f.fmt.pix.bytesperline,
  71963. + IPU_ROTATE_NONE,
  71964. + dummy, dummy, 0,
  71965. + cam->offset.u_offset,
  71966. + cam->offset.v_offset);
  71967. + if (err != 0) {
  71968. + printk(KERN_ERR "CSI_MEM output buffer\n");
  71969. + return err;
  71970. + }
  71971. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  71972. + if (err < 0) {
  71973. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  71974. + return err;
  71975. + }
  71976. +
  71977. + return err;
  71978. +}
  71979. +
  71980. +/*!
  71981. + * function to update physical buffer address for encorder IDMA channel
  71982. + *
  71983. + * @param eba physical buffer address for encorder IDMA channel
  71984. + * @param buffer_num int buffer 0 or buffer 1
  71985. + *
  71986. + * @return status
  71987. + */
  71988. +static int csi_enc_eba_update(struct ipu_soc *ipu, dma_addr_t eba,
  71989. + int *buffer_num)
  71990. +{
  71991. + int err = 0;
  71992. +
  71993. + pr_debug("eba %x\n", eba);
  71994. + err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  71995. + *buffer_num, eba);
  71996. + if (err != 0) {
  71997. + ipu_clear_buffer_ready(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  71998. + *buffer_num);
  71999. +
  72000. + err = ipu_update_channel_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  72001. + *buffer_num, eba);
  72002. + if (err != 0) {
  72003. + pr_err("ERROR: v4l2 capture: fail to update "
  72004. + "buf%d\n", *buffer_num);
  72005. + return err;
  72006. + }
  72007. + }
  72008. +
  72009. + ipu_select_buffer(ipu, CSI_MEM, IPU_OUTPUT_BUFFER, *buffer_num);
  72010. +
  72011. + *buffer_num = (*buffer_num == 0) ? 1 : 0;
  72012. +
  72013. + return 0;
  72014. +}
  72015. +
  72016. +/*!
  72017. + * Enable encoder task
  72018. + * @param private struct cam_data * mxc capture instance
  72019. + *
  72020. + * @return status
  72021. + */
  72022. +static int csi_enc_enabling_tasks(void *private)
  72023. +{
  72024. + cam_data *cam = (cam_data *) private;
  72025. + int err = 0;
  72026. + CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
  72027. +
  72028. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  72029. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  72030. + &cam->dummy_frame.paddress,
  72031. + GFP_DMA | GFP_KERNEL);
  72032. + if (cam->dummy_frame.vaddress == 0) {
  72033. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  72034. + "failed.\n");
  72035. + return -ENOBUFS;
  72036. + }
  72037. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  72038. + cam->dummy_frame.buffer.length =
  72039. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  72040. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  72041. +
  72042. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  72043. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  72044. + csi_enc_callback, 0, "Mxc Camera", cam);
  72045. + if (err != 0) {
  72046. + printk(KERN_ERR "Error registering rot irq\n");
  72047. + return err;
  72048. + }
  72049. +
  72050. + err = csi_enc_setup(cam);
  72051. + if (err != 0) {
  72052. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  72053. + return err;
  72054. + }
  72055. +
  72056. + return err;
  72057. +}
  72058. +
  72059. +/*!
  72060. + * Disable encoder task
  72061. + * @param private struct cam_data * mxc capture instance
  72062. + *
  72063. + * @return int
  72064. + */
  72065. +static int csi_enc_disabling_tasks(void *private)
  72066. +{
  72067. + cam_data *cam = (cam_data *) private;
  72068. + int err = 0;
  72069. +#ifdef CONFIG_MXC_MIPI_CSI2
  72070. + void *mipi_csi2_info;
  72071. + int ipu_id;
  72072. + int csi_id;
  72073. +#endif
  72074. +
  72075. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  72076. +
  72077. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  72078. +
  72079. + if (cam->dummy_frame.vaddress != 0) {
  72080. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  72081. + cam->dummy_frame.vaddress,
  72082. + cam->dummy_frame.paddress);
  72083. + cam->dummy_frame.vaddress = 0;
  72084. + }
  72085. +
  72086. +#ifdef CONFIG_MXC_MIPI_CSI2
  72087. + mipi_csi2_info = mipi_csi2_get_info();
  72088. +
  72089. + if (mipi_csi2_info) {
  72090. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  72091. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  72092. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  72093. +
  72094. + if (cam->ipu == ipu_get_soc(ipu_id)
  72095. + && cam->csi == csi_id)
  72096. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  72097. + }
  72098. + }
  72099. +#endif
  72100. +
  72101. + return err;
  72102. +}
  72103. +
  72104. +/*!
  72105. + * Enable csi
  72106. + * @param private struct cam_data * mxc capture instance
  72107. + *
  72108. + * @return status
  72109. + */
  72110. +static int csi_enc_enable_csi(void *private)
  72111. +{
  72112. + cam_data *cam = (cam_data *) private;
  72113. +
  72114. + return ipu_enable_csi(cam->ipu, cam->csi);
  72115. +}
  72116. +
  72117. +/*!
  72118. + * Disable csi
  72119. + * @param private struct cam_data * mxc capture instance
  72120. + *
  72121. + * @return status
  72122. + */
  72123. +static int csi_enc_disable_csi(void *private)
  72124. +{
  72125. + cam_data *cam = (cam_data *) private;
  72126. +
  72127. + /* free csi eof irq firstly.
  72128. + * when disable csi, wait for idmac eof.
  72129. + * it requests eof irq again */
  72130. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  72131. +
  72132. + return ipu_disable_csi(cam->ipu, cam->csi);
  72133. +}
  72134. +
  72135. +/*!
  72136. + * function to select CSI ENC as the working path
  72137. + *
  72138. + * @param private struct cam_data * mxc capture instance
  72139. + *
  72140. + * @return int
  72141. + */
  72142. +int csi_enc_select(void *private)
  72143. +{
  72144. + cam_data *cam = (cam_data *) private;
  72145. + int err = 0;
  72146. +
  72147. + if (cam) {
  72148. + cam->enc_update_eba = csi_enc_eba_update;
  72149. + cam->enc_enable = csi_enc_enabling_tasks;
  72150. + cam->enc_disable = csi_enc_disabling_tasks;
  72151. + cam->enc_enable_csi = csi_enc_enable_csi;
  72152. + cam->enc_disable_csi = csi_enc_disable_csi;
  72153. + } else {
  72154. + err = -EIO;
  72155. + }
  72156. +
  72157. + return err;
  72158. +}
  72159. +EXPORT_SYMBOL(csi_enc_select);
  72160. +
  72161. +/*!
  72162. + * function to de-select CSI ENC as the working path
  72163. + *
  72164. + * @param private struct cam_data * mxc capture instance
  72165. + *
  72166. + * @return int
  72167. + */
  72168. +int csi_enc_deselect(void *private)
  72169. +{
  72170. + cam_data *cam = (cam_data *) private;
  72171. + int err = 0;
  72172. +
  72173. + if (cam) {
  72174. + cam->enc_update_eba = NULL;
  72175. + cam->enc_enable = NULL;
  72176. + cam->enc_disable = NULL;
  72177. + cam->enc_enable_csi = NULL;
  72178. + cam->enc_disable_csi = NULL;
  72179. + }
  72180. +
  72181. + return err;
  72182. +}
  72183. +EXPORT_SYMBOL(csi_enc_deselect);
  72184. +
  72185. +/*!
  72186. + * Init the Encorder channels
  72187. + *
  72188. + * @return Error code indicating success or failure
  72189. + */
  72190. +__init int csi_enc_init(void)
  72191. +{
  72192. + return 0;
  72193. +}
  72194. +
  72195. +/*!
  72196. + * Deinit the Encorder channels
  72197. + *
  72198. + */
  72199. +void __exit csi_enc_exit(void)
  72200. +{
  72201. +}
  72202. +
  72203. +module_init(csi_enc_init);
  72204. +module_exit(csi_enc_exit);
  72205. +
  72206. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  72207. +MODULE_DESCRIPTION("CSI ENC Driver");
  72208. +MODULE_LICENSE("GPL");
  72209. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c
  72210. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c 1970-01-01 01:00:00.000000000 +0100
  72211. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_fg_overlay_sdc.c 2014-09-11 18:06:02.254038983 +0200
  72212. @@ -0,0 +1,634 @@
  72213. +/*
  72214. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  72215. + */
  72216. +/* * The code contained herein is licensed under the GNU General Public
  72217. + * License. You may obtain a copy of the GNU General Public License
  72218. + * Version 2 or later at the following locations:
  72219. + *
  72220. + * http://www.opensource.org/licenses/gpl-license.html
  72221. + * http://www.gnu.org/copyleft/gpl.html
  72222. + */
  72223. +
  72224. +/*!
  72225. + * @file ipu_foreground_sdc.c
  72226. + *
  72227. + * @brief IPU Use case for PRP-VF
  72228. + *
  72229. + * @ingroup IPU
  72230. + */
  72231. +
  72232. +#include <linux/module.h>
  72233. +#include <linux/dma-mapping.h>
  72234. +#include <linux/console.h>
  72235. +#include <linux/ipu.h>
  72236. +#include <linux/mxcfb.h>
  72237. +#include <linux/mipi_csi2.h>
  72238. +
  72239. +#include "mxc_v4l2_capture.h"
  72240. +#include "ipu_prp_sw.h"
  72241. +
  72242. +#ifdef CAMERA_DBG
  72243. + #define CAMERA_TRACE(x) (printk)x
  72244. +#else
  72245. + #define CAMERA_TRACE(x)
  72246. +#endif
  72247. +
  72248. +static int csi_buffer_num, buffer_num;
  72249. +static u32 csi_mem_bufsize;
  72250. +static struct ipu_soc *disp_ipu;
  72251. +static struct fb_info *fbi;
  72252. +static struct fb_var_screeninfo fbvar;
  72253. +static u32 vf_out_format;
  72254. +static void csi_buf_work_func(struct work_struct *work)
  72255. +{
  72256. + int err = 0;
  72257. + cam_data *cam =
  72258. + container_of(work, struct _cam_data, csi_work_struct);
  72259. +
  72260. + struct ipu_task task;
  72261. + memset(&task, 0, sizeof(task));
  72262. +
  72263. + if (csi_buffer_num)
  72264. + task.input.paddr = cam->vf_bufs[0];
  72265. + else
  72266. + task.input.paddr = cam->vf_bufs[1];
  72267. + task.input.width = cam->crop_current.width;
  72268. + task.input.height = cam->crop_current.height;
  72269. + task.input.format = IPU_PIX_FMT_NV12;
  72270. +
  72271. + if (buffer_num == 0)
  72272. + task.output.paddr = fbi->fix.smem_start +
  72273. + (fbi->fix.line_length * fbvar.yres);
  72274. + else
  72275. + task.output.paddr = fbi->fix.smem_start;
  72276. + task.output.width = cam->win.w.width;
  72277. + task.output.height = cam->win.w.height;
  72278. + task.output.format = vf_out_format;
  72279. + task.output.rotate = cam->rotation;
  72280. +again:
  72281. + err = ipu_check_task(&task);
  72282. + if (err != IPU_CHECK_OK) {
  72283. + if (err > IPU_CHECK_ERR_MIN) {
  72284. + if (err == IPU_CHECK_ERR_SPLIT_INPUTW_OVER) {
  72285. + task.input.crop.w -= 8;
  72286. + goto again;
  72287. + }
  72288. + if (err == IPU_CHECK_ERR_SPLIT_INPUTH_OVER) {
  72289. + task.input.crop.h -= 8;
  72290. + goto again;
  72291. + }
  72292. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  72293. + task.output.width -= 8;
  72294. + task.output.crop.w = task.output.width;
  72295. + goto again;
  72296. + }
  72297. + if (err == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  72298. + task.output.height -= 8;
  72299. + task.output.crop.h = task.output.height;
  72300. + goto again;
  72301. + }
  72302. + printk(KERN_ERR "check ipu taks fail\n");
  72303. + return;
  72304. + }
  72305. + printk(KERN_ERR "check ipu taks fail\n");
  72306. + return;
  72307. + }
  72308. + err = ipu_queue_task(&task);
  72309. + if (err < 0)
  72310. + printk(KERN_ERR "queue ipu task error\n");
  72311. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER, buffer_num);
  72312. + buffer_num = (buffer_num == 0) ? 1 : 0;
  72313. +}
  72314. +
  72315. +static void get_disp_ipu(cam_data *cam)
  72316. +{
  72317. + if (cam->output > 2)
  72318. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  72319. + else
  72320. + disp_ipu = ipu_get_soc(0);
  72321. +}
  72322. +
  72323. +/*!
  72324. + * csi ENC callback function.
  72325. + *
  72326. + * @param irq int irq line
  72327. + * @param dev_id void * device id
  72328. + *
  72329. + * @return status IRQ_HANDLED for handled
  72330. + */
  72331. +static irqreturn_t csi_enc_callback(int irq, void *dev_id)
  72332. +{
  72333. + cam_data *cam = (cam_data *) dev_id;
  72334. +
  72335. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, csi_buffer_num);
  72336. + if ((cam->crop_current.width != cam->win.w.width) ||
  72337. + (cam->crop_current.height != cam->win.w.height) ||
  72338. + (vf_out_format != IPU_PIX_FMT_NV12) ||
  72339. + (cam->rotation >= IPU_ROTATE_VERT_FLIP))
  72340. + schedule_work(&cam->csi_work_struct);
  72341. + csi_buffer_num = (csi_buffer_num == 0) ? 1 : 0;
  72342. + return IRQ_HANDLED;
  72343. +}
  72344. +
  72345. +static int csi_enc_setup(cam_data *cam)
  72346. +{
  72347. + ipu_channel_params_t params;
  72348. + int err = 0, sensor_protocol = 0;
  72349. +#ifdef CONFIG_MXC_MIPI_CSI2
  72350. + void *mipi_csi2_info;
  72351. + int ipu_id;
  72352. + int csi_id;
  72353. +#endif
  72354. +
  72355. + CAMERA_TRACE("In csi_enc_setup\n");
  72356. + if (!cam) {
  72357. + printk(KERN_ERR "cam private is NULL\n");
  72358. + return -ENXIO;
  72359. + }
  72360. +
  72361. + memset(&params, 0, sizeof(ipu_channel_params_t));
  72362. + params.csi_mem.csi = cam->csi;
  72363. +
  72364. + sensor_protocol = ipu_csi_get_sensor_protocol(cam->ipu, cam->csi);
  72365. + switch (sensor_protocol) {
  72366. + case IPU_CSI_CLK_MODE_GATED_CLK:
  72367. + case IPU_CSI_CLK_MODE_NONGATED_CLK:
  72368. + case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
  72369. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
  72370. + case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
  72371. + params.csi_mem.interlaced = false;
  72372. + break;
  72373. + case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
  72374. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
  72375. + case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
  72376. + params.csi_mem.interlaced = true;
  72377. + break;
  72378. + default:
  72379. + printk(KERN_ERR "sensor protocol unsupported\n");
  72380. + return -EINVAL;
  72381. + }
  72382. +
  72383. +#ifdef CONFIG_MXC_MIPI_CSI2
  72384. + mipi_csi2_info = mipi_csi2_get_info();
  72385. +
  72386. + if (mipi_csi2_info) {
  72387. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  72388. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  72389. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  72390. +
  72391. + if (cam->ipu == ipu_get_soc(ipu_id)
  72392. + && cam->csi == csi_id) {
  72393. + params.csi_mem.mipi_en = true;
  72394. + params.csi_mem.mipi_vc =
  72395. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  72396. + params.csi_mem.mipi_id =
  72397. + mipi_csi2_get_datatype(mipi_csi2_info);
  72398. +
  72399. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  72400. + } else {
  72401. + params.csi_mem.mipi_en = false;
  72402. + params.csi_mem.mipi_vc = 0;
  72403. + params.csi_mem.mipi_id = 0;
  72404. + }
  72405. + } else {
  72406. + params.csi_mem.mipi_en = false;
  72407. + params.csi_mem.mipi_vc = 0;
  72408. + params.csi_mem.mipi_id = 0;
  72409. + }
  72410. + }
  72411. +#endif
  72412. +
  72413. + if (cam->vf_bufs_vaddr[0]) {
  72414. + dma_free_coherent(0, cam->vf_bufs_size[0],
  72415. + cam->vf_bufs_vaddr[0],
  72416. + (dma_addr_t) cam->vf_bufs[0]);
  72417. + }
  72418. + if (cam->vf_bufs_vaddr[1]) {
  72419. + dma_free_coherent(0, cam->vf_bufs_size[1],
  72420. + cam->vf_bufs_vaddr[1],
  72421. + (dma_addr_t) cam->vf_bufs[1]);
  72422. + }
  72423. + csi_mem_bufsize = cam->crop_current.width *
  72424. + cam->crop_current.height * 3/2;
  72425. + cam->vf_bufs_size[0] = PAGE_ALIGN(csi_mem_bufsize);
  72426. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  72427. + cam->vf_bufs_size[0],
  72428. + (dma_addr_t *) &
  72429. + cam->vf_bufs[0],
  72430. + GFP_DMA |
  72431. + GFP_KERNEL);
  72432. + if (cam->vf_bufs_vaddr[0] == NULL) {
  72433. + printk(KERN_ERR "Error to allocate vf buffer\n");
  72434. + err = -ENOMEM;
  72435. + goto out_2;
  72436. + }
  72437. + cam->vf_bufs_size[1] = PAGE_ALIGN(csi_mem_bufsize);
  72438. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  72439. + cam->vf_bufs_size[1],
  72440. + (dma_addr_t *) &
  72441. + cam->vf_bufs[1],
  72442. + GFP_DMA |
  72443. + GFP_KERNEL);
  72444. + if (cam->vf_bufs_vaddr[1] == NULL) {
  72445. + printk(KERN_ERR "Error to allocate vf buffer\n");
  72446. + err = -ENOMEM;
  72447. + goto out_1;
  72448. + }
  72449. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  72450. +
  72451. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  72452. + if (err != 0) {
  72453. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  72454. + goto out_1;
  72455. + }
  72456. +
  72457. + if ((cam->crop_current.width == cam->win.w.width) &&
  72458. + (cam->crop_current.height == cam->win.w.height) &&
  72459. + (vf_out_format == IPU_PIX_FMT_NV12) &&
  72460. + (cam->rotation < IPU_ROTATE_VERT_FLIP)) {
  72461. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM,
  72462. + IPU_OUTPUT_BUFFER,
  72463. + IPU_PIX_FMT_NV12,
  72464. + cam->crop_current.width,
  72465. + cam->crop_current.height,
  72466. + cam->crop_current.width, IPU_ROTATE_NONE,
  72467. + fbi->fix.smem_start +
  72468. + (fbi->fix.line_length * fbvar.yres),
  72469. + fbi->fix.smem_start, 0,
  72470. + cam->offset.u_offset, cam->offset.u_offset);
  72471. + } else {
  72472. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM,
  72473. + IPU_OUTPUT_BUFFER,
  72474. + IPU_PIX_FMT_NV12,
  72475. + cam->crop_current.width,
  72476. + cam->crop_current.height,
  72477. + cam->crop_current.width, IPU_ROTATE_NONE,
  72478. + cam->vf_bufs[0], cam->vf_bufs[1], 0,
  72479. + cam->offset.u_offset, cam->offset.u_offset);
  72480. + }
  72481. + if (err != 0) {
  72482. + printk(KERN_ERR "CSI_MEM output buffer\n");
  72483. + goto out_1;
  72484. + }
  72485. + err = ipu_enable_channel(cam->ipu, CSI_MEM);
  72486. + if (err < 0) {
  72487. + printk(KERN_ERR "ipu_enable_channel CSI_MEM\n");
  72488. + goto out_1;
  72489. + }
  72490. +
  72491. + csi_buffer_num = 0;
  72492. +
  72493. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  72494. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 1);
  72495. + return err;
  72496. +out_1:
  72497. + if (cam->vf_bufs_vaddr[0]) {
  72498. + dma_free_coherent(0, cam->vf_bufs_size[0],
  72499. + cam->vf_bufs_vaddr[0],
  72500. + (dma_addr_t) cam->vf_bufs[0]);
  72501. + cam->vf_bufs_vaddr[0] = NULL;
  72502. + cam->vf_bufs[0] = 0;
  72503. + }
  72504. + if (cam->vf_bufs_vaddr[1]) {
  72505. + dma_free_coherent(0, cam->vf_bufs_size[1],
  72506. + cam->vf_bufs_vaddr[1],
  72507. + (dma_addr_t) cam->vf_bufs[1]);
  72508. + cam->vf_bufs_vaddr[1] = NULL;
  72509. + cam->vf_bufs[1] = 0;
  72510. + }
  72511. +out_2:
  72512. + return err;
  72513. +}
  72514. +
  72515. +/*!
  72516. + * Enable encoder task
  72517. + * @param private struct cam_data * mxc capture instance
  72518. + *
  72519. + * @return status
  72520. + */
  72521. +static int csi_enc_enabling_tasks(void *private)
  72522. +{
  72523. + cam_data *cam = (cam_data *) private;
  72524. + int err = 0;
  72525. + CAMERA_TRACE("IPU:In csi_enc_enabling_tasks\n");
  72526. +
  72527. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  72528. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  72529. + csi_enc_callback, 0, "Mxc Camera", cam);
  72530. + if (err != 0) {
  72531. + printk(KERN_ERR "Error registering CSI0_OUT_EOF irq\n");
  72532. + return err;
  72533. + }
  72534. +
  72535. + INIT_WORK(&cam->csi_work_struct, csi_buf_work_func);
  72536. +
  72537. + err = csi_enc_setup(cam);
  72538. + if (err != 0) {
  72539. + printk(KERN_ERR "csi_enc_setup %d\n", err);
  72540. + goto out1;
  72541. + }
  72542. +
  72543. + return err;
  72544. +out1:
  72545. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  72546. + return err;
  72547. +}
  72548. +
  72549. +/*
  72550. + * Function definitions
  72551. + */
  72552. +
  72553. +/*!
  72554. + * foreground_start - start the vf task
  72555. + *
  72556. + * @param private cam_data * mxc v4l2 main structure
  72557. + *
  72558. + */
  72559. +static int foreground_start(void *private)
  72560. +{
  72561. + cam_data *cam = (cam_data *) private;
  72562. + int err = 0, i = 0, screen_size;
  72563. + char *base;
  72564. +
  72565. + if (!cam) {
  72566. + printk(KERN_ERR "private is NULL\n");
  72567. + return -EIO;
  72568. + }
  72569. +
  72570. + if (cam->overlay_active == true) {
  72571. + pr_debug("already started.\n");
  72572. + return 0;
  72573. + }
  72574. +
  72575. + get_disp_ipu(cam);
  72576. +
  72577. + for (i = 0; i < num_registered_fb; i++) {
  72578. + char *idstr = registered_fb[i]->fix.id;
  72579. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  72580. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  72581. + fbi = registered_fb[i];
  72582. + break;
  72583. + }
  72584. + }
  72585. +
  72586. + if (fbi == NULL) {
  72587. + printk(KERN_ERR "DISP FG fb not found\n");
  72588. + return -EPERM;
  72589. + }
  72590. +
  72591. + fbvar = fbi->var;
  72592. +
  72593. + /* Store the overlay frame buffer's original std */
  72594. + cam->fb_origin_std = fbvar.nonstd;
  72595. +
  72596. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  72597. + /* Use DP to do CSC so that we can get better performance */
  72598. + vf_out_format = IPU_PIX_FMT_NV12;
  72599. + fbvar.nonstd = vf_out_format;
  72600. + } else {
  72601. + vf_out_format = IPU_PIX_FMT_RGB565;
  72602. + fbvar.nonstd = 0;
  72603. + }
  72604. +
  72605. + fbvar.bits_per_pixel = 16;
  72606. + fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
  72607. + fbvar.yres = cam->win.w.height;
  72608. + fbvar.yres_virtual = cam->win.w.height * 2;
  72609. + fbvar.yoffset = 0;
  72610. + fbvar.vmode &= ~FB_VMODE_YWRAP;
  72611. + fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
  72612. + fbvar.activate |= FB_ACTIVATE_FORCE;
  72613. + fb_set_var(fbi, &fbvar);
  72614. +
  72615. + ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
  72616. + cam->win.w.top);
  72617. +
  72618. + /* Fill black color for framebuffer */
  72619. + base = (char *) fbi->screen_base;
  72620. + screen_size = fbi->var.xres * fbi->var.yres;
  72621. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  72622. + memset(base, 0, screen_size);
  72623. + base += screen_size;
  72624. + for (i = 0; i < screen_size / 2; i++, base++)
  72625. + *base = 0x80;
  72626. + } else {
  72627. + for (i = 0; i < screen_size * 2; i++, base++)
  72628. + *base = 0x00;
  72629. + }
  72630. +
  72631. + console_lock();
  72632. + fb_blank(fbi, FB_BLANK_UNBLANK);
  72633. + console_unlock();
  72634. +
  72635. + /* correct display ch buffer address */
  72636. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  72637. + 0, fbi->fix.smem_start +
  72638. + (fbi->fix.line_length * fbvar.yres));
  72639. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  72640. + 1, fbi->fix.smem_start);
  72641. +
  72642. + err = csi_enc_enabling_tasks(cam);
  72643. + if (err != 0) {
  72644. + printk(KERN_ERR "Error csi enc enable fail\n");
  72645. + return err;
  72646. + }
  72647. +
  72648. + cam->overlay_active = true;
  72649. + return err;
  72650. +
  72651. +}
  72652. +
  72653. +/*!
  72654. + * foreground_stop - stop the vf task
  72655. + *
  72656. + * @param private cam_data * mxc v4l2 main structure
  72657. + *
  72658. + */
  72659. +static int foreground_stop(void *private)
  72660. +{
  72661. + cam_data *cam = (cam_data *) private;
  72662. + int err = 0, i = 0;
  72663. + struct fb_info *fbi = NULL;
  72664. + struct fb_var_screeninfo fbvar;
  72665. +
  72666. +#ifdef CONFIG_MXC_MIPI_CSI2
  72667. + void *mipi_csi2_info;
  72668. + int ipu_id;
  72669. + int csi_id;
  72670. +#endif
  72671. +
  72672. + if (cam->overlay_active == false)
  72673. + return 0;
  72674. +
  72675. + err = ipu_disable_channel(cam->ipu, CSI_MEM, true);
  72676. +
  72677. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  72678. +
  72679. + csi_buffer_num = 0;
  72680. + buffer_num = 0;
  72681. +
  72682. + for (i = 0; i < num_registered_fb; i++) {
  72683. + char *idstr = registered_fb[i]->fix.id;
  72684. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  72685. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  72686. + fbi = registered_fb[i];
  72687. + break;
  72688. + }
  72689. + }
  72690. +
  72691. + if (fbi == NULL) {
  72692. + printk(KERN_ERR "DISP FG fb not found\n");
  72693. + return -EPERM;
  72694. + }
  72695. +
  72696. + console_lock();
  72697. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  72698. + console_unlock();
  72699. +
  72700. + /* Set the overlay frame buffer std to what it is used to be */
  72701. + fbvar = fbi->var;
  72702. + fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
  72703. + fbvar.nonstd = cam->fb_origin_std;
  72704. + fbvar.activate |= FB_ACTIVATE_FORCE;
  72705. + fb_set_var(fbi, &fbvar);
  72706. +
  72707. +#ifdef CONFIG_MXC_MIPI_CSI2
  72708. + mipi_csi2_info = mipi_csi2_get_info();
  72709. +
  72710. + if (mipi_csi2_info) {
  72711. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  72712. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  72713. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  72714. +
  72715. + if (cam->ipu == ipu_get_soc(ipu_id)
  72716. + && cam->csi == csi_id)
  72717. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  72718. + }
  72719. + }
  72720. +#endif
  72721. +
  72722. + flush_work(&cam->csi_work_struct);
  72723. + cancel_work_sync(&cam->csi_work_struct);
  72724. +
  72725. + if (cam->vf_bufs_vaddr[0]) {
  72726. + dma_free_coherent(0, cam->vf_bufs_size[0],
  72727. + cam->vf_bufs_vaddr[0],
  72728. + (dma_addr_t) cam->vf_bufs[0]);
  72729. + cam->vf_bufs_vaddr[0] = NULL;
  72730. + cam->vf_bufs[0] = 0;
  72731. + }
  72732. + if (cam->vf_bufs_vaddr[1]) {
  72733. + dma_free_coherent(0, cam->vf_bufs_size[1],
  72734. + cam->vf_bufs_vaddr[1],
  72735. + (dma_addr_t) cam->vf_bufs[1]);
  72736. + cam->vf_bufs_vaddr[1] = NULL;
  72737. + cam->vf_bufs[1] = 0;
  72738. + }
  72739. +
  72740. + cam->overlay_active = false;
  72741. + return err;
  72742. +}
  72743. +
  72744. +/*!
  72745. + * Enable csi
  72746. + * @param private struct cam_data * mxc capture instance
  72747. + *
  72748. + * @return status
  72749. + */
  72750. +static int foreground_enable_csi(void *private)
  72751. +{
  72752. + cam_data *cam = (cam_data *) private;
  72753. +
  72754. + return ipu_enable_csi(cam->ipu, cam->csi);
  72755. +}
  72756. +
  72757. +/*!
  72758. + * Disable csi
  72759. + * @param private struct cam_data * mxc capture instance
  72760. + *
  72761. + * @return status
  72762. + */
  72763. +static int foreground_disable_csi(void *private)
  72764. +{
  72765. + cam_data *cam = (cam_data *) private;
  72766. +
  72767. + /* free csi eof irq firstly.
  72768. + * when disable csi, wait for idmac eof.
  72769. + * it requests eof irq again */
  72770. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  72771. +
  72772. + return ipu_disable_csi(cam->ipu, cam->csi);
  72773. +}
  72774. +
  72775. +/*!
  72776. + * function to select foreground as the working path
  72777. + *
  72778. + * @param private cam_data * mxc v4l2 main structure
  72779. + *
  72780. + * @return status
  72781. + */
  72782. +int foreground_sdc_select(void *private)
  72783. +{
  72784. + cam_data *cam;
  72785. + int err = 0;
  72786. + if (private) {
  72787. + cam = (cam_data *) private;
  72788. + cam->vf_start_sdc = foreground_start;
  72789. + cam->vf_stop_sdc = foreground_stop;
  72790. + cam->vf_enable_csi = foreground_enable_csi;
  72791. + cam->vf_disable_csi = foreground_disable_csi;
  72792. + cam->overlay_active = false;
  72793. + } else
  72794. + err = -EIO;
  72795. +
  72796. + return err;
  72797. +}
  72798. +EXPORT_SYMBOL(foreground_sdc_select);
  72799. +
  72800. +/*!
  72801. + * function to de-select foreground as the working path
  72802. + *
  72803. + * @param private cam_data * mxc v4l2 main structure
  72804. + *
  72805. + * @return int
  72806. + */
  72807. +int foreground_sdc_deselect(void *private)
  72808. +{
  72809. + cam_data *cam;
  72810. +
  72811. + if (private) {
  72812. + cam = (cam_data *) private;
  72813. + cam->vf_start_sdc = NULL;
  72814. + cam->vf_stop_sdc = NULL;
  72815. + cam->vf_enable_csi = NULL;
  72816. + cam->vf_disable_csi = NULL;
  72817. + }
  72818. + return 0;
  72819. +}
  72820. +EXPORT_SYMBOL(foreground_sdc_deselect);
  72821. +
  72822. +/*!
  72823. + * Init viewfinder task.
  72824. + *
  72825. + * @return Error code indicating success or failure
  72826. + */
  72827. +__init int foreground_sdc_init(void)
  72828. +{
  72829. + return 0;
  72830. +}
  72831. +
  72832. +/*!
  72833. + * Deinit viewfinder task.
  72834. + *
  72835. + * @return Error code indicating success or failure
  72836. + */
  72837. +void __exit foreground_sdc_exit(void)
  72838. +{
  72839. +}
  72840. +
  72841. +module_init(foreground_sdc_init);
  72842. +module_exit(foreground_sdc_exit);
  72843. +
  72844. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  72845. +MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
  72846. +MODULE_LICENSE("GPL");
  72847. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ipu_prp_enc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_enc.c
  72848. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_prp_enc.c 1970-01-01 01:00:00.000000000 +0100
  72849. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_enc.c 2014-09-11 18:06:02.254038983 +0200
  72850. @@ -0,0 +1,595 @@
  72851. +/*
  72852. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  72853. + */
  72854. +
  72855. +/*
  72856. + * The code contained herein is licensed under the GNU General Public
  72857. + * License. You may obtain a copy of the GNU General Public License
  72858. + * Version 2 or later at the following locations:
  72859. + *
  72860. + * http://www.opensource.org/licenses/gpl-license.html
  72861. + * http://www.gnu.org/copyleft/gpl.html
  72862. + */
  72863. +
  72864. +/*!
  72865. + * @file ipu_prp_enc.c
  72866. + *
  72867. + * @brief IPU Use case for PRP-ENC
  72868. + *
  72869. + * @ingroup IPU
  72870. + */
  72871. +
  72872. +#include <linux/module.h>
  72873. +#include <linux/dma-mapping.h>
  72874. +#include <linux/platform_device.h>
  72875. +#include <linux/ipu.h>
  72876. +#include <linux/mipi_csi2.h>
  72877. +#include "mxc_v4l2_capture.h"
  72878. +#include "ipu_prp_sw.h"
  72879. +
  72880. +#ifdef CAMERA_DBG
  72881. + #define CAMERA_TRACE(x) (printk)x
  72882. +#else
  72883. + #define CAMERA_TRACE(x)
  72884. +#endif
  72885. +
  72886. +static ipu_rotate_mode_t grotation = IPU_ROTATE_NONE;
  72887. +
  72888. +/*
  72889. + * Function definitions
  72890. + */
  72891. +
  72892. +/*!
  72893. + * IPU ENC callback function.
  72894. + *
  72895. + * @param irq int irq line
  72896. + * @param dev_id void * device id
  72897. + *
  72898. + * @return status IRQ_HANDLED for handled
  72899. + */
  72900. +static irqreturn_t prp_enc_callback(int irq, void *dev_id)
  72901. +{
  72902. + cam_data *cam = (cam_data *) dev_id;
  72903. +
  72904. + if (cam->enc_callback == NULL)
  72905. + return IRQ_HANDLED;
  72906. +
  72907. + cam->enc_callback(irq, dev_id);
  72908. +
  72909. + return IRQ_HANDLED;
  72910. +}
  72911. +
  72912. +/*!
  72913. + * PrpENC enable channel setup function
  72914. + *
  72915. + * @param cam struct cam_data * mxc capture instance
  72916. + *
  72917. + * @return status
  72918. + */
  72919. +static int prp_enc_setup(cam_data *cam)
  72920. +{
  72921. + ipu_channel_params_t enc;
  72922. + int err = 0;
  72923. + dma_addr_t dummy = cam->dummy_frame.buffer.m.offset;
  72924. +#ifdef CONFIG_MXC_MIPI_CSI2
  72925. + void *mipi_csi2_info;
  72926. + int ipu_id;
  72927. + int csi_id;
  72928. +#endif
  72929. +
  72930. + CAMERA_TRACE("In prp_enc_setup\n");
  72931. + if (!cam) {
  72932. + printk(KERN_ERR "cam private is NULL\n");
  72933. + return -ENXIO;
  72934. + }
  72935. + memset(&enc, 0, sizeof(ipu_channel_params_t));
  72936. +
  72937. + ipu_csi_get_window_size(cam->ipu, &enc.csi_prp_enc_mem.in_width,
  72938. + &enc.csi_prp_enc_mem.in_height, cam->csi);
  72939. +
  72940. + enc.csi_prp_enc_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  72941. + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.width;
  72942. + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.height;
  72943. + enc.csi_prp_enc_mem.csi = cam->csi;
  72944. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  72945. + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.height;
  72946. + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.width;
  72947. + }
  72948. +
  72949. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
  72950. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV420P;
  72951. + pr_info("YUV420\n");
  72952. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) {
  72953. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YVU420P;
  72954. + pr_info("YVU420\n");
  72955. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) {
  72956. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV422P;
  72957. + pr_info("YUV422P\n");
  72958. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
  72959. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUYV;
  72960. + pr_info("YUYV\n");
  72961. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) {
  72962. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_UYVY;
  72963. + pr_info("UYVY\n");
  72964. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) {
  72965. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_NV12;
  72966. + pr_info("NV12\n");
  72967. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) {
  72968. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR24;
  72969. + pr_info("BGR24\n");
  72970. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
  72971. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB24;
  72972. + pr_info("RGB24\n");
  72973. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
  72974. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB565;
  72975. + pr_info("RGB565\n");
  72976. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) {
  72977. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR32;
  72978. + pr_info("BGR32\n");
  72979. + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) {
  72980. + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB32;
  72981. + pr_info("RGB32\n");
  72982. + } else {
  72983. + printk(KERN_ERR "format not supported\n");
  72984. + return -EINVAL;
  72985. + }
  72986. +
  72987. +#ifdef CONFIG_MXC_MIPI_CSI2
  72988. + mipi_csi2_info = mipi_csi2_get_info();
  72989. +
  72990. + if (mipi_csi2_info) {
  72991. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  72992. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  72993. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  72994. +
  72995. + if (cam->ipu == ipu_get_soc(ipu_id)
  72996. + && cam->csi == csi_id) {
  72997. + enc.csi_prp_enc_mem.mipi_en = true;
  72998. + enc.csi_prp_enc_mem.mipi_vc =
  72999. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  73000. + enc.csi_prp_enc_mem.mipi_id =
  73001. + mipi_csi2_get_datatype(mipi_csi2_info);
  73002. +
  73003. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  73004. + } else {
  73005. + enc.csi_prp_enc_mem.mipi_en = false;
  73006. + enc.csi_prp_enc_mem.mipi_vc = 0;
  73007. + enc.csi_prp_enc_mem.mipi_id = 0;
  73008. + }
  73009. + } else {
  73010. + enc.csi_prp_enc_mem.mipi_en = false;
  73011. + enc.csi_prp_enc_mem.mipi_vc = 0;
  73012. + enc.csi_prp_enc_mem.mipi_id = 0;
  73013. + }
  73014. + }
  73015. +#endif
  73016. +
  73017. + err = ipu_init_channel(cam->ipu, CSI_PRP_ENC_MEM, &enc);
  73018. + if (err != 0) {
  73019. + printk(KERN_ERR "ipu_init_channel %d\n", err);
  73020. + return err;
  73021. + }
  73022. +
  73023. + grotation = cam->rotation;
  73024. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  73025. + if (cam->rot_enc_bufs_vaddr[0]) {
  73026. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  73027. + cam->rot_enc_bufs_vaddr[0],
  73028. + cam->rot_enc_bufs[0]);
  73029. + }
  73030. + if (cam->rot_enc_bufs_vaddr[1]) {
  73031. + dma_free_coherent(0, cam->rot_enc_buf_size[1],
  73032. + cam->rot_enc_bufs_vaddr[1],
  73033. + cam->rot_enc_bufs[1]);
  73034. + }
  73035. + cam->rot_enc_buf_size[0] =
  73036. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  73037. + cam->rot_enc_bufs_vaddr[0] =
  73038. + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[0],
  73039. + &cam->rot_enc_bufs[0],
  73040. + GFP_DMA | GFP_KERNEL);
  73041. + if (!cam->rot_enc_bufs_vaddr[0]) {
  73042. + printk(KERN_ERR "alloc enc_bufs0\n");
  73043. + return -ENOMEM;
  73044. + }
  73045. + cam->rot_enc_buf_size[1] =
  73046. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  73047. + cam->rot_enc_bufs_vaddr[1] =
  73048. + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[1],
  73049. + &cam->rot_enc_bufs[1],
  73050. + GFP_DMA | GFP_KERNEL);
  73051. + if (!cam->rot_enc_bufs_vaddr[1]) {
  73052. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  73053. + cam->rot_enc_bufs_vaddr[0],
  73054. + cam->rot_enc_bufs[0]);
  73055. + cam->rot_enc_bufs_vaddr[0] = NULL;
  73056. + cam->rot_enc_bufs[0] = 0;
  73057. + printk(KERN_ERR "alloc enc_bufs1\n");
  73058. + return -ENOMEM;
  73059. + }
  73060. +
  73061. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  73062. + IPU_OUTPUT_BUFFER,
  73063. + enc.csi_prp_enc_mem.out_pixel_fmt,
  73064. + enc.csi_prp_enc_mem.out_width,
  73065. + enc.csi_prp_enc_mem.out_height,
  73066. + enc.csi_prp_enc_mem.out_width,
  73067. + IPU_ROTATE_NONE,
  73068. + cam->rot_enc_bufs[0],
  73069. + cam->rot_enc_bufs[1], 0, 0, 0);
  73070. + if (err != 0) {
  73071. + printk(KERN_ERR "CSI_PRP_ENC_MEM err\n");
  73072. + return err;
  73073. + }
  73074. +
  73075. + err = ipu_init_channel(cam->ipu, MEM_ROT_ENC_MEM, NULL);
  73076. + if (err != 0) {
  73077. + printk(KERN_ERR "MEM_ROT_ENC_MEM channel err\n");
  73078. + return err;
  73079. + }
  73080. +
  73081. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
  73082. + IPU_INPUT_BUFFER,
  73083. + enc.csi_prp_enc_mem.out_pixel_fmt,
  73084. + enc.csi_prp_enc_mem.out_width,
  73085. + enc.csi_prp_enc_mem.out_height,
  73086. + enc.csi_prp_enc_mem.out_width,
  73087. + cam->rotation,
  73088. + cam->rot_enc_bufs[0],
  73089. + cam->rot_enc_bufs[1], 0, 0, 0);
  73090. + if (err != 0) {
  73091. + printk(KERN_ERR "MEM_ROT_ENC_MEM input buffer\n");
  73092. + return err;
  73093. + }
  73094. +
  73095. + err =
  73096. + ipu_init_channel_buffer(cam->ipu, MEM_ROT_ENC_MEM,
  73097. + IPU_OUTPUT_BUFFER,
  73098. + enc.csi_prp_enc_mem.out_pixel_fmt,
  73099. + enc.csi_prp_enc_mem.out_height,
  73100. + enc.csi_prp_enc_mem.out_width,
  73101. + cam->v2f.fmt.pix.bytesperline /
  73102. + bytes_per_pixel(enc.csi_prp_enc_mem.
  73103. + out_pixel_fmt),
  73104. + IPU_ROTATE_NONE,
  73105. + dummy, dummy, 0,
  73106. + cam->offset.u_offset,
  73107. + cam->offset.v_offset);
  73108. + if (err != 0) {
  73109. + printk(KERN_ERR "MEM_ROT_ENC_MEM output buffer\n");
  73110. + return err;
  73111. + }
  73112. +
  73113. + err = ipu_link_channels(cam->ipu,
  73114. + CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
  73115. + if (err < 0) {
  73116. + printk(KERN_ERR
  73117. + "link CSI_PRP_ENC_MEM-MEM_ROT_ENC_MEM\n");
  73118. + return err;
  73119. + }
  73120. +
  73121. + err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
  73122. + if (err < 0) {
  73123. + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
  73124. + return err;
  73125. + }
  73126. + err = ipu_enable_channel(cam->ipu, MEM_ROT_ENC_MEM);
  73127. + if (err < 0) {
  73128. + printk(KERN_ERR "ipu_enable_channel MEM_ROT_ENC_MEM\n");
  73129. + return err;
  73130. + }
  73131. +
  73132. + ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  73133. + IPU_OUTPUT_BUFFER, 0);
  73134. + ipu_select_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  73135. + IPU_OUTPUT_BUFFER, 1);
  73136. + } else {
  73137. + err =
  73138. + ipu_init_channel_buffer(cam->ipu, CSI_PRP_ENC_MEM,
  73139. + IPU_OUTPUT_BUFFER,
  73140. + enc.csi_prp_enc_mem.out_pixel_fmt,
  73141. + enc.csi_prp_enc_mem.out_width,
  73142. + enc.csi_prp_enc_mem.out_height,
  73143. + cam->v2f.fmt.pix.bytesperline /
  73144. + bytes_per_pixel(enc.csi_prp_enc_mem.
  73145. + out_pixel_fmt),
  73146. + cam->rotation,
  73147. + dummy, dummy, 0,
  73148. + cam->offset.u_offset,
  73149. + cam->offset.v_offset);
  73150. + if (err != 0) {
  73151. + printk(KERN_ERR "CSI_PRP_ENC_MEM output buffer\n");
  73152. + return err;
  73153. + }
  73154. + err = ipu_enable_channel(cam->ipu, CSI_PRP_ENC_MEM);
  73155. + if (err < 0) {
  73156. + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n");
  73157. + return err;
  73158. + }
  73159. + }
  73160. +
  73161. + return err;
  73162. +}
  73163. +
  73164. +/*!
  73165. + * function to update physical buffer address for encorder IDMA channel
  73166. + *
  73167. + * @param eba physical buffer address for encorder IDMA channel
  73168. + * @param buffer_num int buffer 0 or buffer 1
  73169. + *
  73170. + * @return status
  73171. + */
  73172. +static int prp_enc_eba_update(struct ipu_soc *ipu, dma_addr_t eba,
  73173. + int *buffer_num)
  73174. +{
  73175. + int err = 0;
  73176. +
  73177. + pr_debug("eba %x\n", eba);
  73178. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  73179. + err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
  73180. + IPU_OUTPUT_BUFFER, *buffer_num,
  73181. + eba);
  73182. + } else {
  73183. + err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
  73184. + IPU_OUTPUT_BUFFER, *buffer_num,
  73185. + eba);
  73186. + }
  73187. + if (err != 0) {
  73188. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  73189. + ipu_clear_buffer_ready(ipu, MEM_ROT_ENC_MEM,
  73190. + IPU_OUTPUT_BUFFER,
  73191. + *buffer_num);
  73192. + err = ipu_update_channel_buffer(ipu, MEM_ROT_ENC_MEM,
  73193. + IPU_OUTPUT_BUFFER,
  73194. + *buffer_num,
  73195. + eba);
  73196. + } else {
  73197. + ipu_clear_buffer_ready(ipu, CSI_PRP_ENC_MEM,
  73198. + IPU_OUTPUT_BUFFER,
  73199. + *buffer_num);
  73200. + err = ipu_update_channel_buffer(ipu, CSI_PRP_ENC_MEM,
  73201. + IPU_OUTPUT_BUFFER,
  73202. + *buffer_num,
  73203. + eba);
  73204. + }
  73205. +
  73206. + if (err != 0) {
  73207. + pr_err("ERROR: v4l2 capture: fail to update "
  73208. + "buf%d\n", *buffer_num);
  73209. + return err;
  73210. + }
  73211. + }
  73212. +
  73213. + if (grotation >= IPU_ROTATE_90_RIGHT) {
  73214. + ipu_select_buffer(ipu, MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER,
  73215. + *buffer_num);
  73216. + } else {
  73217. + ipu_select_buffer(ipu, CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER,
  73218. + *buffer_num);
  73219. + }
  73220. +
  73221. + *buffer_num = (*buffer_num == 0) ? 1 : 0;
  73222. + return 0;
  73223. +}
  73224. +
  73225. +/*!
  73226. + * Enable encoder task
  73227. + * @param private struct cam_data * mxc capture instance
  73228. + *
  73229. + * @return status
  73230. + */
  73231. +static int prp_enc_enabling_tasks(void *private)
  73232. +{
  73233. + cam_data *cam = (cam_data *) private;
  73234. + int err = 0;
  73235. + CAMERA_TRACE("IPU:In prp_enc_enabling_tasks\n");
  73236. +
  73237. + cam->dummy_frame.vaddress = dma_alloc_coherent(0,
  73238. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  73239. + &cam->dummy_frame.paddress,
  73240. + GFP_DMA | GFP_KERNEL);
  73241. + if (cam->dummy_frame.vaddress == 0) {
  73242. + pr_err("ERROR: v4l2 capture: Allocate dummy frame "
  73243. + "failed.\n");
  73244. + return -ENOBUFS;
  73245. + }
  73246. + cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE;
  73247. + cam->dummy_frame.buffer.length =
  73248. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  73249. + cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress;
  73250. +
  73251. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  73252. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF,
  73253. + prp_enc_callback, 0, "Mxc Camera", cam);
  73254. + } else {
  73255. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF,
  73256. + prp_enc_callback, 0, "Mxc Camera", cam);
  73257. + }
  73258. + if (err != 0) {
  73259. + printk(KERN_ERR "Error registering rot irq\n");
  73260. + return err;
  73261. + }
  73262. +
  73263. + err = prp_enc_setup(cam);
  73264. + if (err != 0) {
  73265. + printk(KERN_ERR "prp_enc_setup %d\n", err);
  73266. + return err;
  73267. + }
  73268. +
  73269. + return err;
  73270. +}
  73271. +
  73272. +/*!
  73273. + * Disable encoder task
  73274. + * @param private struct cam_data * mxc capture instance
  73275. + *
  73276. + * @return int
  73277. + */
  73278. +static int prp_enc_disabling_tasks(void *private)
  73279. +{
  73280. + cam_data *cam = (cam_data *) private;
  73281. + int err = 0;
  73282. +#ifdef CONFIG_MXC_MIPI_CSI2
  73283. + void *mipi_csi2_info;
  73284. + int ipu_id;
  73285. + int csi_id;
  73286. +#endif
  73287. +
  73288. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  73289. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF, cam);
  73290. + ipu_unlink_channels(cam->ipu, CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM);
  73291. + }
  73292. +
  73293. + err = ipu_disable_channel(cam->ipu, CSI_PRP_ENC_MEM, true);
  73294. + if (cam->rotation >= IPU_ROTATE_90_RIGHT)
  73295. + err |= ipu_disable_channel(cam->ipu, MEM_ROT_ENC_MEM, true);
  73296. +
  73297. + ipu_uninit_channel(cam->ipu, CSI_PRP_ENC_MEM);
  73298. + if (cam->rotation >= IPU_ROTATE_90_RIGHT)
  73299. + ipu_uninit_channel(cam->ipu, MEM_ROT_ENC_MEM);
  73300. +
  73301. + if (cam->dummy_frame.vaddress != 0) {
  73302. + dma_free_coherent(0, cam->dummy_frame.buffer.length,
  73303. + cam->dummy_frame.vaddress,
  73304. + cam->dummy_frame.paddress);
  73305. + cam->dummy_frame.vaddress = 0;
  73306. + }
  73307. +
  73308. +#ifdef CONFIG_MXC_MIPI_CSI2
  73309. + mipi_csi2_info = mipi_csi2_get_info();
  73310. +
  73311. + if (mipi_csi2_info) {
  73312. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  73313. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  73314. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  73315. +
  73316. + if (cam->ipu == ipu_get_soc(ipu_id)
  73317. + && cam->csi == csi_id)
  73318. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  73319. + }
  73320. + }
  73321. +#endif
  73322. +
  73323. + return err;
  73324. +}
  73325. +
  73326. +/*!
  73327. + * Enable csi
  73328. + * @param private struct cam_data * mxc capture instance
  73329. + *
  73330. + * @return status
  73331. + */
  73332. +static int prp_enc_enable_csi(void *private)
  73333. +{
  73334. + cam_data *cam = (cam_data *) private;
  73335. +
  73336. + return ipu_enable_csi(cam->ipu, cam->csi);
  73337. +}
  73338. +
  73339. +/*!
  73340. + * Disable csi
  73341. + * @param private struct cam_data * mxc capture instance
  73342. + *
  73343. + * @return status
  73344. + */
  73345. +static int prp_enc_disable_csi(void *private)
  73346. +{
  73347. + cam_data *cam = (cam_data *) private;
  73348. +
  73349. + /* free csi eof irq firstly.
  73350. + * when disable csi, wait for idmac eof.
  73351. + * it requests eof irq again */
  73352. + if (cam->rotation < IPU_ROTATE_90_RIGHT)
  73353. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_OUT_EOF, cam);
  73354. +
  73355. + return ipu_disable_csi(cam->ipu, cam->csi);
  73356. +}
  73357. +
  73358. +/*!
  73359. + * function to select PRP-ENC as the working path
  73360. + *
  73361. + * @param private struct cam_data * mxc capture instance
  73362. + *
  73363. + * @return int
  73364. + */
  73365. +int prp_enc_select(void *private)
  73366. +{
  73367. + cam_data *cam = (cam_data *) private;
  73368. + int err = 0;
  73369. +
  73370. + if (cam) {
  73371. + cam->enc_update_eba = prp_enc_eba_update;
  73372. + cam->enc_enable = prp_enc_enabling_tasks;
  73373. + cam->enc_disable = prp_enc_disabling_tasks;
  73374. + cam->enc_enable_csi = prp_enc_enable_csi;
  73375. + cam->enc_disable_csi = prp_enc_disable_csi;
  73376. + } else {
  73377. + err = -EIO;
  73378. + }
  73379. +
  73380. + return err;
  73381. +}
  73382. +EXPORT_SYMBOL(prp_enc_select);
  73383. +
  73384. +/*!
  73385. + * function to de-select PRP-ENC as the working path
  73386. + *
  73387. + * @param private struct cam_data * mxc capture instance
  73388. + *
  73389. + * @return int
  73390. + */
  73391. +int prp_enc_deselect(void *private)
  73392. +{
  73393. + cam_data *cam = (cam_data *) private;
  73394. + int err = 0;
  73395. +
  73396. + if (cam) {
  73397. + cam->enc_update_eba = NULL;
  73398. + cam->enc_enable = NULL;
  73399. + cam->enc_disable = NULL;
  73400. + cam->enc_enable_csi = NULL;
  73401. + cam->enc_disable_csi = NULL;
  73402. + if (cam->rot_enc_bufs_vaddr[0]) {
  73403. + dma_free_coherent(0, cam->rot_enc_buf_size[0],
  73404. + cam->rot_enc_bufs_vaddr[0],
  73405. + cam->rot_enc_bufs[0]);
  73406. + cam->rot_enc_bufs_vaddr[0] = NULL;
  73407. + cam->rot_enc_bufs[0] = 0;
  73408. + }
  73409. + if (cam->rot_enc_bufs_vaddr[1]) {
  73410. + dma_free_coherent(0, cam->rot_enc_buf_size[1],
  73411. + cam->rot_enc_bufs_vaddr[1],
  73412. + cam->rot_enc_bufs[1]);
  73413. + cam->rot_enc_bufs_vaddr[1] = NULL;
  73414. + cam->rot_enc_bufs[1] = 0;
  73415. + }
  73416. + }
  73417. +
  73418. + return err;
  73419. +}
  73420. +EXPORT_SYMBOL(prp_enc_deselect);
  73421. +
  73422. +/*!
  73423. + * Init the Encorder channels
  73424. + *
  73425. + * @return Error code indicating success or failure
  73426. + */
  73427. +__init int prp_enc_init(void)
  73428. +{
  73429. + return 0;
  73430. +}
  73431. +
  73432. +/*!
  73433. + * Deinit the Encorder channels
  73434. + *
  73435. + */
  73436. +void __exit prp_enc_exit(void)
  73437. +{
  73438. +}
  73439. +
  73440. +module_init(prp_enc_init);
  73441. +module_exit(prp_enc_exit);
  73442. +
  73443. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  73444. +MODULE_DESCRIPTION("IPU PRP ENC Driver");
  73445. +MODULE_LICENSE("GPL");
  73446. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ipu_prp_sw.h linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_sw.h
  73447. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_prp_sw.h 1970-01-01 01:00:00.000000000 +0100
  73448. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_sw.h 2014-09-11 18:06:02.254038983 +0200
  73449. @@ -0,0 +1,43 @@
  73450. +/*
  73451. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  73452. + */
  73453. +
  73454. +/*
  73455. + * The code contained herein is licensed under the GNU General Public
  73456. + * License. You may obtain a copy of the GNU General Public License
  73457. + * Version 2 or later at the following locations:
  73458. + *
  73459. + * http://www.opensource.org/licenses/gpl-license.html
  73460. + * http://www.gnu.org/copyleft/gpl.html
  73461. + */
  73462. +
  73463. +/*!
  73464. + * @file ipu_prp_sw.h
  73465. + *
  73466. + * @brief This file contains the IPU PRP use case driver header.
  73467. + *
  73468. + * @ingroup IPU
  73469. + */
  73470. +
  73471. +#ifndef _INCLUDE_IPU__PRP_SW_H_
  73472. +#define _INCLUDE_IPU__PRP_SW_H_
  73473. +
  73474. +int csi_enc_select(void *private);
  73475. +int csi_enc_deselect(void *private);
  73476. +int prp_enc_select(void *private);
  73477. +int prp_enc_deselect(void *private);
  73478. +#ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  73479. +int prp_vf_sdc_select(void *private);
  73480. +int prp_vf_sdc_deselect(void *private);
  73481. +int prp_vf_sdc_select_bg(void *private);
  73482. +int prp_vf_sdc_deselect_bg(void *private);
  73483. +#else
  73484. +int foreground_sdc_select(void *private);
  73485. +int foreground_sdc_deselect(void *private);
  73486. +int bg_overlay_sdc_select(void *private);
  73487. +int bg_overlay_sdc_deselect(void *private);
  73488. +#endif
  73489. +int prp_still_select(void *private);
  73490. +int prp_still_deselect(void *private);
  73491. +
  73492. +#endif
  73493. diff -Nur linux-3.14.17/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
  73494. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c 1970-01-01 01:00:00.000000000 +0100
  73495. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc_bg.c 2014-09-11 18:06:02.254038983 +0200
  73496. @@ -0,0 +1,521 @@
  73497. +/*
  73498. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  73499. + */
  73500. +
  73501. +/*
  73502. + * The code contained herein is licensed under the GNU General Public
  73503. + * License. You may obtain a copy of the GNU General Public License
  73504. + * Version 2 or later at the following locations:
  73505. + *
  73506. + * http://www.opensource.org/licenses/gpl-license.html
  73507. + * http://www.gnu.org/copyleft/gpl.html
  73508. + */
  73509. +
  73510. +/*!
  73511. + * @file ipu_prp_vf_sdc_bg.c
  73512. + *
  73513. + * @brief IPU Use case for PRP-VF back-ground
  73514. + *
  73515. + * @ingroup IPU
  73516. + */
  73517. +#include <linux/dma-mapping.h>
  73518. +#include <linux/fb.h>
  73519. +#include <linux/ipu.h>
  73520. +#include <linux/module.h>
  73521. +#include <mach/mipi_csi2.h>
  73522. +#include "mxc_v4l2_capture.h"
  73523. +#include "ipu_prp_sw.h"
  73524. +
  73525. +static int buffer_num;
  73526. +static int buffer_ready;
  73527. +static struct ipu_soc *disp_ipu;
  73528. +
  73529. +static void get_disp_ipu(cam_data *cam)
  73530. +{
  73531. + if (cam->output > 2)
  73532. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  73533. + else
  73534. + disp_ipu = ipu_get_soc(0);
  73535. +}
  73536. +
  73537. +/*
  73538. + * Function definitions
  73539. + */
  73540. +
  73541. +/*!
  73542. + * SDC V-Sync callback function.
  73543. + *
  73544. + * @param irq int irq line
  73545. + * @param dev_id void * device id
  73546. + *
  73547. + * @return status IRQ_HANDLED for handled
  73548. + */
  73549. +static irqreturn_t prpvf_sdc_vsync_callback(int irq, void *dev_id)
  73550. +{
  73551. + cam_data *cam = dev_id;
  73552. + if (buffer_ready > 0) {
  73553. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  73554. + IPU_OUTPUT_BUFFER, 0);
  73555. + buffer_ready--;
  73556. + }
  73557. +
  73558. + return IRQ_HANDLED;
  73559. +}
  73560. +
  73561. +/*!
  73562. + * VF EOF callback function.
  73563. + *
  73564. + * @param irq int irq line
  73565. + * @param dev_id void * device id
  73566. + *
  73567. + * @return status IRQ_HANDLED for handled
  73568. + */
  73569. +static irqreturn_t prpvf_vf_eof_callback(int irq, void *dev_id)
  73570. +{
  73571. + cam_data *cam = dev_id;
  73572. + pr_debug("buffer_ready %d buffer_num %d\n", buffer_ready, buffer_num);
  73573. +
  73574. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  73575. + IPU_INPUT_BUFFER, buffer_num);
  73576. + buffer_num = (buffer_num == 0) ? 1 : 0;
  73577. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  73578. + IPU_OUTPUT_BUFFER, buffer_num);
  73579. + buffer_ready++;
  73580. + return IRQ_HANDLED;
  73581. +}
  73582. +
  73583. +/*!
  73584. + * prpvf_start - start the vf task
  73585. + *
  73586. + * @param private cam_data * mxc v4l2 main structure
  73587. + *
  73588. + */
  73589. +static int prpvf_start(void *private)
  73590. +{
  73591. + cam_data *cam = (cam_data *) private;
  73592. + ipu_channel_params_t vf;
  73593. + u32 format;
  73594. + u32 offset;
  73595. + u32 bpp, size = 3;
  73596. + int err = 0;
  73597. +#ifdef CONFIG_MXC_MIPI_CSI2
  73598. + void *mipi_csi2_info;
  73599. + int ipu_id;
  73600. + int csi_id;
  73601. +#endif
  73602. +
  73603. + if (!cam) {
  73604. + printk(KERN_ERR "private is NULL\n");
  73605. + return -EIO;
  73606. + }
  73607. +
  73608. + if (cam->overlay_active == true) {
  73609. + pr_debug("already start.\n");
  73610. + return 0;
  73611. + }
  73612. +
  73613. + get_disp_ipu(cam);
  73614. +
  73615. + format = cam->v4l2_fb.fmt.pixelformat;
  73616. + if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) {
  73617. + bpp = 3, size = 3;
  73618. + pr_info("BGR24\n");
  73619. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) {
  73620. + bpp = 2, size = 2;
  73621. + pr_info("RGB565\n");
  73622. + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) {
  73623. + bpp = 4, size = 4;
  73624. + pr_info("BGR32\n");
  73625. + } else {
  73626. + printk(KERN_ERR
  73627. + "unsupported fix format from the framebuffer.\n");
  73628. + return -EINVAL;
  73629. + }
  73630. +
  73631. + offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top +
  73632. + size * cam->win.w.left;
  73633. +
  73634. + if (cam->v4l2_fb.base == 0)
  73635. + printk(KERN_ERR "invalid frame buffer address.\n");
  73636. + else
  73637. + offset += (u32) cam->v4l2_fb.base;
  73638. +
  73639. + memset(&vf, 0, sizeof(ipu_channel_params_t));
  73640. + ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
  73641. + &vf.csi_prp_vf_mem.in_height, cam->csi);
  73642. + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  73643. + vf.csi_prp_vf_mem.out_width = cam->win.w.width;
  73644. + vf.csi_prp_vf_mem.out_height = cam->win.w.height;
  73645. + vf.csi_prp_vf_mem.csi = cam->csi;
  73646. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  73647. + vf.csi_prp_vf_mem.out_width = cam->win.w.height;
  73648. + vf.csi_prp_vf_mem.out_height = cam->win.w.width;
  73649. + }
  73650. + vf.csi_prp_vf_mem.out_pixel_fmt = format;
  73651. + size = cam->win.w.width * cam->win.w.height * size;
  73652. +
  73653. +#ifdef CONFIG_MXC_MIPI_CSI2
  73654. + mipi_csi2_info = mipi_csi2_get_info();
  73655. +
  73656. + if (mipi_csi2_info) {
  73657. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  73658. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  73659. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  73660. +
  73661. + if (cam->ipu == ipu_get_soc(ipu_id)
  73662. + && cam->csi == csi_id) {
  73663. + vf.csi_prp_vf_mem.mipi_en = true;
  73664. + vf.csi_prp_vf_mem.mipi_vc =
  73665. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  73666. + vf.csi_prp_vf_mem.mipi_id =
  73667. + mipi_csi2_get_datatype(mipi_csi2_info);
  73668. +
  73669. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  73670. + } else {
  73671. + vf.csi_prp_vf_mem.mipi_en = false;
  73672. + vf.csi_prp_vf_mem.mipi_vc = 0;
  73673. + vf.csi_prp_vf_mem.mipi_id = 0;
  73674. + }
  73675. + } else {
  73676. + vf.csi_prp_vf_mem.mipi_en = false;
  73677. + vf.csi_prp_vf_mem.mipi_vc = 0;
  73678. + vf.csi_prp_vf_mem.mipi_id = 0;
  73679. + }
  73680. + }
  73681. +#endif
  73682. +
  73683. + err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
  73684. + if (err != 0)
  73685. + goto out_4;
  73686. +
  73687. + if (cam->vf_bufs_vaddr[0]) {
  73688. + dma_free_coherent(0, cam->vf_bufs_size[0],
  73689. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  73690. + }
  73691. + if (cam->vf_bufs_vaddr[1]) {
  73692. + dma_free_coherent(0, cam->vf_bufs_size[1],
  73693. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  73694. + }
  73695. + cam->vf_bufs_size[0] = PAGE_ALIGN(size);
  73696. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  73697. + cam->vf_bufs_size[0],
  73698. + &cam->vf_bufs[0],
  73699. + GFP_DMA |
  73700. + GFP_KERNEL);
  73701. + if (cam->vf_bufs_vaddr[0] == NULL) {
  73702. + printk(KERN_ERR "Error to allocate vf buffer\n");
  73703. + err = -ENOMEM;
  73704. + goto out_3;
  73705. + }
  73706. + cam->vf_bufs_size[1] = PAGE_ALIGN(size);
  73707. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  73708. + cam->vf_bufs_size[1],
  73709. + &cam->vf_bufs[1],
  73710. + GFP_DMA |
  73711. + GFP_KERNEL);
  73712. + if (cam->vf_bufs_vaddr[1] == NULL) {
  73713. + printk(KERN_ERR "Error to allocate vf buffer\n");
  73714. + err = -ENOMEM;
  73715. + goto out_3;
  73716. + }
  73717. +
  73718. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  73719. + IPU_OUTPUT_BUFFER,
  73720. + format, vf.csi_prp_vf_mem.out_width,
  73721. + vf.csi_prp_vf_mem.out_height,
  73722. + vf.csi_prp_vf_mem.out_width,
  73723. + IPU_ROTATE_NONE,
  73724. + cam->vf_bufs[0],
  73725. + cam->vf_bufs[1],
  73726. + 0, 0, 0);
  73727. + if (err != 0) {
  73728. + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
  73729. + goto out_3;
  73730. + }
  73731. + err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
  73732. + if (err != 0) {
  73733. + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
  73734. + goto out_3;
  73735. + }
  73736. +
  73737. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  73738. + IPU_INPUT_BUFFER,
  73739. + format, vf.csi_prp_vf_mem.out_width,
  73740. + vf.csi_prp_vf_mem.out_height,
  73741. + vf.csi_prp_vf_mem.out_width,
  73742. + cam->vf_rotation,
  73743. + cam->vf_bufs[0],
  73744. + cam->vf_bufs[1],
  73745. + 0, 0, 0);
  73746. + if (err != 0) {
  73747. + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
  73748. + goto out_2;
  73749. + }
  73750. +
  73751. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  73752. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  73753. + IPU_OUTPUT_BUFFER,
  73754. + format,
  73755. + vf.csi_prp_vf_mem.out_height,
  73756. + vf.csi_prp_vf_mem.out_width,
  73757. + cam->overlay_fb->var.xres * bpp,
  73758. + IPU_ROTATE_NONE,
  73759. + offset, 0, 0, 0, 0);
  73760. +
  73761. + if (err != 0) {
  73762. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  73763. + goto out_2;
  73764. + }
  73765. + } else {
  73766. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  73767. + IPU_OUTPUT_BUFFER,
  73768. + format,
  73769. + vf.csi_prp_vf_mem.out_width,
  73770. + vf.csi_prp_vf_mem.out_height,
  73771. + cam->overlay_fb->var.xres * bpp,
  73772. + IPU_ROTATE_NONE,
  73773. + offset, 0, 0, 0, 0);
  73774. + if (err != 0) {
  73775. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  73776. + goto out_2;
  73777. + }
  73778. + }
  73779. +
  73780. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
  73781. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
  73782. + prpvf_vf_eof_callback,
  73783. + 0, "Mxc Camera", cam);
  73784. + if (err != 0) {
  73785. + printk(KERN_ERR
  73786. + "Error registering IPU_IRQ_PRP_VF_OUT_EOF irq.\n");
  73787. + goto out_2;
  73788. + }
  73789. +
  73790. + ipu_clear_irq(disp_ipu, IPU_IRQ_BG_SF_END);
  73791. + err = ipu_request_irq(disp_ipu, IPU_IRQ_BG_SF_END,
  73792. + prpvf_sdc_vsync_callback,
  73793. + 0, "Mxc Camera", cam);
  73794. + if (err != 0) {
  73795. + printk(KERN_ERR "Error registering IPU_IRQ_BG_SF_END irq.\n");
  73796. + goto out_1;
  73797. + }
  73798. +
  73799. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  73800. + ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
  73801. +
  73802. + buffer_num = 0;
  73803. + buffer_ready = 0;
  73804. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0);
  73805. +
  73806. + cam->overlay_active = true;
  73807. + return err;
  73808. +
  73809. +out_1:
  73810. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
  73811. +out_2:
  73812. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  73813. +out_3:
  73814. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  73815. +out_4:
  73816. + if (cam->vf_bufs_vaddr[0]) {
  73817. + dma_free_coherent(0, cam->vf_bufs_size[0],
  73818. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  73819. + cam->vf_bufs_vaddr[0] = NULL;
  73820. + cam->vf_bufs[0] = 0;
  73821. + }
  73822. + if (cam->vf_bufs_vaddr[1]) {
  73823. + dma_free_coherent(0, cam->vf_bufs_size[1],
  73824. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  73825. + cam->vf_bufs_vaddr[1] = NULL;
  73826. + cam->vf_bufs[1] = 0;
  73827. + }
  73828. + if (cam->rot_vf_bufs_vaddr[0]) {
  73829. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  73830. + cam->rot_vf_bufs_vaddr[0],
  73831. + cam->rot_vf_bufs[0]);
  73832. + cam->rot_vf_bufs_vaddr[0] = NULL;
  73833. + cam->rot_vf_bufs[0] = 0;
  73834. + }
  73835. + if (cam->rot_vf_bufs_vaddr[1]) {
  73836. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  73837. + cam->rot_vf_bufs_vaddr[1],
  73838. + cam->rot_vf_bufs[1]);
  73839. + cam->rot_vf_bufs_vaddr[1] = NULL;
  73840. + cam->rot_vf_bufs[1] = 0;
  73841. + }
  73842. + return err;
  73843. +}
  73844. +
  73845. +/*!
  73846. + * prpvf_stop - stop the vf task
  73847. + *
  73848. + * @param private cam_data * mxc v4l2 main structure
  73849. + *
  73850. + */
  73851. +static int prpvf_stop(void *private)
  73852. +{
  73853. + cam_data *cam = (cam_data *) private;
  73854. +#ifdef CONFIG_MXC_MIPI_CSI2
  73855. + void *mipi_csi2_info;
  73856. + int ipu_id;
  73857. + int csi_id;
  73858. +#endif
  73859. +
  73860. + if (cam->overlay_active == false)
  73861. + return 0;
  73862. +
  73863. + ipu_free_irq(disp_ipu, IPU_IRQ_BG_SF_END, cam);
  73864. +
  73865. + ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
  73866. + ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
  73867. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  73868. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  73869. +
  73870. +#ifdef CONFIG_MXC_MIPI_CSI2
  73871. + mipi_csi2_info = mipi_csi2_get_info();
  73872. +
  73873. + if (mipi_csi2_info) {
  73874. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  73875. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  73876. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  73877. +
  73878. + if (cam->ipu == ipu_get_soc(ipu_id)
  73879. + && cam->csi == csi_id)
  73880. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  73881. + }
  73882. + }
  73883. +#endif
  73884. +
  73885. + if (cam->vf_bufs_vaddr[0]) {
  73886. + dma_free_coherent(0, cam->vf_bufs_size[0],
  73887. + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]);
  73888. + cam->vf_bufs_vaddr[0] = NULL;
  73889. + cam->vf_bufs[0] = 0;
  73890. + }
  73891. + if (cam->vf_bufs_vaddr[1]) {
  73892. + dma_free_coherent(0, cam->vf_bufs_size[1],
  73893. + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]);
  73894. + cam->vf_bufs_vaddr[1] = NULL;
  73895. + cam->vf_bufs[1] = 0;
  73896. + }
  73897. + if (cam->rot_vf_bufs_vaddr[0]) {
  73898. + dma_free_coherent(0, cam->rot_vf_buf_size[0],
  73899. + cam->rot_vf_bufs_vaddr[0],
  73900. + cam->rot_vf_bufs[0]);
  73901. + cam->rot_vf_bufs_vaddr[0] = NULL;
  73902. + cam->rot_vf_bufs[0] = 0;
  73903. + }
  73904. + if (cam->rot_vf_bufs_vaddr[1]) {
  73905. + dma_free_coherent(0, cam->rot_vf_buf_size[1],
  73906. + cam->rot_vf_bufs_vaddr[1],
  73907. + cam->rot_vf_bufs[1]);
  73908. + cam->rot_vf_bufs_vaddr[1] = NULL;
  73909. + cam->rot_vf_bufs[1] = 0;
  73910. + }
  73911. +
  73912. + buffer_num = 0;
  73913. + buffer_ready = 0;
  73914. + cam->overlay_active = false;
  73915. + return 0;
  73916. +}
  73917. +
  73918. +/*!
  73919. + * Enable csi
  73920. + * @param private struct cam_data * mxc capture instance
  73921. + *
  73922. + * @return status
  73923. + */
  73924. +static int prp_vf_enable_csi(void *private)
  73925. +{
  73926. + cam_data *cam = (cam_data *) private;
  73927. +
  73928. + return ipu_enable_csi(cam->ipu, cam->csi);
  73929. +}
  73930. +
  73931. +/*!
  73932. + * Disable csi
  73933. + * @param private struct cam_data * mxc capture instance
  73934. + *
  73935. + * @return status
  73936. + */
  73937. +static int prp_vf_disable_csi(void *private)
  73938. +{
  73939. + cam_data *cam = (cam_data *) private;
  73940. +
  73941. + /* free csi eof irq firstly.
  73942. + * when disable csi, wait for idmac eof.
  73943. + * it requests eof irq again */
  73944. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
  73945. +
  73946. + return ipu_disable_csi(cam->ipu, cam->csi);
  73947. +}
  73948. +
  73949. +/*!
  73950. + * function to select PRP-VF as the working path
  73951. + *
  73952. + * @param private cam_data * mxc v4l2 main structure
  73953. + *
  73954. + * @return status
  73955. + */
  73956. +int prp_vf_sdc_select_bg(void *private)
  73957. +{
  73958. + cam_data *cam = (cam_data *) private;
  73959. +
  73960. + if (cam) {
  73961. + cam->vf_start_sdc = prpvf_start;
  73962. + cam->vf_stop_sdc = prpvf_stop;
  73963. + cam->vf_enable_csi = prp_vf_enable_csi;
  73964. + cam->vf_disable_csi = prp_vf_disable_csi;
  73965. + cam->overlay_active = false;
  73966. + }
  73967. +
  73968. + return 0;
  73969. +}
  73970. +EXPORT_SYMBOL(prp_vf_sdc_select_bg);
  73971. +
  73972. +/*!
  73973. + * function to de-select PRP-VF as the working path
  73974. + *
  73975. + * @param private cam_data * mxc v4l2 main structure
  73976. + *
  73977. + * @return status
  73978. + */
  73979. +int prp_vf_sdc_deselect_bg(void *private)
  73980. +{
  73981. + cam_data *cam = (cam_data *) private;
  73982. +
  73983. + if (cam) {
  73984. + cam->vf_start_sdc = NULL;
  73985. + cam->vf_stop_sdc = NULL;
  73986. + cam->vf_enable_csi = NULL;
  73987. + cam->vf_disable_csi = NULL;
  73988. + }
  73989. + return 0;
  73990. +}
  73991. +EXPORT_SYMBOL(prp_vf_sdc_deselect_bg);
  73992. +
  73993. +/*!
  73994. + * Init viewfinder task.
  73995. + *
  73996. + * @return Error code indicating success or failure
  73997. + */
  73998. +__init int prp_vf_sdc_init_bg(void)
  73999. +{
  74000. + return 0;
  74001. +}
  74002. +
  74003. +/*!
  74004. + * Deinit viewfinder task.
  74005. + *
  74006. + * @return Error code indicating success or failure
  74007. + */
  74008. +void __exit prp_vf_sdc_exit_bg(void)
  74009. +{
  74010. +}
  74011. +
  74012. +module_init(prp_vf_sdc_init_bg);
  74013. +module_exit(prp_vf_sdc_exit_bg);
  74014. +
  74015. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  74016. +MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver");
  74017. +MODULE_LICENSE("GPL");
  74018. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c
  74019. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c 1970-01-01 01:00:00.000000000 +0100
  74020. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_prp_vf_sdc.c 2014-09-11 18:06:02.254038983 +0200
  74021. @@ -0,0 +1,582 @@
  74022. +/*
  74023. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  74024. + */
  74025. +/* * The code contained herein is licensed under the GNU General Public
  74026. + * License. You may obtain a copy of the GNU General Public License
  74027. + * Version 2 or later at the following locations:
  74028. + *
  74029. + * http://www.opensource.org/licenses/gpl-license.html
  74030. + * http://www.gnu.org/copyleft/gpl.html
  74031. + */
  74032. +
  74033. +/*!
  74034. + * @file ipu_prp_vf_sdc.c
  74035. + *
  74036. + * @brief IPU Use case for PRP-VF
  74037. + *
  74038. + * @ingroup IPU
  74039. + */
  74040. +
  74041. +#include <linux/dma-mapping.h>
  74042. +#include <linux/console.h>
  74043. +#include <linux/ipu.h>
  74044. +#include <linux/module.h>
  74045. +#include <linux/mxcfb.h>
  74046. +#include <mach/hardware.h>
  74047. +#include <mach/mipi_csi2.h>
  74048. +#include "mxc_v4l2_capture.h"
  74049. +#include "ipu_prp_sw.h"
  74050. +
  74051. +static int buffer_num;
  74052. +static struct ipu_soc *disp_ipu;
  74053. +
  74054. +static void get_disp_ipu(cam_data *cam)
  74055. +{
  74056. + if (cam->output > 2)
  74057. + disp_ipu = ipu_get_soc(1); /* using DISP4 */
  74058. + else
  74059. + disp_ipu = ipu_get_soc(0);
  74060. +}
  74061. +
  74062. +static irqreturn_t prpvf_rot_eof_callback(int irq, void *dev_id)
  74063. +{
  74064. + cam_data *cam = dev_id;
  74065. + pr_debug("buffer_num %d\n", buffer_num);
  74066. +
  74067. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  74068. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
  74069. + IPU_INPUT_BUFFER, buffer_num);
  74070. + buffer_num = (buffer_num == 0) ? 1 : 0;
  74071. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  74072. + IPU_OUTPUT_BUFFER, buffer_num);
  74073. + } else {
  74074. + ipu_select_buffer(disp_ipu, MEM_FG_SYNC,
  74075. + IPU_INPUT_BUFFER, buffer_num);
  74076. + buffer_num = (buffer_num == 0) ? 1 : 0;
  74077. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  74078. + IPU_OUTPUT_BUFFER, buffer_num);
  74079. + }
  74080. + return IRQ_HANDLED;
  74081. +}
  74082. +/*
  74083. + * Function definitions
  74084. + */
  74085. +
  74086. +/*!
  74087. + * prpvf_start - start the vf task
  74088. + *
  74089. + * @param private cam_data * mxc v4l2 main structure
  74090. + *
  74091. + */
  74092. +static int prpvf_start(void *private)
  74093. +{
  74094. + struct fb_var_screeninfo fbvar;
  74095. + struct fb_info *fbi = NULL;
  74096. + cam_data *cam = (cam_data *) private;
  74097. + ipu_channel_params_t vf;
  74098. + u32 vf_out_format = 0;
  74099. + u32 size = 2, temp = 0;
  74100. + int err = 0, i = 0;
  74101. + short *tmp, color;
  74102. +#ifdef CONFIG_MXC_MIPI_CSI2
  74103. + void *mipi_csi2_info;
  74104. + int ipu_id;
  74105. + int csi_id;
  74106. +#endif
  74107. +
  74108. + if (!cam) {
  74109. + printk(KERN_ERR "private is NULL\n");
  74110. + return -EIO;
  74111. + }
  74112. +
  74113. + if (cam->overlay_active == true) {
  74114. + pr_debug("already started.\n");
  74115. + return 0;
  74116. + }
  74117. +
  74118. + get_disp_ipu(cam);
  74119. +
  74120. + for (i = 0; i < num_registered_fb; i++) {
  74121. + char *idstr = registered_fb[i]->fix.id;
  74122. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  74123. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  74124. + fbi = registered_fb[i];
  74125. + break;
  74126. + }
  74127. + }
  74128. +
  74129. + if (fbi == NULL) {
  74130. + printk(KERN_ERR "DISP FG fb not found\n");
  74131. + return -EPERM;
  74132. + }
  74133. +
  74134. + fbvar = fbi->var;
  74135. +
  74136. + /* Store the overlay frame buffer's original std */
  74137. + cam->fb_origin_std = fbvar.nonstd;
  74138. +
  74139. + if (cam->devtype == IMX5_V4L2 || cam->devtype == IMX6_V4L2) {
  74140. + /* Use DP to do CSC so that we can get better performance */
  74141. + vf_out_format = IPU_PIX_FMT_UYVY;
  74142. + fbvar.nonstd = vf_out_format;
  74143. + color = 0x80;
  74144. + } else {
  74145. + vf_out_format = IPU_PIX_FMT_RGB565;
  74146. + fbvar.nonstd = 0;
  74147. + color = 0x0;
  74148. + }
  74149. +
  74150. + fbvar.bits_per_pixel = 16;
  74151. + fbvar.xres = fbvar.xres_virtual = cam->win.w.width;
  74152. + fbvar.yres = cam->win.w.height;
  74153. + fbvar.yres_virtual = cam->win.w.height * 2;
  74154. + fbvar.yoffset = 0;
  74155. + fbvar.accel_flags = FB_ACCEL_DOUBLE_FLAG;
  74156. + fbvar.activate |= FB_ACTIVATE_FORCE;
  74157. + fb_set_var(fbi, &fbvar);
  74158. +
  74159. + ipu_disp_set_window_pos(disp_ipu, MEM_FG_SYNC, cam->win.w.left,
  74160. + cam->win.w.top);
  74161. +
  74162. + /* Fill black color for framebuffer */
  74163. + tmp = (short *) fbi->screen_base;
  74164. + for (i = 0; i < (fbi->fix.line_length * fbi->var.yres)/2;
  74165. + i++, tmp++)
  74166. + *tmp = color;
  74167. +
  74168. + console_lock();
  74169. + fb_blank(fbi, FB_BLANK_UNBLANK);
  74170. + console_unlock();
  74171. +
  74172. + /* correct display ch buffer address */
  74173. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  74174. + 0, fbi->fix.smem_start +
  74175. + (fbi->fix.line_length * fbvar.yres));
  74176. + ipu_update_channel_buffer(disp_ipu, MEM_FG_SYNC, IPU_INPUT_BUFFER,
  74177. + 1, fbi->fix.smem_start);
  74178. +
  74179. + memset(&vf, 0, sizeof(ipu_channel_params_t));
  74180. + ipu_csi_get_window_size(cam->ipu, &vf.csi_prp_vf_mem.in_width,
  74181. + &vf.csi_prp_vf_mem.in_height, cam->csi);
  74182. + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY;
  74183. + vf.csi_prp_vf_mem.out_width = cam->win.w.width;
  74184. + vf.csi_prp_vf_mem.out_height = cam->win.w.height;
  74185. + vf.csi_prp_vf_mem.csi = cam->csi;
  74186. + if (cam->vf_rotation >= IPU_ROTATE_90_RIGHT) {
  74187. + vf.csi_prp_vf_mem.out_width = cam->win.w.height;
  74188. + vf.csi_prp_vf_mem.out_height = cam->win.w.width;
  74189. + }
  74190. + vf.csi_prp_vf_mem.out_pixel_fmt = vf_out_format;
  74191. + size = cam->win.w.width * cam->win.w.height * size;
  74192. +
  74193. +#ifdef CONFIG_MXC_MIPI_CSI2
  74194. + mipi_csi2_info = mipi_csi2_get_info();
  74195. +
  74196. + if (mipi_csi2_info) {
  74197. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  74198. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  74199. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  74200. +
  74201. + if (cam->ipu == ipu_get_soc(ipu_id)
  74202. + && cam->csi == csi_id) {
  74203. + vf.csi_prp_vf_mem.mipi_en = true;
  74204. + vf.csi_prp_vf_mem.mipi_vc =
  74205. + mipi_csi2_get_virtual_channel(mipi_csi2_info);
  74206. + vf.csi_prp_vf_mem.mipi_id =
  74207. + mipi_csi2_get_datatype(mipi_csi2_info);
  74208. +
  74209. + mipi_csi2_pixelclk_enable(mipi_csi2_info);
  74210. + } else {
  74211. + vf.csi_prp_vf_mem.mipi_en = false;
  74212. + vf.csi_prp_vf_mem.mipi_vc = 0;
  74213. + vf.csi_prp_vf_mem.mipi_id = 0;
  74214. + }
  74215. + } else {
  74216. + vf.csi_prp_vf_mem.mipi_en = false;
  74217. + vf.csi_prp_vf_mem.mipi_vc = 0;
  74218. + vf.csi_prp_vf_mem.mipi_id = 0;
  74219. + }
  74220. + }
  74221. +#endif
  74222. +
  74223. + err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
  74224. + if (err != 0)
  74225. + goto out_5;
  74226. +
  74227. + if (cam->vf_bufs_vaddr[0]) {
  74228. + dma_free_coherent(0, cam->vf_bufs_size[0],
  74229. + cam->vf_bufs_vaddr[0],
  74230. + (dma_addr_t) cam->vf_bufs[0]);
  74231. + }
  74232. + if (cam->vf_bufs_vaddr[1]) {
  74233. + dma_free_coherent(0, cam->vf_bufs_size[1],
  74234. + cam->vf_bufs_vaddr[1],
  74235. + (dma_addr_t) cam->vf_bufs[1]);
  74236. + }
  74237. + cam->vf_bufs_size[0] = PAGE_ALIGN(size);
  74238. + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0,
  74239. + cam->vf_bufs_size[0],
  74240. + (dma_addr_t *) &
  74241. + cam->vf_bufs[0],
  74242. + GFP_DMA |
  74243. + GFP_KERNEL);
  74244. + if (cam->vf_bufs_vaddr[0] == NULL) {
  74245. + printk(KERN_ERR "Error to allocate vf buffer\n");
  74246. + err = -ENOMEM;
  74247. + goto out_4;
  74248. + }
  74249. + cam->vf_bufs_size[1] = PAGE_ALIGN(size);
  74250. + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0,
  74251. + cam->vf_bufs_size[1],
  74252. + (dma_addr_t *) &
  74253. + cam->vf_bufs[1],
  74254. + GFP_DMA |
  74255. + GFP_KERNEL);
  74256. + if (cam->vf_bufs_vaddr[1] == NULL) {
  74257. + printk(KERN_ERR "Error to allocate vf buffer\n");
  74258. + err = -ENOMEM;
  74259. + goto out_3;
  74260. + }
  74261. + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]);
  74262. +
  74263. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  74264. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  74265. + IPU_OUTPUT_BUFFER,
  74266. + vf_out_format,
  74267. + vf.csi_prp_vf_mem.out_width,
  74268. + vf.csi_prp_vf_mem.out_height,
  74269. + vf.csi_prp_vf_mem.out_width,
  74270. + IPU_ROTATE_NONE,
  74271. + cam->vf_bufs[0], cam->vf_bufs[1],
  74272. + 0, 0, 0);
  74273. + if (err != 0)
  74274. + goto out_3;
  74275. +
  74276. + err = ipu_init_channel(cam->ipu, MEM_ROT_VF_MEM, NULL);
  74277. + if (err != 0) {
  74278. + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n");
  74279. + goto out_3;
  74280. + }
  74281. +
  74282. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  74283. + IPU_INPUT_BUFFER,
  74284. + vf_out_format,
  74285. + vf.csi_prp_vf_mem.out_width,
  74286. + vf.csi_prp_vf_mem.out_height,
  74287. + vf.csi_prp_vf_mem.out_width,
  74288. + cam->vf_rotation,
  74289. + cam->vf_bufs[0],
  74290. + cam->vf_bufs[1],
  74291. + 0, 0, 0);
  74292. + if (err != 0) {
  74293. + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n");
  74294. + goto out_2;
  74295. + }
  74296. +
  74297. + if (cam->vf_rotation < IPU_ROTATE_90_RIGHT) {
  74298. + temp = vf.csi_prp_vf_mem.out_width;
  74299. + vf.csi_prp_vf_mem.out_width =
  74300. + vf.csi_prp_vf_mem.out_height;
  74301. + vf.csi_prp_vf_mem.out_height = temp;
  74302. + }
  74303. +
  74304. + err = ipu_init_channel_buffer(cam->ipu, MEM_ROT_VF_MEM,
  74305. + IPU_OUTPUT_BUFFER,
  74306. + vf_out_format,
  74307. + vf.csi_prp_vf_mem.out_height,
  74308. + vf.csi_prp_vf_mem.out_width,
  74309. + vf.csi_prp_vf_mem.out_height,
  74310. + IPU_ROTATE_NONE,
  74311. + fbi->fix.smem_start +
  74312. + (fbi->fix.line_length *
  74313. + fbi->var.yres),
  74314. + fbi->fix.smem_start, 0, 0, 0);
  74315. +
  74316. + if (err != 0) {
  74317. + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n");
  74318. + goto out_2;
  74319. + }
  74320. +
  74321. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF);
  74322. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF,
  74323. + prpvf_rot_eof_callback,
  74324. + 0, "Mxc Camera", cam);
  74325. + if (err < 0) {
  74326. + printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_ROT_OUT_EOF\n");
  74327. + goto out_2;
  74328. + }
  74329. +
  74330. + err = ipu_link_channels(cam->ipu,
  74331. + CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
  74332. + if (err < 0) {
  74333. + printk(KERN_ERR
  74334. + "Error link CSI_PRP_VF_MEM-MEM_ROT_VF_MEM\n");
  74335. + goto out_1;
  74336. + }
  74337. +
  74338. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  74339. + ipu_enable_channel(cam->ipu, MEM_ROT_VF_MEM);
  74340. +
  74341. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  74342. + IPU_OUTPUT_BUFFER, 0);
  74343. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  74344. + IPU_OUTPUT_BUFFER, 1);
  74345. + ipu_select_buffer(cam->ipu, MEM_ROT_VF_MEM,
  74346. + IPU_OUTPUT_BUFFER, 0);
  74347. + } else {
  74348. + err = ipu_init_channel_buffer(cam->ipu, CSI_PRP_VF_MEM,
  74349. + IPU_OUTPUT_BUFFER,
  74350. + vf_out_format, cam->win.w.width,
  74351. + cam->win.w.height,
  74352. + cam->win.w.width,
  74353. + cam->vf_rotation,
  74354. + fbi->fix.smem_start +
  74355. + (fbi->fix.line_length *
  74356. + fbi->var.yres),
  74357. + fbi->fix.smem_start, 0, 0, 0);
  74358. + if (err != 0) {
  74359. + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n");
  74360. + goto out_4;
  74361. + }
  74362. + ipu_clear_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF);
  74363. + err = ipu_request_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF,
  74364. + prpvf_rot_eof_callback,
  74365. + 0, "Mxc Camera", cam);
  74366. + if (err < 0) {
  74367. + printk(KERN_ERR "Error request irq:IPU_IRQ_PRP_VF_OUT_EOF\n");
  74368. + goto out_4;
  74369. + }
  74370. +
  74371. + ipu_enable_channel(cam->ipu, CSI_PRP_VF_MEM);
  74372. +
  74373. + ipu_select_buffer(cam->ipu, CSI_PRP_VF_MEM,
  74374. + IPU_OUTPUT_BUFFER, 0);
  74375. + }
  74376. +
  74377. + cam->overlay_active = true;
  74378. + return err;
  74379. +
  74380. +out_1:
  74381. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, NULL);
  74382. +out_2:
  74383. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP)
  74384. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  74385. +out_3:
  74386. + if (cam->vf_bufs_vaddr[0]) {
  74387. + dma_free_coherent(0, cam->vf_bufs_size[0],
  74388. + cam->vf_bufs_vaddr[0],
  74389. + (dma_addr_t) cam->vf_bufs[0]);
  74390. + cam->vf_bufs_vaddr[0] = NULL;
  74391. + cam->vf_bufs[0] = 0;
  74392. + }
  74393. + if (cam->vf_bufs_vaddr[1]) {
  74394. + dma_free_coherent(0, cam->vf_bufs_size[1],
  74395. + cam->vf_bufs_vaddr[1],
  74396. + (dma_addr_t) cam->vf_bufs[1]);
  74397. + cam->vf_bufs_vaddr[1] = NULL;
  74398. + cam->vf_bufs[1] = 0;
  74399. + }
  74400. +out_4:
  74401. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  74402. +out_5:
  74403. + return err;
  74404. +}
  74405. +
  74406. +/*!
  74407. + * prpvf_stop - stop the vf task
  74408. + *
  74409. + * @param private cam_data * mxc v4l2 main structure
  74410. + *
  74411. + */
  74412. +static int prpvf_stop(void *private)
  74413. +{
  74414. + cam_data *cam = (cam_data *) private;
  74415. + int err = 0, i = 0;
  74416. + struct fb_info *fbi = NULL;
  74417. + struct fb_var_screeninfo fbvar;
  74418. +#ifdef CONFIG_MXC_MIPI_CSI2
  74419. + void *mipi_csi2_info;
  74420. + int ipu_id;
  74421. + int csi_id;
  74422. +#endif
  74423. +
  74424. + if (cam->overlay_active == false)
  74425. + return 0;
  74426. +
  74427. + for (i = 0; i < num_registered_fb; i++) {
  74428. + char *idstr = registered_fb[i]->fix.id;
  74429. + if (((strcmp(idstr, "DISP3 FG") == 0) && (cam->output < 3)) ||
  74430. + ((strcmp(idstr, "DISP4 FG") == 0) && (cam->output >= 3))) {
  74431. + fbi = registered_fb[i];
  74432. + break;
  74433. + }
  74434. + }
  74435. +
  74436. + if (fbi == NULL) {
  74437. + printk(KERN_ERR "DISP FG fb not found\n");
  74438. + return -EPERM;
  74439. + }
  74440. +
  74441. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  74442. + ipu_unlink_channels(cam->ipu, CSI_PRP_VF_MEM, MEM_ROT_VF_MEM);
  74443. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_ROT_OUT_EOF, cam);
  74444. + }
  74445. + buffer_num = 0;
  74446. +
  74447. + ipu_disable_channel(cam->ipu, CSI_PRP_VF_MEM, true);
  74448. +
  74449. + if (cam->vf_rotation >= IPU_ROTATE_VERT_FLIP) {
  74450. + ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
  74451. + ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
  74452. + }
  74453. + ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
  74454. +
  74455. + console_lock();
  74456. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  74457. + console_unlock();
  74458. +
  74459. + /* Set the overlay frame buffer std to what it is used to be */
  74460. + fbvar = fbi->var;
  74461. + fbvar.accel_flags = FB_ACCEL_TRIPLE_FLAG;
  74462. + fbvar.nonstd = cam->fb_origin_std;
  74463. + fbvar.activate |= FB_ACTIVATE_FORCE;
  74464. + fb_set_var(fbi, &fbvar);
  74465. +
  74466. +#ifdef CONFIG_MXC_MIPI_CSI2
  74467. + mipi_csi2_info = mipi_csi2_get_info();
  74468. +
  74469. + if (mipi_csi2_info) {
  74470. + if (mipi_csi2_get_status(mipi_csi2_info)) {
  74471. + ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
  74472. + csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
  74473. +
  74474. + if (cam->ipu == ipu_get_soc(ipu_id)
  74475. + && cam->csi == csi_id)
  74476. + mipi_csi2_pixelclk_disable(mipi_csi2_info);
  74477. + }
  74478. + }
  74479. +#endif
  74480. +
  74481. + if (cam->vf_bufs_vaddr[0]) {
  74482. + dma_free_coherent(0, cam->vf_bufs_size[0],
  74483. + cam->vf_bufs_vaddr[0],
  74484. + (dma_addr_t) cam->vf_bufs[0]);
  74485. + cam->vf_bufs_vaddr[0] = NULL;
  74486. + cam->vf_bufs[0] = 0;
  74487. + }
  74488. + if (cam->vf_bufs_vaddr[1]) {
  74489. + dma_free_coherent(0, cam->vf_bufs_size[1],
  74490. + cam->vf_bufs_vaddr[1],
  74491. + (dma_addr_t) cam->vf_bufs[1]);
  74492. + cam->vf_bufs_vaddr[1] = NULL;
  74493. + cam->vf_bufs[1] = 0;
  74494. + }
  74495. +
  74496. + cam->overlay_active = false;
  74497. + return err;
  74498. +}
  74499. +
  74500. +/*!
  74501. + * Enable csi
  74502. + * @param private struct cam_data * mxc capture instance
  74503. + *
  74504. + * @return status
  74505. + */
  74506. +static int prp_vf_enable_csi(void *private)
  74507. +{
  74508. + cam_data *cam = (cam_data *) private;
  74509. +
  74510. + return ipu_enable_csi(cam->ipu, cam->csi);
  74511. +}
  74512. +
  74513. +/*!
  74514. + * Disable csi
  74515. + * @param private struct cam_data * mxc capture instance
  74516. + *
  74517. + * @return status
  74518. + */
  74519. +static int prp_vf_disable_csi(void *private)
  74520. +{
  74521. + cam_data *cam = (cam_data *) private;
  74522. +
  74523. + /* free csi eof irq firstly.
  74524. + * when disable csi, wait for idmac eof.
  74525. + * it requests eof irq again */
  74526. + if (cam->vf_rotation < IPU_ROTATE_VERT_FLIP)
  74527. + ipu_free_irq(cam->ipu, IPU_IRQ_PRP_VF_OUT_EOF, cam);
  74528. +
  74529. + return ipu_disable_csi(cam->ipu, cam->csi);
  74530. +}
  74531. +
  74532. +/*!
  74533. + * function to select PRP-VF as the working path
  74534. + *
  74535. + * @param private cam_data * mxc v4l2 main structure
  74536. + *
  74537. + * @return status
  74538. + */
  74539. +int prp_vf_sdc_select(void *private)
  74540. +{
  74541. + cam_data *cam;
  74542. + int err = 0;
  74543. + if (private) {
  74544. + cam = (cam_data *) private;
  74545. + cam->vf_start_sdc = prpvf_start;
  74546. + cam->vf_stop_sdc = prpvf_stop;
  74547. + cam->vf_enable_csi = prp_vf_enable_csi;
  74548. + cam->vf_disable_csi = prp_vf_disable_csi;
  74549. + cam->overlay_active = false;
  74550. + } else
  74551. + err = -EIO;
  74552. +
  74553. + return err;
  74554. +}
  74555. +EXPORT_SYMBOL(prp_vf_sdc_select);
  74556. +
  74557. +/*!
  74558. + * function to de-select PRP-VF as the working path
  74559. + *
  74560. + * @param private cam_data * mxc v4l2 main structure
  74561. + *
  74562. + * @return int
  74563. + */
  74564. +int prp_vf_sdc_deselect(void *private)
  74565. +{
  74566. + cam_data *cam;
  74567. +
  74568. + if (private) {
  74569. + cam = (cam_data *) private;
  74570. + cam->vf_start_sdc = NULL;
  74571. + cam->vf_stop_sdc = NULL;
  74572. + cam->vf_enable_csi = NULL;
  74573. + cam->vf_disable_csi = NULL;
  74574. + }
  74575. + return 0;
  74576. +}
  74577. +EXPORT_SYMBOL(prp_vf_sdc_deselect);
  74578. +
  74579. +/*!
  74580. + * Init viewfinder task.
  74581. + *
  74582. + * @return Error code indicating success or failure
  74583. + */
  74584. +__init int prp_vf_sdc_init(void)
  74585. +{
  74586. + return 0;
  74587. +}
  74588. +
  74589. +/*!
  74590. + * Deinit viewfinder task.
  74591. + *
  74592. + * @return Error code indicating success or failure
  74593. + */
  74594. +void __exit prp_vf_sdc_exit(void)
  74595. +{
  74596. +}
  74597. +
  74598. +module_init(prp_vf_sdc_init);
  74599. +module_exit(prp_vf_sdc_exit);
  74600. +
  74601. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  74602. +MODULE_DESCRIPTION("IPU PRP VF SDC Driver");
  74603. +MODULE_LICENSE("GPL");
  74604. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ipu_still.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_still.c
  74605. --- linux-3.14.17/drivers/media/platform/mxc/capture/ipu_still.c 1970-01-01 01:00:00.000000000 +0100
  74606. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ipu_still.c 2014-09-11 18:06:02.254038983 +0200
  74607. @@ -0,0 +1,268 @@
  74608. +/*
  74609. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  74610. + */
  74611. +
  74612. +/*
  74613. + * The code contained herein is licensed under the GNU General Public
  74614. + * License. You may obtain a copy of the GNU General Public License
  74615. + * Version 2 or later at the following locations:
  74616. + *
  74617. + * http://www.opensource.org/licenses/gpl-license.html
  74618. + * http://www.gnu.org/copyleft/gpl.html
  74619. + */
  74620. +
  74621. +/*!
  74622. + * @file ipu_still.c
  74623. + *
  74624. + * @brief IPU Use case for still image capture
  74625. + *
  74626. + * @ingroup IPU
  74627. + */
  74628. +
  74629. +#include <linux/module.h>
  74630. +#include <linux/semaphore.h>
  74631. +#include <linux/sched.h>
  74632. +#include <linux/ipu.h>
  74633. +#include "mxc_v4l2_capture.h"
  74634. +#include "ipu_prp_sw.h"
  74635. +
  74636. +static int callback_eof_flag;
  74637. +#ifndef CONFIG_MXC_IPU_V1
  74638. +static int buffer_num;
  74639. +#endif
  74640. +
  74641. +#ifdef CONFIG_MXC_IPU_V1
  74642. +static int callback_flag;
  74643. +/*
  74644. + * Function definitions
  74645. + */
  74646. +/*!
  74647. + * CSI EOF callback function.
  74648. + *
  74649. + * @param irq int irq line
  74650. + * @param dev_id void * device id
  74651. + *
  74652. + * @return status IRQ_HANDLED for handled
  74653. + */
  74654. +static irqreturn_t prp_csi_eof_callback(int irq, void *dev_id)
  74655. +{
  74656. + cam_data *cam = devid;
  74657. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  74658. + callback_flag%2 ? 1 : 0);
  74659. + if (callback_flag == 0)
  74660. + ipu_enable_channel(cam->ipu, CSI_MEM);
  74661. +
  74662. + callback_flag++;
  74663. + return IRQ_HANDLED;
  74664. +}
  74665. +#endif
  74666. +
  74667. +/*!
  74668. + * CSI callback function.
  74669. + *
  74670. + * @param irq int irq line
  74671. + * @param dev_id void * device id
  74672. + *
  74673. + * @return status IRQ_HANDLED for handled
  74674. + */
  74675. +static irqreturn_t prp_still_callback(int irq, void *dev_id)
  74676. +{
  74677. + cam_data *cam = (cam_data *) dev_id;
  74678. +
  74679. + callback_eof_flag++;
  74680. + if (callback_eof_flag < 5) {
  74681. +#ifndef CONFIG_MXC_IPU_V1
  74682. + buffer_num = (buffer_num == 0) ? 1 : 0;
  74683. + ipu_select_buffer(cam->ipu, CSI_MEM,
  74684. + IPU_OUTPUT_BUFFER, buffer_num);
  74685. +#endif
  74686. + } else {
  74687. + cam->still_counter++;
  74688. + wake_up_interruptible(&cam->still_queue);
  74689. + }
  74690. +
  74691. + return IRQ_HANDLED;
  74692. +}
  74693. +
  74694. +/*!
  74695. + * start csi->mem task
  74696. + * @param private struct cam_data * mxc capture instance
  74697. + *
  74698. + * @return status
  74699. + */
  74700. +static int prp_still_start(void *private)
  74701. +{
  74702. + cam_data *cam = (cam_data *) private;
  74703. + u32 pixel_fmt;
  74704. + int err;
  74705. + ipu_channel_params_t params;
  74706. +
  74707. + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
  74708. + pixel_fmt = IPU_PIX_FMT_YUV420P;
  74709. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
  74710. + pixel_fmt = IPU_PIX_FMT_NV12;
  74711. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P)
  74712. + pixel_fmt = IPU_PIX_FMT_YUV422P;
  74713. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  74714. + pixel_fmt = IPU_PIX_FMT_UYVY;
  74715. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
  74716. + pixel_fmt = IPU_PIX_FMT_YUYV;
  74717. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
  74718. + pixel_fmt = IPU_PIX_FMT_BGR24;
  74719. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
  74720. + pixel_fmt = IPU_PIX_FMT_RGB24;
  74721. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  74722. + pixel_fmt = IPU_PIX_FMT_RGB565;
  74723. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
  74724. + pixel_fmt = IPU_PIX_FMT_BGR32;
  74725. + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
  74726. + pixel_fmt = IPU_PIX_FMT_RGB32;
  74727. + else {
  74728. + printk(KERN_ERR "format not supported\n");
  74729. + return -EINVAL;
  74730. + }
  74731. +
  74732. + memset(&params, 0, sizeof(params));
  74733. + err = ipu_init_channel(cam->ipu, CSI_MEM, &params);
  74734. + if (err != 0)
  74735. + return err;
  74736. +
  74737. + err = ipu_init_channel_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER,
  74738. + pixel_fmt, cam->v2f.fmt.pix.width,
  74739. + cam->v2f.fmt.pix.height,
  74740. + cam->v2f.fmt.pix.width, IPU_ROTATE_NONE,
  74741. + cam->still_buf[0], cam->still_buf[1], 0,
  74742. + 0, 0);
  74743. + if (err != 0)
  74744. + return err;
  74745. +
  74746. +#ifdef CONFIG_MXC_IPU_V1
  74747. + ipu_clear_irq(IPU_IRQ_SENSOR_OUT_EOF);
  74748. + err = ipu_request_irq(IPU_IRQ_SENSOR_OUT_EOF, prp_still_callback,
  74749. + 0, "Mxc Camera", cam);
  74750. + if (err != 0) {
  74751. + printk(KERN_ERR "Error registering irq.\n");
  74752. + return err;
  74753. + }
  74754. + callback_flag = 0;
  74755. + callback_eof_flag = 0;
  74756. + ipu_clear_irq(IPU_IRQ_SENSOR_EOF);
  74757. + err = ipu_request_irq(IPU_IRQ_SENSOR_EOF, prp_csi_eof_callback,
  74758. + 0, "Mxc Camera", cam);
  74759. + if (err != 0) {
  74760. + printk(KERN_ERR "Error IPU_IRQ_SENSOR_EOF\n");
  74761. + return err;
  74762. + }
  74763. +#else
  74764. + callback_eof_flag = 0;
  74765. + buffer_num = 0;
  74766. +
  74767. + ipu_clear_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF);
  74768. + err = ipu_request_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF,
  74769. + prp_still_callback,
  74770. + 0, "Mxc Camera", cam);
  74771. + if (err != 0) {
  74772. + printk(KERN_ERR "Error registering irq.\n");
  74773. + return err;
  74774. + }
  74775. +
  74776. + ipu_select_buffer(cam->ipu, CSI_MEM, IPU_OUTPUT_BUFFER, 0);
  74777. + ipu_enable_channel(cam->ipu, CSI_MEM);
  74778. + ipu_enable_csi(cam->ipu, cam->csi);
  74779. +#endif
  74780. +
  74781. + return err;
  74782. +}
  74783. +
  74784. +/*!
  74785. + * stop csi->mem encoder task
  74786. + * @param private struct cam_data * mxc capture instance
  74787. + *
  74788. + * @return status
  74789. + */
  74790. +static int prp_still_stop(void *private)
  74791. +{
  74792. + cam_data *cam = (cam_data *) private;
  74793. + int err = 0;
  74794. +
  74795. +#ifdef CONFIG_MXC_IPU_V1
  74796. + ipu_free_irq(IPU_IRQ_SENSOR_EOF, NULL);
  74797. + ipu_free_irq(IPU_IRQ_SENSOR_OUT_EOF, cam);
  74798. +#else
  74799. + ipu_free_irq(cam->ipu, IPU_IRQ_CSI0_OUT_EOF, cam);
  74800. +#endif
  74801. +
  74802. + ipu_disable_csi(cam->ipu, cam->csi);
  74803. + ipu_disable_channel(cam->ipu, CSI_MEM, true);
  74804. + ipu_uninit_channel(cam->ipu, CSI_MEM);
  74805. +
  74806. + return err;
  74807. +}
  74808. +
  74809. +/*!
  74810. + * function to select CSI_MEM as the working path
  74811. + *
  74812. + * @param private struct cam_data * mxc capture instance
  74813. + *
  74814. + * @return status
  74815. + */
  74816. +int prp_still_select(void *private)
  74817. +{
  74818. + cam_data *cam = (cam_data *) private;
  74819. +
  74820. + if (cam) {
  74821. + cam->csi_start = prp_still_start;
  74822. + cam->csi_stop = prp_still_stop;
  74823. + }
  74824. +
  74825. + return 0;
  74826. +}
  74827. +EXPORT_SYMBOL(prp_still_select);
  74828. +
  74829. +/*!
  74830. + * function to de-select CSI_MEM as the working path
  74831. + *
  74832. + * @param private struct cam_data * mxc capture instance
  74833. + *
  74834. + * @return status
  74835. + */
  74836. +int prp_still_deselect(void *private)
  74837. +{
  74838. + cam_data *cam = (cam_data *) private;
  74839. + int err = 0;
  74840. +
  74841. + err = prp_still_stop(cam);
  74842. +
  74843. + if (cam) {
  74844. + cam->csi_start = NULL;
  74845. + cam->csi_stop = NULL;
  74846. + }
  74847. +
  74848. + return err;
  74849. +}
  74850. +EXPORT_SYMBOL(prp_still_deselect);
  74851. +
  74852. +/*!
  74853. + * Init the Encorder channels
  74854. + *
  74855. + * @return Error code indicating success or failure
  74856. + */
  74857. +__init int prp_still_init(void)
  74858. +{
  74859. + return 0;
  74860. +}
  74861. +
  74862. +/*!
  74863. + * Deinit the Encorder channels
  74864. + *
  74865. + */
  74866. +void __exit prp_still_exit(void)
  74867. +{
  74868. +}
  74869. +
  74870. +module_init(prp_still_init);
  74871. +module_exit(prp_still_exit);
  74872. +
  74873. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  74874. +MODULE_DESCRIPTION("IPU PRP STILL IMAGE Driver");
  74875. +MODULE_LICENSE("GPL");
  74876. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/Kconfig linux-imx6-3.14/drivers/media/platform/mxc/capture/Kconfig
  74877. --- linux-3.14.17/drivers/media/platform/mxc/capture/Kconfig 1970-01-01 01:00:00.000000000 +0100
  74878. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/Kconfig 2014-09-11 18:06:02.250038968 +0200
  74879. @@ -0,0 +1,86 @@
  74880. +if VIDEO_MXC_CAPTURE
  74881. +
  74882. +menu "MXC Camera/V4L2 PRP Features support"
  74883. +config VIDEO_MXC_IPU_CAMERA
  74884. + bool
  74885. + depends on VIDEO_MXC_CAPTURE && MXC_IPU
  74886. + default y
  74887. +
  74888. +config VIDEO_MXC_CSI_CAMERA
  74889. + tristate "CSI camera support"
  74890. + depends on VIDEO_MXC_CAPTURE && VIDEO_V4L2
  74891. + ---help---
  74892. + This is the video4linux2 capture driver based on CSI module.
  74893. +
  74894. +config MXC_CAMERA_OV5640
  74895. + tristate "OmniVision ov5640 camera support"
  74896. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  74897. + ---help---
  74898. + If you plan to use the ov5640 Camera with your MXC system, say Y here.
  74899. +
  74900. +config MXC_CAMERA_OV5642
  74901. + tristate "OmniVision ov5642 camera support"
  74902. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  74903. + ---help---
  74904. + If you plan to use the ov5642 Camera with your MXC system, say Y here.
  74905. +
  74906. +config MXC_CAMERA_OV5640_MIPI
  74907. + tristate "OmniVision ov5640 camera support using mipi"
  74908. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  74909. + ---help---
  74910. + If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
  74911. +
  74912. +config MXC_TVIN_ADV7180
  74913. + tristate "Analog Device adv7180 TV Decoder Input support"
  74914. + depends on !VIDEO_MXC_EMMA_CAMERA && I2C
  74915. + ---help---
  74916. + If you plan to use the adv7180 video decoder with your MXC system, say Y here.
  74917. +
  74918. +choice
  74919. + prompt "Select Overlay Rounting"
  74920. + default MXC_IPU_DEVICE_QUEUE_SDC
  74921. + depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_SYNC_PANEL
  74922. +
  74923. +config MXC_IPU_DEVICE_QUEUE_SDC
  74924. + tristate "Queue ipu device for overlay library"
  74925. + depends on VIDEO_MXC_IPU_CAMERA
  74926. + ---help---
  74927. + Use case CSI->MEM->IPU DEVICE->SDC:
  74928. + Images from sensor will be frist recieved in memory,then
  74929. + queue to ipu device for processing if needed, and displaying
  74930. + it on synchronous display with SDC use case.
  74931. +
  74932. +config MXC_IPU_PRP_VF_SDC
  74933. + bool "Pre-Processor VF SDC library"
  74934. + depends on VIDEO_MXC_IPU_CAMERA
  74935. + ---help---
  74936. + Use case PRP_VF_SDC:
  74937. + Preprocessing image from smart sensor for viewfinder and
  74938. + displaying it on synchronous display with SDC use case.
  74939. + If SDC BG is selected, Rotation will not be supported.
  74940. + CSI -> IC (PRP VF) -> MEM
  74941. + MEM -> IC (ROT) -> MEM
  74942. + MEM -> SDC (FG/BG)
  74943. +
  74944. +endchoice
  74945. +
  74946. +config MXC_IPU_PRP_ENC
  74947. + tristate "Pre-processor Encoder library"
  74948. + depends on VIDEO_MXC_IPU_CAMERA
  74949. + default y
  74950. + ---help---
  74951. + Use case PRP_ENC:
  74952. + Preprocessing image from smart sensor for encoder.
  74953. + CSI -> IC (PRP ENC) -> MEM
  74954. +
  74955. +config MXC_IPU_CSI_ENC
  74956. + tristate "IPU CSI Encoder library"
  74957. + depends on VIDEO_MXC_IPU_CAMERA
  74958. + default y
  74959. + ---help---
  74960. + Use case IPU_CSI_ENC:
  74961. + Get raw image with CSI from smart sensor for encoder.
  74962. + CSI -> MEM
  74963. +endmenu
  74964. +
  74965. +endif
  74966. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/Makefile linux-imx6-3.14/drivers/media/platform/mxc/capture/Makefile
  74967. --- linux-3.14.17/drivers/media/platform/mxc/capture/Makefile 1970-01-01 01:00:00.000000000 +0100
  74968. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/Makefile 2014-09-11 18:06:02.250038968 +0200
  74969. @@ -0,0 +1,21 @@
  74970. +obj-$(CONFIG_VIDEO_MXC_CSI_CAMERA) += fsl_csi.o csi_v4l2_capture.o
  74971. +
  74972. +ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y)
  74973. + obj-$(CONFIG_VIDEO_MXC_CAPTURE) += mxc_v4l2_capture.o
  74974. + obj-$(CONFIG_MXC_IPU_PRP_VF_SDC) += ipu_prp_vf_sdc.o ipu_prp_vf_sdc_bg.o
  74975. + obj-$(CONFIG_MXC_IPU_DEVICE_QUEUE_SDC) += ipu_fg_overlay_sdc.o ipu_bg_overlay_sdc.o
  74976. + obj-$(CONFIG_MXC_IPU_PRP_ENC) += ipu_prp_enc.o ipu_still.o
  74977. + obj-$(CONFIG_MXC_IPU_CSI_ENC) += ipu_csi_enc.o ipu_still.o
  74978. +endif
  74979. +
  74980. +ov5640_camera-objs := ov5640.o
  74981. +obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera.o
  74982. +
  74983. +ov5642_camera-objs := ov5642.o
  74984. +obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
  74985. +
  74986. +ov5640_camera_mipi-objs := ov5640_mipi.o
  74987. +obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o
  74988. +
  74989. +adv7180_tvin-objs := adv7180.o
  74990. +obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
  74991. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c
  74992. --- linux-3.14.17/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c 1970-01-01 01:00:00.000000000 +0100
  74993. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.c 2014-09-11 18:06:02.254038983 +0200
  74994. @@ -0,0 +1,3102 @@
  74995. +/*
  74996. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  74997. + */
  74998. +
  74999. +/*
  75000. + * The code contained herein is licensed under the GNU General Public
  75001. + * License. You may obtain a copy of the GNU General Public License
  75002. + * Version 2 or later at the following locations:
  75003. + *
  75004. + * http://www.opensource.org/licenses/gpl-license.html
  75005. + * http://www.gnu.org/copyleft/gpl.html
  75006. + */
  75007. +
  75008. +/*!
  75009. + * @file drivers/media/video/mxc/capture/mxc_v4l2_capture.c
  75010. + *
  75011. + * @brief Mxc Video For Linux 2 driver
  75012. + *
  75013. + * @ingroup MXC_V4L2_CAPTURE
  75014. + */
  75015. +#include <linux/version.h>
  75016. +#include <linux/module.h>
  75017. +#include <linux/init.h>
  75018. +#include <linux/platform_device.h>
  75019. +#include <linux/fs.h>
  75020. +#include <linux/slab.h>
  75021. +#include <linux/ctype.h>
  75022. +#include <linux/clk.h>
  75023. +#include <linux/io.h>
  75024. +#include <linux/semaphore.h>
  75025. +#include <linux/pagemap.h>
  75026. +#include <linux/vmalloc.h>
  75027. +#include <linux/types.h>
  75028. +#include <linux/fb.h>
  75029. +#include <linux/dma-mapping.h>
  75030. +#include <linux/delay.h>
  75031. +#include <linux/mxcfb.h>
  75032. +#include <linux/of_device.h>
  75033. +#include <media/v4l2-chip-ident.h>
  75034. +#include <media/v4l2-ioctl.h>
  75035. +#include <media/v4l2-int-device.h>
  75036. +#include <linux/fsl_devices.h>
  75037. +#include "mxc_v4l2_capture.h"
  75038. +#include "ipu_prp_sw.h"
  75039. +
  75040. +#define init_MUTEX(sem) sema_init(sem, 1)
  75041. +
  75042. +static struct platform_device_id imx_v4l2_devtype[] = {
  75043. + {
  75044. + .name = "v4l2-capture-imx5",
  75045. + .driver_data = IMX5_V4L2,
  75046. + }, {
  75047. + .name = "v4l2-capture-imx6",
  75048. + .driver_data = IMX6_V4L2,
  75049. + }, {
  75050. + /* sentinel */
  75051. + }
  75052. +};
  75053. +MODULE_DEVICE_TABLE(platform, imx_v4l2_devtype);
  75054. +
  75055. +static const struct of_device_id mxc_v4l2_dt_ids[] = {
  75056. + {
  75057. + .compatible = "fsl,imx6q-v4l2-capture",
  75058. + .data = &imx_v4l2_devtype[IMX6_V4L2],
  75059. + }, {
  75060. + /* sentinel */
  75061. + }
  75062. +};
  75063. +MODULE_DEVICE_TABLE(of, mxc_v4l2_dt_ids);
  75064. +
  75065. +static int video_nr = -1;
  75066. +
  75067. +/*! This data is used for the output to the display. */
  75068. +#define MXC_V4L2_CAPTURE_NUM_OUTPUTS 6
  75069. +#define MXC_V4L2_CAPTURE_NUM_INPUTS 2
  75070. +static struct v4l2_output mxc_capture_outputs[MXC_V4L2_CAPTURE_NUM_OUTPUTS] = {
  75071. + {
  75072. + .index = 0,
  75073. + .name = "DISP3 BG",
  75074. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  75075. + .audioset = 0,
  75076. + .modulator = 0,
  75077. + .std = V4L2_STD_UNKNOWN,
  75078. + },
  75079. + {
  75080. + .index = 1,
  75081. + .name = "DISP3 BG - DI1",
  75082. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  75083. + .audioset = 0,
  75084. + .modulator = 0,
  75085. + .std = V4L2_STD_UNKNOWN,
  75086. + },
  75087. + {
  75088. + .index = 2,
  75089. + .name = "DISP3 FG",
  75090. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  75091. + .audioset = 0,
  75092. + .modulator = 0,
  75093. + .std = V4L2_STD_UNKNOWN,
  75094. + },
  75095. + {
  75096. + .index = 3,
  75097. + .name = "DISP4 BG",
  75098. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  75099. + .audioset = 0,
  75100. + .modulator = 0,
  75101. + .std = V4L2_STD_UNKNOWN,
  75102. + },
  75103. + {
  75104. + .index = 4,
  75105. + .name = "DISP4 BG - DI1",
  75106. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  75107. + .audioset = 0,
  75108. + .modulator = 0,
  75109. + .std = V4L2_STD_UNKNOWN,
  75110. + },
  75111. + {
  75112. + .index = 5,
  75113. + .name = "DISP4 FG",
  75114. + .type = V4L2_OUTPUT_TYPE_ANALOG,
  75115. + .audioset = 0,
  75116. + .modulator = 0,
  75117. + .std = V4L2_STD_UNKNOWN,
  75118. + },
  75119. +};
  75120. +
  75121. +static struct v4l2_input mxc_capture_inputs[MXC_V4L2_CAPTURE_NUM_INPUTS] = {
  75122. + {
  75123. + .index = 0,
  75124. + .name = "CSI IC MEM",
  75125. + .type = V4L2_INPUT_TYPE_CAMERA,
  75126. + .audioset = 0,
  75127. + .tuner = 0,
  75128. + .std = V4L2_STD_UNKNOWN,
  75129. + .status = 0,
  75130. + },
  75131. + {
  75132. + .index = 1,
  75133. + .name = "CSI MEM",
  75134. + .type = V4L2_INPUT_TYPE_CAMERA,
  75135. + .audioset = 0,
  75136. + .tuner = 0,
  75137. + .std = V4L2_STD_UNKNOWN,
  75138. + .status = V4L2_IN_ST_NO_POWER,
  75139. + },
  75140. +};
  75141. +
  75142. +/*! List of TV input video formats supported. The video formats is corresponding
  75143. + * to the v4l2_id in video_fmt_t.
  75144. + * Currently, only PAL and NTSC is supported. Needs to be expanded in the
  75145. + * future.
  75146. + */
  75147. +typedef enum {
  75148. + TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
  75149. + TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */
  75150. + TV_NOT_LOCKED, /*!< Not locked on a signal. */
  75151. +} video_fmt_idx;
  75152. +
  75153. +/*! Number of video standards supported (including 'not locked' signal). */
  75154. +#define TV_STD_MAX (TV_NOT_LOCKED + 1)
  75155. +
  75156. +/*! Video format structure. */
  75157. +typedef struct {
  75158. + int v4l2_id; /*!< Video for linux ID. */
  75159. + char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
  75160. + u16 raw_width; /*!< Raw width. */
  75161. + u16 raw_height; /*!< Raw height. */
  75162. + u16 active_width; /*!< Active width. */
  75163. + u16 active_height; /*!< Active height. */
  75164. + u16 active_top; /*!< Active top. */
  75165. + u16 active_left; /*!< Active left. */
  75166. +} video_fmt_t;
  75167. +
  75168. +/*!
  75169. + * Description of video formats supported.
  75170. + *
  75171. + * PAL: raw=720x625, active=720x576.
  75172. + * NTSC: raw=720x525, active=720x480.
  75173. + */
  75174. +static video_fmt_t video_fmts[] = {
  75175. + { /*! NTSC */
  75176. + .v4l2_id = V4L2_STD_NTSC,
  75177. + .name = "NTSC",
  75178. + .raw_width = 720, /* SENS_FRM_WIDTH */
  75179. + .raw_height = 525, /* SENS_FRM_HEIGHT */
  75180. + .active_width = 720, /* ACT_FRM_WIDTH */
  75181. + .active_height = 480, /* ACT_FRM_HEIGHT */
  75182. + .active_top = 13,
  75183. + .active_left = 0,
  75184. + },
  75185. + { /*! (B, G, H, I, N) PAL */
  75186. + .v4l2_id = V4L2_STD_PAL,
  75187. + .name = "PAL",
  75188. + .raw_width = 720,
  75189. + .raw_height = 625,
  75190. + .active_width = 720,
  75191. + .active_height = 576,
  75192. + .active_top = 0,
  75193. + .active_left = 0,
  75194. + },
  75195. + { /*! Unlocked standard */
  75196. + .v4l2_id = V4L2_STD_ALL,
  75197. + .name = "Autodetect",
  75198. + .raw_width = 720,
  75199. + .raw_height = 625,
  75200. + .active_width = 720,
  75201. + .active_height = 576,
  75202. + .active_top = 0,
  75203. + .active_left = 0,
  75204. + },
  75205. +};
  75206. +
  75207. +/*!* Standard index of TV. */
  75208. +static video_fmt_idx video_index = TV_NOT_LOCKED;
  75209. +
  75210. +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave);
  75211. +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave);
  75212. +static int start_preview(cam_data *cam);
  75213. +static int stop_preview(cam_data *cam);
  75214. +
  75215. +/*! Information about this driver. */
  75216. +static struct v4l2_int_master mxc_v4l2_master = {
  75217. + .attach = mxc_v4l2_master_attach,
  75218. + .detach = mxc_v4l2_master_detach,
  75219. +};
  75220. +
  75221. +/***************************************************************************
  75222. + * Functions for handling Frame buffers.
  75223. + **************************************************************************/
  75224. +
  75225. +/*!
  75226. + * Free frame buffers
  75227. + *
  75228. + * @param cam Structure cam_data *
  75229. + *
  75230. + * @return status 0 success.
  75231. + */
  75232. +static int mxc_free_frame_buf(cam_data *cam)
  75233. +{
  75234. + int i;
  75235. +
  75236. + pr_debug("MVC: In mxc_free_frame_buf\n");
  75237. +
  75238. + for (i = 0; i < FRAME_NUM; i++) {
  75239. + if (cam->frame[i].vaddress != 0) {
  75240. + dma_free_coherent(0, cam->frame[i].buffer.length,
  75241. + cam->frame[i].vaddress,
  75242. + cam->frame[i].paddress);
  75243. + cam->frame[i].vaddress = 0;
  75244. + }
  75245. + }
  75246. +
  75247. + return 0;
  75248. +}
  75249. +
  75250. +/*!
  75251. + * Allocate frame buffers
  75252. + *
  75253. + * @param cam Structure cam_data*
  75254. + * @param count int number of buffer need to allocated
  75255. + *
  75256. + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
  75257. + */
  75258. +static int mxc_allocate_frame_buf(cam_data *cam, int count)
  75259. +{
  75260. + int i;
  75261. +
  75262. + pr_debug("In MVC:mxc_allocate_frame_buf - size=%d\n",
  75263. + cam->v2f.fmt.pix.sizeimage);
  75264. +
  75265. + for (i = 0; i < count; i++) {
  75266. + cam->frame[i].vaddress =
  75267. + dma_alloc_coherent(0,
  75268. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  75269. + &cam->frame[i].paddress,
  75270. + GFP_DMA | GFP_KERNEL);
  75271. + if (cam->frame[i].vaddress == 0) {
  75272. + pr_err("ERROR: v4l2 capture: "
  75273. + "mxc_allocate_frame_buf failed.\n");
  75274. + mxc_free_frame_buf(cam);
  75275. + return -ENOBUFS;
  75276. + }
  75277. + cam->frame[i].buffer.index = i;
  75278. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  75279. + cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  75280. + cam->frame[i].buffer.length =
  75281. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
  75282. + cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
  75283. + cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
  75284. + cam->frame[i].index = i;
  75285. + }
  75286. +
  75287. + return 0;
  75288. +}
  75289. +
  75290. +/*!
  75291. + * Free frame buffers status
  75292. + *
  75293. + * @param cam Structure cam_data *
  75294. + *
  75295. + * @return none
  75296. + */
  75297. +static void mxc_free_frames(cam_data *cam)
  75298. +{
  75299. + int i;
  75300. +
  75301. + pr_debug("In MVC:mxc_free_frames\n");
  75302. +
  75303. + for (i = 0; i < FRAME_NUM; i++)
  75304. + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  75305. +
  75306. + cam->enc_counter = 0;
  75307. + INIT_LIST_HEAD(&cam->ready_q);
  75308. + INIT_LIST_HEAD(&cam->working_q);
  75309. + INIT_LIST_HEAD(&cam->done_q);
  75310. +}
  75311. +
  75312. +/*!
  75313. + * Return the buffer status
  75314. + *
  75315. + * @param cam Structure cam_data *
  75316. + * @param buf Structure v4l2_buffer *
  75317. + *
  75318. + * @return status 0 success, EINVAL failed.
  75319. + */
  75320. +static int mxc_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
  75321. +{
  75322. + pr_debug("In MVC:mxc_v4l2_buffer_status\n");
  75323. +
  75324. + if (buf->index < 0 || buf->index >= FRAME_NUM) {
  75325. + pr_err("ERROR: v4l2 capture: mxc_v4l2_buffer_status buffers "
  75326. + "not allocated\n");
  75327. + return -EINVAL;
  75328. + }
  75329. +
  75330. + memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
  75331. + return 0;
  75332. +}
  75333. +
  75334. +static int mxc_v4l2_release_bufs(cam_data *cam)
  75335. +{
  75336. + pr_debug("In MVC:mxc_v4l2_release_bufs\n");
  75337. + return 0;
  75338. +}
  75339. +
  75340. +static int mxc_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
  75341. +{
  75342. + pr_debug("In MVC:mxc_v4l2_prepare_bufs\n");
  75343. +
  75344. + if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
  75345. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage)) {
  75346. + pr_err("ERROR: v4l2 capture: mxc_v4l2_prepare_bufs buffers "
  75347. + "not allocated,index=%d, length=%d\n", buf->index,
  75348. + buf->length);
  75349. + return -EINVAL;
  75350. + }
  75351. +
  75352. + cam->frame[buf->index].buffer.index = buf->index;
  75353. + cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
  75354. + cam->frame[buf->index].buffer.length = buf->length;
  75355. + cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
  75356. + = buf->m.offset;
  75357. + cam->frame[buf->index].buffer.type = buf->type;
  75358. + cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
  75359. + cam->frame[buf->index].index = buf->index;
  75360. +
  75361. + return 0;
  75362. +}
  75363. +
  75364. +/***************************************************************************
  75365. + * Functions for handling the video stream.
  75366. + **************************************************************************/
  75367. +
  75368. +/*!
  75369. + * Indicates whether the palette is supported.
  75370. + *
  75371. + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
  75372. + *
  75373. + * @return 0 if failed
  75374. + */
  75375. +static inline int valid_mode(u32 palette)
  75376. +{
  75377. + return ((palette == V4L2_PIX_FMT_RGB565) ||
  75378. + (palette == V4L2_PIX_FMT_BGR24) ||
  75379. + (palette == V4L2_PIX_FMT_RGB24) ||
  75380. + (palette == V4L2_PIX_FMT_BGR32) ||
  75381. + (palette == V4L2_PIX_FMT_RGB32) ||
  75382. + (palette == V4L2_PIX_FMT_YUV422P) ||
  75383. + (palette == V4L2_PIX_FMT_UYVY) ||
  75384. + (palette == V4L2_PIX_FMT_YUYV) ||
  75385. + (palette == V4L2_PIX_FMT_YUV420) ||
  75386. + (palette == V4L2_PIX_FMT_YVU420) ||
  75387. + (palette == V4L2_PIX_FMT_NV12));
  75388. +}
  75389. +
  75390. +/*!
  75391. + * Start the encoder job
  75392. + *
  75393. + * @param cam structure cam_data *
  75394. + *
  75395. + * @return status 0 Success
  75396. + */
  75397. +static int mxc_streamon(cam_data *cam)
  75398. +{
  75399. + struct mxc_v4l_frame *frame;
  75400. + unsigned long lock_flags;
  75401. + int err = 0;
  75402. +
  75403. + pr_debug("In MVC:mxc_streamon\n");
  75404. +
  75405. + if (NULL == cam) {
  75406. + pr_err("ERROR! cam parameter is NULL\n");
  75407. + return -1;
  75408. + }
  75409. +
  75410. + if (cam->capture_on) {
  75411. + pr_err("ERROR: v4l2 capture: Capture stream has been turned "
  75412. + " on\n");
  75413. + return -1;
  75414. + }
  75415. +
  75416. + if (list_empty(&cam->ready_q)) {
  75417. + pr_err("ERROR: v4l2 capture: mxc_streamon buffer has not been "
  75418. + "queued yet\n");
  75419. + return -EINVAL;
  75420. + }
  75421. + if (cam->enc_update_eba &&
  75422. + cam->ready_q.prev == cam->ready_q.next) {
  75423. + pr_err("ERROR: v4l2 capture: mxc_streamon buffer need "
  75424. + "ping pong at least two buffers\n");
  75425. + return -EINVAL;
  75426. + }
  75427. +
  75428. + cam->capture_pid = current->pid;
  75429. +
  75430. + if (cam->overlay_on == true)
  75431. + stop_preview(cam);
  75432. +
  75433. + if (cam->enc_enable) {
  75434. + err = cam->enc_enable(cam);
  75435. + if (err != 0)
  75436. + return err;
  75437. + }
  75438. +
  75439. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  75440. + cam->ping_pong_csi = 0;
  75441. + cam->local_buf_num = 0;
  75442. + if (cam->enc_update_eba) {
  75443. + frame =
  75444. + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  75445. + list_del(cam->ready_q.next);
  75446. + list_add_tail(&frame->queue, &cam->working_q);
  75447. + frame->ipu_buf_num = cam->ping_pong_csi;
  75448. + err = cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
  75449. + &cam->ping_pong_csi);
  75450. +
  75451. + frame =
  75452. + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
  75453. + list_del(cam->ready_q.next);
  75454. + list_add_tail(&frame->queue, &cam->working_q);
  75455. + frame->ipu_buf_num = cam->ping_pong_csi;
  75456. + err |= cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
  75457. + &cam->ping_pong_csi);
  75458. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  75459. + } else {
  75460. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  75461. + return -EINVAL;
  75462. + }
  75463. +
  75464. + if (cam->overlay_on == true)
  75465. + start_preview(cam);
  75466. +
  75467. + if (cam->enc_enable_csi) {
  75468. + err = cam->enc_enable_csi(cam);
  75469. + if (err != 0)
  75470. + return err;
  75471. + }
  75472. +
  75473. + cam->capture_on = true;
  75474. +
  75475. + return err;
  75476. +}
  75477. +
  75478. +/*!
  75479. + * Shut down the encoder job
  75480. + *
  75481. + * @param cam structure cam_data *
  75482. + *
  75483. + * @return status 0 Success
  75484. + */
  75485. +static int mxc_streamoff(cam_data *cam)
  75486. +{
  75487. + int err = 0;
  75488. +
  75489. + pr_debug("In MVC:mxc_streamoff\n");
  75490. +
  75491. + if (cam->capture_on == false)
  75492. + return 0;
  75493. +
  75494. + /* For both CSI--MEM and CSI--IC--MEM
  75495. + * 1. wait for idmac eof
  75496. + * 2. disable csi first
  75497. + * 3. disable idmac
  75498. + * 4. disable smfc (CSI--MEM channel)
  75499. + */
  75500. + if (mxc_capture_inputs[cam->current_input].name != NULL) {
  75501. + if (cam->enc_disable_csi) {
  75502. + err = cam->enc_disable_csi(cam);
  75503. + if (err != 0)
  75504. + return err;
  75505. + }
  75506. + if (cam->enc_disable) {
  75507. + err = cam->enc_disable(cam);
  75508. + if (err != 0)
  75509. + return err;
  75510. + }
  75511. + }
  75512. +
  75513. + mxc_free_frames(cam);
  75514. + mxc_capture_inputs[cam->current_input].status |= V4L2_IN_ST_NO_POWER;
  75515. + cam->capture_on = false;
  75516. + return err;
  75517. +}
  75518. +
  75519. +/*!
  75520. + * Valid and adjust the overlay window size, position
  75521. + *
  75522. + * @param cam structure cam_data *
  75523. + * @param win struct v4l2_window *
  75524. + *
  75525. + * @return 0
  75526. + */
  75527. +static int verify_preview(cam_data *cam, struct v4l2_window *win)
  75528. +{
  75529. + int i = 0, width_bound = 0, height_bound = 0;
  75530. + int *width, *height;
  75531. + unsigned int ipu_ch = CHAN_NONE;
  75532. + struct fb_info *bg_fbi = NULL, *fbi = NULL;
  75533. + bool foregound_fb = false;
  75534. + mm_segment_t old_fs;
  75535. +
  75536. + pr_debug("In MVC: verify_preview\n");
  75537. +
  75538. + do {
  75539. + fbi = (struct fb_info *)registered_fb[i];
  75540. + if (fbi == NULL) {
  75541. + pr_err("ERROR: verify_preview frame buffer NULL.\n");
  75542. + return -1;
  75543. + }
  75544. +
  75545. + /* Which DI supports 2 layers? */
  75546. + if (((strncmp(fbi->fix.id, "DISP3 BG", 8) == 0) &&
  75547. + (cam->output < 3)) ||
  75548. + ((strncmp(fbi->fix.id, "DISP4 BG", 8) == 0) &&
  75549. + (cam->output >= 3))) {
  75550. + if (fbi->fbops->fb_ioctl) {
  75551. + old_fs = get_fs();
  75552. + set_fs(KERNEL_DS);
  75553. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
  75554. + (unsigned long)&ipu_ch);
  75555. + set_fs(old_fs);
  75556. + }
  75557. + if (ipu_ch == MEM_BG_SYNC) {
  75558. + bg_fbi = fbi;
  75559. + pr_debug("Found background frame buffer.\n");
  75560. + }
  75561. + }
  75562. +
  75563. + /* Found the frame buffer to preview on. */
  75564. + if (strcmp(fbi->fix.id,
  75565. + mxc_capture_outputs[cam->output].name) == 0) {
  75566. + if (((strcmp(fbi->fix.id, "DISP3 FG") == 0) &&
  75567. + (cam->output < 3)) ||
  75568. + ((strcmp(fbi->fix.id, "DISP4 FG") == 0) &&
  75569. + (cam->output >= 3)))
  75570. + foregound_fb = true;
  75571. +
  75572. + cam->overlay_fb = fbi;
  75573. + break;
  75574. + }
  75575. + } while (++i < FB_MAX);
  75576. +
  75577. + if (foregound_fb) {
  75578. + width_bound = bg_fbi->var.xres;
  75579. + height_bound = bg_fbi->var.yres;
  75580. +
  75581. + if (win->w.width + win->w.left > bg_fbi->var.xres ||
  75582. + win->w.height + win->w.top > bg_fbi->var.yres) {
  75583. + pr_err("ERROR: FG window position exceeds.\n");
  75584. + return -1;
  75585. + }
  75586. + } else {
  75587. + /* 4 bytes alignment for BG */
  75588. + width_bound = cam->overlay_fb->var.xres;
  75589. + height_bound = cam->overlay_fb->var.yres;
  75590. +
  75591. + if (cam->overlay_fb->var.bits_per_pixel == 24)
  75592. + win->w.left -= win->w.left % 4;
  75593. + else if (cam->overlay_fb->var.bits_per_pixel == 16)
  75594. + win->w.left -= win->w.left % 2;
  75595. +
  75596. + if (win->w.width + win->w.left > cam->overlay_fb->var.xres)
  75597. + win->w.width = cam->overlay_fb->var.xres - win->w.left;
  75598. + if (win->w.height + win->w.top > cam->overlay_fb->var.yres)
  75599. + win->w.height = cam->overlay_fb->var.yres - win->w.top;
  75600. + }
  75601. +
  75602. + /* stride line limitation */
  75603. + win->w.height -= win->w.height % 8;
  75604. + win->w.width -= win->w.width % 8;
  75605. +
  75606. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  75607. + height = &win->w.width;
  75608. + width = &win->w.height;
  75609. + } else {
  75610. + width = &win->w.width;
  75611. + height = &win->w.height;
  75612. + }
  75613. +
  75614. + if (*width == 0 || *height == 0) {
  75615. + pr_err("ERROR: v4l2 capture: width or height"
  75616. + " too small.\n");
  75617. + return -EINVAL;
  75618. + }
  75619. +
  75620. + if ((cam->crop_bounds.width / *width > 8) ||
  75621. + ((cam->crop_bounds.width / *width == 8) &&
  75622. + (cam->crop_bounds.width % *width))) {
  75623. + *width = cam->crop_bounds.width / 8;
  75624. + if (*width % 8)
  75625. + *width += 8 - *width % 8;
  75626. + if (*width + win->w.left > width_bound) {
  75627. + pr_err("ERROR: v4l2 capture: width exceeds "
  75628. + "resize limit.\n");
  75629. + return -1;
  75630. + }
  75631. + pr_err("ERROR: v4l2 capture: width exceeds limit. "
  75632. + "Resize to %d.\n",
  75633. + *width);
  75634. + }
  75635. +
  75636. + if ((cam->crop_bounds.height / *height > 8) ||
  75637. + ((cam->crop_bounds.height / *height == 8) &&
  75638. + (cam->crop_bounds.height % *height))) {
  75639. + *height = cam->crop_bounds.height / 8;
  75640. + if (*height % 8)
  75641. + *height += 8 - *height % 8;
  75642. + if (*height + win->w.top > height_bound) {
  75643. + pr_err("ERROR: v4l2 capture: height exceeds "
  75644. + "resize limit.\n");
  75645. + return -1;
  75646. + }
  75647. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  75648. + "resize to %d.\n",
  75649. + *height);
  75650. + }
  75651. +
  75652. + return 0;
  75653. +}
  75654. +
  75655. +/*!
  75656. + * start the viewfinder job
  75657. + *
  75658. + * @param cam structure cam_data *
  75659. + *
  75660. + * @return status 0 Success
  75661. + */
  75662. +static int start_preview(cam_data *cam)
  75663. +{
  75664. + int err = 0;
  75665. +
  75666. + pr_debug("MVC: start_preview\n");
  75667. +
  75668. + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
  75669. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  75670. + err = prp_vf_sdc_select(cam);
  75671. + #else
  75672. + err = foreground_sdc_select(cam);
  75673. + #endif
  75674. + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
  75675. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  75676. + err = prp_vf_sdc_select_bg(cam);
  75677. + #else
  75678. + err = bg_overlay_sdc_select(cam);
  75679. + #endif
  75680. + if (err != 0)
  75681. + return err;
  75682. +
  75683. + if (cam->vf_start_sdc) {
  75684. + err = cam->vf_start_sdc(cam);
  75685. + if (err != 0)
  75686. + return err;
  75687. + }
  75688. +
  75689. + if (cam->vf_enable_csi)
  75690. + err = cam->vf_enable_csi(cam);
  75691. +
  75692. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  75693. + __func__,
  75694. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  75695. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  75696. + __func__,
  75697. + cam->crop_bounds.width, cam->crop_bounds.height);
  75698. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  75699. + __func__,
  75700. + cam->crop_defrect.width, cam->crop_defrect.height);
  75701. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  75702. + __func__,
  75703. + cam->crop_current.width, cam->crop_current.height);
  75704. +
  75705. + return err;
  75706. +}
  75707. +
  75708. +/*!
  75709. + * shut down the viewfinder job
  75710. + *
  75711. + * @param cam structure cam_data *
  75712. + *
  75713. + * @return status 0 Success
  75714. + */
  75715. +static int stop_preview(cam_data *cam)
  75716. +{
  75717. + int err = 0;
  75718. +
  75719. + if (cam->vf_disable_csi) {
  75720. + err = cam->vf_disable_csi(cam);
  75721. + if (err != 0)
  75722. + return err;
  75723. + }
  75724. +
  75725. + if (cam->vf_stop_sdc) {
  75726. + err = cam->vf_stop_sdc(cam);
  75727. + if (err != 0)
  75728. + return err;
  75729. + }
  75730. +
  75731. + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
  75732. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  75733. + err = prp_vf_sdc_deselect(cam);
  75734. + #else
  75735. + err = foreground_sdc_deselect(cam);
  75736. + #endif
  75737. + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
  75738. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  75739. + err = prp_vf_sdc_deselect_bg(cam);
  75740. + #else
  75741. + err = bg_overlay_sdc_deselect(cam);
  75742. + #endif
  75743. +
  75744. + return err;
  75745. +}
  75746. +
  75747. +/***************************************************************************
  75748. + * VIDIOC Functions.
  75749. + **************************************************************************/
  75750. +
  75751. +/*!
  75752. + * V4L2 - mxc_v4l2_g_fmt function
  75753. + *
  75754. + * @param cam structure cam_data *
  75755. + *
  75756. + * @param f structure v4l2_format *
  75757. + *
  75758. + * @return status 0 success, EINVAL failed
  75759. + */
  75760. +static int mxc_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
  75761. +{
  75762. + int retval = 0;
  75763. +
  75764. + pr_debug("In MVC: mxc_v4l2_g_fmt type=%d\n", f->type);
  75765. +
  75766. + switch (f->type) {
  75767. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  75768. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  75769. + f->fmt.pix = cam->v2f.fmt.pix;
  75770. + break;
  75771. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  75772. + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  75773. + f->fmt.win = cam->win;
  75774. + break;
  75775. + default:
  75776. + pr_debug(" type is invalid\n");
  75777. + retval = -EINVAL;
  75778. + }
  75779. +
  75780. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  75781. + __func__,
  75782. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  75783. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  75784. + __func__,
  75785. + cam->crop_bounds.width, cam->crop_bounds.height);
  75786. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  75787. + __func__,
  75788. + cam->crop_defrect.width, cam->crop_defrect.height);
  75789. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  75790. + __func__,
  75791. + cam->crop_current.width, cam->crop_current.height);
  75792. +
  75793. + return retval;
  75794. +}
  75795. +
  75796. +/*!
  75797. + * V4L2 - mxc_v4l2_s_fmt function
  75798. + *
  75799. + * @param cam structure cam_data *
  75800. + *
  75801. + * @param f structure v4l2_format *
  75802. + *
  75803. + * @return status 0 success, EINVAL failed
  75804. + */
  75805. +static int mxc_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
  75806. +{
  75807. + int retval = 0;
  75808. + int size = 0;
  75809. + int bytesperline = 0;
  75810. + int *width, *height;
  75811. +
  75812. + pr_debug("In MVC: mxc_v4l2_s_fmt\n");
  75813. +
  75814. + switch (f->type) {
  75815. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  75816. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
  75817. + if (!valid_mode(f->fmt.pix.pixelformat)) {
  75818. + pr_err("ERROR: v4l2 capture: mxc_v4l2_s_fmt: format "
  75819. + "not supported\n");
  75820. + return -EINVAL;
  75821. + }
  75822. +
  75823. + /*
  75824. + * Force the capture window resolution to be crop bounds
  75825. + * for CSI MEM input mode.
  75826. + */
  75827. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  75828. + "CSI MEM") == 0) {
  75829. + f->fmt.pix.width = cam->crop_current.width;
  75830. + f->fmt.pix.height = cam->crop_current.height;
  75831. + }
  75832. +
  75833. + if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
  75834. + height = &f->fmt.pix.width;
  75835. + width = &f->fmt.pix.height;
  75836. + } else {
  75837. + width = &f->fmt.pix.width;
  75838. + height = &f->fmt.pix.height;
  75839. + }
  75840. +
  75841. + /* stride line limitation */
  75842. + *width -= *width % 8;
  75843. + *height -= *height % 8;
  75844. +
  75845. + if (*width == 0 || *height == 0) {
  75846. + pr_err("ERROR: v4l2 capture: width or height"
  75847. + " too small.\n");
  75848. + return -EINVAL;
  75849. + }
  75850. +
  75851. + if ((cam->crop_current.width / *width > 8) ||
  75852. + ((cam->crop_current.width / *width == 8) &&
  75853. + (cam->crop_current.width % *width))) {
  75854. + *width = cam->crop_current.width / 8;
  75855. + if (*width % 8)
  75856. + *width += 8 - *width % 8;
  75857. + pr_err("ERROR: v4l2 capture: width exceeds limit "
  75858. + "resize to %d.\n",
  75859. + *width);
  75860. + }
  75861. +
  75862. + if ((cam->crop_current.height / *height > 8) ||
  75863. + ((cam->crop_current.height / *height == 8) &&
  75864. + (cam->crop_current.height % *height))) {
  75865. + *height = cam->crop_current.height / 8;
  75866. + if (*height % 8)
  75867. + *height += 8 - *height % 8;
  75868. + pr_err("ERROR: v4l2 capture: height exceeds limit "
  75869. + "resize to %d.\n",
  75870. + *height);
  75871. + }
  75872. +
  75873. + switch (f->fmt.pix.pixelformat) {
  75874. + case V4L2_PIX_FMT_RGB565:
  75875. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  75876. + bytesperline = f->fmt.pix.width * 2;
  75877. + break;
  75878. + case V4L2_PIX_FMT_BGR24:
  75879. + size = f->fmt.pix.width * f->fmt.pix.height * 3;
  75880. + bytesperline = f->fmt.pix.width * 3;
  75881. + break;
  75882. + case V4L2_PIX_FMT_RGB24:
  75883. + size = f->fmt.pix.width * f->fmt.pix.height * 3;
  75884. + bytesperline = f->fmt.pix.width * 3;
  75885. + break;
  75886. + case V4L2_PIX_FMT_BGR32:
  75887. + size = f->fmt.pix.width * f->fmt.pix.height * 4;
  75888. + bytesperline = f->fmt.pix.width * 4;
  75889. + break;
  75890. + case V4L2_PIX_FMT_RGB32:
  75891. + size = f->fmt.pix.width * f->fmt.pix.height * 4;
  75892. + bytesperline = f->fmt.pix.width * 4;
  75893. + break;
  75894. + case V4L2_PIX_FMT_YUV422P:
  75895. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  75896. + bytesperline = f->fmt.pix.width;
  75897. + break;
  75898. + case V4L2_PIX_FMT_UYVY:
  75899. + case V4L2_PIX_FMT_YUYV:
  75900. + size = f->fmt.pix.width * f->fmt.pix.height * 2;
  75901. + bytesperline = f->fmt.pix.width * 2;
  75902. + break;
  75903. + case V4L2_PIX_FMT_YUV420:
  75904. + case V4L2_PIX_FMT_YVU420:
  75905. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  75906. + bytesperline = f->fmt.pix.width;
  75907. + break;
  75908. + case V4L2_PIX_FMT_NV12:
  75909. + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
  75910. + bytesperline = f->fmt.pix.width;
  75911. + break;
  75912. + default:
  75913. + break;
  75914. + }
  75915. +
  75916. + if (f->fmt.pix.bytesperline < bytesperline)
  75917. + f->fmt.pix.bytesperline = bytesperline;
  75918. + else
  75919. + bytesperline = f->fmt.pix.bytesperline;
  75920. +
  75921. + if (f->fmt.pix.sizeimage < size)
  75922. + f->fmt.pix.sizeimage = size;
  75923. + else
  75924. + size = f->fmt.pix.sizeimage;
  75925. +
  75926. + cam->v2f.fmt.pix = f->fmt.pix;
  75927. +
  75928. + if (cam->v2f.fmt.pix.priv != 0) {
  75929. + if (copy_from_user(&cam->offset,
  75930. + (void *)cam->v2f.fmt.pix.priv,
  75931. + sizeof(cam->offset))) {
  75932. + retval = -EFAULT;
  75933. + break;
  75934. + }
  75935. + }
  75936. + break;
  75937. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  75938. + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
  75939. + retval = verify_preview(cam, &f->fmt.win);
  75940. + cam->win = f->fmt.win;
  75941. + break;
  75942. + default:
  75943. + retval = -EINVAL;
  75944. + }
  75945. +
  75946. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  75947. + __func__,
  75948. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  75949. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  75950. + __func__,
  75951. + cam->crop_bounds.width, cam->crop_bounds.height);
  75952. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  75953. + __func__,
  75954. + cam->crop_defrect.width, cam->crop_defrect.height);
  75955. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  75956. + __func__,
  75957. + cam->crop_current.width, cam->crop_current.height);
  75958. +
  75959. + return retval;
  75960. +}
  75961. +
  75962. +/*!
  75963. + * get control param
  75964. + *
  75965. + * @param cam structure cam_data *
  75966. + *
  75967. + * @param c structure v4l2_control *
  75968. + *
  75969. + * @return status 0 success, EINVAL failed
  75970. + */
  75971. +static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
  75972. +{
  75973. + int status = 0;
  75974. +
  75975. + pr_debug("In MVC:mxc_v4l2_g_ctrl\n");
  75976. +
  75977. + /* probably don't need to store the values that can be retrieved,
  75978. + * locally, but they are for now. */
  75979. + switch (c->id) {
  75980. + case V4L2_CID_HFLIP:
  75981. + /* This is handled in the ipu. */
  75982. + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
  75983. + c->value = 1;
  75984. + break;
  75985. + case V4L2_CID_VFLIP:
  75986. + /* This is handled in the ipu. */
  75987. + if (cam->rotation == IPU_ROTATE_VERT_FLIP)
  75988. + c->value = 1;
  75989. + break;
  75990. + case V4L2_CID_MXC_ROT:
  75991. + /* This is handled in the ipu. */
  75992. + c->value = cam->rotation;
  75993. + break;
  75994. + case V4L2_CID_BRIGHTNESS:
  75995. + if (cam->sensor) {
  75996. + c->value = cam->bright;
  75997. + status = vidioc_int_g_ctrl(cam->sensor, c);
  75998. + cam->bright = c->value;
  75999. + } else {
  76000. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76001. + status = -ENODEV;
  76002. + }
  76003. + break;
  76004. + case V4L2_CID_HUE:
  76005. + if (cam->sensor) {
  76006. + c->value = cam->hue;
  76007. + status = vidioc_int_g_ctrl(cam->sensor, c);
  76008. + cam->hue = c->value;
  76009. + } else {
  76010. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76011. + status = -ENODEV;
  76012. + }
  76013. + break;
  76014. + case V4L2_CID_CONTRAST:
  76015. + if (cam->sensor) {
  76016. + c->value = cam->contrast;
  76017. + status = vidioc_int_g_ctrl(cam->sensor, c);
  76018. + cam->contrast = c->value;
  76019. + } else {
  76020. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76021. + status = -ENODEV;
  76022. + }
  76023. + break;
  76024. + case V4L2_CID_SATURATION:
  76025. + if (cam->sensor) {
  76026. + c->value = cam->saturation;
  76027. + status = vidioc_int_g_ctrl(cam->sensor, c);
  76028. + cam->saturation = c->value;
  76029. + } else {
  76030. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76031. + status = -ENODEV;
  76032. + }
  76033. + break;
  76034. + case V4L2_CID_RED_BALANCE:
  76035. + if (cam->sensor) {
  76036. + c->value = cam->red;
  76037. + status = vidioc_int_g_ctrl(cam->sensor, c);
  76038. + cam->red = c->value;
  76039. + } else {
  76040. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76041. + status = -ENODEV;
  76042. + }
  76043. + break;
  76044. + case V4L2_CID_BLUE_BALANCE:
  76045. + if (cam->sensor) {
  76046. + c->value = cam->blue;
  76047. + status = vidioc_int_g_ctrl(cam->sensor, c);
  76048. + cam->blue = c->value;
  76049. + } else {
  76050. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76051. + status = -ENODEV;
  76052. + }
  76053. + break;
  76054. + case V4L2_CID_BLACK_LEVEL:
  76055. + if (cam->sensor) {
  76056. + c->value = cam->ae_mode;
  76057. + status = vidioc_int_g_ctrl(cam->sensor, c);
  76058. + cam->ae_mode = c->value;
  76059. + } else {
  76060. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76061. + status = -ENODEV;
  76062. + }
  76063. + break;
  76064. + default:
  76065. + pr_err("ERROR: v4l2 capture: unsupported ioctrl!\n");
  76066. + }
  76067. +
  76068. + return status;
  76069. +}
  76070. +
  76071. +/*!
  76072. + * V4L2 - set_control function
  76073. + * V4L2_CID_PRIVATE_BASE is the extention for IPU preprocessing.
  76074. + * 0 for normal operation
  76075. + * 1 for vertical flip
  76076. + * 2 for horizontal flip
  76077. + * 3 for horizontal and vertical flip
  76078. + * 4 for 90 degree rotation
  76079. + * @param cam structure cam_data *
  76080. + *
  76081. + * @param c structure v4l2_control *
  76082. + *
  76083. + * @return status 0 success, EINVAL failed
  76084. + */
  76085. +static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
  76086. +{
  76087. + int i, ret = 0;
  76088. + int tmp_rotation = IPU_ROTATE_NONE;
  76089. + struct sensor_data *sensor_data;
  76090. +
  76091. + pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
  76092. +
  76093. + switch (c->id) {
  76094. + case V4L2_CID_HFLIP:
  76095. + /* This is done by the IPU */
  76096. + if (c->value == 1) {
  76097. + if ((cam->rotation != IPU_ROTATE_VERT_FLIP) &&
  76098. + (cam->rotation != IPU_ROTATE_180))
  76099. + cam->rotation = IPU_ROTATE_HORIZ_FLIP;
  76100. + else
  76101. + cam->rotation = IPU_ROTATE_180;
  76102. + } else {
  76103. + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
  76104. + cam->rotation = IPU_ROTATE_NONE;
  76105. + if (cam->rotation == IPU_ROTATE_180)
  76106. + cam->rotation = IPU_ROTATE_VERT_FLIP;
  76107. + }
  76108. + break;
  76109. + case V4L2_CID_VFLIP:
  76110. + /* This is done by the IPU */
  76111. + if (c->value == 1) {
  76112. + if ((cam->rotation != IPU_ROTATE_HORIZ_FLIP) &&
  76113. + (cam->rotation != IPU_ROTATE_180))
  76114. + cam->rotation = IPU_ROTATE_VERT_FLIP;
  76115. + else
  76116. + cam->rotation = IPU_ROTATE_180;
  76117. + } else {
  76118. + if (cam->rotation == IPU_ROTATE_VERT_FLIP)
  76119. + cam->rotation = IPU_ROTATE_NONE;
  76120. + if (cam->rotation == IPU_ROTATE_180)
  76121. + cam->rotation = IPU_ROTATE_HORIZ_FLIP;
  76122. + }
  76123. + break;
  76124. + case V4L2_CID_MXC_ROT:
  76125. + case V4L2_CID_MXC_VF_ROT:
  76126. + /* This is done by the IPU */
  76127. + switch (c->value) {
  76128. + case V4L2_MXC_ROTATE_NONE:
  76129. + tmp_rotation = IPU_ROTATE_NONE;
  76130. + break;
  76131. + case V4L2_MXC_ROTATE_VERT_FLIP:
  76132. + tmp_rotation = IPU_ROTATE_VERT_FLIP;
  76133. + break;
  76134. + case V4L2_MXC_ROTATE_HORIZ_FLIP:
  76135. + tmp_rotation = IPU_ROTATE_HORIZ_FLIP;
  76136. + break;
  76137. + case V4L2_MXC_ROTATE_180:
  76138. + tmp_rotation = IPU_ROTATE_180;
  76139. + break;
  76140. + case V4L2_MXC_ROTATE_90_RIGHT:
  76141. + tmp_rotation = IPU_ROTATE_90_RIGHT;
  76142. + break;
  76143. + case V4L2_MXC_ROTATE_90_RIGHT_VFLIP:
  76144. + tmp_rotation = IPU_ROTATE_90_RIGHT_VFLIP;
  76145. + break;
  76146. + case V4L2_MXC_ROTATE_90_RIGHT_HFLIP:
  76147. + tmp_rotation = IPU_ROTATE_90_RIGHT_HFLIP;
  76148. + break;
  76149. + case V4L2_MXC_ROTATE_90_LEFT:
  76150. + tmp_rotation = IPU_ROTATE_90_LEFT;
  76151. + break;
  76152. + default:
  76153. + ret = -EINVAL;
  76154. + }
  76155. + #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
  76156. + if (c->id == V4L2_CID_MXC_VF_ROT)
  76157. + cam->vf_rotation = tmp_rotation;
  76158. + else
  76159. + cam->rotation = tmp_rotation;
  76160. + #else
  76161. + cam->rotation = tmp_rotation;
  76162. + #endif
  76163. +
  76164. + break;
  76165. + case V4L2_CID_HUE:
  76166. + if (cam->sensor) {
  76167. + cam->hue = c->value;
  76168. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  76169. + } else {
  76170. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76171. + ret = -ENODEV;
  76172. + }
  76173. + break;
  76174. + case V4L2_CID_CONTRAST:
  76175. + if (cam->sensor) {
  76176. + cam->contrast = c->value;
  76177. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  76178. + } else {
  76179. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76180. + ret = -ENODEV;
  76181. + }
  76182. + break;
  76183. + case V4L2_CID_BRIGHTNESS:
  76184. + if (cam->sensor) {
  76185. + cam->bright = c->value;
  76186. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  76187. + } else {
  76188. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76189. + ret = -ENODEV;
  76190. + }
  76191. + break;
  76192. + case V4L2_CID_SATURATION:
  76193. + if (cam->sensor) {
  76194. + cam->saturation = c->value;
  76195. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  76196. + } else {
  76197. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76198. + ret = -ENODEV;
  76199. + }
  76200. + break;
  76201. + case V4L2_CID_RED_BALANCE:
  76202. + if (cam->sensor) {
  76203. + cam->red = c->value;
  76204. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  76205. + } else {
  76206. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76207. + ret = -ENODEV;
  76208. + }
  76209. + break;
  76210. + case V4L2_CID_BLUE_BALANCE:
  76211. + if (cam->sensor) {
  76212. + cam->blue = c->value;
  76213. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  76214. + } else {
  76215. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76216. + ret = -ENODEV;
  76217. + }
  76218. + break;
  76219. + case V4L2_CID_EXPOSURE:
  76220. + if (cam->sensor) {
  76221. + cam->ae_mode = c->value;
  76222. + ret = vidioc_int_s_ctrl(cam->sensor, c);
  76223. + } else {
  76224. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76225. + ret = -ENODEV;
  76226. + }
  76227. + break;
  76228. + case V4L2_CID_MXC_FLASH:
  76229. +#ifdef CONFIG_MXC_IPU_V1
  76230. + ipu_csi_flash_strobe(true);
  76231. +#endif
  76232. + break;
  76233. + case V4L2_CID_MXC_SWITCH_CAM:
  76234. + if (cam->sensor == cam->all_sensors[c->value])
  76235. + break;
  76236. +
  76237. + /* power down other cameraes before enable new one */
  76238. + for (i = 0; i < cam->sensor_index; i++) {
  76239. + if (i != c->value) {
  76240. + vidioc_int_dev_exit(cam->all_sensors[i]);
  76241. + vidioc_int_s_power(cam->all_sensors[i], 0);
  76242. + if (cam->mclk_on[cam->mclk_source]) {
  76243. + ipu_csi_enable_mclk_if(cam->ipu,
  76244. + CSI_MCLK_I2C,
  76245. + cam->mclk_source,
  76246. + false, false);
  76247. + cam->mclk_on[cam->mclk_source] =
  76248. + false;
  76249. + }
  76250. + }
  76251. + }
  76252. + sensor_data = cam->all_sensors[c->value]->priv;
  76253. + if (sensor_data->io_init)
  76254. + sensor_data->io_init();
  76255. + cam->sensor = cam->all_sensors[c->value];
  76256. + cam->mclk_source = sensor_data->mclk_source;
  76257. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  76258. + cam->mclk_source, true, true);
  76259. + cam->mclk_on[cam->mclk_source] = true;
  76260. + vidioc_int_s_power(cam->sensor, 1);
  76261. + vidioc_int_dev_init(cam->sensor);
  76262. + break;
  76263. + default:
  76264. + pr_debug(" default case\n");
  76265. + ret = -EINVAL;
  76266. + break;
  76267. + }
  76268. +
  76269. + return ret;
  76270. +}
  76271. +
  76272. +/*!
  76273. + * V4L2 - mxc_v4l2_s_param function
  76274. + * Allows setting of capturemode and frame rate.
  76275. + *
  76276. + * @param cam structure cam_data *
  76277. + * @param parm structure v4l2_streamparm *
  76278. + *
  76279. + * @return status 0 success, EINVAL failed
  76280. + */
  76281. +static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
  76282. +{
  76283. + struct v4l2_ifparm ifparm;
  76284. + struct v4l2_format cam_fmt;
  76285. + struct v4l2_streamparm currentparm;
  76286. + ipu_csi_signal_cfg_t csi_param;
  76287. + u32 current_fps, parm_fps;
  76288. + int err = 0;
  76289. +
  76290. + pr_debug("In mxc_v4l2_s_param\n");
  76291. +
  76292. + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  76293. + pr_err(KERN_ERR "mxc_v4l2_s_param invalid type\n");
  76294. + return -EINVAL;
  76295. + }
  76296. +
  76297. + /* Stop the viewfinder */
  76298. + if (cam->overlay_on == true)
  76299. + stop_preview(cam);
  76300. +
  76301. + currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  76302. +
  76303. + /* First check that this device can support the changes requested. */
  76304. + err = vidioc_int_g_parm(cam->sensor, &currentparm);
  76305. + if (err) {
  76306. + pr_err("%s: vidioc_int_g_parm returned an error %d\n",
  76307. + __func__, err);
  76308. + goto exit;
  76309. + }
  76310. +
  76311. + current_fps = currentparm.parm.capture.timeperframe.denominator
  76312. + / currentparm.parm.capture.timeperframe.numerator;
  76313. + parm_fps = parm->parm.capture.timeperframe.denominator
  76314. + / parm->parm.capture.timeperframe.numerator;
  76315. +
  76316. + pr_debug(" Current capabilities are %x\n",
  76317. + currentparm.parm.capture.capability);
  76318. + pr_debug(" Current capturemode is %d change to %d\n",
  76319. + currentparm.parm.capture.capturemode,
  76320. + parm->parm.capture.capturemode);
  76321. + pr_debug(" Current framerate is %d change to %d\n",
  76322. + current_fps, parm_fps);
  76323. +
  76324. + /* This will change any camera settings needed. */
  76325. + err = vidioc_int_s_parm(cam->sensor, parm);
  76326. + if (err) {
  76327. + pr_err("%s: vidioc_int_s_parm returned an error %d\n",
  76328. + __func__, err);
  76329. + goto exit;
  76330. + }
  76331. +
  76332. + /* If resolution changed, need to re-program the CSI */
  76333. + /* Get new values. */
  76334. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  76335. +
  76336. + csi_param.data_width = 0;
  76337. + csi_param.clk_mode = 0;
  76338. + csi_param.ext_vsync = 0;
  76339. + csi_param.Vsync_pol = 0;
  76340. + csi_param.Hsync_pol = 0;
  76341. + csi_param.pixclk_pol = 0;
  76342. + csi_param.data_pol = 0;
  76343. + csi_param.sens_clksrc = 0;
  76344. + csi_param.pack_tight = 0;
  76345. + csi_param.force_eof = 0;
  76346. + csi_param.data_en_pol = 0;
  76347. + csi_param.data_fmt = 0;
  76348. + csi_param.csi = cam->csi;
  76349. + csi_param.mclk = 0;
  76350. +
  76351. + pr_debug(" clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr);
  76352. + if (ifparm.u.bt656.clock_curr == 0)
  76353. + csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;
  76354. + else
  76355. + csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
  76356. +
  76357. + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
  76358. +
  76359. + if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) {
  76360. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  76361. + } else if (ifparm.u.bt656.mode
  76362. + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) {
  76363. + csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
  76364. + } else {
  76365. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  76366. + }
  76367. +
  76368. + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
  76369. + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
  76370. + csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct;
  76371. +
  76372. + /* if the capturemode changed, the size bounds will have changed. */
  76373. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  76374. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  76375. + pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
  76376. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  76377. +
  76378. + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
  76379. +
  76380. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  76381. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  76382. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  76383. +
  76384. + /*
  76385. + * Set the default current cropped resolution to be the same with
  76386. + * the cropping boundary(except for tvin module).
  76387. + */
  76388. + if (cam->device_type != 1) {
  76389. + cam->crop_current.width = cam->crop_bounds.width;
  76390. + cam->crop_current.height = cam->crop_bounds.height;
  76391. + }
  76392. +
  76393. + /* This essentially loses the data at the left and bottom of the image
  76394. + * giving a digital zoom image, if crop_current is less than the full
  76395. + * size of the image. */
  76396. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  76397. + cam->crop_current.height, cam->csi);
  76398. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  76399. + cam->crop_current.top,
  76400. + cam->csi);
  76401. + ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
  76402. + cam->crop_bounds.height,
  76403. + cam_fmt.fmt.pix.pixelformat, csi_param);
  76404. +
  76405. +
  76406. +exit:
  76407. + if (cam->overlay_on == true)
  76408. + start_preview(cam);
  76409. +
  76410. + return err;
  76411. +}
  76412. +
  76413. +/*!
  76414. + * V4L2 - mxc_v4l2_s_std function
  76415. + *
  76416. + * Sets the TV standard to be used.
  76417. + *
  76418. + * @param cam structure cam_data *
  76419. + * @param parm structure v4l2_streamparm *
  76420. + *
  76421. + * @return status 0 success, EINVAL failed
  76422. + */
  76423. +static int mxc_v4l2_s_std(cam_data *cam, v4l2_std_id e)
  76424. +{
  76425. + pr_debug("In mxc_v4l2_s_std %Lx\n", e);
  76426. +
  76427. + if (e == V4L2_STD_PAL) {
  76428. + pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL);
  76429. + cam->standard.id = V4L2_STD_PAL;
  76430. + video_index = TV_PAL;
  76431. + } else if (e == V4L2_STD_NTSC) {
  76432. + pr_debug(" Setting standard to NTSC %Lx\n",
  76433. + V4L2_STD_NTSC);
  76434. + /* Get rid of the white dot line in NTSC signal input */
  76435. + cam->standard.id = V4L2_STD_NTSC;
  76436. + video_index = TV_NTSC;
  76437. + } else {
  76438. + cam->standard.id = V4L2_STD_ALL;
  76439. + video_index = TV_NOT_LOCKED;
  76440. + pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n",
  76441. + e, V4L2_STD_PAL, V4L2_STD_NTSC);
  76442. + }
  76443. +
  76444. + cam->standard.index = video_index;
  76445. + strcpy(cam->standard.name, video_fmts[video_index].name);
  76446. + cam->crop_bounds.width = video_fmts[video_index].raw_width;
  76447. + cam->crop_bounds.height = video_fmts[video_index].raw_height;
  76448. + cam->crop_current.width = video_fmts[video_index].active_width;
  76449. + cam->crop_current.height = video_fmts[video_index].active_height;
  76450. + cam->crop_current.top = video_fmts[video_index].active_top;
  76451. + cam->crop_current.left = video_fmts[video_index].active_left;
  76452. +
  76453. + return 0;
  76454. +}
  76455. +
  76456. +/*!
  76457. + * V4L2 - mxc_v4l2_g_std function
  76458. + *
  76459. + * Gets the TV standard from the TV input device.
  76460. + *
  76461. + * @param cam structure cam_data *
  76462. + *
  76463. + * @param e structure v4l2_streamparm *
  76464. + *
  76465. + * @return status 0 success, EINVAL failed
  76466. + */
  76467. +static int mxc_v4l2_g_std(cam_data *cam, v4l2_std_id *e)
  76468. +{
  76469. + struct v4l2_format tv_fmt;
  76470. +
  76471. + pr_debug("In mxc_v4l2_g_std\n");
  76472. +
  76473. + if (cam->device_type == 1) {
  76474. + /* Use this function to get what the TV-In device detects the
  76475. + * format to be. pixelformat is used to return the std value
  76476. + * since the interface has no vidioc_g_std.*/
  76477. + tv_fmt.type = V4L2_BUF_TYPE_PRIVATE;
  76478. + vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt);
  76479. +
  76480. + /* If the TV-in automatically detects the standard, then if it
  76481. + * changes, the settings need to change. */
  76482. + if (cam->standard_autodetect) {
  76483. + if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) {
  76484. + pr_debug("MVC: mxc_v4l2_g_std: "
  76485. + "Changing standard\n");
  76486. + mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat);
  76487. + }
  76488. + }
  76489. +
  76490. + *e = tv_fmt.fmt.pix.pixelformat;
  76491. + }
  76492. +
  76493. + return 0;
  76494. +}
  76495. +
  76496. +/*!
  76497. + * Dequeue one V4L capture buffer
  76498. + *
  76499. + * @param cam structure cam_data *
  76500. + * @param buf structure v4l2_buffer *
  76501. + *
  76502. + * @return status 0 success, EINVAL invalid frame number,
  76503. + * ETIME timeout, ERESTARTSYS interrupted by user
  76504. + */
  76505. +static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
  76506. +{
  76507. + int retval = 0;
  76508. + struct mxc_v4l_frame *frame;
  76509. + unsigned long lock_flags;
  76510. +
  76511. + pr_debug("In MVC:mxc_v4l_dqueue\n");
  76512. +
  76513. + if (!wait_event_interruptible_timeout(cam->enc_queue,
  76514. + cam->enc_counter != 0, 10 * HZ)) {
  76515. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
  76516. + "enc_counter %x\n",
  76517. + cam->enc_counter);
  76518. + return -ETIME;
  76519. + } else if (signal_pending(current)) {
  76520. + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
  76521. + "interrupt received\n");
  76522. + return -ERESTARTSYS;
  76523. + }
  76524. +
  76525. + if (down_interruptible(&cam->busy_lock))
  76526. + return -EBUSY;
  76527. +
  76528. + spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
  76529. + cam->enc_counter--;
  76530. +
  76531. + frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
  76532. + list_del(cam->done_q.next);
  76533. + if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
  76534. + frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
  76535. + } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  76536. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  76537. + "Buffer not filled.\n");
  76538. + frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  76539. + retval = -EINVAL;
  76540. + } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
  76541. + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
  76542. + "Buffer not queued.\n");
  76543. + retval = -EINVAL;
  76544. + }
  76545. +
  76546. + cam->frame[frame->index].buffer.field = cam->device_type ?
  76547. + V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
  76548. +
  76549. + buf->bytesused = cam->v2f.fmt.pix.sizeimage;
  76550. + buf->index = frame->index;
  76551. + buf->flags = frame->buffer.flags;
  76552. + buf->m = cam->frame[frame->index].buffer.m;
  76553. + buf->timestamp = cam->frame[frame->index].buffer.timestamp;
  76554. + buf->field = cam->frame[frame->index].buffer.field;
  76555. + spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
  76556. +
  76557. + up(&cam->busy_lock);
  76558. + return retval;
  76559. +}
  76560. +
  76561. +/*!
  76562. + * V4L interface - open function
  76563. + *
  76564. + * @param file structure file *
  76565. + *
  76566. + * @return status 0 success, ENODEV invalid device instance,
  76567. + * ENODEV timeout, ERESTARTSYS interrupted by user
  76568. + */
  76569. +static int mxc_v4l_open(struct file *file)
  76570. +{
  76571. + struct v4l2_ifparm ifparm;
  76572. + struct v4l2_format cam_fmt;
  76573. + ipu_csi_signal_cfg_t csi_param;
  76574. + struct video_device *dev = video_devdata(file);
  76575. + cam_data *cam = video_get_drvdata(dev);
  76576. + int err = 0;
  76577. + struct sensor_data *sensor;
  76578. +
  76579. + pr_debug("\nIn MVC: mxc_v4l_open\n");
  76580. + pr_debug(" device name is %s\n", dev->name);
  76581. +
  76582. + if (!cam) {
  76583. + pr_err("ERROR: v4l2 capture: Internal error, "
  76584. + "cam_data not found!\n");
  76585. + return -EBADF;
  76586. + }
  76587. +
  76588. + if (cam->sensor == NULL ||
  76589. + cam->sensor->type != v4l2_int_type_slave) {
  76590. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  76591. + return -EAGAIN;
  76592. + }
  76593. +
  76594. + sensor = cam->sensor->priv;
  76595. + if (!sensor) {
  76596. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  76597. + return -EBADF;
  76598. + }
  76599. +
  76600. + down(&cam->busy_lock);
  76601. + err = 0;
  76602. + if (signal_pending(current))
  76603. + goto oops;
  76604. +
  76605. + if (cam->open_count++ == 0) {
  76606. + wait_event_interruptible(cam->power_queue,
  76607. + cam->low_power == false);
  76608. +
  76609. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  76610. + "CSI MEM") == 0) {
  76611. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  76612. + err = csi_enc_select(cam);
  76613. +#endif
  76614. + } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
  76615. + "CSI IC MEM") == 0) {
  76616. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  76617. + err = prp_enc_select(cam);
  76618. +#endif
  76619. + }
  76620. +
  76621. + cam->enc_counter = 0;
  76622. + INIT_LIST_HEAD(&cam->ready_q);
  76623. + INIT_LIST_HEAD(&cam->working_q);
  76624. + INIT_LIST_HEAD(&cam->done_q);
  76625. +
  76626. + vidioc_int_g_ifparm(cam->sensor, &ifparm);
  76627. +
  76628. + csi_param.sens_clksrc = 0;
  76629. +
  76630. + csi_param.clk_mode = 0;
  76631. + csi_param.data_pol = 0;
  76632. + csi_param.ext_vsync = 0;
  76633. +
  76634. + csi_param.pack_tight = 0;
  76635. + csi_param.force_eof = 0;
  76636. + csi_param.data_en_pol = 0;
  76637. +
  76638. + csi_param.mclk = ifparm.u.bt656.clock_curr;
  76639. +
  76640. + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
  76641. +
  76642. + if (ifparm.u.bt656.mode
  76643. + == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT)
  76644. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  76645. + else if (ifparm.u.bt656.mode
  76646. + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT)
  76647. + csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
  76648. + else
  76649. + csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
  76650. +
  76651. +
  76652. + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
  76653. + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
  76654. +
  76655. + csi_param.csi = cam->csi;
  76656. +
  76657. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  76658. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  76659. +
  76660. + /* Reset the sizes. Needed to prevent carryover of last
  76661. + * operation.*/
  76662. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  76663. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  76664. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  76665. +
  76666. + /* This also is the max crop size for this device. */
  76667. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  76668. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  76669. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  76670. +
  76671. + /* At this point, this is also the current image size. */
  76672. + cam->crop_current.top = cam->crop_current.left = 0;
  76673. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  76674. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  76675. +
  76676. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  76677. + __func__,
  76678. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  76679. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  76680. + __func__,
  76681. + cam->crop_bounds.width, cam->crop_bounds.height);
  76682. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  76683. + __func__,
  76684. + cam->crop_defrect.width, cam->crop_defrect.height);
  76685. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  76686. + __func__,
  76687. + cam->crop_current.width, cam->crop_current.height);
  76688. +
  76689. + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
  76690. + pr_debug("On Open: Input to ipu size is %d x %d\n",
  76691. + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
  76692. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  76693. + cam->crop_current.height,
  76694. + cam->csi);
  76695. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  76696. + cam->crop_current.top,
  76697. + cam->csi);
  76698. + ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
  76699. + cam->crop_bounds.height,
  76700. + cam_fmt.fmt.pix.pixelformat,
  76701. + csi_param);
  76702. + clk_prepare_enable(sensor->sensor_clk);
  76703. + vidioc_int_s_power(cam->sensor, 1);
  76704. + vidioc_int_init(cam->sensor);
  76705. + vidioc_int_dev_init(cam->sensor);
  76706. + }
  76707. +
  76708. + file->private_data = dev;
  76709. +
  76710. +oops:
  76711. + up(&cam->busy_lock);
  76712. + return err;
  76713. +}
  76714. +
  76715. +/*!
  76716. + * V4L interface - close function
  76717. + *
  76718. + * @param file struct file *
  76719. + *
  76720. + * @return 0 success
  76721. + */
  76722. +static int mxc_v4l_close(struct file *file)
  76723. +{
  76724. + struct video_device *dev = video_devdata(file);
  76725. + int err = 0;
  76726. + cam_data *cam = video_get_drvdata(dev);
  76727. + struct sensor_data *sensor;
  76728. + pr_debug("In MVC:mxc_v4l_close\n");
  76729. +
  76730. + if (!cam) {
  76731. + pr_err("ERROR: v4l2 capture: Internal error, "
  76732. + "cam_data not found!\n");
  76733. + return -EBADF;
  76734. + }
  76735. +
  76736. + if (!cam->sensor) {
  76737. + pr_err("%s: Internal error, camera is not found!\n", __func__);
  76738. + return -EBADF;
  76739. + }
  76740. +
  76741. + sensor = cam->sensor->priv;
  76742. + if (!sensor) {
  76743. + pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
  76744. + return -EBADF;
  76745. + }
  76746. +
  76747. + down(&cam->busy_lock);
  76748. +
  76749. + /* for the case somebody hit the ctrl C */
  76750. + if (cam->overlay_pid == current->pid && cam->overlay_on) {
  76751. + err = stop_preview(cam);
  76752. + cam->overlay_on = false;
  76753. + }
  76754. + if (cam->capture_pid == current->pid) {
  76755. + err |= mxc_streamoff(cam);
  76756. + wake_up_interruptible(&cam->enc_queue);
  76757. + }
  76758. +
  76759. + if (--cam->open_count == 0) {
  76760. + vidioc_int_s_power(cam->sensor, 0);
  76761. + clk_disable_unprepare(sensor->sensor_clk);
  76762. + wait_event_interruptible(cam->power_queue,
  76763. + cam->low_power == false);
  76764. + pr_debug("mxc_v4l_close: release resource\n");
  76765. +
  76766. + if (strcmp(mxc_capture_inputs[cam->current_input].name,
  76767. + "CSI MEM") == 0) {
  76768. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  76769. + err |= csi_enc_deselect(cam);
  76770. +#endif
  76771. + } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
  76772. + "CSI IC MEM") == 0) {
  76773. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  76774. + err |= prp_enc_deselect(cam);
  76775. +#endif
  76776. + }
  76777. +
  76778. + mxc_free_frame_buf(cam);
  76779. + file->private_data = NULL;
  76780. +
  76781. + /* capture off */
  76782. + wake_up_interruptible(&cam->enc_queue);
  76783. + mxc_free_frames(cam);
  76784. + cam->enc_counter++;
  76785. + }
  76786. +
  76787. + up(&cam->busy_lock);
  76788. +
  76789. + return err;
  76790. +}
  76791. +
  76792. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC) || \
  76793. + defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) || \
  76794. + defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  76795. +/*
  76796. + * V4L interface - read function
  76797. + *
  76798. + * @param file struct file *
  76799. + * @param read buf char *
  76800. + * @param count size_t
  76801. + * @param ppos structure loff_t *
  76802. + *
  76803. + * @return bytes read
  76804. + */
  76805. +static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count,
  76806. + loff_t *ppos)
  76807. +{
  76808. + int err = 0;
  76809. + u8 *v_address[2];
  76810. + struct video_device *dev = video_devdata(file);
  76811. + cam_data *cam = video_get_drvdata(dev);
  76812. +
  76813. + if (down_interruptible(&cam->busy_lock))
  76814. + return -EINTR;
  76815. +
  76816. + /* Stop the viewfinder */
  76817. + if (cam->overlay_on == true)
  76818. + stop_preview(cam);
  76819. +
  76820. + v_address[0] = dma_alloc_coherent(0,
  76821. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  76822. + &cam->still_buf[0],
  76823. + GFP_DMA | GFP_KERNEL);
  76824. +
  76825. + v_address[1] = dma_alloc_coherent(0,
  76826. + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
  76827. + &cam->still_buf[1],
  76828. + GFP_DMA | GFP_KERNEL);
  76829. +
  76830. + if (!v_address[0] || !v_address[1]) {
  76831. + err = -ENOBUFS;
  76832. + goto exit0;
  76833. + }
  76834. +
  76835. + err = prp_still_select(cam);
  76836. + if (err != 0) {
  76837. + err = -EIO;
  76838. + goto exit0;
  76839. + }
  76840. +
  76841. + cam->still_counter = 0;
  76842. + err = cam->csi_start(cam);
  76843. + if (err != 0) {
  76844. + err = -EIO;
  76845. + goto exit1;
  76846. + }
  76847. +
  76848. + if (!wait_event_interruptible_timeout(cam->still_queue,
  76849. + cam->still_counter != 0,
  76850. + 10 * HZ)) {
  76851. + pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x\n",
  76852. + cam->still_counter);
  76853. + err = -ETIME;
  76854. + goto exit1;
  76855. + }
  76856. + err = copy_to_user(buf, v_address[1], cam->v2f.fmt.pix.sizeimage);
  76857. +
  76858. +exit1:
  76859. + prp_still_deselect(cam);
  76860. +
  76861. +exit0:
  76862. + if (v_address[0] != 0)
  76863. + dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[0],
  76864. + cam->still_buf[0]);
  76865. + if (v_address[1] != 0)
  76866. + dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[1],
  76867. + cam->still_buf[1]);
  76868. +
  76869. + cam->still_buf[0] = cam->still_buf[1] = 0;
  76870. +
  76871. + if (cam->overlay_on == true)
  76872. + start_preview(cam);
  76873. +
  76874. + up(&cam->busy_lock);
  76875. + if (err < 0)
  76876. + return err;
  76877. +
  76878. + return cam->v2f.fmt.pix.sizeimage - err;
  76879. +}
  76880. +#endif
  76881. +
  76882. +/*!
  76883. + * V4L interface - ioctl function
  76884. + *
  76885. + * @param file struct file*
  76886. + *
  76887. + * @param ioctlnr unsigned int
  76888. + *
  76889. + * @param arg void*
  76890. + *
  76891. + * @return 0 success, ENODEV for invalid device instance,
  76892. + * -1 for other errors.
  76893. + */
  76894. +static long mxc_v4l_do_ioctl(struct file *file,
  76895. + unsigned int ioctlnr, void *arg)
  76896. +{
  76897. + struct video_device *dev = video_devdata(file);
  76898. + cam_data *cam = video_get_drvdata(dev);
  76899. + int retval = 0;
  76900. + unsigned long lock_flags;
  76901. +
  76902. + pr_debug("In MVC: mxc_v4l_do_ioctl %x\n", ioctlnr);
  76903. + wait_event_interruptible(cam->power_queue, cam->low_power == false);
  76904. + /* make this _really_ smp-safe */
  76905. + if (ioctlnr != VIDIOC_DQBUF)
  76906. + if (down_interruptible(&cam->busy_lock))
  76907. + return -EBUSY;
  76908. +
  76909. + switch (ioctlnr) {
  76910. + /*!
  76911. + * V4l2 VIDIOC_QUERYCAP ioctl
  76912. + */
  76913. + case VIDIOC_QUERYCAP: {
  76914. + struct v4l2_capability *cap = arg;
  76915. + pr_debug(" case VIDIOC_QUERYCAP\n");
  76916. + strcpy(cap->driver, "mxc_v4l2");
  76917. + cap->version = KERNEL_VERSION(0, 1, 11);
  76918. + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
  76919. + V4L2_CAP_VIDEO_OVERLAY |
  76920. + V4L2_CAP_STREAMING |
  76921. + V4L2_CAP_READWRITE;
  76922. + cap->card[0] = '\0';
  76923. + cap->bus_info[0] = '\0';
  76924. + break;
  76925. + }
  76926. +
  76927. + /*!
  76928. + * V4l2 VIDIOC_G_FMT ioctl
  76929. + */
  76930. + case VIDIOC_G_FMT: {
  76931. + struct v4l2_format *gf = arg;
  76932. + pr_debug(" case VIDIOC_G_FMT\n");
  76933. + retval = mxc_v4l2_g_fmt(cam, gf);
  76934. + break;
  76935. + }
  76936. +
  76937. + /*!
  76938. + * V4l2 VIDIOC_S_FMT ioctl
  76939. + */
  76940. + case VIDIOC_S_FMT: {
  76941. + struct v4l2_format *sf = arg;
  76942. + pr_debug(" case VIDIOC_S_FMT\n");
  76943. + retval = mxc_v4l2_s_fmt(cam, sf);
  76944. + break;
  76945. + }
  76946. +
  76947. + /*!
  76948. + * V4l2 VIDIOC_REQBUFS ioctl
  76949. + */
  76950. + case VIDIOC_REQBUFS: {
  76951. + struct v4l2_requestbuffers *req = arg;
  76952. + pr_debug(" case VIDIOC_REQBUFS\n");
  76953. +
  76954. + if (req->count > FRAME_NUM) {
  76955. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  76956. + "not enough buffers\n");
  76957. + req->count = FRAME_NUM;
  76958. + }
  76959. +
  76960. + if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
  76961. + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
  76962. + "wrong buffer type\n");
  76963. + retval = -EINVAL;
  76964. + break;
  76965. + }
  76966. +
  76967. + mxc_streamoff(cam);
  76968. + if (req->memory & V4L2_MEMORY_MMAP) {
  76969. + mxc_free_frame_buf(cam);
  76970. + retval = mxc_allocate_frame_buf(cam, req->count);
  76971. + }
  76972. + break;
  76973. + }
  76974. +
  76975. + /*!
  76976. + * V4l2 VIDIOC_QUERYBUF ioctl
  76977. + */
  76978. + case VIDIOC_QUERYBUF: {
  76979. + struct v4l2_buffer *buf = arg;
  76980. + int index = buf->index;
  76981. + pr_debug(" case VIDIOC_QUERYBUF\n");
  76982. +
  76983. + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
  76984. + pr_err("ERROR: v4l2 capture: "
  76985. + "VIDIOC_QUERYBUFS: "
  76986. + "wrong buffer type\n");
  76987. + retval = -EINVAL;
  76988. + break;
  76989. + }
  76990. +
  76991. + if (buf->memory & V4L2_MEMORY_MMAP) {
  76992. + memset(buf, 0, sizeof(buf));
  76993. + buf->index = index;
  76994. + }
  76995. +
  76996. + down(&cam->param_lock);
  76997. + if (buf->memory & V4L2_MEMORY_USERPTR) {
  76998. + mxc_v4l2_release_bufs(cam);
  76999. + retval = mxc_v4l2_prepare_bufs(cam, buf);
  77000. + }
  77001. +
  77002. + if (buf->memory & V4L2_MEMORY_MMAP)
  77003. + retval = mxc_v4l2_buffer_status(cam, buf);
  77004. + up(&cam->param_lock);
  77005. + break;
  77006. + }
  77007. +
  77008. + /*!
  77009. + * V4l2 VIDIOC_QBUF ioctl
  77010. + */
  77011. + case VIDIOC_QBUF: {
  77012. + struct v4l2_buffer *buf = arg;
  77013. + int index = buf->index;
  77014. + pr_debug(" case VIDIOC_QBUF\n");
  77015. +
  77016. + spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
  77017. + if ((cam->frame[index].buffer.flags & 0x7) ==
  77018. + V4L2_BUF_FLAG_MAPPED) {
  77019. + cam->frame[index].buffer.flags |=
  77020. + V4L2_BUF_FLAG_QUEUED;
  77021. + list_add_tail(&cam->frame[index].queue,
  77022. + &cam->ready_q);
  77023. + } else if (cam->frame[index].buffer.
  77024. + flags & V4L2_BUF_FLAG_QUEUED) {
  77025. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  77026. + "buffer already queued\n");
  77027. + retval = -EINVAL;
  77028. + } else if (cam->frame[index].buffer.
  77029. + flags & V4L2_BUF_FLAG_DONE) {
  77030. + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
  77031. + "overwrite done buffer.\n");
  77032. + cam->frame[index].buffer.flags &=
  77033. + ~V4L2_BUF_FLAG_DONE;
  77034. + cam->frame[index].buffer.flags |=
  77035. + V4L2_BUF_FLAG_QUEUED;
  77036. + retval = -EINVAL;
  77037. + }
  77038. +
  77039. + buf->flags = cam->frame[index].buffer.flags;
  77040. + spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
  77041. + break;
  77042. + }
  77043. +
  77044. + /*!
  77045. + * V4l2 VIDIOC_DQBUF ioctl
  77046. + */
  77047. + case VIDIOC_DQBUF: {
  77048. + struct v4l2_buffer *buf = arg;
  77049. + pr_debug(" case VIDIOC_DQBUF\n");
  77050. +
  77051. + if ((cam->enc_counter == 0) &&
  77052. + (file->f_flags & O_NONBLOCK)) {
  77053. + retval = -EAGAIN;
  77054. + break;
  77055. + }
  77056. +
  77057. + retval = mxc_v4l_dqueue(cam, buf);
  77058. + break;
  77059. + }
  77060. +
  77061. + /*!
  77062. + * V4l2 VIDIOC_STREAMON ioctl
  77063. + */
  77064. + case VIDIOC_STREAMON: {
  77065. + pr_debug(" case VIDIOC_STREAMON\n");
  77066. + retval = mxc_streamon(cam);
  77067. + break;
  77068. + }
  77069. +
  77070. + /*!
  77071. + * V4l2 VIDIOC_STREAMOFF ioctl
  77072. + */
  77073. + case VIDIOC_STREAMOFF: {
  77074. + pr_debug(" case VIDIOC_STREAMOFF\n");
  77075. + retval = mxc_streamoff(cam);
  77076. + break;
  77077. + }
  77078. +
  77079. + /*!
  77080. + * V4l2 VIDIOC_G_CTRL ioctl
  77081. + */
  77082. + case VIDIOC_G_CTRL: {
  77083. + pr_debug(" case VIDIOC_G_CTRL\n");
  77084. + retval = mxc_v4l2_g_ctrl(cam, arg);
  77085. + break;
  77086. + }
  77087. +
  77088. + /*!
  77089. + * V4l2 VIDIOC_S_CTRL ioctl
  77090. + */
  77091. + case VIDIOC_S_CTRL: {
  77092. + pr_debug(" case VIDIOC_S_CTRL\n");
  77093. + retval = mxc_v4l2_s_ctrl(cam, arg);
  77094. + break;
  77095. + }
  77096. +
  77097. + /*!
  77098. + * V4l2 VIDIOC_CROPCAP ioctl
  77099. + */
  77100. + case VIDIOC_CROPCAP: {
  77101. + struct v4l2_cropcap *cap = arg;
  77102. + pr_debug(" case VIDIOC_CROPCAP\n");
  77103. + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  77104. + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  77105. + retval = -EINVAL;
  77106. + break;
  77107. + }
  77108. + cap->bounds = cam->crop_bounds;
  77109. + cap->defrect = cam->crop_defrect;
  77110. + break;
  77111. + }
  77112. +
  77113. + /*!
  77114. + * V4l2 VIDIOC_G_CROP ioctl
  77115. + */
  77116. + case VIDIOC_G_CROP: {
  77117. + struct v4l2_crop *crop = arg;
  77118. + pr_debug(" case VIDIOC_G_CROP\n");
  77119. +
  77120. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  77121. + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  77122. + retval = -EINVAL;
  77123. + break;
  77124. + }
  77125. + crop->c = cam->crop_current;
  77126. + break;
  77127. + }
  77128. +
  77129. + /*!
  77130. + * V4l2 VIDIOC_S_CROP ioctl
  77131. + */
  77132. + case VIDIOC_S_CROP: {
  77133. + struct v4l2_crop *crop = arg;
  77134. + struct v4l2_rect *b = &cam->crop_bounds;
  77135. + pr_debug(" case VIDIOC_S_CROP\n");
  77136. +
  77137. + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
  77138. + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
  77139. + retval = -EINVAL;
  77140. + break;
  77141. + }
  77142. +
  77143. + crop->c.top = (crop->c.top < b->top) ? b->top
  77144. + : crop->c.top;
  77145. + if (crop->c.top > b->top + b->height)
  77146. + crop->c.top = b->top + b->height - 1;
  77147. + if (crop->c.height > b->top + b->height - crop->c.top)
  77148. + crop->c.height =
  77149. + b->top + b->height - crop->c.top;
  77150. +
  77151. + crop->c.left = (crop->c.left < b->left) ? b->left
  77152. + : crop->c.left;
  77153. + if (crop->c.left > b->left + b->width)
  77154. + crop->c.left = b->left + b->width - 1;
  77155. + if (crop->c.width > b->left - crop->c.left + b->width)
  77156. + crop->c.width =
  77157. + b->left - crop->c.left + b->width;
  77158. +
  77159. + crop->c.width -= crop->c.width % 8;
  77160. + crop->c.left -= crop->c.left % 4;
  77161. + cam->crop_current = crop->c;
  77162. +
  77163. + pr_debug(" Cropping Input to ipu size %d x %d\n",
  77164. + cam->crop_current.width,
  77165. + cam->crop_current.height);
  77166. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  77167. + cam->crop_current.height,
  77168. + cam->csi);
  77169. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  77170. + cam->crop_current.top,
  77171. + cam->csi);
  77172. + break;
  77173. + }
  77174. +
  77175. + /*!
  77176. + * V4l2 VIDIOC_OVERLAY ioctl
  77177. + */
  77178. + case VIDIOC_OVERLAY: {
  77179. + int *on = arg;
  77180. + pr_debug(" VIDIOC_OVERLAY on=%d\n", *on);
  77181. + if (*on) {
  77182. + cam->overlay_on = true;
  77183. + cam->overlay_pid = current->pid;
  77184. + retval = start_preview(cam);
  77185. + }
  77186. + if (!*on) {
  77187. + retval = stop_preview(cam);
  77188. + cam->overlay_on = false;
  77189. + }
  77190. + break;
  77191. + }
  77192. +
  77193. + /*!
  77194. + * V4l2 VIDIOC_G_FBUF ioctl
  77195. + */
  77196. + case VIDIOC_G_FBUF: {
  77197. + struct v4l2_framebuffer *fb = arg;
  77198. + pr_debug(" case VIDIOC_G_FBUF\n");
  77199. + *fb = cam->v4l2_fb;
  77200. + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
  77201. + break;
  77202. + }
  77203. +
  77204. + /*!
  77205. + * V4l2 VIDIOC_S_FBUF ioctl
  77206. + */
  77207. + case VIDIOC_S_FBUF: {
  77208. + struct v4l2_framebuffer *fb = arg;
  77209. + pr_debug(" case VIDIOC_S_FBUF\n");
  77210. + cam->v4l2_fb = *fb;
  77211. + break;
  77212. + }
  77213. +
  77214. + case VIDIOC_G_PARM: {
  77215. + struct v4l2_streamparm *parm = arg;
  77216. + pr_debug(" case VIDIOC_G_PARM\n");
  77217. + if (cam->sensor)
  77218. + retval = vidioc_int_g_parm(cam->sensor, parm);
  77219. + else {
  77220. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  77221. + retval = -ENODEV;
  77222. + }
  77223. + break;
  77224. + }
  77225. +
  77226. + case VIDIOC_S_PARM: {
  77227. + struct v4l2_streamparm *parm = arg;
  77228. + pr_debug(" case VIDIOC_S_PARM\n");
  77229. + if (cam->sensor)
  77230. + retval = mxc_v4l2_s_param(cam, parm);
  77231. + else {
  77232. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  77233. + retval = -ENODEV;
  77234. + }
  77235. + break;
  77236. + }
  77237. +
  77238. + /* linux v4l2 bug, kernel c0485619 user c0405619 */
  77239. + case VIDIOC_ENUMSTD: {
  77240. + struct v4l2_standard *e = arg;
  77241. + pr_debug(" case VIDIOC_ENUMSTD\n");
  77242. + *e = cam->standard;
  77243. + break;
  77244. + }
  77245. +
  77246. + case VIDIOC_G_STD: {
  77247. + v4l2_std_id *e = arg;
  77248. + pr_debug(" case VIDIOC_G_STD\n");
  77249. + if (cam->sensor)
  77250. + retval = mxc_v4l2_g_std(cam, e);
  77251. + else {
  77252. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  77253. + retval = -ENODEV;
  77254. + }
  77255. + break;
  77256. + }
  77257. +
  77258. + case VIDIOC_S_STD: {
  77259. + v4l2_std_id *e = arg;
  77260. + pr_debug(" case VIDIOC_S_STD\n");
  77261. + retval = mxc_v4l2_s_std(cam, *e);
  77262. +
  77263. + break;
  77264. + }
  77265. +
  77266. + case VIDIOC_ENUMOUTPUT: {
  77267. + struct v4l2_output *output = arg;
  77268. + pr_debug(" case VIDIOC_ENUMOUTPUT\n");
  77269. + if (output->index >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
  77270. + retval = -EINVAL;
  77271. + break;
  77272. + }
  77273. + *output = mxc_capture_outputs[output->index];
  77274. +
  77275. + break;
  77276. + }
  77277. + case VIDIOC_G_OUTPUT: {
  77278. + int *p_output_num = arg;
  77279. + pr_debug(" case VIDIOC_G_OUTPUT\n");
  77280. + *p_output_num = cam->output;
  77281. + break;
  77282. + }
  77283. +
  77284. + case VIDIOC_S_OUTPUT: {
  77285. + int *p_output_num = arg;
  77286. + pr_debug(" case VIDIOC_S_OUTPUT\n");
  77287. + if (*p_output_num >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
  77288. + retval = -EINVAL;
  77289. + break;
  77290. + }
  77291. + cam->output = *p_output_num;
  77292. + break;
  77293. + }
  77294. +
  77295. + case VIDIOC_ENUMINPUT: {
  77296. + struct v4l2_input *input = arg;
  77297. + pr_debug(" case VIDIOC_ENUMINPUT\n");
  77298. + if (input->index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
  77299. + retval = -EINVAL;
  77300. + break;
  77301. + }
  77302. + *input = mxc_capture_inputs[input->index];
  77303. + break;
  77304. + }
  77305. +
  77306. + case VIDIOC_G_INPUT: {
  77307. + int *index = arg;
  77308. + pr_debug(" case VIDIOC_G_INPUT\n");
  77309. + *index = cam->current_input;
  77310. + break;
  77311. + }
  77312. +
  77313. + case VIDIOC_S_INPUT: {
  77314. + int *index = arg;
  77315. + pr_debug(" case VIDIOC_S_INPUT\n");
  77316. + if (*index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
  77317. + retval = -EINVAL;
  77318. + break;
  77319. + }
  77320. +
  77321. + if (*index == cam->current_input)
  77322. + break;
  77323. +
  77324. + if ((mxc_capture_inputs[cam->current_input].status &
  77325. + V4L2_IN_ST_NO_POWER) == 0) {
  77326. + retval = mxc_streamoff(cam);
  77327. + if (retval)
  77328. + break;
  77329. + mxc_capture_inputs[cam->current_input].status |=
  77330. + V4L2_IN_ST_NO_POWER;
  77331. + }
  77332. +
  77333. + if (strcmp(mxc_capture_inputs[*index].name, "CSI MEM") == 0) {
  77334. +#if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
  77335. + retval = csi_enc_select(cam);
  77336. + if (retval)
  77337. + break;
  77338. +#endif
  77339. + } else if (strcmp(mxc_capture_inputs[*index].name,
  77340. + "CSI IC MEM") == 0) {
  77341. +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
  77342. + retval = prp_enc_select(cam);
  77343. + if (retval)
  77344. + break;
  77345. +#endif
  77346. + }
  77347. +
  77348. + mxc_capture_inputs[*index].status &= ~V4L2_IN_ST_NO_POWER;
  77349. + cam->current_input = *index;
  77350. + break;
  77351. + }
  77352. + case VIDIOC_ENUM_FMT: {
  77353. + struct v4l2_fmtdesc *f = arg;
  77354. + if (cam->sensor)
  77355. + retval = vidioc_int_enum_fmt_cap(cam->sensor, f);
  77356. + else {
  77357. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  77358. + retval = -ENODEV;
  77359. + }
  77360. + break;
  77361. + }
  77362. + case VIDIOC_ENUM_FRAMESIZES: {
  77363. + struct v4l2_frmsizeenum *fsize = arg;
  77364. + if (cam->sensor)
  77365. + retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
  77366. + else {
  77367. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  77368. + retval = -ENODEV;
  77369. + }
  77370. + break;
  77371. + }
  77372. + case VIDIOC_DBG_G_CHIP_IDENT: {
  77373. + struct v4l2_dbg_chip_ident *p = arg;
  77374. + p->ident = V4L2_IDENT_NONE;
  77375. + p->revision = 0;
  77376. + if (cam->sensor)
  77377. + retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
  77378. + else {
  77379. + pr_err("ERROR: v4l2 capture: slave not found!\n");
  77380. + retval = -ENODEV;
  77381. + }
  77382. + break;
  77383. + }
  77384. + case VIDIOC_TRY_FMT:
  77385. + case VIDIOC_QUERYCTRL:
  77386. + case VIDIOC_G_TUNER:
  77387. + case VIDIOC_S_TUNER:
  77388. + case VIDIOC_G_FREQUENCY:
  77389. + case VIDIOC_S_FREQUENCY:
  77390. + default:
  77391. + pr_debug(" case default or not supported\n");
  77392. + retval = -EINVAL;
  77393. + break;
  77394. + }
  77395. +
  77396. + if (ioctlnr != VIDIOC_DQBUF)
  77397. + up(&cam->busy_lock);
  77398. + return retval;
  77399. +}
  77400. +
  77401. +/*
  77402. + * V4L interface - ioctl function
  77403. + *
  77404. + * @return None
  77405. + */
  77406. +static long mxc_v4l_ioctl(struct file *file, unsigned int cmd,
  77407. + unsigned long arg)
  77408. +{
  77409. + pr_debug("In MVC:mxc_v4l_ioctl\n");
  77410. + return video_usercopy(file, cmd, arg, mxc_v4l_do_ioctl);
  77411. +}
  77412. +
  77413. +/*!
  77414. + * V4L interface - mmap function
  77415. + *
  77416. + * @param file structure file *
  77417. + *
  77418. + * @param vma structure vm_area_struct *
  77419. + *
  77420. + * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
  77421. + */
  77422. +static int mxc_mmap(struct file *file, struct vm_area_struct *vma)
  77423. +{
  77424. + struct video_device *dev = video_devdata(file);
  77425. + unsigned long size;
  77426. + int res = 0;
  77427. + cam_data *cam = video_get_drvdata(dev);
  77428. +
  77429. + pr_debug("In MVC:mxc_mmap\n");
  77430. + pr_debug(" pgoff=0x%lx, start=0x%lx, end=0x%lx\n",
  77431. + vma->vm_pgoff, vma->vm_start, vma->vm_end);
  77432. +
  77433. + /* make this _really_ smp-safe */
  77434. + if (down_interruptible(&cam->busy_lock))
  77435. + return -EINTR;
  77436. +
  77437. + size = vma->vm_end - vma->vm_start;
  77438. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  77439. +
  77440. + if (remap_pfn_range(vma, vma->vm_start,
  77441. + vma->vm_pgoff, size, vma->vm_page_prot)) {
  77442. + pr_err("ERROR: v4l2 capture: mxc_mmap: "
  77443. + "remap_pfn_range failed\n");
  77444. + res = -ENOBUFS;
  77445. + goto mxc_mmap_exit;
  77446. + }
  77447. +
  77448. + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
  77449. +
  77450. +mxc_mmap_exit:
  77451. + up(&cam->busy_lock);
  77452. + return res;
  77453. +}
  77454. +
  77455. +/*!
  77456. + * V4L interface - poll function
  77457. + *
  77458. + * @param file structure file *
  77459. + *
  77460. + * @param wait structure poll_table_struct *
  77461. + *
  77462. + * @return status POLLIN | POLLRDNORM
  77463. + */
  77464. +static unsigned int mxc_poll(struct file *file, struct poll_table_struct *wait)
  77465. +{
  77466. + struct video_device *dev = video_devdata(file);
  77467. + cam_data *cam = video_get_drvdata(dev);
  77468. + wait_queue_head_t *queue = NULL;
  77469. + int res = POLLIN | POLLRDNORM;
  77470. +
  77471. + pr_debug("In MVC:mxc_poll\n");
  77472. +
  77473. + if (down_interruptible(&cam->busy_lock))
  77474. + return -EINTR;
  77475. +
  77476. + queue = &cam->enc_queue;
  77477. + poll_wait(file, queue, wait);
  77478. +
  77479. + up(&cam->busy_lock);
  77480. +
  77481. + return res;
  77482. +}
  77483. +
  77484. +/*!
  77485. + * This structure defines the functions to be called in this driver.
  77486. + */
  77487. +static struct v4l2_file_operations mxc_v4l_fops = {
  77488. + .owner = THIS_MODULE,
  77489. + .open = mxc_v4l_open,
  77490. + .release = mxc_v4l_close,
  77491. + .read = mxc_v4l_read,
  77492. + .ioctl = mxc_v4l_ioctl,
  77493. + .mmap = mxc_mmap,
  77494. + .poll = mxc_poll,
  77495. +};
  77496. +
  77497. +static struct video_device mxc_v4l_template = {
  77498. + .name = "Mxc Camera",
  77499. + .fops = &mxc_v4l_fops,
  77500. + .release = video_device_release,
  77501. +};
  77502. +
  77503. +/*!
  77504. + * This function can be used to release any platform data on closing.
  77505. + */
  77506. +static void camera_platform_release(struct device *device)
  77507. +{
  77508. +}
  77509. +
  77510. +/*!
  77511. + * Camera V4l2 callback function.
  77512. + *
  77513. + * @param mask u32
  77514. + *
  77515. + * @param dev void device structure
  77516. + *
  77517. + * @return status
  77518. + */
  77519. +static void camera_callback(u32 mask, void *dev)
  77520. +{
  77521. + struct mxc_v4l_frame *done_frame;
  77522. + struct mxc_v4l_frame *ready_frame;
  77523. + struct timeval cur_time;
  77524. +
  77525. + cam_data *cam = (cam_data *) dev;
  77526. + if (cam == NULL)
  77527. + return;
  77528. +
  77529. + pr_debug("In MVC:camera_callback\n");
  77530. +
  77531. + spin_lock(&cam->queue_int_lock);
  77532. + spin_lock(&cam->dqueue_int_lock);
  77533. + if (!list_empty(&cam->working_q)) {
  77534. + do_gettimeofday(&cur_time);
  77535. +
  77536. + done_frame = list_entry(cam->working_q.next,
  77537. + struct mxc_v4l_frame,
  77538. + queue);
  77539. +
  77540. + if (done_frame->ipu_buf_num != cam->local_buf_num)
  77541. + goto next;
  77542. +
  77543. + /*
  77544. + * Set the current time to done frame buffer's
  77545. + * timestamp. Users can use this information to judge
  77546. + * the frame's usage.
  77547. + */
  77548. + done_frame->buffer.timestamp = cur_time;
  77549. +
  77550. + if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
  77551. + done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
  77552. + done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
  77553. +
  77554. + /* Added to the done queue */
  77555. + list_del(cam->working_q.next);
  77556. + list_add_tail(&done_frame->queue, &cam->done_q);
  77557. +
  77558. + /* Wake up the queue */
  77559. + cam->enc_counter++;
  77560. + wake_up_interruptible(&cam->enc_queue);
  77561. + } else
  77562. + pr_err("ERROR: v4l2 capture: camera_callback: "
  77563. + "buffer not queued\n");
  77564. + }
  77565. +
  77566. +next:
  77567. + if (!list_empty(&cam->ready_q)) {
  77568. + ready_frame = list_entry(cam->ready_q.next,
  77569. + struct mxc_v4l_frame,
  77570. + queue);
  77571. + if (cam->enc_update_eba)
  77572. + if (cam->enc_update_eba(cam->ipu,
  77573. + ready_frame->buffer.m.offset,
  77574. + &cam->ping_pong_csi) == 0) {
  77575. + list_del(cam->ready_q.next);
  77576. + list_add_tail(&ready_frame->queue,
  77577. + &cam->working_q);
  77578. + ready_frame->ipu_buf_num = cam->local_buf_num;
  77579. + }
  77580. + } else {
  77581. + if (cam->enc_update_eba)
  77582. + cam->enc_update_eba(
  77583. + cam->ipu, cam->dummy_frame.buffer.m.offset,
  77584. + &cam->ping_pong_csi);
  77585. + }
  77586. +
  77587. + cam->local_buf_num = (cam->local_buf_num == 0) ? 1 : 0;
  77588. + spin_unlock(&cam->dqueue_int_lock);
  77589. + spin_unlock(&cam->queue_int_lock);
  77590. +
  77591. + return;
  77592. +}
  77593. +
  77594. +/*!
  77595. + * initialize cam_data structure
  77596. + *
  77597. + * @param cam structure cam_data *
  77598. + *
  77599. + * @return status 0 Success
  77600. + */
  77601. +static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
  77602. +{
  77603. + const struct of_device_id *of_id =
  77604. + of_match_device(mxc_v4l2_dt_ids, &pdev->dev);
  77605. + struct device_node *np = pdev->dev.of_node;
  77606. + int ipu_id, csi_id, mclk_source;
  77607. + int ret = 0;
  77608. +
  77609. + pr_debug("In MVC: init_camera_struct\n");
  77610. +
  77611. + ret = of_property_read_u32(np, "ipu_id", &ipu_id);
  77612. + if (ret) {
  77613. + dev_err(&pdev->dev, "ipu_id missing or invalid\n");
  77614. + return ret;
  77615. + }
  77616. +
  77617. + ret = of_property_read_u32(np, "csi_id", &csi_id);
  77618. + if (ret) {
  77619. + dev_err(&pdev->dev, "csi_id missing or invalid\n");
  77620. + return ret;
  77621. + }
  77622. +
  77623. + ret = of_property_read_u32(np, "mclk_source", &mclk_source);
  77624. + if (ret) {
  77625. + dev_err(&pdev->dev, "sensor mclk missing or invalid\n");
  77626. + return ret;
  77627. + }
  77628. +
  77629. + /* Default everything to 0 */
  77630. + memset(cam, 0, sizeof(cam_data));
  77631. +
  77632. + /* get devtype to distinguish if the cpu is imx5 or imx6
  77633. + * IMX5_V4L2 specify the cpu is imx5
  77634. + * IMX6_V4L2 specify the cpu is imx6q or imx6sdl
  77635. + */
  77636. + if (of_id)
  77637. + pdev->id_entry = of_id->data;
  77638. + cam->devtype = pdev->id_entry->driver_data;
  77639. +
  77640. + cam->ipu = ipu_get_soc(ipu_id);
  77641. + if (cam->ipu == NULL) {
  77642. + pr_err("ERROR: v4l2 capture: failed to get ipu\n");
  77643. + return -EINVAL;
  77644. + } else if (cam->ipu == ERR_PTR(-ENODEV)) {
  77645. + pr_err("ERROR: v4l2 capture: get invalid ipu\n");
  77646. + return -ENODEV;
  77647. + }
  77648. +
  77649. + init_MUTEX(&cam->param_lock);
  77650. + init_MUTEX(&cam->busy_lock);
  77651. +
  77652. + cam->video_dev = video_device_alloc();
  77653. + if (cam->video_dev == NULL)
  77654. + return -ENODEV;
  77655. +
  77656. + *(cam->video_dev) = mxc_v4l_template;
  77657. +
  77658. + video_set_drvdata(cam->video_dev, cam);
  77659. + dev_set_drvdata(&pdev->dev, (void *)cam);
  77660. + cam->video_dev->minor = -1;
  77661. +
  77662. + init_waitqueue_head(&cam->enc_queue);
  77663. + init_waitqueue_head(&cam->still_queue);
  77664. +
  77665. + /* setup cropping */
  77666. + cam->crop_bounds.left = 0;
  77667. + cam->crop_bounds.width = 640;
  77668. + cam->crop_bounds.top = 0;
  77669. + cam->crop_bounds.height = 480;
  77670. + cam->crop_current = cam->crop_defrect = cam->crop_bounds;
  77671. + ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
  77672. + cam->crop_current.height, cam->csi);
  77673. + ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
  77674. + cam->crop_current.top, cam->csi);
  77675. + cam->streamparm.parm.capture.capturemode = 0;
  77676. +
  77677. + cam->standard.index = 0;
  77678. + cam->standard.id = V4L2_STD_UNKNOWN;
  77679. + cam->standard.frameperiod.denominator = 30;
  77680. + cam->standard.frameperiod.numerator = 1;
  77681. + cam->standard.framelines = 480;
  77682. + cam->standard_autodetect = true;
  77683. + cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  77684. + cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
  77685. + cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
  77686. + cam->overlay_on = false;
  77687. + cam->capture_on = false;
  77688. + cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
  77689. +
  77690. + cam->v2f.fmt.pix.sizeimage = 352 * 288 * 3 / 2;
  77691. + cam->v2f.fmt.pix.bytesperline = 288 * 3 / 2;
  77692. + cam->v2f.fmt.pix.width = 288;
  77693. + cam->v2f.fmt.pix.height = 352;
  77694. + cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
  77695. + cam->win.w.width = 160;
  77696. + cam->win.w.height = 160;
  77697. + cam->win.w.left = 0;
  77698. + cam->win.w.top = 0;
  77699. +
  77700. + cam->ipu_id = ipu_id;
  77701. + cam->csi = csi_id;
  77702. + cam->mclk_source = mclk_source;
  77703. + cam->mclk_on[cam->mclk_source] = false;
  77704. +
  77705. + cam->enc_callback = camera_callback;
  77706. + init_waitqueue_head(&cam->power_queue);
  77707. + spin_lock_init(&cam->queue_int_lock);
  77708. + spin_lock_init(&cam->dqueue_int_lock);
  77709. +
  77710. + cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
  77711. + cam->self->module = THIS_MODULE;
  77712. + sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
  77713. + cam->self->type = v4l2_int_type_master;
  77714. + cam->self->u.master = &mxc_v4l2_master;
  77715. +
  77716. + return 0;
  77717. +}
  77718. +
  77719. +static ssize_t show_streaming(struct device *dev,
  77720. + struct device_attribute *attr, char *buf)
  77721. +{
  77722. + struct video_device *video_dev = container_of(dev,
  77723. + struct video_device, dev);
  77724. + cam_data *cam = video_get_drvdata(video_dev);
  77725. +
  77726. + if (cam->capture_on)
  77727. + return sprintf(buf, "stream on\n");
  77728. + else
  77729. + return sprintf(buf, "stream off\n");
  77730. +}
  77731. +static DEVICE_ATTR(fsl_v4l2_capture_property, S_IRUGO, show_streaming, NULL);
  77732. +
  77733. +static ssize_t show_overlay(struct device *dev,
  77734. + struct device_attribute *attr, char *buf)
  77735. +{
  77736. + struct video_device *video_dev = container_of(dev,
  77737. + struct video_device, dev);
  77738. + cam_data *cam = video_get_drvdata(video_dev);
  77739. +
  77740. + if (cam->overlay_on)
  77741. + return sprintf(buf, "overlay on\n");
  77742. + else
  77743. + return sprintf(buf, "overlay off\n");
  77744. +}
  77745. +static DEVICE_ATTR(fsl_v4l2_overlay_property, S_IRUGO, show_overlay, NULL);
  77746. +
  77747. +static ssize_t show_csi(struct device *dev,
  77748. + struct device_attribute *attr, char *buf)
  77749. +{
  77750. + struct video_device *video_dev = container_of(dev,
  77751. + struct video_device, dev);
  77752. + cam_data *cam = video_get_drvdata(video_dev);
  77753. +
  77754. + return sprintf(buf, "ipu%d_csi%d\n", cam->ipu_id, cam->csi);
  77755. +}
  77756. +static DEVICE_ATTR(fsl_csi_property, S_IRUGO, show_csi, NULL);
  77757. +
  77758. +/*!
  77759. + * This function is called to probe the devices if registered.
  77760. + *
  77761. + * @param pdev the device structure used to give information on which device
  77762. + * to probe
  77763. + *
  77764. + * @return The function returns 0 on success and -1 on failure.
  77765. + */
  77766. +static int mxc_v4l2_probe(struct platform_device *pdev)
  77767. +{
  77768. + /* Create cam and initialize it. */
  77769. + cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
  77770. + if (cam == NULL) {
  77771. + pr_err("ERROR: v4l2 capture: failed to register camera\n");
  77772. + return -1;
  77773. + }
  77774. +
  77775. + init_camera_struct(cam, pdev);
  77776. + pdev->dev.release = camera_platform_release;
  77777. +
  77778. + /* Set up the v4l2 device and register it*/
  77779. + cam->self->priv = cam;
  77780. + v4l2_int_device_register(cam->self);
  77781. +
  77782. + /* register v4l video device */
  77783. + if (video_register_device(cam->video_dev, VFL_TYPE_GRABBER, video_nr)
  77784. + == -1) {
  77785. + kfree(cam);
  77786. + cam = NULL;
  77787. + pr_err("ERROR: v4l2 capture: video_register_device failed\n");
  77788. + return -1;
  77789. + }
  77790. + pr_debug(" Video device registered: %s #%d\n",
  77791. + cam->video_dev->name, cam->video_dev->minor);
  77792. +
  77793. + if (device_create_file(&cam->video_dev->dev,
  77794. + &dev_attr_fsl_v4l2_capture_property))
  77795. + dev_err(&pdev->dev, "Error on creating sysfs file"
  77796. + " for capture\n");
  77797. +
  77798. + if (device_create_file(&cam->video_dev->dev,
  77799. + &dev_attr_fsl_v4l2_overlay_property))
  77800. + dev_err(&pdev->dev, "Error on creating sysfs file"
  77801. + " for overlay\n");
  77802. +
  77803. + if (device_create_file(&cam->video_dev->dev,
  77804. + &dev_attr_fsl_csi_property))
  77805. + dev_err(&pdev->dev, "Error on creating sysfs file"
  77806. + " for csi number\n");
  77807. +
  77808. + return 0;
  77809. +}
  77810. +
  77811. +/*!
  77812. + * This function is called to remove the devices when device unregistered.
  77813. + *
  77814. + * @param pdev the device structure used to give information on which device
  77815. + * to remove
  77816. + *
  77817. + * @return The function returns 0 on success and -1 on failure.
  77818. + */
  77819. +static int mxc_v4l2_remove(struct platform_device *pdev)
  77820. +{
  77821. + cam_data *cam = (cam_data *)platform_get_drvdata(pdev);
  77822. + if (cam->open_count) {
  77823. + pr_err("ERROR: v4l2 capture:camera open "
  77824. + "-- setting ops to NULL\n");
  77825. + return -EBUSY;
  77826. + } else {
  77827. + device_remove_file(&cam->video_dev->dev,
  77828. + &dev_attr_fsl_v4l2_capture_property);
  77829. + device_remove_file(&cam->video_dev->dev,
  77830. + &dev_attr_fsl_v4l2_overlay_property);
  77831. + device_remove_file(&cam->video_dev->dev,
  77832. + &dev_attr_fsl_csi_property);
  77833. +
  77834. + pr_info("V4L2 freeing image input device\n");
  77835. + v4l2_int_device_unregister(cam->self);
  77836. + video_unregister_device(cam->video_dev);
  77837. +
  77838. + mxc_free_frame_buf(cam);
  77839. + kfree(cam);
  77840. + }
  77841. +
  77842. + pr_info("V4L2 unregistering video\n");
  77843. + return 0;
  77844. +}
  77845. +
  77846. +/*!
  77847. + * This function is called to put the sensor in a low power state.
  77848. + * Refer to the document driver-model/driver.txt in the kernel source tree
  77849. + * for more information.
  77850. + *
  77851. + * @param pdev the device structure used to give information on which I2C
  77852. + * to suspend
  77853. + * @param state the power state the device is entering
  77854. + *
  77855. + * @return The function returns 0 on success and -1 on failure.
  77856. + */
  77857. +static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
  77858. +{
  77859. + cam_data *cam = platform_get_drvdata(pdev);
  77860. +
  77861. + pr_debug("In MVC:mxc_v4l2_suspend\n");
  77862. +
  77863. + if (cam == NULL)
  77864. + return -1;
  77865. +
  77866. + down(&cam->busy_lock);
  77867. +
  77868. + cam->low_power = true;
  77869. +
  77870. + if (cam->overlay_on == true)
  77871. + stop_preview(cam);
  77872. + if ((cam->capture_on == true) && cam->enc_disable)
  77873. + cam->enc_disable(cam);
  77874. +
  77875. + if (cam->sensor && cam->open_count) {
  77876. + if (cam->mclk_on[cam->mclk_source]) {
  77877. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  77878. + cam->mclk_source,
  77879. + false, false);
  77880. + cam->mclk_on[cam->mclk_source] = false;
  77881. + }
  77882. + vidioc_int_s_power(cam->sensor, 0);
  77883. + }
  77884. +
  77885. + up(&cam->busy_lock);
  77886. +
  77887. + return 0;
  77888. +}
  77889. +
  77890. +/*!
  77891. + * This function is called to bring the sensor back from a low power state.
  77892. + * Refer to the document driver-model/driver.txt in the kernel source tree
  77893. + * for more information.
  77894. + *
  77895. + * @param pdev the device structure
  77896. + *
  77897. + * @return The function returns 0 on success and -1 on failure
  77898. + */
  77899. +static int mxc_v4l2_resume(struct platform_device *pdev)
  77900. +{
  77901. + cam_data *cam = platform_get_drvdata(pdev);
  77902. +
  77903. + pr_debug("In MVC:mxc_v4l2_resume\n");
  77904. +
  77905. + if (cam == NULL)
  77906. + return -1;
  77907. +
  77908. + down(&cam->busy_lock);
  77909. +
  77910. + cam->low_power = false;
  77911. + wake_up_interruptible(&cam->power_queue);
  77912. +
  77913. + if (cam->sensor && cam->open_count) {
  77914. + vidioc_int_s_power(cam->sensor, 1);
  77915. +
  77916. + if (!cam->mclk_on[cam->mclk_source]) {
  77917. + ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
  77918. + cam->mclk_source,
  77919. + true, true);
  77920. + cam->mclk_on[cam->mclk_source] = true;
  77921. + }
  77922. + }
  77923. +
  77924. + if (cam->overlay_on == true)
  77925. + start_preview(cam);
  77926. + if (cam->capture_on == true)
  77927. + mxc_streamon(cam);
  77928. +
  77929. + up(&cam->busy_lock);
  77930. +
  77931. + return 0;
  77932. +}
  77933. +
  77934. +/*!
  77935. + * This structure contains pointers to the power management callback functions.
  77936. + */
  77937. +static struct platform_driver mxc_v4l2_driver = {
  77938. + .driver = {
  77939. + .name = "mxc_v4l2_capture",
  77940. + .owner = THIS_MODULE,
  77941. + .of_match_table = mxc_v4l2_dt_ids,
  77942. + },
  77943. + .id_table = imx_v4l2_devtype,
  77944. + .probe = mxc_v4l2_probe,
  77945. + .remove = mxc_v4l2_remove,
  77946. + .suspend = mxc_v4l2_suspend,
  77947. + .resume = mxc_v4l2_resume,
  77948. + .shutdown = NULL,
  77949. +};
  77950. +
  77951. +/*!
  77952. + * Initializes the camera driver.
  77953. + */
  77954. +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
  77955. +{
  77956. + cam_data *cam = slave->u.slave->master->priv;
  77957. + struct v4l2_format cam_fmt;
  77958. + int i;
  77959. + struct sensor_data *sdata = slave->priv;
  77960. +
  77961. + pr_debug("In MVC: mxc_v4l2_master_attach\n");
  77962. + pr_debug(" slave.name = %s\n", slave->name);
  77963. + pr_debug(" master.name = %s\n", slave->u.slave->master->name);
  77964. +
  77965. + if (slave == NULL) {
  77966. + pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
  77967. + return -1;
  77968. + }
  77969. +
  77970. + if (sdata->csi != cam->csi) {
  77971. + pr_debug("%s: csi doesn't match\n", __func__);
  77972. + return -1;
  77973. + }
  77974. +
  77975. + cam->sensor = slave;
  77976. +
  77977. + if (cam->sensor_index < MXC_SENSOR_NUM) {
  77978. + cam->all_sensors[cam->sensor_index] = slave;
  77979. + cam->sensor_index++;
  77980. + } else {
  77981. + pr_err("ERROR: v4l2 capture: slave number exceeds the maximum.\n");
  77982. + return -1;
  77983. + }
  77984. +
  77985. + for (i = 0; i < cam->sensor_index; i++) {
  77986. + vidioc_int_dev_exit(cam->all_sensors[i]);
  77987. + vidioc_int_s_power(cam->all_sensors[i], 0);
  77988. + }
  77989. +
  77990. + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  77991. + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
  77992. +
  77993. + /* Used to detect TV in (type 1) vs. camera (type 0)*/
  77994. + cam->device_type = cam_fmt.fmt.pix.priv;
  77995. +
  77996. + /* Set the input size to the ipu for this device */
  77997. + cam->crop_bounds.top = cam->crop_bounds.left = 0;
  77998. + cam->crop_bounds.width = cam_fmt.fmt.pix.width;
  77999. + cam->crop_bounds.height = cam_fmt.fmt.pix.height;
  78000. +
  78001. + /* This also is the max crop size for this device. */
  78002. + cam->crop_defrect.top = cam->crop_defrect.left = 0;
  78003. + cam->crop_defrect.width = cam_fmt.fmt.pix.width;
  78004. + cam->crop_defrect.height = cam_fmt.fmt.pix.height;
  78005. +
  78006. + /* At this point, this is also the current image size. */
  78007. + cam->crop_current.top = cam->crop_current.left = 0;
  78008. + cam->crop_current.width = cam_fmt.fmt.pix.width;
  78009. + cam->crop_current.height = cam_fmt.fmt.pix.height;
  78010. +
  78011. + pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
  78012. + __func__,
  78013. + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
  78014. + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
  78015. + __func__,
  78016. + cam->crop_bounds.width, cam->crop_bounds.height);
  78017. + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
  78018. + __func__,
  78019. + cam->crop_defrect.width, cam->crop_defrect.height);
  78020. + pr_debug("End of %s: crop_current widthxheight %d x %d\n",
  78021. + __func__,
  78022. + cam->crop_current.width, cam->crop_current.height);
  78023. +
  78024. + return 0;
  78025. +}
  78026. +
  78027. +/*!
  78028. + * Disconnects the camera driver.
  78029. + */
  78030. +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave)
  78031. +{
  78032. + unsigned int i;
  78033. + cam_data *cam = slave->u.slave->master->priv;
  78034. +
  78035. + pr_debug("In MVC:mxc_v4l2_master_detach\n");
  78036. +
  78037. + if (cam->sensor_index > 1) {
  78038. + for (i = 0; i < cam->sensor_index; i++) {
  78039. + if (cam->all_sensors[i] != slave)
  78040. + continue;
  78041. + /* Move all the sensors behind this
  78042. + * sensor one step forward
  78043. + */
  78044. + for (; i <= MXC_SENSOR_NUM - 2; i++)
  78045. + cam->all_sensors[i] = cam->all_sensors[i+1];
  78046. + break;
  78047. + }
  78048. + /* Point current sensor to the last one */
  78049. + cam->sensor = cam->all_sensors[cam->sensor_index - 2];
  78050. + } else
  78051. + cam->sensor = NULL;
  78052. +
  78053. + cam->sensor_index--;
  78054. + vidioc_int_dev_exit(slave);
  78055. +}
  78056. +
  78057. +/*!
  78058. + * Entry point for the V4L2
  78059. + *
  78060. + * @return Error code indicating success or failure
  78061. + */
  78062. +static __init int camera_init(void)
  78063. +{
  78064. + u8 err = 0;
  78065. +
  78066. + pr_debug("In MVC:camera_init\n");
  78067. +
  78068. + /* Register the device driver structure. */
  78069. + err = platform_driver_register(&mxc_v4l2_driver);
  78070. + if (err != 0) {
  78071. + pr_err("ERROR: v4l2 capture:camera_init: "
  78072. + "platform_driver_register failed.\n");
  78073. + return err;
  78074. + }
  78075. +
  78076. + return err;
  78077. +}
  78078. +
  78079. +/*!
  78080. + * Exit and cleanup for the V4L2
  78081. + */
  78082. +static void __exit camera_exit(void)
  78083. +{
  78084. + pr_debug("In MVC: camera_exit\n");
  78085. +
  78086. + platform_driver_unregister(&mxc_v4l2_driver);
  78087. +}
  78088. +
  78089. +module_init(camera_init);
  78090. +module_exit(camera_exit);
  78091. +
  78092. +module_param(video_nr, int, 0444);
  78093. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  78094. +MODULE_DESCRIPTION("V4L2 capture driver for Mxc based cameras");
  78095. +MODULE_LICENSE("GPL");
  78096. +MODULE_SUPPORTED_DEVICE("video");
  78097. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
  78098. --- linux-3.14.17/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h 1970-01-01 01:00:00.000000000 +0100
  78099. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h 2014-09-11 18:06:02.254038983 +0200
  78100. @@ -0,0 +1,260 @@
  78101. +/*
  78102. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  78103. + */
  78104. +
  78105. +/*
  78106. + * The code contained herein is licensed under the GNU General Public
  78107. + * License. You may obtain a copy of the GNU General Public License
  78108. + * Version 2 or later at the following locations:
  78109. + *
  78110. + * http://www.opensource.org/licenses/gpl-license.html
  78111. + * http://www.gnu.org/copyleft/gpl.html
  78112. + */
  78113. +
  78114. +/*!
  78115. + * @defgroup MXC_V4L2_CAPTURE MXC V4L2 Video Capture Driver
  78116. + */
  78117. +/*!
  78118. + * @file mxc_v4l2_capture.h
  78119. + *
  78120. + * @brief mxc V4L2 capture device API Header file
  78121. + *
  78122. + * It include all the defines for frame operations, also three structure defines
  78123. + * use case ops structure, common v4l2 driver structure and frame structure.
  78124. + *
  78125. + * @ingroup MXC_V4L2_CAPTURE
  78126. + */
  78127. +#ifndef __MXC_V4L2_CAPTURE_H__
  78128. +#define __MXC_V4L2_CAPTURE_H__
  78129. +
  78130. +#include <linux/uaccess.h>
  78131. +#include <linux/list.h>
  78132. +#include <linux/mxc_v4l2.h>
  78133. +#include <linux/completion.h>
  78134. +#include <linux/dmaengine.h>
  78135. +#include <linux/pxp_dma.h>
  78136. +#include <linux/ipu-v3.h>
  78137. +#include <linux/platform_data/dma-imx.h>
  78138. +
  78139. +#include <media/v4l2-dev.h>
  78140. +#include <media/v4l2-int-device.h>
  78141. +
  78142. +
  78143. +#define FRAME_NUM 10
  78144. +#define MXC_SENSOR_NUM 2
  78145. +
  78146. +enum imx_v4l2_devtype {
  78147. + IMX5_V4L2,
  78148. + IMX6_V4L2,
  78149. +};
  78150. +
  78151. +/*!
  78152. + * v4l2 frame structure.
  78153. + */
  78154. +struct mxc_v4l_frame {
  78155. + u32 paddress;
  78156. + void *vaddress;
  78157. + int count;
  78158. + int width;
  78159. + int height;
  78160. +
  78161. + struct v4l2_buffer buffer;
  78162. + struct list_head queue;
  78163. + int index;
  78164. + union {
  78165. + int ipu_buf_num;
  78166. + int csi_buf_num;
  78167. + };
  78168. +};
  78169. +
  78170. +/* Only for old version. Will go away soon. */
  78171. +typedef struct {
  78172. + u8 clk_mode;
  78173. + u8 ext_vsync;
  78174. + u8 Vsync_pol;
  78175. + u8 Hsync_pol;
  78176. + u8 pixclk_pol;
  78177. + u8 data_pol;
  78178. + u8 data_width;
  78179. + u8 pack_tight;
  78180. + u8 force_eof;
  78181. + u8 data_en_pol;
  78182. + u16 width;
  78183. + u16 height;
  78184. + u32 pixel_fmt;
  78185. + u32 mclk;
  78186. + u16 active_width;
  78187. + u16 active_height;
  78188. +} sensor_interface;
  78189. +
  78190. +/* Sensor control function */
  78191. +/* Only for old version. Will go away soon. */
  78192. +struct camera_sensor {
  78193. + void (*set_color) (int bright, int saturation, int red, int green,
  78194. + int blue);
  78195. + void (*get_color) (int *bright, int *saturation, int *red, int *green,
  78196. + int *blue);
  78197. + void (*set_ae_mode) (int ae_mode);
  78198. + void (*get_ae_mode) (int *ae_mode);
  78199. + sensor_interface *(*config) (int *frame_rate, int high_quality);
  78200. + sensor_interface *(*reset) (void);
  78201. + void (*get_std) (v4l2_std_id *std);
  78202. + void (*set_std) (v4l2_std_id std);
  78203. + unsigned int csi;
  78204. +};
  78205. +
  78206. +/*!
  78207. + * common v4l2 driver structure.
  78208. + */
  78209. +typedef struct _cam_data {
  78210. + struct video_device *video_dev;
  78211. + int device_type;
  78212. +
  78213. + /* semaphore guard against SMP multithreading */
  78214. + struct semaphore busy_lock;
  78215. +
  78216. + int open_count;
  78217. +
  78218. + /* params lock for this camera */
  78219. + struct semaphore param_lock;
  78220. +
  78221. + /* Encoder */
  78222. + struct list_head ready_q;
  78223. + struct list_head done_q;
  78224. + struct list_head working_q;
  78225. + int ping_pong_csi;
  78226. + spinlock_t queue_int_lock;
  78227. + spinlock_t dqueue_int_lock;
  78228. + struct mxc_v4l_frame frame[FRAME_NUM];
  78229. + struct mxc_v4l_frame dummy_frame;
  78230. + wait_queue_head_t enc_queue;
  78231. + int enc_counter;
  78232. + dma_addr_t rot_enc_bufs[2];
  78233. + void *rot_enc_bufs_vaddr[2];
  78234. + int rot_enc_buf_size[2];
  78235. + enum v4l2_buf_type type;
  78236. +
  78237. + /* still image capture */
  78238. + wait_queue_head_t still_queue;
  78239. + int still_counter;
  78240. + dma_addr_t still_buf[2];
  78241. + void *still_buf_vaddr;
  78242. +
  78243. + /* overlay */
  78244. + struct v4l2_window win;
  78245. + struct v4l2_framebuffer v4l2_fb;
  78246. + dma_addr_t vf_bufs[2];
  78247. + void *vf_bufs_vaddr[2];
  78248. + int vf_bufs_size[2];
  78249. + dma_addr_t rot_vf_bufs[2];
  78250. + void *rot_vf_bufs_vaddr[2];
  78251. + int rot_vf_buf_size[2];
  78252. + bool overlay_active;
  78253. + int output;
  78254. + struct fb_info *overlay_fb;
  78255. + int fb_origin_std;
  78256. + struct work_struct csi_work_struct;
  78257. +
  78258. + /* v4l2 format */
  78259. + struct v4l2_format v2f;
  78260. + int rotation; /* for IPUv1 and IPUv3, this means encoder rotation */
  78261. + int vf_rotation; /* viewfinder rotation only for IPUv1 and IPUv3 */
  78262. + struct v4l2_mxc_offset offset;
  78263. +
  78264. + /* V4l2 control bit */
  78265. + int bright;
  78266. + int hue;
  78267. + int contrast;
  78268. + int saturation;
  78269. + int red;
  78270. + int green;
  78271. + int blue;
  78272. + int ae_mode;
  78273. +
  78274. + /* standard */
  78275. + struct v4l2_streamparm streamparm;
  78276. + struct v4l2_standard standard;
  78277. + bool standard_autodetect;
  78278. +
  78279. + /* crop */
  78280. + struct v4l2_rect crop_bounds;
  78281. + struct v4l2_rect crop_defrect;
  78282. + struct v4l2_rect crop_current;
  78283. +
  78284. + int (*enc_update_eba) (struct ipu_soc *ipu, dma_addr_t eba,
  78285. + int *bufferNum);
  78286. + int (*enc_enable) (void *private);
  78287. + int (*enc_disable) (void *private);
  78288. + int (*enc_enable_csi) (void *private);
  78289. + int (*enc_disable_csi) (void *private);
  78290. + void (*enc_callback) (u32 mask, void *dev);
  78291. + int (*vf_start_adc) (void *private);
  78292. + int (*vf_stop_adc) (void *private);
  78293. + int (*vf_start_sdc) (void *private);
  78294. + int (*vf_stop_sdc) (void *private);
  78295. + int (*vf_enable_csi) (void *private);
  78296. + int (*vf_disable_csi) (void *private);
  78297. + int (*csi_start) (void *private);
  78298. + int (*csi_stop) (void *private);
  78299. +
  78300. + /* misc status flag */
  78301. + bool overlay_on;
  78302. + bool capture_on;
  78303. + int overlay_pid;
  78304. + int capture_pid;
  78305. + bool low_power;
  78306. + wait_queue_head_t power_queue;
  78307. + unsigned int ipu_id;
  78308. + unsigned int csi;
  78309. + u8 mclk_source;
  78310. + bool mclk_on[2]; /* two mclk sources at most now */
  78311. + int current_input;
  78312. +
  78313. + int local_buf_num;
  78314. +
  78315. + /* camera sensor interface */
  78316. + struct camera_sensor *cam_sensor; /* old version */
  78317. + struct v4l2_int_device *all_sensors[MXC_SENSOR_NUM];
  78318. + struct v4l2_int_device *sensor;
  78319. + struct v4l2_int_device *self;
  78320. + int sensor_index;
  78321. + void *ipu;
  78322. + enum imx_v4l2_devtype devtype;
  78323. +
  78324. + /* v4l2 buf elements related to PxP DMA */
  78325. + struct completion pxp_tx_cmpl;
  78326. + struct pxp_channel *pxp_chan;
  78327. + struct pxp_config_data pxp_conf;
  78328. + struct dma_async_tx_descriptor *txd;
  78329. + dma_cookie_t cookie;
  78330. + struct scatterlist sg[2];
  78331. +} cam_data;
  78332. +
  78333. +struct sensor_data {
  78334. + const struct ov5642_platform_data *platform_data;
  78335. + struct v4l2_int_device *v4l2_int_device;
  78336. + struct i2c_client *i2c_client;
  78337. + struct v4l2_pix_format pix;
  78338. + struct v4l2_captureparm streamcap;
  78339. + bool on;
  78340. +
  78341. + /* control settings */
  78342. + int brightness;
  78343. + int hue;
  78344. + int contrast;
  78345. + int saturation;
  78346. + int red;
  78347. + int green;
  78348. + int blue;
  78349. + int ae_mode;
  78350. +
  78351. + u32 mclk;
  78352. + u8 mclk_source;
  78353. + struct clk *sensor_clk;
  78354. + int csi;
  78355. +
  78356. + void (*io_init)(void);
  78357. +};
  78358. +
  78359. +void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi);
  78360. +#endif /* __MXC_V4L2_CAPTURE_H__ */
  78361. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ov5640.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640.c
  78362. --- linux-3.14.17/drivers/media/platform/mxc/capture/ov5640.c 1970-01-01 01:00:00.000000000 +0100
  78363. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640.c 2014-09-11 18:06:02.254038983 +0200
  78364. @@ -0,0 +1,1951 @@
  78365. +/*
  78366. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  78367. + */
  78368. +
  78369. +/*
  78370. + * This program is free software; you can redistribute it and/or modify
  78371. + * it under the terms of the GNU General Public License as published by
  78372. + * the Free Software Foundation; either version 2 of the License, or
  78373. + * (at your option) any later version.
  78374. +
  78375. + * This program is distributed in the hope that it will be useful,
  78376. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  78377. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  78378. + * GNU General Public License for more details.
  78379. +
  78380. + * You should have received a copy of the GNU General Public License along
  78381. + * with this program; if not, write to the Free Software Foundation, Inc.,
  78382. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  78383. + */
  78384. +
  78385. +#include <linux/clk.h>
  78386. +#include <linux/delay.h>
  78387. +#include <linux/device.h>
  78388. +#include <linux/i2c.h>
  78389. +#include <linux/init.h>
  78390. +#include <linux/module.h>
  78391. +#include <linux/of_device.h>
  78392. +#include <linux/of_gpio.h>
  78393. +#include <linux/pinctrl/consumer.h>
  78394. +#include <linux/regulator/consumer.h>
  78395. +#include <media/v4l2-chip-ident.h>
  78396. +#include <media/v4l2-int-device.h>
  78397. +#include "mxc_v4l2_capture.h"
  78398. +
  78399. +#define OV5640_VOLTAGE_ANALOG 2800000
  78400. +#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
  78401. +#define OV5640_VOLTAGE_DIGITAL_IO 1800000
  78402. +
  78403. +#define MIN_FPS 15
  78404. +#define MAX_FPS 30
  78405. +#define DEFAULT_FPS 30
  78406. +
  78407. +#define OV5640_XCLK_MIN 6000000
  78408. +#define OV5640_XCLK_MAX 24000000
  78409. +
  78410. +#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
  78411. +#define OV5640_CHIP_ID_LOW_BYTE 0x300B
  78412. +
  78413. +enum ov5640_mode {
  78414. + ov5640_mode_MIN = 0,
  78415. + ov5640_mode_VGA_640_480 = 0,
  78416. + ov5640_mode_QVGA_320_240 = 1,
  78417. + ov5640_mode_NTSC_720_480 = 2,
  78418. + ov5640_mode_PAL_720_576 = 3,
  78419. + ov5640_mode_720P_1280_720 = 4,
  78420. + ov5640_mode_1080P_1920_1080 = 5,
  78421. + ov5640_mode_QSXGA_2592_1944 = 6,
  78422. + ov5640_mode_QCIF_176_144 = 7,
  78423. + ov5640_mode_XGA_1024_768 = 8,
  78424. + ov5640_mode_MAX = 8
  78425. +};
  78426. +
  78427. +enum ov5640_frame_rate {
  78428. + ov5640_15_fps,
  78429. + ov5640_30_fps
  78430. +};
  78431. +
  78432. +static int ov5640_framerates[] = {
  78433. + [ov5640_15_fps] = 15,
  78434. + [ov5640_30_fps] = 30,
  78435. +};
  78436. +
  78437. +struct reg_value {
  78438. + u16 u16RegAddr;
  78439. + u8 u8Val;
  78440. + u8 u8Mask;
  78441. + u32 u32Delay_ms;
  78442. +};
  78443. +
  78444. +struct ov5640_mode_info {
  78445. + enum ov5640_mode mode;
  78446. + u32 width;
  78447. + u32 height;
  78448. + struct reg_value *init_data_ptr;
  78449. + u32 init_data_size;
  78450. +};
  78451. +
  78452. +/*!
  78453. + * Maintains the information on the current state of the sesor.
  78454. + */
  78455. +static struct sensor_data ov5640_data;
  78456. +static int pwn_gpio, rst_gpio;
  78457. +static int prev_sysclk;
  78458. +static int AE_Target = 52, night_mode;
  78459. +static int prev_HTS;
  78460. +static int AE_high, AE_low;
  78461. +
  78462. +static struct reg_value ov5640_global_init_setting[] = {
  78463. + {0x3008, 0x42, 0, 0},
  78464. + {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
  78465. + {0x3034, 0x1a, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0},
  78466. + {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0},
  78467. + {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0},
  78468. + {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0},
  78469. + {0x370b, 0x60, 0, 0}, {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0},
  78470. + {0x3906, 0x10, 0, 0}, {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0},
  78471. + {0x3600, 0x08, 0, 0}, {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0},
  78472. + {0x3620, 0x52, 0, 0}, {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0},
  78473. + {0x3a13, 0x43, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  78474. + {0x3635, 0x13, 0, 0}, {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0},
  78475. + {0x3622, 0x01, 0, 0}, {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0},
  78476. + {0x3c05, 0x98, 0, 0}, {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0},
  78477. + {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0},
  78478. + {0x3c0b, 0x40, 0, 0}, {0x3810, 0x00, 0, 0}, {0x3811, 0x10, 0, 0},
  78479. + {0x3812, 0x00, 0, 0}, {0x3708, 0x64, 0, 0}, {0x4001, 0x02, 0, 0},
  78480. + {0x4005, 0x1a, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  78481. + {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
  78482. + {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x5000, 0xa7, 0, 0},
  78483. + {0x3008, 0x02, 0, 0},
  78484. +};
  78485. +
  78486. +static struct reg_value ov5640_init_setting_30fps_VGA[] = {
  78487. + {0x3008, 0x42, 0, 0},
  78488. + {0x3103, 0x03, 0, 0}, {0x3017, 0xff, 0, 0}, {0x3018, 0xff, 0, 0},
  78489. + {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x46, 0, 0},
  78490. + {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
  78491. + {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
  78492. + {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
  78493. + {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
  78494. + {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
  78495. + {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
  78496. + {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
  78497. + {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
  78498. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
  78499. + {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
  78500. + {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
  78501. + {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
  78502. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  78503. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78504. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78505. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  78506. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  78507. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  78508. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  78509. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  78510. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  78511. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  78512. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  78513. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  78514. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  78515. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  78516. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
  78517. + {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
  78518. + {0x300e, 0x58, 0, 0}, {0x302e, 0x00, 0, 0}, {0x4300, 0x30, 0, 0},
  78519. + {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
  78520. + {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  78521. + {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0}, {0x5000, 0xa7, 0, 0},
  78522. + {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
  78523. + {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  78524. + {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
  78525. + {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0}, {0x518a, 0x54, 0, 0},
  78526. + {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x50, 0, 0},
  78527. + {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0}, {0x5190, 0x46, 0, 0},
  78528. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  78529. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  78530. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x6c, 0, 0},
  78531. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x09, 0, 0},
  78532. + {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
  78533. + {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
  78534. + {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
  78535. + {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
  78536. + {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
  78537. + {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
  78538. + {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
  78539. + {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
  78540. + {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
  78541. + {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
  78542. + {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
  78543. + {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
  78544. + {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
  78545. + {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
  78546. + {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
  78547. + {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
  78548. + {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
  78549. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
  78550. + {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
  78551. + {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
  78552. + {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
  78553. + {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
  78554. + {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
  78555. + {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
  78556. + {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
  78557. + {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
  78558. + {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
  78559. + {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
  78560. + {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
  78561. + {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
  78562. + {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
  78563. + {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
  78564. + {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
  78565. + {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
  78566. + {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
  78567. + {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
  78568. + {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
  78569. + {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
  78570. + {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
  78571. + {0x3008, 0x02, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  78572. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78573. +};
  78574. +
  78575. +static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
  78576. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78577. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78578. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78579. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78580. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  78581. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  78582. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78583. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78584. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78585. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78586. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78587. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78588. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78589. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  78590. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
  78591. +};
  78592. +
  78593. +static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
  78594. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78595. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78596. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78597. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78598. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  78599. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  78600. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78601. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78602. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78603. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78604. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78605. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78606. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78607. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78608. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0}, {0x3503, 0x00, 0, 0},
  78609. +};
  78610. +
  78611. +static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
  78612. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78613. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78614. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78615. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78616. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
  78617. + {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
  78618. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78619. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78620. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78621. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78622. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78623. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78624. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78625. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  78626. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78627. +};
  78628. +
  78629. +static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
  78630. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78631. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78632. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78633. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78634. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0},
  78635. + {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0},
  78636. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78637. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78638. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78639. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78640. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78641. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78642. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78643. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78644. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78645. +};
  78646. +
  78647. +static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
  78648. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78649. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78650. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78651. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
  78652. + {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  78653. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  78654. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78655. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78656. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78657. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78658. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78659. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78660. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78661. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  78662. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78663. +};
  78664. +
  78665. +static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
  78666. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78667. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78668. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78669. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0},
  78670. + {0x3807, 0xd4, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  78671. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0},
  78672. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78673. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78674. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78675. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78676. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78677. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78678. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78679. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78680. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78681. +};
  78682. +
  78683. +static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
  78684. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78685. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78686. + {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78687. + {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
  78688. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  78689. + {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
  78690. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78691. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78692. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78693. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78694. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78695. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78696. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78697. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  78698. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78699. +};
  78700. +
  78701. +static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
  78702. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78703. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78704. + {0x3801, 0x60, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78705. + {0x3804, 0x09, 0, 0}, {0x3805, 0x7e, 0, 0}, {0x3806, 0x07, 0, 0},
  78706. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0},
  78707. + {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0},
  78708. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78709. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78710. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78711. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78712. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78713. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78714. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78715. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78716. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78717. +};
  78718. +
  78719. +static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
  78720. + {0x3035, 0x21, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
  78721. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78722. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78723. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  78724. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  78725. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  78726. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  78727. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
  78728. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
  78729. + {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
  78730. + {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
  78731. + {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
  78732. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  78733. + {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  78734. + {0x3503, 0x00, 0, 0},
  78735. +};
  78736. +
  78737. +static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
  78738. + {0x3035, 0x41, 0, 0}, {0x3036, 0x69, 0, 0}, {0x3c07, 0x07, 0, 0},
  78739. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  78740. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  78741. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  78742. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  78743. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  78744. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  78745. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3813, 0x04, 0, 0},
  78746. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3709, 0x52, 0, 0},
  78747. + {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe0, 0, 0},
  78748. + {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe0, 0, 0}, {0x4004, 0x02, 0, 0},
  78749. + {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x4713, 0x03, 0, 0},
  78750. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  78751. + {0x4837, 0x16, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  78752. + {0x3503, 0x00, 0, 0},
  78753. +};
  78754. +
  78755. +static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
  78756. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78757. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78758. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78759. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78760. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
  78761. + {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
  78762. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78763. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78764. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78765. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78766. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78767. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78768. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78769. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x11, 0, 0},
  78770. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78771. +};
  78772. +
  78773. +static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
  78774. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78775. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78776. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78777. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78778. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0},
  78779. + {0x380a, 0x00, 0, 0}, {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0},
  78780. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78781. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78782. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78783. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78784. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78785. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78786. + {0x460c, 0x22, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x02, 0, 0},
  78787. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78788. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78789. +};
  78790. +
  78791. +static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
  78792. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78793. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78794. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78795. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78796. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
  78797. + {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
  78798. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78799. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78800. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78801. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78802. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78803. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78804. + {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
  78805. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78806. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  78807. +};
  78808. +
  78809. +static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
  78810. + {0x3c07, 0x08, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0},
  78811. + {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0},
  78812. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0},
  78813. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78814. + {0x3807, 0x9b, 0, 0}, {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0},
  78815. + {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0}, {0x380c, 0x07, 0, 0},
  78816. + {0x380d, 0x68, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0},
  78817. + {0x3813, 0x06, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0},
  78818. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x0b, 0, 0},
  78819. + {0x3a03, 0x88, 0, 0}, {0x3a14, 0x0b, 0, 0}, {0x3a15, 0x88, 0, 0},
  78820. + {0x4004, 0x02, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78821. + {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0},
  78822. + {0x460c, 0x20, 0, 0}, {0x4837, 0x22, 0, 0}, {0x3824, 0x01, 0, 0},
  78823. + {0x5001, 0xa3, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78824. + {0x3036, 0x46, 0, 0}, {0x3037, 0x13, 0, 0},
  78825. +};
  78826. +
  78827. +
  78828. +static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
  78829. + {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
  78830. + {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
  78831. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0xee, 0, 0},
  78832. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x05, 0, 0},
  78833. + {0x3807, 0xc3, 0, 0}, {0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0},
  78834. + {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0}, {0x380c, 0x0b, 0, 0},
  78835. + {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
  78836. + {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
  78837. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
  78838. + {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
  78839. + {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78840. + {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
  78841. + {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
  78842. + {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78843. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  78844. +};
  78845. +
  78846. +static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
  78847. + {0x3c07, 0x07, 0, 0}, {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0},
  78848. + {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0},
  78849. + {0x3801, 0x00, 0, 0}, {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0},
  78850. + {0x3804, 0x0a, 0, 0}, {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0},
  78851. + {0x3807, 0x9f, 0, 0}, {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0},
  78852. + {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0},
  78853. + {0x380d, 0x1c, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0},
  78854. + {0x3813, 0x04, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0},
  78855. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x07, 0, 0},
  78856. + {0x3a03, 0xae, 0, 0}, {0x3a14, 0x07, 0, 0}, {0x3a15, 0xae, 0, 0},
  78857. + {0x4004, 0x06, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
  78858. + {0x4713, 0x02, 0, 0}, {0x4407, 0x0c, 0, 0}, {0x460b, 0x37, 0, 0},
  78859. + {0x460c, 0x20, 0, 0}, {0x4837, 0x2c, 0, 0}, {0x3824, 0x01, 0, 0},
  78860. + {0x5001, 0x83, 0, 0}, {0x3034, 0x1a, 0, 0}, {0x3035, 0x21, 0, 0},
  78861. + {0x3036, 0x69, 0, 0}, {0x3037, 0x13, 0, 0},
  78862. +};
  78863. +
  78864. +static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
  78865. + {
  78866. + {ov5640_mode_VGA_640_480, 640, 480,
  78867. + ov5640_setting_15fps_VGA_640_480,
  78868. + ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
  78869. + {ov5640_mode_QVGA_320_240, 320, 240,
  78870. + ov5640_setting_15fps_QVGA_320_240,
  78871. + ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
  78872. + {ov5640_mode_NTSC_720_480, 720, 480,
  78873. + ov5640_setting_15fps_NTSC_720_480,
  78874. + ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
  78875. + {ov5640_mode_PAL_720_576, 720, 576,
  78876. + ov5640_setting_15fps_PAL_720_576,
  78877. + ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
  78878. + {ov5640_mode_720P_1280_720, 1280, 720,
  78879. + ov5640_setting_15fps_720P_1280_720,
  78880. + ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
  78881. + {ov5640_mode_1080P_1920_1080, 1920, 1080,
  78882. + ov5640_setting_15fps_1080P_1920_1080,
  78883. + ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
  78884. + {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
  78885. + ov5640_setting_15fps_QSXGA_2592_1944,
  78886. + ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
  78887. + {ov5640_mode_QCIF_176_144, 176, 144,
  78888. + ov5640_setting_15fps_QCIF_176_144,
  78889. + ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
  78890. + {ov5640_mode_XGA_1024_768, 1024, 768,
  78891. + ov5640_setting_15fps_XGA_1024_768,
  78892. + ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
  78893. + },
  78894. + {
  78895. + {ov5640_mode_VGA_640_480, 640, 480,
  78896. + ov5640_setting_30fps_VGA_640_480,
  78897. + ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
  78898. + {ov5640_mode_QVGA_320_240, 320, 240,
  78899. + ov5640_setting_30fps_QVGA_320_240,
  78900. + ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
  78901. + {ov5640_mode_NTSC_720_480, 720, 480,
  78902. + ov5640_setting_30fps_NTSC_720_480,
  78903. + ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
  78904. + {ov5640_mode_PAL_720_576, 720, 576,
  78905. + ov5640_setting_30fps_PAL_720_576,
  78906. + ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
  78907. + {ov5640_mode_720P_1280_720, 1280, 720,
  78908. + ov5640_setting_30fps_720P_1280_720,
  78909. + ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
  78910. + {ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
  78911. + {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
  78912. + {ov5640_mode_QCIF_176_144, 176, 144,
  78913. + ov5640_setting_30fps_QCIF_176_144,
  78914. + ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
  78915. + {ov5640_mode_XGA_1024_768, 1024, 768,
  78916. + ov5640_setting_30fps_XGA_1024_768,
  78917. + ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
  78918. + },
  78919. +};
  78920. +
  78921. +static struct regulator *io_regulator;
  78922. +static struct regulator *core_regulator;
  78923. +static struct regulator *analog_regulator;
  78924. +
  78925. +static int ov5640_probe(struct i2c_client *adapter,
  78926. + const struct i2c_device_id *device_id);
  78927. +static int ov5640_remove(struct i2c_client *client);
  78928. +
  78929. +static s32 ov5640_read_reg(u16 reg, u8 *val);
  78930. +static s32 ov5640_write_reg(u16 reg, u8 val);
  78931. +
  78932. +static const struct i2c_device_id ov5640_id[] = {
  78933. + {"ov5640", 0},
  78934. + {"ov564x", 0},
  78935. + {},
  78936. +};
  78937. +
  78938. +MODULE_DEVICE_TABLE(i2c, ov5640_id);
  78939. +
  78940. +static struct i2c_driver ov5640_i2c_driver = {
  78941. + .driver = {
  78942. + .owner = THIS_MODULE,
  78943. + .name = "ov5640",
  78944. + },
  78945. + .probe = ov5640_probe,
  78946. + .remove = ov5640_remove,
  78947. + .id_table = ov5640_id,
  78948. +};
  78949. +
  78950. +static inline void ov5640_power_down(int enable)
  78951. +{
  78952. + gpio_set_value(pwn_gpio, enable);
  78953. +
  78954. + msleep(2);
  78955. +}
  78956. +
  78957. +static inline void ov5640_reset(void)
  78958. +{
  78959. + /* camera reset */
  78960. + gpio_set_value(rst_gpio, 1);
  78961. +
  78962. + /* camera power down */
  78963. + gpio_set_value(pwn_gpio, 1);
  78964. + msleep(5);
  78965. + gpio_set_value(pwn_gpio, 0);
  78966. + msleep(5);
  78967. + gpio_set_value(rst_gpio, 0);
  78968. + msleep(1);
  78969. + gpio_set_value(rst_gpio, 1);
  78970. + msleep(5);
  78971. + gpio_set_value(pwn_gpio, 1);
  78972. +}
  78973. +
  78974. +static int ov5640_regulator_enable(struct device *dev)
  78975. +{
  78976. + int ret = 0;
  78977. +
  78978. + io_regulator = devm_regulator_get(dev, "DOVDD");
  78979. + if (!IS_ERR(io_regulator)) {
  78980. + regulator_set_voltage(io_regulator,
  78981. + OV5640_VOLTAGE_DIGITAL_IO,
  78982. + OV5640_VOLTAGE_DIGITAL_IO);
  78983. + ret = regulator_enable(io_regulator);
  78984. + if (ret) {
  78985. + dev_err(dev, "set io voltage failed\n");
  78986. + return ret;
  78987. + } else {
  78988. + dev_dbg(dev, "set io voltage ok\n");
  78989. + }
  78990. + } else {
  78991. + io_regulator = NULL;
  78992. + dev_warn(dev, "cannot get io voltage\n");
  78993. + }
  78994. +
  78995. + core_regulator = devm_regulator_get(dev, "DVDD");
  78996. + if (!IS_ERR(core_regulator)) {
  78997. + regulator_set_voltage(core_regulator,
  78998. + OV5640_VOLTAGE_DIGITAL_CORE,
  78999. + OV5640_VOLTAGE_DIGITAL_CORE);
  79000. + ret = regulator_enable(core_regulator);
  79001. + if (ret) {
  79002. + dev_err(dev, "set core voltage failed\n");
  79003. + return ret;
  79004. + } else {
  79005. + dev_dbg(dev, "set core voltage ok\n");
  79006. + }
  79007. + } else {
  79008. + core_regulator = NULL;
  79009. + dev_warn(dev, "cannot get core voltage\n");
  79010. + }
  79011. +
  79012. + analog_regulator = devm_regulator_get(dev, "AVDD");
  79013. + if (!IS_ERR(analog_regulator)) {
  79014. + regulator_set_voltage(analog_regulator,
  79015. + OV5640_VOLTAGE_ANALOG,
  79016. + OV5640_VOLTAGE_ANALOG);
  79017. + ret = regulator_enable(analog_regulator);
  79018. + if (ret) {
  79019. + dev_err(dev, "set analog voltage failed\n");
  79020. + return ret;
  79021. + } else {
  79022. + dev_dbg(dev, "set analog voltage ok\n");
  79023. + }
  79024. + } else {
  79025. + analog_regulator = NULL;
  79026. + dev_warn(dev, "cannot get analog voltage\n");
  79027. + }
  79028. +
  79029. + return ret;
  79030. +}
  79031. +
  79032. +static s32 ov5640_write_reg(u16 reg, u8 val)
  79033. +{
  79034. + u8 au8Buf[3] = {0};
  79035. +
  79036. + au8Buf[0] = reg >> 8;
  79037. + au8Buf[1] = reg & 0xff;
  79038. + au8Buf[2] = val;
  79039. +
  79040. + if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
  79041. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  79042. + __func__, reg, val);
  79043. + return -1;
  79044. + }
  79045. +
  79046. + return 0;
  79047. +}
  79048. +
  79049. +static s32 ov5640_read_reg(u16 reg, u8 *val)
  79050. +{
  79051. + u8 au8RegBuf[2] = {0};
  79052. + u8 u8RdVal = 0;
  79053. +
  79054. + au8RegBuf[0] = reg >> 8;
  79055. + au8RegBuf[1] = reg & 0xff;
  79056. +
  79057. + if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
  79058. + pr_err("%s:write reg error:reg=%x\n",
  79059. + __func__, reg);
  79060. + return -1;
  79061. + }
  79062. +
  79063. + if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
  79064. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  79065. + __func__, reg, u8RdVal);
  79066. + return -1;
  79067. + }
  79068. +
  79069. + *val = u8RdVal;
  79070. +
  79071. + return u8RdVal;
  79072. +}
  79073. +
  79074. +static void ov5640_soft_reset(void)
  79075. +{
  79076. + /* sysclk from pad */
  79077. + ov5640_write_reg(0x3103, 0x11);
  79078. +
  79079. + /* software reset */
  79080. + ov5640_write_reg(0x3008, 0x82);
  79081. +
  79082. + /* delay at least 5ms */
  79083. + msleep(10);
  79084. +}
  79085. +
  79086. +/* set sensor driver capability
  79087. + * 0x302c[7:6] - strength
  79088. + 00 - 1x
  79089. + 01 - 2x
  79090. + 10 - 3x
  79091. + 11 - 4x
  79092. + */
  79093. +static int ov5640_driver_capability(int strength)
  79094. +{
  79095. + u8 temp = 0;
  79096. +
  79097. + if (strength > 4 || strength < 1) {
  79098. + pr_err("The valid driver capability of ov5640 is 1x~4x\n");
  79099. + return -EINVAL;
  79100. + }
  79101. +
  79102. + ov5640_read_reg(0x302c, &temp);
  79103. +
  79104. + temp &= ~0xc0; /* clear [7:6] */
  79105. + temp |= ((strength - 1) << 6); /* set [7:6] */
  79106. +
  79107. + ov5640_write_reg(0x302c, temp);
  79108. +
  79109. + return 0;
  79110. +}
  79111. +
  79112. +/* calculate sysclk */
  79113. +static int ov5640_get_sysclk(void)
  79114. +{
  79115. + int xvclk = ov5640_data.mclk / 10000;
  79116. + int sysclk;
  79117. + int temp1, temp2;
  79118. + int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv, Bit_div2x, sclk_rdiv;
  79119. + int sclk_rdiv_map[] = {1, 2, 4, 8};
  79120. + u8 regval = 0;
  79121. +
  79122. + temp1 = ov5640_read_reg(0x3034, &regval);
  79123. + temp2 = temp1 & 0x0f;
  79124. + if (temp2 == 8 || temp2 == 10) {
  79125. + Bit_div2x = temp2 / 2;
  79126. + } else {
  79127. + pr_err("ov5640: unsupported bit mode %d\n", temp2);
  79128. + return -1;
  79129. + }
  79130. +
  79131. + temp1 = ov5640_read_reg(0x3035, &regval);
  79132. + SysDiv = temp1 >> 4;
  79133. + if (SysDiv == 0)
  79134. + SysDiv = 16;
  79135. +
  79136. + temp1 = ov5640_read_reg(0x3036, &regval);
  79137. + Multiplier = temp1;
  79138. + temp1 = ov5640_read_reg(0x3037, &regval);
  79139. + PreDiv = temp1 & 0x0f;
  79140. + Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
  79141. +
  79142. + temp1 = ov5640_read_reg(0x3108, &regval);
  79143. + temp2 = temp1 & 0x03;
  79144. +
  79145. + sclk_rdiv = sclk_rdiv_map[temp2];
  79146. + VCO = xvclk * Multiplier / PreDiv;
  79147. + sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
  79148. +
  79149. + return sysclk;
  79150. +}
  79151. +
  79152. +/* read HTS from register settings */
  79153. +static int ov5640_get_HTS(void)
  79154. +{
  79155. + int HTS;
  79156. + u8 temp = 0;
  79157. +
  79158. + HTS = ov5640_read_reg(0x380c, &temp);
  79159. + HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
  79160. + return HTS;
  79161. +}
  79162. +
  79163. +/* read VTS from register settings */
  79164. +static int ov5640_get_VTS(void)
  79165. +{
  79166. + int VTS;
  79167. + u8 temp = 0;
  79168. +
  79169. + VTS = ov5640_read_reg(0x380e, &temp);
  79170. + VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
  79171. +
  79172. + return VTS;
  79173. +}
  79174. +
  79175. +/* write VTS to registers */
  79176. +static int ov5640_set_VTS(int VTS)
  79177. +{
  79178. + int temp;
  79179. +
  79180. + temp = VTS & 0xff;
  79181. + ov5640_write_reg(0x380f, temp);
  79182. +
  79183. + temp = VTS>>8;
  79184. + ov5640_write_reg(0x380e, temp);
  79185. + return 0;
  79186. +}
  79187. +
  79188. +/* read shutter, in number of line period */
  79189. +static int ov5640_get_shutter(void)
  79190. +{
  79191. + int shutter;
  79192. + u8 regval;
  79193. +
  79194. + shutter = (ov5640_read_reg(0x03500, &regval) & 0x0f);
  79195. +
  79196. + shutter = (shutter<<8) + ov5640_read_reg(0x3501, &regval);
  79197. + shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &regval)>>4);
  79198. +
  79199. + return shutter;
  79200. +}
  79201. +
  79202. +/* write shutter, in number of line period */
  79203. +static int ov5640_set_shutter(int shutter)
  79204. +{
  79205. + int temp;
  79206. +
  79207. + shutter = shutter & 0xffff;
  79208. + temp = shutter & 0x0f;
  79209. + temp = temp<<4;
  79210. + ov5640_write_reg(0x3502, temp);
  79211. +
  79212. + temp = shutter & 0xfff;
  79213. + temp = temp>>4;
  79214. + ov5640_write_reg(0x3501, temp);
  79215. +
  79216. + temp = shutter>>12;
  79217. + ov5640_write_reg(0x3500, temp);
  79218. +
  79219. + return 0;
  79220. +}
  79221. +
  79222. +/* read gain, 16 = 1x */
  79223. +static int ov5640_get_gain16(void)
  79224. +{
  79225. + int gain16;
  79226. + u8 regval;
  79227. +
  79228. + gain16 = ov5640_read_reg(0x350a, &regval) & 0x03;
  79229. + gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &regval);
  79230. +
  79231. + return gain16;
  79232. +}
  79233. +
  79234. +/* write gain, 16 = 1x */
  79235. +static int ov5640_set_gain16(int gain16)
  79236. +{
  79237. + int temp;
  79238. +
  79239. + gain16 = gain16 & 0x3ff;
  79240. + temp = gain16 & 0xff;
  79241. +
  79242. + ov5640_write_reg(0x350b, temp);
  79243. + temp = gain16>>8;
  79244. +
  79245. + ov5640_write_reg(0x350a, temp);
  79246. + return 0;
  79247. +}
  79248. +
  79249. +/* get banding filter value */
  79250. +static int ov5640_get_light_freq(void)
  79251. +{
  79252. + int temp, temp1, light_frequency;
  79253. + u8 regval;
  79254. +
  79255. + temp = ov5640_read_reg(0x3c01, &regval);
  79256. + if (temp & 0x80) {
  79257. + /* manual */
  79258. + temp1 = ov5640_read_reg(0x3c00, &regval);
  79259. + if (temp1 & 0x04) {
  79260. + /* 50Hz */
  79261. + light_frequency = 50;
  79262. + } else {
  79263. + /* 60Hz */
  79264. + light_frequency = 60;
  79265. + }
  79266. + } else {
  79267. + /* auto */
  79268. + temp1 = ov5640_read_reg(0x3c0c, &regval);
  79269. + if (temp1 & 0x01) {
  79270. + /* 50Hz */
  79271. + light_frequency = 50;
  79272. + } else {
  79273. + /* 60Hz */
  79274. + light_frequency = 60;
  79275. + }
  79276. + }
  79277. +
  79278. + return light_frequency;
  79279. +}
  79280. +
  79281. +static void ov5640_set_bandingfilter(void)
  79282. +{
  79283. + int prev_VTS;
  79284. + int band_step60, max_band60, band_step50, max_band50;
  79285. +
  79286. + /* read preview PCLK */
  79287. + prev_sysclk = ov5640_get_sysclk();
  79288. +
  79289. + /* read preview HTS */
  79290. + prev_HTS = ov5640_get_HTS();
  79291. +
  79292. + /* read preview VTS */
  79293. + prev_VTS = ov5640_get_VTS();
  79294. +
  79295. + /* calculate banding filter */
  79296. + /* 60Hz */
  79297. + band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
  79298. + ov5640_write_reg(0x3a0a, (band_step60 >> 8));
  79299. + ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
  79300. +
  79301. + max_band60 = (int)((prev_VTS-4)/band_step60);
  79302. + ov5640_write_reg(0x3a0d, max_band60);
  79303. +
  79304. + /* 50Hz */
  79305. + band_step50 = prev_sysclk * 100/prev_HTS;
  79306. + ov5640_write_reg(0x3a08, (band_step50 >> 8));
  79307. + ov5640_write_reg(0x3a09, (band_step50 & 0xff));
  79308. +
  79309. + max_band50 = (int)((prev_VTS-4)/band_step50);
  79310. + ov5640_write_reg(0x3a0e, max_band50);
  79311. +}
  79312. +
  79313. +/* stable in high */
  79314. +static int ov5640_set_AE_target(int target)
  79315. +{
  79316. + int fast_high, fast_low;
  79317. +
  79318. + AE_low = target * 23 / 25; /* 0.92 */
  79319. + AE_high = target * 27 / 25; /* 1.08 */
  79320. + fast_high = AE_high << 1;
  79321. +
  79322. + if (fast_high > 255)
  79323. + fast_high = 255;
  79324. + fast_low = AE_low >> 1;
  79325. +
  79326. + ov5640_write_reg(0x3a0f, AE_high);
  79327. + ov5640_write_reg(0x3a10, AE_low);
  79328. + ov5640_write_reg(0x3a1b, AE_high);
  79329. + ov5640_write_reg(0x3a1e, AE_low);
  79330. + ov5640_write_reg(0x3a11, fast_high);
  79331. + ov5640_write_reg(0x3a1f, fast_low);
  79332. +
  79333. + return 0;
  79334. +}
  79335. +
  79336. +/* enable = 0 to turn off night mode
  79337. + enable = 1 to turn on night mode */
  79338. +static int ov5640_set_night_mode(int enable)
  79339. +{
  79340. + u8 mode;
  79341. +
  79342. + ov5640_read_reg(0x3a00, &mode);
  79343. +
  79344. + if (enable) {
  79345. + /* night mode on */
  79346. + mode |= 0x04;
  79347. + ov5640_write_reg(0x3a00, mode);
  79348. + } else {
  79349. + /* night mode off */
  79350. + mode &= 0xfb;
  79351. + ov5640_write_reg(0x3a00, mode);
  79352. + }
  79353. +
  79354. + return 0;
  79355. +}
  79356. +
  79357. +/* enable = 0 to turn off AEC/AGC
  79358. + enable = 1 to turn on AEC/AGC */
  79359. +void ov5640_turn_on_AE_AG(int enable)
  79360. +{
  79361. + u8 ae_ag_ctrl;
  79362. +
  79363. + ov5640_read_reg(0x3503, &ae_ag_ctrl);
  79364. + if (enable) {
  79365. + /* turn on auto AE/AG */
  79366. + ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
  79367. + } else {
  79368. + /* turn off AE/AG */
  79369. + ae_ag_ctrl = ae_ag_ctrl | 0x03;
  79370. + }
  79371. + ov5640_write_reg(0x3503, ae_ag_ctrl);
  79372. +}
  79373. +
  79374. +/* download ov5640 settings to sensor through i2c */
  79375. +static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
  79376. +{
  79377. + register u32 Delay_ms = 0;
  79378. + register u16 RegAddr = 0;
  79379. + register u8 Mask = 0;
  79380. + register u8 Val = 0;
  79381. + u8 RegVal = 0;
  79382. + int i, retval = 0;
  79383. +
  79384. + for (i = 0; i < ArySize; ++i, ++pModeSetting) {
  79385. + Delay_ms = pModeSetting->u32Delay_ms;
  79386. + RegAddr = pModeSetting->u16RegAddr;
  79387. + Val = pModeSetting->u8Val;
  79388. + Mask = pModeSetting->u8Mask;
  79389. +
  79390. + if (Mask) {
  79391. + retval = ov5640_read_reg(RegAddr, &RegVal);
  79392. + if (retval < 0)
  79393. + goto err;
  79394. +
  79395. + RegVal &= ~(u8)Mask;
  79396. + Val &= Mask;
  79397. + Val |= RegVal;
  79398. + }
  79399. +
  79400. + retval = ov5640_write_reg(RegAddr, Val);
  79401. + if (retval < 0)
  79402. + goto err;
  79403. +
  79404. + if (Delay_ms)
  79405. + msleep(Delay_ms);
  79406. + }
  79407. +err:
  79408. + return retval;
  79409. +}
  79410. +
  79411. +static int ov5640_init_mode(void)
  79412. +{
  79413. + struct reg_value *pModeSetting = NULL;
  79414. + int ArySize = 0, retval = 0;
  79415. +
  79416. + ov5640_soft_reset();
  79417. +
  79418. + pModeSetting = ov5640_global_init_setting;
  79419. + ArySize = ARRAY_SIZE(ov5640_global_init_setting);
  79420. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79421. + if (retval < 0)
  79422. + goto err;
  79423. +
  79424. + pModeSetting = ov5640_init_setting_30fps_VGA;
  79425. + ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
  79426. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79427. + if (retval < 0)
  79428. + goto err;
  79429. +
  79430. + /* change driver capability to 2x according to validation board.
  79431. + * if the image is not stable, please increase the driver strength.
  79432. + */
  79433. + ov5640_driver_capability(2);
  79434. + ov5640_set_bandingfilter();
  79435. + ov5640_set_AE_target(AE_Target);
  79436. + ov5640_set_night_mode(night_mode);
  79437. +
  79438. + /* skip 9 vysnc: start capture at 10th vsync */
  79439. + msleep(300);
  79440. +
  79441. + /* turn off night mode */
  79442. + night_mode = 0;
  79443. + ov5640_data.pix.width = 640;
  79444. + ov5640_data.pix.height = 480;
  79445. +err:
  79446. + return retval;
  79447. +}
  79448. +
  79449. +/* change to or back to subsampling mode set the mode directly
  79450. + * image size below 1280 * 960 is subsampling mode */
  79451. +static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
  79452. + enum ov5640_mode mode)
  79453. +{
  79454. + struct reg_value *pModeSetting = NULL;
  79455. + s32 ArySize = 0;
  79456. + int retval = 0;
  79457. +
  79458. + if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
  79459. + pr_err("Wrong ov5640 mode detected!\n");
  79460. + return -1;
  79461. + }
  79462. +
  79463. + pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  79464. + ArySize =
  79465. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  79466. +
  79467. + ov5640_data.pix.width = ov5640_mode_info_data[frame_rate][mode].width;
  79468. + ov5640_data.pix.height = ov5640_mode_info_data[frame_rate][mode].height;
  79469. +
  79470. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  79471. + pModeSetting == NULL || ArySize == 0)
  79472. + return -EINVAL;
  79473. +
  79474. + /* set ov5640 to subsampling mode */
  79475. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79476. +
  79477. + /* turn on AE AG for subsampling mode, in case the firmware didn't */
  79478. + ov5640_turn_on_AE_AG(1);
  79479. +
  79480. + /* calculate banding filter */
  79481. + ov5640_set_bandingfilter();
  79482. +
  79483. + /* set AE target */
  79484. + ov5640_set_AE_target(AE_Target);
  79485. +
  79486. + /* update night mode setting */
  79487. + ov5640_set_night_mode(night_mode);
  79488. +
  79489. + /* skip 9 vysnc: start capture at 10th vsync */
  79490. + if (mode == ov5640_mode_XGA_1024_768 && frame_rate == ov5640_30_fps) {
  79491. + pr_warning("ov5640: actual frame rate of XGA is 22.5fps\n");
  79492. + /* 1/22.5 * 9*/
  79493. + msleep(400);
  79494. + return retval;
  79495. + }
  79496. +
  79497. + if (frame_rate == ov5640_15_fps) {
  79498. + /* 1/15 * 9*/
  79499. + msleep(600);
  79500. + } else if (frame_rate == ov5640_30_fps) {
  79501. + /* 1/30 * 9*/
  79502. + msleep(300);
  79503. + }
  79504. +
  79505. + return retval;
  79506. +}
  79507. +
  79508. +/* change to scaling mode go through exposure calucation
  79509. + * image size above 1280 * 960 is scaling mode */
  79510. +static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
  79511. + enum ov5640_mode mode)
  79512. +{
  79513. + int prev_shutter, prev_gain16, average;
  79514. + int cap_shutter, cap_gain16;
  79515. + int cap_sysclk, cap_HTS, cap_VTS;
  79516. + int light_freq, cap_bandfilt, cap_maxband;
  79517. + long cap_gain16_shutter;
  79518. + u8 temp;
  79519. + struct reg_value *pModeSetting = NULL;
  79520. + s32 ArySize = 0;
  79521. + int retval = 0;
  79522. +
  79523. + /* check if the input mode and frame rate is valid */
  79524. + pModeSetting =
  79525. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  79526. + ArySize =
  79527. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  79528. +
  79529. + ov5640_data.pix.width =
  79530. + ov5640_mode_info_data[frame_rate][mode].width;
  79531. + ov5640_data.pix.height =
  79532. + ov5640_mode_info_data[frame_rate][mode].height;
  79533. +
  79534. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  79535. + pModeSetting == NULL || ArySize == 0)
  79536. + return -EINVAL;
  79537. +
  79538. + /* read preview shutter */
  79539. + prev_shutter = ov5640_get_shutter();
  79540. +
  79541. + /* read preview gain */
  79542. + prev_gain16 = ov5640_get_gain16();
  79543. +
  79544. + /* get average */
  79545. + average = ov5640_read_reg(0x56a1, &temp);
  79546. +
  79547. + /* turn off night mode for capture */
  79548. + ov5640_set_night_mode(0);
  79549. +
  79550. + /* turn off overlay */
  79551. + ov5640_write_reg(0x3022, 0x06);
  79552. +
  79553. + /* Write capture setting */
  79554. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  79555. + if (retval < 0)
  79556. + goto err;
  79557. +
  79558. + /* turn off AE AG when capture image. */
  79559. + ov5640_turn_on_AE_AG(0);
  79560. +
  79561. + /* read capture VTS */
  79562. + cap_VTS = ov5640_get_VTS();
  79563. + cap_HTS = ov5640_get_HTS();
  79564. + cap_sysclk = ov5640_get_sysclk();
  79565. +
  79566. + /* calculate capture banding filter */
  79567. + light_freq = ov5640_get_light_freq();
  79568. + if (light_freq == 60) {
  79569. + /* 60Hz */
  79570. + cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
  79571. + } else {
  79572. + /* 50Hz */
  79573. + cap_bandfilt = cap_sysclk * 100 / cap_HTS;
  79574. + }
  79575. + cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
  79576. + /* calculate capture shutter/gain16 */
  79577. + if (average > AE_low && average < AE_high) {
  79578. + /* in stable range */
  79579. + cap_gain16_shutter =
  79580. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
  79581. + prev_HTS/cap_HTS * AE_Target / average;
  79582. + } else {
  79583. + cap_gain16_shutter =
  79584. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk *
  79585. + prev_HTS/cap_HTS;
  79586. + }
  79587. +
  79588. + /* gain to shutter */
  79589. + if (cap_gain16_shutter < (cap_bandfilt * 16)) {
  79590. + /* shutter < 1/100 */
  79591. + cap_shutter = cap_gain16_shutter/16;
  79592. + if (cap_shutter < 1)
  79593. + cap_shutter = 1;
  79594. + cap_gain16 = cap_gain16_shutter/cap_shutter;
  79595. + if (cap_gain16 < 16)
  79596. + cap_gain16 = 16;
  79597. + } else {
  79598. + if (cap_gain16_shutter > (cap_bandfilt*cap_maxband*16)) {
  79599. + /* exposure reach max */
  79600. + cap_shutter = cap_bandfilt*cap_maxband;
  79601. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  79602. + } else {
  79603. + /* 1/100 < cap_shutter =< max, cap_shutter = n/100 */
  79604. + cap_shutter =
  79605. + ((int)(cap_gain16_shutter/16/cap_bandfilt))
  79606. + * cap_bandfilt;
  79607. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  79608. + }
  79609. + }
  79610. +
  79611. + /* write capture gain */
  79612. + ov5640_set_gain16(cap_gain16);
  79613. +
  79614. + /* write capture shutter */
  79615. + if (cap_shutter > (cap_VTS - 4)) {
  79616. + cap_VTS = cap_shutter + 4;
  79617. + ov5640_set_VTS(cap_VTS);
  79618. + }
  79619. +
  79620. + ov5640_set_shutter(cap_shutter);
  79621. +
  79622. + /* skip 2 vysnc: start capture at 3rd vsync
  79623. + * frame rate of QSXGA and 1080P is 7.5fps: 1/7.5 * 2
  79624. + */
  79625. + pr_warning("ov5640: the actual frame rate of %s is 7.5fps\n",
  79626. + mode == ov5640_mode_1080P_1920_1080 ? "1080P" : "QSXGA");
  79627. + msleep(267);
  79628. +err:
  79629. + return retval;
  79630. +}
  79631. +
  79632. +static int ov5640_change_mode(enum ov5640_frame_rate frame_rate,
  79633. + enum ov5640_mode mode)
  79634. +{
  79635. + int retval = 0;
  79636. +
  79637. + if (mode > ov5640_mode_MAX || mode < ov5640_mode_MIN) {
  79638. + pr_err("Wrong ov5640 mode detected!\n");
  79639. + return -1;
  79640. + }
  79641. +
  79642. + if (mode == ov5640_mode_1080P_1920_1080 ||
  79643. + mode == ov5640_mode_QSXGA_2592_1944) {
  79644. + /* change to scaling mode go through exposure calucation
  79645. + * image size above 1280 * 960 is scaling mode */
  79646. + retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
  79647. + } else {
  79648. + /* change back to subsampling modem download firmware directly
  79649. + * image size below 1280 * 960 is subsampling mode */
  79650. + retval = ov5640_change_mode_direct(frame_rate, mode);
  79651. + }
  79652. +
  79653. + return retval;
  79654. +}
  79655. +
  79656. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  79657. +
  79658. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  79659. +{
  79660. + if (s == NULL) {
  79661. + pr_err(" ERROR!! no slave device set!\n");
  79662. + return -1;
  79663. + }
  79664. +
  79665. + memset(p, 0, sizeof(*p));
  79666. + p->u.bt656.clock_curr = ov5640_data.mclk;
  79667. + pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
  79668. + p->if_type = V4L2_IF_TYPE_BT656;
  79669. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  79670. + p->u.bt656.clock_min = OV5640_XCLK_MIN;
  79671. + p->u.bt656.clock_max = OV5640_XCLK_MAX;
  79672. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  79673. +
  79674. + return 0;
  79675. +}
  79676. +
  79677. +/*!
  79678. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  79679. + * @s: pointer to standard V4L2 device structure
  79680. + * @on: indicates power mode (on or off)
  79681. + *
  79682. + * Turns the power on or off, depending on the value of on and returns the
  79683. + * appropriate error code.
  79684. + */
  79685. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  79686. +{
  79687. + struct sensor_data *sensor = s->priv;
  79688. +
  79689. + if (on && !sensor->on) {
  79690. + if (io_regulator)
  79691. + if (regulator_enable(io_regulator) != 0)
  79692. + return -EIO;
  79693. + if (core_regulator)
  79694. + if (regulator_enable(core_regulator) != 0)
  79695. + return -EIO;
  79696. + if (analog_regulator)
  79697. + if (regulator_enable(analog_regulator) != 0)
  79698. + return -EIO;
  79699. + /* Make sure power on */
  79700. + ov5640_power_down(0);
  79701. + } else if (!on && sensor->on) {
  79702. + if (analog_regulator)
  79703. + regulator_disable(analog_regulator);
  79704. + if (core_regulator)
  79705. + regulator_disable(core_regulator);
  79706. + if (io_regulator)
  79707. + regulator_disable(io_regulator);
  79708. +
  79709. + ov5640_power_down(1);
  79710. +}
  79711. +
  79712. + sensor->on = on;
  79713. +
  79714. + return 0;
  79715. +}
  79716. +
  79717. +/*!
  79718. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  79719. + * @s: pointer to standard V4L2 device structure
  79720. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  79721. + *
  79722. + * Returns the sensor's video CAPTURE parameters.
  79723. + */
  79724. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  79725. +{
  79726. + struct sensor_data *sensor = s->priv;
  79727. + struct v4l2_captureparm *cparm = &a->parm.capture;
  79728. + int ret = 0;
  79729. +
  79730. + switch (a->type) {
  79731. + /* This is the only case currently handled. */
  79732. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  79733. + memset(a, 0, sizeof(*a));
  79734. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  79735. + cparm->capability = sensor->streamcap.capability;
  79736. + cparm->timeperframe = sensor->streamcap.timeperframe;
  79737. + cparm->capturemode = sensor->streamcap.capturemode;
  79738. + ret = 0;
  79739. + break;
  79740. +
  79741. + /* These are all the possible cases. */
  79742. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  79743. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  79744. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  79745. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  79746. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  79747. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  79748. + ret = -EINVAL;
  79749. + break;
  79750. +
  79751. + default:
  79752. + pr_debug(" type is unknown - %d\n", a->type);
  79753. + ret = -EINVAL;
  79754. + break;
  79755. + }
  79756. +
  79757. + return ret;
  79758. +}
  79759. +
  79760. +/*!
  79761. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  79762. + * @s: pointer to standard V4L2 device structure
  79763. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  79764. + *
  79765. + * Configures the sensor to use the input parameters, if possible. If
  79766. + * not possible, reverts to the old parameters and returns the
  79767. + * appropriate error code.
  79768. + */
  79769. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  79770. +{
  79771. + struct sensor_data *sensor = s->priv;
  79772. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  79773. + u32 tgt_fps; /* target frames per secound */
  79774. + enum ov5640_frame_rate frame_rate;
  79775. + int ret = 0;
  79776. +
  79777. + /* Make sure power on */
  79778. + ov5640_power_down(0);
  79779. +
  79780. + switch (a->type) {
  79781. + /* This is the only case currently handled. */
  79782. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  79783. + /* Check that the new frame rate is allowed. */
  79784. + if ((timeperframe->numerator == 0) ||
  79785. + (timeperframe->denominator == 0)) {
  79786. + timeperframe->denominator = DEFAULT_FPS;
  79787. + timeperframe->numerator = 1;
  79788. + }
  79789. +
  79790. + tgt_fps = timeperframe->denominator /
  79791. + timeperframe->numerator;
  79792. +
  79793. + if (tgt_fps > MAX_FPS) {
  79794. + timeperframe->denominator = MAX_FPS;
  79795. + timeperframe->numerator = 1;
  79796. + } else if (tgt_fps < MIN_FPS) {
  79797. + timeperframe->denominator = MIN_FPS;
  79798. + timeperframe->numerator = 1;
  79799. + }
  79800. +
  79801. + /* Actual frame rate we use */
  79802. + tgt_fps = timeperframe->denominator /
  79803. + timeperframe->numerator;
  79804. +
  79805. + if (tgt_fps == 15)
  79806. + frame_rate = ov5640_15_fps;
  79807. + else if (tgt_fps == 30)
  79808. + frame_rate = ov5640_30_fps;
  79809. + else {
  79810. + pr_err(" The camera frame rate is not supported!\n");
  79811. + return -EINVAL;
  79812. + }
  79813. +
  79814. + ret = ov5640_change_mode(frame_rate,
  79815. + a->parm.capture.capturemode);
  79816. + if (ret < 0)
  79817. + return ret;
  79818. +
  79819. + sensor->streamcap.timeperframe = *timeperframe;
  79820. + sensor->streamcap.capturemode = a->parm.capture.capturemode;
  79821. +
  79822. + break;
  79823. +
  79824. + /* These are all the possible cases. */
  79825. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  79826. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  79827. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  79828. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  79829. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  79830. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  79831. + pr_debug(" type is not " \
  79832. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  79833. + a->type);
  79834. + ret = -EINVAL;
  79835. + break;
  79836. +
  79837. + default:
  79838. + pr_debug(" type is unknown - %d\n", a->type);
  79839. + ret = -EINVAL;
  79840. + break;
  79841. + }
  79842. +
  79843. + return ret;
  79844. +}
  79845. +
  79846. +/*!
  79847. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  79848. + * @s: pointer to standard V4L2 device structure
  79849. + * @f: pointer to standard V4L2 v4l2_format structure
  79850. + *
  79851. + * Returns the sensor's current pixel format in the v4l2_format
  79852. + * parameter.
  79853. + */
  79854. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  79855. +{
  79856. + struct sensor_data *sensor = s->priv;
  79857. +
  79858. + f->fmt.pix = sensor->pix;
  79859. +
  79860. + return 0;
  79861. +}
  79862. +
  79863. +/*!
  79864. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  79865. + * @s: pointer to standard V4L2 device structure
  79866. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  79867. + *
  79868. + * If the requested control is supported, returns the control's current
  79869. + * value from the video_control[] array. Otherwise, returns -EINVAL
  79870. + * if the control is not supported.
  79871. + */
  79872. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  79873. +{
  79874. + int ret = 0;
  79875. +
  79876. + switch (vc->id) {
  79877. + case V4L2_CID_BRIGHTNESS:
  79878. + vc->value = ov5640_data.brightness;
  79879. + break;
  79880. + case V4L2_CID_HUE:
  79881. + vc->value = ov5640_data.hue;
  79882. + break;
  79883. + case V4L2_CID_CONTRAST:
  79884. + vc->value = ov5640_data.contrast;
  79885. + break;
  79886. + case V4L2_CID_SATURATION:
  79887. + vc->value = ov5640_data.saturation;
  79888. + break;
  79889. + case V4L2_CID_RED_BALANCE:
  79890. + vc->value = ov5640_data.red;
  79891. + break;
  79892. + case V4L2_CID_BLUE_BALANCE:
  79893. + vc->value = ov5640_data.blue;
  79894. + break;
  79895. + case V4L2_CID_EXPOSURE:
  79896. + vc->value = ov5640_data.ae_mode;
  79897. + break;
  79898. + default:
  79899. + ret = -EINVAL;
  79900. + }
  79901. +
  79902. + return ret;
  79903. +}
  79904. +
  79905. +/*!
  79906. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  79907. + * @s: pointer to standard V4L2 device structure
  79908. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  79909. + *
  79910. + * If the requested control is supported, sets the control's current
  79911. + * value in HW (and updates the video_control[] array). Otherwise,
  79912. + * returns -EINVAL if the control is not supported.
  79913. + */
  79914. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  79915. +{
  79916. + int retval = 0;
  79917. +
  79918. + pr_debug("In ov5640:ioctl_s_ctrl %d\n",
  79919. + vc->id);
  79920. +
  79921. + switch (vc->id) {
  79922. + case V4L2_CID_BRIGHTNESS:
  79923. + break;
  79924. + case V4L2_CID_CONTRAST:
  79925. + break;
  79926. + case V4L2_CID_SATURATION:
  79927. + break;
  79928. + case V4L2_CID_HUE:
  79929. + break;
  79930. + case V4L2_CID_AUTO_WHITE_BALANCE:
  79931. + break;
  79932. + case V4L2_CID_DO_WHITE_BALANCE:
  79933. + break;
  79934. + case V4L2_CID_RED_BALANCE:
  79935. + break;
  79936. + case V4L2_CID_BLUE_BALANCE:
  79937. + break;
  79938. + case V4L2_CID_GAMMA:
  79939. + break;
  79940. + case V4L2_CID_EXPOSURE:
  79941. + break;
  79942. + case V4L2_CID_AUTOGAIN:
  79943. + break;
  79944. + case V4L2_CID_GAIN:
  79945. + break;
  79946. + case V4L2_CID_HFLIP:
  79947. + break;
  79948. + case V4L2_CID_VFLIP:
  79949. + break;
  79950. + default:
  79951. + retval = -EPERM;
  79952. + break;
  79953. + }
  79954. +
  79955. + return retval;
  79956. +}
  79957. +
  79958. +/*!
  79959. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  79960. + * VIDIOC_ENUM_FRAMESIZES ioctl
  79961. + * @s: pointer to standard V4L2 device structure
  79962. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  79963. + *
  79964. + * Return 0 if successful, otherwise -EINVAL.
  79965. + */
  79966. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  79967. + struct v4l2_frmsizeenum *fsize)
  79968. +{
  79969. + if (fsize->index > ov5640_mode_MAX)
  79970. + return -EINVAL;
  79971. +
  79972. + fsize->pixel_format = ov5640_data.pix.pixelformat;
  79973. + fsize->discrete.width =
  79974. + max(ov5640_mode_info_data[0][fsize->index].width,
  79975. + ov5640_mode_info_data[1][fsize->index].width);
  79976. + fsize->discrete.height =
  79977. + max(ov5640_mode_info_data[0][fsize->index].height,
  79978. + ov5640_mode_info_data[1][fsize->index].height);
  79979. + return 0;
  79980. +}
  79981. +
  79982. +/*!
  79983. + * ioctl_enum_frameintervals - V4L2 sensor interface handler for
  79984. + * VIDIOC_ENUM_FRAMEINTERVALS ioctl
  79985. + * @s: pointer to standard V4L2 device structure
  79986. + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
  79987. + *
  79988. + * Return 0 if successful, otherwise -EINVAL.
  79989. + */
  79990. +static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
  79991. + struct v4l2_frmivalenum *fival)
  79992. +{
  79993. + int i, j, count;
  79994. +
  79995. + if (fival->index < 0 || fival->index > ov5640_mode_MAX)
  79996. + return -EINVAL;
  79997. +
  79998. + if (fival->width == 0 || fival->height == 0 ||
  79999. + fival->pixel_format == 0) {
  80000. + pr_warning("Please assign pixelformat, width and height.\n");
  80001. + return -EINVAL;
  80002. + }
  80003. +
  80004. + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
  80005. + fival->discrete.numerator = 1;
  80006. +
  80007. + count = 0;
  80008. + for (i = 0; i < ARRAY_SIZE(ov5640_mode_info_data); i++) {
  80009. + for (j = 0; j < (ov5640_mode_MAX + 1); j++) {
  80010. + if (fival->pixel_format == ov5640_data.pix.pixelformat
  80011. + && fival->width == ov5640_mode_info_data[i][j].width
  80012. + && fival->height == ov5640_mode_info_data[i][j].height
  80013. + && ov5640_mode_info_data[i][j].init_data_ptr != NULL) {
  80014. + count++;
  80015. + }
  80016. + if (fival->index == (count - 1)) {
  80017. + fival->discrete.denominator =
  80018. + ov5640_framerates[i];
  80019. + return 0;
  80020. + }
  80021. + }
  80022. + }
  80023. +
  80024. + return -EINVAL;
  80025. +}
  80026. +
  80027. +/*!
  80028. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  80029. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  80030. + * @s: pointer to standard V4L2 device structure
  80031. + * @id: pointer to int
  80032. + *
  80033. + * Return 0.
  80034. + */
  80035. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  80036. +{
  80037. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  80038. + V4L2_CHIP_MATCH_I2C_DRIVER;
  80039. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5640_camera");
  80040. +
  80041. + return 0;
  80042. +}
  80043. +
  80044. +/*!
  80045. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  80046. + * @s: pointer to standard V4L2 device structure
  80047. + */
  80048. +static int ioctl_init(struct v4l2_int_device *s)
  80049. +{
  80050. +
  80051. + return 0;
  80052. +}
  80053. +
  80054. +/*!
  80055. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  80056. + * @s: pointer to standard V4L2 device structure
  80057. + * @fmt: pointer to standard V4L2 fmt description structure
  80058. + *
  80059. + * Return 0.
  80060. + */
  80061. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  80062. + struct v4l2_fmtdesc *fmt)
  80063. +{
  80064. + if (fmt->index > ov5640_mode_MAX)
  80065. + return -EINVAL;
  80066. +
  80067. + fmt->pixelformat = ov5640_data.pix.pixelformat;
  80068. +
  80069. + return 0;
  80070. +}
  80071. +
  80072. +/*!
  80073. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  80074. + * @s: pointer to standard V4L2 device structure
  80075. + *
  80076. + * Initialise the device when slave attaches to the master.
  80077. + */
  80078. +static int ioctl_dev_init(struct v4l2_int_device *s)
  80079. +{
  80080. + struct sensor_data *sensor = s->priv;
  80081. + u32 tgt_xclk; /* target xclk */
  80082. + u32 tgt_fps; /* target frames per secound */
  80083. + enum ov5640_frame_rate frame_rate;
  80084. + int ret;
  80085. +
  80086. + ov5640_data.on = true;
  80087. +
  80088. + /* mclk */
  80089. + tgt_xclk = ov5640_data.mclk;
  80090. + tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
  80091. + tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
  80092. + ov5640_data.mclk = tgt_xclk;
  80093. +
  80094. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  80095. + clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
  80096. +
  80097. + /* Default camera frame rate is set in probe */
  80098. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  80099. + sensor->streamcap.timeperframe.numerator;
  80100. +
  80101. + if (tgt_fps == 15)
  80102. + frame_rate = ov5640_15_fps;
  80103. + else if (tgt_fps == 30)
  80104. + frame_rate = ov5640_30_fps;
  80105. + else
  80106. + return -EINVAL; /* Only support 15fps or 30fps now. */
  80107. +
  80108. + ret = ov5640_init_mode();
  80109. + return ret;
  80110. +}
  80111. +
  80112. +/*!
  80113. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  80114. + * @s: pointer to standard V4L2 device structure
  80115. + *
  80116. + * Delinitialise the device when slave detaches to the master.
  80117. + */
  80118. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  80119. +{
  80120. + return 0;
  80121. +}
  80122. +
  80123. +/*!
  80124. + * This structure defines all the ioctls for this module and links them to the
  80125. + * enumeration.
  80126. + */
  80127. +static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
  80128. + { vidioc_int_dev_init_num,
  80129. + (v4l2_int_ioctl_func *)ioctl_dev_init },
  80130. + { vidioc_int_dev_exit_num,
  80131. + ioctl_dev_exit},
  80132. + { vidioc_int_s_power_num,
  80133. + (v4l2_int_ioctl_func *)ioctl_s_power },
  80134. + { vidioc_int_g_ifparm_num,
  80135. + (v4l2_int_ioctl_func *)ioctl_g_ifparm },
  80136. + { vidioc_int_init_num,
  80137. + (v4l2_int_ioctl_func *)ioctl_init },
  80138. + { vidioc_int_enum_fmt_cap_num,
  80139. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
  80140. + { vidioc_int_g_fmt_cap_num,
  80141. + (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
  80142. + { vidioc_int_g_parm_num,
  80143. + (v4l2_int_ioctl_func *)ioctl_g_parm },
  80144. + { vidioc_int_s_parm_num,
  80145. + (v4l2_int_ioctl_func *)ioctl_s_parm },
  80146. + { vidioc_int_g_ctrl_num,
  80147. + (v4l2_int_ioctl_func *)ioctl_g_ctrl },
  80148. + { vidioc_int_s_ctrl_num,
  80149. + (v4l2_int_ioctl_func *)ioctl_s_ctrl },
  80150. + { vidioc_int_enum_framesizes_num,
  80151. + (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
  80152. + { vidioc_int_enum_frameintervals_num,
  80153. + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
  80154. + { vidioc_int_g_chip_ident_num,
  80155. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
  80156. +};
  80157. +
  80158. +static struct v4l2_int_slave ov5640_slave = {
  80159. + .ioctls = ov5640_ioctl_desc,
  80160. + .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
  80161. +};
  80162. +
  80163. +static struct v4l2_int_device ov5640_int_device = {
  80164. + .module = THIS_MODULE,
  80165. + .name = "ov5640",
  80166. + .type = v4l2_int_type_slave,
  80167. + .u = {
  80168. + .slave = &ov5640_slave,
  80169. + },
  80170. +};
  80171. +
  80172. +/*!
  80173. + * ov5640 I2C probe function
  80174. + *
  80175. + * @param adapter struct i2c_adapter *
  80176. + * @return Error code indicating success or failure
  80177. + */
  80178. +static int ov5640_probe(struct i2c_client *client,
  80179. + const struct i2c_device_id *id)
  80180. +{
  80181. + struct pinctrl *pinctrl;
  80182. + struct device *dev = &client->dev;
  80183. + int retval;
  80184. + u8 chip_id_high, chip_id_low;
  80185. +
  80186. + /* ov5640 pinctrl */
  80187. + pinctrl = devm_pinctrl_get_select_default(dev);
  80188. + if (IS_ERR(pinctrl)) {
  80189. + dev_err(dev, "setup pinctrl failed\n");
  80190. + return PTR_ERR(pinctrl);
  80191. + }
  80192. +
  80193. + /* request power down pin */
  80194. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  80195. + if (!gpio_is_valid(pwn_gpio)) {
  80196. + dev_err(dev, "no sensor pwdn pin available\n");
  80197. + return -ENODEV;
  80198. + }
  80199. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  80200. + "ov5640_pwdn");
  80201. + if (retval < 0)
  80202. + return retval;
  80203. +
  80204. + /* request reset pin */
  80205. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  80206. + if (!gpio_is_valid(rst_gpio)) {
  80207. + dev_err(dev, "no sensor reset pin available\n");
  80208. + return -EINVAL;
  80209. + }
  80210. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  80211. + "ov5640_reset");
  80212. + if (retval < 0)
  80213. + return retval;
  80214. +
  80215. + /* Set initial values for the sensor struct. */
  80216. + memset(&ov5640_data, 0, sizeof(ov5640_data));
  80217. + ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  80218. + if (IS_ERR(ov5640_data.sensor_clk)) {
  80219. + dev_err(dev, "get mclk failed\n");
  80220. + return PTR_ERR(ov5640_data.sensor_clk);
  80221. + }
  80222. +
  80223. + retval = of_property_read_u32(dev->of_node, "mclk",
  80224. + &ov5640_data.mclk);
  80225. + if (retval) {
  80226. + dev_err(dev, "mclk frequency is invalid\n");
  80227. + return retval;
  80228. + }
  80229. +
  80230. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  80231. + (u32 *) &(ov5640_data.mclk_source));
  80232. + if (retval) {
  80233. + dev_err(dev, "mclk_source invalid\n");
  80234. + return retval;
  80235. + }
  80236. +
  80237. + retval = of_property_read_u32(dev->of_node, "csi_id",
  80238. + &(ov5640_data.csi));
  80239. + if (retval) {
  80240. + dev_err(dev, "csi_id invalid\n");
  80241. + return retval;
  80242. + }
  80243. +
  80244. + clk_prepare_enable(ov5640_data.sensor_clk);
  80245. +
  80246. + ov5640_data.io_init = ov5640_reset;
  80247. + ov5640_data.i2c_client = client;
  80248. + ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  80249. + ov5640_data.pix.width = 640;
  80250. + ov5640_data.pix.height = 480;
  80251. + ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  80252. + V4L2_CAP_TIMEPERFRAME;
  80253. + ov5640_data.streamcap.capturemode = 0;
  80254. + ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  80255. + ov5640_data.streamcap.timeperframe.numerator = 1;
  80256. +
  80257. + ov5640_regulator_enable(&client->dev);
  80258. +
  80259. + ov5640_reset();
  80260. +
  80261. + ov5640_power_down(0);
  80262. +
  80263. + retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
  80264. + if (retval < 0 || chip_id_high != 0x56) {
  80265. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80266. + pr_warning("camera ov5640 is not found\n");
  80267. + return -ENODEV;
  80268. + }
  80269. + retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
  80270. + if (retval < 0 || chip_id_low != 0x40) {
  80271. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80272. + pr_warning("camera ov5640 is not found\n");
  80273. + return -ENODEV;
  80274. + }
  80275. +
  80276. + ov5640_power_down(1);
  80277. +
  80278. + clk_disable_unprepare(ov5640_data.sensor_clk);
  80279. +
  80280. + ov5640_int_device.priv = &ov5640_data;
  80281. + retval = v4l2_int_device_register(&ov5640_int_device);
  80282. +
  80283. + pr_info("camera ov5640 is found\n");
  80284. + return retval;
  80285. +}
  80286. +
  80287. +/*!
  80288. + * ov5640 I2C detach function
  80289. + *
  80290. + * @param client struct i2c_client *
  80291. + * @return Error code indicating success or failure
  80292. + */
  80293. +static int ov5640_remove(struct i2c_client *client)
  80294. +{
  80295. + v4l2_int_device_unregister(&ov5640_int_device);
  80296. +
  80297. + if (analog_regulator)
  80298. + regulator_disable(analog_regulator);
  80299. +
  80300. + if (core_regulator)
  80301. + regulator_disable(core_regulator);
  80302. +
  80303. + if (io_regulator)
  80304. + regulator_disable(io_regulator);
  80305. +
  80306. + return 0;
  80307. +}
  80308. +
  80309. +module_i2c_driver(ov5640_i2c_driver);
  80310. +
  80311. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  80312. +MODULE_DESCRIPTION("OV5640 Camera Driver");
  80313. +MODULE_LICENSE("GPL");
  80314. +MODULE_VERSION("1.0");
  80315. +MODULE_ALIAS("CSI");
  80316. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ov5640_mipi.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640_mipi.c
  80317. --- linux-3.14.17/drivers/media/platform/mxc/capture/ov5640_mipi.c 1970-01-01 01:00:00.000000000 +0100
  80318. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5640_mipi.c 2014-09-11 18:06:02.254038983 +0200
  80319. @@ -0,0 +1,2104 @@
  80320. +/*
  80321. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  80322. + */
  80323. +
  80324. +/*
  80325. + * This program is free software; you can redistribute it and/or modify
  80326. + * it under the terms of the GNU General Public License as published by
  80327. + * the Free Software Foundation; either version 2 of the License, or
  80328. + * (at your option) any later version.
  80329. +
  80330. + * This program is distributed in the hope that it will be useful,
  80331. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  80332. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  80333. + * GNU General Public License for more details.
  80334. +
  80335. + * You should have received a copy of the GNU General Public License along
  80336. + * with this program; if not, write to the Free Software Foundation, Inc.,
  80337. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  80338. + */
  80339. +
  80340. +#include <linux/module.h>
  80341. +#include <linux/init.h>
  80342. +#include <linux/slab.h>
  80343. +#include <linux/ctype.h>
  80344. +#include <linux/types.h>
  80345. +#include <linux/delay.h>
  80346. +#include <linux/clk.h>
  80347. +#include <linux/of_device.h>
  80348. +#include <linux/i2c.h>
  80349. +#include <linux/of_gpio.h>
  80350. +#include <linux/pinctrl/consumer.h>
  80351. +#include <linux/regulator/consumer.h>
  80352. +#include <linux/fsl_devices.h>
  80353. +#include <linux/mipi_csi2.h>
  80354. +#include <media/v4l2-chip-ident.h>
  80355. +#include <media/v4l2-int-device.h>
  80356. +#include "mxc_v4l2_capture.h"
  80357. +
  80358. +#define OV5640_VOLTAGE_ANALOG 2800000
  80359. +#define OV5640_VOLTAGE_DIGITAL_CORE 1500000
  80360. +#define OV5640_VOLTAGE_DIGITAL_IO 1800000
  80361. +
  80362. +#define MIN_FPS 15
  80363. +#define MAX_FPS 30
  80364. +#define DEFAULT_FPS 30
  80365. +
  80366. +#define OV5640_XCLK_MIN 6000000
  80367. +#define OV5640_XCLK_MAX 24000000
  80368. +
  80369. +#define OV5640_CHIP_ID_HIGH_BYTE 0x300A
  80370. +#define OV5640_CHIP_ID_LOW_BYTE 0x300B
  80371. +
  80372. +enum ov5640_mode {
  80373. + ov5640_mode_MIN = 0,
  80374. + ov5640_mode_VGA_640_480 = 0,
  80375. + ov5640_mode_QVGA_320_240 = 1,
  80376. + ov5640_mode_NTSC_720_480 = 2,
  80377. + ov5640_mode_PAL_720_576 = 3,
  80378. + ov5640_mode_720P_1280_720 = 4,
  80379. + ov5640_mode_1080P_1920_1080 = 5,
  80380. + ov5640_mode_QSXGA_2592_1944 = 6,
  80381. + ov5640_mode_QCIF_176_144 = 7,
  80382. + ov5640_mode_XGA_1024_768 = 8,
  80383. + ov5640_mode_MAX = 8,
  80384. + ov5640_mode_INIT = 0xff, /*only for sensor init*/
  80385. +};
  80386. +
  80387. +enum ov5640_frame_rate {
  80388. + ov5640_15_fps,
  80389. + ov5640_30_fps
  80390. +};
  80391. +
  80392. +/* image size under 1280 * 960 are SUBSAMPLING
  80393. + * image size upper 1280 * 960 are SCALING
  80394. + */
  80395. +enum ov5640_downsize_mode {
  80396. + SUBSAMPLING,
  80397. + SCALING,
  80398. +};
  80399. +
  80400. +struct reg_value {
  80401. + u16 u16RegAddr;
  80402. + u8 u8Val;
  80403. + u8 u8Mask;
  80404. + u32 u32Delay_ms;
  80405. +};
  80406. +
  80407. +struct ov5640_mode_info {
  80408. + enum ov5640_mode mode;
  80409. + enum ov5640_downsize_mode dn_mode;
  80410. + u32 width;
  80411. + u32 height;
  80412. + struct reg_value *init_data_ptr;
  80413. + u32 init_data_size;
  80414. +};
  80415. +
  80416. +/*!
  80417. + * Maintains the information on the current state of the sesor.
  80418. + */
  80419. +static struct sensor_data ov5640_data;
  80420. +static int pwn_gpio, rst_gpio;
  80421. +
  80422. +static struct reg_value ov5640_init_setting_30fps_VGA[] = {
  80423. +
  80424. + {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
  80425. + {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
  80426. + {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
  80427. + {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
  80428. + {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
  80429. + {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
  80430. + {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
  80431. + {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
  80432. + {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
  80433. + {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
  80434. + {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
  80435. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
  80436. + {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
  80437. + {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
  80438. + {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
  80439. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80440. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80441. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80442. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80443. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80444. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  80445. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80446. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80447. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80448. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80449. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80450. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80451. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80452. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80453. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
  80454. + {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
  80455. + {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
  80456. + {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
  80457. + {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80458. + {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
  80459. + {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
  80460. + {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
  80461. + {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
  80462. + {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
  80463. + {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
  80464. + {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
  80465. + {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
  80466. + {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
  80467. + {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
  80468. + {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
  80469. + {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
  80470. + {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
  80471. + {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
  80472. + {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
  80473. + {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
  80474. + {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
  80475. + {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
  80476. + {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
  80477. + {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
  80478. + {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
  80479. + {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
  80480. + {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
  80481. + {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
  80482. + {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
  80483. + {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
  80484. + {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
  80485. + {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
  80486. + {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
  80487. + {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
  80488. + {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
  80489. + {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
  80490. + {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
  80491. + {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
  80492. + {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
  80493. + {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
  80494. + {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
  80495. + {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
  80496. + {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
  80497. + {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
  80498. + {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
  80499. + {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
  80500. + {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
  80501. + {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
  80502. + {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
  80503. + {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
  80504. + {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
  80505. + {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
  80506. + {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
  80507. + {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
  80508. + {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
  80509. +};
  80510. +
  80511. +static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
  80512. +
  80513. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80514. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80515. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80516. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80517. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80518. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80519. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  80520. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80521. + {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
  80522. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80523. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80524. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80525. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
  80526. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80527. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80528. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80529. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80530. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
  80531. +};
  80532. +
  80533. +static struct reg_value ov5640_setting_15fps_VGA_640_480[] = {
  80534. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80535. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80536. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80537. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80538. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80539. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80540. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  80541. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80542. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80543. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80544. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80545. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80546. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80547. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80548. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80549. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80550. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80551. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80552. +};
  80553. +
  80554. +static struct reg_value ov5640_setting_30fps_XGA_1024_768[] = {
  80555. +
  80556. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80557. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80558. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80559. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80560. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80561. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80562. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  80563. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80564. + {0x380e, 0x04, 0, 0}, {0x380f, 0x38, 0, 0}, {0x3810, 0x00, 0, 0},
  80565. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80566. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80567. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80568. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0},
  80569. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80570. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80571. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80572. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80573. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0},
  80574. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  80575. + {0x380b, 0x00, 0, 0}, {0x3035, 0x12, 0, 0},
  80576. +};
  80577. +
  80578. +static struct reg_value ov5640_setting_15fps_XGA_1024_768[] = {
  80579. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80580. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80581. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80582. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80583. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80584. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80585. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  80586. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80587. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80588. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80589. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80590. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80591. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80592. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80593. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80594. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80595. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80596. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3808, 0x04, 0, 0},
  80597. + {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0}, {0x380b, 0x00, 0, 0},
  80598. +};
  80599. +
  80600. +static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
  80601. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80602. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80603. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80604. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80605. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80606. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80607. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  80608. + {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80609. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80610. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80611. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80612. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80613. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80614. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80615. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80616. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80617. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80618. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80619. +};
  80620. +
  80621. +static struct reg_value ov5640_setting_15fps_QVGA_320_240[] = {
  80622. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80623. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80624. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80625. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80626. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80627. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80628. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  80629. + {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80630. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80631. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80632. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80633. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80634. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80635. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80636. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80637. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80638. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80639. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80640. +};
  80641. +
  80642. +static struct reg_value ov5640_setting_30fps_QCIF_176_144[] = {
  80643. + {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80644. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80645. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80646. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80647. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80648. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80649. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  80650. + {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80651. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80652. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80653. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80654. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80655. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80656. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80657. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80658. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80659. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80660. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80661. +};
  80662. +static struct reg_value ov5640_setting_15fps_QCIF_176_144[] = {
  80663. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80664. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80665. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80666. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80667. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80668. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80669. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  80670. + {0x380b, 0x90, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80671. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80672. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80673. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80674. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80675. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80676. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80677. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80678. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80679. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80680. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80681. +};
  80682. +
  80683. +static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
  80684. + {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80685. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80686. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80687. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80688. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80689. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80690. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
  80691. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80692. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80693. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
  80694. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80695. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80696. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80697. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80698. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80699. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80700. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80701. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80702. +};
  80703. +
  80704. +static struct reg_value ov5640_setting_15fps_NTSC_720_480[] = {
  80705. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80706. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80707. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80708. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80709. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80710. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80711. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
  80712. + {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80713. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80714. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
  80715. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80716. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80717. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80718. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80719. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80720. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80721. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80722. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80723. +};
  80724. +
  80725. +static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
  80726. + {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80727. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80728. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80729. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80730. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80731. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80732. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
  80733. + {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80734. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80735. + {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80736. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80737. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80738. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80739. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80740. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80741. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80742. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80743. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80744. +};
  80745. +
  80746. +static struct reg_value ov5640_setting_15fps_PAL_720_576[] = {
  80747. + {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0},
  80748. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80749. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80750. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80751. + {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
  80752. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
  80753. + {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
  80754. + {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
  80755. + {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
  80756. + {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
  80757. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80758. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
  80759. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80760. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80761. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80762. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
  80763. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80764. + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
  80765. +};
  80766. +
  80767. +static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
  80768. + {0x3008, 0x42, 0, 0},
  80769. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
  80770. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80771. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80772. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80773. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  80774. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  80775. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  80776. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  80777. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
  80778. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  80779. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80780. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
  80781. + {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
  80782. + {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
  80783. + {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
  80784. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
  80785. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  80786. + {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0}, {0x4005, 0x1a, 0, 0},
  80787. + {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
  80788. +};
  80789. +
  80790. +static struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
  80791. + {0x3035, 0x41, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0},
  80792. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80793. + {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
  80794. + {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80795. + {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
  80796. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
  80797. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  80798. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
  80799. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
  80800. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  80801. + {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
  80802. + {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
  80803. + {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
  80804. + {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
  80805. + {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
  80806. + {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
  80807. + {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
  80808. + {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
  80809. +};
  80810. +
  80811. +static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
  80812. + {0x3008, 0x42, 0, 0},
  80813. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  80814. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80815. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  80816. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80817. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  80818. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  80819. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  80820. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  80821. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  80822. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  80823. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  80824. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  80825. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80826. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80827. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80828. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  80829. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80830. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x11, 0, 0},
  80831. + {0x3036, 0x54, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
  80832. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80833. + {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
  80834. + {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
  80835. + {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
  80836. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  80837. + {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
  80838. + {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
  80839. + {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
  80840. + {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
  80841. + {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
  80842. + {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
  80843. + {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
  80844. + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0},
  80845. + {0x3503, 0, 0, 0},
  80846. +};
  80847. +
  80848. +static struct reg_value ov5640_setting_15fps_1080P_1920_1080[] = {
  80849. + {0x3008, 0x42, 0, 0},
  80850. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  80851. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80852. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  80853. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80854. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  80855. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  80856. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  80857. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  80858. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  80859. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  80860. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  80861. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  80862. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80863. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80864. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80865. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  80866. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80867. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3035, 0x21, 0, 0},
  80868. + {0x3036, 0x54, 0, 1}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
  80869. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80870. + {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
  80871. + {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
  80872. + {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3808, 0x07, 0, 0},
  80873. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  80874. + {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0}, {0x380e, 0x04, 0, 0},
  80875. + {0x380f, 0x60, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
  80876. + {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
  80877. + {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
  80878. + {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
  80879. + {0x3a15, 0x60, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
  80880. + {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
  80881. + {0x4005, 0x1a, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0, 0, 0},
  80882. +};
  80883. +
  80884. +static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
  80885. + {0x4202, 0x0f, 0, 0}, /* stream off the sensor */
  80886. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, /*disable flip*/
  80887. + {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0}, {0x3c07, 0x08, 0, 0},
  80888. + {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
  80889. + {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
  80890. + {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
  80891. + {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
  80892. + {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
  80893. + {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
  80894. + {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
  80895. + {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
  80896. + {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
  80897. + {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
  80898. + {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
  80899. + {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
  80900. + {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
  80901. + {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
  80902. + {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4713, 0x03, 0, 0},
  80903. + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
  80904. + {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70},
  80905. + {0x4202, 0x00, 0, 0}, /* stream on the sensor */
  80906. +};
  80907. +
  80908. +static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
  80909. + {
  80910. + {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
  80911. + ov5640_setting_15fps_VGA_640_480,
  80912. + ARRAY_SIZE(ov5640_setting_15fps_VGA_640_480)},
  80913. + {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
  80914. + ov5640_setting_15fps_QVGA_320_240,
  80915. + ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)},
  80916. + {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
  80917. + ov5640_setting_15fps_NTSC_720_480,
  80918. + ARRAY_SIZE(ov5640_setting_15fps_NTSC_720_480)},
  80919. + {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
  80920. + ov5640_setting_15fps_PAL_720_576,
  80921. + ARRAY_SIZE(ov5640_setting_15fps_PAL_720_576)},
  80922. + {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
  80923. + ov5640_setting_15fps_720P_1280_720,
  80924. + ARRAY_SIZE(ov5640_setting_15fps_720P_1280_720)},
  80925. + {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
  80926. + ov5640_setting_15fps_1080P_1920_1080,
  80927. + ARRAY_SIZE(ov5640_setting_15fps_1080P_1920_1080)},
  80928. + {ov5640_mode_QSXGA_2592_1944, SCALING, 2592, 1944,
  80929. + ov5640_setting_15fps_QSXGA_2592_1944,
  80930. + ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
  80931. + {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
  80932. + ov5640_setting_15fps_QCIF_176_144,
  80933. + ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)},
  80934. + {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
  80935. + ov5640_setting_15fps_XGA_1024_768,
  80936. + ARRAY_SIZE(ov5640_setting_15fps_XGA_1024_768)},
  80937. + },
  80938. + {
  80939. + {ov5640_mode_VGA_640_480, SUBSAMPLING, 640, 480,
  80940. + ov5640_setting_30fps_VGA_640_480,
  80941. + ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480)},
  80942. + {ov5640_mode_QVGA_320_240, SUBSAMPLING, 320, 240,
  80943. + ov5640_setting_30fps_QVGA_320_240,
  80944. + ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
  80945. + {ov5640_mode_NTSC_720_480, SUBSAMPLING, 720, 480,
  80946. + ov5640_setting_30fps_NTSC_720_480,
  80947. + ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
  80948. + {ov5640_mode_PAL_720_576, SUBSAMPLING, 720, 576,
  80949. + ov5640_setting_30fps_PAL_720_576,
  80950. + ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
  80951. + {ov5640_mode_720P_1280_720, SUBSAMPLING, 1280, 720,
  80952. + ov5640_setting_30fps_720P_1280_720,
  80953. + ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
  80954. + {ov5640_mode_1080P_1920_1080, SCALING, 1920, 1080,
  80955. + ov5640_setting_30fps_1080P_1920_1080,
  80956. + ARRAY_SIZE(ov5640_setting_30fps_1080P_1920_1080)},
  80957. + {ov5640_mode_QSXGA_2592_1944, -1, 0, 0, NULL, 0},
  80958. + {ov5640_mode_QCIF_176_144, SUBSAMPLING, 176, 144,
  80959. + ov5640_setting_30fps_QCIF_176_144,
  80960. + ARRAY_SIZE(ov5640_setting_30fps_QCIF_176_144)},
  80961. + {ov5640_mode_XGA_1024_768, SUBSAMPLING, 1024, 768,
  80962. + ov5640_setting_30fps_XGA_1024_768,
  80963. + ARRAY_SIZE(ov5640_setting_30fps_XGA_1024_768)},
  80964. + },
  80965. +};
  80966. +
  80967. +static struct regulator *io_regulator;
  80968. +static struct regulator *core_regulator;
  80969. +static struct regulator *analog_regulator;
  80970. +static struct regulator *gpo_regulator;
  80971. +
  80972. +static int ov5640_probe(struct i2c_client *adapter,
  80973. + const struct i2c_device_id *device_id);
  80974. +static int ov5640_remove(struct i2c_client *client);
  80975. +
  80976. +static s32 ov5640_read_reg(u16 reg, u8 *val);
  80977. +static s32 ov5640_write_reg(u16 reg, u8 val);
  80978. +
  80979. +static const struct i2c_device_id ov5640_id[] = {
  80980. + {"ov5640_mipi", 0},
  80981. + {},
  80982. +};
  80983. +
  80984. +MODULE_DEVICE_TABLE(i2c, ov5640_id);
  80985. +
  80986. +static struct i2c_driver ov5640_i2c_driver = {
  80987. + .driver = {
  80988. + .owner = THIS_MODULE,
  80989. + .name = "ov5640_mipi",
  80990. + },
  80991. + .probe = ov5640_probe,
  80992. + .remove = ov5640_remove,
  80993. + .id_table = ov5640_id,
  80994. +};
  80995. +
  80996. +static void ov5640_standby(s32 enable)
  80997. +{
  80998. + if (enable)
  80999. + gpio_set_value(pwn_gpio, 1);
  81000. + else
  81001. + gpio_set_value(pwn_gpio, 0);
  81002. +
  81003. + msleep(2);
  81004. +}
  81005. +
  81006. +static void ov5640_reset(void)
  81007. +{
  81008. + /* camera reset */
  81009. + gpio_set_value(rst_gpio, 1);
  81010. +
  81011. + /* camera power dowmn */
  81012. + gpio_set_value(pwn_gpio, 1);
  81013. + msleep(5);
  81014. +
  81015. + gpio_set_value(pwn_gpio, 0);
  81016. + msleep(5);
  81017. +
  81018. + gpio_set_value(rst_gpio, 0);
  81019. + msleep(1);
  81020. +
  81021. + gpio_set_value(rst_gpio, 1);
  81022. + msleep(5);
  81023. +
  81024. + gpio_set_value(pwn_gpio, 1);
  81025. +}
  81026. +
  81027. +static int ov5640_power_on(struct device *dev)
  81028. +{
  81029. + int ret = 0;
  81030. +
  81031. + io_regulator = devm_regulator_get(dev, "DOVDD");
  81032. + if (!IS_ERR(io_regulator)) {
  81033. + regulator_set_voltage(io_regulator,
  81034. + OV5640_VOLTAGE_DIGITAL_IO,
  81035. + OV5640_VOLTAGE_DIGITAL_IO);
  81036. + ret = regulator_enable(io_regulator);
  81037. + if (ret) {
  81038. + pr_err("%s:io set voltage error\n", __func__);
  81039. + return ret;
  81040. + } else {
  81041. + dev_dbg(dev,
  81042. + "%s:io set voltage ok\n", __func__);
  81043. + }
  81044. + } else {
  81045. + pr_err("%s: cannot get io voltage error\n", __func__);
  81046. + io_regulator = NULL;
  81047. + }
  81048. +
  81049. + core_regulator = devm_regulator_get(dev, "DVDD");
  81050. + if (!IS_ERR(core_regulator)) {
  81051. + regulator_set_voltage(core_regulator,
  81052. + OV5640_VOLTAGE_DIGITAL_CORE,
  81053. + OV5640_VOLTAGE_DIGITAL_CORE);
  81054. + ret = regulator_enable(core_regulator);
  81055. + if (ret) {
  81056. + pr_err("%s:core set voltage error\n", __func__);
  81057. + return ret;
  81058. + } else {
  81059. + dev_dbg(dev,
  81060. + "%s:core set voltage ok\n", __func__);
  81061. + }
  81062. + } else {
  81063. + core_regulator = NULL;
  81064. + pr_err("%s: cannot get core voltage error\n", __func__);
  81065. + }
  81066. +
  81067. + analog_regulator = devm_regulator_get(dev, "AVDD");
  81068. + if (!IS_ERR(analog_regulator)) {
  81069. + regulator_set_voltage(analog_regulator,
  81070. + OV5640_VOLTAGE_ANALOG,
  81071. + OV5640_VOLTAGE_ANALOG);
  81072. + ret = regulator_enable(analog_regulator);
  81073. + if (ret) {
  81074. + pr_err("%s:analog set voltage error\n",
  81075. + __func__);
  81076. + return ret;
  81077. + } else {
  81078. + dev_dbg(dev,
  81079. + "%s:analog set voltage ok\n", __func__);
  81080. + }
  81081. + } else {
  81082. + analog_regulator = NULL;
  81083. + pr_err("%s: cannot get analog voltage error\n", __func__);
  81084. + }
  81085. +
  81086. + return ret;
  81087. +}
  81088. +
  81089. +static s32 ov5640_write_reg(u16 reg, u8 val)
  81090. +{
  81091. + u8 au8Buf[3] = {0};
  81092. +
  81093. + au8Buf[0] = reg >> 8;
  81094. + au8Buf[1] = reg & 0xff;
  81095. + au8Buf[2] = val;
  81096. +
  81097. + if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
  81098. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  81099. + __func__, reg, val);
  81100. + return -1;
  81101. + }
  81102. +
  81103. + return 0;
  81104. +}
  81105. +
  81106. +static s32 ov5640_read_reg(u16 reg, u8 *val)
  81107. +{
  81108. + u8 au8RegBuf[2] = {0};
  81109. + u8 u8RdVal = 0;
  81110. +
  81111. + au8RegBuf[0] = reg >> 8;
  81112. + au8RegBuf[1] = reg & 0xff;
  81113. +
  81114. + if (2 != i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2)) {
  81115. + pr_err("%s:write reg error:reg=%x\n",
  81116. + __func__, reg);
  81117. + return -1;
  81118. + }
  81119. +
  81120. + if (1 != i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1)) {
  81121. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  81122. + __func__, reg, u8RdVal);
  81123. + return -1;
  81124. + }
  81125. +
  81126. + *val = u8RdVal;
  81127. +
  81128. + return u8RdVal;
  81129. +}
  81130. +
  81131. +static int prev_sysclk, prev_HTS;
  81132. +static int AE_low, AE_high, AE_Target = 52;
  81133. +
  81134. +void OV5640_stream_on(void)
  81135. +{
  81136. + ov5640_write_reg(0x4202, 0x00);
  81137. +}
  81138. +
  81139. +void OV5640_stream_off(void)
  81140. +{
  81141. + ov5640_write_reg(0x4202, 0x0f);
  81142. +}
  81143. +
  81144. +
  81145. +int OV5640_get_sysclk(void)
  81146. +{
  81147. + /* calculate sysclk */
  81148. + int xvclk = ov5640_data.mclk / 10000;
  81149. + int temp1, temp2;
  81150. + int Multiplier, PreDiv, VCO, SysDiv, Pll_rdiv;
  81151. + int Bit_div2x = 1, sclk_rdiv, sysclk;
  81152. + u8 temp;
  81153. +
  81154. + int sclk_rdiv_map[] = {1, 2, 4, 8};
  81155. +
  81156. + temp1 = ov5640_read_reg(0x3034, &temp);
  81157. + temp2 = temp1 & 0x0f;
  81158. + if (temp2 == 8 || temp2 == 10)
  81159. + Bit_div2x = temp2 / 2;
  81160. +
  81161. + temp1 = ov5640_read_reg(0x3035, &temp);
  81162. + SysDiv = temp1>>4;
  81163. + if (SysDiv == 0)
  81164. + SysDiv = 16;
  81165. +
  81166. + temp1 = ov5640_read_reg(0x3036, &temp);
  81167. + Multiplier = temp1;
  81168. +
  81169. + temp1 = ov5640_read_reg(0x3037, &temp);
  81170. + PreDiv = temp1 & 0x0f;
  81171. + Pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
  81172. +
  81173. + temp1 = ov5640_read_reg(0x3108, &temp);
  81174. + temp2 = temp1 & 0x03;
  81175. + sclk_rdiv = sclk_rdiv_map[temp2];
  81176. +
  81177. + VCO = xvclk * Multiplier / PreDiv;
  81178. +
  81179. + sysclk = VCO / SysDiv / Pll_rdiv * 2 / Bit_div2x / sclk_rdiv;
  81180. +
  81181. + return sysclk;
  81182. +}
  81183. +
  81184. +void OV5640_set_night_mode(void)
  81185. +{
  81186. + /* read HTS from register settings */
  81187. + u8 mode;
  81188. +
  81189. + ov5640_read_reg(0x3a00, &mode);
  81190. + mode &= 0xfb;
  81191. + ov5640_write_reg(0x3a00, mode);
  81192. +}
  81193. +
  81194. +int OV5640_get_HTS(void)
  81195. +{
  81196. + /* read HTS from register settings */
  81197. + int HTS;
  81198. + u8 temp;
  81199. +
  81200. + HTS = ov5640_read_reg(0x380c, &temp);
  81201. + HTS = (HTS<<8) + ov5640_read_reg(0x380d, &temp);
  81202. +
  81203. + return HTS;
  81204. +}
  81205. +
  81206. +int OV5640_get_VTS(void)
  81207. +{
  81208. + /* read VTS from register settings */
  81209. + int VTS;
  81210. + u8 temp;
  81211. +
  81212. + /* total vertical size[15:8] high byte */
  81213. + VTS = ov5640_read_reg(0x380e, &temp);
  81214. +
  81215. + VTS = (VTS<<8) + ov5640_read_reg(0x380f, &temp);
  81216. +
  81217. + return VTS;
  81218. +}
  81219. +
  81220. +int OV5640_set_VTS(int VTS)
  81221. +{
  81222. + /* write VTS to registers */
  81223. + int temp;
  81224. +
  81225. + temp = VTS & 0xff;
  81226. + ov5640_write_reg(0x380f, temp);
  81227. +
  81228. + temp = VTS>>8;
  81229. + ov5640_write_reg(0x380e, temp);
  81230. +
  81231. + return 0;
  81232. +}
  81233. +
  81234. +int OV5640_get_shutter(void)
  81235. +{
  81236. + /* read shutter, in number of line period */
  81237. + int shutter;
  81238. + u8 temp;
  81239. +
  81240. + shutter = (ov5640_read_reg(0x03500, &temp) & 0x0f);
  81241. + shutter = (shutter<<8) + ov5640_read_reg(0x3501, &temp);
  81242. + shutter = (shutter<<4) + (ov5640_read_reg(0x3502, &temp)>>4);
  81243. +
  81244. + return shutter;
  81245. +}
  81246. +
  81247. +int OV5640_set_shutter(int shutter)
  81248. +{
  81249. + /* write shutter, in number of line period */
  81250. + int temp;
  81251. +
  81252. + shutter = shutter & 0xffff;
  81253. +
  81254. + temp = shutter & 0x0f;
  81255. + temp = temp<<4;
  81256. + ov5640_write_reg(0x3502, temp);
  81257. +
  81258. + temp = shutter & 0xfff;
  81259. + temp = temp>>4;
  81260. + ov5640_write_reg(0x3501, temp);
  81261. +
  81262. + temp = shutter>>12;
  81263. + ov5640_write_reg(0x3500, temp);
  81264. +
  81265. + return 0;
  81266. +}
  81267. +
  81268. +int OV5640_get_gain16(void)
  81269. +{
  81270. + /* read gain, 16 = 1x */
  81271. + int gain16;
  81272. + u8 temp;
  81273. +
  81274. + gain16 = ov5640_read_reg(0x350a, &temp) & 0x03;
  81275. + gain16 = (gain16<<8) + ov5640_read_reg(0x350b, &temp);
  81276. +
  81277. + return gain16;
  81278. +}
  81279. +
  81280. +int OV5640_set_gain16(int gain16)
  81281. +{
  81282. + /* write gain, 16 = 1x */
  81283. + u8 temp;
  81284. + gain16 = gain16 & 0x3ff;
  81285. +
  81286. + temp = gain16 & 0xff;
  81287. + ov5640_write_reg(0x350b, temp);
  81288. +
  81289. + temp = gain16>>8;
  81290. + ov5640_write_reg(0x350a, temp);
  81291. +
  81292. + return 0;
  81293. +}
  81294. +
  81295. +int OV5640_get_light_freq(void)
  81296. +{
  81297. + /* get banding filter value */
  81298. + int temp, temp1, light_freq = 0;
  81299. + u8 tmp;
  81300. +
  81301. + temp = ov5640_read_reg(0x3c01, &tmp);
  81302. +
  81303. + if (temp & 0x80) {
  81304. + /* manual */
  81305. + temp1 = ov5640_read_reg(0x3c00, &tmp);
  81306. + if (temp1 & 0x04) {
  81307. + /* 50Hz */
  81308. + light_freq = 50;
  81309. + } else {
  81310. + /* 60Hz */
  81311. + light_freq = 60;
  81312. + }
  81313. + } else {
  81314. + /* auto */
  81315. + temp1 = ov5640_read_reg(0x3c0c, &tmp);
  81316. + if (temp1 & 0x01) {
  81317. + /* 50Hz */
  81318. + light_freq = 50;
  81319. + } else {
  81320. + /* 60Hz */
  81321. + }
  81322. + }
  81323. + return light_freq;
  81324. +}
  81325. +
  81326. +void OV5640_set_bandingfilter(void)
  81327. +{
  81328. + int prev_VTS;
  81329. + int band_step60, max_band60, band_step50, max_band50;
  81330. +
  81331. + /* read preview PCLK */
  81332. + prev_sysclk = OV5640_get_sysclk();
  81333. + /* read preview HTS */
  81334. + prev_HTS = OV5640_get_HTS();
  81335. +
  81336. + /* read preview VTS */
  81337. + prev_VTS = OV5640_get_VTS();
  81338. +
  81339. + /* calculate banding filter */
  81340. + /* 60Hz */
  81341. + band_step60 = prev_sysclk * 100/prev_HTS * 100/120;
  81342. + ov5640_write_reg(0x3a0a, (band_step60 >> 8));
  81343. + ov5640_write_reg(0x3a0b, (band_step60 & 0xff));
  81344. +
  81345. + max_band60 = (int)((prev_VTS-4)/band_step60);
  81346. + ov5640_write_reg(0x3a0d, max_band60);
  81347. +
  81348. + /* 50Hz */
  81349. + band_step50 = prev_sysclk * 100/prev_HTS;
  81350. + ov5640_write_reg(0x3a08, (band_step50 >> 8));
  81351. + ov5640_write_reg(0x3a09, (band_step50 & 0xff));
  81352. +
  81353. + max_band50 = (int)((prev_VTS-4)/band_step50);
  81354. + ov5640_write_reg(0x3a0e, max_band50);
  81355. +}
  81356. +
  81357. +int OV5640_set_AE_target(int target)
  81358. +{
  81359. + /* stable in high */
  81360. + int fast_high, fast_low;
  81361. + AE_low = target * 23 / 25; /* 0.92 */
  81362. + AE_high = target * 27 / 25; /* 1.08 */
  81363. +
  81364. + fast_high = AE_high<<1;
  81365. + if (fast_high > 255)
  81366. + fast_high = 255;
  81367. +
  81368. + fast_low = AE_low >> 1;
  81369. +
  81370. + ov5640_write_reg(0x3a0f, AE_high);
  81371. + ov5640_write_reg(0x3a10, AE_low);
  81372. + ov5640_write_reg(0x3a1b, AE_high);
  81373. + ov5640_write_reg(0x3a1e, AE_low);
  81374. + ov5640_write_reg(0x3a11, fast_high);
  81375. + ov5640_write_reg(0x3a1f, fast_low);
  81376. +
  81377. + return 0;
  81378. +}
  81379. +
  81380. +void OV5640_turn_on_AE_AG(int enable)
  81381. +{
  81382. + u8 ae_ag_ctrl;
  81383. +
  81384. + ov5640_read_reg(0x3503, &ae_ag_ctrl);
  81385. + if (enable) {
  81386. + /* turn on auto AE/AG */
  81387. + ae_ag_ctrl = ae_ag_ctrl & ~(0x03);
  81388. + } else {
  81389. + /* turn off AE/AG */
  81390. + ae_ag_ctrl = ae_ag_ctrl | 0x03;
  81391. + }
  81392. + ov5640_write_reg(0x3503, ae_ag_ctrl);
  81393. +}
  81394. +
  81395. +bool binning_on(void)
  81396. +{
  81397. + u8 temp;
  81398. + ov5640_read_reg(0x3821, &temp);
  81399. + temp &= 0xfe;
  81400. + if (temp)
  81401. + return true;
  81402. + else
  81403. + return false;
  81404. +}
  81405. +
  81406. +static void ov5640_set_virtual_channel(int channel)
  81407. +{
  81408. + u8 channel_id;
  81409. +
  81410. + ov5640_read_reg(0x4814, &channel_id);
  81411. + channel_id &= ~(3 << 6);
  81412. + ov5640_write_reg(0x4814, channel_id | (channel << 6));
  81413. +}
  81414. +
  81415. +/* download ov5640 settings to sensor through i2c */
  81416. +static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
  81417. +{
  81418. + register u32 Delay_ms = 0;
  81419. + register u16 RegAddr = 0;
  81420. + register u8 Mask = 0;
  81421. + register u8 Val = 0;
  81422. + u8 RegVal = 0;
  81423. + int i, retval = 0;
  81424. +
  81425. + for (i = 0; i < ArySize; ++i, ++pModeSetting) {
  81426. + Delay_ms = pModeSetting->u32Delay_ms;
  81427. + RegAddr = pModeSetting->u16RegAddr;
  81428. + Val = pModeSetting->u8Val;
  81429. + Mask = pModeSetting->u8Mask;
  81430. +
  81431. + if (Mask) {
  81432. + retval = ov5640_read_reg(RegAddr, &RegVal);
  81433. + if (retval < 0)
  81434. + goto err;
  81435. +
  81436. + RegVal &= ~(u8)Mask;
  81437. + Val &= Mask;
  81438. + Val |= RegVal;
  81439. + }
  81440. +
  81441. + retval = ov5640_write_reg(RegAddr, Val);
  81442. + if (retval < 0)
  81443. + goto err;
  81444. +
  81445. + if (Delay_ms)
  81446. + msleep(Delay_ms);
  81447. + }
  81448. +err:
  81449. + return retval;
  81450. +}
  81451. +
  81452. +/* sensor changes between scaling and subsampling
  81453. + * go through exposure calcualtion
  81454. + */
  81455. +static int ov5640_change_mode_exposure_calc(enum ov5640_frame_rate frame_rate,
  81456. + enum ov5640_mode mode)
  81457. +{
  81458. + struct reg_value *pModeSetting = NULL;
  81459. + s32 ArySize = 0;
  81460. + u8 average;
  81461. + int prev_shutter, prev_gain16;
  81462. + int cap_shutter, cap_gain16;
  81463. + int cap_sysclk, cap_HTS, cap_VTS;
  81464. + int light_freq, cap_bandfilt, cap_maxband;
  81465. + long cap_gain16_shutter;
  81466. + int retval = 0;
  81467. +
  81468. + /* check if the input mode and frame rate is valid */
  81469. + pModeSetting =
  81470. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  81471. + ArySize =
  81472. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  81473. +
  81474. + ov5640_data.pix.width =
  81475. + ov5640_mode_info_data[frame_rate][mode].width;
  81476. + ov5640_data.pix.height =
  81477. + ov5640_mode_info_data[frame_rate][mode].height;
  81478. +
  81479. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  81480. + pModeSetting == NULL || ArySize == 0)
  81481. + return -EINVAL;
  81482. +
  81483. + /* auto focus */
  81484. + /* OV5640_auto_focus();//if no af function, just skip it */
  81485. +
  81486. + /* turn off AE/AG */
  81487. + OV5640_turn_on_AE_AG(0);
  81488. +
  81489. + /* read preview shutter */
  81490. + prev_shutter = OV5640_get_shutter();
  81491. + if ((binning_on()) && (mode != ov5640_mode_720P_1280_720)
  81492. + && (mode != ov5640_mode_1080P_1920_1080))
  81493. + prev_shutter *= 2;
  81494. +
  81495. + /* read preview gain */
  81496. + prev_gain16 = OV5640_get_gain16();
  81497. +
  81498. + /* get average */
  81499. + ov5640_read_reg(0x56a1, &average);
  81500. +
  81501. + /* turn off night mode for capture */
  81502. + OV5640_set_night_mode();
  81503. +
  81504. + /* turn off overlay */
  81505. + /* ov5640_write_reg(0x3022, 0x06);//if no af function, just skip it */
  81506. +
  81507. + OV5640_stream_off();
  81508. +
  81509. + /* Write capture setting */
  81510. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  81511. + if (retval < 0)
  81512. + goto err;
  81513. +
  81514. + /* read capture VTS */
  81515. + cap_VTS = OV5640_get_VTS();
  81516. + cap_HTS = OV5640_get_HTS();
  81517. + cap_sysclk = OV5640_get_sysclk();
  81518. +
  81519. + /* calculate capture banding filter */
  81520. + light_freq = OV5640_get_light_freq();
  81521. + if (light_freq == 60) {
  81522. + /* 60Hz */
  81523. + cap_bandfilt = cap_sysclk * 100 / cap_HTS * 100 / 120;
  81524. + } else {
  81525. + /* 50Hz */
  81526. + cap_bandfilt = cap_sysclk * 100 / cap_HTS;
  81527. + }
  81528. + cap_maxband = (int)((cap_VTS - 4)/cap_bandfilt);
  81529. +
  81530. + /* calculate capture shutter/gain16 */
  81531. + if (average > AE_low && average < AE_high) {
  81532. + /* in stable range */
  81533. + cap_gain16_shutter =
  81534. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
  81535. + * prev_HTS/cap_HTS * AE_Target / average;
  81536. + } else {
  81537. + cap_gain16_shutter =
  81538. + prev_gain16 * prev_shutter * cap_sysclk/prev_sysclk
  81539. + * prev_HTS/cap_HTS;
  81540. + }
  81541. +
  81542. + /* gain to shutter */
  81543. + if (cap_gain16_shutter < (cap_bandfilt * 16)) {
  81544. + /* shutter < 1/100 */
  81545. + cap_shutter = cap_gain16_shutter/16;
  81546. + if (cap_shutter < 1)
  81547. + cap_shutter = 1;
  81548. +
  81549. + cap_gain16 = cap_gain16_shutter/cap_shutter;
  81550. + if (cap_gain16 < 16)
  81551. + cap_gain16 = 16;
  81552. + } else {
  81553. + if (cap_gain16_shutter >
  81554. + (cap_bandfilt * cap_maxband * 16)) {
  81555. + /* exposure reach max */
  81556. + cap_shutter = cap_bandfilt * cap_maxband;
  81557. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  81558. + } else {
  81559. + /* 1/100 < (cap_shutter = n/100) =< max */
  81560. + cap_shutter =
  81561. + ((int) (cap_gain16_shutter/16 / cap_bandfilt))
  81562. + *cap_bandfilt;
  81563. + cap_gain16 = cap_gain16_shutter / cap_shutter;
  81564. + }
  81565. + }
  81566. +
  81567. + /* write capture gain */
  81568. + OV5640_set_gain16(cap_gain16);
  81569. +
  81570. + /* write capture shutter */
  81571. + if (cap_shutter > (cap_VTS - 4)) {
  81572. + cap_VTS = cap_shutter + 4;
  81573. + OV5640_set_VTS(cap_VTS);
  81574. + }
  81575. + OV5640_set_shutter(cap_shutter);
  81576. +
  81577. + OV5640_stream_on();
  81578. +
  81579. +err:
  81580. + return retval;
  81581. +}
  81582. +
  81583. +/* if sensor changes inside scaling or subsampling
  81584. + * change mode directly
  81585. + * */
  81586. +static int ov5640_change_mode_direct(enum ov5640_frame_rate frame_rate,
  81587. + enum ov5640_mode mode)
  81588. +{
  81589. + struct reg_value *pModeSetting = NULL;
  81590. + s32 ArySize = 0;
  81591. + int retval = 0;
  81592. +
  81593. + /* check if the input mode and frame rate is valid */
  81594. + pModeSetting =
  81595. + ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
  81596. + ArySize =
  81597. + ov5640_mode_info_data[frame_rate][mode].init_data_size;
  81598. +
  81599. + ov5640_data.pix.width =
  81600. + ov5640_mode_info_data[frame_rate][mode].width;
  81601. + ov5640_data.pix.height =
  81602. + ov5640_mode_info_data[frame_rate][mode].height;
  81603. +
  81604. + if (ov5640_data.pix.width == 0 || ov5640_data.pix.height == 0 ||
  81605. + pModeSetting == NULL || ArySize == 0)
  81606. + return -EINVAL;
  81607. +
  81608. + /* turn off AE/AG */
  81609. + OV5640_turn_on_AE_AG(0);
  81610. +
  81611. + OV5640_stream_off();
  81612. +
  81613. + /* Write capture setting */
  81614. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  81615. + if (retval < 0)
  81616. + goto err;
  81617. +
  81618. + OV5640_stream_on();
  81619. +
  81620. + OV5640_turn_on_AE_AG(1);
  81621. +
  81622. +err:
  81623. + return retval;
  81624. +}
  81625. +
  81626. +static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
  81627. + enum ov5640_mode mode, enum ov5640_mode orig_mode)
  81628. +{
  81629. + struct reg_value *pModeSetting = NULL;
  81630. + s32 ArySize = 0;
  81631. + int retval = 0;
  81632. + void *mipi_csi2_info;
  81633. + u32 mipi_reg, msec_wait4stable = 0;
  81634. + enum ov5640_downsize_mode dn_mode, orig_dn_mode;
  81635. +
  81636. + if ((mode > ov5640_mode_MAX || mode < ov5640_mode_MIN)
  81637. + && (mode != ov5640_mode_INIT)) {
  81638. + pr_err("Wrong ov5640 mode detected!\n");
  81639. + return -1;
  81640. + }
  81641. +
  81642. + mipi_csi2_info = mipi_csi2_get_info();
  81643. +
  81644. + /* initial mipi dphy */
  81645. + if (!mipi_csi2_info) {
  81646. + printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
  81647. + __func__, __FILE__);
  81648. + return -1;
  81649. + }
  81650. +
  81651. + if (!mipi_csi2_get_status(mipi_csi2_info))
  81652. + mipi_csi2_enable(mipi_csi2_info);
  81653. +
  81654. + if (!mipi_csi2_get_status(mipi_csi2_info)) {
  81655. + pr_err("Can not enable mipi csi2 driver!\n");
  81656. + return -1;
  81657. + }
  81658. +
  81659. + mipi_csi2_set_lanes(mipi_csi2_info);
  81660. +
  81661. + /*Only reset MIPI CSI2 HW at sensor initialize*/
  81662. + if (mode == ov5640_mode_INIT)
  81663. + mipi_csi2_reset(mipi_csi2_info);
  81664. +
  81665. + if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_UYVY)
  81666. + mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_YUV422);
  81667. + else if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_RGB565)
  81668. + mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RGB565);
  81669. + else
  81670. + pr_err("currently this sensor format can not be supported!\n");
  81671. +
  81672. + dn_mode = ov5640_mode_info_data[frame_rate][mode].dn_mode;
  81673. + orig_dn_mode = ov5640_mode_info_data[frame_rate][orig_mode].dn_mode;
  81674. + if (mode == ov5640_mode_INIT) {
  81675. + pModeSetting = ov5640_init_setting_30fps_VGA;
  81676. + ArySize = ARRAY_SIZE(ov5640_init_setting_30fps_VGA);
  81677. +
  81678. + ov5640_data.pix.width = 640;
  81679. + ov5640_data.pix.height = 480;
  81680. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  81681. + if (retval < 0)
  81682. + goto err;
  81683. +
  81684. + pModeSetting = ov5640_setting_30fps_VGA_640_480;
  81685. + ArySize = ARRAY_SIZE(ov5640_setting_30fps_VGA_640_480);
  81686. + retval = ov5640_download_firmware(pModeSetting, ArySize);
  81687. + } else if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
  81688. + (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
  81689. + /* change between subsampling and scaling
  81690. + * go through exposure calucation */
  81691. + retval = ov5640_change_mode_exposure_calc(frame_rate, mode);
  81692. + } else {
  81693. + /* change inside subsampling or scaling
  81694. + * download firmware directly */
  81695. + retval = ov5640_change_mode_direct(frame_rate, mode);
  81696. + }
  81697. +
  81698. + if (retval < 0)
  81699. + goto err;
  81700. +
  81701. + OV5640_set_AE_target(AE_Target);
  81702. + OV5640_get_light_freq();
  81703. + OV5640_set_bandingfilter();
  81704. + ov5640_set_virtual_channel(ov5640_data.csi);
  81705. +
  81706. + /* add delay to wait for sensor stable */
  81707. + if (mode == ov5640_mode_QSXGA_2592_1944) {
  81708. + /* dump the first two frames: 1/7.5*2
  81709. + * the frame rate of QSXGA is 7.5fps */
  81710. + msec_wait4stable = 267;
  81711. + } else if (frame_rate == ov5640_15_fps) {
  81712. + /* dump the first nine frames: 1/15*9 */
  81713. + msec_wait4stable = 600;
  81714. + } else if (frame_rate == ov5640_30_fps) {
  81715. + /* dump the first nine frames: 1/30*9 */
  81716. + msec_wait4stable = 300;
  81717. + }
  81718. + msleep(msec_wait4stable);
  81719. +
  81720. + if (mipi_csi2_info) {
  81721. + unsigned int i;
  81722. +
  81723. + i = 0;
  81724. +
  81725. + /* wait for mipi sensor ready */
  81726. + mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
  81727. + while ((mipi_reg == 0x200) && (i < 10)) {
  81728. + mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
  81729. + i++;
  81730. + msleep(10);
  81731. + }
  81732. +
  81733. + if (i >= 10) {
  81734. + pr_err("mipi csi2 can not receive sensor clk!\n");
  81735. + return -1;
  81736. + }
  81737. +
  81738. + i = 0;
  81739. +
  81740. + /* wait for mipi stable */
  81741. + mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
  81742. + while ((mipi_reg != 0x0) && (i < 10)) {
  81743. + mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
  81744. + i++;
  81745. + msleep(10);
  81746. + }
  81747. +
  81748. + if (i >= 10) {
  81749. + pr_err("mipi csi2 can not reveive data correctly!\n");
  81750. + return -1;
  81751. + }
  81752. + }
  81753. +err:
  81754. + return retval;
  81755. +}
  81756. +
  81757. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  81758. +
  81759. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  81760. +{
  81761. + if (s == NULL) {
  81762. + pr_err(" ERROR!! no slave device set!\n");
  81763. + return -1;
  81764. + }
  81765. +
  81766. + memset(p, 0, sizeof(*p));
  81767. + p->u.bt656.clock_curr = ov5640_data.mclk;
  81768. + pr_debug(" clock_curr=mclk=%d\n", ov5640_data.mclk);
  81769. + p->if_type = V4L2_IF_TYPE_BT656;
  81770. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  81771. + p->u.bt656.clock_min = OV5640_XCLK_MIN;
  81772. + p->u.bt656.clock_max = OV5640_XCLK_MAX;
  81773. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  81774. +
  81775. + return 0;
  81776. +}
  81777. +
  81778. +/*!
  81779. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  81780. + * @s: pointer to standard V4L2 device structure
  81781. + * @on: indicates power mode (on or off)
  81782. + *
  81783. + * Turns the power on or off, depending on the value of on and returns the
  81784. + * appropriate error code.
  81785. + */
  81786. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  81787. +{
  81788. + struct sensor_data *sensor = s->priv;
  81789. +
  81790. + if (on && !sensor->on) {
  81791. + if (io_regulator)
  81792. + if (regulator_enable(io_regulator) != 0)
  81793. + return -EIO;
  81794. + if (core_regulator)
  81795. + if (regulator_enable(core_regulator) != 0)
  81796. + return -EIO;
  81797. + if (gpo_regulator)
  81798. + if (regulator_enable(gpo_regulator) != 0)
  81799. + return -EIO;
  81800. + if (analog_regulator)
  81801. + if (regulator_enable(analog_regulator) != 0)
  81802. + return -EIO;
  81803. + /* Make sure power on */
  81804. + ov5640_standby(0);
  81805. + } else if (!on && sensor->on) {
  81806. + if (analog_regulator)
  81807. + regulator_disable(analog_regulator);
  81808. + if (core_regulator)
  81809. + regulator_disable(core_regulator);
  81810. + if (io_regulator)
  81811. + regulator_disable(io_regulator);
  81812. + if (gpo_regulator)
  81813. + regulator_disable(gpo_regulator);
  81814. +
  81815. + ov5640_standby(1);
  81816. + }
  81817. +
  81818. + sensor->on = on;
  81819. +
  81820. + return 0;
  81821. +}
  81822. +
  81823. +/*!
  81824. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  81825. + * @s: pointer to standard V4L2 device structure
  81826. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  81827. + *
  81828. + * Returns the sensor's video CAPTURE parameters.
  81829. + */
  81830. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  81831. +{
  81832. + struct sensor_data *sensor = s->priv;
  81833. + struct v4l2_captureparm *cparm = &a->parm.capture;
  81834. + int ret = 0;
  81835. +
  81836. + switch (a->type) {
  81837. + /* This is the only case currently handled. */
  81838. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  81839. + memset(a, 0, sizeof(*a));
  81840. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  81841. + cparm->capability = sensor->streamcap.capability;
  81842. + cparm->timeperframe = sensor->streamcap.timeperframe;
  81843. + cparm->capturemode = sensor->streamcap.capturemode;
  81844. + ret = 0;
  81845. + break;
  81846. +
  81847. + /* These are all the possible cases. */
  81848. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  81849. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  81850. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  81851. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  81852. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  81853. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  81854. + ret = -EINVAL;
  81855. + break;
  81856. +
  81857. + default:
  81858. + pr_debug(" type is unknown - %d\n", a->type);
  81859. + ret = -EINVAL;
  81860. + break;
  81861. + }
  81862. +
  81863. + return ret;
  81864. +}
  81865. +
  81866. +/*!
  81867. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  81868. + * @s: pointer to standard V4L2 device structure
  81869. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  81870. + *
  81871. + * Configures the sensor to use the input parameters, if possible. If
  81872. + * not possible, reverts to the old parameters and returns the
  81873. + * appropriate error code.
  81874. + */
  81875. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  81876. +{
  81877. + struct sensor_data *sensor = s->priv;
  81878. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  81879. + u32 tgt_fps; /* target frames per secound */
  81880. + enum ov5640_frame_rate frame_rate;
  81881. + enum ov5640_mode orig_mode;
  81882. + int ret = 0;
  81883. +
  81884. + /* Make sure power on */
  81885. + ov5640_standby(0);
  81886. +
  81887. + switch (a->type) {
  81888. + /* This is the only case currently handled. */
  81889. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  81890. + /* Check that the new frame rate is allowed. */
  81891. + if ((timeperframe->numerator == 0) ||
  81892. + (timeperframe->denominator == 0)) {
  81893. + timeperframe->denominator = DEFAULT_FPS;
  81894. + timeperframe->numerator = 1;
  81895. + }
  81896. +
  81897. + tgt_fps = timeperframe->denominator /
  81898. + timeperframe->numerator;
  81899. +
  81900. + if (tgt_fps > MAX_FPS) {
  81901. + timeperframe->denominator = MAX_FPS;
  81902. + timeperframe->numerator = 1;
  81903. + } else if (tgt_fps < MIN_FPS) {
  81904. + timeperframe->denominator = MIN_FPS;
  81905. + timeperframe->numerator = 1;
  81906. + }
  81907. +
  81908. + /* Actual frame rate we use */
  81909. + tgt_fps = timeperframe->denominator /
  81910. + timeperframe->numerator;
  81911. +
  81912. + if (tgt_fps == 15)
  81913. + frame_rate = ov5640_15_fps;
  81914. + else if (tgt_fps == 30)
  81915. + frame_rate = ov5640_30_fps;
  81916. + else {
  81917. + pr_err(" The camera frame rate is not supported!\n");
  81918. + return -EINVAL;
  81919. + }
  81920. +
  81921. + orig_mode = sensor->streamcap.capturemode;
  81922. + ret = ov5640_init_mode(frame_rate,
  81923. + (u32)a->parm.capture.capturemode, orig_mode);
  81924. + if (ret < 0)
  81925. + return ret;
  81926. +
  81927. + sensor->streamcap.timeperframe = *timeperframe;
  81928. + sensor->streamcap.capturemode =
  81929. + (u32)a->parm.capture.capturemode;
  81930. +
  81931. + break;
  81932. +
  81933. + /* These are all the possible cases. */
  81934. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  81935. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  81936. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  81937. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  81938. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  81939. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  81940. + pr_debug(" type is not " \
  81941. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  81942. + a->type);
  81943. + ret = -EINVAL;
  81944. + break;
  81945. +
  81946. + default:
  81947. + pr_debug(" type is unknown - %d\n", a->type);
  81948. + ret = -EINVAL;
  81949. + break;
  81950. + }
  81951. +
  81952. + return ret;
  81953. +}
  81954. +
  81955. +/*!
  81956. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  81957. + * @s: pointer to standard V4L2 device structure
  81958. + * @f: pointer to standard V4L2 v4l2_format structure
  81959. + *
  81960. + * Returns the sensor's current pixel format in the v4l2_format
  81961. + * parameter.
  81962. + */
  81963. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  81964. +{
  81965. + struct sensor_data *sensor = s->priv;
  81966. +
  81967. + f->fmt.pix = sensor->pix;
  81968. +
  81969. + return 0;
  81970. +}
  81971. +
  81972. +/*!
  81973. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  81974. + * @s: pointer to standard V4L2 device structure
  81975. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  81976. + *
  81977. + * If the requested control is supported, returns the control's current
  81978. + * value from the video_control[] array. Otherwise, returns -EINVAL
  81979. + * if the control is not supported.
  81980. + */
  81981. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  81982. +{
  81983. + int ret = 0;
  81984. +
  81985. + switch (vc->id) {
  81986. + case V4L2_CID_BRIGHTNESS:
  81987. + vc->value = ov5640_data.brightness;
  81988. + break;
  81989. + case V4L2_CID_HUE:
  81990. + vc->value = ov5640_data.hue;
  81991. + break;
  81992. + case V4L2_CID_CONTRAST:
  81993. + vc->value = ov5640_data.contrast;
  81994. + break;
  81995. + case V4L2_CID_SATURATION:
  81996. + vc->value = ov5640_data.saturation;
  81997. + break;
  81998. + case V4L2_CID_RED_BALANCE:
  81999. + vc->value = ov5640_data.red;
  82000. + break;
  82001. + case V4L2_CID_BLUE_BALANCE:
  82002. + vc->value = ov5640_data.blue;
  82003. + break;
  82004. + case V4L2_CID_EXPOSURE:
  82005. + vc->value = ov5640_data.ae_mode;
  82006. + break;
  82007. + default:
  82008. + ret = -EINVAL;
  82009. + }
  82010. +
  82011. + return ret;
  82012. +}
  82013. +
  82014. +/*!
  82015. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  82016. + * @s: pointer to standard V4L2 device structure
  82017. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  82018. + *
  82019. + * If the requested control is supported, sets the control's current
  82020. + * value in HW (and updates the video_control[] array). Otherwise,
  82021. + * returns -EINVAL if the control is not supported.
  82022. + */
  82023. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  82024. +{
  82025. + int retval = 0;
  82026. +
  82027. + pr_debug("In ov5640:ioctl_s_ctrl %d\n",
  82028. + vc->id);
  82029. +
  82030. + switch (vc->id) {
  82031. + case V4L2_CID_BRIGHTNESS:
  82032. + break;
  82033. + case V4L2_CID_CONTRAST:
  82034. + break;
  82035. + case V4L2_CID_SATURATION:
  82036. + break;
  82037. + case V4L2_CID_HUE:
  82038. + break;
  82039. + case V4L2_CID_AUTO_WHITE_BALANCE:
  82040. + break;
  82041. + case V4L2_CID_DO_WHITE_BALANCE:
  82042. + break;
  82043. + case V4L2_CID_RED_BALANCE:
  82044. + break;
  82045. + case V4L2_CID_BLUE_BALANCE:
  82046. + break;
  82047. + case V4L2_CID_GAMMA:
  82048. + break;
  82049. + case V4L2_CID_EXPOSURE:
  82050. + break;
  82051. + case V4L2_CID_AUTOGAIN:
  82052. + break;
  82053. + case V4L2_CID_GAIN:
  82054. + break;
  82055. + case V4L2_CID_HFLIP:
  82056. + break;
  82057. + case V4L2_CID_VFLIP:
  82058. + break;
  82059. + default:
  82060. + retval = -EPERM;
  82061. + break;
  82062. + }
  82063. +
  82064. + return retval;
  82065. +}
  82066. +
  82067. +/*!
  82068. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  82069. + * VIDIOC_ENUM_FRAMESIZES ioctl
  82070. + * @s: pointer to standard V4L2 device structure
  82071. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  82072. + *
  82073. + * Return 0 if successful, otherwise -EINVAL.
  82074. + */
  82075. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  82076. + struct v4l2_frmsizeenum *fsize)
  82077. +{
  82078. + if (fsize->index > ov5640_mode_MAX)
  82079. + return -EINVAL;
  82080. +
  82081. + fsize->pixel_format = ov5640_data.pix.pixelformat;
  82082. + fsize->discrete.width =
  82083. + max(ov5640_mode_info_data[0][fsize->index].width,
  82084. + ov5640_mode_info_data[1][fsize->index].width);
  82085. + fsize->discrete.height =
  82086. + max(ov5640_mode_info_data[0][fsize->index].height,
  82087. + ov5640_mode_info_data[1][fsize->index].height);
  82088. + return 0;
  82089. +}
  82090. +
  82091. +/*!
  82092. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  82093. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  82094. + * @s: pointer to standard V4L2 device structure
  82095. + * @id: pointer to int
  82096. + *
  82097. + * Return 0.
  82098. + */
  82099. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  82100. +{
  82101. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  82102. + V4L2_CHIP_MATCH_I2C_DRIVER;
  82103. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
  82104. + "ov5640_mipi_camera");
  82105. +
  82106. + return 0;
  82107. +}
  82108. +
  82109. +/*!
  82110. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  82111. + * @s: pointer to standard V4L2 device structure
  82112. + */
  82113. +static int ioctl_init(struct v4l2_int_device *s)
  82114. +{
  82115. +
  82116. + return 0;
  82117. +}
  82118. +
  82119. +/*!
  82120. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  82121. + * @s: pointer to standard V4L2 device structure
  82122. + * @fmt: pointer to standard V4L2 fmt description structure
  82123. + *
  82124. + * Return 0.
  82125. + */
  82126. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  82127. + struct v4l2_fmtdesc *fmt)
  82128. +{
  82129. + if (fmt->index > ov5640_mode_MAX)
  82130. + return -EINVAL;
  82131. +
  82132. + fmt->pixelformat = ov5640_data.pix.pixelformat;
  82133. +
  82134. + return 0;
  82135. +}
  82136. +
  82137. +/*!
  82138. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  82139. + * @s: pointer to standard V4L2 device structure
  82140. + *
  82141. + * Initialise the device when slave attaches to the master.
  82142. + */
  82143. +static int ioctl_dev_init(struct v4l2_int_device *s)
  82144. +{
  82145. + struct sensor_data *sensor = s->priv;
  82146. + u32 tgt_xclk; /* target xclk */
  82147. + u32 tgt_fps; /* target frames per secound */
  82148. + int ret;
  82149. + enum ov5640_frame_rate frame_rate;
  82150. + void *mipi_csi2_info;
  82151. +
  82152. + ov5640_data.on = true;
  82153. +
  82154. + /* mclk */
  82155. + tgt_xclk = ov5640_data.mclk;
  82156. + tgt_xclk = min(tgt_xclk, (u32)OV5640_XCLK_MAX);
  82157. + tgt_xclk = max(tgt_xclk, (u32)OV5640_XCLK_MIN);
  82158. + ov5640_data.mclk = tgt_xclk;
  82159. +
  82160. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  82161. +
  82162. + /* Default camera frame rate is set in probe */
  82163. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  82164. + sensor->streamcap.timeperframe.numerator;
  82165. +
  82166. + if (tgt_fps == 15)
  82167. + frame_rate = ov5640_15_fps;
  82168. + else if (tgt_fps == 30)
  82169. + frame_rate = ov5640_30_fps;
  82170. + else
  82171. + return -EINVAL; /* Only support 15fps or 30fps now. */
  82172. +
  82173. + mipi_csi2_info = mipi_csi2_get_info();
  82174. +
  82175. + /* enable mipi csi2 */
  82176. + if (mipi_csi2_info)
  82177. + mipi_csi2_enable(mipi_csi2_info);
  82178. + else {
  82179. + printk(KERN_ERR "%s() in %s: Fail to get mipi_csi2_info!\n",
  82180. + __func__, __FILE__);
  82181. + return -EPERM;
  82182. + }
  82183. +
  82184. + ret = ov5640_init_mode(frame_rate, ov5640_mode_INIT, ov5640_mode_INIT);
  82185. +
  82186. + return ret;
  82187. +}
  82188. +
  82189. +/*!
  82190. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  82191. + * @s: pointer to standard V4L2 device structure
  82192. + *
  82193. + * Delinitialise the device when slave detaches to the master.
  82194. + */
  82195. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  82196. +{
  82197. + void *mipi_csi2_info;
  82198. +
  82199. + mipi_csi2_info = mipi_csi2_get_info();
  82200. +
  82201. + /* disable mipi csi2 */
  82202. + if (mipi_csi2_info)
  82203. + if (mipi_csi2_get_status(mipi_csi2_info))
  82204. + mipi_csi2_disable(mipi_csi2_info);
  82205. +
  82206. + return 0;
  82207. +}
  82208. +
  82209. +/*!
  82210. + * This structure defines all the ioctls for this module and links them to the
  82211. + * enumeration.
  82212. + */
  82213. +static struct v4l2_int_ioctl_desc ov5640_ioctl_desc[] = {
  82214. + {vidioc_int_dev_init_num, (v4l2_int_ioctl_func *) ioctl_dev_init},
  82215. + {vidioc_int_dev_exit_num, ioctl_dev_exit},
  82216. + {vidioc_int_s_power_num, (v4l2_int_ioctl_func *) ioctl_s_power},
  82217. + {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *) ioctl_g_ifparm},
  82218. +/* {vidioc_int_g_needs_reset_num,
  82219. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
  82220. +/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
  82221. + {vidioc_int_init_num, (v4l2_int_ioctl_func *) ioctl_init},
  82222. + {vidioc_int_enum_fmt_cap_num,
  82223. + (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
  82224. +/* {vidioc_int_try_fmt_cap_num,
  82225. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
  82226. + {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
  82227. +/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_s_fmt_cap}, */
  82228. + {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
  82229. + {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
  82230. +/* {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */
  82231. + {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
  82232. + {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
  82233. + {vidioc_int_enum_framesizes_num,
  82234. + (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
  82235. + {vidioc_int_g_chip_ident_num,
  82236. + (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
  82237. +};
  82238. +
  82239. +static struct v4l2_int_slave ov5640_slave = {
  82240. + .ioctls = ov5640_ioctl_desc,
  82241. + .num_ioctls = ARRAY_SIZE(ov5640_ioctl_desc),
  82242. +};
  82243. +
  82244. +static struct v4l2_int_device ov5640_int_device = {
  82245. + .module = THIS_MODULE,
  82246. + .name = "ov5640",
  82247. + .type = v4l2_int_type_slave,
  82248. + .u = {
  82249. + .slave = &ov5640_slave,
  82250. + },
  82251. +};
  82252. +
  82253. +/*!
  82254. + * ov5640 I2C probe function
  82255. + *
  82256. + * @param adapter struct i2c_adapter *
  82257. + * @return Error code indicating success or failure
  82258. + */
  82259. +static int ov5640_probe(struct i2c_client *client,
  82260. + const struct i2c_device_id *id)
  82261. +{
  82262. + struct device *dev = &client->dev;
  82263. + int retval;
  82264. + u8 chip_id_high, chip_id_low;
  82265. +
  82266. + /* request power down pin */
  82267. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  82268. + if (!gpio_is_valid(pwn_gpio)) {
  82269. + dev_warn(dev, "no sensor pwdn pin available");
  82270. + return -EINVAL;
  82271. + }
  82272. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  82273. + "ov5640_mipi_pwdn");
  82274. + if (retval < 0)
  82275. + return retval;
  82276. +
  82277. + /* request reset pin */
  82278. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  82279. + if (!gpio_is_valid(rst_gpio)) {
  82280. + dev_warn(dev, "no sensor reset pin available");
  82281. + return -EINVAL;
  82282. + }
  82283. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  82284. + "ov5640_mipi_reset");
  82285. + if (retval < 0)
  82286. + return retval;
  82287. +
  82288. + /* Set initial values for the sensor struct. */
  82289. + memset(&ov5640_data, 0, sizeof(ov5640_data));
  82290. + ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  82291. + if (IS_ERR(ov5640_data.sensor_clk)) {
  82292. + /* assuming clock enabled by default */
  82293. + ov5640_data.sensor_clk = NULL;
  82294. + dev_err(dev, "clock-frequency missing or invalid\n");
  82295. + return PTR_ERR(ov5640_data.sensor_clk);
  82296. + }
  82297. +
  82298. + retval = of_property_read_u32(dev->of_node, "mclk",
  82299. + &(ov5640_data.mclk));
  82300. + if (retval) {
  82301. + dev_err(dev, "mclk missing or invalid\n");
  82302. + return retval;
  82303. + }
  82304. +
  82305. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  82306. + (u32 *) &(ov5640_data.mclk_source));
  82307. + if (retval) {
  82308. + dev_err(dev, "mclk_source missing or invalid\n");
  82309. + return retval;
  82310. + }
  82311. +
  82312. + retval = of_property_read_u32(dev->of_node, "csi_id",
  82313. + &(ov5640_data.csi));
  82314. + if (retval) {
  82315. + dev_err(dev, "csi id missing or invalid\n");
  82316. + return retval;
  82317. + }
  82318. +
  82319. + clk_prepare_enable(ov5640_data.sensor_clk);
  82320. +
  82321. + ov5640_data.io_init = ov5640_reset;
  82322. + ov5640_data.i2c_client = client;
  82323. + ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  82324. + ov5640_data.pix.width = 640;
  82325. + ov5640_data.pix.height = 480;
  82326. + ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  82327. + V4L2_CAP_TIMEPERFRAME;
  82328. + ov5640_data.streamcap.capturemode = 0;
  82329. + ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  82330. + ov5640_data.streamcap.timeperframe.numerator = 1;
  82331. +
  82332. + ov5640_power_on(dev);
  82333. +
  82334. + ov5640_reset();
  82335. +
  82336. + ov5640_standby(0);
  82337. +
  82338. + retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
  82339. + if (retval < 0 || chip_id_high != 0x56) {
  82340. + pr_warning("camera ov5640_mipi is not found\n");
  82341. + clk_disable_unprepare(ov5640_data.sensor_clk);
  82342. + return -ENODEV;
  82343. + }
  82344. + retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
  82345. + if (retval < 0 || chip_id_low != 0x40) {
  82346. + pr_warning("camera ov5640_mipi is not found\n");
  82347. + clk_disable_unprepare(ov5640_data.sensor_clk);
  82348. + return -ENODEV;
  82349. + }
  82350. +
  82351. + ov5640_standby(1);
  82352. +
  82353. + ov5640_int_device.priv = &ov5640_data;
  82354. + retval = v4l2_int_device_register(&ov5640_int_device);
  82355. +
  82356. + clk_disable_unprepare(ov5640_data.sensor_clk);
  82357. +
  82358. + pr_info("camera ov5640_mipi is found\n");
  82359. + return retval;
  82360. +}
  82361. +
  82362. +/*!
  82363. + * ov5640 I2C detach function
  82364. + *
  82365. + * @param client struct i2c_client *
  82366. + * @return Error code indicating success or failure
  82367. + */
  82368. +static int ov5640_remove(struct i2c_client *client)
  82369. +{
  82370. + v4l2_int_device_unregister(&ov5640_int_device);
  82371. +
  82372. + if (gpo_regulator)
  82373. + regulator_disable(gpo_regulator);
  82374. +
  82375. + if (analog_regulator)
  82376. + regulator_disable(analog_regulator);
  82377. +
  82378. + if (core_regulator)
  82379. + regulator_disable(core_regulator);
  82380. +
  82381. + if (io_regulator)
  82382. + regulator_disable(io_regulator);
  82383. +
  82384. + return 0;
  82385. +}
  82386. +
  82387. +/*!
  82388. + * ov5640 init function
  82389. + * Called by insmod ov5640_camera.ko.
  82390. + *
  82391. + * @return Error code indicating success or failure
  82392. + */
  82393. +static __init int ov5640_init(void)
  82394. +{
  82395. + u8 err;
  82396. +
  82397. + err = i2c_add_driver(&ov5640_i2c_driver);
  82398. + if (err != 0)
  82399. + pr_err("%s:driver registration failed, error=%d\n",
  82400. + __func__, err);
  82401. +
  82402. + return err;
  82403. +}
  82404. +
  82405. +/*!
  82406. + * OV5640 cleanup function
  82407. + * Called on rmmod ov5640_camera.ko
  82408. + *
  82409. + * @return Error code indicating success or failure
  82410. + */
  82411. +static void __exit ov5640_clean(void)
  82412. +{
  82413. + i2c_del_driver(&ov5640_i2c_driver);
  82414. +}
  82415. +
  82416. +module_init(ov5640_init);
  82417. +module_exit(ov5640_clean);
  82418. +
  82419. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  82420. +MODULE_DESCRIPTION("OV5640 MIPI Camera Driver");
  82421. +MODULE_LICENSE("GPL");
  82422. +MODULE_VERSION("1.0");
  82423. +MODULE_ALIAS("CSI");
  82424. diff -Nur linux-3.14.17/drivers/media/platform/mxc/capture/ov5642.c linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5642.c
  82425. --- linux-3.14.17/drivers/media/platform/mxc/capture/ov5642.c 1970-01-01 01:00:00.000000000 +0100
  82426. +++ linux-imx6-3.14/drivers/media/platform/mxc/capture/ov5642.c 2014-09-11 18:06:02.254038983 +0200
  82427. @@ -0,0 +1,4252 @@
  82428. +/*
  82429. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  82430. + */
  82431. +
  82432. +/*
  82433. + * This program is free software; you can redistribute it and/or modify
  82434. + * it under the terms of the GNU General Public License as published by
  82435. + * the Free Software Foundation; either version 2 of the License, or
  82436. + * (at your option) any later version.
  82437. +
  82438. + * This program is distributed in the hope that it will be useful,
  82439. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  82440. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  82441. + * GNU General Public License for more details.
  82442. +
  82443. + * You should have received a copy of the GNU General Public License along
  82444. + * with this program; if not, write to the Free Software Foundation, Inc.,
  82445. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  82446. + */
  82447. +
  82448. +#include <linux/module.h>
  82449. +#include <linux/init.h>
  82450. +#include <linux/slab.h>
  82451. +#include <linux/ctype.h>
  82452. +#include <linux/types.h>
  82453. +#include <linux/delay.h>
  82454. +#include <linux/clk.h>
  82455. +#include <linux/of_device.h>
  82456. +#include <linux/i2c.h>
  82457. +#include <linux/of_gpio.h>
  82458. +#include <linux/pinctrl/consumer.h>
  82459. +#include <linux/regulator/consumer.h>
  82460. +#include <linux/fsl_devices.h>
  82461. +#include <media/v4l2-chip-ident.h>
  82462. +#include <media/v4l2-int-device.h>
  82463. +#include "mxc_v4l2_capture.h"
  82464. +
  82465. +#define OV5642_VOLTAGE_ANALOG 2800000
  82466. +#define OV5642_VOLTAGE_DIGITAL_CORE 1500000
  82467. +#define OV5642_VOLTAGE_DIGITAL_IO 1800000
  82468. +
  82469. +#define MIN_FPS 15
  82470. +#define MAX_FPS 30
  82471. +#define DEFAULT_FPS 30
  82472. +
  82473. +#define OV5642_XCLK_MIN 6000000
  82474. +#define OV5642_XCLK_MAX 24000000
  82475. +
  82476. +#define OV5642_CHIP_ID_HIGH_BYTE 0x300A
  82477. +#define OV5642_CHIP_ID_LOW_BYTE 0x300B
  82478. +
  82479. +enum ov5642_mode {
  82480. + ov5642_mode_MIN = 0,
  82481. + ov5642_mode_VGA_640_480 = 0,
  82482. + ov5642_mode_QVGA_320_240 = 1,
  82483. + ov5642_mode_NTSC_720_480 = 2,
  82484. + ov5642_mode_PAL_720_576 = 3,
  82485. + ov5642_mode_720P_1280_720 = 4,
  82486. + ov5642_mode_1080P_1920_1080 = 5,
  82487. + ov5642_mode_QSXGA_2592_1944 = 6,
  82488. + ov5642_mode_QCIF_176_144 = 7,
  82489. + ov5642_mode_XGA_1024_768 = 8,
  82490. + ov5642_mode_MAX = 8
  82491. +};
  82492. +
  82493. +enum ov5642_frame_rate {
  82494. + ov5642_15_fps,
  82495. + ov5642_30_fps
  82496. +};
  82497. +
  82498. +static int ov5642_framerates[] = {
  82499. + [ov5642_15_fps] = 15,
  82500. + [ov5642_30_fps] = 30,
  82501. +};
  82502. +
  82503. +struct reg_value {
  82504. + u16 u16RegAddr;
  82505. + u8 u8Val;
  82506. + u8 u8Mask;
  82507. + u32 u32Delay_ms;
  82508. +};
  82509. +
  82510. +struct ov5642_mode_info {
  82511. + enum ov5642_mode mode;
  82512. + u32 width;
  82513. + u32 height;
  82514. + struct reg_value *init_data_ptr;
  82515. + u32 init_data_size;
  82516. +};
  82517. +
  82518. +/*!
  82519. + * Maintains the information on the current state of the sesor.
  82520. + */
  82521. +static struct sensor_data ov5642_data;
  82522. +static int pwn_gpio, rst_gpio;
  82523. +
  82524. +static struct reg_value ov5642_rot_none_VGA[] = {
  82525. + {0x3818, 0xc1, 0x00, 0x00}, {0x3621, 0x87, 0x00, 0x00},
  82526. +};
  82527. +
  82528. +static struct reg_value ov5642_rot_vert_flip_VGA[] = {
  82529. + {0x3818, 0x20, 0xbf, 0x00}, {0x3621, 0x20, 0xff, 0x00},
  82530. +};
  82531. +
  82532. +static struct reg_value ov5642_rot_horiz_flip_VGA[] = {
  82533. + {0x3818, 0x81, 0x00, 0x01}, {0x3621, 0xa7, 0x00, 0x00},
  82534. +};
  82535. +
  82536. +static struct reg_value ov5642_rot_180_VGA[] = {
  82537. + {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
  82538. +};
  82539. +
  82540. +
  82541. +static struct reg_value ov5642_rot_none_FULL[] = {
  82542. + {0x3818, 0xc0, 0x00, 0x00}, {0x3621, 0x09, 0x00, 0x00},
  82543. +};
  82544. +
  82545. +static struct reg_value ov5642_rot_vert_flip_FULL[] = {
  82546. + {0x3818, 0x20, 0xbf, 0x01}, {0x3621, 0x20, 0xff, 0x00},
  82547. +};
  82548. +
  82549. +static struct reg_value ov5642_rot_horiz_flip_FULL[] = {
  82550. + {0x3818, 0x80, 0x00, 0x01}, {0x3621, 0x29, 0x00, 0x00},
  82551. +};
  82552. +
  82553. +static struct reg_value ov5642_rot_180_FULL[] = {
  82554. + {0x3818, 0x60, 0xff, 0x00}, {0x3621, 0x00, 0xdf, 0x00},
  82555. +};
  82556. +
  82557. +
  82558. +static struct reg_value ov5642_initial_setting[] = {
  82559. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82560. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82561. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82562. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82563. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82564. + {0x3010, 0x00, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82565. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82566. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82567. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82568. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82569. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82570. + {0x3606, 0x3f, 0, 0}, {0x3c00, 0x04, 0, 0}, {0x3c01, 0x80, 0, 0},
  82571. + {0x5000, 0x4f, 0, 0}, {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0},
  82572. + {0x5182, 0x00, 0, 0}, {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0},
  82573. + {0x5001, 0xff, 0, 0}, {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0},
  82574. + {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0},
  82575. + {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0},
  82576. + {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
  82577. + {0x380b, 0xe0, 0, 0}, {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0},
  82578. + {0x501f, 0x00, 0, 0}, {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0},
  82579. + {0x3503, 0x07, 0, 0}, {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0},
  82580. + {0x350b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0},
  82581. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  82582. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0},
  82583. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  82584. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  82585. + {0x3801, 0x80, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0},
  82586. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0},
  82587. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  82588. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  82589. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  82590. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  82591. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  82592. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  82593. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  82594. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  82595. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  82596. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  82597. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  82598. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  82599. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  82600. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  82601. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  82602. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  82603. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  82604. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x0b, 0, 0}, {0x3a02, 0x00, 0, 0},
  82605. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  82606. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  82607. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  82608. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  82609. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82610. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  82611. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  82612. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  82613. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  82614. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  82615. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  82616. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  82617. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  82618. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  82619. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  82620. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  82621. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  82622. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  82623. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  82624. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  82625. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  82626. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  82627. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  82628. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  82629. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  82630. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  82631. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  82632. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  82633. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  82634. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  82635. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  82636. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  82637. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  82638. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  82639. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  82640. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  82641. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  82642. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  82643. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  82644. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  82645. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  82646. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  82647. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  82648. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  82649. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  82650. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  82651. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  82652. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  82653. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  82654. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  82655. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  82656. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  82657. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  82658. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  82659. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  82660. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  82661. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  82662. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82663. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  82664. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  82665. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  82666. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  82667. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  82668. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  82669. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  82670. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  82671. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  82672. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  82673. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  82674. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  82675. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  82676. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  82677. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  82678. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  82679. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  82680. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  82681. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  82682. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  82683. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  82684. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  82685. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  82686. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  82687. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  82688. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  82689. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  82690. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  82691. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  82692. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  82693. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  82694. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  82695. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  82696. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  82697. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  82698. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  82699. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  82700. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  82701. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  82702. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  82703. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  82704. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  82705. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  82706. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  82707. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  82708. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  82709. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  82710. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  82711. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  82712. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  82713. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  82714. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  82715. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  82716. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  82717. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  82718. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  82719. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  82720. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  82721. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  82722. + {0x302b, 0x00, 0, 300},
  82723. +};
  82724. +
  82725. +static struct reg_value ov5642_setting_15fps_QCIF_176_144[] = {
  82726. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82727. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82728. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82729. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82730. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  82731. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82732. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82733. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82734. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82735. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82736. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82737. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82738. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82739. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82740. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82741. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82742. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82743. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82744. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82745. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82746. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82747. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82748. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82749. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82750. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82751. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82752. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82753. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82754. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82755. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82756. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82757. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82758. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82759. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82760. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82761. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82762. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82763. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82764. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82765. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82766. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82767. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82768. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82769. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82770. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82771. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82772. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82773. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82774. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82775. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82776. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82777. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82778. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82779. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82780. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82781. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82782. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82783. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82784. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82785. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82786. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82787. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82788. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82789. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82790. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82791. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82792. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82793. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82794. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82795. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82796. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82797. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  82798. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  82799. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  82800. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  82801. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  82802. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  82803. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  82804. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  82805. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  82806. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  82807. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  82808. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  82809. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  82810. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  82811. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  82812. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  82813. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  82814. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  82815. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  82816. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  82817. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  82818. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  82819. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  82820. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  82821. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  82822. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  82823. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  82824. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  82825. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  82826. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  82827. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  82828. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  82829. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  82830. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  82831. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  82832. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  82833. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  82834. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  82835. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  82836. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  82837. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  82838. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  82839. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  82840. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  82841. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  82842. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  82843. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  82844. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  82845. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  82846. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  82847. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  82848. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  82849. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  82850. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  82851. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  82852. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  82853. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  82854. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  82855. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  82856. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  82857. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  82858. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  82859. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  82860. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  82861. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  82862. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  82863. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  82864. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  82865. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  82866. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  82867. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  82868. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  82869. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  82870. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  82871. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  82872. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  82873. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  82874. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  82875. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  82876. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  82877. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  82878. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  82879. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  82880. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  82881. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  82882. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  82883. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  82884. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  82885. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  82886. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  82887. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  82888. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  82889. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  82890. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  82891. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  82892. + {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
  82893. +};
  82894. +
  82895. +static struct reg_value ov5642_setting_30fps_QCIF_176_144[] = {
  82896. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  82897. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  82898. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  82899. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  82900. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x10, 0, 0},
  82901. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  82902. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  82903. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  82904. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  82905. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  82906. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  82907. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  82908. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  82909. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  82910. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  82911. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  82912. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  82913. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  82914. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  82915. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  82916. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  82917. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  82918. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  82919. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  82920. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  82921. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  82922. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  82923. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  82924. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  82925. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  82926. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  82927. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  82928. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  82929. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  82930. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  82931. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  82932. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  82933. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  82934. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  82935. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  82936. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  82937. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  82938. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  82939. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  82940. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  82941. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  82942. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  82943. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  82944. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  82945. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  82946. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  82947. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  82948. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  82949. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  82950. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  82951. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  82952. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  82953. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  82954. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  82955. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  82956. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  82957. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  82958. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  82959. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  82960. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  82961. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  82962. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  82963. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  82964. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  82965. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  82966. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  82967. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  82968. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  82969. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  82970. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  82971. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  82972. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  82973. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  82974. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  82975. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  82976. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  82977. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  82978. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  82979. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  82980. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  82981. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  82982. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  82983. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  82984. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  82985. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  82986. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  82987. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  82988. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  82989. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  82990. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  82991. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  82992. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  82993. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  82994. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  82995. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  82996. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  82997. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  82998. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  82999. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  83000. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  83001. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  83002. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  83003. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  83004. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  83005. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  83006. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  83007. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  83008. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  83009. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  83010. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  83011. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  83012. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  83013. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  83014. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  83015. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  83016. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  83017. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  83018. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  83019. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  83020. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  83021. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  83022. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  83023. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  83024. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  83025. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  83026. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  83027. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  83028. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  83029. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  83030. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  83031. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  83032. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  83033. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  83034. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  83035. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  83036. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  83037. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  83038. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  83039. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  83040. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  83041. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  83042. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  83043. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  83044. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  83045. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  83046. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  83047. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  83048. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  83049. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  83050. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  83051. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  83052. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  83053. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  83054. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  83055. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  83056. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  83057. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  83058. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  83059. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  83060. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  83061. + {0x3808, 0x00, 0, 0}, {0x3809, 0xb0, 0, 0}, {0x380a, 0x00, 0, 0},
  83062. + {0x380b, 0x90, 0, 0}, {0x3a00, 0x78, 0, 0},
  83063. +};
  83064. +
  83065. +static struct reg_value ov5642_setting_15fps_QSXGA_2592_1944[] = {
  83066. + {0x3503, 0x07, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
  83067. + {0x3002, 0x00, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  83068. + {0x3005, 0xff, 0, 0}, {0x3006, 0xff, 0, 0}, {0x3007, 0x3f, 0, 0},
  83069. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3818, 0xc0, 0, 0},
  83070. + {0x3621, 0x09, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  83071. + {0x3602, 0xe4, 0, 0}, {0x3612, 0xac, 0, 0}, {0x3613, 0x44, 0, 0},
  83072. + {0x3622, 0x60, 0, 0}, {0x3623, 0x22, 0, 0}, {0x3604, 0x48, 0, 0},
  83073. + {0x3705, 0xda, 0, 0}, {0x370a, 0x80, 0, 0}, {0x3801, 0x95, 0, 0},
  83074. + {0x3803, 0x0e, 0, 0}, {0x3804, 0x0a, 0, 0}, {0x3805, 0x20, 0, 0},
  83075. + {0x3806, 0x07, 0, 0}, {0x3807, 0x98, 0, 0}, {0x3808, 0x0a, 0, 0},
  83076. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  83077. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  83078. + {0x380f, 0xd0, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3815, 0x44, 0, 0},
  83079. + {0x3824, 0x11, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  83080. + {0x3a00, 0x78, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  83081. + {0x5682, 0x0a, 0, 0}, {0x5683, 0x20, 0, 0}, {0x5686, 0x07, 0, 0},
  83082. + {0x5687, 0x98, 0, 0}, {0x5001, 0xff, 0, 0}, {0x589b, 0x00, 0, 0},
  83083. + {0x589a, 0xc0, 0, 0}, {0x4407, 0x04, 0, 0}, {0x3008, 0x02, 0, 0},
  83084. + {0x460b, 0x37, 0, 0}, {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0},
  83085. + {0x4713, 0x03, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x3815, 0x01, 0, 0},
  83086. + {0x501f, 0x00, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
  83087. + {0x5002, 0xe0, 0, 0}, {0x530a, 0x01, 0, 0}, {0x530d, 0x10, 0, 0},
  83088. + {0x530c, 0x04, 0, 0}, {0x5312, 0x20, 0, 0}, {0x5282, 0x01, 0, 0},
  83089. + {0x3010, 0x10, 0, 0}, {0x3012, 0x00, 0, 0},
  83090. +};
  83091. +
  83092. +
  83093. +static struct reg_value ov5642_setting_VGA_2_QVGA[] = {
  83094. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  83095. + {0x380b, 0xf0, 0, 0}, {0x3815, 0x04, 0, 0},
  83096. +};
  83097. +
  83098. +static struct reg_value ov5642_setting_QSXGA_2_VGA[] = {
  83099. + {0x3503, 0x00, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0},
  83100. + {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0},
  83101. + {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0},
  83102. + {0x3010, 0x00, 0, 0}, {0x3818, 0xc1, 0, 0}, {0x3621, 0x87, 0, 0},
  83103. + {0x350c, 0x03, 0, 0}, {0x350d, 0xe8, 0, 0}, {0x3602, 0xfc, 0, 0},
  83104. + {0x3612, 0xff, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3622, 0x60, 0, 0},
  83105. + {0x3623, 0x01, 0, 0}, {0x3604, 0x48, 0, 0}, {0x3705, 0xdb, 0, 0},
  83106. + {0x370a, 0x81, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  83107. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
  83108. + {0x3807, 0xc0, 0, 0}, {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0},
  83109. + {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x0c, 0, 0},
  83110. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  83111. + {0x3810, 0x40, 0, 0}, {0x3815, 0x04, 0, 0}, {0x3824, 0x11, 0, 0},
  83112. + {0x3825, 0xb4, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3a00, 0x78, 0, 0},
  83113. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x5682, 0x05, 0, 0},
  83114. + {0x5683, 0x00, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0},
  83115. + {0x5001, 0xff, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  83116. + {0x4407, 0x0c, 0, 0}, {0x3008, 0x02, 0, 0}, {0x460b, 0x37, 0, 0},
  83117. + {0x460c, 0x22, 0, 0}, {0x471d, 0x05, 0, 0}, {0x4713, 0x02, 0, 0},
  83118. + {0x471c, 0xd0, 0, 0}, {0x3815, 0x04, 0, 0}, {0x501f, 0x00, 0, 0},
  83119. + {0x3002, 0x5c, 0, 0}, {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
  83120. + {0x530a, 0x01, 0, 0}, {0x530d, 0x0c, 0, 0}, {0x530c, 0x00, 0, 0},
  83121. + {0x5312, 0x40, 0, 0}, {0x5282, 0x00, 0, 0},
  83122. + {0x3012, 0x02, 0, 0}, {0x3010, 0x00, 0, 0},
  83123. +};
  83124. +
  83125. +static struct reg_value ov5642_setting_30fps_VGA_640_480[] = {
  83126. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  83127. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  83128. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  83129. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  83130. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  83131. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  83132. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  83133. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  83134. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  83135. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  83136. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  83137. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  83138. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  83139. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  83140. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  83141. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  83142. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  83143. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  83144. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  83145. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  83146. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  83147. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  83148. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  83149. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  83150. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83151. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  83152. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  83153. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  83154. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  83155. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  83156. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  83157. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  83158. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  83159. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  83160. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  83161. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  83162. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  83163. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  83164. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  83165. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  83166. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  83167. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  83168. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  83169. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  83170. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  83171. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  83172. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  83173. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  83174. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  83175. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83176. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  83177. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  83178. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  83179. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  83180. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  83181. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  83182. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  83183. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  83184. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  83185. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  83186. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  83187. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  83188. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  83189. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  83190. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  83191. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  83192. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  83193. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  83194. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  83195. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  83196. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  83197. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  83198. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  83199. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  83200. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  83201. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  83202. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  83203. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  83204. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  83205. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  83206. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  83207. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  83208. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  83209. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  83210. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  83211. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  83212. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  83213. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  83214. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  83215. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  83216. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  83217. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  83218. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  83219. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  83220. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  83221. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  83222. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  83223. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  83224. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  83225. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  83226. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  83227. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  83228. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  83229. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  83230. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  83231. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  83232. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  83233. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  83234. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  83235. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  83236. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  83237. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  83238. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  83239. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  83240. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  83241. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  83242. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  83243. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  83244. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  83245. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  83246. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  83247. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  83248. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  83249. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  83250. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  83251. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  83252. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  83253. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  83254. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  83255. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  83256. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  83257. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  83258. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  83259. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  83260. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  83261. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  83262. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  83263. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  83264. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  83265. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  83266. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  83267. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  83268. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  83269. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  83270. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  83271. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  83272. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  83273. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  83274. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  83275. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  83276. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  83277. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  83278. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  83279. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  83280. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  83281. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  83282. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  83283. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  83284. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  83285. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  83286. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  83287. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  83288. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  83289. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  83290. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  83291. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  83292. +};
  83293. +
  83294. +static struct reg_value ov5642_setting_15fps_VGA_640_480[] = {
  83295. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  83296. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  83297. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  83298. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  83299. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  83300. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  83301. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  83302. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  83303. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  83304. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  83305. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  83306. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  83307. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  83308. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  83309. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  83310. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  83311. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  83312. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  83313. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  83314. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  83315. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  83316. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  83317. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  83318. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
  83319. + {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83320. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  83321. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  83322. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  83323. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  83324. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  83325. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  83326. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  83327. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  83328. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  83329. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  83330. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  83331. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  83332. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  83333. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  83334. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  83335. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  83336. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  83337. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  83338. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  83339. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  83340. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  83341. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  83342. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  83343. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  83344. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83345. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  83346. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  83347. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  83348. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  83349. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  83350. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  83351. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  83352. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  83353. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  83354. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  83355. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  83356. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  83357. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  83358. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  83359. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  83360. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  83361. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  83362. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  83363. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  83364. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  83365. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  83366. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  83367. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  83368. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  83369. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  83370. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  83371. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  83372. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  83373. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  83374. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  83375. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  83376. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  83377. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  83378. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  83379. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  83380. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  83381. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  83382. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  83383. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  83384. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  83385. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  83386. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  83387. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  83388. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  83389. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  83390. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  83391. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  83392. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  83393. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  83394. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  83395. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  83396. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  83397. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  83398. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  83399. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  83400. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  83401. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  83402. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  83403. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  83404. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  83405. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  83406. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  83407. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  83408. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  83409. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  83410. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  83411. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  83412. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  83413. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  83414. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  83415. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  83416. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  83417. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  83418. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  83419. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  83420. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  83421. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  83422. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  83423. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  83424. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  83425. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  83426. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  83427. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  83428. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  83429. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  83430. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  83431. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  83432. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  83433. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  83434. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  83435. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  83436. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  83437. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  83438. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  83439. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  83440. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  83441. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  83442. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  83443. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  83444. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  83445. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  83446. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  83447. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  83448. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  83449. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  83450. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  83451. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  83452. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  83453. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  83454. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  83455. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  83456. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  83457. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  83458. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  83459. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  83460. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  83461. +};
  83462. +
  83463. +
  83464. +static struct reg_value ov5642_setting_30fps_XGA_1024_768[] = {
  83465. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  83466. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  83467. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  83468. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  83469. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  83470. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  83471. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  83472. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  83473. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  83474. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  83475. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  83476. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  83477. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  83478. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  83479. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  83480. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  83481. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  83482. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  83483. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  83484. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  83485. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  83486. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  83487. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  83488. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  83489. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83490. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  83491. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  83492. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  83493. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  83494. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  83495. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  83496. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  83497. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  83498. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  83499. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  83500. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  83501. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  83502. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  83503. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  83504. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  83505. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  83506. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  83507. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  83508. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  83509. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  83510. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  83511. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  83512. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  83513. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  83514. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83515. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  83516. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  83517. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  83518. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  83519. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  83520. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  83521. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  83522. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  83523. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  83524. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  83525. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  83526. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  83527. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  83528. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  83529. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  83530. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  83531. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  83532. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  83533. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  83534. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  83535. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  83536. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  83537. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  83538. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  83539. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  83540. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  83541. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  83542. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  83543. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  83544. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  83545. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  83546. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  83547. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  83548. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  83549. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  83550. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  83551. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  83552. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  83553. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  83554. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  83555. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  83556. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  83557. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  83558. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  83559. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  83560. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  83561. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  83562. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  83563. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  83564. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  83565. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  83566. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  83567. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  83568. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  83569. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  83570. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  83571. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  83572. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  83573. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  83574. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  83575. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  83576. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  83577. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  83578. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  83579. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  83580. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  83581. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  83582. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  83583. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  83584. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  83585. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  83586. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  83587. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  83588. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  83589. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  83590. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  83591. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  83592. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  83593. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  83594. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  83595. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  83596. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  83597. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  83598. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  83599. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  83600. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  83601. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  83602. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  83603. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  83604. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  83605. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  83606. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  83607. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  83608. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  83609. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  83610. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  83611. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  83612. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  83613. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  83614. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  83615. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  83616. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  83617. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  83618. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  83619. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  83620. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  83621. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  83622. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  83623. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  83624. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  83625. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  83626. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  83627. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  83628. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  83629. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  83630. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  83631. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  83632. + {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
  83633. +};
  83634. +
  83635. +static struct reg_value ov5642_setting_15fps_XGA_1024_768[] = {
  83636. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  83637. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  83638. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  83639. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  83640. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  83641. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  83642. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  83643. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  83644. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  83645. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  83646. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  83647. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  83648. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  83649. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  83650. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  83651. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  83652. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  83653. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  83654. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  83655. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  83656. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  83657. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  83658. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  83659. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x07, 0, 0},
  83660. + {0x380f, 0xd0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83661. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  83662. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  83663. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  83664. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  83665. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  83666. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  83667. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  83668. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  83669. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  83670. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  83671. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  83672. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  83673. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  83674. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  83675. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  83676. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  83677. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  83678. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  83679. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  83680. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  83681. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  83682. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  83683. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  83684. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  83685. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83686. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  83687. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  83688. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  83689. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  83690. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  83691. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  83692. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  83693. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  83694. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  83695. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  83696. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  83697. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  83698. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  83699. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  83700. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  83701. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  83702. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  83703. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  83704. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  83705. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  83706. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  83707. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  83708. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  83709. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  83710. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  83711. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  83712. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  83713. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  83714. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  83715. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  83716. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  83717. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  83718. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  83719. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  83720. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  83721. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  83722. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  83723. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  83724. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  83725. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  83726. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  83727. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  83728. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  83729. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  83730. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  83731. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  83732. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  83733. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  83734. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  83735. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  83736. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  83737. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  83738. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  83739. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  83740. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  83741. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  83742. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  83743. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  83744. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  83745. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  83746. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  83747. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  83748. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  83749. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  83750. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  83751. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  83752. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  83753. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  83754. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  83755. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  83756. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  83757. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  83758. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  83759. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  83760. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  83761. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  83762. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  83763. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  83764. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  83765. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  83766. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  83767. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  83768. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  83769. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  83770. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  83771. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  83772. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  83773. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  83774. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  83775. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  83776. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  83777. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  83778. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  83779. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  83780. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  83781. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  83782. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  83783. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  83784. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  83785. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  83786. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  83787. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  83788. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  83789. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  83790. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  83791. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  83792. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  83793. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  83794. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  83795. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  83796. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  83797. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  83798. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  83799. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  83800. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  83801. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  83802. + {0x3808, 0x04, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x03, 0, 0},
  83803. + {0x380b, 0x00, 0, 0}, {0x3815, 0x02, 0, 0}, {0x302c, 0x60, 0x60, 0},
  83804. +};
  83805. +
  83806. +static struct reg_value ov5642_setting_30fps_QVGA_320_240[] = {
  83807. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  83808. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  83809. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  83810. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  83811. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  83812. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  83813. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  83814. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  83815. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  83816. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  83817. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  83818. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  83819. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  83820. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  83821. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  83822. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  83823. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  83824. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  83825. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  83826. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  83827. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  83828. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  83829. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  83830. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  83831. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83832. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  83833. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  83834. + {0x3803, 0x08, 0, 0}, {0x3827, 0x08, 0, 0}, {0x3810, 0x80, 0, 0},
  83835. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  83836. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0},
  83837. + {0x5686, 0x03, 0, 0}, {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0},
  83838. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  83839. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  83840. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  83841. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  83842. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  83843. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  83844. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  83845. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  83846. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  83847. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  83848. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  83849. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  83850. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  83851. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  83852. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  83853. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  83854. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  83855. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  83856. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  83857. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  83858. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  83859. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  83860. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  83861. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  83862. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  83863. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  83864. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  83865. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  83866. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  83867. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  83868. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  83869. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  83870. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  83871. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  83872. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  83873. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  83874. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  83875. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  83876. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  83877. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  83878. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  83879. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  83880. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  83881. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  83882. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  83883. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  83884. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  83885. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  83886. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  83887. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  83888. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  83889. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  83890. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  83891. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  83892. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  83893. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  83894. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  83895. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  83896. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  83897. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  83898. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  83899. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  83900. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  83901. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  83902. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  83903. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  83904. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  83905. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  83906. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  83907. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  83908. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  83909. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  83910. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  83911. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  83912. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  83913. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  83914. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  83915. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  83916. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  83917. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  83918. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  83919. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  83920. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  83921. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  83922. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  83923. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  83924. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  83925. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  83926. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  83927. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  83928. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  83929. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  83930. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  83931. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  83932. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  83933. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  83934. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  83935. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  83936. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  83937. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  83938. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  83939. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  83940. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  83941. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  83942. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  83943. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  83944. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  83945. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  83946. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  83947. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  83948. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  83949. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  83950. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  83951. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  83952. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  83953. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  83954. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  83955. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  83956. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  83957. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  83958. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  83959. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  83960. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  83961. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  83962. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  83963. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  83964. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  83965. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  83966. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  83967. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  83968. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  83969. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  83970. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  83971. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  83972. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3808, 0x01, 0, 0},
  83973. + {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0}, {0x380b, 0xf0, 0, 0},
  83974. +};
  83975. +
  83976. +static struct reg_value ov5642_setting_30fps_NTSC_720_480[] = {
  83977. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  83978. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  83979. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  83980. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  83981. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  83982. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  83983. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  83984. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  83985. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  83986. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  83987. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  83988. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  83989. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  83990. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  83991. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  83992. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  83993. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  83994. + {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  83995. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  83996. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  83997. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  83998. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xb0, 0, 0},
  83999. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  84000. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  84001. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  84002. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  84003. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  84004. + {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
  84005. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0},
  84006. + {0x5683, 0x00, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
  84007. + {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
  84008. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  84009. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  84010. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  84011. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  84012. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  84013. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  84014. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  84015. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  84016. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  84017. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  84018. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  84019. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  84020. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  84021. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  84022. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  84023. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  84024. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  84025. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  84026. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  84027. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  84028. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  84029. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  84030. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  84031. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  84032. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  84033. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  84034. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  84035. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  84036. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  84037. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  84038. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  84039. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  84040. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  84041. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  84042. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  84043. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  84044. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  84045. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  84046. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  84047. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  84048. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  84049. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  84050. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  84051. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  84052. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  84053. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  84054. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  84055. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  84056. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  84057. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  84058. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  84059. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  84060. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  84061. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  84062. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  84063. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  84064. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  84065. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  84066. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  84067. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  84068. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  84069. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  84070. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  84071. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  84072. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  84073. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  84074. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  84075. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  84076. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  84077. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  84078. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  84079. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  84080. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  84081. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  84082. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  84083. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  84084. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  84085. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  84086. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  84087. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  84088. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  84089. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  84090. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  84091. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  84092. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  84093. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  84094. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  84095. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  84096. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  84097. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  84098. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  84099. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  84100. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  84101. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  84102. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  84103. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  84104. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  84105. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  84106. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  84107. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  84108. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  84109. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  84110. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  84111. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  84112. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  84113. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  84114. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  84115. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  84116. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  84117. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  84118. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  84119. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  84120. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  84121. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  84122. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  84123. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  84124. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  84125. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  84126. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  84127. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  84128. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  84129. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  84130. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  84131. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  84132. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  84133. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  84134. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  84135. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  84136. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  84137. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  84138. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  84139. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  84140. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  84141. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  84142. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  84143. + {0x302c, 0x60, 0x60, 0},
  84144. +};
  84145. +
  84146. +static struct reg_value ov5642_setting_30fps_PAL_720_576[] = {
  84147. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  84148. + {0x3018, 0xfc, 0, 0}, {0x3615, 0xf0, 0, 0}, {0x3000, 0x00, 0, 0},
  84149. + {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0}, {0x3003, 0x00, 0, 0},
  84150. + {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0}, {0x3006, 0x43, 0, 0},
  84151. + {0x3007, 0x37, 0, 0}, {0x3011, 0x09, 0, 0}, {0x3012, 0x02, 0, 0},
  84152. + {0x3010, 0x00, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3815, 0x04, 0, 0},
  84153. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  84154. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  84155. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  84156. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  84157. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  84158. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  84159. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  84160. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  84161. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  84162. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  84163. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  84164. + {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0}, {0x380b, 0x40, 0, 0},
  84165. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  84166. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  84167. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  84168. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3825, 0xd8, 0, 0},
  84169. + {0x3501, 0x1e, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0},
  84170. + {0x380c, 0x07, 0, 0}, {0x380d, 0x2a, 0, 0}, {0x380e, 0x03, 0, 0},
  84171. + {0x380f, 0xe8, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  84172. + {0x3818, 0xc1, 0, 0}, {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0},
  84173. + {0x3801, 0x80, 0, 0}, {0x3621, 0xc7, 0, 0}, {0x3801, 0x50, 0, 0},
  84174. + {0x3803, 0x08, 0, 0}, {0x3827, 0x3c, 0, 0}, {0x3810, 0x80, 0, 0},
  84175. + {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x5682, 0x04, 0, 0},
  84176. + {0x5683, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0}, {0x3807, 0x58, 0, 0},
  84177. + {0x5686, 0x03, 0, 0}, {0x5687, 0x58, 0, 0}, {0x3a00, 0x78, 0, 0},
  84178. + {0x3a1a, 0x05, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0},
  84179. + {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0},
  84180. + {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0},
  84181. + {0x350d, 0xd0, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  84182. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  84183. + {0x3503, 0x00, 0, 0}, {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0},
  84184. + {0x528c, 0x08, 0, 0}, {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0},
  84185. + {0x528f, 0x10, 0, 0}, {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0},
  84186. + {0x5293, 0x02, 0, 0}, {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0},
  84187. + {0x5296, 0x00, 0, 0}, {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0},
  84188. + {0x5299, 0x02, 0, 0}, {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0},
  84189. + {0x529c, 0x00, 0, 0}, {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0},
  84190. + {0x529f, 0x02, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0},
  84191. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0},
  84192. + {0x3a1f, 0x10, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  84193. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  84194. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  84195. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  84196. + {0x3a0b, 0xa0, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0},
  84197. + {0x5193, 0x70, 0, 0}, {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0},
  84198. + {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0},
  84199. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  84200. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  84201. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  84202. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  84203. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  84204. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  84205. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  84206. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  84207. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  84208. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  84209. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  84210. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  84211. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  84212. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  84213. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  84214. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  84215. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  84216. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  84217. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  84218. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  84219. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  84220. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  84221. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  84222. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  84223. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  84224. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  84225. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  84226. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  84227. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  84228. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  84229. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  84230. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  84231. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  84232. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  84233. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  84234. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  84235. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  84236. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  84237. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  84238. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  84239. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  84240. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  84241. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  84242. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  84243. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  84244. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  84245. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  84246. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  84247. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  84248. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  84249. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  84250. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  84251. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  84252. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  84253. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  84254. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  84255. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  84256. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  84257. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  84258. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  84259. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  84260. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  84261. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  84262. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  84263. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  84264. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  84265. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  84266. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  84267. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  84268. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  84269. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  84270. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  84271. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  84272. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  84273. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  84274. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  84275. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  84276. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  84277. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  84278. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  84279. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  84280. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  84281. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  84282. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  84283. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  84284. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  84285. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  84286. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  84287. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  84288. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  84289. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  84290. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  84291. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  84292. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  84293. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  84294. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  84295. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  84296. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  84297. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  84298. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  84299. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  84300. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  84301. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  84302. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  84303. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  84304. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  84305. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  84306. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  84307. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  84308. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  84309. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  84310. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  84311. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  84312. + {0x302b, 0x00, 0, 0}, {0x3621, 0x87, 0, 0}, {0x3a00, 0x78, 0, 0},
  84313. + {0x302c, 0x60, 0x60, 0},
  84314. +};
  84315. +
  84316. +static struct reg_value ov5642_setting_15fps_720P_1280_720[] = {
  84317. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  84318. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  84319. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  84320. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  84321. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  84322. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  84323. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  84324. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  84325. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  84326. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  84327. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  84328. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  84329. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  84330. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  84331. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  84332. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  84333. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  84334. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  84335. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  84336. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  84337. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  84338. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  84339. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  84340. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  84341. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  84342. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  84343. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  84344. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  84345. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  84346. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  84347. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  84348. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  84349. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  84350. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  84351. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  84352. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  84353. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  84354. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  84355. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  84356. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  84357. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  84358. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  84359. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  84360. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  84361. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  84362. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  84363. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  84364. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  84365. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  84366. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  84367. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  84368. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  84369. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  84370. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  84371. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  84372. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  84373. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  84374. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  84375. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  84376. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  84377. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  84378. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  84379. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  84380. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  84381. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  84382. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  84383. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  84384. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  84385. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  84386. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  84387. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  84388. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  84389. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  84390. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  84391. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  84392. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  84393. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  84394. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  84395. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  84396. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  84397. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  84398. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  84399. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  84400. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  84401. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  84402. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  84403. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  84404. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  84405. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  84406. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  84407. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  84408. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  84409. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  84410. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  84411. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  84412. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  84413. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  84414. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  84415. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  84416. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  84417. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  84418. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  84419. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  84420. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  84421. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  84422. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  84423. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  84424. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  84425. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  84426. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  84427. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  84428. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  84429. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  84430. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  84431. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  84432. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  84433. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  84434. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  84435. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  84436. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  84437. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  84438. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  84439. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  84440. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  84441. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  84442. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  84443. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  84444. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  84445. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  84446. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  84447. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  84448. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  84449. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  84450. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  84451. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  84452. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  84453. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  84454. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  84455. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  84456. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  84457. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  84458. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  84459. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  84460. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  84461. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  84462. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  84463. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  84464. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  84465. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  84466. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  84467. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  84468. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  84469. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  84470. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
  84471. + {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
  84472. + {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
  84473. + {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
  84474. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  84475. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
  84476. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
  84477. + {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
  84478. + {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
  84479. + {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
  84480. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
  84481. + {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
  84482. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
  84483. + {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
  84484. + {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
  84485. + {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
  84486. + {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
  84487. + {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
  84488. + {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0}, {0x3010, 0x30, 0, 0},
  84489. + {0x3a08, 0x06, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x05, 0, 0},
  84490. + {0x3a0b, 0x50, 0, 0}, {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x07, 0, 0},
  84491. +};
  84492. +
  84493. +static struct reg_value ov5642_setting_30fps_720P_1280_720[] = {
  84494. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  84495. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  84496. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  84497. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  84498. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  84499. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  84500. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  84501. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  84502. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  84503. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  84504. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  84505. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  84506. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  84507. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  84508. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  84509. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  84510. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  84511. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  84512. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  84513. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  84514. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  84515. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  84516. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  84517. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  84518. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  84519. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  84520. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  84521. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  84522. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  84523. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  84524. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  84525. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  84526. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  84527. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  84528. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  84529. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  84530. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  84531. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  84532. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  84533. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  84534. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  84535. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  84536. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  84537. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  84538. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  84539. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  84540. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  84541. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  84542. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  84543. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  84544. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  84545. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  84546. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  84547. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  84548. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  84549. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  84550. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  84551. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  84552. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  84553. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  84554. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  84555. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  84556. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  84557. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  84558. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  84559. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  84560. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  84561. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  84562. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  84563. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  84564. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  84565. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  84566. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  84567. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  84568. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  84569. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  84570. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  84571. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  84572. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  84573. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  84574. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  84575. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  84576. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  84577. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  84578. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  84579. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  84580. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  84581. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  84582. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  84583. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  84584. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  84585. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  84586. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  84587. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  84588. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  84589. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  84590. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  84591. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  84592. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  84593. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  84594. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  84595. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  84596. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  84597. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  84598. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  84599. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  84600. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  84601. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  84602. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  84603. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  84604. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  84605. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  84606. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  84607. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  84608. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  84609. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  84610. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  84611. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  84612. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  84613. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  84614. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  84615. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  84616. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  84617. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  84618. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  84619. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  84620. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  84621. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  84622. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  84623. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  84624. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  84625. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  84626. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  84627. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  84628. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  84629. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  84630. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  84631. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  84632. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  84633. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  84634. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  84635. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  84636. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  84637. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  84638. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  84639. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  84640. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  84641. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  84642. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  84643. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  84644. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  84645. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  84646. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  84647. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x08, 0, 0},
  84648. + {0x350c, 0x02, 0, 0}, {0x350d, 0xe4, 0, 0}, {0x3621, 0xc9, 0, 0},
  84649. + {0x370a, 0x81, 0, 0}, {0x3803, 0x08, 0, 0}, {0x3804, 0x05, 0, 0},
  84650. + {0x3805, 0x00, 0, 0}, {0x3806, 0x02, 0, 0}, {0x3807, 0xd0, 0, 0},
  84651. + {0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
  84652. + {0x380b, 0xd0, 0, 0}, {0x380c, 0x08, 0, 0}, {0x380d, 0x72, 0, 0},
  84653. + {0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0xc0, 0, 0},
  84654. + {0x3818, 0xc9, 0, 0}, {0x381c, 0x10, 0, 0}, {0x381d, 0xa0, 0, 0},
  84655. + {0x381e, 0x05, 0, 0}, {0x381f, 0xb0, 0, 0}, {0x3820, 0x00, 0, 0},
  84656. + {0x3821, 0x00, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3a08, 0x1b, 0, 0},
  84657. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x17, 0, 0}, {0x3a0b, 0x20, 0, 0},
  84658. + {0x3a0d, 0x02, 0, 0}, {0x3a0e, 0x01, 0, 0}, {0x401c, 0x04, 0, 0},
  84659. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0}, {0x5686, 0x02, 0, 0},
  84660. + {0x5687, 0xcc, 0, 0}, {0x5001, 0x7f, 0, 0}, {0x589b, 0x06, 0, 0},
  84661. + {0x589a, 0xc5, 0, 0}, {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0},
  84662. + {0x460c, 0x20, 0, 0}, {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0},
  84663. + {0x471d, 0x05, 0, 0}, {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0},
  84664. + {0x501f, 0x00, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0},
  84665. + {0x3819, 0x80, 0, 0}, {0x5002, 0xe0, 0, 0},
  84666. +};
  84667. +
  84668. +static struct reg_value ov5642_setting_15fps_1080P_1920_1080[] = {
  84669. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  84670. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  84671. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x00, 0, 0},
  84672. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3030, 0x2b, 0, 0},
  84673. + {0x3011, 0x08, 0, 0}, {0x3010, 0x10, 0, 0}, {0x3604, 0x60, 0, 0},
  84674. + {0x3622, 0x60, 0, 0}, {0x3621, 0x09, 0, 0}, {0x3709, 0x00, 0, 0},
  84675. + {0x4000, 0x21, 0, 0}, {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0},
  84676. + {0x3605, 0x04, 0, 0}, {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0},
  84677. + {0x300d, 0x22, 0, 0}, {0x3623, 0x22, 0, 0}, {0x5000, 0x4f, 0, 0},
  84678. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  84679. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5500, 0x0a, 0, 0},
  84680. + {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0}, {0x5080, 0x08, 0, 0},
  84681. + {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0}, {0x471d, 0x05, 0, 0},
  84682. + {0x4708, 0x06, 0, 0}, {0x370c, 0xa0, 0, 0}, {0x3808, 0x0a, 0, 0},
  84683. + {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0}, {0x380b, 0x98, 0, 0},
  84684. + {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0}, {0x380e, 0x07, 0, 0},
  84685. + {0x380f, 0xd0, 0, 0}, {0x5687, 0x94, 0, 0}, {0x501f, 0x00, 0, 0},
  84686. + {0x5000, 0x4f, 0, 0}, {0x5001, 0xcf, 0, 0}, {0x4300, 0x30, 0, 0},
  84687. + {0x4300, 0x30, 0, 0}, {0x460b, 0x35, 0, 0}, {0x471d, 0x00, 0, 0},
  84688. + {0x3002, 0x0c, 0, 0}, {0x3002, 0x00, 0, 0}, {0x4713, 0x03, 0, 0},
  84689. + {0x471c, 0x50, 0, 0}, {0x4721, 0x02, 0, 0}, {0x4402, 0x90, 0, 0},
  84690. + {0x460c, 0x22, 0, 0}, {0x3815, 0x44, 0, 0}, {0x3503, 0x07, 0, 0},
  84691. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  84692. + {0x3818, 0xc8, 0, 0}, {0x3801, 0x88, 0, 0}, {0x3824, 0x11, 0, 0},
  84693. + {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x04, 0, 0}, {0x3a13, 0x30, 0, 0},
  84694. + {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0}, {0x3a08, 0x12, 0, 0},
  84695. + {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0}, {0x3a0b, 0xa0, 0, 0},
  84696. + {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0}, {0x3a0d, 0x08, 0, 0},
  84697. + {0x3a0e, 0x06, 0, 0}, {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0},
  84698. + {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0},
  84699. + {0x3503, 0x00, 0, 0}, {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x32, 0, 0},
  84700. + {0x3a1b, 0x3c, 0, 0}, {0x3a1e, 0x32, 0, 0}, {0x3a11, 0x80, 0, 0},
  84701. + {0x3a1f, 0x20, 0, 0}, {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0},
  84702. + {0x3a03, 0x7d, 0, 0}, {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0},
  84703. + {0x3a15, 0x7d, 0, 0}, {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0},
  84704. + {0x3a08, 0x09, 0, 0}, {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0},
  84705. + {0x3a0b, 0xd0, 0, 0}, {0x3a0d, 0x10, 0, 0}, {0x3a0e, 0x0d, 0, 0},
  84706. + {0x4407, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x589b, 0x00, 0, 0},
  84707. + {0x589a, 0xc0, 0, 0}, {0x401e, 0x20, 0, 0}, {0x4001, 0x42, 0, 0},
  84708. + {0x401c, 0x06, 0, 0}, {0x3825, 0xac, 0, 0}, {0x3827, 0x0c, 0, 0},
  84709. + {0x528a, 0x01, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  84710. + {0x528d, 0x10, 0, 0}, {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0},
  84711. + {0x5290, 0x30, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0},
  84712. + {0x5294, 0x00, 0, 0}, {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0},
  84713. + {0x5297, 0x08, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0},
  84714. + {0x529a, 0x00, 0, 0}, {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0},
  84715. + {0x529d, 0x28, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0},
  84716. + {0x5282, 0x00, 0, 0}, {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0},
  84717. + {0x5302, 0x00, 0, 0}, {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0},
  84718. + {0x530d, 0x0c, 0, 0}, {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0},
  84719. + {0x5310, 0x20, 0, 0}, {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0},
  84720. + {0x5309, 0x40, 0, 0}, {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0},
  84721. + {0x5306, 0x00, 0, 0}, {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0},
  84722. + {0x5315, 0x20, 0, 0}, {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0},
  84723. + {0x5317, 0x00, 0, 0}, {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0},
  84724. + {0x5381, 0x00, 0, 0}, {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0},
  84725. + {0x5384, 0x00, 0, 0}, {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0},
  84726. + {0x5387, 0x00, 0, 0}, {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0},
  84727. + {0x538a, 0x00, 0, 0}, {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0},
  84728. + {0x538d, 0x00, 0, 0}, {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0},
  84729. + {0x5390, 0x00, 0, 0}, {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0},
  84730. + {0x5393, 0xa2, 0, 0}, {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0},
  84731. + {0x5481, 0x21, 0, 0}, {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0},
  84732. + {0x5484, 0x65, 0, 0}, {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0},
  84733. + {0x5487, 0x87, 0, 0}, {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0},
  84734. + {0x548a, 0xaa, 0, 0}, {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0},
  84735. + {0x548d, 0xdd, 0, 0}, {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0},
  84736. + {0x5490, 0x05, 0, 0}, {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0},
  84737. + {0x5493, 0x20, 0, 0}, {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0},
  84738. + {0x5496, 0x02, 0, 0}, {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0},
  84739. + {0x5499, 0x86, 0, 0}, {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0},
  84740. + {0x549c, 0x02, 0, 0}, {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0},
  84741. + {0x549f, 0x1c, 0, 0}, {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0},
  84742. + {0x54a2, 0x01, 0, 0}, {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0},
  84743. + {0x54a5, 0xc5, 0, 0}, {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0},
  84744. + {0x54a8, 0x01, 0, 0}, {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0},
  84745. + {0x54ab, 0x41, 0, 0}, {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0},
  84746. + {0x54ae, 0x00, 0, 0}, {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0},
  84747. + {0x54b1, 0x20, 0, 0}, {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0},
  84748. + {0x54b4, 0x00, 0, 0}, {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0},
  84749. + {0x54b7, 0xdf, 0, 0}, {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0},
  84750. + {0x3406, 0x00, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0},
  84751. + {0x5182, 0x11, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
  84752. + {0x5185, 0x24, 0, 0}, {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0},
  84753. + {0x5188, 0x08, 0, 0}, {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0},
  84754. + {0x518b, 0xb2, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0},
  84755. + {0x518e, 0x3d, 0, 0}, {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0},
  84756. + {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
  84757. + {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
  84758. + {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
  84759. + {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
  84760. + {0x519d, 0x82, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0},
  84761. + {0x3a0f, 0x38, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0},
  84762. + {0x3a1e, 0x2e, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0},
  84763. + {0x5688, 0xa6, 0, 0}, {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0},
  84764. + {0x568b, 0xae, 0, 0}, {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0},
  84765. + {0x568e, 0x62, 0, 0}, {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0},
  84766. + {0x5584, 0x40, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0},
  84767. + {0x5800, 0x27, 0, 0}, {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0},
  84768. + {0x5803, 0x0f, 0, 0}, {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0},
  84769. + {0x5806, 0x1e, 0, 0}, {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0},
  84770. + {0x5809, 0x0d, 0, 0}, {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0},
  84771. + {0x580c, 0x0a, 0, 0}, {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0},
  84772. + {0x580f, 0x19, 0, 0}, {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0},
  84773. + {0x5812, 0x04, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0},
  84774. + {0x5815, 0x06, 0, 0}, {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0},
  84775. + {0x5818, 0x0a, 0, 0}, {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0},
  84776. + {0x581b, 0x00, 0, 0}, {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0},
  84777. + {0x581e, 0x08, 0, 0}, {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0},
  84778. + {0x5821, 0x05, 0, 0}, {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0},
  84779. + {0x5824, 0x00, 0, 0}, {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0},
  84780. + {0x5827, 0x0c, 0, 0}, {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0},
  84781. + {0x582a, 0x06, 0, 0}, {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0},
  84782. + {0x582d, 0x07, 0, 0}, {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0},
  84783. + {0x5830, 0x18, 0, 0}, {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0},
  84784. + {0x5833, 0x0a, 0, 0}, {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0},
  84785. + {0x5836, 0x15, 0, 0}, {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0},
  84786. + {0x5839, 0x1f, 0, 0}, {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0},
  84787. + {0x583c, 0x17, 0, 0}, {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0},
  84788. + {0x583f, 0x53, 0, 0}, {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0},
  84789. + {0x5842, 0x0d, 0, 0}, {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0},
  84790. + {0x5845, 0x09, 0, 0}, {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0},
  84791. + {0x5848, 0x10, 0, 0}, {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0},
  84792. + {0x584b, 0x0e, 0, 0}, {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0},
  84793. + {0x584e, 0x11, 0, 0}, {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0},
  84794. + {0x5851, 0x0c, 0, 0}, {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0},
  84795. + {0x5854, 0x10, 0, 0}, {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0},
  84796. + {0x5857, 0x0b, 0, 0}, {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0},
  84797. + {0x585a, 0x0d, 0, 0}, {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0},
  84798. + {0x585d, 0x0c, 0, 0}, {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0},
  84799. + {0x5860, 0x0c, 0, 0}, {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0},
  84800. + {0x5863, 0x08, 0, 0}, {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0},
  84801. + {0x5866, 0x18, 0, 0}, {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0},
  84802. + {0x5869, 0x19, 0, 0}, {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0},
  84803. + {0x586c, 0x13, 0, 0}, {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0},
  84804. + {0x586f, 0x16, 0, 0}, {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0},
  84805. + {0x5872, 0x10, 0, 0}, {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0},
  84806. + {0x5875, 0x16, 0, 0}, {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0},
  84807. + {0x5878, 0x10, 0, 0}, {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0},
  84808. + {0x587b, 0x14, 0, 0}, {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0},
  84809. + {0x587e, 0x11, 0, 0}, {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0},
  84810. + {0x5881, 0x15, 0, 0}, {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0},
  84811. + {0x5884, 0x15, 0, 0}, {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0},
  84812. + {0x5887, 0x17, 0, 0}, {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0},
  84813. + {0x3702, 0x10, 0, 0}, {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0},
  84814. + {0x370b, 0x40, 0, 0}, {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0},
  84815. + {0x3632, 0x52, 0, 0}, {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0},
  84816. + {0x5785, 0x07, 0, 0}, {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0},
  84817. + {0x3604, 0x48, 0, 0}, {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0},
  84818. + {0x370f, 0xc0, 0, 0}, {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0},
  84819. + {0x5007, 0x00, 0, 0}, {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0},
  84820. + {0x5013, 0x00, 0, 0}, {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0},
  84821. + {0x5087, 0x00, 0, 0}, {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0},
  84822. + {0x302b, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3011, 0x07, 0, 0},
  84823. + {0x350c, 0x04, 0, 0}, {0x350d, 0x58, 0, 0}, {0x3801, 0x8a, 0, 0},
  84824. + {0x3803, 0x0a, 0, 0}, {0x3804, 0x07, 0, 0}, {0x3805, 0x80, 0, 0},
  84825. + {0x3806, 0x04, 0, 0}, {0x3807, 0x39, 0, 0}, {0x3808, 0x07, 0, 0},
  84826. + {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0}, {0x380b, 0x38, 0, 0},
  84827. + {0x380c, 0x09, 0, 0}, {0x380d, 0xd6, 0, 0}, {0x380e, 0x04, 0, 0},
  84828. + {0x380f, 0x58, 0, 0}, {0x381c, 0x11, 0, 0}, {0x381d, 0xba, 0, 0},
  84829. + {0x381e, 0x04, 0, 0}, {0x381f, 0x48, 0, 0}, {0x3820, 0x04, 0, 0},
  84830. + {0x3821, 0x18, 0, 0}, {0x3a08, 0x14, 0, 0}, {0x3a09, 0xe0, 0, 0},
  84831. + {0x3a0a, 0x11, 0, 0}, {0x3a0b, 0x60, 0, 0}, {0x3a0d, 0x04, 0, 0},
  84832. + {0x3a0e, 0x03, 0, 0}, {0x5682, 0x07, 0, 0}, {0x5683, 0x60, 0, 0},
  84833. + {0x5686, 0x04, 0, 0}, {0x5687, 0x1c, 0, 0}, {0x5001, 0x7f, 0, 0},
  84834. + {0x3503, 0x00, 0, 0}, {0x3010, 0x10, 0, 0}, {0x460c, 0x20, 0, 0},
  84835. + {0x460b, 0x37, 0, 0}, {0x471c, 0xd0, 0, 0}, {0x471d, 0x05, 0, 0},
  84836. + {0x3815, 0x01, 0, 0}, {0x3818, 0x00, 0x08, 0}, {0x501f, 0x00, 0, 0},
  84837. + {0x4300, 0x30, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3819, 0x80, 0, 0},
  84838. + {0x5002, 0xe0, 0, 0},
  84839. +};
  84840. +
  84841. +static struct reg_value ov5642_setting_15fps_QVGA_320_240[] = {
  84842. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  84843. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  84844. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  84845. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  84846. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  84847. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  84848. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  84849. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  84850. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  84851. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  84852. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  84853. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  84854. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  84855. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  84856. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  84857. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  84858. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  84859. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  84860. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  84861. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  84862. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  84863. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  84864. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  84865. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  84866. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  84867. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  84868. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  84869. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  84870. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  84871. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  84872. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  84873. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  84874. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  84875. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  84876. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  84877. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  84878. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  84879. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  84880. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  84881. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  84882. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  84883. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  84884. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  84885. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  84886. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  84887. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  84888. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  84889. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  84890. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  84891. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  84892. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  84893. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  84894. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  84895. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  84896. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  84897. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  84898. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  84899. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  84900. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  84901. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  84902. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  84903. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  84904. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  84905. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  84906. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  84907. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  84908. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  84909. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  84910. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  84911. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  84912. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  84913. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  84914. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  84915. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  84916. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  84917. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  84918. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  84919. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  84920. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  84921. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  84922. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  84923. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  84924. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  84925. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  84926. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  84927. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  84928. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  84929. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  84930. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  84931. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  84932. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  84933. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  84934. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  84935. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  84936. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  84937. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  84938. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  84939. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  84940. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  84941. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  84942. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  84943. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  84944. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  84945. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  84946. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  84947. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  84948. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  84949. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  84950. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  84951. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  84952. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  84953. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  84954. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  84955. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  84956. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  84957. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  84958. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  84959. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  84960. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  84961. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  84962. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  84963. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  84964. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  84965. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  84966. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  84967. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  84968. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  84969. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  84970. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  84971. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  84972. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  84973. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  84974. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  84975. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  84976. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  84977. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  84978. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  84979. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  84980. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  84981. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  84982. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  84983. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  84984. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  84985. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  84986. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  84987. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  84988. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  84989. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  84990. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  84991. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  84992. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  84993. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  84994. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  84995. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  84996. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  84997. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  84998. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  84999. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  85000. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  85001. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  85002. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  85003. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  85004. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  85005. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  85006. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  85007. + {0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
  85008. + {0x380b, 0xf0, 0, 0}, {0x3a00, 0x78, 0, 0},
  85009. +};
  85010. +
  85011. +static struct reg_value ov5642_setting_15fps_NTSC_720_480[] = {
  85012. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  85013. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  85014. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  85015. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  85016. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  85017. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  85018. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  85019. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  85020. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  85021. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  85022. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  85023. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  85024. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  85025. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  85026. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  85027. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  85028. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  85029. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  85030. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  85031. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  85032. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  85033. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  85034. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  85035. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  85036. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  85037. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  85038. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  85039. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  85040. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  85041. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  85042. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  85043. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  85044. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  85045. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  85046. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  85047. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  85048. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  85049. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  85050. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  85051. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  85052. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  85053. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  85054. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  85055. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  85056. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  85057. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  85058. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  85059. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  85060. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  85061. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  85062. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  85063. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  85064. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  85065. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  85066. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  85067. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  85068. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  85069. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  85070. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  85071. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  85072. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  85073. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  85074. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  85075. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  85076. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  85077. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  85078. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  85079. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  85080. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  85081. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  85082. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  85083. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  85084. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  85085. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  85086. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  85087. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  85088. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  85089. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  85090. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  85091. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  85092. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  85093. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  85094. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  85095. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  85096. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  85097. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  85098. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  85099. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  85100. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  85101. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  85102. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  85103. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  85104. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  85105. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  85106. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  85107. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  85108. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  85109. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  85110. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  85111. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  85112. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  85113. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  85114. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  85115. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  85116. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  85117. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  85118. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  85119. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  85120. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  85121. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  85122. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  85123. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  85124. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  85125. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  85126. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  85127. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  85128. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  85129. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  85130. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  85131. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  85132. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  85133. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  85134. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  85135. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  85136. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  85137. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  85138. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  85139. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  85140. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  85141. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  85142. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  85143. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  85144. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  85145. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  85146. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  85147. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  85148. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  85149. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  85150. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  85151. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  85152. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  85153. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  85154. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  85155. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  85156. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  85157. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  85158. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  85159. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  85160. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  85161. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  85162. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  85163. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  85164. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  85165. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  85166. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  85167. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  85168. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  85169. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  85170. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  85171. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  85172. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  85173. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  85174. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  85175. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  85176. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  85177. + {0x3824, 0x11, 0, 0}, {0x3825, 0xb4, 0, 0}, {0x3826, 0x00, 0, 0},
  85178. + {0x3827, 0x3d, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
  85179. + {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
  85180. + {0x3809, 0xd0, 0, 0}, {0x380A, 0x01, 0, 0}, {0x380B, 0xe0, 0, 0},
  85181. + {0x3804, 0x05, 0, 0}, {0x3805, 0x00, 0, 0}, {0x3806, 0x03, 0, 0},
  85182. + {0x3807, 0x55, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0x55, 0, 0},
  85183. + {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  85184. +};
  85185. +
  85186. +static struct reg_value ov5642_setting_15fps_PAL_720_576[] = {
  85187. + {0x3103, 0x93, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3017, 0x7f, 0, 0},
  85188. + {0x3018, 0xfc, 0, 0}, {0x3810, 0xc2, 0, 0}, {0x3615, 0xf0, 0, 0},
  85189. + {0x3000, 0x00, 0, 0}, {0x3001, 0x00, 0, 0}, {0x3002, 0x5c, 0, 0},
  85190. + {0x3003, 0x00, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3005, 0xff, 0, 0},
  85191. + {0x3006, 0x43, 0, 0}, {0x3007, 0x37, 0, 0}, {0x3011, 0x08, 0, 0},
  85192. + {0x3010, 0x10, 0, 0}, {0x460c, 0x22, 0, 0}, {0x3815, 0x04, 0, 0},
  85193. + {0x370c, 0xa0, 0, 0}, {0x3602, 0xfc, 0, 0}, {0x3612, 0xff, 0, 0},
  85194. + {0x3634, 0xc0, 0, 0}, {0x3613, 0x00, 0, 0}, {0x3605, 0x7c, 0, 0},
  85195. + {0x3621, 0x09, 0, 0}, {0x3622, 0x60, 0, 0}, {0x3604, 0x40, 0, 0},
  85196. + {0x3603, 0xa7, 0, 0}, {0x3603, 0x27, 0, 0}, {0x4000, 0x21, 0, 0},
  85197. + {0x401d, 0x22, 0, 0}, {0x3600, 0x54, 0, 0}, {0x3605, 0x04, 0, 0},
  85198. + {0x3606, 0x3f, 0, 0}, {0x3c01, 0x80, 0, 0}, {0x5000, 0x4f, 0, 0},
  85199. + {0x5020, 0x04, 0, 0}, {0x5181, 0x79, 0, 0}, {0x5182, 0x00, 0, 0},
  85200. + {0x5185, 0x22, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5001, 0xff, 0, 0},
  85201. + {0x5500, 0x0a, 0, 0}, {0x5504, 0x00, 0, 0}, {0x5505, 0x7f, 0, 0},
  85202. + {0x5080, 0x08, 0, 0}, {0x300e, 0x18, 0, 0}, {0x4610, 0x00, 0, 0},
  85203. + {0x471d, 0x05, 0, 0}, {0x4708, 0x06, 0, 0}, {0x3808, 0x02, 0, 0},
  85204. + {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0},
  85205. + {0x380e, 0x07, 0, 0}, {0x380f, 0xd0, 0, 0}, {0x501f, 0x00, 0, 0},
  85206. + {0x5000, 0x4f, 0, 0}, {0x4300, 0x30, 0, 0}, {0x3503, 0x07, 0, 0},
  85207. + {0x3501, 0x73, 0, 0}, {0x3502, 0x80, 0, 0}, {0x350b, 0x00, 0, 0},
  85208. + {0x3503, 0x07, 0, 0}, {0x3824, 0x11, 0, 0}, {0x3501, 0x1e, 0, 0},
  85209. + {0x3502, 0x80, 0, 0}, {0x350b, 0x7f, 0, 0}, {0x380c, 0x0c, 0, 0},
  85210. + {0x380d, 0x80, 0, 0}, {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0},
  85211. + {0x3a0d, 0x04, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3818, 0xc1, 0, 0},
  85212. + {0x3705, 0xdb, 0, 0}, {0x370a, 0x81, 0, 0}, {0x3801, 0x80, 0, 0},
  85213. + {0x3621, 0x87, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3803, 0x08, 0, 0},
  85214. + {0x3827, 0x08, 0, 0}, {0x3810, 0x40, 0, 0}, {0x3804, 0x05, 0, 0},
  85215. + {0x3805, 0x00, 0, 0}, {0x5682, 0x05, 0, 0}, {0x5683, 0x00, 0, 0},
  85216. + {0x3806, 0x03, 0, 0}, {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0},
  85217. + {0x5687, 0xbc, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a1a, 0x05, 0, 0},
  85218. + {0x3a13, 0x30, 0, 0}, {0x3a18, 0x00, 0, 0}, {0x3a19, 0x7c, 0, 0},
  85219. + {0x3a08, 0x12, 0, 0}, {0x3a09, 0xc0, 0, 0}, {0x3a0a, 0x0f, 0, 0},
  85220. + {0x3a0b, 0xa0, 0, 0}, {0x350c, 0x07, 0, 0}, {0x350d, 0xd0, 0, 0},
  85221. + {0x3500, 0x00, 0, 0}, {0x3501, 0x00, 0, 0}, {0x3502, 0x00, 0, 0},
  85222. + {0x350a, 0x00, 0, 0}, {0x350b, 0x00, 0, 0}, {0x3503, 0x00, 0, 0},
  85223. + {0x528a, 0x02, 0, 0}, {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0},
  85224. + {0x528d, 0x08, 0, 0}, {0x528e, 0x08, 0, 0}, {0x528f, 0x10, 0, 0},
  85225. + {0x5290, 0x10, 0, 0}, {0x5292, 0x00, 0, 0}, {0x5293, 0x02, 0, 0},
  85226. + {0x5294, 0x00, 0, 0}, {0x5295, 0x02, 0, 0}, {0x5296, 0x00, 0, 0},
  85227. + {0x5297, 0x02, 0, 0}, {0x5298, 0x00, 0, 0}, {0x5299, 0x02, 0, 0},
  85228. + {0x529a, 0x00, 0, 0}, {0x529b, 0x02, 0, 0}, {0x529c, 0x00, 0, 0},
  85229. + {0x529d, 0x02, 0, 0}, {0x529e, 0x00, 0, 0}, {0x529f, 0x02, 0, 0},
  85230. + {0x3a0f, 0x3c, 0, 0}, {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3c, 0, 0},
  85231. + {0x3a1e, 0x30, 0, 0}, {0x3a11, 0x70, 0, 0}, {0x3a1f, 0x10, 0, 0},
  85232. + {0x3030, 0x2b, 0, 0}, {0x3a02, 0x00, 0, 0}, {0x3a03, 0x7d, 0, 0},
  85233. + {0x3a04, 0x00, 0, 0}, {0x3a14, 0x00, 0, 0}, {0x3a15, 0x7d, 0, 0},
  85234. + {0x3a16, 0x00, 0, 0}, {0x3a00, 0x78, 0, 0}, {0x3a08, 0x09, 0, 0},
  85235. + {0x3a09, 0x60, 0, 0}, {0x3a0a, 0x07, 0, 0}, {0x3a0b, 0xd0, 0, 0},
  85236. + {0x3a0d, 0x08, 0, 0}, {0x3a0e, 0x06, 0, 0}, {0x5193, 0x70, 0, 0},
  85237. + {0x589b, 0x04, 0, 0}, {0x589a, 0xc5, 0, 0}, {0x401e, 0x20, 0, 0},
  85238. + {0x4001, 0x42, 0, 0}, {0x401c, 0x04, 0, 0}, {0x528a, 0x01, 0, 0},
  85239. + {0x528b, 0x04, 0, 0}, {0x528c, 0x08, 0, 0}, {0x528d, 0x10, 0, 0},
  85240. + {0x528e, 0x20, 0, 0}, {0x528f, 0x28, 0, 0}, {0x5290, 0x30, 0, 0},
  85241. + {0x5292, 0x00, 0, 0}, {0x5293, 0x01, 0, 0}, {0x5294, 0x00, 0, 0},
  85242. + {0x5295, 0x04, 0, 0}, {0x5296, 0x00, 0, 0}, {0x5297, 0x08, 0, 0},
  85243. + {0x5298, 0x00, 0, 0}, {0x5299, 0x10, 0, 0}, {0x529a, 0x00, 0, 0},
  85244. + {0x529b, 0x20, 0, 0}, {0x529c, 0x00, 0, 0}, {0x529d, 0x28, 0, 0},
  85245. + {0x529e, 0x00, 0, 0}, {0x529f, 0x30, 0, 0}, {0x5282, 0x00, 0, 0},
  85246. + {0x5300, 0x00, 0, 0}, {0x5301, 0x20, 0, 0}, {0x5302, 0x00, 0, 0},
  85247. + {0x5303, 0x7c, 0, 0}, {0x530c, 0x00, 0, 0}, {0x530d, 0x0c, 0, 0},
  85248. + {0x530e, 0x20, 0, 0}, {0x530f, 0x80, 0, 0}, {0x5310, 0x20, 0, 0},
  85249. + {0x5311, 0x80, 0, 0}, {0x5308, 0x20, 0, 0}, {0x5309, 0x40, 0, 0},
  85250. + {0x5304, 0x00, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x00, 0, 0},
  85251. + {0x5307, 0x80, 0, 0}, {0x5314, 0x08, 0, 0}, {0x5315, 0x20, 0, 0},
  85252. + {0x5319, 0x30, 0, 0}, {0x5316, 0x10, 0, 0}, {0x5317, 0x00, 0, 0},
  85253. + {0x5318, 0x02, 0, 0}, {0x5380, 0x01, 0, 0}, {0x5381, 0x00, 0, 0},
  85254. + {0x5382, 0x00, 0, 0}, {0x5383, 0x4e, 0, 0}, {0x5384, 0x00, 0, 0},
  85255. + {0x5385, 0x0f, 0, 0}, {0x5386, 0x00, 0, 0}, {0x5387, 0x00, 0, 0},
  85256. + {0x5388, 0x01, 0, 0}, {0x5389, 0x15, 0, 0}, {0x538a, 0x00, 0, 0},
  85257. + {0x538b, 0x31, 0, 0}, {0x538c, 0x00, 0, 0}, {0x538d, 0x00, 0, 0},
  85258. + {0x538e, 0x00, 0, 0}, {0x538f, 0x0f, 0, 0}, {0x5390, 0x00, 0, 0},
  85259. + {0x5391, 0xab, 0, 0}, {0x5392, 0x00, 0, 0}, {0x5393, 0xa2, 0, 0},
  85260. + {0x5394, 0x08, 0, 0}, {0x5480, 0x14, 0, 0}, {0x5481, 0x21, 0, 0},
  85261. + {0x5482, 0x36, 0, 0}, {0x5483, 0x57, 0, 0}, {0x5484, 0x65, 0, 0},
  85262. + {0x5485, 0x71, 0, 0}, {0x5486, 0x7d, 0, 0}, {0x5487, 0x87, 0, 0},
  85263. + {0x5488, 0x91, 0, 0}, {0x5489, 0x9a, 0, 0}, {0x548a, 0xaa, 0, 0},
  85264. + {0x548b, 0xb8, 0, 0}, {0x548c, 0xcd, 0, 0}, {0x548d, 0xdd, 0, 0},
  85265. + {0x548e, 0xea, 0, 0}, {0x548f, 0x1d, 0, 0}, {0x5490, 0x05, 0, 0},
  85266. + {0x5491, 0x00, 0, 0}, {0x5492, 0x04, 0, 0}, {0x5493, 0x20, 0, 0},
  85267. + {0x5494, 0x03, 0, 0}, {0x5495, 0x60, 0, 0}, {0x5496, 0x02, 0, 0},
  85268. + {0x5497, 0xb8, 0, 0}, {0x5498, 0x02, 0, 0}, {0x5499, 0x86, 0, 0},
  85269. + {0x549a, 0x02, 0, 0}, {0x549b, 0x5b, 0, 0}, {0x549c, 0x02, 0, 0},
  85270. + {0x549d, 0x3b, 0, 0}, {0x549e, 0x02, 0, 0}, {0x549f, 0x1c, 0, 0},
  85271. + {0x54a0, 0x02, 0, 0}, {0x54a1, 0x04, 0, 0}, {0x54a2, 0x01, 0, 0},
  85272. + {0x54a3, 0xed, 0, 0}, {0x54a4, 0x01, 0, 0}, {0x54a5, 0xc5, 0, 0},
  85273. + {0x54a6, 0x01, 0, 0}, {0x54a7, 0xa5, 0, 0}, {0x54a8, 0x01, 0, 0},
  85274. + {0x54a9, 0x6c, 0, 0}, {0x54aa, 0x01, 0, 0}, {0x54ab, 0x41, 0, 0},
  85275. + {0x54ac, 0x01, 0, 0}, {0x54ad, 0x20, 0, 0}, {0x54ae, 0x00, 0, 0},
  85276. + {0x54af, 0x16, 0, 0}, {0x54b0, 0x01, 0, 0}, {0x54b1, 0x20, 0, 0},
  85277. + {0x54b2, 0x00, 0, 0}, {0x54b3, 0x10, 0, 0}, {0x54b4, 0x00, 0, 0},
  85278. + {0x54b5, 0xf0, 0, 0}, {0x54b6, 0x00, 0, 0}, {0x54b7, 0xdf, 0, 0},
  85279. + {0x5402, 0x3f, 0, 0}, {0x5403, 0x00, 0, 0}, {0x3406, 0x00, 0, 0},
  85280. + {0x5180, 0xff, 0, 0}, {0x5181, 0x52, 0, 0}, {0x5182, 0x11, 0, 0},
  85281. + {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
  85282. + {0x5186, 0x06, 0, 0}, {0x5187, 0x08, 0, 0}, {0x5188, 0x08, 0, 0},
  85283. + {0x5189, 0x7c, 0, 0}, {0x518a, 0x60, 0, 0}, {0x518b, 0xb2, 0, 0},
  85284. + {0x518c, 0xb2, 0, 0}, {0x518d, 0x44, 0, 0}, {0x518e, 0x3d, 0, 0},
  85285. + {0x518f, 0x58, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
  85286. + {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
  85287. + {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
  85288. + {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
  85289. + {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
  85290. + {0x519e, 0x00, 0, 0}, {0x5025, 0x80, 0, 0}, {0x3a0f, 0x38, 0, 0},
  85291. + {0x3a10, 0x30, 0, 0}, {0x3a1b, 0x3a, 0, 0}, {0x3a1e, 0x2e, 0, 0},
  85292. + {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x10, 0, 0}, {0x5688, 0xa6, 0, 0},
  85293. + {0x5689, 0x6a, 0, 0}, {0x568a, 0xea, 0, 0}, {0x568b, 0xae, 0, 0},
  85294. + {0x568c, 0xa6, 0, 0}, {0x568d, 0x6a, 0, 0}, {0x568e, 0x62, 0, 0},
  85295. + {0x568f, 0x26, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x40, 0, 0},
  85296. + {0x5580, 0x02, 0, 0}, {0x5000, 0xcf, 0, 0}, {0x5800, 0x27, 0, 0},
  85297. + {0x5801, 0x19, 0, 0}, {0x5802, 0x12, 0, 0}, {0x5803, 0x0f, 0, 0},
  85298. + {0x5804, 0x10, 0, 0}, {0x5805, 0x15, 0, 0}, {0x5806, 0x1e, 0, 0},
  85299. + {0x5807, 0x2f, 0, 0}, {0x5808, 0x15, 0, 0}, {0x5809, 0x0d, 0, 0},
  85300. + {0x580a, 0x0a, 0, 0}, {0x580b, 0x09, 0, 0}, {0x580c, 0x0a, 0, 0},
  85301. + {0x580d, 0x0c, 0, 0}, {0x580e, 0x12, 0, 0}, {0x580f, 0x19, 0, 0},
  85302. + {0x5810, 0x0b, 0, 0}, {0x5811, 0x07, 0, 0}, {0x5812, 0x04, 0, 0},
  85303. + {0x5813, 0x03, 0, 0}, {0x5814, 0x03, 0, 0}, {0x5815, 0x06, 0, 0},
  85304. + {0x5816, 0x0a, 0, 0}, {0x5817, 0x0f, 0, 0}, {0x5818, 0x0a, 0, 0},
  85305. + {0x5819, 0x05, 0, 0}, {0x581a, 0x01, 0, 0}, {0x581b, 0x00, 0, 0},
  85306. + {0x581c, 0x00, 0, 0}, {0x581d, 0x03, 0, 0}, {0x581e, 0x08, 0, 0},
  85307. + {0x581f, 0x0c, 0, 0}, {0x5820, 0x0a, 0, 0}, {0x5821, 0x05, 0, 0},
  85308. + {0x5822, 0x01, 0, 0}, {0x5823, 0x00, 0, 0}, {0x5824, 0x00, 0, 0},
  85309. + {0x5825, 0x03, 0, 0}, {0x5826, 0x08, 0, 0}, {0x5827, 0x0c, 0, 0},
  85310. + {0x5828, 0x0e, 0, 0}, {0x5829, 0x08, 0, 0}, {0x582a, 0x06, 0, 0},
  85311. + {0x582b, 0x04, 0, 0}, {0x582c, 0x05, 0, 0}, {0x582d, 0x07, 0, 0},
  85312. + {0x582e, 0x0b, 0, 0}, {0x582f, 0x12, 0, 0}, {0x5830, 0x18, 0, 0},
  85313. + {0x5831, 0x10, 0, 0}, {0x5832, 0x0c, 0, 0}, {0x5833, 0x0a, 0, 0},
  85314. + {0x5834, 0x0b, 0, 0}, {0x5835, 0x0e, 0, 0}, {0x5836, 0x15, 0, 0},
  85315. + {0x5837, 0x19, 0, 0}, {0x5838, 0x32, 0, 0}, {0x5839, 0x1f, 0, 0},
  85316. + {0x583a, 0x18, 0, 0}, {0x583b, 0x16, 0, 0}, {0x583c, 0x17, 0, 0},
  85317. + {0x583d, 0x1e, 0, 0}, {0x583e, 0x26, 0, 0}, {0x583f, 0x53, 0, 0},
  85318. + {0x5840, 0x10, 0, 0}, {0x5841, 0x0f, 0, 0}, {0x5842, 0x0d, 0, 0},
  85319. + {0x5843, 0x0c, 0, 0}, {0x5844, 0x0e, 0, 0}, {0x5845, 0x09, 0, 0},
  85320. + {0x5846, 0x11, 0, 0}, {0x5847, 0x10, 0, 0}, {0x5848, 0x10, 0, 0},
  85321. + {0x5849, 0x10, 0, 0}, {0x584a, 0x10, 0, 0}, {0x584b, 0x0e, 0, 0},
  85322. + {0x584c, 0x10, 0, 0}, {0x584d, 0x10, 0, 0}, {0x584e, 0x11, 0, 0},
  85323. + {0x584f, 0x10, 0, 0}, {0x5850, 0x0f, 0, 0}, {0x5851, 0x0c, 0, 0},
  85324. + {0x5852, 0x0f, 0, 0}, {0x5853, 0x10, 0, 0}, {0x5854, 0x10, 0, 0},
  85325. + {0x5855, 0x0f, 0, 0}, {0x5856, 0x0e, 0, 0}, {0x5857, 0x0b, 0, 0},
  85326. + {0x5858, 0x10, 0, 0}, {0x5859, 0x0d, 0, 0}, {0x585a, 0x0d, 0, 0},
  85327. + {0x585b, 0x0c, 0, 0}, {0x585c, 0x0c, 0, 0}, {0x585d, 0x0c, 0, 0},
  85328. + {0x585e, 0x0b, 0, 0}, {0x585f, 0x0c, 0, 0}, {0x5860, 0x0c, 0, 0},
  85329. + {0x5861, 0x0c, 0, 0}, {0x5862, 0x0d, 0, 0}, {0x5863, 0x08, 0, 0},
  85330. + {0x5864, 0x11, 0, 0}, {0x5865, 0x18, 0, 0}, {0x5866, 0x18, 0, 0},
  85331. + {0x5867, 0x19, 0, 0}, {0x5868, 0x17, 0, 0}, {0x5869, 0x19, 0, 0},
  85332. + {0x586a, 0x16, 0, 0}, {0x586b, 0x13, 0, 0}, {0x586c, 0x13, 0, 0},
  85333. + {0x586d, 0x12, 0, 0}, {0x586e, 0x13, 0, 0}, {0x586f, 0x16, 0, 0},
  85334. + {0x5870, 0x14, 0, 0}, {0x5871, 0x12, 0, 0}, {0x5872, 0x10, 0, 0},
  85335. + {0x5873, 0x11, 0, 0}, {0x5874, 0x11, 0, 0}, {0x5875, 0x16, 0, 0},
  85336. + {0x5876, 0x14, 0, 0}, {0x5877, 0x11, 0, 0}, {0x5878, 0x10, 0, 0},
  85337. + {0x5879, 0x0f, 0, 0}, {0x587a, 0x10, 0, 0}, {0x587b, 0x14, 0, 0},
  85338. + {0x587c, 0x13, 0, 0}, {0x587d, 0x12, 0, 0}, {0x587e, 0x11, 0, 0},
  85339. + {0x587f, 0x11, 0, 0}, {0x5880, 0x12, 0, 0}, {0x5881, 0x15, 0, 0},
  85340. + {0x5882, 0x14, 0, 0}, {0x5883, 0x15, 0, 0}, {0x5884, 0x15, 0, 0},
  85341. + {0x5885, 0x15, 0, 0}, {0x5886, 0x13, 0, 0}, {0x5887, 0x17, 0, 0},
  85342. + {0x3710, 0x10, 0, 0}, {0x3632, 0x51, 0, 0}, {0x3702, 0x10, 0, 0},
  85343. + {0x3703, 0xb2, 0, 0}, {0x3704, 0x18, 0, 0}, {0x370b, 0x40, 0, 0},
  85344. + {0x370d, 0x03, 0, 0}, {0x3631, 0x01, 0, 0}, {0x3632, 0x52, 0, 0},
  85345. + {0x3606, 0x24, 0, 0}, {0x3620, 0x96, 0, 0}, {0x5785, 0x07, 0, 0},
  85346. + {0x3a13, 0x30, 0, 0}, {0x3600, 0x52, 0, 0}, {0x3604, 0x48, 0, 0},
  85347. + {0x3606, 0x1b, 0, 0}, {0x370d, 0x0b, 0, 0}, {0x370f, 0xc0, 0, 0},
  85348. + {0x3709, 0x01, 0, 0}, {0x3823, 0x00, 0, 0}, {0x5007, 0x00, 0, 0},
  85349. + {0x5009, 0x00, 0, 0}, {0x5011, 0x00, 0, 0}, {0x5013, 0x00, 0, 0},
  85350. + {0x519e, 0x00, 0, 0}, {0x5086, 0x00, 0, 0}, {0x5087, 0x00, 0, 0},
  85351. + {0x5088, 0x00, 0, 0}, {0x5089, 0x00, 0, 0}, {0x302b, 0x00, 0, 0},
  85352. + {0x3824, 0x11, 0, 0}, {0x3825, 0xdc, 0, 0}, {0x3826, 0x00, 0, 0},
  85353. + {0x3827, 0x08, 0, 0}, {0x380c, 0x0c, 0, 0}, {0x380d, 0x80, 0, 0},
  85354. + {0x380e, 0x03, 0, 0}, {0x380f, 0xe8, 0, 0}, {0x3808, 0x02, 0, 0},
  85355. + {0x3809, 0xd0, 0, 0}, {0x380A, 0x02, 0, 0}, {0x380B, 0x40, 0, 0},
  85356. + {0x3804, 0x04, 0, 0}, {0x3805, 0xb0, 0, 0}, {0x3806, 0x03, 0, 0},
  85357. + {0x3807, 0xc0, 0, 0}, {0x5686, 0x03, 0, 0}, {0x5687, 0xc0, 0, 0},
  85358. + {0x5682, 0x04, 0, 0}, {0x5683, 0xb0, 0, 0},
  85359. +};
  85360. +
  85361. +static struct ov5642_mode_info ov5642_mode_info_data[2][ov5642_mode_MAX + 1] = {
  85362. + {
  85363. + {ov5642_mode_VGA_640_480, 640, 480,
  85364. + ov5642_setting_15fps_VGA_640_480,
  85365. + ARRAY_SIZE(ov5642_setting_15fps_VGA_640_480)},
  85366. + {ov5642_mode_QVGA_320_240, 320, 240,
  85367. + ov5642_setting_15fps_QVGA_320_240,
  85368. + ARRAY_SIZE(ov5642_setting_15fps_QVGA_320_240)},
  85369. + {ov5642_mode_NTSC_720_480, 720, 480,
  85370. + ov5642_setting_15fps_NTSC_720_480,
  85371. + ARRAY_SIZE(ov5642_setting_15fps_NTSC_720_480)},
  85372. + {ov5642_mode_PAL_720_576, 720, 576,
  85373. + ov5642_setting_15fps_PAL_720_576,
  85374. + ARRAY_SIZE(ov5642_setting_15fps_PAL_720_576)},
  85375. + {ov5642_mode_720P_1280_720, 1280, 720,
  85376. + ov5642_setting_15fps_720P_1280_720,
  85377. + ARRAY_SIZE(ov5642_setting_15fps_720P_1280_720)},
  85378. + {ov5642_mode_1080P_1920_1080, 1920, 1080,
  85379. + ov5642_setting_15fps_1080P_1920_1080,
  85380. + ARRAY_SIZE(ov5642_setting_15fps_1080P_1920_1080)},
  85381. + {ov5642_mode_QSXGA_2592_1944, 2592, 1944,
  85382. + ov5642_setting_15fps_QSXGA_2592_1944,
  85383. + ARRAY_SIZE(ov5642_setting_15fps_QSXGA_2592_1944)},
  85384. + {ov5642_mode_QCIF_176_144, 176, 144,
  85385. + ov5642_setting_15fps_QCIF_176_144,
  85386. + ARRAY_SIZE(ov5642_setting_15fps_QCIF_176_144)},
  85387. + {ov5642_mode_XGA_1024_768, 1024, 768,
  85388. + ov5642_setting_15fps_XGA_1024_768,
  85389. + ARRAY_SIZE(ov5642_setting_15fps_XGA_1024_768)},
  85390. + },
  85391. + {
  85392. + {ov5642_mode_VGA_640_480, 640, 480,
  85393. + ov5642_setting_30fps_VGA_640_480,
  85394. + ARRAY_SIZE(ov5642_setting_30fps_VGA_640_480)},
  85395. + {ov5642_mode_QVGA_320_240, 320, 240,
  85396. + ov5642_setting_30fps_QVGA_320_240,
  85397. + ARRAY_SIZE(ov5642_setting_30fps_QVGA_320_240)},
  85398. + {ov5642_mode_NTSC_720_480, 720, 480,
  85399. + ov5642_setting_30fps_NTSC_720_480,
  85400. + ARRAY_SIZE(ov5642_setting_30fps_NTSC_720_480)},
  85401. + {ov5642_mode_PAL_720_576, 720, 576,
  85402. + ov5642_setting_30fps_PAL_720_576,
  85403. + ARRAY_SIZE(ov5642_setting_30fps_PAL_720_576)},
  85404. + {ov5642_mode_720P_1280_720, 1280, 720,
  85405. + ov5642_setting_30fps_720P_1280_720,
  85406. + ARRAY_SIZE(ov5642_setting_30fps_720P_1280_720)},
  85407. + {ov5642_mode_1080P_1920_1080, 0, 0, NULL, 0},
  85408. + {ov5642_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
  85409. + {ov5642_mode_QCIF_176_144, 176, 144,
  85410. + ov5642_setting_30fps_QCIF_176_144,
  85411. + ARRAY_SIZE(ov5642_setting_30fps_QCIF_176_144)},
  85412. + {ov5642_mode_XGA_1024_768, 1024, 768,
  85413. + ov5642_setting_30fps_XGA_1024_768,
  85414. + ARRAY_SIZE(ov5642_setting_30fps_XGA_1024_768)},
  85415. + },
  85416. +};
  85417. +
  85418. +static struct regulator *io_regulator;
  85419. +static struct regulator *core_regulator;
  85420. +static struct regulator *analog_regulator;
  85421. +static struct regulator *gpo_regulator;
  85422. +
  85423. +static int ov5642_probe(struct i2c_client *adapter,
  85424. + const struct i2c_device_id *device_id);
  85425. +static int ov5642_remove(struct i2c_client *client);
  85426. +
  85427. +static s32 ov5642_read_reg(u16 reg, u8 *val);
  85428. +static s32 ov5642_write_reg(u16 reg, u8 val);
  85429. +
  85430. +static const struct i2c_device_id ov5642_id[] = {
  85431. + {"ov5642", 0},
  85432. + {"ov564x", 0},
  85433. + {},
  85434. +};
  85435. +
  85436. +MODULE_DEVICE_TABLE(i2c, ov5642_id);
  85437. +
  85438. +static struct i2c_driver ov5642_i2c_driver = {
  85439. + .driver = {
  85440. + .owner = THIS_MODULE,
  85441. + .name = "ov5642",
  85442. + },
  85443. + .probe = ov5642_probe,
  85444. + .remove = ov5642_remove,
  85445. + .id_table = ov5642_id,
  85446. +};
  85447. +
  85448. +static void ov5642_standby(s32 enable)
  85449. +{
  85450. + if (enable)
  85451. + gpio_set_value(pwn_gpio, 1);
  85452. + else
  85453. + gpio_set_value(pwn_gpio, 0);
  85454. +
  85455. + msleep(2);
  85456. +}
  85457. +
  85458. +static void ov5642_reset(void)
  85459. +{
  85460. + /* camera reset */
  85461. + gpio_set_value(rst_gpio, 1);
  85462. +
  85463. + /* camera power down */
  85464. + gpio_set_value(pwn_gpio, 1);
  85465. + msleep(5);
  85466. +
  85467. + gpio_set_value(pwn_gpio, 0);
  85468. + msleep(5);
  85469. +
  85470. + gpio_set_value(rst_gpio, 0);
  85471. + msleep(1);
  85472. +
  85473. + gpio_set_value(rst_gpio, 1);
  85474. + msleep(5);
  85475. +
  85476. + gpio_set_value(pwn_gpio, 1);
  85477. +}
  85478. +
  85479. +static int ov5642_power_on(struct device *dev)
  85480. +{
  85481. + int ret = 0;
  85482. +
  85483. + io_regulator = devm_regulator_get(dev, "DOVDD");
  85484. + if (!IS_ERR(io_regulator)) {
  85485. + regulator_set_voltage(io_regulator,
  85486. + OV5642_VOLTAGE_DIGITAL_IO,
  85487. + OV5642_VOLTAGE_DIGITAL_IO);
  85488. + ret = regulator_enable(io_regulator);
  85489. + if (ret) {
  85490. + pr_err("%s:io set voltage error\n", __func__);
  85491. + return ret;
  85492. + } else {
  85493. + dev_dbg(dev,
  85494. + "%s:io set voltage ok\n", __func__);
  85495. + }
  85496. + } else {
  85497. + pr_err("%s: cannot get io voltage error\n", __func__);
  85498. + io_regulator = NULL;
  85499. + }
  85500. +
  85501. + core_regulator = devm_regulator_get(dev, "DVDD");
  85502. + if (!IS_ERR(core_regulator)) {
  85503. + regulator_set_voltage(core_regulator,
  85504. + OV5642_VOLTAGE_DIGITAL_CORE,
  85505. + OV5642_VOLTAGE_DIGITAL_CORE);
  85506. + ret = regulator_enable(core_regulator);
  85507. + if (ret) {
  85508. + pr_err("%s:core set voltage error\n", __func__);
  85509. + return ret;
  85510. + } else {
  85511. + dev_dbg(dev,
  85512. + "%s:core set voltage ok\n", __func__);
  85513. + }
  85514. + } else {
  85515. + core_regulator = NULL;
  85516. + pr_err("%s: cannot get core voltage error\n", __func__);
  85517. + }
  85518. +
  85519. + analog_regulator = devm_regulator_get(dev, "AVDD");
  85520. + if (!IS_ERR(analog_regulator)) {
  85521. + regulator_set_voltage(analog_regulator,
  85522. + OV5642_VOLTAGE_ANALOG,
  85523. + OV5642_VOLTAGE_ANALOG);
  85524. + ret = regulator_enable(analog_regulator);
  85525. + if (ret) {
  85526. + pr_err("%s:analog set voltage error\n",
  85527. + __func__);
  85528. + return ret;
  85529. + } else {
  85530. + dev_dbg(dev,
  85531. + "%s:analog set voltage ok\n", __func__);
  85532. + }
  85533. + } else {
  85534. + analog_regulator = NULL;
  85535. + pr_err("%s: cannot get analog voltage error\n", __func__);
  85536. + }
  85537. +
  85538. + return ret;
  85539. +}
  85540. +
  85541. +static s32 ov5642_write_reg(u16 reg, u8 val)
  85542. +{
  85543. + u8 au8Buf[3] = {0};
  85544. +
  85545. + au8Buf[0] = reg >> 8;
  85546. + au8Buf[1] = reg & 0xff;
  85547. + au8Buf[2] = val;
  85548. +
  85549. + if (i2c_master_send(ov5642_data.i2c_client, au8Buf, 3) < 0) {
  85550. + pr_err("%s:write reg error:reg=%x,val=%x\n",
  85551. + __func__, reg, val);
  85552. + return -1;
  85553. + }
  85554. +
  85555. + return 0;
  85556. +}
  85557. +
  85558. +static s32 ov5642_read_reg(u16 reg, u8 *val)
  85559. +{
  85560. + u8 au8RegBuf[2] = {0};
  85561. + u8 u8RdVal = 0;
  85562. +
  85563. + au8RegBuf[0] = reg >> 8;
  85564. + au8RegBuf[1] = reg & 0xff;
  85565. +
  85566. + if (2 != i2c_master_send(ov5642_data.i2c_client, au8RegBuf, 2)) {
  85567. + pr_err("%s:write reg error:reg=%x\n",
  85568. + __func__, reg);
  85569. + return -1;
  85570. + }
  85571. +
  85572. + if (1 != i2c_master_recv(ov5642_data.i2c_client, &u8RdVal, 1)) {
  85573. + pr_err("%s:read reg error:reg=%x,val=%x\n",
  85574. + __func__, reg, u8RdVal);
  85575. + return -1;
  85576. + }
  85577. +
  85578. + *val = u8RdVal;
  85579. +
  85580. + return u8RdVal;
  85581. +}
  85582. +
  85583. +static int ov5642_set_rot_mode(struct reg_value *rot_mode)
  85584. +{
  85585. + s32 i = 0;
  85586. + s32 iModeSettingArySize = 2;
  85587. + register u32 Delay_ms = 0;
  85588. + register u16 RegAddr = 0;
  85589. + register u8 Mask = 0;
  85590. + register u8 Val = 0;
  85591. + u8 RegVal = 0;
  85592. + int retval = 0;
  85593. + for (i = 0; i < iModeSettingArySize; ++i, ++rot_mode) {
  85594. + Delay_ms = rot_mode->u32Delay_ms;
  85595. + RegAddr = rot_mode->u16RegAddr;
  85596. + Val = rot_mode->u8Val;
  85597. + Mask = rot_mode->u8Mask;
  85598. +
  85599. + if (Mask) {
  85600. + retval = ov5642_read_reg(RegAddr, &RegVal);
  85601. + if (retval < 0) {
  85602. + pr_err("%s, read reg 0x%x failed\n",
  85603. + __func__, RegAddr);
  85604. + goto err;
  85605. + }
  85606. +
  85607. + Val |= RegVal;
  85608. + Val &= Mask;
  85609. + }
  85610. +
  85611. + retval = ov5642_write_reg(RegAddr, Val);
  85612. + if (retval < 0) {
  85613. + pr_err("%s, write reg 0x%x failed\n",
  85614. + __func__, RegAddr);
  85615. + goto err;
  85616. + }
  85617. +
  85618. + if (Delay_ms)
  85619. + mdelay(Delay_ms);
  85620. + }
  85621. +err:
  85622. + return retval;
  85623. +}
  85624. +static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
  85625. + enum ov5642_mode mode);
  85626. +static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
  85627. + enum ov5642_mode mode);
  85628. +static int ov5642_change_mode(enum ov5642_frame_rate new_frame_rate,
  85629. + enum ov5642_frame_rate old_frame_rate,
  85630. + enum ov5642_mode new_mode,
  85631. + enum ov5642_mode orig_mode)
  85632. +{
  85633. + struct reg_value *pModeSetting = NULL;
  85634. + s32 i = 0;
  85635. + s32 iModeSettingArySize = 0;
  85636. + register u32 Delay_ms = 0;
  85637. + register u16 RegAddr = 0;
  85638. + register u8 Mask = 0;
  85639. + register u8 Val = 0;
  85640. + u8 RegVal = 0;
  85641. + int retval = 0;
  85642. +
  85643. + if (new_mode > ov5642_mode_MAX || new_mode < ov5642_mode_MIN) {
  85644. + pr_err("Wrong ov5642 mode detected!\n");
  85645. + return -1;
  85646. + }
  85647. +
  85648. + if ((new_frame_rate == old_frame_rate) &&
  85649. + (new_mode == ov5642_mode_VGA_640_480) &&
  85650. + (orig_mode == ov5642_mode_QSXGA_2592_1944)) {
  85651. + pModeSetting = ov5642_setting_QSXGA_2_VGA;
  85652. + iModeSettingArySize = ARRAY_SIZE(ov5642_setting_QSXGA_2_VGA);
  85653. + ov5642_data.pix.width = 640;
  85654. + ov5642_data.pix.height = 480;
  85655. + } else if ((new_frame_rate == old_frame_rate) &&
  85656. + (new_mode == ov5642_mode_QVGA_320_240) &&
  85657. + (orig_mode == ov5642_mode_VGA_640_480)) {
  85658. + pModeSetting = ov5642_setting_VGA_2_QVGA;
  85659. + iModeSettingArySize = ARRAY_SIZE(ov5642_setting_VGA_2_QVGA);
  85660. + ov5642_data.pix.width = 320;
  85661. + ov5642_data.pix.height = 240;
  85662. + } else {
  85663. + retval = ov5642_write_snapshot_para(new_frame_rate, new_mode);
  85664. + goto err;
  85665. + }
  85666. +
  85667. + if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
  85668. + pModeSetting == NULL || iModeSettingArySize == 0)
  85669. + return -EINVAL;
  85670. +
  85671. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  85672. + Delay_ms = pModeSetting->u32Delay_ms;
  85673. + RegAddr = pModeSetting->u16RegAddr;
  85674. + Val = pModeSetting->u8Val;
  85675. + Mask = pModeSetting->u8Mask;
  85676. +
  85677. + if (Mask) {
  85678. + retval = ov5642_read_reg(RegAddr, &RegVal);
  85679. + if (retval < 0) {
  85680. + pr_err("read reg error addr=0x%x", RegAddr);
  85681. + goto err;
  85682. + }
  85683. +
  85684. + RegVal &= ~(u8)Mask;
  85685. + Val &= Mask;
  85686. + Val |= RegVal;
  85687. + }
  85688. +
  85689. + retval = ov5642_write_reg(RegAddr, Val);
  85690. + if (retval < 0) {
  85691. + pr_err("write reg error addr=0x%x", RegAddr);
  85692. + goto err;
  85693. + }
  85694. +
  85695. + if (Delay_ms)
  85696. + msleep(Delay_ms);
  85697. + }
  85698. +err:
  85699. + return retval;
  85700. +}
  85701. +static int ov5642_init_mode(enum ov5642_frame_rate frame_rate,
  85702. + enum ov5642_mode mode)
  85703. +{
  85704. + struct reg_value *pModeSetting = NULL;
  85705. + s32 i = 0;
  85706. + s32 iModeSettingArySize = 0;
  85707. + register u32 Delay_ms = 0;
  85708. + register u16 RegAddr = 0;
  85709. + register u8 Mask = 0;
  85710. + register u8 Val = 0;
  85711. + u8 RegVal = 0;
  85712. + int retval = 0;
  85713. +
  85714. + if (mode > ov5642_mode_MAX || mode < ov5642_mode_MIN) {
  85715. + pr_err("Wrong ov5642 mode detected!\n");
  85716. + return -1;
  85717. + }
  85718. +
  85719. + pModeSetting = ov5642_mode_info_data[frame_rate][mode].init_data_ptr;
  85720. + iModeSettingArySize =
  85721. + ov5642_mode_info_data[frame_rate][mode].init_data_size;
  85722. +
  85723. + ov5642_data.pix.width = ov5642_mode_info_data[frame_rate][mode].width;
  85724. + ov5642_data.pix.height = ov5642_mode_info_data[frame_rate][mode].height;
  85725. +
  85726. + if (ov5642_data.pix.width == 0 || ov5642_data.pix.height == 0 ||
  85727. + pModeSetting == NULL || iModeSettingArySize == 0)
  85728. + return -EINVAL;
  85729. +
  85730. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  85731. + Delay_ms = pModeSetting->u32Delay_ms;
  85732. + RegAddr = pModeSetting->u16RegAddr;
  85733. + Val = pModeSetting->u8Val;
  85734. + Mask = pModeSetting->u8Mask;
  85735. +
  85736. + if (Mask) {
  85737. + retval = ov5642_read_reg(RegAddr, &RegVal);
  85738. + if (retval < 0) {
  85739. + pr_err("read reg error addr=0x%x", RegAddr);
  85740. + goto err;
  85741. + }
  85742. +
  85743. + RegVal &= ~(u8)Mask;
  85744. + Val &= Mask;
  85745. + Val |= RegVal;
  85746. + }
  85747. +
  85748. + retval = ov5642_write_reg(RegAddr, Val);
  85749. + if (retval < 0) {
  85750. + pr_err("write reg error addr=0x%x", RegAddr);
  85751. + goto err;
  85752. + }
  85753. +
  85754. + if (Delay_ms)
  85755. + msleep(Delay_ms);
  85756. + }
  85757. +err:
  85758. + return retval;
  85759. +}
  85760. +
  85761. +static int ov5642_write_snapshot_para(enum ov5642_frame_rate frame_rate,
  85762. + enum ov5642_mode mode)
  85763. +{
  85764. + int ret = 0;
  85765. + bool m_60Hz = false;
  85766. + u16 cap_frame_rate = 50;
  85767. + u16 g_prev_frame_rate = 225;
  85768. +
  85769. + u8 ev_low, ev_mid, ev_high;
  85770. + u8 ret_l, ret_m, ret_h, gain, lines_10ms;
  85771. + u16 ulcap_ev, icap_gain, prev_maxlines;
  85772. + u32 ulcap_ev_gain, cap_maxlines, g_prev_ev;
  85773. +
  85774. + ov5642_write_reg(0x3503, 0x07);
  85775. +
  85776. + ret_h = ret_m = ret_l = 0;
  85777. + g_prev_ev = 0;
  85778. + ov5642_read_reg(0x3500, &ret_h);
  85779. + ov5642_read_reg(0x3501, &ret_m);
  85780. + ov5642_read_reg(0x3502, &ret_l);
  85781. + g_prev_ev = (ret_h << 12) + (ret_m << 4) + (ret_l >> 4);
  85782. +
  85783. + ret_h = ret_m = ret_l = 0;
  85784. + prev_maxlines = 0;
  85785. + ov5642_read_reg(0x380e, &ret_h);
  85786. + ov5642_read_reg(0x380f, &ret_l);
  85787. + prev_maxlines = (ret_h << 8) + ret_l;
  85788. + /*Read back AGC Gain for preview*/
  85789. + gain = 0;
  85790. + ov5642_read_reg(0x350b, &gain);
  85791. +
  85792. + ret = ov5642_init_mode(frame_rate, mode);
  85793. + if (ret < 0)
  85794. + return ret;
  85795. +
  85796. + ret_h = ret_m = ret_l = 0;
  85797. + ov5642_read_reg(0x380e, &ret_h);
  85798. + ov5642_read_reg(0x380f, &ret_l);
  85799. + cap_maxlines = (ret_h << 8) + ret_l;
  85800. + if (m_60Hz == true)
  85801. + lines_10ms = cap_frame_rate * cap_maxlines/12000;
  85802. + else
  85803. + lines_10ms = cap_frame_rate * cap_maxlines/10000;
  85804. +
  85805. + if (prev_maxlines == 0)
  85806. + prev_maxlines = 1;
  85807. +
  85808. + ulcap_ev = (g_prev_ev*(cap_frame_rate)*(cap_maxlines))/
  85809. + (((prev_maxlines)*(g_prev_frame_rate)));
  85810. + icap_gain = (gain & 0x0f) + 16;
  85811. + if (gain & 0x10)
  85812. + icap_gain = icap_gain << 1;
  85813. +
  85814. + if (gain & 0x20)
  85815. + icap_gain = icap_gain << 1;
  85816. +
  85817. + if (gain & 0x40)
  85818. + icap_gain = icap_gain << 1;
  85819. +
  85820. + if (gain & 0x80)
  85821. + icap_gain = icap_gain << 1;
  85822. +
  85823. + ulcap_ev_gain = 2 * ulcap_ev * icap_gain;
  85824. +
  85825. + if (ulcap_ev_gain < cap_maxlines*16) {
  85826. + ulcap_ev = ulcap_ev_gain/16;
  85827. + if (ulcap_ev > lines_10ms) {
  85828. + ulcap_ev /= lines_10ms;
  85829. + ulcap_ev *= lines_10ms;
  85830. + }
  85831. + } else
  85832. + ulcap_ev = cap_maxlines;
  85833. +
  85834. + if (ulcap_ev == 0)
  85835. + ulcap_ev = 1;
  85836. +
  85837. + icap_gain = (ulcap_ev_gain*2/ulcap_ev + 1)/2;
  85838. + ev_low = ((unsigned char)ulcap_ev)<<4;
  85839. + ev_mid = (unsigned char)(ulcap_ev >> 4) & 0xff;
  85840. + ev_high = (unsigned char)(ulcap_ev >> 12);
  85841. +
  85842. + gain = 0;
  85843. + if (icap_gain > 31) {
  85844. + gain |= 0x10;
  85845. + icap_gain = icap_gain >> 1;
  85846. + }
  85847. + if (icap_gain > 31) {
  85848. + gain |= 0x20;
  85849. + icap_gain = icap_gain >> 1;
  85850. + }
  85851. + if (icap_gain > 31) {
  85852. + gain |= 0x40;
  85853. + icap_gain = icap_gain >> 1;
  85854. + }
  85855. + if (icap_gain > 31) {
  85856. + gain |= 0x80;
  85857. + icap_gain = icap_gain >> 1;
  85858. + }
  85859. + if (icap_gain > 16)
  85860. + gain |= ((icap_gain - 16) & 0x0f);
  85861. +
  85862. + if (gain == 0x10)
  85863. + gain = 0x11;
  85864. +
  85865. + ov5642_write_reg(0x350b, gain);
  85866. + ov5642_write_reg(0x3502, ev_low);
  85867. + ov5642_write_reg(0x3501, ev_mid);
  85868. + ov5642_write_reg(0x3500, ev_high);
  85869. + msleep(500);
  85870. +
  85871. + return ret ;
  85872. +}
  85873. +
  85874. +
  85875. +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
  85876. +
  85877. +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
  85878. +{
  85879. + if (s == NULL) {
  85880. + pr_err(" ERROR!! no slave device set!\n");
  85881. + return -1;
  85882. + }
  85883. +
  85884. + memset(p, 0, sizeof(*p));
  85885. + p->u.bt656.clock_curr = ov5642_data.mclk;
  85886. + pr_debug(" clock_curr=mclk=%d\n", ov5642_data.mclk);
  85887. + p->if_type = V4L2_IF_TYPE_BT656;
  85888. + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
  85889. + p->u.bt656.clock_min = OV5642_XCLK_MIN;
  85890. + p->u.bt656.clock_max = OV5642_XCLK_MAX;
  85891. + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
  85892. +
  85893. + return 0;
  85894. +}
  85895. +
  85896. +/*!
  85897. + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
  85898. + * @s: pointer to standard V4L2 device structure
  85899. + * @on: indicates power mode (on or off)
  85900. + *
  85901. + * Turns the power on or off, depending on the value of on and returns the
  85902. + * appropriate error code.
  85903. + */
  85904. +static int ioctl_s_power(struct v4l2_int_device *s, int on)
  85905. +{
  85906. + struct sensor_data *sensor = s->priv;
  85907. +
  85908. + if (on && !sensor->on) {
  85909. + if (io_regulator)
  85910. + if (regulator_enable(io_regulator) != 0)
  85911. + return -EIO;
  85912. + if (core_regulator)
  85913. + if (regulator_enable(core_regulator) != 0)
  85914. + return -EIO;
  85915. + if (gpo_regulator)
  85916. + if (regulator_enable(gpo_regulator) != 0)
  85917. + return -EIO;
  85918. + if (analog_regulator)
  85919. + if (regulator_enable(analog_regulator) != 0)
  85920. + return -EIO;
  85921. + /* Make sure power on */
  85922. + ov5642_standby(0);
  85923. + } else if (!on && sensor->on) {
  85924. + if (analog_regulator)
  85925. + regulator_disable(analog_regulator);
  85926. + if (core_regulator)
  85927. + regulator_disable(core_regulator);
  85928. + if (io_regulator)
  85929. + regulator_disable(io_regulator);
  85930. + if (gpo_regulator)
  85931. + regulator_disable(gpo_regulator);
  85932. +
  85933. + ov5642_standby(1);
  85934. + }
  85935. +
  85936. + sensor->on = on;
  85937. +
  85938. + return 0;
  85939. +}
  85940. +
  85941. +/*!
  85942. + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
  85943. + * @s: pointer to standard V4L2 device structure
  85944. + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  85945. + *
  85946. + * Returns the sensor's video CAPTURE parameters.
  85947. + */
  85948. +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  85949. +{
  85950. + struct sensor_data *sensor = s->priv;
  85951. + struct v4l2_captureparm *cparm = &a->parm.capture;
  85952. + int ret = 0;
  85953. +
  85954. + switch (a->type) {
  85955. + /* This is the only case currently handled. */
  85956. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  85957. + memset(a, 0, sizeof(*a));
  85958. + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  85959. + cparm->capability = sensor->streamcap.capability;
  85960. + cparm->timeperframe = sensor->streamcap.timeperframe;
  85961. + cparm->capturemode = sensor->streamcap.capturemode;
  85962. + ret = 0;
  85963. + break;
  85964. +
  85965. + /* These are all the possible cases. */
  85966. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  85967. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  85968. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  85969. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  85970. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  85971. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  85972. + ret = -EINVAL;
  85973. + break;
  85974. +
  85975. + default:
  85976. + pr_debug(" type is unknown - %d\n", a->type);
  85977. + ret = -EINVAL;
  85978. + break;
  85979. + }
  85980. +
  85981. + return ret;
  85982. +}
  85983. +
  85984. +/*!
  85985. + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
  85986. + * @s: pointer to standard V4L2 device structure
  85987. + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  85988. + *
  85989. + * Configures the sensor to use the input parameters, if possible. If
  85990. + * not possible, reverts to the old parameters and returns the
  85991. + * appropriate error code.
  85992. + */
  85993. +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
  85994. +{
  85995. + struct sensor_data *sensor = s->priv;
  85996. + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
  85997. + u32 tgt_fps, old_fps; /* target frames per secound */
  85998. + enum ov5642_frame_rate new_frame_rate, old_frame_rate;
  85999. + int ret = 0;
  86000. +
  86001. + /* Make sure power on */
  86002. + ov5642_standby(0);
  86003. +
  86004. + switch (a->type) {
  86005. + /* This is the only case currently handled. */
  86006. + case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  86007. + /* Check that the new frame rate is allowed. */
  86008. + if ((timeperframe->numerator == 0) ||
  86009. + (timeperframe->denominator == 0)) {
  86010. + timeperframe->denominator = DEFAULT_FPS;
  86011. + timeperframe->numerator = 1;
  86012. + }
  86013. +
  86014. + tgt_fps = timeperframe->denominator /
  86015. + timeperframe->numerator;
  86016. +
  86017. + if (tgt_fps > MAX_FPS) {
  86018. + timeperframe->denominator = MAX_FPS;
  86019. + timeperframe->numerator = 1;
  86020. + } else if (tgt_fps < MIN_FPS) {
  86021. + timeperframe->denominator = MIN_FPS;
  86022. + timeperframe->numerator = 1;
  86023. + }
  86024. +
  86025. + /* Actual frame rate we use */
  86026. + tgt_fps = timeperframe->denominator /
  86027. + timeperframe->numerator;
  86028. +
  86029. + if (tgt_fps == 15)
  86030. + new_frame_rate = ov5642_15_fps;
  86031. + else if (tgt_fps == 30)
  86032. + new_frame_rate = ov5642_30_fps;
  86033. + else {
  86034. + pr_err(" The camera frame rate is not supported!\n");
  86035. + return -EINVAL;
  86036. + }
  86037. +
  86038. + if (sensor->streamcap.timeperframe.numerator != 0)
  86039. + old_fps = sensor->streamcap.timeperframe.denominator /
  86040. + sensor->streamcap.timeperframe.numerator;
  86041. + else
  86042. + old_fps = 30;
  86043. +
  86044. + if (old_fps == 15)
  86045. + old_frame_rate = ov5642_15_fps;
  86046. + else if (old_fps == 30)
  86047. + old_frame_rate = ov5642_30_fps;
  86048. + else {
  86049. + pr_warning(" No valid frame rate set!\n");
  86050. + old_frame_rate = ov5642_30_fps;
  86051. + }
  86052. +
  86053. + ret = ov5642_change_mode(new_frame_rate, old_frame_rate,
  86054. + a->parm.capture.capturemode,
  86055. + sensor->streamcap.capturemode);
  86056. + if (ret < 0)
  86057. + return ret;
  86058. +
  86059. + sensor->streamcap.timeperframe = *timeperframe;
  86060. + sensor->streamcap.capturemode =
  86061. + (u32)a->parm.capture.capturemode;
  86062. + break;
  86063. +
  86064. + /* These are all the possible cases. */
  86065. + case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  86066. + case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  86067. + case V4L2_BUF_TYPE_VBI_CAPTURE:
  86068. + case V4L2_BUF_TYPE_VBI_OUTPUT:
  86069. + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  86070. + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  86071. + pr_debug(" type is not " \
  86072. + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
  86073. + a->type);
  86074. + ret = -EINVAL;
  86075. + break;
  86076. +
  86077. + default:
  86078. + pr_debug(" type is unknown - %d\n", a->type);
  86079. + ret = -EINVAL;
  86080. + break;
  86081. + }
  86082. +
  86083. + return ret;
  86084. +}
  86085. +
  86086. +/*!
  86087. + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
  86088. + * @s: pointer to standard V4L2 device structure
  86089. + * @f: pointer to standard V4L2 v4l2_format structure
  86090. + *
  86091. + * Returns the sensor's current pixel format in the v4l2_format
  86092. + * parameter.
  86093. + */
  86094. +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  86095. +{
  86096. + struct sensor_data *sensor = s->priv;
  86097. +
  86098. + f->fmt.pix = sensor->pix;
  86099. +
  86100. + return 0;
  86101. +}
  86102. +
  86103. +/*!
  86104. + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
  86105. + * @s: pointer to standard V4L2 device structure
  86106. + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
  86107. + *
  86108. + * If the requested control is supported, returns the control's current
  86109. + * value from the video_control[] array. Otherwise, returns -EINVAL
  86110. + * if the control is not supported.
  86111. + */
  86112. +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  86113. +{
  86114. + int ret = 0;
  86115. +
  86116. + switch (vc->id) {
  86117. + case V4L2_CID_BRIGHTNESS:
  86118. + vc->value = ov5642_data.brightness;
  86119. + break;
  86120. + case V4L2_CID_HUE:
  86121. + vc->value = ov5642_data.hue;
  86122. + break;
  86123. + case V4L2_CID_CONTRAST:
  86124. + vc->value = ov5642_data.contrast;
  86125. + break;
  86126. + case V4L2_CID_SATURATION:
  86127. + vc->value = ov5642_data.saturation;
  86128. + break;
  86129. + case V4L2_CID_RED_BALANCE:
  86130. + vc->value = ov5642_data.red;
  86131. + break;
  86132. + case V4L2_CID_BLUE_BALANCE:
  86133. + vc->value = ov5642_data.blue;
  86134. + break;
  86135. + case V4L2_CID_EXPOSURE:
  86136. + vc->value = ov5642_data.ae_mode;
  86137. + break;
  86138. + default:
  86139. + ret = -EINVAL;
  86140. + }
  86141. +
  86142. + return ret;
  86143. +}
  86144. +
  86145. +/*!
  86146. + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
  86147. + * @s: pointer to standard V4L2 device structure
  86148. + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
  86149. + *
  86150. + * If the requested control is supported, sets the control's current
  86151. + * value in HW (and updates the video_control[] array). Otherwise,
  86152. + * returns -EINVAL if the control is not supported.
  86153. + */
  86154. +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
  86155. +{
  86156. + int retval = 0;
  86157. + struct sensor_data *sensor = s->priv;
  86158. + __u32 captureMode = sensor->streamcap.capturemode;
  86159. + struct reg_value *rot_mode = NULL;
  86160. +
  86161. + pr_debug("In ov5642:ioctl_s_ctrl %d\n",
  86162. + vc->id);
  86163. +
  86164. + switch (vc->id) {
  86165. + case V4L2_CID_BRIGHTNESS:
  86166. + break;
  86167. + case V4L2_CID_CONTRAST:
  86168. + break;
  86169. + case V4L2_CID_SATURATION:
  86170. + break;
  86171. + case V4L2_CID_HUE:
  86172. + break;
  86173. + case V4L2_CID_AUTO_WHITE_BALANCE:
  86174. + break;
  86175. + case V4L2_CID_DO_WHITE_BALANCE:
  86176. + break;
  86177. + case V4L2_CID_RED_BALANCE:
  86178. + break;
  86179. + case V4L2_CID_BLUE_BALANCE:
  86180. + break;
  86181. + case V4L2_CID_GAMMA:
  86182. + break;
  86183. + case V4L2_CID_EXPOSURE:
  86184. + break;
  86185. + case V4L2_CID_AUTOGAIN:
  86186. + break;
  86187. + case V4L2_CID_GAIN:
  86188. + break;
  86189. + case V4L2_CID_HFLIP:
  86190. + break;
  86191. + case V4L2_CID_VFLIP:
  86192. + break;
  86193. + case V4L2_CID_MXC_ROT:
  86194. + case V4L2_CID_MXC_VF_ROT:
  86195. + switch (vc->value) {
  86196. + case V4L2_MXC_ROTATE_NONE:
  86197. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  86198. + rot_mode = ov5642_rot_none_FULL;
  86199. + else
  86200. + rot_mode = ov5642_rot_none_VGA;
  86201. +
  86202. + if (ov5642_set_rot_mode(rot_mode))
  86203. + retval = -EPERM;
  86204. + break;
  86205. + case V4L2_MXC_ROTATE_VERT_FLIP:
  86206. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  86207. + rot_mode = ov5642_rot_vert_flip_FULL;
  86208. + else
  86209. + rot_mode = ov5642_rot_vert_flip_VGA ;
  86210. +
  86211. + if (ov5642_set_rot_mode(rot_mode))
  86212. + retval = -EPERM;
  86213. + break;
  86214. + case V4L2_MXC_ROTATE_HORIZ_FLIP:
  86215. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  86216. + rot_mode = ov5642_rot_horiz_flip_FULL;
  86217. + else
  86218. + rot_mode = ov5642_rot_horiz_flip_VGA;
  86219. +
  86220. + if (ov5642_set_rot_mode(rot_mode))
  86221. + retval = -EPERM;
  86222. + break;
  86223. + case V4L2_MXC_ROTATE_180:
  86224. + if (captureMode == ov5642_mode_QSXGA_2592_1944)
  86225. + rot_mode = ov5642_rot_180_FULL;
  86226. + else
  86227. + rot_mode = ov5642_rot_180_VGA;
  86228. +
  86229. + if (ov5642_set_rot_mode(rot_mode))
  86230. + retval = -EPERM;
  86231. + break;
  86232. + default:
  86233. + retval = -EPERM;
  86234. + break;
  86235. + }
  86236. + break;
  86237. + default:
  86238. + retval = -EPERM;
  86239. + break;
  86240. + }
  86241. +
  86242. + return retval;
  86243. +}
  86244. +
  86245. +/*!
  86246. + * ioctl_enum_framesizes - V4L2 sensor interface handler for
  86247. + * VIDIOC_ENUM_FRAMESIZES ioctl
  86248. + * @s: pointer to standard V4L2 device structure
  86249. + * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
  86250. + *
  86251. + * Return 0 if successful, otherwise -EINVAL.
  86252. + */
  86253. +static int ioctl_enum_framesizes(struct v4l2_int_device *s,
  86254. + struct v4l2_frmsizeenum *fsize)
  86255. +{
  86256. + if (fsize->index > ov5642_mode_MAX)
  86257. + return -EINVAL;
  86258. +
  86259. + fsize->pixel_format = ov5642_data.pix.pixelformat;
  86260. + fsize->discrete.width =
  86261. + max(ov5642_mode_info_data[0][fsize->index].width,
  86262. + ov5642_mode_info_data[1][fsize->index].width);
  86263. + fsize->discrete.height =
  86264. + max(ov5642_mode_info_data[0][fsize->index].height,
  86265. + ov5642_mode_info_data[1][fsize->index].height);
  86266. + return 0;
  86267. +}
  86268. +
  86269. +/*!
  86270. + * ioctl_enum_frameintervals - V4L2 sensor interface handler for
  86271. + * VIDIOC_ENUM_FRAMEINTERVALS ioctl
  86272. + * @s: pointer to standard V4L2 device structure
  86273. + * @fival: standard V4L2 VIDIOC_ENUM_FRAMEINTERVALS ioctl structure
  86274. + *
  86275. + * Return 0 if successful, otherwise -EINVAL.
  86276. + */
  86277. +static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
  86278. + struct v4l2_frmivalenum *fival)
  86279. +{
  86280. + int i, j, count;
  86281. +
  86282. + if (fival->index < 0 || fival->index > ov5642_mode_MAX)
  86283. + return -EINVAL;
  86284. +
  86285. + if (fival->pixel_format == 0 || fival->width == 0 ||
  86286. + fival->height == 0) {
  86287. + pr_warning("Please assign pixelformat, width and height.\n");
  86288. + return -EINVAL;
  86289. + }
  86290. +
  86291. + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
  86292. + fival->discrete.numerator = 1;
  86293. +
  86294. + count = 0;
  86295. + for (i = 0; i < ARRAY_SIZE(ov5642_mode_info_data); i++) {
  86296. + for (j = 0; j < (ov5642_mode_MAX + 1); j++) {
  86297. + if (fival->pixel_format == ov5642_data.pix.pixelformat
  86298. + && fival->width == ov5642_mode_info_data[i][j].width
  86299. + && fival->height == ov5642_mode_info_data[i][j].height
  86300. + && ov5642_mode_info_data[i][j].init_data_ptr != NULL) {
  86301. + count++;
  86302. + }
  86303. + if (fival->index == (count - 1)) {
  86304. + fival->discrete.denominator =
  86305. + ov5642_framerates[i];
  86306. + return 0;
  86307. + }
  86308. + }
  86309. + }
  86310. +
  86311. + return -EINVAL;
  86312. +}
  86313. +
  86314. +/*!
  86315. + * ioctl_g_chip_ident - V4L2 sensor interface handler for
  86316. + * VIDIOC_DBG_G_CHIP_IDENT ioctl
  86317. + * @s: pointer to standard V4L2 device structure
  86318. + * @id: pointer to int
  86319. + *
  86320. + * Return 0.
  86321. + */
  86322. +static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
  86323. +{
  86324. + ((struct v4l2_dbg_chip_ident *)id)->match.type =
  86325. + V4L2_CHIP_MATCH_I2C_DRIVER;
  86326. + strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov5642_camera");
  86327. +
  86328. + return 0;
  86329. +}
  86330. +
  86331. +/*!
  86332. + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
  86333. + * @s: pointer to standard V4L2 device structure
  86334. + */
  86335. +static int ioctl_init(struct v4l2_int_device *s)
  86336. +{
  86337. +
  86338. + return 0;
  86339. +}
  86340. +
  86341. +/*!
  86342. + * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
  86343. + * @s: pointer to standard V4L2 device structure
  86344. + * @fmt: pointer to standard V4L2 fmt description structure
  86345. + *
  86346. + * Return 0.
  86347. + */
  86348. +static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
  86349. + struct v4l2_fmtdesc *fmt)
  86350. +{
  86351. + if (fmt->index > 0) /* only 1 pixelformat support so far */
  86352. + return -EINVAL;
  86353. +
  86354. + fmt->pixelformat = ov5642_data.pix.pixelformat;
  86355. +
  86356. + return 0;
  86357. +}
  86358. +
  86359. +/*!
  86360. + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
  86361. + * @s: pointer to standard V4L2 device structure
  86362. + *
  86363. + * Initialise the device when slave attaches to the master.
  86364. + */
  86365. +static int ioctl_dev_init(struct v4l2_int_device *s)
  86366. +{
  86367. + struct reg_value *pModeSetting = NULL;
  86368. + s32 i = 0;
  86369. + s32 iModeSettingArySize = 0;
  86370. + register u32 Delay_ms = 0;
  86371. + register u16 RegAddr = 0;
  86372. + register u8 Mask = 0;
  86373. + register u8 Val = 0;
  86374. + u8 RegVal = 0;
  86375. + int retval = 0;
  86376. +
  86377. + struct sensor_data *sensor = s->priv;
  86378. + u32 tgt_xclk; /* target xclk */
  86379. + u32 tgt_fps; /* target frames per secound */
  86380. + enum ov5642_frame_rate frame_rate;
  86381. +
  86382. + ov5642_data.on = true;
  86383. +
  86384. + /* mclk */
  86385. + tgt_xclk = ov5642_data.mclk;
  86386. + tgt_xclk = min(tgt_xclk, (u32)OV5642_XCLK_MAX);
  86387. + tgt_xclk = max(tgt_xclk, (u32)OV5642_XCLK_MIN);
  86388. + ov5642_data.mclk = tgt_xclk;
  86389. +
  86390. + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
  86391. +
  86392. + /* Default camera frame rate is set in probe */
  86393. + tgt_fps = sensor->streamcap.timeperframe.denominator /
  86394. + sensor->streamcap.timeperframe.numerator;
  86395. +
  86396. + if (tgt_fps == 15)
  86397. + frame_rate = ov5642_15_fps;
  86398. + else if (tgt_fps == 30)
  86399. + frame_rate = ov5642_30_fps;
  86400. + else
  86401. + return -EINVAL; /* Only support 15fps or 30fps now. */
  86402. +
  86403. + pModeSetting = ov5642_initial_setting;
  86404. + iModeSettingArySize = ARRAY_SIZE(ov5642_initial_setting);
  86405. +
  86406. + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
  86407. + Delay_ms = pModeSetting->u32Delay_ms;
  86408. + RegAddr = pModeSetting->u16RegAddr;
  86409. + Val = pModeSetting->u8Val;
  86410. + Mask = pModeSetting->u8Mask;
  86411. + if (Mask) {
  86412. + retval = ov5642_read_reg(RegAddr, &RegVal);
  86413. + if (retval < 0)
  86414. + goto err;
  86415. +
  86416. + RegVal &= ~(u8)Mask;
  86417. + Val &= Mask;
  86418. + Val |= RegVal;
  86419. + }
  86420. +
  86421. + retval = ov5642_write_reg(RegAddr, Val);
  86422. + if (retval < 0)
  86423. + goto err;
  86424. +
  86425. + if (Delay_ms)
  86426. + msleep(Delay_ms);
  86427. + }
  86428. +err:
  86429. + return retval;
  86430. +}
  86431. +
  86432. +/*!
  86433. + * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
  86434. + * @s: pointer to standard V4L2 device structure
  86435. + *
  86436. + * Delinitialise the device when slave detaches to the master.
  86437. + */
  86438. +static int ioctl_dev_exit(struct v4l2_int_device *s)
  86439. +{
  86440. + return 0;
  86441. +}
  86442. +
  86443. +/*!
  86444. + * This structure defines all the ioctls for this module and links them to the
  86445. + * enumeration.
  86446. + */
  86447. +static struct v4l2_int_ioctl_desc ov5642_ioctl_desc[] = {
  86448. + { vidioc_int_dev_init_num,
  86449. + (v4l2_int_ioctl_func *)ioctl_dev_init },
  86450. + { vidioc_int_dev_exit_num, ioctl_dev_exit},
  86451. + { vidioc_int_s_power_num,
  86452. + (v4l2_int_ioctl_func *)ioctl_s_power },
  86453. + { vidioc_int_g_ifparm_num,
  86454. + (v4l2_int_ioctl_func *)ioctl_g_ifparm },
  86455. +/* { vidioc_int_g_needs_reset_num,
  86456. + (v4l2_int_ioctl_func *)ioctl_g_needs_reset }, */
  86457. +/* { vidioc_int_reset_num,
  86458. + (v4l2_int_ioctl_func *)ioctl_reset }, */
  86459. + { vidioc_int_init_num,
  86460. + (v4l2_int_ioctl_func *)ioctl_init },
  86461. + { vidioc_int_enum_fmt_cap_num,
  86462. + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
  86463. +/* { vidioc_int_try_fmt_cap_num,
  86464. + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap }, */
  86465. + { vidioc_int_g_fmt_cap_num,
  86466. + (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
  86467. +/* { vidioc_int_s_fmt_cap_num,
  86468. + (v4l2_int_ioctl_func *)ioctl_s_fmt_cap }, */
  86469. + { vidioc_int_g_parm_num,
  86470. + (v4l2_int_ioctl_func *)ioctl_g_parm },
  86471. + { vidioc_int_s_parm_num,
  86472. + (v4l2_int_ioctl_func *)ioctl_s_parm },
  86473. +/* { vidioc_int_queryctrl_num,
  86474. + (v4l2_int_ioctl_func *)ioctl_queryctrl }, */
  86475. + { vidioc_int_g_ctrl_num,
  86476. + (v4l2_int_ioctl_func *)ioctl_g_ctrl },
  86477. + { vidioc_int_s_ctrl_num,
  86478. + (v4l2_int_ioctl_func *)ioctl_s_ctrl },
  86479. + { vidioc_int_enum_framesizes_num,
  86480. + (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
  86481. + { vidioc_int_enum_frameintervals_num,
  86482. + (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
  86483. + { vidioc_int_g_chip_ident_num,
  86484. + (v4l2_int_ioctl_func *)ioctl_g_chip_ident },
  86485. +};
  86486. +
  86487. +static struct v4l2_int_slave ov5642_slave = {
  86488. + .ioctls = ov5642_ioctl_desc,
  86489. + .num_ioctls = ARRAY_SIZE(ov5642_ioctl_desc),
  86490. +};
  86491. +
  86492. +static struct v4l2_int_device ov5642_int_device = {
  86493. + .module = THIS_MODULE,
  86494. + .name = "ov5642",
  86495. + .type = v4l2_int_type_slave,
  86496. + .u = {
  86497. + .slave = &ov5642_slave,
  86498. + },
  86499. +};
  86500. +
  86501. +/*!
  86502. + * ov5642 I2C probe function
  86503. + *
  86504. + * @param adapter struct i2c_adapter *
  86505. + * @return Error code indicating success or failure
  86506. + */
  86507. +static int ov5642_probe(struct i2c_client *client,
  86508. + const struct i2c_device_id *id)
  86509. +{
  86510. + struct pinctrl *pinctrl;
  86511. + struct device *dev = &client->dev;
  86512. + int retval;
  86513. + u8 chip_id_high, chip_id_low;
  86514. +
  86515. + /* ov5642 pinctrl */
  86516. + pinctrl = devm_pinctrl_get_select_default(dev);
  86517. + if (IS_ERR(pinctrl)) {
  86518. + dev_err(dev, "ov5642 setup pinctrl failed!");
  86519. + return PTR_ERR(pinctrl);
  86520. + }
  86521. +
  86522. + /* request power down pin */
  86523. + pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
  86524. + if (!gpio_is_valid(pwn_gpio)) {
  86525. + dev_warn(dev, "no sensor pwdn pin available");
  86526. + return -EINVAL;
  86527. + }
  86528. + retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
  86529. + "ov5642_pwdn");
  86530. + if (retval < 0)
  86531. + return retval;
  86532. +
  86533. + /* request reset pin */
  86534. + rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  86535. + if (!gpio_is_valid(rst_gpio)) {
  86536. + dev_warn(dev, "no sensor reset pin available");
  86537. + return -EINVAL;
  86538. + }
  86539. + retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_HIGH,
  86540. + "ov5642_reset");
  86541. + if (retval < 0)
  86542. + return retval;
  86543. +
  86544. + /* Set initial values for the sensor struct. */
  86545. + memset(&ov5642_data, 0, sizeof(ov5642_data));
  86546. + ov5642_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
  86547. + if (IS_ERR(ov5642_data.sensor_clk)) {
  86548. + /* assuming clock enabled by default */
  86549. + ov5642_data.sensor_clk = NULL;
  86550. + dev_err(dev, "clock-frequency missing or invalid\n");
  86551. + return PTR_ERR(ov5642_data.sensor_clk);
  86552. + }
  86553. +
  86554. + retval = of_property_read_u32(dev->of_node, "mclk",
  86555. + (u32 *) &(ov5642_data.mclk));
  86556. + if (retval) {
  86557. + dev_err(dev, "mclk missing or invalid\n");
  86558. + return retval;
  86559. + }
  86560. +
  86561. + retval = of_property_read_u32(dev->of_node, "mclk_source",
  86562. + (u32 *) &(ov5642_data.mclk_source));
  86563. + if (retval) {
  86564. + dev_err(dev, "mclk_source missing or invalid\n");
  86565. + return retval;
  86566. + }
  86567. +
  86568. + retval = of_property_read_u32(dev->of_node, "csi_id",
  86569. + &(ov5642_data.csi));
  86570. + if (retval) {
  86571. + dev_err(dev, "csi_id missing or invalid\n");
  86572. + return retval;
  86573. + }
  86574. +
  86575. + clk_prepare_enable(ov5642_data.sensor_clk);
  86576. +
  86577. + ov5642_data.io_init = ov5642_reset;
  86578. + ov5642_data.i2c_client = client;
  86579. + ov5642_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
  86580. + ov5642_data.pix.width = 640;
  86581. + ov5642_data.pix.height = 480;
  86582. + ov5642_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
  86583. + V4L2_CAP_TIMEPERFRAME;
  86584. + ov5642_data.streamcap.capturemode = 0;
  86585. + ov5642_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  86586. + ov5642_data.streamcap.timeperframe.numerator = 1;
  86587. +
  86588. + ov5642_power_on(&client->dev);
  86589. +
  86590. + ov5642_reset();
  86591. +
  86592. + ov5642_standby(0);
  86593. +
  86594. + retval = ov5642_read_reg(OV5642_CHIP_ID_HIGH_BYTE, &chip_id_high);
  86595. + if (retval < 0 || chip_id_high != 0x56) {
  86596. + pr_warning("camera ov5642 is not found\n");
  86597. + clk_disable_unprepare(ov5642_data.sensor_clk);
  86598. + return -ENODEV;
  86599. + }
  86600. + retval = ov5642_read_reg(OV5642_CHIP_ID_LOW_BYTE, &chip_id_low);
  86601. + if (retval < 0 || chip_id_low != 0x42) {
  86602. + pr_warning("camera ov5642 is not found\n");
  86603. + clk_disable_unprepare(ov5642_data.sensor_clk);
  86604. + return -ENODEV;
  86605. + }
  86606. +
  86607. + ov5642_standby(1);
  86608. +
  86609. + ov5642_int_device.priv = &ov5642_data;
  86610. + retval = v4l2_int_device_register(&ov5642_int_device);
  86611. +
  86612. + clk_disable_unprepare(ov5642_data.sensor_clk);
  86613. +
  86614. + pr_info("camera ov5642 is found\n");
  86615. + return retval;
  86616. +}
  86617. +
  86618. +/*!
  86619. + * ov5642 I2C detach function
  86620. + *
  86621. + * @param client struct i2c_client *
  86622. + * @return Error code indicating success or failure
  86623. + */
  86624. +static int ov5642_remove(struct i2c_client *client)
  86625. +{
  86626. + v4l2_int_device_unregister(&ov5642_int_device);
  86627. +
  86628. + if (gpo_regulator)
  86629. + regulator_disable(gpo_regulator);
  86630. +
  86631. + if (analog_regulator)
  86632. + regulator_disable(analog_regulator);
  86633. +
  86634. + if (core_regulator)
  86635. + regulator_disable(core_regulator);
  86636. +
  86637. + if (io_regulator)
  86638. + regulator_disable(io_regulator);
  86639. +
  86640. + return 0;
  86641. +}
  86642. +
  86643. +/*!
  86644. + * ov5642 init function
  86645. + * Called by insmod ov5642_camera.ko.
  86646. + *
  86647. + * @return Error code indicating success or failure
  86648. + */
  86649. +static __init int ov5642_init(void)
  86650. +{
  86651. + u8 err;
  86652. +
  86653. + err = i2c_add_driver(&ov5642_i2c_driver);
  86654. + if (err != 0)
  86655. + pr_err("%s:driver registration failed, error=%d\n",
  86656. + __func__, err);
  86657. +
  86658. + return err;
  86659. +}
  86660. +
  86661. +/*!
  86662. + * OV5642 cleanup function
  86663. + * Called on rmmod ov5642_camera.ko
  86664. + *
  86665. + * @return Error code indicating success or failure
  86666. + */
  86667. +static void __exit ov5642_clean(void)
  86668. +{
  86669. + i2c_del_driver(&ov5642_i2c_driver);
  86670. +}
  86671. +
  86672. +module_init(ov5642_init);
  86673. +module_exit(ov5642_clean);
  86674. +
  86675. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  86676. +MODULE_DESCRIPTION("OV5642 Camera Driver");
  86677. +MODULE_LICENSE("GPL");
  86678. +MODULE_VERSION("1.0");
  86679. +MODULE_ALIAS("CSI");
  86680. diff -Nur linux-3.14.17/drivers/media/platform/mxc/output/Kconfig linux-imx6-3.14/drivers/media/platform/mxc/output/Kconfig
  86681. --- linux-3.14.17/drivers/media/platform/mxc/output/Kconfig 1970-01-01 01:00:00.000000000 +0100
  86682. +++ linux-imx6-3.14/drivers/media/platform/mxc/output/Kconfig 2014-09-11 18:06:02.254038983 +0200
  86683. @@ -0,0 +1,5 @@
  86684. +config VIDEO_MXC_IPU_OUTPUT
  86685. + tristate "IPU v4l2 output support"
  86686. + depends on VIDEO_MXC_OUTPUT && MXC_IPU
  86687. + ---help---
  86688. + This is the video4linux2 driver for IPU post processing video output.
  86689. diff -Nur linux-3.14.17/drivers/media/platform/mxc/output/Makefile linux-imx6-3.14/drivers/media/platform/mxc/output/Makefile
  86690. --- linux-3.14.17/drivers/media/platform/mxc/output/Makefile 1970-01-01 01:00:00.000000000 +0100
  86691. +++ linux-imx6-3.14/drivers/media/platform/mxc/output/Makefile 2014-09-11 18:06:02.254038983 +0200
  86692. @@ -0,0 +1 @@
  86693. +obj-$(CONFIG_VIDEO_MXC_IPU_OUTPUT) += mxc_vout.o
  86694. diff -Nur linux-3.14.17/drivers/media/platform/mxc/output/mxc_vout.c linux-imx6-3.14/drivers/media/platform/mxc/output/mxc_vout.c
  86695. --- linux-3.14.17/drivers/media/platform/mxc/output/mxc_vout.c 1970-01-01 01:00:00.000000000 +0100
  86696. +++ linux-imx6-3.14/drivers/media/platform/mxc/output/mxc_vout.c 2014-09-11 18:06:02.258038999 +0200
  86697. @@ -0,0 +1,2265 @@
  86698. +/*
  86699. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  86700. + */
  86701. +
  86702. +/*
  86703. + * The code contained herein is licensed under the GNU General Public
  86704. + * License. You may obtain a copy of the GNU General Public License
  86705. + * Version 2 or later at the following locations:
  86706. + *
  86707. + * http://www.opensource.org/licenses/gpl-license.html
  86708. + * http://www.gnu.org/copyleft/gpl.html
  86709. + */
  86710. +
  86711. +#include <linux/console.h>
  86712. +#include <linux/dma-mapping.h>
  86713. +#include <linux/init.h>
  86714. +#include <linux/ipu-v3.h>
  86715. +#include <linux/module.h>
  86716. +#include <linux/mxcfb.h>
  86717. +#include <linux/mxc_v4l2.h>
  86718. +#include <linux/platform_device.h>
  86719. +#include <linux/sched.h>
  86720. +#include <linux/types.h>
  86721. +#include <linux/videodev2.h>
  86722. +#include <linux/vmalloc.h>
  86723. +
  86724. +#include <media/videobuf-dma-contig.h>
  86725. +#include <media/v4l2-device.h>
  86726. +#include <media/v4l2-ioctl.h>
  86727. +
  86728. +#define UYVY_BLACK (0x00800080)
  86729. +#define RGB_BLACK (0x0)
  86730. +#define UV_BLACK (0x80)
  86731. +#define Y_BLACK (0x0)
  86732. +
  86733. +#define MAX_FB_NUM 6
  86734. +#define FB_BUFS 3
  86735. +#define VDOA_FB_BUFS (FB_BUFS - 1)
  86736. +#define VALID_HEIGHT_1080P (1080)
  86737. +#define FRAME_HEIGHT_1080P (1088)
  86738. +#define FRAME_WIDTH_1080P (1920)
  86739. +#define CHECK_TILED_1080P_DISPLAY(vout) \
  86740. + ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
  86741. + ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
  86742. + ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
  86743. + ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
  86744. + ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
  86745. + (((vout)->task.input.crop.h == FRAME_HEIGHT_1080P) || \
  86746. + ((vout)->task.input.crop.h == VALID_HEIGHT_1080P)) && \
  86747. + ((vout)->task.output.width == FRAME_WIDTH_1080P) && \
  86748. + ((vout)->task.output.height == VALID_HEIGHT_1080P) && \
  86749. + ((vout)->task.output.crop.w == FRAME_WIDTH_1080P) && \
  86750. + ((vout)->task.output.crop.h == VALID_HEIGHT_1080P))
  86751. +#define CHECK_TILED_1080P_STREAM(vout) \
  86752. + ((((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12) || \
  86753. + ((vout)->task.input.format == IPU_PIX_FMT_TILED_NV12F)) &&\
  86754. + ((vout)->task.input.width == FRAME_WIDTH_1080P) && \
  86755. + ((vout)->task.input.crop.w == FRAME_WIDTH_1080P) && \
  86756. + ((vout)->task.input.height == FRAME_HEIGHT_1080P) && \
  86757. + ((vout)->task.input.crop.h == FRAME_HEIGHT_1080P))
  86758. +#define IS_PLANAR_PIXEL_FORMAT(format) \
  86759. + (format == IPU_PIX_FMT_NV12 || \
  86760. + format == IPU_PIX_FMT_YUV420P2 || \
  86761. + format == IPU_PIX_FMT_YUV420P || \
  86762. + format == IPU_PIX_FMT_YVU420P || \
  86763. + format == IPU_PIX_FMT_YUV422P || \
  86764. + format == IPU_PIX_FMT_YVU422P || \
  86765. + format == IPU_PIX_FMT_YUV444P)
  86766. +
  86767. +#define NSEC_PER_FRAME_30FPS (33333333)
  86768. +
  86769. +struct mxc_vout_fb {
  86770. + char *name;
  86771. + int ipu_id;
  86772. + struct v4l2_rect crop_bounds;
  86773. + unsigned int disp_fmt;
  86774. + bool disp_support_csc;
  86775. + bool disp_support_windows;
  86776. +};
  86777. +
  86778. +struct dma_mem {
  86779. + void *vaddr;
  86780. + dma_addr_t paddr;
  86781. + size_t size;
  86782. +};
  86783. +
  86784. +struct mxc_vout_output {
  86785. + int open_cnt;
  86786. + struct fb_info *fbi;
  86787. + unsigned long fb_smem_start;
  86788. + unsigned long fb_smem_len;
  86789. + struct video_device *vfd;
  86790. + struct mutex mutex;
  86791. + struct mutex task_lock;
  86792. + enum v4l2_buf_type type;
  86793. +
  86794. + struct videobuf_queue vbq;
  86795. + spinlock_t vbq_lock;
  86796. +
  86797. + struct list_head queue_list;
  86798. + struct list_head active_list;
  86799. +
  86800. + struct v4l2_rect crop_bounds;
  86801. + unsigned int disp_fmt;
  86802. + struct mxcfb_pos win_pos;
  86803. + bool disp_support_windows;
  86804. + bool disp_support_csc;
  86805. +
  86806. + bool fmt_init;
  86807. + bool release;
  86808. + bool linear_bypass_pp;
  86809. + bool vdoa_1080p;
  86810. + bool tiled_bypass_pp;
  86811. + struct v4l2_rect in_rect;
  86812. + struct ipu_task task;
  86813. + struct ipu_task vdoa_task;
  86814. + struct dma_mem vdoa_work;
  86815. + struct dma_mem vdoa_output[VDOA_FB_BUFS];
  86816. +
  86817. + bool timer_stop;
  86818. + struct hrtimer timer;
  86819. + struct workqueue_struct *v4l_wq;
  86820. + struct work_struct disp_work;
  86821. + unsigned long frame_count;
  86822. + unsigned long vdi_frame_cnt;
  86823. + ktime_t start_ktime;
  86824. +
  86825. + int ctrl_rotate;
  86826. + int ctrl_vflip;
  86827. + int ctrl_hflip;
  86828. +
  86829. + dma_addr_t disp_bufs[FB_BUFS];
  86830. +
  86831. + struct videobuf_buffer *pre1_vb;
  86832. + struct videobuf_buffer *pre2_vb;
  86833. +};
  86834. +
  86835. +struct mxc_vout_dev {
  86836. + struct device *dev;
  86837. + struct v4l2_device v4l2_dev;
  86838. + struct mxc_vout_output *out[MAX_FB_NUM];
  86839. + int out_num;
  86840. +};
  86841. +
  86842. +/* Driver Configuration macros */
  86843. +#define VOUT_NAME "mxc_vout"
  86844. +
  86845. +/* Variables configurable through module params*/
  86846. +static int debug;
  86847. +static int vdi_rate_double;
  86848. +static int video_nr = 16;
  86849. +
  86850. +/* Module parameters */
  86851. +module_param(video_nr, int, S_IRUGO);
  86852. +MODULE_PARM_DESC(video_nr, "video device numbers");
  86853. +module_param(debug, int, 0600);
  86854. +MODULE_PARM_DESC(debug, "Debug level (0-1)");
  86855. +module_param(vdi_rate_double, int, 0600);
  86856. +MODULE_PARM_DESC(vdi_rate_double, "vdi frame rate double on/off");
  86857. +
  86858. +static const struct v4l2_fmtdesc mxc_formats[] = {
  86859. + {
  86860. + .description = "RGB565",
  86861. + .pixelformat = V4L2_PIX_FMT_RGB565,
  86862. + },
  86863. + {
  86864. + .description = "BGR24",
  86865. + .pixelformat = V4L2_PIX_FMT_BGR24,
  86866. + },
  86867. + {
  86868. + .description = "RGB24",
  86869. + .pixelformat = V4L2_PIX_FMT_RGB24,
  86870. + },
  86871. + {
  86872. + .description = "RGB32",
  86873. + .pixelformat = V4L2_PIX_FMT_RGB32,
  86874. + },
  86875. + {
  86876. + .description = "BGR32",
  86877. + .pixelformat = V4L2_PIX_FMT_BGR32,
  86878. + },
  86879. + {
  86880. + .description = "NV12",
  86881. + .pixelformat = V4L2_PIX_FMT_NV12,
  86882. + },
  86883. + {
  86884. + .description = "UYVY",
  86885. + .pixelformat = V4L2_PIX_FMT_UYVY,
  86886. + },
  86887. + {
  86888. + .description = "YUYV",
  86889. + .pixelformat = V4L2_PIX_FMT_YUYV,
  86890. + },
  86891. + {
  86892. + .description = "YUV422 planar",
  86893. + .pixelformat = V4L2_PIX_FMT_YUV422P,
  86894. + },
  86895. + {
  86896. + .description = "YUV444",
  86897. + .pixelformat = V4L2_PIX_FMT_YUV444,
  86898. + },
  86899. + {
  86900. + .description = "YUV420",
  86901. + .pixelformat = V4L2_PIX_FMT_YUV420,
  86902. + },
  86903. + {
  86904. + .description = "YVU420",
  86905. + .pixelformat = V4L2_PIX_FMT_YVU420,
  86906. + },
  86907. + {
  86908. + .description = "TILED NV12P",
  86909. + .pixelformat = IPU_PIX_FMT_TILED_NV12,
  86910. + },
  86911. + {
  86912. + .description = "TILED NV12F",
  86913. + .pixelformat = IPU_PIX_FMT_TILED_NV12F,
  86914. + },
  86915. + {
  86916. + .description = "YUV444 planar",
  86917. + .pixelformat = IPU_PIX_FMT_YUV444P,
  86918. + },
  86919. +};
  86920. +
  86921. +#define NUM_MXC_VOUT_FORMATS (ARRAY_SIZE(mxc_formats))
  86922. +
  86923. +#define DEF_INPUT_WIDTH 320
  86924. +#define DEF_INPUT_HEIGHT 240
  86925. +
  86926. +static int mxc_vidioc_streamoff(struct file *file, void *fh,
  86927. + enum v4l2_buf_type i);
  86928. +
  86929. +static struct mxc_vout_fb g_fb_setting[MAX_FB_NUM];
  86930. +static int config_disp_output(struct mxc_vout_output *vout);
  86931. +static void release_disp_output(struct mxc_vout_output *vout);
  86932. +
  86933. +static unsigned int get_frame_size(struct mxc_vout_output *vout)
  86934. +{
  86935. + unsigned int size;
  86936. +
  86937. + if (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)
  86938. + size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
  86939. + vout->task.input.height);
  86940. + else if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
  86941. + size = TILED_NV12_FRAME_SIZE(vout->task.input.width,
  86942. + vout->task.input.height/2);
  86943. + size *= 2;
  86944. + } else
  86945. + size = vout->task.input.width * vout->task.input.height *
  86946. + fmt_to_bpp(vout->task.input.format)/8;
  86947. +
  86948. + return size;
  86949. +}
  86950. +
  86951. +static void free_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
  86952. +{
  86953. + dma_free_coherent(vout->vbq.dev, buf->size, buf->vaddr, buf->paddr);
  86954. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  86955. + "free dma size:0x%x, paddr:0x%x\n",
  86956. + buf->size, buf->paddr);
  86957. + memset(buf, 0, sizeof(*buf));
  86958. +}
  86959. +
  86960. +static int alloc_dma_buf(struct mxc_vout_output *vout, struct dma_mem *buf)
  86961. +{
  86962. +
  86963. + buf->vaddr = dma_alloc_coherent(vout->vbq.dev, buf->size, &buf->paddr,
  86964. + GFP_DMA | GFP_KERNEL);
  86965. + if (!buf->vaddr) {
  86966. + v4l2_err(vout->vfd->v4l2_dev,
  86967. + "cannot get dma buf size:0x%x\n", buf->size);
  86968. + return -ENOMEM;
  86969. + }
  86970. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  86971. + "alloc dma buf size:0x%x, paddr:0x%x\n", buf->size, buf->paddr);
  86972. + return 0;
  86973. +}
  86974. +
  86975. +static ipu_channel_t get_ipu_channel(struct fb_info *fbi)
  86976. +{
  86977. + ipu_channel_t ipu_ch = CHAN_NONE;
  86978. + mm_segment_t old_fs;
  86979. +
  86980. + if (fbi->fbops->fb_ioctl) {
  86981. + old_fs = get_fs();
  86982. + set_fs(KERNEL_DS);
  86983. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
  86984. + (unsigned long)&ipu_ch);
  86985. + set_fs(old_fs);
  86986. + }
  86987. +
  86988. + return ipu_ch;
  86989. +}
  86990. +
  86991. +static unsigned int get_ipu_fmt(struct fb_info *fbi)
  86992. +{
  86993. + mm_segment_t old_fs;
  86994. + unsigned int fb_fmt;
  86995. +
  86996. + if (fbi->fbops->fb_ioctl) {
  86997. + old_fs = get_fs();
  86998. + set_fs(KERNEL_DS);
  86999. + fbi->fbops->fb_ioctl(fbi, MXCFB_GET_DIFMT,
  87000. + (unsigned long)&fb_fmt);
  87001. + set_fs(old_fs);
  87002. + }
  87003. +
  87004. + return fb_fmt;
  87005. +}
  87006. +
  87007. +static void update_display_setting(void)
  87008. +{
  87009. + int i;
  87010. + struct fb_info *fbi;
  87011. + struct v4l2_rect bg_crop_bounds[2];
  87012. +
  87013. + for (i = 0; i < num_registered_fb; i++) {
  87014. + fbi = registered_fb[i];
  87015. +
  87016. + memset(&g_fb_setting[i], 0, sizeof(struct mxc_vout_fb));
  87017. +
  87018. + if (!strncmp(fbi->fix.id, "DISP3", 5))
  87019. + g_fb_setting[i].ipu_id = 0;
  87020. + else
  87021. + g_fb_setting[i].ipu_id = 1;
  87022. +
  87023. + g_fb_setting[i].name = fbi->fix.id;
  87024. + g_fb_setting[i].crop_bounds.left = 0;
  87025. + g_fb_setting[i].crop_bounds.top = 0;
  87026. + g_fb_setting[i].crop_bounds.width = fbi->var.xres;
  87027. + g_fb_setting[i].crop_bounds.height = fbi->var.yres;
  87028. + g_fb_setting[i].disp_fmt = get_ipu_fmt(fbi);
  87029. +
  87030. + if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
  87031. + bg_crop_bounds[g_fb_setting[i].ipu_id] =
  87032. + g_fb_setting[i].crop_bounds;
  87033. + g_fb_setting[i].disp_support_csc = true;
  87034. + } else if (get_ipu_channel(fbi) == MEM_FG_SYNC) {
  87035. + g_fb_setting[i].disp_support_csc = true;
  87036. + g_fb_setting[i].disp_support_windows = true;
  87037. + }
  87038. + }
  87039. +
  87040. + for (i = 0; i < num_registered_fb; i++) {
  87041. + fbi = registered_fb[i];
  87042. +
  87043. + if (get_ipu_channel(fbi) == MEM_FG_SYNC)
  87044. + g_fb_setting[i].crop_bounds =
  87045. + bg_crop_bounds[g_fb_setting[i].ipu_id];
  87046. + }
  87047. +}
  87048. +
  87049. +/* called after g_fb_setting filled by update_display_setting */
  87050. +static int update_setting_from_fbi(struct mxc_vout_output *vout,
  87051. + struct fb_info *fbi)
  87052. +{
  87053. + int i;
  87054. + bool found = false;
  87055. +
  87056. + for (i = 0; i < MAX_FB_NUM; i++) {
  87057. + if (g_fb_setting[i].name) {
  87058. + if (!strcmp(fbi->fix.id, g_fb_setting[i].name)) {
  87059. + vout->crop_bounds = g_fb_setting[i].crop_bounds;
  87060. + vout->disp_fmt = g_fb_setting[i].disp_fmt;
  87061. + vout->disp_support_csc =
  87062. + g_fb_setting[i].disp_support_csc;
  87063. + vout->disp_support_windows =
  87064. + g_fb_setting[i].disp_support_windows;
  87065. + found = true;
  87066. + break;
  87067. + }
  87068. + }
  87069. + }
  87070. +
  87071. + if (!found) {
  87072. + v4l2_err(vout->vfd->v4l2_dev, "can not find output\n");
  87073. + return -EINVAL;
  87074. + }
  87075. + strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
  87076. +
  87077. + memset(&vout->task, 0, sizeof(struct ipu_task));
  87078. +
  87079. + vout->task.input.width = DEF_INPUT_WIDTH;
  87080. + vout->task.input.height = DEF_INPUT_HEIGHT;
  87081. + vout->task.input.crop.pos.x = 0;
  87082. + vout->task.input.crop.pos.y = 0;
  87083. + vout->task.input.crop.w = DEF_INPUT_WIDTH;
  87084. + vout->task.input.crop.h = DEF_INPUT_HEIGHT;
  87085. +
  87086. + vout->task.output.width = vout->crop_bounds.width;
  87087. + vout->task.output.height = vout->crop_bounds.height;
  87088. + vout->task.output.crop.pos.x = 0;
  87089. + vout->task.output.crop.pos.y = 0;
  87090. + vout->task.output.crop.w = vout->crop_bounds.width;
  87091. + vout->task.output.crop.h = vout->crop_bounds.height;
  87092. + if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
  87093. + vout->task.output.format = IPU_PIX_FMT_UYVY;
  87094. + else
  87095. + vout->task.output.format = IPU_PIX_FMT_RGB565;
  87096. +
  87097. + return 0;
  87098. +}
  87099. +
  87100. +static inline unsigned long get_jiffies(struct timeval *t)
  87101. +{
  87102. + struct timeval cur;
  87103. +
  87104. + if (t->tv_usec >= 1000000) {
  87105. + t->tv_sec += t->tv_usec / 1000000;
  87106. + t->tv_usec = t->tv_usec % 1000000;
  87107. + }
  87108. +
  87109. + do_gettimeofday(&cur);
  87110. + if ((t->tv_sec < cur.tv_sec)
  87111. + || ((t->tv_sec == cur.tv_sec) && (t->tv_usec < cur.tv_usec)))
  87112. + return jiffies;
  87113. +
  87114. + if (t->tv_usec < cur.tv_usec) {
  87115. + cur.tv_sec = t->tv_sec - cur.tv_sec - 1;
  87116. + cur.tv_usec = t->tv_usec + 1000000 - cur.tv_usec;
  87117. + } else {
  87118. + cur.tv_sec = t->tv_sec - cur.tv_sec;
  87119. + cur.tv_usec = t->tv_usec - cur.tv_usec;
  87120. + }
  87121. +
  87122. + return jiffies + timeval_to_jiffies(&cur);
  87123. +}
  87124. +
  87125. +static bool deinterlace_3_field(struct mxc_vout_output *vout)
  87126. +{
  87127. + return (vout->task.input.deinterlace.enable &&
  87128. + (vout->task.input.deinterlace.motion != HIGH_MOTION));
  87129. +}
  87130. +
  87131. +static int set_field_fmt(struct mxc_vout_output *vout, enum v4l2_field field)
  87132. +{
  87133. + struct ipu_deinterlace *deinterlace = &vout->task.input.deinterlace;
  87134. +
  87135. + switch (field) {
  87136. + /* Images are in progressive format, not interlaced */
  87137. + case V4L2_FIELD_NONE:
  87138. + case V4L2_FIELD_ANY:
  87139. + deinterlace->enable = false;
  87140. + deinterlace->field_fmt = 0;
  87141. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "Progressive frame.\n");
  87142. + break;
  87143. + case V4L2_FIELD_INTERLACED_TB:
  87144. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87145. + "Enable deinterlace TB.\n");
  87146. + deinterlace->enable = true;
  87147. + deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_TOP;
  87148. + break;
  87149. + case V4L2_FIELD_INTERLACED_BT:
  87150. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87151. + "Enable deinterlace BT.\n");
  87152. + deinterlace->enable = true;
  87153. + deinterlace->field_fmt = IPU_DEINTERLACE_FIELD_BOTTOM;
  87154. + break;
  87155. + default:
  87156. + v4l2_err(vout->vfd->v4l2_dev,
  87157. + "field format:%d not supported yet!\n", field);
  87158. + return -EINVAL;
  87159. + }
  87160. +
  87161. + if (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format) {
  87162. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87163. + "tiled fmt enable deinterlace.\n");
  87164. + deinterlace->enable = true;
  87165. + }
  87166. +
  87167. + if (deinterlace->enable && vdi_rate_double)
  87168. + deinterlace->field_fmt |= IPU_DEINTERLACE_RATE_EN;
  87169. +
  87170. + return 0;
  87171. +}
  87172. +
  87173. +static bool is_pp_bypass(struct mxc_vout_output *vout)
  87174. +{
  87175. + if ((IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
  87176. + (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format))
  87177. + return false;
  87178. + if ((vout->task.input.width == vout->task.output.width) &&
  87179. + (vout->task.input.height == vout->task.output.height) &&
  87180. + (vout->task.input.crop.w == vout->task.output.crop.w) &&
  87181. + (vout->task.input.crop.h == vout->task.output.crop.h) &&
  87182. + (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
  87183. + !vout->task.input.deinterlace.enable) {
  87184. + if (vout->disp_support_csc)
  87185. + return true;
  87186. + else if (!need_csc(vout->task.input.format, vout->disp_fmt))
  87187. + return true;
  87188. + /*
  87189. + * input crop show to full output which can show based on
  87190. + * xres_virtual/yres_virtual
  87191. + */
  87192. + } else if ((vout->task.input.crop.w == vout->task.output.crop.w) &&
  87193. + (vout->task.output.crop.w == vout->task.output.width) &&
  87194. + (vout->task.input.crop.h == vout->task.output.crop.h) &&
  87195. + (vout->task.output.crop.h ==
  87196. + vout->task.output.height) &&
  87197. + (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
  87198. + !vout->task.input.deinterlace.enable) {
  87199. + if (vout->disp_support_csc)
  87200. + return true;
  87201. + else if (!need_csc(vout->task.input.format, vout->disp_fmt))
  87202. + return true;
  87203. + }
  87204. + return false;
  87205. +}
  87206. +
  87207. +static void setup_buf_timer(struct mxc_vout_output *vout,
  87208. + struct videobuf_buffer *vb)
  87209. +{
  87210. + ktime_t expiry_time, now;
  87211. +
  87212. + /* if timestamp is 0, then default to 30fps */
  87213. + if ((vb->ts.tv_sec == 0) && (vb->ts.tv_usec == 0))
  87214. + expiry_time = ktime_add_ns(vout->start_ktime,
  87215. + NSEC_PER_FRAME_30FPS * vout->frame_count);
  87216. + else
  87217. + expiry_time = timeval_to_ktime(vb->ts);
  87218. +
  87219. + now = hrtimer_cb_get_time(&vout->timer);
  87220. + if ((now.tv64 > expiry_time.tv64)) {
  87221. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87222. + "warning: timer timeout already expired.\n");
  87223. + expiry_time = now;
  87224. + }
  87225. +
  87226. + hrtimer_start(&vout->timer, expiry_time, HRTIMER_MODE_ABS);
  87227. +
  87228. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "timer handler next "
  87229. + "schedule: %lldnsecs\n", expiry_time.tv64);
  87230. +}
  87231. +
  87232. +static int show_buf(struct mxc_vout_output *vout, int idx,
  87233. + struct ipu_pos *ipos)
  87234. +{
  87235. + struct fb_info *fbi = vout->fbi;
  87236. + struct fb_var_screeninfo var;
  87237. + int ret;
  87238. + u32 fb_base = 0;
  87239. +
  87240. + memcpy(&var, &fbi->var, sizeof(var));
  87241. +
  87242. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
  87243. + /*
  87244. + * crack fb base
  87245. + * NOTE: should not do other fb operation during v4l2
  87246. + */
  87247. + console_lock();
  87248. + fb_base = fbi->fix.smem_start;
  87249. + fbi->fix.smem_start = vout->task.output.paddr;
  87250. + fbi->var.yoffset = ipos->y + 1;
  87251. + var.xoffset = ipos->x;
  87252. + var.yoffset = ipos->y;
  87253. + var.vmode |= FB_VMODE_YWRAP;
  87254. + ret = fb_pan_display(fbi, &var);
  87255. + fbi->fix.smem_start = fb_base;
  87256. + console_unlock();
  87257. + } else {
  87258. + console_lock();
  87259. + var.yoffset = idx * fbi->var.yres;
  87260. + var.vmode &= ~FB_VMODE_YWRAP;
  87261. + ret = fb_pan_display(fbi, &var);
  87262. + console_unlock();
  87263. + }
  87264. +
  87265. + return ret;
  87266. +}
  87267. +
  87268. +static void disp_work_func(struct work_struct *work)
  87269. +{
  87270. + struct mxc_vout_output *vout =
  87271. + container_of(work, struct mxc_vout_output, disp_work);
  87272. + struct videobuf_queue *q = &vout->vbq;
  87273. + struct videobuf_buffer *vb, *vb_next = NULL;
  87274. + unsigned long flags = 0;
  87275. + struct ipu_pos ipos;
  87276. + int ret = 0;
  87277. + u32 in_fmt = 0;
  87278. + u32 vdi_cnt = 0;
  87279. + u32 vdi_frame;
  87280. + u32 index = 0;
  87281. + u32 ocrop_h = 0;
  87282. + u32 o_height = 0;
  87283. + u32 tiled_interlaced = 0;
  87284. + bool tiled_fmt = false;
  87285. +
  87286. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work begin one frame\n");
  87287. +
  87288. + spin_lock_irqsave(q->irqlock, flags);
  87289. +
  87290. + if (list_empty(&vout->active_list)) {
  87291. + v4l2_warn(vout->vfd->v4l2_dev,
  87292. + "no entry in active_list, should not be here\n");
  87293. + spin_unlock_irqrestore(q->irqlock, flags);
  87294. + return;
  87295. + }
  87296. +
  87297. + vb = list_first_entry(&vout->active_list,
  87298. + struct videobuf_buffer, queue);
  87299. + ret = set_field_fmt(vout, vb->field);
  87300. + if (ret < 0) {
  87301. + spin_unlock_irqrestore(q->irqlock, flags);
  87302. + return;
  87303. + }
  87304. + if (deinterlace_3_field(vout)) {
  87305. + if (list_is_singular(&vout->active_list)) {
  87306. + if (list_empty(&vout->queue_list)) {
  87307. + vout->timer_stop = true;
  87308. + spin_unlock_irqrestore(q->irqlock, flags);
  87309. + v4l2_warn(vout->vfd->v4l2_dev,
  87310. + "no enough entry for 3 fields "
  87311. + "deinterlacer\n");
  87312. + return;
  87313. + }
  87314. +
  87315. + /*
  87316. + * We need to use the next vb even if it is
  87317. + * not on the active list.
  87318. + */
  87319. + vb_next = list_first_entry(&vout->queue_list,
  87320. + struct videobuf_buffer, queue);
  87321. + } else
  87322. + vb_next = list_first_entry(vout->active_list.next,
  87323. + struct videobuf_buffer, queue);
  87324. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87325. + "cur field_fmt:%d, next field_fmt:%d.\n",
  87326. + vb->field, vb_next->field);
  87327. + /* repeat the last field during field format changing */
  87328. + if ((vb->field != vb_next->field) &&
  87329. + (vb_next->field != V4L2_FIELD_NONE))
  87330. + vb_next = vb;
  87331. + }
  87332. +
  87333. + spin_unlock_irqrestore(q->irqlock, flags);
  87334. +
  87335. +vdi_frame_rate_double:
  87336. + mutex_lock(&vout->task_lock);
  87337. +
  87338. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87339. + "v4l2 frame_cnt:%ld, vb_field:%d, fmt:%d\n",
  87340. + vout->frame_count, vb->field,
  87341. + vout->task.input.deinterlace.field_fmt);
  87342. + if (vb->memory == V4L2_MEMORY_USERPTR)
  87343. + vout->task.input.paddr = vb->baddr;
  87344. + else
  87345. + vout->task.input.paddr = videobuf_to_dma_contig(vb);
  87346. +
  87347. + if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
  87348. + index = vout->vdi_frame_cnt % FB_BUFS;
  87349. + else
  87350. + index = vout->frame_count % FB_BUFS;
  87351. + if (vout->linear_bypass_pp) {
  87352. + vout->task.output.paddr = vout->task.input.paddr;
  87353. + ipos.x = vout->task.input.crop.pos.x;
  87354. + ipos.y = vout->task.input.crop.pos.y;
  87355. + } else {
  87356. + if (deinterlace_3_field(vout)) {
  87357. + if (vb->memory == V4L2_MEMORY_USERPTR)
  87358. + vout->task.input.paddr_n = vb_next->baddr;
  87359. + else
  87360. + vout->task.input.paddr_n =
  87361. + videobuf_to_dma_contig(vb_next);
  87362. + }
  87363. + vout->task.output.paddr = vout->disp_bufs[index];
  87364. + if (vout->vdoa_1080p) {
  87365. + o_height = vout->task.output.height;
  87366. + ocrop_h = vout->task.output.crop.h;
  87367. + vout->task.output.height = FRAME_HEIGHT_1080P;
  87368. + vout->task.output.crop.h = FRAME_HEIGHT_1080P;
  87369. + }
  87370. + tiled_fmt =
  87371. + (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format) ||
  87372. + (IPU_PIX_FMT_TILED_NV12F == vout->task.input.format);
  87373. + if (vout->tiled_bypass_pp) {
  87374. + ipos.x = vout->task.input.crop.pos.x;
  87375. + ipos.y = vout->task.input.crop.pos.y;
  87376. + } else if (tiled_fmt) {
  87377. + vout->vdoa_task.input.paddr = vout->task.input.paddr;
  87378. + if (deinterlace_3_field(vout))
  87379. + vout->vdoa_task.input.paddr_n =
  87380. + vout->task.input.paddr_n;
  87381. + vout->vdoa_task.output.paddr = vout->vdoa_work.paddr;
  87382. + ret = ipu_queue_task(&vout->vdoa_task);
  87383. + if (ret < 0) {
  87384. + mutex_unlock(&vout->task_lock);
  87385. + goto err;
  87386. + }
  87387. + vout->task.input.paddr = vout->vdoa_task.output.paddr;
  87388. + in_fmt = vout->task.input.format;
  87389. + vout->task.input.format = vout->vdoa_task.output.format;
  87390. + if (vout->task.input.deinterlace.enable) {
  87391. + tiled_interlaced = 1;
  87392. + vout->task.input.deinterlace.enable = 0;
  87393. + }
  87394. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87395. + "tiled queue task\n");
  87396. + }
  87397. + ret = ipu_queue_task(&vout->task);
  87398. + if ((!vout->tiled_bypass_pp) && tiled_fmt)
  87399. + vout->task.input.format = in_fmt;
  87400. + if (tiled_interlaced)
  87401. + vout->task.input.deinterlace.enable = 1;
  87402. + if (ret < 0) {
  87403. + mutex_unlock(&vout->task_lock);
  87404. + goto err;
  87405. + }
  87406. + if (vout->vdoa_1080p) {
  87407. + vout->task.output.crop.h = ocrop_h;
  87408. + vout->task.output.height = o_height;
  87409. + }
  87410. + }
  87411. +
  87412. + mutex_unlock(&vout->task_lock);
  87413. +
  87414. + ret = show_buf(vout, index, &ipos);
  87415. + if (ret < 0)
  87416. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87417. + "show buf with ret %d\n", ret);
  87418. +
  87419. + if (vout->task.input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN) {
  87420. + vdi_frame = vout->task.input.deinterlace.field_fmt
  87421. + & IPU_DEINTERLACE_RATE_FRAME1;
  87422. + if (vdi_frame)
  87423. + vout->task.input.deinterlace.field_fmt &=
  87424. + ~IPU_DEINTERLACE_RATE_FRAME1;
  87425. + else
  87426. + vout->task.input.deinterlace.field_fmt |=
  87427. + IPU_DEINTERLACE_RATE_FRAME1;
  87428. + vout->vdi_frame_cnt++;
  87429. + vdi_cnt++;
  87430. + if (vdi_cnt < IPU_DEINTERLACE_MAX_FRAME)
  87431. + goto vdi_frame_rate_double;
  87432. + }
  87433. + spin_lock_irqsave(q->irqlock, flags);
  87434. +
  87435. + list_del(&vb->queue);
  87436. +
  87437. + /*
  87438. + * The videobuf before the last one has been shown. Set
  87439. + * VIDEOBUF_DONE state here to avoid tearing issue in ic bypass
  87440. + * case, which makes sure a buffer being shown will not be
  87441. + * dequeued to be overwritten. It also brings side-effect that
  87442. + * the last 2 buffers can not be dequeued correctly, apps need
  87443. + * to take care of it.
  87444. + */
  87445. + if (vout->pre2_vb) {
  87446. + vout->pre2_vb->state = VIDEOBUF_DONE;
  87447. + wake_up_interruptible(&vout->pre2_vb->done);
  87448. + vout->pre2_vb = NULL;
  87449. + }
  87450. +
  87451. + if (vout->linear_bypass_pp) {
  87452. + vout->pre2_vb = vout->pre1_vb;
  87453. + vout->pre1_vb = vb;
  87454. + } else {
  87455. + if (vout->pre1_vb) {
  87456. + vout->pre1_vb->state = VIDEOBUF_DONE;
  87457. + wake_up_interruptible(&vout->pre1_vb->done);
  87458. + vout->pre1_vb = NULL;
  87459. + }
  87460. + vb->state = VIDEOBUF_DONE;
  87461. + wake_up_interruptible(&vb->done);
  87462. + }
  87463. +
  87464. + vout->frame_count++;
  87465. +
  87466. + /* pick next queue buf to setup timer */
  87467. + if (list_empty(&vout->queue_list))
  87468. + vout->timer_stop = true;
  87469. + else {
  87470. + vb = list_first_entry(&vout->queue_list,
  87471. + struct videobuf_buffer, queue);
  87472. + setup_buf_timer(vout, vb);
  87473. + }
  87474. +
  87475. + spin_unlock_irqrestore(q->irqlock, flags);
  87476. +
  87477. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work finish one frame\n");
  87478. +
  87479. + return;
  87480. +err:
  87481. + v4l2_err(vout->vfd->v4l2_dev, "display work fail ret = %d\n", ret);
  87482. + vout->timer_stop = true;
  87483. + vb->state = VIDEOBUF_ERROR;
  87484. + return;
  87485. +}
  87486. +
  87487. +static enum hrtimer_restart mxc_vout_timer_handler(struct hrtimer *timer)
  87488. +{
  87489. + struct mxc_vout_output *vout = container_of(timer,
  87490. + struct mxc_vout_output,
  87491. + timer);
  87492. + struct videobuf_queue *q = &vout->vbq;
  87493. + struct videobuf_buffer *vb;
  87494. + unsigned long flags = 0;
  87495. +
  87496. + spin_lock_irqsave(q->irqlock, flags);
  87497. +
  87498. + /*
  87499. + * put first queued entry into active, if previous entry did not
  87500. + * finish, setup current entry's timer again.
  87501. + */
  87502. + if (list_empty(&vout->queue_list)) {
  87503. + spin_unlock_irqrestore(q->irqlock, flags);
  87504. + return HRTIMER_NORESTART;
  87505. + }
  87506. +
  87507. + /* move videobuf from queued list to active list */
  87508. + vb = list_first_entry(&vout->queue_list,
  87509. + struct videobuf_buffer, queue);
  87510. + list_del(&vb->queue);
  87511. + list_add_tail(&vb->queue, &vout->active_list);
  87512. +
  87513. + if (queue_work(vout->v4l_wq, &vout->disp_work) == 0) {
  87514. + v4l2_warn(vout->vfd->v4l2_dev,
  87515. + "disp work was in queue already, queue buf again next time\n");
  87516. + list_del(&vb->queue);
  87517. + list_add(&vb->queue, &vout->queue_list);
  87518. + spin_unlock_irqrestore(q->irqlock, flags);
  87519. + return HRTIMER_NORESTART;
  87520. + }
  87521. +
  87522. + vb->state = VIDEOBUF_ACTIVE;
  87523. +
  87524. + spin_unlock_irqrestore(q->irqlock, flags);
  87525. +
  87526. + return HRTIMER_NORESTART;
  87527. +}
  87528. +
  87529. +/* Video buffer call backs */
  87530. +
  87531. +/*
  87532. + * Buffer setup function is called by videobuf layer when REQBUF ioctl is
  87533. + * called. This is used to setup buffers and return size and count of
  87534. + * buffers allocated. After the call to this buffer, videobuf layer will
  87535. + * setup buffer queue depending on the size and count of buffers
  87536. + */
  87537. +static int mxc_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
  87538. + unsigned int *size)
  87539. +{
  87540. + struct mxc_vout_output *vout = q->priv_data;
  87541. + unsigned int frame_size;
  87542. +
  87543. + if (!vout)
  87544. + return -EINVAL;
  87545. +
  87546. + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
  87547. + return -EINVAL;
  87548. +
  87549. + frame_size = get_frame_size(vout);
  87550. + *size = PAGE_ALIGN(frame_size);
  87551. +
  87552. + return 0;
  87553. +}
  87554. +
  87555. +/*
  87556. + * This function will be called when VIDIOC_QBUF ioctl is called.
  87557. + * It prepare buffers before give out for the display. This function
  87558. + * converts user space virtual address into physical address if userptr memory
  87559. + * exchange mechanism is used.
  87560. + */
  87561. +static int mxc_vout_buffer_prepare(struct videobuf_queue *q,
  87562. + struct videobuf_buffer *vb,
  87563. + enum v4l2_field field)
  87564. +{
  87565. + vb->state = VIDEOBUF_PREPARED;
  87566. + return 0;
  87567. +}
  87568. +
  87569. +/*
  87570. + * Buffer queue funtion will be called from the videobuf layer when _QBUF
  87571. + * ioctl is called. It is used to enqueue buffer, which is ready to be
  87572. + * displayed.
  87573. + * This function is protected by q->irqlock.
  87574. + */
  87575. +static void mxc_vout_buffer_queue(struct videobuf_queue *q,
  87576. + struct videobuf_buffer *vb)
  87577. +{
  87578. + struct mxc_vout_output *vout = q->priv_data;
  87579. + struct videobuf_buffer *active_vb;
  87580. +
  87581. + list_add_tail(&vb->queue, &vout->queue_list);
  87582. + vb->state = VIDEOBUF_QUEUED;
  87583. +
  87584. + if (vout->timer_stop) {
  87585. + if (deinterlace_3_field(vout) &&
  87586. + !list_empty(&vout->active_list)) {
  87587. + active_vb = list_first_entry(&vout->active_list,
  87588. + struct videobuf_buffer, queue);
  87589. + setup_buf_timer(vout, active_vb);
  87590. + } else {
  87591. + setup_buf_timer(vout, vb);
  87592. + }
  87593. + vout->timer_stop = false;
  87594. + }
  87595. +}
  87596. +
  87597. +/*
  87598. + * Buffer release function is called from videobuf layer to release buffer
  87599. + * which are already allocated
  87600. + */
  87601. +static void mxc_vout_buffer_release(struct videobuf_queue *q,
  87602. + struct videobuf_buffer *vb)
  87603. +{
  87604. + vb->state = VIDEOBUF_NEEDS_INIT;
  87605. +}
  87606. +
  87607. +static int mxc_vout_mmap(struct file *file, struct vm_area_struct *vma)
  87608. +{
  87609. + int ret;
  87610. + struct mxc_vout_output *vout = file->private_data;
  87611. +
  87612. + if (!vout)
  87613. + return -ENODEV;
  87614. +
  87615. + ret = videobuf_mmap_mapper(&vout->vbq, vma);
  87616. + if (ret < 0)
  87617. + v4l2_err(vout->vfd->v4l2_dev,
  87618. + "offset invalid [offset=0x%lx]\n",
  87619. + (vma->vm_pgoff << PAGE_SHIFT));
  87620. +
  87621. + return ret;
  87622. +}
  87623. +
  87624. +static int mxc_vout_release(struct file *file)
  87625. +{
  87626. + unsigned int ret = 0;
  87627. + struct videobuf_queue *q;
  87628. + struct mxc_vout_output *vout = file->private_data;
  87629. +
  87630. + if (!vout)
  87631. + return 0;
  87632. +
  87633. + if (--vout->open_cnt == 0) {
  87634. + q = &vout->vbq;
  87635. + if (q->streaming)
  87636. + mxc_vidioc_streamoff(file, vout, vout->type);
  87637. + else {
  87638. + release_disp_output(vout);
  87639. + videobuf_queue_cancel(q);
  87640. + }
  87641. + destroy_workqueue(vout->v4l_wq);
  87642. + ret = videobuf_mmap_free(q);
  87643. + }
  87644. +
  87645. + return ret;
  87646. +}
  87647. +
  87648. +static int mxc_vout_open(struct file *file)
  87649. +{
  87650. + struct mxc_vout_output *vout = NULL;
  87651. + int ret = 0;
  87652. +
  87653. + vout = video_drvdata(file);
  87654. +
  87655. + if (vout == NULL)
  87656. + return -ENODEV;
  87657. +
  87658. + if (vout->open_cnt++ == 0) {
  87659. + vout->ctrl_rotate = 0;
  87660. + vout->ctrl_vflip = 0;
  87661. + vout->ctrl_hflip = 0;
  87662. + update_display_setting();
  87663. + ret = update_setting_from_fbi(vout, vout->fbi);
  87664. + if (ret < 0)
  87665. + goto err;
  87666. +
  87667. + vout->v4l_wq = create_singlethread_workqueue("v4l2q");
  87668. + if (!vout->v4l_wq) {
  87669. + v4l2_err(vout->vfd->v4l2_dev,
  87670. + "Could not create work queue\n");
  87671. + ret = -ENOMEM;
  87672. + goto err;
  87673. + }
  87674. +
  87675. + INIT_WORK(&vout->disp_work, disp_work_func);
  87676. +
  87677. + INIT_LIST_HEAD(&vout->queue_list);
  87678. + INIT_LIST_HEAD(&vout->active_list);
  87679. +
  87680. + vout->fmt_init = false;
  87681. + vout->frame_count = 0;
  87682. + vout->vdi_frame_cnt = 0;
  87683. +
  87684. + vout->win_pos.x = 0;
  87685. + vout->win_pos.y = 0;
  87686. + vout->release = true;
  87687. + }
  87688. +
  87689. + file->private_data = vout;
  87690. +
  87691. +err:
  87692. + return ret;
  87693. +}
  87694. +
  87695. +/*
  87696. + * V4L2 ioctls
  87697. + */
  87698. +static int mxc_vidioc_querycap(struct file *file, void *fh,
  87699. + struct v4l2_capability *cap)
  87700. +{
  87701. + struct mxc_vout_output *vout = fh;
  87702. +
  87703. + strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
  87704. + strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
  87705. + cap->bus_info[0] = '\0';
  87706. + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
  87707. +
  87708. + return 0;
  87709. +}
  87710. +
  87711. +static int mxc_vidioc_enum_fmt_vid_out(struct file *file, void *fh,
  87712. + struct v4l2_fmtdesc *fmt)
  87713. +{
  87714. + if (fmt->index >= NUM_MXC_VOUT_FORMATS)
  87715. + return -EINVAL;
  87716. +
  87717. + strlcpy(fmt->description, mxc_formats[fmt->index].description,
  87718. + sizeof(fmt->description));
  87719. + fmt->pixelformat = mxc_formats[fmt->index].pixelformat;
  87720. +
  87721. + return 0;
  87722. +}
  87723. +
  87724. +static int mxc_vidioc_g_fmt_vid_out(struct file *file, void *fh,
  87725. + struct v4l2_format *f)
  87726. +{
  87727. + struct mxc_vout_output *vout = fh;
  87728. + struct v4l2_rect rect;
  87729. +
  87730. + f->fmt.pix.width = vout->task.input.width;
  87731. + f->fmt.pix.height = vout->task.input.height;
  87732. + f->fmt.pix.pixelformat = vout->task.input.format;
  87733. + f->fmt.pix.sizeimage = get_frame_size(vout);
  87734. +
  87735. + if (f->fmt.pix.priv) {
  87736. + rect.left = vout->task.input.crop.pos.x;
  87737. + rect.top = vout->task.input.crop.pos.y;
  87738. + rect.width = vout->task.input.crop.w;
  87739. + rect.height = vout->task.input.crop.h;
  87740. + if (copy_to_user((void __user *)f->fmt.pix.priv,
  87741. + &rect, sizeof(rect)))
  87742. + return -EFAULT;
  87743. + }
  87744. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87745. + "frame_size:0x%x, pix_fmt:0x%x\n",
  87746. + f->fmt.pix.sizeimage,
  87747. + vout->task.input.format);
  87748. +
  87749. + return 0;
  87750. +}
  87751. +
  87752. +static inline int ipu_try_task(struct mxc_vout_output *vout)
  87753. +{
  87754. + int ret;
  87755. + struct ipu_task *task = &vout->task;
  87756. +
  87757. +again:
  87758. + ret = ipu_check_task(task);
  87759. + if (ret != IPU_CHECK_OK) {
  87760. + if (ret > IPU_CHECK_ERR_MIN) {
  87761. + if (ret == IPU_CHECK_ERR_SPLIT_INPUTW_OVER ||
  87762. + ret == IPU_CHECK_ERR_W_DOWNSIZE_OVER) {
  87763. + task->input.crop.w -= 8;
  87764. + goto again;
  87765. + }
  87766. + if (ret == IPU_CHECK_ERR_SPLIT_INPUTH_OVER ||
  87767. + ret == IPU_CHECK_ERR_H_DOWNSIZE_OVER) {
  87768. + task->input.crop.h -= 8;
  87769. + goto again;
  87770. + }
  87771. + if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
  87772. + if (vout->disp_support_windows) {
  87773. + task->output.width -= 8;
  87774. + task->output.crop.w =
  87775. + task->output.width;
  87776. + } else
  87777. + task->output.crop.w -= 8;
  87778. + goto again;
  87779. + }
  87780. + if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
  87781. + if (vout->disp_support_windows) {
  87782. + task->output.height -= 8;
  87783. + task->output.crop.h =
  87784. + task->output.height;
  87785. + } else
  87786. + task->output.crop.h -= 8;
  87787. + goto again;
  87788. + }
  87789. + ret = -EINVAL;
  87790. + }
  87791. + } else
  87792. + ret = 0;
  87793. +
  87794. + return ret;
  87795. +}
  87796. +
  87797. +static inline int vdoaipu_try_task(struct mxc_vout_output *vout)
  87798. +{
  87799. + int ret;
  87800. + int is_1080p_stream;
  87801. + size_t size;
  87802. + struct ipu_task *ipu_task = &vout->task;
  87803. + struct ipu_crop *icrop = &ipu_task->input.crop;
  87804. + struct ipu_task *vdoa_task = &vout->vdoa_task;
  87805. + u32 deinterlace = 0;
  87806. + u32 in_fmt;
  87807. +
  87808. + if (vout->task.input.deinterlace.enable)
  87809. + deinterlace = 1;
  87810. +
  87811. + memset(vdoa_task, 0, sizeof(*vdoa_task));
  87812. + vdoa_task->output.format = IPU_PIX_FMT_NV12;
  87813. + memcpy(&vdoa_task->input, &ipu_task->input,
  87814. + sizeof(ipu_task->input));
  87815. + if ((icrop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  87816. + (icrop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
  87817. + vdoa_task->input.crop.w =
  87818. + ALIGN(icrop->w, IPU_PIX_FMT_TILED_NV12_MBALIGN);
  87819. + vdoa_task->input.crop.h =
  87820. + ALIGN(icrop->h, IPU_PIX_FMT_TILED_NV12_MBALIGN);
  87821. + }
  87822. + vdoa_task->output.width = vdoa_task->input.crop.w;
  87823. + vdoa_task->output.height = vdoa_task->input.crop.h;
  87824. + vdoa_task->output.crop.w = vdoa_task->input.crop.w;
  87825. + vdoa_task->output.crop.h = vdoa_task->input.crop.h;
  87826. +
  87827. + size = PAGE_ALIGN(vdoa_task->input.crop.w *
  87828. + vdoa_task->input.crop.h *
  87829. + fmt_to_bpp(vdoa_task->output.format)/8);
  87830. + if (size > vout->vdoa_work.size) {
  87831. + if (vout->vdoa_work.vaddr)
  87832. + free_dma_buf(vout, &vout->vdoa_work);
  87833. + vout->vdoa_work.size = size;
  87834. + ret = alloc_dma_buf(vout, &vout->vdoa_work);
  87835. + if (ret < 0)
  87836. + return ret;
  87837. + }
  87838. + ret = ipu_check_task(vdoa_task);
  87839. + if (ret != IPU_CHECK_OK)
  87840. + return -EINVAL;
  87841. +
  87842. + is_1080p_stream = CHECK_TILED_1080P_STREAM(vout);
  87843. + if (is_1080p_stream)
  87844. + ipu_task->input.crop.h = VALID_HEIGHT_1080P;
  87845. + in_fmt = ipu_task->input.format;
  87846. + ipu_task->input.format = vdoa_task->output.format;
  87847. + ipu_task->input.height = vdoa_task->output.height;
  87848. + ipu_task->input.width = vdoa_task->output.width;
  87849. + if (deinterlace)
  87850. + ipu_task->input.deinterlace.enable = 0;
  87851. + ret = ipu_try_task(vout);
  87852. + if (deinterlace)
  87853. + ipu_task->input.deinterlace.enable = 1;
  87854. + ipu_task->input.format = in_fmt;
  87855. +
  87856. + return ret;
  87857. +}
  87858. +
  87859. +static int mxc_vout_try_task(struct mxc_vout_output *vout)
  87860. +{
  87861. + int ret = 0;
  87862. + struct ipu_output *output = &vout->task.output;
  87863. + struct ipu_input *input = &vout->task.input;
  87864. + struct ipu_crop *crop = &input->crop;
  87865. + u32 o_height = 0;
  87866. + u32 ocrop_h = 0;
  87867. + bool tiled_fmt = false;
  87868. + bool tiled_need_pp = false;
  87869. +
  87870. + vout->vdoa_1080p = CHECK_TILED_1080P_DISPLAY(vout);
  87871. + if (vout->vdoa_1080p) {
  87872. + input->crop.h = FRAME_HEIGHT_1080P;
  87873. + o_height = output->height;
  87874. + ocrop_h = output->crop.h;
  87875. + output->height = FRAME_HEIGHT_1080P;
  87876. + output->crop.h = FRAME_HEIGHT_1080P;
  87877. + }
  87878. +
  87879. + if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
  87880. + (IPU_PIX_FMT_TILED_NV12F == input->format)) {
  87881. + if ((input->width % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  87882. + (input->height % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  87883. + (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  87884. + (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN)) {
  87885. + v4l2_err(vout->vfd->v4l2_dev,
  87886. + "ERR: tiled fmt needs 16 pixel align.\n");
  87887. + return -EINVAL;
  87888. + }
  87889. + if ((crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN) ||
  87890. + (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  87891. + tiled_need_pp = true;
  87892. + } else {
  87893. + crop->w -= crop->w % 8;
  87894. + crop->h -= crop->h % 8;
  87895. + }
  87896. + /* assume task.output already set by S_CROP */
  87897. + vout->linear_bypass_pp = is_pp_bypass(vout);
  87898. + if (vout->linear_bypass_pp) {
  87899. + v4l2_info(vout->vfd->v4l2_dev, "Bypass IC.\n");
  87900. + output->format = input->format;
  87901. + } else {
  87902. + /* if need CSC, choose IPU-DP or IPU_IC do it */
  87903. + if (vout->disp_support_csc) {
  87904. + if (colorspaceofpixel(input->format) == YUV_CS)
  87905. + output->format = IPU_PIX_FMT_UYVY;
  87906. + else
  87907. + output->format = IPU_PIX_FMT_RGB565;
  87908. + } else {
  87909. + if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
  87910. + output->format = IPU_PIX_FMT_UYVY;
  87911. + else
  87912. + output->format = IPU_PIX_FMT_RGB565;
  87913. + }
  87914. +
  87915. + vout->tiled_bypass_pp = false;
  87916. + if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
  87917. + (IPU_PIX_FMT_TILED_NV12F == input->format)) {
  87918. + /* check resize/rotate/flip, or csc task */
  87919. + if (!(tiled_need_pp ||
  87920. + (IPU_ROTATE_NONE != output->rotate) ||
  87921. + (input->crop.w != output->crop.w) ||
  87922. + (input->crop.h != output->crop.h) ||
  87923. + (!vout->disp_support_csc &&
  87924. + (colorspaceofpixel(vout->disp_fmt) == RGB_CS)))
  87925. + ) {
  87926. + /* IC bypass */
  87927. + output->format = IPU_PIX_FMT_NV12;
  87928. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87929. + "tiled bypass pp\n");
  87930. + vout->tiled_bypass_pp = true;
  87931. + }
  87932. + tiled_fmt = true;
  87933. + }
  87934. +
  87935. + if ((!vout->tiled_bypass_pp) && tiled_fmt)
  87936. + ret = vdoaipu_try_task(vout);
  87937. + else
  87938. + ret = ipu_try_task(vout);
  87939. + }
  87940. +
  87941. + if (vout->vdoa_1080p) {
  87942. + output->height = o_height;
  87943. + output->crop.h = ocrop_h;
  87944. + }
  87945. +
  87946. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  87947. + "icrop.w:%u, icrop.h:%u, iw:%u, ih:%u,"
  87948. + "ocrop.w:%u, ocrop.h:%u, ow:%u, oh:%u\n",
  87949. + input->crop.w, input->crop.h,
  87950. + input->width, input->height,
  87951. + output->crop.w, output->crop.h,
  87952. + output->width, output->height);
  87953. + return ret;
  87954. +}
  87955. +
  87956. +static int mxc_vout_try_format(struct mxc_vout_output *vout,
  87957. + struct v4l2_format *f)
  87958. +{
  87959. + int ret = 0;
  87960. + struct v4l2_rect rect;
  87961. +
  87962. + if ((f->fmt.pix.field != V4L2_FIELD_NONE) &&
  87963. + (IPU_PIX_FMT_TILED_NV12 == vout->task.input.format)) {
  87964. + v4l2_err(vout->vfd->v4l2_dev,
  87965. + "progressive tiled fmt should used V4L2_FIELD_NONE!\n");
  87966. + return -EINVAL;
  87967. + }
  87968. +
  87969. + if (f->fmt.pix.priv && copy_from_user(&rect,
  87970. + (void __user *)f->fmt.pix.priv, sizeof(rect)))
  87971. + return -EFAULT;
  87972. +
  87973. + vout->task.input.width = f->fmt.pix.width;
  87974. + vout->task.input.height = f->fmt.pix.height;
  87975. + vout->task.input.format = f->fmt.pix.pixelformat;
  87976. +
  87977. + ret = set_field_fmt(vout, f->fmt.pix.field);
  87978. + if (ret < 0)
  87979. + return ret;
  87980. +
  87981. + if (f->fmt.pix.priv) {
  87982. + vout->task.input.crop.pos.x = rect.left;
  87983. + vout->task.input.crop.pos.y = rect.top;
  87984. + vout->task.input.crop.w = rect.width;
  87985. + vout->task.input.crop.h = rect.height;
  87986. + } else {
  87987. + vout->task.input.crop.pos.x = 0;
  87988. + vout->task.input.crop.pos.y = 0;
  87989. + vout->task.input.crop.w = f->fmt.pix.width;
  87990. + vout->task.input.crop.h = f->fmt.pix.height;
  87991. + }
  87992. + memcpy(&vout->in_rect, &vout->task.input.crop, sizeof(vout->in_rect));
  87993. +
  87994. + ret = mxc_vout_try_task(vout);
  87995. + if (!ret) {
  87996. + if (f->fmt.pix.priv) {
  87997. + rect.width = vout->task.input.crop.w;
  87998. + rect.height = vout->task.input.crop.h;
  87999. + if (copy_to_user((void __user *)f->fmt.pix.priv,
  88000. + &rect, sizeof(rect)))
  88001. + ret = -EFAULT;
  88002. + } else {
  88003. + f->fmt.pix.width = vout->task.input.crop.w;
  88004. + f->fmt.pix.height = vout->task.input.crop.h;
  88005. + }
  88006. + }
  88007. +
  88008. + return ret;
  88009. +}
  88010. +
  88011. +static bool mxc_vout_need_fb_reconfig(struct mxc_vout_output *vout,
  88012. + struct mxc_vout_output *pre_vout)
  88013. +{
  88014. + if (!vout->vbq.streaming)
  88015. + return false;
  88016. +
  88017. + if (vout->tiled_bypass_pp)
  88018. + return true;
  88019. +
  88020. + if (vout->linear_bypass_pp != pre_vout->linear_bypass_pp)
  88021. + return true;
  88022. +
  88023. + /* cropped output resolution or format are changed */
  88024. + if (vout->task.output.format != pre_vout->task.output.format ||
  88025. + vout->task.output.crop.w != pre_vout->task.output.crop.w ||
  88026. + vout->task.output.crop.h != pre_vout->task.output.crop.h)
  88027. + return true;
  88028. +
  88029. + /* overlay: window position or resolution are changed */
  88030. + if (vout->disp_support_windows &&
  88031. + (vout->win_pos.x != pre_vout->win_pos.x ||
  88032. + vout->win_pos.y != pre_vout->win_pos.y ||
  88033. + vout->task.output.width != pre_vout->task.output.width ||
  88034. + vout->task.output.height != pre_vout->task.output.height))
  88035. + return true;
  88036. +
  88037. + /* background: cropped position is changed */
  88038. + if (!vout->disp_support_windows &&
  88039. + (vout->task.output.crop.pos.x !=
  88040. + pre_vout->task.output.crop.pos.x ||
  88041. + vout->task.output.crop.pos.y !=
  88042. + pre_vout->task.output.crop.pos.y))
  88043. + return true;
  88044. +
  88045. + return false;
  88046. +}
  88047. +
  88048. +static int mxc_vidioc_s_fmt_vid_out(struct file *file, void *fh,
  88049. + struct v4l2_format *f)
  88050. +{
  88051. + struct mxc_vout_output *vout = fh;
  88052. + int ret = 0;
  88053. +
  88054. + if (vout->vbq.streaming)
  88055. + return -EBUSY;
  88056. +
  88057. + mutex_lock(&vout->task_lock);
  88058. + ret = mxc_vout_try_format(vout, f);
  88059. + if (ret >= 0)
  88060. + vout->fmt_init = true;
  88061. + mutex_unlock(&vout->task_lock);
  88062. +
  88063. + return ret;
  88064. +}
  88065. +
  88066. +static int mxc_vidioc_cropcap(struct file *file, void *fh,
  88067. + struct v4l2_cropcap *cropcap)
  88068. +{
  88069. + struct mxc_vout_output *vout = fh;
  88070. +
  88071. + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  88072. + return -EINVAL;
  88073. +
  88074. + cropcap->bounds = vout->crop_bounds;
  88075. + cropcap->defrect = vout->crop_bounds;
  88076. +
  88077. + return 0;
  88078. +}
  88079. +
  88080. +static int mxc_vidioc_g_crop(struct file *file, void *fh,
  88081. + struct v4l2_crop *crop)
  88082. +{
  88083. + struct mxc_vout_output *vout = fh;
  88084. +
  88085. + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  88086. + return -EINVAL;
  88087. +
  88088. + if (vout->disp_support_windows) {
  88089. + crop->c.left = vout->win_pos.x;
  88090. + crop->c.top = vout->win_pos.y;
  88091. + crop->c.width = vout->task.output.width;
  88092. + crop->c.height = vout->task.output.height;
  88093. + } else {
  88094. + if (vout->task.output.crop.w && vout->task.output.crop.h) {
  88095. + crop->c.left = vout->task.output.crop.pos.x;
  88096. + crop->c.top = vout->task.output.crop.pos.y;
  88097. + crop->c.width = vout->task.output.crop.w;
  88098. + crop->c.height = vout->task.output.crop.h;
  88099. + } else {
  88100. + crop->c.left = 0;
  88101. + crop->c.top = 0;
  88102. + crop->c.width = vout->task.output.width;
  88103. + crop->c.height = vout->task.output.height;
  88104. + }
  88105. + }
  88106. +
  88107. + return 0;
  88108. +}
  88109. +
  88110. +static int mxc_vidioc_s_crop(struct file *file, void *fh,
  88111. + const struct v4l2_crop *crop)
  88112. +{
  88113. + struct mxc_vout_output *vout = fh, *pre_vout;
  88114. + struct v4l2_rect *b = &vout->crop_bounds;
  88115. + struct v4l2_crop fix_up_crop;
  88116. + int ret = 0;
  88117. +
  88118. + memcpy(&fix_up_crop, crop, sizeof(*crop));
  88119. +
  88120. + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  88121. + return -EINVAL;
  88122. +
  88123. + if (crop->c.width < 0 || crop->c.height < 0)
  88124. + return -EINVAL;
  88125. +
  88126. + if (crop->c.width == 0)
  88127. + fix_up_crop.c.width = b->width - b->left;
  88128. + if (crop->c.height == 0)
  88129. + fix_up_crop.c.height = b->height - b->top;
  88130. +
  88131. + if (crop->c.top < b->top)
  88132. + fix_up_crop.c.top = b->top;
  88133. + if (crop->c.top >= b->top + b->height)
  88134. + fix_up_crop.c.top = b->top + b->height - 1;
  88135. + if (crop->c.height > b->top - crop->c.top + b->height)
  88136. + fix_up_crop.c.height =
  88137. + b->top - fix_up_crop.c.top + b->height;
  88138. +
  88139. + if (crop->c.left < b->left)
  88140. + fix_up_crop.c.left = b->left;
  88141. + if (crop->c.left >= b->left + b->width)
  88142. + fix_up_crop.c.left = b->left + b->width - 1;
  88143. + if (crop->c.width > b->left - crop->c.left + b->width)
  88144. + fix_up_crop.c.width =
  88145. + b->left - fix_up_crop.c.left + b->width;
  88146. +
  88147. + /* stride line limitation */
  88148. + fix_up_crop.c.height -= fix_up_crop.c.height % 8;
  88149. + fix_up_crop.c.width -= fix_up_crop.c.width % 8;
  88150. + if ((fix_up_crop.c.width <= 0) || (fix_up_crop.c.height <= 0) ||
  88151. + ((fix_up_crop.c.left + fix_up_crop.c.width) >
  88152. + (b->left + b->width)) ||
  88153. + ((fix_up_crop.c.top + fix_up_crop.c.height) >
  88154. + (b->top + b->height))) {
  88155. + v4l2_err(vout->vfd->v4l2_dev, "s_crop err: %d, %d, %d, %d",
  88156. + fix_up_crop.c.left, fix_up_crop.c.top,
  88157. + fix_up_crop.c.width, fix_up_crop.c.height);
  88158. + return -EINVAL;
  88159. + }
  88160. +
  88161. + /* the same setting, return */
  88162. + if (vout->disp_support_windows) {
  88163. + if ((vout->win_pos.x == fix_up_crop.c.left) &&
  88164. + (vout->win_pos.y == fix_up_crop.c.top) &&
  88165. + (vout->task.output.crop.w == fix_up_crop.c.width) &&
  88166. + (vout->task.output.crop.h == fix_up_crop.c.height))
  88167. + return 0;
  88168. + } else {
  88169. + if ((vout->task.output.crop.pos.x == fix_up_crop.c.left) &&
  88170. + (vout->task.output.crop.pos.y == fix_up_crop.c.top) &&
  88171. + (vout->task.output.crop.w == fix_up_crop.c.width) &&
  88172. + (vout->task.output.crop.h == fix_up_crop.c.height))
  88173. + return 0;
  88174. + }
  88175. +
  88176. + pre_vout = vmalloc(sizeof(*pre_vout));
  88177. + if (!pre_vout)
  88178. + return -ENOMEM;
  88179. +
  88180. + /* wait current work finish */
  88181. + if (vout->vbq.streaming)
  88182. + flush_workqueue(vout->v4l_wq);
  88183. +
  88184. + mutex_lock(&vout->task_lock);
  88185. +
  88186. + memcpy(pre_vout, vout, sizeof(*vout));
  88187. +
  88188. + if (vout->disp_support_windows) {
  88189. + vout->task.output.crop.pos.x = 0;
  88190. + vout->task.output.crop.pos.y = 0;
  88191. + vout->win_pos.x = fix_up_crop.c.left;
  88192. + vout->win_pos.y = fix_up_crop.c.top;
  88193. + vout->task.output.width = fix_up_crop.c.width;
  88194. + vout->task.output.height = fix_up_crop.c.height;
  88195. + } else {
  88196. + vout->task.output.crop.pos.x = fix_up_crop.c.left;
  88197. + vout->task.output.crop.pos.y = fix_up_crop.c.top;
  88198. + }
  88199. +
  88200. + vout->task.output.crop.w = fix_up_crop.c.width;
  88201. + vout->task.output.crop.h = fix_up_crop.c.height;
  88202. +
  88203. + /*
  88204. + * must S_CROP before S_FMT, for fist time S_CROP, will not check
  88205. + * ipu task, it will check in S_FMT, after S_FMT, S_CROP should
  88206. + * check ipu task too.
  88207. + */
  88208. + if (vout->fmt_init) {
  88209. + memcpy(&vout->task.input.crop, &vout->in_rect,
  88210. + sizeof(vout->in_rect));
  88211. + ret = mxc_vout_try_task(vout);
  88212. + if (ret < 0) {
  88213. + v4l2_err(vout->vfd->v4l2_dev,
  88214. + "vout check task failed\n");
  88215. + memcpy(vout, pre_vout, sizeof(*vout));
  88216. + goto done;
  88217. + }
  88218. +
  88219. + if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
  88220. + ret = config_disp_output(vout);
  88221. + if (ret < 0)
  88222. + v4l2_err(vout->vfd->v4l2_dev,
  88223. + "Config display output failed\n");
  88224. + }
  88225. + }
  88226. +
  88227. +done:
  88228. + vfree(pre_vout);
  88229. + mutex_unlock(&vout->task_lock);
  88230. +
  88231. + return ret;
  88232. +}
  88233. +
  88234. +static int mxc_vidioc_queryctrl(struct file *file, void *fh,
  88235. + struct v4l2_queryctrl *ctrl)
  88236. +{
  88237. + int ret = 0;
  88238. +
  88239. + switch (ctrl->id) {
  88240. + case V4L2_CID_ROTATE:
  88241. + ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
  88242. + break;
  88243. + case V4L2_CID_VFLIP:
  88244. + ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
  88245. + break;
  88246. + case V4L2_CID_HFLIP:
  88247. + ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
  88248. + break;
  88249. + case V4L2_CID_MXC_MOTION:
  88250. + ret = v4l2_ctrl_query_fill(ctrl, 0, 2, 1, 0);
  88251. + break;
  88252. + default:
  88253. + ctrl->name[0] = '\0';
  88254. + ret = -EINVAL;
  88255. + }
  88256. + return ret;
  88257. +}
  88258. +
  88259. +static int mxc_vidioc_g_ctrl(struct file *file, void *fh,
  88260. + struct v4l2_control *ctrl)
  88261. +{
  88262. + int ret = 0;
  88263. + struct mxc_vout_output *vout = fh;
  88264. +
  88265. + switch (ctrl->id) {
  88266. + case V4L2_CID_ROTATE:
  88267. + ctrl->value = vout->ctrl_rotate;
  88268. + break;
  88269. + case V4L2_CID_VFLIP:
  88270. + ctrl->value = vout->ctrl_vflip;
  88271. + break;
  88272. + case V4L2_CID_HFLIP:
  88273. + ctrl->value = vout->ctrl_hflip;
  88274. + break;
  88275. + case V4L2_CID_MXC_MOTION:
  88276. + if (vout->task.input.deinterlace.enable)
  88277. + ctrl->value = vout->task.input.deinterlace.motion;
  88278. + else
  88279. + ctrl->value = 0;
  88280. + break;
  88281. + default:
  88282. + ret = -EINVAL;
  88283. + }
  88284. + return ret;
  88285. +}
  88286. +
  88287. +static void setup_task_rotation(struct mxc_vout_output *vout)
  88288. +{
  88289. + if (vout->ctrl_rotate == 0) {
  88290. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  88291. + vout->task.output.rotate = IPU_ROTATE_180;
  88292. + else if (vout->ctrl_vflip)
  88293. + vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
  88294. + else if (vout->ctrl_hflip)
  88295. + vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
  88296. + else
  88297. + vout->task.output.rotate = IPU_ROTATE_NONE;
  88298. + } else if (vout->ctrl_rotate == 90) {
  88299. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  88300. + vout->task.output.rotate = IPU_ROTATE_90_LEFT;
  88301. + else if (vout->ctrl_vflip)
  88302. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
  88303. + else if (vout->ctrl_hflip)
  88304. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
  88305. + else
  88306. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
  88307. + } else if (vout->ctrl_rotate == 180) {
  88308. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  88309. + vout->task.output.rotate = IPU_ROTATE_NONE;
  88310. + else if (vout->ctrl_vflip)
  88311. + vout->task.output.rotate = IPU_ROTATE_HORIZ_FLIP;
  88312. + else if (vout->ctrl_hflip)
  88313. + vout->task.output.rotate = IPU_ROTATE_VERT_FLIP;
  88314. + else
  88315. + vout->task.output.rotate = IPU_ROTATE_180;
  88316. + } else if (vout->ctrl_rotate == 270) {
  88317. + if (vout->ctrl_vflip && vout->ctrl_hflip)
  88318. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT;
  88319. + else if (vout->ctrl_vflip)
  88320. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_HFLIP;
  88321. + else if (vout->ctrl_hflip)
  88322. + vout->task.output.rotate = IPU_ROTATE_90_RIGHT_VFLIP;
  88323. + else
  88324. + vout->task.output.rotate = IPU_ROTATE_90_LEFT;
  88325. + }
  88326. +}
  88327. +
  88328. +static int mxc_vidioc_s_ctrl(struct file *file, void *fh,
  88329. + struct v4l2_control *ctrl)
  88330. +{
  88331. + int ret = 0;
  88332. + struct mxc_vout_output *vout = fh, *pre_vout;
  88333. +
  88334. + pre_vout = vmalloc(sizeof(*pre_vout));
  88335. + if (!pre_vout)
  88336. + return -ENOMEM;
  88337. +
  88338. + /* wait current work finish */
  88339. + if (vout->vbq.streaming)
  88340. + flush_workqueue(vout->v4l_wq);
  88341. +
  88342. + mutex_lock(&vout->task_lock);
  88343. +
  88344. + memcpy(pre_vout, vout, sizeof(*vout));
  88345. +
  88346. + switch (ctrl->id) {
  88347. + case V4L2_CID_ROTATE:
  88348. + {
  88349. + vout->ctrl_rotate = (ctrl->value/90) * 90;
  88350. + if (vout->ctrl_rotate > 270)
  88351. + vout->ctrl_rotate = 270;
  88352. + setup_task_rotation(vout);
  88353. + break;
  88354. + }
  88355. + case V4L2_CID_VFLIP:
  88356. + {
  88357. + vout->ctrl_vflip = ctrl->value;
  88358. + setup_task_rotation(vout);
  88359. + break;
  88360. + }
  88361. + case V4L2_CID_HFLIP:
  88362. + {
  88363. + vout->ctrl_hflip = ctrl->value;
  88364. + setup_task_rotation(vout);
  88365. + break;
  88366. + }
  88367. + case V4L2_CID_MXC_MOTION:
  88368. + {
  88369. + vout->task.input.deinterlace.motion = ctrl->value;
  88370. + break;
  88371. + }
  88372. + default:
  88373. + ret = -EINVAL;
  88374. + goto done;
  88375. + }
  88376. +
  88377. + if (vout->fmt_init) {
  88378. + memcpy(&vout->task.input.crop, &vout->in_rect,
  88379. + sizeof(vout->in_rect));
  88380. + ret = mxc_vout_try_task(vout);
  88381. + if (ret < 0) {
  88382. + v4l2_err(vout->vfd->v4l2_dev,
  88383. + "vout check task failed\n");
  88384. + memcpy(vout, pre_vout, sizeof(*vout));
  88385. + goto done;
  88386. + }
  88387. +
  88388. + if (mxc_vout_need_fb_reconfig(vout, pre_vout)) {
  88389. + ret = config_disp_output(vout);
  88390. + if (ret < 0)
  88391. + v4l2_err(vout->vfd->v4l2_dev,
  88392. + "Config display output failed\n");
  88393. + }
  88394. + }
  88395. +
  88396. +done:
  88397. + vfree(pre_vout);
  88398. + mutex_unlock(&vout->task_lock);
  88399. +
  88400. + return ret;
  88401. +}
  88402. +
  88403. +static int mxc_vidioc_reqbufs(struct file *file, void *fh,
  88404. + struct v4l2_requestbuffers *req)
  88405. +{
  88406. + int ret = 0;
  88407. + struct mxc_vout_output *vout = fh;
  88408. + struct videobuf_queue *q = &vout->vbq;
  88409. +
  88410. + if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
  88411. + return -EINVAL;
  88412. +
  88413. + /* should not be here after streaming, videobuf_reqbufs will control */
  88414. + mutex_lock(&vout->task_lock);
  88415. +
  88416. + ret = videobuf_reqbufs(q, req);
  88417. +
  88418. + mutex_unlock(&vout->task_lock);
  88419. + return ret;
  88420. +}
  88421. +
  88422. +static int mxc_vidioc_querybuf(struct file *file, void *fh,
  88423. + struct v4l2_buffer *b)
  88424. +{
  88425. + int ret;
  88426. + struct mxc_vout_output *vout = fh;
  88427. +
  88428. + ret = videobuf_querybuf(&vout->vbq, b);
  88429. + if (!ret) {
  88430. + /* return physical address */
  88431. + struct videobuf_buffer *vb = vout->vbq.bufs[b->index];
  88432. + if (b->flags & V4L2_BUF_FLAG_MAPPED)
  88433. + b->m.offset = videobuf_to_dma_contig(vb);
  88434. + }
  88435. +
  88436. + return ret;
  88437. +}
  88438. +
  88439. +static int mxc_vidioc_qbuf(struct file *file, void *fh,
  88440. + struct v4l2_buffer *buffer)
  88441. +{
  88442. + struct mxc_vout_output *vout = fh;
  88443. +
  88444. + return videobuf_qbuf(&vout->vbq, buffer);
  88445. +}
  88446. +
  88447. +static int mxc_vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
  88448. +{
  88449. + struct mxc_vout_output *vout = fh;
  88450. +
  88451. + if (!vout->vbq.streaming)
  88452. + return -EINVAL;
  88453. +
  88454. + if (file->f_flags & O_NONBLOCK)
  88455. + return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 1);
  88456. + else
  88457. + return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 0);
  88458. +}
  88459. +
  88460. +static int set_window_position(struct mxc_vout_output *vout,
  88461. + struct mxcfb_pos *pos)
  88462. +{
  88463. + struct fb_info *fbi = vout->fbi;
  88464. + mm_segment_t old_fs;
  88465. + int ret = 0;
  88466. +
  88467. + if (vout->disp_support_windows) {
  88468. + old_fs = get_fs();
  88469. + set_fs(KERNEL_DS);
  88470. + ret = fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
  88471. + (unsigned long)pos);
  88472. + set_fs(old_fs);
  88473. + }
  88474. +
  88475. + return ret;
  88476. +}
  88477. +
  88478. +static int config_disp_output(struct mxc_vout_output *vout)
  88479. +{
  88480. + struct dma_mem *buf = NULL;
  88481. + struct fb_info *fbi = vout->fbi;
  88482. + struct fb_var_screeninfo var;
  88483. + struct mxcfb_pos pos;
  88484. + int i, fb_num, ret;
  88485. + u32 fb_base;
  88486. + u32 size;
  88487. + u32 display_buf_size;
  88488. + u32 *pixel = NULL;
  88489. + u32 color;
  88490. + int j;
  88491. +
  88492. + memcpy(&var, &fbi->var, sizeof(var));
  88493. + fb_base = fbi->fix.smem_start;
  88494. +
  88495. + var.xres = vout->task.output.width;
  88496. + var.yres = vout->task.output.height;
  88497. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp) {
  88498. + fb_num = 1;
  88499. + /* input crop */
  88500. + if (vout->task.input.width > vout->task.output.width)
  88501. + var.xres_virtual = vout->task.input.width;
  88502. + else
  88503. + var.xres_virtual = var.xres;
  88504. + if (vout->task.input.height > vout->task.output.height)
  88505. + var.yres_virtual = vout->task.input.height;
  88506. + else
  88507. + var.yres_virtual = var.yres;
  88508. + var.rotate = vout->task.output.rotate;
  88509. + var.vmode |= FB_VMODE_YWRAP;
  88510. + } else {
  88511. + fb_num = FB_BUFS;
  88512. + var.xres_virtual = var.xres;
  88513. + var.yres_virtual = fb_num * var.yres;
  88514. + var.vmode &= ~FB_VMODE_YWRAP;
  88515. + }
  88516. + var.bits_per_pixel = fmt_to_bpp(vout->task.output.format);
  88517. + var.nonstd = vout->task.output.format;
  88518. +
  88519. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  88520. + "set display fb to %d %d\n",
  88521. + var.xres, var.yres);
  88522. +
  88523. + /*
  88524. + * To setup the overlay fb from scratch without
  88525. + * the last time overlay fb position or resolution's
  88526. + * impact, we take the following steps:
  88527. + * - blank fb
  88528. + * - set fb position to the starting point
  88529. + * - reconfigure fb
  88530. + * - set fb position to a specific point
  88531. + * - unblank fb
  88532. + * This procedure applies to non-overlay fbs as well.
  88533. + */
  88534. + console_lock();
  88535. + fbi->flags |= FBINFO_MISC_USEREVENT;
  88536. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  88537. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  88538. + console_unlock();
  88539. +
  88540. + pos.x = 0;
  88541. + pos.y = 0;
  88542. + ret = set_window_position(vout, &pos);
  88543. + if (ret < 0) {
  88544. + v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position "
  88545. + "to starting point\n");
  88546. + return ret;
  88547. + }
  88548. +
  88549. + /* Init display channel through fb API */
  88550. + var.yoffset = 0;
  88551. + var.activate |= FB_ACTIVATE_FORCE;
  88552. + console_lock();
  88553. + fbi->flags |= FBINFO_MISC_USEREVENT;
  88554. + ret = fb_set_var(fbi, &var);
  88555. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  88556. + console_unlock();
  88557. + if (ret < 0) {
  88558. + v4l2_err(vout->vfd->v4l2_dev,
  88559. + "ERR:%s fb_set_var ret:%d\n", __func__, ret);
  88560. + return ret;
  88561. + }
  88562. +
  88563. + ret = set_window_position(vout, &vout->win_pos);
  88564. + if (ret < 0) {
  88565. + v4l2_err(vout->vfd->v4l2_dev, "failed to set fb position\n");
  88566. + return ret;
  88567. + }
  88568. +
  88569. + if (vout->linear_bypass_pp || vout->tiled_bypass_pp)
  88570. + display_buf_size = fbi->fix.line_length * fbi->var.yres_virtual;
  88571. + else
  88572. + display_buf_size = fbi->fix.line_length * fbi->var.yres;
  88573. + for (i = 0; i < fb_num; i++)
  88574. + vout->disp_bufs[i] = fbi->fix.smem_start + i * display_buf_size;
  88575. + if (vout->tiled_bypass_pp) {
  88576. + size = PAGE_ALIGN(vout->task.input.crop.w *
  88577. + vout->task.input.crop.h *
  88578. + fmt_to_bpp(vout->task.output.format)/8);
  88579. + if (size > vout->vdoa_output[0].size) {
  88580. + for (i = 0; i < VDOA_FB_BUFS; i++) {
  88581. + buf = &vout->vdoa_output[i];
  88582. + if (buf->vaddr)
  88583. + free_dma_buf(vout, buf);
  88584. + buf->size = size;
  88585. + ret = alloc_dma_buf(vout, buf);
  88586. + if (ret < 0)
  88587. + goto err;
  88588. + }
  88589. + }
  88590. + for (i = fb_num; i < (fb_num + VDOA_FB_BUFS); i++)
  88591. + vout->disp_bufs[i] =
  88592. + vout->vdoa_output[i - fb_num].paddr;
  88593. + }
  88594. + vout->fb_smem_len = fbi->fix.smem_len;
  88595. + vout->fb_smem_start = fbi->fix.smem_start;
  88596. + if (fb_base != fbi->fix.smem_start) {
  88597. + v4l2_dbg(1, debug, vout->vfd->v4l2_dev,
  88598. + "realloc fb mem size:0x%x@0x%lx,old paddr @0x%x\n",
  88599. + fbi->fix.smem_len, fbi->fix.smem_start, fb_base);
  88600. + }
  88601. +
  88602. + /* fill black when video config changed */
  88603. + color = colorspaceofpixel(vout->task.output.format) == YUV_CS ?
  88604. + UYVY_BLACK : RGB_BLACK;
  88605. + if (IS_PLANAR_PIXEL_FORMAT(vout->task.output.format)) {
  88606. + size = display_buf_size * 8 /
  88607. + fmt_to_bpp(vout->task.output.format);
  88608. + memset(fbi->screen_base, Y_BLACK, size);
  88609. + memset(fbi->screen_base + size, UV_BLACK,
  88610. + display_buf_size - size);
  88611. + } else {
  88612. + pixel = (u32 *)fbi->screen_base;
  88613. + for (i = 0; i < (display_buf_size >> 2); i++)
  88614. + *pixel++ = color;
  88615. + }
  88616. + console_lock();
  88617. + fbi->flags |= FBINFO_MISC_USEREVENT;
  88618. + ret = fb_blank(fbi, FB_BLANK_UNBLANK);
  88619. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  88620. + console_unlock();
  88621. + vout->release = false;
  88622. +
  88623. + return ret;
  88624. +err:
  88625. + for (j = i - 1; j >= 0; j--) {
  88626. + buf = &vout->vdoa_output[j];
  88627. + if (buf->vaddr)
  88628. + free_dma_buf(vout, buf);
  88629. + }
  88630. + return ret;
  88631. +}
  88632. +
  88633. +static inline void wait_for_vsync(struct mxc_vout_output *vout)
  88634. +{
  88635. + struct fb_info *fbi = vout->fbi;
  88636. + mm_segment_t old_fs;
  88637. +
  88638. + if (fbi->fbops->fb_ioctl) {
  88639. + old_fs = get_fs();
  88640. + set_fs(KERNEL_DS);
  88641. + fbi->fbops->fb_ioctl(fbi, MXCFB_WAIT_FOR_VSYNC,
  88642. + (unsigned long)NULL);
  88643. + set_fs(old_fs);
  88644. + }
  88645. +
  88646. + return;
  88647. +}
  88648. +
  88649. +static void release_disp_output(struct mxc_vout_output *vout)
  88650. +{
  88651. + struct fb_info *fbi = vout->fbi;
  88652. + struct mxcfb_pos pos;
  88653. +
  88654. + if (vout->release)
  88655. + return;
  88656. + console_lock();
  88657. + fbi->flags |= FBINFO_MISC_USEREVENT;
  88658. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  88659. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  88660. + console_unlock();
  88661. +
  88662. + /* restore pos to 0,0 avoid fb pan display hang? */
  88663. + pos.x = 0;
  88664. + pos.y = 0;
  88665. + set_window_position(vout, &pos);
  88666. +
  88667. + if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
  88668. + console_lock();
  88669. + fbi->fix.smem_start = vout->disp_bufs[0];
  88670. + fbi->flags |= FBINFO_MISC_USEREVENT;
  88671. + fb_blank(fbi, FB_BLANK_UNBLANK);
  88672. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  88673. + console_unlock();
  88674. +
  88675. + }
  88676. +
  88677. + vout->release = true;
  88678. +}
  88679. +
  88680. +static int mxc_vidioc_streamon(struct file *file, void *fh,
  88681. + enum v4l2_buf_type i)
  88682. +{
  88683. + struct mxc_vout_output *vout = fh;
  88684. + struct videobuf_queue *q = &vout->vbq;
  88685. + int ret;
  88686. +
  88687. + if (q->streaming) {
  88688. + v4l2_err(vout->vfd->v4l2_dev,
  88689. + "video output already run\n");
  88690. + ret = -EBUSY;
  88691. + goto done;
  88692. + }
  88693. +
  88694. + if (deinterlace_3_field(vout) && list_is_singular(&q->stream)) {
  88695. + v4l2_err(vout->vfd->v4l2_dev,
  88696. + "deinterlacing: need queue 2 frame before streamon\n");
  88697. + ret = -EINVAL;
  88698. + goto done;
  88699. + }
  88700. +
  88701. + ret = config_disp_output(vout);
  88702. + if (ret < 0) {
  88703. + v4l2_err(vout->vfd->v4l2_dev,
  88704. + "Config display output failed\n");
  88705. + goto done;
  88706. + }
  88707. +
  88708. + hrtimer_init(&vout->timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
  88709. + vout->timer.function = mxc_vout_timer_handler;
  88710. + vout->timer_stop = true;
  88711. +
  88712. + vout->start_ktime = hrtimer_cb_get_time(&vout->timer);
  88713. +
  88714. + vout->pre1_vb = NULL;
  88715. + vout->pre2_vb = NULL;
  88716. +
  88717. + ret = videobuf_streamon(q);
  88718. +done:
  88719. + return ret;
  88720. +}
  88721. +
  88722. +static int mxc_vidioc_streamoff(struct file *file, void *fh,
  88723. + enum v4l2_buf_type i)
  88724. +{
  88725. + struct mxc_vout_output *vout = fh;
  88726. + struct videobuf_queue *q = &vout->vbq;
  88727. + int ret = 0;
  88728. +
  88729. + if (q->streaming) {
  88730. + flush_workqueue(vout->v4l_wq);
  88731. +
  88732. + hrtimer_cancel(&vout->timer);
  88733. +
  88734. + /*
  88735. + * Wait for 2 vsyncs to make sure
  88736. + * frames are drained on triple
  88737. + * buffer.
  88738. + */
  88739. + wait_for_vsync(vout);
  88740. + wait_for_vsync(vout);
  88741. +
  88742. + release_disp_output(vout);
  88743. +
  88744. + ret = videobuf_streamoff(&vout->vbq);
  88745. + }
  88746. + INIT_LIST_HEAD(&vout->queue_list);
  88747. + INIT_LIST_HEAD(&vout->active_list);
  88748. +
  88749. + return ret;
  88750. +}
  88751. +
  88752. +static const struct v4l2_ioctl_ops mxc_vout_ioctl_ops = {
  88753. + .vidioc_querycap = mxc_vidioc_querycap,
  88754. + .vidioc_enum_fmt_vid_out = mxc_vidioc_enum_fmt_vid_out,
  88755. + .vidioc_g_fmt_vid_out = mxc_vidioc_g_fmt_vid_out,
  88756. + .vidioc_s_fmt_vid_out = mxc_vidioc_s_fmt_vid_out,
  88757. + .vidioc_cropcap = mxc_vidioc_cropcap,
  88758. + .vidioc_g_crop = mxc_vidioc_g_crop,
  88759. + .vidioc_s_crop = mxc_vidioc_s_crop,
  88760. + .vidioc_queryctrl = mxc_vidioc_queryctrl,
  88761. + .vidioc_g_ctrl = mxc_vidioc_g_ctrl,
  88762. + .vidioc_s_ctrl = mxc_vidioc_s_ctrl,
  88763. + .vidioc_reqbufs = mxc_vidioc_reqbufs,
  88764. + .vidioc_querybuf = mxc_vidioc_querybuf,
  88765. + .vidioc_qbuf = mxc_vidioc_qbuf,
  88766. + .vidioc_dqbuf = mxc_vidioc_dqbuf,
  88767. + .vidioc_streamon = mxc_vidioc_streamon,
  88768. + .vidioc_streamoff = mxc_vidioc_streamoff,
  88769. +};
  88770. +
  88771. +static const struct v4l2_file_operations mxc_vout_fops = {
  88772. + .owner = THIS_MODULE,
  88773. + .unlocked_ioctl = video_ioctl2,
  88774. + .mmap = mxc_vout_mmap,
  88775. + .open = mxc_vout_open,
  88776. + .release = mxc_vout_release,
  88777. +};
  88778. +
  88779. +static struct video_device mxc_vout_template = {
  88780. + .name = "MXC Video Output",
  88781. + .fops = &mxc_vout_fops,
  88782. + .ioctl_ops = &mxc_vout_ioctl_ops,
  88783. + .release = video_device_release,
  88784. +};
  88785. +
  88786. +static struct videobuf_queue_ops mxc_vout_vbq_ops = {
  88787. + .buf_setup = mxc_vout_buffer_setup,
  88788. + .buf_prepare = mxc_vout_buffer_prepare,
  88789. + .buf_release = mxc_vout_buffer_release,
  88790. + .buf_queue = mxc_vout_buffer_queue,
  88791. +};
  88792. +
  88793. +static void mxc_vout_free_output(struct mxc_vout_dev *dev)
  88794. +{
  88795. + int i;
  88796. + int j;
  88797. + struct mxc_vout_output *vout;
  88798. + struct video_device *vfd;
  88799. +
  88800. + for (i = 0; i < dev->out_num; i++) {
  88801. + vout = dev->out[i];
  88802. + vfd = vout->vfd;
  88803. + if (vout->vdoa_work.vaddr)
  88804. + free_dma_buf(vout, &vout->vdoa_work);
  88805. + for (j = 0; j < VDOA_FB_BUFS; j++) {
  88806. + if (vout->vdoa_output[j].vaddr)
  88807. + free_dma_buf(vout, &vout->vdoa_output[j]);
  88808. + }
  88809. + if (vfd) {
  88810. + if (!video_is_registered(vfd))
  88811. + video_device_release(vfd);
  88812. + else
  88813. + video_unregister_device(vfd);
  88814. + }
  88815. + kfree(vout);
  88816. + }
  88817. +}
  88818. +
  88819. +static int mxc_vout_setup_output(struct mxc_vout_dev *dev)
  88820. +{
  88821. + struct videobuf_queue *q;
  88822. + struct fb_info *fbi;
  88823. + struct mxc_vout_output *vout;
  88824. + int i, ret = 0;
  88825. +
  88826. + update_display_setting();
  88827. +
  88828. + /* all output/overlay based on fb */
  88829. + for (i = 0; i < num_registered_fb; i++) {
  88830. + fbi = registered_fb[i];
  88831. +
  88832. + vout = kzalloc(sizeof(struct mxc_vout_output), GFP_KERNEL);
  88833. + if (!vout) {
  88834. + ret = -ENOMEM;
  88835. + break;
  88836. + }
  88837. +
  88838. + dev->out[dev->out_num] = vout;
  88839. + dev->out_num++;
  88840. +
  88841. + vout->fbi = fbi;
  88842. + vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
  88843. + vout->vfd = video_device_alloc();
  88844. + if (!vout->vfd) {
  88845. + ret = -ENOMEM;
  88846. + break;
  88847. + }
  88848. +
  88849. + *vout->vfd = mxc_vout_template;
  88850. + vout->vfd->debug = debug;
  88851. + vout->vfd->v4l2_dev = &dev->v4l2_dev;
  88852. + vout->vfd->lock = &vout->mutex;
  88853. + vout->vfd->vfl_dir = VFL_DIR_TX;
  88854. +
  88855. + mutex_init(&vout->mutex);
  88856. + mutex_init(&vout->task_lock);
  88857. +
  88858. + strlcpy(vout->vfd->name, fbi->fix.id, sizeof(vout->vfd->name));
  88859. +
  88860. + video_set_drvdata(vout->vfd, vout);
  88861. +
  88862. + if (video_register_device(vout->vfd,
  88863. + VFL_TYPE_GRABBER, video_nr + i) < 0) {
  88864. + ret = -ENODEV;
  88865. + break;
  88866. + }
  88867. +
  88868. + q = &vout->vbq;
  88869. + q->dev = dev->dev;
  88870. + spin_lock_init(&vout->vbq_lock);
  88871. + videobuf_queue_dma_contig_init(q, &mxc_vout_vbq_ops, q->dev,
  88872. + &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
  88873. + sizeof(struct videobuf_buffer), vout, NULL);
  88874. +
  88875. + v4l2_info(vout->vfd->v4l2_dev, "V4L2 device registered as %s\n",
  88876. + video_device_node_name(vout->vfd));
  88877. +
  88878. + }
  88879. +
  88880. + return ret;
  88881. +}
  88882. +
  88883. +static int mxc_vout_probe(struct platform_device *pdev)
  88884. +{
  88885. + int ret;
  88886. + struct mxc_vout_dev *dev;
  88887. +
  88888. + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  88889. + if (!dev)
  88890. + return -ENOMEM;
  88891. +
  88892. + dev->dev = &pdev->dev;
  88893. + dev->dev->dma_mask = kmalloc(sizeof(*dev->dev->dma_mask), GFP_KERNEL);
  88894. + *dev->dev->dma_mask = DMA_BIT_MASK(32);
  88895. + dev->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  88896. +
  88897. + ret = v4l2_device_register(dev->dev, &dev->v4l2_dev);
  88898. + if (ret) {
  88899. + dev_err(dev->dev, "v4l2_device_register failed\n");
  88900. + goto free_dev;
  88901. + }
  88902. +
  88903. + ret = mxc_vout_setup_output(dev);
  88904. + if (ret < 0)
  88905. + goto rel_vdev;
  88906. +
  88907. + return 0;
  88908. +
  88909. +rel_vdev:
  88910. + mxc_vout_free_output(dev);
  88911. + v4l2_device_unregister(&dev->v4l2_dev);
  88912. +free_dev:
  88913. + kfree(dev);
  88914. + return ret;
  88915. +}
  88916. +
  88917. +static int mxc_vout_remove(struct platform_device *pdev)
  88918. +{
  88919. + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
  88920. + struct mxc_vout_dev *dev = container_of(v4l2_dev, struct
  88921. + mxc_vout_dev, v4l2_dev);
  88922. +
  88923. + mxc_vout_free_output(dev);
  88924. + v4l2_device_unregister(v4l2_dev);
  88925. + kfree(dev);
  88926. + return 0;
  88927. +}
  88928. +
  88929. +static const struct of_device_id mxc_v4l2_dt_ids[] = {
  88930. + { .compatible = "fsl,mxc_v4l2_output", },
  88931. + { /* sentinel */ }
  88932. +};
  88933. +
  88934. +static struct platform_driver mxc_vout_driver = {
  88935. + .driver = {
  88936. + .name = "mxc_v4l2_output",
  88937. + .of_match_table = mxc_v4l2_dt_ids,
  88938. + },
  88939. + .probe = mxc_vout_probe,
  88940. + .remove = mxc_vout_remove,
  88941. +};
  88942. +
  88943. +static int __init mxc_vout_init(void)
  88944. +{
  88945. + if (platform_driver_register(&mxc_vout_driver) != 0) {
  88946. + printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
  88947. + return -EINVAL;
  88948. + }
  88949. + return 0;
  88950. +}
  88951. +
  88952. +static void mxc_vout_cleanup(void)
  88953. +{
  88954. + platform_driver_unregister(&mxc_vout_driver);
  88955. +}
  88956. +
  88957. +module_init(mxc_vout_init);
  88958. +module_exit(mxc_vout_cleanup);
  88959. +
  88960. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  88961. +MODULE_DESCRIPTION("V4L2-driver for MXC video output");
  88962. +MODULE_LICENSE("GPL");
  88963. diff -Nur linux-3.14.17/drivers/media/usb/hdpvr/hdpvr-video.c linux-imx6-3.14/drivers/media/usb/hdpvr/hdpvr-video.c
  88964. --- linux-3.14.17/drivers/media/usb/hdpvr/hdpvr-video.c 2014-08-14 03:38:34.000000000 +0200
  88965. +++ linux-imx6-3.14/drivers/media/usb/hdpvr/hdpvr-video.c 2014-09-11 18:06:02.730040885 +0200
  88966. @@ -82,7 +82,7 @@
  88967. }
  88968. /*=========================================================================*/
  88969. -/* buffer bits */
  88970. +/* bufffer bits */
  88971. /* function expects dev->io_mutex to be hold by caller */
  88972. int hdpvr_cancel_queue(struct hdpvr_device *dev)
  88973. @@ -926,7 +926,7 @@
  88974. case V4L2_CID_MPEG_AUDIO_ENCODING:
  88975. if (dev->flags & HDPVR_FLAG_AC3_CAP) {
  88976. opt->audio_codec = ctrl->val;
  88977. - return hdpvr_set_audio(dev, opt->audio_input + 1,
  88978. + return hdpvr_set_audio(dev, opt->audio_input,
  88979. opt->audio_codec);
  88980. }
  88981. return 0;
  88982. @@ -1198,7 +1198,7 @@
  88983. v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
  88984. V4L2_CID_MPEG_AUDIO_ENCODING,
  88985. ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
  88986. - 0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC);
  88987. + 0x7, V4L2_MPEG_AUDIO_ENCODING_AAC);
  88988. v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
  88989. V4L2_CID_MPEG_VIDEO_ENCODING,
  88990. V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
  88991. diff -Nur linux-3.14.17/drivers/media/v4l2-core/v4l2-dv-timings.c linux-imx6-3.14/drivers/media/v4l2-core/v4l2-dv-timings.c
  88992. --- linux-3.14.17/drivers/media/v4l2-core/v4l2-dv-timings.c 2014-08-14 03:38:34.000000000 +0200
  88993. +++ linux-imx6-3.14/drivers/media/v4l2-core/v4l2-dv-timings.c 2014-09-11 18:06:02.834041301 +0200
  88994. @@ -595,10 +595,10 @@
  88995. aspect.denominator = 9;
  88996. } else if (ratio == 34) {
  88997. aspect.numerator = 4;
  88998. - aspect.denominator = 3;
  88999. + aspect.numerator = 3;
  89000. } else if (ratio == 68) {
  89001. aspect.numerator = 15;
  89002. - aspect.denominator = 9;
  89003. + aspect.numerator = 9;
  89004. } else {
  89005. aspect.numerator = hor_landscape + 99;
  89006. aspect.denominator = 100;
  89007. diff -Nur linux-3.14.17/drivers/media/v4l2-core/videobuf2-dma-contig.c linux-imx6-3.14/drivers/media/v4l2-core/videobuf2-dma-contig.c
  89008. --- linux-3.14.17/drivers/media/v4l2-core/videobuf2-dma-contig.c 2014-08-14 03:38:34.000000000 +0200
  89009. +++ linux-imx6-3.14/drivers/media/v4l2-core/videobuf2-dma-contig.c 2014-09-11 18:06:02.838041316 +0200
  89010. @@ -719,7 +719,7 @@
  89011. /* get the associated scatterlist for this buffer */
  89012. sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
  89013. - if (IS_ERR_OR_NULL(sgt)) {
  89014. + if (IS_ERR(sgt)) {
  89015. pr_err("Error getting dmabuf scatterlist\n");
  89016. return -EINVAL;
  89017. }
  89018. diff -Nur linux-3.14.17/drivers/media/v4l2-core/videobuf-dma-contig.c linux-imx6-3.14/drivers/media/v4l2-core/videobuf-dma-contig.c
  89019. --- linux-3.14.17/drivers/media/v4l2-core/videobuf-dma-contig.c 2014-08-14 03:38:34.000000000 +0200
  89020. +++ linux-imx6-3.14/drivers/media/v4l2-core/videobuf-dma-contig.c 2014-09-11 18:06:02.834041301 +0200
  89021. @@ -304,7 +304,7 @@
  89022. /* Try to remap memory */
  89023. size = vma->vm_end - vma->vm_start;
  89024. - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  89025. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  89026. retval = vm_iomap_memory(vma, vma->vm_start, size);
  89027. if (retval) {
  89028. dev_err(q->dev, "mmap: remap failed with error %d. ",
  89029. diff -Nur linux-3.14.17/drivers/mfd/ab8500-core.c linux-imx6-3.14/drivers/mfd/ab8500-core.c
  89030. --- linux-3.14.17/drivers/mfd/ab8500-core.c 2014-08-14 03:38:34.000000000 +0200
  89031. +++ linux-imx6-3.14/drivers/mfd/ab8500-core.c 2014-09-11 18:06:02.862041412 +0200
  89032. @@ -592,7 +592,7 @@
  89033. /* If ->irq_base is zero this will give a linear mapping */
  89034. ab8500->domain = irq_domain_add_simple(NULL,
  89035. - num_irqs, ab8500->irq_base,
  89036. + num_irqs, 0,
  89037. &ab8500_irq_ops, ab8500);
  89038. if (!ab8500->domain) {
  89039. @@ -1583,14 +1583,13 @@
  89040. if (!ab8500)
  89041. return -ENOMEM;
  89042. - if (plat)
  89043. - ab8500->irq_base = plat->irq_base;
  89044. -
  89045. ab8500->dev = &pdev->dev;
  89046. resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  89047. - if (!resource)
  89048. + if (!resource) {
  89049. + dev_err(&pdev->dev, "no IRQ resource\n");
  89050. return -ENODEV;
  89051. + }
  89052. ab8500->irq = resource->start;
  89053. @@ -1612,8 +1611,10 @@
  89054. else {
  89055. ret = get_register_interruptible(ab8500, AB8500_MISC,
  89056. AB8500_IC_NAME_REG, &value);
  89057. - if (ret < 0)
  89058. + if (ret < 0) {
  89059. + dev_err(&pdev->dev, "could not probe HW\n");
  89060. return ret;
  89061. + }
  89062. ab8500->version = value;
  89063. }
  89064. @@ -1759,30 +1760,30 @@
  89065. if (is_ab9540(ab8500))
  89066. ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
  89067. ARRAY_SIZE(ab9540_devs), NULL,
  89068. - ab8500->irq_base, ab8500->domain);
  89069. + 0, ab8500->domain);
  89070. else if (is_ab8540(ab8500)) {
  89071. ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
  89072. ARRAY_SIZE(ab8540_devs), NULL,
  89073. - ab8500->irq_base, NULL);
  89074. + 0, ab8500->domain);
  89075. if (ret)
  89076. return ret;
  89077. if (is_ab8540_1p2_or_earlier(ab8500))
  89078. ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
  89079. ARRAY_SIZE(ab8540_cut1_devs), NULL,
  89080. - ab8500->irq_base, NULL);
  89081. + 0, ab8500->domain);
  89082. else /* ab8540 >= cut2 */
  89083. ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
  89084. ARRAY_SIZE(ab8540_cut2_devs), NULL,
  89085. - ab8500->irq_base, NULL);
  89086. + 0, ab8500->domain);
  89087. } else if (is_ab8505(ab8500))
  89088. ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
  89089. ARRAY_SIZE(ab8505_devs), NULL,
  89090. - ab8500->irq_base, ab8500->domain);
  89091. + 0, ab8500->domain);
  89092. else
  89093. ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
  89094. ARRAY_SIZE(ab8500_devs), NULL,
  89095. - ab8500->irq_base, ab8500->domain);
  89096. + 0, ab8500->domain);
  89097. if (ret)
  89098. return ret;
  89099. @@ -1790,7 +1791,7 @@
  89100. /* Add battery management devices */
  89101. ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
  89102. ARRAY_SIZE(ab8500_bm_devs), NULL,
  89103. - ab8500->irq_base, ab8500->domain);
  89104. + 0, ab8500->domain);
  89105. if (ret)
  89106. dev_err(ab8500->dev, "error adding bm devices\n");
  89107. }
  89108. diff -Nur linux-3.14.17/drivers/mfd/db8500-prcmu.c linux-imx6-3.14/drivers/mfd/db8500-prcmu.c
  89109. --- linux-3.14.17/drivers/mfd/db8500-prcmu.c 2014-08-14 03:38:34.000000000 +0200
  89110. +++ linux-imx6-3.14/drivers/mfd/db8500-prcmu.c 2014-09-11 18:06:02.866041428 +0200
  89111. @@ -25,6 +25,7 @@
  89112. #include <linux/bitops.h>
  89113. #include <linux/fs.h>
  89114. #include <linux/of.h>
  89115. +#include <linux/of_irq.h>
  89116. #include <linux/platform_device.h>
  89117. #include <linux/uaccess.h>
  89118. #include <linux/mfd/core.h>
  89119. @@ -2678,16 +2679,12 @@
  89120. .xlate = irq_domain_xlate_twocell,
  89121. };
  89122. -static int db8500_irq_init(struct device_node *np, int irq_base)
  89123. +static int db8500_irq_init(struct device_node *np)
  89124. {
  89125. int i;
  89126. - /* In the device tree case, just take some IRQs */
  89127. - if (np)
  89128. - irq_base = 0;
  89129. -
  89130. db8500_irq_domain = irq_domain_add_simple(
  89131. - np, NUM_PRCMU_WAKEUPS, irq_base,
  89132. + np, NUM_PRCMU_WAKEUPS, 0,
  89133. &db8500_irq_ops, NULL);
  89134. if (!db8500_irq_domain) {
  89135. @@ -3114,10 +3111,10 @@
  89136. }
  89137. static int db8500_prcmu_register_ab8500(struct device *parent,
  89138. - struct ab8500_platform_data *pdata,
  89139. - int irq)
  89140. + struct ab8500_platform_data *pdata)
  89141. {
  89142. - struct resource ab8500_resource = DEFINE_RES_IRQ(irq);
  89143. + struct device_node *np;
  89144. + struct resource ab8500_resource;
  89145. struct mfd_cell ab8500_cell = {
  89146. .name = "ab8500-core",
  89147. .of_compatible = "stericsson,ab8500",
  89148. @@ -3128,6 +3125,20 @@
  89149. .num_resources = 1,
  89150. };
  89151. + if (!parent->of_node)
  89152. + return -ENODEV;
  89153. +
  89154. + /* Look up the device node, sneak the IRQ out of it */
  89155. + for_each_child_of_node(parent->of_node, np) {
  89156. + if (of_device_is_compatible(np, ab8500_cell.of_compatible))
  89157. + break;
  89158. + }
  89159. + if (!np) {
  89160. + dev_info(parent, "could not find AB8500 node in the device tree\n");
  89161. + return -ENODEV;
  89162. + }
  89163. + of_irq_to_resource_table(np, &ab8500_resource, 1);
  89164. +
  89165. return mfd_add_devices(parent, 0, &ab8500_cell, 1, NULL, 0, NULL);
  89166. }
  89167. @@ -3180,7 +3191,7 @@
  89168. goto no_irq_return;
  89169. }
  89170. - db8500_irq_init(np, pdata->irq_base);
  89171. + db8500_irq_init(np);
  89172. prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
  89173. @@ -3205,8 +3216,7 @@
  89174. }
  89175. }
  89176. - err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata,
  89177. - pdata->ab_irq);
  89178. + err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata);
  89179. if (err) {
  89180. mfd_remove_devices(&pdev->dev);
  89181. pr_err("prcmu: Failed to add ab8500 subdevice\n");
  89182. diff -Nur linux-3.14.17/drivers/mfd/Kconfig linux-imx6-3.14/drivers/mfd/Kconfig
  89183. --- linux-3.14.17/drivers/mfd/Kconfig 2014-08-14 03:38:34.000000000 +0200
  89184. +++ linux-imx6-3.14/drivers/mfd/Kconfig 2014-09-11 18:06:02.862041412 +0200
  89185. @@ -163,6 +163,14 @@
  89186. Additional drivers must be enabled in order to use the functionality
  89187. of the device.
  89188. +config MFD_MXC_HDMI
  89189. + tristate "Freescale HDMI Core"
  89190. + select MFD_CORE
  89191. + help
  89192. + This is the core driver for the Freescale i.MX6 on-chip HDMI.
  89193. + This MFD driver connects with the video and audio drivers for HDMI.
  89194. +
  89195. +
  89196. config MFD_MC13XXX
  89197. tristate
  89198. depends on (SPI_MASTER || I2C)
  89199. @@ -1226,3 +1234,4 @@
  89200. help
  89201. Platform configuration infrastructure for the ARM Ltd.
  89202. Versatile Express.
  89203. +
  89204. diff -Nur linux-3.14.17/drivers/mfd/Makefile linux-imx6-3.14/drivers/mfd/Makefile
  89205. --- linux-3.14.17/drivers/mfd/Makefile 2014-08-14 03:38:34.000000000 +0200
  89206. +++ linux-imx6-3.14/drivers/mfd/Makefile 2014-09-11 18:06:02.862041412 +0200
  89207. @@ -166,3 +166,4 @@
  89208. obj-$(CONFIG_MFD_AS3711) += as3711.o
  89209. obj-$(CONFIG_MFD_AS3722) += as3722.o
  89210. obj-$(CONFIG_MFD_STW481X) += stw481x.o
  89211. +obj-$(CONFIG_MFD_MXC_HDMI) += mxc-hdmi-core.o
  89212. diff -Nur linux-3.14.17/drivers/mfd/mxc-hdmi-core.c linux-imx6-3.14/drivers/mfd/mxc-hdmi-core.c
  89213. --- linux-3.14.17/drivers/mfd/mxc-hdmi-core.c 1970-01-01 01:00:00.000000000 +0100
  89214. +++ linux-imx6-3.14/drivers/mfd/mxc-hdmi-core.c 2014-09-11 18:06:02.874041460 +0200
  89215. @@ -0,0 +1,798 @@
  89216. +/*
  89217. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  89218. + *
  89219. + * This program is free software; you can redistribute it and/or modify
  89220. + * it under the terms of the GNU General Public License as published by
  89221. + * the Free Software Foundation; either version 2 of the License, or
  89222. + * (at your option) any later version.
  89223. + *
  89224. + * This program is distributed in the hope that it will be useful,
  89225. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  89226. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  89227. + * GNU General Public License for more details.
  89228. + *
  89229. + * You should have received a copy of the GNU General Public License
  89230. + * along with this program; if not, write to the Free Software
  89231. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  89232. + *
  89233. + */
  89234. +#include <linux/kernel.h>
  89235. +#include <linux/module.h>
  89236. +#include <linux/init.h>
  89237. +#include <linux/slab.h>
  89238. +#include <linux/device.h>
  89239. +#include <linux/err.h>
  89240. +#include <linux/io.h>
  89241. +#include <linux/clk.h>
  89242. +#include <linux/spinlock.h>
  89243. +#include <linux/irq.h>
  89244. +#include <linux/interrupt.h>
  89245. +
  89246. +#include <linux/platform_device.h>
  89247. +#include <linux/regulator/machine.h>
  89248. +#include <asm/mach-types.h>
  89249. +
  89250. +#include <video/mxc_hdmi.h>
  89251. +#include <linux/ipu-v3.h>
  89252. +#include <video/mxc_edid.h>
  89253. +#include "../mxc/ipu3/ipu_prv.h"
  89254. +#include <linux/mfd/mxc-hdmi-core.h>
  89255. +#include <linux/of_device.h>
  89256. +#include <linux/mod_devicetable.h>
  89257. +
  89258. +struct mxc_hdmi_data {
  89259. + struct platform_device *pdev;
  89260. + unsigned long __iomem *reg_base;
  89261. + unsigned long reg_phys_base;
  89262. + struct device *dev;
  89263. +};
  89264. +
  89265. +static void __iomem *hdmi_base;
  89266. +static struct clk *isfr_clk;
  89267. +static struct clk *iahb_clk;
  89268. +static spinlock_t irq_spinlock;
  89269. +static spinlock_t edid_spinlock;
  89270. +static unsigned int sample_rate;
  89271. +static unsigned long pixel_clk_rate;
  89272. +static struct clk *pixel_clk;
  89273. +static int hdmi_ratio;
  89274. +int mxc_hdmi_ipu_id;
  89275. +int mxc_hdmi_disp_id;
  89276. +static int hdmi_core_edid_status;
  89277. +static struct mxc_edid_cfg hdmi_core_edid_cfg;
  89278. +static int hdmi_core_init;
  89279. +static unsigned int hdmi_dma_running;
  89280. +static struct snd_pcm_substream *hdmi_audio_stream_playback;
  89281. +static unsigned int hdmi_cable_state;
  89282. +static unsigned int hdmi_blank_state;
  89283. +static unsigned int hdmi_abort_state;
  89284. +static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock;
  89285. +
  89286. +void hdmi_set_dvi_mode(unsigned int state)
  89287. +{
  89288. + if (state) {
  89289. + mxc_hdmi_abort_stream();
  89290. + hdmi_cec_stop_device();
  89291. + } else {
  89292. + hdmi_cec_start_device();
  89293. + }
  89294. +}
  89295. +EXPORT_SYMBOL(hdmi_set_dvi_mode);
  89296. +
  89297. +unsigned int hdmi_set_cable_state(unsigned int state)
  89298. +{
  89299. + unsigned long flags;
  89300. + struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
  89301. +
  89302. + spin_lock_irqsave(&hdmi_cable_state_lock, flags);
  89303. + hdmi_cable_state = state;
  89304. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
  89305. +
  89306. + if (check_hdmi_state() && substream && hdmi_abort_state) {
  89307. + hdmi_abort_state = 0;
  89308. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
  89309. + }
  89310. + return 0;
  89311. +}
  89312. +EXPORT_SYMBOL(hdmi_set_cable_state);
  89313. +
  89314. +unsigned int hdmi_set_blank_state(unsigned int state)
  89315. +{
  89316. + unsigned long flags;
  89317. + struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
  89318. +
  89319. + spin_lock_irqsave(&hdmi_blank_state_lock, flags);
  89320. + hdmi_blank_state = state;
  89321. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
  89322. +
  89323. + if (check_hdmi_state() && substream && hdmi_abort_state) {
  89324. + hdmi_abort_state = 0;
  89325. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
  89326. + }
  89327. + return 0;
  89328. +}
  89329. +EXPORT_SYMBOL(hdmi_set_blank_state);
  89330. +
  89331. +static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
  89332. +{
  89333. + unsigned long flags;
  89334. +
  89335. + snd_pcm_stream_lock_irqsave(substream, flags);
  89336. +
  89337. + if (snd_pcm_running(substream)) {
  89338. + hdmi_abort_state = 1;
  89339. + substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
  89340. + }
  89341. +
  89342. + snd_pcm_stream_unlock_irqrestore(substream, flags);
  89343. +}
  89344. +
  89345. +int mxc_hdmi_abort_stream(void)
  89346. +{
  89347. + unsigned long flags;
  89348. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  89349. + if (hdmi_audio_stream_playback)
  89350. + hdmi_audio_abort_stream(hdmi_audio_stream_playback);
  89351. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  89352. +
  89353. + return 0;
  89354. +}
  89355. +EXPORT_SYMBOL(mxc_hdmi_abort_stream);
  89356. +
  89357. +int check_hdmi_state(void)
  89358. +{
  89359. + unsigned long flags1, flags2;
  89360. + unsigned int ret;
  89361. +
  89362. + spin_lock_irqsave(&hdmi_cable_state_lock, flags1);
  89363. + spin_lock_irqsave(&hdmi_blank_state_lock, flags2);
  89364. +
  89365. + ret = hdmi_cable_state && hdmi_blank_state;
  89366. +
  89367. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags2);
  89368. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags1);
  89369. +
  89370. + return ret;
  89371. +}
  89372. +EXPORT_SYMBOL(check_hdmi_state);
  89373. +
  89374. +int mxc_hdmi_register_audio(struct snd_pcm_substream *substream)
  89375. +{
  89376. + unsigned long flags, flags1;
  89377. + int ret = 0;
  89378. +
  89379. + snd_pcm_stream_lock_irqsave(substream, flags);
  89380. +
  89381. + if (substream && check_hdmi_state()) {
  89382. + spin_lock_irqsave(&hdmi_audio_lock, flags1);
  89383. + if (hdmi_audio_stream_playback) {
  89384. + pr_err("%s unconsist hdmi auido stream!\n", __func__);
  89385. + ret = -EINVAL;
  89386. + }
  89387. + hdmi_audio_stream_playback = substream;
  89388. + hdmi_abort_state = 0;
  89389. + spin_unlock_irqrestore(&hdmi_audio_lock, flags1);
  89390. + } else
  89391. + ret = -EINVAL;
  89392. +
  89393. + snd_pcm_stream_unlock_irqrestore(substream, flags);
  89394. +
  89395. + return ret;
  89396. +}
  89397. +EXPORT_SYMBOL(mxc_hdmi_register_audio);
  89398. +
  89399. +void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream)
  89400. +{
  89401. + unsigned long flags;
  89402. +
  89403. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  89404. + hdmi_audio_stream_playback = NULL;
  89405. + hdmi_abort_state = 0;
  89406. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  89407. +}
  89408. +EXPORT_SYMBOL(mxc_hdmi_unregister_audio);
  89409. +
  89410. +u8 hdmi_readb(unsigned int reg)
  89411. +{
  89412. + u8 value;
  89413. +
  89414. + value = __raw_readb(hdmi_base + reg);
  89415. +
  89416. + return value;
  89417. +}
  89418. +EXPORT_SYMBOL(hdmi_readb);
  89419. +
  89420. +#ifdef DEBUG
  89421. +static bool overflow_lo;
  89422. +static bool overflow_hi;
  89423. +
  89424. +bool hdmi_check_overflow(void)
  89425. +{
  89426. + u8 val, lo, hi;
  89427. +
  89428. + val = hdmi_readb(HDMI_IH_FC_STAT2);
  89429. + lo = (val & HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW) != 0;
  89430. + hi = (val & HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW) != 0;
  89431. +
  89432. + if ((lo != overflow_lo) || (hi != overflow_hi)) {
  89433. + pr_debug("%s LowPriority=%d HighPriority=%d <=======================\n",
  89434. + __func__, lo, hi);
  89435. + overflow_lo = lo;
  89436. + overflow_hi = hi;
  89437. + return true;
  89438. + }
  89439. + return false;
  89440. +}
  89441. +#else
  89442. +bool hdmi_check_overflow(void)
  89443. +{
  89444. + return false;
  89445. +}
  89446. +#endif
  89447. +EXPORT_SYMBOL(hdmi_check_overflow);
  89448. +
  89449. +void hdmi_writeb(u8 value, unsigned int reg)
  89450. +{
  89451. + hdmi_check_overflow();
  89452. + __raw_writeb(value, hdmi_base + reg);
  89453. + hdmi_check_overflow();
  89454. +}
  89455. +EXPORT_SYMBOL(hdmi_writeb);
  89456. +
  89457. +void hdmi_mask_writeb(u8 data, unsigned int reg, u8 shift, u8 mask)
  89458. +{
  89459. + u8 value = hdmi_readb(reg) & ~mask;
  89460. + value |= (data << shift) & mask;
  89461. + hdmi_writeb(value, reg);
  89462. +}
  89463. +EXPORT_SYMBOL(hdmi_mask_writeb);
  89464. +
  89465. +unsigned int hdmi_read4(unsigned int reg)
  89466. +{
  89467. + /* read a four byte address from registers */
  89468. + return (hdmi_readb(reg + 3) << 24) |
  89469. + (hdmi_readb(reg + 2) << 16) |
  89470. + (hdmi_readb(reg + 1) << 8) |
  89471. + hdmi_readb(reg);
  89472. +}
  89473. +EXPORT_SYMBOL(hdmi_read4);
  89474. +
  89475. +void hdmi_write4(unsigned int value, unsigned int reg)
  89476. +{
  89477. + /* write a four byte address to hdmi regs */
  89478. + hdmi_writeb(value & 0xff, reg);
  89479. + hdmi_writeb((value >> 8) & 0xff, reg + 1);
  89480. + hdmi_writeb((value >> 16) & 0xff, reg + 2);
  89481. + hdmi_writeb((value >> 24) & 0xff, reg + 3);
  89482. +}
  89483. +EXPORT_SYMBOL(hdmi_write4);
  89484. +
  89485. +static void initialize_hdmi_ih_mutes(void)
  89486. +{
  89487. + u8 ih_mute;
  89488. +
  89489. + /*
  89490. + * Boot up defaults are:
  89491. + * HDMI_IH_MUTE = 0x03 (disabled)
  89492. + * HDMI_IH_MUTE_* = 0x00 (enabled)
  89493. + */
  89494. +
  89495. + /* Disable top level interrupt bits in HDMI block */
  89496. + ih_mute = hdmi_readb(HDMI_IH_MUTE) |
  89497. + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  89498. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
  89499. +
  89500. + hdmi_writeb(ih_mute, HDMI_IH_MUTE);
  89501. +
  89502. + /* by default mask all interrupts */
  89503. + hdmi_writeb(0xff, HDMI_VP_MASK);
  89504. + hdmi_writeb(0xff, HDMI_FC_MASK0);
  89505. + hdmi_writeb(0xff, HDMI_FC_MASK1);
  89506. + hdmi_writeb(0xff, HDMI_FC_MASK2);
  89507. + hdmi_writeb(0xff, HDMI_PHY_MASK0);
  89508. + hdmi_writeb(0xff, HDMI_PHY_I2CM_INT_ADDR);
  89509. + hdmi_writeb(0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
  89510. + hdmi_writeb(0xff, HDMI_AUD_INT);
  89511. + hdmi_writeb(0xff, HDMI_AUD_SPDIFINT);
  89512. + hdmi_writeb(0xff, HDMI_AUD_HBR_MASK);
  89513. + hdmi_writeb(0xff, HDMI_GP_MASK);
  89514. + hdmi_writeb(0xff, HDMI_A_APIINTMSK);
  89515. + hdmi_writeb(0xff, HDMI_CEC_MASK);
  89516. + hdmi_writeb(0xff, HDMI_I2CM_INT);
  89517. + hdmi_writeb(0xff, HDMI_I2CM_CTLINT);
  89518. +
  89519. + /* Disable interrupts in the IH_MUTE_* registers */
  89520. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT0);
  89521. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT1);
  89522. + hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT2);
  89523. + hdmi_writeb(0xff, HDMI_IH_MUTE_AS_STAT0);
  89524. + hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0);
  89525. + hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0);
  89526. + hdmi_writeb(0xff, HDMI_IH_MUTE_CEC_STAT0);
  89527. + hdmi_writeb(0xff, HDMI_IH_MUTE_VP_STAT0);
  89528. + hdmi_writeb(0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
  89529. + hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  89530. +
  89531. + /* Enable top level interrupt bits in HDMI block */
  89532. + ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  89533. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
  89534. + hdmi_writeb(ih_mute, HDMI_IH_MUTE);
  89535. +}
  89536. +
  89537. +static void hdmi_set_clock_regenerator_n(unsigned int value)
  89538. +{
  89539. + u8 val;
  89540. +
  89541. + if (!hdmi_dma_running) {
  89542. + hdmi_writeb(value & 0xff, HDMI_AUD_N1);
  89543. + hdmi_writeb(0, HDMI_AUD_N2);
  89544. + hdmi_writeb(0, HDMI_AUD_N3);
  89545. + }
  89546. +
  89547. + hdmi_writeb(value & 0xff, HDMI_AUD_N1);
  89548. + hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2);
  89549. + hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3);
  89550. +
  89551. + /* nshift factor = 0 */
  89552. + val = hdmi_readb(HDMI_AUD_CTS3);
  89553. + val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK;
  89554. + hdmi_writeb(val, HDMI_AUD_CTS3);
  89555. +}
  89556. +
  89557. +static void hdmi_set_clock_regenerator_cts(unsigned int cts)
  89558. +{
  89559. + u8 val;
  89560. +
  89561. + if (!hdmi_dma_running) {
  89562. + hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
  89563. + hdmi_writeb(0, HDMI_AUD_CTS2);
  89564. + hdmi_writeb(0, HDMI_AUD_CTS3);
  89565. + }
  89566. +
  89567. + /* Must be set/cleared first */
  89568. + val = hdmi_readb(HDMI_AUD_CTS3);
  89569. + val &= ~HDMI_AUD_CTS3_CTS_MANUAL;
  89570. + hdmi_writeb(val, HDMI_AUD_CTS3);
  89571. +
  89572. + hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
  89573. + hdmi_writeb((cts >> 8) & 0xff, HDMI_AUD_CTS2);
  89574. + hdmi_writeb(((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
  89575. + HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
  89576. +}
  89577. +
  89578. +static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
  89579. + unsigned int ratio)
  89580. +{
  89581. + unsigned int n = (128 * freq) / 1000;
  89582. +
  89583. + switch (freq) {
  89584. + case 32000:
  89585. + if (pixel_clk == 25174000)
  89586. + n = (ratio == 150) ? 9152 : 4576;
  89587. + else if (pixel_clk == 27020000)
  89588. + n = (ratio == 150) ? 8192 : 4096;
  89589. + else if (pixel_clk == 74170000 || pixel_clk == 148350000)
  89590. + n = 11648;
  89591. + else if (pixel_clk == 297000000)
  89592. + n = (ratio == 150) ? 6144 : 3072;
  89593. + else
  89594. + n = 4096;
  89595. + break;
  89596. +
  89597. + case 44100:
  89598. + if (pixel_clk == 25174000)
  89599. + n = 7007;
  89600. + else if (pixel_clk == 74170000)
  89601. + n = 17836;
  89602. + else if (pixel_clk == 148350000)
  89603. + n = (ratio == 150) ? 17836 : 8918;
  89604. + else if (pixel_clk == 297000000)
  89605. + n = (ratio == 150) ? 9408 : 4704;
  89606. + else
  89607. + n = 6272;
  89608. + break;
  89609. +
  89610. + case 48000:
  89611. + if (pixel_clk == 25174000)
  89612. + n = (ratio == 150) ? 9152 : 6864;
  89613. + else if (pixel_clk == 27020000)
  89614. + n = (ratio == 150) ? 8192 : 6144;
  89615. + else if (pixel_clk == 74170000)
  89616. + n = 11648;
  89617. + else if (pixel_clk == 148350000)
  89618. + n = (ratio == 150) ? 11648 : 5824;
  89619. + else if (pixel_clk == 297000000)
  89620. + n = (ratio == 150) ? 10240 : 5120;
  89621. + else
  89622. + n = 6144;
  89623. + break;
  89624. +
  89625. + case 88200:
  89626. + n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
  89627. + break;
  89628. +
  89629. + case 96000:
  89630. + n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
  89631. + break;
  89632. +
  89633. + case 176400:
  89634. + n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
  89635. + break;
  89636. +
  89637. + case 192000:
  89638. + n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
  89639. + break;
  89640. +
  89641. + default:
  89642. + break;
  89643. + }
  89644. +
  89645. + return n;
  89646. +}
  89647. +
  89648. +static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
  89649. + unsigned int ratio)
  89650. +{
  89651. + unsigned int cts = 0;
  89652. + switch (freq) {
  89653. + case 32000:
  89654. + if (pixel_clk == 297000000) {
  89655. + cts = 222750;
  89656. + break;
  89657. + } else if (pixel_clk == 25174000) {
  89658. + cts = 28125;
  89659. + break;
  89660. + }
  89661. + case 48000:
  89662. + case 96000:
  89663. + case 192000:
  89664. + switch (pixel_clk) {
  89665. + case 25200000:
  89666. + case 27000000:
  89667. + case 54000000:
  89668. + case 74250000:
  89669. + case 148500000:
  89670. + cts = pixel_clk / 1000;
  89671. + break;
  89672. + case 297000000:
  89673. + cts = 247500;
  89674. + break;
  89675. + case 25174000:
  89676. + cts = 28125l;
  89677. + break;
  89678. + /*
  89679. + * All other TMDS clocks are not supported by
  89680. + * DWC_hdmi_tx. The TMDS clocks divided or
  89681. + * multiplied by 1,001 coefficients are not
  89682. + * supported.
  89683. + */
  89684. + default:
  89685. + break;
  89686. + }
  89687. + break;
  89688. + case 44100:
  89689. + case 88200:
  89690. + case 176400:
  89691. + switch (pixel_clk) {
  89692. + case 25200000:
  89693. + cts = 28000;
  89694. + break;
  89695. + case 25174000:
  89696. + cts = 31250;
  89697. + break;
  89698. + case 27000000:
  89699. + cts = 30000;
  89700. + break;
  89701. + case 54000000:
  89702. + cts = 60000;
  89703. + break;
  89704. + case 74250000:
  89705. + cts = 82500;
  89706. + break;
  89707. + case 148500000:
  89708. + cts = 165000;
  89709. + break;
  89710. + case 297000000:
  89711. + cts = 247500;
  89712. + break;
  89713. + default:
  89714. + break;
  89715. + }
  89716. + break;
  89717. + default:
  89718. + break;
  89719. + }
  89720. + if (ratio == 100)
  89721. + return cts;
  89722. + else
  89723. + return (cts * ratio) / 100;
  89724. +}
  89725. +
  89726. +static void hdmi_set_clk_regenerator(void)
  89727. +{
  89728. + unsigned int clk_n, clk_cts;
  89729. +
  89730. + clk_n = hdmi_compute_n(sample_rate, pixel_clk_rate, hdmi_ratio);
  89731. + clk_cts = hdmi_compute_cts(sample_rate, pixel_clk_rate, hdmi_ratio);
  89732. +
  89733. + if (clk_cts == 0) {
  89734. + pr_debug("%s: pixel clock not supported: %d\n",
  89735. + __func__, (int)pixel_clk_rate);
  89736. + return;
  89737. + }
  89738. +
  89739. + pr_debug("%s: samplerate=%d ratio=%d pixelclk=%d N=%d cts=%d\n",
  89740. + __func__, sample_rate, hdmi_ratio, (int)pixel_clk_rate,
  89741. + clk_n, clk_cts);
  89742. +
  89743. + hdmi_set_clock_regenerator_cts(clk_cts);
  89744. + hdmi_set_clock_regenerator_n(clk_n);
  89745. +}
  89746. +
  89747. +static int hdmi_core_get_of_property(struct platform_device *pdev)
  89748. +{
  89749. + struct device_node *np = pdev->dev.of_node;
  89750. + int err;
  89751. + int ipu_id, disp_id;
  89752. +
  89753. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  89754. + if (err) {
  89755. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  89756. + return err;
  89757. + }
  89758. + err = of_property_read_u32(np, "disp_id", &disp_id);
  89759. + if (err) {
  89760. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  89761. + return err;
  89762. + }
  89763. +
  89764. + mxc_hdmi_ipu_id = ipu_id;
  89765. + mxc_hdmi_disp_id = disp_id;
  89766. +
  89767. + return err;
  89768. +}
  89769. +
  89770. +/* Need to run this before phy is enabled the first time to prevent
  89771. + * overflow condition in HDMI_IH_FC_STAT2 */
  89772. +void hdmi_init_clk_regenerator(void)
  89773. +{
  89774. + if (pixel_clk_rate == 0) {
  89775. + pixel_clk_rate = 74250000;
  89776. + hdmi_set_clk_regenerator();
  89777. + }
  89778. +}
  89779. +EXPORT_SYMBOL(hdmi_init_clk_regenerator);
  89780. +
  89781. +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock)
  89782. +{
  89783. +
  89784. + /* Translate pixel clock in ps (pico seconds) to Hz */
  89785. + pixel_clk_rate = PICOS2KHZ(pixclock) * 1000UL;
  89786. + hdmi_set_clk_regenerator();
  89787. +}
  89788. +EXPORT_SYMBOL(hdmi_clk_regenerator_update_pixel_clock);
  89789. +
  89790. +void hdmi_set_dma_mode(unsigned int dma_running)
  89791. +{
  89792. + hdmi_dma_running = dma_running;
  89793. + hdmi_set_clk_regenerator();
  89794. +}
  89795. +EXPORT_SYMBOL(hdmi_set_dma_mode);
  89796. +
  89797. +void hdmi_set_sample_rate(unsigned int rate)
  89798. +{
  89799. + sample_rate = rate;
  89800. +}
  89801. +EXPORT_SYMBOL(hdmi_set_sample_rate);
  89802. +
  89803. +void hdmi_set_edid_cfg(int edid_status, struct mxc_edid_cfg *cfg)
  89804. +{
  89805. + unsigned long flags;
  89806. +
  89807. + spin_lock_irqsave(&edid_spinlock, flags);
  89808. + hdmi_core_edid_status = edid_status;
  89809. + memcpy(&hdmi_core_edid_cfg, cfg, sizeof(struct mxc_edid_cfg));
  89810. + spin_unlock_irqrestore(&edid_spinlock, flags);
  89811. +}
  89812. +EXPORT_SYMBOL(hdmi_set_edid_cfg);
  89813. +
  89814. +int hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg)
  89815. +{
  89816. + unsigned long flags;
  89817. +
  89818. + spin_lock_irqsave(&edid_spinlock, flags);
  89819. + memcpy(cfg, &hdmi_core_edid_cfg, sizeof(struct mxc_edid_cfg));
  89820. + spin_unlock_irqrestore(&edid_spinlock, flags);
  89821. +
  89822. + return hdmi_core_edid_status;
  89823. +}
  89824. +EXPORT_SYMBOL(hdmi_get_edid_cfg);
  89825. +
  89826. +void hdmi_set_registered(int registered)
  89827. +{
  89828. + hdmi_core_init = registered;
  89829. +}
  89830. +EXPORT_SYMBOL(hdmi_set_registered);
  89831. +
  89832. +int hdmi_get_registered(void)
  89833. +{
  89834. + return hdmi_core_init;
  89835. +}
  89836. +EXPORT_SYMBOL(hdmi_get_registered);
  89837. +
  89838. +static int mxc_hdmi_core_probe(struct platform_device *pdev)
  89839. +{
  89840. + struct mxc_hdmi_data *hdmi_data;
  89841. + struct resource *res;
  89842. + unsigned long flags;
  89843. + int ret = 0;
  89844. +
  89845. +#ifdef DEBUG
  89846. + overflow_lo = false;
  89847. + overflow_hi = false;
  89848. +#endif
  89849. +
  89850. + hdmi_core_init = 0;
  89851. + hdmi_dma_running = 0;
  89852. +
  89853. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  89854. + if (!res)
  89855. + return -ENOENT;
  89856. +
  89857. + ret = hdmi_core_get_of_property(pdev);
  89858. + if (ret < 0) {
  89859. + dev_err(&pdev->dev, "get hdmi of property fail\n");
  89860. + return -ENOENT;
  89861. + }
  89862. +
  89863. + hdmi_data = devm_kzalloc(&pdev->dev, sizeof(struct mxc_hdmi_data), GFP_KERNEL);
  89864. + if (!hdmi_data) {
  89865. + dev_err(&pdev->dev, "Couldn't allocate mxc hdmi mfd device\n");
  89866. + return -ENOMEM;
  89867. + }
  89868. + hdmi_data->pdev = pdev;
  89869. +
  89870. + pixel_clk = NULL;
  89871. + sample_rate = 48000;
  89872. + pixel_clk_rate = 0;
  89873. + hdmi_ratio = 100;
  89874. +
  89875. + spin_lock_init(&irq_spinlock);
  89876. + spin_lock_init(&edid_spinlock);
  89877. +
  89878. +
  89879. + spin_lock_init(&hdmi_cable_state_lock);
  89880. + spin_lock_init(&hdmi_blank_state_lock);
  89881. + spin_lock_init(&hdmi_audio_lock);
  89882. +
  89883. + spin_lock_irqsave(&hdmi_cable_state_lock, flags);
  89884. + hdmi_cable_state = 0;
  89885. + spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
  89886. +
  89887. + spin_lock_irqsave(&hdmi_blank_state_lock, flags);
  89888. + hdmi_blank_state = 0;
  89889. + spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
  89890. +
  89891. + spin_lock_irqsave(&hdmi_audio_lock, flags);
  89892. + hdmi_audio_stream_playback = NULL;
  89893. + hdmi_abort_state = 0;
  89894. + spin_unlock_irqrestore(&hdmi_audio_lock, flags);
  89895. +
  89896. + isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr");
  89897. + if (IS_ERR(isfr_clk)) {
  89898. + ret = PTR_ERR(isfr_clk);
  89899. + dev_err(&hdmi_data->pdev->dev,
  89900. + "Unable to get HDMI isfr clk: %d\n", ret);
  89901. + goto eclkg;
  89902. + }
  89903. +
  89904. + ret = clk_prepare_enable(isfr_clk);
  89905. + if (ret < 0) {
  89906. + dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
  89907. + goto eclke;
  89908. + }
  89909. +
  89910. + pr_debug("%s isfr_clk:%d\n", __func__,
  89911. + (int)clk_get_rate(isfr_clk));
  89912. +
  89913. + iahb_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_iahb");
  89914. + if (IS_ERR(iahb_clk)) {
  89915. + ret = PTR_ERR(iahb_clk);
  89916. + dev_err(&hdmi_data->pdev->dev,
  89917. + "Unable to get HDMI iahb clk: %d\n", ret);
  89918. + goto eclkg2;
  89919. + }
  89920. +
  89921. + ret = clk_prepare_enable(iahb_clk);
  89922. + if (ret < 0) {
  89923. + dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
  89924. + goto eclke2;
  89925. + }
  89926. +
  89927. + hdmi_data->reg_phys_base = res->start;
  89928. + if (!request_mem_region(res->start, resource_size(res),
  89929. + dev_name(&pdev->dev))) {
  89930. + dev_err(&pdev->dev, "request_mem_region failed\n");
  89931. + ret = -EBUSY;
  89932. + goto emem;
  89933. + }
  89934. +
  89935. + hdmi_data->reg_base = ioremap(res->start, resource_size(res));
  89936. + if (!hdmi_data->reg_base) {
  89937. + dev_err(&pdev->dev, "ioremap failed\n");
  89938. + ret = -ENOMEM;
  89939. + goto eirq;
  89940. + }
  89941. + hdmi_base = hdmi_data->reg_base;
  89942. +
  89943. + pr_debug("\n%s hdmi hw base = 0x%08x\n\n", __func__, (int)res->start);
  89944. +
  89945. + initialize_hdmi_ih_mutes();
  89946. +
  89947. + /* Disable HDMI clocks until video/audio sub-drivers are initialized */
  89948. + clk_disable_unprepare(isfr_clk);
  89949. + clk_disable_unprepare(iahb_clk);
  89950. +
  89951. + /* Replace platform data coming in with a local struct */
  89952. + platform_set_drvdata(pdev, hdmi_data);
  89953. +
  89954. + return ret;
  89955. +
  89956. +eirq:
  89957. + release_mem_region(res->start, resource_size(res));
  89958. +emem:
  89959. + clk_disable_unprepare(iahb_clk);
  89960. +eclke2:
  89961. + clk_put(iahb_clk);
  89962. +eclkg2:
  89963. + clk_disable_unprepare(isfr_clk);
  89964. +eclke:
  89965. + clk_put(isfr_clk);
  89966. +eclkg:
  89967. + return ret;
  89968. +}
  89969. +
  89970. +
  89971. +static int __exit mxc_hdmi_core_remove(struct platform_device *pdev)
  89972. +{
  89973. + struct mxc_hdmi_data *hdmi_data = platform_get_drvdata(pdev);
  89974. + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  89975. +
  89976. + iounmap(hdmi_data->reg_base);
  89977. + release_mem_region(res->start, resource_size(res));
  89978. +
  89979. + return 0;
  89980. +}
  89981. +
  89982. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  89983. + { .compatible = "fsl,imx6q-hdmi-core", },
  89984. + { .compatible = "fsl,imx6dl-hdmi-core", },
  89985. + { /* sentinel */ }
  89986. +};
  89987. +
  89988. +static struct platform_driver mxc_hdmi_core_driver = {
  89989. + .driver = {
  89990. + .name = "mxc_hdmi_core",
  89991. + .of_match_table = imx_hdmi_dt_ids,
  89992. + .owner = THIS_MODULE,
  89993. + },
  89994. + .remove = __exit_p(mxc_hdmi_core_remove),
  89995. +};
  89996. +
  89997. +static int __init mxc_hdmi_core_init(void)
  89998. +{
  89999. + return platform_driver_probe(&mxc_hdmi_core_driver,
  90000. + mxc_hdmi_core_probe);
  90001. +}
  90002. +
  90003. +static void __exit mxc_hdmi_core_exit(void)
  90004. +{
  90005. + platform_driver_unregister(&mxc_hdmi_core_driver);
  90006. +}
  90007. +
  90008. +subsys_initcall(mxc_hdmi_core_init);
  90009. +module_exit(mxc_hdmi_core_exit);
  90010. +
  90011. +MODULE_DESCRIPTION("Core driver for Freescale i.Mx on-chip HDMI");
  90012. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  90013. +MODULE_LICENSE("GPL");
  90014. diff -Nur linux-3.14.17/drivers/mfd/si476x-cmd.c linux-imx6-3.14/drivers/mfd/si476x-cmd.c
  90015. --- linux-3.14.17/drivers/mfd/si476x-cmd.c 2014-08-14 03:38:34.000000000 +0200
  90016. +++ linux-imx6-3.14/drivers/mfd/si476x-cmd.c 2014-09-11 18:06:02.910041603 +0200
  90017. @@ -303,13 +303,13 @@
  90018. * possible racing conditions when working in polling mode */
  90019. atomic_set(&core->cts, 0);
  90020. - /* if (unlikely(command == CMD_POWER_DOWN) */
  90021. - if (!wait_event_timeout(core->command,
  90022. - atomic_read(&core->cts),
  90023. - usecs_to_jiffies(usecs) + 1))
  90024. - dev_warn(&core->client->dev,
  90025. - "(%s) [CMD 0x%02x] Answer timeout.\n",
  90026. - __func__, command);
  90027. + if (!(command == CMD_POWER_DOWN))
  90028. + if (!wait_event_timeout(core->command,
  90029. + atomic_read(&core->cts),
  90030. + usecs_to_jiffies(usecs) + 1))
  90031. + dev_warn(&core->client->dev,
  90032. + "(%s) [CMD 0x%02x] Answer timeout.\n",
  90033. + __func__, command);
  90034. /*
  90035. When working in polling mode, for some reason the tuner will
  90036. diff -Nur linux-3.14.17/drivers/mfd/si476x-i2c.c linux-imx6-3.14/drivers/mfd/si476x-i2c.c
  90037. --- linux-3.14.17/drivers/mfd/si476x-i2c.c 2014-08-14 03:38:34.000000000 +0200
  90038. +++ linux-imx6-3.14/drivers/mfd/si476x-i2c.c 2014-09-11 18:06:02.910041603 +0200
  90039. @@ -303,7 +303,7 @@
  90040. */
  90041. udelay(100);
  90042. - err = si476x_core_start(core, false);
  90043. + err = si476x_core_start(core, true);
  90044. if (err < 0)
  90045. goto disable_regulators;
  90046. @@ -312,7 +312,7 @@
  90047. case SI476X_POWER_DOWN:
  90048. core->power_state = next_state;
  90049. - err = si476x_core_stop(core, false);
  90050. + err = si476x_core_stop(core, true);
  90051. if (err < 0)
  90052. core->power_state = SI476X_POWER_INCONSISTENT;
  90053. disable_regulators:
  90054. @@ -740,8 +740,15 @@
  90055. memcpy(&core->pinmux, &pdata->pinmux,
  90056. sizeof(struct si476x_pinmux));
  90057. } else {
  90058. - dev_err(&client->dev, "No platform data provided\n");
  90059. - return -EINVAL;
  90060. + dev_warn(&client->dev, "Using default platform data.\n");
  90061. + core->power_up_parameters.xcload = 0x28;
  90062. + core->power_up_parameters.func = SI476X_FUNC_FM_RECEIVER;
  90063. + core->power_up_parameters.freq = SI476X_FREQ_37P209375_MHZ;
  90064. + core->diversity_mode = SI476X_PHDIV_DISABLED;
  90065. + core->pinmux.dclk = SI476X_DCLK_DAUDIO;
  90066. + core->pinmux.dfs = SI476X_DFS_DAUDIO;
  90067. + core->pinmux.dout = SI476X_DOUT_I2S_OUTPUT;
  90068. + core->pinmux.xout = SI476X_XOUT_TRISTATE;
  90069. }
  90070. core->supplies[0].supply = "vd";
  90071. @@ -799,6 +806,10 @@
  90072. core->chip_id = id->driver_data;
  90073. + /* Power down si476x first */
  90074. + core->power_state = SI476X_POWER_UP_FULL;
  90075. + si476x_core_set_power_state(core, SI476X_POWER_DOWN);
  90076. +
  90077. rval = si476x_core_get_revision_info(core);
  90078. if (rval < 0) {
  90079. rval = -ENODEV;
  90080. diff -Nur linux-3.14.17/drivers/mfd/si476x-prop.c linux-imx6-3.14/drivers/mfd/si476x-prop.c
  90081. --- linux-3.14.17/drivers/mfd/si476x-prop.c 2014-08-14 03:38:34.000000000 +0200
  90082. +++ linux-imx6-3.14/drivers/mfd/si476x-prop.c 2014-09-11 18:06:02.910041603 +0200
  90083. @@ -217,15 +217,36 @@
  90084. return 0;
  90085. }
  90086. +static bool si476x_core_regmap_volatile_register(struct device *dev, unsigned int reg)
  90087. +{
  90088. + switch (reg) {
  90089. + case SI476X_PROP_DIGITAL_IO_OUTPUT_SAMPLE_RATE:
  90090. + case SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT:
  90091. + return false;
  90092. + default:
  90093. + return true;
  90094. + }
  90095. +
  90096. + return true;
  90097. +}
  90098. +
  90099. +/* These two register is used by the codec, so add reg_default here */
  90100. +static struct reg_default si476x_core_reg[] = {
  90101. + { 0x202, 0xBB80 },
  90102. + { 0x203, 0x1700 },
  90103. +};
  90104. static const struct regmap_config si476x_regmap_config = {
  90105. .reg_bits = 16,
  90106. .val_bits = 16,
  90107. .max_register = 0x4003,
  90108. + .reg_defaults = si476x_core_reg,
  90109. + .num_reg_defaults = ARRAY_SIZE(si476x_core_reg),
  90110. .writeable_reg = si476x_core_regmap_writable_register,
  90111. .readable_reg = si476x_core_regmap_readable_register,
  90112. + .volatile_reg = si476x_core_regmap_volatile_register,
  90113. .reg_read = si476x_core_regmap_read,
  90114. .reg_write = si476x_core_regmap_write,
  90115. diff -Nur linux-3.14.17/drivers/misc/sram.c linux-imx6-3.14/drivers/misc/sram.c
  90116. --- linux-3.14.17/drivers/misc/sram.c 2014-08-14 03:38:34.000000000 +0200
  90117. +++ linux-imx6-3.14/drivers/misc/sram.c 2014-09-11 18:06:03.010042004 +0200
  90118. @@ -29,7 +29,7 @@
  90119. #include <linux/spinlock.h>
  90120. #include <linux/genalloc.h>
  90121. -#define SRAM_GRANULARITY 32
  90122. +#define SRAM_GRANULARITY 4096
  90123. struct sram_dev {
  90124. struct gen_pool *pool;
  90125. diff -Nur linux-3.14.17/drivers/mmc/core/core.c linux-imx6-3.14/drivers/mmc/core/core.c
  90126. --- linux-3.14.17/drivers/mmc/core/core.c 2014-08-14 03:38:34.000000000 +0200
  90127. +++ linux-imx6-3.14/drivers/mmc/core/core.c 2014-09-11 18:06:03.018042035 +0200
  90128. @@ -13,11 +13,13 @@
  90129. #include <linux/module.h>
  90130. #include <linux/init.h>
  90131. #include <linux/interrupt.h>
  90132. +#include <linux/clk.h>
  90133. #include <linux/completion.h>
  90134. #include <linux/device.h>
  90135. #include <linux/delay.h>
  90136. #include <linux/pagemap.h>
  90137. #include <linux/err.h>
  90138. +#include <linux/gpio.h>
  90139. #include <linux/leds.h>
  90140. #include <linux/scatterlist.h>
  90141. #include <linux/log2.h>
  90142. @@ -1519,6 +1521,43 @@
  90143. mmc_host_clk_release(host);
  90144. }
  90145. +static void mmc_card_power_up(struct mmc_host *host)
  90146. +{
  90147. + int i;
  90148. + struct gpio_desc **gds = host->card_reset_gpios;
  90149. +
  90150. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  90151. + if (gds[i]) {
  90152. + dev_dbg(host->parent, "Asserting reset line %d", i);
  90153. + gpiod_set_value(gds[i], 1);
  90154. + }
  90155. + }
  90156. +
  90157. + if (host->card_regulator) {
  90158. + dev_dbg(host->parent, "Enabling external regulator");
  90159. + if (regulator_enable(host->card_regulator))
  90160. + dev_err(host->parent, "Failed to enable external regulator");
  90161. + }
  90162. +
  90163. + if (host->card_clk) {
  90164. + dev_dbg(host->parent, "Enabling external clock");
  90165. + clk_prepare_enable(host->card_clk);
  90166. + }
  90167. +
  90168. + /* 2ms delay to let clocks and power settle */
  90169. + mmc_delay(20);
  90170. +
  90171. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  90172. + if (gds[i]) {
  90173. + dev_dbg(host->parent, "Deasserting reset line %d", i);
  90174. + gpiod_set_value(gds[i], 0);
  90175. + }
  90176. + }
  90177. +
  90178. + /* 2ms delay to after reset release */
  90179. + mmc_delay(20);
  90180. +}
  90181. +
  90182. /*
  90183. * Apply power to the MMC stack. This is a two-stage process.
  90184. * First, we enable power to the card without the clock running.
  90185. @@ -1535,6 +1574,9 @@
  90186. if (host->ios.power_mode == MMC_POWER_ON)
  90187. return;
  90188. + /* Power up the card/module first, if needed */
  90189. + mmc_card_power_up(host);
  90190. +
  90191. mmc_host_clk_hold(host);
  90192. host->ios.vdd = fls(ocr) - 1;
  90193. diff -Nur linux-3.14.17/drivers/mmc/core/host.c linux-imx6-3.14/drivers/mmc/core/host.c
  90194. --- linux-3.14.17/drivers/mmc/core/host.c 2014-08-14 03:38:34.000000000 +0200
  90195. +++ linux-imx6-3.14/drivers/mmc/core/host.c 2014-09-11 18:06:03.018042035 +0200
  90196. @@ -12,14 +12,18 @@
  90197. * MMC host class device management
  90198. */
  90199. +#include <linux/kernel.h>
  90200. +#include <linux/clk.h>
  90201. #include <linux/device.h>
  90202. #include <linux/err.h>
  90203. +#include <linux/gpio/consumer.h>
  90204. #include <linux/idr.h>
  90205. #include <linux/of.h>
  90206. #include <linux/of_gpio.h>
  90207. #include <linux/pagemap.h>
  90208. #include <linux/export.h>
  90209. #include <linux/leds.h>
  90210. +#include <linux/regulator/consumer.h>
  90211. #include <linux/slab.h>
  90212. #include <linux/suspend.h>
  90213. @@ -439,6 +443,66 @@
  90214. EXPORT_SYMBOL(mmc_of_parse);
  90215. +static int mmc_of_parse_child(struct mmc_host *host)
  90216. +{
  90217. + struct device_node *np;
  90218. + struct clk *clk;
  90219. + int i;
  90220. +
  90221. + if (!host->parent || !host->parent->of_node)
  90222. + return 0;
  90223. +
  90224. + np = host->parent->of_node;
  90225. +
  90226. + host->card_regulator = regulator_get(host->parent, "card-external-vcc");
  90227. + if (IS_ERR(host->card_regulator)) {
  90228. + if (PTR_ERR(host->card_regulator) == -EPROBE_DEFER)
  90229. + return PTR_ERR(host->card_regulator);
  90230. + host->card_regulator = NULL;
  90231. + }
  90232. +
  90233. + /* Parse card power/reset/clock control */
  90234. + if (of_find_property(np, "card-reset-gpios", NULL)) {
  90235. + struct gpio_desc *gpd;
  90236. + int level = 0;
  90237. +
  90238. + /*
  90239. + * If the regulator is enabled, then we can hold the
  90240. + * card in reset with an active high resets. Otherwise,
  90241. + * hold the resets low.
  90242. + */
  90243. + if (host->card_regulator && regulator_is_enabled(host->card_regulator))
  90244. + level = 1;
  90245. +
  90246. + for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
  90247. + gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
  90248. + if (IS_ERR(gpd)) {
  90249. + if (PTR_ERR(gpd) == -EPROBE_DEFER)
  90250. + return PTR_ERR(gpd);
  90251. + break;
  90252. + }
  90253. + gpiod_direction_output(gpd, gpiod_is_active_low(gpd) | level);
  90254. + host->card_reset_gpios[i] = gpd;
  90255. + }
  90256. +
  90257. + gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
  90258. + if (!IS_ERR(gpd)) {
  90259. + dev_warn(host->parent, "More reset gpios than we can handle");
  90260. + gpiod_put(gpd);
  90261. + }
  90262. + }
  90263. +
  90264. + clk = of_clk_get_by_name(np, "card_ext_clock");
  90265. + if (IS_ERR(clk)) {
  90266. + if (PTR_ERR(clk) == -EPROBE_DEFER)
  90267. + return PTR_ERR(clk);
  90268. + clk = NULL;
  90269. + }
  90270. + host->card_clk = clk;
  90271. +
  90272. + return 0;
  90273. +}
  90274. +
  90275. /**
  90276. * mmc_alloc_host - initialise the per-host structure.
  90277. * @extra: sizeof private data structure
  90278. @@ -518,6 +582,10 @@
  90279. {
  90280. int err;
  90281. + err = mmc_of_parse_child(host);
  90282. + if (err)
  90283. + return err;
  90284. +
  90285. WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
  90286. !host->ops->enable_sdio_irq);
  90287. diff -Nur linux-3.14.17/drivers/mmc/core/mmc.c linux-imx6-3.14/drivers/mmc/core/mmc.c
  90288. --- linux-3.14.17/drivers/mmc/core/mmc.c 2014-08-14 03:38:34.000000000 +0200
  90289. +++ linux-imx6-3.14/drivers/mmc/core/mmc.c 2014-09-11 18:06:03.018042035 +0200
  90290. @@ -317,6 +317,11 @@
  90291. mmc_card_set_blockaddr(card);
  90292. }
  90293. + card->ext_csd.boot_info = ext_csd[EXT_CSD_BOOT_INFO];
  90294. + card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
  90295. + card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT];
  90296. + card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  90297. +
  90298. card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
  90299. mmc_select_card_type(card);
  90300. @@ -655,6 +660,372 @@
  90301. return err;
  90302. }
  90303. +static ssize_t mmc_boot_info_show(struct device *dev,
  90304. + struct device_attribute *attr, char *buf)
  90305. +{
  90306. + char *boot_partition[8] = {
  90307. + "Device not boot enabled",
  90308. + "Boot partition 1 enabled",
  90309. + "Boot partition 2 enabled",
  90310. + "Reserved",
  90311. + "Reserved",
  90312. + "Reserved",
  90313. + "Reserved",
  90314. + "User area enabled for boot"};
  90315. +
  90316. + char *bus_width[4] = {
  90317. + "x1 (sdr) or x4 (ddr) bus width in boot operation mode",
  90318. + "x4 (sdr/ddr) bus width in boot operation mode",
  90319. + "x8 (sdr/ddr) bus width in boot operation mode",
  90320. + "Reserved"};
  90321. +
  90322. + char *boot_mode[4] = {
  90323. + "Use single data rate + backward compatible timings in boot operation",
  90324. + "Use single data rate + high speed timings in boot operation mode",
  90325. + "Use dual data rate in boot operation",
  90326. + "Reserved"};
  90327. +
  90328. + int partition;
  90329. + int width;
  90330. + int mode;
  90331. + int err;
  90332. + u8 *ext_csd = NULL;
  90333. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  90334. +
  90335. + /* read it again because user may change it */
  90336. + mmc_claim_host(card->host);
  90337. + err = mmc_get_ext_csd(card, &ext_csd);
  90338. + mmc_release_host(card->host);
  90339. + if (err || !ext_csd) {
  90340. + pr_err("%s: failed to get ext_csd, err=%d\n",
  90341. + mmc_hostname(card->host),
  90342. + err);
  90343. + return err;
  90344. + }
  90345. +
  90346. + mmc_read_ext_csd(card, ext_csd);
  90347. + mmc_free_ext_csd(ext_csd);
  90348. +
  90349. + partition = (card->ext_csd.boot_config >> 3) & 0x7;
  90350. + width = card->ext_csd.boot_bus_width & 0x3;
  90351. + mode = (card->ext_csd.boot_bus_width >> 3) & 0x3;
  90352. +
  90353. + return sprintf(buf,
  90354. + "boot_info:0x%02x;\n"
  90355. + " ALT_BOOT_MODE:%x - %s\n"
  90356. + " DDR_BOOT_MODE:%x - %s\n"
  90357. + " HS_BOOTMODE:%x - %s\n"
  90358. + "boot_size:%04dKB\n"
  90359. + "boot_partition:0x%02x;\n"
  90360. + " BOOT_ACK:%x - %s\n"
  90361. + " BOOT_PARTITION-ENABLE: %x - %s\n"
  90362. + "boot_bus:0x%02x\n"
  90363. + " BOOT_MODE:%x - %s\n"
  90364. + " RESET_BOOT_BUS_WIDTH:%x - %s\n"
  90365. + " BOOT_BUS_WIDTH:%x - %s\n",
  90366. +
  90367. + card->ext_csd.boot_info,
  90368. + !!(card->ext_csd.boot_info & 0x1),
  90369. + (card->ext_csd.boot_info & 0x1) ?
  90370. + "Supports alternate boot method" :
  90371. + "Does not support alternate boot method",
  90372. + !!(card->ext_csd.boot_info & 0x2),
  90373. + (card->ext_csd.boot_info & 0x2) ?
  90374. + "Supports alternate dual data rate during boot" :
  90375. + "Does not support dual data rate during boot",
  90376. + !!(card->ext_csd.boot_info & 0x4),
  90377. + (card->ext_csd.boot_info & 0x4) ?
  90378. + "Supports high speed timing during boot" :
  90379. + "Does not support high speed timing during boot",
  90380. +
  90381. + card->ext_csd.boot_size * 128,
  90382. +
  90383. + card->ext_csd.boot_config,
  90384. + !!(card->ext_csd.boot_config & 0x40),
  90385. + (card->ext_csd.boot_config & 0x40) ?
  90386. + "Boot acknowledge sent during boot operation" :
  90387. + "No boot acknowledge sent",
  90388. + partition,
  90389. + boot_partition[partition],
  90390. +
  90391. + card->ext_csd.boot_bus_width,
  90392. + mode,
  90393. + boot_mode[mode],
  90394. + !!(card->ext_csd.boot_bus_width & 0x4),
  90395. + (card->ext_csd.boot_bus_width & 0x4) ?
  90396. + "Retain boot bus width and boot mode after boot operation" :
  90397. + "Reset bus width to x1, single data rate and backward"
  90398. + "compatible timings after boot operation",
  90399. + width,
  90400. + bus_width[width]);
  90401. +}
  90402. +
  90403. +/* set up boot partitions */
  90404. +static ssize_t
  90405. +setup_boot_partitions(struct device *dev, struct device_attribute *attr,
  90406. + const char *buf, size_t count)
  90407. +{
  90408. + int err, busy = 0;
  90409. + u32 part;
  90410. + u8 *ext_csd, boot_config;
  90411. + struct mmc_command cmd;
  90412. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  90413. +
  90414. + BUG_ON(!card);
  90415. +
  90416. + sscanf(buf, "%d\n", &part);
  90417. +
  90418. + if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
  90419. + pr_err("%s: invalid mmc version" \
  90420. + " mmc version is below version 4!)\n",
  90421. + mmc_hostname(card->host));
  90422. + return -EINVAL;
  90423. + }
  90424. +
  90425. + /* it's a normal SD/MMC but user request to configure boot partition */
  90426. + if (card->ext_csd.boot_size <= 0) {
  90427. + pr_err("%s: fail to send SWITCH command to card " \
  90428. + "to update boot_config of the EXT_CSD!\n",
  90429. + mmc_hostname(card->host));
  90430. + return -EINVAL;
  90431. + }
  90432. +
  90433. + /*
  90434. + * partition must be -
  90435. + * 0 - user area
  90436. + * 1 - boot partition 1
  90437. + * 2 - boot partition 2
  90438. + * DO NOT switch the partitions that used to be accessed
  90439. + * in OS layer HERE
  90440. + */
  90441. + if (part & EXT_CSD_BOOT_PARTITION_ACCESS_MASK) {
  90442. + pr_err("%s: DO NOT switch the partitions that used to be\n" \
  90443. + " accessed in OS layer HERE. please following the\n" \
  90444. + " guidance of Documentation/mmc/mmc-dev-parts.txt.\n",
  90445. + mmc_hostname(card->host));
  90446. + return -EINVAL;
  90447. + }
  90448. +
  90449. + ext_csd = kmalloc(512, GFP_KERNEL);
  90450. + if (!ext_csd) {
  90451. + pr_err("%s: could not allocate a buffer to " \
  90452. + "receive the ext_csd.\n", mmc_hostname(card->host));
  90453. + return -ENOMEM;
  90454. + }
  90455. +
  90456. + mmc_claim_host(card->host);
  90457. + err = mmc_send_ext_csd(card, ext_csd);
  90458. + if (err) {
  90459. + pr_err("%s: unable to read EXT_CSD.\n",
  90460. + mmc_hostname(card->host));
  90461. + goto err_rtn;
  90462. + }
  90463. +
  90464. + /* enable the boot partition in boot mode */
  90465. + /* boot enable be -
  90466. + * 0x00 - disable boot enable.
  90467. + * 0x08 - boot partition 1 is enabled for boot.
  90468. + * 0x10 - boot partition 2 is enabled for boot.
  90469. + * 0x38 - User area is enabled for boot.
  90470. + */
  90471. + switch (part & EXT_CSD_BOOT_PARTITION_ENABLE_MASK) {
  90472. + case 0:
  90473. + boot_config = (ext_csd[EXT_CSD_PART_CONFIG]
  90474. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK
  90475. + & ~EXT_CSD_BOOT_ACK_ENABLE);
  90476. + break;
  90477. + case EXT_CSD_BOOT_PARTITION_PART1:
  90478. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  90479. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  90480. + | EXT_CSD_BOOT_PARTITION_PART1
  90481. + | EXT_CSD_BOOT_ACK_ENABLE);
  90482. + break;
  90483. + case EXT_CSD_BOOT_PARTITION_PART2:
  90484. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  90485. + & ~EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  90486. + | EXT_CSD_BOOT_PARTITION_PART2
  90487. + | EXT_CSD_BOOT_ACK_ENABLE);
  90488. + break;
  90489. + case EXT_CSD_BOOT_PARTITION_ENABLE_MASK:
  90490. + boot_config = ((ext_csd[EXT_CSD_PART_CONFIG]
  90491. + | EXT_CSD_BOOT_PARTITION_ENABLE_MASK)
  90492. + & ~EXT_CSD_BOOT_ACK_ENABLE);
  90493. + break;
  90494. + default:
  90495. + pr_err("%s: wrong boot config parameter" \
  90496. + " 00 (disable boot), 08 (enable boot1)," \
  90497. + "16 (enable boot2), 56 (User area)\n",
  90498. + mmc_hostname(card->host));
  90499. + err = -EINVAL;
  90500. + goto err_rtn;
  90501. + }
  90502. +
  90503. + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  90504. + EXT_CSD_PART_CONFIG, boot_config, card->ext_csd.part_time);
  90505. + if (err) {
  90506. + pr_err("%s: fail to send SWITCH command to card " \
  90507. + "to update boot_config of the EXT_CSD!\n",
  90508. + mmc_hostname(card->host));
  90509. + goto err_rtn;
  90510. + }
  90511. +
  90512. + /* waiting for the card to finish the busy state */
  90513. + do {
  90514. + memset(&cmd, 0, sizeof(struct mmc_command));
  90515. +
  90516. + cmd.opcode = MMC_SEND_STATUS;
  90517. + cmd.arg = card->rca << 16;
  90518. + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  90519. +
  90520. + err = mmc_wait_for_cmd(card->host, &cmd, 0);
  90521. + if (err || busy > 100) {
  90522. + pr_err("%s: failed to wait for" \
  90523. + "the busy state to end.\n",
  90524. + mmc_hostname(card->host));
  90525. + break;
  90526. + }
  90527. +
  90528. + if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
  90529. + pr_info("%s: card is in busy state" \
  90530. + "pls wait for busy state to end.\n",
  90531. + mmc_hostname(card->host));
  90532. + }
  90533. + busy++;
  90534. + } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
  90535. +
  90536. + /* Now check whether it works */
  90537. + err = mmc_send_ext_csd(card, ext_csd);
  90538. + if (err) {
  90539. + pr_err("%s: %d unable to re-read EXT_CSD.\n",
  90540. + mmc_hostname(card->host), err);
  90541. + goto err_rtn;
  90542. + }
  90543. +
  90544. + card->ext_csd.boot_config = ext_csd[EXT_CSD_PART_CONFIG];
  90545. +
  90546. +err_rtn:
  90547. + mmc_release_host(card->host);
  90548. + kfree(ext_csd);
  90549. + if (err)
  90550. + return err;
  90551. + else
  90552. + return count;
  90553. +}
  90554. +
  90555. +/* configure the boot bus */
  90556. +static ssize_t
  90557. +setup_boot_bus(struct device *dev, struct device_attribute *attr,
  90558. + const char *buf, size_t count)
  90559. +{
  90560. + int err, busy = 0;
  90561. + u32 boot_bus, new_bus;
  90562. + u8 *ext_csd;
  90563. + struct mmc_command cmd;
  90564. + struct mmc_card *card = container_of(dev, struct mmc_card, dev);
  90565. +
  90566. + BUG_ON(!card);
  90567. +
  90568. + sscanf(buf, "%d\n", &boot_bus);
  90569. +
  90570. + if (card->csd.mmca_vsn < CSD_SPEC_VER_4) {
  90571. + pr_err("%s: invalid mmc version" \
  90572. + " mmc version is below version 4!)\n",
  90573. + mmc_hostname(card->host));
  90574. + return -EINVAL;
  90575. + }
  90576. +
  90577. + /* it's a normal SD/MMC but user request to configure boot bus */
  90578. + if (card->ext_csd.boot_size <= 0) {
  90579. + pr_err("%s: this is a normal SD/MMC card" \
  90580. + " but you request to configure boot bus !\n",
  90581. + mmc_hostname(card->host));
  90582. + return -EINVAL;
  90583. + }
  90584. +
  90585. + ext_csd = kmalloc(512, GFP_KERNEL);
  90586. + if (!ext_csd) {
  90587. + pr_err("%s: could not allocate a buffer to " \
  90588. + "receive the ext_csd.\n", mmc_hostname(card->host));
  90589. + return -ENOMEM;
  90590. + }
  90591. +
  90592. + mmc_claim_host(card->host);
  90593. + err = mmc_send_ext_csd(card, ext_csd);
  90594. + if (err) {
  90595. + pr_err("%s: unable to read EXT_CSD.\n",
  90596. + mmc_hostname(card->host));
  90597. + goto err_rtn;
  90598. + }
  90599. +
  90600. + /* Configure the boot bus width when boot partition is enabled */
  90601. + if (((boot_bus & EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK) >> 3) > 2
  90602. + || (boot_bus & EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK) > 2
  90603. + || (boot_bus & ~EXT_CSD_BOOT_BUS_WIDTH_MASK) > 0) {
  90604. + pr_err("%s: Invalid inputs!\n",
  90605. + mmc_hostname(card->host));
  90606. + err = -EINVAL;
  90607. + goto err_rtn;
  90608. + }
  90609. +
  90610. + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
  90611. + EXT_CSD_BOOT_BUS_WIDTH, boot_bus, card->ext_csd.part_time);
  90612. + if (err) {
  90613. + pr_err("%s: fail to send SWITCH command to card " \
  90614. + "to update boot_config of the EXT_CSD!\n",
  90615. + mmc_hostname(card->host));
  90616. + goto err_rtn;
  90617. + }
  90618. +
  90619. + /* waiting for the card to finish the busy state */
  90620. + do {
  90621. + memset(&cmd, 0, sizeof(struct mmc_command));
  90622. +
  90623. + cmd.opcode = MMC_SEND_STATUS;
  90624. + cmd.arg = card->rca << 16;
  90625. + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
  90626. +
  90627. + err = mmc_wait_for_cmd(card->host, &cmd, 0);
  90628. + if (err || busy > 100) {
  90629. + pr_err("%s: failed to wait for" \
  90630. + "the busy state to end.\n",
  90631. + mmc_hostname(card->host));
  90632. + break;
  90633. + }
  90634. +
  90635. + if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
  90636. + pr_info("%s: card is in busy state" \
  90637. + "pls wait for busy state to end.\n",
  90638. + mmc_hostname(card->host));
  90639. + }
  90640. + busy++;
  90641. + } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
  90642. +
  90643. + /* Now check whether it works */
  90644. + err = mmc_send_ext_csd(card, ext_csd);
  90645. + if (err) {
  90646. + pr_err("%s: %d unable to re-read EXT_CSD.\n",
  90647. + mmc_hostname(card->host), err);
  90648. + goto err_rtn;
  90649. + }
  90650. +
  90651. + new_bus = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  90652. + if (boot_bus != new_bus) {
  90653. + pr_err("%s: after SWITCH, current boot bus mode %d" \
  90654. + " is not same as requested bus mode %d!\n",
  90655. + mmc_hostname(card->host), new_bus, boot_bus);
  90656. + goto err_rtn;
  90657. + }
  90658. + card->ext_csd.boot_bus_width = ext_csd[EXT_CSD_BOOT_BUS_WIDTH];
  90659. +
  90660. +err_rtn:
  90661. + mmc_release_host(card->host);
  90662. + mmc_free_ext_csd(ext_csd);
  90663. + if (err)
  90664. + return err;
  90665. + else
  90666. + return count;
  90667. +}
  90668. +
  90669. MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
  90670. card->raw_cid[2], card->raw_cid[3]);
  90671. MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
  90672. @@ -674,6 +1045,9 @@
  90673. MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
  90674. MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
  90675. MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
  90676. +DEVICE_ATTR(boot_info, S_IRUGO, mmc_boot_info_show, NULL);
  90677. +DEVICE_ATTR(boot_config, S_IWUGO, NULL, setup_boot_partitions);
  90678. +DEVICE_ATTR(boot_bus_config, S_IWUGO, NULL, setup_boot_bus);
  90679. static struct attribute *mmc_std_attrs[] = {
  90680. &dev_attr_cid.attr,
  90681. @@ -692,6 +1066,9 @@
  90682. &dev_attr_enhanced_area_size.attr,
  90683. &dev_attr_raw_rpmb_size_mult.attr,
  90684. &dev_attr_rel_sectors.attr,
  90685. + &dev_attr_boot_info.attr,
  90686. + &dev_attr_boot_config.attr,
  90687. + &dev_attr_boot_bus_config.attr,
  90688. NULL,
  90689. };
  90690. diff -Nur linux-3.14.17/drivers/mmc/core/sdio_irq.c linux-imx6-3.14/drivers/mmc/core/sdio_irq.c
  90691. --- linux-3.14.17/drivers/mmc/core/sdio_irq.c 2014-08-14 03:38:34.000000000 +0200
  90692. +++ linux-imx6-3.14/drivers/mmc/core/sdio_irq.c 2014-09-11 18:06:03.022042051 +0200
  90693. @@ -90,6 +90,15 @@
  90694. return ret;
  90695. }
  90696. +void sdio_run_irqs(struct mmc_host *host)
  90697. +{
  90698. + mmc_claim_host(host);
  90699. + host->sdio_irq_pending = true;
  90700. + process_sdio_pending_irqs(host);
  90701. + mmc_release_host(host);
  90702. +}
  90703. +EXPORT_SYMBOL_GPL(sdio_run_irqs);
  90704. +
  90705. static int sdio_irq_thread(void *_host)
  90706. {
  90707. struct mmc_host *host = _host;
  90708. @@ -189,14 +198,20 @@
  90709. WARN_ON(!host->claimed);
  90710. if (!host->sdio_irqs++) {
  90711. - atomic_set(&host->sdio_irq_thread_abort, 0);
  90712. - host->sdio_irq_thread =
  90713. - kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
  90714. - mmc_hostname(host));
  90715. - if (IS_ERR(host->sdio_irq_thread)) {
  90716. - int err = PTR_ERR(host->sdio_irq_thread);
  90717. - host->sdio_irqs--;
  90718. - return err;
  90719. + if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
  90720. + atomic_set(&host->sdio_irq_thread_abort, 0);
  90721. + host->sdio_irq_thread =
  90722. + kthread_run(sdio_irq_thread, host,
  90723. + "ksdioirqd/%s", mmc_hostname(host));
  90724. + if (IS_ERR(host->sdio_irq_thread)) {
  90725. + int err = PTR_ERR(host->sdio_irq_thread);
  90726. + host->sdio_irqs--;
  90727. + return err;
  90728. + }
  90729. + } else {
  90730. + mmc_host_clk_hold(host);
  90731. + host->ops->enable_sdio_irq(host, 1);
  90732. + mmc_host_clk_release(host);
  90733. }
  90734. }
  90735. @@ -211,8 +226,14 @@
  90736. BUG_ON(host->sdio_irqs < 1);
  90737. if (!--host->sdio_irqs) {
  90738. - atomic_set(&host->sdio_irq_thread_abort, 1);
  90739. - kthread_stop(host->sdio_irq_thread);
  90740. + if (!(host->caps2 & MMC_CAP2_SDIO_NOTHREAD)) {
  90741. + atomic_set(&host->sdio_irq_thread_abort, 1);
  90742. + kthread_stop(host->sdio_irq_thread);
  90743. + } else {
  90744. + mmc_host_clk_hold(host);
  90745. + host->ops->enable_sdio_irq(host, 0);
  90746. + mmc_host_clk_release(host);
  90747. + }
  90748. }
  90749. return 0;
  90750. diff -Nur linux-3.14.17/drivers/mmc/host/dw_mmc.c linux-imx6-3.14/drivers/mmc/host/dw_mmc.c
  90751. --- linux-3.14.17/drivers/mmc/host/dw_mmc.c 2014-08-14 03:38:34.000000000 +0200
  90752. +++ linux-imx6-3.14/drivers/mmc/host/dw_mmc.c 2014-09-11 18:06:03.026042067 +0200
  90753. @@ -2140,6 +2140,8 @@
  90754. if (!mmc)
  90755. return -ENOMEM;
  90756. + mmc_of_parse(mmc);
  90757. +
  90758. slot = mmc_priv(mmc);
  90759. slot->id = id;
  90760. slot->mmc = mmc;
  90761. diff -Nur linux-3.14.17/drivers/mmc/host/Kconfig linux-imx6-3.14/drivers/mmc/host/Kconfig
  90762. --- linux-3.14.17/drivers/mmc/host/Kconfig 2014-08-14 03:38:34.000000000 +0200
  90763. +++ linux-imx6-3.14/drivers/mmc/host/Kconfig 2014-09-11 18:06:03.022042051 +0200
  90764. @@ -25,8 +25,7 @@
  90765. If unsure, say N.
  90766. config MMC_SDHCI
  90767. - tristate "Secure Digital Host Controller Interface support"
  90768. - depends on HAS_DMA
  90769. + tristate
  90770. help
  90771. This selects the generic Secure Digital Host Controller Interface.
  90772. It is used by manufacturers such as Texas Instruments(R), Ricoh(R)
  90773. @@ -59,7 +58,8 @@
  90774. config MMC_SDHCI_PCI
  90775. tristate "SDHCI support on PCI bus"
  90776. - depends on MMC_SDHCI && PCI
  90777. + depends on PCI && HAS_DMA
  90778. + select MMC_SDHCI
  90779. help
  90780. This selects the PCI Secure Digital Host Controller Interface.
  90781. Most controllers found today are PCI devices.
  90782. @@ -83,7 +83,8 @@
  90783. config MMC_SDHCI_ACPI
  90784. tristate "SDHCI support for ACPI enumerated SDHCI controllers"
  90785. - depends on MMC_SDHCI && ACPI
  90786. + depends on ACPI && HAS_DMA
  90787. + select MMC_SDHCI
  90788. help
  90789. This selects support for ACPI enumerated SDHCI controllers,
  90790. identified by ACPI Compatibility ID PNP0D40 or specific
  90791. @@ -94,8 +95,8 @@
  90792. If unsure, say N.
  90793. config MMC_SDHCI_PLTFM
  90794. - tristate "SDHCI platform and OF driver helper"
  90795. - depends on MMC_SDHCI
  90796. + tristate
  90797. + select MMC_SDHCI
  90798. help
  90799. This selects the common helper functions support for Secure Digital
  90800. Host Controller Interface based platform and OF drivers.
  90801. @@ -106,8 +107,8 @@
  90802. config MMC_SDHCI_OF_ARASAN
  90803. tristate "SDHCI OF support for the Arasan SDHCI controllers"
  90804. - depends on MMC_SDHCI_PLTFM
  90805. - depends on OF
  90806. + depends on OF && HAS_DMA
  90807. + select MMC_SDHCI_PLTFM
  90808. help
  90809. This selects the Arasan Secure Digital Host Controller Interface
  90810. (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC.
  90811. @@ -118,9 +119,9 @@
  90812. config MMC_SDHCI_OF_ESDHC
  90813. tristate "SDHCI OF support for the Freescale eSDHC controller"
  90814. - depends on MMC_SDHCI_PLTFM
  90815. - depends on PPC_OF
  90816. + depends on PPC_OF && HAS_DMA
  90817. select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
  90818. + select MMC_SDHCI_PLTFM
  90819. help
  90820. This selects the Freescale eSDHC controller support.
  90821. @@ -130,9 +131,9 @@
  90822. config MMC_SDHCI_OF_HLWD
  90823. tristate "SDHCI OF support for the Nintendo Wii SDHCI controllers"
  90824. - depends on MMC_SDHCI_PLTFM
  90825. - depends on PPC_OF
  90826. + depends on PPC_OF && HAS_DMA
  90827. select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
  90828. + select MMC_SDHCI_PLTFM
  90829. help
  90830. This selects the Secure Digital Host Controller Interface (SDHCI)
  90831. found in the "Hollywood" chipset of the Nintendo Wii video game
  90832. @@ -144,8 +145,8 @@
  90833. config MMC_SDHCI_CNS3XXX
  90834. tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
  90835. - depends on ARCH_CNS3XXX
  90836. - depends on MMC_SDHCI_PLTFM
  90837. + depends on ARCH_CNS3XXX && HAS_DMA
  90838. + select MMC_SDHCI_PLTFM
  90839. help
  90840. This selects the SDHCI support for CNS3xxx System-on-Chip devices.
  90841. @@ -155,9 +156,9 @@
  90842. config MMC_SDHCI_ESDHC_IMX
  90843. tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller"
  90844. - depends on ARCH_MXC
  90845. - depends on MMC_SDHCI_PLTFM
  90846. + depends on ARCH_MXC && HAS_DMA
  90847. select MMC_SDHCI_IO_ACCESSORS
  90848. + select MMC_SDHCI_PLTFM
  90849. help
  90850. This selects the Freescale eSDHC/uSDHC controller support
  90851. found on i.MX25, i.MX35 i.MX5x and i.MX6x.
  90852. @@ -168,9 +169,9 @@
  90853. config MMC_SDHCI_DOVE
  90854. tristate "SDHCI support on Marvell's Dove SoC"
  90855. - depends on ARCH_DOVE
  90856. - depends on MMC_SDHCI_PLTFM
  90857. + depends on ARCH_DOVE && HAS_DMA
  90858. select MMC_SDHCI_IO_ACCESSORS
  90859. + select MMC_SDHCI_PLTFM
  90860. help
  90861. This selects the Secure Digital Host Controller Interface in
  90862. Marvell's Dove SoC.
  90863. @@ -181,9 +182,9 @@
  90864. config MMC_SDHCI_TEGRA
  90865. tristate "SDHCI platform support for the Tegra SD/MMC Controller"
  90866. - depends on ARCH_TEGRA
  90867. - depends on MMC_SDHCI_PLTFM
  90868. + depends on ARCH_TEGRA && HAS_DMA
  90869. select MMC_SDHCI_IO_ACCESSORS
  90870. + select MMC_SDHCI_PLTFM
  90871. help
  90872. This selects the Tegra SD/MMC controller. If you have a Tegra
  90873. platform with SD or MMC devices, say Y or M here.
  90874. @@ -192,7 +193,8 @@
  90875. config MMC_SDHCI_S3C
  90876. tristate "SDHCI support on Samsung S3C SoC"
  90877. - depends on MMC_SDHCI && PLAT_SAMSUNG
  90878. + depends on PLAT_SAMSUNG && HAS_DMA
  90879. + select MMC_SDHCI
  90880. help
  90881. This selects the Secure Digital Host Controller Interface (SDHCI)
  90882. often referrered to as the HSMMC block in some of the Samsung S3C
  90883. @@ -204,8 +206,8 @@
  90884. config MMC_SDHCI_SIRF
  90885. tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs"
  90886. - depends on ARCH_SIRF
  90887. - depends on MMC_SDHCI_PLTFM
  90888. + depends on ARCH_SIRF && HAS_DMA
  90889. + select MMC_SDHCI_PLTFM
  90890. help
  90891. This selects the SDHCI support for SiRF System-on-Chip devices.
  90892. @@ -215,8 +217,7 @@
  90893. config MMC_SDHCI_PXAV3
  90894. tristate "Marvell MMP2 SD Host Controller support (PXAV3)"
  90895. - depends on CLKDEV_LOOKUP
  90896. - select MMC_SDHCI
  90897. + depends on CLKDEV_LOOKUP && HAS_DMA
  90898. select MMC_SDHCI_PLTFM
  90899. default CPU_MMP2
  90900. help
  90901. @@ -228,8 +229,7 @@
  90902. config MMC_SDHCI_PXAV2
  90903. tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
  90904. - depends on CLKDEV_LOOKUP
  90905. - select MMC_SDHCI
  90906. + depends on CLKDEV_LOOKUP && HAS_DMA
  90907. select MMC_SDHCI_PLTFM
  90908. default CPU_PXA910
  90909. help
  90910. @@ -241,7 +241,8 @@
  90911. config MMC_SDHCI_SPEAR
  90912. tristate "SDHCI support on ST SPEAr platform"
  90913. - depends on MMC_SDHCI && PLAT_SPEAR
  90914. + depends on PLAT_SPEAR && HAS_DMA
  90915. + select MMC_SDHCI
  90916. help
  90917. This selects the Secure Digital Host Controller Interface (SDHCI)
  90918. often referrered to as the HSMMC block in some of the ST SPEAR range
  90919. @@ -263,7 +264,7 @@
  90920. config MMC_SDHCI_BCM_KONA
  90921. tristate "SDHCI support on Broadcom KONA platform"
  90922. - depends on ARCH_BCM
  90923. + depends on ARCH_BCM && HAS_DMA
  90924. select MMC_SDHCI_PLTFM
  90925. help
  90926. This selects the Broadcom Kona Secure Digital Host Controller
  90927. @@ -274,9 +275,9 @@
  90928. config MMC_SDHCI_BCM2835
  90929. tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
  90930. - depends on ARCH_BCM2835
  90931. - depends on MMC_SDHCI_PLTFM
  90932. + depends on ARCH_BCM2835 && HAS_DMA
  90933. select MMC_SDHCI_IO_ACCESSORS
  90934. + select MMC_SDHCI_PLTFM
  90935. help
  90936. This selects the BCM2835 SD/MMC controller. If you have a BCM2835
  90937. platform with SD or MMC devices, say Y or M here.
  90938. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-acpi.c linux-imx6-3.14/drivers/mmc/host/sdhci-acpi.c
  90939. --- linux-3.14.17/drivers/mmc/host/sdhci-acpi.c 2014-08-14 03:38:34.000000000 +0200
  90940. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-acpi.c 2014-09-11 18:06:03.030042084 +0200
  90941. @@ -101,11 +101,19 @@
  90942. }
  90943. static const struct sdhci_ops sdhci_acpi_ops_dflt = {
  90944. + .set_clock = sdhci_set_clock,
  90945. .enable_dma = sdhci_acpi_enable_dma,
  90946. + .set_bus_width = sdhci_set_bus_width,
  90947. + .reset = sdhci_reset,
  90948. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90949. };
  90950. static const struct sdhci_ops sdhci_acpi_ops_int = {
  90951. + .set_clock = sdhci_set_clock,
  90952. .enable_dma = sdhci_acpi_enable_dma,
  90953. + .set_bus_width = sdhci_set_bus_width,
  90954. + .reset = sdhci_reset,
  90955. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90956. .hw_reset = sdhci_acpi_int_hw_reset,
  90957. };
  90958. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-bcm2835.c linux-imx6-3.14/drivers/mmc/host/sdhci-bcm2835.c
  90959. --- linux-3.14.17/drivers/mmc/host/sdhci-bcm2835.c 2014-08-14 03:38:34.000000000 +0200
  90960. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-bcm2835.c 2014-09-11 18:06:03.030042084 +0200
  90961. @@ -131,8 +131,12 @@
  90962. .read_l = bcm2835_sdhci_readl,
  90963. .read_w = bcm2835_sdhci_readw,
  90964. .read_b = bcm2835_sdhci_readb,
  90965. + .set_clock = sdhci_set_clock,
  90966. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  90967. .get_min_clock = bcm2835_sdhci_get_min_clock,
  90968. + .set_bus_width = sdhci_set_bus_width,
  90969. + .reset = sdhci_reset,
  90970. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90971. };
  90972. static const struct sdhci_pltfm_data bcm2835_sdhci_pdata = {
  90973. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-bcm-kona.c linux-imx6-3.14/drivers/mmc/host/sdhci-bcm-kona.c
  90974. --- linux-3.14.17/drivers/mmc/host/sdhci-bcm-kona.c 2014-08-14 03:38:34.000000000 +0200
  90975. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-bcm-kona.c 2014-09-11 18:06:03.030042084 +0200
  90976. @@ -205,9 +205,13 @@
  90977. }
  90978. static struct sdhci_ops sdhci_bcm_kona_ops = {
  90979. + .set_clock = sdhci_set_clock,
  90980. .get_max_clock = sdhci_bcm_kona_get_max_clk,
  90981. .get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
  90982. .platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
  90983. + .set_bus_width = sdhci_set_bus_width,
  90984. + .reset = sdhci_reset,
  90985. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  90986. .card_event = sdhci_bcm_kona_card_event,
  90987. };
  90988. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci.c linux-imx6-3.14/drivers/mmc/host/sdhci.c
  90989. --- linux-3.14.17/drivers/mmc/host/sdhci.c 2014-08-14 03:38:34.000000000 +0200
  90990. +++ linux-imx6-3.14/drivers/mmc/host/sdhci.c 2014-09-11 18:06:03.034042099 +0200
  90991. @@ -44,6 +44,8 @@
  90992. #define MAX_TUNING_LOOP 40
  90993. +#define ADMA_SIZE ((128 * 2 + 1) * 4)
  90994. +
  90995. static unsigned int debug_quirks = 0;
  90996. static unsigned int debug_quirks2;
  90997. @@ -131,43 +133,28 @@
  90998. * *
  90999. \*****************************************************************************/
  91000. -static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
  91001. -{
  91002. - u32 ier;
  91003. -
  91004. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  91005. - ier &= ~clear;
  91006. - ier |= set;
  91007. - sdhci_writel(host, ier, SDHCI_INT_ENABLE);
  91008. - sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
  91009. -}
  91010. -
  91011. -static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
  91012. -{
  91013. - sdhci_clear_set_irqs(host, 0, irqs);
  91014. -}
  91015. -
  91016. -static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
  91017. -{
  91018. - sdhci_clear_set_irqs(host, irqs, 0);
  91019. -}
  91020. -
  91021. static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
  91022. {
  91023. - u32 present, irqs;
  91024. + u32 present;
  91025. + int gpio_cd = mmc_gpio_get_cd(host->mmc);
  91026. if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
  91027. - (host->mmc->caps & MMC_CAP_NONREMOVABLE))
  91028. + (host->mmc->caps & MMC_CAP_NONREMOVABLE) ||
  91029. + !IS_ERR_VALUE(gpio_cd))
  91030. return;
  91031. - present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  91032. - SDHCI_CARD_PRESENT;
  91033. - irqs = present ? SDHCI_INT_CARD_REMOVE : SDHCI_INT_CARD_INSERT;
  91034. + if (enable) {
  91035. + present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  91036. + SDHCI_CARD_PRESENT;
  91037. - if (enable)
  91038. - sdhci_unmask_irqs(host, irqs);
  91039. - else
  91040. - sdhci_mask_irqs(host, irqs);
  91041. + host->ier |= present ? SDHCI_INT_CARD_REMOVE :
  91042. + SDHCI_INT_CARD_INSERT;
  91043. + } else {
  91044. + host->ier &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
  91045. + }
  91046. +
  91047. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  91048. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  91049. }
  91050. static void sdhci_enable_card_detection(struct sdhci_host *host)
  91051. @@ -180,22 +167,9 @@
  91052. sdhci_set_card_detection(host, false);
  91053. }
  91054. -static void sdhci_reset(struct sdhci_host *host, u8 mask)
  91055. +void sdhci_reset(struct sdhci_host *host, u8 mask)
  91056. {
  91057. unsigned long timeout;
  91058. - u32 uninitialized_var(ier);
  91059. -
  91060. - if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
  91061. - if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
  91062. - SDHCI_CARD_PRESENT))
  91063. - return;
  91064. - }
  91065. -
  91066. - if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  91067. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  91068. -
  91069. - if (host->ops->platform_reset_enter)
  91070. - host->ops->platform_reset_enter(host, mask);
  91071. sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
  91072. @@ -220,16 +194,27 @@
  91073. timeout--;
  91074. mdelay(1);
  91075. }
  91076. +}
  91077. +EXPORT_SYMBOL_GPL(sdhci_reset);
  91078. - if (host->ops->platform_reset_exit)
  91079. - host->ops->platform_reset_exit(host, mask);
  91080. +static void sdhci_do_reset(struct sdhci_host *host, u8 mask)
  91081. +{
  91082. + if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
  91083. + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
  91084. + SDHCI_CARD_PRESENT))
  91085. + return;
  91086. + }
  91087. - if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  91088. - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
  91089. + host->ops->reset(host, mask);
  91090. - if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
  91091. - if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
  91092. - host->ops->enable_dma(host);
  91093. + if (mask & SDHCI_RESET_ALL) {
  91094. + if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
  91095. + if (host->ops->enable_dma)
  91096. + host->ops->enable_dma(host);
  91097. + }
  91098. +
  91099. + /* Resetting the controller clears many */
  91100. + host->preset_enabled = false;
  91101. }
  91102. }
  91103. @@ -238,15 +223,18 @@
  91104. static void sdhci_init(struct sdhci_host *host, int soft)
  91105. {
  91106. if (soft)
  91107. - sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
  91108. + sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
  91109. else
  91110. - sdhci_reset(host, SDHCI_RESET_ALL);
  91111. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  91112. - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
  91113. - SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
  91114. - SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
  91115. - SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
  91116. - SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
  91117. + host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
  91118. + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
  91119. + SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
  91120. + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
  91121. + SDHCI_INT_RESPONSE;
  91122. +
  91123. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  91124. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  91125. if (soft) {
  91126. /* force clock reconfiguration */
  91127. @@ -502,11 +490,6 @@
  91128. else
  91129. direction = DMA_TO_DEVICE;
  91130. - /*
  91131. - * The ADMA descriptor table is mapped further down as we
  91132. - * need to fill it with data first.
  91133. - */
  91134. -
  91135. host->align_addr = dma_map_single(mmc_dev(host->mmc),
  91136. host->align_buffer, 128 * 4, direction);
  91137. if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr))
  91138. @@ -567,7 +550,7 @@
  91139. * If this triggers then we have a calculation bug
  91140. * somewhere. :/
  91141. */
  91142. - WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4);
  91143. + WARN_ON((desc - host->adma_desc) > ADMA_SIZE);
  91144. }
  91145. if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) {
  91146. @@ -595,17 +578,8 @@
  91147. host->align_addr, 128 * 4, direction);
  91148. }
  91149. - host->adma_addr = dma_map_single(mmc_dev(host->mmc),
  91150. - host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE);
  91151. - if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr))
  91152. - goto unmap_entries;
  91153. - BUG_ON(host->adma_addr & 0x3);
  91154. -
  91155. return 0;
  91156. -unmap_entries:
  91157. - dma_unmap_sg(mmc_dev(host->mmc), data->sg,
  91158. - data->sg_len, direction);
  91159. unmap_align:
  91160. dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
  91161. 128 * 4, direction);
  91162. @@ -623,19 +597,25 @@
  91163. u8 *align;
  91164. char *buffer;
  91165. unsigned long flags;
  91166. + bool has_unaligned;
  91167. if (data->flags & MMC_DATA_READ)
  91168. direction = DMA_FROM_DEVICE;
  91169. else
  91170. direction = DMA_TO_DEVICE;
  91171. - dma_unmap_single(mmc_dev(host->mmc), host->adma_addr,
  91172. - (128 * 2 + 1) * 4, DMA_TO_DEVICE);
  91173. -
  91174. dma_unmap_single(mmc_dev(host->mmc), host->align_addr,
  91175. 128 * 4, direction);
  91176. - if (data->flags & MMC_DATA_READ) {
  91177. + /* Do a quick scan of the SG list for any unaligned mappings */
  91178. + has_unaligned = false;
  91179. + for_each_sg(data->sg, sg, host->sg_count, i)
  91180. + if (sg_dma_address(sg) & 3) {
  91181. + has_unaligned = true;
  91182. + break;
  91183. + }
  91184. +
  91185. + if (has_unaligned && data->flags & MMC_DATA_READ) {
  91186. dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg,
  91187. data->sg_len, direction);
  91188. @@ -721,9 +701,12 @@
  91189. u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
  91190. if (host->flags & SDHCI_REQ_USE_DMA)
  91191. - sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
  91192. + host->ier = (host->ier & ~pio_irqs) | dma_irqs;
  91193. else
  91194. - sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
  91195. + host->ier = (host->ier & ~dma_irqs) | pio_irqs;
  91196. +
  91197. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  91198. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  91199. }
  91200. static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
  91201. @@ -976,8 +959,8 @@
  91202. * upon error conditions.
  91203. */
  91204. if (data->error) {
  91205. - sdhci_reset(host, SDHCI_RESET_CMD);
  91206. - sdhci_reset(host, SDHCI_RESET_DATA);
  91207. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  91208. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  91209. }
  91210. sdhci_send_command(host, data->stop);
  91211. @@ -1107,24 +1090,23 @@
  91212. static u16 sdhci_get_preset_value(struct sdhci_host *host)
  91213. {
  91214. - u16 ctrl, preset = 0;
  91215. -
  91216. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91217. + u16 preset = 0;
  91218. - switch (ctrl & SDHCI_CTRL_UHS_MASK) {
  91219. - case SDHCI_CTRL_UHS_SDR12:
  91220. + switch (host->timing) {
  91221. + case MMC_TIMING_UHS_SDR12:
  91222. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12);
  91223. break;
  91224. - case SDHCI_CTRL_UHS_SDR25:
  91225. + case MMC_TIMING_UHS_SDR25:
  91226. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25);
  91227. break;
  91228. - case SDHCI_CTRL_UHS_SDR50:
  91229. + case MMC_TIMING_UHS_SDR50:
  91230. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50);
  91231. break;
  91232. - case SDHCI_CTRL_UHS_SDR104:
  91233. + case MMC_TIMING_UHS_SDR104:
  91234. + case MMC_TIMING_MMC_HS200:
  91235. preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
  91236. break;
  91237. - case SDHCI_CTRL_UHS_DDR50:
  91238. + case MMC_TIMING_UHS_DDR50:
  91239. preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
  91240. break;
  91241. default:
  91242. @@ -1136,32 +1118,22 @@
  91243. return preset;
  91244. }
  91245. -static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
  91246. +void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
  91247. {
  91248. int div = 0; /* Initialized for compiler warning */
  91249. int real_div = div, clk_mul = 1;
  91250. u16 clk = 0;
  91251. unsigned long timeout;
  91252. - if (clock && clock == host->clock)
  91253. - return;
  91254. -
  91255. host->mmc->actual_clock = 0;
  91256. - if (host->ops->set_clock) {
  91257. - host->ops->set_clock(host, clock);
  91258. - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
  91259. - return;
  91260. - }
  91261. -
  91262. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  91263. if (clock == 0)
  91264. - goto out;
  91265. + return;
  91266. if (host->version >= SDHCI_SPEC_300) {
  91267. - if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
  91268. - SDHCI_CTRL_PRESET_VAL_ENABLE) {
  91269. + if (host->preset_enabled) {
  91270. u16 pre_val;
  91271. clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
  91272. @@ -1247,26 +1219,16 @@
  91273. clk |= SDHCI_CLOCK_CARD_EN;
  91274. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  91275. -
  91276. -out:
  91277. - host->clock = clock;
  91278. -}
  91279. -
  91280. -static inline void sdhci_update_clock(struct sdhci_host *host)
  91281. -{
  91282. - unsigned int clock;
  91283. -
  91284. - clock = host->clock;
  91285. - host->clock = 0;
  91286. - sdhci_set_clock(host, clock);
  91287. }
  91288. +EXPORT_SYMBOL_GPL(sdhci_set_clock);
  91289. -static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
  91290. +static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
  91291. + unsigned short vdd)
  91292. {
  91293. u8 pwr = 0;
  91294. - if (power != (unsigned short)-1) {
  91295. - switch (1 << power) {
  91296. + if (mode != MMC_POWER_OFF) {
  91297. + switch (1 << vdd) {
  91298. case MMC_VDD_165_195:
  91299. pwr = SDHCI_POWER_180;
  91300. break;
  91301. @@ -1284,7 +1246,7 @@
  91302. }
  91303. if (host->pwr == pwr)
  91304. - return -1;
  91305. + return;
  91306. host->pwr = pwr;
  91307. @@ -1292,38 +1254,43 @@
  91308. sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  91309. if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  91310. sdhci_runtime_pm_bus_off(host);
  91311. - return 0;
  91312. - }
  91313. -
  91314. - /*
  91315. - * Spec says that we should clear the power reg before setting
  91316. - * a new value. Some controllers don't seem to like this though.
  91317. - */
  91318. - if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
  91319. - sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  91320. + vdd = 0;
  91321. + } else {
  91322. + /*
  91323. + * Spec says that we should clear the power reg before setting
  91324. + * a new value. Some controllers don't seem to like this though.
  91325. + */
  91326. + if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
  91327. + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
  91328. - /*
  91329. - * At least the Marvell CaFe chip gets confused if we set the voltage
  91330. - * and set turn on power at the same time, so set the voltage first.
  91331. - */
  91332. - if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
  91333. - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  91334. + /*
  91335. + * At least the Marvell CaFe chip gets confused if we set the
  91336. + * voltage and set turn on power at the same time, so set the
  91337. + * voltage first.
  91338. + */
  91339. + if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)
  91340. + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  91341. - pwr |= SDHCI_POWER_ON;
  91342. + pwr |= SDHCI_POWER_ON;
  91343. - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  91344. + sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
  91345. - if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  91346. - sdhci_runtime_pm_bus_on(host);
  91347. + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
  91348. + sdhci_runtime_pm_bus_on(host);
  91349. - /*
  91350. - * Some controllers need an extra 10ms delay of 10ms before they
  91351. - * can apply clock after applying power
  91352. - */
  91353. - if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
  91354. - mdelay(10);
  91355. + /*
  91356. + * Some controllers need an extra 10ms delay of 10ms before
  91357. + * they can apply clock after applying power
  91358. + */
  91359. + if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
  91360. + mdelay(10);
  91361. + }
  91362. - return power;
  91363. + if (host->vmmc) {
  91364. + spin_unlock_irq(&host->lock);
  91365. + mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd);
  91366. + spin_lock_irq(&host->lock);
  91367. + }
  91368. }
  91369. /*****************************************************************************\
  91370. @@ -1427,10 +1394,52 @@
  91371. spin_unlock_irqrestore(&host->lock, flags);
  91372. }
  91373. +void sdhci_set_bus_width(struct sdhci_host *host, int width)
  91374. +{
  91375. + u8 ctrl;
  91376. +
  91377. + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  91378. + if (width == MMC_BUS_WIDTH_8) {
  91379. + ctrl &= ~SDHCI_CTRL_4BITBUS;
  91380. + if (host->version >= SDHCI_SPEC_300)
  91381. + ctrl |= SDHCI_CTRL_8BITBUS;
  91382. + } else {
  91383. + if (host->version >= SDHCI_SPEC_300)
  91384. + ctrl &= ~SDHCI_CTRL_8BITBUS;
  91385. + if (width == MMC_BUS_WIDTH_4)
  91386. + ctrl |= SDHCI_CTRL_4BITBUS;
  91387. + else
  91388. + ctrl &= ~SDHCI_CTRL_4BITBUS;
  91389. + }
  91390. + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  91391. +}
  91392. +EXPORT_SYMBOL_GPL(sdhci_set_bus_width);
  91393. +
  91394. +void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
  91395. +{
  91396. + u16 ctrl_2;
  91397. +
  91398. + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91399. + /* Select Bus Speed Mode for host */
  91400. + ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  91401. + if ((timing == MMC_TIMING_MMC_HS200) ||
  91402. + (timing == MMC_TIMING_UHS_SDR104))
  91403. + ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  91404. + else if (timing == MMC_TIMING_UHS_SDR12)
  91405. + ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  91406. + else if (timing == MMC_TIMING_UHS_SDR25)
  91407. + ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  91408. + else if (timing == MMC_TIMING_UHS_SDR50)
  91409. + ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  91410. + else if (timing == MMC_TIMING_UHS_DDR50)
  91411. + ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  91412. + sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  91413. +}
  91414. +EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
  91415. +
  91416. static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
  91417. {
  91418. unsigned long flags;
  91419. - int vdd_bit = -1;
  91420. u8 ctrl;
  91421. spin_lock_irqsave(&host->lock, flags);
  91422. @@ -1456,45 +1465,17 @@
  91423. !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN))
  91424. sdhci_enable_preset_value(host, false);
  91425. - sdhci_set_clock(host, ios->clock);
  91426. -
  91427. - if (ios->power_mode == MMC_POWER_OFF)
  91428. - vdd_bit = sdhci_set_power(host, -1);
  91429. - else
  91430. - vdd_bit = sdhci_set_power(host, ios->vdd);
  91431. -
  91432. - if (host->vmmc && vdd_bit != -1) {
  91433. - spin_unlock_irqrestore(&host->lock, flags);
  91434. - mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
  91435. - spin_lock_irqsave(&host->lock, flags);
  91436. + if (!ios->clock || ios->clock != host->clock) {
  91437. + host->ops->set_clock(host, ios->clock);
  91438. + host->clock = ios->clock;
  91439. }
  91440. + sdhci_set_power(host, ios->power_mode, ios->vdd);
  91441. +
  91442. if (host->ops->platform_send_init_74_clocks)
  91443. host->ops->platform_send_init_74_clocks(host, ios->power_mode);
  91444. - /*
  91445. - * If your platform has 8-bit width support but is not a v3 controller,
  91446. - * or if it requires special setup code, you should implement that in
  91447. - * platform_bus_width().
  91448. - */
  91449. - if (host->ops->platform_bus_width) {
  91450. - host->ops->platform_bus_width(host, ios->bus_width);
  91451. - } else {
  91452. - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  91453. - if (ios->bus_width == MMC_BUS_WIDTH_8) {
  91454. - ctrl &= ~SDHCI_CTRL_4BITBUS;
  91455. - if (host->version >= SDHCI_SPEC_300)
  91456. - ctrl |= SDHCI_CTRL_8BITBUS;
  91457. - } else {
  91458. - if (host->version >= SDHCI_SPEC_300)
  91459. - ctrl &= ~SDHCI_CTRL_8BITBUS;
  91460. - if (ios->bus_width == MMC_BUS_WIDTH_4)
  91461. - ctrl |= SDHCI_CTRL_4BITBUS;
  91462. - else
  91463. - ctrl &= ~SDHCI_CTRL_4BITBUS;
  91464. - }
  91465. - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  91466. - }
  91467. + host->ops->set_bus_width(host, ios->bus_width);
  91468. ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
  91469. @@ -1516,13 +1497,13 @@
  91470. (ios->timing == MMC_TIMING_UHS_SDR25))
  91471. ctrl |= SDHCI_CTRL_HISPD;
  91472. - ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91473. - if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  91474. + if (!host->preset_enabled) {
  91475. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  91476. /*
  91477. * We only need to set Driver Strength if the
  91478. * preset value enable is not set.
  91479. */
  91480. + ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91481. ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
  91482. if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
  91483. ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
  91484. @@ -1546,34 +1527,16 @@
  91485. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  91486. /* Re-enable SD Clock */
  91487. - sdhci_update_clock(host);
  91488. + host->ops->set_clock(host, host->clock);
  91489. }
  91490. -
  91491. /* Reset SD Clock Enable */
  91492. clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
  91493. clk &= ~SDHCI_CLOCK_CARD_EN;
  91494. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  91495. - if (host->ops->set_uhs_signaling)
  91496. - host->ops->set_uhs_signaling(host, ios->timing);
  91497. - else {
  91498. - ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91499. - /* Select Bus Speed Mode for host */
  91500. - ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
  91501. - if ((ios->timing == MMC_TIMING_MMC_HS200) ||
  91502. - (ios->timing == MMC_TIMING_UHS_SDR104))
  91503. - ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
  91504. - else if (ios->timing == MMC_TIMING_UHS_SDR12)
  91505. - ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
  91506. - else if (ios->timing == MMC_TIMING_UHS_SDR25)
  91507. - ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
  91508. - else if (ios->timing == MMC_TIMING_UHS_SDR50)
  91509. - ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
  91510. - else if (ios->timing == MMC_TIMING_UHS_DDR50)
  91511. - ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
  91512. - sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
  91513. - }
  91514. + host->ops->set_uhs_signaling(host, ios->timing);
  91515. + host->timing = ios->timing;
  91516. if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
  91517. ((ios->timing == MMC_TIMING_UHS_SDR12) ||
  91518. @@ -1589,8 +1552,7 @@
  91519. >> SDHCI_PRESET_DRV_SHIFT;
  91520. }
  91521. - /* Re-enable SD Clock */
  91522. - sdhci_update_clock(host);
  91523. + host->ops->set_clock(host, host->clock);
  91524. } else
  91525. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  91526. @@ -1600,7 +1562,7 @@
  91527. * it on each ios seems to solve the problem.
  91528. */
  91529. if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
  91530. - sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
  91531. + sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
  91532. mmiowb();
  91533. spin_unlock_irqrestore(&host->lock, flags);
  91534. @@ -1709,24 +1671,16 @@
  91535. static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable)
  91536. {
  91537. - if (host->flags & SDHCI_DEVICE_DEAD)
  91538. - goto out;
  91539. -
  91540. - if (enable)
  91541. - host->flags |= SDHCI_SDIO_IRQ_ENABLED;
  91542. - else
  91543. - host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
  91544. -
  91545. - /* SDIO IRQ will be enabled as appropriate in runtime resume */
  91546. - if (host->runtime_suspended)
  91547. - goto out;
  91548. + if (!(host->flags & SDHCI_DEVICE_DEAD)) {
  91549. + if (enable)
  91550. + host->ier |= SDHCI_INT_CARD_INT;
  91551. + else
  91552. + host->ier &= ~SDHCI_INT_CARD_INT;
  91553. - if (enable)
  91554. - sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
  91555. - else
  91556. - sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
  91557. -out:
  91558. - mmiowb();
  91559. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  91560. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  91561. + mmiowb();
  91562. + }
  91563. }
  91564. static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
  91565. @@ -1734,9 +1688,18 @@
  91566. struct sdhci_host *host = mmc_priv(mmc);
  91567. unsigned long flags;
  91568. + sdhci_runtime_pm_get(host);
  91569. +
  91570. spin_lock_irqsave(&host->lock, flags);
  91571. + if (enable)
  91572. + host->flags |= SDHCI_SDIO_IRQ_ENABLED;
  91573. + else
  91574. + host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
  91575. +
  91576. sdhci_enable_sdio_irq_nolock(host, enable);
  91577. spin_unlock_irqrestore(&host->lock, flags);
  91578. +
  91579. + sdhci_runtime_pm_put(host);
  91580. }
  91581. static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
  91582. @@ -1855,22 +1818,16 @@
  91583. static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
  91584. {
  91585. - struct sdhci_host *host;
  91586. + struct sdhci_host *host = mmc_priv(mmc);
  91587. u16 ctrl;
  91588. - u32 ier;
  91589. int tuning_loop_counter = MAX_TUNING_LOOP;
  91590. unsigned long timeout;
  91591. int err = 0;
  91592. - bool requires_tuning_nonuhs = false;
  91593. unsigned long flags;
  91594. - host = mmc_priv(mmc);
  91595. -
  91596. sdhci_runtime_pm_get(host);
  91597. spin_lock_irqsave(&host->lock, flags);
  91598. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91599. -
  91600. /*
  91601. * The Host Controller needs tuning only in case of SDR104 mode
  91602. * and for SDR50 mode when Use Tuning for SDR50 is set in the
  91603. @@ -1878,15 +1835,18 @@
  91604. * If the Host Controller supports the HS200 mode then the
  91605. * tuning function has to be executed.
  91606. */
  91607. - if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
  91608. - (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
  91609. - host->flags & SDHCI_SDR104_NEEDS_TUNING))
  91610. - requires_tuning_nonuhs = true;
  91611. -
  91612. - if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
  91613. - requires_tuning_nonuhs)
  91614. - ctrl |= SDHCI_CTRL_EXEC_TUNING;
  91615. - else {
  91616. + switch (host->timing) {
  91617. + case MMC_TIMING_MMC_HS200:
  91618. + case MMC_TIMING_UHS_SDR104:
  91619. + break;
  91620. +
  91621. + case MMC_TIMING_UHS_SDR50:
  91622. + if (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
  91623. + host->flags & SDHCI_SDR104_NEEDS_TUNING)
  91624. + break;
  91625. + /* FALLTHROUGH */
  91626. +
  91627. + default:
  91628. spin_unlock_irqrestore(&host->lock, flags);
  91629. sdhci_runtime_pm_put(host);
  91630. return 0;
  91631. @@ -1899,6 +1859,8 @@
  91632. return err;
  91633. }
  91634. + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91635. + ctrl |= SDHCI_CTRL_EXEC_TUNING;
  91636. sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  91637. /*
  91638. @@ -1911,8 +1873,8 @@
  91639. * to make sure we don't hit a controller bug, we _only_
  91640. * enable Buffer Read Ready interrupt here.
  91641. */
  91642. - ier = sdhci_readl(host, SDHCI_INT_ENABLE);
  91643. - sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
  91644. + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
  91645. + sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
  91646. /*
  91647. * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
  91648. @@ -2045,7 +2007,8 @@
  91649. if (err && (host->flags & SDHCI_USING_RETUNING_TIMER))
  91650. err = 0;
  91651. - sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
  91652. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  91653. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  91654. spin_unlock_irqrestore(&host->lock, flags);
  91655. sdhci_runtime_pm_put(host);
  91656. @@ -2055,26 +2018,30 @@
  91657. static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
  91658. {
  91659. - u16 ctrl;
  91660. -
  91661. /* Host Controller v3.00 defines preset value registers */
  91662. if (host->version < SDHCI_SPEC_300)
  91663. return;
  91664. - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91665. -
  91666. /*
  91667. * We only enable or disable Preset Value if they are not already
  91668. * enabled or disabled respectively. Otherwise, we bail out.
  91669. */
  91670. - if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  91671. - ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
  91672. - sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  91673. - host->flags |= SDHCI_PV_ENABLED;
  91674. - } else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
  91675. - ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  91676. + if (host->preset_enabled != enable) {
  91677. + u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  91678. +
  91679. + if (enable)
  91680. + ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
  91681. + else
  91682. + ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  91683. +
  91684. sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
  91685. - host->flags &= ~SDHCI_PV_ENABLED;
  91686. +
  91687. + if (enable)
  91688. + host->flags |= SDHCI_PV_ENABLED;
  91689. + else
  91690. + host->flags &= ~SDHCI_PV_ENABLED;
  91691. +
  91692. + host->preset_enabled = enable;
  91693. }
  91694. }
  91695. @@ -2096,8 +2063,8 @@
  91696. pr_err("%s: Resetting controller.\n",
  91697. mmc_hostname(host->mmc));
  91698. - sdhci_reset(host, SDHCI_RESET_CMD);
  91699. - sdhci_reset(host, SDHCI_RESET_DATA);
  91700. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  91701. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  91702. host->mrq->cmd->error = -ENOMEDIUM;
  91703. tasklet_schedule(&host->finish_tasklet);
  91704. @@ -2125,15 +2092,6 @@
  91705. * *
  91706. \*****************************************************************************/
  91707. -static void sdhci_tasklet_card(unsigned long param)
  91708. -{
  91709. - struct sdhci_host *host = (struct sdhci_host*)param;
  91710. -
  91711. - sdhci_card_event(host->mmc);
  91712. -
  91713. - mmc_detect_change(host->mmc, msecs_to_jiffies(200));
  91714. -}
  91715. -
  91716. static void sdhci_tasklet_finish(unsigned long param)
  91717. {
  91718. struct sdhci_host *host;
  91719. @@ -2170,12 +2128,12 @@
  91720. /* Some controllers need this kick or reset won't work here */
  91721. if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
  91722. /* This is to force an update */
  91723. - sdhci_update_clock(host);
  91724. + host->ops->set_clock(host, host->clock);
  91725. /* Spec says we should do both at the same time, but Ricoh
  91726. controllers do not like that. */
  91727. - sdhci_reset(host, SDHCI_RESET_CMD);
  91728. - sdhci_reset(host, SDHCI_RESET_DATA);
  91729. + sdhci_do_reset(host, SDHCI_RESET_CMD);
  91730. + sdhci_do_reset(host, SDHCI_RESET_DATA);
  91731. }
  91732. host->mrq = NULL;
  91733. @@ -2425,14 +2383,14 @@
  91734. static irqreturn_t sdhci_irq(int irq, void *dev_id)
  91735. {
  91736. - irqreturn_t result;
  91737. + irqreturn_t result = IRQ_NONE;
  91738. struct sdhci_host *host = dev_id;
  91739. - u32 intmask, unexpected = 0;
  91740. - int cardint = 0, max_loops = 16;
  91741. + u32 intmask, mask, unexpected = 0;
  91742. + int max_loops = 16;
  91743. spin_lock(&host->lock);
  91744. - if (host->runtime_suspended) {
  91745. + if (host->runtime_suspended && !sdhci_sdio_irq_enabled(host)) {
  91746. spin_unlock(&host->lock);
  91747. pr_warning("%s: got irq while runtime suspended\n",
  91748. mmc_hostname(host->mmc));
  91749. @@ -2440,88 +2398,81 @@
  91750. }
  91751. intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  91752. -
  91753. if (!intmask || intmask == 0xffffffff) {
  91754. result = IRQ_NONE;
  91755. goto out;
  91756. }
  91757. -again:
  91758. - DBG("*** %s got interrupt: 0x%08x\n",
  91759. - mmc_hostname(host->mmc), intmask);
  91760. -
  91761. - if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  91762. - u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  91763. - SDHCI_CARD_PRESENT;
  91764. -
  91765. - /*
  91766. - * There is a observation on i.mx esdhc. INSERT bit will be
  91767. - * immediately set again when it gets cleared, if a card is
  91768. - * inserted. We have to mask the irq to prevent interrupt
  91769. - * storm which will freeze the system. And the REMOVE gets
  91770. - * the same situation.
  91771. - *
  91772. - * More testing are needed here to ensure it works for other
  91773. - * platforms though.
  91774. - */
  91775. - sdhci_mask_irqs(host, present ? SDHCI_INT_CARD_INSERT :
  91776. - SDHCI_INT_CARD_REMOVE);
  91777. - sdhci_unmask_irqs(host, present ? SDHCI_INT_CARD_REMOVE :
  91778. - SDHCI_INT_CARD_INSERT);
  91779. -
  91780. - sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
  91781. - SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
  91782. - intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
  91783. - tasklet_schedule(&host->card_tasklet);
  91784. - }
  91785. -
  91786. - if (intmask & SDHCI_INT_CMD_MASK) {
  91787. - sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
  91788. - SDHCI_INT_STATUS);
  91789. - sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
  91790. - }
  91791. + do {
  91792. + /* Clear selected interrupts. */
  91793. + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
  91794. + SDHCI_INT_BUS_POWER);
  91795. + sdhci_writel(host, mask, SDHCI_INT_STATUS);
  91796. +
  91797. + DBG("*** %s got interrupt: 0x%08x\n",
  91798. + mmc_hostname(host->mmc), intmask);
  91799. +
  91800. + if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  91801. + u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
  91802. + SDHCI_CARD_PRESENT;
  91803. - if (intmask & SDHCI_INT_DATA_MASK) {
  91804. - sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
  91805. - SDHCI_INT_STATUS);
  91806. - sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
  91807. - }
  91808. + /*
  91809. + * There is a observation on i.mx esdhc. INSERT
  91810. + * bit will be immediately set again when it gets
  91811. + * cleared, if a card is inserted. We have to mask
  91812. + * the irq to prevent interrupt storm which will
  91813. + * freeze the system. And the REMOVE gets the
  91814. + * same situation.
  91815. + *
  91816. + * More testing are needed here to ensure it works
  91817. + * for other platforms though.
  91818. + */
  91819. + host->ier &= ~(SDHCI_INT_CARD_INSERT |
  91820. + SDHCI_INT_CARD_REMOVE);
  91821. + host->ier |= present ? SDHCI_INT_CARD_REMOVE :
  91822. + SDHCI_INT_CARD_INSERT;
  91823. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  91824. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  91825. - intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
  91826. + sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
  91827. + SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
  91828. - intmask &= ~SDHCI_INT_ERROR;
  91829. + host->thread_isr |= intmask & (SDHCI_INT_CARD_INSERT |
  91830. + SDHCI_INT_CARD_REMOVE);
  91831. + result = IRQ_WAKE_THREAD;
  91832. + }
  91833. - if (intmask & SDHCI_INT_BUS_POWER) {
  91834. - pr_err("%s: Card is consuming too much power!\n",
  91835. - mmc_hostname(host->mmc));
  91836. - sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
  91837. - }
  91838. + if (intmask & SDHCI_INT_CMD_MASK)
  91839. + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
  91840. - intmask &= ~SDHCI_INT_BUS_POWER;
  91841. + if (intmask & SDHCI_INT_DATA_MASK)
  91842. + sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
  91843. - if (intmask & SDHCI_INT_CARD_INT)
  91844. - cardint = 1;
  91845. + if (intmask & SDHCI_INT_BUS_POWER)
  91846. + pr_err("%s: Card is consuming too much power!\n",
  91847. + mmc_hostname(host->mmc));
  91848. - intmask &= ~SDHCI_INT_CARD_INT;
  91849. + if (intmask & SDHCI_INT_CARD_INT) {
  91850. + sdhci_enable_sdio_irq_nolock(host, false);
  91851. + host->thread_isr |= SDHCI_INT_CARD_INT;
  91852. + result = IRQ_WAKE_THREAD;
  91853. + }
  91854. - if (intmask) {
  91855. - unexpected |= intmask;
  91856. - sdhci_writel(host, intmask, SDHCI_INT_STATUS);
  91857. - }
  91858. + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
  91859. + SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
  91860. + SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
  91861. + SDHCI_INT_CARD_INT);
  91862. - result = IRQ_HANDLED;
  91863. + if (intmask) {
  91864. + unexpected |= intmask;
  91865. + sdhci_writel(host, intmask, SDHCI_INT_STATUS);
  91866. + }
  91867. - intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  91868. + if (result == IRQ_NONE)
  91869. + result = IRQ_HANDLED;
  91870. - /*
  91871. - * If we know we'll call the driver to signal SDIO IRQ, disregard
  91872. - * further indications of Card Interrupt in the status to avoid a
  91873. - * needless loop.
  91874. - */
  91875. - if (cardint)
  91876. - intmask &= ~SDHCI_INT_CARD_INT;
  91877. - if (intmask && --max_loops)
  91878. - goto again;
  91879. + intmask = sdhci_readl(host, SDHCI_INT_STATUS);
  91880. + } while (intmask && --max_loops);
  91881. out:
  91882. spin_unlock(&host->lock);
  91883. @@ -2530,15 +2481,38 @@
  91884. mmc_hostname(host->mmc), unexpected);
  91885. sdhci_dumpregs(host);
  91886. }
  91887. - /*
  91888. - * We have to delay this as it calls back into the driver.
  91889. - */
  91890. - if (cardint)
  91891. - mmc_signal_sdio_irq(host->mmc);
  91892. return result;
  91893. }
  91894. +static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
  91895. +{
  91896. + struct sdhci_host *host = dev_id;
  91897. + unsigned long flags;
  91898. + u32 isr;
  91899. +
  91900. + spin_lock_irqsave(&host->lock, flags);
  91901. + isr = host->thread_isr;
  91902. + host->thread_isr = 0;
  91903. + spin_unlock_irqrestore(&host->lock, flags);
  91904. +
  91905. + if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
  91906. + sdhci_card_event(host->mmc);
  91907. + mmc_detect_change(host->mmc, msecs_to_jiffies(200));
  91908. + }
  91909. +
  91910. + if (isr & SDHCI_INT_CARD_INT) {
  91911. + sdio_run_irqs(host->mmc);
  91912. +
  91913. + spin_lock_irqsave(&host->lock, flags);
  91914. + if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
  91915. + sdhci_enable_sdio_irq_nolock(host, true);
  91916. + spin_unlock_irqrestore(&host->lock, flags);
  91917. + }
  91918. +
  91919. + return isr ? IRQ_HANDLED : IRQ_NONE;
  91920. +}
  91921. +
  91922. /*****************************************************************************\
  91923. * *
  91924. * Suspend/resume *
  91925. @@ -2548,6 +2522,7 @@
  91926. #ifdef CONFIG_PM
  91927. void sdhci_enable_irq_wakeups(struct sdhci_host *host)
  91928. {
  91929. + int gpio_cd = mmc_gpio_get_cd(host->mmc);
  91930. u8 val;
  91931. u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE
  91932. | SDHCI_WAKE_ON_INT;
  91933. @@ -2555,7 +2530,8 @@
  91934. val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
  91935. val |= mask ;
  91936. /* Avoid fake wake up */
  91937. - if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
  91938. + if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION ||
  91939. + !IS_ERR_VALUE(gpio_cd))
  91940. val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE);
  91941. sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
  91942. }
  91943. @@ -2575,9 +2551,6 @@
  91944. int sdhci_suspend_host(struct sdhci_host *host)
  91945. {
  91946. - if (host->ops->platform_suspend)
  91947. - host->ops->platform_suspend(host);
  91948. -
  91949. sdhci_disable_card_detection(host);
  91950. /* Disable tuning since we are suspending */
  91951. @@ -2587,7 +2560,9 @@
  91952. }
  91953. if (!device_may_wakeup(mmc_dev(host->mmc))) {
  91954. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  91955. + host->ier = 0;
  91956. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  91957. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  91958. free_irq(host->irq, host);
  91959. } else {
  91960. sdhci_enable_irq_wakeups(host);
  91961. @@ -2608,8 +2583,9 @@
  91962. }
  91963. if (!device_may_wakeup(mmc_dev(host->mmc))) {
  91964. - ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
  91965. - mmc_hostname(host->mmc), host);
  91966. + ret = request_threaded_irq(host->irq, sdhci_irq,
  91967. + sdhci_thread_irq, IRQF_SHARED,
  91968. + mmc_hostname(host->mmc), host);
  91969. if (ret)
  91970. return ret;
  91971. } else {
  91972. @@ -2631,9 +2607,6 @@
  91973. sdhci_enable_card_detection(host);
  91974. - if (host->ops->platform_resume)
  91975. - host->ops->platform_resume(host);
  91976. -
  91977. /* Set the re-tuning expiration flag */
  91978. if (host->flags & SDHCI_USING_RETUNING_TIMER)
  91979. host->flags |= SDHCI_NEEDS_RETUNING;
  91980. @@ -2685,10 +2658,12 @@
  91981. }
  91982. spin_lock_irqsave(&host->lock, flags);
  91983. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  91984. + host->ier &= SDHCI_INT_CARD_INT;
  91985. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  91986. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  91987. spin_unlock_irqrestore(&host->lock, flags);
  91988. - synchronize_irq(host->irq);
  91989. + synchronize_hardirq(host->irq);
  91990. spin_lock_irqsave(&host->lock, flags);
  91991. host->runtime_suspended = true;
  91992. @@ -2732,7 +2707,7 @@
  91993. host->runtime_suspended = false;
  91994. /* Enable SDIO IRQ */
  91995. - if ((host->flags & SDHCI_SDIO_IRQ_ENABLED))
  91996. + if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
  91997. sdhci_enable_sdio_irq_nolock(host, true);
  91998. /* Enable Card Detection */
  91999. @@ -2791,7 +2766,7 @@
  92000. if (debug_quirks2)
  92001. host->quirks2 = debug_quirks2;
  92002. - sdhci_reset(host, SDHCI_RESET_ALL);
  92003. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  92004. host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
  92005. host->version = (host->version & SDHCI_SPEC_VER_MASK)
  92006. @@ -2851,15 +2826,29 @@
  92007. * (128) and potentially one alignment transfer for
  92008. * each of those entries.
  92009. */
  92010. - host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL);
  92011. + host->adma_desc = dma_alloc_coherent(mmc_dev(host->mmc),
  92012. + ADMA_SIZE, &host->adma_addr,
  92013. + GFP_KERNEL);
  92014. host->align_buffer = kmalloc(128 * 4, GFP_KERNEL);
  92015. if (!host->adma_desc || !host->align_buffer) {
  92016. - kfree(host->adma_desc);
  92017. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  92018. + host->adma_desc, host->adma_addr);
  92019. kfree(host->align_buffer);
  92020. pr_warning("%s: Unable to allocate ADMA "
  92021. "buffers. Falling back to standard DMA.\n",
  92022. mmc_hostname(mmc));
  92023. host->flags &= ~SDHCI_USE_ADMA;
  92024. + host->adma_desc = NULL;
  92025. + host->align_buffer = NULL;
  92026. + } else if (host->adma_addr & 3) {
  92027. + pr_warning("%s: unable to allocate aligned ADMA descriptor\n",
  92028. + mmc_hostname(mmc));
  92029. + host->flags &= ~SDHCI_USE_ADMA;
  92030. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  92031. + host->adma_desc, host->adma_addr);
  92032. + kfree(host->align_buffer);
  92033. + host->adma_desc = NULL;
  92034. + host->align_buffer = NULL;
  92035. }
  92036. }
  92037. @@ -2941,9 +2930,22 @@
  92038. if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
  92039. host->timeout_clk = mmc->f_max / 1000;
  92040. - mmc->max_discard_to = (1 << 27) / host->timeout_clk;
  92041. + if (host->quirks2 & SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER) {
  92042. + if (host->ops->get_max_timeout_counter) {
  92043. + mmc->max_discard_to =
  92044. + host->ops->get_max_timeout_counter(host)
  92045. + / host->timeout_clk;
  92046. + } else {
  92047. + pr_err("%s: Hardware doesn't specify max timeout "
  92048. + "counter\n", mmc_hostname(mmc));
  92049. + return -ENODEV;
  92050. + }
  92051. + } else {
  92052. + mmc->max_discard_to = (1 << 27) / host->timeout_clk;
  92053. + }
  92054. mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
  92055. + mmc->caps2 |= MMC_CAP2_SDIO_NOTHREAD;
  92056. if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
  92057. host->flags |= SDHCI_AUTO_CMD12;
  92058. @@ -3214,8 +3216,6 @@
  92059. /*
  92060. * Init tasklets.
  92061. */
  92062. - tasklet_init(&host->card_tasklet,
  92063. - sdhci_tasklet_card, (unsigned long)host);
  92064. tasklet_init(&host->finish_tasklet,
  92065. sdhci_tasklet_finish, (unsigned long)host);
  92066. @@ -3232,8 +3232,8 @@
  92067. sdhci_init(host, 0);
  92068. - ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
  92069. - mmc_hostname(mmc), host);
  92070. + ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq,
  92071. + IRQF_SHARED, mmc_hostname(mmc), host);
  92072. if (ret) {
  92073. pr_err("%s: Failed to request IRQ %d: %d\n",
  92074. mmc_hostname(mmc), host->irq, ret);
  92075. @@ -3275,12 +3275,12 @@
  92076. #ifdef SDHCI_USE_LEDS_CLASS
  92077. reset:
  92078. - sdhci_reset(host, SDHCI_RESET_ALL);
  92079. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  92080. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  92081. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  92082. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  92083. free_irq(host->irq, host);
  92084. #endif
  92085. untasklet:
  92086. - tasklet_kill(&host->card_tasklet);
  92087. tasklet_kill(&host->finish_tasklet);
  92088. return ret;
  92089. @@ -3317,14 +3317,14 @@
  92090. #endif
  92091. if (!dead)
  92092. - sdhci_reset(host, SDHCI_RESET_ALL);
  92093. + sdhci_do_reset(host, SDHCI_RESET_ALL);
  92094. - sdhci_mask_irqs(host, SDHCI_INT_ALL_MASK);
  92095. + sdhci_writel(host, 0, SDHCI_INT_ENABLE);
  92096. + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
  92097. free_irq(host->irq, host);
  92098. del_timer_sync(&host->timer);
  92099. - tasklet_kill(&host->card_tasklet);
  92100. tasklet_kill(&host->finish_tasklet);
  92101. if (host->vmmc) {
  92102. @@ -3337,7 +3337,9 @@
  92103. regulator_put(host->vqmmc);
  92104. }
  92105. - kfree(host->adma_desc);
  92106. + if (host->adma_desc)
  92107. + dma_free_coherent(mmc_dev(host->mmc), ADMA_SIZE,
  92108. + host->adma_desc, host->adma_addr);
  92109. kfree(host->align_buffer);
  92110. host->adma_desc = NULL;
  92111. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-cns3xxx.c linux-imx6-3.14/drivers/mmc/host/sdhci-cns3xxx.c
  92112. --- linux-3.14.17/drivers/mmc/host/sdhci-cns3xxx.c 2014-08-14 03:38:34.000000000 +0200
  92113. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-cns3xxx.c 2014-09-11 18:06:03.030042084 +0200
  92114. @@ -30,13 +30,12 @@
  92115. u16 clk;
  92116. unsigned long timeout;
  92117. - if (clock == host->clock)
  92118. - return;
  92119. + host->mmc->actual_clock = 0;
  92120. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  92121. if (clock == 0)
  92122. - goto out;
  92123. + return;
  92124. while (host->max_clk / div > clock) {
  92125. /*
  92126. @@ -75,13 +74,14 @@
  92127. clk |= SDHCI_CLOCK_CARD_EN;
  92128. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  92129. -out:
  92130. - host->clock = clock;
  92131. }
  92132. static const struct sdhci_ops sdhci_cns3xxx_ops = {
  92133. .get_max_clock = sdhci_cns3xxx_get_max_clk,
  92134. .set_clock = sdhci_cns3xxx_set_clock,
  92135. + .set_bus_width = sdhci_set_bus_width,
  92136. + .reset = sdhci_reset,
  92137. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92138. };
  92139. static const struct sdhci_pltfm_data sdhci_cns3xxx_pdata = {
  92140. @@ -90,8 +90,7 @@
  92141. SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
  92142. SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
  92143. SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
  92144. - SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
  92145. - SDHCI_QUIRK_NONSTANDARD_CLOCK,
  92146. + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
  92147. };
  92148. static int sdhci_cns3xxx_probe(struct platform_device *pdev)
  92149. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-dove.c linux-imx6-3.14/drivers/mmc/host/sdhci-dove.c
  92150. --- linux-3.14.17/drivers/mmc/host/sdhci-dove.c 2014-08-14 03:38:34.000000000 +0200
  92151. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-dove.c 2014-09-11 18:06:03.030042084 +0200
  92152. @@ -86,6 +86,10 @@
  92153. static const struct sdhci_ops sdhci_dove_ops = {
  92154. .read_w = sdhci_dove_readw,
  92155. .read_l = sdhci_dove_readl,
  92156. + .set_clock = sdhci_set_clock,
  92157. + .set_bus_width = sdhci_set_bus_width,
  92158. + .reset = sdhci_reset,
  92159. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92160. };
  92161. static const struct sdhci_pltfm_data sdhci_dove_pdata = {
  92162. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-esdhc.h linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc.h
  92163. --- linux-3.14.17/drivers/mmc/host/sdhci-esdhc.h 2014-08-14 03:38:34.000000000 +0200
  92164. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc.h 2014-09-11 18:06:03.030042084 +0200
  92165. @@ -20,12 +20,11 @@
  92166. #define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
  92167. SDHCI_QUIRK_NO_BUSY_IRQ | \
  92168. - SDHCI_QUIRK_NONSTANDARD_CLOCK | \
  92169. SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
  92170. - SDHCI_QUIRK_PIO_NEEDS_DELAY | \
  92171. - SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
  92172. + SDHCI_QUIRK_PIO_NEEDS_DELAY)
  92173. #define ESDHC_SYSTEM_CONTROL 0x2c
  92174. +#define ESDHC_SYS_CTRL_RSTA (1 << 24)
  92175. #define ESDHC_CLOCK_MASK 0x0000fff0
  92176. #define ESDHC_PREDIV_SHIFT 8
  92177. #define ESDHC_DIVIDER_SHIFT 4
  92178. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-esdhc-imx.c linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc-imx.c
  92179. --- linux-3.14.17/drivers/mmc/host/sdhci-esdhc-imx.c 2014-08-14 03:38:34.000000000 +0200
  92180. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-esdhc-imx.c 2014-09-11 18:06:03.030042084 +0200
  92181. @@ -11,6 +11,7 @@
  92182. * the Free Software Foundation; either version 2 of the License.
  92183. */
  92184. +#include <linux/busfreq-imx6.h>
  92185. #include <linux/io.h>
  92186. #include <linux/delay.h>
  92187. #include <linux/err.h>
  92188. @@ -114,6 +115,10 @@
  92189. #define ESDHC_FLAG_STD_TUNING BIT(5)
  92190. /* The IP has SDHCI_CAPABILITIES_1 register */
  92191. #define ESDHC_FLAG_HAVE_CAP1 BIT(6)
  92192. +/* The IP has errata ERR004536 */
  92193. +#define ESDHC_FLAG_ERR004536 BIT(7)
  92194. +/* need request bus freq during low power */
  92195. +#define ESDHC_FLAG_BUSFREQ BIT(8)
  92196. struct esdhc_soc_data {
  92197. u32 flags;
  92198. @@ -141,7 +146,8 @@
  92199. static struct esdhc_soc_data usdhc_imx6sl_data = {
  92200. .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
  92201. - | ESDHC_FLAG_HAVE_CAP1,
  92202. + | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536
  92203. + | ESDHC_FLAG_BUSFREQ,
  92204. };
  92205. struct pltfm_imx_data {
  92206. @@ -160,7 +166,6 @@
  92207. MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
  92208. WAIT_FOR_INT, /* sent CMD12, waiting for response INT */
  92209. } multiblock_status;
  92210. - u32 uhs_mode;
  92211. u32 is_ddr;
  92212. };
  92213. @@ -382,7 +387,6 @@
  92214. if (val & ESDHC_MIX_CTRL_SMPCLK_SEL)
  92215. ret |= SDHCI_CTRL_TUNED_CLK;
  92216. - ret |= (imx_data->uhs_mode & SDHCI_CTRL_UHS_MASK);
  92217. ret &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
  92218. return ret;
  92219. @@ -429,7 +433,6 @@
  92220. else
  92221. new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
  92222. writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
  92223. - imx_data->uhs_mode = val & SDHCI_CTRL_UHS_MASK;
  92224. if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
  92225. new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
  92226. if (val & SDHCI_CTRL_TUNED_CLK)
  92227. @@ -600,12 +603,14 @@
  92228. u32 temp, val;
  92229. if (clock == 0) {
  92230. + host->mmc->actual_clock = 0;
  92231. +
  92232. if (esdhc_is_usdhc(imx_data)) {
  92233. val = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
  92234. writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
  92235. host->ioaddr + ESDHC_VENDOR_SPEC);
  92236. }
  92237. - goto out;
  92238. + return;
  92239. }
  92240. if (esdhc_is_usdhc(imx_data) && !imx_data->is_ddr)
  92241. @@ -645,8 +650,6 @@
  92242. }
  92243. mdelay(1);
  92244. -out:
  92245. - host->clock = clock;
  92246. }
  92247. static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
  92248. @@ -668,7 +671,7 @@
  92249. return -ENOSYS;
  92250. }
  92251. -static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
  92252. +static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
  92253. {
  92254. u32 ctrl;
  92255. @@ -686,17 +689,56 @@
  92256. esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
  92257. SDHCI_HOST_CONTROL);
  92258. +}
  92259. - return 0;
  92260. +static void esdhc_tuning_reset(struct sdhci_host *host, u32 rst_bits)
  92261. +{
  92262. + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  92263. + struct pltfm_imx_data *imx_data = pltfm_host->priv;
  92264. + u32 timeout;
  92265. + u32 reg;
  92266. +
  92267. + reg = readl(host->ioaddr + ESDHC_SYSTEM_CONTROL);
  92268. + reg |= rst_bits;
  92269. + writel(reg, host->ioaddr + ESDHC_SYSTEM_CONTROL);
  92270. +
  92271. + /* Wait for max 100ms */
  92272. + timeout = 100;
  92273. +
  92274. + /* hw clears the bit when it's done */
  92275. + while (readl(host->ioaddr + ESDHC_SYSTEM_CONTROL) & rst_bits) {
  92276. + if (timeout == 0) {
  92277. + dev_err(mmc_dev(host->mmc),
  92278. + "Reset never completes!\n");
  92279. + return;
  92280. + }
  92281. + timeout--;
  92282. + mdelay(1);
  92283. + }
  92284. +
  92285. + /*
  92286. + * The RSTA, reset all, on usdhc will not clear following regs:
  92287. + * > SDHCI_MIX_CTRL
  92288. + * > SDHCI_TUNE_CTRL_STATUS
  92289. + *
  92290. + * Do it manually here.
  92291. + */
  92292. + if ((rst_bits & ESDHC_SYS_CTRL_RSTA) && is_imx6q_usdhc(imx_data)) {
  92293. + writel(0, host->ioaddr + ESDHC_MIX_CTRL);
  92294. + writel(0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
  92295. + /* FIXME: delay for clear tuning status or some cards may not work */
  92296. + mdelay(1);
  92297. + }
  92298. }
  92299. static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
  92300. {
  92301. u32 reg;
  92302. - /* FIXME: delay a bit for card to be ready for next tuning due to errors */
  92303. - mdelay(1);
  92304. + /* reset controller before tuning or it may fail on some cards */
  92305. + esdhc_tuning_reset(host, ESDHC_SYS_CTRL_RSTA);
  92306. + /* This is balanced by the runtime put in sdhci_tasklet_finish */
  92307. pm_runtime_get_sync(host->mmc->parent);
  92308. reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
  92309. reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL |
  92310. @@ -713,13 +755,12 @@
  92311. complete(&mrq->completion);
  92312. }
  92313. -static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode)
  92314. +static int esdhc_send_tuning_cmd(struct sdhci_host *host, u32 opcode,
  92315. + struct scatterlist *sg)
  92316. {
  92317. struct mmc_command cmd = {0};
  92318. struct mmc_request mrq = {NULL};
  92319. struct mmc_data data = {0};
  92320. - struct scatterlist sg;
  92321. - char tuning_pattern[ESDHC_TUNING_BLOCK_PATTERN_LEN];
  92322. cmd.opcode = opcode;
  92323. cmd.arg = 0;
  92324. @@ -728,11 +769,9 @@
  92325. data.blksz = ESDHC_TUNING_BLOCK_PATTERN_LEN;
  92326. data.blocks = 1;
  92327. data.flags = MMC_DATA_READ;
  92328. - data.sg = &sg;
  92329. + data.sg = sg;
  92330. data.sg_len = 1;
  92331. - sg_init_one(&sg, tuning_pattern, sizeof(tuning_pattern));
  92332. -
  92333. mrq.cmd = &cmd;
  92334. mrq.cmd->mrq = &mrq;
  92335. mrq.data = &data;
  92336. @@ -742,14 +781,12 @@
  92337. mrq.done = esdhc_request_done;
  92338. init_completion(&(mrq.completion));
  92339. - disable_irq(host->irq);
  92340. - spin_lock(&host->lock);
  92341. + spin_lock_irq(&host->lock);
  92342. host->mrq = &mrq;
  92343. sdhci_send_command(host, mrq.cmd);
  92344. - spin_unlock(&host->lock);
  92345. - enable_irq(host->irq);
  92346. + spin_unlock_irq(&host->lock);
  92347. wait_for_completion(&mrq.completion);
  92348. @@ -772,13 +809,21 @@
  92349. static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
  92350. {
  92351. + struct scatterlist sg;
  92352. + char *tuning_pattern;
  92353. int min, max, avg, ret;
  92354. + tuning_pattern = kmalloc(ESDHC_TUNING_BLOCK_PATTERN_LEN, GFP_KERNEL);
  92355. + if (!tuning_pattern)
  92356. + return -ENOMEM;
  92357. +
  92358. + sg_init_one(&sg, tuning_pattern, ESDHC_TUNING_BLOCK_PATTERN_LEN);
  92359. +
  92360. /* find the mininum delay first which can pass tuning */
  92361. min = ESDHC_TUNE_CTRL_MIN;
  92362. while (min < ESDHC_TUNE_CTRL_MAX) {
  92363. esdhc_prepare_tuning(host, min);
  92364. - if (!esdhc_send_tuning_cmd(host, opcode))
  92365. + if (!esdhc_send_tuning_cmd(host, opcode, &sg))
  92366. break;
  92367. min += ESDHC_TUNE_CTRL_STEP;
  92368. }
  92369. @@ -787,7 +832,7 @@
  92370. max = min + ESDHC_TUNE_CTRL_STEP;
  92371. while (max < ESDHC_TUNE_CTRL_MAX) {
  92372. esdhc_prepare_tuning(host, max);
  92373. - if (esdhc_send_tuning_cmd(host, opcode)) {
  92374. + if (esdhc_send_tuning_cmd(host, opcode, &sg)) {
  92375. max -= ESDHC_TUNE_CTRL_STEP;
  92376. break;
  92377. }
  92378. @@ -797,9 +842,11 @@
  92379. /* use average delay to get the best timing */
  92380. avg = (min + max) / 2;
  92381. esdhc_prepare_tuning(host, avg);
  92382. - ret = esdhc_send_tuning_cmd(host, opcode);
  92383. + ret = esdhc_send_tuning_cmd(host, opcode, &sg);
  92384. esdhc_post_tuning(host);
  92385. + kfree(tuning_pattern);
  92386. +
  92387. dev_dbg(mmc_dev(host->mmc), "tunning %s at 0x%x ret %d\n",
  92388. ret ? "failed" : "passed", avg, ret);
  92389. @@ -837,28 +884,20 @@
  92390. return pinctrl_select_state(imx_data->pinctrl, pinctrl);
  92391. }
  92392. -static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  92393. +static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
  92394. {
  92395. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  92396. struct pltfm_imx_data *imx_data = pltfm_host->priv;
  92397. struct esdhc_platform_data *boarddata = &imx_data->boarddata;
  92398. - switch (uhs) {
  92399. + switch (timing) {
  92400. case MMC_TIMING_UHS_SDR12:
  92401. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR12;
  92402. - break;
  92403. case MMC_TIMING_UHS_SDR25:
  92404. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR25;
  92405. - break;
  92406. case MMC_TIMING_UHS_SDR50:
  92407. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR50;
  92408. - break;
  92409. case MMC_TIMING_UHS_SDR104:
  92410. case MMC_TIMING_MMC_HS200:
  92411. - imx_data->uhs_mode = SDHCI_CTRL_UHS_SDR104;
  92412. break;
  92413. case MMC_TIMING_UHS_DDR50:
  92414. - imx_data->uhs_mode = SDHCI_CTRL_UHS_DDR50;
  92415. writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
  92416. ESDHC_MIX_CTRL_DDREN,
  92417. host->ioaddr + ESDHC_MIX_CTRL);
  92418. @@ -875,7 +914,20 @@
  92419. break;
  92420. }
  92421. - return esdhc_change_pinstate(host, uhs);
  92422. + esdhc_change_pinstate(host, timing);
  92423. +}
  92424. +
  92425. +static void esdhc_reset(struct sdhci_host *host, u8 mask)
  92426. +{
  92427. + sdhci_reset(host, mask);
  92428. +
  92429. + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
  92430. + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
  92431. +}
  92432. +
  92433. +static unsigned int esdhc_get_max_timeout_counter(struct sdhci_host *host)
  92434. +{
  92435. + return 1 << 28;
  92436. }
  92437. static struct sdhci_ops sdhci_esdhc_ops = {
  92438. @@ -888,8 +940,9 @@
  92439. .get_max_clock = esdhc_pltfm_get_max_clock,
  92440. .get_min_clock = esdhc_pltfm_get_min_clock,
  92441. .get_ro = esdhc_pltfm_get_ro,
  92442. - .platform_bus_width = esdhc_pltfm_bus_width,
  92443. + .set_bus_width = esdhc_pltfm_set_bus_width,
  92444. .set_uhs_signaling = esdhc_set_uhs_signaling,
  92445. + .reset = esdhc_reset,
  92446. };
  92447. static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
  92448. @@ -906,6 +959,7 @@
  92449. struct esdhc_platform_data *boarddata)
  92450. {
  92451. struct device_node *np = pdev->dev.of_node;
  92452. + struct sdhci_host *host = platform_get_drvdata(pdev);
  92453. if (!np)
  92454. return -ENODEV;
  92455. @@ -939,6 +993,12 @@
  92456. if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
  92457. boarddata->delay_line = 0;
  92458. + if (of_find_property(np, "keep-power-in-suspend", NULL))
  92459. + host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
  92460. +
  92461. + if (of_find_property(np, "enable-sdio-wakeup", NULL))
  92462. + host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
  92463. +
  92464. return 0;
  92465. }
  92466. #else
  92467. @@ -994,6 +1054,9 @@
  92468. goto free_sdhci;
  92469. }
  92470. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  92471. + request_bus_freq(BUS_FREQ_HIGH);
  92472. +
  92473. pltfm_host->clk = imx_data->clk_per;
  92474. pltfm_host->clock = clk_get_rate(pltfm_host->clk);
  92475. clk_prepare_enable(imx_data->clk_per);
  92476. @@ -1027,8 +1090,17 @@
  92477. */
  92478. if (esdhc_is_usdhc(imx_data)) {
  92479. writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
  92480. - host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
  92481. + host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
  92482. + SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER;
  92483. host->mmc->caps |= MMC_CAP_1_8V_DDR;
  92484. +
  92485. + /*
  92486. + * errata ESDHC_FLAG_ERR004536 fix for MX6Q TO1.2 and MX6DL
  92487. + * TO1.1, it's harmless for MX6SL
  92488. + */
  92489. + writel(readl(host->ioaddr + 0x6c) | BIT(7), host->ioaddr + 0x6c);
  92490. + sdhci_esdhc_ops.get_max_timeout_counter =
  92491. + esdhc_get_max_timeout_counter;
  92492. }
  92493. if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
  92494. @@ -1040,6 +1112,9 @@
  92495. ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP,
  92496. host->ioaddr + ESDHC_TUNING_CTRL);
  92497. + if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
  92498. + host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
  92499. +
  92500. boarddata = &imx_data->boarddata;
  92501. if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
  92502. if (!host->mmc->parent->platform_data) {
  92503. @@ -1116,6 +1191,10 @@
  92504. host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
  92505. }
  92506. + if (host->mmc->pm_caps & MMC_PM_KEEP_POWER &&
  92507. + host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)
  92508. + device_init_wakeup(&pdev->dev, 1);
  92509. +
  92510. err = sdhci_add_host(host);
  92511. if (err)
  92512. goto disable_clk;
  92513. @@ -1132,6 +1211,8 @@
  92514. clk_disable_unprepare(imx_data->clk_per);
  92515. clk_disable_unprepare(imx_data->clk_ipg);
  92516. clk_disable_unprepare(imx_data->clk_ahb);
  92517. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  92518. + release_bus_freq(BUS_FREQ_HIGH);
  92519. free_sdhci:
  92520. sdhci_pltfm_free(pdev);
  92521. return err;
  92522. @@ -1170,10 +1251,15 @@
  92523. ret = sdhci_runtime_suspend_host(host);
  92524. - clk_disable_unprepare(imx_data->clk_per);
  92525. - clk_disable_unprepare(imx_data->clk_ipg);
  92526. + if (!sdhci_sdio_irq_enabled(host)) {
  92527. + clk_disable_unprepare(imx_data->clk_per);
  92528. + clk_disable_unprepare(imx_data->clk_ipg);
  92529. + }
  92530. clk_disable_unprepare(imx_data->clk_ahb);
  92531. + if (imx_data->socdata->flags & ESDHC_FLAG_BUSFREQ)
  92532. + release_bus_freq(BUS_FREQ_HIGH);
  92533. +
  92534. return ret;
  92535. }
  92536. @@ -1183,8 +1269,10 @@
  92537. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  92538. struct pltfm_imx_data *imx_data = pltfm_host->priv;
  92539. - clk_prepare_enable(imx_data->clk_per);
  92540. - clk_prepare_enable(imx_data->clk_ipg);
  92541. + if (!sdhci_sdio_irq_enabled(host)) {
  92542. + clk_prepare_enable(imx_data->clk_per);
  92543. + clk_prepare_enable(imx_data->clk_ipg);
  92544. + }
  92545. clk_prepare_enable(imx_data->clk_ahb);
  92546. return sdhci_runtime_resume_host(host);
  92547. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci.h linux-imx6-3.14/drivers/mmc/host/sdhci.h
  92548. --- linux-3.14.17/drivers/mmc/host/sdhci.h 2014-08-14 03:38:34.000000000 +0200
  92549. +++ linux-imx6-3.14/drivers/mmc/host/sdhci.h 2014-09-11 18:06:03.034042099 +0200
  92550. @@ -281,18 +281,15 @@
  92551. unsigned int (*get_max_clock)(struct sdhci_host *host);
  92552. unsigned int (*get_min_clock)(struct sdhci_host *host);
  92553. unsigned int (*get_timeout_clock)(struct sdhci_host *host);
  92554. - int (*platform_bus_width)(struct sdhci_host *host,
  92555. - int width);
  92556. + unsigned int (*get_max_timeout_counter)(struct sdhci_host *host);
  92557. + void (*set_bus_width)(struct sdhci_host *host, int width);
  92558. void (*platform_send_init_74_clocks)(struct sdhci_host *host,
  92559. u8 power_mode);
  92560. unsigned int (*get_ro)(struct sdhci_host *host);
  92561. - void (*platform_reset_enter)(struct sdhci_host *host, u8 mask);
  92562. - void (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
  92563. + void (*reset)(struct sdhci_host *host, u8 mask);
  92564. int (*platform_execute_tuning)(struct sdhci_host *host, u32 opcode);
  92565. - int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
  92566. + void (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
  92567. void (*hw_reset)(struct sdhci_host *host);
  92568. - void (*platform_suspend)(struct sdhci_host *host);
  92569. - void (*platform_resume)(struct sdhci_host *host);
  92570. void (*adma_workaround)(struct sdhci_host *host, u32 intmask);
  92571. void (*platform_init)(struct sdhci_host *host);
  92572. void (*card_event)(struct sdhci_host *host);
  92573. @@ -397,6 +394,16 @@
  92574. extern void sdhci_send_command(struct sdhci_host *host,
  92575. struct mmc_command *cmd);
  92576. +static inline bool sdhci_sdio_irq_enabled(struct sdhci_host *host)
  92577. +{
  92578. + return !!(host->flags & SDHCI_SDIO_IRQ_ENABLED);
  92579. +}
  92580. +
  92581. +void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
  92582. +void sdhci_set_bus_width(struct sdhci_host *host, int width);
  92583. +void sdhci_reset(struct sdhci_host *host, u8 mask);
  92584. +void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
  92585. +
  92586. #ifdef CONFIG_PM
  92587. extern int sdhci_suspend_host(struct sdhci_host *host);
  92588. extern int sdhci_resume_host(struct sdhci_host *host);
  92589. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-of-arasan.c linux-imx6-3.14/drivers/mmc/host/sdhci-of-arasan.c
  92590. --- linux-3.14.17/drivers/mmc/host/sdhci-of-arasan.c 2014-08-14 03:38:34.000000000 +0200
  92591. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-of-arasan.c 2014-09-11 18:06:03.030042084 +0200
  92592. @@ -52,8 +52,12 @@
  92593. }
  92594. static struct sdhci_ops sdhci_arasan_ops = {
  92595. + .set_clock = sdhci_set_clock,
  92596. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  92597. .get_timeout_clock = sdhci_arasan_get_timeout_clock,
  92598. + .set_bus_width = sdhci_set_bus_width,
  92599. + .reset = sdhci_reset,
  92600. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92601. };
  92602. static struct sdhci_pltfm_data sdhci_arasan_pdata = {
  92603. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-of-esdhc.c linux-imx6-3.14/drivers/mmc/host/sdhci-of-esdhc.c
  92604. --- linux-3.14.17/drivers/mmc/host/sdhci-of-esdhc.c 2014-08-14 03:38:34.000000000 +0200
  92605. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-of-esdhc.c 2014-09-11 18:06:03.030042084 +0200
  92606. @@ -199,13 +199,14 @@
  92607. static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
  92608. {
  92609. -
  92610. int pre_div = 2;
  92611. int div = 1;
  92612. u32 temp;
  92613. + host->mmc->actual_clock = 0;
  92614. +
  92615. if (clock == 0)
  92616. - goto out;
  92617. + return;
  92618. /* Workaround to reduce the clock frequency for p1010 esdhc */
  92619. if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
  92620. @@ -238,24 +239,8 @@
  92621. | (pre_div << ESDHC_PREDIV_SHIFT));
  92622. sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
  92623. mdelay(1);
  92624. -out:
  92625. - host->clock = clock;
  92626. }
  92627. -#ifdef CONFIG_PM
  92628. -static u32 esdhc_proctl;
  92629. -static void esdhc_of_suspend(struct sdhci_host *host)
  92630. -{
  92631. - esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
  92632. -}
  92633. -
  92634. -static void esdhc_of_resume(struct sdhci_host *host)
  92635. -{
  92636. - esdhc_of_enable_dma(host);
  92637. - sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
  92638. -}
  92639. -#endif
  92640. -
  92641. static void esdhc_of_platform_init(struct sdhci_host *host)
  92642. {
  92643. u32 vvn;
  92644. @@ -269,7 +254,7 @@
  92645. host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
  92646. }
  92647. -static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
  92648. +static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
  92649. {
  92650. u32 ctrl;
  92651. @@ -289,8 +274,6 @@
  92652. clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
  92653. ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
  92654. -
  92655. - return 0;
  92656. }
  92657. static const struct sdhci_ops sdhci_esdhc_ops = {
  92658. @@ -305,13 +288,46 @@
  92659. .get_max_clock = esdhc_of_get_max_clock,
  92660. .get_min_clock = esdhc_of_get_min_clock,
  92661. .platform_init = esdhc_of_platform_init,
  92662. -#ifdef CONFIG_PM
  92663. - .platform_suspend = esdhc_of_suspend,
  92664. - .platform_resume = esdhc_of_resume,
  92665. -#endif
  92666. .adma_workaround = esdhci_of_adma_workaround,
  92667. - .platform_bus_width = esdhc_pltfm_bus_width,
  92668. + .set_bus_width = esdhc_pltfm_set_bus_width,
  92669. + .reset = sdhci_reset,
  92670. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92671. +};
  92672. +
  92673. +#ifdef CONFIG_PM
  92674. +
  92675. +static u32 esdhc_proctl;
  92676. +static int esdhc_of_suspend(struct device *dev)
  92677. +{
  92678. + struct sdhci_host *host = dev_get_drvdata(dev);
  92679. +
  92680. + esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
  92681. +
  92682. + return sdhci_suspend_host(host);
  92683. +}
  92684. +
  92685. +static void esdhc_of_resume(device *dev)
  92686. +{
  92687. + struct sdhci_host *host = dev_get_drvdata(dev);
  92688. + int ret = sdhci_resume_host(host);
  92689. +
  92690. + if (ret == 0) {
  92691. + /* Isn't this already done by sdhci_resume_host() ? --rmk */
  92692. + esdhc_of_enable_dma(host);
  92693. + sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
  92694. + }
  92695. +
  92696. + return ret;
  92697. +}
  92698. +
  92699. +static const struct dev_pm_ops esdhc_pmops = {
  92700. + .suspend = esdhci_of_suspend,
  92701. + .resume = esdhci_of_resume,
  92702. };
  92703. +#define ESDHC_PMOPS (&esdhc_pmops)
  92704. +#else
  92705. +#define ESDHC_PMOPS NULL
  92706. +#endif
  92707. static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
  92708. /*
  92709. @@ -374,7 +390,7 @@
  92710. .name = "sdhci-esdhc",
  92711. .owner = THIS_MODULE,
  92712. .of_match_table = sdhci_esdhc_of_match,
  92713. - .pm = SDHCI_PLTFM_PMOPS,
  92714. + .pm = ESDHC_PMOPS,
  92715. },
  92716. .probe = sdhci_esdhc_probe,
  92717. .remove = sdhci_esdhc_remove,
  92718. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-of-hlwd.c linux-imx6-3.14/drivers/mmc/host/sdhci-of-hlwd.c
  92719. --- linux-3.14.17/drivers/mmc/host/sdhci-of-hlwd.c 2014-08-14 03:38:34.000000000 +0200
  92720. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-of-hlwd.c 2014-09-11 18:06:03.030042084 +0200
  92721. @@ -58,6 +58,10 @@
  92722. .write_l = sdhci_hlwd_writel,
  92723. .write_w = sdhci_hlwd_writew,
  92724. .write_b = sdhci_hlwd_writeb,
  92725. + .set_clock = sdhci_set_clock,
  92726. + .set_bus_width = sdhci_set_bus_width,
  92727. + .reset = sdhci_reset,
  92728. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92729. };
  92730. static const struct sdhci_pltfm_data sdhci_hlwd_pdata = {
  92731. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-pci.c linux-imx6-3.14/drivers/mmc/host/sdhci-pci.c
  92732. --- linux-3.14.17/drivers/mmc/host/sdhci-pci.c 2014-08-14 03:38:34.000000000 +0200
  92733. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pci.c 2014-09-11 18:06:03.030042084 +0200
  92734. @@ -1011,7 +1011,7 @@
  92735. return 0;
  92736. }
  92737. -static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
  92738. +static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width)
  92739. {
  92740. u8 ctrl;
  92741. @@ -1032,8 +1032,6 @@
  92742. }
  92743. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  92744. -
  92745. - return 0;
  92746. }
  92747. static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
  92748. @@ -1060,8 +1058,11 @@
  92749. }
  92750. static const struct sdhci_ops sdhci_pci_ops = {
  92751. + .set_clock = sdhci_set_clock,
  92752. .enable_dma = sdhci_pci_enable_dma,
  92753. - .platform_bus_width = sdhci_pci_bus_width,
  92754. + .set_bus_width = sdhci_pci_set_bus_width,
  92755. + .reset = sdhci_reset,
  92756. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92757. .hw_reset = sdhci_pci_hw_reset,
  92758. };
  92759. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-pltfm.c linux-imx6-3.14/drivers/mmc/host/sdhci-pltfm.c
  92760. --- linux-3.14.17/drivers/mmc/host/sdhci-pltfm.c 2014-08-14 03:38:34.000000000 +0200
  92761. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pltfm.c 2014-09-11 18:06:03.030042084 +0200
  92762. @@ -45,6 +45,10 @@
  92763. EXPORT_SYMBOL_GPL(sdhci_pltfm_clk_get_max_clock);
  92764. static const struct sdhci_ops sdhci_pltfm_ops = {
  92765. + .set_clock = sdhci_set_clock,
  92766. + .set_bus_width = sdhci_set_bus_width,
  92767. + .reset = sdhci_reset,
  92768. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92769. };
  92770. #ifdef CONFIG_OF
  92771. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-pxav2.c linux-imx6-3.14/drivers/mmc/host/sdhci-pxav2.c
  92772. --- linux-3.14.17/drivers/mmc/host/sdhci-pxav2.c 2014-08-14 03:38:34.000000000 +0200
  92773. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pxav2.c 2014-09-11 18:06:03.030042084 +0200
  92774. @@ -51,11 +51,13 @@
  92775. #define MMC_CARD 0x1000
  92776. #define MMC_WIDTH 0x0100
  92777. -static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
  92778. +static void pxav2_reset(struct sdhci_host *host, u8 mask)
  92779. {
  92780. struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
  92781. struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
  92782. + sdhci_reset(host, mask);
  92783. +
  92784. if (mask == SDHCI_RESET_ALL) {
  92785. u16 tmp = 0;
  92786. @@ -88,7 +90,7 @@
  92787. }
  92788. }
  92789. -static int pxav2_mmc_set_width(struct sdhci_host *host, int width)
  92790. +static void pxav2_mmc_set_bus_width(struct sdhci_host *host, int width)
  92791. {
  92792. u8 ctrl;
  92793. u16 tmp;
  92794. @@ -107,14 +109,14 @@
  92795. }
  92796. writew(tmp, host->ioaddr + SD_CE_ATA_2);
  92797. writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
  92798. -
  92799. - return 0;
  92800. }
  92801. static const struct sdhci_ops pxav2_sdhci_ops = {
  92802. + .set_clock = sdhci_set_clock,
  92803. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  92804. - .platform_reset_exit = pxav2_set_private_registers,
  92805. - .platform_bus_width = pxav2_mmc_set_width,
  92806. + .set_bus_width = pxav2_mmc_set_bus_width,
  92807. + .reset = pxav2_reset,
  92808. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92809. };
  92810. #ifdef CONFIG_OF
  92811. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-pxav3.c linux-imx6-3.14/drivers/mmc/host/sdhci-pxav3.c
  92812. --- linux-3.14.17/drivers/mmc/host/sdhci-pxav3.c 2014-08-14 03:38:34.000000000 +0200
  92813. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-pxav3.c 2014-09-11 18:06:03.030042084 +0200
  92814. @@ -57,11 +57,13 @@
  92815. #define SDCE_MISC_INT (1<<2)
  92816. #define SDCE_MISC_INT_EN (1<<1)
  92817. -static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask)
  92818. +static void pxav3_reset(struct sdhci_host *host, u8 mask)
  92819. {
  92820. struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
  92821. struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
  92822. + sdhci_reset(host, mask);
  92823. +
  92824. if (mask == SDHCI_RESET_ALL) {
  92825. /*
  92826. * tune timing of read data/command when crc error happen
  92827. @@ -129,7 +131,7 @@
  92828. pxa->power_mode = power_mode;
  92829. }
  92830. -static int pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  92831. +static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  92832. {
  92833. u16 ctrl_2;
  92834. @@ -163,15 +165,16 @@
  92835. dev_dbg(mmc_dev(host->mmc),
  92836. "%s uhs = %d, ctrl_2 = %04X\n",
  92837. __func__, uhs, ctrl_2);
  92838. -
  92839. - return 0;
  92840. }
  92841. static const struct sdhci_ops pxav3_sdhci_ops = {
  92842. - .platform_reset_exit = pxav3_set_private_registers,
  92843. + .set_clock = sdhci_set_clock,
  92844. .set_uhs_signaling = pxav3_set_uhs_signaling,
  92845. .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
  92846. .get_max_clock = sdhci_pltfm_clk_get_max_clock,
  92847. + .set_bus_width = sdhci_set_bus_width,
  92848. + .reset = pxav3_reset,
  92849. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92850. };
  92851. static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
  92852. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-s3c.c linux-imx6-3.14/drivers/mmc/host/sdhci-s3c.c
  92853. --- linux-3.14.17/drivers/mmc/host/sdhci-s3c.c 2014-08-14 03:38:34.000000000 +0200
  92854. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-s3c.c 2014-09-11 18:06:03.034042099 +0200
  92855. @@ -57,6 +57,8 @@
  92856. struct clk *clk_io;
  92857. struct clk *clk_bus[MAX_BUS_CLK];
  92858. +
  92859. + bool no_divider;
  92860. };
  92861. /**
  92862. @@ -69,6 +71,7 @@
  92863. */
  92864. struct sdhci_s3c_drv_data {
  92865. unsigned int sdhci_quirks;
  92866. + bool no_divider;
  92867. };
  92868. static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
  92869. @@ -153,7 +156,7 @@
  92870. * If controller uses a non-standard clock division, find the best clock
  92871. * speed possible with selected clock source and skip the division.
  92872. */
  92873. - if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
  92874. + if (ourhost->no_divider) {
  92875. rate = clk_round_rate(clksrc, wanted);
  92876. return wanted - rate;
  92877. }
  92878. @@ -188,9 +191,13 @@
  92879. int src;
  92880. u32 ctrl;
  92881. + host->mmc->actual_clock = 0;
  92882. +
  92883. /* don't bother if the clock is going off. */
  92884. - if (clock == 0)
  92885. + if (clock == 0) {
  92886. + sdhci_set_clock(host, clock);
  92887. return;
  92888. + }
  92889. for (src = 0; src < MAX_BUS_CLK; src++) {
  92890. delta = sdhci_s3c_consider_clock(ourhost, src, clock);
  92891. @@ -240,6 +247,8 @@
  92892. if (clock < 25 * 1000000)
  92893. ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
  92894. writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
  92895. +
  92896. + sdhci_set_clock(host, clock);
  92897. }
  92898. /**
  92899. @@ -296,10 +305,11 @@
  92900. unsigned long timeout;
  92901. u16 clk = 0;
  92902. + host->mmc->actual_clock = 0;
  92903. +
  92904. /* If the clock is going off, set to 0 at clock control register */
  92905. if (clock == 0) {
  92906. sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
  92907. - host->clock = clock;
  92908. return;
  92909. }
  92910. @@ -307,8 +317,6 @@
  92911. clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
  92912. - host->clock = clock;
  92913. -
  92914. clk = SDHCI_CLOCK_INT_EN;
  92915. sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
  92916. @@ -330,14 +338,14 @@
  92917. }
  92918. /**
  92919. - * sdhci_s3c_platform_bus_width - support 8bit buswidth
  92920. + * sdhci_s3c_set_bus_width - support 8bit buswidth
  92921. * @host: The SDHCI host being queried
  92922. * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
  92923. *
  92924. * We have 8-bit width support but is not a v3 controller.
  92925. * So we add platform_bus_width() and support 8bit width.
  92926. */
  92927. -static int sdhci_s3c_platform_bus_width(struct sdhci_host *host, int width)
  92928. +static void sdhci_s3c_set_bus_width(struct sdhci_host *host, int width)
  92929. {
  92930. u8 ctrl;
  92931. @@ -359,15 +367,15 @@
  92932. }
  92933. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  92934. -
  92935. - return 0;
  92936. }
  92937. static struct sdhci_ops sdhci_s3c_ops = {
  92938. .get_max_clock = sdhci_s3c_get_max_clk,
  92939. .set_clock = sdhci_s3c_set_clock,
  92940. .get_min_clock = sdhci_s3c_get_min_clock,
  92941. - .platform_bus_width = sdhci_s3c_platform_bus_width,
  92942. + .set_bus_width = sdhci_s3c_set_bus_width,
  92943. + .reset = sdhci_reset,
  92944. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92945. };
  92946. static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
  92947. @@ -617,8 +625,10 @@
  92948. /* Setup quirks for the controller */
  92949. host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
  92950. host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
  92951. - if (drv_data)
  92952. + if (drv_data) {
  92953. host->quirks |= drv_data->sdhci_quirks;
  92954. + sc->no_divider = drv_data->no_divider;
  92955. + }
  92956. #ifndef CONFIG_MMC_SDHCI_S3C_DMA
  92957. @@ -667,7 +677,7 @@
  92958. * If controller does not have internal clock divider,
  92959. * we can use overriding functions instead of default.
  92960. */
  92961. - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
  92962. + if (sc->no_divider) {
  92963. sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
  92964. sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
  92965. sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
  92966. @@ -813,7 +823,7 @@
  92967. #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
  92968. static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
  92969. - .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
  92970. + .no_divider = true,
  92971. };
  92972. #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
  92973. #else
  92974. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-sirf.c linux-imx6-3.14/drivers/mmc/host/sdhci-sirf.c
  92975. --- linux-3.14.17/drivers/mmc/host/sdhci-sirf.c 2014-08-14 03:38:34.000000000 +0200
  92976. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-sirf.c 2014-09-11 18:06:03.034042099 +0200
  92977. @@ -28,7 +28,11 @@
  92978. }
  92979. static struct sdhci_ops sdhci_sirf_ops = {
  92980. + .set_clock = sdhci_set_clock,
  92981. .get_max_clock = sdhci_sirf_get_max_clk,
  92982. + .set_bus_width = sdhci_set_bus_width,
  92983. + .reset = sdhci_reset,
  92984. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92985. };
  92986. static struct sdhci_pltfm_data sdhci_sirf_pdata = {
  92987. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-spear.c linux-imx6-3.14/drivers/mmc/host/sdhci-spear.c
  92988. --- linux-3.14.17/drivers/mmc/host/sdhci-spear.c 2014-08-14 03:38:34.000000000 +0200
  92989. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-spear.c 2014-09-11 18:06:03.034042099 +0200
  92990. @@ -37,7 +37,10 @@
  92991. /* sdhci ops */
  92992. static const struct sdhci_ops sdhci_pltfm_ops = {
  92993. - /* Nothing to do for now. */
  92994. + .set_clock = sdhci_set_clock,
  92995. + .set_bus_width = sdhci_set_bus_width,
  92996. + .reset = sdhci_reset,
  92997. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  92998. };
  92999. /* gpio card detection interrupt handler */
  93000. diff -Nur linux-3.14.17/drivers/mmc/host/sdhci-tegra.c linux-imx6-3.14/drivers/mmc/host/sdhci-tegra.c
  93001. --- linux-3.14.17/drivers/mmc/host/sdhci-tegra.c 2014-08-14 03:38:34.000000000 +0200
  93002. +++ linux-imx6-3.14/drivers/mmc/host/sdhci-tegra.c 2014-09-11 18:06:03.034042099 +0200
  93003. @@ -48,19 +48,6 @@
  93004. int power_gpio;
  93005. };
  93006. -static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
  93007. -{
  93008. - u32 val;
  93009. -
  93010. - if (unlikely(reg == SDHCI_PRESENT_STATE)) {
  93011. - /* Use wp_gpio here instead? */
  93012. - val = readl(host->ioaddr + reg);
  93013. - return val | SDHCI_WRITE_PROTECT;
  93014. - }
  93015. -
  93016. - return readl(host->ioaddr + reg);
  93017. -}
  93018. -
  93019. static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
  93020. {
  93021. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  93022. @@ -108,12 +95,14 @@
  93023. return mmc_gpio_get_ro(host->mmc);
  93024. }
  93025. -static void tegra_sdhci_reset_exit(struct sdhci_host *host, u8 mask)
  93026. +static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
  93027. {
  93028. struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  93029. struct sdhci_tegra *tegra_host = pltfm_host->priv;
  93030. const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
  93031. + sdhci_reset(host, mask);
  93032. +
  93033. if (!(mask & SDHCI_RESET_ALL))
  93034. return;
  93035. @@ -127,7 +116,7 @@
  93036. }
  93037. }
  93038. -static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width)
  93039. +static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
  93040. {
  93041. u32 ctrl;
  93042. @@ -144,16 +133,16 @@
  93043. ctrl &= ~SDHCI_CTRL_4BITBUS;
  93044. }
  93045. sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
  93046. - return 0;
  93047. }
  93048. static const struct sdhci_ops tegra_sdhci_ops = {
  93049. .get_ro = tegra_sdhci_get_ro,
  93050. - .read_l = tegra_sdhci_readl,
  93051. .read_w = tegra_sdhci_readw,
  93052. .write_l = tegra_sdhci_writel,
  93053. - .platform_bus_width = tegra_sdhci_buswidth,
  93054. - .platform_reset_exit = tegra_sdhci_reset_exit,
  93055. + .set_clock = sdhci_set_clock,
  93056. + .set_bus_width = tegra_sdhci_set_bus_width,
  93057. + .reset = tegra_sdhci_reset,
  93058. + .set_uhs_signaling = sdhci_set_uhs_signaling,
  93059. };
  93060. static const struct sdhci_pltfm_data sdhci_tegra20_pdata = {
  93061. diff -Nur linux-3.14.17/drivers/mtd/chips/cfi_cmdset_0002.c linux-imx6-3.14/drivers/mtd/chips/cfi_cmdset_0002.c
  93062. --- linux-3.14.17/drivers/mtd/chips/cfi_cmdset_0002.c 2014-08-14 03:38:34.000000000 +0200
  93063. +++ linux-imx6-3.14/drivers/mtd/chips/cfi_cmdset_0002.c 2014-09-11 18:06:03.038042115 +0200
  93064. @@ -1058,17 +1058,13 @@
  93065. #define UDELAY(map, chip, adr, usec) \
  93066. do { \
  93067. - mutex_unlock(&chip->mutex); \
  93068. cfi_udelay(usec); \
  93069. - mutex_lock(&chip->mutex); \
  93070. } while (0)
  93071. #define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec) \
  93072. do { \
  93073. - mutex_unlock(&chip->mutex); \
  93074. INVALIDATE_CACHED_RANGE(map, adr, len); \
  93075. cfi_udelay(usec); \
  93076. - mutex_lock(&chip->mutex); \
  93077. } while (0)
  93078. #endif
  93079. diff -Nur linux-3.14.17/drivers/mtd/ubi/build.c linux-imx6-3.14/drivers/mtd/ubi/build.c
  93080. --- linux-3.14.17/drivers/mtd/ubi/build.c 2014-08-14 03:38:34.000000000 +0200
  93081. +++ linux-imx6-3.14/drivers/mtd/ubi/build.c 2014-09-11 18:06:03.074042259 +0200
  93082. @@ -640,7 +640,7 @@
  93083. dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
  93084. dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
  93085. - if (ubi->mtd->numeraseregions != 0) {
  93086. + if (ubi->mtd->numeraseregions > 1) {
  93087. /*
  93088. * Some flashes have several erase regions. Different regions
  93089. * may have different eraseblock size and other
  93090. diff -Nur linux-3.14.17/drivers/mxc/asrc/Kconfig linux-imx6-3.14/drivers/mxc/asrc/Kconfig
  93091. --- linux-3.14.17/drivers/mxc/asrc/Kconfig 1970-01-01 01:00:00.000000000 +0100
  93092. +++ linux-imx6-3.14/drivers/mxc/asrc/Kconfig 2014-09-11 18:06:03.078042276 +0200
  93093. @@ -0,0 +1,14 @@
  93094. +#
  93095. +# ASRC configuration
  93096. +#
  93097. +
  93098. +menu "MXC Asynchronous Sample Rate Converter support"
  93099. +
  93100. +config MXC_ASRC
  93101. + tristate "ASRC support"
  93102. + depends on SOC_IMX35 || SOC_IMX53 || SOC_IMX6Q
  93103. + select SND_SOC_FSL_ASRC
  93104. + ---help---
  93105. + Say Y to get the ASRC service.
  93106. +
  93107. +endmenu
  93108. diff -Nur linux-3.14.17/drivers/mxc/asrc/Makefile linux-imx6-3.14/drivers/mxc/asrc/Makefile
  93109. --- linux-3.14.17/drivers/mxc/asrc/Makefile 1970-01-01 01:00:00.000000000 +0100
  93110. +++ linux-imx6-3.14/drivers/mxc/asrc/Makefile 2014-09-11 18:06:03.078042276 +0200
  93111. @@ -0,0 +1,4 @@
  93112. +#
  93113. +# Makefile for the kernel Asynchronous Sample Rate Converter driver
  93114. +#
  93115. +obj-$(CONFIG_MXC_ASRC) += mxc_asrc.o
  93116. diff -Nur linux-3.14.17/drivers/mxc/asrc/mxc_asrc.c linux-imx6-3.14/drivers/mxc/asrc/mxc_asrc.c
  93117. --- linux-3.14.17/drivers/mxc/asrc/mxc_asrc.c 1970-01-01 01:00:00.000000000 +0100
  93118. +++ linux-imx6-3.14/drivers/mxc/asrc/mxc_asrc.c 2014-09-11 18:06:03.078042276 +0200
  93119. @@ -0,0 +1,1957 @@
  93120. +/*
  93121. + * Freescale Asynchronous Sample Rate Converter (ASRC) driver
  93122. + *
  93123. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  93124. + *
  93125. + * This file is licensed under the terms of the GNU General Public License
  93126. + * version 2. This program is licensed "as is" without any warranty of any
  93127. + * kind, whether express or implied.
  93128. + */
  93129. +
  93130. +#include <linux/clk.h>
  93131. +#include <linux/slab.h>
  93132. +#include <linux/delay.h>
  93133. +#include <linux/sched.h>
  93134. +#include <linux/regmap.h>
  93135. +#include <linux/module.h>
  93136. +#include <linux/proc_fs.h>
  93137. +#include <linux/pagemap.h>
  93138. +#include <linux/interrupt.h>
  93139. +#include <linux/miscdevice.h>
  93140. +#include <linux/dma-mapping.h>
  93141. +#include <linux/of_platform.h>
  93142. +#include <linux/platform_data/dma-imx.h>
  93143. +
  93144. +#include <linux/mxc_asrc.h>
  93145. +
  93146. +#define ASRC_PROC_PATH "driver/asrc"
  93147. +
  93148. +#define ASRC_RATIO_DECIMAL_DEPTH 26
  93149. +
  93150. +#define pair_err(fmt, ...) \
  93151. + dev_err(asrc->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
  93152. +
  93153. +#define pair_dbg(fmt, ...) \
  93154. + dev_dbg(asrc->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
  93155. +
  93156. +DEFINE_SPINLOCK(data_lock);
  93157. +DEFINE_SPINLOCK(pair_lock);
  93158. +
  93159. +/* Sample rates are aligned with that defined in pcm.h file */
  93160. +static const unsigned char asrc_process_table[][8][2] = {
  93161. + /* 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
  93162. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
  93163. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
  93164. + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
  93165. + {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
  93166. + {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
  93167. + {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
  93168. + {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
  93169. + {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
  93170. + {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
  93171. + {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
  93172. + {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
  93173. + {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
  93174. + {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
  93175. +};
  93176. +
  93177. +static struct asrc_data *asrc;
  93178. +
  93179. +/*
  93180. + * The following tables map the relationship between asrc_inclk/asrc_outclk in
  93181. + * mxc_asrc.h and the registers of ASRCSR
  93182. + */
  93183. +static unsigned char input_clk_map_v1[] = {
  93184. + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
  93185. +};
  93186. +
  93187. +static unsigned char output_clk_map_v1[] = {
  93188. + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
  93189. +};
  93190. +
  93191. +/* V2 uses the same map for input and output */
  93192. +static unsigned char input_clk_map_v2[] = {
  93193. +/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
  93194. + 0x0, 0x1, 0x2, 0x7, 0x4, 0x5, 0x6, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xf, 0xe, 0xd,
  93195. +};
  93196. +
  93197. +static unsigned char output_clk_map_v2[] = {
  93198. +/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf */
  93199. + 0x8, 0x9, 0xa, 0x7, 0xc, 0x5, 0x6, 0xb, 0x0, 0x1, 0x2, 0x3, 0x4, 0xf, 0xe, 0xd,
  93200. +};
  93201. +
  93202. +static unsigned char *input_clk_map, *output_clk_map;
  93203. +
  93204. +enum mxc_asrc_type {
  93205. + IMX35_ASRC,
  93206. + IMX53_ASRC,
  93207. +};
  93208. +
  93209. +static const struct platform_device_id mxc_asrc_devtype[] = {
  93210. + {
  93211. + .name = "imx35-asrc",
  93212. + .driver_data = IMX35_ASRC,
  93213. + }, {
  93214. + .name = "imx53-asrc",
  93215. + .driver_data = IMX53_ASRC,
  93216. + }, {
  93217. + /* sentinel */
  93218. + }
  93219. +};
  93220. +MODULE_DEVICE_TABLE(platform, mxc_asrc_devtype);
  93221. +
  93222. +static const struct of_device_id fsl_asrc_ids[] = {
  93223. + {
  93224. + .compatible = "fsl,imx35-asrc",
  93225. + .data = &mxc_asrc_devtype[IMX35_ASRC],
  93226. + }, {
  93227. + .compatible = "fsl,imx53-asrc",
  93228. + .data = &mxc_asrc_devtype[IMX53_ASRC],
  93229. + }, {
  93230. + /* sentinel */
  93231. + }
  93232. +};
  93233. +MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
  93234. +
  93235. +
  93236. +#ifdef DEBUG
  93237. +u32 asrc_reg[] = {
  93238. + REG_ASRCTR,
  93239. + REG_ASRIER,
  93240. + REG_ASRCNCR,
  93241. + REG_ASRCFG,
  93242. + REG_ASRCSR,
  93243. + REG_ASRCDR1,
  93244. + REG_ASRCDR2,
  93245. + REG_ASRSTR,
  93246. + REG_ASRRA,
  93247. + REG_ASRRB,
  93248. + REG_ASRRC,
  93249. + REG_ASRPM1,
  93250. + REG_ASRPM2,
  93251. + REG_ASRPM3,
  93252. + REG_ASRPM4,
  93253. + REG_ASRPM5,
  93254. + REG_ASRTFR1,
  93255. + REG_ASRCCR,
  93256. + REG_ASRIDRHA,
  93257. + REG_ASRIDRLA,
  93258. + REG_ASRIDRHB,
  93259. + REG_ASRIDRLB,
  93260. + REG_ASRIDRHC,
  93261. + REG_ASRIDRLC,
  93262. + REG_ASR76K,
  93263. + REG_ASR56K,
  93264. + REG_ASRMCRA,
  93265. + REG_ASRFSTA,
  93266. + REG_ASRMCRB,
  93267. + REG_ASRFSTB,
  93268. + REG_ASRMCRC,
  93269. + REG_ASRFSTC,
  93270. + REG_ASRMCR1A,
  93271. + REG_ASRMCR1B,
  93272. + REG_ASRMCR1C,
  93273. +};
  93274. +
  93275. +static void dump_regs(void)
  93276. +{
  93277. + u32 reg, val;
  93278. + int i;
  93279. +
  93280. + for (i = 0; i < ARRAY_SIZE(asrc_reg); i++) {
  93281. + reg = asrc_reg[i];
  93282. + regmap_read(asrc->regmap, reg, &val);
  93283. + dev_dbg(asrc->dev, "REG addr=0x%x val=0x%x\n", reg, val);
  93284. + }
  93285. +}
  93286. +#else
  93287. +static void dump_regs(void) {}
  93288. +#endif
  93289. +
  93290. +/* Only used for Ideal Ratio mode */
  93291. +static int asrc_set_clock_ratio(enum asrc_pair_index index,
  93292. + int inrate, int outrate)
  93293. +{
  93294. + unsigned long val = 0;
  93295. + int integ, i;
  93296. +
  93297. + if (outrate == 0) {
  93298. + dev_err(asrc->dev, "wrong output sample rate: %d\n", outrate);
  93299. + return -EINVAL;
  93300. + }
  93301. +
  93302. + /* Formula: r = (1 << ASRC_RATIO_DECIMAL_DEPTH) / outrate * inrate; */
  93303. + for (integ = 0; inrate >= outrate; integ++)
  93304. + inrate -= outrate;
  93305. +
  93306. + val |= (integ << ASRC_RATIO_DECIMAL_DEPTH);
  93307. +
  93308. + for (i = 1; i <= ASRC_RATIO_DECIMAL_DEPTH; i++) {
  93309. + if ((inrate * 2) >= outrate) {
  93310. + val |= (1 << (ASRC_RATIO_DECIMAL_DEPTH - i));
  93311. + inrate = inrate * 2 - outrate;
  93312. + } else
  93313. + inrate = inrate << 1;
  93314. +
  93315. + if (inrate == 0)
  93316. + break;
  93317. + }
  93318. +
  93319. + regmap_write(asrc->regmap, REG_ASRIDRL(index), val);
  93320. + regmap_write(asrc->regmap, REG_ASRIDRH(index), (val >> 24));
  93321. +
  93322. + return 0;
  93323. +}
  93324. +
  93325. +/* Corresponding to asrc_process_table */
  93326. +static int supported_input_rate[] = {
  93327. + 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
  93328. + 96000, 176400, 192000,
  93329. +};
  93330. +
  93331. +static int supported_output_rate[] = {
  93332. + 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
  93333. +};
  93334. +
  93335. +static int asrc_set_process_configuration(enum asrc_pair_index index,
  93336. + int inrate, int outrate)
  93337. +{
  93338. + int in, out;
  93339. +
  93340. + for (in = 0; in < ARRAY_SIZE(supported_input_rate); in++) {
  93341. + if (inrate == supported_input_rate[in])
  93342. + break;
  93343. + }
  93344. +
  93345. + if (in == ARRAY_SIZE(supported_input_rate)) {
  93346. + dev_err(asrc->dev, "unsupported input sample rate: %d\n", in);
  93347. + return -EINVAL;
  93348. + }
  93349. +
  93350. + for (out = 0; out < ARRAY_SIZE(supported_output_rate); out++) {
  93351. + if (outrate == supported_output_rate[out])
  93352. + break;
  93353. + }
  93354. +
  93355. + if (out == ARRAY_SIZE(supported_output_rate)) {
  93356. + dev_err(asrc->dev, "unsupported output sample rate: %d\n", out);
  93357. + return -EINVAL;
  93358. + }
  93359. +
  93360. + regmap_update_bits(asrc->regmap, REG_ASRCFG,
  93361. + ASRCFG_PREMODx_MASK(index) | ASRCFG_POSTMODx_MASK(index),
  93362. + ASRCFG_PREMOD(index, asrc_process_table[in][out][0]) |
  93363. + ASRCFG_POSTMOD(index, asrc_process_table[in][out][1]));
  93364. +
  93365. + return 0;
  93366. +}
  93367. +
  93368. +static int asrc_get_asrck_clock_divider(int samplerate)
  93369. +{
  93370. + unsigned int prescaler, divider, ratio, ra, i;
  93371. + unsigned long bitclk;
  93372. +
  93373. + if (samplerate == 0) {
  93374. + dev_err(asrc->dev, "invalid sample rate: %d\n", samplerate);
  93375. + return -EINVAL;
  93376. + }
  93377. +
  93378. + bitclk = clk_get_rate(asrc->asrc_clk);
  93379. +
  93380. + ra = bitclk / samplerate;
  93381. + ratio = ra;
  93382. +
  93383. + /* Calculate the prescaler */
  93384. + for (i = 0; ratio > 8; i++)
  93385. + ratio >>= 1;
  93386. +
  93387. + prescaler = i;
  93388. +
  93389. + /* Calculate the divider */
  93390. + divider = i ? (((ra + (1 << (i - 1)) - 1) >> i) - 1) : (ra - 1);
  93391. +
  93392. + /* The totally divider is (2 ^ prescaler) * divider */
  93393. + return (divider << ASRCDRx_AxCPx_WIDTH) + prescaler;
  93394. +}
  93395. +
  93396. +int asrc_req_pair(int chn_num, enum asrc_pair_index *index)
  93397. +{
  93398. + int imax = 0, busy = 0, i, ret = 0;
  93399. + unsigned long lock_flags;
  93400. + struct asrc_pair *pair;
  93401. +
  93402. + spin_lock_irqsave(&data_lock, lock_flags);
  93403. +
  93404. + for (i = ASRC_PAIR_A; i < ASRC_PAIR_MAX_NUM; i++) {
  93405. + pair = &asrc->asrc_pair[i];
  93406. + if (chn_num > pair->chn_max) {
  93407. + imax++;
  93408. + continue;
  93409. + } else if (pair->active) {
  93410. + busy++;
  93411. + continue;
  93412. + }
  93413. + /* Save the current qualified pair */
  93414. + *index = i;
  93415. +
  93416. + /* Check if this pair is a perfect one */
  93417. + if (chn_num == pair->chn_max)
  93418. + break;
  93419. + }
  93420. +
  93421. + if (imax == ASRC_PAIR_MAX_NUM) {
  93422. + dev_err(asrc->dev, "no pair could afford required channel number\n");
  93423. + ret = -EINVAL;
  93424. + } else if (busy == ASRC_PAIR_MAX_NUM) {
  93425. + dev_err(asrc->dev, "all pairs are busy now\n");
  93426. + ret = -EBUSY;
  93427. + } else if (busy + imax >= ASRC_PAIR_MAX_NUM) {
  93428. + dev_err(asrc->dev, "all affordable pairs are busy now\n");
  93429. + ret = -EBUSY;
  93430. + } else {
  93431. + pair = &asrc->asrc_pair[*index];
  93432. + pair->chn_num = chn_num;
  93433. + pair->active = 1;
  93434. + }
  93435. +
  93436. + spin_unlock_irqrestore(&data_lock, lock_flags);
  93437. +
  93438. + if (!ret) {
  93439. + clk_enable(asrc->asrc_clk);
  93440. + clk_prepare_enable(asrc->dma_clk);
  93441. + }
  93442. +
  93443. + return ret;
  93444. +}
  93445. +EXPORT_SYMBOL(asrc_req_pair);
  93446. +
  93447. +void asrc_release_pair(enum asrc_pair_index index)
  93448. +{
  93449. + struct asrc_pair *pair = &asrc->asrc_pair[index];
  93450. + unsigned long lock_flags;
  93451. +
  93452. + spin_lock_irqsave(&data_lock, lock_flags);
  93453. +
  93454. + pair->active = 0;
  93455. + pair->overload_error = 0;
  93456. +
  93457. + spin_unlock_irqrestore(&data_lock, lock_flags);
  93458. +
  93459. + /* Disable PAIR */
  93460. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEx_MASK(index), 0);
  93461. +}
  93462. +EXPORT_SYMBOL(asrc_release_pair);
  93463. +
  93464. +int asrc_config_pair(struct asrc_config *config)
  93465. +{
  93466. + u32 inrate = config->input_sample_rate, indiv;
  93467. + u32 outrate = config->output_sample_rate, outdiv;
  93468. + int ret, channels, index = config->pair;
  93469. + unsigned long lock_flags;
  93470. +
  93471. + /* Set the channel number */
  93472. + spin_lock_irqsave(&data_lock, lock_flags);
  93473. + asrc->asrc_pair[index].chn_num = config->channel_num;
  93474. + spin_unlock_irqrestore(&data_lock, lock_flags);
  93475. +
  93476. + if (asrc->channel_bits > 3)
  93477. + channels = config->channel_num;
  93478. + else
  93479. + channels = (config->channel_num + 1) / 2;
  93480. +
  93481. + /* Update channel number of current pair */
  93482. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  93483. + ASRCNCR_ANCx_MASK(index, asrc->channel_bits),
  93484. + ASRCNCR_ANCx_set(index, channels, asrc->channel_bits));
  93485. +
  93486. + /* Set the clock source */
  93487. + regmap_update_bits(asrc->regmap, REG_ASRCSR,
  93488. + ASRCSR_AICSx_MASK(index) | ASRCSR_AOCSx_MASK(index),
  93489. + ASRCSR_AICS(index, input_clk_map[config->inclk]) |
  93490. + ASRCSR_AOCS(index, output_clk_map[config->outclk]));
  93491. +
  93492. + /* Default setting: Automatic selection for processing mode */
  93493. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  93494. + ASRCTR_ATSx_MASK(index), ASRCTR_ATS(index));
  93495. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_USRx_MASK(index), 0);
  93496. +
  93497. + /* Default Input Clock Divider Setting */
  93498. + switch (config->inclk & ASRCSR_AxCSx_MASK) {
  93499. + case INCLK_SPDIF_RX:
  93500. + indiv = ASRC_PRESCALER_SPDIF_RX;
  93501. + break;
  93502. + case INCLK_SPDIF_TX:
  93503. + indiv = ASRC_PRESCALER_SPDIF_TX;
  93504. + break;
  93505. + case INCLK_ASRCK1_CLK:
  93506. + indiv = asrc_get_asrck_clock_divider(inrate);
  93507. + break;
  93508. + default:
  93509. + switch (config->input_word_width) {
  93510. + case ASRC_WIDTH_16_BIT:
  93511. + indiv = ASRC_PRESCALER_I2S_16BIT;
  93512. + break;
  93513. + case ASRC_WIDTH_24_BIT:
  93514. + indiv = ASRC_PRESCALER_I2S_24BIT;
  93515. + break;
  93516. + default:
  93517. + pair_err("unsupported input word width %d\n",
  93518. + config->input_word_width);
  93519. + return -EINVAL;
  93520. + }
  93521. + break;
  93522. + }
  93523. +
  93524. + /* Default Output Clock Divider Setting */
  93525. + switch (config->outclk & ASRCSR_AxCSx_MASK) {
  93526. + case OUTCLK_SPDIF_RX:
  93527. + outdiv = ASRC_PRESCALER_SPDIF_RX;
  93528. + break;
  93529. + case OUTCLK_SPDIF_TX:
  93530. + outdiv = ASRC_PRESCALER_SPDIF_TX;
  93531. + break;
  93532. + case OUTCLK_ASRCK1_CLK:
  93533. + if ((config->inclk & ASRCSR_AxCSx_MASK) == INCLK_NONE)
  93534. + outdiv = ASRC_PRESCALER_IDEAL_RATIO;
  93535. + else
  93536. + outdiv = asrc_get_asrck_clock_divider(outrate);
  93537. + break;
  93538. + default:
  93539. + switch (config->output_word_width) {
  93540. + case ASRC_WIDTH_16_BIT:
  93541. + outdiv = ASRC_PRESCALER_I2S_16BIT;
  93542. + break;
  93543. + case ASRC_WIDTH_24_BIT:
  93544. + outdiv = ASRC_PRESCALER_I2S_24BIT;
  93545. + break;
  93546. + default:
  93547. + pair_err("unsupported output word width %d\n",
  93548. + config->input_word_width);
  93549. + return -EINVAL;
  93550. + }
  93551. + break;
  93552. + }
  93553. +
  93554. + /* indiv and outdiv'd include prescaler's value, so add its MASK too */
  93555. + regmap_update_bits(asrc->regmap, REG_ASRCDR(index),
  93556. + ASRCDRx_AOCPx_MASK(index) | ASRCDRx_AICPx_MASK(index) |
  93557. + ASRCDRx_AOCDx_MASK(index) | ASRCDRx_AICDx_MASK(index),
  93558. + ASRCDRx_AOCP(index, outdiv) | ASRCDRx_AICP(index, indiv));
  93559. +
  93560. + /* Check whether ideal ratio is a must */
  93561. + switch (config->inclk & ASRCSR_AxCSx_MASK) {
  93562. + case INCLK_NONE:
  93563. + /* Clear ASTSx bit to use ideal ratio */
  93564. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  93565. + ASRCTR_ATSx_MASK(index), 0);
  93566. +
  93567. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  93568. + ASRCTR_IDRx_MASK(index) | ASRCTR_USRx_MASK(index),
  93569. + ASRCTR_IDR(index) | ASRCTR_USR(index));
  93570. +
  93571. + ret = asrc_set_clock_ratio(index, inrate, outrate);
  93572. + if (ret)
  93573. + return ret;
  93574. +
  93575. + ret = asrc_set_process_configuration(index, inrate, outrate);
  93576. + if (ret)
  93577. + return ret;
  93578. +
  93579. + break;
  93580. + case INCLK_ASRCK1_CLK:
  93581. + /* This case and default are both remained for v1 */
  93582. + if (inrate == 44100 || inrate == 88200) {
  93583. + pair_err("unsupported sample rate %d by selected clock\n",
  93584. + inrate);
  93585. + return -EINVAL;
  93586. + }
  93587. + break;
  93588. + default:
  93589. + if ((config->outclk & ASRCSR_AxCSx_MASK) != OUTCLK_ASRCK1_CLK)
  93590. + break;
  93591. +
  93592. + if (outrate == 44100 || outrate == 88200) {
  93593. + pair_err("unsupported sample rate %d by selected clock\n",
  93594. + outrate);
  93595. + return -EINVAL;
  93596. + }
  93597. + break;
  93598. + }
  93599. +
  93600. + /* Config input and output wordwidth */
  93601. + if (config->output_word_width == ASRC_WIDTH_8_BIT) {
  93602. + pair_err("unsupported wordwidth for output: 8bit\n");
  93603. + pair_err("output only support: 16bit or 24bit\n");
  93604. + return -EINVAL;
  93605. + }
  93606. +
  93607. + regmap_update_bits(asrc->regmap, REG_ASRMCR1(index),
  93608. + ASRMCR1x_OW16_MASK | ASRMCR1x_IWD_MASK,
  93609. + ASRMCR1x_OW16(config->output_word_width) |
  93610. + ASRMCR1x_IWD(config->input_word_width));
  93611. +
  93612. + /* Enable BUFFER STALL */
  93613. + regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
  93614. + ASRMCRx_BUFSTALLx_MASK, ASRMCRx_BUFSTALLx);
  93615. +
  93616. + /* Set Threshold for input and output FIFO */
  93617. + return asrc_set_watermark(index, ASRC_INPUTFIFO_THRESHOLD,
  93618. + ASRC_INPUTFIFO_THRESHOLD);
  93619. +}
  93620. +EXPORT_SYMBOL(asrc_config_pair);
  93621. +
  93622. +int asrc_set_watermark(enum asrc_pair_index index, u32 in_wm, u32 out_wm)
  93623. +{
  93624. + if (in_wm > ASRC_FIFO_THRESHOLD_MAX || out_wm > ASRC_FIFO_THRESHOLD_MAX) {
  93625. + pair_err("invalid watermark!\n");
  93626. + return -EINVAL;
  93627. + }
  93628. +
  93629. + return regmap_update_bits(asrc->regmap, REG_ASRMCR(index),
  93630. + ASRMCRx_EXTTHRSHx_MASK | ASRMCRx_INFIFO_THRESHOLD_MASK |
  93631. + ASRMCRx_OUTFIFO_THRESHOLD_MASK,
  93632. + ASRMCRx_EXTTHRSHx | ASRMCRx_INFIFO_THRESHOLD(in_wm) |
  93633. + ASRMCRx_OUTFIFO_THRESHOLD(out_wm));
  93634. +}
  93635. +EXPORT_SYMBOL(asrc_set_watermark);
  93636. +
  93637. +void asrc_start_conv(enum asrc_pair_index index)
  93638. +{
  93639. + int reg, retry, channels, i;
  93640. +
  93641. + regmap_update_bits(asrc->regmap, REG_ASRCTR,
  93642. + ASRCTR_ASRCEx_MASK(index), ASRCTR_ASRCE(index));
  93643. +
  93644. + /* Wait for status of initialization */
  93645. + for (retry = 10, reg = 0; !reg && retry; --retry) {
  93646. + udelay(5);
  93647. + regmap_read(asrc->regmap, REG_ASRCFG, &reg);
  93648. + reg &= ASRCFG_INIRQx_MASK(index);
  93649. + }
  93650. +
  93651. + /* Set the input fifo to ASRC STALL level */
  93652. + regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
  93653. + channels = ASRCNCR_ANCx_get(index, reg, asrc->channel_bits);
  93654. + for (i = 0; i < channels * 4; i++)
  93655. + regmap_write(asrc->regmap, REG_ASRDI(index), 0);
  93656. +
  93657. + /* Overload Interrupt Enable */
  93658. + regmap_write(asrc->regmap, REG_ASRIER, ASRIER_AOLIE);
  93659. +}
  93660. +EXPORT_SYMBOL(asrc_start_conv);
  93661. +
  93662. +void asrc_stop_conv(enum asrc_pair_index index)
  93663. +{
  93664. + regmap_update_bits(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEx_MASK(index), 0);
  93665. +}
  93666. +EXPORT_SYMBOL(asrc_stop_conv);
  93667. +
  93668. +void asrc_finish_conv(enum asrc_pair_index index)
  93669. +{
  93670. + clk_disable_unprepare(asrc->dma_clk);
  93671. + clk_disable(asrc->asrc_clk);
  93672. +}
  93673. +EXPORT_SYMBOL(asrc_finish_conv);
  93674. +
  93675. +#define SET_OVERLOAD_ERR(index, err, msg) \
  93676. + do { \
  93677. + asrc->asrc_pair[index].overload_error |= err; \
  93678. + pair_dbg(msg); \
  93679. + } while (0)
  93680. +
  93681. +static irqreturn_t asrc_isr(int irq, void *dev_id)
  93682. +{
  93683. + enum asrc_pair_index index;
  93684. + u32 status;
  93685. +
  93686. + regmap_read(asrc->regmap, REG_ASRSTR, &status);
  93687. +
  93688. + for (index = ASRC_PAIR_A; index < ASRC_PAIR_MAX_NUM; index++) {
  93689. + if (asrc->asrc_pair[index].active == 0)
  93690. + continue;
  93691. + if (status & ASRSTR_ATQOL)
  93692. + SET_OVERLOAD_ERR(index, ASRC_TASK_Q_OVERLOAD,
  93693. + "Task Queue FIFO overload");
  93694. + if (status & ASRSTR_AOOL(index))
  93695. + SET_OVERLOAD_ERR(index, ASRC_OUTPUT_TASK_OVERLOAD,
  93696. + "Output Task Overload");
  93697. + if (status & ASRSTR_AIOL(index))
  93698. + SET_OVERLOAD_ERR(index, ASRC_INPUT_TASK_OVERLOAD,
  93699. + "Input Task Overload");
  93700. + if (status & ASRSTR_AODO(index))
  93701. + SET_OVERLOAD_ERR(index, ASRC_OUTPUT_BUFFER_OVERFLOW,
  93702. + "Output Data Buffer has overflowed");
  93703. + if (status & ASRSTR_AIDU(index))
  93704. + SET_OVERLOAD_ERR(index, ASRC_INPUT_BUFFER_UNDERRUN,
  93705. + "Input Data Buffer has underflowed");
  93706. + }
  93707. +
  93708. + /* Clean overload error */
  93709. + regmap_write(asrc->regmap, REG_ASRSTR, ASRSTR_AOLE);
  93710. +
  93711. + return IRQ_HANDLED;
  93712. +}
  93713. +
  93714. +void asrc_get_status(struct asrc_status_flags *flags)
  93715. +{
  93716. + enum asrc_pair_index index = flags->index;
  93717. + unsigned long lock_flags;
  93718. +
  93719. + spin_lock_irqsave(&data_lock, lock_flags);
  93720. +
  93721. + flags->overload_error = asrc->asrc_pair[index].overload_error;
  93722. +
  93723. + spin_unlock_irqrestore(&data_lock, lock_flags);
  93724. +}
  93725. +EXPORT_SYMBOL(asrc_get_status);
  93726. +
  93727. +u32 asrc_get_per_addr(enum asrc_pair_index index, bool in)
  93728. +{
  93729. + return asrc->paddr + (in ? REG_ASRDI(index) : REG_ASRDO(index));
  93730. +}
  93731. +EXPORT_SYMBOL(asrc_get_per_addr);
  93732. +
  93733. +static int mxc_init_asrc(void)
  93734. +{
  93735. + /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
  93736. + regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
  93737. +
  93738. + /* Disable interrupt by default */
  93739. + regmap_write(asrc->regmap, REG_ASRIER, 0x0);
  93740. +
  93741. + /* Default 2: 6: 2 channel assignment */
  93742. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  93743. + ASRCNCR_ANCx_MASK(ASRC_PAIR_A, asrc->channel_bits),
  93744. + ASRCNCR_ANCx_set(ASRC_PAIR_A, 2, asrc->channel_bits));
  93745. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  93746. + ASRCNCR_ANCx_MASK(ASRC_PAIR_B, asrc->channel_bits),
  93747. + ASRCNCR_ANCx_set(ASRC_PAIR_B, 6, asrc->channel_bits));
  93748. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  93749. + ASRCNCR_ANCx_MASK(ASRC_PAIR_C, asrc->channel_bits),
  93750. + ASRCNCR_ANCx_set(ASRC_PAIR_C, 2, asrc->channel_bits));
  93751. +
  93752. + /* Parameter Registers recommended settings */
  93753. + regmap_write(asrc->regmap, REG_ASRPM1, 0x7fffff);
  93754. + regmap_write(asrc->regmap, REG_ASRPM2, 0x255555);
  93755. + regmap_write(asrc->regmap, REG_ASRPM3, 0xff7280);
  93756. + regmap_write(asrc->regmap, REG_ASRPM4, 0xff7280);
  93757. + regmap_write(asrc->regmap, REG_ASRPM5, 0xff7280);
  93758. +
  93759. + /* Base address for task queue FIFO. Set to 0x7C */
  93760. + regmap_update_bits(asrc->regmap, REG_ASRTFR1,
  93761. + ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
  93762. +
  93763. + /* Set the processing clock for 76KHz, 133M */
  93764. + regmap_write(asrc->regmap, REG_ASR76K, 0x06D6);
  93765. +
  93766. + /* Set the processing clock for 56KHz, 133M */
  93767. + return regmap_write(asrc->regmap, REG_ASR56K, 0x0947);
  93768. +}
  93769. +
  93770. +#define ASRC_xPUT_DMA_CALLBACK(in) \
  93771. + ((in) ? asrc_input_dma_callback : asrc_output_dma_callback)
  93772. +
  93773. +static void asrc_input_dma_callback(void *data)
  93774. +{
  93775. + struct asrc_pair_params *params = (struct asrc_pair_params *)data;
  93776. +
  93777. + dma_unmap_sg(NULL, params->input_sg, params->input_sg_nodes,
  93778. + DMA_MEM_TO_DEV);
  93779. +
  93780. + complete(&params->input_complete);
  93781. +
  93782. + schedule_work(&params->task_output_work);
  93783. +}
  93784. +
  93785. +static void asrc_output_dma_callback(void *data)
  93786. +{
  93787. + struct asrc_pair_params *params = (struct asrc_pair_params *)data;
  93788. +
  93789. + dma_unmap_sg(NULL, params->output_sg, params->output_sg_nodes,
  93790. + DMA_DEV_TO_MEM);
  93791. +
  93792. + complete(&params->output_complete);
  93793. +}
  93794. +
  93795. +static unsigned int asrc_get_output_FIFO_size(enum asrc_pair_index index)
  93796. +{
  93797. + u32 val;
  93798. +
  93799. + regmap_read(asrc->regmap, REG_ASRFST(index), &val);
  93800. +
  93801. + val &= ASRFSTx_OUTPUT_FIFO_MASK;
  93802. +
  93803. + return val >> ASRFSTx_OUTPUT_FIFO_SHIFT;
  93804. +}
  93805. +
  93806. +static u32 asrc_read_one_from_output_FIFO(enum asrc_pair_index index)
  93807. +{
  93808. + u32 val;
  93809. +
  93810. + regmap_read(asrc->regmap, REG_ASRDO(index), &val);
  93811. +
  93812. + return val;
  93813. +}
  93814. +
  93815. +static void asrc_read_output_FIFO(struct asrc_pair_params *params)
  93816. +{
  93817. + u32 *reg24 = params->output_last_period.dma_vaddr;
  93818. + u16 *reg16 = params->output_last_period.dma_vaddr;
  93819. + enum asrc_pair_index index = params->index;
  93820. + u32 i, j, reg, size, t_size;
  93821. + bool bit24 = false;
  93822. +
  93823. + if (params->output_word_width == ASRC_WIDTH_24_BIT)
  93824. + bit24 = true;
  93825. +
  93826. + t_size = 0;
  93827. + do {
  93828. + size = asrc_get_output_FIFO_size(index);
  93829. + for (i = 0; i < size; i++) {
  93830. + for (j = 0; j < params->channel_nums; j++) {
  93831. + reg = asrc_read_one_from_output_FIFO(index);
  93832. + if (bit24) {
  93833. + *(reg24) = reg;
  93834. + reg24++;
  93835. + } else {
  93836. + *(reg16) = (u16)reg;
  93837. + reg16++;
  93838. + }
  93839. + }
  93840. + }
  93841. + t_size += size;
  93842. + } while (size);
  93843. +
  93844. + if (t_size > params->last_period_sample)
  93845. + t_size = params->last_period_sample;
  93846. +
  93847. + params->output_last_period.length = t_size * params->channel_nums * 2;
  93848. + if (bit24)
  93849. + params->output_last_period.length *= 2;
  93850. +}
  93851. +
  93852. +static void asrc_output_task_worker(struct work_struct *w)
  93853. +{
  93854. + struct asrc_pair_params *params =
  93855. + container_of(w, struct asrc_pair_params, task_output_work);
  93856. + enum asrc_pair_index index = params->index;
  93857. + unsigned long lock_flags;
  93858. +
  93859. + if (!wait_for_completion_interruptible_timeout(&params->output_complete, HZ / 10)) {
  93860. + pair_err("output dma task timeout\n");
  93861. + return;
  93862. + }
  93863. +
  93864. + init_completion(&params->output_complete);
  93865. +
  93866. + spin_lock_irqsave(&pair_lock, lock_flags);
  93867. + if (!params->pair_hold) {
  93868. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  93869. + return;
  93870. + }
  93871. + asrc_read_output_FIFO(params);
  93872. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  93873. +
  93874. + complete(&params->lastperiod_complete);
  93875. +}
  93876. +
  93877. +static void mxc_free_dma_buf(struct asrc_pair_params *params)
  93878. +{
  93879. + if (params->input_dma_total.dma_vaddr != NULL) {
  93880. + kfree(params->input_dma_total.dma_vaddr);
  93881. + params->input_dma_total.dma_vaddr = NULL;
  93882. + }
  93883. +
  93884. + if (params->output_dma_total.dma_vaddr != NULL) {
  93885. + kfree(params->output_dma_total.dma_vaddr);
  93886. + params->output_dma_total.dma_vaddr = NULL;
  93887. + }
  93888. +
  93889. + if (params->output_last_period.dma_vaddr) {
  93890. + dma_free_coherent(asrc->dev, 1024 * params->last_period_sample,
  93891. + params->output_last_period.dma_vaddr,
  93892. + params->output_last_period.dma_paddr);
  93893. + params->output_last_period.dma_vaddr = NULL;
  93894. + }
  93895. +}
  93896. +
  93897. +static int mxc_allocate_dma_buf(struct asrc_pair_params *params)
  93898. +{
  93899. + struct dma_block *input_a, *output_a, *last_period;
  93900. + enum asrc_pair_index index = params->index;
  93901. +
  93902. + input_a = &params->input_dma_total;
  93903. + output_a = &params->output_dma_total;
  93904. + last_period = &params->output_last_period;
  93905. +
  93906. + input_a->dma_vaddr = kzalloc(input_a->length, GFP_KERNEL);
  93907. + if (!input_a->dma_vaddr) {
  93908. + pair_err("failed to allocate input dma buffer\n");
  93909. + goto exit;
  93910. + }
  93911. + input_a->dma_paddr = virt_to_dma(NULL, input_a->dma_vaddr);
  93912. +
  93913. + output_a->dma_vaddr = kzalloc(output_a->length, GFP_KERNEL);
  93914. + if (!output_a->dma_vaddr) {
  93915. + pair_err("failed to allocate output dma buffer\n");
  93916. + goto exit;
  93917. + }
  93918. + output_a->dma_paddr = virt_to_dma(NULL, output_a->dma_vaddr);
  93919. +
  93920. + last_period->dma_vaddr = dma_alloc_coherent(asrc->dev,
  93921. + 1024 * params->last_period_sample,
  93922. + &last_period->dma_paddr, GFP_KERNEL);
  93923. + if (!last_period->dma_vaddr) {
  93924. + pair_err("failed to allocate last period buffer\n");
  93925. + goto exit;
  93926. + }
  93927. +
  93928. + return 0;
  93929. +
  93930. +exit:
  93931. + mxc_free_dma_buf(params);
  93932. +
  93933. + return -ENOBUFS;
  93934. +}
  93935. +
  93936. +static struct dma_chan *imx_asrc_get_dma_channel(enum asrc_pair_index index, bool in)
  93937. +{
  93938. + char name[4];
  93939. +
  93940. + sprintf(name, "%cx%c", in ? 'r' : 't', index + 'a');
  93941. +
  93942. + return dma_request_slave_channel(asrc->dev, name);
  93943. +}
  93944. +
  93945. +static int imx_asrc_dma_config(struct asrc_pair_params *params,
  93946. + struct dma_chan *chan, u32 dma_addr,
  93947. + void *buf_addr, u32 buf_len, bool in,
  93948. + enum asrc_word_width word_width)
  93949. +{
  93950. + enum asrc_pair_index index = params->index;
  93951. + struct dma_async_tx_descriptor *desc;
  93952. + struct dma_slave_config slave_config;
  93953. + enum dma_slave_buswidth buswidth;
  93954. + struct scatterlist *sg;
  93955. + unsigned int sg_nent, i;
  93956. + int ret;
  93957. +
  93958. + if (in) {
  93959. + sg = params->input_sg;
  93960. + sg_nent = params->input_sg_nodes;
  93961. + desc = params->desc_in;
  93962. + } else {
  93963. + sg = params->output_sg;
  93964. + sg_nent = params->output_sg_nodes;
  93965. + desc = params->desc_out;
  93966. + }
  93967. +
  93968. + switch (word_width) {
  93969. + case ASRC_WIDTH_16_BIT:
  93970. + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  93971. + break;
  93972. + case ASRC_WIDTH_24_BIT:
  93973. + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
  93974. + break;
  93975. + default:
  93976. + pair_err("invalid word width\n");
  93977. + return -EINVAL;
  93978. + }
  93979. +
  93980. + slave_config.dma_request0 = 0;
  93981. + slave_config.dma_request1 = 0;
  93982. +
  93983. + if (in) {
  93984. + slave_config.direction = DMA_MEM_TO_DEV;
  93985. + slave_config.dst_addr = dma_addr;
  93986. + slave_config.dst_addr_width = buswidth;
  93987. + slave_config.dst_maxburst =
  93988. + params->input_wm * params->channel_nums / buswidth;
  93989. + } else {
  93990. + slave_config.direction = DMA_DEV_TO_MEM;
  93991. + slave_config.src_addr = dma_addr;
  93992. + slave_config.src_addr_width = buswidth;
  93993. + slave_config.src_maxburst =
  93994. + params->output_wm * params->channel_nums / buswidth;
  93995. + }
  93996. + ret = dmaengine_slave_config(chan, &slave_config);
  93997. + if (ret) {
  93998. + pair_err("failed to config dmaengine for %sput task: %d\n",
  93999. + in ? "in" : "out", ret);
  94000. + return -EINVAL;
  94001. + }
  94002. +
  94003. + sg_init_table(sg, sg_nent);
  94004. + switch (sg_nent) {
  94005. + case 1:
  94006. + sg_init_one(sg, buf_addr, buf_len);
  94007. + break;
  94008. + case 2:
  94009. + case 3:
  94010. + case 4:
  94011. + for (i = 0; i < (sg_nent - 1); i++)
  94012. + sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
  94013. + ASRC_MAX_BUFFER_SIZE);
  94014. +
  94015. + sg_set_buf(&sg[i], buf_addr + i * ASRC_MAX_BUFFER_SIZE,
  94016. + buf_len - ASRC_MAX_BUFFER_SIZE * i);
  94017. + break;
  94018. + default:
  94019. + pair_err("invalid input DMA nodes number: %d\n", sg_nent);
  94020. + return -EINVAL;
  94021. + }
  94022. +
  94023. + ret = dma_map_sg(NULL, sg, sg_nent, slave_config.direction);
  94024. + if (ret != sg_nent) {
  94025. + pair_err("failed to map dma sg for %sput task\n",
  94026. + in ? "in" : "out");
  94027. + return -EINVAL;
  94028. + }
  94029. +
  94030. + desc = dmaengine_prep_slave_sg(chan, sg, sg_nent,
  94031. + slave_config.direction, DMA_PREP_INTERRUPT);
  94032. + if (!desc) {
  94033. + pair_err("failed to prepare slave sg for %sput task\n",
  94034. + in ? "in" : "out");
  94035. + return -EINVAL;
  94036. + }
  94037. +
  94038. + if (in) {
  94039. + params->desc_in = desc;
  94040. + params->desc_in->callback = asrc_input_dma_callback;
  94041. + } else {
  94042. + params->desc_out = desc;
  94043. + params->desc_out->callback = asrc_output_dma_callback;
  94044. + }
  94045. +
  94046. + desc->callback = ASRC_xPUT_DMA_CALLBACK(in);
  94047. + desc->callback_param = params;
  94048. +
  94049. + return 0;
  94050. +}
  94051. +
  94052. +static int mxc_asrc_prepare_io_buffer(struct asrc_pair_params *params,
  94053. + struct asrc_convert_buffer *pbuf, bool in)
  94054. +{
  94055. + enum asrc_pair_index index = params->index;
  94056. + struct dma_chan *dma_channel;
  94057. + enum asrc_word_width width;
  94058. + unsigned int *dma_len, *sg_nodes, buf_len, wm;
  94059. + void __user *buf_vaddr;
  94060. + void *dma_vaddr;
  94061. + u32 word_size, fifo_addr;
  94062. +
  94063. + if (in) {
  94064. + dma_channel = params->input_dma_channel;
  94065. + dma_vaddr = params->input_dma_total.dma_vaddr;
  94066. + dma_len = &params->input_dma_total.length;
  94067. + width = params->input_word_width;
  94068. + sg_nodes = &params->input_sg_nodes;
  94069. + wm = params->input_wm;
  94070. + buf_vaddr = (void __user *)pbuf->input_buffer_vaddr;
  94071. + buf_len = pbuf->input_buffer_length;
  94072. + } else {
  94073. + dma_channel = params->output_dma_channel;
  94074. + dma_vaddr = params->output_dma_total.dma_vaddr;
  94075. + dma_len = &params->output_dma_total.length;
  94076. + width = params->output_word_width;
  94077. + sg_nodes = &params->output_sg_nodes;
  94078. + wm = params->last_period_sample;
  94079. + buf_vaddr = (void __user *)pbuf->output_buffer_vaddr;
  94080. + buf_len = pbuf->output_buffer_length;
  94081. + }
  94082. +
  94083. + switch (width) {
  94084. + case ASRC_WIDTH_24_BIT:
  94085. + word_size = 4;
  94086. + break;
  94087. + case ASRC_WIDTH_16_BIT:
  94088. + case ASRC_WIDTH_8_BIT:
  94089. + word_size = 2;
  94090. + break;
  94091. + default:
  94092. + pair_err("invalid %sput word size!\n", in ? "in" : "out");
  94093. + return -EINVAL;
  94094. + }
  94095. +
  94096. + if (buf_len < word_size * params->channel_nums * wm) {
  94097. + pair_err("%sput buffer size[%d] is too small!\n",
  94098. + in ? "in" : "out", buf_len);
  94099. + return -EINVAL;
  94100. + }
  94101. +
  94102. + /* Copy origin data into input buffer */
  94103. + if (in && copy_from_user(dma_vaddr, buf_vaddr, buf_len))
  94104. + return -EFAULT;
  94105. +
  94106. + *dma_len = buf_len;
  94107. + if (!in)
  94108. + *dma_len -= wm * word_size * params->channel_nums;
  94109. +
  94110. + *sg_nodes = *dma_len / ASRC_MAX_BUFFER_SIZE + 1;
  94111. +
  94112. + fifo_addr = asrc_get_per_addr(params->index, in);
  94113. +
  94114. + return imx_asrc_dma_config(params, dma_channel, fifo_addr, dma_vaddr,
  94115. + *dma_len, in, width);
  94116. +}
  94117. +
  94118. +static int mxc_asrc_prepare_buffer(struct asrc_pair_params *params,
  94119. + struct asrc_convert_buffer *pbuf)
  94120. +{
  94121. + enum asrc_pair_index index = params->index;
  94122. + int ret;
  94123. +
  94124. + ret = mxc_asrc_prepare_io_buffer(params, pbuf, true);
  94125. + if (ret) {
  94126. + pair_err("failed to prepare input buffer: %d\n", ret);
  94127. + return ret;
  94128. + }
  94129. +
  94130. + ret = mxc_asrc_prepare_io_buffer(params, pbuf, false);
  94131. + if (ret) {
  94132. + pair_err("failed to prepare output buffer: %d\n", ret);
  94133. + return ret;
  94134. + }
  94135. +
  94136. + return 0;
  94137. +}
  94138. +
  94139. +int mxc_asrc_process_io_buffer(struct asrc_pair_params *params,
  94140. + struct asrc_convert_buffer *pbuf, bool in)
  94141. +{
  94142. + void *last_vaddr = params->output_last_period.dma_vaddr;
  94143. + unsigned int *last_len = &params->output_last_period.length;
  94144. + enum asrc_pair_index index = params->index;
  94145. + unsigned int dma_len, *buf_len;
  94146. + struct completion *complete;
  94147. + void __user *buf_vaddr;
  94148. + void *dma_vaddr;
  94149. +
  94150. + if (in) {
  94151. + dma_vaddr = params->input_dma_total.dma_vaddr;
  94152. + dma_len = params->input_dma_total.length;
  94153. + buf_len = &pbuf->input_buffer_length;
  94154. + complete = &params->input_complete;
  94155. + buf_vaddr = (void __user *)pbuf->input_buffer_vaddr;
  94156. + } else {
  94157. + dma_vaddr = params->output_dma_total.dma_vaddr;
  94158. + dma_len = params->output_dma_total.length;
  94159. + buf_len = &pbuf->output_buffer_length;
  94160. + complete = &params->lastperiod_complete;
  94161. + buf_vaddr = (void __user *)pbuf->output_buffer_vaddr;
  94162. + }
  94163. +
  94164. + if (!wait_for_completion_interruptible_timeout(complete, 10 * HZ)) {
  94165. + pair_err("%s task timeout\n", in ? "input dma" : "last period");
  94166. + return -ETIME;
  94167. + } else if (signal_pending(current)) {
  94168. + pair_err("%sput task forcibly aborted\n", in ? "in" : "out");
  94169. + return -ERESTARTSYS;
  94170. + }
  94171. +
  94172. + init_completion(complete);
  94173. +
  94174. + *buf_len = dma_len;
  94175. +
  94176. + /* Only output need return data to user space */
  94177. + if (!in) {
  94178. + if (copy_to_user(buf_vaddr, dma_vaddr, dma_len))
  94179. + return -EFAULT;
  94180. +
  94181. + *buf_len += *last_len;
  94182. +
  94183. + if (copy_to_user(buf_vaddr + dma_len, last_vaddr, *last_len))
  94184. + return -EFAULT;
  94185. + }
  94186. +
  94187. + return 0;
  94188. +}
  94189. +
  94190. +int mxc_asrc_process_buffer(struct asrc_pair_params *params,
  94191. + struct asrc_convert_buffer *pbuf)
  94192. +{
  94193. + enum asrc_pair_index index = params->index;
  94194. + int ret;
  94195. +
  94196. + ret = mxc_asrc_process_io_buffer(params, pbuf, true);
  94197. + if (ret) {
  94198. + pair_err("failed to process input buffer: %d\n", ret);
  94199. + return ret;
  94200. + }
  94201. +
  94202. + ret = mxc_asrc_process_io_buffer(params, pbuf, false);
  94203. + if (ret) {
  94204. + pair_err("failed to process output buffer: %d\n", ret);
  94205. + return ret;
  94206. + }
  94207. +
  94208. + return 0;
  94209. +}
  94210. +
  94211. +#ifdef ASRC_POLLING_WITHOUT_DMA
  94212. +static void asrc_write_one_to_input_FIFO(enum asrc_pair_index index, u32 val)
  94213. +{
  94214. + regmap_write(asrc->regmap, REG_ASRDI(index), val);
  94215. +}
  94216. +
  94217. +/* THIS FUNCTION ONLY EXISTS FOR DEBUGGING AND ONLY SUPPORTS TWO CHANNELS */
  94218. +static void asrc_polling_debug(struct asrc_pair_params *params)
  94219. +{
  94220. + enum asrc_pair_index index = params->index;
  94221. + u32 *in24 = params->input_dma_total.dma_vaddr;
  94222. + u32 dma_len = params->input_dma_total.length / (params->channel_nums * 4);
  94223. + u32 size, i, j, t_size, reg;
  94224. + u32 *reg24 = params->output_dma_total.dma_vaddr;
  94225. +
  94226. + t_size = 0;
  94227. +
  94228. + for (i = 0; i < dma_len; ) {
  94229. + for (j = 0; j < 2; j++) {
  94230. + asrc_write_one_to_input_FIFO(index, *in24);
  94231. + in24++;
  94232. + asrc_write_one_to_input_FIFO(index, *in24);
  94233. + in24++;
  94234. + i++;
  94235. + }
  94236. + udelay(50);
  94237. + udelay(50 * params->output_sample_rate / params->input_sample_rate);
  94238. +
  94239. + size = asrc_get_output_FIFO_size(index);
  94240. + for (j = 0; j < size; j++) {
  94241. + reg = asrc_read_one_from_output_FIFO(index);
  94242. + *(reg24) = reg;
  94243. + reg24++;
  94244. + reg = asrc_read_one_from_output_FIFO(index);
  94245. + *(reg24) = reg;
  94246. + reg24++;
  94247. + }
  94248. + t_size += size;
  94249. + }
  94250. +
  94251. + mdelay(1);
  94252. + size = asrc_get_output_FIFO_size(index);
  94253. + for (j = 0; j < size; j++) {
  94254. + reg = asrc_read_one_from_output_FIFO(index);
  94255. + *(reg24) = reg;
  94256. + reg24++;
  94257. + reg = asrc_read_one_from_output_FIFO(index);
  94258. + *(reg24) = reg;
  94259. + reg24++;
  94260. + }
  94261. + t_size += size;
  94262. +
  94263. + params->output_dma_total.length = t_size * params->channel_nums * 4;
  94264. + params->output_last_period.length = 0;
  94265. +
  94266. + dma_unmap_sg(NULL, params->input_sg, params->input_sg_nodes,
  94267. + DMA_MEM_TO_DEV);
  94268. + dma_unmap_sg(NULL, params->output_sg, params->output_sg_nodes,
  94269. + DMA_DEV_TO_MEM);
  94270. +
  94271. + complete(&params->input_complete);
  94272. + complete(&params->lastperiod_complete);
  94273. +}
  94274. +#else
  94275. +static void mxc_asrc_submit_dma(struct asrc_pair_params *params)
  94276. +{
  94277. + enum asrc_pair_index index = params->index;
  94278. + u32 size = asrc_get_output_FIFO_size(params->index);
  94279. + int i, j;
  94280. +
  94281. + /* Read all data in OUTPUT FIFO */
  94282. + while (size) {
  94283. + for (j = 0; j < size; j++)
  94284. + for (i = 0; i < params->channel_nums; i++)
  94285. + asrc_read_one_from_output_FIFO(index);
  94286. + /* Fetch the data every 100us */
  94287. + udelay(100);
  94288. +
  94289. + size = asrc_get_output_FIFO_size(index);
  94290. + }
  94291. +
  94292. + /* Submit dma request */
  94293. + dmaengine_submit(params->desc_in);
  94294. + dma_async_issue_pending(params->desc_in->chan);
  94295. +
  94296. + dmaengine_submit(params->desc_out);
  94297. + dma_async_issue_pending(params->desc_out->chan);
  94298. +
  94299. + /*
  94300. + * Clear dma request during the stall state of ASRC:
  94301. + * During STALL state, the remaining in input fifo would never be
  94302. + * smaller than the input threshold while the output fifo would not
  94303. + * be bigger than output one. Thus the dma request would be cleared.
  94304. + */
  94305. + asrc_set_watermark(index, ASRC_FIFO_THRESHOLD_MIN, ASRC_FIFO_THRESHOLD_MAX);
  94306. +
  94307. + /* Update the real input threshold to raise dma request */
  94308. + asrc_set_watermark(index, params->input_wm, params->output_wm);
  94309. +}
  94310. +#endif
  94311. +
  94312. +static long asrc_ioctl_req_pair(struct asrc_pair_params *params,
  94313. + void __user *user)
  94314. +{
  94315. + struct asrc_req req;
  94316. + long ret;
  94317. +
  94318. + ret = copy_from_user(&req, user, sizeof(req));
  94319. + if (ret) {
  94320. + dev_err(asrc->dev, "failed to get req from user space: %ld\n", ret);
  94321. + return ret;
  94322. + }
  94323. +
  94324. + ret = asrc_req_pair(req.chn_num, &req.index);
  94325. + if (ret) {
  94326. + dev_err(asrc->dev, "failed to request pair: %ld\n", ret);
  94327. + return ret;
  94328. + }
  94329. +
  94330. + params->pair_hold = 1;
  94331. + params->index = req.index;
  94332. + params->channel_nums = req.chn_num;
  94333. +
  94334. + ret = copy_to_user(user, &req, sizeof(req));
  94335. + if (ret) {
  94336. + dev_err(asrc->dev, "failed to send req to user space: %ld\n", ret);
  94337. + return ret;
  94338. + }
  94339. +
  94340. + return 0;
  94341. +}
  94342. +
  94343. +static long asrc_ioctl_config_pair(struct asrc_pair_params *params,
  94344. + void __user *user)
  94345. +{
  94346. + struct asrc_config config;
  94347. + enum asrc_pair_index index;
  94348. + long ret;
  94349. +
  94350. + ret = copy_from_user(&config, user, sizeof(config));
  94351. + if (ret) {
  94352. + dev_err(asrc->dev, "failed to get config from user space: %ld\n", ret);
  94353. + return ret;
  94354. + }
  94355. +
  94356. + index = config.pair;
  94357. +
  94358. + ret = asrc_config_pair(&config);
  94359. + if (ret) {
  94360. + pair_err("failed to config pair: %ld\n", ret);
  94361. + return ret;
  94362. + }
  94363. +
  94364. + params->input_wm = 4;
  94365. + params->output_wm = 2;
  94366. +
  94367. + ret = asrc_set_watermark(index, params->input_wm, params->output_wm);
  94368. + if (ret)
  94369. + return ret;
  94370. +
  94371. + params->output_buffer_size = config.dma_buffer_size;
  94372. + params->input_buffer_size = config.dma_buffer_size;
  94373. + if (config.buffer_num > ASRC_DMA_BUFFER_NUM)
  94374. + params->buffer_num = ASRC_DMA_BUFFER_NUM;
  94375. + else
  94376. + params->buffer_num = config.buffer_num;
  94377. +
  94378. + params->input_dma_total.length = ASRC_DMA_BUFFER_SIZE;
  94379. + params->output_dma_total.length = ASRC_DMA_BUFFER_SIZE;
  94380. +
  94381. + params->input_word_width = config.input_word_width;
  94382. + params->output_word_width = config.output_word_width;
  94383. +
  94384. + params->input_sample_rate = config.input_sample_rate;
  94385. + params->output_sample_rate = config.output_sample_rate;
  94386. +
  94387. + params->last_period_sample = ASRC_OUTPUT_LAST_SAMPLE_DEFAULT;
  94388. +
  94389. + ret = mxc_allocate_dma_buf(params);
  94390. + if (ret) {
  94391. + pair_err("failed to allocate dma buffer: %ld\n", ret);
  94392. + return ret;
  94393. + }
  94394. +
  94395. + /* Request DMA channel for both input and output */
  94396. + params->input_dma_channel = imx_asrc_get_dma_channel(index, true);
  94397. + if (params->input_dma_channel == NULL) {
  94398. + pair_err("failed to request input task dma channel\n");
  94399. + return -EBUSY;
  94400. + }
  94401. +
  94402. + params->output_dma_channel = imx_asrc_get_dma_channel(index, false);
  94403. + if (params->output_dma_channel == NULL) {
  94404. + pair_err("failed to request output task dma channel\n");
  94405. + return -EBUSY;
  94406. + }
  94407. +
  94408. + init_completion(&params->input_complete);
  94409. + init_completion(&params->output_complete);
  94410. + init_completion(&params->lastperiod_complete);
  94411. +
  94412. + /* Add work struct to receive last period of output data */
  94413. + INIT_WORK(&params->task_output_work, asrc_output_task_worker);
  94414. +
  94415. + ret = copy_to_user(user, &config, sizeof(config));
  94416. + if (ret) {
  94417. + pair_err("failed to send config to user space: %ld\n", ret);
  94418. + return ret;
  94419. + }
  94420. +
  94421. + return 0;
  94422. +}
  94423. +
  94424. +static long asrc_ioctl_release_pair(struct asrc_pair_params *params,
  94425. + void __user *user)
  94426. +{
  94427. + enum asrc_pair_index index;
  94428. + unsigned long lock_flags;
  94429. + long ret;
  94430. +
  94431. + ret = copy_from_user(&index, user, sizeof(index));
  94432. + if (ret) {
  94433. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  94434. + return ret;
  94435. + }
  94436. +
  94437. + /* index might be not valid due to some application failure. */
  94438. + if (index < 0)
  94439. + return -EINVAL;
  94440. +
  94441. + params->asrc_active = 0;
  94442. +
  94443. + spin_lock_irqsave(&pair_lock, lock_flags);
  94444. + params->pair_hold = 0;
  94445. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  94446. +
  94447. + if (params->input_dma_channel)
  94448. + dma_release_channel(params->input_dma_channel);
  94449. + if (params->output_dma_channel)
  94450. + dma_release_channel(params->output_dma_channel);
  94451. + mxc_free_dma_buf(params);
  94452. + asrc_release_pair(index);
  94453. + asrc_finish_conv(index);
  94454. +
  94455. + return 0;
  94456. +}
  94457. +
  94458. +static long asrc_ioctl_convert(struct asrc_pair_params *params,
  94459. + void __user *user)
  94460. +{
  94461. + enum asrc_pair_index index = params->index;
  94462. + struct asrc_convert_buffer buf;
  94463. + long ret;
  94464. +
  94465. + ret = copy_from_user(&buf, user, sizeof(buf));
  94466. + if (ret) {
  94467. + pair_err("failed to get buf from user space: %ld\n", ret);
  94468. + return ret;
  94469. + }
  94470. +
  94471. + ret = mxc_asrc_prepare_buffer(params, &buf);
  94472. + if (ret) {
  94473. + pair_err("failed to prepare buffer: %ld\n", ret);
  94474. + return ret;
  94475. + }
  94476. +
  94477. +#ifdef ASRC_POLLING_WITHOUT_DMA
  94478. + asrc_polling_debug(params);
  94479. +#else
  94480. + mxc_asrc_submit_dma(params);
  94481. +#endif
  94482. +
  94483. + ret = mxc_asrc_process_buffer(params, &buf);
  94484. + if (ret) {
  94485. + pair_err("failed to process buffer: %ld\n", ret);
  94486. + return ret;
  94487. + }
  94488. +
  94489. + ret = copy_to_user(user, &buf, sizeof(buf));
  94490. + if (ret) {
  94491. + pair_err("failed to send buf to user space: %ld\n", ret);
  94492. + return ret;
  94493. + }
  94494. +
  94495. + return 0;
  94496. +}
  94497. +
  94498. +static long asrc_ioctl_start_conv(struct asrc_pair_params *params,
  94499. + void __user *user)
  94500. +{
  94501. + enum asrc_pair_index index;
  94502. + long ret;
  94503. +
  94504. + ret = copy_from_user(&index, user, sizeof(index));
  94505. + if (ret) {
  94506. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  94507. + return ret;
  94508. + }
  94509. +
  94510. + params->asrc_active = 1;
  94511. + asrc_start_conv(index);
  94512. +
  94513. + return 0;
  94514. +}
  94515. +
  94516. +static long asrc_ioctl_stop_conv(struct asrc_pair_params *params,
  94517. + void __user *user)
  94518. +{
  94519. + enum asrc_pair_index index;
  94520. + long ret;
  94521. +
  94522. + ret = copy_from_user(&index, user, sizeof(index));
  94523. + if (ret) {
  94524. + dev_err(asrc->dev, "failed to get index from user space: %ld\n", ret);
  94525. + return ret;
  94526. + }
  94527. +
  94528. + dmaengine_terminate_all(params->input_dma_channel);
  94529. + dmaengine_terminate_all(params->output_dma_channel);
  94530. +
  94531. + asrc_stop_conv(index);
  94532. + params->asrc_active = 0;
  94533. +
  94534. + return 0;
  94535. +}
  94536. +
  94537. +static long asrc_ioctl_status(struct asrc_pair_params *params,
  94538. + void __user *user)
  94539. +{
  94540. + enum asrc_pair_index index = params->index;
  94541. + struct asrc_status_flags flags;
  94542. + long ret;
  94543. +
  94544. + ret = copy_from_user(&flags, user, sizeof(flags));
  94545. + if (ret) {
  94546. + pair_err("failed to get flags from user space: %ld\n", ret);
  94547. + return ret;
  94548. + }
  94549. +
  94550. + asrc_get_status(&flags);
  94551. +
  94552. + ret = copy_to_user(user, &flags, sizeof(flags));
  94553. + if (ret) {
  94554. + pair_err("failed to send flags to user space: %ld\n", ret);
  94555. + return ret;
  94556. + }
  94557. +
  94558. + return 0;
  94559. +}
  94560. +
  94561. +static long asrc_ioctl_flush(struct asrc_pair_params *params,
  94562. + void __user *user)
  94563. +{
  94564. + enum asrc_pair_index index = params->index;
  94565. + init_completion(&params->input_complete);
  94566. + init_completion(&params->output_complete);
  94567. + init_completion(&params->lastperiod_complete);
  94568. +
  94569. + /* Release DMA and request again */
  94570. + dma_release_channel(params->input_dma_channel);
  94571. + dma_release_channel(params->output_dma_channel);
  94572. +
  94573. + params->input_dma_channel = imx_asrc_get_dma_channel(index, true);
  94574. + if (params->input_dma_channel == NULL) {
  94575. + pair_err("failed to request input task dma channel\n");
  94576. + return -EBUSY;
  94577. + }
  94578. +
  94579. + params->output_dma_channel = imx_asrc_get_dma_channel(index, false);
  94580. + if (params->output_dma_channel == NULL) {
  94581. + pair_err("failed to request output task dma channel\n");
  94582. + return -EBUSY;
  94583. + }
  94584. +
  94585. + return 0;
  94586. +}
  94587. +
  94588. +static long asrc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  94589. +{
  94590. + struct asrc_pair_params *params = file->private_data;
  94591. + void __user *user = (void __user *)arg;
  94592. + long ret = 0;
  94593. +
  94594. + switch (cmd) {
  94595. + case ASRC_REQ_PAIR:
  94596. + ret = asrc_ioctl_req_pair(params, user);
  94597. + break;
  94598. + case ASRC_CONFIG_PAIR:
  94599. + ret = asrc_ioctl_config_pair(params, user);
  94600. + break;
  94601. + case ASRC_RELEASE_PAIR:
  94602. + ret = asrc_ioctl_release_pair(params, user);
  94603. + break;
  94604. + case ASRC_CONVERT:
  94605. + ret = asrc_ioctl_convert(params, user);
  94606. + break;
  94607. + case ASRC_START_CONV:
  94608. + ret = asrc_ioctl_start_conv(params, user);
  94609. + dump_regs();
  94610. + break;
  94611. + case ASRC_STOP_CONV:
  94612. + ret = asrc_ioctl_stop_conv(params, user);
  94613. + break;
  94614. + case ASRC_STATUS:
  94615. + ret = asrc_ioctl_status(params, user);
  94616. + break;
  94617. + case ASRC_FLUSH:
  94618. + ret = asrc_ioctl_flush(params, user);
  94619. + break;
  94620. + default:
  94621. + dev_err(asrc->dev, "invalid ioctl cmd!\n");
  94622. + break;
  94623. + }
  94624. +
  94625. + return ret;
  94626. +}
  94627. +
  94628. +static int mxc_asrc_open(struct inode *inode, struct file *file)
  94629. +{
  94630. + struct asrc_pair_params *params;
  94631. + int ret = 0;
  94632. +
  94633. + ret = signal_pending(current);
  94634. + if (ret) {
  94635. + dev_err(asrc->dev, "current process has a signal pending\n");
  94636. + return ret;
  94637. + }
  94638. +
  94639. + params = kzalloc(sizeof(struct asrc_pair_params), GFP_KERNEL);
  94640. + if (params == NULL) {
  94641. + dev_err(asrc->dev, "failed to allocate pair_params\n");
  94642. + return -ENOBUFS;
  94643. + }
  94644. +
  94645. + file->private_data = params;
  94646. +
  94647. + return ret;
  94648. +}
  94649. +
  94650. +static int mxc_asrc_close(struct inode *inode, struct file *file)
  94651. +{
  94652. + struct asrc_pair_params *params;
  94653. + unsigned long lock_flags;
  94654. +
  94655. + params = file->private_data;
  94656. +
  94657. + if (!params)
  94658. + return 0;
  94659. +
  94660. + if (params->asrc_active) {
  94661. + params->asrc_active = 0;
  94662. +
  94663. + dmaengine_terminate_all(params->input_dma_channel);
  94664. + dmaengine_terminate_all(params->output_dma_channel);
  94665. +
  94666. + asrc_stop_conv(params->index);
  94667. +
  94668. + complete(&params->input_complete);
  94669. + complete(&params->output_complete);
  94670. + complete(&params->lastperiod_complete);
  94671. + }
  94672. +
  94673. + if (params->pair_hold) {
  94674. + spin_lock_irqsave(&pair_lock, lock_flags);
  94675. + params->pair_hold = 0;
  94676. + spin_unlock_irqrestore(&pair_lock, lock_flags);
  94677. +
  94678. + if (params->input_dma_channel)
  94679. + dma_release_channel(params->input_dma_channel);
  94680. + if (params->output_dma_channel)
  94681. + dma_release_channel(params->output_dma_channel);
  94682. +
  94683. + mxc_free_dma_buf(params);
  94684. +
  94685. + asrc_release_pair(params->index);
  94686. + asrc_finish_conv(params->index);
  94687. + }
  94688. +
  94689. + kfree(params);
  94690. + file->private_data = NULL;
  94691. +
  94692. + return 0;
  94693. +}
  94694. +
  94695. +static int mxc_asrc_mmap(struct file *file, struct vm_area_struct *vma)
  94696. +{
  94697. + unsigned long size = vma->vm_end - vma->vm_start;
  94698. + int ret;
  94699. +
  94700. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  94701. +
  94702. + ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  94703. + size, vma->vm_page_prot);
  94704. + if (ret) {
  94705. + dev_err(asrc->dev, "failed to memory map!\n");
  94706. + return ret;
  94707. + }
  94708. +
  94709. + vma->vm_flags &= ~VM_IO;
  94710. +
  94711. + return ret;
  94712. +}
  94713. +
  94714. +static const struct file_operations asrc_fops = {
  94715. + .owner = THIS_MODULE,
  94716. + .unlocked_ioctl = asrc_ioctl,
  94717. + .mmap = mxc_asrc_mmap,
  94718. + .open = mxc_asrc_open,
  94719. + .release = mxc_asrc_close,
  94720. +};
  94721. +
  94722. +static struct miscdevice asrc_miscdev = {
  94723. + .name = "mxc_asrc",
  94724. + .fops = &asrc_fops,
  94725. + .minor = MISC_DYNAMIC_MINOR,
  94726. +};
  94727. +
  94728. +static int asrc_read_proc_attr(struct file *file, char __user *buf,
  94729. + size_t count, loff_t *off)
  94730. +{
  94731. + char tmpbuf[80];
  94732. + int len = 0;
  94733. + u32 reg;
  94734. +
  94735. + if (*off)
  94736. + return 0;
  94737. +
  94738. + regmap_read(asrc->regmap, REG_ASRCNCR, &reg);
  94739. +
  94740. + len += sprintf(tmpbuf, "ANCA: %d\nANCB: %d\nANCC: %d\n",
  94741. + ASRCNCR_ANCx_get(ASRC_PAIR_A, reg, asrc->channel_bits),
  94742. + ASRCNCR_ANCx_get(ASRC_PAIR_B, reg, asrc->channel_bits),
  94743. + ASRCNCR_ANCx_get(ASRC_PAIR_C, reg, asrc->channel_bits));
  94744. +
  94745. + if (len > count)
  94746. + return 0;
  94747. +
  94748. + if (copy_to_user(buf, &tmpbuf, len))
  94749. + return -EFAULT;
  94750. +
  94751. + *off += len;
  94752. +
  94753. + return len;
  94754. +}
  94755. +
  94756. +#define ASRC_MAX_PROC_BUFFER_SIZE 63
  94757. +
  94758. +static int asrc_write_proc_attr(struct file *file, const char __user *buffer,
  94759. + size_t count, loff_t *data)
  94760. +{
  94761. + char buf[ASRC_MAX_PROC_BUFFER_SIZE];
  94762. + int na, nb, nc;
  94763. + int total;
  94764. +
  94765. + if (count > ASRC_MAX_PROC_BUFFER_SIZE) {
  94766. + dev_err(asrc->dev, "proc write: the input string was too long\n");
  94767. + return -EINVAL;
  94768. + }
  94769. +
  94770. + if (copy_from_user(buf, buffer, count)) {
  94771. + dev_err(asrc->dev, "proc write: failed to copy buffer from user\n");
  94772. + return -EFAULT;
  94773. + }
  94774. +
  94775. + sscanf(buf, "ANCA: %d\nANCB: %d\nANCC: %d", &na, &nb, &nc);
  94776. +
  94777. + total = asrc->channel_bits > 3 ? 10 : 5;
  94778. +
  94779. + if (na + nb + nc > total) {
  94780. + dev_err(asrc->dev, "don't surpass %d for total\n", total);
  94781. + return -EINVAL;
  94782. + } else if (na % 2 != 0 || nb % 2 != 0 || nc % 2 != 0) {
  94783. + dev_err(asrc->dev, "please set an even number for each pair\n");
  94784. + return -EINVAL;
  94785. + } else if (na < 0 || nb < 0 || nc < 0) {
  94786. + dev_err(asrc->dev, "please set an positive number for each pair\n");
  94787. + return -EINVAL;
  94788. + }
  94789. +
  94790. +
  94791. + asrc->asrc_pair[ASRC_PAIR_A].chn_max = na;
  94792. + asrc->asrc_pair[ASRC_PAIR_B].chn_max = nb;
  94793. + asrc->asrc_pair[ASRC_PAIR_C].chn_max = nc;
  94794. +
  94795. + /* Update channel number settings */
  94796. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  94797. + ASRCNCR_ANCx_MASK(ASRC_PAIR_A, asrc->channel_bits),
  94798. + ASRCNCR_ANCx_set(ASRC_PAIR_A, na, asrc->channel_bits));
  94799. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  94800. + ASRCNCR_ANCx_MASK(ASRC_PAIR_B, asrc->channel_bits),
  94801. + ASRCNCR_ANCx_set(ASRC_PAIR_B, nb, asrc->channel_bits));
  94802. + regmap_update_bits(asrc->regmap, REG_ASRCNCR,
  94803. + ASRCNCR_ANCx_MASK(ASRC_PAIR_C, asrc->channel_bits),
  94804. + ASRCNCR_ANCx_set(ASRC_PAIR_C, nc, asrc->channel_bits));
  94805. +
  94806. + return count;
  94807. +}
  94808. +
  94809. +static const struct file_operations asrc_proc_fops = {
  94810. + .read = asrc_read_proc_attr,
  94811. + .write = asrc_write_proc_attr,
  94812. +};
  94813. +
  94814. +static void asrc_proc_create(void)
  94815. +{
  94816. + struct proc_dir_entry *proc_attr;
  94817. +
  94818. + asrc->proc_asrc = proc_mkdir(ASRC_PROC_PATH, NULL);
  94819. + if (!asrc->proc_asrc) {
  94820. + dev_err(asrc->dev, "failed to create proc entry %s\n", ASRC_PROC_PATH);
  94821. + return;
  94822. + }
  94823. +
  94824. + proc_attr = proc_create("ChSettings", S_IFREG | S_IRUGO | S_IWUSR,
  94825. + asrc->proc_asrc, &asrc_proc_fops);
  94826. + if (!proc_attr) {
  94827. + remove_proc_entry(ASRC_PROC_PATH, NULL);
  94828. + dev_err(asrc->dev, "failed to create proc attribute entry\n");
  94829. + }
  94830. +}
  94831. +
  94832. +static void asrc_proc_remove(void)
  94833. +{
  94834. + remove_proc_entry("ChSettings", asrc->proc_asrc);
  94835. + remove_proc_entry(ASRC_PROC_PATH, NULL);
  94836. +}
  94837. +
  94838. +
  94839. +static bool asrc_readable_reg(struct device *dev, unsigned int reg)
  94840. +{
  94841. + switch (reg) {
  94842. + case REG_ASRCTR:
  94843. + case REG_ASRIER:
  94844. + case REG_ASRCNCR:
  94845. + case REG_ASRCFG:
  94846. + case REG_ASRCSR:
  94847. + case REG_ASRCDR1:
  94848. + case REG_ASRCDR2:
  94849. + case REG_ASRSTR:
  94850. + case REG_ASRPM1:
  94851. + case REG_ASRPM2:
  94852. + case REG_ASRPM3:
  94853. + case REG_ASRPM4:
  94854. + case REG_ASRPM5:
  94855. + case REG_ASRTFR1:
  94856. + case REG_ASRCCR:
  94857. + case REG_ASRDOA:
  94858. + case REG_ASRDOB:
  94859. + case REG_ASRDOC:
  94860. + case REG_ASRIDRHA:
  94861. + case REG_ASRIDRLA:
  94862. + case REG_ASRIDRHB:
  94863. + case REG_ASRIDRLB:
  94864. + case REG_ASRIDRHC:
  94865. + case REG_ASRIDRLC:
  94866. + case REG_ASR76K:
  94867. + case REG_ASR56K:
  94868. + case REG_ASRMCRA:
  94869. + case REG_ASRFSTA:
  94870. + case REG_ASRMCRB:
  94871. + case REG_ASRFSTB:
  94872. + case REG_ASRMCRC:
  94873. + case REG_ASRFSTC:
  94874. + case REG_ASRMCR1A:
  94875. + case REG_ASRMCR1B:
  94876. + case REG_ASRMCR1C:
  94877. + return true;
  94878. + default:
  94879. + return false;
  94880. + }
  94881. +}
  94882. +
  94883. +static bool asrc_writeable_reg(struct device *dev, unsigned int reg)
  94884. +{
  94885. + switch (reg) {
  94886. + case REG_ASRCTR:
  94887. + case REG_ASRIER:
  94888. + case REG_ASRCNCR:
  94889. + case REG_ASRCFG:
  94890. + case REG_ASRCSR:
  94891. + case REG_ASRCDR1:
  94892. + case REG_ASRCDR2:
  94893. + case REG_ASRSTR:
  94894. + case REG_ASRPM1:
  94895. + case REG_ASRPM2:
  94896. + case REG_ASRPM3:
  94897. + case REG_ASRPM4:
  94898. + case REG_ASRPM5:
  94899. + case REG_ASRTFR1:
  94900. + case REG_ASRCCR:
  94901. + case REG_ASRDIA:
  94902. + case REG_ASRDIB:
  94903. + case REG_ASRDIC:
  94904. + case REG_ASRIDRHA:
  94905. + case REG_ASRIDRLA:
  94906. + case REG_ASRIDRHB:
  94907. + case REG_ASRIDRLB:
  94908. + case REG_ASRIDRHC:
  94909. + case REG_ASRIDRLC:
  94910. + case REG_ASR76K:
  94911. + case REG_ASR56K:
  94912. + case REG_ASRMCRA:
  94913. + case REG_ASRMCRB:
  94914. + case REG_ASRMCRC:
  94915. + case REG_ASRMCR1A:
  94916. + case REG_ASRMCR1B:
  94917. + case REG_ASRMCR1C:
  94918. + return true;
  94919. + default:
  94920. + return false;
  94921. + }
  94922. +}
  94923. +
  94924. +static struct regmap_config asrc_regmap_config = {
  94925. + .reg_bits = 32,
  94926. + .reg_stride = 4,
  94927. + .val_bits = 32,
  94928. +
  94929. + .max_register = REG_ASRMCR1C,
  94930. + .readable_reg = asrc_readable_reg,
  94931. + .writeable_reg = asrc_writeable_reg,
  94932. +};
  94933. +
  94934. +static int mxc_asrc_probe(struct platform_device *pdev)
  94935. +{
  94936. + const struct of_device_id *of_id = of_match_device(fsl_asrc_ids, &pdev->dev);
  94937. + struct device_node *np = pdev->dev.of_node;
  94938. + enum mxc_asrc_type devtype;
  94939. + struct resource *res;
  94940. + void __iomem *regs;
  94941. + int ret;
  94942. +
  94943. + /* Check if the device is existed */
  94944. + if (!np)
  94945. + return -ENODEV;
  94946. +
  94947. + asrc = devm_kzalloc(&pdev->dev, sizeof(struct asrc_data), GFP_KERNEL);
  94948. + if (!asrc)
  94949. + return -ENOMEM;
  94950. +
  94951. + if (of_id) {
  94952. + const struct platform_device_id *id_entry = of_id->data;
  94953. + devtype = id_entry->driver_data;
  94954. + } else {
  94955. + devtype = pdev->id_entry->driver_data;
  94956. + }
  94957. +
  94958. + asrc->dev = &pdev->dev;
  94959. + asrc->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  94960. +
  94961. + asrc->asrc_pair[ASRC_PAIR_A].chn_max = 2;
  94962. + asrc->asrc_pair[ASRC_PAIR_B].chn_max = 6;
  94963. + asrc->asrc_pair[ASRC_PAIR_C].chn_max = 2;
  94964. + asrc->asrc_pair[ASRC_PAIR_A].overload_error = 0;
  94965. + asrc->asrc_pair[ASRC_PAIR_B].overload_error = 0;
  94966. + asrc->asrc_pair[ASRC_PAIR_C].overload_error = 0;
  94967. +
  94968. + /* Map the address */
  94969. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  94970. + if (IS_ERR(res)) {
  94971. + dev_err(&pdev->dev, "could not determine device resources\n");
  94972. + return PTR_ERR(res);
  94973. + }
  94974. +
  94975. + regs = devm_ioremap_resource(&pdev->dev, res);
  94976. + if (IS_ERR(regs)) {
  94977. + dev_err(&pdev->dev, "could not map device resources\n");
  94978. + return PTR_ERR(regs);
  94979. + }
  94980. + asrc->paddr = res->start;
  94981. +
  94982. + /* Register regmap and let it prepare core clock */
  94983. + asrc->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
  94984. + "core", regs, &asrc_regmap_config);
  94985. + if (IS_ERR(asrc->regmap)) {
  94986. + dev_err(&pdev->dev, "regmap init failed\n");
  94987. + return PTR_ERR(asrc->regmap);
  94988. + }
  94989. +
  94990. + asrc->irq = platform_get_irq(pdev, 0);
  94991. + if (asrc->irq == NO_IRQ) {
  94992. + dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
  94993. + return asrc->irq;
  94994. + }
  94995. +
  94996. + ret = devm_request_irq(&pdev->dev, asrc->irq, asrc_isr, 0, np->name, NULL);
  94997. + if (ret) {
  94998. + dev_err(&pdev->dev, "could not claim irq %u: %d\n", asrc->irq, ret);
  94999. + return ret;
  95000. + }
  95001. +
  95002. + asrc->asrc_clk = devm_clk_get(&pdev->dev, "core");
  95003. + if (IS_ERR(asrc->asrc_clk)) {
  95004. + dev_err(&pdev->dev, "failed to get core clock\n");
  95005. + return PTR_ERR(asrc->asrc_clk);
  95006. + }
  95007. +
  95008. + asrc->dma_clk = devm_clk_get(&pdev->dev, "dma");
  95009. + if (IS_ERR(asrc->dma_clk)) {
  95010. + dev_err(&pdev->dev, "failed to get dma script clock\n");
  95011. + return PTR_ERR(asrc->dma_clk);
  95012. + }
  95013. +
  95014. + switch (devtype) {
  95015. + case IMX35_ASRC:
  95016. + asrc->channel_bits = 3;
  95017. + input_clk_map = input_clk_map_v1;
  95018. + output_clk_map = output_clk_map_v1;
  95019. + break;
  95020. + case IMX53_ASRC:
  95021. + asrc->channel_bits = 4;
  95022. + input_clk_map = input_clk_map_v2;
  95023. + output_clk_map = output_clk_map_v2;
  95024. + break;
  95025. + default:
  95026. + dev_err(&pdev->dev, "unsupported device type\n");
  95027. + return -EINVAL;
  95028. + }
  95029. +
  95030. + ret = misc_register(&asrc_miscdev);
  95031. + if (ret) {
  95032. + dev_err(&pdev->dev, "failed to register char device %d\n", ret);
  95033. + return ret;
  95034. + }
  95035. +
  95036. + asrc_proc_create();
  95037. +
  95038. + ret = mxc_init_asrc();
  95039. + if (ret) {
  95040. + dev_err(&pdev->dev, "failed to init asrc %d\n", ret);
  95041. + goto err_misc;
  95042. + }
  95043. +
  95044. + dev_info(&pdev->dev, "mxc_asrc registered\n");
  95045. +
  95046. + return ret;
  95047. +
  95048. +err_misc:
  95049. + misc_deregister(&asrc_miscdev);
  95050. +
  95051. + return ret;
  95052. +}
  95053. +
  95054. +static int mxc_asrc_remove(struct platform_device *pdev)
  95055. +{
  95056. + asrc_proc_remove();
  95057. + misc_deregister(&asrc_miscdev);
  95058. +
  95059. + return 0;
  95060. +}
  95061. +
  95062. +static struct platform_driver mxc_asrc_driver = {
  95063. + .driver = {
  95064. + .name = "mxc_asrc",
  95065. + .of_match_table = fsl_asrc_ids,
  95066. + },
  95067. + .probe = mxc_asrc_probe,
  95068. + .remove = mxc_asrc_remove,
  95069. +};
  95070. +
  95071. +module_platform_driver(mxc_asrc_driver);
  95072. +
  95073. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  95074. +MODULE_DESCRIPTION("Asynchronous Sample Rate Converter");
  95075. +MODULE_LICENSE("GPL");
  95076. +MODULE_ALIAS("platform:mxc_asrc");
  95077. diff -Nur linux-3.14.17/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
  95078. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c 1970-01-01 01:00:00.000000000 +0100
  95079. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.c 2014-09-11 18:06:03.078042276 +0200
  95080. @@ -0,0 +1,932 @@
  95081. +/****************************************************************************
  95082. +*
  95083. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  95084. +*
  95085. +* This program is free software; you can redistribute it and/or modify
  95086. +* it under the terms of the GNU General Public License as published by
  95087. +* the Free Software Foundation; either version 2 of the license, or
  95088. +* (at your option) any later version.
  95089. +*
  95090. +* This program is distributed in the hope that it will be useful,
  95091. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  95092. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  95093. +* GNU General Public License for more details.
  95094. +*
  95095. +* You should have received a copy of the GNU General Public License
  95096. +* along with this program; if not write to the Free Software
  95097. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  95098. +*
  95099. +*****************************************************************************/
  95100. +
  95101. +
  95102. +#include "gc_hal.h"
  95103. +#include "gc_hal_kernel.h"
  95104. +
  95105. +#if gcdENABLE_VG
  95106. +
  95107. +#include "gc_hal_kernel_hardware_command_vg.h"
  95108. +
  95109. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  95110. +
  95111. +/******************************************************************************\
  95112. +****************************** gckVGCOMMAND API code *****************************
  95113. +\******************************************************************************/
  95114. +
  95115. +/*******************************************************************************
  95116. +**
  95117. +** gckVGCOMMAND_InitializeInfo
  95118. +**
  95119. +** Initialize architecture dependent command buffer information.
  95120. +**
  95121. +** INPUT:
  95122. +**
  95123. +** gckVGCOMMAND Command
  95124. +** Pointer to the Command object.
  95125. +**
  95126. +** OUTPUT:
  95127. +**
  95128. +** Nothing.
  95129. +*/
  95130. +gceSTATUS
  95131. +gckVGCOMMAND_InitializeInfo(
  95132. + IN gckVGCOMMAND Command
  95133. + )
  95134. +{
  95135. + gceSTATUS status;
  95136. + gcmkHEADER_ARG("Command=0x%x", Command);
  95137. +
  95138. + /* Verify the arguments. */
  95139. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95140. +
  95141. + do
  95142. + {
  95143. + /* Reset interrupts. */
  95144. + Command->info.feBufferInt = -1;
  95145. + Command->info.tsOverflowInt = -1;
  95146. +
  95147. + /* Set command buffer attributes. */
  95148. + Command->info.addressAlignment = 64;
  95149. + Command->info.commandAlignment = 8;
  95150. +
  95151. + /* Determine command alignment address mask. */
  95152. + 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)));
  95153. +
  95154. + /* Query the number of bytes needed by the STATE command. */
  95155. + gcmkERR_BREAK(gckVGCOMMAND_StateCommand(
  95156. + Command, 0x0, gcvNULL, (gctUINT32)~0, 0,
  95157. + &Command->info.stateCommandSize
  95158. + ));
  95159. +
  95160. + /* Query the number of bytes needed by the RESTART command. */
  95161. + gcmkERR_BREAK(gckVGCOMMAND_RestartCommand(
  95162. + Command, gcvNULL, (gctUINT32)~0, 0,
  95163. + &Command->info.restartCommandSize
  95164. + ));
  95165. +
  95166. + /* Query the number of bytes needed by the FETCH command. */
  95167. + gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
  95168. + Command, gcvNULL, (gctUINT32)~0, 0,
  95169. + &Command->info.fetchCommandSize
  95170. + ));
  95171. +
  95172. + /* Query the number of bytes needed by the CALL command. */
  95173. + gcmkERR_BREAK(gckVGCOMMAND_CallCommand(
  95174. + Command, gcvNULL, (gctUINT32)~0, 0,
  95175. + &Command->info.callCommandSize
  95176. + ));
  95177. +
  95178. + /* Query the number of bytes needed by the RETURN command. */
  95179. + gcmkERR_BREAK(gckVGCOMMAND_ReturnCommand(
  95180. + Command, gcvNULL,
  95181. + &Command->info.returnCommandSize
  95182. + ));
  95183. +
  95184. + /* Query the number of bytes needed by the EVENT command. */
  95185. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  95186. + Command, gcvNULL, gcvBLOCK_PIXEL, -1,
  95187. + &Command->info.eventCommandSize
  95188. + ));
  95189. +
  95190. + /* Query the number of bytes needed by the END command. */
  95191. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  95192. + Command, gcvNULL, -1,
  95193. + &Command->info.endCommandSize
  95194. + ));
  95195. +
  95196. + /* Determine the tail reserve size. */
  95197. + Command->info.staticTailSize = gcmMAX(
  95198. + Command->info.fetchCommandSize,
  95199. + gcmMAX(
  95200. + Command->info.returnCommandSize,
  95201. + Command->info.endCommandSize
  95202. + )
  95203. + );
  95204. +
  95205. + /* Determine the maximum tail size. */
  95206. + Command->info.dynamicTailSize
  95207. + = Command->info.staticTailSize
  95208. + + Command->info.eventCommandSize * gcvBLOCK_COUNT;
  95209. + }
  95210. + while (gcvFALSE);
  95211. +
  95212. + gcmkFOOTER();
  95213. + /* Return status. */
  95214. + return status;
  95215. +}
  95216. +
  95217. +/*******************************************************************************
  95218. +**
  95219. +** gckVGCOMMAND_StateCommand
  95220. +**
  95221. +** Append a STATE command at the specified location in the command buffer.
  95222. +**
  95223. +** INPUT:
  95224. +**
  95225. +** gckVGCOMMAND Command
  95226. +** Pointer to an gckVGCOMMAND object.
  95227. +**
  95228. +** gctUINT32 Pipe
  95229. +** Harwdare destination pipe.
  95230. +**
  95231. +** gctPOINTER Logical
  95232. +** Pointer to the current location inside the command buffer to append
  95233. +** STATE command at or gcvNULL to query the size of the command.
  95234. +**
  95235. +** gctUINT32 Address
  95236. +** Starting register address of the state buffer.
  95237. +** If 'Logical' is gcvNULL, this argument is ignored.
  95238. +**
  95239. +** gctUINT32 Count
  95240. +** Number of states in state buffer.
  95241. +** If 'Logical' is gcvNULL, this argument is ignored.
  95242. +**
  95243. +** gctSIZE_T * Bytes
  95244. +** Pointer to the number of bytes available for the STATE command.
  95245. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  95246. +**
  95247. +** OUTPUT:
  95248. +**
  95249. +** gctSIZE_T * Bytes
  95250. +** Pointer to a variable that will receive the number of bytes required
  95251. +** for the STATE command. If 'Bytes' is gcvNULL, nothing is returned.
  95252. +*/
  95253. +gceSTATUS
  95254. +gckVGCOMMAND_StateCommand(
  95255. + IN gckVGCOMMAND Command,
  95256. + IN gctUINT32 Pipe,
  95257. + IN gctPOINTER Logical,
  95258. + IN gctUINT32 Address,
  95259. + IN gctSIZE_T Count,
  95260. + IN OUT gctSIZE_T * Bytes
  95261. + )
  95262. +{
  95263. + gcmkHEADER_ARG("Command=0x%x Pipe=0x%x Logical=0x%x Address=0x%x Count=0x%x Bytes = 0x%x",
  95264. + Command, Pipe, Logical, Address, Count, Bytes);
  95265. +
  95266. + /* Verify the arguments. */
  95267. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95268. +
  95269. + if (Command->fe20)
  95270. + {
  95271. + if (Logical != gcvNULL)
  95272. + {
  95273. + gctUINT32_PTR buffer;
  95274. +
  95275. + /* Cast the buffer pointer. */
  95276. + buffer = (gctUINT32_PTR) Logical;
  95277. +
  95278. + /* Append STATE. */
  95279. + buffer[0]
  95280. + = ((((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)))
  95281. + | ((((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)))
  95282. + | ((((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)))
  95283. + | ((((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)));
  95284. + }
  95285. +
  95286. + if (Bytes != gcvNULL)
  95287. + {
  95288. + /* Return number of bytes required by the STATE command. */
  95289. + *Bytes = 4 * (Count + 1);
  95290. + }
  95291. + }
  95292. + else
  95293. + {
  95294. + if (Logical != gcvNULL)
  95295. + {
  95296. + gctUINT32_PTR buffer;
  95297. +
  95298. + /* Cast the buffer pointer. */
  95299. + buffer = (gctUINT32_PTR) Logical;
  95300. +
  95301. + /* Append LOAD_STATE. */
  95302. + buffer[0]
  95303. + = ((((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)))
  95304. + | ((((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)))
  95305. + | ((((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)));
  95306. + }
  95307. +
  95308. + if (Bytes != gcvNULL)
  95309. + {
  95310. + /* Return number of bytes required by the STATE command. */
  95311. + *Bytes = 4 * (Count + 1);
  95312. + }
  95313. + }
  95314. +
  95315. + gcmkFOOTER_NO();
  95316. + /* Success. */
  95317. + return gcvSTATUS_OK;
  95318. +}
  95319. +
  95320. +/*******************************************************************************
  95321. +**
  95322. +** gckVGCOMMAND_RestartCommand
  95323. +**
  95324. +** Form a RESTART command at the specified location in the command buffer.
  95325. +**
  95326. +** INPUT:
  95327. +**
  95328. +** gckVGCOMMAND Command
  95329. +** Pointer to an gckVGCOMMAND object.
  95330. +**
  95331. +** gctPOINTER Logical
  95332. +** Pointer to the current location inside the command buffer to append
  95333. +** RESTART command at or gcvNULL to query the size of the command.
  95334. +**
  95335. +** gctUINT32 FetchAddress
  95336. +** The address of another command buffer to be executed by this RESTART
  95337. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  95338. +**
  95339. +** gctUINT FetchCount
  95340. +** The number of 64-bit data quantities in another command buffer to
  95341. +** be executed by this RESTART command. If 'Logical' is gcvNULL, this
  95342. +** argument is ignored.
  95343. +**
  95344. +** gctSIZE_T * Bytes
  95345. +** Pointer to the number of bytes available for the RESTART command.
  95346. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  95347. +**
  95348. +** OUTPUT:
  95349. +**
  95350. +** gctSIZE_T * Bytes
  95351. +** Pointer to a variable that will receive the number of bytes required
  95352. +** for the RESTART command. If 'Bytes' is gcvNULL, nothing is returned.
  95353. +*/
  95354. +gceSTATUS
  95355. +gckVGCOMMAND_RestartCommand(
  95356. + IN gckVGCOMMAND Command,
  95357. + IN gctPOINTER Logical,
  95358. + IN gctUINT32 FetchAddress,
  95359. + IN gctUINT FetchCount,
  95360. + IN OUT gctSIZE_T * Bytes
  95361. + )
  95362. +{
  95363. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  95364. + Command, Logical, FetchAddress, FetchCount, Bytes);
  95365. + /* Verify the arguments. */
  95366. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95367. +
  95368. + if (Command->fe20)
  95369. + {
  95370. + if (Logical != gcvNULL)
  95371. + {
  95372. + gctUINT32_PTR buffer;
  95373. + gctUINT32 beginEndMark;
  95374. +
  95375. + /* Cast the buffer pointer. */
  95376. + buffer = (gctUINT32_PTR) Logical;
  95377. +
  95378. + /* Determine Begin/End flag. */
  95379. + beginEndMark = (FetchCount > 0)
  95380. + ? ((((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)))
  95381. + : ((((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)));
  95382. +
  95383. + /* Append RESTART. */
  95384. + buffer[0]
  95385. + = ((((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)))
  95386. + | ((((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)))
  95387. + | beginEndMark;
  95388. +
  95389. + buffer[1]
  95390. + = FetchAddress;
  95391. + }
  95392. +
  95393. + if (Bytes != gcvNULL)
  95394. + {
  95395. + /* Return number of bytes required by the RESTART command. */
  95396. + *Bytes = 8;
  95397. + }
  95398. + }
  95399. + else
  95400. + {
  95401. + gcmkFOOTER_NO();
  95402. + return gcvSTATUS_NOT_SUPPORTED;
  95403. + }
  95404. +
  95405. +
  95406. + gcmkFOOTER_NO();
  95407. + /* Success. */
  95408. + return gcvSTATUS_OK;
  95409. +}
  95410. +
  95411. +/*******************************************************************************
  95412. +**
  95413. +** gckVGCOMMAND_FetchCommand
  95414. +**
  95415. +** Form a FETCH command at the specified location in the command buffer.
  95416. +**
  95417. +** INPUT:
  95418. +**
  95419. +** gckVGCOMMAND Command
  95420. +** Pointer to an gckVGCOMMAND object.
  95421. +**
  95422. +** gctPOINTER Logical
  95423. +** Pointer to the current location inside the command buffer to append
  95424. +** FETCH command at or gcvNULL to query the size of the command.
  95425. +**
  95426. +** gctUINT32 FetchAddress
  95427. +** The address of another command buffer to be executed by this FETCH
  95428. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  95429. +**
  95430. +** gctUINT FetchCount
  95431. +** The number of 64-bit data quantities in another command buffer to
  95432. +** be executed by this FETCH command. If 'Logical' is gcvNULL, this
  95433. +** argument is ignored.
  95434. +**
  95435. +** gctSIZE_T * Bytes
  95436. +** Pointer to the number of bytes available for the FETCH command.
  95437. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  95438. +**
  95439. +** OUTPUT:
  95440. +**
  95441. +** gctSIZE_T * Bytes
  95442. +** Pointer to a variable that will receive the number of bytes required
  95443. +** for the FETCH command. If 'Bytes' is gcvNULL, nothing is returned.
  95444. +*/
  95445. +gceSTATUS
  95446. +gckVGCOMMAND_FetchCommand(
  95447. + IN gckVGCOMMAND Command,
  95448. + IN gctPOINTER Logical,
  95449. + IN gctUINT32 FetchAddress,
  95450. + IN gctUINT FetchCount,
  95451. + IN OUT gctSIZE_T * Bytes
  95452. + )
  95453. +{
  95454. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  95455. + Command, Logical, FetchAddress, FetchCount, Bytes);
  95456. + /* Verify the arguments. */
  95457. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95458. +
  95459. + if (Command->fe20)
  95460. + {
  95461. + if (Logical != gcvNULL)
  95462. + {
  95463. + gctUINT32_PTR buffer;
  95464. +
  95465. + /* Cast the buffer pointer. */
  95466. + buffer = (gctUINT32_PTR) Logical;
  95467. +
  95468. + /* Append FETCH. */
  95469. + buffer[0]
  95470. + = ((((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)))
  95471. + | ((((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)));
  95472. +
  95473. + buffer[1]
  95474. + = gcmkFIXADDRESS(FetchAddress);
  95475. + }
  95476. +
  95477. + if (Bytes != gcvNULL)
  95478. + {
  95479. + /* Return number of bytes required by the FETCH command. */
  95480. + *Bytes = 8;
  95481. + }
  95482. + }
  95483. + else
  95484. + {
  95485. + if (Logical != gcvNULL)
  95486. + {
  95487. + gctUINT32_PTR buffer;
  95488. +
  95489. + /* Cast the buffer pointer. */
  95490. + buffer = (gctUINT32_PTR) Logical;
  95491. +
  95492. + /* Append LINK. */
  95493. + buffer[0]
  95494. + = ((((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)))
  95495. + | ((((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)));
  95496. +
  95497. + buffer[1]
  95498. + = gcmkFIXADDRESS(FetchAddress);
  95499. + }
  95500. +
  95501. + if (Bytes != gcvNULL)
  95502. + {
  95503. + /* Return number of bytes required by the LINK command. */
  95504. + *Bytes = 8;
  95505. + }
  95506. + }
  95507. +
  95508. + gcmkFOOTER_NO();
  95509. + /* Success. */
  95510. + return gcvSTATUS_OK;
  95511. +}
  95512. +
  95513. +/*******************************************************************************
  95514. +**
  95515. +** gckVGCOMMAND_CallCommand
  95516. +**
  95517. +** Append a CALL command at the specified location in the command buffer.
  95518. +**
  95519. +** INPUT:
  95520. +**
  95521. +** gckVGCOMMAND Command
  95522. +** Pointer to an gckVGCOMMAND object.
  95523. +**
  95524. +** gctPOINTER Logical
  95525. +** Pointer to the current location inside the command buffer to append
  95526. +** CALL command at or gcvNULL to query the size of the command.
  95527. +**
  95528. +** gctUINT32 FetchAddress
  95529. +** The address of another command buffer to be executed by this CALL
  95530. +** command. If 'Logical' is gcvNULL, this argument is ignored.
  95531. +**
  95532. +** gctUINT FetchCount
  95533. +** The number of 64-bit data quantities in another command buffer to
  95534. +** be executed by this CALL command. If 'Logical' is gcvNULL, this
  95535. +** argument is ignored.
  95536. +**
  95537. +** gctSIZE_T * Bytes
  95538. +** Pointer to the number of bytes available for the CALL command.
  95539. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  95540. +**
  95541. +** OUTPUT:
  95542. +**
  95543. +** gctSIZE_T * Bytes
  95544. +** Pointer to a variable that will receive the number of bytes required
  95545. +** for the CALL command. If 'Bytes' is gcvNULL, nothing is returned.
  95546. +*/
  95547. +gceSTATUS
  95548. +gckVGCOMMAND_CallCommand(
  95549. + IN gckVGCOMMAND Command,
  95550. + IN gctPOINTER Logical,
  95551. + IN gctUINT32 FetchAddress,
  95552. + IN gctUINT FetchCount,
  95553. + IN OUT gctSIZE_T * Bytes
  95554. + )
  95555. +{
  95556. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x FetchAddress=0x%x FetchCount=0x%x Bytes = 0x%x",
  95557. + Command, Logical, FetchAddress, FetchCount, Bytes);
  95558. + /* Verify the arguments. */
  95559. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95560. +
  95561. + if (Command->fe20)
  95562. + {
  95563. + if (Logical != gcvNULL)
  95564. + {
  95565. + gctUINT32_PTR buffer;
  95566. +
  95567. + /* Cast the buffer pointer. */
  95568. + buffer = (gctUINT32_PTR) Logical;
  95569. +
  95570. + /* Append CALL. */
  95571. + buffer[0]
  95572. + = ((((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)))
  95573. + | ((((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)));
  95574. +
  95575. + buffer[1]
  95576. + = gcmkFIXADDRESS(FetchAddress);
  95577. + }
  95578. +
  95579. + if (Bytes != gcvNULL)
  95580. + {
  95581. + /* Return number of bytes required by the CALL command. */
  95582. + *Bytes = 8;
  95583. + }
  95584. + }
  95585. + else
  95586. + {
  95587. + gcmkFOOTER_NO();
  95588. + return gcvSTATUS_NOT_SUPPORTED;
  95589. + }
  95590. +
  95591. + gcmkFOOTER_NO();
  95592. + /* Success. */
  95593. + return gcvSTATUS_OK;
  95594. +}
  95595. +
  95596. +/*******************************************************************************
  95597. +**
  95598. +** gckVGCOMMAND_ReturnCommand
  95599. +**
  95600. +** Append a RETURN command at the specified location in the command buffer.
  95601. +**
  95602. +** INPUT:
  95603. +**
  95604. +** gckVGCOMMAND Command
  95605. +** Pointer to an gckVGCOMMAND object.
  95606. +**
  95607. +** gctPOINTER Logical
  95608. +** Pointer to the current location inside the command buffer to append
  95609. +** RETURN command at or gcvNULL to query the size of the command.
  95610. +**
  95611. +** gctSIZE_T * Bytes
  95612. +** Pointer to the number of bytes available for the RETURN command.
  95613. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  95614. +**
  95615. +** OUTPUT:
  95616. +**
  95617. +** gctSIZE_T * Bytes
  95618. +** Pointer to a variable that will receive the number of bytes required
  95619. +** for the RETURN command. If 'Bytes' is gcvNULL, nothing is returned.
  95620. +*/
  95621. +gceSTATUS
  95622. +gckVGCOMMAND_ReturnCommand(
  95623. + IN gckVGCOMMAND Command,
  95624. + IN gctPOINTER Logical,
  95625. + IN OUT gctSIZE_T * Bytes
  95626. + )
  95627. +{
  95628. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Bytes = 0x%x",
  95629. + Command, Logical, Bytes);
  95630. + /* Verify the arguments. */
  95631. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95632. +
  95633. + if (Command->fe20)
  95634. + {
  95635. + if (Logical != gcvNULL)
  95636. + {
  95637. + gctUINT32_PTR buffer;
  95638. +
  95639. + /* Cast the buffer pointer. */
  95640. + buffer = (gctUINT32_PTR) Logical;
  95641. +
  95642. + /* Append RETURN. */
  95643. + buffer[0]
  95644. + = ((((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)));
  95645. + }
  95646. +
  95647. + if (Bytes != gcvNULL)
  95648. + {
  95649. + /* Return number of bytes required by the RETURN command. */
  95650. + *Bytes = 8;
  95651. + }
  95652. + }
  95653. + else
  95654. + {
  95655. + gcmkFOOTER_NO();
  95656. + return gcvSTATUS_NOT_SUPPORTED;
  95657. + }
  95658. +
  95659. + gcmkFOOTER_NO();
  95660. + /* Success. */
  95661. + return gcvSTATUS_OK;
  95662. +}
  95663. +
  95664. +/*******************************************************************************
  95665. +**
  95666. +** gckVGCOMMAND_EventCommand
  95667. +**
  95668. +** Form an EVENT command at the specified location in the command buffer.
  95669. +**
  95670. +** INPUT:
  95671. +**
  95672. +** gckVGCOMMAND Command
  95673. +** Pointer to the Command object.
  95674. +**
  95675. +** gctPOINTER Logical
  95676. +** Pointer to the current location inside the command buffer to append
  95677. +** EVENT command at or gcvNULL to query the size of the command.
  95678. +**
  95679. +** gctINT32 InterruptId
  95680. +** The ID of the interrupt to generate.
  95681. +** If 'Logical' is gcvNULL, this argument is ignored.
  95682. +**
  95683. +** gceBLOCK Block
  95684. +** Block that will generate the interrupt.
  95685. +**
  95686. +** gctSIZE_T * Bytes
  95687. +** Pointer to the number of bytes available for the EVENT command.
  95688. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  95689. +**
  95690. +** OUTPUT:
  95691. +**
  95692. +** gctSIZE_T * Bytes
  95693. +** Pointer to a variable that will receive the number of bytes required
  95694. +** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
  95695. +*/
  95696. +gceSTATUS
  95697. +gckVGCOMMAND_EventCommand(
  95698. + IN gckVGCOMMAND Command,
  95699. + IN gctPOINTER Logical,
  95700. + IN gceBLOCK Block,
  95701. + IN gctINT32 InterruptId,
  95702. + IN OUT gctSIZE_T * Bytes
  95703. + )
  95704. +{
  95705. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x Block=0x%x InterruptId=0x%x Bytes = 0x%x",
  95706. + Command, Logical, Block, InterruptId, Bytes);
  95707. + /* Verify the arguments. */
  95708. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95709. +
  95710. + if (Command->fe20)
  95711. + {
  95712. + typedef struct _gcsEVENTSTATES
  95713. + {
  95714. + /* Chips before VG21 use these values. */
  95715. + gctUINT eventFromFE;
  95716. + gctUINT eventFromPE;
  95717. +
  95718. + /* VG21 chips and later use SOURCE field. */
  95719. + gctUINT eventSource;
  95720. + }
  95721. + gcsEVENTSTATES;
  95722. +
  95723. + static gcsEVENTSTATES states[] =
  95724. + {
  95725. + /* gcvBLOCK_COMMAND */
  95726. + {
  95727. + (gctUINT)~0,
  95728. + (gctUINT)~0,
  95729. + (gctUINT)~0
  95730. + },
  95731. +
  95732. + /* gcvBLOCK_TESSELLATOR */
  95733. + {
  95734. + 0x0,
  95735. + 0x1,
  95736. + 0x10
  95737. + },
  95738. +
  95739. + /* gcvBLOCK_TESSELLATOR2 */
  95740. + {
  95741. + 0x0,
  95742. + 0x1,
  95743. + 0x12
  95744. + },
  95745. +
  95746. + /* gcvBLOCK_TESSELLATOR3 */
  95747. + {
  95748. + 0x0,
  95749. + 0x1,
  95750. + 0x14
  95751. + },
  95752. +
  95753. + /* gcvBLOCK_RASTER */
  95754. + {
  95755. + 0x0,
  95756. + 0x1,
  95757. + 0x07,
  95758. + },
  95759. +
  95760. + /* gcvBLOCK_VG */
  95761. + {
  95762. + 0x0,
  95763. + 0x1,
  95764. + 0x0F
  95765. + },
  95766. +
  95767. + /* gcvBLOCK_VG2 */
  95768. + {
  95769. + 0x0,
  95770. + 0x1,
  95771. + 0x11
  95772. + },
  95773. +
  95774. + /* gcvBLOCK_VG3 */
  95775. + {
  95776. + 0x0,
  95777. + 0x1,
  95778. + 0x13
  95779. + },
  95780. +
  95781. + /* gcvBLOCK_PIXEL */
  95782. + {
  95783. + 0x0,
  95784. + 0x1,
  95785. + 0x07
  95786. + },
  95787. + };
  95788. +
  95789. + /* Verify block ID. */
  95790. + gcmkVERIFY_ARGUMENT(gcmIS_VALID_INDEX(Block, states));
  95791. +
  95792. + if (Logical != gcvNULL)
  95793. + {
  95794. + gctUINT32_PTR buffer;
  95795. +
  95796. + /* Verify the event ID. */
  95797. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  95798. + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
  95799. +
  95800. + /* Cast the buffer pointer. */
  95801. + buffer = (gctUINT32_PTR) Logical;
  95802. +
  95803. + /* Append EVENT. */
  95804. + buffer[0]
  95805. + = ((((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)))
  95806. + | ((((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)))
  95807. + | ((((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)))
  95808. + | ((((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)));
  95809. +
  95810. + /* Determine chip version. */
  95811. + if (Command->vg21)
  95812. + {
  95813. + /* Get the event source for the block. */
  95814. + gctUINT eventSource = states[Block].eventSource;
  95815. +
  95816. + /* Supported? */
  95817. + if (eventSource == ~0)
  95818. + {
  95819. + gcmkFOOTER_NO();
  95820. + return gcvSTATUS_NOT_SUPPORTED;
  95821. + }
  95822. +
  95823. + buffer[1]
  95824. + = ((((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)))
  95825. + | ((((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)));
  95826. + }
  95827. + else
  95828. + {
  95829. + /* Get the event source for the block. */
  95830. + gctUINT eventFromFE = states[Block].eventFromFE;
  95831. + gctUINT eventFromPE = states[Block].eventFromPE;
  95832. +
  95833. + /* Supported? */
  95834. + if (eventFromFE == ~0)
  95835. + {
  95836. + gcmkFOOTER_NO();
  95837. + return gcvSTATUS_NOT_SUPPORTED;
  95838. + }
  95839. +
  95840. + buffer[1]
  95841. + = ((((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)))
  95842. + | ((((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)))
  95843. + | ((((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)));
  95844. + }
  95845. + }
  95846. +
  95847. + if (Bytes != gcvNULL)
  95848. + {
  95849. + /* Make sure the events are directly supported for the block. */
  95850. + if (states[Block].eventSource == ~0)
  95851. + {
  95852. + gcmkFOOTER_NO();
  95853. + return gcvSTATUS_NOT_SUPPORTED;
  95854. + }
  95855. +
  95856. + /* Return number of bytes required by the END command. */
  95857. + *Bytes = 8;
  95858. + }
  95859. + }
  95860. + else
  95861. + {
  95862. + if (Logical != gcvNULL)
  95863. + {
  95864. + gctUINT32_PTR buffer;
  95865. +
  95866. + /* Verify the event ID. */
  95867. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  95868. + gcmkVERIFY_ARGUMENT(InterruptId <= ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))));
  95869. +
  95870. + /* Cast the buffer pointer. */
  95871. + buffer = (gctUINT32_PTR) Logical;
  95872. +
  95873. + /* Append EVENT. */
  95874. + buffer[0]
  95875. + = ((((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)))
  95876. + | ((((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)))
  95877. + | ((((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)));
  95878. +
  95879. + /* Determine event source. */
  95880. + if (Block == gcvBLOCK_COMMAND)
  95881. + {
  95882. + buffer[1]
  95883. + = ((((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)))
  95884. + | ((((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)));
  95885. + }
  95886. + else
  95887. + {
  95888. + buffer[1]
  95889. + = ((((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)))
  95890. + | ((((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)));
  95891. + }
  95892. + }
  95893. +
  95894. + if (Bytes != gcvNULL)
  95895. + {
  95896. + /* Return number of bytes required by the EVENT and END commands. */
  95897. + *Bytes = 8;
  95898. + }
  95899. + }
  95900. +
  95901. + gcmkFOOTER_NO();
  95902. + /* Success. */
  95903. + return gcvSTATUS_OK;
  95904. +}
  95905. +
  95906. +/*******************************************************************************
  95907. +**
  95908. +** gckVGCOMMAND_EndCommand
  95909. +**
  95910. +** Form an END command at the specified location in the command buffer.
  95911. +**
  95912. +** INPUT:
  95913. +**
  95914. +** gckVGCOMMAND Command
  95915. +** Pointer to the Command object.
  95916. +**
  95917. +** gctPOINTER Logical
  95918. +** Pointer to the current location inside the command buffer to append
  95919. +** END command at or gcvNULL to query the size of the command.
  95920. +**
  95921. +** gctINT32 InterruptId
  95922. +** The ID of the interrupt to generate.
  95923. +** If 'Logical' is gcvNULL, this argument will be ignored.
  95924. +**
  95925. +** gctSIZE_T * Bytes
  95926. +** Pointer to the number of bytes available for the END command.
  95927. +** If 'Logical' is gcvNULL, the value from this argument is ignored.
  95928. +**
  95929. +** OUTPUT:
  95930. +**
  95931. +** gctSIZE_T * Bytes
  95932. +** Pointer to a variable that will receive the number of bytes required
  95933. +** for the END command. If 'Bytes' is gcvNULL, nothing is returned.
  95934. +*/
  95935. +gceSTATUS
  95936. +gckVGCOMMAND_EndCommand(
  95937. + IN gckVGCOMMAND Command,
  95938. + IN gctPOINTER Logical,
  95939. + IN gctINT32 InterruptId,
  95940. + IN OUT gctSIZE_T * Bytes
  95941. + )
  95942. +{
  95943. + gcmkHEADER_ARG("Command=0x%x Logical=0x%x InterruptId=0x%x Bytes = 0x%x",
  95944. + Command, Logical, InterruptId, Bytes);
  95945. + /* Verify the arguments. */
  95946. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  95947. +
  95948. + if (Command->fe20)
  95949. + {
  95950. + if (Logical != gcvNULL)
  95951. + {
  95952. + gctUINT32_PTR buffer;
  95953. +
  95954. + /* Verify the event ID. */
  95955. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  95956. +
  95957. + /* Cast the buffer pointer. */
  95958. + buffer = (gctUINT32_PTR) Logical;
  95959. +
  95960. + /* Append END. */
  95961. + buffer[0]
  95962. + = ((((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)))
  95963. + | ((((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)));
  95964. + }
  95965. +
  95966. + if (Bytes != gcvNULL)
  95967. + {
  95968. + /* Return number of bytes required by the END command. */
  95969. + *Bytes = 8;
  95970. + }
  95971. + }
  95972. + else
  95973. + {
  95974. + if (Logical != gcvNULL)
  95975. + {
  95976. + gctUINT32_PTR memory;
  95977. +
  95978. + /* Verify the event ID. */
  95979. + gcmkVERIFY_ARGUMENT(InterruptId >= 0);
  95980. +
  95981. + /* Cast the buffer pointer. */
  95982. + memory = (gctUINT32_PTR) Logical;
  95983. +
  95984. + /* Append EVENT. */
  95985. + memory[0]
  95986. + = ((((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)))
  95987. + | ((((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)))
  95988. + | ((((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)));
  95989. +
  95990. + memory[1]
  95991. + = ((((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)))
  95992. + | ((((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)));
  95993. +
  95994. + /* Append END. */
  95995. + memory[2]
  95996. + = ((((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)));
  95997. + }
  95998. +
  95999. + if (Bytes != gcvNULL)
  96000. + {
  96001. + /* Return number of bytes required by the EVENT and END commands. */
  96002. + *Bytes = 16;
  96003. + }
  96004. + }
  96005. +
  96006. + gcmkFOOTER_NO();
  96007. + /* Success. */
  96008. + return gcvSTATUS_OK;
  96009. +}
  96010. +
  96011. +#endif /* gcdENABLE_VG */
  96012. +
  96013. diff -Nur linux-3.14.17/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
  96014. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h 1970-01-01 01:00:00.000000000 +0100
  96015. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_command_vg.h 2014-09-11 18:06:03.078042276 +0200
  96016. @@ -0,0 +1,319 @@
  96017. +/****************************************************************************
  96018. +*
  96019. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  96020. +*
  96021. +* This program is free software; you can redistribute it and/or modify
  96022. +* it under the terms of the GNU General Public License as published by
  96023. +* the Free Software Foundation; either version 2 of the license, or
  96024. +* (at your option) any later version.
  96025. +*
  96026. +* This program is distributed in the hope that it will be useful,
  96027. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  96028. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  96029. +* GNU General Public License for more details.
  96030. +*
  96031. +* You should have received a copy of the GNU General Public License
  96032. +* along with this program; if not write to the Free Software
  96033. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  96034. +*
  96035. +*****************************************************************************/
  96036. +
  96037. +
  96038. +#ifndef __gc_hal_kernel_hardware_command_vg_h_
  96039. +#define __gc_hal_kernel_hardware_command_vg_h_
  96040. +
  96041. +/******************************************************************************\
  96042. +******************* Task and Interrupt Management Structures. ******************
  96043. +\******************************************************************************/
  96044. +
  96045. +/* Task storage header. */
  96046. +typedef struct _gcsTASK_STORAGE * gcsTASK_STORAGE_PTR;
  96047. +typedef struct _gcsTASK_STORAGE
  96048. +{
  96049. + /* Next allocated storage buffer. */
  96050. + gcsTASK_STORAGE_PTR next;
  96051. +}
  96052. +gcsTASK_STORAGE;
  96053. +
  96054. +/* Task container header. */
  96055. +typedef struct _gcsTASK_CONTAINER * gcsTASK_CONTAINER_PTR;
  96056. +typedef struct _gcsTASK_CONTAINER
  96057. +{
  96058. + /* The number of tasks left to be processed in the container. */
  96059. + gctINT referenceCount;
  96060. +
  96061. + /* Size of the buffer. */
  96062. + gctUINT size;
  96063. +
  96064. + /* Link to the previous and the next allocated containers. */
  96065. + gcsTASK_CONTAINER_PTR allocPrev;
  96066. + gcsTASK_CONTAINER_PTR allocNext;
  96067. +
  96068. + /* Link to the previous and the next containers in the free list. */
  96069. + gcsTASK_CONTAINER_PTR freePrev;
  96070. + gcsTASK_CONTAINER_PTR freeNext;
  96071. +}
  96072. +gcsTASK_CONTAINER;
  96073. +
  96074. +/* Kernel space task master table entry. */
  96075. +typedef struct _gcsBLOCK_TASK_ENTRY * gcsBLOCK_TASK_ENTRY_PTR;
  96076. +typedef struct _gcsBLOCK_TASK_ENTRY
  96077. +{
  96078. + /* Pointer to the current task container for the block. */
  96079. + gcsTASK_CONTAINER_PTR container;
  96080. +
  96081. + /* Pointer to the current task data within the container. */
  96082. + gcsTASK_HEADER_PTR task;
  96083. +
  96084. + /* Pointer to the last link task within the container. */
  96085. + gcsTASK_LINK_PTR link;
  96086. +
  96087. + /* Number of interrupts allocated for this block. */
  96088. + gctUINT interruptCount;
  96089. +
  96090. + /* The index of the current interrupt. */
  96091. + gctUINT interruptIndex;
  96092. +
  96093. + /* Interrupt semaphore. */
  96094. + gctSEMAPHORE interruptSemaphore;
  96095. +
  96096. + /* Interrupt value array. */
  96097. + gctINT32 interruptArray[32];
  96098. +}
  96099. +gcsBLOCK_TASK_ENTRY;
  96100. +
  96101. +
  96102. +/******************************************************************************\
  96103. +********************* Command Queue Management Structures. *********************
  96104. +\******************************************************************************/
  96105. +
  96106. +/* Command queue kernel element pointer. */
  96107. +typedef struct _gcsKERNEL_CMDQUEUE * gcsKERNEL_CMDQUEUE_PTR;
  96108. +
  96109. +/* Command queue object handler function type. */
  96110. +typedef gceSTATUS (* gctOBJECT_HANDLER) (
  96111. + gckVGKERNEL Kernel,
  96112. + gcsKERNEL_CMDQUEUE_PTR Entry
  96113. + );
  96114. +
  96115. +/* Command queue kernel element. */
  96116. +typedef struct _gcsKERNEL_CMDQUEUE
  96117. +{
  96118. + /* The number of buffers in the queue. */
  96119. + gcsCMDBUFFER_PTR commandBuffer;
  96120. +
  96121. + /* Pointer to the object handler function. */
  96122. + gctOBJECT_HANDLER handler;
  96123. +}
  96124. +gcsKERNEL_CMDQUEUE;
  96125. +
  96126. +/* Command queue header. */
  96127. +typedef struct _gcsKERNEL_QUEUE_HEADER * gcsKERNEL_QUEUE_HEADER_PTR;
  96128. +typedef struct _gcsKERNEL_QUEUE_HEADER
  96129. +{
  96130. + /* The size of the buffer in bytes. */
  96131. + gctUINT size;
  96132. +
  96133. + /* The number of pending entries to be processed. */
  96134. + volatile gctUINT pending;
  96135. +
  96136. + /* The current command queue entry. */
  96137. + gcsKERNEL_CMDQUEUE_PTR currentEntry;
  96138. +
  96139. + /* Next buffer. */
  96140. + gcsKERNEL_QUEUE_HEADER_PTR next;
  96141. +}
  96142. +gcsKERNEL_QUEUE_HEADER;
  96143. +
  96144. +
  96145. +/******************************************************************************\
  96146. +******************************* gckVGCOMMAND Object *******************************
  96147. +\******************************************************************************/
  96148. +
  96149. +/* gckVGCOMMAND object. */
  96150. +struct _gckVGCOMMAND
  96151. +{
  96152. + /***************************************************************************
  96153. + ** Object data and pointers.
  96154. + */
  96155. +
  96156. + gcsOBJECT object;
  96157. + gckVGKERNEL kernel;
  96158. + gckOS os;
  96159. + gckVGHARDWARE hardware;
  96160. +
  96161. + /* Features. */
  96162. + gctBOOL fe20;
  96163. + gctBOOL vg20;
  96164. + gctBOOL vg21;
  96165. +
  96166. +
  96167. + /***************************************************************************
  96168. + ** Enable command queue dumping.
  96169. + */
  96170. +
  96171. + gctBOOL enableDumping;
  96172. +
  96173. +
  96174. + /***************************************************************************
  96175. + ** Bus Error interrupt.
  96176. + */
  96177. +
  96178. + gctINT32 busErrorInt;
  96179. +
  96180. +
  96181. + /***************************************************************************
  96182. + ** Command buffer information.
  96183. + */
  96184. +
  96185. + gcsCOMMAND_BUFFER_INFO info;
  96186. +
  96187. +
  96188. + /***************************************************************************
  96189. + ** Synchronization objects.
  96190. + */
  96191. +
  96192. + gctPOINTER queueMutex;
  96193. + gctPOINTER taskMutex;
  96194. + gctPOINTER commitMutex;
  96195. +
  96196. +
  96197. + /***************************************************************************
  96198. + ** Task management.
  96199. + */
  96200. +
  96201. + /* The head of the storage buffer linked list. */
  96202. + gcsTASK_STORAGE_PTR taskStorage;
  96203. +
  96204. + /* Allocation size. */
  96205. + gctUINT taskStorageGranularity;
  96206. + gctUINT taskStorageUsable;
  96207. +
  96208. + /* The free container list. */
  96209. + gcsTASK_CONTAINER_PTR taskFreeHead;
  96210. + gcsTASK_CONTAINER_PTR taskFreeTail;
  96211. +
  96212. + /* Task table */
  96213. + gcsBLOCK_TASK_ENTRY taskTable[gcvBLOCK_COUNT];
  96214. +
  96215. +
  96216. + /***************************************************************************
  96217. + ** Command queue.
  96218. + */
  96219. +
  96220. + /* Pointer to the allocated queue memory. */
  96221. + gcsKERNEL_QUEUE_HEADER_PTR queue;
  96222. +
  96223. + /* Pointer to the current available queue from which new queue entries
  96224. + will be allocated. */
  96225. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  96226. +
  96227. + /* If different from queueHead, points to the command queue which is
  96228. + currently being executed by the hardware. */
  96229. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  96230. +
  96231. + /* Points to the queue to merge the tail with when the tail is processed. */
  96232. + gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
  96233. +
  96234. + /* Queue overflow counter. */
  96235. + gctUINT queueOverflow;
  96236. +
  96237. +
  96238. + /***************************************************************************
  96239. + ** Context.
  96240. + */
  96241. +
  96242. + /* Context counter used for unique ID. */
  96243. + gctUINT64 contextCounter;
  96244. +
  96245. + /* Current context ID. */
  96246. + gctUINT64 currentContext;
  96247. +
  96248. + /* Command queue power semaphore. */
  96249. + gctPOINTER powerSemaphore;
  96250. + gctINT32 powerStallInt;
  96251. + gcsCMDBUFFER_PTR powerStallBuffer;
  96252. + gctSIGNAL powerStallSignal;
  96253. +
  96254. +};
  96255. +
  96256. +/******************************************************************************\
  96257. +************************ gckVGCOMMAND Object Internal API. ***********************
  96258. +\******************************************************************************/
  96259. +
  96260. +/* Initialize architecture dependent command buffer information. */
  96261. +gceSTATUS
  96262. +gckVGCOMMAND_InitializeInfo(
  96263. + IN gckVGCOMMAND Command
  96264. + );
  96265. +
  96266. +/* Form a STATE command at the specified location in the command buffer. */
  96267. +gceSTATUS
  96268. +gckVGCOMMAND_StateCommand(
  96269. + IN gckVGCOMMAND Command,
  96270. + IN gctUINT32 Pipe,
  96271. + IN gctPOINTER Logical,
  96272. + IN gctUINT32 Address,
  96273. + IN gctSIZE_T Count,
  96274. + IN OUT gctSIZE_T * Bytes
  96275. + );
  96276. +
  96277. +/* Form a RESTART command at the specified location in the command buffer. */
  96278. +gceSTATUS
  96279. +gckVGCOMMAND_RestartCommand(
  96280. + IN gckVGCOMMAND Command,
  96281. + IN gctPOINTER Logical,
  96282. + IN gctUINT32 FetchAddress,
  96283. + IN gctUINT FetchCount,
  96284. + IN OUT gctSIZE_T * Bytes
  96285. + );
  96286. +
  96287. +/* Form a FETCH command at the specified location in the command buffer. */
  96288. +gceSTATUS
  96289. +gckVGCOMMAND_FetchCommand(
  96290. + IN gckVGCOMMAND Command,
  96291. + IN gctPOINTER Logical,
  96292. + IN gctUINT32 FetchAddress,
  96293. + IN gctUINT FetchCount,
  96294. + IN OUT gctSIZE_T * Bytes
  96295. + );
  96296. +
  96297. +/* Form a CALL command at the specified location in the command buffer. */
  96298. +gceSTATUS
  96299. +gckVGCOMMAND_CallCommand(
  96300. + IN gckVGCOMMAND Command,
  96301. + IN gctPOINTER Logical,
  96302. + IN gctUINT32 FetchAddress,
  96303. + IN gctUINT FetchCount,
  96304. + IN OUT gctSIZE_T * Bytes
  96305. + );
  96306. +
  96307. +/* Form a RETURN command at the specified location in the command buffer. */
  96308. +gceSTATUS
  96309. +gckVGCOMMAND_ReturnCommand(
  96310. + IN gckVGCOMMAND Command,
  96311. + IN gctPOINTER Logical,
  96312. + IN OUT gctSIZE_T * Bytes
  96313. + );
  96314. +
  96315. +/* Form an EVENT command at the specified location in the command buffer. */
  96316. +gceSTATUS
  96317. +gckVGCOMMAND_EventCommand(
  96318. + IN gckVGCOMMAND Command,
  96319. + IN gctPOINTER Logical,
  96320. + IN gceBLOCK Block,
  96321. + IN gctINT32 InterruptId,
  96322. + IN OUT gctSIZE_T * Bytes
  96323. + );
  96324. +
  96325. +/* Form an END command at the specified location in the command buffer. */
  96326. +gceSTATUS
  96327. +gckVGCOMMAND_EndCommand(
  96328. + IN gckVGCOMMAND Command,
  96329. + IN gctPOINTER Logical,
  96330. + IN gctINT32 InterruptId,
  96331. + IN OUT gctSIZE_T * Bytes
  96332. + );
  96333. +
  96334. +#endif /* __gc_hal_kernel_hardware_command_h_ */
  96335. +
  96336. diff -Nur linux-3.14.17/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
  96337. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c 1970-01-01 01:00:00.000000000 +0100
  96338. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c 2014-09-11 18:06:03.078042276 +0200
  96339. @@ -0,0 +1,2114 @@
  96340. +/****************************************************************************
  96341. +*
  96342. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  96343. +*
  96344. +* This program is free software; you can redistribute it and/or modify
  96345. +* it under the terms of the GNU General Public License as published by
  96346. +* the Free Software Foundation; either version 2 of the license, or
  96347. +* (at your option) any later version.
  96348. +*
  96349. +* This program is distributed in the hope that it will be useful,
  96350. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  96351. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  96352. +* GNU General Public License for more details.
  96353. +*
  96354. +* You should have received a copy of the GNU General Public License
  96355. +* along with this program; if not write to the Free Software
  96356. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  96357. +*
  96358. +*****************************************************************************/
  96359. +
  96360. +
  96361. +#include "gc_hal.h"
  96362. +#include "gc_hal_kernel.h"
  96363. +#include "gc_hal_kernel_hardware_command_vg.h"
  96364. +
  96365. +#if gcdENABLE_VG
  96366. +
  96367. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  96368. +
  96369. +typedef enum
  96370. +{
  96371. + gcvPOWER_FLAG_INITIALIZE = 1 << 0,
  96372. + gcvPOWER_FLAG_STALL = 1 << 1,
  96373. + gcvPOWER_FLAG_STOP = 1 << 2,
  96374. + gcvPOWER_FLAG_START = 1 << 3,
  96375. + gcvPOWER_FLAG_RELEASE = 1 << 4,
  96376. + gcvPOWER_FLAG_DELAY = 1 << 5,
  96377. + gcvPOWER_FLAG_SAVE = 1 << 6,
  96378. + gcvPOWER_FLAG_ACQUIRE = 1 << 7,
  96379. + gcvPOWER_FLAG_POWER_OFF = 1 << 8,
  96380. + gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
  96381. + gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
  96382. + gcvPOWER_FLAG_NOP = 1 << 11,
  96383. +}
  96384. +gcePOWER_FLAGS;
  96385. +
  96386. +/******************************************************************************\
  96387. +********************************* Support Code *********************************
  96388. +\******************************************************************************/
  96389. +static gceSTATUS
  96390. +_ResetGPU(
  96391. + IN gckOS Os
  96392. + )
  96393. +{
  96394. + gctUINT32 control, idle;
  96395. + gceSTATUS status;
  96396. +
  96397. + /* Read register. */
  96398. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  96399. + gcvCORE_VG,
  96400. + 0x00000,
  96401. + &control));
  96402. +
  96403. + for (;;)
  96404. + {
  96405. + /* Disable clock gating. */
  96406. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  96407. + gcvCORE_VG,
  96408. + 0x00104,
  96409. + 0x00000000));
  96410. +
  96411. + /* Wait for clock being stable. */
  96412. + gcmkONERROR(gckOS_Delay(Os, 1));
  96413. +
  96414. + /* Isolate the GPU. */
  96415. + 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)));
  96416. +
  96417. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  96418. + gcvCORE_VG,
  96419. + 0x00000,
  96420. + control));
  96421. +
  96422. + /* Set soft reset. */
  96423. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  96424. + gcvCORE_VG,
  96425. + 0x00000,
  96426. + ((((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)))));
  96427. +
  96428. + /* Wait for reset. */
  96429. + gcmkONERROR(gckOS_Delay(Os, 1));
  96430. +
  96431. + /* Reset soft reset bit. */
  96432. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  96433. + gcvCORE_VG,
  96434. + 0x00000,
  96435. + ((((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)))));
  96436. +
  96437. + /* Reset GPU isolation. */
  96438. + 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)));
  96439. +
  96440. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  96441. + gcvCORE_VG,
  96442. + 0x00000,
  96443. + control));
  96444. +
  96445. + /* Read idle register. */
  96446. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  96447. + gcvCORE_VG,
  96448. + 0x00004,
  96449. + &idle));
  96450. +
  96451. + 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)
  96452. + {
  96453. + continue;
  96454. + }
  96455. +
  96456. + /* Read reset register. */
  96457. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  96458. + gcvCORE_VG,
  96459. + 0x00000,
  96460. + &control));
  96461. +
  96462. + 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)
  96463. + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
  96464. + )
  96465. + {
  96466. + continue;
  96467. + }
  96468. +
  96469. + /* GPU is idle. */
  96470. + break;
  96471. + }
  96472. +
  96473. + /* Success. */
  96474. + return gcvSTATUS_OK;
  96475. +
  96476. +OnError:
  96477. +
  96478. + /* Return the error. */
  96479. + return status;
  96480. +}
  96481. +
  96482. +
  96483. +static gceSTATUS
  96484. +_IdentifyHardware(
  96485. + IN gckOS Os,
  96486. + OUT gceCHIPMODEL * ChipModel,
  96487. + OUT gctUINT32 * ChipRevision,
  96488. + OUT gctUINT32 * ChipFeatures,
  96489. + OUT gctUINT32 * ChipMinorFeatures,
  96490. + OUT gctUINT32 * ChipMinorFeatures2
  96491. + )
  96492. +{
  96493. + gceSTATUS status;
  96494. + gctUINT32 chipIdentity;
  96495. +
  96496. + do
  96497. + {
  96498. + /* Read chip identity register. */
  96499. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, 0x00018, &chipIdentity));
  96500. +
  96501. + /* Special case for older graphic cores. */
  96502. + 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))))))))
  96503. + {
  96504. + *ChipModel = gcv500;
  96505. + *ChipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
  96506. + }
  96507. +
  96508. + else
  96509. + {
  96510. + /* Read chip identity register. */
  96511. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
  96512. + 0x00020,
  96513. + (gctUINT32 *) ChipModel));
  96514. +
  96515. + /* Read CHIP_REV register. */
  96516. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
  96517. + 0x00024,
  96518. + ChipRevision));
  96519. + }
  96520. +
  96521. + /* Read chip feature register. */
  96522. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  96523. + Os, gcvCORE_VG, 0x0001C, ChipFeatures
  96524. + ));
  96525. +
  96526. + /* Read chip minor feature register. */
  96527. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  96528. + Os, gcvCORE_VG, 0x00034, ChipMinorFeatures
  96529. + ));
  96530. +
  96531. + /* Read chip minor feature register #2. */
  96532. + gcmkERR_BREAK(gckOS_ReadRegisterEx(
  96533. + Os, gcvCORE_VG, 0x00074, ChipMinorFeatures2
  96534. + ));
  96535. +
  96536. + gcmkTRACE(
  96537. + gcvLEVEL_VERBOSE,
  96538. + "ChipModel=0x%08X\n"
  96539. + "ChipRevision=0x%08X\n"
  96540. + "ChipFeatures=0x%08X\n"
  96541. + "ChipMinorFeatures=0x%08X\n"
  96542. + "ChipMinorFeatures2=0x%08X\n",
  96543. + *ChipModel,
  96544. + *ChipRevision,
  96545. + *ChipFeatures,
  96546. + *ChipMinorFeatures,
  96547. + *ChipMinorFeatures2
  96548. + );
  96549. +
  96550. + /* Success. */
  96551. + return gcvSTATUS_OK;
  96552. + }
  96553. + while (gcvFALSE);
  96554. +
  96555. + /* Return the status. */
  96556. + return status;
  96557. +}
  96558. +
  96559. +#if gcdPOWEROFF_TIMEOUT
  96560. +void
  96561. +_VGPowerTimerFunction(
  96562. + gctPOINTER Data
  96563. + )
  96564. +{
  96565. + gckVGHARDWARE hardware = (gckVGHARDWARE)Data;
  96566. + gcmkVERIFY_OK(
  96567. + gckVGHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
  96568. +}
  96569. +#endif
  96570. +
  96571. +/******************************************************************************\
  96572. +****************************** gckVGHARDWARE API code *****************************
  96573. +\******************************************************************************/
  96574. +
  96575. +/*******************************************************************************
  96576. +**
  96577. +** gckVGHARDWARE_Construct
  96578. +**
  96579. +** Construct a new gckVGHARDWARE object.
  96580. +**
  96581. +** INPUT:
  96582. +**
  96583. +** gckOS Os
  96584. +** Pointer to an initialized gckOS object.
  96585. +**
  96586. +** OUTPUT:
  96587. +**
  96588. +** gckVGHARDWARE * Hardware
  96589. +** Pointer to a variable that will hold the pointer to the gckVGHARDWARE
  96590. +** object.
  96591. +*/
  96592. +gceSTATUS
  96593. +gckVGHARDWARE_Construct(
  96594. + IN gckOS Os,
  96595. + OUT gckVGHARDWARE * Hardware
  96596. + )
  96597. +{
  96598. + gckVGHARDWARE hardware = gcvNULL;
  96599. + gceSTATUS status;
  96600. + gceCHIPMODEL chipModel;
  96601. + gctUINT32 chipRevision;
  96602. + gctUINT32 chipFeatures;
  96603. + gctUINT32 chipMinorFeatures;
  96604. + gctUINT32 chipMinorFeatures2;
  96605. +
  96606. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x ", Os, Hardware);
  96607. +
  96608. + /* Verify the arguments. */
  96609. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  96610. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  96611. +
  96612. + do
  96613. + {
  96614. + gcmkERR_BREAK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvTRUE, gcvTRUE));
  96615. +
  96616. + status = _ResetGPU(Os);
  96617. +
  96618. + if (status != gcvSTATUS_OK)
  96619. + {
  96620. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  96621. + "_ResetGPU failed: status=%d\n", status);
  96622. + }
  96623. +
  96624. + /* Identify the hardware. */
  96625. + gcmkERR_BREAK(_IdentifyHardware(Os,
  96626. + &chipModel, &chipRevision,
  96627. + &chipFeatures, &chipMinorFeatures, &chipMinorFeatures2
  96628. + ));
  96629. +
  96630. + /* Allocate the gckVGHARDWARE object. */
  96631. + gcmkERR_BREAK(gckOS_Allocate(Os,
  96632. + gcmSIZEOF(struct _gckVGHARDWARE), (gctPOINTER *) &hardware
  96633. + ));
  96634. +
  96635. + /* Initialize the gckVGHARDWARE object. */
  96636. + hardware->object.type = gcvOBJ_HARDWARE;
  96637. + hardware->os = Os;
  96638. +
  96639. + /* Set chip identity. */
  96640. + hardware->chipModel = chipModel;
  96641. + hardware->chipRevision = chipRevision;
  96642. + hardware->chipFeatures = chipFeatures;
  96643. + hardware->chipMinorFeatures = chipMinorFeatures;
  96644. + hardware->chipMinorFeatures2 = chipMinorFeatures2;
  96645. +
  96646. + hardware->powerMutex = gcvNULL;
  96647. + hardware->chipPowerState = gcvPOWER_ON;
  96648. + hardware->chipPowerStateGlobal = gcvPOWER_ON;
  96649. + hardware->clockState = gcvTRUE;
  96650. + hardware->powerState = gcvTRUE;
  96651. +
  96652. +#if gcdPOWEROFF_TIMEOUT
  96653. + hardware->powerOffTime = 0;
  96654. + hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
  96655. +
  96656. + gcmkVERIFY_OK(gckOS_CreateTimer(Os,
  96657. + _VGPowerTimerFunction,
  96658. + (gctPOINTER)hardware,
  96659. + &hardware->powerOffTimer));
  96660. +#endif
  96661. +
  96662. + /* Determine whether FE 2.0 is present. */
  96663. + 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)))))));
  96664. +
  96665. + /* Determine whether VG 2.0 is present. */
  96666. + 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)))))));
  96667. +
  96668. + /* Determine whether VG 2.1 is present. */
  96669. + 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)))))));
  96670. +
  96671. + /* Set default event mask. */
  96672. + hardware->eventMask = 0xFFFFFFFF;
  96673. +
  96674. + gcmkERR_BREAK(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
  96675. +
  96676. + /* Set fast clear to auto. */
  96677. + gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
  96678. +
  96679. + gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
  96680. +
  96681. + /* Enable power management by default. */
  96682. + hardware->powerManagement = gcvTRUE;
  96683. +
  96684. + /* Return pointer to the gckVGHARDWARE object. */
  96685. + *Hardware = hardware;
  96686. +
  96687. + gcmkFOOTER_NO();
  96688. + /* Success. */
  96689. + return gcvSTATUS_OK;
  96690. + }
  96691. + while (gcvFALSE);
  96692. +
  96693. +#if gcdPOWEROFF_TIMEOUT
  96694. + if (hardware->powerOffTimer != gcvNULL)
  96695. + {
  96696. + gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
  96697. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
  96698. + }
  96699. +#endif
  96700. +
  96701. + if (hardware->pageTableDirty != gcvNULL)
  96702. + {
  96703. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
  96704. + }
  96705. +
  96706. + if (hardware != gcvNULL)
  96707. + {
  96708. + gcmkVERIFY_OK(gckOS_Free(Os, hardware));
  96709. + }
  96710. +
  96711. + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
  96712. +
  96713. + gcmkFOOTER();
  96714. + /* Return the status. */
  96715. + return status;
  96716. +}
  96717. +
  96718. +/*******************************************************************************
  96719. +**
  96720. +** gckVGHARDWARE_Destroy
  96721. +**
  96722. +** Destroy an gckVGHARDWARE object.
  96723. +**
  96724. +** INPUT:
  96725. +**
  96726. +** gckVGHARDWARE Hardware
  96727. +** Pointer to the gckVGHARDWARE object that needs to be destroyed.
  96728. +**
  96729. +** OUTPUT:
  96730. +**
  96731. +** Nothing.
  96732. +*/
  96733. +gceSTATUS
  96734. +gckVGHARDWARE_Destroy(
  96735. + IN gckVGHARDWARE Hardware
  96736. + )
  96737. +{
  96738. + gceSTATUS status;
  96739. + gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
  96740. + /* Verify the arguments. */
  96741. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96742. +
  96743. + /* Mark the object as unknown. */
  96744. + Hardware->object.type = gcvOBJ_UNKNOWN;
  96745. +
  96746. + if (Hardware->powerMutex != gcvNULL)
  96747. + {
  96748. + gcmkVERIFY_OK(gckOS_DeleteMutex(
  96749. + Hardware->os, Hardware->powerMutex));
  96750. + }
  96751. +
  96752. +#if gcdPOWEROFF_TIMEOUT
  96753. + gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
  96754. + gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
  96755. +#endif
  96756. +
  96757. + if (Hardware->pageTableDirty != gcvNULL)
  96758. + {
  96759. + gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
  96760. + }
  96761. +
  96762. + /* Free the object. */
  96763. + status = gckOS_Free(Hardware->os, Hardware);
  96764. + gcmkFOOTER();
  96765. + return status;
  96766. +}
  96767. +
  96768. +/*******************************************************************************
  96769. +**
  96770. +** gckVGHARDWARE_QueryMemory
  96771. +**
  96772. +** Query the amount of memory available on the hardware.
  96773. +**
  96774. +** INPUT:
  96775. +**
  96776. +** gckVGHARDWARE Hardware
  96777. +** Pointer to the gckVGHARDWARE object.
  96778. +**
  96779. +** OUTPUT:
  96780. +**
  96781. +** gctSIZE_T * InternalSize
  96782. +** Pointer to a variable that will hold the size of the internal video
  96783. +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
  96784. +** internal memory will be returned.
  96785. +**
  96786. +** gctUINT32 * InternalBaseAddress
  96787. +** Pointer to a variable that will hold the hardware's base address for
  96788. +** the internal video memory. This pointer cannot be gcvNULL if
  96789. +** 'InternalSize' is also non-gcvNULL.
  96790. +**
  96791. +** gctUINT32 * InternalAlignment
  96792. +** Pointer to a variable that will hold the hardware's base address for
  96793. +** the internal video memory. This pointer cannot be gcvNULL if
  96794. +** 'InternalSize' is also non-gcvNULL.
  96795. +**
  96796. +** gctSIZE_T * ExternalSize
  96797. +** Pointer to a variable that will hold the size of the external video
  96798. +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
  96799. +** external memory will be returned.
  96800. +**
  96801. +** gctUINT32 * ExternalBaseAddress
  96802. +** Pointer to a variable that will hold the hardware's base address for
  96803. +** the external video memory. This pointer cannot be gcvNULL if
  96804. +** 'ExternalSize' is also non-gcvNULL.
  96805. +**
  96806. +** gctUINT32 * ExternalAlignment
  96807. +** Pointer to a variable that will hold the hardware's base address for
  96808. +** the external video memory. This pointer cannot be gcvNULL if
  96809. +** 'ExternalSize' is also non-gcvNULL.
  96810. +**
  96811. +** gctUINT32 * HorizontalTileSize
  96812. +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
  96813. +** gcvNULL, no horizontal pixel per tile will be returned.
  96814. +**
  96815. +** gctUINT32 * VerticalTileSize
  96816. +** Number of vertical pixels per tile. If 'VerticalTileSize' is
  96817. +** gcvNULL, no vertical pixel per tile will be returned.
  96818. +*/
  96819. +gceSTATUS
  96820. +gckVGHARDWARE_QueryMemory(
  96821. + IN gckVGHARDWARE Hardware,
  96822. + OUT gctSIZE_T * InternalSize,
  96823. + OUT gctUINT32 * InternalBaseAddress,
  96824. + OUT gctUINT32 * InternalAlignment,
  96825. + OUT gctSIZE_T * ExternalSize,
  96826. + OUT gctUINT32 * ExternalBaseAddress,
  96827. + OUT gctUINT32 * ExternalAlignment,
  96828. + OUT gctUINT32 * HorizontalTileSize,
  96829. + OUT gctUINT32 * VerticalTileSize
  96830. + )
  96831. +{
  96832. + gcmkHEADER_ARG("Hardware=0x%x InternalSize=0x%x InternalBaseAddress=0x%x InternalAlignment=0x%x"
  96833. + "ExternalSize=0x%x ExternalBaseAddress=0x%x ExternalAlignment=0x%x HorizontalTileSize=0x%x VerticalTileSize=0x%x",
  96834. + Hardware, InternalSize, InternalBaseAddress, InternalAlignment,
  96835. + ExternalSize, ExternalBaseAddress, ExternalAlignment, HorizontalTileSize, VerticalTileSize);
  96836. +
  96837. + /* Verify the arguments. */
  96838. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96839. +
  96840. + if (InternalSize != gcvNULL)
  96841. + {
  96842. + /* No internal memory. */
  96843. + *InternalSize = 0;
  96844. + }
  96845. +
  96846. + if (ExternalSize != gcvNULL)
  96847. + {
  96848. + /* No external memory. */
  96849. + *ExternalSize = 0;
  96850. + }
  96851. +
  96852. + if (HorizontalTileSize != gcvNULL)
  96853. + {
  96854. + /* 4x4 tiles. */
  96855. + *HorizontalTileSize = 4;
  96856. + }
  96857. +
  96858. + if (VerticalTileSize != gcvNULL)
  96859. + {
  96860. + /* 4x4 tiles. */
  96861. + *VerticalTileSize = 4;
  96862. + }
  96863. +
  96864. + gcmkFOOTER_NO();
  96865. + /* Success. */
  96866. + return gcvSTATUS_OK;
  96867. +}
  96868. +
  96869. +/*******************************************************************************
  96870. +**
  96871. +** gckVGHARDWARE_QueryChipIdentity
  96872. +**
  96873. +** Query the identity of the hardware.
  96874. +**
  96875. +** INPUT:
  96876. +**
  96877. +** gckVGHARDWARE Hardware
  96878. +** Pointer to the gckVGHARDWARE object.
  96879. +**
  96880. +** OUTPUT:
  96881. +**
  96882. +** gceCHIPMODEL * ChipModel
  96883. +** If 'ChipModel' is not gcvNULL, the variable it points to will
  96884. +** receive the model of the chip.
  96885. +**
  96886. +** gctUINT32 * ChipRevision
  96887. +** If 'ChipRevision' is not gcvNULL, the variable it points to will
  96888. +** receive the revision of the chip.
  96889. +**
  96890. +** gctUINT32 * ChipFeatures
  96891. +** If 'ChipFeatures' is not gcvNULL, the variable it points to will
  96892. +** receive the feature set of the chip.
  96893. +**
  96894. +** gctUINT32 * ChipMinorFeatures
  96895. +** If 'ChipMinorFeatures' is not gcvNULL, the variable it points to
  96896. +** will receive the minor feature set of the chip.
  96897. +**
  96898. +** gctUINT32 * ChipMinorFeatures2
  96899. +** If 'ChipMinorFeatures2' is not gcvNULL, the variable it points to
  96900. +** will receive the minor feature set of the chip.
  96901. +**
  96902. +*/
  96903. +gceSTATUS
  96904. +gckVGHARDWARE_QueryChipIdentity(
  96905. + IN gckVGHARDWARE Hardware,
  96906. + OUT gceCHIPMODEL * ChipModel,
  96907. + OUT gctUINT32 * ChipRevision,
  96908. + OUT gctUINT32* ChipFeatures,
  96909. + OUT gctUINT32* ChipMinorFeatures,
  96910. + OUT gctUINT32* ChipMinorFeatures2
  96911. + )
  96912. +{
  96913. + gcmkHEADER_ARG("Hardware=0x%x ChipModel=0x%x ChipRevision=0x%x ChipFeatures = 0x%x ChipMinorFeatures = 0x%x ChipMinorFeatures2 = 0x%x",
  96914. + Hardware, ChipModel, ChipRevision, ChipFeatures, ChipMinorFeatures, ChipMinorFeatures2);
  96915. +
  96916. + /* Verify the arguments. */
  96917. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  96918. +
  96919. + /* Return chip model. */
  96920. + if (ChipModel != gcvNULL)
  96921. + {
  96922. + *ChipModel = Hardware->chipModel;
  96923. + }
  96924. +
  96925. + /* Return revision number. */
  96926. + if (ChipRevision != gcvNULL)
  96927. + {
  96928. + *ChipRevision = Hardware->chipRevision;
  96929. + }
  96930. +
  96931. + /* Return feature set. */
  96932. + if (ChipFeatures != gcvNULL)
  96933. + {
  96934. + gctUINT32 features = Hardware->chipFeatures;
  96935. +
  96936. + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  96937. + {
  96938. + 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)));
  96939. + }
  96940. +
  96941. + /* Mark 2D pipe as available for GC500.0 since it did not have this *\
  96942. + \* bit. */
  96943. + if ((Hardware->chipModel == gcv500)
  96944. + && (Hardware->chipRevision == 0)
  96945. + )
  96946. + {
  96947. + 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)));
  96948. + }
  96949. +
  96950. + /* Mark 2D pipe as available for GC300 since it did not have this *\
  96951. + \* bit. */
  96952. + if (Hardware->chipModel == gcv300)
  96953. + {
  96954. + 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)));
  96955. + }
  96956. +
  96957. + *ChipFeatures = features;
  96958. + }
  96959. +
  96960. + /* Return minor feature set. */
  96961. + if (ChipMinorFeatures != gcvNULL)
  96962. + {
  96963. + *ChipMinorFeatures = Hardware->chipMinorFeatures;
  96964. + }
  96965. +
  96966. + /* Return minor feature set #2. */
  96967. + if (ChipMinorFeatures2 != gcvNULL)
  96968. + {
  96969. + *ChipMinorFeatures2 = Hardware->chipMinorFeatures2;
  96970. + }
  96971. +
  96972. + gcmkFOOTER_NO();
  96973. + /* Success. */
  96974. + return gcvSTATUS_OK;
  96975. +}
  96976. +
  96977. +/*******************************************************************************
  96978. +**
  96979. +** gckVGHARDWARE_ConvertFormat
  96980. +**
  96981. +** Convert an API format to hardware parameters.
  96982. +**
  96983. +** INPUT:
  96984. +**
  96985. +** gckVGHARDWARE Hardware
  96986. +** Pointer to the gckVGHARDWARE object.
  96987. +**
  96988. +** gceSURF_FORMAT Format
  96989. +** API format to convert.
  96990. +**
  96991. +** OUTPUT:
  96992. +**
  96993. +** gctUINT32 * BitsPerPixel
  96994. +** Pointer to a variable that will hold the number of bits per pixel.
  96995. +**
  96996. +** gctUINT32 * BytesPerTile
  96997. +** Pointer to a variable that will hold the number of bytes per tile.
  96998. +*/
  96999. +gceSTATUS
  97000. +gckVGHARDWARE_ConvertFormat(
  97001. + IN gckVGHARDWARE Hardware,
  97002. + IN gceSURF_FORMAT Format,
  97003. + OUT gctUINT32 * BitsPerPixel,
  97004. + OUT gctUINT32 * BytesPerTile
  97005. + )
  97006. +{
  97007. + gctUINT32 bitsPerPixel;
  97008. + gctUINT32 bytesPerTile;
  97009. +
  97010. + gcmkHEADER_ARG("Hardware=0x%x Format=0x%x BitsPerPixel=0x%x BytesPerTile = 0x%x",
  97011. + Hardware, Format, BitsPerPixel, BytesPerTile);
  97012. +
  97013. + /* Verify the arguments. */
  97014. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97015. +
  97016. + /* Dispatch on format. */
  97017. + switch (Format)
  97018. + {
  97019. + case gcvSURF_A1:
  97020. + case gcvSURF_L1:
  97021. + /* 1-bpp format. */
  97022. + bitsPerPixel = 1;
  97023. + bytesPerTile = (1 * 4 * 4) / 8;
  97024. + break;
  97025. +
  97026. + case gcvSURF_A4:
  97027. + /* 4-bpp format. */
  97028. + bitsPerPixel = 4;
  97029. + bytesPerTile = (4 * 4 * 4) / 8;
  97030. + break;
  97031. +
  97032. + case gcvSURF_INDEX8:
  97033. + case gcvSURF_A8:
  97034. + case gcvSURF_L8:
  97035. + /* 8-bpp format. */
  97036. + bitsPerPixel = 8;
  97037. + bytesPerTile = (8 * 4 * 4) / 8;
  97038. + break;
  97039. +
  97040. + case gcvSURF_YV12:
  97041. + /* 12-bpp planar YUV formats. */
  97042. + bitsPerPixel = 12;
  97043. + bytesPerTile = (12 * 4 * 4) / 8;
  97044. + break;
  97045. +
  97046. + case gcvSURF_NV12:
  97047. + /* 12-bpp planar YUV formats. */
  97048. + bitsPerPixel = 12;
  97049. + bytesPerTile = (12 * 4 * 4) / 8;
  97050. + break;
  97051. +
  97052. + /* 4444 variations. */
  97053. + case gcvSURF_X4R4G4B4:
  97054. + case gcvSURF_A4R4G4B4:
  97055. + case gcvSURF_R4G4B4X4:
  97056. + case gcvSURF_R4G4B4A4:
  97057. + case gcvSURF_B4G4R4X4:
  97058. + case gcvSURF_B4G4R4A4:
  97059. + case gcvSURF_X4B4G4R4:
  97060. + case gcvSURF_A4B4G4R4:
  97061. +
  97062. + /* 1555 variations. */
  97063. + case gcvSURF_X1R5G5B5:
  97064. + case gcvSURF_A1R5G5B5:
  97065. + case gcvSURF_R5G5B5X1:
  97066. + case gcvSURF_R5G5B5A1:
  97067. + case gcvSURF_X1B5G5R5:
  97068. + case gcvSURF_A1B5G5R5:
  97069. + case gcvSURF_B5G5R5X1:
  97070. + case gcvSURF_B5G5R5A1:
  97071. +
  97072. + /* 565 variations. */
  97073. + case gcvSURF_R5G6B5:
  97074. + case gcvSURF_B5G6R5:
  97075. +
  97076. + case gcvSURF_A8L8:
  97077. + case gcvSURF_YUY2:
  97078. + case gcvSURF_UYVY:
  97079. + case gcvSURF_D16:
  97080. + /* 16-bpp format. */
  97081. + bitsPerPixel = 16;
  97082. + bytesPerTile = (16 * 4 * 4) / 8;
  97083. + break;
  97084. +
  97085. + case gcvSURF_X8R8G8B8:
  97086. + case gcvSURF_A8R8G8B8:
  97087. + case gcvSURF_X8B8G8R8:
  97088. + case gcvSURF_A8B8G8R8:
  97089. + case gcvSURF_R8G8B8X8:
  97090. + case gcvSURF_R8G8B8A8:
  97091. + case gcvSURF_B8G8R8X8:
  97092. + case gcvSURF_B8G8R8A8:
  97093. + case gcvSURF_D32:
  97094. + /* 32-bpp format. */
  97095. + bitsPerPixel = 32;
  97096. + bytesPerTile = (32 * 4 * 4) / 8;
  97097. + break;
  97098. +
  97099. + case gcvSURF_D24S8:
  97100. + /* 24-bpp format. */
  97101. + bitsPerPixel = 32;
  97102. + bytesPerTile = (32 * 4 * 4) / 8;
  97103. + break;
  97104. +
  97105. + case gcvSURF_DXT1:
  97106. + case gcvSURF_ETC1:
  97107. + bitsPerPixel = 4;
  97108. + bytesPerTile = (4 * 4 * 4) / 8;
  97109. + break;
  97110. +
  97111. + case gcvSURF_DXT2:
  97112. + case gcvSURF_DXT3:
  97113. + case gcvSURF_DXT4:
  97114. + case gcvSURF_DXT5:
  97115. + bitsPerPixel = 8;
  97116. + bytesPerTile = (8 * 4 * 4) / 8;
  97117. + break;
  97118. +
  97119. + default:
  97120. + /* Invalid format. */
  97121. + gcmkFOOTER_NO();
  97122. + return gcvSTATUS_INVALID_ARGUMENT;
  97123. + }
  97124. +
  97125. + /* Set the result. */
  97126. + if (BitsPerPixel != gcvNULL)
  97127. + {
  97128. + * BitsPerPixel = bitsPerPixel;
  97129. + }
  97130. +
  97131. + if (BytesPerTile != gcvNULL)
  97132. + {
  97133. + * BytesPerTile = bytesPerTile;
  97134. + }
  97135. +
  97136. + gcmkFOOTER_NO();
  97137. + /* Success. */
  97138. + return gcvSTATUS_OK;
  97139. +}
  97140. +
  97141. +/*******************************************************************************
  97142. +**
  97143. +** gckVGHARDWARE_SplitMemory
  97144. +**
  97145. +** Split a hardware specific memory address into a pool and offset.
  97146. +**
  97147. +** INPUT:
  97148. +**
  97149. +** gckVGHARDWARE Hardware
  97150. +** Pointer to the gckVGHARDWARE object.
  97151. +**
  97152. +** gctUINT32 Address
  97153. +** Address in hardware specific format.
  97154. +**
  97155. +** OUTPUT:
  97156. +**
  97157. +** gcePOOL * Pool
  97158. +** Pointer to a variable that will hold the pool type for the address.
  97159. +**
  97160. +** gctUINT32 * Offset
  97161. +** Pointer to a variable that will hold the offset for the address.
  97162. +*/
  97163. +gceSTATUS
  97164. +gckVGHARDWARE_SplitMemory(
  97165. + IN gckVGHARDWARE Hardware,
  97166. + IN gctUINT32 Address,
  97167. + OUT gcePOOL * Pool,
  97168. + OUT gctUINT32 * Offset
  97169. + )
  97170. +{
  97171. + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Pool=0x%x Offset = 0x%x",
  97172. + Hardware, Address, Pool, Offset);
  97173. + /* Verify the arguments. */
  97174. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97175. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  97176. + gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
  97177. +
  97178. + /* Dispatch on memory type. */
  97179. + switch ((((((gctUINT32) (Address)) >> (0 ? 1:0)) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1)))))) ))
  97180. + {
  97181. + case 0x0:
  97182. + /* System memory. */
  97183. + *Pool = gcvPOOL_SYSTEM;
  97184. + break;
  97185. +
  97186. + case 0x2:
  97187. + /* Virtual memory. */
  97188. + *Pool = gcvPOOL_VIRTUAL;
  97189. + break;
  97190. +
  97191. + default:
  97192. + /* Invalid memory type. */
  97193. + gcmkFOOTER_NO();
  97194. + return gcvSTATUS_INVALID_ARGUMENT;
  97195. + }
  97196. +
  97197. + /* Return offset of address. */
  97198. + *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)));
  97199. +
  97200. + gcmkFOOTER_NO();
  97201. + /* Success. */
  97202. + return gcvSTATUS_OK;
  97203. +}
  97204. +
  97205. +/*******************************************************************************
  97206. +**
  97207. +** gckVGHARDWARE_Execute
  97208. +**
  97209. +** Kickstart the hardware's command processor with an initialized command
  97210. +** buffer.
  97211. +**
  97212. +** INPUT:
  97213. +**
  97214. +** gckVGHARDWARE Hardware
  97215. +** Pointer to the gckVGHARDWARE object.
  97216. +**
  97217. +** gctUINT32 Address
  97218. +** Address of the command buffer.
  97219. +**
  97220. +** gctSIZE_T Count
  97221. +** Number of command-sized data units to be executed.
  97222. +**
  97223. +** OUTPUT:
  97224. +**
  97225. +** Nothing.
  97226. +*/
  97227. +gceSTATUS
  97228. +gckVGHARDWARE_Execute(
  97229. + IN gckVGHARDWARE Hardware,
  97230. + IN gctUINT32 Address,
  97231. + IN gctSIZE_T Count
  97232. + )
  97233. +{
  97234. + gceSTATUS status;
  97235. +
  97236. + gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Count=0x%x",
  97237. + Hardware, Address, Count);
  97238. +
  97239. + /* Verify the arguments. */
  97240. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97241. +
  97242. + do
  97243. + {
  97244. + /* Enable all events. */
  97245. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  97246. + Hardware->os,
  97247. + gcvCORE_VG,
  97248. + 0x00014,
  97249. + Hardware->eventMask
  97250. + ));
  97251. +
  97252. + if (Hardware->fe20)
  97253. + {
  97254. + /* Write address register. */
  97255. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  97256. + Hardware->os,
  97257. + gcvCORE_VG,
  97258. + 0x00500,
  97259. + gcmkFIXADDRESS(Address)
  97260. + ));
  97261. +
  97262. + /* Write control register. */
  97263. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  97264. + Hardware->os,
  97265. + gcvCORE_VG,
  97266. + 0x00504,
  97267. + Count
  97268. + ));
  97269. + }
  97270. + else
  97271. + {
  97272. + /* Write address register. */
  97273. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  97274. + Hardware->os,
  97275. + gcvCORE_VG,
  97276. + 0x00654,
  97277. + gcmkFIXADDRESS(Address)
  97278. + ));
  97279. +
  97280. + /* Write control register. */
  97281. + gcmkERR_BREAK(gckOS_WriteRegisterEx(
  97282. + Hardware->os,
  97283. + gcvCORE_VG,
  97284. + 0x00658,
  97285. + ((((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))) |
  97286. + ((((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)))
  97287. + ));
  97288. + }
  97289. +
  97290. + /* Success. */
  97291. + gcmkFOOTER();
  97292. + return gcvSTATUS_OK;
  97293. + }
  97294. + while (gcvFALSE);
  97295. +
  97296. +
  97297. + gcmkFOOTER();
  97298. + /* Return the status. */
  97299. + return status;
  97300. +}
  97301. +
  97302. +/*******************************************************************************
  97303. +**
  97304. +** gckVGHARDWARE_AlignToTile
  97305. +**
  97306. +** Align the specified width and height to tile boundaries.
  97307. +**
  97308. +** INPUT:
  97309. +**
  97310. +** gckVGHARDWARE Hardware
  97311. +** Pointer to an gckVGHARDWARE object.
  97312. +**
  97313. +** gceSURF_TYPE Type
  97314. +** Type of alignment.
  97315. +**
  97316. +** gctUINT32 * Width
  97317. +** Pointer to the width to be aligned. If 'Width' is gcvNULL, no width
  97318. +** will be aligned.
  97319. +**
  97320. +** gctUINT32 * Height
  97321. +** Pointer to the height to be aligned. If 'Height' is gcvNULL, no height
  97322. +** will be aligned.
  97323. +**
  97324. +** OUTPUT:
  97325. +**
  97326. +** gctUINT32 * Width
  97327. +** Pointer to a variable that will receive the aligned width.
  97328. +**
  97329. +** gctUINT32 * Height
  97330. +** Pointer to a variable that will receive the aligned height.
  97331. +*/
  97332. +gceSTATUS
  97333. +gckVGHARDWARE_AlignToTile(
  97334. + IN gckVGHARDWARE Hardware,
  97335. + IN gceSURF_TYPE Type,
  97336. + IN OUT gctUINT32 * Width,
  97337. + IN OUT gctUINT32 * Height
  97338. + )
  97339. +{
  97340. + gcmkHEADER_ARG("Hardware=0x%x Type=0x%x Width=0x%x Height=0x%x",
  97341. + Hardware, Type, Width, Height);
  97342. + /* Verify the arguments. */
  97343. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97344. +
  97345. + if (Width != gcvNULL)
  97346. + {
  97347. + /* Align the width. */
  97348. + *Width = gcmALIGN(*Width, (Type == gcvSURF_TEXTURE) ? 4 : 16);
  97349. + }
  97350. +
  97351. + if (Height != gcvNULL)
  97352. + {
  97353. + /* Special case for VG images. */
  97354. + if ((*Height == 0) && (Type == gcvSURF_IMAGE))
  97355. + {
  97356. + *Height = 4;
  97357. + }
  97358. + else
  97359. + {
  97360. + /* Align the height. */
  97361. + *Height = gcmALIGN(*Height, 4);
  97362. + }
  97363. + }
  97364. +
  97365. + gcmkFOOTER_NO();
  97366. + /* Success. */
  97367. + return gcvSTATUS_OK;
  97368. +}
  97369. +
  97370. +/*******************************************************************************
  97371. +**
  97372. +** gckVGHARDWARE_ConvertLogical
  97373. +**
  97374. +** Convert a logical system address into a hardware specific address.
  97375. +**
  97376. +** INPUT:
  97377. +**
  97378. +** gckVGHARDWARE Hardware
  97379. +** Pointer to an gckVGHARDWARE object.
  97380. +**
  97381. +** gctPOINTER Logical
  97382. +** Logical address to convert.
  97383. +**
  97384. +** gctUINT32* Address
  97385. +** Return hardware specific address.
  97386. +**
  97387. +** OUTPUT:
  97388. +**
  97389. +** Nothing.
  97390. +*/
  97391. +gceSTATUS
  97392. +gckVGHARDWARE_ConvertLogical(
  97393. + IN gckVGHARDWARE Hardware,
  97394. + IN gctPOINTER Logical,
  97395. + OUT gctUINT32 * Address
  97396. + )
  97397. +{
  97398. + gctUINT32 address;
  97399. + gceSTATUS status;
  97400. +
  97401. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Address=0x%x",
  97402. + Hardware, Logical, Address);
  97403. +
  97404. + /* Verify the arguments. */
  97405. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97406. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  97407. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  97408. +
  97409. + do
  97410. + {
  97411. + /* Convert logical address into a physical address. */
  97412. + gcmkERR_BREAK(gckOS_GetPhysicalAddress(
  97413. + Hardware->os, Logical, &address
  97414. + ));
  97415. +
  97416. + /* Return hardware specific address. */
  97417. + *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)));
  97418. +
  97419. + /* Success. */
  97420. + gcmkFOOTER();
  97421. + return gcvSTATUS_OK;
  97422. + }
  97423. + while (gcvFALSE);
  97424. +
  97425. + gcmkFOOTER();
  97426. + /* Return the status. */
  97427. + return status;
  97428. +}
  97429. +
  97430. +/*******************************************************************************
  97431. +**
  97432. +** gckVGHARDWARE_QuerySystemMemory
  97433. +**
  97434. +** Query the command buffer alignment and number of reserved bytes.
  97435. +**
  97436. +** INPUT:
  97437. +**
  97438. +** gckVGHARDWARE Harwdare
  97439. +** Pointer to an gckVGHARDWARE object.
  97440. +**
  97441. +** OUTPUT:
  97442. +**
  97443. +** gctSIZE_T * SystemSize
  97444. +** Pointer to a variable that receives the maximum size of the system
  97445. +** memory.
  97446. +**
  97447. +** gctUINT32 * SystemBaseAddress
  97448. +** Poinetr to a variable that receives the base address for system
  97449. +** memory.
  97450. +*/
  97451. +gceSTATUS gckVGHARDWARE_QuerySystemMemory(
  97452. + IN gckVGHARDWARE Hardware,
  97453. + OUT gctSIZE_T * SystemSize,
  97454. + OUT gctUINT32 * SystemBaseAddress
  97455. + )
  97456. +{
  97457. + gcmkHEADER_ARG("Hardware=0x%x SystemSize=0x%x SystemBaseAddress=0x%x",
  97458. + Hardware, SystemSize, SystemBaseAddress);
  97459. +
  97460. + /* Verify the arguments. */
  97461. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97462. +
  97463. + if (SystemSize != gcvNULL)
  97464. + {
  97465. + /* Maximum system memory can be 2GB. */
  97466. + *SystemSize = (gctSIZE_T)(1 << 31);
  97467. + }
  97468. +
  97469. + if (SystemBaseAddress != gcvNULL)
  97470. + {
  97471. + /* Set system memory base address. */
  97472. + *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)));
  97473. + }
  97474. +
  97475. + gcmkFOOTER_NO();
  97476. + /* Success. */
  97477. + return gcvSTATUS_OK;
  97478. +}
  97479. +
  97480. +/*******************************************************************************
  97481. +**
  97482. +** gckVGHARDWARE_SetMMU
  97483. +**
  97484. +** Set the page table base address.
  97485. +**
  97486. +** INPUT:
  97487. +**
  97488. +** gckVGHARDWARE Harwdare
  97489. +** Pointer to an gckVGHARDWARE object.
  97490. +**
  97491. +** gctPOINTER Logical
  97492. +** Logical address of the page table.
  97493. +**
  97494. +** OUTPUT:
  97495. +**
  97496. +** Nothing.
  97497. +*/
  97498. +gceSTATUS gckVGHARDWARE_SetMMU(
  97499. + IN gckVGHARDWARE Hardware,
  97500. + IN gctPOINTER Logical
  97501. + )
  97502. +{
  97503. + gceSTATUS status;
  97504. + gctUINT32 address = 0;
  97505. +
  97506. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x",
  97507. + Hardware, Logical);
  97508. +
  97509. + /* Verify the arguments. */
  97510. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97511. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  97512. +
  97513. + do
  97514. + {
  97515. + /* Convert the logical address into an hardware address. */
  97516. + gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, &address) );
  97517. +
  97518. + /* Write the AQMemoryFePageTable register. */
  97519. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  97520. + 0x00400,
  97521. + gcmkFIXADDRESS(address)) );
  97522. +
  97523. + /* Write the AQMemoryTxPageTable register. */
  97524. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  97525. + 0x00404,
  97526. + gcmkFIXADDRESS(address)) );
  97527. +
  97528. + /* Write the AQMemoryPePageTable register. */
  97529. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  97530. + 0x00408,
  97531. + gcmkFIXADDRESS(address)) );
  97532. +
  97533. + /* Write the AQMemoryPezPageTable register. */
  97534. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  97535. + 0x0040C,
  97536. + gcmkFIXADDRESS(address)) );
  97537. +
  97538. + /* Write the AQMemoryRaPageTable register. */
  97539. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  97540. + 0x00410,
  97541. + gcmkFIXADDRESS(address)) );
  97542. + }
  97543. + while (gcvFALSE);
  97544. +
  97545. + gcmkFOOTER();
  97546. + /* Return the status. */
  97547. + return status;
  97548. +}
  97549. +
  97550. +/*******************************************************************************
  97551. +**
  97552. +** gckVGHARDWARE_FlushMMU
  97553. +**
  97554. +** Flush the page table.
  97555. +**
  97556. +** INPUT:
  97557. +**
  97558. +** gckVGHARDWARE Harwdare
  97559. +** Pointer to an gckVGHARDWARE object.
  97560. +**
  97561. +** OUTPUT:
  97562. +**
  97563. +** Nothing.
  97564. +*/
  97565. +gceSTATUS gckVGHARDWARE_FlushMMU(
  97566. + IN gckVGHARDWARE Hardware
  97567. + )
  97568. +{
  97569. + gceSTATUS status;
  97570. + gckVGCOMMAND command;
  97571. +
  97572. + gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
  97573. + /* Verify the arguments. */
  97574. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97575. +
  97576. + do
  97577. + {
  97578. + gcsCMDBUFFER_PTR commandBuffer;
  97579. + gctUINT32_PTR buffer;
  97580. +
  97581. + /* Create a shortcut to the command buffer object. */
  97582. + command = Hardware->kernel->command;
  97583. +
  97584. + /* Allocate command buffer space. */
  97585. + gcmkERR_BREAK(gckVGCOMMAND_Allocate(
  97586. + command, 8, &commandBuffer, (gctPOINTER *) &buffer
  97587. + ));
  97588. +
  97589. + buffer[0]
  97590. + = ((((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)))
  97591. + | ((((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)))
  97592. + | ((((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)));
  97593. +
  97594. + buffer[1]
  97595. + = ((((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)))
  97596. + | ((((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)))
  97597. + | ((((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)))
  97598. + | ((((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)))
  97599. + | ((((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)));
  97600. + }
  97601. + while(gcvFALSE);
  97602. +
  97603. + gcmkFOOTER();
  97604. + /* Return the status. */
  97605. + return status;
  97606. +}
  97607. +
  97608. +/*******************************************************************************
  97609. +**
  97610. +** gckVGHARDWARE_BuildVirtualAddress
  97611. +**
  97612. +** Build a virtual address.
  97613. +**
  97614. +** INPUT:
  97615. +**
  97616. +** gckVGHARDWARE Harwdare
  97617. +** Pointer to an gckVGHARDWARE object.
  97618. +**
  97619. +** gctUINT32 Index
  97620. +** Index into page table.
  97621. +**
  97622. +** gctUINT32 Offset
  97623. +** Offset into page.
  97624. +**
  97625. +** OUTPUT:
  97626. +**
  97627. +** gctUINT32 * Address
  97628. +** Pointer to a variable receiving te hardware address.
  97629. +*/
  97630. +gceSTATUS gckVGHARDWARE_BuildVirtualAddress(
  97631. + IN gckVGHARDWARE Hardware,
  97632. + IN gctUINT32 Index,
  97633. + IN gctUINT32 Offset,
  97634. + OUT gctUINT32 * Address
  97635. + )
  97636. +{
  97637. + gctUINT32 address;
  97638. +
  97639. + gcmkHEADER_ARG("Hardware=0x%x Index=0x%x Offset=0x%x Address=0x%x",
  97640. + Hardware, Index, Offset, Address);
  97641. +
  97642. + /* Verify the arguments. */
  97643. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97644. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  97645. +
  97646. + /* Build virtual address. */
  97647. + address = (Index << 12) | Offset;
  97648. +
  97649. + /* Set virtual type. */
  97650. + 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)));
  97651. +
  97652. + /* Set the result. */
  97653. + *Address = address;
  97654. +
  97655. + gcmkFOOTER_NO();
  97656. + /* Success. */
  97657. + return gcvSTATUS_OK;
  97658. +}
  97659. +
  97660. +gceSTATUS
  97661. +gckVGHARDWARE_GetIdle(
  97662. + IN gckVGHARDWARE Hardware,
  97663. + OUT gctUINT32 * Data
  97664. + )
  97665. +{
  97666. + gceSTATUS status;
  97667. + gcmkHEADER_ARG("Hardware=0x%x Data=0x%x", Hardware, Data);
  97668. + /* Verify the arguments. */
  97669. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97670. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  97671. +
  97672. + /* Read register and return. */
  97673. + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, Data);
  97674. + gcmkFOOTER();
  97675. + return status;
  97676. +}
  97677. +
  97678. +gceSTATUS
  97679. +gckVGHARDWARE_SetFastClear(
  97680. + IN gckVGHARDWARE Hardware,
  97681. + IN gctINT Enable
  97682. + )
  97683. +{
  97684. + gctUINT32 debug;
  97685. + gceSTATUS status;
  97686. +
  97687. + 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)))))) ))
  97688. + {
  97689. + return gcvSTATUS_OK;
  97690. + }
  97691. +
  97692. + do
  97693. + {
  97694. + if (Enable == -1)
  97695. + {
  97696. + Enable = (Hardware->chipModel > gcv500) ||
  97697. + ((Hardware->chipModel == gcv500) && (Hardware->chipRevision >= 3));
  97698. + }
  97699. +
  97700. + gcmkERR_BREAK(gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
  97701. + 0x00414,
  97702. + &debug));
  97703. +
  97704. + 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)));
  97705. +
  97706. +#ifdef AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION
  97707. + 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)));
  97708. +#endif
  97709. +
  97710. + gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
  97711. + 0x00414,
  97712. + debug));
  97713. +
  97714. + Hardware->allowFastClear = Enable;
  97715. +
  97716. + status = gcvFALSE;
  97717. + }
  97718. + while (gcvFALSE);
  97719. +
  97720. + return status;
  97721. +}
  97722. +
  97723. +gceSTATUS
  97724. +gckVGHARDWARE_ReadInterrupt(
  97725. + IN gckVGHARDWARE Hardware,
  97726. + OUT gctUINT32_PTR IDs
  97727. + )
  97728. +{
  97729. + gceSTATUS status;
  97730. + gcmkHEADER_ARG("Hardware=0x%x IDs=0x%x", Hardware, IDs);
  97731. +
  97732. + /* Verify the arguments. */
  97733. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97734. + gcmkVERIFY_ARGUMENT(IDs != gcvNULL);
  97735. +
  97736. + /* Read AQIntrAcknowledge register. */
  97737. + status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
  97738. + 0x00010,
  97739. + IDs);
  97740. + gcmkFOOTER();
  97741. + return status;
  97742. +}
  97743. +
  97744. +static gceSTATUS _CommandStall(
  97745. + gckVGHARDWARE Hardware)
  97746. +{
  97747. + gceSTATUS status;
  97748. + gckVGCOMMAND command;
  97749. +
  97750. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  97751. + /* Verify the arguments. */
  97752. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97753. +
  97754. + do
  97755. + {
  97756. + gctUINT32_PTR buffer;
  97757. + command = Hardware->kernel->command;
  97758. +
  97759. + /* Allocate command buffer space. */
  97760. + gcmkERR_BREAK(gckVGCOMMAND_Allocate(
  97761. + command, 8, &command->powerStallBuffer,
  97762. + (gctPOINTER *) &buffer
  97763. + ));
  97764. +
  97765. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  97766. + command, buffer, gcvBLOCK_PIXEL,
  97767. + command->powerStallInt, gcvNULL));
  97768. +
  97769. + gcmkERR_BREAK(gckVGCOMMAND_Execute(
  97770. + command,
  97771. + command->powerStallBuffer
  97772. + ));
  97773. +
  97774. + /* Wait the signal. */
  97775. + gcmkERR_BREAK(gckOS_WaitSignal(
  97776. + command->os,
  97777. + command->powerStallSignal,
  97778. + gcdGPU_TIMEOUT));
  97779. +
  97780. +
  97781. + }
  97782. + while(gcvFALSE);
  97783. +
  97784. + gcmkFOOTER();
  97785. + /* Return the status. */
  97786. + return status;
  97787. +}
  97788. +
  97789. +/*******************************************************************************
  97790. +**
  97791. +** gckHARDWARE_SetPowerManagementState
  97792. +**
  97793. +** Set GPU to a specified power state.
  97794. +**
  97795. +** INPUT:
  97796. +**
  97797. +** gckHARDWARE Harwdare
  97798. +** Pointer to an gckHARDWARE object.
  97799. +**
  97800. +** gceCHIPPOWERSTATE State
  97801. +** Power State.
  97802. +**
  97803. +*/
  97804. +gceSTATUS
  97805. +gckVGHARDWARE_SetPowerManagementState(
  97806. + IN gckVGHARDWARE Hardware,
  97807. + IN gceCHIPPOWERSTATE State
  97808. + )
  97809. +{
  97810. + gceSTATUS status;
  97811. + gckVGCOMMAND command = gcvNULL;
  97812. + gckOS os;
  97813. + gctUINT flag/*, clock*/;
  97814. +
  97815. + gctBOOL acquired = gcvFALSE;
  97816. + gctBOOL stall = gcvTRUE;
  97817. + gctBOOL commitMutex = gcvFALSE;
  97818. + gctBOOL mutexAcquired = gcvFALSE;
  97819. +
  97820. +#if gcdPOWEROFF_TIMEOUT
  97821. + gctBOOL timeout = gcvFALSE;
  97822. + gctBOOL isAfter = gcvFALSE;
  97823. + gctUINT32 currentTime;
  97824. +#endif
  97825. +
  97826. + gctBOOL broadcast = gcvFALSE;
  97827. + gctUINT32 process, thread;
  97828. + gctBOOL global = gcvFALSE;
  97829. +
  97830. +#if gcdENABLE_PROFILING
  97831. + gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
  97832. + initTime, offTime, startTime, totalTime;
  97833. +#endif
  97834. +
  97835. + /* State transition flags. */
  97836. + static const gctUINT flags[4][4] =
  97837. + {
  97838. + /* gcvPOWER_ON */
  97839. + { /* ON */ 0,
  97840. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  97841. + gcvPOWER_FLAG_STALL |
  97842. + gcvPOWER_FLAG_STOP |
  97843. + gcvPOWER_FLAG_POWER_OFF |
  97844. + gcvPOWER_FLAG_CLOCK_OFF,
  97845. + /* IDLE */ gcvPOWER_FLAG_NOP,
  97846. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  97847. + gcvPOWER_FLAG_STALL |
  97848. + gcvPOWER_FLAG_STOP |
  97849. + gcvPOWER_FLAG_CLOCK_OFF,
  97850. + },
  97851. +
  97852. + /* gcvPOWER_OFF */
  97853. + { /* ON */ gcvPOWER_FLAG_INITIALIZE |
  97854. + gcvPOWER_FLAG_START |
  97855. + gcvPOWER_FLAG_RELEASE |
  97856. + gcvPOWER_FLAG_DELAY,
  97857. + /* OFF */ 0,
  97858. + /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
  97859. + gcvPOWER_FLAG_START |
  97860. + gcvPOWER_FLAG_RELEASE |
  97861. + gcvPOWER_FLAG_DELAY,
  97862. + /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
  97863. + gcvPOWER_FLAG_CLOCK_OFF,
  97864. + },
  97865. +
  97866. + /* gcvPOWER_IDLE */
  97867. + { /* ON */ gcvPOWER_FLAG_NOP,
  97868. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  97869. + gcvPOWER_FLAG_STOP |
  97870. + gcvPOWER_FLAG_POWER_OFF |
  97871. + gcvPOWER_FLAG_CLOCK_OFF,
  97872. + /* IDLE */ 0,
  97873. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  97874. + gcvPOWER_FLAG_STOP |
  97875. + gcvPOWER_FLAG_CLOCK_OFF,
  97876. + },
  97877. +
  97878. + /* gcvPOWER_SUSPEND */
  97879. + { /* ON */ gcvPOWER_FLAG_START |
  97880. + gcvPOWER_FLAG_RELEASE |
  97881. + gcvPOWER_FLAG_DELAY |
  97882. + gcvPOWER_FLAG_CLOCK_ON,
  97883. + /* OFF */ gcvPOWER_FLAG_SAVE |
  97884. + gcvPOWER_FLAG_POWER_OFF |
  97885. + gcvPOWER_FLAG_CLOCK_OFF,
  97886. + /* IDLE */ gcvPOWER_FLAG_START |
  97887. + gcvPOWER_FLAG_DELAY |
  97888. + gcvPOWER_FLAG_RELEASE |
  97889. + gcvPOWER_FLAG_CLOCK_ON,
  97890. + /* SUSPEND */ 0,
  97891. + },
  97892. + };
  97893. +
  97894. + gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
  97895. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  97896. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  97897. + "Switching to power state %d",
  97898. + State);
  97899. +#endif
  97900. +
  97901. + /* Verify the arguments. */
  97902. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  97903. +
  97904. + /* Get the gckOS object pointer. */
  97905. + os = Hardware->os;
  97906. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  97907. +
  97908. + /* Get the gckCOMMAND object pointer. */
  97909. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  97910. + command = Hardware->kernel->command;
  97911. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  97912. +
  97913. + if (Hardware->powerManagement == gcvFALSE)
  97914. + {
  97915. + gcmkFOOTER_NO();
  97916. + return gcvSTATUS_OK;
  97917. + }
  97918. +
  97919. + /* Start profiler. */
  97920. + gcmkPROFILE_INIT(freq, time);
  97921. +
  97922. + /* Convert the broadcast power state. */
  97923. + switch (State)
  97924. + {
  97925. + case gcvPOWER_SUSPEND_ATPOWERON:
  97926. + /* Convert to SUSPEND and don't wait for STALL. */
  97927. + State = gcvPOWER_SUSPEND;
  97928. + stall = gcvFALSE;
  97929. + break;
  97930. +
  97931. + case gcvPOWER_OFF_ATPOWERON:
  97932. + /* Convert to OFF and don't wait for STALL. */
  97933. + State = gcvPOWER_OFF;
  97934. + stall = gcvFALSE;
  97935. + break;
  97936. +
  97937. + case gcvPOWER_IDLE_BROADCAST:
  97938. + /* Convert to IDLE and note we are inside broadcast. */
  97939. + State = gcvPOWER_IDLE;
  97940. + broadcast = gcvTRUE;
  97941. + break;
  97942. +
  97943. + case gcvPOWER_SUSPEND_BROADCAST:
  97944. + /* Convert to SUSPEND and note we are inside broadcast. */
  97945. + State = gcvPOWER_SUSPEND;
  97946. + broadcast = gcvTRUE;
  97947. + break;
  97948. +
  97949. + case gcvPOWER_OFF_BROADCAST:
  97950. + /* Convert to OFF and note we are inside broadcast. */
  97951. + State = gcvPOWER_OFF;
  97952. + broadcast = gcvTRUE;
  97953. + break;
  97954. +
  97955. + case gcvPOWER_OFF_RECOVERY:
  97956. + /* Convert to OFF and note we are inside recovery. */
  97957. + State = gcvPOWER_OFF;
  97958. + stall = gcvFALSE;
  97959. + broadcast = gcvTRUE;
  97960. + break;
  97961. +
  97962. + case gcvPOWER_ON_AUTO:
  97963. + /* Convert to ON and note we are inside recovery. */
  97964. + State = gcvPOWER_ON;
  97965. + break;
  97966. +
  97967. + case gcvPOWER_ON:
  97968. + case gcvPOWER_IDLE:
  97969. + case gcvPOWER_SUSPEND:
  97970. + case gcvPOWER_OFF:
  97971. + /* Mark as global power management. */
  97972. + global = gcvTRUE;
  97973. + break;
  97974. +
  97975. +#if gcdPOWEROFF_TIMEOUT
  97976. + case gcvPOWER_OFF_TIMEOUT:
  97977. + /* Convert to OFF and note we are inside broadcast. */
  97978. + State = gcvPOWER_OFF;
  97979. + broadcast = gcvTRUE;
  97980. + /* Check time out */
  97981. + timeout = gcvTRUE;
  97982. + break;
  97983. +#endif
  97984. +
  97985. + default:
  97986. + break;
  97987. + }
  97988. +
  97989. + /* Get current process and thread IDs. */
  97990. + gcmkONERROR(gckOS_GetProcessID(&process));
  97991. + gcmkONERROR(gckOS_GetThreadID(&thread));
  97992. +
  97993. + /* Acquire the power mutex. */
  97994. + if (broadcast)
  97995. + {
  97996. + /* Try to acquire the power mutex. */
  97997. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
  97998. +
  97999. + if (status == gcvSTATUS_TIMEOUT)
  98000. + {
  98001. + /* Check if we already own this mutex. */
  98002. + if ((Hardware->powerProcess == process)
  98003. + && (Hardware->powerThread == thread)
  98004. + )
  98005. + {
  98006. + /* Bail out on recursive power management. */
  98007. + gcmkFOOTER_NO();
  98008. + return gcvSTATUS_OK;
  98009. + }
  98010. + else if (State == gcvPOWER_IDLE)
  98011. + {
  98012. + /* gcvPOWER_IDLE_BROADCAST is from IST,
  98013. + ** so waiting here will cause deadlock,
  98014. + ** if lock holder call gckCOMMAND_Stall() */
  98015. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  98016. + }
  98017. + else
  98018. + {
  98019. + /* Acquire the power mutex. */
  98020. + gcmkONERROR(gckOS_AcquireMutex(os,
  98021. + Hardware->powerMutex,
  98022. + gcvINFINITE));
  98023. + }
  98024. + }
  98025. + }
  98026. + else
  98027. + {
  98028. + /* Acquire the power mutex. */
  98029. + gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
  98030. + }
  98031. +
  98032. + /* Get time until mtuex acquired. */
  98033. + gcmkPROFILE_QUERY(time, mutexTime);
  98034. +
  98035. + Hardware->powerProcess = process;
  98036. + Hardware->powerThread = thread;
  98037. + mutexAcquired = gcvTRUE;
  98038. +
  98039. + /* Grab control flags and clock. */
  98040. + flag = flags[Hardware->chipPowerState][State];
  98041. + /*clock = clocks[State];*/
  98042. +
  98043. +#if gcdPOWEROFF_TIMEOUT
  98044. + if (timeout)
  98045. + {
  98046. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  98047. +
  98048. + gcmkONERROR(
  98049. + gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
  98050. +
  98051. + /* powerOffTime is pushed forward, give up.*/
  98052. + if (isAfter
  98053. + /* Expect a transition start from IDLE. */
  98054. + || (Hardware->chipPowerState == gcvPOWER_ON)
  98055. + || (Hardware->chipPowerState == gcvPOWER_OFF)
  98056. + )
  98057. + {
  98058. + /* Release the power mutex. */
  98059. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  98060. +
  98061. + /* No need to do anything. */
  98062. + gcmkFOOTER_NO();
  98063. + return gcvSTATUS_OK;
  98064. + }
  98065. + }
  98066. +#endif
  98067. +
  98068. + if (flag == 0)
  98069. + {
  98070. + /* Release the power mutex. */
  98071. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  98072. +
  98073. + /* No need to do anything. */
  98074. + gcmkFOOTER_NO();
  98075. + return gcvSTATUS_OK;
  98076. + }
  98077. +
  98078. + /* internal power control */
  98079. + if (!global)
  98080. + {
  98081. + if (Hardware->chipPowerStateGlobal == gcvPOWER_OFF)
  98082. + {
  98083. + /* Release the power mutex. */
  98084. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  98085. +
  98086. + /* No need to do anything. */
  98087. + gcmkFOOTER_NO();
  98088. + return gcvSTATUS_OK;
  98089. + }
  98090. + }
  98091. + else
  98092. + {
  98093. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  98094. + {
  98095. + /* Acquire the power management semaphore. */
  98096. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  98097. + acquired = gcvTRUE;
  98098. +
  98099. + /* avoid acquiring again. */
  98100. + flag &= ~gcvPOWER_FLAG_ACQUIRE;
  98101. + }
  98102. + }
  98103. +
  98104. + if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
  98105. + {
  98106. + /* Turn on the power. */
  98107. + gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG, gcvTRUE, gcvTRUE));
  98108. +
  98109. + /* Mark clock and power as enabled. */
  98110. + Hardware->clockState = gcvTRUE;
  98111. + Hardware->powerState = gcvTRUE;
  98112. + }
  98113. +
  98114. + /* Get time until powered on. */
  98115. + gcmkPROFILE_QUERY(time, onTime);
  98116. +
  98117. + if ((flag & gcvPOWER_FLAG_STALL) && stall)
  98118. + {
  98119. + /* Acquire the mutex. */
  98120. + gcmkONERROR(gckOS_AcquireMutex(
  98121. + command->os,
  98122. + command->commitMutex,
  98123. + gcvINFINITE
  98124. + ));
  98125. +
  98126. + commitMutex = gcvTRUE;
  98127. +
  98128. + gcmkONERROR(_CommandStall(Hardware));
  98129. + }
  98130. +
  98131. + /* Get time until stalled. */
  98132. + gcmkPROFILE_QUERY(time, stallTime);
  98133. +
  98134. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  98135. + {
  98136. + /* Acquire the power management semaphore. */
  98137. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  98138. +
  98139. + acquired = gcvTRUE;
  98140. + }
  98141. +
  98142. + if (flag & gcvPOWER_FLAG_STOP)
  98143. + {
  98144. + }
  98145. +
  98146. + /* Get time until stopped. */
  98147. + gcmkPROFILE_QUERY(time, stopTime);
  98148. +
  98149. + /* Only process this when hardware is enabled. */
  98150. + if (Hardware->clockState && Hardware->powerState)
  98151. + {
  98152. + }
  98153. +
  98154. + if (flag & gcvPOWER_FLAG_DELAY)
  98155. + {
  98156. + /* Wait for the specified amount of time to settle coming back from
  98157. + ** power-off or suspend state. */
  98158. + gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
  98159. + }
  98160. +
  98161. + /* Get time until delayed. */
  98162. + gcmkPROFILE_QUERY(time, delayTime);
  98163. +
  98164. + if (flag & gcvPOWER_FLAG_INITIALIZE)
  98165. + {
  98166. + gcmkONERROR(gckVGHARDWARE_SetMMU(Hardware, Hardware->kernel->mmu->pageTableLogical));
  98167. +
  98168. + /* Force the command queue to reload the next context. */
  98169. + command->currentContext = 0;
  98170. + }
  98171. +
  98172. + /* Get time until initialized. */
  98173. + gcmkPROFILE_QUERY(time, initTime);
  98174. +
  98175. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  98176. + {
  98177. + /* Turn off the GPU power. */
  98178. + gcmkONERROR(
  98179. + gckOS_SetGPUPower(os,
  98180. + gcvCORE_VG,
  98181. + (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  98182. + : gcvTRUE,
  98183. + (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  98184. + : gcvTRUE));
  98185. +
  98186. + /* Save current hardware power and clock states. */
  98187. + Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  98188. + : gcvTRUE;
  98189. + Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  98190. + : gcvTRUE;
  98191. + }
  98192. +
  98193. + /* Get time until off. */
  98194. + gcmkPROFILE_QUERY(time, offTime);
  98195. +
  98196. + if (flag & gcvPOWER_FLAG_START)
  98197. + {
  98198. + }
  98199. +
  98200. + /* Get time until started. */
  98201. + gcmkPROFILE_QUERY(time, startTime);
  98202. +
  98203. + if (flag & gcvPOWER_FLAG_RELEASE)
  98204. + {
  98205. + /* Release the power management semaphore. */
  98206. + gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
  98207. + acquired = gcvFALSE;
  98208. + }
  98209. +
  98210. + /* Save the new power state. */
  98211. + Hardware->chipPowerState = State;
  98212. +
  98213. + if (global)
  98214. + {
  98215. + /* Save the new power state. */
  98216. + Hardware->chipPowerStateGlobal = State;
  98217. + }
  98218. +
  98219. + if (commitMutex)
  98220. + {
  98221. + /* Acquire the mutex. */
  98222. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  98223. + command->os,
  98224. + command->commitMutex
  98225. + ));
  98226. + }
  98227. +
  98228. +#if gcdPOWEROFF_TIMEOUT
  98229. + /* Reset power off time */
  98230. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  98231. +
  98232. + Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
  98233. +
  98234. + if (State == gcvPOWER_IDLE)
  98235. + {
  98236. + /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
  98237. + gcmkVERIFY_OK(gckOS_StartTimer(os,
  98238. + Hardware->powerOffTimer,
  98239. + Hardware->powerOffTimeout));
  98240. + }
  98241. + else
  98242. + {
  98243. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
  98244. +
  98245. + /* Cancel running timer when GPU enters ON or OFF. */
  98246. + gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
  98247. + }
  98248. +#endif
  98249. +
  98250. + /* Release the power mutex. */
  98251. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  98252. +
  98253. + /* Get total time. */
  98254. + gcmkPROFILE_QUERY(time, totalTime);
  98255. +#if gcdENABLE_PROFILING
  98256. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98257. + "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
  98258. + freq, mutexTime, onTime, stallTime, stopTime);
  98259. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  98260. + " delay:%llu init:%llu off:%llu start:%llu total:%llu",
  98261. + delayTime, initTime, offTime, startTime, totalTime);
  98262. +#endif
  98263. +
  98264. + /* Success. */
  98265. + gcmkFOOTER_NO();
  98266. + return gcvSTATUS_OK;
  98267. +
  98268. +OnError:
  98269. +
  98270. + if (acquired)
  98271. + {
  98272. + /* Release semaphore. */
  98273. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  98274. + command->powerSemaphore));
  98275. + }
  98276. +
  98277. + if (mutexAcquired)
  98278. + {
  98279. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  98280. + }
  98281. +
  98282. + if (commitMutex)
  98283. + {
  98284. + /* Acquire the mutex. */
  98285. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  98286. + command->os,
  98287. + command->commitMutex
  98288. + ));
  98289. + }
  98290. +
  98291. + /* Return the status. */
  98292. + gcmkFOOTER();
  98293. + return status;
  98294. +}
  98295. +
  98296. +/*******************************************************************************
  98297. +**
  98298. +** gckHARDWARE_QueryPowerManagementState
  98299. +**
  98300. +** Get GPU power state.
  98301. +**
  98302. +** INPUT:
  98303. +**
  98304. +** gckHARDWARE Harwdare
  98305. +** Pointer to an gckHARDWARE object.
  98306. +**
  98307. +** gceCHIPPOWERSTATE* State
  98308. +** Power State.
  98309. +**
  98310. +*/
  98311. +gceSTATUS
  98312. +gckVGHARDWARE_QueryPowerManagementState(
  98313. + IN gckVGHARDWARE Hardware,
  98314. + OUT gceCHIPPOWERSTATE* State
  98315. + )
  98316. +{
  98317. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  98318. +
  98319. + /* Verify the arguments. */
  98320. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  98321. + gcmkVERIFY_ARGUMENT(State != gcvNULL);
  98322. +
  98323. + /* Return the statue. */
  98324. + *State = Hardware->chipPowerState;
  98325. +
  98326. + /* Success. */
  98327. + gcmkFOOTER_ARG("*State=%d", *State);
  98328. + return gcvSTATUS_OK;
  98329. +}
  98330. +
  98331. +/*******************************************************************************
  98332. +**
  98333. +** gckVGHARDWARE_SetPowerManagement
  98334. +**
  98335. +** Configure GPU power management function.
  98336. +** Only used in driver initialization stage.
  98337. +**
  98338. +** INPUT:
  98339. +**
  98340. +** gckVGHARDWARE Harwdare
  98341. +** Pointer to an gckHARDWARE object.
  98342. +**
  98343. +** gctBOOL PowerManagement
  98344. +** Power Mangement State.
  98345. +**
  98346. +*/
  98347. +gceSTATUS
  98348. +gckVGHARDWARE_SetPowerManagement(
  98349. + IN gckVGHARDWARE Hardware,
  98350. + IN gctBOOL PowerManagement
  98351. + )
  98352. +{
  98353. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  98354. +
  98355. + /* Verify the arguments. */
  98356. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  98357. +
  98358. + Hardware->powerManagement = PowerManagement;
  98359. +
  98360. + /* Success. */
  98361. + gcmkFOOTER_NO();
  98362. + return gcvSTATUS_OK;
  98363. +}
  98364. +
  98365. +gceSTATUS
  98366. +gckVGHARDWARE_SetPowerOffTimeout(
  98367. + IN gckVGHARDWARE Hardware,
  98368. + IN gctUINT32 Timeout
  98369. + )
  98370. +{
  98371. + gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
  98372. +
  98373. +#if gcdPOWEROFF_TIMEOUT
  98374. + Hardware->powerOffTimeout = Timeout;
  98375. +#endif
  98376. +
  98377. + gcmkFOOTER_NO();
  98378. + return gcvSTATUS_OK;
  98379. +}
  98380. +
  98381. +
  98382. +gceSTATUS
  98383. +gckVGHARDWARE_QueryPowerOffTimeout(
  98384. + IN gckVGHARDWARE Hardware,
  98385. + OUT gctUINT32* Timeout
  98386. + )
  98387. +{
  98388. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  98389. +
  98390. +#if gcdPOWEROFF_TIMEOUT
  98391. + *Timeout = Hardware->powerOffTimeout;
  98392. +#endif
  98393. +
  98394. + gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
  98395. + return gcvSTATUS_OK;
  98396. +}
  98397. +
  98398. +gceSTATUS
  98399. +gckVGHARDWARE_QueryIdle(
  98400. + IN gckVGHARDWARE Hardware,
  98401. + OUT gctBOOL_PTR IsIdle
  98402. + )
  98403. +{
  98404. + gceSTATUS status;
  98405. + gctUINT32 idle;
  98406. +
  98407. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  98408. +
  98409. + /* Verify the arguments. */
  98410. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  98411. + gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
  98412. +
  98413. + /* We are idle when the power is not ON. */
  98414. + if (Hardware->chipPowerState != gcvPOWER_ON)
  98415. + {
  98416. + *IsIdle = gcvTRUE;
  98417. + }
  98418. +
  98419. + else
  98420. + {
  98421. + /* Read idle register. */
  98422. + gcmkONERROR(
  98423. + gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, &idle));
  98424. +
  98425. + /* Pipe must be idle. */
  98426. + 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)
  98427. + || ((((((gctUINT32) (idle)) >> (0 ? 8:8)) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) ) != 1)
  98428. + || ((((((gctUINT32) (idle)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ) != 1)
  98429. + || ((((((gctUINT32) (idle)) >> (0 ? 10:10)) & ((gctUINT32) ((((1 ? 10:10) - (0 ? 10:10) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 10:10) - (0 ? 10:10) + 1)))))) ) != 1)
  98430. + || ((((((gctUINT32) (idle)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ) != 1)
  98431. + )
  98432. + {
  98433. + /* Something is busy. */
  98434. + *IsIdle = gcvFALSE;
  98435. + }
  98436. +
  98437. + else
  98438. + {
  98439. + *IsIdle = gcvTRUE;
  98440. + }
  98441. + }
  98442. +
  98443. + /* Success. */
  98444. + gcmkFOOTER_NO();
  98445. + return gcvSTATUS_OK;
  98446. +
  98447. +OnError:
  98448. + /* Return the status. */
  98449. + gcmkFOOTER();
  98450. + return status;
  98451. +}
  98452. +#endif /* gcdENABLE_VG */
  98453. +
  98454. diff -Nur linux-3.14.17/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
  98455. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h 1970-01-01 01:00:00.000000000 +0100
  98456. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h 2014-09-11 18:06:03.078042276 +0200
  98457. @@ -0,0 +1,75 @@
  98458. +/****************************************************************************
  98459. +*
  98460. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  98461. +*
  98462. +* This program is free software; you can redistribute it and/or modify
  98463. +* it under the terms of the GNU General Public License as published by
  98464. +* the Free Software Foundation; either version 2 of the license, or
  98465. +* (at your option) any later version.
  98466. +*
  98467. +* This program is distributed in the hope that it will be useful,
  98468. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  98469. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  98470. +* GNU General Public License for more details.
  98471. +*
  98472. +* You should have received a copy of the GNU General Public License
  98473. +* along with this program; if not write to the Free Software
  98474. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  98475. +*
  98476. +*****************************************************************************/
  98477. +
  98478. +
  98479. +#ifndef __gc_hal_kernel_hardware_vg_h_
  98480. +#define __gc_hal_kernel_hardware_vg_h_
  98481. +
  98482. +/* gckHARDWARE object. */
  98483. +struct _gckVGHARDWARE
  98484. +{
  98485. + /* Object. */
  98486. + gcsOBJECT object;
  98487. +
  98488. + /* Pointer to gckKERNEL object. */
  98489. + gckVGKERNEL kernel;
  98490. +
  98491. + /* Pointer to gckOS object. */
  98492. + gckOS os;
  98493. +
  98494. + /* Chip characteristics. */
  98495. + gceCHIPMODEL chipModel;
  98496. + gctUINT32 chipRevision;
  98497. + gctUINT32 chipFeatures;
  98498. + gctUINT32 chipMinorFeatures;
  98499. + gctUINT32 chipMinorFeatures2;
  98500. + gctBOOL allowFastClear;
  98501. +
  98502. + /* Features. */
  98503. + gctBOOL fe20;
  98504. + gctBOOL vg20;
  98505. + gctBOOL vg21;
  98506. +
  98507. + /* Event mask. */
  98508. + gctUINT32 eventMask;
  98509. +
  98510. + gctBOOL clockState;
  98511. + gctBOOL powerState;
  98512. + gctPOINTER powerMutex;
  98513. + gctUINT32 powerProcess;
  98514. + gctUINT32 powerThread;
  98515. + gceCHIPPOWERSTATE chipPowerState;
  98516. + gceCHIPPOWERSTATE chipPowerStateGlobal;
  98517. + gctISRMANAGERFUNC startIsr;
  98518. + gctISRMANAGERFUNC stopIsr;
  98519. + gctPOINTER isrContext;
  98520. + gctPOINTER pageTableDirty;
  98521. +
  98522. +#if gcdPOWEROFF_TIMEOUT
  98523. + gctUINT32 powerOffTime;
  98524. + gctUINT32 powerOffTimeout;
  98525. + gctPOINTER powerOffTimer;
  98526. +#endif
  98527. +
  98528. + gctBOOL powerManagement;
  98529. +};
  98530. +
  98531. +#endif /* __gc_hal_kernel_hardware_h_ */
  98532. +
  98533. diff -Nur linux-3.14.17/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
  98534. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c 1970-01-01 01:00:00.000000000 +0100
  98535. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c 2014-09-11 18:06:03.082042291 +0200
  98536. @@ -0,0 +1,1735 @@
  98537. +/****************************************************************************
  98538. +*
  98539. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  98540. +*
  98541. +* This program is free software; you can redistribute it and/or modify
  98542. +* it under the terms of the GNU General Public License as published by
  98543. +* the Free Software Foundation; either version 2 of the license, or
  98544. +* (at your option) any later version.
  98545. +*
  98546. +* This program is distributed in the hope that it will be useful,
  98547. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  98548. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  98549. +* GNU General Public License for more details.
  98550. +*
  98551. +* You should have received a copy of the GNU General Public License
  98552. +* along with this program; if not write to the Free Software
  98553. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  98554. +*
  98555. +*****************************************************************************/
  98556. +
  98557. +
  98558. +#include "gc_hal.h"
  98559. +#include "gc_hal_kernel.h"
  98560. +#include "gc_hal_kernel_context.h"
  98561. +#include "gc_hal_kernel_buffer.h"
  98562. +
  98563. +/******************************************************************************\
  98564. +******************************** Debugging Macro *******************************
  98565. +\******************************************************************************/
  98566. +
  98567. +/* Zone used for header/footer. */
  98568. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  98569. +
  98570. +
  98571. +/******************************************************************************\
  98572. +************************** Context State Buffer Helpers ************************
  98573. +\******************************************************************************/
  98574. +
  98575. +#define _STATE(reg) \
  98576. + _State(\
  98577. + Context, index, \
  98578. + reg ## _Address >> 2, \
  98579. + reg ## _ResetValue, \
  98580. + reg ## _Count, \
  98581. + gcvFALSE, gcvFALSE \
  98582. + )
  98583. +
  98584. +#define _STATE_COUNT(reg, count) \
  98585. + _State(\
  98586. + Context, index, \
  98587. + reg ## _Address >> 2, \
  98588. + reg ## _ResetValue, \
  98589. + count, \
  98590. + gcvFALSE, gcvFALSE \
  98591. + )
  98592. +
  98593. +#define _STATE_COUNT_OFFSET(reg, offset, count) \
  98594. + _State(\
  98595. + Context, index, \
  98596. + (reg ## _Address >> 2) + offset, \
  98597. + reg ## _ResetValue, \
  98598. + count, \
  98599. + gcvFALSE, gcvFALSE \
  98600. + )
  98601. +
  98602. +#define _STATE_MIRROR_COUNT(reg, mirror, count) \
  98603. + _StateMirror(\
  98604. + Context, \
  98605. + reg ## _Address >> 2, \
  98606. + count, \
  98607. + mirror ## _Address >> 2 \
  98608. + )
  98609. +
  98610. +#define _STATE_HINT(reg) \
  98611. + _State(\
  98612. + Context, index, \
  98613. + reg ## _Address >> 2, \
  98614. + reg ## _ResetValue, \
  98615. + reg ## _Count, \
  98616. + gcvFALSE, gcvTRUE \
  98617. + )
  98618. +
  98619. +#define _STATE_HINT_BLOCK(reg, block, count) \
  98620. + _State(\
  98621. + Context, index, \
  98622. + (reg ## _Address >> 2) + (block << reg ## _BLK), \
  98623. + reg ## _ResetValue, \
  98624. + count, \
  98625. + gcvFALSE, gcvTRUE \
  98626. + )
  98627. +
  98628. +#define _STATE_X(reg) \
  98629. + _State(\
  98630. + Context, index, \
  98631. + reg ## _Address >> 2, \
  98632. + reg ## _ResetValue, \
  98633. + reg ## _Count, \
  98634. + gcvTRUE, gcvFALSE \
  98635. + )
  98636. +
  98637. +#define _CLOSE_RANGE() \
  98638. + _TerminateStateBlock(Context, index)
  98639. +
  98640. +#define _ENABLE(reg, field) \
  98641. + do \
  98642. + { \
  98643. + if (gcmVERIFYFIELDVALUE(data, reg, MASK_ ## field, ENABLED)) \
  98644. + { \
  98645. + enable |= gcmFIELDMASK(reg, field); \
  98646. + } \
  98647. + } \
  98648. + while (gcvFALSE)
  98649. +
  98650. +#define _BLOCK_COUNT(reg) \
  98651. + ((reg ## _Count) >> (reg ## _BLK))
  98652. +
  98653. +
  98654. +/******************************************************************************\
  98655. +*********************** Support Functions and Definitions **********************
  98656. +\******************************************************************************/
  98657. +
  98658. +#define gcdSTATE_MASK \
  98659. + (((((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))))
  98660. +
  98661. +#if !defined(VIVANTE_NO_3D)
  98662. +static gctSIZE_T
  98663. +_TerminateStateBlock(
  98664. + IN gckCONTEXT Context,
  98665. + IN gctSIZE_T Index
  98666. + )
  98667. +{
  98668. + gctUINT32_PTR buffer;
  98669. + gctSIZE_T align;
  98670. +
  98671. + /* Determine if we need alignment. */
  98672. + align = (Index & 1) ? 1 : 0;
  98673. +
  98674. + /* Address correct index. */
  98675. + buffer = (Context->buffer == gcvNULL)
  98676. + ? gcvNULL
  98677. + : Context->buffer->logical;
  98678. +
  98679. + /* Flush the current state block; make sure no pairing with the states
  98680. + to follow happens. */
  98681. + if (align && (buffer != gcvNULL))
  98682. + {
  98683. + buffer[Index] = 0xDEADDEAD;
  98684. + }
  98685. +
  98686. + /* Reset last address. */
  98687. + Context->lastAddress = ~0U;
  98688. +
  98689. + /* Return alignment requirement. */
  98690. + return align;
  98691. +}
  98692. +#endif
  98693. +
  98694. +
  98695. +static gctSIZE_T
  98696. +_FlushPipe(
  98697. + IN gckCONTEXT Context,
  98698. + IN gctSIZE_T Index,
  98699. + IN gcePIPE_SELECT Pipe
  98700. + )
  98701. +{
  98702. + if (Context->buffer != gcvNULL)
  98703. + {
  98704. + gctUINT32_PTR buffer;
  98705. +
  98706. + /* Address correct index. */
  98707. + buffer = Context->buffer->logical + Index;
  98708. +
  98709. + /* Flush the current pipe. */
  98710. + *buffer++
  98711. + = ((((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)))
  98712. + | ((((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)))
  98713. + | ((((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)));
  98714. +
  98715. + *buffer++
  98716. + = (Pipe == gcvPIPE_2D)
  98717. + ? ((((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)))
  98718. + : ((((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)))
  98719. + | ((((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)))
  98720. + | ((((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)))
  98721. + | ((((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)));
  98722. +
  98723. + /* Semaphore from FE to PE. */
  98724. + *buffer++
  98725. + = ((((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)))
  98726. + | ((((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)))
  98727. + | ((((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)));
  98728. +
  98729. + *buffer++
  98730. + = ((((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)))
  98731. + | ((((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)));
  98732. +
  98733. + /* Stall from FE to PE. */
  98734. + *buffer++
  98735. + = ((((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)));
  98736. +
  98737. + *buffer
  98738. + = ((((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)))
  98739. + | ((((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)));
  98740. + }
  98741. +
  98742. + /* Flushing 3D pipe takes 6 slots. */
  98743. + return 6;
  98744. +}
  98745. +
  98746. +#if !defined(VIVANTE_NO_3D)
  98747. +static gctSIZE_T
  98748. +_SemaphoreStall(
  98749. + IN gckCONTEXT Context,
  98750. + IN gctSIZE_T Index
  98751. + )
  98752. +{
  98753. + if (Context->buffer != gcvNULL)
  98754. + {
  98755. + gctUINT32_PTR buffer;
  98756. +
  98757. + /* Address correct index. */
  98758. + buffer = Context->buffer->logical + Index;
  98759. +
  98760. + /* Semaphore from FE to PE. */
  98761. + *buffer++
  98762. + = ((((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)))
  98763. + | ((((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)))
  98764. + | ((((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)));
  98765. +
  98766. + *buffer++
  98767. + = ((((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)))
  98768. + | ((((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)));
  98769. +
  98770. + /* Stall from FE to PE. */
  98771. + *buffer++
  98772. + = ((((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)));
  98773. +
  98774. + *buffer
  98775. + = ((((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)))
  98776. + | ((((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)));
  98777. + }
  98778. +
  98779. + /* Semaphore/stall takes 4 slots. */
  98780. + return 4;
  98781. +}
  98782. +#endif
  98783. +
  98784. +static gctSIZE_T
  98785. +_SwitchPipe(
  98786. + IN gckCONTEXT Context,
  98787. + IN gctSIZE_T Index,
  98788. + IN gcePIPE_SELECT Pipe
  98789. + )
  98790. +{
  98791. + if (Context->buffer != gcvNULL)
  98792. + {
  98793. + gctUINT32_PTR buffer;
  98794. +
  98795. + /* Address correct index. */
  98796. + buffer = Context->buffer->logical + Index;
  98797. +
  98798. + /* LoadState(AQPipeSelect, 1), pipe. */
  98799. + *buffer++
  98800. + = ((((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)))
  98801. + | ((((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)))
  98802. + | ((((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)));
  98803. +
  98804. + *buffer
  98805. + = (Pipe == gcvPIPE_2D)
  98806. + ? 0x1
  98807. + : 0x0;
  98808. + }
  98809. +
  98810. + return 2;
  98811. +}
  98812. +
  98813. +#if !defined(VIVANTE_NO_3D)
  98814. +static gctSIZE_T
  98815. +_State(
  98816. + IN gckCONTEXT Context,
  98817. + IN gctSIZE_T Index,
  98818. + IN gctUINT32 Address,
  98819. + IN gctUINT32 Value,
  98820. + IN gctSIZE_T Size,
  98821. + IN gctBOOL FixedPoint,
  98822. + IN gctBOOL Hinted
  98823. + )
  98824. +{
  98825. + gctUINT32_PTR buffer;
  98826. + gctSIZE_T align, i;
  98827. +
  98828. + /* Determine if we need alignment. */
  98829. + align = (Index & 1) ? 1 : 0;
  98830. +
  98831. + /* Address correct index. */
  98832. + buffer = (Context->buffer == gcvNULL)
  98833. + ? gcvNULL
  98834. + : Context->buffer->logical;
  98835. +
  98836. + if ((buffer == gcvNULL) && (Address + Size > Context->stateCount))
  98837. + {
  98838. + /* Determine maximum state. */
  98839. + Context->stateCount = Address + Size;
  98840. + }
  98841. +
  98842. + /* Do we need a new entry? */
  98843. + if ((Address != Context->lastAddress) || (FixedPoint != Context->lastFixed))
  98844. + {
  98845. + if (buffer != gcvNULL)
  98846. + {
  98847. + if (align)
  98848. + {
  98849. + /* Add filler. */
  98850. + buffer[Index++] = 0xDEADDEAD;
  98851. + }
  98852. +
  98853. + /* LoadState(Address, Count). */
  98854. + gcmkASSERT((Index & 1) == 0);
  98855. +
  98856. + if (FixedPoint)
  98857. + {
  98858. + buffer[Index]
  98859. + = ((((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)))
  98860. + | ((((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)))
  98861. + | ((((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)))
  98862. + | ((((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)));
  98863. + }
  98864. + else
  98865. + {
  98866. + buffer[Index]
  98867. + = ((((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)))
  98868. + | ((((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)))
  98869. + | ((((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)))
  98870. + | ((((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)));
  98871. + }
  98872. +
  98873. + /* Walk all the states. */
  98874. + for (i = 0; i < Size; i += 1)
  98875. + {
  98876. + /* Set state to uninitialized value. */
  98877. + buffer[Index + 1 + i] = Value;
  98878. +
  98879. + /* Set index in state mapping table. */
  98880. + Context->map[Address + i].index = Index + 1 + i;
  98881. +
  98882. +#if gcdSECURE_USER
  98883. + /* Save hint. */
  98884. + if (Context->hint != gcvNULL)
  98885. + {
  98886. + Context->hint[Address + i] = Hinted;
  98887. + }
  98888. +#endif
  98889. + }
  98890. + }
  98891. +
  98892. + /* Save information for this LoadState. */
  98893. + Context->lastIndex = Index;
  98894. + Context->lastAddress = Address + Size;
  98895. + Context->lastSize = Size;
  98896. + Context->lastFixed = FixedPoint;
  98897. +
  98898. + /* Return size for load state. */
  98899. + return align + 1 + Size;
  98900. + }
  98901. +
  98902. + /* Append this state to the previous one. */
  98903. + if (buffer != gcvNULL)
  98904. + {
  98905. + /* Update last load state. */
  98906. + buffer[Context->lastIndex] =
  98907. + ((((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)));
  98908. +
  98909. + /* Walk all the states. */
  98910. + for (i = 0; i < Size; i += 1)
  98911. + {
  98912. + /* Set state to uninitialized value. */
  98913. + buffer[Index + i] = Value;
  98914. +
  98915. + /* Set index in state mapping table. */
  98916. + Context->map[Address + i].index = Index + i;
  98917. +
  98918. +#if gcdSECURE_USER
  98919. + /* Save hint. */
  98920. + if (Context->hint != gcvNULL)
  98921. + {
  98922. + Context->hint[Address + i] = Hinted;
  98923. + }
  98924. +#endif
  98925. + }
  98926. + }
  98927. +
  98928. + /* Update last address and size. */
  98929. + Context->lastAddress += Size;
  98930. + Context->lastSize += Size;
  98931. +
  98932. + /* Return number of slots required. */
  98933. + return Size;
  98934. +}
  98935. +
  98936. +static gctSIZE_T
  98937. +_StateMirror(
  98938. + IN gckCONTEXT Context,
  98939. + IN gctUINT32 Address,
  98940. + IN gctSIZE_T Size,
  98941. + IN gctUINT32 AddressMirror
  98942. + )
  98943. +{
  98944. + gctSIZE_T i;
  98945. +
  98946. + /* Process when buffer is set. */
  98947. + if (Context->buffer != gcvNULL)
  98948. + {
  98949. + /* Walk all states. */
  98950. + for (i = 0; i < Size; i++)
  98951. + {
  98952. + /* Copy the mapping address. */
  98953. + Context->map[Address + i].index =
  98954. + Context->map[AddressMirror + i].index;
  98955. + }
  98956. + }
  98957. +
  98958. + /* Return the number of required maps. */
  98959. + return Size;
  98960. +}
  98961. +#endif
  98962. +
  98963. +static gceSTATUS
  98964. +_InitializeContextBuffer(
  98965. + IN gckCONTEXT Context
  98966. + )
  98967. +{
  98968. + gctUINT32_PTR buffer;
  98969. + gctSIZE_T index;
  98970. +
  98971. +#if !defined(VIVANTE_NO_3D)
  98972. + gctUINT i;
  98973. + gctUINT vertexUniforms, fragmentUniforms;
  98974. + gctUINT fe2vsCount;
  98975. + gctBOOL halti0;
  98976. +#endif
  98977. +
  98978. + /* Reset the buffer index. */
  98979. + index = 0;
  98980. +
  98981. + /* Reset the last state address. */
  98982. + Context->lastAddress = ~0U;
  98983. +
  98984. + /* Get the buffer pointer. */
  98985. + buffer = (Context->buffer == gcvNULL)
  98986. + ? gcvNULL
  98987. + : Context->buffer->logical;
  98988. +
  98989. +
  98990. + /**************************************************************************/
  98991. + /* Build 2D states. *******************************************************/
  98992. +
  98993. +
  98994. +#if !defined(VIVANTE_NO_3D)
  98995. + /**************************************************************************/
  98996. + /* Build 3D states. *******************************************************/
  98997. + 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)))))) );
  98998. +
  98999. + /* Query shader support. */
  99000. + gcmkVERIFY_OK(gckHARDWARE_QueryShaderCaps(
  99001. + Context->hardware, &vertexUniforms, &fragmentUniforms, gcvNULL));
  99002. +
  99003. + /* Store the 3D entry index. */
  99004. + Context->entryOffset3D = index * gcmSIZEOF(gctUINT32);
  99005. +
  99006. + /* Flush 2D pipe. */
  99007. + index += _FlushPipe(Context, index, gcvPIPE_2D);
  99008. +
  99009. + /* Switch to 3D pipe. */
  99010. + index += _SwitchPipe(Context, index, gcvPIPE_3D);
  99011. +
  99012. + /* Current context pointer. */
  99013. +#if gcdDEBUG
  99014. + index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99015. +#endif
  99016. +
  99017. + index += _FlushPipe(Context, index, gcvPIPE_3D);
  99018. +
  99019. + /* Global states. */
  99020. + index += _State(Context, index, 0x03814 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
  99021. + index += _State(Context, index, 0x03818 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99022. + index += _State(Context, index, 0x0381C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99023. + index += _State(Context, index, 0x03820 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99024. + index += _State(Context, index, 0x03828 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99025. + index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99026. + index += _State(Context, index, 0x03834 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99027. + index += _State(Context, index, 0x03838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99028. + index += _State(Context, index, 0x0384C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99029. +
  99030. + /* Front End states. */
  99031. + fe2vsCount = 12;
  99032. + 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)))))) ))
  99033. + {
  99034. + fe2vsCount = 16;
  99035. + }
  99036. + index += _State(Context, index, 0x00600 >> 2, 0x00000000, fe2vsCount, gcvFALSE, gcvFALSE);
  99037. + index += _CLOSE_RANGE();
  99038. +
  99039. + index += _State(Context, index, 0x00644 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99040. + index += _State(Context, index, 0x00648 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99041. + index += _State(Context, index, 0x0064C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99042. + index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99043. + index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  99044. + index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  99045. + index += _State(Context, index, 0x00670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99046. + index += _State(Context, index, 0x00678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99047. + index += _State(Context, index, 0x0067C >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  99048. + index += _State(Context, index, 0x006C0 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  99049. + index += _State(Context, index, 0x00700 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  99050. + index += _State(Context, index, 0x00740 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  99051. + index += _State(Context, index, 0x00780 >> 2, 0x3F800000, 16, gcvFALSE, gcvFALSE);
  99052. +
  99053. + /* Vertex Shader states. */
  99054. + index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99055. + index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99056. + index += _State(Context, index, 0x00808 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99057. + index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99058. + index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  99059. + index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  99060. + index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99061. + index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99062. + if (Context->hardware->identity.instructionCount <= 256)
  99063. + {
  99064. + index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
  99065. + }
  99066. +
  99067. + index += _CLOSE_RANGE();
  99068. + index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
  99069. +
  99070. + /* Primitive Assembly states. */
  99071. + index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99072. + index += _State(Context, index, 0x00A04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99073. + index += _State(Context, index, 0x00A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99074. + index += _State(Context, index, 0x00A0C >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99075. + index += _State(Context, index, 0x00A10 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99076. + index += _State(Context, index, 0x00A14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99077. + index += _State(Context, index, 0x00A18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99078. + index += _State(Context, index, 0x00A1C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99079. + index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99080. + index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99081. + index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99082. + index += _State(Context, index, 0x00A40 >> 2, 0x00000000, 10, gcvFALSE, gcvFALSE);
  99083. + index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99084. + index += _State(Context, index, 0x00A38 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99085. + index += _State(Context, index, 0x00A3C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99086. + index += _State(Context, index, 0x00A80 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99087. + index += _State(Context, index, 0x00A84 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99088. + index += _State(Context, index, 0x00A8C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99089. +
  99090. + /* Setup states. */
  99091. + index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99092. + index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99093. + index += _State(Context, index, 0x00C08 >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
  99094. + index += _State(Context, index, 0x00C0C >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
  99095. + index += _State(Context, index, 0x00C10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99096. + index += _State(Context, index, 0x00C14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99097. + index += _State(Context, index, 0x00C18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99098. + index += _State(Context, index, 0x00C1C >> 2, 0x42000000, 1, gcvFALSE, gcvFALSE);
  99099. + index += _State(Context, index, 0x00C20 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99100. + index += _State(Context, index, 0x00C24 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
  99101. +
  99102. + /* Raster states. */
  99103. + index += _State(Context, index, 0x00E00 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
  99104. + index += _State(Context, index, 0x00E10 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  99105. + index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99106. + index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
  99107. + index += _State(Context, index, 0x00E08 >> 2, 0x00000031, 1, gcvFALSE, gcvFALSE);
  99108. +
  99109. + /* Pixel Shader states. */
  99110. + index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99111. + index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99112. + index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99113. + index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99114. + index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99115. + index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
  99116. + if (Context->hardware->identity.instructionCount <= 256)
  99117. + {
  99118. + index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
  99119. + }
  99120. +
  99121. + index += _CLOSE_RANGE();
  99122. + index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
  99123. +
  99124. + /* Texture states. */
  99125. + index += _State(Context, index, 0x02000 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99126. + index += _State(Context, index, 0x02040 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99127. + index += _State(Context, index, 0x02080 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99128. + index += _State(Context, index, 0x020C0 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99129. + index += _State(Context, index, 0x02100 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99130. + index += _State(Context, index, 0x02140 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99131. + index += _State(Context, index, 0x02180 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99132. + index += _State(Context, index, 0x021C0 >> 2, 0x00321000, 12, gcvFALSE, gcvFALSE);
  99133. + index += _State(Context, index, 0x02200 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99134. + index += _State(Context, index, 0x02240 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
  99135. + index += _State(Context, index, (0x02400 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99136. + index += _State(Context, index, (0x02440 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99137. + index += _State(Context, index, (0x02480 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99138. + index += _State(Context, index, (0x024C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99139. + index += _State(Context, index, (0x02500 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99140. + index += _State(Context, index, (0x02540 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99141. + index += _State(Context, index, (0x02580 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99142. + index += _State(Context, index, (0x025C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99143. + index += _State(Context, index, (0x02600 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99144. + index += _State(Context, index, (0x02640 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99145. + index += _State(Context, index, (0x02680 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99146. + index += _State(Context, index, (0x026C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99147. + index += _State(Context, index, (0x02700 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99148. + index += _State(Context, index, (0x02740 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
  99149. + index += _CLOSE_RANGE();
  99150. +
  99151. + 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)))))) ))
  99152. + {
  99153. + gctUINT texBlockCount;
  99154. +
  99155. + /* New texture block. */
  99156. + index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99157. + index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99158. + index += _State(Context, index, 0x10100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99159. + index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99160. + index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99161. + index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99162. + for (i = 0; i < 256 / 16; i += 1)
  99163. + {
  99164. + index += _State(Context, index, (0x02C00 >> 2) + i * 16, 0x00000000, 14, gcvFALSE, gcvFALSE);
  99165. + }
  99166. + index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99167. + index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
  99168. + index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99169. + index += _State(Context, index, 0x10480 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
  99170. +
  99171. + 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)))))) ))
  99172. + {
  99173. + index += _State(Context, index, 0x12000 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
  99174. + index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
  99175. + }
  99176. +
  99177. + if ((Context->hardware->identity.chipModel == gcv2000)
  99178. + && (Context->hardware->identity.chipRevision == 0x5108))
  99179. + {
  99180. + texBlockCount = 12;
  99181. + }
  99182. + else
  99183. + {
  99184. + texBlockCount = ((512) >> (4));
  99185. + }
  99186. + for (i = 0; i < texBlockCount; i += 1)
  99187. + {
  99188. + index += _State(Context, index, (0x10800 >> 2) + (i << 4), 0x00000000, 14, gcvFALSE, gcvTRUE);
  99189. + }
  99190. + }
  99191. +
  99192. + /* YUV. */
  99193. + index += _State(Context, index, 0x01678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99194. + index += _State(Context, index, 0x0167C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99195. + index += _State(Context, index, 0x01680 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99196. + index += _State(Context, index, 0x01684 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99197. + index += _State(Context, index, 0x01688 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99198. + index += _State(Context, index, 0x0168C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99199. + index += _State(Context, index, 0x01690 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99200. + index += _State(Context, index, 0x01694 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99201. + index += _State(Context, index, 0x01698 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99202. + index += _State(Context, index, 0x0169C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99203. + index += _CLOSE_RANGE();
  99204. +
  99205. + /* Thread walker states. */
  99206. + index += _State(Context, index, 0x00900 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99207. + index += _State(Context, index, 0x00904 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99208. + index += _State(Context, index, 0x00908 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99209. + index += _State(Context, index, 0x0090C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99210. + index += _State(Context, index, 0x00910 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99211. + index += _State(Context, index, 0x00914 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99212. + index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99213. + index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99214. + index += _State(Context, index, 0x00924 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99215. + index += _CLOSE_RANGE();
  99216. +
  99217. + if (Context->hardware->identity.instructionCount > 1024)
  99218. + {
  99219. + /* New Shader instruction memory. */
  99220. + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99221. + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
  99222. + index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99223. + index += _CLOSE_RANGE();
  99224. +
  99225. + for (i = 0;
  99226. + i < Context->hardware->identity.instructionCount << 2;
  99227. + i += 256 << 2
  99228. + )
  99229. + {
  99230. + index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
  99231. + index += _CLOSE_RANGE();
  99232. + }
  99233. + }
  99234. + else if (Context->hardware->identity.instructionCount > 256)
  99235. + {
  99236. + /* New Shader instruction memory. */
  99237. + index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99238. + index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
  99239. + index += _CLOSE_RANGE();
  99240. +
  99241. + /* VX instruction memory. */
  99242. + for (i = 0;
  99243. + i < Context->hardware->identity.instructionCount << 2;
  99244. + i += 256 << 2
  99245. + )
  99246. + {
  99247. + index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
  99248. + index += _CLOSE_RANGE();
  99249. + }
  99250. +
  99251. + _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2);
  99252. + }
  99253. +
  99254. + /* Store the index of the "XD" entry. */
  99255. + Context->entryOffsetXDFrom3D = index * gcmSIZEOF(gctUINT32);
  99256. +
  99257. +
  99258. + /* Pixel Engine states. */
  99259. + index += _State(Context, index, 0x01400 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99260. + index += _State(Context, index, 0x01404 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99261. + index += _State(Context, index, 0x01408 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99262. + index += _State(Context, index, 0x0140C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99263. + index += _State(Context, index, 0x01414 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99264. + index += _State(Context, index, 0x01418 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99265. + index += _State(Context, index, 0x0141C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99266. + index += _State(Context, index, 0x01420 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99267. + index += _State(Context, index, 0x01424 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99268. + index += _State(Context, index, 0x01428 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99269. + index += _State(Context, index, 0x0142C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99270. + index += _State(Context, index, 0x01434 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99271. + index += _State(Context, index, 0x01454 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99272. + index += _State(Context, index, 0x01458 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99273. + index += _State(Context, index, 0x0145C >> 2, 0x00000010, 1, gcvFALSE, gcvFALSE);
  99274. + index += _State(Context, index, 0x014A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99275. + index += _State(Context, index, 0x014A8 >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  99276. + index += _State(Context, index, 0x014AC >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
  99277. + index += _State(Context, index, 0x014B0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99278. + index += _State(Context, index, 0x014B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99279. + index += _State(Context, index, 0x014A4 >> 2, 0x000E400C, 1, gcvFALSE, gcvFALSE);
  99280. + index += _State(Context, index, 0x01580 >> 2, 0x00000000, 3, gcvFALSE, gcvFALSE);
  99281. + index += _State(Context, index, 0x014B8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99282. +
  99283. + /* Composition states. */
  99284. + index += _State(Context, index, 0x03008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99285. +
  99286. + if (Context->hardware->identity.pixelPipes == 1)
  99287. + {
  99288. + index += _State(Context, index, 0x01460 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  99289. +
  99290. + index += _State(Context, index, 0x01430 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99291. + index += _State(Context, index, 0x01410 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99292. + }
  99293. + else
  99294. + {
  99295. + index += _State(Context, index, (0x01460 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  99296. +
  99297. + for (i = 0; i < 2; i++)
  99298. + {
  99299. + index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  99300. + }
  99301. + }
  99302. +
  99303. + if (Context->hardware->identity.pixelPipes > 1 || halti0)
  99304. + {
  99305. + index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  99306. + }
  99307. +
  99308. + /* Resolve states. */
  99309. + index += _State(Context, index, 0x01604 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99310. + index += _State(Context, index, 0x01608 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99311. + index += _State(Context, index, 0x0160C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99312. + index += _State(Context, index, 0x01610 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99313. + index += _State(Context, index, 0x01614 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99314. + index += _State(Context, index, 0x01620 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99315. + index += _State(Context, index, 0x01630 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
  99316. + index += _State(Context, index, 0x01640 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
  99317. + index += _State(Context, index, 0x0163C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99318. + index += _State(Context, index, 0x016A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99319. + index += _State(Context, index, 0x016B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99320. + index += _CLOSE_RANGE();
  99321. +
  99322. + if (Context->hardware->identity.pixelPipes > 1)
  99323. + {
  99324. + index += _State(Context, index, (0x016C0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  99325. +
  99326. + index += _State(Context, index, (0x016E0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
  99327. +
  99328. + index += _State(Context, index, 0x01700 >> 2, 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvFALSE);
  99329. + }
  99330. +
  99331. + /* Tile status. */
  99332. + index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE);
  99333. +
  99334. + index += _CLOSE_RANGE();
  99335. + index += _State(Context, index, 0x01658 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99336. + index += _State(Context, index, 0x0165C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99337. + index += _State(Context, index, 0x01660 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99338. + index += _State(Context, index, 0x01664 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99339. + index += _State(Context, index, 0x01668 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99340. + index += _State(Context, index, 0x0166C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99341. + index += _State(Context, index, 0x01670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99342. + index += _State(Context, index, 0x01674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99343. + index += _State(Context, index, 0x016A4 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
  99344. + index += _State(Context, index, 0x016AC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99345. + index += _State(Context, index, 0x016A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
  99346. + index += _State(Context, index, 0x01720 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  99347. + index += _State(Context, index, 0x01740 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
  99348. + index += _State(Context, index, 0x01760 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
  99349. + index += _CLOSE_RANGE();
  99350. +
  99351. + /* Semaphore/stall. */
  99352. + index += _SemaphoreStall(Context, index);
  99353. +#endif
  99354. +
  99355. + /**************************************************************************/
  99356. + /* Link to another address. ***********************************************/
  99357. +
  99358. + Context->linkIndex3D = index;
  99359. +
  99360. + if (buffer != gcvNULL)
  99361. + {
  99362. + buffer[index + 0]
  99363. + = ((((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)))
  99364. + | ((((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)));
  99365. +
  99366. + buffer[index + 1]
  99367. + = 0;
  99368. + }
  99369. +
  99370. + index += 2;
  99371. +
  99372. + /* Store the end of the context buffer. */
  99373. + Context->bufferSize = index * gcmSIZEOF(gctUINT32);
  99374. +
  99375. +
  99376. + /**************************************************************************/
  99377. + /* Pipe switch for the case where neither 2D nor 3D are used. *************/
  99378. +
  99379. + /* Store the 3D entry index. */
  99380. + Context->entryOffsetXDFrom2D = index * gcmSIZEOF(gctUINT32);
  99381. +
  99382. + /* Flush 2D pipe. */
  99383. + index += _FlushPipe(Context, index, gcvPIPE_2D);
  99384. +
  99385. + /* Switch to 3D pipe. */
  99386. + index += _SwitchPipe(Context, index, gcvPIPE_3D);
  99387. +
  99388. + /* Store the location of the link. */
  99389. + Context->linkIndexXD = index;
  99390. +
  99391. + if (buffer != gcvNULL)
  99392. + {
  99393. + buffer[index + 0]
  99394. + = ((((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)))
  99395. + | ((((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)));
  99396. +
  99397. + buffer[index + 1]
  99398. + = 0;
  99399. + }
  99400. +
  99401. + index += 2;
  99402. +
  99403. +
  99404. + /**************************************************************************/
  99405. + /* Save size for buffer. **************************************************/
  99406. +
  99407. + Context->totalSize = index * gcmSIZEOF(gctUINT32);
  99408. +
  99409. +
  99410. + /* Success. */
  99411. + return gcvSTATUS_OK;
  99412. +}
  99413. +
  99414. +static gceSTATUS
  99415. +_DestroyContext(
  99416. + IN gckCONTEXT Context
  99417. + )
  99418. +{
  99419. + gceSTATUS status = gcvSTATUS_OK;
  99420. +
  99421. + if (Context != gcvNULL)
  99422. + {
  99423. + gcsCONTEXT_PTR bufferHead;
  99424. +
  99425. + /* Free context buffers. */
  99426. + for (bufferHead = Context->buffer; Context->buffer != gcvNULL;)
  99427. + {
  99428. + /* Get a shortcut to the current buffer. */
  99429. + gcsCONTEXT_PTR buffer = Context->buffer;
  99430. +
  99431. + /* Get the next buffer. */
  99432. + gcsCONTEXT_PTR next = buffer->next;
  99433. +
  99434. + /* Last item? */
  99435. + if (next == bufferHead)
  99436. + {
  99437. + next = gcvNULL;
  99438. + }
  99439. +
  99440. + /* Destroy the signal. */
  99441. + if (buffer->signal != gcvNULL)
  99442. + {
  99443. + gcmkONERROR(gckOS_DestroySignal(
  99444. + Context->os, buffer->signal
  99445. + ));
  99446. +
  99447. + buffer->signal = gcvNULL;
  99448. + }
  99449. +
  99450. + /* Free state delta map. */
  99451. + if (buffer->logical != gcvNULL)
  99452. + {
  99453. +#if gcdVIRTUAL_COMMAND_BUFFER
  99454. + gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
  99455. + Context->hardware->kernel->eventObj,
  99456. + Context->totalSize,
  99457. + buffer->physical,
  99458. + buffer->logical,
  99459. + gcvKERNEL_PIXEL
  99460. + ));
  99461. +
  99462. +#else
  99463. + gcmkONERROR(gckEVENT_FreeContiguousMemory(
  99464. + Context->hardware->kernel->eventObj,
  99465. + Context->totalSize,
  99466. + buffer->physical,
  99467. + buffer->logical,
  99468. + gcvKERNEL_PIXEL
  99469. + ));
  99470. +#endif
  99471. +
  99472. + buffer->logical = gcvNULL;
  99473. + }
  99474. +
  99475. + /* Free context buffer. */
  99476. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, buffer));
  99477. +
  99478. + /* Remove from the list. */
  99479. + Context->buffer = next;
  99480. + }
  99481. +
  99482. +#if gcdSECURE_USER
  99483. + /* Free the hint array. */
  99484. + if (Context->hint != gcvNULL)
  99485. + {
  99486. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
  99487. + }
  99488. +#endif
  99489. + /* Free record array copy. */
  99490. + if (Context->recordArray != gcvNULL)
  99491. + {
  99492. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArray));
  99493. + }
  99494. +
  99495. + /* Free the state mapping. */
  99496. + if (Context->map != gcvNULL)
  99497. + {
  99498. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->map));
  99499. + }
  99500. +
  99501. + /* Mark the gckCONTEXT object as unknown. */
  99502. + Context->object.type = gcvOBJ_UNKNOWN;
  99503. +
  99504. + /* Free the gckCONTEXT object. */
  99505. + gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context));
  99506. + }
  99507. +
  99508. +OnError:
  99509. + return status;
  99510. +}
  99511. +
  99512. +
  99513. +/******************************************************************************\
  99514. +**************************** Context Management API ****************************
  99515. +\******************************************************************************/
  99516. +
  99517. +/******************************************************************************\
  99518. +**
  99519. +** gckCONTEXT_Construct
  99520. +**
  99521. +** Construct a new gckCONTEXT object.
  99522. +**
  99523. +** INPUT:
  99524. +**
  99525. +** gckOS Os
  99526. +** Pointer to gckOS object.
  99527. +**
  99528. +** gctUINT32 ProcessID
  99529. +** Current process ID.
  99530. +**
  99531. +** gckHARDWARE Hardware
  99532. +** Pointer to gckHARDWARE object.
  99533. +**
  99534. +** OUTPUT:
  99535. +**
  99536. +** gckCONTEXT * Context
  99537. +** Pointer to a variable thet will receive the gckCONTEXT object
  99538. +** pointer.
  99539. +*/
  99540. +gceSTATUS
  99541. +gckCONTEXT_Construct(
  99542. + IN gckOS Os,
  99543. + IN gckHARDWARE Hardware,
  99544. + IN gctUINT32 ProcessID,
  99545. + OUT gckCONTEXT * Context
  99546. + )
  99547. +{
  99548. + gceSTATUS status;
  99549. + gckCONTEXT context = gcvNULL;
  99550. + gctSIZE_T allocationSize;
  99551. + gctUINT i;
  99552. + gctPOINTER pointer = gcvNULL;
  99553. +
  99554. + gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
  99555. +
  99556. + /* Verify the arguments. */
  99557. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  99558. + gcmkVERIFY_ARGUMENT(Context != gcvNULL);
  99559. +
  99560. +
  99561. + /**************************************************************************/
  99562. + /* Allocate and initialize basic fields of gckCONTEXT. ********************/
  99563. +
  99564. + /* The context object size. */
  99565. + allocationSize = gcmSIZEOF(struct _gckCONTEXT);
  99566. +
  99567. + /* Allocate the object. */
  99568. + gcmkONERROR(gckOS_Allocate(
  99569. + Os, allocationSize, &pointer
  99570. + ));
  99571. +
  99572. + context = pointer;
  99573. +
  99574. + /* Reset the entire object. */
  99575. + gcmkONERROR(gckOS_ZeroMemory(context, allocationSize));
  99576. +
  99577. + /* Initialize the gckCONTEXT object. */
  99578. + context->object.type = gcvOBJ_CONTEXT;
  99579. + context->os = Os;
  99580. + context->hardware = Hardware;
  99581. +
  99582. +
  99583. +#if defined(VIVANTE_NO_3D)
  99584. + context->entryPipe = gcvPIPE_2D;
  99585. + context->exitPipe = gcvPIPE_2D;
  99586. +#elif gcdCMD_NO_2D_CONTEXT
  99587. + context->entryPipe = gcvPIPE_3D;
  99588. + context->exitPipe = gcvPIPE_3D;
  99589. +#else
  99590. + context->entryPipe
  99591. + = (((((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)))))) )
  99592. + ? gcvPIPE_2D
  99593. + : gcvPIPE_3D;
  99594. + context->exitPipe = gcvPIPE_3D;
  99595. +#endif
  99596. +
  99597. + /* Get the command buffer requirements. */
  99598. + gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
  99599. + Hardware,
  99600. + &context->alignment,
  99601. + &context->reservedHead,
  99602. + &context->reservedTail
  99603. + ));
  99604. +
  99605. + /* Mark the context as dirty to force loading of the entire state table
  99606. + the first time. */
  99607. + context->dirty = gcvTRUE;
  99608. +
  99609. +
  99610. + /**************************************************************************/
  99611. + /* Get the size of the context buffer. ************************************/
  99612. +
  99613. + gcmkONERROR(_InitializeContextBuffer(context));
  99614. +
  99615. +
  99616. + /**************************************************************************/
  99617. + /* Compute the size of the record array. **********************************/
  99618. +
  99619. + context->recordArraySize
  99620. + = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * context->stateCount;
  99621. +
  99622. +
  99623. + if (context->stateCount > 0)
  99624. + {
  99625. + /**************************************************************************/
  99626. + /* Allocate and reset the state mapping table. ****************************/
  99627. +
  99628. + /* Allocate the state mapping table. */
  99629. + gcmkONERROR(gckOS_Allocate(
  99630. + Os,
  99631. + gcmSIZEOF(gcsSTATE_MAP) * context->stateCount,
  99632. + &pointer
  99633. + ));
  99634. +
  99635. + context->map = pointer;
  99636. +
  99637. + /* Zero the state mapping table. */
  99638. + gcmkONERROR(gckOS_ZeroMemory(
  99639. + context->map, gcmSIZEOF(gcsSTATE_MAP) * context->stateCount
  99640. + ));
  99641. +
  99642. +
  99643. + /**************************************************************************/
  99644. + /* Allocate the hint array. ***********************************************/
  99645. +
  99646. +#if gcdSECURE_USER
  99647. + /* Allocate hints. */
  99648. + gcmkONERROR(gckOS_Allocate(
  99649. + Os,
  99650. + gcmSIZEOF(gctBOOL) * context->stateCount,
  99651. + &pointer
  99652. + ));
  99653. +
  99654. + context->hint = pointer;
  99655. +#endif
  99656. + }
  99657. +
  99658. + /**************************************************************************/
  99659. + /* Allocate the context and state delta buffers. **************************/
  99660. +
  99661. + for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i += 1)
  99662. + {
  99663. + /* Allocate a context buffer. */
  99664. + gcsCONTEXT_PTR buffer;
  99665. +
  99666. + /* Allocate the context buffer structure. */
  99667. + gcmkONERROR(gckOS_Allocate(
  99668. + Os,
  99669. + gcmSIZEOF(gcsCONTEXT),
  99670. + &pointer
  99671. + ));
  99672. +
  99673. + buffer = pointer;
  99674. +
  99675. + /* Reset the context buffer structure. */
  99676. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  99677. + buffer, gcmSIZEOF(gcsCONTEXT)
  99678. + ));
  99679. +
  99680. + /* Append to the list. */
  99681. + if (context->buffer == gcvNULL)
  99682. + {
  99683. + buffer->next = buffer;
  99684. + context->buffer = buffer;
  99685. + }
  99686. + else
  99687. + {
  99688. + buffer->next = context->buffer->next;
  99689. + context->buffer->next = buffer;
  99690. + }
  99691. +
  99692. + /* Set the number of delta in the order of creation. */
  99693. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  99694. + buffer->num = i;
  99695. +#endif
  99696. +
  99697. + /* Create the busy signal. */
  99698. + gcmkONERROR(gckOS_CreateSignal(
  99699. + Os, gcvFALSE, &buffer->signal
  99700. + ));
  99701. +
  99702. + /* Set the signal, buffer is currently not busy. */
  99703. + gcmkONERROR(gckOS_Signal(
  99704. + Os, buffer->signal, gcvTRUE
  99705. + ));
  99706. +
  99707. + /* Create a new physical context buffer. */
  99708. +#if gcdVIRTUAL_COMMAND_BUFFER
  99709. + gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
  99710. + context->hardware->kernel,
  99711. + gcvFALSE,
  99712. + &context->totalSize,
  99713. + &buffer->physical,
  99714. + &pointer
  99715. + ));
  99716. +
  99717. +#else
  99718. + gcmkONERROR(gckOS_AllocateContiguous(
  99719. + Os,
  99720. + gcvFALSE,
  99721. + &context->totalSize,
  99722. + &buffer->physical,
  99723. + &pointer
  99724. + ));
  99725. +#endif
  99726. +
  99727. + buffer->logical = pointer;
  99728. +
  99729. + /* Set gckEVENT object pointer. */
  99730. + buffer->eventObj = Hardware->kernel->eventObj;
  99731. +
  99732. + /* Set the pointers to the LINK commands. */
  99733. + if (context->linkIndex2D != 0)
  99734. + {
  99735. + buffer->link2D = &buffer->logical[context->linkIndex2D];
  99736. + }
  99737. +
  99738. + if (context->linkIndex3D != 0)
  99739. + {
  99740. + buffer->link3D = &buffer->logical[context->linkIndex3D];
  99741. + }
  99742. +
  99743. + if (context->linkIndexXD != 0)
  99744. + {
  99745. + gctPOINTER xdLink;
  99746. + gctUINT8_PTR xdEntryLogical;
  99747. + gctSIZE_T xdEntrySize;
  99748. + gctSIZE_T linkBytes;
  99749. +
  99750. + /* Determine LINK parameters. */
  99751. + xdLink
  99752. + = &buffer->logical[context->linkIndexXD];
  99753. +
  99754. + xdEntryLogical
  99755. + = (gctUINT8_PTR) buffer->logical
  99756. + + context->entryOffsetXDFrom3D;
  99757. +
  99758. + xdEntrySize
  99759. + = context->bufferSize
  99760. + - context->entryOffsetXDFrom3D;
  99761. +
  99762. + /* Query LINK size. */
  99763. + gcmkONERROR(gckHARDWARE_Link(
  99764. + Hardware, gcvNULL, gcvNULL, 0, &linkBytes
  99765. + ));
  99766. +
  99767. + /* Generate a LINK. */
  99768. + gcmkONERROR(gckHARDWARE_Link(
  99769. + Hardware,
  99770. + xdLink,
  99771. + xdEntryLogical,
  99772. + xdEntrySize,
  99773. + &linkBytes
  99774. + ));
  99775. + }
  99776. + }
  99777. +
  99778. +
  99779. + /**************************************************************************/
  99780. + /* Initialize the context buffers. ****************************************/
  99781. +
  99782. + /* Initialize the current context buffer. */
  99783. + gcmkONERROR(_InitializeContextBuffer(context));
  99784. +
  99785. + /* Make all created contexts equal. */
  99786. + {
  99787. + gcsCONTEXT_PTR currContext, tempContext;
  99788. +
  99789. + /* Set the current context buffer. */
  99790. + currContext = context->buffer;
  99791. +
  99792. + /* Get the next context buffer. */
  99793. + tempContext = currContext->next;
  99794. +
  99795. + /* Loop through all buffers. */
  99796. + while (tempContext != currContext)
  99797. + {
  99798. + if (tempContext == gcvNULL)
  99799. + {
  99800. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  99801. + }
  99802. +
  99803. + /* Copy the current context. */
  99804. + gckOS_MemCopy(
  99805. + tempContext->logical,
  99806. + currContext->logical,
  99807. + context->totalSize
  99808. + );
  99809. +
  99810. + /* Get the next context buffer. */
  99811. + tempContext = tempContext->next;
  99812. + }
  99813. + }
  99814. +
  99815. + /* Return pointer to the gckCONTEXT object. */
  99816. + *Context = context;
  99817. +
  99818. + /* Success. */
  99819. + gcmkFOOTER_ARG("*Context=0x%08X", *Context);
  99820. + return gcvSTATUS_OK;
  99821. +
  99822. +OnError:
  99823. + /* Roll back on error. */
  99824. + gcmkVERIFY_OK(_DestroyContext(context));
  99825. +
  99826. + /* Return the status. */
  99827. + gcmkFOOTER();
  99828. + return status;
  99829. +}
  99830. +
  99831. +/******************************************************************************\
  99832. +**
  99833. +** gckCONTEXT_Destroy
  99834. +**
  99835. +** Destroy a gckCONTEXT object.
  99836. +**
  99837. +** INPUT:
  99838. +**
  99839. +** gckCONTEXT Context
  99840. +** Pointer to an gckCONTEXT object.
  99841. +**
  99842. +** OUTPUT:
  99843. +**
  99844. +** Nothing.
  99845. +*/
  99846. +gceSTATUS
  99847. +gckCONTEXT_Destroy(
  99848. + IN gckCONTEXT Context
  99849. + )
  99850. +{
  99851. + gceSTATUS status;
  99852. +
  99853. + gcmkHEADER_ARG("Context=0x%08X", Context);
  99854. +
  99855. + /* Verify the arguments. */
  99856. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  99857. +
  99858. + /* Destroy the context and all related objects. */
  99859. + status = _DestroyContext(Context);
  99860. +
  99861. + /* Success. */
  99862. + gcmkFOOTER_NO();
  99863. + return status;
  99864. +}
  99865. +
  99866. +/******************************************************************************\
  99867. +**
  99868. +** gckCONTEXT_Update
  99869. +**
  99870. +** Merge all pending state delta buffers into the current context buffer.
  99871. +**
  99872. +** INPUT:
  99873. +**
  99874. +** gckCONTEXT Context
  99875. +** Pointer to an gckCONTEXT object.
  99876. +**
  99877. +** gctUINT32 ProcessID
  99878. +** Current process ID.
  99879. +**
  99880. +** gcsSTATE_DELTA_PTR StateDelta
  99881. +** Pointer to the state delta.
  99882. +**
  99883. +** OUTPUT:
  99884. +**
  99885. +** Nothing.
  99886. +*/
  99887. +gceSTATUS
  99888. +gckCONTEXT_Update(
  99889. + IN gckCONTEXT Context,
  99890. + IN gctUINT32 ProcessID,
  99891. + IN gcsSTATE_DELTA_PTR StateDelta
  99892. + )
  99893. +{
  99894. +#ifndef VIVANTE_NO_3D
  99895. + gceSTATUS status = gcvSTATUS_OK;
  99896. + gcsSTATE_DELTA _stateDelta;
  99897. + gckKERNEL kernel;
  99898. + gcsCONTEXT_PTR buffer;
  99899. + gcsSTATE_MAP_PTR map;
  99900. + gctBOOL needCopy = gcvFALSE;
  99901. + gcsSTATE_DELTA_PTR nDelta;
  99902. + gcsSTATE_DELTA_PTR uDelta = gcvNULL;
  99903. + gcsSTATE_DELTA_PTR kDelta = gcvNULL;
  99904. + gcsSTATE_DELTA_RECORD_PTR record;
  99905. + gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL;
  99906. + gctUINT elementCount;
  99907. + gctUINT address;
  99908. + gctUINT32 mask;
  99909. + gctUINT32 data;
  99910. + gctUINT index;
  99911. + gctUINT i, j;
  99912. +
  99913. +#if gcdSECURE_USER
  99914. + gcskSECURE_CACHE_PTR cache;
  99915. +#endif
  99916. +
  99917. + gcmkHEADER_ARG(
  99918. + "Context=0x%08X ProcessID=%d StateDelta=0x%08X",
  99919. + Context, ProcessID, StateDelta
  99920. + );
  99921. +
  99922. + /* Verify the arguments. */
  99923. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  99924. +
  99925. + /* Get a shortcut to the kernel object. */
  99926. + kernel = Context->hardware->kernel;
  99927. +
  99928. + /* Check wehther we need to copy the structures or not. */
  99929. + gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy));
  99930. +
  99931. + /* Allocate the copy buffer for the user record array. */
  99932. + if (needCopy && (Context->recordArray == gcvNULL))
  99933. + {
  99934. + /* Allocate the buffer. */
  99935. + gcmkONERROR(gckOS_Allocate(
  99936. + Context->os,
  99937. + Context->recordArraySize,
  99938. + (gctPOINTER *) &Context->recordArray
  99939. + ));
  99940. + }
  99941. +
  99942. + /* Get the current context buffer. */
  99943. + buffer = Context->buffer;
  99944. +
  99945. + /* Wait until the context buffer becomes available; this will
  99946. + also reset the signal and mark the buffer as busy. */
  99947. + gcmkONERROR(gckOS_WaitSignal(
  99948. + Context->os, buffer->signal, gcvINFINITE
  99949. + ));
  99950. +
  99951. +#if gcdSECURE_USER
  99952. + /* Get the cache form the database. */
  99953. + gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
  99954. +#endif
  99955. +
  99956. +#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && !defined(VIVANTE_NO_3D)
  99957. + /* Update current context token. */
  99958. + buffer->logical[Context->map[0x0E14].index]
  99959. + = gcmPTR2INT(Context);
  99960. +#endif
  99961. +
  99962. + /* Are there any pending deltas? */
  99963. + if (buffer->deltaCount != 0)
  99964. + {
  99965. + /* Get the state map. */
  99966. + map = Context->map;
  99967. +
  99968. + /* Get the first delta item. */
  99969. + uDelta = buffer->delta;
  99970. +
  99971. + /* Reset the vertex stream count. */
  99972. + elementCount = 0;
  99973. +
  99974. + /* Merge all pending deltas. */
  99975. + for (i = 0; i < buffer->deltaCount; i += 1)
  99976. + {
  99977. + /* Get access to the state delta. */
  99978. + gcmkONERROR(gckKERNEL_OpenUserData(
  99979. + kernel, needCopy,
  99980. + &_stateDelta,
  99981. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  99982. + (gctPOINTER *) &kDelta
  99983. + ));
  99984. +
  99985. + /* Get access to the state records. */
  99986. + gcmkONERROR(gckKERNEL_OpenUserData(
  99987. + kernel, needCopy,
  99988. + Context->recordArray,
  99989. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  99990. + (gctPOINTER *) &recordArray
  99991. + ));
  99992. +
  99993. + /* Merge all pending states. */
  99994. + for (j = 0; j < kDelta->recordCount; j += 1)
  99995. + {
  99996. + if (j >= Context->stateCount)
  99997. + {
  99998. + break;
  99999. + }
  100000. +
  100001. + /* Get the current state record. */
  100002. + record = &recordArray[j];
  100003. +
  100004. + /* Get the state address. */
  100005. + address = record->address;
  100006. +
  100007. + /* Make sure the state is a part of the mapping table. */
  100008. + if (address >= Context->stateCount)
  100009. + {
  100010. + gcmkTRACE(
  100011. + gcvLEVEL_ERROR,
  100012. + "%s(%d): State 0x%04X is not mapped.\n",
  100013. + __FUNCTION__, __LINE__,
  100014. + address
  100015. + );
  100016. +
  100017. + continue;
  100018. + }
  100019. +
  100020. + /* Get the state index. */
  100021. + index = map[address].index;
  100022. +
  100023. + /* Skip the state if not mapped. */
  100024. + if (index == 0)
  100025. + {
  100026. +#if gcdDEBUG
  100027. + if ((address != 0x0594)
  100028. + && (address != 0x0E00)
  100029. + && (address != 0x0E03)
  100030. + )
  100031. + {
  100032. +#endif
  100033. + gcmkTRACE(
  100034. + gcvLEVEL_ERROR,
  100035. + "%s(%d): State 0x%04X is not mapped.\n",
  100036. + __FUNCTION__, __LINE__,
  100037. + address
  100038. + );
  100039. +#if gcdDEBUG
  100040. + }
  100041. +#endif
  100042. + continue;
  100043. + }
  100044. +
  100045. + /* Get the data mask. */
  100046. + mask = record->mask;
  100047. +
  100048. + /* Masked states that are being completly reset or regular states. */
  100049. + if ((mask == 0) || (mask == ~0U))
  100050. + {
  100051. + /* Get the new data value. */
  100052. + data = record->data;
  100053. +
  100054. + /* Process special states. */
  100055. + if (address == 0x0595)
  100056. + {
  100057. + /* Force auto-disable to be disabled. */
  100058. + 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)));
  100059. + 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)));
  100060. + 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)));
  100061. + }
  100062. +
  100063. +#if gcdSECURE_USER
  100064. + /* Do we need to convert the logical address? */
  100065. + if (Context->hint[address])
  100066. + {
  100067. + /* Map handle into physical address. */
  100068. + gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
  100069. + kernel, cache, (gctPOINTER) &data
  100070. + ));
  100071. + }
  100072. +#endif
  100073. +
  100074. + /* Set new data. */
  100075. + buffer->logical[index] = data;
  100076. + }
  100077. +
  100078. + /* Masked states that are being set partially. */
  100079. + else
  100080. + {
  100081. + buffer->logical[index]
  100082. + = (~mask & buffer->logical[index])
  100083. + | (mask & record->data);
  100084. + }
  100085. + }
  100086. +
  100087. + /* Get the element count. */
  100088. + if (kDelta->elementCount != 0)
  100089. + {
  100090. + elementCount = kDelta->elementCount;
  100091. + }
  100092. +
  100093. + /* Dereference delta. */
  100094. + kDelta->refCount -= 1;
  100095. + gcmkASSERT(kDelta->refCount >= 0);
  100096. +
  100097. + /* Get the next state delta. */
  100098. + nDelta = gcmUINT64_TO_PTR(kDelta->next);
  100099. +
  100100. + /* Get access to the state records. */
  100101. + gcmkONERROR(gckKERNEL_CloseUserData(
  100102. + kernel, needCopy,
  100103. + gcvFALSE,
  100104. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  100105. + (gctPOINTER *) &recordArray
  100106. + ));
  100107. +
  100108. + /* Close access to the current state delta. */
  100109. + gcmkONERROR(gckKERNEL_CloseUserData(
  100110. + kernel, needCopy,
  100111. + gcvTRUE,
  100112. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  100113. + (gctPOINTER *) &kDelta
  100114. + ));
  100115. +
  100116. + /* Update the user delta pointer. */
  100117. + uDelta = nDelta;
  100118. + }
  100119. +
  100120. + /* Hardware disables all input streams when the stream 0 is programmed,
  100121. + it then reenables those streams that were explicitely programmed by
  100122. + the software. Because of this we cannot program the entire array of
  100123. + values, otherwise we'll get all streams reenabled, but rather program
  100124. + only those that are actully needed by the software. */
  100125. + if (elementCount != 0)
  100126. + {
  100127. + gctUINT base;
  100128. + gctUINT nopCount;
  100129. + gctUINT32_PTR nop;
  100130. + gctUINT fe2vsCount = 12;
  100131. +
  100132. + 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)))))) ))
  100133. + {
  100134. + fe2vsCount = 16;
  100135. + }
  100136. +
  100137. + /* Determine the base index of the vertex stream array. */
  100138. + base = map[0x0180].index;
  100139. +
  100140. + /* Set the proper state count. */
  100141. + buffer->logical[base - 1]
  100142. + = ((((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)));
  100143. +
  100144. + /* Determine the number of NOP commands. */
  100145. + nopCount
  100146. + = (fe2vsCount / 2)
  100147. + - (elementCount / 2);
  100148. +
  100149. + /* Determine the location of the first NOP. */
  100150. + nop = &buffer->logical[base + (elementCount | 1)];
  100151. +
  100152. + /* Fill the unused space with NOPs. */
  100153. + for (i = 0; i < nopCount; i += 1)
  100154. + {
  100155. + if (nop >= buffer->logical + Context->totalSize)
  100156. + {
  100157. + break;
  100158. + }
  100159. +
  100160. + /* Generate a NOP command. */
  100161. + *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)));
  100162. +
  100163. + /* Advance. */
  100164. + nop += 2;
  100165. + }
  100166. + }
  100167. +
  100168. + /* Reset pending deltas. */
  100169. + buffer->deltaCount = 0;
  100170. + buffer->delta = gcvNULL;
  100171. + }
  100172. +
  100173. + /* Set state delta user pointer. */
  100174. + uDelta = StateDelta;
  100175. +
  100176. + /* Get access to the state delta. */
  100177. + gcmkONERROR(gckKERNEL_OpenUserData(
  100178. + kernel, needCopy,
  100179. + &_stateDelta,
  100180. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  100181. + (gctPOINTER *) &kDelta
  100182. + ));
  100183. +
  100184. + /* State delta cannot be attached to anything yet. */
  100185. + if (kDelta->refCount != 0)
  100186. + {
  100187. + gcmkTRACE(
  100188. + gcvLEVEL_ERROR,
  100189. + "%s(%d): kDelta->refCount = %d (has to be 0).\n",
  100190. + __FUNCTION__, __LINE__,
  100191. + kDelta->refCount
  100192. + );
  100193. + }
  100194. +
  100195. + /* Attach to all contexts. */
  100196. + buffer = Context->buffer;
  100197. +
  100198. + do
  100199. + {
  100200. + /* Attach to the context if nothing is attached yet. If a delta
  100201. + is allready attached, all we need to do is to increment
  100202. + the number of deltas in the context. */
  100203. + if (buffer->delta == gcvNULL)
  100204. + {
  100205. + buffer->delta = uDelta;
  100206. + }
  100207. +
  100208. + /* Update reference count. */
  100209. + kDelta->refCount += 1;
  100210. +
  100211. + /* Update counters. */
  100212. + buffer->deltaCount += 1;
  100213. +
  100214. + /* Get the next context buffer. */
  100215. + buffer = buffer->next;
  100216. +
  100217. + if (buffer == gcvNULL)
  100218. + {
  100219. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  100220. + }
  100221. + }
  100222. + while (Context->buffer != buffer);
  100223. +
  100224. + /* Close access to the current state delta. */
  100225. + gcmkONERROR(gckKERNEL_CloseUserData(
  100226. + kernel, needCopy,
  100227. + gcvTRUE,
  100228. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  100229. + (gctPOINTER *) &kDelta
  100230. + ));
  100231. +
  100232. + /* Schedule an event to mark the context buffer as available. */
  100233. + gcmkONERROR(gckEVENT_Signal(
  100234. + buffer->eventObj, buffer->signal, gcvKERNEL_PIXEL
  100235. + ));
  100236. +
  100237. + /* Advance to the next context buffer. */
  100238. + Context->buffer = buffer->next;
  100239. +
  100240. + /* Return the status. */
  100241. + gcmkFOOTER();
  100242. + return gcvSTATUS_OK;
  100243. +
  100244. +OnError:
  100245. + /* Get access to the state records. */
  100246. + if (kDelta != gcvNULL)
  100247. + {
  100248. + gcmkVERIFY_OK(gckKERNEL_CloseUserData(
  100249. + kernel, needCopy,
  100250. + gcvFALSE,
  100251. + gcmUINT64_TO_PTR(kDelta->recordArray), Context->recordArraySize,
  100252. + (gctPOINTER *) &recordArray
  100253. + ));
  100254. + }
  100255. +
  100256. + /* Close access to the current state delta. */
  100257. + gcmkVERIFY_OK(gckKERNEL_CloseUserData(
  100258. + kernel, needCopy,
  100259. + gcvTRUE,
  100260. + uDelta, gcmSIZEOF(gcsSTATE_DELTA),
  100261. + (gctPOINTER *) &kDelta
  100262. + ));
  100263. +
  100264. + /* Return the status. */
  100265. + gcmkFOOTER();
  100266. + return status;
  100267. +#else
  100268. + return gcvSTATUS_OK;
  100269. +#endif
  100270. +}
  100271. +
  100272. diff -Nur linux-3.14.17/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
  100273. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h 1970-01-01 01:00:00.000000000 +0100
  100274. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h 2014-09-11 18:06:03.082042291 +0200
  100275. @@ -0,0 +1,157 @@
  100276. +/****************************************************************************
  100277. +*
  100278. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  100279. +*
  100280. +* This program is free software; you can redistribute it and/or modify
  100281. +* it under the terms of the GNU General Public License as published by
  100282. +* the Free Software Foundation; either version 2 of the license, or
  100283. +* (at your option) any later version.
  100284. +*
  100285. +* This program is distributed in the hope that it will be useful,
  100286. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  100287. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  100288. +* GNU General Public License for more details.
  100289. +*
  100290. +* You should have received a copy of the GNU General Public License
  100291. +* along with this program; if not write to the Free Software
  100292. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  100293. +*
  100294. +*****************************************************************************/
  100295. +
  100296. +
  100297. +#ifndef __gc_hal_kernel_context_h_
  100298. +#define __gc_hal_kernel_context_h_
  100299. +
  100300. +#include "gc_hal_kernel_buffer.h"
  100301. +
  100302. +#ifdef __cplusplus
  100303. +extern "C" {
  100304. +#endif
  100305. +
  100306. +/* Maps state locations within the context buffer. */
  100307. +typedef struct _gcsSTATE_MAP * gcsSTATE_MAP_PTR;
  100308. +typedef struct _gcsSTATE_MAP
  100309. +{
  100310. + /* Index of the state in the context buffer. */
  100311. + gctUINT index;
  100312. +
  100313. + /* State mask. */
  100314. + gctUINT32 mask;
  100315. +}
  100316. +gcsSTATE_MAP;
  100317. +
  100318. +/* Context buffer. */
  100319. +typedef struct _gcsCONTEXT * gcsCONTEXT_PTR;
  100320. +typedef struct _gcsCONTEXT
  100321. +{
  100322. + /* For debugging: the number of context buffer in the order of creation. */
  100323. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  100324. + gctUINT num;
  100325. +#endif
  100326. +
  100327. + /* Pointer to gckEVENT object. */
  100328. + gckEVENT eventObj;
  100329. +
  100330. + /* Context busy signal. */
  100331. + gctSIGNAL signal;
  100332. +
  100333. + /* Physical address of the context buffer. */
  100334. + gctPHYS_ADDR physical;
  100335. +
  100336. + /* Logical address of the context buffer. */
  100337. + gctUINT32_PTR logical;
  100338. +
  100339. + /* Pointer to the LINK commands. */
  100340. + gctPOINTER link2D;
  100341. + gctPOINTER link3D;
  100342. +
  100343. + /* The number of pending state deltas. */
  100344. + gctUINT deltaCount;
  100345. +
  100346. + /* Pointer to the first delta to be applied. */
  100347. + gcsSTATE_DELTA_PTR delta;
  100348. +
  100349. + /* Next context buffer. */
  100350. + gcsCONTEXT_PTR next;
  100351. +}
  100352. +gcsCONTEXT;
  100353. +
  100354. +/* gckCONTEXT structure that hold the current context. */
  100355. +struct _gckCONTEXT
  100356. +{
  100357. + /* Object. */
  100358. + gcsOBJECT object;
  100359. +
  100360. + /* Pointer to gckOS object. */
  100361. + gckOS os;
  100362. +
  100363. + /* Pointer to gckHARDWARE object. */
  100364. + gckHARDWARE hardware;
  100365. +
  100366. + /* Command buffer alignment. */
  100367. + gctSIZE_T alignment;
  100368. + gctSIZE_T reservedHead;
  100369. + gctSIZE_T reservedTail;
  100370. +
  100371. + /* Context buffer metrics. */
  100372. + gctSIZE_T stateCount;
  100373. + gctSIZE_T totalSize;
  100374. + gctSIZE_T bufferSize;
  100375. + gctUINT32 linkIndex2D;
  100376. + gctUINT32 linkIndex3D;
  100377. + gctUINT32 linkIndexXD;
  100378. + gctUINT32 entryOffset3D;
  100379. + gctUINT32 entryOffsetXDFrom2D;
  100380. + gctUINT32 entryOffsetXDFrom3D;
  100381. +
  100382. + /* Dirty flags. */
  100383. + gctBOOL dirty;
  100384. + gctBOOL dirty2D;
  100385. + gctBOOL dirty3D;
  100386. + gcsCONTEXT_PTR dirtyBuffer;
  100387. +
  100388. + /* State mapping. */
  100389. + gcsSTATE_MAP_PTR map;
  100390. +
  100391. + /* List of context buffers. */
  100392. + gcsCONTEXT_PTR buffer;
  100393. +
  100394. + /* A copy of the user record array. */
  100395. + gctUINT recordArraySize;
  100396. + gcsSTATE_DELTA_RECORD_PTR recordArray;
  100397. +
  100398. + /* Requested pipe select for context. */
  100399. + gcePIPE_SELECT entryPipe;
  100400. + gcePIPE_SELECT exitPipe;
  100401. +
  100402. + /* Variables used for building state buffer. */
  100403. + gctUINT32 lastAddress;
  100404. + gctSIZE_T lastSize;
  100405. + gctUINT32 lastIndex;
  100406. + gctBOOL lastFixed;
  100407. +
  100408. + /* Hint array. */
  100409. +#if gcdSECURE_USER
  100410. + gctBOOL_PTR hint;
  100411. +#endif
  100412. +
  100413. +#if VIVANTE_PROFILER_CONTEXT
  100414. + gcsPROFILER_COUNTERS latestProfiler;
  100415. + gcsPROFILER_COUNTERS histroyProfiler;
  100416. + gctUINT32 prevVSInstCount;
  100417. + gctUINT32 prevVSBranchInstCount;
  100418. + gctUINT32 prevVSTexInstCount;
  100419. + gctUINT32 prevVSVertexCount;
  100420. + gctUINT32 prevPSInstCount;
  100421. + gctUINT32 prevPSBranchInstCount;
  100422. + gctUINT32 prevPSTexInstCount;
  100423. + gctUINT32 prevPSPixelCount;
  100424. +#endif
  100425. +};
  100426. +
  100427. +#ifdef __cplusplus
  100428. +}
  100429. +#endif
  100430. +
  100431. +#endif /* __gc_hal_kernel_context_h_ */
  100432. +
  100433. diff -Nur linux-3.14.17/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
  100434. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c 1970-01-01 01:00:00.000000000 +0100
  100435. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c 2014-09-11 18:06:03.082042291 +0200
  100436. @@ -0,0 +1,7280 @@
  100437. +/****************************************************************************
  100438. +*
  100439. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  100440. +*
  100441. +* This program is free software; you can redistribute it and/or modify
  100442. +* it under the terms of the GNU General Public License as published by
  100443. +* the Free Software Foundation; either version 2 of the license, or
  100444. +* (at your option) any later version.
  100445. +*
  100446. +* This program is distributed in the hope that it will be useful,
  100447. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  100448. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  100449. +* GNU General Public License for more details.
  100450. +*
  100451. +* You should have received a copy of the GNU General Public License
  100452. +* along with this program; if not write to the Free Software
  100453. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  100454. +*
  100455. +*****************************************************************************/
  100456. +
  100457. +
  100458. +#include "gc_hal.h"
  100459. +#include "gc_hal_kernel.h"
  100460. +#if VIVANTE_PROFILER_CONTEXT
  100461. +#include "gc_hal_kernel_context.h"
  100462. +#endif
  100463. +
  100464. +#define _GC_OBJ_ZONE gcvZONE_HARDWARE
  100465. +
  100466. +typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR;
  100467. +typedef struct _gcsiDEBUG_REGISTERS
  100468. +{
  100469. + gctSTRING module;
  100470. + gctUINT index;
  100471. + gctUINT shift;
  100472. + gctUINT data;
  100473. + gctUINT count;
  100474. + gctUINT32 signature;
  100475. +}
  100476. +gcsiDEBUG_REGISTERS;
  100477. +
  100478. +extern int gpu3DMinClock;
  100479. +/******************************************************************************\
  100480. +********************************* Support Code *********************************
  100481. +\******************************************************************************/
  100482. +static gceSTATUS
  100483. +_ResetGPU(
  100484. + IN gckHARDWARE Hardware,
  100485. + IN gckOS Os,
  100486. + IN gceCORE Core
  100487. + );
  100488. +
  100489. +static gceSTATUS
  100490. +_IdentifyHardware(
  100491. + IN gckOS Os,
  100492. + IN gceCORE Core,
  100493. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  100494. + )
  100495. +{
  100496. + gceSTATUS status;
  100497. +
  100498. + gctUINT32 chipIdentity;
  100499. +
  100500. + gctUINT32 streamCount = 0;
  100501. + gctUINT32 registerMax = 0;
  100502. + gctUINT32 threadCount = 0;
  100503. + gctUINT32 shaderCoreCount = 0;
  100504. + gctUINT32 vertexCacheSize = 0;
  100505. + gctUINT32 vertexOutputBufferSize = 0;
  100506. + gctUINT32 pixelPipes = 0;
  100507. + gctUINT32 instructionCount = 0;
  100508. + gctUINT32 numConstants = 0;
  100509. + gctUINT32 bufferSize = 0;
  100510. + gctUINT32 varyingsCount = 0;
  100511. + gctBOOL useHZ;
  100512. +
  100513. + gcmkHEADER_ARG("Os=0x%x", Os);
  100514. +
  100515. + /***************************************************************************
  100516. + ** Get chip ID and revision.
  100517. + */
  100518. +
  100519. + /* Read chip identity register. */
  100520. + gcmkONERROR(
  100521. + gckOS_ReadRegisterEx(Os, Core,
  100522. + 0x00018,
  100523. + &chipIdentity));
  100524. +
  100525. + /* Special case for older graphic cores. */
  100526. + 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))))))))
  100527. + {
  100528. + Identity->chipModel = gcv500;
  100529. + 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)))))) );
  100530. + }
  100531. +
  100532. + else
  100533. + {
  100534. + /* Read chip identity register. */
  100535. + gcmkONERROR(
  100536. + gckOS_ReadRegisterEx(Os, Core,
  100537. + 0x00020,
  100538. + (gctUINT32_PTR) &Identity->chipModel));
  100539. +
  100540. + /* !!!! HACK ALERT !!!! */
  100541. + /* Because people change device IDs without letting software know
  100542. + ** about it - here is the hack to make it all look the same. Only
  100543. + ** for GC400 family. Next time - TELL ME!!! */
  100544. + if (((Identity->chipModel & 0xFF00) == 0x0400)
  100545. + && (Identity->chipModel != 0x0420))
  100546. + {
  100547. + Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400);
  100548. + }
  100549. +
  100550. + /* Read CHIP_REV register. */
  100551. + gcmkONERROR(
  100552. + gckOS_ReadRegisterEx(Os, Core,
  100553. + 0x00024,
  100554. + &Identity->chipRevision));
  100555. +
  100556. + if ((Identity->chipModel == gcv300)
  100557. + && (Identity->chipRevision == 0x2201)
  100558. + )
  100559. + {
  100560. + gctUINT32 chipDate;
  100561. + gctUINT32 chipTime;
  100562. +
  100563. + /* Read date and time registers. */
  100564. + gcmkONERROR(
  100565. + gckOS_ReadRegisterEx(Os, Core,
  100566. + 0x00028,
  100567. + &chipDate));
  100568. +
  100569. + gcmkONERROR(
  100570. + gckOS_ReadRegisterEx(Os, Core,
  100571. + 0x0002C,
  100572. + &chipTime));
  100573. +
  100574. + if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
  100575. + {
  100576. + /* This IP has an ECO; put the correct revision in it. */
  100577. + Identity->chipRevision = 0x1051;
  100578. + }
  100579. + }
  100580. + }
  100581. +
  100582. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100583. + "Identity: chipModel=%X",
  100584. + Identity->chipModel);
  100585. +
  100586. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100587. + "Identity: chipRevision=%X",
  100588. + Identity->chipRevision);
  100589. +
  100590. +
  100591. + /***************************************************************************
  100592. + ** Get chip features.
  100593. + */
  100594. +
  100595. + /* Read chip feature register. */
  100596. + gcmkONERROR(
  100597. + gckOS_ReadRegisterEx(Os, Core,
  100598. + 0x0001C,
  100599. + &Identity->chipFeatures));
  100600. +
  100601. +#ifndef VIVANTE_NO_3D
  100602. + /* Disable fast clear on GC700. */
  100603. + if (Identity->chipModel == gcv700)
  100604. + {
  100605. + Identity->chipFeatures
  100606. + = ((((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)));
  100607. + }
  100608. +#endif
  100609. +
  100610. + if (((Identity->chipModel == gcv500) && (Identity->chipRevision < 2))
  100611. + || ((Identity->chipModel == gcv300) && (Identity->chipRevision < 0x2000))
  100612. + )
  100613. + {
  100614. + /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */
  100615. + Identity->chipMinorFeatures = 0;
  100616. + Identity->chipMinorFeatures1 = 0;
  100617. + Identity->chipMinorFeatures2 = 0;
  100618. + Identity->chipMinorFeatures3 = 0;
  100619. + Identity->chipMinorFeatures4 = 0;
  100620. + }
  100621. + else
  100622. + {
  100623. + /* Read chip minor feature register #0. */
  100624. + gcmkONERROR(
  100625. + gckOS_ReadRegisterEx(Os, Core,
  100626. + 0x00034,
  100627. + &Identity->chipMinorFeatures));
  100628. +
  100629. + 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)))))))
  100630. + )
  100631. + {
  100632. + /* Read chip minor featuress register #1. */
  100633. + gcmkONERROR(
  100634. + gckOS_ReadRegisterEx(Os, Core,
  100635. + 0x00074,
  100636. + &Identity->chipMinorFeatures1));
  100637. +
  100638. + /* Read chip minor featuress register #2. */
  100639. + gcmkONERROR(
  100640. + gckOS_ReadRegisterEx(Os, Core,
  100641. + 0x00084,
  100642. + &Identity->chipMinorFeatures2));
  100643. +
  100644. + /*Identity->chipMinorFeatures2 &= ~(0x1 << 3);*/
  100645. +
  100646. + /* Read chip minor featuress register #1. */
  100647. + gcmkONERROR(
  100648. + gckOS_ReadRegisterEx(Os, Core,
  100649. + 0x00088,
  100650. + &Identity->chipMinorFeatures3));
  100651. +
  100652. + /*The BG2 chip has no compression supertiled, and the bit of GCMinorFeature3BugFixes15 is n/a*/
  100653. + if(Identity->chipModel == gcv1000 && Identity->chipRevision == 0x5036)
  100654. + {
  100655. + Identity->chipMinorFeatures3
  100656. + = ((((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)));
  100657. + Identity->chipMinorFeatures3
  100658. + = ((((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)));
  100659. + }
  100660. +
  100661. + /* Read chip minor featuress register #4. */
  100662. + gcmkONERROR(
  100663. + gckOS_ReadRegisterEx(Os, Core,
  100664. + 0x00094,
  100665. + &Identity->chipMinorFeatures4));
  100666. + }
  100667. + else
  100668. + {
  100669. + /* Chip doesn't has minor features register #1 or 2 or 3 or 4. */
  100670. + Identity->chipMinorFeatures1 = 0;
  100671. + Identity->chipMinorFeatures2 = 0;
  100672. + Identity->chipMinorFeatures3 = 0;
  100673. + Identity->chipMinorFeatures4 = 0;
  100674. + }
  100675. + }
  100676. +
  100677. + /* Get the Supertile layout in the hardware. */
  100678. + 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)))))))
  100679. + || ((((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))))))))
  100680. + {
  100681. + Identity->superTileMode = 2;
  100682. + }
  100683. + 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))))))))
  100684. + {
  100685. + Identity->superTileMode = 1;
  100686. + }
  100687. + else
  100688. + {
  100689. + Identity->superTileMode = 0;
  100690. + }
  100691. +
  100692. + /* Exception for GC1000, revision 5035 & GC800, revision 4612 */
  100693. + if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
  100694. + || (Identity->chipRevision == 0x5036)
  100695. + || (Identity->chipRevision == 0x5037)))
  100696. + || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612))
  100697. + || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647)))
  100698. + {
  100699. + Identity->superTileMode = 1;
  100700. + }
  100701. +
  100702. + if (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245)
  100703. + {
  100704. + 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)))))))
  100705. + || ((((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)))))));
  100706. + }
  100707. + else
  100708. + {
  100709. + useHZ = gcvFALSE;
  100710. + }
  100711. +
  100712. + if (useHZ)
  100713. + {
  100714. + /* Disable EZ. */
  100715. + Identity->chipFeatures
  100716. + = ((((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)));
  100717. + }
  100718. +
  100719. + /* Disable HZ when EZ is present for older chips. */
  100720. + 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))))))))
  100721. + {
  100722. + /* Disable HIERARCHICAL_Z. */
  100723. + Identity->chipMinorFeatures
  100724. + = ((((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)));
  100725. + }
  100726. +
  100727. + /* Disable rectangle primitive when chip is gc880_5_1_0_rc6*/
  100728. + if ((Identity->chipModel == gcv880) && (Identity->chipRevision == 0x5106))
  100729. + {
  100730. + /* Disable rectangle primitive. */
  100731. + Identity->chipMinorFeatures2
  100732. + = ((((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)));
  100733. + }
  100734. +
  100735. + if ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4605))
  100736. + {
  100737. + /* Correct feature bit: RTL does not have such feature. */
  100738. + Identity->chipFeatures
  100739. + = ((((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)));
  100740. + }
  100741. +
  100742. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100743. + "Identity: chipFeatures=0x%08X",
  100744. + Identity->chipFeatures);
  100745. +
  100746. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100747. + "Identity: chipMinorFeatures=0x%08X",
  100748. + Identity->chipMinorFeatures);
  100749. +
  100750. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100751. + "Identity: chipMinorFeatures1=0x%08X",
  100752. + Identity->chipMinorFeatures1);
  100753. +
  100754. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100755. + "Identity: chipMinorFeatures2=0x%08X",
  100756. + Identity->chipMinorFeatures2);
  100757. +
  100758. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100759. + "Identity: chipMinorFeatures3=0x%08X",
  100760. + Identity->chipMinorFeatures3);
  100761. +
  100762. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100763. + "Identity: chipMinorFeatures4=0x%08X",
  100764. + Identity->chipMinorFeatures4);
  100765. +
  100766. + /***************************************************************************
  100767. + ** Get chip specs.
  100768. + */
  100769. +
  100770. + 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))))))))
  100771. + {
  100772. + gctUINT32 specs, specs2, specs3;
  100773. +
  100774. + /* Read gcChipSpecs register. */
  100775. + gcmkONERROR(
  100776. + gckOS_ReadRegisterEx(Os, Core,
  100777. + 0x00048,
  100778. + &specs));
  100779. +
  100780. + /* Extract the fields. */
  100781. + streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) );
  100782. + registerMax = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) );
  100783. + threadCount = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) );
  100784. + shaderCoreCount = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) );
  100785. + vertexCacheSize = (((((gctUINT32) (specs)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) );
  100786. + vertexOutputBufferSize = (((((gctUINT32) (specs)) >> (0 ? 31:28)) & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1)))))) );
  100787. + pixelPipes = (((((gctUINT32) (specs)) >> (0 ? 27:25)) & ((gctUINT32) ((((1 ? 27:25) - (0 ? 27:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:25) - (0 ? 27:25) + 1)))))) );
  100788. +
  100789. + /* Read gcChipSpecs2 register. */
  100790. + gcmkONERROR(
  100791. + gckOS_ReadRegisterEx(Os, Core,
  100792. + 0x00080,
  100793. + &specs2));
  100794. +
  100795. + instructionCount = (((((gctUINT32) (specs2)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
  100796. + numConstants = (((((gctUINT32) (specs2)) >> (0 ? 31:16)) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1)))))) );
  100797. + bufferSize = (((((gctUINT32) (specs2)) >> (0 ? 7:0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1)))))) );
  100798. +
  100799. + /* Read gcChipSpecs3 register. */
  100800. + gcmkONERROR(
  100801. + gckOS_ReadRegisterEx(Os, Core,
  100802. + 0x0008C,
  100803. + &specs3));
  100804. +
  100805. + varyingsCount = (((((gctUINT32) (specs3)) >> (0 ? 8:4)) & ((gctUINT32) ((((1 ? 8:4) - (0 ? 8:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:4) - (0 ? 8:4) + 1)))))) );
  100806. + }
  100807. +
  100808. + /* Get the number of pixel pipes. */
  100809. + Identity->pixelPipes = gcmMAX(pixelPipes, 1);
  100810. +
  100811. + /* Get the stream count. */
  100812. + Identity->streamCount = (streamCount != 0)
  100813. + ? streamCount
  100814. + : (Identity->chipModel >= gcv1000) ? 4 : 1;
  100815. +
  100816. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100817. + "Specs: streamCount=%u%s",
  100818. + Identity->streamCount,
  100819. + (streamCount == 0) ? " (default)" : "");
  100820. +
  100821. + /* Get the vertex output buffer size. */
  100822. + Identity->vertexOutputBufferSize = (vertexOutputBufferSize != 0)
  100823. + ? 1 << vertexOutputBufferSize
  100824. + : (Identity->chipModel == gcv400)
  100825. + ? (Identity->chipRevision < 0x4000) ? 512
  100826. + : (Identity->chipRevision < 0x4200) ? 256
  100827. + : 128
  100828. + : (Identity->chipModel == gcv530)
  100829. + ? (Identity->chipRevision < 0x4200) ? 512
  100830. + : 128
  100831. + : 512;
  100832. +
  100833. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100834. + "Specs: vertexOutputBufferSize=%u%s",
  100835. + Identity->vertexOutputBufferSize,
  100836. + (vertexOutputBufferSize == 0) ? " (default)" : "");
  100837. +
  100838. + /* Get the maximum number of threads. */
  100839. + Identity->threadCount = (threadCount != 0)
  100840. + ? 1 << threadCount
  100841. + : (Identity->chipModel == gcv400) ? 64
  100842. + : (Identity->chipModel == gcv500) ? 128
  100843. + : (Identity->chipModel == gcv530) ? 128
  100844. + : 256;
  100845. +
  100846. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100847. + "Specs: threadCount=%u%s",
  100848. + Identity->threadCount,
  100849. + (threadCount == 0) ? " (default)" : "");
  100850. +
  100851. + /* Get the number of shader cores. */
  100852. + Identity->shaderCoreCount = (shaderCoreCount != 0)
  100853. + ? shaderCoreCount
  100854. + : (Identity->chipModel >= gcv1000) ? 2
  100855. + : 1;
  100856. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100857. + "Specs: shaderCoreCount=%u%s",
  100858. + Identity->shaderCoreCount,
  100859. + (shaderCoreCount == 0) ? " (default)" : "");
  100860. +
  100861. + /* Get the vertex cache size. */
  100862. + Identity->vertexCacheSize = (vertexCacheSize != 0)
  100863. + ? vertexCacheSize
  100864. + : 8;
  100865. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100866. + "Specs: vertexCacheSize=%u%s",
  100867. + Identity->vertexCacheSize,
  100868. + (vertexCacheSize == 0) ? " (default)" : "");
  100869. +
  100870. + /* Get the maximum number of temporary registers. */
  100871. + Identity->registerMax = (registerMax != 0)
  100872. + /* Maximum of registerMax/4 registers are accessible to 1 shader */
  100873. + ? 1 << registerMax
  100874. + : (Identity->chipModel == gcv400) ? 32
  100875. + : 64;
  100876. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100877. + "Specs: registerMax=%u%s",
  100878. + Identity->registerMax,
  100879. + (registerMax == 0) ? " (default)" : "");
  100880. +
  100881. + /* Get the instruction count. */
  100882. + Identity->instructionCount = (instructionCount == 0) ? 256
  100883. + : (instructionCount == 1) ? 1024
  100884. + : (instructionCount == 2) ? 2048
  100885. + : (instructionCount == 0xFF) ? 512
  100886. + : 256;
  100887. +
  100888. + if (Identity->instructionCount == 256)
  100889. + {
  100890. + if ((Identity->chipModel == gcv2000 && Identity->chipRevision == 0x5108)
  100891. + || Identity->chipModel == gcv880)
  100892. + {
  100893. + Identity->instructionCount = 512;
  100894. + }
  100895. + }
  100896. +
  100897. + 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))))))))
  100898. + {
  100899. + Identity->instructionCount = 512;
  100900. + }
  100901. +
  100902. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100903. + "Specs: instructionCount=%u%s",
  100904. + Identity->instructionCount,
  100905. + (instructionCount == 0) ? " (default)" : "");
  100906. +
  100907. + /* Get the number of constants. */
  100908. + Identity->numConstants = (numConstants == 0) ? 168 : numConstants;
  100909. +
  100910. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100911. + "Specs: numConstants=%u%s",
  100912. + Identity->numConstants,
  100913. + (numConstants == 0) ? " (default)" : "");
  100914. +
  100915. + /* Get the buffer size. */
  100916. + Identity->bufferSize = bufferSize;
  100917. +
  100918. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  100919. + "Specs: bufferSize=%u%s",
  100920. + Identity->bufferSize,
  100921. + (bufferSize == 0) ? " (default)" : "");
  100922. +
  100923. +
  100924. + if (varyingsCount != 0)
  100925. + {
  100926. + /* Bug 4480. */
  100927. + /*Identity->varyingsCount = varyingsCount;*/
  100928. + Identity->varyingsCount = 12;
  100929. + }
  100930. + 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))))))))
  100931. + {
  100932. + Identity->varyingsCount = 12;
  100933. + }
  100934. + else
  100935. + {
  100936. + Identity->varyingsCount = 8;
  100937. + }
  100938. +
  100939. + /* For some cores, it consumes two varying for position, so the max varying vectors should minus one. */
  100940. + if ((Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) ||
  100941. + (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5208) ||
  100942. + ((Identity->chipModel == gcv2100 || Identity->chipModel == gcv2000) && Identity->chipRevision == 0x5108) ||
  100943. + (Identity->chipModel == gcv880 && (Identity->chipRevision == 0x5107 || Identity->chipRevision == 0x5106)))
  100944. + {
  100945. + Identity->varyingsCount -= 1;
  100946. + }
  100947. +
  100948. + Identity->chip2DControl = 0;
  100949. + if (Identity->chipModel == gcv320)
  100950. + {
  100951. + gctUINT32 data;
  100952. +
  100953. + gcmkONERROR(
  100954. + gckOS_ReadRegisterEx(Os,
  100955. + Core,
  100956. + 0x0002C,
  100957. + &data));
  100958. +
  100959. + if ((data != 33956864) &&
  100960. + ((Identity->chipRevision == 0x5007) ||
  100961. + (Identity->chipRevision == 0x5220)))
  100962. + {
  100963. + Identity->chip2DControl |= 0xFF &
  100964. + (Identity->chipRevision == 0x5220 ? 8 :
  100965. + (Identity->chipRevision == 0x5007 ? 12 : 0));
  100966. + }
  100967. +
  100968. + if (Identity->chipRevision == 0x5007)
  100969. + {
  100970. + /* Disable splitting rectangle. */
  100971. + Identity->chip2DControl |= 0x100;
  100972. +
  100973. + /* Enable 2D Flush. */
  100974. + Identity->chip2DControl |= 0x200;
  100975. + }
  100976. + }
  100977. +
  100978. + /* Success. */
  100979. + gcmkFOOTER();
  100980. + return gcvSTATUS_OK;
  100981. +
  100982. +OnError:
  100983. + /* Return the status. */
  100984. + gcmkFOOTER();
  100985. + return status;
  100986. +}
  100987. +
  100988. +#if gcdPOWEROFF_TIMEOUT
  100989. +void
  100990. +_PowerTimerFunction(
  100991. + gctPOINTER Data
  100992. + )
  100993. +{
  100994. + gckHARDWARE hardware = (gckHARDWARE)Data;
  100995. + gcmkVERIFY_OK(
  100996. + gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
  100997. +}
  100998. +#endif
  100999. +
  101000. +static gceSTATUS
  101001. +_VerifyDMA(
  101002. + IN gckOS Os,
  101003. + IN gceCORE Core,
  101004. + gctUINT32_PTR Address1,
  101005. + gctUINT32_PTR Address2,
  101006. + gctUINT32_PTR State1,
  101007. + gctUINT32_PTR State2
  101008. + )
  101009. +{
  101010. + gceSTATUS status;
  101011. + gctUINT32 i;
  101012. +
  101013. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State1));
  101014. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address1));
  101015. +
  101016. + for (i = 0; i < 500; i += 1)
  101017. + {
  101018. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State2));
  101019. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address2));
  101020. +
  101021. + if (*Address1 != *Address2)
  101022. + {
  101023. + break;
  101024. + }
  101025. +
  101026. + if (*State1 != *State2)
  101027. + {
  101028. + break;
  101029. + }
  101030. + }
  101031. +
  101032. +OnError:
  101033. + return status;
  101034. +}
  101035. +
  101036. +static gceSTATUS
  101037. +_DumpDebugRegisters(
  101038. + IN gckOS Os,
  101039. + IN gceCORE Core,
  101040. + IN gcsiDEBUG_REGISTERS_PTR Descriptor
  101041. + )
  101042. +{
  101043. + gceSTATUS status = gcvSTATUS_OK;
  101044. + gctUINT32 select;
  101045. + gctUINT32 data = 0;
  101046. + gctUINT i;
  101047. +
  101048. + gcmkHEADER_ARG("Os=0x%X Descriptor=0x%X", Os, Descriptor);
  101049. +
  101050. + gcmkPRINT_N(4, " %s debug registers:\n", Descriptor->module);
  101051. +
  101052. + for (i = 0; i < Descriptor->count; i += 1)
  101053. + {
  101054. + select = i << Descriptor->shift;
  101055. +
  101056. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
  101057. +#if gcdFPGA_BUILD
  101058. + gcmkONERROR(gckOS_Delay(Os, 1000));
  101059. +#endif
  101060. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
  101061. +
  101062. + gcmkPRINT_N(12, " [0x%02X] 0x%08X\n", i, data);
  101063. + }
  101064. +
  101065. + select = 0xF << Descriptor->shift;
  101066. +
  101067. + for (i = 0; i < 500; i += 1)
  101068. + {
  101069. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
  101070. +#if gcdFPGA_BUILD
  101071. + gcmkONERROR(gckOS_Delay(Os, 1000));
  101072. +#endif
  101073. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
  101074. +
  101075. + if (data == Descriptor->signature)
  101076. + {
  101077. + break;
  101078. + }
  101079. + }
  101080. +
  101081. + if (i == 500)
  101082. + {
  101083. + gcmkPRINT_N(4, " failed to obtain the signature (read 0x%08X).\n", data);
  101084. + }
  101085. + else
  101086. + {
  101087. + gcmkPRINT_N(8, " signature = 0x%08X (%d read attempt(s))\n", data, i + 1);
  101088. + }
  101089. +
  101090. +OnError:
  101091. + /* Return the error. */
  101092. + gcmkFOOTER();
  101093. + return status;
  101094. +}
  101095. +
  101096. +static gceSTATUS
  101097. +_IsGPUPresent(
  101098. + IN gckHARDWARE Hardware
  101099. + )
  101100. +{
  101101. + gceSTATUS status;
  101102. + gcsHAL_QUERY_CHIP_IDENTITY identity;
  101103. + gctUINT32 control;
  101104. +
  101105. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101106. +
  101107. + /* Verify the arguments. */
  101108. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101109. +
  101110. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  101111. + Hardware->core,
  101112. + 0x00000,
  101113. + &control));
  101114. +
  101115. + 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)));
  101116. + 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)));
  101117. +
  101118. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101119. + Hardware->core,
  101120. + 0x00000,
  101121. + control));
  101122. +
  101123. + /* Identify the hardware. */
  101124. + gcmkONERROR(_IdentifyHardware(Hardware->os,
  101125. + Hardware->core,
  101126. + &identity));
  101127. +
  101128. + /* Check if these are the same values as saved before. */
  101129. + if ((Hardware->identity.chipModel != identity.chipModel)
  101130. + || (Hardware->identity.chipRevision != identity.chipRevision)
  101131. + || (Hardware->identity.chipFeatures != identity.chipFeatures)
  101132. + || (Hardware->identity.chipMinorFeatures != identity.chipMinorFeatures)
  101133. + || (Hardware->identity.chipMinorFeatures1 != identity.chipMinorFeatures1)
  101134. + || (Hardware->identity.chipMinorFeatures2 != identity.chipMinorFeatures2)
  101135. + )
  101136. + {
  101137. + gcmkPRINT("[galcore]: GPU is not present.");
  101138. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  101139. + }
  101140. +
  101141. + /* Success. */
  101142. + gcmkFOOTER_NO();
  101143. + return gcvSTATUS_OK;
  101144. +
  101145. +OnError:
  101146. + /* Return the error. */
  101147. + gcmkFOOTER();
  101148. + return status;
  101149. +}
  101150. +
  101151. +gceSTATUS
  101152. +_FlushCache(
  101153. + gckHARDWARE Hardware,
  101154. + gckCOMMAND Command
  101155. + )
  101156. +{
  101157. + gceSTATUS status;
  101158. + gctSIZE_T bytes, requested;
  101159. + gctPOINTER buffer;
  101160. +
  101161. + /* Get the size of the flush command. */
  101162. + gcmkONERROR(gckHARDWARE_Flush(Hardware,
  101163. + gcvFLUSH_ALL,
  101164. + gcvNULL,
  101165. + &requested));
  101166. +
  101167. + /* Reserve space in the command queue. */
  101168. + gcmkONERROR(gckCOMMAND_Reserve(Command,
  101169. + requested,
  101170. + &buffer,
  101171. + &bytes));
  101172. +
  101173. + /* Append a flush. */
  101174. + gcmkONERROR(gckHARDWARE_Flush(
  101175. + Hardware, gcvFLUSH_ALL, buffer, &bytes
  101176. + ));
  101177. +
  101178. + /* Execute the command queue. */
  101179. + gcmkONERROR(gckCOMMAND_Execute(Command, requested));
  101180. +
  101181. + return gcvSTATUS_OK;
  101182. +
  101183. +OnError:
  101184. + return status;
  101185. +}
  101186. +
  101187. +/******************************************************************************\
  101188. +****************************** gckHARDWARE API code *****************************
  101189. +\******************************************************************************/
  101190. +
  101191. +/*******************************************************************************
  101192. +**
  101193. +** gckHARDWARE_Construct
  101194. +**
  101195. +** Construct a new gckHARDWARE object.
  101196. +**
  101197. +** INPUT:
  101198. +**
  101199. +** gckOS Os
  101200. +** Pointer to an initialized gckOS object.
  101201. +**
  101202. +** gceCORE Core
  101203. +** Specified core.
  101204. +**
  101205. +** OUTPUT:
  101206. +**
  101207. +** gckHARDWARE * Hardware
  101208. +** Pointer to a variable that will hold the pointer to the gckHARDWARE
  101209. +** object.
  101210. +*/
  101211. +gceSTATUS
  101212. +gckHARDWARE_Construct(
  101213. + IN gckOS Os,
  101214. + IN gceCORE Core,
  101215. + OUT gckHARDWARE * Hardware
  101216. + )
  101217. +{
  101218. + gceSTATUS status;
  101219. + gckHARDWARE hardware = gcvNULL;
  101220. + gctUINT16 data = 0xff00;
  101221. + gctUINT32 axi_ot;
  101222. + gctPOINTER pointer = gcvNULL;
  101223. +
  101224. + gcmkHEADER_ARG("Os=0x%x", Os);
  101225. +
  101226. + /* Verify the arguments. */
  101227. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  101228. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  101229. +
  101230. + /* Enable the GPU. */
  101231. + gcmkONERROR(gckOS_SetGPUPower(Os, Core, gcvTRUE, gcvTRUE));
  101232. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  101233. + Core,
  101234. + 0x00000,
  101235. + 0x00000900));
  101236. +
  101237. + /* Allocate the gckHARDWARE object. */
  101238. + gcmkONERROR(gckOS_Allocate(Os,
  101239. + gcmSIZEOF(struct _gckHARDWARE),
  101240. + &pointer));
  101241. +
  101242. + hardware = (gckHARDWARE) pointer;
  101243. +
  101244. + /* Initialize the gckHARDWARE object. */
  101245. + hardware->object.type = gcvOBJ_HARDWARE;
  101246. + hardware->os = Os;
  101247. + hardware->core = Core;
  101248. +
  101249. + /* Identify the hardware. */
  101250. + gcmkONERROR(_IdentifyHardware(Os, Core, &hardware->identity));
  101251. +
  101252. + /* Determine the hardware type */
  101253. + switch (hardware->identity.chipModel)
  101254. + {
  101255. + case gcv350:
  101256. + case gcv355:
  101257. + hardware->type = gcvHARDWARE_VG;
  101258. + break;
  101259. +
  101260. + case gcv300:
  101261. + case gcv320:
  101262. + case gcv420:
  101263. + hardware->type = gcvHARDWARE_2D;
  101264. + /*set outstanding limit*/
  101265. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
  101266. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  101267. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
  101268. + break;
  101269. +
  101270. + default:
  101271. + hardware->type = gcvHARDWARE_3D;
  101272. + if(hardware->identity.chipModel == gcv880)
  101273. + {
  101274. + /*set outstanding limit*/
  101275. + gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
  101276. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  101277. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
  101278. + }
  101279. +
  101280. + 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)))))) ))
  101281. + {
  101282. + hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D);
  101283. + }
  101284. + }
  101285. +
  101286. + hardware->powerBaseAddress
  101287. + = ((hardware->identity.chipModel == gcv300)
  101288. + && (hardware->identity.chipRevision < 0x2000))
  101289. + ? 0x0100
  101290. + : 0x0000;
  101291. +
  101292. + /* _ResetGPU need powerBaseAddress. */
  101293. + status = _ResetGPU(hardware, Os, Core);
  101294. +
  101295. + if (status != gcvSTATUS_OK)
  101296. + {
  101297. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  101298. + "_ResetGPU failed: status=%d\n", status);
  101299. + }
  101300. +
  101301. + hardware->powerMutex = gcvNULL;
  101302. +
  101303. + hardware->mmuVersion
  101304. + = (((((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)))))) );
  101305. +
  101306. + /* Determine whether bug fixes #1 are present. */
  101307. + 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)))))));
  101308. +
  101309. + /* Check if big endian */
  101310. + hardware->bigEndian = (*(gctUINT8 *)&data == 0xff);
  101311. +
  101312. + /* Initialize the fast clear. */
  101313. + gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
  101314. +
  101315. +#if !gcdENABLE_128B_MERGE
  101316. +
  101317. + 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))))))))
  101318. + {
  101319. + /* 128B merge is turned on by default. Disable it. */
  101320. + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0));
  101321. + }
  101322. +
  101323. +#endif
  101324. +
  101325. + /* Set power state to ON. */
  101326. + hardware->chipPowerState = gcvPOWER_ON;
  101327. + hardware->clockState = gcvTRUE;
  101328. + hardware->powerState = gcvTRUE;
  101329. + hardware->lastWaitLink = ~0U;
  101330. + hardware->globalSemaphore = gcvNULL;
  101331. +#if gcdENABLE_FSCALE_VAL_ADJUST
  101332. + hardware->powerOnFscaleVal = 64;
  101333. +#endif
  101334. +
  101335. + gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
  101336. + gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
  101337. + hardware->startIsr = gcvNULL;
  101338. + hardware->stopIsr = gcvNULL;
  101339. +
  101340. +#if gcdPOWEROFF_TIMEOUT
  101341. + hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
  101342. +
  101343. + gcmkVERIFY_OK(gckOS_CreateTimer(Os,
  101344. + _PowerTimerFunction,
  101345. + (gctPOINTER)hardware,
  101346. + &hardware->powerOffTimer));
  101347. +#endif
  101348. +
  101349. + gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
  101350. +
  101351. +#if gcdLINK_QUEUE_SIZE
  101352. + hardware->linkQueue.front = 0;
  101353. + hardware->linkQueue.rear = 0;
  101354. + hardware->linkQueue.count = 0;
  101355. +#endif
  101356. +
  101357. + /* Enable power management by default. */
  101358. + hardware->powerManagement = gcvTRUE;
  101359. +
  101360. + /* Disable profiler by default */
  101361. + hardware->gpuProfiler = gcvFALSE;
  101362. +
  101363. + /* Return pointer to the gckHARDWARE object. */
  101364. + *Hardware = hardware;
  101365. +
  101366. + /* Success. */
  101367. + gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware);
  101368. + return gcvSTATUS_OK;
  101369. +
  101370. +OnError:
  101371. + /* Roll back. */
  101372. + if (hardware != gcvNULL)
  101373. + {
  101374. + /* Turn off the power. */
  101375. + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, Core, gcvFALSE, gcvFALSE));
  101376. +
  101377. + if (hardware->globalSemaphore != gcvNULL)
  101378. + {
  101379. + /* Destroy the global semaphore. */
  101380. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Os,
  101381. + hardware->globalSemaphore));
  101382. + }
  101383. +
  101384. + if (hardware->powerMutex != gcvNULL)
  101385. + {
  101386. + /* Destroy the power mutex. */
  101387. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
  101388. + }
  101389. +
  101390. +#if gcdPOWEROFF_TIMEOUT
  101391. + if (hardware->powerOffTimer != gcvNULL)
  101392. + {
  101393. + gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
  101394. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
  101395. + }
  101396. +#endif
  101397. +
  101398. + if (hardware->pageTableDirty != gcvNULL)
  101399. + {
  101400. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
  101401. + }
  101402. +
  101403. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
  101404. + }
  101405. +
  101406. + /* Return the status. */
  101407. + gcmkFOOTER();
  101408. + return status;
  101409. +}
  101410. +
  101411. +/*******************************************************************************
  101412. +**
  101413. +** gckHARDWARE_Destroy
  101414. +**
  101415. +** Destroy an gckHARDWARE object.
  101416. +**
  101417. +** INPUT:
  101418. +**
  101419. +** gckHARDWARE Hardware
  101420. +** Pointer to the gckHARDWARE object that needs to be destroyed.
  101421. +**
  101422. +** OUTPUT:
  101423. +**
  101424. +** Nothing.
  101425. +*/
  101426. +gceSTATUS
  101427. +gckHARDWARE_Destroy(
  101428. + IN gckHARDWARE Hardware
  101429. + )
  101430. +{
  101431. + gceSTATUS status;
  101432. +
  101433. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101434. +
  101435. + /* Verify the arguments. */
  101436. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101437. +
  101438. + /* Destroy the power semaphore. */
  101439. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os,
  101440. + Hardware->globalSemaphore));
  101441. +
  101442. + /* Destroy the power mutex. */
  101443. + gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex));
  101444. +
  101445. +#if gcdPOWEROFF_TIMEOUT
  101446. + gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
  101447. + gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
  101448. +#endif
  101449. +
  101450. + gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
  101451. +
  101452. + /* Mark the object as unknown. */
  101453. + Hardware->object.type = gcvOBJ_UNKNOWN;
  101454. +
  101455. + /* Free the object. */
  101456. + gcmkONERROR(gcmkOS_SAFE_FREE(Hardware->os, Hardware));
  101457. +
  101458. + /* Success. */
  101459. + gcmkFOOTER_NO();
  101460. + return gcvSTATUS_OK;
  101461. +
  101462. +OnError:
  101463. + gcmkFOOTER();
  101464. + return status;
  101465. +}
  101466. +
  101467. +/*******************************************************************************
  101468. +**
  101469. +** gckHARDWARE_GetType
  101470. +**
  101471. +** Get the hardware type.
  101472. +**
  101473. +** INPUT:
  101474. +**
  101475. +** gckHARDWARE Harwdare
  101476. +** Pointer to an gckHARDWARE object.
  101477. +**
  101478. +** OUTPUT:
  101479. +**
  101480. +** gceHARDWARE_TYPE * Type
  101481. +** Pointer to a variable that receives the type of hardware object.
  101482. +*/
  101483. +gceSTATUS
  101484. +gckHARDWARE_GetType(
  101485. + IN gckHARDWARE Hardware,
  101486. + OUT gceHARDWARE_TYPE * Type
  101487. + )
  101488. +{
  101489. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101490. + gcmkVERIFY_ARGUMENT(Type != gcvNULL);
  101491. +
  101492. + *Type = Hardware->type;
  101493. +
  101494. + gcmkFOOTER_ARG("*Type=%d", *Type);
  101495. + return gcvSTATUS_OK;
  101496. +}
  101497. +
  101498. +/*******************************************************************************
  101499. +**
  101500. +** gckHARDWARE_InitializeHardware
  101501. +**
  101502. +** Initialize the hardware.
  101503. +**
  101504. +** INPUT:
  101505. +**
  101506. +** gckHARDWARE Hardware
  101507. +** Pointer to the gckHARDWARE object.
  101508. +**
  101509. +** OUTPUT:
  101510. +**
  101511. +** Nothing.
  101512. +*/
  101513. +gceSTATUS
  101514. +gckHARDWARE_InitializeHardware(
  101515. + IN gckHARDWARE Hardware
  101516. + )
  101517. +{
  101518. + gceSTATUS status;
  101519. + gctUINT32 baseAddress;
  101520. + gctUINT32 chipRev;
  101521. + gctUINT32 control;
  101522. +
  101523. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101524. +
  101525. + /* Verify the arguments. */
  101526. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101527. +
  101528. + /* Read the chip revision register. */
  101529. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  101530. + Hardware->core,
  101531. + 0x00024,
  101532. + &chipRev));
  101533. +
  101534. + if (chipRev != Hardware->identity.chipRevision)
  101535. + {
  101536. + /* Chip is not there! */
  101537. + gcmkONERROR(gcvSTATUS_CONTEXT_LOSSED);
  101538. + }
  101539. +
  101540. + /* Disable isolate GPU bit. */
  101541. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101542. + Hardware->core,
  101543. + 0x00000,
  101544. + ((((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)))));
  101545. +
  101546. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  101547. + Hardware->core,
  101548. + 0x00000,
  101549. + &control));
  101550. +
  101551. + /* Enable debug register. */
  101552. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101553. + Hardware->core,
  101554. + 0x00000,
  101555. + ((((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)))));
  101556. +
  101557. + /* Reset memory counters. */
  101558. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101559. + Hardware->core,
  101560. + 0x0003C,
  101561. + ~0U));
  101562. +
  101563. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101564. + Hardware->core,
  101565. + 0x0003C,
  101566. + 0));
  101567. +
  101568. + /* Get the system's physical base address. */
  101569. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  101570. +
  101571. + /* Program the base addesses. */
  101572. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101573. + Hardware->core,
  101574. + 0x0041C,
  101575. + baseAddress));
  101576. +
  101577. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101578. + Hardware->core,
  101579. + 0x00418,
  101580. + baseAddress));
  101581. +
  101582. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101583. + Hardware->core,
  101584. + 0x00428,
  101585. + baseAddress));
  101586. +
  101587. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101588. + Hardware->core,
  101589. + 0x00420,
  101590. + baseAddress));
  101591. +
  101592. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101593. + Hardware->core,
  101594. + 0x00424,
  101595. + baseAddress));
  101596. +
  101597. +#if !VIVANTE_PROFILER
  101598. + {
  101599. + gctUINT32 data;
  101600. +
  101601. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  101602. + Hardware->core,
  101603. + Hardware->powerBaseAddress +
  101604. + 0x00100,
  101605. + &data));
  101606. +
  101607. + /* Enable clock gating. */
  101608. + 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)));
  101609. +
  101610. + if ((Hardware->identity.chipRevision == 0x4301)
  101611. + || (Hardware->identity.chipRevision == 0x4302)
  101612. + )
  101613. + {
  101614. + /* Disable stall module level clock gating for 4.3.0.1 and 4.3.0.2
  101615. + ** revisions. */
  101616. + 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)));
  101617. + }
  101618. +
  101619. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101620. + Hardware->core,
  101621. + Hardware->powerBaseAddress
  101622. + + 0x00100,
  101623. + data));
  101624. +
  101625. +#ifndef VIVANTE_NO_3D
  101626. + /* Disable PE clock gating on revs < 5.0 when HZ is present without a
  101627. + ** bug fix. */
  101628. + if ((Hardware->identity.chipRevision < 0x5000)
  101629. + && ((((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)))))))
  101630. + && ((((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)))))))
  101631. + )
  101632. + {
  101633. + gcmkONERROR(
  101634. + gckOS_ReadRegisterEx(Hardware->os,
  101635. + Hardware->core,
  101636. + Hardware->powerBaseAddress
  101637. + + 0x00104,
  101638. + &data));
  101639. +
  101640. + /* Disable PE clock gating. */
  101641. + 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)));
  101642. +
  101643. + gcmkONERROR(
  101644. + gckOS_WriteRegisterEx(Hardware->os,
  101645. + Hardware->core,
  101646. + Hardware->powerBaseAddress
  101647. + + 0x00104,
  101648. + data));
  101649. + }
  101650. +
  101651. +#endif
  101652. + }
  101653. +#endif
  101654. +
  101655. + /* Special workaround for this core
  101656. + ** Make sure pulse eater kicks in only when SH is idle */
  101657. + if (Hardware->identity.chipModel == gcv4000 &&
  101658. + Hardware->identity.chipRevision == 0x5208)
  101659. + {
  101660. + gcmkONERROR(
  101661. + gckOS_WriteRegisterEx(Hardware->os,
  101662. + Hardware->core,
  101663. + 0x0010C,
  101664. + ((((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)))));
  101665. + }
  101666. +
  101667. + if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvFALSE)
  101668. + || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) && (Hardware->identity.chipRevision < 0x5422))
  101669. + )
  101670. + {
  101671. + gctUINT32 data;
  101672. +
  101673. + gcmkONERROR(
  101674. + gckOS_ReadRegisterEx(Hardware->os,
  101675. + Hardware->core,
  101676. + Hardware->powerBaseAddress
  101677. + + 0x00104,
  101678. + &data));
  101679. +
  101680. +
  101681. + 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)));
  101682. +
  101683. +
  101684. + gcmkONERROR(
  101685. + gckOS_WriteRegisterEx(Hardware->os,
  101686. + Hardware->core,
  101687. + Hardware->powerBaseAddress
  101688. + + 0x00104,
  101689. + data));
  101690. + }
  101691. +
  101692. + /* Special workaround for this core
  101693. + ** Make sure FE and TX are on different buses */
  101694. + if ((Hardware->identity.chipModel == gcv2000)
  101695. + && (Hardware->identity.chipRevision == 0x5108))
  101696. + {
  101697. + gctUINT32 data;
  101698. +
  101699. + gcmkONERROR(
  101700. + gckOS_ReadRegisterEx(Hardware->os,
  101701. + Hardware->core,
  101702. + 0x00480,
  101703. + &data));
  101704. +
  101705. + /* Set FE bus to one, TX bus to zero */
  101706. + 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)));
  101707. + 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)));
  101708. +
  101709. + gcmkONERROR(
  101710. + gckOS_WriteRegisterEx(Hardware->os,
  101711. + Hardware->core,
  101712. + 0x00480,
  101713. + data));
  101714. + }
  101715. +
  101716. + /* Test if MMU is initialized. */
  101717. + if ((Hardware->kernel != gcvNULL)
  101718. + && (Hardware->kernel->mmu != gcvNULL)
  101719. + )
  101720. + {
  101721. + /* Reset MMU. */
  101722. + if (Hardware->mmuVersion == 0)
  101723. + {
  101724. + gcmkONERROR(
  101725. + gckHARDWARE_SetMMU(Hardware,
  101726. + Hardware->kernel->mmu->pageTableLogical));
  101727. + }
  101728. + }
  101729. +
  101730. + if (Hardware->identity.chipModel >= gcv400
  101731. + && Hardware->identity.chipModel != gcv420
  101732. + && (((((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)
  101733. + )
  101734. + {
  101735. + gctUINT32 data;
  101736. +
  101737. + gcmkONERROR(
  101738. + gckOS_ReadRegisterEx(Hardware->os,
  101739. + Hardware->core,
  101740. + Hardware->powerBaseAddress
  101741. + + 0x00104,
  101742. + &data));
  101743. +
  101744. + /* Disable PA clock gating. */
  101745. + 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)));
  101746. +
  101747. + gcmkONERROR(
  101748. + gckOS_WriteRegisterEx(Hardware->os,
  101749. + Hardware->core,
  101750. + Hardware->powerBaseAddress
  101751. + + 0x00104,
  101752. + data));
  101753. + }
  101754. +
  101755. +#if gcdHZ_L2_DISALBE
  101756. + /* Disable HZ-L2. */
  101757. + 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 ||
  101758. + ((((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)
  101759. + {
  101760. + gctUINT32 data;
  101761. +
  101762. + gcmkONERROR(
  101763. + gckOS_ReadRegisterEx(Hardware->os,
  101764. + Hardware->core,
  101765. + 0x00414,
  101766. + &data));
  101767. +
  101768. + 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)));
  101769. +
  101770. + gcmkONERROR(
  101771. + gckOS_WriteRegisterEx(Hardware->os,
  101772. + Hardware->core,
  101773. + 0x00414,
  101774. + data));
  101775. + }
  101776. +#endif
  101777. +
  101778. + /* Limit 2D outstanding request. */
  101779. + if(Hardware->identity.chipModel == gcv880)
  101780. + {
  101781. + gctUINT32 axi_ot;
  101782. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot));
  101783. + axi_ot = (axi_ot & (~0xFF)) | 0x10;
  101784. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot));
  101785. + }
  101786. +
  101787. + if (Hardware->identity.chip2DControl & 0xFF)
  101788. + {
  101789. + gctUINT32 data;
  101790. +
  101791. + gcmkONERROR(
  101792. + gckOS_ReadRegisterEx(Hardware->os,
  101793. + Hardware->core,
  101794. + 0x00414,
  101795. + &data));
  101796. + 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)));
  101797. +
  101798. + gcmkONERROR(
  101799. + gckOS_WriteRegisterEx(Hardware->os,
  101800. + Hardware->core,
  101801. + 0x00414,
  101802. + data));
  101803. + }
  101804. +
  101805. + /* Update GPU AXI cache atttribute. */
  101806. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  101807. + Hardware->core,
  101808. + 0x00008,
  101809. + 0x00002200));
  101810. +
  101811. + /* Success. */
  101812. + gcmkFOOTER_NO();
  101813. + return gcvSTATUS_OK;
  101814. +
  101815. +OnError:
  101816. + /* Return the error. */
  101817. + gcmkFOOTER();
  101818. + return status;
  101819. +}
  101820. +
  101821. +/*******************************************************************************
  101822. +**
  101823. +** gckHARDWARE_QueryMemory
  101824. +**
  101825. +** Query the amount of memory available on the hardware.
  101826. +**
  101827. +** INPUT:
  101828. +**
  101829. +** gckHARDWARE Hardware
  101830. +** Pointer to the gckHARDWARE object.
  101831. +**
  101832. +** OUTPUT:
  101833. +**
  101834. +** gctSIZE_T * InternalSize
  101835. +** Pointer to a variable that will hold the size of the internal video
  101836. +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
  101837. +** internal memory will be returned.
  101838. +**
  101839. +** gctUINT32 * InternalBaseAddress
  101840. +** Pointer to a variable that will hold the hardware's base address for
  101841. +** the internal video memory. This pointer cannot be gcvNULL if
  101842. +** 'InternalSize' is also non-gcvNULL.
  101843. +**
  101844. +** gctUINT32 * InternalAlignment
  101845. +** Pointer to a variable that will hold the hardware's base address for
  101846. +** the internal video memory. This pointer cannot be gcvNULL if
  101847. +** 'InternalSize' is also non-gcvNULL.
  101848. +**
  101849. +** gctSIZE_T * ExternalSize
  101850. +** Pointer to a variable that will hold the size of the external video
  101851. +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
  101852. +** external memory will be returned.
  101853. +**
  101854. +** gctUINT32 * ExternalBaseAddress
  101855. +** Pointer to a variable that will hold the hardware's base address for
  101856. +** the external video memory. This pointer cannot be gcvNULL if
  101857. +** 'ExternalSize' is also non-gcvNULL.
  101858. +**
  101859. +** gctUINT32 * ExternalAlignment
  101860. +** Pointer to a variable that will hold the hardware's base address for
  101861. +** the external video memory. This pointer cannot be gcvNULL if
  101862. +** 'ExternalSize' is also non-gcvNULL.
  101863. +**
  101864. +** gctUINT32 * HorizontalTileSize
  101865. +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
  101866. +** gcvNULL, no horizontal pixel per tile will be returned.
  101867. +**
  101868. +** gctUINT32 * VerticalTileSize
  101869. +** Number of vertical pixels per tile. If 'VerticalTileSize' is
  101870. +** gcvNULL, no vertical pixel per tile will be returned.
  101871. +*/
  101872. +gceSTATUS
  101873. +gckHARDWARE_QueryMemory(
  101874. + IN gckHARDWARE Hardware,
  101875. + OUT gctSIZE_T * InternalSize,
  101876. + OUT gctUINT32 * InternalBaseAddress,
  101877. + OUT gctUINT32 * InternalAlignment,
  101878. + OUT gctSIZE_T * ExternalSize,
  101879. + OUT gctUINT32 * ExternalBaseAddress,
  101880. + OUT gctUINT32 * ExternalAlignment,
  101881. + OUT gctUINT32 * HorizontalTileSize,
  101882. + OUT gctUINT32 * VerticalTileSize
  101883. + )
  101884. +{
  101885. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101886. +
  101887. + /* Verify the arguments. */
  101888. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101889. +
  101890. + if (InternalSize != gcvNULL)
  101891. + {
  101892. + /* No internal memory. */
  101893. + *InternalSize = 0;
  101894. + }
  101895. +
  101896. + if (ExternalSize != gcvNULL)
  101897. + {
  101898. + /* No external memory. */
  101899. + *ExternalSize = 0;
  101900. + }
  101901. +
  101902. + if (HorizontalTileSize != gcvNULL)
  101903. + {
  101904. + /* 4x4 tiles. */
  101905. + *HorizontalTileSize = 4;
  101906. + }
  101907. +
  101908. + if (VerticalTileSize != gcvNULL)
  101909. + {
  101910. + /* 4x4 tiles. */
  101911. + *VerticalTileSize = 4;
  101912. + }
  101913. +
  101914. + /* Success. */
  101915. + gcmkFOOTER_ARG("*InternalSize=%lu *InternalBaseAddress=0x%08x "
  101916. + "*InternalAlignment=0x%08x *ExternalSize=%lu "
  101917. + "*ExternalBaseAddress=0x%08x *ExtenalAlignment=0x%08x "
  101918. + "*HorizontalTileSize=%u *VerticalTileSize=%u",
  101919. + gcmOPT_VALUE(InternalSize),
  101920. + gcmOPT_VALUE(InternalBaseAddress),
  101921. + gcmOPT_VALUE(InternalAlignment),
  101922. + gcmOPT_VALUE(ExternalSize),
  101923. + gcmOPT_VALUE(ExternalBaseAddress),
  101924. + gcmOPT_VALUE(ExternalAlignment),
  101925. + gcmOPT_VALUE(HorizontalTileSize),
  101926. + gcmOPT_VALUE(VerticalTileSize));
  101927. + return gcvSTATUS_OK;
  101928. +}
  101929. +
  101930. +/*******************************************************************************
  101931. +**
  101932. +** gckHARDWARE_QueryChipIdentity
  101933. +**
  101934. +** Query the identity of the hardware.
  101935. +**
  101936. +** INPUT:
  101937. +**
  101938. +** gckHARDWARE Hardware
  101939. +** Pointer to the gckHARDWARE object.
  101940. +**
  101941. +** OUTPUT:
  101942. +**
  101943. +** gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  101944. +** Pointer to the identity structure.
  101945. +**
  101946. +*/
  101947. +gceSTATUS
  101948. +gckHARDWARE_QueryChipIdentity(
  101949. + IN gckHARDWARE Hardware,
  101950. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  101951. + )
  101952. +{
  101953. + gctUINT32 features;
  101954. +
  101955. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  101956. +
  101957. + /* Verify the arguments. */
  101958. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  101959. + gcmkVERIFY_ARGUMENT(Identity != gcvNULL);
  101960. +
  101961. + /* Return chip model and revision. */
  101962. + Identity->chipModel = Hardware->identity.chipModel;
  101963. + Identity->chipRevision = Hardware->identity.chipRevision;
  101964. +
  101965. + /* Return feature set. */
  101966. + features = Hardware->identity.chipFeatures;
  101967. +
  101968. + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  101969. + {
  101970. + /* Override fast clear by command line. */
  101971. + 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)));
  101972. + }
  101973. +
  101974. + if ((((((gctUINT32) (features)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ))
  101975. + {
  101976. + /* Override compression by command line. */
  101977. + 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)));
  101978. + }
  101979. +
  101980. + /* Mark 2D pipe as available for GC500.0 through GC500.2 and GC300,
  101981. + ** since they did not have this bit. */
  101982. + if (((Hardware->identity.chipModel == gcv500) && (Hardware->identity.chipRevision <= 2))
  101983. + || (Hardware->identity.chipModel == gcv300)
  101984. + )
  101985. + {
  101986. + 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)));
  101987. + }
  101988. +
  101989. + Identity->chipFeatures = features;
  101990. +
  101991. + /* Return minor features. */
  101992. + Identity->chipMinorFeatures = Hardware->identity.chipMinorFeatures;
  101993. + Identity->chipMinorFeatures1 = Hardware->identity.chipMinorFeatures1;
  101994. + Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2;
  101995. + Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3;
  101996. + Identity->chipMinorFeatures4 = Hardware->identity.chipMinorFeatures4;
  101997. +
  101998. + /* Return chip specs. */
  101999. + Identity->streamCount = Hardware->identity.streamCount;
  102000. + Identity->registerMax = Hardware->identity.registerMax;
  102001. + Identity->threadCount = Hardware->identity.threadCount;
  102002. + Identity->shaderCoreCount = Hardware->identity.shaderCoreCount;
  102003. + Identity->vertexCacheSize = Hardware->identity.vertexCacheSize;
  102004. + Identity->vertexOutputBufferSize = Hardware->identity.vertexOutputBufferSize;
  102005. + Identity->pixelPipes = Hardware->identity.pixelPipes;
  102006. + Identity->instructionCount = Hardware->identity.instructionCount;
  102007. + Identity->numConstants = Hardware->identity.numConstants;
  102008. + Identity->bufferSize = Hardware->identity.bufferSize;
  102009. + Identity->varyingsCount = Hardware->identity.varyingsCount;
  102010. + Identity->superTileMode = Hardware->identity.superTileMode;
  102011. + Identity->chip2DControl = Hardware->identity.chip2DControl;
  102012. +
  102013. + /* Success. */
  102014. + gcmkFOOTER_NO();
  102015. + return gcvSTATUS_OK;
  102016. +}
  102017. +
  102018. +/*******************************************************************************
  102019. +**
  102020. +** gckHARDWARE_SplitMemory
  102021. +**
  102022. +** Split a hardware specific memory address into a pool and offset.
  102023. +**
  102024. +** INPUT:
  102025. +**
  102026. +** gckHARDWARE Hardware
  102027. +** Pointer to the gckHARDWARE object.
  102028. +**
  102029. +** gctUINT32 Address
  102030. +** Address in hardware specific format.
  102031. +**
  102032. +** OUTPUT:
  102033. +**
  102034. +** gcePOOL * Pool
  102035. +** Pointer to a variable that will hold the pool type for the address.
  102036. +**
  102037. +** gctUINT32 * Offset
  102038. +** Pointer to a variable that will hold the offset for the address.
  102039. +*/
  102040. +gceSTATUS
  102041. +gckHARDWARE_SplitMemory(
  102042. + IN gckHARDWARE Hardware,
  102043. + IN gctUINT32 Address,
  102044. + OUT gcePOOL * Pool,
  102045. + OUT gctUINT32 * Offset
  102046. + )
  102047. +{
  102048. + gcmkHEADER_ARG("Hardware=0x%x Addres=0x%08x", Hardware, Address);
  102049. +
  102050. + /* Verify the arguments. */
  102051. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102052. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  102053. + gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
  102054. +
  102055. + if (Hardware->mmuVersion == 0)
  102056. + {
  102057. + /* Dispatch on memory type. */
  102058. + switch ((((((gctUINT32) (Address)) >> (0 ? 31:31)) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) ))
  102059. + {
  102060. + case 0x0:
  102061. + /* System memory. */
  102062. + *Pool = gcvPOOL_SYSTEM;
  102063. + break;
  102064. +
  102065. + case 0x1:
  102066. + /* Virtual memory. */
  102067. + *Pool = gcvPOOL_VIRTUAL;
  102068. + break;
  102069. +
  102070. + default:
  102071. + /* Invalid memory type. */
  102072. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  102073. + return gcvSTATUS_INVALID_ARGUMENT;
  102074. + }
  102075. +
  102076. + /* Return offset of address. */
  102077. + *Offset = (((((gctUINT32) (Address)) >> (0 ? 30:0)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1)))))) );
  102078. + }
  102079. + else
  102080. + {
  102081. + *Pool = gcvPOOL_SYSTEM;
  102082. + *Offset = Address;
  102083. + }
  102084. +
  102085. + /* Success. */
  102086. + gcmkFOOTER_ARG("*Pool=%d *Offset=0x%08x", *Pool, *Offset);
  102087. + return gcvSTATUS_OK;
  102088. +}
  102089. +
  102090. +/*******************************************************************************
  102091. +**
  102092. +** gckHARDWARE_Execute
  102093. +**
  102094. +** Kickstart the hardware's command processor with an initialized command
  102095. +** buffer.
  102096. +**
  102097. +** INPUT:
  102098. +**
  102099. +** gckHARDWARE Hardware
  102100. +** Pointer to the gckHARDWARE object.
  102101. +**
  102102. +** gctPOINTER Logical
  102103. +** Logical address of command buffer.
  102104. +**
  102105. +** gctSIZE_T Bytes
  102106. +** Number of bytes for the prefetch unit (until after the first LINK).
  102107. +**
  102108. +** OUTPUT:
  102109. +**
  102110. +** Nothing.
  102111. +*/
  102112. +gceSTATUS
  102113. +gckHARDWARE_Execute(
  102114. + IN gckHARDWARE Hardware,
  102115. + IN gctPOINTER Logical,
  102116. +#ifdef __QNXNTO__
  102117. + IN gctPOINTER Physical,
  102118. + IN gctBOOL PhysicalAddresses,
  102119. +#endif
  102120. + IN gctSIZE_T Bytes
  102121. + )
  102122. +{
  102123. + gceSTATUS status;
  102124. + gctUINT32 address = 0, control;
  102125. +
  102126. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu",
  102127. + Hardware, Logical, Bytes);
  102128. +
  102129. + /* Verify the arguments. */
  102130. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102131. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  102132. +
  102133. +#ifdef __QNXNTO__
  102134. + if (PhysicalAddresses && (Hardware->mmuVersion == 0))
  102135. + {
  102136. + /* Convert physical into hardware specific address. */
  102137. + gcmkONERROR(
  102138. + gckHARDWARE_ConvertPhysical(Hardware, Physical, &address));
  102139. + }
  102140. + else
  102141. + {
  102142. +#endif
  102143. + /* Convert logical into hardware specific address. */
  102144. + gcmkONERROR(
  102145. + gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
  102146. +#ifdef __QNXNTO__
  102147. + }
  102148. +#endif
  102149. +
  102150. + /* Enable all events. */
  102151. + gcmkONERROR(
  102152. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
  102153. +
  102154. + /* Write address register. */
  102155. + gcmkONERROR(
  102156. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address));
  102157. +
  102158. + /* Build control register. */
  102159. + 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)))
  102160. + | ((((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)));
  102161. +
  102162. + /* Set big endian */
  102163. + if (Hardware->bigEndian)
  102164. + {
  102165. + 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)));
  102166. + }
  102167. +
  102168. + /* Write control register. */
  102169. + gcmkONERROR(
  102170. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
  102171. +
  102172. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102173. + "Started command buffer @ 0x%08x",
  102174. + address);
  102175. +
  102176. + /* Success. */
  102177. + gcmkFOOTER_NO();
  102178. + return gcvSTATUS_OK;
  102179. +
  102180. +OnError:
  102181. + /* Return the status. */
  102182. + gcmkFOOTER();
  102183. + return status;
  102184. +}
  102185. +
  102186. +/*******************************************************************************
  102187. +**
  102188. +** gckHARDWARE_WaitLink
  102189. +**
  102190. +** Append a WAIT/LINK command sequence at the specified location in the command
  102191. +** queue.
  102192. +**
  102193. +** INPUT:
  102194. +**
  102195. +** gckHARDWARE Hardware
  102196. +** Pointer to an gckHARDWARE object.
  102197. +**
  102198. +** gctPOINTER Logical
  102199. +** Pointer to the current location inside the command queue to append
  102200. +** WAIT/LINK command sequence at or gcvNULL just to query the size of the
  102201. +** WAIT/LINK command sequence.
  102202. +**
  102203. +** gctUINT32 Offset
  102204. +** Offset into command buffer required for alignment.
  102205. +**
  102206. +** gctSIZE_T * Bytes
  102207. +** Pointer to the number of bytes available for the WAIT/LINK command
  102208. +** sequence. If 'Logical' is gcvNULL, this argument will be ignored.
  102209. +**
  102210. +** OUTPUT:
  102211. +**
  102212. +** gctSIZE_T * Bytes
  102213. +** Pointer to a variable that will receive the number of bytes required
  102214. +** by the WAIT/LINK command sequence. If 'Bytes' is gcvNULL, nothing will
  102215. +** be returned.
  102216. +**
  102217. +** gctUINT32 * WaitOffset
  102218. +** Pointer to a variable that will receive the offset of the WAIT command
  102219. +** from the specified logcial pointer.
  102220. +** If 'WaitOffset' is gcvNULL nothing will be returned.
  102221. +**
  102222. +** gctSIZE_T * WaitSize
  102223. +** Pointer to a variable that will receive the number of bytes used by
  102224. +** the WAIT command. If 'LinkSize' is gcvNULL nothing will be returned.
  102225. +*/
  102226. +gceSTATUS
  102227. +gckHARDWARE_WaitLink(
  102228. + IN gckHARDWARE Hardware,
  102229. + IN gctPOINTER Logical,
  102230. + IN gctUINT32 Offset,
  102231. + IN OUT gctSIZE_T * Bytes,
  102232. + OUT gctUINT32 * WaitOffset,
  102233. + OUT gctSIZE_T * WaitSize
  102234. + )
  102235. +{
  102236. + static const gctUINT waitCount = 200;
  102237. +
  102238. + gceSTATUS status;
  102239. + gctUINT32 address;
  102240. + gctUINT32_PTR logical;
  102241. + gctSIZE_T bytes;
  102242. +
  102243. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu",
  102244. + Hardware, Logical, Offset, gcmOPT_VALUE(Bytes));
  102245. +
  102246. + /* Verify the arguments. */
  102247. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102248. + gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL));
  102249. +
  102250. + /* Compute number of bytes required. */
  102251. +#if gcd6000_SUPPORT
  102252. + bytes = gcmALIGN(Offset + 96, 8) - Offset;
  102253. +#else
  102254. + bytes = gcmALIGN(Offset + 16, 8) - Offset;
  102255. +#endif
  102256. +
  102257. + /* Cast the input pointer. */
  102258. + logical = (gctUINT32_PTR) Logical;
  102259. +
  102260. + if (logical != gcvNULL)
  102261. + {
  102262. + /* Not enough space? */
  102263. + if (*Bytes < bytes)
  102264. + {
  102265. + /* Command queue too small. */
  102266. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  102267. + }
  102268. +
  102269. + /* Convert logical into hardware specific address. */
  102270. + gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address));
  102271. +
  102272. + /* Store the WAIT/LINK address. */
  102273. + Hardware->lastWaitLink = address;
  102274. +
  102275. + /* Append WAIT(count). */
  102276. + logical[0]
  102277. + = ((((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)))
  102278. + | ((((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)));
  102279. +
  102280. +#if gcd6000_SUPPORT
  102281. + /* Send FE-PE sempahore token. */
  102282. + logical[2]
  102283. + = ((((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)))
  102284. + | ((((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)))
  102285. + | ((((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)));
  102286. +
  102287. + logical[3]
  102288. + = ((((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)))
  102289. + | ((((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)));
  102290. +
  102291. + /* Send FE-PE stall token. */
  102292. + logical[4]
  102293. + = ((((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)));
  102294. +
  102295. + logical[5]
  102296. + = ((((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)))
  102297. + | ((((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)));
  102298. +
  102299. + /*************************************************************/
  102300. + /* Enable chip ID 0. */
  102301. + logical[6] =
  102302. + ((((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)))
  102303. + | (1 << 0);
  102304. +
  102305. + /* Send semaphore from FE to ChipID 1. */
  102306. + logical[8] =
  102307. + ((((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)))
  102308. + | ((((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)))
  102309. + | ((((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)));
  102310. +
  102311. + logical[9] =
  102312. + ((((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)))
  102313. + | ((((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)))
  102314. + | ((((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)));
  102315. +
  102316. + /* Send semaphore from FE to ChipID 1. */
  102317. + logical[10] =
  102318. + ((((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)));
  102319. +
  102320. + logical[11] =
  102321. + ((((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)))
  102322. + | ((((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)))
  102323. + | ((((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)));
  102324. +
  102325. + /*************************************************************/
  102326. + /* Enable chip ID 1. */
  102327. + logical[12] =
  102328. + ((((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)))
  102329. + | (1 << 1);
  102330. +
  102331. + /* Send semaphore from FE to ChipID 1. */
  102332. + logical[14] =
  102333. + ((((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)))
  102334. + | ((((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)))
  102335. + | ((((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)));
  102336. +
  102337. + logical[15] =
  102338. + ((((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)))
  102339. + | ((((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)))
  102340. + | ((((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)));
  102341. +
  102342. + /* Wait for semaphore from ChipID 0. */
  102343. + logical[16] =
  102344. + ((((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)));
  102345. +
  102346. + logical[17] =
  102347. + ((((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)))
  102348. + | ((((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)))
  102349. + | ((((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)));
  102350. +
  102351. + /*************************************************************/
  102352. + /* Enable all chips. */
  102353. + logical[18] =
  102354. + ((((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)))
  102355. + | (0xFFFF);
  102356. +
  102357. + /* LoadState(AQFlush, 1), flush. */
  102358. + logical[20]
  102359. + = ((((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)))
  102360. + | ((((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)))
  102361. + | ((((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)));
  102362. +
  102363. + logical[21]
  102364. + = ((((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)));
  102365. +
  102366. + /* Append LINK(2, address). */
  102367. + logical[22]
  102368. + = ((((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)))
  102369. + | ((((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)));
  102370. +
  102371. + logical[23] = address;
  102372. +#else
  102373. + /* Append LINK(2, address). */
  102374. + logical[2]
  102375. + = ((((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)))
  102376. + | ((((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)));
  102377. +
  102378. + logical[3] = address;
  102379. +
  102380. + gcmkTRACE_ZONE(
  102381. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102382. + "0x%08x: WAIT %u", address, waitCount
  102383. + );
  102384. +
  102385. + gcmkTRACE_ZONE(
  102386. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102387. + "0x%08x: LINK 0x%08x, #%lu",
  102388. + address + 8, address, bytes
  102389. + );
  102390. +#endif
  102391. +
  102392. + if (WaitOffset != gcvNULL)
  102393. + {
  102394. + /* Return the offset pointer to WAIT command. */
  102395. + *WaitOffset = 0;
  102396. + }
  102397. +
  102398. + if (WaitSize != gcvNULL)
  102399. + {
  102400. + /* Return number of bytes used by the WAIT command. */
  102401. + *WaitSize = 8;
  102402. + }
  102403. + }
  102404. +
  102405. + if (Bytes != gcvNULL)
  102406. + {
  102407. + /* Return number of bytes required by the WAIT/LINK command
  102408. + ** sequence. */
  102409. + *Bytes = bytes;
  102410. + }
  102411. +
  102412. + /* Success. */
  102413. + gcmkFOOTER_ARG("*Bytes=%lu *WaitOffset=0x%x *WaitSize=%lu",
  102414. + gcmOPT_VALUE(Bytes), gcmOPT_VALUE(WaitOffset),
  102415. + gcmOPT_VALUE(WaitSize));
  102416. + return gcvSTATUS_OK;
  102417. +
  102418. +OnError:
  102419. + /* Return the status. */
  102420. + gcmkFOOTER();
  102421. + return status;
  102422. +}
  102423. +
  102424. +/*******************************************************************************
  102425. +**
  102426. +** gckHARDWARE_End
  102427. +**
  102428. +** Append an END command at the specified location in the command queue.
  102429. +**
  102430. +** INPUT:
  102431. +**
  102432. +** gckHARDWARE Hardware
  102433. +** Pointer to an gckHARDWARE object.
  102434. +**
  102435. +** gctPOINTER Logical
  102436. +** Pointer to the current location inside the command queue to append
  102437. +** END command at or gcvNULL just to query the size of the END command.
  102438. +**
  102439. +** gctSIZE_T * Bytes
  102440. +** Pointer to the number of bytes available for the END command. If
  102441. +** 'Logical' is gcvNULL, this argument will be ignored.
  102442. +**
  102443. +** OUTPUT:
  102444. +**
  102445. +** gctSIZE_T * Bytes
  102446. +** Pointer to a variable that will receive the number of bytes required
  102447. +** for the END command. If 'Bytes' is gcvNULL, nothing will be returned.
  102448. +*/
  102449. +gceSTATUS
  102450. +gckHARDWARE_End(
  102451. + IN gckHARDWARE Hardware,
  102452. + IN gctPOINTER Logical,
  102453. + IN OUT gctSIZE_T * Bytes
  102454. + )
  102455. +{
  102456. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  102457. + gceSTATUS status;
  102458. +
  102459. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
  102460. + Hardware, Logical, gcmOPT_VALUE(Bytes));
  102461. +
  102462. + /* Verify the arguments. */
  102463. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102464. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  102465. +
  102466. + if (Logical != gcvNULL)
  102467. + {
  102468. + if (*Bytes < 8)
  102469. + {
  102470. + /* Command queue too small. */
  102471. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  102472. + }
  102473. +
  102474. + /* Append END. */
  102475. + logical[0] =
  102476. + ((((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)));
  102477. +
  102478. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical);
  102479. +
  102480. + /* Make sure the CPU writes out the data to memory. */
  102481. + gcmkONERROR(
  102482. + gckOS_MemoryBarrier(Hardware->os, Logical));
  102483. + }
  102484. +
  102485. + if (Bytes != gcvNULL)
  102486. + {
  102487. + /* Return number of bytes required by the END command. */
  102488. + *Bytes = 8;
  102489. + }
  102490. +
  102491. + /* Success. */
  102492. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  102493. + return gcvSTATUS_OK;
  102494. +
  102495. +OnError:
  102496. + /* Return the status. */
  102497. + gcmkFOOTER();
  102498. + return status;
  102499. +}
  102500. +
  102501. +/*******************************************************************************
  102502. +**
  102503. +** gckHARDWARE_Nop
  102504. +**
  102505. +** Append a NOP command at the specified location in the command queue.
  102506. +**
  102507. +** INPUT:
  102508. +**
  102509. +** gckHARDWARE Hardware
  102510. +** Pointer to an gckHARDWARE object.
  102511. +**
  102512. +** gctPOINTER Logical
  102513. +** Pointer to the current location inside the command queue to append
  102514. +** NOP command at or gcvNULL just to query the size of the NOP command.
  102515. +**
  102516. +** gctSIZE_T * Bytes
  102517. +** Pointer to the number of bytes available for the NOP command. If
  102518. +** 'Logical' is gcvNULL, this argument will be ignored.
  102519. +**
  102520. +** OUTPUT:
  102521. +**
  102522. +** gctSIZE_T * Bytes
  102523. +** Pointer to a variable that will receive the number of bytes required
  102524. +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
  102525. +*/
  102526. +gceSTATUS
  102527. +gckHARDWARE_Nop(
  102528. + IN gckHARDWARE Hardware,
  102529. + IN gctPOINTER Logical,
  102530. + IN OUT gctSIZE_T * Bytes
  102531. + )
  102532. +{
  102533. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  102534. + gceSTATUS status;
  102535. +
  102536. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
  102537. + Hardware, Logical, gcmOPT_VALUE(Bytes));
  102538. +
  102539. + /* Verify the arguments. */
  102540. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102541. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  102542. +
  102543. + if (Logical != gcvNULL)
  102544. + {
  102545. + if (*Bytes < 8)
  102546. + {
  102547. + /* Command queue too small. */
  102548. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  102549. + }
  102550. +
  102551. + /* Append NOP. */
  102552. + 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)));
  102553. +
  102554. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
  102555. + }
  102556. +
  102557. + if (Bytes != gcvNULL)
  102558. + {
  102559. + /* Return number of bytes required by the NOP command. */
  102560. + *Bytes = 8;
  102561. + }
  102562. +
  102563. + /* Success. */
  102564. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  102565. + return gcvSTATUS_OK;
  102566. +
  102567. +OnError:
  102568. + /* Return the status. */
  102569. + gcmkFOOTER();
  102570. + return status;
  102571. +}
  102572. +
  102573. +/*******************************************************************************
  102574. +**
  102575. +** gckHARDWARE_Wait
  102576. +**
  102577. +** Append a WAIT command at the specified location in the command queue.
  102578. +**
  102579. +** INPUT:
  102580. +**
  102581. +** gckHARDWARE Hardware
  102582. +** Pointer to an gckHARDWARE object.
  102583. +**
  102584. +** gctPOINTER Logical
  102585. +** Pointer to the current location inside the command queue to append
  102586. +** WAIT command at or gcvNULL just to query the size of the WAIT command.
  102587. +**
  102588. +** gctUINT32 Count
  102589. +** Number of cycles to wait.
  102590. +**
  102591. +** gctSIZE_T * Bytes
  102592. +** Pointer to the number of bytes available for the WAIT command. If
  102593. +** 'Logical' is gcvNULL, this argument will be ignored.
  102594. +**
  102595. +** OUTPUT:
  102596. +**
  102597. +** gctSIZE_T * Bytes
  102598. +** Pointer to a variable that will receive the number of bytes required
  102599. +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
  102600. +*/
  102601. +gceSTATUS
  102602. +gckHARDWARE_Wait(
  102603. + IN gckHARDWARE Hardware,
  102604. + IN gctPOINTER Logical,
  102605. + IN gctUINT32 Count,
  102606. + IN OUT gctSIZE_T * Bytes
  102607. + )
  102608. +{
  102609. + gceSTATUS status;
  102610. + gctUINT32_PTR logical;
  102611. +
  102612. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu",
  102613. + Hardware, Logical, Count, gcmOPT_VALUE(Bytes));
  102614. +
  102615. + /* Verify the arguments. */
  102616. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102617. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  102618. +
  102619. + /* Cast the input pointer. */
  102620. + logical = (gctUINT32_PTR) Logical;
  102621. +
  102622. + if (Logical != gcvNULL)
  102623. + {
  102624. + if (*Bytes < 8)
  102625. + {
  102626. + /* Command queue too small. */
  102627. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  102628. + }
  102629. +
  102630. + /* Append WAIT. */
  102631. + 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)))
  102632. + | ((((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)));
  102633. +
  102634. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  102635. + {
  102636. + gctUINT32 address;
  102637. +
  102638. + /* Convert logical into hardware specific address. */
  102639. + gcmkONERROR(gckHARDWARE_ConvertLogical(
  102640. + Hardware, logical, &address
  102641. + ));
  102642. +
  102643. + gcmkTRACE_ZONE(
  102644. + gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102645. + "0x%08x: WAIT %u", address, Count
  102646. + );
  102647. + }
  102648. +#endif
  102649. + }
  102650. +
  102651. + if (Bytes != gcvNULL)
  102652. + {
  102653. + /* Return number of bytes required by the WAIT command. */
  102654. + *Bytes = 8;
  102655. + }
  102656. +
  102657. + /* Success. */
  102658. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  102659. + return gcvSTATUS_OK;
  102660. +
  102661. +OnError:
  102662. + /* Return the status. */
  102663. + gcmkFOOTER();
  102664. + return status;
  102665. +}
  102666. +
  102667. +/*******************************************************************************
  102668. +**
  102669. +** gckHARDWARE_Event
  102670. +**
  102671. +** Append an EVENT command at the specified location in the command queue.
  102672. +**
  102673. +** INPUT:
  102674. +**
  102675. +** gckHARDWARE Hardware
  102676. +** Pointer to an gckHARDWARE object.
  102677. +**
  102678. +** gctPOINTER Logical
  102679. +** Pointer to the current location inside the command queue to append
  102680. +** the EVENT command at or gcvNULL just to query the size of the EVENT
  102681. +** command.
  102682. +**
  102683. +** gctUINT8 Event
  102684. +** Event ID to program.
  102685. +**
  102686. +** gceKERNEL_WHERE FromWhere
  102687. +** Location of the pipe to send the event.
  102688. +**
  102689. +** gctSIZE_T * Bytes
  102690. +** Pointer to the number of bytes available for the EVENT command. If
  102691. +** 'Logical' is gcvNULL, this argument will be ignored.
  102692. +**
  102693. +** OUTPUT:
  102694. +**
  102695. +** gctSIZE_T * Bytes
  102696. +** Pointer to a variable that will receive the number of bytes required
  102697. +** for the EVENT command. If 'Bytes' is gcvNULL, nothing will be
  102698. +** returned.
  102699. +*/
  102700. +gceSTATUS
  102701. +gckHARDWARE_Event(
  102702. + IN gckHARDWARE Hardware,
  102703. + IN gctPOINTER Logical,
  102704. + IN gctUINT8 Event,
  102705. + IN gceKERNEL_WHERE FromWhere,
  102706. + IN OUT gctSIZE_T * Bytes
  102707. + )
  102708. +{
  102709. + gctUINT size;
  102710. + gctUINT32 destination = 0;
  102711. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  102712. + gceSTATUS status;
  102713. +
  102714. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Event=%u FromWhere=%d *Bytes=%lu",
  102715. + Hardware, Logical, Event, FromWhere, gcmOPT_VALUE(Bytes));
  102716. +
  102717. + /* Verify the arguments. */
  102718. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102719. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  102720. + gcmkVERIFY_ARGUMENT(Event < 32);
  102721. +
  102722. + /* Determine the size of the command. */
  102723. +
  102724. + size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL))
  102725. + ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
  102726. + : 8;
  102727. +
  102728. + if (Logical != gcvNULL)
  102729. + {
  102730. + if (*Bytes < size)
  102731. + {
  102732. + /* Command queue too small. */
  102733. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  102734. + }
  102735. +
  102736. + switch (FromWhere)
  102737. + {
  102738. + case gcvKERNEL_COMMAND:
  102739. + /* From command processor. */
  102740. + 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)));
  102741. + break;
  102742. +
  102743. + case gcvKERNEL_PIXEL:
  102744. + /* From pixel engine. */
  102745. + 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)));
  102746. + break;
  102747. +
  102748. + default:
  102749. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  102750. + }
  102751. +
  102752. + /* Append EVENT(Event, destiantion). */
  102753. + 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)))
  102754. + | ((((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)))
  102755. + | ((((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)));
  102756. +
  102757. + 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)));
  102758. +
  102759. + /* Make sure the event ID gets written out before GPU can access it. */
  102760. + gcmkONERROR(
  102761. + gckOS_MemoryBarrier(Hardware->os, logical + 1));
  102762. +
  102763. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  102764. + {
  102765. + gctUINT32 phys;
  102766. + gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
  102767. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102768. + "0x%08x: EVENT %d", phys, Event);
  102769. + }
  102770. +#endif
  102771. +
  102772. + /* Append the extra states. These are needed for the chips that do not
  102773. + ** support back-to-back events due to the async interface. The extra
  102774. + ** states add the necessary delay to ensure that event IDs do not
  102775. + ** collide. */
  102776. + if (size > 8)
  102777. + {
  102778. + 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)))
  102779. + | ((((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)))
  102780. + | ((((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)));
  102781. + logical[3] = 0;
  102782. + logical[4] = 0;
  102783. + logical[5] = 0;
  102784. + logical[6] = 0;
  102785. + logical[7] = 0;
  102786. + }
  102787. + }
  102788. +
  102789. + if (Bytes != gcvNULL)
  102790. + {
  102791. + /* Return number of bytes required by the EVENT command. */
  102792. + *Bytes = size;
  102793. + }
  102794. +
  102795. + /* Success. */
  102796. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  102797. + return gcvSTATUS_OK;
  102798. +
  102799. +OnError:
  102800. + /* Return the status. */
  102801. + gcmkFOOTER();
  102802. + return status;
  102803. +}
  102804. +
  102805. +/*******************************************************************************
  102806. +**
  102807. +** gckHARDWARE_PipeSelect
  102808. +**
  102809. +** Append a PIPESELECT command at the specified location in the command queue.
  102810. +**
  102811. +** INPUT:
  102812. +**
  102813. +** gckHARDWARE Hardware
  102814. +** Pointer to an gckHARDWARE object.
  102815. +**
  102816. +** gctPOINTER Logical
  102817. +** Pointer to the current location inside the command queue to append
  102818. +** the PIPESELECT command at or gcvNULL just to query the size of the
  102819. +** PIPESELECT command.
  102820. +**
  102821. +** gcePIPE_SELECT Pipe
  102822. +** Pipe value to select.
  102823. +**
  102824. +** gctSIZE_T * Bytes
  102825. +** Pointer to the number of bytes available for the PIPESELECT command.
  102826. +** If 'Logical' is gcvNULL, this argument will be ignored.
  102827. +**
  102828. +** OUTPUT:
  102829. +**
  102830. +** gctSIZE_T * Bytes
  102831. +** Pointer to a variable that will receive the number of bytes required
  102832. +** for the PIPESELECT command. If 'Bytes' is gcvNULL, nothing will be
  102833. +** returned.
  102834. +*/
  102835. +gceSTATUS
  102836. +gckHARDWARE_PipeSelect(
  102837. + IN gckHARDWARE Hardware,
  102838. + IN gctPOINTER Logical,
  102839. + IN gcePIPE_SELECT Pipe,
  102840. + IN OUT gctSIZE_T * Bytes
  102841. + )
  102842. +{
  102843. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  102844. + gceSTATUS status;
  102845. +
  102846. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Pipe=%d *Bytes=%lu",
  102847. + Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes));
  102848. +
  102849. + /* Verify the arguments. */
  102850. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102851. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  102852. +
  102853. + /* Append a PipeSelect. */
  102854. + if (Logical != gcvNULL)
  102855. + {
  102856. + gctUINT32 flush, stall;
  102857. +
  102858. + if (*Bytes < 32)
  102859. + {
  102860. + /* Command queue too small. */
  102861. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  102862. + }
  102863. +
  102864. + flush = (Pipe == gcvPIPE_2D)
  102865. + ? ((((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)))
  102866. + | ((((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)))
  102867. + : ((((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)));
  102868. +
  102869. + 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)))
  102870. + | ((((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)));
  102871. +
  102872. + /* LoadState(AQFlush, 1), flush. */
  102873. + logical[0]
  102874. + = ((((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)))
  102875. + | ((((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)))
  102876. + | ((((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)));
  102877. +
  102878. + logical[1]
  102879. + = flush;
  102880. +
  102881. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102882. + "0x%x: FLUSH 0x%x", logical, flush);
  102883. +
  102884. + /* LoadState(AQSempahore, 1), stall. */
  102885. + logical[2]
  102886. + = ((((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)))
  102887. + | ((((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)))
  102888. + | ((((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)));
  102889. +
  102890. + logical[3]
  102891. + = stall;
  102892. +
  102893. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102894. + "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
  102895. +
  102896. + /* Stall, stall. */
  102897. + 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)));
  102898. + logical[5] = stall;
  102899. +
  102900. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102901. + "0x%x: STALL 0x%x", logical + 4, stall);
  102902. +
  102903. + /* LoadState(AQPipeSelect, 1), pipe. */
  102904. + logical[6]
  102905. + = ((((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)))
  102906. + | ((((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)))
  102907. + | ((((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)));
  102908. +
  102909. + logical[7] = (Pipe == gcvPIPE_2D)
  102910. + ? 0x1
  102911. + : 0x0;
  102912. +
  102913. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  102914. + "0x%x: PIPE %d", logical + 6, Pipe);
  102915. + }
  102916. +
  102917. + if (Bytes != gcvNULL)
  102918. + {
  102919. + /* Return number of bytes required by the PIPESELECT command. */
  102920. + *Bytes = 32;
  102921. + }
  102922. +
  102923. + /* Success. */
  102924. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  102925. + return gcvSTATUS_OK;
  102926. +
  102927. +OnError:
  102928. + /* Return the status. */
  102929. + gcmkFOOTER();
  102930. + return status;
  102931. +}
  102932. +
  102933. +/*******************************************************************************
  102934. +**
  102935. +** gckHARDWARE_Link
  102936. +**
  102937. +** Append a LINK command at the specified location in the command queue.
  102938. +**
  102939. +** INPUT:
  102940. +**
  102941. +** gckHARDWARE Hardware
  102942. +** Pointer to an gckHARDWARE object.
  102943. +**
  102944. +** gctPOINTER Logical
  102945. +** Pointer to the current location inside the command queue to append
  102946. +** the LINK command at or gcvNULL just to query the size of the LINK
  102947. +** command.
  102948. +**
  102949. +** gctPOINTER FetchAddress
  102950. +** Logical address of destination of LINK.
  102951. +**
  102952. +** gctSIZE_T FetchSize
  102953. +** Number of bytes in destination of LINK.
  102954. +**
  102955. +** gctSIZE_T * Bytes
  102956. +** Pointer to the number of bytes available for the LINK command. If
  102957. +** 'Logical' is gcvNULL, this argument will be ignored.
  102958. +**
  102959. +** OUTPUT:
  102960. +**
  102961. +** gctSIZE_T * Bytes
  102962. +** Pointer to a variable that will receive the number of bytes required
  102963. +** for the LINK command. If 'Bytes' is gcvNULL, nothing will be returned.
  102964. +*/
  102965. +gceSTATUS
  102966. +gckHARDWARE_Link(
  102967. + IN gckHARDWARE Hardware,
  102968. + IN gctPOINTER Logical,
  102969. + IN gctPOINTER FetchAddress,
  102970. + IN gctSIZE_T FetchSize,
  102971. + IN OUT gctSIZE_T * Bytes
  102972. + )
  102973. +{
  102974. + gceSTATUS status;
  102975. + gctSIZE_T bytes;
  102976. + gctUINT32 address;
  102977. + gctUINT32 link;
  102978. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  102979. +
  102980. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x FetchAddress=0x%x FetchSize=%lu "
  102981. + "*Bytes=%lu",
  102982. + Hardware, Logical, FetchAddress, FetchSize,
  102983. + gcmOPT_VALUE(Bytes));
  102984. +
  102985. + /* Verify the arguments. */
  102986. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  102987. + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
  102988. +
  102989. + if (Logical != gcvNULL)
  102990. + {
  102991. + if (*Bytes < 8)
  102992. + {
  102993. + /* Command queue too small. */
  102994. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  102995. + }
  102996. +
  102997. + /* Convert logical address to hardware address. */
  102998. + gcmkONERROR(
  102999. + gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address));
  103000. +
  103001. + gcmkONERROR(
  103002. + gckOS_WriteMemory(Hardware->os, logical + 1, address));
  103003. +
  103004. + /* Make sure the address got written before the LINK command. */
  103005. + gcmkONERROR(
  103006. + gckOS_MemoryBarrier(Hardware->os, logical + 1));
  103007. +
  103008. + /* Compute number of 64-byte aligned bytes to fetch. */
  103009. + bytes = gcmALIGN(address + FetchSize, 8) - address;
  103010. +
  103011. + /* Append LINK(bytes / 8), FetchAddress. */
  103012. + 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)))
  103013. + | ((((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)));
  103014. +
  103015. + gcmkONERROR(
  103016. + gckOS_WriteMemory(Hardware->os, logical, link));
  103017. +
  103018. + /* Memory barrier. */
  103019. + gcmkONERROR(
  103020. + gckOS_MemoryBarrier(Hardware->os, logical));
  103021. +
  103022. +#if gcdLINK_QUEUE_SIZE && gcdVIRTUAL_COMMAND_BUFFER
  103023. + if (address >= 0x80000000)
  103024. + {
  103025. + gckLINKQUEUE_Enqueue(&Hardware->linkQueue, address, address + bytes);
  103026. + }
  103027. +#endif
  103028. + }
  103029. +
  103030. + if (Bytes != gcvNULL)
  103031. + {
  103032. + /* Return number of bytes required by the LINK command. */
  103033. + *Bytes = 8;
  103034. + }
  103035. +
  103036. + /* Success. */
  103037. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  103038. + return gcvSTATUS_OK;
  103039. +
  103040. +OnError:
  103041. + /* Return the status. */
  103042. + gcmkFOOTER();
  103043. + return status;
  103044. +}
  103045. +
  103046. +/*******************************************************************************
  103047. +**
  103048. +** gckHARDWARE_UpdateQueueTail
  103049. +**
  103050. +** Update the tail of the command queue.
  103051. +**
  103052. +** INPUT:
  103053. +**
  103054. +** gckHARDWARE Hardware
  103055. +** Pointer to an gckHARDWARE object.
  103056. +**
  103057. +** gctPOINTER Logical
  103058. +** Logical address of the start of the command queue.
  103059. +**
  103060. +** gctUINT32 Offset
  103061. +** Offset into the command queue of the tail (last command).
  103062. +**
  103063. +** OUTPUT:
  103064. +**
  103065. +** Nothing.
  103066. +*/
  103067. +gceSTATUS
  103068. +gckHARDWARE_UpdateQueueTail(
  103069. + IN gckHARDWARE Hardware,
  103070. + IN gctPOINTER Logical,
  103071. + IN gctUINT32 Offset
  103072. + )
  103073. +{
  103074. + gceSTATUS status;
  103075. +
  103076. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x",
  103077. + Hardware, Logical, Offset);
  103078. +
  103079. + /* Verify the hardware. */
  103080. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103081. +
  103082. + /* Force a barrier. */
  103083. + gcmkONERROR(
  103084. + gckOS_MemoryBarrier(Hardware->os, Logical));
  103085. +
  103086. + /* Notify gckKERNEL object of change. */
  103087. + gcmkONERROR(
  103088. + gckKERNEL_Notify(Hardware->kernel,
  103089. + gcvNOTIFY_COMMAND_QUEUE,
  103090. + gcvFALSE));
  103091. +
  103092. + if (status == gcvSTATUS_CHIP_NOT_READY)
  103093. + {
  103094. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  103095. + }
  103096. +
  103097. + /* Success. */
  103098. + gcmkFOOTER_NO();
  103099. + return gcvSTATUS_OK;
  103100. +
  103101. +OnError:
  103102. + /* Return the status. */
  103103. + gcmkFOOTER();
  103104. + return status;
  103105. +}
  103106. +
  103107. +/*******************************************************************************
  103108. +**
  103109. +** gckHARDWARE_ConvertLogical
  103110. +**
  103111. +** Convert a logical system address into a hardware specific address.
  103112. +**
  103113. +** INPUT:
  103114. +**
  103115. +** gckHARDWARE Hardware
  103116. +** Pointer to an gckHARDWARE object.
  103117. +**
  103118. +** gctPOINTER Logical
  103119. +** Logical address to convert.
  103120. +**
  103121. +** gctUINT32* Address
  103122. +** Return hardware specific address.
  103123. +**
  103124. +** OUTPUT:
  103125. +**
  103126. +** Nothing.
  103127. +*/
  103128. +gceSTATUS
  103129. +gckHARDWARE_ConvertLogical(
  103130. + IN gckHARDWARE Hardware,
  103131. + IN gctPOINTER Logical,
  103132. + OUT gctUINT32 * Address
  103133. + )
  103134. +{
  103135. + gctUINT32 address;
  103136. + gceSTATUS status;
  103137. + gctUINT32 baseAddress;
  103138. +
  103139. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
  103140. +
  103141. + /* Verify the arguments. */
  103142. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103143. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  103144. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  103145. +
  103146. +#if gcdVIRTUAL_COMMAND_BUFFER
  103147. + status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
  103148. +
  103149. + if (status == gcvSTATUS_INVALID_ADDRESS)
  103150. +#endif
  103151. + {
  103152. + /* Convert logical address into a physical address. */
  103153. + gcmkONERROR(
  103154. + gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
  103155. +
  103156. + /* For old MMU, get GPU address according to baseAddress. */
  103157. + if (Hardware->mmuVersion == 0)
  103158. + {
  103159. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  103160. +
  103161. + /* Subtract base address to get a GPU address. */
  103162. + gcmkASSERT(address >= baseAddress);
  103163. + address -= baseAddress;
  103164. + }
  103165. +
  103166. + /* Return hardware specific address. */
  103167. + *Address = (Hardware->mmuVersion == 0)
  103168. + ? ((((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)))
  103169. + | ((((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)))
  103170. + : address;
  103171. + }
  103172. +
  103173. + /* Success. */
  103174. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  103175. + return gcvSTATUS_OK;
  103176. +
  103177. +OnError:
  103178. + /* Return the status. */
  103179. + gcmkFOOTER();
  103180. + return status;
  103181. +}
  103182. +
  103183. +/*******************************************************************************
  103184. +**
  103185. +** gckHARDWARE_ConvertPhysical
  103186. +**
  103187. +** Convert a physical address into a hardware specific address.
  103188. +**
  103189. +** INPUT:
  103190. +**
  103191. +** gckHARDWARE Hardware
  103192. +** Pointer to an gckHARDWARE object.
  103193. +**
  103194. +** gctPHYS_ADDR Physical
  103195. +** Physical address to convert.
  103196. +**
  103197. +** gctUINT32* Address
  103198. +** Return hardware specific address.
  103199. +**
  103200. +** OUTPUT:
  103201. +**
  103202. +** Nothing.
  103203. +*/
  103204. +gceSTATUS
  103205. +gckHARDWARE_ConvertPhysical(
  103206. + IN gckHARDWARE Hardware,
  103207. + IN gctPHYS_ADDR Physical,
  103208. + OUT gctUINT32 * Address
  103209. + )
  103210. +{
  103211. + gctUINT32 address;
  103212. + gctUINT32 baseAddress;
  103213. +
  103214. + gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical);
  103215. +
  103216. + /* Verify the arguments. */
  103217. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103218. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  103219. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  103220. +
  103221. + address = gcmPTR2INT(Physical);
  103222. +
  103223. + /* For old MMU, get GPU address according to baseAddress. */
  103224. + if (Hardware->mmuVersion == 0)
  103225. + {
  103226. + gcmkVERIFY_OK(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  103227. +
  103228. + /* Subtract base address to get a GPU address. */
  103229. + gcmkASSERT(address >= baseAddress);
  103230. + address -= baseAddress;
  103231. + }
  103232. +
  103233. + /* Return hardware specific address. */
  103234. + *Address = (Hardware->mmuVersion == 0)
  103235. + ? ((((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)))
  103236. + | ((((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)))
  103237. + : address;
  103238. +
  103239. + /* Return the status. */
  103240. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  103241. + return gcvSTATUS_OK;
  103242. +}
  103243. +
  103244. +/*******************************************************************************
  103245. +**
  103246. +** gckHARDWARE_Interrupt
  103247. +**
  103248. +** Process an interrupt.
  103249. +**
  103250. +** INPUT:
  103251. +**
  103252. +** gckHARDWARE Hardware
  103253. +** Pointer to an gckHARDWARE object.
  103254. +**
  103255. +** gctBOOL InterruptValid
  103256. +** If gcvTRUE, this function will read the interrupt acknowledge
  103257. +** register, stores the data, and return whether or not the interrupt
  103258. +** is ours or not. If gcvFALSE, this functions will read the interrupt
  103259. +** acknowledge register and combine it with any stored value to handle
  103260. +** the event notifications.
  103261. +**
  103262. +** OUTPUT:
  103263. +**
  103264. +** Nothing.
  103265. +*/
  103266. +gceSTATUS
  103267. +gckHARDWARE_Interrupt(
  103268. + IN gckHARDWARE Hardware,
  103269. + IN gctBOOL InterruptValid
  103270. + )
  103271. +{
  103272. + gckEVENT eventObj;
  103273. + gctUINT32 data;
  103274. + gceSTATUS status;
  103275. +
  103276. + gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid);
  103277. +
  103278. + /* Verify the arguments. */
  103279. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103280. +
  103281. + /* Extract gckEVENT object. */
  103282. + eventObj = Hardware->kernel->eventObj;
  103283. + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
  103284. +
  103285. + if (InterruptValid)
  103286. + {
  103287. + /* Read AQIntrAcknowledge register. */
  103288. + gcmkONERROR(
  103289. + gckOS_ReadRegisterEx(Hardware->os,
  103290. + Hardware->core,
  103291. + 0x00010,
  103292. + &data));
  103293. +
  103294. + if (data == 0)
  103295. + {
  103296. + /* Not our interrupt. */
  103297. + status = gcvSTATUS_NOT_OUR_INTERRUPT;
  103298. + }
  103299. + else
  103300. + {
  103301. + /* Inform gckEVENT of the interrupt. */
  103302. + status = gckEVENT_Interrupt(eventObj, data);
  103303. + }
  103304. + }
  103305. + else
  103306. + {
  103307. + /* Handle events. */
  103308. + status = gckEVENT_Notify(eventObj, 0);
  103309. + }
  103310. +
  103311. +OnError:
  103312. + /* Return the status. */
  103313. + gcmkFOOTER();
  103314. + return status;
  103315. +}
  103316. +
  103317. +/*******************************************************************************
  103318. +**
  103319. +** gckHARDWARE_QueryCommandBuffer
  103320. +**
  103321. +** Query the command buffer alignment and number of reserved bytes.
  103322. +**
  103323. +** INPUT:
  103324. +**
  103325. +** gckHARDWARE Harwdare
  103326. +** Pointer to an gckHARDWARE object.
  103327. +**
  103328. +** OUTPUT:
  103329. +**
  103330. +** gctSIZE_T * Alignment
  103331. +** Pointer to a variable receiving the alignment for each command.
  103332. +**
  103333. +** gctSIZE_T * ReservedHead
  103334. +** Pointer to a variable receiving the number of reserved bytes at the
  103335. +** head of each command buffer.
  103336. +**
  103337. +** gctSIZE_T * ReservedTail
  103338. +** Pointer to a variable receiving the number of bytes reserved at the
  103339. +** tail of each command buffer.
  103340. +*/
  103341. +gceSTATUS
  103342. +gckHARDWARE_QueryCommandBuffer(
  103343. + IN gckHARDWARE Hardware,
  103344. + OUT gctSIZE_T * Alignment,
  103345. + OUT gctSIZE_T * ReservedHead,
  103346. + OUT gctSIZE_T * ReservedTail
  103347. + )
  103348. +{
  103349. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103350. +
  103351. + /* Verify the arguments. */
  103352. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103353. +
  103354. + if (Alignment != gcvNULL)
  103355. + {
  103356. + /* Align every 8 bytes. */
  103357. + *Alignment = 8;
  103358. + }
  103359. +
  103360. + if (ReservedHead != gcvNULL)
  103361. + {
  103362. + /* Reserve space for SelectPipe(). */
  103363. + *ReservedHead = 32;
  103364. + }
  103365. +
  103366. + if (ReservedTail != gcvNULL)
  103367. + {
  103368. + /* Reserve space for Link(). */
  103369. + *ReservedTail = 8;
  103370. + }
  103371. +
  103372. + /* Success. */
  103373. + gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
  103374. + gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
  103375. + gcmOPT_VALUE(ReservedTail));
  103376. + return gcvSTATUS_OK;
  103377. +}
  103378. +
  103379. +/*******************************************************************************
  103380. +**
  103381. +** gckHARDWARE_QuerySystemMemory
  103382. +**
  103383. +** Query the command buffer alignment and number of reserved bytes.
  103384. +**
  103385. +** INPUT:
  103386. +**
  103387. +** gckHARDWARE Harwdare
  103388. +** Pointer to an gckHARDWARE object.
  103389. +**
  103390. +** OUTPUT:
  103391. +**
  103392. +** gctSIZE_T * SystemSize
  103393. +** Pointer to a variable that receives the maximum size of the system
  103394. +** memory.
  103395. +**
  103396. +** gctUINT32 * SystemBaseAddress
  103397. +** Poinetr to a variable that receives the base address for system
  103398. +** memory.
  103399. +*/
  103400. +gceSTATUS
  103401. +gckHARDWARE_QuerySystemMemory(
  103402. + IN gckHARDWARE Hardware,
  103403. + OUT gctSIZE_T * SystemSize,
  103404. + OUT gctUINT32 * SystemBaseAddress
  103405. + )
  103406. +{
  103407. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103408. +
  103409. + /* Verify the arguments. */
  103410. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103411. +
  103412. + if (SystemSize != gcvNULL)
  103413. + {
  103414. + /* Maximum system memory can be 2GB. */
  103415. + *SystemSize = 1U << 31;
  103416. + }
  103417. +
  103418. + if (SystemBaseAddress != gcvNULL)
  103419. + {
  103420. + /* Set system memory base address. */
  103421. + *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)));
  103422. + }
  103423. +
  103424. + /* Success. */
  103425. + gcmkFOOTER_ARG("*SystemSize=%lu *SystemBaseAddress=%lu",
  103426. + gcmOPT_VALUE(SystemSize), gcmOPT_VALUE(SystemBaseAddress));
  103427. + return gcvSTATUS_OK;
  103428. +}
  103429. +
  103430. +#ifndef VIVANTE_NO_3D
  103431. +/*******************************************************************************
  103432. +**
  103433. +** gckHARDWARE_QueryShaderCaps
  103434. +**
  103435. +** Query the shader capabilities.
  103436. +**
  103437. +** INPUT:
  103438. +**
  103439. +** Nothing.
  103440. +**
  103441. +** OUTPUT:
  103442. +**
  103443. +** gctUINT * VertexUniforms
  103444. +** Pointer to a variable receiving the number of uniforms in the vertex
  103445. +** shader.
  103446. +**
  103447. +** gctUINT * FragmentUniforms
  103448. +** Pointer to a variable receiving the number of uniforms in the
  103449. +** fragment shader.
  103450. +**
  103451. +** gctUINT * Varyings
  103452. +** Pointer to a variable receiving the maimum number of varyings.
  103453. +*/
  103454. +gceSTATUS
  103455. +gckHARDWARE_QueryShaderCaps(
  103456. + IN gckHARDWARE Hardware,
  103457. + OUT gctUINT * VertexUniforms,
  103458. + OUT gctUINT * FragmentUniforms,
  103459. + OUT gctUINT * Varyings
  103460. + )
  103461. +{
  103462. + gctUINT32 vsConstMax;
  103463. + gctUINT32 psConstMax;
  103464. +
  103465. + gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
  103466. + "FragmentUniforms=0x%x Varyings=0x%x",
  103467. + Hardware, VertexUniforms,
  103468. + FragmentUniforms, Varyings);
  103469. +
  103470. + if ((Hardware->identity.chipModel == gcv2000)
  103471. + && (Hardware->identity.chipRevision == 0x5118))
  103472. + {
  103473. + vsConstMax = 256;
  103474. + psConstMax = 64;
  103475. + }
  103476. + else if (Hardware->identity.numConstants > 256)
  103477. + {
  103478. + vsConstMax = 256;
  103479. + psConstMax = 256;
  103480. + }
  103481. + else if (Hardware->identity.numConstants == 256)
  103482. + {
  103483. + vsConstMax = 256;
  103484. + psConstMax = 256;
  103485. + }
  103486. + else
  103487. + {
  103488. + vsConstMax = 168;
  103489. + psConstMax = 64;
  103490. + }
  103491. +
  103492. + if (VertexUniforms != gcvNULL)
  103493. + {
  103494. + *VertexUniforms = vsConstMax;
  103495. + }
  103496. +
  103497. + if (FragmentUniforms != gcvNULL)
  103498. + {
  103499. + *FragmentUniforms = psConstMax;
  103500. + }
  103501. +
  103502. + if (Varyings != gcvNULL)
  103503. + {
  103504. + /* Return the shader varyings count. */
  103505. + *Varyings = Hardware->identity.varyingsCount;
  103506. + }
  103507. +
  103508. + /* Success. */
  103509. + gcmkFOOTER_NO();
  103510. + return gcvSTATUS_OK;
  103511. +}
  103512. +#endif
  103513. +
  103514. +/*******************************************************************************
  103515. +**
  103516. +** gckHARDWARE_SetMMU
  103517. +**
  103518. +** Set the page table base address.
  103519. +**
  103520. +** INPUT:
  103521. +**
  103522. +** gckHARDWARE Harwdare
  103523. +** Pointer to an gckHARDWARE object.
  103524. +**
  103525. +** gctPOINTER Logical
  103526. +** Logical address of the page table.
  103527. +**
  103528. +** OUTPUT:
  103529. +**
  103530. +** Nothing.
  103531. +*/
  103532. +gceSTATUS
  103533. +gckHARDWARE_SetMMU(
  103534. + IN gckHARDWARE Hardware,
  103535. + IN gctPOINTER Logical
  103536. + )
  103537. +{
  103538. + gceSTATUS status;
  103539. + gctUINT32 address = 0;
  103540. + gctUINT32 baseAddress;
  103541. +
  103542. + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
  103543. +
  103544. + /* Verify the arguments. */
  103545. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103546. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  103547. +
  103548. + /* Convert the logical address into an hardware address. */
  103549. + gcmkONERROR(
  103550. + gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
  103551. +
  103552. + /* Also get the base address - we need a real physical address. */
  103553. + gcmkONERROR(
  103554. + gckOS_GetBaseAddress(Hardware->os, &baseAddress));
  103555. +
  103556. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  103557. + "Setting page table to 0x%08X",
  103558. + address + baseAddress);
  103559. +
  103560. + /* Write the AQMemoryFePageTable register. */
  103561. + gcmkONERROR(
  103562. + gckOS_WriteRegisterEx(Hardware->os,
  103563. + Hardware->core,
  103564. + 0x00400,
  103565. + address + baseAddress));
  103566. +
  103567. + /* Write the AQMemoryRaPageTable register. */
  103568. + gcmkONERROR(
  103569. + gckOS_WriteRegisterEx(Hardware->os,
  103570. + Hardware->core,
  103571. + 0x00410,
  103572. + address + baseAddress));
  103573. +
  103574. + /* Write the AQMemoryTxPageTable register. */
  103575. + gcmkONERROR(
  103576. + gckOS_WriteRegisterEx(Hardware->os,
  103577. + Hardware->core,
  103578. + 0x00404,
  103579. + address + baseAddress));
  103580. +
  103581. +
  103582. + /* Write the AQMemoryPePageTable register. */
  103583. + gcmkONERROR(
  103584. + gckOS_WriteRegisterEx(Hardware->os,
  103585. + Hardware->core,
  103586. + 0x00408,
  103587. + address + baseAddress));
  103588. +
  103589. + /* Write the AQMemoryPezPageTable register. */
  103590. + gcmkONERROR(
  103591. + gckOS_WriteRegisterEx(Hardware->os,
  103592. + Hardware->core,
  103593. + 0x0040C,
  103594. + address + baseAddress));
  103595. +
  103596. + /* Return the status. */
  103597. + gcmkFOOTER_NO();
  103598. + return status;
  103599. +
  103600. +OnError:
  103601. + /* Return the status. */
  103602. + gcmkFOOTER();
  103603. + return status;
  103604. +}
  103605. +
  103606. +/*******************************************************************************
  103607. +**
  103608. +** gckHARDWARE_FlushMMU
  103609. +**
  103610. +** Flush the page table.
  103611. +**
  103612. +** INPUT:
  103613. +**
  103614. +** gckHARDWARE Harwdare
  103615. +** Pointer to an gckHARDWARE object.
  103616. +**
  103617. +** OUTPUT:
  103618. +**
  103619. +** Nothing.
  103620. +*/
  103621. +gceSTATUS
  103622. +gckHARDWARE_FlushMMU(
  103623. + IN gckHARDWARE Hardware
  103624. + )
  103625. +{
  103626. + gceSTATUS status;
  103627. + gckCOMMAND command;
  103628. + gctUINT32_PTR buffer;
  103629. + gctSIZE_T bufferSize;
  103630. + gctBOOL commitEntered = gcvFALSE;
  103631. + gctPOINTER pointer = gcvNULL;
  103632. + gctUINT32 flushSize;
  103633. + gctUINT32 count;
  103634. + gctUINT32 physical;
  103635. +
  103636. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  103637. +
  103638. + /* Verify the arguments. */
  103639. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103640. +
  103641. + /* Verify the gckCOMMAND object pointer. */
  103642. + command = Hardware->kernel->command;
  103643. +
  103644. + /* Acquire the command queue. */
  103645. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
  103646. + commitEntered = gcvTRUE;
  103647. +
  103648. + /* Flush the memory controller. */
  103649. + if (Hardware->mmuVersion == 0)
  103650. + {
  103651. + gcmkONERROR(gckCOMMAND_Reserve(
  103652. + command, 8, &pointer, &bufferSize
  103653. + ));
  103654. +
  103655. + buffer = (gctUINT32_PTR) pointer;
  103656. +
  103657. + buffer[0]
  103658. + = ((((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)))
  103659. + | ((((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)))
  103660. + | ((((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)));
  103661. +
  103662. + buffer[1]
  103663. + = ((((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)))
  103664. + | ((((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)))
  103665. + | ((((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)))
  103666. + | ((((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)))
  103667. + | ((((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)));
  103668. +
  103669. + gcmkONERROR(gckCOMMAND_Execute(command, 8));
  103670. + }
  103671. + else
  103672. + {
  103673. + flushSize = 16 * 4;
  103674. +
  103675. + gcmkONERROR(gckCOMMAND_Reserve(
  103676. + command, flushSize, &pointer, &bufferSize
  103677. + ));
  103678. +
  103679. + buffer = (gctUINT32_PTR) pointer;
  103680. +
  103681. + count = (bufferSize - flushSize + 7) >> 3;
  103682. +
  103683. + gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical));
  103684. +
  103685. + /* Flush cache. */
  103686. + buffer[0]
  103687. + = ((((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)))
  103688. + | ((((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)))
  103689. + | ((((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)));
  103690. +
  103691. + buffer[1]
  103692. + = ((((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)))
  103693. + | ((((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)))
  103694. + | ((((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)))
  103695. + | ((((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)))
  103696. + | ((((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)))
  103697. + | ((((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)));
  103698. +
  103699. + /* Arm the PE-FE Semaphore. */
  103700. + buffer[2]
  103701. + = ((((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)))
  103702. + | ((((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)))
  103703. + | ((((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)));
  103704. +
  103705. + buffer[3]
  103706. + = ((((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)))
  103707. + | ((((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)));
  103708. +
  103709. + /* STALL FE until PE is done flushing. */
  103710. + buffer[4]
  103711. + = ((((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)));
  103712. +
  103713. + buffer[5]
  103714. + = ((((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)))
  103715. + | ((((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)));
  103716. +
  103717. + /* LINK to next slot to flush FE FIFO. */
  103718. + buffer[6]
  103719. + = ((((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)))
  103720. + | ((((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)));
  103721. +
  103722. + buffer[7]
  103723. + = physical + 8 * gcmSIZEOF(gctUINT32);
  103724. +
  103725. + /* Flush MMU cache. */
  103726. + buffer[8]
  103727. + = ((((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)))
  103728. + | ((((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)))
  103729. + | ((((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)));
  103730. +
  103731. + buffer[9]
  103732. + = (((((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))));
  103733. +
  103734. + /* Arm the PE-FE Semaphore. */
  103735. + buffer[10]
  103736. + = ((((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)))
  103737. + | ((((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)))
  103738. + | ((((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)));
  103739. +
  103740. + buffer[11]
  103741. + = ((((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)))
  103742. + | ((((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)));
  103743. +
  103744. + /* STALL FE until PE is done flushing. */
  103745. + buffer[12]
  103746. + = ((((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)));
  103747. +
  103748. + buffer[13]
  103749. + = ((((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)))
  103750. + | ((((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)));
  103751. +
  103752. + /* LINK to next slot to flush FE FIFO. */
  103753. + buffer[14]
  103754. + = ((((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)))
  103755. + | ((((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)));
  103756. +
  103757. + buffer[15]
  103758. + = physical + flushSize;
  103759. +
  103760. + gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
  103761. + }
  103762. +
  103763. + /* Release the command queue. */
  103764. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
  103765. + commitEntered = gcvFALSE;
  103766. +
  103767. + /* Success. */
  103768. + gcmkFOOTER_NO();
  103769. + return gcvSTATUS_OK;
  103770. +
  103771. +OnError:
  103772. + if (commitEntered)
  103773. + {
  103774. + /* Release the command queue mutex. */
  103775. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
  103776. + gcvFALSE));
  103777. + }
  103778. +
  103779. + /* Return the status. */
  103780. + gcmkFOOTER();
  103781. + return status;
  103782. +}
  103783. +
  103784. +/*******************************************************************************
  103785. +**
  103786. +** gckHARDWARE_SetMMUv2
  103787. +**
  103788. +** Set the page table base address.
  103789. +**
  103790. +** INPUT:
  103791. +**
  103792. +** gckHARDWARE Harwdare
  103793. +** Pointer to an gckHARDWARE object.
  103794. +**
  103795. +** OUTPUT:
  103796. +**
  103797. +** Nothing.
  103798. +*/
  103799. +gceSTATUS
  103800. +gckHARDWARE_SetMMUv2(
  103801. + IN gckHARDWARE Hardware,
  103802. + IN gctBOOL Enable,
  103803. + IN gctPOINTER MtlbAddress,
  103804. + IN gceMMU_MODE Mode,
  103805. + IN gctPOINTER SafeAddress,
  103806. + IN gctBOOL FromPower
  103807. + )
  103808. +{
  103809. + gceSTATUS status;
  103810. + gctUINT32 config, address;
  103811. + gckCOMMAND command;
  103812. + gctUINT32_PTR buffer;
  103813. + gctSIZE_T bufferSize;
  103814. + gctBOOL commitEntered = gcvFALSE;
  103815. + gctPOINTER pointer = gcvNULL;
  103816. + gctBOOL acquired = gcvFALSE;
  103817. + gctBOOL config2D;
  103818. + gctSIZE_T configSize;
  103819. +
  103820. + gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable);
  103821. +
  103822. + /* Verify the arguments. */
  103823. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  103824. +
  103825. + config2D = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)
  103826. + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D);
  103827. +
  103828. + configSize = 4 * 4;
  103829. +
  103830. + if (config2D)
  103831. + {
  103832. + configSize +=
  103833. + /* Pipe Select. */
  103834. + 4 * 4
  103835. + /* Configure MMU States. */
  103836. + + 4 * 4;
  103837. + }
  103838. +
  103839. + /* Convert logical address into physical address. */
  103840. + gcmkONERROR(
  103841. + gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &config));
  103842. +
  103843. + gcmkONERROR(
  103844. + gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &address));
  103845. +
  103846. + if (address & 0x3F)
  103847. + {
  103848. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  103849. + }
  103850. +
  103851. + switch (Mode)
  103852. + {
  103853. + case gcvMMU_MODE_1K:
  103854. + if (config & 0x3FF)
  103855. + {
  103856. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  103857. + }
  103858. +
  103859. + 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)));
  103860. +
  103861. + break;
  103862. +
  103863. + case gcvMMU_MODE_4K:
  103864. + if (config & 0xFFF)
  103865. + {
  103866. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  103867. + }
  103868. +
  103869. + 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)));
  103870. +
  103871. + break;
  103872. +
  103873. + default:
  103874. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  103875. + }
  103876. +
  103877. + /* Verify the gckCOMMAND object pointer. */
  103878. + command = Hardware->kernel->command;
  103879. +
  103880. + /* Acquire the command queue. */
  103881. + gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
  103882. + commitEntered = gcvTRUE;
  103883. +
  103884. + gcmkONERROR(gckCOMMAND_Reserve(
  103885. + command, configSize, &pointer, &bufferSize
  103886. + ));
  103887. +
  103888. + buffer = pointer;
  103889. +
  103890. + buffer[0]
  103891. + = ((((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)))
  103892. + | ((((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)))
  103893. + | ((((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)));
  103894. +
  103895. + buffer[1] = config;
  103896. +
  103897. + buffer[2]
  103898. + = ((((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)))
  103899. + | ((((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)))
  103900. + | ((((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)));
  103901. +
  103902. + buffer[3] = address;
  103903. +
  103904. + if (config2D)
  103905. + {
  103906. + /* LoadState(AQPipeSelect, 1), pipe. */
  103907. + buffer[4]
  103908. + = ((((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)))
  103909. + | ((((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)))
  103910. + | ((((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)));
  103911. +
  103912. + buffer[5] = 0x1;
  103913. +
  103914. + buffer[6]
  103915. + = ((((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)))
  103916. + | ((((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)))
  103917. + | ((((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)));
  103918. +
  103919. + buffer[7] = config;
  103920. +
  103921. + buffer[8]
  103922. + = ((((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)))
  103923. + | ((((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)))
  103924. + | ((((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)));
  103925. +
  103926. + buffer[9] = address;
  103927. +
  103928. + /* LoadState(AQPipeSelect, 1), pipe. */
  103929. + buffer[10]
  103930. + = ((((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)))
  103931. + | ((((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)))
  103932. + | ((((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)));
  103933. +
  103934. + buffer[11] = 0x0;
  103935. + }
  103936. +
  103937. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  103938. + "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address);
  103939. +
  103940. + gcmkONERROR(gckCOMMAND_Execute(command, configSize));
  103941. +
  103942. + if (FromPower == gcvFALSE)
  103943. + {
  103944. + /* Acquire global semaphore to suspend power management until MMU
  103945. + ** is enabled. And acquired it before gckCOMMAND_ExitCommit to
  103946. + ** make sure GPU keeps ON. */
  103947. + gcmkONERROR(
  103948. + gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore));
  103949. +
  103950. + acquired = gcvTRUE;
  103951. + }
  103952. +
  103953. + /* Release the command queue. */
  103954. + gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
  103955. + commitEntered = gcvFALSE;
  103956. +
  103957. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  103958. + "call gckCOMMAND_Stall to make sure the config is done.\n ");
  103959. +
  103960. + gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
  103961. +
  103962. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  103963. + "Enable MMU through GCREG_MMU_CONTROL.");
  103964. +
  103965. + /* Enable MMU. */
  103966. + gcmkONERROR(
  103967. + gckOS_WriteRegisterEx(Hardware->os,
  103968. + Hardware->core,
  103969. + 0x0018C,
  103970. + ((((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)))));
  103971. +
  103972. + if (FromPower == gcvFALSE)
  103973. + {
  103974. + /* Relase global semaphore. */
  103975. + gcmkVERIFY_OK(
  103976. + gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
  103977. +
  103978. + acquired = gcvFALSE;
  103979. + }
  103980. +
  103981. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  103982. + "call gckCOMMAND_Stall to check MMU available.\n");
  103983. +
  103984. + gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
  103985. +
  103986. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  103987. + "The MMU is available.\n");
  103988. +
  103989. + /* Return the status. */
  103990. + gcmkFOOTER_NO();
  103991. + return status;
  103992. +
  103993. +OnError:
  103994. + if (commitEntered)
  103995. + {
  103996. + /* Release the command queue mutex. */
  103997. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
  103998. + FromPower));
  103999. + }
  104000. +
  104001. + if (acquired)
  104002. + {
  104003. + gcmkVERIFY_OK(
  104004. + gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
  104005. + }
  104006. +
  104007. + /* Return the status. */
  104008. + gcmkFOOTER();
  104009. + return status;
  104010. +}
  104011. +
  104012. +/*******************************************************************************
  104013. +**
  104014. +** gckHARDWARE_BuildVirtualAddress
  104015. +**
  104016. +** Build a virtual address.
  104017. +**
  104018. +** INPUT:
  104019. +**
  104020. +** gckHARDWARE Harwdare
  104021. +** Pointer to an gckHARDWARE object.
  104022. +**
  104023. +** gctUINT32 Index
  104024. +** Index into page table.
  104025. +**
  104026. +** gctUINT32 Offset
  104027. +** Offset into page.
  104028. +**
  104029. +** OUTPUT:
  104030. +**
  104031. +** gctUINT32 * Address
  104032. +** Pointer to a variable receiving te hardware address.
  104033. +*/
  104034. +gceSTATUS
  104035. +gckHARDWARE_BuildVirtualAddress(
  104036. + IN gckHARDWARE Hardware,
  104037. + IN gctUINT32 Index,
  104038. + IN gctUINT32 Offset,
  104039. + OUT gctUINT32 * Address
  104040. + )
  104041. +{
  104042. + gcmkHEADER_ARG("Hardware=0x%x Index=%u Offset=%u", Hardware, Index, Offset);
  104043. +
  104044. + /* Verify the arguments. */
  104045. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104046. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  104047. +
  104048. + /* Build virtual address. */
  104049. + *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)))
  104050. + | ((((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)));
  104051. +
  104052. + /* Success. */
  104053. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  104054. + return gcvSTATUS_OK;
  104055. +}
  104056. +
  104057. +gceSTATUS
  104058. +gckHARDWARE_GetIdle(
  104059. + IN gckHARDWARE Hardware,
  104060. + IN gctBOOL Wait,
  104061. + OUT gctUINT32 * Data
  104062. + )
  104063. +{
  104064. + gceSTATUS status;
  104065. + gctUINT32 idle = 0;
  104066. + gctINT retry, poll, pollCount;
  104067. +
  104068. + gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait);
  104069. +
  104070. + /* Verify the arguments. */
  104071. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104072. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  104073. +
  104074. +
  104075. + /* If we have to wait, try 100 polls per millisecond. */
  104076. + pollCount = Wait ? 100 : 1;
  104077. +
  104078. + /* At most, try for 1 second. */
  104079. + for (retry = 0; retry < 1000; ++retry)
  104080. + {
  104081. + /* If we have to wait, try 100 polls per millisecond. */
  104082. + for (poll = pollCount; poll > 0; --poll)
  104083. + {
  104084. + /* Read register. */
  104085. + gcmkONERROR(
  104086. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
  104087. +
  104088. + /* See if we have to wait for FE idle. */
  104089. + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
  104090. + {
  104091. + /* FE is idle. */
  104092. + break;
  104093. + }
  104094. + }
  104095. +
  104096. + /* Check if we need to wait for FE and FE is busy. */
  104097. + 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)))))) ))
  104098. + {
  104099. + /* Wait a little. */
  104100. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104101. + "%s: Waiting for idle: 0x%08X",
  104102. + __FUNCTION__, idle);
  104103. +
  104104. + gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
  104105. + }
  104106. + else
  104107. + {
  104108. + break;
  104109. + }
  104110. + }
  104111. +
  104112. + /* Return idle to caller. */
  104113. + *Data = idle;
  104114. +
  104115. + /* Success. */
  104116. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  104117. + return gcvSTATUS_OK;
  104118. +
  104119. +OnError:
  104120. + /* Return the status. */
  104121. + gcmkFOOTER();
  104122. + return status;
  104123. +}
  104124. +
  104125. +/* Flush the caches. */
  104126. +gceSTATUS
  104127. +gckHARDWARE_Flush(
  104128. + IN gckHARDWARE Hardware,
  104129. + IN gceKERNEL_FLUSH Flush,
  104130. + IN gctPOINTER Logical,
  104131. + IN OUT gctSIZE_T * Bytes
  104132. + )
  104133. +{
  104134. + gctUINT32 pipe;
  104135. + gctUINT32 flush = 0;
  104136. + gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
  104137. + gceSTATUS status;
  104138. + gctBOOL fcFlushStall;
  104139. + gctUINT32 reserveBytes = 8;
  104140. +
  104141. + gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
  104142. + Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
  104143. +
  104144. + /* Verify the arguments. */
  104145. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104146. +
  104147. + /* Get current pipe. */
  104148. + pipe = Hardware->kernel->command->pipeSelect;
  104149. +
  104150. + fcFlushStall
  104151. + = ((((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)))))))
  104152. + && (Flush == gcvFLUSH_ALL)
  104153. + ;
  104154. +
  104155. + if (fcFlushStall)
  104156. + {
  104157. + reserveBytes += 8;
  104158. + }
  104159. +
  104160. + /* Flush 3D color cache. */
  104161. + if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
  104162. + {
  104163. + 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)));
  104164. + }
  104165. +
  104166. + /* Flush 3D depth cache. */
  104167. + if ((Flush & gcvFLUSH_DEPTH) && (pipe == 0x0))
  104168. + {
  104169. + 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)));
  104170. + }
  104171. +
  104172. + /* Flush 3D texture cache. */
  104173. + if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
  104174. + {
  104175. + 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)));
  104176. + 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)));
  104177. + }
  104178. +
  104179. + /* Flush 2D cache. */
  104180. + if ((Flush & gcvFLUSH_2D) && (pipe == 0x1))
  104181. + {
  104182. + 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)));
  104183. + }
  104184. +
  104185. + /* See if there is a valid flush. */
  104186. + if (flush == 0)
  104187. + {
  104188. + if (Bytes != gcvNULL)
  104189. + {
  104190. + /* No bytes required. */
  104191. + *Bytes = 0;
  104192. + }
  104193. + }
  104194. +
  104195. + else
  104196. + {
  104197. + /* Copy to command queue. */
  104198. + if (Logical != gcvNULL)
  104199. + {
  104200. + if (*Bytes < reserveBytes)
  104201. + {
  104202. + /* Command queue too small. */
  104203. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  104204. + }
  104205. +
  104206. + /* Append LOAD_STATE to AQFlush. */
  104207. + 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)))
  104208. + | ((((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)))
  104209. + | ((((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)));
  104210. +
  104211. + logical[1] = flush;
  104212. +
  104213. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104214. + "0x%x: FLUSH 0x%x", logical, flush);
  104215. +
  104216. + if (fcFlushStall)
  104217. + {
  104218. + 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)))
  104219. + | ((((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)))
  104220. + | ((((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)));
  104221. +
  104222. + 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)));
  104223. +
  104224. +
  104225. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104226. + "0x%x: FLUSH 0x%x", logical + 3, logical[3]);
  104227. + }
  104228. +
  104229. + }
  104230. +
  104231. + if (Bytes != gcvNULL)
  104232. + {
  104233. + /* bytes required. */
  104234. + *Bytes = reserveBytes;
  104235. + }
  104236. + }
  104237. +
  104238. + /* Success. */
  104239. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  104240. + return gcvSTATUS_OK;
  104241. +
  104242. +OnError:
  104243. + /* Return the status. */
  104244. + gcmkFOOTER();
  104245. + return status;
  104246. +}
  104247. +
  104248. +gceSTATUS
  104249. +gckHARDWARE_SetFastClear(
  104250. + IN gckHARDWARE Hardware,
  104251. + IN gctINT Enable,
  104252. + IN gctINT Compression
  104253. + )
  104254. +{
  104255. +#ifndef VIVANTE_NO_3D
  104256. + gctUINT32 debug;
  104257. + gceSTATUS status;
  104258. +
  104259. + gcmkHEADER_ARG("Hardware=0x%x Enable=%d Compression=%d",
  104260. + Hardware, Enable, Compression);
  104261. +
  104262. + /* Only process if fast clear is available. */
  104263. + 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)))))) ))
  104264. + {
  104265. + if (Enable == -1)
  104266. + {
  104267. + /* Determine automatic value for fast clear. */
  104268. + Enable = ((Hardware->identity.chipModel != gcv500)
  104269. + || (Hardware->identity.chipRevision >= 3)
  104270. + ) ? 1 : 0;
  104271. + }
  104272. +
  104273. + if (Compression == -1)
  104274. + {
  104275. + /* Determine automatic value for compression. */
  104276. + Compression = Enable
  104277. + & (((((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)))))) );
  104278. + }
  104279. +
  104280. + /* Read AQMemoryDebug register. */
  104281. + gcmkONERROR(
  104282. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug));
  104283. +
  104284. + /* Set fast clear bypass. */
  104285. + 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)));
  104286. +
  104287. + if (
  104288. + ((((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))))))) ||
  104289. + (Hardware->identity.chipModel >= gcv4000))
  104290. + {
  104291. + /* Set compression bypass. */
  104292. + 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)));
  104293. + }
  104294. +
  104295. + /* Write back AQMemoryDebug register. */
  104296. + gcmkONERROR(
  104297. + gckOS_WriteRegisterEx(Hardware->os,
  104298. + Hardware->core,
  104299. + 0x00414,
  104300. + debug));
  104301. +
  104302. + /* Store fast clear and comprersison flags. */
  104303. + Hardware->allowFastClear = Enable;
  104304. + Hardware->allowCompression = Compression;
  104305. +
  104306. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104307. + "FastClear=%d Compression=%d", Enable, Compression);
  104308. + }
  104309. +
  104310. + /* Success. */
  104311. + gcmkFOOTER_NO();
  104312. + return gcvSTATUS_OK;
  104313. +
  104314. +OnError:
  104315. + /* Return the status. */
  104316. + gcmkFOOTER();
  104317. + return status;
  104318. +#else
  104319. + return gcvSTATUS_OK;
  104320. +#endif
  104321. +}
  104322. +
  104323. +typedef enum
  104324. +{
  104325. + gcvPOWER_FLAG_INITIALIZE = 1 << 0,
  104326. + gcvPOWER_FLAG_STALL = 1 << 1,
  104327. + gcvPOWER_FLAG_STOP = 1 << 2,
  104328. + gcvPOWER_FLAG_START = 1 << 3,
  104329. + gcvPOWER_FLAG_RELEASE = 1 << 4,
  104330. + gcvPOWER_FLAG_DELAY = 1 << 5,
  104331. + gcvPOWER_FLAG_SAVE = 1 << 6,
  104332. + gcvPOWER_FLAG_ACQUIRE = 1 << 7,
  104333. + gcvPOWER_FLAG_POWER_OFF = 1 << 8,
  104334. + gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
  104335. + gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
  104336. +}
  104337. +gcePOWER_FLAGS;
  104338. +
  104339. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  104340. +static gctCONST_STRING
  104341. +_PowerEnum(gceCHIPPOWERSTATE State)
  104342. +{
  104343. + const gctCONST_STRING states[] =
  104344. + {
  104345. + gcmSTRING(gcvPOWER_ON),
  104346. + gcmSTRING(gcvPOWER_OFF),
  104347. + gcmSTRING(gcvPOWER_IDLE),
  104348. + gcmSTRING(gcvPOWER_SUSPEND),
  104349. + gcmSTRING(gcvPOWER_SUSPEND_ATPOWERON),
  104350. + gcmSTRING(gcvPOWER_OFF_ATPOWERON),
  104351. + gcmSTRING(gcvPOWER_IDLE_BROADCAST),
  104352. + gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
  104353. + gcmSTRING(gcvPOWER_OFF_BROADCAST),
  104354. + gcmSTRING(gcvPOWER_OFF_RECOVERY),
  104355. + gcmSTRING(gcvPOWER_ON_AUTO)
  104356. + };
  104357. +
  104358. + if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
  104359. + {
  104360. + return states[State - gcvPOWER_ON];
  104361. + }
  104362. +
  104363. + return "unknown";
  104364. +}
  104365. +#endif
  104366. +
  104367. +/*******************************************************************************
  104368. +**
  104369. +** gckHARDWARE_SetPowerManagementState
  104370. +**
  104371. +** Set GPU to a specified power state.
  104372. +**
  104373. +** INPUT:
  104374. +**
  104375. +** gckHARDWARE Harwdare
  104376. +** Pointer to an gckHARDWARE object.
  104377. +**
  104378. +** gceCHIPPOWERSTATE State
  104379. +** Power State.
  104380. +**
  104381. +*/
  104382. +gceSTATUS
  104383. +gckHARDWARE_SetPowerManagementState(
  104384. + IN gckHARDWARE Hardware,
  104385. + IN gceCHIPPOWERSTATE State
  104386. + )
  104387. +{
  104388. + gceSTATUS status;
  104389. + gckCOMMAND command = gcvNULL;
  104390. + gckOS os;
  104391. + gctUINT flag, clock;
  104392. + gctPOINTER buffer;
  104393. + gctSIZE_T bytes, requested;
  104394. + gctBOOL acquired = gcvFALSE;
  104395. + gctBOOL mutexAcquired = gcvFALSE;
  104396. + gctBOOL stall = gcvTRUE;
  104397. + gctBOOL broadcast = gcvFALSE;
  104398. +#if gcdPOWEROFF_TIMEOUT
  104399. + gctBOOL timeout = gcvFALSE;
  104400. + gctBOOL isAfter = gcvFALSE;
  104401. + gctUINT32 currentTime;
  104402. +#endif
  104403. + gctUINT32 process, thread;
  104404. + gctBOOL commitEntered = gcvFALSE;
  104405. + gctBOOL commandStarted = gcvFALSE;
  104406. + gctBOOL isrStarted = gcvFALSE;
  104407. +
  104408. +#if gcdENABLE_PROFILING
  104409. + gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
  104410. + initTime, offTime, startTime, totalTime;
  104411. +#endif
  104412. + gctBOOL global = gcvFALSE;
  104413. + gctBOOL globalAcquired = gcvFALSE;
  104414. + gctBOOL configMmu = gcvFALSE;
  104415. +
  104416. + /* State transition flags. */
  104417. + static const gctUINT flags[4][4] =
  104418. + {
  104419. + /* gcvPOWER_ON */
  104420. + { /* ON */ 0,
  104421. + /* OFF */ gcvPOWER_FLAG_ACQUIRE |
  104422. + gcvPOWER_FLAG_STALL |
  104423. + gcvPOWER_FLAG_STOP |
  104424. + gcvPOWER_FLAG_POWER_OFF |
  104425. + gcvPOWER_FLAG_CLOCK_OFF,
  104426. + /* IDLE */ gcvPOWER_FLAG_ACQUIRE |
  104427. + gcvPOWER_FLAG_STALL,
  104428. + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
  104429. + gcvPOWER_FLAG_STALL |
  104430. + gcvPOWER_FLAG_STOP |
  104431. + gcvPOWER_FLAG_CLOCK_OFF,
  104432. + },
  104433. +
  104434. + /* gcvPOWER_OFF */
  104435. + { /* ON */ gcvPOWER_FLAG_INITIALIZE |
  104436. + gcvPOWER_FLAG_START |
  104437. + gcvPOWER_FLAG_RELEASE |
  104438. + gcvPOWER_FLAG_DELAY,
  104439. + /* OFF */ 0,
  104440. + /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
  104441. + gcvPOWER_FLAG_START |
  104442. + gcvPOWER_FLAG_DELAY,
  104443. + /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
  104444. + gcvPOWER_FLAG_CLOCK_OFF,
  104445. + },
  104446. +
  104447. + /* gcvPOWER_IDLE */
  104448. + { /* ON */ gcvPOWER_FLAG_RELEASE,
  104449. + /* OFF */ gcvPOWER_FLAG_STOP |
  104450. + gcvPOWER_FLAG_POWER_OFF |
  104451. + gcvPOWER_FLAG_CLOCK_OFF,
  104452. + /* IDLE */ 0,
  104453. + /* SUSPEND */ gcvPOWER_FLAG_STOP |
  104454. + gcvPOWER_FLAG_CLOCK_OFF,
  104455. + },
  104456. +
  104457. + /* gcvPOWER_SUSPEND */
  104458. + { /* ON */ gcvPOWER_FLAG_START |
  104459. + gcvPOWER_FLAG_RELEASE |
  104460. + gcvPOWER_FLAG_DELAY |
  104461. + gcvPOWER_FLAG_CLOCK_ON,
  104462. + /* OFF */ gcvPOWER_FLAG_SAVE |
  104463. + gcvPOWER_FLAG_POWER_OFF |
  104464. + gcvPOWER_FLAG_CLOCK_OFF,
  104465. + /* IDLE */ gcvPOWER_FLAG_START |
  104466. + gcvPOWER_FLAG_DELAY |
  104467. + gcvPOWER_FLAG_CLOCK_ON,
  104468. + /* SUSPEND */ 0,
  104469. + },
  104470. + };
  104471. +
  104472. + /* Clocks. */
  104473. + static const gctUINT clocks[4] =
  104474. + {
  104475. + /* gcvPOWER_ON */
  104476. + ((((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))) |
  104477. + ((((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))) |
  104478. + ((((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))) |
  104479. + ((((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))),
  104480. +
  104481. + /* gcvPOWER_OFF */
  104482. + ((((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))) |
  104483. + ((((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))) |
  104484. + ((((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))) |
  104485. + ((((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))),
  104486. +
  104487. + /* gcvPOWER_IDLE */
  104488. + ((((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))) |
  104489. + ((((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))) |
  104490. + ((((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))) |
  104491. + ((((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))),
  104492. +
  104493. + /* gcvPOWER_SUSPEND */
  104494. + ((((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))) |
  104495. + ((((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))) |
  104496. + ((((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))) |
  104497. + ((((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))),
  104498. + };
  104499. +
  104500. + gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
  104501. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  104502. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104503. + "Switching to power state %d(%s)",
  104504. + State, _PowerEnum(State));
  104505. +#endif
  104506. +
  104507. + /* Verify the arguments. */
  104508. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  104509. +
  104510. + /* Get the gckOS object pointer. */
  104511. + os = Hardware->os;
  104512. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  104513. +
  104514. + /* Get the gckCOMMAND object pointer. */
  104515. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  104516. + command = Hardware->kernel->command;
  104517. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  104518. +
  104519. + if (Hardware->powerManagement == gcvFALSE)
  104520. + {
  104521. + gcmkFOOTER_NO();
  104522. + return gcvSTATUS_OK;
  104523. + }
  104524. +
  104525. + /* Start profiler. */
  104526. + gcmkPROFILE_INIT(freq, time);
  104527. +
  104528. + /* Convert the broadcast power state. */
  104529. + switch (State)
  104530. + {
  104531. + case gcvPOWER_SUSPEND_ATPOWERON:
  104532. + /* Convert to SUSPEND and don't wait for STALL. */
  104533. + State = gcvPOWER_SUSPEND;
  104534. + stall = gcvFALSE;
  104535. + break;
  104536. +
  104537. + case gcvPOWER_OFF_ATPOWERON:
  104538. + /* Convert to OFF and don't wait for STALL. */
  104539. + State = gcvPOWER_OFF;
  104540. + stall = gcvFALSE;
  104541. + break;
  104542. +
  104543. + case gcvPOWER_IDLE_BROADCAST:
  104544. + /* Convert to IDLE and note we are inside broadcast. */
  104545. + State = gcvPOWER_IDLE;
  104546. + broadcast = gcvTRUE;
  104547. + break;
  104548. +
  104549. + case gcvPOWER_SUSPEND_BROADCAST:
  104550. + /* Convert to SUSPEND and note we are inside broadcast. */
  104551. + State = gcvPOWER_SUSPEND;
  104552. + broadcast = gcvTRUE;
  104553. + break;
  104554. +
  104555. + case gcvPOWER_OFF_BROADCAST:
  104556. + /* Convert to OFF and note we are inside broadcast. */
  104557. + State = gcvPOWER_OFF;
  104558. + broadcast = gcvTRUE;
  104559. + break;
  104560. +
  104561. + case gcvPOWER_OFF_RECOVERY:
  104562. + /* Convert to OFF and note we are inside recovery. */
  104563. + State = gcvPOWER_OFF;
  104564. + stall = gcvFALSE;
  104565. + broadcast = gcvTRUE;
  104566. + break;
  104567. +
  104568. + case gcvPOWER_ON_AUTO:
  104569. + /* Convert to ON and note we are inside recovery. */
  104570. + State = gcvPOWER_ON;
  104571. + break;
  104572. +
  104573. + case gcvPOWER_ON:
  104574. + case gcvPOWER_IDLE:
  104575. + case gcvPOWER_SUSPEND:
  104576. + case gcvPOWER_OFF:
  104577. + /* Mark as global power management. */
  104578. + global = gcvTRUE;
  104579. + break;
  104580. +
  104581. +#if gcdPOWEROFF_TIMEOUT
  104582. + case gcvPOWER_OFF_TIMEOUT:
  104583. + /* Convert to OFF and note we are inside broadcast. */
  104584. + State = gcvPOWER_OFF;
  104585. + broadcast = gcvTRUE;
  104586. + /* Check time out */
  104587. + timeout = gcvTRUE;
  104588. + break;
  104589. +#endif
  104590. +
  104591. + default:
  104592. + break;
  104593. + }
  104594. +
  104595. + /* Get current process and thread IDs. */
  104596. + gcmkONERROR(gckOS_GetProcessID(&process));
  104597. + gcmkONERROR(gckOS_GetThreadID(&thread));
  104598. +
  104599. + /* Before we grab locks see if this is actually a needed change */
  104600. + if (State == Hardware->chipPowerState)
  104601. + return gcvSTATUS_OK;
  104602. +
  104603. + if (broadcast)
  104604. + {
  104605. + /* Try to acquire the power mutex. */
  104606. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
  104607. +
  104608. + if (status == gcvSTATUS_TIMEOUT)
  104609. + {
  104610. + /* Check if we already own this mutex. */
  104611. + if ((Hardware->powerProcess == process)
  104612. + && (Hardware->powerThread == thread)
  104613. + )
  104614. + {
  104615. + /* Bail out on recursive power management. */
  104616. + gcmkFOOTER_NO();
  104617. + return gcvSTATUS_OK;
  104618. + }
  104619. + else if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  104620. + {
  104621. + /* Called from IST,
  104622. + ** so waiting here will cause deadlock,
  104623. + ** if lock holder call gckCOMMAND_Stall() */
  104624. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  104625. + }
  104626. +#if gcdPOWEROFF_TIMEOUT
  104627. + else if(State == gcvPOWER_OFF && timeout == gcvTRUE)
  104628. + {
  104629. + /*
  104630. + ** try to aqcuire the mutex with more milliseconds,
  104631. + ** flush_delayed_work should be running with timeout,
  104632. + ** so waiting here will cause deadlock */
  104633. + status = gckOS_AcquireMutex(os, Hardware->powerMutex, gcdPOWEROFF_TIMEOUT);
  104634. +
  104635. + if (status == gcvSTATUS_TIMEOUT)
  104636. + {
  104637. + gckOS_Print("GPU Timer deadlock, exit by timeout!!!!\n");
  104638. +
  104639. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  104640. + }
  104641. + }
  104642. +#endif
  104643. + else
  104644. + {
  104645. + /* Acquire the power mutex. */
  104646. + gcmkONERROR(gckOS_AcquireMutex(os,
  104647. + Hardware->powerMutex,
  104648. + gcvINFINITE));
  104649. + }
  104650. + }
  104651. + }
  104652. + else
  104653. + {
  104654. + /* Acquire the power mutex. */
  104655. + gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
  104656. + }
  104657. +
  104658. + /* Get time until mtuex acquired. */
  104659. + gcmkPROFILE_QUERY(time, mutexTime);
  104660. +
  104661. + Hardware->powerProcess = process;
  104662. + Hardware->powerThread = thread;
  104663. + mutexAcquired = gcvTRUE;
  104664. +
  104665. + /* Grab control flags and clock. */
  104666. + flag = flags[Hardware->chipPowerState][State];
  104667. + clock = clocks[State];
  104668. +
  104669. +#if gcdENABLE_FSCALE_VAL_ADJUST
  104670. + if (State == gcvPOWER_ON)
  104671. + {
  104672. + 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)));
  104673. + }
  104674. +#endif
  104675. +
  104676. + if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
  104677. + {
  104678. +#if gcdPOWER_SUSNPEND_WHEN_IDLE
  104679. + /* Do nothing */
  104680. +
  104681. + /* Release the power mutex. */
  104682. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  104683. +
  104684. + gcmkFOOTER_NO();
  104685. + return gcvSTATUS_OK;
  104686. +#else
  104687. + /* Clock should be on when switch power from off to suspend */
  104688. + 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))) |
  104689. + ((((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))) |
  104690. + ((((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))) |
  104691. + ((((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))) ;
  104692. +#endif
  104693. + }
  104694. +
  104695. +#if gcdPOWEROFF_TIMEOUT
  104696. + if (timeout)
  104697. + {
  104698. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  104699. +
  104700. + gcmkONERROR(
  104701. + gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
  104702. +
  104703. + /* powerOffTime is pushed forward, give up.*/
  104704. + if (isAfter
  104705. + /* Expect a transition start from IDLE or SUSPEND. */
  104706. + || (Hardware->chipPowerState == gcvPOWER_ON)
  104707. + || (Hardware->chipPowerState == gcvPOWER_OFF)
  104708. + )
  104709. + {
  104710. + /* Release the power mutex. */
  104711. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  104712. +
  104713. + /* No need to do anything. */
  104714. + gcmkFOOTER_NO();
  104715. + return gcvSTATUS_OK;
  104716. + }
  104717. +
  104718. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104719. + "Power Off GPU[%d] at %u [supposed to be at %u]",
  104720. + Hardware->core, currentTime, Hardware->powerOffTime);
  104721. + }
  104722. +
  104723. + if (State == gcvPOWER_ON || State == gcvPOWER_OFF)
  104724. + {
  104725. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
  104726. +
  104727. + /* Cancel running timer when GPU enters ON or OFF. */
  104728. + gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
  104729. + }
  104730. +#endif
  104731. +
  104732. + if (flag == 0)
  104733. + {
  104734. + /* Release the power mutex. */
  104735. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  104736. +
  104737. + /* No need to do anything. */
  104738. + gcmkFOOTER_NO();
  104739. + return gcvSTATUS_OK;
  104740. + }
  104741. +
  104742. + /* If this is an internal power management, we have to check if we can grab
  104743. + ** the global power semaphore. If we cannot, we have to wait until the
  104744. + ** external world changes power management. */
  104745. + if (!global)
  104746. + {
  104747. + /* Try to acquire the global semaphore. */
  104748. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  104749. + if (status == gcvSTATUS_TIMEOUT)
  104750. + {
  104751. + if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  104752. + {
  104753. + /* Called from thread routine which should NEVER sleep.*/
  104754. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  104755. + }
  104756. +
  104757. + /* Release the power mutex. */
  104758. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104759. + "Releasing the power mutex.");
  104760. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  104761. + mutexAcquired = gcvFALSE;
  104762. +
  104763. + /* Wait for the semaphore. */
  104764. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104765. + "Waiting for global semaphore.");
  104766. + gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
  104767. + globalAcquired = gcvTRUE;
  104768. +
  104769. + /* Acquire the power mutex. */
  104770. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  104771. + "Reacquiring the power mutex.");
  104772. + gcmkONERROR(gckOS_AcquireMutex(os,
  104773. + Hardware->powerMutex,
  104774. + gcvINFINITE));
  104775. + mutexAcquired = gcvTRUE;
  104776. +
  104777. + /* chipPowerState may be changed by external world during the time
  104778. + ** we give up powerMutex, so updating flag now is necessary. */
  104779. + flag = flags[Hardware->chipPowerState][State];
  104780. +
  104781. + if (flag == 0)
  104782. + {
  104783. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  104784. + globalAcquired = gcvFALSE;
  104785. +
  104786. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  104787. + mutexAcquired = gcvFALSE;
  104788. +
  104789. + gcmkFOOTER_NO();
  104790. + return gcvSTATUS_OK;
  104791. + }
  104792. + }
  104793. + else
  104794. + {
  104795. + /* Error. */
  104796. + gcmkONERROR(status);
  104797. + }
  104798. +
  104799. + /* Release the global semaphore again. */
  104800. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  104801. + globalAcquired = gcvFALSE;
  104802. + }
  104803. + else
  104804. + {
  104805. + if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
  104806. + {
  104807. + /* Acquire the global semaphore if it has not been acquired. */
  104808. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  104809. + if (status == gcvSTATUS_OK)
  104810. + {
  104811. + globalAcquired = gcvTRUE;
  104812. + }
  104813. + else if (status != gcvSTATUS_TIMEOUT)
  104814. + {
  104815. + /* Other errors. */
  104816. + gcmkONERROR(status);
  104817. + }
  104818. + /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
  104819. + ** gcvSTATUS_TIMEOUT means global semaphore has already
  104820. + ** been acquired before this operation, so even if we fail,
  104821. + ** we should not release it in our error handling. It should be
  104822. + ** released by the next successful global gcvPOWER_ON. */
  104823. + }
  104824. +
  104825. + /* Global power management can't be aborted, so sync with
  104826. + ** proceeding last commit. */
  104827. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  104828. + {
  104829. + /* Acquire the power management semaphore. */
  104830. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  104831. + acquired = gcvTRUE;
  104832. +
  104833. + /* avoid acquiring again. */
  104834. + flag &= ~gcvPOWER_FLAG_ACQUIRE;
  104835. + }
  104836. + }
  104837. +
  104838. + if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
  104839. + {
  104840. + /* Turn on the power. */
  104841. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
  104842. +
  104843. + /* Mark clock and power as enabled. */
  104844. + Hardware->clockState = gcvTRUE;
  104845. + Hardware->powerState = gcvTRUE;
  104846. +
  104847. + for (;;)
  104848. + {
  104849. + /* Check if GPU is present and awake. */
  104850. + status = _IsGPUPresent(Hardware);
  104851. +
  104852. + /* Check if the GPU is not responding. */
  104853. + if (status == gcvSTATUS_GPU_NOT_RESPONDING)
  104854. + {
  104855. + /* Turn off the power and clock. */
  104856. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvFALSE, gcvFALSE));
  104857. +
  104858. + Hardware->clockState = gcvFALSE;
  104859. + Hardware->powerState = gcvFALSE;
  104860. +
  104861. + /* Wait a little. */
  104862. + gckOS_Delay(os, 1);
  104863. +
  104864. + /* Turn on the power and clock. */
  104865. + gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
  104866. +
  104867. + Hardware->clockState = gcvTRUE;
  104868. + Hardware->powerState = gcvTRUE;
  104869. +
  104870. + /* We need to initialize the hardware and start the command
  104871. + * processor. */
  104872. + flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
  104873. + }
  104874. + else
  104875. + {
  104876. + /* Test for error. */
  104877. + gcmkONERROR(status);
  104878. +
  104879. + /* Break out of loop. */
  104880. + break;
  104881. + }
  104882. + }
  104883. + }
  104884. +
  104885. + /* Get time until powered on. */
  104886. + gcmkPROFILE_QUERY(time, onTime);
  104887. +
  104888. + if ((flag & gcvPOWER_FLAG_STALL) && stall)
  104889. + {
  104890. + gctBOOL idle;
  104891. + gctINT32 atomValue;
  104892. +
  104893. + /* For global operation, all pending commits have already been
  104894. + ** blocked by globalSemaphore or powerSemaphore.*/
  104895. + if (!global)
  104896. + {
  104897. + /* Check commit atom. */
  104898. + gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
  104899. +
  104900. + if (atomValue > 0)
  104901. + {
  104902. + /* Commits are pending - abort power management. */
  104903. + status = broadcast ? gcvSTATUS_CHIP_NOT_READY
  104904. + : gcvSTATUS_MORE_DATA;
  104905. + goto OnError;
  104906. + }
  104907. + }
  104908. +
  104909. + if (broadcast)
  104910. + {
  104911. + /* Check for idle. */
  104912. + gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
  104913. +
  104914. + if (!idle)
  104915. + {
  104916. + status = gcvSTATUS_CHIP_NOT_READY;
  104917. + goto OnError;
  104918. + }
  104919. + }
  104920. +
  104921. + else
  104922. + {
  104923. + /* Acquire the command queue. */
  104924. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvTRUE));
  104925. + commitEntered = gcvTRUE;
  104926. +
  104927. + /* Get the size of the flush command. */
  104928. + gcmkONERROR(gckHARDWARE_Flush(Hardware,
  104929. + gcvFLUSH_ALL,
  104930. + gcvNULL,
  104931. + &requested));
  104932. +
  104933. + /* Reserve space in the command queue. */
  104934. + gcmkONERROR(gckCOMMAND_Reserve(command,
  104935. + requested,
  104936. + &buffer,
  104937. + &bytes));
  104938. +
  104939. + /* Append a flush. */
  104940. + gcmkONERROR(gckHARDWARE_Flush(
  104941. + Hardware, gcvFLUSH_ALL, buffer, &bytes
  104942. + ));
  104943. +
  104944. + /* Execute the command queue. */
  104945. + gcmkONERROR(gckCOMMAND_Execute(command, requested));
  104946. +
  104947. + /* Release the command queue. */
  104948. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvTRUE));
  104949. + commitEntered = gcvFALSE;
  104950. +
  104951. + /* Wait to finish all commands. */
  104952. + gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
  104953. + }
  104954. + }
  104955. +
  104956. + /* Get time until stalled. */
  104957. + gcmkPROFILE_QUERY(time, stallTime);
  104958. +
  104959. + if (flag & gcvPOWER_FLAG_ACQUIRE)
  104960. + {
  104961. + /* Acquire the power management semaphore. */
  104962. + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
  104963. + acquired = gcvTRUE;
  104964. + }
  104965. +
  104966. + if (flag & gcvPOWER_FLAG_STOP)
  104967. + {
  104968. + /* Stop the command parser. */
  104969. + gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
  104970. +
  104971. + /* Stop the Isr. */
  104972. + if (Hardware->stopIsr)
  104973. + {
  104974. + gcmkONERROR(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  104975. + }
  104976. + }
  104977. +
  104978. + /* Flush Cache before Power Off. */
  104979. + if (flag & gcvPOWER_FLAG_POWER_OFF)
  104980. + {
  104981. + if (Hardware->clockState == gcvFALSE)
  104982. + {
  104983. + /* Turn off the GPU power. */
  104984. + gcmkONERROR(
  104985. + gckOS_SetGPUPower(os,
  104986. + Hardware->core,
  104987. + gcvTRUE,
  104988. + gcvTRUE));
  104989. +
  104990. + Hardware->clockState = gcvTRUE;
  104991. +
  104992. + if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE)
  104993. + {
  104994. + /* Write the clock control register. */
  104995. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  104996. + Hardware->core,
  104997. + 0x00000,
  104998. + clocks[0]));
  104999. +
  105000. + /* Done loading the frequency scaler. */
  105001. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  105002. + Hardware->core,
  105003. + 0x00000,
  105004. + ((((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)))));
  105005. + }
  105006. + }
  105007. +
  105008. + gcmkONERROR(gckCOMMAND_Start(command));
  105009. +
  105010. + gcmkONERROR(_FlushCache(Hardware, command));
  105011. +
  105012. + gckOS_Delay(gcvNULL, 1);
  105013. +
  105014. + /* Stop the command parser. */
  105015. + gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
  105016. +
  105017. + flag |= gcvPOWER_FLAG_CLOCK_OFF;
  105018. + }
  105019. +
  105020. + /* Get time until stopped. */
  105021. + gcmkPROFILE_QUERY(time, stopTime);
  105022. +
  105023. + /* Only process this when hardware is enabled. */
  105024. + if (Hardware->clockState && Hardware->powerState
  105025. + /* Don't touch clock control if dynamic frequency scaling is available. */
  105026. + && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
  105027. + )
  105028. + {
  105029. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  105030. + {
  105031. + if (Hardware->identity.chipModel == gcv4000
  105032. + && Hardware->identity.chipRevision == 0x5208)
  105033. + {
  105034. + clock &= ~2U;
  105035. + }
  105036. + }
  105037. +
  105038. + /* Write the clock control register. */
  105039. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  105040. + Hardware->core,
  105041. + 0x00000,
  105042. + clock));
  105043. +
  105044. + /* Done loading the frequency scaler. */
  105045. + gcmkONERROR(gckOS_WriteRegisterEx(os,
  105046. + Hardware->core,
  105047. + 0x00000,
  105048. + ((((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)))));
  105049. + }
  105050. +
  105051. + if (flag & gcvPOWER_FLAG_DELAY)
  105052. + {
  105053. + /* Wait for the specified amount of time to settle coming back from
  105054. + ** power-off or suspend state. */
  105055. + gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
  105056. + }
  105057. +
  105058. + /* Get time until delayed. */
  105059. + gcmkPROFILE_QUERY(time, delayTime);
  105060. +
  105061. + if (flag & gcvPOWER_FLAG_INITIALIZE)
  105062. + {
  105063. + /* Initialize hardware. */
  105064. + gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
  105065. +
  105066. + gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
  105067. + Hardware->allowFastClear,
  105068. + Hardware->allowCompression));
  105069. +
  105070. + /* Force the command queue to reload the next context. */
  105071. + command->currContext = gcvNULL;
  105072. +
  105073. + /* Need to config mmu after command start. */
  105074. + configMmu = gcvTRUE;
  105075. + }
  105076. +
  105077. + /* Get time until initialized. */
  105078. + gcmkPROFILE_QUERY(time, initTime);
  105079. +
  105080. + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
  105081. + {
  105082. + /* Turn off the GPU power. */
  105083. + gcmkONERROR(
  105084. + gckOS_SetGPUPower(os,
  105085. + Hardware->core,
  105086. + (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  105087. + : gcvTRUE,
  105088. + (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  105089. + : gcvTRUE));
  105090. +
  105091. + /* Save current hardware power and clock states. */
  105092. + Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
  105093. + : gcvTRUE;
  105094. + Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
  105095. + : gcvTRUE;
  105096. + }
  105097. +
  105098. + /* Get time until off. */
  105099. + gcmkPROFILE_QUERY(time, offTime);
  105100. +
  105101. + if (flag & gcvPOWER_FLAG_START)
  105102. + {
  105103. + /* Start the command processor. */
  105104. + gcmkONERROR(gckCOMMAND_Start(command));
  105105. + commandStarted = gcvTRUE;
  105106. +
  105107. + if (Hardware->startIsr)
  105108. + {
  105109. + /* Start the Isr. */
  105110. + gcmkONERROR(Hardware->startIsr(Hardware->isrContext, Hardware->core));
  105111. + isrStarted = gcvTRUE;
  105112. + }
  105113. +
  105114. + /* Set NEW MMU. */
  105115. + if (Hardware->mmuVersion != 0 && configMmu)
  105116. + {
  105117. + gcmkONERROR(
  105118. + gckHARDWARE_SetMMUv2(
  105119. + Hardware,
  105120. + gcvTRUE,
  105121. + Hardware->kernel->mmu->mtlbLogical,
  105122. + gcvMMU_MODE_4K,
  105123. + (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  105124. + gcvTRUE
  105125. + ));
  105126. + }
  105127. + }
  105128. +
  105129. + /* Get time until started. */
  105130. + gcmkPROFILE_QUERY(time, startTime);
  105131. +
  105132. + if (flag & gcvPOWER_FLAG_RELEASE)
  105133. + {
  105134. + /* Release the power management semaphore. */
  105135. + gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
  105136. + acquired = gcvFALSE;
  105137. +
  105138. + if (global)
  105139. + {
  105140. + /* Verify global semaphore has been acquired already before
  105141. + ** we release it.
  105142. + ** If it was acquired, gckOS_TryAcquireSemaphore will return
  105143. + ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
  105144. + ** semaphore will be acquried now, but it still is released
  105145. + ** immediately. */
  105146. + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
  105147. + if (status != gcvSTATUS_TIMEOUT)
  105148. + {
  105149. + gcmkONERROR(status);
  105150. + }
  105151. +
  105152. + /* Release the global semaphore. */
  105153. + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
  105154. + globalAcquired = gcvFALSE;
  105155. + }
  105156. + }
  105157. +
  105158. + /* Save the new power state. */
  105159. + Hardware->chipPowerState = State;
  105160. +
  105161. +#if gcdDVFS
  105162. + if (State == gcvPOWER_ON && Hardware->kernel->dvfs)
  105163. + {
  105164. + gckDVFS_Start(Hardware->kernel->dvfs);
  105165. + }
  105166. +#endif
  105167. +
  105168. +#if gcdPOWEROFF_TIMEOUT
  105169. + if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
  105170. + {
  105171. + gcmkONERROR(gckOS_GetTicks(&currentTime));
  105172. +
  105173. + Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
  105174. + /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
  105175. + gcmkVERIFY_OK(gckOS_StartTimer(os,
  105176. + Hardware->powerOffTimer,
  105177. + Hardware->powerOffTimeout));
  105178. + }
  105179. +#endif
  105180. +
  105181. + /* Release the power mutex. */
  105182. + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
  105183. +
  105184. + /* Get total time. */
  105185. + gcmkPROFILE_QUERY(time, totalTime);
  105186. +#if gcdENABLE_PROFILING
  105187. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  105188. + "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
  105189. + freq, mutexTime, onTime, stallTime, stopTime);
  105190. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  105191. + " delay:%llu init:%llu off:%llu start:%llu total:%llu",
  105192. + delayTime, initTime, offTime, startTime, totalTime);
  105193. +#endif
  105194. +
  105195. + /* Success. */
  105196. + gcmkFOOTER_NO();
  105197. + return gcvSTATUS_OK;
  105198. +
  105199. +OnError:
  105200. + if (commandStarted)
  105201. + {
  105202. + gcmkVERIFY_OK(gckCOMMAND_Stop(command, gcvFALSE));
  105203. + }
  105204. +
  105205. + if (isrStarted)
  105206. + {
  105207. + gcmkVERIFY_OK(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  105208. + }
  105209. +
  105210. + if (commitEntered)
  105211. + {
  105212. + /* Release the command queue mutex. */
  105213. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvTRUE));
  105214. + }
  105215. +
  105216. + if (acquired)
  105217. + {
  105218. + /* Release semaphore. */
  105219. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  105220. + command->powerSemaphore));
  105221. + }
  105222. +
  105223. + if (globalAcquired)
  105224. + {
  105225. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
  105226. + Hardware->globalSemaphore));
  105227. + }
  105228. +
  105229. + if (mutexAcquired)
  105230. + {
  105231. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  105232. + }
  105233. +
  105234. + /* Return the status. */
  105235. + gcmkFOOTER();
  105236. + return status;
  105237. +}
  105238. +
  105239. +/*******************************************************************************
  105240. +**
  105241. +** gckHARDWARE_QueryPowerManagementState
  105242. +**
  105243. +** Get GPU power state.
  105244. +**
  105245. +** INPUT:
  105246. +**
  105247. +** gckHARDWARE Harwdare
  105248. +** Pointer to an gckHARDWARE object.
  105249. +**
  105250. +** gceCHIPPOWERSTATE* State
  105251. +** Power State.
  105252. +**
  105253. +*/
  105254. +gceSTATUS
  105255. +gckHARDWARE_QueryPowerManagementState(
  105256. + IN gckHARDWARE Hardware,
  105257. + OUT gceCHIPPOWERSTATE* State
  105258. + )
  105259. +{
  105260. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  105261. +
  105262. + /* Verify the arguments. */
  105263. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105264. + gcmkVERIFY_ARGUMENT(State != gcvNULL);
  105265. +
  105266. + /* Return the statue. */
  105267. + *State = Hardware->chipPowerState;
  105268. +
  105269. + /* Success. */
  105270. + gcmkFOOTER_ARG("*State=%d", *State);
  105271. + return gcvSTATUS_OK;
  105272. +}
  105273. +
  105274. +/*******************************************************************************
  105275. +**
  105276. +** gckHARDWARE_SetPowerManagement
  105277. +**
  105278. +** Configure GPU power management function.
  105279. +** Only used in driver initialization stage.
  105280. +**
  105281. +** INPUT:
  105282. +**
  105283. +** gckHARDWARE Harwdare
  105284. +** Pointer to an gckHARDWARE object.
  105285. +**
  105286. +** gctBOOL PowerManagement
  105287. +** Power Mangement State.
  105288. +**
  105289. +*/
  105290. +gceSTATUS
  105291. +gckHARDWARE_SetPowerManagement(
  105292. + IN gckHARDWARE Hardware,
  105293. + IN gctBOOL PowerManagement
  105294. + )
  105295. +{
  105296. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  105297. +
  105298. + /* Verify the arguments. */
  105299. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105300. +
  105301. + Hardware->powerManagement = PowerManagement;
  105302. +
  105303. + /* Success. */
  105304. + gcmkFOOTER_NO();
  105305. + return gcvSTATUS_OK;
  105306. +}
  105307. +
  105308. +/*******************************************************************************
  105309. +**
  105310. +** gckHARDWARE_SetGpuProfiler
  105311. +**
  105312. +** Configure GPU profiler function.
  105313. +** Only used in driver initialization stage.
  105314. +**
  105315. +** INPUT:
  105316. +**
  105317. +** gckHARDWARE Harwdare
  105318. +** Pointer to an gckHARDWARE object.
  105319. +**
  105320. +** gctBOOL GpuProfiler
  105321. +** GOU Profiler State.
  105322. +**
  105323. +*/
  105324. +gceSTATUS
  105325. +gckHARDWARE_SetGpuProfiler(
  105326. + IN gckHARDWARE Hardware,
  105327. + IN gctBOOL GpuProfiler
  105328. + )
  105329. +{
  105330. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  105331. +
  105332. + /* Verify the arguments. */
  105333. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105334. +
  105335. + Hardware->gpuProfiler = GpuProfiler;
  105336. +
  105337. + /* Success. */
  105338. + gcmkFOOTER_NO();
  105339. + return gcvSTATUS_OK;
  105340. +}
  105341. +
  105342. +#if gcdENABLE_FSCALE_VAL_ADJUST
  105343. +gceSTATUS
  105344. +gckHARDWARE_SetFscaleValue(
  105345. + IN gckHARDWARE Hardware,
  105346. + IN gctUINT32 FscaleValue
  105347. + )
  105348. +{
  105349. + gceSTATUS status;
  105350. + gctUINT32 clock;
  105351. + gctBOOL acquired = gcvFALSE;
  105352. +
  105353. + gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
  105354. +
  105355. + gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
  105356. +
  105357. + gcmkONERROR(
  105358. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
  105359. + acquired = gcvTRUE;
  105360. +
  105361. + Hardware->powerOnFscaleVal = FscaleValue;
  105362. +
  105363. + if (Hardware->chipPowerState == gcvPOWER_ON)
  105364. + {
  105365. + gctUINT32 data;
  105366. +
  105367. + gcmkONERROR(
  105368. + gckOS_ReadRegisterEx(Hardware->os,
  105369. + Hardware->core,
  105370. + Hardware->powerBaseAddress
  105371. + + 0x00104,
  105372. + &data));
  105373. +
  105374. + /* Disable all clock gating. */
  105375. + gcmkONERROR(
  105376. + gckOS_WriteRegisterEx(Hardware->os,
  105377. + Hardware->core,
  105378. + Hardware->powerBaseAddress
  105379. + + 0x00104,
  105380. + ((((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)))
  105381. + | ((((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)))
  105382. + | ((((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)))
  105383. + | ((((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)))
  105384. + | ((((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)))
  105385. + | ((((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)))
  105386. + | ((((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)))
  105387. + | ((((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)))
  105388. + | ((((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)))
  105389. + | ((((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)))
  105390. + | ((((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)))));
  105391. +
  105392. + 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)))
  105393. + | ((((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)))
  105394. + | ((((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)))
  105395. + | ((((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)));
  105396. +
  105397. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105398. + Hardware->core,
  105399. + 0x00000,
  105400. + clock));
  105401. +
  105402. + /* Done loading the frequency scaler. */
  105403. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105404. + Hardware->core,
  105405. + 0x00000,
  105406. + ((((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)))));
  105407. +
  105408. + /* Restore all clock gating. */
  105409. + gcmkONERROR(
  105410. + gckOS_WriteRegisterEx(Hardware->os,
  105411. + Hardware->core,
  105412. + Hardware->powerBaseAddress
  105413. + + 0x00104,
  105414. + data));
  105415. + }
  105416. +
  105417. + gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  105418. +
  105419. + gcmkFOOTER_NO();
  105420. + return gcvSTATUS_OK;
  105421. +
  105422. +OnError:
  105423. + if (acquired)
  105424. + {
  105425. + gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  105426. + }
  105427. +
  105428. + gcmkFOOTER();
  105429. + return status;
  105430. +}
  105431. +
  105432. +gceSTATUS
  105433. +gckHARDWARE_GetFscaleValue(
  105434. + IN gckHARDWARE Hardware,
  105435. + IN gctUINT * FscaleValue,
  105436. + IN gctUINT * MinFscaleValue,
  105437. + IN gctUINT * MaxFscaleValue
  105438. + )
  105439. +{
  105440. + *FscaleValue = Hardware->powerOnFscaleVal;
  105441. + if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR))
  105442. + *MinFscaleValue = gpu3DMinClock;
  105443. + else
  105444. + *MinFscaleValue = 1;
  105445. + *MaxFscaleValue = 64;
  105446. +
  105447. + return gcvSTATUS_OK;
  105448. +}
  105449. +
  105450. +#endif
  105451. +
  105452. +#if gcdPOWEROFF_TIMEOUT
  105453. +gceSTATUS
  105454. +gckHARDWARE_SetPowerOffTimeout(
  105455. + IN gckHARDWARE Hardware,
  105456. + IN gctUINT32 Timeout
  105457. +)
  105458. +{
  105459. + gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
  105460. +
  105461. + Hardware->powerOffTimeout = Timeout;
  105462. +
  105463. + gcmkFOOTER_NO();
  105464. + return gcvSTATUS_OK;
  105465. +}
  105466. +
  105467. +
  105468. +gceSTATUS
  105469. +gckHARDWARE_QueryPowerOffTimeout(
  105470. + IN gckHARDWARE Hardware,
  105471. + OUT gctUINT32* Timeout
  105472. +)
  105473. +{
  105474. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  105475. +
  105476. + *Timeout = Hardware->powerOffTimeout;
  105477. +
  105478. + gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
  105479. + return gcvSTATUS_OK;
  105480. +}
  105481. +#endif
  105482. +
  105483. +gceSTATUS
  105484. +gckHARDWARE_QueryIdle(
  105485. + IN gckHARDWARE Hardware,
  105486. + OUT gctBOOL_PTR IsIdle
  105487. + )
  105488. +{
  105489. + gceSTATUS status;
  105490. + gctUINT32 idle, address;
  105491. +
  105492. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  105493. +
  105494. + /* Verify the arguments. */
  105495. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105496. + gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
  105497. +
  105498. + /* We are idle when the power is not ON. */
  105499. + if (Hardware->chipPowerState != gcvPOWER_ON)
  105500. + {
  105501. + *IsIdle = gcvTRUE;
  105502. + }
  105503. +
  105504. + else
  105505. + {
  105506. + /* Read idle register. */
  105507. + gcmkONERROR(
  105508. + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
  105509. +
  105510. + /* Pipe must be idle. */
  105511. + 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)
  105512. + || ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1)
  105513. + || ((((((gctUINT32) (idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1)
  105514. + || ((((((gctUINT32) (idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1)
  105515. + || ((((((gctUINT32) (idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1)
  105516. + || ((((((gctUINT32) (idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1)
  105517. + || ((((((gctUINT32) (idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1)
  105518. + )
  105519. + {
  105520. + /* Something is busy. */
  105521. + *IsIdle = gcvFALSE;
  105522. + }
  105523. +
  105524. + else
  105525. + {
  105526. + /* Read the current FE address. */
  105527. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105528. + Hardware->core,
  105529. + 0x00664,
  105530. + &address));
  105531. +
  105532. + /* Test if address is inside the last WAIT/LINK sequence. */
  105533. + if ((address >= Hardware->lastWaitLink)
  105534. + && (address <= Hardware->lastWaitLink + 16)
  105535. + )
  105536. + {
  105537. + /* FE is in last WAIT/LINK and the pipe is idle. */
  105538. + *IsIdle = gcvTRUE;
  105539. + }
  105540. + else
  105541. + {
  105542. + /* FE is not in WAIT/LINK yet. */
  105543. + *IsIdle = gcvFALSE;
  105544. + }
  105545. + }
  105546. + }
  105547. +
  105548. + /* Success. */
  105549. + gcmkFOOTER_NO();
  105550. + return gcvSTATUS_OK;
  105551. +
  105552. +OnError:
  105553. + /* Return the status. */
  105554. + gcmkFOOTER();
  105555. + return status;
  105556. +}
  105557. +
  105558. +/*******************************************************************************
  105559. +** Handy macros that will help in reading those debug registers.
  105560. +*/
  105561. +
  105562. +#define gcmkREAD_DEBUG_REGISTER(control, block, index, data) \
  105563. + gcmkONERROR(\
  105564. + gckOS_WriteRegisterEx(Hardware->os, \
  105565. + Hardware->core, \
  105566. + GC_DEBUG_CONTROL##control##_Address, \
  105567. + gcmSETFIELD(0, \
  105568. + GC_DEBUG_CONTROL##control, \
  105569. + block, \
  105570. + index))); \
  105571. + gcmkONERROR(\
  105572. + gckOS_ReadRegisterEx(Hardware->os, \
  105573. + Hardware->core, \
  105574. + GC_DEBUG_SIGNALS_##block##_Address, \
  105575. + &profiler->data))
  105576. +
  105577. +#define gcmkREAD_DEBUG_REGISTER_N(control, block, index, data) \
  105578. + gcmkONERROR(\
  105579. + gckOS_WriteRegisterEx(Hardware->os, \
  105580. + Hardware->core, \
  105581. + GC_DEBUG_CONTROL##control##_Address, \
  105582. + gcmSETFIELD(0, \
  105583. + GC_DEBUG_CONTROL##control, \
  105584. + block, \
  105585. + index))); \
  105586. + gcmkONERROR(\
  105587. + gckOS_ReadRegisterEx(Hardware->os, \
  105588. + Hardware->core, \
  105589. + GC_DEBUG_SIGNALS_##block##_Address, \
  105590. + &data))
  105591. +
  105592. +#define gcmkRESET_DEBUG_REGISTER(control, block) \
  105593. + gcmkONERROR(\
  105594. + gckOS_WriteRegisterEx(Hardware->os, \
  105595. + Hardware->core, \
  105596. + GC_DEBUG_CONTROL##control##_Address, \
  105597. + gcmSETFIELD(0, \
  105598. + GC_DEBUG_CONTROL##control, \
  105599. + block, \
  105600. + 15))); \
  105601. + gcmkONERROR(\
  105602. + gckOS_WriteRegisterEx(Hardware->os, \
  105603. + Hardware->core, \
  105604. + GC_DEBUG_CONTROL##control##_Address, \
  105605. + gcmSETFIELD(0, \
  105606. + GC_DEBUG_CONTROL##control, \
  105607. + block, \
  105608. + 0)))
  105609. +
  105610. +/*******************************************************************************
  105611. +**
  105612. +** gckHARDWARE_ProfileEngine2D
  105613. +**
  105614. +** Read the profile registers available in the 2D engine and sets them in the
  105615. +** profile. The function will also reset the pixelsRendered counter every time.
  105616. +**
  105617. +** INPUT:
  105618. +**
  105619. +** gckHARDWARE Hardware
  105620. +** Pointer to an gckHARDWARE object.
  105621. +**
  105622. +** OPTIONAL gcs2D_PROFILE_PTR Profile
  105623. +** Pointer to a gcs2D_Profile structure.
  105624. +**
  105625. +** OUTPUT:
  105626. +**
  105627. +** Nothing.
  105628. +*/
  105629. +gceSTATUS
  105630. +gckHARDWARE_ProfileEngine2D(
  105631. + IN gckHARDWARE Hardware,
  105632. + OPTIONAL gcs2D_PROFILE_PTR Profile
  105633. + )
  105634. +{
  105635. + gceSTATUS status;
  105636. + gcs2D_PROFILE_PTR profiler = Profile;
  105637. +
  105638. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  105639. +
  105640. + /* Verify the arguments. */
  105641. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105642. +
  105643. + if (Profile != gcvNULL)
  105644. + {
  105645. + /* Read the cycle count. */
  105646. + gcmkONERROR(
  105647. + gckOS_ReadRegisterEx(Hardware->os,
  105648. + Hardware->core,
  105649. + 0x00438,
  105650. + &Profile->cycleCount));
  105651. +
  105652. + /* Read pixels rendered by 2D engine. */
  105653. + 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))) ));
  105654. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pixelsRendered));
  105655. +
  105656. + /* Reset counter. */
  105657. + 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))) ));
  105658. +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)))
  105659. +));
  105660. + }
  105661. +
  105662. + /* Success. */
  105663. + gcmkFOOTER_NO();
  105664. + return gcvSTATUS_OK;
  105665. +
  105666. +OnError:
  105667. + /* Return the status. */
  105668. + gcmkFOOTER();
  105669. + return status;
  105670. +}
  105671. +
  105672. +#if VIVANTE_PROFILER
  105673. +gceSTATUS
  105674. +gckHARDWARE_QueryProfileRegisters(
  105675. + IN gckHARDWARE Hardware,
  105676. + IN gctBOOL Reset,
  105677. + OUT gcsPROFILER_COUNTERS * Counters
  105678. + )
  105679. +{
  105680. + gceSTATUS status;
  105681. + gcsPROFILER_COUNTERS * profiler = Counters;
  105682. + gctUINT i, clock;
  105683. + gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
  105684. + gctUINT32 totalRead, totalWrite;
  105685. +
  105686. + gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
  105687. +
  105688. + /* Verify the arguments. */
  105689. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105690. +
  105691. + /* Read the counters. */
  105692. + gcmkONERROR(
  105693. + gckOS_ReadRegisterEx(Hardware->os,
  105694. + Hardware->core,
  105695. + 0x00438,
  105696. + &profiler->gpuCyclesCounter));
  105697. +
  105698. + gcmkONERROR(
  105699. + gckOS_ReadRegisterEx(Hardware->os,
  105700. + Hardware->core,
  105701. + 0x00078,
  105702. + &profiler->gpuTotalCyclesCounter));
  105703. +
  105704. + gcmkONERROR(
  105705. + gckOS_ReadRegisterEx(Hardware->os,
  105706. + Hardware->core,
  105707. + 0x0007C,
  105708. + &profiler->gpuIdleCyclesCounter));
  105709. +
  105710. +
  105711. + /* Read clock control register. */
  105712. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  105713. + Hardware->core,
  105714. + 0x00000,
  105715. + &clock));
  105716. +
  105717. + profiler->gpuTotalRead64BytesPerFrame = 0;
  105718. + profiler->gpuTotalWrite64BytesPerFrame = 0;
  105719. + profiler->pe_pixel_count_killed_by_color_pipe = 0;
  105720. + profiler->pe_pixel_count_killed_by_depth_pipe = 0;
  105721. + profiler->pe_pixel_count_drawn_by_color_pipe = 0;
  105722. + profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
  105723. +
  105724. + /* Walk through all avaiable pixel pipes. */
  105725. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  105726. + {
  105727. + /* Select proper pipe. */
  105728. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105729. + Hardware->core,
  105730. + 0x00000,
  105731. + ((((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)))));
  105732. +
  105733. + /* BW */
  105734. + gcmkONERROR(
  105735. + gckOS_ReadRegisterEx(Hardware->os,
  105736. + Hardware->core,
  105737. + 0x00040,
  105738. + &totalRead));
  105739. + gcmkONERROR(
  105740. + gckOS_ReadRegisterEx(Hardware->os,
  105741. + Hardware->core,
  105742. + 0x00044,
  105743. + &totalWrite));
  105744. +
  105745. + profiler->gpuTotalRead64BytesPerFrame += totalRead;
  105746. + profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
  105747. +
  105748. + /* PE */
  105749. + 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));
  105750. + 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));
  105751. + 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));
  105752. + 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));
  105753. +
  105754. + profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
  105755. + profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
  105756. + profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
  105757. + profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
  105758. + }
  105759. +
  105760. + /* Reset clock control register. */
  105761. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  105762. + Hardware->core,
  105763. + 0x00000,
  105764. + clock));
  105765. +
  105766. + if(Reset){
  105767. + /* Reset counters. */
  105768. + gcmkONERROR(
  105769. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
  105770. + gcmkONERROR(
  105771. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
  105772. + gcmkONERROR(
  105773. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
  105774. + gcmkONERROR(
  105775. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
  105776. + 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))) ));
  105777. +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)))
  105778. +));
  105779. + }
  105780. +
  105781. + /* SH */
  105782. + 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))) ));
  105783. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
  105784. + 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))) ));
  105785. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
  105786. + 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))) ));
  105787. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
  105788. + 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))) ));
  105789. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
  105790. + 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))) ));
  105791. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
  105792. + 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))) ));
  105793. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
  105794. + 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))) ));
  105795. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
  105796. + 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))) ));
  105797. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
  105798. + 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))) ));
  105799. +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)))
  105800. +));}
  105801. +
  105802. + /* PA */
  105803. + 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))) ));
  105804. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
  105805. + 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))) ));
  105806. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
  105807. + 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))) ));
  105808. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
  105809. + 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))) ));
  105810. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
  105811. + 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))) ));
  105812. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
  105813. + 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))) ));
  105814. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
  105815. + 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))) ));
  105816. +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)))
  105817. +));}
  105818. +
  105819. + /* SE */
  105820. + 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))) ));
  105821. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
  105822. + 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))) ));
  105823. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
  105824. + 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))) ));
  105825. +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)))
  105826. +));}
  105827. +
  105828. + /* RA */
  105829. + 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))) ));
  105830. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
  105831. + 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))) ));
  105832. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
  105833. + 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))) ));
  105834. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
  105835. + 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))) ));
  105836. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
  105837. + 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))) ));
  105838. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
  105839. + 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))) ));
  105840. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
  105841. + 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))) ));
  105842. +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)))
  105843. +));}
  105844. +
  105845. + /* TX */
  105846. + 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))) ));
  105847. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
  105848. + 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))) ));
  105849. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
  105850. + 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))) ));
  105851. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
  105852. + 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))) ));
  105853. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
  105854. + 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))) ));
  105855. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
  105856. + 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))) ));
  105857. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
  105858. + 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))) ));
  105859. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
  105860. + 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))) ));
  105861. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
  105862. + 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))) ));
  105863. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
  105864. + 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))) ));
  105865. +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)))
  105866. +));}
  105867. +
  105868. + /* MC */
  105869. + 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))) ));
  105870. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
  105871. + 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))) ));
  105872. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
  105873. + 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))) ));
  105874. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
  105875. + 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))) ));
  105876. +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)))
  105877. +));}
  105878. +
  105879. + /* HI */
  105880. + 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))) ));
  105881. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
  105882. + 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))) ));
  105883. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
  105884. + 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))) ));
  105885. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
  105886. + 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))) ));
  105887. +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)))
  105888. +));}
  105889. +
  105890. + /* Success. */
  105891. + gcmkFOOTER_NO();
  105892. + return gcvSTATUS_OK;
  105893. +
  105894. +OnError:
  105895. + /* Return the status. */
  105896. + gcmkFOOTER();
  105897. + return status;
  105898. +}
  105899. +#endif
  105900. +
  105901. +#if VIVANTE_PROFILER_CONTEXT
  105902. +#define gcmkUPDATE_PROFILE_DATA(data) \
  105903. + profilerHistroy->data += profiler->data
  105904. +
  105905. +gceSTATUS
  105906. +gckHARDWARE_QueryContextProfile(
  105907. + IN gckHARDWARE Hardware,
  105908. + IN gctBOOL Reset,
  105909. + IN gckCONTEXT Context,
  105910. + OUT gcsPROFILER_COUNTERS * Counters
  105911. + )
  105912. +{
  105913. + gceSTATUS status;
  105914. + gckCOMMAND command = Hardware->kernel->command;
  105915. + gcsPROFILER_COUNTERS * profiler = Counters;
  105916. +
  105917. + gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
  105918. +
  105919. + /* Verify the arguments. */
  105920. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105921. +
  105922. + /* Acquire the context sequnence mutex. */
  105923. + gcmkONERROR(gckOS_AcquireMutex(
  105924. + command->os, command->mutexContextSeq, gcvINFINITE
  105925. + ));
  105926. +
  105927. + /* Read the counters. */
  105928. + gcmkVERIFY_OK(gckOS_MemCopy(
  105929. + profiler, &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
  105930. + ));
  105931. +
  105932. + if (Reset)
  105933. + {
  105934. + /* Reset counters. */
  105935. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  105936. + &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
  105937. + ));
  105938. + }
  105939. +
  105940. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  105941. + command->os, command->mutexContextSeq
  105942. + ));
  105943. +
  105944. + /* Success. */
  105945. + gcmkFOOTER_NO();
  105946. + return gcvSTATUS_OK;
  105947. +
  105948. +OnError:
  105949. + /* Return the status. */
  105950. + gcmkFOOTER();
  105951. + return status;
  105952. +}
  105953. +
  105954. +
  105955. +gceSTATUS
  105956. +gckHARDWARE_UpdateContextProfile(
  105957. + IN gckHARDWARE Hardware,
  105958. + IN gckCONTEXT Context
  105959. + )
  105960. +{
  105961. + gceSTATUS status;
  105962. + gcsPROFILER_COUNTERS * profiler = &Context->latestProfiler;
  105963. + gcsPROFILER_COUNTERS * profilerHistroy = &Context->histroyProfiler;
  105964. + gctUINT i, clock;
  105965. + gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
  105966. + gctUINT32 totalRead, totalWrite;
  105967. + gceCHIPMODEL chipModel;
  105968. + gctUINT32 chipRevision;
  105969. + gctUINT32 temp;
  105970. + gctBOOL needResetShader = gcvFALSE;
  105971. +
  105972. + gcmkHEADER_ARG("Hardware=0x%x Context=0x%x", Hardware, Context);
  105973. +
  105974. + /* Verify the arguments. */
  105975. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  105976. + gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
  105977. +
  105978. + chipModel = Hardware->identity.chipModel;
  105979. + chipRevision = Hardware->identity.chipRevision;
  105980. + if (chipModel == gcv2000 || (chipModel == gcv2100 && chipRevision == 0x5118))
  105981. + {
  105982. + needResetShader = gcvTRUE;
  105983. + }
  105984. +
  105985. + /* Read the counters. */
  105986. + gcmkONERROR(
  105987. + gckOS_ReadRegisterEx(Hardware->os,
  105988. + Hardware->core,
  105989. + 0x00438,
  105990. + &profiler->gpuCyclesCounter));
  105991. + gcmkUPDATE_PROFILE_DATA(gpuCyclesCounter);
  105992. +
  105993. + gcmkONERROR(
  105994. + gckOS_ReadRegisterEx(Hardware->os,
  105995. + Hardware->core,
  105996. + 0x00078,
  105997. + &profiler->gpuTotalCyclesCounter));
  105998. + gcmkUPDATE_PROFILE_DATA(gpuTotalCyclesCounter);
  105999. +
  106000. + gcmkONERROR(
  106001. + gckOS_ReadRegisterEx(Hardware->os,
  106002. + Hardware->core,
  106003. + 0x0007C,
  106004. + &profiler->gpuIdleCyclesCounter));
  106005. + gcmkUPDATE_PROFILE_DATA(gpuIdleCyclesCounter);
  106006. +
  106007. + /* Read clock control register. */
  106008. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  106009. + Hardware->core,
  106010. + 0x00000,
  106011. + &clock));
  106012. +
  106013. + profiler->gpuTotalRead64BytesPerFrame = 0;
  106014. + profiler->gpuTotalWrite64BytesPerFrame = 0;
  106015. + profiler->pe_pixel_count_killed_by_color_pipe = 0;
  106016. + profiler->pe_pixel_count_killed_by_depth_pipe = 0;
  106017. + profiler->pe_pixel_count_drawn_by_color_pipe = 0;
  106018. + profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
  106019. +
  106020. + /* Walk through all avaiable pixel pipes. */
  106021. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  106022. + {
  106023. + /* Select proper pipe. */
  106024. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  106025. + Hardware->core,
  106026. + 0x00000,
  106027. + ((((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)))));
  106028. +
  106029. + /* BW */
  106030. + gcmkONERROR(
  106031. + gckOS_ReadRegisterEx(Hardware->os,
  106032. + Hardware->core,
  106033. + 0x00040,
  106034. + &totalRead));
  106035. + gcmkONERROR(
  106036. + gckOS_ReadRegisterEx(Hardware->os,
  106037. + Hardware->core,
  106038. + 0x00044,
  106039. + &totalWrite));
  106040. +
  106041. + profiler->gpuTotalRead64BytesPerFrame += totalRead;
  106042. + profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
  106043. + gcmkUPDATE_PROFILE_DATA(gpuTotalRead64BytesPerFrame);
  106044. + gcmkUPDATE_PROFILE_DATA(gpuTotalWrite64BytesPerFrame);
  106045. +
  106046. + /* PE */
  106047. + 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));
  106048. + 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));
  106049. + 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));
  106050. + 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));
  106051. +
  106052. + profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
  106053. + profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
  106054. + profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
  106055. + profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
  106056. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_color_pipe);
  106057. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_depth_pipe);
  106058. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_color_pipe);
  106059. + gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_depth_pipe);
  106060. + }
  106061. +
  106062. + /* Reset clock control register. */
  106063. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  106064. + Hardware->core,
  106065. + 0x00000,
  106066. + clock));
  106067. +
  106068. +
  106069. +
  106070. +
  106071. + /* Reset counters. */
  106072. + gcmkONERROR(
  106073. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
  106074. + gcmkONERROR(
  106075. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
  106076. + gcmkONERROR(
  106077. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
  106078. + gcmkONERROR(
  106079. + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
  106080. + 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))) ));
  106081. +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)))
  106082. +));
  106083. +
  106084. + /* SH */
  106085. + 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))) ));
  106086. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
  106087. + if (needResetShader)
  106088. + {
  106089. + temp = profiler->ps_inst_counter;
  106090. + profiler->ps_inst_counter -= Context->prevPSInstCount;
  106091. + Context->prevPSInstCount = temp;
  106092. + }
  106093. + gcmkUPDATE_PROFILE_DATA(ps_inst_counter);
  106094. +
  106095. + 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))) ));
  106096. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
  106097. + if (needResetShader)
  106098. + {
  106099. + temp = profiler->rendered_pixel_counter;
  106100. + profiler->rendered_pixel_counter -= Context->prevPSPixelCount;
  106101. + Context->prevPSPixelCount = temp;
  106102. + }
  106103. + gcmkUPDATE_PROFILE_DATA(rendered_pixel_counter);
  106104. +
  106105. + 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))) ));
  106106. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
  106107. + if (needResetShader)
  106108. + {
  106109. + temp = profiler->vs_inst_counter;
  106110. + profiler->vs_inst_counter -= Context->prevVSInstCount;
  106111. + Context->prevVSInstCount = temp;
  106112. + }
  106113. + gcmkUPDATE_PROFILE_DATA(vs_inst_counter);
  106114. +
  106115. + 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))) ));
  106116. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
  106117. + if (needResetShader)
  106118. + {
  106119. + temp = profiler->rendered_vertice_counter;
  106120. + profiler->rendered_vertice_counter -= Context->prevVSVertexCount;
  106121. + Context->prevVSVertexCount = temp;
  106122. + }
  106123. + gcmkUPDATE_PROFILE_DATA(rendered_vertice_counter);
  106124. +
  106125. + 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))) ));
  106126. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
  106127. + if (needResetShader)
  106128. + {
  106129. + temp = profiler->vtx_branch_inst_counter;
  106130. + profiler->vtx_branch_inst_counter -= Context->prevVSBranchInstCount;
  106131. + Context->prevVSBranchInstCount = temp;
  106132. + }
  106133. + gcmkUPDATE_PROFILE_DATA(vtx_branch_inst_counter);
  106134. +
  106135. + 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))) ));
  106136. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
  106137. + if (needResetShader)
  106138. + {
  106139. + temp = profiler->vtx_texld_inst_counter;
  106140. + profiler->vtx_texld_inst_counter -= Context->prevVSTexInstCount;
  106141. + Context->prevVSTexInstCount = temp;
  106142. + }
  106143. + gcmkUPDATE_PROFILE_DATA(vtx_texld_inst_counter);
  106144. +
  106145. + 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))) ));
  106146. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
  106147. + if (needResetShader)
  106148. + {
  106149. + temp = profiler->pxl_branch_inst_counter;
  106150. + profiler->pxl_branch_inst_counter -= Context->prevPSBranchInstCount;
  106151. + Context->prevPSBranchInstCount = temp;
  106152. + }
  106153. + gcmkUPDATE_PROFILE_DATA(pxl_branch_inst_counter);
  106154. +
  106155. + 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))) ));
  106156. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
  106157. + if (needResetShader)
  106158. + {
  106159. + temp = profiler->pxl_texld_inst_counter;
  106160. + profiler->pxl_texld_inst_counter -= Context->prevPSTexInstCount;
  106161. + Context->prevPSTexInstCount = temp;
  106162. + }
  106163. + gcmkUPDATE_PROFILE_DATA(pxl_texld_inst_counter);
  106164. +
  106165. + 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))) ));
  106166. +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)))
  106167. +));
  106168. +
  106169. + /* PA */
  106170. + 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))) ));
  106171. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
  106172. + gcmkUPDATE_PROFILE_DATA(pa_input_vtx_counter);
  106173. + 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))) ));
  106174. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
  106175. + gcmkUPDATE_PROFILE_DATA(pa_input_prim_counter);
  106176. + 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))) ));
  106177. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
  106178. + gcmkUPDATE_PROFILE_DATA(pa_output_prim_counter);
  106179. + 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))) ));
  106180. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
  106181. + gcmkUPDATE_PROFILE_DATA(pa_depth_clipped_counter);
  106182. + 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))) ));
  106183. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
  106184. + gcmkUPDATE_PROFILE_DATA(pa_trivial_rejected_counter);
  106185. + 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))) ));
  106186. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
  106187. + gcmkUPDATE_PROFILE_DATA(pa_culled_counter);
  106188. + 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))) ));
  106189. +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)))
  106190. +));
  106191. +
  106192. + /* SE */
  106193. + 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))) ));
  106194. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
  106195. + gcmkUPDATE_PROFILE_DATA(se_culled_triangle_count);
  106196. + 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))) ));
  106197. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
  106198. + gcmkUPDATE_PROFILE_DATA(se_culled_lines_count);
  106199. + 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))) ));
  106200. +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)))
  106201. +));
  106202. +
  106203. + /* RA */
  106204. + 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))) ));
  106205. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
  106206. + gcmkUPDATE_PROFILE_DATA(ra_valid_pixel_count);
  106207. + 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))) ));
  106208. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
  106209. + gcmkUPDATE_PROFILE_DATA(ra_total_quad_count);
  106210. + 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))) ));
  106211. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
  106212. + gcmkUPDATE_PROFILE_DATA(ra_valid_quad_count_after_early_z);
  106213. + 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))) ));
  106214. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
  106215. + gcmkUPDATE_PROFILE_DATA(ra_total_primitive_count);
  106216. + 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))) ));
  106217. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
  106218. + gcmkUPDATE_PROFILE_DATA(ra_pipe_cache_miss_counter);
  106219. + 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))) ));
  106220. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
  106221. + gcmkUPDATE_PROFILE_DATA(ra_prefetch_cache_miss_counter);
  106222. + 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))) ));
  106223. +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)))
  106224. +));
  106225. +
  106226. + /* TX */
  106227. + 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))) ));
  106228. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
  106229. + gcmkUPDATE_PROFILE_DATA(tx_total_bilinear_requests);
  106230. + 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))) ));
  106231. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
  106232. + gcmkUPDATE_PROFILE_DATA(tx_total_trilinear_requests);
  106233. + 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))) ));
  106234. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
  106235. + gcmkUPDATE_PROFILE_DATA(tx_total_discarded_texture_requests);
  106236. + 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))) ));
  106237. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
  106238. + gcmkUPDATE_PROFILE_DATA(tx_total_texture_requests);
  106239. + 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))) ));
  106240. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
  106241. + gcmkUPDATE_PROFILE_DATA(tx_mem_read_count);
  106242. + 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))) ));
  106243. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
  106244. + gcmkUPDATE_PROFILE_DATA(tx_mem_read_in_8B_count);
  106245. + 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))) ));
  106246. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
  106247. + gcmkUPDATE_PROFILE_DATA(tx_cache_miss_count);
  106248. + 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))) ));
  106249. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
  106250. + gcmkUPDATE_PROFILE_DATA(tx_cache_hit_texel_count);
  106251. + 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))) ));
  106252. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
  106253. + gcmkUPDATE_PROFILE_DATA(tx_cache_miss_texel_count);
  106254. + 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))) ));
  106255. +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)))
  106256. +));
  106257. +
  106258. + /* MC */
  106259. + 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))) ));
  106260. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
  106261. + gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_pipeline);
  106262. + 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))) ));
  106263. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
  106264. + gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_IP);
  106265. + 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))) ));
  106266. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
  106267. + gcmkUPDATE_PROFILE_DATA(mc_total_write_req_8B_from_pipeline);
  106268. + 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))) ));
  106269. +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)))
  106270. +));
  106271. +
  106272. + /* HI */
  106273. + 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))) ));
  106274. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
  106275. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_read_request_stalled);
  106276. + 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))) ));
  106277. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
  106278. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_request_stalled);
  106279. + 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))) ));
  106280. +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
  106281. + gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_data_stalled);
  106282. + 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))) ));
  106283. +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)))
  106284. +));
  106285. +
  106286. + /* Success. */
  106287. + gcmkFOOTER_NO();
  106288. + return gcvSTATUS_OK;
  106289. +
  106290. +OnError:
  106291. + /* Return the status. */
  106292. + gcmkFOOTER();
  106293. + return status;
  106294. +}
  106295. +#endif
  106296. +
  106297. +static gceSTATUS
  106298. +_ResetGPU(
  106299. + IN gckHARDWARE Hardware,
  106300. + IN gckOS Os,
  106301. + IN gceCORE Core
  106302. + )
  106303. +{
  106304. + gctUINT32 control, idle;
  106305. + gceSTATUS status;
  106306. +
  106307. + for (;;)
  106308. + {
  106309. + /* Disable clock gating. */
  106310. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106311. + Core,
  106312. + Hardware->powerBaseAddress +
  106313. + 0x00104,
  106314. + 0x00000000));
  106315. +
  106316. + 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)));
  106317. +
  106318. + /* Disable pulse-eater. */
  106319. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106320. + Core,
  106321. + 0x0010C,
  106322. + control));
  106323. +
  106324. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106325. + Core,
  106326. + 0x0010C,
  106327. + ((((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)))));
  106328. +
  106329. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106330. + Core,
  106331. + 0x0010C,
  106332. + control));
  106333. +
  106334. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106335. + Core,
  106336. + 0x00000,
  106337. + ((((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)))));
  106338. +
  106339. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106340. + Core,
  106341. + 0x00000,
  106342. + 0x00000900));
  106343. +
  106344. + /* Wait for clock being stable. */
  106345. + gcmkONERROR(gckOS_Delay(Os, 1));
  106346. +
  106347. + /* Isolate the GPU. */
  106348. + 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)));
  106349. +
  106350. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106351. + Core,
  106352. + 0x00000,
  106353. + control));
  106354. +
  106355. + /* Set soft reset. */
  106356. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106357. + Core,
  106358. + 0x00000,
  106359. + ((((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)))));
  106360. +
  106361. + /* Wait for reset. */
  106362. + gcmkONERROR(gckOS_Delay(Os, 1));
  106363. +
  106364. + /* Reset soft reset bit. */
  106365. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106366. + Core,
  106367. + 0x00000,
  106368. + ((((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)))));
  106369. +
  106370. + /* Reset GPU isolation. */
  106371. + 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)));
  106372. +
  106373. + gcmkONERROR(gckOS_WriteRegisterEx(Os,
  106374. + Core,
  106375. + 0x00000,
  106376. + control));
  106377. +
  106378. + /* Read idle register. */
  106379. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  106380. + Core,
  106381. + 0x00004,
  106382. + &idle));
  106383. +
  106384. + 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)
  106385. + {
  106386. + continue;
  106387. + }
  106388. +
  106389. + /* Read reset register. */
  106390. + gcmkONERROR(gckOS_ReadRegisterEx(Os,
  106391. + Core,
  106392. + 0x00000,
  106393. + &control));
  106394. +
  106395. + 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)
  106396. + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
  106397. + )
  106398. + {
  106399. + continue;
  106400. + }
  106401. +
  106402. + /* GPU is idle. */
  106403. + break;
  106404. + }
  106405. +
  106406. + /* Success. */
  106407. + return gcvSTATUS_OK;
  106408. +
  106409. +OnError:
  106410. +
  106411. + /* Return the error. */
  106412. + return status;
  106413. +}
  106414. +
  106415. +gceSTATUS
  106416. +gckHARDWARE_Reset(
  106417. + IN gckHARDWARE Hardware
  106418. + )
  106419. +{
  106420. + gceSTATUS status;
  106421. + gckCOMMAND command;
  106422. + gctBOOL acquired = gcvFALSE;
  106423. + gctBOOL mutexAcquired = gcvFALSE;
  106424. + gctUINT32 process, thread;
  106425. +
  106426. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  106427. +
  106428. + /* Verify the arguments. */
  106429. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  106430. + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
  106431. + command = Hardware->kernel->command;
  106432. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  106433. +
  106434. + if (Hardware->identity.chipRevision < 0x4600)
  106435. + {
  106436. + /* Not supported - we need the isolation bit. */
  106437. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  106438. + }
  106439. +
  106440. + status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
  106441. + if (status == gcvSTATUS_TIMEOUT)
  106442. + {
  106443. + gcmkONERROR(gckOS_GetProcessID(&process));
  106444. + gcmkONERROR(gckOS_GetThreadID(&thread));
  106445. +
  106446. + if ((Hardware->powerProcess == process)
  106447. + && (Hardware->powerThread == thread))
  106448. + {
  106449. + /* No way to recovery from a error in power management. */
  106450. + gcmkFOOTER_NO();
  106451. + return gcvSTATUS_OK;
  106452. + }
  106453. + }
  106454. + else
  106455. + {
  106456. + mutexAcquired = gcvTRUE;
  106457. + }
  106458. +
  106459. + if (Hardware->chipPowerState == gcvPOWER_ON)
  106460. + {
  106461. + /* Acquire the power management semaphore. */
  106462. + gcmkONERROR(
  106463. + gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore));
  106464. + acquired = gcvTRUE;
  106465. + }
  106466. +
  106467. + if ((Hardware->chipPowerState == gcvPOWER_ON)
  106468. + || (Hardware->chipPowerState == gcvPOWER_IDLE)
  106469. + )
  106470. + {
  106471. + /* Stop the command processor. */
  106472. + gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
  106473. + }
  106474. +
  106475. + /* Stop isr, we will start it again when power on GPU. */
  106476. + if (Hardware->stopIsr)
  106477. + {
  106478. + gcmkONERROR(Hardware->stopIsr(Hardware->isrContext, Hardware->core));
  106479. + }
  106480. +
  106481. + /* Hardware reset. */
  106482. + status = gckOS_ResetGPU(Hardware->os, Hardware->core);
  106483. +
  106484. + if (gcmIS_ERROR(status))
  106485. + {
  106486. + /* Soft reset. */
  106487. + gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core));
  106488. + }
  106489. +
  106490. + /* Force an OFF to ON power switch. */
  106491. + Hardware->chipPowerState = gcvPOWER_OFF;
  106492. +
  106493. + gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
  106494. + mutexAcquired = gcvFALSE;
  106495. +
  106496. + /* Success. */
  106497. + gcmkFOOTER_NO();
  106498. + return gcvSTATUS_OK;
  106499. +
  106500. +OnError:
  106501. + if (acquired)
  106502. + {
  106503. + /* Release the power management semaphore. */
  106504. + gcmkVERIFY_OK(
  106505. + gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
  106506. + }
  106507. +
  106508. + if (mutexAcquired)
  106509. + {
  106510. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  106511. + }
  106512. +
  106513. + /* Return the error. */
  106514. + gcmkFOOTER();
  106515. + return status;
  106516. +}
  106517. +
  106518. +gceSTATUS
  106519. +gckHARDWARE_GetBaseAddress(
  106520. + IN gckHARDWARE Hardware,
  106521. + OUT gctUINT32_PTR BaseAddress
  106522. + )
  106523. +{
  106524. + gceSTATUS status;
  106525. +
  106526. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  106527. +
  106528. + /* Verify the arguments. */
  106529. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  106530. + gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
  106531. +
  106532. + /* Test if we have a new Memory Controller. */
  106533. + 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))))))))
  106534. + {
  106535. + /* No base address required. */
  106536. + *BaseAddress = 0;
  106537. + }
  106538. + else
  106539. + {
  106540. + /* Get the base address from the OS. */
  106541. + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, BaseAddress));
  106542. + }
  106543. +
  106544. + /* Success. */
  106545. + gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
  106546. + return gcvSTATUS_OK;
  106547. +
  106548. +OnError:
  106549. + /* Return the status. */
  106550. + gcmkFOOTER();
  106551. + return status;
  106552. +}
  106553. +
  106554. +gceSTATUS
  106555. +gckHARDWARE_NeedBaseAddress(
  106556. + IN gckHARDWARE Hardware,
  106557. + IN gctUINT32 State,
  106558. + OUT gctBOOL_PTR NeedBase
  106559. + )
  106560. +{
  106561. + gctBOOL need = gcvFALSE;
  106562. +
  106563. + gcmkHEADER_ARG("Hardware=0x%x State=0x%08x", Hardware, State);
  106564. +
  106565. + /* Verify the arguments. */
  106566. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  106567. + gcmkVERIFY_ARGUMENT(NeedBase != gcvNULL);
  106568. +
  106569. + /* Make sure this is a load state. */
  106570. + 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))))))))
  106571. + {
  106572. +#ifndef VIVANTE_NO_3D
  106573. + /* Get the state address. */
  106574. + switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ))
  106575. + {
  106576. + case 0x0596:
  106577. + case 0x0597:
  106578. + case 0x0599:
  106579. + case 0x059A:
  106580. + case 0x05A9:
  106581. + /* These states need a TRUE physical address. */
  106582. + need = gcvTRUE;
  106583. + break;
  106584. + }
  106585. +#else
  106586. + /* 2D addresses don't need a base address. */
  106587. +#endif
  106588. + }
  106589. +
  106590. + /* Return the flag. */
  106591. + *NeedBase = need;
  106592. +
  106593. + /* Success. */
  106594. + gcmkFOOTER_ARG("*NeedBase=%d", *NeedBase);
  106595. + return gcvSTATUS_OK;
  106596. +}
  106597. +
  106598. +gceSTATUS
  106599. +gckHARDWARE_SetIsrManager(
  106600. + IN gckHARDWARE Hardware,
  106601. + IN gctISRMANAGERFUNC StartIsr,
  106602. + IN gctISRMANAGERFUNC StopIsr,
  106603. + IN gctPOINTER Context
  106604. + )
  106605. +{
  106606. + gceSTATUS status = gcvSTATUS_OK;
  106607. +
  106608. + gcmkHEADER_ARG("Hardware=0x%x, StartIsr=0x%x, StopIsr=0x%x, Context=0x%x",
  106609. + Hardware, StartIsr, StopIsr, Context);
  106610. +
  106611. + /* Verify the arguments. */
  106612. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  106613. +
  106614. + if (StartIsr == gcvNULL ||
  106615. + StopIsr == gcvNULL ||
  106616. + Context == gcvNULL)
  106617. + {
  106618. + status = gcvSTATUS_INVALID_ARGUMENT;
  106619. +
  106620. + gcmkFOOTER();
  106621. + return status;
  106622. + }
  106623. +
  106624. + Hardware->startIsr = StartIsr;
  106625. + Hardware->stopIsr = StopIsr;
  106626. + Hardware->isrContext = Context;
  106627. +
  106628. + /* Success. */
  106629. + gcmkFOOTER();
  106630. +
  106631. + return status;
  106632. +}
  106633. +
  106634. +/*******************************************************************************
  106635. +**
  106636. +** gckHARDWARE_Compose
  106637. +**
  106638. +** Start a composition.
  106639. +**
  106640. +** INPUT:
  106641. +**
  106642. +** gckHARDWARE Hardware
  106643. +** Pointer to the gckHARDWARE object.
  106644. +**
  106645. +** OUTPUT:
  106646. +**
  106647. +** Nothing.
  106648. +*/
  106649. +gceSTATUS
  106650. +gckHARDWARE_Compose(
  106651. + IN gckHARDWARE Hardware,
  106652. + IN gctUINT32 ProcessID,
  106653. + IN gctPHYS_ADDR Physical,
  106654. + IN gctPOINTER Logical,
  106655. + IN gctSIZE_T Offset,
  106656. + IN gctSIZE_T Size,
  106657. + IN gctUINT8 EventID
  106658. + )
  106659. +{
  106660. +#ifndef VIVANTE_NO_3D
  106661. + gceSTATUS status;
  106662. + gctUINT32_PTR triggerState;
  106663. +
  106664. + gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x Logical=0x%x"
  106665. + " Offset=%d Size=%d EventID=%d",
  106666. + Hardware, Physical, Logical, Offset, Size, EventID);
  106667. +
  106668. + /* Verify the arguments. */
  106669. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  106670. + gcmkVERIFY_ARGUMENT(((Size + 8) & 63) == 0);
  106671. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  106672. +
  106673. + /* Program the trigger state. */
  106674. + triggerState = (gctUINT32_PTR) ((gctUINT8_PTR) Logical + Offset + Size);
  106675. + triggerState[0] = 0x0C03;
  106676. + triggerState[1]
  106677. + = ((((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)))
  106678. + | ((((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)))
  106679. + | ((((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)))
  106680. + | ((((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)))
  106681. + | ((((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)))
  106682. + | ((((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)))
  106683. + ;
  106684. +
  106685. +#if gcdNONPAGED_MEMORY_CACHEABLE
  106686. + /* Flush the cache for the wait/link. */
  106687. + gcmkONERROR(gckOS_CacheClean(
  106688. + Hardware->os, ProcessID, gcvNULL,
  106689. + Physical, Logical, Offset + Size
  106690. + ));
  106691. +#endif
  106692. +
  106693. + /* Start composition. */
  106694. + gcmkONERROR(gckOS_WriteRegisterEx(
  106695. + Hardware->os, Hardware->core, 0x00554,
  106696. + ((((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)))
  106697. + ));
  106698. +
  106699. + /* Success. */
  106700. + gcmkFOOTER_NO();
  106701. + return gcvSTATUS_OK;
  106702. +
  106703. +OnError:
  106704. + /* Return the status. */
  106705. + gcmkFOOTER();
  106706. + return status;
  106707. +#else
  106708. + /* Return the status. */
  106709. + return gcvSTATUS_NOT_SUPPORTED;
  106710. +#endif
  106711. +}
  106712. +
  106713. +/*******************************************************************************
  106714. +**
  106715. +** gckHARDWARE_IsFeatureAvailable
  106716. +**
  106717. +** Verifies whether the specified feature is available in hardware.
  106718. +**
  106719. +** INPUT:
  106720. +**
  106721. +** gckHARDWARE Hardware
  106722. +** Pointer to an gckHARDWARE object.
  106723. +**
  106724. +** gceFEATURE Feature
  106725. +** Feature to be verified.
  106726. +*/
  106727. +gceSTATUS
  106728. +gckHARDWARE_IsFeatureAvailable(
  106729. + IN gckHARDWARE Hardware,
  106730. + IN gceFEATURE Feature
  106731. + )
  106732. +{
  106733. + gctBOOL available;
  106734. +
  106735. + gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature);
  106736. +
  106737. + /* Verify the arguments. */
  106738. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  106739. +
  106740. + /* Only features needed by common kernel logic added here. */
  106741. + switch (Feature)
  106742. + {
  106743. + case gcvFEATURE_END_EVENT:
  106744. + /*available = gcmVERIFYFIELDVALUE(Hardware->identity.chipMinorFeatures2,
  106745. + GC_MINOR_FEATURES2, END_EVENT, AVAILABLE
  106746. + );*/
  106747. + available = gcvFALSE;
  106748. + break;
  106749. + case gcvFEATURE_MC20:
  106750. + 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)))))));
  106751. + break;
  106752. + case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING:
  106753. + /* This feature doesn't apply for 2D cores. */
  106754. + 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)))))))
  106755. + && ((((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)))))));
  106756. + break;
  106757. +
  106758. + case gcvFEATURE_PIPE_2D:
  106759. + 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)))))));
  106760. + break;
  106761. +
  106762. + case gcvFEATURE_PIPE_3D:
  106763. +#ifndef VIVANTE_NO_3D
  106764. + 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)))))));
  106765. +#else
  106766. + available = gcvFALSE;
  106767. +#endif
  106768. + break;
  106769. +
  106770. + case gcvFEATURE_HALTI2:
  106771. + 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)))))));
  106772. + break;
  106773. +
  106774. + default:
  106775. + gcmkFATAL("Invalid feature has been requested.");
  106776. + available = gcvFALSE;
  106777. + }
  106778. +
  106779. + /* Return result. */
  106780. + gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK);
  106781. + return available ? gcvSTATUS_TRUE : gcvSTATUS_OK;
  106782. +}
  106783. +
  106784. +/*******************************************************************************
  106785. +**
  106786. +** gckHARDWARE_DumpMMUException
  106787. +**
  106788. +** Dump the MMU debug info on an MMU exception.
  106789. +**
  106790. +** INPUT:
  106791. +**
  106792. +** gckHARDWARE Harwdare
  106793. +** Pointer to an gckHARDWARE object.
  106794. +**
  106795. +** OUTPUT:
  106796. +**
  106797. +** Nothing.
  106798. +*/
  106799. +gceSTATUS
  106800. +gckHARDWARE_DumpMMUException(
  106801. + IN gckHARDWARE Hardware
  106802. + )
  106803. +{
  106804. +#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
  106805. + gctUINT32 mmu, mmuStatus, address, i;
  106806. +#if gcdDEBUG
  106807. + gctUINT32 mtlb, stlb, offset;
  106808. +#endif
  106809. +
  106810. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  106811. +
  106812. + /* Verify the arguments. */
  106813. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  106814. +
  106815. + gcmkPRINT("GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
  106816. + Hardware->core,
  106817. + Hardware->identity.chipModel,
  106818. + Hardware->identity.chipRevision);
  106819. +
  106820. + gcmkPRINT("**************************\n");
  106821. + gcmkPRINT("*** MMU ERROR DUMP ***\n");
  106822. + gcmkPRINT("**************************\n");
  106823. +
  106824. + gcmkVERIFY_OK(
  106825. + gckOS_ReadRegisterEx(Hardware->os,
  106826. + Hardware->core,
  106827. + 0x00188,
  106828. + &mmuStatus));
  106829. +
  106830. + gcmkPRINT(" MMU status = 0x%08X\n", mmuStatus);
  106831. +
  106832. + for (i = 0; i < 4; i += 1)
  106833. + {
  106834. + mmu = mmuStatus & 0xF;
  106835. + mmuStatus >>= 4;
  106836. +
  106837. + if (mmu == 0)
  106838. + {
  106839. + continue;
  106840. + }
  106841. +
  106842. + switch (mmu)
  106843. + {
  106844. + case 1:
  106845. + gcmkPRINT(" MMU%d: slave not present\n", i);
  106846. + break;
  106847. +
  106848. + case 2:
  106849. + gcmkPRINT(" MMU%d: page not present\n", i);
  106850. + break;
  106851. +
  106852. + case 3:
  106853. + gcmkPRINT(" MMU%d: write violation\n", i);
  106854. + break;
  106855. +
  106856. + default:
  106857. + gcmkPRINT(" MMU%d: unknown state\n", i);
  106858. + }
  106859. +
  106860. + gcmkVERIFY_OK(
  106861. + gckOS_ReadRegisterEx(Hardware->os,
  106862. + Hardware->core,
  106863. + 0x00190 + i * 4,
  106864. + &address));
  106865. +
  106866. + mtlb = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
  106867. + stlb = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
  106868. + offset = address & gcdMMU_OFFSET_4K_MASK;
  106869. +
  106870. + gcmkPRINT(" MMU%d: exception address = 0x%08X\n", i, address);
  106871. +
  106872. + gcmkPRINT(" MTLB entry = %d\n", mtlb);
  106873. +
  106874. + gcmkPRINT(" STLB entry = %d\n", stlb);
  106875. +
  106876. + gcmkPRINT(" Offset = 0x%08X (%d)\n", offset, offset);
  106877. +
  106878. + gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
  106879. +
  106880. + }
  106881. +
  106882. + gcmkFOOTER_NO();
  106883. +#else
  106884. + /* If clock could be off automatically, we can't read mmu debug
  106885. + ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
  106886. + ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
  106887. + gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
  106888. +#endif
  106889. +
  106890. + return gcvSTATUS_OK;
  106891. +}
  106892. +
  106893. +/*******************************************************************************
  106894. +**
  106895. +** gckHARDWARE_DumpGPUState
  106896. +**
  106897. +** Dump the GPU debug registers.
  106898. +**
  106899. +** INPUT:
  106900. +**
  106901. +** gckHARDWARE Harwdare
  106902. +** Pointer to an gckHARDWARE object.
  106903. +**
  106904. +** OUTPUT:
  106905. +**
  106906. +** Nothing.
  106907. +*/
  106908. +gceSTATUS
  106909. +gckHARDWARE_DumpGPUState(
  106910. + IN gckHARDWARE Hardware
  106911. + )
  106912. +{
  106913. + static gctCONST_STRING _cmdState[] =
  106914. + {
  106915. + "PAR_IDLE_ST", "PAR_DEC_ST", "PAR_ADR0_ST", "PAR_LOAD0_ST",
  106916. + "PAR_ADR1_ST", "PAR_LOAD1_ST", "PAR_3DADR_ST", "PAR_3DCMD_ST",
  106917. + "PAR_3DCNTL_ST", "PAR_3DIDXCNTL_ST", "PAR_INITREQDMA_ST",
  106918. + "PAR_DRAWIDX_ST", "PAR_DRAW_ST", "PAR_2DRECT0_ST", "PAR_2DRECT1_ST",
  106919. + "PAR_2DDATA0_ST", "PAR_2DDATA1_ST", "PAR_WAITFIFO_ST", "PAR_WAIT_ST",
  106920. + "PAR_LINK_ST", "PAR_END_ST", "PAR_STALL_ST"
  106921. + };
  106922. +
  106923. + static gctCONST_STRING _cmdDmaState[] =
  106924. + {
  106925. + "CMD_IDLE_ST", "CMD_START_ST", "CMD_REQ_ST", "CMD_END_ST"
  106926. + };
  106927. +
  106928. + static gctCONST_STRING _cmdFetState[] =
  106929. + {
  106930. + "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST"
  106931. + };
  106932. +
  106933. + static gctCONST_STRING _reqDmaState[] =
  106934. + {
  106935. + "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST"
  106936. + };
  106937. +
  106938. + static gctCONST_STRING _calState[] =
  106939. + {
  106940. + "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST"
  106941. + };
  106942. +
  106943. + static gctCONST_STRING _veReqState[] =
  106944. + {
  106945. + "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST"
  106946. + };
  106947. +
  106948. + static gcsiDEBUG_REGISTERS _dbgRegs[] =
  106949. + {
  106950. + { "RA", 0x474, 16, 0x448, 16, 0x12344321 },
  106951. + { "TX", 0x474, 24, 0x44C, 16, 0x12211221 },
  106952. + { "FE", 0x470, 0, 0x450, 16, 0xBABEF00D },
  106953. + { "PE", 0x470, 16, 0x454, 16, 0xBABEF00D },
  106954. + { "DE", 0x470, 8, 0x458, 16, 0xBABEF00D },
  106955. + { "SH", 0x470, 24, 0x45C, 16, 0xDEADBEEF },
  106956. + { "PA", 0x474, 0, 0x460, 16, 0x0000AAAA },
  106957. + { "SE", 0x474, 8, 0x464, 16, 0x5E5E5E5E },
  106958. + { "MC", 0x478, 0, 0x468, 16, 0x12345678 },
  106959. + { "HI", 0x478, 8, 0x46C, 16, 0xAAAAAAAA }
  106960. + };
  106961. +
  106962. + static gctUINT32 _otherRegs[] =
  106963. + {
  106964. + 0x040, 0x044, 0x04C, 0x050, 0x054, 0x058, 0x05C, 0x060,
  106965. + 0x43c, 0x440, 0x444, 0x414,
  106966. + };
  106967. +
  106968. + gceSTATUS status;
  106969. + gckKERNEL kernel;
  106970. + gctUINT32 idle, axi;
  106971. + gctUINT32 dmaAddress1, dmaAddress2;
  106972. + gctUINT32 dmaState1, dmaState2;
  106973. + gctUINT32 dmaLow, dmaHigh;
  106974. + gctUINT32 cmdState, cmdDmaState, cmdFetState;
  106975. + gctUINT32 dmaReqState, calState, veReqState;
  106976. + gctUINT i;
  106977. + gctUINT pipe, pixelPipes;
  106978. + gctUINT32 control, oldControl;
  106979. + gckOS os = Hardware->os;
  106980. + gceCORE core = Hardware->core;
  106981. +
  106982. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  106983. +
  106984. + kernel = Hardware->kernel;
  106985. +
  106986. + gcmkPRINT_N(12, "GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
  106987. + core,
  106988. + Hardware->identity.chipModel,
  106989. + Hardware->identity.chipRevision);
  106990. +
  106991. + pixelPipes = Hardware->identity.pixelPipes
  106992. + ? Hardware->identity.pixelPipes
  106993. + : 1;
  106994. +
  106995. + /* Reset register values. */
  106996. + idle = axi =
  106997. + dmaState1 = dmaState2 =
  106998. + dmaAddress1 = dmaAddress2 =
  106999. + dmaLow = dmaHigh = 0;
  107000. +
  107001. + /* Verify whether DMA is running. */
  107002. + gcmkONERROR(_VerifyDMA(
  107003. + os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  107004. + ));
  107005. +
  107006. + cmdState = dmaState2 & 0x1F;
  107007. + cmdDmaState = (dmaState2 >> 8) & 0x03;
  107008. + cmdFetState = (dmaState2 >> 10) & 0x03;
  107009. + dmaReqState = (dmaState2 >> 12) & 0x03;
  107010. + calState = (dmaState2 >> 14) & 0x03;
  107011. + veReqState = (dmaState2 >> 16) & 0x03;
  107012. +
  107013. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x004, &idle));
  107014. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00C, &axi));
  107015. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x668, &dmaLow));
  107016. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x66C, &dmaHigh));
  107017. +
  107018. + gcmkPRINT_N(0, "**************************\n");
  107019. + gcmkPRINT_N(0, "*** GPU STATE DUMP ***\n");
  107020. + gcmkPRINT_N(0, "**************************\n");
  107021. +
  107022. + gcmkPRINT_N(4, " axi = 0x%08X\n", axi);
  107023. +
  107024. + gcmkPRINT_N(4, " idle = 0x%08X\n", idle);
  107025. + if ((idle & 0x00000001) == 0) gcmkPRINT_N(0, " FE not idle\n");
  107026. + if ((idle & 0x00000002) == 0) gcmkPRINT_N(0, " DE not idle\n");
  107027. + if ((idle & 0x00000004) == 0) gcmkPRINT_N(0, " PE not idle\n");
  107028. + if ((idle & 0x00000008) == 0) gcmkPRINT_N(0, " SH not idle\n");
  107029. + if ((idle & 0x00000010) == 0) gcmkPRINT_N(0, " PA not idle\n");
  107030. + if ((idle & 0x00000020) == 0) gcmkPRINT_N(0, " SE not idle\n");
  107031. + if ((idle & 0x00000040) == 0) gcmkPRINT_N(0, " RA not idle\n");
  107032. + if ((idle & 0x00000080) == 0) gcmkPRINT_N(0, " TX not idle\n");
  107033. + if ((idle & 0x00000100) == 0) gcmkPRINT_N(0, " VG not idle\n");
  107034. + if ((idle & 0x00000200) == 0) gcmkPRINT_N(0, " IM not idle\n");
  107035. + if ((idle & 0x00000400) == 0) gcmkPRINT_N(0, " FP not idle\n");
  107036. + if ((idle & 0x00000800) == 0) gcmkPRINT_N(0, " TS not idle\n");
  107037. + if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, " AXI low power mode\n");
  107038. +
  107039. + if (
  107040. + (dmaAddress1 == dmaAddress2)
  107041. + && (dmaState1 == dmaState2)
  107042. + )
  107043. + {
  107044. + gcmkPRINT_N(0, " DMA appears to be stuck at this address:\n");
  107045. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
  107046. + }
  107047. + else
  107048. + {
  107049. + if (dmaAddress1 == dmaAddress2)
  107050. + {
  107051. + gcmkPRINT_N(0, " DMA address is constant, but state is changing:\n");
  107052. + gcmkPRINT_N(4, " 0x%08X\n", dmaState1);
  107053. + gcmkPRINT_N(4, " 0x%08X\n", dmaState2);
  107054. + }
  107055. + else
  107056. + {
  107057. + gcmkPRINT_N(0, " DMA is running; known addresses are:\n");
  107058. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
  107059. + gcmkPRINT_N(4, " 0x%08X\n", dmaAddress2);
  107060. + }
  107061. + }
  107062. + gcmkPRINT_N(4, " dmaLow = 0x%08X\n", dmaLow);
  107063. + gcmkPRINT_N(4, " dmaHigh = 0x%08X\n", dmaHigh);
  107064. + gcmkPRINT_N(4, " dmaState = 0x%08X\n", dmaState2);
  107065. + gcmkPRINT_N(8, " command state = %d (%s)\n", cmdState, _cmdState [cmdState]);
  107066. + gcmkPRINT_N(8, " command DMA state = %d (%s)\n", cmdDmaState, _cmdDmaState[cmdDmaState]);
  107067. + gcmkPRINT_N(8, " command fetch state = %d (%s)\n", cmdFetState, _cmdFetState[cmdFetState]);
  107068. + gcmkPRINT_N(8, " DMA request state = %d (%s)\n", dmaReqState, _reqDmaState[dmaReqState]);
  107069. + gcmkPRINT_N(8, " cal state = %d (%s)\n", calState, _calState [calState]);
  107070. + gcmkPRINT_N(8, " VE request state = %d (%s)\n", veReqState, _veReqState [veReqState]);
  107071. +
  107072. + /* Record control. */
  107073. + gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
  107074. +
  107075. + for (pipe = 0; pipe < pixelPipes; pipe++)
  107076. + {
  107077. + gcmkPRINT_N(4, " Debug registers of pipe[%d]:\n", pipe);
  107078. +
  107079. + /* Switch pipe. */
  107080. + gckOS_ReadRegisterEx(os, core, 0x0, &control);
  107081. + control &= ~(0xF << 20);
  107082. + control |= (pipe << 20);
  107083. + gckOS_WriteRegisterEx(os, core, 0x0, control);
  107084. +
  107085. + for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
  107086. + {
  107087. + gcmkONERROR(_DumpDebugRegisters(os, core, &_dbgRegs[i]));
  107088. + }
  107089. +
  107090. + gcmkPRINT_N(0, " Other Registers:\n");
  107091. + for (i = 0; i < gcmCOUNTOF(_otherRegs); i += 1)
  107092. + {
  107093. + gctUINT32 read;
  107094. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, _otherRegs[i], &read));
  107095. + gcmkPRINT_N(12, " [0x%04X] 0x%08X\n", _otherRegs[i], read);
  107096. + }
  107097. + }
  107098. +
  107099. + if (kernel->hardware->identity.chipFeatures & (1 << 4))
  107100. + {
  107101. + gctUINT32 read0, read1, write;
  107102. +
  107103. + read0 = read1 = write = 0;
  107104. +
  107105. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x43C, &read0));
  107106. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x440, &read1));
  107107. + gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x444, &write));
  107108. +
  107109. + gcmkPRINT_N(4, " read0 = 0x%08X\n", read0);
  107110. + gcmkPRINT_N(4, " read1 = 0x%08X\n", read1);
  107111. + gcmkPRINT_N(4, " write = 0x%08X\n", write);
  107112. + }
  107113. +
  107114. + /* Restore control. */
  107115. + gckOS_WriteRegisterEx(os, core, 0x0, oldControl);
  107116. +
  107117. + /* dump stack. */
  107118. + gckOS_DumpCallStack(os);
  107119. +
  107120. +OnError:
  107121. +
  107122. + /* Return the error. */
  107123. + gcmkFOOTER();
  107124. + return status;
  107125. +}
  107126. +
  107127. +
  107128. +#if gcdFRAME_DB
  107129. +static gceSTATUS
  107130. +gckHARDWARE_ReadPerformanceRegister(
  107131. + IN gckHARDWARE Hardware,
  107132. + IN gctUINT PerformanceAddress,
  107133. + IN gctUINT IndexAddress,
  107134. + IN gctUINT IndexShift,
  107135. + IN gctUINT Index,
  107136. + OUT gctUINT32_PTR Value
  107137. + )
  107138. +{
  107139. + gceSTATUS status;
  107140. +
  107141. + gcmkHEADER_ARG("Hardware=0x%x PerformanceAddress=0x%x IndexAddress=0x%x "
  107142. + "IndexShift=%u Index=%u",
  107143. + Hardware, PerformanceAddress, IndexAddress, IndexShift,
  107144. + Index);
  107145. +
  107146. + /* Write the index. */
  107147. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107148. + Hardware->core,
  107149. + IndexAddress,
  107150. + Index << IndexShift));
  107151. +
  107152. + /* Read the register. */
  107153. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107154. + Hardware->core,
  107155. + PerformanceAddress,
  107156. + Value));
  107157. +
  107158. + /* Test for reset. */
  107159. + if (Index == 15)
  107160. + {
  107161. + /* Index another register to get out of reset. */
  107162. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, IndexAddress, 0));
  107163. + }
  107164. +
  107165. + /* Success. */
  107166. + gcmkFOOTER_ARG("*Value=0x%x", *Value);
  107167. + return gcvSTATUS_OK;
  107168. +
  107169. +OnError:
  107170. + /* Return the status. */
  107171. + gcmkFOOTER();
  107172. + return status;
  107173. +}
  107174. +
  107175. +gceSTATUS
  107176. +gckHARDWARE_GetFrameInfo(
  107177. + IN gckHARDWARE Hardware,
  107178. + OUT gcsHAL_FRAME_INFO * FrameInfo
  107179. + )
  107180. +{
  107181. + gceSTATUS status;
  107182. + gctUINT i, clock;
  107183. + gcsHAL_FRAME_INFO info;
  107184. +#if gcdFRAME_DB_RESET
  107185. + gctUINT reset;
  107186. +#endif
  107187. +
  107188. + gcmkHEADER_ARG("Hardware=0x%x", Hardware);
  107189. +
  107190. + /* Get profile tick. */
  107191. + gcmkONERROR(gckOS_GetProfileTick(&info.ticks));
  107192. +
  107193. + /* Read SH counters and reset them. */
  107194. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107195. + Hardware,
  107196. + 0x0045C,
  107197. + 0x00470,
  107198. + 24,
  107199. + 4,
  107200. + &info.shaderCycles));
  107201. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107202. + Hardware,
  107203. + 0x0045C,
  107204. + 0x00470,
  107205. + 24,
  107206. + 9,
  107207. + &info.vsInstructionCount));
  107208. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107209. + Hardware,
  107210. + 0x0045C,
  107211. + 0x00470,
  107212. + 24,
  107213. + 12,
  107214. + &info.vsTextureCount));
  107215. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107216. + Hardware,
  107217. + 0x0045C,
  107218. + 0x00470,
  107219. + 24,
  107220. + 7,
  107221. + &info.psInstructionCount));
  107222. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107223. + Hardware,
  107224. + 0x0045C,
  107225. + 0x00470,
  107226. + 24,
  107227. + 14,
  107228. + &info.psTextureCount));
  107229. +#if gcdFRAME_DB_RESET
  107230. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107231. + Hardware,
  107232. + 0x0045C,
  107233. + 0x00470,
  107234. + 24,
  107235. + 15,
  107236. + &reset));
  107237. +#endif
  107238. +
  107239. + /* Read PA counters and reset them. */
  107240. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107241. + Hardware,
  107242. + 0x00460,
  107243. + 0x00474,
  107244. + 0,
  107245. + 3,
  107246. + &info.vertexCount));
  107247. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107248. + Hardware,
  107249. + 0x00460,
  107250. + 0x00474,
  107251. + 0,
  107252. + 4,
  107253. + &info.primitiveCount));
  107254. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107255. + Hardware,
  107256. + 0x00460,
  107257. + 0x00474,
  107258. + 0,
  107259. + 7,
  107260. + &info.rejectedPrimitives));
  107261. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107262. + Hardware,
  107263. + 0x00460,
  107264. + 0x00474,
  107265. + 0,
  107266. + 8,
  107267. + &info.culledPrimitives));
  107268. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107269. + Hardware,
  107270. + 0x00460,
  107271. + 0x00474,
  107272. + 0,
  107273. + 6,
  107274. + &info.clippedPrimitives));
  107275. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107276. + Hardware,
  107277. + 0x00460,
  107278. + 0x00474,
  107279. + 0,
  107280. + 5,
  107281. + &info.outPrimitives));
  107282. +#if gcdFRAME_DB_RESET
  107283. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107284. + Hardware,
  107285. + 0x00460,
  107286. + 0x00474,
  107287. + 0,
  107288. + 15,
  107289. + &reset));
  107290. +#endif
  107291. +
  107292. + /* Read RA counters and reset them. */
  107293. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107294. + Hardware,
  107295. + 0x00448,
  107296. + 0x00474,
  107297. + 16,
  107298. + 3,
  107299. + &info.inPrimitives));
  107300. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107301. + Hardware,
  107302. + 0x00448,
  107303. + 0x00474,
  107304. + 16,
  107305. + 11,
  107306. + &info.culledQuadCount));
  107307. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107308. + Hardware,
  107309. + 0x00448,
  107310. + 0x00474,
  107311. + 16,
  107312. + 1,
  107313. + &info.totalQuadCount));
  107314. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107315. + Hardware,
  107316. + 0x00448,
  107317. + 0x00474,
  107318. + 16,
  107319. + 2,
  107320. + &info.quadCount));
  107321. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107322. + Hardware,
  107323. + 0x00448,
  107324. + 0x00474,
  107325. + 16,
  107326. + 0,
  107327. + &info.totalPixelCount));
  107328. +#if gcdFRAME_DB_RESET
  107329. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107330. + Hardware,
  107331. + 0x00448,
  107332. + 0x00474,
  107333. + 16,
  107334. + 15,
  107335. + &reset));
  107336. +#endif
  107337. +
  107338. + /* Read TX counters and reset them. */
  107339. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107340. + Hardware,
  107341. + 0x0044C,
  107342. + 0x00474,
  107343. + 24,
  107344. + 0,
  107345. + &info.bilinearRequests));
  107346. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107347. + Hardware,
  107348. + 0x0044C,
  107349. + 0x00474,
  107350. + 24,
  107351. + 1,
  107352. + &info.trilinearRequests));
  107353. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107354. + Hardware,
  107355. + 0x0044C,
  107356. + 0x00474,
  107357. + 24,
  107358. + 8,
  107359. + &info.txHitCount));
  107360. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107361. + Hardware,
  107362. + 0x0044C,
  107363. + 0x00474,
  107364. + 24,
  107365. + 9,
  107366. + &info.txMissCount));
  107367. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107368. + Hardware,
  107369. + 0x0044C,
  107370. + 0x00474,
  107371. + 24,
  107372. + 6,
  107373. + &info.txBytes8));
  107374. +#if gcdFRAME_DB_RESET
  107375. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107376. + Hardware,
  107377. + 0x0044C,
  107378. + 0x00474,
  107379. + 24,
  107380. + 15,
  107381. + &reset));
  107382. +#endif
  107383. +
  107384. + /* Read clock control register. */
  107385. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107386. + Hardware->core,
  107387. + 0x00000,
  107388. + &clock));
  107389. +
  107390. + /* Walk through all avaiable pixel pipes. */
  107391. + for (i = 0; i < Hardware->identity.pixelPipes; ++i)
  107392. + {
  107393. + /* Select proper pipe. */
  107394. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107395. + Hardware->core,
  107396. + 0x00000,
  107397. + ((((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)))));
  107398. +
  107399. + /* Read cycle registers. */
  107400. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107401. + Hardware->core,
  107402. + 0x00078,
  107403. + &info.cycles[i]));
  107404. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107405. + Hardware->core,
  107406. + 0x0007C,
  107407. + &info.idleCycles[i]));
  107408. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107409. + Hardware->core,
  107410. + 0x00438,
  107411. + &info.mcCycles[i]));
  107412. +
  107413. + /* Read bandwidth registers. */
  107414. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107415. + Hardware->core,
  107416. + 0x0005C,
  107417. + &info.readRequests[i]));
  107418. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107419. + Hardware->core,
  107420. + 0x00040,
  107421. + &info.readBytes8[i]));
  107422. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107423. + Hardware->core,
  107424. + 0x00050,
  107425. + &info.writeRequests[i]));
  107426. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107427. + Hardware->core,
  107428. + 0x00044,
  107429. + &info.writeBytes8[i]));
  107430. +
  107431. + /* Read PE counters. */
  107432. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107433. + Hardware,
  107434. + 0x00454,
  107435. + 0x00470,
  107436. + 16,
  107437. + 0,
  107438. + &info.colorKilled[i]));
  107439. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107440. + Hardware,
  107441. + 0x00454,
  107442. + 0x00470,
  107443. + 16,
  107444. + 2,
  107445. + &info.colorDrawn[i]));
  107446. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107447. + Hardware,
  107448. + 0x00454,
  107449. + 0x00470,
  107450. + 16,
  107451. + 1,
  107452. + &info.depthKilled[i]));
  107453. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107454. + Hardware,
  107455. + 0x00454,
  107456. + 0x00470,
  107457. + 16,
  107458. + 3,
  107459. + &info.depthDrawn[i]));
  107460. + }
  107461. +
  107462. + /* Zero out remaning reserved counters. */
  107463. + for (; i < 8; ++i)
  107464. + {
  107465. + info.readBytes8[i] = 0;
  107466. + info.writeBytes8[i] = 0;
  107467. + info.cycles[i] = 0;
  107468. + info.idleCycles[i] = 0;
  107469. + info.mcCycles[i] = 0;
  107470. + info.readRequests[i] = 0;
  107471. + info.writeRequests[i] = 0;
  107472. + info.colorKilled[i] = 0;
  107473. + info.colorDrawn[i] = 0;
  107474. + info.depthKilled[i] = 0;
  107475. + info.depthDrawn[i] = 0;
  107476. + }
  107477. +
  107478. + /* Reset clock control register. */
  107479. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107480. + Hardware->core,
  107481. + 0x00000,
  107482. + clock));
  107483. +
  107484. + /* Reset cycle and bandwidth counters. */
  107485. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107486. + Hardware->core,
  107487. + 0x0003C,
  107488. + 1));
  107489. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107490. + Hardware->core,
  107491. + 0x0003C,
  107492. + 0));
  107493. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107494. + Hardware->core,
  107495. + 0x00078,
  107496. + 0));
  107497. +
  107498. +#if gcdFRAME_DB_RESET
  107499. + /* Reset PE counters. */
  107500. + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
  107501. + Hardware,
  107502. + 0x00454,
  107503. + 0x00470,
  107504. + 16,
  107505. + 15,
  107506. + &reset));
  107507. +#endif
  107508. +
  107509. + /* Copy to user. */
  107510. + gcmkONERROR(gckOS_CopyToUserData(Hardware->os,
  107511. + &info,
  107512. + FrameInfo,
  107513. + gcmSIZEOF(info)));
  107514. +
  107515. + /* Success. */
  107516. + gcmkFOOTER_NO();
  107517. + return gcvSTATUS_OK;
  107518. +
  107519. +OnError:
  107520. + /* Return the status. */
  107521. + gcmkFOOTER();
  107522. + return status;
  107523. +}
  107524. +#endif
  107525. +
  107526. +#if gcdDVFS
  107527. +#define READ_FROM_EATER1 0
  107528. +
  107529. +gceSTATUS
  107530. +gckHARDWARE_QueryLoad(
  107531. + IN gckHARDWARE Hardware,
  107532. + OUT gctUINT32 * Load
  107533. + )
  107534. +{
  107535. + gctUINT32 debug1;
  107536. + gceSTATUS status;
  107537. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  107538. +
  107539. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  107540. + gcmkVERIFY_ARGUMENT(Load != gcvNULL);
  107541. +
  107542. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
  107543. +
  107544. + if (Hardware->chipPowerState == gcvPOWER_ON)
  107545. + {
  107546. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107547. + Hardware->core,
  107548. + 0x00110,
  107549. + Load));
  107550. +#if READ_FROM_EATER1
  107551. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107552. + Hardware->core,
  107553. + 0x00134,
  107554. + Load));
  107555. +#endif
  107556. +
  107557. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107558. + Hardware->core,
  107559. + 0x00114,
  107560. + &debug1));
  107561. +
  107562. + /* Patch result of 0x110 with result of 0x114. */
  107563. + if ((debug1 & 0xFF) == 1)
  107564. + {
  107565. + *Load &= ~0xFF;
  107566. + *Load |= 1;
  107567. + }
  107568. +
  107569. + if (((debug1 & 0xFF00) >> 8) == 1)
  107570. + {
  107571. + *Load &= ~(0xFF << 8);
  107572. + *Load |= 1 << 8;
  107573. + }
  107574. +
  107575. + if (((debug1 & 0xFF0000) >> 16) == 1)
  107576. + {
  107577. + *Load &= ~(0xFF << 16);
  107578. + *Load |= 1 << 16;
  107579. + }
  107580. +
  107581. + if (((debug1 & 0xFF000000) >> 24) == 1)
  107582. + {
  107583. + *Load &= ~(0xFF << 24);
  107584. + *Load |= 1 << 24;
  107585. + }
  107586. + }
  107587. + else
  107588. + {
  107589. + status = gcvSTATUS_INVALID_REQUEST;
  107590. + }
  107591. +
  107592. +OnError:
  107593. +
  107594. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  107595. +
  107596. + gcmkFOOTER();
  107597. + return status;
  107598. +}
  107599. +
  107600. +gceSTATUS
  107601. +gckHARDWARE_SetDVFSPeroid(
  107602. + IN gckHARDWARE Hardware,
  107603. + OUT gctUINT32 Frequency
  107604. + )
  107605. +{
  107606. + gceSTATUS status;
  107607. + gctUINT32 period;
  107608. + gctUINT32 eater;
  107609. +
  107610. +#if READ_FROM_EATER1
  107611. + gctUINT32 period1;
  107612. + gctUINT32 eater1;
  107613. +#endif
  107614. +
  107615. + gcmkHEADER_ARG("Hardware=0x%X Frequency=%d", Hardware, Frequency);
  107616. +
  107617. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  107618. +
  107619. + period = 0;
  107620. +
  107621. + while((64 << period) < (gcdDVFS_ANAYLSE_WINDOW * Frequency * 1000) )
  107622. + {
  107623. + period++;
  107624. + }
  107625. +
  107626. +#if READ_FROM_EATER1
  107627. + /*
  107628. + * Peroid = F * 1000 * 1000 / (60 * 16 * 1024);
  107629. + */
  107630. + period1 = Frequency * 6250 / 6114;
  107631. +#endif
  107632. +
  107633. + gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
  107634. +
  107635. + if (Hardware->chipPowerState == gcvPOWER_ON)
  107636. + {
  107637. + /* Get current configure. */
  107638. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107639. + Hardware->core,
  107640. + 0x0010C,
  107641. + &eater));
  107642. +
  107643. + /* Change peroid. */
  107644. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107645. + Hardware->core,
  107646. + 0x0010C,
  107647. + ((((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)))));
  107648. +
  107649. +#if READ_FROM_EATER1
  107650. + /* Config eater1. */
  107651. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107652. + Hardware->core,
  107653. + 0x00130,
  107654. + &eater1));
  107655. +
  107656. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107657. + Hardware->core,
  107658. + 0x00130,
  107659. + ((((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)))));
  107660. +#endif
  107661. + }
  107662. + else
  107663. + {
  107664. + status = gcvSTATUS_INVALID_REQUEST;
  107665. + }
  107666. +
  107667. +OnError:
  107668. + gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
  107669. +
  107670. + gcmkFOOTER();
  107671. + return status;
  107672. +}
  107673. +
  107674. +gceSTATUS
  107675. +gckHARDWARE_InitDVFS(
  107676. + IN gckHARDWARE Hardware
  107677. + )
  107678. +{
  107679. + gceSTATUS status;
  107680. + gctUINT32 data;
  107681. +
  107682. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  107683. +
  107684. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  107685. +
  107686. + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
  107687. + Hardware->core,
  107688. + 0x0010C,
  107689. + &data));
  107690. +
  107691. + 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)));
  107692. + 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)));
  107693. + 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)));
  107694. + 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)));
  107695. + 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)));
  107696. + 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)));
  107697. +
  107698. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
  107699. + "DVFS Configure=0x%X",
  107700. + data);
  107701. +
  107702. + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
  107703. + Hardware->core,
  107704. + 0x0010C,
  107705. + data));
  107706. +
  107707. + gcmkFOOTER_NO();
  107708. + return gcvSTATUS_OK;
  107709. +
  107710. +OnError:
  107711. + gcmkFOOTER();
  107712. + return status;
  107713. +}
  107714. +#endif
  107715. +
  107716. +
  107717. diff -Nur linux-3.14.17/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
  107718. --- linux-3.14.17/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h 1970-01-01 01:00:00.000000000 +0100
  107719. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h 2014-09-11 18:06:03.082042291 +0200
  107720. @@ -0,0 +1,136 @@
  107721. +/****************************************************************************
  107722. +*
  107723. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  107724. +*
  107725. +* This program is free software; you can redistribute it and/or modify
  107726. +* it under the terms of the GNU General Public License as published by
  107727. +* the Free Software Foundation; either version 2 of the license, or
  107728. +* (at your option) any later version.
  107729. +*
  107730. +* This program is distributed in the hope that it will be useful,
  107731. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  107732. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  107733. +* GNU General Public License for more details.
  107734. +*
  107735. +* You should have received a copy of the GNU General Public License
  107736. +* along with this program; if not write to the Free Software
  107737. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  107738. +*
  107739. +*****************************************************************************/
  107740. +
  107741. +
  107742. +#ifndef __gc_hal_kernel_hardware_h_
  107743. +#define __gc_hal_kernel_hardware_h_
  107744. +
  107745. +#if gcdENABLE_VG
  107746. +#include "gc_hal_kernel_hardware_vg.h"
  107747. +#endif
  107748. +
  107749. +#ifdef __cplusplus
  107750. +extern "C" {
  107751. +#endif
  107752. +
  107753. +/* gckHARDWARE object. */
  107754. +struct _gckHARDWARE
  107755. +{
  107756. + /* Object. */
  107757. + gcsOBJECT object;
  107758. +
  107759. + /* Pointer to gctKERNEL object. */
  107760. + gckKERNEL kernel;
  107761. +
  107762. + /* Pointer to gctOS object. */
  107763. + gckOS os;
  107764. +
  107765. + /* Core */
  107766. + gceCORE core;
  107767. +
  107768. + /* Chip characteristics. */
  107769. + gcsHAL_QUERY_CHIP_IDENTITY identity;
  107770. + gctBOOL allowFastClear;
  107771. + gctBOOL allowCompression;
  107772. + gctUINT32 powerBaseAddress;
  107773. + gctBOOL extraEventStates;
  107774. +
  107775. + /* Big endian */
  107776. + gctBOOL bigEndian;
  107777. +
  107778. + /* Chip status */
  107779. + gctPOINTER powerMutex;
  107780. + gctUINT32 powerProcess;
  107781. + gctUINT32 powerThread;
  107782. + gceCHIPPOWERSTATE chipPowerState;
  107783. + gctUINT32 lastWaitLink;
  107784. + gctBOOL clockState;
  107785. + gctBOOL powerState;
  107786. + gctPOINTER globalSemaphore;
  107787. +
  107788. + gctISRMANAGERFUNC startIsr;
  107789. + gctISRMANAGERFUNC stopIsr;
  107790. + gctPOINTER isrContext;
  107791. +
  107792. + gctUINT32 mmuVersion;
  107793. +
  107794. + /* Type */
  107795. + gceHARDWARE_TYPE type;
  107796. +
  107797. +#if gcdPOWEROFF_TIMEOUT
  107798. + gctUINT32 powerOffTime;
  107799. + gctUINT32 powerOffTimeout;
  107800. + gctPOINTER powerOffTimer;
  107801. +#endif
  107802. +
  107803. + gctPOINTER pageTableDirty;
  107804. +
  107805. +#if gcdENABLE_FSCALE_VAL_ADJUST
  107806. + /* FSCALE_VAL when gcvPOWER_ON. */
  107807. + gctUINT32 powerOnFscaleVal;
  107808. +#endif
  107809. +
  107810. +#if gcdLINK_QUEUE_SIZE
  107811. + struct _gckLINKQUEUE linkQueue;
  107812. +#endif
  107813. +
  107814. + gctBOOL powerManagement;
  107815. + gctBOOL gpuProfiler;
  107816. +};
  107817. +
  107818. +gceSTATUS
  107819. +gckHARDWARE_GetBaseAddress(
  107820. + IN gckHARDWARE Hardware,
  107821. + OUT gctUINT32_PTR BaseAddress
  107822. + );
  107823. +
  107824. +gceSTATUS
  107825. +gckHARDWARE_NeedBaseAddress(
  107826. + IN gckHARDWARE Hardware,
  107827. + IN gctUINT32 State,
  107828. + OUT gctBOOL_PTR NeedBase
  107829. + );
  107830. +
  107831. +gceSTATUS
  107832. +gckHARDWARE_GetFrameInfo(
  107833. + IN gckHARDWARE Hardware,
  107834. + OUT gcsHAL_FRAME_INFO * FrameInfo
  107835. + );
  107836. +
  107837. +gceSTATUS
  107838. +gckHARDWARE_SetFscaleValue(
  107839. + IN gckHARDWARE Hardware,
  107840. + IN gctUINT32 FscaleValue
  107841. + );
  107842. +
  107843. +gceSTATUS
  107844. +gckHARDWARE_GetFscaleValue(
  107845. + IN gckHARDWARE Hardware,
  107846. + IN gctUINT * FscaleValue,
  107847. + IN gctUINT * MinFscaleValue,
  107848. + IN gctUINT * MaxFscaleValue
  107849. + );
  107850. +
  107851. +#ifdef __cplusplus
  107852. +}
  107853. +#endif
  107854. +
  107855. +#endif /* __gc_hal_kernel_hardware_h_ */
  107856. +
  107857. diff -Nur linux-3.14.17/drivers/mxc/gpu-viv/config linux-imx6-3.14/drivers/mxc/gpu-viv/config
  107858. --- linux-3.14.17/drivers/mxc/gpu-viv/config 1970-01-01 01:00:00.000000000 +0100
  107859. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/config 2014-09-11 18:06:03.082042291 +0200
  107860. @@ -0,0 +1,38 @@
  107861. +##############################################################################
  107862. +#
  107863. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  107864. +#
  107865. +# This program is free software; you can redistribute it and/or modify
  107866. +# it under the terms of the GNU General Public License as published by
  107867. +# the Free Software Foundation; either version 2 of the license, or
  107868. +# (at your option) any later version.
  107869. +#
  107870. +# This program is distributed in the hope that it will be useful,
  107871. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  107872. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  107873. +# GNU General Public License for more details.
  107874. +#
  107875. +# You should have received a copy of the GNU General Public License
  107876. +# along with this program; if not write to the Free Software
  107877. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  107878. +#
  107879. +##############################################################################
  107880. +
  107881. +
  107882. +ARCH_TYPE ?= arm
  107883. +SDK_DIR ?= $(AQROOT)/build/sdk
  107884. +USE_3D_VG ?= 1
  107885. +FORCE_ALL_VIDEO_MEMORY_CACHED ?= 0
  107886. +NONPAGED_MEMORY_CACHEABLE ?= 0
  107887. +NONPAGED_MEMORY_BUFFERABLE ?= 1
  107888. +CACHE_FUNCTION_UNIMPLEMENTED ?= 0
  107889. +VIVANTE_ENABLE_VG ?= 1
  107890. +NO_USER_DIRECT_ACCESS_FROM_KERNEL ?= 1
  107891. +VIVANTE_NO_3D ?= 0
  107892. +ENABLE_OUTER_CACHE_PATCH ?= 1
  107893. +USE_BANK_ALIGNMENT ?= 1
  107894. +BANK_BIT_START ?= 13
  107895. +BANK_BIT_END ?= 15
  107896. +BANK_CHANNEL_BIT ?= 12
  107897. +ENABLE_GPU_CLOCK_BY_DRIVER = 1
  107898. +
  107899. diff -Nur linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
  107900. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c 1970-01-01 01:00:00.000000000 +0100
  107901. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c 2014-09-11 18:06:03.082042291 +0200
  107902. @@ -0,0 +1,3967 @@
  107903. +/****************************************************************************
  107904. +*
  107905. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  107906. +*
  107907. +* This program is free software; you can redistribute it and/or modify
  107908. +* it under the terms of the GNU General Public License as published by
  107909. +* the Free Software Foundation; either version 2 of the license, or
  107910. +* (at your option) any later version.
  107911. +*
  107912. +* This program is distributed in the hope that it will be useful,
  107913. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  107914. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  107915. +* GNU General Public License for more details.
  107916. +*
  107917. +* You should have received a copy of the GNU General Public License
  107918. +* along with this program; if not write to the Free Software
  107919. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  107920. +*
  107921. +*****************************************************************************/
  107922. +
  107923. +
  107924. +#include "gc_hal_kernel_precomp.h"
  107925. +
  107926. +#define _GC_OBJ_ZONE gcvZONE_KERNEL
  107927. +
  107928. +/*******************************************************************************
  107929. +***** Version Signature *******************************************************/
  107930. +
  107931. +#define _gcmTXT2STR(t) #t
  107932. +#define gcmTXT2STR(t) _gcmTXT2STR(t)
  107933. +const char * _VERSION = "\n\0$VERSION$"
  107934. + gcmTXT2STR(gcvVERSION_MAJOR) "."
  107935. + gcmTXT2STR(gcvVERSION_MINOR) "."
  107936. + gcmTXT2STR(gcvVERSION_PATCH) ":"
  107937. + gcmTXT2STR(gcvVERSION_BUILD) "$\n";
  107938. +
  107939. +/******************************************************************************\
  107940. +******************************* gckKERNEL API Code ******************************
  107941. +\******************************************************************************/
  107942. +
  107943. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  107944. +#define gcmDEFINE2TEXT(d) #d
  107945. +gctCONST_STRING _DispatchText[] =
  107946. +{
  107947. + gcmDEFINE2TEXT(gcvHAL_QUERY_VIDEO_MEMORY),
  107948. + gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_IDENTITY),
  107949. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_NON_PAGED_MEMORY),
  107950. + gcmDEFINE2TEXT(gcvHAL_FREE_NON_PAGED_MEMORY),
  107951. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY),
  107952. + gcmDEFINE2TEXT(gcvHAL_FREE_CONTIGUOUS_MEMORY),
  107953. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIDEO_MEMORY),
  107954. + gcmDEFINE2TEXT(gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY),
  107955. + gcmDEFINE2TEXT(gcvHAL_FREE_VIDEO_MEMORY),
  107956. + gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY),
  107957. + gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY),
  107958. + gcmDEFINE2TEXT(gcvHAL_MAP_USER_MEMORY),
  107959. + gcmDEFINE2TEXT(gcvHAL_UNMAP_USER_MEMORY),
  107960. + gcmDEFINE2TEXT(gcvHAL_LOCK_VIDEO_MEMORY),
  107961. + gcmDEFINE2TEXT(gcvHAL_UNLOCK_VIDEO_MEMORY),
  107962. + gcmDEFINE2TEXT(gcvHAL_EVENT_COMMIT),
  107963. + gcmDEFINE2TEXT(gcvHAL_USER_SIGNAL),
  107964. + gcmDEFINE2TEXT(gcvHAL_SIGNAL),
  107965. + gcmDEFINE2TEXT(gcvHAL_WRITE_DATA),
  107966. + gcmDEFINE2TEXT(gcvHAL_COMMIT),
  107967. + gcmDEFINE2TEXT(gcvHAL_STALL),
  107968. + gcmDEFINE2TEXT(gcvHAL_READ_REGISTER),
  107969. + gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER),
  107970. + gcmDEFINE2TEXT(gcvHAL_GET_PROFILE_SETTING),
  107971. + gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING),
  107972. + gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS),
  107973. +#if VIVANTE_PROFILER_PERDRAW
  107974. + gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING),
  107975. +#endif
  107976. + gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
  107977. + gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE),
  107978. + gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE),
  107979. + gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS),
  107980. + gcmDEFINE2TEXT(gcvHAL_SET_IDLE),
  107981. + gcmDEFINE2TEXT(gcvHAL_QUERY_KERNEL_SETTINGS),
  107982. + gcmDEFINE2TEXT(gcvHAL_RESET),
  107983. + gcmDEFINE2TEXT(gcvHAL_MAP_PHYSICAL),
  107984. + gcmDEFINE2TEXT(gcvHAL_DEBUG),
  107985. + gcmDEFINE2TEXT(gcvHAL_CACHE),
  107986. + gcmDEFINE2TEXT(gcvHAL_TIMESTAMP),
  107987. + gcmDEFINE2TEXT(gcvHAL_DATABASE),
  107988. + gcmDEFINE2TEXT(gcvHAL_VERSION),
  107989. + gcmDEFINE2TEXT(gcvHAL_CHIP_INFO),
  107990. + gcmDEFINE2TEXT(gcvHAL_ATTACH),
  107991. + gcmDEFINE2TEXT(gcvHAL_DETACH)
  107992. +};
  107993. +#endif
  107994. +
  107995. +#if gcdENABLE_RECOVERY
  107996. +void
  107997. +_ResetFinishFunction(
  107998. + gctPOINTER Data
  107999. + )
  108000. +{
  108001. + gckKERNEL kernel = (gckKERNEL)Data;
  108002. +
  108003. + gckOS_AtomSet(kernel->os, kernel->resetAtom, 0);
  108004. +}
  108005. +#endif
  108006. +
  108007. +/*******************************************************************************
  108008. +**
  108009. +** gckKERNEL_Construct
  108010. +**
  108011. +** Construct a new gckKERNEL object.
  108012. +**
  108013. +** INPUT:
  108014. +**
  108015. +** gckOS Os
  108016. +** Pointer to an gckOS object.
  108017. +**
  108018. +** gceCORE Core
  108019. +** Specified core.
  108020. +**
  108021. +** IN gctPOINTER Context
  108022. +** Pointer to a driver defined context.
  108023. +**
  108024. +** IN gckDB SharedDB,
  108025. +** Pointer to a shared DB.
  108026. +**
  108027. +** OUTPUT:
  108028. +**
  108029. +** gckKERNEL * Kernel
  108030. +** Pointer to a variable that will hold the pointer to the gckKERNEL
  108031. +** object.
  108032. +*/
  108033. +
  108034. +gceSTATUS
  108035. +gckKERNEL_Construct(
  108036. + IN gckOS Os,
  108037. + IN gceCORE Core,
  108038. + IN gctPOINTER Context,
  108039. + IN gckDB SharedDB,
  108040. + OUT gckKERNEL * Kernel
  108041. + )
  108042. +{
  108043. + gckKERNEL kernel = gcvNULL;
  108044. + gceSTATUS status;
  108045. + gctSIZE_T i;
  108046. + gctPOINTER pointer = gcvNULL;
  108047. +
  108048. + gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
  108049. +
  108050. + /* Verify the arguments. */
  108051. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  108052. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  108053. +
  108054. + /* Allocate the gckKERNEL object. */
  108055. + gcmkONERROR(gckOS_Allocate(Os,
  108056. + gcmSIZEOF(struct _gckKERNEL),
  108057. + &pointer));
  108058. +
  108059. + kernel = pointer;
  108060. +
  108061. + /* Zero the object pointers. */
  108062. + kernel->hardware = gcvNULL;
  108063. + kernel->command = gcvNULL;
  108064. + kernel->eventObj = gcvNULL;
  108065. + kernel->mmu = gcvNULL;
  108066. +#if gcdDVFS
  108067. + kernel->dvfs = gcvNULL;
  108068. +#endif
  108069. +
  108070. + /* Initialize the gckKERNEL object. */
  108071. + kernel->object.type = gcvOBJ_KERNEL;
  108072. + kernel->os = Os;
  108073. + kernel->core = Core;
  108074. +
  108075. +
  108076. + if (SharedDB == gcvNULL)
  108077. + {
  108078. + gcmkONERROR(gckOS_Allocate(Os,
  108079. + gcmSIZEOF(struct _gckDB),
  108080. + &pointer));
  108081. +
  108082. + kernel->db = pointer;
  108083. + kernel->dbCreated = gcvTRUE;
  108084. + kernel->db->freeDatabase = gcvNULL;
  108085. + kernel->db->freeRecord = gcvNULL;
  108086. + kernel->db->dbMutex = gcvNULL;
  108087. + kernel->db->lastDatabase = gcvNULL;
  108088. + kernel->db->idleTime = 0;
  108089. + kernel->db->lastIdle = 0;
  108090. + kernel->db->lastSlowdown = 0;
  108091. +
  108092. + for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
  108093. + {
  108094. + kernel->db->db[i] = gcvNULL;
  108095. + }
  108096. +
  108097. + /* Construct a database mutex. */
  108098. + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex));
  108099. +
  108100. + /* Construct a id-pointer database. */
  108101. + gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase));
  108102. +
  108103. + /* Construct a id-pointer database mutex. */
  108104. + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex));
  108105. + }
  108106. + else
  108107. + {
  108108. + kernel->db = SharedDB;
  108109. + kernel->dbCreated = gcvFALSE;
  108110. + }
  108111. +
  108112. + for (i = 0; i < gcmCOUNTOF(kernel->timers); ++i)
  108113. + {
  108114. + kernel->timers[i].startTime = 0;
  108115. + kernel->timers[i].stopTime = 0;
  108116. + }
  108117. +
  108118. + kernel->timeOut = gcdGPU_TIMEOUT;
  108119. +
  108120. + /* Save context. */
  108121. + kernel->context = Context;
  108122. +
  108123. +#if gcdVIRTUAL_COMMAND_BUFFER
  108124. + kernel->virtualBufferHead =
  108125. + kernel->virtualBufferTail = gcvNULL;
  108126. +
  108127. + gcmkONERROR(
  108128. + gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
  108129. +#endif
  108130. +
  108131. + /* Construct atom holding number of clients. */
  108132. + kernel->atomClients = gcvNULL;
  108133. + gcmkONERROR(gckOS_AtomConstruct(Os, &kernel->atomClients));
  108134. +
  108135. +#if gcdENABLE_VG
  108136. + kernel->vg = gcvNULL;
  108137. +
  108138. + if (Core == gcvCORE_VG)
  108139. + {
  108140. + /* Construct the gckMMU object. */
  108141. + gcmkONERROR(
  108142. + gckVGKERNEL_Construct(Os, Context, kernel, &kernel->vg));
  108143. + }
  108144. + else
  108145. +#endif
  108146. + {
  108147. + /* Construct the gckHARDWARE object. */
  108148. + gcmkONERROR(
  108149. + gckHARDWARE_Construct(Os, kernel->core, &kernel->hardware));
  108150. +
  108151. + /* Set pointer to gckKERNEL object in gckHARDWARE object. */
  108152. + kernel->hardware->kernel = kernel;
  108153. +
  108154. + /* Initialize the hardware. */
  108155. + gcmkONERROR(
  108156. + gckHARDWARE_InitializeHardware(kernel->hardware));
  108157. +
  108158. + /* Construct the gckCOMMAND object. */
  108159. + gcmkONERROR(
  108160. + gckCOMMAND_Construct(kernel, &kernel->command));
  108161. +
  108162. + /* Construct the gckEVENT object. */
  108163. + gcmkONERROR(
  108164. + gckEVENT_Construct(kernel, &kernel->eventObj));
  108165. +
  108166. + /* Construct the gckMMU object. */
  108167. + gcmkONERROR(
  108168. + gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
  108169. +
  108170. +#if gcdENABLE_RECOVERY
  108171. + gcmkONERROR(
  108172. + gckOS_AtomConstruct(Os, &kernel->resetAtom));
  108173. +
  108174. + gcmkVERIFY_OK(
  108175. + gckOS_CreateTimer(Os,
  108176. + (gctTIMERFUNCTION)_ResetFinishFunction,
  108177. + (gctPOINTER)kernel,
  108178. + &kernel->resetFlagClearTimer));
  108179. + kernel->resetTimeStamp = 0;
  108180. +#endif
  108181. +
  108182. +#if gcdDVFS
  108183. + if (gckHARDWARE_IsFeatureAvailable(kernel->hardware,
  108184. + gcvFEATURE_DYNAMIC_FREQUENCY_SCALING))
  108185. + {
  108186. + gcmkONERROR(gckDVFS_Construct(kernel->hardware, &kernel->dvfs));
  108187. + gcmkONERROR(gckDVFS_Start(kernel->dvfs));
  108188. + }
  108189. +#endif
  108190. + }
  108191. +
  108192. + spin_lock_init(&kernel->irq_lock);
  108193. +
  108194. +#if VIVANTE_PROFILER
  108195. + /* Initialize profile setting */
  108196. + kernel->profileEnable = gcvFALSE;
  108197. + kernel->profileCleanRegister = gcvTRUE;
  108198. +#endif
  108199. +
  108200. +#if gcdANDROID_NATIVE_FENCE_SYNC
  108201. + gcmkONERROR(gckOS_CreateSyncTimeline(Os, &kernel->timeline));
  108202. +#endif
  108203. +
  108204. + /* Return pointer to the gckKERNEL object. */
  108205. + *Kernel = kernel;
  108206. +
  108207. + /* Success. */
  108208. + gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
  108209. + return gcvSTATUS_OK;
  108210. +
  108211. +OnError:
  108212. + if (kernel != gcvNULL)
  108213. + {
  108214. +#if gcdENABLE_VG
  108215. + if (Core != gcvCORE_VG)
  108216. +#endif
  108217. + {
  108218. + if (kernel->eventObj != gcvNULL)
  108219. + {
  108220. + gcmkVERIFY_OK(gckEVENT_Destroy(kernel->eventObj));
  108221. + }
  108222. +
  108223. + if (kernel->command != gcvNULL)
  108224. + {
  108225. + gcmkVERIFY_OK(gckCOMMAND_Destroy(kernel->command));
  108226. + }
  108227. +
  108228. + if (kernel->hardware != gcvNULL)
  108229. + {
  108230. + /* Turn off the power. */
  108231. + gcmkVERIFY_OK(gckOS_SetGPUPower(kernel->hardware->os,
  108232. + kernel->hardware->core,
  108233. + gcvFALSE,
  108234. + gcvFALSE));
  108235. + gcmkVERIFY_OK(gckHARDWARE_Destroy(kernel->hardware));
  108236. + }
  108237. + }
  108238. +
  108239. + if (kernel->atomClients != gcvNULL)
  108240. + {
  108241. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients));
  108242. + }
  108243. +
  108244. +#if gcdENABLE_RECOVERY
  108245. + if (kernel->resetAtom != gcvNULL)
  108246. + {
  108247. + gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->resetAtom));
  108248. + }
  108249. +
  108250. + if (kernel->resetFlagClearTimer)
  108251. + {
  108252. + gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer));
  108253. + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->resetFlagClearTimer));
  108254. + }
  108255. +#endif
  108256. +
  108257. + if (kernel->dbCreated && kernel->db != gcvNULL)
  108258. + {
  108259. + if (kernel->db->dbMutex != gcvNULL)
  108260. + {
  108261. + /* Destroy the database mutex. */
  108262. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->db->dbMutex));
  108263. + }
  108264. +
  108265. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel->db));
  108266. + }
  108267. +
  108268. +#if gcdVIRTUAL_COMMAND_BUFFER
  108269. + if (kernel->virtualBufferLock != gcvNULL)
  108270. + {
  108271. + /* Destroy the virtual command buffer mutex. */
  108272. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, kernel->virtualBufferLock));
  108273. + }
  108274. +#endif
  108275. +
  108276. +#if gcdDVFS
  108277. + if (kernel->dvfs)
  108278. + {
  108279. + gcmkVERIFY_OK(gckDVFS_Stop(kernel->dvfs));
  108280. + gcmkVERIFY_OK(gckDVFS_Destroy(kernel->dvfs));
  108281. + }
  108282. +#endif
  108283. +
  108284. +#if gcdANDROID_NATIVE_FENCE_SYNC
  108285. + if (kernel->timeline)
  108286. + {
  108287. + gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Os, kernel->timeline));
  108288. + }
  108289. +#endif
  108290. +
  108291. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel));
  108292. + }
  108293. +
  108294. + /* Return the error. */
  108295. + gcmkFOOTER();
  108296. + return status;
  108297. +}
  108298. +
  108299. +/*******************************************************************************
  108300. +**
  108301. +** gckKERNEL_Destroy
  108302. +**
  108303. +** Destroy an gckKERNEL object.
  108304. +**
  108305. +** INPUT:
  108306. +**
  108307. +** gckKERNEL Kernel
  108308. +** Pointer to an gckKERNEL object to destroy.
  108309. +**
  108310. +** OUTPUT:
  108311. +**
  108312. +** Nothing.
  108313. +*/
  108314. +gceSTATUS
  108315. +gckKERNEL_Destroy(
  108316. + IN gckKERNEL Kernel
  108317. + )
  108318. +{
  108319. + gctSIZE_T i;
  108320. + gcsDATABASE_PTR database, databaseNext;
  108321. + gcsDATABASE_RECORD_PTR record, recordNext;
  108322. +
  108323. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  108324. +
  108325. + /* Verify the arguments. */
  108326. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108327. +#if QNX_SINGLE_THREADED_DEBUGGING
  108328. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->debugMutex));
  108329. +#endif
  108330. +
  108331. + /* Destroy the database. */
  108332. + if (Kernel->dbCreated)
  108333. + {
  108334. + for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
  108335. + {
  108336. + if (Kernel->db->db[i] != gcvNULL)
  108337. + {
  108338. + gcmkVERIFY_OK(
  108339. + gckKERNEL_DestroyProcessDB(Kernel, Kernel->db->db[i]->processID));
  108340. + }
  108341. + }
  108342. +
  108343. + /* Free all databases. */
  108344. + for (database = Kernel->db->freeDatabase;
  108345. + database != gcvNULL;
  108346. + database = databaseNext)
  108347. + {
  108348. + databaseNext = database->next;
  108349. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, database));
  108350. + }
  108351. +
  108352. + if (Kernel->db->lastDatabase != gcvNULL)
  108353. + {
  108354. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db->lastDatabase));
  108355. + }
  108356. +
  108357. + /* Free all database records. */
  108358. + for (record = Kernel->db->freeRecord; record != gcvNULL; record = recordNext)
  108359. + {
  108360. + recordNext = record->next;
  108361. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
  108362. + }
  108363. +
  108364. + /* Destroy the database mutex. */
  108365. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->dbMutex));
  108366. +
  108367. +
  108368. + /* Destroy id-pointer database. */
  108369. + gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase));
  108370. +
  108371. + /* Destroy id-pointer database mutex. */
  108372. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
  108373. + }
  108374. +
  108375. +#if gcdENABLE_VG
  108376. + if (Kernel->vg)
  108377. + {
  108378. + gcmkVERIFY_OK(gckVGKERNEL_Destroy(Kernel->vg));
  108379. + }
  108380. + else
  108381. +#endif
  108382. + {
  108383. + /* Destroy the gckMMU object. */
  108384. + gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
  108385. +
  108386. + /* Destroy the gckCOMMNAND object. */
  108387. + gcmkVERIFY_OK(gckCOMMAND_Destroy(Kernel->command));
  108388. +
  108389. + /* Destroy the gckEVENT object. */
  108390. + gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->eventObj));
  108391. +
  108392. + /* Destroy the gckHARDWARE object. */
  108393. + gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
  108394. +
  108395. +#if gcdENABLE_RECOVERY
  108396. + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->resetAtom));
  108397. +
  108398. + if (Kernel->resetFlagClearTimer)
  108399. + {
  108400. + gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer));
  108401. + gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->resetFlagClearTimer));
  108402. + }
  108403. +#endif
  108404. + }
  108405. +
  108406. + /* Detsroy the client atom. */
  108407. + gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
  108408. +
  108409. +#if gcdVIRTUAL_COMMAND_BUFFER
  108410. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock));
  108411. +#endif
  108412. +
  108413. +#if gcdDVFS
  108414. + if (Kernel->dvfs)
  108415. + {
  108416. + gcmkVERIFY_OK(gckDVFS_Stop(Kernel->dvfs));
  108417. + gcmkVERIFY_OK(gckDVFS_Destroy(Kernel->dvfs));
  108418. + }
  108419. +#endif
  108420. +
  108421. +#if gcdANDROID_NATIVE_FENCE_SYNC
  108422. + gcmkVERIFY_OK(gckOS_DestroySyncTimeline(Kernel->os, Kernel->timeline));
  108423. +#endif
  108424. +
  108425. + /* Mark the gckKERNEL object as unknown. */
  108426. + Kernel->object.type = gcvOBJ_UNKNOWN;
  108427. +
  108428. + /* Free the gckKERNEL object. */
  108429. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel));
  108430. +
  108431. + /* Success. */
  108432. + gcmkFOOTER_NO();
  108433. + return gcvSTATUS_OK;
  108434. +}
  108435. +
  108436. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  108437. +#include <linux/kernel.h>
  108438. +#include <linux/mm.h>
  108439. +#include <linux/oom.h>
  108440. +#include <linux/sched.h>
  108441. +#include <linux/notifier.h>
  108442. +
  108443. +extern struct task_struct *lowmem_deathpending;
  108444. +static unsigned long lowmem_deathpending_timeout;
  108445. +
  108446. +static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
  108447. +{
  108448. + struct task_struct *p;
  108449. + struct task_struct *selected = NULL;
  108450. + int tasksize;
  108451. + int ret = -1;
  108452. + int min_adj = 0;
  108453. + int selected_tasksize = 0;
  108454. + int selected_oom_adj;
  108455. + /*
  108456. + * If we already have a death outstanding, then
  108457. + * bail out right away; indicating to vmscan
  108458. + * that we have nothing further to offer on
  108459. + * this pass.
  108460. + *
  108461. + */
  108462. + if (lowmem_deathpending &&
  108463. + time_before_eq(jiffies, lowmem_deathpending_timeout))
  108464. + return 0;
  108465. + selected_oom_adj = min_adj;
  108466. +
  108467. + read_lock(&tasklist_lock);
  108468. + for_each_process(p) {
  108469. + struct mm_struct *mm;
  108470. + struct signal_struct *sig;
  108471. + gcuDATABASE_INFO info;
  108472. + int oom_adj;
  108473. +
  108474. + task_lock(p);
  108475. + mm = p->mm;
  108476. + sig = p->signal;
  108477. + if (!mm || !sig) {
  108478. + task_unlock(p);
  108479. + continue;
  108480. + }
  108481. + oom_adj = sig->oom_adj;
  108482. + if (oom_adj < min_adj) {
  108483. + task_unlock(p);
  108484. + continue;
  108485. + }
  108486. +
  108487. + tasksize = 0;
  108488. + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
  108489. + tasksize += info.counters.bytes / PAGE_SIZE;
  108490. + }
  108491. + if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
  108492. + tasksize += info.counters.bytes / PAGE_SIZE;
  108493. + }
  108494. +
  108495. + task_unlock(p);
  108496. +
  108497. + if (tasksize <= 0)
  108498. + continue;
  108499. +
  108500. + gckOS_Print("<gpu> pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize);
  108501. +
  108502. + if (selected) {
  108503. + if (oom_adj < selected_oom_adj)
  108504. + continue;
  108505. + if (oom_adj == selected_oom_adj &&
  108506. + tasksize <= selected_tasksize)
  108507. + continue;
  108508. + }
  108509. + selected = p;
  108510. + selected_tasksize = tasksize;
  108511. + selected_oom_adj = oom_adj;
  108512. + }
  108513. + if (selected) {
  108514. + gckOS_Print("<gpu> send sigkill to %d (%s), adj %d, size %d\n",
  108515. + selected->pid, selected->comm,
  108516. + selected_oom_adj, selected_tasksize);
  108517. + lowmem_deathpending = selected;
  108518. + lowmem_deathpending_timeout = jiffies + HZ;
  108519. + force_sig(SIGKILL, selected);
  108520. + ret = 0;
  108521. + }
  108522. + read_unlock(&tasklist_lock);
  108523. + return ret;
  108524. +}
  108525. +
  108526. +#endif
  108527. +
  108528. +/*******************************************************************************
  108529. +**
  108530. +** _AllocateMemory
  108531. +**
  108532. +** Private function to walk all required memory pools to allocate the requested
  108533. +** amount of video memory.
  108534. +**
  108535. +** INPUT:
  108536. +**
  108537. +** gckKERNEL Kernel
  108538. +** Pointer to an gckKERNEL object.
  108539. +**
  108540. +** gcsHAL_INTERFACE * Interface
  108541. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  108542. +** be dispatched.
  108543. +**
  108544. +** OUTPUT:
  108545. +**
  108546. +** gcsHAL_INTERFACE * Interface
  108547. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  108548. +** returned.
  108549. +*/
  108550. +static gceSTATUS
  108551. +_AllocateMemory(
  108552. + IN gckKERNEL Kernel,
  108553. + IN OUT gcePOOL * Pool,
  108554. + IN gctSIZE_T Bytes,
  108555. + IN gctSIZE_T Alignment,
  108556. + IN gceSURF_TYPE Type,
  108557. + OUT gcuVIDMEM_NODE_PTR * Node
  108558. + )
  108559. +{
  108560. + gcePOOL pool;
  108561. + gceSTATUS status;
  108562. + gckVIDMEM videoMemory;
  108563. + gctINT loopCount;
  108564. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  108565. + gctBOOL tileStatusInVirtual;
  108566. + gctBOOL forceContiguous = gcvFALSE;
  108567. +
  108568. + gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d",
  108569. + Kernel, *Pool, Bytes, Alignment, Type);
  108570. +
  108571. + gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
  108572. + gcmkVERIFY_ARGUMENT(Bytes != 0);
  108573. +
  108574. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  108575. +_AllocateMemory_Retry:
  108576. +#endif
  108577. + /* Get initial pool. */
  108578. + switch (pool = *Pool)
  108579. + {
  108580. + case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS:
  108581. + forceContiguous = gcvTRUE;
  108582. + case gcvPOOL_DEFAULT:
  108583. + case gcvPOOL_LOCAL:
  108584. + pool = gcvPOOL_LOCAL_INTERNAL;
  108585. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  108586. + break;
  108587. +
  108588. + case gcvPOOL_UNIFIED:
  108589. + pool = gcvPOOL_SYSTEM;
  108590. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  108591. + break;
  108592. +
  108593. + case gcvPOOL_CONTIGUOUS:
  108594. + loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
  108595. + break;
  108596. +
  108597. + case gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE:
  108598. + pool = gcvPOOL_CONTIGUOUS;
  108599. + loopCount = 1;
  108600. + forceContiguous = gcvTRUE;
  108601. + break;
  108602. +
  108603. + default:
  108604. + loopCount = 1;
  108605. + break;
  108606. + }
  108607. +
  108608. + while (loopCount-- > 0)
  108609. + {
  108610. + if (pool == gcvPOOL_VIRTUAL)
  108611. + {
  108612. + /* Create a gcuVIDMEM_NODE for virtual memory. */
  108613. + gcmkONERROR(
  108614. + gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, &node));
  108615. +
  108616. + /* Success. */
  108617. + break;
  108618. + }
  108619. +
  108620. + else
  108621. + if (pool == gcvPOOL_CONTIGUOUS)
  108622. + {
  108623. +#if gcdCONTIGUOUS_SIZE_LIMIT
  108624. + if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && forceContiguous == gcvFALSE)
  108625. + {
  108626. + status = gcvSTATUS_OUT_OF_MEMORY;
  108627. + }
  108628. + else
  108629. +#endif
  108630. + {
  108631. + /* Create a gcuVIDMEM_NODE from contiguous memory. */
  108632. + status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, &node);
  108633. + }
  108634. +
  108635. + if (gcmIS_SUCCESS(status) || forceContiguous == gcvTRUE)
  108636. + {
  108637. + /* Memory allocated. */
  108638. + if(node && forceContiguous == gcvTRUE)
  108639. + {
  108640. + gctUINT32 physAddr=0;
  108641. + gctUINT32 baseAddress = 0;
  108642. +
  108643. + gcmkONERROR(
  108644. + gckOS_LockPages(Kernel->os,
  108645. + node->Virtual.physical,
  108646. + node->Virtual.bytes,
  108647. + gcvFALSE,
  108648. + &node->Virtual.logical,
  108649. + &node->Virtual.pageCount));
  108650. +
  108651. + /* Convert logical address into a physical address. */
  108652. + gcmkONERROR(
  108653. + gckOS_GetPhysicalAddress(Kernel->os,
  108654. + node->Virtual.logical,
  108655. + &physAddr));
  108656. +
  108657. + gcmkONERROR(
  108658. + gckOS_UnlockPages(Kernel->os,
  108659. + node->Virtual.physical,
  108660. + node->Virtual.bytes,
  108661. + node->Virtual.logical));
  108662. +
  108663. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  108664. +
  108665. + gcmkASSERT(physAddr >= baseAddress);
  108666. +
  108667. + /* Subtract baseAddress to get a GPU address used for programming. */
  108668. + physAddr -= baseAddress;
  108669. +
  108670. + if((physAddr & 0x80000000) || ((physAddr + Bytes) & 0x80000000))
  108671. + {
  108672. + gckOS_Print("gpu virtual memory 0x%x cannot be allocated in force contiguous request!\n", physAddr);
  108673. +
  108674. + gcmkONERROR(gckVIDMEM_Free(node));
  108675. +
  108676. + node = gcvNULL;
  108677. + }
  108678. + }
  108679. +
  108680. + break;
  108681. + }
  108682. + }
  108683. +
  108684. + else
  108685. + {
  108686. + /* Get pointer to gckVIDMEM object for pool. */
  108687. +#if gcdUSE_VIDMEM_PER_PID
  108688. + gctUINT32 pid;
  108689. + gckOS_GetProcessID(&pid);
  108690. +
  108691. + status = gckKERNEL_GetVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
  108692. + if (status == gcvSTATUS_NOT_FOUND)
  108693. + {
  108694. + /* Create VidMem pool for this process. */
  108695. + status = gckKERNEL_CreateVideoMemoryPoolPid(Kernel, pool, pid, &videoMemory);
  108696. + }
  108697. +#else
  108698. + status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
  108699. +#endif
  108700. +
  108701. + if (gcmIS_SUCCESS(status))
  108702. + {
  108703. + /* Allocate memory. */
  108704. + status = gckVIDMEM_AllocateLinear(videoMemory,
  108705. + Bytes,
  108706. + Alignment,
  108707. + Type,
  108708. + &node);
  108709. +
  108710. + if (gcmIS_SUCCESS(status))
  108711. + {
  108712. + /* Memory allocated. */
  108713. + node->VidMem.pool = pool;
  108714. + break;
  108715. + }
  108716. + }
  108717. + }
  108718. +
  108719. + if (pool == gcvPOOL_LOCAL_INTERNAL)
  108720. + {
  108721. + /* Advance to external memory. */
  108722. + pool = gcvPOOL_LOCAL_EXTERNAL;
  108723. + }
  108724. +
  108725. + else
  108726. + if (pool == gcvPOOL_LOCAL_EXTERNAL)
  108727. + {
  108728. + /* Advance to contiguous system memory. */
  108729. + pool = gcvPOOL_SYSTEM;
  108730. + }
  108731. +
  108732. + else
  108733. + if (pool == gcvPOOL_SYSTEM)
  108734. + {
  108735. + /* Advance to contiguous memory. */
  108736. + pool = gcvPOOL_CONTIGUOUS;
  108737. + }
  108738. +
  108739. + else
  108740. + if (pool == gcvPOOL_CONTIGUOUS)
  108741. + {
  108742. + tileStatusInVirtual =
  108743. + gckHARDWARE_IsFeatureAvailable(Kernel->hardware,
  108744. + gcvFEATURE_MC20);
  108745. +
  108746. + if (Type == gcvSURF_TILE_STATUS && tileStatusInVirtual != gcvTRUE)
  108747. + {
  108748. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  108749. + }
  108750. +
  108751. + /* Advance to virtual memory. */
  108752. + pool = gcvPOOL_VIRTUAL;
  108753. + }
  108754. +
  108755. + else
  108756. + {
  108757. + /* Out of pools. */
  108758. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  108759. + }
  108760. + }
  108761. +
  108762. + if (node == gcvNULL)
  108763. + {
  108764. +
  108765. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  108766. + if(forceContiguous == gcvTRUE)
  108767. + {
  108768. + if(force_contiguous_lowmem_shrink(Kernel) == 0)
  108769. + {
  108770. + /* Sleep 1 millisecond. */
  108771. + gckOS_Delay(gcvNULL, 1);
  108772. + goto _AllocateMemory_Retry;
  108773. + }
  108774. + }
  108775. +#endif
  108776. + /* Nothing allocated. */
  108777. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  108778. + }
  108779. +
  108780. + /* Return node and pool used for allocation. */
  108781. + *Node = node;
  108782. + *Pool = pool;
  108783. +
  108784. + /* Return status. */
  108785. + gcmkFOOTER_ARG("*Pool=%d *Node=0x%x", *Pool, *Node);
  108786. + return gcvSTATUS_OK;
  108787. +
  108788. +OnError:
  108789. + /* Return the status. */
  108790. + gcmkFOOTER();
  108791. + return status;
  108792. +}
  108793. +
  108794. +/*******************************************************************************
  108795. +**
  108796. +** gckKERNEL_Dispatch
  108797. +**
  108798. +** Dispatch a command received from the user HAL layer.
  108799. +**
  108800. +** INPUT:
  108801. +**
  108802. +** gckKERNEL Kernel
  108803. +** Pointer to an gckKERNEL object.
  108804. +**
  108805. +** gctBOOL FromUser
  108806. +** whether the call is from the user space.
  108807. +**
  108808. +** gcsHAL_INTERFACE * Interface
  108809. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  108810. +** be dispatched.
  108811. +**
  108812. +** OUTPUT:
  108813. +**
  108814. +** gcsHAL_INTERFACE * Interface
  108815. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  108816. +** returned.
  108817. +*/
  108818. +
  108819. +gceSTATUS
  108820. +gckKERNEL_Dispatch(
  108821. + IN gckKERNEL Kernel,
  108822. + IN gctBOOL FromUser,
  108823. + IN OUT gcsHAL_INTERFACE * Interface
  108824. + )
  108825. +{
  108826. + gceSTATUS status = gcvSTATUS_OK;
  108827. + gctSIZE_T bytes;
  108828. + gcuVIDMEM_NODE_PTR node;
  108829. + gctBOOL locked = gcvFALSE;
  108830. + gctPHYS_ADDR physical = gcvNULL;
  108831. + gctPOINTER logical = gcvNULL;
  108832. + gctPOINTER info = gcvNULL;
  108833. + gckCONTEXT context = gcvNULL;
  108834. + gctUINT32 address;
  108835. + gctUINT32 processID;
  108836. + gckKERNEL kernel = Kernel;
  108837. +#if gcdSECURE_USER
  108838. + gcskSECURE_CACHE_PTR cache;
  108839. +#endif
  108840. + gctBOOL asynchronous;
  108841. + gctPOINTER paddr = gcvNULL;
  108842. +#if !USE_NEW_LINUX_SIGNAL
  108843. + gctSIGNAL signal;
  108844. +#endif
  108845. + gceSURF_TYPE type;
  108846. +
  108847. + gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
  108848. + Kernel, FromUser, Interface);
  108849. +
  108850. + /* Verify the arguments. */
  108851. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  108852. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  108853. +
  108854. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  108855. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  108856. + "Dispatching command %d (%s)",
  108857. + Interface->command, _DispatchText[Interface->command]);
  108858. +#endif
  108859. +#if QNX_SINGLE_THREADED_DEBUGGING
  108860. + gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE);
  108861. +#endif
  108862. +
  108863. + /* Get the current process ID. */
  108864. + gcmkONERROR(gckOS_GetProcessID(&processID));
  108865. +
  108866. +#if gcdSECURE_USER
  108867. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
  108868. +#endif
  108869. +
  108870. + /* Dispatch on command. */
  108871. + switch (Interface->command)
  108872. + {
  108873. + case gcvHAL_GET_BASE_ADDRESS:
  108874. + /* Get base address. */
  108875. + gcmkONERROR(
  108876. + gckOS_GetBaseAddress(Kernel->os,
  108877. + &Interface->u.GetBaseAddress.baseAddress));
  108878. + break;
  108879. +
  108880. + case gcvHAL_QUERY_VIDEO_MEMORY:
  108881. + /* Query video memory size. */
  108882. + gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface));
  108883. + break;
  108884. +
  108885. + case gcvHAL_QUERY_CHIP_IDENTITY:
  108886. + /* Query chip identity. */
  108887. + gcmkONERROR(
  108888. + gckHARDWARE_QueryChipIdentity(
  108889. + Kernel->hardware,
  108890. + &Interface->u.QueryChipIdentity));
  108891. + break;
  108892. +
  108893. + case gcvHAL_MAP_MEMORY:
  108894. + physical = gcmINT2PTR(Interface->u.MapMemory.physical);
  108895. +
  108896. + /* Map memory. */
  108897. + gcmkONERROR(
  108898. + gckKERNEL_MapMemory(Kernel,
  108899. + physical,
  108900. + (gctSIZE_T) Interface->u.MapMemory.bytes,
  108901. + &logical));
  108902. +
  108903. + Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
  108904. +
  108905. + gcmkVERIFY_OK(
  108906. + gckKERNEL_AddProcessDB(Kernel,
  108907. + processID, gcvDB_MAP_MEMORY,
  108908. + logical,
  108909. + physical,
  108910. + (gctSIZE_T) Interface->u.MapMemory.bytes));
  108911. + break;
  108912. +
  108913. + case gcvHAL_UNMAP_MEMORY:
  108914. + physical = gcmINT2PTR(Interface->u.UnmapMemory.physical);
  108915. +
  108916. + /* Unmap memory. */
  108917. + gcmkONERROR(
  108918. + gckKERNEL_UnmapMemory(Kernel,
  108919. + physical,
  108920. + (gctSIZE_T) Interface->u.UnmapMemory.bytes,
  108921. + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
  108922. + gcmkVERIFY_OK(
  108923. + gckKERNEL_RemoveProcessDB(Kernel,
  108924. + processID, gcvDB_MAP_MEMORY,
  108925. + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical)));
  108926. + break;
  108927. +
  108928. + case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
  108929. + bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes;
  108930. +
  108931. + /* Allocate non-paged memory. */
  108932. + gcmkONERROR(
  108933. + gckOS_AllocateNonPagedMemory(
  108934. + Kernel->os,
  108935. + FromUser,
  108936. + &bytes,
  108937. + &physical,
  108938. + &logical));
  108939. +
  108940. + Interface->u.AllocateNonPagedMemory.bytes = bytes;
  108941. + Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  108942. + Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  108943. +
  108944. + gcmkVERIFY_OK(
  108945. + gckKERNEL_AddProcessDB(Kernel,
  108946. + processID, gcvDB_NON_PAGED,
  108947. + logical,
  108948. + gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical),
  108949. + bytes));
  108950. +
  108951. + break;
  108952. +
  108953. + case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
  108954. +#if gcdVIRTUAL_COMMAND_BUFFER
  108955. + bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes;
  108956. +
  108957. + gcmkONERROR(
  108958. + gckKERNEL_AllocateVirtualCommandBuffer(
  108959. + Kernel,
  108960. + FromUser,
  108961. + &bytes,
  108962. + &physical,
  108963. + &logical));
  108964. +
  108965. + Interface->u.AllocateVirtualCommandBuffer.bytes = bytes;
  108966. + Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical);
  108967. + Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical);
  108968. +
  108969. + gcmkVERIFY_OK(
  108970. + gckKERNEL_AddProcessDB(Kernel,
  108971. + processID, gcvDB_COMMAND_BUFFER,
  108972. + logical,
  108973. + gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical),
  108974. + bytes));
  108975. +#else
  108976. + status = gcvSTATUS_NOT_SUPPORTED;
  108977. +#endif
  108978. + break;
  108979. +
  108980. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  108981. + physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical);
  108982. +
  108983. + /* Unmap user logical out of physical memory first. */
  108984. + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
  108985. + physical,
  108986. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  108987. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  108988. +
  108989. + /* Free non-paged memory. */
  108990. + gcmkONERROR(
  108991. + gckOS_FreeNonPagedMemory(Kernel->os,
  108992. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  108993. + physical,
  108994. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  108995. +
  108996. + gcmkVERIFY_OK(
  108997. + gckKERNEL_RemoveProcessDB(Kernel,
  108998. + processID, gcvDB_NON_PAGED,
  108999. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  109000. +
  109001. +#if gcdSECURE_USER
  109002. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  109003. + Kernel,
  109004. + cache,
  109005. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
  109006. + Interface->u.FreeNonPagedMemory.bytes));
  109007. +#endif
  109008. +
  109009. + gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical);
  109010. +
  109011. + break;
  109012. +
  109013. + case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
  109014. + bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes;
  109015. +
  109016. + /* Allocate contiguous memory. */
  109017. + gcmkONERROR(gckOS_AllocateContiguous(
  109018. + Kernel->os,
  109019. + FromUser,
  109020. + &bytes,
  109021. + &physical,
  109022. + &logical));
  109023. +
  109024. + Interface->u.AllocateContiguousMemory.bytes = bytes;
  109025. + Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical);
  109026. + Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
  109027. +
  109028. + gcmkONERROR(gckHARDWARE_ConvertLogical(
  109029. + Kernel->hardware,
  109030. + gcmUINT64_TO_PTR(Interface->u.AllocateContiguousMemory.logical),
  109031. + &Interface->u.AllocateContiguousMemory.address));
  109032. +
  109033. + gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
  109034. + Kernel,
  109035. + processID, gcvDB_CONTIGUOUS,
  109036. + logical,
  109037. + gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical),
  109038. + bytes));
  109039. +
  109040. + break;
  109041. +
  109042. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  109043. + physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical);
  109044. +
  109045. + /* Unmap user logical out of physical memory first. */
  109046. + gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
  109047. + physical,
  109048. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
  109049. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
  109050. +
  109051. + /* Free contiguous memory. */
  109052. + gcmkONERROR(
  109053. + gckOS_FreeContiguous(Kernel->os,
  109054. + physical,
  109055. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
  109056. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
  109057. +
  109058. + gcmkVERIFY_OK(
  109059. + gckKERNEL_RemoveProcessDB(Kernel,
  109060. + processID, gcvDB_CONTIGUOUS,
  109061. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  109062. +
  109063. +#if gcdSECURE_USER
  109064. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  109065. + Kernel,
  109066. + cache,
  109067. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
  109068. + Interface->u.FreeContiguousMemory.bytes));
  109069. +#endif
  109070. +
  109071. + gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical);
  109072. +
  109073. + break;
  109074. +
  109075. + case gcvHAL_ALLOCATE_VIDEO_MEMORY:
  109076. +
  109077. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  109078. +
  109079. + break;
  109080. +
  109081. + case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
  109082. + type = Interface->u.AllocateLinearVideoMemory.type;
  109083. +
  109084. + /* Allocate memory. */
  109085. + gcmkONERROR(
  109086. + _AllocateMemory(Kernel,
  109087. + &Interface->u.AllocateLinearVideoMemory.pool,
  109088. + Interface->u.AllocateLinearVideoMemory.bytes,
  109089. + Interface->u.AllocateLinearVideoMemory.alignment,
  109090. + Interface->u.AllocateLinearVideoMemory.type,
  109091. + &node));
  109092. +
  109093. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  109094. + {
  109095. + bytes = node->VidMem.bytes;
  109096. + node->VidMem.type = type;
  109097. +
  109098. + gcmkONERROR(
  109099. + gckKERNEL_AddProcessDB(Kernel,
  109100. + processID, gcvDB_VIDEO_MEMORY_RESERVED,
  109101. + node,
  109102. + gcvNULL,
  109103. + bytes));
  109104. + }
  109105. + else
  109106. + {
  109107. + bytes = node->Virtual.bytes;
  109108. + node->Virtual.type = type;
  109109. +
  109110. + if(node->Virtual.contiguous)
  109111. + {
  109112. + gcmkONERROR(
  109113. + gckKERNEL_AddProcessDB(Kernel,
  109114. + processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  109115. + node,
  109116. + gcvNULL,
  109117. + bytes));
  109118. + }
  109119. + else
  109120. + {
  109121. + gcmkONERROR(
  109122. + gckKERNEL_AddProcessDB(Kernel,
  109123. + processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
  109124. + node,
  109125. + gcvNULL,
  109126. + bytes));
  109127. + }
  109128. +
  109129. + }
  109130. +
  109131. + gcmkONERROR(
  109132. + gckKERNEL_AddProcessDB(Kernel,
  109133. + processID, gcvDB_VIDEO_MEMORY,
  109134. + node,
  109135. + gcvNULL,
  109136. + bytes));
  109137. +
  109138. + /* Get the node. */
  109139. + Interface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
  109140. + break;
  109141. +
  109142. + case gcvHAL_FREE_VIDEO_MEMORY:
  109143. + node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
  109144. +#ifdef __QNXNTO__
  109145. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM
  109146. + && node->VidMem.logical != gcvNULL)
  109147. + {
  109148. + gcmkONERROR(
  109149. + gckKERNEL_UnmapVideoMemory(Kernel,
  109150. + node->VidMem.logical,
  109151. + processID,
  109152. + node->VidMem.bytes));
  109153. + node->VidMem.logical = gcvNULL;
  109154. + }
  109155. +#endif
  109156. + /* Free video memory. */
  109157. + gcmkONERROR(
  109158. + gckVIDMEM_Free(node));
  109159. +
  109160. + gcmkONERROR(
  109161. + gckKERNEL_RemoveProcessDB(Kernel,
  109162. + processID, gcvDB_VIDEO_MEMORY,
  109163. + node));
  109164. +
  109165. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  109166. + {
  109167. + gcmkONERROR(
  109168. + gckKERNEL_RemoveProcessDB(Kernel,
  109169. + processID, gcvDB_VIDEO_MEMORY_RESERVED,
  109170. + node));
  109171. + }
  109172. + else if(node->Virtual.contiguous)
  109173. + {
  109174. + gcmkONERROR(
  109175. + gckKERNEL_RemoveProcessDB(Kernel,
  109176. + processID, gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  109177. + node));
  109178. + }
  109179. + else
  109180. + {
  109181. + gcmkONERROR(
  109182. + gckKERNEL_RemoveProcessDB(Kernel,
  109183. + processID, gcvDB_VIDEO_MEMORY_VIRTUAL,
  109184. + node));
  109185. + }
  109186. +
  109187. + break;
  109188. +
  109189. + case gcvHAL_LOCK_VIDEO_MEMORY:
  109190. + node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
  109191. +
  109192. + /* Lock video memory. */
  109193. + gcmkONERROR(
  109194. + gckVIDMEM_Lock(Kernel,
  109195. + node,
  109196. + Interface->u.LockVideoMemory.cacheable,
  109197. + &Interface->u.LockVideoMemory.address));
  109198. +
  109199. + locked = gcvTRUE;
  109200. +
  109201. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  109202. + {
  109203. + /* Map video memory address into user space. */
  109204. +#ifdef __QNXNTO__
  109205. + if (node->VidMem.logical == gcvNULL)
  109206. + {
  109207. + gcmkONERROR(
  109208. + gckKERNEL_MapVideoMemory(Kernel,
  109209. + FromUser,
  109210. + Interface->u.LockVideoMemory.address,
  109211. + processID,
  109212. + node->VidMem.bytes,
  109213. + &node->VidMem.logical));
  109214. + }
  109215. + gcmkASSERT(node->VidMem.logical != gcvNULL);
  109216. +
  109217. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
  109218. +#else
  109219. + gcmkONERROR(
  109220. + gckKERNEL_MapVideoMemory(Kernel,
  109221. + FromUser,
  109222. + Interface->u.LockVideoMemory.address,
  109223. + &logical));
  109224. +
  109225. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
  109226. +#endif
  109227. + }
  109228. + else
  109229. + {
  109230. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
  109231. +
  109232. + /* Success. */
  109233. + status = gcvSTATUS_OK;
  109234. + }
  109235. +
  109236. +#if gcdSECURE_USER
  109237. + /* Return logical address as physical address. */
  109238. + Interface->u.LockVideoMemory.address =
  109239. + Interface->u.LockVideoMemory.memory;
  109240. +#endif
  109241. + gcmkONERROR(
  109242. + gckKERNEL_AddProcessDB(Kernel,
  109243. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  109244. + node,
  109245. + gcvNULL,
  109246. + 0));
  109247. +
  109248. + break;
  109249. +
  109250. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  109251. + /* Unlock video memory. */
  109252. + node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
  109253. +
  109254. +#if gcdSECURE_USER
  109255. + /* Save node information before it disappears. */
  109256. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  109257. + {
  109258. + logical = gcvNULL;
  109259. + bytes = 0;
  109260. + }
  109261. + else
  109262. + {
  109263. + logical = node->Virtual.logical;
  109264. + bytes = node->Virtual.bytes;
  109265. + }
  109266. +#endif
  109267. +
  109268. + /* Unlock video memory. */
  109269. + gcmkONERROR(
  109270. + gckVIDMEM_Unlock(Kernel,
  109271. + node,
  109272. + Interface->u.UnlockVideoMemory.type,
  109273. + &Interface->u.UnlockVideoMemory.asynchroneous));
  109274. +
  109275. +#if gcdSECURE_USER
  109276. + /* Flush the translation cache for virtual surfaces. */
  109277. + if (logical != gcvNULL)
  109278. + {
  109279. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
  109280. + cache,
  109281. + logical,
  109282. + bytes));
  109283. + }
  109284. +#endif
  109285. + if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
  109286. + {
  109287. + /* There isn't a event to unlock this node, remove record now */
  109288. + gcmkONERROR(
  109289. + gckKERNEL_RemoveProcessDB(Kernel,
  109290. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  109291. + node));
  109292. + }
  109293. + break;
  109294. +
  109295. + case gcvHAL_EVENT_COMMIT:
  109296. + /* Commit an event queue. */
  109297. + gcmkONERROR(
  109298. + gckEVENT_Commit(Kernel->eventObj,
  109299. + gcmUINT64_TO_PTR(Interface->u.Event.queue)));
  109300. + break;
  109301. +
  109302. + case gcvHAL_COMMIT:
  109303. + /* Commit a command and context buffer. */
  109304. + gcmkONERROR(
  109305. + gckCOMMAND_Commit(Kernel->command,
  109306. + Interface->u.Commit.context ?
  109307. + gcmNAME_TO_PTR(Interface->u.Commit.context) : gcvNULL,
  109308. + gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer),
  109309. + gcmUINT64_TO_PTR(Interface->u.Commit.delta),
  109310. + gcmUINT64_TO_PTR(Interface->u.Commit.queue),
  109311. + processID));
  109312. + break;
  109313. +
  109314. + case gcvHAL_STALL:
  109315. + /* Stall the command queue. */
  109316. + gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE));
  109317. + break;
  109318. +
  109319. + case gcvHAL_MAP_USER_MEMORY:
  109320. + /* Map user memory to DMA. */
  109321. + gcmkONERROR(
  109322. + gckOS_MapUserMemory(Kernel->os,
  109323. + Kernel->core,
  109324. + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory),
  109325. + Interface->u.MapUserMemory.physical,
  109326. + (gctSIZE_T) Interface->u.MapUserMemory.size,
  109327. + &info,
  109328. + &Interface->u.MapUserMemory.address));
  109329. +
  109330. + Interface->u.MapUserMemory.info = gcmPTR_TO_NAME(info);
  109331. +
  109332. + gcmkVERIFY_OK(
  109333. + gckKERNEL_AddProcessDB(Kernel,
  109334. + processID, gcvDB_MAP_USER_MEMORY,
  109335. + gcmINT2PTR(Interface->u.MapUserMemory.info),
  109336. + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory),
  109337. + (gctSIZE_T) Interface->u.MapUserMemory.size));
  109338. + break;
  109339. +
  109340. + case gcvHAL_UNMAP_USER_MEMORY:
  109341. + address = Interface->u.UnmapUserMemory.address;
  109342. + info = gcmNAME_TO_PTR(Interface->u.UnmapUserMemory.info);
  109343. +
  109344. + /* Unmap user memory. */
  109345. + gcmkONERROR(
  109346. + gckOS_UnmapUserMemory(Kernel->os,
  109347. + Kernel->core,
  109348. + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory),
  109349. + (gctSIZE_T) Interface->u.UnmapUserMemory.size,
  109350. + info,
  109351. + address));
  109352. +
  109353. +#if gcdSECURE_USER
  109354. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  109355. + Kernel,
  109356. + cache,
  109357. + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory),
  109358. + Interface->u.UnmapUserMemory.size));
  109359. +#endif
  109360. + gcmkVERIFY_OK(
  109361. + gckKERNEL_RemoveProcessDB(Kernel,
  109362. + processID, gcvDB_MAP_USER_MEMORY,
  109363. + gcmINT2PTR(Interface->u.UnmapUserMemory.info)));
  109364. +
  109365. + gcmRELEASE_NAME(Interface->u.UnmapUserMemory.info);
  109366. +
  109367. + break;
  109368. +
  109369. +#if !USE_NEW_LINUX_SIGNAL
  109370. + case gcvHAL_USER_SIGNAL:
  109371. + /* Dispatch depends on the user signal subcommands. */
  109372. + switch(Interface->u.UserSignal.command)
  109373. + {
  109374. + case gcvUSER_SIGNAL_CREATE:
  109375. + /* Create a signal used in the user space. */
  109376. + gcmkONERROR(
  109377. + gckOS_CreateUserSignal(Kernel->os,
  109378. + Interface->u.UserSignal.manualReset,
  109379. + &Interface->u.UserSignal.id));
  109380. +
  109381. + gcmkVERIFY_OK(
  109382. + gckKERNEL_AddProcessDB(Kernel,
  109383. + processID, gcvDB_SIGNAL,
  109384. + gcmINT2PTR(Interface->u.UserSignal.id),
  109385. + gcvNULL,
  109386. + 0));
  109387. + break;
  109388. +
  109389. + case gcvUSER_SIGNAL_DESTROY:
  109390. + /* Destroy the signal. */
  109391. + gcmkONERROR(
  109392. + gckOS_DestroyUserSignal(Kernel->os,
  109393. + Interface->u.UserSignal.id));
  109394. +
  109395. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  109396. + Kernel,
  109397. + processID, gcvDB_SIGNAL,
  109398. + gcmINT2PTR(Interface->u.UserSignal.id)));
  109399. + break;
  109400. +
  109401. + case gcvUSER_SIGNAL_SIGNAL:
  109402. + /* Signal the signal. */
  109403. + gcmkONERROR(
  109404. + gckOS_SignalUserSignal(Kernel->os,
  109405. + Interface->u.UserSignal.id,
  109406. + Interface->u.UserSignal.state));
  109407. + break;
  109408. +
  109409. + case gcvUSER_SIGNAL_WAIT:
  109410. +#if gcdGPU_TIMEOUT
  109411. + if (Interface->u.UserSignal.wait == gcvINFINITE)
  109412. + {
  109413. + gckHARDWARE hardware;
  109414. + gctUINT32 timer = 0;
  109415. +
  109416. + for(;;)
  109417. + {
  109418. + /* Wait on the signal. */
  109419. + status = gckOS_WaitUserSignal(Kernel->os,
  109420. + Interface->u.UserSignal.id,
  109421. + gcdGPU_ADVANCETIMER);
  109422. +
  109423. + if (status == gcvSTATUS_TIMEOUT)
  109424. + {
  109425. + gcmkONERROR(
  109426. + gckOS_SignalQueryHardware(Kernel->os,
  109427. + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
  109428. + &hardware));
  109429. +
  109430. + if (hardware)
  109431. + {
  109432. + /* This signal is bound to a hardware,
  109433. + ** so the timeout is limited by Kernel->timeOut.
  109434. + */
  109435. + timer += gcdGPU_ADVANCETIMER;
  109436. + }
  109437. +
  109438. + if (timer >= Kernel->timeOut)
  109439. + {
  109440. + gcmkONERROR(
  109441. + gckOS_Broadcast(Kernel->os,
  109442. + hardware,
  109443. + gcvBROADCAST_GPU_STUCK));
  109444. +
  109445. + timer = 0;
  109446. +
  109447. + /* If a few process try to reset GPU, only one
  109448. + ** of them can do the real reset, other processes
  109449. + ** still need to wait for this signal is triggered,
  109450. + ** which menas reset is finished.
  109451. + */
  109452. + continue;
  109453. + }
  109454. + }
  109455. + else
  109456. + {
  109457. + /* Bail out on other error. */
  109458. + gcmkONERROR(status);
  109459. +
  109460. + /* Wait for signal successfully. */
  109461. + break;
  109462. + }
  109463. + }
  109464. + }
  109465. + else
  109466. +#endif
  109467. + {
  109468. + /* Wait on the signal. */
  109469. + status = gckOS_WaitUserSignal(Kernel->os,
  109470. + Interface->u.UserSignal.id,
  109471. + Interface->u.UserSignal.wait);
  109472. + }
  109473. +
  109474. + break;
  109475. +
  109476. + case gcvUSER_SIGNAL_MAP:
  109477. + gcmkONERROR(
  109478. + gckOS_MapSignal(Kernel->os,
  109479. + (gctSIGNAL)(gctUINTPTR_T)Interface->u.UserSignal.id,
  109480. + (gctHANDLE)(gctUINTPTR_T)processID,
  109481. + &signal));
  109482. +
  109483. + gcmkVERIFY_OK(
  109484. + gckKERNEL_AddProcessDB(Kernel,
  109485. + processID, gcvDB_SIGNAL,
  109486. + gcmINT2PTR(Interface->u.UserSignal.id),
  109487. + gcvNULL,
  109488. + 0));
  109489. + break;
  109490. +
  109491. + case gcvUSER_SIGNAL_UNMAP:
  109492. + /* Destroy the signal. */
  109493. + gcmkONERROR(
  109494. + gckOS_DestroyUserSignal(Kernel->os,
  109495. + Interface->u.UserSignal.id));
  109496. +
  109497. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  109498. + Kernel,
  109499. + processID, gcvDB_SIGNAL,
  109500. + gcmINT2PTR(Interface->u.UserSignal.id)));
  109501. + break;
  109502. +
  109503. + default:
  109504. + /* Invalid user signal command. */
  109505. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  109506. + }
  109507. + break;
  109508. +#endif
  109509. +
  109510. + case gcvHAL_SET_POWER_MANAGEMENT_STATE:
  109511. + /* Set the power management state. */
  109512. + gcmkONERROR(
  109513. + gckHARDWARE_SetPowerManagementState(
  109514. + Kernel->hardware,
  109515. + Interface->u.SetPowerManagement.state));
  109516. + break;
  109517. +
  109518. + case gcvHAL_QUERY_POWER_MANAGEMENT_STATE:
  109519. + /* Chip is not idle. */
  109520. + Interface->u.QueryPowerManagement.isIdle = gcvFALSE;
  109521. +
  109522. + /* Query the power management state. */
  109523. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
  109524. + Kernel->hardware,
  109525. + &Interface->u.QueryPowerManagement.state));
  109526. +
  109527. + /* Query the idle state. */
  109528. + gcmkONERROR(
  109529. + gckHARDWARE_QueryIdle(Kernel->hardware,
  109530. + &Interface->u.QueryPowerManagement.isIdle));
  109531. + break;
  109532. +
  109533. + case gcvHAL_READ_REGISTER:
  109534. +#if gcdREGISTER_ACCESS_FROM_USER
  109535. + {
  109536. + gceCHIPPOWERSTATE power;
  109537. +
  109538. + gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
  109539. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  109540. + &power));
  109541. + if (power == gcvPOWER_ON)
  109542. + {
  109543. + /* Read a register. */
  109544. + gcmkONERROR(gckOS_ReadRegisterEx(
  109545. + Kernel->os,
  109546. + Kernel->core,
  109547. + Interface->u.ReadRegisterData.address,
  109548. + &Interface->u.ReadRegisterData.data));
  109549. + }
  109550. + else
  109551. + {
  109552. + /* Chip is in power-state. */
  109553. + Interface->u.ReadRegisterData.data = 0;
  109554. + status = gcvSTATUS_CHIP_NOT_READY;
  109555. + }
  109556. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
  109557. + }
  109558. +#else
  109559. + /* No access from user land to read registers. */
  109560. + Interface->u.ReadRegisterData.data = 0;
  109561. + status = gcvSTATUS_NOT_SUPPORTED;
  109562. +#endif
  109563. + break;
  109564. +
  109565. + case gcvHAL_WRITE_REGISTER:
  109566. +#if gcdREGISTER_ACCESS_FROM_USER
  109567. + {
  109568. + gceCHIPPOWERSTATE power;
  109569. +
  109570. + gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE);
  109571. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  109572. + &power));
  109573. + if (power == gcvPOWER_ON)
  109574. + {
  109575. + /* Write a register. */
  109576. + gcmkONERROR(
  109577. + gckOS_WriteRegisterEx(Kernel->os,
  109578. + Kernel->core,
  109579. + Interface->u.WriteRegisterData.address,
  109580. + Interface->u.WriteRegisterData.data));
  109581. + }
  109582. + else
  109583. + {
  109584. + /* Chip is in power-state. */
  109585. + Interface->u.WriteRegisterData.data = 0;
  109586. + status = gcvSTATUS_CHIP_NOT_READY;
  109587. + }
  109588. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->hardware->powerMutex));
  109589. + }
  109590. +#else
  109591. + /* No access from user land to write registers. */
  109592. + status = gcvSTATUS_NOT_SUPPORTED;
  109593. +#endif
  109594. + break;
  109595. +
  109596. + case gcvHAL_READ_ALL_PROFILE_REGISTERS:
  109597. +#if VIVANTE_PROFILER && VIVANTE_PROFILER_CONTEXT
  109598. + /* Read profile data according to the context. */
  109599. + gcmkONERROR(
  109600. + gckHARDWARE_QueryContextProfile(
  109601. + Kernel->hardware,
  109602. + Kernel->profileCleanRegister,
  109603. + gcmNAME_TO_PTR(Interface->u.RegisterProfileData.context),
  109604. + &Interface->u.RegisterProfileData.counters));
  109605. +#elif VIVANTE_PROFILER
  109606. + /* Read all 3D profile registers. */
  109607. + gcmkONERROR(
  109608. + gckHARDWARE_QueryProfileRegisters(
  109609. + Kernel->hardware,
  109610. + Kernel->profileCleanRegister,
  109611. + &Interface->u.RegisterProfileData.counters));
  109612. +#else
  109613. + status = gcvSTATUS_OK;
  109614. +#endif
  109615. + break;
  109616. +
  109617. + case gcvHAL_PROFILE_REGISTERS_2D:
  109618. +#if VIVANTE_PROFILER
  109619. + /* Read all 2D profile registers. */
  109620. + gcmkONERROR(
  109621. + gckHARDWARE_ProfileEngine2D(
  109622. + Kernel->hardware,
  109623. + gcmUINT64_TO_PTR(Interface->u.RegisterProfileData2D.hwProfile2D)));
  109624. +#else
  109625. + status = gcvSTATUS_OK;
  109626. +#endif
  109627. + break;
  109628. +
  109629. + case gcvHAL_GET_PROFILE_SETTING:
  109630. +#if VIVANTE_PROFILER
  109631. + /* Get profile setting */
  109632. + Interface->u.GetProfileSetting.enable = Kernel->profileEnable;
  109633. +#endif
  109634. +
  109635. + status = gcvSTATUS_OK;
  109636. + break;
  109637. + case gcvHAL_SET_PROFILE_SETTING:
  109638. +#if VIVANTE_PROFILER
  109639. + /* Set profile setting */
  109640. + if(Kernel->hardware->gpuProfiler)
  109641. + Kernel->profileEnable = Interface->u.SetProfileSetting.enable;
  109642. + else
  109643. + {
  109644. + status = gcvSTATUS_NOT_SUPPORTED;
  109645. + break;
  109646. + }
  109647. +#endif
  109648. +
  109649. + status = gcvSTATUS_OK;
  109650. + break;
  109651. +
  109652. +#if VIVANTE_PROFILER_PERDRAW
  109653. + case gcvHAL_READ_PROFILER_REGISTER_SETTING:
  109654. + #if VIVANTE_PROFILER
  109655. + Kernel->profileCleanRegister = Interface->u.SetProfilerRegisterClear.bclear;
  109656. + #endif
  109657. + status = gcvSTATUS_OK;
  109658. + break;
  109659. +#endif
  109660. +
  109661. + case gcvHAL_QUERY_KERNEL_SETTINGS:
  109662. + /* Get kernel settings. */
  109663. + gcmkONERROR(
  109664. + gckKERNEL_QuerySettings(Kernel,
  109665. + &Interface->u.QueryKernelSettings.settings));
  109666. + break;
  109667. +
  109668. + case gcvHAL_RESET:
  109669. + /* Reset the hardware. */
  109670. + gckKERNEL_Recovery(Kernel);
  109671. + break;
  109672. +
  109673. + case gcvHAL_DEBUG:
  109674. + /* Set debug level and zones. */
  109675. + if (Interface->u.Debug.set)
  109676. + {
  109677. + gckOS_SetDebugLevel(Interface->u.Debug.level);
  109678. + gckOS_SetDebugZones(Interface->u.Debug.zones,
  109679. + Interface->u.Debug.enable);
  109680. + }
  109681. +
  109682. + if (Interface->u.Debug.message[0] != '\0')
  109683. + {
  109684. + /* Print a message to the debugger. */
  109685. + if (Interface->u.Debug.type == gcvMESSAGE_TEXT)
  109686. + {
  109687. + gckOS_CopyPrint(Interface->u.Debug.message);
  109688. + }
  109689. + else
  109690. + {
  109691. + gckOS_DumpBuffer(Kernel->os,
  109692. + Interface->u.Debug.message,
  109693. + Interface->u.Debug.messageSize,
  109694. + gceDUMP_BUFFER_FROM_USER,
  109695. + gcvTRUE);
  109696. + }
  109697. + }
  109698. + status = gcvSTATUS_OK;
  109699. + break;
  109700. +
  109701. + case gcvHAL_DUMP_GPU_STATE:
  109702. + /* Dump GPU state */
  109703. + {
  109704. + gceCHIPPOWERSTATE power;
  109705. + gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
  109706. + &power));
  109707. + if (power == gcvPOWER_ON)
  109708. + {
  109709. + Interface->u.ReadRegisterData.data = 1;
  109710. + gcmkVERIFY_OK(
  109711. + gckHARDWARE_DumpGPUState(Kernel->hardware));
  109712. +#if gcdVIRTUAL_COMMAND_BUFFER
  109713. + gcmkVERIFY_OK(
  109714. + gckCOMMAND_DumpExecutingBuffer(Kernel->command));
  109715. +#endif
  109716. + }
  109717. + else
  109718. + {
  109719. + Interface->u.ReadRegisterData.data = 0;
  109720. + status = gcvSTATUS_CHIP_NOT_READY;
  109721. + }
  109722. + }
  109723. + break;
  109724. +
  109725. + case gcvHAL_DUMP_EVENT:
  109726. + /* Dump GPU event */
  109727. + gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj));
  109728. +
  109729. + /* Dump Process DB. */
  109730. + gcmkVERIFY_OK(gckKERNEL_DumpProcessDB(Kernel));
  109731. + break;
  109732. +
  109733. + case gcvHAL_CACHE:
  109734. + node = gcmUINT64_TO_PTR(Interface->u.Cache.node);
  109735. + if (node == gcvNULL)
  109736. + {
  109737. + /* FIXME Surface wrap some memory which is not allocated by us,
  109738. + ** So we don't have physical address to handle outer cache, ignore it*/
  109739. + status = gcvSTATUS_OK;
  109740. + break;
  109741. + }
  109742. + else if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  109743. + {
  109744. + /* Video memory has no physical handles. */
  109745. + physical = gcvNULL;
  109746. + }
  109747. + else
  109748. + {
  109749. + /* Grab physical handle. */
  109750. + physical = node->Virtual.physical;
  109751. + }
  109752. +
  109753. + logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical);
  109754. + bytes = (gctSIZE_T) Interface->u.Cache.bytes;
  109755. + switch(Interface->u.Cache.operation)
  109756. + {
  109757. + case gcvCACHE_FLUSH:
  109758. + /* Clean and invalidate the cache. */
  109759. + status = gckOS_CacheFlush(Kernel->os,
  109760. + processID,
  109761. + physical,
  109762. + paddr,
  109763. + logical,
  109764. + bytes);
  109765. + break;
  109766. + case gcvCACHE_CLEAN:
  109767. + /* Clean the cache. */
  109768. + status = gckOS_CacheClean(Kernel->os,
  109769. + processID,
  109770. + physical,
  109771. + paddr,
  109772. + logical,
  109773. + bytes);
  109774. + break;
  109775. + case gcvCACHE_INVALIDATE:
  109776. + /* Invalidate the cache. */
  109777. + status = gckOS_CacheInvalidate(Kernel->os,
  109778. + processID,
  109779. + physical,
  109780. + paddr,
  109781. + logical,
  109782. + bytes);
  109783. + break;
  109784. +
  109785. + case gcvCACHE_MEMORY_BARRIER:
  109786. + status = gckOS_MemoryBarrier(Kernel->os,
  109787. + logical);
  109788. + break;
  109789. + default:
  109790. + status = gcvSTATUS_INVALID_ARGUMENT;
  109791. + break;
  109792. + }
  109793. + break;
  109794. +
  109795. + case gcvHAL_TIMESTAMP:
  109796. + /* Check for invalid timer. */
  109797. + if ((Interface->u.TimeStamp.timer >= gcmCOUNTOF(Kernel->timers))
  109798. + || (Interface->u.TimeStamp.request != 2))
  109799. + {
  109800. + Interface->u.TimeStamp.timeDelta = 0;
  109801. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  109802. + }
  109803. +
  109804. + /* Return timer results and reset timer. */
  109805. + {
  109806. + gcsTIMER_PTR timer = &(Kernel->timers[Interface->u.TimeStamp.timer]);
  109807. + gctUINT64 timeDelta = 0;
  109808. +
  109809. + if (timer->stopTime < timer->startTime )
  109810. + {
  109811. + Interface->u.TimeStamp.timeDelta = 0;
  109812. + gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
  109813. + }
  109814. +
  109815. + timeDelta = timer->stopTime - timer->startTime;
  109816. +
  109817. + /* Check truncation overflow. */
  109818. + Interface->u.TimeStamp.timeDelta = (gctINT32) timeDelta;
  109819. + /*bit0~bit30 is available*/
  109820. + if (timeDelta>>31)
  109821. + {
  109822. + Interface->u.TimeStamp.timeDelta = 0;
  109823. + gcmkONERROR(gcvSTATUS_TIMER_OVERFLOW);
  109824. + }
  109825. +
  109826. + status = gcvSTATUS_OK;
  109827. + }
  109828. + break;
  109829. +
  109830. + case gcvHAL_DATABASE:
  109831. + /* Query video memory. */
  109832. + gcmkONERROR(
  109833. + gckKERNEL_QueryProcessDB(Kernel,
  109834. + Interface->u.Database.processID,
  109835. + !Interface->u.Database.validProcessID,
  109836. + gcvDB_VIDEO_MEMORY,
  109837. + &Interface->u.Database.vidMem));
  109838. +
  109839. + /* Query non-paged memory. */
  109840. + gcmkONERROR(
  109841. + gckKERNEL_QueryProcessDB(Kernel,
  109842. + Interface->u.Database.processID,
  109843. + !Interface->u.Database.validProcessID,
  109844. + gcvDB_NON_PAGED,
  109845. + &Interface->u.Database.nonPaged));
  109846. +
  109847. + /* Query contiguous memory. */
  109848. + gcmkONERROR(
  109849. + gckKERNEL_QueryProcessDB(Kernel,
  109850. + Interface->u.Database.processID,
  109851. + !Interface->u.Database.validProcessID,
  109852. + gcvDB_CONTIGUOUS,
  109853. + &Interface->u.Database.contiguous));
  109854. +
  109855. + /* Query GPU idle time. */
  109856. + gcmkONERROR(
  109857. + gckKERNEL_QueryProcessDB(Kernel,
  109858. + Interface->u.Database.processID,
  109859. + !Interface->u.Database.validProcessID,
  109860. + gcvDB_IDLE,
  109861. + &Interface->u.Database.gpuIdle));
  109862. + break;
  109863. +
  109864. + case gcvHAL_VIDMEM_DATABASE:
  109865. + /* Query reserved video memory. */
  109866. + gcmkONERROR(
  109867. + gckKERNEL_QueryProcessDB(Kernel,
  109868. + Interface->u.VidMemDatabase.processID,
  109869. + !Interface->u.VidMemDatabase.validProcessID,
  109870. + gcvDB_VIDEO_MEMORY_RESERVED,
  109871. + &Interface->u.VidMemDatabase.vidMemResv));
  109872. +
  109873. + /* Query contiguous video memory. */
  109874. + gcmkONERROR(
  109875. + gckKERNEL_QueryProcessDB(Kernel,
  109876. + Interface->u.VidMemDatabase.processID,
  109877. + !Interface->u.VidMemDatabase.validProcessID,
  109878. + gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  109879. + &Interface->u.VidMemDatabase.vidMemCont));
  109880. +
  109881. + /* Query virtual video memory. */
  109882. + gcmkONERROR(
  109883. + gckKERNEL_QueryProcessDB(Kernel,
  109884. + Interface->u.VidMemDatabase.processID,
  109885. + !Interface->u.VidMemDatabase.validProcessID,
  109886. + gcvDB_VIDEO_MEMORY_VIRTUAL,
  109887. + &Interface->u.VidMemDatabase.vidMemVirt));
  109888. +
  109889. + break;
  109890. +
  109891. + case gcvHAL_VERSION:
  109892. + Interface->u.Version.major = gcvVERSION_MAJOR;
  109893. + Interface->u.Version.minor = gcvVERSION_MINOR;
  109894. + Interface->u.Version.patch = gcvVERSION_PATCH;
  109895. + Interface->u.Version.build = gcvVERSION_BUILD;
  109896. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  109897. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  109898. + "KERNEL version %d.%d.%d build %u %s %s",
  109899. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
  109900. + gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
  109901. +#endif
  109902. + break;
  109903. +
  109904. + case gcvHAL_CHIP_INFO:
  109905. + /* Only if not support multi-core */
  109906. + Interface->u.ChipInfo.count = 1;
  109907. + Interface->u.ChipInfo.types[0] = Kernel->hardware->type;
  109908. + break;
  109909. +
  109910. + case gcvHAL_ATTACH:
  109911. + /* Attach user process. */
  109912. + gcmkONERROR(
  109913. + gckCOMMAND_Attach(Kernel->command,
  109914. + &context,
  109915. + &bytes,
  109916. + processID));
  109917. +
  109918. + Interface->u.Attach.stateCount = bytes;
  109919. + Interface->u.Attach.context = gcmPTR_TO_NAME(context);
  109920. +
  109921. + gcmkVERIFY_OK(
  109922. + gckKERNEL_AddProcessDB(Kernel,
  109923. + processID, gcvDB_CONTEXT,
  109924. + gcmINT2PTR(Interface->u.Attach.context),
  109925. + gcvNULL,
  109926. + 0));
  109927. + break;
  109928. +
  109929. + case gcvHAL_DETACH:
  109930. + /* Detach user process. */
  109931. + gcmkONERROR(
  109932. + gckCOMMAND_Detach(Kernel->command,
  109933. + gcmNAME_TO_PTR(Interface->u.Detach.context)));
  109934. +
  109935. + gcmkVERIFY_OK(
  109936. + gckKERNEL_RemoveProcessDB(Kernel,
  109937. + processID, gcvDB_CONTEXT,
  109938. + gcmINT2PTR(Interface->u.Detach.context)));
  109939. +
  109940. + gcmRELEASE_NAME(Interface->u.Detach.context);
  109941. + break;
  109942. +
  109943. + case gcvHAL_COMPOSE:
  109944. + Interface->u.Compose.physical = gcmPTR_TO_UINT64(gcmNAME_TO_PTR(Interface->u.Compose.physical));
  109945. + /* Start composition. */
  109946. + gcmkONERROR(
  109947. + gckEVENT_Compose(Kernel->eventObj,
  109948. + &Interface->u.Compose));
  109949. + break;
  109950. +
  109951. + case gcvHAL_SET_TIMEOUT:
  109952. + /* set timeOut value from user */
  109953. + gckKERNEL_SetTimeOut(Kernel, Interface->u.SetTimeOut.timeOut);
  109954. + break;
  109955. +
  109956. +#if gcdFRAME_DB
  109957. + case gcvHAL_GET_FRAME_INFO:
  109958. + gcmkONERROR(gckHARDWARE_GetFrameInfo(
  109959. + Kernel->hardware,
  109960. + gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo)));
  109961. + break;
  109962. +#endif
  109963. +
  109964. + case gcvHAL_GET_SHARED_INFO:
  109965. + if (Interface->u.GetSharedInfo.data == gcvNULL)
  109966. + {
  109967. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  109968. + }
  109969. + else
  109970. + {
  109971. + gctUINT32 pid = Interface->u.GetSharedInfo.pid;
  109972. + gctUINT32 dataId = Interface->u.GetSharedInfo.dataId;
  109973. + gctSIZE_T bytes = Interface->u.GetSharedInfo.bytes;
  109974. + gctPOINTER data = Interface->u.GetSharedInfo.data;
  109975. + gcsDATABASE_RECORD record;
  109976. +
  109977. + /* Find record. */
  109978. + gcmkONERROR(
  109979. + gckKERNEL_FindProcessDB(Kernel,
  109980. + pid,
  109981. + 0,
  109982. + gcvDB_SHARED_INFO,
  109983. + gcmINT2PTR(dataId),
  109984. + &record));
  109985. +
  109986. + /* Check memory size. */
  109987. + if (bytes < record.bytes)
  109988. + {
  109989. + /* Insufficient memory to hold shared data. */
  109990. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  109991. + }
  109992. +
  109993. + /* Copy to user. */
  109994. + status = gckOS_CopyToUserData(Kernel->os,
  109995. + record.physical,
  109996. + data,
  109997. + record.bytes);
  109998. +
  109999. + /*
  110000. + * Remove from process db.
  110001. + * Every time when shared info is taken, the record is erased in
  110002. + * kernel side.
  110003. + */
  110004. + gcmkVERIFY_OK(
  110005. + gckKERNEL_RemoveProcessDB(Kernel,
  110006. + pid,
  110007. + gcvDB_SHARED_INFO,
  110008. + gcmINT2PTR(dataId)));
  110009. + /* Free existed data. */
  110010. + gcmkVERIFY_OK(
  110011. + gckOS_FreeMemory(Kernel->os, record.physical));
  110012. + }
  110013. + break;
  110014. +
  110015. + case gcvHAL_SET_SHARED_INFO:
  110016. + {
  110017. + gctUINT32 dataId = Interface->u.SetSharedInfo.dataId;
  110018. + gctPOINTER data = Interface->u.SetSharedInfo.data;
  110019. + gctUINT32 bytes = Interface->u.SetSharedInfo.bytes;
  110020. + gctPOINTER memory = gcvNULL;
  110021. + gcsDATABASE_RECORD record;
  110022. +
  110023. + if (gcmIS_SUCCESS(gckKERNEL_FindProcessDB(Kernel,
  110024. + processID,
  110025. + 0,
  110026. + gcvDB_SHARED_INFO,
  110027. + gcmINT2PTR(dataId),
  110028. + &record)))
  110029. + {
  110030. + /* Find a record with the same id. */
  110031. + if (bytes != record.bytes)
  110032. + {
  110033. + /* Remove from process db. */
  110034. + gcmkVERIFY_OK(
  110035. + gckKERNEL_RemoveProcessDB(Kernel,
  110036. + processID,
  110037. + gcvDB_SHARED_INFO,
  110038. + gcmINT2PTR(dataId)));
  110039. +
  110040. + /* Free existed data. */
  110041. + gcmkVERIFY_OK(
  110042. + gckOS_FreeMemory(Kernel->os, record.physical));
  110043. + }
  110044. + else
  110045. + {
  110046. + /* Re-use allocated memory. */
  110047. + memory = record.physical;
  110048. + }
  110049. + }
  110050. +
  110051. + if ((data == gcvNULL) || (bytes == 0))
  110052. + {
  110053. + /* Nothing to record. */
  110054. + break;
  110055. + }
  110056. +
  110057. + if (bytes > 1024)
  110058. + {
  110059. + /* Limite data size. */
  110060. + gcmkONERROR(gcvSTATUS_TOO_COMPLEX);
  110061. + }
  110062. +
  110063. + if (memory == gcvNULL)
  110064. + {
  110065. + /* Allocate memory for holding shared data. */
  110066. + gcmkONERROR(
  110067. + gckOS_AllocateMemory(Kernel->os, bytes, &memory));
  110068. +
  110069. + /* Add to process db. */
  110070. + status = gckKERNEL_AddProcessDB(Kernel,
  110071. + processID,
  110072. + gcvDB_SHARED_INFO,
  110073. + gcmINT2PTR(dataId),
  110074. + memory,
  110075. + bytes);
  110076. +
  110077. + if (gcmIS_ERROR(status))
  110078. + {
  110079. + /* Failed to add process db. Free allocated memory. */
  110080. + gcmkVERIFY_OK(gckOS_FreeMemory(Kernel->os, memory));
  110081. + break;
  110082. + }
  110083. + }
  110084. +
  110085. + /* Copy shared data to kernel memory. */
  110086. + gcmkONERROR(
  110087. + gckOS_CopyFromUserData(Kernel->os,
  110088. + memory,
  110089. + data,
  110090. + bytes));
  110091. + }
  110092. + break;
  110093. +
  110094. + case gcvHAL_SET_FSCALE_VALUE:
  110095. +#if gcdENABLE_FSCALE_VAL_ADJUST
  110096. + status = gckHARDWARE_SetFscaleValue(Kernel->hardware,
  110097. + Interface->u.SetFscaleValue.value);
  110098. +#else
  110099. + status = gcvSTATUS_NOT_SUPPORTED;
  110100. +#endif
  110101. + break;
  110102. + case gcvHAL_GET_FSCALE_VALUE:
  110103. +#if gcdENABLE_FSCALE_VAL_ADJUST
  110104. + status = gckHARDWARE_GetFscaleValue(Kernel->hardware,
  110105. + &Interface->u.GetFscaleValue.value,
  110106. + &Interface->u.GetFscaleValue.minValue,
  110107. + &Interface->u.GetFscaleValue.maxValue);
  110108. +#else
  110109. + status = gcvSTATUS_NOT_SUPPORTED;
  110110. +#endif
  110111. + break;
  110112. +
  110113. + case gcvHAL_QUERY_RESET_TIME_STAMP:
  110114. +#if gcdENABLE_RECOVERY
  110115. + Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp;
  110116. +#else
  110117. + Interface->u.QueryResetTimeStamp.timeStamp = 0;
  110118. +#endif
  110119. + break;
  110120. +
  110121. +#if gcdANDROID_NATIVE_FENCE_SYNC
  110122. + case gcvHAL_SYNC_POINT:
  110123. + {
  110124. + gctSYNC_POINT syncPoint;
  110125. +
  110126. + switch (Interface->u.SyncPoint.command)
  110127. + {
  110128. + case gcvSYNC_POINT_CREATE:
  110129. + gcmkONERROR(gckOS_CreateSyncPoint(Kernel->os, &syncPoint));
  110130. +
  110131. + Interface->u.SyncPoint.syncPoint = gcmPTR_TO_UINT64(syncPoint);
  110132. +
  110133. + gcmkVERIFY_OK(
  110134. + gckKERNEL_AddProcessDB(Kernel,
  110135. + processID, gcvDB_SYNC_POINT,
  110136. + syncPoint,
  110137. + gcvNULL,
  110138. + 0));
  110139. + break;
  110140. +
  110141. + case gcvSYNC_POINT_DESTROY:
  110142. + syncPoint = gcmUINT64_TO_PTR(Interface->u.SyncPoint.syncPoint);
  110143. +
  110144. + gcmkONERROR(gckOS_DestroySyncPoint(Kernel->os, syncPoint));
  110145. +
  110146. + gcmkVERIFY_OK(
  110147. + gckKERNEL_RemoveProcessDB(Kernel,
  110148. + processID, gcvDB_SYNC_POINT,
  110149. + syncPoint));
  110150. + break;
  110151. +
  110152. + default:
  110153. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  110154. + break;
  110155. + }
  110156. + }
  110157. + break;
  110158. +
  110159. + case gcvHAL_CREATE_NATIVE_FENCE:
  110160. + {
  110161. + gctINT fenceFD;
  110162. + gctSYNC_POINT syncPoint =
  110163. + gcmUINT64_TO_PTR(Interface->u.CreateNativeFence.syncPoint);
  110164. +
  110165. + gcmkONERROR(
  110166. + gckOS_CreateNativeFence(Kernel->os,
  110167. + Kernel->timeline,
  110168. + syncPoint,
  110169. + &fenceFD));
  110170. +
  110171. + Interface->u.CreateNativeFence.fenceFD = fenceFD;
  110172. + }
  110173. + break;
  110174. +#endif
  110175. +
  110176. + default:
  110177. + /* Invalid command. */
  110178. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  110179. + }
  110180. +
  110181. +OnError:
  110182. + /* Save status. */
  110183. + Interface->status = status;
  110184. +
  110185. + if (gcmIS_ERROR(status))
  110186. + {
  110187. + if (locked)
  110188. + {
  110189. + /* Roll back the lock. */
  110190. + gcmkVERIFY_OK(
  110191. + gckVIDMEM_Unlock(Kernel,
  110192. + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
  110193. + gcvSURF_TYPE_UNKNOWN,
  110194. + &asynchronous));
  110195. +
  110196. + if (gcvTRUE == asynchronous)
  110197. + {
  110198. + /* Bottom Half */
  110199. + gcmkVERIFY_OK(
  110200. + gckVIDMEM_Unlock(Kernel,
  110201. + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node),
  110202. + gcvSURF_TYPE_UNKNOWN,
  110203. + gcvNULL));
  110204. + }
  110205. + }
  110206. + }
  110207. +
  110208. +#if QNX_SINGLE_THREADED_DEBUGGING
  110209. + gckOS_ReleaseMutex(Kernel->os, Kernel->debugMutex);
  110210. +#endif
  110211. +
  110212. + /* Return the status. */
  110213. + gcmkFOOTER();
  110214. + return status;
  110215. +}
  110216. +
  110217. +/*******************************************************************************
  110218. +** gckKERNEL_AttachProcess
  110219. +**
  110220. +** Attach or detach a process.
  110221. +**
  110222. +** INPUT:
  110223. +**
  110224. +** gckKERNEL Kernel
  110225. +** Pointer to an gckKERNEL object.
  110226. +**
  110227. +** gctBOOL Attach
  110228. +** gcvTRUE if a new process gets attached or gcFALSE when a process
  110229. +** gets detatched.
  110230. +**
  110231. +** OUTPUT:
  110232. +**
  110233. +** Nothing.
  110234. +*/
  110235. +gceSTATUS
  110236. +gckKERNEL_AttachProcess(
  110237. + IN gckKERNEL Kernel,
  110238. + IN gctBOOL Attach
  110239. + )
  110240. +{
  110241. + gceSTATUS status;
  110242. + gctUINT32 processID;
  110243. +
  110244. + gcmkHEADER_ARG("Kernel=0x%x Attach=%d", Kernel, Attach);
  110245. +
  110246. + /* Verify the arguments. */
  110247. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  110248. +
  110249. + /* Get current process ID. */
  110250. + gcmkONERROR(gckOS_GetProcessID(&processID));
  110251. +
  110252. + gcmkONERROR(gckKERNEL_AttachProcessEx(Kernel, Attach, processID));
  110253. +
  110254. + /* Success. */
  110255. + gcmkFOOTER_NO();
  110256. + return gcvSTATUS_OK;
  110257. +
  110258. +OnError:
  110259. + /* Return the status. */
  110260. + gcmkFOOTER();
  110261. + return status;
  110262. +}
  110263. +
  110264. +/*******************************************************************************
  110265. +** gckKERNEL_AttachProcessEx
  110266. +**
  110267. +** Attach or detach a process with the given PID. Can be paired with gckKERNEL_AttachProcess
  110268. +** provided the programmer is aware of the consequences.
  110269. +**
  110270. +** INPUT:
  110271. +**
  110272. +** gckKERNEL Kernel
  110273. +** Pointer to an gckKERNEL object.
  110274. +**
  110275. +** gctBOOL Attach
  110276. +** gcvTRUE if a new process gets attached or gcFALSE when a process
  110277. +** gets detatched.
  110278. +**
  110279. +** gctUINT32 PID
  110280. +** PID of the process to attach or detach.
  110281. +**
  110282. +** OUTPUT:
  110283. +**
  110284. +** Nothing.
  110285. +*/
  110286. +gceSTATUS
  110287. +gckKERNEL_AttachProcessEx(
  110288. + IN gckKERNEL Kernel,
  110289. + IN gctBOOL Attach,
  110290. + IN gctUINT32 PID
  110291. + )
  110292. +{
  110293. + gceSTATUS status;
  110294. + gctINT32 old;
  110295. +
  110296. + gcmkHEADER_ARG("Kernel=0x%x Attach=%d PID=%d", Kernel, Attach, PID);
  110297. +
  110298. + /* Verify the arguments. */
  110299. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  110300. +
  110301. + if (Attach)
  110302. + {
  110303. + /* Increment the number of clients attached. */
  110304. + gcmkONERROR(
  110305. + gckOS_AtomIncrement(Kernel->os, Kernel->atomClients, &old));
  110306. +
  110307. + if (old == 0)
  110308. + {
  110309. +#if gcdENABLE_VG
  110310. + if (Kernel->vg == gcvNULL)
  110311. +#endif
  110312. + {
  110313. + gcmkONERROR(gckOS_Broadcast(Kernel->os,
  110314. + Kernel->hardware,
  110315. + gcvBROADCAST_FIRST_PROCESS));
  110316. + }
  110317. + }
  110318. +
  110319. + if (Kernel->dbCreated)
  110320. + {
  110321. + /* Create the process database. */
  110322. + gcmkONERROR(gckKERNEL_CreateProcessDB(Kernel, PID));
  110323. + }
  110324. + }
  110325. + else
  110326. + {
  110327. + if (Kernel->dbCreated)
  110328. + {
  110329. + /* Clean up the process database. */
  110330. + gcmkONERROR(gckKERNEL_DestroyProcessDB(Kernel, PID));
  110331. +
  110332. + /* Save the last know process ID. */
  110333. + Kernel->db->lastProcessID = PID;
  110334. + }
  110335. +
  110336. +#if gcdENABLE_VG
  110337. + if (Kernel->vg == gcvNULL)
  110338. +#endif
  110339. + {
  110340. + status = gckEVENT_Submit(Kernel->eventObj, gcvTRUE, gcvFALSE);
  110341. +
  110342. + if (status == gcvSTATUS_INTERRUPTED && Kernel->eventObj->submitTimer)
  110343. + {
  110344. + gcmkONERROR(gckOS_StartTimer(Kernel->os,
  110345. + Kernel->eventObj->submitTimer,
  110346. + 1));
  110347. + }
  110348. + else
  110349. + {
  110350. + gcmkONERROR(status);
  110351. + }
  110352. + }
  110353. +
  110354. + /* Decrement the number of clients attached. */
  110355. + gcmkONERROR(
  110356. + gckOS_AtomDecrement(Kernel->os, Kernel->atomClients, &old));
  110357. +
  110358. + if (old == 1)
  110359. + {
  110360. +#if gcdENABLE_VG
  110361. + if (Kernel->vg == gcvNULL)
  110362. +#endif
  110363. + {
  110364. + /* Last client detached, switch to SUSPEND power state. */
  110365. + gcmkONERROR(gckOS_Broadcast(Kernel->os,
  110366. + Kernel->hardware,
  110367. + gcvBROADCAST_LAST_PROCESS));
  110368. + }
  110369. +
  110370. + /* Flush the debug cache. */
  110371. + gcmkDEBUGFLUSH(~0U);
  110372. + }
  110373. + }
  110374. +
  110375. + /* Success. */
  110376. + gcmkFOOTER_NO();
  110377. + return gcvSTATUS_OK;
  110378. +
  110379. +OnError:
  110380. + /* Return the status. */
  110381. + gcmkFOOTER();
  110382. + return status;
  110383. +}
  110384. +
  110385. +#if gcdSECURE_USER
  110386. +gceSTATUS
  110387. +gckKERNEL_MapLogicalToPhysical(
  110388. + IN gckKERNEL Kernel,
  110389. + IN gcskSECURE_CACHE_PTR Cache,
  110390. + IN OUT gctPOINTER * Data
  110391. + )
  110392. +{
  110393. + gceSTATUS status;
  110394. + static gctBOOL baseAddressValid = gcvFALSE;
  110395. + static gctUINT32 baseAddress;
  110396. + gctBOOL needBase;
  110397. + gcskLOGICAL_CACHE_PTR slot;
  110398. +
  110399. + gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x *Data=0x%x",
  110400. + Kernel, Cache, gcmOPT_POINTER(Data));
  110401. +
  110402. + /* Verify the arguments. */
  110403. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  110404. +
  110405. + if (!baseAddressValid)
  110406. + {
  110407. + /* Get base address. */
  110408. + gcmkONERROR(gckHARDWARE_GetBaseAddress(Kernel->hardware, &baseAddress));
  110409. +
  110410. + baseAddressValid = gcvTRUE;
  110411. + }
  110412. +
  110413. + /* Does this state load need a base address? */
  110414. + gcmkONERROR(gckHARDWARE_NeedBaseAddress(Kernel->hardware,
  110415. + ((gctUINT32_PTR) Data)[-1],
  110416. + &needBase));
  110417. +
  110418. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
  110419. + {
  110420. + gcskLOGICAL_CACHE_PTR next;
  110421. + gctINT i;
  110422. +
  110423. + /* Walk all used cache slots. */
  110424. + for (i = 1, slot = Cache->cache[0].next, next = gcvNULL;
  110425. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  110426. + ++i, slot = slot->next
  110427. + )
  110428. + {
  110429. + if (slot->logical == *Data)
  110430. + {
  110431. + /* Bail out. */
  110432. + next = slot;
  110433. + break;
  110434. + }
  110435. + }
  110436. +
  110437. + /* See if we had a miss. */
  110438. + if (next == gcvNULL)
  110439. + {
  110440. + /* Use the tail of the cache. */
  110441. + slot = Cache->cache[0].prev;
  110442. +
  110443. + /* Initialize the cache line. */
  110444. + slot->logical = *Data;
  110445. +
  110446. + /* Map the logical address to a DMA address. */
  110447. + gcmkONERROR(
  110448. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  110449. + }
  110450. +
  110451. + /* Move slot to head of list. */
  110452. + if (slot != Cache->cache[0].next)
  110453. + {
  110454. + /* Unlink. */
  110455. + slot->prev->next = slot->next;
  110456. + slot->next->prev = slot->prev;
  110457. +
  110458. + /* Move to head of chain. */
  110459. + slot->prev = &Cache->cache[0];
  110460. + slot->next = Cache->cache[0].next;
  110461. + slot->prev->next = slot;
  110462. + slot->next->prev = slot;
  110463. + }
  110464. + }
  110465. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  110466. + {
  110467. + gctINT i;
  110468. + gcskLOGICAL_CACHE_PTR next = gcvNULL;
  110469. + gcskLOGICAL_CACHE_PTR oldestSlot = gcvNULL;
  110470. + slot = gcvNULL;
  110471. +
  110472. + if (Cache->cacheIndex != gcvNULL)
  110473. + {
  110474. + /* Walk the cache forwards. */
  110475. + for (i = 1, slot = Cache->cacheIndex;
  110476. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  110477. + ++i, slot = slot->next)
  110478. + {
  110479. + if (slot->logical == *Data)
  110480. + {
  110481. + /* Bail out. */
  110482. + next = slot;
  110483. + break;
  110484. + }
  110485. +
  110486. + /* Determine age of this slot. */
  110487. + if ((oldestSlot == gcvNULL)
  110488. + || (oldestSlot->stamp > slot->stamp)
  110489. + )
  110490. + {
  110491. + oldestSlot = slot;
  110492. + }
  110493. + }
  110494. +
  110495. + if (next == gcvNULL)
  110496. + {
  110497. + /* Walk the cache backwards. */
  110498. + for (slot = Cache->cacheIndex->prev;
  110499. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  110500. + ++i, slot = slot->prev)
  110501. + {
  110502. + if (slot->logical == *Data)
  110503. + {
  110504. + /* Bail out. */
  110505. + next = slot;
  110506. + break;
  110507. + }
  110508. +
  110509. + /* Determine age of this slot. */
  110510. + if ((oldestSlot == gcvNULL)
  110511. + || (oldestSlot->stamp > slot->stamp)
  110512. + )
  110513. + {
  110514. + oldestSlot = slot;
  110515. + }
  110516. + }
  110517. + }
  110518. + }
  110519. +
  110520. + /* See if we had a miss. */
  110521. + if (next == gcvNULL)
  110522. + {
  110523. + if (Cache->cacheFree != 0)
  110524. + {
  110525. + slot = &Cache->cache[Cache->cacheFree];
  110526. + gcmkASSERT(slot->logical == gcvNULL);
  110527. +
  110528. + ++ Cache->cacheFree;
  110529. + if (Cache->cacheFree >= gcmCOUNTOF(Cache->cache))
  110530. + {
  110531. + Cache->cacheFree = 0;
  110532. + }
  110533. + }
  110534. + else
  110535. + {
  110536. + /* Use the oldest cache slot. */
  110537. + gcmkASSERT(oldestSlot != gcvNULL);
  110538. + slot = oldestSlot;
  110539. +
  110540. + /* Unlink from the chain. */
  110541. + slot->prev->next = slot->next;
  110542. + slot->next->prev = slot->prev;
  110543. +
  110544. + /* Append to the end. */
  110545. + slot->prev = Cache->cache[0].prev;
  110546. + slot->next = &Cache->cache[0];
  110547. + slot->prev->next = slot;
  110548. + slot->next->prev = slot;
  110549. + }
  110550. +
  110551. + /* Initialize the cache line. */
  110552. + slot->logical = *Data;
  110553. +
  110554. + /* Map the logical address to a DMA address. */
  110555. + gcmkONERROR(
  110556. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  110557. + }
  110558. +
  110559. + /* Save time stamp. */
  110560. + slot->stamp = ++ Cache->cacheStamp;
  110561. +
  110562. + /* Save current slot for next lookup. */
  110563. + Cache->cacheIndex = slot;
  110564. + }
  110565. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  110566. + {
  110567. + gctINT i;
  110568. + gctUINT32 data = gcmPTR2INT(*Data);
  110569. + gctUINT32 key, index;
  110570. + gcskLOGICAL_CACHE_PTR hash;
  110571. +
  110572. + /* Generate a hash key. */
  110573. + key = (data >> 24) + (data >> 16) + (data >> 8) + data;
  110574. + index = key % gcmCOUNTOF(Cache->hash);
  110575. +
  110576. + /* Get the hash entry. */
  110577. + hash = &Cache->hash[index];
  110578. +
  110579. + for (slot = hash->nextHash, i = 0;
  110580. + (slot != gcvNULL) && (i < gcdSECURE_CACHE_SLOTS);
  110581. + slot = slot->nextHash, ++i
  110582. + )
  110583. + {
  110584. + if (slot->logical == (*Data))
  110585. + {
  110586. + break;
  110587. + }
  110588. + }
  110589. +
  110590. + if (slot == gcvNULL)
  110591. + {
  110592. + /* Grab from the tail of the cache. */
  110593. + slot = Cache->cache[0].prev;
  110594. +
  110595. + /* Unlink slot from any hash table it is part of. */
  110596. + if (slot->prevHash != gcvNULL)
  110597. + {
  110598. + slot->prevHash->nextHash = slot->nextHash;
  110599. + }
  110600. + if (slot->nextHash != gcvNULL)
  110601. + {
  110602. + slot->nextHash->prevHash = slot->prevHash;
  110603. + }
  110604. +
  110605. + /* Initialize the cache line. */
  110606. + slot->logical = *Data;
  110607. +
  110608. + /* Map the logical address to a DMA address. */
  110609. + gcmkONERROR(
  110610. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  110611. +
  110612. + if (hash->nextHash != gcvNULL)
  110613. + {
  110614. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  110615. + "Hash Collision: logical=0x%x key=0x%08x",
  110616. + *Data, key);
  110617. + }
  110618. +
  110619. + /* Insert the slot at the head of the hash list. */
  110620. + slot->nextHash = hash->nextHash;
  110621. + if (slot->nextHash != gcvNULL)
  110622. + {
  110623. + slot->nextHash->prevHash = slot;
  110624. + }
  110625. + slot->prevHash = hash;
  110626. + hash->nextHash = slot;
  110627. + }
  110628. +
  110629. + /* Move slot to head of list. */
  110630. + if (slot != Cache->cache[0].next)
  110631. + {
  110632. + /* Unlink. */
  110633. + slot->prev->next = slot->next;
  110634. + slot->next->prev = slot->prev;
  110635. +
  110636. + /* Move to head of chain. */
  110637. + slot->prev = &Cache->cache[0];
  110638. + slot->next = Cache->cache[0].next;
  110639. + slot->prev->next = slot;
  110640. + slot->next->prev = slot;
  110641. + }
  110642. + }
  110643. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
  110644. + {
  110645. + gctUINT32 index = (gcmPTR2INT(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
  110646. +
  110647. + /* Get cache slot. */
  110648. + slot = &Cache->cache[index];
  110649. +
  110650. + /* Check for cache miss. */
  110651. + if (slot->logical != *Data)
  110652. + {
  110653. + /* Initialize the cache line. */
  110654. + slot->logical = *Data;
  110655. +
  110656. + /* Map the logical address to a DMA address. */
  110657. + gcmkONERROR(
  110658. + gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
  110659. + }
  110660. + }
  110661. +#endif
  110662. +
  110663. + /* Return DMA address. */
  110664. + *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
  110665. +
  110666. + /* Success. */
  110667. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  110668. + return gcvSTATUS_OK;
  110669. +
  110670. +OnError:
  110671. + /* Return the status. */
  110672. + gcmkFOOTER();
  110673. + return status;
  110674. +}
  110675. +
  110676. +gceSTATUS
  110677. +gckKERNEL_FlushTranslationCache(
  110678. + IN gckKERNEL Kernel,
  110679. + IN gcskSECURE_CACHE_PTR Cache,
  110680. + IN gctPOINTER Logical,
  110681. + IN gctSIZE_T Bytes
  110682. + )
  110683. +{
  110684. + gctINT i;
  110685. + gcskLOGICAL_CACHE_PTR slot;
  110686. + gctUINT8_PTR ptr;
  110687. +
  110688. + gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
  110689. + Kernel, Cache, Logical, Bytes);
  110690. +
  110691. + /* Do we need to flush the entire cache? */
  110692. + if (Logical == gcvNULL)
  110693. + {
  110694. + /* Clear all cache slots. */
  110695. + for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
  110696. + {
  110697. + Cache->cache[i].logical = gcvNULL;
  110698. +
  110699. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  110700. + Cache->cache[i].nextHash = gcvNULL;
  110701. + Cache->cache[i].prevHash = gcvNULL;
  110702. +#endif
  110703. +}
  110704. +
  110705. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  110706. + /* Zero the hash table. */
  110707. + for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
  110708. + {
  110709. + Cache->hash[i].nextHash = gcvNULL;
  110710. + }
  110711. +#endif
  110712. +
  110713. + /* Reset the cache functionality. */
  110714. + Cache->cacheIndex = gcvNULL;
  110715. + Cache->cacheFree = 1;
  110716. + Cache->cacheStamp = 0;
  110717. + }
  110718. +
  110719. + else
  110720. + {
  110721. + gctUINT8_PTR low = (gctUINT8_PTR) Logical;
  110722. + gctUINT8_PTR high = low + Bytes;
  110723. +
  110724. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
  110725. + gcskLOGICAL_CACHE_PTR next;
  110726. +
  110727. + /* Walk all used cache slots. */
  110728. + for (i = 1, slot = Cache->cache[0].next;
  110729. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  110730. + ++i, slot = next
  110731. + )
  110732. + {
  110733. + /* Save pointer to next slot. */
  110734. + next = slot->next;
  110735. +
  110736. + /* Test if this slot falls within the range to flush. */
  110737. + ptr = (gctUINT8_PTR) slot->logical;
  110738. + if ((ptr >= low) && (ptr < high))
  110739. + {
  110740. + /* Unlink slot. */
  110741. + slot->prev->next = slot->next;
  110742. + slot->next->prev = slot->prev;
  110743. +
  110744. + /* Append slot to tail of cache. */
  110745. + slot->prev = Cache->cache[0].prev;
  110746. + slot->next = &Cache->cache[0];
  110747. + slot->prev->next = slot;
  110748. + slot->next->prev = slot;
  110749. +
  110750. + /* Mark slot as empty. */
  110751. + slot->logical = gcvNULL;
  110752. + }
  110753. + }
  110754. +
  110755. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  110756. + gcskLOGICAL_CACHE_PTR next;
  110757. +
  110758. + for (i = 1, slot = Cache->cache[0].next;
  110759. + (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
  110760. + ++i, slot = next)
  110761. + {
  110762. + /* Save pointer to next slot. */
  110763. + next = slot->next;
  110764. +
  110765. + /* Test if this slot falls within the range to flush. */
  110766. + ptr = (gctUINT8_PTR) slot->logical;
  110767. + if ((ptr >= low) && (ptr < high))
  110768. + {
  110769. + /* Test if this slot is the current slot. */
  110770. + if (slot == Cache->cacheIndex)
  110771. + {
  110772. + /* Move to next or previous slot. */
  110773. + Cache->cacheIndex = (slot->next->logical != gcvNULL)
  110774. + ? slot->next
  110775. + : (slot->prev->logical != gcvNULL)
  110776. + ? slot->prev
  110777. + : gcvNULL;
  110778. + }
  110779. +
  110780. + /* Unlink slot from cache. */
  110781. + slot->prev->next = slot->next;
  110782. + slot->next->prev = slot->prev;
  110783. +
  110784. + /* Insert slot to head of cache. */
  110785. + slot->prev = &Cache->cache[0];
  110786. + slot->next = Cache->cache[0].next;
  110787. + slot->prev->next = slot;
  110788. + slot->next->prev = slot;
  110789. +
  110790. + /* Mark slot as empty. */
  110791. + slot->logical = gcvNULL;
  110792. + slot->stamp = 0;
  110793. + }
  110794. + }
  110795. +
  110796. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  110797. + gctINT j;
  110798. + gcskLOGICAL_CACHE_PTR hash, next;
  110799. +
  110800. + /* Walk all hash tables. */
  110801. + for (i = 0, hash = Cache->hash;
  110802. + i < gcmCOUNTOF(Cache->hash);
  110803. + ++i, ++hash)
  110804. + {
  110805. + /* Walk all slots in the hash. */
  110806. + for (j = 0, slot = hash->nextHash;
  110807. + (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
  110808. + ++j, slot = next)
  110809. + {
  110810. + /* Save pointer to next slot. */
  110811. + next = slot->next;
  110812. +
  110813. + /* Test if this slot falls within the range to flush. */
  110814. + ptr = (gctUINT8_PTR) slot->logical;
  110815. + if ((ptr >= low) && (ptr < high))
  110816. + {
  110817. + /* Unlink slot from hash table. */
  110818. + if (slot->prevHash == hash)
  110819. + {
  110820. + hash->nextHash = slot->nextHash;
  110821. + }
  110822. + else
  110823. + {
  110824. + slot->prevHash->nextHash = slot->nextHash;
  110825. + }
  110826. +
  110827. + if (slot->nextHash != gcvNULL)
  110828. + {
  110829. + slot->nextHash->prevHash = slot->prevHash;
  110830. + }
  110831. +
  110832. + /* Unlink slot from cache. */
  110833. + slot->prev->next = slot->next;
  110834. + slot->next->prev = slot->prev;
  110835. +
  110836. + /* Append slot to tail of cache. */
  110837. + slot->prev = Cache->cache[0].prev;
  110838. + slot->next = &Cache->cache[0];
  110839. + slot->prev->next = slot;
  110840. + slot->next->prev = slot;
  110841. +
  110842. + /* Mark slot as empty. */
  110843. + slot->logical = gcvNULL;
  110844. + slot->prevHash = gcvNULL;
  110845. + slot->nextHash = gcvNULL;
  110846. + }
  110847. + }
  110848. + }
  110849. +
  110850. +#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
  110851. + gctUINT32 index;
  110852. +
  110853. + /* Loop while inside the range. */
  110854. + for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
  110855. + {
  110856. + /* Get index into cache for this range. */
  110857. + index = (gcmPTR2INT(low) % gcdSECURE_CACHE_SLOTS) + 1;
  110858. + slot = &Cache->cache[index];
  110859. +
  110860. + /* Test if this slot falls within the range to flush. */
  110861. + ptr = (gctUINT8_PTR) slot->logical;
  110862. + if ((ptr >= low) && (ptr < high))
  110863. + {
  110864. + /* Remove entry from cache. */
  110865. + slot->logical = gcvNULL;
  110866. + }
  110867. +
  110868. + /* Next block. */
  110869. + low += gcdSECURE_CACHE_SLOTS;
  110870. + }
  110871. +#endif
  110872. + }
  110873. +
  110874. + /* Success. */
  110875. + gcmkFOOTER_NO();
  110876. + return gcvSTATUS_OK;
  110877. +}
  110878. +#endif
  110879. +
  110880. +/*******************************************************************************
  110881. +**
  110882. +** gckKERNEL_Recovery
  110883. +**
  110884. +** Try to recover the GPU from a fatal error.
  110885. +**
  110886. +** INPUT:
  110887. +**
  110888. +** gckKERNEL Kernel
  110889. +** Pointer to an gckKERNEL object.
  110890. +**
  110891. +** OUTPUT:
  110892. +**
  110893. +** Nothing.
  110894. +*/
  110895. +gceSTATUS
  110896. +gckKERNEL_Recovery(
  110897. + IN gckKERNEL Kernel
  110898. + )
  110899. +{
  110900. +#if gcdENABLE_RECOVERY
  110901. +#define gcdEVENT_MASK 0x3FFFFFFF
  110902. + gceSTATUS status;
  110903. + gckEVENT eventObj;
  110904. + gckHARDWARE hardware;
  110905. +#if gcdSECURE_USER
  110906. + gctUINT32 processID;
  110907. + gcskSECURE_CACHE_PTR cache;
  110908. +#endif
  110909. + gctUINT32 oldValue;
  110910. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  110911. +
  110912. + /* Validate the arguemnts. */
  110913. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  110914. +
  110915. + /* Grab gckEVENT object. */
  110916. + eventObj = Kernel->eventObj;
  110917. + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
  110918. +
  110919. + /* Grab gckHARDWARE object. */
  110920. + hardware = Kernel->hardware;
  110921. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  110922. +
  110923. +#if gcdSECURE_USER
  110924. + /* Flush the secure mapping cache. */
  110925. + gcmkONERROR(gckOS_GetProcessID(&processID));
  110926. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
  110927. + gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
  110928. +#endif
  110929. +
  110930. + gcmkONERROR(
  110931. + gckOS_AtomicExchange(Kernel->os, Kernel->resetAtom, 1, &oldValue));
  110932. +
  110933. + if (oldValue)
  110934. + {
  110935. + /* Some one else will recovery GPU. */
  110936. + return gcvSTATUS_OK;
  110937. + }
  110938. +
  110939. + gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
  110940. +
  110941. + /* Start a timer to clear reset flag, before timer is expired,
  110942. + ** other recovery request is ignored. */
  110943. + gcmkVERIFY_OK(
  110944. + gckOS_StartTimer(Kernel->os,
  110945. + Kernel->resetFlagClearTimer,
  110946. + gcdGPU_TIMEOUT - 500));
  110947. +
  110948. +
  110949. + /* Try issuing a soft reset for the GPU. */
  110950. + status = gckHARDWARE_Reset(hardware);
  110951. + if (status == gcvSTATUS_NOT_SUPPORTED)
  110952. + {
  110953. + /* Switch to OFF power. The next submit should return the GPU to ON
  110954. + ** state. */
  110955. + gcmkONERROR(
  110956. + gckHARDWARE_SetPowerManagementState(hardware,
  110957. + gcvPOWER_OFF_RECOVERY));
  110958. + }
  110959. + else
  110960. + {
  110961. + /* Bail out on reset error. */
  110962. + gcmkONERROR(status);
  110963. + }
  110964. +
  110965. + /* Handle all outstanding events now. */
  110966. +#if gcdSMP
  110967. + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
  110968. +#else
  110969. + eventObj->pending = gcdEVENT_MASK;
  110970. +#endif
  110971. + gcmkONERROR(gckEVENT_Notify(eventObj, 1));
  110972. +
  110973. + /* Again in case more events got submitted. */
  110974. +#if gcdSMP
  110975. + gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
  110976. +#else
  110977. + eventObj->pending = gcdEVENT_MASK;
  110978. +#endif
  110979. + gcmkONERROR(gckEVENT_Notify(eventObj, 2));
  110980. +
  110981. + Kernel->resetTimeStamp++;
  110982. +
  110983. + /* Success. */
  110984. + gcmkFOOTER_NO();
  110985. + return gcvSTATUS_OK;
  110986. +
  110987. +OnError:
  110988. + /* Return the status. */
  110989. + gcmkFOOTER();
  110990. + return status;
  110991. +#else
  110992. + return gcvSTATUS_OK;
  110993. +#endif
  110994. +}
  110995. +
  110996. +/*******************************************************************************
  110997. +**
  110998. +** gckKERNEL_OpenUserData
  110999. +**
  111000. +** Get access to the user data.
  111001. +**
  111002. +** INPUT:
  111003. +**
  111004. +** gckKERNEL Kernel
  111005. +** Pointer to an gckKERNEL object.
  111006. +**
  111007. +** gctBOOL NeedCopy
  111008. +** The flag indicating whether or not the data should be copied.
  111009. +**
  111010. +** gctPOINTER StaticStorage
  111011. +** Pointer to the kernel storage where the data is to be copied if
  111012. +** NeedCopy is gcvTRUE.
  111013. +**
  111014. +** gctPOINTER UserPointer
  111015. +** User pointer to the data.
  111016. +**
  111017. +** gctSIZE_T Size
  111018. +** Size of the data.
  111019. +**
  111020. +** OUTPUT:
  111021. +**
  111022. +** gctPOINTER * KernelPointer
  111023. +** Pointer to the kernel pointer that will be pointing to the data.
  111024. +*/
  111025. +gceSTATUS
  111026. +gckKERNEL_OpenUserData(
  111027. + IN gckKERNEL Kernel,
  111028. + IN gctBOOL NeedCopy,
  111029. + IN gctPOINTER StaticStorage,
  111030. + IN gctPOINTER UserPointer,
  111031. + IN gctSIZE_T Size,
  111032. + OUT gctPOINTER * KernelPointer
  111033. + )
  111034. +{
  111035. + gceSTATUS status;
  111036. +
  111037. + gcmkHEADER_ARG(
  111038. + "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X "
  111039. + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
  111040. + Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer
  111041. + );
  111042. +
  111043. + /* Validate the arguemnts. */
  111044. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  111045. + gcmkVERIFY_ARGUMENT(!NeedCopy || (StaticStorage != gcvNULL));
  111046. + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
  111047. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  111048. + gcmkVERIFY_ARGUMENT(Size > 0);
  111049. +
  111050. + if (NeedCopy)
  111051. + {
  111052. + /* Copy the user data to the static storage. */
  111053. + gcmkONERROR(gckOS_CopyFromUserData(
  111054. + Kernel->os, StaticStorage, UserPointer, Size
  111055. + ));
  111056. +
  111057. + /* Set the kernel pointer. */
  111058. + * KernelPointer = StaticStorage;
  111059. + }
  111060. + else
  111061. + {
  111062. + gctPOINTER pointer = gcvNULL;
  111063. +
  111064. + /* Map the user pointer. */
  111065. + gcmkONERROR(gckOS_MapUserPointer(
  111066. + Kernel->os, UserPointer, Size, &pointer
  111067. + ));
  111068. +
  111069. + /* Set the kernel pointer. */
  111070. + * KernelPointer = pointer;
  111071. + }
  111072. +
  111073. +OnError:
  111074. + /* Return the status. */
  111075. + gcmkFOOTER();
  111076. + return status;
  111077. +}
  111078. +
  111079. +/*******************************************************************************
  111080. +**
  111081. +** gckKERNEL_CloseUserData
  111082. +**
  111083. +** Release resources associated with the user data connection opened by
  111084. +** gckKERNEL_OpenUserData.
  111085. +**
  111086. +** INPUT:
  111087. +**
  111088. +** gckKERNEL Kernel
  111089. +** Pointer to an gckKERNEL object.
  111090. +**
  111091. +** gctBOOL NeedCopy
  111092. +** The flag indicating whether or not the data should be copied.
  111093. +**
  111094. +** gctBOOL FlushData
  111095. +** If gcvTRUE, the data is written back to the user.
  111096. +**
  111097. +** gctPOINTER UserPointer
  111098. +** User pointer to the data.
  111099. +**
  111100. +** gctSIZE_T Size
  111101. +** Size of the data.
  111102. +**
  111103. +** OUTPUT:
  111104. +**
  111105. +** gctPOINTER * KernelPointer
  111106. +** Kernel pointer to the data.
  111107. +*/
  111108. +gceSTATUS
  111109. +gckKERNEL_CloseUserData(
  111110. + IN gckKERNEL Kernel,
  111111. + IN gctBOOL NeedCopy,
  111112. + IN gctBOOL FlushData,
  111113. + IN gctPOINTER UserPointer,
  111114. + IN gctSIZE_T Size,
  111115. + OUT gctPOINTER * KernelPointer
  111116. + )
  111117. +{
  111118. + gceSTATUS status = gcvSTATUS_OK;
  111119. + gctPOINTER pointer;
  111120. +
  111121. + gcmkHEADER_ARG(
  111122. + "Kernel=0x%08X NeedCopy=%d FlushData=%d "
  111123. + "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
  111124. + Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
  111125. + );
  111126. +
  111127. + /* Validate the arguemnts. */
  111128. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  111129. + gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
  111130. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  111131. + gcmkVERIFY_ARGUMENT(Size > 0);
  111132. +
  111133. + /* Get a shortcut to the kernel pointer. */
  111134. + pointer = * KernelPointer;
  111135. +
  111136. + if (pointer != gcvNULL)
  111137. + {
  111138. + if (NeedCopy)
  111139. + {
  111140. + if (FlushData)
  111141. + {
  111142. + gcmkONERROR(gckOS_CopyToUserData(
  111143. + Kernel->os, * KernelPointer, UserPointer, Size
  111144. + ));
  111145. + }
  111146. + }
  111147. + else
  111148. + {
  111149. + /* Unmap record from kernel memory. */
  111150. + gcmkONERROR(gckOS_UnmapUserPointer(
  111151. + Kernel->os,
  111152. + UserPointer,
  111153. + Size,
  111154. + * KernelPointer
  111155. + ));
  111156. + }
  111157. +
  111158. + /* Reset the kernel pointer. */
  111159. + * KernelPointer = gcvNULL;
  111160. + }
  111161. +
  111162. +OnError:
  111163. + /* Return the status. */
  111164. + gcmkFOOTER();
  111165. + return status;
  111166. +}
  111167. +
  111168. +void
  111169. +gckKERNEL_SetTimeOut(
  111170. + IN gckKERNEL Kernel,
  111171. + IN gctUINT32 timeOut
  111172. + )
  111173. +{
  111174. + gcmkHEADER_ARG("Kernel=0x%x timeOut=%d", Kernel, timeOut);
  111175. +#if gcdGPU_TIMEOUT
  111176. + Kernel->timeOut = timeOut;
  111177. +#endif
  111178. + gcmkFOOTER_NO();
  111179. +}
  111180. +
  111181. +#if gcdVIRTUAL_COMMAND_BUFFER
  111182. +gceSTATUS
  111183. +gckKERNEL_AllocateVirtualCommandBuffer(
  111184. + IN gckKERNEL Kernel,
  111185. + IN gctBOOL InUserSpace,
  111186. + IN OUT gctSIZE_T * Bytes,
  111187. + OUT gctPHYS_ADDR * Physical,
  111188. + OUT gctPOINTER * Logical
  111189. + )
  111190. +{
  111191. + gckOS os = Kernel->os;
  111192. + gceSTATUS status;
  111193. + gctPOINTER logical;
  111194. + gctSIZE_T pageCount;
  111195. + gctSIZE_T bytes = *Bytes;
  111196. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  111197. +
  111198. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  111199. + os, InUserSpace, gcmOPT_VALUE(Bytes));
  111200. +
  111201. + /* Verify the arguments. */
  111202. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  111203. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  111204. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  111205. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  111206. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  111207. +
  111208. + gcmkONERROR(gckOS_Allocate(os,
  111209. + sizeof(gckVIRTUAL_COMMAND_BUFFER),
  111210. + (gctPOINTER)&buffer));
  111211. +
  111212. + gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
  111213. +
  111214. + gcmkONERROR(gckOS_AllocatePagedMemoryEx(os,
  111215. + gcvFALSE,
  111216. + bytes,
  111217. + &buffer->physical));
  111218. +
  111219. + if (InUserSpace)
  111220. + {
  111221. + gcmkONERROR(gckOS_LockPages(os,
  111222. + buffer->physical,
  111223. + bytes,
  111224. + gcvFALSE,
  111225. + &logical,
  111226. + &pageCount));
  111227. +
  111228. + *Logical =
  111229. + buffer->userLogical = logical;
  111230. + }
  111231. + else
  111232. + {
  111233. + gcmkONERROR(
  111234. + gckOS_CreateKernelVirtualMapping(buffer->physical,
  111235. + &pageCount,
  111236. + &logical));
  111237. + *Logical =
  111238. + buffer->kernelLogical = logical;
  111239. + }
  111240. +
  111241. + buffer->pageCount = pageCount;
  111242. + buffer->kernel = Kernel;
  111243. +
  111244. + gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
  111245. +
  111246. + gcmkONERROR(gckMMU_AllocatePages(Kernel->mmu,
  111247. + pageCount,
  111248. + &buffer->pageTable,
  111249. + &buffer->gpuAddress));
  111250. +
  111251. + gcmkONERROR(gckOS_MapPagesEx(os,
  111252. + Kernel->core,
  111253. + buffer->physical,
  111254. + pageCount,
  111255. + buffer->pageTable));
  111256. +
  111257. + gcmkONERROR(gckMMU_Flush(Kernel->mmu));
  111258. +
  111259. + *Physical = buffer;
  111260. +
  111261. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
  111262. + "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
  111263. + buffer->gpuAddress, buffer->pageCount,
  111264. + buffer->kernelLogical, buffer->userLogical);
  111265. +
  111266. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
  111267. +
  111268. + if (Kernel->virtualBufferHead == gcvNULL)
  111269. + {
  111270. + Kernel->virtualBufferHead =
  111271. + Kernel->virtualBufferTail = buffer;
  111272. + }
  111273. + else
  111274. + {
  111275. + buffer->prev = Kernel->virtualBufferTail;
  111276. + Kernel->virtualBufferTail->next = buffer;
  111277. + Kernel->virtualBufferTail = buffer;
  111278. + }
  111279. +
  111280. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
  111281. +
  111282. + gcmkFOOTER_NO();
  111283. + return gcvSTATUS_OK;
  111284. +
  111285. +OnError:
  111286. + if (buffer->gpuAddress)
  111287. + {
  111288. + gcmkVERIFY_OK(
  111289. + gckMMU_FreePages(Kernel->mmu, buffer->pageTable, buffer->pageCount));
  111290. + }
  111291. +
  111292. + if (buffer->userLogical)
  111293. + {
  111294. + gcmkVERIFY_OK(
  111295. + gckOS_UnlockPages(os, buffer->physical, bytes, buffer->userLogical));
  111296. + }
  111297. +
  111298. + if (buffer->kernelLogical)
  111299. + {
  111300. + gcmkVERIFY_OK(
  111301. + gckOS_DestroyKernelVirtualMapping(buffer->kernelLogical));
  111302. + }
  111303. +
  111304. + if (buffer->physical)
  111305. + {
  111306. + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
  111307. + }
  111308. +
  111309. + gcmkVERIFY_OK(gckOS_Free(os, buffer));
  111310. +
  111311. + /* Return the status. */
  111312. + gcmkFOOTER();
  111313. + return status;
  111314. +}
  111315. +
  111316. +gceSTATUS
  111317. +gckKERNEL_DestroyVirtualCommandBuffer(
  111318. + IN gckKERNEL Kernel,
  111319. + IN gctSIZE_T Bytes,
  111320. + IN gctPHYS_ADDR Physical,
  111321. + IN gctPOINTER Logical
  111322. + )
  111323. +{
  111324. + gckOS os;
  111325. + gckKERNEL kernel;
  111326. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
  111327. +
  111328. + gcmkHEADER();
  111329. + gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
  111330. +
  111331. + kernel = buffer->kernel;
  111332. + os = kernel->os;
  111333. +
  111334. + if (buffer->userLogical)
  111335. + {
  111336. + gcmkVERIFY_OK(gckOS_UnlockPages(os, buffer->physical, Bytes, Logical));
  111337. + }
  111338. + else
  111339. + {
  111340. + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(Logical));
  111341. + }
  111342. +
  111343. + gcmkVERIFY_OK(
  111344. + gckMMU_FreePages(kernel->mmu, buffer->pageTable, buffer->pageCount));
  111345. +
  111346. + gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, Bytes));
  111347. +
  111348. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
  111349. +
  111350. + if (buffer == kernel->virtualBufferHead)
  111351. + {
  111352. + if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
  111353. + {
  111354. + kernel->virtualBufferTail = gcvNULL;
  111355. + }
  111356. + }
  111357. + else
  111358. + {
  111359. + buffer->prev->next = buffer->next;
  111360. +
  111361. + if (buffer == kernel->virtualBufferTail)
  111362. + {
  111363. + kernel->virtualBufferTail = buffer->prev;
  111364. + }
  111365. + else
  111366. + {
  111367. + buffer->next->prev = buffer->prev;
  111368. + }
  111369. + }
  111370. +
  111371. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
  111372. +
  111373. + gcmkVERIFY_OK(gckOS_Free(os, buffer));
  111374. +
  111375. + gcmkFOOTER_NO();
  111376. + return gcvSTATUS_OK;
  111377. +}
  111378. +
  111379. +gceSTATUS
  111380. +gckKERNEL_GetGPUAddress(
  111381. + IN gckKERNEL Kernel,
  111382. + IN gctPOINTER Logical,
  111383. + OUT gctUINT32 * Address
  111384. + )
  111385. +{
  111386. + gceSTATUS status;
  111387. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  111388. + gctPOINTER start;
  111389. + gctINT pid;
  111390. +
  111391. + gcmkHEADER_ARG("Logical = %x", Logical);
  111392. +
  111393. + gckOS_GetProcessID(&pid);
  111394. +
  111395. + status = gcvSTATUS_INVALID_ADDRESS;
  111396. +
  111397. + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
  111398. +
  111399. + /* Walk all command buffer. */
  111400. + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
  111401. + {
  111402. + if (buffer->userLogical)
  111403. + {
  111404. + start = buffer->userLogical;
  111405. + }
  111406. + else
  111407. + {
  111408. + start = buffer->kernelLogical;
  111409. + }
  111410. +
  111411. + if (Logical >= start
  111412. + && (Logical < (start + buffer->pageCount * 4096))
  111413. + && pid == buffer->pid
  111414. + )
  111415. + {
  111416. + * Address = buffer->gpuAddress + (Logical - start);
  111417. + status = gcvSTATUS_OK;
  111418. + break;
  111419. + }
  111420. + }
  111421. +
  111422. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
  111423. +
  111424. + gcmkFOOTER_NO();
  111425. + return status;
  111426. +}
  111427. +
  111428. +gceSTATUS
  111429. +gckKERNEL_QueryGPUAddress(
  111430. + IN gckKERNEL Kernel,
  111431. + IN gctUINT32 GpuAddress,
  111432. + OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
  111433. + )
  111434. +{
  111435. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  111436. + gctUINT32 start;
  111437. + gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
  111438. +
  111439. + gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
  111440. +
  111441. + /* Walk all command buffers. */
  111442. + for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
  111443. + {
  111444. + start = (gctUINT32)buffer->gpuAddress;
  111445. +
  111446. + if (GpuAddress >= start && GpuAddress < (start + buffer->pageCount * 4096))
  111447. + {
  111448. + /* Find a range matched. */
  111449. + *Buffer = buffer;
  111450. + status = gcvSTATUS_OK;
  111451. + break;
  111452. + }
  111453. + }
  111454. +
  111455. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
  111456. +
  111457. + return status;
  111458. +}
  111459. +#endif
  111460. +
  111461. +#if gcdLINK_QUEUE_SIZE
  111462. +static void
  111463. +gckLINKQUEUE_Dequeue(
  111464. + IN gckLINKQUEUE LinkQueue
  111465. + )
  111466. +{
  111467. + gcmkASSERT(LinkQueue->count == gcdLINK_QUEUE_SIZE);
  111468. +
  111469. + LinkQueue->count--;
  111470. + LinkQueue->front = (LinkQueue->front + 1) % gcdLINK_QUEUE_SIZE;
  111471. +}
  111472. +
  111473. +void
  111474. +gckLINKQUEUE_Enqueue(
  111475. + IN gckLINKQUEUE LinkQueue,
  111476. + IN gctUINT32 start,
  111477. + IN gctUINT32 end
  111478. + )
  111479. +{
  111480. + if (LinkQueue->count == gcdLINK_QUEUE_SIZE)
  111481. + {
  111482. + gckLINKQUEUE_Dequeue(LinkQueue);
  111483. + }
  111484. +
  111485. + gcmkASSERT(LinkQueue->count < gcdLINK_QUEUE_SIZE);
  111486. +
  111487. + LinkQueue->count++;
  111488. +
  111489. + LinkQueue->data[LinkQueue->rear].start = start;
  111490. + LinkQueue->data[LinkQueue->rear].end = end;
  111491. +
  111492. + gcmkVERIFY_OK(
  111493. + gckOS_GetProcessID(&LinkQueue->data[LinkQueue->rear].pid));
  111494. +
  111495. + LinkQueue->rear = (LinkQueue->rear + 1) % gcdLINK_QUEUE_SIZE;
  111496. +}
  111497. +
  111498. +void
  111499. +gckLINKQUEUE_GetData(
  111500. + IN gckLINKQUEUE LinkQueue,
  111501. + IN gctUINT32 Index,
  111502. + OUT gckLINKDATA * Data
  111503. + )
  111504. +{
  111505. + gcmkASSERT(Index >= 0 && Index < gcdLINK_QUEUE_SIZE);
  111506. +
  111507. + *Data = &LinkQueue->data[(Index + LinkQueue->front) % gcdLINK_QUEUE_SIZE];
  111508. +}
  111509. +#endif
  111510. +
  111511. +/******************************************************************************\
  111512. +*************************** Pointer - ID translation ***************************
  111513. +\******************************************************************************/
  111514. +#define gcdID_TABLE_LENGTH 1024
  111515. +typedef struct _gcsINTEGERDB * gckINTEGERDB;
  111516. +typedef struct _gcsINTEGERDB
  111517. +{
  111518. + gckOS os;
  111519. + gctPOINTER* table;
  111520. + gctPOINTER mutex;
  111521. + gctUINT32 tableLen;
  111522. + gctUINT32 currentID;
  111523. + gctUINT32 unused;
  111524. +}
  111525. +gcsINTEGERDB;
  111526. +
  111527. +gceSTATUS
  111528. +gckKERNEL_CreateIntegerDatabase(
  111529. + IN gckKERNEL Kernel,
  111530. + OUT gctPOINTER * Database
  111531. + )
  111532. +{
  111533. + gceSTATUS status;
  111534. + gckINTEGERDB database = gcvNULL;
  111535. +
  111536. + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
  111537. +
  111538. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  111539. + gcmkVERIFY_ARGUMENT(Database != gcvNULL);
  111540. +
  111541. + /* Allocate a database. */
  111542. + gcmkONERROR(gckOS_Allocate(
  111543. + Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database));
  111544. +
  111545. + gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB));
  111546. +
  111547. + /* Allocate a pointer table. */
  111548. + gcmkONERROR(gckOS_Allocate(
  111549. + Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table));
  111550. +
  111551. + gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
  111552. +
  111553. + /* Allocate a database mutex. */
  111554. + gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex));
  111555. +
  111556. + /* Initialize. */
  111557. + database->currentID = 0;
  111558. + database->unused = gcdID_TABLE_LENGTH;
  111559. + database->os = Kernel->os;
  111560. + database->tableLen = gcdID_TABLE_LENGTH;
  111561. +
  111562. + *Database = database;
  111563. +
  111564. + gcmkFOOTER_ARG("*Database=0x%08X", *Database);
  111565. + return gcvSTATUS_OK;
  111566. +
  111567. +OnError:
  111568. + /* Rollback. */
  111569. + if (database)
  111570. + {
  111571. + if (database->table)
  111572. + {
  111573. + gcmkOS_SAFE_FREE(Kernel->os, database->table);
  111574. + }
  111575. +
  111576. + gcmkOS_SAFE_FREE(Kernel->os, database);
  111577. + }
  111578. +
  111579. + gcmkFOOTER();
  111580. + return status;
  111581. +}
  111582. +
  111583. +gceSTATUS
  111584. +gckKERNEL_DestroyIntegerDatabase(
  111585. + IN gckKERNEL Kernel,
  111586. + IN gctPOINTER Database
  111587. + )
  111588. +{
  111589. + gckINTEGERDB database = Database;
  111590. +
  111591. + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
  111592. +
  111593. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  111594. + gcmkVERIFY_ARGUMENT(Database != gcvNULL);
  111595. +
  111596. + /* Destroy pointer table. */
  111597. + gcmkOS_SAFE_FREE(Kernel->os, database->table);
  111598. +
  111599. + /* Destroy database mutex. */
  111600. + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex));
  111601. +
  111602. + /* Destroy database. */
  111603. + gcmkOS_SAFE_FREE(Kernel->os, database);
  111604. +
  111605. + gcmkFOOTER_NO();
  111606. + return gcvSTATUS_OK;
  111607. +}
  111608. +
  111609. +gceSTATUS
  111610. +gckKERNEL_AllocateIntegerId(
  111611. + IN gctPOINTER Database,
  111612. + IN gctPOINTER Pointer,
  111613. + OUT gctUINT32 * Id
  111614. + )
  111615. +{
  111616. + gceSTATUS status;
  111617. + gckINTEGERDB database = Database;
  111618. + gctUINT32 i, unused, currentID, tableLen;
  111619. + gctPOINTER * table;
  111620. + gckOS os = database->os;
  111621. + gctBOOL acquired = gcvFALSE;
  111622. +
  111623. + gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer);
  111624. +
  111625. + gcmkVERIFY_ARGUMENT(Id != gcvNULL);
  111626. +
  111627. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  111628. + acquired = gcvTRUE;
  111629. +
  111630. + if (database->unused < 1)
  111631. + {
  111632. + /* Extend table. */
  111633. + gcmkONERROR(
  111634. + gckOS_Allocate(os,
  111635. + gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH),
  111636. + (gctPOINTER *)&table));
  111637. +
  111638. + gckOS_ZeroMemory(table + database->tableLen,
  111639. + gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH);
  111640. +
  111641. + /* Copy data from old table. */
  111642. + gckOS_MemCopy(table,
  111643. + database->table,
  111644. + database->tableLen * gcmSIZEOF(gctPOINTER));
  111645. +
  111646. + gcmkOS_SAFE_FREE(os, database->table);
  111647. +
  111648. + /* Update databse with new allocated table. */
  111649. + database->table = table;
  111650. + database->currentID = database->tableLen;
  111651. + database->tableLen += gcdID_TABLE_LENGTH;
  111652. + database->unused += gcdID_TABLE_LENGTH;
  111653. + }
  111654. +
  111655. + table = database->table;
  111656. + currentID = database->currentID;
  111657. + tableLen = database->tableLen;
  111658. + unused = database->unused;
  111659. +
  111660. + /* Connect id with pointer. */
  111661. + table[currentID] = Pointer;
  111662. +
  111663. + *Id = currentID + 1;
  111664. +
  111665. + /* Update the currentID. */
  111666. + if (--unused > 0)
  111667. + {
  111668. + for (i = 0; i < tableLen; i++)
  111669. + {
  111670. + if (++currentID >= tableLen)
  111671. + {
  111672. + /* Wrap to the begin. */
  111673. + currentID = 0;
  111674. + }
  111675. +
  111676. + if (table[currentID] == gcvNULL)
  111677. + {
  111678. + break;
  111679. + }
  111680. + }
  111681. + }
  111682. +
  111683. + database->table = table;
  111684. + database->currentID = currentID;
  111685. + database->tableLen = tableLen;
  111686. + database->unused = unused;
  111687. +
  111688. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  111689. + acquired = gcvFALSE;
  111690. +
  111691. + gcmkFOOTER_ARG("*Id=%d", *Id);
  111692. + return gcvSTATUS_OK;
  111693. +
  111694. +OnError:
  111695. + if (acquired)
  111696. + {
  111697. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  111698. + }
  111699. +
  111700. + gcmkFOOTER();
  111701. + return status;
  111702. +}
  111703. +
  111704. +gceSTATUS
  111705. +gckKERNEL_FreeIntegerId(
  111706. + IN gctPOINTER Database,
  111707. + IN gctUINT32 Id
  111708. + )
  111709. +{
  111710. + gceSTATUS status;
  111711. + gckINTEGERDB database = Database;
  111712. + gckOS os = database->os;
  111713. + gctBOOL acquired = gcvFALSE;
  111714. +
  111715. + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
  111716. +
  111717. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  111718. + acquired = gcvTRUE;
  111719. +
  111720. + if (!(Id > 0 && Id <= database->tableLen))
  111721. + {
  111722. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  111723. + }
  111724. +
  111725. + Id -= 1;
  111726. +
  111727. + database->table[Id] = gcvNULL;
  111728. +
  111729. + if (database->unused++ == 0)
  111730. + {
  111731. + database->currentID = Id;
  111732. + }
  111733. +
  111734. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  111735. + acquired = gcvFALSE;
  111736. +
  111737. + gcmkFOOTER_NO();
  111738. + return gcvSTATUS_OK;
  111739. +
  111740. +OnError:
  111741. + if (acquired)
  111742. + {
  111743. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  111744. + }
  111745. +
  111746. + gcmkFOOTER();
  111747. + return status;
  111748. +}
  111749. +
  111750. +gceSTATUS
  111751. +gckKERNEL_QueryIntegerId(
  111752. + IN gctPOINTER Database,
  111753. + IN gctUINT32 Id,
  111754. + OUT gctPOINTER * Pointer
  111755. + )
  111756. +{
  111757. + gceSTATUS status;
  111758. + gckINTEGERDB database = Database;
  111759. + gctPOINTER pointer;
  111760. + gckOS os = database->os;
  111761. + gctBOOL acquired = gcvFALSE;
  111762. +
  111763. + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
  111764. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  111765. +
  111766. + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
  111767. + acquired = gcvTRUE;
  111768. +
  111769. + if (!(Id > 0 && Id <= database->tableLen))
  111770. + {
  111771. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  111772. + }
  111773. +
  111774. + Id -= 1;
  111775. +
  111776. + pointer = database->table[Id];
  111777. +
  111778. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  111779. + acquired = gcvFALSE;
  111780. +
  111781. + if (pointer)
  111782. + {
  111783. + *Pointer = pointer;
  111784. + }
  111785. + else
  111786. + {
  111787. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  111788. + }
  111789. +
  111790. + gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer);
  111791. + return gcvSTATUS_OK;
  111792. +
  111793. +OnError:
  111794. + if (acquired)
  111795. + {
  111796. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
  111797. + }
  111798. +
  111799. + gcmkFOOTER();
  111800. + return status;
  111801. +}
  111802. +
  111803. +
  111804. +gctUINT32
  111805. +gckKERNEL_AllocateNameFromPointer(
  111806. + IN gckKERNEL Kernel,
  111807. + IN gctPOINTER Pointer
  111808. + )
  111809. +{
  111810. + gceSTATUS status;
  111811. + gctUINT32 name;
  111812. + gctPOINTER database = Kernel->db->pointerDatabase;
  111813. +
  111814. + gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer);
  111815. +
  111816. + gcmkONERROR(
  111817. + gckKERNEL_AllocateIntegerId(database, Pointer, &name));
  111818. +
  111819. + gcmkFOOTER_ARG("name=%d", name);
  111820. + return name;
  111821. +
  111822. +OnError:
  111823. + gcmkFOOTER();
  111824. + return 0;
  111825. +}
  111826. +
  111827. +gctPOINTER
  111828. +gckKERNEL_QueryPointerFromName(
  111829. + IN gckKERNEL Kernel,
  111830. + IN gctUINT32 Name
  111831. + )
  111832. +{
  111833. + gceSTATUS status;
  111834. + gctPOINTER pointer = gcvNULL;
  111835. + gctPOINTER database = Kernel->db->pointerDatabase;
  111836. +
  111837. + gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
  111838. +
  111839. + /* Lookup in database to get pointer. */
  111840. + gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer));
  111841. +
  111842. + gcmkFOOTER_ARG("pointer=0x%X", pointer);
  111843. + return pointer;
  111844. +
  111845. +OnError:
  111846. + gcmkFOOTER();
  111847. + return gcvNULL;
  111848. +}
  111849. +
  111850. +gceSTATUS
  111851. +gckKERNEL_DeleteName(
  111852. + IN gckKERNEL Kernel,
  111853. + IN gctUINT32 Name
  111854. + )
  111855. +{
  111856. + gctPOINTER database = Kernel->db->pointerDatabase;
  111857. +
  111858. + gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name);
  111859. +
  111860. + /* Free name if exists. */
  111861. + gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name));
  111862. +
  111863. + gcmkFOOTER_NO();
  111864. + return gcvSTATUS_OK;
  111865. +}
  111866. +/*******************************************************************************
  111867. +***** Test Code ****************************************************************
  111868. +*******************************************************************************/
  111869. +
  111870. diff -Nur linux-3.14.17/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
  111871. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c 1970-01-01 01:00:00.000000000 +0100
  111872. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c 2014-09-11 18:06:03.082042291 +0200
  111873. @@ -0,0 +1,3042 @@
  111874. +/****************************************************************************
  111875. +*
  111876. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  111877. +*
  111878. +* This program is free software; you can redistribute it and/or modify
  111879. +* it under the terms of the GNU General Public License as published by
  111880. +* the Free Software Foundation; either version 2 of the license, or
  111881. +* (at your option) any later version.
  111882. +*
  111883. +* This program is distributed in the hope that it will be useful,
  111884. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  111885. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  111886. +* GNU General Public License for more details.
  111887. +*
  111888. +* You should have received a copy of the GNU General Public License
  111889. +* along with this program; if not write to the Free Software
  111890. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  111891. +*
  111892. +*****************************************************************************/
  111893. +
  111894. +
  111895. +#include "gc_hal_kernel_precomp.h"
  111896. +#include "gc_hal_kernel_context.h"
  111897. +
  111898. +#ifdef __QNXNTO__
  111899. +#include <sys/slog.h>
  111900. +#endif
  111901. +
  111902. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  111903. +
  111904. +/******************************************************************************\
  111905. +********************************* Support Code *********************************
  111906. +\******************************************************************************/
  111907. +
  111908. +/*******************************************************************************
  111909. +**
  111910. +** _NewQueue
  111911. +**
  111912. +** Allocate a new command queue.
  111913. +**
  111914. +** INPUT:
  111915. +**
  111916. +** gckCOMMAND Command
  111917. +** Pointer to an gckCOMMAND object.
  111918. +**
  111919. +** OUTPUT:
  111920. +**
  111921. +** gckCOMMAND Command
  111922. +** gckCOMMAND object has been updated with a new command queue.
  111923. +*/
  111924. +static gceSTATUS
  111925. +_NewQueue(
  111926. + IN OUT gckCOMMAND Command
  111927. + )
  111928. +{
  111929. + gceSTATUS status;
  111930. + gctINT currentIndex, newIndex;
  111931. +
  111932. + gcmkHEADER_ARG("Command=0x%x", Command);
  111933. +
  111934. + /* Switch to the next command buffer. */
  111935. + currentIndex = Command->index;
  111936. + newIndex = (currentIndex + 1) % gcdCOMMAND_QUEUES;
  111937. +
  111938. + /* Wait for availability. */
  111939. +#if gcdDUMP_COMMAND
  111940. + gcmkPRINT("@[kernel.waitsignal]");
  111941. +#endif
  111942. +
  111943. + gcmkONERROR(gckOS_WaitSignal(
  111944. + Command->os,
  111945. + Command->queues[newIndex].signal,
  111946. + gcvINFINITE
  111947. + ));
  111948. +
  111949. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  111950. + if (newIndex < currentIndex)
  111951. + {
  111952. + Command->wrapCount += 1;
  111953. +
  111954. + gcmkTRACE_ZONE_N(
  111955. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  111956. + 2 * 4,
  111957. + "%s(%d): queue array wrapped around.\n",
  111958. + __FUNCTION__, __LINE__
  111959. + );
  111960. + }
  111961. +
  111962. + gcmkTRACE_ZONE_N(
  111963. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  111964. + 3 * 4,
  111965. + "%s(%d): total queue wrap arounds %d.\n",
  111966. + __FUNCTION__, __LINE__, Command->wrapCount
  111967. + );
  111968. +
  111969. + gcmkTRACE_ZONE_N(
  111970. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  111971. + 3 * 4,
  111972. + "%s(%d): switched to queue %d.\n",
  111973. + __FUNCTION__, __LINE__, newIndex
  111974. + );
  111975. +#endif
  111976. +
  111977. + /* Update gckCOMMAND object with new command queue. */
  111978. + Command->index = newIndex;
  111979. + Command->newQueue = gcvTRUE;
  111980. + Command->logical = Command->queues[newIndex].logical;
  111981. + Command->offset = 0;
  111982. +
  111983. + gcmkONERROR(
  111984. + gckOS_GetPhysicalAddress(
  111985. + Command->os,
  111986. + Command->logical,
  111987. + (gctUINT32 *) &Command->physical
  111988. + ));
  111989. +
  111990. + if (currentIndex != -1)
  111991. + {
  111992. + /* Mark the command queue as available. */
  111993. + gcmkONERROR(gckEVENT_Signal(
  111994. + Command->kernel->eventObj,
  111995. + Command->queues[currentIndex].signal,
  111996. + gcvKERNEL_COMMAND
  111997. + ));
  111998. + }
  111999. +
  112000. + /* Success. */
  112001. + gcmkFOOTER_ARG("Command->index=%d", Command->index);
  112002. + return gcvSTATUS_OK;
  112003. +
  112004. +OnError:
  112005. + /* Return the status. */
  112006. + gcmkFOOTER();
  112007. + return status;
  112008. +}
  112009. +
  112010. +static gceSTATUS
  112011. +_IncrementCommitAtom(
  112012. + IN gckCOMMAND Command,
  112013. + IN gctBOOL Increment
  112014. + )
  112015. +{
  112016. + gceSTATUS status;
  112017. + gckHARDWARE hardware;
  112018. + gctINT32 atomValue;
  112019. + gctBOOL powerAcquired = gcvFALSE;
  112020. +
  112021. + gcmkHEADER_ARG("Command=0x%x", Command);
  112022. +
  112023. + /* Extract the gckHARDWARE and gckEVENT objects. */
  112024. + hardware = Command->kernel->hardware;
  112025. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  112026. +
  112027. + /* Grab the power mutex. */
  112028. + gcmkONERROR(gckOS_AcquireMutex(
  112029. + Command->os, hardware->powerMutex, gcvINFINITE
  112030. + ));
  112031. + powerAcquired = gcvTRUE;
  112032. +
  112033. + /* Increment the commit atom. */
  112034. + if (Increment)
  112035. + {
  112036. + gcmkONERROR(gckOS_AtomIncrement(
  112037. + Command->os, Command->atomCommit, &atomValue
  112038. + ));
  112039. + }
  112040. + else
  112041. + {
  112042. + gcmkONERROR(gckOS_AtomDecrement(
  112043. + Command->os, Command->atomCommit, &atomValue
  112044. + ));
  112045. + }
  112046. +
  112047. + /* Release the power mutex. */
  112048. + gcmkONERROR(gckOS_ReleaseMutex(
  112049. + Command->os, hardware->powerMutex
  112050. + ));
  112051. + powerAcquired = gcvFALSE;
  112052. +
  112053. + /* Success. */
  112054. + gcmkFOOTER();
  112055. + return gcvSTATUS_OK;
  112056. +
  112057. +OnError:
  112058. + if (powerAcquired)
  112059. + {
  112060. + /* Release the power mutex. */
  112061. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  112062. + Command->os, hardware->powerMutex
  112063. + ));
  112064. + }
  112065. +
  112066. + /* Return the status. */
  112067. + gcmkFOOTER();
  112068. + return status;
  112069. +}
  112070. +
  112071. +#if gcdSECURE_USER
  112072. +static gceSTATUS
  112073. +_ProcessHints(
  112074. + IN gckCOMMAND Command,
  112075. + IN gctUINT32 ProcessID,
  112076. + IN gcoCMDBUF CommandBuffer
  112077. + )
  112078. +{
  112079. + gceSTATUS status = gcvSTATUS_OK;
  112080. + gckKERNEL kernel;
  112081. + gctBOOL needCopy = gcvFALSE;
  112082. + gcskSECURE_CACHE_PTR cache;
  112083. + gctUINT8_PTR commandBufferLogical;
  112084. + gctUINT8_PTR hintedData;
  112085. + gctUINT32_PTR hintArray;
  112086. + gctUINT i, hintCount;
  112087. +
  112088. + gcmkHEADER_ARG(
  112089. + "Command=0x%08X ProcessID=%d CommandBuffer=0x%08X",
  112090. + Command, ProcessID, CommandBuffer
  112091. + );
  112092. +
  112093. + /* Verify the arguments. */
  112094. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112095. +
  112096. + /* Reset state array pointer. */
  112097. + hintArray = gcvNULL;
  112098. +
  112099. + /* Get the kernel object. */
  112100. + kernel = Command->kernel;
  112101. +
  112102. + /* Get the cache form the database. */
  112103. + gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
  112104. +
  112105. + /* Determine the start of the command buffer. */
  112106. + commandBufferLogical
  112107. + = (gctUINT8_PTR) CommandBuffer->logical
  112108. + + CommandBuffer->startOffset;
  112109. +
  112110. + /* Determine the number of records in the state array. */
  112111. + hintCount = CommandBuffer->hintArrayTail - CommandBuffer->hintArray;
  112112. +
  112113. + /* Check wehther we need to copy the structures or not. */
  112114. + gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
  112115. +
  112116. + /* Get access to the state array. */
  112117. + if (needCopy)
  112118. + {
  112119. + gctUINT copySize;
  112120. +
  112121. + if (Command->hintArrayAllocated &&
  112122. + (Command->hintArraySize < CommandBuffer->hintArraySize))
  112123. + {
  112124. + gcmkONERROR(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
  112125. + Command->hintArraySize = gcvFALSE;
  112126. + }
  112127. +
  112128. + if (!Command->hintArrayAllocated)
  112129. + {
  112130. + gctPOINTER pointer = gcvNULL;
  112131. +
  112132. + gcmkONERROR(gckOS_Allocate(
  112133. + Command->os,
  112134. + CommandBuffer->hintArraySize,
  112135. + &pointer
  112136. + ));
  112137. +
  112138. + Command->hintArray = gcmPTR_TO_UINT64(pointer);
  112139. + Command->hintArrayAllocated = gcvTRUE;
  112140. + Command->hintArraySize = CommandBuffer->hintArraySize;
  112141. + }
  112142. +
  112143. + hintArray = gcmUINT64_TO_PTR(Command->hintArray);
  112144. + copySize = hintCount * gcmSIZEOF(gctUINT32);
  112145. +
  112146. + gcmkONERROR(gckOS_CopyFromUserData(
  112147. + Command->os,
  112148. + hintArray,
  112149. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  112150. + copySize
  112151. + ));
  112152. + }
  112153. + else
  112154. + {
  112155. + gctPOINTER pointer = gcvNULL;
  112156. +
  112157. + gcmkONERROR(gckOS_MapUserPointer(
  112158. + Command->os,
  112159. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  112160. + CommandBuffer->hintArraySize,
  112161. + &pointer
  112162. + ));
  112163. +
  112164. + hintArray = pointer;
  112165. + }
  112166. +
  112167. + /* Scan through the buffer. */
  112168. + for (i = 0; i < hintCount; i += 1)
  112169. + {
  112170. + /* Determine the location of the hinted data. */
  112171. + hintedData = commandBufferLogical + hintArray[i];
  112172. +
  112173. + /* Map handle into physical address. */
  112174. + gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
  112175. + kernel, cache, (gctPOINTER) hintedData
  112176. + ));
  112177. + }
  112178. +
  112179. +OnError:
  112180. + /* Get access to the state array. */
  112181. + if (!needCopy && (hintArray != gcvNULL))
  112182. + {
  112183. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  112184. + Command->os,
  112185. + gcmUINT64_TO_PTR(CommandBuffer->hintArray),
  112186. + CommandBuffer->hintArraySize,
  112187. + hintArray
  112188. + ));
  112189. + }
  112190. +
  112191. + /* Return the status. */
  112192. + gcmkFOOTER();
  112193. + return status;
  112194. +}
  112195. +#endif
  112196. +
  112197. +static gceSTATUS
  112198. +_FlushMMU(
  112199. + IN gckCOMMAND Command
  112200. + )
  112201. +{
  112202. + gceSTATUS status;
  112203. + gctUINT32 oldValue;
  112204. + gckHARDWARE hardware = Command->kernel->hardware;
  112205. +
  112206. + gcmkONERROR(gckOS_AtomicExchange(Command->os,
  112207. + hardware->pageTableDirty,
  112208. + 0,
  112209. + &oldValue));
  112210. +
  112211. + if (oldValue)
  112212. + {
  112213. + /* Page Table is upated, flush mmu before commit. */
  112214. + gcmkONERROR(gckHARDWARE_FlushMMU(hardware));
  112215. + }
  112216. +
  112217. + return gcvSTATUS_OK;
  112218. +OnError:
  112219. + return status;
  112220. +}
  112221. +
  112222. +#if gcdVIRTUAL_COMMAND_BUFFER
  112223. +static void
  112224. +_DumpBuffer(
  112225. + IN gctPOINTER Buffer,
  112226. + IN gctUINT32 GpuAddress,
  112227. + IN gctSIZE_T Size
  112228. + )
  112229. +{
  112230. + gctINT i, line, left;
  112231. + gctUINT32_PTR data = Buffer;
  112232. +
  112233. + line = Size / 32;
  112234. + left = Size % 32;
  112235. +
  112236. +
  112237. + for (i = 0; i < line; i++)
  112238. + {
  112239. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X %08X ",
  112240. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
  112241. + data += 8;
  112242. + GpuAddress += 8 * 4;
  112243. + }
  112244. +
  112245. + switch(left)
  112246. + {
  112247. + case 28:
  112248. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X %08X ",
  112249. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
  112250. + break;
  112251. + case 24:
  112252. + gcmkPRINT("%X : %08X %08X %08X %08X %08X %08X ",
  112253. + GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5]);
  112254. + break;
  112255. + case 20:
  112256. + gcmkPRINT("%X : %08X %08X %08X %08X %08X ",
  112257. + GpuAddress, data[0], data[1], data[2], data[3], data[4]);
  112258. + break;
  112259. + case 16:
  112260. + gcmkPRINT("%X : %08X %08X %08X %08X ",
  112261. + GpuAddress, data[0], data[1], data[2], data[3]);
  112262. + break;
  112263. + case 12:
  112264. + gcmkPRINT("%X : %08X %08X %08X ",
  112265. + GpuAddress, data[0], data[1], data[2]);
  112266. + break;
  112267. + case 8:
  112268. + gcmkPRINT("%X : %08X %08X ",
  112269. + GpuAddress, data[0], data[1]);
  112270. + break;
  112271. + case 4:
  112272. + gcmkPRINT("%X : %08X ",
  112273. + GpuAddress, data[0]);
  112274. + break;
  112275. + default:
  112276. + break;
  112277. + }
  112278. +}
  112279. +
  112280. +static void
  112281. +_DumpKernelCommandBuffer(
  112282. + IN gckCOMMAND Command
  112283. +)
  112284. +{
  112285. + gctINT i;
  112286. + gctUINT32 physical;
  112287. + gctPOINTER entry;
  112288. +
  112289. + for (i = 0; i < gcdCOMMAND_QUEUES; i++)
  112290. + {
  112291. + entry = Command->queues[i].logical;
  112292. +
  112293. + gckOS_GetPhysicalAddress(Command->os, entry, &physical);
  112294. +
  112295. + gcmkPRINT("Kernel command buffer %d\n", i);
  112296. +
  112297. + _DumpBuffer(entry, physical, Command->pageSize);
  112298. + }
  112299. +}
  112300. +#endif
  112301. +
  112302. +/******************************************************************************\
  112303. +****************************** gckCOMMAND API Code ******************************
  112304. +\******************************************************************************/
  112305. +
  112306. +/*******************************************************************************
  112307. +**
  112308. +** gckCOMMAND_Construct
  112309. +**
  112310. +** Construct a new gckCOMMAND object.
  112311. +**
  112312. +** INPUT:
  112313. +**
  112314. +** gckKERNEL Kernel
  112315. +** Pointer to an gckKERNEL object.
  112316. +**
  112317. +** OUTPUT:
  112318. +**
  112319. +** gckCOMMAND * Command
  112320. +** Pointer to a variable that will hold the pointer to the gckCOMMAND
  112321. +** object.
  112322. +*/
  112323. +gceSTATUS
  112324. +gckCOMMAND_Construct(
  112325. + IN gckKERNEL Kernel,
  112326. + OUT gckCOMMAND * Command
  112327. + )
  112328. +{
  112329. + gckOS os;
  112330. + gckCOMMAND command = gcvNULL;
  112331. + gceSTATUS status;
  112332. + gctINT i;
  112333. + gctPOINTER pointer = gcvNULL;
  112334. +
  112335. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  112336. +
  112337. + /* Verify the arguments. */
  112338. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  112339. + gcmkVERIFY_ARGUMENT(Command != gcvNULL);
  112340. +
  112341. + /* Extract the gckOS object. */
  112342. + os = Kernel->os;
  112343. +
  112344. + /* Allocate the gckCOMMAND structure. */
  112345. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckCOMMAND), &pointer));
  112346. + command = pointer;
  112347. +
  112348. + /* Reset the entire object. */
  112349. + gcmkONERROR(gckOS_ZeroMemory(command, gcmSIZEOF(struct _gckCOMMAND)));
  112350. +
  112351. + /* Initialize the gckCOMMAND object.*/
  112352. + command->object.type = gcvOBJ_COMMAND;
  112353. + command->kernel = Kernel;
  112354. + command->os = os;
  112355. +
  112356. + /* Get the command buffer requirements. */
  112357. + gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
  112358. + Kernel->hardware,
  112359. + &command->alignment,
  112360. + &command->reservedHead,
  112361. + &command->reservedTail
  112362. + ));
  112363. +
  112364. + /* Create the command queue mutex. */
  112365. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexQueue));
  112366. +
  112367. + /* Create the context switching mutex. */
  112368. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContext));
  112369. +
  112370. +#if VIVANTE_PROFILER_CONTEXT
  112371. + /* Create the context switching mutex. */
  112372. + gcmkONERROR(gckOS_CreateMutex(os, &command->mutexContextSeq));
  112373. +#endif
  112374. +
  112375. + /* Create the power management semaphore. */
  112376. + gcmkONERROR(gckOS_CreateSemaphore(os, &command->powerSemaphore));
  112377. +
  112378. + /* Create the commit atom. */
  112379. + gcmkONERROR(gckOS_AtomConstruct(os, &command->atomCommit));
  112380. +
  112381. + /* Get the page size from teh OS. */
  112382. + gcmkONERROR(gckOS_GetPageSize(os, &command->pageSize));
  112383. +
  112384. + /* Get process ID. */
  112385. + gcmkONERROR(gckOS_GetProcessID(&command->kernelProcessID));
  112386. +
  112387. + /* Set hardware to pipe 0. */
  112388. + command->pipeSelect = gcvPIPE_INVALID;
  112389. +
  112390. + /* Pre-allocate the command queues. */
  112391. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  112392. + {
  112393. + gcmkONERROR(gckOS_AllocateNonPagedMemory(
  112394. + os,
  112395. + gcvFALSE,
  112396. + &command->pageSize,
  112397. + &command->queues[i].physical,
  112398. + &command->queues[i].logical
  112399. + ));
  112400. +
  112401. + gcmkONERROR(gckOS_CreateSignal(
  112402. + os, gcvFALSE, &command->queues[i].signal
  112403. + ));
  112404. +
  112405. + gcmkONERROR(gckOS_Signal(
  112406. + os, command->queues[i].signal, gcvTRUE
  112407. + ));
  112408. + }
  112409. +
  112410. + /* No command queue in use yet. */
  112411. + command->index = -1;
  112412. + command->logical = gcvNULL;
  112413. + command->newQueue = gcvFALSE;
  112414. +
  112415. + /* Command is not yet running. */
  112416. + command->running = gcvFALSE;
  112417. +
  112418. + /* Command queue is idle. */
  112419. + command->idle = gcvTRUE;
  112420. +
  112421. + /* Commit stamp is zero. */
  112422. + command->commitStamp = 0;
  112423. +
  112424. + /* END event signal not created. */
  112425. + command->endEventSignal = gcvNULL;
  112426. +
  112427. + /* Return pointer to the gckCOMMAND object. */
  112428. + *Command = command;
  112429. +
  112430. + /* Success. */
  112431. + gcmkFOOTER_ARG("*Command=0x%x", *Command);
  112432. + return gcvSTATUS_OK;
  112433. +
  112434. +OnError:
  112435. + /* Roll back. */
  112436. + if (command != gcvNULL)
  112437. + {
  112438. + if (command->atomCommit != gcvNULL)
  112439. + {
  112440. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, command->atomCommit));
  112441. + }
  112442. +
  112443. + if (command->powerSemaphore != gcvNULL)
  112444. + {
  112445. + gcmkVERIFY_OK(gckOS_DestroySemaphore(os, command->powerSemaphore));
  112446. + }
  112447. +
  112448. + if (command->mutexContext != gcvNULL)
  112449. + {
  112450. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexContext));
  112451. + }
  112452. +
  112453. +#if VIVANTE_PROFILER_CONTEXT
  112454. + if (command->mutexContextSeq != gcvNULL)
  112455. + {
  112456. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexContextSeq));
  112457. + }
  112458. +#endif
  112459. +
  112460. + if (command->mutexQueue != gcvNULL)
  112461. + {
  112462. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, command->mutexQueue));
  112463. + }
  112464. +
  112465. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  112466. + {
  112467. + if (command->queues[i].signal != gcvNULL)
  112468. + {
  112469. + gcmkVERIFY_OK(gckOS_DestroySignal(
  112470. + os, command->queues[i].signal
  112471. + ));
  112472. + }
  112473. +
  112474. + if (command->queues[i].logical != gcvNULL)
  112475. + {
  112476. + gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
  112477. + os,
  112478. + command->pageSize,
  112479. + command->queues[i].physical,
  112480. + command->queues[i].logical
  112481. + ));
  112482. + }
  112483. + }
  112484. +
  112485. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, command));
  112486. + }
  112487. +
  112488. + /* Return the status. */
  112489. + gcmkFOOTER();
  112490. + return status;
  112491. +}
  112492. +
  112493. +/*******************************************************************************
  112494. +**
  112495. +** gckCOMMAND_Destroy
  112496. +**
  112497. +** Destroy an gckCOMMAND object.
  112498. +**
  112499. +** INPUT:
  112500. +**
  112501. +** gckCOMMAND Command
  112502. +** Pointer to an gckCOMMAND object to destroy.
  112503. +**
  112504. +** OUTPUT:
  112505. +**
  112506. +** Nothing.
  112507. +*/
  112508. +gceSTATUS
  112509. +gckCOMMAND_Destroy(
  112510. + IN gckCOMMAND Command
  112511. + )
  112512. +{
  112513. + gctINT i;
  112514. +
  112515. + gcmkHEADER_ARG("Command=0x%x", Command);
  112516. +
  112517. + /* Verify the arguments. */
  112518. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112519. +
  112520. + /* Stop the command queue. */
  112521. + gcmkVERIFY_OK(gckCOMMAND_Stop(Command, gcvFALSE));
  112522. +
  112523. + for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
  112524. + {
  112525. + gcmkASSERT(Command->queues[i].signal != gcvNULL);
  112526. + gcmkVERIFY_OK(gckOS_DestroySignal(
  112527. + Command->os, Command->queues[i].signal
  112528. + ));
  112529. +
  112530. + gcmkASSERT(Command->queues[i].logical != gcvNULL);
  112531. + gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
  112532. + Command->os,
  112533. + Command->pageSize,
  112534. + Command->queues[i].physical,
  112535. + Command->queues[i].logical
  112536. + ));
  112537. + }
  112538. +
  112539. + /* END event signal. */
  112540. + if (Command->endEventSignal != gcvNULL)
  112541. + {
  112542. + gcmkVERIFY_OK(gckOS_DestroySignal(
  112543. + Command->os, Command->endEventSignal
  112544. + ));
  112545. + }
  112546. +
  112547. + /* Delete the context switching mutex. */
  112548. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContext));
  112549. +
  112550. +#if VIVANTE_PROFILER_CONTEXT
  112551. + if (Command->mutexContextSeq != gcvNULL)
  112552. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexContextSeq));
  112553. +#endif
  112554. +
  112555. + /* Delete the command queue mutex. */
  112556. + gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutexQueue));
  112557. +
  112558. + /* Destroy the power management semaphore. */
  112559. + gcmkVERIFY_OK(gckOS_DestroySemaphore(Command->os, Command->powerSemaphore));
  112560. +
  112561. + /* Destroy the commit atom. */
  112562. + gcmkVERIFY_OK(gckOS_AtomDestroy(Command->os, Command->atomCommit));
  112563. +
  112564. +#if gcdSECURE_USER
  112565. + /* Free state array. */
  112566. + if (Command->hintArrayAllocated)
  112567. + {
  112568. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
  112569. + Command->hintArrayAllocated = gcvFALSE;
  112570. + }
  112571. +#endif
  112572. +
  112573. + /* Mark object as unknown. */
  112574. + Command->object.type = gcvOBJ_UNKNOWN;
  112575. +
  112576. + /* Free the gckCOMMAND object. */
  112577. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, Command));
  112578. +
  112579. + /* Success. */
  112580. + gcmkFOOTER_NO();
  112581. + return gcvSTATUS_OK;
  112582. +}
  112583. +
  112584. +/*******************************************************************************
  112585. +**
  112586. +** gckCOMMAND_EnterCommit
  112587. +**
  112588. +** Acquire command queue synchronization objects.
  112589. +**
  112590. +** INPUT:
  112591. +**
  112592. +** gckCOMMAND Command
  112593. +** Pointer to an gckCOMMAND object to destroy.
  112594. +**
  112595. +** gctBOOL FromPower
  112596. +** Determines whether the call originates from inside the power
  112597. +** management or not.
  112598. +**
  112599. +** OUTPUT:
  112600. +**
  112601. +** Nothing.
  112602. +*/
  112603. +gceSTATUS
  112604. +gckCOMMAND_EnterCommit(
  112605. + IN gckCOMMAND Command,
  112606. + IN gctBOOL FromPower
  112607. + )
  112608. +{
  112609. + gceSTATUS status;
  112610. + gckHARDWARE hardware;
  112611. + gctBOOL atomIncremented = gcvFALSE;
  112612. + gctBOOL semaAcquired = gcvFALSE;
  112613. +
  112614. + gcmkHEADER_ARG("Command=0x%x", Command);
  112615. +
  112616. + /* Extract the gckHARDWARE and gckEVENT objects. */
  112617. + hardware = Command->kernel->hardware;
  112618. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  112619. +
  112620. + if (!FromPower)
  112621. + {
  112622. + /* Increment COMMIT atom to let power management know that a commit is
  112623. + ** in progress. */
  112624. + gcmkONERROR(_IncrementCommitAtom(Command, gcvTRUE));
  112625. + atomIncremented = gcvTRUE;
  112626. +
  112627. + /* Notify the system the GPU has a commit. */
  112628. + gcmkONERROR(gckOS_Broadcast(Command->os,
  112629. + hardware,
  112630. + gcvBROADCAST_GPU_COMMIT));
  112631. +
  112632. + /* Acquire the power management semaphore. */
  112633. + gcmkONERROR(gckOS_AcquireSemaphore(Command->os,
  112634. + Command->powerSemaphore));
  112635. + semaAcquired = gcvTRUE;
  112636. + }
  112637. +
  112638. + /* Grab the conmmand queue mutex. */
  112639. + gcmkONERROR(gckOS_AcquireMutex(Command->os,
  112640. + Command->mutexQueue,
  112641. + gcvINFINITE));
  112642. +
  112643. + /* Success. */
  112644. + gcmkFOOTER();
  112645. + return gcvSTATUS_OK;
  112646. +
  112647. +OnError:
  112648. + if (semaAcquired)
  112649. + {
  112650. + /* Release the power management semaphore. */
  112651. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  112652. + Command->os, Command->powerSemaphore
  112653. + ));
  112654. + }
  112655. +
  112656. + if (atomIncremented)
  112657. + {
  112658. + /* Decrement the commit atom. */
  112659. + gcmkVERIFY_OK(_IncrementCommitAtom(
  112660. + Command, gcvFALSE
  112661. + ));
  112662. + }
  112663. +
  112664. + /* Return the status. */
  112665. + gcmkFOOTER();
  112666. + return status;
  112667. +}
  112668. +
  112669. +/*******************************************************************************
  112670. +**
  112671. +** gckCOMMAND_ExitCommit
  112672. +**
  112673. +** Release command queue synchronization objects.
  112674. +**
  112675. +** INPUT:
  112676. +**
  112677. +** gckCOMMAND Command
  112678. +** Pointer to an gckCOMMAND object to destroy.
  112679. +**
  112680. +** gctBOOL FromPower
  112681. +** Determines whether the call originates from inside the power
  112682. +** management or not.
  112683. +**
  112684. +** OUTPUT:
  112685. +**
  112686. +** Nothing.
  112687. +*/
  112688. +gceSTATUS
  112689. +gckCOMMAND_ExitCommit(
  112690. + IN gckCOMMAND Command,
  112691. + IN gctBOOL FromPower
  112692. + )
  112693. +{
  112694. + gceSTATUS status;
  112695. +
  112696. + gcmkHEADER_ARG("Command=0x%x", Command);
  112697. +
  112698. + /* Release the power mutex. */
  112699. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexQueue));
  112700. +
  112701. + if (!FromPower)
  112702. + {
  112703. + /* Release the power management semaphore. */
  112704. + gcmkONERROR(gckOS_ReleaseSemaphore(Command->os,
  112705. + Command->powerSemaphore));
  112706. +
  112707. + /* Decrement the commit atom. */
  112708. + gcmkONERROR(_IncrementCommitAtom(Command, gcvFALSE));
  112709. + }
  112710. +
  112711. + /* Success. */
  112712. + gcmkFOOTER();
  112713. + return gcvSTATUS_OK;
  112714. +
  112715. +OnError:
  112716. + /* Return the status. */
  112717. + gcmkFOOTER();
  112718. + return status;
  112719. +}
  112720. +
  112721. +/*******************************************************************************
  112722. +**
  112723. +** gckCOMMAND_Start
  112724. +**
  112725. +** Start up the command queue.
  112726. +**
  112727. +** INPUT:
  112728. +**
  112729. +** gckCOMMAND Command
  112730. +** Pointer to an gckCOMMAND object to start.
  112731. +**
  112732. +** OUTPUT:
  112733. +**
  112734. +** Nothing.
  112735. +*/
  112736. +gceSTATUS
  112737. +gckCOMMAND_Start(
  112738. + IN gckCOMMAND Command
  112739. + )
  112740. +{
  112741. + gceSTATUS status;
  112742. + gckHARDWARE hardware;
  112743. + gctUINT32 waitOffset;
  112744. + gctSIZE_T waitLinkBytes;
  112745. +
  112746. + gcmkHEADER_ARG("Command=0x%x", Command);
  112747. +
  112748. + /* Verify the arguments. */
  112749. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112750. +
  112751. + if (Command->running)
  112752. + {
  112753. + /* Command queue already running. */
  112754. + gcmkFOOTER_NO();
  112755. + return gcvSTATUS_OK;
  112756. + }
  112757. +
  112758. + /* Extract the gckHARDWARE object. */
  112759. + hardware = Command->kernel->hardware;
  112760. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  112761. +
  112762. + if (Command->logical == gcvNULL)
  112763. + {
  112764. + /* Start at beginning of a new queue. */
  112765. + gcmkONERROR(_NewQueue(Command));
  112766. + }
  112767. +
  112768. + /* Start at beginning of page. */
  112769. + Command->offset = 0;
  112770. +
  112771. + /* Set abvailable number of bytes for WAIT/LINK command sequence. */
  112772. + waitLinkBytes = Command->pageSize;
  112773. +
  112774. + /* Append WAIT/LINK. */
  112775. + gcmkONERROR(gckHARDWARE_WaitLink(
  112776. + hardware,
  112777. + Command->logical,
  112778. + 0,
  112779. + &waitLinkBytes,
  112780. + &waitOffset,
  112781. + &Command->waitSize
  112782. + ));
  112783. +
  112784. + Command->waitLogical = (gctUINT8_PTR) Command->logical + waitOffset;
  112785. + Command->waitPhysical = (gctUINT8_PTR) Command->physical + waitOffset;
  112786. +
  112787. +#if gcdNONPAGED_MEMORY_CACHEABLE
  112788. + /* Flush the cache for the wait/link. */
  112789. + gcmkONERROR(gckOS_CacheClean(
  112790. + Command->os,
  112791. + Command->kernelProcessID,
  112792. + gcvNULL,
  112793. + Command->physical,
  112794. + Command->logical,
  112795. + waitLinkBytes
  112796. + ));
  112797. +#endif
  112798. +
  112799. + /* Adjust offset. */
  112800. + Command->offset = waitLinkBytes;
  112801. + Command->newQueue = gcvFALSE;
  112802. +
  112803. + /* Enable command processor. */
  112804. +#ifdef __QNXNTO__
  112805. + gcmkONERROR(gckHARDWARE_Execute(
  112806. + hardware,
  112807. + Command->logical,
  112808. + Command->physical,
  112809. + gcvTRUE,
  112810. + waitLinkBytes
  112811. + ));
  112812. +#else
  112813. + gcmkONERROR(gckHARDWARE_Execute(
  112814. + hardware,
  112815. + Command->logical,
  112816. + waitLinkBytes
  112817. + ));
  112818. +#endif
  112819. +
  112820. + /* Command queue is running. */
  112821. + Command->running = gcvTRUE;
  112822. +
  112823. + /* Success. */
  112824. + gcmkFOOTER_NO();
  112825. + return gcvSTATUS_OK;
  112826. +
  112827. +OnError:
  112828. + /* Return the status. */
  112829. + gcmkFOOTER();
  112830. + return status;
  112831. +}
  112832. +
  112833. +/*******************************************************************************
  112834. +**
  112835. +** gckCOMMAND_Stop
  112836. +**
  112837. +** Stop the command queue.
  112838. +**
  112839. +** INPUT:
  112840. +**
  112841. +** gckCOMMAND Command
  112842. +** Pointer to an gckCOMMAND object to stop.
  112843. +**
  112844. +** OUTPUT:
  112845. +**
  112846. +** Nothing.
  112847. +*/
  112848. +gceSTATUS
  112849. +gckCOMMAND_Stop(
  112850. + IN gckCOMMAND Command,
  112851. + IN gctBOOL FromRecovery
  112852. + )
  112853. +{
  112854. + gckHARDWARE hardware;
  112855. + gceSTATUS status;
  112856. + gctUINT32 idle;
  112857. +
  112858. + gcmkHEADER_ARG("Command=0x%x", Command);
  112859. +
  112860. + /* Verify the arguments. */
  112861. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  112862. +
  112863. + if (!Command->running)
  112864. + {
  112865. + /* Command queue is not running. */
  112866. + gcmkFOOTER_NO();
  112867. + return gcvSTATUS_OK;
  112868. + }
  112869. +
  112870. + /* Extract the gckHARDWARE object. */
  112871. + hardware = Command->kernel->hardware;
  112872. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  112873. +
  112874. + if (gckHARDWARE_IsFeatureAvailable(hardware,
  112875. + gcvFEATURE_END_EVENT) == gcvSTATUS_TRUE)
  112876. + {
  112877. + /* Allocate the signal. */
  112878. + if (Command->endEventSignal == gcvNULL)
  112879. + {
  112880. + gcmkONERROR(gckOS_CreateSignal(Command->os,
  112881. + gcvTRUE,
  112882. + &Command->endEventSignal));
  112883. + }
  112884. +
  112885. + /* Append the END EVENT command to trigger the signal. */
  112886. + gcmkONERROR(gckEVENT_Stop(Command->kernel->eventObj,
  112887. + Command->kernelProcessID,
  112888. + Command->waitPhysical,
  112889. + Command->waitLogical,
  112890. + Command->endEventSignal,
  112891. + &Command->waitSize));
  112892. + }
  112893. + else
  112894. + {
  112895. + /* Replace last WAIT with END. */
  112896. + gcmkONERROR(gckHARDWARE_End(
  112897. + hardware, Command->waitLogical, &Command->waitSize
  112898. + ));
  112899. +
  112900. + /* Update queue tail pointer. */
  112901. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware,
  112902. + Command->logical,
  112903. + Command->offset));
  112904. +
  112905. +#if gcdNONPAGED_MEMORY_CACHEABLE
  112906. + /* Flush the cache for the END. */
  112907. + gcmkONERROR(gckOS_CacheClean(
  112908. + Command->os,
  112909. + Command->kernelProcessID,
  112910. + gcvNULL,
  112911. + Command->waitPhysical,
  112912. + Command->waitLogical,
  112913. + Command->waitSize
  112914. + ));
  112915. +#endif
  112916. +
  112917. + /* Wait for idle. */
  112918. + gcmkONERROR(gckHARDWARE_GetIdle(hardware, !FromRecovery, &idle));
  112919. + }
  112920. +
  112921. + /* Command queue is no longer running. */
  112922. + Command->running = gcvFALSE;
  112923. +
  112924. + /* Success. */
  112925. + gcmkFOOTER_NO();
  112926. + return gcvSTATUS_OK;
  112927. +
  112928. +OnError:
  112929. + /* Return the status. */
  112930. + gcmkFOOTER();
  112931. + return status;
  112932. +}
  112933. +
  112934. +/*******************************************************************************
  112935. +**
  112936. +** gckCOMMAND_Commit
  112937. +**
  112938. +** Commit a command buffer to the command queue.
  112939. +**
  112940. +** INPUT:
  112941. +**
  112942. +** gckCOMMAND Command
  112943. +** Pointer to a gckCOMMAND object.
  112944. +**
  112945. +** gckCONTEXT Context
  112946. +** Pointer to a gckCONTEXT object.
  112947. +**
  112948. +** gcoCMDBUF CommandBuffer
  112949. +** Pointer to a gcoCMDBUF object.
  112950. +**
  112951. +** gcsSTATE_DELTA_PTR StateDelta
  112952. +** Pointer to the state delta.
  112953. +**
  112954. +** gctUINT32 ProcessID
  112955. +** Current process ID.
  112956. +**
  112957. +** OUTPUT:
  112958. +**
  112959. +** Nothing.
  112960. +*/
  112961. +gceSTATUS
  112962. +gckCOMMAND_Commit(
  112963. + IN gckCOMMAND Command,
  112964. + IN gckCONTEXT Context,
  112965. + IN gcoCMDBUF CommandBuffer,
  112966. + IN gcsSTATE_DELTA_PTR StateDelta,
  112967. + IN gcsQUEUE_PTR EventQueue,
  112968. + IN gctUINT32 ProcessID
  112969. + )
  112970. +{
  112971. + gceSTATUS status;
  112972. + gctBOOL commitEntered = gcvFALSE;
  112973. + gctBOOL contextAcquired = gcvFALSE;
  112974. + gckHARDWARE hardware;
  112975. + gctBOOL needCopy = gcvFALSE;
  112976. + gcsQUEUE_PTR eventRecord = gcvNULL;
  112977. + gcsQUEUE _eventRecord;
  112978. + gcsQUEUE_PTR nextEventRecord;
  112979. + gctBOOL commandBufferMapped = gcvFALSE;
  112980. + gcoCMDBUF commandBufferObject = gcvNULL;
  112981. +
  112982. +#if !gcdNULL_DRIVER
  112983. + gcsCONTEXT_PTR contextBuffer;
  112984. + struct _gcoCMDBUF _commandBufferObject;
  112985. + gctPHYS_ADDR commandBufferPhysical;
  112986. + gctUINT8_PTR commandBufferLogical;
  112987. + gctUINT8_PTR commandBufferLink;
  112988. + gctUINT commandBufferSize;
  112989. + gctSIZE_T nopBytes;
  112990. + gctSIZE_T pipeBytes;
  112991. + gctSIZE_T linkBytes;
  112992. + gctSIZE_T bytes;
  112993. + gctUINT32 offset;
  112994. +#if gcdNONPAGED_MEMORY_CACHEABLE
  112995. + gctPHYS_ADDR entryPhysical;
  112996. +#endif
  112997. + gctPOINTER entryLogical;
  112998. + gctSIZE_T entryBytes;
  112999. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113000. + gctPHYS_ADDR exitPhysical;
  113001. +#endif
  113002. + gctPOINTER exitLogical;
  113003. + gctSIZE_T exitBytes;
  113004. + gctPHYS_ADDR waitLinkPhysical;
  113005. + gctPOINTER waitLinkLogical;
  113006. + gctSIZE_T waitLinkBytes;
  113007. + gctPHYS_ADDR waitPhysical;
  113008. + gctPOINTER waitLogical;
  113009. + gctUINT32 waitOffset;
  113010. + gctSIZE_T waitSize;
  113011. +
  113012. +#if gcdDUMP_COMMAND
  113013. + gctPOINTER contextDumpLogical = gcvNULL;
  113014. + gctSIZE_T contextDumpBytes = 0;
  113015. + gctPOINTER bufferDumpLogical = gcvNULL;
  113016. + gctSIZE_T bufferDumpBytes = 0;
  113017. +# endif
  113018. +#endif
  113019. +
  113020. +#if VIVANTE_PROFILER_CONTEXT
  113021. + gctBOOL sequenceAcquired = gcvFALSE;
  113022. +#endif
  113023. +
  113024. + gctPOINTER pointer = gcvNULL;
  113025. +
  113026. + gcmkHEADER_ARG(
  113027. + "Command=0x%x CommandBuffer=0x%x ProcessID=%d",
  113028. + Command, CommandBuffer, ProcessID
  113029. + );
  113030. +
  113031. + /* Verify the arguments. */
  113032. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  113033. +
  113034. + if (Command->kernel->core == gcvCORE_2D)
  113035. + {
  113036. + /* There is no context for 2D. */
  113037. + Context = gcvNULL;
  113038. + }
  113039. +
  113040. + gcmkONERROR(_FlushMMU(Command));
  113041. +
  113042. +#if VIVANTE_PROFILER_CONTEXT
  113043. + if((Command->kernel->hardware->gpuProfiler) && (Command->kernel->profileEnable))
  113044. + {
  113045. + /* Acquire the context sequnence mutex. */
  113046. + gcmkONERROR(gckOS_AcquireMutex(
  113047. + Command->os, Command->mutexContextSeq, gcvINFINITE
  113048. + ));
  113049. + sequenceAcquired = gcvTRUE;
  113050. + }
  113051. +#endif
  113052. +
  113053. + /* Acquire the command queue. */
  113054. + gcmkONERROR(gckCOMMAND_EnterCommit(Command, gcvFALSE));
  113055. + commitEntered = gcvTRUE;
  113056. +
  113057. + /* Acquire the context switching mutex. */
  113058. + gcmkONERROR(gckOS_AcquireMutex(
  113059. + Command->os, Command->mutexContext, gcvINFINITE
  113060. + ));
  113061. + contextAcquired = gcvTRUE;
  113062. +
  113063. + /* Extract the gckHARDWARE and gckEVENT objects. */
  113064. + hardware = Command->kernel->hardware;
  113065. +
  113066. + /* Check wehther we need to copy the structures or not. */
  113067. + gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
  113068. +
  113069. +#if gcdNULL_DRIVER
  113070. + /* Context switch required? */
  113071. + if ((Context != gcvNULL) && (Command->currContext != Context))
  113072. + {
  113073. + /* Yes, merge in the deltas. */
  113074. + gckCONTEXT_Update(Context, ProcessID, StateDelta);
  113075. +
  113076. + /* Update the current context. */
  113077. + Command->currContext = Context;
  113078. + }
  113079. +#else
  113080. + if (needCopy)
  113081. + {
  113082. + commandBufferObject = &_commandBufferObject;
  113083. +
  113084. + gcmkONERROR(gckOS_CopyFromUserData(
  113085. + Command->os,
  113086. + commandBufferObject,
  113087. + CommandBuffer,
  113088. + gcmSIZEOF(struct _gcoCMDBUF)
  113089. + ));
  113090. +
  113091. + gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
  113092. + }
  113093. + else
  113094. + {
  113095. + gcmkONERROR(gckOS_MapUserPointer(
  113096. + Command->os,
  113097. + CommandBuffer,
  113098. + gcmSIZEOF(struct _gcoCMDBUF),
  113099. + &pointer
  113100. + ));
  113101. +
  113102. + commandBufferObject = pointer;
  113103. +
  113104. + gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
  113105. + commandBufferMapped = gcvTRUE;
  113106. + }
  113107. +
  113108. + /* Query the size of NOP command. */
  113109. + gcmkONERROR(gckHARDWARE_Nop(
  113110. + hardware, gcvNULL, &nopBytes
  113111. + ));
  113112. +
  113113. + /* Query the size of pipe select command sequence. */
  113114. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113115. + hardware, gcvNULL, gcvPIPE_3D, &pipeBytes
  113116. + ));
  113117. +
  113118. + /* Query the size of LINK command. */
  113119. + gcmkONERROR(gckHARDWARE_Link(
  113120. + hardware, gcvNULL, gcvNULL, 0, &linkBytes
  113121. + ));
  113122. +
  113123. + /* Compute the command buffer entry and the size. */
  113124. + commandBufferLogical
  113125. + = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
  113126. + + commandBufferObject->startOffset;
  113127. +
  113128. + gcmkONERROR(gckOS_GetPhysicalAddress(
  113129. + Command->os,
  113130. + commandBufferLogical,
  113131. + (gctUINT32_PTR)&commandBufferPhysical
  113132. + ));
  113133. +
  113134. + commandBufferSize
  113135. + = commandBufferObject->offset
  113136. + + Command->reservedTail
  113137. + - commandBufferObject->startOffset;
  113138. +
  113139. + /* Get the current offset. */
  113140. + offset = Command->offset;
  113141. +
  113142. + /* Compute number of bytes left in current kernel command queue. */
  113143. + bytes = Command->pageSize - offset;
  113144. +
  113145. + /* Query the size of WAIT/LINK command sequence. */
  113146. + gcmkONERROR(gckHARDWARE_WaitLink(
  113147. + hardware,
  113148. + gcvNULL,
  113149. + offset,
  113150. + &waitLinkBytes,
  113151. + gcvNULL,
  113152. + gcvNULL
  113153. + ));
  113154. +
  113155. + /* Is there enough space in the current command queue? */
  113156. + if (bytes < waitLinkBytes)
  113157. + {
  113158. + /* No, create a new one. */
  113159. + gcmkONERROR(_NewQueue(Command));
  113160. +
  113161. + /* Get the new current offset. */
  113162. + offset = Command->offset;
  113163. +
  113164. + /* Recompute the number of bytes in the new kernel command queue. */
  113165. + bytes = Command->pageSize - offset;
  113166. + gcmkASSERT(bytes >= waitLinkBytes);
  113167. + }
  113168. +
  113169. + /* Compute the location if WAIT/LINK command sequence. */
  113170. + waitLinkPhysical = (gctUINT8_PTR) Command->physical + offset;
  113171. + waitLinkLogical = (gctUINT8_PTR) Command->logical + offset;
  113172. +
  113173. + /* Context switch required? */
  113174. + if (Context == gcvNULL)
  113175. + {
  113176. + /* See if we have to switch pipes for the command buffer. */
  113177. + if (commandBufferObject->entryPipe == Command->pipeSelect)
  113178. + {
  113179. + /* Skip pipe switching sequence. */
  113180. + offset = pipeBytes;
  113181. + }
  113182. + else
  113183. + {
  113184. + /* The current hardware and the entry command buffer pipes
  113185. + ** are different, switch to the correct pipe. */
  113186. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113187. + Command->kernel->hardware,
  113188. + commandBufferLogical,
  113189. + commandBufferObject->entryPipe,
  113190. + &pipeBytes
  113191. + ));
  113192. +
  113193. + /* Do not skip pipe switching sequence. */
  113194. + offset = 0;
  113195. + }
  113196. +
  113197. + /* Compute the entry. */
  113198. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113199. + entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
  113200. +#endif
  113201. + entryLogical = commandBufferLogical + offset;
  113202. + entryBytes = commandBufferSize - offset;
  113203. + }
  113204. + else if (Command->currContext != Context)
  113205. + {
  113206. + /* Temporary disable context length oprimization. */
  113207. + Context->dirty = gcvTRUE;
  113208. +
  113209. + /* Get the current context buffer. */
  113210. + contextBuffer = Context->buffer;
  113211. +
  113212. + /* Yes, merge in the deltas. */
  113213. + gcmkONERROR(gckCONTEXT_Update(Context, ProcessID, StateDelta));
  113214. +
  113215. + /* Determine context entry and exit points. */
  113216. + if (0)
  113217. + {
  113218. + /* Reset 2D dirty flag. */
  113219. + Context->dirty2D = gcvFALSE;
  113220. +
  113221. + if (Context->dirty || commandBufferObject->using3D)
  113222. + {
  113223. + /***************************************************************
  113224. + ** SWITCHING CONTEXT: 2D and 3D are used.
  113225. + */
  113226. +
  113227. + /* Reset 3D dirty flag. */
  113228. + Context->dirty3D = gcvFALSE;
  113229. +
  113230. + /* Compute the entry. */
  113231. + if (Command->pipeSelect == gcvPIPE_2D)
  113232. + {
  113233. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113234. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  113235. +#endif
  113236. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  113237. + entryBytes = Context->bufferSize - pipeBytes;
  113238. + }
  113239. + else
  113240. + {
  113241. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113242. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  113243. +#endif
  113244. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  113245. + entryBytes = Context->bufferSize;
  113246. + }
  113247. +
  113248. + /* See if we have to switch pipes between the context
  113249. + and command buffers. */
  113250. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  113251. + {
  113252. + /* Skip pipe switching sequence. */
  113253. + offset = pipeBytes;
  113254. + }
  113255. + else
  113256. + {
  113257. + /* The current hardware and the initial context pipes are
  113258. + different, switch to the correct pipe. */
  113259. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113260. + Command->kernel->hardware,
  113261. + commandBufferLogical,
  113262. + commandBufferObject->entryPipe,
  113263. + &pipeBytes
  113264. + ));
  113265. +
  113266. + /* Do not skip pipe switching sequence. */
  113267. + offset = 0;
  113268. + }
  113269. +
  113270. + /* Ensure the NOP between 2D and 3D is in place so that the
  113271. + execution falls through from 2D to 3D. */
  113272. + gcmkONERROR(gckHARDWARE_Nop(
  113273. + hardware,
  113274. + contextBuffer->link2D,
  113275. + &nopBytes
  113276. + ));
  113277. +
  113278. + /* Generate a LINK from the context buffer to
  113279. + the command buffer. */
  113280. + gcmkONERROR(gckHARDWARE_Link(
  113281. + hardware,
  113282. + contextBuffer->link3D,
  113283. + commandBufferLogical + offset,
  113284. + commandBufferSize - offset,
  113285. + &linkBytes
  113286. + ));
  113287. +
  113288. + /* Mark context as not dirty. */
  113289. + Context->dirty = gcvFALSE;
  113290. + }
  113291. + else
  113292. + {
  113293. + /***************************************************************
  113294. + ** SWITCHING CONTEXT: 2D only command buffer.
  113295. + */
  113296. +
  113297. + /* Mark 3D as dirty. */
  113298. + Context->dirty3D = gcvTRUE;
  113299. +
  113300. + /* Compute the entry. */
  113301. + if (Command->pipeSelect == gcvPIPE_2D)
  113302. + {
  113303. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113304. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  113305. +#endif
  113306. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  113307. + entryBytes = Context->entryOffset3D - pipeBytes;
  113308. + }
  113309. + else
  113310. + {
  113311. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113312. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  113313. +#endif
  113314. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  113315. + entryBytes = Context->entryOffset3D;
  113316. + }
  113317. +
  113318. + /* Store the current context buffer. */
  113319. + Context->dirtyBuffer = contextBuffer;
  113320. +
  113321. + /* See if we have to switch pipes between the context
  113322. + and command buffers. */
  113323. + if (commandBufferObject->entryPipe == gcvPIPE_2D)
  113324. + {
  113325. + /* Skip pipe switching sequence. */
  113326. + offset = pipeBytes;
  113327. + }
  113328. + else
  113329. + {
  113330. + /* The current hardware and the initial context pipes are
  113331. + different, switch to the correct pipe. */
  113332. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113333. + Command->kernel->hardware,
  113334. + commandBufferLogical,
  113335. + commandBufferObject->entryPipe,
  113336. + &pipeBytes
  113337. + ));
  113338. +
  113339. + /* Do not skip pipe switching sequence. */
  113340. + offset = 0;
  113341. + }
  113342. +
  113343. + /* 3D is not used, generate a LINK from the end of 2D part of
  113344. + the context buffer to the command buffer. */
  113345. + gcmkONERROR(gckHARDWARE_Link(
  113346. + hardware,
  113347. + contextBuffer->link2D,
  113348. + commandBufferLogical + offset,
  113349. + commandBufferSize - offset,
  113350. + &linkBytes
  113351. + ));
  113352. + }
  113353. + }
  113354. +
  113355. + /* Not using 2D. */
  113356. + else
  113357. + {
  113358. + /* Mark 2D as dirty. */
  113359. + Context->dirty2D = gcvTRUE;
  113360. +
  113361. + /* Store the current context buffer. */
  113362. + Context->dirtyBuffer = contextBuffer;
  113363. +
  113364. + if (Context->dirty || commandBufferObject->using3D)
  113365. + {
  113366. + /***************************************************************
  113367. + ** SWITCHING CONTEXT: 3D only command buffer.
  113368. + */
  113369. +
  113370. + /* Reset 3D dirty flag. */
  113371. + Context->dirty3D = gcvFALSE;
  113372. +
  113373. + /* Determine context buffer entry offset. */
  113374. + offset = (Command->pipeSelect == gcvPIPE_3D)
  113375. +
  113376. + /* Skip pipe switching sequence. */
  113377. + ? Context->entryOffset3D + pipeBytes
  113378. +
  113379. + /* Do not skip pipe switching sequence. */
  113380. + : Context->entryOffset3D;
  113381. +
  113382. + /* Compute the entry. */
  113383. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113384. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
  113385. +#endif
  113386. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
  113387. + entryBytes = Context->bufferSize - offset;
  113388. +
  113389. + /* See if we have to switch pipes between the context
  113390. + and command buffers. */
  113391. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  113392. + {
  113393. + /* Skip pipe switching sequence. */
  113394. + offset = pipeBytes;
  113395. + }
  113396. + else
  113397. + {
  113398. + /* The current hardware and the initial context pipes are
  113399. + different, switch to the correct pipe. */
  113400. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113401. + Command->kernel->hardware,
  113402. + commandBufferLogical,
  113403. + commandBufferObject->entryPipe,
  113404. + &pipeBytes
  113405. + ));
  113406. +
  113407. + /* Do not skip pipe switching sequence. */
  113408. + offset = 0;
  113409. + }
  113410. +
  113411. + /* Generate a LINK from the context buffer to
  113412. + the command buffer. */
  113413. + gcmkONERROR(gckHARDWARE_Link(
  113414. + hardware,
  113415. + contextBuffer->link3D,
  113416. + commandBufferLogical + offset,
  113417. + commandBufferSize - offset,
  113418. + &linkBytes
  113419. + ));
  113420. + }
  113421. + else
  113422. + {
  113423. + /***************************************************************
  113424. + ** SWITCHING CONTEXT: "XD" command buffer - neither 2D nor 3D.
  113425. + */
  113426. +
  113427. + /* Mark 3D as dirty. */
  113428. + Context->dirty3D = gcvTRUE;
  113429. +
  113430. + /* Compute the entry. */
  113431. + if (Command->pipeSelect == gcvPIPE_3D)
  113432. + {
  113433. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113434. + entryPhysical
  113435. + = (gctUINT8_PTR) contextBuffer->physical
  113436. + + Context->entryOffsetXDFrom3D;
  113437. +#endif
  113438. + entryLogical
  113439. + = (gctUINT8_PTR) contextBuffer->logical
  113440. + + Context->entryOffsetXDFrom3D;
  113441. +
  113442. + entryBytes
  113443. + = Context->bufferSize
  113444. + - Context->entryOffsetXDFrom3D;
  113445. + }
  113446. + else
  113447. + {
  113448. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113449. + entryPhysical
  113450. + = (gctUINT8_PTR) contextBuffer->physical
  113451. + + Context->entryOffsetXDFrom2D;
  113452. +#endif
  113453. + entryLogical
  113454. + = (gctUINT8_PTR) contextBuffer->logical
  113455. + + Context->entryOffsetXDFrom2D;
  113456. +
  113457. + entryBytes
  113458. + = Context->totalSize
  113459. + - Context->entryOffsetXDFrom2D;
  113460. + }
  113461. +
  113462. + /* See if we have to switch pipes between the context
  113463. + and command buffers. */
  113464. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  113465. + {
  113466. + /* Skip pipe switching sequence. */
  113467. + offset = pipeBytes;
  113468. + }
  113469. + else
  113470. + {
  113471. + /* The current hardware and the initial context pipes are
  113472. + different, switch to the correct pipe. */
  113473. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113474. + Command->kernel->hardware,
  113475. + commandBufferLogical,
  113476. + commandBufferObject->entryPipe,
  113477. + &pipeBytes
  113478. + ));
  113479. +
  113480. + /* Do not skip pipe switching sequence. */
  113481. + offset = 0;
  113482. + }
  113483. +
  113484. + /* Generate a LINK from the context buffer to
  113485. + the command buffer. */
  113486. + gcmkONERROR(gckHARDWARE_Link(
  113487. + hardware,
  113488. + contextBuffer->link3D,
  113489. + commandBufferLogical + offset,
  113490. + commandBufferSize - offset,
  113491. + &linkBytes
  113492. + ));
  113493. + }
  113494. + }
  113495. +
  113496. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113497. + /* Flush the context buffer cache. */
  113498. + gcmkONERROR(gckOS_CacheClean(
  113499. + Command->os,
  113500. + Command->kernelProcessID,
  113501. + gcvNULL,
  113502. + entryPhysical,
  113503. + entryLogical,
  113504. + entryBytes
  113505. + ));
  113506. +#endif
  113507. +
  113508. + /* Update the current context. */
  113509. + Command->currContext = Context;
  113510. +
  113511. +#if gcdDUMP_COMMAND
  113512. + contextDumpLogical = entryLogical;
  113513. + contextDumpBytes = entryBytes;
  113514. +#endif
  113515. + }
  113516. +
  113517. + /* Same context. */
  113518. + else
  113519. + {
  113520. + /* Determine context entry and exit points. */
  113521. + if (commandBufferObject->using2D && Context->dirty2D)
  113522. + {
  113523. + /* Reset 2D dirty flag. */
  113524. + Context->dirty2D = gcvFALSE;
  113525. +
  113526. + /* Get the "dirty" context buffer. */
  113527. + contextBuffer = Context->dirtyBuffer;
  113528. +
  113529. + if (commandBufferObject->using3D && Context->dirty3D)
  113530. + {
  113531. + /* Reset 3D dirty flag. */
  113532. + Context->dirty3D = gcvFALSE;
  113533. +
  113534. + /* Compute the entry. */
  113535. + if (Command->pipeSelect == gcvPIPE_2D)
  113536. + {
  113537. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113538. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  113539. +#endif
  113540. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  113541. + entryBytes = Context->bufferSize - pipeBytes;
  113542. + }
  113543. + else
  113544. + {
  113545. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113546. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  113547. +#endif
  113548. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  113549. + entryBytes = Context->bufferSize;
  113550. + }
  113551. +
  113552. + /* See if we have to switch pipes between the context
  113553. + and command buffers. */
  113554. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  113555. + {
  113556. + /* Skip pipe switching sequence. */
  113557. + offset = pipeBytes;
  113558. + }
  113559. + else
  113560. + {
  113561. + /* The current hardware and the initial context pipes are
  113562. + different, switch to the correct pipe. */
  113563. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113564. + Command->kernel->hardware,
  113565. + commandBufferLogical,
  113566. + commandBufferObject->entryPipe,
  113567. + &pipeBytes
  113568. + ));
  113569. +
  113570. + /* Do not skip pipe switching sequence. */
  113571. + offset = 0;
  113572. + }
  113573. +
  113574. + /* Ensure the NOP between 2D and 3D is in place so that the
  113575. + execution falls through from 2D to 3D. */
  113576. + gcmkONERROR(gckHARDWARE_Nop(
  113577. + hardware,
  113578. + contextBuffer->link2D,
  113579. + &nopBytes
  113580. + ));
  113581. +
  113582. + /* Generate a LINK from the context buffer to
  113583. + the command buffer. */
  113584. + gcmkONERROR(gckHARDWARE_Link(
  113585. + hardware,
  113586. + contextBuffer->link3D,
  113587. + commandBufferLogical + offset,
  113588. + commandBufferSize - offset,
  113589. + &linkBytes
  113590. + ));
  113591. + }
  113592. + else
  113593. + {
  113594. + /* Compute the entry. */
  113595. + if (Command->pipeSelect == gcvPIPE_2D)
  113596. + {
  113597. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113598. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + pipeBytes;
  113599. +#endif
  113600. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + pipeBytes;
  113601. + entryBytes = Context->entryOffset3D - pipeBytes;
  113602. + }
  113603. + else
  113604. + {
  113605. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113606. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical;
  113607. +#endif
  113608. + entryLogical = (gctUINT8_PTR) contextBuffer->logical;
  113609. + entryBytes = Context->entryOffset3D;
  113610. + }
  113611. +
  113612. + /* See if we have to switch pipes between the context
  113613. + and command buffers. */
  113614. + if (commandBufferObject->entryPipe == gcvPIPE_2D)
  113615. + {
  113616. + /* Skip pipe switching sequence. */
  113617. + offset = pipeBytes;
  113618. + }
  113619. + else
  113620. + {
  113621. + /* The current hardware and the initial context pipes are
  113622. + different, switch to the correct pipe. */
  113623. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113624. + Command->kernel->hardware,
  113625. + commandBufferLogical,
  113626. + commandBufferObject->entryPipe,
  113627. + &pipeBytes
  113628. + ));
  113629. +
  113630. + /* Do not skip pipe switching sequence. */
  113631. + offset = 0;
  113632. + }
  113633. +
  113634. + /* 3D is not used, generate a LINK from the end of 2D part of
  113635. + the context buffer to the command buffer. */
  113636. + gcmkONERROR(gckHARDWARE_Link(
  113637. + hardware,
  113638. + contextBuffer->link2D,
  113639. + commandBufferLogical + offset,
  113640. + commandBufferSize - offset,
  113641. + &linkBytes
  113642. + ));
  113643. + }
  113644. + }
  113645. + else
  113646. + {
  113647. + if (commandBufferObject->using3D && Context->dirty3D)
  113648. + {
  113649. + /* Reset 3D dirty flag. */
  113650. + Context->dirty3D = gcvFALSE;
  113651. +
  113652. + /* Get the "dirty" context buffer. */
  113653. + contextBuffer = Context->dirtyBuffer;
  113654. +
  113655. + /* Determine context buffer entry offset. */
  113656. + offset = (Command->pipeSelect == gcvPIPE_3D)
  113657. +
  113658. + /* Skip pipe switching sequence. */
  113659. + ? Context->entryOffset3D + pipeBytes
  113660. +
  113661. + /* Do not skip pipe switching sequence. */
  113662. + : Context->entryOffset3D;
  113663. +
  113664. + /* Compute the entry. */
  113665. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113666. + entryPhysical = (gctUINT8_PTR) contextBuffer->physical + offset;
  113667. +#endif
  113668. + entryLogical = (gctUINT8_PTR) contextBuffer->logical + offset;
  113669. + entryBytes = Context->bufferSize - offset;
  113670. +
  113671. + /* See if we have to switch pipes between the context
  113672. + and command buffers. */
  113673. + if (commandBufferObject->entryPipe == gcvPIPE_3D)
  113674. + {
  113675. + /* Skip pipe switching sequence. */
  113676. + offset = pipeBytes;
  113677. + }
  113678. + else
  113679. + {
  113680. + /* The current hardware and the initial context pipes are
  113681. + different, switch to the correct pipe. */
  113682. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113683. + Command->kernel->hardware,
  113684. + commandBufferLogical,
  113685. + commandBufferObject->entryPipe,
  113686. + &pipeBytes
  113687. + ));
  113688. +
  113689. + /* Do not skip pipe switching sequence. */
  113690. + offset = 0;
  113691. + }
  113692. +
  113693. + /* Generate a LINK from the context buffer to
  113694. + the command buffer. */
  113695. + gcmkONERROR(gckHARDWARE_Link(
  113696. + hardware,
  113697. + contextBuffer->link3D,
  113698. + commandBufferLogical + offset,
  113699. + commandBufferSize - offset,
  113700. + &linkBytes
  113701. + ));
  113702. + }
  113703. + else
  113704. + {
  113705. + /* See if we have to switch pipes for the command buffer. */
  113706. + if (commandBufferObject->entryPipe == Command->pipeSelect)
  113707. + {
  113708. + /* Skip pipe switching sequence. */
  113709. + offset = pipeBytes;
  113710. + }
  113711. + else
  113712. + {
  113713. + /* The current hardware and the entry command buffer pipes
  113714. + ** are different, switch to the correct pipe. */
  113715. + gcmkONERROR(gckHARDWARE_PipeSelect(
  113716. + Command->kernel->hardware,
  113717. + commandBufferLogical,
  113718. + commandBufferObject->entryPipe,
  113719. + &pipeBytes
  113720. + ));
  113721. +
  113722. + /* Do not skip pipe switching sequence. */
  113723. + offset = 0;
  113724. + }
  113725. +
  113726. + /* Compute the entry. */
  113727. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113728. + entryPhysical = (gctUINT8_PTR) commandBufferPhysical + offset;
  113729. +#endif
  113730. + entryLogical = commandBufferLogical + offset;
  113731. + entryBytes = commandBufferSize - offset;
  113732. + }
  113733. + }
  113734. + }
  113735. +
  113736. +#if gcdDUMP_COMMAND
  113737. + bufferDumpLogical = commandBufferLogical + offset;
  113738. + bufferDumpBytes = commandBufferSize - offset;
  113739. +#endif
  113740. +
  113741. +#if gcdSECURE_USER
  113742. + /* Process user hints. */
  113743. + gcmkONERROR(_ProcessHints(Command, ProcessID, commandBufferObject));
  113744. +#endif
  113745. +
  113746. + /* Determine the location to jump to for the command buffer being
  113747. + ** scheduled. */
  113748. + if (Command->newQueue)
  113749. + {
  113750. + /* New command queue, jump to the beginning of it. */
  113751. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113752. + exitPhysical = Command->physical;
  113753. +#endif
  113754. + exitLogical = Command->logical;
  113755. + exitBytes = Command->offset + waitLinkBytes;
  113756. + }
  113757. + else
  113758. + {
  113759. + /* Still within the preexisting command queue, jump to the new
  113760. + WAIT/LINK command sequence. */
  113761. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113762. + exitPhysical = waitLinkPhysical;
  113763. +#endif
  113764. + exitLogical = waitLinkLogical;
  113765. + exitBytes = waitLinkBytes;
  113766. + }
  113767. +
  113768. + /* Add a new WAIT/LINK command sequence. When the command buffer which is
  113769. + currently being scheduled is fully executed by the GPU, the FE will
  113770. + jump to this WAIT/LINK sequence. */
  113771. + gcmkONERROR(gckHARDWARE_WaitLink(
  113772. + hardware,
  113773. + waitLinkLogical,
  113774. + offset,
  113775. + &waitLinkBytes,
  113776. + &waitOffset,
  113777. + &waitSize
  113778. + ));
  113779. +
  113780. + /* Compute the location if WAIT command. */
  113781. + waitPhysical = (gctUINT8_PTR) waitLinkPhysical + waitOffset;
  113782. + waitLogical = (gctUINT8_PTR) waitLinkLogical + waitOffset;
  113783. +
  113784. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113785. + /* Flush the command queue cache. */
  113786. + gcmkONERROR(gckOS_CacheClean(
  113787. + Command->os,
  113788. + Command->kernelProcessID,
  113789. + gcvNULL,
  113790. + exitPhysical,
  113791. + exitLogical,
  113792. + exitBytes
  113793. + ));
  113794. +#endif
  113795. +
  113796. + /* Determine the location of the LINK command in the command buffer. */
  113797. + commandBufferLink
  113798. + = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
  113799. + + commandBufferObject->offset;
  113800. +
  113801. + /* Generate a LINK from the end of the command buffer being scheduled
  113802. + back to the kernel command queue. */
  113803. + gcmkONERROR(gckHARDWARE_Link(
  113804. + hardware,
  113805. + commandBufferLink,
  113806. + exitLogical,
  113807. + exitBytes,
  113808. + &linkBytes
  113809. + ));
  113810. +
  113811. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113812. + /* Flush the command buffer cache. */
  113813. + gcmkONERROR(gckOS_CacheClean(
  113814. + Command->os,
  113815. + ProcessID,
  113816. + gcvNULL,
  113817. + commandBufferPhysical,
  113818. + commandBufferLogical,
  113819. + commandBufferSize
  113820. + ));
  113821. +#endif
  113822. +
  113823. + /* Generate a LINK from the previous WAIT/LINK command sequence to the
  113824. + entry determined above (either the context or the command buffer).
  113825. + This LINK replaces the WAIT instruction from the previous WAIT/LINK
  113826. + pair, therefore we use WAIT metrics for generation of this LINK.
  113827. + This action will execute the entire sequence. */
  113828. + gcmkONERROR(gckHARDWARE_Link(
  113829. + hardware,
  113830. + Command->waitLogical,
  113831. + entryLogical,
  113832. + entryBytes,
  113833. + &Command->waitSize
  113834. + ));
  113835. +
  113836. +#if gcdNONPAGED_MEMORY_CACHEABLE
  113837. + /* Flush the cache for the link. */
  113838. + gcmkONERROR(gckOS_CacheClean(
  113839. + Command->os,
  113840. + Command->kernelProcessID,
  113841. + gcvNULL,
  113842. + Command->waitPhysical,
  113843. + Command->waitLogical,
  113844. + Command->waitSize
  113845. + ));
  113846. +#endif
  113847. +
  113848. + gcmkDUMPCOMMAND(
  113849. + Command->os,
  113850. + Command->waitLogical,
  113851. + Command->waitSize,
  113852. + gceDUMP_BUFFER_LINK,
  113853. + gcvFALSE
  113854. + );
  113855. +
  113856. + gcmkDUMPCOMMAND(
  113857. + Command->os,
  113858. + contextDumpLogical,
  113859. + contextDumpBytes,
  113860. + gceDUMP_BUFFER_CONTEXT,
  113861. + gcvFALSE
  113862. + );
  113863. +
  113864. + gcmkDUMPCOMMAND(
  113865. + Command->os,
  113866. + bufferDumpLogical,
  113867. + bufferDumpBytes,
  113868. + gceDUMP_BUFFER_USER,
  113869. + gcvFALSE
  113870. + );
  113871. +
  113872. + gcmkDUMPCOMMAND(
  113873. + Command->os,
  113874. + waitLinkLogical,
  113875. + waitLinkBytes,
  113876. + gceDUMP_BUFFER_WAITLINK,
  113877. + gcvFALSE
  113878. + );
  113879. +
  113880. + /* Update the current pipe. */
  113881. + Command->pipeSelect = commandBufferObject->exitPipe;
  113882. +
  113883. + /* Update command queue offset. */
  113884. + Command->offset += waitLinkBytes;
  113885. + Command->newQueue = gcvFALSE;
  113886. +
  113887. + /* Update address of last WAIT. */
  113888. + Command->waitPhysical = waitPhysical;
  113889. + Command->waitLogical = waitLogical;
  113890. + Command->waitSize = waitSize;
  113891. +
  113892. + /* Update queue tail pointer. */
  113893. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(
  113894. + hardware, Command->logical, Command->offset
  113895. + ));
  113896. +
  113897. +#if gcdDUMP_COMMAND
  113898. + gcmkPRINT("@[kernel.commit]");
  113899. +#endif
  113900. +#endif /* gcdNULL_DRIVER */
  113901. +
  113902. + /* Release the context switching mutex. */
  113903. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  113904. + contextAcquired = gcvFALSE;
  113905. +
  113906. + /* Release the command queue. */
  113907. + gcmkONERROR(gckCOMMAND_ExitCommit(Command, gcvFALSE));
  113908. + commitEntered = gcvFALSE;
  113909. +
  113910. +#if VIVANTE_PROFILER_CONTEXT
  113911. + if(sequenceAcquired)
  113912. + {
  113913. + gcmkONERROR(gckCOMMAND_Stall(Command, gcvTRUE));
  113914. + if (Command->currContext)
  113915. + {
  113916. + gcmkONERROR(gckHARDWARE_UpdateContextProfile(
  113917. + hardware,
  113918. + Command->currContext));
  113919. + }
  113920. +
  113921. + /* Release the context switching mutex. */
  113922. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContextSeq));
  113923. + sequenceAcquired = gcvFALSE;
  113924. + }
  113925. +#endif
  113926. +
  113927. + /* Loop while there are records in the queue. */
  113928. + while (EventQueue != gcvNULL)
  113929. + {
  113930. + if (needCopy)
  113931. + {
  113932. + /* Point to stack record. */
  113933. + eventRecord = &_eventRecord;
  113934. +
  113935. + /* Copy the data from the client. */
  113936. + gcmkONERROR(gckOS_CopyFromUserData(
  113937. + Command->os, eventRecord, EventQueue, gcmSIZEOF(gcsQUEUE)
  113938. + ));
  113939. + }
  113940. + else
  113941. + {
  113942. + /* Map record into kernel memory. */
  113943. + gcmkONERROR(gckOS_MapUserPointer(Command->os,
  113944. + EventQueue,
  113945. + gcmSIZEOF(gcsQUEUE),
  113946. + &pointer));
  113947. +
  113948. + eventRecord = pointer;
  113949. + }
  113950. +
  113951. + /* Append event record to event queue. */
  113952. + gcmkONERROR(gckEVENT_AddList(
  113953. + Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE
  113954. + ));
  113955. +
  113956. + /* Next record in the queue. */
  113957. + nextEventRecord = gcmUINT64_TO_PTR(eventRecord->next);
  113958. +
  113959. + if (!needCopy)
  113960. + {
  113961. + /* Unmap record from kernel memory. */
  113962. + gcmkONERROR(gckOS_UnmapUserPointer(
  113963. + Command->os, EventQueue, gcmSIZEOF(gcsQUEUE), (gctPOINTER *) eventRecord
  113964. + ));
  113965. +
  113966. + eventRecord = gcvNULL;
  113967. + }
  113968. +
  113969. + EventQueue = nextEventRecord;
  113970. + }
  113971. +
  113972. + if (Command->kernel->eventObj->queueHead == gcvNULL
  113973. + && Command->kernel->hardware->powerManagement == gcvTRUE
  113974. + )
  113975. + {
  113976. + /* Commit done event by which work thread knows all jobs done. */
  113977. + gcmkVERIFY_OK(
  113978. + gckEVENT_CommitDone(Command->kernel->eventObj, gcvKERNEL_PIXEL));
  113979. + }
  113980. +
  113981. + /* Submit events. */
  113982. + status = gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE);
  113983. +
  113984. + if (status == gcvSTATUS_INTERRUPTED)
  113985. + {
  113986. + gcmkTRACE(
  113987. + gcvLEVEL_INFO,
  113988. + "%s(%d): Intterupted in gckEVENT_Submit",
  113989. + __FUNCTION__, __LINE__
  113990. + );
  113991. + status = gcvSTATUS_OK;
  113992. + }
  113993. + else
  113994. + {
  113995. + gcmkONERROR(status);
  113996. + }
  113997. +
  113998. + /* Unmap the command buffer pointer. */
  113999. + if (commandBufferMapped)
  114000. + {
  114001. + gcmkONERROR(gckOS_UnmapUserPointer(
  114002. + Command->os,
  114003. + CommandBuffer,
  114004. + gcmSIZEOF(struct _gcoCMDBUF),
  114005. + commandBufferObject
  114006. + ));
  114007. +
  114008. + commandBufferMapped = gcvFALSE;
  114009. + }
  114010. +
  114011. + /* Return status. */
  114012. + gcmkFOOTER();
  114013. + return gcvSTATUS_OK;
  114014. +
  114015. +OnError:
  114016. + if ((eventRecord != gcvNULL) && !needCopy)
  114017. + {
  114018. + /* Roll back. */
  114019. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  114020. + Command->os,
  114021. + EventQueue,
  114022. + gcmSIZEOF(gcsQUEUE),
  114023. + (gctPOINTER *) eventRecord
  114024. + ));
  114025. + }
  114026. +
  114027. + if (contextAcquired)
  114028. + {
  114029. + /* Release the context switching mutex. */
  114030. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  114031. + }
  114032. +
  114033. + if (commitEntered)
  114034. + {
  114035. + /* Release the command queue mutex. */
  114036. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Command, gcvFALSE));
  114037. + }
  114038. +
  114039. +#if VIVANTE_PROFILER_CONTEXT
  114040. + if (sequenceAcquired)
  114041. + {
  114042. + /* Release the context sequence mutex. */
  114043. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContextSeq));
  114044. + }
  114045. +#endif
  114046. +
  114047. + /* Unmap the command buffer pointer. */
  114048. + if (commandBufferMapped)
  114049. + {
  114050. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(
  114051. + Command->os,
  114052. + CommandBuffer,
  114053. + gcmSIZEOF(struct _gcoCMDBUF),
  114054. + commandBufferObject
  114055. + ));
  114056. + }
  114057. +
  114058. + /* Return status. */
  114059. + gcmkFOOTER();
  114060. + return status;
  114061. +}
  114062. +
  114063. +/*******************************************************************************
  114064. +**
  114065. +** gckCOMMAND_Reserve
  114066. +**
  114067. +** Reserve space in the command queue. Also acquire the command queue mutex.
  114068. +**
  114069. +** INPUT:
  114070. +**
  114071. +** gckCOMMAND Command
  114072. +** Pointer to an gckCOMMAND object.
  114073. +**
  114074. +** gctSIZE_T RequestedBytes
  114075. +** Number of bytes previously reserved.
  114076. +**
  114077. +** OUTPUT:
  114078. +**
  114079. +** gctPOINTER * Buffer
  114080. +** Pointer to a variable that will receive the address of the reserved
  114081. +** space.
  114082. +**
  114083. +** gctSIZE_T * BufferSize
  114084. +** Pointer to a variable that will receive the number of bytes
  114085. +** available in the command queue.
  114086. +*/
  114087. +gceSTATUS
  114088. +gckCOMMAND_Reserve(
  114089. + IN gckCOMMAND Command,
  114090. + IN gctSIZE_T RequestedBytes,
  114091. + OUT gctPOINTER * Buffer,
  114092. + OUT gctSIZE_T * BufferSize
  114093. + )
  114094. +{
  114095. + gceSTATUS status;
  114096. + gctSIZE_T bytes;
  114097. + gctSIZE_T requiredBytes;
  114098. + gctUINT32 requestedAligned;
  114099. +
  114100. + gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
  114101. +
  114102. + /* Verify the arguments. */
  114103. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  114104. +
  114105. + /* Compute aligned number of reuested bytes. */
  114106. + requestedAligned = gcmALIGN(RequestedBytes, Command->alignment);
  114107. +
  114108. + /* Another WAIT/LINK command sequence will have to be appended after
  114109. + the requested area being reserved. Compute the number of bytes
  114110. + required for WAIT/LINK at the location after the reserved area. */
  114111. + gcmkONERROR(gckHARDWARE_WaitLink(
  114112. + Command->kernel->hardware,
  114113. + gcvNULL,
  114114. + Command->offset + requestedAligned,
  114115. + &requiredBytes,
  114116. + gcvNULL,
  114117. + gcvNULL
  114118. + ));
  114119. +
  114120. + /* Compute total number of bytes required. */
  114121. + requiredBytes += requestedAligned;
  114122. +
  114123. + /* Compute number of bytes available in command queue. */
  114124. + bytes = Command->pageSize - Command->offset;
  114125. +
  114126. + /* Is there enough space in the current command queue? */
  114127. + if (bytes < requiredBytes)
  114128. + {
  114129. + /* Create a new command queue. */
  114130. + gcmkONERROR(_NewQueue(Command));
  114131. +
  114132. + /* Recompute the number of bytes in the new kernel command queue. */
  114133. + bytes = Command->pageSize - Command->offset;
  114134. +
  114135. + /* Still not enough space? */
  114136. + if (bytes < requiredBytes)
  114137. + {
  114138. + /* Rare case, not enough room in command queue. */
  114139. + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
  114140. + }
  114141. + }
  114142. +
  114143. + /* Return pointer to empty slot command queue. */
  114144. + *Buffer = (gctUINT8 *) Command->logical + Command->offset;
  114145. +
  114146. + /* Return number of bytes left in command queue. */
  114147. + *BufferSize = bytes;
  114148. +
  114149. + /* Success. */
  114150. + gcmkFOOTER_ARG("*Buffer=0x%x *BufferSize=%lu", *Buffer, *BufferSize);
  114151. + return gcvSTATUS_OK;
  114152. +
  114153. +OnError:
  114154. + /* Return status. */
  114155. + gcmkFOOTER();
  114156. + return status;
  114157. +}
  114158. +
  114159. +/*******************************************************************************
  114160. +**
  114161. +** gckCOMMAND_Execute
  114162. +**
  114163. +** Execute a previously reserved command queue by appending a WAIT/LINK command
  114164. +** sequence after it and modifying the last WAIT into a LINK command. The
  114165. +** command FIFO mutex will be released whether this function succeeds or not.
  114166. +**
  114167. +** INPUT:
  114168. +**
  114169. +** gckCOMMAND Command
  114170. +** Pointer to an gckCOMMAND object.
  114171. +**
  114172. +** gctSIZE_T RequestedBytes
  114173. +** Number of bytes previously reserved.
  114174. +**
  114175. +** OUTPUT:
  114176. +**
  114177. +** Nothing.
  114178. +*/
  114179. +gceSTATUS
  114180. +gckCOMMAND_Execute(
  114181. + IN gckCOMMAND Command,
  114182. + IN gctSIZE_T RequestedBytes
  114183. + )
  114184. +{
  114185. + gceSTATUS status;
  114186. +
  114187. + gctPHYS_ADDR waitLinkPhysical;
  114188. + gctUINT8_PTR waitLinkLogical;
  114189. + gctUINT32 waitLinkOffset;
  114190. + gctSIZE_T waitLinkBytes;
  114191. +
  114192. + gctPHYS_ADDR waitPhysical;
  114193. + gctPOINTER waitLogical;
  114194. + gctUINT32 waitOffset;
  114195. + gctSIZE_T waitBytes;
  114196. +
  114197. +#if gcdNONPAGED_MEMORY_CACHEABLE
  114198. + gctPHYS_ADDR execPhysical;
  114199. +#endif
  114200. + gctPOINTER execLogical;
  114201. + gctSIZE_T execBytes;
  114202. +
  114203. + gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
  114204. +
  114205. + /* Verify the arguments. */
  114206. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  114207. +
  114208. + /* Compute offset for WAIT/LINK. */
  114209. + waitLinkOffset = Command->offset + RequestedBytes;
  114210. +
  114211. + /* Compute number of bytes left in command queue. */
  114212. + waitLinkBytes = Command->pageSize - waitLinkOffset;
  114213. +
  114214. + /* Compute the location if WAIT/LINK command sequence. */
  114215. + waitLinkPhysical = (gctUINT8_PTR) Command->physical + waitLinkOffset;
  114216. + waitLinkLogical = (gctUINT8_PTR) Command->logical + waitLinkOffset;
  114217. +
  114218. + /* Append WAIT/LINK in command queue. */
  114219. + gcmkONERROR(gckHARDWARE_WaitLink(
  114220. + Command->kernel->hardware,
  114221. + waitLinkLogical,
  114222. + waitLinkOffset,
  114223. + &waitLinkBytes,
  114224. + &waitOffset,
  114225. + &waitBytes
  114226. + ));
  114227. +
  114228. + /* Compute the location if WAIT command. */
  114229. + waitPhysical = (gctUINT8_PTR) waitLinkPhysical + waitOffset;
  114230. + waitLogical = waitLinkLogical + waitOffset;
  114231. +
  114232. + /* Determine the location to jump to for the command buffer being
  114233. + ** scheduled. */
  114234. + if (Command->newQueue)
  114235. + {
  114236. + /* New command queue, jump to the beginning of it. */
  114237. +#if gcdNONPAGED_MEMORY_CACHEABLE
  114238. + execPhysical = Command->physical;
  114239. +#endif
  114240. + execLogical = Command->logical;
  114241. + execBytes = waitLinkOffset + waitLinkBytes;
  114242. + }
  114243. + else
  114244. + {
  114245. + /* Still within the preexisting command queue, jump directly to the
  114246. + reserved area. */
  114247. +#if gcdNONPAGED_MEMORY_CACHEABLE
  114248. + execPhysical = (gctUINT8 *) Command->physical + Command->offset;
  114249. +#endif
  114250. + execLogical = (gctUINT8 *) Command->logical + Command->offset;
  114251. + execBytes = RequestedBytes + waitLinkBytes;
  114252. + }
  114253. +
  114254. +#if gcdNONPAGED_MEMORY_CACHEABLE
  114255. + /* Flush the cache. */
  114256. + gcmkONERROR(gckOS_CacheClean(
  114257. + Command->os,
  114258. + Command->kernelProcessID,
  114259. + gcvNULL,
  114260. + execPhysical,
  114261. + execLogical,
  114262. + execBytes
  114263. + ));
  114264. +#endif
  114265. +
  114266. + /* Convert the last WAIT into a LINK. */
  114267. + gcmkONERROR(gckHARDWARE_Link(
  114268. + Command->kernel->hardware,
  114269. + Command->waitLogical,
  114270. + execLogical,
  114271. + execBytes,
  114272. + &Command->waitSize
  114273. + ));
  114274. +
  114275. +#if gcdNONPAGED_MEMORY_CACHEABLE
  114276. + /* Flush the cache. */
  114277. + gcmkONERROR(gckOS_CacheClean(
  114278. + Command->os,
  114279. + Command->kernelProcessID,
  114280. + gcvNULL,
  114281. + Command->waitPhysical,
  114282. + Command->waitLogical,
  114283. + Command->waitSize
  114284. + ));
  114285. +#endif
  114286. +
  114287. + gcmkDUMPCOMMAND(
  114288. + Command->os,
  114289. + Command->waitLogical,
  114290. + Command->waitSize,
  114291. + gceDUMP_BUFFER_LINK,
  114292. + gcvFALSE
  114293. + );
  114294. +
  114295. + gcmkDUMPCOMMAND(
  114296. + Command->os,
  114297. + execLogical,
  114298. + execBytes,
  114299. + gceDUMP_BUFFER_KERNEL,
  114300. + gcvFALSE
  114301. + );
  114302. +
  114303. + /* Update the pointer to the last WAIT. */
  114304. + Command->waitPhysical = waitPhysical;
  114305. + Command->waitLogical = waitLogical;
  114306. + Command->waitSize = waitBytes;
  114307. +
  114308. + /* Update the command queue. */
  114309. + Command->offset += RequestedBytes + waitLinkBytes;
  114310. + Command->newQueue = gcvFALSE;
  114311. +
  114312. + /* Update queue tail pointer. */
  114313. + gcmkONERROR(gckHARDWARE_UpdateQueueTail(
  114314. + Command->kernel->hardware, Command->logical, Command->offset
  114315. + ));
  114316. +
  114317. +#if gcdDUMP_COMMAND
  114318. + gcmkPRINT("@[kernel.execute]");
  114319. +#endif
  114320. +
  114321. + /* Success. */
  114322. + gcmkFOOTER_NO();
  114323. + return gcvSTATUS_OK;
  114324. +
  114325. +OnError:
  114326. + /* Return the status. */
  114327. + gcmkFOOTER();
  114328. + return status;
  114329. +}
  114330. +
  114331. +/*******************************************************************************
  114332. +**
  114333. +** gckCOMMAND_Stall
  114334. +**
  114335. +** The calling thread will be suspended until the command queue has been
  114336. +** completed.
  114337. +**
  114338. +** INPUT:
  114339. +**
  114340. +** gckCOMMAND Command
  114341. +** Pointer to an gckCOMMAND object.
  114342. +**
  114343. +** gctBOOL FromPower
  114344. +** Determines whether the call originates from inside the power
  114345. +** management or not.
  114346. +**
  114347. +** OUTPUT:
  114348. +**
  114349. +** Nothing.
  114350. +*/
  114351. +gceSTATUS
  114352. +gckCOMMAND_Stall(
  114353. + IN gckCOMMAND Command,
  114354. + IN gctBOOL FromPower
  114355. + )
  114356. +{
  114357. +#if gcdNULL_DRIVER
  114358. + /* Do nothing with infinite hardware. */
  114359. + return gcvSTATUS_OK;
  114360. +#else
  114361. + gckOS os;
  114362. + gckHARDWARE hardware;
  114363. + gckEVENT eventObject;
  114364. + gceSTATUS status;
  114365. + gctSIGNAL signal = gcvNULL;
  114366. + gctUINT timer = 0;
  114367. +
  114368. + gcmkHEADER_ARG("Command=0x%x", Command);
  114369. +
  114370. + /* Verify the arguments. */
  114371. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  114372. +
  114373. + /* Extract the gckOS object pointer. */
  114374. + os = Command->os;
  114375. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  114376. +
  114377. + /* Extract the gckHARDWARE object pointer. */
  114378. + hardware = Command->kernel->hardware;
  114379. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  114380. +
  114381. + /* Extract the gckEVENT object pointer. */
  114382. + eventObject = Command->kernel->eventObj;
  114383. + gcmkVERIFY_OBJECT(eventObject, gcvOBJ_EVENT);
  114384. +
  114385. + /* Allocate the signal. */
  114386. + gcmkONERROR(gckOS_CreateSignal(os, gcvTRUE, &signal));
  114387. +
  114388. + /* Append the EVENT command to trigger the signal. */
  114389. + gcmkONERROR(gckEVENT_Signal(eventObject, signal, gcvKERNEL_PIXEL));
  114390. +
  114391. + /* Submit the event queue. */
  114392. + gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower));
  114393. +
  114394. +#if gcdDUMP_COMMAND
  114395. + gcmkPRINT("@[kernel.stall]");
  114396. +#endif
  114397. +
  114398. + if (status == gcvSTATUS_CHIP_NOT_READY)
  114399. + {
  114400. + /* Error. */
  114401. + goto OnError;
  114402. + }
  114403. +
  114404. + do
  114405. + {
  114406. + /* Wait for the signal. */
  114407. + status = gckOS_WaitSignal(os, signal, gcdGPU_ADVANCETIMER);
  114408. +
  114409. + if (status == gcvSTATUS_TIMEOUT)
  114410. + {
  114411. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  114412. + gctUINT32 idle;
  114413. +
  114414. + /* Read idle register. */
  114415. + gcmkVERIFY_OK(gckHARDWARE_GetIdle(
  114416. + hardware, gcvFALSE, &idle
  114417. + ));
  114418. +
  114419. + gcmkTRACE(
  114420. + gcvLEVEL_ERROR,
  114421. + "%s(%d): idle=%08x",
  114422. + __FUNCTION__, __LINE__, idle
  114423. + );
  114424. +
  114425. + gcmkONERROR(gckOS_MemoryBarrier(os, gcvNULL));
  114426. +
  114427. +#ifdef __QNXNTO__
  114428. + gctUINT32 reg_cmdbuf_fetch;
  114429. + gctUINT32 reg_intr;
  114430. +
  114431. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(
  114432. + Command->kernel->hardware->os, Command->kernel->core, 0x0664, &reg_cmdbuf_fetch
  114433. + ));
  114434. +
  114435. + if (idle == 0x7FFFFFFE)
  114436. + {
  114437. + /*
  114438. + * GPU is idle so there should not be pending interrupts.
  114439. + * Just double check.
  114440. + *
  114441. + * Note that reading interrupt register clears it.
  114442. + * That's why we don't read it in all cases.
  114443. + */
  114444. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(
  114445. + Command->kernel->hardware->os, Command->kernel->core, 0x10, &reg_intr
  114446. + ));
  114447. +
  114448. + slogf(
  114449. + _SLOG_SETCODE(1, 0),
  114450. + _SLOG_CRITICAL,
  114451. + "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X, interrupt = 0x%X)",
  114452. + idle, reg_cmdbuf_fetch, reg_intr
  114453. + );
  114454. + }
  114455. + else
  114456. + {
  114457. + slogf(
  114458. + _SLOG_SETCODE(1, 0),
  114459. + _SLOG_CRITICAL,
  114460. + "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X)",
  114461. + idle, reg_cmdbuf_fetch
  114462. + );
  114463. + }
  114464. +#endif
  114465. +#endif
  114466. + /* Advance timer. */
  114467. + timer += gcdGPU_ADVANCETIMER;
  114468. + }
  114469. + else if (status == gcvSTATUS_INTERRUPTED)
  114470. + {
  114471. + gcmkONERROR(gcvSTATUS_INTERRUPTED);
  114472. + }
  114473. +
  114474. + }
  114475. + while (gcmIS_ERROR(status)
  114476. +#if gcdGPU_TIMEOUT
  114477. + && (timer < Command->kernel->timeOut)
  114478. +#endif
  114479. + );
  114480. +
  114481. + /* Bail out on timeout. */
  114482. + if (gcmIS_ERROR(status))
  114483. + {
  114484. + /* Broadcast the stuck GPU. */
  114485. + gcmkONERROR(gckOS_Broadcast(
  114486. + os, hardware, gcvBROADCAST_GPU_STUCK
  114487. + ));
  114488. + }
  114489. +
  114490. + /* Delete the signal. */
  114491. + gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
  114492. +
  114493. + /* Success. */
  114494. + gcmkFOOTER_NO();
  114495. + return gcvSTATUS_OK;
  114496. +
  114497. +OnError:
  114498. + if (signal != gcvNULL)
  114499. + {
  114500. + /* Free the signal. */
  114501. + gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
  114502. + }
  114503. +
  114504. + /* Return the status. */
  114505. + gcmkFOOTER();
  114506. + return status;
  114507. +#endif
  114508. +}
  114509. +
  114510. +/*******************************************************************************
  114511. +**
  114512. +** gckCOMMAND_Attach
  114513. +**
  114514. +** Attach user process.
  114515. +**
  114516. +** INPUT:
  114517. +**
  114518. +** gckCOMMAND Command
  114519. +** Pointer to a gckCOMMAND object.
  114520. +**
  114521. +** gctUINT32 ProcessID
  114522. +** Current process ID.
  114523. +**
  114524. +** OUTPUT:
  114525. +**
  114526. +** gckCONTEXT * Context
  114527. +** Pointer to a variable that will receive a pointer to a new
  114528. +** gckCONTEXT object.
  114529. +**
  114530. +** gctSIZE_T * StateCount
  114531. +** Pointer to a variable that will receive the number of states
  114532. +** in the context buffer.
  114533. +*/
  114534. +gceSTATUS
  114535. +gckCOMMAND_Attach(
  114536. + IN gckCOMMAND Command,
  114537. + OUT gckCONTEXT * Context,
  114538. + OUT gctSIZE_T * StateCount,
  114539. + IN gctUINT32 ProcessID
  114540. + )
  114541. +{
  114542. + gceSTATUS status;
  114543. + gctBOOL acquired = gcvFALSE;
  114544. +
  114545. + gcmkHEADER_ARG("Command=0x%x", Command);
  114546. +
  114547. + /* Verify the arguments. */
  114548. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  114549. +
  114550. + /* Acquire the context switching mutex. */
  114551. + gcmkONERROR(gckOS_AcquireMutex(
  114552. + Command->os, Command->mutexContext, gcvINFINITE
  114553. + ));
  114554. + acquired = gcvTRUE;
  114555. +
  114556. + /* Construct a gckCONTEXT object. */
  114557. + gcmkONERROR(gckCONTEXT_Construct(
  114558. + Command->os,
  114559. + Command->kernel->hardware,
  114560. + ProcessID,
  114561. + Context
  114562. + ));
  114563. +
  114564. + /* Return the number of states in the context. */
  114565. + * StateCount = (* Context)->stateCount;
  114566. +
  114567. + /* Release the context switching mutex. */
  114568. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  114569. + acquired = gcvFALSE;
  114570. +
  114571. + /* Success. */
  114572. + gcmkFOOTER_ARG("*Context=0x%x", *Context);
  114573. + return gcvSTATUS_OK;
  114574. +
  114575. +OnError:
  114576. + /* Release mutex. */
  114577. + if (acquired)
  114578. + {
  114579. + /* Release the context switching mutex. */
  114580. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  114581. + acquired = gcvFALSE;
  114582. + }
  114583. +
  114584. + /* Return the status. */
  114585. + gcmkFOOTER();
  114586. + return status;
  114587. +}
  114588. +
  114589. +/*******************************************************************************
  114590. +**
  114591. +** gckCOMMAND_Detach
  114592. +**
  114593. +** Detach user process.
  114594. +**
  114595. +** INPUT:
  114596. +**
  114597. +** gckCOMMAND Command
  114598. +** Pointer to a gckCOMMAND object.
  114599. +**
  114600. +** gckCONTEXT Context
  114601. +** Pointer to a gckCONTEXT object to be destroyed.
  114602. +**
  114603. +** OUTPUT:
  114604. +**
  114605. +** Nothing.
  114606. +*/
  114607. +gceSTATUS
  114608. +gckCOMMAND_Detach(
  114609. + IN gckCOMMAND Command,
  114610. + IN gckCONTEXT Context
  114611. + )
  114612. +{
  114613. + gceSTATUS status;
  114614. + gctBOOL acquired = gcvFALSE;
  114615. +
  114616. + gcmkHEADER_ARG("Command=0x%x Context=0x%x", Command, Context);
  114617. +
  114618. + /* Verify the arguments. */
  114619. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  114620. +
  114621. + /* Acquire the context switching mutex. */
  114622. + gcmkONERROR(gckOS_AcquireMutex(
  114623. + Command->os, Command->mutexContext, gcvINFINITE
  114624. + ));
  114625. + acquired = gcvTRUE;
  114626. +
  114627. + /* Construct a gckCONTEXT object. */
  114628. + gcmkONERROR(gckCONTEXT_Destroy(Context));
  114629. +
  114630. + if (Command->currContext == Context)
  114631. + {
  114632. + /* Detach from gckCOMMAND object if the destoryed context is current context. */
  114633. + Command->currContext = gcvNULL;
  114634. + }
  114635. +
  114636. + /* Release the context switching mutex. */
  114637. + gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  114638. + acquired = gcvFALSE;
  114639. +
  114640. + /* Return the status. */
  114641. + gcmkFOOTER();
  114642. + return gcvSTATUS_OK;
  114643. +
  114644. +OnError:
  114645. + /* Release mutex. */
  114646. + if (acquired)
  114647. + {
  114648. + /* Release the context switching mutex. */
  114649. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
  114650. + acquired = gcvFALSE;
  114651. + }
  114652. +
  114653. + /* Return the status. */
  114654. + gcmkFOOTER();
  114655. + return status;
  114656. +}
  114657. +
  114658. +#if gcdVIRTUAL_COMMAND_BUFFER
  114659. +/*******************************************************************************
  114660. +**
  114661. +** gckCOMMAND_DumpExecutingBuffer
  114662. +**
  114663. +** Dump the command buffer which GPU is executing.
  114664. +**
  114665. +** INPUT:
  114666. +**
  114667. +** gckCOMMAND Command
  114668. +** Pointer to a gckCOMMAND object.
  114669. +**
  114670. +** OUTPUT:
  114671. +**
  114672. +** Nothing.
  114673. +*/
  114674. +gceSTATUS
  114675. +gckCOMMAND_DumpExecutingBuffer(
  114676. + IN gckCOMMAND Command
  114677. + )
  114678. +{
  114679. + gceSTATUS status;
  114680. + gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
  114681. + gctUINT32 gpuAddress;
  114682. + gctSIZE_T pageCount;
  114683. + gctPOINTER entry;
  114684. + gckOS os = Command->os;
  114685. + gckKERNEL kernel = Command->kernel;
  114686. +#if gcdLINK_QUEUE_SIZE
  114687. + gctINT pid;
  114688. + gctINT i, rear;
  114689. + gctUINT32 start, end;
  114690. + gctUINT32 dumpFront, dumpRear;
  114691. + gckLINKQUEUE queue = &kernel->hardware->linkQueue;
  114692. + gckLINKQUEUE queueMirror;
  114693. + gctUINT32 bytes;
  114694. + gckLINKDATA linkData;
  114695. +#endif
  114696. +
  114697. + gcmkPRINT("**************************\n");
  114698. + gcmkPRINT("**** COMMAND BUF DUMP ****\n");
  114699. + gcmkPRINT("**************************\n");
  114700. +
  114701. + gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress));
  114702. +
  114703. + gcmkPRINT("DMA Address 0x%08X", gpuAddress);
  114704. +
  114705. +#if gcdLINK_QUEUE_SIZE
  114706. + /* Duplicate queue because it will be changed.*/
  114707. + gcmkONERROR(gckOS_AllocateMemory(os,
  114708. + sizeof(struct _gckLINKQUEUE),
  114709. + (gctPOINTER *)&queueMirror));
  114710. +
  114711. + gcmkONERROR(gckOS_MemCopy(queueMirror,
  114712. + queue,
  114713. + sizeof(struct _gckLINKQUEUE)));
  114714. +
  114715. + /* If kernel command buffer link to a context buffer, then link to a user command
  114716. + ** buffer, the second link will be in queue first, so we must fix this.
  114717. + ** In Queue: C1 U1 U2 C2 U3 U4 U5 C3
  114718. + ** Real: C1 X1 U1 C2 U2 U3 U4 C3 U5
  114719. + ** Command buffer X1 which is after C1 is out of queue, so C1 is meaningless.
  114720. + */
  114721. + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
  114722. + {
  114723. + gckLINKQUEUE_GetData(queueMirror, i, &linkData);
  114724. +
  114725. + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
  114726. +
  114727. + if (gcmIS_ERROR(status))
  114728. + {
  114729. + /* Can't find it in virtual command buffer list, ignore it. */
  114730. + continue;
  114731. + }
  114732. +
  114733. + if (buffer->kernelLogical)
  114734. + {
  114735. + /* It is a context buffer. */
  114736. + if (i == 0)
  114737. + {
  114738. + /* The real command buffer is out, so clear this slot. */
  114739. + linkData->start = 0;
  114740. + linkData->end = 0;
  114741. + linkData->pid = 0;
  114742. + }
  114743. + else
  114744. + {
  114745. + /* switch context buffer and command buffer. */
  114746. + struct _gckLINKDATA tmp = *linkData;
  114747. + gckLINKDATA linkDataPrevious;
  114748. +
  114749. + gckLINKQUEUE_GetData(queueMirror, i - 1, &linkDataPrevious);
  114750. + *linkData = *linkDataPrevious;
  114751. + *linkDataPrevious = tmp;
  114752. + }
  114753. + }
  114754. + }
  114755. +
  114756. + /* Clear search result. */
  114757. + dumpFront = dumpRear = gcvINFINITE;
  114758. +
  114759. + gcmkPRINT("Link Stack:");
  114760. +
  114761. + /* Search stuck address in link queue from rear. */
  114762. + rear = gcdLINK_QUEUE_SIZE - 1;
  114763. + for (i = 0; i < gcdLINK_QUEUE_SIZE; i++)
  114764. + {
  114765. + gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
  114766. +
  114767. + start = linkData->start;
  114768. + end = linkData->end;
  114769. + pid = linkData->pid;
  114770. +
  114771. + if (gpuAddress >= start && gpuAddress < end)
  114772. + {
  114773. + /* Find latest matched command buffer. */
  114774. + gcmkPRINT(" %d, [%08X - %08X]", pid, start, end);
  114775. +
  114776. + /* Initiliaze dump information. */
  114777. + dumpFront = dumpRear = rear;
  114778. + }
  114779. +
  114780. + /* Advance to previous one. */
  114781. + rear--;
  114782. +
  114783. + if (dumpFront != gcvINFINITE)
  114784. + {
  114785. + break;
  114786. + }
  114787. + }
  114788. +
  114789. + if (dumpFront == gcvINFINITE)
  114790. + {
  114791. + /* Can't find matched record in link queue, dump kernel command buffer. */
  114792. + _DumpKernelCommandBuffer(Command);
  114793. +
  114794. + /* Free local copy. */
  114795. + gcmkOS_SAFE_FREE(os, queueMirror);
  114796. + return gcvSTATUS_OK;
  114797. + }
  114798. +
  114799. + /* Search the last context buffer linked. */
  114800. + while (rear >= 0)
  114801. + {
  114802. + gckLINKQUEUE_GetData(queueMirror, rear, &linkData);
  114803. +
  114804. + gcmkPRINT(" %d, [%08X - %08X]",
  114805. + linkData->pid,
  114806. + linkData->start,
  114807. + linkData->end);
  114808. +
  114809. + status = gckKERNEL_QueryGPUAddress(kernel, linkData->start, &buffer);
  114810. +
  114811. + if (gcmIS_SUCCESS(status) && buffer->kernelLogical)
  114812. + {
  114813. + /* Find a context buffer. */
  114814. + dumpFront = rear;
  114815. + break;
  114816. + }
  114817. +
  114818. + rear--;
  114819. + }
  114820. +
  114821. + /* Dump from last context buffer to last command buffer where hang happens. */
  114822. + for (i = dumpFront; i <= dumpRear; i++)
  114823. + {
  114824. + gckLINKQUEUE_GetData(queueMirror, i, &linkData);
  114825. +
  114826. + /* Get gpu address of this command buffer. */
  114827. + gpuAddress = linkData->start;
  114828. + bytes = linkData->end - gpuAddress;
  114829. +
  114830. + /* Get the whole buffer. */
  114831. + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
  114832. +
  114833. + if (gcmIS_ERROR(status))
  114834. + {
  114835. + gcmkPRINT("Buffer [%08X - %08X] is lost",
  114836. + linkData->start,
  114837. + linkData->end);
  114838. + continue;
  114839. + }
  114840. +
  114841. + /* Get kernel logical for dump. */
  114842. + if (buffer->kernelLogical)
  114843. + {
  114844. + /* Get kernel logical directly if it is a context buffer. */
  114845. + entry = buffer->kernelLogical;
  114846. + gcmkPRINT("Context Buffer:");
  114847. + }
  114848. + else
  114849. + {
  114850. + /* Make it accessiable by kernel if it is a user command buffer. */
  114851. + gcmkVERIFY_OK(
  114852. + gckOS_CreateKernelVirtualMapping(buffer->physical,
  114853. + &pageCount,
  114854. + &entry));
  114855. + gcmkPRINT("User Command Buffer:");
  114856. + }
  114857. +
  114858. + /* Dump from the entry. */
  114859. + _DumpBuffer(entry + (gpuAddress - buffer->gpuAddress), gpuAddress, bytes);
  114860. +
  114861. + /* Release kernel logical address if neccessary. */
  114862. + if (!buffer->kernelLogical)
  114863. + {
  114864. + gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(entry));
  114865. + }
  114866. + }
  114867. +
  114868. + /* Free local copy. */
  114869. + gcmkOS_SAFE_FREE(os, queueMirror);
  114870. + return gcvSTATUS_OK;
  114871. +OnError:
  114872. + return status;
  114873. +#else
  114874. + /* Without link queue information, we don't know the entry of last command
  114875. + ** buffer, just dump the page where GPU stuck. */
  114876. + status = gckKERNEL_QueryGPUAddress(kernel, gpuAddress, &buffer);
  114877. +
  114878. + if (gcmIS_SUCCESS(status))
  114879. + {
  114880. + gcmkVERIFY_OK(
  114881. + gckOS_CreateKernelVirtualMapping(buffer->physical, &pageCount, &entry));
  114882. +
  114883. + if (entry)
  114884. + {
  114885. + gctUINT32 offset = gpuAddress - buffer->gpuAddress;
  114886. + gctPOINTER entryDump = entry;
  114887. +
  114888. + /* Dump one pages. */
  114889. + gctUINT32 bytes = 4096;
  114890. +
  114891. + /* Align to page. */
  114892. + offset &= 0xfffff000;
  114893. +
  114894. + /* Kernel address of page where stall point stay. */
  114895. + entryDump += offset;
  114896. +
  114897. + /* Align to page. */
  114898. + gpuAddress &= 0xfffff000;
  114899. +
  114900. + gcmkPRINT("User Command Buffer:\n");
  114901. + _DumpBuffer(entryDump, gpuAddress, bytes);
  114902. + }
  114903. +
  114904. + gcmkVERIFY_OK(
  114905. + gckOS_DestroyKernelVirtualMapping(entry));
  114906. + }
  114907. + else
  114908. + {
  114909. + _DumpKernelCommandBuffer(Command);
  114910. + }
  114911. +
  114912. + return gcvSTATUS_OK;
  114913. +#endif
  114914. +}
  114915. +#endif
  114916. diff -Nur linux-3.14.17/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
  114917. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c 1970-01-01 01:00:00.000000000 +0100
  114918. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c 2014-09-11 18:06:03.082042291 +0200
  114919. @@ -0,0 +1,3677 @@
  114920. +/****************************************************************************
  114921. +*
  114922. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  114923. +*
  114924. +* This program is free software; you can redistribute it and/or modify
  114925. +* it under the terms of the GNU General Public License as published by
  114926. +* the Free Software Foundation; either version 2 of the license, or
  114927. +* (at your option) any later version.
  114928. +*
  114929. +* This program is distributed in the hope that it will be useful,
  114930. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  114931. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  114932. +* GNU General Public License for more details.
  114933. +*
  114934. +* You should have received a copy of the GNU General Public License
  114935. +* along with this program; if not write to the Free Software
  114936. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  114937. +*
  114938. +*****************************************************************************/
  114939. +
  114940. +
  114941. +#include "gc_hal_kernel_precomp.h"
  114942. +
  114943. +#if gcdENABLE_VG
  114944. +
  114945. +#include "gc_hal_kernel_hardware_command_vg.h"
  114946. +
  114947. +#define _GC_OBJ_ZONE gcvZONE_COMMAND
  114948. +
  114949. +/******************************************************************************\
  114950. +*********************************** Debugging **********************************
  114951. +\******************************************************************************/
  114952. +
  114953. +#define gcvDISABLE_TIMEOUT 1
  114954. +#define gcvDUMP_COMMAND_BUFFER 0
  114955. +#define gcvDUMP_COMMAND_LINES 0
  114956. +
  114957. +
  114958. +#if gcvDEBUG || defined(EMULATOR) || gcvDISABLE_TIMEOUT
  114959. +# define gcvQUEUE_TIMEOUT ~0
  114960. +#else
  114961. +# define gcvQUEUE_TIMEOUT 10
  114962. +#endif
  114963. +
  114964. +
  114965. +/******************************************************************************\
  114966. +********************************** Definitions *********************************
  114967. +\******************************************************************************/
  114968. +
  114969. +/* Minimum buffer size. */
  114970. +#define gcvMINUMUM_BUFFER \
  114971. + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER) + \
  114972. + gcmSIZEOF(gcsKERNEL_CMDQUEUE) * 2
  114973. +
  114974. +#define gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
  114975. + static gceSTATUS \
  114976. + _EventHandler_##Block##_##Number( \
  114977. + IN gckVGKERNEL Kernel \
  114978. + )
  114979. +
  114980. +#define gcmDEFINE_INTERRUPT_HANDLER(Block, Number) \
  114981. + gcmDECLARE_INTERRUPT_HANDLER(Block, Number) \
  114982. + { \
  114983. + return _EventHandler_Block( \
  114984. + Kernel, \
  114985. + &Kernel->command->taskTable[gcvBLOCK_##Block], \
  114986. + gcvFALSE \
  114987. + ); \
  114988. + }
  114989. +
  114990. +#define gcmDEFINE_INTERRUPT_HANDLER_ENTRY(Block, Number) \
  114991. + { gcvBLOCK_##Block, _EventHandler_##Block##_##Number }
  114992. +
  114993. +/* Block interrupt handling table entry. */
  114994. +typedef struct _gcsBLOCK_INTERRUPT_HANDLER * gcsBLOCK_INTERRUPT_HANDLER_PTR;
  114995. +typedef struct _gcsBLOCK_INTERRUPT_HANDLER
  114996. +{
  114997. + gceBLOCK block;
  114998. + gctINTERRUPT_HANDLER handler;
  114999. +}
  115000. +gcsBLOCK_INTERRUPT_HANDLER;
  115001. +
  115002. +/* Queue control functions. */
  115003. +typedef struct _gcsQUEUE_UPDATE_CONTROL * gcsQUEUE_UPDATE_CONTROL_PTR;
  115004. +typedef struct _gcsQUEUE_UPDATE_CONTROL
  115005. +{
  115006. + gctOBJECT_HANDLER execute;
  115007. + gctOBJECT_HANDLER update;
  115008. + gctOBJECT_HANDLER lastExecute;
  115009. + gctOBJECT_HANDLER lastUpdate;
  115010. +}
  115011. +gcsQUEUE_UPDATE_CONTROL;
  115012. +
  115013. +
  115014. +/******************************************************************************\
  115015. +********************************* Support Code *********************************
  115016. +\******************************************************************************/
  115017. +static gceSTATUS
  115018. +_FlushMMU(
  115019. + IN gckVGCOMMAND Command
  115020. + )
  115021. +{
  115022. + gceSTATUS status;
  115023. + gctUINT32 oldValue;
  115024. + gckVGHARDWARE hardware = Command->hardware;
  115025. +
  115026. + gcmkONERROR(gckOS_AtomicExchange(Command->os,
  115027. + hardware->pageTableDirty,
  115028. + 0,
  115029. + &oldValue));
  115030. +
  115031. + if (oldValue)
  115032. + {
  115033. + /* Page Table is upated, flush mmu before commit. */
  115034. + gcmkONERROR(gckVGHARDWARE_FlushMMU(hardware));
  115035. + }
  115036. +
  115037. + return gcvSTATUS_OK;
  115038. +OnError:
  115039. + return status;
  115040. +}
  115041. +
  115042. +static gceSTATUS
  115043. +_WaitForIdle(
  115044. + IN gckVGCOMMAND Command,
  115045. + IN gcsKERNEL_QUEUE_HEADER_PTR Queue
  115046. + )
  115047. +{
  115048. + gceSTATUS status = gcvSTATUS_OK;
  115049. + gctUINT32 idle;
  115050. + gctUINT timeout = 0;
  115051. +
  115052. + /* Loop while not idle. */
  115053. + while (Queue->pending)
  115054. + {
  115055. + /* Did we reach the timeout limit? */
  115056. + if (timeout == gcvQUEUE_TIMEOUT)
  115057. + {
  115058. + /* Hardware is probably dead... */
  115059. + return gcvSTATUS_TIMEOUT;
  115060. + }
  115061. +
  115062. + /* Sleep for 100ms. */
  115063. + gcmkERR_BREAK(gckOS_Delay(Command->os, 100));
  115064. +
  115065. + /* Not the first loop? */
  115066. + if (timeout > 0)
  115067. + {
  115068. + /* Read IDLE register. */
  115069. + gcmkVERIFY_OK(gckVGHARDWARE_GetIdle(Command->hardware, &idle));
  115070. +
  115071. + gcmkTRACE_ZONE(
  115072. + gcvLEVEL_ERROR, gcvZONE_COMMAND,
  115073. + "%s: timeout, IDLE=%08X\n",
  115074. + __FUNCTION__, idle
  115075. + );
  115076. + }
  115077. +
  115078. + /* Increment the timeout counter. */
  115079. + timeout += 1;
  115080. + }
  115081. +
  115082. + /* Return status. */
  115083. + return status;
  115084. +}
  115085. +
  115086. +static gctINT32
  115087. +_GetNextInterrupt(
  115088. + IN gckVGCOMMAND Command,
  115089. + IN gceBLOCK Block
  115090. + )
  115091. +{
  115092. + gctUINT index;
  115093. + gcsBLOCK_TASK_ENTRY_PTR entry;
  115094. + gctINT32 interrupt;
  115095. +
  115096. + /* Get the block entry. */
  115097. + entry = &Command->taskTable[Block];
  115098. +
  115099. + /* Make sure we have initialized interrupts. */
  115100. + gcmkASSERT(entry->interruptCount > 0);
  115101. +
  115102. + /* Decrement the interrupt usage semaphore. */
  115103. + gcmkVERIFY_OK(gckOS_DecrementSemaphore(
  115104. + Command->os, entry->interruptSemaphore
  115105. + ));
  115106. +
  115107. + /* Get the value index. */
  115108. + index = entry->interruptIndex;
  115109. +
  115110. + /* Get the interrupt value. */
  115111. + interrupt = entry->interruptArray[index];
  115112. +
  115113. + /* Must be a valid value. */
  115114. + gcmkASSERT((interrupt >= 0) && (interrupt <= 31));
  115115. +
  115116. + /* Advance the index to the next value. */
  115117. + index += 1;
  115118. +
  115119. + /* Set the new index. */
  115120. + entry->interruptIndex = (index == entry->interruptCount)
  115121. + ? 0
  115122. + : index;
  115123. +
  115124. + /* Return interrupt value. */
  115125. + return interrupt;
  115126. +}
  115127. +
  115128. +
  115129. +/******************************************************************************\
  115130. +***************************** Task Storage Management **************************
  115131. +\******************************************************************************/
  115132. +
  115133. +/* Minimum task buffer size. */
  115134. +#define gcvMIN_TASK_BUFFER \
  115135. +( \
  115136. + gcmSIZEOF(gcsTASK_CONTAINER) + 128 \
  115137. +)
  115138. +
  115139. +/* Free list terminator. */
  115140. +#define gcvFREE_TASK_TERMINATOR \
  115141. +( \
  115142. + (gcsTASK_CONTAINER_PTR) gcmINT2PTR(~0) \
  115143. +)
  115144. +
  115145. +
  115146. +/*----------------------------------------------------------------------------*/
  115147. +/*------------------- Allocated Task Buffer List Management ------------------*/
  115148. +
  115149. +static void
  115150. +_InsertTaskBuffer(
  115151. + IN gcsTASK_CONTAINER_PTR AddAfter,
  115152. + IN gcsTASK_CONTAINER_PTR Buffer
  115153. + )
  115154. +{
  115155. + gcsTASK_CONTAINER_PTR addBefore;
  115156. +
  115157. + /* Cannot add before the first buffer. */
  115158. + gcmkASSERT(AddAfter != gcvNULL);
  115159. +
  115160. + /* Create a shortcut to the next buffer. */
  115161. + addBefore = AddAfter->allocNext;
  115162. +
  115163. + /* Initialize the links. */
  115164. + Buffer->allocPrev = AddAfter;
  115165. + Buffer->allocNext = addBefore;
  115166. +
  115167. + /* Link to the previous buffer. */
  115168. + AddAfter->allocNext = Buffer;
  115169. +
  115170. + /* Link to the next buffer. */
  115171. + if (addBefore != gcvNULL)
  115172. + {
  115173. + addBefore->allocPrev = Buffer;
  115174. + }
  115175. +}
  115176. +
  115177. +static void
  115178. +_RemoveTaskBuffer(
  115179. + IN gcsTASK_CONTAINER_PTR Buffer
  115180. + )
  115181. +{
  115182. + gcsTASK_CONTAINER_PTR prev;
  115183. + gcsTASK_CONTAINER_PTR next;
  115184. +
  115185. + /* Cannot remove the first buffer. */
  115186. + gcmkASSERT(Buffer->allocPrev != gcvNULL);
  115187. +
  115188. + /* Create shortcuts to the previous and next buffers. */
  115189. + prev = Buffer->allocPrev;
  115190. + next = Buffer->allocNext;
  115191. +
  115192. + /* Tail buffer? */
  115193. + if (next == gcvNULL)
  115194. + {
  115195. + /* Remove from the list. */
  115196. + prev->allocNext = gcvNULL;
  115197. + }
  115198. +
  115199. + /* Buffer from the middle. */
  115200. + else
  115201. + {
  115202. + prev->allocNext = next;
  115203. + next->allocPrev = prev;
  115204. + }
  115205. +}
  115206. +
  115207. +
  115208. +/*----------------------------------------------------------------------------*/
  115209. +/*--------------------- Free Task Buffer List Management ---------------------*/
  115210. +
  115211. +static void
  115212. +_AppendToFreeList(
  115213. + IN gckVGCOMMAND Command,
  115214. + IN gcsTASK_CONTAINER_PTR Buffer
  115215. + )
  115216. +{
  115217. + /* Cannot be a part of the free list already. */
  115218. + gcmkASSERT(Buffer->freePrev == gcvNULL);
  115219. + gcmkASSERT(Buffer->freeNext == gcvNULL);
  115220. +
  115221. + /* First buffer to add? */
  115222. + if (Command->taskFreeHead == gcvNULL)
  115223. + {
  115224. + /* Terminate the links. */
  115225. + Buffer->freePrev = gcvFREE_TASK_TERMINATOR;
  115226. + Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
  115227. +
  115228. + /* Initialize the list pointer. */
  115229. + Command->taskFreeHead = Command->taskFreeTail = Buffer;
  115230. + }
  115231. +
  115232. + /* Not the first, add after the tail. */
  115233. + else
  115234. + {
  115235. + /* Initialize the new tail buffer. */
  115236. + Buffer->freePrev = Command->taskFreeTail;
  115237. + Buffer->freeNext = gcvFREE_TASK_TERMINATOR;
  115238. +
  115239. + /* Add after the tail. */
  115240. + Command->taskFreeTail->freeNext = Buffer;
  115241. + Command->taskFreeTail = Buffer;
  115242. + }
  115243. +}
  115244. +
  115245. +static void
  115246. +_RemoveFromFreeList(
  115247. + IN gckVGCOMMAND Command,
  115248. + IN gcsTASK_CONTAINER_PTR Buffer
  115249. + )
  115250. +{
  115251. + /* Has to be a part of the free list. */
  115252. + gcmkASSERT(Buffer->freePrev != gcvNULL);
  115253. + gcmkASSERT(Buffer->freeNext != gcvNULL);
  115254. +
  115255. + /* Head buffer? */
  115256. + if (Buffer->freePrev == gcvFREE_TASK_TERMINATOR)
  115257. + {
  115258. + /* Tail buffer as well? */
  115259. + if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
  115260. + {
  115261. + /* Reset the list pointer. */
  115262. + Command->taskFreeHead = Command->taskFreeTail = gcvNULL;
  115263. + }
  115264. +
  115265. + /* No, just the head. */
  115266. + else
  115267. + {
  115268. + /* Update the head. */
  115269. + Command->taskFreeHead = Buffer->freeNext;
  115270. +
  115271. + /* Terminate the next buffer. */
  115272. + Command->taskFreeHead->freePrev = gcvFREE_TASK_TERMINATOR;
  115273. + }
  115274. + }
  115275. +
  115276. + /* Not the head. */
  115277. + else
  115278. + {
  115279. + /* Tail buffer? */
  115280. + if (Buffer->freeNext == gcvFREE_TASK_TERMINATOR)
  115281. + {
  115282. + /* Update the tail. */
  115283. + Command->taskFreeTail = Buffer->freePrev;
  115284. +
  115285. + /* Terminate the previous buffer. */
  115286. + Command->taskFreeTail->freeNext = gcvFREE_TASK_TERMINATOR;
  115287. + }
  115288. +
  115289. + /* A buffer in the middle. */
  115290. + else
  115291. + {
  115292. + /* Remove the buffer from the list. */
  115293. + Buffer->freePrev->freeNext = Buffer->freeNext;
  115294. + Buffer->freeNext->freePrev = Buffer->freePrev;
  115295. + }
  115296. + }
  115297. +
  115298. + /* Reset free list pointers. */
  115299. + Buffer->freePrev = gcvNULL;
  115300. + Buffer->freeNext = gcvNULL;
  115301. +}
  115302. +
  115303. +
  115304. +/*----------------------------------------------------------------------------*/
  115305. +/*-------------------------- Task Buffer Allocation --------------------------*/
  115306. +
  115307. +static void
  115308. +_SplitTaskBuffer(
  115309. + IN gckVGCOMMAND Command,
  115310. + IN gcsTASK_CONTAINER_PTR Buffer,
  115311. + IN gctUINT Size
  115312. + )
  115313. +{
  115314. + /* Determine the size of the new buffer. */
  115315. + gctINT splitBufferSize = Buffer->size - Size;
  115316. + gcmkASSERT(splitBufferSize >= 0);
  115317. +
  115318. + /* Is the split buffer big enough to become a separate buffer? */
  115319. + if (splitBufferSize >= gcvMIN_TASK_BUFFER)
  115320. + {
  115321. + /* Place the new path data. */
  115322. + gcsTASK_CONTAINER_PTR splitBuffer = (gcsTASK_CONTAINER_PTR)
  115323. + (
  115324. + (gctUINT8_PTR) Buffer + Size
  115325. + );
  115326. +
  115327. + /* Set the trimmed buffer size. */
  115328. + Buffer->size = Size;
  115329. +
  115330. + /* Initialize the split buffer. */
  115331. + splitBuffer->referenceCount = 0;
  115332. + splitBuffer->size = splitBufferSize;
  115333. + splitBuffer->freePrev = gcvNULL;
  115334. + splitBuffer->freeNext = gcvNULL;
  115335. +
  115336. + /* Link in. */
  115337. + _InsertTaskBuffer(Buffer, splitBuffer);
  115338. + _AppendToFreeList(Command, splitBuffer);
  115339. + }
  115340. +}
  115341. +
  115342. +static gceSTATUS
  115343. +_AllocateTaskContainer(
  115344. + IN gckVGCOMMAND Command,
  115345. + IN gctUINT Size,
  115346. + OUT gcsTASK_CONTAINER_PTR * Buffer
  115347. + )
  115348. +{
  115349. + gceSTATUS status;
  115350. +
  115351. + gcmkHEADER_ARG("Command=0x%x Size=0x%x, Buffer ==0x%x", Command, Size, Buffer);
  115352. +
  115353. + /* Verify arguments. */
  115354. + gcmkVERIFY_ARGUMENT(Buffer != gcvNULL);
  115355. +
  115356. + do
  115357. + {
  115358. + gcsTASK_STORAGE_PTR storage;
  115359. + gcsTASK_CONTAINER_PTR buffer;
  115360. +
  115361. + /* Adjust the size. */
  115362. + Size += gcmSIZEOF(gcsTASK_CONTAINER);
  115363. +
  115364. + /* Adjust the allocation size if not big enough. */
  115365. + if (Size > Command->taskStorageUsable)
  115366. + {
  115367. + Command->taskStorageGranularity
  115368. + = gcmALIGN(Size + gcmSIZEOF(gcsTASK_STORAGE), 1024);
  115369. +
  115370. + Command->taskStorageUsable
  115371. + = Command->taskStorageGranularity - gcmSIZEOF(gcsTASK_STORAGE);
  115372. + }
  115373. +
  115374. + /* Is there a free buffer available? */
  115375. + else if (Command->taskFreeHead != gcvNULL)
  115376. + {
  115377. + /* Set the initial free buffer. */
  115378. + gcsTASK_CONTAINER_PTR buffer = Command->taskFreeHead;
  115379. +
  115380. + do
  115381. + {
  115382. + /* Is the buffer big enough? */
  115383. + if (buffer->size >= Size)
  115384. + {
  115385. + /* Remove the buffer from the free list. */
  115386. + _RemoveFromFreeList(Command, buffer);
  115387. +
  115388. + /* Split the buffer. */
  115389. + _SplitTaskBuffer(Command, buffer, Size);
  115390. +
  115391. + /* Set the result. */
  115392. + * Buffer = buffer;
  115393. +
  115394. + gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
  115395. + /* Success. */
  115396. + return gcvSTATUS_OK;
  115397. + }
  115398. +
  115399. + /* Get the next free buffer. */
  115400. + buffer = buffer->freeNext;
  115401. + }
  115402. + while (buffer != gcvFREE_TASK_TERMINATOR);
  115403. + }
  115404. +
  115405. + /* Allocate a container. */
  115406. + gcmkERR_BREAK(gckOS_Allocate(
  115407. + Command->os,
  115408. + Command->taskStorageGranularity,
  115409. + (gctPOINTER *) &storage
  115410. + ));
  115411. +
  115412. + /* Link in the storage buffer. */
  115413. + storage->next = Command->taskStorage;
  115414. + Command->taskStorage = storage;
  115415. +
  115416. + /* Place the task buffer. */
  115417. + buffer = (gcsTASK_CONTAINER_PTR) (storage + 1);
  115418. +
  115419. + /* Determine the size of the buffer. */
  115420. + buffer->size
  115421. + = Command->taskStorageGranularity
  115422. + - gcmSIZEOF(gcsTASK_STORAGE);
  115423. +
  115424. + /* Initialize the task buffer. */
  115425. + buffer->referenceCount = 0;
  115426. + buffer->allocPrev = gcvNULL;
  115427. + buffer->allocNext = gcvNULL;
  115428. + buffer->freePrev = gcvNULL;
  115429. + buffer->freeNext = gcvNULL;
  115430. +
  115431. + /* Split the buffer. */
  115432. + _SplitTaskBuffer(Command, buffer, Size);
  115433. +
  115434. + /* Set the result. */
  115435. + * Buffer = buffer;
  115436. +
  115437. + gcmkFOOTER_ARG("*Buffer=0x%x",*Buffer);
  115438. + /* Success. */
  115439. + return gcvSTATUS_OK;
  115440. + }
  115441. + while (gcvFALSE);
  115442. +
  115443. + gcmkFOOTER();
  115444. + /* Return status. */
  115445. + return status;
  115446. +}
  115447. +
  115448. +static void
  115449. +_FreeTaskContainer(
  115450. + IN gckVGCOMMAND Command,
  115451. + IN gcsTASK_CONTAINER_PTR Buffer
  115452. + )
  115453. +{
  115454. + gcsTASK_CONTAINER_PTR prev;
  115455. + gcsTASK_CONTAINER_PTR next;
  115456. + gcsTASK_CONTAINER_PTR merged;
  115457. +
  115458. + gctSIZE_T mergedSize;
  115459. +
  115460. + /* Verify arguments. */
  115461. + gcmkASSERT(Buffer != gcvNULL);
  115462. + gcmkASSERT(Buffer->freePrev == gcvNULL);
  115463. + gcmkASSERT(Buffer->freeNext == gcvNULL);
  115464. +
  115465. + /* Get shortcuts to the previous and next path data buffers. */
  115466. + prev = Buffer->allocPrev;
  115467. + next = Buffer->allocNext;
  115468. +
  115469. + /* Is the previous path data buffer already free? */
  115470. + if (prev && prev->freeNext)
  115471. + {
  115472. + /* The previous path data buffer is the one that remains. */
  115473. + merged = prev;
  115474. +
  115475. + /* Is the next path data buffer already free? */
  115476. + if (next && next->freeNext)
  115477. + {
  115478. + /* Merge all three path data buffers into the previous. */
  115479. + mergedSize = prev->size + Buffer->size + next->size;
  115480. +
  115481. + /* Remove the next path data buffer. */
  115482. + _RemoveFromFreeList(Command, next);
  115483. + _RemoveTaskBuffer(next);
  115484. + }
  115485. + else
  115486. + {
  115487. + /* Merge the current path data buffer into the previous. */
  115488. + mergedSize = prev->size + Buffer->size;
  115489. + }
  115490. +
  115491. + /* Delete the current path data buffer. */
  115492. + _RemoveTaskBuffer(Buffer);
  115493. +
  115494. + /* Set new size. */
  115495. + merged->size = mergedSize;
  115496. + }
  115497. + else
  115498. + {
  115499. + /* The current path data buffer is the one that remains. */
  115500. + merged = Buffer;
  115501. +
  115502. + /* Is the next buffer already free? */
  115503. + if (next && next->freeNext)
  115504. + {
  115505. + /* Merge the next into the current. */
  115506. + mergedSize = Buffer->size + next->size;
  115507. +
  115508. + /* Remove the next buffer. */
  115509. + _RemoveFromFreeList(Command, next);
  115510. + _RemoveTaskBuffer(next);
  115511. +
  115512. + /* Set new size. */
  115513. + merged->size = mergedSize;
  115514. + }
  115515. +
  115516. + /* Add the current buffer into the free list. */
  115517. + _AppendToFreeList(Command, merged);
  115518. + }
  115519. +}
  115520. +
  115521. +gceSTATUS
  115522. +_RemoveRecordFromProcesDB(
  115523. + IN gckVGCOMMAND Command,
  115524. + IN gcsTASK_HEADER_PTR Task
  115525. + )
  115526. +{
  115527. + gcsTASK_PTR task = (gcsTASK_PTR)((gctUINT8_PTR)Task - sizeof(gcsTASK));
  115528. + gcsTASK_FREE_VIDEO_MEMORY_PTR freeVideoMemory;
  115529. + gcsTASK_UNLOCK_VIDEO_MEMORY_PTR unlockVideoMemory;
  115530. + gctINT pid;
  115531. + gctUINT32 size;
  115532. +
  115533. + /* Get the total size of all tasks. */
  115534. + size = task->size;
  115535. +
  115536. + gcmkVERIFY_OK(gckOS_GetProcessID((gctUINT32_PTR)&pid));
  115537. +
  115538. + do
  115539. + {
  115540. + switch (Task->id)
  115541. + {
  115542. + case gcvTASK_FREE_VIDEO_MEMORY:
  115543. + freeVideoMemory = (gcsTASK_FREE_VIDEO_MEMORY_PTR)Task;
  115544. +
  115545. + /* Remove record from process db. */
  115546. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  115547. + Command->kernel->kernel,
  115548. + pid,
  115549. + gcvDB_VIDEO_MEMORY,
  115550. + gcmUINT64_TO_PTR(freeVideoMemory->node)));
  115551. +
  115552. + /* Advance to next task. */
  115553. + size -= sizeof(gcsTASK_FREE_VIDEO_MEMORY);
  115554. + Task = (gcsTASK_HEADER_PTR)(freeVideoMemory + 1);
  115555. +
  115556. + break;
  115557. + case gcvTASK_UNLOCK_VIDEO_MEMORY:
  115558. + unlockVideoMemory = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR)Task;
  115559. +
  115560. + /* Remove record from process db. */
  115561. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  115562. + Command->kernel->kernel,
  115563. + pid,
  115564. + gcvDB_VIDEO_MEMORY_LOCKED,
  115565. + gcmUINT64_TO_PTR(unlockVideoMemory->node)));
  115566. +
  115567. + /* Advance to next task. */
  115568. + size -= sizeof(gcsTASK_UNLOCK_VIDEO_MEMORY);
  115569. + Task = (gcsTASK_HEADER_PTR)(unlockVideoMemory + 1);
  115570. +
  115571. + break;
  115572. + default:
  115573. + /* Skip the whole task. */
  115574. + size = 0;
  115575. + break;
  115576. + }
  115577. + }
  115578. + while(size);
  115579. +
  115580. + return gcvSTATUS_OK;
  115581. +}
  115582. +
  115583. +/******************************************************************************\
  115584. +********************************* Task Scheduling ******************************
  115585. +\******************************************************************************/
  115586. +
  115587. +static gceSTATUS
  115588. +_ScheduleTasks(
  115589. + IN gckVGCOMMAND Command,
  115590. + IN gcsTASK_MASTER_TABLE_PTR TaskTable,
  115591. + IN gctUINT8_PTR PreviousEnd
  115592. + )
  115593. +{
  115594. + gceSTATUS status;
  115595. +
  115596. + do
  115597. + {
  115598. + gctINT block;
  115599. + gcsTASK_CONTAINER_PTR container;
  115600. + gcsTASK_MASTER_ENTRY_PTR userTaskEntry;
  115601. + gcsBLOCK_TASK_ENTRY_PTR kernelTaskEntry;
  115602. + gcsTASK_PTR userTask;
  115603. + gctUINT8_PTR kernelTask;
  115604. + gctINT32 interrupt;
  115605. + gctUINT8_PTR eventCommand;
  115606. +
  115607. + /* Nothing to schedule? */
  115608. + if (TaskTable->size == 0)
  115609. + {
  115610. + status = gcvSTATUS_OK;
  115611. + break;
  115612. + }
  115613. +
  115614. + /* Acquire the mutex. */
  115615. + gcmkERR_BREAK(gckOS_AcquireMutex(
  115616. + Command->os,
  115617. + Command->taskMutex,
  115618. + gcvINFINITE
  115619. + ));
  115620. +
  115621. + gcmkTRACE_ZONE(
  115622. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  115623. + "%s(%d)\n",
  115624. + __FUNCTION__, __LINE__
  115625. + );
  115626. +
  115627. + do
  115628. + {
  115629. + gcmkTRACE_ZONE(
  115630. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  115631. + " number of tasks scheduled = %d\n"
  115632. + " size of event data in bytes = %d\n",
  115633. + TaskTable->count,
  115634. + TaskTable->size
  115635. + );
  115636. +
  115637. + /* Allocate task buffer. */
  115638. + gcmkERR_BREAK(_AllocateTaskContainer(
  115639. + Command,
  115640. + TaskTable->size,
  115641. + &container
  115642. + ));
  115643. +
  115644. + /* Determine the task data pointer. */
  115645. + kernelTask = (gctUINT8_PTR) (container + 1);
  115646. +
  115647. + /* Initialize the reference count. */
  115648. + container->referenceCount = TaskTable->count;
  115649. +
  115650. + /* Process tasks. */
  115651. + for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
  115652. + {
  115653. + /* Get the current user table entry. */
  115654. + userTaskEntry = &TaskTable->table[block];
  115655. +
  115656. + /* Are there tasks scheduled? */
  115657. + if (userTaskEntry->head == gcvNULL)
  115658. + {
  115659. + /* No, skip to the next block. */
  115660. + continue;
  115661. + }
  115662. +
  115663. + gcmkTRACE_ZONE(
  115664. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  115665. + " processing tasks for block %d\n",
  115666. + block
  115667. + );
  115668. +
  115669. + /* Get the current kernel table entry. */
  115670. + kernelTaskEntry = &Command->taskTable[block];
  115671. +
  115672. + /* Are there tasks for the current block scheduled? */
  115673. + if (kernelTaskEntry->container == gcvNULL)
  115674. + {
  115675. + gcmkTRACE_ZONE(
  115676. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  115677. + " first task container for the block added\n",
  115678. + block
  115679. + );
  115680. +
  115681. + /* Nothing yet, set the container buffer pointer. */
  115682. + kernelTaskEntry->container = container;
  115683. + kernelTaskEntry->task = (gcsTASK_HEADER_PTR) kernelTask;
  115684. + }
  115685. +
  115686. + /* Yes, append to the end. */
  115687. + else
  115688. + {
  115689. + kernelTaskEntry->link->cotainer = container;
  115690. + kernelTaskEntry->link->task = (gcsTASK_HEADER_PTR) kernelTask;
  115691. + }
  115692. +
  115693. + /* Set initial task. */
  115694. + userTask = userTaskEntry->head;
  115695. +
  115696. + gcmkTRACE_ZONE(
  115697. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  115698. + " copying user tasks over to the kernel\n"
  115699. + );
  115700. +
  115701. + /* Copy tasks. */
  115702. + do
  115703. + {
  115704. + gcsTASK_HEADER_PTR taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
  115705. +
  115706. + gcmkVERIFY_OK(_RemoveRecordFromProcesDB(Command, taskHeader));
  115707. +
  115708. + gcmkTRACE_ZONE(
  115709. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  115710. + " task ID = %d, size = %d\n",
  115711. + ((gcsTASK_HEADER_PTR) (userTask + 1))->id,
  115712. + userTask->size
  115713. + );
  115714. +
  115715. +#ifdef __QNXNTO__
  115716. + if (taskHeader->id == gcvTASK_SIGNAL)
  115717. + {
  115718. + ((gcsTASK_SIGNAL_PTR)taskHeader)->coid = TaskTable->coid;
  115719. + ((gcsTASK_SIGNAL_PTR)taskHeader)->rcvid = TaskTable->rcvid;
  115720. + }
  115721. +#endif /* __QNXNTO__ */
  115722. + /* Copy the task data. */
  115723. + gcmkVERIFY_OK(gckOS_MemCopy(
  115724. + kernelTask, taskHeader, userTask->size
  115725. + ));
  115726. +
  115727. + /* Advance to the next task. */
  115728. + kernelTask += userTask->size;
  115729. + userTask = userTask->next;
  115730. + }
  115731. + while (userTask != gcvNULL);
  115732. +
  115733. + /* Update link pointer in the header. */
  115734. + kernelTaskEntry->link = (gcsTASK_LINK_PTR) kernelTask;
  115735. +
  115736. + /* Initialize link task. */
  115737. + kernelTaskEntry->link->id = gcvTASK_LINK;
  115738. + kernelTaskEntry->link->cotainer = gcvNULL;
  115739. + kernelTaskEntry->link->task = gcvNULL;
  115740. +
  115741. + /* Advance the task data pointer. */
  115742. + kernelTask += gcmSIZEOF(gcsTASK_LINK);
  115743. + }
  115744. + }
  115745. + while (gcvFALSE);
  115746. +
  115747. + /* Release the mutex. */
  115748. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  115749. + Command->os,
  115750. + Command->taskMutex
  115751. + ));
  115752. +
  115753. + /* Assign interrupts to the blocks. */
  115754. + eventCommand = PreviousEnd;
  115755. +
  115756. + for (block = gcvBLOCK_COUNT - 1; block >= 0; block -= 1)
  115757. + {
  115758. + /* Get the current user table entry. */
  115759. + userTaskEntry = &TaskTable->table[block];
  115760. +
  115761. + /* Are there tasks scheduled? */
  115762. + if (userTaskEntry->head == gcvNULL)
  115763. + {
  115764. + /* No, skip to the next block. */
  115765. + continue;
  115766. + }
  115767. +
  115768. + /* Get the interrupt number. */
  115769. + interrupt = _GetNextInterrupt(Command, block);
  115770. +
  115771. + gcmkTRACE_ZONE(
  115772. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  115773. + "%s(%d): block = %d interrupt = %d\n",
  115774. + __FUNCTION__, __LINE__,
  115775. + block, interrupt
  115776. + );
  115777. +
  115778. + /* Determine the command position. */
  115779. + eventCommand -= Command->info.eventCommandSize;
  115780. +
  115781. + /* Append an EVENT command. */
  115782. + gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
  115783. + Command, eventCommand, block, interrupt, gcvNULL
  115784. + ));
  115785. + }
  115786. + }
  115787. + while (gcvFALSE);
  115788. +
  115789. + /* Return status. */
  115790. + return status;
  115791. +}
  115792. +
  115793. +
  115794. +/******************************************************************************\
  115795. +******************************** Memory Management *****************************
  115796. +\******************************************************************************/
  115797. +
  115798. +static gceSTATUS
  115799. +_HardwareToKernel(
  115800. + IN gckOS Os,
  115801. + IN gcuVIDMEM_NODE_PTR Node,
  115802. + IN gctUINT32 Address,
  115803. + OUT gctPOINTER * KernelPointer
  115804. + )
  115805. +{
  115806. + gceSTATUS status;
  115807. + gckVIDMEM memory;
  115808. + gctUINT32 offset;
  115809. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  115810. + gctUINT32 nodePhysical;
  115811. +#endif
  115812. + status = gcvSTATUS_OK;
  115813. + /* Assume a non-virtual node and get the pool manager object. */
  115814. + memory = Node->VidMem.memory;
  115815. +
  115816. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  115817. + nodePhysical = memory->baseAddress
  115818. + + Node->VidMem.offset
  115819. + + Node->VidMem.alignment;
  115820. +
  115821. + if (Node->VidMem.kernelVirtual == gcvNULL)
  115822. + {
  115823. + status = gckOS_MapPhysical(Os,
  115824. + nodePhysical,
  115825. + Node->VidMem.bytes,
  115826. + (gctPOINTER *)&Node->VidMem.kernelVirtual);
  115827. +
  115828. + if (gcmkIS_ERROR(status))
  115829. + {
  115830. + return status;
  115831. + }
  115832. + }
  115833. +
  115834. + offset = Address - nodePhysical;
  115835. + *KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset);
  115836. +#else
  115837. + /* Determine the header offset within the pool it is allocated in. */
  115838. + offset = Address - memory->baseAddress;
  115839. +
  115840. + /* Translate the offset into the kernel side pointer. */
  115841. + status = gckOS_GetKernelLogicalEx(
  115842. + Os,
  115843. + gcvCORE_VG,
  115844. + offset,
  115845. + KernelPointer
  115846. + );
  115847. +#endif
  115848. +
  115849. + /* Return status. */
  115850. + return status;
  115851. +}
  115852. +
  115853. +static gceSTATUS
  115854. +_ConvertUserCommandBufferPointer(
  115855. + IN gckVGCOMMAND Command,
  115856. + IN gcsCMDBUFFER_PTR UserCommandBuffer,
  115857. + OUT gcsCMDBUFFER_PTR * KernelCommandBuffer
  115858. + )
  115859. +{
  115860. + gceSTATUS status, last;
  115861. + gcsCMDBUFFER_PTR mappedUserCommandBuffer = gcvNULL;
  115862. +
  115863. + do
  115864. + {
  115865. + gctUINT32 headerAddress;
  115866. +
  115867. + /* Map the command buffer structure into the kernel space. */
  115868. + gcmkERR_BREAK(gckOS_MapUserPointer(
  115869. + Command->os,
  115870. + UserCommandBuffer,
  115871. + gcmSIZEOF(gcsCMDBUFFER),
  115872. + (gctPOINTER *) &mappedUserCommandBuffer
  115873. + ));
  115874. +
  115875. + /* Determine the address of the header. */
  115876. + headerAddress
  115877. + = mappedUserCommandBuffer->address
  115878. + - mappedUserCommandBuffer->bufferOffset;
  115879. +
  115880. + /* Translate the logical address to the kernel space. */
  115881. + gcmkERR_BREAK(_HardwareToKernel(
  115882. + Command->os,
  115883. + gcmUINT64_TO_PTR(mappedUserCommandBuffer->node),
  115884. + headerAddress,
  115885. + (gctPOINTER *) KernelCommandBuffer
  115886. + ));
  115887. + }
  115888. + while (gcvFALSE);
  115889. +
  115890. + /* Unmap the user command buffer. */
  115891. + if (mappedUserCommandBuffer != gcvNULL)
  115892. + {
  115893. + gcmkCHECK_STATUS(gckOS_UnmapUserPointer(
  115894. + Command->os,
  115895. + UserCommandBuffer,
  115896. + gcmSIZEOF(gcsCMDBUFFER),
  115897. + mappedUserCommandBuffer
  115898. + ));
  115899. + }
  115900. +
  115901. + /* Return status. */
  115902. + return status;
  115903. +}
  115904. +
  115905. +static gceSTATUS
  115906. +_AllocateLinear(
  115907. + IN gckVGCOMMAND Command,
  115908. + IN gctUINT Size,
  115909. + IN gctUINT Alignment,
  115910. + OUT gcuVIDMEM_NODE_PTR * Node,
  115911. + OUT gctUINT32 * Address,
  115912. + OUT gctPOINTER * Logical
  115913. + )
  115914. +{
  115915. + gceSTATUS status, last;
  115916. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  115917. + gctUINT32 address = (gctUINT32)~0;
  115918. +
  115919. + do
  115920. + {
  115921. + gcePOOL pool;
  115922. + gctPOINTER logical;
  115923. +
  115924. + /* Allocate from the system pool. */
  115925. + pool = gcvPOOL_SYSTEM;
  115926. +
  115927. + /* Allocate memory. */
  115928. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  115929. + Command->kernel->kernel, &pool,
  115930. + Size, Alignment,
  115931. + gcvSURF_TYPE_UNKNOWN,
  115932. + &node
  115933. + ));
  115934. +
  115935. + /* Do not accept virtual pools for now because we don't handle the
  115936. + kernel pointer translation at the moment. */
  115937. + if (pool == gcvPOOL_VIRTUAL)
  115938. + {
  115939. + status = gcvSTATUS_OUT_OF_MEMORY;
  115940. + break;
  115941. + }
  115942. +
  115943. + /* Lock the command buffer. */
  115944. + gcmkERR_BREAK(gckVIDMEM_Lock(
  115945. + Command->kernel->kernel,
  115946. + node,
  115947. + gcvFALSE,
  115948. + &address
  115949. + ));
  115950. +
  115951. + /* Translate the logical address to the kernel space. */
  115952. + gcmkERR_BREAK(_HardwareToKernel(
  115953. + Command->os,
  115954. + node,
  115955. + address,
  115956. + &logical
  115957. + ));
  115958. +
  115959. + /* Set return values. */
  115960. + * Node = node;
  115961. + * Address = address;
  115962. + * Logical = logical;
  115963. +
  115964. + /* Success. */
  115965. + return gcvSTATUS_OK;
  115966. + }
  115967. + while (gcvFALSE);
  115968. +
  115969. + /* Roll back. */
  115970. + if (node != gcvNULL)
  115971. + {
  115972. + /* Unlock the command buffer. */
  115973. + if (address != ~0)
  115974. + {
  115975. + gcmkCHECK_STATUS(gckVIDMEM_Unlock(
  115976. + Command->kernel->kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL
  115977. + ));
  115978. + }
  115979. +
  115980. + /* Free the command buffer. */
  115981. + gcmkCHECK_STATUS(gckVIDMEM_Free(
  115982. + node
  115983. + ));
  115984. + }
  115985. +
  115986. + /* Return status. */
  115987. + return status;
  115988. +}
  115989. +
  115990. +static gceSTATUS
  115991. +_FreeLinear(
  115992. + IN gckVGKERNEL Kernel,
  115993. + IN gcuVIDMEM_NODE_PTR Node
  115994. + )
  115995. +{
  115996. + gceSTATUS status;
  115997. +
  115998. + do
  115999. + {
  116000. + /* Unlock the linear buffer. */
  116001. + gcmkERR_BREAK(gckVIDMEM_Unlock(Kernel->kernel, Node, gcvSURF_TYPE_UNKNOWN, gcvNULL));
  116002. +
  116003. + /* Free the linear buffer. */
  116004. + gcmkERR_BREAK(gckVIDMEM_Free(Node));
  116005. + }
  116006. + while (gcvFALSE);
  116007. +
  116008. + /* Return status. */
  116009. + return status;
  116010. +}
  116011. +
  116012. +gceSTATUS
  116013. +_AllocateCommandBuffer(
  116014. + IN gckVGCOMMAND Command,
  116015. + IN gctSIZE_T Size,
  116016. + OUT gcsCMDBUFFER_PTR * CommandBuffer
  116017. + )
  116018. +{
  116019. + gceSTATUS status, last;
  116020. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  116021. +
  116022. + do
  116023. + {
  116024. + gctUINT alignedHeaderSize;
  116025. + gctUINT requestedSize;
  116026. + gctUINT allocationSize;
  116027. + gctUINT32 address = 0;
  116028. + gcsCMDBUFFER_PTR commandBuffer;
  116029. + gctUINT8_PTR endCommand;
  116030. +
  116031. + /* Determine the aligned header size. */
  116032. + alignedHeaderSize
  116033. + = gcmALIGN(gcmSIZEOF(gcsCMDBUFFER), Command->info.addressAlignment);
  116034. +
  116035. + /* Align the requested size. */
  116036. + requestedSize
  116037. + = gcmALIGN(Size, Command->info.commandAlignment);
  116038. +
  116039. + /* Determine the size of the buffer to allocate. */
  116040. + allocationSize
  116041. + = alignedHeaderSize
  116042. + + requestedSize
  116043. + + Command->info.staticTailSize;
  116044. +
  116045. + /* Allocate the command buffer. */
  116046. + gcmkERR_BREAK(_AllocateLinear(
  116047. + Command,
  116048. + allocationSize,
  116049. + Command->info.addressAlignment,
  116050. + &node,
  116051. + &address,
  116052. + (gctPOINTER *) &commandBuffer
  116053. + ));
  116054. +
  116055. + /* Initialize the structure. */
  116056. + commandBuffer->completion = gcvVACANT_BUFFER;
  116057. + commandBuffer->node = gcmPTR_TO_UINT64(node);
  116058. + commandBuffer->address = address + alignedHeaderSize;
  116059. + commandBuffer->bufferOffset = alignedHeaderSize;
  116060. + commandBuffer->size = requestedSize;
  116061. + commandBuffer->offset = requestedSize;
  116062. + commandBuffer->nextAllocated = gcvNULL;
  116063. + commandBuffer->nextSubBuffer = gcvNULL;
  116064. +
  116065. + /* Determine the data count. */
  116066. + commandBuffer->dataCount
  116067. + = (requestedSize + Command->info.staticTailSize)
  116068. + / Command->info.commandAlignment;
  116069. +
  116070. + /* Determine the location of the END command. */
  116071. + endCommand
  116072. + = (gctUINT8_PTR) commandBuffer
  116073. + + alignedHeaderSize
  116074. + + requestedSize;
  116075. +
  116076. + /* Append an END command. */
  116077. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  116078. + Command,
  116079. + endCommand,
  116080. + Command->info.feBufferInt,
  116081. + gcvNULL
  116082. + ));
  116083. +
  116084. + /* Set the return pointer. */
  116085. + * CommandBuffer = commandBuffer;
  116086. +
  116087. + /* Success. */
  116088. + return gcvSTATUS_OK;
  116089. + }
  116090. + while (gcvFALSE);
  116091. +
  116092. + /* Roll back. */
  116093. + if (node != gcvNULL)
  116094. + {
  116095. + /* Free the command buffer. */
  116096. + gcmkCHECK_STATUS(_FreeLinear(Command->kernel, node));
  116097. + }
  116098. +
  116099. + /* Return status. */
  116100. + return status;
  116101. +}
  116102. +
  116103. +static gceSTATUS
  116104. +_FreeCommandBuffer(
  116105. + IN gckVGKERNEL Kernel,
  116106. + IN gcsCMDBUFFER_PTR CommandBuffer
  116107. + )
  116108. +{
  116109. + gceSTATUS status;
  116110. +
  116111. + /* Free the buffer. */
  116112. + status = _FreeLinear(Kernel, gcmUINT64_TO_PTR(CommandBuffer->node));
  116113. +
  116114. + /* Return status. */
  116115. + return status;
  116116. +}
  116117. +
  116118. +
  116119. +/******************************************************************************\
  116120. +****************************** TS Overflow Handler *****************************
  116121. +\******************************************************************************/
  116122. +
  116123. +static gceSTATUS
  116124. +_EventHandler_TSOverflow(
  116125. + IN gckVGKERNEL Kernel
  116126. + )
  116127. +{
  116128. + gcmkTRACE(
  116129. + gcvLEVEL_ERROR,
  116130. + "%s(%d): **** TS OVERFLOW ENCOUNTERED ****\n",
  116131. + __FUNCTION__, __LINE__
  116132. + );
  116133. +
  116134. + return gcvSTATUS_OK;
  116135. +}
  116136. +
  116137. +
  116138. +/******************************************************************************\
  116139. +****************************** Bus Error Handler *******************************
  116140. +\******************************************************************************/
  116141. +
  116142. +static gceSTATUS
  116143. +_EventHandler_BusError(
  116144. + IN gckVGKERNEL Kernel
  116145. + )
  116146. +{
  116147. + gcmkTRACE(
  116148. + gcvLEVEL_ERROR,
  116149. + "%s(%d): **** BUS ERROR ENCOUNTERED ****\n",
  116150. + __FUNCTION__, __LINE__
  116151. + );
  116152. +
  116153. + return gcvSTATUS_OK;
  116154. +}
  116155. +
  116156. +/******************************************************************************\
  116157. +****************************** Power Stall Handler *******************************
  116158. +\******************************************************************************/
  116159. +
  116160. +static gceSTATUS
  116161. +_EventHandler_PowerStall(
  116162. + IN gckVGKERNEL Kernel
  116163. + )
  116164. +{
  116165. + /* Signal. */
  116166. + return gckOS_Signal(
  116167. + Kernel->os,
  116168. + Kernel->command->powerStallSignal,
  116169. + gcvTRUE);
  116170. +}
  116171. +
  116172. +/******************************************************************************\
  116173. +******************************** Task Routines *********************************
  116174. +\******************************************************************************/
  116175. +
  116176. +typedef gceSTATUS (* gctTASKROUTINE) (
  116177. + gckVGCOMMAND Command,
  116178. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116179. + );
  116180. +
  116181. +static gceSTATUS
  116182. +_TaskLink(
  116183. + gckVGCOMMAND Command,
  116184. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116185. + );
  116186. +
  116187. +static gceSTATUS
  116188. +_TaskCluster(
  116189. + gckVGCOMMAND Command,
  116190. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116191. + );
  116192. +
  116193. +static gceSTATUS
  116194. +_TaskIncrement(
  116195. + gckVGCOMMAND Command,
  116196. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116197. + );
  116198. +
  116199. +static gceSTATUS
  116200. +_TaskDecrement(
  116201. + gckVGCOMMAND Command,
  116202. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116203. + );
  116204. +
  116205. +static gceSTATUS
  116206. +_TaskSignal(
  116207. + gckVGCOMMAND Command,
  116208. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116209. + );
  116210. +
  116211. +static gceSTATUS
  116212. +_TaskLockdown(
  116213. + gckVGCOMMAND Command,
  116214. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116215. + );
  116216. +
  116217. +static gceSTATUS
  116218. +_TaskUnlockVideoMemory(
  116219. + gckVGCOMMAND Command,
  116220. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116221. + );
  116222. +
  116223. +static gceSTATUS
  116224. +_TaskFreeVideoMemory(
  116225. + gckVGCOMMAND Command,
  116226. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116227. + );
  116228. +
  116229. +static gceSTATUS
  116230. +_TaskFreeContiguousMemory(
  116231. + gckVGCOMMAND Command,
  116232. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116233. + );
  116234. +
  116235. +static gceSTATUS
  116236. +_TaskUnmapUserMemory(
  116237. + gckVGCOMMAND Command,
  116238. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116239. + );
  116240. +
  116241. +static gctTASKROUTINE _taskRoutine[] =
  116242. +{
  116243. + _TaskLink, /* gcvTASK_LINK */
  116244. + _TaskCluster, /* gcvTASK_CLUSTER */
  116245. + _TaskIncrement, /* gcvTASK_INCREMENT */
  116246. + _TaskDecrement, /* gcvTASK_DECREMENT */
  116247. + _TaskSignal, /* gcvTASK_SIGNAL */
  116248. + _TaskLockdown, /* gcvTASK_LOCKDOWN */
  116249. + _TaskUnlockVideoMemory, /* gcvTASK_UNLOCK_VIDEO_MEMORY */
  116250. + _TaskFreeVideoMemory, /* gcvTASK_FREE_VIDEO_MEMORY */
  116251. + _TaskFreeContiguousMemory, /* gcvTASK_FREE_CONTIGUOUS_MEMORY */
  116252. + _TaskUnmapUserMemory, /* gcvTASK_UNMAP_USER_MEMORY */
  116253. +};
  116254. +
  116255. +static gceSTATUS
  116256. +_TaskLink(
  116257. + gckVGCOMMAND Command,
  116258. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116259. + )
  116260. +{
  116261. + /* Cast the task pointer. */
  116262. + gcsTASK_LINK_PTR task = (gcsTASK_LINK_PTR) TaskHeader->task;
  116263. +
  116264. + /* Save the pointer to the container. */
  116265. + gcsTASK_CONTAINER_PTR container = TaskHeader->container;
  116266. +
  116267. + /* No more tasks in the list? */
  116268. + if (task->task == gcvNULL)
  116269. + {
  116270. + /* Reset the entry. */
  116271. + TaskHeader->container = gcvNULL;
  116272. + TaskHeader->task = gcvNULL;
  116273. + TaskHeader->link = gcvNULL;
  116274. + }
  116275. + else
  116276. + {
  116277. + /* Update the entry. */
  116278. + TaskHeader->container = task->cotainer;
  116279. + TaskHeader->task = task->task;
  116280. + }
  116281. +
  116282. + /* Decrement the task buffer reference. */
  116283. + gcmkASSERT(container->referenceCount >= 0);
  116284. + if (container->referenceCount == 0)
  116285. + {
  116286. + /* Free the container. */
  116287. + _FreeTaskContainer(Command, container);
  116288. + }
  116289. +
  116290. + /* Success. */
  116291. + return gcvSTATUS_OK;
  116292. +}
  116293. +
  116294. +static gceSTATUS
  116295. +_TaskCluster(
  116296. + gckVGCOMMAND Command,
  116297. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116298. + )
  116299. +{
  116300. + gceSTATUS status = gcvSTATUS_OK;
  116301. +
  116302. + /* Cast the task pointer. */
  116303. + gcsTASK_CLUSTER_PTR cluster = (gcsTASK_CLUSTER_PTR) TaskHeader->task;
  116304. +
  116305. + /* Get the number of tasks. */
  116306. + gctUINT taskCount = cluster->taskCount;
  116307. +
  116308. + /* Advance to the next task. */
  116309. + TaskHeader->task = (gcsTASK_HEADER_PTR) (cluster + 1);
  116310. +
  116311. + /* Perform all tasks in the cluster. */
  116312. + while (taskCount)
  116313. + {
  116314. + /* Perform the current task. */
  116315. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  116316. + Command,
  116317. + TaskHeader
  116318. + ));
  116319. +
  116320. + /* Update the task count. */
  116321. + taskCount -= 1;
  116322. + }
  116323. +
  116324. + /* Return status. */
  116325. + return status;
  116326. +}
  116327. +
  116328. +static gceSTATUS
  116329. +_TaskIncrement(
  116330. + gckVGCOMMAND Command,
  116331. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116332. + )
  116333. +{
  116334. + gceSTATUS status;
  116335. +
  116336. + do
  116337. + {
  116338. + /* Cast the task pointer. */
  116339. + gcsTASK_INCREMENT_PTR task = (gcsTASK_INCREMENT_PTR) TaskHeader->task;
  116340. +
  116341. + /* Convert physical into logical address. */
  116342. + gctUINT32_PTR logical;
  116343. + gcmkERR_BREAK(gckOS_MapPhysical(
  116344. + Command->os,
  116345. + task->address,
  116346. + gcmSIZEOF(gctUINT32),
  116347. + (gctPOINTER *) &logical
  116348. + ));
  116349. +
  116350. + /* Increment data. */
  116351. + (* logical) += 1;
  116352. +
  116353. + /* Unmap the physical memory. */
  116354. + gcmkERR_BREAK(gckOS_UnmapPhysical(
  116355. + Command->os,
  116356. + logical,
  116357. + gcmSIZEOF(gctUINT32)
  116358. + ));
  116359. +
  116360. + /* Update the reference counter. */
  116361. + TaskHeader->container->referenceCount -= 1;
  116362. +
  116363. + /* Update the task pointer. */
  116364. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116365. + }
  116366. + while (gcvFALSE);
  116367. +
  116368. + /* Return status. */
  116369. + return status;
  116370. +}
  116371. +
  116372. +static gceSTATUS
  116373. +_TaskDecrement(
  116374. + gckVGCOMMAND Command,
  116375. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116376. + )
  116377. +{
  116378. + gceSTATUS status;
  116379. +
  116380. + do
  116381. + {
  116382. + /* Cast the task pointer. */
  116383. + gcsTASK_DECREMENT_PTR task = (gcsTASK_DECREMENT_PTR) TaskHeader->task;
  116384. +
  116385. + /* Convert physical into logical address. */
  116386. + gctUINT32_PTR logical;
  116387. + gcmkERR_BREAK(gckOS_MapPhysical(
  116388. + Command->os,
  116389. + task->address,
  116390. + gcmSIZEOF(gctUINT32),
  116391. + (gctPOINTER *) &logical
  116392. + ));
  116393. +
  116394. + /* Decrement data. */
  116395. + (* logical) -= 1;
  116396. +
  116397. + /* Unmap the physical memory. */
  116398. + gcmkERR_BREAK(gckOS_UnmapPhysical(
  116399. + Command->os,
  116400. + logical,
  116401. + gcmSIZEOF(gctUINT32)
  116402. + ));
  116403. +
  116404. + /* Update the reference counter. */
  116405. + TaskHeader->container->referenceCount -= 1;
  116406. +
  116407. + /* Update the task pointer. */
  116408. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116409. + }
  116410. + while (gcvFALSE);
  116411. +
  116412. + /* Return status. */
  116413. + return status;
  116414. +}
  116415. +
  116416. +static gceSTATUS
  116417. +_TaskSignal(
  116418. + gckVGCOMMAND Command,
  116419. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116420. + )
  116421. +{
  116422. + gceSTATUS status;
  116423. +
  116424. + do
  116425. + {
  116426. + /* Cast the task pointer. */
  116427. + gcsTASK_SIGNAL_PTR task = (gcsTASK_SIGNAL_PTR) TaskHeader->task;
  116428. +
  116429. +
  116430. + /* Map the signal into kernel space. */
  116431. +#ifdef __QNXNTO__
  116432. + gcmkERR_BREAK(gckOS_UserSignal(
  116433. + Command->os, task->signal, task->rcvid, task->coid
  116434. + ));
  116435. +#else
  116436. + gcmkERR_BREAK(gckOS_UserSignal(
  116437. + Command->os, task->signal, task->process
  116438. + ));
  116439. +#endif /* __QNXNTO__ */
  116440. +
  116441. + /* Update the reference counter. */
  116442. + TaskHeader->container->referenceCount -= 1;
  116443. +
  116444. + /* Update the task pointer. */
  116445. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116446. + }
  116447. + while (gcvFALSE);
  116448. +
  116449. + /* Return status. */
  116450. + return status;
  116451. +}
  116452. +
  116453. +static gceSTATUS
  116454. +_TaskLockdown(
  116455. + gckVGCOMMAND Command,
  116456. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116457. + )
  116458. +{
  116459. + gceSTATUS status;
  116460. + gctUINT32_PTR userCounter = gcvNULL;
  116461. + gctUINT32_PTR kernelCounter = gcvNULL;
  116462. + gctSIGNAL signal = gcvNULL;
  116463. +
  116464. + do
  116465. + {
  116466. + /* Cast the task pointer. */
  116467. + gcsTASK_LOCKDOWN_PTR task = (gcsTASK_LOCKDOWN_PTR) TaskHeader->task;
  116468. +
  116469. + /* Convert physical addresses into logical. */
  116470. + gcmkERR_BREAK(gckOS_MapPhysical(
  116471. + Command->os,
  116472. + task->userCounter,
  116473. + gcmSIZEOF(gctUINT32),
  116474. + (gctPOINTER *) &userCounter
  116475. + ));
  116476. +
  116477. + gcmkERR_BREAK(gckOS_MapPhysical(
  116478. + Command->os,
  116479. + task->kernelCounter,
  116480. + gcmSIZEOF(gctUINT32),
  116481. + (gctPOINTER *) &kernelCounter
  116482. + ));
  116483. +
  116484. + /* Update the kernel counter. */
  116485. + (* kernelCounter) += 1;
  116486. +
  116487. + /* Are the counters equal? */
  116488. + if ((* userCounter) == (* kernelCounter))
  116489. + {
  116490. + /* Map the signal into kernel space. */
  116491. + gcmkERR_BREAK(gckOS_MapSignal(
  116492. + Command->os, task->signal, task->process, &signal
  116493. + ));
  116494. +
  116495. + if (signal == gcvNULL)
  116496. + {
  116497. + /* Signal. */
  116498. + gcmkERR_BREAK(gckOS_Signal(
  116499. + Command->os, task->signal, gcvTRUE
  116500. + ));
  116501. + }
  116502. + else
  116503. + {
  116504. + /* Signal. */
  116505. + gcmkERR_BREAK(gckOS_Signal(
  116506. + Command->os, signal, gcvTRUE
  116507. + ));
  116508. + }
  116509. + }
  116510. +
  116511. + /* Update the reference counter. */
  116512. + TaskHeader->container->referenceCount -= 1;
  116513. +
  116514. + /* Update the task pointer. */
  116515. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116516. + }
  116517. + while (gcvFALSE);
  116518. +
  116519. + /* Destroy the mapped signal. */
  116520. + if (signal != gcvNULL)
  116521. + {
  116522. + gcmkVERIFY_OK(gckOS_DestroySignal(
  116523. + Command->os, signal
  116524. + ));
  116525. + }
  116526. +
  116527. + /* Unmap the physical memory. */
  116528. + if (kernelCounter != gcvNULL)
  116529. + {
  116530. + gcmkVERIFY_OK(gckOS_UnmapPhysical(
  116531. + Command->os,
  116532. + kernelCounter,
  116533. + gcmSIZEOF(gctUINT32)
  116534. + ));
  116535. + }
  116536. +
  116537. + if (userCounter != gcvNULL)
  116538. + {
  116539. + gcmkVERIFY_OK(gckOS_UnmapPhysical(
  116540. + Command->os,
  116541. + userCounter,
  116542. + gcmSIZEOF(gctUINT32)
  116543. + ));
  116544. + }
  116545. +
  116546. + /* Return status. */
  116547. + return status;
  116548. +}
  116549. +
  116550. +static gceSTATUS
  116551. +_TaskUnlockVideoMemory(
  116552. + gckVGCOMMAND Command,
  116553. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116554. + )
  116555. +{
  116556. + gceSTATUS status;
  116557. +
  116558. + do
  116559. + {
  116560. + /* Cast the task pointer. */
  116561. + gcsTASK_UNLOCK_VIDEO_MEMORY_PTR task
  116562. + = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR) TaskHeader->task;
  116563. +
  116564. + /* Unlock video memory. */
  116565. + gcmkERR_BREAK(gckVIDMEM_Unlock(
  116566. + Command->kernel->kernel,
  116567. + gcmUINT64_TO_PTR(task->node),
  116568. + gcvSURF_TYPE_UNKNOWN,
  116569. + gcvNULL));
  116570. +
  116571. + /* Update the reference counter. */
  116572. + TaskHeader->container->referenceCount -= 1;
  116573. +
  116574. + /* Update the task pointer. */
  116575. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116576. + }
  116577. + while (gcvFALSE);
  116578. +
  116579. + /* Return status. */
  116580. + return status;
  116581. +}
  116582. +
  116583. +static gceSTATUS
  116584. +_TaskFreeVideoMemory(
  116585. + gckVGCOMMAND Command,
  116586. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116587. + )
  116588. +{
  116589. + gceSTATUS status;
  116590. +
  116591. + do
  116592. + {
  116593. + /* Cast the task pointer. */
  116594. + gcsTASK_FREE_VIDEO_MEMORY_PTR task
  116595. + = (gcsTASK_FREE_VIDEO_MEMORY_PTR) TaskHeader->task;
  116596. +
  116597. + /* Free video memory. */
  116598. + gcmkERR_BREAK(gckVIDMEM_Free(gcmUINT64_TO_PTR(task->node)));
  116599. +
  116600. + /* Update the reference counter. */
  116601. + TaskHeader->container->referenceCount -= 1;
  116602. +
  116603. + /* Update the task pointer. */
  116604. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116605. + }
  116606. + while (gcvFALSE);
  116607. +
  116608. + /* Return status. */
  116609. + return status;
  116610. +}
  116611. +
  116612. +static gceSTATUS
  116613. +_TaskFreeContiguousMemory(
  116614. + gckVGCOMMAND Command,
  116615. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116616. + )
  116617. +{
  116618. + gceSTATUS status;
  116619. +
  116620. + do
  116621. + {
  116622. + /* Cast the task pointer. */
  116623. + gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR task
  116624. + = (gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR) TaskHeader->task;
  116625. +
  116626. + /* Free contiguous memory. */
  116627. + gcmkERR_BREAK(gckOS_FreeContiguous(
  116628. + Command->os, task->physical, task->logical, task->bytes
  116629. + ));
  116630. +
  116631. + /* Update the reference counter. */
  116632. + TaskHeader->container->referenceCount -= 1;
  116633. +
  116634. + /* Update the task pointer. */
  116635. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116636. + }
  116637. + while (gcvFALSE);
  116638. +
  116639. + /* Return status. */
  116640. + return status;
  116641. +}
  116642. +
  116643. +static gceSTATUS
  116644. +_TaskUnmapUserMemory(
  116645. + gckVGCOMMAND Command,
  116646. + gcsBLOCK_TASK_ENTRY_PTR TaskHeader
  116647. + )
  116648. +{
  116649. + gceSTATUS status;
  116650. +
  116651. + do
  116652. + {
  116653. + /* Cast the task pointer. */
  116654. + gcsTASK_UNMAP_USER_MEMORY_PTR task
  116655. + = (gcsTASK_UNMAP_USER_MEMORY_PTR) TaskHeader->task;
  116656. +
  116657. + /* Unmap the user memory. */
  116658. + gcmkERR_BREAK(gckOS_UnmapUserMemory(
  116659. + Command->os, gcvCORE_VG, task->memory, task->size, task->info, task->address
  116660. + ));
  116661. +
  116662. + /* Update the reference counter. */
  116663. + TaskHeader->container->referenceCount -= 1;
  116664. +
  116665. + /* Update the task pointer. */
  116666. + TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
  116667. + }
  116668. + while (gcvFALSE);
  116669. +
  116670. + /* Return status. */
  116671. + return status;
  116672. +}
  116673. +
  116674. +/******************************************************************************\
  116675. +************ Hardware Block Interrupt Handlers For Scheduled Events ************
  116676. +\******************************************************************************/
  116677. +
  116678. +static gceSTATUS
  116679. +_EventHandler_Block(
  116680. + IN gckVGKERNEL Kernel,
  116681. + IN gcsBLOCK_TASK_ENTRY_PTR TaskHeader,
  116682. + IN gctBOOL ProcessAll
  116683. + )
  116684. +{
  116685. + gceSTATUS status, last;
  116686. +
  116687. + gcmkHEADER_ARG("Kernel=0x%x TaskHeader=0x%x ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll);
  116688. + /* Verify the arguments. */
  116689. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  116690. +
  116691. + do
  116692. + {
  116693. + gckVGCOMMAND command;
  116694. +
  116695. + /* Get the command buffer object. */
  116696. + command = Kernel->command;
  116697. +
  116698. + /* Increment the interrupt usage semaphore. */
  116699. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  116700. + command->os, TaskHeader->interruptSemaphore
  116701. + ));
  116702. +
  116703. + /* Acquire the mutex. */
  116704. + gcmkERR_BREAK(gckOS_AcquireMutex(
  116705. + command->os,
  116706. + command->taskMutex,
  116707. + gcvINFINITE
  116708. + ));
  116709. +
  116710. + /* Verify inputs. */
  116711. + gcmkASSERT(TaskHeader != gcvNULL);
  116712. + gcmkASSERT(TaskHeader->container != gcvNULL);
  116713. + gcmkASSERT(TaskHeader->task != gcvNULL);
  116714. + gcmkASSERT(TaskHeader->link != gcvNULL);
  116715. +
  116716. + /* Process tasks. */
  116717. + do
  116718. + {
  116719. + /* Process the current task. */
  116720. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  116721. + command,
  116722. + TaskHeader
  116723. + ));
  116724. +
  116725. + /* Is the next task is LINK? */
  116726. + if (TaskHeader->task->id == gcvTASK_LINK)
  116727. + {
  116728. + gcmkERR_BREAK(_taskRoutine[TaskHeader->task->id](
  116729. + command,
  116730. + TaskHeader
  116731. + ));
  116732. +
  116733. + /* Done. */
  116734. + break;
  116735. + }
  116736. + }
  116737. + while (ProcessAll);
  116738. +
  116739. + /* Release the mutex. */
  116740. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  116741. + command->os,
  116742. + command->taskMutex
  116743. + ));
  116744. + }
  116745. + while (gcvFALSE);
  116746. +
  116747. + gcmkFOOTER();
  116748. + /* Return status. */
  116749. + return status;
  116750. +}
  116751. +
  116752. +gcmDECLARE_INTERRUPT_HANDLER(COMMAND, 0)
  116753. +{
  116754. + gceSTATUS status, last;
  116755. +
  116756. + gcmkHEADER_ARG("Kernel=0x%x ", Kernel);
  116757. +
  116758. + /* Verify the arguments. */
  116759. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  116760. +
  116761. +
  116762. + do
  116763. + {
  116764. + gckVGCOMMAND command;
  116765. + gcsKERNEL_QUEUE_HEADER_PTR mergeQueue;
  116766. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  116767. + gcsKERNEL_CMDQUEUE_PTR entry;
  116768. + gctUINT entryCount;
  116769. +
  116770. + /* Get the command buffer object. */
  116771. + command = Kernel->command;
  116772. +
  116773. + /* Acquire the mutex. */
  116774. + gcmkERR_BREAK(gckOS_AcquireMutex(
  116775. + command->os,
  116776. + command->queueMutex,
  116777. + gcvINFINITE
  116778. + ));
  116779. +
  116780. + /* Get the current queue. */
  116781. + queueTail = command->queueTail;
  116782. +
  116783. + /* Get the current queue entry. */
  116784. + entry = queueTail->currentEntry;
  116785. +
  116786. + /* Get the number of entries in the queue. */
  116787. + entryCount = queueTail->pending;
  116788. +
  116789. + /* Process all entries. */
  116790. + while (gcvTRUE)
  116791. + {
  116792. + /* Call post-execution function. */
  116793. + status = entry->handler(Kernel, entry);
  116794. +
  116795. + /* Failed? */
  116796. + if (gcmkIS_ERROR(status))
  116797. + {
  116798. + gcmkTRACE_ZONE(
  116799. + gcvLEVEL_ERROR,
  116800. + gcvZONE_COMMAND,
  116801. + "[%s] line %d: post action failed.\n",
  116802. + __FUNCTION__, __LINE__
  116803. + );
  116804. + }
  116805. +
  116806. + /* Executed the next buffer? */
  116807. + if (status == gcvSTATUS_EXECUTED)
  116808. + {
  116809. + /* Update the queue. */
  116810. + queueTail->pending = entryCount;
  116811. + queueTail->currentEntry = entry;
  116812. +
  116813. + /* Success. */
  116814. + status = gcvSTATUS_OK;
  116815. +
  116816. + /* Break out of the loop. */
  116817. + break;
  116818. + }
  116819. +
  116820. + /* Advance to the next entry. */
  116821. + entry += 1;
  116822. + entryCount -= 1;
  116823. +
  116824. + /* Last entry? */
  116825. + if (entryCount == 0)
  116826. + {
  116827. + /* Reset the queue to idle. */
  116828. + queueTail->pending = 0;
  116829. +
  116830. + /* Get a shortcut to the queue to merge with. */
  116831. + mergeQueue = command->mergeQueue;
  116832. +
  116833. + /* Merge the queues if necessary. */
  116834. + if (mergeQueue != queueTail)
  116835. + {
  116836. + gcmkASSERT(mergeQueue < queueTail);
  116837. + gcmkASSERT(mergeQueue->next == queueTail);
  116838. +
  116839. + mergeQueue->size
  116840. + += gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  116841. + + queueTail->size;
  116842. +
  116843. + mergeQueue->next = queueTail->next;
  116844. + }
  116845. +
  116846. + /* Advance to the next queue. */
  116847. + queueTail = queueTail->next;
  116848. +
  116849. + /* Did it wrap around? */
  116850. + if (command->queue == queueTail)
  116851. + {
  116852. + /* Reset merge queue. */
  116853. + command->mergeQueue = queueTail;
  116854. + }
  116855. +
  116856. + /* Set new queue. */
  116857. + command->queueTail = queueTail;
  116858. +
  116859. + /* Is the next queue scheduled? */
  116860. + if (queueTail->pending > 0)
  116861. + {
  116862. + gcsCMDBUFFER_PTR commandBuffer;
  116863. +
  116864. + /* The first entry must be a command buffer. */
  116865. + commandBuffer = queueTail->currentEntry->commandBuffer;
  116866. +
  116867. + /* Start the command processor. */
  116868. + status = gckVGHARDWARE_Execute(
  116869. + command->hardware,
  116870. + commandBuffer->address,
  116871. + commandBuffer->dataCount
  116872. + );
  116873. +
  116874. + /* Failed? */
  116875. + if (gcmkIS_ERROR(status))
  116876. + {
  116877. + gcmkTRACE_ZONE(
  116878. + gcvLEVEL_ERROR,
  116879. + gcvZONE_COMMAND,
  116880. + "[%s] line %d: failed to start the next queue.\n",
  116881. + __FUNCTION__, __LINE__
  116882. + );
  116883. + }
  116884. + }
  116885. + else
  116886. + {
  116887. + status = gckVGHARDWARE_SetPowerManagementState(
  116888. + Kernel->command->hardware, gcvPOWER_IDLE_BROADCAST
  116889. + );
  116890. + }
  116891. +
  116892. + /* Break out of the loop. */
  116893. + break;
  116894. + }
  116895. + }
  116896. +
  116897. + /* Release the mutex. */
  116898. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  116899. + command->os,
  116900. + command->queueMutex
  116901. + ));
  116902. + }
  116903. + while (gcvFALSE);
  116904. +
  116905. +
  116906. + gcmkFOOTER();
  116907. + /* Return status. */
  116908. + return status;
  116909. +}
  116910. +
  116911. +/* Define standard block interrupt handlers. */
  116912. +gcmDEFINE_INTERRUPT_HANDLER(TESSELLATOR, 0)
  116913. +gcmDEFINE_INTERRUPT_HANDLER(VG, 0)
  116914. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 0)
  116915. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 1)
  116916. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 2)
  116917. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 3)
  116918. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 4)
  116919. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 5)
  116920. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 6)
  116921. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 7)
  116922. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 8)
  116923. +gcmDEFINE_INTERRUPT_HANDLER(PIXEL, 9)
  116924. +
  116925. +/* The entries in the array are arranged by event priority. */
  116926. +static gcsBLOCK_INTERRUPT_HANDLER _blockHandlers[] =
  116927. +{
  116928. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(TESSELLATOR, 0),
  116929. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(VG, 0),
  116930. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 0),
  116931. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 1),
  116932. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 2),
  116933. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 3),
  116934. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 4),
  116935. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 5),
  116936. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 6),
  116937. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 7),
  116938. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 8),
  116939. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(PIXEL, 9),
  116940. + gcmDEFINE_INTERRUPT_HANDLER_ENTRY(COMMAND, 0),
  116941. +};
  116942. +
  116943. +
  116944. +/******************************************************************************\
  116945. +************************* Static Command Buffer Handlers ***********************
  116946. +\******************************************************************************/
  116947. +
  116948. +static gceSTATUS
  116949. +_UpdateStaticCommandBuffer(
  116950. + IN gckVGKERNEL Kernel,
  116951. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  116952. + )
  116953. +{
  116954. + gcmkTRACE_ZONE(
  116955. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  116956. + "%s(%d)\n",
  116957. + __FUNCTION__, __LINE__
  116958. + );
  116959. +
  116960. + /* Success. */
  116961. + return gcvSTATUS_OK;
  116962. +}
  116963. +
  116964. +static gceSTATUS
  116965. +_ExecuteStaticCommandBuffer(
  116966. + IN gckVGKERNEL Kernel,
  116967. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  116968. + )
  116969. +{
  116970. + gceSTATUS status;
  116971. +
  116972. + do
  116973. + {
  116974. + gcsCMDBUFFER_PTR commandBuffer;
  116975. +
  116976. + /* Cast the command buffer header. */
  116977. + commandBuffer = Entry->commandBuffer;
  116978. +
  116979. + /* Set to update the command buffer next time. */
  116980. + Entry->handler = _UpdateStaticCommandBuffer;
  116981. +
  116982. + gcmkTRACE_ZONE(
  116983. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  116984. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  116985. + __FUNCTION__, __LINE__,
  116986. + commandBuffer->address,
  116987. + commandBuffer->dataCount
  116988. + );
  116989. +
  116990. + /* Start the command processor. */
  116991. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  116992. + Kernel->hardware,
  116993. + commandBuffer->address,
  116994. + commandBuffer->dataCount
  116995. + ));
  116996. +
  116997. + /* Success. */
  116998. + return gcvSTATUS_EXECUTED;
  116999. + }
  117000. + while (gcvFALSE);
  117001. +
  117002. + /* Return status. */
  117003. + return status;
  117004. +}
  117005. +
  117006. +static gceSTATUS
  117007. +_UpdateLastStaticCommandBuffer(
  117008. + IN gckVGKERNEL Kernel,
  117009. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  117010. + )
  117011. +{
  117012. +#if gcvDEBUG || gcdFORCE_MESSAGES
  117013. + /* Get the command buffer header. */
  117014. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  117015. +
  117016. + /* Validate the command buffer. */
  117017. + gcmkASSERT(commandBuffer->completion != gcvNULL);
  117018. + gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
  117019. +
  117020. +#endif
  117021. +
  117022. + gcmkTRACE_ZONE(
  117023. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  117024. + "%s(%d): processing all tasks scheduled for FE.\n",
  117025. + __FUNCTION__, __LINE__
  117026. + );
  117027. +
  117028. + /* Perform scheduled tasks. */
  117029. + return _EventHandler_Block(
  117030. + Kernel,
  117031. + &Kernel->command->taskTable[gcvBLOCK_COMMAND],
  117032. + gcvTRUE
  117033. + );
  117034. +}
  117035. +
  117036. +static gceSTATUS
  117037. +_ExecuteLastStaticCommandBuffer(
  117038. + IN gckVGKERNEL Kernel,
  117039. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  117040. + )
  117041. +{
  117042. + gceSTATUS status;
  117043. +
  117044. + do
  117045. + {
  117046. + /* Cast the command buffer header. */
  117047. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  117048. +
  117049. + /* Set to update the command buffer next time. */
  117050. + Entry->handler = _UpdateLastStaticCommandBuffer;
  117051. +
  117052. + gcmkTRACE_ZONE(
  117053. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  117054. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  117055. + __FUNCTION__, __LINE__,
  117056. + commandBuffer->address,
  117057. + commandBuffer->dataCount
  117058. + );
  117059. +
  117060. + /* Start the command processor. */
  117061. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  117062. + Kernel->hardware,
  117063. + commandBuffer->address,
  117064. + commandBuffer->dataCount
  117065. + ));
  117066. +
  117067. + /* Success. */
  117068. + return gcvSTATUS_EXECUTED;
  117069. + }
  117070. + while (gcvFALSE);
  117071. +
  117072. + /* Return status. */
  117073. + return status;
  117074. +}
  117075. +
  117076. +
  117077. +/******************************************************************************\
  117078. +************************* Dynamic Command Buffer Handlers **********************
  117079. +\******************************************************************************/
  117080. +
  117081. +static gceSTATUS
  117082. +_UpdateDynamicCommandBuffer(
  117083. + IN gckVGKERNEL Kernel,
  117084. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  117085. + )
  117086. +{
  117087. + gcmkTRACE_ZONE(
  117088. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  117089. + "%s(%d)\n",
  117090. + __FUNCTION__, __LINE__
  117091. + );
  117092. +
  117093. + /* Success. */
  117094. + return gcvSTATUS_OK;
  117095. +}
  117096. +
  117097. +static gceSTATUS
  117098. +_ExecuteDynamicCommandBuffer(
  117099. + IN gckVGKERNEL Kernel,
  117100. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  117101. + )
  117102. +{
  117103. + gceSTATUS status;
  117104. +
  117105. + do
  117106. + {
  117107. + /* Cast the command buffer header. */
  117108. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  117109. +
  117110. + /* Set to update the command buffer next time. */
  117111. + Entry->handler = _UpdateDynamicCommandBuffer;
  117112. +
  117113. + gcmkTRACE_ZONE(
  117114. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  117115. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  117116. + __FUNCTION__, __LINE__,
  117117. + commandBuffer->address,
  117118. + commandBuffer->dataCount
  117119. + );
  117120. +
  117121. + /* Start the command processor. */
  117122. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  117123. + Kernel->hardware,
  117124. + commandBuffer->address,
  117125. + commandBuffer->dataCount
  117126. + ));
  117127. +
  117128. + /* Success. */
  117129. + return gcvSTATUS_EXECUTED;
  117130. + }
  117131. + while (gcvFALSE);
  117132. +
  117133. + /* Return status. */
  117134. + return status;
  117135. +}
  117136. +
  117137. +static gceSTATUS
  117138. +_UpdateLastDynamicCommandBuffer(
  117139. + IN gckVGKERNEL Kernel,
  117140. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  117141. + )
  117142. +{
  117143. +#if gcvDEBUG || gcdFORCE_MESSAGES
  117144. + /* Get the command buffer header. */
  117145. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  117146. +
  117147. + /* Validate the command buffer. */
  117148. + gcmkASSERT(commandBuffer->completion != gcvNULL);
  117149. + gcmkASSERT(commandBuffer->completion != gcvVACANT_BUFFER);
  117150. +
  117151. +#endif
  117152. +
  117153. + gcmkTRACE_ZONE(
  117154. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  117155. + "%s(%d): processing all tasks scheduled for FE.\n",
  117156. + __FUNCTION__, __LINE__
  117157. + );
  117158. +
  117159. + /* Perform scheduled tasks. */
  117160. + return _EventHandler_Block(
  117161. + Kernel,
  117162. + &Kernel->command->taskTable[gcvBLOCK_COMMAND],
  117163. + gcvTRUE
  117164. + );
  117165. +}
  117166. +
  117167. +static gceSTATUS
  117168. +_ExecuteLastDynamicCommandBuffer(
  117169. + IN gckVGKERNEL Kernel,
  117170. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  117171. + )
  117172. +{
  117173. + gceSTATUS status;
  117174. +
  117175. + do
  117176. + {
  117177. + /* Cast the command buffer header. */
  117178. + gcsCMDBUFFER_PTR commandBuffer = Entry->commandBuffer;
  117179. +
  117180. + /* Set to update the command buffer next time. */
  117181. + Entry->handler = _UpdateLastDynamicCommandBuffer;
  117182. +
  117183. + gcmkTRACE_ZONE(
  117184. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  117185. + "%s(%d): executing next buffer @ 0x%08X, data count = %d\n",
  117186. + __FUNCTION__, __LINE__,
  117187. + commandBuffer->address,
  117188. + commandBuffer->dataCount
  117189. + );
  117190. +
  117191. + /* Start the command processor. */
  117192. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  117193. + Kernel->hardware,
  117194. + commandBuffer->address,
  117195. + commandBuffer->dataCount
  117196. + ));
  117197. +
  117198. + /* Success. */
  117199. + return gcvSTATUS_EXECUTED;
  117200. + }
  117201. + while (gcvFALSE);
  117202. +
  117203. + /* Return status. */
  117204. + return status;
  117205. +}
  117206. +
  117207. +
  117208. +/******************************************************************************\
  117209. +********************************* Other Handlers *******************************
  117210. +\******************************************************************************/
  117211. +
  117212. +static gceSTATUS
  117213. +_FreeKernelCommandBuffer(
  117214. + IN gckVGKERNEL Kernel,
  117215. + IN gcsKERNEL_CMDQUEUE_PTR Entry
  117216. + )
  117217. +{
  117218. + gceSTATUS status;
  117219. +
  117220. + /* Free the command buffer. */
  117221. + status = _FreeCommandBuffer(Kernel, Entry->commandBuffer);
  117222. +
  117223. + /* Return status. */
  117224. + return status;
  117225. +}
  117226. +
  117227. +
  117228. +/******************************************************************************\
  117229. +******************************* Queue Management *******************************
  117230. +\******************************************************************************/
  117231. +
  117232. +#if gcvDUMP_COMMAND_BUFFER
  117233. +static void
  117234. +_DumpCommandQueue(
  117235. + IN gckVGCOMMAND Command,
  117236. + IN gcsKERNEL_QUEUE_HEADER_PTR QueueHeader,
  117237. + IN gctUINT EntryCount
  117238. + )
  117239. +{
  117240. + gcsKERNEL_CMDQUEUE_PTR entry;
  117241. + gctUINT queueIndex;
  117242. +
  117243. +#if defined(gcvCOMMAND_BUFFER_NAME)
  117244. + static gctUINT arrayCount = 0;
  117245. +#endif
  117246. +
  117247. + /* Is dumpinng enabled? */
  117248. + if (!Commad->enableDumping)
  117249. + {
  117250. + return;
  117251. + }
  117252. +
  117253. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  117254. + gcmkTRACE_ZONE(
  117255. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  117256. + "COMMAND QUEUE DUMP: %d entries\n", EntryCount
  117257. + );
  117258. +#endif
  117259. +
  117260. + /* Get the pointer to the first entry. */
  117261. + entry = QueueHeader->currentEntry;
  117262. +
  117263. + /* Iterate through the queue. */
  117264. + for (queueIndex = 0; queueIndex < EntryCount; queueIndex += 1)
  117265. + {
  117266. + gcsCMDBUFFER_PTR buffer;
  117267. + gctUINT bufferCount;
  117268. + gctUINT bufferIndex;
  117269. + gctUINT i, count;
  117270. + gctUINT size;
  117271. + gctUINT32_PTR data;
  117272. +
  117273. +#if gcvDUMP_COMMAND_LINES
  117274. + gctUINT lineNumber;
  117275. +#endif
  117276. +
  117277. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  117278. + gcmkTRACE_ZONE(
  117279. + gcvLEVEL_INFO, gcvZONE_COMMAND,
  117280. + "ENTRY %d\n", queueIndex
  117281. + );
  117282. +#endif
  117283. +
  117284. + /* Reset the count. */
  117285. + bufferCount = 0;
  117286. +
  117287. + /* Set the initial buffer. */
  117288. + buffer = entry->commandBuffer;
  117289. +
  117290. + /* Loop through all subbuffers. */
  117291. + while (buffer)
  117292. + {
  117293. + /* Update the count. */
  117294. + bufferCount += 1;
  117295. +
  117296. + /* Advance to the next subbuffer. */
  117297. + buffer = buffer->nextSubBuffer;
  117298. + }
  117299. +
  117300. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  117301. + if (bufferCount > 1)
  117302. + {
  117303. + gcmkTRACE_ZONE(
  117304. + gcvLEVEL_INFO,
  117305. + gcvZONE_COMMAND,
  117306. + " COMMAND BUFFER SET: %d buffers.\n",
  117307. + bufferCount
  117308. + );
  117309. + }
  117310. +#endif
  117311. +
  117312. + /* Reset the buffer index. */
  117313. + bufferIndex = 0;
  117314. +
  117315. + /* Set the initial buffer. */
  117316. + buffer = entry->commandBuffer;
  117317. +
  117318. + /* Loop through all subbuffers. */
  117319. + while (buffer)
  117320. + {
  117321. + /* Determine the size of the buffer. */
  117322. + size = buffer->dataCount * Command->info.commandAlignment;
  117323. +
  117324. +#if !defined(gcvCOMMAND_BUFFER_NAME)
  117325. + /* A single buffer? */
  117326. + if (bufferCount == 1)
  117327. + {
  117328. + gcmkTRACE_ZONE(
  117329. + gcvLEVEL_INFO,
  117330. + gcvZONE_COMMAND,
  117331. + " COMMAND BUFFER: count=%d (0x%X), size=%d bytes @ %08X.\n",
  117332. + buffer->dataCount,
  117333. + buffer->dataCount,
  117334. + size,
  117335. + buffer->address
  117336. + );
  117337. + }
  117338. + else
  117339. + {
  117340. + gcmkTRACE_ZONE(
  117341. + gcvLEVEL_INFO,
  117342. + gcvZONE_COMMAND,
  117343. + " COMMAND BUFFER %d: count=%d (0x%X), size=%d bytes @ %08X\n",
  117344. + bufferIndex,
  117345. + buffer->dataCount,
  117346. + buffer->dataCount,
  117347. + size,
  117348. + buffer->address
  117349. + );
  117350. + }
  117351. +#endif
  117352. +
  117353. + /* Determine the number of double words to print. */
  117354. + count = size / 4;
  117355. +
  117356. + /* Determine the buffer location. */
  117357. + data = (gctUINT32_PTR)
  117358. + (
  117359. + (gctUINT8_PTR) buffer + buffer->bufferOffset
  117360. + );
  117361. +
  117362. +#if defined(gcvCOMMAND_BUFFER_NAME)
  117363. + gcmkTRACE_ZONE(
  117364. + gcvLEVEL_INFO,
  117365. + gcvZONE_COMMAND,
  117366. + "unsigned int _" gcvCOMMAND_BUFFER_NAME "_%d[] =\n",
  117367. + arrayCount
  117368. + );
  117369. +
  117370. + gcmkTRACE_ZONE(
  117371. + gcvLEVEL_INFO,
  117372. + gcvZONE_COMMAND,
  117373. + "{\n"
  117374. + );
  117375. +
  117376. + arrayCount += 1;
  117377. +#endif
  117378. +
  117379. +#if gcvDUMP_COMMAND_LINES
  117380. + /* Reset the line number. */
  117381. + lineNumber = 0;
  117382. +#endif
  117383. +
  117384. +#if defined(gcvCOMMAND_BUFFER_NAME)
  117385. + count -= 2;
  117386. +#endif
  117387. +
  117388. + for (i = 0; i < count; i += 1)
  117389. + {
  117390. + if ((i % 8) == 0)
  117391. + {
  117392. +#if defined(gcvCOMMAND_BUFFER_NAME)
  117393. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\t");
  117394. +#else
  117395. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " ");
  117396. +#endif
  117397. + }
  117398. +
  117399. +#if gcvDUMP_COMMAND_LINES
  117400. + if (lineNumber == gcvDUMP_COMMAND_LINES)
  117401. + {
  117402. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, " . . . . . . . . .\n");
  117403. + break;
  117404. + }
  117405. +#endif
  117406. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "0x%08X", data[i]);
  117407. +
  117408. + if (i + 1 == count)
  117409. + {
  117410. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, "\n");
  117411. +
  117412. +#if gcvDUMP_COMMAND_LINES
  117413. + lineNumber += 1;
  117414. +#endif
  117415. + }
  117416. + else
  117417. + {
  117418. + if (((i + 1) % 8) == 0)
  117419. + {
  117420. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ",\n");
  117421. +
  117422. +#if gcvDUMP_COMMAND_LINES
  117423. + lineNumber += 1;
  117424. +#endif
  117425. + }
  117426. + else
  117427. + {
  117428. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_COMMAND, ", ");
  117429. + }
  117430. + }
  117431. + }
  117432. +
  117433. +#if defined(gcvCOMMAND_BUFFER_NAME)
  117434. + gcmkTRACE_ZONE(
  117435. + gcvLEVEL_INFO,
  117436. + gcvZONE_COMMAND,
  117437. + "};\n\n"
  117438. + );
  117439. +#endif
  117440. +
  117441. + /* Advance to the next subbuffer. */
  117442. + buffer = buffer->nextSubBuffer;
  117443. + bufferIndex += 1;
  117444. + }
  117445. +
  117446. + /* Advance to the next entry. */
  117447. + entry += 1;
  117448. + }
  117449. +}
  117450. +#endif
  117451. +
  117452. +static gceSTATUS
  117453. +_LockCurrentQueue(
  117454. + IN gckVGCOMMAND Command,
  117455. + OUT gcsKERNEL_CMDQUEUE_PTR * Entries,
  117456. + OUT gctUINT_PTR EntryCount
  117457. + )
  117458. +{
  117459. + gceSTATUS status;
  117460. +
  117461. + do
  117462. + {
  117463. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  117464. +
  117465. + /* Get a shortcut to the head of the queue. */
  117466. + queueHead = Command->queueHead;
  117467. +
  117468. + /* Is the head buffer still being worked on? */
  117469. + if (queueHead->pending)
  117470. + {
  117471. + /* Increment overflow count. */
  117472. + Command->queueOverflow += 1;
  117473. +
  117474. + /* Wait until the head becomes idle. */
  117475. + gcmkERR_BREAK(_WaitForIdle(Command, queueHead));
  117476. + }
  117477. +
  117478. + /* Acquire the mutex. */
  117479. + gcmkERR_BREAK(gckOS_AcquireMutex(
  117480. + Command->os,
  117481. + Command->queueMutex,
  117482. + gcvINFINITE
  117483. + ));
  117484. +
  117485. + /* Determine the first queue entry. */
  117486. + queueHead->currentEntry = (gcsKERNEL_CMDQUEUE_PTR)
  117487. + (
  117488. + (gctUINT8_PTR) queueHead + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  117489. + );
  117490. +
  117491. + /* Set the pointer to the first entry. */
  117492. + * Entries = queueHead->currentEntry;
  117493. +
  117494. + /* Determine the number of available entries. */
  117495. + * EntryCount = queueHead->size / gcmSIZEOF(gcsKERNEL_CMDQUEUE);
  117496. +
  117497. + /* Success. */
  117498. + return gcvSTATUS_OK;
  117499. + }
  117500. + while (gcvFALSE);
  117501. +
  117502. + /* Return status. */
  117503. + return status;
  117504. +}
  117505. +
  117506. +static gceSTATUS
  117507. +_UnlockCurrentQueue(
  117508. + IN gckVGCOMMAND Command,
  117509. + IN gctUINT EntryCount
  117510. + )
  117511. +{
  117512. + gceSTATUS status;
  117513. +
  117514. + do
  117515. + {
  117516. +#if !gcdENABLE_INFINITE_SPEED_HW
  117517. + gcsKERNEL_QUEUE_HEADER_PTR queueTail;
  117518. + gcsKERNEL_QUEUE_HEADER_PTR queueHead;
  117519. + gcsKERNEL_QUEUE_HEADER_PTR queueNext;
  117520. + gctUINT queueSize;
  117521. + gctUINT newSize;
  117522. + gctUINT unusedSize;
  117523. +
  117524. + /* Get shortcut to the head and to the tail of the queue. */
  117525. + queueTail = Command->queueTail;
  117526. + queueHead = Command->queueHead;
  117527. +
  117528. + /* Dump the command buffer. */
  117529. +#if gcvDUMP_COMMAND_BUFFER
  117530. + _DumpCommandQueue(Command, queueHead, EntryCount);
  117531. +#endif
  117532. +
  117533. + /* Get a shortcut to the current queue size. */
  117534. + queueSize = queueHead->size;
  117535. +
  117536. + /* Determine the new queue size. */
  117537. + newSize = EntryCount * gcmSIZEOF(gcsKERNEL_CMDQUEUE);
  117538. + gcmkASSERT(newSize <= queueSize);
  117539. +
  117540. + /* Determine the size of the unused area. */
  117541. + unusedSize = queueSize - newSize;
  117542. +
  117543. + /* Is the unused area big enough to become a buffer? */
  117544. + if (unusedSize >= gcvMINUMUM_BUFFER)
  117545. + {
  117546. + gcsKERNEL_QUEUE_HEADER_PTR nextHead;
  117547. +
  117548. + /* Place the new header. */
  117549. + nextHead = (gcsKERNEL_QUEUE_HEADER_PTR)
  117550. + (
  117551. + (gctUINT8_PTR) queueHead
  117552. + + gcmSIZEOF(gcsKERNEL_QUEUE_HEADER)
  117553. + + newSize
  117554. + );
  117555. +
  117556. + /* Initialize the buffer. */
  117557. + nextHead->size = unusedSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
  117558. + nextHead->pending = 0;
  117559. +
  117560. + /* Link the buffer in. */
  117561. + nextHead->next = queueHead->next;
  117562. + queueHead->next = nextHead;
  117563. + queueNext = nextHead;
  117564. +
  117565. + /* Update the size of the current buffer. */
  117566. + queueHead->size = newSize;
  117567. + }
  117568. +
  117569. + /* Not big enough. */
  117570. + else
  117571. + {
  117572. + /* Determine the next queue. */
  117573. + queueNext = queueHead->next;
  117574. + }
  117575. +
  117576. + /* Mark the buffer as busy. */
  117577. + queueHead->pending = EntryCount;
  117578. +
  117579. + /* Advance to the next buffer. */
  117580. + Command->queueHead = queueNext;
  117581. +
  117582. + /* Start the command processor if the queue was empty. */
  117583. + if (queueTail == queueHead)
  117584. + {
  117585. + gcsCMDBUFFER_PTR commandBuffer;
  117586. +
  117587. + /* The first entry must be a command buffer. */
  117588. + commandBuffer = queueTail->currentEntry->commandBuffer;
  117589. +
  117590. + /* Start the command processor. */
  117591. + gcmkERR_BREAK(gckVGHARDWARE_Execute(
  117592. + Command->hardware,
  117593. + commandBuffer->address,
  117594. + commandBuffer->dataCount
  117595. + ));
  117596. + }
  117597. +
  117598. + /* The queue was not empty. */
  117599. + else
  117600. + {
  117601. + /* Advance the merge buffer if needed. */
  117602. + if (queueHead == Command->mergeQueue)
  117603. + {
  117604. + Command->mergeQueue = queueNext;
  117605. + }
  117606. + }
  117607. +#endif
  117608. +
  117609. + /* Release the mutex. */
  117610. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  117611. + Command->os,
  117612. + Command->queueMutex
  117613. + ));
  117614. +
  117615. + /* Success. */
  117616. + return gcvSTATUS_OK;
  117617. + }
  117618. + while (gcvFALSE);
  117619. +
  117620. + /* Return status. */
  117621. + return status;
  117622. +}
  117623. +
  117624. +
  117625. +
  117626. +/******************************************************************************\
  117627. +****************************** gckVGCOMMAND API Code *****************************
  117628. +\******************************************************************************/
  117629. +gceSTATUS
  117630. +gckVGCOMMAND_Construct(
  117631. + IN gckVGKERNEL Kernel,
  117632. + IN gctUINT TaskGranularity,
  117633. + IN gctUINT QueueSize,
  117634. + OUT gckVGCOMMAND * Command
  117635. + )
  117636. +{
  117637. + gceSTATUS status, last;
  117638. + gckVGCOMMAND command = gcvNULL;
  117639. + gcsKERNEL_QUEUE_HEADER_PTR queue;
  117640. + gctUINT i, j;
  117641. +
  117642. + gcmkHEADER_ARG("Kernel=0x%x TaskGranularity=0x%x QueueSize=0x%x Command=0x%x",
  117643. + Kernel, TaskGranularity, QueueSize, Command);
  117644. + /* Verify the arguments. */
  117645. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  117646. + gcmkVERIFY_ARGUMENT(QueueSize >= gcvMINUMUM_BUFFER);
  117647. + gcmkVERIFY_ARGUMENT(Command != gcvNULL);
  117648. +
  117649. + do
  117650. + {
  117651. + /***********************************************************************
  117652. + ** Generic object initialization.
  117653. + */
  117654. +
  117655. + /* Allocate the gckVGCOMMAND structure. */
  117656. + gcmkERR_BREAK(gckOS_Allocate(
  117657. + Kernel->os,
  117658. + gcmSIZEOF(struct _gckVGCOMMAND),
  117659. + (gctPOINTER *) &command
  117660. + ));
  117661. +
  117662. + /* Initialize the object. */
  117663. + command->object.type = gcvOBJ_COMMAND;
  117664. +
  117665. + /* Set the object pointers. */
  117666. + command->kernel = Kernel;
  117667. + command->os = Kernel->os;
  117668. + command->hardware = Kernel->hardware;
  117669. +
  117670. + /* Reset pointers. */
  117671. + command->queue = gcvNULL;
  117672. + command->queueMutex = gcvNULL;
  117673. + command->taskMutex = gcvNULL;
  117674. + command->commitMutex = gcvNULL;
  117675. +
  117676. + command->powerStallBuffer = gcvNULL;
  117677. + command->powerStallSignal = gcvNULL;
  117678. + command->powerSemaphore = gcvNULL;
  117679. +
  117680. + /* Reset context states. */
  117681. + command->contextCounter = 0;
  117682. + command->currentContext = 0;
  117683. +
  117684. + /* Enable command buffer dumping. */
  117685. + command->enableDumping = gcvTRUE;
  117686. +
  117687. + /* Set features. */
  117688. + command->fe20 = Kernel->hardware->fe20;
  117689. + command->vg20 = Kernel->hardware->vg20;
  117690. + command->vg21 = Kernel->hardware->vg21;
  117691. +
  117692. + /* Reset task table .*/
  117693. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  117694. + command->taskTable, gcmSIZEOF(command->taskTable)
  117695. + ));
  117696. +
  117697. + /* Query command buffer attributes. */
  117698. + gcmkERR_BREAK(gckVGCOMMAND_InitializeInfo(command));
  117699. +
  117700. + /* Create the control mutexes. */
  117701. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->queueMutex));
  117702. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->taskMutex));
  117703. + gcmkERR_BREAK(gckOS_CreateMutex(Kernel->os, &command->commitMutex));
  117704. +
  117705. + /* Create the power management semaphore. */
  117706. + gcmkERR_BREAK(gckOS_CreateSemaphore(Kernel->os,
  117707. + &command->powerSemaphore));
  117708. +
  117709. + gcmkERR_BREAK(gckOS_CreateSignal(Kernel->os,
  117710. + gcvFALSE, &command->powerStallSignal));
  117711. +
  117712. + /***********************************************************************
  117713. + ** Command queue initialization.
  117714. + */
  117715. +
  117716. + /* Allocate the command queue. */
  117717. + gcmkERR_BREAK(gckOS_Allocate(
  117718. + Kernel->os,
  117719. + QueueSize,
  117720. + (gctPOINTER *) &command->queue
  117721. + ));
  117722. +
  117723. + /* Initialize the command queue. */
  117724. + queue = command->queue;
  117725. +
  117726. + queue->size = QueueSize - gcmSIZEOF(gcsKERNEL_QUEUE_HEADER);
  117727. + queue->pending = 0;
  117728. + queue->next = queue;
  117729. +
  117730. + command->queueHead =
  117731. + command->queueTail =
  117732. + command->mergeQueue = command->queue;
  117733. +
  117734. + command->queueOverflow = 0;
  117735. +
  117736. +
  117737. + /***********************************************************************
  117738. + ** Enable TS overflow interrupt.
  117739. + */
  117740. +
  117741. + command->info.tsOverflowInt = 0;
  117742. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  117743. + Kernel->interrupt,
  117744. + &command->info.tsOverflowInt,
  117745. + _EventHandler_TSOverflow
  117746. + ));
  117747. +
  117748. + /* Mask out the interrupt. */
  117749. + Kernel->hardware->eventMask &= ~(1 << command->info.tsOverflowInt);
  117750. +
  117751. +
  117752. + /***********************************************************************
  117753. + ** Enable Bus Error interrupt.
  117754. + */
  117755. +
  117756. + /* Hardwired to bit 31. */
  117757. + command->busErrorInt = 31;
  117758. +
  117759. + /* Enable the interrupt. */
  117760. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  117761. + Kernel->interrupt,
  117762. + &command->busErrorInt,
  117763. + _EventHandler_BusError
  117764. + ));
  117765. +
  117766. +
  117767. + command->powerStallInt = 30;
  117768. + /* Enable the interrupt. */
  117769. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  117770. + Kernel->interrupt,
  117771. + &command->powerStallInt,
  117772. + _EventHandler_PowerStall
  117773. + ));
  117774. +
  117775. + /***********************************************************************
  117776. + ** Task management initialization.
  117777. + */
  117778. +
  117779. + command->taskStorage = gcvNULL;
  117780. + command->taskStorageGranularity = TaskGranularity;
  117781. + command->taskStorageUsable = TaskGranularity - gcmSIZEOF(gcsTASK_STORAGE);
  117782. +
  117783. + command->taskFreeHead = gcvNULL;
  117784. + command->taskFreeTail = gcvNULL;
  117785. +
  117786. + /* Enable block handlers. */
  117787. + for (i = 0; i < gcmCOUNTOF(_blockHandlers); i += 1)
  117788. + {
  117789. + /* Get the target hardware block. */
  117790. + gceBLOCK block = _blockHandlers[i].block;
  117791. +
  117792. + /* Get the interrupt array entry. */
  117793. + gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[block];
  117794. +
  117795. + /* Determine the interrupt value index. */
  117796. + gctUINT index = entry->interruptCount;
  117797. +
  117798. + /* Create the block semaphore. */
  117799. + if (entry->interruptSemaphore == gcvNULL)
  117800. + {
  117801. + gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
  117802. + command->os, &entry->interruptSemaphore
  117803. + ));
  117804. + }
  117805. +
  117806. + /* Enable auto-detection. */
  117807. + entry->interruptArray[index] = -1;
  117808. +
  117809. + /* Enable interrupt for the block. */
  117810. + gcmkERR_BREAK(gckVGINTERRUPT_Enable(
  117811. + Kernel->interrupt,
  117812. + &entry->interruptArray[index],
  117813. + _blockHandlers[i].handler
  117814. + ));
  117815. +
  117816. + /* Update the number of registered interrupts. */
  117817. + entry->interruptCount += 1;
  117818. +
  117819. + /* Inrement the semaphore to allow the usage of the registered
  117820. + interrupt. */
  117821. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  117822. + command->os, entry->interruptSemaphore
  117823. + ));
  117824. +
  117825. + }
  117826. +
  117827. + /* Error? */
  117828. + if (gcmkIS_ERROR(status))
  117829. + {
  117830. + break;
  117831. + }
  117832. +
  117833. + /* Get the FE interrupt. */
  117834. + command->info.feBufferInt
  117835. + = command->taskTable[gcvBLOCK_COMMAND].interruptArray[0];
  117836. +
  117837. + /* Return gckVGCOMMAND object pointer. */
  117838. + *Command = command;
  117839. +
  117840. + gcmkFOOTER_ARG("*Command=0x%x",*Command);
  117841. + /* Success. */
  117842. + return gcvSTATUS_OK;
  117843. + }
  117844. + while (gcvFALSE);
  117845. +
  117846. + /* Roll back. */
  117847. + if (command != gcvNULL)
  117848. + {
  117849. + /* Disable block handlers. */
  117850. + for (i = 0; i < gcvBLOCK_COUNT; i += 1)
  117851. + {
  117852. + /* Get the task table entry. */
  117853. + gcsBLOCK_TASK_ENTRY_PTR entry = &command->taskTable[i];
  117854. +
  117855. + /* Destroy the semaphore. */
  117856. + if (entry->interruptSemaphore != gcvNULL)
  117857. + {
  117858. + gcmkCHECK_STATUS(gckOS_DestroySemaphore(
  117859. + command->os, entry->interruptSemaphore
  117860. + ));
  117861. + }
  117862. +
  117863. + /* Disable all enabled interrupts. */
  117864. + for (j = 0; j < entry->interruptCount; j += 1)
  117865. + {
  117866. + /* Must be a valid value. */
  117867. + gcmkASSERT(entry->interruptArray[j] >= 0);
  117868. + gcmkASSERT(entry->interruptArray[j] <= 31);
  117869. +
  117870. + /* Disable the interrupt. */
  117871. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  117872. + Kernel->interrupt,
  117873. + entry->interruptArray[j]
  117874. + ));
  117875. + }
  117876. + }
  117877. +
  117878. + /* Disable the bus error interrupt. */
  117879. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  117880. + Kernel->interrupt,
  117881. + command->busErrorInt
  117882. + ));
  117883. +
  117884. + /* Disable TS overflow interrupt. */
  117885. + if (command->info.tsOverflowInt != -1)
  117886. + {
  117887. + gcmkCHECK_STATUS(gckVGINTERRUPT_Disable(
  117888. + Kernel->interrupt,
  117889. + command->info.tsOverflowInt
  117890. + ));
  117891. + }
  117892. +
  117893. + /* Delete the commit mutex. */
  117894. + if (command->commitMutex != gcvNULL)
  117895. + {
  117896. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  117897. + Kernel->os, command->commitMutex
  117898. + ));
  117899. + }
  117900. +
  117901. + /* Delete the command queue mutex. */
  117902. + if (command->taskMutex != gcvNULL)
  117903. + {
  117904. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  117905. + Kernel->os, command->taskMutex
  117906. + ));
  117907. + }
  117908. +
  117909. + /* Delete the command queue mutex. */
  117910. + if (command->queueMutex != gcvNULL)
  117911. + {
  117912. + gcmkCHECK_STATUS(gckOS_DeleteMutex(
  117913. + Kernel->os, command->queueMutex
  117914. + ));
  117915. + }
  117916. +
  117917. + /* Delete the command queue. */
  117918. + if (command->queue != gcvNULL)
  117919. + {
  117920. + gcmkCHECK_STATUS(gckOS_Free(
  117921. + Kernel->os, command->queue
  117922. + ));
  117923. + }
  117924. +
  117925. + if (command->powerSemaphore != gcvNULL)
  117926. + {
  117927. + gcmkVERIFY_OK(gckOS_DestroySemaphore(
  117928. + Kernel->os, command->powerSemaphore));
  117929. + }
  117930. +
  117931. + if (command->powerStallSignal != gcvNULL)
  117932. + {
  117933. + /* Create the power management semaphore. */
  117934. + gcmkVERIFY_OK(gckOS_DestroySignal(
  117935. + Kernel->os,
  117936. + command->powerStallSignal));
  117937. + }
  117938. +
  117939. + /* Free the gckVGCOMMAND structure. */
  117940. + gcmkCHECK_STATUS(gckOS_Free(
  117941. + Kernel->os, command
  117942. + ));
  117943. + }
  117944. +
  117945. + gcmkFOOTER();
  117946. + /* Return the error. */
  117947. + return status;
  117948. +}
  117949. +
  117950. +gceSTATUS
  117951. +gckVGCOMMAND_Destroy(
  117952. + OUT gckVGCOMMAND Command
  117953. + )
  117954. +{
  117955. + gceSTATUS status = gcvSTATUS_OK;
  117956. +
  117957. + gcmkHEADER_ARG("Command=0x%x", Command);
  117958. +
  117959. + /* Verify the arguments. */
  117960. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  117961. +
  117962. + do
  117963. + {
  117964. + gctUINT i;
  117965. + gcsTASK_STORAGE_PTR nextStorage;
  117966. +
  117967. + if (Command->queueHead != gcvNULL)
  117968. + {
  117969. + /* Wait until the head becomes idle. */
  117970. + gcmkERR_BREAK(_WaitForIdle(Command, Command->queueHead));
  117971. + }
  117972. +
  117973. + /* Disable block handlers. */
  117974. + for (i = 0; i < gcvBLOCK_COUNT; i += 1)
  117975. + {
  117976. + /* Get the interrupt array entry. */
  117977. + gcsBLOCK_TASK_ENTRY_PTR entry = &Command->taskTable[i];
  117978. +
  117979. + /* Determine the index of the last interrupt in the array. */
  117980. + gctINT index = entry->interruptCount - 1;
  117981. +
  117982. + /* Destroy the semaphore. */
  117983. + if (entry->interruptSemaphore != gcvNULL)
  117984. + {
  117985. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  117986. + Command->os, entry->interruptSemaphore
  117987. + ));
  117988. + }
  117989. +
  117990. + /* Disable all enabled interrupts. */
  117991. + while (index >= 0)
  117992. + {
  117993. + /* Must be a valid value. */
  117994. + gcmkASSERT(entry->interruptArray[index] >= 0);
  117995. + gcmkASSERT(entry->interruptArray[index] <= 31);
  117996. +
  117997. + /* Disable the interrupt. */
  117998. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  117999. + Command->kernel->interrupt,
  118000. + entry->interruptArray[index]
  118001. + ));
  118002. +
  118003. + /* Update to the next interrupt. */
  118004. + index -= 1;
  118005. + entry->interruptCount -= 1;
  118006. + }
  118007. +
  118008. + /* Error? */
  118009. + if (gcmkIS_ERROR(status))
  118010. + {
  118011. + break;
  118012. + }
  118013. + }
  118014. +
  118015. + /* Error? */
  118016. + if (gcmkIS_ERROR(status))
  118017. + {
  118018. + break;
  118019. + }
  118020. +
  118021. + /* Disable the bus error interrupt. */
  118022. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  118023. + Command->kernel->interrupt,
  118024. + Command->busErrorInt
  118025. + ));
  118026. +
  118027. + /* Disable TS overflow interrupt. */
  118028. + if (Command->info.tsOverflowInt != -1)
  118029. + {
  118030. + gcmkERR_BREAK(gckVGINTERRUPT_Disable(
  118031. + Command->kernel->interrupt,
  118032. + Command->info.tsOverflowInt
  118033. + ));
  118034. +
  118035. + Command->info.tsOverflowInt = -1;
  118036. + }
  118037. +
  118038. + /* Delete the commit mutex. */
  118039. + if (Command->commitMutex != gcvNULL)
  118040. + {
  118041. + gcmkERR_BREAK(gckOS_DeleteMutex(
  118042. + Command->os, Command->commitMutex
  118043. + ));
  118044. +
  118045. + Command->commitMutex = gcvNULL;
  118046. + }
  118047. +
  118048. + /* Delete the command queue mutex. */
  118049. + if (Command->taskMutex != gcvNULL)
  118050. + {
  118051. + gcmkERR_BREAK(gckOS_DeleteMutex(
  118052. + Command->os, Command->taskMutex
  118053. + ));
  118054. +
  118055. + Command->taskMutex = gcvNULL;
  118056. + }
  118057. +
  118058. + /* Delete the command queue mutex. */
  118059. + if (Command->queueMutex != gcvNULL)
  118060. + {
  118061. + gcmkERR_BREAK(gckOS_DeleteMutex(
  118062. + Command->os, Command->queueMutex
  118063. + ));
  118064. +
  118065. + Command->queueMutex = gcvNULL;
  118066. + }
  118067. +
  118068. + if (Command->powerSemaphore != gcvNULL)
  118069. + {
  118070. + /* Destroy the power management semaphore. */
  118071. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  118072. + Command->os, Command->powerSemaphore));
  118073. + }
  118074. +
  118075. + if (Command->powerStallSignal != gcvNULL)
  118076. + {
  118077. + /* Create the power management semaphore. */
  118078. + gcmkERR_BREAK(gckOS_DestroySignal(
  118079. + Command->os,
  118080. + Command->powerStallSignal));
  118081. + }
  118082. +
  118083. + if (Command->queue != gcvNULL)
  118084. + {
  118085. + /* Delete the command queue. */
  118086. + gcmkERR_BREAK(gckOS_Free(
  118087. + Command->os, Command->queue
  118088. + ));
  118089. + }
  118090. +
  118091. + /* Destroy all allocated buffers. */
  118092. + while (Command->taskStorage)
  118093. + {
  118094. + /* Copy the buffer pointer. */
  118095. + nextStorage = Command->taskStorage->next;
  118096. +
  118097. + /* Free the current container. */
  118098. + gcmkERR_BREAK(gckOS_Free(
  118099. + Command->os, Command->taskStorage
  118100. + ));
  118101. +
  118102. + /* Advance to the next one. */
  118103. + Command->taskStorage = nextStorage;
  118104. + }
  118105. +
  118106. + /* Error? */
  118107. + if (gcmkIS_ERROR(status))
  118108. + {
  118109. + break;
  118110. + }
  118111. +
  118112. + /* Mark the object as unknown. */
  118113. + Command->object.type = gcvOBJ_UNKNOWN;
  118114. +
  118115. + /* Free the gckVGCOMMAND structure. */
  118116. + gcmkERR_BREAK(gckOS_Free(Command->os, Command));
  118117. +
  118118. + gcmkFOOTER_NO();
  118119. + /* Success. */
  118120. + return gcvSTATUS_OK;
  118121. + }
  118122. + while (gcvFALSE);
  118123. +
  118124. + /* Restore the object type if failed. */
  118125. + Command->object.type = gcvOBJ_COMMAND;
  118126. +
  118127. + gcmkFOOTER();
  118128. + /* Return the error. */
  118129. + return status;
  118130. +}
  118131. +
  118132. +gceSTATUS
  118133. +gckVGCOMMAND_QueryCommandBuffer(
  118134. + IN gckVGCOMMAND Command,
  118135. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  118136. + )
  118137. +{
  118138. + gcmkHEADER_ARG("Command=0x%x Information=0x%x", Command, Information);
  118139. + /* Verify the arguments. */
  118140. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  118141. + gcmkVERIFY_ARGUMENT(Information != gcvNULL);
  118142. +
  118143. + /* Copy the information. */
  118144. + gcmkVERIFY_OK(gckOS_MemCopy(
  118145. + Information, &Command->info, sizeof(gcsCOMMAND_BUFFER_INFO)
  118146. + ));
  118147. +
  118148. + gcmkFOOTER_NO();
  118149. + /* Success. */
  118150. + return gcvSTATUS_OK;
  118151. +}
  118152. +
  118153. +gceSTATUS
  118154. +gckVGCOMMAND_Allocate(
  118155. + IN gckVGCOMMAND Command,
  118156. + IN gctSIZE_T Size,
  118157. + OUT gcsCMDBUFFER_PTR * CommandBuffer,
  118158. + OUT gctPOINTER * Data
  118159. + )
  118160. +{
  118161. + gceSTATUS status;
  118162. +
  118163. + gcmkHEADER_ARG("Command=0x%x Size=0x%x CommandBuffer=0x%x Data=0x%x",
  118164. + Command, Size, CommandBuffer, Data);
  118165. +
  118166. + /* Verify the arguments. */
  118167. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  118168. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  118169. +
  118170. + do
  118171. + {
  118172. + /* Allocate the buffer. */
  118173. + gcmkERR_BREAK(_AllocateCommandBuffer(Command, Size, CommandBuffer));
  118174. +
  118175. + /* Determine the data pointer. */
  118176. + * Data = (gctUINT8_PTR) (*CommandBuffer) + (* CommandBuffer)->bufferOffset;
  118177. + }
  118178. + while (gcvFALSE);
  118179. +
  118180. + gcmkFOOTER();
  118181. + /* Return status. */
  118182. + return status;
  118183. +}
  118184. +
  118185. +gceSTATUS
  118186. +gckVGCOMMAND_Free(
  118187. + IN gckVGCOMMAND Command,
  118188. + IN gcsCMDBUFFER_PTR CommandBuffer
  118189. + )
  118190. +{
  118191. + gceSTATUS status;
  118192. +
  118193. + gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
  118194. + Command, CommandBuffer);
  118195. +
  118196. + /* Verify the arguments. */
  118197. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  118198. + gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
  118199. +
  118200. + /* Free command buffer. */
  118201. + status = _FreeCommandBuffer(Command->kernel, CommandBuffer);
  118202. +
  118203. + gcmkFOOTER();
  118204. + /* Return status. */
  118205. + return status;
  118206. +}
  118207. +
  118208. +gceSTATUS
  118209. +gckVGCOMMAND_Execute(
  118210. + IN gckVGCOMMAND Command,
  118211. + IN gcsCMDBUFFER_PTR CommandBuffer
  118212. + )
  118213. +{
  118214. + gceSTATUS status;
  118215. +
  118216. + gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
  118217. + Command, CommandBuffer);
  118218. +
  118219. + /* Verify the arguments. */
  118220. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  118221. + gcmkVERIFY_ARGUMENT(CommandBuffer != gcvNULL);
  118222. +
  118223. + do
  118224. + {
  118225. + gctUINT queueLength;
  118226. + gcsKERNEL_CMDQUEUE_PTR kernelEntry;
  118227. +
  118228. + /* Lock the current queue. */
  118229. + gcmkERR_BREAK(_LockCurrentQueue(
  118230. + Command, &kernelEntry, &queueLength
  118231. + ));
  118232. +
  118233. + /* Set the buffer. */
  118234. + kernelEntry->commandBuffer = CommandBuffer;
  118235. + kernelEntry->handler = _FreeKernelCommandBuffer;
  118236. +
  118237. + /* Lock the current queue. */
  118238. + gcmkERR_BREAK(_UnlockCurrentQueue(
  118239. + Command, 1
  118240. + ));
  118241. + }
  118242. + while (gcvFALSE);
  118243. +
  118244. + gcmkFOOTER();
  118245. + /* Return status. */
  118246. + return status;
  118247. +}
  118248. +
  118249. +gceSTATUS
  118250. +gckVGCOMMAND_Commit(
  118251. + IN gckVGCOMMAND Command,
  118252. + IN gcsVGCONTEXT_PTR Context,
  118253. + IN gcsVGCMDQUEUE_PTR Queue,
  118254. + IN gctUINT EntryCount,
  118255. + IN gcsTASK_MASTER_TABLE_PTR TaskTable
  118256. + )
  118257. +{
  118258. + /*
  118259. + The first buffer is executed through a direct gckVGHARDWARE_Execute call,
  118260. + therefore only an update is needed after the execution is over. All
  118261. + consequent buffers need to be executed upon the first update call from
  118262. + the FE interrupt handler.
  118263. + */
  118264. +
  118265. + static gcsQUEUE_UPDATE_CONTROL _dynamicBuffer[] =
  118266. + {
  118267. + {
  118268. + _UpdateDynamicCommandBuffer,
  118269. + _UpdateDynamicCommandBuffer,
  118270. + _UpdateLastDynamicCommandBuffer,
  118271. + _UpdateLastDynamicCommandBuffer
  118272. + },
  118273. + {
  118274. + _ExecuteDynamicCommandBuffer,
  118275. + _UpdateDynamicCommandBuffer,
  118276. + _ExecuteLastDynamicCommandBuffer,
  118277. + _UpdateLastDynamicCommandBuffer
  118278. + }
  118279. + };
  118280. +
  118281. + static gcsQUEUE_UPDATE_CONTROL _staticBuffer[] =
  118282. + {
  118283. + {
  118284. + _UpdateStaticCommandBuffer,
  118285. + _UpdateStaticCommandBuffer,
  118286. + _UpdateLastStaticCommandBuffer,
  118287. + _UpdateLastStaticCommandBuffer
  118288. + },
  118289. + {
  118290. + _ExecuteStaticCommandBuffer,
  118291. + _UpdateStaticCommandBuffer,
  118292. + _ExecuteLastStaticCommandBuffer,
  118293. + _UpdateLastStaticCommandBuffer
  118294. + }
  118295. + };
  118296. +
  118297. + gceSTATUS status, last;
  118298. +
  118299. + gcmkHEADER_ARG("Command=0x%x Context=0x%x Queue=0x%x EntryCount=0x%x TaskTable=0x%x",
  118300. + Command, Context, Queue, EntryCount, TaskTable);
  118301. +
  118302. + /* Verify the arguments. */
  118303. + gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
  118304. + gcmkVERIFY_ARGUMENT(Context != gcvNULL);
  118305. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  118306. + gcmkVERIFY_ARGUMENT(EntryCount > 1);
  118307. +
  118308. +#ifdef __QNXNTO__
  118309. + TaskTable->coid = Context->coid;
  118310. + TaskTable->rcvid = Context->rcvid;
  118311. +#endif /* __QNXNTO__ */
  118312. +
  118313. + do
  118314. + {
  118315. + gctBOOL haveFETasks;
  118316. + gctUINT queueSize;
  118317. + gcsVGCMDQUEUE_PTR mappedQueue;
  118318. + gcsVGCMDQUEUE_PTR userEntry;
  118319. + gcsKERNEL_CMDQUEUE_PTR kernelEntry;
  118320. + gcsQUEUE_UPDATE_CONTROL_PTR queueControl;
  118321. + gctUINT currentLength;
  118322. + gctUINT queueLength;
  118323. + gctUINT entriesQueued;
  118324. + gctUINT8_PTR previousEnd;
  118325. + gctBOOL previousDynamic;
  118326. + gctBOOL previousExecuted;
  118327. + gctUINT controlIndex;
  118328. +
  118329. + gcmkERR_BREAK(gckVGHARDWARE_SetPowerManagementState(
  118330. + Command->hardware, gcvPOWER_ON_AUTO
  118331. + ));
  118332. +
  118333. + /* Acquire the power semaphore. */
  118334. + gcmkERR_BREAK(gckOS_AcquireSemaphore(
  118335. + Command->os, Command->powerSemaphore
  118336. + ));
  118337. +
  118338. + /* Acquire the mutex. */
  118339. + status = gckOS_AcquireMutex(
  118340. + Command->os,
  118341. + Command->commitMutex,
  118342. + gcvINFINITE
  118343. + );
  118344. +
  118345. + if (gcmIS_ERROR(status))
  118346. + {
  118347. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  118348. + Command->os, Command->powerSemaphore));
  118349. + break;
  118350. + }
  118351. +
  118352. + do
  118353. + {
  118354. + gcmkERR_BREAK(_FlushMMU(Command));
  118355. +
  118356. + /* Assign a context ID if not yet assigned. */
  118357. + if (Context->id == 0)
  118358. + {
  118359. + /* Assign the next context number. */
  118360. + Context->id = ++ Command->contextCounter;
  118361. +
  118362. + /* See if we overflowed. */
  118363. + if (Command->contextCounter == 0)
  118364. + {
  118365. + /* We actually did overflow, wow... */
  118366. + status = gcvSTATUS_OUT_OF_RESOURCES;
  118367. + break;
  118368. + }
  118369. + }
  118370. +
  118371. + /* The first entry in the queue is always the context buffer.
  118372. + Verify whether the user context is the same as the current
  118373. + context and if that's the case, skip the first entry. */
  118374. + if (Context->id == Command->currentContext)
  118375. + {
  118376. + /* Same context as before, skip the first entry. */
  118377. + EntryCount -= 1;
  118378. + Queue += 1;
  118379. +
  118380. + /* Set the signal to avoid user waiting. */
  118381. +#ifdef __QNXNTO__
  118382. + gcmkERR_BREAK(gckOS_UserSignal(
  118383. + Command->os, Context->signal, Context->rcvid, Context->coid
  118384. + ));
  118385. +#else
  118386. + gcmkERR_BREAK(gckOS_UserSignal(
  118387. + Command->os, Context->signal, Context->process
  118388. + ));
  118389. +
  118390. +#endif /* __QNXNTO__ */
  118391. +
  118392. + }
  118393. + else
  118394. + {
  118395. + /* Different user context - keep the first entry.
  118396. + Set the user context as the current one. */
  118397. + Command->currentContext = Context->id;
  118398. + }
  118399. +
  118400. + /* Reset pointers. */
  118401. + queueControl = gcvNULL;
  118402. + previousEnd = gcvNULL;
  118403. +
  118404. + /* Determine whether there are FE tasks to be performed. */
  118405. + haveFETasks = (TaskTable->table[gcvBLOCK_COMMAND].head != gcvNULL);
  118406. +
  118407. + /* Determine the size of the queue. */
  118408. + queueSize = EntryCount * gcmSIZEOF(gcsVGCMDQUEUE);
  118409. +
  118410. + /* Map the command queue into the kernel space. */
  118411. + gcmkERR_BREAK(gckOS_MapUserPointer(
  118412. + Command->os,
  118413. + Queue,
  118414. + queueSize,
  118415. + (gctPOINTER *) &mappedQueue
  118416. + ));
  118417. +
  118418. + /* Set the first entry. */
  118419. + userEntry = mappedQueue;
  118420. +
  118421. + /* Process the command queue. */
  118422. + while (EntryCount)
  118423. + {
  118424. + /* Lock the current queue. */
  118425. + gcmkERR_BREAK(_LockCurrentQueue(
  118426. + Command, &kernelEntry, &queueLength
  118427. + ));
  118428. +
  118429. + /* Determine the number of entries to process. */
  118430. + currentLength = (queueLength < EntryCount)
  118431. + ? queueLength
  118432. + : EntryCount;
  118433. +
  118434. + /* Update the number of the entries left to process. */
  118435. + EntryCount -= currentLength;
  118436. +
  118437. + /* Reset previous flags. */
  118438. + previousDynamic = gcvFALSE;
  118439. + previousExecuted = gcvFALSE;
  118440. +
  118441. + /* Set the initial control index. */
  118442. + controlIndex = 0;
  118443. +
  118444. + /* Process entries. */
  118445. + for (entriesQueued = 0; entriesQueued < currentLength; entriesQueued += 1)
  118446. + {
  118447. + /* Get the kernel pointer to the command buffer header. */
  118448. + gcsCMDBUFFER_PTR commandBuffer = gcvNULL;
  118449. + gcmkERR_BREAK(_ConvertUserCommandBufferPointer(
  118450. + Command,
  118451. + userEntry->commandBuffer,
  118452. + &commandBuffer
  118453. + ));
  118454. +
  118455. + /* Is it a dynamic command buffer? */
  118456. + if (userEntry->dynamic)
  118457. + {
  118458. + /* Select dynamic buffer control functions. */
  118459. + queueControl = &_dynamicBuffer[controlIndex];
  118460. + }
  118461. +
  118462. + /* No, a static command buffer. */
  118463. + else
  118464. + {
  118465. + /* Select static buffer control functions. */
  118466. + queueControl = &_staticBuffer[controlIndex];
  118467. + }
  118468. +
  118469. + /* Set the command buffer pointer to the entry. */
  118470. + kernelEntry->commandBuffer = commandBuffer;
  118471. +
  118472. + /* If the previous entry was a dynamic command buffer,
  118473. + link it to the current. */
  118474. + if (previousDynamic)
  118475. + {
  118476. + gcmkERR_BREAK(gckVGCOMMAND_FetchCommand(
  118477. + Command,
  118478. + previousEnd,
  118479. + commandBuffer->address,
  118480. + commandBuffer->dataCount,
  118481. + gcvNULL
  118482. + ));
  118483. +
  118484. + /* The buffer will be auto-executed, only need to
  118485. + update it after it has been executed. */
  118486. + kernelEntry->handler = queueControl->update;
  118487. +
  118488. + /* The buffer is only being updated. */
  118489. + previousExecuted = gcvFALSE;
  118490. + }
  118491. + else
  118492. + {
  118493. + /* Set the buffer up for execution. */
  118494. + kernelEntry->handler = queueControl->execute;
  118495. +
  118496. + /* The buffer is being updated. */
  118497. + previousExecuted = gcvTRUE;
  118498. + }
  118499. +
  118500. + /* The current buffer's END command becomes the last END. */
  118501. + previousEnd
  118502. + = ((gctUINT8_PTR) commandBuffer)
  118503. + + commandBuffer->bufferOffset
  118504. + + commandBuffer->dataCount * Command->info.commandAlignment
  118505. + - Command->info.staticTailSize;
  118506. +
  118507. + /* Update the last entry info. */
  118508. + previousDynamic = userEntry->dynamic;
  118509. +
  118510. + /* Advance entries. */
  118511. + userEntry += 1;
  118512. + kernelEntry += 1;
  118513. +
  118514. + /* Update the control index. */
  118515. + controlIndex = 1;
  118516. + }
  118517. +
  118518. + /* If the previous entry was a dynamic command buffer,
  118519. + terminate it with an END. */
  118520. + if (previousDynamic)
  118521. + {
  118522. + gcmkERR_BREAK(gckVGCOMMAND_EndCommand(
  118523. + Command,
  118524. + previousEnd,
  118525. + Command->info.feBufferInt,
  118526. + gcvNULL
  118527. + ));
  118528. + }
  118529. +
  118530. + /* Last buffer? */
  118531. + if (EntryCount == 0)
  118532. + {
  118533. + /* Modify the last command buffer's routines to handle
  118534. + tasks if any.*/
  118535. + if (haveFETasks)
  118536. + {
  118537. + if (previousExecuted)
  118538. + {
  118539. + kernelEntry[-1].handler = queueControl->lastExecute;
  118540. + }
  118541. + else
  118542. + {
  118543. + kernelEntry[-1].handler = queueControl->lastUpdate;
  118544. + }
  118545. + }
  118546. +
  118547. + /* Release the mutex. */
  118548. + gcmkERR_BREAK(gckOS_ReleaseMutex(
  118549. + Command->os,
  118550. + Command->queueMutex
  118551. + ));
  118552. + /* Schedule tasks. */
  118553. + gcmkERR_BREAK(_ScheduleTasks(Command, TaskTable, previousEnd));
  118554. +
  118555. + /* Acquire the mutex. */
  118556. + gcmkERR_BREAK(gckOS_AcquireMutex(
  118557. + Command->os,
  118558. + Command->queueMutex,
  118559. + gcvINFINITE
  118560. + ));
  118561. + }
  118562. +
  118563. + /* Unkock and schedule the current queue for execution. */
  118564. + gcmkERR_BREAK(_UnlockCurrentQueue(
  118565. + Command, currentLength
  118566. + ));
  118567. + }
  118568. +
  118569. +
  118570. + /* Unmap the user command buffer. */
  118571. + gcmkERR_BREAK(gckOS_UnmapUserPointer(
  118572. + Command->os,
  118573. + Queue,
  118574. + queueSize,
  118575. + mappedQueue
  118576. + ));
  118577. + }
  118578. + while (gcvFALSE);
  118579. +
  118580. + /* Release the mutex. */
  118581. + gcmkCHECK_STATUS(gckOS_ReleaseMutex(
  118582. + Command->os,
  118583. + Command->commitMutex
  118584. + ));
  118585. +
  118586. + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(
  118587. + Command->os, Command->powerSemaphore));
  118588. + }
  118589. + while (gcvFALSE);
  118590. +
  118591. + gcmkFOOTER();
  118592. + /* Return status. */
  118593. + return status;
  118594. +}
  118595. +
  118596. +#endif /* gcdENABLE_VG */
  118597. diff -Nur linux-3.14.17/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
  118598. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c 1970-01-01 01:00:00.000000000 +0100
  118599. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c 2014-09-11 18:06:03.086042307 +0200
  118600. @@ -0,0 +1,1604 @@
  118601. +/****************************************************************************
  118602. +*
  118603. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  118604. +*
  118605. +* This program is free software; you can redistribute it and/or modify
  118606. +* it under the terms of the GNU General Public License as published by
  118607. +* the Free Software Foundation; either version 2 of the license, or
  118608. +* (at your option) any later version.
  118609. +*
  118610. +* This program is distributed in the hope that it will be useful,
  118611. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  118612. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  118613. +* GNU General Public License for more details.
  118614. +*
  118615. +* You should have received a copy of the GNU General Public License
  118616. +* along with this program; if not write to the Free Software
  118617. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  118618. +*
  118619. +*****************************************************************************/
  118620. +
  118621. +
  118622. +#include "gc_hal_kernel_precomp.h"
  118623. +
  118624. +#define _GC_OBJ_ZONE gcvZONE_DATABASE
  118625. +
  118626. +/*******************************************************************************
  118627. +***** Private fuctions ********************************************************/
  118628. +
  118629. +#define _GetSlot(database, x) \
  118630. + (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
  118631. +
  118632. +/*******************************************************************************
  118633. +** gckKERNEL_NewDatabase
  118634. +**
  118635. +** Create a new database structure and insert it to the head of the hash list.
  118636. +**
  118637. +** INPUT:
  118638. +**
  118639. +** gckKERNEL Kernel
  118640. +** Pointer to a gckKERNEL object.
  118641. +**
  118642. +** gctUINT32 ProcessID
  118643. +** ProcessID that identifies the database.
  118644. +**
  118645. +** OUTPUT:
  118646. +**
  118647. +** gcsDATABASE_PTR * Database
  118648. +** Pointer to a variable receiving the database structure pointer on
  118649. +** success.
  118650. +*/
  118651. +static gceSTATUS
  118652. +gckKERNEL_NewDatabase(
  118653. + IN gckKERNEL Kernel,
  118654. + IN gctUINT32 ProcessID,
  118655. + OUT gcsDATABASE_PTR * Database
  118656. + )
  118657. +{
  118658. + gceSTATUS status;
  118659. + gcsDATABASE_PTR database;
  118660. + gctBOOL acquired = gcvFALSE;
  118661. + gctSIZE_T slot;
  118662. + gcsDATABASE_PTR existingDatabase;
  118663. +
  118664. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  118665. +
  118666. + /* Acquire the database mutex. */
  118667. + gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  118668. + acquired = gcvTRUE;
  118669. +
  118670. + /* Compute the hash for the database. */
  118671. + slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
  118672. +
  118673. + /* Walk the hash list. */
  118674. + for (existingDatabase = Kernel->db->db[slot];
  118675. + existingDatabase != gcvNULL;
  118676. + existingDatabase = existingDatabase->next)
  118677. + {
  118678. + if (existingDatabase->processID == ProcessID)
  118679. + {
  118680. + /* One process can't be added twice. */
  118681. + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
  118682. + }
  118683. + }
  118684. +
  118685. + if (Kernel->db->freeDatabase != gcvNULL)
  118686. + {
  118687. + /* Allocate a database from the free list. */
  118688. + database = Kernel->db->freeDatabase;
  118689. + Kernel->db->freeDatabase = database->next;
  118690. + }
  118691. + else
  118692. + {
  118693. + gctPOINTER pointer = gcvNULL;
  118694. +
  118695. + /* Allocate a new database from the heap. */
  118696. + gcmkONERROR(gckOS_Allocate(Kernel->os,
  118697. + gcmSIZEOF(gcsDATABASE),
  118698. + &pointer));
  118699. +
  118700. + database = pointer;
  118701. + }
  118702. +
  118703. + /* Insert the database into the hash. */
  118704. + database->next = Kernel->db->db[slot];
  118705. + Kernel->db->db[slot] = database;
  118706. +
  118707. + /* Save the hash slot. */
  118708. + database->slot = slot;
  118709. +
  118710. + /* Release the database mutex. */
  118711. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  118712. +
  118713. + /* Return the database. */
  118714. + *Database = database;
  118715. +
  118716. + /* Success. */
  118717. + gcmkFOOTER_ARG("*Database=0x%x", *Database);
  118718. + return gcvSTATUS_OK;
  118719. +
  118720. +OnError:
  118721. + if (acquired)
  118722. + {
  118723. + /* Release the database mutex. */
  118724. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  118725. + }
  118726. +
  118727. + /* Return the status. */
  118728. + gcmkFOOTER();
  118729. + return status;
  118730. +}
  118731. +
  118732. +/*******************************************************************************
  118733. +** gckKERNEL_FindDatabase
  118734. +**
  118735. +** Find a database identified by a process ID and move it to the head of the
  118736. +** hash list.
  118737. +**
  118738. +** INPUT:
  118739. +**
  118740. +** gckKERNEL Kernel
  118741. +** Pointer to a gckKERNEL object.
  118742. +**
  118743. +** gctUINT32 ProcessID
  118744. +** ProcessID that identifies the database.
  118745. +**
  118746. +** gctBOOL LastProcessID
  118747. +** gcvTRUE if searching for the last known process ID. gcvFALSE if
  118748. +** we need to search for the process ID specified by the ProcessID
  118749. +** argument.
  118750. +**
  118751. +** OUTPUT:
  118752. +**
  118753. +** gcsDATABASE_PTR * Database
  118754. +** Pointer to a variable receiving the database structure pointer on
  118755. +** success.
  118756. +*/
  118757. +static gceSTATUS
  118758. +gckKERNEL_FindDatabase(
  118759. + IN gckKERNEL Kernel,
  118760. + IN gctUINT32 ProcessID,
  118761. + IN gctBOOL LastProcessID,
  118762. + OUT gcsDATABASE_PTR * Database
  118763. + )
  118764. +{
  118765. + gceSTATUS status;
  118766. + gcsDATABASE_PTR database, previous;
  118767. + gctSIZE_T slot;
  118768. + gctBOOL acquired = gcvFALSE;
  118769. +
  118770. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d LastProcessID=%d",
  118771. + Kernel, ProcessID, LastProcessID);
  118772. +
  118773. + /* Compute the hash for the database. */
  118774. + slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
  118775. +
  118776. + /* Acquire the database mutex. */
  118777. + gcmkONERROR(
  118778. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  118779. + acquired = gcvTRUE;
  118780. +
  118781. + /* Check whether we are getting the last known database. */
  118782. + if (LastProcessID)
  118783. + {
  118784. + /* Use last database. */
  118785. + database = Kernel->db->lastDatabase;
  118786. +
  118787. + if (database == gcvNULL)
  118788. + {
  118789. + /* Database not found. */
  118790. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  118791. + }
  118792. + }
  118793. + else
  118794. + {
  118795. + /* Walk the hash list. */
  118796. + for (previous = gcvNULL, database = Kernel->db->db[slot];
  118797. + database != gcvNULL;
  118798. + database = database->next)
  118799. + {
  118800. + if (database->processID == ProcessID)
  118801. + {
  118802. + /* Found it! */
  118803. + break;
  118804. + }
  118805. +
  118806. + previous = database;
  118807. + }
  118808. +
  118809. + if (database == gcvNULL)
  118810. + {
  118811. + /* Database not found. */
  118812. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  118813. + }
  118814. +
  118815. + if (previous != gcvNULL)
  118816. + {
  118817. + /* Move database to the head of the hash list. */
  118818. + previous->next = database->next;
  118819. + database->next = Kernel->db->db[slot];
  118820. + Kernel->db->db[slot] = database;
  118821. + }
  118822. + }
  118823. +
  118824. + /* Release the database mutex. */
  118825. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  118826. +
  118827. + /* Return the database. */
  118828. + *Database = database;
  118829. +
  118830. + /* Success. */
  118831. + gcmkFOOTER_ARG("*Database=0x%x", *Database);
  118832. + return gcvSTATUS_OK;
  118833. +
  118834. +OnError:
  118835. + if (acquired)
  118836. + {
  118837. + /* Release the database mutex. */
  118838. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  118839. + }
  118840. +
  118841. + /* Return the status. */
  118842. + gcmkFOOTER();
  118843. + return status;
  118844. +}
  118845. +
  118846. +/*******************************************************************************
  118847. +** gckKERNEL_DeleteDatabase
  118848. +**
  118849. +** Remove a database from the hash list and delete its structure.
  118850. +**
  118851. +** INPUT:
  118852. +**
  118853. +** gckKERNEL Kernel
  118854. +** Pointer to a gckKERNEL object.
  118855. +**
  118856. +** gcsDATABASE_PTR Database
  118857. +** Pointer to the database structure to remove.
  118858. +**
  118859. +** OUTPUT:
  118860. +**
  118861. +** Nothing.
  118862. +*/
  118863. +static gceSTATUS
  118864. +gckKERNEL_DeleteDatabase(
  118865. + IN gckKERNEL Kernel,
  118866. + IN gcsDATABASE_PTR Database
  118867. + )
  118868. +{
  118869. + gceSTATUS status;
  118870. + gctBOOL acquired = gcvFALSE;
  118871. + gcsDATABASE_PTR database;
  118872. +
  118873. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
  118874. +
  118875. + /* Acquire the database mutex. */
  118876. + gcmkONERROR(
  118877. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  118878. + acquired = gcvTRUE;
  118879. +
  118880. + /* Check slot value. */
  118881. + gcmkVERIFY_ARGUMENT(Database->slot < gcmCOUNTOF(Kernel->db->db));
  118882. +
  118883. + if (Database->slot < gcmCOUNTOF(Kernel->db->db))
  118884. + {
  118885. + /* Check if database if the head of the hash list. */
  118886. + if (Kernel->db->db[Database->slot] == Database)
  118887. + {
  118888. + /* Remove the database from the hash list. */
  118889. + Kernel->db->db[Database->slot] = Database->next;
  118890. + }
  118891. + else
  118892. + {
  118893. + /* Walk the has list to find the database. */
  118894. + for (database = Kernel->db->db[Database->slot];
  118895. + database != gcvNULL;
  118896. + database = database->next
  118897. + )
  118898. + {
  118899. + /* Check if the next list entry is this database. */
  118900. + if (database->next == Database)
  118901. + {
  118902. + /* Remove the database from the hash list. */
  118903. + database->next = Database->next;
  118904. + break;
  118905. + }
  118906. + }
  118907. +
  118908. + if (database == gcvNULL)
  118909. + {
  118910. + /* Ouch! Something got corrupted. */
  118911. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  118912. + }
  118913. + }
  118914. + }
  118915. +
  118916. + if (Kernel->db->lastDatabase != gcvNULL)
  118917. + {
  118918. + /* Insert database to the free list. */
  118919. + Kernel->db->lastDatabase->next = Kernel->db->freeDatabase;
  118920. + Kernel->db->freeDatabase = Kernel->db->lastDatabase;
  118921. + }
  118922. +
  118923. + /* Keep database as the last database. */
  118924. + Kernel->db->lastDatabase = Database;
  118925. +
  118926. + /* Release the database mutex. */
  118927. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  118928. +
  118929. + /* Success. */
  118930. + gcmkFOOTER_NO();
  118931. + return gcvSTATUS_OK;
  118932. +
  118933. +OnError:
  118934. + if (acquired)
  118935. + {
  118936. + /* Release the database mutex. */
  118937. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  118938. + }
  118939. +
  118940. + /* Return the status. */
  118941. + gcmkFOOTER();
  118942. + return status;
  118943. +}
  118944. +
  118945. +/*******************************************************************************
  118946. +** gckKERNEL_NewRecord
  118947. +**
  118948. +** Create a new database record structure and insert it to the head of the
  118949. +** database.
  118950. +**
  118951. +** INPUT:
  118952. +**
  118953. +** gckKERNEL Kernel
  118954. +** Pointer to a gckKERNEL object.
  118955. +**
  118956. +** gcsDATABASE_PTR Database
  118957. +** Pointer to a database structure.
  118958. +**
  118959. +** OUTPUT:
  118960. +**
  118961. +** gcsDATABASE_RECORD_PTR * Record
  118962. +** Pointer to a variable receiving the database record structure
  118963. +** pointer on success.
  118964. +*/
  118965. +static gceSTATUS
  118966. +gckKERNEL_NewRecord(
  118967. + IN gckKERNEL Kernel,
  118968. + IN gcsDATABASE_PTR Database,
  118969. + IN gctUINT32 Slot,
  118970. + OUT gcsDATABASE_RECORD_PTR * Record
  118971. + )
  118972. +{
  118973. + gceSTATUS status;
  118974. + gctBOOL acquired = gcvFALSE;
  118975. + gcsDATABASE_RECORD_PTR record = gcvNULL;
  118976. +
  118977. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
  118978. +
  118979. + /* Acquire the database mutex. */
  118980. + gcmkONERROR(
  118981. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  118982. + acquired = gcvTRUE;
  118983. +
  118984. + if (Kernel->db->freeRecord != gcvNULL)
  118985. + {
  118986. + /* Allocate the record from the free list. */
  118987. + record = Kernel->db->freeRecord;
  118988. + Kernel->db->freeRecord = record->next;
  118989. + }
  118990. + else
  118991. + {
  118992. + gctPOINTER pointer = gcvNULL;
  118993. +
  118994. + /* Allocate the record from the heap. */
  118995. + gcmkONERROR(gckOS_Allocate(Kernel->os,
  118996. + gcmSIZEOF(gcsDATABASE_RECORD),
  118997. + &pointer));
  118998. +
  118999. + record = pointer;
  119000. + }
  119001. +
  119002. + /* Insert the record in the database. */
  119003. + record->next = Database->list[Slot];
  119004. + Database->list[Slot] = record;
  119005. +
  119006. + /* Release the database mutex. */
  119007. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  119008. +
  119009. + /* Return the record. */
  119010. + *Record = record;
  119011. +
  119012. + /* Success. */
  119013. + gcmkFOOTER_ARG("*Record=0x%x", *Record);
  119014. + return gcvSTATUS_OK;
  119015. +
  119016. +OnError:
  119017. + if (acquired)
  119018. + {
  119019. + /* Release the database mutex. */
  119020. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  119021. + }
  119022. + if (record != gcvNULL)
  119023. + {
  119024. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, record));
  119025. + }
  119026. +
  119027. + /* Return the status. */
  119028. + gcmkFOOTER();
  119029. + return status;
  119030. +}
  119031. +
  119032. +/*******************************************************************************
  119033. +** gckKERNEL_DeleteRecord
  119034. +**
  119035. +** Remove a database record from the database and delete its structure.
  119036. +**
  119037. +** INPUT:
  119038. +**
  119039. +** gckKERNEL Kernel
  119040. +** Pointer to a gckKERNEL object.
  119041. +**
  119042. +** gcsDATABASE_PTR Database
  119043. +** Pointer to a database structure.
  119044. +**
  119045. +** gceDATABASE_TYPE Type
  119046. +** Type of the record to remove.
  119047. +**
  119048. +** gctPOINTER Data
  119049. +** Data of the record to remove.
  119050. +**
  119051. +** OUTPUT:
  119052. +**
  119053. +** gctSIZE_T_PTR Bytes
  119054. +** Pointer to a variable that receives the size of the record deleted.
  119055. +** Can be gcvNULL if the size is not required.
  119056. +*/
  119057. +static gceSTATUS
  119058. +gckKERNEL_DeleteRecord(
  119059. + IN gckKERNEL Kernel,
  119060. + IN gcsDATABASE_PTR Database,
  119061. + IN gceDATABASE_TYPE Type,
  119062. + IN gctPOINTER Data,
  119063. + OUT gctSIZE_T_PTR Bytes OPTIONAL
  119064. + )
  119065. +{
  119066. + gceSTATUS status;
  119067. + gctBOOL acquired = gcvFALSE;
  119068. + gcsDATABASE_RECORD_PTR record, previous;
  119069. + gctUINT32 slot = _GetSlot(Database, Data);
  119070. +
  119071. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
  119072. + Kernel, Database, Type, Data);
  119073. +
  119074. + /* Acquire the database mutex. */
  119075. + gcmkONERROR(
  119076. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  119077. + acquired = gcvTRUE;
  119078. +
  119079. +
  119080. + /* Scan the database for this record. */
  119081. + for (record = Database->list[slot], previous = gcvNULL;
  119082. + record != gcvNULL;
  119083. + record = record->next
  119084. + )
  119085. + {
  119086. + if ((record->type == Type)
  119087. + && (record->data == Data)
  119088. + )
  119089. + {
  119090. + /* Found it! */
  119091. + break;
  119092. + }
  119093. +
  119094. + previous = record;
  119095. + }
  119096. +
  119097. + if (record == gcvNULL)
  119098. + {
  119099. + /* Ouch! This record is not found? */
  119100. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  119101. + }
  119102. +
  119103. + if (Bytes != gcvNULL)
  119104. + {
  119105. + /* Return size of record. */
  119106. + *Bytes = record->bytes;
  119107. + }
  119108. +
  119109. + /* Remove record from database. */
  119110. + if (previous == gcvNULL)
  119111. + {
  119112. + Database->list[slot] = record->next;
  119113. + }
  119114. + else
  119115. + {
  119116. + previous->next = record->next;
  119117. + }
  119118. +
  119119. + /* Insert record in free list. */
  119120. + record->next = Kernel->db->freeRecord;
  119121. + Kernel->db->freeRecord = record;
  119122. +
  119123. + /* Release the database mutex. */
  119124. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  119125. +
  119126. + /* Success. */
  119127. + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
  119128. + return gcvSTATUS_OK;
  119129. +
  119130. +OnError:
  119131. + if (acquired)
  119132. + {
  119133. + /* Release the database mutex. */
  119134. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  119135. + }
  119136. +
  119137. + /* Return the status. */
  119138. + gcmkFOOTER();
  119139. + return status;
  119140. +}
  119141. +
  119142. +/*******************************************************************************
  119143. +** gckKERNEL_FindRecord
  119144. +**
  119145. +** Find a database record from the database.
  119146. +**
  119147. +** INPUT:
  119148. +**
  119149. +** gckKERNEL Kernel
  119150. +** Pointer to a gckKERNEL object.
  119151. +**
  119152. +** gcsDATABASE_PTR Database
  119153. +** Pointer to a database structure.
  119154. +**
  119155. +** gceDATABASE_TYPE Type
  119156. +** Type of the record to remove.
  119157. +**
  119158. +** gctPOINTER Data
  119159. +** Data of the record to remove.
  119160. +**
  119161. +** OUTPUT:
  119162. +**
  119163. +** gctSIZE_T_PTR Bytes
  119164. +** Pointer to a variable that receives the size of the record deleted.
  119165. +** Can be gcvNULL if the size is not required.
  119166. +*/
  119167. +static gceSTATUS
  119168. +gckKERNEL_FindRecord(
  119169. + IN gckKERNEL Kernel,
  119170. + IN gcsDATABASE_PTR Database,
  119171. + IN gceDATABASE_TYPE Type,
  119172. + IN gctPOINTER Data,
  119173. + OUT gcsDATABASE_RECORD_PTR Record
  119174. + )
  119175. +{
  119176. + gceSTATUS status;
  119177. + gctBOOL acquired = gcvFALSE;
  119178. + gcsDATABASE_RECORD_PTR record;
  119179. + gctUINT32 slot = _GetSlot(Database, Data);
  119180. +
  119181. + gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
  119182. + Kernel, Database, Type, Data);
  119183. +
  119184. + /* Acquire the database mutex. */
  119185. + gcmkONERROR(
  119186. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  119187. + acquired = gcvTRUE;
  119188. +
  119189. + /* Scan the database for this record. */
  119190. + for (record = Database->list[slot];
  119191. + record != gcvNULL;
  119192. + record = record->next
  119193. + )
  119194. + {
  119195. + if ((record->type == Type)
  119196. + && (record->data == Data)
  119197. + )
  119198. + {
  119199. + /* Found it! */
  119200. + break;
  119201. + }
  119202. + }
  119203. +
  119204. + if (record == gcvNULL)
  119205. + {
  119206. + /* Ouch! This record is not found? */
  119207. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  119208. + }
  119209. +
  119210. + if (Record != gcvNULL)
  119211. + {
  119212. + /* Return information of record. */
  119213. + gcmkONERROR(
  119214. + gckOS_MemCopy(Record, record, sizeof(gcsDATABASE_RECORD)));
  119215. + }
  119216. +
  119217. + /* Release the database mutex. */
  119218. + gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  119219. +
  119220. + /* Success. */
  119221. + gcmkFOOTER_ARG("Record=0x%x", Record);
  119222. + return gcvSTATUS_OK;
  119223. +
  119224. +OnError:
  119225. + if (acquired)
  119226. + {
  119227. + /* Release the database mutex. */
  119228. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  119229. + }
  119230. +
  119231. + /* Return the status. */
  119232. + gcmkFOOTER();
  119233. + return status;
  119234. +}
  119235. +
  119236. +
  119237. +/*******************************************************************************
  119238. +***** Public API **************************************************************/
  119239. +
  119240. +/*******************************************************************************
  119241. +** gckKERNEL_CreateProcessDB
  119242. +**
  119243. +** Create a new process database.
  119244. +**
  119245. +** INPUT:
  119246. +**
  119247. +** gckKERNEL Kernel
  119248. +** Pointer to a gckKERNEL object.
  119249. +**
  119250. +** gctUINT32 ProcessID
  119251. +** Process ID used to identify the database.
  119252. +**
  119253. +** OUTPUT:
  119254. +**
  119255. +** Nothing.
  119256. +*/
  119257. +gceSTATUS
  119258. +gckKERNEL_CreateProcessDB(
  119259. + IN gckKERNEL Kernel,
  119260. + IN gctUINT32 ProcessID
  119261. + )
  119262. +{
  119263. + gceSTATUS status;
  119264. + gcsDATABASE_PTR database = gcvNULL;
  119265. + gctUINT32 i;
  119266. +
  119267. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  119268. +
  119269. + /* Verify the arguments. */
  119270. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  119271. +
  119272. + /* Create a new database. */
  119273. + gcmkONERROR(gckKERNEL_NewDatabase(Kernel, ProcessID, &database));
  119274. +
  119275. + /* Initialize the database. */
  119276. + database->processID = ProcessID;
  119277. + database->vidMem.bytes = 0;
  119278. + database->vidMem.maxBytes = 0;
  119279. + database->vidMem.totalBytes = 0;
  119280. + database->nonPaged.bytes = 0;
  119281. + database->nonPaged.maxBytes = 0;
  119282. + database->nonPaged.totalBytes = 0;
  119283. + database->contiguous.bytes = 0;
  119284. + database->contiguous.maxBytes = 0;
  119285. + database->contiguous.totalBytes = 0;
  119286. + database->mapMemory.bytes = 0;
  119287. + database->mapMemory.maxBytes = 0;
  119288. + database->mapMemory.totalBytes = 0;
  119289. + database->mapUserMemory.bytes = 0;
  119290. + database->mapUserMemory.maxBytes = 0;
  119291. + database->mapUserMemory.totalBytes = 0;
  119292. + database->vidMemResv.bytes = 0;
  119293. + database->vidMemResv.maxBytes = 0;
  119294. + database->vidMemResv.totalBytes = 0;
  119295. + database->vidMemCont.bytes = 0;
  119296. + database->vidMemCont.maxBytes = 0;
  119297. + database->vidMemCont.totalBytes = 0;
  119298. + database->vidMemVirt.bytes = 0;
  119299. + database->vidMemVirt.maxBytes = 0;
  119300. + database->vidMemVirt.totalBytes = 0;
  119301. +
  119302. + for (i = 0; i < gcmCOUNTOF(database->list); i++)
  119303. + {
  119304. + database->list[i] = gcvNULL;
  119305. + }
  119306. +
  119307. +#if gcdSECURE_USER
  119308. + {
  119309. + gctINT slot;
  119310. + gcskSECURE_CACHE * cache = &database->cache;
  119311. +
  119312. + /* Setup the linked list of cache nodes. */
  119313. + for (slot = 1; slot <= gcdSECURE_CACHE_SLOTS; ++slot)
  119314. + {
  119315. + cache->cache[slot].logical = gcvNULL;
  119316. +
  119317. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  119318. + cache->cache[slot].prev = &cache->cache[slot - 1];
  119319. + cache->cache[slot].next = &cache->cache[slot + 1];
  119320. +# endif
  119321. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  119322. + cache->cache[slot].nextHash = gcvNULL;
  119323. + cache->cache[slot].prevHash = gcvNULL;
  119324. +# endif
  119325. + }
  119326. +
  119327. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  119328. + /* Setup the head and tail of the cache. */
  119329. + cache->cache[0].next = &cache->cache[1];
  119330. + cache->cache[0].prev = &cache->cache[gcdSECURE_CACHE_SLOTS];
  119331. + cache->cache[0].logical = gcvNULL;
  119332. +
  119333. + /* Fix up the head and tail pointers. */
  119334. + cache->cache[0].next->prev = &cache->cache[0];
  119335. + cache->cache[0].prev->next = &cache->cache[0];
  119336. +# endif
  119337. +
  119338. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  119339. + /* Zero out the hash table. */
  119340. + for (slot = 0; slot < gcmCOUNTOF(cache->hash); ++slot)
  119341. + {
  119342. + cache->hash[slot].logical = gcvNULL;
  119343. + cache->hash[slot].nextHash = gcvNULL;
  119344. + }
  119345. +# endif
  119346. +
  119347. + /* Initialize cache index. */
  119348. + cache->cacheIndex = gcvNULL;
  119349. + cache->cacheFree = 1;
  119350. + cache->cacheStamp = 0;
  119351. + }
  119352. +#endif
  119353. +
  119354. + /* Reset idle timer. */
  119355. + Kernel->db->lastIdle = 0;
  119356. +
  119357. + /* Success. */
  119358. + gcmkFOOTER_NO();
  119359. + return gcvSTATUS_OK;
  119360. +
  119361. +OnError:
  119362. + /* Return the status. */
  119363. + gcmkFOOTER();
  119364. + return status;
  119365. +}
  119366. +
  119367. +/*******************************************************************************
  119368. +** gckKERNEL_AddProcessDB
  119369. +**
  119370. +** Add a record to a process database.
  119371. +**
  119372. +** INPUT:
  119373. +**
  119374. +** gckKERNEL Kernel
  119375. +** Pointer to a gckKERNEL object.
  119376. +**
  119377. +** gctUINT32 ProcessID
  119378. +** Process ID used to identify the database.
  119379. +**
  119380. +** gceDATABASE_TYPE TYPE
  119381. +** Type of the record to add.
  119382. +**
  119383. +** gctPOINTER Pointer
  119384. +** Data of the record to add.
  119385. +**
  119386. +** gctPHYS_ADDR Physical
  119387. +** Physical address of the record to add.
  119388. +**
  119389. +** gctSIZE_T Size
  119390. +** Size of the record to add.
  119391. +**
  119392. +** OUTPUT:
  119393. +**
  119394. +** Nothing.
  119395. +*/
  119396. +gceSTATUS
  119397. +gckKERNEL_AddProcessDB(
  119398. + IN gckKERNEL Kernel,
  119399. + IN gctUINT32 ProcessID,
  119400. + IN gceDATABASE_TYPE Type,
  119401. + IN gctPOINTER Pointer,
  119402. + IN gctPHYS_ADDR Physical,
  119403. + IN gctSIZE_T Size
  119404. + )
  119405. +{
  119406. + gceSTATUS status;
  119407. + gcsDATABASE_PTR database;
  119408. + gcsDATABASE_RECORD_PTR record = gcvNULL;
  119409. + gcsDATABASE_COUNTERS * count;
  119410. +
  119411. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
  119412. + "Physical=0x%x Size=%lu",
  119413. + Kernel, ProcessID, Type, Pointer, Physical, Size);
  119414. +
  119415. + /* Verify the arguments. */
  119416. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  119417. +
  119418. + /* Special case the idle record. */
  119419. + if (Type == gcvDB_IDLE)
  119420. + {
  119421. + gctUINT64 time;
  119422. +
  119423. + /* Get the current profile time. */
  119424. + gcmkONERROR(gckOS_GetProfileTick(&time));
  119425. +
  119426. + if ((ProcessID == 0) && (Kernel->db->lastIdle != 0))
  119427. + {
  119428. + /* Out of idle, adjust time it was idle. */
  119429. + Kernel->db->idleTime += time - Kernel->db->lastIdle;
  119430. + Kernel->db->lastIdle = 0;
  119431. + }
  119432. + else if (ProcessID == 1)
  119433. + {
  119434. + /* Save current idle time. */
  119435. + Kernel->db->lastIdle = time;
  119436. + }
  119437. +
  119438. +#if gcdDYNAMIC_SPEED
  119439. + {
  119440. + /* Test for first call. */
  119441. + if (Kernel->db->lastSlowdown == 0)
  119442. + {
  119443. + /* Save milliseconds. */
  119444. + Kernel->db->lastSlowdown = time;
  119445. + Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
  119446. + }
  119447. + else
  119448. + {
  119449. + /* Compute ellapsed time in milliseconds. */
  119450. + gctUINT delta = gckOS_ProfileToMS(time - Kernel->db->lastSlowdown);
  119451. +
  119452. + /* Test for end of period. */
  119453. + if (delta >= gcdDYNAMIC_SPEED)
  119454. + {
  119455. + /* Compute number of idle milliseconds. */
  119456. + gctUINT idle = gckOS_ProfileToMS(
  119457. + Kernel->db->idleTime - Kernel->db->lastSlowdownIdle);
  119458. +
  119459. + /* Broadcast to slow down the GPU. */
  119460. + gcmkONERROR(gckOS_BroadcastCalibrateSpeed(Kernel->os,
  119461. + Kernel->hardware,
  119462. + idle,
  119463. + delta));
  119464. +
  119465. + /* Save current time. */
  119466. + Kernel->db->lastSlowdown = time;
  119467. + Kernel->db->lastSlowdownIdle = Kernel->db->idleTime;
  119468. + }
  119469. + }
  119470. + }
  119471. +#endif
  119472. +
  119473. + /* Success. */
  119474. + gcmkFOOTER_NO();
  119475. + return gcvSTATUS_OK;
  119476. + }
  119477. +
  119478. + /* Verify the arguments. */
  119479. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  119480. +
  119481. + /* Find the database. */
  119482. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  119483. +
  119484. + /* Create a new record in the database. */
  119485. + gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record));
  119486. +
  119487. + /* Initialize the record. */
  119488. + record->kernel = Kernel;
  119489. + record->type = Type;
  119490. + record->data = Pointer;
  119491. + record->physical = Physical;
  119492. + record->bytes = Size;
  119493. +
  119494. + /* Get pointer to counters. */
  119495. + switch (Type)
  119496. + {
  119497. + case gcvDB_VIDEO_MEMORY:
  119498. + count = &database->vidMem;
  119499. + break;
  119500. +
  119501. + case gcvDB_NON_PAGED:
  119502. + count = &database->nonPaged;
  119503. + break;
  119504. +
  119505. + case gcvDB_CONTIGUOUS:
  119506. + count = &database->contiguous;
  119507. + break;
  119508. +
  119509. + case gcvDB_MAP_MEMORY:
  119510. + count = &database->mapMemory;
  119511. + break;
  119512. +
  119513. + case gcvDB_MAP_USER_MEMORY:
  119514. + count = &database->mapUserMemory;
  119515. + break;
  119516. +
  119517. + case gcvDB_VIDEO_MEMORY_RESERVED:
  119518. + count = &database->vidMemResv;
  119519. + break;
  119520. +
  119521. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  119522. + count = &database->vidMemCont;
  119523. + break;
  119524. +
  119525. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  119526. + count = &database->vidMemVirt;
  119527. + break;
  119528. +
  119529. + default:
  119530. + count = gcvNULL;
  119531. + break;
  119532. + }
  119533. +
  119534. + if (count != gcvNULL)
  119535. + {
  119536. + /* Adjust counters. */
  119537. + count->totalBytes += Size;
  119538. + count->bytes += Size;
  119539. +
  119540. + if (count->bytes > count->maxBytes)
  119541. + {
  119542. + count->maxBytes = count->bytes;
  119543. + }
  119544. + }
  119545. +
  119546. + /* Success. */
  119547. + gcmkFOOTER_NO();
  119548. + return gcvSTATUS_OK;
  119549. +
  119550. +OnError:
  119551. + /* Return the status. */
  119552. + gcmkFOOTER();
  119553. + return status;
  119554. +}
  119555. +
  119556. +/*******************************************************************************
  119557. +** gckKERNEL_RemoveProcessDB
  119558. +**
  119559. +** Remove a record from a process database.
  119560. +**
  119561. +** INPUT:
  119562. +**
  119563. +** gckKERNEL Kernel
  119564. +** Pointer to a gckKERNEL object.
  119565. +**
  119566. +** gctUINT32 ProcessID
  119567. +** Process ID used to identify the database.
  119568. +**
  119569. +** gceDATABASE_TYPE TYPE
  119570. +** Type of the record to remove.
  119571. +**
  119572. +** gctPOINTER Pointer
  119573. +** Data of the record to remove.
  119574. +**
  119575. +** OUTPUT:
  119576. +**
  119577. +** Nothing.
  119578. +*/
  119579. +gceSTATUS
  119580. +gckKERNEL_RemoveProcessDB(
  119581. + IN gckKERNEL Kernel,
  119582. + IN gctUINT32 ProcessID,
  119583. + IN gceDATABASE_TYPE Type,
  119584. + IN gctPOINTER Pointer
  119585. + )
  119586. +{
  119587. + gceSTATUS status;
  119588. + gcsDATABASE_PTR database;
  119589. + gctSIZE_T bytes = 0;
  119590. +
  119591. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
  119592. + Kernel, ProcessID, Type, Pointer);
  119593. +
  119594. + /* Verify the arguments. */
  119595. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  119596. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  119597. +
  119598. + /* Find the database. */
  119599. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  119600. +
  119601. + /* Delete the record. */
  119602. + gcmkONERROR(
  119603. + gckKERNEL_DeleteRecord(Kernel, database, Type, Pointer, &bytes));
  119604. +
  119605. + /* Update counters. */
  119606. + switch (Type)
  119607. + {
  119608. + case gcvDB_VIDEO_MEMORY:
  119609. + database->vidMem.bytes -= bytes;
  119610. + break;
  119611. +
  119612. + case gcvDB_NON_PAGED:
  119613. + database->nonPaged.bytes -= bytes;
  119614. + break;
  119615. +
  119616. + case gcvDB_CONTIGUOUS:
  119617. + database->contiguous.bytes -= bytes;
  119618. + break;
  119619. +
  119620. + case gcvDB_MAP_MEMORY:
  119621. + database->mapMemory.bytes -= bytes;
  119622. + break;
  119623. +
  119624. + case gcvDB_MAP_USER_MEMORY:
  119625. + database->mapUserMemory.bytes -= bytes;
  119626. + break;
  119627. +
  119628. + case gcvDB_VIDEO_MEMORY_RESERVED:
  119629. + database->vidMemResv.bytes -= bytes;
  119630. + break;
  119631. +
  119632. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  119633. + database->vidMemCont.bytes -= bytes;
  119634. + break;
  119635. +
  119636. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  119637. + database->vidMemVirt.bytes -= bytes;
  119638. + break;
  119639. +
  119640. + default:
  119641. + break;
  119642. + }
  119643. +
  119644. + /* Success. */
  119645. + gcmkFOOTER_NO();
  119646. + return gcvSTATUS_OK;
  119647. +
  119648. +OnError:
  119649. + /* Return the status. */
  119650. + gcmkFOOTER();
  119651. + return status;
  119652. +}
  119653. +
  119654. +/*******************************************************************************
  119655. +** gckKERNEL_FindProcessDB
  119656. +**
  119657. +** Find a record from a process database.
  119658. +**
  119659. +** INPUT:
  119660. +**
  119661. +** gckKERNEL Kernel
  119662. +** Pointer to a gckKERNEL object.
  119663. +**
  119664. +** gctUINT32 ProcessID
  119665. +** Process ID used to identify the database.
  119666. +**
  119667. +** gceDATABASE_TYPE TYPE
  119668. +** Type of the record to remove.
  119669. +**
  119670. +** gctPOINTER Pointer
  119671. +** Data of the record to remove.
  119672. +**
  119673. +** OUTPUT:
  119674. +**
  119675. +** gcsDATABASE_RECORD_PTR Record
  119676. +** Copy of record.
  119677. +*/
  119678. +gceSTATUS
  119679. +gckKERNEL_FindProcessDB(
  119680. + IN gckKERNEL Kernel,
  119681. + IN gctUINT32 ProcessID,
  119682. + IN gctUINT32 ThreadID,
  119683. + IN gceDATABASE_TYPE Type,
  119684. + IN gctPOINTER Pointer,
  119685. + OUT gcsDATABASE_RECORD_PTR Record
  119686. + )
  119687. +{
  119688. + gceSTATUS status;
  119689. + gcsDATABASE_PTR database;
  119690. +
  119691. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
  119692. + Kernel, ProcessID, ThreadID, Type, Pointer);
  119693. +
  119694. + /* Verify the arguments. */
  119695. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  119696. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  119697. +
  119698. + /* Find the database. */
  119699. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  119700. +
  119701. + /* Find the record. */
  119702. + gcmkONERROR(
  119703. + gckKERNEL_FindRecord(Kernel, database, Type, Pointer, Record));
  119704. +
  119705. + /* Success. */
  119706. + gcmkFOOTER_NO();
  119707. + return gcvSTATUS_OK;
  119708. +
  119709. +OnError:
  119710. + /* Return the status. */
  119711. + gcmkFOOTER();
  119712. + return status;
  119713. +}
  119714. +
  119715. +/*******************************************************************************
  119716. +** gckKERNEL_DestroyProcessDB
  119717. +**
  119718. +** Destroy a process database. If the database contains any records, the data
  119719. +** inside those records will be deleted as well. This aids in the cleanup if
  119720. +** a process has died unexpectedly or has memory leaks.
  119721. +**
  119722. +** INPUT:
  119723. +**
  119724. +** gckKERNEL Kernel
  119725. +** Pointer to a gckKERNEL object.
  119726. +**
  119727. +** gctUINT32 ProcessID
  119728. +** Process ID used to identify the database.
  119729. +**
  119730. +** OUTPUT:
  119731. +**
  119732. +** Nothing.
  119733. +*/
  119734. +gceSTATUS
  119735. +gckKERNEL_DestroyProcessDB(
  119736. + IN gckKERNEL Kernel,
  119737. + IN gctUINT32 ProcessID
  119738. + )
  119739. +{
  119740. + gceSTATUS status;
  119741. + gcsDATABASE_PTR database;
  119742. + gcsDATABASE_RECORD_PTR record, next;
  119743. + gctBOOL asynchronous;
  119744. + gctPHYS_ADDR physical;
  119745. + gcuVIDMEM_NODE_PTR node;
  119746. + gckKERNEL kernel = Kernel;
  119747. + gctUINT32 i;
  119748. +
  119749. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  119750. +
  119751. + /* Verify the arguments. */
  119752. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  119753. +
  119754. + /* Find the database. */
  119755. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  119756. +
  119757. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  119758. + "DB(%d): VidMem: total=%lu max=%lu",
  119759. + ProcessID, database->vidMem.totalBytes,
  119760. + database->vidMem.maxBytes);
  119761. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  119762. + "DB(%d): NonPaged: total=%lu max=%lu",
  119763. + ProcessID, database->nonPaged.totalBytes,
  119764. + database->nonPaged.maxBytes);
  119765. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  119766. + "DB(%d): Contiguous: total=%lu max=%lu",
  119767. + ProcessID, database->contiguous.totalBytes,
  119768. + database->contiguous.maxBytes);
  119769. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  119770. + "DB(%d): Idle time=%llu",
  119771. + ProcessID, Kernel->db->idleTime);
  119772. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  119773. + "DB(%d): Map: total=%lu max=%lu",
  119774. + ProcessID, database->mapMemory.totalBytes,
  119775. + database->mapMemory.maxBytes);
  119776. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
  119777. + "DB(%d): Map: total=%lu max=%lu",
  119778. + ProcessID, database->mapUserMemory.totalBytes,
  119779. + database->mapUserMemory.maxBytes);
  119780. +
  119781. + if (database->list != gcvNULL)
  119782. + {
  119783. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119784. + "Process %d has entries in its database:",
  119785. + ProcessID);
  119786. + }
  119787. +
  119788. + for(i = 0; i < gcmCOUNTOF(database->list); i++)
  119789. + {
  119790. +
  119791. + /* Walk all records. */
  119792. + for (record = database->list[i]; record != gcvNULL; record = next)
  119793. + {
  119794. + /* Next next record. */
  119795. + next = record->next;
  119796. +
  119797. + /* Dispatch on record type. */
  119798. + switch (record->type)
  119799. + {
  119800. + case gcvDB_VIDEO_MEMORY:
  119801. + /* Free the video memory. */
  119802. + status = gckVIDMEM_Free(gcmUINT64_TO_PTR(record->data));
  119803. +
  119804. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119805. + "DB: VIDEO_MEMORY 0x%x (status=%d)",
  119806. + record->data, status);
  119807. + break;
  119808. +
  119809. + case gcvDB_NON_PAGED:
  119810. + physical = gcmNAME_TO_PTR(record->physical);
  119811. + /* Unmap user logical memory first. */
  119812. + status = gckOS_UnmapUserLogical(Kernel->os,
  119813. + physical,
  119814. + record->bytes,
  119815. + record->data);
  119816. +
  119817. + /* Free the non paged memory. */
  119818. + status = gckOS_FreeNonPagedMemory(Kernel->os,
  119819. + record->bytes,
  119820. + physical,
  119821. + record->data);
  119822. + gcmRELEASE_NAME(record->physical);
  119823. +
  119824. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119825. + "DB: NON_PAGED 0x%x, bytes=%lu (status=%d)",
  119826. + record->data, record->bytes, status);
  119827. + break;
  119828. +
  119829. +#if gcdVIRTUAL_COMMAND_BUFFER
  119830. + case gcvDB_COMMAND_BUFFER:
  119831. + /* Free the command buffer. */
  119832. + status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
  119833. + record->bytes,
  119834. + gcmNAME_TO_PTR(record->physical),
  119835. + record->data,
  119836. + gcvKERNEL_PIXEL);
  119837. + gcmRELEASE_NAME(record->physical);
  119838. +
  119839. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119840. + "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
  119841. + record->data, record->bytes, status);
  119842. + break;
  119843. +#endif
  119844. +
  119845. + case gcvDB_CONTIGUOUS:
  119846. + physical = gcmNAME_TO_PTR(record->physical);
  119847. + /* Unmap user logical memory first. */
  119848. + status = gckOS_UnmapUserLogical(Kernel->os,
  119849. + physical,
  119850. + record->bytes,
  119851. + record->data);
  119852. +
  119853. + /* Free the contiguous memory. */
  119854. + status = gckEVENT_FreeContiguousMemory(Kernel->eventObj,
  119855. + record->bytes,
  119856. + physical,
  119857. + record->data,
  119858. + gcvKERNEL_PIXEL);
  119859. + gcmRELEASE_NAME(record->physical);
  119860. +
  119861. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119862. + "DB: CONTIGUOUS 0x%x bytes=%lu (status=%d)",
  119863. + record->data, record->bytes, status);
  119864. + break;
  119865. +
  119866. + case gcvDB_SIGNAL:
  119867. +#if USE_NEW_LINUX_SIGNAL
  119868. + status = gcvSTATUS_NOT_SUPPORTED;
  119869. +#else
  119870. + /* Free the user signal. */
  119871. + status = gckOS_DestroyUserSignal(Kernel->os,
  119872. + gcmPTR2INT(record->data));
  119873. +#endif /* USE_NEW_LINUX_SIGNAL */
  119874. +
  119875. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119876. + "DB: SIGNAL %d (status=%d)",
  119877. + (gctINT)(gctUINTPTR_T)record->data, status);
  119878. + break;
  119879. +
  119880. + case gcvDB_VIDEO_MEMORY_LOCKED:
  119881. + node = gcmUINT64_TO_PTR(record->data);
  119882. + /* Unlock what we still locked */
  119883. + status = gckVIDMEM_Unlock(record->kernel,
  119884. + node,
  119885. + gcvSURF_TYPE_UNKNOWN,
  119886. + &asynchronous);
  119887. +
  119888. + if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
  119889. + {
  119890. + /* TODO: we maybe need to schedule a event here */
  119891. + status = gckVIDMEM_Unlock(record->kernel,
  119892. + node,
  119893. + gcvSURF_TYPE_UNKNOWN,
  119894. + gcvNULL);
  119895. + }
  119896. +
  119897. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119898. + "DB: VIDEO_MEMORY_LOCKED 0x%x (status=%d)",
  119899. + node, status);
  119900. + break;
  119901. +
  119902. + case gcvDB_CONTEXT:
  119903. + /* TODO: Free the context */
  119904. + status = gckCOMMAND_Detach(Kernel->command, gcmNAME_TO_PTR(record->data));
  119905. + gcmRELEASE_NAME(record->data);
  119906. +
  119907. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119908. + "DB: CONTEXT 0x%x (status=%d)",
  119909. + record->data, status);
  119910. + break;
  119911. +
  119912. + case gcvDB_MAP_MEMORY:
  119913. + /* Unmap memory. */
  119914. + status = gckKERNEL_UnmapMemory(Kernel,
  119915. + record->physical,
  119916. + record->bytes,
  119917. + record->data);
  119918. +
  119919. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119920. + "DB: MAP MEMORY %d (status=%d)",
  119921. + gcmPTR2INT(record->data), status);
  119922. + break;
  119923. +
  119924. + case gcvDB_MAP_USER_MEMORY:
  119925. + /* TODO: Unmap user memory. */
  119926. + status = gckOS_UnmapUserMemory(Kernel->os,
  119927. + Kernel->core,
  119928. + record->physical,
  119929. + record->bytes,
  119930. + gcmNAME_TO_PTR(record->data),
  119931. + 0);
  119932. + gcmRELEASE_NAME(record->data);
  119933. +
  119934. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119935. + "DB: MAP USER MEMORY %d (status=%d)",
  119936. + gcmPTR2INT(record->data), status);
  119937. + break;
  119938. +
  119939. + case gcvDB_SHARED_INFO:
  119940. + status = gckOS_FreeMemory(Kernel->os, record->physical);
  119941. + break;
  119942. +
  119943. +#if gcdANDROID_NATIVE_FENCE_SYNC
  119944. + case gcvDB_SYNC_POINT:
  119945. + /* Free the user signal. */
  119946. + status = gckOS_DestroySyncPoint(Kernel->os,
  119947. + (gctSYNC_POINT) record->data);
  119948. +
  119949. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
  119950. + "DB: SYNC POINT %d (status=%d)",
  119951. + (gctINT)(gctUINTPTR_T)record->data, status);
  119952. + break;
  119953. +#endif
  119954. +
  119955. + case gcvDB_VIDEO_MEMORY_RESERVED:
  119956. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  119957. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  119958. + break;//Nothing to do
  119959. +
  119960. + default:
  119961. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DATABASE,
  119962. + "DB: Correcupted record=0x%08x type=%d",
  119963. + record, record->type);
  119964. + break;
  119965. + }
  119966. +
  119967. + /* Delete the record. */
  119968. + gcmkONERROR(gckKERNEL_DeleteRecord(Kernel,
  119969. + database,
  119970. + record->type,
  119971. + record->data,
  119972. + gcvNULL));
  119973. + }
  119974. +
  119975. + }
  119976. +
  119977. + /* Delete the database. */
  119978. + gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
  119979. +
  119980. + /* Success. */
  119981. + gcmkFOOTER_NO();
  119982. + return gcvSTATUS_OK;
  119983. +
  119984. +OnError:
  119985. + /* Return the status. */
  119986. + gcmkFOOTER();
  119987. + return status;
  119988. +}
  119989. +
  119990. +/*******************************************************************************
  119991. +** gckKERNEL_QueryProcessDB
  119992. +**
  119993. +** Query a process database for the current usage of a particular record type.
  119994. +**
  119995. +** INPUT:
  119996. +**
  119997. +** gckKERNEL Kernel
  119998. +** Pointer to a gckKERNEL object.
  119999. +**
  120000. +** gctUINT32 ProcessID
  120001. +** Process ID used to identify the database.
  120002. +**
  120003. +** gctBOOL LastProcessID
  120004. +** gcvTRUE if searching for the last known process ID. gcvFALSE if
  120005. +** we need to search for the process ID specified by the ProcessID
  120006. +** argument.
  120007. +**
  120008. +** gceDATABASE_TYPE Type
  120009. +** Type of the record to query.
  120010. +**
  120011. +** OUTPUT:
  120012. +**
  120013. +** gcuDATABASE_INFO * Info
  120014. +** Pointer to a variable that receives the requested information.
  120015. +*/
  120016. +gceSTATUS
  120017. +gckKERNEL_QueryProcessDB(
  120018. + IN gckKERNEL Kernel,
  120019. + IN gctUINT32 ProcessID,
  120020. + IN gctBOOL LastProcessID,
  120021. + IN gceDATABASE_TYPE Type,
  120022. + OUT gcuDATABASE_INFO * Info
  120023. + )
  120024. +{
  120025. + gceSTATUS status;
  120026. + gcsDATABASE_PTR database;
  120027. +
  120028. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
  120029. + Kernel, ProcessID, Type, Info);
  120030. +
  120031. + /* Verify the arguments. */
  120032. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  120033. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  120034. +
  120035. + /* Find the database. */
  120036. + gcmkONERROR(
  120037. + gckKERNEL_FindDatabase(Kernel, ProcessID, LastProcessID, &database));
  120038. +
  120039. + /* Get pointer to counters. */
  120040. + switch (Type)
  120041. + {
  120042. + case gcvDB_VIDEO_MEMORY:
  120043. + gckOS_MemCopy(&Info->counters,
  120044. + &database->vidMem,
  120045. + gcmSIZEOF(database->vidMem));
  120046. + break;
  120047. +
  120048. + case gcvDB_NON_PAGED:
  120049. + gckOS_MemCopy(&Info->counters,
  120050. + &database->nonPaged,
  120051. + gcmSIZEOF(database->vidMem));
  120052. + break;
  120053. +
  120054. + case gcvDB_CONTIGUOUS:
  120055. + gckOS_MemCopy(&Info->counters,
  120056. + &database->contiguous,
  120057. + gcmSIZEOF(database->vidMem));
  120058. + break;
  120059. +
  120060. + case gcvDB_IDLE:
  120061. + Info->time = Kernel->db->idleTime;
  120062. + Kernel->db->idleTime = 0;
  120063. + break;
  120064. +
  120065. + case gcvDB_MAP_MEMORY:
  120066. + gckOS_MemCopy(&Info->counters,
  120067. + &database->mapMemory,
  120068. + gcmSIZEOF(database->mapMemory));
  120069. + break;
  120070. +
  120071. + case gcvDB_MAP_USER_MEMORY:
  120072. + gckOS_MemCopy(&Info->counters,
  120073. + &database->mapUserMemory,
  120074. + gcmSIZEOF(database->mapUserMemory));
  120075. + break;
  120076. +
  120077. + case gcvDB_VIDEO_MEMORY_RESERVED:
  120078. + gckOS_MemCopy(&Info->counters,
  120079. + &database->vidMemResv,
  120080. + gcmSIZEOF(database->vidMemResv));
  120081. + break;
  120082. +
  120083. + case gcvDB_VIDEO_MEMORY_CONTIGUOUS:
  120084. + gckOS_MemCopy(&Info->counters,
  120085. + &database->vidMemCont,
  120086. + gcmSIZEOF(database->vidMemCont));
  120087. + break;
  120088. +
  120089. + case gcvDB_VIDEO_MEMORY_VIRTUAL:
  120090. + gckOS_MemCopy(&Info->counters,
  120091. + &database->vidMemVirt,
  120092. + gcmSIZEOF(database->vidMemVirt));
  120093. + break;
  120094. +
  120095. + default:
  120096. + break;
  120097. + }
  120098. +
  120099. + /* Success. */
  120100. + gcmkFOOTER_NO();
  120101. + return gcvSTATUS_OK;
  120102. +
  120103. +OnError:
  120104. + /* Return the status. */
  120105. + gcmkFOOTER();
  120106. + return status;
  120107. +}
  120108. +
  120109. +#if gcdSECURE_USER
  120110. +/*******************************************************************************
  120111. +** gckKERNEL_GetProcessDBCache
  120112. +**
  120113. +** Get teh secure cache from a process database.
  120114. +**
  120115. +** INPUT:
  120116. +**
  120117. +** gckKERNEL Kernel
  120118. +** Pointer to a gckKERNEL object.
  120119. +**
  120120. +** gctUINT32 ProcessID
  120121. +** Process ID used to identify the database.
  120122. +**
  120123. +** OUTPUT:
  120124. +**
  120125. +** gcskSECURE_CACHE_PTR * Cache
  120126. +** Pointer to a variable that receives the secure cache pointer.
  120127. +*/
  120128. +gceSTATUS
  120129. +gckKERNEL_GetProcessDBCache(
  120130. + IN gckKERNEL Kernel,
  120131. + IN gctUINT32 ProcessID,
  120132. + OUT gcskSECURE_CACHE_PTR * Cache
  120133. + )
  120134. +{
  120135. + gceSTATUS status;
  120136. + gcsDATABASE_PTR database;
  120137. +
  120138. + gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
  120139. +
  120140. + /* Verify the arguments. */
  120141. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  120142. + gcmkVERIFY_ARGUMENT(Cache != gcvNULL);
  120143. +
  120144. + /* Find the database. */
  120145. + gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
  120146. +
  120147. + /* Return the pointer to the cache. */
  120148. + *Cache = &database->cache;
  120149. +
  120150. + /* Success. */
  120151. + gcmkFOOTER_ARG("*Cache=0x%x", *Cache);
  120152. + return gcvSTATUS_OK;
  120153. +
  120154. +OnError:
  120155. + /* Return the status. */
  120156. + gcmkFOOTER();
  120157. + return status;
  120158. +}
  120159. +#endif
  120160. +
  120161. +gceSTATUS
  120162. +gckKERNEL_DumpProcessDB(
  120163. + IN gckKERNEL Kernel
  120164. + )
  120165. +{
  120166. + gcsDATABASE_PTR database;
  120167. + gctINT i, pid;
  120168. + gctUINT8 name[24];
  120169. +
  120170. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  120171. +
  120172. + /* Acquire the database mutex. */
  120173. + gcmkVERIFY_OK(
  120174. + gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
  120175. +
  120176. + gcmkPRINT("**************************\n");
  120177. + gcmkPRINT("*** PROCESS DB DUMP ***\n");
  120178. + gcmkPRINT("**************************\n");
  120179. +
  120180. + gcmkPRINT_N(8, "%-8s%s\n", "PID", "NAME");
  120181. + /* Walk the databases. */
  120182. + for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
  120183. + {
  120184. + for (database = Kernel->db->db[i];
  120185. + database != gcvNULL;
  120186. + database = database->next)
  120187. + {
  120188. + pid = database->processID;
  120189. +
  120190. + gcmkVERIFY_OK(gckOS_ZeroMemory(name, gcmSIZEOF(name)));
  120191. +
  120192. + gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
  120193. +
  120194. + gcmkPRINT_N(8, "%-8d%s\n", pid, name);
  120195. + }
  120196. + }
  120197. +
  120198. + /* Release the database mutex. */
  120199. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
  120200. +
  120201. + /* Success. */
  120202. + gcmkFOOTER_NO();
  120203. + return gcvSTATUS_OK;
  120204. +}
  120205. diff -Nur linux-3.14.17/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
  120206. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c 1970-01-01 01:00:00.000000000 +0100
  120207. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c 2014-09-11 18:06:03.086042307 +0200
  120208. @@ -0,0 +1,2559 @@
  120209. +/****************************************************************************
  120210. +*
  120211. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  120212. +*
  120213. +* This program is free software; you can redistribute it and/or modify
  120214. +* it under the terms of the GNU General Public License as published by
  120215. +* the Free Software Foundation; either version 2 of the license, or
  120216. +* (at your option) any later version.
  120217. +*
  120218. +* This program is distributed in the hope that it will be useful,
  120219. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  120220. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  120221. +* GNU General Public License for more details.
  120222. +*
  120223. +* You should have received a copy of the GNU General Public License
  120224. +* along with this program; if not write to the Free Software
  120225. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  120226. +*
  120227. +*****************************************************************************/
  120228. +
  120229. +
  120230. +#include "gc_hal_kernel_precomp.h"
  120231. +#include <gc_hal_kernel_debug.h>
  120232. +
  120233. +/******************************************************************************\
  120234. +******************************** Debug Variables *******************************
  120235. +\******************************************************************************/
  120236. +
  120237. +static gceSTATUS _lastError = gcvSTATUS_OK;
  120238. +static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
  120239. +/*
  120240. +_debugZones config value
  120241. +Please Reference define in gc_hal_base.h
  120242. +*/
  120243. +static gctUINT32 _debugZones = gcvZONE_NONE;
  120244. +
  120245. +/******************************************************************************\
  120246. +********************************* Debug Switches *******************************
  120247. +\******************************************************************************/
  120248. +
  120249. +/*
  120250. + gcdBUFFERED_OUTPUT
  120251. +
  120252. + When set to non-zero, all output is collected into a buffer with the
  120253. + specified size. Once the buffer gets full, the debug buffer will be
  120254. + printed to the console. gcdBUFFERED_SIZE determines the size of the buffer.
  120255. +*/
  120256. +#define gcdBUFFERED_OUTPUT 0
  120257. +
  120258. +/*
  120259. + gcdBUFFERED_SIZE
  120260. +
  120261. + When set to non-zero, all output is collected into a buffer with the
  120262. + specified size. Once the buffer gets full, the debug buffer will be
  120263. + printed to the console.
  120264. +*/
  120265. +#define gcdBUFFERED_SIZE (1024 * 1024 * 2)
  120266. +
  120267. +/*
  120268. + gcdDMA_BUFFER_COUNT
  120269. +
  120270. + If greater then zero, the debugger will attempt to find the command buffer
  120271. + where DMA is currently executing and then print this buffer and
  120272. + (gcdDMA_BUFFER_COUNT - 1) buffers before the current one. If set to zero
  120273. + or the current buffer is not found, all buffers are printed.
  120274. +*/
  120275. +#define gcdDMA_BUFFER_COUNT 0
  120276. +
  120277. +/*
  120278. + gcdTHREAD_BUFFERS
  120279. +
  120280. + When greater then one, will accumulate messages from the specified number
  120281. + of threads in separate output buffers.
  120282. +*/
  120283. +#define gcdTHREAD_BUFFERS 1
  120284. +
  120285. +/*
  120286. + gcdENABLE_OVERFLOW
  120287. +
  120288. + When set to non-zero, and the output buffer gets full, instead of being
  120289. + printed, it will be allowed to overflow removing the oldest messages.
  120290. +*/
  120291. +#define gcdENABLE_OVERFLOW 1
  120292. +
  120293. +/*
  120294. + gcdSHOW_LINE_NUMBER
  120295. +
  120296. + When enabledm each print statement will be preceeded with the current
  120297. + line number.
  120298. +*/
  120299. +#define gcdSHOW_LINE_NUMBER 0
  120300. +
  120301. +/*
  120302. + gcdSHOW_PROCESS_ID
  120303. +
  120304. + When enabledm each print statement will be preceeded with the current
  120305. + process ID.
  120306. +*/
  120307. +#define gcdSHOW_PROCESS_ID 0
  120308. +
  120309. +/*
  120310. + gcdSHOW_THREAD_ID
  120311. +
  120312. + When enabledm each print statement will be preceeded with the current
  120313. + thread ID.
  120314. +*/
  120315. +#define gcdSHOW_THREAD_ID 0
  120316. +
  120317. +/*
  120318. + gcdSHOW_TIME
  120319. +
  120320. + When enabled each print statement will be preceeded with the current
  120321. + high-resolution time.
  120322. +*/
  120323. +#define gcdSHOW_TIME 0
  120324. +
  120325. +
  120326. +/******************************************************************************\
  120327. +****************************** Miscellaneous Macros ****************************
  120328. +\******************************************************************************/
  120329. +
  120330. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  120331. +# define gcmDBGASSERT(Expression, Format, Value) \
  120332. + if (!(Expression)) \
  120333. + { \
  120334. + _DirectPrint( \
  120335. + "*** gcmDBGASSERT ***************************\n" \
  120336. + " function : %s\n" \
  120337. + " line : %d\n" \
  120338. + " expression : " #Expression "\n" \
  120339. + " actual value : " Format "\n", \
  120340. + __FUNCTION__, __LINE__, Value \
  120341. + ); \
  120342. + }
  120343. +#else
  120344. +# define gcmDBGASSERT(Expression, Format, Value)
  120345. +#endif
  120346. +
  120347. +#define gcmPTRALIGNMENT(Pointer, Alignemnt) \
  120348. +( \
  120349. + gcmALIGN(gcmPTR2INT(Pointer), Alignemnt) - gcmPTR2INT(Pointer) \
  120350. +)
  120351. +
  120352. +#if gcdALIGNBYSIZE
  120353. +# define gcmISALIGNED(Offset, Alignment) \
  120354. + (((Offset) & ((Alignment) - 1)) == 0)
  120355. +
  120356. +# define gcmkALIGNPTR(Type, Pointer, Alignment) \
  120357. + Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT(Pointer), Alignment))
  120358. +#else
  120359. +# define gcmISALIGNED(Offset, Alignment) \
  120360. + gcvTRUE
  120361. +
  120362. +# define gcmkALIGNPTR(Type, Pointer, Alignment)
  120363. +#endif
  120364. +
  120365. +#define gcmALIGNSIZE(Offset, Size) \
  120366. + ((Size - Offset) + Size)
  120367. +
  120368. +#define gcdHAVEPREFIX \
  120369. +( \
  120370. + gcdSHOW_TIME \
  120371. + || gcdSHOW_LINE_NUMBER \
  120372. + || gcdSHOW_PROCESS_ID \
  120373. + || gcdSHOW_THREAD_ID \
  120374. +)
  120375. +
  120376. +#if gcdHAVEPREFIX
  120377. +
  120378. +# define gcdOFFSET 0
  120379. +
  120380. +#if gcdSHOW_TIME
  120381. +#if gcmISALIGNED(gcdOFFSET, 8)
  120382. +# define gcdTIMESIZE gcmSIZEOF(gctUINT64)
  120383. +# elif gcdOFFSET == 4
  120384. +# define gcdTIMESIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
  120385. +# else
  120386. +# error "Unexpected offset value."
  120387. +# endif
  120388. +# undef gcdOFFSET
  120389. +# define gcdOFFSET 8
  120390. +#if !defined(gcdPREFIX_LEADER)
  120391. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
  120392. +# define gcdTIMEFORMAT "0x%016llX"
  120393. +# else
  120394. +# define gcdTIMEFORMAT ", 0x%016llX"
  120395. +# endif
  120396. +# else
  120397. +# define gcdTIMESIZE 0
  120398. +# define gcdTIMEFORMAT
  120399. +# endif
  120400. +
  120401. +#if gcdSHOW_LINE_NUMBER
  120402. +#if gcmISALIGNED(gcdOFFSET, 8)
  120403. +# define gcdNUMSIZE gcmSIZEOF(gctUINT64)
  120404. +# elif gcdOFFSET == 4
  120405. +# define gcdNUMSIZE gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
  120406. +# else
  120407. +# error "Unexpected offset value."
  120408. +# endif
  120409. +# undef gcdOFFSET
  120410. +# define gcdOFFSET 8
  120411. +#if !defined(gcdPREFIX_LEADER)
  120412. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT64)
  120413. +# define gcdNUMFORMAT "%8llu"
  120414. +# else
  120415. +# define gcdNUMFORMAT ", %8llu"
  120416. +# endif
  120417. +# else
  120418. +# define gcdNUMSIZE 0
  120419. +# define gcdNUMFORMAT
  120420. +# endif
  120421. +
  120422. +#if gcdSHOW_PROCESS_ID
  120423. +#if gcmISALIGNED(gcdOFFSET, 4)
  120424. +# define gcdPIDSIZE gcmSIZEOF(gctUINT32)
  120425. +# else
  120426. +# error "Unexpected offset value."
  120427. +# endif
  120428. +# undef gcdOFFSET
  120429. +# define gcdOFFSET 4
  120430. +#if !defined(gcdPREFIX_LEADER)
  120431. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  120432. +# define gcdPIDFORMAT "pid=%5d"
  120433. +# else
  120434. +# define gcdPIDFORMAT ", pid=%5d"
  120435. +# endif
  120436. +# else
  120437. +# define gcdPIDSIZE 0
  120438. +# define gcdPIDFORMAT
  120439. +# endif
  120440. +
  120441. +#if gcdSHOW_THREAD_ID
  120442. +#if gcmISALIGNED(gcdOFFSET, 4)
  120443. +# define gcdTIDSIZE gcmSIZEOF(gctUINT32)
  120444. +# else
  120445. +# error "Unexpected offset value."
  120446. +# endif
  120447. +# undef gcdOFFSET
  120448. +# define gcdOFFSET 4
  120449. +#if !defined(gcdPREFIX_LEADER)
  120450. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  120451. +# define gcdTIDFORMAT "tid=%5d"
  120452. +# else
  120453. +# define gcdTIDFORMAT ", tid=%5d"
  120454. +# endif
  120455. +# else
  120456. +# define gcdTIDSIZE 0
  120457. +# define gcdTIDFORMAT
  120458. +# endif
  120459. +
  120460. +# define gcdPREFIX_SIZE \
  120461. + ( \
  120462. + gcdTIMESIZE \
  120463. + + gcdNUMSIZE \
  120464. + + gcdPIDSIZE \
  120465. + + gcdTIDSIZE \
  120466. + )
  120467. +
  120468. + static const char * _prefixFormat =
  120469. + "["
  120470. + gcdTIMEFORMAT
  120471. + gcdNUMFORMAT
  120472. + gcdPIDFORMAT
  120473. + gcdTIDFORMAT
  120474. + "] ";
  120475. +
  120476. +#else
  120477. +
  120478. +# define gcdPREFIX_LEADER gcmSIZEOF(gctUINT32)
  120479. +# define gcdPREFIX_SIZE 0
  120480. +
  120481. +#endif
  120482. +
  120483. +/* Assumed largest variable argument leader size. */
  120484. +#define gcdVARARG_LEADER gcmSIZEOF(gctUINT64)
  120485. +
  120486. +/* Alignnments. */
  120487. +#if gcdALIGNBYSIZE
  120488. +# define gcdPREFIX_ALIGNMENT gcdPREFIX_LEADER
  120489. +# define gcdVARARG_ALIGNMENT gcdVARARG_LEADER
  120490. +#else
  120491. +# define gcdPREFIX_ALIGNMENT 0
  120492. +# define gcdVARARG_ALIGNMENT 0
  120493. +#endif
  120494. +
  120495. +#if gcdBUFFERED_OUTPUT
  120496. +# define gcdOUTPUTPREFIX _AppendPrefix
  120497. +# define gcdOUTPUTSTRING _AppendString
  120498. +# define gcdOUTPUTCOPY _AppendCopy
  120499. +# define gcdOUTPUTBUFFER _AppendBuffer
  120500. +#else
  120501. +# define gcdOUTPUTPREFIX _PrintPrefix
  120502. +# define gcdOUTPUTSTRING _PrintString
  120503. +# define gcdOUTPUTCOPY _PrintString
  120504. +# define gcdOUTPUTBUFFER _PrintBuffer
  120505. +#endif
  120506. +
  120507. +/******************************************************************************\
  120508. +****************************** Private Structures ******************************
  120509. +\******************************************************************************/
  120510. +
  120511. +typedef enum _gceBUFITEM
  120512. +{
  120513. + gceBUFITEM_NONE,
  120514. + gcvBUFITEM_PREFIX,
  120515. + gcvBUFITEM_STRING,
  120516. + gcvBUFITEM_COPY,
  120517. + gcvBUFITEM_BUFFER
  120518. +}
  120519. +gceBUFITEM;
  120520. +
  120521. +/* Common item head/buffer terminator. */
  120522. +typedef struct _gcsBUFITEM_HEAD * gcsBUFITEM_HEAD_PTR;
  120523. +typedef struct _gcsBUFITEM_HEAD
  120524. +{
  120525. + gceBUFITEM type;
  120526. +}
  120527. +gcsBUFITEM_HEAD;
  120528. +
  120529. +/* String prefix (for ex. [ 1,tid=0x019A]) */
  120530. +typedef struct _gcsBUFITEM_PREFIX * gcsBUFITEM_PREFIX_PTR;
  120531. +typedef struct _gcsBUFITEM_PREFIX
  120532. +{
  120533. + gceBUFITEM type;
  120534. +#if gcdHAVEPREFIX
  120535. + gctPOINTER prefixData;
  120536. +#endif
  120537. +}
  120538. +gcsBUFITEM_PREFIX;
  120539. +
  120540. +/* Buffered string. */
  120541. +typedef struct _gcsBUFITEM_STRING * gcsBUFITEM_STRING_PTR;
  120542. +typedef struct _gcsBUFITEM_STRING
  120543. +{
  120544. + gceBUFITEM type;
  120545. + gctINT indent;
  120546. + gctCONST_STRING message;
  120547. + gctPOINTER messageData;
  120548. + gctUINT messageDataSize;
  120549. +}
  120550. +gcsBUFITEM_STRING;
  120551. +
  120552. +/* Buffered string (copy of the string is included with the record). */
  120553. +typedef struct _gcsBUFITEM_COPY * gcsBUFITEM_COPY_PTR;
  120554. +typedef struct _gcsBUFITEM_COPY
  120555. +{
  120556. + gceBUFITEM type;
  120557. + gctINT indent;
  120558. + gctPOINTER messageData;
  120559. + gctUINT messageDataSize;
  120560. +}
  120561. +gcsBUFITEM_COPY;
  120562. +
  120563. +/* Memory buffer. */
  120564. +typedef struct _gcsBUFITEM_BUFFER * gcsBUFITEM_BUFFER_PTR;
  120565. +typedef struct _gcsBUFITEM_BUFFER
  120566. +{
  120567. + gceBUFITEM type;
  120568. + gctINT indent;
  120569. + gceDUMP_BUFFER bufferType;
  120570. +
  120571. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  120572. + gctUINT32 dmaAddress;
  120573. +#endif
  120574. +
  120575. + gctUINT dataSize;
  120576. + gctUINT32 address;
  120577. +#if gcdHAVEPREFIX
  120578. + gctPOINTER prefixData;
  120579. +#endif
  120580. +}
  120581. +gcsBUFITEM_BUFFER;
  120582. +
  120583. +typedef struct _gcsBUFFERED_OUTPUT * gcsBUFFERED_OUTPUT_PTR;
  120584. +typedef struct _gcsBUFFERED_OUTPUT
  120585. +{
  120586. +#if gcdTHREAD_BUFFERS > 1
  120587. + gctUINT32 threadID;
  120588. +#endif
  120589. +
  120590. +#if gcdSHOW_LINE_NUMBER
  120591. + gctUINT64 lineNumber;
  120592. +#endif
  120593. +
  120594. + gctINT indent;
  120595. +
  120596. +#if gcdBUFFERED_OUTPUT
  120597. + gctINT start;
  120598. + gctINT index;
  120599. + gctINT count;
  120600. + gctUINT8 buffer[gcdBUFFERED_SIZE];
  120601. +#endif
  120602. +
  120603. + gcsBUFFERED_OUTPUT_PTR prev;
  120604. + gcsBUFFERED_OUTPUT_PTR next;
  120605. +}
  120606. +gcsBUFFERED_OUTPUT;
  120607. +
  120608. +typedef gctUINT (* gcfPRINTSTRING) (
  120609. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  120610. + IN gcsBUFITEM_HEAD_PTR Item
  120611. + );
  120612. +
  120613. +typedef gctINT (* gcfGETITEMSIZE) (
  120614. + IN gcsBUFITEM_HEAD_PTR Item
  120615. + );
  120616. +
  120617. +/******************************************************************************\
  120618. +******************************* Private Variables ******************************
  120619. +\******************************************************************************/
  120620. +
  120621. +static gcsBUFFERED_OUTPUT _outputBuffer[gcdTHREAD_BUFFERS];
  120622. +static gcsBUFFERED_OUTPUT_PTR _outputBufferHead = gcvNULL;
  120623. +static gcsBUFFERED_OUTPUT_PTR _outputBufferTail = gcvNULL;
  120624. +
  120625. +/******************************************************************************\
  120626. +****************************** Item Size Functions *****************************
  120627. +\******************************************************************************/
  120628. +
  120629. +#if gcdBUFFERED_OUTPUT
  120630. +static gctINT
  120631. +_GetTerminatorItemSize(
  120632. + IN gcsBUFITEM_HEAD_PTR Item
  120633. + )
  120634. +{
  120635. + return gcmSIZEOF(gcsBUFITEM_HEAD);
  120636. +}
  120637. +
  120638. +static gctINT
  120639. +_GetPrefixItemSize(
  120640. + IN gcsBUFITEM_HEAD_PTR Item
  120641. + )
  120642. +{
  120643. +#if gcdHAVEPREFIX
  120644. + gcsBUFITEM_PREFIX_PTR item = (gcsBUFITEM_PREFIX_PTR) Item;
  120645. + gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  120646. + return vlen + gcdPREFIX_SIZE;
  120647. +#else
  120648. + return gcmSIZEOF(gcsBUFITEM_PREFIX);
  120649. +#endif
  120650. +}
  120651. +
  120652. +static gctINT
  120653. +_GetStringItemSize(
  120654. + IN gcsBUFITEM_HEAD_PTR Item
  120655. + )
  120656. +{
  120657. + gcsBUFITEM_STRING_PTR item = (gcsBUFITEM_STRING_PTR) Item;
  120658. + gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  120659. + return vlen + item->messageDataSize;
  120660. +}
  120661. +
  120662. +static gctINT
  120663. +_GetCopyItemSize(
  120664. + IN gcsBUFITEM_HEAD_PTR Item
  120665. + )
  120666. +{
  120667. + gcsBUFITEM_COPY_PTR item = (gcsBUFITEM_COPY_PTR) Item;
  120668. + gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  120669. + return vlen + item->messageDataSize;
  120670. +}
  120671. +
  120672. +static gctINT
  120673. +_GetBufferItemSize(
  120674. + IN gcsBUFITEM_HEAD_PTR Item
  120675. + )
  120676. +{
  120677. +#if gcdHAVEPREFIX
  120678. + gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
  120679. + gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  120680. + return vlen + gcdPREFIX_SIZE + item->dataSize;
  120681. +#else
  120682. + gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
  120683. + return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
  120684. +#endif
  120685. +}
  120686. +
  120687. +static gcfGETITEMSIZE _itemSize[] =
  120688. +{
  120689. + _GetTerminatorItemSize,
  120690. + _GetPrefixItemSize,
  120691. + _GetStringItemSize,
  120692. + _GetCopyItemSize,
  120693. + _GetBufferItemSize
  120694. +};
  120695. +#endif
  120696. +
  120697. +/******************************************************************************\
  120698. +******************************* Printing Functions *****************************
  120699. +\******************************************************************************/
  120700. +
  120701. +#if gcdDEBUG || gcdBUFFERED_OUTPUT
  120702. +static void
  120703. +_DirectPrint(
  120704. + gctCONST_STRING Message,
  120705. + ...
  120706. + )
  120707. +{
  120708. + gctINT len;
  120709. + char buffer[768];
  120710. + gctARGUMENTS arguments;
  120711. +
  120712. + gcmkARGUMENTS_START(arguments, Message);
  120713. + len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, arguments);
  120714. + gcmkARGUMENTS_END(arguments);
  120715. +
  120716. + buffer[len] = '\0';
  120717. + gcmkOUTPUT_STRING(buffer);
  120718. +}
  120719. +#endif
  120720. +
  120721. +static int
  120722. +_AppendIndent(
  120723. + IN gctINT Indent,
  120724. + IN char * Buffer,
  120725. + IN int BufferSize
  120726. + )
  120727. +{
  120728. + gctINT i;
  120729. +
  120730. + gctINT len = 0;
  120731. + gctINT indent = Indent % 40;
  120732. +
  120733. + for (i = 0; i < indent; i += 1)
  120734. + {
  120735. + Buffer[len++] = ' ';
  120736. + }
  120737. +
  120738. + if (indent != Indent)
  120739. + {
  120740. + len += gcmkSPRINTF(
  120741. + Buffer + len, BufferSize - len, " <%d> ", Indent
  120742. + );
  120743. +
  120744. + Buffer[len] = '\0';
  120745. + }
  120746. +
  120747. + return len;
  120748. +}
  120749. +
  120750. +#if gcdHAVEPREFIX
  120751. +static void
  120752. +_PrintPrefix(
  120753. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  120754. + IN gctPOINTER Data
  120755. + )
  120756. +{
  120757. + char buffer[768];
  120758. + gctINT len;
  120759. +
  120760. + /* Format the string. */
  120761. + len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, Data);
  120762. + buffer[len] = '\0';
  120763. +
  120764. + /* Print the string. */
  120765. + gcmkOUTPUT_STRING(buffer);
  120766. +}
  120767. +#endif
  120768. +
  120769. +static void
  120770. +_PrintString(
  120771. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  120772. + IN gctINT Indent,
  120773. + IN gctCONST_STRING Message,
  120774. + IN gctUINT ArgumentSize,
  120775. + IN gctPOINTER Data
  120776. + )
  120777. +{
  120778. + char buffer[768];
  120779. + gctINT len;
  120780. +
  120781. + /* Append the indent string. */
  120782. + len = _AppendIndent(Indent, buffer, gcmSIZEOF(buffer));
  120783. +
  120784. + /* Format the string. */
  120785. + len += gcmkVSPRINTF(buffer + len, gcmSIZEOF(buffer) - len, Message, Data);
  120786. + buffer[len] = '\0';
  120787. +
  120788. + /* Add end-of-line if missing. */
  120789. + if (buffer[len - 1] != '\n')
  120790. + {
  120791. + buffer[len++] = '\n';
  120792. + buffer[len] = '\0';
  120793. + }
  120794. +
  120795. + /* Print the string. */
  120796. + gcmkOUTPUT_STRING(buffer);
  120797. +}
  120798. +
  120799. +static void
  120800. +_PrintBuffer(
  120801. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  120802. + IN gctINT Indent,
  120803. + IN gctPOINTER PrefixData,
  120804. + IN gctPOINTER Data,
  120805. + IN gctUINT Address,
  120806. + IN gctUINT DataSize,
  120807. + IN gceDUMP_BUFFER Type,
  120808. + IN gctUINT32 DmaAddress
  120809. + )
  120810. +{
  120811. + static gctCONST_STRING _titleString[] =
  120812. + {
  120813. + "CONTEXT BUFFER",
  120814. + "USER COMMAND BUFFER",
  120815. + "KERNEL COMMAND BUFFER",
  120816. + "LINK BUFFER",
  120817. + "WAIT LINK BUFFER",
  120818. + ""
  120819. + };
  120820. +
  120821. + static const gctINT COLUMN_COUNT = 8;
  120822. +
  120823. + gctUINT i, count, column, address;
  120824. + gctUINT32_PTR data;
  120825. + gctCHAR buffer[768];
  120826. + gctUINT indent, len;
  120827. + gctBOOL command;
  120828. +
  120829. + /* Append space for the prefix. */
  120830. +#if gcdHAVEPREFIX
  120831. + indent = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, PrefixData);
  120832. + buffer[indent] = '\0';
  120833. +#else
  120834. + indent = 0;
  120835. +#endif
  120836. +
  120837. + /* Append the indent string. */
  120838. + indent += _AppendIndent(
  120839. + Indent, buffer + indent, gcmSIZEOF(buffer) - indent
  120840. + );
  120841. +
  120842. + switch (Type)
  120843. + {
  120844. + case gceDUMP_BUFFER_CONTEXT:
  120845. + case gceDUMP_BUFFER_USER:
  120846. + case gceDUMP_BUFFER_KERNEL:
  120847. + case gceDUMP_BUFFER_LINK:
  120848. + case gceDUMP_BUFFER_WAITLINK:
  120849. + /* Form and print the title string. */
  120850. + gcmkSPRINTF2(
  120851. + buffer + indent, gcmSIZEOF(buffer) - indent,
  120852. + "%s%s\n", _titleString[Type],
  120853. + ((DmaAddress >= Address) && (DmaAddress < Address + DataSize))
  120854. + ? " (CURRENT)" : ""
  120855. + );
  120856. +
  120857. + gcmkOUTPUT_STRING(buffer);
  120858. +
  120859. + /* Terminate the string. */
  120860. + buffer[indent] = '\0';
  120861. +
  120862. + /* This is a command buffer. */
  120863. + command = gcvTRUE;
  120864. + break;
  120865. +
  120866. + case gceDUMP_BUFFER_FROM_USER:
  120867. + /* This is not a command buffer. */
  120868. + command = gcvFALSE;
  120869. +
  120870. + /* No title. */
  120871. + break;
  120872. +
  120873. + default:
  120874. + gcmDBGASSERT(gcvFALSE, "%s", "invalid buffer type");
  120875. +
  120876. + /* This is not a command buffer. */
  120877. + command = gcvFALSE;
  120878. + }
  120879. +
  120880. + /* Overwrite the prefix with spaces. */
  120881. + for (i = 0; i < indent; i += 1)
  120882. + {
  120883. + buffer[i] = ' ';
  120884. + }
  120885. +
  120886. + /* Form and print the opening string. */
  120887. + if (command)
  120888. + {
  120889. + gcmkSPRINTF2(
  120890. + buffer + indent, gcmSIZEOF(buffer) - indent,
  120891. + "@[kernel.command %08X %08X\n", Address, DataSize
  120892. + );
  120893. +
  120894. + gcmkOUTPUT_STRING(buffer);
  120895. +
  120896. + /* Terminate the string. */
  120897. + buffer[indent] = '\0';
  120898. + }
  120899. +
  120900. + /* Get initial address. */
  120901. + address = Address;
  120902. +
  120903. + /* Cast the data pointer. */
  120904. + data = (gctUINT32_PTR) Data;
  120905. +
  120906. + /* Compute the number of double words. */
  120907. + count = DataSize / gcmSIZEOF(gctUINT32);
  120908. +
  120909. + /* Print the buffer. */
  120910. + for (i = 0, len = indent, column = 0; i < count; i += 1)
  120911. + {
  120912. + /* Append the address. */
  120913. + if (column == 0)
  120914. + {
  120915. + len += gcmkSPRINTF(
  120916. + buffer + len, gcmSIZEOF(buffer) - len, "0x%08X:", address
  120917. + );
  120918. + }
  120919. +
  120920. + /* Append the data value. */
  120921. + len += gcmkSPRINTF2(
  120922. + buffer + len, gcmSIZEOF(buffer) - len, "%c%08X",
  120923. + (address == DmaAddress)? '>' : ' ', data[i]
  120924. + );
  120925. +
  120926. + buffer[len] = '\0';
  120927. +
  120928. + /* Update the address. */
  120929. + address += gcmSIZEOF(gctUINT32);
  120930. +
  120931. + /* Advance column count. */
  120932. + column += 1;
  120933. +
  120934. + /* End of line? */
  120935. + if ((column % COLUMN_COUNT) == 0)
  120936. + {
  120937. + /* Append EOL. */
  120938. + gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
  120939. +
  120940. + /* Print the string. */
  120941. + gcmkOUTPUT_STRING(buffer);
  120942. +
  120943. + /* Reset. */
  120944. + len = indent;
  120945. + column = 0;
  120946. + }
  120947. + }
  120948. +
  120949. + /* Print the last partial string. */
  120950. + if (column != 0)
  120951. + {
  120952. + /* Append EOL. */
  120953. + gcmkSTRCAT(buffer + len, gcmSIZEOF(buffer) - len, "\n");
  120954. +
  120955. + /* Print the string. */
  120956. + gcmkOUTPUT_STRING(buffer);
  120957. + }
  120958. +
  120959. + /* Form and print the opening string. */
  120960. + if (command)
  120961. + {
  120962. + buffer[indent] = '\0';
  120963. + gcmkSTRCAT(buffer, gcmSIZEOF(buffer), "] -- command\n");
  120964. + gcmkOUTPUT_STRING(buffer);
  120965. + }
  120966. +}
  120967. +
  120968. +#if gcdBUFFERED_OUTPUT
  120969. +static gctUINT
  120970. +_PrintNone(
  120971. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  120972. + IN gcsBUFITEM_HEAD_PTR Item
  120973. + )
  120974. +{
  120975. + /* Return the size of the node. */
  120976. + return gcmSIZEOF(gcsBUFITEM_HEAD);
  120977. +}
  120978. +
  120979. +static gctUINT
  120980. +_PrintPrefixWrapper(
  120981. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  120982. + IN gcsBUFITEM_HEAD_PTR Item
  120983. + )
  120984. +{
  120985. +#if gcdHAVEPREFIX
  120986. + gcsBUFITEM_PREFIX_PTR item;
  120987. + gctUINT vlen;
  120988. +
  120989. + /* Get access to the data. */
  120990. + item = (gcsBUFITEM_PREFIX_PTR) Item;
  120991. +
  120992. + /* Print the message. */
  120993. + _PrintPrefix(OutputBuffer, item->prefixData);
  120994. +
  120995. + /* Compute the size of the variable portion of the structure. */
  120996. + vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  120997. +
  120998. + /* Return the size of the node. */
  120999. + return vlen + gcdPREFIX_SIZE;
  121000. +#else
  121001. + return gcmSIZEOF(gcsBUFITEM_PREFIX);
  121002. +#endif
  121003. +}
  121004. +
  121005. +static gctUINT
  121006. +_PrintStringWrapper(
  121007. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121008. + IN gcsBUFITEM_HEAD_PTR Item
  121009. + )
  121010. +{
  121011. + gcsBUFITEM_STRING_PTR item;
  121012. + gctUINT vlen;
  121013. +
  121014. + /* Get access to the data. */
  121015. + item = (gcsBUFITEM_STRING_PTR) Item;
  121016. +
  121017. + /* Print the message. */
  121018. + _PrintString(
  121019. + OutputBuffer,
  121020. + item->indent, item->message, item->messageDataSize, item->messageData
  121021. + );
  121022. +
  121023. + /* Compute the size of the variable portion of the structure. */
  121024. + vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  121025. +
  121026. + /* Return the size of the node. */
  121027. + return vlen + item->messageDataSize;
  121028. +}
  121029. +
  121030. +static gctUINT
  121031. +_PrintCopyWrapper(
  121032. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121033. + IN gcsBUFITEM_HEAD_PTR Item
  121034. + )
  121035. +{
  121036. + gcsBUFITEM_COPY_PTR item;
  121037. + gctCONST_STRING message;
  121038. + gctUINT vlen;
  121039. +
  121040. + /* Get access to the data. */
  121041. + item = (gcsBUFITEM_COPY_PTR) Item;
  121042. +
  121043. + /* Determine the string pointer. */
  121044. + message = (gctCONST_STRING) (item + 1);
  121045. +
  121046. + /* Print the message. */
  121047. + _PrintString(
  121048. + OutputBuffer,
  121049. + item->indent, message, item->messageDataSize, item->messageData
  121050. + );
  121051. +
  121052. + /* Compute the size of the variable portion of the structure. */
  121053. + vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
  121054. +
  121055. + /* Return the size of the node. */
  121056. + return vlen + item->messageDataSize;
  121057. +}
  121058. +
  121059. +static gctUINT
  121060. +_PrintBufferWrapper(
  121061. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121062. + IN gcsBUFITEM_HEAD_PTR Item
  121063. + )
  121064. +{
  121065. +#if gcdHAVEPREFIX
  121066. + gctUINT32 dmaAddress;
  121067. + gcsBUFITEM_BUFFER_PTR item;
  121068. + gctPOINTER data;
  121069. + gctUINT vlen;
  121070. +
  121071. + /* Get access to the data. */
  121072. + item = (gcsBUFITEM_BUFFER_PTR) Item;
  121073. +
  121074. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  121075. + dmaAddress = item->dmaAddress;
  121076. +#else
  121077. + dmaAddress = 0xFFFFFFFF;
  121078. +#endif
  121079. +
  121080. + if (dmaAddress != 0)
  121081. + {
  121082. + /* Compute the data address. */
  121083. + data = ((gctUINT8_PTR) item->prefixData) + gcdPREFIX_SIZE;
  121084. +
  121085. + /* Print buffer. */
  121086. + _PrintBuffer(
  121087. + OutputBuffer,
  121088. + item->indent, item->prefixData,
  121089. + data, item->address, item->dataSize,
  121090. + item->bufferType, dmaAddress
  121091. + );
  121092. + }
  121093. +
  121094. + /* Compute the size of the variable portion of the structure. */
  121095. + vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
  121096. +
  121097. + /* Return the size of the node. */
  121098. + return vlen + gcdPREFIX_SIZE + item->dataSize;
  121099. +#else
  121100. + gctUINT32 dmaAddress;
  121101. + gcsBUFITEM_BUFFER_PTR item;
  121102. +
  121103. + /* Get access to the data. */
  121104. + item = (gcsBUFITEM_BUFFER_PTR) Item;
  121105. +
  121106. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  121107. + dmaAddress = item->dmaAddress;
  121108. +#else
  121109. + dmaAddress = 0xFFFFFFFF;
  121110. +#endif
  121111. +
  121112. + if (dmaAddress != 0)
  121113. + {
  121114. + /* Print buffer. */
  121115. + _PrintBuffer(
  121116. + OutputBuffer,
  121117. + item->indent, gcvNULL,
  121118. + item + 1, item->address, item->dataSize,
  121119. + item->bufferType, dmaAddress
  121120. + );
  121121. + }
  121122. +
  121123. + /* Return the size of the node. */
  121124. + return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
  121125. +#endif
  121126. +}
  121127. +
  121128. +static gcfPRINTSTRING _printArray[] =
  121129. +{
  121130. + _PrintNone,
  121131. + _PrintPrefixWrapper,
  121132. + _PrintStringWrapper,
  121133. + _PrintCopyWrapper,
  121134. + _PrintBufferWrapper
  121135. +};
  121136. +#endif
  121137. +
  121138. +/******************************************************************************\
  121139. +******************************* Private Functions ******************************
  121140. +\******************************************************************************/
  121141. +
  121142. +#if gcdBUFFERED_OUTPUT
  121143. +
  121144. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  121145. +static gcsBUFITEM_BUFFER_PTR
  121146. +_FindCurrentDMABuffer(
  121147. + gctUINT32 DmaAddress
  121148. + )
  121149. +{
  121150. + gctINT i, skip;
  121151. + gcsBUFITEM_HEAD_PTR item;
  121152. + gcsBUFITEM_BUFFER_PTR dmaCurrent;
  121153. +
  121154. + /* Reset the current buffer. */
  121155. + dmaCurrent = gcvNULL;
  121156. +
  121157. + /* Get the first stored item. */
  121158. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  121159. +
  121160. + /* Run through all items. */
  121161. + for (i = 0; i < _outputBufferHead->count; i += 1)
  121162. + {
  121163. + /* Buffer item? */
  121164. + if (item->type == gcvBUFITEM_BUFFER)
  121165. + {
  121166. + gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
  121167. +
  121168. + if ((DmaAddress >= buffer->address) &&
  121169. + (DmaAddress < buffer->address + buffer->dataSize))
  121170. + {
  121171. + dmaCurrent = buffer;
  121172. + }
  121173. + }
  121174. +
  121175. + /* Get the item size and skip it. */
  121176. + skip = (* _itemSize[item->type]) (item);
  121177. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  121178. +
  121179. + /* End of the buffer? Wrap around. */
  121180. + if (item->type == gceBUFITEM_NONE)
  121181. + {
  121182. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  121183. + }
  121184. + }
  121185. +
  121186. + /* Return result. */
  121187. + return dmaCurrent;
  121188. +}
  121189. +
  121190. +static void
  121191. +_EnableAllDMABuffers(
  121192. + void
  121193. + )
  121194. +{
  121195. + gctINT i, skip;
  121196. + gcsBUFITEM_HEAD_PTR item;
  121197. +
  121198. + /* Get the first stored item. */
  121199. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  121200. +
  121201. + /* Run through all items. */
  121202. + for (i = 0; i < _outputBufferHead->count; i += 1)
  121203. + {
  121204. + /* Buffer item? */
  121205. + if (item->type == gcvBUFITEM_BUFFER)
  121206. + {
  121207. + gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
  121208. +
  121209. + /* Enable the buffer. */
  121210. + buffer->dmaAddress = ~0U;
  121211. + }
  121212. +
  121213. + /* Get the item size and skip it. */
  121214. + skip = (* _itemSize[item->type]) (item);
  121215. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  121216. +
  121217. + /* End of the buffer? Wrap around. */
  121218. + if (item->type == gceBUFITEM_NONE)
  121219. + {
  121220. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  121221. + }
  121222. + }
  121223. +}
  121224. +
  121225. +static void
  121226. +_EnableDMABuffers(
  121227. + gctUINT32 DmaAddress,
  121228. + gcsBUFITEM_BUFFER_PTR CurrentDMABuffer
  121229. + )
  121230. +{
  121231. + gctINT i, skip, index;
  121232. + gcsBUFITEM_HEAD_PTR item;
  121233. + gcsBUFITEM_BUFFER_PTR buffers[gcdDMA_BUFFER_COUNT];
  121234. +
  121235. + /* Reset buffer pointers. */
  121236. + gckOS_ZeroMemory(buffers, gcmSIZEOF(buffers));
  121237. +
  121238. + /* Set the current buffer index. */
  121239. + index = -1;
  121240. +
  121241. + /* Get the first stored item. */
  121242. + item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
  121243. +
  121244. + /* Run through all items until the current DMA buffer is found. */
  121245. + for (i = 0; i < _outputBufferHead->count; i += 1)
  121246. + {
  121247. + /* Buffer item? */
  121248. + if (item->type == gcvBUFITEM_BUFFER)
  121249. + {
  121250. + /* Advance the index. */
  121251. + index = (index + 1) % gcdDMA_BUFFER_COUNT;
  121252. +
  121253. + /* Add to the buffer array. */
  121254. + buffers[index] = (gcsBUFITEM_BUFFER_PTR) item;
  121255. +
  121256. + /* Stop if this is the current DMA buffer. */
  121257. + if ((gcsBUFITEM_BUFFER_PTR) item == CurrentDMABuffer)
  121258. + {
  121259. + break;
  121260. + }
  121261. + }
  121262. +
  121263. + /* Get the item size and skip it. */
  121264. + skip = (* _itemSize[item->type]) (item);
  121265. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  121266. +
  121267. + /* End of the buffer? Wrap around. */
  121268. + if (item->type == gceBUFITEM_NONE)
  121269. + {
  121270. + item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
  121271. + }
  121272. + }
  121273. +
  121274. + /* Enable the found buffers. */
  121275. + gcmDBGASSERT(index != -1, "%d", index);
  121276. +
  121277. + for (i = 0; i < gcdDMA_BUFFER_COUNT; i += 1)
  121278. + {
  121279. + if (buffers[index] == gcvNULL)
  121280. + {
  121281. + break;
  121282. + }
  121283. +
  121284. + buffers[index]->dmaAddress = DmaAddress;
  121285. +
  121286. + index -= 1;
  121287. +
  121288. + if (index == -1)
  121289. + {
  121290. + index = gcdDMA_BUFFER_COUNT - 1;
  121291. + }
  121292. + }
  121293. +}
  121294. +#endif
  121295. +
  121296. +static void
  121297. +_Flush(
  121298. + gctUINT32 DmaAddress
  121299. + )
  121300. +{
  121301. + gctINT i, skip;
  121302. + gcsBUFITEM_HEAD_PTR item;
  121303. +
  121304. + gcsBUFFERED_OUTPUT_PTR outputBuffer = _outputBufferHead;
  121305. +
  121306. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  121307. + if ((outputBuffer != gcvNULL) && (outputBuffer->count != 0))
  121308. + {
  121309. + /* Find the current DMA buffer. */
  121310. + gcsBUFITEM_BUFFER_PTR dmaCurrent = _FindCurrentDMABuffer(DmaAddress);
  121311. +
  121312. + /* Was the current buffer found? */
  121313. + if (dmaCurrent == gcvNULL)
  121314. + {
  121315. + /* No, print all buffers. */
  121316. + _EnableAllDMABuffers();
  121317. + }
  121318. + else
  121319. + {
  121320. + /* Yes, enable only specified number of buffers. */
  121321. + _EnableDMABuffers(DmaAddress, dmaCurrent);
  121322. + }
  121323. + }
  121324. +#endif
  121325. +
  121326. + while (outputBuffer != gcvNULL)
  121327. + {
  121328. + if (outputBuffer->count != 0)
  121329. + {
  121330. + _DirectPrint("********************************************************************************\n");
  121331. + _DirectPrint("FLUSHING DEBUG OUTPUT BUFFER (%d elements).\n", outputBuffer->count);
  121332. + _DirectPrint("********************************************************************************\n");
  121333. +
  121334. + item = (gcsBUFITEM_HEAD_PTR) &outputBuffer->buffer[outputBuffer->start];
  121335. +
  121336. + for (i = 0; i < outputBuffer->count; i += 1)
  121337. + {
  121338. + skip = (* _printArray[item->type]) (outputBuffer, item);
  121339. +
  121340. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  121341. +
  121342. + if (item->type == gceBUFITEM_NONE)
  121343. + {
  121344. + item = (gcsBUFITEM_HEAD_PTR) outputBuffer->buffer;
  121345. + }
  121346. + }
  121347. +
  121348. + outputBuffer->start = 0;
  121349. + outputBuffer->index = 0;
  121350. + outputBuffer->count = 0;
  121351. + }
  121352. +
  121353. + outputBuffer = outputBuffer->next;
  121354. + }
  121355. +}
  121356. +
  121357. +static gcsBUFITEM_HEAD_PTR
  121358. +_AllocateItem(
  121359. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121360. + IN gctINT Size
  121361. + )
  121362. +{
  121363. + gctINT skip;
  121364. + gcsBUFITEM_HEAD_PTR item, next;
  121365. +
  121366. +#if gcdENABLE_OVERFLOW
  121367. + if (
  121368. + (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  121369. + ||
  121370. + (
  121371. + (OutputBuffer->index < OutputBuffer->start) &&
  121372. + (OutputBuffer->index + Size >= OutputBuffer->start)
  121373. + )
  121374. + )
  121375. + {
  121376. + if (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  121377. + {
  121378. + if (OutputBuffer->index < OutputBuffer->start)
  121379. + {
  121380. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
  121381. +
  121382. + while (item->type != gceBUFITEM_NONE)
  121383. + {
  121384. + skip = (* _itemSize[item->type]) (item);
  121385. +
  121386. + OutputBuffer->start += skip;
  121387. + OutputBuffer->count -= 1;
  121388. +
  121389. + item->type = gceBUFITEM_NONE;
  121390. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  121391. + }
  121392. +
  121393. + OutputBuffer->start = 0;
  121394. + }
  121395. +
  121396. + OutputBuffer->index = 0;
  121397. + }
  121398. +
  121399. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
  121400. +
  121401. + while (OutputBuffer->start - OutputBuffer->index <= Size)
  121402. + {
  121403. + skip = (* _itemSize[item->type]) (item);
  121404. +
  121405. + OutputBuffer->start += skip;
  121406. + OutputBuffer->count -= 1;
  121407. +
  121408. + item->type = gceBUFITEM_NONE;
  121409. + item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
  121410. +
  121411. + if (item->type == gceBUFITEM_NONE)
  121412. + {
  121413. + OutputBuffer->start = 0;
  121414. + break;
  121415. + }
  121416. + }
  121417. + }
  121418. +#else
  121419. + if (OutputBuffer->index + Size > gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
  121420. + {
  121421. + _DirectPrint("\nMessage buffer full; forcing message flush.\n\n");
  121422. + _Flush(~0U);
  121423. + }
  121424. +#endif
  121425. +
  121426. + item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->index];
  121427. +
  121428. + OutputBuffer->index += Size;
  121429. + OutputBuffer->count += 1;
  121430. +
  121431. + next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + Size);
  121432. + next->type = gceBUFITEM_NONE;
  121433. +
  121434. + return item;
  121435. +}
  121436. +
  121437. +#if gcdALIGNBYSIZE
  121438. +static void
  121439. +_FreeExtraSpace(
  121440. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121441. + IN gctPOINTER Item,
  121442. + IN gctINT ItemSize,
  121443. + IN gctINT FreeSize
  121444. + )
  121445. +{
  121446. + gcsBUFITEM_HEAD_PTR next;
  121447. +
  121448. + OutputBuffer->index -= FreeSize;
  121449. +
  121450. + next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) Item + ItemSize);
  121451. + next->type = gceBUFITEM_NONE;
  121452. +}
  121453. +#endif
  121454. +
  121455. +#if gcdHAVEPREFIX
  121456. +static void
  121457. +_AppendPrefix(
  121458. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121459. + IN gctPOINTER Data
  121460. + )
  121461. +{
  121462. + gctUINT8_PTR prefixData;
  121463. + gcsBUFITEM_PREFIX_PTR item;
  121464. + gctINT allocSize;
  121465. +
  121466. +#if gcdALIGNBYSIZE
  121467. + gctUINT alignment;
  121468. + gctINT size, freeSize;
  121469. +#endif
  121470. +
  121471. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  121472. +
  121473. + /* Determine the maximum item size. */
  121474. + allocSize
  121475. + = gcmSIZEOF(gcsBUFITEM_PREFIX)
  121476. + + gcdPREFIX_SIZE
  121477. + + gcdPREFIX_ALIGNMENT;
  121478. +
  121479. + /* Allocate prefix item. */
  121480. + item = (gcsBUFITEM_PREFIX_PTR) _AllocateItem(OutputBuffer, allocSize);
  121481. +
  121482. + /* Compute the initial prefix data pointer. */
  121483. + prefixData = (gctUINT8_PTR) (item + 1);
  121484. +
  121485. + /* Align the data pointer as necessary. */
  121486. +#if gcdALIGNBYSIZE
  121487. + alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
  121488. + prefixData += alignment;
  121489. +#endif
  121490. +
  121491. + /* Set item data. */
  121492. + item->type = gcvBUFITEM_PREFIX;
  121493. + item->prefixData = prefixData;
  121494. +
  121495. + /* Copy argument value. */
  121496. + memcpy(prefixData, Data, gcdPREFIX_SIZE);
  121497. +
  121498. +#if gcdALIGNBYSIZE
  121499. + /* Compute the actual node size. */
  121500. + size = gcmSIZEOF(gcsBUFITEM_PREFIX) + gcdPREFIX_SIZE + alignment;
  121501. +
  121502. + /* Free extra memory if any. */
  121503. + freeSize = allocSize - size;
  121504. + if (freeSize != 0)
  121505. + {
  121506. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  121507. + }
  121508. +#endif
  121509. +}
  121510. +#endif
  121511. +
  121512. +static void
  121513. +_AppendString(
  121514. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121515. + IN gctINT Indent,
  121516. + IN gctCONST_STRING Message,
  121517. + IN gctUINT ArgumentSize,
  121518. + IN gctPOINTER Data
  121519. + )
  121520. +{
  121521. + gctUINT8_PTR messageData;
  121522. + gcsBUFITEM_STRING_PTR item;
  121523. + gctINT allocSize;
  121524. +
  121525. +#if gcdALIGNBYSIZE
  121526. + gctUINT alignment;
  121527. + gctINT size, freeSize;
  121528. +#endif
  121529. +
  121530. + /* Determine the maximum item size. */
  121531. + allocSize
  121532. + = gcmSIZEOF(gcsBUFITEM_STRING)
  121533. + + ArgumentSize
  121534. + + gcdVARARG_ALIGNMENT;
  121535. +
  121536. + /* Allocate prefix item. */
  121537. + item = (gcsBUFITEM_STRING_PTR) _AllocateItem(OutputBuffer, allocSize);
  121538. +
  121539. + /* Compute the initial message data pointer. */
  121540. + messageData = (gctUINT8_PTR) (item + 1);
  121541. +
  121542. + /* Align the data pointer as necessary. */
  121543. +#if gcdALIGNBYSIZE
  121544. + alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
  121545. + messageData += alignment;
  121546. +#endif
  121547. +
  121548. + /* Set item data. */
  121549. + item->type = gcvBUFITEM_STRING;
  121550. + item->indent = Indent;
  121551. + item->message = Message;
  121552. + item->messageData = messageData;
  121553. + item->messageDataSize = ArgumentSize;
  121554. +
  121555. + /* Copy argument value. */
  121556. + if (ArgumentSize != 0)
  121557. + {
  121558. + memcpy(messageData, Data, ArgumentSize);
  121559. + }
  121560. +
  121561. +#if gcdALIGNBYSIZE
  121562. + /* Compute the actual node size. */
  121563. + size = gcmSIZEOF(gcsBUFITEM_STRING) + ArgumentSize + alignment;
  121564. +
  121565. + /* Free extra memory if any. */
  121566. + freeSize = allocSize - size;
  121567. + if (freeSize != 0)
  121568. + {
  121569. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  121570. + }
  121571. +#endif
  121572. +}
  121573. +
  121574. +static void
  121575. +_AppendCopy(
  121576. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121577. + IN gctINT Indent,
  121578. + IN gctCONST_STRING Message,
  121579. + IN gctUINT ArgumentSize,
  121580. + IN gctPOINTER Data
  121581. + )
  121582. +{
  121583. + gctUINT8_PTR messageData;
  121584. + gcsBUFITEM_COPY_PTR item;
  121585. + gctINT allocSize;
  121586. + gctINT messageLength;
  121587. + gctCONST_STRING message;
  121588. +
  121589. +#if gcdALIGNBYSIZE
  121590. + gctUINT alignment;
  121591. + gctINT size, freeSize;
  121592. +#endif
  121593. +
  121594. + /* Get the length of the string. */
  121595. + messageLength = strlen(Message) + 1;
  121596. +
  121597. + /* Determine the maximum item size. */
  121598. + allocSize
  121599. + = gcmSIZEOF(gcsBUFITEM_COPY)
  121600. + + messageLength
  121601. + + ArgumentSize
  121602. + + gcdVARARG_ALIGNMENT;
  121603. +
  121604. + /* Allocate prefix item. */
  121605. + item = (gcsBUFITEM_COPY_PTR) _AllocateItem(OutputBuffer, allocSize);
  121606. +
  121607. + /* Determine the message placement. */
  121608. + message = (gctCONST_STRING) (item + 1);
  121609. +
  121610. + /* Compute the initial message data pointer. */
  121611. + messageData = (gctUINT8_PTR) message + messageLength;
  121612. +
  121613. + /* Align the data pointer as necessary. */
  121614. +#if gcdALIGNBYSIZE
  121615. + if (ArgumentSize == 0)
  121616. + {
  121617. + alignment = 0;
  121618. + }
  121619. + else
  121620. + {
  121621. + alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
  121622. + messageData += alignment;
  121623. + }
  121624. +#endif
  121625. +
  121626. + /* Set item data. */
  121627. + item->type = gcvBUFITEM_COPY;
  121628. + item->indent = Indent;
  121629. + item->messageData = messageData;
  121630. + item->messageDataSize = ArgumentSize;
  121631. +
  121632. + /* Copy the message. */
  121633. + memcpy((gctPOINTER) message, Message, messageLength);
  121634. +
  121635. + /* Copy argument value. */
  121636. + if (ArgumentSize != 0)
  121637. + {
  121638. + memcpy(messageData, Data, ArgumentSize);
  121639. + }
  121640. +
  121641. +#if gcdALIGNBYSIZE
  121642. + /* Compute the actual node size. */
  121643. + size
  121644. + = gcmSIZEOF(gcsBUFITEM_COPY)
  121645. + + messageLength
  121646. + + ArgumentSize
  121647. + + alignment;
  121648. +
  121649. + /* Free extra memory if any. */
  121650. + freeSize = allocSize - size;
  121651. + if (freeSize != 0)
  121652. + {
  121653. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  121654. + }
  121655. +#endif
  121656. +}
  121657. +
  121658. +static void
  121659. +_AppendBuffer(
  121660. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121661. + IN gctINT Indent,
  121662. + IN gctPOINTER PrefixData,
  121663. + IN gctPOINTER Data,
  121664. + IN gctUINT Address,
  121665. + IN gctUINT DataSize,
  121666. + IN gceDUMP_BUFFER Type,
  121667. + IN gctUINT32 DmaAddress
  121668. + )
  121669. +{
  121670. +#if gcdHAVEPREFIX
  121671. + gctUINT8_PTR prefixData;
  121672. + gcsBUFITEM_BUFFER_PTR item;
  121673. + gctINT allocSize;
  121674. + gctPOINTER data;
  121675. +
  121676. +#if gcdALIGNBYSIZE
  121677. + gctUINT alignment;
  121678. + gctINT size, freeSize;
  121679. +#endif
  121680. +
  121681. + gcmDBGASSERT(DataSize != 0, "%d", DataSize);
  121682. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  121683. +
  121684. + /* Determine the maximum item size. */
  121685. + allocSize
  121686. + = gcmSIZEOF(gcsBUFITEM_BUFFER)
  121687. + + gcdPREFIX_SIZE
  121688. + + gcdPREFIX_ALIGNMENT
  121689. + + DataSize;
  121690. +
  121691. + /* Allocate prefix item. */
  121692. + item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, allocSize);
  121693. +
  121694. + /* Compute the initial prefix data pointer. */
  121695. + prefixData = (gctUINT8_PTR) (item + 1);
  121696. +
  121697. +#if gcdALIGNBYSIZE
  121698. + /* Align the data pointer as necessary. */
  121699. + alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
  121700. + prefixData += alignment;
  121701. +#endif
  121702. +
  121703. + /* Set item data. */
  121704. + item->type = gcvBUFITEM_BUFFER;
  121705. + item->indent = Indent;
  121706. + item->bufferType = Type;
  121707. + item->dataSize = DataSize;
  121708. + item->address = Address;
  121709. + item->prefixData = prefixData;
  121710. +
  121711. +#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
  121712. + item->dmaAddress = DmaAddress;
  121713. +#endif
  121714. +
  121715. + /* Copy prefix data. */
  121716. + memcpy(prefixData, PrefixData, gcdPREFIX_SIZE);
  121717. +
  121718. + /* Compute the data pointer. */
  121719. + data = prefixData + gcdPREFIX_SIZE;
  121720. +
  121721. + /* Copy argument value. */
  121722. + memcpy(data, Data, DataSize);
  121723. +
  121724. +#if gcdALIGNBYSIZE
  121725. + /* Compute the actual node size. */
  121726. + size
  121727. + = gcmSIZEOF(gcsBUFITEM_BUFFER)
  121728. + + gcdPREFIX_SIZE
  121729. + + alignment
  121730. + + DataSize;
  121731. +
  121732. + /* Free extra memory if any. */
  121733. + freeSize = allocSize - size;
  121734. + if (freeSize != 0)
  121735. + {
  121736. + _FreeExtraSpace(OutputBuffer, item, size, freeSize);
  121737. + }
  121738. +#endif
  121739. +#else
  121740. + gcsBUFITEM_BUFFER_PTR item;
  121741. + gctINT size;
  121742. +
  121743. + gcmDBGASSERT(DataSize != 0, "%d", DataSize);
  121744. + gcmDBGASSERT(Data != gcvNULL, "%p", Data);
  121745. +
  121746. + /* Determine the maximum item size. */
  121747. + size = gcmSIZEOF(gcsBUFITEM_BUFFER) + DataSize;
  121748. +
  121749. + /* Allocate prefix item. */
  121750. + item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, size);
  121751. +
  121752. + /* Set item data. */
  121753. + item->type = gcvBUFITEM_BUFFER;
  121754. + item->indent = Indent;
  121755. + item->dataSize = DataSize;
  121756. + item->address = Address;
  121757. +
  121758. + /* Copy argument value. */
  121759. + memcpy(item + 1, Data, DataSize);
  121760. +#endif
  121761. +}
  121762. +#endif
  121763. +
  121764. +static gcmINLINE void
  121765. +_InitBuffers(
  121766. + void
  121767. + )
  121768. +{
  121769. + int i;
  121770. +
  121771. + if (_outputBufferHead == gcvNULL)
  121772. + {
  121773. + for (i = 0; i < gcdTHREAD_BUFFERS; i += 1)
  121774. + {
  121775. + if (_outputBufferTail == gcvNULL)
  121776. + {
  121777. + _outputBufferHead = &_outputBuffer[i];
  121778. + }
  121779. + else
  121780. + {
  121781. + _outputBufferTail->next = &_outputBuffer[i];
  121782. + }
  121783. +
  121784. +#if gcdTHREAD_BUFFERS > 1
  121785. + _outputBuffer[i].threadID = ~0U;
  121786. +#endif
  121787. +
  121788. + _outputBuffer[i].prev = _outputBufferTail;
  121789. + _outputBuffer[i].next = gcvNULL;
  121790. +
  121791. + _outputBufferTail = &_outputBuffer[i];
  121792. + }
  121793. + }
  121794. +}
  121795. +
  121796. +static gcmINLINE gcsBUFFERED_OUTPUT_PTR
  121797. +_GetOutputBuffer(
  121798. + void
  121799. + )
  121800. +{
  121801. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  121802. +
  121803. +#if gcdTHREAD_BUFFERS > 1
  121804. + /* Get the current thread ID. */
  121805. + gctUINT32 ThreadID = gcmkGETTHREADID();
  121806. +
  121807. + /* Locate the output buffer for the thread. */
  121808. + outputBuffer = _outputBufferHead;
  121809. +
  121810. + while (outputBuffer != gcvNULL)
  121811. + {
  121812. + if (outputBuffer->threadID == ThreadID)
  121813. + {
  121814. + break;
  121815. + }
  121816. +
  121817. + outputBuffer = outputBuffer->next;
  121818. + }
  121819. +
  121820. + /* No matching buffer found? */
  121821. + if (outputBuffer == gcvNULL)
  121822. + {
  121823. + /* Get the tail for the buffer. */
  121824. + outputBuffer = _outputBufferTail;
  121825. +
  121826. + /* Move it to the head. */
  121827. + _outputBufferTail = _outputBufferTail->prev;
  121828. + _outputBufferTail->next = gcvNULL;
  121829. +
  121830. + outputBuffer->prev = gcvNULL;
  121831. + outputBuffer->next = _outputBufferHead;
  121832. +
  121833. + _outputBufferHead->prev = outputBuffer;
  121834. + _outputBufferHead = outputBuffer;
  121835. +
  121836. + /* Reset the buffer. */
  121837. + outputBuffer->threadID = ThreadID;
  121838. +#if gcdBUFFERED_OUTPUT
  121839. + outputBuffer->start = 0;
  121840. + outputBuffer->index = 0;
  121841. + outputBuffer->count = 0;
  121842. +#endif
  121843. +#if gcdSHOW_LINE_NUMBER
  121844. + outputBuffer->lineNumber = 0;
  121845. +#endif
  121846. + }
  121847. +#else
  121848. + outputBuffer = _outputBufferHead;
  121849. +#endif
  121850. +
  121851. + return outputBuffer;
  121852. +}
  121853. +
  121854. +static gcmINLINE int _GetArgumentSize(
  121855. + IN gctCONST_STRING Message
  121856. + )
  121857. +{
  121858. + int i, count;
  121859. +
  121860. + gcmDBGASSERT(Message != gcvNULL, "%p", Message);
  121861. +
  121862. + for (i = 0, count = 0; Message[i]; i += 1)
  121863. + {
  121864. + if (Message[i] == '%')
  121865. + {
  121866. + count += 1;
  121867. + }
  121868. + }
  121869. +
  121870. + return count * gcmSIZEOF(gctUINT32);
  121871. +}
  121872. +
  121873. +#if gcdHAVEPREFIX
  121874. +static void
  121875. +_InitPrefixData(
  121876. + IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
  121877. + IN gctPOINTER Data
  121878. + )
  121879. +{
  121880. + gctUINT8_PTR data = (gctUINT8_PTR) Data;
  121881. +
  121882. +#if gcdSHOW_TIME
  121883. + {
  121884. + gctUINT64 time;
  121885. + gckOS_GetProfileTick(&time);
  121886. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
  121887. + * ((gctUINT64_PTR) data) = time;
  121888. + data += gcmSIZEOF(gctUINT64);
  121889. + }
  121890. +#endif
  121891. +
  121892. +#if gcdSHOW_LINE_NUMBER
  121893. + {
  121894. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
  121895. + * ((gctUINT64_PTR) data) = OutputBuffer->lineNumber;
  121896. + data += gcmSIZEOF(gctUINT64);
  121897. + }
  121898. +#endif
  121899. +
  121900. +#if gcdSHOW_PROCESS_ID
  121901. + {
  121902. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
  121903. + * ((gctUINT32_PTR) data) = gcmkGETPROCESSID();
  121904. + data += gcmSIZEOF(gctUINT32);
  121905. + }
  121906. +#endif
  121907. +
  121908. +#if gcdSHOW_THREAD_ID
  121909. + {
  121910. + gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
  121911. + * ((gctUINT32_PTR) data) = gcmkGETTHREADID();
  121912. + }
  121913. +#endif
  121914. +}
  121915. +#endif
  121916. +
  121917. +static void
  121918. +_Print(
  121919. + IN gctUINT ArgumentSize,
  121920. + IN gctBOOL CopyMessage,
  121921. + IN gctCONST_STRING Message,
  121922. + IN gctARGUMENTS Arguments
  121923. + )
  121924. +{
  121925. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  121926. + gcmkDECLARE_LOCK(lockHandle);
  121927. +
  121928. + gcmkLOCKSECTION(lockHandle);
  121929. +
  121930. + /* Initialize output buffer list. */
  121931. + _InitBuffers();
  121932. +
  121933. + /* Locate the proper output buffer. */
  121934. + outputBuffer = _GetOutputBuffer();
  121935. +
  121936. + /* Update the line number. */
  121937. +#if gcdSHOW_LINE_NUMBER
  121938. + outputBuffer->lineNumber += 1;
  121939. +#endif
  121940. +
  121941. + /* Print prefix. */
  121942. +#if gcdHAVEPREFIX
  121943. + {
  121944. + gctUINT8_PTR alignedPrefixData;
  121945. + gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
  121946. +
  121947. + /* Compute aligned pointer. */
  121948. + alignedPrefixData = prefixData;
  121949. + gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
  121950. +
  121951. + /* Initialize the prefix data. */
  121952. + _InitPrefixData(outputBuffer, alignedPrefixData);
  121953. +
  121954. + /* Print the prefix. */
  121955. + gcdOUTPUTPREFIX(outputBuffer, alignedPrefixData);
  121956. + }
  121957. +#endif
  121958. +
  121959. + /* Form the indent string. */
  121960. + if (strncmp(Message, "--", 2) == 0)
  121961. + {
  121962. + outputBuffer->indent -= 2;
  121963. + }
  121964. +
  121965. + /* Print the message. */
  121966. + if (CopyMessage)
  121967. + {
  121968. + gcdOUTPUTCOPY(
  121969. + outputBuffer, outputBuffer->indent,
  121970. + Message, ArgumentSize, * (gctPOINTER *) &Arguments
  121971. + );
  121972. + }
  121973. + else
  121974. + {
  121975. + gcdOUTPUTSTRING(
  121976. + outputBuffer, outputBuffer->indent,
  121977. + Message, ArgumentSize, * (gctPOINTER *) &Arguments
  121978. + );
  121979. + }
  121980. +
  121981. + /* Check increasing indent. */
  121982. + if (strncmp(Message, "++", 2) == 0)
  121983. + {
  121984. + outputBuffer->indent += 2;
  121985. + }
  121986. +
  121987. + gcmkUNLOCKSECTION(lockHandle);
  121988. +}
  121989. +
  121990. +
  121991. +/******************************************************************************\
  121992. +********************************* Debug Macros *********************************
  121993. +\******************************************************************************/
  121994. +
  121995. +#ifdef __QNXNTO__
  121996. +
  121997. +extern volatile unsigned g_nQnxInIsrs;
  121998. +
  121999. +#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
  122000. +{ \
  122001. + if (atomic_add_value(&g_nQnxInIsrs, 1) == 0) \
  122002. + { \
  122003. + gctARGUMENTS __arguments__; \
  122004. + gcmkARGUMENTS_START(__arguments__, Message); \
  122005. + _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
  122006. + gcmkARGUMENTS_END(__arguments__); \
  122007. + } \
  122008. + atomic_sub(&g_nQnxInIsrs, 1); \
  122009. +}
  122010. +
  122011. +#else
  122012. +
  122013. +#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
  122014. +{ \
  122015. + gctARGUMENTS __arguments__; \
  122016. + gcmkARGUMENTS_START(__arguments__, Message); \
  122017. + _Print(ArgumentSize, CopyMessage, Message, __arguments__); \
  122018. + gcmkARGUMENTS_END(__arguments__); \
  122019. +}
  122020. +
  122021. +#endif
  122022. +
  122023. +/******************************************************************************\
  122024. +********************************** Debug Code **********************************
  122025. +\******************************************************************************/
  122026. +
  122027. +/*******************************************************************************
  122028. +**
  122029. +** gckOS_Print
  122030. +**
  122031. +** Send a message to the debugger.
  122032. +**
  122033. +** INPUT:
  122034. +**
  122035. +** gctCONST_STRING Message
  122036. +** Pointer to message.
  122037. +**
  122038. +** ...
  122039. +** Optional arguments.
  122040. +**
  122041. +** OUTPUT:
  122042. +**
  122043. +** Nothing.
  122044. +*/
  122045. +
  122046. +void
  122047. +gckOS_Print(
  122048. + IN gctCONST_STRING Message,
  122049. + ...
  122050. + )
  122051. +{
  122052. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  122053. +}
  122054. +
  122055. +/*******************************************************************************
  122056. +**
  122057. +** gckOS_PrintN
  122058. +**
  122059. +** Send a message to the debugger.
  122060. +**
  122061. +** INPUT:
  122062. +**
  122063. +** gctUINT ArgumentSize
  122064. +** The size of the optional arguments in bytes.
  122065. +**
  122066. +** gctCONST_STRING Message
  122067. +** Pointer to message.
  122068. +**
  122069. +** ...
  122070. +** Optional arguments.
  122071. +**
  122072. +** OUTPUT:
  122073. +**
  122074. +** Nothing.
  122075. +*/
  122076. +
  122077. +void
  122078. +gckOS_PrintN(
  122079. + IN gctUINT ArgumentSize,
  122080. + IN gctCONST_STRING Message,
  122081. + ...
  122082. + )
  122083. +{
  122084. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  122085. +}
  122086. +
  122087. +/*******************************************************************************
  122088. +**
  122089. +** gckOS_CopyPrint
  122090. +**
  122091. +** Send a message to the debugger. If in buffered output mode, the entire
  122092. +** message will be copied into the buffer instead of using the pointer to
  122093. +** the string.
  122094. +**
  122095. +** INPUT:
  122096. +**
  122097. +** gctCONST_STRING Message
  122098. +** Pointer to message.
  122099. +**
  122100. +** ...
  122101. +** Optional arguments.
  122102. +**
  122103. +** OUTPUT:
  122104. +**
  122105. +** Nothing.
  122106. +*/
  122107. +
  122108. +void
  122109. +gckOS_CopyPrint(
  122110. + IN gctCONST_STRING Message,
  122111. + ...
  122112. + )
  122113. +{
  122114. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvTRUE, Message);
  122115. +}
  122116. +
  122117. +/*******************************************************************************
  122118. +**
  122119. +** gckOS_DumpBuffer
  122120. +**
  122121. +** Print the contents of the specified buffer.
  122122. +**
  122123. +** INPUT:
  122124. +**
  122125. +** gckOS Os
  122126. +** Pointer to gckOS object.
  122127. +**
  122128. +** gctPOINTER Buffer
  122129. +** Pointer to the buffer to print.
  122130. +**
  122131. +** gctUINT Size
  122132. +** Size of the buffer.
  122133. +**
  122134. +** gceDUMP_BUFFER Type
  122135. +** Buffer type.
  122136. +**
  122137. +** OUTPUT:
  122138. +**
  122139. +** Nothing.
  122140. +*/
  122141. +
  122142. +void
  122143. +gckOS_DumpBuffer(
  122144. + IN gckOS Os,
  122145. + IN gctPOINTER Buffer,
  122146. + IN gctUINT Size,
  122147. + IN gceDUMP_BUFFER Type,
  122148. + IN gctBOOL CopyMessage
  122149. + )
  122150. +{
  122151. + gctUINT32 address;
  122152. + gcsBUFFERED_OUTPUT_PTR outputBuffer;
  122153. + static gctBOOL userLocked;
  122154. + gctCHAR *buffer = (gctCHAR*)Buffer;
  122155. +
  122156. + gcmkDECLARE_LOCK(lockHandle);
  122157. +
  122158. + /* Request lock when not coming from user,
  122159. + or coming from user and not yet locked
  122160. + and message is starting with @[. */
  122161. + if (Type == gceDUMP_BUFFER_FROM_USER)
  122162. + {
  122163. + if ((Size > 2)
  122164. + && (buffer[0] == '@')
  122165. + && (buffer[1] == '['))
  122166. + {
  122167. + /* Beginning of a user dump. */
  122168. + gcmkLOCKSECTION(lockHandle);
  122169. + userLocked = gcvTRUE;
  122170. + }
  122171. + /* Else, let it pass through. */
  122172. + }
  122173. + else
  122174. + {
  122175. + gcmkLOCKSECTION(lockHandle);
  122176. + userLocked = gcvFALSE;
  122177. + }
  122178. +
  122179. + if (Buffer != gcvNULL)
  122180. + {
  122181. + /* Initialize output buffer list. */
  122182. + _InitBuffers();
  122183. +
  122184. + /* Locate the proper output buffer. */
  122185. + outputBuffer = _GetOutputBuffer();
  122186. +
  122187. + /* Update the line number. */
  122188. +#if gcdSHOW_LINE_NUMBER
  122189. + outputBuffer->lineNumber += 1;
  122190. +#endif
  122191. +
  122192. + /* Get the physical address of the buffer. */
  122193. + if (Type != gceDUMP_BUFFER_FROM_USER)
  122194. + {
  122195. + gcmkVERIFY_OK(gckOS_GetPhysicalAddress(Os, Buffer, &address));
  122196. + }
  122197. + else
  122198. + {
  122199. + address = 0;
  122200. + }
  122201. +
  122202. +#if gcdHAVEPREFIX
  122203. + {
  122204. + gctUINT8_PTR alignedPrefixData;
  122205. + gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
  122206. +
  122207. + /* Compute aligned pointer. */
  122208. + alignedPrefixData = prefixData;
  122209. + gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
  122210. +
  122211. + /* Initialize the prefix data. */
  122212. + _InitPrefixData(outputBuffer, alignedPrefixData);
  122213. +
  122214. + /* Print/schedule the buffer. */
  122215. + gcdOUTPUTBUFFER(
  122216. + outputBuffer, outputBuffer->indent,
  122217. + alignedPrefixData, Buffer, address, Size, Type, 0
  122218. + );
  122219. + }
  122220. +#else
  122221. + /* Print/schedule the buffer. */
  122222. + if (Type == gceDUMP_BUFFER_FROM_USER)
  122223. + {
  122224. + gcdOUTPUTSTRING(
  122225. + outputBuffer, outputBuffer->indent,
  122226. + Buffer, 0, gcvNULL
  122227. + );
  122228. + }
  122229. + else
  122230. + {
  122231. + gcdOUTPUTBUFFER(
  122232. + outputBuffer, outputBuffer->indent,
  122233. + gcvNULL, Buffer, address, Size, Type, 0
  122234. + );
  122235. + }
  122236. +#endif
  122237. + }
  122238. +
  122239. + /* Unlock when not coming from user,
  122240. + or coming from user and not yet locked. */
  122241. + if (userLocked)
  122242. + {
  122243. + if ((Size > 4)
  122244. + && (buffer[0] == ']')
  122245. + && (buffer[1] == ' ')
  122246. + && (buffer[2] == '-')
  122247. + && (buffer[3] == '-'))
  122248. + {
  122249. + /* End of a user dump. */
  122250. + gcmkUNLOCKSECTION(lockHandle);
  122251. + userLocked = gcvFALSE;
  122252. + }
  122253. + /* Else, let it pass through, don't unlock. */
  122254. + }
  122255. + else
  122256. + {
  122257. + gcmkUNLOCKSECTION(lockHandle);
  122258. + }
  122259. +}
  122260. +
  122261. +/*******************************************************************************
  122262. +**
  122263. +** gckOS_DebugTrace
  122264. +**
  122265. +** Send a leveled message to the debugger.
  122266. +**
  122267. +** INPUT:
  122268. +**
  122269. +** gctUINT32 Level
  122270. +** Debug level of message.
  122271. +**
  122272. +** gctCONST_STRING Message
  122273. +** Pointer to message.
  122274. +**
  122275. +** ...
  122276. +** Optional arguments.
  122277. +**
  122278. +** OUTPUT:
  122279. +**
  122280. +** Nothing.
  122281. +*/
  122282. +
  122283. +void
  122284. +gckOS_DebugTrace(
  122285. + IN gctUINT32 Level,
  122286. + IN gctCONST_STRING Message,
  122287. + ...
  122288. + )
  122289. +{
  122290. + if (Level > _debugLevel)
  122291. + {
  122292. + return;
  122293. + }
  122294. +
  122295. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  122296. +}
  122297. +
  122298. +/*******************************************************************************
  122299. +**
  122300. +** gckOS_DebugTraceN
  122301. +**
  122302. +** Send a leveled message to the debugger.
  122303. +**
  122304. +** INPUT:
  122305. +**
  122306. +** gctUINT32 Level
  122307. +** Debug level of message.
  122308. +**
  122309. +** gctUINT ArgumentSize
  122310. +** The size of the optional arguments in bytes.
  122311. +**
  122312. +** gctCONST_STRING Message
  122313. +** Pointer to message.
  122314. +**
  122315. +** ...
  122316. +** Optional arguments.
  122317. +**
  122318. +** OUTPUT:
  122319. +**
  122320. +** Nothing.
  122321. +*/
  122322. +
  122323. +void
  122324. +gckOS_DebugTraceN(
  122325. + IN gctUINT32 Level,
  122326. + IN gctUINT ArgumentSize,
  122327. + IN gctCONST_STRING Message,
  122328. + ...
  122329. + )
  122330. +{
  122331. + if (Level > _debugLevel)
  122332. + {
  122333. + return;
  122334. + }
  122335. +
  122336. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  122337. +}
  122338. +
  122339. +/*******************************************************************************
  122340. +**
  122341. +** gckOS_DebugTraceZone
  122342. +**
  122343. +** Send a leveled and zoned message to the debugger.
  122344. +**
  122345. +** INPUT:
  122346. +**
  122347. +** gctUINT32 Level
  122348. +** Debug level for message.
  122349. +**
  122350. +** gctUINT32 Zone
  122351. +** Debug zone for message.
  122352. +**
  122353. +** gctCONST_STRING Message
  122354. +** Pointer to message.
  122355. +**
  122356. +** ...
  122357. +** Optional arguments.
  122358. +**
  122359. +** OUTPUT:
  122360. +**
  122361. +** Nothing.
  122362. +*/
  122363. +
  122364. +void
  122365. +gckOS_DebugTraceZone(
  122366. + IN gctUINT32 Level,
  122367. + IN gctUINT32 Zone,
  122368. + IN gctCONST_STRING Message,
  122369. + ...
  122370. + )
  122371. +{
  122372. + if ((Level > _debugLevel) || !(Zone & _debugZones))
  122373. + {
  122374. + return;
  122375. + }
  122376. +
  122377. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  122378. +}
  122379. +
  122380. +/*******************************************************************************
  122381. +**
  122382. +** gckOS_DebugTraceZoneN
  122383. +**
  122384. +** Send a leveled and zoned message to the debugger.
  122385. +**
  122386. +** INPUT:
  122387. +**
  122388. +** gctUINT32 Level
  122389. +** Debug level for message.
  122390. +**
  122391. +** gctUINT32 Zone
  122392. +** Debug zone for message.
  122393. +**
  122394. +** gctUINT ArgumentSize
  122395. +** The size of the optional arguments in bytes.
  122396. +**
  122397. +** gctCONST_STRING Message
  122398. +** Pointer to message.
  122399. +**
  122400. +** ...
  122401. +** Optional arguments.
  122402. +**
  122403. +** OUTPUT:
  122404. +**
  122405. +** Nothing.
  122406. +*/
  122407. +
  122408. +void
  122409. +gckOS_DebugTraceZoneN(
  122410. + IN gctUINT32 Level,
  122411. + IN gctUINT32 Zone,
  122412. + IN gctUINT ArgumentSize,
  122413. + IN gctCONST_STRING Message,
  122414. + ...
  122415. + )
  122416. +{
  122417. + if ((Level > _debugLevel) || !(Zone & _debugZones))
  122418. + {
  122419. + return;
  122420. + }
  122421. +
  122422. + gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
  122423. +}
  122424. +
  122425. +/*******************************************************************************
  122426. +**
  122427. +** gckOS_DebugBreak
  122428. +**
  122429. +** Break into the debugger.
  122430. +**
  122431. +** INPUT:
  122432. +**
  122433. +** Nothing.
  122434. +**
  122435. +** OUTPUT:
  122436. +**
  122437. +** Nothing.
  122438. +*/
  122439. +void
  122440. +gckOS_DebugBreak(
  122441. + void
  122442. + )
  122443. +{
  122444. + gckOS_DebugTrace(gcvLEVEL_ERROR, "%s(%d)", __FUNCTION__, __LINE__);
  122445. +}
  122446. +
  122447. +/*******************************************************************************
  122448. +**
  122449. +** gckOS_DebugFatal
  122450. +**
  122451. +** Send a message to the debugger and break into the debugger.
  122452. +**
  122453. +** INPUT:
  122454. +**
  122455. +** gctCONST_STRING Message
  122456. +** Pointer to message.
  122457. +**
  122458. +** ...
  122459. +** Optional arguments.
  122460. +**
  122461. +** OUTPUT:
  122462. +**
  122463. +** Nothing.
  122464. +*/
  122465. +void
  122466. +gckOS_DebugFatal(
  122467. + IN gctCONST_STRING Message,
  122468. + ...
  122469. + )
  122470. +{
  122471. + gcmkPRINT_VERSION();
  122472. + gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
  122473. +
  122474. + /* Break into the debugger. */
  122475. + gckOS_DebugBreak();
  122476. +}
  122477. +
  122478. +/*******************************************************************************
  122479. +**
  122480. +** gckOS_SetDebugLevel
  122481. +**
  122482. +** Set the debug level.
  122483. +**
  122484. +** INPUT:
  122485. +**
  122486. +** gctUINT32 Level
  122487. +** New debug level.
  122488. +**
  122489. +** OUTPUT:
  122490. +**
  122491. +** Nothing.
  122492. +*/
  122493. +
  122494. +void
  122495. +gckOS_SetDebugLevel(
  122496. + IN gctUINT32 Level
  122497. + )
  122498. +{
  122499. + _debugLevel = Level;
  122500. +}
  122501. +
  122502. +/*******************************************************************************
  122503. +**
  122504. +** gckOS_SetDebugZone
  122505. +**
  122506. +** Set the debug zone.
  122507. +**
  122508. +** INPUT:
  122509. +**
  122510. +** gctUINT32 Zone
  122511. +** New debug zone.
  122512. +**
  122513. +** OUTPUT:
  122514. +**
  122515. +** Nothing.
  122516. +*/
  122517. +void
  122518. +gckOS_SetDebugZone(
  122519. + IN gctUINT32 Zone
  122520. + )
  122521. +{
  122522. + _debugZones = Zone;
  122523. +}
  122524. +
  122525. +/*******************************************************************************
  122526. +**
  122527. +** gckOS_SetDebugLevelZone
  122528. +**
  122529. +** Set the debug level and zone.
  122530. +**
  122531. +** INPUT:
  122532. +**
  122533. +** gctUINT32 Level
  122534. +** New debug level.
  122535. +**
  122536. +** gctUINT32 Zone
  122537. +** New debug zone.
  122538. +**
  122539. +** OUTPUT:
  122540. +**
  122541. +** Nothing.
  122542. +*/
  122543. +
  122544. +void
  122545. +gckOS_SetDebugLevelZone(
  122546. + IN gctUINT32 Level,
  122547. + IN gctUINT32 Zone
  122548. + )
  122549. +{
  122550. + _debugLevel = Level;
  122551. + _debugZones = Zone;
  122552. +}
  122553. +
  122554. +/*******************************************************************************
  122555. +**
  122556. +** gckOS_SetDebugZones
  122557. +**
  122558. +** Enable or disable debug zones.
  122559. +**
  122560. +** INPUT:
  122561. +**
  122562. +** gctUINT32 Zones
  122563. +** Debug zones to enable or disable.
  122564. +**
  122565. +** gctBOOL Enable
  122566. +** Set to gcvTRUE to enable the zones (or the Zones with the current
  122567. +** zones) or gcvFALSE to disable the specified Zones.
  122568. +**
  122569. +** OUTPUT:
  122570. +**
  122571. +** Nothing.
  122572. +*/
  122573. +
  122574. +void
  122575. +gckOS_SetDebugZones(
  122576. + IN gctUINT32 Zones,
  122577. + IN gctBOOL Enable
  122578. + )
  122579. +{
  122580. + if (Enable)
  122581. + {
  122582. + /* Enable the zones. */
  122583. + _debugZones |= Zones;
  122584. + }
  122585. + else
  122586. + {
  122587. + /* Disable the zones. */
  122588. + _debugZones &= ~Zones;
  122589. + }
  122590. +}
  122591. +
  122592. +/*******************************************************************************
  122593. +**
  122594. +** gckOS_Verify
  122595. +**
  122596. +** Called to verify the result of a function call.
  122597. +**
  122598. +** INPUT:
  122599. +**
  122600. +** gceSTATUS Status
  122601. +** Function call result.
  122602. +**
  122603. +** OUTPUT:
  122604. +**
  122605. +** Nothing.
  122606. +*/
  122607. +
  122608. +void
  122609. +gckOS_Verify(
  122610. + IN gceSTATUS status
  122611. + )
  122612. +{
  122613. + _lastError = status;
  122614. +}
  122615. +
  122616. +/*******************************************************************************
  122617. +**
  122618. +** gckOS_DebugFlush
  122619. +**
  122620. +** Force messages to be flushed out.
  122621. +**
  122622. +** INPUT:
  122623. +**
  122624. +** gctCONST_STRING CallerName
  122625. +** Name of the caller function.
  122626. +**
  122627. +** gctUINT LineNumber
  122628. +** Line number of the caller.
  122629. +**
  122630. +** gctUINT32 DmaAddress
  122631. +** The current DMA address or ~0U to ignore.
  122632. +**
  122633. +** OUTPUT:
  122634. +**
  122635. +** Nothing.
  122636. +*/
  122637. +
  122638. +void
  122639. +gckOS_DebugFlush(
  122640. + gctCONST_STRING CallerName,
  122641. + gctUINT LineNumber,
  122642. + gctUINT32 DmaAddress
  122643. + )
  122644. +{
  122645. +#if gcdBUFFERED_OUTPUT
  122646. + _DirectPrint("\nFlush requested by %s(%d).\n\n", CallerName, LineNumber);
  122647. + _Flush(DmaAddress);
  122648. +#endif
  122649. +}
  122650. +gctCONST_STRING
  122651. +gckOS_DebugStatus2Name(
  122652. + gceSTATUS status
  122653. + )
  122654. +{
  122655. + switch (status)
  122656. + {
  122657. + case gcvSTATUS_OK:
  122658. + return "gcvSTATUS_OK";
  122659. + case gcvSTATUS_TRUE:
  122660. + return "gcvSTATUS_TRUE";
  122661. + case gcvSTATUS_NO_MORE_DATA:
  122662. + return "gcvSTATUS_NO_MORE_DATA";
  122663. + case gcvSTATUS_CACHED:
  122664. + return "gcvSTATUS_CACHED";
  122665. + case gcvSTATUS_MIPMAP_TOO_LARGE:
  122666. + return "gcvSTATUS_MIPMAP_TOO_LARGE";
  122667. + case gcvSTATUS_NAME_NOT_FOUND:
  122668. + return "gcvSTATUS_NAME_NOT_FOUND";
  122669. + case gcvSTATUS_NOT_OUR_INTERRUPT:
  122670. + return "gcvSTATUS_NOT_OUR_INTERRUPT";
  122671. + case gcvSTATUS_MISMATCH:
  122672. + return "gcvSTATUS_MISMATCH";
  122673. + case gcvSTATUS_MIPMAP_TOO_SMALL:
  122674. + return "gcvSTATUS_MIPMAP_TOO_SMALL";
  122675. + case gcvSTATUS_LARGER:
  122676. + return "gcvSTATUS_LARGER";
  122677. + case gcvSTATUS_SMALLER:
  122678. + return "gcvSTATUS_SMALLER";
  122679. + case gcvSTATUS_CHIP_NOT_READY:
  122680. + return "gcvSTATUS_CHIP_NOT_READY";
  122681. + case gcvSTATUS_NEED_CONVERSION:
  122682. + return "gcvSTATUS_NEED_CONVERSION";
  122683. + case gcvSTATUS_SKIP:
  122684. + return "gcvSTATUS_SKIP";
  122685. + case gcvSTATUS_DATA_TOO_LARGE:
  122686. + return "gcvSTATUS_DATA_TOO_LARGE";
  122687. + case gcvSTATUS_INVALID_CONFIG:
  122688. + return "gcvSTATUS_INVALID_CONFIG";
  122689. + case gcvSTATUS_CHANGED:
  122690. + return "gcvSTATUS_CHANGED";
  122691. + case gcvSTATUS_NOT_SUPPORT_DITHER:
  122692. + return "gcvSTATUS_NOT_SUPPORT_DITHER";
  122693. +
  122694. + case gcvSTATUS_INVALID_ARGUMENT:
  122695. + return "gcvSTATUS_INVALID_ARGUMENT";
  122696. + case gcvSTATUS_INVALID_OBJECT:
  122697. + return "gcvSTATUS_INVALID_OBJECT";
  122698. + case gcvSTATUS_OUT_OF_MEMORY:
  122699. + return "gcvSTATUS_OUT_OF_MEMORY";
  122700. + case gcvSTATUS_MEMORY_LOCKED:
  122701. + return "gcvSTATUS_MEMORY_LOCKED";
  122702. + case gcvSTATUS_MEMORY_UNLOCKED:
  122703. + return "gcvSTATUS_MEMORY_UNLOCKED";
  122704. + case gcvSTATUS_HEAP_CORRUPTED:
  122705. + return "gcvSTATUS_HEAP_CORRUPTED";
  122706. + case gcvSTATUS_GENERIC_IO:
  122707. + return "gcvSTATUS_GENERIC_IO";
  122708. + case gcvSTATUS_INVALID_ADDRESS:
  122709. + return "gcvSTATUS_INVALID_ADDRESS";
  122710. + case gcvSTATUS_CONTEXT_LOSSED:
  122711. + return "gcvSTATUS_CONTEXT_LOSSED";
  122712. + case gcvSTATUS_TOO_COMPLEX:
  122713. + return "gcvSTATUS_TOO_COMPLEX";
  122714. + case gcvSTATUS_BUFFER_TOO_SMALL:
  122715. + return "gcvSTATUS_BUFFER_TOO_SMALL";
  122716. + case gcvSTATUS_INTERFACE_ERROR:
  122717. + return "gcvSTATUS_INTERFACE_ERROR";
  122718. + case gcvSTATUS_NOT_SUPPORTED:
  122719. + return "gcvSTATUS_NOT_SUPPORTED";
  122720. + case gcvSTATUS_MORE_DATA:
  122721. + return "gcvSTATUS_MORE_DATA";
  122722. + case gcvSTATUS_TIMEOUT:
  122723. + return "gcvSTATUS_TIMEOUT";
  122724. + case gcvSTATUS_OUT_OF_RESOURCES:
  122725. + return "gcvSTATUS_OUT_OF_RESOURCES";
  122726. + case gcvSTATUS_INVALID_DATA:
  122727. + return "gcvSTATUS_INVALID_DATA";
  122728. + case gcvSTATUS_INVALID_MIPMAP:
  122729. + return "gcvSTATUS_INVALID_MIPMAP";
  122730. + case gcvSTATUS_NOT_FOUND:
  122731. + return "gcvSTATUS_NOT_FOUND";
  122732. + case gcvSTATUS_NOT_ALIGNED:
  122733. + return "gcvSTATUS_NOT_ALIGNED";
  122734. + case gcvSTATUS_INVALID_REQUEST:
  122735. + return "gcvSTATUS_INVALID_REQUEST";
  122736. + case gcvSTATUS_GPU_NOT_RESPONDING:
  122737. + return "gcvSTATUS_GPU_NOT_RESPONDING";
  122738. + case gcvSTATUS_TIMER_OVERFLOW:
  122739. + return "gcvSTATUS_TIMER_OVERFLOW";
  122740. + case gcvSTATUS_VERSION_MISMATCH:
  122741. + return "gcvSTATUS_VERSION_MISMATCH";
  122742. + case gcvSTATUS_LOCKED:
  122743. + return "gcvSTATUS_LOCKED";
  122744. +
  122745. + /* Linker errors. */
  122746. + case gcvSTATUS_GLOBAL_TYPE_MISMATCH:
  122747. + return "gcvSTATUS_GLOBAL_TYPE_MISMATCH";
  122748. + case gcvSTATUS_TOO_MANY_ATTRIBUTES:
  122749. + return "gcvSTATUS_TOO_MANY_ATTRIBUTES";
  122750. + case gcvSTATUS_TOO_MANY_UNIFORMS:
  122751. + return "gcvSTATUS_TOO_MANY_UNIFORMS";
  122752. + case gcvSTATUS_TOO_MANY_VARYINGS:
  122753. + return "gcvSTATUS_TOO_MANY_VARYINGS";
  122754. + case gcvSTATUS_UNDECLARED_VARYING:
  122755. + return "gcvSTATUS_UNDECLARED_VARYING";
  122756. + case gcvSTATUS_VARYING_TYPE_MISMATCH:
  122757. + return "gcvSTATUS_VARYING_TYPE_MISMATCH";
  122758. + case gcvSTATUS_MISSING_MAIN:
  122759. + return "gcvSTATUS_MISSING_MAIN";
  122760. + case gcvSTATUS_NAME_MISMATCH:
  122761. + return "gcvSTATUS_NAME_MISMATCH";
  122762. + case gcvSTATUS_INVALID_INDEX:
  122763. + return "gcvSTATUS_INVALID_INDEX";
  122764. + default:
  122765. + return "nil";
  122766. + }
  122767. +}
  122768. diff -Nur linux-3.14.17/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
  122769. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c 1970-01-01 01:00:00.000000000 +0100
  122770. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c 2014-09-11 18:06:03.110042404 +0200
  122771. @@ -0,0 +1,2898 @@
  122772. +/****************************************************************************
  122773. +*
  122774. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  122775. +*
  122776. +* This program is free software; you can redistribute it and/or modify
  122777. +* it under the terms of the GNU General Public License as published by
  122778. +* the Free Software Foundation; either version 2 of the license, or
  122779. +* (at your option) any later version.
  122780. +*
  122781. +* This program is distributed in the hope that it will be useful,
  122782. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  122783. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  122784. +* GNU General Public License for more details.
  122785. +*
  122786. +* You should have received a copy of the GNU General Public License
  122787. +* along with this program; if not write to the Free Software
  122788. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  122789. +*
  122790. +*****************************************************************************/
  122791. +
  122792. +
  122793. +#include "gc_hal_kernel_precomp.h"
  122794. +#include "gc_hal_kernel_buffer.h"
  122795. +
  122796. +#ifdef __QNXNTO__
  122797. +#include <atomic.h>
  122798. +#include "gc_hal_kernel_qnx.h"
  122799. +#endif
  122800. +
  122801. +#define _GC_OBJ_ZONE gcvZONE_EVENT
  122802. +
  122803. +#define gcdEVENT_ALLOCATION_COUNT (4096 / gcmSIZEOF(gcsHAL_INTERFACE))
  122804. +#define gcdEVENT_MIN_THRESHOLD 4
  122805. +
  122806. +/******************************************************************************\
  122807. +********************************* Support Code *********************************
  122808. +\******************************************************************************/
  122809. +
  122810. +static gceSTATUS
  122811. +gckEVENT_AllocateQueue(
  122812. + IN gckEVENT Event,
  122813. + OUT gcsEVENT_QUEUE_PTR * Queue
  122814. + )
  122815. +{
  122816. + gceSTATUS status;
  122817. +
  122818. + gcmkHEADER_ARG("Event=0x%x", Event);
  122819. +
  122820. + /* Verify the arguments. */
  122821. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122822. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  122823. +
  122824. + /* Do we have free queues? */
  122825. + if (Event->freeList == gcvNULL)
  122826. + {
  122827. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  122828. + }
  122829. +
  122830. + /* Move one free queue from the free list. */
  122831. + * Queue = Event->freeList;
  122832. + Event->freeList = Event->freeList->next;
  122833. +
  122834. + /* Success. */
  122835. + gcmkFOOTER_ARG("*Queue=0x%x", gcmOPT_POINTER(Queue));
  122836. + return gcvSTATUS_OK;
  122837. +
  122838. +OnError:
  122839. + /* Return the status. */
  122840. + gcmkFOOTER();
  122841. + return status;
  122842. +}
  122843. +
  122844. +static gceSTATUS
  122845. +gckEVENT_FreeQueue(
  122846. + IN gckEVENT Event,
  122847. + OUT gcsEVENT_QUEUE_PTR Queue
  122848. + )
  122849. +{
  122850. + gceSTATUS status = gcvSTATUS_OK;
  122851. +
  122852. + gcmkHEADER_ARG("Event=0x%x", Event);
  122853. +
  122854. + /* Verify the arguments. */
  122855. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122856. + gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
  122857. +
  122858. + /* Move one free queue from the free list. */
  122859. + Queue->next = Event->freeList;
  122860. + Event->freeList = Queue;
  122861. +
  122862. + /* Success. */
  122863. + gcmkFOOTER();
  122864. + return status;
  122865. +}
  122866. +
  122867. +static gceSTATUS
  122868. +gckEVENT_FreeRecord(
  122869. + IN gckEVENT Event,
  122870. + IN gcsEVENT_PTR Record
  122871. + )
  122872. +{
  122873. + gceSTATUS status;
  122874. + gctBOOL acquired = gcvFALSE;
  122875. +
  122876. + gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
  122877. +
  122878. + /* Verify the arguments. */
  122879. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122880. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  122881. +
  122882. + /* Acquire the mutex. */
  122883. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  122884. + Event->freeEventMutex,
  122885. + gcvINFINITE));
  122886. + acquired = gcvTRUE;
  122887. +
  122888. + /* Push the record on the free list. */
  122889. + Record->next = Event->freeEventList;
  122890. + Event->freeEventList = Record;
  122891. + Event->freeEventCount += 1;
  122892. +
  122893. + /* Release the mutex. */
  122894. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  122895. +
  122896. + /* Success. */
  122897. + gcmkFOOTER_NO();
  122898. + return gcvSTATUS_OK;
  122899. +
  122900. +OnError:
  122901. + /* Roll back. */
  122902. + if (acquired)
  122903. + {
  122904. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  122905. + }
  122906. +
  122907. + /* Return the status. */
  122908. + gcmkFOOTER();
  122909. + return gcvSTATUS_OK;
  122910. +}
  122911. +
  122912. +static gceSTATUS
  122913. +gckEVENT_IsEmpty(
  122914. + IN gckEVENT Event,
  122915. + OUT gctBOOL_PTR IsEmpty
  122916. + )
  122917. +{
  122918. + gceSTATUS status;
  122919. + gctSIZE_T i;
  122920. +
  122921. + gcmkHEADER_ARG("Event=0x%x", Event);
  122922. +
  122923. + /* Verify the arguments. */
  122924. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122925. + gcmkVERIFY_ARGUMENT(IsEmpty != gcvNULL);
  122926. +
  122927. + /* Assume the event queue is empty. */
  122928. + *IsEmpty = gcvTRUE;
  122929. +
  122930. + /* Try acquiring the mutex. */
  122931. + status = gckOS_AcquireMutex(Event->os, Event->eventQueueMutex, 0);
  122932. + if (status == gcvSTATUS_TIMEOUT)
  122933. + {
  122934. + /* Timeout - queue is no longer empty. */
  122935. + *IsEmpty = gcvFALSE;
  122936. + }
  122937. + else
  122938. + {
  122939. + /* Bail out on error. */
  122940. + gcmkONERROR(status);
  122941. +
  122942. + /* Walk the event queue. */
  122943. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  122944. + {
  122945. + /* Check whether this event is in use. */
  122946. + if (Event->queues[i].head != gcvNULL)
  122947. + {
  122948. + /* The event is in use, hence the queue is not empty. */
  122949. + *IsEmpty = gcvFALSE;
  122950. + break;
  122951. + }
  122952. + }
  122953. +
  122954. + /* Release the mutex. */
  122955. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  122956. + }
  122957. +
  122958. + /* Success. */
  122959. + gcmkFOOTER_ARG("*IsEmpty=%d", gcmOPT_VALUE(IsEmpty));
  122960. + return gcvSTATUS_OK;
  122961. +
  122962. +OnError:
  122963. + /* Return the status. */
  122964. + gcmkFOOTER();
  122965. + return status;
  122966. +}
  122967. +
  122968. +static gceSTATUS
  122969. +_TryToIdleGPU(
  122970. + IN gckEVENT Event
  122971. +)
  122972. +{
  122973. + gceSTATUS status;
  122974. + gctBOOL empty = gcvFALSE, idle = gcvFALSE;
  122975. + gctBOOL powerLocked = gcvFALSE;
  122976. + gckHARDWARE hardware;
  122977. +
  122978. + gcmkHEADER_ARG("Event=0x%x", Event);
  122979. +
  122980. + /* Verify the arguments. */
  122981. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  122982. +
  122983. + /* Grab gckHARDWARE object. */
  122984. + hardware = Event->kernel->hardware;
  122985. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  122986. +
  122987. + /* Check whether the event queue is empty. */
  122988. + gcmkONERROR(gckEVENT_IsEmpty(Event, &empty));
  122989. +
  122990. + if (empty)
  122991. + {
  122992. + status = gckOS_AcquireMutex(hardware->os, hardware->powerMutex, 0);
  122993. + if (status == gcvSTATUS_TIMEOUT)
  122994. + {
  122995. + gcmkFOOTER_NO();
  122996. + return gcvSTATUS_OK;
  122997. + }
  122998. +
  122999. + powerLocked = gcvTRUE;
  123000. +
  123001. + /* Query whether the hardware is idle. */
  123002. + gcmkONERROR(gckHARDWARE_QueryIdle(Event->kernel->hardware, &idle));
  123003. +
  123004. + gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
  123005. + powerLocked = gcvFALSE;
  123006. +
  123007. + if (idle)
  123008. + {
  123009. + /* Inform the system of idle GPU. */
  123010. + gcmkONERROR(gckOS_Broadcast(Event->os,
  123011. + Event->kernel->hardware,
  123012. + gcvBROADCAST_GPU_IDLE));
  123013. + }
  123014. + }
  123015. +
  123016. + gcmkFOOTER_NO();
  123017. + return gcvSTATUS_OK;
  123018. +
  123019. +OnError:
  123020. + if (powerLocked)
  123021. + {
  123022. + gcmkONERROR(gckOS_ReleaseMutex(hardware->os, hardware->powerMutex));
  123023. + powerLocked = gcvFALSE;
  123024. + }
  123025. +
  123026. + gcmkFOOTER();
  123027. + return status;
  123028. +}
  123029. +
  123030. +static gceSTATUS
  123031. +__RemoveRecordFromProcessDB(
  123032. + IN gckEVENT Event,
  123033. + IN gcsEVENT_PTR Record
  123034. + )
  123035. +{
  123036. + gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
  123037. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  123038. +
  123039. + while (Record != gcvNULL)
  123040. + {
  123041. + if (Record->info.command == gcvHAL_SIGNAL)
  123042. + {
  123043. + /* TODO: Find a better place to bind signal to hardware.*/
  123044. + gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
  123045. + gcmUINT64_TO_PTR(Record->info.u.Signal.signal),
  123046. + Event->kernel->hardware));
  123047. + }
  123048. +
  123049. + if (Record->fromKernel)
  123050. + {
  123051. + /* No need to check db if event is from kernel. */
  123052. + Record = Record->next;
  123053. + continue;
  123054. + }
  123055. +
  123056. + switch (Record->info.command)
  123057. + {
  123058. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  123059. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  123060. + Event->kernel,
  123061. + Record->processID,
  123062. + gcvDB_NON_PAGED,
  123063. + gcmUINT64_TO_PTR(Record->info.u.FreeNonPagedMemory.logical)));
  123064. + break;
  123065. +
  123066. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  123067. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  123068. + Event->kernel,
  123069. + Record->processID,
  123070. + gcvDB_CONTIGUOUS,
  123071. + gcmUINT64_TO_PTR(Record->info.u.FreeContiguousMemory.logical)));
  123072. + break;
  123073. +
  123074. + case gcvHAL_FREE_VIDEO_MEMORY:
  123075. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  123076. + Event->kernel,
  123077. + Record->processID,
  123078. + gcvDB_VIDEO_MEMORY,
  123079. + gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node)));
  123080. +
  123081. + {
  123082. + gcuVIDMEM_NODE_PTR node = (gcuVIDMEM_NODE_PTR)(gcmUINT64_TO_PTR(Record->info.u.FreeVideoMemory.node));
  123083. +
  123084. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  123085. + {
  123086. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  123087. + Record->processID,
  123088. + gcvDB_VIDEO_MEMORY_RESERVED,
  123089. + node));
  123090. + }
  123091. + else if(node->Virtual.contiguous)
  123092. + {
  123093. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  123094. + Record->processID,
  123095. + gcvDB_VIDEO_MEMORY_CONTIGUOUS,
  123096. + node));
  123097. + }
  123098. + else
  123099. + {
  123100. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(Event->kernel,
  123101. + Record->processID,
  123102. + gcvDB_VIDEO_MEMORY_VIRTUAL,
  123103. + node));
  123104. + }
  123105. + }
  123106. +
  123107. + break;
  123108. +
  123109. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  123110. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  123111. + Event->kernel,
  123112. + Record->processID,
  123113. + gcvDB_VIDEO_MEMORY_LOCKED,
  123114. + gcmUINT64_TO_PTR(Record->info.u.UnlockVideoMemory.node)));
  123115. + break;
  123116. +
  123117. + case gcvHAL_UNMAP_USER_MEMORY:
  123118. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  123119. + Event->kernel,
  123120. + Record->processID,
  123121. + gcvDB_MAP_USER_MEMORY,
  123122. + gcmINT2PTR(Record->info.u.UnmapUserMemory.info)));
  123123. + break;
  123124. +
  123125. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  123126. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  123127. + Event->kernel,
  123128. + Record->processID,
  123129. + gcvDB_COMMAND_BUFFER,
  123130. + gcmUINT64_TO_PTR(Record->info.u.FreeVirtualCommandBuffer.logical)));
  123131. + break;
  123132. +
  123133. + default:
  123134. + break;
  123135. + }
  123136. +
  123137. + Record = Record->next;
  123138. + }
  123139. + gcmkFOOTER_NO();
  123140. + return gcvSTATUS_OK;
  123141. +}
  123142. +
  123143. +void
  123144. +_SubmitTimerFunction(
  123145. + gctPOINTER Data
  123146. + )
  123147. +{
  123148. + gckEVENT event = (gckEVENT)Data;
  123149. + gcmkVERIFY_OK(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));
  123150. +}
  123151. +
  123152. +/******************************************************************************\
  123153. +******************************* gckEVENT API Code *******************************
  123154. +\******************************************************************************/
  123155. +
  123156. +/*******************************************************************************
  123157. +**
  123158. +** gckEVENT_Construct
  123159. +**
  123160. +** Construct a new gckEVENT object.
  123161. +**
  123162. +** INPUT:
  123163. +**
  123164. +** gckKERNEL Kernel
  123165. +** Pointer to an gckKERNEL object.
  123166. +**
  123167. +** OUTPUT:
  123168. +**
  123169. +** gckEVENT * Event
  123170. +** Pointer to a variable that receives the gckEVENT object pointer.
  123171. +*/
  123172. +gceSTATUS
  123173. +gckEVENT_Construct(
  123174. + IN gckKERNEL Kernel,
  123175. + OUT gckEVENT * Event
  123176. + )
  123177. +{
  123178. + gckOS os;
  123179. + gceSTATUS status;
  123180. + gckEVENT eventObj = gcvNULL;
  123181. + int i;
  123182. + gcsEVENT_PTR record;
  123183. + gctPOINTER pointer = gcvNULL;
  123184. +
  123185. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  123186. +
  123187. + /* Verify the arguments. */
  123188. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  123189. + gcmkVERIFY_ARGUMENT(Event != gcvNULL);
  123190. +
  123191. + /* Extract the pointer to the gckOS object. */
  123192. + os = Kernel->os;
  123193. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  123194. +
  123195. + /* Allocate the gckEVENT object. */
  123196. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckEVENT), &pointer));
  123197. +
  123198. + eventObj = pointer;
  123199. +
  123200. + /* Reset the object. */
  123201. + gcmkVERIFY_OK(gckOS_ZeroMemory(eventObj, gcmSIZEOF(struct _gckEVENT)));
  123202. +
  123203. + /* Initialize the gckEVENT object. */
  123204. + eventObj->object.type = gcvOBJ_EVENT;
  123205. + eventObj->kernel = Kernel;
  123206. + eventObj->os = os;
  123207. +
  123208. + /* Create the mutexes. */
  123209. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventQueueMutex));
  123210. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->freeEventMutex));
  123211. + gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventListMutex));
  123212. +
  123213. + /* Create a bunch of event reccords. */
  123214. + for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
  123215. + {
  123216. + /* Allocate an event record. */
  123217. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsEVENT), &pointer));
  123218. +
  123219. + record = pointer;
  123220. +
  123221. + /* Push it on the free list. */
  123222. + record->next = eventObj->freeEventList;
  123223. + eventObj->freeEventList = record;
  123224. + eventObj->freeEventCount += 1;
  123225. + }
  123226. +
  123227. + /* Initialize the free list of event queues. */
  123228. + for (i = 0; i < gcdREPO_LIST_COUNT; i += 1)
  123229. + {
  123230. + eventObj->repoList[i].next = eventObj->freeList;
  123231. + eventObj->freeList = &eventObj->repoList[i];
  123232. + }
  123233. +
  123234. + /* Construct the atom. */
  123235. + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->freeAtom));
  123236. + gcmkONERROR(gckOS_AtomSet(os,
  123237. + eventObj->freeAtom,
  123238. + gcmCOUNTOF(eventObj->queues)));
  123239. +
  123240. +#if gcdSMP
  123241. + gcmkONERROR(gckOS_AtomConstruct(os, &eventObj->pending));
  123242. +#endif
  123243. +
  123244. + gcmkVERIFY_OK(gckOS_CreateTimer(os,
  123245. + _SubmitTimerFunction,
  123246. + (gctPOINTER)eventObj,
  123247. + &eventObj->submitTimer));
  123248. +
  123249. + /* Return pointer to the gckEVENT object. */
  123250. + *Event = eventObj;
  123251. +
  123252. + /* Success. */
  123253. + gcmkFOOTER_ARG("*Event=0x%x", *Event);
  123254. + return gcvSTATUS_OK;
  123255. +
  123256. +OnError:
  123257. + /* Roll back. */
  123258. + if (eventObj != gcvNULL)
  123259. + {
  123260. + if (eventObj->eventQueueMutex != gcvNULL)
  123261. + {
  123262. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventQueueMutex));
  123263. + }
  123264. +
  123265. + if (eventObj->freeEventMutex != gcvNULL)
  123266. + {
  123267. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->freeEventMutex));
  123268. + }
  123269. +
  123270. + if (eventObj->eventListMutex != gcvNULL)
  123271. + {
  123272. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, eventObj->eventListMutex));
  123273. + }
  123274. +
  123275. + while (eventObj->freeEventList != gcvNULL)
  123276. + {
  123277. + record = eventObj->freeEventList;
  123278. + eventObj->freeEventList = record->next;
  123279. +
  123280. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, record));
  123281. + }
  123282. +
  123283. + if (eventObj->freeAtom != gcvNULL)
  123284. + {
  123285. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->freeAtom));
  123286. + }
  123287. +
  123288. +#if gcdSMP
  123289. + if (eventObj->pending != gcvNULL)
  123290. + {
  123291. + gcmkVERIFY_OK(gckOS_AtomDestroy(os, eventObj->pending));
  123292. + }
  123293. +#endif
  123294. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, eventObj));
  123295. + }
  123296. +
  123297. + /* Return the status. */
  123298. + gcmkFOOTER();
  123299. + return status;
  123300. +}
  123301. +
  123302. +/*******************************************************************************
  123303. +**
  123304. +** gckEVENT_Destroy
  123305. +**
  123306. +** Destroy an gckEVENT object.
  123307. +**
  123308. +** INPUT:
  123309. +**
  123310. +** gckEVENT Event
  123311. +** Pointer to an gckEVENT object.
  123312. +**
  123313. +** OUTPUT:
  123314. +**
  123315. +** Nothing.
  123316. +*/
  123317. +gceSTATUS
  123318. +gckEVENT_Destroy(
  123319. + IN gckEVENT Event
  123320. + )
  123321. +{
  123322. + gcsEVENT_PTR record;
  123323. + gcsEVENT_QUEUE_PTR queue;
  123324. +
  123325. + gcmkHEADER_ARG("Event=0x%x", Event);
  123326. +
  123327. + /* Verify the arguments. */
  123328. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123329. +
  123330. + if (Event->submitTimer != gcvNULL)
  123331. + {
  123332. + gcmkVERIFY_OK(gckOS_StopTimer(Event->os, Event->submitTimer));
  123333. + gcmkVERIFY_OK(gckOS_DestroyTimer(Event->os, Event->submitTimer));
  123334. + }
  123335. +
  123336. + /* Delete the queue mutex. */
  123337. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventQueueMutex));
  123338. +
  123339. + /* Free all free events. */
  123340. + while (Event->freeEventList != gcvNULL)
  123341. + {
  123342. + record = Event->freeEventList;
  123343. + Event->freeEventList = record->next;
  123344. +
  123345. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
  123346. + }
  123347. +
  123348. + /* Delete the free mutex. */
  123349. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->freeEventMutex));
  123350. +
  123351. + /* Free all pending queues. */
  123352. + while (Event->queueHead != gcvNULL)
  123353. + {
  123354. + /* Get the current queue. */
  123355. + queue = Event->queueHead;
  123356. +
  123357. + /* Free all pending events. */
  123358. + while (queue->head != gcvNULL)
  123359. + {
  123360. + record = queue->head;
  123361. + queue->head = record->next;
  123362. +
  123363. + gcmkTRACE_ZONE_N(
  123364. + gcvLEVEL_WARNING, gcvZONE_EVENT,
  123365. + gcmSIZEOF(record) + gcmSIZEOF(queue->source),
  123366. + "Event record 0x%x is still pending for %d.",
  123367. + record, queue->source
  123368. + );
  123369. +
  123370. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, record));
  123371. + }
  123372. +
  123373. + /* Remove the top queue from the list. */
  123374. + if (Event->queueHead == Event->queueTail)
  123375. + {
  123376. + Event->queueHead =
  123377. + Event->queueTail = gcvNULL;
  123378. + }
  123379. + else
  123380. + {
  123381. + Event->queueHead = Event->queueHead->next;
  123382. + }
  123383. +
  123384. + /* Free the queue. */
  123385. + gcmkVERIFY_OK(gckEVENT_FreeQueue(Event, queue));
  123386. + }
  123387. +
  123388. + /* Delete the list mutex. */
  123389. + gcmkVERIFY_OK(gckOS_DeleteMutex(Event->os, Event->eventListMutex));
  123390. +
  123391. + /* Delete the atom. */
  123392. + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->freeAtom));
  123393. +
  123394. +#if gcdSMP
  123395. + gcmkVERIFY_OK(gckOS_AtomDestroy(Event->os, Event->pending));
  123396. +#endif
  123397. +
  123398. + /* Mark the gckEVENT object as unknown. */
  123399. + Event->object.type = gcvOBJ_UNKNOWN;
  123400. +
  123401. + /* Free the gckEVENT object. */
  123402. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Event->os, Event));
  123403. +
  123404. + /* Success. */
  123405. + gcmkFOOTER_NO();
  123406. + return gcvSTATUS_OK;
  123407. +}
  123408. +
  123409. +/*******************************************************************************
  123410. +**
  123411. +** gckEVENT_GetEvent
  123412. +**
  123413. +** Reserve the next available hardware event.
  123414. +**
  123415. +** INPUT:
  123416. +**
  123417. +** gckEVENT Event
  123418. +** Pointer to an gckEVENT object.
  123419. +**
  123420. +** gctBOOL Wait
  123421. +** Set to gcvTRUE to force the function to wait if no events are
  123422. +** immediately available.
  123423. +**
  123424. +** gceKERNEL_WHERE Source
  123425. +** Source of the event.
  123426. +**
  123427. +** OUTPUT:
  123428. +**
  123429. +** gctUINT8 * EventID
  123430. +** Reserved event ID.
  123431. +*/
  123432. +static gceSTATUS
  123433. +gckEVENT_GetEvent(
  123434. + IN gckEVENT Event,
  123435. + IN gctBOOL Wait,
  123436. + OUT gctUINT8 * EventID,
  123437. + IN gcsEVENT_PTR Head,
  123438. + IN gceKERNEL_WHERE Source
  123439. + )
  123440. +{
  123441. + gctINT i, id;
  123442. + gceSTATUS status;
  123443. + gctBOOL acquired = gcvFALSE;
  123444. + gctINT32 free;
  123445. +
  123446. +#if gcdGPU_TIMEOUT
  123447. + gctUINT32 timer = 0;
  123448. +#endif
  123449. +
  123450. + gcmkHEADER_ARG("Event=0x%x Head=%p Source=%d", Event, Head, Source);
  123451. +
  123452. + while (gcvTRUE)
  123453. + {
  123454. + /* Grab the queue mutex. */
  123455. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  123456. + Event->eventQueueMutex,
  123457. + gcvINFINITE));
  123458. + acquired = gcvTRUE;
  123459. +
  123460. + /* Walk through all events. */
  123461. + id = Event->lastID;
  123462. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  123463. + {
  123464. + gctINT nextID = gckMATH_ModuloInt((id + 1),
  123465. + gcmCOUNTOF(Event->queues));
  123466. +
  123467. + if (Event->queues[id].head == gcvNULL)
  123468. + {
  123469. + *EventID = (gctUINT8) id;
  123470. +
  123471. + Event->lastID = (gctUINT8) nextID;
  123472. +
  123473. + /* Save time stamp of event. */
  123474. + Event->queues[id].stamp = ++(Event->stamp);
  123475. + Event->queues[id].head = Head;
  123476. + Event->queues[id].source = Source;
  123477. +
  123478. + gcmkONERROR(gckOS_AtomDecrement(Event->os,
  123479. + Event->freeAtom,
  123480. + &free));
  123481. +#if gcdDYNAMIC_SPEED
  123482. + if (free <= gcdDYNAMIC_EVENT_THRESHOLD)
  123483. + {
  123484. + gcmkONERROR(gckOS_BroadcastHurry(
  123485. + Event->os,
  123486. + Event->kernel->hardware,
  123487. + gcdDYNAMIC_EVENT_THRESHOLD - free));
  123488. + }
  123489. +#endif
  123490. +
  123491. + /* Release the queue mutex. */
  123492. + gcmkONERROR(gckOS_ReleaseMutex(Event->os,
  123493. + Event->eventQueueMutex));
  123494. +
  123495. + /* Success. */
  123496. + gcmkTRACE_ZONE_N(
  123497. + gcvLEVEL_INFO, gcvZONE_EVENT,
  123498. + gcmSIZEOF(id),
  123499. + "Using id=%d",
  123500. + id
  123501. + );
  123502. +
  123503. + gcmkFOOTER_ARG("*EventID=%u", *EventID);
  123504. + return gcvSTATUS_OK;
  123505. + }
  123506. +
  123507. + id = nextID;
  123508. + }
  123509. +
  123510. +#if gcdDYNAMIC_SPEED
  123511. + /* No free events, speed up the GPU right now! */
  123512. + gcmkONERROR(gckOS_BroadcastHurry(Event->os,
  123513. + Event->kernel->hardware,
  123514. + gcdDYNAMIC_EVENT_THRESHOLD));
  123515. +#endif
  123516. +
  123517. + /* Release the queue mutex. */
  123518. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  123519. + acquired = gcvFALSE;
  123520. +
  123521. + /* Fail if wait is not requested. */
  123522. + if (!Wait)
  123523. + {
  123524. + /* Out of resources. */
  123525. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  123526. + }
  123527. +
  123528. + /* Delay a while. */
  123529. + gcmkONERROR(gckOS_Delay(Event->os, 1));
  123530. +
  123531. +#if gcdGPU_TIMEOUT
  123532. + /* Increment the wait timer. */
  123533. + timer += 1;
  123534. +
  123535. + if (timer == Event->kernel->timeOut)
  123536. + {
  123537. + /* Try to call any outstanding events. */
  123538. + gcmkONERROR(gckHARDWARE_Interrupt(Event->kernel->hardware,
  123539. + gcvTRUE));
  123540. + }
  123541. + else if (timer > Event->kernel->timeOut)
  123542. + {
  123543. + gcmkTRACE_N(
  123544. + gcvLEVEL_ERROR,
  123545. + gcmSIZEOF(gctCONST_STRING) + gcmSIZEOF(gctINT),
  123546. + "%s(%d): no available events\n",
  123547. + __FUNCTION__, __LINE__
  123548. + );
  123549. +
  123550. + /* Bail out. */
  123551. + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
  123552. + }
  123553. +#endif
  123554. + }
  123555. +
  123556. +OnError:
  123557. + if (acquired)
  123558. + {
  123559. + /* Release the queue mutex. */
  123560. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  123561. + }
  123562. +
  123563. + /* Return the status. */
  123564. + gcmkFOOTER();
  123565. + return status;
  123566. +}
  123567. +
  123568. +/*******************************************************************************
  123569. +**
  123570. +** gckEVENT_AllocateRecord
  123571. +**
  123572. +** Allocate a record for the new event.
  123573. +**
  123574. +** INPUT:
  123575. +**
  123576. +** gckEVENT Event
  123577. +** Pointer to an gckEVENT object.
  123578. +**
  123579. +** gctBOOL AllocateAllowed
  123580. +** State for allocation if out of free events.
  123581. +**
  123582. +** OUTPUT:
  123583. +**
  123584. +** gcsEVENT_PTR * Record
  123585. +** Allocated event record.
  123586. +*/
  123587. +gceSTATUS
  123588. +gckEVENT_AllocateRecord(
  123589. + IN gckEVENT Event,
  123590. + IN gctBOOL AllocateAllowed,
  123591. + OUT gcsEVENT_PTR * Record
  123592. + )
  123593. +{
  123594. + gceSTATUS status;
  123595. + gctBOOL acquired = gcvFALSE;
  123596. + gctINT i;
  123597. + gcsEVENT_PTR record;
  123598. + gctPOINTER pointer = gcvNULL;
  123599. +
  123600. + gcmkHEADER_ARG("Event=0x%x AllocateAllowed=%d", Event, AllocateAllowed);
  123601. +
  123602. + /* Verify the arguments. */
  123603. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123604. + gcmkVERIFY_ARGUMENT(Record != gcvNULL);
  123605. +
  123606. + /* Acquire the mutex. */
  123607. + gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->freeEventMutex, gcvINFINITE));
  123608. + acquired = gcvTRUE;
  123609. +
  123610. + /* Test if we are below the allocation threshold. */
  123611. + if ( (AllocateAllowed && (Event->freeEventCount < gcdEVENT_MIN_THRESHOLD)) ||
  123612. + (Event->freeEventCount == 0) )
  123613. + {
  123614. + /* Allocate a bunch of records. */
  123615. + for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
  123616. + {
  123617. + /* Allocate an event record. */
  123618. + gcmkONERROR(gckOS_Allocate(Event->os,
  123619. + gcmSIZEOF(gcsEVENT),
  123620. + &pointer));
  123621. +
  123622. + record = pointer;
  123623. +
  123624. + /* Push it on the free list. */
  123625. + record->next = Event->freeEventList;
  123626. + Event->freeEventList = record;
  123627. + Event->freeEventCount += 1;
  123628. + }
  123629. + }
  123630. +
  123631. + *Record = Event->freeEventList;
  123632. + Event->freeEventList = Event->freeEventList->next;
  123633. + Event->freeEventCount -= 1;
  123634. +
  123635. + /* Release the mutex. */
  123636. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  123637. + acquired = gcvFALSE;
  123638. +
  123639. + /* Success. */
  123640. + gcmkFOOTER_ARG("*Record=0x%x", gcmOPT_POINTER(Record));
  123641. + return gcvSTATUS_OK;
  123642. +
  123643. +OnError:
  123644. + /* Roll back. */
  123645. + if (acquired)
  123646. + {
  123647. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
  123648. + }
  123649. +
  123650. + /* Return the status. */
  123651. + gcmkFOOTER();
  123652. + return status;
  123653. +}
  123654. +
  123655. +/*******************************************************************************
  123656. +**
  123657. +** gckEVENT_AddList
  123658. +**
  123659. +** Add a new event to the list of events.
  123660. +**
  123661. +** INPUT:
  123662. +**
  123663. +** gckEVENT Event
  123664. +** Pointer to an gckEVENT object.
  123665. +**
  123666. +** gcsHAL_INTERFACE_PTR Interface
  123667. +** Pointer to the interface for the event to be added.
  123668. +**
  123669. +** gceKERNEL_WHERE FromWhere
  123670. +** Place in the pipe where the event needs to be generated.
  123671. +**
  123672. +** gctBOOL AllocateAllowed
  123673. +** State for allocation if out of free events.
  123674. +**
  123675. +** OUTPUT:
  123676. +**
  123677. +** Nothing.
  123678. +*/
  123679. +gceSTATUS
  123680. +gckEVENT_AddList(
  123681. + IN gckEVENT Event,
  123682. + IN gcsHAL_INTERFACE_PTR Interface,
  123683. + IN gceKERNEL_WHERE FromWhere,
  123684. + IN gctBOOL AllocateAllowed,
  123685. + IN gctBOOL FromKernel
  123686. + )
  123687. +{
  123688. + gceSTATUS status;
  123689. + gctBOOL acquired = gcvFALSE;
  123690. + gcsEVENT_PTR record = gcvNULL;
  123691. + gcsEVENT_QUEUE_PTR queue;
  123692. + gckKERNEL kernel = Event->kernel;
  123693. +
  123694. + gcmkHEADER_ARG("Event=0x%x Interface=0x%x",
  123695. + Event, Interface);
  123696. +
  123697. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, _GC_OBJ_ZONE,
  123698. + "FromWhere=%d AllocateAllowed=%d",
  123699. + FromWhere, AllocateAllowed);
  123700. +
  123701. + /* Verify the arguments. */
  123702. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123703. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  123704. +
  123705. + /* Verify the event command. */
  123706. + gcmkASSERT
  123707. + ( (Interface->command == gcvHAL_FREE_NON_PAGED_MEMORY)
  123708. + || (Interface->command == gcvHAL_FREE_CONTIGUOUS_MEMORY)
  123709. + || (Interface->command == gcvHAL_FREE_VIDEO_MEMORY)
  123710. + || (Interface->command == gcvHAL_WRITE_DATA)
  123711. + || (Interface->command == gcvHAL_UNLOCK_VIDEO_MEMORY)
  123712. + || (Interface->command == gcvHAL_SIGNAL)
  123713. + || (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
  123714. + || (Interface->command == gcvHAL_TIMESTAMP)
  123715. + || (Interface->command == gcvHAL_COMMIT_DONE)
  123716. + || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
  123717. + || (Interface->command == gcvHAL_SYNC_POINT)
  123718. + );
  123719. +
  123720. + /* Validate the source. */
  123721. + if ((FromWhere != gcvKERNEL_COMMAND) && (FromWhere != gcvKERNEL_PIXEL))
  123722. + {
  123723. + /* Invalid argument. */
  123724. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  123725. + }
  123726. +
  123727. + /* Allocate a free record. */
  123728. + gcmkONERROR(gckEVENT_AllocateRecord(Event, AllocateAllowed, &record));
  123729. +
  123730. + /* Termninate the record. */
  123731. + record->next = gcvNULL;
  123732. +
  123733. + /* Record the committer. */
  123734. + record->fromKernel = FromKernel;
  123735. +
  123736. + /* Copy the event interface into the record. */
  123737. + gckOS_MemCopy(&record->info, Interface, gcmSIZEOF(record->info));
  123738. +
  123739. + /* Get process ID. */
  123740. + gcmkONERROR(gckOS_GetProcessID(&record->processID));
  123741. +
  123742. +#ifdef __QNXNTO__
  123743. + record->kernel = Event->kernel;
  123744. +#endif
  123745. +
  123746. + gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
  123747. +
  123748. + /* Acquire the mutex. */
  123749. + gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
  123750. + acquired = gcvTRUE;
  123751. +
  123752. + /* Do we need to allocate a new queue? */
  123753. + if ((Event->queueTail == gcvNULL) || (Event->queueTail->source < FromWhere))
  123754. + {
  123755. + /* Allocate a new queue. */
  123756. + gcmkONERROR(gckEVENT_AllocateQueue(Event, &queue));
  123757. +
  123758. + /* Initialize the queue. */
  123759. + queue->source = FromWhere;
  123760. + queue->head = gcvNULL;
  123761. + queue->next = gcvNULL;
  123762. +
  123763. + /* Attach it to the list of allocated queues. */
  123764. + if (Event->queueTail == gcvNULL)
  123765. + {
  123766. + Event->queueHead =
  123767. + Event->queueTail = queue;
  123768. + }
  123769. + else
  123770. + {
  123771. + Event->queueTail->next = queue;
  123772. + Event->queueTail = queue;
  123773. + }
  123774. + }
  123775. + else
  123776. + {
  123777. + queue = Event->queueTail;
  123778. + }
  123779. +
  123780. + /* Attach the record to the queue. */
  123781. + if (queue->head == gcvNULL)
  123782. + {
  123783. + queue->head = record;
  123784. + queue->tail = record;
  123785. + }
  123786. + else
  123787. + {
  123788. + queue->tail->next = record;
  123789. + queue->tail = record;
  123790. + }
  123791. +
  123792. + /* Unmap user space logical address.
  123793. + * Linux kernel does not support unmap the memory of other process any more since 3.5.
  123794. + * Let's unmap memory of self process before submit the event to gpu.
  123795. + * */
  123796. + switch(Interface->command)
  123797. + {
  123798. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  123799. + gcmkONERROR(gckOS_UnmapUserLogical(
  123800. + Event->os,
  123801. + gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical),
  123802. + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
  123803. + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
  123804. + break;
  123805. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  123806. + gcmkONERROR(gckOS_UnmapUserLogical(
  123807. + Event->os,
  123808. + gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical),
  123809. + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
  123810. + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
  123811. + break;
  123812. + default:
  123813. + break;
  123814. + }
  123815. +
  123816. +
  123817. + /* Release the mutex. */
  123818. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  123819. +
  123820. + /* Success. */
  123821. + gcmkFOOTER_NO();
  123822. + return gcvSTATUS_OK;
  123823. +
  123824. +OnError:
  123825. + /* Roll back. */
  123826. + if (acquired)
  123827. + {
  123828. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  123829. + }
  123830. +
  123831. + if (record != gcvNULL)
  123832. + {
  123833. + gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
  123834. + }
  123835. +
  123836. + /* Return the status. */
  123837. + gcmkFOOTER();
  123838. + return status;
  123839. +}
  123840. +
  123841. +/*******************************************************************************
  123842. +**
  123843. +** gckEVENT_Unlock
  123844. +**
  123845. +** Schedule an event to unlock virtual memory.
  123846. +**
  123847. +** INPUT:
  123848. +**
  123849. +** gckEVENT Event
  123850. +** Pointer to an gckEVENT object.
  123851. +**
  123852. +** gceKERNEL_WHERE FromWhere
  123853. +** Place in the pipe where the event needs to be generated.
  123854. +**
  123855. +** gcuVIDMEM_NODE_PTR Node
  123856. +** Pointer to a gcuVIDMEM_NODE union that specifies the virtual memory
  123857. +** to unlock.
  123858. +**
  123859. +** gceSURF_TYPE Type
  123860. +** Type of surface to unlock.
  123861. +**
  123862. +** OUTPUT:
  123863. +**
  123864. +** Nothing.
  123865. +*/
  123866. +gceSTATUS
  123867. +gckEVENT_Unlock(
  123868. + IN gckEVENT Event,
  123869. + IN gceKERNEL_WHERE FromWhere,
  123870. + IN gcuVIDMEM_NODE_PTR Node,
  123871. + IN gceSURF_TYPE Type
  123872. + )
  123873. +{
  123874. + gceSTATUS status;
  123875. + gcsHAL_INTERFACE iface;
  123876. +
  123877. + gcmkHEADER_ARG("Event=0x%x FromWhere=%d Node=0x%x Type=%d",
  123878. + Event, FromWhere, Node, Type);
  123879. +
  123880. + /* Verify the arguments. */
  123881. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123882. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  123883. +
  123884. + /* Mark the event as an unlock. */
  123885. + iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
  123886. + iface.u.UnlockVideoMemory.node = gcmPTR_TO_UINT64(Node);
  123887. + iface.u.UnlockVideoMemory.type = Type;
  123888. + iface.u.UnlockVideoMemory.asynchroneous = 0;
  123889. +
  123890. + /* Append it to the queue. */
  123891. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  123892. +
  123893. + /* Success. */
  123894. + gcmkFOOTER_NO();
  123895. + return gcvSTATUS_OK;
  123896. +
  123897. +OnError:
  123898. + /* Return the status. */
  123899. + gcmkFOOTER();
  123900. + return status;
  123901. +}
  123902. +
  123903. +/*******************************************************************************
  123904. +**
  123905. +** gckEVENT_FreeVideoMemory
  123906. +**
  123907. +** Schedule an event to free video memory.
  123908. +**
  123909. +** INPUT:
  123910. +**
  123911. +** gckEVENT Event
  123912. +** Pointer to an gckEVENT object.
  123913. +**
  123914. +** gcuVIDMEM_NODE_PTR VideoMemory
  123915. +** Pointer to a gcuVIDMEM_NODE object to free.
  123916. +**
  123917. +** gceKERNEL_WHERE FromWhere
  123918. +** Place in the pipe where the event needs to be generated.
  123919. +**
  123920. +** OUTPUT:
  123921. +**
  123922. +** Nothing.
  123923. +*/
  123924. +gceSTATUS
  123925. +gckEVENT_FreeVideoMemory(
  123926. + IN gckEVENT Event,
  123927. + IN gcuVIDMEM_NODE_PTR VideoMemory,
  123928. + IN gceKERNEL_WHERE FromWhere
  123929. + )
  123930. +{
  123931. + gceSTATUS status;
  123932. + gcsHAL_INTERFACE iface;
  123933. +
  123934. + gcmkHEADER_ARG("Event=0x%x VideoMemory=0x%x FromWhere=%d",
  123935. + Event, VideoMemory, FromWhere);
  123936. +
  123937. + /* Verify the arguments. */
  123938. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  123939. + gcmkVERIFY_ARGUMENT(VideoMemory != gcvNULL);
  123940. +
  123941. + /* Create an event. */
  123942. + iface.command = gcvHAL_FREE_VIDEO_MEMORY;
  123943. + iface.u.FreeVideoMemory.node = gcmPTR_TO_UINT64(VideoMemory);
  123944. +
  123945. + /* Append it to the queue. */
  123946. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  123947. +
  123948. + /* Success. */
  123949. + gcmkFOOTER_NO();
  123950. + return gcvSTATUS_OK;
  123951. +
  123952. +OnError:
  123953. + /* Return the status. */
  123954. + gcmkFOOTER();
  123955. + return status;
  123956. +}
  123957. +
  123958. +/*******************************************************************************
  123959. +**
  123960. +** gckEVENT_FreeNonPagedMemory
  123961. +**
  123962. +** Schedule an event to free non-paged memory.
  123963. +**
  123964. +** INPUT:
  123965. +**
  123966. +** gckEVENT Event
  123967. +** Pointer to an gckEVENT object.
  123968. +**
  123969. +** gctSIZE_T Bytes
  123970. +** Number of bytes of non-paged memory to free.
  123971. +**
  123972. +** gctPHYS_ADDR Physical
  123973. +** Physical address of non-paged memory to free.
  123974. +**
  123975. +** gctPOINTER Logical
  123976. +** Logical address of non-paged memory to free.
  123977. +**
  123978. +** gceKERNEL_WHERE FromWhere
  123979. +** Place in the pipe where the event needs to be generated.
  123980. +*/
  123981. +gceSTATUS
  123982. +gckEVENT_FreeNonPagedMemory(
  123983. + IN gckEVENT Event,
  123984. + IN gctSIZE_T Bytes,
  123985. + IN gctPHYS_ADDR Physical,
  123986. + IN gctPOINTER Logical,
  123987. + IN gceKERNEL_WHERE FromWhere
  123988. + )
  123989. +{
  123990. + gceSTATUS status;
  123991. + gcsHAL_INTERFACE iface;
  123992. + gckKERNEL kernel = Event->kernel;
  123993. +
  123994. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  123995. + "FromWhere=%d",
  123996. + Event, Bytes, Physical, Logical, FromWhere);
  123997. +
  123998. + /* Verify the arguments. */
  123999. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124000. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  124001. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  124002. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  124003. +
  124004. + /* Create an event. */
  124005. + iface.command = gcvHAL_FREE_NON_PAGED_MEMORY;
  124006. + iface.u.FreeNonPagedMemory.bytes = Bytes;
  124007. + iface.u.FreeNonPagedMemory.physical = gcmPTR_TO_NAME(Physical);
  124008. + iface.u.FreeNonPagedMemory.logical = gcmPTR_TO_UINT64(Logical);
  124009. +
  124010. + /* Append it to the queue. */
  124011. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  124012. +
  124013. + /* Success. */
  124014. + gcmkFOOTER_NO();
  124015. + return gcvSTATUS_OK;
  124016. +
  124017. +OnError:
  124018. + /* Return the status. */
  124019. + gcmkFOOTER();
  124020. + return status;
  124021. +}
  124022. +
  124023. +gceSTATUS
  124024. +gckEVENT_DestroyVirtualCommandBuffer(
  124025. + IN gckEVENT Event,
  124026. + IN gctSIZE_T Bytes,
  124027. + IN gctPHYS_ADDR Physical,
  124028. + IN gctPOINTER Logical,
  124029. + IN gceKERNEL_WHERE FromWhere
  124030. + )
  124031. +{
  124032. + gceSTATUS status;
  124033. + gcsHAL_INTERFACE iface;
  124034. + gckKERNEL kernel = Event->kernel;
  124035. +
  124036. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  124037. + "FromWhere=%d",
  124038. + Event, Bytes, Physical, Logical, FromWhere);
  124039. +
  124040. + /* Verify the arguments. */
  124041. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124042. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  124043. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  124044. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  124045. +
  124046. + /* Create an event. */
  124047. + iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER;
  124048. + iface.u.FreeVirtualCommandBuffer.bytes = Bytes;
  124049. + iface.u.FreeVirtualCommandBuffer.physical = gcmPTR_TO_NAME(Physical);
  124050. + iface.u.FreeVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(Logical);
  124051. +
  124052. + /* Append it to the queue. */
  124053. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  124054. +
  124055. + /* Success. */
  124056. + gcmkFOOTER_NO();
  124057. + return gcvSTATUS_OK;
  124058. +
  124059. +OnError:
  124060. + /* Return the status. */
  124061. + gcmkFOOTER();
  124062. + return status;
  124063. +}
  124064. +
  124065. +/*******************************************************************************
  124066. +**
  124067. +** gckEVENT_FreeContigiuousMemory
  124068. +**
  124069. +** Schedule an event to free contiguous memory.
  124070. +**
  124071. +** INPUT:
  124072. +**
  124073. +** gckEVENT Event
  124074. +** Pointer to an gckEVENT object.
  124075. +**
  124076. +** gctSIZE_T Bytes
  124077. +** Number of bytes of contiguous memory to free.
  124078. +**
  124079. +** gctPHYS_ADDR Physical
  124080. +** Physical address of contiguous memory to free.
  124081. +**
  124082. +** gctPOINTER Logical
  124083. +** Logical address of contiguous memory to free.
  124084. +**
  124085. +** gceKERNEL_WHERE FromWhere
  124086. +** Place in the pipe where the event needs to be generated.
  124087. +*/
  124088. +gceSTATUS
  124089. +gckEVENT_FreeContiguousMemory(
  124090. + IN gckEVENT Event,
  124091. + IN gctSIZE_T Bytes,
  124092. + IN gctPHYS_ADDR Physical,
  124093. + IN gctPOINTER Logical,
  124094. + IN gceKERNEL_WHERE FromWhere
  124095. + )
  124096. +{
  124097. + gceSTATUS status;
  124098. + gcsHAL_INTERFACE iface;
  124099. + gckKERNEL kernel = Event->kernel;
  124100. +
  124101. + gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
  124102. + "FromWhere=%d",
  124103. + Event, Bytes, Physical, Logical, FromWhere);
  124104. +
  124105. + /* Verify the arguments. */
  124106. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124107. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  124108. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  124109. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  124110. +
  124111. + /* Create an event. */
  124112. + iface.command = gcvHAL_FREE_CONTIGUOUS_MEMORY;
  124113. + iface.u.FreeContiguousMemory.bytes = Bytes;
  124114. + iface.u.FreeContiguousMemory.physical = gcmPTR_TO_NAME(Physical);
  124115. + iface.u.FreeContiguousMemory.logical = gcmPTR_TO_UINT64(Logical);
  124116. +
  124117. + /* Append it to the queue. */
  124118. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  124119. +
  124120. + /* Success. */
  124121. + gcmkFOOTER_NO();
  124122. + return gcvSTATUS_OK;
  124123. +
  124124. +OnError:
  124125. + /* Return the status. */
  124126. + gcmkFOOTER();
  124127. + return status;
  124128. +}
  124129. +
  124130. +/*******************************************************************************
  124131. +**
  124132. +** gckEVENT_Signal
  124133. +**
  124134. +** Schedule an event to trigger a signal.
  124135. +**
  124136. +** INPUT:
  124137. +**
  124138. +** gckEVENT Event
  124139. +** Pointer to an gckEVENT object.
  124140. +**
  124141. +** gctSIGNAL Signal
  124142. +** Pointer to the signal to trigger.
  124143. +**
  124144. +** gceKERNEL_WHERE FromWhere
  124145. +** Place in the pipe where the event needs to be generated.
  124146. +**
  124147. +** OUTPUT:
  124148. +**
  124149. +** Nothing.
  124150. +*/
  124151. +gceSTATUS
  124152. +gckEVENT_Signal(
  124153. + IN gckEVENT Event,
  124154. + IN gctSIGNAL Signal,
  124155. + IN gceKERNEL_WHERE FromWhere
  124156. + )
  124157. +{
  124158. + gceSTATUS status;
  124159. + gcsHAL_INTERFACE iface;
  124160. +
  124161. + gcmkHEADER_ARG("Event=0x%x Signal=0x%x FromWhere=%d",
  124162. + Event, Signal, FromWhere);
  124163. +
  124164. + /* Verify the arguments. */
  124165. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124166. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  124167. +
  124168. + /* Mark the event as a signal. */
  124169. + iface.command = gcvHAL_SIGNAL;
  124170. + iface.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
  124171. +#ifdef __QNXNTO__
  124172. + iface.u.Signal.coid = 0;
  124173. + iface.u.Signal.rcvid = 0;
  124174. +#endif
  124175. + iface.u.Signal.auxSignal = 0;
  124176. + iface.u.Signal.process = 0;
  124177. +
  124178. + /* Append it to the queue. */
  124179. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  124180. +
  124181. + /* Success. */
  124182. + gcmkFOOTER_NO();
  124183. + return gcvSTATUS_OK;
  124184. +
  124185. +OnError:
  124186. + /* Return the status. */
  124187. + gcmkFOOTER();
  124188. + return status;
  124189. +}
  124190. +
  124191. +/*******************************************************************************
  124192. +**
  124193. +** gckEVENT_CommitDone
  124194. +**
  124195. +** Schedule an event to wake up work thread when commit is done by GPU.
  124196. +**
  124197. +** INPUT:
  124198. +**
  124199. +** gckEVENT Event
  124200. +** Pointer to an gckEVENT object.
  124201. +**
  124202. +** gceKERNEL_WHERE FromWhere
  124203. +** Place in the pipe where the event needs to be generated.
  124204. +**
  124205. +** OUTPUT:
  124206. +**
  124207. +** Nothing.
  124208. +*/
  124209. +gceSTATUS
  124210. +gckEVENT_CommitDone(
  124211. + IN gckEVENT Event,
  124212. + IN gceKERNEL_WHERE FromWhere
  124213. + )
  124214. +{
  124215. + gceSTATUS status;
  124216. + gcsHAL_INTERFACE iface;
  124217. +
  124218. + gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere);
  124219. +
  124220. + /* Verify the arguments. */
  124221. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124222. +
  124223. + iface.command = gcvHAL_COMMIT_DONE;
  124224. +
  124225. + /* Append it to the queue. */
  124226. + gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
  124227. +
  124228. + /* Success. */
  124229. + gcmkFOOTER_NO();
  124230. + return gcvSTATUS_OK;
  124231. +
  124232. +OnError:
  124233. + /* Return the status. */
  124234. + gcmkFOOTER();
  124235. + return status;
  124236. +}
  124237. +/*******************************************************************************
  124238. +**
  124239. +** gckEVENT_Submit
  124240. +**
  124241. +** Submit the current event queue to the GPU.
  124242. +**
  124243. +** INPUT:
  124244. +**
  124245. +** gckEVENT Event
  124246. +** Pointer to an gckEVENT object.
  124247. +**
  124248. +** gctBOOL Wait
  124249. +** Submit requires one vacant event; if Wait is set to not zero,
  124250. +** and there are no vacant events at this time, the function will
  124251. +** wait until an event becomes vacant so that submission of the
  124252. +** queue is successful.
  124253. +**
  124254. +** gctBOOL FromPower
  124255. +** Determines whether the call originates from inside the power
  124256. +** management or not.
  124257. +**
  124258. +** OUTPUT:
  124259. +**
  124260. +** Nothing.
  124261. +*/
  124262. +gceSTATUS
  124263. +gckEVENT_Submit(
  124264. + IN gckEVENT Event,
  124265. + IN gctBOOL Wait,
  124266. + IN gctBOOL FromPower
  124267. + )
  124268. +{
  124269. + gceSTATUS status;
  124270. + gctUINT8 id = 0xFF;
  124271. + gcsEVENT_QUEUE_PTR queue;
  124272. + gctBOOL acquired = gcvFALSE;
  124273. + gckCOMMAND command = gcvNULL;
  124274. + gctBOOL commitEntered = gcvFALSE;
  124275. +#if !gcdNULL_DRIVER
  124276. + gctSIZE_T bytes;
  124277. + gctPOINTER buffer;
  124278. +#endif
  124279. +
  124280. + gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
  124281. +
  124282. + /* Get gckCOMMAND object. */
  124283. + command = Event->kernel->command;
  124284. +
  124285. + /* Are there event queues? */
  124286. + if (Event->queueHead != gcvNULL)
  124287. + {
  124288. + /* Acquire the command queue. */
  124289. + gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
  124290. + commitEntered = gcvTRUE;
  124291. +
  124292. + /* Process all queues. */
  124293. + while (Event->queueHead != gcvNULL)
  124294. + {
  124295. + /* Acquire the list mutex. */
  124296. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  124297. + Event->eventListMutex,
  124298. + gcvINFINITE));
  124299. + acquired = gcvTRUE;
  124300. +
  124301. + /* Get the current queue. */
  124302. + queue = Event->queueHead;
  124303. +
  124304. + /* Allocate an event ID. */
  124305. + gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->head, queue->source));
  124306. +
  124307. + /* Copy event list to event ID queue. */
  124308. + Event->queues[id].head = queue->head;
  124309. +
  124310. + /* Remove the top queue from the list. */
  124311. + if (Event->queueHead == Event->queueTail)
  124312. + {
  124313. + Event->queueHead = gcvNULL;
  124314. + Event->queueTail = gcvNULL;
  124315. + }
  124316. + else
  124317. + {
  124318. + Event->queueHead = Event->queueHead->next;
  124319. + }
  124320. +
  124321. + /* Free the queue. */
  124322. + gcmkONERROR(gckEVENT_FreeQueue(Event, queue));
  124323. +
  124324. + /* Release the list mutex. */
  124325. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  124326. + acquired = gcvFALSE;
  124327. +
  124328. +#if gcdNULL_DRIVER
  124329. + /* Notify immediately on infinite hardware. */
  124330. + gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
  124331. +
  124332. + gcmkONERROR(gckEVENT_Notify(Event, 0));
  124333. +#else
  124334. + /* Get the size of the hardware event. */
  124335. + gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
  124336. + gcvNULL,
  124337. + id,
  124338. + Event->queues[id].source,
  124339. + &bytes));
  124340. +
  124341. + /* Reserve space in the command queue. */
  124342. + gcmkONERROR(gckCOMMAND_Reserve(command,
  124343. + bytes,
  124344. + &buffer,
  124345. + &bytes));
  124346. +
  124347. + /* Set the hardware event in the command queue. */
  124348. + gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware,
  124349. + buffer,
  124350. + id,
  124351. + Event->queues[id].source,
  124352. + &bytes));
  124353. +
  124354. + /* Execute the hardware event. */
  124355. + gcmkONERROR(gckCOMMAND_Execute(command, bytes));
  124356. +#endif
  124357. + }
  124358. +
  124359. + /* Release the command queue. */
  124360. + gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
  124361. + commitEntered = gcvFALSE;
  124362. + }
  124363. +
  124364. + /* Success. */
  124365. + gcmkFOOTER_NO();
  124366. + return gcvSTATUS_OK;
  124367. +
  124368. +OnError:
  124369. + if (commitEntered)
  124370. + {
  124371. + /* Release the command queue mutex. */
  124372. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, FromPower));
  124373. + }
  124374. +
  124375. + if (acquired)
  124376. + {
  124377. + /* Need to unroll the mutex acquire. */
  124378. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
  124379. + }
  124380. +
  124381. + if (id != 0xFF)
  124382. + {
  124383. + /* Need to unroll the event allocation. */
  124384. + Event->queues[id].head = gcvNULL;
  124385. + }
  124386. +
  124387. + if (status == gcvSTATUS_GPU_NOT_RESPONDING)
  124388. + {
  124389. + /* Broadcast GPU stuck. */
  124390. + status = gckOS_Broadcast(Event->os,
  124391. + Event->kernel->hardware,
  124392. + gcvBROADCAST_GPU_STUCK);
  124393. + }
  124394. +
  124395. + /* Return the status. */
  124396. + gcmkFOOTER();
  124397. + return status;
  124398. +}
  124399. +
  124400. +/*******************************************************************************
  124401. +**
  124402. +** gckEVENT_Commit
  124403. +**
  124404. +** Commit an event queue from the user.
  124405. +**
  124406. +** INPUT:
  124407. +**
  124408. +** gckEVENT Event
  124409. +** Pointer to an gckEVENT object.
  124410. +**
  124411. +** gcsQUEUE_PTR Queue
  124412. +** User event queue.
  124413. +**
  124414. +** OUTPUT:
  124415. +**
  124416. +** Nothing.
  124417. +*/
  124418. +gceSTATUS
  124419. +gckEVENT_Commit(
  124420. + IN gckEVENT Event,
  124421. + IN gcsQUEUE_PTR Queue
  124422. + )
  124423. +{
  124424. + gceSTATUS status;
  124425. + gcsQUEUE_PTR record = gcvNULL, next;
  124426. + gctUINT32 processID;
  124427. + gctBOOL needCopy = gcvFALSE;
  124428. +
  124429. + gcmkHEADER_ARG("Event=0x%x Queue=0x%x", Event, Queue);
  124430. +
  124431. + /* Verify the arguments. */
  124432. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124433. +
  124434. + /* Get the current process ID. */
  124435. + gcmkONERROR(gckOS_GetProcessID(&processID));
  124436. +
  124437. + /* Query if we need to copy the client data. */
  124438. + gcmkONERROR(gckOS_QueryNeedCopy(Event->os, processID, &needCopy));
  124439. +
  124440. + /* Loop while there are records in the queue. */
  124441. + while (Queue != gcvNULL)
  124442. + {
  124443. + gcsQUEUE queue;
  124444. +
  124445. + if (needCopy)
  124446. + {
  124447. + /* Point to stack record. */
  124448. + record = &queue;
  124449. +
  124450. + /* Copy the data from the client. */
  124451. + gcmkONERROR(gckOS_CopyFromUserData(Event->os,
  124452. + record,
  124453. + Queue,
  124454. + gcmSIZEOF(gcsQUEUE)));
  124455. + }
  124456. + else
  124457. + {
  124458. + gctPOINTER pointer = gcvNULL;
  124459. +
  124460. + /* Map record into kernel memory. */
  124461. + gcmkONERROR(gckOS_MapUserPointer(Event->os,
  124462. + Queue,
  124463. + gcmSIZEOF(gcsQUEUE),
  124464. + &pointer));
  124465. +
  124466. + record = pointer;
  124467. + }
  124468. +
  124469. + /* Append event record to event queue. */
  124470. + gcmkONERROR(
  124471. + gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE));
  124472. +
  124473. + /* Next record in the queue. */
  124474. + next = gcmUINT64_TO_PTR(record->next);
  124475. +
  124476. + if (!needCopy)
  124477. + {
  124478. + /* Unmap record from kernel memory. */
  124479. + gcmkONERROR(
  124480. + gckOS_UnmapUserPointer(Event->os,
  124481. + Queue,
  124482. + gcmSIZEOF(gcsQUEUE),
  124483. + (gctPOINTER *) record));
  124484. + record = gcvNULL;
  124485. + }
  124486. +
  124487. + Queue = next;
  124488. + }
  124489. +
  124490. + /* Submit the event list. */
  124491. + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
  124492. +
  124493. + /* Success */
  124494. + gcmkFOOTER_NO();
  124495. + return gcvSTATUS_OK;
  124496. +
  124497. +OnError:
  124498. + if ((record != gcvNULL) && !needCopy)
  124499. + {
  124500. + /* Roll back. */
  124501. + gcmkVERIFY_OK(gckOS_UnmapUserPointer(Event->os,
  124502. + Queue,
  124503. + gcmSIZEOF(gcsQUEUE),
  124504. + (gctPOINTER *) record));
  124505. + }
  124506. +
  124507. + /* Return the status. */
  124508. + gcmkFOOTER();
  124509. + return status;
  124510. +}
  124511. +
  124512. +/*******************************************************************************
  124513. +**
  124514. +** gckEVENT_Compose
  124515. +**
  124516. +** Schedule a composition event and start a composition.
  124517. +**
  124518. +** INPUT:
  124519. +**
  124520. +** gckEVENT Event
  124521. +** Pointer to an gckEVENT object.
  124522. +**
  124523. +** gcsHAL_COMPOSE_PTR Info
  124524. +** Pointer to the composition structure.
  124525. +**
  124526. +** OUTPUT:
  124527. +**
  124528. +** Nothing.
  124529. +*/
  124530. +gceSTATUS
  124531. +gckEVENT_Compose(
  124532. + IN gckEVENT Event,
  124533. + IN gcsHAL_COMPOSE_PTR Info
  124534. + )
  124535. +{
  124536. + gceSTATUS status;
  124537. + gcsEVENT_PTR headRecord;
  124538. + gcsEVENT_PTR tailRecord;
  124539. + gcsEVENT_PTR tempRecord;
  124540. + gctUINT8 id = 0xFF;
  124541. + gctUINT32 processID;
  124542. +
  124543. + gcmkHEADER_ARG("Event=0x%x Info=0x%x", Event, Info);
  124544. +
  124545. + /* Verify the arguments. */
  124546. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124547. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  124548. +
  124549. + /* Get process ID. */
  124550. + gcmkONERROR(gckOS_GetProcessID(&processID));
  124551. +
  124552. + /* Allocate a record. */
  124553. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  124554. + headRecord = tailRecord = tempRecord;
  124555. +
  124556. + /* Initialize the record. */
  124557. + tempRecord->info.command = gcvHAL_SIGNAL;
  124558. + tempRecord->info.u.Signal.process = Info->process;
  124559. +#ifdef __QNXNTO__
  124560. + tempRecord->info.u.Signal.coid = Info->coid;
  124561. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  124562. +#endif
  124563. + tempRecord->info.u.Signal.signal = Info->signal;
  124564. + tempRecord->info.u.Signal.auxSignal = 0;
  124565. + tempRecord->next = gcvNULL;
  124566. + tempRecord->processID = processID;
  124567. +
  124568. + /* Allocate another record for user signal #1. */
  124569. + if (gcmUINT64_TO_PTR(Info->userSignal1) != gcvNULL)
  124570. + {
  124571. + /* Allocate a record. */
  124572. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  124573. + tailRecord->next = tempRecord;
  124574. + tailRecord = tempRecord;
  124575. +
  124576. + /* Initialize the record. */
  124577. + tempRecord->info.command = gcvHAL_SIGNAL;
  124578. + tempRecord->info.u.Signal.process = Info->userProcess;
  124579. +#ifdef __QNXNTO__
  124580. + tempRecord->info.u.Signal.coid = Info->coid;
  124581. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  124582. +#endif
  124583. + tempRecord->info.u.Signal.signal = Info->userSignal1;
  124584. + tempRecord->info.u.Signal.auxSignal = 0;
  124585. + tempRecord->next = gcvNULL;
  124586. + tempRecord->processID = processID;
  124587. + }
  124588. +
  124589. + /* Allocate another record for user signal #2. */
  124590. + if (gcmUINT64_TO_PTR(Info->userSignal2) != gcvNULL)
  124591. + {
  124592. + /* Allocate a record. */
  124593. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &tempRecord));
  124594. + tailRecord->next = tempRecord;
  124595. + tailRecord = tempRecord;
  124596. +
  124597. + /* Initialize the record. */
  124598. + tempRecord->info.command = gcvHAL_SIGNAL;
  124599. + tempRecord->info.u.Signal.process = Info->userProcess;
  124600. +#ifdef __QNXNTO__
  124601. + tempRecord->info.u.Signal.coid = Info->coid;
  124602. + tempRecord->info.u.Signal.rcvid = Info->rcvid;
  124603. +#endif
  124604. + tempRecord->info.u.Signal.signal = Info->userSignal2;
  124605. + tempRecord->info.u.Signal.auxSignal = 0;
  124606. + tempRecord->next = gcvNULL;
  124607. + tempRecord->processID = processID;
  124608. + }
  124609. +
  124610. + /* Allocate an event ID. */
  124611. + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, headRecord, gcvKERNEL_PIXEL));
  124612. +
  124613. + /* Start composition. */
  124614. + gcmkONERROR(gckHARDWARE_Compose(
  124615. + Event->kernel->hardware, processID,
  124616. + gcmUINT64_TO_PTR(Info->physical), gcmUINT64_TO_PTR(Info->logical), Info->offset, Info->size, id
  124617. + ));
  124618. +
  124619. + /* Success. */
  124620. + gcmkFOOTER_NO();
  124621. + return gcvSTATUS_OK;
  124622. +
  124623. +OnError:
  124624. + /* Return the status. */
  124625. + gcmkFOOTER();
  124626. + return status;
  124627. +}
  124628. +
  124629. +/*******************************************************************************
  124630. +**
  124631. +** gckEVENT_Interrupt
  124632. +**
  124633. +** Called by the interrupt service routine to store the triggered interrupt
  124634. +** mask to be later processed by gckEVENT_Notify.
  124635. +**
  124636. +** INPUT:
  124637. +**
  124638. +** gckEVENT Event
  124639. +** Pointer to an gckEVENT object.
  124640. +**
  124641. +** gctUINT32 Data
  124642. +** Mask for the 32 interrupts.
  124643. +**
  124644. +** OUTPUT:
  124645. +**
  124646. +** Nothing.
  124647. +*/
  124648. +gceSTATUS
  124649. +gckEVENT_Interrupt(
  124650. + IN gckEVENT Event,
  124651. + IN gctUINT32 Data
  124652. + )
  124653. +{
  124654. + unsigned long flags;
  124655. + gcmkHEADER_ARG("Event=0x%x Data=0x%x", Event, Data);
  124656. +
  124657. + /* Verify the arguments. */
  124658. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124659. +
  124660. + /* Combine current interrupt status with pending flags. */
  124661. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  124662. +#if gcdSMP
  124663. + gckOS_AtomSetMask(Event->pending, Data);
  124664. +#elif defined(__QNXNTO__)
  124665. + atomic_set(&Event->pending, Data);
  124666. +#else
  124667. + Event->pending |= Data;
  124668. +#endif
  124669. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  124670. +
  124671. + /* Success. */
  124672. + gcmkFOOTER_NO();
  124673. + return gcvSTATUS_OK;
  124674. +}
  124675. +
  124676. +/*******************************************************************************
  124677. +**
  124678. +** gckEVENT_Notify
  124679. +**
  124680. +** Process all triggered interrupts.
  124681. +**
  124682. +** INPUT:
  124683. +**
  124684. +** gckEVENT Event
  124685. +** Pointer to an gckEVENT object.
  124686. +**
  124687. +** OUTPUT:
  124688. +**
  124689. +** Nothing.
  124690. +*/
  124691. +gceSTATUS
  124692. +gckEVENT_Notify(
  124693. + IN gckEVENT Event,
  124694. + IN gctUINT32 IDs
  124695. + )
  124696. +{
  124697. + gceSTATUS status = gcvSTATUS_OK;
  124698. + gctINT i;
  124699. + gcsEVENT_QUEUE * queue;
  124700. + gctUINT mask = 0;
  124701. + gctBOOL acquired = gcvFALSE;
  124702. + gcuVIDMEM_NODE_PTR node;
  124703. + gctPOINTER info;
  124704. + gctSIGNAL signal;
  124705. + gctUINT pending;
  124706. + gckKERNEL kernel = Event->kernel;
  124707. +#if !gcdSMP
  124708. + gctBOOL suspended = gcvFALSE;
  124709. +#endif
  124710. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  124711. + gctINT eventNumber = 0;
  124712. +#endif
  124713. + gctINT32 free;
  124714. +#if gcdSECURE_USER
  124715. + gcskSECURE_CACHE_PTR cache;
  124716. +#endif
  124717. + unsigned long flags;
  124718. +
  124719. + gcmkHEADER_ARG("Event=0x%x IDs=0x%x", Event, IDs);
  124720. +
  124721. + /* Verify the arguments. */
  124722. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  124723. +
  124724. + gcmDEBUG_ONLY(
  124725. + if (IDs != 0)
  124726. + {
  124727. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  124728. + {
  124729. + if (Event->queues[i].head != gcvNULL)
  124730. + {
  124731. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  124732. + "Queue(%d): stamp=%llu source=%d",
  124733. + i,
  124734. + Event->queues[i].stamp,
  124735. + Event->queues[i].source);
  124736. + }
  124737. + }
  124738. + }
  124739. + );
  124740. +
  124741. + for (;;)
  124742. + {
  124743. + gcsEVENT_PTR record;
  124744. +
  124745. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  124746. +#if gcdSMP
  124747. + /* Get current interrupts. */
  124748. + gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending);
  124749. +#else
  124750. + /* Get current interrupts. */
  124751. + pending = Event->pending;
  124752. +#endif
  124753. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  124754. +
  124755. + if (pending & 0x80000000)
  124756. + {
  124757. + //gckOS_Print("!!!!!!!!!!!!! AXI BUS ERROR !!!!!!!!!!!!!\n");
  124758. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_EVENT, "AXI BUS ERROR");
  124759. + pending &= 0x7FFFFFFF;
  124760. + }
  124761. +
  124762. + if (pending & 0x40000000)
  124763. + {
  124764. + gckHARDWARE_DumpMMUException(Event->kernel->hardware);
  124765. +
  124766. + pending &= 0x3FFFFFFF;
  124767. + }
  124768. +
  124769. + gcmkTRACE_ZONE_N(
  124770. + gcvLEVEL_INFO, gcvZONE_EVENT,
  124771. + gcmSIZEOF(pending),
  124772. + "Pending interrupts 0x%x",
  124773. + pending
  124774. + );
  124775. +
  124776. + if (pending == 0)
  124777. + {
  124778. + /* No more pending interrupts - done. */
  124779. + break;
  124780. + }
  124781. +
  124782. + queue = gcvNULL;
  124783. +
  124784. + /* Grab the mutex queue. */
  124785. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  124786. + Event->eventQueueMutex,
  124787. + gcvINFINITE));
  124788. + acquired = gcvTRUE;
  124789. +
  124790. + gcmDEBUG_ONLY(
  124791. + if (IDs == 0)
  124792. + {
  124793. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  124794. + {
  124795. + if (Event->queues[i].head != gcvNULL)
  124796. + {
  124797. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  124798. + "Queue(%d): stamp=%llu source=%d",
  124799. + i,
  124800. + Event->queues[i].stamp,
  124801. + Event->queues[i].source);
  124802. + }
  124803. + }
  124804. + }
  124805. + );
  124806. +
  124807. + /* Find the oldest pending interrupt. */
  124808. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  124809. + {
  124810. + if ((Event->queues[i].head != gcvNULL)
  124811. + && (pending & (1 << i))
  124812. + )
  124813. + {
  124814. + if ((queue == gcvNULL)
  124815. + || (Event->queues[i].stamp < queue->stamp)
  124816. + )
  124817. + {
  124818. + queue = &Event->queues[i];
  124819. + mask = 1 << i;
  124820. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  124821. + eventNumber = i;
  124822. +#endif
  124823. + }
  124824. + }
  124825. + }
  124826. +
  124827. + if (queue == gcvNULL)
  124828. + {
  124829. + gcmkTRACE_ZONE_N(
  124830. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  124831. + gcmSIZEOF(pending),
  124832. + "Interrupts 0x%x are not pending.",
  124833. + pending
  124834. + );
  124835. +
  124836. + /* Release the mutex queue. */
  124837. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  124838. + acquired = gcvFALSE;
  124839. +
  124840. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  124841. +#if gcdSMP
  124842. + /* Mark pending interrupts as handled. */
  124843. + gckOS_AtomClearMask(Event->pending, pending);
  124844. +#elif defined(__QNXNTO__)
  124845. + /* Mark pending interrupts as handled. */
  124846. + atomic_clr((gctUINT32_PTR)&Event->pending, pending);
  124847. +#else
  124848. + /* Mark pending interrupts as handled. */
  124849. + Event->pending &= ~pending;
  124850. +#endif
  124851. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  124852. + break;
  124853. + }
  124854. +
  124855. + /* Check whether there is a missed interrupt. */
  124856. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  124857. + {
  124858. + if ((Event->queues[i].head != gcvNULL)
  124859. + && (Event->queues[i].stamp < queue->stamp)
  124860. + && (Event->queues[i].source <= queue->source)
  124861. + )
  124862. + {
  124863. + gcmkTRACE_N(
  124864. + gcvLEVEL_ERROR,
  124865. + gcmSIZEOF(i) + gcmSIZEOF(Event->queues[i].stamp),
  124866. + "Event %d lost (stamp %llu)",
  124867. + i, Event->queues[i].stamp
  124868. + );
  124869. +
  124870. + /* Use this event instead. */
  124871. + queue = &Event->queues[i];
  124872. + mask = 0;
  124873. + }
  124874. + }
  124875. +
  124876. + if (mask != 0)
  124877. + {
  124878. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  124879. + gcmkTRACE_ZONE_N(
  124880. + gcvLEVEL_INFO, gcvZONE_EVENT,
  124881. + gcmSIZEOF(eventNumber),
  124882. + "Processing interrupt %d",
  124883. + eventNumber
  124884. + );
  124885. +#endif
  124886. + }
  124887. +
  124888. + spin_lock_irqsave(&Event->kernel->irq_lock, flags);
  124889. +#if gcdSMP
  124890. + /* Mark pending interrupt as handled. */
  124891. + gckOS_AtomClearMask(Event->pending, mask);
  124892. +#elif defined(__QNXNTO__)
  124893. + /* Mark pending interrupt as handled. */
  124894. + atomic_clr(&Event->pending, mask);
  124895. +#else
  124896. + /* Mark pending interrupt as handled. */
  124897. + Event->pending &= ~mask;
  124898. +#endif
  124899. + spin_unlock_irqrestore(&Event->kernel->irq_lock, flags);
  124900. +
  124901. + /* We are in the notify loop. */
  124902. + Event->inNotify = gcvTRUE;
  124903. +
  124904. + /* We are in the notify loop. */
  124905. + Event->inNotify = gcvTRUE;
  124906. +
  124907. + /* Grab the event head. */
  124908. + record = queue->head;
  124909. +
  124910. + /* Now quickly clear its event list. */
  124911. + queue->head = gcvNULL;
  124912. +
  124913. + /* Release the mutex queue. */
  124914. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  124915. + acquired = gcvFALSE;
  124916. +
  124917. + /* Increase the number of free events. */
  124918. + gcmkONERROR(gckOS_AtomIncrement(Event->os, Event->freeAtom, &free));
  124919. +
  124920. + /* Walk all events for this interrupt. */
  124921. + while (record != gcvNULL)
  124922. + {
  124923. + gcsEVENT_PTR recordNext;
  124924. +#ifndef __QNXNTO__
  124925. + gctPOINTER logical;
  124926. +#endif
  124927. +#if gcdSECURE_USER
  124928. + gctSIZE_T bytes;
  124929. +#endif
  124930. +
  124931. + /* Grab next record. */
  124932. + recordNext = record->next;
  124933. +
  124934. +#ifdef __QNXNTO__
  124935. + /* Assign record->processID as the pid for this galcore thread.
  124936. + * Used in OS calls like gckOS_UnlockMemory() which do not take a pid.
  124937. + */
  124938. + drv_thread_specific_key_assign(record->processID, 0, Event->kernel->core);
  124939. +#endif
  124940. +
  124941. +#if gcdSECURE_USER
  124942. + /* Get the cache that belongs to this process. */
  124943. + gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel,
  124944. + record->processID,
  124945. + &cache));
  124946. +#endif
  124947. +
  124948. + gcmkTRACE_ZONE_N(
  124949. + gcvLEVEL_INFO, gcvZONE_EVENT,
  124950. + gcmSIZEOF(record->info.command),
  124951. + "Processing event type: %d",
  124952. + record->info.command
  124953. + );
  124954. +
  124955. + switch (record->info.command)
  124956. + {
  124957. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  124958. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  124959. + "gcvHAL_FREE_NON_PAGED_MEMORY: 0x%x",
  124960. + gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical));
  124961. +
  124962. + /* Free non-paged memory. */
  124963. + status = gckOS_FreeNonPagedMemory(
  124964. + Event->os,
  124965. + (gctSIZE_T) record->info.u.FreeNonPagedMemory.bytes,
  124966. + gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical),
  124967. + gcmUINT64_TO_PTR(record->info.u.FreeNonPagedMemory.logical));
  124968. +
  124969. + if (gcmIS_SUCCESS(status))
  124970. + {
  124971. +#if gcdSECURE_USER
  124972. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  124973. + Event->kernel,
  124974. + cache,
  124975. + gcmUINT64_TO_PTR(record->record.u.FreeNonPagedMemory.logical),
  124976. + (gctSIZE_T) record->record.u.FreeNonPagedMemory.bytes));
  124977. +#endif
  124978. + }
  124979. + gcmRELEASE_NAME(record->info.u.FreeNonPagedMemory.physical);
  124980. + break;
  124981. +
  124982. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  124983. + gcmkTRACE_ZONE(
  124984. + gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  124985. + "gcvHAL_FREE_CONTIGUOUS_MEMORY: 0x%x",
  124986. + gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical));
  124987. +
  124988. + /* Unmap the user memory. */
  124989. + status = gckOS_FreeContiguous(
  124990. + Event->os,
  124991. + gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical),
  124992. + gcmUINT64_TO_PTR(record->info.u.FreeContiguousMemory.logical),
  124993. + (gctSIZE_T) record->info.u.FreeContiguousMemory.bytes);
  124994. +
  124995. + if (gcmIS_SUCCESS(status))
  124996. + {
  124997. +#if gcdSECURE_USER
  124998. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  124999. + Event->kernel,
  125000. + cache,
  125001. + gcmUINT64_TO_PTR(record->record.u.FreeContiguousMemory.logical),
  125002. + (gctSIZE_T) record->record.u.FreeContiguousMemory.bytes));
  125003. +#endif
  125004. + }
  125005. + gcmRELEASE_NAME(record->info.u.FreeContiguousMemory.physical);
  125006. + break;
  125007. +
  125008. + case gcvHAL_FREE_VIDEO_MEMORY:
  125009. + node = gcmUINT64_TO_PTR(record->info.u.FreeVideoMemory.node);
  125010. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  125011. + "gcvHAL_FREE_VIDEO_MEMORY: 0x%x",
  125012. + node);
  125013. +#ifdef __QNXNTO__
  125014. +#if gcdUSE_VIDMEM_PER_PID
  125015. + /* Check if the VidMem object still exists. */
  125016. + if (gckKERNEL_GetVideoMemoryPoolPid(record->kernel,
  125017. + gcvPOOL_SYSTEM,
  125018. + record->processID,
  125019. + gcvNULL) == gcvSTATUS_NOT_FOUND)
  125020. + {
  125021. + /*printf("Vidmem not found for process:%d\n", queue->processID);*/
  125022. + status = gcvSTATUS_OK;
  125023. + break;
  125024. + }
  125025. +#else
  125026. + if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  125027. + && (node->VidMem.logical != gcvNULL)
  125028. + )
  125029. + {
  125030. + gcmkERR_BREAK(
  125031. + gckKERNEL_UnmapVideoMemory(record->kernel,
  125032. + node->VidMem.logical,
  125033. + record->processID,
  125034. + node->VidMem.bytes));
  125035. + node->VidMem.logical = gcvNULL;
  125036. + }
  125037. +#endif
  125038. +#endif
  125039. +
  125040. + /* Free video memory. */
  125041. + status =
  125042. + gckVIDMEM_Free(node);
  125043. +
  125044. + break;
  125045. +
  125046. + case gcvHAL_WRITE_DATA:
  125047. +#ifndef __QNXNTO__
  125048. + /* Convert physical into logical address. */
  125049. + gcmkERR_BREAK(
  125050. + gckOS_MapPhysical(Event->os,
  125051. + record->info.u.WriteData.address,
  125052. + gcmSIZEOF(gctUINT32),
  125053. + &logical));
  125054. +
  125055. + /* Write data. */
  125056. + gcmkERR_BREAK(
  125057. + gckOS_WriteMemory(Event->os,
  125058. + logical,
  125059. + record->info.u.WriteData.data));
  125060. +
  125061. + /* Unmap the physical memory. */
  125062. + gcmkERR_BREAK(
  125063. + gckOS_UnmapPhysical(Event->os,
  125064. + logical,
  125065. + gcmSIZEOF(gctUINT32)));
  125066. +#else
  125067. + /* Write data. */
  125068. + gcmkERR_BREAK(
  125069. + gckOS_WriteMemory(Event->os,
  125070. + (gctPOINTER)
  125071. + record->info.u.WriteData.address,
  125072. + record->info.u.WriteData.data));
  125073. +#endif
  125074. + break;
  125075. +
  125076. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  125077. + node = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
  125078. +
  125079. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  125080. + "gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x",
  125081. + node);
  125082. +
  125083. + /* Save node information before it disappears. */
  125084. +#if gcdSECURE_USER
  125085. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  125086. + {
  125087. + logical = gcvNULL;
  125088. + bytes = 0;
  125089. + }
  125090. + else
  125091. + {
  125092. + logical = node->Virtual.logical;
  125093. + bytes = node->Virtual.bytes;
  125094. + }
  125095. +#endif
  125096. +
  125097. + /* Unlock. */
  125098. + status = gckVIDMEM_Unlock(
  125099. + Event->kernel,
  125100. + node,
  125101. + record->info.u.UnlockVideoMemory.type,
  125102. + gcvNULL);
  125103. +
  125104. +#if gcdSECURE_USER
  125105. + if (gcmIS_SUCCESS(status) && (logical != gcvNULL))
  125106. + {
  125107. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  125108. + Event->kernel,
  125109. + cache,
  125110. + logical,
  125111. + bytes));
  125112. + }
  125113. +#endif
  125114. + break;
  125115. +
  125116. + case gcvHAL_SIGNAL:
  125117. + signal = gcmUINT64_TO_PTR(record->info.u.Signal.signal);
  125118. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  125119. + "gcvHAL_SIGNAL: 0x%x",
  125120. + signal);
  125121. +
  125122. +#ifdef __QNXNTO__
  125123. + if ((record->info.u.Signal.coid == 0)
  125124. + && (record->info.u.Signal.rcvid == 0)
  125125. + )
  125126. + {
  125127. + /* Kernel signal. */
  125128. + gcmkERR_BREAK(
  125129. + gckOS_Signal(Event->os,
  125130. + signal,
  125131. + gcvTRUE));
  125132. + }
  125133. + else
  125134. + {
  125135. + /* User signal. */
  125136. + gcmkERR_BREAK(
  125137. + gckOS_UserSignal(Event->os,
  125138. + signal,
  125139. + record->info.u.Signal.rcvid,
  125140. + record->info.u.Signal.coid));
  125141. + }
  125142. +#else
  125143. + /* Set signal. */
  125144. + if (gcmUINT64_TO_PTR(record->info.u.Signal.process) == gcvNULL)
  125145. + {
  125146. + /* Kernel signal. */
  125147. + gcmkERR_BREAK(
  125148. + gckOS_Signal(Event->os,
  125149. + signal,
  125150. + gcvTRUE));
  125151. + }
  125152. + else
  125153. + {
  125154. + /* User signal. */
  125155. + gcmkERR_BREAK(
  125156. + gckOS_UserSignal(Event->os,
  125157. + signal,
  125158. + gcmUINT64_TO_PTR(record->info.u.Signal.process)));
  125159. + }
  125160. +
  125161. + gcmkASSERT(record->info.u.Signal.auxSignal == 0);
  125162. +#endif
  125163. + break;
  125164. +
  125165. + case gcvHAL_UNMAP_USER_MEMORY:
  125166. + info = gcmNAME_TO_PTR(record->info.u.UnmapUserMemory.info);
  125167. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  125168. + "gcvHAL_UNMAP_USER_MEMORY: 0x%x",
  125169. + info);
  125170. +
  125171. + /* Unmap the user memory. */
  125172. + status = gckOS_UnmapUserMemory(
  125173. + Event->os,
  125174. + Event->kernel->core,
  125175. + gcmUINT64_TO_PTR(record->info.u.UnmapUserMemory.memory),
  125176. + (gctSIZE_T) record->info.u.UnmapUserMemory.size,
  125177. + info,
  125178. + record->info.u.UnmapUserMemory.address);
  125179. +
  125180. +#if gcdSECURE_USER
  125181. + if (gcmIS_SUCCESS(status))
  125182. + {
  125183. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
  125184. + Event->kernel,
  125185. + cache,
  125186. + gcmUINT64_TO_PTR(record->info.u.UnmapUserMemory.memory),
  125187. + (gctSIZE_T) record->info.u.UnmapUserMemory.size));
  125188. + }
  125189. +#endif
  125190. + gcmRELEASE_NAME(record->info.u.UnmapUserMemory.info);
  125191. + break;
  125192. +
  125193. + case gcvHAL_TIMESTAMP:
  125194. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  125195. + "gcvHAL_TIMESTAMP: %d %d",
  125196. + record->info.u.TimeStamp.timer,
  125197. + record->info.u.TimeStamp.request);
  125198. +
  125199. + /* Process the timestamp. */
  125200. + switch (record->info.u.TimeStamp.request)
  125201. + {
  125202. + case 0:
  125203. + status = gckOS_GetTime(&Event->kernel->timers[
  125204. + record->info.u.TimeStamp.timer].
  125205. + stopTime);
  125206. + break;
  125207. +
  125208. + case 1:
  125209. + status = gckOS_GetTime(&Event->kernel->timers[
  125210. + record->info.u.TimeStamp.timer].
  125211. + startTime);
  125212. + break;
  125213. +
  125214. + default:
  125215. + gcmkTRACE_ZONE_N(
  125216. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  125217. + gcmSIZEOF(record->info.u.TimeStamp.request),
  125218. + "Invalid timestamp request: %d",
  125219. + record->info.u.TimeStamp.request
  125220. + );
  125221. +
  125222. + status = gcvSTATUS_INVALID_ARGUMENT;
  125223. + break;
  125224. + }
  125225. + break;
  125226. +
  125227. +#if gcdVIRTUAL_COMMAND_BUFFER
  125228. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  125229. + gcmkVERIFY_OK(
  125230. + gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
  125231. + (gctSIZE_T) record->info.u.FreeVirtualCommandBuffer.bytes,
  125232. + gcmNAME_TO_PTR(record->info.u.FreeVirtualCommandBuffer.physical),
  125233. + gcmUINT64_TO_PTR(record->info.u.FreeVirtualCommandBuffer.logical)
  125234. + ));
  125235. + gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical);
  125236. + break;
  125237. +#endif
  125238. +
  125239. +#if gcdANDROID_NATIVE_FENCE_SYNC
  125240. + case gcvHAL_SYNC_POINT:
  125241. + {
  125242. + gctSYNC_POINT syncPoint;
  125243. +
  125244. + syncPoint = gcmUINT64_TO_PTR(record->info.u.SyncPoint.syncPoint);
  125245. + status = gckOS_SignalSyncPoint(Event->os, syncPoint);
  125246. + }
  125247. + break;
  125248. +#endif
  125249. +
  125250. + case gcvHAL_COMMIT_DONE:
  125251. + break;
  125252. +
  125253. + default:
  125254. + /* Invalid argument. */
  125255. + gcmkTRACE_ZONE_N(
  125256. + gcvLEVEL_ERROR, gcvZONE_EVENT,
  125257. + gcmSIZEOF(record->info.command),
  125258. + "Unknown event type: %d",
  125259. + record->info.command
  125260. + );
  125261. +
  125262. + status = gcvSTATUS_INVALID_ARGUMENT;
  125263. + break;
  125264. + }
  125265. +
  125266. + /* Make sure there are no errors generated. */
  125267. + if (gcmIS_ERROR(status))
  125268. + {
  125269. + gcmkTRACE_ZONE_N(
  125270. + gcvLEVEL_WARNING, gcvZONE_EVENT,
  125271. + gcmSIZEOF(status),
  125272. + "Event produced status: %d(%s)",
  125273. + status, gckOS_DebugStatus2Name(status));
  125274. + }
  125275. +
  125276. + /* Free the event. */
  125277. + gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record));
  125278. +
  125279. + /* Advance to next record. */
  125280. + record = recordNext;
  125281. + }
  125282. +
  125283. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
  125284. + "Handled interrupt 0x%x", mask);
  125285. + }
  125286. +
  125287. + if (IDs == 0)
  125288. + {
  125289. + gcmkONERROR(_TryToIdleGPU(Event));
  125290. + }
  125291. +
  125292. + /* We are out the notify loop. */
  125293. + Event->inNotify = gcvFALSE;
  125294. +
  125295. + /* Success. */
  125296. + gcmkFOOTER_NO();
  125297. + return gcvSTATUS_OK;
  125298. +
  125299. +OnError:
  125300. + if (acquired)
  125301. + {
  125302. + /* Release mutex. */
  125303. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  125304. + }
  125305. +
  125306. +#if !gcdSMP
  125307. + if (suspended)
  125308. + {
  125309. + /* Resume interrupts. */
  125310. + gcmkVERIFY_OK(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core));
  125311. + }
  125312. +#endif
  125313. +
  125314. + /* We are out the notify loop. */
  125315. + Event->inNotify = gcvFALSE;
  125316. +
  125317. + /* Return the status. */
  125318. + gcmkFOOTER();
  125319. + return status;
  125320. +}
  125321. +
  125322. +/*******************************************************************************
  125323. +** gckEVENT_FreeProcess
  125324. +**
  125325. +** Free all events owned by a particular process ID.
  125326. +**
  125327. +** INPUT:
  125328. +**
  125329. +** gckEVENT Event
  125330. +** Pointer to an gckEVENT object.
  125331. +**
  125332. +** gctUINT32 ProcessID
  125333. +** Process ID of the process to be freed up.
  125334. +**
  125335. +** OUTPUT:
  125336. +**
  125337. +** Nothing.
  125338. +*/
  125339. +gceSTATUS
  125340. +gckEVENT_FreeProcess(
  125341. + IN gckEVENT Event,
  125342. + IN gctUINT32 ProcessID
  125343. + )
  125344. +{
  125345. + gctSIZE_T i;
  125346. + gctBOOL acquired = gcvFALSE;
  125347. + gcsEVENT_PTR record, next;
  125348. + gceSTATUS status;
  125349. + gcsEVENT_PTR deleteHead, deleteTail;
  125350. +
  125351. + gcmkHEADER_ARG("Event=0x%x ProcessID=%d", Event, ProcessID);
  125352. +
  125353. + /* Verify the arguments. */
  125354. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  125355. +
  125356. + /* Walk through all queues. */
  125357. + for (i = 0; i < gcmCOUNTOF(Event->queues); ++i)
  125358. + {
  125359. + if (Event->queues[i].head != gcvNULL)
  125360. + {
  125361. + /* Grab the event queue mutex. */
  125362. + gcmkONERROR(gckOS_AcquireMutex(Event->os,
  125363. + Event->eventQueueMutex,
  125364. + gcvINFINITE));
  125365. + acquired = gcvTRUE;
  125366. +
  125367. + /* Grab the mutex head. */
  125368. + record = Event->queues[i].head;
  125369. + Event->queues[i].head = gcvNULL;
  125370. + Event->queues[i].tail = gcvNULL;
  125371. + deleteHead = gcvNULL;
  125372. + deleteTail = gcvNULL;
  125373. +
  125374. + while (record != gcvNULL)
  125375. + {
  125376. + next = record->next;
  125377. + if (record->processID == ProcessID)
  125378. + {
  125379. + if (deleteHead == gcvNULL)
  125380. + {
  125381. + deleteHead = record;
  125382. + }
  125383. + else
  125384. + {
  125385. + deleteTail->next = record;
  125386. + }
  125387. +
  125388. + deleteTail = record;
  125389. + }
  125390. + else
  125391. + {
  125392. + if (Event->queues[i].head == gcvNULL)
  125393. + {
  125394. + Event->queues[i].head = record;
  125395. + }
  125396. + else
  125397. + {
  125398. + Event->queues[i].tail->next = record;
  125399. + }
  125400. +
  125401. + Event->queues[i].tail = record;
  125402. + }
  125403. +
  125404. + record->next = gcvNULL;
  125405. + record = next;
  125406. + }
  125407. +
  125408. + /* Release the mutex queue. */
  125409. + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  125410. + acquired = gcvFALSE;
  125411. +
  125412. + /* Loop through the entire list of events. */
  125413. + for (record = deleteHead; record != gcvNULL; record = next)
  125414. + {
  125415. + /* Get the next event record. */
  125416. + next = record->next;
  125417. +
  125418. + /* Free the event record. */
  125419. + gcmkONERROR(gckEVENT_FreeRecord(Event, record));
  125420. + }
  125421. + }
  125422. + }
  125423. +
  125424. + gcmkONERROR(_TryToIdleGPU(Event));
  125425. +
  125426. + /* Success. */
  125427. + gcmkFOOTER_NO();
  125428. + return gcvSTATUS_OK;
  125429. +
  125430. +OnError:
  125431. + /* Release the event queue mutex. */
  125432. + if (acquired)
  125433. + {
  125434. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex));
  125435. + }
  125436. +
  125437. + /* Return the status. */
  125438. + gcmkFOOTER();
  125439. + return status;
  125440. +}
  125441. +
  125442. +/*******************************************************************************
  125443. +** gckEVENT_Stop
  125444. +**
  125445. +** Stop the hardware using the End event mechanism.
  125446. +**
  125447. +** INPUT:
  125448. +**
  125449. +** gckEVENT Event
  125450. +** Pointer to an gckEVENT object.
  125451. +**
  125452. +** gctUINT32 ProcessID
  125453. +** Process ID Logical belongs.
  125454. +**
  125455. +** gctPHYS_ADDR Handle
  125456. +** Physical address handle. If gcvNULL it is video memory.
  125457. +**
  125458. +** gctPOINTER Logical
  125459. +** Logical address to flush.
  125460. +**
  125461. +** gctSIGNAL Signal
  125462. +** Pointer to the signal to trigger.
  125463. +**
  125464. +** OUTPUT:
  125465. +**
  125466. +** Nothing.
  125467. +*/
  125468. +gceSTATUS
  125469. +gckEVENT_Stop(
  125470. + IN gckEVENT Event,
  125471. + IN gctUINT32 ProcessID,
  125472. + IN gctPHYS_ADDR Handle,
  125473. + IN gctPOINTER Logical,
  125474. + IN gctSIGNAL Signal,
  125475. + IN OUT gctSIZE_T * waitSize
  125476. + )
  125477. +{
  125478. + gceSTATUS status;
  125479. + /* gctSIZE_T waitSize;*/
  125480. + gcsEVENT_PTR record;
  125481. + gctUINT8 id = 0xFF;
  125482. +
  125483. + gcmkHEADER_ARG("Event=0x%x ProcessID=%u Handle=0x%x Logical=0x%x "
  125484. + "Signal=0x%x",
  125485. + Event, ProcessID, Handle, Logical, Signal);
  125486. +
  125487. + /* Verify the arguments. */
  125488. + gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
  125489. +
  125490. + /* Submit the current event queue. */
  125491. + gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
  125492. +
  125493. + /* Allocate a record. */
  125494. + gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &record));
  125495. +
  125496. + /* Initialize the record. */
  125497. + record->next = gcvNULL;
  125498. + record->processID = ProcessID;
  125499. + record->info.command = gcvHAL_SIGNAL;
  125500. + record->info.u.Signal.signal = gcmPTR_TO_UINT64(Signal);
  125501. +#ifdef __QNXNTO__
  125502. + record->info.u.Signal.coid = 0;
  125503. + record->info.u.Signal.rcvid = 0;
  125504. +#endif
  125505. + record->info.u.Signal.auxSignal = 0;
  125506. + record->info.u.Signal.process = 0;
  125507. +
  125508. +
  125509. + gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, record, gcvKERNEL_PIXEL));
  125510. +
  125511. + /* Replace last WAIT with END. */
  125512. + gcmkONERROR(gckHARDWARE_End(
  125513. + Event->kernel->hardware, Logical, waitSize
  125514. + ));
  125515. +
  125516. +#if gcdNONPAGED_MEMORY_CACHEABLE
  125517. + /* Flush the cache for the END. */
  125518. + gcmkONERROR(gckOS_CacheClean(
  125519. + Event->os,
  125520. + ProcessID,
  125521. + gcvNULL,
  125522. + Handle,
  125523. + Logical,
  125524. + *waitSize
  125525. + ));
  125526. +#endif
  125527. +
  125528. + /* Wait for the signal. */
  125529. + gcmkONERROR(gckOS_WaitSignal(Event->os, Signal, gcvINFINITE));
  125530. +
  125531. + /* Success. */
  125532. + gcmkFOOTER_NO();
  125533. + return gcvSTATUS_OK;
  125534. +
  125535. +OnError:
  125536. +
  125537. + /* Return the status. */
  125538. + gcmkFOOTER();
  125539. + return status;
  125540. +}
  125541. +
  125542. +static void
  125543. +_PrintRecord(
  125544. + gcsEVENT_PTR record
  125545. + )
  125546. +{
  125547. + switch (record->info.command)
  125548. + {
  125549. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  125550. + gcmkPRINT(" gcvHAL_FREE_NON_PAGED_MEMORY");
  125551. + break;
  125552. +
  125553. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  125554. + gcmkPRINT(" gcvHAL_FREE_CONTIGUOUS_MEMORY");
  125555. + break;
  125556. +
  125557. + case gcvHAL_FREE_VIDEO_MEMORY:
  125558. + gcmkPRINT(" gcvHAL_FREE_VIDEO_MEMORY");
  125559. + break;
  125560. +
  125561. + case gcvHAL_WRITE_DATA:
  125562. + gcmkPRINT(" gcvHAL_WRITE_DATA");
  125563. + break;
  125564. +
  125565. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  125566. + gcmkPRINT(" gcvHAL_UNLOCK_VIDEO_MEMORY");
  125567. + break;
  125568. +
  125569. + case gcvHAL_SIGNAL:
  125570. + gcmkPRINT(" gcvHAL_SIGNAL process=%d signal=0x%x",
  125571. + record->info.u.Signal.process,
  125572. + record->info.u.Signal.signal);
  125573. + break;
  125574. +
  125575. + case gcvHAL_UNMAP_USER_MEMORY:
  125576. + gcmkPRINT(" gcvHAL_UNMAP_USER_MEMORY");
  125577. + break;
  125578. +
  125579. + case gcvHAL_TIMESTAMP:
  125580. + gcmkPRINT(" gcvHAL_TIMESTAMP");
  125581. + break;
  125582. +
  125583. + case gcvHAL_COMMIT_DONE:
  125584. + gcmkPRINT(" gcvHAL_COMMIT_DONE");
  125585. + break;
  125586. +
  125587. + case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
  125588. + gcmkPRINT(" gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x",
  125589. + record->info.u.FreeVirtualCommandBuffer.logical);
  125590. + break;
  125591. +
  125592. + default:
  125593. + gcmkPRINT(" Illegal Event %d", record->info.command);
  125594. + break;
  125595. + }
  125596. +}
  125597. +
  125598. +/*******************************************************************************
  125599. +** gckEVENT_Dump
  125600. +**
  125601. +** Dump record in event queue when stuck happens.
  125602. +** No protection for the event queue.
  125603. +**/
  125604. +gceSTATUS
  125605. +gckEVENT_Dump(
  125606. + IN gckEVENT Event
  125607. + )
  125608. +{
  125609. + gcsEVENT_QUEUE_PTR queueHead = Event->queueHead;
  125610. + gcsEVENT_QUEUE_PTR queue;
  125611. + gcsEVENT_PTR record = gcvNULL;
  125612. + gctINT i;
  125613. +
  125614. + gcmkHEADER_ARG("Event=0x%x", Event);
  125615. +
  125616. + gcmkPRINT("**************************\n");
  125617. + gcmkPRINT("*** EVENT STATE DUMP ***\n");
  125618. + gcmkPRINT("**************************\n");
  125619. +
  125620. +
  125621. + gcmkPRINT(" Unsumbitted Event:");
  125622. + while(queueHead)
  125623. + {
  125624. + queue = queueHead;
  125625. + record = queueHead->head;
  125626. +
  125627. + gcmkPRINT(" [%x]:", queue);
  125628. + while(record)
  125629. + {
  125630. + _PrintRecord(record);
  125631. + record = record->next;
  125632. + }
  125633. +
  125634. + if (queueHead == Event->queueTail)
  125635. + {
  125636. + queueHead = gcvNULL;
  125637. + }
  125638. + else
  125639. + {
  125640. + queueHead = queueHead->next;
  125641. + }
  125642. + }
  125643. +
  125644. + gcmkPRINT(" Untriggered Event:");
  125645. + for (i = 0; i < 30; i++)
  125646. + {
  125647. + queue = &Event->queues[i];
  125648. + record = queue->head;
  125649. +
  125650. + gcmkPRINT(" [%d]:", i);
  125651. + while(record)
  125652. + {
  125653. + _PrintRecord(record);
  125654. + record = record->next;
  125655. + }
  125656. + }
  125657. +
  125658. + gcmkFOOTER_NO();
  125659. + return gcvSTATUS_OK;
  125660. +}
  125661. +
  125662. +gceSTATUS gckEVENT_WaitEmpty(gckEVENT Event)
  125663. +{
  125664. + gctBOOL isEmpty;
  125665. +
  125666. + while (Event->inNotify || (gcmIS_SUCCESS(gckEVENT_IsEmpty(Event, &isEmpty)) && !isEmpty)) ;
  125667. +
  125668. + return gcvSTATUS_OK;
  125669. +}
  125670. diff -Nur linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
  125671. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h 1970-01-01 01:00:00.000000000 +0100
  125672. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h 2014-09-11 18:06:03.082042291 +0200
  125673. @@ -0,0 +1,1011 @@
  125674. +/****************************************************************************
  125675. +*
  125676. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  125677. +*
  125678. +* This program is free software; you can redistribute it and/or modify
  125679. +* it under the terms of the GNU General Public License as published by
  125680. +* the Free Software Foundation; either version 2 of the license, or
  125681. +* (at your option) any later version.
  125682. +*
  125683. +* This program is distributed in the hope that it will be useful,
  125684. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  125685. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  125686. +* GNU General Public License for more details.
  125687. +*
  125688. +* You should have received a copy of the GNU General Public License
  125689. +* along with this program; if not write to the Free Software
  125690. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  125691. +*
  125692. +*****************************************************************************/
  125693. +
  125694. +
  125695. +#ifndef __gc_hal_kernel_h_
  125696. +#define __gc_hal_kernel_h_
  125697. +
  125698. +#include <linux/spinlock.h>
  125699. +
  125700. +#include "gc_hal.h"
  125701. +#include "gc_hal_kernel_hardware.h"
  125702. +#include "gc_hal_driver.h"
  125703. +
  125704. +#if gcdENABLE_VG
  125705. +#include "gc_hal_kernel_vg.h"
  125706. +#endif
  125707. +
  125708. +#ifdef __cplusplus
  125709. +extern "C" {
  125710. +#endif
  125711. +
  125712. +
  125713. +/*******************************************************************************
  125714. +***** New MMU Defination *******************************************************/
  125715. +#define gcdMMU_MTLB_SHIFT 22
  125716. +#define gcdMMU_STLB_4K_SHIFT 12
  125717. +#define gcdMMU_STLB_64K_SHIFT 16
  125718. +
  125719. +#define gcdMMU_MTLB_BITS (32 - gcdMMU_MTLB_SHIFT)
  125720. +#define gcdMMU_PAGE_4K_BITS gcdMMU_STLB_4K_SHIFT
  125721. +#define gcdMMU_STLB_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
  125722. +#define gcdMMU_PAGE_64K_BITS gcdMMU_STLB_64K_SHIFT
  125723. +#define gcdMMU_STLB_64K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
  125724. +
  125725. +#define gcdMMU_MTLB_ENTRY_NUM (1 << gcdMMU_MTLB_BITS)
  125726. +#define gcdMMU_MTLB_SIZE (gcdMMU_MTLB_ENTRY_NUM << 2)
  125727. +#define gcdMMU_STLB_4K_ENTRY_NUM (1 << gcdMMU_STLB_4K_BITS)
  125728. +#define gcdMMU_STLB_4K_SIZE (gcdMMU_STLB_4K_ENTRY_NUM << 2)
  125729. +#define gcdMMU_PAGE_4K_SIZE (1 << gcdMMU_STLB_4K_SHIFT)
  125730. +#define gcdMMU_STLB_64K_ENTRY_NUM (1 << gcdMMU_STLB_64K_BITS)
  125731. +#define gcdMMU_STLB_64K_SIZE (gcdMMU_STLB_64K_ENTRY_NUM << 2)
  125732. +#define gcdMMU_PAGE_64K_SIZE (1 << gcdMMU_STLB_64K_SHIFT)
  125733. +
  125734. +#define gcdMMU_MTLB_MASK (~((1U << gcdMMU_MTLB_SHIFT)-1))
  125735. +#define gcdMMU_STLB_4K_MASK ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
  125736. +#define gcdMMU_PAGE_4K_MASK (gcdMMU_PAGE_4K_SIZE - 1)
  125737. +#define gcdMMU_STLB_64K_MASK ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
  125738. +#define gcdMMU_PAGE_64K_MASK (gcdMMU_PAGE_64K_SIZE - 1)
  125739. +
  125740. +/* Page offset definitions. */
  125741. +#define gcdMMU_OFFSET_4K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
  125742. +#define gcdMMU_OFFSET_4K_MASK ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
  125743. +#define gcdMMU_OFFSET_16K_BITS (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
  125744. +#define gcdMMU_OFFSET_16K_MASK ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
  125745. +
  125746. +/*******************************************************************************
  125747. +***** Process Secure Cache ****************************************************/
  125748. +
  125749. +#define gcdSECURE_CACHE_LRU 1
  125750. +#define gcdSECURE_CACHE_LINEAR 2
  125751. +#define gcdSECURE_CACHE_HASH 3
  125752. +#define gcdSECURE_CACHE_TABLE 4
  125753. +
  125754. +typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR;
  125755. +typedef struct _gcskLOGICAL_CACHE gcskLOGICAL_CACHE;
  125756. +struct _gcskLOGICAL_CACHE
  125757. +{
  125758. + /* Logical address. */
  125759. + gctPOINTER logical;
  125760. +
  125761. + /* DMAable address. */
  125762. + gctUINT32 dma;
  125763. +
  125764. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  125765. + /* Pointer to the previous and next hash tables. */
  125766. + gcskLOGICAL_CACHE_PTR nextHash;
  125767. + gcskLOGICAL_CACHE_PTR prevHash;
  125768. +#endif
  125769. +
  125770. +#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
  125771. + /* Pointer to the previous and next slot. */
  125772. + gcskLOGICAL_CACHE_PTR next;
  125773. + gcskLOGICAL_CACHE_PTR prev;
  125774. +#endif
  125775. +
  125776. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
  125777. + /* Time stamp. */
  125778. + gctUINT64 stamp;
  125779. +#endif
  125780. +};
  125781. +
  125782. +typedef struct _gcskSECURE_CACHE * gcskSECURE_CACHE_PTR;
  125783. +typedef struct _gcskSECURE_CACHE
  125784. +{
  125785. + /* Cache memory. */
  125786. + gcskLOGICAL_CACHE cache[1 + gcdSECURE_CACHE_SLOTS];
  125787. +
  125788. + /* Last known index for LINEAR mode. */
  125789. + gcskLOGICAL_CACHE_PTR cacheIndex;
  125790. +
  125791. + /* Current free slot for LINEAR mode. */
  125792. + gctUINT32 cacheFree;
  125793. +
  125794. + /* Time stamp for LINEAR mode. */
  125795. + gctUINT64 cacheStamp;
  125796. +
  125797. +#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
  125798. + /* Hash table for HASH mode. */
  125799. + gcskLOGICAL_CACHE hash[256];
  125800. +#endif
  125801. +}
  125802. +gcskSECURE_CACHE;
  125803. +
  125804. +/*******************************************************************************
  125805. +***** Process Database Management *********************************************/
  125806. +
  125807. +typedef enum _gceDATABASE_TYPE
  125808. +{
  125809. + gcvDB_VIDEO_MEMORY = 1, /* Video memory created. */
  125810. + gcvDB_COMMAND_BUFFER, /* Command Buffer. */
  125811. + gcvDB_NON_PAGED, /* Non paged memory. */
  125812. + gcvDB_CONTIGUOUS, /* Contiguous memory. */
  125813. + gcvDB_SIGNAL, /* Signal. */
  125814. + gcvDB_VIDEO_MEMORY_LOCKED, /* Video memory locked. */
  125815. + gcvDB_CONTEXT, /* Context */
  125816. + gcvDB_IDLE, /* GPU idle. */
  125817. + gcvDB_MAP_MEMORY, /* Map memory */
  125818. + gcvDB_SHARED_INFO, /* Private data */
  125819. + gcvDB_MAP_USER_MEMORY, /* Map user memory */
  125820. + gcvDB_SYNC_POINT, /* Sync point. */
  125821. + gcvDB_VIDEO_MEMORY_RESERVED, /* Reserved video memory */
  125822. + gcvDB_VIDEO_MEMORY_CONTIGUOUS, /* Contiguous video memory */
  125823. + gcvDB_VIDEO_MEMORY_VIRTUAL, /* Virtual video memory */
  125824. +}
  125825. +gceDATABASE_TYPE;
  125826. +
  125827. +typedef struct _gcsDATABASE_RECORD * gcsDATABASE_RECORD_PTR;
  125828. +typedef struct _gcsDATABASE_RECORD
  125829. +{
  125830. + /* Pointer to kernel. */
  125831. + gckKERNEL kernel;
  125832. +
  125833. + /* Pointer to next database record. */
  125834. + gcsDATABASE_RECORD_PTR next;
  125835. +
  125836. + /* Type of record. */
  125837. + gceDATABASE_TYPE type;
  125838. +
  125839. + /* Data for record. */
  125840. + gctPOINTER data;
  125841. + gctPHYS_ADDR physical;
  125842. + gctSIZE_T bytes;
  125843. +}
  125844. +gcsDATABASE_RECORD;
  125845. +
  125846. +typedef struct _gcsDATABASE * gcsDATABASE_PTR;
  125847. +typedef struct _gcsDATABASE
  125848. +{
  125849. + /* Pointer to next entry is hash list. */
  125850. + gcsDATABASE_PTR next;
  125851. + gctSIZE_T slot;
  125852. +
  125853. + /* Process ID. */
  125854. + gctUINT32 processID;
  125855. +
  125856. + /* Sizes to query. */
  125857. + gcsDATABASE_COUNTERS vidMem;
  125858. + gcsDATABASE_COUNTERS nonPaged;
  125859. + gcsDATABASE_COUNTERS contiguous;
  125860. + gcsDATABASE_COUNTERS mapUserMemory;
  125861. + gcsDATABASE_COUNTERS mapMemory;
  125862. + gcsDATABASE_COUNTERS vidMemResv;
  125863. + gcsDATABASE_COUNTERS vidMemCont;
  125864. + gcsDATABASE_COUNTERS vidMemVirt;
  125865. +
  125866. + /* Idle time management. */
  125867. + gctUINT64 lastIdle;
  125868. + gctUINT64 idle;
  125869. +
  125870. + /* Pointer to database. */
  125871. + gcsDATABASE_RECORD_PTR list[48];
  125872. +
  125873. +#if gcdSECURE_USER
  125874. + /* Secure cache. */
  125875. + gcskSECURE_CACHE cache;
  125876. +#endif
  125877. +
  125878. + gctPOINTER handleDatabase;
  125879. + gctPOINTER handleDatabaseMutex;
  125880. +}
  125881. +gcsDATABASE;
  125882. +
  125883. +/* Create a process database that will contain all its allocations. */
  125884. +gceSTATUS
  125885. +gckKERNEL_CreateProcessDB(
  125886. + IN gckKERNEL Kernel,
  125887. + IN gctUINT32 ProcessID
  125888. + );
  125889. +
  125890. +/* Add a record to the process database. */
  125891. +gceSTATUS
  125892. +gckKERNEL_AddProcessDB(
  125893. + IN gckKERNEL Kernel,
  125894. + IN gctUINT32 ProcessID,
  125895. + IN gceDATABASE_TYPE Type,
  125896. + IN gctPOINTER Pointer,
  125897. + IN gctPHYS_ADDR Physical,
  125898. + IN gctSIZE_T Size
  125899. + );
  125900. +
  125901. +/* Remove a record to the process database. */
  125902. +gceSTATUS
  125903. +gckKERNEL_RemoveProcessDB(
  125904. + IN gckKERNEL Kernel,
  125905. + IN gctUINT32 ProcessID,
  125906. + IN gceDATABASE_TYPE Type,
  125907. + IN gctPOINTER Pointer
  125908. + );
  125909. +
  125910. +/* Destroy the process database. */
  125911. +gceSTATUS
  125912. +gckKERNEL_DestroyProcessDB(
  125913. + IN gckKERNEL Kernel,
  125914. + IN gctUINT32 ProcessID
  125915. + );
  125916. +
  125917. +/* Find a record to the process database. */
  125918. +gceSTATUS
  125919. +gckKERNEL_FindProcessDB(
  125920. + IN gckKERNEL Kernel,
  125921. + IN gctUINT32 ProcessID,
  125922. + IN gctUINT32 ThreadID,
  125923. + IN gceDATABASE_TYPE Type,
  125924. + IN gctPOINTER Pointer,
  125925. + OUT gcsDATABASE_RECORD_PTR Record
  125926. + );
  125927. +
  125928. +/* Query the process database. */
  125929. +gceSTATUS
  125930. +gckKERNEL_QueryProcessDB(
  125931. + IN gckKERNEL Kernel,
  125932. + IN gctUINT32 ProcessID,
  125933. + IN gctBOOL LastProcessID,
  125934. + IN gceDATABASE_TYPE Type,
  125935. + OUT gcuDATABASE_INFO * Info
  125936. + );
  125937. +
  125938. +/* Dump the process database. */
  125939. +gceSTATUS
  125940. +gckKERNEL_DumpProcessDB(
  125941. + IN gckKERNEL Kernel
  125942. + );
  125943. +
  125944. +/* ID database */
  125945. +gceSTATUS
  125946. +gckKERNEL_CreateIntegerDatabase(
  125947. + IN gckKERNEL Kernel,
  125948. + OUT gctPOINTER * Database
  125949. + );
  125950. +
  125951. +gceSTATUS
  125952. +gckKERNEL_DestroyIntegerDatabase(
  125953. + IN gckKERNEL Kernel,
  125954. + IN gctPOINTER Database
  125955. + );
  125956. +
  125957. +gceSTATUS
  125958. +gckKERNEL_AllocateIntegerId(
  125959. + IN gctPOINTER Database,
  125960. + IN gctPOINTER Pointer,
  125961. + OUT gctUINT32 * Id
  125962. + );
  125963. +
  125964. +gceSTATUS
  125965. +gckKERNEL_FreeIntegerId(
  125966. + IN gctPOINTER Database,
  125967. + IN gctUINT32 Id
  125968. + );
  125969. +
  125970. +gceSTATUS
  125971. +gckKERNEL_QueryIntegerId(
  125972. + IN gctPOINTER Database,
  125973. + IN gctUINT32 Id,
  125974. + OUT gctPOINTER * Pointer
  125975. + );
  125976. +
  125977. +gctUINT32
  125978. +gckKERNEL_AllocateNameFromPointer(
  125979. + IN gckKERNEL Kernel,
  125980. + IN gctPOINTER Pointer
  125981. + );
  125982. +
  125983. +gctPOINTER
  125984. +gckKERNEL_QueryPointerFromName(
  125985. + IN gckKERNEL Kernel,
  125986. + IN gctUINT32 Name
  125987. + );
  125988. +
  125989. +gceSTATUS
  125990. +gckKERNEL_DeleteName(
  125991. + IN gckKERNEL Kernel,
  125992. + IN gctUINT32 Name
  125993. + );
  125994. +
  125995. +#if gcdSECURE_USER
  125996. +/* Get secure cache from the process database. */
  125997. +gceSTATUS
  125998. +gckKERNEL_GetProcessDBCache(
  125999. + IN gckKERNEL Kernel,
  126000. + IN gctUINT32 ProcessID,
  126001. + OUT gcskSECURE_CACHE_PTR * Cache
  126002. + );
  126003. +#endif
  126004. +
  126005. +/*******************************************************************************
  126006. +********* Timer Management ****************************************************/
  126007. +typedef struct _gcsTIMER * gcsTIMER_PTR;
  126008. +typedef struct _gcsTIMER
  126009. +{
  126010. + /* Start and Stop time holders. */
  126011. + gctUINT64 startTime;
  126012. + gctUINT64 stopTime;
  126013. +}
  126014. +gcsTIMER;
  126015. +
  126016. +/******************************************************************************\
  126017. +********************************** Structures **********************************
  126018. +\******************************************************************************/
  126019. +
  126020. +/* gckDB object. */
  126021. +struct _gckDB
  126022. +{
  126023. + /* Database management. */
  126024. + gcsDATABASE_PTR db[16];
  126025. + gctPOINTER dbMutex;
  126026. + gcsDATABASE_PTR freeDatabase;
  126027. + gcsDATABASE_RECORD_PTR freeRecord;
  126028. + gcsDATABASE_PTR lastDatabase;
  126029. + gctUINT32 lastProcessID;
  126030. + gctUINT64 lastIdle;
  126031. + gctUINT64 idleTime;
  126032. + gctUINT64 lastSlowdown;
  126033. + gctUINT64 lastSlowdownIdle;
  126034. + /* ID - Pointer database*/
  126035. + gctPOINTER pointerDatabase;
  126036. + gctPOINTER pointerDatabaseMutex;
  126037. +};
  126038. +
  126039. +#if gcdVIRTUAL_COMMAND_BUFFER
  126040. +typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
  126041. +typedef struct _gckVIRTUAL_COMMAND_BUFFER
  126042. +{
  126043. + gctPHYS_ADDR physical;
  126044. + gctPOINTER userLogical;
  126045. + gctPOINTER kernelLogical;
  126046. + gctSIZE_T pageCount;
  126047. + gctPOINTER pageTable;
  126048. + gctUINT32 gpuAddress;
  126049. + gctUINT pid;
  126050. + gckVIRTUAL_COMMAND_BUFFER_PTR next;
  126051. + gckVIRTUAL_COMMAND_BUFFER_PTR prev;
  126052. + gckKERNEL kernel;
  126053. +}
  126054. +gckVIRTUAL_COMMAND_BUFFER;
  126055. +#endif
  126056. +
  126057. +/* gckKERNEL object. */
  126058. +struct _gckKERNEL
  126059. +{
  126060. + /* Object. */
  126061. + gcsOBJECT object;
  126062. +
  126063. + /* Pointer to gckOS object. */
  126064. + gckOS os;
  126065. +
  126066. + /* Core */
  126067. + gceCORE core;
  126068. +
  126069. + /* Pointer to gckHARDWARE object. */
  126070. + gckHARDWARE hardware;
  126071. +
  126072. + /* Pointer to gckCOMMAND object. */
  126073. + gckCOMMAND command;
  126074. +
  126075. + /* Pointer to gckEVENT object. */
  126076. + gckEVENT eventObj;
  126077. +
  126078. + /* Pointer to context. */
  126079. + gctPOINTER context;
  126080. +
  126081. + /* Pointer to gckMMU object. */
  126082. + gckMMU mmu;
  126083. +
  126084. + /* Arom holding number of clients. */
  126085. + gctPOINTER atomClients;
  126086. +
  126087. +#if VIVANTE_PROFILER
  126088. + /* Enable profiling */
  126089. + gctBOOL profileEnable;
  126090. +
  126091. + /* Clear profile register or not*/
  126092. + gctBOOL profileCleanRegister;
  126093. +
  126094. +#endif
  126095. +
  126096. +#ifdef QNX_SINGLE_THREADED_DEBUGGING
  126097. + gctPOINTER debugMutex;
  126098. +#endif
  126099. +
  126100. + /* Database management. */
  126101. + gckDB db;
  126102. + gctBOOL dbCreated;
  126103. +
  126104. +#if gcdENABLE_RECOVERY
  126105. + gctPOINTER resetFlagClearTimer;
  126106. + gctPOINTER resetAtom;
  126107. + gctUINT64 resetTimeStamp;
  126108. +#endif
  126109. +
  126110. + /* Pointer to gckEVENT object. */
  126111. + gcsTIMER timers[8];
  126112. + gctUINT32 timeOut;
  126113. +
  126114. +#if gcdENABLE_VG
  126115. + gckVGKERNEL vg;
  126116. +#endif
  126117. +
  126118. +#if gcdVIRTUAL_COMMAND_BUFFER
  126119. + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
  126120. + gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
  126121. + gctPOINTER virtualBufferLock;
  126122. +#endif
  126123. +
  126124. +#if gcdDVFS
  126125. + gckDVFS dvfs;
  126126. +#endif
  126127. +
  126128. +#if gcdANDROID_NATIVE_FENCE_SYNC
  126129. + gctHANDLE timeline;
  126130. +#endif
  126131. +
  126132. + spinlock_t irq_lock;
  126133. +};
  126134. +
  126135. +struct _FrequencyHistory
  126136. +{
  126137. + gctUINT32 frequency;
  126138. + gctUINT32 count;
  126139. +};
  126140. +
  126141. +/* gckDVFS object. */
  126142. +struct _gckDVFS
  126143. +{
  126144. + gckOS os;
  126145. + gckHARDWARE hardware;
  126146. + gctPOINTER timer;
  126147. + gctUINT32 pollingTime;
  126148. + gctBOOL stop;
  126149. + gctUINT32 totalConfig;
  126150. + gctUINT32 loads[8];
  126151. + gctUINT8 currentScale;
  126152. + struct _FrequencyHistory frequencyHistory[16];
  126153. +};
  126154. +
  126155. +/* gckCOMMAND object. */
  126156. +struct _gckCOMMAND
  126157. +{
  126158. + /* Object. */
  126159. + gcsOBJECT object;
  126160. +
  126161. + /* Pointer to required object. */
  126162. + gckKERNEL kernel;
  126163. + gckOS os;
  126164. +
  126165. + /* Number of bytes per page. */
  126166. + gctSIZE_T pageSize;
  126167. +
  126168. + /* Current pipe select. */
  126169. + gcePIPE_SELECT pipeSelect;
  126170. +
  126171. + /* Command queue running flag. */
  126172. + gctBOOL running;
  126173. +
  126174. + /* Idle flag and commit stamp. */
  126175. + gctBOOL idle;
  126176. + gctUINT64 commitStamp;
  126177. +
  126178. + /* Command queue mutex. */
  126179. + gctPOINTER mutexQueue;
  126180. +
  126181. + /* Context switching mutex. */
  126182. + gctPOINTER mutexContext;
  126183. +
  126184. +#if VIVANTE_PROFILER_CONTEXT
  126185. + /* Context sequence mutex. */
  126186. + gctPOINTER mutexContextSeq;
  126187. +#endif
  126188. +
  126189. + /* Command queue power semaphore. */
  126190. + gctPOINTER powerSemaphore;
  126191. +
  126192. + /* Current command queue. */
  126193. + struct _gcskCOMMAND_QUEUE
  126194. + {
  126195. + gctSIGNAL signal;
  126196. + gctPHYS_ADDR physical;
  126197. + gctPOINTER logical;
  126198. + }
  126199. + queues[gcdCOMMAND_QUEUES];
  126200. +
  126201. + gctPHYS_ADDR physical;
  126202. + gctPOINTER logical;
  126203. + gctUINT32 offset;
  126204. + gctINT index;
  126205. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  126206. + gctUINT wrapCount;
  126207. +#endif
  126208. +
  126209. + /* The command queue is new. */
  126210. + gctBOOL newQueue;
  126211. +
  126212. + /* Context management. */
  126213. + gckCONTEXT currContext;
  126214. +
  126215. + /* Pointer to last WAIT command. */
  126216. + gctPHYS_ADDR waitPhysical;
  126217. + gctPOINTER waitLogical;
  126218. + gctSIZE_T waitSize;
  126219. +
  126220. + /* Command buffer alignment. */
  126221. + gctSIZE_T alignment;
  126222. + gctSIZE_T reservedHead;
  126223. + gctSIZE_T reservedTail;
  126224. +
  126225. + /* Commit counter. */
  126226. + gctPOINTER atomCommit;
  126227. +
  126228. + /* Kernel process ID. */
  126229. + gctUINT32 kernelProcessID;
  126230. +
  126231. + /* End Event signal. */
  126232. + gctSIGNAL endEventSignal;
  126233. +
  126234. +#if gcdSECURE_USER
  126235. + /* Hint array copy buffer. */
  126236. + gctBOOL hintArrayAllocated;
  126237. + gctUINT hintArraySize;
  126238. + gctUINT32_PTR hintArray;
  126239. +#endif
  126240. +};
  126241. +
  126242. +typedef struct _gcsEVENT * gcsEVENT_PTR;
  126243. +
  126244. +/* Structure holding one event to be processed. */
  126245. +typedef struct _gcsEVENT
  126246. +{
  126247. + /* Pointer to next event in queue. */
  126248. + gcsEVENT_PTR next;
  126249. +
  126250. + /* Event information. */
  126251. + gcsHAL_INTERFACE info;
  126252. +
  126253. + /* Process ID owning the event. */
  126254. + gctUINT32 processID;
  126255. +
  126256. +#ifdef __QNXNTO__
  126257. + /* Kernel. */
  126258. + gckKERNEL kernel;
  126259. +#endif
  126260. +
  126261. + gctBOOL fromKernel;
  126262. +}
  126263. +gcsEVENT;
  126264. +
  126265. +/* Structure holding a list of events to be processed by an interrupt. */
  126266. +typedef struct _gcsEVENT_QUEUE * gcsEVENT_QUEUE_PTR;
  126267. +typedef struct _gcsEVENT_QUEUE
  126268. +{
  126269. + /* Time stamp. */
  126270. + gctUINT64 stamp;
  126271. +
  126272. + /* Source of the event. */
  126273. + gceKERNEL_WHERE source;
  126274. +
  126275. + /* Pointer to head of event queue. */
  126276. + gcsEVENT_PTR head;
  126277. +
  126278. + /* Pointer to tail of event queue. */
  126279. + gcsEVENT_PTR tail;
  126280. +
  126281. + /* Next list of events. */
  126282. + gcsEVENT_QUEUE_PTR next;
  126283. +}
  126284. +gcsEVENT_QUEUE;
  126285. +
  126286. +/*
  126287. + gcdREPO_LIST_COUNT defines the maximum number of event queues with different
  126288. + hardware module sources that may coexist at the same time. Only two sources
  126289. + are supported - gcvKERNEL_COMMAND and gcvKERNEL_PIXEL. gcvKERNEL_COMMAND
  126290. + source is used only for managing the kernel command queue and is only issued
  126291. + when the current command queue gets full. Since we commit event queues every
  126292. + time we commit command buffers, in the worst case we can have up to three
  126293. + pending event queues:
  126294. + - gcvKERNEL_PIXEL
  126295. + - gcvKERNEL_COMMAND (queue overflow)
  126296. + - gcvKERNEL_PIXEL
  126297. +*/
  126298. +#define gcdREPO_LIST_COUNT 3
  126299. +
  126300. +/* gckEVENT object. */
  126301. +struct _gckEVENT
  126302. +{
  126303. + /* The object. */
  126304. + gcsOBJECT object;
  126305. +
  126306. + /* Pointer to required objects. */
  126307. + gckOS os;
  126308. + gckKERNEL kernel;
  126309. +
  126310. + /* Time stamp. */
  126311. + gctUINT64 stamp;
  126312. + gctUINT64 lastCommitStamp;
  126313. +
  126314. + /* Queue mutex. */
  126315. + gctPOINTER eventQueueMutex;
  126316. +
  126317. + /* Array of event queues. */
  126318. + gcsEVENT_QUEUE queues[30];
  126319. + gctUINT8 lastID;
  126320. + gctPOINTER freeAtom;
  126321. +
  126322. + /* Pending events. */
  126323. +#if gcdSMP
  126324. + gctPOINTER pending;
  126325. +#else
  126326. + volatile gctUINT pending;
  126327. +#endif
  126328. +
  126329. + /* List of free event structures and its mutex. */
  126330. + gcsEVENT_PTR freeEventList;
  126331. + gctSIZE_T freeEventCount;
  126332. + gctPOINTER freeEventMutex;
  126333. +
  126334. + /* Event queues. */
  126335. + gcsEVENT_QUEUE_PTR queueHead;
  126336. + gcsEVENT_QUEUE_PTR queueTail;
  126337. + gcsEVENT_QUEUE_PTR freeList;
  126338. + gcsEVENT_QUEUE repoList[gcdREPO_LIST_COUNT];
  126339. + gctPOINTER eventListMutex;
  126340. +
  126341. + gctPOINTER submitTimer;
  126342. +
  126343. + volatile gctBOOL inNotify;
  126344. +};
  126345. +
  126346. +/* Free all events belonging to a process. */
  126347. +gceSTATUS
  126348. +gckEVENT_FreeProcess(
  126349. + IN gckEVENT Event,
  126350. + IN gctUINT32 ProcessID
  126351. + );
  126352. +
  126353. +gceSTATUS
  126354. +gckEVENT_Stop(
  126355. + IN gckEVENT Event,
  126356. + IN gctUINT32 ProcessID,
  126357. + IN gctPHYS_ADDR Handle,
  126358. + IN gctPOINTER Logical,
  126359. + IN gctSIGNAL Signal,
  126360. + IN OUT gctSIZE_T * waitSize
  126361. + );
  126362. +
  126363. +gceSTATUS
  126364. +gckEVENT_WaitEmpty(
  126365. + IN gckEVENT Event
  126366. + );
  126367. +
  126368. +/* gcuVIDMEM_NODE structure. */
  126369. +typedef union _gcuVIDMEM_NODE
  126370. +{
  126371. + /* Allocated from gckVIDMEM. */
  126372. + struct _gcsVIDMEM_NODE_VIDMEM
  126373. + {
  126374. + /* Owner of this node. */
  126375. + gckVIDMEM memory;
  126376. +
  126377. + /* Dual-linked list of nodes. */
  126378. + gcuVIDMEM_NODE_PTR next;
  126379. + gcuVIDMEM_NODE_PTR prev;
  126380. +
  126381. + /* Dual linked list of free nodes. */
  126382. + gcuVIDMEM_NODE_PTR nextFree;
  126383. + gcuVIDMEM_NODE_PTR prevFree;
  126384. +
  126385. + /* Information for this node. */
  126386. + gctUINT32 offset;
  126387. + gctSIZE_T bytes;
  126388. + gctUINT32 alignment;
  126389. +
  126390. +#ifdef __QNXNTO__
  126391. + /* Client/server vaddr (mapped using mmap_join). */
  126392. + gctPOINTER logical;
  126393. +#endif
  126394. +
  126395. + /* Locked counter. */
  126396. + gctINT32 locked;
  126397. +
  126398. + /* Memory pool. */
  126399. + gcePOOL pool;
  126400. + gctUINT32 physical;
  126401. +
  126402. + /* Process ID owning this memory. */
  126403. + gctUINT32 processID;
  126404. +
  126405. + /* Prevent compositor from freeing until client unlocks. */
  126406. + gctBOOL freePending;
  126407. +
  126408. + /* */
  126409. + gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
  126410. +
  126411. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  126412. + gctPOINTER kernelVirtual;
  126413. +#endif
  126414. +
  126415. + /* Surface type. */
  126416. + gceSURF_TYPE type;
  126417. + }
  126418. + VidMem;
  126419. +
  126420. + /* Allocated from gckOS. */
  126421. + struct _gcsVIDMEM_NODE_VIRTUAL
  126422. + {
  126423. + /* Pointer to gckKERNEL object. */
  126424. + gckKERNEL kernel;
  126425. +
  126426. + /* Information for this node. */
  126427. + /* Contiguously allocated? */
  126428. + gctBOOL contiguous;
  126429. + /* mdl record pointer... a kmalloc address. Process agnostic. */
  126430. + gctPHYS_ADDR physical;
  126431. + gctSIZE_T bytes;
  126432. + /* do_mmap_pgoff address... mapped per-process. */
  126433. + gctPOINTER logical;
  126434. +
  126435. + /* Page table information. */
  126436. + /* Used only when node is not contiguous */
  126437. + gctSIZE_T pageCount;
  126438. +
  126439. + /* Used only when node is not contiguous */
  126440. + gctPOINTER pageTables[gcdMAX_GPU_COUNT];
  126441. + /* Pointer to gckKERNEL object who lock this. */
  126442. + gckKERNEL lockKernels[gcdMAX_GPU_COUNT];
  126443. + /* Actual physical address */
  126444. + gctUINT32 addresses[gcdMAX_GPU_COUNT];
  126445. +
  126446. + /* Mutex. */
  126447. + gctPOINTER mutex;
  126448. +
  126449. + /* Locked counter. */
  126450. + gctINT32 lockeds[gcdMAX_GPU_COUNT];
  126451. +
  126452. +#ifdef __QNXNTO__
  126453. + /* Single linked list of nodes. */
  126454. + gcuVIDMEM_NODE_PTR next;
  126455. +
  126456. + /* Unlock pending flag. */
  126457. + gctBOOL unlockPendings[gcdMAX_GPU_COUNT];
  126458. +
  126459. + /* Free pending flag. */
  126460. + gctBOOL freePending;
  126461. +#endif
  126462. +
  126463. + /* Process ID owning this memory. */
  126464. + gctUINT32 processID;
  126465. +
  126466. + /* Owner process sets freed to true
  126467. + * when it trys to free a locked
  126468. + * node */
  126469. + gctBOOL freed;
  126470. +
  126471. + /* */
  126472. + gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
  126473. +
  126474. + /* Surface type. */
  126475. + gceSURF_TYPE type;
  126476. + }
  126477. + Virtual;
  126478. +}
  126479. +gcuVIDMEM_NODE;
  126480. +
  126481. +/* gckVIDMEM object. */
  126482. +struct _gckVIDMEM
  126483. +{
  126484. + /* Object. */
  126485. + gcsOBJECT object;
  126486. +
  126487. + /* Pointer to gckOS object. */
  126488. + gckOS os;
  126489. +
  126490. + /* Information for this video memory heap. */
  126491. + gctUINT32 baseAddress;
  126492. + gctSIZE_T bytes;
  126493. + gctSIZE_T freeBytes;
  126494. +
  126495. + /* Mapping for each type of surface. */
  126496. + gctINT mapping[gcvSURF_NUM_TYPES];
  126497. +
  126498. + /* Sentinel nodes for up to 8 banks. */
  126499. + gcuVIDMEM_NODE sentinel[8];
  126500. +
  126501. + /* Allocation threshold. */
  126502. + gctSIZE_T threshold;
  126503. +
  126504. + /* The heap mutex. */
  126505. + gctPOINTER mutex;
  126506. +
  126507. +#if gcdUSE_VIDMEM_PER_PID
  126508. + /* The Pid this VidMem belongs to. */
  126509. + gctUINT32 pid;
  126510. +
  126511. + struct _gckVIDMEM* next;
  126512. +#endif
  126513. +};
  126514. +
  126515. +/* gckMMU object. */
  126516. +struct _gckMMU
  126517. +{
  126518. + /* The object. */
  126519. + gcsOBJECT object;
  126520. +
  126521. + /* Pointer to gckOS object. */
  126522. + gckOS os;
  126523. +
  126524. + /* Pointer to gckHARDWARE object. */
  126525. + gckHARDWARE hardware;
  126526. +
  126527. + /* The page table mutex. */
  126528. + gctPOINTER pageTableMutex;
  126529. +
  126530. + /* Page table information. */
  126531. + gctSIZE_T pageTableSize;
  126532. + gctPHYS_ADDR pageTablePhysical;
  126533. + gctUINT32_PTR pageTableLogical;
  126534. + gctUINT32 pageTableEntries;
  126535. +
  126536. + /* Master TLB information. */
  126537. + gctSIZE_T mtlbSize;
  126538. + gctPHYS_ADDR mtlbPhysical;
  126539. + gctUINT32_PTR mtlbLogical;
  126540. + gctUINT32 mtlbEntries;
  126541. +
  126542. + /* Free entries. */
  126543. + gctUINT32 heapList;
  126544. + gctBOOL freeNodes;
  126545. +
  126546. + gctPOINTER staticSTLB;
  126547. + gctBOOL enabled;
  126548. +
  126549. + gctUINT32 dynamicMappingStart;
  126550. +
  126551. +#ifdef __QNXNTO__
  126552. + /* Single linked list of all allocated nodes. */
  126553. + gctPOINTER nodeMutex;
  126554. + gcuVIDMEM_NODE_PTR nodeList;
  126555. +#endif
  126556. +};
  126557. +
  126558. +#if gcdVIRTUAL_COMMAND_BUFFER
  126559. +gceSTATUS
  126560. +gckOS_CreateKernelVirtualMapping(
  126561. + IN gctPHYS_ADDR Physical,
  126562. + OUT gctSIZE_T * PageCount,
  126563. + OUT gctPOINTER * Logical
  126564. + );
  126565. +
  126566. +gceSTATUS
  126567. +gckOS_DestroyKernelVirtualMapping(
  126568. + IN gctPOINTER Logical
  126569. + );
  126570. +
  126571. +gceSTATUS
  126572. +gckKERNEL_AllocateVirtualCommandBuffer(
  126573. + IN gckKERNEL Kernel,
  126574. + IN gctBOOL InUserSpace,
  126575. + IN OUT gctSIZE_T * Bytes,
  126576. + OUT gctPHYS_ADDR * Physical,
  126577. + OUT gctPOINTER * Logical
  126578. + );
  126579. +
  126580. +gceSTATUS
  126581. +gckKERNEL_DestroyVirtualCommandBuffer(
  126582. + IN gckKERNEL Kernel,
  126583. + IN gctSIZE_T Bytes,
  126584. + IN gctPHYS_ADDR Physical,
  126585. + IN gctPOINTER Logical
  126586. + );
  126587. +
  126588. +gceSTATUS
  126589. +gckKERNEL_GetGPUAddress(
  126590. + IN gckKERNEL Kernel,
  126591. + IN gctPOINTER Logical,
  126592. + OUT gctUINT32 * Address
  126593. + );
  126594. +
  126595. +gceSTATUS
  126596. +gckKERNEL_QueryGPUAddress(
  126597. + IN gckKERNEL Kernel,
  126598. + IN gctUINT32 GpuAddress,
  126599. + OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
  126600. + );
  126601. +#endif
  126602. +
  126603. +gceSTATUS
  126604. +gckKERNEL_AttachProcess(
  126605. + IN gckKERNEL Kernel,
  126606. + IN gctBOOL Attach
  126607. + );
  126608. +
  126609. +gceSTATUS
  126610. +gckKERNEL_AttachProcessEx(
  126611. + IN gckKERNEL Kernel,
  126612. + IN gctBOOL Attach,
  126613. + IN gctUINT32 PID
  126614. + );
  126615. +
  126616. +#if gcdSECURE_USER
  126617. +gceSTATUS
  126618. +gckKERNEL_MapLogicalToPhysical(
  126619. + IN gckKERNEL Kernel,
  126620. + IN gcskSECURE_CACHE_PTR Cache,
  126621. + IN OUT gctPOINTER * Data
  126622. + );
  126623. +
  126624. +gceSTATUS
  126625. +gckKERNEL_FlushTranslationCache(
  126626. + IN gckKERNEL Kernel,
  126627. + IN gcskSECURE_CACHE_PTR Cache,
  126628. + IN gctPOINTER Logical,
  126629. + IN gctSIZE_T Bytes
  126630. + );
  126631. +#endif
  126632. +
  126633. +gceSTATUS
  126634. +gckHARDWARE_QueryIdle(
  126635. + IN gckHARDWARE Hardware,
  126636. + OUT gctBOOL_PTR IsIdle
  126637. + );
  126638. +
  126639. +/******************************************************************************\
  126640. +******************************* gckCONTEXT Object *******************************
  126641. +\******************************************************************************/
  126642. +
  126643. +gceSTATUS
  126644. +gckCONTEXT_Construct(
  126645. + IN gckOS Os,
  126646. + IN gckHARDWARE Hardware,
  126647. + IN gctUINT32 ProcessID,
  126648. + OUT gckCONTEXT * Context
  126649. + );
  126650. +
  126651. +gceSTATUS
  126652. +gckCONTEXT_Destroy(
  126653. + IN gckCONTEXT Context
  126654. + );
  126655. +
  126656. +gceSTATUS
  126657. +gckCONTEXT_Update(
  126658. + IN gckCONTEXT Context,
  126659. + IN gctUINT32 ProcessID,
  126660. + IN gcsSTATE_DELTA_PTR StateDelta
  126661. + );
  126662. +
  126663. +#if gcdLINK_QUEUE_SIZE
  126664. +void
  126665. +gckLINKQUEUE_Enqueue(
  126666. + IN gckLINKQUEUE LinkQueue,
  126667. + IN gctUINT32 start,
  126668. + IN gctUINT32 end
  126669. + );
  126670. +
  126671. +void
  126672. +gckLINKQUEUE_GetData(
  126673. + IN gckLINKQUEUE LinkQueue,
  126674. + IN gctUINT32 Index,
  126675. + OUT gckLINKDATA * Data
  126676. + );
  126677. +#endif
  126678. +
  126679. +
  126680. +#ifdef __cplusplus
  126681. +}
  126682. +#endif
  126683. +
  126684. +#endif /* __gc_hal_kernel_h_ */
  126685. diff -Nur linux-3.14.17/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
  126686. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c 1970-01-01 01:00:00.000000000 +0100
  126687. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c 2014-09-11 18:06:03.110042404 +0200
  126688. @@ -0,0 +1,859 @@
  126689. +/****************************************************************************
  126690. +*
  126691. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  126692. +*
  126693. +* This program is free software; you can redistribute it and/or modify
  126694. +* it under the terms of the GNU General Public License as published by
  126695. +* the Free Software Foundation; either version 2 of the license, or
  126696. +* (at your option) any later version.
  126697. +*
  126698. +* This program is distributed in the hope that it will be useful,
  126699. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  126700. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  126701. +* GNU General Public License for more details.
  126702. +*
  126703. +* You should have received a copy of the GNU General Public License
  126704. +* along with this program; if not write to the Free Software
  126705. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  126706. +*
  126707. +*****************************************************************************/
  126708. +
  126709. +
  126710. +/**
  126711. +** @file
  126712. +** gckHEAP object for kernel HAL layer. The heap implemented here is an arena-
  126713. +** based memory allocation. An arena-based memory heap allocates data quickly
  126714. +** from specified arenas and reduces memory fragmentation.
  126715. +**
  126716. +*/
  126717. +#include "gc_hal_kernel_precomp.h"
  126718. +
  126719. +#define _GC_OBJ_ZONE gcvZONE_HEAP
  126720. +
  126721. +/*******************************************************************************
  126722. +***** Structures ***************************************************************
  126723. +*******************************************************************************/
  126724. +
  126725. +#define gcdIN_USE ((gcskNODE_PTR) ~0)
  126726. +
  126727. +typedef struct _gcskNODE * gcskNODE_PTR;
  126728. +typedef struct _gcskNODE
  126729. +{
  126730. + /* Number of byets in node. */
  126731. + gctSIZE_T bytes;
  126732. +
  126733. + /* Pointer to next free node, or gcvNULL to mark the node as freed, or
  126734. + ** gcdIN_USE to mark the node as used. */
  126735. + gcskNODE_PTR next;
  126736. +
  126737. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  126738. + /* Time stamp of allocation. */
  126739. + gctUINT64 timeStamp;
  126740. +#endif
  126741. +}
  126742. +gcskNODE;
  126743. +
  126744. +typedef struct _gcskHEAP * gcskHEAP_PTR;
  126745. +typedef struct _gcskHEAP
  126746. +{
  126747. + /* Linked list. */
  126748. + gcskHEAP_PTR next;
  126749. + gcskHEAP_PTR prev;
  126750. +
  126751. + /* Heap size. */
  126752. + gctSIZE_T size;
  126753. +
  126754. + /* Free list. */
  126755. + gcskNODE_PTR freeList;
  126756. +}
  126757. +gcskHEAP;
  126758. +
  126759. +struct _gckHEAP
  126760. +{
  126761. + /* Object. */
  126762. + gcsOBJECT object;
  126763. +
  126764. + /* Pointer to a gckOS object. */
  126765. + gckOS os;
  126766. +
  126767. + /* Locking mutex. */
  126768. + gctPOINTER mutex;
  126769. +
  126770. + /* Allocation parameters. */
  126771. + gctSIZE_T allocationSize;
  126772. +
  126773. + /* Heap list. */
  126774. + gcskHEAP_PTR heap;
  126775. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  126776. + gctUINT64 timeStamp;
  126777. +#endif
  126778. +
  126779. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  126780. + /* Profile information. */
  126781. + gctUINT32 allocCount;
  126782. + gctUINT64 allocBytes;
  126783. + gctUINT64 allocBytesMax;
  126784. + gctUINT64 allocBytesTotal;
  126785. + gctUINT32 heapCount;
  126786. + gctUINT32 heapCountMax;
  126787. + gctUINT64 heapMemory;
  126788. + gctUINT64 heapMemoryMax;
  126789. +#endif
  126790. +};
  126791. +
  126792. +/*******************************************************************************
  126793. +***** Static Support Functions *************************************************
  126794. +*******************************************************************************/
  126795. +
  126796. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  126797. +static gctSIZE_T
  126798. +_DumpHeap(
  126799. + IN gcskHEAP_PTR Heap
  126800. + )
  126801. +{
  126802. + gctPOINTER p;
  126803. + gctSIZE_T leaked = 0;
  126804. +
  126805. + /* Start at first node. */
  126806. + for (p = Heap + 1;;)
  126807. + {
  126808. + /* Convert the pointer. */
  126809. + gcskNODE_PTR node = (gcskNODE_PTR) p;
  126810. +
  126811. + /* Check if this is a used node. */
  126812. + if (node->next == gcdIN_USE)
  126813. + {
  126814. + /* Print the leaking node. */
  126815. + gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_HEAP,
  126816. + "Detected leaking: node=0x%x bytes=%lu timeStamp=%llu "
  126817. + "(%08X %c%c%c%c)",
  126818. + node, node->bytes, node->timeStamp,
  126819. + ((gctUINT32_PTR) (node + 1))[0],
  126820. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[0]),
  126821. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[1]),
  126822. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[2]),
  126823. + gcmPRINTABLE(((gctUINT8_PTR) (node + 1))[3]));
  126824. +
  126825. + /* Add leaking byte count. */
  126826. + leaked += node->bytes;
  126827. + }
  126828. +
  126829. + /* Test for end of heap. */
  126830. + if (node->bytes == 0)
  126831. + {
  126832. + break;
  126833. + }
  126834. +
  126835. + else
  126836. + {
  126837. + /* Move to next node. */
  126838. + p = (gctUINT8_PTR) node + node->bytes;
  126839. + }
  126840. + }
  126841. +
  126842. + /* Return the number of leaked bytes. */
  126843. + return leaked;
  126844. +}
  126845. +#endif
  126846. +
  126847. +static gceSTATUS
  126848. +_CompactKernelHeap(
  126849. + IN gckHEAP Heap
  126850. + )
  126851. +{
  126852. + gcskHEAP_PTR heap, next;
  126853. + gctPOINTER p;
  126854. + gcskHEAP_PTR freeList = gcvNULL;
  126855. +
  126856. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  126857. +
  126858. + /* Walk all the heaps. */
  126859. + for (heap = Heap->heap; heap != gcvNULL; heap = next)
  126860. + {
  126861. + gcskNODE_PTR lastFree = gcvNULL;
  126862. +
  126863. + /* Zero out the free list. */
  126864. + heap->freeList = gcvNULL;
  126865. +
  126866. + /* Start at the first node. */
  126867. + for (p = (gctUINT8_PTR) (heap + 1);;)
  126868. + {
  126869. + /* Convert the pointer. */
  126870. + gcskNODE_PTR node = (gcskNODE_PTR) p;
  126871. +
  126872. + gcmkASSERT(p <= (gctPOINTER) ((gctUINT8_PTR) (heap + 1) + heap->size));
  126873. +
  126874. + /* Test if this node not used. */
  126875. + if (node->next != gcdIN_USE)
  126876. + {
  126877. + /* Test if this is the end of the heap. */
  126878. + if (node->bytes == 0)
  126879. + {
  126880. + break;
  126881. + }
  126882. +
  126883. + /* Test of this is the first free node. */
  126884. + else if (lastFree == gcvNULL)
  126885. + {
  126886. + /* Initialzie the free list. */
  126887. + heap->freeList = node;
  126888. + lastFree = node;
  126889. + }
  126890. +
  126891. + else
  126892. + {
  126893. + /* Test if this free node is contiguous with the previous
  126894. + ** free node. */
  126895. + if ((gctUINT8_PTR) lastFree + lastFree->bytes == p)
  126896. + {
  126897. + /* Just increase the size of the previous free node. */
  126898. + lastFree->bytes += node->bytes;
  126899. + }
  126900. + else
  126901. + {
  126902. + /* Add to linked list. */
  126903. + lastFree->next = node;
  126904. + lastFree = node;
  126905. + }
  126906. + }
  126907. + }
  126908. +
  126909. + /* Move to next node. */
  126910. + p = (gctUINT8_PTR) node + node->bytes;
  126911. + }
  126912. +
  126913. + /* Mark the end of the chain. */
  126914. + if (lastFree != gcvNULL)
  126915. + {
  126916. + lastFree->next = gcvNULL;
  126917. + }
  126918. +
  126919. + /* Get next heap. */
  126920. + next = heap->next;
  126921. +
  126922. + /* Check if the entire heap is free. */
  126923. + if ((heap->freeList != gcvNULL)
  126924. + && (heap->freeList->bytes == heap->size - gcmSIZEOF(gcskNODE))
  126925. + )
  126926. + {
  126927. + /* Remove the heap from the linked list. */
  126928. + if (heap->prev == gcvNULL)
  126929. + {
  126930. + Heap->heap = next;
  126931. + }
  126932. + else
  126933. + {
  126934. + heap->prev->next = next;
  126935. + }
  126936. +
  126937. + if (heap->next != gcvNULL)
  126938. + {
  126939. + heap->next->prev = heap->prev;
  126940. + }
  126941. +
  126942. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  126943. + /* Update profiling. */
  126944. + Heap->heapCount -= 1;
  126945. + Heap->heapMemory -= heap->size + gcmSIZEOF(gcskHEAP);
  126946. +#endif
  126947. +
  126948. + /* Add this heap to the list of heaps that need to be freed. */
  126949. + heap->next = freeList;
  126950. + freeList = heap;
  126951. + }
  126952. + }
  126953. +
  126954. + if (freeList != gcvNULL)
  126955. + {
  126956. + /* Release the mutex, remove any chance for a dead lock. */
  126957. + gcmkVERIFY_OK(
  126958. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  126959. +
  126960. + /* Free all heaps in the free list. */
  126961. + for (heap = freeList; heap != gcvNULL; heap = next)
  126962. + {
  126963. + /* Get pointer to the next heap. */
  126964. + next = heap->next;
  126965. +
  126966. + /* Free the heap. */
  126967. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
  126968. + "Freeing heap 0x%x (%lu bytes)",
  126969. + heap, heap->size + gcmSIZEOF(gcskHEAP));
  126970. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
  126971. + }
  126972. +
  126973. + /* Acquire the mutex again. */
  126974. + gcmkVERIFY_OK(
  126975. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  126976. + }
  126977. +
  126978. + /* Success. */
  126979. + gcmkFOOTER_NO();
  126980. + return gcvSTATUS_OK;
  126981. +}
  126982. +
  126983. +/*******************************************************************************
  126984. +***** gckHEAP API Code *********************************************************
  126985. +*******************************************************************************/
  126986. +
  126987. +/*******************************************************************************
  126988. +**
  126989. +** gckHEAP_Construct
  126990. +**
  126991. +** Construct a new gckHEAP object.
  126992. +**
  126993. +** INPUT:
  126994. +**
  126995. +** gckOS Os
  126996. +** Pointer to a gckOS object.
  126997. +**
  126998. +** gctSIZE_T AllocationSize
  126999. +** Minimum size per arena.
  127000. +**
  127001. +** OUTPUT:
  127002. +**
  127003. +** gckHEAP * Heap
  127004. +** Pointer to a variable that will hold the pointer to the gckHEAP
  127005. +** object.
  127006. +*/
  127007. +gceSTATUS
  127008. +gckHEAP_Construct(
  127009. + IN gckOS Os,
  127010. + IN gctSIZE_T AllocationSize,
  127011. + OUT gckHEAP * Heap
  127012. + )
  127013. +{
  127014. + gceSTATUS status;
  127015. + gckHEAP heap = gcvNULL;
  127016. + gctPOINTER pointer = gcvNULL;
  127017. +
  127018. + gcmkHEADER_ARG("Os=0x%x AllocationSize=%lu", Os, AllocationSize);
  127019. +
  127020. + /* Verify the arguments. */
  127021. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  127022. + gcmkVERIFY_ARGUMENT(Heap != gcvNULL);
  127023. +
  127024. + /* Allocate the gckHEAP object. */
  127025. + gcmkONERROR(gckOS_AllocateMemory(Os,
  127026. + gcmSIZEOF(struct _gckHEAP),
  127027. + &pointer));
  127028. +
  127029. + heap = pointer;
  127030. +
  127031. + /* Initialize the gckHEAP object. */
  127032. + heap->object.type = gcvOBJ_HEAP;
  127033. + heap->os = Os;
  127034. + heap->allocationSize = AllocationSize;
  127035. + heap->heap = gcvNULL;
  127036. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  127037. + heap->timeStamp = 0;
  127038. +#endif
  127039. +
  127040. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  127041. + /* Zero the counters. */
  127042. + heap->allocCount = 0;
  127043. + heap->allocBytes = 0;
  127044. + heap->allocBytesMax = 0;
  127045. + heap->allocBytesTotal = 0;
  127046. + heap->heapCount = 0;
  127047. + heap->heapCountMax = 0;
  127048. + heap->heapMemory = 0;
  127049. + heap->heapMemoryMax = 0;
  127050. +#endif
  127051. +
  127052. + /* Create the mutex. */
  127053. + gcmkONERROR(gckOS_CreateMutex(Os, &heap->mutex));
  127054. +
  127055. + /* Return the pointer to the gckHEAP object. */
  127056. + *Heap = heap;
  127057. +
  127058. + /* Success. */
  127059. + gcmkFOOTER_ARG("*Heap=0x%x", *Heap);
  127060. + return gcvSTATUS_OK;
  127061. +
  127062. +OnError:
  127063. + /* Roll back. */
  127064. + if (heap != gcvNULL)
  127065. + {
  127066. + /* Free the heap structure. */
  127067. + gcmkVERIFY_OK(gckOS_FreeMemory(Os, heap));
  127068. + }
  127069. +
  127070. + /* Return the status. */
  127071. + gcmkFOOTER();
  127072. + return status;
  127073. +}
  127074. +
  127075. +/*******************************************************************************
  127076. +**
  127077. +** gckHEAP_Destroy
  127078. +**
  127079. +** Destroy a gckHEAP object.
  127080. +**
  127081. +** INPUT:
  127082. +**
  127083. +** gckHEAP Heap
  127084. +** Pointer to a gckHEAP object to destroy.
  127085. +**
  127086. +** OUTPUT:
  127087. +**
  127088. +** Nothing.
  127089. +*/
  127090. +gceSTATUS
  127091. +gckHEAP_Destroy(
  127092. + IN gckHEAP Heap
  127093. + )
  127094. +{
  127095. + gcskHEAP_PTR heap;
  127096. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  127097. + gctSIZE_T leaked = 0;
  127098. +#endif
  127099. +
  127100. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  127101. +
  127102. + for (heap = Heap->heap; heap != gcvNULL; heap = Heap->heap)
  127103. + {
  127104. + /* Unlink heap from linked list. */
  127105. + Heap->heap = heap->next;
  127106. +
  127107. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  127108. + /* Check for leaked memory. */
  127109. + leaked += _DumpHeap(heap);
  127110. +#endif
  127111. +
  127112. + /* Free the heap. */
  127113. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, heap));
  127114. + }
  127115. +
  127116. + /* Free the mutex. */
  127117. + gcmkVERIFY_OK(gckOS_DeleteMutex(Heap->os, Heap->mutex));
  127118. +
  127119. + /* Free the heap structure. */
  127120. + gcmkVERIFY_OK(gckOS_FreeMemory(Heap->os, Heap));
  127121. +
  127122. + /* Success. */
  127123. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  127124. + gcmkFOOTER_ARG("leaked=%lu", leaked);
  127125. +#else
  127126. + gcmkFOOTER_NO();
  127127. +#endif
  127128. + return gcvSTATUS_OK;
  127129. +}
  127130. +
  127131. +/*******************************************************************************
  127132. +**
  127133. +** gckHEAP_Allocate
  127134. +**
  127135. +** Allocate data from the heap.
  127136. +**
  127137. +** INPUT:
  127138. +**
  127139. +** gckHEAP Heap
  127140. +** Pointer to a gckHEAP object.
  127141. +**
  127142. +** IN gctSIZE_T Bytes
  127143. +** Number of byte to allocate.
  127144. +**
  127145. +** OUTPUT:
  127146. +**
  127147. +** gctPOINTER * Memory
  127148. +** Pointer to a variable that will hold the address of the allocated
  127149. +** memory.
  127150. +*/
  127151. +gceSTATUS
  127152. +gckHEAP_Allocate(
  127153. + IN gckHEAP Heap,
  127154. + IN gctSIZE_T Bytes,
  127155. + OUT gctPOINTER * Memory
  127156. + )
  127157. +{
  127158. + gctBOOL acquired = gcvFALSE;
  127159. + gcskHEAP_PTR heap;
  127160. + gceSTATUS status;
  127161. + gctSIZE_T bytes;
  127162. + gcskNODE_PTR node, used, prevFree = gcvNULL;
  127163. + gctPOINTER memory = gcvNULL;
  127164. +
  127165. + gcmkHEADER_ARG("Heap=0x%x Bytes=%lu", Heap, Bytes);
  127166. +
  127167. + /* Verify the arguments. */
  127168. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  127169. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  127170. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  127171. +
  127172. + /* Determine number of bytes required for a node. */
  127173. + bytes = gcmALIGN(Bytes + gcmSIZEOF(gcskNODE), 8);
  127174. +
  127175. + /* Acquire the mutex. */
  127176. + gcmkONERROR(
  127177. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  127178. +
  127179. + acquired = gcvTRUE;
  127180. +
  127181. + /* Check if this allocation is bigger than the default allocation size. */
  127182. + if (bytes > Heap->allocationSize - gcmSIZEOF(gcskHEAP) - gcmSIZEOF(gcskNODE))
  127183. + {
  127184. + /* Adjust allocation size. */
  127185. + Heap->allocationSize = bytes * 2;
  127186. + }
  127187. +
  127188. + else if (Heap->heap != gcvNULL)
  127189. + {
  127190. + gctINT i;
  127191. +
  127192. + /* 2 retries, since we might need to compact. */
  127193. + for (i = 0; i < 2; ++i)
  127194. + {
  127195. + /* Walk all the heaps. */
  127196. + for (heap = Heap->heap; heap != gcvNULL; heap = heap->next)
  127197. + {
  127198. + /* Check if this heap has enough bytes to hold the request. */
  127199. + if (bytes <= heap->size - gcmSIZEOF(gcskNODE))
  127200. + {
  127201. + prevFree = gcvNULL;
  127202. +
  127203. + /* Walk the chain of free nodes. */
  127204. + for (node = heap->freeList;
  127205. + node != gcvNULL;
  127206. + node = node->next
  127207. + )
  127208. + {
  127209. + gcmkASSERT(node->next != gcdIN_USE);
  127210. +
  127211. + /* Check if this free node has enough bytes. */
  127212. + if (node->bytes >= bytes)
  127213. + {
  127214. + /* Use the node. */
  127215. + goto UseNode;
  127216. + }
  127217. +
  127218. + /* Save current free node for linked list management. */
  127219. + prevFree = node;
  127220. + }
  127221. + }
  127222. + }
  127223. +
  127224. + if (i == 0)
  127225. + {
  127226. + /* Compact the heap. */
  127227. + gcmkVERIFY_OK(_CompactKernelHeap(Heap));
  127228. +
  127229. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  127230. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127231. + "===== KERNEL HEAP =====");
  127232. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127233. + "Number of allocations : %12u",
  127234. + Heap->allocCount);
  127235. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127236. + "Number of bytes allocated : %12llu",
  127237. + Heap->allocBytes);
  127238. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127239. + "Maximum allocation size : %12llu",
  127240. + Heap->allocBytesMax);
  127241. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127242. + "Total number of bytes allocated : %12llu",
  127243. + Heap->allocBytesTotal);
  127244. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127245. + "Number of heaps : %12u",
  127246. + Heap->heapCount);
  127247. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127248. + "Heap memory in bytes : %12llu",
  127249. + Heap->heapMemory);
  127250. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127251. + "Maximum number of heaps : %12u",
  127252. + Heap->heapCountMax);
  127253. + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_HEAP,
  127254. + "Maximum heap memory in bytes : %12llu",
  127255. + Heap->heapMemoryMax);
  127256. +#endif
  127257. + }
  127258. + }
  127259. + }
  127260. +
  127261. + /* Release the mutex. */
  127262. + gcmkONERROR(
  127263. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  127264. +
  127265. + acquired = gcvFALSE;
  127266. +
  127267. + /* Allocate a new heap. */
  127268. + gcmkONERROR(
  127269. + gckOS_AllocateMemory(Heap->os,
  127270. + Heap->allocationSize,
  127271. + &memory));
  127272. +
  127273. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HEAP,
  127274. + "Allocated heap 0x%x (%lu bytes)",
  127275. + memory, Heap->allocationSize);
  127276. +
  127277. + /* Acquire the mutex. */
  127278. + gcmkONERROR(
  127279. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  127280. +
  127281. + acquired = gcvTRUE;
  127282. +
  127283. + /* Use the allocated memory as the heap. */
  127284. + heap = (gcskHEAP_PTR) memory;
  127285. +
  127286. + /* Insert this heap to the head of the chain. */
  127287. + heap->next = Heap->heap;
  127288. + heap->prev = gcvNULL;
  127289. + heap->size = Heap->allocationSize - gcmSIZEOF(gcskHEAP);
  127290. +
  127291. + if (heap->next != gcvNULL)
  127292. + {
  127293. + heap->next->prev = heap;
  127294. + }
  127295. + Heap->heap = heap;
  127296. +
  127297. + /* Mark the end of the heap. */
  127298. + node = (gcskNODE_PTR) ( (gctUINT8_PTR) heap
  127299. + + Heap->allocationSize
  127300. + - gcmSIZEOF(gcskNODE)
  127301. + );
  127302. + node->bytes = 0;
  127303. + node->next = gcvNULL;
  127304. +
  127305. + /* Create a free list. */
  127306. + node = (gcskNODE_PTR) (heap + 1);
  127307. + heap->freeList = node;
  127308. +
  127309. + /* Initialize the free list. */
  127310. + node->bytes = heap->size - gcmSIZEOF(gcskNODE);
  127311. + node->next = gcvNULL;
  127312. +
  127313. + /* No previous free. */
  127314. + prevFree = gcvNULL;
  127315. +
  127316. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  127317. + /* Update profiling. */
  127318. + Heap->heapCount += 1;
  127319. + Heap->heapMemory += Heap->allocationSize;
  127320. +
  127321. + if (Heap->heapCount > Heap->heapCountMax)
  127322. + {
  127323. + Heap->heapCountMax = Heap->heapCount;
  127324. + }
  127325. + if (Heap->heapMemory > Heap->heapMemoryMax)
  127326. + {
  127327. + Heap->heapMemoryMax = Heap->heapMemory;
  127328. + }
  127329. +#endif
  127330. +
  127331. +UseNode:
  127332. + /* Verify some stuff. */
  127333. + gcmkASSERT(heap != gcvNULL);
  127334. + gcmkASSERT(node != gcvNULL);
  127335. + gcmkASSERT(node->bytes >= bytes);
  127336. +
  127337. + if (heap->prev != gcvNULL)
  127338. + {
  127339. + /* Unlink the heap from the linked list. */
  127340. + heap->prev->next = heap->next;
  127341. + if (heap->next != gcvNULL)
  127342. + {
  127343. + heap->next->prev = heap->prev;
  127344. + }
  127345. +
  127346. + /* Move the heap to the front of the list. */
  127347. + heap->next = Heap->heap;
  127348. + heap->prev = gcvNULL;
  127349. + Heap->heap = heap;
  127350. + heap->next->prev = heap;
  127351. + }
  127352. +
  127353. + /* Check if there is enough free space left after usage for another free
  127354. + ** node. */
  127355. + if (node->bytes - bytes >= gcmSIZEOF(gcskNODE))
  127356. + {
  127357. + /* Allocated used space from the back of the free list. */
  127358. + used = (gcskNODE_PTR) ((gctUINT8_PTR) node + node->bytes - bytes);
  127359. +
  127360. + /* Adjust the number of free bytes. */
  127361. + node->bytes -= bytes;
  127362. + gcmkASSERT(node->bytes >= gcmSIZEOF(gcskNODE));
  127363. + }
  127364. + else
  127365. + {
  127366. + /* Remove this free list from the chain. */
  127367. + if (prevFree == gcvNULL)
  127368. + {
  127369. + heap->freeList = node->next;
  127370. + }
  127371. + else
  127372. + {
  127373. + prevFree->next = node->next;
  127374. + }
  127375. +
  127376. + /* Consume the entire free node. */
  127377. + used = (gcskNODE_PTR) node;
  127378. + bytes = node->bytes;
  127379. + }
  127380. +
  127381. + /* Mark node as used. */
  127382. + used->bytes = bytes;
  127383. + used->next = gcdIN_USE;
  127384. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  127385. + used->timeStamp = ++Heap->timeStamp;
  127386. +#endif
  127387. +
  127388. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  127389. + /* Update profile counters. */
  127390. + Heap->allocCount += 1;
  127391. + Heap->allocBytes += bytes;
  127392. + Heap->allocBytesMax = gcmMAX(Heap->allocBytes, Heap->allocBytesMax);
  127393. + Heap->allocBytesTotal += bytes;
  127394. +#endif
  127395. +
  127396. + /* Release the mutex. */
  127397. + gcmkVERIFY_OK(
  127398. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  127399. +
  127400. + /* Return pointer to memory. */
  127401. + *Memory = used + 1;
  127402. +
  127403. + /* Success. */
  127404. + gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
  127405. + return gcvSTATUS_OK;
  127406. +
  127407. +OnError:
  127408. + if (acquired)
  127409. + {
  127410. + /* Release the mutex. */
  127411. + gcmkVERIFY_OK(
  127412. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  127413. + }
  127414. +
  127415. + if (memory != gcvNULL)
  127416. + {
  127417. + /* Free the heap memory. */
  127418. + gckOS_FreeMemory(Heap->os, memory);
  127419. + }
  127420. +
  127421. + /* Return the status. */
  127422. + gcmkFOOTER();
  127423. + return status;
  127424. +}
  127425. +
  127426. +/*******************************************************************************
  127427. +**
  127428. +** gckHEAP_Free
  127429. +**
  127430. +** Free allocated memory from the heap.
  127431. +**
  127432. +** INPUT:
  127433. +**
  127434. +** gckHEAP Heap
  127435. +** Pointer to a gckHEAP object.
  127436. +**
  127437. +** IN gctPOINTER Memory
  127438. +** Pointer to memory to free.
  127439. +**
  127440. +** OUTPUT:
  127441. +**
  127442. +** NOTHING.
  127443. +*/
  127444. +gceSTATUS
  127445. +gckHEAP_Free(
  127446. + IN gckHEAP Heap,
  127447. + IN gctPOINTER Memory
  127448. + )
  127449. +{
  127450. + gcskNODE_PTR node;
  127451. + gceSTATUS status;
  127452. +
  127453. + gcmkHEADER_ARG("Heap=0x%x Memory=0x%x", Heap, Memory);
  127454. +
  127455. + /* Verify the arguments. */
  127456. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  127457. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  127458. +
  127459. + /* Acquire the mutex. */
  127460. + gcmkONERROR(
  127461. + gckOS_AcquireMutex(Heap->os, Heap->mutex, gcvINFINITE));
  127462. +
  127463. + /* Pointer to structure. */
  127464. + node = (gcskNODE_PTR) Memory - 1;
  127465. +
  127466. + /* Mark the node as freed. */
  127467. + node->next = gcvNULL;
  127468. +
  127469. +#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
  127470. + /* Update profile counters. */
  127471. + Heap->allocBytes -= node->bytes;
  127472. +#endif
  127473. +
  127474. + /* Release the mutex. */
  127475. + gcmkVERIFY_OK(
  127476. + gckOS_ReleaseMutex(Heap->os, Heap->mutex));
  127477. +
  127478. + /* Success. */
  127479. + gcmkFOOTER_NO();
  127480. + return gcvSTATUS_OK;
  127481. +
  127482. +OnError:
  127483. + /* Return the status. */
  127484. + gcmkFOOTER();
  127485. + return status;
  127486. +}
  127487. +
  127488. +#if VIVANTE_PROFILER
  127489. +gceSTATUS
  127490. +gckHEAP_ProfileStart(
  127491. + IN gckHEAP Heap
  127492. + )
  127493. +{
  127494. + gcmkHEADER_ARG("Heap=0x%x", Heap);
  127495. +
  127496. + /* Verify the arguments. */
  127497. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  127498. +
  127499. + /* Zero the counters. */
  127500. + Heap->allocCount = 0;
  127501. + Heap->allocBytes = 0;
  127502. + Heap->allocBytesMax = 0;
  127503. + Heap->allocBytesTotal = 0;
  127504. + Heap->heapCount = 0;
  127505. + Heap->heapCountMax = 0;
  127506. + Heap->heapMemory = 0;
  127507. + Heap->heapMemoryMax = 0;
  127508. +
  127509. + /* Success. */
  127510. + gcmkFOOTER_NO();
  127511. + return gcvSTATUS_OK;
  127512. +}
  127513. +
  127514. +gceSTATUS
  127515. +gckHEAP_ProfileEnd(
  127516. + IN gckHEAP Heap,
  127517. + IN gctCONST_STRING Title
  127518. + )
  127519. +{
  127520. + gcmkHEADER_ARG("Heap=0x%x Title=0x%x", Heap, Title);
  127521. +
  127522. + /* Verify the arguments. */
  127523. + gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
  127524. + gcmkVERIFY_ARGUMENT(Title != gcvNULL);
  127525. +
  127526. + gcmkPRINT("");
  127527. + gcmkPRINT("=====[ HEAP - %s ]=====", Title);
  127528. + gcmkPRINT("Number of allocations : %12u", Heap->allocCount);
  127529. + gcmkPRINT("Number of bytes allocated : %12llu", Heap->allocBytes);
  127530. + gcmkPRINT("Maximum allocation size : %12llu", Heap->allocBytesMax);
  127531. + gcmkPRINT("Total number of bytes allocated : %12llu", Heap->allocBytesTotal);
  127532. + gcmkPRINT("Number of heaps : %12u", Heap->heapCount);
  127533. + gcmkPRINT("Heap memory in bytes : %12llu", Heap->heapMemory);
  127534. + gcmkPRINT("Maximum number of heaps : %12u", Heap->heapCountMax);
  127535. + gcmkPRINT("Maximum heap memory in bytes : %12llu", Heap->heapMemoryMax);
  127536. + gcmkPRINT("==============================================");
  127537. +
  127538. + /* Success. */
  127539. + gcmkFOOTER_NO();
  127540. + return gcvSTATUS_OK;
  127541. +}
  127542. +#endif /* VIVANTE_PROFILER */
  127543. +
  127544. +/*******************************************************************************
  127545. +***** Test Code ****************************************************************
  127546. +*******************************************************************************/
  127547. +
  127548. diff -Nur linux-3.14.17/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
  127549. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c 1970-01-01 01:00:00.000000000 +0100
  127550. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c 2014-09-11 18:06:03.110042404 +0200
  127551. @@ -0,0 +1,877 @@
  127552. +/****************************************************************************
  127553. +*
  127554. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  127555. +*
  127556. +* This program is free software; you can redistribute it and/or modify
  127557. +* it under the terms of the GNU General Public License as published by
  127558. +* the Free Software Foundation; either version 2 of the license, or
  127559. +* (at your option) any later version.
  127560. +*
  127561. +* This program is distributed in the hope that it will be useful,
  127562. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  127563. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  127564. +* GNU General Public License for more details.
  127565. +*
  127566. +* You should have received a copy of the GNU General Public License
  127567. +* along with this program; if not write to the Free Software
  127568. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  127569. +*
  127570. +*****************************************************************************/
  127571. +
  127572. +
  127573. +#include "gc_hal_kernel_precomp.h"
  127574. +
  127575. +#if gcdENABLE_VG
  127576. +
  127577. +/******************************************************************************\
  127578. +*********************** Support Functions and Definitions **********************
  127579. +\******************************************************************************/
  127580. +
  127581. +/* Interruot statistics will be accumulated if not zero. */
  127582. +#define gcmENABLE_INTERRUPT_STATISTICS 0
  127583. +
  127584. +#define _GC_OBJ_ZONE gcvZONE_INTERRUPT
  127585. +
  127586. +/* Object structure. */
  127587. +struct _gckVGINTERRUPT
  127588. +{
  127589. + /* Object. */
  127590. + gcsOBJECT object;
  127591. +
  127592. + /* gckVGKERNEL pointer. */
  127593. + gckVGKERNEL kernel;
  127594. +
  127595. + /* gckOS pointer. */
  127596. + gckOS os;
  127597. +
  127598. + /* Interrupt handlers. */
  127599. + gctINTERRUPT_HANDLER handlers[32];
  127600. +
  127601. + /* Main interrupt handler thread. */
  127602. + gctTHREAD handler;
  127603. + gctBOOL terminate;
  127604. +
  127605. + /* Interrupt FIFO. */
  127606. + gctSEMAPHORE fifoValid;
  127607. + gctUINT32 fifo[256];
  127608. + gctUINT fifoItems;
  127609. + gctUINT8 head;
  127610. + gctUINT8 tail;
  127611. +
  127612. + /* Interrupt statistics. */
  127613. +#if gcmENABLE_INTERRUPT_STATISTICS
  127614. + gctUINT maxFifoItems;
  127615. + gctUINT fifoOverflow;
  127616. + gctUINT maxSimultaneous;
  127617. + gctUINT multipleCount;
  127618. +#endif
  127619. +};
  127620. +
  127621. +
  127622. +/*******************************************************************************
  127623. +**
  127624. +** _ProcessInterrupt
  127625. +**
  127626. +** The interrupt processor.
  127627. +**
  127628. +** INPUT:
  127629. +**
  127630. +** ThreadParameter
  127631. +** Pointer to the gckVGINTERRUPT object.
  127632. +**
  127633. +** OUTPUT:
  127634. +**
  127635. +** Nothing.
  127636. +*/
  127637. +
  127638. +#if gcmENABLE_INTERRUPT_STATISTICS
  127639. +static void
  127640. +_ProcessInterrupt(
  127641. + gckVGINTERRUPT Interrupt,
  127642. + gctUINT_PTR TriggeredCount
  127643. + )
  127644. +#else
  127645. +static void
  127646. +_ProcessInterrupt(
  127647. + gckVGINTERRUPT Interrupt
  127648. + )
  127649. +#endif
  127650. +{
  127651. + gceSTATUS status;
  127652. + gctUINT32 triggered;
  127653. + gctUINT i;
  127654. +
  127655. + /* Advance to the next entry. */
  127656. + Interrupt->tail += 1;
  127657. + Interrupt->fifoItems -= 1;
  127658. +
  127659. + /* Get the interrupt value. */
  127660. + triggered = Interrupt->fifo[Interrupt->tail];
  127661. + gcmkASSERT(triggered != 0);
  127662. +
  127663. + gcmkTRACE_ZONE(
  127664. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  127665. + "%s: triggered=0x%08X\n",
  127666. + __FUNCTION__,
  127667. + triggered
  127668. + );
  127669. +
  127670. + /* Walk through all possible interrupts. */
  127671. + for (i = 0; i < gcmSIZEOF(Interrupt->handlers); i += 1)
  127672. + {
  127673. + /* Test if interrupt happened. */
  127674. + if ((triggered & 1) == 1)
  127675. + {
  127676. +#if gcmENABLE_INTERRUPT_STATISTICS
  127677. + if (TriggeredCount != gcvNULL)
  127678. + {
  127679. + (* TriggeredCount) += 1;
  127680. + }
  127681. +#endif
  127682. +
  127683. + /* Make sure we have valid handler. */
  127684. + if (Interrupt->handlers[i] == gcvNULL)
  127685. + {
  127686. + gcmkTRACE(
  127687. + gcvLEVEL_ERROR,
  127688. + "%s: Interrupt %d isn't registered.\n",
  127689. + __FUNCTION__, i
  127690. + );
  127691. + }
  127692. + else
  127693. + {
  127694. + gcmkTRACE_ZONE(
  127695. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  127696. + "%s: interrupt=%d\n",
  127697. + __FUNCTION__,
  127698. + i
  127699. + );
  127700. +
  127701. + /* Call the handler. */
  127702. + status = Interrupt->handlers[i] (Interrupt->kernel);
  127703. +
  127704. + if (gcmkIS_ERROR(status))
  127705. + {
  127706. + /* Failed to signal the semaphore. */
  127707. + gcmkTRACE(
  127708. + gcvLEVEL_ERROR,
  127709. + "%s: Error %d incrementing the semaphore #%d.\n",
  127710. + __FUNCTION__, status, i
  127711. + );
  127712. + }
  127713. + }
  127714. + }
  127715. +
  127716. + /* Next interrupt. */
  127717. + triggered >>= 1;
  127718. +
  127719. + /* No more interrupts to handle? */
  127720. + if (triggered == 0)
  127721. + {
  127722. + break;
  127723. + }
  127724. + }
  127725. +}
  127726. +
  127727. +
  127728. +/*******************************************************************************
  127729. +**
  127730. +** _MainInterruptHandler
  127731. +**
  127732. +** The main interrupt thread serves the interrupt FIFO and calls registered
  127733. +** handlers for the interrupts that occured. The handlers are called in the
  127734. +** sequence interrupts occured with the exception when multiple interrupts
  127735. +** occured at the same time. In that case the handler calls are "sorted" by
  127736. +** the interrupt number therefore giving the interrupts with lower numbers
  127737. +** higher priority.
  127738. +**
  127739. +** INPUT:
  127740. +**
  127741. +** ThreadParameter
  127742. +** Pointer to the gckVGINTERRUPT object.
  127743. +**
  127744. +** OUTPUT:
  127745. +**
  127746. +** Nothing.
  127747. +*/
  127748. +
  127749. +static gctTHREADFUNCRESULT gctTHREADFUNCTYPE
  127750. +_MainInterruptHandler(
  127751. + gctTHREADFUNCPARAMETER ThreadParameter
  127752. + )
  127753. +{
  127754. + gceSTATUS status;
  127755. + gckVGINTERRUPT interrupt;
  127756. +
  127757. +#if gcmENABLE_INTERRUPT_STATISTICS
  127758. + gctUINT count;
  127759. +#endif
  127760. +
  127761. + /* Cast the object. */
  127762. + interrupt = (gckVGINTERRUPT) ThreadParameter;
  127763. +
  127764. + /* Enter the loop. */
  127765. + while (gcvTRUE)
  127766. + {
  127767. + /* Wait for an interrupt. */
  127768. + status = gckOS_DecrementSemaphore(interrupt->os, interrupt->fifoValid);
  127769. +
  127770. + /* Error? */
  127771. + if (gcmkIS_ERROR(status))
  127772. + {
  127773. + break;
  127774. + }
  127775. +
  127776. + /* System termination request? */
  127777. + if (status == gcvSTATUS_TERMINATE)
  127778. + {
  127779. + break;
  127780. + }
  127781. +
  127782. + /* Driver is shutting down? */
  127783. + if (interrupt->terminate)
  127784. + {
  127785. + break;
  127786. + }
  127787. +
  127788. +#if gcmENABLE_INTERRUPT_STATISTICS
  127789. + /* Reset triggered count. */
  127790. + count = 0;
  127791. +
  127792. + /* Process the interrupt. */
  127793. + _ProcessInterrupt(interrupt, &count);
  127794. +
  127795. + /* Update conters. */
  127796. + if (count > interrupt->maxSimultaneous)
  127797. + {
  127798. + interrupt->maxSimultaneous = count;
  127799. + }
  127800. +
  127801. + if (count > 1)
  127802. + {
  127803. + interrupt->multipleCount += 1;
  127804. + }
  127805. +#else
  127806. + /* Process the interrupt. */
  127807. + _ProcessInterrupt(interrupt);
  127808. +#endif
  127809. + }
  127810. +
  127811. + return 0;
  127812. +}
  127813. +
  127814. +
  127815. +/*******************************************************************************
  127816. +**
  127817. +** _StartInterruptHandler / _StopInterruptHandler
  127818. +**
  127819. +** Main interrupt handler routine control.
  127820. +**
  127821. +** INPUT:
  127822. +**
  127823. +** ThreadParameter
  127824. +** Pointer to the gckVGINTERRUPT object.
  127825. +**
  127826. +** OUTPUT:
  127827. +**
  127828. +** Nothing.
  127829. +*/
  127830. +
  127831. +static gceSTATUS
  127832. +_StartInterruptHandler(
  127833. + gckVGINTERRUPT Interrupt
  127834. + )
  127835. +{
  127836. + gceSTATUS status, last;
  127837. +
  127838. + do
  127839. + {
  127840. + /* Objects must not be already created. */
  127841. + gcmkASSERT(Interrupt->fifoValid == gcvNULL);
  127842. + gcmkASSERT(Interrupt->handler == gcvNULL);
  127843. +
  127844. + /* Reset the termination request. */
  127845. + Interrupt->terminate = gcvFALSE;
  127846. +
  127847. +#if !gcdENABLE_INFINITE_SPEED_HW
  127848. + /* Construct the fifo semaphore. */
  127849. + gcmkERR_BREAK(gckOS_CreateSemaphoreVG(
  127850. + Interrupt->os, &Interrupt->fifoValid
  127851. + ));
  127852. +
  127853. + /* Start the interrupt handler thread. */
  127854. + gcmkERR_BREAK(gckOS_StartThread(
  127855. + Interrupt->os,
  127856. + _MainInterruptHandler,
  127857. + Interrupt,
  127858. + &Interrupt->handler
  127859. + ));
  127860. +#endif
  127861. +
  127862. + /* Success. */
  127863. + return gcvSTATUS_OK;
  127864. + }
  127865. + while (gcvFALSE);
  127866. +
  127867. + /* Roll back. */
  127868. + if (Interrupt->fifoValid != gcvNULL)
  127869. + {
  127870. + gcmkCHECK_STATUS(gckOS_DestroySemaphore(
  127871. + Interrupt->os, Interrupt->fifoValid
  127872. + ));
  127873. +
  127874. + Interrupt->fifoValid = gcvNULL;
  127875. + }
  127876. +
  127877. + /* Return the status. */
  127878. + return status;
  127879. +}
  127880. +
  127881. +static gceSTATUS
  127882. +_StopInterruptHandler(
  127883. + gckVGINTERRUPT Interrupt
  127884. + )
  127885. +{
  127886. + gceSTATUS status;
  127887. +
  127888. + do
  127889. + {
  127890. + /* Does the thread exist? */
  127891. + if (Interrupt->handler == gcvNULL)
  127892. + {
  127893. + /* The semaphore must be NULL as well. */
  127894. + gcmkASSERT(Interrupt->fifoValid == gcvNULL);
  127895. +
  127896. + /* Success. */
  127897. + status = gcvSTATUS_OK;
  127898. + break;
  127899. + }
  127900. +
  127901. + /* The semaphore must exist as well. */
  127902. + gcmkASSERT(Interrupt->fifoValid != gcvNULL);
  127903. +
  127904. + /* Set the termination request. */
  127905. + Interrupt->terminate = gcvTRUE;
  127906. +
  127907. + /* Unlock the thread. */
  127908. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  127909. + Interrupt->os, Interrupt->fifoValid
  127910. + ));
  127911. +
  127912. + /* Wait until the thread quits. */
  127913. + gcmkERR_BREAK(gckOS_StopThread(
  127914. + Interrupt->os,
  127915. + Interrupt->handler
  127916. + ));
  127917. +
  127918. + /* Destroy the semaphore. */
  127919. + gcmkERR_BREAK(gckOS_DestroySemaphore(
  127920. + Interrupt->os, Interrupt->fifoValid
  127921. + ));
  127922. +
  127923. + /* Reset handles. */
  127924. + Interrupt->handler = gcvNULL;
  127925. + Interrupt->fifoValid = gcvNULL;
  127926. + }
  127927. + while (gcvFALSE);
  127928. +
  127929. + /* Return the status. */
  127930. + return status;
  127931. +}
  127932. +
  127933. +
  127934. +/******************************************************************************\
  127935. +***************************** Interrupt Object API *****************************
  127936. +\******************************************************************************/
  127937. +
  127938. +/*******************************************************************************
  127939. +**
  127940. +** gckVGINTERRUPT_Construct
  127941. +**
  127942. +** Construct an interrupt object.
  127943. +**
  127944. +** INPUT:
  127945. +**
  127946. +** Kernel
  127947. +** Pointer to the gckVGKERNEL object.
  127948. +**
  127949. +** OUTPUT:
  127950. +**
  127951. +** Interrupt
  127952. +** Pointer to the new gckVGINTERRUPT object.
  127953. +*/
  127954. +
  127955. +gceSTATUS
  127956. +gckVGINTERRUPT_Construct(
  127957. + IN gckVGKERNEL Kernel,
  127958. + OUT gckVGINTERRUPT * Interrupt
  127959. + )
  127960. +{
  127961. + gceSTATUS status;
  127962. + gckVGINTERRUPT interrupt = gcvNULL;
  127963. +
  127964. + gcmkHEADER_ARG("Kernel=0x%x Interrupt=0x%x", Kernel, Interrupt);
  127965. +
  127966. + /* Verify argeuments. */
  127967. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  127968. + gcmkVERIFY_ARGUMENT(Interrupt != gcvNULL);
  127969. +
  127970. + do
  127971. + {
  127972. + /* Allocate the gckVGINTERRUPT structure. */
  127973. + gcmkERR_BREAK(gckOS_Allocate(
  127974. + Kernel->os,
  127975. + gcmSIZEOF(struct _gckVGINTERRUPT),
  127976. + (gctPOINTER *) &interrupt
  127977. + ));
  127978. +
  127979. + /* Reset the object data. */
  127980. + gcmkVERIFY_OK(gckOS_ZeroMemory(
  127981. + interrupt, gcmSIZEOF(struct _gckVGINTERRUPT)
  127982. + ));
  127983. +
  127984. + /* Initialize the object. */
  127985. + interrupt->object.type = gcvOBJ_INTERRUPT;
  127986. +
  127987. + /* Initialize the object pointers. */
  127988. + interrupt->kernel = Kernel;
  127989. + interrupt->os = Kernel->os;
  127990. +
  127991. + /* Initialize the current FIFO position. */
  127992. + interrupt->head = (gctUINT8)~0;
  127993. + interrupt->tail = (gctUINT8)~0;
  127994. +
  127995. + /* Start the thread. */
  127996. + gcmkERR_BREAK(_StartInterruptHandler(interrupt));
  127997. +
  127998. + /* Return interrupt object. */
  127999. + *Interrupt = interrupt;
  128000. +
  128001. + gcmkFOOTER_ARG("*Interrup=0x%x", *Interrupt);
  128002. + /* Success. */
  128003. + return gcvSTATUS_OK;
  128004. + }
  128005. + while (gcvFALSE);
  128006. +
  128007. + /* Roll back. */
  128008. + if (interrupt != gcvNULL)
  128009. + {
  128010. + /* Free the gckVGINTERRUPT structure. */
  128011. + gcmkVERIFY_OK(gckOS_Free(interrupt->os, interrupt));
  128012. + }
  128013. +
  128014. + gcmkFOOTER();
  128015. +
  128016. + /* Return the status. */
  128017. + return status;
  128018. +}
  128019. +
  128020. +
  128021. +/*******************************************************************************
  128022. +**
  128023. +** gckVGINTERRUPT_Destroy
  128024. +**
  128025. +** Destroy an interrupt object.
  128026. +**
  128027. +** INPUT:
  128028. +**
  128029. +** Interrupt
  128030. +** Pointer to the gckVGINTERRUPT object to destroy.
  128031. +**
  128032. +** OUTPUT:
  128033. +**
  128034. +** Nothing.
  128035. +*/
  128036. +
  128037. +gceSTATUS
  128038. +gckVGINTERRUPT_Destroy(
  128039. + IN gckVGINTERRUPT Interrupt
  128040. + )
  128041. +{
  128042. + gceSTATUS status;
  128043. +
  128044. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  128045. +
  128046. + /* Verify the arguments. */
  128047. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  128048. +
  128049. + do
  128050. + {
  128051. + /* Stop the interrupt thread. */
  128052. + gcmkERR_BREAK(_StopInterruptHandler(Interrupt));
  128053. +
  128054. + /* Mark the object as unknown. */
  128055. + Interrupt->object.type = gcvOBJ_UNKNOWN;
  128056. +
  128057. + /* Free the gckVGINTERRUPT structure. */
  128058. + gcmkERR_BREAK(gckOS_Free(Interrupt->os, Interrupt));
  128059. + }
  128060. + while (gcvFALSE);
  128061. +
  128062. + gcmkFOOTER();
  128063. +
  128064. + /* Return the status. */
  128065. + return status;
  128066. +}
  128067. +
  128068. +
  128069. +/*******************************************************************************
  128070. +**
  128071. +** gckVGINTERRUPT_DumpState
  128072. +**
  128073. +** Print the current state of the interrupt manager.
  128074. +**
  128075. +** INPUT:
  128076. +**
  128077. +** Interrupt
  128078. +** Pointer to a gckVGINTERRUPT object.
  128079. +**
  128080. +** OUTPUT:
  128081. +**
  128082. +** Nothing.
  128083. +*/
  128084. +
  128085. +#if gcvDEBUG
  128086. +gceSTATUS
  128087. +gckVGINTERRUPT_DumpState(
  128088. + IN gckVGINTERRUPT Interrupt
  128089. + )
  128090. +{
  128091. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  128092. + /* Verify the arguments. */
  128093. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  128094. +
  128095. + /* Print the header. */
  128096. + gcmkTRACE_ZONE(
  128097. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128098. + "%s: INTERRUPT OBJECT STATUS\n",
  128099. + __FUNCTION__
  128100. + );
  128101. +
  128102. + /* Print statistics. */
  128103. +#if gcmENABLE_INTERRUPT_STATISTICS
  128104. + gcmkTRACE_ZONE(
  128105. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128106. + " Maximum number of FIFO items accumulated at a single time: %d\n",
  128107. + Interrupt->maxFifoItems
  128108. + );
  128109. +
  128110. + gcmkTRACE_ZONE(
  128111. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128112. + " Interrupt FIFO overflow happened times: %d\n",
  128113. + Interrupt->fifoOverflow
  128114. + );
  128115. +
  128116. + gcmkTRACE_ZONE(
  128117. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128118. + " Maximum number of interrupts simultaneously generated: %d\n",
  128119. + Interrupt->maxSimultaneous
  128120. + );
  128121. +
  128122. + gcmkTRACE_ZONE(
  128123. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128124. + " Number of times when there were multiple interrupts generated: %d\n",
  128125. + Interrupt->multipleCount
  128126. + );
  128127. +#endif
  128128. +
  128129. + gcmkTRACE_ZONE(
  128130. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128131. + " The current number of entries in the FIFO: %d\n",
  128132. + Interrupt->fifoItems
  128133. + );
  128134. +
  128135. + /* Print the FIFO contents. */
  128136. + if (Interrupt->fifoItems != 0)
  128137. + {
  128138. + gctUINT8 index;
  128139. + gctUINT8 last;
  128140. +
  128141. + gcmkTRACE_ZONE(
  128142. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128143. + " FIFO current contents:\n"
  128144. + );
  128145. +
  128146. + /* Get the current pointers. */
  128147. + index = Interrupt->tail;
  128148. + last = Interrupt->head;
  128149. +
  128150. + while (index != last)
  128151. + {
  128152. + /* Advance to the next entry. */
  128153. + index += 1;
  128154. +
  128155. + gcmkTRACE_ZONE(
  128156. + gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
  128157. + " %d: 0x%08X\n",
  128158. + index, Interrupt->fifo[index]
  128159. + );
  128160. + }
  128161. + }
  128162. +
  128163. + gcmkFOOTER_NO();
  128164. + /* Success. */
  128165. + return gcvSTATUS_OK;
  128166. +}
  128167. +#endif
  128168. +
  128169. +
  128170. +/*******************************************************************************
  128171. +**
  128172. +** gckVGINTERRUPT_Enable
  128173. +**
  128174. +** Enable the specified interrupt.
  128175. +**
  128176. +** INPUT:
  128177. +**
  128178. +** Interrupt
  128179. +** Pointer to a gckVGINTERRUPT object.
  128180. +**
  128181. +** Id
  128182. +** Pointer to the variable that holds the interrupt number to be
  128183. +** registered in range 0..31.
  128184. +** If the value is less then 0, gckVGINTERRUPT_Enable will attempt
  128185. +** to find an unused interrupt. If such interrupt is found, the number
  128186. +** will be assigned to the variable if the functuion call succeedes.
  128187. +**
  128188. +** Handler
  128189. +** Pointer to the handler to register for the interrupt.
  128190. +**
  128191. +** OUTPUT:
  128192. +**
  128193. +** Nothing.
  128194. +*/
  128195. +
  128196. +gceSTATUS
  128197. +gckVGINTERRUPT_Enable(
  128198. + IN gckVGINTERRUPT Interrupt,
  128199. + IN OUT gctINT32_PTR Id,
  128200. + IN gctINTERRUPT_HANDLER Handler
  128201. + )
  128202. +{
  128203. + gceSTATUS status;
  128204. + gctINT32 i;
  128205. +
  128206. + gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x Handler=0x%x", Interrupt, Id, Handler);
  128207. +
  128208. + /* Verify the arguments. */
  128209. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  128210. + gcmkVERIFY_ARGUMENT(Id != gcvNULL);
  128211. + gcmkVERIFY_ARGUMENT(Handler != gcvNULL);
  128212. +
  128213. + do
  128214. + {
  128215. + /* See if we need to allocate an ID. */
  128216. + if (*Id < 0)
  128217. + {
  128218. + /* Find the first unused interrupt handler. */
  128219. + for (i = 0; i < gcmCOUNTOF(Interrupt->handlers); ++i)
  128220. + {
  128221. + if (Interrupt->handlers[i] == gcvNULL)
  128222. + {
  128223. + break;
  128224. + }
  128225. + }
  128226. +
  128227. + /* No unused innterrupts? */
  128228. + if (i == gcmCOUNTOF(Interrupt->handlers))
  128229. + {
  128230. + status = gcvSTATUS_OUT_OF_RESOURCES;
  128231. + break;
  128232. + }
  128233. +
  128234. + /* Update the interrupt ID. */
  128235. + *Id = i;
  128236. + }
  128237. +
  128238. + /* Make sure the ID is in range. */
  128239. + else if (*Id >= gcmCOUNTOF(Interrupt->handlers))
  128240. + {
  128241. + status = gcvSTATUS_INVALID_ARGUMENT;
  128242. + break;
  128243. + }
  128244. +
  128245. + /* Set interrupt handler. */
  128246. + Interrupt->handlers[*Id] = Handler;
  128247. +
  128248. + /* Success. */
  128249. + status = gcvSTATUS_OK;
  128250. + }
  128251. + while (gcvFALSE);
  128252. +
  128253. + gcmkFOOTER();
  128254. + /* Return the status. */
  128255. + return status;
  128256. +}
  128257. +
  128258. +
  128259. +/*******************************************************************************
  128260. +**
  128261. +** gckVGINTERRUPT_Disable
  128262. +**
  128263. +** Disable the specified interrupt.
  128264. +**
  128265. +** INPUT:
  128266. +**
  128267. +** Interrupt
  128268. +** Pointer to a gckVGINTERRUPT object.
  128269. +**
  128270. +** Id
  128271. +** Interrupt number to be disabled in range 0..31.
  128272. +**
  128273. +** OUTPUT:
  128274. +**
  128275. +** Nothing.
  128276. +*/
  128277. +
  128278. +gceSTATUS
  128279. +gckVGINTERRUPT_Disable(
  128280. + IN gckVGINTERRUPT Interrupt,
  128281. + IN gctINT32 Id
  128282. + )
  128283. +{
  128284. + gcmkHEADER_ARG("Interrupt=0x%x Id=0x%x", Interrupt, Id);
  128285. + /* Verify the arguments. */
  128286. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  128287. + gcmkVERIFY_ARGUMENT((Id >= 0) && (Id < gcmCOUNTOF(Interrupt->handlers)));
  128288. +
  128289. + /* Reset interrupt handler. */
  128290. + Interrupt->handlers[Id] = gcvNULL;
  128291. +
  128292. + gcmkFOOTER_NO();
  128293. + /* Success. */
  128294. + return gcvSTATUS_OK;
  128295. +}
  128296. +
  128297. +
  128298. +/*******************************************************************************
  128299. +**
  128300. +** gckVGINTERRUPT_Enque
  128301. +**
  128302. +** Read the interrupt status register and put the value in the interrupt FIFO.
  128303. +**
  128304. +** INPUT:
  128305. +**
  128306. +** Interrupt
  128307. +** Pointer to a gckVGINTERRUPT object.
  128308. +**
  128309. +** OUTPUT:
  128310. +**
  128311. +** Nothing.
  128312. +*/
  128313. +
  128314. +#ifndef __QNXNTO__
  128315. +gceSTATUS
  128316. +gckVGINTERRUPT_Enque(
  128317. + IN gckVGINTERRUPT Interrupt
  128318. + )
  128319. +#else
  128320. +gceSTATUS
  128321. +gckVGINTERRUPT_Enque(
  128322. + IN gckVGINTERRUPT Interrupt,
  128323. + OUT gckOS *Os,
  128324. + OUT gctSEMAPHORE *Semaphore
  128325. + )
  128326. +#endif
  128327. +{
  128328. + gceSTATUS status;
  128329. + gctUINT32 triggered;
  128330. +
  128331. + gcmkHEADER_ARG("Interrupt=0x%x", Interrupt);
  128332. +
  128333. + /* Verify the arguments. */
  128334. + gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
  128335. +
  128336. +#ifdef __QNXNTO__
  128337. + *Os = gcvNULL;
  128338. + *Semaphore = gcvNULL;
  128339. +#endif
  128340. +
  128341. + do
  128342. + {
  128343. + /* Read interrupt status register. */
  128344. + gcmkERR_BREAK(gckVGHARDWARE_ReadInterrupt(
  128345. + Interrupt->kernel->hardware, &triggered
  128346. + ));
  128347. +
  128348. + /* Mask out TS overflow interrupt */
  128349. + triggered &= 0xfffffffe;
  128350. +
  128351. + /* No interrupts to process? */
  128352. + if (triggered == 0)
  128353. + {
  128354. + status = gcvSTATUS_NOT_OUR_INTERRUPT;
  128355. + break;
  128356. + }
  128357. +
  128358. + /* FIFO overflow? */
  128359. + if (Interrupt->fifoItems == gcmCOUNTOF(Interrupt->fifo))
  128360. + {
  128361. +#if gcmENABLE_INTERRUPT_STATISTICS
  128362. + Interrupt->fifoOverflow += 1;
  128363. +#endif
  128364. +
  128365. + /* OR the interrupt with the last value in the FIFO. */
  128366. + Interrupt->fifo[Interrupt->head] |= triggered;
  128367. +
  128368. + /* Success (kind of). */
  128369. + status = gcvSTATUS_OK;
  128370. + }
  128371. + else
  128372. + {
  128373. + /* Advance to the next entry. */
  128374. + Interrupt->head += 1;
  128375. + Interrupt->fifoItems += 1;
  128376. +
  128377. +#if gcmENABLE_INTERRUPT_STATISTICS
  128378. + if (Interrupt->fifoItems > Interrupt->maxFifoItems)
  128379. + {
  128380. + Interrupt->maxFifoItems = Interrupt->fifoItems;
  128381. + }
  128382. +#endif
  128383. +
  128384. + /* Set the new value. */
  128385. + Interrupt->fifo[Interrupt->head] = triggered;
  128386. +
  128387. +#ifndef __QNXNTO__
  128388. + /* Increment the FIFO semaphore. */
  128389. + gcmkERR_BREAK(gckOS_IncrementSemaphore(
  128390. + Interrupt->os, Interrupt->fifoValid
  128391. + ));
  128392. +#else
  128393. + *Os = Interrupt->os;
  128394. + *Semaphore = Interrupt->fifoValid;
  128395. +#endif
  128396. +
  128397. + /* Windows kills our threads prematurely when the application
  128398. + exists. Verify here that the thread is still alive. */
  128399. + status = gckOS_VerifyThread(Interrupt->os, Interrupt->handler);
  128400. +
  128401. + /* Has the thread been prematurely terminated? */
  128402. + if (status != gcvSTATUS_OK)
  128403. + {
  128404. + /* Process all accumulated interrupts. */
  128405. + while (Interrupt->head != Interrupt->tail)
  128406. + {
  128407. +#if gcmENABLE_INTERRUPT_STATISTICS
  128408. + /* Process the interrupt. */
  128409. + _ProcessInterrupt(Interrupt, gcvNULL);
  128410. +#else
  128411. + /* Process the interrupt. */
  128412. + _ProcessInterrupt(Interrupt);
  128413. +#endif
  128414. + }
  128415. +
  128416. + /* Set success. */
  128417. + status = gcvSTATUS_OK;
  128418. + }
  128419. + }
  128420. + }
  128421. + while (gcvFALSE);
  128422. +
  128423. + gcmkFOOTER();
  128424. + /* Return status. */
  128425. + return status;
  128426. +}
  128427. +
  128428. +#endif /* gcdENABLE_VG */
  128429. diff -Nur linux-3.14.17/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
  128430. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c 1970-01-01 01:00:00.000000000 +0100
  128431. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c 2014-09-11 18:06:03.114042420 +0200
  128432. @@ -0,0 +1,1982 @@
  128433. +/****************************************************************************
  128434. +*
  128435. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  128436. +*
  128437. +* This program is free software; you can redistribute it and/or modify
  128438. +* it under the terms of the GNU General Public License as published by
  128439. +* the Free Software Foundation; either version 2 of the license, or
  128440. +* (at your option) any later version.
  128441. +*
  128442. +* This program is distributed in the hope that it will be useful,
  128443. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  128444. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  128445. +* GNU General Public License for more details.
  128446. +*
  128447. +* You should have received a copy of the GNU General Public License
  128448. +* along with this program; if not write to the Free Software
  128449. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  128450. +*
  128451. +*****************************************************************************/
  128452. +
  128453. +
  128454. +#include "gc_hal_kernel_precomp.h"
  128455. +
  128456. +#define _GC_OBJ_ZONE gcvZONE_MMU
  128457. +
  128458. +typedef enum _gceMMU_TYPE
  128459. +{
  128460. + gcvMMU_USED = (0 << 4),
  128461. + gcvMMU_SINGLE = (1 << 4),
  128462. + gcvMMU_FREE = (2 << 4),
  128463. +}
  128464. +gceMMU_TYPE;
  128465. +
  128466. +#define gcmENTRY_TYPE(x) (x & 0xF0)
  128467. +
  128468. +#define gcdMMU_TABLE_DUMP 0
  128469. +
  128470. +#define gcdUSE_MMU_EXCEPTION 0
  128471. +
  128472. +/*
  128473. + gcdMMU_CLEAR_VALUE
  128474. +
  128475. + The clear value for the entry of the old MMU.
  128476. +*/
  128477. +#ifndef gcdMMU_CLEAR_VALUE
  128478. +# define gcdMMU_CLEAR_VALUE 0x00000ABC
  128479. +#endif
  128480. +
  128481. +/* VIV: Start GPU address for gcvSURF_VERTEX. */
  128482. +#define gcdVERTEX_START (128 << 10)
  128483. +
  128484. +typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR;
  128485. +
  128486. +typedef struct _gcsMMU_STLB
  128487. +{
  128488. + gctPHYS_ADDR physical;
  128489. + gctUINT32_PTR logical;
  128490. + gctSIZE_T size;
  128491. + gctUINT32 physBase;
  128492. + gctSIZE_T pageCount;
  128493. + gctUINT32 mtlbIndex;
  128494. + gctUINT32 mtlbEntryNum;
  128495. + gcsMMU_STLB_PTR next;
  128496. +} gcsMMU_STLB;
  128497. +
  128498. +#if gcdSHARED_PAGETABLE
  128499. +typedef struct _gcsSharedPageTable * gcsSharedPageTable_PTR;
  128500. +typedef struct _gcsSharedPageTable
  128501. +{
  128502. + /* Shared gckMMU object. */
  128503. + gckMMU mmu;
  128504. +
  128505. + /* Hardwares which use this shared pagetable. */
  128506. + gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
  128507. +
  128508. + /* Number of cores use this shared pagetable. */
  128509. + gctUINT32 reference;
  128510. +}
  128511. +gcsSharedPageTable;
  128512. +
  128513. +static gcsSharedPageTable_PTR sharedPageTable = gcvNULL;
  128514. +#endif
  128515. +
  128516. +#if gcdMIRROR_PAGETABLE
  128517. +typedef struct _gcsMirrorPageTable * gcsMirrorPageTable_PTR;
  128518. +typedef struct _gcsMirrorPageTable
  128519. +{
  128520. + /* gckMMU objects. */
  128521. + gckMMU mmus[gcdMAX_GPU_COUNT];
  128522. +
  128523. + /* Hardwares which use this shared pagetable. */
  128524. + gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
  128525. +
  128526. + /* Number of cores use this shared pagetable. */
  128527. + gctUINT32 reference;
  128528. +}
  128529. +gcsMirrorPageTable;
  128530. +
  128531. +static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
  128532. +static gctPOINTER mirrorPageTableMutex = gcvNULL;
  128533. +#endif
  128534. +
  128535. +typedef struct _gcsDynamicSpaceNode * gcsDynamicSpaceNode_PTR;
  128536. +typedef struct _gcsDynamicSpaceNode
  128537. +{
  128538. + gctUINT32 start;
  128539. + gctINT32 entries;
  128540. +}
  128541. +gcsDynamicSpaceNode;
  128542. +
  128543. +static void
  128544. +_WritePageEntry(
  128545. + IN gctUINT32_PTR PageEntry,
  128546. + IN gctUINT32 EntryValue
  128547. + )
  128548. +{
  128549. + static gctUINT16 data = 0xff00;
  128550. +
  128551. + if (*(gctUINT8 *)&data == 0xff)
  128552. + {
  128553. + *PageEntry = gcmSWAB32(EntryValue);
  128554. + }
  128555. + else
  128556. + {
  128557. + *PageEntry = EntryValue;
  128558. + }
  128559. +}
  128560. +
  128561. +static gctUINT32
  128562. +_ReadPageEntry(
  128563. + IN gctUINT32_PTR PageEntry
  128564. + )
  128565. +{
  128566. + static gctUINT16 data = 0xff00;
  128567. + gctUINT32 entryValue;
  128568. +
  128569. + if (*(gctUINT8 *)&data == 0xff)
  128570. + {
  128571. + entryValue = *PageEntry;
  128572. + return gcmSWAB32(entryValue);
  128573. + }
  128574. + else
  128575. + {
  128576. + return *PageEntry;
  128577. + }
  128578. +}
  128579. +
  128580. +static gceSTATUS
  128581. +_FillPageTable(
  128582. + IN gctUINT32_PTR PageTable,
  128583. + IN gctUINT32 PageCount,
  128584. + IN gctUINT32 EntryValue
  128585. +)
  128586. +{
  128587. + gctUINT i;
  128588. +
  128589. + for (i = 0; i < PageCount; i++)
  128590. + {
  128591. + _WritePageEntry(PageTable + i, EntryValue);
  128592. + }
  128593. +
  128594. + return gcvSTATUS_OK;
  128595. +}
  128596. +
  128597. +static gceSTATUS
  128598. +_Link(
  128599. + IN gckMMU Mmu,
  128600. + IN gctUINT32 Index,
  128601. + IN gctUINT32 Next
  128602. + )
  128603. +{
  128604. + if (Index >= Mmu->pageTableEntries)
  128605. + {
  128606. + /* Just move heap pointer. */
  128607. + Mmu->heapList = Next;
  128608. + }
  128609. + else
  128610. + {
  128611. + /* Address page table. */
  128612. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  128613. +
  128614. + /* Dispatch on node type. */
  128615. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index])))
  128616. + {
  128617. + case gcvMMU_SINGLE:
  128618. + /* Set single index. */
  128619. + _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE);
  128620. + break;
  128621. +
  128622. + case gcvMMU_FREE:
  128623. + /* Set index. */
  128624. + _WritePageEntry(&pageTable[Index + 1], Next);
  128625. + break;
  128626. +
  128627. + default:
  128628. + gcmkFATAL("MMU table correcupted at index %u!", Index);
  128629. + return gcvSTATUS_HEAP_CORRUPTED;
  128630. + }
  128631. + }
  128632. +
  128633. + /* Success. */
  128634. + return gcvSTATUS_OK;
  128635. +}
  128636. +
  128637. +static gceSTATUS
  128638. +_AddFree(
  128639. + IN gckMMU Mmu,
  128640. + IN gctUINT32 Index,
  128641. + IN gctUINT32 Node,
  128642. + IN gctUINT32 Count
  128643. + )
  128644. +{
  128645. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  128646. +
  128647. + if (Count == 1)
  128648. + {
  128649. + /* Initialize a single page node. */
  128650. + _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
  128651. + }
  128652. + else
  128653. + {
  128654. + /* Initialize the node. */
  128655. + _WritePageEntry(pageTable + Node + 0, (Count << 8) | gcvMMU_FREE);
  128656. + _WritePageEntry(pageTable + Node + 1, ~0U);
  128657. + }
  128658. +
  128659. + /* Append the node. */
  128660. + return _Link(Mmu, Index, Node);
  128661. +}
  128662. +
  128663. +static gceSTATUS
  128664. +_Collect(
  128665. + IN gckMMU Mmu
  128666. + )
  128667. +{
  128668. + gctUINT32_PTR pageTable = Mmu->pageTableLogical;
  128669. + gceSTATUS status;
  128670. + gctUINT32 i, previous, start = 0, count = 0;
  128671. +
  128672. + previous = Mmu->heapList = ~0U;
  128673. + Mmu->freeNodes = gcvFALSE;
  128674. +
  128675. + /* Walk the entire page table. */
  128676. + for (i = 0; i < Mmu->pageTableEntries; ++i)
  128677. + {
  128678. + /* Dispatch based on type of page. */
  128679. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i])))
  128680. + {
  128681. + case gcvMMU_USED:
  128682. + /* Used page, so close any open node. */
  128683. + if (count > 0)
  128684. + {
  128685. + /* Add the node. */
  128686. + gcmkONERROR(_AddFree(Mmu, previous, start, count));
  128687. +
  128688. + /* Reset the node. */
  128689. + previous = start;
  128690. + count = 0;
  128691. + }
  128692. + break;
  128693. +
  128694. + case gcvMMU_SINGLE:
  128695. + /* Single free node. */
  128696. + if (count++ == 0)
  128697. + {
  128698. + /* Start a new node. */
  128699. + start = i;
  128700. + }
  128701. + break;
  128702. +
  128703. + case gcvMMU_FREE:
  128704. + /* A free node. */
  128705. + if (count == 0)
  128706. + {
  128707. + /* Start a new node. */
  128708. + start = i;
  128709. + }
  128710. +
  128711. + /* Advance the count. */
  128712. + count += _ReadPageEntry(&pageTable[i]) >> 8;
  128713. +
  128714. + /* Advance the index into the page table. */
  128715. + i += (_ReadPageEntry(&pageTable[i]) >> 8) - 1;
  128716. + break;
  128717. +
  128718. + default:
  128719. + gcmkFATAL("MMU page table correcupted at index %u!", i);
  128720. + return gcvSTATUS_HEAP_CORRUPTED;
  128721. + }
  128722. + }
  128723. +
  128724. + /* See if we have an open node left. */
  128725. + if (count > 0)
  128726. + {
  128727. + /* Add the node to the list. */
  128728. + gcmkONERROR(_AddFree(Mmu, previous, start, count));
  128729. + }
  128730. +
  128731. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_MMU,
  128732. + "Performed a garbage collection of the MMU heap.");
  128733. +
  128734. + /* Success. */
  128735. + return gcvSTATUS_OK;
  128736. +
  128737. +OnError:
  128738. + /* Return the staus. */
  128739. + return status;
  128740. +}
  128741. +
  128742. +static gctUINT32
  128743. +_SetPage(gctUINT32 PageAddress)
  128744. +{
  128745. + return PageAddress
  128746. + /* writable */
  128747. + | (1 << 2)
  128748. + /* Ignore exception */
  128749. + | (0 << 1)
  128750. + /* Present */
  128751. + | (1 << 0);
  128752. +}
  128753. +
  128754. +static gceSTATUS
  128755. +_FillFlatMapping(
  128756. + IN gckMMU Mmu,
  128757. + IN gctUINT32 PhysBase,
  128758. + OUT gctSIZE_T Size
  128759. + )
  128760. +{
  128761. + gceSTATUS status;
  128762. + gctBOOL mutex = gcvFALSE;
  128763. + gcsMMU_STLB_PTR head = gcvNULL, pre = gcvNULL;
  128764. + gctUINT32 start = PhysBase & (~gcdMMU_PAGE_64K_MASK);
  128765. + gctUINT32 end = (PhysBase + Size - 1) & (~gcdMMU_PAGE_64K_MASK);
  128766. + gctUINT32 mStart = start >> gcdMMU_MTLB_SHIFT;
  128767. + gctUINT32 mEnd = end >> gcdMMU_MTLB_SHIFT;
  128768. + gctUINT32 sStart = (start & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
  128769. + gctUINT32 sEnd = (end & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
  128770. +
  128771. + /* Grab the mutex. */
  128772. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  128773. + mutex = gcvTRUE;
  128774. +
  128775. + while (mStart <= mEnd)
  128776. + {
  128777. + gcmkASSERT(mStart < gcdMMU_MTLB_ENTRY_NUM);
  128778. + if (*(Mmu->mtlbLogical + mStart) == 0)
  128779. + {
  128780. + gcsMMU_STLB_PTR stlb;
  128781. + gctPOINTER pointer = gcvNULL;
  128782. + gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_64K_ENTRY_NUM - 1);
  128783. +
  128784. + gcmkONERROR(gckOS_Allocate(Mmu->os, sizeof(struct _gcsMMU_STLB), &pointer));
  128785. + stlb = pointer;
  128786. +
  128787. + stlb->mtlbEntryNum = 0;
  128788. + stlb->next = gcvNULL;
  128789. + stlb->physical = gcvNULL;
  128790. + stlb->logical = gcvNULL;
  128791. + stlb->size = gcdMMU_STLB_64K_SIZE;
  128792. + stlb->pageCount = 0;
  128793. +
  128794. + if (pre == gcvNULL)
  128795. + {
  128796. + pre = head = stlb;
  128797. + }
  128798. + else
  128799. + {
  128800. + gcmkASSERT(pre->next == gcvNULL);
  128801. + pre->next = stlb;
  128802. + pre = stlb;
  128803. + }
  128804. +
  128805. + gcmkONERROR(
  128806. + gckOS_AllocateContiguous(Mmu->os,
  128807. + gcvFALSE,
  128808. + &stlb->size,
  128809. + &stlb->physical,
  128810. + (gctPOINTER)&stlb->logical));
  128811. +
  128812. + gcmkONERROR(gckOS_ZeroMemory(stlb->logical, stlb->size));
  128813. +
  128814. + gcmkONERROR(gckOS_GetPhysicalAddress(
  128815. + Mmu->os,
  128816. + stlb->logical,
  128817. + &stlb->physBase));
  128818. +
  128819. + if (stlb->physBase & (gcdMMU_STLB_64K_SIZE - 1))
  128820. + {
  128821. + gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
  128822. + }
  128823. +
  128824. + _WritePageEntry(Mmu->mtlbLogical + mStart,
  128825. + stlb->physBase
  128826. + /* 64KB page size */
  128827. + | (1 << 2)
  128828. + /* Ignore exception */
  128829. + | (0 << 1)
  128830. + /* Present */
  128831. + | (1 << 0)
  128832. + );
  128833. +#if gcdMMU_TABLE_DUMP
  128834. + gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
  128835. + __FUNCTION__, __LINE__,
  128836. + mStart,
  128837. + _ReadPageEntry(Mmu->mtlbLogical + mStart));
  128838. +#endif
  128839. +
  128840. + stlb->mtlbIndex = mStart;
  128841. + stlb->mtlbEntryNum = 1;
  128842. +#if gcdMMU_TABLE_DUMP
  128843. + gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
  128844. + __FUNCTION__, __LINE__,
  128845. + stlb->logical,
  128846. + stlb->physBase);
  128847. +#endif
  128848. +
  128849. + while (sStart <= last)
  128850. + {
  128851. + gcmkASSERT(!(start & gcdMMU_PAGE_64K_MASK));
  128852. + _WritePageEntry(stlb->logical + sStart, _SetPage(start));
  128853. +#if gcdMMU_TABLE_DUMP
  128854. + gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
  128855. + __FUNCTION__, __LINE__,
  128856. + sStart,
  128857. + _ReadPageEntry(stlb->logical + sStart));
  128858. +#endif
  128859. + /* next page. */
  128860. + start += gcdMMU_PAGE_64K_SIZE;
  128861. + sStart++;
  128862. + stlb->pageCount++;
  128863. + }
  128864. +
  128865. + sStart = 0;
  128866. + ++mStart;
  128867. + }
  128868. + else
  128869. + {
  128870. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  128871. + }
  128872. + }
  128873. +
  128874. + /* Insert the stlb into staticSTLB. */
  128875. + if (Mmu->staticSTLB == gcvNULL)
  128876. + {
  128877. + Mmu->staticSTLB = head;
  128878. + }
  128879. + else
  128880. + {
  128881. + gcmkASSERT(pre == gcvNULL);
  128882. + gcmkASSERT(pre->next == gcvNULL);
  128883. + pre->next = Mmu->staticSTLB;
  128884. + Mmu->staticSTLB = head;
  128885. + }
  128886. +
  128887. + /* Release the mutex. */
  128888. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  128889. +
  128890. + return gcvSTATUS_OK;
  128891. +
  128892. +OnError:
  128893. +
  128894. + /* Roll back. */
  128895. + while (head != gcvNULL)
  128896. + {
  128897. + pre = head;
  128898. + head = head->next;
  128899. +
  128900. + if (pre->physical != gcvNULL)
  128901. + {
  128902. + gcmkVERIFY_OK(
  128903. + gckOS_FreeContiguous(Mmu->os,
  128904. + pre->physical,
  128905. + pre->logical,
  128906. + pre->size));
  128907. + }
  128908. +
  128909. + if (pre->mtlbEntryNum != 0)
  128910. + {
  128911. + gcmkASSERT(pre->mtlbEntryNum == 1);
  128912. + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
  128913. + }
  128914. +
  128915. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
  128916. + }
  128917. +
  128918. + if (mutex)
  128919. + {
  128920. + /* Release the mutex. */
  128921. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  128922. + }
  128923. +
  128924. + return status;
  128925. +}
  128926. +
  128927. +static gceSTATUS
  128928. +_FindDynamicSpace(
  128929. + IN gckMMU Mmu,
  128930. + OUT gcsDynamicSpaceNode_PTR *Array,
  128931. + OUT gctINT * Size
  128932. + )
  128933. +{
  128934. + gceSTATUS status = gcvSTATUS_OK;
  128935. + gctPOINTER pointer = gcvNULL;
  128936. + gcsDynamicSpaceNode_PTR array = gcvNULL;
  128937. + gctINT size = 0;
  128938. + gctINT i = 0, nodeStart = -1, nodeEntries = 0;
  128939. +
  128940. + /* Allocate memory for the array. */
  128941. + gcmkONERROR(gckOS_Allocate(Mmu->os,
  128942. + gcmSIZEOF(*array) * (gcdMMU_MTLB_ENTRY_NUM / 2),
  128943. + &pointer));
  128944. +
  128945. + array = (gcsDynamicSpaceNode_PTR)pointer;
  128946. +
  128947. + /* Loop all the entries. */
  128948. + while (i < gcdMMU_MTLB_ENTRY_NUM)
  128949. + {
  128950. + if (!Mmu->mtlbLogical[i])
  128951. + {
  128952. + if (nodeStart < 0)
  128953. + {
  128954. + /* This is the first entry of the dynamic space. */
  128955. + nodeStart = i;
  128956. + nodeEntries = 1;
  128957. + }
  128958. + else
  128959. + {
  128960. + /* Other entries of the dynamic space. */
  128961. + nodeEntries++;
  128962. + }
  128963. + }
  128964. + else if (nodeStart >= 0)
  128965. + {
  128966. + /* Save the previous node. */
  128967. + array[size].start = nodeStart;
  128968. + array[size].entries = nodeEntries;
  128969. + size++;
  128970. +
  128971. + /* Reset the start. */
  128972. + nodeStart = -1;
  128973. + nodeEntries = 0;
  128974. + }
  128975. +
  128976. + i++;
  128977. + }
  128978. +
  128979. + /* Save the previous node. */
  128980. + if (nodeStart >= 0)
  128981. + {
  128982. + array[size].start = nodeStart;
  128983. + array[size].entries = nodeEntries;
  128984. + size++;
  128985. + }
  128986. +
  128987. +#if gcdMMU_TABLE_DUMP
  128988. + for (i = 0; i < size; i++)
  128989. + {
  128990. + gckOS_Print("%s(%d): [%d]: start=%d, entries=%d.\n",
  128991. + __FUNCTION__, __LINE__,
  128992. + i,
  128993. + array[i].start,
  128994. + array[i].entries);
  128995. + }
  128996. +#endif
  128997. +
  128998. + *Array = array;
  128999. + *Size = size;
  129000. +
  129001. + return gcvSTATUS_OK;
  129002. +
  129003. +OnError:
  129004. + if (pointer != gcvNULL)
  129005. + {
  129006. + gckOS_Free(Mmu->os, pointer);
  129007. + }
  129008. +
  129009. + return status;
  129010. +}
  129011. +
  129012. +static gceSTATUS
  129013. +_SetupDynamicSpace(
  129014. + IN gckMMU Mmu
  129015. + )
  129016. +{
  129017. + gceSTATUS status;
  129018. + gcsDynamicSpaceNode_PTR nodeArray = gcvNULL;
  129019. + gctINT i, nodeArraySize = 0;
  129020. + gctUINT32 physical;
  129021. + gctINT numEntries = 0;
  129022. + gctUINT32_PTR pageTable;
  129023. + gctBOOL acquired = gcvFALSE;
  129024. +
  129025. + /* Find all the dynamic address space. */
  129026. + gcmkONERROR(_FindDynamicSpace(Mmu, &nodeArray, &nodeArraySize));
  129027. +
  129028. + /* TODO: We only use the largest one for now. */
  129029. + for (i = 0; i < nodeArraySize; i++)
  129030. + {
  129031. + if (nodeArray[i].entries > numEntries)
  129032. + {
  129033. + Mmu->dynamicMappingStart = nodeArray[i].start;
  129034. + numEntries = nodeArray[i].entries;
  129035. + }
  129036. + }
  129037. +
  129038. + gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
  129039. +
  129040. + Mmu->pageTableSize = numEntries * 4096;
  129041. +
  129042. + Mmu->pageTableEntries = Mmu->pageTableSize / gcmSIZEOF(gctUINT32);
  129043. +
  129044. + /* Construct Slave TLB. */
  129045. + gcmkONERROR(gckOS_AllocateContiguous(Mmu->os,
  129046. + gcvFALSE,
  129047. + &Mmu->pageTableSize,
  129048. + &Mmu->pageTablePhysical,
  129049. + (gctPOINTER)&Mmu->pageTableLogical));
  129050. +
  129051. +#if gcdUSE_MMU_EXCEPTION
  129052. + gcmkONERROR(_FillPageTable(Mmu->pageTableLogical,
  129053. + Mmu->pageTableEntries,
  129054. + /* Enable exception */
  129055. + 1 << 1));
  129056. +#else
  129057. + /* Invalidate all entries. */
  129058. + gcmkONERROR(gckOS_ZeroMemory(Mmu->pageTableLogical,
  129059. + Mmu->pageTableSize));
  129060. +#endif
  129061. +
  129062. + /* Initilization. */
  129063. + pageTable = Mmu->pageTableLogical;
  129064. + _WritePageEntry(pageTable, (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
  129065. + _WritePageEntry(pageTable + 1, ~0U);
  129066. + Mmu->heapList = 0;
  129067. + Mmu->freeNodes = gcvFALSE;
  129068. +
  129069. + gcmkONERROR(gckOS_GetPhysicalAddress(Mmu->os,
  129070. + Mmu->pageTableLogical,
  129071. + &physical));
  129072. +
  129073. + /* Grab the mutex. */
  129074. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  129075. + acquired = gcvTRUE;
  129076. +
  129077. + /* Map to Master TLB. */
  129078. + for (i = (gctINT)Mmu->dynamicMappingStart;
  129079. + i < (gctINT)Mmu->dynamicMappingStart + numEntries;
  129080. + i++)
  129081. + {
  129082. + _WritePageEntry(Mmu->mtlbLogical + i,
  129083. + physical
  129084. + /* 4KB page size */
  129085. + | (0 << 2)
  129086. + /* Ignore exception */
  129087. + | (0 << 1)
  129088. + /* Present */
  129089. + | (1 << 0)
  129090. + );
  129091. +#if gcdMMU_TABLE_DUMP
  129092. + gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
  129093. + __FUNCTION__, __LINE__,
  129094. + i,
  129095. + _ReadPageEntry(Mmu->mtlbLogical + i));
  129096. +#endif
  129097. + physical += gcdMMU_STLB_4K_SIZE;
  129098. + }
  129099. +
  129100. + /* Release the mutex. */
  129101. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  129102. +
  129103. + return gcvSTATUS_OK;
  129104. +
  129105. +OnError:
  129106. + if (Mmu->pageTableLogical)
  129107. + {
  129108. + /* Free the page table. */
  129109. + gcmkVERIFY_OK(
  129110. + gckOS_FreeContiguous(Mmu->os,
  129111. + Mmu->pageTablePhysical,
  129112. + (gctPOINTER) Mmu->pageTableLogical,
  129113. + Mmu->pageTableSize));
  129114. + }
  129115. +
  129116. + if (acquired)
  129117. + {
  129118. + /* Release the mutex. */
  129119. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  129120. + }
  129121. +
  129122. + return status;
  129123. +}
  129124. +
  129125. +/*******************************************************************************
  129126. +**
  129127. +** _Construct
  129128. +**
  129129. +** Construct a new gckMMU object.
  129130. +**
  129131. +** INPUT:
  129132. +**
  129133. +** gckKERNEL Kernel
  129134. +** Pointer to an gckKERNEL object.
  129135. +**
  129136. +** gctSIZE_T MmuSize
  129137. +** Number of bytes for the page table.
  129138. +**
  129139. +** OUTPUT:
  129140. +**
  129141. +** gckMMU * Mmu
  129142. +** Pointer to a variable that receives the gckMMU object pointer.
  129143. +*/
  129144. +gceSTATUS
  129145. +_Construct(
  129146. + IN gckKERNEL Kernel,
  129147. + IN gctSIZE_T MmuSize,
  129148. + OUT gckMMU * Mmu
  129149. + )
  129150. +{
  129151. + gckOS os;
  129152. + gckHARDWARE hardware;
  129153. + gceSTATUS status;
  129154. + gckMMU mmu = gcvNULL;
  129155. + gctUINT32_PTR pageTable;
  129156. + gctPOINTER pointer = gcvNULL;
  129157. +
  129158. + gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize);
  129159. +
  129160. + /* Verify the arguments. */
  129161. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  129162. + gcmkVERIFY_ARGUMENT(MmuSize > 0);
  129163. + gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
  129164. +
  129165. + /* Extract the gckOS object pointer. */
  129166. + os = Kernel->os;
  129167. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  129168. +
  129169. + /* Extract the gckHARDWARE object pointer. */
  129170. + hardware = Kernel->hardware;
  129171. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  129172. +
  129173. + /* Allocate memory for the gckMMU object. */
  129174. + gcmkONERROR(gckOS_Allocate(os, sizeof(struct _gckMMU), &pointer));
  129175. +
  129176. + mmu = pointer;
  129177. +
  129178. + /* Initialize the gckMMU object. */
  129179. + mmu->object.type = gcvOBJ_MMU;
  129180. + mmu->os = os;
  129181. + mmu->hardware = hardware;
  129182. + mmu->pageTableMutex = gcvNULL;
  129183. + mmu->pageTableLogical = gcvNULL;
  129184. + mmu->mtlbLogical = gcvNULL;
  129185. + mmu->staticSTLB = gcvNULL;
  129186. + mmu->enabled = gcvFALSE;
  129187. +#ifdef __QNXNTO__
  129188. + mmu->nodeList = gcvNULL;
  129189. + mmu->nodeMutex = gcvNULL;
  129190. +#endif
  129191. +
  129192. + /* Create the page table mutex. */
  129193. + gcmkONERROR(gckOS_CreateMutex(os, &mmu->pageTableMutex));
  129194. +
  129195. +#ifdef __QNXNTO__
  129196. + /* Create the node list mutex. */
  129197. + gcmkONERROR(gckOS_CreateMutex(os, &mmu->nodeMutex));
  129198. +#endif
  129199. +
  129200. + if (hardware->mmuVersion == 0)
  129201. + {
  129202. + mmu->pageTableSize = MmuSize;
  129203. +
  129204. + gcmkONERROR(
  129205. + gckOS_AllocateContiguous(os,
  129206. + gcvFALSE,
  129207. + &mmu->pageTableSize,
  129208. + &mmu->pageTablePhysical,
  129209. + &pointer));
  129210. +
  129211. + mmu->pageTableLogical = pointer;
  129212. +
  129213. + /* Compute number of entries in page table. */
  129214. + mmu->pageTableEntries = mmu->pageTableSize / sizeof(gctUINT32);
  129215. +
  129216. + /* Mark all pages as free. */
  129217. + pageTable = mmu->pageTableLogical;
  129218. +
  129219. +#if gcdMMU_CLEAR_VALUE
  129220. + _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
  129221. +#endif
  129222. +
  129223. + _WritePageEntry(pageTable, (mmu->pageTableEntries << 8) | gcvMMU_FREE);
  129224. + _WritePageEntry(pageTable + 1, ~0U);
  129225. + mmu->heapList = 0;
  129226. + mmu->freeNodes = gcvFALSE;
  129227. +
  129228. + /* Set page table address. */
  129229. + gcmkONERROR(
  129230. + gckHARDWARE_SetMMU(hardware, (gctPOINTER) mmu->pageTableLogical));
  129231. + }
  129232. + else
  129233. + {
  129234. + /* Allocate the 4K mode MTLB table. */
  129235. + mmu->mtlbSize = gcdMMU_MTLB_SIZE + 64;
  129236. +
  129237. + gcmkONERROR(
  129238. + gckOS_AllocateContiguous(os,
  129239. + gcvFALSE,
  129240. + &mmu->mtlbSize,
  129241. + &mmu->mtlbPhysical,
  129242. + &pointer));
  129243. +
  129244. + mmu->mtlbLogical = pointer;
  129245. +
  129246. + /* Invalid all the entries. */
  129247. + gcmkONERROR(
  129248. + gckOS_ZeroMemory(pointer, mmu->mtlbSize));
  129249. + }
  129250. +
  129251. + /* Return the gckMMU object pointer. */
  129252. + *Mmu = mmu;
  129253. +
  129254. + /* Success. */
  129255. + gcmkFOOTER_ARG("*Mmu=0x%x", *Mmu);
  129256. + return gcvSTATUS_OK;
  129257. +
  129258. +OnError:
  129259. + /* Roll back. */
  129260. + if (mmu != gcvNULL)
  129261. + {
  129262. + if (mmu->pageTableLogical != gcvNULL)
  129263. + {
  129264. + /* Free the page table. */
  129265. + gcmkVERIFY_OK(
  129266. + gckOS_FreeContiguous(os,
  129267. + mmu->pageTablePhysical,
  129268. + (gctPOINTER) mmu->pageTableLogical,
  129269. + mmu->pageTableSize));
  129270. +
  129271. + }
  129272. +
  129273. + if (mmu->mtlbLogical != gcvNULL)
  129274. + {
  129275. + gcmkVERIFY_OK(
  129276. + gckOS_FreeContiguous(os,
  129277. + mmu->mtlbPhysical,
  129278. + (gctPOINTER) mmu->mtlbLogical,
  129279. + mmu->mtlbSize));
  129280. + }
  129281. +
  129282. + if (mmu->pageTableMutex != gcvNULL)
  129283. + {
  129284. + /* Delete the mutex. */
  129285. + gcmkVERIFY_OK(
  129286. + gckOS_DeleteMutex(os, mmu->pageTableMutex));
  129287. + }
  129288. +
  129289. +#ifdef __QNXNTO__
  129290. + if (mmu->nodeMutex != gcvNULL)
  129291. + {
  129292. + /* Delete the mutex. */
  129293. + gcmkVERIFY_OK(
  129294. + gckOS_DeleteMutex(os, mmu->nodeMutex));
  129295. + }
  129296. +#endif
  129297. +
  129298. + /* Mark the gckMMU object as unknown. */
  129299. + mmu->object.type = gcvOBJ_UNKNOWN;
  129300. +
  129301. + /* Free the allocates memory. */
  129302. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, mmu));
  129303. + }
  129304. +
  129305. + /* Return the status. */
  129306. + gcmkFOOTER();
  129307. + return status;
  129308. +}
  129309. +
  129310. +/*******************************************************************************
  129311. +**
  129312. +** _Destroy
  129313. +**
  129314. +** Destroy a gckMMU object.
  129315. +**
  129316. +** INPUT:
  129317. +**
  129318. +** gckMMU Mmu
  129319. +** Pointer to an gckMMU object.
  129320. +**
  129321. +** OUTPUT:
  129322. +**
  129323. +** Nothing.
  129324. +*/
  129325. +gceSTATUS
  129326. +_Destroy(
  129327. + IN gckMMU Mmu
  129328. + )
  129329. +{
  129330. +#ifdef __QNXNTO__
  129331. + gcuVIDMEM_NODE_PTR node, next;
  129332. +#endif
  129333. +
  129334. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  129335. +
  129336. + /* Verify the arguments. */
  129337. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  129338. +
  129339. +#ifdef __QNXNTO__
  129340. + /* Free all associated virtual memory. */
  129341. + for (node = Mmu->nodeList; node != gcvNULL; node = next)
  129342. + {
  129343. + next = node->Virtual.next;
  129344. + gcmkVERIFY_OK(gckVIDMEM_Free(node));
  129345. + }
  129346. +#endif
  129347. +
  129348. + while (Mmu->staticSTLB != gcvNULL)
  129349. + {
  129350. + gcsMMU_STLB_PTR pre = Mmu->staticSTLB;
  129351. + Mmu->staticSTLB = pre->next;
  129352. +
  129353. + if (pre->physical != gcvNULL)
  129354. + {
  129355. + gcmkVERIFY_OK(
  129356. + gckOS_FreeContiguous(Mmu->os,
  129357. + pre->physical,
  129358. + pre->logical,
  129359. + pre->size));
  129360. + }
  129361. +
  129362. + if (pre->mtlbEntryNum != 0)
  129363. + {
  129364. + gcmkASSERT(pre->mtlbEntryNum == 1);
  129365. + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
  129366. +#if gcdMMU_TABLE_DUMP
  129367. + gckOS_Print("%s(%d): clean MTLB[%d]\n",
  129368. + __FUNCTION__, __LINE__,
  129369. + pre->mtlbIndex);
  129370. +#endif
  129371. + }
  129372. +
  129373. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
  129374. + }
  129375. +
  129376. + if (Mmu->hardware->mmuVersion != 0)
  129377. + {
  129378. + gcmkVERIFY_OK(
  129379. + gckOS_FreeContiguous(Mmu->os,
  129380. + Mmu->mtlbPhysical,
  129381. + (gctPOINTER) Mmu->mtlbLogical,
  129382. + Mmu->mtlbSize));
  129383. + }
  129384. +
  129385. + /* Free the page table. */
  129386. + gcmkVERIFY_OK(
  129387. + gckOS_FreeContiguous(Mmu->os,
  129388. + Mmu->pageTablePhysical,
  129389. + (gctPOINTER) Mmu->pageTableLogical,
  129390. + Mmu->pageTableSize));
  129391. +
  129392. +#ifdef __QNXNTO__
  129393. + /* Delete the node list mutex. */
  129394. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->nodeMutex));
  129395. +#endif
  129396. +
  129397. + /* Delete the page table mutex. */
  129398. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->pageTableMutex));
  129399. +
  129400. + /* Mark the gckMMU object as unknown. */
  129401. + Mmu->object.type = gcvOBJ_UNKNOWN;
  129402. +
  129403. + /* Free the gckMMU object. */
  129404. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, Mmu));
  129405. +
  129406. + /* Success. */
  129407. + gcmkFOOTER_NO();
  129408. + return gcvSTATUS_OK;
  129409. +}
  129410. +
  129411. +/*******************************************************************************
  129412. +** _AdjstIndex
  129413. +**
  129414. +** Adjust the index from which we search for a usable node to make sure
  129415. +** index allocated is greater than Start.
  129416. +*/
  129417. +gceSTATUS
  129418. +_AdjustIndex(
  129419. + IN gckMMU Mmu,
  129420. + IN gctUINT32 Index,
  129421. + IN gctUINT32 PageCount,
  129422. + IN gctUINT32 Start,
  129423. + OUT gctUINT32 * IndexAdjusted
  129424. + )
  129425. +{
  129426. + gceSTATUS status;
  129427. + gctUINT32 index = Index;
  129428. + gctUINT32_PTR map = Mmu->pageTableLogical;
  129429. +
  129430. + gcmkHEADER();
  129431. +
  129432. + for (; index < Mmu->pageTableEntries;)
  129433. + {
  129434. + gctUINT32 result = 0;
  129435. + gctUINT32 nodeSize = 0;
  129436. +
  129437. + if (index >= Start)
  129438. + {
  129439. + break;
  129440. + }
  129441. +
  129442. + switch (gcmENTRY_TYPE(map[index]))
  129443. + {
  129444. + case gcvMMU_SINGLE:
  129445. + nodeSize = 1;
  129446. + break;
  129447. +
  129448. + case gcvMMU_FREE:
  129449. + nodeSize = map[index] >> 8;
  129450. + break;
  129451. +
  129452. + default:
  129453. + gcmkFATAL("MMU table correcupted at index %u!", index);
  129454. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  129455. + }
  129456. +
  129457. + if (nodeSize > PageCount)
  129458. + {
  129459. + result = index + (nodeSize - PageCount);
  129460. +
  129461. + if (result >= Start)
  129462. + {
  129463. + break;
  129464. + }
  129465. + }
  129466. +
  129467. + switch (gcmENTRY_TYPE(map[index]))
  129468. + {
  129469. + case gcvMMU_SINGLE:
  129470. + index = map[index] >> 8;
  129471. + break;
  129472. +
  129473. + case gcvMMU_FREE:
  129474. + index = map[index + 1];
  129475. + break;
  129476. +
  129477. + default:
  129478. + gcmkFATAL("MMU table correcupted at index %u!", index);
  129479. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  129480. + }
  129481. + }
  129482. +
  129483. + *IndexAdjusted = index;
  129484. +
  129485. + gcmkFOOTER_NO();
  129486. + return gcvSTATUS_OK;
  129487. +
  129488. +OnError:
  129489. + gcmkFOOTER();
  129490. + return status;
  129491. +}
  129492. +
  129493. +gceSTATUS
  129494. +gckMMU_Construct(
  129495. + IN gckKERNEL Kernel,
  129496. + IN gctSIZE_T MmuSize,
  129497. + OUT gckMMU * Mmu
  129498. + )
  129499. +{
  129500. +#if gcdSHARED_PAGETABLE
  129501. + gceSTATUS status;
  129502. + gctPOINTER pointer;
  129503. +
  129504. + gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
  129505. +
  129506. + if (sharedPageTable == gcvNULL)
  129507. + {
  129508. + gcmkONERROR(
  129509. + gckOS_Allocate(Kernel->os,
  129510. + sizeof(struct _gcsSharedPageTable),
  129511. + &pointer));
  129512. + sharedPageTable = pointer;
  129513. +
  129514. + gcmkONERROR(
  129515. + gckOS_ZeroMemory(sharedPageTable,
  129516. + sizeof(struct _gcsSharedPageTable)));
  129517. +
  129518. + gcmkONERROR(_Construct(Kernel, MmuSize, &sharedPageTable->mmu));
  129519. + }
  129520. + else if (Kernel->hardware->mmuVersion == 0)
  129521. + {
  129522. + /* Set page table address. */
  129523. + gcmkONERROR(
  129524. + gckHARDWARE_SetMMU(Kernel->hardware, (gctPOINTER) sharedPageTable->mmu->pageTableLogical));
  129525. + }
  129526. +
  129527. + *Mmu = sharedPageTable->mmu;
  129528. +
  129529. + sharedPageTable->hardwares[sharedPageTable->reference] = Kernel->hardware;
  129530. +
  129531. + sharedPageTable->reference++;
  129532. +
  129533. + gcmkFOOTER_ARG("sharedPageTable->reference=%lu", sharedPageTable->reference);
  129534. + return gcvSTATUS_OK;
  129535. +
  129536. +OnError:
  129537. + if (sharedPageTable)
  129538. + {
  129539. + if (sharedPageTable->mmu)
  129540. + {
  129541. + gcmkVERIFY_OK(gckMMU_Destroy(sharedPageTable->mmu));
  129542. + }
  129543. +
  129544. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, sharedPageTable));
  129545. + }
  129546. +
  129547. + gcmkFOOTER();
  129548. + return status;
  129549. +#elif gcdMIRROR_PAGETABLE
  129550. + gceSTATUS status;
  129551. + gctPOINTER pointer;
  129552. +
  129553. + gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
  129554. +
  129555. + if (mirrorPageTable == gcvNULL)
  129556. + {
  129557. + gcmkONERROR(
  129558. + gckOS_Allocate(Kernel->os,
  129559. + sizeof(struct _gcsMirrorPageTable),
  129560. + &pointer));
  129561. + mirrorPageTable = pointer;
  129562. +
  129563. + gcmkONERROR(
  129564. + gckOS_ZeroMemory(mirrorPageTable,
  129565. + sizeof(struct _gcsMirrorPageTable)));
  129566. +
  129567. + gcmkONERROR(
  129568. + gckOS_CreateMutex(Kernel->os, &mirrorPageTableMutex));
  129569. + }
  129570. +
  129571. + gcmkONERROR(_Construct(Kernel, MmuSize, Mmu));
  129572. +
  129573. + mirrorPageTable->mmus[mirrorPageTable->reference] = *Mmu;
  129574. +
  129575. + mirrorPageTable->hardwares[mirrorPageTable->reference] = Kernel->hardware;
  129576. +
  129577. + mirrorPageTable->reference++;
  129578. +
  129579. + gcmkFOOTER_ARG("mirrorPageTable->reference=%lu", mirrorPageTable->reference);
  129580. + return gcvSTATUS_OK;
  129581. +
  129582. +OnError:
  129583. + if (mirrorPageTable && mirrorPageTable->reference == 0)
  129584. + {
  129585. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, mirrorPageTable));
  129586. + }
  129587. +
  129588. + gcmkFOOTER();
  129589. + return status;
  129590. +#else
  129591. + return _Construct(Kernel, MmuSize, Mmu);
  129592. +#endif
  129593. +}
  129594. +
  129595. +gceSTATUS
  129596. +gckMMU_Destroy(
  129597. + IN gckMMU Mmu
  129598. + )
  129599. +{
  129600. +#if gcdSHARED_PAGETABLE
  129601. + sharedPageTable->reference--;
  129602. +
  129603. + if (sharedPageTable->reference == 0)
  129604. + {
  129605. + if (sharedPageTable->mmu)
  129606. + {
  129607. + gcmkVERIFY_OK(_Destroy(Mmu));
  129608. + }
  129609. +
  129610. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, sharedPageTable));
  129611. + }
  129612. +
  129613. + return gcvSTATUS_OK;
  129614. +#elif gcdMIRROR_PAGETABLE
  129615. + mirrorPageTable->reference--;
  129616. +
  129617. + if (mirrorPageTable->reference == 0)
  129618. + {
  129619. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTable));
  129620. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTableMutex));
  129621. + }
  129622. +
  129623. + return _Destroy(Mmu);
  129624. +#else
  129625. + return _Destroy(Mmu);
  129626. +#endif
  129627. +}
  129628. +
  129629. +/*******************************************************************************
  129630. +**
  129631. +** gckMMU_AllocatePages
  129632. +**
  129633. +** Allocate pages inside the page table.
  129634. +**
  129635. +** INPUT:
  129636. +**
  129637. +** gckMMU Mmu
  129638. +** Pointer to an gckMMU object.
  129639. +**
  129640. +** gctSIZE_T PageCount
  129641. +** Number of pages to allocate.
  129642. +**
  129643. +** OUTPUT:
  129644. +**
  129645. +** gctPOINTER * PageTable
  129646. +** Pointer to a variable that receives the base address of the page
  129647. +** table.
  129648. +**
  129649. +** gctUINT32 * Address
  129650. +** Pointer to a variable that receives the hardware specific address.
  129651. +*/
  129652. +gceSTATUS
  129653. +_AllocatePages(
  129654. + IN gckMMU Mmu,
  129655. + IN gctSIZE_T PageCount,
  129656. + IN gceSURF_TYPE Type,
  129657. + OUT gctPOINTER * PageTable,
  129658. + OUT gctUINT32 * Address
  129659. + )
  129660. +{
  129661. + gceSTATUS status;
  129662. + gctBOOL mutex = gcvFALSE;
  129663. + gctUINT32 index = 0, previous = ~0U, left;
  129664. + gctUINT32_PTR pageTable;
  129665. + gctBOOL gotIt;
  129666. + gctUINT32 address;
  129667. +
  129668. + gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount);
  129669. +
  129670. + /* Verify the arguments. */
  129671. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  129672. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  129673. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  129674. +
  129675. + if (PageCount > Mmu->pageTableEntries)
  129676. + {
  129677. + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
  129678. + __FUNCTION__, __LINE__);
  129679. +
  129680. + /* Not enough pages avaiable. */
  129681. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  129682. + }
  129683. +
  129684. + /* Grab the mutex. */
  129685. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  129686. + mutex = gcvTRUE;
  129687. +
  129688. + /* Cast pointer to page table. */
  129689. + for (pageTable = Mmu->pageTableLogical, gotIt = gcvFALSE; !gotIt;)
  129690. + {
  129691. + index = Mmu->heapList;
  129692. +
  129693. + if ((Mmu->hardware->mmuVersion == 0) && (Type == gcvSURF_VERTEX))
  129694. + {
  129695. + gcmkONERROR(_AdjustIndex(
  129696. + Mmu,
  129697. + index,
  129698. + PageCount,
  129699. + gcdVERTEX_START / gcmSIZEOF(gctUINT32),
  129700. + &index
  129701. + ));
  129702. + }
  129703. +
  129704. + /* Walk the heap list. */
  129705. + for (; !gotIt && (index < Mmu->pageTableEntries);)
  129706. + {
  129707. + /* Check the node type. */
  129708. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
  129709. + {
  129710. + case gcvMMU_SINGLE:
  129711. + /* Single odes are valid if we only need 1 page. */
  129712. + if (PageCount == 1)
  129713. + {
  129714. + gotIt = gcvTRUE;
  129715. + }
  129716. + else
  129717. + {
  129718. + /* Move to next node. */
  129719. + previous = index;
  129720. + index = _ReadPageEntry(&pageTable[index]) >> 8;
  129721. + }
  129722. + break;
  129723. +
  129724. + case gcvMMU_FREE:
  129725. + /* Test if the node has enough space. */
  129726. + if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8))
  129727. + {
  129728. + gotIt = gcvTRUE;
  129729. + }
  129730. + else
  129731. + {
  129732. + /* Move to next node. */
  129733. + previous = index;
  129734. + index = _ReadPageEntry(&pageTable[index + 1]);
  129735. + }
  129736. + break;
  129737. +
  129738. + default:
  129739. + gcmkFATAL("MMU table correcupted at index %u!", index);
  129740. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  129741. + }
  129742. + }
  129743. +
  129744. + /* Test if we are out of memory. */
  129745. + if (index >= Mmu->pageTableEntries)
  129746. + {
  129747. + if (Mmu->freeNodes)
  129748. + {
  129749. + /* Time to move out the trash! */
  129750. + gcmkONERROR(_Collect(Mmu));
  129751. + }
  129752. + else
  129753. + {
  129754. + gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
  129755. + __FUNCTION__, __LINE__);
  129756. +
  129757. + /* Out of resources. */
  129758. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  129759. + }
  129760. + }
  129761. + }
  129762. +
  129763. + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
  129764. + {
  129765. + case gcvMMU_SINGLE:
  129766. + /* Unlink single node from free list. */
  129767. + gcmkONERROR(
  129768. + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8));
  129769. + break;
  129770. +
  129771. + case gcvMMU_FREE:
  129772. + /* Check how many pages will be left. */
  129773. + left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount;
  129774. + switch (left)
  129775. + {
  129776. + case 0:
  129777. + /* The entire node is consumed, just unlink it. */
  129778. + gcmkONERROR(
  129779. + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1])));
  129780. + break;
  129781. +
  129782. + case 1:
  129783. + /* One page will remain. Convert the node to a single node and
  129784. + ** advance the index. */
  129785. + _WritePageEntry(&pageTable[index], (_ReadPageEntry(&pageTable[index + 1]) << 8) | gcvMMU_SINGLE);
  129786. + index ++;
  129787. + break;
  129788. +
  129789. + default:
  129790. + /* Enough pages remain for a new node. However, we will just adjust
  129791. + ** the size of the current node and advance the index. */
  129792. + _WritePageEntry(&pageTable[index], (left << 8) | gcvMMU_FREE);
  129793. + index += left;
  129794. + break;
  129795. + }
  129796. + break;
  129797. + }
  129798. +
  129799. + /* Mark node as used. */
  129800. + gcmkONERROR(_FillPageTable(&pageTable[index], PageCount, gcvMMU_USED));
  129801. +
  129802. + /* Return pointer to page table. */
  129803. + *PageTable = &pageTable[index];
  129804. +
  129805. + /* Build virtual address. */
  129806. + if (Mmu->hardware->mmuVersion == 0)
  129807. + {
  129808. + gcmkONERROR(
  129809. + gckHARDWARE_BuildVirtualAddress(Mmu->hardware, index, 0, &address));
  129810. + }
  129811. + else
  129812. + {
  129813. + gctUINT32 masterOffset = index / gcdMMU_STLB_4K_ENTRY_NUM
  129814. + + Mmu->dynamicMappingStart;
  129815. + gctUINT32 slaveOffset = index % gcdMMU_STLB_4K_ENTRY_NUM;
  129816. +
  129817. + address = (masterOffset << gcdMMU_MTLB_SHIFT)
  129818. + | (slaveOffset << gcdMMU_STLB_4K_SHIFT);
  129819. + }
  129820. +
  129821. + if (Address != gcvNULL)
  129822. + {
  129823. + *Address = address;
  129824. + }
  129825. +
  129826. + /* Release the mutex. */
  129827. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  129828. +
  129829. + /* Success. */
  129830. + gcmkFOOTER_ARG("*PageTable=0x%x *Address=%08x",
  129831. + *PageTable, gcmOPT_VALUE(Address));
  129832. + return gcvSTATUS_OK;
  129833. +
  129834. +OnError:
  129835. +
  129836. + if (mutex)
  129837. + {
  129838. + /* Release the mutex. */
  129839. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  129840. + }
  129841. +
  129842. + /* Return the status. */
  129843. + gcmkFOOTER();
  129844. + return status;
  129845. +}
  129846. +
  129847. +/*******************************************************************************
  129848. +**
  129849. +** gckMMU_FreePages
  129850. +**
  129851. +** Free pages inside the page table.
  129852. +**
  129853. +** INPUT:
  129854. +**
  129855. +** gckMMU Mmu
  129856. +** Pointer to an gckMMU object.
  129857. +**
  129858. +** gctPOINTER PageTable
  129859. +** Base address of the page table to free.
  129860. +**
  129861. +** gctSIZE_T PageCount
  129862. +** Number of pages to free.
  129863. +**
  129864. +** OUTPUT:
  129865. +**
  129866. +** Nothing.
  129867. +*/
  129868. +gceSTATUS
  129869. +_FreePages(
  129870. + IN gckMMU Mmu,
  129871. + IN gctPOINTER PageTable,
  129872. + IN gctSIZE_T PageCount
  129873. + )
  129874. +{
  129875. + gctUINT32_PTR pageTable;
  129876. + gceSTATUS status;
  129877. + gctBOOL acquired = gcvFALSE;
  129878. +
  129879. + gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
  129880. + Mmu, PageTable, PageCount);
  129881. +
  129882. + /* Verify the arguments. */
  129883. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  129884. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  129885. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  129886. +
  129887. + /* Convert the pointer. */
  129888. + pageTable = (gctUINT32_PTR) PageTable;
  129889. +
  129890. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
  129891. + acquired = gcvTRUE;
  129892. +
  129893. +#if gcdMMU_CLEAR_VALUE
  129894. + if (Mmu->hardware->mmuVersion == 0)
  129895. + {
  129896. + _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE);
  129897. + }
  129898. +#endif
  129899. +
  129900. + if (PageCount == 1)
  129901. + {
  129902. + /* Single page node. */
  129903. + _WritePageEntry(pageTable,
  129904. + (~((1U<<8)-1)) | gcvMMU_SINGLE
  129905. +#if gcdUSE_MMU_EXCEPTION
  129906. + /* Enable exception */
  129907. + | 1 << 1
  129908. +#endif
  129909. + );
  129910. + }
  129911. + else
  129912. + {
  129913. + /* Mark the node as free. */
  129914. + _WritePageEntry(pageTable,
  129915. + (PageCount << 8) | gcvMMU_FREE
  129916. +#if gcdUSE_MMU_EXCEPTION
  129917. + /* Enable exception */
  129918. + | 1 << 1
  129919. +#endif
  129920. + );
  129921. + _WritePageEntry(pageTable + 1, ~0U);
  129922. +
  129923. +#if gcdUSE_MMU_EXCEPTION
  129924. + /* Enable exception */
  129925. + gcmkVERIFY_OK(_FillPageTable(pageTable + 2, PageCount - 2, 1 << 1));
  129926. +#endif
  129927. + }
  129928. +
  129929. + /* We have free nodes. */
  129930. + Mmu->freeNodes = gcvTRUE;
  129931. +
  129932. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  129933. + acquired = gcvFALSE;
  129934. +
  129935. + /* Success. */
  129936. + gcmkFOOTER_NO();
  129937. + return gcvSTATUS_OK;
  129938. +
  129939. +OnError:
  129940. + if (acquired)
  129941. + {
  129942. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
  129943. + }
  129944. +
  129945. + gcmkFOOTER();
  129946. + return status;
  129947. +}
  129948. +
  129949. +gceSTATUS
  129950. +gckMMU_AllocatePages(
  129951. + IN gckMMU Mmu,
  129952. + IN gctSIZE_T PageCount,
  129953. + OUT gctPOINTER * PageTable,
  129954. + OUT gctUINT32 * Address
  129955. + )
  129956. +{
  129957. + return gckMMU_AllocatePagesEx(
  129958. + Mmu, PageCount, gcvSURF_UNKNOWN, PageTable, Address);
  129959. +}
  129960. +
  129961. +gceSTATUS
  129962. +gckMMU_AllocatePagesEx(
  129963. + IN gckMMU Mmu,
  129964. + IN gctSIZE_T PageCount,
  129965. + IN gceSURF_TYPE Type,
  129966. + OUT gctPOINTER * PageTable,
  129967. + OUT gctUINT32 * Address
  129968. + )
  129969. +{
  129970. +#if gcdMIRROR_PAGETABLE
  129971. + gceSTATUS status;
  129972. + gctPOINTER pageTable;
  129973. + gctUINT32 address;
  129974. + gctINT i;
  129975. + gckMMU mmu;
  129976. + gctBOOL acquired = gcvFALSE;
  129977. + gctBOOL allocated = gcvFALSE;
  129978. +
  129979. + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
  129980. + acquired = gcvTRUE;
  129981. +
  129982. + /* Allocate page table for current MMU. */
  129983. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  129984. + {
  129985. + if (Mmu == mirrorPageTable->mmus[i])
  129986. + {
  129987. + gcmkONERROR(_AllocatePages(Mmu, PageCount, Type, PageTable, Address));
  129988. + allocated = gcvTRUE;
  129989. + }
  129990. + }
  129991. +
  129992. + /* Allocate page table for other MMUs. */
  129993. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  129994. + {
  129995. + mmu = mirrorPageTable->mmus[i];
  129996. +
  129997. + if (Mmu != mmu)
  129998. + {
  129999. + gcmkONERROR(_AllocatePages(mmu, PageCount, Type, &pageTable, &address));
  130000. + gcmkASSERT(address == *Address);
  130001. + }
  130002. + }
  130003. +
  130004. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  130005. + acquired = gcvFALSE;
  130006. +
  130007. + return gcvSTATUS_OK;
  130008. +OnError:
  130009. +
  130010. + if (allocated)
  130011. + {
  130012. + /* Page tables for multiple GPU always keep the same. So it is impossible
  130013. + * the fist one allocates successfully but others fail.
  130014. + */
  130015. + gcmkASSERT(0);
  130016. + }
  130017. +
  130018. + if (acquired)
  130019. + {
  130020. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  130021. + }
  130022. +
  130023. + return status;
  130024. +#else
  130025. + return _AllocatePages(Mmu, PageCount, Type, PageTable, Address);
  130026. +#endif
  130027. +}
  130028. +
  130029. +gceSTATUS
  130030. +gckMMU_FreePages(
  130031. + IN gckMMU Mmu,
  130032. + IN gctPOINTER PageTable,
  130033. + IN gctSIZE_T PageCount
  130034. + )
  130035. +{
  130036. +#if gcdMIRROR_PAGETABLE
  130037. + gctINT i;
  130038. + gctUINT32 offset;
  130039. + gckMMU mmu;
  130040. +
  130041. + gckOS_AcquireMutex(Mmu->os, mirrorPageTableMutex, gcvINFINITE);
  130042. +
  130043. + gcmkVERIFY_OK(_FreePages(Mmu, PageTable, PageCount));
  130044. +
  130045. + offset = (gctUINT32)PageTable - (gctUINT32)Mmu->pageTableLogical;
  130046. +
  130047. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  130048. + {
  130049. + mmu = mirrorPageTable->mmus[i];
  130050. +
  130051. + if (mmu != Mmu)
  130052. + {
  130053. + gcmkVERIFY_OK(_FreePages(mmu, mmu->pageTableLogical + offset/4, PageCount));
  130054. + }
  130055. + }
  130056. +
  130057. + gckOS_ReleaseMutex(Mmu->os, mirrorPageTableMutex);
  130058. +
  130059. + return gcvSTATUS_OK;
  130060. +#else
  130061. + return _FreePages(Mmu, PageTable, PageCount);
  130062. +#endif
  130063. +}
  130064. +
  130065. +gceSTATUS
  130066. +gckMMU_Enable(
  130067. + IN gckMMU Mmu,
  130068. + IN gctUINT32 PhysBaseAddr,
  130069. + IN gctUINT32 PhysSize
  130070. + )
  130071. +{
  130072. + gceSTATUS status;
  130073. +#if gcdSHARED_PAGETABLE
  130074. + gckHARDWARE hardware;
  130075. + gctINT i;
  130076. +#endif
  130077. +
  130078. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  130079. +
  130080. + /* Verify the arguments. */
  130081. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130082. +
  130083. +#if gcdSHARED_PAGETABLE
  130084. + if (Mmu->enabled)
  130085. + {
  130086. + gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
  130087. + return gcvSTATUS_SKIP;
  130088. + }
  130089. +#endif
  130090. +
  130091. + if (Mmu->hardware->mmuVersion == 0)
  130092. + {
  130093. + /* Success. */
  130094. + gcmkFOOTER_ARG("Status=%d", gcvSTATUS_SKIP);
  130095. + return gcvSTATUS_SKIP;
  130096. + }
  130097. + else
  130098. + {
  130099. + if (PhysSize != 0)
  130100. + {
  130101. + gcmkONERROR(_FillFlatMapping(
  130102. + Mmu,
  130103. + PhysBaseAddr,
  130104. + PhysSize
  130105. + ));
  130106. + }
  130107. +
  130108. + gcmkONERROR(_SetupDynamicSpace(Mmu));
  130109. +
  130110. +#if gcdSHARED_PAGETABLE
  130111. + for(i = 0; i < gcdMAX_GPU_COUNT; i++)
  130112. + {
  130113. + hardware = sharedPageTable->hardwares[i];
  130114. + if (hardware != gcvNULL)
  130115. + {
  130116. + gcmkONERROR(
  130117. + gckHARDWARE_SetMMUv2(
  130118. + hardware,
  130119. + gcvTRUE,
  130120. + Mmu->mtlbLogical,
  130121. + gcvMMU_MODE_4K,
  130122. + (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  130123. + gcvFALSE
  130124. + ));
  130125. + }
  130126. + }
  130127. +#else
  130128. + gcmkONERROR(
  130129. + gckHARDWARE_SetMMUv2(
  130130. + Mmu->hardware,
  130131. + gcvTRUE,
  130132. + Mmu->mtlbLogical,
  130133. + gcvMMU_MODE_4K,
  130134. + (gctUINT8_PTR)Mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
  130135. + gcvFALSE
  130136. + ));
  130137. +#endif
  130138. +
  130139. + Mmu->enabled = gcvTRUE;
  130140. +
  130141. + /* Success. */
  130142. + gcmkFOOTER_NO();
  130143. + return gcvSTATUS_OK;
  130144. + }
  130145. +
  130146. +OnError:
  130147. + /* Return the status. */
  130148. + gcmkFOOTER();
  130149. + return status;
  130150. +}
  130151. +
  130152. +gceSTATUS
  130153. +gckMMU_SetPage(
  130154. + IN gckMMU Mmu,
  130155. + IN gctUINT32 PageAddress,
  130156. + IN gctUINT32 *PageEntry
  130157. + )
  130158. +{
  130159. +#if gcdMIRROR_PAGETABLE
  130160. + gctUINT32_PTR pageEntry;
  130161. + gctINT i;
  130162. + gckMMU mmu;
  130163. + gctUINT32 offset = (gctUINT32)PageEntry - (gctUINT32)Mmu->pageTableLogical;
  130164. +#endif
  130165. +
  130166. + gctUINT32 data;
  130167. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  130168. +
  130169. + /* Verify the arguments. */
  130170. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130171. + gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
  130172. + gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
  130173. +
  130174. + if (Mmu->hardware->mmuVersion == 0)
  130175. + {
  130176. + data = PageAddress;
  130177. + }
  130178. + else
  130179. + {
  130180. + data = _SetPage(PageAddress);
  130181. + }
  130182. +
  130183. + _WritePageEntry(PageEntry, data);
  130184. +
  130185. +#if gcdMIRROR_PAGETABLE
  130186. + for (i = 0; i < (gctINT)mirrorPageTable->reference; i++)
  130187. + {
  130188. + mmu = mirrorPageTable->mmus[i];
  130189. +
  130190. + if (mmu != Mmu)
  130191. + {
  130192. + pageEntry = mmu->pageTableLogical + offset / 4;
  130193. +
  130194. + if (mmu->hardware->mmuVersion == 0)
  130195. + {
  130196. + _WritePageEntry(pageEntry, PageAddress);
  130197. + }
  130198. + else
  130199. + {
  130200. + _WritePageEntry(pageEntry, _SetPage(PageAddress));
  130201. + }
  130202. + }
  130203. +
  130204. + }
  130205. +#endif
  130206. + /* Success. */
  130207. + gcmkFOOTER_NO();
  130208. + return gcvSTATUS_OK;
  130209. +}
  130210. +
  130211. +#ifdef __QNXNTO__
  130212. +gceSTATUS
  130213. +gckMMU_InsertNode(
  130214. + IN gckMMU Mmu,
  130215. + IN gcuVIDMEM_NODE_PTR Node)
  130216. +{
  130217. + gceSTATUS status;
  130218. + gctBOOL mutex = gcvFALSE;
  130219. +
  130220. + gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
  130221. +
  130222. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130223. +
  130224. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  130225. + mutex = gcvTRUE;
  130226. +
  130227. + Node->Virtual.next = Mmu->nodeList;
  130228. + Mmu->nodeList = Node;
  130229. +
  130230. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  130231. +
  130232. + gcmkFOOTER();
  130233. + return gcvSTATUS_OK;
  130234. +
  130235. +OnError:
  130236. + if (mutex)
  130237. + {
  130238. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  130239. + }
  130240. +
  130241. + gcmkFOOTER();
  130242. + return status;
  130243. +}
  130244. +
  130245. +gceSTATUS
  130246. +gckMMU_RemoveNode(
  130247. + IN gckMMU Mmu,
  130248. + IN gcuVIDMEM_NODE_PTR Node)
  130249. +{
  130250. + gceSTATUS status;
  130251. + gctBOOL mutex = gcvFALSE;
  130252. + gcuVIDMEM_NODE_PTR *iter;
  130253. +
  130254. + gcmkHEADER_ARG("Mmu=0x%x Node=0x%x", Mmu, Node);
  130255. +
  130256. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130257. +
  130258. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  130259. + mutex = gcvTRUE;
  130260. +
  130261. + for (iter = &Mmu->nodeList; *iter; iter = &(*iter)->Virtual.next)
  130262. + {
  130263. + if (*iter == Node)
  130264. + {
  130265. + *iter = Node->Virtual.next;
  130266. + break;
  130267. + }
  130268. + }
  130269. +
  130270. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  130271. +
  130272. + gcmkFOOTER();
  130273. + return gcvSTATUS_OK;
  130274. +
  130275. +OnError:
  130276. + if (mutex)
  130277. + {
  130278. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  130279. + }
  130280. +
  130281. + gcmkFOOTER();
  130282. + return status;
  130283. +}
  130284. +
  130285. +gceSTATUS
  130286. +gckMMU_FreeHandleMemory(
  130287. + IN gckKERNEL Kernel,
  130288. + IN gckMMU Mmu,
  130289. + IN gctUINT32 Pid
  130290. + )
  130291. +{
  130292. + gceSTATUS status;
  130293. + gctBOOL acquired = gcvFALSE;
  130294. + gcuVIDMEM_NODE_PTR curr, next;
  130295. +
  130296. + gcmkHEADER_ARG("Kernel=0x%x, Mmu=0x%x Pid=%u", Kernel, Mmu, Pid);
  130297. +
  130298. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  130299. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130300. +
  130301. + gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->nodeMutex, gcvINFINITE));
  130302. + acquired = gcvTRUE;
  130303. +
  130304. + for (curr = Mmu->nodeList; curr != gcvNULL; curr = next)
  130305. + {
  130306. + next = curr->Virtual.next;
  130307. +
  130308. + if (curr->Virtual.processID == Pid)
  130309. + {
  130310. + while (curr->Virtual.unlockPendings[Kernel->core] == 0 && curr->Virtual.lockeds[Kernel->core] > 0)
  130311. + {
  130312. + gcmkONERROR(gckVIDMEM_Unlock(Kernel, curr, gcvSURF_TYPE_UNKNOWN, gcvNULL));
  130313. + }
  130314. +
  130315. + gcmkVERIFY_OK(gckVIDMEM_Free(curr));
  130316. + }
  130317. + }
  130318. +
  130319. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  130320. +
  130321. + gcmkFOOTER();
  130322. + return gcvSTATUS_OK;
  130323. +
  130324. +OnError:
  130325. + if (acquired)
  130326. + {
  130327. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->nodeMutex));
  130328. + }
  130329. +
  130330. + gcmkFOOTER();
  130331. + return status;
  130332. +}
  130333. +#endif
  130334. +
  130335. +gceSTATUS
  130336. +gckMMU_Flush(
  130337. + IN gckMMU Mmu
  130338. + )
  130339. +{
  130340. + gckHARDWARE hardware;
  130341. +#if gcdSHARED_PAGETABLE
  130342. + gctINT i;
  130343. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  130344. + {
  130345. +#if gcdENABLE_VG
  130346. + if (i == gcvCORE_VG)
  130347. + {
  130348. + continue;
  130349. + }
  130350. +#endif
  130351. + hardware = sharedPageTable->hardwares[i];
  130352. + if (hardware)
  130353. + {
  130354. + /* Notify cores who use this page table. */
  130355. + gcmkVERIFY_OK(
  130356. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  130357. + }
  130358. + }
  130359. +#elif gcdMIRROR_PAGETABLE
  130360. + gctINT i;
  130361. + for (i = 0; i < mirrorPageTable->reference; i++)
  130362. + {
  130363. + hardware = mirrorPageTable->hardwares[i];
  130364. +
  130365. + /* Notify cores who use this page table. */
  130366. + gcmkVERIFY_OK(
  130367. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  130368. + }
  130369. +#else
  130370. + hardware = Mmu->hardware;
  130371. + gcmkVERIFY_OK(
  130372. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  130373. +#endif
  130374. +
  130375. + return gcvSTATUS_OK;
  130376. +}
  130377. +
  130378. +gceSTATUS
  130379. +gckMMU_DumpPageTableEntry(
  130380. + IN gckMMU Mmu,
  130381. + IN gctUINT32 Address
  130382. + )
  130383. +{
  130384. + gctUINT32_PTR pageTable;
  130385. + gctUINT32 index;
  130386. + gctUINT32 mtlb, stlb;
  130387. +
  130388. + gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
  130389. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130390. +
  130391. + gcmkASSERT(Mmu->hardware->mmuVersion > 0);
  130392. +
  130393. + mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
  130394. + stlb = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
  130395. +
  130396. + if (Address >= 0x80000000)
  130397. + {
  130398. + pageTable = Mmu->pageTableLogical;
  130399. +
  130400. + index = (mtlb - Mmu->dynamicMappingStart)
  130401. + * gcdMMU_STLB_4K_ENTRY_NUM
  130402. + + stlb;
  130403. +
  130404. + gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
  130405. + }
  130406. +
  130407. + gcmkFOOTER_NO();
  130408. + return gcvSTATUS_OK;
  130409. +}
  130410. +
  130411. +/******************************************************************************
  130412. +****************************** T E S T C O D E ******************************
  130413. +******************************************************************************/
  130414. +
  130415. diff -Nur linux-3.14.17/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
  130416. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c 1970-01-01 01:00:00.000000000 +0100
  130417. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c 2014-09-11 18:06:03.114042420 +0200
  130418. @@ -0,0 +1,522 @@
  130419. +/****************************************************************************
  130420. +*
  130421. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  130422. +*
  130423. +* This program is free software; you can redistribute it and/or modify
  130424. +* it under the terms of the GNU General Public License as published by
  130425. +* the Free Software Foundation; either version 2 of the license, or
  130426. +* (at your option) any later version.
  130427. +*
  130428. +* This program is distributed in the hope that it will be useful,
  130429. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  130430. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  130431. +* GNU General Public License for more details.
  130432. +*
  130433. +* You should have received a copy of the GNU General Public License
  130434. +* along with this program; if not write to the Free Software
  130435. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  130436. +*
  130437. +*****************************************************************************/
  130438. +
  130439. +
  130440. +#include "gc_hal_kernel_precomp.h"
  130441. +
  130442. +#if gcdENABLE_VG
  130443. +
  130444. +#define _GC_OBJ_ZONE gcvZONE_MMU
  130445. +
  130446. +/*******************************************************************************
  130447. +**
  130448. +** gckVGMMU_Construct
  130449. +**
  130450. +** Construct a new gckVGMMU object.
  130451. +**
  130452. +** INPUT:
  130453. +**
  130454. +** gckVGKERNEL Kernel
  130455. +** Pointer to an gckVGKERNEL object.
  130456. +**
  130457. +** gctSIZE_T MmuSize
  130458. +** Number of bytes for the page table.
  130459. +**
  130460. +** OUTPUT:
  130461. +**
  130462. +** gckVGMMU * Mmu
  130463. +** Pointer to a variable that receives the gckVGMMU object pointer.
  130464. +*/
  130465. +gceSTATUS gckVGMMU_Construct(
  130466. + IN gckVGKERNEL Kernel,
  130467. + IN gctSIZE_T MmuSize,
  130468. + OUT gckVGMMU * Mmu
  130469. + )
  130470. +{
  130471. + gckOS os;
  130472. + gckVGHARDWARE hardware;
  130473. + gceSTATUS status;
  130474. + gckVGMMU mmu;
  130475. + gctUINT32 * pageTable;
  130476. + gctUINT32 i;
  130477. +
  130478. + gcmkHEADER_ARG("Kernel=0x%x MmuSize=0x%x Mmu=0x%x", Kernel, MmuSize, Mmu);
  130479. +
  130480. + /* Verify the arguments. */
  130481. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  130482. + gcmkVERIFY_ARGUMENT(MmuSize > 0);
  130483. + gcmkVERIFY_ARGUMENT(Mmu != gcvNULL);
  130484. +
  130485. + /* Extract the gckOS object pointer. */
  130486. + os = Kernel->os;
  130487. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  130488. +
  130489. + /* Extract the gckVGHARDWARE object pointer. */
  130490. + hardware = Kernel->hardware;
  130491. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  130492. +
  130493. + /* Allocate memory for the gckVGMMU object. */
  130494. + status = gckOS_Allocate(os, sizeof(struct _gckVGMMU), (gctPOINTER *) &mmu);
  130495. +
  130496. + if (status < 0)
  130497. + {
  130498. + /* Error. */
  130499. + gcmkFATAL(
  130500. + "%s(%d): could not allocate gckVGMMU object.",
  130501. + __FUNCTION__, __LINE__
  130502. + );
  130503. +
  130504. + gcmkFOOTER();
  130505. + return status;
  130506. + }
  130507. +
  130508. + /* Initialize the gckVGMMU object. */
  130509. + mmu->object.type = gcvOBJ_MMU;
  130510. + mmu->os = os;
  130511. + mmu->hardware = hardware;
  130512. +
  130513. + /* Create the mutex. */
  130514. + status = gckOS_CreateMutex(os, &mmu->mutex);
  130515. +
  130516. + if (status < 0)
  130517. + {
  130518. + /* Roll back. */
  130519. + mmu->object.type = gcvOBJ_UNKNOWN;
  130520. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  130521. +
  130522. + gcmkFOOTER();
  130523. + /* Error. */
  130524. + return status;
  130525. + }
  130526. +
  130527. + /* Allocate the page table. */
  130528. + mmu->pageTableSize = MmuSize;
  130529. + status = gckOS_AllocateContiguous(os,
  130530. + gcvFALSE,
  130531. + &mmu->pageTableSize,
  130532. + &mmu->pageTablePhysical,
  130533. + &mmu->pageTableLogical);
  130534. +
  130535. + if (status < 0)
  130536. + {
  130537. + /* Roll back. */
  130538. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
  130539. +
  130540. + mmu->object.type = gcvOBJ_UNKNOWN;
  130541. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  130542. +
  130543. + /* Error. */
  130544. + gcmkFATAL(
  130545. + "%s(%d): could not allocate page table.",
  130546. + __FUNCTION__, __LINE__
  130547. + );
  130548. +
  130549. + gcmkFOOTER();
  130550. + return status;
  130551. + }
  130552. +
  130553. + /* Compute number of entries in page table. */
  130554. + mmu->entryCount = mmu->pageTableSize / sizeof(gctUINT32);
  130555. + mmu->entry = 0;
  130556. +
  130557. + /* Mark the entire page table as available. */
  130558. + pageTable = (gctUINT32 *) mmu->pageTableLogical;
  130559. + for (i = 0; i < mmu->entryCount; i++)
  130560. + {
  130561. + pageTable[i] = (gctUINT32)~0;
  130562. + }
  130563. +
  130564. + /* Set page table address. */
  130565. + status = gckVGHARDWARE_SetMMU(hardware, mmu->pageTableLogical);
  130566. +
  130567. + if (status < 0)
  130568. + {
  130569. + /* Free the page table. */
  130570. + gcmkVERIFY_OK(gckOS_FreeContiguous(mmu->os,
  130571. + mmu->pageTablePhysical,
  130572. + mmu->pageTableLogical,
  130573. + mmu->pageTableSize));
  130574. +
  130575. + /* Roll back. */
  130576. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
  130577. +
  130578. + mmu->object.type = gcvOBJ_UNKNOWN;
  130579. + gcmkVERIFY_OK(gckOS_Free(os, mmu));
  130580. +
  130581. + /* Error. */
  130582. + gcmkFATAL(
  130583. + "%s(%d): could not program page table.",
  130584. + __FUNCTION__, __LINE__
  130585. + );
  130586. +
  130587. + gcmkFOOTER();
  130588. + return status;
  130589. + }
  130590. +
  130591. + /* Return the gckVGMMU object pointer. */
  130592. + *Mmu = mmu;
  130593. +
  130594. + gcmkTRACE_ZONE(
  130595. + gcvLEVEL_INFO, gcvZONE_MMU,
  130596. + "%s(%d): %u entries at %p.(0x%08X)\n",
  130597. + __FUNCTION__, __LINE__,
  130598. + mmu->entryCount,
  130599. + mmu->pageTableLogical,
  130600. + mmu->pageTablePhysical
  130601. + );
  130602. +
  130603. + gcmkFOOTER_NO();
  130604. + /* Success. */
  130605. + return gcvSTATUS_OK;
  130606. +}
  130607. +
  130608. +/*******************************************************************************
  130609. +**
  130610. +** gckVGMMU_Destroy
  130611. +**
  130612. +** Destroy a nAQMMU object.
  130613. +**
  130614. +** INPUT:
  130615. +**
  130616. +** gckVGMMU Mmu
  130617. +** Pointer to an gckVGMMU object.
  130618. +**
  130619. +** OUTPUT:
  130620. +**
  130621. +** Nothing.
  130622. +*/
  130623. +gceSTATUS gckVGMMU_Destroy(
  130624. + IN gckVGMMU Mmu
  130625. + )
  130626. +{
  130627. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  130628. +
  130629. + /* Verify the arguments. */
  130630. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130631. +
  130632. + /* Free the page table. */
  130633. + gcmkVERIFY_OK(gckOS_FreeContiguous(Mmu->os,
  130634. + Mmu->pageTablePhysical,
  130635. + Mmu->pageTableLogical,
  130636. + Mmu->pageTableSize));
  130637. +
  130638. + /* Roll back. */
  130639. + gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->mutex));
  130640. +
  130641. + /* Mark the gckVGMMU object as unknown. */
  130642. + Mmu->object.type = gcvOBJ_UNKNOWN;
  130643. +
  130644. + /* Free the gckVGMMU object. */
  130645. + gcmkVERIFY_OK(gckOS_Free(Mmu->os, Mmu));
  130646. +
  130647. + gcmkFOOTER_NO();
  130648. + /* Success. */
  130649. + return gcvSTATUS_OK;
  130650. +}
  130651. +
  130652. +/*******************************************************************************
  130653. +**
  130654. +** gckVGMMU_AllocatePages
  130655. +**
  130656. +** Allocate pages inside the page table.
  130657. +**
  130658. +** INPUT:
  130659. +**
  130660. +** gckVGMMU Mmu
  130661. +** Pointer to an gckVGMMU object.
  130662. +**
  130663. +** gctSIZE_T PageCount
  130664. +** Number of pages to allocate.
  130665. +**
  130666. +** OUTPUT:
  130667. +**
  130668. +** gctPOINTER * PageTable
  130669. +** Pointer to a variable that receives the base address of the page
  130670. +** table.
  130671. +**
  130672. +** gctUINT32 * Address
  130673. +** Pointer to a variable that receives the hardware specific address.
  130674. +*/
  130675. +gceSTATUS gckVGMMU_AllocatePages(
  130676. + IN gckVGMMU Mmu,
  130677. + IN gctSIZE_T PageCount,
  130678. + OUT gctPOINTER * PageTable,
  130679. + OUT gctUINT32 * Address
  130680. + )
  130681. +{
  130682. + gceSTATUS status;
  130683. + gctUINT32 tail, index, i;
  130684. + gctUINT32 * table;
  130685. + gctBOOL allocated = gcvFALSE;
  130686. +
  130687. + gcmkHEADER_ARG("Mmu=0x%x PageCount=0x%x PageTable=0x%x Address=0x%x",
  130688. + Mmu, PageCount, PageTable, Address);
  130689. +
  130690. + /* Verify the arguments. */
  130691. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130692. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  130693. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  130694. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  130695. +
  130696. + gcmkTRACE_ZONE(
  130697. + gcvLEVEL_INFO, gcvZONE_MMU,
  130698. + "%s(%d): %u pages.\n",
  130699. + __FUNCTION__, __LINE__,
  130700. + PageCount
  130701. + );
  130702. +
  130703. + if (PageCount > Mmu->entryCount)
  130704. + {
  130705. + gcmkTRACE_ZONE(
  130706. + gcvLEVEL_ERROR, gcvZONE_MMU,
  130707. + "%s(%d): page table too small for %u pages.\n",
  130708. + __FUNCTION__, __LINE__,
  130709. + PageCount
  130710. + );
  130711. +
  130712. + gcmkFOOTER_NO();
  130713. + /* Not enough pages avaiable. */
  130714. + return gcvSTATUS_OUT_OF_RESOURCES;
  130715. + }
  130716. +
  130717. + /* Grab the mutex. */
  130718. + status = gckOS_AcquireMutex(Mmu->os, Mmu->mutex, gcvINFINITE);
  130719. +
  130720. + if (status < 0)
  130721. + {
  130722. + gcmkTRACE_ZONE(
  130723. + gcvLEVEL_ERROR, gcvZONE_MMU,
  130724. + "%s(%d): could not acquire mutex.\n"
  130725. + ,__FUNCTION__, __LINE__
  130726. + );
  130727. +
  130728. + gcmkFOOTER();
  130729. + /* Error. */
  130730. + return status;
  130731. + }
  130732. +
  130733. + /* Compute the tail for this allocation. */
  130734. + tail = Mmu->entryCount - PageCount;
  130735. +
  130736. + /* Walk all entries until we find enough slots. */
  130737. + for (index = Mmu->entry; index <= tail;)
  130738. + {
  130739. + /* Access page table. */
  130740. + table = (gctUINT32 *) Mmu->pageTableLogical + index;
  130741. +
  130742. + /* See if all slots are available. */
  130743. + for (i = 0; i < PageCount; i++, table++)
  130744. + {
  130745. + if (*table != ~0)
  130746. + {
  130747. + /* Start from next slot. */
  130748. + index += i + 1;
  130749. + break;
  130750. + }
  130751. + }
  130752. +
  130753. + if (i == PageCount)
  130754. + {
  130755. + /* Bail out if we have enough page entries. */
  130756. + allocated = gcvTRUE;
  130757. + break;
  130758. + }
  130759. + }
  130760. +
  130761. + if (!allocated)
  130762. + {
  130763. + if (status >= 0)
  130764. + {
  130765. + /* Walk all entries until we find enough slots. */
  130766. + for (index = 0; index <= tail;)
  130767. + {
  130768. + /* Access page table. */
  130769. + table = (gctUINT32 *) Mmu->pageTableLogical + index;
  130770. +
  130771. + /* See if all slots are available. */
  130772. + for (i = 0; i < PageCount; i++, table++)
  130773. + {
  130774. + if (*table != ~0)
  130775. + {
  130776. + /* Start from next slot. */
  130777. + index += i + 1;
  130778. + break;
  130779. + }
  130780. + }
  130781. +
  130782. + if (i == PageCount)
  130783. + {
  130784. + /* Bail out if we have enough page entries. */
  130785. + allocated = gcvTRUE;
  130786. + break;
  130787. + }
  130788. + }
  130789. + }
  130790. + }
  130791. +
  130792. + if (!allocated && (status >= 0))
  130793. + {
  130794. + gcmkTRACE_ZONE(
  130795. + gcvLEVEL_ERROR, gcvZONE_MMU,
  130796. + "%s(%d): not enough free pages for %u pages.\n",
  130797. + __FUNCTION__, __LINE__,
  130798. + PageCount
  130799. + );
  130800. +
  130801. + /* Not enough empty slots available. */
  130802. + status = gcvSTATUS_OUT_OF_RESOURCES;
  130803. + }
  130804. +
  130805. + if (status >= 0)
  130806. + {
  130807. + /* Build virtual address. */
  130808. + status = gckVGHARDWARE_BuildVirtualAddress(Mmu->hardware,
  130809. + index,
  130810. + 0,
  130811. + Address);
  130812. +
  130813. + if (status >= 0)
  130814. + {
  130815. + /* Update current entry into page table. */
  130816. + Mmu->entry = index + PageCount;
  130817. +
  130818. + /* Return pointer to page table. */
  130819. + *PageTable = (gctUINT32 *) Mmu->pageTableLogical + index;
  130820. +
  130821. + gcmkTRACE_ZONE(
  130822. + gcvLEVEL_INFO, gcvZONE_MMU,
  130823. + "%s(%d): allocated %u pages at index %u (0x%08X) @ %p.\n",
  130824. + __FUNCTION__, __LINE__,
  130825. + PageCount,
  130826. + index,
  130827. + *Address,
  130828. + *PageTable
  130829. + );
  130830. + }
  130831. + }
  130832. +
  130833. + /* Release the mutex. */
  130834. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->mutex));
  130835. + gcmkFOOTER();
  130836. +
  130837. + /* Return status. */
  130838. + return status;
  130839. +}
  130840. +
  130841. +/*******************************************************************************
  130842. +**
  130843. +** gckVGMMU_FreePages
  130844. +**
  130845. +** Free pages inside the page table.
  130846. +**
  130847. +** INPUT:
  130848. +**
  130849. +** gckVGMMU Mmu
  130850. +** Pointer to an gckVGMMU object.
  130851. +**
  130852. +** gctPOINTER PageTable
  130853. +** Base address of the page table to free.
  130854. +**
  130855. +** gctSIZE_T PageCount
  130856. +** Number of pages to free.
  130857. +**
  130858. +** OUTPUT:
  130859. +**
  130860. +** Nothing.
  130861. +*/
  130862. +gceSTATUS gckVGMMU_FreePages(
  130863. + IN gckVGMMU Mmu,
  130864. + IN gctPOINTER PageTable,
  130865. + IN gctSIZE_T PageCount
  130866. + )
  130867. +{
  130868. + gctUINT32 * table;
  130869. +
  130870. + gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=0x%x",
  130871. + Mmu, PageTable, PageCount);
  130872. +
  130873. + /* Verify the arguments. */
  130874. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130875. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  130876. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  130877. +
  130878. + gcmkTRACE_ZONE(
  130879. + gcvLEVEL_INFO, gcvZONE_MMU,
  130880. + "%s(%d): freeing %u pages at index %u @ %p.\n",
  130881. + __FUNCTION__, __LINE__,
  130882. + PageCount,
  130883. + ((gctUINT32 *) PageTable - (gctUINT32 *) Mmu->pageTableLogical),
  130884. + PageTable
  130885. + );
  130886. +
  130887. + /* Convert pointer. */
  130888. + table = (gctUINT32 *) PageTable;
  130889. +
  130890. + /* Mark the page table entries as available. */
  130891. + while (PageCount-- > 0)
  130892. + {
  130893. + *table++ = (gctUINT32)~0;
  130894. + }
  130895. +
  130896. + gcmkFOOTER_NO();
  130897. + /* Success. */
  130898. + return gcvSTATUS_OK;
  130899. +}
  130900. +
  130901. +gceSTATUS
  130902. +gckVGMMU_SetPage(
  130903. + IN gckVGMMU Mmu,
  130904. + IN gctUINT32 PageAddress,
  130905. + IN gctUINT32 *PageEntry
  130906. + )
  130907. +{
  130908. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  130909. +
  130910. + /* Verify the arguments. */
  130911. + gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
  130912. + gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
  130913. + gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
  130914. +
  130915. + *PageEntry = PageAddress;
  130916. +
  130917. + /* Success. */
  130918. + gcmkFOOTER_NO();
  130919. + return gcvSTATUS_OK;
  130920. +}
  130921. +
  130922. +gceSTATUS
  130923. +gckVGMMU_Flush(
  130924. + IN gckVGMMU Mmu
  130925. + )
  130926. +{
  130927. + gckVGHARDWARE hardware;
  130928. +
  130929. + gcmkHEADER_ARG("Mmu=0x%x", Mmu);
  130930. +
  130931. + hardware = Mmu->hardware;
  130932. + gcmkVERIFY_OK(
  130933. + gckOS_AtomSet(hardware->os, hardware->pageTableDirty, 1));
  130934. +
  130935. + /* Success. */
  130936. + gcmkFOOTER_NO();
  130937. + return gcvSTATUS_OK;
  130938. +}
  130939. +
  130940. +#endif /* gcdENABLE_VG */
  130941. diff -Nur linux-3.14.17/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
  130942. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c 1970-01-01 01:00:00.000000000 +0100
  130943. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c 2014-09-11 18:06:03.114042420 +0200
  130944. @@ -0,0 +1,347 @@
  130945. +/****************************************************************************
  130946. +*
  130947. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  130948. +*
  130949. +* This program is free software; you can redistribute it and/or modify
  130950. +* it under the terms of the GNU General Public License as published by
  130951. +* the Free Software Foundation; either version 2 of the license, or
  130952. +* (at your option) any later version.
  130953. +*
  130954. +* This program is distributed in the hope that it will be useful,
  130955. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  130956. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  130957. +* GNU General Public License for more details.
  130958. +*
  130959. +* You should have received a copy of the GNU General Public License
  130960. +* along with this program; if not write to the Free Software
  130961. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  130962. +*
  130963. +*****************************************************************************/
  130964. +
  130965. +
  130966. +#include "gc_hal_kernel_precomp.h"
  130967. +
  130968. +#define _GC_OBJ_ZONE gcvZONE_POWER
  130969. +
  130970. +/******************************************************************************\
  130971. +************************ Dynamic Voltage Frequency Setting *********************
  130972. +\******************************************************************************/
  130973. +#if gcdDVFS
  130974. +static gctUINT32
  130975. +_GetLoadHistory(
  130976. + IN gckDVFS Dvfs,
  130977. + IN gctUINT32 Select,
  130978. + IN gctUINT32 Index
  130979. +)
  130980. +{
  130981. + return Dvfs->loads[Index];
  130982. +}
  130983. +
  130984. +static void
  130985. +_IncreaseScale(
  130986. + IN gckDVFS Dvfs,
  130987. + IN gctUINT32 Load,
  130988. + OUT gctUINT8 *Scale
  130989. + )
  130990. +{
  130991. + if (Dvfs->currentScale < 32)
  130992. + {
  130993. + *Scale = Dvfs->currentScale + 8;
  130994. + }
  130995. + else
  130996. + {
  130997. + *Scale = Dvfs->currentScale + 8;
  130998. + *Scale = gcmMIN(64, *Scale);
  130999. + }
  131000. +}
  131001. +
  131002. +static void
  131003. +_RecordFrequencyHistory(
  131004. + gckDVFS Dvfs,
  131005. + gctUINT32 Frequency
  131006. + )
  131007. +{
  131008. + gctUINT32 i = 0;
  131009. +
  131010. + struct _FrequencyHistory *history = Dvfs->frequencyHistory;
  131011. +
  131012. + for (i = 0; i < 16; i++)
  131013. + {
  131014. + if (history->frequency == Frequency)
  131015. + {
  131016. + break;
  131017. + }
  131018. +
  131019. + if (history->frequency == 0)
  131020. + {
  131021. + history->frequency = Frequency;
  131022. + break;
  131023. + }
  131024. +
  131025. + history++;
  131026. + }
  131027. +
  131028. + if (i < 16)
  131029. + {
  131030. + history->count++;
  131031. + }
  131032. +}
  131033. +
  131034. +static gctUINT32
  131035. +_GetFrequencyHistory(
  131036. + gckDVFS Dvfs,
  131037. + gctUINT32 Frequency
  131038. + )
  131039. +{
  131040. + gctUINT32 i = 0;
  131041. +
  131042. + struct _FrequencyHistory * history = Dvfs->frequencyHistory;
  131043. +
  131044. + for (i = 0; i < 16; i++)
  131045. + {
  131046. + if (history->frequency == Frequency)
  131047. + {
  131048. + break;
  131049. + }
  131050. +
  131051. + history++;
  131052. + }
  131053. +
  131054. + if (i < 16)
  131055. + {
  131056. + return history->count;
  131057. + }
  131058. +
  131059. + return 0;
  131060. +}
  131061. +
  131062. +static void
  131063. +_Policy(
  131064. + IN gckDVFS Dvfs,
  131065. + IN gctUINT32 Load,
  131066. + OUT gctUINT8 *Scale
  131067. + )
  131068. +{
  131069. + gctUINT8 load[4], nextLoad;
  131070. + gctUINT8 scale;
  131071. +
  131072. + /* Last 4 history. */
  131073. + load[0] = (Load & 0xFF);
  131074. + load[1] = (Load & 0xFF00) >> 8;
  131075. + load[2] = (Load & 0xFF0000) >> 16;
  131076. + load[3] = (Load & 0xFF000000) >> 24;
  131077. +
  131078. + /* Determine target scale. */
  131079. + if (load[0] > 54)
  131080. + {
  131081. + _IncreaseScale(Dvfs, Load, &scale);
  131082. + }
  131083. + else
  131084. + {
  131085. + nextLoad = (load[0] + load[1] + load[2] + load[3])/4;
  131086. +
  131087. + scale = Dvfs->currentScale * (nextLoad) / 54;
  131088. +
  131089. + scale = gcmMAX(1, scale);
  131090. + scale = gcmMIN(64, scale);
  131091. + }
  131092. +
  131093. + Dvfs->totalConfig++;
  131094. +
  131095. + Dvfs->loads[(load[0]-1)/8]++;
  131096. +
  131097. + *Scale = scale;
  131098. +
  131099. +
  131100. + if (Dvfs->totalConfig % 100 == 0)
  131101. + {
  131102. + gcmkPRINT("=======================================================");
  131103. + gcmkPRINT("GPU Load: %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
  131104. + 8, 16, 24, 32, 40, 48, 56, 64);
  131105. + gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
  131106. + _GetLoadHistory(Dvfs,2, 0),
  131107. + _GetLoadHistory(Dvfs,2, 1),
  131108. + _GetLoadHistory(Dvfs,2, 2),
  131109. + _GetLoadHistory(Dvfs,2, 3),
  131110. + _GetLoadHistory(Dvfs,2, 4),
  131111. + _GetLoadHistory(Dvfs,2, 5),
  131112. + _GetLoadHistory(Dvfs,2, 6),
  131113. + _GetLoadHistory(Dvfs,2, 7)
  131114. + );
  131115. +
  131116. + gcmkPRINT("Frequency(MHz) %-8d %-8d %-8d %-8d %-8d",
  131117. + 58, 120, 240, 360, 480);
  131118. + gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d",
  131119. + _GetFrequencyHistory(Dvfs, 58),
  131120. + _GetFrequencyHistory(Dvfs,120),
  131121. + _GetFrequencyHistory(Dvfs,240),
  131122. + _GetFrequencyHistory(Dvfs,360),
  131123. + _GetFrequencyHistory(Dvfs,480)
  131124. + );
  131125. + }
  131126. +}
  131127. +
  131128. +static void
  131129. +_TimerFunction(
  131130. + gctPOINTER Data
  131131. + )
  131132. +{
  131133. + gceSTATUS status;
  131134. + gckDVFS dvfs = (gckDVFS) Data;
  131135. + gckHARDWARE hardware = dvfs->hardware;
  131136. + gctUINT32 value;
  131137. + gctUINT32 frequency;
  131138. + gctUINT8 scale;
  131139. + gctUINT32 t1, t2, consumed;
  131140. +
  131141. + gckOS_GetTicks(&t1);
  131142. +
  131143. + gcmkONERROR(gckHARDWARE_QueryLoad(hardware, &value));
  131144. +
  131145. + /* determine target sacle. */
  131146. + _Policy(dvfs, value, &scale);
  131147. +
  131148. + /* Set frequency and voltage. */
  131149. + gcmkONERROR(gckOS_SetGPUFrequency(hardware->os, hardware->core, scale));
  131150. +
  131151. + /* Query real frequency. */
  131152. + gcmkONERROR(
  131153. + gckOS_QueryGPUFrequency(hardware->os,
  131154. + hardware->core,
  131155. + &frequency,
  131156. + &dvfs->currentScale));
  131157. +
  131158. + _RecordFrequencyHistory(dvfs, frequency);
  131159. +
  131160. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_POWER,
  131161. + "Current frequency = %d",
  131162. + frequency);
  131163. +
  131164. + /* Set period. */
  131165. + gcmkONERROR(gckHARDWARE_SetDVFSPeroid(hardware, frequency));
  131166. +
  131167. +OnError:
  131168. + /* Determine next querying time. */
  131169. + gckOS_GetTicks(&t2);
  131170. +
  131171. + consumed = gcmMIN(((long)t2 - (long)t1), 5);
  131172. +
  131173. + if (dvfs->stop == gcvFALSE)
  131174. + {
  131175. + gcmkVERIFY_OK(gckOS_StartTimer(hardware->os,
  131176. + dvfs->timer,
  131177. + dvfs->pollingTime - consumed));
  131178. + }
  131179. +
  131180. + return;
  131181. +}
  131182. +
  131183. +gceSTATUS
  131184. +gckDVFS_Construct(
  131185. + IN gckHARDWARE Hardware,
  131186. + OUT gckDVFS * Dvfs
  131187. + )
  131188. +{
  131189. + gceSTATUS status;
  131190. + gctPOINTER pointer;
  131191. + gckDVFS dvfs = gcvNULL;
  131192. + gckOS os = Hardware->os;
  131193. +
  131194. + gcmkHEADER_ARG("Hardware=0x%X", Hardware);
  131195. +
  131196. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  131197. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  131198. +
  131199. + /* Allocate a gckDVFS manager. */
  131200. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(struct _gckDVFS), &pointer));
  131201. +
  131202. + gckOS_ZeroMemory(pointer, gcmSIZEOF(struct _gckDVFS));
  131203. +
  131204. + dvfs = pointer;
  131205. +
  131206. + /* Initialization. */
  131207. + dvfs->hardware = Hardware;
  131208. + dvfs->pollingTime = gcdDVFS_POLLING_TIME;
  131209. + dvfs->os = Hardware->os;
  131210. + dvfs->currentScale = 64;
  131211. +
  131212. + /* Create a polling timer. */
  131213. + gcmkONERROR(gckOS_CreateTimer(os, _TimerFunction, pointer, &dvfs->timer));
  131214. +
  131215. + /* Initialize frequency and voltage adjustment helper. */
  131216. + gcmkONERROR(gckOS_PrepareGPUFrequency(os, Hardware->core));
  131217. +
  131218. + /* Return result. */
  131219. + *Dvfs = dvfs;
  131220. +
  131221. + gcmkFOOTER_NO();
  131222. + return gcvSTATUS_OK;
  131223. +
  131224. +OnError:
  131225. + /* Roll back. */
  131226. + if (dvfs)
  131227. + {
  131228. + if (dvfs->timer)
  131229. + {
  131230. + gcmkVERIFY_OK(gckOS_DestroyTimer(os, dvfs->timer));
  131231. + }
  131232. +
  131233. + gcmkOS_SAFE_FREE(os, dvfs);
  131234. + }
  131235. +
  131236. + gcmkFOOTER();
  131237. + return status;
  131238. +}
  131239. +
  131240. +gceSTATUS
  131241. +gckDVFS_Destroy(
  131242. + IN gckDVFS Dvfs
  131243. + )
  131244. +{
  131245. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  131246. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  131247. +
  131248. + /* Deinitialize helper fuunction. */
  131249. + gcmkVERIFY_OK(gckOS_FinishGPUFrequency(Dvfs->os, Dvfs->hardware->core));
  131250. +
  131251. + /* DestroyTimer. */
  131252. + gcmkVERIFY_OK(gckOS_DestroyTimer(Dvfs->os, Dvfs->timer));
  131253. +
  131254. + gcmkOS_SAFE_FREE(Dvfs->os, Dvfs);
  131255. +
  131256. + gcmkFOOTER_NO();
  131257. + return gcvSTATUS_OK;
  131258. +}
  131259. +
  131260. +gceSTATUS
  131261. +gckDVFS_Start(
  131262. + IN gckDVFS Dvfs
  131263. + )
  131264. +{
  131265. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  131266. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  131267. +
  131268. + gckHARDWARE_InitDVFS(Dvfs->hardware);
  131269. +
  131270. + Dvfs->stop = gcvFALSE;
  131271. +
  131272. + gckOS_StartTimer(Dvfs->os, Dvfs->timer, Dvfs->pollingTime);
  131273. +
  131274. + gcmkFOOTER_NO();
  131275. + return gcvSTATUS_OK;
  131276. +}
  131277. +
  131278. +gceSTATUS
  131279. +gckDVFS_Stop(
  131280. + IN gckDVFS Dvfs
  131281. + )
  131282. +{
  131283. + gcmkHEADER_ARG("Dvfs=0x%X", Dvfs);
  131284. + gcmkVERIFY_ARGUMENT(Dvfs != gcvNULL);
  131285. +
  131286. + Dvfs->stop = gcvTRUE;
  131287. +
  131288. + gcmkFOOTER_NO();
  131289. + return gcvSTATUS_OK;
  131290. +}
  131291. +#endif
  131292. diff -Nur linux-3.14.17/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
  131293. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h 1970-01-01 01:00:00.000000000 +0100
  131294. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h 2014-09-11 18:06:03.114042420 +0200
  131295. @@ -0,0 +1,29 @@
  131296. +/****************************************************************************
  131297. +*
  131298. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  131299. +*
  131300. +* This program is free software; you can redistribute it and/or modify
  131301. +* it under the terms of the GNU General Public License as published by
  131302. +* the Free Software Foundation; either version 2 of the license, or
  131303. +* (at your option) any later version.
  131304. +*
  131305. +* This program is distributed in the hope that it will be useful,
  131306. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  131307. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  131308. +* GNU General Public License for more details.
  131309. +*
  131310. +* You should have received a copy of the GNU General Public License
  131311. +* along with this program; if not write to the Free Software
  131312. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  131313. +*
  131314. +*****************************************************************************/
  131315. +
  131316. +
  131317. +#ifndef __gc_hal_kernel_precomp_h_
  131318. +#define __gc_hal_kernel_precomp_h_
  131319. +
  131320. +#include "gc_hal.h"
  131321. +#include "gc_hal_driver.h"
  131322. +#include "gc_hal_kernel.h"
  131323. +
  131324. +#endif /* __gc_hal_kernel_precomp_h_ */
  131325. diff -Nur linux-3.14.17/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
  131326. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c 1970-01-01 01:00:00.000000000 +0100
  131327. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c 2014-09-11 18:06:03.114042420 +0200
  131328. @@ -0,0 +1,895 @@
  131329. +/****************************************************************************
  131330. +*
  131331. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  131332. +*
  131333. +* This program is free software; you can redistribute it and/or modify
  131334. +* it under the terms of the GNU General Public License as published by
  131335. +* the Free Software Foundation; either version 2 of the license, or
  131336. +* (at your option) any later version.
  131337. +*
  131338. +* This program is distributed in the hope that it will be useful,
  131339. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  131340. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  131341. +* GNU General Public License for more details.
  131342. +*
  131343. +* You should have received a copy of the GNU General Public License
  131344. +* along with this program; if not write to the Free Software
  131345. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  131346. +*
  131347. +*****************************************************************************/
  131348. +
  131349. +
  131350. +#include "gc_hal_kernel_precomp.h"
  131351. +
  131352. +#if gcdENABLE_VG
  131353. +
  131354. +#define ENABLE_VG_TRY_VIRTUAL_MEMORY 0
  131355. +
  131356. +#define _GC_OBJ_ZONE gcvZONE_VG
  131357. +
  131358. +/******************************************************************************\
  131359. +******************************* gckKERNEL API Code ******************************
  131360. +\******************************************************************************/
  131361. +
  131362. +/*******************************************************************************
  131363. +**
  131364. +** gckKERNEL_Construct
  131365. +**
  131366. +** Construct a new gckKERNEL object.
  131367. +**
  131368. +** INPUT:
  131369. +**
  131370. +** gckOS Os
  131371. +** Pointer to an gckOS object.
  131372. +**
  131373. +** IN gctPOINTER Context
  131374. +** Pointer to a driver defined context.
  131375. +**
  131376. +** OUTPUT:
  131377. +**
  131378. +** gckKERNEL * Kernel
  131379. +** Pointer to a variable that will hold the pointer to the gckKERNEL
  131380. +** object.
  131381. +*/
  131382. +gceSTATUS gckVGKERNEL_Construct(
  131383. + IN gckOS Os,
  131384. + IN gctPOINTER Context,
  131385. + IN gckKERNEL inKernel,
  131386. + OUT gckVGKERNEL * Kernel
  131387. + )
  131388. +{
  131389. + gceSTATUS status;
  131390. + gckVGKERNEL kernel = gcvNULL;
  131391. +
  131392. + gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
  131393. + /* Verify the arguments. */
  131394. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  131395. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  131396. +
  131397. + do
  131398. + {
  131399. + /* Allocate the gckKERNEL object. */
  131400. + gcmkERR_BREAK(gckOS_Allocate(
  131401. + Os,
  131402. + sizeof(struct _gckVGKERNEL),
  131403. + (gctPOINTER *) &kernel
  131404. + ));
  131405. +
  131406. + /* Initialize the gckKERNEL object. */
  131407. + kernel->object.type = gcvOBJ_KERNEL;
  131408. + kernel->os = Os;
  131409. + kernel->context = Context;
  131410. + kernel->hardware = gcvNULL;
  131411. + kernel->interrupt = gcvNULL;
  131412. + kernel->command = gcvNULL;
  131413. + kernel->mmu = gcvNULL;
  131414. + kernel->kernel = inKernel;
  131415. +
  131416. + /* Construct the gckVGHARDWARE object. */
  131417. + gcmkERR_BREAK(gckVGHARDWARE_Construct(
  131418. + Os, &kernel->hardware
  131419. + ));
  131420. +
  131421. + /* Set pointer to gckKERNEL object in gckVGHARDWARE object. */
  131422. + kernel->hardware->kernel = kernel;
  131423. +
  131424. + /* Construct the gckVGINTERRUPT object. */
  131425. + gcmkERR_BREAK(gckVGINTERRUPT_Construct(
  131426. + kernel, &kernel->interrupt
  131427. + ));
  131428. +
  131429. + /* Construct the gckVGCOMMAND object. */
  131430. + gcmkERR_BREAK(gckVGCOMMAND_Construct(
  131431. + kernel, gcmKB2BYTES(8), gcmKB2BYTES(2), &kernel->command
  131432. + ));
  131433. +
  131434. + /* Construct the gckVGMMU object. */
  131435. + gcmkERR_BREAK(gckVGMMU_Construct(
  131436. + kernel, gcmKB2BYTES(32), &kernel->mmu
  131437. + ));
  131438. +
  131439. + /* Return pointer to the gckKERNEL object. */
  131440. + *Kernel = kernel;
  131441. +
  131442. + gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
  131443. + /* Success. */
  131444. + return gcvSTATUS_OK;
  131445. + }
  131446. + while (gcvFALSE);
  131447. +
  131448. + /* Roll back. */
  131449. + if (kernel != gcvNULL)
  131450. + {
  131451. + if (kernel->mmu != gcvNULL)
  131452. + {
  131453. + gcmkVERIFY_OK(gckVGMMU_Destroy(kernel->mmu));
  131454. + }
  131455. +
  131456. + if (kernel->command != gcvNULL)
  131457. + {
  131458. + gcmkVERIFY_OK(gckVGCOMMAND_Destroy(kernel->command));
  131459. + }
  131460. +
  131461. + if (kernel->interrupt != gcvNULL)
  131462. + {
  131463. + gcmkVERIFY_OK(gckVGINTERRUPT_Destroy(kernel->interrupt));
  131464. + }
  131465. +
  131466. + if (kernel->hardware != gcvNULL)
  131467. + {
  131468. + gcmkVERIFY_OK(gckVGHARDWARE_Destroy(kernel->hardware));
  131469. + }
  131470. +
  131471. + gcmkVERIFY_OK(gckOS_Free(Os, kernel));
  131472. + }
  131473. +
  131474. + gcmkFOOTER();
  131475. + /* Return status. */
  131476. + return status;
  131477. +}
  131478. +
  131479. +/*******************************************************************************
  131480. +**
  131481. +** gckKERNEL_Destroy
  131482. +**
  131483. +** Destroy an gckKERNEL object.
  131484. +**
  131485. +** INPUT:
  131486. +**
  131487. +** gckKERNEL Kernel
  131488. +** Pointer to an gckKERNEL object to destroy.
  131489. +**
  131490. +** OUTPUT:
  131491. +**
  131492. +** Nothing.
  131493. +*/
  131494. +gceSTATUS gckVGKERNEL_Destroy(
  131495. + IN gckVGKERNEL Kernel
  131496. + )
  131497. +{
  131498. + gceSTATUS status;
  131499. +
  131500. + gcmkHEADER_ARG("Kernel=0x%x", Kernel);
  131501. +
  131502. + /* Verify the arguments. */
  131503. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  131504. +
  131505. + do
  131506. + {
  131507. + /* Destroy the gckVGMMU object. */
  131508. + if (Kernel->mmu != gcvNULL)
  131509. + {
  131510. + gcmkERR_BREAK(gckVGMMU_Destroy(Kernel->mmu));
  131511. + Kernel->mmu = gcvNULL;
  131512. + }
  131513. +
  131514. + /* Destroy the gckVGCOMMAND object. */
  131515. + if (Kernel->command != gcvNULL)
  131516. + {
  131517. + gcmkERR_BREAK(gckVGCOMMAND_Destroy(Kernel->command));
  131518. + Kernel->command = gcvNULL;
  131519. + }
  131520. +
  131521. + /* Destroy the gckVGINTERRUPT object. */
  131522. + if (Kernel->interrupt != gcvNULL)
  131523. + {
  131524. + gcmkERR_BREAK(gckVGINTERRUPT_Destroy(Kernel->interrupt));
  131525. + Kernel->interrupt = gcvNULL;
  131526. + }
  131527. +
  131528. + /* Destroy the gckVGHARDWARE object. */
  131529. + if (Kernel->hardware != gcvNULL)
  131530. + {
  131531. + gcmkERR_BREAK(gckVGHARDWARE_Destroy(Kernel->hardware));
  131532. + Kernel->hardware = gcvNULL;
  131533. + }
  131534. +
  131535. + /* Mark the gckKERNEL object as unknown. */
  131536. + Kernel->object.type = gcvOBJ_UNKNOWN;
  131537. +
  131538. + /* Free the gckKERNEL object. */
  131539. + gcmkERR_BREAK(gckOS_Free(Kernel->os, Kernel));
  131540. + }
  131541. + while (gcvFALSE);
  131542. +
  131543. + gcmkFOOTER();
  131544. +
  131545. + /* Return status. */
  131546. + return status;
  131547. +}
  131548. +
  131549. +/*******************************************************************************
  131550. +**
  131551. +** gckKERNEL_AllocateLinearMemory
  131552. +**
  131553. +** Function walks all required memory pools and allocates the requested
  131554. +** amount of video memory.
  131555. +**
  131556. +** INPUT:
  131557. +**
  131558. +** gckKERNEL Kernel
  131559. +** Pointer to an gckKERNEL object.
  131560. +**
  131561. +** gcePOOL * Pool
  131562. +** Pointer the desired memory pool.
  131563. +**
  131564. +** gctSIZE_T Bytes
  131565. +** Number of bytes to allocate.
  131566. +**
  131567. +** gctSIZE_T Alignment
  131568. +** Required buffer alignment.
  131569. +**
  131570. +** gceSURF_TYPE Type
  131571. +** Surface type.
  131572. +**
  131573. +** OUTPUT:
  131574. +**
  131575. +** gcePOOL * Pool
  131576. +** Pointer to the actual pool where the memory was allocated.
  131577. +**
  131578. +** gcuVIDMEM_NODE_PTR * Node
  131579. +** Allocated node.
  131580. +*/
  131581. +gceSTATUS
  131582. +gckKERNEL_AllocateLinearMemory(
  131583. + IN gckKERNEL Kernel,
  131584. + IN OUT gcePOOL * Pool,
  131585. + IN gctSIZE_T Bytes,
  131586. + IN gctSIZE_T Alignment,
  131587. + IN gceSURF_TYPE Type,
  131588. + OUT gcuVIDMEM_NODE_PTR * Node
  131589. + )
  131590. +{
  131591. + gcePOOL pool;
  131592. + gceSTATUS status;
  131593. + gckVIDMEM videoMemory;
  131594. +
  131595. + /* Get initial pool. */
  131596. + switch (pool = *Pool)
  131597. + {
  131598. + case gcvPOOL_DEFAULT:
  131599. + case gcvPOOL_LOCAL:
  131600. + pool = gcvPOOL_LOCAL_INTERNAL;
  131601. + break;
  131602. +
  131603. + case gcvPOOL_UNIFIED:
  131604. + pool = gcvPOOL_SYSTEM;
  131605. + break;
  131606. +
  131607. + default:
  131608. + break;
  131609. + }
  131610. +
  131611. + do
  131612. + {
  131613. + /* Verify the number of bytes to allocate. */
  131614. + if (Bytes == 0)
  131615. + {
  131616. + status = gcvSTATUS_INVALID_ARGUMENT;
  131617. + break;
  131618. + }
  131619. +
  131620. + if (pool == gcvPOOL_VIRTUAL)
  131621. + {
  131622. + /* Create a gcuVIDMEM_NODE for virtual memory. */
  131623. + gcmkERR_BREAK(gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, Node));
  131624. +
  131625. + /* Success. */
  131626. + break;
  131627. + }
  131628. +
  131629. + else
  131630. + {
  131631. + /* Get pointer to gckVIDMEM object for pool. */
  131632. + status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
  131633. +
  131634. + if (status == gcvSTATUS_OK)
  131635. + {
  131636. + if(*Pool == gcvPOOL_SYSTEM)
  131637. + Type |= gcvSURF_VG;
  131638. + /* Allocate memory. */
  131639. + status = gckVIDMEM_AllocateLinear(videoMemory,
  131640. + Bytes,
  131641. + Alignment,
  131642. + Type,
  131643. + Node);
  131644. +
  131645. + if (status == gcvSTATUS_OK)
  131646. + {
  131647. + /* Memory allocated. */
  131648. + break;
  131649. + }
  131650. + }
  131651. + }
  131652. +
  131653. + if (pool == gcvPOOL_LOCAL_INTERNAL)
  131654. + {
  131655. + /* Advance to external memory. */
  131656. + pool = gcvPOOL_LOCAL_EXTERNAL;
  131657. + }
  131658. + else if (pool == gcvPOOL_LOCAL_EXTERNAL)
  131659. + {
  131660. + /* Advance to contiguous system memory. */
  131661. + pool = gcvPOOL_SYSTEM;
  131662. + }
  131663. + else if (pool == gcvPOOL_SYSTEM)
  131664. + {
  131665. + /* Advance to virtual memory. */
  131666. +#if ENABLE_VG_TRY_VIRTUAL_MEMORY
  131667. + pool = gcvPOOL_VIRTUAL;
  131668. +#else
  131669. + /*VG non-contiguous memory support is not ready yet, disable it temporary*/
  131670. + status = gcvSTATUS_OUT_OF_MEMORY;
  131671. + break;
  131672. +#endif
  131673. + }
  131674. + else
  131675. + {
  131676. + /* Out of pools. */
  131677. + status = gcvSTATUS_OUT_OF_MEMORY;
  131678. + break;
  131679. + }
  131680. + }
  131681. + /* Loop only for multiple selection pools. */
  131682. + while ((*Pool == gcvPOOL_DEFAULT)
  131683. + || (*Pool == gcvPOOL_LOCAL)
  131684. + || (*Pool == gcvPOOL_UNIFIED)
  131685. + );
  131686. +
  131687. + if (gcmIS_SUCCESS(status))
  131688. + {
  131689. + /* Return pool used for allocation. */
  131690. + *Pool = pool;
  131691. + }
  131692. +
  131693. + /* Return status. */
  131694. + return status;
  131695. +}
  131696. +
  131697. +/*******************************************************************************
  131698. +**
  131699. +** gckKERNEL_Dispatch
  131700. +**
  131701. +** Dispatch a command received from the user HAL layer.
  131702. +**
  131703. +** INPUT:
  131704. +**
  131705. +** gckKERNEL Kernel
  131706. +** Pointer to an gckKERNEL object.
  131707. +**
  131708. +** gcsHAL_INTERFACE * Interface
  131709. +** Pointer to a gcsHAL_INTERFACE structure that defines the command to
  131710. +** be dispatched.
  131711. +**
  131712. +** OUTPUT:
  131713. +**
  131714. +** gcsHAL_INTERFACE * Interface
  131715. +** Pointer to a gcsHAL_INTERFACE structure that receives any data to be
  131716. +** returned.
  131717. +*/
  131718. +gceSTATUS gckVGKERNEL_Dispatch(
  131719. + IN gckKERNEL Kernel,
  131720. + IN gctBOOL FromUser,
  131721. + IN OUT gcsHAL_INTERFACE * Interface
  131722. + )
  131723. +{
  131724. + gceSTATUS status;
  131725. + gcsHAL_INTERFACE * kernelInterface = Interface;
  131726. + gcuVIDMEM_NODE_PTR node;
  131727. + gctUINT32 processID;
  131728. + gckKERNEL kernel = Kernel;
  131729. + gctPOINTER info = gcvNULL;
  131730. + gctPHYS_ADDR physical = gcvNULL;
  131731. + gctPOINTER logical = gcvNULL;
  131732. + gctSIZE_T bytes = 0;
  131733. +
  131734. + gcmkHEADER_ARG("Kernel=0x%x Interface=0x%x ", Kernel, Interface);
  131735. +
  131736. + /* Verify the arguments. */
  131737. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  131738. + gcmkVERIFY_ARGUMENT(Interface != gcvNULL);
  131739. +
  131740. + gcmkONERROR(gckOS_GetProcessID(&processID));
  131741. +
  131742. + /* Dispatch on command. */
  131743. + switch (Interface->command)
  131744. + {
  131745. + case gcvHAL_QUERY_VIDEO_MEMORY:
  131746. + /* Query video memory size. */
  131747. + gcmkERR_BREAK(gckKERNEL_QueryVideoMemory(
  131748. + Kernel, kernelInterface
  131749. + ));
  131750. + break;
  131751. +
  131752. + case gcvHAL_QUERY_CHIP_IDENTITY:
  131753. + /* Query chip identity. */
  131754. + gcmkERR_BREAK(gckVGHARDWARE_QueryChipIdentity(
  131755. + Kernel->vg->hardware,
  131756. + &kernelInterface->u.QueryChipIdentity.chipModel,
  131757. + &kernelInterface->u.QueryChipIdentity.chipRevision,
  131758. + &kernelInterface->u.QueryChipIdentity.chipFeatures,
  131759. + &kernelInterface->u.QueryChipIdentity.chipMinorFeatures,
  131760. + &kernelInterface->u.QueryChipIdentity.chipMinorFeatures2
  131761. + ));
  131762. + break;
  131763. +
  131764. + case gcvHAL_QUERY_COMMAND_BUFFER:
  131765. + /* Query command buffer information. */
  131766. + gcmkERR_BREAK(gckKERNEL_QueryCommandBuffer(
  131767. + Kernel,
  131768. + &kernelInterface->u.QueryCommandBuffer.information
  131769. + ));
  131770. + break;
  131771. + case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
  131772. + bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
  131773. + /* Allocate non-paged memory. */
  131774. + gcmkERR_BREAK(gckOS_AllocateContiguous(
  131775. + Kernel->os,
  131776. + gcvTRUE,
  131777. + &bytes,
  131778. + &physical,
  131779. + &logical
  131780. + ));
  131781. +
  131782. + kernelInterface->u.AllocateNonPagedMemory.bytes = bytes;
  131783. + kernelInterface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  131784. + kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  131785. + break;
  131786. +
  131787. + case gcvHAL_FREE_NON_PAGED_MEMORY:
  131788. + physical = gcmNAME_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.physical);
  131789. +
  131790. + /* Unmap user logical out of physical memory first. */
  131791. + gcmkERR_BREAK(gckOS_UnmapUserLogical(
  131792. + Kernel->os,
  131793. + physical,
  131794. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  131795. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  131796. + ));
  131797. +
  131798. + /* Free non-paged memory. */
  131799. + gcmkERR_BREAK(gckOS_FreeNonPagedMemory(
  131800. + Kernel->os,
  131801. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  131802. + physical,
  131803. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  131804. + ));
  131805. +
  131806. + gcmRELEASE_NAME(kernelInterface->u.AllocateNonPagedMemory.physical);
  131807. + break;
  131808. +
  131809. + case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
  131810. + bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
  131811. + /* Allocate contiguous memory. */
  131812. + gcmkERR_BREAK(gckOS_AllocateContiguous(
  131813. + Kernel->os,
  131814. + gcvTRUE,
  131815. + &bytes,
  131816. + &physical,
  131817. + &logical
  131818. + ));
  131819. +
  131820. + kernelInterface->u.AllocateNonPagedMemory.bytes = bytes;
  131821. + kernelInterface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical);
  131822. + kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
  131823. + break;
  131824. +
  131825. + case gcvHAL_FREE_CONTIGUOUS_MEMORY:
  131826. + physical = gcmNAME_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.physical);
  131827. + /* Unmap user logical out of physical memory first. */
  131828. + gcmkERR_BREAK(gckOS_UnmapUserLogical(
  131829. + Kernel->os,
  131830. + physical,
  131831. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes,
  131832. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical)
  131833. + ));
  131834. +
  131835. + /* Free contiguous memory. */
  131836. + gcmkERR_BREAK(gckOS_FreeContiguous(
  131837. + Kernel->os,
  131838. + physical,
  131839. + gcmUINT64_TO_PTR(kernelInterface->u.AllocateNonPagedMemory.logical),
  131840. + (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes
  131841. + ));
  131842. +
  131843. + gcmRELEASE_NAME(kernelInterface->u.AllocateNonPagedMemory.physical);
  131844. + break;
  131845. +
  131846. + case gcvHAL_ALLOCATE_VIDEO_MEMORY:
  131847. + {
  131848. + gctSIZE_T bytes;
  131849. + gctUINT32 bitsPerPixel;
  131850. + gctUINT32 bits;
  131851. +
  131852. + /* Align width and height to tiles. */
  131853. + gcmkERR_BREAK(gckVGHARDWARE_AlignToTile(
  131854. + Kernel->vg->hardware,
  131855. + kernelInterface->u.AllocateVideoMemory.type,
  131856. + &kernelInterface->u.AllocateVideoMemory.width,
  131857. + &kernelInterface->u.AllocateVideoMemory.height
  131858. + ));
  131859. +
  131860. + /* Convert format into bytes per pixel and bytes per tile. */
  131861. + gcmkERR_BREAK(gckVGHARDWARE_ConvertFormat(
  131862. + Kernel->vg->hardware,
  131863. + kernelInterface->u.AllocateVideoMemory.format,
  131864. + &bitsPerPixel,
  131865. + gcvNULL
  131866. + ));
  131867. +
  131868. + /* Compute number of bits for the allocation. */
  131869. + bits
  131870. + = kernelInterface->u.AllocateVideoMemory.width
  131871. + * kernelInterface->u.AllocateVideoMemory.height
  131872. + * kernelInterface->u.AllocateVideoMemory.depth
  131873. + * bitsPerPixel;
  131874. +
  131875. + /* Compute number of bytes for the allocation. */
  131876. + bytes = gcmALIGN(bits, 8) / 8;
  131877. +
  131878. + /* Allocate memory. */
  131879. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  131880. + Kernel,
  131881. + &kernelInterface->u.AllocateVideoMemory.pool,
  131882. + bytes,
  131883. + 64,
  131884. + kernelInterface->u.AllocateVideoMemory.type,
  131885. + &node
  131886. + ));
  131887. +
  131888. + kernelInterface->u.AllocateVideoMemory.node = gcmPTR_TO_UINT64(node);
  131889. + }
  131890. + break;
  131891. +
  131892. + case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
  131893. + /* Allocate memory. */
  131894. + gcmkERR_BREAK(gckKERNEL_AllocateLinearMemory(
  131895. + Kernel,
  131896. + &kernelInterface->u.AllocateLinearVideoMemory.pool,
  131897. + kernelInterface->u.AllocateLinearVideoMemory.bytes,
  131898. + kernelInterface->u.AllocateLinearVideoMemory.alignment,
  131899. + kernelInterface->u.AllocateLinearVideoMemory.type,
  131900. + &node
  131901. + ));
  131902. +
  131903. + gcmkERR_BREAK(gckKERNEL_AddProcessDB(Kernel,
  131904. + processID, gcvDB_VIDEO_MEMORY,
  131905. + node,
  131906. + gcvNULL,
  131907. + kernelInterface->u.AllocateLinearVideoMemory.bytes
  131908. + ));
  131909. +
  131910. + kernelInterface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node);
  131911. + break;
  131912. +
  131913. + case gcvHAL_FREE_VIDEO_MEMORY:
  131914. + node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node);
  131915. +#ifdef __QNXNTO__
  131916. + /* Unmap the video memory */
  131917. +
  131918. + if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) &&
  131919. + (node->VidMem.logical != gcvNULL))
  131920. + {
  131921. + gckKERNEL_UnmapVideoMemory(Kernel,
  131922. + node->VidMem.logical,
  131923. + processID,
  131924. + node->VidMem.bytes);
  131925. + node->VidMem.logical = gcvNULL;
  131926. + }
  131927. +#endif /* __QNXNTO__ */
  131928. +
  131929. + /* Free video memory. */
  131930. + gcmkERR_BREAK(gckVIDMEM_Free(
  131931. + node
  131932. + ));
  131933. +
  131934. + gcmkERR_BREAK(gckKERNEL_RemoveProcessDB(
  131935. + Kernel,
  131936. + processID, gcvDB_VIDEO_MEMORY,
  131937. + node
  131938. + ));
  131939. +
  131940. + break;
  131941. +
  131942. + case gcvHAL_MAP_MEMORY:
  131943. + /* Map memory. */
  131944. + gcmkERR_BREAK(gckKERNEL_MapMemory(
  131945. + Kernel,
  131946. + gcmINT2PTR(kernelInterface->u.MapMemory.physical),
  131947. + (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
  131948. + &logical
  131949. + ));
  131950. + kernelInterface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
  131951. + break;
  131952. +
  131953. + case gcvHAL_UNMAP_MEMORY:
  131954. + /* Unmap memory. */
  131955. + gcmkERR_BREAK(gckKERNEL_UnmapMemory(
  131956. + Kernel,
  131957. + gcmINT2PTR(kernelInterface->u.MapMemory.physical),
  131958. + (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
  131959. + gcmUINT64_TO_PTR(kernelInterface->u.MapMemory.logical)
  131960. + ));
  131961. + break;
  131962. +
  131963. + case gcvHAL_MAP_USER_MEMORY:
  131964. + /* Map user memory to DMA. */
  131965. + gcmkERR_BREAK(gckOS_MapUserMemory(
  131966. + Kernel->os,
  131967. + gcvCORE_VG,
  131968. + gcmUINT64_TO_PTR(kernelInterface->u.MapUserMemory.memory),
  131969. + kernelInterface->u.MapUserMemory.physical,
  131970. + (gctSIZE_T) kernelInterface->u.MapUserMemory.size,
  131971. + &info,
  131972. + &kernelInterface->u.MapUserMemory.address
  131973. + ));
  131974. +
  131975. + kernelInterface->u.MapUserMemory.info = gcmPTR_TO_NAME(info);
  131976. + break;
  131977. +
  131978. + case gcvHAL_UNMAP_USER_MEMORY:
  131979. + /* Unmap user memory. */
  131980. + gcmkERR_BREAK(gckOS_UnmapUserMemory(
  131981. + Kernel->os,
  131982. + gcvCORE_VG,
  131983. + gcmUINT64_TO_PTR(kernelInterface->u.UnmapUserMemory.memory),
  131984. + (gctSIZE_T) kernelInterface->u.UnmapUserMemory.size,
  131985. + gcmNAME_TO_PTR(kernelInterface->u.UnmapUserMemory.info),
  131986. + kernelInterface->u.UnmapUserMemory.address
  131987. + ));
  131988. + gcmRELEASE_NAME(kernelInterface->u.UnmapUserMemory.info);
  131989. + break;
  131990. + case gcvHAL_LOCK_VIDEO_MEMORY:
  131991. + node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node);
  131992. +
  131993. + /* Lock video memory. */
  131994. + gcmkERR_BREAK(
  131995. + gckVIDMEM_Lock(Kernel,
  131996. + node,
  131997. + gcvFALSE,
  131998. + &Interface->u.LockVideoMemory.address));
  131999. +
  132000. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  132001. + {
  132002. + /* Map video memory address into user space. */
  132003. +#ifdef __QNXNTO__
  132004. + if (node->VidMem.logical == gcvNULL)
  132005. + {
  132006. + gcmkONERROR(
  132007. + gckKERNEL_MapVideoMemory(Kernel,
  132008. + FromUser,
  132009. + Interface->u.LockVideoMemory.address,
  132010. + processID,
  132011. + node->VidMem.bytes,
  132012. + &node->VidMem.logical));
  132013. + }
  132014. +
  132015. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
  132016. +#else
  132017. + gcmkERR_BREAK(
  132018. + gckKERNEL_MapVideoMemoryEx(Kernel,
  132019. + gcvCORE_VG,
  132020. + FromUser,
  132021. + Interface->u.LockVideoMemory.address,
  132022. + &logical));
  132023. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
  132024. +#endif
  132025. + }
  132026. + else
  132027. + {
  132028. + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
  132029. +
  132030. + /* Success. */
  132031. + status = gcvSTATUS_OK;
  132032. + }
  132033. +
  132034. +#if gcdSECURE_USER
  132035. + /* Return logical address as physical address. */
  132036. + Interface->u.LockVideoMemory.address =
  132037. + (gctUINT32)(Interface->u.LockVideoMemory.memory);
  132038. +#endif
  132039. + gcmkERR_BREAK(
  132040. + gckKERNEL_AddProcessDB(Kernel,
  132041. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  132042. + node,
  132043. + gcvNULL,
  132044. + 0));
  132045. + break;
  132046. +
  132047. + case gcvHAL_UNLOCK_VIDEO_MEMORY:
  132048. + /* Unlock video memory. */
  132049. + node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node);
  132050. +
  132051. +#if gcdSECURE_USER
  132052. + /* Save node information before it disappears. */
  132053. + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  132054. + {
  132055. + logical = gcvNULL;
  132056. + bytes = 0;
  132057. + }
  132058. + else
  132059. + {
  132060. + logical = node->Virtual.logical;
  132061. + bytes = node->Virtual.bytes;
  132062. + }
  132063. +#endif
  132064. +
  132065. + /* Unlock video memory. */
  132066. + gcmkERR_BREAK(
  132067. + gckVIDMEM_Unlock(Kernel,
  132068. + node,
  132069. + Interface->u.UnlockVideoMemory.type,
  132070. + &Interface->u.UnlockVideoMemory.asynchroneous));
  132071. +
  132072. +#if gcdSECURE_USER
  132073. + /* Flush the translation cache for virtual surfaces. */
  132074. + if (logical != gcvNULL)
  132075. + {
  132076. + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
  132077. + cache,
  132078. + logical,
  132079. + bytes));
  132080. + }
  132081. +#endif
  132082. +
  132083. + if (Interface->u.UnlockVideoMemory.asynchroneous == gcvFALSE)
  132084. + {
  132085. + /* There isn't a event to unlock this node, remove record now */
  132086. + gcmkERR_BREAK(
  132087. + gckKERNEL_RemoveProcessDB(Kernel,
  132088. + processID, gcvDB_VIDEO_MEMORY_LOCKED,
  132089. + node));
  132090. + }
  132091. +
  132092. + break;
  132093. + case gcvHAL_USER_SIGNAL:
  132094. +#if !USE_NEW_LINUX_SIGNAL
  132095. + /* Dispatch depends on the user signal subcommands. */
  132096. + switch(Interface->u.UserSignal.command)
  132097. + {
  132098. + case gcvUSER_SIGNAL_CREATE:
  132099. + /* Create a signal used in the user space. */
  132100. + gcmkERR_BREAK(
  132101. + gckOS_CreateUserSignal(Kernel->os,
  132102. + Interface->u.UserSignal.manualReset,
  132103. + &Interface->u.UserSignal.id));
  132104. +
  132105. + gcmkVERIFY_OK(
  132106. + gckKERNEL_AddProcessDB(Kernel,
  132107. + processID, gcvDB_SIGNAL,
  132108. + gcmINT2PTR(Interface->u.UserSignal.id),
  132109. + gcvNULL,
  132110. + 0));
  132111. + break;
  132112. +
  132113. + case gcvUSER_SIGNAL_DESTROY:
  132114. + /* Destroy the signal. */
  132115. + gcmkERR_BREAK(
  132116. + gckOS_DestroyUserSignal(Kernel->os,
  132117. + Interface->u.UserSignal.id));
  132118. +
  132119. + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
  132120. + Kernel,
  132121. + processID, gcvDB_SIGNAL,
  132122. + gcmINT2PTR(Interface->u.UserSignal.id)));
  132123. + break;
  132124. +
  132125. + case gcvUSER_SIGNAL_SIGNAL:
  132126. + /* Signal the signal. */
  132127. + gcmkERR_BREAK(
  132128. + gckOS_SignalUserSignal(Kernel->os,
  132129. + Interface->u.UserSignal.id,
  132130. + Interface->u.UserSignal.state));
  132131. + break;
  132132. +
  132133. + case gcvUSER_SIGNAL_WAIT:
  132134. + /* Wait on the signal. */
  132135. + status = gckOS_WaitUserSignal(Kernel->os,
  132136. + Interface->u.UserSignal.id,
  132137. + Interface->u.UserSignal.wait);
  132138. + break;
  132139. +
  132140. + default:
  132141. + /* Invalid user signal command. */
  132142. + gcmkERR_BREAK(gcvSTATUS_INVALID_ARGUMENT);
  132143. + }
  132144. +#endif
  132145. + break;
  132146. +
  132147. + case gcvHAL_COMMIT:
  132148. + /* Commit a command and context buffer. */
  132149. + gcmkERR_BREAK(gckVGCOMMAND_Commit(
  132150. + Kernel->vg->command,
  132151. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.context),
  132152. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.queue),
  132153. + kernelInterface->u.VGCommit.entryCount,
  132154. + gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.taskTable)
  132155. + ));
  132156. + break;
  132157. + case gcvHAL_VERSION:
  132158. + kernelInterface->u.Version.major = gcvVERSION_MAJOR;
  132159. + kernelInterface->u.Version.minor = gcvVERSION_MINOR;
  132160. + kernelInterface->u.Version.patch = gcvVERSION_PATCH;
  132161. + kernelInterface->u.Version.build = gcvVERSION_BUILD;
  132162. + status = gcvSTATUS_OK;
  132163. + break;
  132164. +
  132165. + case gcvHAL_GET_BASE_ADDRESS:
  132166. + /* Get base address. */
  132167. + gcmkERR_BREAK(
  132168. + gckOS_GetBaseAddress(Kernel->os,
  132169. + &kernelInterface->u.GetBaseAddress.baseAddress));
  132170. + break;
  132171. + default:
  132172. + /* Invalid command. */
  132173. + status = gcvSTATUS_INVALID_ARGUMENT;
  132174. + }
  132175. +
  132176. +OnError:
  132177. + /* Save status. */
  132178. + kernelInterface->status = status;
  132179. +
  132180. + gcmkFOOTER();
  132181. +
  132182. + /* Return the status. */
  132183. + return status;
  132184. +}
  132185. +
  132186. +/*******************************************************************************
  132187. +**
  132188. +** gckKERNEL_QueryCommandBuffer
  132189. +**
  132190. +** Query command buffer attributes.
  132191. +**
  132192. +** INPUT:
  132193. +**
  132194. +** gckKERNEL Kernel
  132195. +** Pointer to an gckVGHARDWARE object.
  132196. +**
  132197. +** OUTPUT:
  132198. +**
  132199. +** gcsCOMMAND_BUFFER_INFO_PTR Information
  132200. +** Pointer to the information structure to receive buffer attributes.
  132201. +*/
  132202. +gceSTATUS
  132203. +gckKERNEL_QueryCommandBuffer(
  132204. + IN gckKERNEL Kernel,
  132205. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  132206. + )
  132207. +{
  132208. + gceSTATUS status;
  132209. +
  132210. + gcmkHEADER_ARG("Kernel=0x%x *Pool=0x%x",
  132211. + Kernel, Information);
  132212. + /* Verify the arguments. */
  132213. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  132214. +
  132215. + /* Get the information. */
  132216. + status = gckVGCOMMAND_QueryCommandBuffer(Kernel->vg->command, Information);
  132217. +
  132218. + gcmkFOOTER();
  132219. + /* Return status. */
  132220. + return status;
  132221. +}
  132222. +
  132223. +#endif /* gcdENABLE_VG */
  132224. diff -Nur linux-3.14.17/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
  132225. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h 1970-01-01 01:00:00.000000000 +0100
  132226. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h 2014-09-11 18:06:03.114042420 +0200
  132227. @@ -0,0 +1,85 @@
  132228. +/****************************************************************************
  132229. +*
  132230. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  132231. +*
  132232. +* This program is free software; you can redistribute it and/or modify
  132233. +* it under the terms of the GNU General Public License as published by
  132234. +* the Free Software Foundation; either version 2 of the license, or
  132235. +* (at your option) any later version.
  132236. +*
  132237. +* This program is distributed in the hope that it will be useful,
  132238. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  132239. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  132240. +* GNU General Public License for more details.
  132241. +*
  132242. +* You should have received a copy of the GNU General Public License
  132243. +* along with this program; if not write to the Free Software
  132244. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  132245. +*
  132246. +*****************************************************************************/
  132247. +
  132248. +
  132249. +#ifndef __gc_hal_kernel_vg_h_
  132250. +#define __gc_hal_kernel_vg_h_
  132251. +
  132252. +#include "gc_hal.h"
  132253. +#include "gc_hal_driver.h"
  132254. +#include "gc_hal_kernel_hardware.h"
  132255. +
  132256. +/******************************************************************************\
  132257. +********************************** Structures **********************************
  132258. +\******************************************************************************/
  132259. +
  132260. +/* gckKERNEL object. */
  132261. +struct _gckVGKERNEL
  132262. +{
  132263. + /* Object. */
  132264. + gcsOBJECT object;
  132265. +
  132266. + /* Pointer to gckOS object. */
  132267. + gckOS os;
  132268. +
  132269. + /* Pointer to gckHARDWARE object. */
  132270. + gckVGHARDWARE hardware;
  132271. +
  132272. + /* Pointer to gckINTERRUPT object. */
  132273. + gckVGINTERRUPT interrupt;
  132274. +
  132275. + /* Pointer to gckCOMMAND object. */
  132276. + gckVGCOMMAND command;
  132277. +
  132278. + /* Pointer to context. */
  132279. + gctPOINTER context;
  132280. +
  132281. + /* Pointer to gckMMU object. */
  132282. + gckVGMMU mmu;
  132283. +
  132284. + gckKERNEL kernel;
  132285. +};
  132286. +
  132287. +/* gckMMU object. */
  132288. +struct _gckVGMMU
  132289. +{
  132290. + /* The object. */
  132291. + gcsOBJECT object;
  132292. +
  132293. + /* Pointer to gckOS object. */
  132294. + gckOS os;
  132295. +
  132296. + /* Pointer to gckHARDWARE object. */
  132297. + gckVGHARDWARE hardware;
  132298. +
  132299. + /* The page table mutex. */
  132300. + gctPOINTER mutex;
  132301. +
  132302. + /* Page table information. */
  132303. + gctSIZE_T pageTableSize;
  132304. + gctPHYS_ADDR pageTablePhysical;
  132305. + gctPOINTER pageTableLogical;
  132306. +
  132307. + /* Allocation index. */
  132308. + gctUINT32 entryCount;
  132309. + gctUINT32 entry;
  132310. +};
  132311. +
  132312. +#endif /* __gc_hal_kernel_h_ */
  132313. diff -Nur linux-3.14.17/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
  132314. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c 1970-01-01 01:00:00.000000000 +0100
  132315. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c 2014-09-11 18:06:03.114042420 +0200
  132316. @@ -0,0 +1,2264 @@
  132317. +/****************************************************************************
  132318. +*
  132319. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  132320. +*
  132321. +* This program is free software; you can redistribute it and/or modify
  132322. +* it under the terms of the GNU General Public License as published by
  132323. +* the Free Software Foundation; either version 2 of the license, or
  132324. +* (at your option) any later version.
  132325. +*
  132326. +* This program is distributed in the hope that it will be useful,
  132327. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  132328. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  132329. +* GNU General Public License for more details.
  132330. +*
  132331. +* You should have received a copy of the GNU General Public License
  132332. +* along with this program; if not write to the Free Software
  132333. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  132334. +*
  132335. +*****************************************************************************/
  132336. +
  132337. +
  132338. +#include "gc_hal_kernel_precomp.h"
  132339. +
  132340. +#define _GC_OBJ_ZONE gcvZONE_VIDMEM
  132341. +
  132342. +/******************************************************************************\
  132343. +******************************* Private Functions ******************************
  132344. +\******************************************************************************/
  132345. +
  132346. +/*******************************************************************************
  132347. +**
  132348. +** _Split
  132349. +**
  132350. +** Split a node on the required byte boundary.
  132351. +**
  132352. +** INPUT:
  132353. +**
  132354. +** gckOS Os
  132355. +** Pointer to an gckOS object.
  132356. +**
  132357. +** gcuVIDMEM_NODE_PTR Node
  132358. +** Pointer to the node to split.
  132359. +**
  132360. +** gctSIZE_T Bytes
  132361. +** Number of bytes to keep in the node.
  132362. +**
  132363. +** OUTPUT:
  132364. +**
  132365. +** Nothing.
  132366. +**
  132367. +** RETURNS:
  132368. +**
  132369. +** gctBOOL
  132370. +** gcvTRUE if the node was split successfully, or gcvFALSE if there is an
  132371. +** error.
  132372. +**
  132373. +*/
  132374. +static gctBOOL
  132375. +_Split(
  132376. + IN gckOS Os,
  132377. + IN gcuVIDMEM_NODE_PTR Node,
  132378. + IN gctSIZE_T Bytes
  132379. + )
  132380. +{
  132381. + gcuVIDMEM_NODE_PTR node;
  132382. + gctPOINTER pointer = gcvNULL;
  132383. +
  132384. + /* Make sure the byte boundary makes sense. */
  132385. + if ((Bytes <= 0) || (Bytes > Node->VidMem.bytes))
  132386. + {
  132387. + return gcvFALSE;
  132388. + }
  132389. +
  132390. + /* Allocate a new gcuVIDMEM_NODE object. */
  132391. + if (gcmIS_ERROR(gckOS_Allocate(Os,
  132392. + gcmSIZEOF(gcuVIDMEM_NODE),
  132393. + &pointer)))
  132394. + {
  132395. + /* Error. */
  132396. + return gcvFALSE;
  132397. + }
  132398. +
  132399. + node = pointer;
  132400. +
  132401. + /* Initialize gcuVIDMEM_NODE structure. */
  132402. + node->VidMem.offset = Node->VidMem.offset + Bytes;
  132403. + node->VidMem.bytes = Node->VidMem.bytes - Bytes;
  132404. + node->VidMem.alignment = 0;
  132405. + node->VidMem.locked = 0;
  132406. + node->VidMem.memory = Node->VidMem.memory;
  132407. + node->VidMem.pool = Node->VidMem.pool;
  132408. + node->VidMem.physical = Node->VidMem.physical;
  132409. +#ifdef __QNXNTO__
  132410. +#if gcdUSE_VIDMEM_PER_PID
  132411. + gcmkASSERT(Node->VidMem.physical != 0);
  132412. + gcmkASSERT(Node->VidMem.logical != gcvNULL);
  132413. + node->VidMem.processID = Node->VidMem.processID;
  132414. + node->VidMem.physical = Node->VidMem.physical + Bytes;
  132415. + node->VidMem.logical = Node->VidMem.logical + Bytes;
  132416. +#else
  132417. + node->VidMem.processID = 0;
  132418. + node->VidMem.logical = gcvNULL;
  132419. +#endif
  132420. +#endif
  132421. +
  132422. + /* Insert node behind specified node. */
  132423. + node->VidMem.next = Node->VidMem.next;
  132424. + node->VidMem.prev = Node;
  132425. + Node->VidMem.next = node->VidMem.next->VidMem.prev = node;
  132426. +
  132427. + /* Insert free node behind specified node. */
  132428. + node->VidMem.nextFree = Node->VidMem.nextFree;
  132429. + node->VidMem.prevFree = Node;
  132430. + Node->VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
  132431. +
  132432. + /* Adjust size of specified node. */
  132433. + Node->VidMem.bytes = Bytes;
  132434. +
  132435. + /* Success. */
  132436. + return gcvTRUE;
  132437. +}
  132438. +
  132439. +/*******************************************************************************
  132440. +**
  132441. +** _Merge
  132442. +**
  132443. +** Merge two adjacent nodes together.
  132444. +**
  132445. +** INPUT:
  132446. +**
  132447. +** gckOS Os
  132448. +** Pointer to an gckOS object.
  132449. +**
  132450. +** gcuVIDMEM_NODE_PTR Node
  132451. +** Pointer to the first of the two nodes to merge.
  132452. +**
  132453. +** OUTPUT:
  132454. +**
  132455. +** Nothing.
  132456. +**
  132457. +*/
  132458. +static gceSTATUS
  132459. +_Merge(
  132460. + IN gckOS Os,
  132461. + IN gcuVIDMEM_NODE_PTR Node
  132462. + )
  132463. +{
  132464. + gcuVIDMEM_NODE_PTR node;
  132465. + gceSTATUS status;
  132466. +
  132467. + /* Save pointer to next node. */
  132468. + node = Node->VidMem.next;
  132469. +#if gcdUSE_VIDMEM_PER_PID
  132470. + /* Check if the nodes are adjacent physically. */
  132471. + if ( ((Node->VidMem.physical + Node->VidMem.bytes) != node->VidMem.physical) ||
  132472. + ((Node->VidMem.logical + Node->VidMem.bytes) != node->VidMem.logical) )
  132473. + {
  132474. + /* Can't merge. */
  132475. + return gcvSTATUS_OK;
  132476. + }
  132477. +#else
  132478. +
  132479. + /* This is a good time to make sure the heap is not corrupted. */
  132480. + if (Node->VidMem.offset + Node->VidMem.bytes != node->VidMem.offset)
  132481. + {
  132482. + /* Corrupted heap. */
  132483. + gcmkASSERT(
  132484. + Node->VidMem.offset + Node->VidMem.bytes == node->VidMem.offset);
  132485. + return gcvSTATUS_HEAP_CORRUPTED;
  132486. + }
  132487. +#endif
  132488. +
  132489. + /* Adjust byte count. */
  132490. + Node->VidMem.bytes += node->VidMem.bytes;
  132491. +
  132492. + /* Unlink next node from linked list. */
  132493. + Node->VidMem.next = node->VidMem.next;
  132494. + Node->VidMem.nextFree = node->VidMem.nextFree;
  132495. +
  132496. + Node->VidMem.next->VidMem.prev =
  132497. + Node->VidMem.nextFree->VidMem.prevFree = Node;
  132498. +
  132499. + /* Free next node. */
  132500. + status = gcmkOS_SAFE_FREE(Os, node);
  132501. + return status;
  132502. +}
  132503. +
  132504. +/******************************************************************************\
  132505. +******************************* gckVIDMEM API Code ******************************
  132506. +\******************************************************************************/
  132507. +
  132508. +/*******************************************************************************
  132509. +**
  132510. +** gckVIDMEM_ConstructVirtual
  132511. +**
  132512. +** Construct a new gcuVIDMEM_NODE union for virtual memory.
  132513. +**
  132514. +** INPUT:
  132515. +**
  132516. +** gckKERNEL Kernel
  132517. +** Pointer to an gckKERNEL object.
  132518. +**
  132519. +** gctSIZE_T Bytes
  132520. +** Number of byte to allocate.
  132521. +**
  132522. +** OUTPUT:
  132523. +**
  132524. +** gcuVIDMEM_NODE_PTR * Node
  132525. +** Pointer to a variable that receives the gcuVIDMEM_NODE union pointer.
  132526. +*/
  132527. +gceSTATUS
  132528. +gckVIDMEM_ConstructVirtual(
  132529. + IN gckKERNEL Kernel,
  132530. + IN gctBOOL Contiguous,
  132531. + IN gctSIZE_T Bytes,
  132532. + OUT gcuVIDMEM_NODE_PTR * Node
  132533. + )
  132534. +{
  132535. + gckOS os;
  132536. + gceSTATUS status;
  132537. + gcuVIDMEM_NODE_PTR node = gcvNULL;
  132538. + gctPOINTER pointer = gcvNULL;
  132539. + gctINT i;
  132540. +
  132541. + gcmkHEADER_ARG("Kernel=0x%x Contiguous=%d Bytes=%lu", Kernel, Contiguous, Bytes);
  132542. +
  132543. + /* Verify the arguments. */
  132544. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  132545. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  132546. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  132547. +
  132548. + /* Extract the gckOS object pointer. */
  132549. + os = Kernel->os;
  132550. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  132551. +
  132552. + /* Allocate an gcuVIDMEM_NODE union. */
  132553. + gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
  132554. +
  132555. + node = pointer;
  132556. +
  132557. + /* Initialize gcuVIDMEM_NODE union for virtual memory. */
  132558. + node->Virtual.kernel = Kernel;
  132559. + node->Virtual.contiguous = Contiguous;
  132560. + node->Virtual.logical = gcvNULL;
  132561. +
  132562. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  132563. + {
  132564. + node->Virtual.lockeds[i] = 0;
  132565. + node->Virtual.pageTables[i] = gcvNULL;
  132566. + node->Virtual.lockKernels[i] = gcvNULL;
  132567. + }
  132568. +
  132569. + node->Virtual.mutex = gcvNULL;
  132570. +
  132571. + gcmkONERROR(gckOS_GetProcessID(&node->Virtual.processID));
  132572. +
  132573. +#ifdef __QNXNTO__
  132574. + node->Virtual.next = gcvNULL;
  132575. + node->Virtual.freePending = gcvFALSE;
  132576. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  132577. + {
  132578. + node->Virtual.unlockPendings[i] = gcvFALSE;
  132579. + }
  132580. +#endif
  132581. +
  132582. + node->Virtual.freed = gcvFALSE;
  132583. +
  132584. + gcmkONERROR(gckOS_ZeroMemory(&node->Virtual.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
  132585. +
  132586. + /* Create the mutex. */
  132587. + gcmkONERROR(
  132588. + gckOS_CreateMutex(os, &node->Virtual.mutex));
  132589. +
  132590. + /* Allocate the virtual memory. */
  132591. + gcmkONERROR(
  132592. + gckOS_AllocatePagedMemoryEx(os,
  132593. + node->Virtual.contiguous,
  132594. + node->Virtual.bytes = Bytes,
  132595. + &node->Virtual.physical));
  132596. +
  132597. +#ifdef __QNXNTO__
  132598. + /* Register. */
  132599. +#if gcdENABLE_VG
  132600. + if (Kernel->core != gcvCORE_VG)
  132601. +#endif
  132602. + {
  132603. + gckMMU_InsertNode(Kernel->mmu, node);
  132604. + }
  132605. +#endif
  132606. +
  132607. + /* Return pointer to the gcuVIDMEM_NODE union. */
  132608. + *Node = node;
  132609. +
  132610. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132611. + "Created virtual node 0x%x for %u bytes @ 0x%x",
  132612. + node, Bytes, node->Virtual.physical);
  132613. +
  132614. + /* Success. */
  132615. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  132616. + return gcvSTATUS_OK;
  132617. +
  132618. +OnError:
  132619. + /* Roll back. */
  132620. + if (node != gcvNULL)
  132621. + {
  132622. + if (node->Virtual.mutex != gcvNULL)
  132623. + {
  132624. + /* Destroy the mutex. */
  132625. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->Virtual.mutex));
  132626. + }
  132627. +
  132628. + /* Free the structure. */
  132629. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
  132630. + }
  132631. +
  132632. + /* Return the status. */
  132633. + gcmkFOOTER();
  132634. + return status;
  132635. +}
  132636. +
  132637. +/*******************************************************************************
  132638. +**
  132639. +** gckVIDMEM_DestroyVirtual
  132640. +**
  132641. +** Destroy an gcuVIDMEM_NODE union for virtual memory.
  132642. +**
  132643. +** INPUT:
  132644. +**
  132645. +** gcuVIDMEM_NODE_PTR Node
  132646. +** Pointer to a gcuVIDMEM_NODE union.
  132647. +**
  132648. +** OUTPUT:
  132649. +**
  132650. +** Nothing.
  132651. +*/
  132652. +gceSTATUS
  132653. +gckVIDMEM_DestroyVirtual(
  132654. + IN gcuVIDMEM_NODE_PTR Node
  132655. + )
  132656. +{
  132657. + gckOS os;
  132658. + gctINT i;
  132659. +
  132660. + gcmkHEADER_ARG("Node=0x%x", Node);
  132661. +
  132662. + /* Verify the arguments. */
  132663. + gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
  132664. +
  132665. + /* Extact the gckOS object pointer. */
  132666. + os = Node->Virtual.kernel->os;
  132667. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  132668. +
  132669. +#ifdef __QNXNTO__
  132670. + /* Unregister. */
  132671. +#if gcdENABLE_VG
  132672. + if (Node->Virtual.kernel->core != gcvCORE_VG)
  132673. +#endif
  132674. + {
  132675. + gcmkVERIFY_OK(
  132676. + gckMMU_RemoveNode(Node->Virtual.kernel->mmu, Node));
  132677. + }
  132678. +#endif
  132679. +
  132680. + /* Delete the mutex. */
  132681. + gcmkVERIFY_OK(gckOS_DeleteMutex(os, Node->Virtual.mutex));
  132682. +
  132683. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  132684. + {
  132685. + if (Node->Virtual.pageTables[i] != gcvNULL)
  132686. + {
  132687. +#if gcdENABLE_VG
  132688. + if (i == gcvCORE_VG)
  132689. + {
  132690. + /* Free the pages. */
  132691. + gcmkVERIFY_OK(gckVGMMU_FreePages(Node->Virtual.lockKernels[i]->vg->mmu,
  132692. + Node->Virtual.pageTables[i],
  132693. + Node->Virtual.pageCount));
  132694. + }
  132695. + else
  132696. +#endif
  132697. + {
  132698. + /* Free the pages. */
  132699. + gcmkVERIFY_OK(gckMMU_FreePages(Node->Virtual.lockKernels[i]->mmu,
  132700. + Node->Virtual.pageTables[i],
  132701. + Node->Virtual.pageCount));
  132702. + }
  132703. + }
  132704. + }
  132705. +
  132706. + /* Delete the gcuVIDMEM_NODE union. */
  132707. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, Node));
  132708. +
  132709. + /* Success. */
  132710. + gcmkFOOTER_NO();
  132711. + return gcvSTATUS_OK;
  132712. +}
  132713. +
  132714. +/*******************************************************************************
  132715. +**
  132716. +** gckVIDMEM_Construct
  132717. +**
  132718. +** Construct a new gckVIDMEM object.
  132719. +**
  132720. +** INPUT:
  132721. +**
  132722. +** gckOS Os
  132723. +** Pointer to an gckOS object.
  132724. +**
  132725. +** gctUINT32 BaseAddress
  132726. +** Base address for the video memory heap.
  132727. +**
  132728. +** gctSIZE_T Bytes
  132729. +** Number of bytes in the video memory heap.
  132730. +**
  132731. +** gctSIZE_T Threshold
  132732. +** Minimum number of bytes beyond am allocation before the node is
  132733. +** split. Can be used as a minimum alignment requirement.
  132734. +**
  132735. +** gctSIZE_T BankSize
  132736. +** Number of bytes per physical memory bank. Used by bank
  132737. +** optimization.
  132738. +**
  132739. +** OUTPUT:
  132740. +**
  132741. +** gckVIDMEM * Memory
  132742. +** Pointer to a variable that will hold the pointer to the gckVIDMEM
  132743. +** object.
  132744. +*/
  132745. +gceSTATUS
  132746. +gckVIDMEM_Construct(
  132747. + IN gckOS Os,
  132748. + IN gctUINT32 BaseAddress,
  132749. + IN gctSIZE_T Bytes,
  132750. + IN gctSIZE_T Threshold,
  132751. + IN gctSIZE_T BankSize,
  132752. + OUT gckVIDMEM * Memory
  132753. + )
  132754. +{
  132755. + gckVIDMEM memory = gcvNULL;
  132756. + gceSTATUS status;
  132757. + gcuVIDMEM_NODE_PTR node;
  132758. + gctINT i, banks = 0;
  132759. + gctPOINTER pointer = gcvNULL;
  132760. +
  132761. + gcmkHEADER_ARG("Os=0x%x BaseAddress=%08x Bytes=%lu Threshold=%lu "
  132762. + "BankSize=%lu",
  132763. + Os, BaseAddress, Bytes, Threshold, BankSize);
  132764. +
  132765. + /* Verify the arguments. */
  132766. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  132767. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  132768. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  132769. +
  132770. + /* Allocate the gckVIDMEM object. */
  132771. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct _gckVIDMEM), &pointer));
  132772. +
  132773. + memory = pointer;
  132774. +
  132775. + /* Initialize the gckVIDMEM object. */
  132776. + memory->object.type = gcvOBJ_VIDMEM;
  132777. + memory->os = Os;
  132778. +
  132779. + /* Set video memory heap information. */
  132780. + memory->baseAddress = BaseAddress;
  132781. + memory->bytes = Bytes;
  132782. + memory->freeBytes = Bytes;
  132783. + memory->threshold = Threshold;
  132784. + memory->mutex = gcvNULL;
  132785. +#if gcdUSE_VIDMEM_PER_PID
  132786. + gcmkONERROR(gckOS_GetProcessID(&memory->pid));
  132787. +#endif
  132788. +
  132789. + BaseAddress = 0;
  132790. +
  132791. + /* Walk all possible banks. */
  132792. + for (i = 0; i < gcmCOUNTOF(memory->sentinel); ++i)
  132793. + {
  132794. + gctSIZE_T bytes;
  132795. +
  132796. + if (BankSize == 0)
  132797. + {
  132798. + /* Use all bytes for the first bank. */
  132799. + bytes = Bytes;
  132800. + }
  132801. + else
  132802. + {
  132803. + /* Compute number of bytes for this bank. */
  132804. + bytes = gcmALIGN(BaseAddress + 1, BankSize) - BaseAddress;
  132805. +
  132806. + if (bytes > Bytes)
  132807. + {
  132808. + /* Make sure we don't exceed the total number of bytes. */
  132809. + bytes = Bytes;
  132810. + }
  132811. + }
  132812. +
  132813. + if (bytes == 0)
  132814. + {
  132815. + /* Mark heap is not used. */
  132816. + memory->sentinel[i].VidMem.next =
  132817. + memory->sentinel[i].VidMem.prev =
  132818. + memory->sentinel[i].VidMem.nextFree =
  132819. + memory->sentinel[i].VidMem.prevFree = gcvNULL;
  132820. + continue;
  132821. + }
  132822. +
  132823. + /* Allocate one gcuVIDMEM_NODE union. */
  132824. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
  132825. +
  132826. + node = pointer;
  132827. +
  132828. + /* Initialize gcuVIDMEM_NODE union. */
  132829. + node->VidMem.memory = memory;
  132830. +
  132831. + node->VidMem.next =
  132832. + node->VidMem.prev =
  132833. + node->VidMem.nextFree =
  132834. + node->VidMem.prevFree = &memory->sentinel[i];
  132835. +
  132836. + node->VidMem.offset = BaseAddress;
  132837. + node->VidMem.bytes = bytes;
  132838. + node->VidMem.alignment = 0;
  132839. + node->VidMem.physical = 0;
  132840. + node->VidMem.pool = gcvPOOL_UNKNOWN;
  132841. +
  132842. + node->VidMem.locked = 0;
  132843. +
  132844. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  132845. + node->VidMem.kernelVirtual = gcvNULL;
  132846. +#endif
  132847. +
  132848. + gcmkONERROR(gckOS_ZeroMemory(&node->VidMem.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
  132849. +
  132850. +#ifdef __QNXNTO__
  132851. +#if gcdUSE_VIDMEM_PER_PID
  132852. + node->VidMem.processID = memory->pid;
  132853. + node->VidMem.physical = memory->baseAddress + BaseAddress;
  132854. + gcmkONERROR(gckOS_GetLogicalAddressProcess(Os,
  132855. + node->VidMem.processID,
  132856. + node->VidMem.physical,
  132857. + &node->VidMem.logical));
  132858. +#else
  132859. + node->VidMem.processID = 0;
  132860. + node->VidMem.logical = gcvNULL;
  132861. +#endif
  132862. +#endif
  132863. +
  132864. + /* Initialize the linked list of nodes. */
  132865. + memory->sentinel[i].VidMem.next =
  132866. + memory->sentinel[i].VidMem.prev =
  132867. + memory->sentinel[i].VidMem.nextFree =
  132868. + memory->sentinel[i].VidMem.prevFree = node;
  132869. +
  132870. + /* Mark sentinel. */
  132871. + memory->sentinel[i].VidMem.bytes = 0;
  132872. +
  132873. + /* Adjust address for next bank. */
  132874. + BaseAddress += bytes;
  132875. + Bytes -= bytes;
  132876. + banks ++;
  132877. + }
  132878. +
  132879. + /* Assign all the bank mappings. */
  132880. + memory->mapping[gcvSURF_RENDER_TARGET] = banks - 1;
  132881. + memory->mapping[gcvSURF_BITMAP] = banks - 1;
  132882. + if (banks > 1) --banks;
  132883. + memory->mapping[gcvSURF_DEPTH] = banks - 1;
  132884. + memory->mapping[gcvSURF_HIERARCHICAL_DEPTH] = banks - 1;
  132885. + if (banks > 1) --banks;
  132886. + memory->mapping[gcvSURF_TEXTURE] = banks - 1;
  132887. + if (banks > 1) --banks;
  132888. + memory->mapping[gcvSURF_VERTEX] = banks - 1;
  132889. + if (banks > 1) --banks;
  132890. + memory->mapping[gcvSURF_INDEX] = banks - 1;
  132891. + if (banks > 1) --banks;
  132892. + memory->mapping[gcvSURF_TILE_STATUS] = banks - 1;
  132893. + if (banks > 1) --banks;
  132894. + memory->mapping[gcvSURF_TYPE_UNKNOWN] = 0;
  132895. +
  132896. +#if gcdENABLE_VG
  132897. + memory->mapping[gcvSURF_IMAGE] = 0;
  132898. + memory->mapping[gcvSURF_MASK] = 0;
  132899. + memory->mapping[gcvSURF_SCISSOR] = 0;
  132900. +#endif
  132901. +
  132902. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132903. + "[GALCORE] INDEX: bank %d",
  132904. + memory->mapping[gcvSURF_INDEX]);
  132905. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132906. + "[GALCORE] VERTEX: bank %d",
  132907. + memory->mapping[gcvSURF_VERTEX]);
  132908. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132909. + "[GALCORE] TEXTURE: bank %d",
  132910. + memory->mapping[gcvSURF_TEXTURE]);
  132911. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132912. + "[GALCORE] RENDER_TARGET: bank %d",
  132913. + memory->mapping[gcvSURF_RENDER_TARGET]);
  132914. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132915. + "[GALCORE] DEPTH: bank %d",
  132916. + memory->mapping[gcvSURF_DEPTH]);
  132917. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  132918. + "[GALCORE] TILE_STATUS: bank %d",
  132919. + memory->mapping[gcvSURF_TILE_STATUS]);
  132920. +
  132921. + /* Allocate the mutex. */
  132922. + gcmkONERROR(gckOS_CreateMutex(Os, &memory->mutex));
  132923. +
  132924. + /* Return pointer to the gckVIDMEM object. */
  132925. + *Memory = memory;
  132926. +
  132927. + /* Success. */
  132928. + gcmkFOOTER_ARG("*Memory=0x%x", *Memory);
  132929. + return gcvSTATUS_OK;
  132930. +
  132931. +OnError:
  132932. + /* Roll back. */
  132933. + if (memory != gcvNULL)
  132934. + {
  132935. + if (memory->mutex != gcvNULL)
  132936. + {
  132937. + /* Delete the mutex. */
  132938. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, memory->mutex));
  132939. + }
  132940. +
  132941. + for (i = 0; i < banks; ++i)
  132942. + {
  132943. + /* Free the heap. */
  132944. + gcmkASSERT(memory->sentinel[i].VidMem.next != gcvNULL);
  132945. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory->sentinel[i].VidMem.next));
  132946. + }
  132947. +
  132948. + /* Free the object. */
  132949. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, memory));
  132950. + }
  132951. +
  132952. + /* Return the status. */
  132953. + gcmkFOOTER();
  132954. + return status;
  132955. +}
  132956. +
  132957. +/*******************************************************************************
  132958. +**
  132959. +** gckVIDMEM_Destroy
  132960. +**
  132961. +** Destroy an gckVIDMEM object.
  132962. +**
  132963. +** INPUT:
  132964. +**
  132965. +** gckVIDMEM Memory
  132966. +** Pointer to an gckVIDMEM object to destroy.
  132967. +**
  132968. +** OUTPUT:
  132969. +**
  132970. +** Nothing.
  132971. +*/
  132972. +gceSTATUS
  132973. +gckVIDMEM_Destroy(
  132974. + IN gckVIDMEM Memory
  132975. + )
  132976. +{
  132977. + gcuVIDMEM_NODE_PTR node, next;
  132978. + gctINT i;
  132979. +
  132980. + gcmkHEADER_ARG("Memory=0x%x", Memory);
  132981. +
  132982. + /* Verify the arguments. */
  132983. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  132984. +
  132985. + /* Walk all sentinels. */
  132986. + for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
  132987. + {
  132988. + /* Bail out of the heap is not used. */
  132989. + if (Memory->sentinel[i].VidMem.next == gcvNULL)
  132990. + {
  132991. + break;
  132992. + }
  132993. +
  132994. + /* Walk all the nodes until we reach the sentinel. */
  132995. + for (node = Memory->sentinel[i].VidMem.next;
  132996. + node->VidMem.bytes != 0;
  132997. + node = next)
  132998. + {
  132999. + /* Save pointer to the next node. */
  133000. + next = node->VidMem.next;
  133001. +
  133002. + /* Free the node. */
  133003. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, node));
  133004. + }
  133005. + }
  133006. +
  133007. + /* Free the mutex. */
  133008. + gcmkVERIFY_OK(gckOS_DeleteMutex(Memory->os, Memory->mutex));
  133009. +
  133010. + /* Mark the object as unknown. */
  133011. + Memory->object.type = gcvOBJ_UNKNOWN;
  133012. +
  133013. + /* Free the gckVIDMEM object. */
  133014. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Memory->os, Memory));
  133015. +
  133016. + /* Success. */
  133017. + gcmkFOOTER_NO();
  133018. + return gcvSTATUS_OK;
  133019. +}
  133020. +
  133021. +/*******************************************************************************
  133022. +**
  133023. +** gckVIDMEM_Allocate
  133024. +**
  133025. +** Allocate rectangular memory from the gckVIDMEM object.
  133026. +**
  133027. +** INPUT:
  133028. +**
  133029. +** gckVIDMEM Memory
  133030. +** Pointer to an gckVIDMEM object.
  133031. +**
  133032. +** gctUINT Width
  133033. +** Width of rectangle to allocate. Make sure the width is properly
  133034. +** aligned.
  133035. +**
  133036. +** gctUINT Height
  133037. +** Height of rectangle to allocate. Make sure the height is properly
  133038. +** aligned.
  133039. +**
  133040. +** gctUINT Depth
  133041. +** Depth of rectangle to allocate. This equals to the number of
  133042. +** rectangles to allocate contiguously (i.e., for cubic maps and volume
  133043. +** textures).
  133044. +**
  133045. +** gctUINT BytesPerPixel
  133046. +** Number of bytes per pixel.
  133047. +**
  133048. +** gctUINT32 Alignment
  133049. +** Byte alignment for allocation.
  133050. +**
  133051. +** gceSURF_TYPE Type
  133052. +** Type of surface to allocate (use by bank optimization).
  133053. +**
  133054. +** OUTPUT:
  133055. +**
  133056. +** gcuVIDMEM_NODE_PTR * Node
  133057. +** Pointer to a variable that will hold the allocated memory node.
  133058. +*/
  133059. +gceSTATUS
  133060. +gckVIDMEM_Allocate(
  133061. + IN gckVIDMEM Memory,
  133062. + IN gctUINT Width,
  133063. + IN gctUINT Height,
  133064. + IN gctUINT Depth,
  133065. + IN gctUINT BytesPerPixel,
  133066. + IN gctUINT32 Alignment,
  133067. + IN gceSURF_TYPE Type,
  133068. + OUT gcuVIDMEM_NODE_PTR * Node
  133069. + )
  133070. +{
  133071. + gctSIZE_T bytes;
  133072. + gceSTATUS status;
  133073. +
  133074. + gcmkHEADER_ARG("Memory=0x%x Width=%u Height=%u Depth=%u BytesPerPixel=%u "
  133075. + "Alignment=%u Type=%d",
  133076. + Memory, Width, Height, Depth, BytesPerPixel, Alignment,
  133077. + Type);
  133078. +
  133079. + /* Verify the arguments. */
  133080. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  133081. + gcmkVERIFY_ARGUMENT(Width > 0);
  133082. + gcmkVERIFY_ARGUMENT(Height > 0);
  133083. + gcmkVERIFY_ARGUMENT(Depth > 0);
  133084. + gcmkVERIFY_ARGUMENT(BytesPerPixel > 0);
  133085. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  133086. +
  133087. + /* Compute linear size. */
  133088. + bytes = Width * Height * Depth * BytesPerPixel;
  133089. +
  133090. + /* Allocate through linear function. */
  133091. + gcmkONERROR(
  133092. + gckVIDMEM_AllocateLinear(Memory, bytes, Alignment, Type, Node));
  133093. +
  133094. + /* Success. */
  133095. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  133096. + return gcvSTATUS_OK;
  133097. +
  133098. +OnError:
  133099. + /* Return the status. */
  133100. + gcmkFOOTER();
  133101. + return status;
  133102. +}
  133103. +
  133104. +#if gcdENABLE_BANK_ALIGNMENT
  133105. +
  133106. +#if !gcdBANK_BIT_START
  133107. +#error gcdBANK_BIT_START not defined.
  133108. +#endif
  133109. +
  133110. +#if !gcdBANK_BIT_END
  133111. +#error gcdBANK_BIT_END not defined.
  133112. +#endif
  133113. +/*******************************************************************************
  133114. +** _GetSurfaceBankAlignment
  133115. +**
  133116. +** Return the required offset alignment required to the make BaseAddress
  133117. +** aligned properly.
  133118. +**
  133119. +** INPUT:
  133120. +**
  133121. +** gckOS Os
  133122. +** Pointer to gcoOS object.
  133123. +**
  133124. +** gceSURF_TYPE Type
  133125. +** Type of allocation.
  133126. +**
  133127. +** gctUINT32 BaseAddress
  133128. +** Base address of current video memory node.
  133129. +**
  133130. +** OUTPUT:
  133131. +**
  133132. +** gctUINT32_PTR AlignmentOffset
  133133. +** Pointer to a variable that will hold the number of bytes to skip in
  133134. +** the current video memory node in order to make the alignment bank
  133135. +** aligned.
  133136. +*/
  133137. +static gceSTATUS
  133138. +_GetSurfaceBankAlignment(
  133139. + IN gceSURF_TYPE Type,
  133140. + IN gctUINT32 BaseAddress,
  133141. + OUT gctUINT32_PTR AlignmentOffset
  133142. + )
  133143. +{
  133144. + gctUINT32 bank;
  133145. + /* To retrieve the bank. */
  133146. + static const gctUINT32 bankMask = (0xFFFFFFFF << gcdBANK_BIT_START)
  133147. + ^ (0xFFFFFFFF << (gcdBANK_BIT_END + 1));
  133148. +
  133149. + /* To retrieve the bank and all the lower bytes. */
  133150. + static const gctUINT32 byteMask = ~(0xFFFFFFFF << (gcdBANK_BIT_END + 1));
  133151. +
  133152. + gcmkHEADER_ARG("Type=%d BaseAddress=0x%x ", Type, BaseAddress);
  133153. +
  133154. + /* Verify the arguments. */
  133155. + gcmkVERIFY_ARGUMENT(AlignmentOffset != gcvNULL);
  133156. +
  133157. + switch (Type)
  133158. + {
  133159. + case gcvSURF_RENDER_TARGET:
  133160. + bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
  133161. +
  133162. + /* Align to the first bank. */
  133163. + *AlignmentOffset = (bank == 0) ?
  133164. + 0 :
  133165. + ((1 << (gcdBANK_BIT_END + 1)) + 0) - (BaseAddress & byteMask);
  133166. + break;
  133167. +
  133168. + case gcvSURF_DEPTH:
  133169. + bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
  133170. +
  133171. + /* Align to the third bank. */
  133172. + *AlignmentOffset = (bank == 2) ?
  133173. + 0 :
  133174. + ((1 << (gcdBANK_BIT_END + 1)) + (2 << gcdBANK_BIT_START)) - (BaseAddress & byteMask);
  133175. +
  133176. + /* Add a channel offset at the channel bit. */
  133177. + *AlignmentOffset += (1 << gcdBANK_CHANNEL_BIT);
  133178. + break;
  133179. +
  133180. + default:
  133181. + /* no alignment needed. */
  133182. + *AlignmentOffset = 0;
  133183. + }
  133184. +
  133185. + /* Return the status. */
  133186. + gcmkFOOTER_ARG("*AlignmentOffset=%u", *AlignmentOffset);
  133187. + return gcvSTATUS_OK;
  133188. +}
  133189. +#endif
  133190. +
  133191. +static gcuVIDMEM_NODE_PTR
  133192. +_FindNode(
  133193. + IN gckVIDMEM Memory,
  133194. + IN gctINT Bank,
  133195. + IN gctSIZE_T Bytes,
  133196. + IN gceSURF_TYPE Type,
  133197. + IN OUT gctUINT32_PTR Alignment
  133198. + )
  133199. +{
  133200. + gcuVIDMEM_NODE_PTR node;
  133201. + gctUINT32 alignment;
  133202. +
  133203. +#if gcdENABLE_BANK_ALIGNMENT
  133204. + gctUINT32 bankAlignment;
  133205. + gceSTATUS status;
  133206. +#endif
  133207. +
  133208. + if (Memory->sentinel[Bank].VidMem.nextFree == gcvNULL)
  133209. + {
  133210. + /* No free nodes left. */
  133211. + return gcvNULL;
  133212. + }
  133213. +
  133214. +#if gcdENABLE_BANK_ALIGNMENT
  133215. + /* Walk all free nodes until we have one that is big enough or we have
  133216. + ** reached the sentinel. */
  133217. + for (node = Memory->sentinel[Bank].VidMem.nextFree;
  133218. + node->VidMem.bytes != 0;
  133219. + node = node->VidMem.nextFree)
  133220. + {
  133221. + gcmkONERROR(_GetSurfaceBankAlignment(
  133222. + Type,
  133223. + node->VidMem.memory->baseAddress + node->VidMem.offset,
  133224. + &bankAlignment));
  133225. +
  133226. + bankAlignment = gcmALIGN(bankAlignment, *Alignment);
  133227. +
  133228. + /* Compute number of bytes to skip for alignment. */
  133229. + alignment = (*Alignment == 0)
  133230. + ? 0
  133231. + : (*Alignment - (node->VidMem.offset % *Alignment));
  133232. +
  133233. + if (alignment == *Alignment)
  133234. + {
  133235. + /* Node is already aligned. */
  133236. + alignment = 0;
  133237. + }
  133238. +
  133239. + if (node->VidMem.bytes >= Bytes + alignment + bankAlignment)
  133240. + {
  133241. + /* This node is big enough. */
  133242. + *Alignment = alignment + bankAlignment;
  133243. + return node;
  133244. + }
  133245. + }
  133246. +#endif
  133247. +
  133248. + /* Walk all free nodes until we have one that is big enough or we have
  133249. + reached the sentinel. */
  133250. + for (node = Memory->sentinel[Bank].VidMem.nextFree;
  133251. + node->VidMem.bytes != 0;
  133252. + node = node->VidMem.nextFree)
  133253. + {
  133254. +
  133255. + gctINT modulo = gckMATH_ModuloInt(node->VidMem.offset, *Alignment);
  133256. +
  133257. + /* Compute number of bytes to skip for alignment. */
  133258. + alignment = (*Alignment == 0) ? 0 : (*Alignment - modulo);
  133259. +
  133260. + if (alignment == *Alignment)
  133261. + {
  133262. + /* Node is already aligned. */
  133263. + alignment = 0;
  133264. + }
  133265. +
  133266. + if (node->VidMem.bytes >= Bytes + alignment)
  133267. + {
  133268. + /* This node is big enough. */
  133269. + *Alignment = alignment;
  133270. + return node;
  133271. + }
  133272. + }
  133273. +
  133274. +#if gcdENABLE_BANK_ALIGNMENT
  133275. +OnError:
  133276. +#endif
  133277. + /* Not enough memory. */
  133278. + return gcvNULL;
  133279. +}
  133280. +
  133281. +/*******************************************************************************
  133282. +**
  133283. +** gckVIDMEM_AllocateLinear
  133284. +**
  133285. +** Allocate linear memory from the gckVIDMEM object.
  133286. +**
  133287. +** INPUT:
  133288. +**
  133289. +** gckVIDMEM Memory
  133290. +** Pointer to an gckVIDMEM object.
  133291. +**
  133292. +** gctSIZE_T Bytes
  133293. +** Number of bytes to allocate.
  133294. +**
  133295. +** gctUINT32 Alignment
  133296. +** Byte alignment for allocation.
  133297. +**
  133298. +** gceSURF_TYPE Type
  133299. +** Type of surface to allocate (use by bank optimization).
  133300. +**
  133301. +** OUTPUT:
  133302. +**
  133303. +** gcuVIDMEM_NODE_PTR * Node
  133304. +** Pointer to a variable that will hold the allocated memory node.
  133305. +*/
  133306. +gceSTATUS
  133307. +gckVIDMEM_AllocateLinear(
  133308. + IN gckVIDMEM Memory,
  133309. + IN gctSIZE_T Bytes,
  133310. + IN gctUINT32 Alignment,
  133311. + IN gceSURF_TYPE Type,
  133312. + OUT gcuVIDMEM_NODE_PTR * Node
  133313. + )
  133314. +{
  133315. + gceSTATUS status;
  133316. + gcuVIDMEM_NODE_PTR node;
  133317. + gctUINT32 alignment;
  133318. + gctINT bank, i;
  133319. + gctBOOL acquired = gcvFALSE;
  133320. +#if gcdSMALL_BLOCK_SIZE
  133321. + gctBOOL force_allocate = (Type == gcvSURF_TILE_STATUS) || (Type & gcvSURF_VG);
  133322. +#endif
  133323. +
  133324. + gcmkHEADER_ARG("Memory=0x%x Bytes=%lu Alignment=%u Type=%d",
  133325. + Memory, Bytes, Alignment, Type);
  133326. +
  133327. + Type &= ~gcvSURF_VG;
  133328. + /* Verify the arguments. */
  133329. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  133330. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  133331. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  133332. + gcmkVERIFY_ARGUMENT(Type < gcvSURF_NUM_TYPES);
  133333. +
  133334. + /* Acquire the mutex. */
  133335. + gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
  133336. +
  133337. + acquired = gcvTRUE;
  133338. +#if !gcdUSE_VIDMEM_PER_PID
  133339. +
  133340. + if (Bytes > Memory->freeBytes)
  133341. + {
  133342. + /* Not enough memory. */
  133343. + status = gcvSTATUS_OUT_OF_MEMORY;
  133344. + goto OnError;
  133345. + }
  133346. +#endif
  133347. +
  133348. +#if gcdSMALL_BLOCK_SIZE
  133349. + if ((!force_allocate) && (Memory->freeBytes < (Memory->bytes/gcdRATIO_FOR_SMALL_MEMORY))
  133350. + && (Bytes >= gcdSMALL_BLOCK_SIZE)
  133351. + )
  133352. + {
  133353. + /* The left memory is for small memory.*/
  133354. + status = gcvSTATUS_OUT_OF_MEMORY;
  133355. + goto OnError;
  133356. + }
  133357. +#endif
  133358. +
  133359. + /* Find the default bank for this surface type. */
  133360. + gcmkASSERT((gctINT) Type < gcmCOUNTOF(Memory->mapping));
  133361. + bank = Memory->mapping[Type];
  133362. + alignment = Alignment;
  133363. +
  133364. +#if gcdUSE_VIDMEM_PER_PID
  133365. + if (Bytes <= Memory->freeBytes)
  133366. + {
  133367. +#endif
  133368. + /* Find a free node in the default bank. */
  133369. + node = _FindNode(Memory, bank, Bytes, Type, &alignment);
  133370. +
  133371. + /* Out of memory? */
  133372. + if (node == gcvNULL)
  133373. + {
  133374. + /* Walk all lower banks. */
  133375. + for (i = bank - 1; i >= 0; --i)
  133376. + {
  133377. + /* Find a free node inside the current bank. */
  133378. + node = _FindNode(Memory, i, Bytes, Type, &alignment);
  133379. + if (node != gcvNULL)
  133380. + {
  133381. + break;
  133382. + }
  133383. + }
  133384. + }
  133385. +
  133386. + if (node == gcvNULL)
  133387. + {
  133388. + /* Walk all upper banks. */
  133389. + for (i = bank + 1; i < gcmCOUNTOF(Memory->sentinel); ++i)
  133390. + {
  133391. + if (Memory->sentinel[i].VidMem.nextFree == gcvNULL)
  133392. + {
  133393. + /* Abort when we reach unused banks. */
  133394. + break;
  133395. + }
  133396. +
  133397. + /* Find a free node inside the current bank. */
  133398. + node = _FindNode(Memory, i, Bytes, Type, &alignment);
  133399. + if (node != gcvNULL)
  133400. + {
  133401. + break;
  133402. + }
  133403. + }
  133404. + }
  133405. +#if gcdUSE_VIDMEM_PER_PID
  133406. + }
  133407. +#endif
  133408. +
  133409. + if (node == gcvNULL)
  133410. + {
  133411. + /* Out of memory. */
  133412. +#if gcdUSE_VIDMEM_PER_PID
  133413. + /* Allocate more memory from shared pool. */
  133414. + gctSIZE_T bytes;
  133415. + gctPHYS_ADDR physical_temp;
  133416. + gctUINT32 physical;
  133417. + gctPOINTER logical;
  133418. +
  133419. + bytes = gcmALIGN(Bytes, gcdUSE_VIDMEM_PER_PID_SIZE);
  133420. +
  133421. + gcmkONERROR(gckOS_AllocateContiguous(Memory->os,
  133422. + gcvTRUE,
  133423. + &bytes,
  133424. + &physical_temp,
  133425. + &logical));
  133426. +
  133427. + /* physical address is returned as 0 for user space. workaround. */
  133428. + if (physical_temp == gcvNULL)
  133429. + {
  133430. + gcmkONERROR(gckOS_GetPhysicalAddress(Memory->os, logical, &physical));
  133431. + }
  133432. +
  133433. + /* Allocate one gcuVIDMEM_NODE union. */
  133434. + gcmkONERROR(
  133435. + gckOS_Allocate(Memory->os,
  133436. + gcmSIZEOF(gcuVIDMEM_NODE),
  133437. + (gctPOINTER *) &node));
  133438. +
  133439. + /* Initialize gcuVIDMEM_NODE union. */
  133440. + node->VidMem.memory = Memory;
  133441. +
  133442. + node->VidMem.offset = 0;
  133443. + node->VidMem.bytes = bytes;
  133444. + node->VidMem.alignment = 0;
  133445. + node->VidMem.physical = physical;
  133446. + node->VidMem.pool = gcvPOOL_UNKNOWN;
  133447. +
  133448. + node->VidMem.locked = 0;
  133449. +
  133450. +#ifdef __QNXNTO__
  133451. + gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
  133452. + node->VidMem.logical = logical;
  133453. + gcmkASSERT(logical != gcvNULL);
  133454. +#endif
  133455. +
  133456. + /* Insert node behind sentinel node. */
  133457. + node->VidMem.next = Memory->sentinel[bank].VidMem.next;
  133458. + node->VidMem.prev = &Memory->sentinel[bank];
  133459. + Memory->sentinel[bank].VidMem.next = node->VidMem.next->VidMem.prev = node;
  133460. +
  133461. + /* Insert free node behind sentinel node. */
  133462. + node->VidMem.nextFree = Memory->sentinel[bank].VidMem.nextFree;
  133463. + node->VidMem.prevFree = &Memory->sentinel[bank];
  133464. + Memory->sentinel[bank].VidMem.nextFree = node->VidMem.nextFree->VidMem.prevFree = node;
  133465. +
  133466. + Memory->freeBytes += bytes;
  133467. +#else
  133468. + status = gcvSTATUS_OUT_OF_MEMORY;
  133469. + goto OnError;
  133470. +#endif
  133471. + }
  133472. +
  133473. + /* Do we have an alignment? */
  133474. + if (alignment > 0)
  133475. + {
  133476. + /* Split the node so it is aligned. */
  133477. + if (_Split(Memory->os, node, alignment))
  133478. + {
  133479. + /* Successful split, move to aligned node. */
  133480. + node = node->VidMem.next;
  133481. +
  133482. + /* Remove alignment. */
  133483. + alignment = 0;
  133484. + }
  133485. + }
  133486. +
  133487. + /* Do we have enough memory after the allocation to split it? */
  133488. + if (node->VidMem.bytes - Bytes > Memory->threshold)
  133489. + {
  133490. + /* Adjust the node size. */
  133491. + _Split(Memory->os, node, Bytes);
  133492. + }
  133493. +
  133494. + /* Remove the node from the free list. */
  133495. + node->VidMem.prevFree->VidMem.nextFree = node->VidMem.nextFree;
  133496. + node->VidMem.nextFree->VidMem.prevFree = node->VidMem.prevFree;
  133497. + node->VidMem.nextFree =
  133498. + node->VidMem.prevFree = gcvNULL;
  133499. +
  133500. + /* Fill in the information. */
  133501. + node->VidMem.alignment = alignment;
  133502. + node->VidMem.memory = Memory;
  133503. +#ifdef __QNXNTO__
  133504. +#if !gcdUSE_VIDMEM_PER_PID
  133505. + node->VidMem.logical = gcvNULL;
  133506. + gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
  133507. +#else
  133508. + gcmkASSERT(node->VidMem.logical != gcvNULL);
  133509. +#endif
  133510. +#endif
  133511. +
  133512. + /* Adjust the number of free bytes. */
  133513. + Memory->freeBytes -= node->VidMem.bytes;
  133514. +
  133515. + node->VidMem.freePending = gcvFALSE;
  133516. +
  133517. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  133518. + node->VidMem.kernelVirtual = gcvNULL;
  133519. +#endif
  133520. +
  133521. + /* Release the mutex. */
  133522. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  133523. +
  133524. + /* Return the pointer to the node. */
  133525. + *Node = node;
  133526. +
  133527. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  133528. + "Allocated %u bytes @ 0x%x [0x%08X]",
  133529. + node->VidMem.bytes, node, node->VidMem.offset);
  133530. +
  133531. + /* Success. */
  133532. + gcmkFOOTER_ARG("*Node=0x%x", *Node);
  133533. + return gcvSTATUS_OK;
  133534. +
  133535. +OnError:
  133536. + if (acquired)
  133537. + {
  133538. + /* Release the mutex. */
  133539. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  133540. + }
  133541. +
  133542. + /* Return the status. */
  133543. + gcmkFOOTER();
  133544. + return status;
  133545. +}
  133546. +
  133547. +/*******************************************************************************
  133548. +**
  133549. +** gckVIDMEM_Free
  133550. +**
  133551. +** Free an allocated video memory node.
  133552. +**
  133553. +** INPUT:
  133554. +**
  133555. +** gcuVIDMEM_NODE_PTR Node
  133556. +** Pointer to a gcuVIDMEM_NODE object.
  133557. +**
  133558. +** OUTPUT:
  133559. +**
  133560. +** Nothing.
  133561. +*/
  133562. +gceSTATUS
  133563. +gckVIDMEM_Free(
  133564. + IN gcuVIDMEM_NODE_PTR Node
  133565. + )
  133566. +{
  133567. + gceSTATUS status;
  133568. + gckKERNEL kernel = gcvNULL;
  133569. + gckVIDMEM memory = gcvNULL;
  133570. + gcuVIDMEM_NODE_PTR node;
  133571. + gctBOOL mutexAcquired = gcvFALSE;
  133572. + gckOS os = gcvNULL;
  133573. + gctBOOL acquired = gcvFALSE;
  133574. + gctINT32 i, totalLocked;
  133575. +
  133576. + gcmkHEADER_ARG("Node=0x%x", Node);
  133577. +
  133578. + /* Verify the arguments. */
  133579. + if ((Node == gcvNULL)
  133580. + || (Node->VidMem.memory == gcvNULL)
  133581. + )
  133582. + {
  133583. + /* Invalid object. */
  133584. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  133585. + }
  133586. +
  133587. + /**************************** Video Memory ********************************/
  133588. +
  133589. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  133590. + {
  133591. + if (Node->VidMem.locked > 0)
  133592. + {
  133593. + /* Client still has a lock, defer free op 'till when lock reaches 0. */
  133594. + Node->VidMem.freePending = gcvTRUE;
  133595. +
  133596. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  133597. + "Node 0x%x is locked (%d)... deferring free.",
  133598. + Node, Node->VidMem.locked);
  133599. +
  133600. + gcmkFOOTER_NO();
  133601. + return gcvSTATUS_OK;
  133602. + }
  133603. +
  133604. + /* Extract pointer to gckVIDMEM object owning the node. */
  133605. + memory = Node->VidMem.memory;
  133606. +
  133607. + /* Acquire the mutex. */
  133608. + gcmkONERROR(
  133609. + gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
  133610. +
  133611. + mutexAcquired = gcvTRUE;
  133612. +
  133613. +#ifdef __QNXNTO__
  133614. +#if !gcdUSE_VIDMEM_PER_PID
  133615. + /* Reset. */
  133616. + Node->VidMem.processID = 0;
  133617. + Node->VidMem.logical = gcvNULL;
  133618. +#endif
  133619. +
  133620. + /* Don't try to re-free an already freed node. */
  133621. + if ((Node->VidMem.nextFree == gcvNULL)
  133622. + && (Node->VidMem.prevFree == gcvNULL)
  133623. + )
  133624. +#endif
  133625. + {
  133626. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  133627. + if (Node->VidMem.kernelVirtual)
  133628. + {
  133629. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  133630. + "%s(%d) Unmap %x from kernel space.",
  133631. + __FUNCTION__, __LINE__,
  133632. + Node->VidMem.kernelVirtual);
  133633. +
  133634. + gcmkVERIFY_OK(
  133635. + gckOS_UnmapPhysical(memory->os,
  133636. + Node->VidMem.kernelVirtual,
  133637. + Node->VidMem.bytes));
  133638. +
  133639. + Node->VidMem.kernelVirtual = gcvNULL;
  133640. + }
  133641. +#endif
  133642. +
  133643. + /* Check if Node is already freed. */
  133644. + if (Node->VidMem.nextFree)
  133645. + {
  133646. + /* Node is alread freed. */
  133647. + gcmkONERROR(gcvSTATUS_INVALID_DATA);
  133648. + }
  133649. +
  133650. + /* Update the number of free bytes. */
  133651. + memory->freeBytes += Node->VidMem.bytes;
  133652. +
  133653. + /* Find the next free node. */
  133654. + for (node = Node->VidMem.next;
  133655. + node != gcvNULL && node->VidMem.nextFree == gcvNULL;
  133656. + node = node->VidMem.next) ;
  133657. +
  133658. + /* Insert this node in the free list. */
  133659. + Node->VidMem.nextFree = node;
  133660. + Node->VidMem.prevFree = node->VidMem.prevFree;
  133661. +
  133662. + Node->VidMem.prevFree->VidMem.nextFree =
  133663. + node->VidMem.prevFree = Node;
  133664. +
  133665. + /* Is the next node a free node and not the sentinel? */
  133666. + if ((Node->VidMem.next == Node->VidMem.nextFree)
  133667. + && (Node->VidMem.next->VidMem.bytes != 0)
  133668. + )
  133669. + {
  133670. + /* Merge this node with the next node. */
  133671. + gcmkONERROR(_Merge(memory->os, node = Node));
  133672. + gcmkASSERT(node->VidMem.nextFree != node);
  133673. + gcmkASSERT(node->VidMem.prevFree != node);
  133674. + }
  133675. +
  133676. + /* Is the previous node a free node and not the sentinel? */
  133677. + if ((Node->VidMem.prev == Node->VidMem.prevFree)
  133678. + && (Node->VidMem.prev->VidMem.bytes != 0)
  133679. + )
  133680. + {
  133681. + /* Merge this node with the previous node. */
  133682. + gcmkONERROR(_Merge(memory->os, node = Node->VidMem.prev));
  133683. + gcmkASSERT(node->VidMem.nextFree != node);
  133684. + gcmkASSERT(node->VidMem.prevFree != node);
  133685. + }
  133686. + }
  133687. +
  133688. + /* Release the mutex. */
  133689. + gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
  133690. +
  133691. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  133692. + "Node 0x%x is freed.",
  133693. + Node);
  133694. +
  133695. + /* Success. */
  133696. + gcmkFOOTER_NO();
  133697. + return gcvSTATUS_OK;
  133698. + }
  133699. +
  133700. + /*************************** Virtual Memory *******************************/
  133701. +
  133702. + /* Get gckKERNEL object. */
  133703. + kernel = Node->Virtual.kernel;
  133704. +
  133705. + /* Verify the gckKERNEL object pointer. */
  133706. + gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL);
  133707. +
  133708. + /* Get the gckOS object pointer. */
  133709. + os = kernel->os;
  133710. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  133711. +
  133712. + /* Grab the mutex. */
  133713. + gcmkONERROR(
  133714. + gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  133715. +
  133716. + acquired = gcvTRUE;
  133717. +
  133718. + for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
  133719. + {
  133720. + totalLocked += Node->Virtual.lockeds[i];
  133721. + }
  133722. +
  133723. + if (totalLocked > 0)
  133724. + {
  133725. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_VIDMEM,
  133726. + "gckVIDMEM_Free: Virtual node 0x%x is locked (%d)",
  133727. + Node, totalLocked);
  133728. +
  133729. + /* Set Flag */
  133730. + Node->Virtual.freed = gcvTRUE;
  133731. +
  133732. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  133733. + }
  133734. + else
  133735. + {
  133736. + /* Free the virtual memory. */
  133737. + gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
  133738. + Node->Virtual.physical,
  133739. + Node->Virtual.bytes));
  133740. +
  133741. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  133742. +
  133743. + /* Destroy the gcuVIDMEM_NODE union. */
  133744. + gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
  133745. + }
  133746. +
  133747. + /* Success. */
  133748. + gcmkFOOTER_NO();
  133749. + return gcvSTATUS_OK;
  133750. +
  133751. +OnError:
  133752. + if (mutexAcquired)
  133753. + {
  133754. + /* Release the mutex. */
  133755. + gcmkVERIFY_OK(gckOS_ReleaseMutex(
  133756. + memory->os, memory->mutex
  133757. + ));
  133758. + }
  133759. +
  133760. + if (acquired)
  133761. + {
  133762. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  133763. + }
  133764. +
  133765. + /* Return the status. */
  133766. + gcmkFOOTER();
  133767. + return status;
  133768. +}
  133769. +
  133770. +
  133771. +#ifdef __QNXNTO__
  133772. +/*******************************************************************************
  133773. +**
  133774. +** gcoVIDMEM_FreeHandleMemory
  133775. +**
  133776. +** Free all allocated video memory nodes for a handle.
  133777. +**
  133778. +** INPUT:
  133779. +**
  133780. +** gcoVIDMEM Memory
  133781. +** Pointer to an gcoVIDMEM object..
  133782. +**
  133783. +** OUTPUT:
  133784. +**
  133785. +** Nothing.
  133786. +*/
  133787. +gceSTATUS
  133788. +gckVIDMEM_FreeHandleMemory(
  133789. + IN gckKERNEL Kernel,
  133790. + IN gckVIDMEM Memory,
  133791. + IN gctUINT32 Pid
  133792. + )
  133793. +{
  133794. + gceSTATUS status;
  133795. + gctBOOL mutex = gcvFALSE;
  133796. + gcuVIDMEM_NODE_PTR node;
  133797. + gctINT i;
  133798. + gctUINT32 nodeCount = 0, byteCount = 0;
  133799. + gctBOOL again;
  133800. +
  133801. + gcmkHEADER_ARG("Kernel=0x%x, Memory=0x%x Pid=0x%u", Kernel, Memory, Pid);
  133802. +
  133803. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  133804. + gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
  133805. +
  133806. + gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
  133807. + mutex = gcvTRUE;
  133808. +
  133809. + /* Walk all sentinels. */
  133810. + for (i = 0; i < gcmCOUNTOF(Memory->sentinel); ++i)
  133811. + {
  133812. + /* Bail out of the heap if it is not used. */
  133813. + if (Memory->sentinel[i].VidMem.next == gcvNULL)
  133814. + {
  133815. + break;
  133816. + }
  133817. +
  133818. + do
  133819. + {
  133820. + again = gcvFALSE;
  133821. +
  133822. + /* Walk all the nodes until we reach the sentinel. */
  133823. + for (node = Memory->sentinel[i].VidMem.next;
  133824. + node->VidMem.bytes != 0;
  133825. + node = node->VidMem.next)
  133826. + {
  133827. + /* Free the node if it was allocated by Handle. */
  133828. + if (node->VidMem.processID == Pid)
  133829. + {
  133830. + /* Unlock video memory. */
  133831. + while (node->VidMem.locked > 0)
  133832. + {
  133833. + gckVIDMEM_Unlock(Kernel, node, gcvSURF_TYPE_UNKNOWN, gcvNULL);
  133834. + }
  133835. +
  133836. + nodeCount++;
  133837. + byteCount += node->VidMem.bytes;
  133838. +
  133839. + /* Free video memory. */
  133840. + gcmkVERIFY_OK(gckVIDMEM_Free(node));
  133841. +
  133842. + /*
  133843. + * Freeing may cause a merge which will invalidate our iteration.
  133844. + * Don't be clever, just restart.
  133845. + */
  133846. + again = gcvTRUE;
  133847. +
  133848. + break;
  133849. + }
  133850. +#if gcdUSE_VIDMEM_PER_PID
  133851. + else
  133852. + {
  133853. + gcmkASSERT(node->VidMem.processID == Pid);
  133854. + }
  133855. +#endif
  133856. + }
  133857. + }
  133858. + while (again);
  133859. + }
  133860. +
  133861. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  133862. + gcmkFOOTER();
  133863. + return gcvSTATUS_OK;
  133864. +
  133865. +OnError:
  133866. + if (mutex)
  133867. + {
  133868. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
  133869. + }
  133870. +
  133871. + gcmkFOOTER();
  133872. + return status;
  133873. +}
  133874. +#endif
  133875. +
  133876. +/*******************************************************************************
  133877. +**
  133878. +** _NeedVirtualMapping
  133879. +**
  133880. +** Whether setup GPU page table for video node.
  133881. +**
  133882. +** INPUT:
  133883. +** gckKERNEL Kernel
  133884. +** Pointer to an gckKERNEL object.
  133885. +**
  133886. +** gcuVIDMEM_NODE_PTR Node
  133887. +** Pointer to a gcuVIDMEM_NODE union.
  133888. +**
  133889. +** gceCORE Core
  133890. +** Id of current GPU.
  133891. +**
  133892. +** OUTPUT:
  133893. +** gctBOOL * NeedMapping
  133894. +** A pointer hold the result whether Node should be mapping.
  133895. +*/
  133896. +static gceSTATUS
  133897. +_NeedVirtualMapping(
  133898. + IN gckKERNEL Kernel,
  133899. + IN gceCORE Core,
  133900. + IN gcuVIDMEM_NODE_PTR Node,
  133901. + OUT gctBOOL * NeedMapping
  133902. +)
  133903. +{
  133904. + gceSTATUS status;
  133905. + gctUINT32 phys;
  133906. + gctUINT32 end;
  133907. + gcePOOL pool;
  133908. + gctUINT32 offset;
  133909. + gctUINT32 baseAddress;
  133910. +
  133911. + gcmkHEADER_ARG("Node=0x%X", Node);
  133912. +
  133913. + /* Verify the arguments. */
  133914. + gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
  133915. + gcmkVERIFY_ARGUMENT(Node != gcvNULL);
  133916. + gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
  133917. + gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT);
  133918. +
  133919. + if (Node->Virtual.contiguous)
  133920. + {
  133921. +#if gcdENABLE_VG
  133922. + if (Core == gcvCORE_VG)
  133923. + {
  133924. + *NeedMapping = gcvFALSE;
  133925. + }
  133926. + else
  133927. +#endif
  133928. + {
  133929. + /* Convert logical address into a physical address. */
  133930. + gcmkONERROR(
  133931. + gckOS_GetPhysicalAddress(Kernel->os, Node->Virtual.logical, &phys));
  133932. +
  133933. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  133934. +
  133935. + gcmkASSERT(phys >= baseAddress);
  133936. +
  133937. + /* Subtract baseAddress to get a GPU address used for programming. */
  133938. + phys -= baseAddress;
  133939. +
  133940. + /* If part of region is belong to gcvPOOL_VIRTUAL,
  133941. + ** whole region has to be mapped. */
  133942. + end = phys + Node->Virtual.bytes - 1;
  133943. +
  133944. + gcmkONERROR(gckHARDWARE_SplitMemory(
  133945. + Kernel->hardware, end, &pool, &offset
  133946. + ));
  133947. +
  133948. + *NeedMapping = (pool == gcvPOOL_VIRTUAL);
  133949. + }
  133950. + }
  133951. + else
  133952. + {
  133953. + *NeedMapping = gcvTRUE;
  133954. + }
  133955. +
  133956. + gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
  133957. + return gcvSTATUS_OK;
  133958. +
  133959. +OnError:
  133960. + gcmkFOOTER();
  133961. + return status;
  133962. +}
  133963. +
  133964. +/*******************************************************************************
  133965. +**
  133966. +** gckVIDMEM_Lock
  133967. +**
  133968. +** Lock a video memory node and return its hardware specific address.
  133969. +**
  133970. +** INPUT:
  133971. +**
  133972. +** gckKERNEL Kernel
  133973. +** Pointer to an gckKERNEL object.
  133974. +**
  133975. +** gcuVIDMEM_NODE_PTR Node
  133976. +** Pointer to a gcuVIDMEM_NODE union.
  133977. +**
  133978. +** OUTPUT:
  133979. +**
  133980. +** gctUINT32 * Address
  133981. +** Pointer to a variable that will hold the hardware specific address.
  133982. +*/
  133983. +gceSTATUS
  133984. +gckVIDMEM_Lock(
  133985. + IN gckKERNEL Kernel,
  133986. + IN gcuVIDMEM_NODE_PTR Node,
  133987. + IN gctBOOL Cacheable,
  133988. + OUT gctUINT32 * Address
  133989. + )
  133990. +{
  133991. + gceSTATUS status;
  133992. + gctBOOL acquired = gcvFALSE;
  133993. + gctBOOL locked = gcvFALSE;
  133994. + gckOS os = gcvNULL;
  133995. + gctBOOL needMapping;
  133996. + gctUINT32 baseAddress;
  133997. +
  133998. + gcmkHEADER_ARG("Node=0x%x", Node);
  133999. +
  134000. + /* Verify the arguments. */
  134001. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  134002. +
  134003. + if ((Node == gcvNULL)
  134004. + || (Node->VidMem.memory == gcvNULL)
  134005. + )
  134006. + {
  134007. + /* Invalid object. */
  134008. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  134009. + }
  134010. +
  134011. + /**************************** Video Memory ********************************/
  134012. +
  134013. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  134014. + {
  134015. + if (Cacheable == gcvTRUE)
  134016. + {
  134017. + gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
  134018. + }
  134019. +
  134020. + /* Increment the lock count. */
  134021. + Node->VidMem.locked ++;
  134022. +
  134023. + /* Return the physical address of the node. */
  134024. +#if !gcdUSE_VIDMEM_PER_PID
  134025. + *Address = Node->VidMem.memory->baseAddress
  134026. + + Node->VidMem.offset
  134027. + + Node->VidMem.alignment;
  134028. +#else
  134029. + *Address = Node->VidMem.physical;
  134030. +#endif
  134031. +
  134032. + /* Get hardware specific address. */
  134033. +#if gcdENABLE_VG
  134034. + if (Kernel->vg == gcvNULL)
  134035. +#endif
  134036. + {
  134037. + if (Kernel->hardware->mmuVersion == 0)
  134038. + {
  134039. + /* Convert physical to GPU address for old mmu. */
  134040. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  134041. + gcmkASSERT(*Address > baseAddress);
  134042. + *Address -= baseAddress;
  134043. + }
  134044. + }
  134045. +
  134046. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  134047. + "Locked node 0x%x (%d) @ 0x%08X",
  134048. + Node,
  134049. + Node->VidMem.locked,
  134050. + *Address);
  134051. + }
  134052. +
  134053. + /*************************** Virtual Memory *******************************/
  134054. +
  134055. + else
  134056. + {
  134057. + /* Verify the gckKERNEL object pointer. */
  134058. + gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
  134059. +
  134060. + /* Extract the gckOS object pointer. */
  134061. + os = Node->Virtual.kernel->os;
  134062. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  134063. +
  134064. + /* Grab the mutex. */
  134065. + gcmkONERROR(gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  134066. + acquired = gcvTRUE;
  134067. +
  134068. +#if gcdPAGED_MEMORY_CACHEABLE
  134069. + /* Force video memory cacheable. */
  134070. + Cacheable = gcvTRUE;
  134071. +#endif
  134072. +
  134073. + gcmkONERROR(
  134074. + gckOS_LockPages(os,
  134075. + Node->Virtual.physical,
  134076. + Node->Virtual.bytes,
  134077. + Cacheable,
  134078. + &Node->Virtual.logical,
  134079. + &Node->Virtual.pageCount));
  134080. +
  134081. + /* Increment the lock count. */
  134082. + if (Node->Virtual.lockeds[Kernel->core] ++ == 0)
  134083. + {
  134084. + /* Is this node pending for a final unlock? */
  134085. +#ifdef __QNXNTO__
  134086. + if (!Node->Virtual.contiguous && Node->Virtual.unlockPendings[Kernel->core])
  134087. + {
  134088. + /* Make sure we have a page table. */
  134089. + gcmkASSERT(Node->Virtual.pageTables[Kernel->core] != gcvNULL);
  134090. +
  134091. + /* Remove pending unlock. */
  134092. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  134093. + }
  134094. +
  134095. + /* First lock - create a page table. */
  134096. + gcmkASSERT(Node->Virtual.pageTables[Kernel->core] == gcvNULL);
  134097. +
  134098. + /* Make sure we mark our node as not flushed. */
  134099. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  134100. +#endif
  134101. +
  134102. + locked = gcvTRUE;
  134103. +
  134104. + gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, Node, &needMapping));
  134105. +
  134106. + if (needMapping == gcvFALSE)
  134107. + {
  134108. + /* Get hardware specific address. */
  134109. +#if gcdENABLE_VG
  134110. + if (Kernel->vg != gcvNULL)
  134111. + {
  134112. + gcmkONERROR(gckVGHARDWARE_ConvertLogical(Kernel->vg->hardware,
  134113. + Node->Virtual.logical,
  134114. + &Node->Virtual.addresses[Kernel->core]));
  134115. + }
  134116. + else
  134117. +#endif
  134118. + {
  134119. + gcmkONERROR(gckHARDWARE_ConvertLogical(Kernel->hardware,
  134120. + Node->Virtual.logical,
  134121. + &Node->Virtual.addresses[Kernel->core]));
  134122. + }
  134123. + }
  134124. + else
  134125. + {
  134126. +#if gcdENABLE_VG
  134127. + if (Kernel->vg != gcvNULL)
  134128. + {
  134129. + /* Allocate pages inside the MMU. */
  134130. + gcmkONERROR(
  134131. + gckVGMMU_AllocatePages(Kernel->vg->mmu,
  134132. + Node->Virtual.pageCount,
  134133. + &Node->Virtual.pageTables[Kernel->core],
  134134. + &Node->Virtual.addresses[Kernel->core]));
  134135. + }
  134136. + else
  134137. +#endif
  134138. + {
  134139. + /* Allocate pages inside the MMU. */
  134140. + gcmkONERROR(
  134141. + gckMMU_AllocatePagesEx(Kernel->mmu,
  134142. + Node->Virtual.pageCount,
  134143. + Node->Virtual.type,
  134144. + &Node->Virtual.pageTables[Kernel->core],
  134145. + &Node->Virtual.addresses[Kernel->core]));
  134146. + }
  134147. +
  134148. + Node->Virtual.lockKernels[Kernel->core] = Kernel;
  134149. +
  134150. + /* Map the pages. */
  134151. +#ifdef __QNXNTO__
  134152. + gcmkONERROR(
  134153. + gckOS_MapPagesEx(os,
  134154. + Kernel->core,
  134155. + Node->Virtual.physical,
  134156. + Node->Virtual.logical,
  134157. + Node->Virtual.pageCount,
  134158. + Node->Virtual.pageTables[Kernel->core]));
  134159. +#else
  134160. + gcmkONERROR(
  134161. + gckOS_MapPagesEx(os,
  134162. + Kernel->core,
  134163. + Node->Virtual.physical,
  134164. + Node->Virtual.pageCount,
  134165. + Node->Virtual.pageTables[Kernel->core]));
  134166. +#endif
  134167. +
  134168. +#if gcdENABLE_VG
  134169. + if (Kernel->core == gcvCORE_VG)
  134170. + {
  134171. + gcmkONERROR(gckVGMMU_Flush(Kernel->vg->mmu));
  134172. + }
  134173. + else
  134174. +#endif
  134175. + {
  134176. + gcmkONERROR(gckMMU_Flush(Kernel->mmu));
  134177. + }
  134178. + }
  134179. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  134180. + "Mapped virtual node 0x%x to 0x%08X",
  134181. + Node,
  134182. + Node->Virtual.addresses[Kernel->core]);
  134183. + }
  134184. +
  134185. + /* Return hardware address. */
  134186. + *Address = Node->Virtual.addresses[Kernel->core];
  134187. +
  134188. + /* Release the mutex. */
  134189. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  134190. + }
  134191. +
  134192. + /* Success. */
  134193. + gcmkFOOTER_ARG("*Address=%08x", *Address);
  134194. + return gcvSTATUS_OK;
  134195. +
  134196. +OnError:
  134197. + if (locked)
  134198. + {
  134199. + if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
  134200. + {
  134201. +#if gcdENABLE_VG
  134202. + if (Kernel->vg != gcvNULL)
  134203. + {
  134204. + /* Free the pages from the MMU. */
  134205. + gcmkVERIFY_OK(
  134206. + gckVGMMU_FreePages(Kernel->vg->mmu,
  134207. + Node->Virtual.pageTables[Kernel->core],
  134208. + Node->Virtual.pageCount));
  134209. + }
  134210. + else
  134211. +#endif
  134212. + {
  134213. + /* Free the pages from the MMU. */
  134214. + gcmkVERIFY_OK(
  134215. + gckMMU_FreePages(Kernel->mmu,
  134216. + Node->Virtual.pageTables[Kernel->core],
  134217. + Node->Virtual.pageCount));
  134218. + }
  134219. + Node->Virtual.pageTables[Kernel->core] = gcvNULL;
  134220. + Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
  134221. + }
  134222. +
  134223. + /* Unlock the pages. */
  134224. + gcmkVERIFY_OK(
  134225. + gckOS_UnlockPages(os,
  134226. + Node->Virtual.physical,
  134227. + Node->Virtual.bytes,
  134228. + Node->Virtual.logical
  134229. + ));
  134230. +
  134231. + Node->Virtual.lockeds[Kernel->core]--;
  134232. + }
  134233. +
  134234. + if (acquired)
  134235. + {
  134236. + /* Release the mutex. */
  134237. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  134238. + }
  134239. +
  134240. + /* Return the status. */
  134241. + gcmkFOOTER();
  134242. + return status;
  134243. +}
  134244. +
  134245. +/*******************************************************************************
  134246. +**
  134247. +** gckVIDMEM_Unlock
  134248. +**
  134249. +** Unlock a video memory node.
  134250. +**
  134251. +** INPUT:
  134252. +**
  134253. +** gckKERNEL Kernel
  134254. +** Pointer to an gckKERNEL object.
  134255. +**
  134256. +** gcuVIDMEM_NODE_PTR Node
  134257. +** Pointer to a locked gcuVIDMEM_NODE union.
  134258. +**
  134259. +** gceSURF_TYPE Type
  134260. +** Type of surface to unlock.
  134261. +**
  134262. +** gctBOOL * Asynchroneous
  134263. +** Pointer to a variable specifying whether the surface should be
  134264. +** unlocked asynchroneously or not.
  134265. +**
  134266. +** OUTPUT:
  134267. +**
  134268. +** gctBOOL * Asynchroneous
  134269. +** Pointer to a variable receiving the number of bytes used in the
  134270. +** command buffer specified by 'Commands'. If gcvNULL, there is no
  134271. +** command buffer.
  134272. +*/
  134273. +gceSTATUS
  134274. +gckVIDMEM_Unlock(
  134275. + IN gckKERNEL Kernel,
  134276. + IN gcuVIDMEM_NODE_PTR Node,
  134277. + IN gceSURF_TYPE Type,
  134278. + IN OUT gctBOOL * Asynchroneous
  134279. + )
  134280. +{
  134281. + gceSTATUS status;
  134282. + gckHARDWARE hardware;
  134283. + gctPOINTER buffer;
  134284. + gctSIZE_T requested, bufferSize;
  134285. + gckCOMMAND command = gcvNULL;
  134286. + gceKERNEL_FLUSH flush;
  134287. + gckOS os = gcvNULL;
  134288. + gctBOOL acquired = gcvFALSE;
  134289. + gctBOOL commitEntered = gcvFALSE;
  134290. + gctINT32 i, totalLocked;
  134291. +
  134292. + gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d",
  134293. + Node, Type, gcmOPT_VALUE(Asynchroneous));
  134294. +
  134295. + /* Verify the arguments. */
  134296. + if ((Node == gcvNULL)
  134297. + || (Node->VidMem.memory == gcvNULL)
  134298. + )
  134299. + {
  134300. + /* Invalid object. */
  134301. + gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
  134302. + }
  134303. +
  134304. + /**************************** Video Memory ********************************/
  134305. +
  134306. + if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  134307. + {
  134308. + if (Node->VidMem.locked <= 0)
  134309. + {
  134310. + /* The surface was not locked. */
  134311. + status = gcvSTATUS_MEMORY_UNLOCKED;
  134312. + goto OnError;
  134313. + }
  134314. +
  134315. + /* Decrement the lock count. */
  134316. + Node->VidMem.locked --;
  134317. +
  134318. + if (Asynchroneous != gcvNULL)
  134319. + {
  134320. + /* No need for any events. */
  134321. + *Asynchroneous = gcvFALSE;
  134322. + }
  134323. +
  134324. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  134325. + "Unlocked node 0x%x (%d)",
  134326. + Node,
  134327. + Node->VidMem.locked);
  134328. +
  134329. +#ifdef __QNXNTO__
  134330. + /* Unmap the video memory */
  134331. + if ((Node->VidMem.locked == 0) && (Node->VidMem.logical != gcvNULL))
  134332. + {
  134333. + if (Kernel->core == gcvCORE_VG)
  134334. + {
  134335. + gckKERNEL_UnmapVideoMemory(Kernel,
  134336. + Node->VidMem.logical,
  134337. + Node->VidMem.processID,
  134338. + Node->VidMem.bytes);
  134339. + Node->VidMem.logical = gcvNULL;
  134340. + }
  134341. + }
  134342. +#endif /* __QNXNTO__ */
  134343. +
  134344. + if (Node->VidMem.freePending && (Node->VidMem.locked == 0))
  134345. + {
  134346. + /* Client has unlocked node previously attempted to be freed by compositor. Free now. */
  134347. + Node->VidMem.freePending = gcvFALSE;
  134348. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  134349. + "Deferred-freeing Node 0x%x.",
  134350. + Node);
  134351. + gcmkONERROR(gckVIDMEM_Free(Node));
  134352. + }
  134353. + }
  134354. +
  134355. + /*************************** Virtual Memory *******************************/
  134356. +
  134357. + else
  134358. + {
  134359. + /* Verify the gckHARDWARE object pointer. */
  134360. + hardware = Kernel->hardware;
  134361. + gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
  134362. +
  134363. + /* Verify the gckCOMMAND object pointer. */
  134364. + command = Kernel->command;
  134365. + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
  134366. +
  134367. + /* Get the gckOS object pointer. */
  134368. + os = Kernel->os;
  134369. + gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
  134370. +
  134371. + /* Grab the mutex. */
  134372. + gcmkONERROR(
  134373. + gckOS_AcquireMutex(os, Node->Virtual.mutex, gcvINFINITE));
  134374. +
  134375. + acquired = gcvTRUE;
  134376. +
  134377. + if (Asynchroneous == gcvNULL)
  134378. + {
  134379. + if (Node->Virtual.lockeds[Kernel->core] == 0)
  134380. + {
  134381. + status = gcvSTATUS_MEMORY_UNLOCKED;
  134382. + goto OnError;
  134383. + }
  134384. +
  134385. + /* Decrement lock count. */
  134386. + -- Node->Virtual.lockeds[Kernel->core];
  134387. +
  134388. + /* See if we can unlock the resources. */
  134389. + if (Node->Virtual.lockeds[Kernel->core] == 0)
  134390. + {
  134391. + /* Free the page table. */
  134392. + if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
  134393. + {
  134394. +#if gcdENABLE_VG
  134395. + if (Kernel->vg != gcvNULL)
  134396. + {
  134397. + gcmkONERROR(
  134398. + gckVGMMU_FreePages(Kernel->vg->mmu,
  134399. + Node->Virtual.pageTables[Kernel->core],
  134400. + Node->Virtual.pageCount));
  134401. + }
  134402. + else
  134403. +#endif
  134404. + {
  134405. + gcmkONERROR(
  134406. + gckMMU_FreePages(Kernel->mmu,
  134407. + Node->Virtual.pageTables[Kernel->core],
  134408. + Node->Virtual.pageCount));
  134409. + }
  134410. + /* Mark page table as freed. */
  134411. + Node->Virtual.pageTables[Kernel->core] = gcvNULL;
  134412. + Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
  134413. + }
  134414. +
  134415. +#ifdef __QNXNTO__
  134416. + /* Mark node as unlocked. */
  134417. + Node->Virtual.unlockPendings[Kernel->core] = gcvFALSE;
  134418. +#endif
  134419. + }
  134420. +
  134421. + for (i = 0, totalLocked = 0; i < gcdMAX_GPU_COUNT; i++)
  134422. + {
  134423. + totalLocked += Node->Virtual.lockeds[i];
  134424. + }
  134425. +
  134426. + if (totalLocked == 0)
  134427. + {
  134428. + /* Owner have already freed this node
  134429. + ** and we are the last one to unlock, do
  134430. + ** real free */
  134431. + if (Node->Virtual.freed)
  134432. + {
  134433. + /* Free the virtual memory. */
  134434. + gcmkVERIFY_OK(gckOS_FreePagedMemory(Kernel->os,
  134435. + Node->Virtual.physical,
  134436. + Node->Virtual.bytes));
  134437. +
  134438. + /* Release mutex before node is destroyed */
  134439. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  134440. +
  134441. + acquired = gcvFALSE;
  134442. +
  134443. + /* Destroy the gcuVIDMEM_NODE union. */
  134444. + gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
  134445. +
  134446. + /* Node has been destroyed, so we should not touch it any more */
  134447. + gcmkFOOTER();
  134448. + return gcvSTATUS_OK;
  134449. + }
  134450. + }
  134451. +
  134452. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  134453. + "Unmapped virtual node 0x%x from 0x%08X",
  134454. + Node, Node->Virtual.addresses[Kernel->core]);
  134455. +
  134456. + }
  134457. +
  134458. + else
  134459. + {
  134460. + /* If we need to unlock a node from virtual memory we have to be
  134461. + ** very carefull. If the node is still inside the caches we
  134462. + ** might get a bus error later if the cache line needs to be
  134463. + ** replaced. So - we have to flush the caches before we do
  134464. + ** anything. */
  134465. +
  134466. + /* gckCommand_EnterCommit() can't be called in interrupt handler because
  134467. + ** of a dead lock situation:
  134468. + ** process call Command_Commit(), and acquire Command->mutexQueue in
  134469. + ** gckCOMMAND_EnterCommit(). Then it will wait for a signal which depends
  134470. + ** on interrupt handler to generate, if interrupt handler enter
  134471. + ** gckCommand_EnterCommit(), process will never get the signal. */
  134472. +
  134473. + /* So, flush cache when we still in process context, and then ask caller to
  134474. + ** schedule a event. */
  134475. +
  134476. + gcmkONERROR(
  134477. + gckOS_UnlockPages(os,
  134478. + Node->Virtual.physical,
  134479. + Node->Virtual.bytes,
  134480. + Node->Virtual.logical));
  134481. +
  134482. + if (!Node->Virtual.contiguous
  134483. + && (Node->Virtual.lockeds[Kernel->core] == 1)
  134484. +#if gcdENABLE_VG
  134485. + && (Kernel->vg == gcvNULL)
  134486. +#endif
  134487. + )
  134488. + {
  134489. + if (Type == gcvSURF_BITMAP)
  134490. + {
  134491. + /* Flush 2D cache. */
  134492. + flush = gcvFLUSH_2D;
  134493. + }
  134494. + else if (Type == gcvSURF_RENDER_TARGET)
  134495. + {
  134496. + /* Flush color cache. */
  134497. + flush = gcvFLUSH_COLOR;
  134498. + }
  134499. + else if (Type == gcvSURF_DEPTH)
  134500. + {
  134501. + /* Flush depth cache. */
  134502. + flush = gcvFLUSH_DEPTH;
  134503. + }
  134504. + else
  134505. + {
  134506. + /* No flush required. */
  134507. + flush = (gceKERNEL_FLUSH) 0;
  134508. + }
  134509. + if(hardware)
  134510. + {
  134511. + gcmkONERROR(
  134512. + gckHARDWARE_Flush(hardware, flush, gcvNULL, &requested));
  134513. +
  134514. + if (requested != 0)
  134515. + {
  134516. + /* Acquire the command queue. */
  134517. + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
  134518. + commitEntered = gcvTRUE;
  134519. +
  134520. + gcmkONERROR(gckCOMMAND_Reserve(
  134521. + command, requested, &buffer, &bufferSize
  134522. + ));
  134523. +
  134524. + gcmkONERROR(gckHARDWARE_Flush(
  134525. + hardware, flush, buffer, &bufferSize
  134526. + ));
  134527. +
  134528. + /* Mark node as pending. */
  134529. +#ifdef __QNXNTO__
  134530. + Node->Virtual.unlockPendings[Kernel->core] = gcvTRUE;
  134531. +#endif
  134532. +
  134533. + gcmkONERROR(gckCOMMAND_Execute(command, requested));
  134534. +
  134535. + /* Release the command queue. */
  134536. + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
  134537. + commitEntered = gcvFALSE;
  134538. + }
  134539. + }
  134540. + else
  134541. + {
  134542. + gckOS_Print("Hardware already is freed.\n");
  134543. + }
  134544. + }
  134545. +
  134546. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
  134547. + "Scheduled unlock for virtual node 0x%x",
  134548. + Node);
  134549. +
  134550. + /* Schedule the surface to be unlocked. */
  134551. + *Asynchroneous = gcvTRUE;
  134552. + }
  134553. +
  134554. + /* Release the mutex. */
  134555. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  134556. +
  134557. + acquired = gcvFALSE;
  134558. + }
  134559. +
  134560. + /* Success. */
  134561. + gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
  134562. + return gcvSTATUS_OK;
  134563. +
  134564. +OnError:
  134565. + if (commitEntered)
  134566. + {
  134567. + /* Release the command queue mutex. */
  134568. + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvFALSE));
  134569. + }
  134570. +
  134571. + if (acquired)
  134572. + {
  134573. + /* Release the mutex. */
  134574. + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->Virtual.mutex));
  134575. + }
  134576. +
  134577. + /* Return the status. */
  134578. + gcmkFOOTER();
  134579. + return status;
  134580. +}
  134581. diff -Nur linux-3.14.17/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
  134582. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h 1970-01-01 01:00:00.000000000 +0100
  134583. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h 2014-09-11 18:06:03.118042434 +0200
  134584. @@ -0,0 +1,3896 @@
  134585. +/****************************************************************************
  134586. +*
  134587. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  134588. +*
  134589. +* This program is free software; you can redistribute it and/or modify
  134590. +* it under the terms of the GNU General Public License as published by
  134591. +* the Free Software Foundation; either version 2 of the license, or
  134592. +* (at your option) any later version.
  134593. +*
  134594. +* This program is distributed in the hope that it will be useful,
  134595. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  134596. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  134597. +* GNU General Public License for more details.
  134598. +*
  134599. +* You should have received a copy of the GNU General Public License
  134600. +* along with this program; if not write to the Free Software
  134601. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  134602. +*
  134603. +*****************************************************************************/
  134604. +
  134605. +
  134606. +#ifndef __gc_hal_base_h_
  134607. +#define __gc_hal_base_h_
  134608. +
  134609. +#include "gc_hal_enum.h"
  134610. +#include "gc_hal_types.h"
  134611. +
  134612. +#include "gc_hal_dump.h"
  134613. +
  134614. +#ifdef __cplusplus
  134615. +extern "C" {
  134616. +#endif
  134617. +
  134618. +/******************************************************************************\
  134619. +****************************** Object Declarations *****************************
  134620. +\******************************************************************************/
  134621. +
  134622. +typedef struct _gckOS * gckOS;
  134623. +typedef struct _gcoHAL * gcoHAL;
  134624. +typedef struct _gcoOS * gcoOS;
  134625. +typedef struct _gco2D * gco2D;
  134626. +
  134627. +#ifndef VIVANTE_NO_3D
  134628. +typedef struct _gco3D * gco3D;
  134629. +#endif
  134630. +
  134631. +typedef struct _gcoSURF * gcoSURF;
  134632. +typedef struct _gcsSURF_INFO * gcsSURF_INFO_PTR;
  134633. +typedef struct _gcsSURF_NODE * gcsSURF_NODE_PTR;
  134634. +typedef struct _gcsSURF_FORMAT_INFO * gcsSURF_FORMAT_INFO_PTR;
  134635. +typedef struct _gcsPOINT * gcsPOINT_PTR;
  134636. +typedef struct _gcsSIZE * gcsSIZE_PTR;
  134637. +typedef struct _gcsRECT * gcsRECT_PTR;
  134638. +typedef struct _gcsBOUNDARY * gcsBOUNDARY_PTR;
  134639. +typedef struct _gcoDUMP * gcoDUMP;
  134640. +typedef struct _gcoHARDWARE * gcoHARDWARE;
  134641. +typedef union _gcuVIDMEM_NODE * gcuVIDMEM_NODE_PTR;
  134642. +
  134643. +typedef struct gcsATOM * gcsATOM_PTR;
  134644. +
  134645. +#if gcdENABLE_VG
  134646. +typedef struct _gcoVG * gcoVG;
  134647. +typedef struct _gcsCOMPLETION_SIGNAL * gcsCOMPLETION_SIGNAL_PTR;
  134648. +typedef struct _gcsCONTEXT_MAP * gcsCONTEXT_MAP_PTR;
  134649. +#else
  134650. +typedef void * gcoVG;
  134651. +#endif
  134652. +
  134653. +#if gcdSYNC
  134654. +typedef struct _gcoFENCE * gcoFENCE;
  134655. +typedef struct _gcsSYNC_CONTEXT * gcsSYNC_CONTEXT_PTR;
  134656. +#endif
  134657. +
  134658. +typedef struct _gcoOS_SymbolsList gcoOS_SymbolsList;
  134659. +
  134660. +/******************************************************************************\
  134661. +******************************* Process local storage *************************
  134662. +\******************************************************************************/
  134663. +typedef struct _gcsPLS * gcsPLS_PTR;
  134664. +
  134665. +typedef void (* gctPLS_DESTRUCTOR) (
  134666. + gcsPLS_PTR
  134667. + );
  134668. +
  134669. +typedef struct _gcsPLS
  134670. +{
  134671. + /* Global objects. */
  134672. + gcoOS os;
  134673. + gcoHAL hal;
  134674. +
  134675. + /* Internal memory pool. */
  134676. + gctSIZE_T internalSize;
  134677. + gctPHYS_ADDR internalPhysical;
  134678. + gctPOINTER internalLogical;
  134679. +
  134680. + /* External memory pool. */
  134681. + gctSIZE_T externalSize;
  134682. + gctPHYS_ADDR externalPhysical;
  134683. + gctPOINTER externalLogical;
  134684. +
  134685. + /* Contiguous memory pool. */
  134686. + gctSIZE_T contiguousSize;
  134687. + gctPHYS_ADDR contiguousPhysical;
  134688. + gctPOINTER contiguousLogical;
  134689. +
  134690. + /* EGL-specific process-wide objects. */
  134691. + gctPOINTER eglDisplayInfo;
  134692. + gctPOINTER eglSurfaceInfo;
  134693. + gceSURF_FORMAT eglConfigFormat;
  134694. +
  134695. + /* PorcessID of the constrcutor process */
  134696. + gctUINT32 processID;
  134697. +#if gcdFORCE_GAL_LOAD_TWICE
  134698. + /* ThreadID of the constrcutor process. */
  134699. + gctSIZE_T threadID;
  134700. + /* Flag for calling module destructor. */
  134701. + gctBOOL exiting;
  134702. +#endif
  134703. +
  134704. + /* Reference count for destructor. */
  134705. + gcsATOM_PTR reference;
  134706. + gctBOOL bKFS;
  134707. +#if gcdUSE_NPOT_PATCH
  134708. + gctBOOL bNeedSupportNP2Texture;
  134709. +#endif
  134710. +
  134711. + /* Destructor for eglDisplayInfo. */
  134712. + gctPLS_DESTRUCTOR destructor;
  134713. +}
  134714. +gcsPLS;
  134715. +
  134716. +extern gcsPLS gcPLS;
  134717. +
  134718. +/******************************************************************************\
  134719. +******************************* Thread local storage *************************
  134720. +\******************************************************************************/
  134721. +
  134722. +typedef struct _gcsTLS * gcsTLS_PTR;
  134723. +
  134724. +typedef void (* gctTLS_DESTRUCTOR) (
  134725. + gcsTLS_PTR
  134726. + );
  134727. +
  134728. +typedef struct _gcsTLS
  134729. +{
  134730. + gceHARDWARE_TYPE currentType;
  134731. + gcoHARDWARE hardware;
  134732. + /* Only for separated 3D and 2D */
  134733. + gcoHARDWARE hardware2D;
  134734. +#if gcdENABLE_VG
  134735. + gcoVGHARDWARE vg;
  134736. + gcoVG engineVG;
  134737. +#endif /* gcdENABLE_VG */
  134738. + gctPOINTER context;
  134739. + gctTLS_DESTRUCTOR destructor;
  134740. + gctBOOL ProcessExiting;
  134741. +
  134742. +#ifndef VIVANTE_NO_3D
  134743. + gco3D engine3D;
  134744. +#endif
  134745. +#if gcdSYNC
  134746. + gctBOOL fenceEnable;
  134747. +#endif
  134748. + gco2D engine2D;
  134749. + gctBOOL copied;
  134750. +
  134751. +#if gcdFORCE_GAL_LOAD_TWICE
  134752. + /* libGAL.so handle */
  134753. + gctHANDLE handle;
  134754. +#endif
  134755. +}
  134756. +gcsTLS;
  134757. +
  134758. +/******************************************************************************\
  134759. +********************************* Enumerations *********************************
  134760. +\******************************************************************************/
  134761. +
  134762. +typedef enum _gcePLS_VALUE
  134763. +{
  134764. + gcePLS_VALUE_EGL_DISPLAY_INFO,
  134765. + gcePLS_VALUE_EGL_SURFACE_INFO,
  134766. + gcePLS_VALUE_EGL_CONFIG_FORMAT_INFO,
  134767. + gcePLS_VALUE_EGL_DESTRUCTOR_INFO,
  134768. +}
  134769. +gcePLS_VALUE;
  134770. +
  134771. +/* Video memory pool type. */
  134772. +typedef enum _gcePOOL
  134773. +{
  134774. + gcvPOOL_UNKNOWN = 0,
  134775. + gcvPOOL_DEFAULT,
  134776. + gcvPOOL_LOCAL,
  134777. + gcvPOOL_LOCAL_INTERNAL,
  134778. + gcvPOOL_LOCAL_EXTERNAL,
  134779. + gcvPOOL_UNIFIED,
  134780. + gcvPOOL_SYSTEM,
  134781. + gcvPOOL_VIRTUAL,
  134782. + gcvPOOL_USER,
  134783. + gcvPOOL_CONTIGUOUS,
  134784. + gcvPOOL_DEFAULT_FORCE_CONTIGUOUS,
  134785. + gcvPOOL_DEFAULT_FORCE_CONTIGUOUS_CACHEABLE,
  134786. +
  134787. + gcvPOOL_NUMBER_OF_POOLS
  134788. +}
  134789. +gcePOOL;
  134790. +
  134791. +#ifndef VIVANTE_NO_3D
  134792. +/* Blending functions. */
  134793. +typedef enum _gceBLEND_FUNCTION
  134794. +{
  134795. + gcvBLEND_ZERO,
  134796. + gcvBLEND_ONE,
  134797. + gcvBLEND_SOURCE_COLOR,
  134798. + gcvBLEND_INV_SOURCE_COLOR,
  134799. + gcvBLEND_SOURCE_ALPHA,
  134800. + gcvBLEND_INV_SOURCE_ALPHA,
  134801. + gcvBLEND_TARGET_COLOR,
  134802. + gcvBLEND_INV_TARGET_COLOR,
  134803. + gcvBLEND_TARGET_ALPHA,
  134804. + gcvBLEND_INV_TARGET_ALPHA,
  134805. + gcvBLEND_SOURCE_ALPHA_SATURATE,
  134806. + gcvBLEND_CONST_COLOR,
  134807. + gcvBLEND_INV_CONST_COLOR,
  134808. + gcvBLEND_CONST_ALPHA,
  134809. + gcvBLEND_INV_CONST_ALPHA,
  134810. +}
  134811. +gceBLEND_FUNCTION;
  134812. +
  134813. +/* Blending modes. */
  134814. +typedef enum _gceBLEND_MODE
  134815. +{
  134816. + gcvBLEND_ADD,
  134817. + gcvBLEND_SUBTRACT,
  134818. + gcvBLEND_REVERSE_SUBTRACT,
  134819. + gcvBLEND_MIN,
  134820. + gcvBLEND_MAX,
  134821. +}
  134822. +gceBLEND_MODE;
  134823. +
  134824. +/* API flags. */
  134825. +typedef enum _gceAPI
  134826. +{
  134827. + gcvAPI_D3D = 0x1,
  134828. + gcvAPI_OPENGL = 0x2,
  134829. + gcvAPI_OPENVG = 0x3,
  134830. + gcvAPI_OPENCL = 0x4,
  134831. +}
  134832. +gceAPI;
  134833. +
  134834. +/* Depth modes. */
  134835. +typedef enum _gceDEPTH_MODE
  134836. +{
  134837. + gcvDEPTH_NONE,
  134838. + gcvDEPTH_Z,
  134839. + gcvDEPTH_W,
  134840. +}
  134841. +gceDEPTH_MODE;
  134842. +#endif /* VIVANTE_NO_3D */
  134843. +
  134844. +typedef enum _gceWHERE
  134845. +{
  134846. + gcvWHERE_COMMAND,
  134847. + gcvWHERE_RASTER,
  134848. + gcvWHERE_PIXEL,
  134849. +}
  134850. +gceWHERE;
  134851. +
  134852. +typedef enum _gceHOW
  134853. +{
  134854. + gcvHOW_SEMAPHORE = 0x1,
  134855. + gcvHOW_STALL = 0x2,
  134856. + gcvHOW_SEMAPHORE_STALL = 0x3,
  134857. +}
  134858. +gceHOW;
  134859. +
  134860. +typedef enum _gceSignalHandlerType
  134861. +{
  134862. + gcvHANDLE_SIGFPE_WHEN_SIGNAL_CODE_IS_0 = 0x1,
  134863. +}
  134864. +gceSignalHandlerType;
  134865. +
  134866. +
  134867. +#if gcdENABLE_VG
  134868. +/* gcsHAL_Limits*/
  134869. +typedef struct _gcsHAL_LIMITS
  134870. +{
  134871. + /* chip info */
  134872. + gceCHIPMODEL chipModel;
  134873. + gctUINT32 chipRevision;
  134874. + gctUINT32 featureCount;
  134875. + gctUINT32 *chipFeatures;
  134876. +
  134877. + /* target caps */
  134878. + gctUINT32 maxWidth;
  134879. + gctUINT32 maxHeight;
  134880. + gctUINT32 multiTargetCount;
  134881. + gctUINT32 maxSamples;
  134882. +
  134883. +}gcsHAL_LIMITS;
  134884. +#endif
  134885. +
  134886. +/******************************************************************************\
  134887. +*********** Generic Memory Allocation Optimization Using Containers ************
  134888. +\******************************************************************************/
  134889. +
  134890. +/* Generic container definition. */
  134891. +typedef struct _gcsCONTAINER_LINK * gcsCONTAINER_LINK_PTR;
  134892. +typedef struct _gcsCONTAINER_LINK
  134893. +{
  134894. + /* Points to the next container. */
  134895. + gcsCONTAINER_LINK_PTR next;
  134896. +}
  134897. +gcsCONTAINER_LINK;
  134898. +
  134899. +typedef struct _gcsCONTAINER_RECORD * gcsCONTAINER_RECORD_PTR;
  134900. +typedef struct _gcsCONTAINER_RECORD
  134901. +{
  134902. + gcsCONTAINER_RECORD_PTR prev;
  134903. + gcsCONTAINER_RECORD_PTR next;
  134904. +}
  134905. +gcsCONTAINER_RECORD;
  134906. +
  134907. +typedef struct _gcsCONTAINER * gcsCONTAINER_PTR;
  134908. +typedef struct _gcsCONTAINER
  134909. +{
  134910. + gctUINT containerSize;
  134911. + gctUINT recordSize;
  134912. + gctUINT recordCount;
  134913. + gcsCONTAINER_LINK_PTR containers;
  134914. + gcsCONTAINER_RECORD freeList;
  134915. + gcsCONTAINER_RECORD allocList;
  134916. +}
  134917. +gcsCONTAINER;
  134918. +
  134919. +gceSTATUS
  134920. +gcsCONTAINER_Construct(
  134921. + IN gcsCONTAINER_PTR Container,
  134922. + gctUINT RecordsPerContainer,
  134923. + gctUINT RecordSize
  134924. + );
  134925. +
  134926. +gceSTATUS
  134927. +gcsCONTAINER_Destroy(
  134928. + IN gcsCONTAINER_PTR Container
  134929. + );
  134930. +
  134931. +gceSTATUS
  134932. +gcsCONTAINER_AllocateRecord(
  134933. + IN gcsCONTAINER_PTR Container,
  134934. + OUT gctPOINTER * Record
  134935. + );
  134936. +
  134937. +gceSTATUS
  134938. +gcsCONTAINER_FreeRecord(
  134939. + IN gcsCONTAINER_PTR Container,
  134940. + IN gctPOINTER Record
  134941. + );
  134942. +
  134943. +gceSTATUS
  134944. +gcsCONTAINER_FreeAll(
  134945. + IN gcsCONTAINER_PTR Container
  134946. + );
  134947. +
  134948. +/******************************************************************************\
  134949. +********************************* gcoHAL Object *********************************
  134950. +\******************************************************************************/
  134951. +
  134952. +/* Construct a new gcoHAL object. */
  134953. +gceSTATUS
  134954. +gcoHAL_Construct(
  134955. + IN gctPOINTER Context,
  134956. + IN gcoOS Os,
  134957. + OUT gcoHAL * Hal
  134958. + );
  134959. +
  134960. +/* Destroy an gcoHAL object. */
  134961. +gceSTATUS
  134962. +gcoHAL_Destroy(
  134963. + IN gcoHAL Hal
  134964. + );
  134965. +
  134966. +/* Get pointer to gco2D object. */
  134967. +gceSTATUS
  134968. +gcoHAL_Get2DEngine(
  134969. + IN gcoHAL Hal,
  134970. + OUT gco2D * Engine
  134971. + );
  134972. +
  134973. +gceSTATUS
  134974. +gcoHAL_SetFscaleValue(
  134975. + IN gctUINT FscaleValue
  134976. + );
  134977. +
  134978. +gceSTATUS
  134979. +gcoHAL_GetFscaleValue(
  134980. + OUT gctUINT * FscaleValue,
  134981. + OUT gctUINT * MinFscaleValue,
  134982. + OUT gctUINT * MaxFscaleValue
  134983. + );
  134984. +
  134985. +gceSTATUS
  134986. +gcoHAL_SetBltNP2Texture(
  134987. + gctBOOL enable
  134988. + );
  134989. +
  134990. +#ifndef VIVANTE_NO_3D
  134991. +/* Get pointer to gco3D object. */
  134992. +gceSTATUS
  134993. +gcoHAL_Get3DEngine(
  134994. + IN gcoHAL Hal,
  134995. + OUT gco3D * Engine
  134996. + );
  134997. +
  134998. +gceSTATUS
  134999. +gcoHAL_Query3DEngine(
  135000. + IN gcoHAL Hal,
  135001. + OUT gco3D * Engine
  135002. + );
  135003. +
  135004. +gceSTATUS
  135005. +gcoHAL_Set3DEngine(
  135006. + IN gcoHAL Hal,
  135007. + IN gco3D Engine
  135008. + );
  135009. +
  135010. +gceSTATUS
  135011. +gcoHAL_Get3DHardware(
  135012. + IN gcoHAL Hal,
  135013. + OUT gcoHARDWARE * Hardware
  135014. + );
  135015. +
  135016. +gceSTATUS
  135017. +gcoHAL_Set3DHardware(
  135018. + IN gcoHAL Hal,
  135019. + IN gcoHARDWARE Hardware
  135020. + );
  135021. +
  135022. +
  135023. +#endif /* VIVANTE_NO_3D */
  135024. +
  135025. +/* Verify whether the specified feature is available in hardware. */
  135026. +gceSTATUS
  135027. +gcoHAL_IsFeatureAvailable(
  135028. + IN gcoHAL Hal,
  135029. + IN gceFEATURE Feature
  135030. + );
  135031. +
  135032. +/* Query the identity of the hardware. */
  135033. +gceSTATUS
  135034. +gcoHAL_QueryChipIdentity(
  135035. + IN gcoHAL Hal,
  135036. + OUT gceCHIPMODEL* ChipModel,
  135037. + OUT gctUINT32* ChipRevision,
  135038. + OUT gctUINT32* ChipFeatures,
  135039. + OUT gctUINT32* ChipMinorFeatures
  135040. + );
  135041. +
  135042. +/* Query the minor features of the hardware. */
  135043. +gceSTATUS gcoHAL_QueryChipMinorFeatures(
  135044. + IN gcoHAL Hal,
  135045. + OUT gctUINT32* NumFeatures,
  135046. + OUT gctUINT32* ChipMinorFeatures
  135047. + );
  135048. +
  135049. +/* Query the amount of video memory. */
  135050. +gceSTATUS
  135051. +gcoHAL_QueryVideoMemory(
  135052. + IN gcoHAL Hal,
  135053. + OUT gctPHYS_ADDR * InternalAddress,
  135054. + OUT gctSIZE_T * InternalSize,
  135055. + OUT gctPHYS_ADDR * ExternalAddress,
  135056. + OUT gctSIZE_T * ExternalSize,
  135057. + OUT gctPHYS_ADDR * ContiguousAddress,
  135058. + OUT gctSIZE_T * ContiguousSize
  135059. + );
  135060. +
  135061. +/* Map video memory. */
  135062. +gceSTATUS
  135063. +gcoHAL_MapMemory(
  135064. + IN gcoHAL Hal,
  135065. + IN gctPHYS_ADDR Physical,
  135066. + IN gctSIZE_T NumberOfBytes,
  135067. + OUT gctPOINTER * Logical
  135068. + );
  135069. +
  135070. +/* Unmap video memory. */
  135071. +gceSTATUS
  135072. +gcoHAL_UnmapMemory(
  135073. + IN gcoHAL Hal,
  135074. + IN gctPHYS_ADDR Physical,
  135075. + IN gctSIZE_T NumberOfBytes,
  135076. + IN gctPOINTER Logical
  135077. + );
  135078. +
  135079. +/* Schedule an unmap of a buffer mapped through its physical address. */
  135080. +gceSTATUS
  135081. +gcoHAL_ScheduleUnmapMemory(
  135082. + IN gcoHAL Hal,
  135083. + IN gctPHYS_ADDR Physical,
  135084. + IN gctSIZE_T NumberOfBytes,
  135085. + IN gctPOINTER Logical
  135086. + );
  135087. +
  135088. +/* Map user memory. */
  135089. +gceSTATUS
  135090. +gcoHAL_MapUserMemory(
  135091. + IN gctPOINTER Logical,
  135092. + IN gctUINT32 Physical,
  135093. + IN gctSIZE_T Size,
  135094. + OUT gctPOINTER * Info,
  135095. + OUT gctUINT32_PTR GPUAddress
  135096. + );
  135097. +
  135098. +/* Unmap user memory. */
  135099. +gceSTATUS
  135100. +gcoHAL_UnmapUserMemory(
  135101. + IN gctPOINTER Logical,
  135102. + IN gctSIZE_T Size,
  135103. + IN gctPOINTER Info,
  135104. + IN gctUINT32 GPUAddress
  135105. + );
  135106. +
  135107. +/* Schedule an unmap of a user buffer using event mechanism. */
  135108. +gceSTATUS
  135109. +gcoHAL_ScheduleUnmapUserMemory(
  135110. + IN gcoHAL Hal,
  135111. + IN gctPOINTER Info,
  135112. + IN gctSIZE_T Size,
  135113. + IN gctUINT32 Address,
  135114. + IN gctPOINTER Memory
  135115. + );
  135116. +
  135117. +/* Commit the current command buffer. */
  135118. +gceSTATUS
  135119. +gcoHAL_Commit(
  135120. + IN gcoHAL Hal,
  135121. + IN gctBOOL Stall
  135122. + );
  135123. +
  135124. +/* Query the tile capabilities. */
  135125. +gceSTATUS
  135126. +gcoHAL_QueryTiled(
  135127. + IN gcoHAL Hal,
  135128. + OUT gctINT32 * TileWidth2D,
  135129. + OUT gctINT32 * TileHeight2D,
  135130. + OUT gctINT32 * TileWidth3D,
  135131. + OUT gctINT32 * TileHeight3D
  135132. + );
  135133. +
  135134. +gceSTATUS
  135135. +gcoHAL_Compact(
  135136. + IN gcoHAL Hal
  135137. + );
  135138. +
  135139. +#if VIVANTE_PROFILER
  135140. +gceSTATUS
  135141. +gcoHAL_ProfileStart(
  135142. + IN gcoHAL Hal
  135143. + );
  135144. +
  135145. +gceSTATUS
  135146. +gcoHAL_ProfileEnd(
  135147. + IN gcoHAL Hal,
  135148. + IN gctCONST_STRING Title
  135149. + );
  135150. +#endif
  135151. +
  135152. +/* Power Management */
  135153. +gceSTATUS
  135154. +gcoHAL_SetPowerManagementState(
  135155. + IN gcoHAL Hal,
  135156. + IN gceCHIPPOWERSTATE State
  135157. + );
  135158. +
  135159. +gceSTATUS
  135160. +gcoHAL_QueryPowerManagementState(
  135161. + IN gcoHAL Hal,
  135162. + OUT gceCHIPPOWERSTATE *State
  135163. + );
  135164. +
  135165. +/* Set the filter type for filter blit. */
  135166. +gceSTATUS
  135167. +gcoHAL_SetFilterType(
  135168. + IN gcoHAL Hal,
  135169. + IN gceFILTER_TYPE FilterType
  135170. + );
  135171. +
  135172. +gceSTATUS
  135173. +gcoHAL_GetDump(
  135174. + IN gcoHAL Hal,
  135175. + OUT gcoDUMP * Dump
  135176. + );
  135177. +
  135178. +/* Call the kernel HAL layer. */
  135179. +gceSTATUS
  135180. +gcoHAL_Call(
  135181. + IN gcoHAL Hal,
  135182. + IN OUT gcsHAL_INTERFACE_PTR Interface
  135183. + );
  135184. +
  135185. +gceSTATUS
  135186. +gcoHAL_GetPatchID(
  135187. + IN gcoHAL Hal,
  135188. + OUT gcePATCH_ID * PatchID
  135189. + );
  135190. +
  135191. +/* Schedule an event. */
  135192. +gceSTATUS
  135193. +gcoHAL_ScheduleEvent(
  135194. + IN gcoHAL Hal,
  135195. + IN OUT gcsHAL_INTERFACE_PTR Interface
  135196. + );
  135197. +
  135198. +/* Destroy a surface. */
  135199. +gceSTATUS
  135200. +gcoHAL_DestroySurface(
  135201. + IN gcoHAL Hal,
  135202. + IN gcoSURF Surface
  135203. + );
  135204. +
  135205. +/* Request a start/stop timestamp. */
  135206. +gceSTATUS
  135207. +gcoHAL_SetTimer(
  135208. + IN gcoHAL Hal,
  135209. + IN gctUINT32 Index,
  135210. + IN gctBOOL Start
  135211. + );
  135212. +
  135213. +/* Get Time delta from a Timer in microseconds. */
  135214. +gceSTATUS
  135215. +gcoHAL_GetTimerTime(
  135216. + IN gcoHAL Hal,
  135217. + IN gctUINT32 Timer,
  135218. + OUT gctINT32_PTR TimeDelta
  135219. + );
  135220. +
  135221. +/* set timeout value. */
  135222. +gceSTATUS
  135223. +gcoHAL_SetTimeOut(
  135224. + IN gcoHAL Hal,
  135225. + IN gctUINT32 timeOut
  135226. + );
  135227. +
  135228. +gceSTATUS
  135229. +gcoHAL_SetHardwareType(
  135230. + IN gcoHAL Hal,
  135231. + IN gceHARDWARE_TYPE HardwardType
  135232. + );
  135233. +
  135234. +gceSTATUS
  135235. +gcoHAL_GetHardwareType(
  135236. + IN gcoHAL Hal,
  135237. + OUT gceHARDWARE_TYPE * HardwardType
  135238. + );
  135239. +
  135240. +gceSTATUS
  135241. +gcoHAL_QueryChipCount(
  135242. + IN gcoHAL Hal,
  135243. + OUT gctINT32 * Count
  135244. + );
  135245. +
  135246. +gceSTATUS
  135247. +gcoHAL_QuerySeparated3D2D(
  135248. + IN gcoHAL Hal
  135249. + );
  135250. +
  135251. +gceSTATUS
  135252. +gcoHAL_QuerySpecialHint(
  135253. + IN gceSPECIAL_HINT Hint
  135254. + );
  135255. +
  135256. +gceSTATUS
  135257. +gcoHAL_SetSpecialHintData(
  135258. + IN gcoHARDWARE Hardware
  135259. + );
  135260. +
  135261. +/* Get pointer to gcoVG object. */
  135262. +gceSTATUS
  135263. +gcoHAL_GetVGEngine(
  135264. + IN gcoHAL Hal,
  135265. + OUT gcoVG * Engine
  135266. + );
  135267. +
  135268. +#if gcdENABLE_VG
  135269. +gceSTATUS
  135270. +gcoHAL_QueryChipLimits(
  135271. + IN gcoHAL Hal,
  135272. + IN gctINT32 Chip,
  135273. + OUT gcsHAL_LIMITS *Limits);
  135274. +
  135275. +gceSTATUS
  135276. +gcoHAL_QueryChipFeature(
  135277. + IN gcoHAL Hal,
  135278. + IN gctINT32 Chip,
  135279. + IN gceFEATURE Feature);
  135280. +
  135281. +#endif
  135282. +/******************************************************************************\
  135283. +********************************** gcoOS Object *********************************
  135284. +\******************************************************************************/
  135285. +
  135286. +/* Get PLS value for given key */
  135287. +gctPOINTER
  135288. +gcoOS_GetPLSValue(
  135289. + IN gcePLS_VALUE key
  135290. + );
  135291. +
  135292. +/* Set PLS value of a given key */
  135293. +void
  135294. +gcoOS_SetPLSValue(
  135295. + IN gcePLS_VALUE key,
  135296. + OUT gctPOINTER value
  135297. + );
  135298. +
  135299. +/* Get access to the thread local storage. */
  135300. +gceSTATUS
  135301. +gcoOS_GetTLS(
  135302. + OUT gcsTLS_PTR * TLS
  135303. + );
  135304. +
  135305. + /* Copy the TLS from a source thread. */
  135306. + gceSTATUS gcoOS_CopyTLS(IN gcsTLS_PTR Source);
  135307. +
  135308. +/* Destroy the objects associated with the current thread. */
  135309. +void
  135310. +gcoOS_FreeThreadData(
  135311. + IN gctBOOL ProcessExiting
  135312. + );
  135313. +
  135314. +/* Construct a new gcoOS object. */
  135315. +gceSTATUS
  135316. +gcoOS_Construct(
  135317. + IN gctPOINTER Context,
  135318. + OUT gcoOS * Os
  135319. + );
  135320. +
  135321. +/* Destroy an gcoOS object. */
  135322. +gceSTATUS
  135323. +gcoOS_Destroy(
  135324. + IN gcoOS Os
  135325. + );
  135326. +
  135327. +/* Get the base address for the physical memory. */
  135328. +gceSTATUS
  135329. +gcoOS_GetBaseAddress(
  135330. + IN gcoOS Os,
  135331. + OUT gctUINT32_PTR BaseAddress
  135332. + );
  135333. +
  135334. +/* Allocate memory from the heap. */
  135335. +gceSTATUS
  135336. +gcoOS_Allocate(
  135337. + IN gcoOS Os,
  135338. + IN gctSIZE_T Bytes,
  135339. + OUT gctPOINTER * Memory
  135340. + );
  135341. +
  135342. +/* Get allocated memory size. */
  135343. +gceSTATUS
  135344. +gcoOS_GetMemorySize(
  135345. + IN gcoOS Os,
  135346. + IN gctPOINTER Memory,
  135347. + OUT gctSIZE_T_PTR MemorySize
  135348. + );
  135349. +
  135350. +/* Free allocated memory. */
  135351. +gceSTATUS
  135352. +gcoOS_Free(
  135353. + IN gcoOS Os,
  135354. + IN gctPOINTER Memory
  135355. + );
  135356. +
  135357. +/* Allocate memory. */
  135358. +gceSTATUS
  135359. +gcoOS_AllocateMemory(
  135360. + IN gcoOS Os,
  135361. + IN gctSIZE_T Bytes,
  135362. + OUT gctPOINTER * Memory
  135363. + );
  135364. +
  135365. +/* Free memory. */
  135366. +gceSTATUS
  135367. +gcoOS_FreeMemory(
  135368. + IN gcoOS Os,
  135369. + IN gctPOINTER Memory
  135370. + );
  135371. +
  135372. +/* Allocate contiguous memory. */
  135373. +gceSTATUS
  135374. +gcoOS_AllocateContiguous(
  135375. + IN gcoOS Os,
  135376. + IN gctBOOL InUserSpace,
  135377. + IN OUT gctSIZE_T * Bytes,
  135378. + OUT gctPHYS_ADDR * Physical,
  135379. + OUT gctPOINTER * Logical
  135380. + );
  135381. +
  135382. +/* Free contiguous memory. */
  135383. +gceSTATUS
  135384. +gcoOS_FreeContiguous(
  135385. + IN gcoOS Os,
  135386. + IN gctPHYS_ADDR Physical,
  135387. + IN gctPOINTER Logical,
  135388. + IN gctSIZE_T Bytes
  135389. + );
  135390. +
  135391. +/* Allocate video memory. */
  135392. +gceSTATUS
  135393. +gcoOS_AllocateVideoMemory(
  135394. + IN gcoOS Os,
  135395. + IN gctBOOL InUserSpace,
  135396. + IN gctBOOL InCacheable,
  135397. + IN OUT gctSIZE_T * Bytes,
  135398. + OUT gctUINT32 * Physical,
  135399. + OUT gctPOINTER * Logical,
  135400. + OUT gctPOINTER * Handle
  135401. + );
  135402. +
  135403. +/* Free video memory. */
  135404. +gceSTATUS
  135405. +gcoOS_FreeVideoMemory(
  135406. + IN gcoOS Os,
  135407. + IN gctPOINTER Handle
  135408. + );
  135409. +
  135410. +gceSTATUS
  135411. +gcoSURF_GetBankOffsetBytes(
  135412. + IN gcoSURF Surfce,
  135413. + IN gceSURF_TYPE Type,
  135414. + IN gctUINT32 Stride,
  135415. + IN gctUINT32_PTR Bytes
  135416. + );
  135417. +
  135418. +/* Map user memory. */
  135419. +gceSTATUS
  135420. +gcoOS_MapUserMemory(
  135421. + IN gcoOS Os,
  135422. + IN gctPOINTER Memory,
  135423. + IN gctSIZE_T Size,
  135424. + OUT gctPOINTER * Info,
  135425. + OUT gctUINT32_PTR Address
  135426. + );
  135427. +
  135428. +/* Map user memory. */
  135429. +gceSTATUS
  135430. +gcoOS_MapUserMemoryEx(
  135431. + IN gcoOS Os,
  135432. + IN gctPOINTER Memory,
  135433. + IN gctUINT32 Physical,
  135434. + IN gctSIZE_T Size,
  135435. + OUT gctPOINTER * Info,
  135436. + OUT gctUINT32_PTR Address
  135437. + );
  135438. +
  135439. +/* Unmap user memory. */
  135440. +gceSTATUS
  135441. +gcoOS_UnmapUserMemory(
  135442. + IN gcoOS Os,
  135443. + IN gctPOINTER Memory,
  135444. + IN gctSIZE_T Size,
  135445. + IN gctPOINTER Info,
  135446. + IN gctUINT32 Address
  135447. + );
  135448. +
  135449. +/* Device I/O Control call to the kernel HAL layer. */
  135450. +gceSTATUS
  135451. +gcoOS_DeviceControl(
  135452. + IN gcoOS Os,
  135453. + IN gctUINT32 IoControlCode,
  135454. + IN gctPOINTER InputBuffer,
  135455. + IN gctSIZE_T InputBufferSize,
  135456. + IN gctPOINTER OutputBuffer,
  135457. + IN gctSIZE_T OutputBufferSize
  135458. + );
  135459. +
  135460. +/* Allocate non paged memory. */
  135461. +gceSTATUS
  135462. +gcoOS_AllocateNonPagedMemory(
  135463. + IN gcoOS Os,
  135464. + IN gctBOOL InUserSpace,
  135465. + IN OUT gctSIZE_T * Bytes,
  135466. + OUT gctPHYS_ADDR * Physical,
  135467. + OUT gctPOINTER * Logical
  135468. + );
  135469. +
  135470. +/* Free non paged memory. */
  135471. +gceSTATUS
  135472. +gcoOS_FreeNonPagedMemory(
  135473. + IN gcoOS Os,
  135474. + IN gctSIZE_T Bytes,
  135475. + IN gctPHYS_ADDR Physical,
  135476. + IN gctPOINTER Logical
  135477. + );
  135478. +
  135479. +#define gcmOS_SAFE_FREE(os, mem) \
  135480. + gcoOS_Free(os, mem); \
  135481. + mem = gcvNULL
  135482. +
  135483. +#define gcmkOS_SAFE_FREE(os, mem) \
  135484. + gckOS_Free(os, mem); \
  135485. + mem = gcvNULL
  135486. +
  135487. +typedef enum _gceFILE_MODE
  135488. +{
  135489. + gcvFILE_CREATE = 0,
  135490. + gcvFILE_APPEND,
  135491. + gcvFILE_READ,
  135492. + gcvFILE_CREATETEXT,
  135493. + gcvFILE_APPENDTEXT,
  135494. + gcvFILE_READTEXT,
  135495. +}
  135496. +gceFILE_MODE;
  135497. +
  135498. +/* Open a file. */
  135499. +gceSTATUS
  135500. +gcoOS_Open(
  135501. + IN gcoOS Os,
  135502. + IN gctCONST_STRING FileName,
  135503. + IN gceFILE_MODE Mode,
  135504. + OUT gctFILE * File
  135505. + );
  135506. +
  135507. +/* Close a file. */
  135508. +gceSTATUS
  135509. +gcoOS_Close(
  135510. + IN gcoOS Os,
  135511. + IN gctFILE File
  135512. + );
  135513. +
  135514. +/* Read data from a file. */
  135515. +gceSTATUS
  135516. +gcoOS_Read(
  135517. + IN gcoOS Os,
  135518. + IN gctFILE File,
  135519. + IN gctSIZE_T ByteCount,
  135520. + IN gctPOINTER Data,
  135521. + OUT gctSIZE_T * ByteRead
  135522. + );
  135523. +
  135524. +/* Write data to a file. */
  135525. +gceSTATUS
  135526. +gcoOS_Write(
  135527. + IN gcoOS Os,
  135528. + IN gctFILE File,
  135529. + IN gctSIZE_T ByteCount,
  135530. + IN gctCONST_POINTER Data
  135531. + );
  135532. +
  135533. +/* Flush data to a file. */
  135534. +gceSTATUS
  135535. +gcoOS_Flush(
  135536. + IN gcoOS Os,
  135537. + IN gctFILE File
  135538. + );
  135539. +
  135540. +/* Close a file descriptor. */
  135541. +gceSTATUS
  135542. +gcoOS_CloseFD(
  135543. + IN gcoOS Os,
  135544. + IN gctINT FD
  135545. + );
  135546. +
  135547. +/* Dup file descriptor to another. */
  135548. +gceSTATUS
  135549. +gcoOS_DupFD(
  135550. + IN gcoOS Os,
  135551. + IN gctINT FD,
  135552. + OUT gctINT * FD2
  135553. + );
  135554. +
  135555. +/* Create an endpoint for communication. */
  135556. +gceSTATUS
  135557. +gcoOS_Socket(
  135558. + IN gcoOS Os,
  135559. + IN gctINT Domain,
  135560. + IN gctINT Type,
  135561. + IN gctINT Protocol,
  135562. + OUT gctINT *SockFd
  135563. + );
  135564. +
  135565. +/* Close a socket. */
  135566. +gceSTATUS
  135567. +gcoOS_CloseSocket(
  135568. + IN gcoOS Os,
  135569. + IN gctINT SockFd
  135570. + );
  135571. +
  135572. +/* Initiate a connection on a socket. */
  135573. +gceSTATUS
  135574. +gcoOS_Connect(
  135575. + IN gcoOS Os,
  135576. + IN gctINT SockFd,
  135577. + IN gctCONST_POINTER HostName,
  135578. + IN gctUINT Port);
  135579. +
  135580. +/* Shut down part of connection on a socket. */
  135581. +gceSTATUS
  135582. +gcoOS_Shutdown(
  135583. + IN gcoOS Os,
  135584. + IN gctINT SockFd,
  135585. + IN gctINT How
  135586. + );
  135587. +
  135588. +/* Send a message on a socket. */
  135589. +gceSTATUS
  135590. +gcoOS_Send(
  135591. + IN gcoOS Os,
  135592. + IN gctINT SockFd,
  135593. + IN gctSIZE_T ByteCount,
  135594. + IN gctCONST_POINTER Data,
  135595. + IN gctINT Flags
  135596. + );
  135597. +
  135598. +/* Initiate a connection on a socket. */
  135599. +gceSTATUS
  135600. +gcoOS_WaitForSend(
  135601. + IN gcoOS Os,
  135602. + IN gctINT SockFd,
  135603. + IN gctINT Seconds,
  135604. + IN gctINT MicroSeconds);
  135605. +
  135606. +/* Get environment variable value. */
  135607. +gceSTATUS
  135608. +gcoOS_GetEnv(
  135609. + IN gcoOS Os,
  135610. + IN gctCONST_STRING VarName,
  135611. + OUT gctSTRING * Value
  135612. + );
  135613. +
  135614. +/* Set environment variable value. */
  135615. +gceSTATUS
  135616. +gcoOS_SetEnv(
  135617. + IN gcoOS Os,
  135618. + IN gctCONST_STRING VarName,
  135619. + IN gctSTRING Value
  135620. + );
  135621. +
  135622. +/* Get current working directory. */
  135623. +gceSTATUS
  135624. +gcoOS_GetCwd(
  135625. + IN gcoOS Os,
  135626. + IN gctINT SizeInBytes,
  135627. + OUT gctSTRING Buffer
  135628. + );
  135629. +
  135630. +/* Get file status info. */
  135631. +gceSTATUS
  135632. +gcoOS_Stat(
  135633. + IN gcoOS Os,
  135634. + IN gctCONST_STRING FileName,
  135635. + OUT gctPOINTER Buffer
  135636. + );
  135637. +
  135638. +typedef enum _gceFILE_WHENCE
  135639. +{
  135640. + gcvFILE_SEEK_SET,
  135641. + gcvFILE_SEEK_CUR,
  135642. + gcvFILE_SEEK_END
  135643. +}
  135644. +gceFILE_WHENCE;
  135645. +
  135646. +/* Set the current position of a file. */
  135647. +gceSTATUS
  135648. +gcoOS_Seek(
  135649. + IN gcoOS Os,
  135650. + IN gctFILE File,
  135651. + IN gctUINT32 Offset,
  135652. + IN gceFILE_WHENCE Whence
  135653. + );
  135654. +
  135655. +/* Set the current position of a file. */
  135656. +gceSTATUS
  135657. +gcoOS_SetPos(
  135658. + IN gcoOS Os,
  135659. + IN gctFILE File,
  135660. + IN gctUINT32 Position
  135661. + );
  135662. +
  135663. +/* Get the current position of a file. */
  135664. +gceSTATUS
  135665. +gcoOS_GetPos(
  135666. + IN gcoOS Os,
  135667. + IN gctFILE File,
  135668. + OUT gctUINT32 * Position
  135669. + );
  135670. +
  135671. +/* Same as strstr. */
  135672. +gceSTATUS
  135673. +gcoOS_StrStr(
  135674. + IN gctCONST_STRING String,
  135675. + IN gctCONST_STRING SubString,
  135676. + OUT gctSTRING * Output
  135677. + );
  135678. +
  135679. +/* Find the last occurance of a character inside a string. */
  135680. +gceSTATUS
  135681. +gcoOS_StrFindReverse(
  135682. + IN gctCONST_STRING String,
  135683. + IN gctINT8 Character,
  135684. + OUT gctSTRING * Output
  135685. + );
  135686. +
  135687. +gceSTATUS
  135688. +gcoOS_StrDup(
  135689. + IN gcoOS Os,
  135690. + IN gctCONST_STRING String,
  135691. + OUT gctSTRING * Target
  135692. + );
  135693. +
  135694. +/* Copy a string. */
  135695. +gceSTATUS
  135696. +gcoOS_StrCopySafe(
  135697. + IN gctSTRING Destination,
  135698. + IN gctSIZE_T DestinationSize,
  135699. + IN gctCONST_STRING Source
  135700. + );
  135701. +
  135702. +/* Append a string. */
  135703. +gceSTATUS
  135704. +gcoOS_StrCatSafe(
  135705. + IN gctSTRING Destination,
  135706. + IN gctSIZE_T DestinationSize,
  135707. + IN gctCONST_STRING Source
  135708. + );
  135709. +
  135710. +/* Compare two strings. */
  135711. +gceSTATUS
  135712. +gcoOS_StrCmp(
  135713. + IN gctCONST_STRING String1,
  135714. + IN gctCONST_STRING String2
  135715. + );
  135716. +
  135717. +/* Compare characters of two strings. */
  135718. +gceSTATUS
  135719. +gcoOS_StrNCmp(
  135720. + IN gctCONST_STRING String1,
  135721. + IN gctCONST_STRING String2,
  135722. + IN gctSIZE_T Count
  135723. + );
  135724. +
  135725. +/* Convert string to float. */
  135726. +gceSTATUS
  135727. +gcoOS_StrToFloat(
  135728. + IN gctCONST_STRING String,
  135729. + OUT gctFLOAT * Float
  135730. + );
  135731. +
  135732. +/* Convert hex string to integer. */
  135733. +gceSTATUS
  135734. +gcoOS_HexStrToInt(
  135735. + IN gctCONST_STRING String,
  135736. + OUT gctINT * Int
  135737. + );
  135738. +
  135739. +/* Convert hex string to float. */
  135740. +gceSTATUS
  135741. +gcoOS_HexStrToFloat(
  135742. + IN gctCONST_STRING String,
  135743. + OUT gctFLOAT * Float
  135744. + );
  135745. +
  135746. +/* Convert string to integer. */
  135747. +gceSTATUS
  135748. +gcoOS_StrToInt(
  135749. + IN gctCONST_STRING String,
  135750. + OUT gctINT * Int
  135751. + );
  135752. +
  135753. +gceSTATUS
  135754. +gcoOS_MemCmp(
  135755. + IN gctCONST_POINTER Memory1,
  135756. + IN gctCONST_POINTER Memory2,
  135757. + IN gctSIZE_T Bytes
  135758. + );
  135759. +
  135760. +gceSTATUS
  135761. +gcoOS_PrintStrSafe(
  135762. + OUT gctSTRING String,
  135763. + IN gctSIZE_T StringSize,
  135764. + IN OUT gctUINT * Offset,
  135765. + IN gctCONST_STRING Format,
  135766. + ...
  135767. + );
  135768. +
  135769. +gceSTATUS
  135770. +gcoOS_LoadLibrary(
  135771. + IN gcoOS Os,
  135772. + IN gctCONST_STRING Library,
  135773. + OUT gctHANDLE * Handle
  135774. + );
  135775. +
  135776. +gceSTATUS
  135777. +gcoOS_FreeLibrary(
  135778. + IN gcoOS Os,
  135779. + IN gctHANDLE Handle
  135780. + );
  135781. +
  135782. +gceSTATUS
  135783. +gcoOS_GetProcAddress(
  135784. + IN gcoOS Os,
  135785. + IN gctHANDLE Handle,
  135786. + IN gctCONST_STRING Name,
  135787. + OUT gctPOINTER * Function
  135788. + );
  135789. +
  135790. +gceSTATUS
  135791. +gcoOS_Compact(
  135792. + IN gcoOS Os
  135793. + );
  135794. +
  135795. +gceSTATUS
  135796. +gcoOS_AddSignalHandler (
  135797. + IN gceSignalHandlerType SignalHandlerType
  135798. + );
  135799. +
  135800. +#if VIVANTE_PROFILER
  135801. +gceSTATUS
  135802. +gcoOS_ProfileStart(
  135803. + IN gcoOS Os
  135804. + );
  135805. +
  135806. +gceSTATUS
  135807. +gcoOS_ProfileEnd(
  135808. + IN gcoOS Os,
  135809. + IN gctCONST_STRING Title
  135810. + );
  135811. +
  135812. +gceSTATUS
  135813. +gcoOS_SetProfileSetting(
  135814. + IN gcoOS Os,
  135815. + IN gctBOOL Enable,
  135816. + IN gctCONST_STRING FileName
  135817. + );
  135818. +#endif
  135819. +
  135820. +gctBOOL
  135821. +gcoOS_IsNeededSupportNP2Texture(
  135822. + IN gctCHAR* ProcName
  135823. + );
  135824. +
  135825. +/* Query the video memory. */
  135826. +gceSTATUS
  135827. +gcoOS_QueryVideoMemory(
  135828. + IN gcoOS Os,
  135829. + OUT gctPHYS_ADDR * InternalAddress,
  135830. + OUT gctSIZE_T * InternalSize,
  135831. + OUT gctPHYS_ADDR * ExternalAddress,
  135832. + OUT gctSIZE_T * ExternalSize,
  135833. + OUT gctPHYS_ADDR * ContiguousAddress,
  135834. + OUT gctSIZE_T * ContiguousSize
  135835. + );
  135836. +
  135837. +/* Detect if the process is the executable specified. */
  135838. +gceSTATUS
  135839. +gcoOS_DetectProcessByNamePid(
  135840. + IN gctCONST_STRING Name,
  135841. + IN gctHANDLE Pid
  135842. + );
  135843. +
  135844. +/* Detect if the current process is the executable specified. */
  135845. +gceSTATUS
  135846. +gcoOS_DetectProcessByName(
  135847. + IN gctCONST_STRING Name
  135848. + );
  135849. +
  135850. +gceSTATUS
  135851. +gcoOS_DetectProcessByEncryptedName(
  135852. + IN gctCONST_STRING Name
  135853. + );
  135854. +
  135855. +#if defined(ANDROID)
  135856. +gceSTATUS
  135857. +gcoOS_DetectProgrameByEncryptedSymbols(
  135858. + IN gcoOS_SymbolsList Symbols
  135859. + );
  135860. +#endif
  135861. +
  135862. +/*----------------------------------------------------------------------------*/
  135863. +/*----- Atoms ----------------------------------------------------------------*/
  135864. +
  135865. +/* Construct an atom. */
  135866. +gceSTATUS
  135867. +gcoOS_AtomConstruct(
  135868. + IN gcoOS Os,
  135869. + OUT gcsATOM_PTR * Atom
  135870. + );
  135871. +
  135872. +/* Destroy an atom. */
  135873. +gceSTATUS
  135874. +gcoOS_AtomDestroy(
  135875. + IN gcoOS Os,
  135876. + IN gcsATOM_PTR Atom
  135877. + );
  135878. +
  135879. +/* Increment an atom. */
  135880. +gceSTATUS
  135881. +gcoOS_AtomIncrement(
  135882. + IN gcoOS Os,
  135883. + IN gcsATOM_PTR Atom,
  135884. + OUT gctINT32_PTR OldValue
  135885. + );
  135886. +
  135887. +/* Decrement an atom. */
  135888. +gceSTATUS
  135889. +gcoOS_AtomDecrement(
  135890. + IN gcoOS Os,
  135891. + IN gcsATOM_PTR Atom,
  135892. + OUT gctINT32_PTR OldValue
  135893. + );
  135894. +
  135895. +gctHANDLE
  135896. +gcoOS_GetCurrentProcessID(
  135897. + void
  135898. + );
  135899. +
  135900. +gctHANDLE
  135901. +gcoOS_GetCurrentThreadID(
  135902. + void
  135903. + );
  135904. +
  135905. +/*----------------------------------------------------------------------------*/
  135906. +/*----- Time -----------------------------------------------------------------*/
  135907. +
  135908. +/* Get the number of milliseconds since the system started. */
  135909. +gctUINT32
  135910. +gcoOS_GetTicks(
  135911. + void
  135912. + );
  135913. +
  135914. +/* Get time in microseconds. */
  135915. +gceSTATUS
  135916. +gcoOS_GetTime(
  135917. + gctUINT64_PTR Time
  135918. + );
  135919. +
  135920. +/* Get CPU usage in microseconds. */
  135921. +gceSTATUS
  135922. +gcoOS_GetCPUTime(
  135923. + gctUINT64_PTR CPUTime
  135924. + );
  135925. +
  135926. +/* Get memory usage. */
  135927. +gceSTATUS
  135928. +gcoOS_GetMemoryUsage(
  135929. + gctUINT32_PTR MaxRSS,
  135930. + gctUINT32_PTR IxRSS,
  135931. + gctUINT32_PTR IdRSS,
  135932. + gctUINT32_PTR IsRSS
  135933. + );
  135934. +
  135935. +/* Delay a number of microseconds. */
  135936. +gceSTATUS
  135937. +gcoOS_Delay(
  135938. + IN gcoOS Os,
  135939. + IN gctUINT32 Delay
  135940. + );
  135941. +
  135942. +/*----------------------------------------------------------------------------*/
  135943. +/*----- Threads --------------------------------------------------------------*/
  135944. +
  135945. +#ifdef _WIN32
  135946. +/* Cannot include windows.h here becuase "near" and "far"
  135947. + * which are used in gcsDEPTH_INFO, are defined to nothing in WinDef.h.
  135948. + * So, use the real value of DWORD and WINAPI, instead.
  135949. + * DWORD is unsigned long, and WINAPI is __stdcall.
  135950. + * If these two are change in WinDef.h, the following two typdefs
  135951. + * need to be changed, too.
  135952. + */
  135953. +typedef unsigned long gctTHREAD_RETURN;
  135954. +typedef unsigned long (__stdcall * gcTHREAD_ROUTINE)(void * Argument);
  135955. +#else
  135956. +typedef void * gctTHREAD_RETURN;
  135957. +typedef void * (* gcTHREAD_ROUTINE)(void *);
  135958. +#endif
  135959. +
  135960. +/* Create a new thread. */
  135961. +gceSTATUS
  135962. +gcoOS_CreateThread(
  135963. + IN gcoOS Os,
  135964. + IN gcTHREAD_ROUTINE Worker,
  135965. + IN gctPOINTER Argument,
  135966. + OUT gctPOINTER * Thread
  135967. + );
  135968. +
  135969. +/* Close a thread. */
  135970. +gceSTATUS
  135971. +gcoOS_CloseThread(
  135972. + IN gcoOS Os,
  135973. + IN gctPOINTER Thread
  135974. + );
  135975. +
  135976. +/*----------------------------------------------------------------------------*/
  135977. +/*----- Mutexes --------------------------------------------------------------*/
  135978. +
  135979. +/* Create a new mutex. */
  135980. +gceSTATUS
  135981. +gcoOS_CreateMutex(
  135982. + IN gcoOS Os,
  135983. + OUT gctPOINTER * Mutex
  135984. + );
  135985. +
  135986. +/* Delete a mutex. */
  135987. +gceSTATUS
  135988. +gcoOS_DeleteMutex(
  135989. + IN gcoOS Os,
  135990. + IN gctPOINTER Mutex
  135991. + );
  135992. +
  135993. +/* Acquire a mutex. */
  135994. +gceSTATUS
  135995. +gcoOS_AcquireMutex(
  135996. + IN gcoOS Os,
  135997. + IN gctPOINTER Mutex,
  135998. + IN gctUINT32 Timeout
  135999. + );
  136000. +
  136001. +/* Release a mutex. */
  136002. +gceSTATUS
  136003. +gcoOS_ReleaseMutex(
  136004. + IN gcoOS Os,
  136005. + IN gctPOINTER Mutex
  136006. + );
  136007. +
  136008. +/*----------------------------------------------------------------------------*/
  136009. +/*----- Signals --------------------------------------------------------------*/
  136010. +
  136011. +/* Create a signal. */
  136012. +gceSTATUS
  136013. +gcoOS_CreateSignal(
  136014. + IN gcoOS Os,
  136015. + IN gctBOOL ManualReset,
  136016. + OUT gctSIGNAL * Signal
  136017. + );
  136018. +
  136019. +/* Destroy a signal. */
  136020. +gceSTATUS
  136021. +gcoOS_DestroySignal(
  136022. + IN gcoOS Os,
  136023. + IN gctSIGNAL Signal
  136024. + );
  136025. +
  136026. +/* Signal a signal. */
  136027. +gceSTATUS
  136028. +gcoOS_Signal(
  136029. + IN gcoOS Os,
  136030. + IN gctSIGNAL Signal,
  136031. + IN gctBOOL State
  136032. + );
  136033. +
  136034. +/* Wait for a signal. */
  136035. +gceSTATUS
  136036. +gcoOS_WaitSignal(
  136037. + IN gcoOS Os,
  136038. + IN gctSIGNAL Signal,
  136039. + IN gctUINT32 Wait
  136040. + );
  136041. +
  136042. +/* Map a signal from another process */
  136043. +gceSTATUS
  136044. +gcoOS_MapSignal(
  136045. + IN gctSIGNAL RemoteSignal,
  136046. + OUT gctSIGNAL * LocalSignal
  136047. + );
  136048. +
  136049. +/* Unmap a signal mapped from another process */
  136050. +gceSTATUS
  136051. +gcoOS_UnmapSignal(
  136052. + IN gctSIGNAL Signal
  136053. + );
  136054. +
  136055. +/*----------------------------------------------------------------------------*/
  136056. +/*----- Android Native Fence -------------------------------------------------*/
  136057. +
  136058. +/* Create sync point. */
  136059. +gceSTATUS
  136060. +gcoOS_CreateSyncPoint(
  136061. + IN gcoOS Os,
  136062. + OUT gctSYNC_POINT * SyncPoint
  136063. + );
  136064. +
  136065. +/* Destroy sync point. */
  136066. +gceSTATUS
  136067. +gcoOS_DestroySyncPoint(
  136068. + IN gcoOS Os,
  136069. + IN gctSYNC_POINT SyncPoint
  136070. + );
  136071. +
  136072. +/* Create native fence. */
  136073. +gceSTATUS
  136074. +gcoOS_CreateNativeFence(
  136075. + IN gcoOS Os,
  136076. + IN gctSYNC_POINT SyncPoint,
  136077. + OUT gctINT * FenceFD
  136078. + );
  136079. +
  136080. +/* Wait on native fence. */
  136081. +gceSTATUS
  136082. +gcoOS_WaitNativeFence(
  136083. + IN gcoOS Os,
  136084. + IN gctINT FenceFD,
  136085. + IN gctUINT32 Timeout
  136086. + );
  136087. +
  136088. +/*----------------------------------------------------------------------------*/
  136089. +/*----- Memory Access and Cache ----------------------------------------------*/
  136090. +
  136091. +/* Write a register. */
  136092. +gceSTATUS
  136093. +gcoOS_WriteRegister(
  136094. + IN gcoOS Os,
  136095. + IN gctUINT32 Address,
  136096. + IN gctUINT32 Data
  136097. + );
  136098. +
  136099. +/* Read a register. */
  136100. +gceSTATUS
  136101. +gcoOS_ReadRegister(
  136102. + IN gcoOS Os,
  136103. + IN gctUINT32 Address,
  136104. + OUT gctUINT32 * Data
  136105. + );
  136106. +
  136107. +gceSTATUS
  136108. +gcoOS_CacheClean(
  136109. + IN gcoOS Os,
  136110. + IN gctUINT64 Node,
  136111. + IN gctPOINTER Logical,
  136112. + IN gctSIZE_T Bytes
  136113. + );
  136114. +
  136115. +gceSTATUS
  136116. +gcoOS_CacheFlush(
  136117. + IN gcoOS Os,
  136118. + IN gctUINT64 Node,
  136119. + IN gctPOINTER Logical,
  136120. + IN gctSIZE_T Bytes
  136121. + );
  136122. +
  136123. +gceSTATUS
  136124. +gcoOS_CacheInvalidate(
  136125. + IN gcoOS Os,
  136126. + IN gctUINT64 Node,
  136127. + IN gctPOINTER Logical,
  136128. + IN gctSIZE_T Bytes
  136129. + );
  136130. +
  136131. +gceSTATUS
  136132. +gcoOS_MemoryBarrier(
  136133. + IN gcoOS Os,
  136134. + IN gctPOINTER Logical
  136135. + );
  136136. +
  136137. +
  136138. +/*----------------------------------------------------------------------------*/
  136139. +/*----- Profile --------------------------------------------------------------*/
  136140. +
  136141. +gceSTATUS
  136142. +gckOS_GetProfileTick(
  136143. + OUT gctUINT64_PTR Tick
  136144. + );
  136145. +
  136146. +gceSTATUS
  136147. +gckOS_QueryProfileTickRate(
  136148. + OUT gctUINT64_PTR TickRate
  136149. + );
  136150. +
  136151. +gctUINT32
  136152. +gckOS_ProfileToMS(
  136153. + IN gctUINT64 Ticks
  136154. + );
  136155. +
  136156. +gceSTATUS
  136157. +gcoOS_GetProfileTick(
  136158. + OUT gctUINT64_PTR Tick
  136159. + );
  136160. +
  136161. +gceSTATUS
  136162. +gcoOS_QueryProfileTickRate(
  136163. + OUT gctUINT64_PTR TickRate
  136164. + );
  136165. +
  136166. +#define _gcmPROFILE_INIT(prefix, freq, start) \
  136167. + do { \
  136168. + prefix ## OS_QueryProfileTickRate(&(freq)); \
  136169. + prefix ## OS_GetProfileTick(&(start)); \
  136170. + } while (gcvFALSE)
  136171. +
  136172. +#define _gcmPROFILE_QUERY(prefix, start, ticks) \
  136173. + do { \
  136174. + prefix ## OS_GetProfileTick(&(ticks)); \
  136175. + (ticks) = ((ticks) > (start)) ? ((ticks) - (start)) \
  136176. + : (~0ull - (start) + (ticks) + 1); \
  136177. + } while (gcvFALSE)
  136178. +
  136179. +#if gcdENABLE_PROFILING
  136180. +# define gcmkPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gck, freq, start)
  136181. +# define gcmkPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gck, start, ticks)
  136182. +# define gcmPROFILE_INIT(freq, start) _gcmPROFILE_INIT(gco, freq, start)
  136183. +# define gcmPROFILE_QUERY(start, ticks) _gcmPROFILE_QUERY(gco, start, ticks)
  136184. +# define gcmPROFILE_ONLY(x) x
  136185. +# define gcmPROFILE_ELSE(x) do { } while (gcvFALSE)
  136186. +# define gcmPROFILE_DECLARE_ONLY(x) x
  136187. +# define gcmPROFILE_DECLARE_ELSE(x) typedef x
  136188. +#else
  136189. +# define gcmkPROFILE_INIT(start, freq) do { } while (gcvFALSE)
  136190. +# define gcmkPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
  136191. +# define gcmPROFILE_INIT(start, freq) do { } while (gcvFALSE)
  136192. +# define gcmPROFILE_QUERY(start, ticks) do { } while (gcvFALSE)
  136193. +# define gcmPROFILE_ONLY(x) do { } while (gcvFALSE)
  136194. +# define gcmPROFILE_ELSE(x) x
  136195. +# define gcmPROFILE_DECLARE_ONLY(x) do { } while (gcvFALSE)
  136196. +# define gcmPROFILE_DECLARE_ELSE(x) x
  136197. +#endif
  136198. +
  136199. +/*******************************************************************************
  136200. +** gcoMATH object
  136201. +*/
  136202. +
  136203. +#define gcdPI 3.14159265358979323846f
  136204. +
  136205. +/* Kernel. */
  136206. +gctINT
  136207. +gckMATH_ModuloInt(
  136208. + IN gctINT X,
  136209. + IN gctINT Y
  136210. + );
  136211. +
  136212. +/* User. */
  136213. +gctUINT32
  136214. +gcoMATH_Log2in5dot5(
  136215. + IN gctINT X
  136216. + );
  136217. +
  136218. +
  136219. +gctFLOAT
  136220. +gcoMATH_UIntAsFloat(
  136221. + IN gctUINT32 X
  136222. + );
  136223. +
  136224. +gctUINT32
  136225. +gcoMATH_FloatAsUInt(
  136226. + IN gctFLOAT X
  136227. + );
  136228. +
  136229. +gctBOOL
  136230. +gcoMATH_CompareEqualF(
  136231. + IN gctFLOAT X,
  136232. + IN gctFLOAT Y
  136233. + );
  136234. +
  136235. +gctUINT16
  136236. +gcoMATH_UInt8AsFloat16(
  136237. + IN gctUINT8 X
  136238. + );
  136239. +
  136240. +/******************************************************************************\
  136241. +**************************** Coordinate Structures *****************************
  136242. +\******************************************************************************/
  136243. +
  136244. +typedef struct _gcsPOINT
  136245. +{
  136246. + gctINT32 x;
  136247. + gctINT32 y;
  136248. +}
  136249. +gcsPOINT;
  136250. +
  136251. +typedef struct _gcsSIZE
  136252. +{
  136253. + gctINT32 width;
  136254. + gctINT32 height;
  136255. +}
  136256. +gcsSIZE;
  136257. +
  136258. +typedef struct _gcsRECT
  136259. +{
  136260. + gctINT32 left;
  136261. + gctINT32 top;
  136262. + gctINT32 right;
  136263. + gctINT32 bottom;
  136264. +}
  136265. +gcsRECT;
  136266. +
  136267. +typedef union _gcsPIXEL
  136268. +{
  136269. + struct
  136270. + {
  136271. + gctFLOAT r, g, b, a;
  136272. + gctFLOAT d, s;
  136273. + } pf;
  136274. +
  136275. + struct
  136276. + {
  136277. + gctINT32 r, g, b, a;
  136278. + gctINT32 d, s;
  136279. + } pi;
  136280. +
  136281. + struct
  136282. + {
  136283. + gctUINT32 r, g, b, a;
  136284. + gctUINT32 d, s;
  136285. + } pui;
  136286. +
  136287. +} gcsPIXEL;
  136288. +
  136289. +
  136290. +/******************************************************************************\
  136291. +********************************* gcoSURF Object ********************************
  136292. +\******************************************************************************/
  136293. +
  136294. +/*----------------------------------------------------------------------------*/
  136295. +/*------------------------------- gcoSURF Common ------------------------------*/
  136296. +
  136297. +/* Color format classes. */
  136298. +typedef enum _gceFORMAT_CLASS
  136299. +{
  136300. + gcvFORMAT_CLASS_RGBA = 4500,
  136301. + gcvFORMAT_CLASS_YUV,
  136302. + gcvFORMAT_CLASS_INDEX,
  136303. + gcvFORMAT_CLASS_LUMINANCE,
  136304. + gcvFORMAT_CLASS_BUMP,
  136305. + gcvFORMAT_CLASS_DEPTH,
  136306. +}
  136307. +gceFORMAT_CLASS;
  136308. +
  136309. +/* Special enums for width field in gcsFORMAT_COMPONENT. */
  136310. +typedef enum _gceCOMPONENT_CONTROL
  136311. +{
  136312. + gcvCOMPONENT_NOTPRESENT = 0x00,
  136313. + gcvCOMPONENT_DONTCARE = 0x80,
  136314. + gcvCOMPONENT_WIDTHMASK = 0x7F,
  136315. + gcvCOMPONENT_ODD = 0x80
  136316. +}
  136317. +gceCOMPONENT_CONTROL;
  136318. +
  136319. +/* Color format component parameters. */
  136320. +typedef struct _gcsFORMAT_COMPONENT
  136321. +{
  136322. + gctUINT8 start;
  136323. + gctUINT8 width;
  136324. +}
  136325. +gcsFORMAT_COMPONENT;
  136326. +
  136327. +/* RGBA color format class. */
  136328. +typedef struct _gcsFORMAT_CLASS_TYPE_RGBA
  136329. +{
  136330. + gcsFORMAT_COMPONENT alpha;
  136331. + gcsFORMAT_COMPONENT red;
  136332. + gcsFORMAT_COMPONENT green;
  136333. + gcsFORMAT_COMPONENT blue;
  136334. +}
  136335. +gcsFORMAT_CLASS_TYPE_RGBA;
  136336. +
  136337. +/* YUV color format class. */
  136338. +typedef struct _gcsFORMAT_CLASS_TYPE_YUV
  136339. +{
  136340. + gcsFORMAT_COMPONENT y;
  136341. + gcsFORMAT_COMPONENT u;
  136342. + gcsFORMAT_COMPONENT v;
  136343. +}
  136344. +gcsFORMAT_CLASS_TYPE_YUV;
  136345. +
  136346. +/* Index color format class. */
  136347. +typedef struct _gcsFORMAT_CLASS_TYPE_INDEX
  136348. +{
  136349. + gcsFORMAT_COMPONENT value;
  136350. +}
  136351. +gcsFORMAT_CLASS_TYPE_INDEX;
  136352. +
  136353. +/* Luminance color format class. */
  136354. +typedef struct _gcsFORMAT_CLASS_TYPE_LUMINANCE
  136355. +{
  136356. + gcsFORMAT_COMPONENT alpha;
  136357. + gcsFORMAT_COMPONENT value;
  136358. +}
  136359. +gcsFORMAT_CLASS_TYPE_LUMINANCE;
  136360. +
  136361. +/* Bump map color format class. */
  136362. +typedef struct _gcsFORMAT_CLASS_TYPE_BUMP
  136363. +{
  136364. + gcsFORMAT_COMPONENT alpha;
  136365. + gcsFORMAT_COMPONENT l;
  136366. + gcsFORMAT_COMPONENT v;
  136367. + gcsFORMAT_COMPONENT u;
  136368. + gcsFORMAT_COMPONENT q;
  136369. + gcsFORMAT_COMPONENT w;
  136370. +}
  136371. +gcsFORMAT_CLASS_TYPE_BUMP;
  136372. +
  136373. +/* Depth and stencil format class. */
  136374. +typedef struct _gcsFORMAT_CLASS_TYPE_DEPTH
  136375. +{
  136376. + gcsFORMAT_COMPONENT depth;
  136377. + gcsFORMAT_COMPONENT stencil;
  136378. +}
  136379. +gcsFORMAT_CLASS_TYPE_DEPTH;
  136380. +
  136381. +/* Format parameters. */
  136382. +typedef struct _gcsSURF_FORMAT_INFO
  136383. +{
  136384. + /* Format code and class. */
  136385. + gceSURF_FORMAT format;
  136386. + gceFORMAT_CLASS fmtClass;
  136387. +
  136388. + /* The size of one pixel in bits. */
  136389. + gctUINT8 bitsPerPixel;
  136390. +
  136391. + /* Component swizzle. */
  136392. + gceSURF_SWIZZLE swizzle;
  136393. +
  136394. + /* Some formats have two neighbour pixels interleaved together. */
  136395. + /* To describe such format, set the flag to 1 and add another */
  136396. + /* like this one describing the odd pixel format. */
  136397. + gctUINT8 interleaved;
  136398. +
  136399. + /* Format components. */
  136400. + union
  136401. + {
  136402. + gcsFORMAT_CLASS_TYPE_BUMP bump;
  136403. + gcsFORMAT_CLASS_TYPE_RGBA rgba;
  136404. + gcsFORMAT_CLASS_TYPE_YUV yuv;
  136405. + gcsFORMAT_CLASS_TYPE_LUMINANCE lum;
  136406. + gcsFORMAT_CLASS_TYPE_INDEX index;
  136407. + gcsFORMAT_CLASS_TYPE_DEPTH depth;
  136408. + } u;
  136409. +}
  136410. +gcsSURF_FORMAT_INFO;
  136411. +
  136412. +/* Frame buffer information. */
  136413. +typedef struct _gcsSURF_FRAMEBUFFER
  136414. +{
  136415. + gctPOINTER logical;
  136416. + gctUINT width, height;
  136417. + gctINT stride;
  136418. + gceSURF_FORMAT format;
  136419. +}
  136420. +gcsSURF_FRAMEBUFFER;
  136421. +
  136422. +typedef struct _gcsVIDMEM_NODE_SHARED_INFO
  136423. +{
  136424. + gctBOOL tileStatusDisabled;
  136425. + gcsPOINT SrcOrigin;
  136426. + gcsPOINT DestOrigin;
  136427. + gcsSIZE RectSize;
  136428. + gctUINT32 clearValue;
  136429. +}
  136430. +gcsVIDMEM_NODE_SHARED_INFO;
  136431. +
  136432. +/* Generic pixel component descriptors. */
  136433. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XXX8;
  136434. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_XX8X;
  136435. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_X8XX;
  136436. +extern gcsFORMAT_COMPONENT gcvPIXEL_COMP_8XXX;
  136437. +
  136438. +typedef enum _gceORIENTATION
  136439. +{
  136440. + gcvORIENTATION_TOP_BOTTOM,
  136441. + gcvORIENTATION_BOTTOM_TOP,
  136442. +}
  136443. +gceORIENTATION;
  136444. +
  136445. +
  136446. +/* Construct a new gcoSURF object. */
  136447. +gceSTATUS
  136448. +gcoSURF_Construct(
  136449. + IN gcoHAL Hal,
  136450. + IN gctUINT Width,
  136451. + IN gctUINT Height,
  136452. + IN gctUINT Depth,
  136453. + IN gceSURF_TYPE Type,
  136454. + IN gceSURF_FORMAT Format,
  136455. + IN gcePOOL Pool,
  136456. + OUT gcoSURF * Surface
  136457. + );
  136458. +
  136459. +/* Destroy an gcoSURF object. */
  136460. +gceSTATUS
  136461. +gcoSURF_Destroy(
  136462. + IN gcoSURF Surface
  136463. + );
  136464. +
  136465. +/* Map user-allocated surface. */
  136466. +gceSTATUS
  136467. +gcoSURF_MapUserSurface(
  136468. + IN gcoSURF Surface,
  136469. + IN gctUINT Alignment,
  136470. + IN gctPOINTER Logical,
  136471. + IN gctUINT32 Physical
  136472. + );
  136473. +
  136474. +/* Query vid mem node info. */
  136475. +gceSTATUS
  136476. +gcoSURF_QueryVidMemNode(
  136477. + IN gcoSURF Surface,
  136478. + OUT gctUINT64 * Node,
  136479. + OUT gcePOOL * Pool,
  136480. + OUT gctUINT_PTR Bytes
  136481. + );
  136482. +
  136483. +/* Set the color type of the surface. */
  136484. +gceSTATUS
  136485. +gcoSURF_SetColorType(
  136486. + IN gcoSURF Surface,
  136487. + IN gceSURF_COLOR_TYPE ColorType
  136488. + );
  136489. +
  136490. +/* Get the color type of the surface. */
  136491. +gceSTATUS
  136492. +gcoSURF_GetColorType(
  136493. + IN gcoSURF Surface,
  136494. + OUT gceSURF_COLOR_TYPE *ColorType
  136495. + );
  136496. +
  136497. +/* Set the surface ration angle. */
  136498. +gceSTATUS
  136499. +gcoSURF_SetRotation(
  136500. + IN gcoSURF Surface,
  136501. + IN gceSURF_ROTATION Rotation
  136502. + );
  136503. +
  136504. +gceSTATUS
  136505. +gcoSURF_SetPreRotation(
  136506. + IN gcoSURF Surface,
  136507. + IN gceSURF_ROTATION Rotation
  136508. + );
  136509. +
  136510. +gceSTATUS
  136511. +gcoSURF_GetPreRotation(
  136512. + IN gcoSURF Surface,
  136513. + IN gceSURF_ROTATION *Rotation
  136514. + );
  136515. +
  136516. +gceSTATUS
  136517. +gcoSURF_IsValid(
  136518. + IN gcoSURF Surface
  136519. + );
  136520. +
  136521. +#ifndef VIVANTE_NO_3D
  136522. +/* Verify and return the state of the tile status mechanism. */
  136523. +gceSTATUS
  136524. +gcoSURF_IsTileStatusSupported(
  136525. + IN gcoSURF Surface
  136526. + );
  136527. +
  136528. +/* Process tile status for the specified surface. */
  136529. +gceSTATUS
  136530. +gcoSURF_SetTileStatus(
  136531. + IN gcoSURF Surface
  136532. + );
  136533. +
  136534. +/* Enable tile status for the specified surface. */
  136535. +gceSTATUS
  136536. +gcoSURF_EnableTileStatus(
  136537. + IN gcoSURF Surface
  136538. + );
  136539. +
  136540. +/* Disable tile status for the specified surface. */
  136541. +gceSTATUS
  136542. +gcoSURF_DisableTileStatus(
  136543. + IN gcoSURF Surface,
  136544. + IN gctBOOL Decompress
  136545. + );
  136546. +
  136547. +gceSTATUS
  136548. +gcoSURF_AlignResolveRect(
  136549. + IN gcoSURF Surf,
  136550. + IN gcsPOINT_PTR RectOrigin,
  136551. + IN gcsPOINT_PTR RectSize,
  136552. + OUT gcsPOINT_PTR AlignedOrigin,
  136553. + OUT gcsPOINT_PTR AlignedSize
  136554. + );
  136555. +#endif /* VIVANTE_NO_3D */
  136556. +
  136557. +/* Get surface size. */
  136558. +gceSTATUS
  136559. +gcoSURF_GetSize(
  136560. + IN gcoSURF Surface,
  136561. + OUT gctUINT * Width,
  136562. + OUT gctUINT * Height,
  136563. + OUT gctUINT * Depth
  136564. + );
  136565. +
  136566. +/* Get surface aligned sizes. */
  136567. +gceSTATUS
  136568. +gcoSURF_GetAlignedSize(
  136569. + IN gcoSURF Surface,
  136570. + OUT gctUINT * Width,
  136571. + OUT gctUINT * Height,
  136572. + OUT gctINT * Stride
  136573. + );
  136574. +
  136575. +/* Get alignments. */
  136576. +gceSTATUS
  136577. +gcoSURF_GetAlignment(
  136578. + IN gceSURF_TYPE Type,
  136579. + IN gceSURF_FORMAT Format,
  136580. + OUT gctUINT * AddressAlignment,
  136581. + OUT gctUINT * XAlignment,
  136582. + OUT gctUINT * YAlignment
  136583. + );
  136584. +
  136585. +/* Get surface type and format. */
  136586. +gceSTATUS
  136587. +gcoSURF_GetFormat(
  136588. + IN gcoSURF Surface,
  136589. + OUT gceSURF_TYPE * Type,
  136590. + OUT gceSURF_FORMAT * Format
  136591. + );
  136592. +
  136593. +/* Get surface tiling. */
  136594. +gceSTATUS
  136595. +gcoSURF_GetTiling(
  136596. + IN gcoSURF Surface,
  136597. + OUT gceTILING * Tiling
  136598. + );
  136599. +
  136600. +/* Lock the surface. */
  136601. +gceSTATUS
  136602. +gcoSURF_Lock(
  136603. + IN gcoSURF Surface,
  136604. + IN OUT gctUINT32 * Address,
  136605. + IN OUT gctPOINTER * Memory
  136606. + );
  136607. +
  136608. +/* Unlock the surface. */
  136609. +gceSTATUS
  136610. +gcoSURF_Unlock(
  136611. + IN gcoSURF Surface,
  136612. + IN gctPOINTER Memory
  136613. + );
  136614. +
  136615. +/* Return pixel format parameters. */
  136616. +gceSTATUS
  136617. +gcoSURF_QueryFormat(
  136618. + IN gceSURF_FORMAT Format,
  136619. + OUT gcsSURF_FORMAT_INFO_PTR * Info
  136620. + );
  136621. +
  136622. +/* Compute the color pixel mask. */
  136623. +gceSTATUS
  136624. +gcoSURF_ComputeColorMask(
  136625. + IN gcsSURF_FORMAT_INFO_PTR Format,
  136626. + OUT gctUINT32_PTR ColorMask
  136627. + );
  136628. +
  136629. +/* Flush the surface. */
  136630. +gceSTATUS
  136631. +gcoSURF_Flush(
  136632. + IN gcoSURF Surface
  136633. + );
  136634. +
  136635. +/* Fill surface from it's tile status buffer. */
  136636. +gceSTATUS
  136637. +gcoSURF_FillFromTile(
  136638. + IN gcoSURF Surface
  136639. + );
  136640. +
  136641. +/* Check if surface needs a filler. */
  136642. +gceSTATUS gcoSURF_NeedFiller(IN gcoSURF Surface);
  136643. +
  136644. +/* Fill surface with a value. */
  136645. +gceSTATUS
  136646. +gcoSURF_Fill(
  136647. + IN gcoSURF Surface,
  136648. + IN gcsPOINT_PTR Origin,
  136649. + IN gcsSIZE_PTR Size,
  136650. + IN gctUINT32 Value,
  136651. + IN gctUINT32 Mask
  136652. + );
  136653. +
  136654. +/* Alpha blend two surfaces together. */
  136655. +gceSTATUS
  136656. +gcoSURF_Blend(
  136657. + IN gcoSURF SrcSurface,
  136658. + IN gcoSURF DestSurface,
  136659. + IN gcsPOINT_PTR SrcOrig,
  136660. + IN gcsPOINT_PTR DestOrigin,
  136661. + IN gcsSIZE_PTR Size,
  136662. + IN gceSURF_BLEND_MODE Mode
  136663. + );
  136664. +
  136665. +/* Create a new gcoSURF wrapper object. */
  136666. +gceSTATUS
  136667. +gcoSURF_ConstructWrapper(
  136668. + IN gcoHAL Hal,
  136669. + OUT gcoSURF * Surface
  136670. + );
  136671. +
  136672. +/* Set the underlying buffer for the surface wrapper. */
  136673. +gceSTATUS
  136674. +gcoSURF_SetBuffer(
  136675. + IN gcoSURF Surface,
  136676. + IN gceSURF_TYPE Type,
  136677. + IN gceSURF_FORMAT Format,
  136678. + IN gctUINT Stride,
  136679. + IN gctPOINTER Logical,
  136680. + IN gctUINT32 Physical
  136681. + );
  136682. +
  136683. +/* Set the underlying video buffer for the surface wrapper. */
  136684. +gceSTATUS
  136685. +gcoSURF_SetVideoBuffer(
  136686. + IN gcoSURF Surface,
  136687. + IN gceSURF_TYPE Type,
  136688. + IN gceSURF_FORMAT Format,
  136689. + IN gctUINT Width,
  136690. + IN gctUINT Height,
  136691. + IN gctUINT Stride,
  136692. + IN gctPOINTER *LogicalPlane1,
  136693. + IN gctUINT32 *PhysicalPlane1
  136694. + );
  136695. +
  136696. +/* Set the size of the surface in pixels and map the underlying buffer. */
  136697. +gceSTATUS
  136698. +gcoSURF_SetWindow(
  136699. + IN gcoSURF Surface,
  136700. + IN gctUINT X,
  136701. + IN gctUINT Y,
  136702. + IN gctUINT Width,
  136703. + IN gctUINT Height
  136704. + );
  136705. +
  136706. +/* Set width/height alignment of the surface directly and calculate stride/size. This is only for dri backend now. Please be careful before use. */
  136707. +gceSTATUS
  136708. +gcoSURF_SetAlignment(
  136709. + IN gcoSURF Surface,
  136710. + IN gctUINT Width,
  136711. + IN gctUINT Height
  136712. + );
  136713. +
  136714. +/* Increase reference count of the surface. */
  136715. +gceSTATUS
  136716. +gcoSURF_ReferenceSurface(
  136717. + IN gcoSURF Surface
  136718. + );
  136719. +
  136720. +/* Get surface reference count. */
  136721. +gceSTATUS
  136722. +gcoSURF_QueryReferenceCount(
  136723. + IN gcoSURF Surface,
  136724. + OUT gctINT32 * ReferenceCount
  136725. + );
  136726. +
  136727. +/* Set surface orientation. */
  136728. +gceSTATUS
  136729. +gcoSURF_SetOrientation(
  136730. + IN gcoSURF Surface,
  136731. + IN gceORIENTATION Orientation
  136732. + );
  136733. +
  136734. +/* Query surface orientation. */
  136735. +gceSTATUS
  136736. +gcoSURF_QueryOrientation(
  136737. + IN gcoSURF Surface,
  136738. + OUT gceORIENTATION * Orientation
  136739. + );
  136740. +
  136741. +gceSTATUS
  136742. +gcoSURF_SetOffset(
  136743. + IN gcoSURF Surface,
  136744. + IN gctUINT Offset
  136745. + );
  136746. +
  136747. +gceSTATUS
  136748. +gcoSURF_GetOffset(
  136749. + IN gcoSURF Surface,
  136750. + OUT gctUINT *Offset
  136751. + );
  136752. +
  136753. +gceSTATUS
  136754. +gcoSURF_NODE_Cache(
  136755. + IN gcsSURF_NODE_PTR Node,
  136756. + IN gctPOINTER Logical,
  136757. + IN gctSIZE_T Bytes,
  136758. + IN gceCACHEOPERATION Operation
  136759. + );
  136760. +
  136761. +/* Perform CPU cache operation on surface */
  136762. +gceSTATUS
  136763. +gcoSURF_CPUCacheOperation(
  136764. + IN gcoSURF Surface,
  136765. + IN gceCACHEOPERATION Operation
  136766. + );
  136767. +
  136768. +
  136769. +gceSTATUS
  136770. +gcoSURF_SetLinearResolveAddress(
  136771. + IN gcoSURF Surface,
  136772. + IN gctUINT32 Address,
  136773. + IN gctPOINTER Memory
  136774. + );
  136775. +
  136776. + gceSTATUS
  136777. + gcoSURF_Swap(IN gcoSURF Surface1, IN gcoSURF Surface2);
  136778. +
  136779. +/******************************************************************************\
  136780. +********************************* gcoDUMP Object ********************************
  136781. +\******************************************************************************/
  136782. +
  136783. +/* Construct a new gcoDUMP object. */
  136784. +gceSTATUS
  136785. +gcoDUMP_Construct(
  136786. + IN gcoOS Os,
  136787. + IN gcoHAL Hal,
  136788. + OUT gcoDUMP * Dump
  136789. + );
  136790. +
  136791. +/* Destroy a gcoDUMP object. */
  136792. +gceSTATUS
  136793. +gcoDUMP_Destroy(
  136794. + IN gcoDUMP Dump
  136795. + );
  136796. +
  136797. +/* Enable/disable dumping. */
  136798. +gceSTATUS
  136799. +gcoDUMP_Control(
  136800. + IN gcoDUMP Dump,
  136801. + IN gctSTRING FileName
  136802. + );
  136803. +
  136804. +gceSTATUS
  136805. +gcoDUMP_IsEnabled(
  136806. + IN gcoDUMP Dump,
  136807. + OUT gctBOOL * Enabled
  136808. + );
  136809. +
  136810. +/* Add surface. */
  136811. +gceSTATUS
  136812. +gcoDUMP_AddSurface(
  136813. + IN gcoDUMP Dump,
  136814. + IN gctINT32 Width,
  136815. + IN gctINT32 Height,
  136816. + IN gceSURF_FORMAT PixelFormat,
  136817. + IN gctUINT32 Address,
  136818. + IN gctSIZE_T ByteCount
  136819. + );
  136820. +
  136821. +/* Mark the beginning of a frame. */
  136822. +gceSTATUS
  136823. +gcoDUMP_FrameBegin(
  136824. + IN gcoDUMP Dump
  136825. + );
  136826. +
  136827. +/* Mark the end of a frame. */
  136828. +gceSTATUS
  136829. +gcoDUMP_FrameEnd(
  136830. + IN gcoDUMP Dump
  136831. + );
  136832. +
  136833. +/* Dump data. */
  136834. +gceSTATUS
  136835. +gcoDUMP_DumpData(
  136836. + IN gcoDUMP Dump,
  136837. + IN gceDUMP_TAG Type,
  136838. + IN gctUINT32 Address,
  136839. + IN gctSIZE_T ByteCount,
  136840. + IN gctCONST_POINTER Data
  136841. + );
  136842. +
  136843. +/* Delete an address. */
  136844. +gceSTATUS
  136845. +gcoDUMP_Delete(
  136846. + IN gcoDUMP Dump,
  136847. + IN gctUINT32 Address
  136848. + );
  136849. +
  136850. +/* Enable dump or not. */
  136851. +gceSTATUS
  136852. +gcoDUMP_SetDumpFlag(
  136853. + IN gctBOOL DumpState
  136854. + );
  136855. +
  136856. +/******************************************************************************\
  136857. +******************************* gcsRECT Structure ******************************
  136858. +\******************************************************************************/
  136859. +
  136860. +/* Initialize rectangle structure. */
  136861. +gceSTATUS
  136862. +gcsRECT_Set(
  136863. + OUT gcsRECT_PTR Rect,
  136864. + IN gctINT32 Left,
  136865. + IN gctINT32 Top,
  136866. + IN gctINT32 Right,
  136867. + IN gctINT32 Bottom
  136868. + );
  136869. +
  136870. +/* Return the width of the rectangle. */
  136871. +gceSTATUS
  136872. +gcsRECT_Width(
  136873. + IN gcsRECT_PTR Rect,
  136874. + OUT gctINT32 * Width
  136875. + );
  136876. +
  136877. +/* Return the height of the rectangle. */
  136878. +gceSTATUS
  136879. +gcsRECT_Height(
  136880. + IN gcsRECT_PTR Rect,
  136881. + OUT gctINT32 * Height
  136882. + );
  136883. +
  136884. +/* Ensure that top left corner is to the left and above the right bottom. */
  136885. +gceSTATUS
  136886. +gcsRECT_Normalize(
  136887. + IN OUT gcsRECT_PTR Rect
  136888. + );
  136889. +
  136890. +/* Compare two rectangles. */
  136891. +gceSTATUS
  136892. +gcsRECT_IsEqual(
  136893. + IN gcsRECT_PTR Rect1,
  136894. + IN gcsRECT_PTR Rect2,
  136895. + OUT gctBOOL * Equal
  136896. + );
  136897. +
  136898. +/* Compare the sizes of two rectangles. */
  136899. +gceSTATUS
  136900. +gcsRECT_IsOfEqualSize(
  136901. + IN gcsRECT_PTR Rect1,
  136902. + IN gcsRECT_PTR Rect2,
  136903. + OUT gctBOOL * EqualSize
  136904. + );
  136905. +
  136906. +gceSTATUS
  136907. +gcsRECT_RelativeRotation(
  136908. + IN gceSURF_ROTATION Orientation,
  136909. + IN OUT gceSURF_ROTATION *Relation);
  136910. +
  136911. +gceSTATUS
  136912. +
  136913. +gcsRECT_Rotate(
  136914. +
  136915. + IN OUT gcsRECT_PTR Rect,
  136916. +
  136917. + IN gceSURF_ROTATION Rotation,
  136918. +
  136919. + IN gceSURF_ROTATION toRotation,
  136920. +
  136921. + IN gctINT32 SurfaceWidth,
  136922. +
  136923. + IN gctINT32 SurfaceHeight
  136924. +
  136925. + );
  136926. +
  136927. +/******************************************************************************\
  136928. +**************************** gcsBOUNDARY Structure *****************************
  136929. +\******************************************************************************/
  136930. +
  136931. +typedef struct _gcsBOUNDARY
  136932. +{
  136933. + gctINT x;
  136934. + gctINT y;
  136935. + gctINT width;
  136936. + gctINT height;
  136937. +}
  136938. +gcsBOUNDARY;
  136939. +
  136940. +/******************************************************************************\
  136941. +********************************* gcoHEAP Object ********************************
  136942. +\******************************************************************************/
  136943. +
  136944. +typedef struct _gcoHEAP * gcoHEAP;
  136945. +
  136946. +/* Construct a new gcoHEAP object. */
  136947. +gceSTATUS
  136948. +gcoHEAP_Construct(
  136949. + IN gcoOS Os,
  136950. + IN gctSIZE_T AllocationSize,
  136951. + OUT gcoHEAP * Heap
  136952. + );
  136953. +
  136954. +/* Destroy an gcoHEAP object. */
  136955. +gceSTATUS
  136956. +gcoHEAP_Destroy(
  136957. + IN gcoHEAP Heap
  136958. + );
  136959. +
  136960. +/* Allocate memory. */
  136961. +gceSTATUS
  136962. +gcoHEAP_Allocate(
  136963. + IN gcoHEAP Heap,
  136964. + IN gctSIZE_T Bytes,
  136965. + OUT gctPOINTER * Node
  136966. + );
  136967. +
  136968. +gceSTATUS
  136969. +gcoHEAP_GetMemorySize(
  136970. + IN gcoHEAP Heap,
  136971. + IN gctPOINTER Memory,
  136972. + OUT gctSIZE_T_PTR MemorySize
  136973. + );
  136974. +
  136975. +/* Free memory. */
  136976. +gceSTATUS
  136977. +gcoHEAP_Free(
  136978. + IN gcoHEAP Heap,
  136979. + IN gctPOINTER Node
  136980. + );
  136981. +
  136982. +#if (VIVANTE_PROFILER || gcdDEBUG)
  136983. +/* Profile the heap. */
  136984. +gceSTATUS
  136985. +gcoHEAP_ProfileStart(
  136986. + IN gcoHEAP Heap
  136987. + );
  136988. +
  136989. +gceSTATUS
  136990. +gcoHEAP_ProfileEnd(
  136991. + IN gcoHEAP Heap,
  136992. + IN gctCONST_STRING Title
  136993. + );
  136994. +#endif
  136995. +
  136996. +
  136997. +/******************************************************************************\
  136998. +******************************* Debugging Macros *******************************
  136999. +\******************************************************************************/
  137000. +
  137001. +void
  137002. +gcoOS_SetDebugLevel(
  137003. + IN gctUINT32 Level
  137004. + );
  137005. +
  137006. +void
  137007. +gcoOS_GetDebugLevel(
  137008. + OUT gctUINT32_PTR DebugLevel
  137009. + );
  137010. +
  137011. +void
  137012. +gcoOS_SetDebugZone(
  137013. + IN gctUINT32 Zone
  137014. + );
  137015. +
  137016. +void
  137017. +gcoOS_GetDebugZone(
  137018. + IN gctUINT32 Zone,
  137019. + OUT gctUINT32_PTR DebugZone
  137020. + );
  137021. +
  137022. +void
  137023. +gcoOS_SetDebugLevelZone(
  137024. + IN gctUINT32 Level,
  137025. + IN gctUINT32 Zone
  137026. + );
  137027. +
  137028. +void
  137029. +gcoOS_SetDebugZones(
  137030. + IN gctUINT32 Zones,
  137031. + IN gctBOOL Enable
  137032. + );
  137033. +
  137034. +void
  137035. +gcoOS_SetDebugFile(
  137036. + IN gctCONST_STRING FileName
  137037. + );
  137038. +
  137039. +gctFILE
  137040. +gcoOS_ReplaceDebugFile(
  137041. + IN gctFILE fp
  137042. + );
  137043. +
  137044. +/*******************************************************************************
  137045. +**
  137046. +** gcmFATAL
  137047. +**
  137048. +** Print a message to the debugger and execute a break point.
  137049. +**
  137050. +** ARGUMENTS:
  137051. +**
  137052. +** message Message.
  137053. +** ... Optional arguments.
  137054. +*/
  137055. +
  137056. +void
  137057. +gckOS_DebugFatal(
  137058. + IN gctCONST_STRING Message,
  137059. + ...
  137060. + );
  137061. +
  137062. +void
  137063. +gcoOS_DebugFatal(
  137064. + IN gctCONST_STRING Message,
  137065. + ...
  137066. + );
  137067. +
  137068. +#if gcmIS_DEBUG(gcdDEBUG_FATAL)
  137069. +# define gcmFATAL gcoOS_DebugFatal
  137070. +# define gcmkFATAL gckOS_DebugFatal
  137071. +#elif gcdHAS_ELLIPSES
  137072. +# define gcmFATAL(...)
  137073. +# define gcmkFATAL(...)
  137074. +#else
  137075. + gcmINLINE static void
  137076. + __dummy_fatal(
  137077. + IN gctCONST_STRING Message,
  137078. + ...
  137079. + )
  137080. + {
  137081. + }
  137082. +# define gcmFATAL __dummy_fatal
  137083. +# define gcmkFATAL __dummy_fatal
  137084. +#endif
  137085. +
  137086. +#define gcmENUM2TEXT(e) case e: return #e
  137087. +
  137088. +/*******************************************************************************
  137089. +**
  137090. +** gcmTRACE
  137091. +**
  137092. +** Print a message to the debugfer if the correct level has been set. In
  137093. +** retail mode this macro does nothing.
  137094. +**
  137095. +** ARGUMENTS:
  137096. +**
  137097. +** level Level of message.
  137098. +** message Message.
  137099. +** ... Optional arguments.
  137100. +*/
  137101. +#define gcvLEVEL_NONE -1
  137102. +#define gcvLEVEL_ERROR 0
  137103. +#define gcvLEVEL_WARNING 1
  137104. +#define gcvLEVEL_INFO 2
  137105. +#define gcvLEVEL_VERBOSE 3
  137106. +
  137107. +void
  137108. +gckOS_DebugTrace(
  137109. + IN gctUINT32 Level,
  137110. + IN gctCONST_STRING Message,
  137111. + ...
  137112. + );
  137113. +
  137114. +void
  137115. +gckOS_DebugTraceN(
  137116. + IN gctUINT32 Level,
  137117. + IN gctUINT ArgumentSize,
  137118. + IN gctCONST_STRING Message,
  137119. + ...
  137120. + );
  137121. +
  137122. +void
  137123. +gcoOS_DebugTrace(
  137124. + IN gctUINT32 Level,
  137125. + IN gctCONST_STRING Message,
  137126. + ...
  137127. + );
  137128. +
  137129. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  137130. +# define gcmTRACE gcoOS_DebugTrace
  137131. +# define gcmkTRACE gckOS_DebugTrace
  137132. +# define gcmkTRACE_N gckOS_DebugTraceN
  137133. +#elif gcdHAS_ELLIPSES
  137134. +# define gcmTRACE(...)
  137135. +# define gcmkTRACE(...)
  137136. +# define gcmkTRACE_N(...)
  137137. +#else
  137138. + gcmINLINE static void
  137139. + __dummy_trace(
  137140. + IN gctUINT32 Level,
  137141. + IN gctCONST_STRING Message,
  137142. + ...
  137143. + )
  137144. + {
  137145. + }
  137146. +
  137147. + gcmINLINE static void
  137148. + __dummy_trace_n(
  137149. + IN gctUINT32 Level,
  137150. + IN gctUINT ArgumentSize,
  137151. + IN gctCONST_STRING Message,
  137152. + ...
  137153. + )
  137154. + {
  137155. + }
  137156. +
  137157. +# define gcmTRACE __dummy_trace
  137158. +# define gcmkTRACE __dummy_trace
  137159. +# define gcmkTRACE_N __dummy_trace_n
  137160. +#endif
  137161. +
  137162. +/* Zones common for kernel and user. */
  137163. +#define gcvZONE_OS (1 << 0)
  137164. +#define gcvZONE_HARDWARE (1 << 1)
  137165. +#define gcvZONE_HEAP (1 << 2)
  137166. +#define gcvZONE_SIGNAL (1 << 27)
  137167. +
  137168. +/* Kernel zones. */
  137169. +#define gcvZONE_KERNEL (1 << 3)
  137170. +#define gcvZONE_VIDMEM (1 << 4)
  137171. +#define gcvZONE_COMMAND (1 << 5)
  137172. +#define gcvZONE_DRIVER (1 << 6)
  137173. +#define gcvZONE_CMODEL (1 << 7)
  137174. +#define gcvZONE_MMU (1 << 8)
  137175. +#define gcvZONE_EVENT (1 << 9)
  137176. +#define gcvZONE_DEVICE (1 << 10)
  137177. +#define gcvZONE_DATABASE (1 << 11)
  137178. +#define gcvZONE_INTERRUPT (1 << 12)
  137179. +#define gcvZONE_POWER (1 << 13)
  137180. +
  137181. +/* User zones. */
  137182. +#define gcvZONE_HAL (1 << 3)
  137183. +#define gcvZONE_BUFFER (1 << 4)
  137184. +#define gcvZONE_CONTEXT (1 << 5)
  137185. +#define gcvZONE_SURFACE (1 << 6)
  137186. +#define gcvZONE_INDEX (1 << 7)
  137187. +#define gcvZONE_STREAM (1 << 8)
  137188. +#define gcvZONE_TEXTURE (1 << 9)
  137189. +#define gcvZONE_2D (1 << 10)
  137190. +#define gcvZONE_3D (1 << 11)
  137191. +#define gcvZONE_COMPILER (1 << 12)
  137192. +#define gcvZONE_MEMORY (1 << 13)
  137193. +#define gcvZONE_STATE (1 << 14)
  137194. +#define gcvZONE_AUX (1 << 15)
  137195. +#define gcvZONE_VERTEX (1 << 16)
  137196. +#define gcvZONE_CL (1 << 17)
  137197. +#define gcvZONE_COMPOSITION (1 << 17)
  137198. +#define gcvZONE_VG (1 << 18)
  137199. +#define gcvZONE_IMAGE (1 << 19)
  137200. +#define gcvZONE_UTILITY (1 << 20)
  137201. +#define gcvZONE_PARAMETERS (1 << 21)
  137202. +
  137203. +/* API definitions. */
  137204. +#define gcvZONE_API_HAL (1 << 28)
  137205. +#define gcvZONE_API_EGL (2 << 28)
  137206. +#define gcvZONE_API_ES11 (3 << 28)
  137207. +#define gcvZONE_API_ES20 (4 << 28)
  137208. +#define gcvZONE_API_VG11 (5 << 28)
  137209. +#define gcvZONE_API_GL (6 << 28)
  137210. +#define gcvZONE_API_DFB (7 << 28)
  137211. +#define gcvZONE_API_GDI (8 << 28)
  137212. +#define gcvZONE_API_D3D (9 << 28)
  137213. +#define gcvZONE_API_ES30 (10 << 28)
  137214. +
  137215. +
  137216. +#define gcmZONE_GET_API(zone) ((zone) >> 28)
  137217. +/*Set gcdZONE_MASE like 0x0 | gcvZONE_API_EGL
  137218. +will enable print EGL module debug info*/
  137219. +#define gcdZONE_MASK 0x0FFFFFFF
  137220. +
  137221. +/* Handy zones. */
  137222. +#define gcvZONE_NONE 0
  137223. +#define gcvZONE_ALL 0x0FFFFFFF
  137224. +
  137225. +/*Dump API depth set 1 for API, 2 for API and API behavior*/
  137226. +#define gcvDUMP_API_DEPTH 1
  137227. +
  137228. +/*******************************************************************************
  137229. +**
  137230. +** gcmTRACE_ZONE
  137231. +**
  137232. +** Print a message to the debugger if the correct level and zone has been
  137233. +** set. In retail mode this macro does nothing.
  137234. +**
  137235. +** ARGUMENTS:
  137236. +**
  137237. +** Level Level of message.
  137238. +** Zone Zone of message.
  137239. +** Message Message.
  137240. +** ... Optional arguments.
  137241. +*/
  137242. +
  137243. +void
  137244. +gckOS_DebugTraceZone(
  137245. + IN gctUINT32 Level,
  137246. + IN gctUINT32 Zone,
  137247. + IN gctCONST_STRING Message,
  137248. + ...
  137249. + );
  137250. +
  137251. +void
  137252. +gckOS_DebugTraceZoneN(
  137253. + IN gctUINT32 Level,
  137254. + IN gctUINT32 Zone,
  137255. + IN gctUINT ArgumentSize,
  137256. + IN gctCONST_STRING Message,
  137257. + ...
  137258. + );
  137259. +
  137260. +void
  137261. +gcoOS_DebugTraceZone(
  137262. + IN gctUINT32 Level,
  137263. + IN gctUINT32 Zone,
  137264. + IN gctCONST_STRING Message,
  137265. + ...
  137266. + );
  137267. +
  137268. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  137269. +# define gcmTRACE_ZONE gcoOS_DebugTraceZone
  137270. +# define gcmkTRACE_ZONE gckOS_DebugTraceZone
  137271. +# define gcmkTRACE_ZONE_N gckOS_DebugTraceZoneN
  137272. +#elif gcdHAS_ELLIPSES
  137273. +# define gcmTRACE_ZONE(...)
  137274. +# define gcmkTRACE_ZONE(...)
  137275. +# define gcmkTRACE_ZONE_N(...)
  137276. +#else
  137277. + gcmINLINE static void
  137278. + __dummy_trace_zone(
  137279. + IN gctUINT32 Level,
  137280. + IN gctUINT32 Zone,
  137281. + IN gctCONST_STRING Message,
  137282. + ...
  137283. + )
  137284. + {
  137285. + }
  137286. +
  137287. + gcmINLINE static void
  137288. + __dummy_trace_zone_n(
  137289. + IN gctUINT32 Level,
  137290. + IN gctUINT32 Zone,
  137291. + IN gctUINT ArgumentSize,
  137292. + IN gctCONST_STRING Message,
  137293. + ...
  137294. + )
  137295. + {
  137296. + }
  137297. +
  137298. +# define gcmTRACE_ZONE __dummy_trace_zone
  137299. +# define gcmkTRACE_ZONE __dummy_trace_zone
  137300. +# define gcmkTRACE_ZONE_N __dummy_trace_zone_n
  137301. +#endif
  137302. +
  137303. +/*******************************************************************************
  137304. +**
  137305. +** gcmDEBUG_ONLY
  137306. +**
  137307. +** Execute a statement or function only in DEBUG mode.
  137308. +**
  137309. +** ARGUMENTS:
  137310. +**
  137311. +** f Statement or function to execute.
  137312. +*/
  137313. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  137314. +# define gcmDEBUG_ONLY(f) f
  137315. +#else
  137316. +# define gcmDEBUG_ONLY(f)
  137317. +#endif
  137318. +
  137319. +/*******************************************************************************
  137320. +**
  137321. +** gcmSTACK_PUSH
  137322. +** gcmSTACK_POP
  137323. +** gcmSTACK_DUMP
  137324. +**
  137325. +** Push or pop a function with entry arguments on the trace stack.
  137326. +**
  137327. +** ARGUMENTS:
  137328. +**
  137329. +** Function Name of function.
  137330. +** Line Line number.
  137331. +** Text Optional text.
  137332. +** ... Optional arguments for text.
  137333. +*/
  137334. +#if gcmIS_DEBUG(gcdDEBUG_STACK)
  137335. + void
  137336. + gcoOS_StackPush(
  137337. + IN gctCONST_STRING Function,
  137338. + IN gctINT Line,
  137339. + IN gctCONST_STRING Text,
  137340. + ...
  137341. + );
  137342. + void
  137343. + gcoOS_StackPop(
  137344. + IN gctCONST_STRING Function
  137345. + );
  137346. + void
  137347. + gcoOS_StackDump(
  137348. + void
  137349. + );
  137350. +# define gcmSTACK_PUSH gcoOS_StackPush
  137351. +# define gcmSTACK_POP gcoOS_StackPop
  137352. +# define gcmSTACK_DUMP gcoOS_StackDump
  137353. +#elif gcdHAS_ELLIPSES
  137354. +# define gcmSTACK_PUSH(...) do { } while (0)
  137355. +# define gcmSTACK_POP(Function) do { } while (0)
  137356. +# define gcmSTACK_DUMP() do { } while (0)
  137357. +#else
  137358. + gcmINLINE static void
  137359. + __dummy_stack_push(
  137360. + IN gctCONST_STRING Function,
  137361. + IN gctINT Line,
  137362. + IN gctCONST_STRING Text, ...
  137363. + )
  137364. + {
  137365. + }
  137366. +# define gcmSTACK_PUSH __dummy_stack_push
  137367. +# define gcmSTACK_POP(Function) do { } while (0)
  137368. +# define gcmSTACK_DUMP() do { } while (0)
  137369. +#endif
  137370. +
  137371. +/******************************************************************************\
  137372. +******************************** Logging Macros ********************************
  137373. +\******************************************************************************/
  137374. +
  137375. +#define gcdHEADER_LEVEL gcvLEVEL_VERBOSE
  137376. +
  137377. +
  137378. +#if gcdENABLE_PROFILING
  137379. +void
  137380. +gcoOS_ProfileDB(
  137381. + IN gctCONST_STRING Function,
  137382. + IN OUT gctBOOL_PTR Initialized
  137383. + );
  137384. +
  137385. +#define gcmHEADER() \
  137386. + static gctBOOL __profile__initialized__ = gcvFALSE; \
  137387. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
  137388. + gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
  137389. +#define gcmHEADER_ARG(...) \
  137390. + static gctBOOL __profile__initialized__ = gcvFALSE; \
  137391. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
  137392. + gcoOS_ProfileDB(__FUNCTION__, &__profile__initialized__)
  137393. +#define gcmFOOTER() \
  137394. + gcmSTACK_POP(__FUNCTION__); \
  137395. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  137396. +#define gcmFOOTER_NO() \
  137397. + gcmSTACK_POP(__FUNCTION__); \
  137398. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  137399. +#define gcmFOOTER_ARG(...) \
  137400. + gcmSTACK_POP(__FUNCTION__); \
  137401. + gcoOS_ProfileDB(__FUNCTION__, gcvNULL)
  137402. +#define gcmFOOTER_KILL() \
  137403. + gcmSTACK_POP(__FUNCTION__); \
  137404. + gcoOS_ProfileDB(gcvNULL, gcvNULL)
  137405. +
  137406. +#else /* gcdENABLE_PROFILING */
  137407. +
  137408. +#if gcdHAS_ELLIPSES
  137409. +#define gcmHEADER() \
  137410. + gctINT8 __user__ = 1; \
  137411. + gctINT8_PTR __user_ptr__ = &__user__; \
  137412. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, gcvNULL, gcvNULL); \
  137413. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137414. + "++%s(%d)", __FUNCTION__, __LINE__)
  137415. +#else
  137416. + gcmINLINE static void
  137417. + __dummy_header(void)
  137418. + {
  137419. + }
  137420. +# define gcmHEADER __dummy_header
  137421. +#endif
  137422. +
  137423. +#if gcdHAS_ELLIPSES
  137424. +# define gcmHEADER_ARG(Text, ...) \
  137425. + gctINT8 __user__ = 1; \
  137426. + gctINT8_PTR __user_ptr__ = &__user__; \
  137427. + gcmSTACK_PUSH(__FUNCTION__, __LINE__, Text, __VA_ARGS__); \
  137428. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137429. + "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
  137430. +#else
  137431. + gcmINLINE static void
  137432. + __dummy_header_arg(
  137433. + IN gctCONST_STRING Text,
  137434. + ...
  137435. + )
  137436. + {
  137437. + }
  137438. +# define gcmHEADER_ARG __dummy_header_arg
  137439. +#endif
  137440. +
  137441. +#if gcdHAS_ELLIPSES
  137442. +# define gcmFOOTER() \
  137443. + gcmSTACK_POP(__FUNCTION__); \
  137444. + gcmPROFILE_ONLY(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137445. + "--%s(%d) [%llu,%llu]: status=%d(%s)", \
  137446. + __FUNCTION__, __LINE__, \
  137447. + __ticks__, __total__, \
  137448. + status, gcoOS_DebugStatus2Name(status))); \
  137449. + gcmPROFILE_ELSE(gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137450. + "--%s(%d): status=%d(%s)", \
  137451. + __FUNCTION__, __LINE__, \
  137452. + status, gcoOS_DebugStatus2Name(status))); \
  137453. + *__user_ptr__ -= 1
  137454. +#else
  137455. + gcmINLINE static void
  137456. + __dummy_footer(void)
  137457. + {
  137458. + }
  137459. +# define gcmFOOTER __dummy_footer
  137460. +#endif
  137461. +
  137462. +#if gcdHAS_ELLIPSES
  137463. +#define gcmFOOTER_NO() \
  137464. + gcmSTACK_POP(__FUNCTION__); \
  137465. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137466. + "--%s(%d)", __FUNCTION__, __LINE__); \
  137467. + *__user_ptr__ -= 1
  137468. +#else
  137469. + gcmINLINE static void
  137470. + __dummy_footer_no(void)
  137471. + {
  137472. + }
  137473. +# define gcmFOOTER_NO __dummy_footer_no
  137474. +#endif
  137475. +
  137476. +#if gcdHAS_ELLIPSES
  137477. +#define gcmFOOTER_KILL() \
  137478. + gcmSTACK_POP(__FUNCTION__); \
  137479. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137480. + "--%s(%d)", __FUNCTION__, __LINE__); \
  137481. + *__user_ptr__ -= 1
  137482. +#else
  137483. + gcmINLINE static void
  137484. + __dummy_footer_kill(void)
  137485. + {
  137486. + }
  137487. +# define gcmFOOTER_KILL __dummy_footer_kill
  137488. +#endif
  137489. +
  137490. +#if gcdHAS_ELLIPSES
  137491. +# define gcmFOOTER_ARG(Text, ...) \
  137492. + gcmSTACK_POP(__FUNCTION__); \
  137493. + gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137494. + "--%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__); \
  137495. + *__user_ptr__ -= 1
  137496. +#else
  137497. + gcmINLINE static void
  137498. + __dummy_footer_arg(
  137499. + IN gctCONST_STRING Text,
  137500. + ...
  137501. + )
  137502. + {
  137503. + }
  137504. +# define gcmFOOTER_ARG __dummy_footer_arg
  137505. +#endif
  137506. +
  137507. +#endif /* gcdENABLE_PROFILING */
  137508. +
  137509. +#if gcdHAS_ELLIPSES
  137510. +#define gcmkHEADER() \
  137511. + gctINT8 __kernel__ = 1; \
  137512. + gctINT8_PTR __kernel_ptr__ = &__kernel__; \
  137513. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137514. + "++%s(%d)", __FUNCTION__, __LINE__)
  137515. +#else
  137516. + gcmINLINE static void
  137517. + __dummy_kheader(void)
  137518. + {
  137519. + }
  137520. +# define gcmkHEADER __dummy_kheader
  137521. +#endif
  137522. +
  137523. +#if gcdHAS_ELLIPSES
  137524. +# define gcmkHEADER_ARG(Text, ...) \
  137525. + gctINT8 __kernel__ = 1; \
  137526. + gctINT8_PTR __kernel_ptr__ = &__kernel__; \
  137527. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137528. + "++%s(%d): " Text, __FUNCTION__, __LINE__, __VA_ARGS__)
  137529. +#else
  137530. + gcmINLINE static void
  137531. + __dummy_kheader_arg(
  137532. + IN gctCONST_STRING Text,
  137533. + ...
  137534. + )
  137535. + {
  137536. + }
  137537. +# define gcmkHEADER_ARG __dummy_kheader_arg
  137538. +#endif
  137539. +
  137540. +#if gcdHAS_ELLIPSES
  137541. +#define gcmkFOOTER() \
  137542. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137543. + "--%s(%d): status=%d(%s)", \
  137544. + __FUNCTION__, __LINE__, status, gckOS_DebugStatus2Name(status)); \
  137545. + *__kernel_ptr__ -= 1
  137546. +#else
  137547. + gcmINLINE static void
  137548. + __dummy_kfooter(void)
  137549. + {
  137550. + }
  137551. +# define gcmkFOOTER __dummy_kfooter
  137552. +#endif
  137553. +
  137554. +#if gcdHAS_ELLIPSES
  137555. +#define gcmkFOOTER_NO() \
  137556. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137557. + "--%s(%d)", __FUNCTION__, __LINE__); \
  137558. + *__kernel_ptr__ -= 1
  137559. +#else
  137560. + gcmINLINE static void
  137561. + __dummy_kfooter_no(void)
  137562. + {
  137563. + }
  137564. +# define gcmkFOOTER_NO __dummy_kfooter_no
  137565. +#endif
  137566. +
  137567. +#if gcdHAS_ELLIPSES
  137568. +# define gcmkFOOTER_ARG(Text, ...) \
  137569. + gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
  137570. + "--%s(%d): " Text, \
  137571. + __FUNCTION__, __LINE__, __VA_ARGS__); \
  137572. + *__kernel_ptr__ -= 1
  137573. +#else
  137574. + gcmINLINE static void
  137575. + __dummy_kfooter_arg(
  137576. + IN gctCONST_STRING Text,
  137577. + ...
  137578. + )
  137579. + {
  137580. + }
  137581. +# define gcmkFOOTER_ARG __dummy_kfooter_arg
  137582. +#endif
  137583. +
  137584. +#define gcmOPT_VALUE(ptr) (((ptr) == gcvNULL) ? 0 : *(ptr))
  137585. +#define gcmOPT_VALUE_INDEX(ptr, index) (((ptr) == gcvNULL) ? 0 : ptr[index])
  137586. +#define gcmOPT_POINTER(ptr) (((ptr) == gcvNULL) ? gcvNULL : *(ptr))
  137587. +#define gcmOPT_STRING(ptr) (((ptr) == gcvNULL) ? "(nil)" : (ptr))
  137588. +
  137589. +void
  137590. +gckOS_Print(
  137591. + IN gctCONST_STRING Message,
  137592. + ...
  137593. + );
  137594. +
  137595. +void
  137596. +gckOS_PrintN(
  137597. + IN gctUINT ArgumentSize,
  137598. + IN gctCONST_STRING Message,
  137599. + ...
  137600. + );
  137601. +
  137602. +void
  137603. +gckOS_CopyPrint(
  137604. + IN gctCONST_STRING Message,
  137605. + ...
  137606. + );
  137607. +
  137608. +void
  137609. +gcoOS_Print(
  137610. + IN gctCONST_STRING Message,
  137611. + ...
  137612. + );
  137613. +
  137614. +#define gcmPRINT gcoOS_Print
  137615. +#define gcmkPRINT gckOS_Print
  137616. +#define gcmkPRINT_N gckOS_PrintN
  137617. +
  137618. +#if gcdPRINT_VERSION
  137619. +# define gcmPRINT_VERSION() do { \
  137620. + _gcmPRINT_VERSION(gcm); \
  137621. + gcmSTACK_DUMP(); \
  137622. + } while (0)
  137623. +# define gcmkPRINT_VERSION() _gcmPRINT_VERSION(gcmk)
  137624. +# define _gcmPRINT_VERSION(prefix) \
  137625. + prefix##TRACE(gcvLEVEL_ERROR, \
  137626. + "Vivante HAL version %d.%d.%d build %d %s %s", \
  137627. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, \
  137628. + gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME )
  137629. +#else
  137630. +# define gcmPRINT_VERSION() do { gcmSTACK_DUMP(); } while (gcvFALSE)
  137631. +# define gcmkPRINT_VERSION() do { } while (gcvFALSE)
  137632. +#endif
  137633. +
  137634. +typedef enum _gceDUMP_BUFFER
  137635. +{
  137636. + gceDUMP_BUFFER_CONTEXT,
  137637. + gceDUMP_BUFFER_USER,
  137638. + gceDUMP_BUFFER_KERNEL,
  137639. + gceDUMP_BUFFER_LINK,
  137640. + gceDUMP_BUFFER_WAITLINK,
  137641. + gceDUMP_BUFFER_FROM_USER,
  137642. +}
  137643. +gceDUMP_BUFFER;
  137644. +
  137645. +void
  137646. +gckOS_DumpBuffer(
  137647. + IN gckOS Os,
  137648. + IN gctPOINTER Buffer,
  137649. + IN gctUINT Size,
  137650. + IN gceDUMP_BUFFER Type,
  137651. + IN gctBOOL CopyMessage
  137652. + );
  137653. +
  137654. +#define gcmkDUMPBUFFER gckOS_DumpBuffer
  137655. +
  137656. +#if gcdDUMP_COMMAND
  137657. +# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage) \
  137658. + gcmkDUMPBUFFER(Os, Buffer, Size, Type, CopyMessage)
  137659. +#else
  137660. +# define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage)
  137661. +#endif
  137662. +
  137663. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  137664. +
  137665. +void
  137666. +gckOS_DebugFlush(
  137667. + gctCONST_STRING CallerName,
  137668. + gctUINT LineNumber,
  137669. + gctUINT32 DmaAddress
  137670. + );
  137671. +
  137672. +# define gcmkDEBUGFLUSH(DmaAddress) \
  137673. + gckOS_DebugFlush(__FUNCTION__, __LINE__, DmaAddress)
  137674. +#else
  137675. +# define gcmkDEBUGFLUSH(DmaAddress)
  137676. +#endif
  137677. +
  137678. +/*******************************************************************************
  137679. +**
  137680. +** gcmDUMP_FRAMERATE
  137681. +**
  137682. +** Print average frame rate
  137683. +**
  137684. +*/
  137685. +#if gcdDUMP_FRAMERATE
  137686. + gceSTATUS
  137687. + gcfDumpFrameRate(
  137688. + void
  137689. + );
  137690. +# define gcmDUMP_FRAMERATE gcfDumpFrameRate
  137691. +#elif gcdHAS_ELLIPSES
  137692. +# define gcmDUMP_FRAMERATE(...)
  137693. +#else
  137694. + gcmINLINE static void
  137695. + __dummy_dump_frame_rate(
  137696. + void
  137697. + )
  137698. + {
  137699. + }
  137700. +# define gcmDUMP_FRAMERATE __dummy_dump_frame_rate
  137701. +#endif
  137702. +
  137703. +
  137704. +/*******************************************************************************
  137705. +**
  137706. +** gcmDUMP
  137707. +**
  137708. +** Print a dump message.
  137709. +**
  137710. +** ARGUMENTS:
  137711. +**
  137712. +** gctSTRING Message.
  137713. +**
  137714. +** ... Optional arguments.
  137715. +*/
  137716. +#if gcdDUMP
  137717. + gceSTATUS
  137718. + gcfDump(
  137719. + IN gcoOS Os,
  137720. + IN gctCONST_STRING String,
  137721. + ...
  137722. + );
  137723. +# define gcmDUMP gcfDump
  137724. +#elif gcdHAS_ELLIPSES
  137725. +# define gcmDUMP(...)
  137726. +#else
  137727. + gcmINLINE static void
  137728. + __dummy_dump(
  137729. + IN gcoOS Os,
  137730. + IN gctCONST_STRING Message,
  137731. + ...
  137732. + )
  137733. + {
  137734. + }
  137735. +# define gcmDUMP __dummy_dump
  137736. +#endif
  137737. +
  137738. +/*******************************************************************************
  137739. +**
  137740. +** gcmDUMP_DATA
  137741. +**
  137742. +** Add data to the dump.
  137743. +**
  137744. +** ARGUMENTS:
  137745. +**
  137746. +** gctSTRING Tag
  137747. +** Tag for dump.
  137748. +**
  137749. +** gctPOINTER Logical
  137750. +** Logical address of buffer.
  137751. +**
  137752. +** gctSIZE_T Bytes
  137753. +** Number of bytes.
  137754. +*/
  137755. +
  137756. +#if gcdDUMP || gcdDUMP_COMMAND
  137757. + gceSTATUS
  137758. + gcfDumpData(
  137759. + IN gcoOS Os,
  137760. + IN gctSTRING Tag,
  137761. + IN gctPOINTER Logical,
  137762. + IN gctSIZE_T Bytes
  137763. + );
  137764. +# define gcmDUMP_DATA gcfDumpData
  137765. +#elif gcdHAS_ELLIPSES
  137766. +# define gcmDUMP_DATA(...)
  137767. +#else
  137768. + gcmINLINE static void
  137769. + __dummy_dump_data(
  137770. + IN gcoOS Os,
  137771. + IN gctSTRING Tag,
  137772. + IN gctPOINTER Logical,
  137773. + IN gctSIZE_T Bytes
  137774. + )
  137775. + {
  137776. + }
  137777. +# define gcmDUMP_DATA __dummy_dump_data
  137778. +#endif
  137779. +
  137780. +/*******************************************************************************
  137781. +**
  137782. +** gcmDUMP_BUFFER
  137783. +**
  137784. +** Print a buffer to the dump.
  137785. +**
  137786. +** ARGUMENTS:
  137787. +**
  137788. +** gctSTRING Tag
  137789. +** Tag for dump.
  137790. +**
  137791. +** gctUINT32 Physical
  137792. +** Physical address of buffer.
  137793. +**
  137794. +** gctPOINTER Logical
  137795. +** Logical address of buffer.
  137796. +**
  137797. +** gctUINT32 Offset
  137798. +** Offset into buffer.
  137799. +**
  137800. +** gctSIZE_T Bytes
  137801. +** Number of bytes.
  137802. +*/
  137803. +
  137804. +#if gcdDUMP || gcdDUMP_COMMAND
  137805. +gceSTATUS
  137806. +gcfDumpBuffer(
  137807. + IN gcoOS Os,
  137808. + IN gctSTRING Tag,
  137809. + IN gctUINT32 Physical,
  137810. + IN gctPOINTER Logical,
  137811. + IN gctUINT32 Offset,
  137812. + IN gctSIZE_T Bytes
  137813. + );
  137814. +# define gcmDUMP_BUFFER gcfDumpBuffer
  137815. +#elif gcdHAS_ELLIPSES
  137816. +# define gcmDUMP_BUFFER(...)
  137817. +#else
  137818. + gcmINLINE static void
  137819. + __dummy_dump_buffer(
  137820. + IN gcoOS Os,
  137821. + IN gctSTRING Tag,
  137822. + IN gctUINT32 Physical,
  137823. + IN gctPOINTER Logical,
  137824. + IN gctUINT32 Offset,
  137825. + IN gctSIZE_T Bytes
  137826. + )
  137827. + {
  137828. + }
  137829. +# define gcmDUMP_BUFFER __dummy_dump_buffer
  137830. +#endif
  137831. +
  137832. +/*******************************************************************************
  137833. +**
  137834. +** gcmDUMP_API
  137835. +**
  137836. +** Print a dump message for a high level API prefixed by the function name.
  137837. +**
  137838. +** ARGUMENTS:
  137839. +**
  137840. +** gctSTRING Message.
  137841. +**
  137842. +** ... Optional arguments.
  137843. +*/
  137844. +gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...);
  137845. +#if gcdDUMP_API
  137846. +# define gcmDUMP_API gcfDumpApi
  137847. +#elif gcdHAS_ELLIPSES
  137848. +# define gcmDUMP_API(...)
  137849. +#else
  137850. + gcmINLINE static void
  137851. + __dummy_dump_api(
  137852. + IN gctCONST_STRING Message,
  137853. + ...
  137854. + )
  137855. + {
  137856. + }
  137857. +# define gcmDUMP_API __dummy_dump_api
  137858. +#endif
  137859. +
  137860. +/*******************************************************************************
  137861. +**
  137862. +** gcmDUMP_API_ARRAY
  137863. +**
  137864. +** Print an array of data.
  137865. +**
  137866. +** ARGUMENTS:
  137867. +**
  137868. +** gctUINT32_PTR Pointer to array.
  137869. +** gctUINT32 Size.
  137870. +*/
  137871. +gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
  137872. +#if gcdDUMP_API
  137873. +# define gcmDUMP_API_ARRAY gcfDumpArray
  137874. +#elif gcdHAS_ELLIPSES
  137875. +# define gcmDUMP_API_ARRAY(...)
  137876. +#else
  137877. + gcmINLINE static void
  137878. + __dummy_dump_api_array(
  137879. + IN gctCONST_POINTER Data,
  137880. + IN gctUINT32 Size
  137881. + )
  137882. + {
  137883. + }
  137884. +# define gcmDUMP_API_ARRAY __dummy_dump_api_array
  137885. +#endif
  137886. +
  137887. +/*******************************************************************************
  137888. +**
  137889. +** gcmDUMP_API_ARRAY_TOKEN
  137890. +**
  137891. +** Print an array of data terminated by a token.
  137892. +**
  137893. +** ARGUMENTS:
  137894. +**
  137895. +** gctUINT32_PTR Pointer to array.
  137896. +** gctUINT32 Termination.
  137897. +*/
  137898. +gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
  137899. +#if gcdDUMP_API
  137900. +# define gcmDUMP_API_ARRAY_TOKEN gcfDumpArrayToken
  137901. +#elif gcdHAS_ELLIPSES
  137902. +# define gcmDUMP_API_ARRAY_TOKEN(...)
  137903. +#else
  137904. + gcmINLINE static void
  137905. + __dummy_dump_api_array_token(
  137906. + IN gctCONST_POINTER Data,
  137907. + IN gctUINT32 Termination
  137908. + )
  137909. + {
  137910. + }
  137911. +# define gcmDUMP_API_ARRAY_TOKEN __dummy_dump_api_array_token
  137912. +#endif
  137913. +
  137914. +/*******************************************************************************
  137915. +**
  137916. +** gcmDUMP_API_DATA
  137917. +**
  137918. +** Print an array of bytes.
  137919. +**
  137920. +** ARGUMENTS:
  137921. +**
  137922. +** gctCONST_POINTER Pointer to array.
  137923. +** gctSIZE_T Size.
  137924. +*/
  137925. +gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
  137926. +#if gcdDUMP_API
  137927. +# define gcmDUMP_API_DATA gcfDumpApiData
  137928. +#elif gcdHAS_ELLIPSES
  137929. +# define gcmDUMP_API_DATA(...)
  137930. +#else
  137931. + gcmINLINE static void
  137932. + __dummy_dump_api_data(
  137933. + IN gctCONST_POINTER Data,
  137934. + IN gctSIZE_T Size
  137935. + )
  137936. + {
  137937. + }
  137938. +# define gcmDUMP_API_DATA __dummy_dump_api_data
  137939. +#endif
  137940. +
  137941. +/*******************************************************************************
  137942. +**
  137943. +** gcmTRACE_RELEASE
  137944. +**
  137945. +** Print a message to the shader debugger.
  137946. +**
  137947. +** ARGUMENTS:
  137948. +**
  137949. +** message Message.
  137950. +** ... Optional arguments.
  137951. +*/
  137952. +
  137953. +#define gcmTRACE_RELEASE gcoOS_DebugShaderTrace
  137954. +
  137955. +void
  137956. +gcoOS_DebugShaderTrace(
  137957. + IN gctCONST_STRING Message,
  137958. + ...
  137959. + );
  137960. +
  137961. +void
  137962. +gcoOS_SetDebugShaderFiles(
  137963. + IN gctCONST_STRING VSFileName,
  137964. + IN gctCONST_STRING FSFileName
  137965. + );
  137966. +
  137967. +void
  137968. +gcoOS_SetDebugShaderFileType(
  137969. + IN gctUINT32 ShaderType
  137970. + );
  137971. +
  137972. +void
  137973. +gcoOS_EnableDebugBuffer(
  137974. + IN gctBOOL Enable
  137975. + );
  137976. +
  137977. +/*******************************************************************************
  137978. +**
  137979. +** gcmBREAK
  137980. +**
  137981. +** Break into the debugger. In retail mode this macro does nothing.
  137982. +**
  137983. +** ARGUMENTS:
  137984. +**
  137985. +** None.
  137986. +*/
  137987. +
  137988. +void
  137989. +gcoOS_DebugBreak(
  137990. + void
  137991. + );
  137992. +
  137993. +void
  137994. +gckOS_DebugBreak(
  137995. + void
  137996. + );
  137997. +
  137998. +#if gcmIS_DEBUG(gcdDEBUG_BREAK)
  137999. +# define gcmBREAK gcoOS_DebugBreak
  138000. +# define gcmkBREAK gckOS_DebugBreak
  138001. +#else
  138002. +# define gcmBREAK()
  138003. +# define gcmkBREAK()
  138004. +#endif
  138005. +
  138006. +/*******************************************************************************
  138007. +**
  138008. +** gcmASSERT
  138009. +**
  138010. +** Evaluate an expression and break into the debugger if the expression
  138011. +** evaluates to false. In retail mode this macro does nothing.
  138012. +**
  138013. +** ARGUMENTS:
  138014. +**
  138015. +** exp Expression to evaluate.
  138016. +*/
  138017. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  138018. +# define _gcmASSERT(prefix, exp) \
  138019. + do \
  138020. + { \
  138021. + if (!(exp)) \
  138022. + { \
  138023. + prefix##TRACE(gcvLEVEL_ERROR, \
  138024. + #prefix "ASSERT at %s(%d)", \
  138025. + __FUNCTION__, __LINE__); \
  138026. + prefix##TRACE(gcvLEVEL_ERROR, \
  138027. + "(%s)", #exp); \
  138028. + prefix##BREAK(); \
  138029. + } \
  138030. + } \
  138031. + while (gcvFALSE)
  138032. +# define gcmASSERT(exp) _gcmASSERT(gcm, exp)
  138033. +# define gcmkASSERT(exp) _gcmASSERT(gcmk, exp)
  138034. +#else
  138035. +# define gcmASSERT(exp)
  138036. +# define gcmkASSERT(exp)
  138037. +#endif
  138038. +
  138039. +/*******************************************************************************
  138040. +**
  138041. +** gcmVERIFY
  138042. +**
  138043. +** Verify if an expression returns true. If the expression does not
  138044. +** evaluates to true, an assertion will happen in debug mode.
  138045. +**
  138046. +** ARGUMENTS:
  138047. +**
  138048. +** exp Expression to evaluate.
  138049. +*/
  138050. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  138051. +# define gcmVERIFY(exp) gcmASSERT(exp)
  138052. +# define gcmkVERIFY(exp) gcmkASSERT(exp)
  138053. +#else
  138054. +# define gcmVERIFY(exp) exp
  138055. +# define gcmkVERIFY(exp) exp
  138056. +#endif
  138057. +
  138058. +/*******************************************************************************
  138059. +**
  138060. +** gcmVERIFY_OK
  138061. +**
  138062. +** Verify a fucntion returns gcvSTATUS_OK. If the function does not return
  138063. +** gcvSTATUS_OK, an assertion will happen in debug mode.
  138064. +**
  138065. +** ARGUMENTS:
  138066. +**
  138067. +** func Function to evaluate.
  138068. +*/
  138069. +
  138070. +void
  138071. +gcoOS_Verify(
  138072. + IN gceSTATUS status
  138073. + );
  138074. +
  138075. +void
  138076. +gckOS_Verify(
  138077. + IN gceSTATUS status
  138078. + );
  138079. +
  138080. +#if gcmIS_DEBUG(gcdDEBUG_ASSERT)
  138081. +# define gcmVERIFY_OK(func) \
  138082. + do \
  138083. + { \
  138084. + gceSTATUS verifyStatus = func; \
  138085. + gcoOS_Verify(verifyStatus); \
  138086. + if (verifyStatus != gcvSTATUS_OK) \
  138087. + { \
  138088. + gcmTRACE( \
  138089. + gcvLEVEL_ERROR, \
  138090. + "gcmVERIFY_OK(%d): function returned %d", \
  138091. + __LINE__, verifyStatus \
  138092. + ); \
  138093. + } \
  138094. + gcmASSERT(verifyStatus == gcvSTATUS_OK); \
  138095. + } \
  138096. + while (gcvFALSE)
  138097. +# define gcmkVERIFY_OK(func) \
  138098. + do \
  138099. + { \
  138100. + gceSTATUS verifyStatus = func; \
  138101. + if (verifyStatus != gcvSTATUS_OK) \
  138102. + { \
  138103. + gcmkTRACE( \
  138104. + gcvLEVEL_ERROR, \
  138105. + "gcmkVERIFY_OK(%d): function returned %d", \
  138106. + __LINE__, verifyStatus \
  138107. + ); \
  138108. + } \
  138109. + gckOS_Verify(verifyStatus); \
  138110. + gcmkASSERT(verifyStatus == gcvSTATUS_OK); \
  138111. + } \
  138112. + while (gcvFALSE)
  138113. +#else
  138114. +# define gcmVERIFY_OK(func) func
  138115. +# define gcmkVERIFY_OK(func) func
  138116. +#endif
  138117. +
  138118. +gctCONST_STRING
  138119. +gcoOS_DebugStatus2Name(
  138120. + gceSTATUS status
  138121. + );
  138122. +
  138123. +gctCONST_STRING
  138124. +gckOS_DebugStatus2Name(
  138125. + gceSTATUS status
  138126. + );
  138127. +
  138128. +/*******************************************************************************
  138129. +**
  138130. +** gcmERR_BREAK
  138131. +**
  138132. +** Executes a break statement on error.
  138133. +**
  138134. +** ASSUMPTIONS:
  138135. +**
  138136. +** 'status' variable of gceSTATUS type must be defined.
  138137. +**
  138138. +** ARGUMENTS:
  138139. +**
  138140. +** func Function to evaluate.
  138141. +*/
  138142. +#define _gcmERR_BREAK(prefix, func) \
  138143. + status = func; \
  138144. + if (gcmIS_ERROR(status)) \
  138145. + { \
  138146. + prefix##PRINT_VERSION(); \
  138147. + prefix##TRACE(gcvLEVEL_ERROR, \
  138148. + #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
  138149. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  138150. + break; \
  138151. + } \
  138152. + do { } while (gcvFALSE)
  138153. +#define _gcmkERR_BREAK(prefix, func) \
  138154. + status = func; \
  138155. + if (gcmIS_ERROR(status)) \
  138156. + { \
  138157. + prefix##PRINT_VERSION(); \
  138158. + prefix##TRACE(gcvLEVEL_ERROR, \
  138159. + #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
  138160. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  138161. + break; \
  138162. + } \
  138163. + do { } while (gcvFALSE)
  138164. +#define gcmERR_BREAK(func) _gcmERR_BREAK(gcm, func)
  138165. +#define gcmkERR_BREAK(func) _gcmkERR_BREAK(gcmk, func)
  138166. +
  138167. +/*******************************************************************************
  138168. +**
  138169. +** gcmERR_RETURN
  138170. +**
  138171. +** Executes a return on error.
  138172. +**
  138173. +** ASSUMPTIONS:
  138174. +**
  138175. +** 'status' variable of gceSTATUS type must be defined.
  138176. +**
  138177. +** ARGUMENTS:
  138178. +**
  138179. +** func Function to evaluate.
  138180. +*/
  138181. +#define _gcmERR_RETURN(prefix, func) \
  138182. + status = func; \
  138183. + if (gcmIS_ERROR(status)) \
  138184. + { \
  138185. + prefix##PRINT_VERSION(); \
  138186. + prefix##TRACE(gcvLEVEL_ERROR, \
  138187. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  138188. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  138189. + prefix##FOOTER(); \
  138190. + return status; \
  138191. + } \
  138192. + do { } while (gcvFALSE)
  138193. +#define _gcmkERR_RETURN(prefix, func) \
  138194. + status = func; \
  138195. + if (gcmIS_ERROR(status)) \
  138196. + { \
  138197. + prefix##PRINT_VERSION(); \
  138198. + prefix##TRACE(gcvLEVEL_ERROR, \
  138199. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  138200. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  138201. + prefix##FOOTER(); \
  138202. + return status; \
  138203. + } \
  138204. + do { } while (gcvFALSE)
  138205. +#define gcmERR_RETURN(func) _gcmERR_RETURN(gcm, func)
  138206. +#define gcmkERR_RETURN(func) _gcmkERR_RETURN(gcmk, func)
  138207. +
  138208. +
  138209. +/*******************************************************************************
  138210. +**
  138211. +** gcmONERROR
  138212. +**
  138213. +** Jump to the error handler in case there is an error.
  138214. +**
  138215. +** ASSUMPTIONS:
  138216. +**
  138217. +** 'status' variable of gceSTATUS type must be defined.
  138218. +**
  138219. +** ARGUMENTS:
  138220. +**
  138221. +** func Function to evaluate.
  138222. +*/
  138223. +#define _gcmONERROR(prefix, func) \
  138224. + do \
  138225. + { \
  138226. + status = func; \
  138227. + if (gcmIS_ERROR(status)) \
  138228. + { \
  138229. + prefix##PRINT_VERSION(); \
  138230. + prefix##TRACE(gcvLEVEL_ERROR, \
  138231. + #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
  138232. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  138233. + goto OnError; \
  138234. + } \
  138235. + } \
  138236. + while (gcvFALSE)
  138237. +#define _gcmkONERROR(prefix, func) \
  138238. + do \
  138239. + { \
  138240. + status = func; \
  138241. + if (gcmIS_ERROR(status)) \
  138242. + { \
  138243. + prefix##PRINT_VERSION(); \
  138244. + prefix##TRACE(gcvLEVEL_ERROR, \
  138245. + #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
  138246. + status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  138247. + goto OnError; \
  138248. + } \
  138249. + } \
  138250. + while (gcvFALSE)
  138251. +#define gcmONERROR(func) _gcmONERROR(gcm, func)
  138252. +#define gcmkONERROR(func) _gcmkONERROR(gcmk, func)
  138253. +
  138254. +/*******************************************************************************
  138255. +**
  138256. +** gcmVERIFY_LOCK
  138257. +**
  138258. +** Verifies whether the surface is locked.
  138259. +**
  138260. +** ARGUMENTS:
  138261. +**
  138262. +** surfaceInfo Pointer to the surface iniformational structure.
  138263. +*/
  138264. +#define gcmVERIFY_LOCK(surfaceInfo) \
  138265. + if (!surfaceInfo->node.valid) \
  138266. + { \
  138267. + gcmONERROR(gcvSTATUS_MEMORY_UNLOCKED); \
  138268. + } \
  138269. +
  138270. +/*******************************************************************************
  138271. +**
  138272. +** gcmVERIFY_NODE_LOCK
  138273. +**
  138274. +** Verifies whether the surface node is locked.
  138275. +**
  138276. +** ARGUMENTS:
  138277. +**
  138278. +** surfaceInfo Pointer to the surface iniformational structure.
  138279. +*/
  138280. +#define gcmVERIFY_NODE_LOCK(surfaceNode) \
  138281. + if (!(surfaceNode)->valid) \
  138282. + { \
  138283. + status = gcvSTATUS_MEMORY_UNLOCKED; \
  138284. + break; \
  138285. + } \
  138286. + do { } while (gcvFALSE)
  138287. +
  138288. +/*******************************************************************************
  138289. +**
  138290. +** gcmBADOBJECT_BREAK
  138291. +**
  138292. +** Executes a break statement on bad object.
  138293. +**
  138294. +** ARGUMENTS:
  138295. +**
  138296. +** obj Object to test.
  138297. +** t Expected type of the object.
  138298. +*/
  138299. +#define gcmBADOBJECT_BREAK(obj, t) \
  138300. + if ((obj == gcvNULL) \
  138301. + || (((gcsOBJECT *)(obj))->type != t) \
  138302. + ) \
  138303. + { \
  138304. + status = gcvSTATUS_INVALID_OBJECT; \
  138305. + break; \
  138306. + } \
  138307. + do { } while (gcvFALSE)
  138308. +
  138309. +/*******************************************************************************
  138310. +**
  138311. +** gcmCHECK_STATUS
  138312. +**
  138313. +** Executes a break statement on error.
  138314. +**
  138315. +** ASSUMPTIONS:
  138316. +**
  138317. +** 'status' variable of gceSTATUS type must be defined.
  138318. +**
  138319. +** ARGUMENTS:
  138320. +**
  138321. +** func Function to evaluate.
  138322. +*/
  138323. +#define _gcmCHECK_STATUS(prefix, func) \
  138324. + do \
  138325. + { \
  138326. + last = func; \
  138327. + if (gcmIS_ERROR(last)) \
  138328. + { \
  138329. + prefix##TRACE(gcvLEVEL_ERROR, \
  138330. + #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
  138331. + last, gcoOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
  138332. + status = last; \
  138333. + } \
  138334. + } \
  138335. + while (gcvFALSE)
  138336. +#define _gcmkCHECK_STATUS(prefix, func) \
  138337. + do \
  138338. + { \
  138339. + last = func; \
  138340. + if (gcmIS_ERROR(last)) \
  138341. + { \
  138342. + prefix##TRACE(gcvLEVEL_ERROR, \
  138343. + #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
  138344. + last, gckOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
  138345. + status = last; \
  138346. + } \
  138347. + } \
  138348. + while (gcvFALSE)
  138349. +#define gcmCHECK_STATUS(func) _gcmCHECK_STATUS(gcm, func)
  138350. +#define gcmkCHECK_STATUS(func) _gcmkCHECK_STATUS(gcmk, func)
  138351. +
  138352. +/*******************************************************************************
  138353. +**
  138354. +** gcmVERIFY_ARGUMENT
  138355. +**
  138356. +** Assert if an argument does not apply to the specified expression. If
  138357. +** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
  138358. +** returned from the current function. In retail mode this macro does
  138359. +** nothing.
  138360. +**
  138361. +** ARGUMENTS:
  138362. +**
  138363. +** arg Argument to evaluate.
  138364. +*/
  138365. +# define _gcmVERIFY_ARGUMENT(prefix, arg) \
  138366. + do \
  138367. + { \
  138368. + if (!(arg)) \
  138369. + { \
  138370. + prefix##TRACE(gcvLEVEL_ERROR, #prefix "VERIFY_ARGUMENT failed:"); \
  138371. + prefix##ASSERT(arg); \
  138372. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT); \
  138373. + return gcvSTATUS_INVALID_ARGUMENT; \
  138374. + } \
  138375. + } \
  138376. + while (gcvFALSE)
  138377. +# define gcmVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
  138378. +# define gcmkVERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcmk, arg)
  138379. +
  138380. +/*******************************************************************************
  138381. +**
  138382. +** gcmDEBUG_VERIFY_ARGUMENT
  138383. +**
  138384. +** Works just like gcmVERIFY_ARGUMENT, but is only valid in debug mode.
  138385. +** Use this to verify arguments inside non-public API functions.
  138386. +*/
  138387. +#if gcdDEBUG
  138388. +# define gcmDEBUG_VERIFY_ARGUMENT(arg) _gcmVERIFY_ARGUMENT(gcm, arg)
  138389. +# define gcmkDEBUG_VERIFY_ARGUMENT(arg) _gcmkVERIFY_ARGUMENT(gcm, arg)
  138390. +#else
  138391. +# define gcmDEBUG_VERIFY_ARGUMENT(arg)
  138392. +# define gcmkDEBUG_VERIFY_ARGUMENT(arg)
  138393. +#endif
  138394. +
  138395. +/*******************************************************************************
  138396. +**
  138397. +** gcmVERIFY_ARGUMENT_RETURN
  138398. +**
  138399. +** Assert if an argument does not apply to the specified expression. If
  138400. +** the argument evaluates to false, gcvSTATUS_INVALID_ARGUMENT will be
  138401. +** returned from the current function. In retail mode this macro does
  138402. +** nothing.
  138403. +**
  138404. +** ARGUMENTS:
  138405. +**
  138406. +** arg Argument to evaluate.
  138407. +*/
  138408. +# define _gcmVERIFY_ARGUMENT_RETURN(prefix, arg, value) \
  138409. + do \
  138410. + { \
  138411. + if (!(arg)) \
  138412. + { \
  138413. + prefix##TRACE(gcvLEVEL_ERROR, \
  138414. + #prefix "gcmVERIFY_ARGUMENT_RETURN failed:"); \
  138415. + prefix##ASSERT(arg); \
  138416. + prefix##FOOTER_ARG("value=%d", value); \
  138417. + return value; \
  138418. + } \
  138419. + } \
  138420. + while (gcvFALSE)
  138421. +# define gcmVERIFY_ARGUMENT_RETURN(arg, value) \
  138422. + _gcmVERIFY_ARGUMENT_RETURN(gcm, arg, value)
  138423. +# define gcmkVERIFY_ARGUMENT_RETURN(arg, value) \
  138424. + _gcmVERIFY_ARGUMENT_RETURN(gcmk, arg, value)
  138425. +
  138426. +#define MAX_LOOP_COUNT 0x7FFFFFFF
  138427. +
  138428. +/******************************************************************************\
  138429. +****************************** User Debug Option ******************************
  138430. +\******************************************************************************/
  138431. +
  138432. +/* User option. */
  138433. +typedef enum _gceDEBUG_MSG
  138434. +{
  138435. + gcvDEBUG_MSG_NONE,
  138436. + gcvDEBUG_MSG_ERROR,
  138437. + gcvDEBUG_MSG_WARNING
  138438. +}
  138439. +gceDEBUG_MSG;
  138440. +
  138441. +typedef struct _gcsUSER_DEBUG_OPTION
  138442. +{
  138443. + gceDEBUG_MSG debugMsg;
  138444. +}
  138445. +gcsUSER_DEBUG_OPTION;
  138446. +
  138447. +gcsUSER_DEBUG_OPTION *
  138448. +gcGetUserDebugOption(
  138449. + void
  138450. + );
  138451. +
  138452. +struct _gcoOS_SymbolsList
  138453. +{
  138454. + gcePATCH_ID patchId;
  138455. + const char * symList[10];
  138456. +};
  138457. +
  138458. +#if gcdHAS_ELLIPSES
  138459. +#define gcmUSER_DEBUG_MSG(level, ...) \
  138460. + do \
  138461. + { \
  138462. + if (level <= gcGetUserDebugOption()->debugMsg) \
  138463. + { \
  138464. + gcoOS_Print(__VA_ARGS__); \
  138465. + } \
  138466. + } while (gcvFALSE)
  138467. +
  138468. +#define gcmUSER_DEBUG_ERROR_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_ERROR, "Error: " __VA_ARGS__)
  138469. +#define gcmUSER_DEBUG_WARNING_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_WARNING, "Warring: " __VA_ARGS__)
  138470. +#else
  138471. +#define gcmUSER_DEBUG_MSG
  138472. +#define gcmUSER_DEBUG_ERROR_MSG
  138473. +#define gcmUSER_DEBUG_WARNING_MSG
  138474. +#endif
  138475. +
  138476. +#ifdef __cplusplus
  138477. +}
  138478. +#endif
  138479. +
  138480. +#endif /* __gc_hal_base_h_ */
  138481. diff -Nur linux-3.14.17/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
  138482. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h 1970-01-01 01:00:00.000000000 +0100
  138483. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h 2014-09-11 18:06:03.118042434 +0200
  138484. @@ -0,0 +1,4298 @@
  138485. +/****************************************************************************
  138486. +*
  138487. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  138488. +*
  138489. +* This program is free software; you can redistribute it and/or modify
  138490. +* it under the terms of the GNU General Public License as published by
  138491. +* the Free Software Foundation; either version 2 of the license, or
  138492. +* (at your option) any later version.
  138493. +*
  138494. +* This program is distributed in the hope that it will be useful,
  138495. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  138496. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  138497. +* GNU General Public License for more details.
  138498. +*
  138499. +* You should have received a copy of the GNU General Public License
  138500. +* along with this program; if not write to the Free Software
  138501. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  138502. +*
  138503. +*****************************************************************************/
  138504. +
  138505. +/*
  138506. +** Include file the defines the front- and back-end compilers, as well as the
  138507. +** objects they use.
  138508. +*/
  138509. +
  138510. +#ifndef __gc_hal_compiler_h_
  138511. +#define __gc_hal_compiler_h_
  138512. +
  138513. +#ifndef VIVANTE_NO_3D
  138514. +#include "gc_hal_types.h"
  138515. +#include "gc_hal_engine.h"
  138516. +
  138517. +#ifdef __cplusplus
  138518. +extern "C" {
  138519. +#endif
  138520. +
  138521. +#ifndef GC_ENABLE_LOADTIME_OPT
  138522. +#define GC_ENABLE_LOADTIME_OPT 1
  138523. +#endif
  138524. +
  138525. +#define TEMP_OPT_CONSTANT_TEXLD_COORD 0
  138526. +
  138527. +#define TEMP_SHADER_PATCH 1
  138528. +
  138529. +#define TEMP_INLINE_ALL_EXPANSION 1
  138530. +/******************************* IR VERSION ******************/
  138531. +#define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1')
  138532. +
  138533. +/******************************************************************************\
  138534. +|******************************* SHADER LANGUAGE ******************************|
  138535. +\******************************************************************************/
  138536. +
  138537. + /* allocator/deallocator function pointer */
  138538. +typedef gceSTATUS (*gctAllocatorFunc)(
  138539. + IN gctSIZE_T Bytes,
  138540. + OUT gctPOINTER * Memory
  138541. + );
  138542. +
  138543. +typedef gceSTATUS (*gctDeallocatorFunc)(
  138544. + IN gctPOINTER Memory
  138545. + );
  138546. +
  138547. +typedef gctBOOL (*compareFunc) (
  138548. + IN void * data,
  138549. + IN void * key
  138550. + );
  138551. +
  138552. +typedef struct _gcsListNode gcsListNode;
  138553. +struct _gcsListNode
  138554. +{
  138555. + gcsListNode * next;
  138556. + void * data;
  138557. +};
  138558. +
  138559. +typedef struct _gcsAllocator
  138560. +{
  138561. + gctAllocatorFunc allocate;
  138562. + gctDeallocatorFunc deallocate;
  138563. +} gcsAllocator;
  138564. +
  138565. +/* simple map structure */
  138566. +typedef struct _SimpleMap SimpleMap;
  138567. +struct _SimpleMap
  138568. +{
  138569. + gctUINT32 key;
  138570. + gctUINT32 val;
  138571. + SimpleMap *next;
  138572. + gcsAllocator *allocator;
  138573. +
  138574. +};
  138575. +
  138576. +/* SimpleMap Operations */
  138577. +/* return -1 if not found, otherwise return the mapped value */
  138578. +gctUINT32
  138579. +gcSimpleMap_Find(
  138580. + IN SimpleMap *Map,
  138581. + IN gctUINT32 Key
  138582. + );
  138583. +
  138584. +gceSTATUS
  138585. +gcSimpleMap_Destory(
  138586. + IN SimpleMap * Map,
  138587. + IN gcsAllocator * Allocator
  138588. + );
  138589. +
  138590. +/* Add a pair <Key, Val> to the Map head, the user should be aware that the
  138591. + * map pointer is always changed when adding a new node :
  138592. + *
  138593. + * gcSimpleMap_AddNode(&theMap, key, val, allocator);
  138594. + *
  138595. + */
  138596. +gceSTATUS
  138597. +gcSimpleMap_AddNode(
  138598. + IN SimpleMap ** Map,
  138599. + IN gctUINT32 Key,
  138600. + IN gctUINT32 Val,
  138601. + IN gcsAllocator * Allocator
  138602. + );
  138603. +
  138604. +/* gcsList data structure and related operations */
  138605. +typedef struct _gcsList
  138606. +{
  138607. + gcsListNode *head;
  138608. + gcsListNode *tail;
  138609. + gctINT count;
  138610. + gcsAllocator *allocator;
  138611. +} gcsList;
  138612. +
  138613. +/* List operations */
  138614. +void
  138615. +gcList_Init(
  138616. + IN gcsList *list,
  138617. + IN gcsAllocator *allocator
  138618. + );
  138619. +
  138620. +gceSTATUS
  138621. +gcList_CreateNode(
  138622. + IN void * Data,
  138623. + IN gctAllocatorFunc Allocator,
  138624. + OUT gcsListNode ** ListNode
  138625. + );
  138626. +
  138627. +gceSTATUS
  138628. +gcList_Clean(
  138629. + IN gcsList * List,
  138630. + IN gctBOOL FreeData
  138631. + );
  138632. +
  138633. +gcsListNode *
  138634. +gcList_FindNode(
  138635. + IN gcsList * List,
  138636. + IN void * Key,
  138637. + IN compareFunc compare
  138638. + );
  138639. +
  138640. +gceSTATUS
  138641. +gcList_AddNode(
  138642. + IN gcsList * List,
  138643. + IN void * Data
  138644. + );
  138645. +
  138646. +gceSTATUS
  138647. +gcList_RemoveNode(
  138648. + IN gcsList * List,
  138649. + IN gcsListNode * Node
  138650. + );
  138651. +
  138652. +/* link list structure for code list */
  138653. +typedef gcsList gcsCodeList;
  138654. +typedef gcsCodeList * gctCodeList;
  138655. +typedef gcsListNode gcsCodeListNode;
  138656. +
  138657. +/* Possible shader language opcodes. */
  138658. +typedef enum _gcSL_OPCODE
  138659. +{
  138660. + gcSL_NOP, /* 0x00 */
  138661. + gcSL_MOV, /* 0x01 */
  138662. + gcSL_SAT, /* 0x02 */
  138663. + gcSL_DP3, /* 0x03 */
  138664. + gcSL_DP4, /* 0x04 */
  138665. + gcSL_ABS, /* 0x05 */
  138666. + gcSL_JMP, /* 0x06 */
  138667. + gcSL_ADD, /* 0x07 */
  138668. + gcSL_MUL, /* 0x08 */
  138669. + gcSL_RCP, /* 0x09 */
  138670. + gcSL_SUB, /* 0x0A */
  138671. + gcSL_KILL, /* 0x0B */
  138672. + gcSL_TEXLD, /* 0x0C */
  138673. + gcSL_CALL, /* 0x0D */
  138674. + gcSL_RET, /* 0x0E */
  138675. + gcSL_NORM, /* 0x0F */
  138676. + gcSL_MAX, /* 0x10 */
  138677. + gcSL_MIN, /* 0x11 */
  138678. + gcSL_POW, /* 0x12 */
  138679. + gcSL_RSQ, /* 0x13 */
  138680. + gcSL_LOG, /* 0x14 */
  138681. + gcSL_FRAC, /* 0x15 */
  138682. + gcSL_FLOOR, /* 0x16 */
  138683. + gcSL_CEIL, /* 0x17 */
  138684. + gcSL_CROSS, /* 0x18 */
  138685. + gcSL_TEXLDP, /* 0x19 */
  138686. + gcSL_TEXBIAS, /* 0x1A */
  138687. + gcSL_TEXGRAD, /* 0x1B */
  138688. + gcSL_TEXLOD, /* 0x1C */
  138689. + gcSL_SIN, /* 0x1D */
  138690. + gcSL_COS, /* 0x1E */
  138691. + gcSL_TAN, /* 0x1F */
  138692. + gcSL_EXP, /* 0x20 */
  138693. + gcSL_SIGN, /* 0x21 */
  138694. + gcSL_STEP, /* 0x22 */
  138695. + gcSL_SQRT, /* 0x23 */
  138696. + gcSL_ACOS, /* 0x24 */
  138697. + gcSL_ASIN, /* 0x25 */
  138698. + gcSL_ATAN, /* 0x26 */
  138699. + gcSL_SET, /* 0x27 */
  138700. + gcSL_DSX, /* 0x28 */
  138701. + gcSL_DSY, /* 0x29 */
  138702. + gcSL_FWIDTH, /* 0x2A */
  138703. + gcSL_DIV, /* 0x2B */
  138704. + gcSL_MOD, /* 0x2C */
  138705. + gcSL_AND_BITWISE, /* 0x2D */
  138706. + gcSL_OR_BITWISE, /* 0x2E */
  138707. + gcSL_XOR_BITWISE, /* 0x2F */
  138708. + gcSL_NOT_BITWISE, /* 0x30 */
  138709. + gcSL_LSHIFT, /* 0x31 */
  138710. + gcSL_RSHIFT, /* 0x32 */
  138711. + gcSL_ROTATE, /* 0x33 */
  138712. + gcSL_BITSEL, /* 0x34 */
  138713. + gcSL_LEADZERO, /* 0x35 */
  138714. + gcSL_LOAD, /* 0x36 */
  138715. + gcSL_STORE, /* 0x37 */
  138716. + gcSL_BARRIER, /* 0x38 */
  138717. + gcSL_STORE1, /* 0x39 */
  138718. + gcSL_ATOMADD, /* 0x3A */
  138719. + gcSL_ATOMSUB, /* 0x3B */
  138720. + gcSL_ATOMXCHG, /* 0x3C */
  138721. + gcSL_ATOMCMPXCHG, /* 0x3D */
  138722. + gcSL_ATOMMIN, /* 0x3E */
  138723. + gcSL_ATOMMAX, /* 0x3F */
  138724. + gcSL_ATOMOR, /* 0x40 */
  138725. + gcSL_ATOMAND, /* 0x41 */
  138726. + gcSL_ATOMXOR, /* 0x42 */
  138727. + /*gcSL_UNUSED, 0x43 */
  138728. + /*gcSL_UNUSED, 0x44 */
  138729. + /*gcSL_UNUSED, 0x45 */
  138730. + /*gcSL_UNUSED, 0x46 */
  138731. + /*gcSL_UNUSED, 0x47 */
  138732. + /*gcSL_UNUSED, 0x48 */
  138733. + /*gcSL_UNUSED, 0x49 */
  138734. + /*gcSL_UNUSED, 0x4A */
  138735. + /*gcSL_UNUSED, 0x4B */
  138736. + /*gcSL_UNUSED, 0x4C */
  138737. + /*gcSL_UNUSED, 0x4D */
  138738. + /*gcSL_UNUSED, 0x4E */
  138739. + /*gcSL_UNUSED, 0x4F */
  138740. + /*gcSL_UNUSED, 0x50 */
  138741. + /*gcSL_UNUSED, 0x51 */
  138742. + /*gcSL_UNUSED, 0x52 */
  138743. + gcSL_ADDLO = 0x53, /* 0x53 */ /* Float only. */
  138744. + gcSL_MULLO, /* 0x54 */ /* Float only. */
  138745. + gcSL_CONV, /* 0x55 */
  138746. + gcSL_GETEXP, /* 0x56 */
  138747. + gcSL_GETMANT, /* 0x57 */
  138748. + gcSL_MULHI, /* 0x58 */ /* Integer only. */
  138749. + gcSL_CMP, /* 0x59 */
  138750. + gcSL_I2F, /* 0x5A */
  138751. + gcSL_F2I, /* 0x5B */
  138752. + gcSL_ADDSAT, /* 0x5C */ /* Integer only. */
  138753. + gcSL_SUBSAT, /* 0x5D */ /* Integer only. */
  138754. + gcSL_MULSAT, /* 0x5E */ /* Integer only. */
  138755. + gcSL_DP2, /* 0x5F */
  138756. + gcSL_MAXOPCODE
  138757. +}
  138758. +gcSL_OPCODE;
  138759. +
  138760. +typedef enum _gcSL_FORMAT
  138761. +{
  138762. + gcSL_FLOAT = 0, /* 0 */
  138763. + gcSL_INTEGER = 1, /* 1 */
  138764. + gcSL_INT32 = 1, /* 1 */
  138765. + gcSL_BOOLEAN = 2, /* 2 */
  138766. + gcSL_UINT32 = 3, /* 3 */
  138767. + gcSL_INT8, /* 4 */
  138768. + gcSL_UINT8, /* 5 */
  138769. + gcSL_INT16, /* 6 */
  138770. + gcSL_UINT16, /* 7 */
  138771. + gcSL_INT64, /* 8 */ /* Reserved for future enhancement. */
  138772. + gcSL_UINT64, /* 9 */ /* Reserved for future enhancement. */
  138773. + gcSL_INT128, /* 10 */ /* Reserved for future enhancement. */
  138774. + gcSL_UINT128, /* 11 */ /* Reserved for future enhancement. */
  138775. + gcSL_FLOAT16, /* 12 */
  138776. + gcSL_FLOAT64, /* 13 */ /* Reserved for future enhancement. */
  138777. + gcSL_FLOAT128, /* 14 */ /* Reserved for future enhancement. */
  138778. +}
  138779. +gcSL_FORMAT;
  138780. +
  138781. +/* Destination write enable bits. */
  138782. +typedef enum _gcSL_ENABLE
  138783. +{
  138784. + gcSL_ENABLE_NONE = 0x0, /* none is enabled, error/uninitialized state */
  138785. + gcSL_ENABLE_X = 0x1,
  138786. + gcSL_ENABLE_Y = 0x2,
  138787. + gcSL_ENABLE_Z = 0x4,
  138788. + gcSL_ENABLE_W = 0x8,
  138789. + /* Combinations. */
  138790. + gcSL_ENABLE_XY = gcSL_ENABLE_X | gcSL_ENABLE_Y,
  138791. + gcSL_ENABLE_XYZ = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z,
  138792. + gcSL_ENABLE_XYZW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  138793. + gcSL_ENABLE_XYW = gcSL_ENABLE_X | gcSL_ENABLE_Y | gcSL_ENABLE_W,
  138794. + gcSL_ENABLE_XZ = gcSL_ENABLE_X | gcSL_ENABLE_Z,
  138795. + gcSL_ENABLE_XZW = gcSL_ENABLE_X | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  138796. + gcSL_ENABLE_XW = gcSL_ENABLE_X | gcSL_ENABLE_W,
  138797. + gcSL_ENABLE_YZ = gcSL_ENABLE_Y | gcSL_ENABLE_Z,
  138798. + gcSL_ENABLE_YZW = gcSL_ENABLE_Y | gcSL_ENABLE_Z | gcSL_ENABLE_W,
  138799. + gcSL_ENABLE_YW = gcSL_ENABLE_Y | gcSL_ENABLE_W,
  138800. + gcSL_ENABLE_ZW = gcSL_ENABLE_Z | gcSL_ENABLE_W,
  138801. +}
  138802. +gcSL_ENABLE;
  138803. +
  138804. +/* Possible indices. */
  138805. +typedef enum _gcSL_INDEXED
  138806. +{
  138807. + gcSL_NOT_INDEXED, /* 0 */
  138808. + gcSL_INDEXED_X, /* 1 */
  138809. + gcSL_INDEXED_Y, /* 2 */
  138810. + gcSL_INDEXED_Z, /* 3 */
  138811. + gcSL_INDEXED_W, /* 4 */
  138812. +}
  138813. +gcSL_INDEXED;
  138814. +
  138815. +/* Opcode conditions. */
  138816. +typedef enum _gcSL_CONDITION
  138817. +{
  138818. + gcSL_ALWAYS, /* 0x0 */
  138819. + gcSL_NOT_EQUAL, /* 0x1 */
  138820. + gcSL_LESS_OR_EQUAL, /* 0x2 */
  138821. + gcSL_LESS, /* 0x3 */
  138822. + gcSL_EQUAL, /* 0x4 */
  138823. + gcSL_GREATER, /* 0x5 */
  138824. + gcSL_GREATER_OR_EQUAL, /* 0x6 */
  138825. + gcSL_AND, /* 0x7 */
  138826. + gcSL_OR, /* 0x8 */
  138827. + gcSL_XOR, /* 0x9 */
  138828. + gcSL_NOT_ZERO, /* 0xA */
  138829. +}
  138830. +gcSL_CONDITION;
  138831. +
  138832. +/* Possible source operand types. */
  138833. +typedef enum _gcSL_TYPE
  138834. +{
  138835. + gcSL_NONE, /* 0x0 */
  138836. + gcSL_TEMP, /* 0x1 */
  138837. + gcSL_ATTRIBUTE, /* 0x2 */
  138838. + gcSL_UNIFORM, /* 0x3 */
  138839. + gcSL_SAMPLER, /* 0x4 */
  138840. + gcSL_CONSTANT, /* 0x5 */
  138841. + gcSL_OUTPUT, /* 0x6 */
  138842. + gcSL_PHYSICAL, /* 0x7 */
  138843. +}
  138844. +gcSL_TYPE;
  138845. +
  138846. +/* Swizzle generator macro. */
  138847. +#define gcmSWIZZLE(Component1, Component2, Component3, Component4) \
  138848. +( \
  138849. + (gcSL_SWIZZLE_ ## Component1 << 0) | \
  138850. + (gcSL_SWIZZLE_ ## Component2 << 2) | \
  138851. + (gcSL_SWIZZLE_ ## Component3 << 4) | \
  138852. + (gcSL_SWIZZLE_ ## Component4 << 6) \
  138853. +)
  138854. +
  138855. +#define gcmExtractSwizzle(Swizzle, Index) \
  138856. + ((gcSL_SWIZZLE) ((((Swizzle) >> (Index * 2)) & 0x3)))
  138857. +
  138858. +#define gcmComposeSwizzle(SwizzleX, SwizzleY, SwizzleZ, SwizzleW) \
  138859. +( \
  138860. + ((SwizzleX) << 0) | \
  138861. + ((SwizzleY) << 2) | \
  138862. + ((SwizzleZ) << 4) | \
  138863. + ((SwizzleW) << 6) \
  138864. +)
  138865. +
  138866. +/* Possible swizzle values. */
  138867. +typedef enum _gcSL_SWIZZLE
  138868. +{
  138869. + gcSL_SWIZZLE_X, /* 0x0 */
  138870. + gcSL_SWIZZLE_Y, /* 0x1 */
  138871. + gcSL_SWIZZLE_Z, /* 0x2 */
  138872. + gcSL_SWIZZLE_W, /* 0x3 */
  138873. + /* Combinations. */
  138874. + gcSL_SWIZZLE_XXXX = gcmSWIZZLE(X, X, X, X),
  138875. + gcSL_SWIZZLE_YYYY = gcmSWIZZLE(Y, Y, Y, Y),
  138876. + gcSL_SWIZZLE_ZZZZ = gcmSWIZZLE(Z, Z, Z, Z),
  138877. + gcSL_SWIZZLE_WWWW = gcmSWIZZLE(W, W, W, W),
  138878. + gcSL_SWIZZLE_XYYY = gcmSWIZZLE(X, Y, Y, Y),
  138879. + gcSL_SWIZZLE_XZZZ = gcmSWIZZLE(X, Z, Z, Z),
  138880. + gcSL_SWIZZLE_XWWW = gcmSWIZZLE(X, W, W, W),
  138881. + gcSL_SWIZZLE_YZZZ = gcmSWIZZLE(Y, Z, Z, Z),
  138882. + gcSL_SWIZZLE_YWWW = gcmSWIZZLE(Y, W, W, W),
  138883. + gcSL_SWIZZLE_ZWWW = gcmSWIZZLE(Z, W, W, W),
  138884. + gcSL_SWIZZLE_XYZZ = gcmSWIZZLE(X, Y, Z, Z),
  138885. + gcSL_SWIZZLE_XYWW = gcmSWIZZLE(X, Y, W, W),
  138886. + gcSL_SWIZZLE_XZWW = gcmSWIZZLE(X, Z, W, W),
  138887. + gcSL_SWIZZLE_YZWW = gcmSWIZZLE(Y, Z, W, W),
  138888. + gcSL_SWIZZLE_XXYZ = gcmSWIZZLE(X, X, Y, Z),
  138889. + gcSL_SWIZZLE_XYZW = gcmSWIZZLE(X, Y, Z, W),
  138890. + gcSL_SWIZZLE_XYXY = gcmSWIZZLE(X, Y, X, Y),
  138891. + gcSL_SWIZZLE_YYZZ = gcmSWIZZLE(Y, Y, Z, Z),
  138892. + gcSL_SWIZZLE_YYWW = gcmSWIZZLE(Y, Y, W, W),
  138893. + gcSL_SWIZZLE_ZZZW = gcmSWIZZLE(Z, Z, Z, W),
  138894. + gcSL_SWIZZLE_XZZW = gcmSWIZZLE(X, Z, Z, W),
  138895. + gcSL_SWIZZLE_YYZW = gcmSWIZZLE(Y, Y, Z, W),
  138896. +
  138897. + gcSL_SWIZZLE_INVALID = 0x7FFFFFFF
  138898. +}
  138899. +gcSL_SWIZZLE;
  138900. +
  138901. +typedef enum _gcSL_COMPONENT
  138902. +{
  138903. + gcSL_COMPONENT_X, /* 0x0 */
  138904. + gcSL_COMPONENT_Y, /* 0x1 */
  138905. + gcSL_COMPONENT_Z, /* 0x2 */
  138906. + gcSL_COMPONENT_W, /* 0x3 */
  138907. + gcSL_COMPONENT_COUNT /* 0x4 */
  138908. +} gcSL_COMPONENT;
  138909. +
  138910. +#define gcmIsComponentEnabled(Enable, Component) (((Enable) & (1 << (Component))) != 0)
  138911. +
  138912. +/******************************************************************************\
  138913. +|*********************************** SHADERS **********************************|
  138914. +\******************************************************************************/
  138915. +
  138916. +/* Shader types. */
  138917. +typedef enum _gcSHADER_KIND {
  138918. + gcSHADER_TYPE_UNKNOWN = 0,
  138919. + gcSHADER_TYPE_VERTEX,
  138920. + gcSHADER_TYPE_FRAGMENT,
  138921. + gcSHADER_TYPE_CL,
  138922. + gcSHADER_TYPE_PRECOMPILED,
  138923. + gcSHADER_KIND_COUNT
  138924. +} gcSHADER_KIND;
  138925. +
  138926. +typedef enum _gcGL_DRIVER_VERSION {
  138927. + gcGL_DRIVER_ES11, /* OpenGL ES 1.1 */
  138928. + gcGL_DRIVER_ES20, /* OpenGL ES 2.0 */
  138929. + gcGL_DRIVER_ES30 /* OpenGL ES 3.0 */
  138930. +} gcGL_DRIVER_VERSION;
  138931. +
  138932. +/* gcSHADER objects. */
  138933. +typedef struct _gcSHADER * gcSHADER;
  138934. +typedef struct _gcATTRIBUTE * gcATTRIBUTE;
  138935. +typedef struct _gcUNIFORM * gcUNIFORM;
  138936. +typedef struct _gcOUTPUT * gcOUTPUT;
  138937. +typedef struct _gcsFUNCTION * gcFUNCTION;
  138938. +typedef struct _gcsKERNEL_FUNCTION * gcKERNEL_FUNCTION;
  138939. +typedef struct _gcsHINT * gcsHINT_PTR;
  138940. +typedef struct _gcSHADER_PROFILER * gcSHADER_PROFILER;
  138941. +typedef struct _gcVARIABLE * gcVARIABLE;
  138942. +
  138943. +struct _gcsHINT
  138944. +{
  138945. + /* Numbr of data transfers for Vertex Shader output. */
  138946. + gctUINT32 vsOutputCount;
  138947. +
  138948. + /* Flag whether the VS has point size or not. */
  138949. + gctBOOL vsHasPointSize;
  138950. +
  138951. +#if gcdUSE_WCLIP_PATCH
  138952. + /* Flag whether the VS gl_position.z depends on gl_position.w
  138953. + it's a hint for wclipping */
  138954. + gctBOOL vsPositionZDependsOnW;
  138955. +#endif
  138956. +
  138957. + gctBOOL clipW;
  138958. +
  138959. + /* Flag whether or not the shader has a KILL instruction. */
  138960. + gctBOOL hasKill;
  138961. +
  138962. + /* Element count. */
  138963. + gctUINT32 elementCount;
  138964. +
  138965. + /* Component count. */
  138966. + gctUINT32 componentCount;
  138967. +
  138968. + /* Number of data transfers for Fragment Shader input. */
  138969. + gctUINT32 fsInputCount;
  138970. +
  138971. + /* Maximum number of temporary registers used in FS. */
  138972. + gctUINT32 fsMaxTemp;
  138973. +
  138974. + /* Maximum number of temporary registers used in VS. */
  138975. + gctUINT32 vsMaxTemp;
  138976. +
  138977. + /* Balance minimum. */
  138978. + gctUINT32 balanceMin;
  138979. +
  138980. + /* Balance maximum. */
  138981. + gctUINT32 balanceMax;
  138982. +
  138983. + /* Auto-shift balancing. */
  138984. + gctBOOL autoShift;
  138985. +
  138986. + /* Flag whether the PS outputs the depth value or not. */
  138987. + gctBOOL psHasFragDepthOut;
  138988. +
  138989. + /* Flag whether the ThreadWalker is in PS. */
  138990. + gctBOOL threadWalkerInPS;
  138991. +
  138992. + /* HW reg number for position of VS */
  138993. + gctUINT32 hwRegNoOfSIVPos;
  138994. +
  138995. +#if gcdALPHA_KILL_IN_SHADER
  138996. + /* States to set when alpha kill is enabled. */
  138997. + gctUINT32 killStateAddress;
  138998. + gctUINT32 alphaKillStateValue;
  138999. + gctUINT32 colorKillStateValue;
  139000. +
  139001. + /* Shader instructiuon. */
  139002. + gctUINT32 killInstructionAddress;
  139003. + gctUINT32 alphaKillInstruction[3];
  139004. + gctUINT32 colorKillInstruction[3];
  139005. +#endif
  139006. +
  139007. +#if TEMP_SHADER_PATCH
  139008. + gctUINT32 pachedShaderIdentifier;
  139009. +#endif
  139010. +};
  139011. +
  139012. +#if TEMP_SHADER_PATCH
  139013. +#define INVALID_SHADER_IDENTIFIER 0xFFFFFFFF
  139014. +#endif
  139015. +
  139016. +/* gcSHADER_TYPE enumeration. */
  139017. +typedef enum _gcSHADER_TYPE
  139018. +{
  139019. + gcSHADER_FLOAT_X1 = 0, /* 0x00 */
  139020. + gcSHADER_FLOAT_X2, /* 0x01 */
  139021. + gcSHADER_FLOAT_X3, /* 0x02 */
  139022. + gcSHADER_FLOAT_X4, /* 0x03 */
  139023. + gcSHADER_FLOAT_2X2, /* 0x04 */
  139024. + gcSHADER_FLOAT_3X3, /* 0x05 */
  139025. + gcSHADER_FLOAT_4X4, /* 0x06 */
  139026. + gcSHADER_BOOLEAN_X1, /* 0x07 */
  139027. + gcSHADER_BOOLEAN_X2, /* 0x08 */
  139028. + gcSHADER_BOOLEAN_X3, /* 0x09 */
  139029. + gcSHADER_BOOLEAN_X4, /* 0x0A */
  139030. + gcSHADER_INTEGER_X1, /* 0x0B */
  139031. + gcSHADER_INTEGER_X2, /* 0x0C */
  139032. + gcSHADER_INTEGER_X3, /* 0x0D */
  139033. + gcSHADER_INTEGER_X4, /* 0x0E */
  139034. + gcSHADER_SAMPLER_1D, /* 0x0F */
  139035. + gcSHADER_SAMPLER_2D, /* 0x10 */
  139036. + gcSHADER_SAMPLER_3D, /* 0x11 */
  139037. + gcSHADER_SAMPLER_CUBIC, /* 0x12 */
  139038. + gcSHADER_FIXED_X1, /* 0x13 */
  139039. + gcSHADER_FIXED_X2, /* 0x14 */
  139040. + gcSHADER_FIXED_X3, /* 0x15 */
  139041. + gcSHADER_FIXED_X4, /* 0x16 */
  139042. + gcSHADER_IMAGE_2D, /* 0x17 */ /* For OCL. */
  139043. + gcSHADER_IMAGE_3D, /* 0x18 */ /* For OCL. */
  139044. + gcSHADER_SAMPLER, /* 0x19 */ /* For OCL. */
  139045. + gcSHADER_FLOAT_2X3, /* 0x1A */
  139046. + gcSHADER_FLOAT_2X4, /* 0x1B */
  139047. + gcSHADER_FLOAT_3X2, /* 0x1C */
  139048. + gcSHADER_FLOAT_3X4, /* 0x1D */
  139049. + gcSHADER_FLOAT_4X2, /* 0x1E */
  139050. + gcSHADER_FLOAT_4X3, /* 0x1F */
  139051. + gcSHADER_ISAMPLER_2D, /* 0x20 */
  139052. + gcSHADER_ISAMPLER_3D, /* 0x21 */
  139053. + gcSHADER_ISAMPLER_CUBIC, /* 0x22 */
  139054. + gcSHADER_USAMPLER_2D, /* 0x23 */
  139055. + gcSHADER_USAMPLER_3D, /* 0x24 */
  139056. + gcSHADER_USAMPLER_CUBIC, /* 0x25 */
  139057. + gcSHADER_SAMPLER_EXTERNAL_OES, /* 0x26 */
  139058. +
  139059. + gcSHADER_UINT_X1, /* 0x27 */
  139060. + gcSHADER_UINT_X2, /* 0x28 */
  139061. + gcSHADER_UINT_X3, /* 0x29 */
  139062. + gcSHADER_UINT_X4, /* 0x2A */
  139063. +
  139064. + gcSHADER_UNKONWN_TYPE, /* do not add type after this */
  139065. + gcSHADER_TYPE_COUNT /* must to change gcvShaderTypeInfo at the
  139066. + * same time if you add any new type! */}
  139067. +gcSHADER_TYPE;
  139068. +
  139069. +typedef enum _gcSHADER_TYPE_KIND
  139070. +{
  139071. + gceTK_UNKOWN,
  139072. + gceTK_FLOAT,
  139073. + gceTK_INT,
  139074. + gceTK_UINT,
  139075. + gceTK_BOOL,
  139076. + gceTK_FIXED,
  139077. + gceTK_SAMPLER,
  139078. + gceTK_IMAGE,
  139079. + gceTK_OTHER
  139080. +} gcSHADER_TYPE_KIND;
  139081. +
  139082. +typedef struct _gcSHADER_TYPEINFO
  139083. +{
  139084. + gcSHADER_TYPE type; /* e.g. gcSHADER_FLOAT_2X4 */
  139085. + gctINT components; /* e.g. 4 components */
  139086. + gctINT rows; /* e.g. 2 rows */
  139087. + gcSHADER_TYPE componentType; /* e.g. gcSHADER_FLOAT_X4 */
  139088. + gcSHADER_TYPE_KIND kind; /* e.g. gceTK_FLOAT */
  139089. + gctCONST_STRING name; /* e.g. "FLOAT_2X4" */
  139090. +} gcSHADER_TYPEINFO;
  139091. +
  139092. +extern gcSHADER_TYPEINFO gcvShaderTypeInfo[];
  139093. +
  139094. +#define gcmType_Comonents(Type) (gcvShaderTypeInfo[Type].components)
  139095. +#define gcmType_Rows(Type) (gcvShaderTypeInfo[Type].rows)
  139096. +#define gcmType_ComonentType(Type) (gcvShaderTypeInfo[Type].componentType)
  139097. +#define gcmType_Kind(Type) (gcvShaderTypeInfo[Type].kind)
  139098. +#define gcmType_Name(Type) (gcvShaderTypeInfo[Type].name)
  139099. +
  139100. +#define gcmType_isMatrix(type) (gcmType_Rows(type) > 1)
  139101. +
  139102. +typedef enum _gcSHADER_VAR_CATEGORY
  139103. +{
  139104. + gcSHADER_VAR_CATEGORY_NORMAL = 0, /* primitive type and its array */
  139105. + gcSHADER_VAR_CATEGORY_STRUCT = 1 /* structure */
  139106. +}
  139107. +gcSHADER_VAR_CATEGORY;
  139108. +
  139109. +typedef enum _gceTYPE_QUALIFIER
  139110. +{
  139111. + gcvTYPE_QUALIFIER_NONE = 0x0, /* unqualified */
  139112. + gcvTYPE_QUALIFIER_VOLATILE = 0x1, /* volatile */
  139113. +}gceTYPE_QUALIFIER;
  139114. +
  139115. +typedef gctUINT16 gctTYPE_QUALIFIER;
  139116. +
  139117. +#if GC_ENABLE_LOADTIME_OPT
  139118. +typedef struct _gcSHADER_TYPE_INFO
  139119. +{
  139120. + gcSHADER_TYPE type; /* eg. gcSHADER_FLOAT_2X3 is the type */
  139121. + gctCONST_STRING name; /* the name of the type: "gcSHADER_FLOAT_2X3" */
  139122. + gcSHADER_TYPE baseType; /* its base type is gcSHADER_FLOAT_2 */
  139123. + gctINT components; /* it has 2 components */
  139124. + gctINT rows; /* and 3 rows */
  139125. + gctINT size; /* the size in byte */
  139126. +} gcSHADER_TYPE_INFO;
  139127. +
  139128. +extern gcSHADER_TYPE_INFO shader_type_info[];
  139129. +
  139130. +enum gceLTCDumpOption {
  139131. + gceLTC_DUMP_UNIFORM = 0x0001,
  139132. + gceLTC_DUMP_EVALUATION = 0x0002,
  139133. + gceLTC_DUMP_EXPESSION = 0x0004,
  139134. + gceLTC_DUMP_COLLECTING = 0x0008,
  139135. +};
  139136. +
  139137. +gctBOOL gcDumpOption(gctINT Opt);
  139138. +
  139139. +#endif /* GC_ENABLE_LOADTIME_OPT */
  139140. +
  139141. +#define IS_MATRIX_TYPE(type) \
  139142. + (((type >= gcSHADER_FLOAT_2X2) && (type <= gcSHADER_FLOAT_4X4)) || \
  139143. + ((type >= gcSHADER_FLOAT_2X3) && (type <= gcSHADER_FLOAT_4X3)))
  139144. +
  139145. +/* gcSHADER_PRECISION enumeration. */
  139146. +typedef enum _gcSHADER_PRECISION
  139147. +{
  139148. + gcSHADER_PRECISION_DEFAULT, /* 0x00 */
  139149. + gcSHADER_PRECISION_HIGH, /* 0x01 */
  139150. + gcSHADER_PRECISION_MEDIUM, /* 0x02 */
  139151. + gcSHADER_PRECISION_LOW, /* 0x03 */
  139152. +}
  139153. +gcSHADER_PRECISION;
  139154. +
  139155. +/* Shader flags. */
  139156. +typedef enum _gceSHADER_FLAGS
  139157. +{
  139158. + gcvSHADER_NO_OPTIMIZATION = 0x00,
  139159. + gcvSHADER_DEAD_CODE = 0x01,
  139160. + gcvSHADER_RESOURCE_USAGE = 0x02,
  139161. + gcvSHADER_OPTIMIZER = 0x04,
  139162. + gcvSHADER_USE_GL_Z = 0x08,
  139163. + /*
  139164. + The GC family of GPU cores model GC860 and under require the Z
  139165. + to be from 0 <= z <= w.
  139166. + However, OpenGL specifies the Z to be from -w <= z <= w. So we
  139167. + have to a conversion here:
  139168. +
  139169. + z = (z + w) / 2.
  139170. +
  139171. + So here we append two instructions to the vertex shader.
  139172. + */
  139173. + gcvSHADER_USE_GL_POSITION = 0x10,
  139174. + gcvSHADER_USE_GL_FACE = 0x20,
  139175. + gcvSHADER_USE_GL_POINT_COORD = 0x40,
  139176. + gcvSHADER_LOADTIME_OPTIMIZER = 0x80,
  139177. +#if gcdALPHA_KILL_IN_SHADER
  139178. + gcvSHADER_USE_ALPHA_KILL = 0x100,
  139179. +#endif
  139180. +
  139181. +#if gcdPRE_ROTATION && (ANDROID_SDK_VERSION >= 14)
  139182. + gcvSHADER_VS_PRE_ROTATION = 0x200,
  139183. +#endif
  139184. +
  139185. +#if TEMP_INLINE_ALL_EXPANSION
  139186. + gcvSHADER_INLINE_ALL_EXPANSION = 0x400,
  139187. +#endif
  139188. +}
  139189. +gceSHADER_FLAGS;
  139190. +
  139191. +gceSTATUS
  139192. +gcSHADER_CheckClipW(
  139193. + IN gctCONST_STRING VertexSource,
  139194. + IN gctCONST_STRING FragmentSource,
  139195. + OUT gctBOOL * clipW);
  139196. +
  139197. +/*******************************************************************************
  139198. +** gcSHADER_GetUniformVectorCount
  139199. +**
  139200. +** Get the number of vectors used by uniforms for this shader.
  139201. +**
  139202. +** INPUT:
  139203. +**
  139204. +** gcSHADER Shader
  139205. +** Pointer to a gcSHADER object.
  139206. +**
  139207. +** OUTPUT:
  139208. +**
  139209. +** gctSIZE_T * Count
  139210. +** Pointer to a variable receiving the number of vectors.
  139211. +*/
  139212. +gceSTATUS
  139213. +gcSHADER_GetUniformVectorCount(
  139214. + IN gcSHADER Shader,
  139215. + OUT gctSIZE_T * Count
  139216. + );
  139217. +
  139218. +/*******************************************************************************
  139219. +** gcOptimizer Data Structures
  139220. +*******************************************************************************/
  139221. +typedef enum _gceSHADER_OPTIMIZATION
  139222. +{
  139223. + /* No optimization. */
  139224. + gcvOPTIMIZATION_NONE,
  139225. +
  139226. + /* Flow graph construction. */
  139227. + gcvOPTIMIZATION_CONSTRUCTION = 1 << 0,
  139228. +
  139229. + /* Dead code elimination. */
  139230. + gcvOPTIMIZATION_DEAD_CODE = 1 << 1,
  139231. +
  139232. + /* Redundant move instruction elimination. */
  139233. + gcvOPTIMIZATION_REDUNDANT_MOVE = 1 << 2,
  139234. +
  139235. + /* Inline expansion. */
  139236. + gcvOPTIMIZATION_INLINE_EXPANSION = 1 << 3,
  139237. +
  139238. + /* Constant propagation. */
  139239. + gcvOPTIMIZATION_CONSTANT_PROPAGATION = 1 << 4,
  139240. +
  139241. + /* Redundant bounds/checking elimination. */
  139242. + gcvOPTIMIZATION_REDUNDANT_CHECKING = 1 << 5,
  139243. +
  139244. + /* Loop invariant movement. */
  139245. + gcvOPTIMIZATION_LOOP_INVARIANT = 1 << 6,
  139246. +
  139247. + /* Induction variable removal. */
  139248. + gcvOPTIMIZATION_INDUCTION_VARIABLE = 1 << 7,
  139249. +
  139250. + /* Common subexpression elimination. */
  139251. + gcvOPTIMIZATION_COMMON_SUBEXPRESSION = 1 << 8,
  139252. +
  139253. + /* Control flow/banch optimization. */
  139254. + gcvOPTIMIZATION_CONTROL_FLOW = 1 << 9,
  139255. +
  139256. + /* Vector component operation merge. */
  139257. + gcvOPTIMIZATION_VECTOR_INSTRUCTION_MERGE = 1 << 10,
  139258. +
  139259. + /* Algebra simplificaton. */
  139260. + gcvOPTIMIZATION_ALGEBRAIC_SIMPLIFICATION = 1 << 11,
  139261. +
  139262. + /* Pattern matching and replacing. */
  139263. + gcvOPTIMIZATION_PATTERN_MATCHING = 1 << 12,
  139264. +
  139265. + /* Interprocedural constant propagation. */
  139266. + gcvOPTIMIZATION_IP_CONSTANT_PROPAGATION = 1 << 13,
  139267. +
  139268. + /* Interprecedural register optimization. */
  139269. + gcvOPTIMIZATION_IP_REGISTRATION = 1 << 14,
  139270. +
  139271. + /* Optimization option number. */
  139272. + gcvOPTIMIZATION_OPTION_NUMBER = 1 << 15,
  139273. +
  139274. + /* Loadtime constant. */
  139275. + gcvOPTIMIZATION_LOADTIME_CONSTANT = 1 << 16,
  139276. +
  139277. + /* MAD instruction optimization. */
  139278. + gcvOPTIMIZATION_MAD_INSTRUCTION = 1 << 17,
  139279. +
  139280. + /* Special optimization for LOAD SW workaround. */
  139281. + gcvOPTIMIZATION_LOAD_SW_WORKAROUND = 1 << 18,
  139282. +
  139283. + /* move code into conditional block if possile */
  139284. + gcvOPTIMIZATION_CONDITIONALIZE = 1 << 19,
  139285. +
  139286. + /* expriemental: power optimization mode
  139287. + 1. add extra dummy texld to tune performance
  139288. + 2. insert NOP after high power instrucitons
  139289. + 3. split high power vec3/vec4 instruciton to vec2/vec1 operation
  139290. + 4. ...
  139291. + */
  139292. + gcvOPTIMIZATION_POWER_OPTIMIZATION = 1 << 20,
  139293. +
  139294. + /* optimize varying packing */
  139295. + gcvOPTIMIZATION_VARYINGPACKING = 1 << 22,
  139296. +
  139297. +#if TEMP_INLINE_ALL_EXPANSION
  139298. + gcvOPTIMIZATION_INLINE_ALL_EXPANSION = 1 << 23,
  139299. +#endif
  139300. +
  139301. + /* Full optimization. */
  139302. + /* Note that gcvOPTIMIZATION_LOAD_SW_WORKAROUND is off. */
  139303. + gcvOPTIMIZATION_FULL = 0x7FFFFFFF &
  139304. + ~gcvOPTIMIZATION_LOAD_SW_WORKAROUND &
  139305. + ~gcvOPTIMIZATION_INLINE_ALL_EXPANSION &
  139306. + ~gcvOPTIMIZATION_POWER_OPTIMIZATION,
  139307. +
  139308. + /* Optimization Unit Test flag. */
  139309. + gcvOPTIMIZATION_UNIT_TEST = 1 << 31
  139310. +}
  139311. +gceSHADER_OPTIMIZATION;
  139312. +
  139313. +typedef enum _gceOPTIMIZATION_VaryingPaking
  139314. +{
  139315. + gcvOPTIMIZATION_VARYINGPACKING_NONE = 0,
  139316. + gcvOPTIMIZATION_VARYINGPACKING_NOSPLIT,
  139317. + gcvOPTIMIZATION_VARYINGPACKING_SPLIT
  139318. +} gceOPTIMIZATION_VaryingPaking;
  139319. +
  139320. +typedef struct _gcOPTIMIZER_OPTION
  139321. +{
  139322. + gceSHADER_OPTIMIZATION optFlags;
  139323. +
  139324. + /* debug & dump options:
  139325. +
  139326. + VC_OPTION=-DUMP:SRC:OPT|:OPTV|:CG|:CGV:|ALL|ALLV
  139327. +
  139328. + SRC: dump shader source code
  139329. + OPT: dump incoming and final IR
  139330. + OPTV: dump result IR in each optimization phase
  139331. + CG: dump generated machine code
  139332. + CGV: dump BE tree and optimization detail
  139333. +
  139334. + ALL = SRC|OPT|CG
  139335. + ALLV = SRC|OPT|OPTV|CG|CGV
  139336. + */
  139337. + gctBOOL dumpShaderSource; /* dump shader source code */
  139338. + gctBOOL dumpOptimizer; /* dump incoming and final IR */
  139339. + gctBOOL dumpOptimizerVerbose; /* dump result IR in each optimization phase */
  139340. + gctBOOL dumpBEGenertedCode; /* dump generated machine code */
  139341. + gctBOOL dumpBEVerbose; /* dump BE tree and optimization detail */
  139342. + gctBOOL dumpBEFinalIR; /* dump BE final IR */
  139343. +
  139344. + /* Code generation */
  139345. +
  139346. + /* Varying Packing:
  139347. +
  139348. + VC_OPTION=-PACKVARYING:[0-2]|:T[-]m[,n]|:LshaderIdx,min,max
  139349. +
  139350. + 0: turn off varying packing
  139351. + 1: pack varyings, donot split any varying
  139352. + 2: pack varyings, may split to make fully packed output
  139353. +
  139354. + Tm: only packing shader pair which vertex shader id is m
  139355. + Tm,n: only packing shader pair which vertex shader id
  139356. + is in range of [m, n]
  139357. + T-m: do not packing shader pair which vertex shader id is m
  139358. + T-m,n: do not packing shader pair which vertex shader id
  139359. + is in range of [m, n]
  139360. +
  139361. + LshaderIdx,min,max : set load balance (min, max) for shaderIdx
  139362. + if shaderIdx is -1, all shaders are impacted
  139363. + newMin = origMin * (min/100.);
  139364. + newMax = origMax * (max/100.);
  139365. + */
  139366. + gceOPTIMIZATION_VaryingPaking packVarying;
  139367. + gctINT _triageStart;
  139368. + gctINT _triageEnd;
  139369. + gctINT _loadBalanceShaderIdx;
  139370. + gctINT _loadBalanceMin;
  139371. + gctINT _loadBalanceMax;
  139372. +
  139373. + /* Do not generate immdeiate
  139374. +
  139375. + VC_OPTION=-NOIMM
  139376. +
  139377. + Force generate immediate even the machine model don't support it,
  139378. + for testing purpose only
  139379. +
  139380. + VC_OPTION=-FORCEIMM
  139381. + */
  139382. + gctBOOL noImmediate;
  139383. + gctBOOL forceImmediate;
  139384. +
  139385. + /* Power reduction mode options */
  139386. + gctBOOL needPowerOptimization;
  139387. +
  139388. + /* Patch TEXLD instruction by adding dummy texld
  139389. + (can be used to tune GPU power usage):
  139390. + for every TEXLD we seen, add n dummy TEXLD
  139391. +
  139392. + it can be enabled by environment variable:
  139393. +
  139394. + VC_OPTION=-PATCH_TEXLD:M:N
  139395. +
  139396. + (for each M texld, add N dummy texld)
  139397. + */
  139398. + gctINT patchEveryTEXLDs;
  139399. + gctINT patchDummyTEXLDs;
  139400. +
  139401. + /* Insert NOP after high power consumption instructions
  139402. +
  139403. + VC_OPTION="-INSERTNOP:MUL:MULLO:DP3:DP4:SEENTEXLD"
  139404. + */
  139405. + gctBOOL insertNOP;
  139406. + gctBOOL insertNOPAfterMUL;
  139407. + gctBOOL insertNOPAfterMULLO;
  139408. + gctBOOL insertNOPAfterDP3;
  139409. + gctBOOL insertNOPAfterDP4;
  139410. + gctBOOL insertNOPOnlyWhenTexldSeen;
  139411. +
  139412. + /* split MAD to MUL and ADD:
  139413. +
  139414. + VC_OPTION=-SPLITMAD
  139415. + */
  139416. + gctBOOL splitMAD;
  139417. +
  139418. + /* Convert vect3/vec4 operations to multiple vec2/vec1 operations
  139419. +
  139420. + VC_OPTION=-SPLITVEC:MUL:MULLO:DP3:DP4
  139421. + */
  139422. + gctBOOL splitVec;
  139423. + gctBOOL splitVec4MUL;
  139424. + gctBOOL splitVec4MULLO;
  139425. + gctBOOL splitVec4DP3;
  139426. + gctBOOL splitVec4DP4;
  139427. +
  139428. + /* turn/off features:
  139429. +
  139430. + VC_OPTION=-F:n,[0|1]
  139431. + Note: n must be decimal number
  139432. + */
  139433. + gctUINT featureBits;
  139434. +
  139435. + /* inline level (default 2 at O1):
  139436. +
  139437. + VC_OPTION=-INLINELEVEL:[0-3]
  139438. + 0: no inline
  139439. + 1: only inline the function only called once or small function
  139440. + 2: inline functions be called less than 5 times or medium size function
  139441. + 3: inline everything possible
  139442. + */
  139443. + gctUINT inlineLevel;
  139444. +} gcOPTIMIZER_OPTION;
  139445. +
  139446. +extern gcOPTIMIZER_OPTION theOptimizerOption;
  139447. +#define gcmGetOptimizerOption() gcGetOptimizerOption()
  139448. +
  139449. +#define gcmOPT_DUMP_SHADER_SRC() \
  139450. + (gcmGetOptimizerOption()->dumpShaderSource != 0)
  139451. +#define gcmOPT_DUMP_OPTIMIZER() \
  139452. + (gcmGetOptimizerOption()->dumpOptimizer != 0 || \
  139453. + gcmOPT_DUMP_OPTIMIZER_VERBOSE() )
  139454. +#define gcmOPT_DUMP_OPTIMIZER_VERBOSE() \
  139455. + (gcmGetOptimizerOption()->dumpOptimizerVerbose != 0)
  139456. +#define gcmOPT_DUMP_CODEGEN() \
  139457. + (gcmGetOptimizerOption()->dumpBEGenertedCode != 0 || \
  139458. + gcmOPT_DUMP_CODEGEN_VERBOSE() )
  139459. +#define gcmOPT_DUMP_CODEGEN_VERBOSE() \
  139460. + (gcmGetOptimizerOption()->dumpBEVerbose != 0)
  139461. +#define gcmOPT_DUMP_FINAL_IR() \
  139462. + (gcmGetOptimizerOption()->dumpBEFinalIR != 0)
  139463. +
  139464. +#define gcmOPT_SET_DUMP_SHADER_SRC(v) \
  139465. + gcmGetOptimizerOption()->dumpShaderSource = (v)
  139466. +
  139467. +#define gcmOPT_PATCH_TEXLD() (gcmGetOptimizerOption()->patchDummyTEXLDs != 0)
  139468. +#define gcmOPT_INSERT_NOP() (gcmGetOptimizerOption()->insertNOP == gcvTRUE)
  139469. +#define gcmOPT_SPLITMAD() (gcmGetOptimizerOption()->splitMAD == gcvTRUE)
  139470. +#define gcmOPT_SPLITVEC() (gcmGetOptimizerOption()->splitVec == gcvTRUE)
  139471. +
  139472. +#define gcmOPT_NOIMMEDIATE() (gcmGetOptimizerOption()->noImmediate == gcvTRUE)
  139473. +#define gcmOPT_FORCEIMMEDIATE() (gcmGetOptimizerOption()->forceImmediate == gcvTRUE)
  139474. +
  139475. +#define gcmOPT_PACKVARYING() (gcmGetOptimizerOption()->packVarying)
  139476. +#define gcmOPT_PACKVARYING_triageStart() (gcmGetOptimizerOption()->_triageStart)
  139477. +#define gcmOPT_PACKVARYING_triageEnd() (gcmGetOptimizerOption()->_triageEnd)
  139478. +
  139479. +#define gcmOPT_INLINELEVEL() (gcmGetOptimizerOption()->inlineLevel)
  139480. +
  139481. +/* Setters */
  139482. +#define gcmOPT_SetPatchTexld(m,n) (gcmGetOptimizerOption()->patchEveryTEXLDs = (m),\
  139483. + gcmGetOptimizerOption()->patchDummyTEXLDs = (n))
  139484. +#define gcmOPT_SetSplitVecMUL() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  139485. + gcmGetOptimizerOption()->splitVec4MUL = gcvTRUE)
  139486. +#define gcmOPT_SetSplitVecMULLO() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  139487. + gcmGetOptimizerOption()->splitVec4MULLO = gcvTRUE)
  139488. +#define gcmOPT_SetSplitVecDP3() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  139489. + gcmGetOptimizerOption()->splitVec4DP3 = gcvTRUE)
  139490. +#define gcmOPT_SetSplitVecDP4() (gcmGetOptimizerOption()->splitVec = gcvTRUE, \
  139491. + gcmGetOptimizerOption()->splitVec4DP4 = gcvTRUE)
  139492. +
  139493. +#define gcmOPT_SetPackVarying(v) (gcmGetOptimizerOption()->packVarying = v)
  139494. +
  139495. +#define FB_LIVERANGE_FIX1 0x0001
  139496. +
  139497. +
  139498. +#define PredefinedDummySamplerId 8
  139499. +
  139500. +/* Function argument qualifier */
  139501. +typedef enum _gceINPUT_OUTPUT
  139502. +{
  139503. + gcvFUNCTION_INPUT,
  139504. + gcvFUNCTION_OUTPUT,
  139505. + gcvFUNCTION_INOUT
  139506. +}
  139507. +gceINPUT_OUTPUT;
  139508. +
  139509. +/* Kernel function property flags. */
  139510. +typedef enum _gcePROPERTY_FLAGS
  139511. +{
  139512. + gcvPROPERTY_REQD_WORK_GRP_SIZE = 0x01
  139513. +}
  139514. +gceKERNEL_FUNCTION_PROPERTY_FLAGS;
  139515. +
  139516. +/* Uniform flags. */
  139517. +typedef enum _gceUNIFORM_FLAGS
  139518. +{
  139519. + gcvUNIFORM_KERNEL_ARG = 0x01,
  139520. + gcvUNIFORM_KERNEL_ARG_LOCAL = 0x02,
  139521. + gcvUNIFORM_KERNEL_ARG_SAMPLER = 0x04,
  139522. + gcvUNIFORM_LOCAL_ADDRESS_SPACE = 0x08,
  139523. + gcvUNIFORM_PRIVATE_ADDRESS_SPACE = 0x10,
  139524. + gcvUNIFORM_CONSTANT_ADDRESS_SPACE = 0x20,
  139525. + gcvUNIFORM_GLOBAL_SIZE = 0x40,
  139526. + gcvUNIFORM_LOCAL_SIZE = 0x80,
  139527. + gcvUNIFORM_NUM_GROUPS = 0x100,
  139528. + gcvUNIFORM_GLOBAL_OFFSET = 0x200,
  139529. + gcvUNIFORM_WORK_DIM = 0x400,
  139530. + gcvUNIFORM_KERNEL_ARG_CONSTANT = 0x800,
  139531. + gcvUNIFORM_KERNEL_ARG_LOCAL_MEM_SIZE = 0x1000,
  139532. + gcvUNIFORM_KERNEL_ARG_PRIVATE = 0x2000,
  139533. + gcvUNIFORM_LOADTIME_CONSTANT = 0x4000,
  139534. + gcvUNIFORM_IS_ARRAY = 0x8000,
  139535. +}
  139536. +gceUNIFORM_FLAGS;
  139537. +
  139538. +#define gcdUNIFORM_KERNEL_ARG_MASK (gcvUNIFORM_KERNEL_ARG | \
  139539. + gcvUNIFORM_KERNEL_ARG_LOCAL | \
  139540. + gcvUNIFORM_KERNEL_ARG_SAMPLER | \
  139541. + gcvUNIFORM_KERNEL_ARG_PRIVATE | \
  139542. + gcvUNIFORM_KERNEL_ARG_CONSTANT)
  139543. +
  139544. +typedef enum _gceVARIABLE_UPDATE_FLAGS
  139545. +{
  139546. + gcvVARIABLE_UPDATE_NOUPDATE = 0,
  139547. + gcvVARIABLE_UPDATE_TEMPREG,
  139548. + gcvVARIABLE_UPDATE_TYPE_QUALIFIER,
  139549. +}gceVARIABLE_UPDATE_FLAGS;
  139550. +
  139551. +typedef struct _gcMACHINE_INST
  139552. +{
  139553. + gctUINT state0;
  139554. + gctUINT state1;
  139555. + gctUINT state2;
  139556. + gctUINT state3;
  139557. +}gcMACHINE_INST, *gcMACHINE_INST_PTR;
  139558. +
  139559. +typedef struct _gcMACHINECODE
  139560. +{
  139561. + gcMACHINE_INST_PTR pCode; /* machine code */
  139562. + gctUINT instCount; /* 128-bit count */
  139563. + gctUINT maxConstRegNo;
  139564. + gctUINT maxTempRegNo;
  139565. + gctUINT endPCOfMainRoutine;
  139566. +}gcMACHINECODE, *gcMACHINECODE_PTR;
  139567. +
  139568. +typedef enum NP2_ADDRESS_MODE
  139569. +{
  139570. + NP2_ADDRESS_MODE_CLAMP = 0,
  139571. + NP2_ADDRESS_MODE_REPEAT = 1,
  139572. + NP2_ADDRESS_MODE_MIRROR = 2
  139573. +}NP2_ADDRESS_MODE;
  139574. +
  139575. +typedef struct _gcNPOT_PATCH_PARAM
  139576. +{
  139577. + gctINT samplerSlot;
  139578. + NP2_ADDRESS_MODE addressMode[3];
  139579. + gctINT texDimension; /* 2 or 3 */
  139580. +}gcNPOT_PATCH_PARAM, *gcNPOT_PATCH_PARAM_PTR;
  139581. +
  139582. +typedef struct _gcZBIAS_PATCH_PARAM
  139583. +{
  139584. + /* Driver uses this to program uniform that designating zbias */
  139585. + gctINT uniformAddr;
  139586. + gctINT channel;
  139587. +}gcZBIAS_PATCH_PARAM, *gcZBIAS_PATCH_PARAM_PTR;
  139588. +
  139589. +void
  139590. +gcGetOptionFromEnv(
  139591. + IN OUT gcOPTIMIZER_OPTION * Option
  139592. + );
  139593. +
  139594. +void
  139595. +gcSetOptimizerOption(
  139596. + IN gceSHADER_FLAGS Flags
  139597. + );
  139598. +
  139599. +gcOPTIMIZER_OPTION *
  139600. +gcGetOptimizerOption();
  139601. +
  139602. +/*******************************************************************************
  139603. +** gcSHADER_SetCompilerVersion
  139604. +**
  139605. +** Set the compiler version of a gcSHADER object.
  139606. +**
  139607. +** INPUT:
  139608. +**
  139609. +** gcSHADER Shader
  139610. +** Pointer to gcSHADER object
  139611. +**
  139612. +** gctINT *Version
  139613. +** Pointer to a two word version
  139614. +*/
  139615. +gceSTATUS
  139616. +gcSHADER_SetCompilerVersion(
  139617. + IN gcSHADER Shader,
  139618. + IN gctUINT32 *Version
  139619. + );
  139620. +
  139621. +/*******************************************************************************
  139622. +** gcSHADER_GetCompilerVersion
  139623. +**
  139624. +** Get the compiler version of a gcSHADER object.
  139625. +**
  139626. +** INPUT:
  139627. +**
  139628. +** gcSHADER Shader
  139629. +** Pointer to a gcSHADER object.
  139630. +**
  139631. +** OUTPUT:
  139632. +**
  139633. +** gctUINT32_PTR *CompilerVersion.
  139634. +** Pointer to holder of returned compilerVersion pointer
  139635. +*/
  139636. +gceSTATUS
  139637. +gcSHADER_GetCompilerVersion(
  139638. + IN gcSHADER Shader,
  139639. + OUT gctUINT32_PTR *CompilerVersion
  139640. + );
  139641. +
  139642. +/*******************************************************************************
  139643. +** gcSHADER_GetType
  139644. +**
  139645. +** Get the gcSHADER object's type.
  139646. +**
  139647. +** INPUT:
  139648. +**
  139649. +** gcSHADER Shader
  139650. +** Pointer to a gcSHADER object.
  139651. +**
  139652. +** OUTPUT:
  139653. +**
  139654. +** gctINT *Type.
  139655. +** Pointer to return shader type.
  139656. +*/
  139657. +gceSTATUS
  139658. +gcSHADER_GetType(
  139659. + IN gcSHADER Shader,
  139660. + OUT gctINT *Type
  139661. + );
  139662. +
  139663. +gctUINT
  139664. +gcSHADER_NextId();
  139665. +/*******************************************************************************
  139666. +** gcSHADER_Construct
  139667. +********************************************************************************
  139668. +**
  139669. +** Construct a new gcSHADER object.
  139670. +**
  139671. +** INPUT:
  139672. +**
  139673. +** gcoOS Hal
  139674. +** Pointer to an gcoHAL object.
  139675. +**
  139676. +** gctINT ShaderType
  139677. +** Type of gcSHADER object to cerate. 'ShaderType' can be one of the
  139678. +** following:
  139679. +**
  139680. +** gcSHADER_TYPE_VERTEX Vertex shader.
  139681. +** gcSHADER_TYPE_FRAGMENT Fragment shader.
  139682. +**
  139683. +** OUTPUT:
  139684. +**
  139685. +** gcSHADER * Shader
  139686. +** Pointer to a variable receiving the gcSHADER object pointer.
  139687. +*/
  139688. +gceSTATUS
  139689. +gcSHADER_Construct(
  139690. + IN gcoHAL Hal,
  139691. + IN gctINT ShaderType,
  139692. + OUT gcSHADER * Shader
  139693. + );
  139694. +
  139695. +/*******************************************************************************
  139696. +** gcSHADER_Destroy
  139697. +********************************************************************************
  139698. +**
  139699. +** Destroy a gcSHADER object.
  139700. +**
  139701. +** INPUT:
  139702. +**
  139703. +** gcSHADER Shader
  139704. +** Pointer to a gcSHADER object.
  139705. +**
  139706. +** OUTPUT:
  139707. +**
  139708. +** Nothing.
  139709. +*/
  139710. +gceSTATUS
  139711. +gcSHADER_Destroy(
  139712. + IN gcSHADER Shader
  139713. + );
  139714. +
  139715. +/*******************************************************************************
  139716. +** gcSHADER_Copy
  139717. +********************************************************************************
  139718. +**
  139719. +** Copy a gcSHADER object.
  139720. +**
  139721. +** INPUT:
  139722. +**
  139723. +** gcSHADER Shader
  139724. +** Pointer to a gcSHADER object.
  139725. +**
  139726. +** gcSHADER Source
  139727. +** Pointer to a gcSHADER object that will be copied.
  139728. +**
  139729. +** OUTPUT:
  139730. +**
  139731. +** Nothing.
  139732. +*/
  139733. +gceSTATUS
  139734. +gcSHADER_Copy(
  139735. + IN gcSHADER Shader,
  139736. + IN gcSHADER Source
  139737. + );
  139738. +
  139739. +/*******************************************************************************
  139740. +** gcSHADER_LoadHeader
  139741. +**
  139742. +** Load a gcSHADER object from a binary buffer. The binary buffer is layed out
  139743. +** as follows:
  139744. +** // Six word header
  139745. +** // Signature, must be 'S','H','D','R'.
  139746. +** gctINT8 signature[4];
  139747. +** gctUINT32 binFileVersion;
  139748. +** gctUINT32 compilerVersion[2];
  139749. +** gctUINT32 gcSLVersion;
  139750. +** gctUINT32 binarySize;
  139751. +**
  139752. +** INPUT:
  139753. +**
  139754. +** gcSHADER Shader
  139755. +** Pointer to a gcSHADER object.
  139756. +** Shader type will be returned if type in shader object is not gcSHADER_TYPE_PRECOMPILED
  139757. +**
  139758. +** gctPOINTER Buffer
  139759. +** Pointer to a binary buffer containing the shader data to load.
  139760. +**
  139761. +** gctSIZE_T BufferSize
  139762. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  139763. +**
  139764. +** OUTPUT:
  139765. +** nothing
  139766. +**
  139767. +*/
  139768. +gceSTATUS
  139769. +gcSHADER_LoadHeader(
  139770. + IN gcSHADER Shader,
  139771. + IN gctPOINTER Buffer,
  139772. + IN gctSIZE_T BufferSize,
  139773. + OUT gctUINT32 * ShaderVersion
  139774. + );
  139775. +
  139776. +/*******************************************************************************
  139777. +** gcSHADER_LoadKernel
  139778. +**
  139779. +** Load a kernel function given by name into gcSHADER object
  139780. +**
  139781. +** INPUT:
  139782. +**
  139783. +** gcSHADER Shader
  139784. +** Pointer to a gcSHADER object.
  139785. +**
  139786. +** gctSTRING KernelName
  139787. +** Pointer to a kernel function name
  139788. +**
  139789. +** OUTPUT:
  139790. +** nothing
  139791. +**
  139792. +*/
  139793. +gceSTATUS
  139794. +gcSHADER_LoadKernel(
  139795. + IN gcSHADER Shader,
  139796. + IN gctSTRING KernelName
  139797. + );
  139798. +
  139799. +/*******************************************************************************
  139800. +** gcSHADER_Load
  139801. +********************************************************************************
  139802. +**
  139803. +** Load a gcSHADER object from a binary buffer.
  139804. +**
  139805. +** INPUT:
  139806. +**
  139807. +** gcSHADER Shader
  139808. +** Pointer to a gcSHADER object.
  139809. +**
  139810. +** gctPOINTER Buffer
  139811. +** Pointer to a binary buffer containg the shader data to load.
  139812. +**
  139813. +** gctSIZE_T BufferSize
  139814. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  139815. +**
  139816. +** OUTPUT:
  139817. +**
  139818. +** Nothing.
  139819. +*/
  139820. +gceSTATUS
  139821. +gcSHADER_Load(
  139822. + IN gcSHADER Shader,
  139823. + IN gctPOINTER Buffer,
  139824. + IN gctSIZE_T BufferSize
  139825. + );
  139826. +
  139827. +/*******************************************************************************
  139828. +** gcSHADER_Save
  139829. +********************************************************************************
  139830. +**
  139831. +** Save a gcSHADER object to a binary buffer.
  139832. +**
  139833. +** INPUT:
  139834. +**
  139835. +** gcSHADER Shader
  139836. +** Pointer to a gcSHADER object.
  139837. +**
  139838. +** gctPOINTER Buffer
  139839. +** Pointer to a binary buffer to be used as storage for the gcSHADER
  139840. +** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
  139841. +** but the number of bytes required to hold the binary output for the
  139842. +** gcSHADER object will be returned.
  139843. +**
  139844. +** gctSIZE_T * BufferSize
  139845. +** Pointer to a variable holding the number of bytes allocated in
  139846. +** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
  139847. +**
  139848. +** OUTPUT:
  139849. +**
  139850. +** gctSIZE_T * BufferSize
  139851. +** Pointer to a variable receiving the number of bytes required to hold
  139852. +** the binary form of the gcSHADER object.
  139853. +*/
  139854. +gceSTATUS
  139855. +gcSHADER_Save(
  139856. + IN gcSHADER Shader,
  139857. + IN gctPOINTER Buffer,
  139858. + IN OUT gctSIZE_T * BufferSize
  139859. + );
  139860. +
  139861. +/*******************************************************************************
  139862. +** gcSHADER_LoadEx
  139863. +********************************************************************************
  139864. +**
  139865. +** Load a gcSHADER object from a binary buffer.
  139866. +**
  139867. +** INPUT:
  139868. +**
  139869. +** gcSHADER Shader
  139870. +** Pointer to a gcSHADER object.
  139871. +**
  139872. +** gctPOINTER Buffer
  139873. +** Pointer to a binary buffer containg the shader data to load.
  139874. +**
  139875. +** gctSIZE_T BufferSize
  139876. +** Number of bytes inside the binary buffer pointed to by 'Buffer'.
  139877. +**
  139878. +** OUTPUT:
  139879. +**
  139880. +** Nothing.
  139881. +*/
  139882. +gceSTATUS
  139883. +gcSHADER_LoadEx(
  139884. + IN gcSHADER Shader,
  139885. + IN gctPOINTER Buffer,
  139886. + IN gctSIZE_T BufferSize
  139887. + );
  139888. +
  139889. +/*******************************************************************************
  139890. +** gcSHADER_SaveEx
  139891. +********************************************************************************
  139892. +**
  139893. +** Save a gcSHADER object to a binary buffer.
  139894. +**
  139895. +** INPUT:
  139896. +**
  139897. +** gcSHADER Shader
  139898. +** Pointer to a gcSHADER object.
  139899. +**
  139900. +** gctPOINTER Buffer
  139901. +** Pointer to a binary buffer to be used as storage for the gcSHADER
  139902. +** object. If 'Buffer' is gcvNULL, the gcSHADER object will not be saved,
  139903. +** but the number of bytes required to hold the binary output for the
  139904. +** gcSHADER object will be returned.
  139905. +**
  139906. +** gctSIZE_T * BufferSize
  139907. +** Pointer to a variable holding the number of bytes allocated in
  139908. +** 'Buffer'. Only valid if 'Buffer' is not gcvNULL.
  139909. +**
  139910. +** OUTPUT:
  139911. +**
  139912. +** gctSIZE_T * BufferSize
  139913. +** Pointer to a variable receiving the number of bytes required to hold
  139914. +** the binary form of the gcSHADER object.
  139915. +*/
  139916. +gceSTATUS
  139917. +gcSHADER_SaveEx(
  139918. + IN gcSHADER Shader,
  139919. + IN gctPOINTER Buffer,
  139920. + IN OUT gctSIZE_T * BufferSize
  139921. + );
  139922. +
  139923. +/*******************************************************************************
  139924. +** gcSHADER_ReallocateAttributes
  139925. +**
  139926. +** Reallocate an array of pointers to gcATTRIBUTE objects.
  139927. +**
  139928. +** INPUT:
  139929. +**
  139930. +** gcSHADER Shader
  139931. +** Pointer to a gcSHADER object.
  139932. +**
  139933. +** gctSIZE_T Count
  139934. +** Array count to reallocate. 'Count' must be at least 1.
  139935. +*/
  139936. +gceSTATUS
  139937. +gcSHADER_ReallocateAttributes(
  139938. + IN gcSHADER Shader,
  139939. + IN gctSIZE_T Count
  139940. + );
  139941. +
  139942. +/*******************************************************************************
  139943. +** gcSHADER_AddAttribute
  139944. +********************************************************************************
  139945. +**
  139946. +** Add an attribute to a gcSHADER object.
  139947. +**
  139948. +** INPUT:
  139949. +**
  139950. +** gcSHADER Shader
  139951. +** Pointer to a gcSHADER object.
  139952. +**
  139953. +** gctCONST_STRING Name
  139954. +** Name of the attribute to add.
  139955. +**
  139956. +** gcSHADER_TYPE Type
  139957. +** Type of the attribute to add.
  139958. +**
  139959. +** gctSIZE_T Length
  139960. +** Array length of the attribute to add. 'Length' must be at least 1.
  139961. +**
  139962. +** gctBOOL IsTexture
  139963. +** gcvTRUE if the attribute is used as a texture coordinate, gcvFALSE if not.
  139964. +**
  139965. +** OUTPUT:
  139966. +**
  139967. +** gcATTRIBUTE * Attribute
  139968. +** Pointer to a variable receiving the gcATTRIBUTE object pointer.
  139969. +*/
  139970. +gceSTATUS
  139971. +gcSHADER_AddAttribute(
  139972. + IN gcSHADER Shader,
  139973. + IN gctCONST_STRING Name,
  139974. + IN gcSHADER_TYPE Type,
  139975. + IN gctSIZE_T Length,
  139976. + IN gctBOOL IsTexture,
  139977. + OUT gcATTRIBUTE * Attribute
  139978. + );
  139979. +
  139980. +/*******************************************************************************
  139981. +** gcSHADER_GetAttributeCount
  139982. +********************************************************************************
  139983. +**
  139984. +** Get the number of attributes for this shader.
  139985. +**
  139986. +** INPUT:
  139987. +**
  139988. +** gcSHADER Shader
  139989. +** Pointer to a gcSHADER object.
  139990. +**
  139991. +** OUTPUT:
  139992. +**
  139993. +** gctSIZE_T * Count
  139994. +** Pointer to a variable receiving the number of attributes.
  139995. +*/
  139996. +gceSTATUS
  139997. +gcSHADER_GetAttributeCount(
  139998. + IN gcSHADER Shader,
  139999. + OUT gctSIZE_T * Count
  140000. + );
  140001. +
  140002. +/*******************************************************************************
  140003. +** gcSHADER_GetAttribute
  140004. +********************************************************************************
  140005. +**
  140006. +** Get the gcATTRIBUTE object poniter for an indexed attribute for this shader.
  140007. +**
  140008. +** INPUT:
  140009. +**
  140010. +** gcSHADER Shader
  140011. +** Pointer to a gcSHADER object.
  140012. +**
  140013. +** gctUINT Index
  140014. +** Index of the attribute to retrieve.
  140015. +**
  140016. +** OUTPUT:
  140017. +**
  140018. +** gcATTRIBUTE * Attribute
  140019. +** Pointer to a variable receiving the gcATTRIBUTE object pointer.
  140020. +*/
  140021. +gceSTATUS
  140022. +gcSHADER_GetAttribute(
  140023. + IN gcSHADER Shader,
  140024. + IN gctUINT Index,
  140025. + OUT gcATTRIBUTE * Attribute
  140026. + );
  140027. +
  140028. +/*******************************************************************************
  140029. +** gcSHADER_ReallocateUniforms
  140030. +**
  140031. +** Reallocate an array of pointers to gcUNIFORM objects.
  140032. +**
  140033. +** INPUT:
  140034. +**
  140035. +** gcSHADER Shader
  140036. +** Pointer to a gcSHADER object.
  140037. +**
  140038. +** gctSIZE_T Count
  140039. +** Array count to reallocate. 'Count' must be at least 1.
  140040. +*/
  140041. +gceSTATUS
  140042. +gcSHADER_ReallocateUniforms(
  140043. + IN gcSHADER Shader,
  140044. + IN gctSIZE_T Count
  140045. + );
  140046. +
  140047. +/*******************************************************************************
  140048. +** gcSHADER_AddUniform
  140049. +********************************************************************************
  140050. +**
  140051. +** Add an uniform to a gcSHADER object.
  140052. +**
  140053. +** INPUT:
  140054. +**
  140055. +** gcSHADER Shader
  140056. +** Pointer to a gcSHADER object.
  140057. +**
  140058. +** gctCONST_STRING Name
  140059. +** Name of the uniform to add.
  140060. +**
  140061. +** gcSHADER_TYPE Type
  140062. +** Type of the uniform to add.
  140063. +**
  140064. +** gctSIZE_T Length
  140065. +** Array length of the uniform to add. 'Length' must be at least 1.
  140066. +**
  140067. +** OUTPUT:
  140068. +**
  140069. +** gcUNIFORM * Uniform
  140070. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  140071. +*/
  140072. +gceSTATUS
  140073. +gcSHADER_AddUniform(
  140074. + IN gcSHADER Shader,
  140075. + IN gctCONST_STRING Name,
  140076. + IN gcSHADER_TYPE Type,
  140077. + IN gctSIZE_T Length,
  140078. + OUT gcUNIFORM * Uniform
  140079. + );
  140080. +
  140081. +/*******************************************************************************
  140082. +** gcSHADER_AddPreRotationUniform
  140083. +********************************************************************************
  140084. +**
  140085. +** Add an uniform to a gcSHADER object.
  140086. +**
  140087. +** INPUT:
  140088. +**
  140089. +** gcSHADER Shader
  140090. +** Pointer to a gcSHADER object.
  140091. +**
  140092. +** gctCONST_STRING Name
  140093. +** Name of the uniform to add.
  140094. +**
  140095. +** gcSHADER_TYPE Type
  140096. +** Type of the uniform to add.
  140097. +**
  140098. +** gctSIZE_T Length
  140099. +** Array length of the uniform to add. 'Length' must be at least 1.
  140100. +**
  140101. +** gctINT col
  140102. +** Which uniform.
  140103. +**
  140104. +** OUTPUT:
  140105. +**
  140106. +** gcUNIFORM * Uniform
  140107. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  140108. +*/
  140109. +gceSTATUS
  140110. +gcSHADER_AddPreRotationUniform(
  140111. + IN gcSHADER Shader,
  140112. + IN gctCONST_STRING Name,
  140113. + IN gcSHADER_TYPE Type,
  140114. + IN gctSIZE_T Length,
  140115. + IN gctINT col,
  140116. + OUT gcUNIFORM * Uniform
  140117. + );
  140118. +
  140119. +/*******************************************************************************
  140120. +** gcSHADER_AddUniformEx
  140121. +********************************************************************************
  140122. +**
  140123. +** Add an uniform to a gcSHADER object.
  140124. +**
  140125. +** INPUT:
  140126. +**
  140127. +** gcSHADER Shader
  140128. +** Pointer to a gcSHADER object.
  140129. +**
  140130. +** gctCONST_STRING Name
  140131. +** Name of the uniform to add.
  140132. +**
  140133. +** gcSHADER_TYPE Type
  140134. +** Type of the uniform to add.
  140135. +**
  140136. +** gcSHADER_PRECISION precision
  140137. +** Precision of the uniform to add.
  140138. +**
  140139. +** gctSIZE_T Length
  140140. +** Array length of the uniform to add. 'Length' must be at least 1.
  140141. +**
  140142. +** OUTPUT:
  140143. +**
  140144. +** gcUNIFORM * Uniform
  140145. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  140146. +*/
  140147. +gceSTATUS
  140148. +gcSHADER_AddUniformEx(
  140149. + IN gcSHADER Shader,
  140150. + IN gctCONST_STRING Name,
  140151. + IN gcSHADER_TYPE Type,
  140152. + IN gcSHADER_PRECISION precision,
  140153. + IN gctSIZE_T Length,
  140154. + OUT gcUNIFORM * Uniform
  140155. + );
  140156. +
  140157. +/*******************************************************************************
  140158. +** gcSHADER_AddUniformEx1
  140159. +********************************************************************************
  140160. +**
  140161. +** Add an uniform to a gcSHADER object.
  140162. +**
  140163. +** INPUT:
  140164. +**
  140165. +** gcSHADER Shader
  140166. +** Pointer to a gcSHADER object.
  140167. +**
  140168. +** gctCONST_STRING Name
  140169. +** Name of the uniform to add.
  140170. +**
  140171. +** gcSHADER_TYPE Type
  140172. +** Type of the uniform to add.
  140173. +**
  140174. +** gcSHADER_PRECISION precision
  140175. +** Precision of the uniform to add.
  140176. +**
  140177. +** gctSIZE_T Length
  140178. +** Array length of the uniform to add. 'Length' must be at least 1.
  140179. +**
  140180. +** gcSHADER_VAR_CATEGORY varCategory
  140181. +** Variable category, normal or struct.
  140182. +**
  140183. +** gctUINT16 numStructureElement
  140184. +** If struct, its element number.
  140185. +**
  140186. +** gctINT16 parent
  140187. +** If struct, parent index in gcSHADER.variables.
  140188. +**
  140189. +** gctINT16 prevSibling
  140190. +** If struct, previous sibling index in gcSHADER.variables.
  140191. +**
  140192. +** OUTPUT:
  140193. +**
  140194. +** gcUNIFORM * Uniform
  140195. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  140196. +**
  140197. +** gctINT16* ThisUniformIndex
  140198. +** Returned value about uniform index in gcSHADER.
  140199. +*/
  140200. +gceSTATUS
  140201. +gcSHADER_AddUniformEx1(
  140202. + IN gcSHADER Shader,
  140203. + IN gctCONST_STRING Name,
  140204. + IN gcSHADER_TYPE Type,
  140205. + IN gcSHADER_PRECISION precision,
  140206. + IN gctSIZE_T Length,
  140207. + IN gctINT IsArray,
  140208. + IN gcSHADER_VAR_CATEGORY varCategory,
  140209. + IN gctUINT16 numStructureElement,
  140210. + IN gctINT16 parent,
  140211. + IN gctINT16 prevSibling,
  140212. + OUT gctINT16* ThisUniformIndex,
  140213. + OUT gcUNIFORM * Uniform
  140214. + );
  140215. +
  140216. +/*******************************************************************************
  140217. +** gcSHADER_GetUniformCount
  140218. +********************************************************************************
  140219. +**
  140220. +** Get the number of uniforms for this shader.
  140221. +**
  140222. +** INPUT:
  140223. +**
  140224. +** gcSHADER Shader
  140225. +** Pointer to a gcSHADER object.
  140226. +**
  140227. +** OUTPUT:
  140228. +**
  140229. +** gctSIZE_T * Count
  140230. +** Pointer to a variable receiving the number of uniforms.
  140231. +*/
  140232. +gceSTATUS
  140233. +gcSHADER_GetUniformCount(
  140234. + IN gcSHADER Shader,
  140235. + OUT gctSIZE_T * Count
  140236. + );
  140237. +
  140238. +/*******************************************************************************
  140239. +** gcSHADER_GetPreRotationUniform
  140240. +********************************************************************************
  140241. +**
  140242. +** Get the preRotate Uniform.
  140243. +**
  140244. +** INPUT:
  140245. +**
  140246. +** gcSHADER Shader
  140247. +** Pointer to a gcSHADER object.
  140248. +**
  140249. +** OUTPUT:
  140250. +**
  140251. +** gcUNIFORM ** pUniform
  140252. +** Pointer to a preRotation uniforms array.
  140253. +*/
  140254. +gceSTATUS
  140255. +gcSHADER_GetPreRotationUniform(
  140256. + IN gcSHADER Shader,
  140257. + OUT gcUNIFORM ** pUniform
  140258. + );
  140259. +
  140260. +/*******************************************************************************
  140261. +** gcSHADER_GetUniform
  140262. +********************************************************************************
  140263. +**
  140264. +** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
  140265. +**
  140266. +** INPUT:
  140267. +**
  140268. +** gcSHADER Shader
  140269. +** Pointer to a gcSHADER object.
  140270. +**
  140271. +** gctUINT Index
  140272. +** Index of the uniform to retrieve.
  140273. +**
  140274. +** OUTPUT:
  140275. +**
  140276. +** gcUNIFORM * Uniform
  140277. +** Pointer to a variable receiving the gcUNIFORM object pointer.
  140278. +*/
  140279. +gceSTATUS
  140280. +gcSHADER_GetUniform(
  140281. + IN gcSHADER Shader,
  140282. + IN gctUINT Index,
  140283. + OUT gcUNIFORM * Uniform
  140284. + );
  140285. +
  140286. +
  140287. +/*******************************************************************************
  140288. +** gcSHADER_GetUniformIndexingRange
  140289. +********************************************************************************
  140290. +**
  140291. +** Get the gcUNIFORM object pointer for an indexed uniform for this shader.
  140292. +**
  140293. +** INPUT:
  140294. +**
  140295. +** gcSHADER Shader
  140296. +** Pointer to a gcSHADER object.
  140297. +**
  140298. +** gctINT uniformIndex
  140299. +** Index of the start uniform.
  140300. +**
  140301. +** gctINT offset
  140302. +** Offset to indexing.
  140303. +**
  140304. +** OUTPUT:
  140305. +**
  140306. +** gctINT * LastUniformIndex
  140307. +** Pointer to index of last uniform in indexing range.
  140308. +**
  140309. +** gctINT * OffsetUniformIndex
  140310. +** Pointer to index of uniform that indexing at offset.
  140311. +**
  140312. +** gctINT * DeviationInOffsetUniform
  140313. +** Pointer to offset in uniform picked up.
  140314. +*/
  140315. +gceSTATUS
  140316. +gcSHADER_GetUniformIndexingRange(
  140317. + IN gcSHADER Shader,
  140318. + IN gctINT uniformIndex,
  140319. + IN gctINT offset,
  140320. + OUT gctINT * LastUniformIndex,
  140321. + OUT gctINT * OffsetUniformIndex,
  140322. + OUT gctINT * DeviationInOffsetUniform
  140323. + );
  140324. +
  140325. +/*******************************************************************************
  140326. +** gcSHADER_GetKernelFucntion
  140327. +**
  140328. +** Get the gcKERNEL_FUNCTION object pointer for an indexed kernel function for this shader.
  140329. +**
  140330. +** INPUT:
  140331. +**
  140332. +** gcSHADER Shader
  140333. +** Pointer to a gcSHADER object.
  140334. +**
  140335. +** gctUINT Index
  140336. +** Index of kernel function to retreive the name for.
  140337. +**
  140338. +** OUTPUT:
  140339. +**
  140340. +** gcKERNEL_FUNCTION * KernelFunction
  140341. +** Pointer to a variable receiving the gcKERNEL_FUNCTION object pointer.
  140342. +*/
  140343. +gceSTATUS
  140344. +gcSHADER_GetKernelFunction(
  140345. + IN gcSHADER Shader,
  140346. + IN gctUINT Index,
  140347. + OUT gcKERNEL_FUNCTION * KernelFunction
  140348. + );
  140349. +
  140350. +gceSTATUS
  140351. +gcSHADER_GetKernelFunctionByName(
  140352. + IN gcSHADER Shader,
  140353. + IN gctSTRING KernelName,
  140354. + OUT gcKERNEL_FUNCTION * KernelFunction
  140355. + );
  140356. +/*******************************************************************************
  140357. +** gcSHADER_GetKernelFunctionCount
  140358. +**
  140359. +** Get the number of kernel functions for this shader.
  140360. +**
  140361. +** INPUT:
  140362. +**
  140363. +** gcSHADER Shader
  140364. +** Pointer to a gcSHADER object.
  140365. +**
  140366. +** OUTPUT:
  140367. +**
  140368. +** gctSIZE_T * Count
  140369. +** Pointer to a variable receiving the number of kernel functions.
  140370. +*/
  140371. +gceSTATUS
  140372. +gcSHADER_GetKernelFunctionCount(
  140373. + IN gcSHADER Shader,
  140374. + OUT gctSIZE_T * Count
  140375. + );
  140376. +
  140377. +/*******************************************************************************
  140378. +** gcSHADER_ReallocateOutputs
  140379. +**
  140380. +** Reallocate an array of pointers to gcOUTPUT objects.
  140381. +**
  140382. +** INPUT:
  140383. +**
  140384. +** gcSHADER Shader
  140385. +** Pointer to a gcSHADER object.
  140386. +**
  140387. +** gctSIZE_T Count
  140388. +** Array count to reallocate. 'Count' must be at least 1.
  140389. +*/
  140390. +gceSTATUS
  140391. +gcSHADER_ReallocateOutputs(
  140392. + IN gcSHADER Shader,
  140393. + IN gctSIZE_T Count
  140394. + );
  140395. +
  140396. +/*******************************************************************************
  140397. +** gcSHADER_AddOutput
  140398. +********************************************************************************
  140399. +**
  140400. +** Add an output to a gcSHADER object.
  140401. +**
  140402. +** INPUT:
  140403. +**
  140404. +** gcSHADER Shader
  140405. +** Pointer to a gcSHADER object.
  140406. +**
  140407. +** gctCONST_STRING Name
  140408. +** Name of the output to add.
  140409. +**
  140410. +** gcSHADER_TYPE Type
  140411. +** Type of the output to add.
  140412. +**
  140413. +** gctSIZE_T Length
  140414. +** Array length of the output to add. 'Length' must be at least 1.
  140415. +**
  140416. +** gctUINT16 TempRegister
  140417. +** Temporary register index that holds the output value.
  140418. +**
  140419. +** OUTPUT:
  140420. +**
  140421. +** Nothing.
  140422. +*/
  140423. +gceSTATUS
  140424. +gcSHADER_AddOutput(
  140425. + IN gcSHADER Shader,
  140426. + IN gctCONST_STRING Name,
  140427. + IN gcSHADER_TYPE Type,
  140428. + IN gctSIZE_T Length,
  140429. + IN gctUINT16 TempRegister
  140430. + );
  140431. +
  140432. +gceSTATUS
  140433. +gcSHADER_AddOutputIndexed(
  140434. + IN gcSHADER Shader,
  140435. + IN gctCONST_STRING Name,
  140436. + IN gctSIZE_T Index,
  140437. + IN gctUINT16 TempIndex
  140438. + );
  140439. +
  140440. +/*******************************************************************************
  140441. +** gcSHADER_GetOutputCount
  140442. +********************************************************************************
  140443. +**
  140444. +** Get the number of outputs for this shader.
  140445. +**
  140446. +** INPUT:
  140447. +**
  140448. +** gcSHADER Shader
  140449. +** Pointer to a gcSHADER object.
  140450. +**
  140451. +** OUTPUT:
  140452. +**
  140453. +** gctSIZE_T * Count
  140454. +** Pointer to a variable receiving the number of outputs.
  140455. +*/
  140456. +gceSTATUS
  140457. +gcSHADER_GetOutputCount(
  140458. + IN gcSHADER Shader,
  140459. + OUT gctSIZE_T * Count
  140460. + );
  140461. +
  140462. +/*******************************************************************************
  140463. +** gcSHADER_GetOutput
  140464. +********************************************************************************
  140465. +**
  140466. +** Get the gcOUTPUT object pointer for an indexed output for this shader.
  140467. +**
  140468. +** INPUT:
  140469. +**
  140470. +** gcSHADER Shader
  140471. +** Pointer to a gcSHADER object.
  140472. +**
  140473. +** gctUINT Index
  140474. +** Index of output to retrieve.
  140475. +**
  140476. +** OUTPUT:
  140477. +**
  140478. +** gcOUTPUT * Output
  140479. +** Pointer to a variable receiving the gcOUTPUT object pointer.
  140480. +*/
  140481. +gceSTATUS
  140482. +gcSHADER_GetOutput(
  140483. + IN gcSHADER Shader,
  140484. + IN gctUINT Index,
  140485. + OUT gcOUTPUT * Output
  140486. + );
  140487. +
  140488. +
  140489. +/*******************************************************************************
  140490. +** gcSHADER_GetOutputByName
  140491. +********************************************************************************
  140492. +**
  140493. +** Get the gcOUTPUT object pointer for this shader by output name.
  140494. +**
  140495. +** INPUT:
  140496. +**
  140497. +** gcSHADER Shader
  140498. +** Pointer to a gcSHADER object.
  140499. +**
  140500. +** gctSTRING name
  140501. +** Name of output to retrieve.
  140502. +**
  140503. +** gctSIZE_T nameLength
  140504. +** Length of name to retrieve
  140505. +**
  140506. +** OUTPUT:
  140507. +**
  140508. +** gcOUTPUT * Output
  140509. +** Pointer to a variable receiving the gcOUTPUT object pointer.
  140510. +*/
  140511. +gceSTATUS
  140512. +gcSHADER_GetOutputByName(
  140513. + IN gcSHADER Shader,
  140514. + IN gctSTRING name,
  140515. + IN gctSIZE_T nameLength,
  140516. + OUT gcOUTPUT * Output
  140517. + );
  140518. +
  140519. +/*******************************************************************************
  140520. +** gcSHADER_ReallocateVariables
  140521. +**
  140522. +** Reallocate an array of pointers to gcVARIABLE objects.
  140523. +**
  140524. +** INPUT:
  140525. +**
  140526. +** gcSHADER Shader
  140527. +** Pointer to a gcSHADER object.
  140528. +**
  140529. +** gctSIZE_T Count
  140530. +** Array count to reallocate. 'Count' must be at least 1.
  140531. +*/
  140532. +gceSTATUS
  140533. +gcSHADER_ReallocateVariables(
  140534. + IN gcSHADER Shader,
  140535. + IN gctSIZE_T Count
  140536. + );
  140537. +
  140538. +/*******************************************************************************
  140539. +** gcSHADER_AddVariable
  140540. +********************************************************************************
  140541. +**
  140542. +** Add a variable to a gcSHADER object.
  140543. +**
  140544. +** INPUT:
  140545. +**
  140546. +** gcSHADER Shader
  140547. +** Pointer to a gcSHADER object.
  140548. +**
  140549. +** gctCONST_STRING Name
  140550. +** Name of the variable to add.
  140551. +**
  140552. +** gcSHADER_TYPE Type
  140553. +** Type of the variable to add.
  140554. +**
  140555. +** gctSIZE_T Length
  140556. +** Array length of the variable to add. 'Length' must be at least 1.
  140557. +**
  140558. +** gctUINT16 TempRegister
  140559. +** Temporary register index that holds the variable value.
  140560. +**
  140561. +** OUTPUT:
  140562. +**
  140563. +** Nothing.
  140564. +*/
  140565. +gceSTATUS
  140566. +gcSHADER_AddVariable(
  140567. + IN gcSHADER Shader,
  140568. + IN gctCONST_STRING Name,
  140569. + IN gcSHADER_TYPE Type,
  140570. + IN gctSIZE_T Length,
  140571. + IN gctUINT16 TempRegister
  140572. + );
  140573. +
  140574. +
  140575. +/*******************************************************************************
  140576. +** gcSHADER_AddVariableEx
  140577. +********************************************************************************
  140578. +**
  140579. +** Add a variable to a gcSHADER object.
  140580. +**
  140581. +** INPUT:
  140582. +**
  140583. +** gcSHADER Shader
  140584. +** Pointer to a gcSHADER object.
  140585. +**
  140586. +** gctCONST_STRING Name
  140587. +** Name of the variable to add.
  140588. +**
  140589. +** gcSHADER_TYPE Type
  140590. +** Type of the variable to add.
  140591. +**
  140592. +** gctSIZE_T Length
  140593. +** Array length of the variable to add. 'Length' must be at least 1.
  140594. +**
  140595. +** gctUINT16 TempRegister
  140596. +** Temporary register index that holds the variable value.
  140597. +**
  140598. +** gcSHADER_VAR_CATEGORY varCategory
  140599. +** Variable category, normal or struct.
  140600. +**
  140601. +** gctUINT16 numStructureElement
  140602. +** If struct, its element number.
  140603. +**
  140604. +** gctINT16 parent
  140605. +** If struct, parent index in gcSHADER.variables.
  140606. +**
  140607. +** gctINT16 prevSibling
  140608. +** If struct, previous sibling index in gcSHADER.variables.
  140609. +**
  140610. +** OUTPUT:
  140611. +**
  140612. +** gctINT16* ThisVarIndex
  140613. +** Returned value about variable index in gcSHADER.
  140614. +*/
  140615. +gceSTATUS
  140616. +gcSHADER_AddVariableEx(
  140617. + IN gcSHADER Shader,
  140618. + IN gctCONST_STRING Name,
  140619. + IN gcSHADER_TYPE Type,
  140620. + IN gctSIZE_T Length,
  140621. + IN gctUINT16 TempRegister,
  140622. + IN gcSHADER_VAR_CATEGORY varCategory,
  140623. + IN gctUINT16 numStructureElement,
  140624. + IN gctINT16 parent,
  140625. + IN gctINT16 prevSibling,
  140626. + OUT gctINT16* ThisVarIndex
  140627. + );
  140628. +
  140629. +/*******************************************************************************
  140630. +** gcSHADER_UpdateVariable
  140631. +********************************************************************************
  140632. +**
  140633. +** Update a variable to a gcSHADER object.
  140634. +**
  140635. +** INPUT:
  140636. +**
  140637. +** gcSHADER Shader
  140638. +** Pointer to a gcSHADER object.
  140639. +**
  140640. +** gctUINT Index
  140641. +** Index of variable to retrieve.
  140642. +**
  140643. +** gceVARIABLE_UPDATE_FLAGS flag
  140644. +** Flag which property of variable will be updated.
  140645. +**
  140646. +** gctUINT newValue
  140647. +** New value to update.
  140648. +**
  140649. +** OUTPUT:
  140650. +**
  140651. +** Nothing.
  140652. +*/
  140653. +gceSTATUS
  140654. +gcSHADER_UpdateVariable(
  140655. + IN gcSHADER Shader,
  140656. + IN gctUINT Index,
  140657. + IN gceVARIABLE_UPDATE_FLAGS flag,
  140658. + IN gctUINT newValue
  140659. + );
  140660. +
  140661. +/*******************************************************************************
  140662. +** gcSHADER_GetVariableCount
  140663. +********************************************************************************
  140664. +**
  140665. +** Get the number of variables for this shader.
  140666. +**
  140667. +** INPUT:
  140668. +**
  140669. +** gcSHADER Shader
  140670. +** Pointer to a gcSHADER object.
  140671. +**
  140672. +** OUTPUT:
  140673. +**
  140674. +** gctSIZE_T * Count
  140675. +** Pointer to a variable receiving the number of variables.
  140676. +*/
  140677. +gceSTATUS
  140678. +gcSHADER_GetVariableCount(
  140679. + IN gcSHADER Shader,
  140680. + OUT gctSIZE_T * Count
  140681. + );
  140682. +
  140683. +/*******************************************************************************
  140684. +** gcSHADER_GetVariable
  140685. +********************************************************************************
  140686. +**
  140687. +** Get the gcVARIABLE object pointer for an indexed variable for this shader.
  140688. +**
  140689. +** INPUT:
  140690. +**
  140691. +** gcSHADER Shader
  140692. +** Pointer to a gcSHADER object.
  140693. +**
  140694. +** gctUINT Index
  140695. +** Index of variable to retrieve.
  140696. +**
  140697. +** OUTPUT:
  140698. +**
  140699. +** gcVARIABLE * Variable
  140700. +** Pointer to a variable receiving the gcVARIABLE object pointer.
  140701. +*/
  140702. +gceSTATUS
  140703. +gcSHADER_GetVariable(
  140704. + IN gcSHADER Shader,
  140705. + IN gctUINT Index,
  140706. + OUT gcVARIABLE * Variable
  140707. + );
  140708. +
  140709. +/*******************************************************************************
  140710. +** gcSHADER_GetVariableIndexingRange
  140711. +********************************************************************************
  140712. +**
  140713. +** Get the gcVARIABLE indexing range.
  140714. +**
  140715. +** INPUT:
  140716. +**
  140717. +** gcSHADER Shader
  140718. +** Pointer to a gcSHADER object.
  140719. +**
  140720. +** gcVARIABLE variable
  140721. +** Start variable.
  140722. +**
  140723. +** gctBOOL whole
  140724. +** Indicate whether maximum indexing range is queried
  140725. +**
  140726. +** OUTPUT:
  140727. +**
  140728. +** gctUINT *Start
  140729. +** Pointer to range start (temp register index).
  140730. +**
  140731. +** gctUINT *End
  140732. +** Pointer to range end (temp register index).
  140733. +*/
  140734. +gceSTATUS
  140735. +gcSHADER_GetVariableIndexingRange(
  140736. + IN gcSHADER Shader,
  140737. + IN gcVARIABLE variable,
  140738. + IN gctBOOL whole,
  140739. + OUT gctUINT *Start,
  140740. + OUT gctUINT *End
  140741. + );
  140742. +
  140743. +/*******************************************************************************
  140744. +** gcSHADER_AddOpcode
  140745. +********************************************************************************
  140746. +**
  140747. +** Add an opcode to a gcSHADER object.
  140748. +**
  140749. +** INPUT:
  140750. +**
  140751. +** gcSHADER Shader
  140752. +** Pointer to a gcSHADER object.
  140753. +**
  140754. +** gcSL_OPCODE Opcode
  140755. +** Opcode to add.
  140756. +**
  140757. +** gctUINT16 TempRegister
  140758. +** Temporary register index that acts as the target of the opcode.
  140759. +**
  140760. +** gctUINT8 Enable
  140761. +** Write enable bits for the temporary register that acts as the target
  140762. +** of the opcode.
  140763. +**
  140764. +** gcSL_FORMAT Format
  140765. +** Format of the temporary register.
  140766. +**
  140767. +** OUTPUT:
  140768. +**
  140769. +** Nothing.
  140770. +*/
  140771. +gceSTATUS
  140772. +gcSHADER_AddOpcode(
  140773. + IN gcSHADER Shader,
  140774. + IN gcSL_OPCODE Opcode,
  140775. + IN gctUINT16 TempRegister,
  140776. + IN gctUINT8 Enable,
  140777. + IN gcSL_FORMAT Format
  140778. + );
  140779. +
  140780. +gceSTATUS
  140781. +gcSHADER_AddOpcode2(
  140782. + IN gcSHADER Shader,
  140783. + IN gcSL_OPCODE Opcode,
  140784. + IN gcSL_CONDITION Condition,
  140785. + IN gctUINT16 TempRegister,
  140786. + IN gctUINT8 Enable,
  140787. + IN gcSL_FORMAT Format
  140788. + );
  140789. +
  140790. +/*******************************************************************************
  140791. +** gcSHADER_AddOpcodeIndexed
  140792. +********************************************************************************
  140793. +**
  140794. +** Add an opcode to a gcSHADER object that writes to an dynamically indexed
  140795. +** target.
  140796. +**
  140797. +** INPUT:
  140798. +**
  140799. +** gcSHADER Shader
  140800. +** Pointer to a gcSHADER object.
  140801. +**
  140802. +** gcSL_OPCODE Opcode
  140803. +** Opcode to add.
  140804. +**
  140805. +** gctUINT16 TempRegister
  140806. +** Temporary register index that acts as the target of the opcode.
  140807. +**
  140808. +** gctUINT8 Enable
  140809. +** Write enable bits for the temporary register that acts as the
  140810. +** target of the opcode.
  140811. +**
  140812. +** gcSL_INDEXED Mode
  140813. +** Location of the dynamic index inside the temporary register. Valid
  140814. +** values can be:
  140815. +**
  140816. +** gcSL_INDEXED_X - Use x component of the temporary register.
  140817. +** gcSL_INDEXED_Y - Use y component of the temporary register.
  140818. +** gcSL_INDEXED_Z - Use z component of the temporary register.
  140819. +** gcSL_INDEXED_W - Use w component of the temporary register.
  140820. +**
  140821. +** gctUINT16 IndexRegister
  140822. +** Temporary register index that holds the dynamic index.
  140823. +**
  140824. +** gcSL_FORMAT Format
  140825. +** Format of the temporary register.
  140826. +**
  140827. +** OUTPUT:
  140828. +**
  140829. +** Nothing.
  140830. +*/
  140831. +gceSTATUS
  140832. +gcSHADER_AddOpcodeIndexed(
  140833. + IN gcSHADER Shader,
  140834. + IN gcSL_OPCODE Opcode,
  140835. + IN gctUINT16 TempRegister,
  140836. + IN gctUINT8 Enable,
  140837. + IN gcSL_INDEXED Mode,
  140838. + IN gctUINT16 IndexRegister,
  140839. + IN gcSL_FORMAT Format
  140840. + );
  140841. +
  140842. +/*******************************************************************************
  140843. +** gcSHADER_AddOpcodeConditionIndexed
  140844. +**
  140845. +** Add an opcode to a gcSHADER object that writes to an dynamically indexed
  140846. +** target.
  140847. +**
  140848. +** INPUT:
  140849. +**
  140850. +** gcSHADER Shader
  140851. +** Pointer to a gcSHADER object.
  140852. +**
  140853. +** gcSL_OPCODE Opcode
  140854. +** Opcode to add.
  140855. +**
  140856. +** gcSL_CONDITION Condition
  140857. +** Condition to check.
  140858. +**
  140859. +** gctUINT16 TempRegister
  140860. +** Temporary register index that acts as the target of the opcode.
  140861. +**
  140862. +** gctUINT8 Enable
  140863. +** Write enable bits for the temporary register that acts as the
  140864. +** target of the opcode.
  140865. +**
  140866. +** gcSL_INDEXED Indexed
  140867. +** Location of the dynamic index inside the temporary register. Valid
  140868. +** values can be:
  140869. +**
  140870. +** gcSL_INDEXED_X - Use x component of the temporary register.
  140871. +** gcSL_INDEXED_Y - Use y component of the temporary register.
  140872. +** gcSL_INDEXED_Z - Use z component of the temporary register.
  140873. +** gcSL_INDEXED_W - Use w component of the temporary register.
  140874. +**
  140875. +** gctUINT16 IndexRegister
  140876. +** Temporary register index that holds the dynamic index.
  140877. +**
  140878. +** OUTPUT:
  140879. +**
  140880. +** Nothing.
  140881. +*/
  140882. +gceSTATUS
  140883. +gcSHADER_AddOpcodeConditionIndexed(
  140884. + IN gcSHADER Shader,
  140885. + IN gcSL_OPCODE Opcode,
  140886. + IN gcSL_CONDITION Condition,
  140887. + IN gctUINT16 TempRegister,
  140888. + IN gctUINT8 Enable,
  140889. + IN gcSL_INDEXED Indexed,
  140890. + IN gctUINT16 IndexRegister,
  140891. + IN gcSL_FORMAT Format
  140892. + );
  140893. +
  140894. +/*******************************************************************************
  140895. +** gcSHADER_AddOpcodeConditional
  140896. +********************************************************************************
  140897. +**
  140898. +** Add an conditional opcode to a gcSHADER object.
  140899. +**
  140900. +** INPUT:
  140901. +**
  140902. +** gcSHADER Shader
  140903. +** Pointer to a gcSHADER object.
  140904. +**
  140905. +** gcSL_OPCODE Opcode
  140906. +** Opcode to add.
  140907. +**
  140908. +** gcSL_CONDITION Condition
  140909. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  140910. +** execute.
  140911. +**
  140912. +** gctUINT Label
  140913. +** Target label if 'Condition' evaluates to gcvTRUE.
  140914. +**
  140915. +** OUTPUT:
  140916. +**
  140917. +** Nothing.
  140918. +*/
  140919. +gceSTATUS
  140920. +gcSHADER_AddOpcodeConditional(
  140921. + IN gcSHADER Shader,
  140922. + IN gcSL_OPCODE Opcode,
  140923. + IN gcSL_CONDITION Condition,
  140924. + IN gctUINT Label
  140925. + );
  140926. +
  140927. +/*******************************************************************************
  140928. +** gcSHADER_AddOpcodeConditionalFormatted
  140929. +**
  140930. +** Add an conditional jump or call opcode to a gcSHADER object.
  140931. +**
  140932. +** INPUT:
  140933. +**
  140934. +** gcSHADER Shader
  140935. +** Pointer to a gcSHADER object.
  140936. +**
  140937. +** gcSL_OPCODE Opcode
  140938. +** Opcode to add.
  140939. +**
  140940. +** gcSL_CONDITION Condition
  140941. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  140942. +** execute.
  140943. +**
  140944. +** gcSL_FORMAT Format
  140945. +** Format of conditional operands
  140946. +**
  140947. +** gctUINT Label
  140948. +** Target label if 'Condition' evaluates to gcvTRUE.
  140949. +**
  140950. +** OUTPUT:
  140951. +**
  140952. +** Nothing.
  140953. +*/
  140954. +gceSTATUS
  140955. +gcSHADER_AddOpcodeConditionalFormatted(
  140956. + IN gcSHADER Shader,
  140957. + IN gcSL_OPCODE Opcode,
  140958. + IN gcSL_CONDITION Condition,
  140959. + IN gcSL_FORMAT Format,
  140960. + IN gctUINT Label
  140961. + );
  140962. +
  140963. +/*******************************************************************************
  140964. +** gcSHADER_AddOpcodeConditionalFormattedEnable
  140965. +**
  140966. +** Add an conditional jump or call opcode to a gcSHADER object.
  140967. +**
  140968. +** INPUT:
  140969. +**
  140970. +** gcSHADER Shader
  140971. +** Pointer to a gcSHADER object.
  140972. +**
  140973. +** gcSL_OPCODE Opcode
  140974. +** Opcode to add.
  140975. +**
  140976. +** gcSL_CONDITION Condition
  140977. +** Condition that needs to evaluate to gcvTRUE in order for the opcode to
  140978. +** execute.
  140979. +**
  140980. +** gcSL_FORMAT Format
  140981. +** Format of conditional operands
  140982. +**
  140983. +** gctUINT8 Enable
  140984. +** Write enable value for the target of the opcode.
  140985. +**
  140986. +** gctUINT Label
  140987. +** Target label if 'Condition' evaluates to gcvTRUE.
  140988. +**
  140989. +** OUTPUT:
  140990. +**
  140991. +** Nothing.
  140992. +*/
  140993. +gceSTATUS
  140994. +gcSHADER_AddOpcodeConditionalFormattedEnable(
  140995. + IN gcSHADER Shader,
  140996. + IN gcSL_OPCODE Opcode,
  140997. + IN gcSL_CONDITION Condition,
  140998. + IN gcSL_FORMAT Format,
  140999. + IN gctUINT8 Enable,
  141000. + IN gctUINT Label
  141001. + );
  141002. +
  141003. +/*******************************************************************************
  141004. +** gcSHADER_AddLabel
  141005. +********************************************************************************
  141006. +**
  141007. +** Define a label at the current instruction of a gcSHADER object.
  141008. +**
  141009. +** INPUT:
  141010. +**
  141011. +** gcSHADER Shader
  141012. +** Pointer to a gcSHADER object.
  141013. +**
  141014. +** gctUINT Label
  141015. +** Label to define.
  141016. +**
  141017. +** OUTPUT:
  141018. +**
  141019. +** Nothing.
  141020. +*/
  141021. +gceSTATUS
  141022. +gcSHADER_AddLabel(
  141023. + IN gcSHADER Shader,
  141024. + IN gctUINT Label
  141025. + );
  141026. +
  141027. +/*******************************************************************************
  141028. +** gcSHADER_AddSource
  141029. +********************************************************************************
  141030. +**
  141031. +** Add a source operand to a gcSHADER object.
  141032. +**
  141033. +** INPUT:
  141034. +**
  141035. +** gcSHADER Shader
  141036. +** Pointer to a gcSHADER object.
  141037. +**
  141038. +** gcSL_TYPE Type
  141039. +** Type of the source operand.
  141040. +**
  141041. +** gctUINT16 SourceIndex
  141042. +** Index of the source operand.
  141043. +**
  141044. +** gctUINT8 Swizzle
  141045. +** x, y, z, and w swizzle values packed into one 8-bit value.
  141046. +**
  141047. +** gcSL_FORMAT Format
  141048. +** Format of the source operand.
  141049. +**
  141050. +** OUTPUT:
  141051. +**
  141052. +** Nothing.
  141053. +*/
  141054. +gceSTATUS
  141055. +gcSHADER_AddSource(
  141056. + IN gcSHADER Shader,
  141057. + IN gcSL_TYPE Type,
  141058. + IN gctUINT16 SourceIndex,
  141059. + IN gctUINT8 Swizzle,
  141060. + IN gcSL_FORMAT Format
  141061. + );
  141062. +
  141063. +/*******************************************************************************
  141064. +** gcSHADER_AddSourceIndexed
  141065. +********************************************************************************
  141066. +**
  141067. +** Add a dynamically indexed source operand to a gcSHADER object.
  141068. +**
  141069. +** INPUT:
  141070. +**
  141071. +** gcSHADER Shader
  141072. +** Pointer to a gcSHADER object.
  141073. +**
  141074. +** gcSL_TYPE Type
  141075. +** Type of the source operand.
  141076. +**
  141077. +** gctUINT16 SourceIndex
  141078. +** Index of the source operand.
  141079. +**
  141080. +** gctUINT8 Swizzle
  141081. +** x, y, z, and w swizzle values packed into one 8-bit value.
  141082. +**
  141083. +** gcSL_INDEXED Mode
  141084. +** Addressing mode for the index.
  141085. +**
  141086. +** gctUINT16 IndexRegister
  141087. +** Temporary register index that holds the dynamic index.
  141088. +**
  141089. +** gcSL_FORMAT Format
  141090. +** Format of the source operand.
  141091. +**
  141092. +** OUTPUT:
  141093. +**
  141094. +** Nothing.
  141095. +*/
  141096. +gceSTATUS
  141097. +gcSHADER_AddSourceIndexed(
  141098. + IN gcSHADER Shader,
  141099. + IN gcSL_TYPE Type,
  141100. + IN gctUINT16 SourceIndex,
  141101. + IN gctUINT8 Swizzle,
  141102. + IN gcSL_INDEXED Mode,
  141103. + IN gctUINT16 IndexRegister,
  141104. + IN gcSL_FORMAT Format
  141105. + );
  141106. +
  141107. +/*******************************************************************************
  141108. +** gcSHADER_AddSourceAttribute
  141109. +********************************************************************************
  141110. +**
  141111. +** Add an attribute as a source operand to a gcSHADER object.
  141112. +**
  141113. +** INPUT:
  141114. +**
  141115. +** gcSHADER Shader
  141116. +** Pointer to a gcSHADER object.
  141117. +**
  141118. +** gcATTRIBUTE Attribute
  141119. +** Pointer to a gcATTRIBUTE object.
  141120. +**
  141121. +** gctUINT8 Swizzle
  141122. +** x, y, z, and w swizzle values packed into one 8-bit value.
  141123. +**
  141124. +** gctINT Index
  141125. +** Static index into the attribute in case the attribute is a matrix
  141126. +** or array.
  141127. +**
  141128. +** OUTPUT:
  141129. +**
  141130. +** Nothing.
  141131. +*/
  141132. +gceSTATUS
  141133. +gcSHADER_AddSourceAttribute(
  141134. + IN gcSHADER Shader,
  141135. + IN gcATTRIBUTE Attribute,
  141136. + IN gctUINT8 Swizzle,
  141137. + IN gctINT Index
  141138. + );
  141139. +
  141140. +/*******************************************************************************
  141141. +** gcSHADER_AddSourceAttributeIndexed
  141142. +********************************************************************************
  141143. +**
  141144. +** Add an indexed attribute as a source operand to a gcSHADER object.
  141145. +**
  141146. +** INPUT:
  141147. +**
  141148. +** gcSHADER Shader
  141149. +** Pointer to a gcSHADER object.
  141150. +**
  141151. +** gcATTRIBUTE Attribute
  141152. +** Pointer to a gcATTRIBUTE object.
  141153. +**
  141154. +** gctUINT8 Swizzle
  141155. +** x, y, z, and w swizzle values packed into one 8-bit value.
  141156. +**
  141157. +** gctINT Index
  141158. +** Static index into the attribute in case the attribute is a matrix
  141159. +** or array.
  141160. +**
  141161. +** gcSL_INDEXED Mode
  141162. +** Addressing mode of the dynamic index.
  141163. +**
  141164. +** gctUINT16 IndexRegister
  141165. +** Temporary register index that holds the dynamic index.
  141166. +**
  141167. +** OUTPUT:
  141168. +**
  141169. +** Nothing.
  141170. +*/
  141171. +gceSTATUS
  141172. +gcSHADER_AddSourceAttributeIndexed(
  141173. + IN gcSHADER Shader,
  141174. + IN gcATTRIBUTE Attribute,
  141175. + IN gctUINT8 Swizzle,
  141176. + IN gctINT Index,
  141177. + IN gcSL_INDEXED Mode,
  141178. + IN gctUINT16 IndexRegister
  141179. + );
  141180. +
  141181. +/*******************************************************************************
  141182. +** gcSHADER_AddSourceUniform
  141183. +********************************************************************************
  141184. +**
  141185. +** Add a uniform as a source operand to a gcSHADER object.
  141186. +**
  141187. +** INPUT:
  141188. +**
  141189. +** gcSHADER Shader
  141190. +** Pointer to a gcSHADER object.
  141191. +**
  141192. +** gcUNIFORM Uniform
  141193. +** Pointer to a gcUNIFORM object.
  141194. +**
  141195. +** gctUINT8 Swizzle
  141196. +** x, y, z, and w swizzle values packed into one 8-bit value.
  141197. +**
  141198. +** gctINT Index
  141199. +** Static index into the uniform in case the uniform is a matrix or
  141200. +** array.
  141201. +**
  141202. +** OUTPUT:
  141203. +**
  141204. +** Nothing.
  141205. +*/
  141206. +gceSTATUS
  141207. +gcSHADER_AddSourceUniform(
  141208. + IN gcSHADER Shader,
  141209. + IN gcUNIFORM Uniform,
  141210. + IN gctUINT8 Swizzle,
  141211. + IN gctINT Index
  141212. + );
  141213. +
  141214. +/*******************************************************************************
  141215. +** gcSHADER_AddSourceUniformIndexed
  141216. +********************************************************************************
  141217. +**
  141218. +** Add an indexed uniform as a source operand to a gcSHADER object.
  141219. +**
  141220. +** INPUT:
  141221. +**
  141222. +** gcSHADER Shader
  141223. +** Pointer to a gcSHADER object.
  141224. +**
  141225. +** gcUNIFORM Uniform
  141226. +** Pointer to a gcUNIFORM object.
  141227. +**
  141228. +** gctUINT8 Swizzle
  141229. +** x, y, z, and w swizzle values packed into one 8-bit value.
  141230. +**
  141231. +** gctINT Index
  141232. +** Static index into the uniform in case the uniform is a matrix or
  141233. +** array.
  141234. +**
  141235. +** gcSL_INDEXED Mode
  141236. +** Addressing mode of the dynamic index.
  141237. +**
  141238. +** gctUINT16 IndexRegister
  141239. +** Temporary register index that holds the dynamic index.
  141240. +**
  141241. +** OUTPUT:
  141242. +**
  141243. +** Nothing.
  141244. +*/
  141245. +gceSTATUS
  141246. +gcSHADER_AddSourceUniformIndexed(
  141247. + IN gcSHADER Shader,
  141248. + IN gcUNIFORM Uniform,
  141249. + IN gctUINT8 Swizzle,
  141250. + IN gctINT Index,
  141251. + IN gcSL_INDEXED Mode,
  141252. + IN gctUINT16 IndexRegister
  141253. + );
  141254. +
  141255. +gceSTATUS
  141256. +gcSHADER_AddSourceSamplerIndexed(
  141257. + IN gcSHADER Shader,
  141258. + IN gctUINT8 Swizzle,
  141259. + IN gcSL_INDEXED Mode,
  141260. + IN gctUINT16 IndexRegister
  141261. + );
  141262. +
  141263. +gceSTATUS
  141264. +gcSHADER_AddSourceAttributeFormatted(
  141265. + IN gcSHADER Shader,
  141266. + IN gcATTRIBUTE Attribute,
  141267. + IN gctUINT8 Swizzle,
  141268. + IN gctINT Index,
  141269. + IN gcSL_FORMAT Format
  141270. + );
  141271. +
  141272. +gceSTATUS
  141273. +gcSHADER_AddSourceAttributeIndexedFormatted(
  141274. + IN gcSHADER Shader,
  141275. + IN gcATTRIBUTE Attribute,
  141276. + IN gctUINT8 Swizzle,
  141277. + IN gctINT Index,
  141278. + IN gcSL_INDEXED Mode,
  141279. + IN gctUINT16 IndexRegister,
  141280. + IN gcSL_FORMAT Format
  141281. + );
  141282. +
  141283. +gceSTATUS
  141284. +gcSHADER_AddSourceUniformFormatted(
  141285. + IN gcSHADER Shader,
  141286. + IN gcUNIFORM Uniform,
  141287. + IN gctUINT8 Swizzle,
  141288. + IN gctINT Index,
  141289. + IN gcSL_FORMAT Format
  141290. + );
  141291. +
  141292. +gceSTATUS
  141293. +gcSHADER_AddSourceUniformIndexedFormatted(
  141294. + IN gcSHADER Shader,
  141295. + IN gcUNIFORM Uniform,
  141296. + IN gctUINT8 Swizzle,
  141297. + IN gctINT Index,
  141298. + IN gcSL_INDEXED Mode,
  141299. + IN gctUINT16 IndexRegister,
  141300. + IN gcSL_FORMAT Format
  141301. + );
  141302. +
  141303. +gceSTATUS
  141304. +gcSHADER_AddSourceSamplerIndexedFormatted(
  141305. + IN gcSHADER Shader,
  141306. + IN gctUINT8 Swizzle,
  141307. + IN gcSL_INDEXED Mode,
  141308. + IN gctUINT16 IndexRegister,
  141309. + IN gcSL_FORMAT Format
  141310. + );
  141311. +
  141312. +/*******************************************************************************
  141313. +** gcSHADER_AddSourceConstant
  141314. +********************************************************************************
  141315. +**
  141316. +** Add a constant floating point value as a source operand to a gcSHADER
  141317. +** object.
  141318. +**
  141319. +** INPUT:
  141320. +**
  141321. +** gcSHADER Shader
  141322. +** Pointer to a gcSHADER object.
  141323. +**
  141324. +** gctFLOAT Constant
  141325. +** Floating point constant.
  141326. +**
  141327. +** OUTPUT:
  141328. +**
  141329. +** Nothing.
  141330. +*/
  141331. +gceSTATUS
  141332. +gcSHADER_AddSourceConstant(
  141333. + IN gcSHADER Shader,
  141334. + IN gctFLOAT Constant
  141335. + );
  141336. +
  141337. +/*******************************************************************************
  141338. +** gcSHADER_AddSourceConstantFormatted
  141339. +********************************************************************************
  141340. +**
  141341. +** Add a constant value as a source operand to a gcSHADER
  141342. +** object.
  141343. +**
  141344. +** INPUT:
  141345. +**
  141346. +** gcSHADER Shader
  141347. +** Pointer to a gcSHADER object.
  141348. +**
  141349. +** void * Constant
  141350. +** Pointer to constant.
  141351. +**
  141352. +** gcSL_FORMAT Format
  141353. +**
  141354. +** OUTPUT:
  141355. +**
  141356. +** Nothing.
  141357. +*/
  141358. +gceSTATUS
  141359. +gcSHADER_AddSourceConstantFormatted(
  141360. + IN gcSHADER Shader,
  141361. + IN void *Constant,
  141362. + IN gcSL_FORMAT Format
  141363. + );
  141364. +
  141365. +/*******************************************************************************
  141366. +** gcSHADER_Pack
  141367. +********************************************************************************
  141368. +**
  141369. +** Pack a dynamically created gcSHADER object by trimming the allocated arrays
  141370. +** and resolving all the labeling.
  141371. +**
  141372. +** INPUT:
  141373. +**
  141374. +** gcSHADER Shader
  141375. +** Pointer to a gcSHADER object.
  141376. +**
  141377. +** OUTPUT:
  141378. +**
  141379. +** Nothing.
  141380. +*/
  141381. +gceSTATUS
  141382. +gcSHADER_Pack(
  141383. + IN gcSHADER Shader
  141384. + );
  141385. +
  141386. +/*******************************************************************************
  141387. +** gcSHADER_SetOptimizationOption
  141388. +********************************************************************************
  141389. +**
  141390. +** Set optimization option of a gcSHADER object.
  141391. +**
  141392. +** INPUT:
  141393. +**
  141394. +** gcSHADER Shader
  141395. +** Pointer to a gcSHADER object.
  141396. +**
  141397. +** gctUINT OptimizationOption
  141398. +** Optimization option. Can be one of the following:
  141399. +**
  141400. +** 0 - No optimization.
  141401. +** 1 - Full optimization.
  141402. +** Other value - For optimizer testing.
  141403. +**
  141404. +** OUTPUT:
  141405. +**
  141406. +** Nothing.
  141407. +*/
  141408. +gceSTATUS
  141409. +gcSHADER_SetOptimizationOption(
  141410. + IN gcSHADER Shader,
  141411. + IN gctUINT OptimizationOption
  141412. + );
  141413. +
  141414. +/*******************************************************************************
  141415. +** gcSHADER_ReallocateFunctions
  141416. +**
  141417. +** Reallocate an array of pointers to gcFUNCTION objects.
  141418. +**
  141419. +** INPUT:
  141420. +**
  141421. +** gcSHADER Shader
  141422. +** Pointer to a gcSHADER object.
  141423. +**
  141424. +** gctSIZE_T Count
  141425. +** Array count to reallocate. 'Count' must be at least 1.
  141426. +*/
  141427. +gceSTATUS
  141428. +gcSHADER_ReallocateFunctions(
  141429. + IN gcSHADER Shader,
  141430. + IN gctSIZE_T Count
  141431. + );
  141432. +
  141433. +gceSTATUS
  141434. +gcSHADER_AddFunction(
  141435. + IN gcSHADER Shader,
  141436. + IN gctCONST_STRING Name,
  141437. + OUT gcFUNCTION * Function
  141438. + );
  141439. +
  141440. +gceSTATUS
  141441. +gcSHADER_ReallocateKernelFunctions(
  141442. + IN gcSHADER Shader,
  141443. + IN gctSIZE_T Count
  141444. + );
  141445. +
  141446. +gceSTATUS
  141447. +gcSHADER_AddKernelFunction(
  141448. + IN gcSHADER Shader,
  141449. + IN gctCONST_STRING Name,
  141450. + OUT gcKERNEL_FUNCTION * KernelFunction
  141451. + );
  141452. +
  141453. +gceSTATUS
  141454. +gcSHADER_BeginFunction(
  141455. + IN gcSHADER Shader,
  141456. + IN gcFUNCTION Function
  141457. + );
  141458. +
  141459. +gceSTATUS
  141460. +gcSHADER_EndFunction(
  141461. + IN gcSHADER Shader,
  141462. + IN gcFUNCTION Function
  141463. + );
  141464. +
  141465. +gceSTATUS
  141466. +gcSHADER_BeginKernelFunction(
  141467. + IN gcSHADER Shader,
  141468. + IN gcKERNEL_FUNCTION KernelFunction
  141469. + );
  141470. +
  141471. +gceSTATUS
  141472. +gcSHADER_EndKernelFunction(
  141473. + IN gcSHADER Shader,
  141474. + IN gcKERNEL_FUNCTION KernelFunction,
  141475. + IN gctSIZE_T LocalMemorySize
  141476. + );
  141477. +
  141478. +gceSTATUS
  141479. +gcSHADER_SetMaxKernelFunctionArgs(
  141480. + IN gcSHADER Shader,
  141481. + IN gctUINT32 MaxKernelFunctionArgs
  141482. + );
  141483. +
  141484. +/*******************************************************************************
  141485. +** gcSHADER_SetConstantMemorySize
  141486. +**
  141487. +** Set the constant memory address space size of a gcSHADER object.
  141488. +**
  141489. +** INPUT:
  141490. +**
  141491. +** gcSHADER Shader
  141492. +** Pointer to a gcSHADER object.
  141493. +**
  141494. +** gctSIZE_T ConstantMemorySize
  141495. +** Constant memory size in bytes
  141496. +**
  141497. +** gctCHAR *ConstantMemoryBuffer
  141498. +** Constant memory buffer
  141499. +*/
  141500. +gceSTATUS
  141501. +gcSHADER_SetConstantMemorySize(
  141502. + IN gcSHADER Shader,
  141503. + IN gctSIZE_T ConstantMemorySize,
  141504. + IN gctCHAR * ConstantMemoryBuffer
  141505. + );
  141506. +
  141507. +/*******************************************************************************
  141508. +** gcSHADER_GetConstantMemorySize
  141509. +**
  141510. +** Set the constant memory address space size of a gcSHADER object.
  141511. +**
  141512. +** INPUT:
  141513. +**
  141514. +** gcSHADER Shader
  141515. +** Pointer to a gcSHADER object.
  141516. +**
  141517. +** OUTPUT:
  141518. +**
  141519. +** gctSIZE_T * ConstantMemorySize
  141520. +** Pointer to a variable receiving constant memory size in bytes
  141521. +**
  141522. +** gctCHAR **ConstantMemoryBuffer.
  141523. +** Pointer to a variable for returned shader constant memory buffer.
  141524. +*/
  141525. +gceSTATUS
  141526. +gcSHADER_GetConstantMemorySize(
  141527. + IN gcSHADER Shader,
  141528. + OUT gctSIZE_T * ConstantMemorySize,
  141529. + OUT gctCHAR ** ConstantMemoryBuffer
  141530. + );
  141531. +
  141532. +/*******************************************************************************
  141533. +** gcSHADER_SetPrivateMemorySize
  141534. +**
  141535. +** Set the private memory address space size of a gcSHADER object.
  141536. +**
  141537. +** INPUT:
  141538. +**
  141539. +** gcSHADER Shader
  141540. +** Pointer to a gcSHADER object.
  141541. +**
  141542. +** gctSIZE_T PrivateMemorySize
  141543. +** Private memory size in bytes
  141544. +*/
  141545. +gceSTATUS
  141546. +gcSHADER_SetPrivateMemorySize(
  141547. + IN gcSHADER Shader,
  141548. + IN gctSIZE_T PrivateMemorySize
  141549. + );
  141550. +
  141551. +/*******************************************************************************
  141552. +** gcSHADER_GetPrivateMemorySize
  141553. +**
  141554. +** Set the private memory address space size of a gcSHADER object.
  141555. +**
  141556. +** INPUT:
  141557. +**
  141558. +** gcSHADER Shader
  141559. +** Pointer to a gcSHADER object.
  141560. +**
  141561. +** OUTPUT:
  141562. +**
  141563. +** gctSIZE_T * PrivateMemorySize
  141564. +** Pointer to a variable receiving private memory size in bytes
  141565. +*/
  141566. +gceSTATUS
  141567. +gcSHADER_GetPrivateMemorySize(
  141568. + IN gcSHADER Shader,
  141569. + OUT gctSIZE_T * PrivateMemorySize
  141570. + );
  141571. +
  141572. +/*******************************************************************************
  141573. +** gcSHADER_SetLocalMemorySize
  141574. +**
  141575. +** Set the local memory address space size of a gcSHADER object.
  141576. +**
  141577. +** INPUT:
  141578. +**
  141579. +** gcSHADER Shader
  141580. +** Pointer to a gcSHADER object.
  141581. +**
  141582. +** gctSIZE_T LocalMemorySize
  141583. +** Local memory size in bytes
  141584. +*/
  141585. +gceSTATUS
  141586. +gcSHADER_SetLocalMemorySize(
  141587. + IN gcSHADER Shader,
  141588. + IN gctSIZE_T LocalMemorySize
  141589. + );
  141590. +
  141591. +/*******************************************************************************
  141592. +** gcSHADER_GetLocalMemorySize
  141593. +**
  141594. +** Set the local memory address space size of a gcSHADER object.
  141595. +**
  141596. +** INPUT:
  141597. +**
  141598. +** gcSHADER Shader
  141599. +** Pointer to a gcSHADER object.
  141600. +**
  141601. +** OUTPUT:
  141602. +**
  141603. +** gctSIZE_T * LocalMemorySize
  141604. +** Pointer to a variable receiving lcoal memory size in bytes
  141605. +*/
  141606. +gceSTATUS
  141607. +gcSHADER_GetLocalMemorySize(
  141608. + IN gcSHADER Shader,
  141609. + OUT gctSIZE_T * LocalMemorySize
  141610. + );
  141611. +
  141612. +
  141613. +/*******************************************************************************
  141614. +** gcSHADER_CheckValidity
  141615. +**
  141616. +** Check validity for a gcSHADER object.
  141617. +**
  141618. +** INPUT:
  141619. +**
  141620. +** gcSHADER Shader
  141621. +** Pointer to a gcSHADER object.
  141622. +**
  141623. +*/
  141624. +gceSTATUS
  141625. +gcSHADER_CheckValidity(
  141626. + IN gcSHADER Shader
  141627. + );
  141628. +
  141629. +#if gcdUSE_WCLIP_PATCH
  141630. +gceSTATUS
  141631. +gcATTRIBUTE_IsPosition(
  141632. + IN gcATTRIBUTE Attribute,
  141633. + OUT gctBOOL * IsPosition
  141634. + );
  141635. +#endif
  141636. +
  141637. +/*******************************************************************************
  141638. +** gcATTRIBUTE_GetType
  141639. +********************************************************************************
  141640. +**
  141641. +** Get the type and array length of a gcATTRIBUTE object.
  141642. +**
  141643. +** INPUT:
  141644. +**
  141645. +** gcATTRIBUTE Attribute
  141646. +** Pointer to a gcATTRIBUTE object.
  141647. +**
  141648. +** OUTPUT:
  141649. +**
  141650. +** gcSHADER_TYPE * Type
  141651. +** Pointer to a variable receiving the type of the attribute. 'Type'
  141652. +** can be gcvNULL, in which case no type will be returned.
  141653. +**
  141654. +** gctSIZE_T * ArrayLength
  141655. +** Pointer to a variable receiving the length of the array if the
  141656. +** attribute was declared as an array. If the attribute was not
  141657. +** declared as an array, the array length will be 1. 'ArrayLength' can
  141658. +** be gcvNULL, in which case no array length will be returned.
  141659. +*/
  141660. +gceSTATUS
  141661. +gcATTRIBUTE_GetType(
  141662. + IN gcATTRIBUTE Attribute,
  141663. + OUT gcSHADER_TYPE * Type,
  141664. + OUT gctSIZE_T * ArrayLength
  141665. + );
  141666. +
  141667. +/*******************************************************************************
  141668. +** gcATTRIBUTE_GetName
  141669. +********************************************************************************
  141670. +**
  141671. +** Get the name of a gcATTRIBUTE object.
  141672. +**
  141673. +** INPUT:
  141674. +**
  141675. +** gcATTRIBUTE Attribute
  141676. +** Pointer to a gcATTRIBUTE object.
  141677. +**
  141678. +** OUTPUT:
  141679. +**
  141680. +** gctSIZE_T * Length
  141681. +** Pointer to a variable receiving the length of the attribute name.
  141682. +** 'Length' can be gcvNULL, in which case no length will be returned.
  141683. +**
  141684. +** gctCONST_STRING * Name
  141685. +** Pointer to a variable receiving the pointer to the attribute name.
  141686. +** 'Name' can be gcvNULL, in which case no name will be returned.
  141687. +*/
  141688. +gceSTATUS
  141689. +gcATTRIBUTE_GetName(
  141690. + IN gcATTRIBUTE Attribute,
  141691. + OUT gctSIZE_T * Length,
  141692. + OUT gctCONST_STRING * Name
  141693. + );
  141694. +
  141695. +/*******************************************************************************
  141696. +** gcATTRIBUTE_IsEnabled
  141697. +********************************************************************************
  141698. +**
  141699. +** Query the enabled state of a gcATTRIBUTE object.
  141700. +**
  141701. +** INPUT:
  141702. +**
  141703. +** gcATTRIBUTE Attribute
  141704. +** Pointer to a gcATTRIBUTE object.
  141705. +**
  141706. +** OUTPUT:
  141707. +**
  141708. +** gctBOOL * Enabled
  141709. +** Pointer to a variable receiving the enabled state of the attribute.
  141710. +*/
  141711. +gceSTATUS
  141712. +gcATTRIBUTE_IsEnabled(
  141713. + IN gcATTRIBUTE Attribute,
  141714. + OUT gctBOOL * Enabled
  141715. + );
  141716. +
  141717. +/*******************************************************************************
  141718. +** gcUNIFORM_GetType
  141719. +********************************************************************************
  141720. +**
  141721. +** Get the type and array length of a gcUNIFORM object.
  141722. +**
  141723. +** INPUT:
  141724. +**
  141725. +** gcUNIFORM Uniform
  141726. +** Pointer to a gcUNIFORM object.
  141727. +**
  141728. +** OUTPUT:
  141729. +**
  141730. +** gcSHADER_TYPE * Type
  141731. +** Pointer to a variable receiving the type of the uniform. 'Type' can
  141732. +** be gcvNULL, in which case no type will be returned.
  141733. +**
  141734. +** gctSIZE_T * ArrayLength
  141735. +** Pointer to a variable receiving the length of the array if the
  141736. +** uniform was declared as an array. If the uniform was not declared
  141737. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  141738. +** in which case no array length will be returned.
  141739. +*/
  141740. +gceSTATUS
  141741. +gcUNIFORM_GetType(
  141742. + IN gcUNIFORM Uniform,
  141743. + OUT gcSHADER_TYPE * Type,
  141744. + OUT gctSIZE_T * ArrayLength
  141745. + );
  141746. +
  141747. +/*******************************************************************************
  141748. +** gcUNIFORM_GetTypeEx
  141749. +********************************************************************************
  141750. +**
  141751. +** Get the type and array length of a gcUNIFORM object.
  141752. +**
  141753. +** INPUT:
  141754. +**
  141755. +** gcUNIFORM Uniform
  141756. +** Pointer to a gcUNIFORM object.
  141757. +**
  141758. +** OUTPUT:
  141759. +**
  141760. +** gcSHADER_TYPE * Type
  141761. +** Pointer to a variable receiving the type of the uniform. 'Type' can
  141762. +** be gcvNULL, in which case no type will be returned.
  141763. +**
  141764. +** gcSHADER_PRECISION * Precision
  141765. +** Pointer to a variable receiving the precision of the uniform. 'Precision' can
  141766. +** be gcvNULL, in which case no type will be returned.
  141767. +**
  141768. +** gctSIZE_T * ArrayLength
  141769. +** Pointer to a variable receiving the length of the array if the
  141770. +** uniform was declared as an array. If the uniform was not declared
  141771. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  141772. +** in which case no array length will be returned.
  141773. +*/
  141774. +gceSTATUS
  141775. +gcUNIFORM_GetTypeEx(
  141776. + IN gcUNIFORM Uniform,
  141777. + OUT gcSHADER_TYPE * Type,
  141778. + OUT gcSHADER_PRECISION * Precision,
  141779. + OUT gctSIZE_T * ArrayLength
  141780. + );
  141781. +
  141782. +/*******************************************************************************
  141783. +** gcUNIFORM_GetFlags
  141784. +********************************************************************************
  141785. +**
  141786. +** Get the flags of a gcUNIFORM object.
  141787. +**
  141788. +** INPUT:
  141789. +**
  141790. +** gcUNIFORM Uniform
  141791. +** Pointer to a gcUNIFORM object.
  141792. +**
  141793. +** OUTPUT:
  141794. +**
  141795. +** gceUNIFORM_FLAGS * Flags
  141796. +** Pointer to a variable receiving the flags of the uniform.
  141797. +**
  141798. +*/
  141799. +gceSTATUS
  141800. +gcUNIFORM_GetFlags(
  141801. + IN gcUNIFORM Uniform,
  141802. + OUT gceUNIFORM_FLAGS * Flags
  141803. + );
  141804. +
  141805. +/*******************************************************************************
  141806. +** gcUNIFORM_SetFlags
  141807. +********************************************************************************
  141808. +**
  141809. +** Set the flags of a gcUNIFORM object.
  141810. +**
  141811. +** INPUT:
  141812. +**
  141813. +** gcUNIFORM Uniform
  141814. +** Pointer to a gcUNIFORM object.
  141815. +**
  141816. +** gceUNIFORM_FLAGS Flags
  141817. +** Flags of the uniform to be set.
  141818. +**
  141819. +** OUTPUT:
  141820. +** Nothing.
  141821. +**
  141822. +*/
  141823. +gceSTATUS
  141824. +gcUNIFORM_SetFlags(
  141825. + IN gcUNIFORM Uniform,
  141826. + IN gceUNIFORM_FLAGS Flags
  141827. + );
  141828. +
  141829. +/*******************************************************************************
  141830. +** gcUNIFORM_GetName
  141831. +********************************************************************************
  141832. +**
  141833. +** Get the name of a gcUNIFORM object.
  141834. +**
  141835. +** INPUT:
  141836. +**
  141837. +** gcUNIFORM Uniform
  141838. +** Pointer to a gcUNIFORM object.
  141839. +**
  141840. +** OUTPUT:
  141841. +**
  141842. +** gctSIZE_T * Length
  141843. +** Pointer to a variable receiving the length of the uniform name.
  141844. +** 'Length' can be gcvNULL, in which case no length will be returned.
  141845. +**
  141846. +** gctCONST_STRING * Name
  141847. +** Pointer to a variable receiving the pointer to the uniform name.
  141848. +** 'Name' can be gcvNULL, in which case no name will be returned.
  141849. +*/
  141850. +gceSTATUS
  141851. +gcUNIFORM_GetName(
  141852. + IN gcUNIFORM Uniform,
  141853. + OUT gctSIZE_T * Length,
  141854. + OUT gctCONST_STRING * Name
  141855. + );
  141856. +
  141857. +/*******************************************************************************
  141858. +** gcUNIFORM_GetSampler
  141859. +********************************************************************************
  141860. +**
  141861. +** Get the physical sampler number for a sampler gcUNIFORM object.
  141862. +**
  141863. +** INPUT:
  141864. +**
  141865. +** gcUNIFORM Uniform
  141866. +** Pointer to a gcUNIFORM object.
  141867. +**
  141868. +** OUTPUT:
  141869. +**
  141870. +** gctUINT32 * Sampler
  141871. +** Pointer to a variable receiving the physical sampler.
  141872. +*/
  141873. +gceSTATUS
  141874. +gcUNIFORM_GetSampler(
  141875. + IN gcUNIFORM Uniform,
  141876. + OUT gctUINT32 * Sampler
  141877. + );
  141878. +
  141879. +/*******************************************************************************
  141880. +** gcUNIFORM_GetFormat
  141881. +**
  141882. +** Get the type and array length of a gcUNIFORM object.
  141883. +**
  141884. +** INPUT:
  141885. +**
  141886. +** gcUNIFORM Uniform
  141887. +** Pointer to a gcUNIFORM object.
  141888. +**
  141889. +** OUTPUT:
  141890. +**
  141891. +** gcSL_FORMAT * Format
  141892. +** Pointer to a variable receiving the format of element of the uniform.
  141893. +** 'Type' can be gcvNULL, in which case no type will be returned.
  141894. +**
  141895. +** gctBOOL * IsPointer
  141896. +** Pointer to a variable receiving the state wheter the uniform is a pointer.
  141897. +** 'IsPointer' can be gcvNULL, in which case no array length will be returned.
  141898. +*/
  141899. +gceSTATUS
  141900. +gcUNIFORM_GetFormat(
  141901. + IN gcUNIFORM Uniform,
  141902. + OUT gcSL_FORMAT * Format,
  141903. + OUT gctBOOL * IsPointer
  141904. + );
  141905. +
  141906. +/*******************************************************************************
  141907. +** gcUNIFORM_SetFormat
  141908. +**
  141909. +** Set the format and isPointer of a uniform.
  141910. +**
  141911. +** INPUT:
  141912. +**
  141913. +** gcUNIFORM Uniform
  141914. +** Pointer to a gcUNIFORM object.
  141915. +**
  141916. +** gcSL_FORMAT Format
  141917. +** Format of element of the uniform shaderType.
  141918. +**
  141919. +** gctBOOL IsPointer
  141920. +** Wheter the uniform is a pointer.
  141921. +**
  141922. +** OUTPUT:
  141923. +**
  141924. +** Nothing.
  141925. +*/
  141926. +gceSTATUS
  141927. +gcUNIFORM_SetFormat(
  141928. + IN gcUNIFORM Uniform,
  141929. + IN gcSL_FORMAT Format,
  141930. + IN gctBOOL IsPointer
  141931. + );
  141932. +
  141933. +/*******************************************************************************
  141934. +** gcUNIFORM_SetValue
  141935. +********************************************************************************
  141936. +**
  141937. +** Set the value of a uniform in integer.
  141938. +**
  141939. +** INPUT:
  141940. +**
  141941. +** gcUNIFORM Uniform
  141942. +** Pointer to a gcUNIFORM object.
  141943. +**
  141944. +** gctSIZE_T Count
  141945. +** Number of entries to program if the uniform has been declared as an
  141946. +** array.
  141947. +**
  141948. +** const gctINT * Value
  141949. +** Pointer to a buffer holding the integer values for the uniform.
  141950. +**
  141951. +** OUTPUT:
  141952. +**
  141953. +** Nothing.
  141954. +*/
  141955. +gceSTATUS
  141956. +gcUNIFORM_SetValue(
  141957. + IN gcUNIFORM Uniform,
  141958. + IN gctSIZE_T Count,
  141959. + IN const gctINT * Value
  141960. + );
  141961. +
  141962. +/*******************************************************************************
  141963. +** gcUNIFORM_SetValueX
  141964. +********************************************************************************
  141965. +**
  141966. +** Set the value of a uniform in fixed point.
  141967. +**
  141968. +** INPUT:
  141969. +**
  141970. +** gcUNIFORM Uniform
  141971. +** Pointer to a gcUNIFORM object.
  141972. +**
  141973. +** gctSIZE_T Count
  141974. +** Number of entries to program if the uniform has been declared as an
  141975. +** array.
  141976. +**
  141977. +** const gctFIXED_POINT * Value
  141978. +** Pointer to a buffer holding the fixed point values for the uniform.
  141979. +**
  141980. +** OUTPUT:
  141981. +**
  141982. +** Nothing.
  141983. +*/
  141984. +gceSTATUS
  141985. +gcUNIFORM_SetValueX(
  141986. + IN gcUNIFORM Uniform,
  141987. + IN gctSIZE_T Count,
  141988. + IN gctFIXED_POINT * Value
  141989. + );
  141990. +
  141991. +/*******************************************************************************
  141992. +** gcUNIFORM_SetValueF
  141993. +********************************************************************************
  141994. +**
  141995. +** Set the value of a uniform in floating point.
  141996. +**
  141997. +** INPUT:
  141998. +**
  141999. +** gcUNIFORM Uniform
  142000. +** Pointer to a gcUNIFORM object.
  142001. +**
  142002. +** gctSIZE_T Count
  142003. +** Number of entries to program if the uniform has been declared as an
  142004. +** array.
  142005. +**
  142006. +** const gctFLOAT * Value
  142007. +** Pointer to a buffer holding the floating point values for the
  142008. +** uniform.
  142009. +**
  142010. +** OUTPUT:
  142011. +**
  142012. +** Nothing.
  142013. +*/
  142014. +gceSTATUS
  142015. +gcUNIFORM_SetValueF(
  142016. + IN gcUNIFORM Uniform,
  142017. + IN gctSIZE_T Count,
  142018. + IN const gctFLOAT * Value
  142019. + );
  142020. +
  142021. +/*******************************************************************************
  142022. +** gcUNIFORM_ProgramF
  142023. +**
  142024. +** Set the value of a uniform in floating point.
  142025. +**
  142026. +** INPUT:
  142027. +**
  142028. +** gctUINT32 Address
  142029. +** Address of Uniform.
  142030. +**
  142031. +** gctSIZE_T Row/Col
  142032. +**
  142033. +** const gctFLOAT * Value
  142034. +** Pointer to a buffer holding the floating point values for the
  142035. +** uniform.
  142036. +**
  142037. +** OUTPUT:
  142038. +**
  142039. +** Nothing.
  142040. +*/
  142041. +gceSTATUS
  142042. +gcUNIFORM_ProgramF(
  142043. + IN gctUINT32 Address,
  142044. + IN gctSIZE_T Row,
  142045. + IN gctSIZE_T Col,
  142046. + IN const gctFLOAT * Value
  142047. + );
  142048. +
  142049. +/*******************************************************************************
  142050. +** gcUNIFORM_GetModelViewProjMatrix
  142051. +********************************************************************************
  142052. +**
  142053. +** Get the value of uniform modelViewProjMatrix ID if present.
  142054. +**
  142055. +** INPUT:
  142056. +**
  142057. +** gcUNIFORM Uniform
  142058. +** Pointer to a gcUNIFORM object.
  142059. +**
  142060. +** OUTPUT:
  142061. +**
  142062. +** Nothing.
  142063. +*/
  142064. +gctUINT
  142065. +gcUNIFORM_GetModelViewProjMatrix(
  142066. + IN gcUNIFORM Uniform
  142067. + );
  142068. +
  142069. +/*******************************************************************************
  142070. +** gcOUTPUT_GetType
  142071. +********************************************************************************
  142072. +**
  142073. +** Get the type and array length of a gcOUTPUT object.
  142074. +**
  142075. +** INPUT:
  142076. +**
  142077. +** gcOUTPUT Output
  142078. +** Pointer to a gcOUTPUT object.
  142079. +**
  142080. +** OUTPUT:
  142081. +**
  142082. +** gcSHADER_TYPE * Type
  142083. +** Pointer to a variable receiving the type of the output. 'Type' can
  142084. +** be gcvNULL, in which case no type will be returned.
  142085. +**
  142086. +** gctSIZE_T * ArrayLength
  142087. +** Pointer to a variable receiving the length of the array if the
  142088. +** output was declared as an array. If the output was not declared
  142089. +** as an array, the array length will be 1. 'ArrayLength' can be gcvNULL,
  142090. +** in which case no array length will be returned.
  142091. +*/
  142092. +gceSTATUS
  142093. +gcOUTPUT_GetType(
  142094. + IN gcOUTPUT Output,
  142095. + OUT gcSHADER_TYPE * Type,
  142096. + OUT gctSIZE_T * ArrayLength
  142097. + );
  142098. +
  142099. +/*******************************************************************************
  142100. +** gcOUTPUT_GetIndex
  142101. +********************************************************************************
  142102. +**
  142103. +** Get the index of a gcOUTPUT object.
  142104. +**
  142105. +** INPUT:
  142106. +**
  142107. +** gcOUTPUT Output
  142108. +** Pointer to a gcOUTPUT object.
  142109. +**
  142110. +** OUTPUT:
  142111. +**
  142112. +** gctUINT * Index
  142113. +** Pointer to a variable receiving the temporary register index of the
  142114. +** output. 'Index' can be gcvNULL,. in which case no index will be
  142115. +** returned.
  142116. +*/
  142117. +gceSTATUS
  142118. +gcOUTPUT_GetIndex(
  142119. + IN gcOUTPUT Output,
  142120. + OUT gctUINT * Index
  142121. + );
  142122. +
  142123. +/*******************************************************************************
  142124. +** gcOUTPUT_GetName
  142125. +********************************************************************************
  142126. +**
  142127. +** Get the name of a gcOUTPUT object.
  142128. +**
  142129. +** INPUT:
  142130. +**
  142131. +** gcOUTPUT Output
  142132. +** Pointer to a gcOUTPUT object.
  142133. +**
  142134. +** OUTPUT:
  142135. +**
  142136. +** gctSIZE_T * Length
  142137. +** Pointer to a variable receiving the length of the output name.
  142138. +** 'Length' can be gcvNULL, in which case no length will be returned.
  142139. +**
  142140. +** gctCONST_STRING * Name
  142141. +** Pointer to a variable receiving the pointer to the output name.
  142142. +** 'Name' can be gcvNULL, in which case no name will be returned.
  142143. +*/
  142144. +gceSTATUS
  142145. +gcOUTPUT_GetName(
  142146. + IN gcOUTPUT Output,
  142147. + OUT gctSIZE_T * Length,
  142148. + OUT gctCONST_STRING * Name
  142149. + );
  142150. +
  142151. +/*******************************************************************************
  142152. +*********************************************************** F U N C T I O N S **
  142153. +*******************************************************************************/
  142154. +
  142155. +/*******************************************************************************
  142156. +** gcFUNCTION_ReallocateArguments
  142157. +**
  142158. +** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
  142159. +**
  142160. +** INPUT:
  142161. +**
  142162. +** gcFUNCTION Function
  142163. +** Pointer to a gcFUNCTION object.
  142164. +**
  142165. +** gctSIZE_T Count
  142166. +** Array count to reallocate. 'Count' must be at least 1.
  142167. +*/
  142168. +gceSTATUS
  142169. +gcFUNCTION_ReallocateArguments(
  142170. + IN gcFUNCTION Function,
  142171. + IN gctSIZE_T Count
  142172. + );
  142173. +
  142174. +gceSTATUS
  142175. +gcFUNCTION_AddArgument(
  142176. + IN gcFUNCTION Function,
  142177. + IN gctUINT16 TempIndex,
  142178. + IN gctUINT8 Enable,
  142179. + IN gctUINT8 Qualifier
  142180. + );
  142181. +
  142182. +gceSTATUS
  142183. +gcFUNCTION_GetArgument(
  142184. + IN gcFUNCTION Function,
  142185. + IN gctUINT16 Index,
  142186. + OUT gctUINT16_PTR Temp,
  142187. + OUT gctUINT8_PTR Enable,
  142188. + OUT gctUINT8_PTR Swizzle
  142189. + );
  142190. +
  142191. +gceSTATUS
  142192. +gcFUNCTION_GetLabel(
  142193. + IN gcFUNCTION Function,
  142194. + OUT gctUINT_PTR Label
  142195. + );
  142196. +
  142197. +/*******************************************************************************
  142198. +************************* K E R N E L P R O P E R T Y F U N C T I O N S **
  142199. +*******************************************************************************/
  142200. +/*******************************************************************************/
  142201. +gceSTATUS
  142202. +gcKERNEL_FUNCTION_AddKernelFunctionProperties(
  142203. + IN gcKERNEL_FUNCTION KernelFunction,
  142204. + IN gctINT propertyType,
  142205. + IN gctSIZE_T propertySize,
  142206. + IN gctINT * values
  142207. + );
  142208. +
  142209. +gceSTATUS
  142210. +gcKERNEL_FUNCTION_GetPropertyCount(
  142211. + IN gcKERNEL_FUNCTION KernelFunction,
  142212. + OUT gctSIZE_T * Count
  142213. + );
  142214. +
  142215. +gceSTATUS
  142216. +gcKERNEL_FUNCTION_GetProperty(
  142217. + IN gcKERNEL_FUNCTION KernelFunction,
  142218. + IN gctUINT Index,
  142219. + OUT gctSIZE_T * propertySize,
  142220. + OUT gctINT * propertyType,
  142221. + OUT gctINT * propertyValues
  142222. + );
  142223. +
  142224. +
  142225. +/*******************************************************************************
  142226. +*******************************I M A G E S A M P L E R F U N C T I O N S **
  142227. +*******************************************************************************/
  142228. +/*******************************************************************************
  142229. +** gcKERNEL_FUNCTION_ReallocateImageSamplers
  142230. +**
  142231. +** Reallocate an array of pointers to image sampler pair.
  142232. +**
  142233. +** INPUT:
  142234. +**
  142235. +** gcKERNEL_FUNCTION KernelFunction
  142236. +** Pointer to a gcKERNEL_FUNCTION object.
  142237. +**
  142238. +** gctSIZE_T Count
  142239. +** Array count to reallocate. 'Count' must be at least 1.
  142240. +*/
  142241. +gceSTATUS
  142242. +gcKERNEL_FUNCTION_ReallocateImageSamplers(
  142243. + IN gcKERNEL_FUNCTION KernelFunction,
  142244. + IN gctSIZE_T Count
  142245. + );
  142246. +
  142247. +gceSTATUS
  142248. +gcKERNEL_FUNCTION_AddImageSampler(
  142249. + IN gcKERNEL_FUNCTION KernelFunction,
  142250. + IN gctUINT8 ImageNum,
  142251. + IN gctBOOL IsConstantSamplerType,
  142252. + IN gctUINT32 SamplerType
  142253. + );
  142254. +
  142255. +gceSTATUS
  142256. +gcKERNEL_FUNCTION_GetImageSamplerCount(
  142257. + IN gcKERNEL_FUNCTION KernelFunction,
  142258. + OUT gctSIZE_T * Count
  142259. + );
  142260. +
  142261. +gceSTATUS
  142262. +gcKERNEL_FUNCTION_GetImageSampler(
  142263. + IN gcKERNEL_FUNCTION KernelFunction,
  142264. + IN gctUINT Index,
  142265. + OUT gctUINT8 *ImageNum,
  142266. + OUT gctBOOL *IsConstantSamplerType,
  142267. + OUT gctUINT32 *SamplerType
  142268. + );
  142269. +
  142270. +/*******************************************************************************
  142271. +*********************************************K E R N E L F U N C T I O N S **
  142272. +*******************************************************************************/
  142273. +
  142274. +/*******************************************************************************
  142275. +** gcKERNEL_FUNCTION_ReallocateArguments
  142276. +**
  142277. +** Reallocate an array of gcsFUNCTION_ARGUMENT objects.
  142278. +**
  142279. +** INPUT:
  142280. +**
  142281. +** gcKERNEL_FUNCTION Function
  142282. +** Pointer to a gcKERNEL_FUNCTION object.
  142283. +**
  142284. +** gctSIZE_T Count
  142285. +** Array count to reallocate. 'Count' must be at least 1.
  142286. +*/
  142287. +gceSTATUS
  142288. +gcKERNEL_FUNCTION_ReallocateArguments(
  142289. + IN gcKERNEL_FUNCTION Function,
  142290. + IN gctSIZE_T Count
  142291. + );
  142292. +
  142293. +gceSTATUS
  142294. +gcKERNEL_FUNCTION_AddArgument(
  142295. + IN gcKERNEL_FUNCTION Function,
  142296. + IN gctUINT16 TempIndex,
  142297. + IN gctUINT8 Enable,
  142298. + IN gctUINT8 Qualifier
  142299. + );
  142300. +
  142301. +gceSTATUS
  142302. +gcKERNEL_FUNCTION_GetArgument(
  142303. + IN gcKERNEL_FUNCTION Function,
  142304. + IN gctUINT16 Index,
  142305. + OUT gctUINT16_PTR Temp,
  142306. + OUT gctUINT8_PTR Enable,
  142307. + OUT gctUINT8_PTR Swizzle
  142308. + );
  142309. +
  142310. +gceSTATUS
  142311. +gcKERNEL_FUNCTION_GetLabel(
  142312. + IN gcKERNEL_FUNCTION Function,
  142313. + OUT gctUINT_PTR Label
  142314. + );
  142315. +
  142316. +gceSTATUS
  142317. +gcKERNEL_FUNCTION_GetName(
  142318. + IN gcKERNEL_FUNCTION KernelFunction,
  142319. + OUT gctSIZE_T * Length,
  142320. + OUT gctCONST_STRING * Name
  142321. + );
  142322. +
  142323. +gceSTATUS
  142324. +gcKERNEL_FUNCTION_ReallocateUniformArguments(
  142325. + IN gcKERNEL_FUNCTION KernelFunction,
  142326. + IN gctSIZE_T Count
  142327. + );
  142328. +
  142329. +gceSTATUS
  142330. +gcKERNEL_FUNCTION_AddUniformArgument(
  142331. + IN gcKERNEL_FUNCTION KernelFunction,
  142332. + IN gctCONST_STRING Name,
  142333. + IN gcSHADER_TYPE Type,
  142334. + IN gctSIZE_T Length,
  142335. + OUT gcUNIFORM * UniformArgument
  142336. + );
  142337. +
  142338. +gceSTATUS
  142339. +gcKERNEL_FUNCTION_GetUniformArgumentCount(
  142340. + IN gcKERNEL_FUNCTION KernelFunction,
  142341. + OUT gctSIZE_T * Count
  142342. + );
  142343. +
  142344. +gceSTATUS
  142345. +gcKERNEL_FUNCTION_GetUniformArgument(
  142346. + IN gcKERNEL_FUNCTION KernelFunction,
  142347. + IN gctUINT Index,
  142348. + OUT gcUNIFORM * UniformArgument
  142349. + );
  142350. +
  142351. +gceSTATUS
  142352. +gcKERNEL_FUNCTION_SetCodeEnd(
  142353. + IN gcKERNEL_FUNCTION KernelFunction
  142354. + );
  142355. +
  142356. +/*******************************************************************************
  142357. +** gcCompileShader
  142358. +********************************************************************************
  142359. +**
  142360. +** Compile a shader.
  142361. +**
  142362. +** INPUT:
  142363. +**
  142364. +** gcoOS Hal
  142365. +** Pointer to an gcoHAL object.
  142366. +**
  142367. +** gctINT ShaderType
  142368. +** Shader type to compile. Can be one of the following values:
  142369. +**
  142370. +** gcSHADER_TYPE_VERTEX
  142371. +** Compile a vertex shader.
  142372. +**
  142373. +** gcSHADER_TYPE_FRAGMENT
  142374. +** Compile a fragment shader.
  142375. +**
  142376. +** gctSIZE_T SourceSize
  142377. +** Size of the source buffer in bytes.
  142378. +**
  142379. +** gctCONST_STRING Source
  142380. +** Pointer to the buffer containing the shader source code.
  142381. +**
  142382. +** OUTPUT:
  142383. +**
  142384. +** gcSHADER * Binary
  142385. +** Pointer to a variable receiving the pointer to a gcSHADER object
  142386. +** containg the compiled shader code.
  142387. +**
  142388. +** gctSTRING * Log
  142389. +** Pointer to a variable receiving a string pointer containging the
  142390. +** compile log.
  142391. +*/
  142392. +gceSTATUS
  142393. +gcCompileShader(
  142394. + IN gcoHAL Hal,
  142395. + IN gctINT ShaderType,
  142396. + IN gctSIZE_T SourceSize,
  142397. + IN gctCONST_STRING Source,
  142398. + OUT gcSHADER * Binary,
  142399. + OUT gctSTRING * Log
  142400. + );
  142401. +
  142402. +/*******************************************************************************
  142403. +** gcOptimizeShader
  142404. +********************************************************************************
  142405. +**
  142406. +** Optimize a shader.
  142407. +**
  142408. +** INPUT:
  142409. +**
  142410. +** gcSHADER Shader
  142411. +** Pointer to a gcSHADER object holding information about the compiled
  142412. +** shader.
  142413. +**
  142414. +** gctFILE LogFile
  142415. +** Pointer to an open FILE object.
  142416. +*/
  142417. +gceSTATUS
  142418. +gcOptimizeShader(
  142419. + IN gcSHADER Shader,
  142420. + IN gctFILE LogFile
  142421. + );
  142422. +
  142423. +/*******************************************************************************
  142424. +** gcLinkShaders
  142425. +********************************************************************************
  142426. +**
  142427. +** Link two shaders and generate a harwdare specific state buffer by compiling
  142428. +** the compiler generated code through the resource allocator and code
  142429. +** generator.
  142430. +**
  142431. +** INPUT:
  142432. +**
  142433. +** gcSHADER VertexShader
  142434. +** Pointer to a gcSHADER object holding information about the compiled
  142435. +** vertex shader.
  142436. +**
  142437. +** gcSHADER FragmentShader
  142438. +** Pointer to a gcSHADER object holding information about the compiled
  142439. +** fragment shader.
  142440. +**
  142441. +** gceSHADER_FLAGS Flags
  142442. +** Compiler flags. Can be any of the following:
  142443. +**
  142444. +** gcvSHADER_DEAD_CODE - Dead code elimination.
  142445. +** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
  142446. +** gcvSHADER_OPTIMIZER - Full optimization.
  142447. +** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
  142448. +** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
  142449. +** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
  142450. +**
  142451. +** OUTPUT:
  142452. +**
  142453. +** gctSIZE_T * StateBufferSize
  142454. +** Pointer to a variable receicing the number of bytes in the buffer
  142455. +** returned in 'StateBuffer'.
  142456. +**
  142457. +** gctPOINTER * StateBuffer
  142458. +** Pointer to a variable receiving a buffer pointer that contains the
  142459. +** states required to download the shaders into the hardware.
  142460. +**
  142461. +** gcsHINT_PTR * Hints
  142462. +** Pointer to a variable receiving a gcsHINT structure pointer that
  142463. +** contains information required when loading the shader states.
  142464. +*/
  142465. +gceSTATUS
  142466. +gcLinkShaders(
  142467. + IN gcSHADER VertexShader,
  142468. + IN gcSHADER FragmentShader,
  142469. + IN gceSHADER_FLAGS Flags,
  142470. + OUT gctSIZE_T * StateBufferSize,
  142471. + OUT gctPOINTER * StateBuffer,
  142472. + OUT gcsHINT_PTR * Hints,
  142473. + OUT gcMACHINECODE_PTR *ppVsMachineCode,
  142474. + OUT gcMACHINECODE_PTR *ppFsMachineCode
  142475. + );
  142476. +
  142477. +/*******************************************************************************
  142478. +** gcLoadShaders
  142479. +********************************************************************************
  142480. +**
  142481. +** Load a pre-compiled and pre-linked shader program into the hardware.
  142482. +**
  142483. +** INPUT:
  142484. +**
  142485. +** gcoHAL Hal
  142486. +** Pointer to a gcoHAL object.
  142487. +**
  142488. +** gctSIZE_T StateBufferSize
  142489. +** The number of bytes in the 'StateBuffer'.
  142490. +**
  142491. +** gctPOINTER StateBuffer
  142492. +** Pointer to the states that make up the shader program.
  142493. +**
  142494. +** gcsHINT_PTR Hints
  142495. +** Pointer to a gcsHINT structure that contains information required
  142496. +** when loading the shader states.
  142497. +*/
  142498. +gceSTATUS
  142499. +gcLoadShaders(
  142500. + IN gcoHAL Hal,
  142501. + IN gctSIZE_T StateBufferSize,
  142502. + IN gctPOINTER StateBuffer,
  142503. + IN gcsHINT_PTR Hints
  142504. + );
  142505. +
  142506. +gceSTATUS
  142507. +gcRecompileShaders(
  142508. + IN gcoHAL Hal,
  142509. + IN gcMACHINECODE_PTR pVsMachineCode,
  142510. + IN gcMACHINECODE_PTR pPsMachineCode,
  142511. + /*Recompile variables*/
  142512. + IN OUT gctPOINTER *ppRecompileStateBuffer,
  142513. + IN OUT gctSIZE_T *pRecompileStateBufferSize,
  142514. + IN OUT gcsHINT_PTR *ppRecompileHints,
  142515. + /* natvie state*/
  142516. + IN gctPOINTER pNativeStateBuffer,
  142517. + IN gctSIZE_T nativeStateBufferSize,
  142518. + IN gcsHINT_PTR pNativeHints,
  142519. + /* npt info */
  142520. + IN gctUINT32 Samplers,
  142521. + IN gctUINT32 *SamplerWrapS,
  142522. + IN gctUINT32 *SamplerWrapT
  142523. + );
  142524. +
  142525. +gceSTATUS
  142526. +gcRecompileDepthBias(
  142527. + IN gcoHAL Hal,
  142528. + IN gcMACHINECODE_PTR pVsMachineCode,
  142529. + /*Recompile variables*/
  142530. + IN OUT gctPOINTER *ppRecompileStateBuffer,
  142531. + IN OUT gctSIZE_T *pRecompileStateBufferSize,
  142532. + IN OUT gcsHINT_PTR *ppRecompileHints,
  142533. + /* natvie state*/
  142534. + IN gctPOINTER pNativeStateBuffer,
  142535. + IN gctSIZE_T nativeStateBufferSize,
  142536. + IN gcsHINT_PTR pNativeHints,
  142537. + OUT gctINT * uniformAddr,
  142538. + OUT gctINT * uniformChannel
  142539. + );
  142540. +
  142541. +/*******************************************************************************
  142542. +** gcSaveProgram
  142543. +********************************************************************************
  142544. +**
  142545. +** Save pre-compiled shaders and pre-linked programs to a binary file.
  142546. +**
  142547. +** INPUT:
  142548. +**
  142549. +** gcSHADER VertexShader
  142550. +** Pointer to vertex shader object.
  142551. +**
  142552. +** gcSHADER FragmentShader
  142553. +** Pointer to fragment shader object.
  142554. +**
  142555. +** gctSIZE_T ProgramBufferSize
  142556. +** Number of bytes in 'ProgramBuffer'.
  142557. +**
  142558. +** gctPOINTER ProgramBuffer
  142559. +** Pointer to buffer containing the program states.
  142560. +**
  142561. +** gcsHINT_PTR Hints
  142562. +** Pointer to HINTS structure for program states.
  142563. +**
  142564. +** OUTPUT:
  142565. +**
  142566. +** gctPOINTER * Binary
  142567. +** Pointer to a variable receiving the binary data to be saved.
  142568. +**
  142569. +** gctSIZE_T * BinarySize
  142570. +** Pointer to a variable receiving the number of bytes inside 'Binary'.
  142571. +*/
  142572. +gceSTATUS
  142573. +gcSaveProgram(
  142574. + IN gcSHADER VertexShader,
  142575. + IN gcSHADER FragmentShader,
  142576. + IN gctSIZE_T ProgramBufferSize,
  142577. + IN gctPOINTER ProgramBuffer,
  142578. + IN gcsHINT_PTR Hints,
  142579. + OUT gctPOINTER * Binary,
  142580. + OUT gctSIZE_T * BinarySize
  142581. + );
  142582. +
  142583. +/*******************************************************************************
  142584. +** gcLoadProgram
  142585. +********************************************************************************
  142586. +**
  142587. +** Load pre-compiled shaders and pre-linked programs from a binary file.
  142588. +**
  142589. +** INPUT:
  142590. +**
  142591. +** gctPOINTER Binary
  142592. +** Pointer to the binary data loaded.
  142593. +**
  142594. +** gctSIZE_T BinarySize
  142595. +** Number of bytes in 'Binary'.
  142596. +**
  142597. +** OUTPUT:
  142598. +**
  142599. +** gcSHADER VertexShader
  142600. +** Pointer to a vertex shader object.
  142601. +**
  142602. +** gcSHADER FragmentShader
  142603. +** Pointer to a fragment shader object.
  142604. +**
  142605. +** gctSIZE_T * ProgramBufferSize
  142606. +** Pointer to a variable receicing the number of bytes in the buffer
  142607. +** returned in 'ProgramBuffer'.
  142608. +**
  142609. +** gctPOINTER * ProgramBuffer
  142610. +** Pointer to a variable receiving a buffer pointer that contains the
  142611. +** states required to download the shaders into the hardware.
  142612. +**
  142613. +** gcsHINT_PTR * Hints
  142614. +** Pointer to a variable receiving a gcsHINT structure pointer that
  142615. +** contains information required when loading the shader states.
  142616. +*/
  142617. +gceSTATUS
  142618. +gcLoadProgram(
  142619. + IN gctPOINTER Binary,
  142620. + IN gctSIZE_T BinarySize,
  142621. + OUT gcSHADER VertexShader,
  142622. + OUT gcSHADER FragmentShader,
  142623. + OUT gctSIZE_T * ProgramBufferSize,
  142624. + OUT gctPOINTER * ProgramBuffer,
  142625. + OUT gcsHINT_PTR * Hints
  142626. + );
  142627. +
  142628. +/*******************************************************************************
  142629. +** gcCompileKernel
  142630. +********************************************************************************
  142631. +**
  142632. +** Compile a OpenCL kernel shader.
  142633. +**
  142634. +** INPUT:
  142635. +**
  142636. +** gcoOS Hal
  142637. +** Pointer to an gcoHAL object.
  142638. +**
  142639. +** gctSIZE_T SourceSize
  142640. +** Size of the source buffer in bytes.
  142641. +**
  142642. +** gctCONST_STRING Source
  142643. +** Pointer to the buffer containing the shader source code.
  142644. +**
  142645. +** OUTPUT:
  142646. +**
  142647. +** gcSHADER * Binary
  142648. +** Pointer to a variable receiving the pointer to a gcSHADER object
  142649. +** containg the compiled shader code.
  142650. +**
  142651. +** gctSTRING * Log
  142652. +** Pointer to a variable receiving a string pointer containging the
  142653. +** compile log.
  142654. +*/
  142655. +gceSTATUS
  142656. +gcCompileKernel(
  142657. + IN gcoHAL Hal,
  142658. + IN gctSIZE_T SourceSize,
  142659. + IN gctCONST_STRING Source,
  142660. + IN gctCONST_STRING Options,
  142661. + OUT gcSHADER * Binary,
  142662. + OUT gctSTRING * Log
  142663. + );
  142664. +
  142665. +/*******************************************************************************
  142666. +** gcLinkKernel
  142667. +********************************************************************************
  142668. +**
  142669. +** Link OpenCL kernel and generate a harwdare specific state buffer by compiling
  142670. +** the compiler generated code through the resource allocator and code
  142671. +** generator.
  142672. +**
  142673. +** INPUT:
  142674. +**
  142675. +** gcSHADER Kernel
  142676. +** Pointer to a gcSHADER object holding information about the compiled
  142677. +** OpenCL kernel.
  142678. +**
  142679. +** gceSHADER_FLAGS Flags
  142680. +** Compiler flags. Can be any of the following:
  142681. +**
  142682. +** gcvSHADER_DEAD_CODE - Dead code elimination.
  142683. +** gcvSHADER_RESOURCE_USAGE - Resource usage optimizaion.
  142684. +** gcvSHADER_OPTIMIZER - Full optimization.
  142685. +** gcvSHADER_USE_GL_Z - Use OpenGL ES Z coordinate.
  142686. +** gcvSHADER_USE_GL_POSITION - Use OpenGL ES gl_Position.
  142687. +** gcvSHADER_USE_GL_FACE - Use OpenGL ES gl_FaceForward.
  142688. +**
  142689. +** OUTPUT:
  142690. +**
  142691. +** gctSIZE_T * StateBufferSize
  142692. +** Pointer to a variable receiving the number of bytes in the buffer
  142693. +** returned in 'StateBuffer'.
  142694. +**
  142695. +** gctPOINTER * StateBuffer
  142696. +** Pointer to a variable receiving a buffer pointer that contains the
  142697. +** states required to download the shaders into the hardware.
  142698. +**
  142699. +** gcsHINT_PTR * Hints
  142700. +** Pointer to a variable receiving a gcsHINT structure pointer that
  142701. +** contains information required when loading the shader states.
  142702. +*/
  142703. +gceSTATUS
  142704. +gcLinkKernel(
  142705. + IN gcSHADER Kernel,
  142706. + IN gceSHADER_FLAGS Flags,
  142707. + OUT gctSIZE_T * StateBufferSize,
  142708. + OUT gctPOINTER * StateBuffer,
  142709. + OUT gcsHINT_PTR * Hints
  142710. + );
  142711. +
  142712. +/*******************************************************************************
  142713. +** gcLoadKernel
  142714. +********************************************************************************
  142715. +**
  142716. +** Load a pre-compiled and pre-linked kernel program into the hardware.
  142717. +**
  142718. +** INPUT:
  142719. +**
  142720. +** gctSIZE_T StateBufferSize
  142721. +** The number of bytes in the 'StateBuffer'.
  142722. +**
  142723. +** gctPOINTER StateBuffer
  142724. +** Pointer to the states that make up the shader program.
  142725. +**
  142726. +** gcsHINT_PTR Hints
  142727. +** Pointer to a gcsHINT structure that contains information required
  142728. +** when loading the shader states.
  142729. +*/
  142730. +gceSTATUS
  142731. +gcLoadKernel(
  142732. + IN gctSIZE_T StateBufferSize,
  142733. + IN gctPOINTER StateBuffer,
  142734. + IN gcsHINT_PTR Hints
  142735. + );
  142736. +
  142737. +gceSTATUS
  142738. +gcInvokeThreadWalker(
  142739. + IN gcsTHREAD_WALKER_INFO_PTR Info
  142740. + );
  142741. +
  142742. +void
  142743. +gcTYPE_GetTypeInfo(
  142744. + IN gcSHADER_TYPE Type,
  142745. + OUT gctINT * Components,
  142746. + OUT gctINT * Rows,
  142747. + OUT gctCONST_STRING * Name
  142748. + );
  142749. +
  142750. +gctBOOL
  142751. +gcOPT_doVaryingPackingForShader(
  142752. + IN gcSHADER Shader
  142753. + );
  142754. +
  142755. +gceSTATUS
  142756. +gcSHADER_PatchNPOTForMachineCode(
  142757. + IN gcSHADER_KIND shaderType,
  142758. + IN gcMACHINECODE_PTR pMachineCode,
  142759. + IN gcNPOT_PATCH_PARAM_PTR pPatchParam,
  142760. + IN gctUINT countOfPatchParam,
  142761. + IN gctUINT hwSupportedInstCount,
  142762. + OUT gctPOINTER* ppCmdBuffer,
  142763. + OUT gctUINT32* pByteSizeOfCmdBuffer,
  142764. + IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
  142765. + );
  142766. +
  142767. +gceSTATUS
  142768. +gcSHADER_PatchZBiasForMachineCodeVS(
  142769. + IN gcMACHINECODE_PTR pMachineCode,
  142770. + IN OUT gcZBIAS_PATCH_PARAM_PTR pPatchParam,
  142771. + IN gctUINT hwSupportedInstCount,
  142772. + OUT gctPOINTER* ppCmdBuffer,
  142773. + OUT gctUINT32* pByteSizeOfCmdBuffer,
  142774. + IN OUT gcsHINT_PTR pHints /* User needs copy original hints to this one, then passed this one in */
  142775. + );
  142776. +
  142777. +#ifdef __cplusplus
  142778. +}
  142779. +#endif
  142780. +
  142781. +#endif /* VIVANTE_NO_3D */
  142782. +#endif /* __gc_hal_compiler_h_ */
  142783. diff -Nur linux-3.14.17/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
  142784. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h 1970-01-01 01:00:00.000000000 +0100
  142785. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h 2014-09-11 18:06:03.118042434 +0200
  142786. @@ -0,0 +1,1051 @@
  142787. +/****************************************************************************
  142788. +*
  142789. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  142790. +*
  142791. +* This program is free software; you can redistribute it and/or modify
  142792. +* it under the terms of the GNU General Public License as published by
  142793. +* the Free Software Foundation; either version 2 of the license, or
  142794. +* (at your option) any later version.
  142795. +*
  142796. +* This program is distributed in the hope that it will be useful,
  142797. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  142798. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  142799. +* GNU General Public License for more details.
  142800. +*
  142801. +* You should have received a copy of the GNU General Public License
  142802. +* along with this program; if not write to the Free Software
  142803. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  142804. +*
  142805. +*****************************************************************************/
  142806. +
  142807. +
  142808. +#ifndef __gc_hal_driver_h_
  142809. +#define __gc_hal_driver_h_
  142810. +
  142811. +#include "gc_hal_enum.h"
  142812. +#include "gc_hal_types.h"
  142813. +
  142814. +#if gcdENABLE_VG
  142815. +#include "gc_hal_driver_vg.h"
  142816. +#endif
  142817. +
  142818. +#ifdef __cplusplus
  142819. +extern "C" {
  142820. +#endif
  142821. +
  142822. +/******************************************************************************\
  142823. +******************************* I/O Control Codes ******************************
  142824. +\******************************************************************************/
  142825. +
  142826. +#define gcvHAL_CLASS "galcore"
  142827. +#define IOCTL_GCHAL_INTERFACE 30000
  142828. +#define IOCTL_GCHAL_KERNEL_INTERFACE 30001
  142829. +#define IOCTL_GCHAL_TERMINATE 30002
  142830. +
  142831. +/******************************************************************************\
  142832. +********************************* Command Codes ********************************
  142833. +\******************************************************************************/
  142834. +
  142835. +typedef enum _gceHAL_COMMAND_CODES
  142836. +{
  142837. + /* Generic query. */
  142838. + gcvHAL_QUERY_VIDEO_MEMORY,
  142839. + gcvHAL_QUERY_CHIP_IDENTITY,
  142840. +
  142841. + /* Contiguous memory. */
  142842. + gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
  142843. + gcvHAL_FREE_NON_PAGED_MEMORY,
  142844. + gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY,
  142845. + gcvHAL_FREE_CONTIGUOUS_MEMORY,
  142846. +
  142847. + /* Video memory allocation. */
  142848. + gcvHAL_ALLOCATE_VIDEO_MEMORY, /* Enforced alignment. */
  142849. + gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY, /* No alignment. */
  142850. + gcvHAL_FREE_VIDEO_MEMORY,
  142851. +
  142852. + /* Physical-to-logical mapping. */
  142853. + gcvHAL_MAP_MEMORY,
  142854. + gcvHAL_UNMAP_MEMORY,
  142855. +
  142856. + /* Logical-to-physical mapping. */
  142857. + gcvHAL_MAP_USER_MEMORY,
  142858. + gcvHAL_UNMAP_USER_MEMORY,
  142859. +
  142860. + /* Surface lock/unlock. */
  142861. + gcvHAL_LOCK_VIDEO_MEMORY,
  142862. + gcvHAL_UNLOCK_VIDEO_MEMORY,
  142863. +
  142864. + /* Event queue. */
  142865. + gcvHAL_EVENT_COMMIT,
  142866. +
  142867. + gcvHAL_USER_SIGNAL,
  142868. + gcvHAL_SIGNAL,
  142869. + gcvHAL_WRITE_DATA,
  142870. +
  142871. + gcvHAL_COMMIT,
  142872. + gcvHAL_STALL,
  142873. +
  142874. + gcvHAL_READ_REGISTER,
  142875. + gcvHAL_WRITE_REGISTER,
  142876. +
  142877. + gcvHAL_GET_PROFILE_SETTING,
  142878. + gcvHAL_SET_PROFILE_SETTING,
  142879. +
  142880. + gcvHAL_READ_ALL_PROFILE_REGISTERS,
  142881. + gcvHAL_PROFILE_REGISTERS_2D,
  142882. +#if VIVANTE_PROFILER_PERDRAW
  142883. + gcvHAL_READ_PROFILER_REGISTER_SETTING,
  142884. +#endif
  142885. +
  142886. + /* Power management. */
  142887. + gcvHAL_SET_POWER_MANAGEMENT_STATE,
  142888. + gcvHAL_QUERY_POWER_MANAGEMENT_STATE,
  142889. +
  142890. + gcvHAL_GET_BASE_ADDRESS,
  142891. +
  142892. + gcvHAL_SET_IDLE, /* reserved */
  142893. +
  142894. + /* Queries. */
  142895. + gcvHAL_QUERY_KERNEL_SETTINGS,
  142896. +
  142897. + /* Reset. */
  142898. + gcvHAL_RESET,
  142899. +
  142900. + /* Map physical address into handle. */
  142901. + gcvHAL_MAP_PHYSICAL,
  142902. +
  142903. + /* Debugger stuff. */
  142904. + gcvHAL_DEBUG,
  142905. +
  142906. + /* Cache stuff. */
  142907. + gcvHAL_CACHE,
  142908. +
  142909. + /* TimeStamp */
  142910. + gcvHAL_TIMESTAMP,
  142911. +
  142912. + /* Database. */
  142913. + gcvHAL_DATABASE,
  142914. +
  142915. + /* Version. */
  142916. + gcvHAL_VERSION,
  142917. +
  142918. + /* Chip info */
  142919. + gcvHAL_CHIP_INFO,
  142920. +
  142921. + /* Process attaching/detaching. */
  142922. + gcvHAL_ATTACH,
  142923. + gcvHAL_DETACH,
  142924. +
  142925. + /* Composition. */
  142926. + gcvHAL_COMPOSE,
  142927. +
  142928. + /* Set timeOut value */
  142929. + gcvHAL_SET_TIMEOUT,
  142930. +
  142931. + /* Frame database. */
  142932. + gcvHAL_GET_FRAME_INFO,
  142933. +
  142934. + /* Shared info for each process */
  142935. + gcvHAL_GET_SHARED_INFO,
  142936. + gcvHAL_SET_SHARED_INFO,
  142937. + gcvHAL_QUERY_COMMAND_BUFFER,
  142938. +
  142939. + gcvHAL_COMMIT_DONE,
  142940. +
  142941. + /* GPU and event dump */
  142942. + gcvHAL_DUMP_GPU_STATE,
  142943. + gcvHAL_DUMP_EVENT,
  142944. +
  142945. + /* Virtual command buffer. */
  142946. + gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER,
  142947. + gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER,
  142948. +
  142949. + /* FSCALE_VAL. */
  142950. + gcvHAL_SET_FSCALE_VALUE,
  142951. + gcvHAL_GET_FSCALE_VALUE,
  142952. +
  142953. + /* Reset time stamp. */
  142954. + gcvHAL_QUERY_RESET_TIME_STAMP,
  142955. +
  142956. + /* Sync point operations. */
  142957. + gcvHAL_SYNC_POINT,
  142958. +
  142959. + /* Create native fence and return its fd. */
  142960. + gcvHAL_CREATE_NATIVE_FENCE,
  142961. +
  142962. + /* Video memory database */
  142963. + gcvHAL_VIDMEM_DATABASE,
  142964. +}
  142965. +gceHAL_COMMAND_CODES;
  142966. +
  142967. +/******************************************************************************\
  142968. +****************************** Interface Structure *****************************
  142969. +\******************************************************************************/
  142970. +
  142971. +#define gcdMAX_PROFILE_FILE_NAME 128
  142972. +
  142973. +/* Kernel settings. */
  142974. +typedef struct _gcsKERNEL_SETTINGS
  142975. +{
  142976. + /* Used RealTime signal between kernel and user. */
  142977. + gctINT signal;
  142978. +}
  142979. +gcsKERNEL_SETTINGS;
  142980. +
  142981. +
  142982. +/* gcvHAL_QUERY_CHIP_IDENTITY */
  142983. +typedef struct _gcsHAL_QUERY_CHIP_IDENTITY * gcsHAL_QUERY_CHIP_IDENTITY_PTR;
  142984. +typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
  142985. +{
  142986. +
  142987. + /* Chip model. */
  142988. + gceCHIPMODEL chipModel;
  142989. +
  142990. + /* Revision value.*/
  142991. + gctUINT32 chipRevision;
  142992. +
  142993. + /* Supported feature fields. */
  142994. + gctUINT32 chipFeatures;
  142995. +
  142996. + /* Supported minor feature fields. */
  142997. + gctUINT32 chipMinorFeatures;
  142998. +
  142999. + /* Supported minor feature 1 fields. */
  143000. + gctUINT32 chipMinorFeatures1;
  143001. +
  143002. + /* Supported minor feature 2 fields. */
  143003. + gctUINT32 chipMinorFeatures2;
  143004. +
  143005. + /* Supported minor feature 3 fields. */
  143006. + gctUINT32 chipMinorFeatures3;
  143007. +
  143008. + /* Supported minor feature 4 fields. */
  143009. + gctUINT32 chipMinorFeatures4;
  143010. +
  143011. + /* Number of streams supported. */
  143012. + gctUINT32 streamCount;
  143013. +
  143014. + /* Total number of temporary registers per thread. */
  143015. + gctUINT32 registerMax;
  143016. +
  143017. + /* Maximum number of threads. */
  143018. + gctUINT32 threadCount;
  143019. +
  143020. + /* Number of shader cores. */
  143021. + gctUINT32 shaderCoreCount;
  143022. +
  143023. + /* Size of the vertex cache. */
  143024. + gctUINT32 vertexCacheSize;
  143025. +
  143026. + /* Number of entries in the vertex output buffer. */
  143027. + gctUINT32 vertexOutputBufferSize;
  143028. +
  143029. + /* Number of pixel pipes. */
  143030. + gctUINT32 pixelPipes;
  143031. +
  143032. + /* Number of instructions. */
  143033. + gctUINT32 instructionCount;
  143034. +
  143035. + /* Number of constants. */
  143036. + gctUINT32 numConstants;
  143037. +
  143038. + /* Buffer size */
  143039. + gctUINT32 bufferSize;
  143040. +
  143041. + /* Number of varyings */
  143042. + gctUINT32 varyingsCount;
  143043. +
  143044. + /* Supertile layout style in hardware */
  143045. + gctUINT32 superTileMode;
  143046. +
  143047. + /* Special control bits for 2D chip. */
  143048. + gctUINT32 chip2DControl;
  143049. +}
  143050. +gcsHAL_QUERY_CHIP_IDENTITY;
  143051. +
  143052. +/* gcvHAL_COMPOSE. */
  143053. +typedef struct _gcsHAL_COMPOSE * gcsHAL_COMPOSE_PTR;
  143054. +typedef struct _gcsHAL_COMPOSE
  143055. +{
  143056. + /* Composition state buffer. */
  143057. + gctUINT64 physical;
  143058. + gctUINT64 logical;
  143059. + gctUINT offset;
  143060. + gctUINT size;
  143061. +
  143062. + /* Composition end signal. */
  143063. + gctUINT64 process;
  143064. + gctUINT64 signal;
  143065. +
  143066. + /* User signals. */
  143067. + gctUINT64 userProcess;
  143068. + gctUINT64 userSignal1;
  143069. + gctUINT64 userSignal2;
  143070. +
  143071. +#if defined(__QNXNTO__)
  143072. + /* Client pulse side-channel connection ID. */
  143073. + gctINT32 coid;
  143074. +
  143075. + /* Set by server. */
  143076. + gctINT32 rcvid;
  143077. +#endif
  143078. +}
  143079. +gcsHAL_COMPOSE;
  143080. +
  143081. +
  143082. +typedef struct _gcsHAL_INTERFACE
  143083. +{
  143084. + /* Command code. */
  143085. + gceHAL_COMMAND_CODES command;
  143086. +
  143087. + /* Hardware type. */
  143088. + gceHARDWARE_TYPE hardwareType;
  143089. +
  143090. + /* Status value. */
  143091. + gceSTATUS status;
  143092. +
  143093. + /* Handle to this interface channel. */
  143094. + gctUINT64 handle;
  143095. +
  143096. + /* Pid of the client. */
  143097. + gctUINT32 pid;
  143098. +
  143099. + /* Union of command structures. */
  143100. + union _u
  143101. + {
  143102. + /* gcvHAL_GET_BASE_ADDRESS */
  143103. + struct _gcsHAL_GET_BASE_ADDRESS
  143104. + {
  143105. + /* Physical memory address of internal memory. */
  143106. + OUT gctUINT32 baseAddress;
  143107. + }
  143108. + GetBaseAddress;
  143109. +
  143110. + /* gcvHAL_QUERY_VIDEO_MEMORY */
  143111. + struct _gcsHAL_QUERY_VIDEO_MEMORY
  143112. + {
  143113. + /* Physical memory address of internal memory. Just a name. */
  143114. + OUT gctUINT32 internalPhysical;
  143115. +
  143116. + /* Size in bytes of internal memory. */
  143117. + OUT gctUINT64 internalSize;
  143118. +
  143119. + /* Physical memory address of external memory. Just a name. */
  143120. + OUT gctUINT32 externalPhysical;
  143121. +
  143122. + /* Size in bytes of external memory.*/
  143123. + OUT gctUINT64 externalSize;
  143124. +
  143125. + /* Physical memory address of contiguous memory. Just a name. */
  143126. + OUT gctUINT32 contiguousPhysical;
  143127. +
  143128. + /* Size in bytes of contiguous memory.*/
  143129. + OUT gctUINT64 contiguousSize;
  143130. + }
  143131. + QueryVideoMemory;
  143132. +
  143133. + /* gcvHAL_QUERY_CHIP_IDENTITY */
  143134. + gcsHAL_QUERY_CHIP_IDENTITY QueryChipIdentity;
  143135. +
  143136. + /* gcvHAL_MAP_MEMORY */
  143137. + struct _gcsHAL_MAP_MEMORY
  143138. + {
  143139. + /* Physical memory address to map. Just a name on Linux/Qnx. */
  143140. + IN gctUINT32 physical;
  143141. +
  143142. + /* Number of bytes in physical memory to map. */
  143143. + IN gctUINT64 bytes;
  143144. +
  143145. + /* Address of mapped memory. */
  143146. + OUT gctUINT64 logical;
  143147. + }
  143148. + MapMemory;
  143149. +
  143150. + /* gcvHAL_UNMAP_MEMORY */
  143151. + struct _gcsHAL_UNMAP_MEMORY
  143152. + {
  143153. + /* Physical memory address to unmap. Just a name on Linux/Qnx. */
  143154. + IN gctUINT32 physical;
  143155. +
  143156. + /* Number of bytes in physical memory to unmap. */
  143157. + IN gctUINT64 bytes;
  143158. +
  143159. + /* Address of mapped memory to unmap. */
  143160. + IN gctUINT64 logical;
  143161. + }
  143162. + UnmapMemory;
  143163. +
  143164. + /* gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY */
  143165. + struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
  143166. + {
  143167. + /* Number of bytes to allocate. */
  143168. + IN OUT gctUINT bytes;
  143169. +
  143170. + /* Buffer alignment. */
  143171. + IN gctUINT alignment;
  143172. +
  143173. + /* Type of allocation. */
  143174. + IN gceSURF_TYPE type;
  143175. +
  143176. + /* Memory pool to allocate from. */
  143177. + IN OUT gcePOOL pool;
  143178. +
  143179. + /* Allocated video memory in gcuVIDMEM_NODE. */
  143180. + OUT gctUINT64 node;
  143181. + }
  143182. + AllocateLinearVideoMemory;
  143183. +
  143184. + /* gcvHAL_ALLOCATE_VIDEO_MEMORY */
  143185. + struct _gcsHAL_ALLOCATE_VIDEO_MEMORY
  143186. + {
  143187. + /* Width of rectangle to allocate. */
  143188. + IN OUT gctUINT width;
  143189. +
  143190. + /* Height of rectangle to allocate. */
  143191. + IN OUT gctUINT height;
  143192. +
  143193. + /* Depth of rectangle to allocate. */
  143194. + IN gctUINT depth;
  143195. +
  143196. + /* Format rectangle to allocate in gceSURF_FORMAT. */
  143197. + IN gceSURF_FORMAT format;
  143198. +
  143199. + /* Type of allocation. */
  143200. + IN gceSURF_TYPE type;
  143201. +
  143202. + /* Memory pool to allocate from. */
  143203. + IN OUT gcePOOL pool;
  143204. +
  143205. + /* Allocated video memory in gcuVIDMEM_NODE. */
  143206. + OUT gctUINT64 node;
  143207. + }
  143208. + AllocateVideoMemory;
  143209. +
  143210. + /* gcvHAL_FREE_VIDEO_MEMORY */
  143211. + struct _gcsHAL_FREE_VIDEO_MEMORY
  143212. + {
  143213. + /* Allocated video memory in gcuVIDMEM_NODE. */
  143214. + IN gctUINT64 node;
  143215. +
  143216. +#ifdef __QNXNTO__
  143217. +/* TODO: This is part of the unlock - why is it here? */
  143218. + /* Mapped logical address to unmap in user space. */
  143219. + OUT gctUINT64 memory;
  143220. +
  143221. + /* Number of bytes to allocated. */
  143222. + OUT gctUINT64 bytes;
  143223. +#endif
  143224. + }
  143225. + FreeVideoMemory;
  143226. +
  143227. + /* gcvHAL_LOCK_VIDEO_MEMORY */
  143228. + struct _gcsHAL_LOCK_VIDEO_MEMORY
  143229. + {
  143230. + /* Allocated video memory gcuVIDMEM_NODE gcuVIDMEM_NODE. */
  143231. + IN gctUINT64 node;
  143232. +
  143233. + /* Cache configuration. */
  143234. + /* Only gcvPOOL_CONTIGUOUS and gcvPOOL_VIRUTAL
  143235. + ** can be configured */
  143236. + IN gctBOOL cacheable;
  143237. +
  143238. + /* Hardware specific address. */
  143239. + OUT gctUINT32 address;
  143240. +
  143241. + /* Mapped logical address. */
  143242. + OUT gctUINT64 memory;
  143243. + }
  143244. + LockVideoMemory;
  143245. +
  143246. + /* gcvHAL_UNLOCK_VIDEO_MEMORY */
  143247. + struct _gcsHAL_UNLOCK_VIDEO_MEMORY
  143248. + {
  143249. + /* Allocated video memory in gcuVIDMEM_NODE. */
  143250. + IN gctUINT64 node;
  143251. +
  143252. + /* Type of surface. */
  143253. + IN gceSURF_TYPE type;
  143254. +
  143255. + /* Flag to unlock surface asynchroneously. */
  143256. + IN OUT gctBOOL asynchroneous;
  143257. + }
  143258. + UnlockVideoMemory;
  143259. +
  143260. + /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
  143261. + struct _gcsHAL_ALLOCATE_NON_PAGED_MEMORY
  143262. + {
  143263. + /* Number of bytes to allocate. */
  143264. + IN OUT gctUINT64 bytes;
  143265. +
  143266. + /* Physical address of allocation. Just a name. */
  143267. + OUT gctUINT32 physical;
  143268. +
  143269. + /* Logical address of allocation. */
  143270. + OUT gctUINT64 logical;
  143271. + }
  143272. + AllocateNonPagedMemory;
  143273. +
  143274. + /* gcvHAL_FREE_NON_PAGED_MEMORY */
  143275. + struct _gcsHAL_FREE_NON_PAGED_MEMORY
  143276. + {
  143277. + /* Number of bytes allocated. */
  143278. + IN gctUINT64 bytes;
  143279. +
  143280. + /* Physical address of allocation. Just a name. */
  143281. + IN gctUINT32 physical;
  143282. +
  143283. + /* Logical address of allocation. */
  143284. + IN gctUINT64 logical;
  143285. + }
  143286. + FreeNonPagedMemory;
  143287. +
  143288. + /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
  143289. + struct _gcsHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER
  143290. + {
  143291. + /* Number of bytes to allocate. */
  143292. + IN OUT gctUINT64 bytes;
  143293. +
  143294. + /* Physical address of allocation. Just a name. */
  143295. + OUT gctUINT32 physical;
  143296. +
  143297. + /* Logical address of allocation. */
  143298. + OUT gctUINT64 logical;
  143299. + }
  143300. + AllocateVirtualCommandBuffer;
  143301. +
  143302. + /* gcvHAL_FREE_NON_PAGED_MEMORY */
  143303. + struct _gcsHAL_FREE_VIRTUAL_COMMAND_BUFFER
  143304. + {
  143305. + /* Number of bytes allocated. */
  143306. + IN gctUINT64 bytes;
  143307. +
  143308. + /* Physical address of allocation. Just a name. */
  143309. + IN gctUINT32 physical;
  143310. +
  143311. + /* Logical address of allocation. */
  143312. + IN gctUINT64 logical;
  143313. + }
  143314. + FreeVirtualCommandBuffer;
  143315. +
  143316. + /* gcvHAL_EVENT_COMMIT. */
  143317. + struct _gcsHAL_EVENT_COMMIT
  143318. + {
  143319. + /* Event queue in gcsQUEUE. */
  143320. + IN gctUINT64 queue;
  143321. + }
  143322. + Event;
  143323. +
  143324. + /* gcvHAL_COMMIT */
  143325. + struct _gcsHAL_COMMIT
  143326. + {
  143327. + /* Context buffer object gckCONTEXT. */
  143328. + IN gctUINT64 context;
  143329. +
  143330. + /* Command buffer gcoCMDBUF. */
  143331. + IN gctUINT64 commandBuffer;
  143332. +
  143333. + /* State delta buffer in gcsSTATE_DELTA. */
  143334. + gctUINT64 delta;
  143335. +
  143336. + /* Event queue in gcsQUEUE. */
  143337. + IN gctUINT64 queue;
  143338. + }
  143339. + Commit;
  143340. +
  143341. + /* gcvHAL_MAP_USER_MEMORY */
  143342. + struct _gcsHAL_MAP_USER_MEMORY
  143343. + {
  143344. + /* Base address of user memory to map. */
  143345. + IN gctUINT64 memory;
  143346. +
  143347. + /* Physical address of user memory to map. */
  143348. + IN gctUINT32 physical;
  143349. +
  143350. + /* Size of user memory in bytes to map. */
  143351. + IN gctUINT64 size;
  143352. +
  143353. + /* Info record required by gcvHAL_UNMAP_USER_MEMORY. Just a name. */
  143354. + OUT gctUINT32 info;
  143355. +
  143356. + /* Physical address of mapped memory. */
  143357. + OUT gctUINT32 address;
  143358. + }
  143359. + MapUserMemory;
  143360. +
  143361. + /* gcvHAL_UNMAP_USER_MEMORY */
  143362. + struct _gcsHAL_UNMAP_USER_MEMORY
  143363. + {
  143364. + /* Base address of user memory to unmap. */
  143365. + IN gctUINT64 memory;
  143366. +
  143367. + /* Size of user memory in bytes to unmap. */
  143368. + IN gctUINT64 size;
  143369. +
  143370. + /* Info record returned by gcvHAL_MAP_USER_MEMORY. Just a name. */
  143371. + IN gctUINT32 info;
  143372. +
  143373. + /* Physical address of mapped memory as returned by
  143374. + gcvHAL_MAP_USER_MEMORY. */
  143375. + IN gctUINT32 address;
  143376. + }
  143377. + UnmapUserMemory;
  143378. +#if !USE_NEW_LINUX_SIGNAL
  143379. + /* gcsHAL_USER_SIGNAL */
  143380. + struct _gcsHAL_USER_SIGNAL
  143381. + {
  143382. + /* Command. */
  143383. + gceUSER_SIGNAL_COMMAND_CODES command;
  143384. +
  143385. + /* Signal ID. */
  143386. + IN OUT gctINT id;
  143387. +
  143388. + /* Reset mode. */
  143389. + IN gctBOOL manualReset;
  143390. +
  143391. + /* Wait timedout. */
  143392. + IN gctUINT32 wait;
  143393. +
  143394. + /* State. */
  143395. + IN gctBOOL state;
  143396. + }
  143397. + UserSignal;
  143398. +#endif
  143399. +
  143400. + /* gcvHAL_SIGNAL. */
  143401. + struct _gcsHAL_SIGNAL
  143402. + {
  143403. + /* Signal handle to signal gctSIGNAL. */
  143404. + IN gctUINT64 signal;
  143405. +
  143406. + /* Reserved gctSIGNAL. */
  143407. + IN gctUINT64 auxSignal;
  143408. +
  143409. + /* Process owning the signal gctHANDLE. */
  143410. + IN gctUINT64 process;
  143411. +
  143412. +#if defined(__QNXNTO__)
  143413. + /* Client pulse side-channel connection ID. Set by client in gcoOS_CreateSignal. */
  143414. + IN gctINT32 coid;
  143415. +
  143416. + /* Set by server. */
  143417. + IN gctINT32 rcvid;
  143418. +#endif
  143419. + /* Event generated from where of pipeline */
  143420. + IN gceKERNEL_WHERE fromWhere;
  143421. + }
  143422. + Signal;
  143423. +
  143424. + /* gcvHAL_WRITE_DATA. */
  143425. + struct _gcsHAL_WRITE_DATA
  143426. + {
  143427. + /* Address to write data to. */
  143428. + IN gctUINT32 address;
  143429. +
  143430. + /* Data to write. */
  143431. + IN gctUINT32 data;
  143432. + }
  143433. + WriteData;
  143434. +
  143435. + /* gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY */
  143436. + struct _gcsHAL_ALLOCATE_CONTIGUOUS_MEMORY
  143437. + {
  143438. + /* Number of bytes to allocate. */
  143439. + IN OUT gctUINT64 bytes;
  143440. +
  143441. + /* Hardware address of allocation. */
  143442. + OUT gctUINT32 address;
  143443. +
  143444. + /* Physical address of allocation. Just a name. */
  143445. + OUT gctUINT32 physical;
  143446. +
  143447. + /* Logical address of allocation. */
  143448. + OUT gctUINT64 logical;
  143449. + }
  143450. + AllocateContiguousMemory;
  143451. +
  143452. + /* gcvHAL_FREE_CONTIGUOUS_MEMORY */
  143453. + struct _gcsHAL_FREE_CONTIGUOUS_MEMORY
  143454. + {
  143455. + /* Number of bytes allocated. */
  143456. + IN gctUINT64 bytes;
  143457. +
  143458. + /* Physical address of allocation. Just a name. */
  143459. + IN gctUINT32 physical;
  143460. +
  143461. + /* Logical address of allocation. */
  143462. + IN gctUINT64 logical;
  143463. + }
  143464. + FreeContiguousMemory;
  143465. +
  143466. + /* gcvHAL_READ_REGISTER */
  143467. + struct _gcsHAL_READ_REGISTER
  143468. + {
  143469. + /* Logical address of memory to write data to. */
  143470. + IN gctUINT32 address;
  143471. +
  143472. + /* Data read. */
  143473. + OUT gctUINT32 data;
  143474. + }
  143475. + ReadRegisterData;
  143476. +
  143477. + /* gcvHAL_WRITE_REGISTER */
  143478. + struct _gcsHAL_WRITE_REGISTER
  143479. + {
  143480. + /* Logical address of memory to write data to. */
  143481. + IN gctUINT32 address;
  143482. +
  143483. + /* Data read. */
  143484. + IN gctUINT32 data;
  143485. + }
  143486. + WriteRegisterData;
  143487. +
  143488. +#if VIVANTE_PROFILER
  143489. + /* gcvHAL_GET_PROFILE_SETTING */
  143490. + struct _gcsHAL_GET_PROFILE_SETTING
  143491. + {
  143492. + /* Enable profiling */
  143493. + OUT gctBOOL enable;
  143494. +
  143495. + /* The profile file name */
  143496. + OUT gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
  143497. + }
  143498. + GetProfileSetting;
  143499. +
  143500. + /* gcvHAL_SET_PROFILE_SETTING */
  143501. + struct _gcsHAL_SET_PROFILE_SETTING
  143502. + {
  143503. + /* Enable profiling */
  143504. + IN gctBOOL enable;
  143505. +
  143506. + /* The profile file name */
  143507. + IN gctCHAR fileName[gcdMAX_PROFILE_FILE_NAME];
  143508. + }
  143509. + SetProfileSetting;
  143510. +
  143511. +#if VIVANTE_PROFILER_PERDRAW
  143512. + /* gcvHAL_READ_PROFILER_REGISTER_SETTING */
  143513. + struct _gcsHAL_READ_PROFILER_REGISTER_SETTING
  143514. + {
  143515. + /*Should Clear Register*/
  143516. + IN gctBOOL bclear;
  143517. + }
  143518. + SetProfilerRegisterClear;
  143519. +#endif
  143520. +
  143521. + /* gcvHAL_READ_ALL_PROFILE_REGISTERS */
  143522. + struct _gcsHAL_READ_ALL_PROFILE_REGISTERS
  143523. + {
  143524. +#if VIVANTE_PROFILER_CONTEXT
  143525. + /* Context buffer object gckCONTEXT. Just a name. */
  143526. + IN gctUINT32 context;
  143527. +#endif
  143528. + /* Data read. */
  143529. + OUT gcsPROFILER_COUNTERS counters;
  143530. + }
  143531. + RegisterProfileData;
  143532. +
  143533. + /* gcvHAL_PROFILE_REGISTERS_2D */
  143534. + struct _gcsHAL_PROFILE_REGISTERS_2D
  143535. + {
  143536. + /* Data read in gcs2D_PROFILE. */
  143537. + OUT gctUINT64 hwProfile2D;
  143538. + }
  143539. + RegisterProfileData2D;
  143540. +#endif
  143541. + /* Power management. */
  143542. + /* gcvHAL_SET_POWER_MANAGEMENT_STATE */
  143543. + struct _gcsHAL_SET_POWER_MANAGEMENT
  143544. + {
  143545. + /* Data read. */
  143546. + IN gceCHIPPOWERSTATE state;
  143547. + }
  143548. + SetPowerManagement;
  143549. +
  143550. + /* gcvHAL_QUERY_POWER_MANAGEMENT_STATE */
  143551. + struct _gcsHAL_QUERY_POWER_MANAGEMENT
  143552. + {
  143553. + /* Data read. */
  143554. + OUT gceCHIPPOWERSTATE state;
  143555. +
  143556. + /* Idle query. */
  143557. + OUT gctBOOL isIdle;
  143558. + }
  143559. + QueryPowerManagement;
  143560. +
  143561. + /* gcvHAL_QUERY_KERNEL_SETTINGS */
  143562. + struct _gcsHAL_QUERY_KERNEL_SETTINGS
  143563. + {
  143564. + /* Settings.*/
  143565. + OUT gcsKERNEL_SETTINGS settings;
  143566. + }
  143567. + QueryKernelSettings;
  143568. +
  143569. + /* gcvHAL_MAP_PHYSICAL */
  143570. + struct _gcsHAL_MAP_PHYSICAL
  143571. + {
  143572. + /* gcvTRUE to map, gcvFALSE to unmap. */
  143573. + IN gctBOOL map;
  143574. +
  143575. + /* Physical address. */
  143576. + IN OUT gctUINT64 physical;
  143577. + }
  143578. + MapPhysical;
  143579. +
  143580. + /* gcvHAL_DEBUG */
  143581. + struct _gcsHAL_DEBUG
  143582. + {
  143583. + /* If gcvTRUE, set the debug information. */
  143584. + IN gctBOOL set;
  143585. + IN gctUINT32 level;
  143586. + IN gctUINT32 zones;
  143587. + IN gctBOOL enable;
  143588. +
  143589. + IN gceDEBUG_MESSAGE_TYPE type;
  143590. + IN gctUINT32 messageSize;
  143591. +
  143592. + /* Message to print if not empty. */
  143593. + IN gctCHAR message[80];
  143594. + }
  143595. + Debug;
  143596. +
  143597. + /* gcvHAL_CACHE */
  143598. + struct _gcsHAL_CACHE
  143599. + {
  143600. + IN gceCACHEOPERATION operation;
  143601. + /* gctHANDLE */
  143602. + IN gctUINT64 process;
  143603. + IN gctUINT64 logical;
  143604. + IN gctUINT64 bytes;
  143605. + /* gcuVIDMEM_NODE_PTR */
  143606. + IN gctUINT64 node;
  143607. + }
  143608. + Cache;
  143609. +
  143610. + /* gcvHAL_TIMESTAMP */
  143611. + struct _gcsHAL_TIMESTAMP
  143612. + {
  143613. + /* Timer select. */
  143614. + IN gctUINT32 timer;
  143615. +
  143616. + /* Timer request type (0-stop, 1-start, 2-send delta). */
  143617. + IN gctUINT32 request;
  143618. +
  143619. + /* Result of delta time in microseconds. */
  143620. + OUT gctINT32 timeDelta;
  143621. + }
  143622. + TimeStamp;
  143623. +
  143624. + /* gcvHAL_DATABASE */
  143625. + struct _gcsHAL_DATABASE
  143626. + {
  143627. + /* Set to gcvTRUE if you want to query a particular process ID.
  143628. + ** Set to gcvFALSE to query the last detached process. */
  143629. + IN gctBOOL validProcessID;
  143630. +
  143631. + /* Process ID to query. */
  143632. + IN gctUINT32 processID;
  143633. +
  143634. + /* Information. */
  143635. + OUT gcuDATABASE_INFO vidMem;
  143636. + OUT gcuDATABASE_INFO nonPaged;
  143637. + OUT gcuDATABASE_INFO contiguous;
  143638. + OUT gcuDATABASE_INFO gpuIdle;
  143639. + }
  143640. + Database;
  143641. +
  143642. + /* gcvHAL_VIDMEM_DATABASE */
  143643. + struct _gcsHAL_VIDMEM_DATABASE
  143644. + {
  143645. + /* Set to gcvTRUE if you want to query a particular process ID.
  143646. + ** Set to gcvFALSE to query the last detached process. */
  143647. + IN gctBOOL validProcessID;
  143648. +
  143649. + /* Process ID to query. */
  143650. + IN gctUINT32 processID;
  143651. +
  143652. + /* Information. */
  143653. + OUT gcuDATABASE_INFO vidMemResv;
  143654. + OUT gcuDATABASE_INFO vidMemCont;
  143655. + OUT gcuDATABASE_INFO vidMemVirt;
  143656. + }
  143657. + VidMemDatabase;
  143658. +
  143659. + /* gcvHAL_VERSION */
  143660. + struct _gcsHAL_VERSION
  143661. + {
  143662. + /* Major version: N.n.n. */
  143663. + OUT gctINT32 major;
  143664. +
  143665. + /* Minor version: n.N.n. */
  143666. + OUT gctINT32 minor;
  143667. +
  143668. + /* Patch version: n.n.N. */
  143669. + OUT gctINT32 patch;
  143670. +
  143671. + /* Build version. */
  143672. + OUT gctUINT32 build;
  143673. + }
  143674. + Version;
  143675. +
  143676. + /* gcvHAL_CHIP_INFO */
  143677. + struct _gcsHAL_CHIP_INFO
  143678. + {
  143679. + /* Chip count. */
  143680. + OUT gctINT32 count;
  143681. +
  143682. + /* Chip types. */
  143683. + OUT gceHARDWARE_TYPE types[gcdCHIP_COUNT];
  143684. + }
  143685. + ChipInfo;
  143686. +
  143687. + /* gcvHAL_ATTACH */
  143688. + struct _gcsHAL_ATTACH
  143689. + {
  143690. + /* Context buffer object gckCONTEXT. Just a name. */
  143691. + OUT gctUINT32 context;
  143692. +
  143693. + /* Number of states in the buffer. */
  143694. + OUT gctUINT64 stateCount;
  143695. + }
  143696. + Attach;
  143697. +
  143698. + /* gcvHAL_DETACH */
  143699. + struct _gcsHAL_DETACH
  143700. + {
  143701. + /* Context buffer object gckCONTEXT. Just a name. */
  143702. + IN gctUINT32 context;
  143703. + }
  143704. + Detach;
  143705. +
  143706. + /* gcvHAL_COMPOSE. */
  143707. + gcsHAL_COMPOSE Compose;
  143708. +
  143709. + /* gcvHAL_GET_FRAME_INFO. */
  143710. + struct _gcsHAL_GET_FRAME_INFO
  143711. + {
  143712. + /* gcsHAL_FRAME_INFO* */
  143713. + OUT gctUINT64 frameInfo;
  143714. + }
  143715. + GetFrameInfo;
  143716. +
  143717. + /* gcvHAL_SET_TIME_OUT. */
  143718. + struct _gcsHAL_SET_TIMEOUT
  143719. + {
  143720. + gctUINT32 timeOut;
  143721. + }
  143722. + SetTimeOut;
  143723. +
  143724. +#if gcdENABLE_VG
  143725. + /* gcvHAL_COMMIT */
  143726. + struct _gcsHAL_VGCOMMIT
  143727. + {
  143728. + /* Context buffer in gcsVGCONTEXT. */
  143729. + IN gctUINT64 context;
  143730. +
  143731. + /* Command queue in gcsVGCMDQUEUE. */
  143732. + IN gctUINT64 queue;
  143733. +
  143734. + /* Number of entries in the queue. */
  143735. + IN gctUINT entryCount;
  143736. +
  143737. + /* Task table in gcsTASK_MASTER_TABLE. */
  143738. + IN gctUINT64 taskTable;
  143739. + }
  143740. + VGCommit;
  143741. +
  143742. + /* gcvHAL_QUERY_COMMAND_BUFFER */
  143743. + struct _gcsHAL_QUERY_COMMAND_BUFFER
  143744. + {
  143745. + /* Command buffer attributes. */
  143746. + OUT gcsCOMMAND_BUFFER_INFO information;
  143747. + }
  143748. + QueryCommandBuffer;
  143749. +
  143750. +#endif
  143751. +
  143752. + struct _gcsHAL_GET_SHARED_INFO
  143753. + {
  143754. + /* Process id. */
  143755. + IN gctUINT32 pid;
  143756. +
  143757. + /* Data id. */
  143758. + IN gctUINT32 dataId;
  143759. +
  143760. + /* Data size. */
  143761. + IN gctSIZE_T bytes;
  143762. +
  143763. + /* Pointer to save the shared data. */
  143764. + OUT gctPOINTER data;
  143765. + }
  143766. + GetSharedInfo;
  143767. +
  143768. + struct _gcsHAL_SET_SHARED_INFO
  143769. + {
  143770. + /* Data id. */
  143771. + IN gctUINT32 dataId;
  143772. +
  143773. + /* Data to be shared. */
  143774. + IN gctPOINTER data;
  143775. +
  143776. + /* Data size. */
  143777. + IN gctSIZE_T bytes;
  143778. + }
  143779. + SetSharedInfo;
  143780. +
  143781. + struct _gcsHAL_SET_FSCALE_VALUE
  143782. + {
  143783. + IN gctUINT value;
  143784. + }
  143785. + SetFscaleValue;
  143786. +
  143787. + struct _gcsHAL_GET_FSCALE_VALUE
  143788. + {
  143789. + OUT gctUINT value;
  143790. + OUT gctUINT minValue;
  143791. + OUT gctUINT maxValue;
  143792. + }
  143793. + GetFscaleValue;
  143794. +
  143795. + struct _gcsHAL_QUERY_RESET_TIME_STAMP
  143796. + {
  143797. + OUT gctUINT64 timeStamp;
  143798. + }
  143799. + QueryResetTimeStamp;
  143800. +
  143801. + struct _gcsHAL_SYNC_POINT
  143802. + {
  143803. + /* Command. */
  143804. + gceSYNC_POINT_COMMAND_CODES command;
  143805. +
  143806. + /* Sync point. */
  143807. + IN OUT gctUINT64 syncPoint;
  143808. +
  143809. + /* From where. */
  143810. + IN gceKERNEL_WHERE fromWhere;
  143811. +
  143812. + /* Signaled state. */
  143813. + OUT gctBOOL state;
  143814. + }
  143815. + SyncPoint;
  143816. +
  143817. + struct _gcsHAL_CREATE_NATIVE_FENCE
  143818. + {
  143819. + /* Signal id to dup. */
  143820. + IN gctUINT64 syncPoint;
  143821. +
  143822. + /* Native fence file descriptor. */
  143823. + OUT gctINT fenceFD;
  143824. +
  143825. + }
  143826. + CreateNativeFence;
  143827. + }
  143828. + u;
  143829. +}
  143830. +gcsHAL_INTERFACE;
  143831. +
  143832. +
  143833. +#ifdef __cplusplus
  143834. +}
  143835. +#endif
  143836. +
  143837. +#endif /* __gc_hal_driver_h_ */
  143838. diff -Nur linux-3.14.17/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
  143839. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h 1970-01-01 01:00:00.000000000 +0100
  143840. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h 2014-09-11 18:06:03.118042434 +0200
  143841. @@ -0,0 +1,270 @@
  143842. +/****************************************************************************
  143843. +*
  143844. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  143845. +*
  143846. +* This program is free software; you can redistribute it and/or modify
  143847. +* it under the terms of the GNU General Public License as published by
  143848. +* the Free Software Foundation; either version 2 of the license, or
  143849. +* (at your option) any later version.
  143850. +*
  143851. +* This program is distributed in the hope that it will be useful,
  143852. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  143853. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  143854. +* GNU General Public License for more details.
  143855. +*
  143856. +* You should have received a copy of the GNU General Public License
  143857. +* along with this program; if not write to the Free Software
  143858. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  143859. +*
  143860. +*****************************************************************************/
  143861. +
  143862. +
  143863. +#ifndef __gc_hal_driver_vg_h_
  143864. +#define __gc_hal_driver_vg_h_
  143865. +
  143866. +
  143867. +
  143868. +#include "gc_hal_types.h"
  143869. +
  143870. +#ifdef __cplusplus
  143871. +extern "C" {
  143872. +#endif
  143873. +
  143874. +/******************************************************************************\
  143875. +******************************* I/O Control Codes ******************************
  143876. +\******************************************************************************/
  143877. +
  143878. +#define gcvHAL_CLASS "galcore"
  143879. +#define IOCTL_GCHAL_INTERFACE 30000
  143880. +
  143881. +/******************************************************************************\
  143882. +********************************* Command Codes ********************************
  143883. +\******************************************************************************/
  143884. +
  143885. +/******************************************************************************\
  143886. +********************* Command buffer information structure. ********************
  143887. +\******************************************************************************/
  143888. +
  143889. +typedef struct _gcsCOMMAND_BUFFER_INFO * gcsCOMMAND_BUFFER_INFO_PTR;
  143890. +typedef struct _gcsCOMMAND_BUFFER_INFO
  143891. +{
  143892. + /* FE command buffer interrupt ID. */
  143893. + gctINT32 feBufferInt;
  143894. +
  143895. + /* TS overflow interrupt ID. */
  143896. + gctINT32 tsOverflowInt;
  143897. +
  143898. + /* Alignment and mask for the buffer address. */
  143899. + gctUINT addressMask;
  143900. + gctSIZE_T addressAlignment;
  143901. +
  143902. + /* Alignment for each command. */
  143903. + gctSIZE_T commandAlignment;
  143904. +
  143905. + /* Number of bytes required by the STATE command. */
  143906. + gctSIZE_T stateCommandSize;
  143907. +
  143908. + /* Number of bytes required by the RESTART command. */
  143909. + gctSIZE_T restartCommandSize;
  143910. +
  143911. + /* Number of bytes required by the FETCH command. */
  143912. + gctSIZE_T fetchCommandSize;
  143913. +
  143914. + /* Number of bytes required by the CALL command. */
  143915. + gctSIZE_T callCommandSize;
  143916. +
  143917. + /* Number of bytes required by the RETURN command. */
  143918. + gctSIZE_T returnCommandSize;
  143919. +
  143920. + /* Number of bytes required by the EVENT command. */
  143921. + gctSIZE_T eventCommandSize;
  143922. +
  143923. + /* Number of bytes required by the END command. */
  143924. + gctSIZE_T endCommandSize;
  143925. +
  143926. + /* Number of bytes reserved at the tail of a static command buffer. */
  143927. + gctSIZE_T staticTailSize;
  143928. +
  143929. + /* Number of bytes reserved at the tail of a dynamic command buffer. */
  143930. + gctSIZE_T dynamicTailSize;
  143931. +}
  143932. +gcsCOMMAND_BUFFER_INFO;
  143933. +
  143934. +/******************************************************************************\
  143935. +******************************** Task Structures *******************************
  143936. +\******************************************************************************/
  143937. +
  143938. +typedef enum _gceTASK
  143939. +{
  143940. + gcvTASK_LINK,
  143941. + gcvTASK_CLUSTER,
  143942. + gcvTASK_INCREMENT,
  143943. + gcvTASK_DECREMENT,
  143944. + gcvTASK_SIGNAL,
  143945. + gcvTASK_LOCKDOWN,
  143946. + gcvTASK_UNLOCK_VIDEO_MEMORY,
  143947. + gcvTASK_FREE_VIDEO_MEMORY,
  143948. + gcvTASK_FREE_CONTIGUOUS_MEMORY,
  143949. + gcvTASK_UNMAP_USER_MEMORY
  143950. +}
  143951. +gceTASK;
  143952. +
  143953. +typedef struct _gcsTASK_HEADER * gcsTASK_HEADER_PTR;
  143954. +typedef struct _gcsTASK_HEADER
  143955. +{
  143956. + /* Task ID. */
  143957. + IN gceTASK id;
  143958. +}
  143959. +gcsTASK_HEADER;
  143960. +
  143961. +typedef struct _gcsTASK_LINK * gcsTASK_LINK_PTR;
  143962. +typedef struct _gcsTASK_LINK
  143963. +{
  143964. + /* Task ID (gcvTASK_LINK). */
  143965. + IN gceTASK id;
  143966. +
  143967. + /* Pointer to the next task container. */
  143968. + IN gctPOINTER cotainer;
  143969. +
  143970. + /* Pointer to the next task from the next task container. */
  143971. + IN gcsTASK_HEADER_PTR task;
  143972. +}
  143973. +gcsTASK_LINK;
  143974. +
  143975. +typedef struct _gcsTASK_CLUSTER * gcsTASK_CLUSTER_PTR;
  143976. +typedef struct _gcsTASK_CLUSTER
  143977. +{
  143978. + /* Task ID (gcvTASK_CLUSTER). */
  143979. + IN gceTASK id;
  143980. +
  143981. + /* Number of tasks in the cluster. */
  143982. + IN gctUINT taskCount;
  143983. +}
  143984. +gcsTASK_CLUSTER;
  143985. +
  143986. +typedef struct _gcsTASK_INCREMENT * gcsTASK_INCREMENT_PTR;
  143987. +typedef struct _gcsTASK_INCREMENT
  143988. +{
  143989. + /* Task ID (gcvTASK_INCREMENT). */
  143990. + IN gceTASK id;
  143991. +
  143992. + /* Address of the variable to increment. */
  143993. + IN gctUINT32 address;
  143994. +}
  143995. +gcsTASK_INCREMENT;
  143996. +
  143997. +typedef struct _gcsTASK_DECREMENT * gcsTASK_DECREMENT_PTR;
  143998. +typedef struct _gcsTASK_DECREMENT
  143999. +{
  144000. + /* Task ID (gcvTASK_DECREMENT). */
  144001. + IN gceTASK id;
  144002. +
  144003. + /* Address of the variable to decrement. */
  144004. + IN gctUINT32 address;
  144005. +}
  144006. +gcsTASK_DECREMENT;
  144007. +
  144008. +typedef struct _gcsTASK_SIGNAL * gcsTASK_SIGNAL_PTR;
  144009. +typedef struct _gcsTASK_SIGNAL
  144010. +{
  144011. + /* Task ID (gcvTASK_SIGNAL). */
  144012. + IN gceTASK id;
  144013. +
  144014. + /* Process owning the signal. */
  144015. + IN gctHANDLE process;
  144016. +
  144017. + /* Signal handle to signal. */
  144018. + IN gctSIGNAL signal;
  144019. +
  144020. +#if defined(__QNXNTO__)
  144021. + IN gctINT32 coid;
  144022. + IN gctINT32 rcvid;
  144023. +#endif
  144024. +}
  144025. +gcsTASK_SIGNAL;
  144026. +
  144027. +typedef struct _gcsTASK_LOCKDOWN * gcsTASK_LOCKDOWN_PTR;
  144028. +typedef struct _gcsTASK_LOCKDOWN
  144029. +{
  144030. + /* Task ID (gcvTASK_LOCKDOWN). */
  144031. + IN gceTASK id;
  144032. +
  144033. + /* Address of the user space counter. */
  144034. + IN gctUINT32 userCounter;
  144035. +
  144036. + /* Address of the kernel space counter. */
  144037. + IN gctUINT32 kernelCounter;
  144038. +
  144039. + /* Process owning the signal. */
  144040. + IN gctHANDLE process;
  144041. +
  144042. + /* Signal handle to signal. */
  144043. + IN gctSIGNAL signal;
  144044. +}
  144045. +gcsTASK_LOCKDOWN;
  144046. +
  144047. +typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY * gcsTASK_UNLOCK_VIDEO_MEMORY_PTR;
  144048. +typedef struct _gcsTASK_UNLOCK_VIDEO_MEMORY
  144049. +{
  144050. + /* Task ID (gcvTASK_UNLOCK_VIDEO_MEMORY). */
  144051. + IN gceTASK id;
  144052. +
  144053. + /* Allocated video memory. */
  144054. + IN gctUINT64 node;
  144055. +}
  144056. +gcsTASK_UNLOCK_VIDEO_MEMORY;
  144057. +
  144058. +typedef struct _gcsTASK_FREE_VIDEO_MEMORY * gcsTASK_FREE_VIDEO_MEMORY_PTR;
  144059. +typedef struct _gcsTASK_FREE_VIDEO_MEMORY
  144060. +{
  144061. + /* Task ID (gcvTASK_FREE_VIDEO_MEMORY). */
  144062. + IN gceTASK id;
  144063. +
  144064. + /* Allocated video memory. */
  144065. + IN gctUINT64 node;
  144066. +}
  144067. +gcsTASK_FREE_VIDEO_MEMORY;
  144068. +
  144069. +typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY * gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR;
  144070. +typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY
  144071. +{
  144072. + /* Task ID (gcvTASK_FREE_CONTIGUOUS_MEMORY). */
  144073. + IN gceTASK id;
  144074. +
  144075. + /* Number of bytes allocated. */
  144076. + IN gctSIZE_T bytes;
  144077. +
  144078. + /* Physical address of allocation. */
  144079. + IN gctPHYS_ADDR physical;
  144080. +
  144081. + /* Logical address of allocation. */
  144082. + IN gctPOINTER logical;
  144083. +}
  144084. +gcsTASK_FREE_CONTIGUOUS_MEMORY;
  144085. +
  144086. +typedef struct _gcsTASK_UNMAP_USER_MEMORY * gcsTASK_UNMAP_USER_MEMORY_PTR;
  144087. +typedef struct _gcsTASK_UNMAP_USER_MEMORY
  144088. +{
  144089. + /* Task ID (gcvTASK_UNMAP_USER_MEMORY). */
  144090. + IN gceTASK id;
  144091. +
  144092. + /* Base address of user memory to unmap. */
  144093. + IN gctPOINTER memory;
  144094. +
  144095. + /* Size of user memory in bytes to unmap. */
  144096. + IN gctSIZE_T size;
  144097. +
  144098. + /* Info record returned by gcvHAL_MAP_USER_MEMORY. */
  144099. + IN gctPOINTER info;
  144100. +
  144101. + /* Physical address of mapped memory as returned by
  144102. + gcvHAL_MAP_USER_MEMORY. */
  144103. + IN gctUINT32 address;
  144104. +}
  144105. +gcsTASK_UNMAP_USER_MEMORY;
  144106. +
  144107. +#ifdef __cplusplus
  144108. +}
  144109. +#endif
  144110. +
  144111. +#endif /* __gc_hal_driver_h_ */
  144112. diff -Nur linux-3.14.17/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
  144113. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h 1970-01-01 01:00:00.000000000 +0100
  144114. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h 2014-09-11 18:06:03.118042434 +0200
  144115. @@ -0,0 +1,88 @@
  144116. +/****************************************************************************
  144117. +*
  144118. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  144119. +*
  144120. +* This program is free software; you can redistribute it and/or modify
  144121. +* it under the terms of the GNU General Public License as published by
  144122. +* the Free Software Foundation; either version 2 of the license, or
  144123. +* (at your option) any later version.
  144124. +*
  144125. +* This program is distributed in the hope that it will be useful,
  144126. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  144127. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  144128. +* GNU General Public License for more details.
  144129. +*
  144130. +* You should have received a copy of the GNU General Public License
  144131. +* along with this program; if not write to the Free Software
  144132. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  144133. +*
  144134. +*****************************************************************************/
  144135. +
  144136. +
  144137. +#ifndef __gc_hal_dump_h_
  144138. +#define __gc_hal_dump_h_
  144139. +
  144140. +#ifdef __cplusplus
  144141. +extern "C" {
  144142. +#endif
  144143. +
  144144. +/*
  144145. +** FILE LAYOUT:
  144146. +**
  144147. +** gcsDUMP_FILE structure
  144148. +**
  144149. +** gcsDUMP_DATA frame
  144150. +** gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame
  144151. +** gctUINT8 data[length]
  144152. +*/
  144153. +
  144154. +#define gcvDUMP_FILE_SIGNATURE gcmCC('g','c','D','B')
  144155. +
  144156. +typedef struct _gcsDUMP_FILE
  144157. +{
  144158. + gctUINT32 signature; /* File signature */
  144159. + gctSIZE_T length; /* Length of file */
  144160. + gctUINT32 frames; /* Number of frames in file */
  144161. +}
  144162. +gcsDUMP_FILE;
  144163. +
  144164. +typedef enum _gceDUMP_TAG
  144165. +{
  144166. + gcvTAG_SURFACE = gcmCC('s','u','r','f'),
  144167. + gcvTAG_FRAME = gcmCC('f','r','m',' '),
  144168. + gcvTAG_COMMAND = gcmCC('c','m','d',' '),
  144169. + gcvTAG_INDEX = gcmCC('i','n','d','x'),
  144170. + gcvTAG_STREAM = gcmCC('s','t','r','m'),
  144171. + gcvTAG_TEXTURE = gcmCC('t','e','x','t'),
  144172. + gcvTAG_RENDER_TARGET = gcmCC('r','n','d','r'),
  144173. + gcvTAG_DEPTH = gcmCC('z','b','u','f'),
  144174. + gcvTAG_RESOLVE = gcmCC('r','s','l','v'),
  144175. + gcvTAG_DELETE = gcmCC('d','e','l',' '),
  144176. +}
  144177. +gceDUMP_TAG;
  144178. +
  144179. +typedef struct _gcsDUMP_SURFACE
  144180. +{
  144181. + gceDUMP_TAG type; /* Type of record. */
  144182. + gctUINT32 address; /* Address of the surface. */
  144183. + gctINT16 width; /* Width of surface. */
  144184. + gctINT16 height; /* Height of surface. */
  144185. + gceSURF_FORMAT format; /* Surface pixel format. */
  144186. + gctSIZE_T length; /* Number of bytes inside the surface. */
  144187. +}
  144188. +gcsDUMP_SURFACE;
  144189. +
  144190. +typedef struct _gcsDUMP_DATA
  144191. +{
  144192. + gceDUMP_TAG type; /* Type of record. */
  144193. + gctSIZE_T length; /* Number of bytes of data. */
  144194. + gctUINT32 address; /* Address for the data. */
  144195. +}
  144196. +gcsDUMP_DATA;
  144197. +
  144198. +#ifdef __cplusplus
  144199. +}
  144200. +#endif
  144201. +
  144202. +#endif /* __gc_hal_dump_h_ */
  144203. +
  144204. diff -Nur linux-3.14.17/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
  144205. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h 1970-01-01 01:00:00.000000000 +0100
  144206. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h 2014-09-11 18:06:03.118042434 +0200
  144207. @@ -0,0 +1,627 @@
  144208. +/****************************************************************************
  144209. +*
  144210. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  144211. +*
  144212. +* This program is free software; you can redistribute it and/or modify
  144213. +* it under the terms of the GNU General Public License as published by
  144214. +* the Free Software Foundation; either version 2 of the license, or
  144215. +* (at your option) any later version.
  144216. +*
  144217. +* This program is distributed in the hope that it will be useful,
  144218. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  144219. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  144220. +* GNU General Public License for more details.
  144221. +*
  144222. +* You should have received a copy of the GNU General Public License
  144223. +* along with this program; if not write to the Free Software
  144224. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  144225. +*
  144226. +*****************************************************************************/
  144227. +
  144228. +#ifndef __gc_hal_eglplatform_h_
  144229. +#define __gc_hal_eglplatform_h_
  144230. +
  144231. +/* Include VDK types. */
  144232. +#include "gc_hal_types.h"
  144233. +#include "gc_hal_base.h"
  144234. +#include "gc_hal_eglplatform_type.h"
  144235. +#ifdef __cplusplus
  144236. +extern "C" {
  144237. +#endif
  144238. +
  144239. +
  144240. +#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
  144241. +/* Win32 and Windows CE platforms. */
  144242. +#include <windows.h>
  144243. +typedef HDC HALNativeDisplayType;
  144244. +typedef HWND HALNativeWindowType;
  144245. +typedef HBITMAP HALNativePixmapType;
  144246. +
  144247. +typedef struct __BITFIELDINFO{
  144248. + BITMAPINFO bmi;
  144249. + RGBQUAD bmiColors[2];
  144250. +} BITFIELDINFO;
  144251. +
  144252. +#elif defined(LINUX) && defined(EGL_API_DFB) && !defined(__APPLE__)
  144253. +#include <directfb.h>
  144254. +typedef struct _DFBDisplay * HALNativeDisplayType;
  144255. +typedef struct _DFBWindow * HALNativeWindowType;
  144256. +typedef struct _DFBPixmap * HALNativePixmapType;
  144257. +
  144258. +#elif defined(LINUX) && defined(EGL_API_FB) && !defined(__APPLE__)
  144259. +
  144260. +#if defined(EGL_API_WL)
  144261. +/* Wayland platform. */
  144262. +#include "wayland-server.h"
  144263. +#include <wayland-egl.h>
  144264. +
  144265. +#define WL_EGL_NUM_BACKBUFFERS 3
  144266. +
  144267. +typedef struct _gcsWL_VIV_BUFFER
  144268. +{
  144269. + struct wl_resource *wl_buffer;
  144270. + gcoSURF surface;
  144271. + gctINT32 width, height;
  144272. +} gcsWL_VIV_BUFFER;
  144273. +
  144274. +typedef struct _gcsWL_EGL_DISPLAY
  144275. +{
  144276. + struct wl_display* wl_display;
  144277. + struct wl_viv* wl_viv;
  144278. + struct wl_registry *registry;
  144279. + struct wl_event_queue *wl_queue;
  144280. +} gcsWL_EGL_DISPLAY;
  144281. +
  144282. +typedef struct _gcsWL_EGL_BUFFER_INFO
  144283. +{
  144284. + gctINT32 width;
  144285. + gctINT32 height;
  144286. + gctINT32 stride;
  144287. + gceSURF_FORMAT format;
  144288. + gcuVIDMEM_NODE_PTR node;
  144289. + gcePOOL pool;
  144290. + gctUINT bytes;
  144291. + gcoSURF surface;
  144292. + gcoSURF attached_surface;
  144293. + gctINT32 invalidate;
  144294. + gctBOOL locked;
  144295. +} gcsWL_EGL_BUFFER_INFO;
  144296. +
  144297. +typedef struct _gcsWL_EGL_BUFFER
  144298. +{
  144299. + struct wl_buffer* wl_buffer;
  144300. + gcsWL_EGL_BUFFER_INFO info;
  144301. +} gcsWL_EGL_BUFFER;
  144302. +
  144303. +typedef struct _gcsWL_EGL_WINDOW_INFO
  144304. +{
  144305. + gctINT32 dx;
  144306. + gctINT32 dy;
  144307. + gctUINT width;
  144308. + gctUINT height;
  144309. + gctINT32 attached_width;
  144310. + gctINT32 attached_height;
  144311. + gceSURF_FORMAT format;
  144312. + gctUINT bpp;
  144313. +} gcsWL_EGL_WINDOW_INFO;
  144314. +
  144315. +struct wl_egl_window
  144316. +{
  144317. + gcsWL_EGL_DISPLAY* display;
  144318. + gcsWL_EGL_BUFFER backbuffers[WL_EGL_NUM_BACKBUFFERS];
  144319. + gcsWL_EGL_WINDOW_INFO info;
  144320. + gctUINT current;
  144321. + struct wl_surface* surface;
  144322. + struct wl_callback* frame_callback;
  144323. +};
  144324. +
  144325. +typedef void* HALNativeDisplayType;
  144326. +typedef void* HALNativeWindowType;
  144327. +typedef void* HALNativePixmapType;
  144328. +#else
  144329. +/* Linux platform for FBDEV. */
  144330. +typedef struct _FBDisplay * HALNativeDisplayType;
  144331. +typedef struct _FBWindow * HALNativeWindowType;
  144332. +typedef struct _FBPixmap * HALNativePixmapType;
  144333. +#endif
  144334. +#elif defined(__ANDROID__) || defined(ANDROID)
  144335. +
  144336. +struct egl_native_pixmap_t;
  144337. +
  144338. +#if ANDROID_SDK_VERSION >= 9
  144339. + #include <android/native_window.h>
  144340. +
  144341. + typedef struct ANativeWindow* HALNativeWindowType;
  144342. + typedef struct egl_native_pixmap_t* HALNativePixmapType;
  144343. + typedef void* HALNativeDisplayType;
  144344. +#else
  144345. + struct android_native_window_t;
  144346. + typedef struct android_native_window_t* HALNativeWindowType;
  144347. + typedef struct egl_native_pixmap_t * HALNativePixmapType;
  144348. + typedef void* HALNativeDisplayType;
  144349. +#endif
  144350. +
  144351. +#elif defined(LINUX) || defined(__APPLE__)
  144352. +/* X11 platform. */
  144353. +#include <X11/Xlib.h>
  144354. +#include <X11/Xutil.h>
  144355. +
  144356. +typedef Display * HALNativeDisplayType;
  144357. +typedef Window HALNativeWindowType;
  144358. +
  144359. +#ifdef CUSTOM_PIXMAP
  144360. +typedef void * HALNativePixmapType;
  144361. +#else
  144362. +typedef Pixmap HALNativePixmapType;
  144363. +#endif /* CUSTOM_PIXMAP */
  144364. +
  144365. +/* Rename some badly named X defines. */
  144366. +#ifdef Status
  144367. +# define XStatus int
  144368. +# undef Status
  144369. +#endif
  144370. +#ifdef Always
  144371. +# define XAlways 2
  144372. +# undef Always
  144373. +#endif
  144374. +#ifdef CurrentTime
  144375. +# undef CurrentTime
  144376. +# define XCurrentTime 0
  144377. +#endif
  144378. +
  144379. +#elif defined(__QNXNTO__)
  144380. +#include <screen/screen.h>
  144381. +
  144382. +/* VOID */
  144383. +typedef int HALNativeDisplayType;
  144384. +typedef screen_window_t HALNativeWindowType;
  144385. +typedef screen_pixmap_t HALNativePixmapType;
  144386. +
  144387. +#else
  144388. +
  144389. +#error "Platform not recognized"
  144390. +
  144391. +/* VOID */
  144392. +typedef void * HALNativeDisplayType;
  144393. +typedef void * HALNativeWindowType;
  144394. +typedef void * HALNativePixmapType;
  144395. +
  144396. +#endif
  144397. +
  144398. +/* define DUMMY according to the system */
  144399. +#if defined(EGL_API_WL)
  144400. +# define WL_DUMMY (31415926)
  144401. +# define EGL_DUMMY WL_DUMMY
  144402. +#elif defined(__ANDROID__) || defined(ANDROID)
  144403. +# define ANDROID_DUMMY (31415926)
  144404. +# define EGL_DUMMY ANDROID_DUMMY
  144405. +#else
  144406. +# define EGL_DUMMY (31415926)
  144407. +#endif
  144408. +
  144409. +/*******************************************************************************
  144410. +** Display. ********************************************************************
  144411. +*/
  144412. +
  144413. +gceSTATUS
  144414. +gcoOS_GetDisplay(
  144415. + OUT HALNativeDisplayType * Display,
  144416. + IN gctPOINTER Context
  144417. + );
  144418. +
  144419. +gceSTATUS
  144420. +gcoOS_GetDisplayByIndex(
  144421. + IN gctINT DisplayIndex,
  144422. + OUT HALNativeDisplayType * Display,
  144423. + IN gctPOINTER Context
  144424. + );
  144425. +
  144426. +gceSTATUS
  144427. +gcoOS_GetDisplayInfo(
  144428. + IN HALNativeDisplayType Display,
  144429. + OUT gctINT * Width,
  144430. + OUT gctINT * Height,
  144431. + OUT gctSIZE_T * Physical,
  144432. + OUT gctINT * Stride,
  144433. + OUT gctINT * BitsPerPixel
  144434. + );
  144435. +
  144436. +
  144437. +
  144438. +gceSTATUS
  144439. +gcoOS_GetDisplayInfoEx(
  144440. + IN HALNativeDisplayType Display,
  144441. + IN HALNativeWindowType Window,
  144442. + IN gctUINT DisplayInfoSize,
  144443. + OUT halDISPLAY_INFO * DisplayInfo
  144444. + );
  144445. +
  144446. +gceSTATUS
  144447. +gcoOS_GetNextDisplayInfoExByIndex(
  144448. + IN gctINT Index,
  144449. + IN HALNativeDisplayType Display,
  144450. + IN HALNativeWindowType Window,
  144451. + IN gctUINT DisplayInfoSize,
  144452. + OUT halDISPLAY_INFO * DisplayInfo
  144453. + );
  144454. +
  144455. +gceSTATUS
  144456. +gcoOS_GetDisplayVirtual(
  144457. + IN HALNativeDisplayType Display,
  144458. + OUT gctINT * Width,
  144459. + OUT gctINT * Height
  144460. + );
  144461. +
  144462. +gceSTATUS
  144463. +gcoOS_GetDisplayBackbuffer(
  144464. + IN HALNativeDisplayType Display,
  144465. + IN HALNativeWindowType Window,
  144466. + OUT gctPOINTER * context,
  144467. + OUT gcoSURF * surface,
  144468. + OUT gctUINT * Offset,
  144469. + OUT gctINT * X,
  144470. + OUT gctINT * Y
  144471. + );
  144472. +
  144473. +gceSTATUS
  144474. +gcoOS_SetDisplayVirtual(
  144475. + IN HALNativeDisplayType Display,
  144476. + IN HALNativeWindowType Window,
  144477. + IN gctUINT Offset,
  144478. + IN gctINT X,
  144479. + IN gctINT Y
  144480. + );
  144481. +
  144482. +gceSTATUS
  144483. +gcoOS_SetDisplayVirtualEx(
  144484. + IN HALNativeDisplayType Display,
  144485. + IN HALNativeWindowType Window,
  144486. + IN gctPOINTER Context,
  144487. + IN gcoSURF Surface,
  144488. + IN gctUINT Offset,
  144489. + IN gctINT X,
  144490. + IN gctINT Y
  144491. + );
  144492. +
  144493. +gceSTATUS
  144494. +gcoOS_SetSwapInterval(
  144495. + IN HALNativeDisplayType Display,
  144496. + IN gctINT Interval
  144497. +);
  144498. +
  144499. +gceSTATUS
  144500. +gcoOS_GetSwapInterval(
  144501. + IN HALNativeDisplayType Display,
  144502. + IN gctINT_PTR Min,
  144503. + IN gctINT_PTR Max
  144504. +);
  144505. +
  144506. +gceSTATUS
  144507. +gcoOS_DisplayBufferRegions(
  144508. + IN HALNativeDisplayType Display,
  144509. + IN HALNativeWindowType Window,
  144510. + IN gctINT NumRects,
  144511. + IN gctINT_PTR Rects
  144512. + );
  144513. +
  144514. +gceSTATUS
  144515. +gcoOS_DestroyDisplay(
  144516. + IN HALNativeDisplayType Display
  144517. + );
  144518. +
  144519. +gceSTATUS
  144520. +gcoOS_InitLocalDisplayInfo(
  144521. + IN HALNativeDisplayType Display,
  144522. + IN OUT gctPOINTER * localDisplay
  144523. + );
  144524. +
  144525. +gceSTATUS
  144526. +gcoOS_DeinitLocalDisplayInfo(
  144527. + IN HALNativeDisplayType Display,
  144528. + IN OUT gctPOINTER * localDisplay
  144529. + );
  144530. +
  144531. +gceSTATUS
  144532. +gcoOS_GetDisplayInfoEx2(
  144533. + IN HALNativeDisplayType Display,
  144534. + IN HALNativeWindowType Window,
  144535. + IN gctPOINTER localDisplay,
  144536. + IN gctUINT DisplayInfoSize,
  144537. + OUT halDISPLAY_INFO * DisplayInfo
  144538. + );
  144539. +
  144540. +gceSTATUS
  144541. +gcoOS_GetDisplayBackbufferEx(
  144542. + IN HALNativeDisplayType Display,
  144543. + IN HALNativeWindowType Window,
  144544. + IN gctPOINTER localDisplay,
  144545. + OUT gctPOINTER * context,
  144546. + OUT gcoSURF * surface,
  144547. + OUT gctUINT * Offset,
  144548. + OUT gctINT * X,
  144549. + OUT gctINT * Y
  144550. + );
  144551. +
  144552. +gceSTATUS
  144553. +gcoOS_IsValidDisplay(
  144554. + IN HALNativeDisplayType Display
  144555. + );
  144556. +
  144557. +gceSTATUS
  144558. +gcoOS_GetNativeVisualId(
  144559. + IN HALNativeDisplayType Display,
  144560. + OUT gctINT* nativeVisualId
  144561. + );
  144562. +
  144563. +gctBOOL
  144564. +gcoOS_SynchronousFlip(
  144565. + IN HALNativeDisplayType Display
  144566. + );
  144567. +
  144568. +/*******************************************************************************
  144569. +** Windows. ********************************************************************
  144570. +*/
  144571. +
  144572. +gceSTATUS
  144573. +gcoOS_CreateWindow(
  144574. + IN HALNativeDisplayType Display,
  144575. + IN gctINT X,
  144576. + IN gctINT Y,
  144577. + IN gctINT Width,
  144578. + IN gctINT Height,
  144579. + OUT HALNativeWindowType * Window
  144580. + );
  144581. +
  144582. +gceSTATUS
  144583. +gcoOS_GetWindowInfo(
  144584. + IN HALNativeDisplayType Display,
  144585. + IN HALNativeWindowType Window,
  144586. + OUT gctINT * X,
  144587. + OUT gctINT * Y,
  144588. + OUT gctINT * Width,
  144589. + OUT gctINT * Height,
  144590. + OUT gctINT * BitsPerPixel,
  144591. + OUT gctUINT * Offset
  144592. + );
  144593. +
  144594. +gceSTATUS
  144595. +gcoOS_DestroyWindow(
  144596. + IN HALNativeDisplayType Display,
  144597. + IN HALNativeWindowType Window
  144598. + );
  144599. +
  144600. +gceSTATUS
  144601. +gcoOS_DrawImage(
  144602. + IN HALNativeDisplayType Display,
  144603. + IN HALNativeWindowType Window,
  144604. + IN gctINT Left,
  144605. + IN gctINT Top,
  144606. + IN gctINT Right,
  144607. + IN gctINT Bottom,
  144608. + IN gctINT Width,
  144609. + IN gctINT Height,
  144610. + IN gctINT BitsPerPixel,
  144611. + IN gctPOINTER Bits
  144612. + );
  144613. +
  144614. +gceSTATUS
  144615. +gcoOS_GetImage(
  144616. + IN HALNativeWindowType Window,
  144617. + IN gctINT Left,
  144618. + IN gctINT Top,
  144619. + IN gctINT Right,
  144620. + IN gctINT Bottom,
  144621. + OUT gctINT * BitsPerPixel,
  144622. + OUT gctPOINTER * Bits
  144623. + );
  144624. +
  144625. +gceSTATUS
  144626. +gcoOS_GetWindowInfoEx(
  144627. + IN HALNativeDisplayType Display,
  144628. + IN HALNativeWindowType Window,
  144629. + OUT gctINT * X,
  144630. + OUT gctINT * Y,
  144631. + OUT gctINT * Width,
  144632. + OUT gctINT * Height,
  144633. + OUT gctINT * BitsPerPixel,
  144634. + OUT gctUINT * Offset,
  144635. + OUT gceSURF_FORMAT * Format
  144636. + );
  144637. +
  144638. +gceSTATUS
  144639. +gcoOS_DrawImageEx(
  144640. + IN HALNativeDisplayType Display,
  144641. + IN HALNativeWindowType Window,
  144642. + IN gctINT Left,
  144643. + IN gctINT Top,
  144644. + IN gctINT Right,
  144645. + IN gctINT Bottom,
  144646. + IN gctINT Width,
  144647. + IN gctINT Height,
  144648. + IN gctINT BitsPerPixel,
  144649. + IN gctPOINTER Bits,
  144650. + IN gceSURF_FORMAT Format
  144651. + );
  144652. +
  144653. +/*******************************************************************************
  144654. +** Pixmaps. ********************************************************************
  144655. +*/
  144656. +
  144657. +gceSTATUS
  144658. +gcoOS_CreatePixmap(
  144659. + IN HALNativeDisplayType Display,
  144660. + IN gctINT Width,
  144661. + IN gctINT Height,
  144662. + IN gctINT BitsPerPixel,
  144663. + OUT HALNativePixmapType * Pixmap
  144664. + );
  144665. +
  144666. +gceSTATUS
  144667. +gcoOS_GetPixmapInfo(
  144668. + IN HALNativeDisplayType Display,
  144669. + IN HALNativePixmapType Pixmap,
  144670. + OUT gctINT * Width,
  144671. + OUT gctINT * Height,
  144672. + OUT gctINT * BitsPerPixel,
  144673. + OUT gctINT * Stride,
  144674. + OUT gctPOINTER * Bits
  144675. + );
  144676. +
  144677. +gceSTATUS
  144678. +gcoOS_DrawPixmap(
  144679. + IN HALNativeDisplayType Display,
  144680. + IN HALNativePixmapType Pixmap,
  144681. + IN gctINT Left,
  144682. + IN gctINT Top,
  144683. + IN gctINT Right,
  144684. + IN gctINT Bottom,
  144685. + IN gctINT Width,
  144686. + IN gctINT Height,
  144687. + IN gctINT BitsPerPixel,
  144688. + IN gctPOINTER Bits
  144689. + );
  144690. +
  144691. +gceSTATUS
  144692. +gcoOS_DestroyPixmap(
  144693. + IN HALNativeDisplayType Display,
  144694. + IN HALNativePixmapType Pixmap
  144695. + );
  144696. +
  144697. +gceSTATUS
  144698. +gcoOS_GetPixmapInfoEx(
  144699. + IN HALNativeDisplayType Display,
  144700. + IN HALNativePixmapType Pixmap,
  144701. + OUT gctINT * Width,
  144702. + OUT gctINT * Height,
  144703. + OUT gctINT * BitsPerPixel,
  144704. + OUT gctINT * Stride,
  144705. + OUT gctPOINTER * Bits,
  144706. + OUT gceSURF_FORMAT * Format
  144707. + );
  144708. +
  144709. +gceSTATUS
  144710. +gcoOS_CopyPixmapBits(
  144711. + IN HALNativeDisplayType Display,
  144712. + IN HALNativePixmapType Pixmap,
  144713. + IN gctUINT DstWidth,
  144714. + IN gctUINT DstHeight,
  144715. + IN gctINT DstStride,
  144716. + IN gceSURF_FORMAT DstFormat,
  144717. + OUT gctPOINTER DstBits
  144718. + );
  144719. +
  144720. +/*******************************************************************************
  144721. +** OS relative. ****************************************************************
  144722. +*/
  144723. +gceSTATUS
  144724. +gcoOS_LoadEGLLibrary(
  144725. + OUT gctHANDLE * Handle
  144726. + );
  144727. +
  144728. +gceSTATUS
  144729. +gcoOS_FreeEGLLibrary(
  144730. + IN gctHANDLE Handle
  144731. + );
  144732. +
  144733. +gceSTATUS
  144734. +gcoOS_ShowWindow(
  144735. + IN HALNativeDisplayType Display,
  144736. + IN HALNativeWindowType Window
  144737. + );
  144738. +
  144739. +gceSTATUS
  144740. +gcoOS_HideWindow(
  144741. + IN HALNativeDisplayType Display,
  144742. + IN HALNativeWindowType Window
  144743. + );
  144744. +
  144745. +gceSTATUS
  144746. +gcoOS_SetWindowTitle(
  144747. + IN HALNativeDisplayType Display,
  144748. + IN HALNativeWindowType Window,
  144749. + IN gctCONST_STRING Title
  144750. + );
  144751. +
  144752. +gceSTATUS
  144753. +gcoOS_CapturePointer(
  144754. + IN HALNativeDisplayType Display,
  144755. + IN HALNativeWindowType Window
  144756. + );
  144757. +
  144758. +gceSTATUS
  144759. +gcoOS_GetEvent(
  144760. + IN HALNativeDisplayType Display,
  144761. + IN HALNativeWindowType Window,
  144762. + OUT halEvent * Event
  144763. + );
  144764. +
  144765. +gceSTATUS
  144766. +gcoOS_CreateClientBuffer(
  144767. + IN gctINT Width,
  144768. + IN gctINT Height,
  144769. + IN gctINT Format,
  144770. + IN gctINT Type,
  144771. + OUT gctPOINTER * ClientBuffer
  144772. + );
  144773. +
  144774. +gceSTATUS
  144775. +gcoOS_GetClientBufferInfo(
  144776. + IN gctPOINTER ClientBuffer,
  144777. + OUT gctINT * Width,
  144778. + OUT gctINT * Height,
  144779. + OUT gctINT * Stride,
  144780. + OUT gctPOINTER * Bits
  144781. + );
  144782. +
  144783. +gceSTATUS
  144784. +gcoOS_DestroyClientBuffer(
  144785. + IN gctPOINTER ClientBuffer
  144786. + );
  144787. +
  144788. +gceSTATUS
  144789. +gcoOS_DestroyContext(
  144790. + IN gctPOINTER Display,
  144791. + IN gctPOINTER Context
  144792. + );
  144793. +
  144794. +gceSTATUS
  144795. +gcoOS_CreateContext(
  144796. + IN gctPOINTER LocalDisplay,
  144797. + IN gctPOINTER Context
  144798. + );
  144799. +
  144800. +gceSTATUS
  144801. +gcoOS_MakeCurrent(
  144802. + IN gctPOINTER LocalDisplay,
  144803. + IN HALNativeWindowType DrawDrawable,
  144804. + IN HALNativeWindowType ReadDrawable,
  144805. + IN gctPOINTER Context,
  144806. + IN gcoSURF ResolveTarget
  144807. + );
  144808. +
  144809. +gceSTATUS
  144810. +gcoOS_CreateDrawable(
  144811. + IN gctPOINTER LocalDisplay,
  144812. + IN HALNativeWindowType Drawable
  144813. + );
  144814. +
  144815. +gceSTATUS
  144816. +gcoOS_DestroyDrawable(
  144817. + IN gctPOINTER LocalDisplay,
  144818. + IN HALNativeWindowType Drawable
  144819. + );
  144820. +gceSTATUS
  144821. +gcoOS_SwapBuffers(
  144822. + IN gctPOINTER LocalDisplay,
  144823. + IN HALNativeWindowType Drawable,
  144824. + IN gcoSURF RenderTarget,
  144825. + IN gcoSURF ResolveTarget,
  144826. + IN gctPOINTER ResolveBits,
  144827. + OUT gctUINT *Width,
  144828. + OUT gctUINT *Height
  144829. + );
  144830. +#ifdef __cplusplus
  144831. +}
  144832. +#endif
  144833. +
  144834. +#endif /* __gc_hal_eglplatform_h_ */
  144835. diff -Nur linux-3.14.17/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
  144836. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h 1970-01-01 01:00:00.000000000 +0100
  144837. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h 2014-09-11 18:06:03.118042434 +0200
  144838. @@ -0,0 +1,286 @@
  144839. +/****************************************************************************
  144840. +*
  144841. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  144842. +*
  144843. +* This program is free software; you can redistribute it and/or modify
  144844. +* it under the terms of the GNU General Public License as published by
  144845. +* the Free Software Foundation; either version 2 of the license, or
  144846. +* (at your option) any later version.
  144847. +*
  144848. +* This program is distributed in the hope that it will be useful,
  144849. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  144850. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  144851. +* GNU General Public License for more details.
  144852. +*
  144853. +* You should have received a copy of the GNU General Public License
  144854. +* along with this program; if not write to the Free Software
  144855. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  144856. +*
  144857. +*****************************************************************************/
  144858. +
  144859. +
  144860. +#ifndef __gc_hal_eglplatform_type_h_
  144861. +#define __gc_hal_eglplatform_type_h_
  144862. +
  144863. +#ifdef __cplusplus
  144864. +extern "C" {
  144865. +#endif
  144866. +
  144867. +/*******************************************************************************
  144868. +** Events. *********************************************************************
  144869. +*/
  144870. +
  144871. +typedef enum _halEventType
  144872. +{
  144873. + /* Keyboard event. */
  144874. + HAL_KEYBOARD,
  144875. +
  144876. + /* Mouse move event. */
  144877. + HAL_POINTER,
  144878. +
  144879. + /* Mouse button event. */
  144880. + HAL_BUTTON,
  144881. +
  144882. + /* Application close event. */
  144883. + HAL_CLOSE,
  144884. +
  144885. + /* Application window has been updated. */
  144886. + HAL_WINDOW_UPDATE
  144887. +}
  144888. +halEventType;
  144889. +
  144890. +/* Scancodes for keyboard. */
  144891. +typedef enum _halKeys
  144892. +{
  144893. + HAL_UNKNOWN = -1,
  144894. +
  144895. + HAL_BACKSPACE = 0x08,
  144896. + HAL_TAB,
  144897. + HAL_ENTER = 0x0D,
  144898. + HAL_ESCAPE = 0x1B,
  144899. +
  144900. + HAL_SPACE = 0x20,
  144901. + HAL_SINGLEQUOTE = 0x27,
  144902. + HAL_PAD_ASTERISK = 0x2A,
  144903. + HAL_COMMA = 0x2C,
  144904. + HAL_HYPHEN,
  144905. + HAL_PERIOD,
  144906. + HAL_SLASH,
  144907. + HAL_0,
  144908. + HAL_1,
  144909. + HAL_2,
  144910. + HAL_3,
  144911. + HAL_4,
  144912. + HAL_5,
  144913. + HAL_6,
  144914. + HAL_7,
  144915. + HAL_8,
  144916. + HAL_9,
  144917. + HAL_SEMICOLON = 0x3B,
  144918. + HAL_EQUAL = 0x3D,
  144919. + HAL_A = 0x41,
  144920. + HAL_B,
  144921. + HAL_C,
  144922. + HAL_D,
  144923. + HAL_E,
  144924. + HAL_F,
  144925. + HAL_G,
  144926. + HAL_H,
  144927. + HAL_I,
  144928. + HAL_J,
  144929. + HAL_K,
  144930. + HAL_L,
  144931. + HAL_M,
  144932. + HAL_N,
  144933. + HAL_O,
  144934. + HAL_P,
  144935. + HAL_Q,
  144936. + HAL_R,
  144937. + HAL_S,
  144938. + HAL_T,
  144939. + HAL_U,
  144940. + HAL_V,
  144941. + HAL_W,
  144942. + HAL_X,
  144943. + HAL_Y,
  144944. + HAL_Z,
  144945. + HAL_LBRACKET,
  144946. + HAL_BACKSLASH,
  144947. + HAL_RBRACKET,
  144948. + HAL_BACKQUOTE = 0x60,
  144949. +
  144950. + HAL_F1 = 0x80,
  144951. + HAL_F2,
  144952. + HAL_F3,
  144953. + HAL_F4,
  144954. + HAL_F5,
  144955. + HAL_F6,
  144956. + HAL_F7,
  144957. + HAL_F8,
  144958. + HAL_F9,
  144959. + HAL_F10,
  144960. + HAL_F11,
  144961. + HAL_F12,
  144962. +
  144963. + HAL_LCTRL,
  144964. + HAL_RCTRL,
  144965. + HAL_LSHIFT,
  144966. + HAL_RSHIFT,
  144967. + HAL_LALT,
  144968. + HAL_RALT,
  144969. + HAL_CAPSLOCK,
  144970. + HAL_NUMLOCK,
  144971. + HAL_SCROLLLOCK,
  144972. + HAL_PAD_0,
  144973. + HAL_PAD_1,
  144974. + HAL_PAD_2,
  144975. + HAL_PAD_3,
  144976. + HAL_PAD_4,
  144977. + HAL_PAD_5,
  144978. + HAL_PAD_6,
  144979. + HAL_PAD_7,
  144980. + HAL_PAD_8,
  144981. + HAL_PAD_9,
  144982. + HAL_PAD_HYPHEN,
  144983. + HAL_PAD_PLUS,
  144984. + HAL_PAD_SLASH,
  144985. + HAL_PAD_PERIOD,
  144986. + HAL_PAD_ENTER,
  144987. + HAL_SYSRQ,
  144988. + HAL_PRNTSCRN,
  144989. + HAL_BREAK,
  144990. + HAL_UP,
  144991. + HAL_LEFT,
  144992. + HAL_RIGHT,
  144993. + HAL_DOWN,
  144994. + HAL_HOME,
  144995. + HAL_END,
  144996. + HAL_PGUP,
  144997. + HAL_PGDN,
  144998. + HAL_INSERT,
  144999. + HAL_DELETE,
  145000. + HAL_LWINDOW,
  145001. + HAL_RWINDOW,
  145002. + HAL_MENU,
  145003. + HAL_POWER,
  145004. + HAL_SLEEP,
  145005. + HAL_WAKE
  145006. +}
  145007. +halKeys;
  145008. +
  145009. +/* Structure that defined keyboard mapping. */
  145010. +typedef struct _halKeyMap
  145011. +{
  145012. + /* Normal key. */
  145013. + halKeys normal;
  145014. +
  145015. + /* Extended key. */
  145016. + halKeys extended;
  145017. +}
  145018. +halKeyMap;
  145019. +
  145020. +/* Event structure. */
  145021. +typedef struct _halEvent
  145022. +{
  145023. + /* Event type. */
  145024. + halEventType type;
  145025. +
  145026. + /* Event data union. */
  145027. + union _halEventData
  145028. + {
  145029. + /* Event data for keyboard. */
  145030. + struct _halKeyboard
  145031. + {
  145032. + /* Scancode. */
  145033. + halKeys scancode;
  145034. +
  145035. + /* ASCII characte of the key pressed. */
  145036. + char key;
  145037. +
  145038. + /* Flag whether the key was pressed (1) or released (0). */
  145039. + char pressed;
  145040. + }
  145041. + keyboard;
  145042. +
  145043. + /* Event data for pointer. */
  145044. + struct _halPointer
  145045. + {
  145046. + /* Current pointer coordinate. */
  145047. + int x;
  145048. + int y;
  145049. + }
  145050. + pointer;
  145051. +
  145052. + /* Event data for mouse buttons. */
  145053. + struct _halButton
  145054. + {
  145055. + /* Left button state. */
  145056. + int left;
  145057. +
  145058. + /* Middle button state. */
  145059. + int middle;
  145060. +
  145061. + /* Right button state. */
  145062. + int right;
  145063. +
  145064. + /* Current pointer coordinate. */
  145065. + int x;
  145066. + int y;
  145067. + }
  145068. + button;
  145069. + }
  145070. + data;
  145071. +}
  145072. +halEvent;
  145073. +
  145074. +/* VFK_DISPLAY_INFO structure defining information returned by
  145075. + vdkGetDisplayInfoEx. */
  145076. +typedef struct _halDISPLAY_INFO
  145077. +{
  145078. + /* The size of the display in pixels. */
  145079. + int width;
  145080. + int height;
  145081. +
  145082. + /* The stride of the dispay. -1 is returned if the stride is not known
  145083. + ** for the specified display.*/
  145084. + int stride;
  145085. +
  145086. + /* The color depth of the display in bits per pixel. */
  145087. + int bitsPerPixel;
  145088. +
  145089. + /* The logical pointer to the display memory buffer. NULL is returned
  145090. + ** if the pointer is not known for the specified display. */
  145091. + void * logical;
  145092. +
  145093. + /* The physical address of the display memory buffer. ~0 is returned
  145094. + ** if the address is not known for the specified display. */
  145095. + unsigned long physical;
  145096. +
  145097. + int wrapFB; /* true if compositor, false otherwise. */
  145098. +
  145099. +#ifndef __QNXNTO__
  145100. + /* 355_FB_MULTI_BUFFER */
  145101. + int multiBuffer;
  145102. + int backBufferY;
  145103. +#endif
  145104. +
  145105. + /* The color info of the display. */
  145106. + unsigned int alphaLength;
  145107. + unsigned int alphaOffset;
  145108. + unsigned int redLength;
  145109. + unsigned int redOffset;
  145110. + unsigned int greenLength;
  145111. + unsigned int greenOffset;
  145112. + unsigned int blueLength;
  145113. + unsigned int blueOffset;
  145114. +
  145115. + /* Display flip support. */
  145116. + int flip;
  145117. +}
  145118. +halDISPLAY_INFO;
  145119. +
  145120. +#ifdef __cplusplus
  145121. +}
  145122. +#endif
  145123. +
  145124. +#endif /* __gc_hal_eglplatform_type_h_ */
  145125. diff -Nur linux-3.14.17/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
  145126. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h 1970-01-01 01:00:00.000000000 +0100
  145127. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h 2014-09-11 18:06:03.118042434 +0200
  145128. @@ -0,0 +1,2053 @@
  145129. +/****************************************************************************
  145130. +*
  145131. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  145132. +*
  145133. +* This program is free software; you can redistribute it and/or modify
  145134. +* it under the terms of the GNU General Public License as published by
  145135. +* the Free Software Foundation; either version 2 of the license, or
  145136. +* (at your option) any later version.
  145137. +*
  145138. +* This program is distributed in the hope that it will be useful,
  145139. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  145140. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  145141. +* GNU General Public License for more details.
  145142. +*
  145143. +* You should have received a copy of the GNU General Public License
  145144. +* along with this program; if not write to the Free Software
  145145. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  145146. +*
  145147. +*****************************************************************************/
  145148. +
  145149. +
  145150. +#ifndef __gc_hal_engine_h_
  145151. +#define __gc_hal_engine_h_
  145152. +
  145153. +#ifndef VIVANTE_NO_3D
  145154. +#include "gc_hal_types.h"
  145155. +#include "gc_hal_enum.h"
  145156. +
  145157. +#if gcdENABLE_VG
  145158. +#include "gc_hal_engine_vg.h"
  145159. +#endif
  145160. +
  145161. +#ifdef __cplusplus
  145162. +extern "C" {
  145163. +#endif
  145164. +
  145165. +/******************************************************************************\
  145166. +****************************** Object Declarations *****************************
  145167. +\******************************************************************************/
  145168. +
  145169. +typedef struct _gcoSTREAM * gcoSTREAM;
  145170. +typedef struct _gcoVERTEX * gcoVERTEX;
  145171. +typedef struct _gcoTEXTURE * gcoTEXTURE;
  145172. +typedef struct _gcoINDEX * gcoINDEX;
  145173. +typedef struct _gcsVERTEX_ATTRIBUTES * gcsVERTEX_ATTRIBUTES_PTR;
  145174. +typedef struct _gcoVERTEXARRAY * gcoVERTEXARRAY;
  145175. +
  145176. +#define gcdATTRIBUTE_COUNT 16
  145177. +
  145178. +/******************************************************************************\
  145179. +********************************* Enumerations *********************************
  145180. +\******************************************************************************/
  145181. +
  145182. +/* Shading format. */
  145183. +typedef enum _gceSHADING
  145184. +{
  145185. + gcvSHADING_SMOOTH,
  145186. + gcvSHADING_FLAT_D3D,
  145187. + gcvSHADING_FLAT_OPENGL,
  145188. +}
  145189. +gceSHADING;
  145190. +
  145191. +/* Culling modes. */
  145192. +typedef enum _gceCULL
  145193. +{
  145194. + gcvCULL_NONE,
  145195. + gcvCULL_CCW,
  145196. + gcvCULL_CW,
  145197. +}
  145198. +gceCULL;
  145199. +
  145200. +/* Fill modes. */
  145201. +typedef enum _gceFILL
  145202. +{
  145203. + gcvFILL_POINT,
  145204. + gcvFILL_WIRE_FRAME,
  145205. + gcvFILL_SOLID,
  145206. +}
  145207. +gceFILL;
  145208. +
  145209. +/* Compare modes. */
  145210. +typedef enum _gceCOMPARE
  145211. +{
  145212. + gcvCOMPARE_NEVER,
  145213. + gcvCOMPARE_NOT_EQUAL,
  145214. + gcvCOMPARE_LESS,
  145215. + gcvCOMPARE_LESS_OR_EQUAL,
  145216. + gcvCOMPARE_EQUAL,
  145217. + gcvCOMPARE_GREATER,
  145218. + gcvCOMPARE_GREATER_OR_EQUAL,
  145219. + gcvCOMPARE_ALWAYS,
  145220. + gcvCOMPARE_INVALID = -1
  145221. +}
  145222. +gceCOMPARE;
  145223. +
  145224. +/* Stencil modes. */
  145225. +typedef enum _gceSTENCIL_MODE
  145226. +{
  145227. + gcvSTENCIL_NONE,
  145228. + gcvSTENCIL_SINGLE_SIDED,
  145229. + gcvSTENCIL_DOUBLE_SIDED,
  145230. +}
  145231. +gceSTENCIL_MODE;
  145232. +
  145233. +/* Stencil operations. */
  145234. +typedef enum _gceSTENCIL_OPERATION
  145235. +{
  145236. + gcvSTENCIL_KEEP,
  145237. + gcvSTENCIL_REPLACE,
  145238. + gcvSTENCIL_ZERO,
  145239. + gcvSTENCIL_INVERT,
  145240. + gcvSTENCIL_INCREMENT,
  145241. + gcvSTENCIL_DECREMENT,
  145242. + gcvSTENCIL_INCREMENT_SATURATE,
  145243. + gcvSTENCIL_DECREMENT_SATURATE,
  145244. + gcvSTENCIL_OPERATION_INVALID = -1
  145245. +}
  145246. +gceSTENCIL_OPERATION;
  145247. +
  145248. +/* Stencil selection. */
  145249. +typedef enum _gceSTENCIL_WHERE
  145250. +{
  145251. + gcvSTENCIL_FRONT,
  145252. + gcvSTENCIL_BACK,
  145253. +}
  145254. +gceSTENCIL_WHERE;
  145255. +
  145256. +/* Texture addressing selection. */
  145257. +typedef enum _gceTEXTURE_WHICH
  145258. +{
  145259. + gcvTEXTURE_S,
  145260. + gcvTEXTURE_T,
  145261. + gcvTEXTURE_R,
  145262. +}
  145263. +gceTEXTURE_WHICH;
  145264. +
  145265. +/* Texture addressing modes. */
  145266. +typedef enum _gceTEXTURE_ADDRESSING
  145267. +{
  145268. + gcvTEXTURE_WRAP,
  145269. + gcvTEXTURE_CLAMP,
  145270. + gcvTEXTURE_BORDER,
  145271. + gcvTEXTURE_MIRROR,
  145272. + gcvTEXTURE_MIRROR_ONCE,
  145273. +}
  145274. +gceTEXTURE_ADDRESSING;
  145275. +
  145276. +/* Texture filters. */
  145277. +typedef enum _gceTEXTURE_FILTER
  145278. +{
  145279. + gcvTEXTURE_NONE,
  145280. + gcvTEXTURE_POINT,
  145281. + gcvTEXTURE_LINEAR,
  145282. + gcvTEXTURE_ANISOTROPIC,
  145283. +}
  145284. +gceTEXTURE_FILTER;
  145285. +
  145286. +/* Primitive types. */
  145287. +typedef enum _gcePRIMITIVE
  145288. +{
  145289. + gcvPRIMITIVE_POINT_LIST,
  145290. + gcvPRIMITIVE_LINE_LIST,
  145291. + gcvPRIMITIVE_LINE_STRIP,
  145292. + gcvPRIMITIVE_LINE_LOOP,
  145293. + gcvPRIMITIVE_TRIANGLE_LIST,
  145294. + gcvPRIMITIVE_TRIANGLE_STRIP,
  145295. + gcvPRIMITIVE_TRIANGLE_FAN,
  145296. + gcvPRIMITIVE_RECTANGLE,
  145297. +}
  145298. +gcePRIMITIVE;
  145299. +
  145300. +/* Index types. */
  145301. +typedef enum _gceINDEX_TYPE
  145302. +{
  145303. + gcvINDEX_8,
  145304. + gcvINDEX_16,
  145305. + gcvINDEX_32,
  145306. +}
  145307. +gceINDEX_TYPE;
  145308. +
  145309. +/******************************************************************************\
  145310. +********************************* gcoHAL Object *********************************
  145311. +\******************************************************************************/
  145312. +
  145313. +/* Query the target capabilities. */
  145314. +gceSTATUS
  145315. +gcoHAL_QueryTargetCaps(
  145316. + IN gcoHAL Hal,
  145317. + OUT gctUINT * MaxWidth,
  145318. + OUT gctUINT * MaxHeight,
  145319. + OUT gctUINT * MultiTargetCount,
  145320. + OUT gctUINT * MaxSamples
  145321. + );
  145322. +
  145323. +gceSTATUS
  145324. +gcoHAL_SetDepthOnly(
  145325. + IN gcoHAL Hal,
  145326. + IN gctBOOL Enable
  145327. + );
  145328. +
  145329. +gceSTATUS
  145330. +gcoHAL_QueryShaderCaps(
  145331. + IN gcoHAL Hal,
  145332. + OUT gctUINT * VertexUniforms,
  145333. + OUT gctUINT * FragmentUniforms,
  145334. + OUT gctUINT * Varyings
  145335. + );
  145336. +
  145337. +gceSTATUS
  145338. +gcoHAL_QueryTextureCaps(
  145339. + IN gcoHAL Hal,
  145340. + OUT gctUINT * MaxWidth,
  145341. + OUT gctUINT * MaxHeight,
  145342. + OUT gctUINT * MaxDepth,
  145343. + OUT gctBOOL * Cubic,
  145344. + OUT gctBOOL * NonPowerOfTwo,
  145345. + OUT gctUINT * VertexSamplers,
  145346. + OUT gctUINT * PixelSamplers
  145347. + );
  145348. +
  145349. +gceSTATUS
  145350. +gcoHAL_QueryTextureMaxAniso(
  145351. + IN gcoHAL Hal,
  145352. + OUT gctUINT * MaxAnisoValue
  145353. + );
  145354. +
  145355. +gceSTATUS
  145356. +gcoHAL_QueryStreamCaps(
  145357. + IN gcoHAL Hal,
  145358. + OUT gctUINT32 * MaxAttributes,
  145359. + OUT gctUINT32 * MaxStreamSize,
  145360. + OUT gctUINT32 * NumberOfStreams,
  145361. + OUT gctUINT32 * Alignment
  145362. + );
  145363. +
  145364. +/******************************************************************************\
  145365. +********************************* gcoSURF Object ********************************
  145366. +\******************************************************************************/
  145367. +
  145368. +/*----------------------------------------------------------------------------*/
  145369. +/*--------------------------------- gcoSURF 3D --------------------------------*/
  145370. +
  145371. +/* Copy surface. */
  145372. +gceSTATUS
  145373. +gcoSURF_Copy(
  145374. + IN gcoSURF Surface,
  145375. + IN gcoSURF Source
  145376. + );
  145377. +
  145378. +/* Clear surface. */
  145379. +gceSTATUS
  145380. +gcoSURF_Clear(
  145381. + IN gcoSURF Surface,
  145382. + IN gctUINT Flags
  145383. + );
  145384. +
  145385. +/* Set number of samples for a gcoSURF object. */
  145386. +gceSTATUS
  145387. +gcoSURF_SetSamples(
  145388. + IN gcoSURF Surface,
  145389. + IN gctUINT Samples
  145390. + );
  145391. +
  145392. +/* Get the number of samples per pixel. */
  145393. +gceSTATUS
  145394. +gcoSURF_GetSamples(
  145395. + IN gcoSURF Surface,
  145396. + OUT gctUINT_PTR Samples
  145397. + );
  145398. +
  145399. +/* Clear rectangular surface. */
  145400. +gceSTATUS
  145401. +gcoSURF_ClearRect(
  145402. + IN gcoSURF Surface,
  145403. + IN gctINT Left,
  145404. + IN gctINT Top,
  145405. + IN gctINT Right,
  145406. + IN gctINT Bottom,
  145407. + IN gctUINT Flags
  145408. + );
  145409. +
  145410. +/* TO BE REMOVED */
  145411. + gceSTATUS
  145412. + depr_gcoSURF_Resolve(
  145413. + IN gcoSURF SrcSurface,
  145414. + IN gcoSURF DestSurface,
  145415. + IN gctUINT32 DestAddress,
  145416. + IN gctPOINTER DestBits,
  145417. + IN gctINT DestStride,
  145418. + IN gceSURF_TYPE DestType,
  145419. + IN gceSURF_FORMAT DestFormat,
  145420. + IN gctUINT DestWidth,
  145421. + IN gctUINT DestHeight
  145422. + );
  145423. +
  145424. + gceSTATUS
  145425. + depr_gcoSURF_ResolveRect(
  145426. + IN gcoSURF SrcSurface,
  145427. + IN gcoSURF DestSurface,
  145428. + IN gctUINT32 DestAddress,
  145429. + IN gctPOINTER DestBits,
  145430. + IN gctINT DestStride,
  145431. + IN gceSURF_TYPE DestType,
  145432. + IN gceSURF_FORMAT DestFormat,
  145433. + IN gctUINT DestWidth,
  145434. + IN gctUINT DestHeight,
  145435. + IN gcsPOINT_PTR SrcOrigin,
  145436. + IN gcsPOINT_PTR DestOrigin,
  145437. + IN gcsPOINT_PTR RectSize
  145438. + );
  145439. +
  145440. +/* Resample surface. */
  145441. +gceSTATUS
  145442. +gcoSURF_Resample(
  145443. + IN gcoSURF SrcSurface,
  145444. + IN gcoSURF DestSurface
  145445. + );
  145446. +
  145447. +/* Resolve surface. */
  145448. +gceSTATUS
  145449. +gcoSURF_Resolve(
  145450. + IN gcoSURF SrcSurface,
  145451. + IN gcoSURF DestSurface
  145452. + );
  145453. +
  145454. +gceSTATUS
  145455. +gcoSURF_IsHWResolveable(
  145456. + IN gcoSURF SrcSurface,
  145457. + IN gcoSURF DestSurface,
  145458. + IN gcsPOINT_PTR SrcOrigin,
  145459. + IN gcsPOINT_PTR DestOrigin,
  145460. + IN gcsPOINT_PTR RectSize
  145461. + );
  145462. +
  145463. +/* Resolve rectangular area of a surface. */
  145464. +gceSTATUS
  145465. +gcoSURF_ResolveRect(
  145466. + IN gcoSURF SrcSurface,
  145467. + IN gcoSURF DestSurface,
  145468. + IN gcsPOINT_PTR SrcOrigin,
  145469. + IN gcsPOINT_PTR DestOrigin,
  145470. + IN gcsPOINT_PTR RectSize
  145471. + );
  145472. +
  145473. +/* Set surface resolvability. */
  145474. +gceSTATUS
  145475. +gcoSURF_SetResolvability(
  145476. + IN gcoSURF Surface,
  145477. + IN gctBOOL Resolvable
  145478. + );
  145479. +
  145480. +gceSTATUS
  145481. +gcoSURF_IsRenderable(
  145482. + IN gcoSURF Surface
  145483. + );
  145484. +
  145485. +gceSTATUS
  145486. +gcoSURF_IsFormatRenderableAsRT(
  145487. + IN gcoSURF Surface
  145488. + );
  145489. +
  145490. +#if gcdSYNC
  145491. +gceSTATUS
  145492. +gcoSURF_GetFence(
  145493. + IN gcoSURF Surface
  145494. + );
  145495. +gceSTATUS
  145496. +gcoSURF_WaitFence(
  145497. + IN gcoSURF Surface
  145498. + );
  145499. +
  145500. +gceSTATUS
  145501. +gcoSTREAM_GetFence(
  145502. + IN gcoSTREAM stream
  145503. + );
  145504. +
  145505. +gceSTATUS
  145506. +gcoSTREAM_WaitFence(
  145507. + IN gcoSTREAM stream
  145508. + );
  145509. +
  145510. +gceSTATUS
  145511. +gcoINDEX_GetFence(
  145512. + IN gcoINDEX index
  145513. + );
  145514. +
  145515. +gceSTATUS
  145516. +gcoINDEX_WaitFence(
  145517. + IN gcoINDEX index
  145518. + );
  145519. +#endif
  145520. +
  145521. +/******************************************************************************\
  145522. +******************************** gcoINDEX Object *******************************
  145523. +\******************************************************************************/
  145524. +
  145525. +/* Construct a new gcoINDEX object. */
  145526. +gceSTATUS
  145527. +gcoINDEX_Construct(
  145528. + IN gcoHAL Hal,
  145529. + OUT gcoINDEX * Index
  145530. + );
  145531. +
  145532. +/* Destroy a gcoINDEX object. */
  145533. +gceSTATUS
  145534. +gcoINDEX_Destroy(
  145535. + IN gcoINDEX Index
  145536. + );
  145537. +
  145538. +/* Lock index in memory. */
  145539. +gceSTATUS
  145540. +gcoINDEX_Lock(
  145541. + IN gcoINDEX Index,
  145542. + OUT gctUINT32 * Address,
  145543. + OUT gctPOINTER * Memory
  145544. + );
  145545. +
  145546. +/* Unlock index that was previously locked with gcoINDEX_Lock. */
  145547. +gceSTATUS
  145548. +gcoINDEX_Unlock(
  145549. + IN gcoINDEX Index
  145550. + );
  145551. +
  145552. +/* Upload index data into the memory. */
  145553. +gceSTATUS
  145554. +gcoINDEX_Load(
  145555. + IN gcoINDEX Index,
  145556. + IN gceINDEX_TYPE IndexType,
  145557. + IN gctUINT32 IndexCount,
  145558. + IN gctPOINTER IndexBuffer
  145559. + );
  145560. +
  145561. +/* Bind an index object to the hardware. */
  145562. +gceSTATUS
  145563. +gcoINDEX_Bind(
  145564. + IN gcoINDEX Index,
  145565. + IN gceINDEX_TYPE Type
  145566. + );
  145567. +
  145568. +/* Bind an index object to the hardware. */
  145569. +gceSTATUS
  145570. +gcoINDEX_BindOffset(
  145571. + IN gcoINDEX Index,
  145572. + IN gceINDEX_TYPE Type,
  145573. + IN gctUINT32 Offset
  145574. + );
  145575. +
  145576. +/* Free existing index buffer. */
  145577. +gceSTATUS
  145578. +gcoINDEX_Free(
  145579. + IN gcoINDEX Index
  145580. + );
  145581. +
  145582. +/* Upload data into an index buffer. */
  145583. +gceSTATUS
  145584. +gcoINDEX_Upload(
  145585. + IN gcoINDEX Index,
  145586. + IN gctCONST_POINTER Buffer,
  145587. + IN gctSIZE_T Bytes
  145588. + );
  145589. +
  145590. +/* Upload data into an index buffer starting at an offset. */
  145591. +gceSTATUS
  145592. +gcoINDEX_UploadOffset(
  145593. + IN gcoINDEX Index,
  145594. + IN gctUINT32 Offset,
  145595. + IN gctCONST_POINTER Buffer,
  145596. + IN gctSIZE_T Bytes
  145597. + );
  145598. +
  145599. +/*Merge index2 to index1 from 0, index2 must subset of inex1*/
  145600. +gceSTATUS
  145601. +gcoINDEX_Merge(
  145602. + IN gcoINDEX Index1,
  145603. + IN gcoINDEX Index2
  145604. + );
  145605. +
  145606. +/*check if index buffer is enough for this draw*/
  145607. +gctBOOL
  145608. +gcoINDEX_CheckRange(
  145609. + IN gcoINDEX Index,
  145610. + IN gceINDEX_TYPE Type,
  145611. + IN gctINT Count,
  145612. + IN gctUINT32 Indices
  145613. + );
  145614. +
  145615. +/* Query the index capabilities. */
  145616. +gceSTATUS
  145617. +gcoINDEX_QueryCaps(
  145618. + OUT gctBOOL * Index8,
  145619. + OUT gctBOOL * Index16,
  145620. + OUT gctBOOL * Index32,
  145621. + OUT gctUINT * MaxIndex
  145622. + );
  145623. +
  145624. +/* Determine the index range in the current index buffer. */
  145625. +gceSTATUS
  145626. +gcoINDEX_GetIndexRange(
  145627. + IN gcoINDEX Index,
  145628. + IN gceINDEX_TYPE Type,
  145629. + IN gctUINT32 Offset,
  145630. + IN gctUINT32 Count,
  145631. + OUT gctUINT32 * MinimumIndex,
  145632. + OUT gctUINT32 * MaximumIndex
  145633. + );
  145634. +
  145635. +/* Dynamic buffer management. */
  145636. +gceSTATUS
  145637. +gcoINDEX_SetDynamic(
  145638. + IN gcoINDEX Index,
  145639. + IN gctSIZE_T Bytes,
  145640. + IN gctUINT Buffers
  145641. + );
  145642. +
  145643. +gceSTATUS
  145644. +gcoINDEX_UploadDynamic(
  145645. + IN gcoINDEX Index,
  145646. + IN gctCONST_POINTER Data,
  145647. + IN gctSIZE_T Bytes
  145648. + );
  145649. +
  145650. +/******************************************************************************\
  145651. +********************************** gco3D Object *********************************
  145652. +\******************************************************************************/
  145653. +
  145654. +/* Clear flags. */
  145655. +typedef enum _gceCLEAR
  145656. +{
  145657. + gcvCLEAR_COLOR = 0x1,
  145658. + gcvCLEAR_DEPTH = 0x2,
  145659. + gcvCLEAR_STENCIL = 0x4,
  145660. + gcvCLEAR_HZ = 0x8,
  145661. + gcvCLEAR_HAS_VAA = 0x10,
  145662. +}
  145663. +gceCLEAR;
  145664. +
  145665. +/* Blending targets. */
  145666. +typedef enum _gceBLEND_UNIT
  145667. +{
  145668. + gcvBLEND_SOURCE,
  145669. + gcvBLEND_TARGET,
  145670. +}
  145671. +gceBLEND_UNIT;
  145672. +
  145673. +/* Construct a new gco3D object. */
  145674. +gceSTATUS
  145675. +gco3D_Construct(
  145676. + IN gcoHAL Hal,
  145677. + OUT gco3D * Engine
  145678. + );
  145679. +
  145680. +/* Destroy an gco3D object. */
  145681. +gceSTATUS
  145682. +gco3D_Destroy(
  145683. + IN gco3D Engine
  145684. + );
  145685. +
  145686. +/* Set 3D API type. */
  145687. +gceSTATUS
  145688. +gco3D_SetAPI(
  145689. + IN gco3D Engine,
  145690. + IN gceAPI ApiType
  145691. + );
  145692. +
  145693. +/* Set render target. */
  145694. +gceSTATUS
  145695. +gco3D_SetTarget(
  145696. + IN gco3D Engine,
  145697. + IN gcoSURF Surface
  145698. + );
  145699. +
  145700. +/* Unset render target. */
  145701. +gceSTATUS
  145702. +gco3D_UnsetTarget(
  145703. + IN gco3D Engine,
  145704. + IN gcoSURF Surface
  145705. + );
  145706. +
  145707. +/* Set depth buffer. */
  145708. +gceSTATUS
  145709. +gco3D_SetDepth(
  145710. + IN gco3D Engine,
  145711. + IN gcoSURF Surface
  145712. + );
  145713. +
  145714. +/* Unset depth buffer. */
  145715. +gceSTATUS
  145716. +gco3D_UnsetDepth(
  145717. + IN gco3D Engine,
  145718. + IN gcoSURF Surface
  145719. + );
  145720. +
  145721. +/* Set viewport. */
  145722. +gceSTATUS
  145723. +gco3D_SetViewport(
  145724. + IN gco3D Engine,
  145725. + IN gctINT32 Left,
  145726. + IN gctINT32 Top,
  145727. + IN gctINT32 Right,
  145728. + IN gctINT32 Bottom
  145729. + );
  145730. +
  145731. +/* Set scissors. */
  145732. +gceSTATUS
  145733. +gco3D_SetScissors(
  145734. + IN gco3D Engine,
  145735. + IN gctINT32 Left,
  145736. + IN gctINT32 Top,
  145737. + IN gctINT32 Right,
  145738. + IN gctINT32 Bottom
  145739. + );
  145740. +
  145741. +/* Set clear color. */
  145742. +gceSTATUS
  145743. +gco3D_SetClearColor(
  145744. + IN gco3D Engine,
  145745. + IN gctUINT8 Red,
  145746. + IN gctUINT8 Green,
  145747. + IN gctUINT8 Blue,
  145748. + IN gctUINT8 Alpha
  145749. + );
  145750. +
  145751. +/* Set fixed point clear color. */
  145752. +gceSTATUS
  145753. +gco3D_SetClearColorX(
  145754. + IN gco3D Engine,
  145755. + IN gctFIXED_POINT Red,
  145756. + IN gctFIXED_POINT Green,
  145757. + IN gctFIXED_POINT Blue,
  145758. + IN gctFIXED_POINT Alpha
  145759. + );
  145760. +
  145761. +/* Set floating point clear color. */
  145762. +gceSTATUS
  145763. +gco3D_SetClearColorF(
  145764. + IN gco3D Engine,
  145765. + IN gctFLOAT Red,
  145766. + IN gctFLOAT Green,
  145767. + IN gctFLOAT Blue,
  145768. + IN gctFLOAT Alpha
  145769. + );
  145770. +
  145771. +/* Set fixed point clear depth. */
  145772. +gceSTATUS
  145773. +gco3D_SetClearDepthX(
  145774. + IN gco3D Engine,
  145775. + IN gctFIXED_POINT Depth
  145776. + );
  145777. +
  145778. +/* Set floating point clear depth. */
  145779. +gceSTATUS
  145780. +gco3D_SetClearDepthF(
  145781. + IN gco3D Engine,
  145782. + IN gctFLOAT Depth
  145783. + );
  145784. +
  145785. +/* Set clear stencil. */
  145786. +gceSTATUS
  145787. +gco3D_SetClearStencil(
  145788. + IN gco3D Engine,
  145789. + IN gctUINT32 Stencil
  145790. + );
  145791. +
  145792. +/* Clear a Rect sub-surface. */
  145793. +gceSTATUS
  145794. +gco3D_ClearRect(
  145795. + IN gco3D Engine,
  145796. + IN gctUINT32 Address,
  145797. + IN gctPOINTER Memory,
  145798. + IN gctUINT32 Stride,
  145799. + IN gceSURF_FORMAT Format,
  145800. + IN gctINT32 Left,
  145801. + IN gctINT32 Top,
  145802. + IN gctINT32 Right,
  145803. + IN gctINT32 Bottom,
  145804. + IN gctUINT32 Width,
  145805. + IN gctUINT32 Height,
  145806. + IN gctUINT32 Flags
  145807. + );
  145808. +
  145809. +/* Clear surface. */
  145810. +gceSTATUS
  145811. +gco3D_Clear(
  145812. + IN gco3D Engine,
  145813. + IN gctUINT32 Address,
  145814. + IN gctUINT32 Stride,
  145815. + IN gceSURF_FORMAT Format,
  145816. + IN gctUINT32 Width,
  145817. + IN gctUINT32 Height,
  145818. + IN gctUINT32 Flags
  145819. + );
  145820. +
  145821. +
  145822. +/* Clear tile status. */
  145823. +gceSTATUS
  145824. +gco3D_ClearTileStatus(
  145825. + IN gco3D Engine,
  145826. + IN gcsSURF_INFO_PTR Surface,
  145827. + IN gctUINT32 TileStatusAddress,
  145828. + IN gctUINT32 Flags
  145829. + );
  145830. +
  145831. +/* Set shading mode. */
  145832. +gceSTATUS
  145833. +gco3D_SetShading(
  145834. + IN gco3D Engine,
  145835. + IN gceSHADING Shading
  145836. + );
  145837. +
  145838. +/* Set blending mode. */
  145839. +gceSTATUS
  145840. +gco3D_EnableBlending(
  145841. + IN gco3D Engine,
  145842. + IN gctBOOL Enable
  145843. + );
  145844. +
  145845. +/* Set blending function. */
  145846. +gceSTATUS
  145847. +gco3D_SetBlendFunction(
  145848. + IN gco3D Engine,
  145849. + IN gceBLEND_UNIT Unit,
  145850. + IN gceBLEND_FUNCTION FunctionRGB,
  145851. + IN gceBLEND_FUNCTION FunctionAlpha
  145852. + );
  145853. +
  145854. +/* Set blending mode. */
  145855. +gceSTATUS
  145856. +gco3D_SetBlendMode(
  145857. + IN gco3D Engine,
  145858. + IN gceBLEND_MODE ModeRGB,
  145859. + IN gceBLEND_MODE ModeAlpha
  145860. + );
  145861. +
  145862. +/* Set blending color. */
  145863. +gceSTATUS
  145864. +gco3D_SetBlendColor(
  145865. + IN gco3D Engine,
  145866. + IN gctUINT Red,
  145867. + IN gctUINT Green,
  145868. + IN gctUINT Blue,
  145869. + IN gctUINT Alpha
  145870. + );
  145871. +
  145872. +/* Set fixed point blending color. */
  145873. +gceSTATUS
  145874. +gco3D_SetBlendColorX(
  145875. + IN gco3D Engine,
  145876. + IN gctFIXED_POINT Red,
  145877. + IN gctFIXED_POINT Green,
  145878. + IN gctFIXED_POINT Blue,
  145879. + IN gctFIXED_POINT Alpha
  145880. + );
  145881. +
  145882. +/* Set floating point blending color. */
  145883. +gceSTATUS
  145884. +gco3D_SetBlendColorF(
  145885. + IN gco3D Engine,
  145886. + IN gctFLOAT Red,
  145887. + IN gctFLOAT Green,
  145888. + IN gctFLOAT Blue,
  145889. + IN gctFLOAT Alpha
  145890. + );
  145891. +
  145892. +/* Set culling mode. */
  145893. +gceSTATUS
  145894. +gco3D_SetCulling(
  145895. + IN gco3D Engine,
  145896. + IN gceCULL Mode
  145897. + );
  145898. +
  145899. +/* Enable point size */
  145900. +gceSTATUS
  145901. +gco3D_SetPointSizeEnable(
  145902. + IN gco3D Engine,
  145903. + IN gctBOOL Enable
  145904. + );
  145905. +
  145906. +/* Set point sprite */
  145907. +gceSTATUS
  145908. +gco3D_SetPointSprite(
  145909. + IN gco3D Engine,
  145910. + IN gctBOOL Enable
  145911. + );
  145912. +
  145913. +/* Set fill mode. */
  145914. +gceSTATUS
  145915. +gco3D_SetFill(
  145916. + IN gco3D Engine,
  145917. + IN gceFILL Mode
  145918. + );
  145919. +
  145920. +/* Set depth compare mode. */
  145921. +gceSTATUS
  145922. +gco3D_SetDepthCompare(
  145923. + IN gco3D Engine,
  145924. + IN gceCOMPARE Compare
  145925. + );
  145926. +
  145927. +/* Enable depth writing. */
  145928. +gceSTATUS
  145929. +gco3D_EnableDepthWrite(
  145930. + IN gco3D Engine,
  145931. + IN gctBOOL Enable
  145932. + );
  145933. +
  145934. +/* Set depth mode. */
  145935. +gceSTATUS
  145936. +gco3D_SetDepthMode(
  145937. + IN gco3D Engine,
  145938. + IN gceDEPTH_MODE Mode
  145939. + );
  145940. +
  145941. +/* Set depth range. */
  145942. +gceSTATUS
  145943. +gco3D_SetDepthRangeX(
  145944. + IN gco3D Engine,
  145945. + IN gceDEPTH_MODE Mode,
  145946. + IN gctFIXED_POINT Near,
  145947. + IN gctFIXED_POINT Far
  145948. + );
  145949. +
  145950. +/* Set depth range. */
  145951. +gceSTATUS
  145952. +gco3D_SetDepthRangeF(
  145953. + IN gco3D Engine,
  145954. + IN gceDEPTH_MODE Mode,
  145955. + IN gctFLOAT Near,
  145956. + IN gctFLOAT Far
  145957. + );
  145958. +
  145959. +/* Set last pixel enable */
  145960. +gceSTATUS
  145961. +gco3D_SetLastPixelEnable(
  145962. + IN gco3D Engine,
  145963. + IN gctBOOL Enable
  145964. + );
  145965. +
  145966. +/* Set depth Bias and Scale */
  145967. +gceSTATUS
  145968. +gco3D_SetDepthScaleBiasX(
  145969. + IN gco3D Engine,
  145970. + IN gctFIXED_POINT DepthScale,
  145971. + IN gctFIXED_POINT DepthBias
  145972. + );
  145973. +
  145974. +gceSTATUS
  145975. +gco3D_SetDepthScaleBiasF(
  145976. + IN gco3D Engine,
  145977. + IN gctFLOAT DepthScale,
  145978. + IN gctFLOAT DepthBias
  145979. + );
  145980. +
  145981. +/* Set depth near and far clipping plane. */
  145982. +gceSTATUS
  145983. +gco3D_SetDepthPlaneF(
  145984. + IN gco3D Engine,
  145985. + IN gctFLOAT Near,
  145986. + IN gctFLOAT Far
  145987. + );
  145988. +
  145989. +/* Enable or disable dithering. */
  145990. +gceSTATUS
  145991. +gco3D_EnableDither(
  145992. + IN gco3D Engine,
  145993. + IN gctBOOL Enable
  145994. + );
  145995. +
  145996. +/* Set color write enable bits. */
  145997. +gceSTATUS
  145998. +gco3D_SetColorWrite(
  145999. + IN gco3D Engine,
  146000. + IN gctUINT8 Enable
  146001. + );
  146002. +
  146003. +/* Enable or disable early depth. */
  146004. +gceSTATUS
  146005. +gco3D_SetEarlyDepth(
  146006. + IN gco3D Engine,
  146007. + IN gctBOOL Enable
  146008. + );
  146009. +
  146010. +/* Enable or disable all early depth operations. */
  146011. +gceSTATUS
  146012. +gco3D_SetAllEarlyDepthModes(
  146013. + IN gco3D Engine,
  146014. + IN gctBOOL Disable
  146015. + );
  146016. +
  146017. +/* Switch dynamic early mode */
  146018. +gceSTATUS
  146019. +gco3D_SwitchDynamicEarlyDepthMode(
  146020. + IN gco3D Engine
  146021. + );
  146022. +
  146023. +/* Set dynamic early mode */
  146024. +gceSTATUS
  146025. +gco3D_DisableDynamicEarlyDepthMode(
  146026. + IN gco3D Engine,
  146027. + IN gctBOOL Disable
  146028. + );
  146029. +
  146030. +/* Enable or disable depth-only mode. */
  146031. +gceSTATUS
  146032. +gco3D_SetDepthOnly(
  146033. + IN gco3D Engine,
  146034. + IN gctBOOL Enable
  146035. + );
  146036. +
  146037. +typedef struct _gcsSTENCIL_INFO * gcsSTENCIL_INFO_PTR;
  146038. +typedef struct _gcsSTENCIL_INFO
  146039. +{
  146040. + gceSTENCIL_MODE mode;
  146041. +
  146042. + gctUINT8 maskFront;
  146043. + gctUINT8 maskBack;
  146044. + gctUINT8 writeMaskFront;
  146045. + gctUINT8 writeMaskBack;
  146046. +
  146047. + gctUINT8 referenceFront;
  146048. +
  146049. + gceCOMPARE compareFront;
  146050. + gceSTENCIL_OPERATION passFront;
  146051. + gceSTENCIL_OPERATION failFront;
  146052. + gceSTENCIL_OPERATION depthFailFront;
  146053. +
  146054. + gctUINT8 referenceBack;
  146055. + gceCOMPARE compareBack;
  146056. + gceSTENCIL_OPERATION passBack;
  146057. + gceSTENCIL_OPERATION failBack;
  146058. + gceSTENCIL_OPERATION depthFailBack;
  146059. +}
  146060. +gcsSTENCIL_INFO;
  146061. +
  146062. +/* Set stencil mode. */
  146063. +gceSTATUS
  146064. +gco3D_SetStencilMode(
  146065. + IN gco3D Engine,
  146066. + IN gceSTENCIL_MODE Mode
  146067. + );
  146068. +
  146069. +/* Set stencil mask. */
  146070. +gceSTATUS
  146071. +gco3D_SetStencilMask(
  146072. + IN gco3D Engine,
  146073. + IN gctUINT8 Mask
  146074. + );
  146075. +
  146076. +/* Set stencil back mask. */
  146077. +gceSTATUS
  146078. +gco3D_SetStencilMaskBack(
  146079. + IN gco3D Engine,
  146080. + IN gctUINT8 Mask
  146081. + );
  146082. +
  146083. +/* Set stencil write mask. */
  146084. +gceSTATUS
  146085. +gco3D_SetStencilWriteMask(
  146086. + IN gco3D Engine,
  146087. + IN gctUINT8 Mask
  146088. + );
  146089. +
  146090. +/* Set stencil back write mask. */
  146091. +gceSTATUS
  146092. +gco3D_SetStencilWriteMaskBack(
  146093. + IN gco3D Engine,
  146094. + IN gctUINT8 Mask
  146095. + );
  146096. +
  146097. +/* Set stencil reference. */
  146098. +gceSTATUS
  146099. +gco3D_SetStencilReference(
  146100. + IN gco3D Engine,
  146101. + IN gctUINT8 Reference,
  146102. + IN gctBOOL Front
  146103. + );
  146104. +
  146105. +/* Set stencil compare. */
  146106. +gceSTATUS
  146107. +gco3D_SetStencilCompare(
  146108. + IN gco3D Engine,
  146109. + IN gceSTENCIL_WHERE Where,
  146110. + IN gceCOMPARE Compare
  146111. + );
  146112. +
  146113. +/* Set stencil operation on pass. */
  146114. +gceSTATUS
  146115. +gco3D_SetStencilPass(
  146116. + IN gco3D Engine,
  146117. + IN gceSTENCIL_WHERE Where,
  146118. + IN gceSTENCIL_OPERATION Operation
  146119. + );
  146120. +
  146121. +/* Set stencil operation on fail. */
  146122. +gceSTATUS
  146123. +gco3D_SetStencilFail(
  146124. + IN gco3D Engine,
  146125. + IN gceSTENCIL_WHERE Where,
  146126. + IN gceSTENCIL_OPERATION Operation
  146127. + );
  146128. +
  146129. +/* Set stencil operation on depth fail. */
  146130. +gceSTATUS
  146131. +gco3D_SetStencilDepthFail(
  146132. + IN gco3D Engine,
  146133. + IN gceSTENCIL_WHERE Where,
  146134. + IN gceSTENCIL_OPERATION Operation
  146135. + );
  146136. +
  146137. +/* Set all stencil states in one blow. */
  146138. +gceSTATUS
  146139. +gco3D_SetStencilAll(
  146140. + IN gco3D Engine,
  146141. + IN gcsSTENCIL_INFO_PTR Info
  146142. + );
  146143. +
  146144. +typedef struct _gcsALPHA_INFO * gcsALPHA_INFO_PTR;
  146145. +typedef struct _gcsALPHA_INFO
  146146. +{
  146147. + /* Alpha test states. */
  146148. + gctBOOL test;
  146149. + gceCOMPARE compare;
  146150. + gctUINT8 reference;
  146151. + gctFLOAT floatReference;
  146152. +
  146153. + /* Alpha blending states. */
  146154. + gctBOOL blend;
  146155. +
  146156. + gceBLEND_FUNCTION srcFuncColor;
  146157. + gceBLEND_FUNCTION srcFuncAlpha;
  146158. + gceBLEND_FUNCTION trgFuncColor;
  146159. + gceBLEND_FUNCTION trgFuncAlpha;
  146160. +
  146161. + gceBLEND_MODE modeColor;
  146162. + gceBLEND_MODE modeAlpha;
  146163. +
  146164. + gctUINT32 color;
  146165. +}
  146166. +gcsALPHA_INFO;
  146167. +
  146168. +/* Enable or disable alpha test. */
  146169. +gceSTATUS
  146170. +gco3D_SetAlphaTest(
  146171. + IN gco3D Engine,
  146172. + IN gctBOOL Enable
  146173. + );
  146174. +
  146175. +/* Set alpha test compare. */
  146176. +gceSTATUS
  146177. +gco3D_SetAlphaCompare(
  146178. + IN gco3D Engine,
  146179. + IN gceCOMPARE Compare
  146180. + );
  146181. +
  146182. +/* Set alpha test reference in unsigned integer. */
  146183. +gceSTATUS
  146184. +gco3D_SetAlphaReference(
  146185. + IN gco3D Engine,
  146186. + IN gctUINT8 Reference,
  146187. + IN gctFLOAT FloatReference
  146188. + );
  146189. +
  146190. +/* Set alpha test reference in fixed point. */
  146191. +gceSTATUS
  146192. +gco3D_SetAlphaReferenceX(
  146193. + IN gco3D Engine,
  146194. + IN gctFIXED_POINT Reference
  146195. + );
  146196. +
  146197. +/* Set alpha test reference in floating point. */
  146198. +gceSTATUS
  146199. +gco3D_SetAlphaReferenceF(
  146200. + IN gco3D Engine,
  146201. + IN gctFLOAT Reference
  146202. + );
  146203. +
  146204. +/* Enable/Disable anti-alias line. */
  146205. +gceSTATUS
  146206. +gco3D_SetAntiAliasLine(
  146207. + IN gco3D Engine,
  146208. + IN gctBOOL Enable
  146209. + );
  146210. +
  146211. +/* Set texture slot for anti-alias line. */
  146212. +gceSTATUS
  146213. +gco3D_SetAALineTexSlot(
  146214. + IN gco3D Engine,
  146215. + IN gctUINT TexSlot
  146216. + );
  146217. +
  146218. +/* Set anti-alias line width scale. */
  146219. +gceSTATUS
  146220. +gco3D_SetAALineWidth(
  146221. + IN gco3D Engine,
  146222. + IN gctFLOAT Width
  146223. + );
  146224. +
  146225. +/* Draw a number of primitives. */
  146226. +gceSTATUS
  146227. +gco3D_DrawPrimitives(
  146228. + IN gco3D Engine,
  146229. + IN gcePRIMITIVE Type,
  146230. + IN gctINT StartVertex,
  146231. + IN gctSIZE_T PrimitiveCount
  146232. + );
  146233. +
  146234. +gceSTATUS
  146235. +gco3D_DrawPrimitivesCount(
  146236. + IN gco3D Engine,
  146237. + IN gcePRIMITIVE Type,
  146238. + IN gctINT* StartVertex,
  146239. + IN gctSIZE_T* VertexCount,
  146240. + IN gctSIZE_T PrimitiveCount
  146241. + );
  146242. +
  146243. +
  146244. +/* Draw a number of primitives using offsets. */
  146245. +gceSTATUS
  146246. +gco3D_DrawPrimitivesOffset(
  146247. + IN gco3D Engine,
  146248. + IN gcePRIMITIVE Type,
  146249. + IN gctINT32 StartOffset,
  146250. + IN gctSIZE_T PrimitiveCount
  146251. + );
  146252. +
  146253. +/* Draw a number of indexed primitives. */
  146254. +gceSTATUS
  146255. +gco3D_DrawIndexedPrimitives(
  146256. + IN gco3D Engine,
  146257. + IN gcePRIMITIVE Type,
  146258. + IN gctINT BaseVertex,
  146259. + IN gctINT StartIndex,
  146260. + IN gctSIZE_T PrimitiveCount
  146261. + );
  146262. +
  146263. +/* Draw a number of indexed primitives using offsets. */
  146264. +gceSTATUS
  146265. +gco3D_DrawIndexedPrimitivesOffset(
  146266. + IN gco3D Engine,
  146267. + IN gcePRIMITIVE Type,
  146268. + IN gctINT32 BaseOffset,
  146269. + IN gctINT32 StartOffset,
  146270. + IN gctSIZE_T PrimitiveCount
  146271. + );
  146272. +
  146273. +/* Enable or disable anti-aliasing. */
  146274. +gceSTATUS
  146275. +gco3D_SetAntiAlias(
  146276. + IN gco3D Engine,
  146277. + IN gctBOOL Enable
  146278. + );
  146279. +
  146280. +/* Write data into the command buffer. */
  146281. +gceSTATUS
  146282. +gco3D_WriteBuffer(
  146283. + IN gco3D Engine,
  146284. + IN gctCONST_POINTER Data,
  146285. + IN gctSIZE_T Bytes,
  146286. + IN gctBOOL Aligned
  146287. + );
  146288. +
  146289. +/* Send sempahore and stall until sempahore is signalled. */
  146290. +gceSTATUS
  146291. +gco3D_Semaphore(
  146292. + IN gco3D Engine,
  146293. + IN gceWHERE From,
  146294. + IN gceWHERE To,
  146295. + IN gceHOW How);
  146296. +
  146297. +/* Set the subpixels center. */
  146298. +gceSTATUS
  146299. +gco3D_SetCentroids(
  146300. + IN gco3D Engine,
  146301. + IN gctUINT32 Index,
  146302. + IN gctPOINTER Centroids
  146303. + );
  146304. +
  146305. +gceSTATUS
  146306. +gco3D_SetLogicOp(
  146307. + IN gco3D Engine,
  146308. + IN gctUINT8 Rop
  146309. + );
  146310. +
  146311. +/* OCL thread walker information. */
  146312. +typedef struct _gcsTHREAD_WALKER_INFO * gcsTHREAD_WALKER_INFO_PTR;
  146313. +typedef struct _gcsTHREAD_WALKER_INFO
  146314. +{
  146315. + gctUINT32 dimensions;
  146316. + gctUINT32 traverseOrder;
  146317. + gctUINT32 enableSwathX;
  146318. + gctUINT32 enableSwathY;
  146319. + gctUINT32 enableSwathZ;
  146320. + gctUINT32 swathSizeX;
  146321. + gctUINT32 swathSizeY;
  146322. + gctUINT32 swathSizeZ;
  146323. + gctUINT32 valueOrder;
  146324. +
  146325. + gctUINT32 globalSizeX;
  146326. + gctUINT32 globalOffsetX;
  146327. + gctUINT32 globalSizeY;
  146328. + gctUINT32 globalOffsetY;
  146329. + gctUINT32 globalSizeZ;
  146330. + gctUINT32 globalOffsetZ;
  146331. +
  146332. + gctUINT32 workGroupSizeX;
  146333. + gctUINT32 workGroupCountX;
  146334. + gctUINT32 workGroupSizeY;
  146335. + gctUINT32 workGroupCountY;
  146336. + gctUINT32 workGroupSizeZ;
  146337. + gctUINT32 workGroupCountZ;
  146338. +
  146339. + gctUINT32 threadAllocation;
  146340. +}
  146341. +gcsTHREAD_WALKER_INFO;
  146342. +
  146343. +/* Start OCL thread walker. */
  146344. +gceSTATUS
  146345. +gco3D_InvokeThreadWalker(
  146346. + IN gco3D Engine,
  146347. + IN gcsTHREAD_WALKER_INFO_PTR Info
  146348. + );
  146349. +
  146350. +/* Set w clip and w plane limit value. */
  146351. +gceSTATUS
  146352. +gco3D_SetWClipEnable(
  146353. + IN gco3D Engine,
  146354. + IN gctBOOL Enable
  146355. + );
  146356. +
  146357. +gceSTATUS
  146358. +gco3D_GetWClipEnable(
  146359. + IN gco3D Engine,
  146360. + OUT gctBOOL * Enable
  146361. + );
  146362. +
  146363. +gceSTATUS
  146364. +gco3D_SetWPlaneLimitF(
  146365. + IN gco3D Engine,
  146366. + IN gctFLOAT Value
  146367. + );
  146368. +
  146369. +gceSTATUS
  146370. +gco3D_SetWPlaneLimitX(
  146371. + IN gco3D Engine,
  146372. + IN gctFIXED_POINT Value
  146373. + );
  146374. +
  146375. +
  146376. +gceSTATUS
  146377. +gco3D_SetWPlaneLimit(
  146378. + IN gco3D Engine,
  146379. + IN gctFLOAT Value
  146380. + );
  146381. +
  146382. +/*----------------------------------------------------------------------------*/
  146383. +/*-------------------------- gco3D Fragment Processor ------------------------*/
  146384. +
  146385. +/* Set the fragment processor configuration. */
  146386. +gceSTATUS
  146387. +gco3D_SetFragmentConfiguration(
  146388. + IN gco3D Engine,
  146389. + IN gctBOOL ColorFromStream,
  146390. + IN gctBOOL EnableFog,
  146391. + IN gctBOOL EnableSmoothPoint,
  146392. + IN gctUINT32 ClipPlanes
  146393. + );
  146394. +
  146395. +/* Enable/disable texture stage operation. */
  146396. +gceSTATUS
  146397. +gco3D_EnableTextureStage(
  146398. + IN gco3D Engine,
  146399. + IN gctINT Stage,
  146400. + IN gctBOOL Enable
  146401. + );
  146402. +
  146403. +/* Program the channel enable masks for the color texture function. */
  146404. +gceSTATUS
  146405. +gco3D_SetTextureColorMask(
  146406. + IN gco3D Engine,
  146407. + IN gctINT Stage,
  146408. + IN gctBOOL ColorEnabled,
  146409. + IN gctBOOL AlphaEnabled
  146410. + );
  146411. +
  146412. +/* Program the channel enable masks for the alpha texture function. */
  146413. +gceSTATUS
  146414. +gco3D_SetTextureAlphaMask(
  146415. + IN gco3D Engine,
  146416. + IN gctINT Stage,
  146417. + IN gctBOOL ColorEnabled,
  146418. + IN gctBOOL AlphaEnabled
  146419. + );
  146420. +
  146421. +/* Program the constant fragment color. */
  146422. +gceSTATUS
  146423. +gco3D_SetFragmentColorX(
  146424. + IN gco3D Engine,
  146425. + IN gctFIXED_POINT Red,
  146426. + IN gctFIXED_POINT Green,
  146427. + IN gctFIXED_POINT Blue,
  146428. + IN gctFIXED_POINT Alpha
  146429. + );
  146430. +
  146431. +gceSTATUS
  146432. +gco3D_SetFragmentColorF(
  146433. + IN gco3D Engine,
  146434. + IN gctFLOAT Red,
  146435. + IN gctFLOAT Green,
  146436. + IN gctFLOAT Blue,
  146437. + IN gctFLOAT Alpha
  146438. + );
  146439. +
  146440. +/* Program the constant fog color. */
  146441. +gceSTATUS
  146442. +gco3D_SetFogColorX(
  146443. + IN gco3D Engine,
  146444. + IN gctFIXED_POINT Red,
  146445. + IN gctFIXED_POINT Green,
  146446. + IN gctFIXED_POINT Blue,
  146447. + IN gctFIXED_POINT Alpha
  146448. + );
  146449. +
  146450. +gceSTATUS
  146451. +gco3D_SetFogColorF(
  146452. + IN gco3D Engine,
  146453. + IN gctFLOAT Red,
  146454. + IN gctFLOAT Green,
  146455. + IN gctFLOAT Blue,
  146456. + IN gctFLOAT Alpha
  146457. + );
  146458. +
  146459. +/* Program the constant texture color. */
  146460. +gceSTATUS
  146461. +gco3D_SetTetxureColorX(
  146462. + IN gco3D Engine,
  146463. + IN gctINT Stage,
  146464. + IN gctFIXED_POINT Red,
  146465. + IN gctFIXED_POINT Green,
  146466. + IN gctFIXED_POINT Blue,
  146467. + IN gctFIXED_POINT Alpha
  146468. + );
  146469. +
  146470. +gceSTATUS
  146471. +gco3D_SetTetxureColorF(
  146472. + IN gco3D Engine,
  146473. + IN gctINT Stage,
  146474. + IN gctFLOAT Red,
  146475. + IN gctFLOAT Green,
  146476. + IN gctFLOAT Blue,
  146477. + IN gctFLOAT Alpha
  146478. + );
  146479. +
  146480. +/* Configure color texture function. */
  146481. +gceSTATUS
  146482. +gco3D_SetColorTextureFunction(
  146483. + IN gco3D Engine,
  146484. + IN gctINT Stage,
  146485. + IN gceTEXTURE_FUNCTION Function,
  146486. + IN gceTEXTURE_SOURCE Source0,
  146487. + IN gceTEXTURE_CHANNEL Channel0,
  146488. + IN gceTEXTURE_SOURCE Source1,
  146489. + IN gceTEXTURE_CHANNEL Channel1,
  146490. + IN gceTEXTURE_SOURCE Source2,
  146491. + IN gceTEXTURE_CHANNEL Channel2,
  146492. + IN gctINT Scale
  146493. + );
  146494. +
  146495. +/* Configure alpha texture function. */
  146496. +gceSTATUS
  146497. +gco3D_SetAlphaTextureFunction(
  146498. + IN gco3D Engine,
  146499. + IN gctINT Stage,
  146500. + IN gceTEXTURE_FUNCTION Function,
  146501. + IN gceTEXTURE_SOURCE Source0,
  146502. + IN gceTEXTURE_CHANNEL Channel0,
  146503. + IN gceTEXTURE_SOURCE Source1,
  146504. + IN gceTEXTURE_CHANNEL Channel1,
  146505. + IN gceTEXTURE_SOURCE Source2,
  146506. + IN gceTEXTURE_CHANNEL Channel2,
  146507. + IN gctINT Scale
  146508. + );
  146509. +
  146510. +/* Invoke OCL thread walker. */
  146511. +gceSTATUS
  146512. +gcoHARDWARE_InvokeThreadWalker(
  146513. + IN gcsTHREAD_WALKER_INFO_PTR Info
  146514. + );
  146515. +
  146516. +/******************************************************************************\
  146517. +******************************* gcoTEXTURE Object *******************************
  146518. +\******************************************************************************/
  146519. +
  146520. +/* Cube faces. */
  146521. +typedef enum _gceTEXTURE_FACE
  146522. +{
  146523. + gcvFACE_NONE,
  146524. + gcvFACE_POSITIVE_X,
  146525. + gcvFACE_NEGATIVE_X,
  146526. + gcvFACE_POSITIVE_Y,
  146527. + gcvFACE_NEGATIVE_Y,
  146528. + gcvFACE_POSITIVE_Z,
  146529. + gcvFACE_NEGATIVE_Z,
  146530. +}
  146531. +gceTEXTURE_FACE;
  146532. +
  146533. +#if gcdFORCE_MIPMAP
  146534. +typedef enum
  146535. +{
  146536. + gcvForceMipDisabled = 0,
  146537. + gcvForceMipEnable = 1,
  146538. + gcvForceMipGenerated = 2,
  146539. + gcvForceMipNever = 3,
  146540. +}gceFORCE_MIPMAP;
  146541. +#endif
  146542. +
  146543. +typedef struct _gcsTEXTURE
  146544. +{
  146545. + /* Addressing modes. */
  146546. + gceTEXTURE_ADDRESSING s;
  146547. + gceTEXTURE_ADDRESSING t;
  146548. + gceTEXTURE_ADDRESSING r;
  146549. +
  146550. + /* Border color. */
  146551. + gctUINT8 border[4];
  146552. +
  146553. + /* Filters. */
  146554. + gceTEXTURE_FILTER minFilter;
  146555. + gceTEXTURE_FILTER magFilter;
  146556. + gceTEXTURE_FILTER mipFilter;
  146557. + gctUINT anisoFilter;
  146558. + gctBOOL forceTopLevel;
  146559. + gctBOOL autoMipmap;
  146560. +#if gcdFORCE_MIPMAP
  146561. + gceFORCE_MIPMAP forceMipmap;
  146562. +#endif
  146563. + /* Level of detail. */
  146564. + gctFIXED_POINT lodBias;
  146565. + gctFIXED_POINT lodMin;
  146566. + gctFIXED_POINT lodMax;
  146567. +}
  146568. +gcsTEXTURE, * gcsTEXTURE_PTR;
  146569. +
  146570. +/* Construct a new gcoTEXTURE object. */
  146571. +gceSTATUS
  146572. +gcoTEXTURE_Construct(
  146573. + IN gcoHAL Hal,
  146574. + OUT gcoTEXTURE * Texture
  146575. + );
  146576. +
  146577. +/* Construct a new sized gcoTEXTURE object. */
  146578. +gceSTATUS
  146579. +gcoTEXTURE_ConstructSized(
  146580. + IN gcoHAL Hal,
  146581. + IN gceSURF_FORMAT Format,
  146582. + IN gctUINT Width,
  146583. + IN gctUINT Height,
  146584. + IN gctUINT Depth,
  146585. + IN gctUINT Faces,
  146586. + IN gctUINT MipMapCount,
  146587. + IN gcePOOL Pool,
  146588. + OUT gcoTEXTURE * Texture
  146589. + );
  146590. +
  146591. +/* Destroy an gcoTEXTURE object. */
  146592. +gceSTATUS
  146593. +gcoTEXTURE_Destroy(
  146594. + IN gcoTEXTURE Texture
  146595. + );
  146596. +#if gcdFORCE_MIPMAP
  146597. +gceSTATUS
  146598. +gcoTEXTURE_DestroyForceMipmap(
  146599. + IN gcoTEXTURE Texture
  146600. + );
  146601. +
  146602. +gceSTATUS
  146603. +gcoTEXTURE_GetMipLevels(
  146604. + IN gcoTEXTURE Texture,
  146605. + OUT gctINT * levels
  146606. + );
  146607. +#endif
  146608. +/* Replace a mipmap in gcoTEXTURE object. */
  146609. +gceSTATUS
  146610. +gcoTEXTURE_ReplaceMipMap(
  146611. + IN gcoTEXTURE Texture,
  146612. + IN gctUINT Level,
  146613. + IN gctUINT Width,
  146614. + IN gctUINT Height,
  146615. + IN gctINT imageFormat,
  146616. + IN gceSURF_FORMAT Format,
  146617. + IN gctUINT Depth,
  146618. + IN gctUINT Faces,
  146619. + IN gcePOOL Pool
  146620. + );
  146621. +
  146622. +/* Upload data to an gcoTEXTURE object. */
  146623. +gceSTATUS
  146624. +gcoTEXTURE_Upload(
  146625. + IN gcoTEXTURE Texture,
  146626. + IN gceTEXTURE_FACE Face,
  146627. + IN gctUINT Width,
  146628. + IN gctUINT Height,
  146629. + IN gctUINT Slice,
  146630. + IN gctCONST_POINTER Memory,
  146631. + IN gctINT Stride,
  146632. + IN gceSURF_FORMAT Format
  146633. + );
  146634. +
  146635. +/* Upload data to an gcoTEXTURE object. */
  146636. +gceSTATUS
  146637. +gcoTEXTURE_UploadSub(
  146638. + IN gcoTEXTURE Texture,
  146639. + IN gctUINT MipMap,
  146640. + IN gceTEXTURE_FACE Face,
  146641. + IN gctUINT X,
  146642. + IN gctUINT Y,
  146643. + IN gctUINT Width,
  146644. + IN gctUINT Height,
  146645. + IN gctUINT Slice,
  146646. + IN gctCONST_POINTER Memory,
  146647. + IN gctINT Stride,
  146648. + IN gceSURF_FORMAT Format
  146649. + );
  146650. +
  146651. +/* Upload YUV data to an gcoTEXTURE object. */
  146652. +gceSTATUS
  146653. +gcoTEXTURE_UploadYUV(
  146654. + IN gcoTEXTURE Texture,
  146655. + IN gceTEXTURE_FACE Face,
  146656. + IN gctUINT Width,
  146657. + IN gctUINT Height,
  146658. + IN gctUINT Slice,
  146659. + IN gctPOINTER Memory[3],
  146660. + IN gctINT Stride[3],
  146661. + IN gceSURF_FORMAT Format
  146662. + );
  146663. +
  146664. +/* Upload compressed data to an gcoTEXTURE object. */
  146665. +gceSTATUS
  146666. +gcoTEXTURE_UploadCompressed(
  146667. + IN gcoTEXTURE Texture,
  146668. + IN gceTEXTURE_FACE Face,
  146669. + IN gctUINT Width,
  146670. + IN gctUINT Height,
  146671. + IN gctUINT Slice,
  146672. + IN gctCONST_POINTER Memory,
  146673. + IN gctSIZE_T Bytes
  146674. + );
  146675. +
  146676. +/* Upload compressed sub data to an gcoTEXTURE object. */
  146677. +gceSTATUS
  146678. +gcoTEXTURE_UploadCompressedSub(
  146679. + IN gcoTEXTURE Texture,
  146680. + IN gctUINT MipMap,
  146681. + IN gceTEXTURE_FACE Face,
  146682. + IN gctUINT XOffset,
  146683. + IN gctUINT YOffset,
  146684. + IN gctUINT Width,
  146685. + IN gctUINT Height,
  146686. + IN gctUINT Slice,
  146687. + IN gctCONST_POINTER Memory,
  146688. + IN gctSIZE_T Size
  146689. + );
  146690. +
  146691. +/* GetImageFormat of texture. */
  146692. +gceSTATUS
  146693. +gcoTEXTURE_GetImageFormat(
  146694. + IN gcoTEXTURE Texture,
  146695. + IN gctUINT MipMap,
  146696. + OUT gctINT * ImageFormat
  146697. + );
  146698. +
  146699. +/* Get gcoSURF object for a mipmap level. */
  146700. +gceSTATUS
  146701. +gcoTEXTURE_GetMipMap(
  146702. + IN gcoTEXTURE Texture,
  146703. + IN gctUINT MipMap,
  146704. + OUT gcoSURF * Surface
  146705. + );
  146706. +
  146707. +/* Get gcoSURF object for a mipmap level and face offset. */
  146708. +gceSTATUS
  146709. +gcoTEXTURE_GetMipMapFace(
  146710. + IN gcoTEXTURE Texture,
  146711. + IN gctUINT MipMap,
  146712. + IN gceTEXTURE_FACE Face,
  146713. + OUT gcoSURF * Surface,
  146714. + OUT gctUINT32_PTR Offset
  146715. + );
  146716. +
  146717. +gceSTATUS
  146718. +gcoTEXTURE_AddMipMap(
  146719. + IN gcoTEXTURE Texture,
  146720. + IN gctINT Level,
  146721. + IN gctINT imageFormat,
  146722. + IN gceSURF_FORMAT Format,
  146723. + IN gctUINT Width,
  146724. + IN gctUINT Height,
  146725. + IN gctUINT Depth,
  146726. + IN gctUINT Faces,
  146727. + IN gcePOOL Pool,
  146728. + OUT gcoSURF * Surface
  146729. + );
  146730. +
  146731. +gceSTATUS
  146732. +gcoTEXTURE_AddMipMapFromClient(
  146733. + IN gcoTEXTURE Texture,
  146734. + IN gctINT Level,
  146735. + IN gcoSURF Surface
  146736. + );
  146737. +
  146738. +gceSTATUS
  146739. +gcoTEXTURE_AddMipMapFromSurface(
  146740. + IN gcoTEXTURE Texture,
  146741. + IN gctINT Level,
  146742. + IN gcoSURF Surface
  146743. + );
  146744. +
  146745. +gceSTATUS
  146746. +gcoTEXTURE_SetMaxLevel(
  146747. + IN gcoTEXTURE Texture,
  146748. + IN gctUINT Levels
  146749. + );
  146750. +
  146751. +gceSTATUS
  146752. +gcoTEXTURE_SetEndianHint(
  146753. + IN gcoTEXTURE Texture,
  146754. + IN gceENDIAN_HINT EndianHint
  146755. + );
  146756. +
  146757. +gceSTATUS
  146758. +gcoTEXTURE_Disable(
  146759. + IN gcoHAL Hal,
  146760. + IN gctINT Sampler
  146761. + );
  146762. +
  146763. +gceSTATUS
  146764. +gcoTEXTURE_Flush(
  146765. + IN gcoTEXTURE Texture
  146766. + );
  146767. +
  146768. +gceSTATUS
  146769. +gcoTEXTURE_QueryCaps(
  146770. + IN gcoHAL Hal,
  146771. + OUT gctUINT * MaxWidth,
  146772. + OUT gctUINT * MaxHeight,
  146773. + OUT gctUINT * MaxDepth,
  146774. + OUT gctBOOL * Cubic,
  146775. + OUT gctBOOL * NonPowerOfTwo,
  146776. + OUT gctUINT * VertexSamplers,
  146777. + OUT gctUINT * PixelSamplers
  146778. + );
  146779. +
  146780. +gceSTATUS
  146781. +gcoTEXTURE_GetTiling(
  146782. + IN gcoTEXTURE Texture,
  146783. + IN gctINT preferLevel,
  146784. + OUT gceTILING * Tiling
  146785. + );
  146786. +
  146787. +gceSTATUS
  146788. +gcoTEXTURE_GetClosestFormat(
  146789. + IN gcoHAL Hal,
  146790. + IN gceSURF_FORMAT InFormat,
  146791. + OUT gceSURF_FORMAT* OutFormat
  146792. + );
  146793. +
  146794. +gceSTATUS
  146795. +gcoTEXTURE_RenderIntoMipMap(
  146796. + IN gcoTEXTURE Texture,
  146797. + IN gctINT Level
  146798. + );
  146799. +
  146800. +gceSTATUS
  146801. +gcoTEXTURE_IsRenderable(
  146802. + IN gcoTEXTURE Texture,
  146803. + IN gctUINT Level
  146804. + );
  146805. +
  146806. +gceSTATUS
  146807. +gcoTEXTURE_IsRenderableEx(
  146808. + IN gcoTEXTURE Texture,
  146809. + IN gctUINT Level
  146810. + );
  146811. +
  146812. +gceSTATUS
  146813. +gcoTEXTURE_IsComplete(
  146814. + IN gcoTEXTURE Texture,
  146815. + IN gctINT MaxLevel
  146816. + );
  146817. +
  146818. +gceSTATUS
  146819. +gcoTEXTURE_BindTexture(
  146820. + IN gcoTEXTURE Texture,
  146821. + IN gctINT Target,
  146822. + IN gctINT Sampler,
  146823. + IN gcsTEXTURE_PTR Info
  146824. + );
  146825. +
  146826. +/******************************************************************************\
  146827. +******************************* gcoSTREAM Object ******************************
  146828. +\******************************************************************************/
  146829. +
  146830. +typedef enum _gceVERTEX_FORMAT
  146831. +{
  146832. + gcvVERTEX_BYTE,
  146833. + gcvVERTEX_UNSIGNED_BYTE,
  146834. + gcvVERTEX_SHORT,
  146835. + gcvVERTEX_UNSIGNED_SHORT,
  146836. + gcvVERTEX_INT,
  146837. + gcvVERTEX_UNSIGNED_INT,
  146838. + gcvVERTEX_FIXED,
  146839. + gcvVERTEX_HALF,
  146840. + gcvVERTEX_FLOAT,
  146841. + gcvVERTEX_UNSIGNED_INT_10_10_10_2,
  146842. + gcvVERTEX_INT_10_10_10_2,
  146843. +}
  146844. +gceVERTEX_FORMAT;
  146845. +
  146846. +gceSTATUS
  146847. +gcoSTREAM_Construct(
  146848. + IN gcoHAL Hal,
  146849. + OUT gcoSTREAM * Stream
  146850. + );
  146851. +
  146852. +gceSTATUS
  146853. +gcoSTREAM_Destroy(
  146854. + IN gcoSTREAM Stream
  146855. + );
  146856. +
  146857. +gceSTATUS
  146858. +gcoSTREAM_Upload(
  146859. + IN gcoSTREAM Stream,
  146860. + IN gctCONST_POINTER Buffer,
  146861. + IN gctUINT32 Offset,
  146862. + IN gctSIZE_T Bytes,
  146863. + IN gctBOOL Dynamic
  146864. + );
  146865. +
  146866. +gceSTATUS
  146867. +gcoSTREAM_SetStride(
  146868. + IN gcoSTREAM Stream,
  146869. + IN gctUINT32 Stride
  146870. + );
  146871. +
  146872. +gceSTATUS
  146873. +gcoSTREAM_Lock(
  146874. + IN gcoSTREAM Stream,
  146875. + OUT gctPOINTER * Logical,
  146876. + OUT gctUINT32 * Physical
  146877. + );
  146878. +
  146879. +gceSTATUS
  146880. +gcoSTREAM_Unlock(
  146881. + IN gcoSTREAM Stream
  146882. + );
  146883. +
  146884. +gceSTATUS
  146885. +gcoSTREAM_Reserve(
  146886. + IN gcoSTREAM Stream,
  146887. + IN gctSIZE_T Bytes
  146888. + );
  146889. +
  146890. +gceSTATUS
  146891. +gcoSTREAM_Flush(
  146892. + IN gcoSTREAM Stream
  146893. + );
  146894. +
  146895. +/* Dynamic buffer API. */
  146896. +gceSTATUS
  146897. +gcoSTREAM_SetDynamic(
  146898. + IN gcoSTREAM Stream,
  146899. + IN gctSIZE_T Bytes,
  146900. + IN gctUINT Buffers
  146901. + );
  146902. +
  146903. +typedef struct _gcsSTREAM_INFO
  146904. +{
  146905. + gctUINT index;
  146906. + gceVERTEX_FORMAT format;
  146907. + gctBOOL normalized;
  146908. + gctUINT components;
  146909. + gctSIZE_T size;
  146910. + gctCONST_POINTER data;
  146911. + gctUINT stride;
  146912. +}
  146913. +gcsSTREAM_INFO, * gcsSTREAM_INFO_PTR;
  146914. +
  146915. +gceSTATUS
  146916. +gcoSTREAM_UploadDynamic(
  146917. + IN gcoSTREAM Stream,
  146918. + IN gctUINT VertexCount,
  146919. + IN gctUINT InfoCount,
  146920. + IN gcsSTREAM_INFO_PTR Info,
  146921. + IN gcoVERTEX Vertex
  146922. + );
  146923. +
  146924. +gceSTATUS
  146925. +gcoSTREAM_CPUCacheOperation(
  146926. + IN gcoSTREAM Stream,
  146927. + IN gceCACHEOPERATION Operation
  146928. + );
  146929. +
  146930. +/******************************************************************************\
  146931. +******************************** gcoVERTEX Object ******************************
  146932. +\******************************************************************************/
  146933. +
  146934. +typedef struct _gcsVERTEX_ATTRIBUTES
  146935. +{
  146936. + gceVERTEX_FORMAT format;
  146937. + gctBOOL normalized;
  146938. + gctUINT32 components;
  146939. + gctSIZE_T size;
  146940. + gctUINT32 stream;
  146941. + gctUINT32 offset;
  146942. + gctUINT32 stride;
  146943. +}
  146944. +gcsVERTEX_ATTRIBUTES;
  146945. +
  146946. +gceSTATUS
  146947. +gcoVERTEX_Construct(
  146948. + IN gcoHAL Hal,
  146949. + OUT gcoVERTEX * Vertex
  146950. + );
  146951. +
  146952. +gceSTATUS
  146953. +gcoVERTEX_Destroy(
  146954. + IN gcoVERTEX Vertex
  146955. + );
  146956. +
  146957. +gceSTATUS
  146958. +gcoVERTEX_Reset(
  146959. + IN gcoVERTEX Vertex
  146960. + );
  146961. +
  146962. +gceSTATUS
  146963. +gcoVERTEX_EnableAttribute(
  146964. + IN gcoVERTEX Vertex,
  146965. + IN gctUINT32 Index,
  146966. + IN gceVERTEX_FORMAT Format,
  146967. + IN gctBOOL Normalized,
  146968. + IN gctUINT32 Components,
  146969. + IN gcoSTREAM Stream,
  146970. + IN gctUINT32 Offset,
  146971. + IN gctUINT32 Stride
  146972. + );
  146973. +
  146974. +gceSTATUS
  146975. +gcoVERTEX_DisableAttribute(
  146976. + IN gcoVERTEX Vertex,
  146977. + IN gctUINT32 Index
  146978. + );
  146979. +
  146980. +gceSTATUS
  146981. +gcoVERTEX_Bind(
  146982. + IN gcoVERTEX Vertex
  146983. + );
  146984. +
  146985. +/*******************************************************************************
  146986. +***** gcoVERTEXARRAY Object ***************************************************/
  146987. +
  146988. +typedef struct _gcsVERTEXARRAY
  146989. +{
  146990. + /* Enabled. */
  146991. + gctBOOL enable;
  146992. +
  146993. + /* Number of components. */
  146994. + gctINT size;
  146995. +
  146996. + /* Attribute format. */
  146997. + gceVERTEX_FORMAT format;
  146998. +
  146999. + /* Flag whether the attribute is normalized or not. */
  147000. + gctBOOL normalized;
  147001. +
  147002. + /* Stride of the component. */
  147003. + gctUINT stride;
  147004. +
  147005. + /* Pointer to the attribute data. */
  147006. + gctCONST_POINTER pointer;
  147007. +
  147008. + /* Stream object owning the attribute data. */
  147009. + gcoSTREAM stream;
  147010. +
  147011. + /* Generic values for attribute. */
  147012. + gctFLOAT genericValue[4];
  147013. +
  147014. + /* Generic size for attribute. */
  147015. + gctINT genericSize;
  147016. +
  147017. + /* Vertex shader linkage. */
  147018. + gctUINT linkage;
  147019. +
  147020. +#if gcdUSE_WCLIP_PATCH
  147021. + gctBOOL isPosition;
  147022. +#endif
  147023. +}
  147024. +gcsVERTEXARRAY,
  147025. +* gcsVERTEXARRAY_PTR;
  147026. +
  147027. +gceSTATUS
  147028. +gcoVERTEXARRAY_Construct(
  147029. + IN gcoHAL Hal,
  147030. + OUT gcoVERTEXARRAY * Vertex
  147031. + );
  147032. +
  147033. +gceSTATUS
  147034. +gcoVERTEXARRAY_Destroy(
  147035. + IN gcoVERTEXARRAY Vertex
  147036. + );
  147037. +
  147038. +gceSTATUS
  147039. +gcoVERTEXARRAY_Bind(
  147040. + IN gcoVERTEXARRAY Vertex,
  147041. + IN gctUINT32 EnableBits,
  147042. + IN gcsVERTEXARRAY_PTR VertexArray,
  147043. + IN gctUINT First,
  147044. + IN gctSIZE_T Count,
  147045. + IN gceINDEX_TYPE IndexType,
  147046. + IN gcoINDEX IndexObject,
  147047. + IN gctPOINTER IndexMemory,
  147048. + IN OUT gcePRIMITIVE * PrimitiveType,
  147049. +#if gcdUSE_WCLIP_PATCH
  147050. + IN OUT gctUINT * PrimitiveCount,
  147051. + IN OUT gctFLOAT * wLimitRms,
  147052. + IN OUT gctBOOL * wLimitDirty
  147053. +#else
  147054. + IN OUT gctUINT * PrimitiveCount
  147055. +#endif
  147056. + );
  147057. +
  147058. +gctUINT
  147059. +gcoVERTEXARRAY_GetMaxStream(
  147060. + IN gcoVERTEXARRAY Vertex
  147061. +);
  147062. +
  147063. +gceSTATUS
  147064. +gcoVERTEXARRAY_SetMaxStream(
  147065. + IN gcoVERTEXARRAY Vertex,
  147066. + gctUINT maxStreams
  147067. +);
  147068. +/*******************************************************************************
  147069. +***** Composition *************************************************************/
  147070. +
  147071. +typedef enum _gceCOMPOSITION
  147072. +{
  147073. + gcvCOMPOSE_CLEAR = 1,
  147074. + gcvCOMPOSE_BLUR,
  147075. + gcvCOMPOSE_DIM,
  147076. + gcvCOMPOSE_LAYER
  147077. +}
  147078. +gceCOMPOSITION;
  147079. +
  147080. +typedef struct _gcsCOMPOSITION * gcsCOMPOSITION_PTR;
  147081. +typedef struct _gcsCOMPOSITION
  147082. +{
  147083. + /* Structure size. */
  147084. + gctUINT structSize;
  147085. +
  147086. + /* Composition operation. */
  147087. + gceCOMPOSITION operation;
  147088. +
  147089. + /* Layer to be composed. */
  147090. + gcoSURF layer;
  147091. +
  147092. + /* Source and target coordinates. */
  147093. + gcsRECT srcRect;
  147094. + gcsRECT trgRect;
  147095. +
  147096. + /* Target rectangle */
  147097. + gcsPOINT v0;
  147098. + gcsPOINT v1;
  147099. + gcsPOINT v2;
  147100. +
  147101. + /* Blending parameters. */
  147102. + gctBOOL enableBlending;
  147103. + gctBOOL premultiplied;
  147104. + gctUINT8 alphaValue;
  147105. +
  147106. + /* Clear color. */
  147107. + gctFLOAT r;
  147108. + gctFLOAT g;
  147109. + gctFLOAT b;
  147110. + gctFLOAT a;
  147111. +}
  147112. +gcsCOMPOSITION;
  147113. +
  147114. +gceSTATUS
  147115. +gco3D_ProbeComposition(
  147116. + gctBOOL ResetIfEmpty
  147117. + );
  147118. +
  147119. +gceSTATUS
  147120. +gco3D_CompositionBegin(
  147121. + void
  147122. + );
  147123. +
  147124. +gceSTATUS
  147125. +gco3D_ComposeLayer(
  147126. + IN gcsCOMPOSITION_PTR Layer
  147127. + );
  147128. +
  147129. +gceSTATUS
  147130. +gco3D_CompositionSignals(
  147131. + IN gctHANDLE Process,
  147132. + IN gctSIGNAL Signal1,
  147133. + IN gctSIGNAL Signal2
  147134. + );
  147135. +
  147136. +gceSTATUS
  147137. +gco3D_CompositionEnd(
  147138. + IN gcoSURF Target,
  147139. + IN gctBOOL Synchronous
  147140. + );
  147141. +
  147142. +/* Frame Database */
  147143. +gceSTATUS
  147144. +gcoHAL_AddFrameDB(
  147145. + void
  147146. + );
  147147. +
  147148. +gceSTATUS
  147149. +gcoHAL_DumpFrameDB(
  147150. + gctCONST_STRING Filename OPTIONAL
  147151. + );
  147152. +
  147153. +gceSTATUS
  147154. +gcoHAL_GetSharedInfo(
  147155. + IN gctUINT32 Pid,
  147156. + IN gctUINT32 DataId,
  147157. + IN gctSIZE_T Bytes,
  147158. + OUT gctPOINTER Data
  147159. + );
  147160. +
  147161. +gceSTATUS
  147162. +gcoHAL_SetSharedInfo(
  147163. + IN gctUINT32 DataId,
  147164. + IN gctPOINTER Data,
  147165. + IN gctSIZE_T Bytes
  147166. + );
  147167. +
  147168. +#if VIVANTE_PROFILER_CONTEXT
  147169. +gceSTATUS
  147170. +gcoHARDWARE_GetContext(
  147171. + IN gcoHARDWARE Hardware,
  147172. + OUT gctUINT32 * Context
  147173. + );
  147174. +#endif
  147175. +
  147176. +#ifdef __cplusplus
  147177. +}
  147178. +#endif
  147179. +
  147180. +#endif /* VIVANTE_NO_3D */
  147181. +#endif /* __gc_hal_engine_h_ */
  147182. diff -Nur linux-3.14.17/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
  147183. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h 1970-01-01 01:00:00.000000000 +0100
  147184. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h 2014-09-11 18:06:03.118042434 +0200
  147185. @@ -0,0 +1,904 @@
  147186. +/****************************************************************************
  147187. +*
  147188. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  147189. +*
  147190. +* This program is free software; you can redistribute it and/or modify
  147191. +* it under the terms of the GNU General Public License as published by
  147192. +* the Free Software Foundation; either version 2 of the license, or
  147193. +* (at your option) any later version.
  147194. +*
  147195. +* This program is distributed in the hope that it will be useful,
  147196. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  147197. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  147198. +* GNU General Public License for more details.
  147199. +*
  147200. +* You should have received a copy of the GNU General Public License
  147201. +* along with this program; if not write to the Free Software
  147202. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  147203. +*
  147204. +*****************************************************************************/
  147205. +
  147206. +
  147207. +#ifndef __gc_hal_engine_vg_h_
  147208. +#define __gc_hal_engine_vg_h_
  147209. +
  147210. +#ifdef __cplusplus
  147211. +extern "C" {
  147212. +#endif
  147213. +
  147214. +#include "gc_hal_types.h"
  147215. +
  147216. +/******************************************************************************\
  147217. +******************************** VG Enumerations *******************************
  147218. +\******************************************************************************/
  147219. +
  147220. +/**
  147221. +** @ingroup gcoVG
  147222. +**
  147223. +** @brief Tiling mode for painting and imagig.
  147224. +**
  147225. +** This enumeration defines the tiling modes supported by the HAL. This is
  147226. +** in fact a one-to-one mapping of the OpenVG 1.1 tile modes.
  147227. +*/
  147228. +typedef enum _gceTILE_MODE
  147229. +{
  147230. + gcvTILE_FILL,
  147231. + gcvTILE_PAD,
  147232. + gcvTILE_REPEAT,
  147233. + gcvTILE_REFLECT
  147234. +}
  147235. +gceTILE_MODE;
  147236. +
  147237. +/******************************************************************************/
  147238. +/** @ingroup gcoVG
  147239. +**
  147240. +** @brief The different paint modes.
  147241. +**
  147242. +** This enumeration lists the available paint modes.
  147243. +*/
  147244. +typedef enum _gcePAINT_TYPE
  147245. +{
  147246. + /** Solid color. */
  147247. + gcvPAINT_MODE_SOLID,
  147248. +
  147249. + /** Linear gradient. */
  147250. + gcvPAINT_MODE_LINEAR,
  147251. +
  147252. + /** Radial gradient. */
  147253. + gcvPAINT_MODE_RADIAL,
  147254. +
  147255. + /** Pattern. */
  147256. + gcvPAINT_MODE_PATTERN,
  147257. +
  147258. + /** Mode count. */
  147259. + gcvPAINT_MODE_COUNT
  147260. +}
  147261. +gcePAINT_TYPE;
  147262. +
  147263. +/**
  147264. +** @ingroup gcoVG
  147265. +**
  147266. +** @brief Types of path data supported by HAL.
  147267. +**
  147268. +** This enumeration defines the types of path data supported by the HAL.
  147269. +** This is in fact a one-to-one mapping of the OpenVG 1.1 path types.
  147270. +*/
  147271. +typedef enum _gcePATHTYPE
  147272. +{
  147273. + gcePATHTYPE_UNKNOWN = -1,
  147274. + gcePATHTYPE_INT8,
  147275. + gcePATHTYPE_INT16,
  147276. + gcePATHTYPE_INT32,
  147277. + gcePATHTYPE_FLOAT
  147278. +}
  147279. +gcePATHTYPE;
  147280. +
  147281. +/**
  147282. +** @ingroup gcoVG
  147283. +**
  147284. +** @brief Supported path segment commands.
  147285. +**
  147286. +** This enumeration defines the path segment commands supported by the HAL.
  147287. +*/
  147288. +typedef enum _gceVGCMD
  147289. +{
  147290. + gcvVGCMD_END, /* 0: GCCMD_TS_OPCODE_END */
  147291. + gcvVGCMD_CLOSE, /* 1: GCCMD_TS_OPCODE_CLOSE */
  147292. + gcvVGCMD_MOVE, /* 2: GCCMD_TS_OPCODE_MOVE */
  147293. + gcvVGCMD_MOVE_REL, /* 3: GCCMD_TS_OPCODE_MOVE_REL */
  147294. + gcvVGCMD_LINE, /* 4: GCCMD_TS_OPCODE_LINE */
  147295. + gcvVGCMD_LINE_REL, /* 5: GCCMD_TS_OPCODE_LINE_REL */
  147296. + gcvVGCMD_QUAD, /* 6: GCCMD_TS_OPCODE_QUADRATIC */
  147297. + gcvVGCMD_QUAD_REL, /* 7: GCCMD_TS_OPCODE_QUADRATIC_REL */
  147298. + gcvVGCMD_CUBIC, /* 8: GCCMD_TS_OPCODE_CUBIC */
  147299. + gcvVGCMD_CUBIC_REL, /* 9: GCCMD_TS_OPCODE_CUBIC_REL */
  147300. + gcvVGCMD_BREAK, /* 10: GCCMD_TS_OPCODE_BREAK */
  147301. + gcvVGCMD_HLINE, /* 11: ******* R E S E R V E D *******/
  147302. + gcvVGCMD_HLINE_REL, /* 12: ******* R E S E R V E D *******/
  147303. + gcvVGCMD_VLINE, /* 13: ******* R E S E R V E D *******/
  147304. + gcvVGCMD_VLINE_REL, /* 14: ******* R E S E R V E D *******/
  147305. + gcvVGCMD_SQUAD, /* 15: ******* R E S E R V E D *******/
  147306. + gcvVGCMD_SQUAD_REL, /* 16: ******* R E S E R V E D *******/
  147307. + gcvVGCMD_SCUBIC, /* 17: ******* R E S E R V E D *******/
  147308. + gcvVGCMD_SCUBIC_REL, /* 18: ******* R E S E R V E D *******/
  147309. + gcvVGCMD_SCCWARC, /* 19: ******* R E S E R V E D *******/
  147310. + gcvVGCMD_SCCWARC_REL, /* 20: ******* R E S E R V E D *******/
  147311. + gcvVGCMD_SCWARC, /* 21: ******* R E S E R V E D *******/
  147312. + gcvVGCMD_SCWARC_REL, /* 22: ******* R E S E R V E D *******/
  147313. + gcvVGCMD_LCCWARC, /* 23: ******* R E S E R V E D *******/
  147314. + gcvVGCMD_LCCWARC_REL, /* 24: ******* R E S E R V E D *******/
  147315. + gcvVGCMD_LCWARC, /* 25: ******* R E S E R V E D *******/
  147316. + gcvVGCMD_LCWARC_REL, /* 26: ******* R E S E R V E D *******/
  147317. +
  147318. + /* The width of the command recognized by the hardware on bits. */
  147319. + gcvVGCMD_WIDTH = 5,
  147320. +
  147321. + /* Hardware command mask. */
  147322. + gcvVGCMD_MASK = (1 << gcvVGCMD_WIDTH) - 1,
  147323. +
  147324. + /* Command modifiers. */
  147325. + gcvVGCMD_H_MOD = 1 << gcvVGCMD_WIDTH, /* = 32 */
  147326. + gcvVGCMD_V_MOD = 2 << gcvVGCMD_WIDTH, /* = 64 */
  147327. + gcvVGCMD_S_MOD = 3 << gcvVGCMD_WIDTH, /* = 96 */
  147328. + gcvVGCMD_ARC_MOD = 4 << gcvVGCMD_WIDTH, /* = 128 */
  147329. +
  147330. + /* Emulated LINE commands. */
  147331. + gcvVGCMD_HLINE_EMUL = gcvVGCMD_H_MOD | gcvVGCMD_LINE, /* = 36 */
  147332. + gcvVGCMD_HLINE_EMUL_REL = gcvVGCMD_H_MOD | gcvVGCMD_LINE_REL, /* = 37 */
  147333. + gcvVGCMD_VLINE_EMUL = gcvVGCMD_V_MOD | gcvVGCMD_LINE, /* = 68 */
  147334. + gcvVGCMD_VLINE_EMUL_REL = gcvVGCMD_V_MOD | gcvVGCMD_LINE_REL, /* = 69 */
  147335. +
  147336. + /* Emulated SMOOTH commands. */
  147337. + gcvVGCMD_SQUAD_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD, /* = 102 */
  147338. + gcvVGCMD_SQUAD_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_QUAD_REL, /* = 103 */
  147339. + gcvVGCMD_SCUBIC_EMUL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC, /* = 104 */
  147340. + gcvVGCMD_SCUBIC_EMUL_REL = gcvVGCMD_S_MOD | gcvVGCMD_CUBIC_REL, /* = 105 */
  147341. +
  147342. + /* Emulation ARC commands. */
  147343. + gcvVGCMD_ARC_LINE = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE, /* = 132 */
  147344. + gcvVGCMD_ARC_LINE_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_LINE_REL, /* = 133 */
  147345. + gcvVGCMD_ARC_QUAD = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD, /* = 134 */
  147346. + gcvVGCMD_ARC_QUAD_REL = gcvVGCMD_ARC_MOD | gcvVGCMD_QUAD_REL /* = 135 */
  147347. +}
  147348. +gceVGCMD;
  147349. +typedef enum _gceVGCMD * gceVGCMD_PTR;
  147350. +
  147351. +/**
  147352. +** @ingroup gcoVG
  147353. +**
  147354. +** @brief Blending modes supported by the HAL.
  147355. +**
  147356. +** This enumeration defines the blending modes supported by the HAL. This is
  147357. +** in fact a one-to-one mapping of the OpenVG 1.1 blending modes.
  147358. +*/
  147359. +typedef enum _gceVG_BLEND
  147360. +{
  147361. + gcvVG_BLEND_SRC,
  147362. + gcvVG_BLEND_SRC_OVER,
  147363. + gcvVG_BLEND_DST_OVER,
  147364. + gcvVG_BLEND_SRC_IN,
  147365. + gcvVG_BLEND_DST_IN,
  147366. + gcvVG_BLEND_MULTIPLY,
  147367. + gcvVG_BLEND_SCREEN,
  147368. + gcvVG_BLEND_DARKEN,
  147369. + gcvVG_BLEND_LIGHTEN,
  147370. + gcvVG_BLEND_ADDITIVE,
  147371. + gcvVG_BLEND_SUBTRACT,
  147372. + gcvVG_BLEND_FILTER
  147373. +}
  147374. +gceVG_BLEND;
  147375. +
  147376. +/**
  147377. +** @ingroup gcoVG
  147378. +**
  147379. +** @brief Image modes supported by the HAL.
  147380. +**
  147381. +** This enumeration defines the image modes supported by the HAL. This is
  147382. +** in fact a one-to-one mapping of the OpenVG 1.1 image modes with the addition
  147383. +** of NO IMAGE.
  147384. +*/
  147385. +typedef enum _gceVG_IMAGE
  147386. +{
  147387. + gcvVG_IMAGE_NONE,
  147388. + gcvVG_IMAGE_NORMAL,
  147389. + gcvVG_IMAGE_MULTIPLY,
  147390. + gcvVG_IMAGE_STENCIL,
  147391. + gcvVG_IMAGE_FILTER
  147392. +}
  147393. +gceVG_IMAGE;
  147394. +
  147395. +/**
  147396. +** @ingroup gcoVG
  147397. +**
  147398. +** @brief Filter mode patterns and imaging.
  147399. +**
  147400. +** This enumeration defines the filter modes supported by the HAL.
  147401. +*/
  147402. +typedef enum _gceIMAGE_FILTER
  147403. +{
  147404. + gcvFILTER_POINT,
  147405. + gcvFILTER_LINEAR,
  147406. + gcvFILTER_BI_LINEAR
  147407. +}
  147408. +gceIMAGE_FILTER;
  147409. +
  147410. +/**
  147411. +** @ingroup gcoVG
  147412. +**
  147413. +** @brief Primitive modes supported by the HAL.
  147414. +**
  147415. +** This enumeration defines the primitive modes supported by the HAL.
  147416. +*/
  147417. +typedef enum _gceVG_PRIMITIVE
  147418. +{
  147419. + gcvVG_SCANLINE,
  147420. + gcvVG_RECTANGLE,
  147421. + gcvVG_TESSELLATED,
  147422. + gcvVG_TESSELLATED_TILED
  147423. +}
  147424. +gceVG_PRIMITIVE;
  147425. +
  147426. +/**
  147427. +** @ingroup gcoVG
  147428. +**
  147429. +** @brief Rendering quality modes supported by the HAL.
  147430. +**
  147431. +** This enumeration defines the rendering quality modes supported by the HAL.
  147432. +*/
  147433. +typedef enum _gceRENDER_QUALITY
  147434. +{
  147435. + gcvVG_NONANTIALIASED,
  147436. + gcvVG_2X2_MSAA,
  147437. + gcvVG_2X4_MSAA,
  147438. + gcvVG_4X4_MSAA
  147439. +}
  147440. +gceRENDER_QUALITY;
  147441. +
  147442. +/**
  147443. +** @ingroup gcoVG
  147444. +**
  147445. +** @brief Fill rules supported by the HAL.
  147446. +**
  147447. +** This enumeration defines the fill rules supported by the HAL.
  147448. +*/
  147449. +typedef enum _gceFILL_RULE
  147450. +{
  147451. + gcvVG_EVEN_ODD,
  147452. + gcvVG_NON_ZERO
  147453. +}
  147454. +gceFILL_RULE;
  147455. +
  147456. +/**
  147457. +** @ingroup gcoVG
  147458. +**
  147459. +** @brief Cap styles supported by the HAL.
  147460. +**
  147461. +** This enumeration defines the cap styles supported by the HAL.
  147462. +*/
  147463. +typedef enum _gceCAP_STYLE
  147464. +{
  147465. + gcvCAP_BUTT,
  147466. + gcvCAP_ROUND,
  147467. + gcvCAP_SQUARE
  147468. +}
  147469. +gceCAP_STYLE;
  147470. +
  147471. +/**
  147472. +** @ingroup gcoVG
  147473. +**
  147474. +** @brief Join styles supported by the HAL.
  147475. +**
  147476. +** This enumeration defines the join styles supported by the HAL.
  147477. +*/
  147478. +typedef enum _gceJOIN_STYLE
  147479. +{
  147480. + gcvJOIN_MITER,
  147481. + gcvJOIN_ROUND,
  147482. + gcvJOIN_BEVEL
  147483. +}
  147484. +gceJOIN_STYLE;
  147485. +
  147486. +/**
  147487. +** @ingroup gcoVG
  147488. +**
  147489. +** @brief Channel mask values.
  147490. +**
  147491. +** This enumeration defines the values for channel mask used in image
  147492. +** filtering.
  147493. +*/
  147494. +
  147495. +/* Base values for channel mask definitions. */
  147496. +#define gcvCHANNEL_X (0)
  147497. +#define gcvCHANNEL_R (1 << 0)
  147498. +#define gcvCHANNEL_G (1 << 1)
  147499. +#define gcvCHANNEL_B (1 << 2)
  147500. +#define gcvCHANNEL_A (1 << 3)
  147501. +
  147502. +typedef enum _gceCHANNEL
  147503. +{
  147504. + gcvCHANNEL_XXXX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
  147505. + gcvCHANNEL_XXXA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
  147506. + gcvCHANNEL_XXBX = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
  147507. + gcvCHANNEL_XXBA = (gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
  147508. +
  147509. + gcvCHANNEL_XGXX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
  147510. + gcvCHANNEL_XGXA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
  147511. + gcvCHANNEL_XGBX = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
  147512. + gcvCHANNEL_XGBA = (gcvCHANNEL_X | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
  147513. +
  147514. + gcvCHANNEL_RXXX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_X),
  147515. + gcvCHANNEL_RXXA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_X | gcvCHANNEL_A),
  147516. + gcvCHANNEL_RXBX = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_X),
  147517. + gcvCHANNEL_RXBA = (gcvCHANNEL_R | gcvCHANNEL_X | gcvCHANNEL_B | gcvCHANNEL_A),
  147518. +
  147519. + gcvCHANNEL_RGXX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_X),
  147520. + gcvCHANNEL_RGXA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_X | gcvCHANNEL_A),
  147521. + gcvCHANNEL_RGBX = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_X),
  147522. + gcvCHANNEL_RGBA = (gcvCHANNEL_R | gcvCHANNEL_G | gcvCHANNEL_B | gcvCHANNEL_A),
  147523. +}
  147524. +gceCHANNEL;
  147525. +
  147526. +/******************************************************************************\
  147527. +******************************** VG Structures *******************************
  147528. +\******************************************************************************/
  147529. +
  147530. +/**
  147531. +** @ingroup gcoVG
  147532. +**
  147533. +** @brief Definition of the color ramp used by the gradient paints.
  147534. +**
  147535. +** The gcsCOLOR_RAMP structure defines the layout of one single color inside
  147536. +** a color ramp which is used by gradient paints.
  147537. +*/
  147538. +typedef struct _gcsCOLOR_RAMP
  147539. +{
  147540. + /** Value for the color stop. */
  147541. + gctFLOAT stop;
  147542. +
  147543. + /** Red color channel value for the color stop. */
  147544. + gctFLOAT red;
  147545. +
  147546. + /** Green color channel value for the color stop. */
  147547. + gctFLOAT green;
  147548. +
  147549. + /** Blue color channel value for the color stop. */
  147550. + gctFLOAT blue;
  147551. +
  147552. + /** Alpha color channel value for the color stop. */
  147553. + gctFLOAT alpha;
  147554. +}
  147555. +gcsCOLOR_RAMP, * gcsCOLOR_RAMP_PTR;
  147556. +
  147557. +/**
  147558. +** @ingroup gcoVG
  147559. +**
  147560. +** @brief Definition of the color ramp used by the gradient paints in fixed form.
  147561. +**
  147562. +** The gcsCOLOR_RAMP structure defines the layout of one single color inside
  147563. +** a color ramp which is used by gradient paints.
  147564. +*/
  147565. +typedef struct _gcsFIXED_COLOR_RAMP
  147566. +{
  147567. + /** Value for the color stop. */
  147568. + gctFIXED_POINT stop;
  147569. +
  147570. + /** Red color channel value for the color stop. */
  147571. + gctFIXED_POINT red;
  147572. +
  147573. + /** Green color channel value for the color stop. */
  147574. + gctFIXED_POINT green;
  147575. +
  147576. + /** Blue color channel value for the color stop. */
  147577. + gctFIXED_POINT blue;
  147578. +
  147579. + /** Alpha color channel value for the color stop. */
  147580. + gctFIXED_POINT alpha;
  147581. +}
  147582. +gcsFIXED_COLOR_RAMP, * gcsFIXED_COLOR_RAMP_PTR;
  147583. +
  147584. +
  147585. +/**
  147586. +** @ingroup gcoVG
  147587. +**
  147588. +** @brief Rectangle structure used by the gcoVG object.
  147589. +**
  147590. +** This structure defines the layout of a rectangle. Make sure width and
  147591. +** height are larger than 0.
  147592. +*/
  147593. +typedef struct _gcsVG_RECT * gcsVG_RECT_PTR;
  147594. +typedef struct _gcsVG_RECT
  147595. +{
  147596. + /** Left location of the rectangle. */
  147597. + gctINT x;
  147598. +
  147599. + /** Top location of the rectangle. */
  147600. + gctINT y;
  147601. +
  147602. + /** Width of the rectangle. */
  147603. + gctINT width;
  147604. +
  147605. + /** Height of the rectangle. */
  147606. + gctINT height;
  147607. +}
  147608. +gcsVG_RECT;
  147609. +
  147610. +/**
  147611. +** @ingroup gcoVG
  147612. +**
  147613. +** @brief Path command buffer attribute structure.
  147614. +**
  147615. +** The gcsPATH_BUFFER_INFO structure contains the specifics about
  147616. +** the layout of the path data command buffer.
  147617. +*/
  147618. +typedef struct _gcsPATH_BUFFER_INFO * gcsPATH_BUFFER_INFO_PTR;
  147619. +typedef struct _gcsPATH_BUFFER_INFO
  147620. +{
  147621. + gctUINT reservedForHead;
  147622. + gctUINT reservedForTail;
  147623. +}
  147624. +gcsPATH_BUFFER_INFO;
  147625. +
  147626. +/**
  147627. +** @ingroup gcoVG
  147628. +**
  147629. +** @brief Definition of the path data container structure.
  147630. +**
  147631. +** The gcsPATH structure defines the layout of the path data container.
  147632. +*/
  147633. +typedef struct _gcsPATH_DATA * gcsPATH_DATA_PTR;
  147634. +typedef struct _gcsPATH_DATA
  147635. +{
  147636. + /* Data container in command buffer format. */
  147637. + gcsCMDBUFFER data;
  147638. +
  147639. + /* Path data type. */
  147640. + gcePATHTYPE dataType;
  147641. +}
  147642. +gcsPATH_DATA;
  147643. +
  147644. +
  147645. +/******************************************************************************\
  147646. +********************************* gcoHAL Object ********************************
  147647. +\******************************************************************************/
  147648. +
  147649. +/* Query path data storage attributes. */
  147650. +gceSTATUS
  147651. +gcoHAL_QueryPathStorage(
  147652. + IN gcoHAL Hal,
  147653. + OUT gcsPATH_BUFFER_INFO_PTR Information
  147654. + );
  147655. +
  147656. +/* Associate a completion signal with the command buffer. */
  147657. +gceSTATUS
  147658. +gcoHAL_AssociateCompletion(
  147659. + IN gcoHAL Hal,
  147660. + IN gcsPATH_DATA_PTR PathData
  147661. + );
  147662. +
  147663. +/* Release the current command buffer completion signal. */
  147664. +gceSTATUS
  147665. +gcoHAL_DeassociateCompletion(
  147666. + IN gcoHAL Hal,
  147667. + IN gcsPATH_DATA_PTR PathData
  147668. + );
  147669. +
  147670. +/* Verify whether the command buffer is still in use. */
  147671. +gceSTATUS
  147672. +gcoHAL_CheckCompletion(
  147673. + IN gcoHAL Hal,
  147674. + IN gcsPATH_DATA_PTR PathData
  147675. + );
  147676. +
  147677. +/* Wait until the command buffer is no longer in use. */
  147678. +gceSTATUS
  147679. +gcoHAL_WaitCompletion(
  147680. + IN gcoHAL Hal,
  147681. + IN gcsPATH_DATA_PTR PathData
  147682. + );
  147683. +
  147684. +/* Flush the pixel cache. */
  147685. +gceSTATUS
  147686. +gcoHAL_Flush(
  147687. + IN gcoHAL Hal
  147688. + );
  147689. +
  147690. +/* Split a harwdare address into pool and offset. */
  147691. +gceSTATUS
  147692. +gcoHAL_SplitAddress(
  147693. + IN gcoHAL Hal,
  147694. + IN gctUINT32 Address,
  147695. + OUT gcePOOL * Pool,
  147696. + OUT gctUINT32 * Offset
  147697. + );
  147698. +
  147699. +/* Combine pool and offset into a harwdare address. */
  147700. +gceSTATUS
  147701. +gcoHAL_CombineAddress(
  147702. + IN gcoHAL Hal,
  147703. + IN gcePOOL Pool,
  147704. + IN gctUINT32 Offset,
  147705. + OUT gctUINT32 * Address
  147706. + );
  147707. +
  147708. +/* Schedule to free linear video memory allocated. */
  147709. +gceSTATUS
  147710. +gcoHAL_ScheduleVideoMemory(
  147711. + IN gcoHAL Hal,
  147712. + IN gctUINT64 Node
  147713. + );
  147714. +
  147715. +/* Free linear video memory allocated with gcoHAL_AllocateLinearVideoMemory. */
  147716. +gceSTATUS
  147717. +gcoHAL_FreeVideoMemory(
  147718. + IN gcoHAL Hal,
  147719. + IN gctUINT64 Node
  147720. + );
  147721. +
  147722. +/* Query command buffer attributes. */
  147723. +gceSTATUS
  147724. +gcoHAL_QueryCommandBuffer(
  147725. + IN gcoHAL Hal,
  147726. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  147727. + );
  147728. +/* Allocate and lock linear video memory. */
  147729. +gceSTATUS
  147730. +gcoHAL_AllocateLinearVideoMemory(
  147731. + IN gcoHAL Hal,
  147732. + IN gctUINT Size,
  147733. + IN gctUINT Alignment,
  147734. + IN gcePOOL Pool,
  147735. + OUT gctUINT64 * Node,
  147736. + OUT gctUINT32 * Address,
  147737. + OUT gctPOINTER * Memory
  147738. + );
  147739. +
  147740. +/* Align the specified size accordingly to the hardware requirements. */
  147741. +gceSTATUS
  147742. +gcoHAL_GetAlignedSurfaceSize(
  147743. + IN gcoHAL Hal,
  147744. + IN gceSURF_TYPE Type,
  147745. + IN OUT gctUINT32_PTR Width,
  147746. + IN OUT gctUINT32_PTR Height
  147747. + );
  147748. +
  147749. +gceSTATUS
  147750. +gcoHAL_ReserveTask(
  147751. + IN gcoHAL Hal,
  147752. + IN gceBLOCK Block,
  147753. + IN gctUINT TaskCount,
  147754. + IN gctSIZE_T Bytes,
  147755. + OUT gctPOINTER * Memory
  147756. + );
  147757. +/******************************************************************************\
  147758. +********************************** gcoVG Object ********************************
  147759. +\******************************************************************************/
  147760. +
  147761. +/** @defgroup gcoVG gcoVG
  147762. +**
  147763. +** The gcoVG object abstracts the VG hardware pipe.
  147764. +*/
  147765. +
  147766. +gctBOOL
  147767. +gcoVG_IsMaskSupported(
  147768. + IN gceSURF_FORMAT Format
  147769. + );
  147770. +
  147771. +gctBOOL
  147772. +gcoVG_IsTargetSupported(
  147773. + IN gceSURF_FORMAT Format
  147774. + );
  147775. +
  147776. +gctBOOL
  147777. +gcoVG_IsImageSupported(
  147778. + IN gceSURF_FORMAT Format
  147779. + );
  147780. +
  147781. +gctUINT8 gcoVG_PackColorComponent(
  147782. + gctFLOAT Value
  147783. + );
  147784. +
  147785. +gceSTATUS
  147786. +gcoVG_Construct(
  147787. + IN gcoHAL Hal,
  147788. + OUT gcoVG * Vg
  147789. + );
  147790. +
  147791. +gceSTATUS
  147792. +gcoVG_Destroy(
  147793. + IN gcoVG Vg
  147794. + );
  147795. +
  147796. +gceSTATUS
  147797. +gcoVG_SetTarget(
  147798. + IN gcoVG Vg,
  147799. + IN gcoSURF Target
  147800. + );
  147801. +
  147802. +gceSTATUS
  147803. +gcoVG_UnsetTarget(
  147804. + IN gcoVG Vg,
  147805. + IN gcoSURF Surface
  147806. + );
  147807. +
  147808. +gceSTATUS
  147809. +gcoVG_SetUserToSurface(
  147810. + IN gcoVG Vg,
  147811. + IN gctFLOAT UserToSurface[9]
  147812. + );
  147813. +
  147814. +gceSTATUS
  147815. +gcoVG_SetSurfaceToImage(
  147816. + IN gcoVG Vg,
  147817. + IN gctFLOAT SurfaceToImage[9]
  147818. + );
  147819. +
  147820. +gceSTATUS
  147821. +gcoVG_EnableMask(
  147822. + IN gcoVG Vg,
  147823. + IN gctBOOL Enable
  147824. + );
  147825. +
  147826. +gceSTATUS
  147827. +gcoVG_SetMask(
  147828. + IN gcoVG Vg,
  147829. + IN gcoSURF Mask
  147830. + );
  147831. +
  147832. +gceSTATUS
  147833. +gcoVG_UnsetMask(
  147834. + IN gcoVG Vg,
  147835. + IN gcoSURF Surface
  147836. + );
  147837. +
  147838. +gceSTATUS
  147839. +gcoVG_FlushMask(
  147840. + IN gcoVG Vg
  147841. + );
  147842. +
  147843. +gceSTATUS
  147844. +gcoVG_EnableScissor(
  147845. + IN gcoVG Vg,
  147846. + IN gctBOOL Enable
  147847. + );
  147848. +
  147849. +gceSTATUS
  147850. +gcoVG_SetScissor(
  147851. + IN gcoVG Vg,
  147852. + IN gctSIZE_T RectangleCount,
  147853. + IN gcsVG_RECT_PTR Rectangles
  147854. + );
  147855. +
  147856. +gceSTATUS
  147857. +gcoVG_EnableColorTransform(
  147858. + IN gcoVG Vg,
  147859. + IN gctBOOL Enable
  147860. + );
  147861. +
  147862. +gceSTATUS
  147863. +gcoVG_SetColorTransform(
  147864. + IN gcoVG Vg,
  147865. + IN gctFLOAT ColorTransform[8]
  147866. + );
  147867. +
  147868. +gceSTATUS
  147869. +gcoVG_SetTileFillColor(
  147870. + IN gcoVG Vg,
  147871. + IN gctFLOAT Red,
  147872. + IN gctFLOAT Green,
  147873. + IN gctFLOAT Blue,
  147874. + IN gctFLOAT Alpha
  147875. + );
  147876. +
  147877. +gceSTATUS
  147878. +gcoVG_SetSolidPaint(
  147879. + IN gcoVG Vg,
  147880. + IN gctUINT8 Red,
  147881. + IN gctUINT8 Green,
  147882. + IN gctUINT8 Blue,
  147883. + IN gctUINT8 Alpha
  147884. + );
  147885. +
  147886. +gceSTATUS
  147887. +gcoVG_SetLinearPaint(
  147888. + IN gcoVG Vg,
  147889. + IN gctFLOAT Constant,
  147890. + IN gctFLOAT StepX,
  147891. + IN gctFLOAT StepY
  147892. + );
  147893. +
  147894. +gceSTATUS
  147895. +gcoVG_SetRadialPaint(
  147896. + IN gcoVG Vg,
  147897. + IN gctFLOAT LinConstant,
  147898. + IN gctFLOAT LinStepX,
  147899. + IN gctFLOAT LinStepY,
  147900. + IN gctFLOAT RadConstant,
  147901. + IN gctFLOAT RadStepX,
  147902. + IN gctFLOAT RadStepY,
  147903. + IN gctFLOAT RadStepXX,
  147904. + IN gctFLOAT RadStepYY,
  147905. + IN gctFLOAT RadStepXY
  147906. + );
  147907. +
  147908. +gceSTATUS
  147909. +gcoVG_SetPatternPaint(
  147910. + IN gcoVG Vg,
  147911. + IN gctFLOAT UConstant,
  147912. + IN gctFLOAT UStepX,
  147913. + IN gctFLOAT UStepY,
  147914. + IN gctFLOAT VConstant,
  147915. + IN gctFLOAT VStepX,
  147916. + IN gctFLOAT VStepY,
  147917. + IN gctBOOL Linear
  147918. + );
  147919. +
  147920. +gceSTATUS
  147921. +gcoVG_SetColorRamp(
  147922. + IN gcoVG Vg,
  147923. + IN gcoSURF ColorRamp,
  147924. + IN gceTILE_MODE ColorRampSpreadMode
  147925. + );
  147926. +
  147927. +gceSTATUS
  147928. +gcoVG_SetPattern(
  147929. + IN gcoVG Vg,
  147930. + IN gcoSURF Pattern,
  147931. + IN gceTILE_MODE TileMode,
  147932. + IN gceIMAGE_FILTER Filter
  147933. + );
  147934. +
  147935. +gceSTATUS
  147936. +gcoVG_SetImageMode(
  147937. + IN gcoVG Vg,
  147938. + IN gceVG_IMAGE Mode
  147939. + );
  147940. +
  147941. +gceSTATUS
  147942. +gcoVG_SetBlendMode(
  147943. + IN gcoVG Vg,
  147944. + IN gceVG_BLEND Mode
  147945. + );
  147946. +
  147947. +gceSTATUS
  147948. +gcoVG_SetRenderingQuality(
  147949. + IN gcoVG Vg,
  147950. + IN gceRENDER_QUALITY Quality
  147951. + );
  147952. +
  147953. +gceSTATUS
  147954. +gcoVG_SetFillRule(
  147955. + IN gcoVG Vg,
  147956. + IN gceFILL_RULE FillRule
  147957. + );
  147958. +
  147959. +gceSTATUS
  147960. +gcoVG_FinalizePath(
  147961. + IN gcoVG Vg,
  147962. + IN gcsPATH_DATA_PTR PathData
  147963. + );
  147964. +
  147965. +gceSTATUS
  147966. +gcoVG_Clear(
  147967. + IN gcoVG Vg,
  147968. + IN gctINT X,
  147969. + IN gctINT Y,
  147970. + IN gctINT Width,
  147971. + IN gctINT Height
  147972. + );
  147973. +
  147974. +gceSTATUS
  147975. +gcoVG_DrawPath(
  147976. + IN gcoVG Vg,
  147977. + IN gcsPATH_DATA_PTR PathData,
  147978. + IN gctFLOAT Scale,
  147979. + IN gctFLOAT Bias,
  147980. + IN gctBOOL SoftwareTesselation
  147981. + );
  147982. +
  147983. +gceSTATUS
  147984. +gcoVG_DrawImage(
  147985. + IN gcoVG Vg,
  147986. + IN gcoSURF Source,
  147987. + IN gcsPOINT_PTR SourceOrigin,
  147988. + IN gcsPOINT_PTR TargetOrigin,
  147989. + IN gcsSIZE_PTR SourceSize,
  147990. + IN gctINT SourceX,
  147991. + IN gctINT SourceY,
  147992. + IN gctINT TargetX,
  147993. + IN gctINT TargetY,
  147994. + IN gctINT Width,
  147995. + IN gctINT Height,
  147996. + IN gctBOOL Mask
  147997. + );
  147998. +
  147999. +gceSTATUS
  148000. +gcoVG_TesselateImage(
  148001. + IN gcoVG Vg,
  148002. + IN gcoSURF Image,
  148003. + IN gcsVG_RECT_PTR Rectangle,
  148004. + IN gceIMAGE_FILTER Filter,
  148005. + IN gctBOOL Mask,
  148006. + IN gctBOOL SoftwareTesselation
  148007. + );
  148008. +
  148009. +gceSTATUS
  148010. +gcoVG_Blit(
  148011. + IN gcoVG Vg,
  148012. + IN gcoSURF Source,
  148013. + IN gcoSURF Target,
  148014. + IN gcsVG_RECT_PTR SrcRect,
  148015. + IN gcsVG_RECT_PTR TrgRect,
  148016. + IN gceIMAGE_FILTER Filter,
  148017. + IN gceVG_BLEND Mode
  148018. + );
  148019. +
  148020. +gceSTATUS
  148021. +gcoVG_ColorMatrix(
  148022. + IN gcoVG Vg,
  148023. + IN gcoSURF Source,
  148024. + IN gcoSURF Target,
  148025. + IN const gctFLOAT * Matrix,
  148026. + IN gceCHANNEL ColorChannels,
  148027. + IN gctBOOL FilterLinear,
  148028. + IN gctBOOL FilterPremultiplied,
  148029. + IN gcsPOINT_PTR SourceOrigin,
  148030. + IN gcsPOINT_PTR TargetOrigin,
  148031. + IN gctINT Width,
  148032. + IN gctINT Height
  148033. + );
  148034. +
  148035. +gceSTATUS
  148036. +gcoVG_SeparableConvolve(
  148037. + IN gcoVG Vg,
  148038. + IN gcoSURF Source,
  148039. + IN gcoSURF Target,
  148040. + IN gctINT KernelWidth,
  148041. + IN gctINT KernelHeight,
  148042. + IN gctINT ShiftX,
  148043. + IN gctINT ShiftY,
  148044. + IN const gctINT16 * KernelX,
  148045. + IN const gctINT16 * KernelY,
  148046. + IN gctFLOAT Scale,
  148047. + IN gctFLOAT Bias,
  148048. + IN gceTILE_MODE TilingMode,
  148049. + IN gctFLOAT_PTR FillColor,
  148050. + IN gceCHANNEL ColorChannels,
  148051. + IN gctBOOL FilterLinear,
  148052. + IN gctBOOL FilterPremultiplied,
  148053. + IN gcsPOINT_PTR SourceOrigin,
  148054. + IN gcsPOINT_PTR TargetOrigin,
  148055. + IN gcsSIZE_PTR SourceSize,
  148056. + IN gctINT Width,
  148057. + IN gctINT Height
  148058. + );
  148059. +
  148060. +gceSTATUS
  148061. +gcoVG_GaussianBlur(
  148062. + IN gcoVG Vg,
  148063. + IN gcoSURF Source,
  148064. + IN gcoSURF Target,
  148065. + IN gctFLOAT StdDeviationX,
  148066. + IN gctFLOAT StdDeviationY,
  148067. + IN gceTILE_MODE TilingMode,
  148068. + IN gctFLOAT_PTR FillColor,
  148069. + IN gceCHANNEL ColorChannels,
  148070. + IN gctBOOL FilterLinear,
  148071. + IN gctBOOL FilterPremultiplied,
  148072. + IN gcsPOINT_PTR SourceOrigin,
  148073. + IN gcsPOINT_PTR TargetOrigin,
  148074. + IN gcsSIZE_PTR SourceSize,
  148075. + IN gctINT Width,
  148076. + IN gctINT Height
  148077. + );
  148078. +
  148079. +gceSTATUS
  148080. +gcoVG_EnableDither(
  148081. + IN gcoVG Vg,
  148082. + IN gctBOOL Enable
  148083. + );
  148084. +
  148085. +#ifdef __cplusplus
  148086. +}
  148087. +#endif
  148088. +
  148089. +#endif /* __gc_hal_vg_h_ */
  148090. diff -Nur linux-3.14.17/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
  148091. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h 1970-01-01 01:00:00.000000000 +0100
  148092. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h 2014-09-11 18:06:03.118042434 +0200
  148093. @@ -0,0 +1,965 @@
  148094. +/****************************************************************************
  148095. +*
  148096. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  148097. +*
  148098. +* This program is free software; you can redistribute it and/or modify
  148099. +* it under the terms of the GNU General Public License as published by
  148100. +* the Free Software Foundation; either version 2 of the license, or
  148101. +* (at your option) any later version.
  148102. +*
  148103. +* This program is distributed in the hope that it will be useful,
  148104. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  148105. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  148106. +* GNU General Public License for more details.
  148107. +*
  148108. +* You should have received a copy of the GNU General Public License
  148109. +* along with this program; if not write to the Free Software
  148110. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  148111. +*
  148112. +*****************************************************************************/
  148113. +
  148114. +
  148115. +#ifndef __gc_hal_enum_h_
  148116. +#define __gc_hal_enum_h_
  148117. +
  148118. +#ifdef __cplusplus
  148119. +extern "C" {
  148120. +#endif
  148121. +
  148122. +/* Chip models. */
  148123. +typedef enum _gceCHIPMODEL
  148124. +{
  148125. + gcv300 = 0x0300,
  148126. + gcv320 = 0x0320,
  148127. + gcv350 = 0x0350,
  148128. + gcv355 = 0x0355,
  148129. + gcv400 = 0x0400,
  148130. + gcv410 = 0x0410,
  148131. + gcv420 = 0x0420,
  148132. + gcv450 = 0x0450,
  148133. + gcv500 = 0x0500,
  148134. + gcv530 = 0x0530,
  148135. + gcv600 = 0x0600,
  148136. + gcv700 = 0x0700,
  148137. + gcv800 = 0x0800,
  148138. + gcv860 = 0x0860,
  148139. + gcv880 = 0x0880,
  148140. + gcv1000 = 0x1000,
  148141. + gcv2000 = 0x2000,
  148142. + gcv2100 = 0x2100,
  148143. + gcv4000 = 0x4000,
  148144. +}
  148145. +gceCHIPMODEL;
  148146. +
  148147. +/* Chip features. */
  148148. +typedef enum _gceFEATURE
  148149. +{
  148150. + gcvFEATURE_PIPE_2D = 0,
  148151. + gcvFEATURE_PIPE_3D,
  148152. + gcvFEATURE_PIPE_VG,
  148153. + gcvFEATURE_DC,
  148154. + gcvFEATURE_HIGH_DYNAMIC_RANGE,
  148155. + gcvFEATURE_MODULE_CG,
  148156. + gcvFEATURE_MIN_AREA,
  148157. + gcvFEATURE_BUFFER_INTERLEAVING,
  148158. + gcvFEATURE_BYTE_WRITE_2D,
  148159. + gcvFEATURE_ENDIANNESS_CONFIG,
  148160. + gcvFEATURE_DUAL_RETURN_BUS,
  148161. + gcvFEATURE_DEBUG_MODE,
  148162. + gcvFEATURE_YUY2_RENDER_TARGET,
  148163. + gcvFEATURE_FRAGMENT_PROCESSOR,
  148164. + gcvFEATURE_2DPE20,
  148165. + gcvFEATURE_FAST_CLEAR,
  148166. + gcvFEATURE_YUV420_TILER,
  148167. + gcvFEATURE_YUY2_AVERAGING,
  148168. + gcvFEATURE_FLIP_Y,
  148169. + gcvFEATURE_EARLY_Z,
  148170. + gcvFEATURE_Z_COMPRESSION,
  148171. + gcvFEATURE_MSAA,
  148172. + gcvFEATURE_SPECIAL_ANTI_ALIASING,
  148173. + gcvFEATURE_SPECIAL_MSAA_LOD,
  148174. + gcvFEATURE_422_TEXTURE_COMPRESSION,
  148175. + gcvFEATURE_DXT_TEXTURE_COMPRESSION,
  148176. + gcvFEATURE_ETC1_TEXTURE_COMPRESSION,
  148177. + gcvFEATURE_CORRECT_TEXTURE_CONVERTER,
  148178. + gcvFEATURE_TEXTURE_8K,
  148179. + gcvFEATURE_SCALER,
  148180. + gcvFEATURE_YUV420_SCALER,
  148181. + gcvFEATURE_SHADER_HAS_W,
  148182. + gcvFEATURE_SHADER_HAS_SIGN,
  148183. + gcvFEATURE_SHADER_HAS_FLOOR,
  148184. + gcvFEATURE_SHADER_HAS_CEIL,
  148185. + gcvFEATURE_SHADER_HAS_SQRT,
  148186. + gcvFEATURE_SHADER_HAS_TRIG,
  148187. + gcvFEATURE_VAA,
  148188. + gcvFEATURE_HZ,
  148189. + gcvFEATURE_CORRECT_STENCIL,
  148190. + gcvFEATURE_VG20,
  148191. + gcvFEATURE_VG_FILTER,
  148192. + gcvFEATURE_VG21,
  148193. + gcvFEATURE_VG_DOUBLE_BUFFER,
  148194. + gcvFEATURE_MC20,
  148195. + gcvFEATURE_SUPER_TILED,
  148196. + gcvFEATURE_2D_FILTERBLIT_PLUS_ALPHABLEND,
  148197. + gcvFEATURE_2D_DITHER,
  148198. + gcvFEATURE_2D_A8_TARGET,
  148199. + gcvFEATURE_2D_FILTERBLIT_FULLROTATION,
  148200. + gcvFEATURE_2D_BITBLIT_FULLROTATION,
  148201. + gcvFEATURE_WIDE_LINE,
  148202. + gcvFEATURE_FC_FLUSH_STALL,
  148203. + gcvFEATURE_FULL_DIRECTFB,
  148204. + gcvFEATURE_HALF_FLOAT_PIPE,
  148205. + gcvFEATURE_LINE_LOOP,
  148206. + gcvFEATURE_2D_YUV_BLIT,
  148207. + gcvFEATURE_2D_TILING,
  148208. + gcvFEATURE_NON_POWER_OF_TWO,
  148209. + gcvFEATURE_3D_TEXTURE,
  148210. + gcvFEATURE_TEXTURE_ARRAY,
  148211. + gcvFEATURE_TILE_FILLER,
  148212. + gcvFEATURE_LOGIC_OP,
  148213. + gcvFEATURE_COMPOSITION,
  148214. + gcvFEATURE_MIXED_STREAMS,
  148215. + gcvFEATURE_2D_MULTI_SOURCE_BLT,
  148216. + gcvFEATURE_END_EVENT,
  148217. + gcvFEATURE_VERTEX_10_10_10_2,
  148218. + gcvFEATURE_TEXTURE_10_10_10_2,
  148219. + gcvFEATURE_TEXTURE_ANISOTROPIC_FILTERING,
  148220. + gcvFEATURE_TEXTURE_FLOAT_HALF_FLOAT,
  148221. + gcvFEATURE_2D_ROTATION_STALL_FIX,
  148222. + gcvFEATURE_2D_MULTI_SOURCE_BLT_EX,
  148223. + gcvFEATURE_BUG_FIXES10,
  148224. + gcvFEATURE_2D_MINOR_TILING,
  148225. + /* Supertiled compressed textures are supported. */
  148226. + gcvFEATURE_TEX_COMPRRESSION_SUPERTILED,
  148227. + gcvFEATURE_FAST_MSAA,
  148228. + gcvFEATURE_BUG_FIXED_INDEXED_TRIANGLE_STRIP,
  148229. + gcvFEATURE_TEXTURE_TILED_READ,
  148230. + gcvFEATURE_DEPTH_BIAS_FIX,
  148231. + gcvFEATURE_RECT_PRIMITIVE,
  148232. + gcvFEATURE_BUG_FIXES11,
  148233. + gcvFEATURE_SUPERTILED_TEXTURE,
  148234. + gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
  148235. + gcvFEATURE_RS_YUV_TARGET,
  148236. + gcvFEATURE_2D_FC_SOURCE,
  148237. + gcvFEATURE_PE_DITHER_FIX,
  148238. + gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
  148239. + gcvFEATURE_FRUSTUM_CLIP_FIX,
  148240. + gcvFEATURE_TEXTURE_LINEAR,
  148241. + gcvFEATURE_TEXTURE_YUV_ASSEMBLER,
  148242. + gcvFEATURE_SHADER_HAS_INSTRUCTION_CACHE,
  148243. + gcvFEATURE_DYNAMIC_FREQUENCY_SCALING,
  148244. + gcvFEATURE_BUGFIX15,
  148245. + gcvFEATURE_2D_GAMMA,
  148246. + gcvFEATURE_2D_COLOR_SPACE_CONVERSION,
  148247. + gcvFEATURE_2D_SUPER_TILE_VERSION,
  148248. + gcvFEATURE_2D_MIRROR_EXTENSION,
  148249. + gcvFEATURE_2D_SUPER_TILE_V1,
  148250. + gcvFEATURE_2D_SUPER_TILE_V2,
  148251. + gcvFEATURE_2D_SUPER_TILE_V3,
  148252. + gcvFEATURE_2D_MULTI_SOURCE_BLT_EX2,
  148253. + gcvFEATURE_ELEMENT_INDEX_UINT,
  148254. + gcvFEATURE_2D_COMPRESSION,
  148255. + gcvFEATURE_2D_OPF_YUV_OUTPUT,
  148256. + gcvFEATURE_2D_MULTI_SRC_BLT_TO_UNIFIED_DST_RECT,
  148257. + gcvFEATURE_2D_YUV_MODE,
  148258. + gcvFEATURE_DECOMPRESS_Z16,
  148259. + gcvFEATURE_LINEAR_RENDER_TARGET,
  148260. + gcvFEATURE_BUG_FIXES8,
  148261. + gcvFEATURE_HALTI2,
  148262. + gcvFEATURE_MMU,
  148263. +}
  148264. +gceFEATURE;
  148265. +
  148266. +/* Chip Power Status. */
  148267. +typedef enum _gceCHIPPOWERSTATE
  148268. +{
  148269. + gcvPOWER_ON = 0,
  148270. + gcvPOWER_OFF,
  148271. + gcvPOWER_IDLE,
  148272. + gcvPOWER_SUSPEND,
  148273. + gcvPOWER_SUSPEND_ATPOWERON,
  148274. + gcvPOWER_OFF_ATPOWERON,
  148275. + gcvPOWER_IDLE_BROADCAST,
  148276. + gcvPOWER_SUSPEND_BROADCAST,
  148277. + gcvPOWER_OFF_BROADCAST,
  148278. + gcvPOWER_OFF_RECOVERY,
  148279. + gcvPOWER_OFF_TIMEOUT,
  148280. + gcvPOWER_ON_AUTO
  148281. +}
  148282. +gceCHIPPOWERSTATE;
  148283. +
  148284. +/* CPU cache operations */
  148285. +typedef enum _gceCACHEOPERATION
  148286. +{
  148287. + gcvCACHE_CLEAN = 0x01,
  148288. + gcvCACHE_INVALIDATE = 0x02,
  148289. + gcvCACHE_FLUSH = gcvCACHE_CLEAN | gcvCACHE_INVALIDATE,
  148290. + gcvCACHE_MEMORY_BARRIER = 0x04
  148291. +}
  148292. +gceCACHEOPERATION;
  148293. +
  148294. +/* Surface types. */
  148295. +typedef enum _gceSURF_TYPE
  148296. +{
  148297. + gcvSURF_TYPE_UNKNOWN = 0,
  148298. + gcvSURF_INDEX,
  148299. + gcvSURF_VERTEX,
  148300. + gcvSURF_TEXTURE,
  148301. + gcvSURF_RENDER_TARGET,
  148302. + gcvSURF_DEPTH,
  148303. + gcvSURF_BITMAP,
  148304. + gcvSURF_TILE_STATUS,
  148305. + gcvSURF_IMAGE,
  148306. + gcvSURF_MASK,
  148307. + gcvSURF_SCISSOR,
  148308. + gcvSURF_HIERARCHICAL_DEPTH,
  148309. + gcvSURF_NUM_TYPES, /* Make sure this is the last one! */
  148310. +
  148311. + /* Combinations. */
  148312. + gcvSURF_NO_TILE_STATUS = 0x100,
  148313. + gcvSURF_NO_VIDMEM = 0x200, /* Used to allocate surfaces with no underlying vidmem node.
  148314. + In Android, vidmem node is allocated by another process. */
  148315. + gcvSURF_CACHEABLE = 0x400, /* Used to allocate a cacheable surface */
  148316. + gcvSURF_FLIP = 0x800, /* The Resolve Target the will been flip resolve from RT */
  148317. + gcvSURF_TILE_STATUS_DIRTY = 0x1000, /* Init tile status to all dirty */
  148318. +
  148319. + gcvSURF_LINEAR = 0x2000,
  148320. + gcvSURF_VG = 0x4000,
  148321. +
  148322. + gcvSURF_TEXTURE_LINEAR = gcvSURF_TEXTURE
  148323. + | gcvSURF_LINEAR,
  148324. +
  148325. + gcvSURF_RENDER_TARGET_NO_TILE_STATUS = gcvSURF_RENDER_TARGET
  148326. + | gcvSURF_NO_TILE_STATUS,
  148327. +
  148328. + gcvSURF_RENDER_TARGET_TS_DIRTY = gcvSURF_RENDER_TARGET
  148329. + | gcvSURF_TILE_STATUS_DIRTY,
  148330. +
  148331. + gcvSURF_DEPTH_NO_TILE_STATUS = gcvSURF_DEPTH
  148332. + | gcvSURF_NO_TILE_STATUS,
  148333. +
  148334. + gcvSURF_DEPTH_TS_DIRTY = gcvSURF_DEPTH
  148335. + | gcvSURF_TILE_STATUS_DIRTY,
  148336. +
  148337. + /* Supported surface types with no vidmem node. */
  148338. + gcvSURF_BITMAP_NO_VIDMEM = gcvSURF_BITMAP
  148339. + | gcvSURF_NO_VIDMEM,
  148340. +
  148341. + gcvSURF_TEXTURE_NO_VIDMEM = gcvSURF_TEXTURE
  148342. + | gcvSURF_NO_VIDMEM,
  148343. +
  148344. + /* Cacheable surface types with no vidmem node. */
  148345. + gcvSURF_CACHEABLE_BITMAP_NO_VIDMEM = gcvSURF_BITMAP_NO_VIDMEM
  148346. + | gcvSURF_CACHEABLE,
  148347. +
  148348. + gcvSURF_CACHEABLE_BITMAP = gcvSURF_BITMAP
  148349. + | gcvSURF_CACHEABLE,
  148350. +
  148351. + gcvSURF_FLIP_BITMAP = gcvSURF_BITMAP
  148352. + | gcvSURF_FLIP,
  148353. +}
  148354. +gceSURF_TYPE;
  148355. +
  148356. +typedef enum _gceSURF_USAGE
  148357. +{
  148358. + gcvSURF_USAGE_UNKNOWN,
  148359. + gcvSURF_USAGE_RESOLVE_AFTER_CPU,
  148360. + gcvSURF_USAGE_RESOLVE_AFTER_3D
  148361. +}
  148362. +gceSURF_USAGE;
  148363. +
  148364. +typedef enum _gceSURF_COLOR_TYPE
  148365. +{
  148366. + gcvSURF_COLOR_UNKNOWN = 0,
  148367. + gcvSURF_COLOR_LINEAR = 0x01,
  148368. + gcvSURF_COLOR_ALPHA_PRE = 0x02,
  148369. +}
  148370. +gceSURF_COLOR_TYPE;
  148371. +
  148372. +/* Rotation. */
  148373. +typedef enum _gceSURF_ROTATION
  148374. +{
  148375. + gcvSURF_0_DEGREE = 0,
  148376. + gcvSURF_90_DEGREE,
  148377. + gcvSURF_180_DEGREE,
  148378. + gcvSURF_270_DEGREE,
  148379. + gcvSURF_FLIP_X,
  148380. + gcvSURF_FLIP_Y,
  148381. +
  148382. + gcvSURF_POST_FLIP_X = 0x40000000,
  148383. + gcvSURF_POST_FLIP_Y = 0x80000000,
  148384. +}
  148385. +gceSURF_ROTATION;
  148386. +
  148387. +typedef enum _gceMIPMAP_IMAGE_FORMAT
  148388. +{
  148389. + gcvUNKNOWN_MIPMAP_IMAGE_FORMAT = -2
  148390. +}
  148391. +gceMIPMAP_IMAGE_FORMAT;
  148392. +
  148393. +
  148394. +/* Surface formats. */
  148395. +typedef enum _gceSURF_FORMAT
  148396. +{
  148397. + /* Unknown format. */
  148398. + gcvSURF_UNKNOWN = 0,
  148399. +
  148400. + /* Palettized formats. */
  148401. + gcvSURF_INDEX1 = 100,
  148402. + gcvSURF_INDEX4,
  148403. + gcvSURF_INDEX8,
  148404. +
  148405. + /* RGB formats. */
  148406. + gcvSURF_A2R2G2B2 = 200,
  148407. + gcvSURF_R3G3B2,
  148408. + gcvSURF_A8R3G3B2,
  148409. + gcvSURF_X4R4G4B4,
  148410. + gcvSURF_A4R4G4B4,
  148411. + gcvSURF_R4G4B4A4,
  148412. + gcvSURF_X1R5G5B5,
  148413. + gcvSURF_A1R5G5B5,
  148414. + gcvSURF_R5G5B5A1,
  148415. + gcvSURF_R5G6B5,
  148416. + gcvSURF_R8G8B8,
  148417. + gcvSURF_X8R8G8B8,
  148418. + gcvSURF_A8R8G8B8,
  148419. + gcvSURF_R8G8B8A8,
  148420. + gcvSURF_G8R8G8B8,
  148421. + gcvSURF_R8G8B8G8,
  148422. + gcvSURF_X2R10G10B10,
  148423. + gcvSURF_A2R10G10B10,
  148424. + gcvSURF_X12R12G12B12,
  148425. + gcvSURF_A12R12G12B12,
  148426. + gcvSURF_X16R16G16B16,
  148427. + gcvSURF_A16R16G16B16,
  148428. + gcvSURF_A32R32G32B32,
  148429. + gcvSURF_R8G8B8X8,
  148430. + gcvSURF_R5G5B5X1,
  148431. + gcvSURF_R4G4B4X4,
  148432. +
  148433. + /* BGR formats. */
  148434. + gcvSURF_A4B4G4R4 = 300,
  148435. + gcvSURF_A1B5G5R5,
  148436. + gcvSURF_B5G6R5,
  148437. + gcvSURF_B8G8R8,
  148438. + gcvSURF_B16G16R16,
  148439. + gcvSURF_X8B8G8R8,
  148440. + gcvSURF_A8B8G8R8,
  148441. + gcvSURF_A2B10G10R10,
  148442. + gcvSURF_X16B16G16R16,
  148443. + gcvSURF_A16B16G16R16,
  148444. + gcvSURF_B32G32R32,
  148445. + gcvSURF_X32B32G32R32,
  148446. + gcvSURF_A32B32G32R32,
  148447. + gcvSURF_B4G4R4A4,
  148448. + gcvSURF_B5G5R5A1,
  148449. + gcvSURF_B8G8R8X8,
  148450. + gcvSURF_B8G8R8A8,
  148451. + gcvSURF_X4B4G4R4,
  148452. + gcvSURF_X1B5G5R5,
  148453. + gcvSURF_B4G4R4X4,
  148454. + gcvSURF_B5G5R5X1,
  148455. + gcvSURF_X2B10G10R10,
  148456. +
  148457. + /* Compressed formats. */
  148458. + gcvSURF_DXT1 = 400,
  148459. + gcvSURF_DXT2,
  148460. + gcvSURF_DXT3,
  148461. + gcvSURF_DXT4,
  148462. + gcvSURF_DXT5,
  148463. + gcvSURF_CXV8U8,
  148464. + gcvSURF_ETC1,
  148465. + gcvSURF_R11_EAC,
  148466. + gcvSURF_SIGNED_R11_EAC,
  148467. + gcvSURF_RG11_EAC,
  148468. + gcvSURF_SIGNED_RG11_EAC,
  148469. + gcvSURF_RGB8_ETC2,
  148470. + gcvSURF_SRGB8_ETC2,
  148471. + gcvSURF_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
  148472. + gcvSURF_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
  148473. + gcvSURF_RGBA8_ETC2_EAC,
  148474. + gcvSURF_SRGB8_ALPHA8_ETC2_EAC,
  148475. +
  148476. + /* YUV formats. */
  148477. + gcvSURF_YUY2 = 500,
  148478. + gcvSURF_UYVY,
  148479. + gcvSURF_YV12,
  148480. + gcvSURF_I420,
  148481. + gcvSURF_NV12,
  148482. + gcvSURF_NV21,
  148483. + gcvSURF_NV16,
  148484. + gcvSURF_NV61,
  148485. + gcvSURF_YVYU,
  148486. + gcvSURF_VYUY,
  148487. +
  148488. + /* Depth formats. */
  148489. + gcvSURF_D16 = 600,
  148490. + gcvSURF_D24S8,
  148491. + gcvSURF_D32,
  148492. + gcvSURF_D24X8,
  148493. +
  148494. + /* Alpha formats. */
  148495. + gcvSURF_A4 = 700,
  148496. + gcvSURF_A8,
  148497. + gcvSURF_A12,
  148498. + gcvSURF_A16,
  148499. + gcvSURF_A32,
  148500. + gcvSURF_A1,
  148501. +
  148502. + /* Luminance formats. */
  148503. + gcvSURF_L4 = 800,
  148504. + gcvSURF_L8,
  148505. + gcvSURF_L12,
  148506. + gcvSURF_L16,
  148507. + gcvSURF_L32,
  148508. + gcvSURF_L1,
  148509. +
  148510. + /* Alpha/Luminance formats. */
  148511. + gcvSURF_A4L4 = 900,
  148512. + gcvSURF_A2L6,
  148513. + gcvSURF_A8L8,
  148514. + gcvSURF_A4L12,
  148515. + gcvSURF_A12L12,
  148516. + gcvSURF_A16L16,
  148517. +
  148518. + /* Bump formats. */
  148519. + gcvSURF_L6V5U5 = 1000,
  148520. + gcvSURF_V8U8,
  148521. + gcvSURF_X8L8V8U8,
  148522. + gcvSURF_Q8W8V8U8,
  148523. + gcvSURF_A2W10V10U10,
  148524. + gcvSURF_V16U16,
  148525. + gcvSURF_Q16W16V16U16,
  148526. +
  148527. + /* R/RG/RA formats. */
  148528. + gcvSURF_R8 = 1100,
  148529. + gcvSURF_X8R8,
  148530. + gcvSURF_G8R8,
  148531. + gcvSURF_X8G8R8,
  148532. + gcvSURF_A8R8,
  148533. + gcvSURF_R16,
  148534. + gcvSURF_X16R16,
  148535. + gcvSURF_G16R16,
  148536. + gcvSURF_X16G16R16,
  148537. + gcvSURF_A16R16,
  148538. + gcvSURF_R32,
  148539. + gcvSURF_X32R32,
  148540. + gcvSURF_G32R32,
  148541. + gcvSURF_X32G32R32,
  148542. + gcvSURF_A32R32,
  148543. + gcvSURF_RG16,
  148544. +
  148545. + /* Floating point formats. */
  148546. + gcvSURF_R16F = 1200,
  148547. + gcvSURF_X16R16F,
  148548. + gcvSURF_G16R16F,
  148549. + gcvSURF_X16G16R16F,
  148550. + gcvSURF_B16G16R16F,
  148551. + gcvSURF_X16B16G16R16F,
  148552. + gcvSURF_A16B16G16R16F,
  148553. + gcvSURF_R32F,
  148554. + gcvSURF_X32R32F,
  148555. + gcvSURF_G32R32F,
  148556. + gcvSURF_X32G32R32F,
  148557. + gcvSURF_B32G32R32F,
  148558. + gcvSURF_X32B32G32R32F,
  148559. + gcvSURF_A32B32G32R32F,
  148560. + gcvSURF_A16F,
  148561. + gcvSURF_L16F,
  148562. + gcvSURF_A16L16F,
  148563. + gcvSURF_A16R16F,
  148564. + gcvSURF_A32F,
  148565. + gcvSURF_L32F,
  148566. + gcvSURF_A32L32F,
  148567. + gcvSURF_A32R32F,
  148568. +
  148569. +}
  148570. +gceSURF_FORMAT;
  148571. +
  148572. +/* Pixel swizzle modes. */
  148573. +typedef enum _gceSURF_SWIZZLE
  148574. +{
  148575. + gcvSURF_NOSWIZZLE = 0,
  148576. + gcvSURF_ARGB,
  148577. + gcvSURF_ABGR,
  148578. + gcvSURF_RGBA,
  148579. + gcvSURF_BGRA
  148580. +}
  148581. +gceSURF_SWIZZLE;
  148582. +
  148583. +/* Transparency modes. */
  148584. +typedef enum _gceSURF_TRANSPARENCY
  148585. +{
  148586. + /* Valid only for PE 1.0 */
  148587. + gcvSURF_OPAQUE = 0,
  148588. + gcvSURF_SOURCE_MATCH,
  148589. + gcvSURF_SOURCE_MASK,
  148590. + gcvSURF_PATTERN_MASK,
  148591. +}
  148592. +gceSURF_TRANSPARENCY;
  148593. +
  148594. +/* Surface Alignment. */
  148595. +typedef enum _gceSURF_ALIGNMENT
  148596. +{
  148597. + gcvSURF_FOUR = 0,
  148598. + gcvSURF_SIXTEEN,
  148599. + gcvSURF_SUPER_TILED,
  148600. + gcvSURF_SPLIT_TILED,
  148601. + gcvSURF_SPLIT_SUPER_TILED,
  148602. +}
  148603. +gceSURF_ALIGNMENT;
  148604. +
  148605. +
  148606. +/* Surface Addressing. */
  148607. +typedef enum _gceSURF_ADDRESSING
  148608. +{
  148609. + gcvSURF_NO_STRIDE_TILED = 0,
  148610. + gcvSURF_NO_STRIDE_LINEAR,
  148611. + gcvSURF_STRIDE_TILED,
  148612. + gcvSURF_STRIDE_LINEAR
  148613. +}
  148614. +gceSURF_ADDRESSING;
  148615. +
  148616. +/* Transparency modes. */
  148617. +typedef enum _gce2D_TRANSPARENCY
  148618. +{
  148619. + /* Valid only for PE 2.0 */
  148620. + gcv2D_OPAQUE = 0,
  148621. + gcv2D_KEYED,
  148622. + gcv2D_MASKED
  148623. +}
  148624. +gce2D_TRANSPARENCY;
  148625. +
  148626. +/* Mono packing modes. */
  148627. +typedef enum _gceSURF_MONOPACK
  148628. +{
  148629. + gcvSURF_PACKED8 = 0,
  148630. + gcvSURF_PACKED16,
  148631. + gcvSURF_PACKED32,
  148632. + gcvSURF_UNPACKED,
  148633. +}
  148634. +gceSURF_MONOPACK;
  148635. +
  148636. +/* Blending modes. */
  148637. +typedef enum _gceSURF_BLEND_MODE
  148638. +{
  148639. + /* Porter-Duff blending modes. */
  148640. + /* Fsrc Fdst */
  148641. + gcvBLEND_CLEAR = 0, /* 0 0 */
  148642. + gcvBLEND_SRC, /* 1 0 */
  148643. + gcvBLEND_DST, /* 0 1 */
  148644. + gcvBLEND_SRC_OVER_DST, /* 1 1 - Asrc */
  148645. + gcvBLEND_DST_OVER_SRC, /* 1 - Adst 1 */
  148646. + gcvBLEND_SRC_IN_DST, /* Adst 0 */
  148647. + gcvBLEND_DST_IN_SRC, /* 0 Asrc */
  148648. + gcvBLEND_SRC_OUT_DST, /* 1 - Adst 0 */
  148649. + gcvBLEND_DST_OUT_SRC, /* 0 1 - Asrc */
  148650. + gcvBLEND_SRC_ATOP_DST, /* Adst 1 - Asrc */
  148651. + gcvBLEND_DST_ATOP_SRC, /* 1 - Adst Asrc */
  148652. + gcvBLEND_SRC_XOR_DST, /* 1 - Adst 1 - Asrc */
  148653. +
  148654. + /* Special blending modes. */
  148655. + gcvBLEND_SET, /* DST = 1 */
  148656. + gcvBLEND_SUB /* DST = DST * (1 - SRC) */
  148657. +}
  148658. +gceSURF_BLEND_MODE;
  148659. +
  148660. +/* Per-pixel alpha modes. */
  148661. +typedef enum _gceSURF_PIXEL_ALPHA_MODE
  148662. +{
  148663. + gcvSURF_PIXEL_ALPHA_STRAIGHT = 0,
  148664. + gcvSURF_PIXEL_ALPHA_INVERSED
  148665. +}
  148666. +gceSURF_PIXEL_ALPHA_MODE;
  148667. +
  148668. +/* Global alpha modes. */
  148669. +typedef enum _gceSURF_GLOBAL_ALPHA_MODE
  148670. +{
  148671. + gcvSURF_GLOBAL_ALPHA_OFF = 0,
  148672. + gcvSURF_GLOBAL_ALPHA_ON,
  148673. + gcvSURF_GLOBAL_ALPHA_SCALE
  148674. +}
  148675. +gceSURF_GLOBAL_ALPHA_MODE;
  148676. +
  148677. +/* Color component modes for alpha blending. */
  148678. +typedef enum _gceSURF_PIXEL_COLOR_MODE
  148679. +{
  148680. + gcvSURF_COLOR_STRAIGHT = 0,
  148681. + gcvSURF_COLOR_MULTIPLY
  148682. +}
  148683. +gceSURF_PIXEL_COLOR_MODE;
  148684. +
  148685. +/* Color component modes for alpha blending. */
  148686. +typedef enum _gce2D_PIXEL_COLOR_MULTIPLY_MODE
  148687. +{
  148688. + gcv2D_COLOR_MULTIPLY_DISABLE = 0,
  148689. + gcv2D_COLOR_MULTIPLY_ENABLE
  148690. +}
  148691. +gce2D_PIXEL_COLOR_MULTIPLY_MODE;
  148692. +
  148693. +/* Color component modes for alpha blending. */
  148694. +typedef enum _gce2D_GLOBAL_COLOR_MULTIPLY_MODE
  148695. +{
  148696. + gcv2D_GLOBAL_COLOR_MULTIPLY_DISABLE = 0,
  148697. + gcv2D_GLOBAL_COLOR_MULTIPLY_ALPHA,
  148698. + gcv2D_GLOBAL_COLOR_MULTIPLY_COLOR
  148699. +}
  148700. +gce2D_GLOBAL_COLOR_MULTIPLY_MODE;
  148701. +
  148702. +/* Alpha blending factor modes. */
  148703. +typedef enum _gceSURF_BLEND_FACTOR_MODE
  148704. +{
  148705. + gcvSURF_BLEND_ZERO = 0,
  148706. + gcvSURF_BLEND_ONE,
  148707. + gcvSURF_BLEND_STRAIGHT,
  148708. + gcvSURF_BLEND_INVERSED,
  148709. + gcvSURF_BLEND_COLOR,
  148710. + gcvSURF_BLEND_COLOR_INVERSED,
  148711. + gcvSURF_BLEND_SRC_ALPHA_SATURATED,
  148712. + gcvSURF_BLEND_STRAIGHT_NO_CROSS,
  148713. + gcvSURF_BLEND_INVERSED_NO_CROSS,
  148714. + gcvSURF_BLEND_COLOR_NO_CROSS,
  148715. + gcvSURF_BLEND_COLOR_INVERSED_NO_CROSS,
  148716. + gcvSURF_BLEND_SRC_ALPHA_SATURATED_CROSS
  148717. +}
  148718. +gceSURF_BLEND_FACTOR_MODE;
  148719. +
  148720. +/* Alpha blending porter duff rules. */
  148721. +typedef enum _gce2D_PORTER_DUFF_RULE
  148722. +{
  148723. + gcvPD_CLEAR = 0,
  148724. + gcvPD_SRC,
  148725. + gcvPD_SRC_OVER,
  148726. + gcvPD_DST_OVER,
  148727. + gcvPD_SRC_IN,
  148728. + gcvPD_DST_IN,
  148729. + gcvPD_SRC_OUT,
  148730. + gcvPD_DST_OUT,
  148731. + gcvPD_SRC_ATOP,
  148732. + gcvPD_DST_ATOP,
  148733. + gcvPD_ADD,
  148734. + gcvPD_XOR,
  148735. + gcvPD_DST
  148736. +}
  148737. +gce2D_PORTER_DUFF_RULE;
  148738. +
  148739. +/* Alpha blending factor modes. */
  148740. +typedef enum _gce2D_YUV_COLOR_MODE
  148741. +{
  148742. + gcv2D_YUV_601= 0,
  148743. + gcv2D_YUV_709,
  148744. + gcv2D_YUV_USER_DEFINED,
  148745. + gcv2D_YUV_USER_DEFINED_CLAMP,
  148746. +
  148747. + /* Default setting is for src. gcv2D_YUV_DST
  148748. + can be ORed to set dst.
  148749. + */
  148750. + gcv2D_YUV_DST = 0x80000000,
  148751. +}
  148752. +gce2D_YUV_COLOR_MODE;
  148753. +
  148754. +typedef enum _gce2D_COMMAND
  148755. +{
  148756. + gcv2D_CLEAR = 0,
  148757. + gcv2D_LINE,
  148758. + gcv2D_BLT,
  148759. + gcv2D_STRETCH,
  148760. + gcv2D_HOR_FILTER,
  148761. + gcv2D_VER_FILTER,
  148762. + gcv2D_MULTI_SOURCE_BLT,
  148763. +}
  148764. +gce2D_COMMAND;
  148765. +
  148766. +typedef enum _gce2D_TILE_STATUS_CONFIG
  148767. +{
  148768. + gcv2D_TSC_DISABLE = 0,
  148769. + gcv2D_TSC_ENABLE = 0x00000001,
  148770. + gcv2D_TSC_COMPRESSED = 0x00000002,
  148771. + gcv2D_TSC_DOWN_SAMPLER = 0x00000004,
  148772. + gcv2D_TSC_2D_COMPRESSED = 0x00000008,
  148773. +}
  148774. +gce2D_TILE_STATUS_CONFIG;
  148775. +
  148776. +typedef enum _gce2D_QUERY
  148777. +{
  148778. + gcv2D_QUERY_RGB_ADDRESS_MIN_ALIGN = 0,
  148779. + gcv2D_QUERY_RGB_STRIDE_MIN_ALIGN,
  148780. + gcv2D_QUERY_YUV_ADDRESS_MIN_ALIGN,
  148781. + gcv2D_QUERY_YUV_STRIDE_MIN_ALIGN,
  148782. +}
  148783. +gce2D_QUERY;
  148784. +
  148785. +typedef enum _gce2D_SUPER_TILE_VERSION
  148786. +{
  148787. + gcv2D_SUPER_TILE_VERSION_V1 = 1,
  148788. + gcv2D_SUPER_TILE_VERSION_V2 = 2,
  148789. + gcv2D_SUPER_TILE_VERSION_V3 = 3,
  148790. +}
  148791. +gce2D_SUPER_TILE_VERSION;
  148792. +
  148793. +typedef enum _gce2D_STATE
  148794. +{
  148795. + gcv2D_STATE_SPECIAL_FILTER_MIRROR_MODE = 1,
  148796. + gcv2D_STATE_SUPER_TILE_VERSION,
  148797. + gcv2D_STATE_EN_GAMMA,
  148798. + gcv2D_STATE_DE_GAMMA,
  148799. + gcv2D_STATE_MULTI_SRC_BLIT_UNIFIED_DST_RECT,
  148800. + gcv2D_STATE_XRGB_ENABLE,
  148801. +
  148802. + gcv2D_STATE_ARRAY_EN_GAMMA = 0x10001,
  148803. + gcv2D_STATE_ARRAY_DE_GAMMA,
  148804. + gcv2D_STATE_ARRAY_CSC_YUV_TO_RGB,
  148805. + gcv2D_STATE_ARRAY_CSC_RGB_TO_YUV,
  148806. +}
  148807. +gce2D_STATE;
  148808. +
  148809. +#ifndef VIVANTE_NO_3D
  148810. +/* Texture functions. */
  148811. +typedef enum _gceTEXTURE_FUNCTION
  148812. +{
  148813. + gcvTEXTURE_DUMMY = 0,
  148814. + gcvTEXTURE_REPLACE = 0,
  148815. + gcvTEXTURE_MODULATE,
  148816. + gcvTEXTURE_ADD,
  148817. + gcvTEXTURE_ADD_SIGNED,
  148818. + gcvTEXTURE_INTERPOLATE,
  148819. + gcvTEXTURE_SUBTRACT,
  148820. + gcvTEXTURE_DOT3
  148821. +}
  148822. +gceTEXTURE_FUNCTION;
  148823. +
  148824. +/* Texture sources. */
  148825. +typedef enum _gceTEXTURE_SOURCE
  148826. +{
  148827. + gcvCOLOR_FROM_TEXTURE = 0,
  148828. + gcvCOLOR_FROM_CONSTANT_COLOR,
  148829. + gcvCOLOR_FROM_PRIMARY_COLOR,
  148830. + gcvCOLOR_FROM_PREVIOUS_COLOR
  148831. +}
  148832. +gceTEXTURE_SOURCE;
  148833. +
  148834. +/* Texture source channels. */
  148835. +typedef enum _gceTEXTURE_CHANNEL
  148836. +{
  148837. + gcvFROM_COLOR = 0,
  148838. + gcvFROM_ONE_MINUS_COLOR,
  148839. + gcvFROM_ALPHA,
  148840. + gcvFROM_ONE_MINUS_ALPHA
  148841. +}
  148842. +gceTEXTURE_CHANNEL;
  148843. +#endif /* VIVANTE_NO_3D */
  148844. +
  148845. +/* Filter types. */
  148846. +typedef enum _gceFILTER_TYPE
  148847. +{
  148848. + gcvFILTER_SYNC = 0,
  148849. + gcvFILTER_BLUR,
  148850. + gcvFILTER_USER
  148851. +}
  148852. +gceFILTER_TYPE;
  148853. +
  148854. +/* Filter pass types. */
  148855. +typedef enum _gceFILTER_PASS_TYPE
  148856. +{
  148857. + gcvFILTER_HOR_PASS = 0,
  148858. + gcvFILTER_VER_PASS
  148859. +}
  148860. +gceFILTER_PASS_TYPE;
  148861. +
  148862. +/* Endian hints. */
  148863. +typedef enum _gceENDIAN_HINT
  148864. +{
  148865. + gcvENDIAN_NO_SWAP = 0,
  148866. + gcvENDIAN_SWAP_WORD,
  148867. + gcvENDIAN_SWAP_DWORD
  148868. +}
  148869. +gceENDIAN_HINT;
  148870. +
  148871. +/* Tiling modes. */
  148872. +typedef enum _gceTILING
  148873. +{
  148874. + gcvLINEAR = 0,
  148875. + gcvTILED,
  148876. + gcvSUPERTILED,
  148877. + gcvMULTI_TILED,
  148878. + gcvMULTI_SUPERTILED,
  148879. + gcvMINORTILED,
  148880. +}
  148881. +gceTILING;
  148882. +
  148883. +/* 2D pattern type. */
  148884. +typedef enum _gce2D_PATTERN
  148885. +{
  148886. + gcv2D_PATTERN_SOLID = 0,
  148887. + gcv2D_PATTERN_MONO,
  148888. + gcv2D_PATTERN_COLOR,
  148889. + gcv2D_PATTERN_INVALID
  148890. +}
  148891. +gce2D_PATTERN;
  148892. +
  148893. +/* 2D source type. */
  148894. +typedef enum _gce2D_SOURCE
  148895. +{
  148896. + gcv2D_SOURCE_MASKED = 0,
  148897. + gcv2D_SOURCE_MONO,
  148898. + gcv2D_SOURCE_COLOR,
  148899. + gcv2D_SOURCE_INVALID
  148900. +}
  148901. +gce2D_SOURCE;
  148902. +
  148903. +/* Pipes. */
  148904. +typedef enum _gcePIPE_SELECT
  148905. +{
  148906. + gcvPIPE_INVALID = ~0,
  148907. + gcvPIPE_3D = 0,
  148908. + gcvPIPE_2D
  148909. +}
  148910. +gcePIPE_SELECT;
  148911. +
  148912. +/* Hardware type. */
  148913. +typedef enum _gceHARDWARE_TYPE
  148914. +{
  148915. + gcvHARDWARE_INVALID = 0x00,
  148916. + gcvHARDWARE_3D = 0x01,
  148917. + gcvHARDWARE_2D = 0x02,
  148918. + gcvHARDWARE_VG = 0x04,
  148919. +
  148920. + gcvHARDWARE_3D2D = gcvHARDWARE_3D | gcvHARDWARE_2D
  148921. +}
  148922. +gceHARDWARE_TYPE;
  148923. +
  148924. +#define gcdCHIP_COUNT 3
  148925. +
  148926. +typedef enum _gceMMU_MODE
  148927. +{
  148928. + gcvMMU_MODE_1K,
  148929. + gcvMMU_MODE_4K,
  148930. +} gceMMU_MODE;
  148931. +
  148932. +/* User signal command codes. */
  148933. +typedef enum _gceUSER_SIGNAL_COMMAND_CODES
  148934. +{
  148935. + gcvUSER_SIGNAL_CREATE,
  148936. + gcvUSER_SIGNAL_DESTROY,
  148937. + gcvUSER_SIGNAL_SIGNAL,
  148938. + gcvUSER_SIGNAL_WAIT,
  148939. + gcvUSER_SIGNAL_MAP,
  148940. + gcvUSER_SIGNAL_UNMAP,
  148941. +}
  148942. +gceUSER_SIGNAL_COMMAND_CODES;
  148943. +
  148944. +/* Sync point command codes. */
  148945. +typedef enum _gceSYNC_POINT_COMMAND_CODES
  148946. +{
  148947. + gcvSYNC_POINT_CREATE,
  148948. + gcvSYNC_POINT_DESTROY,
  148949. + gcvSYNC_POINT_SIGNAL,
  148950. +}
  148951. +gceSYNC_POINT_COMMAND_CODES;
  148952. +
  148953. +/* Event locations. */
  148954. +typedef enum _gceKERNEL_WHERE
  148955. +{
  148956. + gcvKERNEL_COMMAND,
  148957. + gcvKERNEL_VERTEX,
  148958. + gcvKERNEL_TRIANGLE,
  148959. + gcvKERNEL_TEXTURE,
  148960. + gcvKERNEL_PIXEL,
  148961. +}
  148962. +gceKERNEL_WHERE;
  148963. +
  148964. +#if gcdENABLE_VG
  148965. +/* Hardware blocks. */
  148966. +typedef enum _gceBLOCK
  148967. +{
  148968. + gcvBLOCK_COMMAND,
  148969. + gcvBLOCK_TESSELLATOR,
  148970. + gcvBLOCK_TESSELLATOR2,
  148971. + gcvBLOCK_TESSELLATOR3,
  148972. + gcvBLOCK_RASTER,
  148973. + gcvBLOCK_VG,
  148974. + gcvBLOCK_VG2,
  148975. + gcvBLOCK_VG3,
  148976. + gcvBLOCK_PIXEL,
  148977. +
  148978. + /* Number of defined blocks. */
  148979. + gcvBLOCK_COUNT
  148980. +}
  148981. +gceBLOCK;
  148982. +#endif
  148983. +
  148984. +/* gcdDUMP message type. */
  148985. +typedef enum _gceDEBUG_MESSAGE_TYPE
  148986. +{
  148987. + gcvMESSAGE_TEXT,
  148988. + gcvMESSAGE_DUMP
  148989. +}
  148990. +gceDEBUG_MESSAGE_TYPE;
  148991. +
  148992. +typedef enum _gceSPECIAL_HINT
  148993. +{
  148994. + gceSPECIAL_HINT0,
  148995. + gceSPECIAL_HINT1,
  148996. + gceSPECIAL_HINT2,
  148997. + gceSPECIAL_HINT3,
  148998. + /* For disable dynamic stream/index */
  148999. + gceSPECIAL_HINT4
  149000. +}
  149001. +gceSPECIAL_HINT;
  149002. +
  149003. +typedef enum _gceMACHINECODE
  149004. +{
  149005. + gcvMACHINECODE_HOVERJET0 = 0x0,
  149006. + gcvMACHINECODE_HOVERJET1 ,
  149007. +
  149008. + gcvMACHINECODE_TAIJI0 ,
  149009. + gcvMACHINECODE_TAIJI1 ,
  149010. + gcvMACHINECODE_TAIJI2 ,
  149011. +
  149012. + gcvMACHINECODE_ANTUTU0 ,
  149013. +
  149014. + gcvMACHINECODE_GLB27_RELEASE_0,
  149015. + gcvMACHINECODE_GLB27_RELEASE_1,
  149016. +
  149017. + gcvMACHINECODE_WAVESCAPE0 ,
  149018. + gcvMACHINECODE_WAVESCAPE1 ,
  149019. +
  149020. + gcvMACHINECODE_NENAMARKV2_4_0 ,
  149021. + gcvMACHINECODE_NENAMARKV2_4_1 ,
  149022. +
  149023. + gcvMACHINECODE_GLB25_RELEASE_0,
  149024. + gcvMACHINECODE_GLB25_RELEASE_1,
  149025. + gcvMACHINECODE_GLB25_RELEASE_2,
  149026. +}
  149027. +gceMACHINECODE;
  149028. +
  149029. +
  149030. +/******************************************************************************\
  149031. +****************************** Object Declarations *****************************
  149032. +\******************************************************************************/
  149033. +
  149034. +typedef struct _gckCONTEXT * gckCONTEXT;
  149035. +typedef struct _gcoCMDBUF * gcoCMDBUF;
  149036. +typedef struct _gcsSTATE_DELTA * gcsSTATE_DELTA_PTR;
  149037. +typedef struct _gcsQUEUE * gcsQUEUE_PTR;
  149038. +typedef struct _gcoQUEUE * gcoQUEUE;
  149039. +typedef struct _gcsHAL_INTERFACE * gcsHAL_INTERFACE_PTR;
  149040. +typedef struct _gcs2D_PROFILE * gcs2D_PROFILE_PTR;
  149041. +
  149042. +#if gcdENABLE_VG
  149043. +typedef struct _gcoVGHARDWARE * gcoVGHARDWARE;
  149044. +typedef struct _gcoVGBUFFER * gcoVGBUFFER;
  149045. +typedef struct _gckVGHARDWARE * gckVGHARDWARE;
  149046. +typedef struct _gcsVGCONTEXT * gcsVGCONTEXT_PTR;
  149047. +typedef struct _gcsVGCONTEXT_MAP * gcsVGCONTEXT_MAP_PTR;
  149048. +typedef struct _gcsVGCMDQUEUE * gcsVGCMDQUEUE_PTR;
  149049. +typedef struct _gcsTASK_MASTER_TABLE * gcsTASK_MASTER_TABLE_PTR;
  149050. +typedef struct _gckVGKERNEL * gckVGKERNEL;
  149051. +typedef void * gctTHREAD;
  149052. +#endif
  149053. +
  149054. +#ifdef __cplusplus
  149055. +}
  149056. +#endif
  149057. +
  149058. +#endif /* __gc_hal_enum_h_ */
  149059. diff -Nur linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
  149060. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h 1970-01-01 01:00:00.000000000 +0100
  149061. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h 2014-09-11 18:06:03.114042420 +0200
  149062. @@ -0,0 +1,2661 @@
  149063. +/****************************************************************************
  149064. +*
  149065. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  149066. +*
  149067. +* This program is free software; you can redistribute it and/or modify
  149068. +* it under the terms of the GNU General Public License as published by
  149069. +* the Free Software Foundation; either version 2 of the license, or
  149070. +* (at your option) any later version.
  149071. +*
  149072. +* This program is distributed in the hope that it will be useful,
  149073. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  149074. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  149075. +* GNU General Public License for more details.
  149076. +*
  149077. +* You should have received a copy of the GNU General Public License
  149078. +* along with this program; if not write to the Free Software
  149079. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  149080. +*
  149081. +*****************************************************************************/
  149082. +
  149083. +
  149084. +#ifndef __gc_hal_h_
  149085. +#define __gc_hal_h_
  149086. +
  149087. +#include "gc_hal_rename.h"
  149088. +#include "gc_hal_types.h"
  149089. +#include "gc_hal_enum.h"
  149090. +#include "gc_hal_base.h"
  149091. +#include "gc_hal_profiler.h"
  149092. +#include "gc_hal_driver.h"
  149093. +#ifndef VIVANTE_NO_3D
  149094. +#include "gc_hal_statistics.h"
  149095. +#endif
  149096. +
  149097. +#ifdef __cplusplus
  149098. +extern "C" {
  149099. +#endif
  149100. +
  149101. +/******************************************************************************\
  149102. +******************************* Alignment Macros *******************************
  149103. +\******************************************************************************/
  149104. +
  149105. +#define gcmALIGN(n, align) \
  149106. +( \
  149107. + ((n) + ((align) - 1)) & ~((align) - 1) \
  149108. +)
  149109. +
  149110. +#define gcmALIGN_BASE(n, align) \
  149111. +( \
  149112. + ((n) & ~((align) - 1)) \
  149113. +)
  149114. +
  149115. +/******************************************************************************\
  149116. +***************************** Element Count Macro *****************************
  149117. +\******************************************************************************/
  149118. +
  149119. +#define gcmSIZEOF(a) \
  149120. +( \
  149121. + (gctSIZE_T) (sizeof(a)) \
  149122. +)
  149123. +
  149124. +#define gcmCOUNTOF(a) \
  149125. +( \
  149126. + sizeof(a) / sizeof(a[0]) \
  149127. +)
  149128. +
  149129. +/******************************************************************************\
  149130. +********************************* Cast Macro **********************************
  149131. +\******************************************************************************/
  149132. +#define gcmNAME_TO_PTR(na) \
  149133. + gckKERNEL_QueryPointerFromName(kernel, gcmALL_TO_UINT32(na))
  149134. +
  149135. +#define gcmPTR_TO_NAME(ptr) \
  149136. + gckKERNEL_AllocateNameFromPointer(kernel, ptr)
  149137. +
  149138. +#define gcmRELEASE_NAME(na) \
  149139. + gckKERNEL_DeleteName(kernel, gcmALL_TO_UINT32(na))
  149140. +
  149141. +#ifdef __LP64__
  149142. +
  149143. +#define gcmALL_TO_UINT32(t) \
  149144. +( \
  149145. + (gctUINT32) (gctUINTPTR_T) (t)\
  149146. +)
  149147. +
  149148. +#define gcmPTR_TO_UINT64(p) \
  149149. +( \
  149150. + (gctUINT64) (p)\
  149151. +)
  149152. +
  149153. +#define gcmUINT64_TO_PTR(u) \
  149154. +( \
  149155. + (gctPOINTER) (u)\
  149156. +)
  149157. +
  149158. +#else /* 32 bit */
  149159. +
  149160. +#define gcmALL_TO_UINT32(t) \
  149161. +( \
  149162. + (gctUINT32) (t)\
  149163. +)
  149164. +
  149165. +#define gcmPTR_TO_UINT64(p) \
  149166. +( \
  149167. + (gctUINT64) (gctUINTPTR_T) (p)\
  149168. +)
  149169. +
  149170. +#define gcmUINT64_TO_PTR(u) \
  149171. +( \
  149172. + (gctPOINTER) (gctUINTPTR_T) (u)\
  149173. +)
  149174. +
  149175. +#endif
  149176. +
  149177. +#define gcmUINT64_TO_TYPE(u, t) \
  149178. +( \
  149179. + (t) (gctUINTPTR_T) (u)\
  149180. +)
  149181. +
  149182. +/******************************************************************************\
  149183. +******************************** Useful Macro *********************************
  149184. +\******************************************************************************/
  149185. +
  149186. +#define gcvINVALID_ADDRESS ~0U
  149187. +
  149188. +#define gcmGET_PRE_ROTATION(rotate) \
  149189. + ((rotate) & (~(gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y)))
  149190. +
  149191. +#define gcmGET_POST_ROTATION(rotate) \
  149192. + ((rotate) & (gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y))
  149193. +
  149194. +/******************************************************************************\
  149195. +******************************** gcsOBJECT Object *******************************
  149196. +\******************************************************************************/
  149197. +
  149198. +/* Type of objects. */
  149199. +typedef enum _gceOBJECT_TYPE
  149200. +{
  149201. + gcvOBJ_UNKNOWN = 0,
  149202. + gcvOBJ_2D = gcmCC('2','D',' ',' '),
  149203. + gcvOBJ_3D = gcmCC('3','D',' ',' '),
  149204. + gcvOBJ_ATTRIBUTE = gcmCC('A','T','T','R'),
  149205. + gcvOBJ_BRUSHCACHE = gcmCC('B','R','U','$'),
  149206. + gcvOBJ_BRUSHNODE = gcmCC('B','R','U','n'),
  149207. + gcvOBJ_BRUSH = gcmCC('B','R','U','o'),
  149208. + gcvOBJ_BUFFER = gcmCC('B','U','F','R'),
  149209. + gcvOBJ_COMMAND = gcmCC('C','M','D',' '),
  149210. + gcvOBJ_COMMANDBUFFER = gcmCC('C','M','D','B'),
  149211. + gcvOBJ_CONTEXT = gcmCC('C','T','X','T'),
  149212. + gcvOBJ_DEVICE = gcmCC('D','E','V',' '),
  149213. + gcvOBJ_DUMP = gcmCC('D','U','M','P'),
  149214. + gcvOBJ_EVENT = gcmCC('E','V','N','T'),
  149215. + gcvOBJ_FUNCTION = gcmCC('F','U','N','C'),
  149216. + gcvOBJ_HAL = gcmCC('H','A','L',' '),
  149217. + gcvOBJ_HARDWARE = gcmCC('H','A','R','D'),
  149218. + gcvOBJ_HEAP = gcmCC('H','E','A','P'),
  149219. + gcvOBJ_INDEX = gcmCC('I','N','D','X'),
  149220. + gcvOBJ_INTERRUPT = gcmCC('I','N','T','R'),
  149221. + gcvOBJ_KERNEL = gcmCC('K','E','R','N'),
  149222. + gcvOBJ_KERNEL_FUNCTION = gcmCC('K','F','C','N'),
  149223. + gcvOBJ_MEMORYBUFFER = gcmCC('M','E','M','B'),
  149224. + gcvOBJ_MMU = gcmCC('M','M','U',' '),
  149225. + gcvOBJ_OS = gcmCC('O','S',' ',' '),
  149226. + gcvOBJ_OUTPUT = gcmCC('O','U','T','P'),
  149227. + gcvOBJ_PAINT = gcmCC('P','N','T',' '),
  149228. + gcvOBJ_PATH = gcmCC('P','A','T','H'),
  149229. + gcvOBJ_QUEUE = gcmCC('Q','U','E',' '),
  149230. + gcvOBJ_SAMPLER = gcmCC('S','A','M','P'),
  149231. + gcvOBJ_SHADER = gcmCC('S','H','D','R'),
  149232. + gcvOBJ_STREAM = gcmCC('S','T','R','M'),
  149233. + gcvOBJ_SURF = gcmCC('S','U','R','F'),
  149234. + gcvOBJ_TEXTURE = gcmCC('T','X','T','R'),
  149235. + gcvOBJ_UNIFORM = gcmCC('U','N','I','F'),
  149236. + gcvOBJ_VARIABLE = gcmCC('V','A','R','I'),
  149237. + gcvOBJ_VERTEX = gcmCC('V','R','T','X'),
  149238. + gcvOBJ_VIDMEM = gcmCC('V','M','E','M'),
  149239. + gcvOBJ_VG = gcmCC('V','G',' ',' '),
  149240. +}
  149241. +gceOBJECT_TYPE;
  149242. +
  149243. +/* gcsOBJECT object defintinon. */
  149244. +typedef struct _gcsOBJECT
  149245. +{
  149246. + /* Type of an object. */
  149247. + gceOBJECT_TYPE type;
  149248. +}
  149249. +gcsOBJECT;
  149250. +
  149251. +typedef struct _gckHARDWARE * gckHARDWARE;
  149252. +
  149253. +/* CORE flags. */
  149254. +typedef enum _gceCORE
  149255. +{
  149256. + gcvCORE_MAJOR = 0x0,
  149257. + gcvCORE_2D = 0x1,
  149258. + gcvCORE_VG = 0x2
  149259. +}
  149260. +gceCORE;
  149261. +
  149262. +#define gcdMAX_GPU_COUNT 3
  149263. +
  149264. +/*******************************************************************************
  149265. +**
  149266. +** gcmVERIFY_OBJECT
  149267. +**
  149268. +** Assert if an object is invalid or is not of the specified type. If the
  149269. +** object is invalid or not of the specified type, gcvSTATUS_INVALID_OBJECT
  149270. +** will be returned from the current function. In retail mode this macro
  149271. +** does nothing.
  149272. +**
  149273. +** ARGUMENTS:
  149274. +**
  149275. +** obj Object to test.
  149276. +** t Expected type of the object.
  149277. +*/
  149278. +#if gcmIS_DEBUG(gcdDEBUG_TRACE)
  149279. +#define _gcmVERIFY_OBJECT(prefix, obj, t) \
  149280. + if ((obj) == gcvNULL) \
  149281. + { \
  149282. + prefix##TRACE(gcvLEVEL_ERROR, \
  149283. + #prefix "VERIFY_OBJECT failed: NULL"); \
  149284. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  149285. + gcmCC_PRINT(t)); \
  149286. + prefix##ASSERT((obj) != gcvNULL); \
  149287. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
  149288. + return gcvSTATUS_INVALID_OBJECT; \
  149289. + } \
  149290. + else if (((gcsOBJECT*) (obj))->type != t) \
  149291. + { \
  149292. + prefix##TRACE(gcvLEVEL_ERROR, \
  149293. + #prefix "VERIFY_OBJECT failed: %c%c%c%c", \
  149294. + gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
  149295. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  149296. + gcmCC_PRINT(t)); \
  149297. + prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
  149298. + prefix##FOOTER_ARG("status=%d", gcvSTATUS_INVALID_OBJECT); \
  149299. + return gcvSTATUS_INVALID_OBJECT; \
  149300. + }
  149301. +
  149302. +# define gcmVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcm, obj, t)
  149303. +# define gcmkVERIFY_OBJECT(obj, t) _gcmVERIFY_OBJECT(gcmk, obj, t)
  149304. +#else
  149305. +# define gcmVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
  149306. +# define gcmkVERIFY_OBJECT(obj, t) do {} while (gcvFALSE)
  149307. +#endif
  149308. +
  149309. +/******************************************************************************/
  149310. +/*VERIFY_OBJECT if special return expected*/
  149311. +/******************************************************************************/
  149312. +#ifndef EGL_API_ANDROID
  149313. +# define _gcmVERIFY_OBJECT_RETURN(prefix, obj, t, retVal) \
  149314. + do \
  149315. + { \
  149316. + if ((obj) == gcvNULL) \
  149317. + { \
  149318. + prefix##PRINT_VERSION(); \
  149319. + prefix##TRACE(gcvLEVEL_ERROR, \
  149320. + #prefix "VERIFY_OBJECT_RETURN failed: NULL"); \
  149321. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  149322. + gcmCC_PRINT(t)); \
  149323. + prefix##ASSERT((obj) != gcvNULL); \
  149324. + prefix##FOOTER_ARG("retVal=%d", retVal); \
  149325. + return retVal; \
  149326. + } \
  149327. + else if (((gcsOBJECT*) (obj))->type != t) \
  149328. + { \
  149329. + prefix##PRINT_VERSION(); \
  149330. + prefix##TRACE(gcvLEVEL_ERROR, \
  149331. + #prefix "VERIFY_OBJECT_RETURN failed: %c%c%c%c", \
  149332. + gcmCC_PRINT(((gcsOBJECT*) (obj))->type)); \
  149333. + prefix##TRACE(gcvLEVEL_ERROR, " expected: %c%c%c%c", \
  149334. + gcmCC_PRINT(t)); \
  149335. + prefix##ASSERT(((gcsOBJECT*)(obj))->type == t); \
  149336. + prefix##FOOTER_ARG("retVal=%d", retVal); \
  149337. + return retVal; \
  149338. + } \
  149339. + } \
  149340. + while (gcvFALSE)
  149341. +# define gcmVERIFY_OBJECT_RETURN(obj, t, retVal) \
  149342. + _gcmVERIFY_OBJECT_RETURN(gcm, obj, t, retVal)
  149343. +# define gcmkVERIFY_OBJECT_RETURN(obj, t, retVal) \
  149344. + _gcmVERIFY_OBJECT_RETURN(gcmk, obj, t, retVal)
  149345. +#else
  149346. +# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
  149347. +# define gcmVERIFY_OBJECT_RETURN(obj, t) do {} while (gcvFALSE)
  149348. +#endif
  149349. +
  149350. +/******************************************************************************\
  149351. +********************************** gckOS Object *********************************
  149352. +\******************************************************************************/
  149353. +
  149354. +/* Construct a new gckOS object. */
  149355. +gceSTATUS
  149356. +gckOS_Construct(
  149357. + IN gctPOINTER Context,
  149358. + OUT gckOS * Os
  149359. + );
  149360. +
  149361. +/* Destroy an gckOS object. */
  149362. +gceSTATUS
  149363. +gckOS_Destroy(
  149364. + IN gckOS Os
  149365. + );
  149366. +
  149367. +/* Query the video memory. */
  149368. +gceSTATUS
  149369. +gckOS_QueryVideoMemory(
  149370. + IN gckOS Os,
  149371. + OUT gctPHYS_ADDR * InternalAddress,
  149372. + OUT gctSIZE_T * InternalSize,
  149373. + OUT gctPHYS_ADDR * ExternalAddress,
  149374. + OUT gctSIZE_T * ExternalSize,
  149375. + OUT gctPHYS_ADDR * ContiguousAddress,
  149376. + OUT gctSIZE_T * ContiguousSize
  149377. + );
  149378. +
  149379. +/* Allocate memory from the heap. */
  149380. +gceSTATUS
  149381. +gckOS_Allocate(
  149382. + IN gckOS Os,
  149383. + IN gctSIZE_T Bytes,
  149384. + OUT gctPOINTER * Memory
  149385. + );
  149386. +
  149387. +/* Free allocated memory. */
  149388. +gceSTATUS
  149389. +gckOS_Free(
  149390. + IN gckOS Os,
  149391. + IN gctPOINTER Memory
  149392. + );
  149393. +
  149394. +/* Wrapper for allocation memory.. */
  149395. +gceSTATUS
  149396. +gckOS_AllocateMemory(
  149397. + IN gckOS Os,
  149398. + IN gctSIZE_T Bytes,
  149399. + OUT gctPOINTER * Memory
  149400. + );
  149401. +
  149402. +/* Wrapper for freeing memory. */
  149403. +gceSTATUS
  149404. +gckOS_FreeMemory(
  149405. + IN gckOS Os,
  149406. + IN gctPOINTER Memory
  149407. + );
  149408. +
  149409. +/* Allocate paged memory. */
  149410. +gceSTATUS
  149411. +gckOS_AllocatePagedMemory(
  149412. + IN gckOS Os,
  149413. + IN gctSIZE_T Bytes,
  149414. + OUT gctPHYS_ADDR * Physical
  149415. + );
  149416. +
  149417. +/* Allocate paged memory. */
  149418. +gceSTATUS
  149419. +gckOS_AllocatePagedMemoryEx(
  149420. + IN gckOS Os,
  149421. + IN gctBOOL Contiguous,
  149422. + IN gctSIZE_T Bytes,
  149423. + OUT gctPHYS_ADDR * Physical
  149424. + );
  149425. +
  149426. +/* Lock pages. */
  149427. +gceSTATUS
  149428. +gckOS_LockPages(
  149429. + IN gckOS Os,
  149430. + IN gctPHYS_ADDR Physical,
  149431. + IN gctSIZE_T Bytes,
  149432. + IN gctBOOL Cacheable,
  149433. + OUT gctPOINTER * Logical,
  149434. + OUT gctSIZE_T * PageCount
  149435. + );
  149436. +
  149437. +/* Map pages. */
  149438. +gceSTATUS
  149439. +gckOS_MapPages(
  149440. + IN gckOS Os,
  149441. + IN gctPHYS_ADDR Physical,
  149442. +#ifdef __QNXNTO__
  149443. + IN gctPOINTER Logical,
  149444. +#endif
  149445. + IN gctSIZE_T PageCount,
  149446. + IN gctPOINTER PageTable
  149447. + );
  149448. +
  149449. +/* Map pages. */
  149450. +gceSTATUS
  149451. +gckOS_MapPagesEx(
  149452. + IN gckOS Os,
  149453. + IN gceCORE Core,
  149454. + IN gctPHYS_ADDR Physical,
  149455. +#ifdef __QNXNTO__
  149456. + IN gctPOINTER Logical,
  149457. +#endif
  149458. + IN gctSIZE_T PageCount,
  149459. + IN gctPOINTER PageTable
  149460. + );
  149461. +
  149462. +/* Unlock pages. */
  149463. +gceSTATUS
  149464. +gckOS_UnlockPages(
  149465. + IN gckOS Os,
  149466. + IN gctPHYS_ADDR Physical,
  149467. + IN gctSIZE_T Bytes,
  149468. + IN gctPOINTER Logical
  149469. + );
  149470. +
  149471. +/* Free paged memory. */
  149472. +gceSTATUS
  149473. +gckOS_FreePagedMemory(
  149474. + IN gckOS Os,
  149475. + IN gctPHYS_ADDR Physical,
  149476. + IN gctSIZE_T Bytes
  149477. + );
  149478. +
  149479. +/* Allocate non-paged memory. */
  149480. +gceSTATUS
  149481. +gckOS_AllocateNonPagedMemory(
  149482. + IN gckOS Os,
  149483. + IN gctBOOL InUserSpace,
  149484. + IN OUT gctSIZE_T * Bytes,
  149485. + OUT gctPHYS_ADDR * Physical,
  149486. + OUT gctPOINTER * Logical
  149487. + );
  149488. +
  149489. +/* Free non-paged memory. */
  149490. +gceSTATUS
  149491. +gckOS_FreeNonPagedMemory(
  149492. + IN gckOS Os,
  149493. + IN gctSIZE_T Bytes,
  149494. + IN gctPHYS_ADDR Physical,
  149495. + IN gctPOINTER Logical
  149496. + );
  149497. +
  149498. +/* Allocate contiguous memory. */
  149499. +gceSTATUS
  149500. +gckOS_AllocateContiguous(
  149501. + IN gckOS Os,
  149502. + IN gctBOOL InUserSpace,
  149503. + IN OUT gctSIZE_T * Bytes,
  149504. + OUT gctPHYS_ADDR * Physical,
  149505. + OUT gctPOINTER * Logical
  149506. + );
  149507. +
  149508. +/* Free contiguous memory. */
  149509. +gceSTATUS
  149510. +gckOS_FreeContiguous(
  149511. + IN gckOS Os,
  149512. + IN gctPHYS_ADDR Physical,
  149513. + IN gctPOINTER Logical,
  149514. + IN gctSIZE_T Bytes
  149515. + );
  149516. +
  149517. +/* Get the number fo bytes per page. */
  149518. +gceSTATUS
  149519. +gckOS_GetPageSize(
  149520. + IN gckOS Os,
  149521. + OUT gctSIZE_T * PageSize
  149522. + );
  149523. +
  149524. +/* Get the physical address of a corresponding logical address. */
  149525. +gceSTATUS
  149526. +gckOS_GetPhysicalAddress(
  149527. + IN gckOS Os,
  149528. + IN gctPOINTER Logical,
  149529. + OUT gctUINT32 * Address
  149530. + );
  149531. +
  149532. +/* Get the physical address of a corresponding logical address. */
  149533. +gceSTATUS
  149534. +gckOS_GetPhysicalAddressProcess(
  149535. + IN gckOS Os,
  149536. + IN gctPOINTER Logical,
  149537. + IN gctUINT32 ProcessID,
  149538. + OUT gctUINT32 * Address
  149539. + );
  149540. +
  149541. +/* Map physical memory. */
  149542. +gceSTATUS
  149543. +gckOS_MapPhysical(
  149544. + IN gckOS Os,
  149545. + IN gctUINT32 Physical,
  149546. + IN gctSIZE_T Bytes,
  149547. + OUT gctPOINTER * Logical
  149548. + );
  149549. +
  149550. +/* Unmap previously mapped physical memory. */
  149551. +gceSTATUS
  149552. +gckOS_UnmapPhysical(
  149553. + IN gckOS Os,
  149554. + IN gctPOINTER Logical,
  149555. + IN gctSIZE_T Bytes
  149556. + );
  149557. +
  149558. +/* Read data from a hardware register. */
  149559. +gceSTATUS
  149560. +gckOS_ReadRegister(
  149561. + IN gckOS Os,
  149562. + IN gctUINT32 Address,
  149563. + OUT gctUINT32 * Data
  149564. + );
  149565. +
  149566. +/* Read data from a hardware register. */
  149567. +gceSTATUS
  149568. +gckOS_ReadRegisterEx(
  149569. + IN gckOS Os,
  149570. + IN gceCORE Core,
  149571. + IN gctUINT32 Address,
  149572. + OUT gctUINT32 * Data
  149573. + );
  149574. +
  149575. +/* Write data to a hardware register. */
  149576. +gceSTATUS
  149577. +gckOS_WriteRegister(
  149578. + IN gckOS Os,
  149579. + IN gctUINT32 Address,
  149580. + IN gctUINT32 Data
  149581. + );
  149582. +
  149583. +/* Write data to a hardware register. */
  149584. +gceSTATUS
  149585. +gckOS_WriteRegisterEx(
  149586. + IN gckOS Os,
  149587. + IN gceCORE Core,
  149588. + IN gctUINT32 Address,
  149589. + IN gctUINT32 Data
  149590. + );
  149591. +
  149592. +/* Write data to a 32-bit memory location. */
  149593. +gceSTATUS
  149594. +gckOS_WriteMemory(
  149595. + IN gckOS Os,
  149596. + IN gctPOINTER Address,
  149597. + IN gctUINT32 Data
  149598. + );
  149599. +
  149600. +/* Map physical memory into the process space. */
  149601. +gceSTATUS
  149602. +gckOS_MapMemory(
  149603. + IN gckOS Os,
  149604. + IN gctPHYS_ADDR Physical,
  149605. + IN gctSIZE_T Bytes,
  149606. + OUT gctPOINTER * Logical
  149607. + );
  149608. +
  149609. +/* Unmap physical memory from the specified process space. */
  149610. +gceSTATUS
  149611. +gckOS_UnmapMemoryEx(
  149612. + IN gckOS Os,
  149613. + IN gctPHYS_ADDR Physical,
  149614. + IN gctSIZE_T Bytes,
  149615. + IN gctPOINTER Logical,
  149616. + IN gctUINT32 PID
  149617. + );
  149618. +
  149619. +/* Unmap physical memory from the process space. */
  149620. +gceSTATUS
  149621. +gckOS_UnmapMemory(
  149622. + IN gckOS Os,
  149623. + IN gctPHYS_ADDR Physical,
  149624. + IN gctSIZE_T Bytes,
  149625. + IN gctPOINTER Logical
  149626. + );
  149627. +
  149628. +/* Unmap user logical memory out of physical memory.
  149629. + * This function is only supported in Linux currently.
  149630. + */
  149631. +gceSTATUS
  149632. +gckOS_UnmapUserLogical(
  149633. + IN gckOS Os,
  149634. + IN gctPHYS_ADDR Physical,
  149635. + IN gctSIZE_T Bytes,
  149636. + IN gctPOINTER Logical
  149637. + );
  149638. +
  149639. +/* Create a new mutex. */
  149640. +gceSTATUS
  149641. +gckOS_CreateMutex(
  149642. + IN gckOS Os,
  149643. + OUT gctPOINTER * Mutex
  149644. + );
  149645. +
  149646. +/* Delete a mutex. */
  149647. +gceSTATUS
  149648. +gckOS_DeleteMutex(
  149649. + IN gckOS Os,
  149650. + IN gctPOINTER Mutex
  149651. + );
  149652. +
  149653. +/* Acquire a mutex. */
  149654. +gceSTATUS
  149655. +gckOS_AcquireMutex(
  149656. + IN gckOS Os,
  149657. + IN gctPOINTER Mutex,
  149658. + IN gctUINT32 Timeout
  149659. + );
  149660. +
  149661. +/* Release a mutex. */
  149662. +gceSTATUS
  149663. +gckOS_ReleaseMutex(
  149664. + IN gckOS Os,
  149665. + IN gctPOINTER Mutex
  149666. + );
  149667. +
  149668. +/* Atomically exchange a pair of 32-bit values. */
  149669. +gceSTATUS
  149670. +gckOS_AtomicExchange(
  149671. + IN gckOS Os,
  149672. + IN OUT gctUINT32_PTR Target,
  149673. + IN gctUINT32 NewValue,
  149674. + OUT gctUINT32_PTR OldValue
  149675. + );
  149676. +
  149677. +/* Atomically exchange a pair of pointers. */
  149678. +gceSTATUS
  149679. +gckOS_AtomicExchangePtr(
  149680. + IN gckOS Os,
  149681. + IN OUT gctPOINTER * Target,
  149682. + IN gctPOINTER NewValue,
  149683. + OUT gctPOINTER * OldValue
  149684. + );
  149685. +
  149686. +#if gcdSMP
  149687. +gceSTATUS
  149688. +gckOS_AtomSetMask(
  149689. + IN gctPOINTER Atom,
  149690. + IN gctUINT32 Mask
  149691. + );
  149692. +
  149693. +gceSTATUS
  149694. +gckOS_AtomClearMask(
  149695. + IN gctPOINTER Atom,
  149696. + IN gctUINT32 Mask
  149697. + );
  149698. +#endif
  149699. +
  149700. +gceSTATUS
  149701. +gckOS_DumpCallStack(
  149702. + IN gckOS Os
  149703. + );
  149704. +
  149705. +gceSTATUS
  149706. +gckOS_GetProcessNameByPid(
  149707. + IN gctINT Pid,
  149708. + IN gctSIZE_T Length,
  149709. + OUT gctUINT8_PTR String
  149710. + );
  149711. +
  149712. +
  149713. +
  149714. +/*******************************************************************************
  149715. +**
  149716. +** gckOS_AtomConstruct
  149717. +**
  149718. +** Create an atom.
  149719. +**
  149720. +** INPUT:
  149721. +**
  149722. +** gckOS Os
  149723. +** Pointer to a gckOS object.
  149724. +**
  149725. +** OUTPUT:
  149726. +**
  149727. +** gctPOINTER * Atom
  149728. +** Pointer to a variable receiving the constructed atom.
  149729. +*/
  149730. +gceSTATUS
  149731. +gckOS_AtomConstruct(
  149732. + IN gckOS Os,
  149733. + OUT gctPOINTER * Atom
  149734. + );
  149735. +
  149736. +/*******************************************************************************
  149737. +**
  149738. +** gckOS_AtomDestroy
  149739. +**
  149740. +** Destroy an atom.
  149741. +**
  149742. +** INPUT:
  149743. +**
  149744. +** gckOS Os
  149745. +** Pointer to a gckOS object.
  149746. +**
  149747. +** gctPOINTER Atom
  149748. +** Pointer to the atom to destroy.
  149749. +**
  149750. +** OUTPUT:
  149751. +**
  149752. +** Nothing.
  149753. +*/
  149754. +gceSTATUS
  149755. +gckOS_AtomDestroy(
  149756. + IN gckOS Os,
  149757. + OUT gctPOINTER Atom
  149758. + );
  149759. +
  149760. +/*******************************************************************************
  149761. +**
  149762. +** gckOS_AtomGet
  149763. +**
  149764. +** Get the 32-bit value protected by an atom.
  149765. +**
  149766. +** INPUT:
  149767. +**
  149768. +** gckOS Os
  149769. +** Pointer to a gckOS object.
  149770. +**
  149771. +** gctPOINTER Atom
  149772. +** Pointer to the atom.
  149773. +**
  149774. +** OUTPUT:
  149775. +**
  149776. +** gctINT32_PTR Value
  149777. +** Pointer to a variable the receives the value of the atom.
  149778. +*/
  149779. +gceSTATUS
  149780. +gckOS_AtomGet(
  149781. + IN gckOS Os,
  149782. + IN gctPOINTER Atom,
  149783. + OUT gctINT32_PTR Value
  149784. + );
  149785. +
  149786. +/*******************************************************************************
  149787. +**
  149788. +** gckOS_AtomSet
  149789. +**
  149790. +** Set the 32-bit value protected by an atom.
  149791. +**
  149792. +** INPUT:
  149793. +**
  149794. +** gckOS Os
  149795. +** Pointer to a gckOS object.
  149796. +**
  149797. +** gctPOINTER Atom
  149798. +** Pointer to the atom.
  149799. +**
  149800. +** gctINT32 Value
  149801. +** The value of the atom.
  149802. +**
  149803. +** OUTPUT:
  149804. +**
  149805. +** Nothing.
  149806. +*/
  149807. +gceSTATUS
  149808. +gckOS_AtomSet(
  149809. + IN gckOS Os,
  149810. + IN gctPOINTER Atom,
  149811. + IN gctINT32 Value
  149812. + );
  149813. +
  149814. +/*******************************************************************************
  149815. +**
  149816. +** gckOS_AtomIncrement
  149817. +**
  149818. +** Atomically increment the 32-bit integer value inside an atom.
  149819. +**
  149820. +** INPUT:
  149821. +**
  149822. +** gckOS Os
  149823. +** Pointer to a gckOS object.
  149824. +**
  149825. +** gctPOINTER Atom
  149826. +** Pointer to the atom.
  149827. +**
  149828. +** OUTPUT:
  149829. +**
  149830. +** gctINT32_PTR Value
  149831. +** Pointer to a variable the receives the original value of the atom.
  149832. +*/
  149833. +gceSTATUS
  149834. +gckOS_AtomIncrement(
  149835. + IN gckOS Os,
  149836. + IN gctPOINTER Atom,
  149837. + OUT gctINT32_PTR Value
  149838. + );
  149839. +
  149840. +/*******************************************************************************
  149841. +**
  149842. +** gckOS_AtomDecrement
  149843. +**
  149844. +** Atomically decrement the 32-bit integer value inside an atom.
  149845. +**
  149846. +** INPUT:
  149847. +**
  149848. +** gckOS Os
  149849. +** Pointer to a gckOS object.
  149850. +**
  149851. +** gctPOINTER Atom
  149852. +** Pointer to the atom.
  149853. +**
  149854. +** OUTPUT:
  149855. +**
  149856. +** gctINT32_PTR Value
  149857. +** Pointer to a variable the receives the original value of the atom.
  149858. +*/
  149859. +gceSTATUS
  149860. +gckOS_AtomDecrement(
  149861. + IN gckOS Os,
  149862. + IN gctPOINTER Atom,
  149863. + OUT gctINT32_PTR Value
  149864. + );
  149865. +
  149866. +/* Delay a number of microseconds. */
  149867. +gceSTATUS
  149868. +gckOS_Delay(
  149869. + IN gckOS Os,
  149870. + IN gctUINT32 Delay
  149871. + );
  149872. +
  149873. +/* Get time in milliseconds. */
  149874. +gceSTATUS
  149875. +gckOS_GetTicks(
  149876. + OUT gctUINT32_PTR Time
  149877. + );
  149878. +
  149879. +/* Compare time value. */
  149880. +gceSTATUS
  149881. +gckOS_TicksAfter(
  149882. + IN gctUINT32 Time1,
  149883. + IN gctUINT32 Time2,
  149884. + OUT gctBOOL_PTR IsAfter
  149885. + );
  149886. +
  149887. +/* Get time in microseconds. */
  149888. +gceSTATUS
  149889. +gckOS_GetTime(
  149890. + OUT gctUINT64_PTR Time
  149891. + );
  149892. +
  149893. +/* Memory barrier. */
  149894. +gceSTATUS
  149895. +gckOS_MemoryBarrier(
  149896. + IN gckOS Os,
  149897. + IN gctPOINTER Address
  149898. + );
  149899. +
  149900. +/* Map user pointer. */
  149901. +gceSTATUS
  149902. +gckOS_MapUserPointer(
  149903. + IN gckOS Os,
  149904. + IN gctPOINTER Pointer,
  149905. + IN gctSIZE_T Size,
  149906. + OUT gctPOINTER * KernelPointer
  149907. + );
  149908. +
  149909. +/* Unmap user pointer. */
  149910. +gceSTATUS
  149911. +gckOS_UnmapUserPointer(
  149912. + IN gckOS Os,
  149913. + IN gctPOINTER Pointer,
  149914. + IN gctSIZE_T Size,
  149915. + IN gctPOINTER KernelPointer
  149916. + );
  149917. +
  149918. +/*******************************************************************************
  149919. +**
  149920. +** gckOS_QueryNeedCopy
  149921. +**
  149922. +** Query whether the memory can be accessed or mapped directly or it has to be
  149923. +** copied.
  149924. +**
  149925. +** INPUT:
  149926. +**
  149927. +** gckOS Os
  149928. +** Pointer to an gckOS object.
  149929. +**
  149930. +** gctUINT32 ProcessID
  149931. +** Process ID of the current process.
  149932. +**
  149933. +** OUTPUT:
  149934. +**
  149935. +** gctBOOL_PTR NeedCopy
  149936. +** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
  149937. +** gcvFALSE if the memory can be accessed or mapped dircetly.
  149938. +*/
  149939. +gceSTATUS
  149940. +gckOS_QueryNeedCopy(
  149941. + IN gckOS Os,
  149942. + IN gctUINT32 ProcessID,
  149943. + OUT gctBOOL_PTR NeedCopy
  149944. + );
  149945. +
  149946. +/*******************************************************************************
  149947. +**
  149948. +** gckOS_CopyFromUserData
  149949. +**
  149950. +** Copy data from user to kernel memory.
  149951. +**
  149952. +** INPUT:
  149953. +**
  149954. +** gckOS Os
  149955. +** Pointer to an gckOS object.
  149956. +**
  149957. +** gctPOINTER KernelPointer
  149958. +** Pointer to kernel memory.
  149959. +**
  149960. +** gctPOINTER Pointer
  149961. +** Pointer to user memory.
  149962. +**
  149963. +** gctSIZE_T Size
  149964. +** Number of bytes to copy.
  149965. +**
  149966. +** OUTPUT:
  149967. +**
  149968. +** Nothing.
  149969. +*/
  149970. +gceSTATUS
  149971. +gckOS_CopyFromUserData(
  149972. + IN gckOS Os,
  149973. + IN gctPOINTER KernelPointer,
  149974. + IN gctPOINTER Pointer,
  149975. + IN gctSIZE_T Size
  149976. + );
  149977. +
  149978. +/*******************************************************************************
  149979. +**
  149980. +** gckOS_CopyToUserData
  149981. +**
  149982. +** Copy data from kernel to user memory.
  149983. +**
  149984. +** INPUT:
  149985. +**
  149986. +** gckOS Os
  149987. +** Pointer to an gckOS object.
  149988. +**
  149989. +** gctPOINTER KernelPointer
  149990. +** Pointer to kernel memory.
  149991. +**
  149992. +** gctPOINTER Pointer
  149993. +** Pointer to user memory.
  149994. +**
  149995. +** gctSIZE_T Size
  149996. +** Number of bytes to copy.
  149997. +**
  149998. +** OUTPUT:
  149999. +**
  150000. +** Nothing.
  150001. +*/
  150002. +gceSTATUS
  150003. +gckOS_CopyToUserData(
  150004. + IN gckOS Os,
  150005. + IN gctPOINTER KernelPointer,
  150006. + IN gctPOINTER Pointer,
  150007. + IN gctSIZE_T Size
  150008. + );
  150009. +
  150010. +#ifdef __QNXNTO__
  150011. +/* Map user physical address. */
  150012. +gceSTATUS
  150013. +gckOS_MapUserPhysical(
  150014. + IN gckOS Os,
  150015. + IN gctPHYS_ADDR Phys,
  150016. + OUT gctPOINTER * KernelPointer
  150017. + );
  150018. +#endif
  150019. +
  150020. +gceSTATUS
  150021. +gckOS_SuspendInterrupt(
  150022. + IN gckOS Os
  150023. + );
  150024. +
  150025. +gceSTATUS
  150026. +gckOS_SuspendInterruptEx(
  150027. + IN gckOS Os,
  150028. + IN gceCORE Core
  150029. + );
  150030. +
  150031. +gceSTATUS
  150032. +gckOS_ResumeInterrupt(
  150033. + IN gckOS Os
  150034. + );
  150035. +
  150036. +gceSTATUS
  150037. +gckOS_ResumeInterruptEx(
  150038. + IN gckOS Os,
  150039. + IN gceCORE Core
  150040. + );
  150041. +
  150042. +/* Get the base address for the physical memory. */
  150043. +gceSTATUS
  150044. +gckOS_GetBaseAddress(
  150045. + IN gckOS Os,
  150046. + OUT gctUINT32_PTR BaseAddress
  150047. + );
  150048. +
  150049. +/* Perform a memory copy. */
  150050. +gceSTATUS
  150051. +gckOS_MemCopy(
  150052. + IN gctPOINTER Destination,
  150053. + IN gctCONST_POINTER Source,
  150054. + IN gctSIZE_T Bytes
  150055. + );
  150056. +
  150057. +/* Zero memory. */
  150058. +gceSTATUS
  150059. +gckOS_ZeroMemory(
  150060. + IN gctPOINTER Memory,
  150061. + IN gctSIZE_T Bytes
  150062. + );
  150063. +
  150064. +/* Device I/O control to the kernel HAL layer. */
  150065. +gceSTATUS
  150066. +gckOS_DeviceControl(
  150067. + IN gckOS Os,
  150068. + IN gctBOOL FromUser,
  150069. + IN gctUINT32 IoControlCode,
  150070. + IN gctPOINTER InputBuffer,
  150071. + IN gctSIZE_T InputBufferSize,
  150072. + OUT gctPOINTER OutputBuffer,
  150073. + IN gctSIZE_T OutputBufferSize
  150074. + );
  150075. +
  150076. +/*******************************************************************************
  150077. +**
  150078. +** gckOS_GetProcessID
  150079. +**
  150080. +** Get current process ID.
  150081. +**
  150082. +** INPUT:
  150083. +**
  150084. +** Nothing.
  150085. +**
  150086. +** OUTPUT:
  150087. +**
  150088. +** gctUINT32_PTR ProcessID
  150089. +** Pointer to the variable that receives the process ID.
  150090. +*/
  150091. +gceSTATUS
  150092. +gckOS_GetProcessID(
  150093. + OUT gctUINT32_PTR ProcessID
  150094. + );
  150095. +
  150096. +gceSTATUS
  150097. +gckOS_GetCurrentProcessID(
  150098. + OUT gctUINT32_PTR ProcessID
  150099. + );
  150100. +
  150101. +/*******************************************************************************
  150102. +**
  150103. +** gckOS_GetThreadID
  150104. +**
  150105. +** Get current thread ID.
  150106. +**
  150107. +** INPUT:
  150108. +**
  150109. +** Nothing.
  150110. +**
  150111. +** OUTPUT:
  150112. +**
  150113. +** gctUINT32_PTR ThreadID
  150114. +** Pointer to the variable that receives the thread ID.
  150115. +*/
  150116. +gceSTATUS
  150117. +gckOS_GetThreadID(
  150118. + OUT gctUINT32_PTR ThreadID
  150119. + );
  150120. +
  150121. +/******************************************************************************\
  150122. +********************************** Signal Object *********************************
  150123. +\******************************************************************************/
  150124. +
  150125. +/* Create a signal. */
  150126. +gceSTATUS
  150127. +gckOS_CreateSignal(
  150128. + IN gckOS Os,
  150129. + IN gctBOOL ManualReset,
  150130. + OUT gctSIGNAL * Signal
  150131. + );
  150132. +
  150133. +/* Destroy a signal. */
  150134. +gceSTATUS
  150135. +gckOS_DestroySignal(
  150136. + IN gckOS Os,
  150137. + IN gctSIGNAL Signal
  150138. + );
  150139. +
  150140. +/* Signal a signal. */
  150141. +gceSTATUS
  150142. +gckOS_Signal(
  150143. + IN gckOS Os,
  150144. + IN gctSIGNAL Signal,
  150145. + IN gctBOOL State
  150146. + );
  150147. +
  150148. +/* Wait for a signal. */
  150149. +gceSTATUS
  150150. +gckOS_WaitSignal(
  150151. + IN gckOS Os,
  150152. + IN gctSIGNAL Signal,
  150153. + IN gctUINT32 Wait
  150154. + );
  150155. +
  150156. +/* Map a user signal to the kernel space. */
  150157. +gceSTATUS
  150158. +gckOS_MapSignal(
  150159. + IN gckOS Os,
  150160. + IN gctSIGNAL Signal,
  150161. + IN gctHANDLE Process,
  150162. + OUT gctSIGNAL * MappedSignal
  150163. + );
  150164. +
  150165. +/* Unmap a user signal */
  150166. +gceSTATUS
  150167. +gckOS_UnmapSignal(
  150168. + IN gckOS Os,
  150169. + IN gctSIGNAL Signal
  150170. + );
  150171. +
  150172. +/* Map user memory. */
  150173. +gceSTATUS
  150174. +gckOS_MapUserMemory(
  150175. + IN gckOS Os,
  150176. + IN gceCORE Core,
  150177. + IN gctPOINTER Memory,
  150178. + IN gctUINT32 Physical,
  150179. + IN gctSIZE_T Size,
  150180. + OUT gctPOINTER * Info,
  150181. + OUT gctUINT32_PTR Address
  150182. + );
  150183. +
  150184. +/* Unmap user memory. */
  150185. +gceSTATUS
  150186. +gckOS_UnmapUserMemory(
  150187. + IN gckOS Os,
  150188. + IN gceCORE Core,
  150189. + IN gctPOINTER Memory,
  150190. + IN gctSIZE_T Size,
  150191. + IN gctPOINTER Info,
  150192. + IN gctUINT32 Address
  150193. + );
  150194. +
  150195. +/******************************************************************************\
  150196. +************************** Android Native Fence Sync ***************************
  150197. +\******************************************************************************/
  150198. +gceSTATUS
  150199. +gckOS_CreateSyncTimeline(
  150200. + IN gckOS Os,
  150201. + OUT gctHANDLE * Timeline
  150202. + );
  150203. +
  150204. +gceSTATUS
  150205. +gckOS_DestroySyncTimeline(
  150206. + IN gckOS Os,
  150207. + IN gctHANDLE Timeline
  150208. + );
  150209. +
  150210. +gceSTATUS
  150211. +gckOS_CreateSyncPoint(
  150212. + IN gckOS Os,
  150213. + OUT gctSYNC_POINT * SyncPoint
  150214. + );
  150215. +
  150216. +gceSTATUS
  150217. +gckOS_ReferenceSyncPoint(
  150218. + IN gckOS Os,
  150219. + IN gctSYNC_POINT SyncPoint
  150220. + );
  150221. +
  150222. +gceSTATUS
  150223. +gckOS_DestroySyncPoint(
  150224. + IN gckOS Os,
  150225. + IN gctSYNC_POINT SyncPoint
  150226. + );
  150227. +
  150228. +gceSTATUS
  150229. +gckOS_SignalSyncPoint(
  150230. + IN gckOS Os,
  150231. + IN gctSYNC_POINT SyncPoint
  150232. + );
  150233. +
  150234. +gceSTATUS
  150235. +gckOS_QuerySyncPoint(
  150236. + IN gckOS Os,
  150237. + IN gctSYNC_POINT SyncPoint,
  150238. + OUT gctBOOL_PTR State
  150239. + );
  150240. +
  150241. +gceSTATUS
  150242. +gckOS_CreateNativeFence(
  150243. + IN gckOS Os,
  150244. + IN gctHANDLE Timeline,
  150245. + IN gctSYNC_POINT SyncPoint,
  150246. + OUT gctINT * FenceFD
  150247. + );
  150248. +
  150249. +#if !USE_NEW_LINUX_SIGNAL
  150250. +/* Create signal to be used in the user space. */
  150251. +gceSTATUS
  150252. +gckOS_CreateUserSignal(
  150253. + IN gckOS Os,
  150254. + IN gctBOOL ManualReset,
  150255. + OUT gctINT * SignalID
  150256. + );
  150257. +
  150258. +/* Destroy signal used in the user space. */
  150259. +gceSTATUS
  150260. +gckOS_DestroyUserSignal(
  150261. + IN gckOS Os,
  150262. + IN gctINT SignalID
  150263. + );
  150264. +
  150265. +/* Wait for signal used in the user space. */
  150266. +gceSTATUS
  150267. +gckOS_WaitUserSignal(
  150268. + IN gckOS Os,
  150269. + IN gctINT SignalID,
  150270. + IN gctUINT32 Wait
  150271. + );
  150272. +
  150273. +/* Signal a signal used in the user space. */
  150274. +gceSTATUS
  150275. +gckOS_SignalUserSignal(
  150276. + IN gckOS Os,
  150277. + IN gctINT SignalID,
  150278. + IN gctBOOL State
  150279. + );
  150280. +#endif /* USE_NEW_LINUX_SIGNAL */
  150281. +
  150282. +/* Set a signal owned by a process. */
  150283. +#if defined(__QNXNTO__)
  150284. +gceSTATUS
  150285. +gckOS_UserSignal(
  150286. + IN gckOS Os,
  150287. + IN gctSIGNAL Signal,
  150288. + IN gctINT Recvid,
  150289. + IN gctINT Coid
  150290. + );
  150291. +#else
  150292. +gceSTATUS
  150293. +gckOS_UserSignal(
  150294. + IN gckOS Os,
  150295. + IN gctSIGNAL Signal,
  150296. + IN gctHANDLE Process
  150297. + );
  150298. +#endif
  150299. +
  150300. +/******************************************************************************\
  150301. +** Cache Support
  150302. +*/
  150303. +
  150304. +gceSTATUS
  150305. +gckOS_CacheClean(
  150306. + gckOS Os,
  150307. + gctUINT32 ProcessID,
  150308. + gctPHYS_ADDR Handle,
  150309. + gctPOINTER Physical,
  150310. + gctPOINTER Logical,
  150311. + gctSIZE_T Bytes
  150312. + );
  150313. +
  150314. +gceSTATUS
  150315. +gckOS_CacheFlush(
  150316. + gckOS Os,
  150317. + gctUINT32 ProcessID,
  150318. + gctPHYS_ADDR Handle,
  150319. + gctPOINTER Physical,
  150320. + gctPOINTER Logical,
  150321. + gctSIZE_T Bytes
  150322. + );
  150323. +
  150324. +gceSTATUS
  150325. +gckOS_CacheInvalidate(
  150326. + gckOS Os,
  150327. + gctUINT32 ProcessID,
  150328. + gctPHYS_ADDR Handle,
  150329. + gctPOINTER Physical,
  150330. + gctPOINTER Logical,
  150331. + gctSIZE_T Bytes
  150332. + );
  150333. +
  150334. +/******************************************************************************\
  150335. +** Debug Support
  150336. +*/
  150337. +
  150338. +void
  150339. +gckOS_SetDebugLevel(
  150340. + IN gctUINT32 Level
  150341. + );
  150342. +
  150343. +void
  150344. +gckOS_SetDebugZone(
  150345. + IN gctUINT32 Zone
  150346. + );
  150347. +
  150348. +void
  150349. +gckOS_SetDebugLevelZone(
  150350. + IN gctUINT32 Level,
  150351. + IN gctUINT32 Zone
  150352. + );
  150353. +
  150354. +void
  150355. +gckOS_SetDebugZones(
  150356. + IN gctUINT32 Zones,
  150357. + IN gctBOOL Enable
  150358. + );
  150359. +
  150360. +void
  150361. +gckOS_SetDebugFile(
  150362. + IN gctCONST_STRING FileName
  150363. + );
  150364. +
  150365. +/*******************************************************************************
  150366. +** Broadcast interface.
  150367. +*/
  150368. +
  150369. +typedef enum _gceBROADCAST
  150370. +{
  150371. + /* GPU might be idle. */
  150372. + gcvBROADCAST_GPU_IDLE,
  150373. +
  150374. + /* A commit is going to happen. */
  150375. + gcvBROADCAST_GPU_COMMIT,
  150376. +
  150377. + /* GPU seems to be stuck. */
  150378. + gcvBROADCAST_GPU_STUCK,
  150379. +
  150380. + /* First process gets attached. */
  150381. + gcvBROADCAST_FIRST_PROCESS,
  150382. +
  150383. + /* Last process gets detached. */
  150384. + gcvBROADCAST_LAST_PROCESS,
  150385. +
  150386. + /* AXI bus error. */
  150387. + gcvBROADCAST_AXI_BUS_ERROR,
  150388. +}
  150389. +gceBROADCAST;
  150390. +
  150391. +gceSTATUS
  150392. +gckOS_Broadcast(
  150393. + IN gckOS Os,
  150394. + IN gckHARDWARE Hardware,
  150395. + IN gceBROADCAST Reason
  150396. + );
  150397. +
  150398. +gceSTATUS
  150399. +gckOS_BroadcastHurry(
  150400. + IN gckOS Os,
  150401. + IN gckHARDWARE Hardware,
  150402. + IN gctUINT Urgency
  150403. + );
  150404. +
  150405. +gceSTATUS
  150406. +gckOS_BroadcastCalibrateSpeed(
  150407. + IN gckOS Os,
  150408. + IN gckHARDWARE Hardware,
  150409. + IN gctUINT Idle,
  150410. + IN gctUINT Time
  150411. + );
  150412. +
  150413. +/*******************************************************************************
  150414. +**
  150415. +** gckOS_SetGPUPower
  150416. +**
  150417. +** Set the power of the GPU on or off.
  150418. +**
  150419. +** INPUT:
  150420. +**
  150421. +** gckOS Os
  150422. +** Pointer to a gckOS object.ß
  150423. +**
  150424. +** gckCORE Core
  150425. +** GPU whose power is set.
  150426. +**
  150427. +** gctBOOL Clock
  150428. +** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
  150429. +**
  150430. +** gctBOOL Power
  150431. +** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
  150432. +**
  150433. +** OUTPUT:
  150434. +**
  150435. +** Nothing.
  150436. +*/
  150437. +gceSTATUS
  150438. +gckOS_SetGPUPower(
  150439. + IN gckOS Os,
  150440. + IN gceCORE Core,
  150441. + IN gctBOOL Clock,
  150442. + IN gctBOOL Power
  150443. + );
  150444. +
  150445. +gceSTATUS
  150446. +gckOS_ResetGPU(
  150447. + IN gckOS Os,
  150448. + IN gceCORE Core
  150449. + );
  150450. +
  150451. +gceSTATUS
  150452. +gckOS_PrepareGPUFrequency(
  150453. + IN gckOS Os,
  150454. + IN gceCORE Core
  150455. + );
  150456. +
  150457. +gceSTATUS
  150458. +gckOS_FinishGPUFrequency(
  150459. + IN gckOS Os,
  150460. + IN gceCORE Core
  150461. + );
  150462. +
  150463. +gceSTATUS
  150464. +gckOS_QueryGPUFrequency(
  150465. + IN gckOS Os,
  150466. + IN gceCORE Core,
  150467. + OUT gctUINT32 * Frequency,
  150468. + OUT gctUINT8 * Scale
  150469. + );
  150470. +
  150471. +gceSTATUS
  150472. +gckOS_SetGPUFrequency(
  150473. + IN gckOS Os,
  150474. + IN gceCORE Core,
  150475. + IN gctUINT8 Scale
  150476. + );
  150477. +
  150478. +/*******************************************************************************
  150479. +** Semaphores.
  150480. +*/
  150481. +
  150482. +/* Create a new semaphore. */
  150483. +gceSTATUS
  150484. +gckOS_CreateSemaphore(
  150485. + IN gckOS Os,
  150486. + OUT gctPOINTER * Semaphore
  150487. + );
  150488. +
  150489. +#if gcdENABLE_VG
  150490. +gceSTATUS
  150491. +gckOS_CreateSemaphoreVG(
  150492. + IN gckOS Os,
  150493. + OUT gctPOINTER * Semaphore
  150494. + );
  150495. +#endif
  150496. +
  150497. +/* Delete a semahore. */
  150498. +gceSTATUS
  150499. +gckOS_DestroySemaphore(
  150500. + IN gckOS Os,
  150501. + IN gctPOINTER Semaphore
  150502. + );
  150503. +
  150504. +/* Acquire a semahore. */
  150505. +gceSTATUS
  150506. +gckOS_AcquireSemaphore(
  150507. + IN gckOS Os,
  150508. + IN gctPOINTER Semaphore
  150509. + );
  150510. +
  150511. +/* Try to acquire a semahore. */
  150512. +gceSTATUS
  150513. +gckOS_TryAcquireSemaphore(
  150514. + IN gckOS Os,
  150515. + IN gctPOINTER Semaphore
  150516. + );
  150517. +
  150518. +/* Release a semahore. */
  150519. +gceSTATUS
  150520. +gckOS_ReleaseSemaphore(
  150521. + IN gckOS Os,
  150522. + IN gctPOINTER Semaphore
  150523. + );
  150524. +
  150525. +/*******************************************************************************
  150526. +** Timer API.
  150527. +*/
  150528. +
  150529. +typedef void (*gctTIMERFUNCTION)(gctPOINTER);
  150530. +
  150531. +/* Create a timer. */
  150532. +gceSTATUS
  150533. +gckOS_CreateTimer(
  150534. + IN gckOS Os,
  150535. + IN gctTIMERFUNCTION Function,
  150536. + IN gctPOINTER Data,
  150537. + OUT gctPOINTER * Timer
  150538. + );
  150539. +
  150540. +/* Destory a timer. */
  150541. +gceSTATUS
  150542. +gckOS_DestroyTimer(
  150543. + IN gckOS Os,
  150544. + IN gctPOINTER Timer
  150545. + );
  150546. +
  150547. +/* Start a timer. */
  150548. +gceSTATUS
  150549. +gckOS_StartTimer(
  150550. + IN gckOS Os,
  150551. + IN gctPOINTER Timer,
  150552. + IN gctUINT32 Delay
  150553. + );
  150554. +
  150555. +/* Stop a timer. */
  150556. +gceSTATUS
  150557. +gckOS_StopTimer(
  150558. + IN gckOS Os,
  150559. + IN gctPOINTER Timer
  150560. + );
  150561. +
  150562. +/******************************************************************************\
  150563. +********************************* gckHEAP Object ********************************
  150564. +\******************************************************************************/
  150565. +
  150566. +typedef struct _gckHEAP * gckHEAP;
  150567. +
  150568. +/* Construct a new gckHEAP object. */
  150569. +gceSTATUS
  150570. +gckHEAP_Construct(
  150571. + IN gckOS Os,
  150572. + IN gctSIZE_T AllocationSize,
  150573. + OUT gckHEAP * Heap
  150574. + );
  150575. +
  150576. +/* Destroy an gckHEAP object. */
  150577. +gceSTATUS
  150578. +gckHEAP_Destroy(
  150579. + IN gckHEAP Heap
  150580. + );
  150581. +
  150582. +/* Allocate memory. */
  150583. +gceSTATUS
  150584. +gckHEAP_Allocate(
  150585. + IN gckHEAP Heap,
  150586. + IN gctSIZE_T Bytes,
  150587. + OUT gctPOINTER * Node
  150588. + );
  150589. +
  150590. +/* Free memory. */
  150591. +gceSTATUS
  150592. +gckHEAP_Free(
  150593. + IN gckHEAP Heap,
  150594. + IN gctPOINTER Node
  150595. + );
  150596. +
  150597. +/* Profile the heap. */
  150598. +gceSTATUS
  150599. +gckHEAP_ProfileStart(
  150600. + IN gckHEAP Heap
  150601. + );
  150602. +
  150603. +gceSTATUS
  150604. +gckHEAP_ProfileEnd(
  150605. + IN gckHEAP Heap,
  150606. + IN gctCONST_STRING Title
  150607. + );
  150608. +
  150609. +
  150610. +/******************************************************************************\
  150611. +******************************** gckVIDMEM Object ******************************
  150612. +\******************************************************************************/
  150613. +
  150614. +typedef struct _gckVIDMEM * gckVIDMEM;
  150615. +typedef struct _gckKERNEL * gckKERNEL;
  150616. +typedef struct _gckDB * gckDB;
  150617. +typedef struct _gckDVFS * gckDVFS;
  150618. +
  150619. +/* Construct a new gckVIDMEM object. */
  150620. +gceSTATUS
  150621. +gckVIDMEM_Construct(
  150622. + IN gckOS Os,
  150623. + IN gctUINT32 BaseAddress,
  150624. + IN gctSIZE_T Bytes,
  150625. + IN gctSIZE_T Threshold,
  150626. + IN gctSIZE_T Banking,
  150627. + OUT gckVIDMEM * Memory
  150628. + );
  150629. +
  150630. +/* Destroy an gckVDIMEM object. */
  150631. +gceSTATUS
  150632. +gckVIDMEM_Destroy(
  150633. + IN gckVIDMEM Memory
  150634. + );
  150635. +
  150636. +/* Allocate rectangular memory. */
  150637. +gceSTATUS
  150638. +gckVIDMEM_Allocate(
  150639. + IN gckVIDMEM Memory,
  150640. + IN gctUINT Width,
  150641. + IN gctUINT Height,
  150642. + IN gctUINT Depth,
  150643. + IN gctUINT BytesPerPixel,
  150644. + IN gctUINT32 Alignment,
  150645. + IN gceSURF_TYPE Type,
  150646. + OUT gcuVIDMEM_NODE_PTR * Node
  150647. + );
  150648. +
  150649. +/* Allocate linear memory. */
  150650. +gceSTATUS
  150651. +gckVIDMEM_AllocateLinear(
  150652. + IN gckVIDMEM Memory,
  150653. + IN gctSIZE_T Bytes,
  150654. + IN gctUINT32 Alignment,
  150655. + IN gceSURF_TYPE Type,
  150656. + OUT gcuVIDMEM_NODE_PTR * Node
  150657. + );
  150658. +
  150659. +/* Free memory. */
  150660. +gceSTATUS
  150661. +gckVIDMEM_Free(
  150662. + IN gcuVIDMEM_NODE_PTR Node
  150663. + );
  150664. +
  150665. +/* Lock memory. */
  150666. +gceSTATUS
  150667. +gckVIDMEM_Lock(
  150668. + IN gckKERNEL Kernel,
  150669. + IN gcuVIDMEM_NODE_PTR Node,
  150670. + IN gctBOOL Cacheable,
  150671. + OUT gctUINT32 * Address
  150672. + );
  150673. +
  150674. +/* Unlock memory. */
  150675. +gceSTATUS
  150676. +gckVIDMEM_Unlock(
  150677. + IN gckKERNEL Kernel,
  150678. + IN gcuVIDMEM_NODE_PTR Node,
  150679. + IN gceSURF_TYPE Type,
  150680. + IN OUT gctBOOL * Asynchroneous
  150681. + );
  150682. +
  150683. +/* Construct a gcuVIDMEM_NODE union for virtual memory. */
  150684. +gceSTATUS
  150685. +gckVIDMEM_ConstructVirtual(
  150686. + IN gckKERNEL Kernel,
  150687. + IN gctBOOL Contiguous,
  150688. + IN gctSIZE_T Bytes,
  150689. + OUT gcuVIDMEM_NODE_PTR * Node
  150690. + );
  150691. +
  150692. +/* Destroy a gcuVIDMEM_NODE union for virtual memory. */
  150693. +gceSTATUS
  150694. +gckVIDMEM_DestroyVirtual(
  150695. + IN gcuVIDMEM_NODE_PTR Node
  150696. + );
  150697. +
  150698. +/******************************************************************************\
  150699. +******************************** gckKERNEL Object ******************************
  150700. +\******************************************************************************/
  150701. +
  150702. +struct _gcsHAL_INTERFACE;
  150703. +
  150704. +/* Notifications. */
  150705. +typedef enum _gceNOTIFY
  150706. +{
  150707. + gcvNOTIFY_INTERRUPT,
  150708. + gcvNOTIFY_COMMAND_QUEUE,
  150709. +}
  150710. +gceNOTIFY;
  150711. +
  150712. +/* Flush flags. */
  150713. +typedef enum _gceKERNEL_FLUSH
  150714. +{
  150715. + gcvFLUSH_COLOR = 0x01,
  150716. + gcvFLUSH_DEPTH = 0x02,
  150717. + gcvFLUSH_TEXTURE = 0x04,
  150718. + gcvFLUSH_2D = 0x08,
  150719. + gcvFLUSH_ALL = gcvFLUSH_COLOR
  150720. + | gcvFLUSH_DEPTH
  150721. + | gcvFLUSH_TEXTURE
  150722. + | gcvFLUSH_2D,
  150723. +}
  150724. +gceKERNEL_FLUSH;
  150725. +
  150726. +/* Construct a new gckKERNEL object. */
  150727. +gceSTATUS
  150728. +gckKERNEL_Construct(
  150729. + IN gckOS Os,
  150730. + IN gceCORE Core,
  150731. + IN gctPOINTER Context,
  150732. + IN gckDB SharedDB,
  150733. + OUT gckKERNEL * Kernel
  150734. + );
  150735. +
  150736. +/* Destroy an gckKERNEL object. */
  150737. +gceSTATUS
  150738. +gckKERNEL_Destroy(
  150739. + IN gckKERNEL Kernel
  150740. + );
  150741. +
  150742. +/* Dispatch a user-level command. */
  150743. +gceSTATUS
  150744. +gckKERNEL_Dispatch(
  150745. + IN gckKERNEL Kernel,
  150746. + IN gctBOOL FromUser,
  150747. + IN OUT struct _gcsHAL_INTERFACE * Interface
  150748. + );
  150749. +
  150750. +/* Query the video memory. */
  150751. +gceSTATUS
  150752. +gckKERNEL_QueryVideoMemory(
  150753. + IN gckKERNEL Kernel,
  150754. + OUT struct _gcsHAL_INTERFACE * Interface
  150755. + );
  150756. +
  150757. +/* Lookup the gckVIDMEM object for a pool. */
  150758. +gceSTATUS
  150759. +gckKERNEL_GetVideoMemoryPool(
  150760. + IN gckKERNEL Kernel,
  150761. + IN gcePOOL Pool,
  150762. + OUT gckVIDMEM * VideoMemory
  150763. + );
  150764. +
  150765. +#if gcdUSE_VIDMEM_PER_PID
  150766. +gceSTATUS
  150767. +gckKERNEL_GetVideoMemoryPoolPid(
  150768. + IN gckKERNEL Kernel,
  150769. + IN gcePOOL Pool,
  150770. + IN gctUINT32 Pid,
  150771. + OUT gckVIDMEM * VideoMemory
  150772. + );
  150773. +
  150774. +gceSTATUS
  150775. +gckKERNEL_CreateVideoMemoryPoolPid(
  150776. + IN gckKERNEL Kernel,
  150777. + IN gcePOOL Pool,
  150778. + IN gctUINT32 Pid,
  150779. + OUT gckVIDMEM * VideoMemory
  150780. + );
  150781. +
  150782. +gceSTATUS
  150783. +gckKERNEL_RemoveVideoMemoryPoolPid(
  150784. + IN gckKERNEL Kernel,
  150785. + IN gckVIDMEM VideoMemory
  150786. + );
  150787. +#endif
  150788. +
  150789. +/* Map video memory. */
  150790. +gceSTATUS
  150791. +gckKERNEL_MapVideoMemory(
  150792. + IN gckKERNEL Kernel,
  150793. + IN gctBOOL InUserSpace,
  150794. + IN gctUINT32 Address,
  150795. +#ifdef __QNXNTO__
  150796. + IN gctUINT32 Pid,
  150797. + IN gctUINT32 Bytes,
  150798. +#endif
  150799. + OUT gctPOINTER * Logical
  150800. + );
  150801. +
  150802. +/* Map video memory. */
  150803. +gceSTATUS
  150804. +gckKERNEL_MapVideoMemoryEx(
  150805. + IN gckKERNEL Kernel,
  150806. + IN gceCORE Core,
  150807. + IN gctBOOL InUserSpace,
  150808. + IN gctUINT32 Address,
  150809. +#ifdef __QNXNTO__
  150810. + IN gctUINT32 Pid,
  150811. + IN gctUINT32 Bytes,
  150812. +#endif
  150813. + OUT gctPOINTER * Logical
  150814. + );
  150815. +
  150816. +#ifdef __QNXNTO__
  150817. +/* Unmap video memory. */
  150818. +gceSTATUS
  150819. +gckKERNEL_UnmapVideoMemory(
  150820. + IN gckKERNEL Kernel,
  150821. + IN gctPOINTER Logical,
  150822. + IN gctUINT32 Pid,
  150823. + IN gctUINT32 Bytes
  150824. + );
  150825. +#endif
  150826. +
  150827. +/* Map memory. */
  150828. +gceSTATUS
  150829. +gckKERNEL_MapMemory(
  150830. + IN gckKERNEL Kernel,
  150831. + IN gctPHYS_ADDR Physical,
  150832. + IN gctSIZE_T Bytes,
  150833. + OUT gctPOINTER * Logical
  150834. + );
  150835. +
  150836. +/* Unmap memory. */
  150837. +gceSTATUS
  150838. +gckKERNEL_UnmapMemory(
  150839. + IN gckKERNEL Kernel,
  150840. + IN gctPHYS_ADDR Physical,
  150841. + IN gctSIZE_T Bytes,
  150842. + IN gctPOINTER Logical
  150843. + );
  150844. +
  150845. +/* Notification of events. */
  150846. +gceSTATUS
  150847. +gckKERNEL_Notify(
  150848. + IN gckKERNEL Kernel,
  150849. + IN gceNOTIFY Notifcation,
  150850. + IN gctBOOL Data
  150851. + );
  150852. +
  150853. +gceSTATUS
  150854. +gckKERNEL_QuerySettings(
  150855. + IN gckKERNEL Kernel,
  150856. + OUT gcsKERNEL_SETTINGS * Settings
  150857. + );
  150858. +
  150859. +/*******************************************************************************
  150860. +**
  150861. +** gckKERNEL_Recovery
  150862. +**
  150863. +** Try to recover the GPU from a fatal error.
  150864. +**
  150865. +** INPUT:
  150866. +**
  150867. +** gckKERNEL Kernel
  150868. +** Pointer to an gckKERNEL object.
  150869. +**
  150870. +** OUTPUT:
  150871. +**
  150872. +** Nothing.
  150873. +*/
  150874. +gceSTATUS
  150875. +gckKERNEL_Recovery(
  150876. + IN gckKERNEL Kernel
  150877. + );
  150878. +
  150879. +/* Set the value of timeout on HW operation. */
  150880. +void
  150881. +gckKERNEL_SetTimeOut(
  150882. + IN gckKERNEL Kernel,
  150883. + IN gctUINT32 timeOut
  150884. + );
  150885. +
  150886. +/* Get access to the user data. */
  150887. +gceSTATUS
  150888. +gckKERNEL_OpenUserData(
  150889. + IN gckKERNEL Kernel,
  150890. + IN gctBOOL NeedCopy,
  150891. + IN gctPOINTER StaticStorage,
  150892. + IN gctPOINTER UserPointer,
  150893. + IN gctSIZE_T Size,
  150894. + OUT gctPOINTER * KernelPointer
  150895. + );
  150896. +
  150897. +/* Release resources associated with the user data connection. */
  150898. +gceSTATUS
  150899. +gckKERNEL_CloseUserData(
  150900. + IN gckKERNEL Kernel,
  150901. + IN gctBOOL NeedCopy,
  150902. + IN gctBOOL FlushData,
  150903. + IN gctPOINTER UserPointer,
  150904. + IN gctSIZE_T Size,
  150905. + OUT gctPOINTER * KernelPointer
  150906. + );
  150907. +
  150908. +gceSTATUS
  150909. +gckDVFS_Construct(
  150910. + IN gckHARDWARE Hardware,
  150911. + OUT gckDVFS * Frequency
  150912. + );
  150913. +
  150914. +gceSTATUS
  150915. +gckDVFS_Destroy(
  150916. + IN gckDVFS Dvfs
  150917. + );
  150918. +
  150919. +gceSTATUS
  150920. +gckDVFS_Start(
  150921. + IN gckDVFS Dvfs
  150922. + );
  150923. +
  150924. +gceSTATUS
  150925. +gckDVFS_Stop(
  150926. + IN gckDVFS Dvfs
  150927. + );
  150928. +
  150929. +/******************************************************************************\
  150930. +******************************* gckHARDWARE Object *****************************
  150931. +\******************************************************************************/
  150932. +
  150933. +/* Construct a new gckHARDWARE object. */
  150934. +gceSTATUS
  150935. +gckHARDWARE_Construct(
  150936. + IN gckOS Os,
  150937. + IN gceCORE Core,
  150938. + OUT gckHARDWARE * Hardware
  150939. + );
  150940. +
  150941. +/* Destroy an gckHARDWARE object. */
  150942. +gceSTATUS
  150943. +gckHARDWARE_Destroy(
  150944. + IN gckHARDWARE Hardware
  150945. + );
  150946. +
  150947. +/* Get hardware type. */
  150948. +gceSTATUS
  150949. +gckHARDWARE_GetType(
  150950. + IN gckHARDWARE Hardware,
  150951. + OUT gceHARDWARE_TYPE * Type
  150952. + );
  150953. +
  150954. +/* Query system memory requirements. */
  150955. +gceSTATUS
  150956. +gckHARDWARE_QuerySystemMemory(
  150957. + IN gckHARDWARE Hardware,
  150958. + OUT gctSIZE_T * SystemSize,
  150959. + OUT gctUINT32 * SystemBaseAddress
  150960. + );
  150961. +
  150962. +/* Build virtual address. */
  150963. +gceSTATUS
  150964. +gckHARDWARE_BuildVirtualAddress(
  150965. + IN gckHARDWARE Hardware,
  150966. + IN gctUINT32 Index,
  150967. + IN gctUINT32 Offset,
  150968. + OUT gctUINT32 * Address
  150969. + );
  150970. +
  150971. +/* Query command buffer requirements. */
  150972. +gceSTATUS
  150973. +gckHARDWARE_QueryCommandBuffer(
  150974. + IN gckHARDWARE Hardware,
  150975. + OUT gctSIZE_T * Alignment,
  150976. + OUT gctSIZE_T * ReservedHead,
  150977. + OUT gctSIZE_T * ReservedTail
  150978. + );
  150979. +
  150980. +/* Add a WAIT/LINK pair in the command queue. */
  150981. +gceSTATUS
  150982. +gckHARDWARE_WaitLink(
  150983. + IN gckHARDWARE Hardware,
  150984. + IN gctPOINTER Logical,
  150985. + IN gctUINT32 Offset,
  150986. + IN OUT gctSIZE_T * Bytes,
  150987. + OUT gctUINT32 * WaitOffset,
  150988. + OUT gctSIZE_T * WaitBytes
  150989. + );
  150990. +
  150991. +/* Kickstart the command processor. */
  150992. +gceSTATUS
  150993. +gckHARDWARE_Execute(
  150994. + IN gckHARDWARE Hardware,
  150995. + IN gctPOINTER Logical,
  150996. +#ifdef __QNXNTO__
  150997. + IN gctPOINTER Physical,
  150998. + IN gctBOOL PhysicalAddresses,
  150999. +#endif
  151000. + IN gctSIZE_T Bytes
  151001. + );
  151002. +
  151003. +/* Add an END command in the command queue. */
  151004. +gceSTATUS
  151005. +gckHARDWARE_End(
  151006. + IN gckHARDWARE Hardware,
  151007. + IN gctPOINTER Logical,
  151008. + IN OUT gctSIZE_T * Bytes
  151009. + );
  151010. +
  151011. +/* Add a NOP command in the command queue. */
  151012. +gceSTATUS
  151013. +gckHARDWARE_Nop(
  151014. + IN gckHARDWARE Hardware,
  151015. + IN gctPOINTER Logical,
  151016. + IN OUT gctSIZE_T * Bytes
  151017. + );
  151018. +
  151019. +/* Add a WAIT command in the command queue. */
  151020. +gceSTATUS
  151021. +gckHARDWARE_Wait(
  151022. + IN gckHARDWARE Hardware,
  151023. + IN gctPOINTER Logical,
  151024. + IN gctUINT32 Count,
  151025. + IN OUT gctSIZE_T * Bytes
  151026. + );
  151027. +
  151028. +/* Add a PIPESELECT command in the command queue. */
  151029. +gceSTATUS
  151030. +gckHARDWARE_PipeSelect(
  151031. + IN gckHARDWARE Hardware,
  151032. + IN gctPOINTER Logical,
  151033. + IN gcePIPE_SELECT Pipe,
  151034. + IN OUT gctSIZE_T * Bytes
  151035. + );
  151036. +
  151037. +/* Add a LINK command in the command queue. */
  151038. +gceSTATUS
  151039. +gckHARDWARE_Link(
  151040. + IN gckHARDWARE Hardware,
  151041. + IN gctPOINTER Logical,
  151042. + IN gctPOINTER FetchAddress,
  151043. + IN gctSIZE_T FetchSize,
  151044. + IN OUT gctSIZE_T * Bytes
  151045. + );
  151046. +
  151047. +/* Add an EVENT command in the command queue. */
  151048. +gceSTATUS
  151049. +gckHARDWARE_Event(
  151050. + IN gckHARDWARE Hardware,
  151051. + IN gctPOINTER Logical,
  151052. + IN gctUINT8 Event,
  151053. + IN gceKERNEL_WHERE FromWhere,
  151054. + IN OUT gctSIZE_T * Bytes
  151055. + );
  151056. +
  151057. +/* Query the available memory. */
  151058. +gceSTATUS
  151059. +gckHARDWARE_QueryMemory(
  151060. + IN gckHARDWARE Hardware,
  151061. + OUT gctSIZE_T * InternalSize,
  151062. + OUT gctUINT32 * InternalBaseAddress,
  151063. + OUT gctUINT32 * InternalAlignment,
  151064. + OUT gctSIZE_T * ExternalSize,
  151065. + OUT gctUINT32 * ExternalBaseAddress,
  151066. + OUT gctUINT32 * ExternalAlignment,
  151067. + OUT gctUINT32 * HorizontalTileSize,
  151068. + OUT gctUINT32 * VerticalTileSize
  151069. + );
  151070. +
  151071. +/* Query the identity of the hardware. */
  151072. +gceSTATUS
  151073. +gckHARDWARE_QueryChipIdentity(
  151074. + IN gckHARDWARE Hardware,
  151075. + OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
  151076. + );
  151077. +
  151078. +/* Query the shader support. */
  151079. +gceSTATUS
  151080. +gckHARDWARE_QueryShaderCaps(
  151081. + IN gckHARDWARE Hardware,
  151082. + OUT gctUINT * VertexUniforms,
  151083. + OUT gctUINT * FragmentUniforms,
  151084. + OUT gctUINT * Varyings
  151085. + );
  151086. +
  151087. +/* Split a harwdare specific address into API stuff. */
  151088. +gceSTATUS
  151089. +gckHARDWARE_SplitMemory(
  151090. + IN gckHARDWARE Hardware,
  151091. + IN gctUINT32 Address,
  151092. + OUT gcePOOL * Pool,
  151093. + OUT gctUINT32 * Offset
  151094. + );
  151095. +
  151096. +/* Update command queue tail pointer. */
  151097. +gceSTATUS
  151098. +gckHARDWARE_UpdateQueueTail(
  151099. + IN gckHARDWARE Hardware,
  151100. + IN gctPOINTER Logical,
  151101. + IN gctUINT32 Offset
  151102. + );
  151103. +
  151104. +/* Convert logical address to hardware specific address. */
  151105. +gceSTATUS
  151106. +gckHARDWARE_ConvertLogical(
  151107. + IN gckHARDWARE Hardware,
  151108. + IN gctPOINTER Logical,
  151109. + OUT gctUINT32 * Address
  151110. + );
  151111. +
  151112. +#ifdef __QNXNTO__
  151113. +/* Convert physical address to hardware specific address. */
  151114. +gceSTATUS
  151115. +gckHARDWARE_ConvertPhysical(
  151116. + IN gckHARDWARE Hardware,
  151117. + IN gctPHYS_ADDR Physical,
  151118. + OUT gctUINT32 * Address
  151119. + );
  151120. +#endif
  151121. +
  151122. +/* Interrupt manager. */
  151123. +gceSTATUS
  151124. +gckHARDWARE_Interrupt(
  151125. + IN gckHARDWARE Hardware,
  151126. + IN gctBOOL InterruptValid
  151127. + );
  151128. +
  151129. +/* Program MMU. */
  151130. +gceSTATUS
  151131. +gckHARDWARE_SetMMU(
  151132. + IN gckHARDWARE Hardware,
  151133. + IN gctPOINTER Logical
  151134. + );
  151135. +
  151136. +/* Flush the MMU. */
  151137. +gceSTATUS
  151138. +gckHARDWARE_FlushMMU(
  151139. + IN gckHARDWARE Hardware
  151140. + );
  151141. +
  151142. +/* Set the page table base address. */
  151143. +gceSTATUS
  151144. +gckHARDWARE_SetMMUv2(
  151145. + IN gckHARDWARE Hardware,
  151146. + IN gctBOOL Enable,
  151147. + IN gctPOINTER MtlbAddress,
  151148. + IN gceMMU_MODE Mode,
  151149. + IN gctPOINTER SafeAddress,
  151150. + IN gctBOOL FromPower
  151151. + );
  151152. +
  151153. +/* Get idle register. */
  151154. +gceSTATUS
  151155. +gckHARDWARE_GetIdle(
  151156. + IN gckHARDWARE Hardware,
  151157. + IN gctBOOL Wait,
  151158. + OUT gctUINT32 * Data
  151159. + );
  151160. +
  151161. +/* Flush the caches. */
  151162. +gceSTATUS
  151163. +gckHARDWARE_Flush(
  151164. + IN gckHARDWARE Hardware,
  151165. + IN gceKERNEL_FLUSH Flush,
  151166. + IN gctPOINTER Logical,
  151167. + IN OUT gctSIZE_T * Bytes
  151168. + );
  151169. +
  151170. +/* Enable/disable fast clear. */
  151171. +gceSTATUS
  151172. +gckHARDWARE_SetFastClear(
  151173. + IN gckHARDWARE Hardware,
  151174. + IN gctINT Enable,
  151175. + IN gctINT Compression
  151176. + );
  151177. +
  151178. +gceSTATUS
  151179. +gckHARDWARE_ReadInterrupt(
  151180. + IN gckHARDWARE Hardware,
  151181. + OUT gctUINT32_PTR IDs
  151182. + );
  151183. +
  151184. +/* Power management. */
  151185. +gceSTATUS
  151186. +gckHARDWARE_SetPowerManagementState(
  151187. + IN gckHARDWARE Hardware,
  151188. + IN gceCHIPPOWERSTATE State
  151189. + );
  151190. +
  151191. +gceSTATUS
  151192. +gckHARDWARE_QueryPowerManagementState(
  151193. + IN gckHARDWARE Hardware,
  151194. + OUT gceCHIPPOWERSTATE* State
  151195. + );
  151196. +
  151197. +gceSTATUS
  151198. +gckHARDWARE_SetPowerManagement(
  151199. + IN gckHARDWARE Hardware,
  151200. + IN gctBOOL PowerManagement
  151201. + );
  151202. +
  151203. +gceSTATUS
  151204. +gckHARDWARE_SetGpuProfiler(
  151205. + IN gckHARDWARE Hardware,
  151206. + IN gctBOOL GpuProfiler
  151207. + );
  151208. +
  151209. +#if gcdENABLE_FSCALE_VAL_ADJUST
  151210. +gceSTATUS
  151211. +gckHARDWARE_SetFscaleValue(
  151212. + IN gckHARDWARE Hardware,
  151213. + IN gctUINT32 FscaleValue
  151214. + );
  151215. +
  151216. +gceSTATUS
  151217. +gckHARDWARE_GetFscaleValue(
  151218. + IN gckHARDWARE Hardware,
  151219. + IN gctUINT * FscaleValue,
  151220. + IN gctUINT * MinFscaleValue,
  151221. + IN gctUINT * MaxFscaleValue
  151222. + );
  151223. +#endif
  151224. +
  151225. +#if gcdPOWEROFF_TIMEOUT
  151226. +gceSTATUS
  151227. +gckHARDWARE_SetPowerOffTimeout(
  151228. + IN gckHARDWARE Hardware,
  151229. + IN gctUINT32 Timeout
  151230. +);
  151231. +
  151232. +gceSTATUS
  151233. +gckHARDWARE_QueryPowerOffTimeout(
  151234. + IN gckHARDWARE Hardware,
  151235. + OUT gctUINT32* Timeout
  151236. +);
  151237. +#endif
  151238. +
  151239. +/* Profile 2D Engine. */
  151240. +gceSTATUS
  151241. +gckHARDWARE_ProfileEngine2D(
  151242. + IN gckHARDWARE Hardware,
  151243. + OUT gcs2D_PROFILE_PTR Profile
  151244. + );
  151245. +
  151246. +gceSTATUS
  151247. +gckHARDWARE_InitializeHardware(
  151248. + IN gckHARDWARE Hardware
  151249. + );
  151250. +
  151251. +gceSTATUS
  151252. +gckHARDWARE_Reset(
  151253. + IN gckHARDWARE Hardware
  151254. + );
  151255. +
  151256. +typedef gceSTATUS (*gctISRMANAGERFUNC)(gctPOINTER Context, gceCORE Core);
  151257. +
  151258. +gceSTATUS
  151259. +gckHARDWARE_SetIsrManager(
  151260. + IN gckHARDWARE Hardware,
  151261. + IN gctISRMANAGERFUNC StartIsr,
  151262. + IN gctISRMANAGERFUNC StopIsr,
  151263. + IN gctPOINTER Context
  151264. + );
  151265. +
  151266. +/* Start a composition. */
  151267. +gceSTATUS
  151268. +gckHARDWARE_Compose(
  151269. + IN gckHARDWARE Hardware,
  151270. + IN gctUINT32 ProcessID,
  151271. + IN gctPHYS_ADDR Physical,
  151272. + IN gctPOINTER Logical,
  151273. + IN gctSIZE_T Offset,
  151274. + IN gctSIZE_T Size,
  151275. + IN gctUINT8 EventID
  151276. + );
  151277. +
  151278. +/* Check for Hardware features. */
  151279. +gceSTATUS
  151280. +gckHARDWARE_IsFeatureAvailable(
  151281. + IN gckHARDWARE Hardware,
  151282. + IN gceFEATURE Feature
  151283. + );
  151284. +
  151285. +gceSTATUS
  151286. +gckHARDWARE_DumpMMUException(
  151287. + IN gckHARDWARE Hardware
  151288. + );
  151289. +
  151290. +gceSTATUS
  151291. +gckHARDWARE_DumpGPUState(
  151292. + IN gckHARDWARE Hardware
  151293. + );
  151294. +
  151295. +gceSTATUS
  151296. +gckHARDWARE_InitDVFS(
  151297. + IN gckHARDWARE Hardware
  151298. + );
  151299. +
  151300. +gceSTATUS
  151301. +gckHARDWARE_QueryLoad(
  151302. + IN gckHARDWARE Hardware,
  151303. + OUT gctUINT32 * Load
  151304. + );
  151305. +
  151306. +gceSTATUS
  151307. +gckHARDWARE_SetDVFSPeroid(
  151308. + IN gckHARDWARE Hardware,
  151309. + IN gctUINT32 Frequency
  151310. + );
  151311. +
  151312. +#if !gcdENABLE_VG
  151313. +/******************************************************************************\
  151314. +***************************** gckINTERRUPT Object ******************************
  151315. +\******************************************************************************/
  151316. +
  151317. +typedef struct _gckINTERRUPT * gckINTERRUPT;
  151318. +
  151319. +typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
  151320. + IN gckKERNEL Kernel
  151321. + );
  151322. +
  151323. +gceSTATUS
  151324. +gckINTERRUPT_Construct(
  151325. + IN gckKERNEL Kernel,
  151326. + OUT gckINTERRUPT * Interrupt
  151327. + );
  151328. +
  151329. +gceSTATUS
  151330. +gckINTERRUPT_Destroy(
  151331. + IN gckINTERRUPT Interrupt
  151332. + );
  151333. +
  151334. +gceSTATUS
  151335. +gckINTERRUPT_SetHandler(
  151336. + IN gckINTERRUPT Interrupt,
  151337. + IN OUT gctINT32_PTR Id,
  151338. + IN gctINTERRUPT_HANDLER Handler
  151339. + );
  151340. +
  151341. +gceSTATUS
  151342. +gckINTERRUPT_Notify(
  151343. + IN gckINTERRUPT Interrupt,
  151344. + IN gctBOOL Valid
  151345. + );
  151346. +#endif
  151347. +/******************************************************************************\
  151348. +******************************** gckEVENT Object *******************************
  151349. +\******************************************************************************/
  151350. +
  151351. +typedef struct _gckEVENT * gckEVENT;
  151352. +
  151353. +/* Construct a new gckEVENT object. */
  151354. +gceSTATUS
  151355. +gckEVENT_Construct(
  151356. + IN gckKERNEL Kernel,
  151357. + OUT gckEVENT * Event
  151358. + );
  151359. +
  151360. +/* Destroy an gckEVENT object. */
  151361. +gceSTATUS
  151362. +gckEVENT_Destroy(
  151363. + IN gckEVENT Event
  151364. + );
  151365. +
  151366. +/* Add a new event to the list of events. */
  151367. +gceSTATUS
  151368. +gckEVENT_AddList(
  151369. + IN gckEVENT Event,
  151370. + IN gcsHAL_INTERFACE_PTR Interface,
  151371. + IN gceKERNEL_WHERE FromWhere,
  151372. + IN gctBOOL AllocateAllowed,
  151373. + IN gctBOOL FromKernel
  151374. + );
  151375. +
  151376. +/* Schedule a FreeNonPagedMemory event. */
  151377. +gceSTATUS
  151378. +gckEVENT_FreeNonPagedMemory(
  151379. + IN gckEVENT Event,
  151380. + IN gctSIZE_T Bytes,
  151381. + IN gctPHYS_ADDR Physical,
  151382. + IN gctPOINTER Logical,
  151383. + IN gceKERNEL_WHERE FromWhere
  151384. + );
  151385. +
  151386. +/* Schedule a FreeContiguousMemory event. */
  151387. +gceSTATUS
  151388. +gckEVENT_FreeContiguousMemory(
  151389. + IN gckEVENT Event,
  151390. + IN gctSIZE_T Bytes,
  151391. + IN gctPHYS_ADDR Physical,
  151392. + IN gctPOINTER Logical,
  151393. + IN gceKERNEL_WHERE FromWhere
  151394. + );
  151395. +
  151396. +/* Schedule a FreeVideoMemory event. */
  151397. +gceSTATUS
  151398. +gckEVENT_FreeVideoMemory(
  151399. + IN gckEVENT Event,
  151400. + IN gcuVIDMEM_NODE_PTR VideoMemory,
  151401. + IN gceKERNEL_WHERE FromWhere
  151402. + );
  151403. +
  151404. +/* Schedule a signal event. */
  151405. +gceSTATUS
  151406. +gckEVENT_Signal(
  151407. + IN gckEVENT Event,
  151408. + IN gctSIGNAL Signal,
  151409. + IN gceKERNEL_WHERE FromWhere
  151410. + );
  151411. +
  151412. +/* Schedule an Unlock event. */
  151413. +gceSTATUS
  151414. +gckEVENT_Unlock(
  151415. + IN gckEVENT Event,
  151416. + IN gceKERNEL_WHERE FromWhere,
  151417. + IN gcuVIDMEM_NODE_PTR Node,
  151418. + IN gceSURF_TYPE Type
  151419. + );
  151420. +
  151421. +gceSTATUS
  151422. +gckEVENT_CommitDone(
  151423. + IN gckEVENT Event,
  151424. + IN gceKERNEL_WHERE FromWhere
  151425. + );
  151426. +
  151427. +#if gcdVIRTUAL_COMMAND_BUFFER
  151428. +/* Schedule a FreeVirtualCommandBuffer event. */
  151429. +gceSTATUS
  151430. +gckEVENT_DestroyVirtualCommandBuffer(
  151431. + IN gckEVENT Event,
  151432. + IN gctSIZE_T Bytes,
  151433. + IN gctPHYS_ADDR Physical,
  151434. + IN gctPOINTER Logical,
  151435. + IN gceKERNEL_WHERE FromWhere
  151436. + );
  151437. +#endif
  151438. +
  151439. +gceSTATUS
  151440. +gckEVENT_Submit(
  151441. + IN gckEVENT Event,
  151442. + IN gctBOOL Wait,
  151443. + IN gctBOOL FromPower
  151444. + );
  151445. +
  151446. +/* Commit an event queue. */
  151447. +gceSTATUS
  151448. +gckEVENT_Commit(
  151449. + IN gckEVENT Event,
  151450. + IN gcsQUEUE_PTR Queue
  151451. + );
  151452. +
  151453. +/* Schedule a composition event. */
  151454. +gceSTATUS
  151455. +gckEVENT_Compose(
  151456. + IN gckEVENT Event,
  151457. + IN gcsHAL_COMPOSE_PTR Info
  151458. + );
  151459. +
  151460. +/* Event callback routine. */
  151461. +gceSTATUS
  151462. +gckEVENT_Notify(
  151463. + IN gckEVENT Event,
  151464. + IN gctUINT32 IDs
  151465. + );
  151466. +
  151467. +/* Event callback routine. */
  151468. +gceSTATUS
  151469. +gckEVENT_Interrupt(
  151470. + IN gckEVENT Event,
  151471. + IN gctUINT32 IDs
  151472. + );
  151473. +
  151474. +gceSTATUS
  151475. +gckEVENT_Dump(
  151476. + IN gckEVENT Event
  151477. + );
  151478. +/******************************************************************************\
  151479. +******************************* gckCOMMAND Object ******************************
  151480. +\******************************************************************************/
  151481. +
  151482. +typedef struct _gckCOMMAND * gckCOMMAND;
  151483. +
  151484. +/* Construct a new gckCOMMAND object. */
  151485. +gceSTATUS
  151486. +gckCOMMAND_Construct(
  151487. + IN gckKERNEL Kernel,
  151488. + OUT gckCOMMAND * Command
  151489. + );
  151490. +
  151491. +/* Destroy an gckCOMMAND object. */
  151492. +gceSTATUS
  151493. +gckCOMMAND_Destroy(
  151494. + IN gckCOMMAND Command
  151495. + );
  151496. +
  151497. +/* Acquire command queue synchronization objects. */
  151498. +gceSTATUS
  151499. +gckCOMMAND_EnterCommit(
  151500. + IN gckCOMMAND Command,
  151501. + IN gctBOOL FromPower
  151502. + );
  151503. +
  151504. +/* Release command queue synchronization objects. */
  151505. +gceSTATUS
  151506. +gckCOMMAND_ExitCommit(
  151507. + IN gckCOMMAND Command,
  151508. + IN gctBOOL FromPower
  151509. + );
  151510. +
  151511. +/* Start the command queue. */
  151512. +gceSTATUS
  151513. +gckCOMMAND_Start(
  151514. + IN gckCOMMAND Command
  151515. + );
  151516. +
  151517. +/* Stop the command queue. */
  151518. +gceSTATUS
  151519. +gckCOMMAND_Stop(
  151520. + IN gckCOMMAND Command,
  151521. + IN gctBOOL FromRecovery
  151522. + );
  151523. +
  151524. +/* Commit a buffer to the command queue. */
  151525. +gceSTATUS
  151526. +gckCOMMAND_Commit(
  151527. + IN gckCOMMAND Command,
  151528. + IN gckCONTEXT Context,
  151529. + IN gcoCMDBUF CommandBuffer,
  151530. + IN gcsSTATE_DELTA_PTR StateDelta,
  151531. + IN gcsQUEUE_PTR EventQueue,
  151532. + IN gctUINT32 ProcessID
  151533. + );
  151534. +
  151535. +/* Reserve space in the command buffer. */
  151536. +gceSTATUS
  151537. +gckCOMMAND_Reserve(
  151538. + IN gckCOMMAND Command,
  151539. + IN gctSIZE_T RequestedBytes,
  151540. + OUT gctPOINTER * Buffer,
  151541. + OUT gctSIZE_T * BufferSize
  151542. + );
  151543. +
  151544. +/* Execute reserved space in the command buffer. */
  151545. +gceSTATUS
  151546. +gckCOMMAND_Execute(
  151547. + IN gckCOMMAND Command,
  151548. + IN gctSIZE_T RequstedBytes
  151549. + );
  151550. +
  151551. +/* Stall the command queue. */
  151552. +gceSTATUS
  151553. +gckCOMMAND_Stall(
  151554. + IN gckCOMMAND Command,
  151555. + IN gctBOOL FromPower
  151556. + );
  151557. +
  151558. +/* Attach user process. */
  151559. +gceSTATUS
  151560. +gckCOMMAND_Attach(
  151561. + IN gckCOMMAND Command,
  151562. + OUT gckCONTEXT * Context,
  151563. + OUT gctSIZE_T * StateCount,
  151564. + IN gctUINT32 ProcessID
  151565. + );
  151566. +
  151567. +/* Detach user process. */
  151568. +gceSTATUS
  151569. +gckCOMMAND_Detach(
  151570. + IN gckCOMMAND Command,
  151571. + IN gckCONTEXT Context
  151572. + );
  151573. +
  151574. +#if gcdVIRTUAL_COMMAND_BUFFER
  151575. +gceSTATUS
  151576. +gckCOMMAND_DumpExecutingBuffer(
  151577. + IN gckCOMMAND Command
  151578. + );
  151579. +#endif
  151580. +
  151581. +/******************************************************************************\
  151582. +********************************* gckMMU Object ********************************
  151583. +\******************************************************************************/
  151584. +
  151585. +typedef struct _gckMMU * gckMMU;
  151586. +
  151587. +/* Construct a new gckMMU object. */
  151588. +gceSTATUS
  151589. +gckMMU_Construct(
  151590. + IN gckKERNEL Kernel,
  151591. + IN gctSIZE_T MmuSize,
  151592. + OUT gckMMU * Mmu
  151593. + );
  151594. +
  151595. +/* Destroy an gckMMU object. */
  151596. +gceSTATUS
  151597. +gckMMU_Destroy(
  151598. + IN gckMMU Mmu
  151599. + );
  151600. +
  151601. +/* Enable the MMU. */
  151602. +gceSTATUS
  151603. +gckMMU_Enable(
  151604. + IN gckMMU Mmu,
  151605. + IN gctUINT32 PhysBaseAddr,
  151606. + IN gctUINT32 PhysSize
  151607. + );
  151608. +
  151609. +/* Allocate pages inside the MMU. */
  151610. +gceSTATUS
  151611. +gckMMU_AllocatePages(
  151612. + IN gckMMU Mmu,
  151613. + IN gctSIZE_T PageCount,
  151614. + OUT gctPOINTER * PageTable,
  151615. + OUT gctUINT32 * Address
  151616. + );
  151617. +
  151618. +gceSTATUS
  151619. +gckMMU_AllocatePagesEx(
  151620. + IN gckMMU Mmu,
  151621. + IN gctSIZE_T PageCount,
  151622. + IN gceSURF_TYPE Type,
  151623. + OUT gctPOINTER * PageTable,
  151624. + OUT gctUINT32 * Address
  151625. + );
  151626. +
  151627. +/* Remove a page table from the MMU. */
  151628. +gceSTATUS
  151629. +gckMMU_FreePages(
  151630. + IN gckMMU Mmu,
  151631. + IN gctPOINTER PageTable,
  151632. + IN gctSIZE_T PageCount
  151633. + );
  151634. +
  151635. +/* Set the MMU page with info. */
  151636. +gceSTATUS
  151637. +gckMMU_SetPage(
  151638. + IN gckMMU Mmu,
  151639. + IN gctUINT32 PageAddress,
  151640. + IN gctUINT32 *PageEntry
  151641. + );
  151642. +
  151643. +#ifdef __QNXNTO__
  151644. +gceSTATUS
  151645. +gckMMU_InsertNode(
  151646. + IN gckMMU Mmu,
  151647. + IN gcuVIDMEM_NODE_PTR Node);
  151648. +
  151649. +gceSTATUS
  151650. +gckMMU_RemoveNode(
  151651. + IN gckMMU Mmu,
  151652. + IN gcuVIDMEM_NODE_PTR Node);
  151653. +#endif
  151654. +
  151655. +#ifdef __QNXNTO__
  151656. +gceSTATUS
  151657. +gckMMU_FreeHandleMemory(
  151658. + IN gckKERNEL Kernel,
  151659. + IN gckMMU Mmu,
  151660. + IN gctUINT32 Pid
  151661. + );
  151662. +#endif
  151663. +
  151664. +gceSTATUS
  151665. +gckMMU_Flush(
  151666. + IN gckMMU Mmu
  151667. + );
  151668. +
  151669. +gceSTATUS
  151670. +gckMMU_DumpPageTableEntry(
  151671. + IN gckMMU Mmu,
  151672. + IN gctUINT32 Address
  151673. + );
  151674. +
  151675. +
  151676. +#if VIVANTE_PROFILER
  151677. +gceSTATUS
  151678. +gckHARDWARE_QueryProfileRegisters(
  151679. + IN gckHARDWARE Hardware,
  151680. + IN gctBOOL Clear,
  151681. + OUT gcsPROFILER_COUNTERS * Counters
  151682. + );
  151683. +#endif
  151684. +
  151685. +#if VIVANTE_PROFILER_CONTEXT
  151686. +gceSTATUS
  151687. +gckHARDWARE_QueryContextProfile(
  151688. + IN gckHARDWARE Hardware,
  151689. + IN gctBOOL Clear,
  151690. + IN gckCONTEXT Context,
  151691. + OUT gcsPROFILER_COUNTERS * Counters
  151692. + );
  151693. +
  151694. +gceSTATUS
  151695. +gckHARDWARE_UpdateContextProfile(
  151696. + IN gckHARDWARE Hardware,
  151697. + IN gckCONTEXT Context
  151698. + );
  151699. +#endif
  151700. +
  151701. +gceSTATUS
  151702. +gckOS_SignalQueryHardware(
  151703. + IN gckOS Os,
  151704. + IN gctSIGNAL Signal,
  151705. + OUT gckHARDWARE * Hardware
  151706. + );
  151707. +
  151708. +gceSTATUS
  151709. +gckOS_SignalSetHardware(
  151710. + IN gckOS Os,
  151711. + IN gctSIGNAL Signal,
  151712. + gckHARDWARE Hardware
  151713. + );
  151714. +
  151715. +#ifdef __cplusplus
  151716. +}
  151717. +#endif
  151718. +
  151719. +#if gcdENABLE_VG
  151720. +#include "gc_hal_vg.h"
  151721. +#endif
  151722. +
  151723. +#endif /* __gc_hal_h_ */
  151724. diff -Nur linux-3.14.17/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
  151725. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h 1970-01-01 01:00:00.000000000 +0100
  151726. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h 2014-09-11 18:06:03.122042450 +0200
  151727. @@ -0,0 +1,185 @@
  151728. +/****************************************************************************
  151729. +*
  151730. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  151731. +*
  151732. +* This program is free software; you can redistribute it and/or modify
  151733. +* it under the terms of the GNU General Public License as published by
  151734. +* the Free Software Foundation; either version 2 of the license, or
  151735. +* (at your option) any later version.
  151736. +*
  151737. +* This program is distributed in the hope that it will be useful,
  151738. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  151739. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  151740. +* GNU General Public License for more details.
  151741. +*
  151742. +* You should have received a copy of the GNU General Public License
  151743. +* along with this program; if not write to the Free Software
  151744. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  151745. +*
  151746. +*****************************************************************************/
  151747. +
  151748. +
  151749. +#ifndef __gc_hal_kernel_buffer_h_
  151750. +#define __gc_hal_kernel_buffer_h_
  151751. +
  151752. +
  151753. +#ifdef __cplusplus
  151754. +extern "C" {
  151755. +#endif
  151756. +
  151757. +/******************************************************************************\
  151758. +************************ Command Buffer and Event Objects **********************
  151759. +\******************************************************************************/
  151760. +
  151761. +/* The number of context buffers per user. */
  151762. +#define gcdCONTEXT_BUFFER_COUNT 2
  151763. +
  151764. +/* State delta record. */
  151765. +typedef struct _gcsSTATE_DELTA_RECORD * gcsSTATE_DELTA_RECORD_PTR;
  151766. +typedef struct _gcsSTATE_DELTA_RECORD
  151767. +{
  151768. + /* State address. */
  151769. + gctUINT address;
  151770. +
  151771. + /* State mask. */
  151772. + gctUINT32 mask;
  151773. +
  151774. + /* State data. */
  151775. + gctUINT32 data;
  151776. +}
  151777. +gcsSTATE_DELTA_RECORD;
  151778. +
  151779. +/* State delta. */
  151780. +typedef struct _gcsSTATE_DELTA
  151781. +{
  151782. + /* For debugging: the number of delta in the order of creation. */
  151783. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  151784. + gctUINT num;
  151785. +#endif
  151786. +
  151787. + /* Main state delta ID. Every time state delta structure gets reinitialized,
  151788. + main ID is incremented. If main state ID overflows, all map entry IDs get
  151789. + reinitialized to make sure there is no potential erroneous match after
  151790. + the overflow.*/
  151791. + gctUINT id;
  151792. +
  151793. + /* The number of contexts pending modification by the delta. */
  151794. + gctINT refCount;
  151795. +
  151796. + /* Vertex element count for the delta buffer. */
  151797. + gctUINT elementCount;
  151798. +
  151799. + /* Number of states currently stored in the record array. */
  151800. + gctUINT recordCount;
  151801. +
  151802. + /* Record array; holds all modified states in gcsSTATE_DELTA_RECORD. */
  151803. + gctUINT64 recordArray;
  151804. +
  151805. + /* Map entry ID is used for map entry validation. If map entry ID does not
  151806. + match the main state delta ID, the entry and the corresponding state are
  151807. + considered not in use. */
  151808. + gctUINT64 mapEntryID;
  151809. + gctUINT mapEntryIDSize;
  151810. +
  151811. + /* If the map entry ID matches the main state delta ID, index points to
  151812. + the state record in the record array. */
  151813. + gctUINT64 mapEntryIndex;
  151814. +
  151815. + /* Previous and next state deltas in gcsSTATE_DELTA. */
  151816. + gctUINT64 prev;
  151817. + gctUINT64 next;
  151818. +}
  151819. +gcsSTATE_DELTA;
  151820. +
  151821. +/* Command buffer object. */
  151822. +struct _gcoCMDBUF
  151823. +{
  151824. + /* The object. */
  151825. + gcsOBJECT object;
  151826. +
  151827. + /* Command buffer entry and exit pipes. */
  151828. + gcePIPE_SELECT entryPipe;
  151829. + gcePIPE_SELECT exitPipe;
  151830. +
  151831. + /* Feature usage flags. */
  151832. + gctBOOL using2D;
  151833. + gctBOOL using3D;
  151834. + gctBOOL usingFilterBlit;
  151835. + gctBOOL usingPalette;
  151836. +
  151837. + /* Physical address of command buffer. Just a name. */
  151838. + gctUINT32 physical;
  151839. +
  151840. + /* Logical address of command buffer. */
  151841. + gctUINT64 logical;
  151842. +
  151843. + /* Number of bytes in command buffer. */
  151844. + gctUINT bytes;
  151845. +
  151846. + /* Start offset into the command buffer. */
  151847. + gctUINT startOffset;
  151848. +
  151849. + /* Current offset into the command buffer. */
  151850. + gctUINT offset;
  151851. +
  151852. + /* Number of free bytes in command buffer. */
  151853. + gctUINT free;
  151854. +
  151855. + /* Location of the last reserved area. */
  151856. + gctUINT64 lastReserve;
  151857. + gctUINT lastOffset;
  151858. +
  151859. +#if gcdSECURE_USER
  151860. + /* Hint array for the current command buffer. */
  151861. + gctUINT hintArraySize;
  151862. + gctUINT64 hintArray;
  151863. + gctUINT64 hintArrayTail;
  151864. +#endif
  151865. +
  151866. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  151867. + /* Last load state command location and hardware address. */
  151868. + gctUINT64 lastLoadStatePtr;
  151869. + gctUINT32 lastLoadStateAddress;
  151870. + gctUINT32 lastLoadStateCount;
  151871. +#endif
  151872. +};
  151873. +
  151874. +typedef struct _gcsQUEUE
  151875. +{
  151876. + /* Pointer to next gcsQUEUE structure in gcsQUEUE. */
  151877. + gctUINT64 next;
  151878. +
  151879. + /* Event information. */
  151880. + gcsHAL_INTERFACE iface;
  151881. +}
  151882. +gcsQUEUE;
  151883. +
  151884. +/* Event queue. */
  151885. +struct _gcoQUEUE
  151886. +{
  151887. + /* The object. */
  151888. + gcsOBJECT object;
  151889. +
  151890. + /* Pointer to current event queue. */
  151891. + gcsQUEUE_PTR head;
  151892. + gcsQUEUE_PTR tail;
  151893. +
  151894. +#ifdef __QNXNTO__
  151895. + /* Buffer for records. */
  151896. + gcsQUEUE_PTR records;
  151897. + gctUINT32 freeBytes;
  151898. + gctUINT32 offset;
  151899. +#else
  151900. + /* List of free records. */
  151901. + gcsQUEUE_PTR freeList;
  151902. +#endif
  151903. + #define gcdIN_QUEUE_RECORD_LIMIT 16
  151904. + /* Number of records currently in queue */
  151905. + gctUINT32 recordCount;
  151906. +};
  151907. +
  151908. +#ifdef __cplusplus
  151909. +}
  151910. +#endif
  151911. +
  151912. +#endif /* __gc_hal_kernel_buffer_h_ */
  151913. diff -Nur linux-3.14.17/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
  151914. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h 1970-01-01 01:00:00.000000000 +0100
  151915. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h 2014-09-11 18:06:03.122042450 +0200
  151916. @@ -0,0 +1,530 @@
  151917. +/****************************************************************************
  151918. +*
  151919. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  151920. +*
  151921. +* This program is free software; you can redistribute it and/or modify
  151922. +* it under the terms of the GNU General Public License as published by
  151923. +* the Free Software Foundation; either version 2 of the license, or
  151924. +* (at your option) any later version.
  151925. +*
  151926. +* This program is distributed in the hope that it will be useful,
  151927. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  151928. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  151929. +* GNU General Public License for more details.
  151930. +*
  151931. +* You should have received a copy of the GNU General Public License
  151932. +* along with this program; if not write to the Free Software
  151933. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  151934. +*
  151935. +*****************************************************************************/
  151936. +
  151937. +
  151938. +/*
  151939. +** Include file for the local memory management.
  151940. +*/
  151941. +
  151942. +#ifndef __gc_hal_mem_h_
  151943. +#define __gc_hal_mem_h_
  151944. +#ifndef VIVANTE_NO_3D
  151945. +
  151946. +#ifdef __cplusplus
  151947. +extern "C" {
  151948. +#endif
  151949. +
  151950. +/*******************************************************************************
  151951. +** Usage:
  151952. +
  151953. + The macros to declare MemPool type and functions are
  151954. + gcmMEM_DeclareFSMemPool (Type, TypeName, Prefix)
  151955. + gcmMEM_DeclareVSMemPool (Type, TypeName, Prefix)
  151956. + gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix)
  151957. +
  151958. + The data structures for MemPool are
  151959. + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
  151960. + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
  151961. + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
  151962. +
  151963. + The MemPool constructor and destructor functions are
  151964. + gcfMEM_InitFSMemPool(gcsMEM_FS_MEM_POOL *, gcoOS, gctUINT, gctUINT);
  151965. + gcfMEM_FreeFSMemPool(gcsMEM_FS_MEM_POOL *);
  151966. + gcfMEM_InitVSMemPool(gcsMEM_VS_MEM_POOL *, gcoOS, gctUINT, gctBOOL);
  151967. + gcfMEM_FreeVSMemPool(gcsMEM_VS_MEM_POOL *);
  151968. + gcfMEM_InitAFSMemPool(gcsMEM_AFS_MEM_POOL *, gcoOS, gctUINT);
  151969. + gcfMEM_FreeAFSMemPool(gcsMEM_AFS_MEM_POOL *);
  151970. +
  151971. + FS: for Fixed-Size data structures
  151972. + VS: for Variable-size data structures
  151973. + AFS: for Array of Fixed-Size data structures
  151974. +
  151975. +
  151976. + // Example 1: For a fixed-size data structure, struct gcsNode.
  151977. + // It is used locally in a file, so the functions are static without prefix.
  151978. + // At top level, declear allocate and free functions.
  151979. + // The first argument is the data type.
  151980. + // The second armument is the short name used in the fuctions.
  151981. + gcmMEM_DeclareFSMemPool(struct gcsNode, Node, );
  151982. +
  151983. + // The previous macro creates two inline functions,
  151984. + // _AllocateNode and _FreeNode.
  151985. +
  151986. + // In function or struct
  151987. + gcsMEM_FS_MEM_POOL nodeMemPool;
  151988. +
  151989. + // In function,
  151990. + struct gcsNode * node;
  151991. + gceSTATUS status;
  151992. +
  151993. + // Before using the memory pool, initialize it.
  151994. + // The second argument is the gcoOS object.
  151995. + // The third argument is the number of data structures to allocate for each chunk.
  151996. + status = gcfMEM_InitFSMemPool(&nodeMemPool, os, 100, sizeof(struct gcsNode));
  151997. + ...
  151998. +
  151999. + // Allocate a node.
  152000. + status = _AllocateNode(nodeMemPool, &node);
  152001. + ...
  152002. + // Free a node.
  152003. + _FreeNode(nodeMemPool, node);
  152004. +
  152005. + // After using the memory pool, free it.
  152006. + gcfMEM_FreeFSMemPool(&nodeMemPool);
  152007. +
  152008. +
  152009. + // Example 2: For array of fixed-size data structures, struct gcsNode.
  152010. + // It is used in several files, so the functions are extern with prefix.
  152011. + // At top level, declear allocate and free functions.
  152012. + // The first argument is the data type, and the second one is the short name
  152013. + // used in the fuctions.
  152014. + gcmMEM_DeclareAFSMemPool(struct gcsNode, NodeArray, gcfOpt);
  152015. +
  152016. + // The previous macro creates two inline functions,
  152017. + // gcfOpt_AllocateNodeArray and gcfOpt_FreeNodeArray.
  152018. +
  152019. + // In function or struct
  152020. + gcsMEM_AFS_MEM_POOL nodeArrayMemPool;
  152021. +
  152022. + // In function,
  152023. + struct gcsNode * nodeArray;
  152024. + gceSTATUS status;
  152025. +
  152026. + // Before using the array memory pool, initialize it.
  152027. + // The second argument is the gcoOS object, the third is the number of data
  152028. + // structures to allocate for each chunk.
  152029. + status = gcfMEM_InitAFSMemPool(&nodeArrayMemPool, os, sizeof(struct gcsNode));
  152030. + ...
  152031. +
  152032. + // Allocate a node array of size 100.
  152033. + status = gcfOpt_AllocateNodeArray(nodeArrayMemPool, &nodeArray, 100);
  152034. + ...
  152035. + // Free a node array.
  152036. + gcfOpt_FreeNodeArray(&nodeArrayMemPool, nodeArray);
  152037. +
  152038. + // After using the array memory pool, free it.
  152039. + gcfMEM_FreeAFSMemPool(&nodeArrayMemPool);
  152040. +
  152041. +*******************************************************************************/
  152042. +
  152043. +/*******************************************************************************
  152044. +** To switch back to use gcoOS_Allocate and gcoOS_Free, add
  152045. +** #define USE_LOCAL_MEMORY_POOL 0
  152046. +** before including this file.
  152047. +*******************************************************************************/
  152048. +#ifndef USE_LOCAL_MEMORY_POOL
  152049. +/*
  152050. + USE_LOCAL_MEMORY_POOL
  152051. +
  152052. + This define enables the local memory management to improve performance.
  152053. +*/
  152054. +#define USE_LOCAL_MEMORY_POOL 1
  152055. +#endif
  152056. +
  152057. +/*******************************************************************************
  152058. +** Memory Pool Data Structures
  152059. +*******************************************************************************/
  152060. +#if USE_LOCAL_MEMORY_POOL
  152061. + typedef struct _gcsMEM_FS_MEM_POOL * gcsMEM_FS_MEM_POOL;
  152062. + typedef struct _gcsMEM_VS_MEM_POOL * gcsMEM_VS_MEM_POOL;
  152063. + typedef struct _gcsMEM_AFS_MEM_POOL * gcsMEM_AFS_MEM_POOL;
  152064. +#else
  152065. + typedef gcoOS gcsMEM_FS_MEM_POOL;
  152066. + typedef gcoOS gcsMEM_VS_MEM_POOL;
  152067. + typedef gcoOS gcsMEM_AFS_MEM_POOL;
  152068. +#endif
  152069. +
  152070. +/*******************************************************************************
  152071. +** Memory Pool Macros
  152072. +*******************************************************************************/
  152073. +#if USE_LOCAL_MEMORY_POOL
  152074. +#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
  152075. +gceSTATUS \
  152076. +Prefix##_Allocate##TypeName( \
  152077. + gcsMEM_FS_MEM_POOL MemPool, \
  152078. + Type ** Pointer \
  152079. + ) \
  152080. +{ \
  152081. + return(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
  152082. +} \
  152083. + \
  152084. +gceSTATUS \
  152085. +Prefix##_CAllocate##TypeName( \
  152086. + gcsMEM_FS_MEM_POOL MemPool, \
  152087. + Type ** Pointer \
  152088. + ) \
  152089. +{ \
  152090. + gceSTATUS status; \
  152091. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152092. + gcmERR_RETURN(gcfMEM_FSMemPoolGetANode(MemPool, (gctPOINTER *) Pointer)); \
  152093. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
  152094. + gcmFOOTER(); \
  152095. + return gcvSTATUS_OK; \
  152096. +} \
  152097. + \
  152098. +gceSTATUS \
  152099. +Prefix##_Free##TypeName( \
  152100. + gcsMEM_FS_MEM_POOL MemPool, \
  152101. + Type * Pointer \
  152102. + ) \
  152103. +{ \
  152104. + gceSTATUS status; \
  152105. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152106. + status = gcfMEM_FSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  152107. + gcmFOOTER(); \
  152108. + return status; \
  152109. +} \
  152110. + \
  152111. +gceSTATUS \
  152112. +Prefix##_Free##TypeName##List( \
  152113. + gcsMEM_FS_MEM_POOL MemPool, \
  152114. + Type * FirstPointer, \
  152115. + Type * LastPointer \
  152116. + ) \
  152117. +{ \
  152118. + gceSTATUS status; \
  152119. + gcmHEADER_ARG("MemPool=0x%x FirstPointer=0x%x LastPointer=0x%x", MemPool, FirstPointer, LastPointer); \
  152120. + status = gcfMEM_FSMemPoolFreeAList(MemPool, (gctPOINTER) FirstPointer, (gctPOINTER) LastPointer); \
  152121. + gcmFOOTER(); \
  152122. + return status; \
  152123. +}
  152124. +
  152125. +#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
  152126. +gceSTATUS \
  152127. +Prefix##_Allocate##TypeName( \
  152128. + gcsMEM_FS_MEM_POOL MemPool, \
  152129. + Type ** Pointer, \
  152130. + gctUINT Size \
  152131. + ) \
  152132. +{ \
  152133. + gceSTATUS status;\
  152134. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  152135. + status = gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer); \
  152136. + gcmFOOTER(); \
  152137. + return status; \
  152138. +} \
  152139. + \
  152140. +gceSTATUS \
  152141. + Prefix##_CAllocate##TypeName( \
  152142. + gcsMEM_FS_MEM_POOL MemPool, \
  152143. + Type ** Pointer, \
  152144. + gctUINT Size \
  152145. + ) \
  152146. +{ \
  152147. + gceSTATUS status; \
  152148. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  152149. + gcmERR_RETURN(gcfMEM_VSMemPoolGetANode(MemPool, Size, (gctPOINTER *) Pointer)); \
  152150. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, size); \
  152151. + gcmFOOTER(); \
  152152. + return gcvSTATUS_OK; \
  152153. +} \
  152154. + \
  152155. +gceSTATUS \
  152156. +Prefix##_Free##TypeName( \
  152157. + gcsMEM_FS_MEM_POOL MemPool, \
  152158. + Type * Pointer \
  152159. + ) \
  152160. +{ \
  152161. + gceSTATUS status; \
  152162. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pinter); \
  152163. + status = gcfMEM_VSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  152164. + gcmFOOTER(); \
  152165. + return status; \
  152166. +}
  152167. +
  152168. +#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
  152169. +gceSTATUS \
  152170. +Prefix##_Allocate##TypeName( \
  152171. + gcsMEM_AFS_MEM_POOL MemPool, \
  152172. + Type ** Pointer, \
  152173. + gctUINT Count \
  152174. + ) \
  152175. +{ \
  152176. + gceSTATUS status; \
  152177. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  152178. + status = gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer); \
  152179. + gcmFOOTER(); \
  152180. + return status; \
  152181. +} \
  152182. + \
  152183. +gceSTATUS \
  152184. +Prefix##_CAllocate##TypeName( \
  152185. + gcsMEM_AFS_MEM_POOL MemPool, \
  152186. + Type ** Pointer, \
  152187. + gctUINT Count \
  152188. + ) \
  152189. +{ \
  152190. + gceSTATUS status; \
  152191. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  152192. + gcmERR_RETURN(gcfMEM_AFSMemPoolGetANode(MemPool, Count, (gctPOINTER *) Pointer)); \
  152193. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
  152194. + gcmFOOTER(); \
  152195. + return gcvSTATUS_OK; \
  152196. +} \
  152197. + \
  152198. +gceSTATUS \
  152199. +Prefix##_Free##TypeName( \
  152200. + gcsMEM_AFS_MEM_POOL MemPool, \
  152201. + Type * Pointer \
  152202. + ) \
  152203. +{ \
  152204. + gceSTATUS status; \
  152205. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152206. + status = gcfMEM_AFSMemPoolFreeANode(MemPool, (gctPOINTER) Pointer); \
  152207. + gcmFOOTER(); \
  152208. + return status; \
  152209. +}
  152210. +
  152211. +#else
  152212. +
  152213. +#define gcmMEM_DeclareFSMemPool(Type, TypeName, Prefix) \
  152214. +gceSTATUS \
  152215. +Prefix##_Allocate##TypeName( \
  152216. + gcsMEM_FS_MEM_POOL MemPool, \
  152217. + Type ** Pointer \
  152218. + ) \
  152219. +{ \
  152220. + gceSTATUS status; \
  152221. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152222. + status = gcoOS_Allocate(MemPool, \
  152223. + gcmSIZEOF(Type), \
  152224. + (gctPOINTER *) Pointer); \
  152225. + gcmFOOTER(); \
  152226. + return status; \
  152227. +} \
  152228. + \
  152229. +gceSTATUS \
  152230. +Prefix##_CAllocate##TypeName( \
  152231. + gcsMEM_FS_MEM_POOL MemPool, \
  152232. + Type ** Pointer \
  152233. + ) \
  152234. +{ \
  152235. + gceSTATUS status; \
  152236. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152237. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  152238. + gcmSIZEOF(Type), \
  152239. + (gctPOINTER *) Pointer)); \
  152240. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, gcmSIZEOF(Type)); \
  152241. + gcmFOOTER(); \
  152242. + return gcvSTATUS_OK; \
  152243. +} \
  152244. + \
  152245. +gceSTATUS \
  152246. +Prefix##_Free##TypeName( \
  152247. + gcsMEM_FS_MEM_POOL MemPool, \
  152248. + Type * Pointer \
  152249. + ) \
  152250. +{ \
  152251. + gceSTATUS status; \
  152252. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152253. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  152254. + gcmFOOTER(); \
  152255. + return status; \
  152256. +}
  152257. +
  152258. +#define gcmMEM_DeclareVSMemPool(Type, TypeName, Prefix) \
  152259. +gceSTATUS \
  152260. +Prefix##_Allocate##TypeName( \
  152261. + gcsMEM_VS_MEM_POOL MemPool, \
  152262. + Type ** Pointer, \
  152263. + gctUINT Size \
  152264. + ) \
  152265. +{ \
  152266. + gceSTATUS status; \
  152267. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  152268. + status = gcoOS_Allocate(MemPool, \
  152269. + Size, \
  152270. + (gctPOINTER *) Pointer); \
  152271. + gcmFOOTER(); \
  152272. + return status; \
  152273. +} \
  152274. + \
  152275. +gceSTATUS \
  152276. +Prefix##_CAllocate##TypeName( \
  152277. + gcsMEM_VS_MEM_POOL MemPool, \
  152278. + Type ** Pointer, \
  152279. + gctUINT Size \
  152280. + ) \
  152281. +{ \
  152282. + gceSTATUS status; \
  152283. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Size=%u", MemPool, Pointer, Size); \
  152284. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  152285. + Size, \
  152286. + (gctPOINTER *) Pointer)); \
  152287. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Size); \
  152288. + gcmFOOTER(); \
  152289. + return gcvSTATUS_OK; \
  152290. +} \
  152291. + \
  152292. +gceSTATUS \
  152293. +Prefix##_Free##TypeName( \
  152294. + gcsMEM_VS_MEM_POOL MemPool, \
  152295. + Type * Pointer \
  152296. + ) \
  152297. +{ \
  152298. + gceSTATUS status; \
  152299. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152300. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  152301. + gcmFOOTER(); \
  152302. + return status; \
  152303. +}
  152304. +
  152305. +#define gcmMEM_DeclareAFSMemPool(Type, TypeName, Prefix) \
  152306. +gceSTATUS \
  152307. +Prefix##_Allocate##TypeName( \
  152308. + gcsMEM_AFS_MEM_POOL MemPool, \
  152309. + Type ** Pointer, \
  152310. + gctUINT Count \
  152311. + ) \
  152312. +{ \
  152313. + gceSTATUS status; \
  152314. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  152315. + status = gcoOS_Allocate(MemPool, \
  152316. + Count * gcmSIZEOF(Type), \
  152317. + (gctPOINTER *) Pointer); \
  152318. + gcmFOOTER(); \
  152319. + return status; \
  152320. +} \
  152321. + \
  152322. +gceSTATUS \
  152323. +Prefix##_CAllocate##TypeName( \
  152324. + gcsMEM_AFS_MEM_POOL MemPool, \
  152325. + Type ** Pointer, \
  152326. + gctUINT Count \
  152327. + ) \
  152328. +{ \
  152329. + gceSTATUS status; \
  152330. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x Count=%u", MemPool, Pointer, Count); \
  152331. + gcmERR_RETURN(gcoOS_Allocate(MemPool, \
  152332. + Count * gcmSIZEOF(Type), \
  152333. + (gctPOINTER *) Pointer)); \
  152334. + gcoOS_ZeroMemory(*(gctPOINTER *) Pointer, Count * gcmSIZEOF(Type)); \
  152335. + gcmFOOTER(); \
  152336. + return gcvSTATUS_OK; \
  152337. +} \
  152338. + \
  152339. +gceSTATUS \
  152340. +Prefix##_Free##TypeName( \
  152341. + gcsMEM_AFS_MEM_POOL MemPool, \
  152342. + Type * Pointer \
  152343. + ) \
  152344. +{ \
  152345. + gceSTATUS status; \
  152346. + gcmHEADER_ARG("MemPool=0x%x Pointer=0x%x", MemPool, Pointer); \
  152347. + status = gcmOS_SAFE_FREE(MemPool, Pointer); \
  152348. + gcmFOOTER(); \
  152349. + return status; \
  152350. +}
  152351. +#endif
  152352. +
  152353. +/*******************************************************************************
  152354. +** Memory Pool Data Functions
  152355. +*******************************************************************************/
  152356. +gceSTATUS
  152357. +gcfMEM_InitFSMemPool(
  152358. + IN gcsMEM_FS_MEM_POOL * MemPool,
  152359. + IN gcoOS OS,
  152360. + IN gctUINT NodeCount,
  152361. + IN gctUINT NodeSize
  152362. + );
  152363. +
  152364. +gceSTATUS
  152365. +gcfMEM_FreeFSMemPool(
  152366. + IN gcsMEM_FS_MEM_POOL * MemPool
  152367. + );
  152368. +
  152369. +gceSTATUS
  152370. +gcfMEM_FSMemPoolGetANode(
  152371. + IN gcsMEM_FS_MEM_POOL MemPool,
  152372. + OUT gctPOINTER * Node
  152373. + );
  152374. +
  152375. +gceSTATUS
  152376. +gcfMEM_FSMemPoolFreeANode(
  152377. + IN gcsMEM_FS_MEM_POOL MemPool,
  152378. + IN gctPOINTER Node
  152379. + );
  152380. +
  152381. +gceSTATUS
  152382. +gcfMEM_FSMemPoolFreeAList(
  152383. + IN gcsMEM_FS_MEM_POOL MemPool,
  152384. + IN gctPOINTER FirstNode,
  152385. + IN gctPOINTER LastNode
  152386. + );
  152387. +
  152388. +gceSTATUS
  152389. +gcfMEM_InitVSMemPool(
  152390. + IN gcsMEM_VS_MEM_POOL * MemPool,
  152391. + IN gcoOS OS,
  152392. + IN gctUINT BlockSize,
  152393. + IN gctBOOL RecycleFreeNode
  152394. + );
  152395. +
  152396. +gceSTATUS
  152397. +gcfMEM_FreeVSMemPool(
  152398. + IN gcsMEM_VS_MEM_POOL * MemPool
  152399. + );
  152400. +
  152401. +gceSTATUS
  152402. +gcfMEM_VSMemPoolGetANode(
  152403. + IN gcsMEM_VS_MEM_POOL MemPool,
  152404. + IN gctUINT Size,
  152405. + IN gctUINT Alignment,
  152406. + OUT gctPOINTER * Node
  152407. + );
  152408. +
  152409. +gceSTATUS
  152410. +gcfMEM_VSMemPoolFreeANode(
  152411. + IN gcsMEM_VS_MEM_POOL MemPool,
  152412. + IN gctPOINTER Node
  152413. + );
  152414. +
  152415. +gceSTATUS
  152416. +gcfMEM_InitAFSMemPool(
  152417. + IN gcsMEM_AFS_MEM_POOL *MemPool,
  152418. + IN gcoOS OS,
  152419. + IN gctUINT NodeCount,
  152420. + IN gctUINT NodeSize
  152421. + );
  152422. +
  152423. +gceSTATUS
  152424. +gcfMEM_FreeAFSMemPool(
  152425. + IN gcsMEM_AFS_MEM_POOL *MemPool
  152426. + );
  152427. +
  152428. +gceSTATUS
  152429. +gcfMEM_AFSMemPoolGetANode(
  152430. + IN gcsMEM_AFS_MEM_POOL MemPool,
  152431. + IN gctUINT Count,
  152432. + OUT gctPOINTER * Node
  152433. + );
  152434. +
  152435. +gceSTATUS
  152436. +gcfMEM_AFSMemPoolFreeANode(
  152437. + IN gcsMEM_AFS_MEM_POOL MemPool,
  152438. + IN gctPOINTER Node
  152439. + );
  152440. +
  152441. +#ifdef __cplusplus
  152442. +}
  152443. +#endif
  152444. +
  152445. +#endif /* VIVANTE_NO_3D */
  152446. +#endif /* __gc_hal_mem_h_ */
  152447. diff -Nur linux-3.14.17/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
  152448. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h 1970-01-01 01:00:00.000000000 +0100
  152449. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h 2014-09-11 18:06:03.122042450 +0200
  152450. @@ -0,0 +1,947 @@
  152451. +/****************************************************************************
  152452. +*
  152453. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  152454. +*
  152455. +* This program is free software; you can redistribute it and/or modify
  152456. +* it under the terms of the GNU General Public License as published by
  152457. +* the Free Software Foundation; either version 2 of the license, or
  152458. +* (at your option) any later version.
  152459. +*
  152460. +* This program is distributed in the hope that it will be useful,
  152461. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  152462. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  152463. +* GNU General Public License for more details.
  152464. +*
  152465. +* You should have received a copy of the GNU General Public License
  152466. +* along with this program; if not write to the Free Software
  152467. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  152468. +*
  152469. +*****************************************************************************/
  152470. +
  152471. +
  152472. +#ifndef __gc_hal_options_h_
  152473. +#define __gc_hal_options_h_
  152474. +
  152475. +/*
  152476. + gcdPRINT_VERSION
  152477. +
  152478. + Print HAL version.
  152479. +*/
  152480. +#ifndef gcdPRINT_VERSION
  152481. +# define gcdPRINT_VERSION 0
  152482. +#endif
  152483. +
  152484. +/*
  152485. + USE_NEW_LINUX_SIGNAL
  152486. +
  152487. + This define enables the Linux kernel signaling between kernel and user.
  152488. +*/
  152489. +#ifndef USE_NEW_LINUX_SIGNAL
  152490. +# define USE_NEW_LINUX_SIGNAL 0
  152491. +#endif
  152492. +
  152493. +/*
  152494. + VIVANTE_PROFILER
  152495. +
  152496. + This define enables the profiler.
  152497. +*/
  152498. +#ifndef VIVANTE_PROFILER
  152499. +# define VIVANTE_PROFILER 1
  152500. +#endif
  152501. +
  152502. +#ifndef VIVANTE_PROFILER_PERDRAW
  152503. +# define VIVANTE_PROFILER_PERDRAW 0
  152504. +#endif
  152505. +
  152506. +/*
  152507. + VIVANTE_PROFILER_CONTEXT
  152508. +
  152509. + This define enables the profiler according to each hw context.
  152510. +*/
  152511. +#ifndef VIVANTE_PROFILER_CONTEXT
  152512. +# define VIVANTE_PROFILER_CONTEXT 1
  152513. +#endif
  152514. +
  152515. +/*
  152516. + gcdUSE_VG
  152517. +
  152518. + Enable VG HAL layer (only for GC350).
  152519. +*/
  152520. +#ifndef gcdUSE_VG
  152521. +# define gcdUSE_VG 0
  152522. +#endif
  152523. +
  152524. +/*
  152525. + USE_SW_FB
  152526. +
  152527. + Set to 1 if the frame buffer memory cannot be accessed by the GPU.
  152528. +*/
  152529. +#ifndef USE_SW_FB
  152530. +# define USE_SW_FB 0
  152531. +#endif
  152532. +
  152533. +/*
  152534. + USE_SUPER_SAMPLING
  152535. +
  152536. + This define enables super-sampling support.
  152537. +*/
  152538. +#define USE_SUPER_SAMPLING 0
  152539. +
  152540. +/*
  152541. + PROFILE_HAL_COUNTERS
  152542. +
  152543. + This define enables HAL counter profiling support. HW and SHADER
  152544. + counter profiling depends on this.
  152545. +*/
  152546. +#ifndef PROFILE_HAL_COUNTERS
  152547. +# define PROFILE_HAL_COUNTERS 1
  152548. +#endif
  152549. +
  152550. +/*
  152551. + PROFILE_HW_COUNTERS
  152552. +
  152553. + This define enables HW counter profiling support.
  152554. +*/
  152555. +#ifndef PROFILE_HW_COUNTERS
  152556. +# define PROFILE_HW_COUNTERS 1
  152557. +#endif
  152558. +
  152559. +/*
  152560. + PROFILE_SHADER_COUNTERS
  152561. +
  152562. + This define enables SHADER counter profiling support.
  152563. +*/
  152564. +#ifndef PROFILE_SHADER_COUNTERS
  152565. +# define PROFILE_SHADER_COUNTERS 1
  152566. +#endif
  152567. +
  152568. +/*
  152569. + COMMAND_PROCESSOR_VERSION
  152570. +
  152571. + The version of the command buffer and task manager.
  152572. +*/
  152573. +#define COMMAND_PROCESSOR_VERSION 1
  152574. +
  152575. +/*
  152576. + gcdDUMP_KEY
  152577. +
  152578. + Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
  152579. + HAL will create dumps for the processes matching this key.
  152580. +*/
  152581. +#ifndef gcdDUMP_KEY
  152582. +# define gcdDUMP_KEY "process"
  152583. +#endif
  152584. +
  152585. +/*
  152586. + gcdDUMP_PATH
  152587. +
  152588. + The dump file location. Some processes cannot write to the sdcard.
  152589. + Try apps' data dir, e.g. /data/data/com.android.launcher
  152590. +*/
  152591. +#ifndef gcdDUMP_PATH
  152592. +#if defined(ANDROID)
  152593. +# define gcdDUMP_PATH "/mnt/sdcard/"
  152594. +#else
  152595. +# define gcdDUMP_PATH "./"
  152596. +#endif
  152597. +#endif
  152598. +
  152599. +/*
  152600. + gcdDUMP
  152601. +
  152602. + When set to 1, a dump of all states and memory uploads, as well as other
  152603. + hardware related execution will be printed to the debug console. This
  152604. + data can be used for playing back applications.
  152605. +*/
  152606. +#ifndef gcdDUMP
  152607. +# define gcdDUMP 0
  152608. +#endif
  152609. +
  152610. +/*
  152611. + gcdDUMP_API
  152612. +
  152613. + When set to 1, a high level dump of the EGL and GL/VG APs's are
  152614. + captured.
  152615. +*/
  152616. +#ifndef gcdDUMP_API
  152617. +# define gcdDUMP_API 0
  152618. +#endif
  152619. +
  152620. +/*
  152621. + gcdDUMP_FRAMERATE
  152622. + When set to a value other than zero, averaqe frame rate will be dumped.
  152623. + The value set is the starting frame that the average will be calculated.
  152624. + This is needed because sometimes first few frames are too slow to be included
  152625. + in the average. Frame count starts from 1.
  152626. +*/
  152627. +#ifndef gcdDUMP_FRAMERATE
  152628. +# define gcdDUMP_FRAMERATE 0
  152629. +#endif
  152630. +
  152631. +/*
  152632. + gcdVIRTUAL_COMMAND_BUFFER
  152633. + When set to 1, user command buffer and context buffer will be allocated
  152634. + from gcvPOOL_VIRTUAL.
  152635. +*/
  152636. +#ifndef gcdVIRTUAL_COMMAND_BUFFER
  152637. +# define gcdVIRTUAL_COMMAND_BUFFER 0
  152638. +#endif
  152639. +
  152640. +/*
  152641. + gcdENABLE_FSCALE_VAL_ADJUST
  152642. + When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally.
  152643. + */
  152644. +#ifndef gcdENABLE_FSCALE_VAL_ADJUST
  152645. +# define gcdENABLE_FSCALE_VAL_ADJUST 1
  152646. +#endif
  152647. +
  152648. +/*
  152649. + gcdDUMP_IN_KERNEL
  152650. +
  152651. + When set to 1, all dumps will happen in the kernel. This is handy if
  152652. + you want the kernel to dump its command buffers as well and the data
  152653. + needs to be in sync.
  152654. +*/
  152655. +#ifndef gcdDUMP_IN_KERNEL
  152656. +# define gcdDUMP_IN_KERNEL 0
  152657. +#endif
  152658. +
  152659. +/*
  152660. + gcdDUMP_COMMAND
  152661. +
  152662. + When set to non-zero, the command queue will dump all incoming command
  152663. + and context buffers as well as all other modifications to the command
  152664. + queue.
  152665. +*/
  152666. +#ifndef gcdDUMP_COMMAND
  152667. +# define gcdDUMP_COMMAND 0
  152668. +#endif
  152669. +
  152670. +/*
  152671. + gcdDUMP_FRAME_TGA
  152672. +
  152673. + When set to a value other than 0, a dump of the frame specified by the value,
  152674. + will be done into frame.tga. Frame count starts from 1.
  152675. + */
  152676. +#ifndef gcdDUMP_FRAME_TGA
  152677. +#define gcdDUMP_FRAME_TGA 0
  152678. +#endif
  152679. +/*
  152680. + gcdNULL_DRIVER
  152681. +
  152682. + Set to 1 for infinite speed hardware.
  152683. + Set to 2 for bypassing the HAL.
  152684. + Set to 3 for bypassing the drivers.
  152685. +*/
  152686. +#ifndef gcdNULL_DRIVER
  152687. +# define gcdNULL_DRIVER 0
  152688. +#endif
  152689. +
  152690. +/*
  152691. + gcdENABLE_TIMEOUT_DETECTION
  152692. +
  152693. + Enable timeout detection.
  152694. +*/
  152695. +#ifndef gcdENABLE_TIMEOUT_DETECTION
  152696. +# define gcdENABLE_TIMEOUT_DETECTION 0
  152697. +#endif
  152698. +
  152699. +/*
  152700. + gcdCMD_BUFFER_SIZE
  152701. +
  152702. + Number of bytes in a command buffer.
  152703. +*/
  152704. +#ifndef gcdCMD_BUFFER_SIZE
  152705. +# define gcdCMD_BUFFER_SIZE (128 << 10)
  152706. +#endif
  152707. +
  152708. +/*
  152709. + gcdCMD_BUFFERS
  152710. +
  152711. + Number of command buffers to use per client.
  152712. +*/
  152713. +#ifndef gcdCMD_BUFFERS
  152714. +# define gcdCMD_BUFFERS 2
  152715. +#endif
  152716. +
  152717. +/*
  152718. + gcdMAX_CMD_BUFFERS
  152719. +
  152720. + Maximum number of command buffers to use per client.
  152721. +*/
  152722. +#ifndef gcdMAX_CMD_BUFFERS
  152723. +# define gcdMAX_CMD_BUFFERS 8
  152724. +#endif
  152725. +
  152726. +/*
  152727. + gcdCOMMAND_QUEUES
  152728. +
  152729. + Number of command queues in the kernel.
  152730. +*/
  152731. +#ifndef gcdCOMMAND_QUEUES
  152732. +# define gcdCOMMAND_QUEUES 2
  152733. +#endif
  152734. +
  152735. +/*
  152736. + gcdPOWER_CONTROL_DELAY
  152737. +
  152738. + The delay in milliseconds required to wait until the GPU has woke up
  152739. + from a suspend or power-down state. This is system dependent because
  152740. + the bus clock also needs to stabalize.
  152741. +*/
  152742. +#ifndef gcdPOWER_CONTROL_DELAY
  152743. +# define gcdPOWER_CONTROL_DELAY 0
  152744. +#endif
  152745. +
  152746. +/*
  152747. + gcdMIRROR_PAGETABLE
  152748. +
  152749. + Enable it when GPUs with old MMU and new MMU exist at same SoC. It makes
  152750. + each GPU use same virtual address to access same physical memory.
  152751. +*/
  152752. +#ifndef gcdMIRROR_PAGETABLE
  152753. +# define gcdMIRROR_PAGETABLE 0
  152754. +#endif
  152755. +
  152756. +/*
  152757. + gcdMMU_SIZE
  152758. +
  152759. + Size of the MMU page table in bytes. Each 4 bytes can hold 4kB worth of
  152760. + virtual data.
  152761. +*/
  152762. +#ifndef gcdMMU_SIZE
  152763. +#if gcdMIRROR_PAGETABLE
  152764. +# define gcdMMU_SIZE 0x200000
  152765. +#else
  152766. +# define gcdMMU_SIZE (2048 << 10)
  152767. +#endif
  152768. +#endif
  152769. +
  152770. +/*
  152771. + gcdSECURE_USER
  152772. +
  152773. + Use logical addresses instead of physical addresses in user land. In
  152774. + this case a hint table is created for both command buffers and context
  152775. + buffers, and that hint table will be used to patch up those buffers in
  152776. + the kernel when they are ready to submit.
  152777. +*/
  152778. +#ifndef gcdSECURE_USER
  152779. +# define gcdSECURE_USER 0
  152780. +#endif
  152781. +
  152782. +/*
  152783. + gcdSECURE_CACHE_SLOTS
  152784. +
  152785. + Number of slots in the logical to DMA address cache table. Each time a
  152786. + logical address needs to be translated into a DMA address for the GPU,
  152787. + this cache will be walked. The replacement scheme is LRU.
  152788. +*/
  152789. +#ifndef gcdSECURE_CACHE_SLOTS
  152790. +# define gcdSECURE_CACHE_SLOTS 1024
  152791. +#endif
  152792. +
  152793. +/*
  152794. + gcdSECURE_CACHE_METHOD
  152795. +
  152796. + Replacement scheme used for Secure Cache. The following options are
  152797. + available:
  152798. +
  152799. + gcdSECURE_CACHE_LRU
  152800. + A standard LRU cache.
  152801. +
  152802. + gcdSECURE_CACHE_LINEAR
  152803. + A linear walker with the idea that an application will always
  152804. + render the scene in a similar way, so the next entry in the
  152805. + cache should be a hit most of the time.
  152806. +
  152807. + gcdSECURE_CACHE_HASH
  152808. + A 256-entry hash table.
  152809. +
  152810. + gcdSECURE_CACHE_TABLE
  152811. + A simple cache but with potential of a lot of cache replacement.
  152812. +*/
  152813. +#ifndef gcdSECURE_CACHE_METHOD
  152814. +# define gcdSECURE_CACHE_METHOD gcdSECURE_CACHE_HASH
  152815. +#endif
  152816. +
  152817. +/*
  152818. + gcdREGISTER_ACCESS_FROM_USER
  152819. +
  152820. + Set to 1 to allow IOCTL calls to get through from user land. This
  152821. + should only be in debug or development drops.
  152822. +*/
  152823. +#ifndef gcdREGISTER_ACCESS_FROM_USER
  152824. +# define gcdREGISTER_ACCESS_FROM_USER 1
  152825. +#endif
  152826. +
  152827. +/*
  152828. + gcdUSER_HEAP_ALLOCATOR
  152829. +
  152830. + Set to 1 to enable user mode heap allocator for fast memory allocation
  152831. + and destroying. Otherwise, memory allocation/destroying in user mode
  152832. + will be directly managed by system. Only for linux for now.
  152833. +*/
  152834. +#ifndef gcdUSER_HEAP_ALLOCATOR
  152835. +# define gcdUSER_HEAP_ALLOCATOR 1
  152836. +#endif
  152837. +
  152838. +/*
  152839. + gcdHEAP_SIZE
  152840. +
  152841. + Set the allocation size for the internal heaps. Each time a heap is
  152842. + full, a new heap will be allocated with this minmimum amount of bytes.
  152843. + The bigger this size, the fewer heaps there are to allocate, the better
  152844. + the performance. However, heaps won't be freed until they are
  152845. + completely free, so there might be some more memory waste if the size is
  152846. + too big.
  152847. +*/
  152848. +#ifndef gcdHEAP_SIZE
  152849. +# define gcdHEAP_SIZE (64 << 10)
  152850. +#endif
  152851. +
  152852. +/*
  152853. + gcdPOWER_SUSNPEND_WHEN_IDLE
  152854. +
  152855. + Set to 1 to make GPU enter gcvPOWER_SUSPEND when idle detected,
  152856. + otherwise GPU will enter gcvPOWER_IDLE.
  152857. +*/
  152858. +#ifndef gcdPOWER_SUSNPEND_WHEN_IDLE
  152859. +# define gcdPOWER_SUSNPEND_WHEN_IDLE 1
  152860. +#endif
  152861. +
  152862. +/*
  152863. + gcdFPGA_BUILD
  152864. +
  152865. + This define enables work arounds for FPGA images.
  152866. +*/
  152867. +#ifndef gcdFPGA_BUILD
  152868. +# define gcdFPGA_BUILD 0
  152869. +#endif
  152870. +
  152871. +/*
  152872. + gcdGPU_TIMEOUT
  152873. +
  152874. + This define specified the number of milliseconds the system will wait
  152875. + before it broadcasts the GPU is stuck. In other words, it will define
  152876. + the timeout of any operation that needs to wait for the GPU.
  152877. +
  152878. + If the value is 0, no timeout will be checked for.
  152879. +*/
  152880. +#ifndef gcdGPU_TIMEOUT
  152881. +#if gcdFPGA_BUILD
  152882. +# define gcdGPU_TIMEOUT 0
  152883. +# else
  152884. +# define gcdGPU_TIMEOUT 20000
  152885. +# endif
  152886. +#endif
  152887. +
  152888. +/*
  152889. + gcdGPU_ADVANCETIMER
  152890. +
  152891. + it is advance timer.
  152892. +*/
  152893. +#ifndef gcdGPU_ADVANCETIMER
  152894. +# define gcdGPU_ADVANCETIMER 250
  152895. +#endif
  152896. +
  152897. +/*
  152898. + gcdSTATIC_LINK
  152899. +
  152900. + This define disalbes static linking;
  152901. +*/
  152902. +#ifndef gcdSTATIC_LINK
  152903. +# define gcdSTATIC_LINK 0
  152904. +#endif
  152905. +
  152906. +/*
  152907. + gcdUSE_NEW_HEAP
  152908. +
  152909. + Setting this define to 1 enables new heap.
  152910. +*/
  152911. +#ifndef gcdUSE_NEW_HEAP
  152912. +# define gcdUSE_NEW_HEAP 0
  152913. +#endif
  152914. +
  152915. +/*
  152916. + gcdCMD_NO_2D_CONTEXT
  152917. +
  152918. + This define enables no-context 2D command buffer.
  152919. +*/
  152920. +#ifndef gcdCMD_NO_2D_CONTEXT
  152921. +# define gcdCMD_NO_2D_CONTEXT 1
  152922. +#endif
  152923. +
  152924. +/*
  152925. + gcdENABLE_BANK_ALIGNMENT
  152926. +
  152927. + When enabled, video memory is allocated bank aligned. The vendor can modify
  152928. + _GetSurfaceBankAlignment() and gcoSURF_GetBankOffsetBytes() to define how
  152929. + different types of allocations are bank and channel aligned.
  152930. + When disabled (default), no bank alignment is done.
  152931. +*/
  152932. +#ifndef gcdENABLE_BANK_ALIGNMENT
  152933. +# define gcdENABLE_BANK_ALIGNMENT 0
  152934. +#endif
  152935. +
  152936. +/*
  152937. + gcdBANK_BIT_START
  152938. +
  152939. + Specifies the start bit of the bank (inclusive).
  152940. +*/
  152941. +#ifndef gcdBANK_BIT_START
  152942. +# define gcdBANK_BIT_START 12
  152943. +#endif
  152944. +
  152945. +/*
  152946. + gcdBANK_BIT_END
  152947. +
  152948. + Specifies the end bit of the bank (inclusive).
  152949. +*/
  152950. +#ifndef gcdBANK_BIT_END
  152951. +# define gcdBANK_BIT_END 14
  152952. +#endif
  152953. +
  152954. +/*
  152955. + gcdBANK_CHANNEL_BIT
  152956. +
  152957. + When set, video memory when allocated bank aligned is allocated such that
  152958. + render and depth buffer addresses alternate on the channel bit specified.
  152959. + This option has an effect only when gcdENABLE_BANK_ALIGNMENT is enabled.
  152960. + When disabled (default), no alteration is done.
  152961. +*/
  152962. +#ifndef gcdBANK_CHANNEL_BIT
  152963. +# define gcdBANK_CHANNEL_BIT 7
  152964. +#endif
  152965. +
  152966. +/*
  152967. + gcdDYNAMIC_SPEED
  152968. +
  152969. + When non-zero, it informs the kernel driver to use the speed throttling
  152970. + broadcasting functions to inform the system the GPU should be spet up or
  152971. + slowed down. It will send a broadcast for slowdown each "interval"
  152972. + specified by this define in milliseconds
  152973. + (gckOS_BroadcastCalibrateSpeed).
  152974. +*/
  152975. +#ifndef gcdDYNAMIC_SPEED
  152976. +# define gcdDYNAMIC_SPEED 2000
  152977. +#endif
  152978. +
  152979. +/*
  152980. + gcdDYNAMIC_EVENT_THRESHOLD
  152981. +
  152982. + When non-zero, it specifies the maximum number of available events at
  152983. + which the kernel driver will issue a broadcast to speed up the GPU
  152984. + (gckOS_BroadcastHurry).
  152985. +*/
  152986. +#ifndef gcdDYNAMIC_EVENT_THRESHOLD
  152987. +# define gcdDYNAMIC_EVENT_THRESHOLD 5
  152988. +#endif
  152989. +
  152990. +/*
  152991. + gcdENABLE_PROFILING
  152992. +
  152993. + Enable profiling macros.
  152994. +*/
  152995. +#ifndef gcdENABLE_PROFILING
  152996. +# define gcdENABLE_PROFILING 0
  152997. +#endif
  152998. +
  152999. +/*
  153000. + gcdENABLE_128B_MERGE
  153001. +
  153002. + Enable 128B merge for the BUS control.
  153003. +*/
  153004. +#ifndef gcdENABLE_128B_MERGE
  153005. +# define gcdENABLE_128B_MERGE 0
  153006. +#endif
  153007. +
  153008. +/*
  153009. + gcdFRAME_DB
  153010. +
  153011. + When non-zero, it specified the number of frames inside the frame
  153012. + database. The frame DB will collect per-frame timestamps and hardware
  153013. + counters.
  153014. +*/
  153015. +#ifndef gcdFRAME_DB
  153016. +# define gcdFRAME_DB 0
  153017. +# define gcdFRAME_DB_RESET 0
  153018. +# define gcdFRAME_DB_NAME "/var/log/frameDB.log"
  153019. +#endif
  153020. +
  153021. +/*
  153022. + gcdENABLE_VG
  153023. + enable the 2D openVG
  153024. +*/
  153025. +
  153026. +#ifndef gcdENABLE_VG
  153027. +# define gcdENABLE_VG 0
  153028. +#endif
  153029. +
  153030. +/*
  153031. + gcdDYNAMIC_MAP_RESERVED_MEMORY
  153032. +
  153033. + When gcvPOOL_SYSTEM is constructed from RESERVED memory,
  153034. + driver can map the whole reserved memory to kernel space
  153035. + at the beginning, or just map a piece of memory when need
  153036. + to access.
  153037. +
  153038. + Notice:
  153039. + - It's only for the 2D openVG. For other cores, there is
  153040. + _NO_ need to map reserved memory to kernel.
  153041. + - It's meaningless when memory is allocated by
  153042. + gckOS_AllocateContiguous, in that case, memory is always
  153043. + mapped by system when allocated.
  153044. +*/
  153045. +#ifndef gcdDYNAMIC_MAP_RESERVED_MEMORY
  153046. +# define gcdDYNAMIC_MAP_RESERVED_MEMORY 1
  153047. +#endif
  153048. +
  153049. +/*
  153050. + gcdPAGED_MEMORY_CACHEABLE
  153051. +
  153052. + When non-zero, paged memory will be cacheable.
  153053. +
  153054. + Normally, driver will detemines whether a video memory
  153055. + is cacheable or not. When cacheable is not neccessary,
  153056. + it will be writecombine.
  153057. +
  153058. + This option is only for those SOC which can't enable
  153059. + writecombine without enabling cacheable.
  153060. +*/
  153061. +
  153062. +#ifndef gcdPAGED_MEMORY_CACHEABLE
  153063. +# define gcdPAGED_MEMORY_CACHEABLE 0
  153064. +#endif
  153065. +
  153066. +/*
  153067. + gcdNONPAGED_MEMORY_CACHEABLE
  153068. +
  153069. + When non-zero, non paged memory will be cacheable.
  153070. +*/
  153071. +
  153072. +#ifndef gcdNONPAGED_MEMORY_CACHEABLE
  153073. +# define gcdNONPAGED_MEMORY_CACHEABLE 0
  153074. +#endif
  153075. +
  153076. +/*
  153077. + gcdNONPAGED_MEMORY_BUFFERABLE
  153078. +
  153079. + When non-zero, non paged memory will be bufferable.
  153080. + gcdNONPAGED_MEMORY_BUFFERABLE and gcdNONPAGED_MEMORY_CACHEABLE
  153081. + can't be set 1 at same time
  153082. +*/
  153083. +
  153084. +#ifndef gcdNONPAGED_MEMORY_BUFFERABLE
  153085. +# define gcdNONPAGED_MEMORY_BUFFERABLE 1
  153086. +#endif
  153087. +
  153088. +/*
  153089. + gcdENABLE_INFINITE_SPEED_HW
  153090. + enable the Infinte HW , this is for 2D openVG
  153091. +*/
  153092. +
  153093. +#ifndef gcdENABLE_INFINITE_SPEED_HW
  153094. +# define gcdENABLE_INFINITE_SPEED_HW 0
  153095. +#endif
  153096. +
  153097. +/*
  153098. + gcdENABLE_TS_DOUBLE_BUFFER
  153099. + enable the TS double buffer, this is for 2D openVG
  153100. +*/
  153101. +
  153102. +#ifndef gcdENABLE_TS_DOUBLE_BUFFER
  153103. +# define gcdENABLE_TS_DOUBLE_BUFFER 1
  153104. +#endif
  153105. +
  153106. +/*
  153107. + gcd6000_SUPPORT
  153108. +
  153109. + Temporary define to enable/disable 6000 support.
  153110. + */
  153111. +#ifndef gcd6000_SUPPORT
  153112. +# define gcd6000_SUPPORT 0
  153113. +#endif
  153114. +
  153115. +/*
  153116. + gcdPOWEROFF_TIMEOUT
  153117. +
  153118. + When non-zero, GPU will power off automatically from
  153119. + idle state, and gcdPOWEROFF_TIMEOUT is also the default
  153120. + timeout in milliseconds.
  153121. + */
  153122. +
  153123. +#ifndef gcdPOWEROFF_TIMEOUT
  153124. +# define gcdPOWEROFF_TIMEOUT 300
  153125. +#endif
  153126. +
  153127. +/*
  153128. + gcdUSE_VIDMEM_PER_PID
  153129. +*/
  153130. +#ifndef gcdUSE_VIDMEM_PER_PID
  153131. +# define gcdUSE_VIDMEM_PER_PID 0
  153132. +#endif
  153133. +
  153134. +/*
  153135. + QNX_SINGLE_THREADED_DEBUGGING
  153136. +*/
  153137. +#ifndef QNX_SINGLE_THREADED_DEBUGGING
  153138. +# define QNX_SINGLE_THREADED_DEBUGGING 0
  153139. +#endif
  153140. +
  153141. +/*
  153142. + gcdENABLE_RECOVERY
  153143. +
  153144. + This define enables the recovery code.
  153145. +*/
  153146. +#ifndef gcdENABLE_RECOVERY
  153147. +# define gcdENABLE_RECOVERY 1
  153148. +#endif
  153149. +
  153150. +/*
  153151. + gcdRENDER_THREADS
  153152. +
  153153. + Number of render threads. Make it zero, and there will be no render
  153154. + threads.
  153155. +*/
  153156. +#ifndef gcdRENDER_THREADS
  153157. +# define gcdRENDER_THREADS 0
  153158. +#endif
  153159. +
  153160. +/*
  153161. + gcdSMP
  153162. +
  153163. + This define enables SMP support.
  153164. +
  153165. + Currently, it only works on Linux/Android,
  153166. + Kbuild will config it according to whether
  153167. + CONFIG_SMP is set.
  153168. +
  153169. +*/
  153170. +#ifndef gcdSMP
  153171. +# define gcdSMP 0
  153172. +#endif
  153173. +
  153174. +/*
  153175. + gcdSUPPORT_SWAP_RECTANGLE
  153176. +
  153177. + Support swap with a specific rectangle.
  153178. +
  153179. + Set the rectangle with eglSetSwapRectangleANDROID api.
  153180. +*/
  153181. +#ifndef gcdSUPPORT_SWAP_RECTANGLE
  153182. +# define gcdSUPPORT_SWAP_RECTANGLE 0
  153183. +#endif
  153184. +
  153185. +/*
  153186. + gcdGPU_LINEAR_BUFFER_ENABLED
  153187. +
  153188. + Use linear buffer for GPU apps so HWC can do 2D composition.
  153189. +*/
  153190. +#ifndef gcdGPU_LINEAR_BUFFER_ENABLED
  153191. +# define gcdGPU_LINEAR_BUFFER_ENABLED 1
  153192. +#endif
  153193. +
  153194. +/*
  153195. + gcdENABLE_RENDER_INTO_WINDOW
  153196. +
  153197. + Enable Render-Into-Window (ie, No-Resolve) feature on android.
  153198. + NOTE that even if enabled, it still depends on hardware feature and
  153199. + android application behavior. When hardware feature or application
  153200. + behavior can not support render into window mode, it will fail back
  153201. + to normal mode.
  153202. + When Render-Into-Window is finally used, window back buffer of android
  153203. + applications will be allocated matching render target tiling format.
  153204. + Otherwise buffer tiling is decided by the above option
  153205. + 'gcdGPU_LINEAR_BUFFER_ENABLED'.
  153206. +*/
  153207. +#ifndef gcdENABLE_RENDER_INTO_WINDOW
  153208. +# define gcdENABLE_RENDER_INTO_WINDOW 1
  153209. +#endif
  153210. +
  153211. +/*
  153212. + gcdSHARED_RESOLVE_BUFFER_ENABLED
  153213. +
  153214. + Use shared resolve buffer for all app buffers.
  153215. +*/
  153216. +#ifndef gcdSHARED_RESOLVE_BUFFER_ENABLED
  153217. +# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0
  153218. +#endif
  153219. +
  153220. +/*
  153221. + gcdUSE_TRIANGLE_STRIP_PATCH
  153222. + */
  153223. +#ifndef gcdUSE_TRIANGLE_STRIP_PATCH
  153224. +# define gcdUSE_TRIANGLE_STRIP_PATCH 1
  153225. +#endif
  153226. +
  153227. +/*
  153228. + gcdENABLE_OUTER_CACHE_PATCH
  153229. +
  153230. + Enable the outer cache patch.
  153231. +*/
  153232. +#ifndef gcdENABLE_OUTER_CACHE_PATCH
  153233. +# define gcdENABLE_OUTER_CACHE_PATCH 0
  153234. +#endif
  153235. +
  153236. +#ifndef gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST
  153237. +# ifdef ANDROID
  153238. +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 1
  153239. +# else
  153240. +# define gcdANDROID_UNALIGNED_LINEAR_COMPOSITION_ADJUST 0
  153241. +# endif
  153242. +#endif
  153243. +
  153244. +#ifndef gcdENABLE_PE_DITHER_FIX
  153245. +# define gcdENABLE_PE_DITHER_FIX 1
  153246. +#endif
  153247. +
  153248. +#ifndef gcdSHARED_PAGETABLE
  153249. +# define gcdSHARED_PAGETABLE 1
  153250. +#endif
  153251. +#ifndef gcdUSE_PVR
  153252. +# define gcdUSE_PVR 1
  153253. +#endif
  153254. +
  153255. +/*
  153256. + gcdSMALL_BLOCK_SIZE
  153257. +
  153258. + When non-zero, a part of VIDMEM will be reserved for requests
  153259. + whose requesting size is less than gcdSMALL_BLOCK_SIZE.
  153260. +
  153261. + For Linux, it's the size of a page. If this requeset fallbacks
  153262. + to gcvPOOL_CONTIGUOUS or gcvPOOL_VIRTUAL, memory will be wasted
  153263. + because they allocate a page at least.
  153264. + */
  153265. +#ifndef gcdSMALL_BLOCK_SIZE
  153266. +# define gcdSMALL_BLOCK_SIZE 4096
  153267. +# define gcdRATIO_FOR_SMALL_MEMORY 32
  153268. +#endif
  153269. +
  153270. +/*
  153271. + gcdCONTIGUOUS_SIZE_LIMIT
  153272. + When non-zero, size of video node from gcvPOOL_CONTIGUOUS is
  153273. + limited by gcdCONTIGUOUS_SIZE_LIMIT.
  153274. + */
  153275. +#ifndef gcdCONTIGUOUS_SIZE_LIMIT
  153276. +# define gcdCONTIGUOUS_SIZE_LIMIT 0
  153277. +#endif
  153278. +
  153279. +#ifndef gcdDISALBE_EARLY_EARLY_Z
  153280. +# define gcdDISALBE_EARLY_EARLY_Z 1
  153281. +#endif
  153282. +
  153283. +#ifndef gcdSHADER_SRC_BY_MACHINECODE
  153284. +# define gcdSHADER_SRC_BY_MACHINECODE 1
  153285. +#endif
  153286. +
  153287. +/*
  153288. + gcdLINK_QUEUE_SIZE
  153289. +
  153290. + When non-zero, driver maintains a queue to record information of
  153291. + latest lined context buffer and command buffer. Data in this queue
  153292. + is be used to debug.
  153293. +*/
  153294. +#ifndef gcdLINK_QUEUE_SIZE
  153295. +# define gcdLINK_QUEUE_SIZE 0
  153296. +#endif
  153297. +
  153298. +/* gcdALPHA_KILL_IN_SHADER
  153299. + *
  153300. + * Enable alpha kill inside the shader. This will be set automatically by the
  153301. + * HAL if certain states match a criteria.
  153302. + */
  153303. +#ifndef gcdALPHA_KILL_IN_SHADER
  153304. +# define gcdALPHA_KILL_IN_SHADER 1
  153305. +#endif
  153306. +
  153307. +/* gcdHIGH_PRECISION_DELAY_ENABLE
  153308. + *
  153309. + * Enable high precision schedule delay with 1ms unit. otherwise schedule delay up to 10ms.
  153310. + * Browser app performance will have obvious drop without this enablement
  153311. + */
  153312. +#ifndef gcdHIGH_PRECISION_DELAY_ENABLE
  153313. +# define gcdHIGH_PRECISION_DELAY_ENABLE 1
  153314. +#endif
  153315. +
  153316. +#ifndef gcdUSE_WCLIP_PATCH
  153317. +# define gcdUSE_WCLIP_PATCH 1
  153318. +#endif
  153319. +
  153320. +#ifndef gcdHZ_L2_DISALBE
  153321. +# define gcdHZ_L2_DISALBE 1
  153322. +#endif
  153323. +
  153324. +#ifndef gcdBUGFIX15_DISABLE
  153325. +# define gcdBUGFIX15_DISABLE 1
  153326. +#endif
  153327. +
  153328. +#ifndef gcdDISABLE_HZ_FAST_CLEAR
  153329. +# define gcdDISABLE_HZ_FAST_CLEAR 1
  153330. +#endif
  153331. +
  153332. +#ifndef gcdUSE_NPOT_PATCH
  153333. +#define gcdUSE_NPOT_PATCH 1
  153334. +#endif
  153335. +
  153336. +#ifndef gcdSYNC
  153337. +# define gcdSYNC 1
  153338. +#endif
  153339. +
  153340. +#ifndef gcdENABLE_SPECIAL_HINT3
  153341. +# define gcdENABLE_SPECIAL_HINT3 1
  153342. +#endif
  153343. +
  153344. +#if defined(ANDROID)
  153345. +#ifndef gcdPRE_ROTATION
  153346. +# define gcdPRE_ROTATION 1
  153347. +#endif
  153348. +#endif
  153349. +
  153350. +/*
  153351. + gcdDVFS
  153352. +
  153353. + When non-zero, software will make use of dynamic voltage and
  153354. + frequency feature.
  153355. + */
  153356. +#ifndef gcdDVFS
  153357. +# define gcdDVFS 0
  153358. +# define gcdDVFS_ANAYLSE_WINDOW 4
  153359. +# define gcdDVFS_POLLING_TIME (gcdDVFS_ANAYLSE_WINDOW * 4)
  153360. +#endif
  153361. +
  153362. +/*
  153363. + gcdANDROID_NATIVE_FENCE_SYNC
  153364. +
  153365. + Enable android native fence sync. It is introduced since jellybean-4.2.
  153366. + Depends on linux kernel option: CONFIG_SYNC.
  153367. +
  153368. + 0: Disabled
  153369. + 1: Build framework for native fence sync feature, and EGL extension
  153370. + 2: Enable async swap buffers for client
  153371. + * Native fence sync for client 'queueBuffer' in EGL, which is
  153372. + 'acquireFenceFd' for layer in compositor side.
  153373. + 3. Enable async hwcomposer composition.
  153374. + * 'releaseFenceFd' for layer in compositor side, which is native
  153375. + fence sync when client 'dequeueBuffer'
  153376. + * Native fence sync for compositor 'queueBuffer' in EGL, which is
  153377. + 'acquireFenceFd' for framebuffer target for DC
  153378. + */
  153379. +#ifndef gcdANDROID_NATIVE_FENCE_SYNC
  153380. +# define gcdANDROID_NATIVE_FENCE_SYNC 0
  153381. +#endif
  153382. +
  153383. +#ifndef gcdFORCE_MIPMAP
  153384. +# define gcdFORCE_MIPMAP 0
  153385. +#endif
  153386. +
  153387. +/*
  153388. + gcdFORCE_GAL_LOAD_TWICE
  153389. +
  153390. + When non-zero, each thread except the main one will load libGAL.so twice to avoid potential segmetantion fault when app using dlopen/dlclose.
  153391. + If threads exit arbitrarily, libGAL.so may not unload until the process quit.
  153392. + */
  153393. +#ifndef gcdFORCE_GAL_LOAD_TWICE
  153394. +# define gcdFORCE_GAL_LOAD_TWICE 0
  153395. +#endif
  153396. +
  153397. +#endif /* __gc_hal_options_h_ */
  153398. diff -Nur linux-3.14.17/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
  153399. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h 1970-01-01 01:00:00.000000000 +0100
  153400. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h 2014-09-11 18:06:03.122042450 +0200
  153401. @@ -0,0 +1,584 @@
  153402. +/****************************************************************************
  153403. +*
  153404. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  153405. +*
  153406. +* This program is free software; you can redistribute it and/or modify
  153407. +* it under the terms of the GNU General Public License as published by
  153408. +* the Free Software Foundation; either version 2 of the license, or
  153409. +* (at your option) any later version.
  153410. +*
  153411. +* This program is distributed in the hope that it will be useful,
  153412. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  153413. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  153414. +* GNU General Public License for more details.
  153415. +*
  153416. +* You should have received a copy of the GNU General Public License
  153417. +* along with this program; if not write to the Free Software
  153418. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  153419. +*
  153420. +*****************************************************************************/
  153421. +
  153422. +
  153423. +#ifndef __gc_hal_profiler_h_
  153424. +#define __gc_hal_profiler_h_
  153425. +
  153426. +#ifdef __cplusplus
  153427. +extern "C" {
  153428. +#endif
  153429. +
  153430. +#define GLVERTEX_OBJECT 10
  153431. +#define GLVERTEX_OBJECT_BYTES 11
  153432. +
  153433. +#define GLINDEX_OBJECT 20
  153434. +#define GLINDEX_OBJECT_BYTES 21
  153435. +
  153436. +#define GLTEXTURE_OBJECT 30
  153437. +#define GLTEXTURE_OBJECT_BYTES 31
  153438. +
  153439. +#if VIVANTE_PROFILER
  153440. +#define gcmPROFILE_GC(Enum, Value) gcoPROFILER_Count(gcvNULL, Enum, Value)
  153441. +#else
  153442. +#define gcmPROFILE_GC(Enum, Value) do { } while (gcvFALSE)
  153443. +#endif
  153444. +
  153445. +#ifndef gcdNEW_PROFILER_FILE
  153446. +#define gcdNEW_PROFILER_FILE 1
  153447. +#endif
  153448. +
  153449. +#define ES11_CALLS 151
  153450. +#define ES11_DRAWCALLS (ES11_CALLS + 1)
  153451. +#define ES11_STATECHANGECALLS (ES11_DRAWCALLS + 1)
  153452. +#define ES11_POINTCOUNT (ES11_STATECHANGECALLS + 1)
  153453. +#define ES11_LINECOUNT (ES11_POINTCOUNT + 1)
  153454. +#define ES11_TRIANGLECOUNT (ES11_LINECOUNT + 1)
  153455. +
  153456. +#define ES20_CALLS 159
  153457. +#define ES20_DRAWCALLS (ES20_CALLS + 1)
  153458. +#define ES20_STATECHANGECALLS (ES20_DRAWCALLS + 1)
  153459. +#define ES20_POINTCOUNT (ES20_STATECHANGECALLS + 1)
  153460. +#define ES20_LINECOUNT (ES20_POINTCOUNT + 1)
  153461. +#define ES20_TRIANGLECOUNT (ES20_LINECOUNT + 1)
  153462. +
  153463. +#define VG11_CALLS 88
  153464. +#define VG11_DRAWCALLS (VG11_CALLS + 1)
  153465. +#define VG11_STATECHANGECALLS (VG11_DRAWCALLS + 1)
  153466. +#define VG11_FILLCOUNT (VG11_STATECHANGECALLS + 1)
  153467. +#define VG11_STROKECOUNT (VG11_FILLCOUNT + 1)
  153468. +/* End of Driver API ID Definitions. */
  153469. +
  153470. +/* HAL & MISC IDs. */
  153471. +#define HAL_VERTBUFNEWBYTEALLOC 1
  153472. +#define HAL_VERTBUFTOTALBYTEALLOC (HAL_VERTBUFNEWBYTEALLOC + 1)
  153473. +#define HAL_VERTBUFNEWOBJALLOC (HAL_VERTBUFTOTALBYTEALLOC + 1)
  153474. +#define HAL_VERTBUFTOTALOBJALLOC (HAL_VERTBUFNEWOBJALLOC + 1)
  153475. +#define HAL_INDBUFNEWBYTEALLOC (HAL_VERTBUFTOTALOBJALLOC + 1)
  153476. +#define HAL_INDBUFTOTALBYTEALLOC (HAL_INDBUFNEWBYTEALLOC + 1)
  153477. +#define HAL_INDBUFNEWOBJALLOC (HAL_INDBUFTOTALBYTEALLOC + 1)
  153478. +#define HAL_INDBUFTOTALOBJALLOC (HAL_INDBUFNEWOBJALLOC + 1)
  153479. +#define HAL_TEXBUFNEWBYTEALLOC (HAL_INDBUFTOTALOBJALLOC + 1)
  153480. +#define HAL_TEXBUFTOTALBYTEALLOC (HAL_TEXBUFNEWBYTEALLOC + 1)
  153481. +#define HAL_TEXBUFNEWOBJALLOC (HAL_TEXBUFTOTALBYTEALLOC + 1)
  153482. +#define HAL_TEXBUFTOTALOBJALLOC (HAL_TEXBUFNEWOBJALLOC + 1)
  153483. +
  153484. +#define GPU_CYCLES 1
  153485. +#define GPU_READ64BYTE (GPU_CYCLES + 1)
  153486. +#define GPU_WRITE64BYTE (GPU_READ64BYTE + 1)
  153487. +#define GPU_TOTALCYCLES (GPU_WRITE64BYTE + 1)
  153488. +#define GPU_IDLECYCLES (GPU_TOTALCYCLES + 1)
  153489. +
  153490. +#define VS_INSTCOUNT 1
  153491. +#define VS_BRANCHINSTCOUNT (VS_INSTCOUNT + 1)
  153492. +#define VS_TEXLDINSTCOUNT (VS_BRANCHINSTCOUNT + 1)
  153493. +#define VS_RENDEREDVERTCOUNT (VS_TEXLDINSTCOUNT + 1)
  153494. +#define VS_SOURCE (VS_RENDEREDVERTCOUNT + 1)
  153495. +
  153496. +#define PS_INSTCOUNT 1
  153497. +#define PS_BRANCHINSTCOUNT (PS_INSTCOUNT + 1)
  153498. +#define PS_TEXLDINSTCOUNT (PS_BRANCHINSTCOUNT + 1)
  153499. +#define PS_RENDEREDPIXCOUNT (PS_TEXLDINSTCOUNT + 1)
  153500. +#define PS_SOURCE (PS_RENDEREDPIXCOUNT + 1)
  153501. +
  153502. +#define PA_INVERTCOUNT 1
  153503. +#define PA_INPRIMCOUNT (PA_INVERTCOUNT + 1)
  153504. +#define PA_OUTPRIMCOUNT (PA_INPRIMCOUNT + 1)
  153505. +#define PA_DEPTHCLIPCOUNT (PA_OUTPRIMCOUNT + 1)
  153506. +#define PA_TRIVIALREJCOUNT (PA_DEPTHCLIPCOUNT + 1)
  153507. +#define PA_CULLCOUNT (PA_TRIVIALREJCOUNT + 1)
  153508. +
  153509. +#define SE_TRIANGLECOUNT 1
  153510. +#define SE_LINECOUNT (SE_TRIANGLECOUNT + 1)
  153511. +
  153512. +#define RA_VALIDPIXCOUNT 1
  153513. +#define RA_TOTALQUADCOUNT (RA_VALIDPIXCOUNT + 1)
  153514. +#define RA_VALIDQUADCOUNTEZ (RA_TOTALQUADCOUNT + 1)
  153515. +#define RA_TOTALPRIMCOUNT (RA_VALIDQUADCOUNTEZ + 1)
  153516. +#define RA_PIPECACHEMISSCOUNT (RA_TOTALPRIMCOUNT + 1)
  153517. +#define RA_PREFCACHEMISSCOUNT (RA_PIPECACHEMISSCOUNT + 1)
  153518. +#define RA_EEZCULLCOUNT (RA_PREFCACHEMISSCOUNT + 1)
  153519. +
  153520. +#define TX_TOTBILINEARREQ 1
  153521. +#define TX_TOTTRILINEARREQ (TX_TOTBILINEARREQ + 1)
  153522. +#define TX_TOTDISCARDTEXREQ (TX_TOTTRILINEARREQ + 1)
  153523. +#define TX_TOTTEXREQ (TX_TOTDISCARDTEXREQ + 1)
  153524. +#define TX_MEMREADCOUNT (TX_TOTTEXREQ + 1)
  153525. +#define TX_MEMREADIN8BCOUNT (TX_MEMREADCOUNT + 1)
  153526. +#define TX_CACHEMISSCOUNT (TX_MEMREADIN8BCOUNT + 1)
  153527. +#define TX_CACHEHITTEXELCOUNT (TX_CACHEMISSCOUNT + 1)
  153528. +#define TX_CACHEMISSTEXELCOUNT (TX_CACHEHITTEXELCOUNT + 1)
  153529. +
  153530. +#define PE_KILLEDBYCOLOR 1
  153531. +#define PE_KILLEDBYDEPTH (PE_KILLEDBYCOLOR + 1)
  153532. +#define PE_DRAWNBYCOLOR (PE_KILLEDBYDEPTH + 1)
  153533. +#define PE_DRAWNBYDEPTH (PE_DRAWNBYCOLOR + 1)
  153534. +
  153535. +#define MC_READREQ8BPIPE 1
  153536. +#define MC_READREQ8BIP (MC_READREQ8BPIPE + 1)
  153537. +#define MC_WRITEREQ8BPIPE (MC_READREQ8BIP + 1)
  153538. +
  153539. +#define AXI_READREQSTALLED 1
  153540. +#define AXI_WRITEREQSTALLED (AXI_READREQSTALLED + 1)
  153541. +#define AXI_WRITEDATASTALLED (AXI_WRITEREQSTALLED + 1)
  153542. +
  153543. +#define PVS_INSTRCOUNT 1
  153544. +#define PVS_ALUINSTRCOUNT (PVS_INSTRCOUNT + 1)
  153545. +#define PVS_TEXINSTRCOUNT (PVS_ALUINSTRCOUNT + 1)
  153546. +#define PVS_ATTRIBCOUNT (PVS_TEXINSTRCOUNT + 1)
  153547. +#define PVS_UNIFORMCOUNT (PVS_ATTRIBCOUNT + 1)
  153548. +#define PVS_FUNCTIONCOUNT (PVS_UNIFORMCOUNT + 1)
  153549. +#define PVS_SOURCE (PVS_FUNCTIONCOUNT + 1)
  153550. +
  153551. +#define PPS_INSTRCOUNT 1
  153552. +#define PPS_ALUINSTRCOUNT (PPS_INSTRCOUNT + 1)
  153553. +#define PPS_TEXINSTRCOUNT (PPS_ALUINSTRCOUNT + 1)
  153554. +#define PPS_ATTRIBCOUNT (PPS_TEXINSTRCOUNT + 1)
  153555. +#define PPS_UNIFORMCOUNT (PPS_ATTRIBCOUNT + 1)
  153556. +#define PPS_FUNCTIONCOUNT (PPS_UNIFORMCOUNT + 1)
  153557. +#define PPS_SOURCE (PPS_FUNCTIONCOUNT + 1)
  153558. +/* End of MISC Counter IDs. */
  153559. +
  153560. +#ifdef gcdNEW_PROFILER_FILE
  153561. +
  153562. +/* Category Constants. */
  153563. +#define VPHEADER 0x010000
  153564. +#define VPG_INFO 0x020000
  153565. +#define VPG_TIME 0x030000
  153566. +#define VPG_MEM 0x040000
  153567. +#define VPG_ES11 0x050000
  153568. +#define VPG_ES20 0x060000
  153569. +#define VPG_VG11 0x070000
  153570. +#define VPG_HAL 0x080000
  153571. +#define VPG_HW 0x090000
  153572. +#define VPG_GPU 0x0a0000
  153573. +#define VPG_VS 0x0b0000
  153574. +#define VPG_PS 0x0c0000
  153575. +#define VPG_PA 0x0d0000
  153576. +#define VPG_SETUP 0x0e0000
  153577. +#define VPG_RA 0x0f0000
  153578. +#define VPG_TX 0x100000
  153579. +#define VPG_PE 0x110000
  153580. +#define VPG_MC 0x120000
  153581. +#define VPG_AXI 0x130000
  153582. +#define VPG_PROG 0x140000
  153583. +#define VPG_PVS 0x150000
  153584. +#define VPG_PPS 0x160000
  153585. +#define VPG_ES11_TIME 0x170000
  153586. +#define VPG_ES20_TIME 0x180000
  153587. +#define VPG_FRAME 0x190000
  153588. +#define VPG_ES11_DRAW 0x200000
  153589. +#define VPG_ES20_DRAW 0x210000
  153590. +#define VPG_END 0xff0000
  153591. +
  153592. +/* Info. */
  153593. +#define VPC_INFOCOMPANY (VPG_INFO + 1)
  153594. +#define VPC_INFOVERSION (VPC_INFOCOMPANY + 1)
  153595. +#define VPC_INFORENDERER (VPC_INFOVERSION + 1)
  153596. +#define VPC_INFOREVISION (VPC_INFORENDERER + 1)
  153597. +#define VPC_INFODRIVER (VPC_INFOREVISION + 1)
  153598. +#define VPC_INFODRIVERMODE (VPC_INFODRIVER + 1)
  153599. +#define VPC_INFOSCREENSIZE (VPC_INFODRIVERMODE + 1)
  153600. +
  153601. +/* Counter Constants. */
  153602. +#define VPC_ELAPSETIME (VPG_TIME + 1)
  153603. +#define VPC_CPUTIME (VPC_ELAPSETIME + 1)
  153604. +
  153605. +#define VPC_MEMMAXRES (VPG_MEM + 1)
  153606. +#define VPC_MEMSHARED (VPC_MEMMAXRES + 1)
  153607. +#define VPC_MEMUNSHAREDDATA (VPC_MEMSHARED + 1)
  153608. +#define VPC_MEMUNSHAREDSTACK (VPC_MEMUNSHAREDDATA + 1)
  153609. +
  153610. +/* OpenGL ES11 Statics Counter IDs. */
  153611. +#define VPC_ES11CALLS (VPG_ES11 + ES11_CALLS)
  153612. +#define VPC_ES11DRAWCALLS (VPG_ES11 + ES11_DRAWCALLS)
  153613. +#define VPC_ES11STATECHANGECALLS (VPG_ES11 + ES11_STATECHANGECALLS)
  153614. +#define VPC_ES11POINTCOUNT (VPG_ES11 + ES11_POINTCOUNT)
  153615. +#define VPC_ES11LINECOUNT (VPG_ES11 + ES11_LINECOUNT)
  153616. +#define VPC_ES11TRIANGLECOUNT (VPG_ES11 + ES11_TRIANGLECOUNT)
  153617. +
  153618. +/* OpenGL ES20 Statistics Counter IDs. */
  153619. +#define VPC_ES20CALLS (VPG_ES20 + ES20_CALLS)
  153620. +#define VPC_ES20DRAWCALLS (VPG_ES20 + ES20_DRAWCALLS)
  153621. +#define VPC_ES20STATECHANGECALLS (VPG_ES20 + ES20_STATECHANGECALLS)
  153622. +#define VPC_ES20POINTCOUNT (VPG_ES20 + ES20_POINTCOUNT)
  153623. +#define VPC_ES20LINECOUNT (VPG_ES20 + ES20_LINECOUNT)
  153624. +#define VPC_ES20TRIANGLECOUNT (VPG_ES20 + ES20_TRIANGLECOUNT)
  153625. +
  153626. +/* OpenVG Statistics Counter IDs. */
  153627. +#define VPC_VG11CALLS (VPG_VG11 + VG11_CALLS)
  153628. +#define VPC_VG11DRAWCALLS (VPG_VG11 + VG11_DRAWCALLS)
  153629. +#define VPC_VG11STATECHANGECALLS (VPG_VG11 + VG11_STATECHANGECALLS)
  153630. +#define VPC_VG11FILLCOUNT (VPG_VG11 + VG11_FILLCOUNT)
  153631. +#define VPC_VG11STROKECOUNT (VPG_VG11 + VG11_STROKECOUNT)
  153632. +
  153633. +/* HAL Counters. */
  153634. +#define VPC_HALVERTBUFNEWBYTEALLOC (VPG_HAL + HAL_VERTBUFNEWBYTEALLOC)
  153635. +#define VPC_HALVERTBUFTOTALBYTEALLOC (VPG_HAL + HAL_VERTBUFTOTALBYTEALLOC)
  153636. +#define VPC_HALVERTBUFNEWOBJALLOC (VPG_HAL + HAL_VERTBUFNEWOBJALLOC)
  153637. +#define VPC_HALVERTBUFTOTALOBJALLOC (VPG_HAL + HAL_VERTBUFTOTALOBJALLOC)
  153638. +#define VPC_HALINDBUFNEWBYTEALLOC (VPG_HAL + HAL_INDBUFNEWBYTEALLOC)
  153639. +#define VPC_HALINDBUFTOTALBYTEALLOC (VPG_HAL + HAL_INDBUFTOTALBYTEALLOC)
  153640. +#define VPC_HALINDBUFNEWOBJALLOC (VPG_HAL + HAL_INDBUFNEWOBJALLOC)
  153641. +#define VPC_HALINDBUFTOTALOBJALLOC (VPG_HAL + HAL_INDBUFTOTALOBJALLOC)
  153642. +#define VPC_HALTEXBUFNEWBYTEALLOC (VPG_HAL + HAL_TEXBUFNEWBYTEALLOC)
  153643. +#define VPC_HALTEXBUFTOTALBYTEALLOC (VPG_HAL + HAL_TEXBUFTOTALBYTEALLOC)
  153644. +#define VPC_HALTEXBUFNEWOBJALLOC (VPG_HAL + HAL_TEXBUFNEWOBJALLOC)
  153645. +#define VPC_HALTEXBUFTOTALOBJALLOC (VPG_HAL + HAL_TEXBUFTOTALOBJALLOC)
  153646. +
  153647. +/* HW: GPU Counters. */
  153648. +#define VPC_GPUCYCLES (VPG_GPU + GPU_CYCLES)
  153649. +#define VPC_GPUREAD64BYTE (VPG_GPU + GPU_READ64BYTE)
  153650. +#define VPC_GPUWRITE64BYTE (VPG_GPU + GPU_WRITE64BYTE)
  153651. +#define VPC_GPUTOTALCYCLES (VPG_GPU + GPU_TOTALCYCLES)
  153652. +#define VPC_GPUIDLECYCLES (VPG_GPU + GPU_IDLECYCLES)
  153653. +
  153654. +/* HW: Shader Counters. */
  153655. +#define VPC_VSINSTCOUNT (VPG_VS + VS_INSTCOUNT)
  153656. +#define VPC_VSBRANCHINSTCOUNT (VPG_VS + VS_BRANCHINSTCOUNT)
  153657. +#define VPC_VSTEXLDINSTCOUNT (VPG_VS + VS_TEXLDINSTCOUNT)
  153658. +#define VPC_VSRENDEREDVERTCOUNT (VPG_VS + VS_RENDEREDVERTCOUNT)
  153659. +/* HW: PS Count. */
  153660. +#define VPC_PSINSTCOUNT (VPG_PS + PS_INSTCOUNT)
  153661. +#define VPC_PSBRANCHINSTCOUNT (VPG_PS + PS_BRANCHINSTCOUNT)
  153662. +#define VPC_PSTEXLDINSTCOUNT (VPG_PS + PS_TEXLDINSTCOUNT)
  153663. +#define VPC_PSRENDEREDPIXCOUNT (VPG_PS + PS_RENDEREDPIXCOUNT)
  153664. +
  153665. +
  153666. +/* HW: PA Counters. */
  153667. +#define VPC_PAINVERTCOUNT (VPG_PA + PA_INVERTCOUNT)
  153668. +#define VPC_PAINPRIMCOUNT (VPG_PA + PA_INPRIMCOUNT)
  153669. +#define VPC_PAOUTPRIMCOUNT (VPG_PA + PA_OUTPRIMCOUNT)
  153670. +#define VPC_PADEPTHCLIPCOUNT (VPG_PA + PA_DEPTHCLIPCOUNT)
  153671. +#define VPC_PATRIVIALREJCOUNT (VPG_PA + PA_TRIVIALREJCOUNT)
  153672. +#define VPC_PACULLCOUNT (VPG_PA + PA_CULLCOUNT)
  153673. +
  153674. +/* HW: Setup Counters. */
  153675. +#define VPC_SETRIANGLECOUNT (VPG_SETUP + SE_TRIANGLECOUNT)
  153676. +#define VPC_SELINECOUNT (VPG_SETUP + SE_LINECOUNT)
  153677. +
  153678. +/* HW: RA Counters. */
  153679. +#define VPC_RAVALIDPIXCOUNT (VPG_RA + RA_VALIDPIXCOUNT)
  153680. +#define VPC_RATOTALQUADCOUNT (VPG_RA + RA_TOTALQUADCOUNT)
  153681. +#define VPC_RAVALIDQUADCOUNTEZ (VPG_RA + RA_VALIDQUADCOUNTEZ)
  153682. +#define VPC_RATOTALPRIMCOUNT (VPG_RA + RA_TOTALPRIMCOUNT)
  153683. +#define VPC_RAPIPECACHEMISSCOUNT (VPG_RA + RA_PIPECACHEMISSCOUNT)
  153684. +#define VPC_RAPREFCACHEMISSCOUNT (VPG_RA + RA_PREFCACHEMISSCOUNT)
  153685. +#define VPC_RAEEZCULLCOUNT (VPG_RA + RA_EEZCULLCOUNT)
  153686. +
  153687. +/* HW: TEX Counters. */
  153688. +#define VPC_TXTOTBILINEARREQ (VPG_TX + TX_TOTBILINEARREQ)
  153689. +#define VPC_TXTOTTRILINEARREQ (VPG_TX + TX_TOTTRILINEARREQ)
  153690. +#define VPC_TXTOTDISCARDTEXREQ (VPG_TX + TX_TOTDISCARDTEXREQ)
  153691. +#define VPC_TXTOTTEXREQ (VPG_TX + TX_TOTTEXREQ)
  153692. +#define VPC_TXMEMREADCOUNT (VPG_TX + TX_MEMREADCOUNT)
  153693. +#define VPC_TXMEMREADIN8BCOUNT (VPG_TX + TX_MEMREADIN8BCOUNT)
  153694. +#define VPC_TXCACHEMISSCOUNT (VPG_TX + TX_CACHEMISSCOUNT)
  153695. +#define VPC_TXCACHEHITTEXELCOUNT (VPG_TX + TX_CACHEHITTEXELCOUNT)
  153696. +#define VPC_TXCACHEMISSTEXELCOUNT (VPG_TX + TX_CACHEMISSTEXELCOUNT)
  153697. +
  153698. +/* HW: PE Counters. */
  153699. +#define VPC_PEKILLEDBYCOLOR (VPG_PE + PE_KILLEDBYCOLOR)
  153700. +#define VPC_PEKILLEDBYDEPTH (VPG_PE + PE_KILLEDBYDEPTH)
  153701. +#define VPC_PEDRAWNBYCOLOR (VPG_PE + PE_DRAWNBYCOLOR)
  153702. +#define VPC_PEDRAWNBYDEPTH (VPG_PE + PE_DRAWNBYDEPTH)
  153703. +
  153704. +/* HW: MC Counters. */
  153705. +#define VPC_MCREADREQ8BPIPE (VPG_MC + MC_READREQ8BPIPE)
  153706. +#define VPC_MCREADREQ8BIP (VPG_MC + MC_READREQ8BIP)
  153707. +#define VPC_MCWRITEREQ8BPIPE (VPG_MC + MC_WRITEREQ8BPIPE)
  153708. +
  153709. +/* HW: AXI Counters. */
  153710. +#define VPC_AXIREADREQSTALLED (VPG_AXI + AXI_READREQSTALLED)
  153711. +#define VPC_AXIWRITEREQSTALLED (VPG_AXI + AXI_WRITEREQSTALLED)
  153712. +#define VPC_AXIWRITEDATASTALLED (VPG_AXI + AXI_WRITEDATASTALLED)
  153713. +
  153714. +/* PROGRAM: Shader program counters. */
  153715. +#define VPC_PVSINSTRCOUNT (VPG_PVS + PVS_INSTRCOUNT)
  153716. +#define VPC_PVSALUINSTRCOUNT (VPG_PVS + PVS_ALUINSTRCOUNT)
  153717. +#define VPC_PVSTEXINSTRCOUNT (VPG_PVS + PVS_TEXINSTRCOUNT)
  153718. +#define VPC_PVSATTRIBCOUNT (VPG_PVS + PVS_ATTRIBCOUNT)
  153719. +#define VPC_PVSUNIFORMCOUNT (VPG_PVS + PVS_UNIFORMCOUNT)
  153720. +#define VPC_PVSFUNCTIONCOUNT (VPG_PVS + PVS_FUNCTIONCOUNT)
  153721. +#define VPC_PVSSOURCE (VPG_PVS + PVS_SOURCE)
  153722. +
  153723. +#define VPC_PPSINSTRCOUNT (VPG_PPS + PPS_INSTRCOUNT)
  153724. +#define VPC_PPSALUINSTRCOUNT (VPG_PPS + PPS_ALUINSTRCOUNT)
  153725. +#define VPC_PPSTEXINSTRCOUNT (VPG_PPS + PPS_TEXINSTRCOUNT)
  153726. +#define VPC_PPSATTRIBCOUNT (VPG_PPS + PPS_ATTRIBCOUNT)
  153727. +#define VPC_PPSUNIFORMCOUNT (VPG_PPS + PPS_UNIFORMCOUNT)
  153728. +#define VPC_PPSFUNCTIONCOUNT (VPG_PPS + PPS_FUNCTIONCOUNT)
  153729. +#define VPC_PPSSOURCE (VPG_PPS + PPS_SOURCE)
  153730. +
  153731. +#define VPC_PROGRAMHANDLE (VPG_PROG + 1)
  153732. +
  153733. +#define VPG_ES20_DRAW_NO (VPG_ES20_DRAW + 1)
  153734. +#define VPG_ES11_DRAW_NO (VPG_ES11_DRAW + 1)
  153735. +
  153736. +#define VPG_FRAME_USEVBO (VPG_FRAME + 1)
  153737. +
  153738. +#endif
  153739. +
  153740. +
  153741. +/* HW profile information. */
  153742. +typedef struct _gcsPROFILER_COUNTERS
  153743. +{
  153744. + /* HW static counters. */
  153745. + gctUINT32 gpuClock;
  153746. + gctUINT32 axiClock;
  153747. + gctUINT32 shaderClock;
  153748. +
  153749. + /* HW vairable counters. */
  153750. + gctUINT32 gpuClockStart;
  153751. + gctUINT32 gpuClockEnd;
  153752. +
  153753. + /* HW vairable counters. */
  153754. + gctUINT32 gpuCyclesCounter;
  153755. + gctUINT32 gpuTotalCyclesCounter;
  153756. + gctUINT32 gpuIdleCyclesCounter;
  153757. + gctUINT32 gpuTotalRead64BytesPerFrame;
  153758. + gctUINT32 gpuTotalWrite64BytesPerFrame;
  153759. +
  153760. + /* PE */
  153761. + gctUINT32 pe_pixel_count_killed_by_color_pipe;
  153762. + gctUINT32 pe_pixel_count_killed_by_depth_pipe;
  153763. + gctUINT32 pe_pixel_count_drawn_by_color_pipe;
  153764. + gctUINT32 pe_pixel_count_drawn_by_depth_pipe;
  153765. +
  153766. + /* SH */
  153767. + gctUINT32 ps_inst_counter;
  153768. + gctUINT32 rendered_pixel_counter;
  153769. + gctUINT32 vs_inst_counter;
  153770. + gctUINT32 rendered_vertice_counter;
  153771. + gctUINT32 vtx_branch_inst_counter;
  153772. + gctUINT32 vtx_texld_inst_counter;
  153773. + gctUINT32 pxl_branch_inst_counter;
  153774. + gctUINT32 pxl_texld_inst_counter;
  153775. +
  153776. + /* PA */
  153777. + gctUINT32 pa_input_vtx_counter;
  153778. + gctUINT32 pa_input_prim_counter;
  153779. + gctUINT32 pa_output_prim_counter;
  153780. + gctUINT32 pa_depth_clipped_counter;
  153781. + gctUINT32 pa_trivial_rejected_counter;
  153782. + gctUINT32 pa_culled_counter;
  153783. +
  153784. + /* SE */
  153785. + gctUINT32 se_culled_triangle_count;
  153786. + gctUINT32 se_culled_lines_count;
  153787. +
  153788. + /* RA */
  153789. + gctUINT32 ra_valid_pixel_count;
  153790. + gctUINT32 ra_total_quad_count;
  153791. + gctUINT32 ra_valid_quad_count_after_early_z;
  153792. + gctUINT32 ra_total_primitive_count;
  153793. + gctUINT32 ra_pipe_cache_miss_counter;
  153794. + gctUINT32 ra_prefetch_cache_miss_counter;
  153795. + gctUINT32 ra_eez_culled_counter;
  153796. +
  153797. + /* TX */
  153798. + gctUINT32 tx_total_bilinear_requests;
  153799. + gctUINT32 tx_total_trilinear_requests;
  153800. + gctUINT32 tx_total_discarded_texture_requests;
  153801. + gctUINT32 tx_total_texture_requests;
  153802. + gctUINT32 tx_mem_read_count;
  153803. + gctUINT32 tx_mem_read_in_8B_count;
  153804. + gctUINT32 tx_cache_miss_count;
  153805. + gctUINT32 tx_cache_hit_texel_count;
  153806. + gctUINT32 tx_cache_miss_texel_count;
  153807. +
  153808. + /* MC */
  153809. + gctUINT32 mc_total_read_req_8B_from_pipeline;
  153810. + gctUINT32 mc_total_read_req_8B_from_IP;
  153811. + gctUINT32 mc_total_write_req_8B_from_pipeline;
  153812. +
  153813. + /* HI */
  153814. + gctUINT32 hi_axi_cycles_read_request_stalled;
  153815. + gctUINT32 hi_axi_cycles_write_request_stalled;
  153816. + gctUINT32 hi_axi_cycles_write_data_stalled;
  153817. +}
  153818. +gcsPROFILER_COUNTERS;
  153819. +
  153820. +/* HAL profile information. */
  153821. +typedef struct _gcsPROFILER
  153822. +{
  153823. + gctUINT32 enable;
  153824. + gctBOOL enableHal;
  153825. + gctBOOL enableHW;
  153826. + gctBOOL enableSH;
  153827. + gctBOOL isSyncMode;
  153828. +
  153829. + gctBOOL useSocket;
  153830. + gctINT sockFd;
  153831. +
  153832. + gctFILE file;
  153833. +
  153834. + /* Aggregate Information */
  153835. +
  153836. + /* Clock Info */
  153837. + gctUINT64 frameStart;
  153838. + gctUINT64 frameEnd;
  153839. +
  153840. + /* Current frame information */
  153841. + gctUINT32 frameNumber;
  153842. + gctUINT64 frameStartTimeusec;
  153843. + gctUINT64 frameEndTimeusec;
  153844. + gctUINT64 frameStartCPUTimeusec;
  153845. + gctUINT64 frameEndCPUTimeusec;
  153846. +
  153847. +#if PROFILE_HAL_COUNTERS
  153848. + gctUINT32 vertexBufferTotalBytesAlloc;
  153849. + gctUINT32 vertexBufferNewBytesAlloc;
  153850. + int vertexBufferTotalObjectsAlloc;
  153851. + int vertexBufferNewObjectsAlloc;
  153852. +
  153853. + gctUINT32 indexBufferTotalBytesAlloc;
  153854. + gctUINT32 indexBufferNewBytesAlloc;
  153855. + int indexBufferTotalObjectsAlloc;
  153856. + int indexBufferNewObjectsAlloc;
  153857. +
  153858. + gctUINT32 textureBufferTotalBytesAlloc;
  153859. + gctUINT32 textureBufferNewBytesAlloc;
  153860. + int textureBufferTotalObjectsAlloc;
  153861. + int textureBufferNewObjectsAlloc;
  153862. +
  153863. + gctUINT32 numCommits;
  153864. + gctUINT32 drawPointCount;
  153865. + gctUINT32 drawLineCount;
  153866. + gctUINT32 drawTriangleCount;
  153867. + gctUINT32 drawVertexCount;
  153868. + gctUINT32 redundantStateChangeCalls;
  153869. +#endif
  153870. +
  153871. + gctUINT32 prevVSInstCount;
  153872. + gctUINT32 prevVSBranchInstCount;
  153873. + gctUINT32 prevVSTexInstCount;
  153874. + gctUINT32 prevVSVertexCount;
  153875. + gctUINT32 prevPSInstCount;
  153876. + gctUINT32 prevPSBranchInstCount;
  153877. + gctUINT32 prevPSTexInstCount;
  153878. + gctUINT32 prevPSPixelCount;
  153879. +
  153880. + char* psSource;
  153881. + char* vsSource;
  153882. +
  153883. +}
  153884. +gcsPROFILER;
  153885. +
  153886. +/* Memory profile information. */
  153887. +struct _gcsMemProfile
  153888. +{
  153889. + /* Memory Usage */
  153890. + gctUINT32 videoMemUsed;
  153891. + gctUINT32 systemMemUsed;
  153892. + gctUINT32 commitBufferSize;
  153893. + gctUINT32 contextBufferCopyBytes;
  153894. +};
  153895. +
  153896. +/* Shader profile information. */
  153897. +struct _gcsSHADER_PROFILER
  153898. +{
  153899. + gctUINT32 shaderLength;
  153900. + gctUINT32 shaderALUCycles;
  153901. + gctUINT32 shaderTexLoadCycles;
  153902. + gctUINT32 shaderTempRegCount;
  153903. + gctUINT32 shaderSamplerRegCount;
  153904. + gctUINT32 shaderInputRegCount;
  153905. + gctUINT32 shaderOutputRegCount;
  153906. +};
  153907. +
  153908. +/* Initialize the gcsProfiler. */
  153909. +gceSTATUS
  153910. +gcoPROFILER_Initialize(
  153911. + IN gcoHAL Hal
  153912. + );
  153913. +
  153914. +/* Destroy the gcProfiler. */
  153915. +gceSTATUS
  153916. +gcoPROFILER_Destroy(
  153917. + IN gcoHAL Hal
  153918. + );
  153919. +
  153920. +/* Write data to profiler. */
  153921. +gceSTATUS
  153922. +gcoPROFILER_Write(
  153923. + IN gcoHAL Hal,
  153924. + IN gctSIZE_T ByteCount,
  153925. + IN gctCONST_POINTER Data
  153926. + );
  153927. +
  153928. +/* Flush data out. */
  153929. +gceSTATUS
  153930. +gcoPROFILER_Flush(
  153931. + IN gcoHAL Hal
  153932. + );
  153933. +
  153934. +/* Call to signal end of frame. */
  153935. +gceSTATUS
  153936. +gcoPROFILER_EndFrame(
  153937. + IN gcoHAL Hal
  153938. + );
  153939. +
  153940. +/* Call to signal end of draw. */
  153941. +gceSTATUS
  153942. +gcoPROFILER_EndDraw(
  153943. + IN gcoHAL Hal,
  153944. + IN gctBOOL FirstDraw
  153945. + );
  153946. +
  153947. +/* Increase profile counter Enum by Value. */
  153948. +gceSTATUS
  153949. +gcoPROFILER_Count(
  153950. + IN gcoHAL Hal,
  153951. + IN gctUINT32 Enum,
  153952. + IN gctINT Value
  153953. + );
  153954. +
  153955. +gceSTATUS
  153956. +gcoPROFILER_ShaderSourceFS(
  153957. + IN gcoHAL Hal,
  153958. + IN char* source
  153959. + );
  153960. +
  153961. +gceSTATUS
  153962. +gcoPROFILER_ShaderSourceVS(
  153963. + IN gcoHAL Hal,
  153964. + IN char* source
  153965. + );
  153966. +
  153967. +/* Profile input vertex shader. */
  153968. +gceSTATUS
  153969. +gcoPROFILER_ShaderVS(
  153970. + IN gcoHAL Hal,
  153971. + IN gctPOINTER Vs
  153972. + );
  153973. +
  153974. +/* Profile input fragment shader. */
  153975. +gceSTATUS
  153976. +gcoPROFILER_ShaderFS(
  153977. + IN gcoHAL Hal,
  153978. + IN gctPOINTER Fs
  153979. + );
  153980. +
  153981. +#ifdef __cplusplus
  153982. +}
  153983. +#endif
  153984. +
  153985. +#endif /* __gc_hal_profiler_h_ */
  153986. diff -Nur linux-3.14.17/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
  153987. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h 1970-01-01 01:00:00.000000000 +0100
  153988. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h 2014-09-11 18:06:03.122042450 +0200
  153989. @@ -0,0 +1,1010 @@
  153990. +/****************************************************************************
  153991. +*
  153992. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  153993. +*
  153994. +* This program is free software; you can redistribute it and/or modify
  153995. +* it under the terms of the GNU General Public License as published by
  153996. +* the Free Software Foundation; either version 2 of the license, or
  153997. +* (at your option) any later version.
  153998. +*
  153999. +* This program is distributed in the hope that it will be useful,
  154000. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  154001. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  154002. +* GNU General Public License for more details.
  154003. +*
  154004. +* You should have received a copy of the GNU General Public License
  154005. +* along with this program; if not write to the Free Software
  154006. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  154007. +*
  154008. +*****************************************************************************/
  154009. +
  154010. +
  154011. +#ifndef __gc_hal_raster_h_
  154012. +#define __gc_hal_raster_h_
  154013. +
  154014. +#include "gc_hal_enum.h"
  154015. +#include "gc_hal_types.h"
  154016. +
  154017. +#ifdef __cplusplus
  154018. +extern "C" {
  154019. +#endif
  154020. +
  154021. +/******************************************************************************\
  154022. +****************************** Object Declarations *****************************
  154023. +\******************************************************************************/
  154024. +
  154025. +typedef struct _gcoBRUSH * gcoBRUSH;
  154026. +typedef struct _gcoBRUSH_CACHE * gcoBRUSH_CACHE;
  154027. +
  154028. +/******************************************************************************\
  154029. +******************************** gcoBRUSH Object *******************************
  154030. +\******************************************************************************/
  154031. +
  154032. +/* Create a new solid color gcoBRUSH object. */
  154033. +gceSTATUS
  154034. +gcoBRUSH_ConstructSingleColor(
  154035. + IN gcoHAL Hal,
  154036. + IN gctUINT32 ColorConvert,
  154037. + IN gctUINT32 Color,
  154038. + IN gctUINT64 Mask,
  154039. + gcoBRUSH * Brush
  154040. + );
  154041. +
  154042. +/* Create a new monochrome gcoBRUSH object. */
  154043. +gceSTATUS
  154044. +gcoBRUSH_ConstructMonochrome(
  154045. + IN gcoHAL Hal,
  154046. + IN gctUINT32 OriginX,
  154047. + IN gctUINT32 OriginY,
  154048. + IN gctUINT32 ColorConvert,
  154049. + IN gctUINT32 FgColor,
  154050. + IN gctUINT32 BgColor,
  154051. + IN gctUINT64 Bits,
  154052. + IN gctUINT64 Mask,
  154053. + gcoBRUSH * Brush
  154054. + );
  154055. +
  154056. +/* Create a color gcoBRUSH object. */
  154057. +gceSTATUS
  154058. +gcoBRUSH_ConstructColor(
  154059. + IN gcoHAL Hal,
  154060. + IN gctUINT32 OriginX,
  154061. + IN gctUINT32 OriginY,
  154062. + IN gctPOINTER Address,
  154063. + IN gceSURF_FORMAT Format,
  154064. + IN gctUINT64 Mask,
  154065. + gcoBRUSH * Brush
  154066. + );
  154067. +
  154068. +/* Destroy an gcoBRUSH object. */
  154069. +gceSTATUS
  154070. +gcoBRUSH_Destroy(
  154071. + IN gcoBRUSH Brush
  154072. + );
  154073. +
  154074. +/******************************************************************************\
  154075. +******************************** gcoSURF Object *******************************
  154076. +\******************************************************************************/
  154077. +
  154078. +/* Set cipping rectangle. */
  154079. +gceSTATUS
  154080. +gcoSURF_SetClipping(
  154081. + IN gcoSURF Surface
  154082. + );
  154083. +
  154084. +/* Clear one or more rectangular areas. */
  154085. +gceSTATUS
  154086. +gcoSURF_Clear2D(
  154087. + IN gcoSURF DestSurface,
  154088. + IN gctUINT32 RectCount,
  154089. + IN gcsRECT_PTR DestRect,
  154090. + IN gctUINT32 LoColor,
  154091. + IN gctUINT32 HiColor
  154092. + );
  154093. +
  154094. +/* Draw one or more Bresenham lines. */
  154095. +gceSTATUS
  154096. +gcoSURF_Line(
  154097. + IN gcoSURF Surface,
  154098. + IN gctUINT32 LineCount,
  154099. + IN gcsRECT_PTR Position,
  154100. + IN gcoBRUSH Brush,
  154101. + IN gctUINT8 FgRop,
  154102. + IN gctUINT8 BgRop
  154103. + );
  154104. +
  154105. +/* Generic rectangular blit. */
  154106. +gceSTATUS
  154107. +gcoSURF_Blit(
  154108. + IN OPTIONAL gcoSURF SrcSurface,
  154109. + IN gcoSURF DestSurface,
  154110. + IN gctUINT32 RectCount,
  154111. + IN OPTIONAL gcsRECT_PTR SrcRect,
  154112. + IN gcsRECT_PTR DestRect,
  154113. + IN OPTIONAL gcoBRUSH Brush,
  154114. + IN gctUINT8 FgRop,
  154115. + IN gctUINT8 BgRop,
  154116. + IN OPTIONAL gceSURF_TRANSPARENCY Transparency,
  154117. + IN OPTIONAL gctUINT32 TransparencyColor,
  154118. + IN OPTIONAL gctPOINTER Mask,
  154119. + IN OPTIONAL gceSURF_MONOPACK MaskPack
  154120. + );
  154121. +
  154122. +/* Monochrome blit. */
  154123. +gceSTATUS
  154124. +gcoSURF_MonoBlit(
  154125. + IN gcoSURF DestSurface,
  154126. + IN gctPOINTER Source,
  154127. + IN gceSURF_MONOPACK SourcePack,
  154128. + IN gcsPOINT_PTR SourceSize,
  154129. + IN gcsPOINT_PTR SourceOrigin,
  154130. + IN gcsRECT_PTR DestRect,
  154131. + IN OPTIONAL gcoBRUSH Brush,
  154132. + IN gctUINT8 FgRop,
  154133. + IN gctUINT8 BgRop,
  154134. + IN gctBOOL ColorConvert,
  154135. + IN gctUINT8 MonoTransparency,
  154136. + IN gceSURF_TRANSPARENCY Transparency,
  154137. + IN gctUINT32 FgColor,
  154138. + IN gctUINT32 BgColor
  154139. + );
  154140. +
  154141. +/* Filter blit. */
  154142. +gceSTATUS
  154143. +gcoSURF_FilterBlit(
  154144. + IN gcoSURF SrcSurface,
  154145. + IN gcoSURF DestSurface,
  154146. + IN gcsRECT_PTR SrcRect,
  154147. + IN gcsRECT_PTR DestRect,
  154148. + IN gcsRECT_PTR DestSubRect
  154149. + );
  154150. +
  154151. +/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
  154152. +gceSTATUS
  154153. +gcoSURF_EnableAlphaBlend(
  154154. + IN gcoSURF Surface,
  154155. + IN gctUINT8 SrcGlobalAlphaValue,
  154156. + IN gctUINT8 DstGlobalAlphaValue,
  154157. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  154158. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  154159. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  154160. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  154161. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  154162. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
  154163. + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
  154164. + IN gceSURF_PIXEL_COLOR_MODE DstColorMode
  154165. + );
  154166. +
  154167. +/* Disable alpha blending engine in the hardware and engage the ROP engine. */
  154168. +gceSTATUS
  154169. +gcoSURF_DisableAlphaBlend(
  154170. + IN gcoSURF Surface
  154171. + );
  154172. +
  154173. +/* Copy a rectangular area with format conversion. */
  154174. +gceSTATUS
  154175. +gcoSURF_CopyPixels(
  154176. + IN gcoSURF Source,
  154177. + IN gcoSURF Target,
  154178. + IN gctINT SourceX,
  154179. + IN gctINT SourceY,
  154180. + IN gctINT TargetX,
  154181. + IN gctINT TargetY,
  154182. + IN gctINT Width,
  154183. + IN gctINT Height
  154184. + );
  154185. +
  154186. +/* Read surface pixel. */
  154187. +gceSTATUS
  154188. +gcoSURF_ReadPixel(
  154189. + IN gcoSURF Surface,
  154190. + IN gctPOINTER Memory,
  154191. + IN gctINT X,
  154192. + IN gctINT Y,
  154193. + IN gceSURF_FORMAT Format,
  154194. + OUT gctPOINTER PixelValue
  154195. + );
  154196. +
  154197. +/* Write surface pixel. */
  154198. +gceSTATUS
  154199. +gcoSURF_WritePixel(
  154200. + IN gcoSURF Surface,
  154201. + IN gctPOINTER Memory,
  154202. + IN gctINT X,
  154203. + IN gctINT Y,
  154204. + IN gceSURF_FORMAT Format,
  154205. + IN gctPOINTER PixelValue
  154206. + );
  154207. +
  154208. +gceSTATUS
  154209. +gcoSURF_SetDither(
  154210. + IN gcoSURF Surface,
  154211. + IN gctBOOL Dither
  154212. + );
  154213. +/******************************************************************************\
  154214. +********************************** gco2D Object *********************************
  154215. +\******************************************************************************/
  154216. +
  154217. +/* Construct a new gco2D object. */
  154218. +gceSTATUS
  154219. +gco2D_Construct(
  154220. + IN gcoHAL Hal,
  154221. + OUT gco2D * Hardware
  154222. + );
  154223. +
  154224. +/* Destroy an gco2D object. */
  154225. +gceSTATUS
  154226. +gco2D_Destroy(
  154227. + IN gco2D Hardware
  154228. + );
  154229. +
  154230. +/* Sets the maximum number of brushes in the brush cache. */
  154231. +gceSTATUS
  154232. +gco2D_SetBrushLimit(
  154233. + IN gco2D Hardware,
  154234. + IN gctUINT MaxCount
  154235. + );
  154236. +
  154237. +/* Flush the brush. */
  154238. +gceSTATUS
  154239. +gco2D_FlushBrush(
  154240. + IN gco2D Engine,
  154241. + IN gcoBRUSH Brush,
  154242. + IN gceSURF_FORMAT Format
  154243. + );
  154244. +
  154245. +/* Program the specified solid color brush. */
  154246. +gceSTATUS
  154247. +gco2D_LoadSolidBrush(
  154248. + IN gco2D Engine,
  154249. + IN gceSURF_FORMAT Format,
  154250. + IN gctUINT32 ColorConvert,
  154251. + IN gctUINT32 Color,
  154252. + IN gctUINT64 Mask
  154253. + );
  154254. +
  154255. +gceSTATUS
  154256. +gco2D_LoadMonochromeBrush(
  154257. + IN gco2D Engine,
  154258. + IN gctUINT32 OriginX,
  154259. + IN gctUINT32 OriginY,
  154260. + IN gctUINT32 ColorConvert,
  154261. + IN gctUINT32 FgColor,
  154262. + IN gctUINT32 BgColor,
  154263. + IN gctUINT64 Bits,
  154264. + IN gctUINT64 Mask
  154265. + );
  154266. +
  154267. +gceSTATUS
  154268. +gco2D_LoadColorBrush(
  154269. + IN gco2D Engine,
  154270. + IN gctUINT32 OriginX,
  154271. + IN gctUINT32 OriginY,
  154272. + IN gctUINT32 Address,
  154273. + IN gceSURF_FORMAT Format,
  154274. + IN gctUINT64 Mask
  154275. + );
  154276. +
  154277. +/* Configure monochrome source. */
  154278. +gceSTATUS
  154279. +gco2D_SetMonochromeSource(
  154280. + IN gco2D Engine,
  154281. + IN gctBOOL ColorConvert,
  154282. + IN gctUINT8 MonoTransparency,
  154283. + IN gceSURF_MONOPACK DataPack,
  154284. + IN gctBOOL CoordRelative,
  154285. + IN gceSURF_TRANSPARENCY Transparency,
  154286. + IN gctUINT32 FgColor,
  154287. + IN gctUINT32 BgColor
  154288. + );
  154289. +
  154290. +/* Configure color source. */
  154291. +gceSTATUS
  154292. +gco2D_SetColorSource(
  154293. + IN gco2D Engine,
  154294. + IN gctUINT32 Address,
  154295. + IN gctUINT32 Stride,
  154296. + IN gceSURF_FORMAT Format,
  154297. + IN gceSURF_ROTATION Rotation,
  154298. + IN gctUINT32 SurfaceWidth,
  154299. + IN gctBOOL CoordRelative,
  154300. + IN gceSURF_TRANSPARENCY Transparency,
  154301. + IN gctUINT32 TransparencyColor
  154302. + );
  154303. +
  154304. +/* Configure color source extension for full rotation. */
  154305. +gceSTATUS
  154306. +gco2D_SetColorSourceEx(
  154307. + IN gco2D Engine,
  154308. + IN gctUINT32 Address,
  154309. + IN gctUINT32 Stride,
  154310. + IN gceSURF_FORMAT Format,
  154311. + IN gceSURF_ROTATION Rotation,
  154312. + IN gctUINT32 SurfaceWidth,
  154313. + IN gctUINT32 SurfaceHeight,
  154314. + IN gctBOOL CoordRelative,
  154315. + IN gceSURF_TRANSPARENCY Transparency,
  154316. + IN gctUINT32 TransparencyColor
  154317. + );
  154318. +
  154319. +/* Configure color source. */
  154320. +gceSTATUS
  154321. +gco2D_SetColorSourceAdvanced(
  154322. + IN gco2D Engine,
  154323. + IN gctUINT32 Address,
  154324. + IN gctUINT32 Stride,
  154325. + IN gceSURF_FORMAT Format,
  154326. + IN gceSURF_ROTATION Rotation,
  154327. + IN gctUINT32 SurfaceWidth,
  154328. + IN gctUINT32 SurfaceHeight,
  154329. + IN gctBOOL CoordRelative
  154330. + );
  154331. +
  154332. +gceSTATUS
  154333. +gco2D_SetColorSourceN(
  154334. + IN gco2D Engine,
  154335. + IN gctUINT32 Address,
  154336. + IN gctUINT32 Stride,
  154337. + IN gceSURF_FORMAT Format,
  154338. + IN gceSURF_ROTATION Rotation,
  154339. + IN gctUINT32 SurfaceWidth,
  154340. + IN gctUINT32 SurfaceHeight,
  154341. + IN gctUINT32 SurfaceNumber
  154342. + );
  154343. +
  154344. +/* Configure masked color source. */
  154345. +gceSTATUS
  154346. +gco2D_SetMaskedSource(
  154347. + IN gco2D Engine,
  154348. + IN gctUINT32 Address,
  154349. + IN gctUINT32 Stride,
  154350. + IN gceSURF_FORMAT Format,
  154351. + IN gctBOOL CoordRelative,
  154352. + IN gceSURF_MONOPACK MaskPack
  154353. + );
  154354. +
  154355. +/* Configure masked color source extension for full rotation. */
  154356. +gceSTATUS
  154357. +gco2D_SetMaskedSourceEx(
  154358. + IN gco2D Engine,
  154359. + IN gctUINT32 Address,
  154360. + IN gctUINT32 Stride,
  154361. + IN gceSURF_FORMAT Format,
  154362. + IN gctBOOL CoordRelative,
  154363. + IN gceSURF_MONOPACK MaskPack,
  154364. + IN gceSURF_ROTATION Rotation,
  154365. + IN gctUINT32 SurfaceWidth,
  154366. + IN gctUINT32 SurfaceHeight
  154367. + );
  154368. +
  154369. +/* Setup the source rectangle. */
  154370. +gceSTATUS
  154371. +gco2D_SetSource(
  154372. + IN gco2D Engine,
  154373. + IN gcsRECT_PTR SrcRect
  154374. + );
  154375. +
  154376. +/* Set clipping rectangle. */
  154377. +gceSTATUS
  154378. +gco2D_SetClipping(
  154379. + IN gco2D Engine,
  154380. + IN gcsRECT_PTR Rect
  154381. + );
  154382. +
  154383. +/* Configure destination. */
  154384. +gceSTATUS
  154385. +gco2D_SetTarget(
  154386. + IN gco2D Engine,
  154387. + IN gctUINT32 Address,
  154388. + IN gctUINT32 Stride,
  154389. + IN gceSURF_ROTATION Rotation,
  154390. + IN gctUINT32 SurfaceWidth
  154391. + );
  154392. +
  154393. +/* Configure destination extension for full rotation. */
  154394. +gceSTATUS
  154395. +gco2D_SetTargetEx(
  154396. + IN gco2D Engine,
  154397. + IN gctUINT32 Address,
  154398. + IN gctUINT32 Stride,
  154399. + IN gceSURF_ROTATION Rotation,
  154400. + IN gctUINT32 SurfaceWidth,
  154401. + IN gctUINT32 SurfaceHeight
  154402. + );
  154403. +
  154404. +/* Calculate and program the stretch factors. */
  154405. +gceSTATUS
  154406. +gco2D_CalcStretchFactor(
  154407. + IN gco2D Engine,
  154408. + IN gctINT32 SrcSize,
  154409. + IN gctINT32 DestSize,
  154410. + OUT gctUINT32_PTR Factor
  154411. + );
  154412. +
  154413. +gceSTATUS
  154414. +gco2D_SetStretchFactors(
  154415. + IN gco2D Engine,
  154416. + IN gctUINT32 HorFactor,
  154417. + IN gctUINT32 VerFactor
  154418. + );
  154419. +
  154420. +/* Calculate and program the stretch factors based on the rectangles. */
  154421. +gceSTATUS
  154422. +gco2D_SetStretchRectFactors(
  154423. + IN gco2D Engine,
  154424. + IN gcsRECT_PTR SrcRect,
  154425. + IN gcsRECT_PTR DestRect
  154426. + );
  154427. +
  154428. +/* Create a new solid color gcoBRUSH object. */
  154429. +gceSTATUS
  154430. +gco2D_ConstructSingleColorBrush(
  154431. + IN gco2D Engine,
  154432. + IN gctUINT32 ColorConvert,
  154433. + IN gctUINT32 Color,
  154434. + IN gctUINT64 Mask,
  154435. + gcoBRUSH * Brush
  154436. + );
  154437. +
  154438. +/* Create a new monochrome gcoBRUSH object. */
  154439. +gceSTATUS
  154440. +gco2D_ConstructMonochromeBrush(
  154441. + IN gco2D Engine,
  154442. + IN gctUINT32 OriginX,
  154443. + IN gctUINT32 OriginY,
  154444. + IN gctUINT32 ColorConvert,
  154445. + IN gctUINT32 FgColor,
  154446. + IN gctUINT32 BgColor,
  154447. + IN gctUINT64 Bits,
  154448. + IN gctUINT64 Mask,
  154449. + gcoBRUSH * Brush
  154450. + );
  154451. +
  154452. +/* Create a color gcoBRUSH object. */
  154453. +gceSTATUS
  154454. +gco2D_ConstructColorBrush(
  154455. + IN gco2D Engine,
  154456. + IN gctUINT32 OriginX,
  154457. + IN gctUINT32 OriginY,
  154458. + IN gctPOINTER Address,
  154459. + IN gceSURF_FORMAT Format,
  154460. + IN gctUINT64 Mask,
  154461. + gcoBRUSH * Brush
  154462. + );
  154463. +
  154464. +/* Clear one or more rectangular areas. */
  154465. +gceSTATUS
  154466. +gco2D_Clear(
  154467. + IN gco2D Engine,
  154468. + IN gctUINT32 RectCount,
  154469. + IN gcsRECT_PTR Rect,
  154470. + IN gctUINT32 Color32,
  154471. + IN gctUINT8 FgRop,
  154472. + IN gctUINT8 BgRop,
  154473. + IN gceSURF_FORMAT DestFormat
  154474. + );
  154475. +
  154476. +/* Draw one or more Bresenham lines. */
  154477. +gceSTATUS
  154478. +gco2D_Line(
  154479. + IN gco2D Engine,
  154480. + IN gctUINT32 LineCount,
  154481. + IN gcsRECT_PTR Position,
  154482. + IN gcoBRUSH Brush,
  154483. + IN gctUINT8 FgRop,
  154484. + IN gctUINT8 BgRop,
  154485. + IN gceSURF_FORMAT DestFormat
  154486. + );
  154487. +
  154488. +/* Draw one or more Bresenham lines based on the 32-bit color. */
  154489. +gceSTATUS
  154490. +gco2D_ColorLine(
  154491. + IN gco2D Engine,
  154492. + IN gctUINT32 LineCount,
  154493. + IN gcsRECT_PTR Position,
  154494. + IN gctUINT32 Color32,
  154495. + IN gctUINT8 FgRop,
  154496. + IN gctUINT8 BgRop,
  154497. + IN gceSURF_FORMAT DestFormat
  154498. + );
  154499. +
  154500. +/* Generic blit. */
  154501. +gceSTATUS
  154502. +gco2D_Blit(
  154503. + IN gco2D Engine,
  154504. + IN gctUINT32 RectCount,
  154505. + IN gcsRECT_PTR Rect,
  154506. + IN gctUINT8 FgRop,
  154507. + IN gctUINT8 BgRop,
  154508. + IN gceSURF_FORMAT DestFormat
  154509. + );
  154510. +
  154511. +gceSTATUS
  154512. +gco2D_Blend(
  154513. + IN gco2D Engine,
  154514. + IN gctUINT32 SrcCount,
  154515. + IN gctUINT32 RectCount,
  154516. + IN gcsRECT_PTR Rect,
  154517. + IN gctUINT8 FgRop,
  154518. + IN gctUINT8 BgRop,
  154519. + IN gceSURF_FORMAT DestFormat
  154520. + );
  154521. +
  154522. +/* Batch blit. */
  154523. +gceSTATUS
  154524. +gco2D_BatchBlit(
  154525. + IN gco2D Engine,
  154526. + IN gctUINT32 RectCount,
  154527. + IN gcsRECT_PTR SrcRect,
  154528. + IN gcsRECT_PTR DestRect,
  154529. + IN gctUINT8 FgRop,
  154530. + IN gctUINT8 BgRop,
  154531. + IN gceSURF_FORMAT DestFormat
  154532. + );
  154533. +
  154534. +/* Stretch blit. */
  154535. +gceSTATUS
  154536. +gco2D_StretchBlit(
  154537. + IN gco2D Engine,
  154538. + IN gctUINT32 RectCount,
  154539. + IN gcsRECT_PTR Rect,
  154540. + IN gctUINT8 FgRop,
  154541. + IN gctUINT8 BgRop,
  154542. + IN gceSURF_FORMAT DestFormat
  154543. + );
  154544. +
  154545. +/* Monochrome blit. */
  154546. +gceSTATUS
  154547. +gco2D_MonoBlit(
  154548. + IN gco2D Engine,
  154549. + IN gctPOINTER StreamBits,
  154550. + IN gcsPOINT_PTR StreamSize,
  154551. + IN gcsRECT_PTR StreamRect,
  154552. + IN gceSURF_MONOPACK SrcStreamPack,
  154553. + IN gceSURF_MONOPACK DestStreamPack,
  154554. + IN gcsRECT_PTR DestRect,
  154555. + IN gctUINT32 FgRop,
  154556. + IN gctUINT32 BgRop,
  154557. + IN gceSURF_FORMAT DestFormat
  154558. + );
  154559. +
  154560. +gceSTATUS
  154561. +gco2D_MonoBlitEx(
  154562. + IN gco2D Engine,
  154563. + IN gctPOINTER StreamBits,
  154564. + IN gctINT32 StreamStride,
  154565. + IN gctINT32 StreamWidth,
  154566. + IN gctINT32 StreamHeight,
  154567. + IN gctINT32 StreamX,
  154568. + IN gctINT32 StreamY,
  154569. + IN gctUINT32 FgColor,
  154570. + IN gctUINT32 BgColor,
  154571. + IN gcsRECT_PTR SrcRect,
  154572. + IN gcsRECT_PTR DstRect,
  154573. + IN gctUINT8 FgRop,
  154574. + IN gctUINT8 BgRop
  154575. + );
  154576. +
  154577. +/* Set kernel size. */
  154578. +gceSTATUS
  154579. +gco2D_SetKernelSize(
  154580. + IN gco2D Engine,
  154581. + IN gctUINT8 HorKernelSize,
  154582. + IN gctUINT8 VerKernelSize
  154583. + );
  154584. +
  154585. +/* Set filter type. */
  154586. +gceSTATUS
  154587. +gco2D_SetFilterType(
  154588. + IN gco2D Engine,
  154589. + IN gceFILTER_TYPE FilterType
  154590. + );
  154591. +
  154592. +/* Set the filter kernel by user. */
  154593. +gceSTATUS
  154594. +gco2D_SetUserFilterKernel(
  154595. + IN gco2D Engine,
  154596. + IN gceFILTER_PASS_TYPE PassType,
  154597. + IN gctUINT16_PTR KernelArray
  154598. + );
  154599. +
  154600. +/* Select the pass(es) to be done for user defined filter. */
  154601. +gceSTATUS
  154602. +gco2D_EnableUserFilterPasses(
  154603. + IN gco2D Engine,
  154604. + IN gctBOOL HorPass,
  154605. + IN gctBOOL VerPass
  154606. + );
  154607. +
  154608. +/* Frees the temporary buffer allocated by filter blit operation. */
  154609. +gceSTATUS
  154610. +gco2D_FreeFilterBuffer(
  154611. + IN gco2D Engine
  154612. + );
  154613. +
  154614. +/* Filter blit. */
  154615. +gceSTATUS
  154616. +gco2D_FilterBlit(
  154617. + IN gco2D Engine,
  154618. + IN gctUINT32 SrcAddress,
  154619. + IN gctUINT SrcStride,
  154620. + IN gctUINT32 SrcUAddress,
  154621. + IN gctUINT SrcUStride,
  154622. + IN gctUINT32 SrcVAddress,
  154623. + IN gctUINT SrcVStride,
  154624. + IN gceSURF_FORMAT SrcFormat,
  154625. + IN gceSURF_ROTATION SrcRotation,
  154626. + IN gctUINT32 SrcSurfaceWidth,
  154627. + IN gcsRECT_PTR SrcRect,
  154628. + IN gctUINT32 DestAddress,
  154629. + IN gctUINT DestStride,
  154630. + IN gceSURF_FORMAT DestFormat,
  154631. + IN gceSURF_ROTATION DestRotation,
  154632. + IN gctUINT32 DestSurfaceWidth,
  154633. + IN gcsRECT_PTR DestRect,
  154634. + IN gcsRECT_PTR DestSubRect
  154635. + );
  154636. +
  154637. +/* Filter blit extension for full rotation. */
  154638. +gceSTATUS
  154639. +gco2D_FilterBlitEx(
  154640. + IN gco2D Engine,
  154641. + IN gctUINT32 SrcAddress,
  154642. + IN gctUINT SrcStride,
  154643. + IN gctUINT32 SrcUAddress,
  154644. + IN gctUINT SrcUStride,
  154645. + IN gctUINT32 SrcVAddress,
  154646. + IN gctUINT SrcVStride,
  154647. + IN gceSURF_FORMAT SrcFormat,
  154648. + IN gceSURF_ROTATION SrcRotation,
  154649. + IN gctUINT32 SrcSurfaceWidth,
  154650. + IN gctUINT32 SrcSurfaceHeight,
  154651. + IN gcsRECT_PTR SrcRect,
  154652. + IN gctUINT32 DestAddress,
  154653. + IN gctUINT DestStride,
  154654. + IN gceSURF_FORMAT DestFormat,
  154655. + IN gceSURF_ROTATION DestRotation,
  154656. + IN gctUINT32 DestSurfaceWidth,
  154657. + IN gctUINT32 DestSurfaceHeight,
  154658. + IN gcsRECT_PTR DestRect,
  154659. + IN gcsRECT_PTR DestSubRect
  154660. + );
  154661. +
  154662. +gceSTATUS
  154663. +gco2D_FilterBlitEx2(
  154664. + IN gco2D Engine,
  154665. + IN gctUINT32_PTR SrcAddresses,
  154666. + IN gctUINT32 SrcAddressNum,
  154667. + IN gctUINT32_PTR SrcStrides,
  154668. + IN gctUINT32 SrcStrideNum,
  154669. + IN gceTILING SrcTiling,
  154670. + IN gceSURF_FORMAT SrcFormat,
  154671. + IN gceSURF_ROTATION SrcRotation,
  154672. + IN gctUINT32 SrcSurfaceWidth,
  154673. + IN gctUINT32 SrcSurfaceHeight,
  154674. + IN gcsRECT_PTR SrcRect,
  154675. + IN gctUINT32_PTR DestAddresses,
  154676. + IN gctUINT32 DestAddressNum,
  154677. + IN gctUINT32_PTR DestStrides,
  154678. + IN gctUINT32 DestStrideNum,
  154679. + IN gceTILING DestTiling,
  154680. + IN gceSURF_FORMAT DestFormat,
  154681. + IN gceSURF_ROTATION DestRotation,
  154682. + IN gctUINT32 DestSurfaceWidth,
  154683. + IN gctUINT32 DestSurfaceHeight,
  154684. + IN gcsRECT_PTR DestRect,
  154685. + IN gcsRECT_PTR DestSubRect
  154686. + );
  154687. +
  154688. +/* Enable alpha blending engine in the hardware and disengage the ROP engine. */
  154689. +gceSTATUS
  154690. +gco2D_EnableAlphaBlend(
  154691. + IN gco2D Engine,
  154692. + IN gctUINT8 SrcGlobalAlphaValue,
  154693. + IN gctUINT8 DstGlobalAlphaValue,
  154694. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  154695. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  154696. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  154697. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  154698. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  154699. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode,
  154700. + IN gceSURF_PIXEL_COLOR_MODE SrcColorMode,
  154701. + IN gceSURF_PIXEL_COLOR_MODE DstColorMode
  154702. + );
  154703. +
  154704. +/* Enable alpha blending engine in the hardware. */
  154705. +gceSTATUS
  154706. +gco2D_EnableAlphaBlendAdvanced(
  154707. + IN gco2D Engine,
  154708. + IN gceSURF_PIXEL_ALPHA_MODE SrcAlphaMode,
  154709. + IN gceSURF_PIXEL_ALPHA_MODE DstAlphaMode,
  154710. + IN gceSURF_GLOBAL_ALPHA_MODE SrcGlobalAlphaMode,
  154711. + IN gceSURF_GLOBAL_ALPHA_MODE DstGlobalAlphaMode,
  154712. + IN gceSURF_BLEND_FACTOR_MODE SrcFactorMode,
  154713. + IN gceSURF_BLEND_FACTOR_MODE DstFactorMode
  154714. + );
  154715. +
  154716. +/* Enable alpha blending engine with Porter Duff rule. */
  154717. +gceSTATUS
  154718. +gco2D_SetPorterDuffBlending(
  154719. + IN gco2D Engine,
  154720. + IN gce2D_PORTER_DUFF_RULE Rule
  154721. + );
  154722. +
  154723. +/* Disable alpha blending engine in the hardware and engage the ROP engine. */
  154724. +gceSTATUS
  154725. +gco2D_DisableAlphaBlend(
  154726. + IN gco2D Engine
  154727. + );
  154728. +
  154729. +/* Retrieve the maximum number of 32-bit data chunks for a single DE command. */
  154730. +gctUINT32
  154731. +gco2D_GetMaximumDataCount(
  154732. + void
  154733. + );
  154734. +
  154735. +/* Retrieve the maximum number of rectangles, that can be passed in a single DE command. */
  154736. +gctUINT32
  154737. +gco2D_GetMaximumRectCount(
  154738. + void
  154739. + );
  154740. +
  154741. +/* Returns the pixel alignment of the surface. */
  154742. +gceSTATUS
  154743. +gco2D_GetPixelAlignment(
  154744. + gceSURF_FORMAT Format,
  154745. + gcsPOINT_PTR Alignment
  154746. + );
  154747. +
  154748. +/* Retrieve monochrome stream pack size. */
  154749. +gceSTATUS
  154750. +gco2D_GetPackSize(
  154751. + IN gceSURF_MONOPACK StreamPack,
  154752. + OUT gctUINT32 * PackWidth,
  154753. + OUT gctUINT32 * PackHeight
  154754. + );
  154755. +
  154756. +/* Flush the 2D pipeline. */
  154757. +gceSTATUS
  154758. +gco2D_Flush(
  154759. + IN gco2D Engine
  154760. + );
  154761. +
  154762. +/* Load 256-entry color table for INDEX8 source surfaces. */
  154763. +gceSTATUS
  154764. +gco2D_LoadPalette(
  154765. + IN gco2D Engine,
  154766. + IN gctUINT FirstIndex,
  154767. + IN gctUINT IndexCount,
  154768. + IN gctPOINTER ColorTable,
  154769. + IN gctBOOL ColorConvert
  154770. + );
  154771. +
  154772. +/* Enable/disable 2D BitBlt mirrorring. */
  154773. +gceSTATUS
  154774. +gco2D_SetBitBlitMirror(
  154775. + IN gco2D Engine,
  154776. + IN gctBOOL HorizontalMirror,
  154777. + IN gctBOOL VerticalMirror
  154778. + );
  154779. +
  154780. +/*
  154781. + * Set the transparency for source, destination and pattern.
  154782. + * It also enable or disable the DFB color key mode.
  154783. + */
  154784. +gceSTATUS
  154785. +gco2D_SetTransparencyAdvancedEx(
  154786. + IN gco2D Engine,
  154787. + IN gce2D_TRANSPARENCY SrcTransparency,
  154788. + IN gce2D_TRANSPARENCY DstTransparency,
  154789. + IN gce2D_TRANSPARENCY PatTransparency,
  154790. + IN gctBOOL EnableDFBColorKeyMode
  154791. + );
  154792. +
  154793. +/* Set the transparency for source, destination and pattern. */
  154794. +gceSTATUS
  154795. +gco2D_SetTransparencyAdvanced(
  154796. + IN gco2D Engine,
  154797. + IN gce2D_TRANSPARENCY SrcTransparency,
  154798. + IN gce2D_TRANSPARENCY DstTransparency,
  154799. + IN gce2D_TRANSPARENCY PatTransparency
  154800. + );
  154801. +
  154802. +/* Set the source color key. */
  154803. +gceSTATUS
  154804. +gco2D_SetSourceColorKeyAdvanced(
  154805. + IN gco2D Engine,
  154806. + IN gctUINT32 ColorKey
  154807. + );
  154808. +
  154809. +/* Set the source color key range. */
  154810. +gceSTATUS
  154811. +gco2D_SetSourceColorKeyRangeAdvanced(
  154812. + IN gco2D Engine,
  154813. + IN gctUINT32 ColorKeyLow,
  154814. + IN gctUINT32 ColorKeyHigh
  154815. + );
  154816. +
  154817. +/* Set the target color key. */
  154818. +gceSTATUS
  154819. +gco2D_SetTargetColorKeyAdvanced(
  154820. + IN gco2D Engine,
  154821. + IN gctUINT32 ColorKey
  154822. + );
  154823. +
  154824. +/* Set the target color key range. */
  154825. +gceSTATUS
  154826. +gco2D_SetTargetColorKeyRangeAdvanced(
  154827. + IN gco2D Engine,
  154828. + IN gctUINT32 ColorKeyLow,
  154829. + IN gctUINT32 ColorKeyHigh
  154830. + );
  154831. +
  154832. +/* Set the YUV color space mode. */
  154833. +gceSTATUS
  154834. +gco2D_SetYUVColorMode(
  154835. + IN gco2D Engine,
  154836. + IN gce2D_YUV_COLOR_MODE Mode
  154837. + );
  154838. +
  154839. +/* Setup the source global color value in ARGB8 format. */
  154840. +gceSTATUS gco2D_SetSourceGlobalColorAdvanced(
  154841. + IN gco2D Engine,
  154842. + IN gctUINT32 Color32
  154843. + );
  154844. +
  154845. +/* Setup the target global color value in ARGB8 format. */
  154846. +gceSTATUS gco2D_SetTargetGlobalColorAdvanced(
  154847. + IN gco2D Engine,
  154848. + IN gctUINT32 Color32
  154849. + );
  154850. +
  154851. +/* Setup the source and target pixel multiply modes. */
  154852. +gceSTATUS
  154853. +gco2D_SetPixelMultiplyModeAdvanced(
  154854. + IN gco2D Engine,
  154855. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE SrcPremultiplySrcAlpha,
  154856. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstPremultiplyDstAlpha,
  154857. + IN gce2D_GLOBAL_COLOR_MULTIPLY_MODE SrcPremultiplyGlobalMode,
  154858. + IN gce2D_PIXEL_COLOR_MULTIPLY_MODE DstDemultiplyDstAlpha
  154859. + );
  154860. +
  154861. +/* Set the GPU clock cycles after which the idle engine will keep auto-flushing. */
  154862. +gceSTATUS
  154863. +gco2D_SetAutoFlushCycles(
  154864. + IN gco2D Engine,
  154865. + IN gctUINT32 Cycles
  154866. + );
  154867. +
  154868. +#if VIVANTE_PROFILER
  154869. +/* Read the profile registers available in the 2D engine and sets them in the profile.
  154870. + The function will also reset the pixelsRendered counter every time.
  154871. +*/
  154872. +gceSTATUS
  154873. +gco2D_ProfileEngine(
  154874. + IN gco2D Engine,
  154875. + OPTIONAL gcs2D_PROFILE_PTR Profile
  154876. + );
  154877. +#endif
  154878. +
  154879. +/* Enable or disable 2D dithering. */
  154880. +gceSTATUS
  154881. +gco2D_EnableDither(
  154882. + IN gco2D Engine,
  154883. + IN gctBOOL Enable
  154884. + );
  154885. +
  154886. +gceSTATUS
  154887. +gco2D_SetGenericSource(
  154888. + IN gco2D Engine,
  154889. + IN gctUINT32_PTR Addresses,
  154890. + IN gctUINT32 AddressNum,
  154891. + IN gctUINT32_PTR Strides,
  154892. + IN gctUINT32 StrideNum,
  154893. + IN gceTILING Tiling,
  154894. + IN gceSURF_FORMAT Format,
  154895. + IN gceSURF_ROTATION Rotation,
  154896. + IN gctUINT32 SurfaceWidth,
  154897. + IN gctUINT32 SurfaceHeight
  154898. +);
  154899. +
  154900. +gceSTATUS
  154901. +gco2D_SetGenericTarget(
  154902. + IN gco2D Engine,
  154903. + IN gctUINT32_PTR Addresses,
  154904. + IN gctUINT32 AddressNum,
  154905. + IN gctUINT32_PTR Strides,
  154906. + IN gctUINT32 StrideNum,
  154907. + IN gceTILING Tiling,
  154908. + IN gceSURF_FORMAT Format,
  154909. + IN gceSURF_ROTATION Rotation,
  154910. + IN gctUINT32 SurfaceWidth,
  154911. + IN gctUINT32 SurfaceHeight
  154912. +);
  154913. +
  154914. +gceSTATUS
  154915. +gco2D_SetCurrentSourceIndex(
  154916. + IN gco2D Engine,
  154917. + IN gctUINT32 SrcIndex
  154918. + );
  154919. +
  154920. +gceSTATUS
  154921. +gco2D_MultiSourceBlit(
  154922. + IN gco2D Engine,
  154923. + IN gctUINT32 SourceMask,
  154924. + IN gcsRECT_PTR DestRect,
  154925. + IN gctUINT32 RectCount
  154926. + );
  154927. +
  154928. +gceSTATUS
  154929. +gco2D_SetROP(
  154930. + IN gco2D Engine,
  154931. + IN gctUINT8 FgRop,
  154932. + IN gctUINT8 BgRop
  154933. + );
  154934. +
  154935. +gceSTATUS
  154936. +gco2D_SetGdiStretchMode(
  154937. + IN gco2D Engine,
  154938. + IN gctBOOL Enable
  154939. + );
  154940. +
  154941. +gceSTATUS
  154942. +gco2D_SetSourceTileStatus(
  154943. + IN gco2D Engine,
  154944. + IN gce2D_TILE_STATUS_CONFIG TSControl,
  154945. + IN gceSURF_FORMAT CompressedFormat,
  154946. + IN gctUINT32 ClearValue,
  154947. + IN gctUINT32 GpuAddress
  154948. + );
  154949. +
  154950. +gceSTATUS
  154951. +gco2D_SetTargetTileStatus(
  154952. + IN gco2D Engine,
  154953. + IN gce2D_TILE_STATUS_CONFIG TileStatusConfig,
  154954. + IN gceSURF_FORMAT CompressedFormat,
  154955. + IN gctUINT32 ClearValue,
  154956. + IN gctUINT32 GpuAddress
  154957. + );
  154958. +
  154959. +gceSTATUS
  154960. +gco2D_QueryU32(
  154961. + IN gco2D Engine,
  154962. + IN gce2D_QUERY Item,
  154963. + OUT gctUINT32_PTR Value
  154964. + );
  154965. +
  154966. +gceSTATUS
  154967. +gco2D_SetStateU32(
  154968. + IN gco2D Engine,
  154969. + IN gce2D_STATE State,
  154970. + IN gctUINT32 Value
  154971. + );
  154972. +
  154973. +gceSTATUS
  154974. +gco2D_SetStateArrayI32(
  154975. + IN gco2D Engine,
  154976. + IN gce2D_STATE State,
  154977. + IN gctINT32_PTR Array,
  154978. + IN gctINT32 ArraySize
  154979. + );
  154980. +
  154981. +gceSTATUS
  154982. +gco2D_SetStateArrayU32(
  154983. + IN gco2D Engine,
  154984. + IN gce2D_STATE State,
  154985. + IN gctUINT32_PTR Array,
  154986. + IN gctINT32 ArraySize
  154987. + );
  154988. +
  154989. +gceSTATUS
  154990. +gco2D_SetTargetRect(
  154991. + IN gco2D Engine,
  154992. + IN gcsRECT_PTR Rect
  154993. + );
  154994. +
  154995. +#ifdef __cplusplus
  154996. +}
  154997. +#endif
  154998. +
  154999. +#endif /* __gc_hal_raster_h_ */
  155000. diff -Nur linux-3.14.17/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
  155001. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h 1970-01-01 01:00:00.000000000 +0100
  155002. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h 2014-09-11 18:06:03.122042450 +0200
  155003. @@ -0,0 +1,248 @@
  155004. +/****************************************************************************
  155005. +*
  155006. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155007. +*
  155008. +* This program is free software; you can redistribute it and/or modify
  155009. +* it under the terms of the GNU General Public License as published by
  155010. +* the Free Software Foundation; either version 2 of the license, or
  155011. +* (at your option) any later version.
  155012. +*
  155013. +* This program is distributed in the hope that it will be useful,
  155014. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155015. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155016. +* GNU General Public License for more details.
  155017. +*
  155018. +* You should have received a copy of the GNU General Public License
  155019. +* along with this program; if not write to the Free Software
  155020. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155021. +*
  155022. +*****************************************************************************/
  155023. +
  155024. +
  155025. +#ifndef __gc_hal_rename_h_
  155026. +#define __gc_hal_rename_h_
  155027. +
  155028. +
  155029. +#if defined(_HAL2D_APPENDIX)
  155030. +
  155031. +#define _HAL2D_RENAME_2(api, appendix) api ## appendix
  155032. +#define _HAL2D_RENAME_1(api, appendix) _HAL2D_RENAME_2(api, appendix)
  155033. +#define gcmHAL2D(api) _HAL2D_RENAME_1(api, _HAL2D_APPENDIX)
  155034. +
  155035. +
  155036. +#define gckOS_Construct gcmHAL2D(gckOS_Construct)
  155037. +#define gckOS_Destroy gcmHAL2D(gckOS_Destroy)
  155038. +#define gckOS_QueryVideoMemory gcmHAL2D(gckOS_QueryVideoMemory)
  155039. +#define gckOS_Allocate gcmHAL2D(gckOS_Allocate)
  155040. +#define gckOS_Free gcmHAL2D(gckOS_Free)
  155041. +#define gckOS_AllocateMemory gcmHAL2D(gckOS_AllocateMemory)
  155042. +#define gckOS_FreeMemory gcmHAL2D(gckOS_FreeMemory)
  155043. +#define gckOS_AllocatePagedMemory gcmHAL2D(gckOS_AllocatePagedMemory)
  155044. +#define gckOS_AllocatePagedMemoryEx gcmHAL2D(gckOS_AllocatePagedMemoryEx)
  155045. +#define gckOS_LockPages gcmHAL2D(gckOS_LockPages)
  155046. +#define gckOS_MapPages gcmHAL2D(gckOS_MapPages)
  155047. +#define gckOS_UnlockPages gcmHAL2D(gckOS_UnlockPages)
  155048. +#define gckOS_FreePagedMemory gcmHAL2D(gckOS_FreePagedMemory)
  155049. +#define gckOS_AllocateNonPagedMemory gcmHAL2D(gckOS_AllocateNonPagedMemory)
  155050. +#define gckOS_FreeNonPagedMemory gcmHAL2D(gckOS_FreeNonPagedMemory)
  155051. +#define gckOS_AllocateContiguous gcmHAL2D(gckOS_AllocateContiguous)
  155052. +#define gckOS_FreeContiguous gcmHAL2D(gckOS_FreeContiguous)
  155053. +#define gckOS_GetPageSize gcmHAL2D(gckOS_GetPageSize)
  155054. +#define gckOS_GetPhysicalAddress gcmHAL2D(gckOS_GetPhysicalAddress)
  155055. +#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess)
  155056. +#define gckOS_MapPhysical gcmHAL2D(gckOS_MapPhysical)
  155057. +#define gckOS_UnmapPhysical gcmHAL2D(gckOS_UnmapPhysical)
  155058. +#define gckOS_ReadRegister gcmHAL2D(gckOS_ReadRegister)
  155059. +#define gckOS_WriteRegister gcmHAL2D(gckOS_WriteRegister)
  155060. +#define gckOS_WriteMemory gcmHAL2D(gckOS_WriteMemory)
  155061. +#define gckOS_MapMemory gcmHAL2D(gckOS_MapMemory)
  155062. +#define gckOS_UnmapMemory gcmHAL2D(gckOS_UnmapMemory)
  155063. +#define gckOS_UnmapMemoryEx gcmHAL2D(gckOS_UnmapMemoryEx)
  155064. +#define gckOS_CreateMutex gcmHAL2D(gckOS_CreateMutex)
  155065. +#define gckOS_DeleteMutex gcmHAL2D(gckOS_DeleteMutex)
  155066. +#define gckOS_AcquireMutex gcmHAL2D(gckOS_AcquireMutex)
  155067. +#define gckOS_ReleaseMutex gcmHAL2D(gckOS_ReleaseMutex)
  155068. +#define gckOS_AtomicExchange gcmHAL2D(gckOS_AtomicExchange)
  155069. +#define gckOS_AtomicExchangePtr gcmHAL2D(gckOS_AtomicExchangePtr)
  155070. +#define gckOS_AtomConstruct gcmHAL2D(gckOS_AtomConstruct)
  155071. +#define gckOS_AtomDestroy gcmHAL2D(gckOS_AtomDestroy)
  155072. +#define gckOS_AtomGet gcmHAL2D(gckOS_AtomGet)
  155073. +#define gckOS_AtomIncrement gcmHAL2D(gckOS_AtomIncrement)
  155074. +#define gckOS_AtomDecrement gcmHAL2D(gckOS_AtomDecrement)
  155075. +#define gckOS_Delay gcmHAL2D(gckOS_Delay)
  155076. +#define gckOS_GetTime gcmHAL2D(gckOS_GetTime)
  155077. +#define gckOS_MemoryBarrier gcmHAL2D(gckOS_MemoryBarrier)
  155078. +#define gckOS_MapUserPointer gcmHAL2D(gckOS_MapUserPointer)
  155079. +#define gckOS_UnmapUserPointer gcmHAL2D(gckOS_UnmapUserPointer)
  155080. +#define gckOS_QueryNeedCopy gcmHAL2D(gckOS_QueryNeedCopy)
  155081. +#define gckOS_CopyFromUserData gcmHAL2D(gckOS_CopyFromUserData)
  155082. +#define gckOS_CopyToUserData gcmHAL2D(gckOS_CopyToUserData)
  155083. +#define gckOS_MapUserPhysical gcmHAL2D(gckOS_MapUserPhysical)
  155084. +#define gckOS_SuspendInterrupt gcmHAL2D(gckOS_SuspendInterrupt)
  155085. +#define gckOS_ResumeInterrupt gcmHAL2D(gckOS_ResumeInterrupt)
  155086. +#define gckOS_GetBaseAddress gcmHAL2D(gckOS_GetBaseAddress)
  155087. +#define gckOS_MemCopy gcmHAL2D(gckOS_MemCopy)
  155088. +#define gckOS_ZeroMemory gcmHAL2D(gckOS_ZeroMemory)
  155089. +#define gckOS_DeviceControl gcmHAL2D(gckOS_DeviceControl)
  155090. +#define gckOS_GetProcessID gcmHAL2D(gckOS_GetProcessID)
  155091. +#define gckOS_GetThreadID gcmHAL2D(gckOS_GetThreadID)
  155092. +#define gckOS_CreateSignal gcmHAL2D(gckOS_CreateSignal)
  155093. +#define gckOS_DestroySignal gcmHAL2D(gckOS_DestroySignal)
  155094. +#define gckOS_Signal gcmHAL2D(gckOS_Signal)
  155095. +#define gckOS_WaitSignal gcmHAL2D(gckOS_WaitSignal)
  155096. +#define gckOS_MapSignal gcmHAL2D(gckOS_MapSignal)
  155097. +#define gckOS_MapUserMemory gcmHAL2D(gckOS_MapUserMemory)
  155098. +#define gckOS_UnmapUserMemory gcmHAL2D(gckOS_UnmapUserMemory)
  155099. +#define gckOS_CreateUserSignal gcmHAL2D(gckOS_CreateUserSignal)
  155100. +#define gckOS_DestroyUserSignal gcmHAL2D(gckOS_DestroyUserSignal)
  155101. +#define gckOS_WaitUserSignal gcmHAL2D(gckOS_WaitUserSignal)
  155102. +#define gckOS_SignalUserSignal gcmHAL2D(gckOS_SignalUserSignal)
  155103. +#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
  155104. +#define gckOS_UserSignal gcmHAL2D(gckOS_UserSignal)
  155105. +#define gckOS_CacheClean gcmHAL2D(gckOS_CacheClean)
  155106. +#define gckOS_CacheFlush gcmHAL2D(gckOS_CacheFlush)
  155107. +#define gckOS_SetDebugLevel gcmHAL2D(gckOS_SetDebugLevel)
  155108. +#define gckOS_SetDebugZone gcmHAL2D(gckOS_SetDebugZone)
  155109. +#define gckOS_SetDebugLevelZone gcmHAL2D(gckOS_SetDebugLevelZone)
  155110. +#define gckOS_SetDebugZones gcmHAL2D(gckOS_SetDebugZones)
  155111. +#define gckOS_SetDebugFile gcmHAL2D(gckOS_SetDebugFile)
  155112. +#define gckOS_Broadcast gcmHAL2D(gckOS_Broadcast)
  155113. +#define gckOS_SetGPUPower gcmHAL2D(gckOS_SetGPUPower)
  155114. +#define gckOS_CreateSemaphore gcmHAL2D(gckOS_CreateSemaphore)
  155115. +#define gckOS_DestroySemaphore gcmHAL2D(gckOS_DestroySemaphore)
  155116. +#define gckOS_AcquireSemaphore gcmHAL2D(gckOS_AcquireSemaphore)
  155117. +#define gckOS_ReleaseSemaphore gcmHAL2D(gckOS_ReleaseSemaphore)
  155118. +#define gckHEAP_Construct gcmHAL2D(gckHEAP_Construct)
  155119. +#define gckHEAP_Destroy gcmHAL2D(gckHEAP_Destroy)
  155120. +#define gckHEAP_Allocate gcmHAL2D(gckHEAP_Allocate)
  155121. +#define gckHEAP_Free gcmHAL2D(gckHEAP_Free)
  155122. +#define gckHEAP_ProfileStart gcmHAL2D(gckHEAP_ProfileStart)
  155123. +#define gckHEAP_ProfileEnd gcmHAL2D(gckHEAP_ProfileEnd)
  155124. +#define gckHEAP_Test gcmHAL2D(gckHEAP_Test)
  155125. +#define gckVIDMEM_Construct gcmHAL2D(gckVIDMEM_Construct)
  155126. +#define gckVIDMEM_Destroy gcmHAL2D(gckVIDMEM_Destroy)
  155127. +#define gckVIDMEM_Allocate gcmHAL2D(gckVIDMEM_Allocate)
  155128. +#define gckVIDMEM_AllocateLinear gcmHAL2D(gckVIDMEM_AllocateLinear)
  155129. +#define gckVIDMEM_Free gcmHAL2D(gckVIDMEM_Free)
  155130. +#define gckVIDMEM_Lock gcmHAL2D(gckVIDMEM_Lock)
  155131. +#define gckVIDMEM_Unlock gcmHAL2D(gckVIDMEM_Unlock)
  155132. +#define gckVIDMEM_ConstructVirtual gcmHAL2D(gckVIDMEM_ConstructVirtual)
  155133. +#define gckVIDMEM_DestroyVirtual gcmHAL2D(gckVIDMEM_DestroyVirtual)
  155134. +#define gckKERNEL_Construct gcmHAL2D(gckKERNEL_Construct)
  155135. +#define gckKERNEL_Destroy gcmHAL2D(gckKERNEL_Destroy)
  155136. +#define gckKERNEL_Dispatch gcmHAL2D(gckKERNEL_Dispatch)
  155137. +#define gckKERNEL_QueryVideoMemory gcmHAL2D(gckKERNEL_QueryVideoMemory)
  155138. +#define gckKERNEL_GetVideoMemoryPool gcmHAL2D(gckKERNEL_GetVideoMemoryPool)
  155139. +#define gckKERNEL_MapVideoMemory gcmHAL2D(gckKERNEL_MapVideoMemory)
  155140. +#define gckKERNEL_UnmapVideoMemory gcmHAL2D(gckKERNEL_UnmapVideoMemory)
  155141. +#define gckKERNEL_MapMemory gcmHAL2D(gckKERNEL_MapMemory)
  155142. +#define gckKERNEL_UnmapMemory gcmHAL2D(gckKERNEL_UnmapMemory)
  155143. +#define gckKERNEL_Notify gcmHAL2D(gckKERNEL_Notify)
  155144. +#define gckKERNEL_QuerySettings gcmHAL2D(gckKERNEL_QuerySettings)
  155145. +#define gckKERNEL_Recovery gcmHAL2D(gckKERNEL_Recovery)
  155146. +#define gckKERNEL_OpenUserData gcmHAL2D(gckKERNEL_OpenUserData)
  155147. +#define gckKERNEL_CloseUserData gcmHAL2D(gckKERNEL_CloseUserData)
  155148. +#define gckHARDWARE_Construct gcmHAL2D(gckHARDWARE_Construct)
  155149. +#define gckHARDWARE_Destroy gcmHAL2D(gckHARDWARE_Destroy)
  155150. +#define gckHARDWARE_QuerySystemMemory gcmHAL2D(gckHARDWARE_QuerySystemMemory)
  155151. +#define gckHARDWARE_BuildVirtualAddress gcmHAL2D(gckHARDWARE_BuildVirtualAddress)
  155152. +#define gckHARDWARE_QueryCommandBuffer gcmHAL2D(gckHARDWARE_QueryCommandBuffer)
  155153. +#define gckHARDWARE_WaitLink gcmHAL2D(gckHARDWARE_WaitLink)
  155154. +#define gckHARDWARE_Execute gcmHAL2D(gckHARDWARE_Execute)
  155155. +#define gckHARDWARE_End gcmHAL2D(gckHARDWARE_End)
  155156. +#define gckHARDWARE_Nop gcmHAL2D(gckHARDWARE_Nop)
  155157. +#define gckHARDWARE_Wait gcmHAL2D(gckHARDWARE_Wait)
  155158. +#define gckHARDWARE_PipeSelect gcmHAL2D(gckHARDWARE_PipeSelect)
  155159. +#define gckHARDWARE_Link gcmHAL2D(gckHARDWARE_Link)
  155160. +#define gckHARDWARE_Event gcmHAL2D(gckHARDWARE_Event)
  155161. +#define gckHARDWARE_QueryMemory gcmHAL2D(gckHARDWARE_QueryMemory)
  155162. +#define gckHARDWARE_QueryChipIdentity gcmHAL2D(gckHARDWARE_QueryChipIdentity)
  155163. +#define gckHARDWARE_QueryChipSpecs gcmHAL2D(gckHARDWARE_QueryChipSpecs)
  155164. +#define gckHARDWARE_QueryShaderCaps gcmHAL2D(gckHARDWARE_QueryShaderCaps)
  155165. +#define gckHARDWARE_ConvertFormat gcmHAL2D(gckHARDWARE_ConvertFormat)
  155166. +#define gckHARDWARE_SplitMemory gcmHAL2D(gckHARDWARE_SplitMemory)
  155167. +#define gckHARDWARE_AlignToTile gcmHAL2D(gckHARDWARE_AlignToTile)
  155168. +#define gckHARDWARE_UpdateQueueTail gcmHAL2D(gckHARDWARE_UpdateQueueTail)
  155169. +#define gckHARDWARE_ConvertLogical gcmHAL2D(gckHARDWARE_ConvertLogical)
  155170. +#define gckHARDWARE_ConvertPhysical gcmHAL2D(gckHARDWARE_ConvertPhysical)
  155171. +#define gckHARDWARE_Interrupt gcmHAL2D(gckHARDWARE_Interrupt)
  155172. +#define gckHARDWARE_SetMMU gcmHAL2D(gckHARDWARE_SetMMU)
  155173. +#define gckHARDWARE_FlushMMU gcmHAL2D(gckHARDWARE_FlushMMU)
  155174. +#define gckHARDWARE_GetIdle gcmHAL2D(gckHARDWARE_GetIdle)
  155175. +#define gckHARDWARE_Flush gcmHAL2D(gckHARDWARE_Flush)
  155176. +#define gckHARDWARE_SetFastClear gcmHAL2D(gckHARDWARE_SetFastClear)
  155177. +#define gckHARDWARE_ReadInterrupt gcmHAL2D(gckHARDWARE_ReadInterrupt)
  155178. +#define gckHARDWARE_SetPowerManagementState gcmHAL2D(gckHARDWARE_SetPowerManagementState)
  155179. +#define gckHARDWARE_QueryPowerManagementState gcmHAL2D(gckHARDWARE_QueryPowerManagementState)
  155180. +#define gckHARDWARE_ProfileEngine2D gcmHAL2D(gckHARDWARE_ProfileEngine2D)
  155181. +#define gckHARDWARE_InitializeHardware gcmHAL2D(gckHARDWARE_InitializeHardware)
  155182. +#define gckHARDWARE_Reset gcmHAL2D(gckHARDWARE_Reset)
  155183. +#define gckINTERRUPT_Construct gcmHAL2D(gckINTERRUPT_Construct)
  155184. +#define gckINTERRUPT_Destroy gcmHAL2D(gckINTERRUPT_Destroy)
  155185. +#define gckINTERRUPT_SetHandler gcmHAL2D(gckINTERRUPT_SetHandler)
  155186. +#define gckINTERRUPT_Notify gcmHAL2D(gckINTERRUPT_Notify)
  155187. +#define gckEVENT_Construct gcmHAL2D(gckEVENT_Construct)
  155188. +#define gckEVENT_Destroy gcmHAL2D(gckEVENT_Destroy)
  155189. +#define gckEVENT_AddList gcmHAL2D(gckEVENT_AddList)
  155190. +#define gckEVENT_FreeNonPagedMemory gcmHAL2D(gckEVENT_FreeNonPagedMemory)
  155191. +#define gckEVENT_FreeContiguousMemory gcmHAL2D(gckEVENT_FreeContiguousMemory)
  155192. +#define gckEVENT_FreeVideoMemory gcmHAL2D(gckEVENT_FreeVideoMemory)
  155193. +#define gckEVENT_Signal gcmHAL2D(gckEVENT_Signal)
  155194. +#define gckEVENT_Unlock gcmHAL2D(gckEVENT_Unlock)
  155195. +#define gckEVENT_Submit gcmHAL2D(gckEVENT_Submit)
  155196. +#define gckEVENT_Commit gcmHAL2D(gckEVENT_Commit)
  155197. +#define gckEVENT_Notify gcmHAL2D(gckEVENT_Notify)
  155198. +#define gckEVENT_Interrupt gcmHAL2D(gckEVENT_Interrupt)
  155199. +#define gckCOMMAND_Construct gcmHAL2D(gckCOMMAND_Construct)
  155200. +#define gckCOMMAND_Destroy gcmHAL2D(gckCOMMAND_Destroy)
  155201. +#define gckCOMMAND_EnterCommit gcmHAL2D(gckCOMMAND_EnterCommit)
  155202. +#define gckCOMMAND_ExitCommit gcmHAL2D(gckCOMMAND_ExitCommit)
  155203. +#define gckCOMMAND_Start gcmHAL2D(gckCOMMAND_Start)
  155204. +#define gckCOMMAND_Stop gcmHAL2D(gckCOMMAND_Stop)
  155205. +#define gckCOMMAND_Commit gcmHAL2D(gckCOMMAND_Commit)
  155206. +#define gckCOMMAND_Reserve gcmHAL2D(gckCOMMAND_Reserve)
  155207. +#define gckCOMMAND_Execute gcmHAL2D(gckCOMMAND_Execute)
  155208. +#define gckCOMMAND_Stall gcmHAL2D(gckCOMMAND_Stall)
  155209. +#define gckCOMMAND_Attach gcmHAL2D(gckCOMMAND_Attach)
  155210. +#define gckCOMMAND_Detach gcmHAL2D(gckCOMMAND_Detach)
  155211. +#define gckMMU_Construct gcmHAL2D(gckMMU_Construct)
  155212. +#define gckMMU_Destroy gcmHAL2D(gckMMU_Destroy)
  155213. +#define gckMMU_AllocatePages gcmHAL2D(gckMMU_AllocatePages)
  155214. +#define gckMMU_FreePages gcmHAL2D(gckMMU_FreePages)
  155215. +#define gckMMU_InsertNode gcmHAL2D(gckMMU_InsertNode)
  155216. +#define gckMMU_RemoveNode gcmHAL2D(gckMMU_RemoveNode)
  155217. +#define gckMMU_FreeHandleMemory gcmHAL2D(gckMMU_FreeHandleMemory)
  155218. +#define gckMMU_Test gcmHAL2D(gckMMU_Test)
  155219. +#define gckHARDWARE_QueryProfileRegisters gcmHAL2D(gckHARDWARE_QueryProfileRegisters)
  155220. +
  155221. +
  155222. +#define FindMdlMap gcmHAL2D(FindMdlMap)
  155223. +#define OnProcessExit gcmHAL2D(OnProcessExit)
  155224. +
  155225. +#define gckGALDEVICE_Destroy gcmHAL2D(gckGALDEVICE_Destroy)
  155226. +#define gckOS_Print gcmHAL2D(gckOS_Print)
  155227. +#define gckGALDEVICE_FreeMemory gcmHAL2D(gckGALDEVICE_FreeMemory)
  155228. +#define gckGALDEVICE_AllocateMemory gcmHAL2D(gckGALDEVICE_AllocateMemory)
  155229. +#define gckOS_DebugBreak gcmHAL2D(gckOS_DebugBreak)
  155230. +#define gckGALDEVICE_Release_ISR gcmHAL2D(gckGALDEVICE_Release_ISR)
  155231. +#define gckOS_Verify gcmHAL2D(gckOS_Verify)
  155232. +#define gckCOMMAND_Release gcmHAL2D(gckCOMMAND_Release)
  155233. +#define gckGALDEVICE_Stop gcmHAL2D(gckGALDEVICE_Stop)
  155234. +#define gckGALDEVICE_Construct gcmHAL2D(gckGALDEVICE_Construct)
  155235. +#define gckOS_DebugFatal gcmHAL2D(gckOS_DebugFatal)
  155236. +#define gckOS_DebugTrace gcmHAL2D(gckOS_DebugTrace)
  155237. +#define gckHARDWARE_GetBaseAddress gcmHAL2D(gckHARDWARE_GetBaseAddress)
  155238. +#define gckGALDEVICE_Setup_ISR gcmHAL2D(gckGALDEVICE_Setup_ISR)
  155239. +#define gckKERNEL_AttachProcess gcmHAL2D(gckKERNEL_AttachProcess)
  155240. +#define gckKERNEL_AttachProcessEx gcmHAL2D(gckKERNEL_AttachProcessEx)
  155241. +#define gckGALDEVICE_Start_Thread gcmHAL2D(gckGALDEVICE_Start_Thread)
  155242. +#define gckHARDWARE_QueryIdle gcmHAL2D(gckHARDWARE_QueryIdle)
  155243. +#define gckGALDEVICE_Start gcmHAL2D(gckGALDEVICE_Start)
  155244. +#define gckOS_GetKernelLogical gcmHAL2D(gckOS_GetKernelLogical)
  155245. +#define gckOS_DebugTraceZone gcmHAL2D(gckOS_DebugTraceZone)
  155246. +#define gckGALDEVICE_Stop_Thread gcmHAL2D(gckGALDEVICE_Stop_Thread)
  155247. +#define gckHARDWARE_NeedBaseAddress gcmHAL2D(gckHARDWARE_NeedBaseAddress)
  155248. +
  155249. +#endif
  155250. +
  155251. +#endif /* __gc_hal_rename_h_ */
  155252. diff -Nur linux-3.14.17/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
  155253. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h 1970-01-01 01:00:00.000000000 +0100
  155254. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h 2014-09-11 18:06:03.122042450 +0200
  155255. @@ -0,0 +1,115 @@
  155256. +/****************************************************************************
  155257. +*
  155258. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155259. +*
  155260. +* This program is free software; you can redistribute it and/or modify
  155261. +* it under the terms of the GNU General Public License as published by
  155262. +* the Free Software Foundation; either version 2 of the license, or
  155263. +* (at your option) any later version.
  155264. +*
  155265. +* This program is distributed in the hope that it will be useful,
  155266. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155267. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155268. +* GNU General Public License for more details.
  155269. +*
  155270. +* You should have received a copy of the GNU General Public License
  155271. +* along with this program; if not write to the Free Software
  155272. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155273. +*
  155274. +*****************************************************************************/
  155275. +
  155276. +
  155277. +#ifndef __gc_hal_statistics_h_
  155278. +#define __gc_hal_statistics_h_
  155279. +
  155280. +
  155281. +#define VIV_STAT_ENABLE_STATISTICS 0
  155282. +
  155283. +/* Toal number of frames for which the frame time is accounted. We have storage
  155284. + to keep frame times for last this many frames.
  155285. +*/
  155286. +#define VIV_STAT_FRAME_BUFFER_SIZE 30
  155287. +
  155288. +/*
  155289. + Total number of frames sampled for a mode. This means
  155290. +
  155291. + # of frames for HZ Current : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
  155292. + # of frames for HZ Switched : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
  155293. + +
  155294. + --------------------------------------------------------
  155295. + : (2 * VIV_STAT_EARLY_Z_SAMPLE_FRAMES) frames needed
  155296. +
  155297. + IMPORTANT: This total must be smaller than VIV_STAT_FRAME_BUFFER_SIZE
  155298. +*/
  155299. +#define VIV_STAT_EARLY_Z_SAMPLE_FRAMES 7
  155300. +#define VIV_STAT_EARLY_Z_LATENCY_FRAMES 2
  155301. +
  155302. +/* Multiplication factor for previous Hz off mode. Make it more than 1.0 to advertise HZ on.*/
  155303. +#define VIV_STAT_EARLY_Z_FACTOR (1.05f)
  155304. +
  155305. +/* Defines the statistical data keys monitored by the statistics module */
  155306. +typedef enum _gceSTATISTICS
  155307. +{
  155308. + gcvFRAME_FPS = 1,
  155309. +}
  155310. +gceSTATISTICS;
  155311. +
  155312. +/* HAL statistics information. */
  155313. +typedef struct _gcsSTATISTICS_EARLYZ
  155314. +{
  155315. + gctUINT switchBackCount;
  155316. + gctUINT nextCheckPoint;
  155317. + gctBOOL disabled;
  155318. +}
  155319. +gcsSTATISTICS_EARLYZ;
  155320. +
  155321. +
  155322. +/* Defines the statistical data keys monitored by the statistics module */
  155323. +typedef enum _gceSTATISTICS_Call
  155324. +{
  155325. + gcvSTAT_ES11_GLDRAWELEMENTS = 1,
  155326. +}
  155327. +gceSTATISTICS_Call;
  155328. +
  155329. +
  155330. +/* HAL statistics information. */
  155331. +typedef struct _gcsSTATISTICS
  155332. +{
  155333. + gctUINT64 frameTime[VIV_STAT_FRAME_BUFFER_SIZE];
  155334. + gctUINT64 previousFrameTime;
  155335. + gctUINT frame;
  155336. + gcsSTATISTICS_EARLYZ earlyZ;
  155337. + gctUINT ES11_drawElementsCount;
  155338. + gctBOOL applyRTestVAFix;
  155339. +}
  155340. +gcsSTATISTICS;
  155341. +
  155342. +
  155343. +/* Add a frame based data into current statistics. */
  155344. +void
  155345. +gcfSTATISTICS_AddData(
  155346. + IN gceSTATISTICS Key,
  155347. + IN gctUINT Value
  155348. + );
  155349. +
  155350. +/* Marks the frame end and triggers statistical calculations and decisions.*/
  155351. +void
  155352. +gcfSTATISTICS_MarkFrameEnd (
  155353. + void
  155354. + );
  155355. +
  155356. +/* Sets whether the dynmaic HZ is disabled or not .*/
  155357. +void
  155358. +gcfSTATISTICS_DisableDynamicEarlyZ (
  155359. + IN gctBOOL Disabled
  155360. + );
  155361. +
  155362. +/* Checks whether or not glDrawArray function call will be discarded */
  155363. +gctBOOL
  155364. +gcfSTATISTICS_DiscardCall(
  155365. + gceSTATISTICS_Call Function
  155366. + );
  155367. +
  155368. +
  155369. +#endif /*__gc_hal_statistics_h_ */
  155370. +
  155371. diff -Nur linux-3.14.17/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
  155372. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h 1970-01-01 01:00:00.000000000 +0100
  155373. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h 2014-09-11 18:06:03.122042450 +0200
  155374. @@ -0,0 +1,1080 @@
  155375. +/****************************************************************************
  155376. +*
  155377. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  155378. +*
  155379. +* This program is free software; you can redistribute it and/or modify
  155380. +* it under the terms of the GNU General Public License as published by
  155381. +* the Free Software Foundation; either version 2 of the license, or
  155382. +* (at your option) any later version.
  155383. +*
  155384. +* This program is distributed in the hope that it will be useful,
  155385. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  155386. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155387. +* GNU General Public License for more details.
  155388. +*
  155389. +* You should have received a copy of the GNU General Public License
  155390. +* along with this program; if not write to the Free Software
  155391. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  155392. +*
  155393. +*****************************************************************************/
  155394. +
  155395. +
  155396. +#ifndef __gc_hal_types_h_
  155397. +#define __gc_hal_types_h_
  155398. +
  155399. +#include "gc_hal_version.h"
  155400. +#include "gc_hal_options.h"
  155401. +
  155402. +#ifdef _WIN32
  155403. +#pragma warning(disable:4127) /* Conditional expression is constant (do { }
  155404. + ** while(0)). */
  155405. +#pragma warning(disable:4100) /* Unreferenced formal parameter. */
  155406. +#pragma warning(disable:4204) /* Non-constant aggregate initializer (C99). */
  155407. +#pragma warning(disable:4131) /* Uses old-style declarator (for Bison and
  155408. + ** Flex generated files). */
  155409. +#pragma warning(disable:4206) /* Translation unit is empty. */
  155410. +#endif
  155411. +
  155412. +#ifdef __cplusplus
  155413. +extern "C" {
  155414. +#endif
  155415. +
  155416. +/******************************************************************************\
  155417. +** Platform macros.
  155418. +*/
  155419. +
  155420. +#if defined(__GNUC__)
  155421. +# define gcdHAS_ELLIPSES 1 /* GCC always has it. */
  155422. +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
  155423. +# define gcdHAS_ELLIPSES 1 /* C99 has it. */
  155424. +#elif defined(_MSC_VER) && (_MSC_VER >= 1500)
  155425. +# define gcdHAS_ELLIPSES 1 /* MSVC 2007+ has it. */
  155426. +#elif defined(UNDER_CE)
  155427. +#if UNDER_CE >= 600
  155428. +# define gcdHAS_ELLIPSES 1
  155429. +# else
  155430. +# define gcdHAS_ELLIPSES 0
  155431. +# endif
  155432. +#else
  155433. +# error "gcdHAS_ELLIPSES: Platform could not be determined"
  155434. +#endif
  155435. +
  155436. +/******************************************************************************\
  155437. +************************************ Keyword ***********************************
  155438. +\******************************************************************************/
  155439. +
  155440. +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
  155441. +# define gcmINLINE inline /* C99 keyword. */
  155442. +#elif defined(__GNUC__)
  155443. +# define gcmINLINE __inline__ /* GNU keyword. */
  155444. +#elif defined(_MSC_VER) || defined(UNDER_CE)
  155445. +# define gcmINLINE __inline /* Internal keyword. */
  155446. +#else
  155447. +# error "gcmINLINE: Platform could not be determined"
  155448. +#endif
  155449. +
  155450. +/* Possible debug flags. */
  155451. +#define gcdDEBUG_NONE 0
  155452. +#define gcdDEBUG_ALL (1 << 0)
  155453. +#define gcdDEBUG_FATAL (1 << 1)
  155454. +#define gcdDEBUG_TRACE (1 << 2)
  155455. +#define gcdDEBUG_BREAK (1 << 3)
  155456. +#define gcdDEBUG_ASSERT (1 << 4)
  155457. +#define gcdDEBUG_CODE (1 << 5)
  155458. +#define gcdDEBUG_STACK (1 << 6)
  155459. +
  155460. +#define gcmIS_DEBUG(flag) ( gcdDEBUG & (flag | gcdDEBUG_ALL) )
  155461. +
  155462. +#ifndef gcdDEBUG
  155463. +#if (defined(DBG) && DBG) || defined(DEBUG) || defined(_DEBUG)
  155464. +# define gcdDEBUG gcdDEBUG_ALL
  155465. +# else
  155466. +# define gcdDEBUG gcdDEBUG_NONE
  155467. +# endif
  155468. +#endif
  155469. +
  155470. +#ifdef _USRDLL
  155471. +#ifdef _MSC_VER
  155472. +#ifdef HAL_EXPORTS
  155473. +# define HALAPI __declspec(dllexport)
  155474. +# else
  155475. +# define HALAPI __declspec(dllimport)
  155476. +# endif
  155477. +# define HALDECL __cdecl
  155478. +# else
  155479. +#ifdef HAL_EXPORTS
  155480. +# define HALAPI
  155481. +# else
  155482. +# define HALAPI extern
  155483. +# endif
  155484. +# endif
  155485. +#else
  155486. +# define HALAPI
  155487. +# define HALDECL
  155488. +#endif
  155489. +
  155490. +/******************************************************************************\
  155491. +********************************** Common Types ********************************
  155492. +\******************************************************************************/
  155493. +
  155494. +#define gcvFALSE 0
  155495. +#define gcvTRUE 1
  155496. +
  155497. +#define gcvINFINITE ((gctUINT32) ~0U)
  155498. +
  155499. +#define gcvINVALID_HANDLE ((gctHANDLE) ~0U)
  155500. +
  155501. +typedef int gctBOOL;
  155502. +typedef gctBOOL * gctBOOL_PTR;
  155503. +
  155504. +typedef int gctINT;
  155505. +typedef long gctLONG;
  155506. +typedef signed char gctINT8;
  155507. +typedef signed short gctINT16;
  155508. +typedef signed int gctINT32;
  155509. +typedef signed long long gctINT64;
  155510. +
  155511. +typedef gctINT * gctINT_PTR;
  155512. +typedef gctINT8 * gctINT8_PTR;
  155513. +typedef gctINT16 * gctINT16_PTR;
  155514. +typedef gctINT32 * gctINT32_PTR;
  155515. +typedef gctINT64 * gctINT64_PTR;
  155516. +
  155517. +typedef unsigned int gctUINT;
  155518. +typedef unsigned char gctUINT8;
  155519. +typedef unsigned short gctUINT16;
  155520. +typedef unsigned int gctUINT32;
  155521. +typedef unsigned long long gctUINT64;
  155522. +typedef unsigned long gctUINTPTR_T;
  155523. +
  155524. +typedef gctUINT * gctUINT_PTR;
  155525. +typedef gctUINT8 * gctUINT8_PTR;
  155526. +typedef gctUINT16 * gctUINT16_PTR;
  155527. +typedef gctUINT32 * gctUINT32_PTR;
  155528. +typedef gctUINT64 * gctUINT64_PTR;
  155529. +
  155530. +typedef unsigned long gctSIZE_T;
  155531. +typedef gctSIZE_T * gctSIZE_T_PTR;
  155532. +
  155533. +#ifdef __cplusplus
  155534. +# define gcvNULL 0
  155535. +#else
  155536. +# define gcvNULL ((void *) 0)
  155537. +#endif
  155538. +
  155539. +typedef float gctFLOAT;
  155540. +typedef signed int gctFIXED_POINT;
  155541. +typedef float * gctFLOAT_PTR;
  155542. +
  155543. +typedef void * gctPHYS_ADDR;
  155544. +typedef void * gctHANDLE;
  155545. +typedef void * gctFILE;
  155546. +typedef void * gctSIGNAL;
  155547. +typedef void * gctWINDOW;
  155548. +typedef void * gctIMAGE;
  155549. +typedef void * gctSYNC_POINT;
  155550. +
  155551. +typedef void * gctSEMAPHORE;
  155552. +
  155553. +typedef void * gctPOINTER;
  155554. +typedef const void * gctCONST_POINTER;
  155555. +
  155556. +typedef char gctCHAR;
  155557. +typedef char * gctSTRING;
  155558. +typedef const char * gctCONST_STRING;
  155559. +
  155560. +typedef struct _gcsCOUNT_STRING
  155561. +{
  155562. + gctSIZE_T Length;
  155563. + gctCONST_STRING String;
  155564. +}
  155565. +gcsCOUNT_STRING;
  155566. +
  155567. +typedef union _gcuFLOAT_UINT32
  155568. +{
  155569. + gctFLOAT f;
  155570. + gctUINT32 u;
  155571. +}
  155572. +gcuFLOAT_UINT32;
  155573. +
  155574. +/* Fixed point constants. */
  155575. +#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
  155576. +#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
  155577. +#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
  155578. +#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
  155579. +#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
  155580. +
  155581. +/* Stringizing macro. */
  155582. +#define gcmSTRING(Value) #Value
  155583. +
  155584. +/******************************************************************************\
  155585. +******************************* Fixed Point Math *******************************
  155586. +\******************************************************************************/
  155587. +
  155588. +#define gcmXMultiply(x1, x2) gcoMATH_MultiplyFixed(x1, x2)
  155589. +#define gcmXDivide(x1, x2) gcoMATH_DivideFixed(x1, x2)
  155590. +#define gcmXMultiplyDivide(x1, x2, x3) gcoMATH_MultiplyDivideFixed(x1, x2, x3)
  155591. +
  155592. +/* 2D Engine profile. */
  155593. +typedef struct _gcs2D_PROFILE
  155594. +{
  155595. + /* Cycle count.
  155596. + 32bit counter incremented every 2D clock cycle.
  155597. + Wraps back to 0 when the counter overflows.
  155598. + */
  155599. + gctUINT32 cycleCount;
  155600. +
  155601. + /* Pixels rendered by the 2D engine.
  155602. + Resets to 0 every time it is read. */
  155603. + gctUINT32 pixelsRendered;
  155604. +}
  155605. +gcs2D_PROFILE;
  155606. +
  155607. +/* Macro to combine four characters into a Charcater Code. */
  155608. +#define gcmCC(c1, c2, c3, c4) \
  155609. +( \
  155610. + (char) (c1) \
  155611. + | \
  155612. + ((char) (c2) << 8) \
  155613. + | \
  155614. + ((char) (c3) << 16) \
  155615. + | \
  155616. + ((char) (c4) << 24) \
  155617. +)
  155618. +
  155619. +#define gcmPRINTABLE(c) ((((c) >= ' ') && ((c) <= '}')) ? ((c) != '%' ? (c) : ' ') : ' ')
  155620. +
  155621. +#define gcmCC_PRINT(cc) \
  155622. + gcmPRINTABLE((char) ( (cc) & 0xFF)), \
  155623. + gcmPRINTABLE((char) (((cc) >> 8) & 0xFF)), \
  155624. + gcmPRINTABLE((char) (((cc) >> 16) & 0xFF)), \
  155625. + gcmPRINTABLE((char) (((cc) >> 24) & 0xFF))
  155626. +
  155627. +/******************************************************************************\
  155628. +****************************** Function Parameters *****************************
  155629. +\******************************************************************************/
  155630. +
  155631. +#define IN
  155632. +#define OUT
  155633. +#define OPTIONAL
  155634. +
  155635. +/******************************************************************************\
  155636. +********************************* Status Codes *********************************
  155637. +\******************************************************************************/
  155638. +
  155639. +typedef enum _gceSTATUS
  155640. +{
  155641. + gcvSTATUS_OK = 0,
  155642. + gcvSTATUS_FALSE = 0,
  155643. + gcvSTATUS_TRUE = 1,
  155644. + gcvSTATUS_NO_MORE_DATA = 2,
  155645. + gcvSTATUS_CACHED = 3,
  155646. + gcvSTATUS_MIPMAP_TOO_LARGE = 4,
  155647. + gcvSTATUS_NAME_NOT_FOUND = 5,
  155648. + gcvSTATUS_NOT_OUR_INTERRUPT = 6,
  155649. + gcvSTATUS_MISMATCH = 7,
  155650. + gcvSTATUS_MIPMAP_TOO_SMALL = 8,
  155651. + gcvSTATUS_LARGER = 9,
  155652. + gcvSTATUS_SMALLER = 10,
  155653. + gcvSTATUS_CHIP_NOT_READY = 11,
  155654. + gcvSTATUS_NEED_CONVERSION = 12,
  155655. + gcvSTATUS_SKIP = 13,
  155656. + gcvSTATUS_DATA_TOO_LARGE = 14,
  155657. + gcvSTATUS_INVALID_CONFIG = 15,
  155658. + gcvSTATUS_CHANGED = 16,
  155659. + gcvSTATUS_NOT_SUPPORT_DITHER = 17,
  155660. + gcvSTATUS_EXECUTED = 18,
  155661. + gcvSTATUS_TERMINATE = 19,
  155662. +
  155663. + gcvSTATUS_CONVERT_TO_SINGLE_STREAM = 20,
  155664. +
  155665. + gcvSTATUS_INVALID_ARGUMENT = -1,
  155666. + gcvSTATUS_INVALID_OBJECT = -2,
  155667. + gcvSTATUS_OUT_OF_MEMORY = -3,
  155668. + gcvSTATUS_MEMORY_LOCKED = -4,
  155669. + gcvSTATUS_MEMORY_UNLOCKED = -5,
  155670. + gcvSTATUS_HEAP_CORRUPTED = -6,
  155671. + gcvSTATUS_GENERIC_IO = -7,
  155672. + gcvSTATUS_INVALID_ADDRESS = -8,
  155673. + gcvSTATUS_CONTEXT_LOSSED = -9,
  155674. + gcvSTATUS_TOO_COMPLEX = -10,
  155675. + gcvSTATUS_BUFFER_TOO_SMALL = -11,
  155676. + gcvSTATUS_INTERFACE_ERROR = -12,
  155677. + gcvSTATUS_NOT_SUPPORTED = -13,
  155678. + gcvSTATUS_MORE_DATA = -14,
  155679. + gcvSTATUS_TIMEOUT = -15,
  155680. + gcvSTATUS_OUT_OF_RESOURCES = -16,
  155681. + gcvSTATUS_INVALID_DATA = -17,
  155682. + gcvSTATUS_INVALID_MIPMAP = -18,
  155683. + gcvSTATUS_NOT_FOUND = -19,
  155684. + gcvSTATUS_NOT_ALIGNED = -20,
  155685. + gcvSTATUS_INVALID_REQUEST = -21,
  155686. + gcvSTATUS_GPU_NOT_RESPONDING = -22,
  155687. + gcvSTATUS_TIMER_OVERFLOW = -23,
  155688. + gcvSTATUS_VERSION_MISMATCH = -24,
  155689. + gcvSTATUS_LOCKED = -25,
  155690. + gcvSTATUS_INTERRUPTED = -26,
  155691. + gcvSTATUS_DEVICE = -27,
  155692. + gcvSTATUS_NOT_MULTI_PIPE_ALIGNED = -28,
  155693. +
  155694. + /* Linker errors. */
  155695. + gcvSTATUS_GLOBAL_TYPE_MISMATCH = -1000,
  155696. + gcvSTATUS_TOO_MANY_ATTRIBUTES = -1001,
  155697. + gcvSTATUS_TOO_MANY_UNIFORMS = -1002,
  155698. + gcvSTATUS_TOO_MANY_VARYINGS = -1003,
  155699. + gcvSTATUS_UNDECLARED_VARYING = -1004,
  155700. + gcvSTATUS_VARYING_TYPE_MISMATCH = -1005,
  155701. + gcvSTATUS_MISSING_MAIN = -1006,
  155702. + gcvSTATUS_NAME_MISMATCH = -1007,
  155703. + gcvSTATUS_INVALID_INDEX = -1008,
  155704. + gcvSTATUS_UNIFORM_TYPE_MISMATCH = -1009,
  155705. +
  155706. + /* Compiler errors. */
  155707. + gcvSTATUS_COMPILER_FE_PREPROCESSOR_ERROR = -2000,
  155708. + gcvSTATUS_COMPILER_FE_PARSER_ERROR = -2001,
  155709. +}
  155710. +gceSTATUS;
  155711. +
  155712. +/******************************************************************************\
  155713. +********************************* Status Macros ********************************
  155714. +\******************************************************************************/
  155715. +
  155716. +#define gcmIS_ERROR(status) (status < 0)
  155717. +#define gcmNO_ERROR(status) (status >= 0)
  155718. +#define gcmIS_SUCCESS(status) (status == gcvSTATUS_OK)
  155719. +
  155720. +/******************************************************************************\
  155721. +********************************* Field Macros *********************************
  155722. +\******************************************************************************/
  155723. +
  155724. +#define __gcmSTART(reg_field) \
  155725. + (0 ? reg_field)
  155726. +
  155727. +#define __gcmEND(reg_field) \
  155728. + (1 ? reg_field)
  155729. +
  155730. +#define __gcmGETSIZE(reg_field) \
  155731. + (__gcmEND(reg_field) - __gcmSTART(reg_field) + 1)
  155732. +
  155733. +#define __gcmALIGN(data, reg_field) \
  155734. + (((gctUINT32) (data)) << __gcmSTART(reg_field))
  155735. +
  155736. +#define __gcmMASK(reg_field) \
  155737. + ((gctUINT32) ((__gcmGETSIZE(reg_field) == 32) \
  155738. + ? ~0 \
  155739. + : (~(~0 << __gcmGETSIZE(reg_field)))))
  155740. +
  155741. +/*******************************************************************************
  155742. +**
  155743. +** gcmFIELDMASK
  155744. +**
  155745. +** Get aligned field mask.
  155746. +**
  155747. +** ARGUMENTS:
  155748. +**
  155749. +** reg Name of register.
  155750. +** field Name of field within register.
  155751. +*/
  155752. +#define gcmFIELDMASK(reg, field) \
  155753. +( \
  155754. + __gcmALIGN(__gcmMASK(reg##_##field), reg##_##field) \
  155755. +)
  155756. +
  155757. +/*******************************************************************************
  155758. +**
  155759. +** gcmGETFIELD
  155760. +**
  155761. +** Extract the value of a field from specified data.
  155762. +**
  155763. +** ARGUMENTS:
  155764. +**
  155765. +** data Data value.
  155766. +** reg Name of register.
  155767. +** field Name of field within register.
  155768. +*/
  155769. +#define gcmGETFIELD(data, reg, field) \
  155770. +( \
  155771. + ((((gctUINT32) (data)) >> __gcmSTART(reg##_##field)) \
  155772. + & __gcmMASK(reg##_##field)) \
  155773. +)
  155774. +
  155775. +/*******************************************************************************
  155776. +**
  155777. +** gcmSETFIELD
  155778. +**
  155779. +** Set the value of a field within specified data.
  155780. +**
  155781. +** ARGUMENTS:
  155782. +**
  155783. +** data Data value.
  155784. +** reg Name of register.
  155785. +** field Name of field within register.
  155786. +** value Value for field.
  155787. +*/
  155788. +#define gcmSETFIELD(data, reg, field, value) \
  155789. +( \
  155790. + (((gctUINT32) (data)) \
  155791. + & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
  155792. + | __gcmALIGN((gctUINT32) (value) \
  155793. + & __gcmMASK(reg##_##field), reg##_##field) \
  155794. +)
  155795. +
  155796. +/*******************************************************************************
  155797. +**
  155798. +** gcmSETFIELDVALUE
  155799. +**
  155800. +** Set the value of a field within specified data with a
  155801. +** predefined value.
  155802. +**
  155803. +** ARGUMENTS:
  155804. +**
  155805. +** data Data value.
  155806. +** reg Name of register.
  155807. +** field Name of field within register.
  155808. +** value Name of the value within the field.
  155809. +*/
  155810. +#define gcmSETFIELDVALUE(data, reg, field, value) \
  155811. +( \
  155812. + (((gctUINT32) (data)) \
  155813. + & ~__gcmALIGN(__gcmMASK(reg##_##field), reg##_##field)) \
  155814. + | __gcmALIGN(reg##_##field##_##value \
  155815. + & __gcmMASK(reg##_##field), reg##_##field) \
  155816. +)
  155817. +
  155818. +/*******************************************************************************
  155819. +**
  155820. +** gcmGETMASKEDFIELDMASK
  155821. +**
  155822. +** Determine field mask of a masked field.
  155823. +**
  155824. +** ARGUMENTS:
  155825. +**
  155826. +** reg Name of register.
  155827. +** field Name of field within register.
  155828. +*/
  155829. +#define gcmGETMASKEDFIELDMASK(reg, field) \
  155830. +( \
  155831. + gcmSETFIELD(0, reg, field, ~0) | \
  155832. + gcmSETFIELD(0, reg, MASK_ ## field, ~0) \
  155833. +)
  155834. +
  155835. +/*******************************************************************************
  155836. +**
  155837. +** gcmSETMASKEDFIELD
  155838. +**
  155839. +** Set the value of a masked field with specified data.
  155840. +**
  155841. +** ARGUMENTS:
  155842. +**
  155843. +** reg Name of register.
  155844. +** field Name of field within register.
  155845. +** value Value for field.
  155846. +*/
  155847. +#define gcmSETMASKEDFIELD(reg, field, value) \
  155848. +( \
  155849. + gcmSETFIELD (~0, reg, field, value) & \
  155850. + gcmSETFIELDVALUE(~0, reg, MASK_ ## field, ENABLED) \
  155851. +)
  155852. +
  155853. +/*******************************************************************************
  155854. +**
  155855. +** gcmSETMASKEDFIELDVALUE
  155856. +**
  155857. +** Set the value of a masked field with specified data.
  155858. +**
  155859. +** ARGUMENTS:
  155860. +**
  155861. +** reg Name of register.
  155862. +** field Name of field within register.
  155863. +** value Value for field.
  155864. +*/
  155865. +#define gcmSETMASKEDFIELDVALUE(reg, field, value) \
  155866. +( \
  155867. + gcmSETFIELDVALUE(~0, reg, field, value) & \
  155868. + gcmSETFIELDVALUE(~0, reg, MASK_ ## field, ENABLED) \
  155869. +)
  155870. +
  155871. +/*******************************************************************************
  155872. +**
  155873. +** gcmVERIFYFIELDVALUE
  155874. +**
  155875. +** Verify if the value of a field within specified data equals a
  155876. +** predefined value.
  155877. +**
  155878. +** ARGUMENTS:
  155879. +**
  155880. +** data Data value.
  155881. +** reg Name of register.
  155882. +** field Name of field within register.
  155883. +** value Name of the value within the field.
  155884. +*/
  155885. +#define gcmVERIFYFIELDVALUE(data, reg, field, value) \
  155886. +( \
  155887. + (((gctUINT32) (data)) >> __gcmSTART(reg##_##field) & \
  155888. + __gcmMASK(reg##_##field)) \
  155889. + == \
  155890. + (reg##_##field##_##value & __gcmMASK(reg##_##field)) \
  155891. +)
  155892. +
  155893. +/*******************************************************************************
  155894. +** Bit field macros.
  155895. +*/
  155896. +
  155897. +#define __gcmSTARTBIT(Field) \
  155898. + ( 1 ? Field )
  155899. +
  155900. +#define __gcmBITSIZE(Field) \
  155901. + ( 0 ? Field )
  155902. +
  155903. +#define __gcmBITMASK(Field) \
  155904. +( \
  155905. + (1 << __gcmBITSIZE(Field)) - 1 \
  155906. +)
  155907. +
  155908. +#define gcmGETBITS(Value, Type, Field) \
  155909. +( \
  155910. + ( ((Type) (Value)) >> __gcmSTARTBIT(Field) ) \
  155911. + & \
  155912. + __gcmBITMASK(Field) \
  155913. +)
  155914. +
  155915. +#define gcmSETBITS(Value, Type, Field, NewValue) \
  155916. +( \
  155917. + ( ((Type) (Value)) \
  155918. + & ~(__gcmBITMASK(Field) << __gcmSTARTBIT(Field)) \
  155919. + ) \
  155920. + | \
  155921. + ( ( ((Type) (NewValue)) \
  155922. + & __gcmBITMASK(Field) \
  155923. + ) << __gcmSTARTBIT(Field) \
  155924. + ) \
  155925. +)
  155926. +
  155927. +/*******************************************************************************
  155928. +**
  155929. +** gcmISINREGRANGE
  155930. +**
  155931. +** Verify whether the specified address is in the register range.
  155932. +**
  155933. +** ARGUMENTS:
  155934. +**
  155935. +** Address Address to be verified.
  155936. +** Name Name of a register.
  155937. +*/
  155938. +
  155939. +#define gcmISINREGRANGE(Address, Name) \
  155940. +( \
  155941. + ((Address & (~0U << Name ## _LSB)) == (Name ## _Address >> 2)) \
  155942. +)
  155943. +
  155944. +/*******************************************************************************
  155945. +**
  155946. +** A set of macros to aid state loading.
  155947. +**
  155948. +** ARGUMENTS:
  155949. +**
  155950. +** CommandBuffer Pointer to a gcoCMDBUF object.
  155951. +** StateDelta Pointer to a gcsSTATE_DELTA state delta structure.
  155952. +** Memory Destination memory pointer of gctUINT32_PTR type.
  155953. +** PartOfContext Whether or not the state is a part of the context.
  155954. +** FixedPoint Whether or not the state is of the fixed point format.
  155955. +** Count Number of consecutive states to be loaded.
  155956. +** Address State address.
  155957. +** Data Data to be set to the state.
  155958. +*/
  155959. +
  155960. +/*----------------------------------------------------------------------------*/
  155961. +
  155962. +#if gcmIS_DEBUG(gcdDEBUG_CODE)
  155963. +
  155964. +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count) \
  155965. + CommandBuffer->lastLoadStatePtr = gcmPTR_TO_UINT64(Memory); \
  155966. + CommandBuffer->lastLoadStateAddress = Address; \
  155967. + CommandBuffer->lastLoadStateCount = Count
  155968. +
  155969. +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address) \
  155970. + gcmASSERT( \
  155971. + (gctUINT) (Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastLoadStatePtr, gctUINT32_PTR) - 1) \
  155972. + == \
  155973. + (gctUINT) (Address - CommandBuffer->lastLoadStateAddress) \
  155974. + ); \
  155975. + \
  155976. + gcmASSERT(CommandBuffer->lastLoadStateCount > 0); \
  155977. + \
  155978. + CommandBuffer->lastLoadStateCount -= 1
  155979. +
  155980. +# define gcmVERIFYLOADSTATEDONE(CommandBuffer) \
  155981. + gcmASSERT(CommandBuffer->lastLoadStateCount == 0)
  155982. +
  155983. +#else
  155984. +
  155985. +# define gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count)
  155986. +# define gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address)
  155987. +# define gcmVERIFYLOADSTATEDONE(CommandBuffer)
  155988. +
  155989. +#endif
  155990. +
  155991. +#if gcdSECURE_USER
  155992. +
  155993. +# define gcmDEFINESECUREUSER() \
  155994. + gctUINT __secure_user_offset__; \
  155995. + gctUINT32_PTR __secure_user_hintArray__;
  155996. +
  155997. +# define gcmBEGINSECUREUSER() \
  155998. + __secure_user_offset__ = reserve->lastOffset; \
  155999. + \
  156000. + __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
  156001. +
  156002. +# define gcmENDSECUREUSER() \
  156003. + reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
  156004. +
  156005. +# define gcmSKIPSECUREUSER() \
  156006. + __secure_user_offset__ += gcmSIZEOF(gctUINT32)
  156007. +
  156008. +# define gcmUPDATESECUREUSER() \
  156009. + *__secure_user_hintArray__ = __secure_user_offset__; \
  156010. + \
  156011. + __secure_user_offset__ += gcmSIZEOF(gctUINT32); \
  156012. + __secure_user_hintArray__ += 1
  156013. +
  156014. +#else
  156015. +
  156016. +# define gcmDEFINESECUREUSER()
  156017. +# define gcmBEGINSECUREUSER()
  156018. +# define gcmENDSECUREUSER()
  156019. +# define gcmSKIPSECUREUSER()
  156020. +# define gcmUPDATESECUREUSER()
  156021. +
  156022. +#endif
  156023. +
  156024. +/*----------------------------------------------------------------------------*/
  156025. +
  156026. +#if gcdDUMP
  156027. +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \
  156028. + if (FixedPoint) \
  156029. + { \
  156030. + gcmDUMP(gcvNULL, "@[state.x 0x%04X 0x%08X]", \
  156031. + Address, Data \
  156032. + ); \
  156033. + } \
  156034. + else \
  156035. + { \
  156036. + gcmDUMP(gcvNULL, "@[state 0x%04X 0x%08X]", \
  156037. + Address, Data \
  156038. + ); \
  156039. + }
  156040. +#else
  156041. +# define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
  156042. +#endif
  156043. +
  156044. +/*----------------------------------------------------------------------------*/
  156045. +
  156046. +#define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
  156047. + gcmDEFINESECUREUSER() \
  156048. + gctSIZE_T ReserveSize; \
  156049. + gcoCMDBUF CommandBuffer; \
  156050. + gctUINT32_PTR Memory; \
  156051. + gcsSTATE_DELTA_PTR StateDelta
  156052. +
  156053. +#define gcmBEGINSTATEBUFFER(Hardware, CommandBuffer, StateDelta, Memory, ReserveSize) \
  156054. +{ \
  156055. + gcmONERROR(gcoBUFFER_Reserve( \
  156056. + Hardware->buffer, ReserveSize, gcvTRUE, &CommandBuffer \
  156057. + )); \
  156058. + \
  156059. + Memory = gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
  156060. + \
  156061. + StateDelta = Hardware->delta; \
  156062. + \
  156063. + gcmBEGINSECUREUSER(); \
  156064. +}
  156065. +
  156066. +#define gcmENDSTATEBUFFER(CommandBuffer, Memory, ReserveSize) \
  156067. +{ \
  156068. + gcmENDSECUREUSER(); \
  156069. + \
  156070. + gcmASSERT( \
  156071. + gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
  156072. + == \
  156073. + (gctUINT8_PTR) Memory \
  156074. + ); \
  156075. +}
  156076. +
  156077. +/*----------------------------------------------------------------------------*/
  156078. +
  156079. +#define gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, Count) \
  156080. +{ \
  156081. + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
  156082. + gcmASSERT((gctUINT32)Count <= 1024); \
  156083. + \
  156084. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  156085. + \
  156086. + gcmSTORELOADSTATE(CommandBuffer, Memory, Address, Count); \
  156087. + \
  156088. + *Memory++ \
  156089. + = gcmSETFIELDVALUE(0, AQ_COMMAND_LOAD_STATE_COMMAND, OPCODE, LOAD_STATE) \
  156090. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
  156091. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
  156092. + | gcmSETFIELD (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
  156093. + \
  156094. + gcmSKIPSECUREUSER(); \
  156095. +}
  156096. +
  156097. +#define gcmENDSTATEBATCH(CommandBuffer, Memory) \
  156098. +{ \
  156099. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  156100. + \
  156101. + gcmASSERT(((Memory - gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT32_PTR)) & 1) == 0); \
  156102. +}
  156103. +
  156104. +/*----------------------------------------------------------------------------*/
  156105. +
  156106. +#define gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
  156107. + Address, Data) \
  156108. +{ \
  156109. + gctUINT32 __temp_data32__; \
  156110. + \
  156111. + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
  156112. + \
  156113. + __temp_data32__ = Data; \
  156114. + \
  156115. + *Memory++ = __temp_data32__; \
  156116. + \
  156117. + gcoHARDWARE_UpdateDelta( \
  156118. + StateDelta, FixedPoint, Address, 0, __temp_data32__ \
  156119. + ); \
  156120. + \
  156121. + gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
  156122. + \
  156123. + gcmUPDATESECUREUSER(); \
  156124. +}
  156125. +
  156126. +#define gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data) \
  156127. +{ \
  156128. + gctUINT32 __temp_data32__; \
  156129. + \
  156130. + gcmVERIFYLOADSTATE(CommandBuffer, Memory, Address); \
  156131. + \
  156132. + __temp_data32__ = Data; \
  156133. + \
  156134. + *Memory++ = __temp_data32__; \
  156135. + \
  156136. + gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
  156137. + \
  156138. + gcmSKIPSECUREUSER(); \
  156139. +}
  156140. +
  156141. +#define gcmSETFILLER(CommandBuffer, Memory) \
  156142. +{ \
  156143. + gcmVERIFYLOADSTATEDONE(CommandBuffer); \
  156144. + \
  156145. + Memory += 1; \
  156146. + \
  156147. + gcmSKIPSECUREUSER(); \
  156148. +}
  156149. +
  156150. +/*----------------------------------------------------------------------------*/
  156151. +
  156152. +#define gcmSETSINGLESTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
  156153. + Address, Data) \
  156154. +{ \
  156155. + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
  156156. + gcmSETSTATEDATA(StateDelta, CommandBuffer, Memory, FixedPoint, \
  156157. + Address, Data); \
  156158. + gcmENDSTATEBATCH(CommandBuffer, Memory); \
  156159. +}
  156160. +
  156161. +#define gcmSETSINGLECTRLSTATE(StateDelta, CommandBuffer, Memory, FixedPoint, \
  156162. + Address, Data) \
  156163. +{ \
  156164. + gcmBEGINSTATEBATCH(CommandBuffer, Memory, FixedPoint, Address, 1); \
  156165. + gcmSETCTRLSTATE(StateDelta, CommandBuffer, Memory, Address, Data); \
  156166. + gcmENDSTATEBATCH(CommandBuffer, Memory); \
  156167. +}
  156168. +
  156169. +
  156170. +/*******************************************************************************
  156171. +**
  156172. +** gcmSETSTARTDECOMMAND
  156173. +**
  156174. +** Form a START_DE command.
  156175. +**
  156176. +** ARGUMENTS:
  156177. +**
  156178. +** Memory Destination memory pointer of gctUINT32_PTR type.
  156179. +** Count Number of the rectangles.
  156180. +*/
  156181. +
  156182. +#define gcmSETSTARTDECOMMAND(Memory, Count) \
  156183. +{ \
  156184. + *Memory++ \
  156185. + = gcmSETFIELDVALUE(0, AQ_COMMAND_START_DE_COMMAND, OPCODE, START_DE) \
  156186. + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, COUNT, Count) \
  156187. + | gcmSETFIELD (0, AQ_COMMAND_START_DE_COMMAND, DATA_COUNT, 0); \
  156188. + \
  156189. + *Memory++ = 0xDEADDEED; \
  156190. +}
  156191. +
  156192. +/******************************************************************************\
  156193. +******************************** Ceiling Macro ********************************
  156194. +\******************************************************************************/
  156195. +#define gcmCEIL(x) ((x - (gctUINT32)x) == 0 ? (gctUINT32)x : (gctUINT32)x + 1)
  156196. +
  156197. +/******************************************************************************\
  156198. +******************************** Min/Max Macros ********************************
  156199. +\******************************************************************************/
  156200. +
  156201. +#define gcmMIN(x, y) (((x) <= (y)) ? (x) : (y))
  156202. +#define gcmMAX(x, y) (((x) >= (y)) ? (x) : (y))
  156203. +#define gcmCLAMP(x, min, max) (((x) < (min)) ? (min) : \
  156204. + ((x) > (max)) ? (max) : (x))
  156205. +#define gcmABS(x) (((x) < 0) ? -(x) : (x))
  156206. +#define gcmNEG(x) (((x) < 0) ? (x) : -(x))
  156207. +
  156208. +/*******************************************************************************
  156209. +**
  156210. +** gcmPTR2INT
  156211. +**
  156212. +** Convert a pointer to an integer value.
  156213. +**
  156214. +** ARGUMENTS:
  156215. +**
  156216. +** p Pointer value.
  156217. +*/
  156218. +#if defined(_WIN32) || (defined(__LP64__) && __LP64__)
  156219. +# define gcmPTR2INT(p) \
  156220. + ( \
  156221. + (gctUINT32) (gctUINT64) (p) \
  156222. + )
  156223. +#else
  156224. +# define gcmPTR2INT(p) \
  156225. + ( \
  156226. + (gctUINT32) (p) \
  156227. + )
  156228. +#endif
  156229. +
  156230. +/*******************************************************************************
  156231. +**
  156232. +** gcmINT2PTR
  156233. +**
  156234. +** Convert an integer value into a pointer.
  156235. +**
  156236. +** ARGUMENTS:
  156237. +**
  156238. +** v Integer value.
  156239. +*/
  156240. +#ifdef __LP64__
  156241. +# define gcmINT2PTR(i) \
  156242. + ( \
  156243. + (gctPOINTER) (gctINT64) (i) \
  156244. + )
  156245. +#else
  156246. +# define gcmINT2PTR(i) \
  156247. + ( \
  156248. + (gctPOINTER) (i) \
  156249. + )
  156250. +#endif
  156251. +
  156252. +/*******************************************************************************
  156253. +**
  156254. +** gcmOFFSETOF
  156255. +**
  156256. +** Compute the byte offset of a field inside a structure.
  156257. +**
  156258. +** ARGUMENTS:
  156259. +**
  156260. +** s Structure name.
  156261. +** field Field name.
  156262. +*/
  156263. +#define gcmOFFSETOF(s, field) \
  156264. +( \
  156265. + gcmPTR2INT(& (((struct s *) 0)->field)) \
  156266. +)
  156267. +
  156268. +#define gcmSWAB32(x) ((gctUINT32)( \
  156269. + (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
  156270. + (((gctUINT32)(x) & (gctUINT32)0x0000FF00UL) << 8) | \
  156271. + (((gctUINT32)(x) & (gctUINT32)0x00FF0000UL) >> 8) | \
  156272. + (((gctUINT32)(x) & (gctUINT32)0xFF000000UL) >> 24)))
  156273. +
  156274. +/*******************************************************************************
  156275. +***** Database ****************************************************************/
  156276. +
  156277. +typedef struct _gcsDATABASE_COUNTERS
  156278. +{
  156279. + /* Number of currently allocated bytes. */
  156280. + gctUINT64 bytes;
  156281. +
  156282. + /* Maximum number of bytes allocated (memory footprint). */
  156283. + gctUINT64 maxBytes;
  156284. +
  156285. + /* Total number of bytes allocated. */
  156286. + gctUINT64 totalBytes;
  156287. +}
  156288. +gcsDATABASE_COUNTERS;
  156289. +
  156290. +typedef struct _gcuDATABASE_INFO
  156291. +{
  156292. + /* Counters. */
  156293. + gcsDATABASE_COUNTERS counters;
  156294. +
  156295. + /* Time value. */
  156296. + gctUINT64 time;
  156297. +}
  156298. +gcuDATABASE_INFO;
  156299. +
  156300. +/*******************************************************************************
  156301. +***** Frame database **********************************************************/
  156302. +
  156303. +/* gcsHAL_FRAME_INFO */
  156304. +typedef struct _gcsHAL_FRAME_INFO
  156305. +{
  156306. + /* Current timer tick. */
  156307. + OUT gctUINT64 ticks;
  156308. +
  156309. + /* Bandwidth counters. */
  156310. + OUT gctUINT readBytes8[8];
  156311. + OUT gctUINT writeBytes8[8];
  156312. +
  156313. + /* Counters. */
  156314. + OUT gctUINT cycles[8];
  156315. + OUT gctUINT idleCycles[8];
  156316. + OUT gctUINT mcCycles[8];
  156317. + OUT gctUINT readRequests[8];
  156318. + OUT gctUINT writeRequests[8];
  156319. +
  156320. + /* FE counters. */
  156321. + OUT gctUINT drawCount;
  156322. + OUT gctUINT vertexOutCount;
  156323. + OUT gctUINT vertexMissCount;
  156324. +
  156325. + /* 3D counters. */
  156326. + OUT gctUINT vertexCount;
  156327. + OUT gctUINT primitiveCount;
  156328. + OUT gctUINT rejectedPrimitives;
  156329. + OUT gctUINT culledPrimitives;
  156330. + OUT gctUINT clippedPrimitives;
  156331. + OUT gctUINT droppedPrimitives;
  156332. + OUT gctUINT frustumClippedPrimitives;
  156333. + OUT gctUINT outPrimitives;
  156334. + OUT gctUINT inPrimitives;
  156335. + OUT gctUINT culledQuadCount;
  156336. + OUT gctUINT totalQuadCount;
  156337. + OUT gctUINT quadCount;
  156338. + OUT gctUINT totalPixelCount;
  156339. +
  156340. + /* PE counters. */
  156341. + OUT gctUINT colorKilled[8];
  156342. + OUT gctUINT colorDrawn[8];
  156343. + OUT gctUINT depthKilled[8];
  156344. + OUT gctUINT depthDrawn[8];
  156345. +
  156346. + /* Shader counters. */
  156347. + OUT gctUINT shaderCycles;
  156348. + OUT gctUINT vsInstructionCount;
  156349. + OUT gctUINT vsTextureCount;
  156350. + OUT gctUINT vsBranchCount;
  156351. + OUT gctUINT vsVertices;
  156352. + OUT gctUINT psInstructionCount;
  156353. + OUT gctUINT psTextureCount;
  156354. + OUT gctUINT psBranchCount;
  156355. + OUT gctUINT psPixels;
  156356. +
  156357. + /* Texture counters. */
  156358. + OUT gctUINT bilinearRequests;
  156359. + OUT gctUINT trilinearRequests;
  156360. + OUT gctUINT txBytes8[2];
  156361. + OUT gctUINT txHitCount;
  156362. + OUT gctUINT txMissCount;
  156363. +}
  156364. +gcsHAL_FRAME_INFO;
  156365. +
  156366. +typedef enum _gcePATCH_ID
  156367. +{
  156368. + gcePATCH_UNKNOWN = 0xFFFFFFFF,
  156369. +
  156370. + /* Benchmark list*/
  156371. + gcePATCH_GLB11 = 0x0,
  156372. + gcePATCH_GLB21,
  156373. + gcePATCH_GLB25,
  156374. + gcePATCH_GLB27,
  156375. +
  156376. + gcePATCH_BM21,
  156377. + gcePATCH_MM,
  156378. + gcePATCH_MM06,
  156379. + gcePATCH_MM07,
  156380. + gcePATCH_QUADRANT,
  156381. + gcePATCH_ANTUTU,
  156382. + gcePATCH_SMARTBENCH,
  156383. + gcePATCH_JPCT,
  156384. + gcePATCH_NENAMARK,
  156385. + gcePATCH_NENAMARK2,
  156386. + gcePATCH_NEOCORE,
  156387. + gcePATCH_GLB,
  156388. + gcePATCH_GB,
  156389. + gcePATCH_RTESTVA,
  156390. + gcePATCH_BMX,
  156391. + gcePATCH_BMGUI,
  156392. +
  156393. + /* Game list */
  156394. + gcePATCH_NBA2013,
  156395. + gcePATCH_BARDTALE,
  156396. + gcePATCH_BUSPARKING3D,
  156397. + gcePATCH_FISHBOODLE,
  156398. + gcePATCH_SUBWAYSURFER,
  156399. + gcePATCH_HIGHWAYDRIVER,
  156400. + gcePATCH_PREMIUM,
  156401. + gcePATCH_RACEILLEGAL,
  156402. + gcePATCH_BLABLA,
  156403. + gcePATCH_MEGARUN,
  156404. + gcePATCH_GALAXYONFIRE2,
  156405. + gcePATCH_GLOFTR3HM,
  156406. + gcePATCH_GLOFTSXHM,
  156407. + gcePATCH_GLOFTF3HM,
  156408. + gcePATCH_GLOFTGANG,
  156409. + gcePATCH_XRUNNER,
  156410. + gcePATCH_WP,
  156411. + gcePATCH_DEVIL,
  156412. + gcePATCH_HOLYARCH,
  156413. + gcePATCH_MUSE,
  156414. + gcePATCH_SG,
  156415. + gcePATCH_SIEGECRAFT,
  156416. + gcePATCH_CARCHALLENGE,
  156417. + gcePATCH_HEROESCALL,
  156418. + gcePATCH_MONOPOLY,
  156419. + gcePATCH_CTGL20,
  156420. + gcePATCH_FIREFOX,
  156421. + gcePATCH_CHORME,
  156422. + gcePATCH_DUOKANTV,
  156423. + gcePATCH_TESTAPP,
  156424. + gcePATCH_GOOGLEEARTH,
  156425. +
  156426. + /* Count enum*/
  156427. + gcePATCH_COUNT,
  156428. +}
  156429. +gcePATCH_ID;
  156430. +
  156431. +#if gcdLINK_QUEUE_SIZE
  156432. +typedef struct _gckLINKDATA * gckLINKDATA;
  156433. +struct _gckLINKDATA
  156434. +{
  156435. + gctUINT32 start;
  156436. + gctUINT32 end;
  156437. + gctINT pid;
  156438. +};
  156439. +
  156440. +typedef struct _gckLINKQUEUE * gckLINKQUEUE;
  156441. +struct _gckLINKQUEUE
  156442. +{
  156443. + struct _gckLINKDATA data[gcdLINK_QUEUE_SIZE];
  156444. + gctUINT32 rear;
  156445. + gctUINT32 front;
  156446. + gctUINT32 count;
  156447. +};
  156448. +#endif
  156449. +
  156450. +#ifdef __cplusplus
  156451. +}
  156452. +#endif
  156453. +
  156454. +#endif /* __gc_hal_types_h_ */
  156455. diff -Nur linux-3.14.17/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
  156456. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h 1970-01-01 01:00:00.000000000 +0100
  156457. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h 2014-09-11 18:06:03.122042450 +0200
  156458. @@ -0,0 +1,37 @@
  156459. +/****************************************************************************
  156460. +*
  156461. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  156462. +*
  156463. +* This program is free software; you can redistribute it and/or modify
  156464. +* it under the terms of the GNU General Public License as published by
  156465. +* the Free Software Foundation; either version 2 of the license, or
  156466. +* (at your option) any later version.
  156467. +*
  156468. +* This program is distributed in the hope that it will be useful,
  156469. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  156470. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  156471. +* GNU General Public License for more details.
  156472. +*
  156473. +* You should have received a copy of the GNU General Public License
  156474. +* along with this program; if not write to the Free Software
  156475. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  156476. +*
  156477. +*****************************************************************************/
  156478. +
  156479. +
  156480. +#ifndef __gc_hal_version_h_
  156481. +#define __gc_hal_version_h_
  156482. +
  156483. +#define gcvVERSION_MAJOR 4
  156484. +
  156485. +#define gcvVERSION_MINOR 6
  156486. +
  156487. +#define gcvVERSION_PATCH 9
  156488. +
  156489. +#define gcvVERSION_BUILD 9754
  156490. +
  156491. +#define gcvVERSION_DATE __DATE__
  156492. +
  156493. +#define gcvVERSION_TIME __TIME__
  156494. +
  156495. +#endif /* __gc_hal_version_h_ */
  156496. diff -Nur linux-3.14.17/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
  156497. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h 1970-01-01 01:00:00.000000000 +0100
  156498. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h 2014-09-11 18:06:03.122042450 +0200
  156499. @@ -0,0 +1,913 @@
  156500. +/****************************************************************************
  156501. +*
  156502. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  156503. +*
  156504. +* This program is free software; you can redistribute it and/or modify
  156505. +* it under the terms of the GNU General Public License as published by
  156506. +* the Free Software Foundation; either version 2 of the license, or
  156507. +* (at your option) any later version.
  156508. +*
  156509. +* This program is distributed in the hope that it will be useful,
  156510. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  156511. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  156512. +* GNU General Public License for more details.
  156513. +*
  156514. +* You should have received a copy of the GNU General Public License
  156515. +* along with this program; if not write to the Free Software
  156516. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  156517. +*
  156518. +*****************************************************************************/
  156519. +
  156520. +
  156521. +#ifndef __gc_hal_vg_h_
  156522. +#define __gc_hal_vg_h_
  156523. +
  156524. +#ifdef __cplusplus
  156525. +extern "C" {
  156526. +#endif
  156527. +
  156528. +
  156529. +#include "gc_hal_rename.h"
  156530. +#include "gc_hal_types.h"
  156531. +#include "gc_hal_enum.h"
  156532. +#include "gc_hal_base.h"
  156533. +
  156534. +#if gcdENABLE_VG
  156535. +
  156536. +/* Thread routine type. */
  156537. +#if defined(LINUX)
  156538. + typedef gctINT gctTHREADFUNCRESULT;
  156539. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  156540. +# define gctTHREADFUNCTYPE
  156541. +#elif defined(WIN32)
  156542. + typedef gctUINT gctTHREADFUNCRESULT;
  156543. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  156544. +# define gctTHREADFUNCTYPE __stdcall
  156545. +#elif defined(__QNXNTO__)
  156546. + typedef void * gctTHREADFUNCRESULT;
  156547. + typedef gctPOINTER gctTHREADFUNCPARAMETER;
  156548. +# define gctTHREADFUNCTYPE
  156549. +#endif
  156550. +
  156551. +typedef gctTHREADFUNCRESULT (gctTHREADFUNCTYPE * gctTHREADFUNC) (
  156552. + gctTHREADFUNCPARAMETER ThreadParameter
  156553. + );
  156554. +
  156555. +
  156556. +#if defined(gcvDEBUG)
  156557. +# undef gcvDEBUG
  156558. +#endif
  156559. +
  156560. +#define gcdFORCE_DEBUG 0
  156561. +#define gcdFORCE_MESSAGES 0
  156562. +
  156563. +
  156564. +#if DBG || defined(DEBUG) || defined(_DEBUG) || gcdFORCE_DEBUG
  156565. +# define gcvDEBUG 1
  156566. +#else
  156567. +# define gcvDEBUG 0
  156568. +#endif
  156569. +
  156570. +#define _gcmERROR_RETURN(prefix, func) \
  156571. + status = func; \
  156572. + if (gcmIS_ERROR(status)) \
  156573. + { \
  156574. + prefix##PRINT_VERSION(); \
  156575. + prefix##TRACE(gcvLEVEL_ERROR, \
  156576. + #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
  156577. + status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
  156578. + return status; \
  156579. + } \
  156580. + do { } while (gcvFALSE)
  156581. +
  156582. +#define gcmERROR_RETURN(func) _gcmERROR_RETURN(gcm, func)
  156583. +
  156584. +#define gcmLOG_LOCATION()
  156585. +
  156586. +#define gcmkIS_ERROR(status) (status < 0)
  156587. +
  156588. +#define gcmALIGNDOWN(n, align) \
  156589. +( \
  156590. + (n) & ~((align) - 1) \
  156591. +)
  156592. +
  156593. +#define gcmIS_VALID_INDEX(Index, Array) \
  156594. + (((gctUINT) (Index)) < gcmCOUNTOF(Array))
  156595. +
  156596. +
  156597. +#define gcmIS_NAN(x) \
  156598. +( \
  156599. + ((* (gctUINT32_PTR) &(x)) & 0x7FFFFFFF) == 0x7FFFFFFF \
  156600. +)
  156601. +
  156602. +#define gcmLERP(v1, v2, w) \
  156603. + ((v1) * (w) + (v2) * (1.0f - (w)))
  156604. +
  156605. +#define gcmINTERSECT(Start1, Start2, Length) \
  156606. + (gcmABS((Start1) - (Start2)) < (Length))
  156607. +
  156608. +/*******************************************************************************
  156609. +**
  156610. +** gcmERR_GOTO
  156611. +**
  156612. +** Prints a message and terminates the current loop on error.
  156613. +**
  156614. +** ASSUMPTIONS:
  156615. +**
  156616. +** 'status' variable of gceSTATUS type must be defined.
  156617. +**
  156618. +** ARGUMENTS:
  156619. +**
  156620. +** Function
  156621. +** Function to evaluate.
  156622. +*/
  156623. +
  156624. +#define gcmERR_GOTO(Function) \
  156625. + status = Function; \
  156626. + if (gcmIS_ERROR(status)) \
  156627. + { \
  156628. + gcmTRACE( \
  156629. + gcvLEVEL_ERROR, \
  156630. + "gcmERR_GOTO: status=%d @ line=%d in function %s.\n", \
  156631. + status, __LINE__, __FUNCTION__ \
  156632. + ); \
  156633. + goto ErrorHandler; \
  156634. + }
  156635. +
  156636. +#if gcvDEBUG || gcdFORCE_MESSAGES
  156637. +# define gcmVERIFY_BOOLEAN(Expression) \
  156638. + gcmASSERT( \
  156639. + ( (Expression) == gcvFALSE ) || \
  156640. + ( (Expression) == gcvTRUE ) \
  156641. + )
  156642. +#else
  156643. +# define gcmVERIFY_BOOLEAN(Expression)
  156644. +#endif
  156645. +
  156646. +/*******************************************************************************
  156647. +**
  156648. +** gcmVERIFYFIELDFIT
  156649. +**
  156650. +** Verify whether the value fits in the field.
  156651. +**
  156652. +** ARGUMENTS:
  156653. +**
  156654. +** data Data value.
  156655. +** reg Name of register.
  156656. +** field Name of field within register.
  156657. +** value Value for field.
  156658. +*/
  156659. +#define gcmVERIFYFIELDFIT(reg, field, value) \
  156660. + gcmASSERT( \
  156661. + (value) <= gcmFIELDMAX(reg, field) \
  156662. + )
  156663. +/*******************************************************************************
  156664. +**
  156665. +** gcmFIELDMAX
  156666. +**
  156667. +** Get field maximum value.
  156668. +**
  156669. +** ARGUMENTS:
  156670. +**
  156671. +** reg Name of register.
  156672. +** field Name of field within register.
  156673. +*/
  156674. +#define gcmFIELDMAX(reg, field) \
  156675. +( \
  156676. + (gctUINT32) \
  156677. + ( \
  156678. + (__gcmGETSIZE(reg##_##field) == 32) \
  156679. + ? ~0 \
  156680. + : (~(~0 << __gcmGETSIZE(reg##_##field))) \
  156681. + ) \
  156682. +)
  156683. +
  156684. +
  156685. +/* ANSI C does not have the 'f' functions, define replacements here. */
  156686. +#define gcmSINF(x) ((gctFLOAT) sin(x))
  156687. +#define gcmCOSF(x) ((gctFLOAT) cos(x))
  156688. +#define gcmASINF(x) ((gctFLOAT) asin(x))
  156689. +#define gcmACOSF(x) ((gctFLOAT) acos(x))
  156690. +#define gcmSQRTF(x) ((gctFLOAT) sqrt(x))
  156691. +#define gcmFABSF(x) ((gctFLOAT) fabs(x))
  156692. +#define gcmFMODF(x, y) ((gctFLOAT) fmod((x), (y)))
  156693. +#define gcmCEILF(x) ((gctFLOAT) ceil(x))
  156694. +#define gcmFLOORF(x) ((gctFLOAT) floor(x))
  156695. +
  156696. +
  156697. +
  156698. +/* Fixed point constants. */
  156699. +#define gcvZERO_X ((gctFIXED_POINT) 0x00000000)
  156700. +#define gcvHALF_X ((gctFIXED_POINT) 0x00008000)
  156701. +#define gcvONE_X ((gctFIXED_POINT) 0x00010000)
  156702. +#define gcvNEGONE_X ((gctFIXED_POINT) 0xFFFF0000)
  156703. +#define gcvTWO_X ((gctFIXED_POINT) 0x00020000)
  156704. +
  156705. +/* Integer constants. */
  156706. +#define gcvMAX_POS_INT ((gctINT) 0x7FFFFFFF)
  156707. +#define gcvMAX_NEG_INT ((gctINT) 0x80000000)
  156708. +
  156709. +/* Float constants. */
  156710. +#define gcvMAX_POS_FLOAT ((gctFLOAT) 3.4028235e+038)
  156711. +#define gcvMAX_NEG_FLOAT ((gctFLOAT) -3.4028235e+038)
  156712. +
  156713. +/******************************************************************************\
  156714. +***************************** Miscellaneous Macro ******************************
  156715. +\******************************************************************************/
  156716. +
  156717. +#define gcmKB2BYTES(Kilobyte) \
  156718. +( \
  156719. + (Kilobyte) << 10 \
  156720. +)
  156721. +
  156722. +#define gcmMB2BYTES(Megabyte) \
  156723. +( \
  156724. + (Megabyte) << 20 \
  156725. +)
  156726. +
  156727. +#define gcmMAT(Matrix, Row, Column) \
  156728. +( \
  156729. + (Matrix) [(Row) * 3 + (Column)] \
  156730. +)
  156731. +
  156732. +#define gcmMAKE2CHAR(Char1, Char2) \
  156733. +( \
  156734. + ((gctUINT16) (gctUINT8) (Char1) << 0) | \
  156735. + ((gctUINT16) (gctUINT8) (Char2) << 8) \
  156736. +)
  156737. +
  156738. +#define gcmMAKE4CHAR(Char1, Char2, Char3, Char4) \
  156739. +( \
  156740. + ((gctUINT32)(gctUINT8) (Char1) << 0) | \
  156741. + ((gctUINT32)(gctUINT8) (Char2) << 8) | \
  156742. + ((gctUINT32)(gctUINT8) (Char3) << 16) | \
  156743. + ((gctUINT32)(gctUINT8) (Char4) << 24) \
  156744. +)
  156745. +
  156746. +/* some platforms need to fix the physical address for HW to access*/
  156747. +#define gcmFIXADDRESS(address) \
  156748. +(\
  156749. + (address)\
  156750. +)
  156751. +
  156752. +#define gcmkFIXADDRESS(address) \
  156753. +(\
  156754. + (address)\
  156755. +)
  156756. +
  156757. +/******************************************************************************\
  156758. +****************************** Kernel Debug Macro ******************************
  156759. +\******************************************************************************/
  156760. +
  156761. +/* Set signal to signaled state for specified process. */
  156762. +gceSTATUS
  156763. +gckOS_SetSignal(
  156764. + IN gckOS Os,
  156765. + IN gctHANDLE Process,
  156766. + IN gctSIGNAL Signal
  156767. + );
  156768. +
  156769. +/* Return the kernel logical pointer for the given physical one. */
  156770. +gceSTATUS
  156771. +gckOS_GetKernelLogical(
  156772. + IN gckOS Os,
  156773. + IN gctUINT32 Address,
  156774. + OUT gctPOINTER * KernelPointer
  156775. + );
  156776. +
  156777. +/* Return the kernel logical pointer for the given physical one. */
  156778. +gceSTATUS
  156779. +gckOS_GetKernelLogicalEx(
  156780. + IN gckOS Os,
  156781. + IN gceCORE Core,
  156782. + IN gctUINT32 Address,
  156783. + OUT gctPOINTER * KernelPointer
  156784. + );
  156785. +
  156786. +/*----------------------------------------------------------------------------*/
  156787. +/*----------------------------- Semaphore Object -----------------------------*/
  156788. +
  156789. +/* Increment the value of a semaphore. */
  156790. +gceSTATUS
  156791. +gckOS_IncrementSemaphore(
  156792. + IN gckOS Os,
  156793. + IN gctSEMAPHORE Semaphore
  156794. + );
  156795. +
  156796. +/* Decrement the value of a semaphore (waiting might occur). */
  156797. +gceSTATUS
  156798. +gckOS_DecrementSemaphore(
  156799. + IN gckOS Os,
  156800. + IN gctSEMAPHORE Semaphore
  156801. + );
  156802. +
  156803. +
  156804. +/*----------------------------------------------------------------------------*/
  156805. +/*------------------------------- Thread Object ------------------------------*/
  156806. +
  156807. +/* Start a thread. */
  156808. +gceSTATUS
  156809. +gckOS_StartThread(
  156810. + IN gckOS Os,
  156811. + IN gctTHREADFUNC ThreadFunction,
  156812. + IN gctPOINTER ThreadParameter,
  156813. + OUT gctTHREAD * Thread
  156814. + );
  156815. +
  156816. +/* Stop a thread. */
  156817. +gceSTATUS
  156818. +gckOS_StopThread(
  156819. + IN gckOS Os,
  156820. + IN gctTHREAD Thread
  156821. + );
  156822. +
  156823. +/* Verify whether the thread is still running. */
  156824. +gceSTATUS
  156825. +gckOS_VerifyThread(
  156826. + IN gckOS Os,
  156827. + IN gctTHREAD Thread
  156828. + );
  156829. +
  156830. +
  156831. +/* Construct a new gckVGKERNEL object. */
  156832. +gceSTATUS
  156833. +gckVGKERNEL_Construct(
  156834. + IN gckOS Os,
  156835. + IN gctPOINTER Context,
  156836. + IN gckKERNEL inKernel,
  156837. + OUT gckVGKERNEL * Kernel
  156838. + );
  156839. +
  156840. +/* Destroy an gckVGKERNEL object. */
  156841. +gceSTATUS
  156842. +gckVGKERNEL_Destroy(
  156843. + IN gckVGKERNEL Kernel
  156844. + );
  156845. +
  156846. +/* Allocate linear video memory. */
  156847. +gceSTATUS
  156848. +gckKERNEL_AllocateLinearMemory(
  156849. + IN gckKERNEL Kernel,
  156850. + IN OUT gcePOOL * Pool,
  156851. + IN gctSIZE_T Bytes,
  156852. + IN gctSIZE_T Alignment,
  156853. + IN gceSURF_TYPE Type,
  156854. + OUT gcuVIDMEM_NODE_PTR * Node
  156855. + );
  156856. +
  156857. +/* Unmap memory. */
  156858. +gceSTATUS
  156859. +gckKERNEL_UnmapMemory(
  156860. + IN gckKERNEL Kernel,
  156861. + IN gctPHYS_ADDR Physical,
  156862. + IN gctSIZE_T Bytes,
  156863. + IN gctPOINTER Logical
  156864. + );
  156865. +
  156866. +/* Dispatch a user-level command. */
  156867. +gceSTATUS
  156868. +gckVGKERNEL_Dispatch(
  156869. + IN gckKERNEL Kernel,
  156870. + IN gctBOOL FromUser,
  156871. + IN OUT struct _gcsHAL_INTERFACE * Interface
  156872. + );
  156873. +
  156874. +/* Query command buffer requirements. */
  156875. +gceSTATUS
  156876. +gckKERNEL_QueryCommandBuffer(
  156877. + IN gckKERNEL Kernel,
  156878. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  156879. + );
  156880. +
  156881. +#if gcdDYNAMIC_MAP_RESERVED_MEMORY
  156882. +gceSTATUS
  156883. +gckOS_MapReservedMemoryToKernel(
  156884. + IN gckOS Os,
  156885. + IN gctUINT32 Physical,
  156886. + IN gctINT Bytes,
  156887. + IN OUT gctPOINTER *Virtual
  156888. + );
  156889. +
  156890. +gceSTATUS
  156891. +gckOS_UnmapReservedMemoryFromKernel(
  156892. + IN gctPOINTER Virtual
  156893. + );
  156894. +#endif
  156895. +
  156896. +/******************************************************************************\
  156897. +******************************* gckVGHARDWARE Object ******************************
  156898. +\******************************************************************************/
  156899. +
  156900. +/* Construct a new gckVGHARDWARE object. */
  156901. +gceSTATUS
  156902. +gckVGHARDWARE_Construct(
  156903. + IN gckOS Os,
  156904. + OUT gckVGHARDWARE * Hardware
  156905. + );
  156906. +
  156907. +/* Destroy an gckVGHARDWARE object. */
  156908. +gceSTATUS
  156909. +gckVGHARDWARE_Destroy(
  156910. + IN gckVGHARDWARE Hardware
  156911. + );
  156912. +
  156913. +/* Query system memory requirements. */
  156914. +gceSTATUS
  156915. +gckVGHARDWARE_QuerySystemMemory(
  156916. + IN gckVGHARDWARE Hardware,
  156917. + OUT gctSIZE_T * SystemSize,
  156918. + OUT gctUINT32 * SystemBaseAddress
  156919. + );
  156920. +
  156921. +/* Build virtual address. */
  156922. +gceSTATUS
  156923. +gckVGHARDWARE_BuildVirtualAddress(
  156924. + IN gckVGHARDWARE Hardware,
  156925. + IN gctUINT32 Index,
  156926. + IN gctUINT32 Offset,
  156927. + OUT gctUINT32 * Address
  156928. + );
  156929. +
  156930. +/* Kickstart the command processor. */
  156931. +gceSTATUS
  156932. +gckVGHARDWARE_Execute(
  156933. + IN gckVGHARDWARE Hardware,
  156934. + IN gctUINT32 Address,
  156935. + IN gctSIZE_T Count
  156936. + );
  156937. +
  156938. +/* Query the available memory. */
  156939. +gceSTATUS
  156940. +gckVGHARDWARE_QueryMemory(
  156941. + IN gckVGHARDWARE Hardware,
  156942. + OUT gctSIZE_T * InternalSize,
  156943. + OUT gctUINT32 * InternalBaseAddress,
  156944. + OUT gctUINT32 * InternalAlignment,
  156945. + OUT gctSIZE_T * ExternalSize,
  156946. + OUT gctUINT32 * ExternalBaseAddress,
  156947. + OUT gctUINT32 * ExternalAlignment,
  156948. + OUT gctUINT32 * HorizontalTileSize,
  156949. + OUT gctUINT32 * VerticalTileSize
  156950. + );
  156951. +
  156952. +/* Query the identity of the hardware. */
  156953. +gceSTATUS
  156954. +gckVGHARDWARE_QueryChipIdentity(
  156955. + IN gckVGHARDWARE Hardware,
  156956. + OUT gceCHIPMODEL* ChipModel,
  156957. + OUT gctUINT32* ChipRevision,
  156958. + OUT gctUINT32* ChipFeatures,
  156959. + OUT gctUINT32* ChipMinorFeatures,
  156960. + OUT gctUINT32* ChipMinorFeatures1
  156961. + );
  156962. +
  156963. +/* Convert an API format. */
  156964. +gceSTATUS
  156965. +gckVGHARDWARE_ConvertFormat(
  156966. + IN gckVGHARDWARE Hardware,
  156967. + IN gceSURF_FORMAT Format,
  156968. + OUT gctUINT32 * BitsPerPixel,
  156969. + OUT gctUINT32 * BytesPerTile
  156970. + );
  156971. +
  156972. +/* Split a harwdare specific address into API stuff. */
  156973. +gceSTATUS
  156974. +gckVGHARDWARE_SplitMemory(
  156975. + IN gckVGHARDWARE Hardware,
  156976. + IN gctUINT32 Address,
  156977. + OUT gcePOOL * Pool,
  156978. + OUT gctUINT32 * Offset
  156979. + );
  156980. +
  156981. +/* Align size to tile boundary. */
  156982. +gceSTATUS
  156983. +gckVGHARDWARE_AlignToTile(
  156984. + IN gckVGHARDWARE Hardware,
  156985. + IN gceSURF_TYPE Type,
  156986. + IN OUT gctUINT32_PTR Width,
  156987. + IN OUT gctUINT32_PTR Height
  156988. + );
  156989. +
  156990. +/* Convert logical address to hardware specific address. */
  156991. +gceSTATUS
  156992. +gckVGHARDWARE_ConvertLogical(
  156993. + IN gckVGHARDWARE Hardware,
  156994. + IN gctPOINTER Logical,
  156995. + OUT gctUINT32 * Address
  156996. + );
  156997. +
  156998. +/* Program MMU. */
  156999. +gceSTATUS
  157000. +gckVGHARDWARE_SetMMU(
  157001. + IN gckVGHARDWARE Hardware,
  157002. + IN gctPOINTER Logical
  157003. + );
  157004. +
  157005. +/* Flush the MMU. */
  157006. +gceSTATUS
  157007. +gckVGHARDWARE_FlushMMU(
  157008. + IN gckVGHARDWARE Hardware
  157009. + );
  157010. +
  157011. +/* Get idle register. */
  157012. +gceSTATUS
  157013. +gckVGHARDWARE_GetIdle(
  157014. + IN gckVGHARDWARE Hardware,
  157015. + OUT gctUINT32 * Data
  157016. + );
  157017. +
  157018. +/* Flush the caches. */
  157019. +gceSTATUS
  157020. +gckVGHARDWARE_Flush(
  157021. + IN gckVGHARDWARE Hardware,
  157022. + IN gceKERNEL_FLUSH Flush,
  157023. + IN gctPOINTER Logical,
  157024. + IN OUT gctSIZE_T * Bytes
  157025. + );
  157026. +
  157027. +/* Enable/disable fast clear. */
  157028. +gceSTATUS
  157029. +gckVGHARDWARE_SetFastClear(
  157030. + IN gckVGHARDWARE Hardware,
  157031. + IN gctINT Enable
  157032. + );
  157033. +
  157034. +gceSTATUS
  157035. +gckVGHARDWARE_ReadInterrupt(
  157036. + IN gckVGHARDWARE Hardware,
  157037. + OUT gctUINT32_PTR IDs
  157038. + );
  157039. +
  157040. +/* Power management. */
  157041. +gceSTATUS
  157042. +gckVGHARDWARE_SetPowerManagementState(
  157043. + IN gckVGHARDWARE Hardware,
  157044. + IN gceCHIPPOWERSTATE State
  157045. + );
  157046. +
  157047. +gceSTATUS
  157048. +gckVGHARDWARE_QueryPowerManagementState(
  157049. + IN gckVGHARDWARE Hardware,
  157050. + OUT gceCHIPPOWERSTATE* State
  157051. + );
  157052. +
  157053. +gceSTATUS
  157054. +gckVGHARDWARE_SetPowerManagement(
  157055. + IN gckVGHARDWARE Hardware,
  157056. + IN gctBOOL PowerManagement
  157057. + );
  157058. +
  157059. +gceSTATUS
  157060. +gckVGHARDWARE_SetPowerOffTimeout(
  157061. + IN gckVGHARDWARE Hardware,
  157062. + IN gctUINT32 Timeout
  157063. + );
  157064. +
  157065. +gceSTATUS
  157066. +gckVGHARDWARE_QueryPowerOffTimeout(
  157067. + IN gckVGHARDWARE Hardware,
  157068. + OUT gctUINT32* Timeout
  157069. + );
  157070. +
  157071. +gceSTATUS
  157072. +gckVGHARDWARE_QueryIdle(
  157073. + IN gckVGHARDWARE Hardware,
  157074. + OUT gctBOOL_PTR IsIdle
  157075. + );
  157076. +/******************************************************************************\
  157077. +*************************** Command Buffer Structures **************************
  157078. +\******************************************************************************/
  157079. +
  157080. +/* Vacant command buffer marker. */
  157081. +#define gcvVACANT_BUFFER ((gcsCOMPLETION_SIGNAL_PTR) (1))
  157082. +
  157083. +/* Command buffer header. */
  157084. +typedef struct _gcsCMDBUFFER * gcsCMDBUFFER_PTR;
  157085. +typedef struct _gcsCMDBUFFER
  157086. +{
  157087. + /* Pointer to the completion signal. */
  157088. + gcsCOMPLETION_SIGNAL_PTR completion;
  157089. +
  157090. + /* The user sets this to the node of the container buffer whitin which
  157091. + this particular command buffer resides. The kernel sets this to the
  157092. + node of the internally allocated buffer. */
  157093. + gctUINT64 node;
  157094. +
  157095. + /* Command buffer hardware address. */
  157096. + gctUINT32 address;
  157097. +
  157098. + /* The offset of the buffer from the beginning of the header. */
  157099. + gctUINT32 bufferOffset;
  157100. +
  157101. + /* Size of the area allocated for the data portion of this particular
  157102. + command buffer (headers and tail reserves are excluded). */
  157103. + gctSIZE_T size;
  157104. +
  157105. + /* Offset into the buffer [0..size]; reflects exactly how much data has
  157106. + been put into the command buffer. */
  157107. + gctUINT offset;
  157108. +
  157109. + /* The number of command units in the buffer for the hardware to
  157110. + execute. */
  157111. + gctSIZE_T dataCount;
  157112. +
  157113. + /* MANAGED BY : user HAL (gcoBUFFER object).
  157114. + USED BY : user HAL (gcoBUFFER object).
  157115. + Points to the immediate next allocated command buffer. */
  157116. + gcsCMDBUFFER_PTR nextAllocated;
  157117. +
  157118. + /* MANAGED BY : user layers (HAL and drivers).
  157119. + USED BY : kernel HAL (gcoBUFFER object).
  157120. + Points to the next subbuffer if any. A family of subbuffers are chained
  157121. + together and are meant to be executed inseparably as a unit. Meaning
  157122. + that context switching cannot occur while a chain of subbuffers is being
  157123. + executed. */
  157124. + gcsCMDBUFFER_PTR nextSubBuffer;
  157125. +}
  157126. +gcsCMDBUFFER;
  157127. +
  157128. +/* Command queue element. */
  157129. +typedef struct _gcsVGCMDQUEUE
  157130. +{
  157131. + /* Pointer to the command buffer header. */
  157132. + gcsCMDBUFFER_PTR commandBuffer;
  157133. +
  157134. + /* Dynamic vs. static command buffer state. */
  157135. + gctBOOL dynamic;
  157136. +}
  157137. +gcsVGCMDQUEUE;
  157138. +
  157139. +/* Context map entry. */
  157140. +typedef struct _gcsVGCONTEXT_MAP
  157141. +{
  157142. + /* State index. */
  157143. + gctUINT32 index;
  157144. +
  157145. + /* New state value. */
  157146. + gctUINT32 data;
  157147. +
  157148. + /* Points to the next entry in the mod list. */
  157149. + gcsVGCONTEXT_MAP_PTR next;
  157150. +}
  157151. +gcsVGCONTEXT_MAP;
  157152. +
  157153. +/* gcsVGCONTEXT structure that holds the current context. */
  157154. +typedef struct _gcsVGCONTEXT
  157155. +{
  157156. + /* Context ID. */
  157157. + gctUINT64 id;
  157158. +
  157159. + /* State caching ebable flag. */
  157160. + gctBOOL stateCachingEnabled;
  157161. +
  157162. + /* Current pipe. */
  157163. + gctUINT32 currentPipe;
  157164. +
  157165. + /* State map/mod buffer. */
  157166. + gctSIZE_T mapFirst;
  157167. + gctSIZE_T mapLast;
  157168. +#ifdef __QNXNTO__
  157169. + gctSIZE_T mapContainerSize;
  157170. +#endif
  157171. + gcsVGCONTEXT_MAP_PTR mapContainer;
  157172. + gcsVGCONTEXT_MAP_PTR mapPrev;
  157173. + gcsVGCONTEXT_MAP_PTR mapCurr;
  157174. + gcsVGCONTEXT_MAP_PTR firstPrevMap;
  157175. + gcsVGCONTEXT_MAP_PTR firstCurrMap;
  157176. +
  157177. + /* Main context buffer. */
  157178. + gcsCMDBUFFER_PTR header;
  157179. + gctUINT32_PTR buffer;
  157180. +
  157181. + /* Completion signal. */
  157182. + gctHANDLE process;
  157183. + gctSIGNAL signal;
  157184. +
  157185. +#if defined(__QNXNTO__)
  157186. + gctINT32 coid;
  157187. + gctINT32 rcvid;
  157188. +#endif
  157189. +}
  157190. +gcsVGCONTEXT;
  157191. +
  157192. +/* User space task header. */
  157193. +typedef struct _gcsTASK * gcsTASK_PTR;
  157194. +typedef struct _gcsTASK
  157195. +{
  157196. + /* Pointer to the next task for the same interrupt in user space. */
  157197. + gcsTASK_PTR next;
  157198. +
  157199. + /* Size of the task data that immediately follows the structure. */
  157200. + gctUINT size;
  157201. +
  157202. + /* Task data starts here. */
  157203. + /* ... */
  157204. +}
  157205. +gcsTASK;
  157206. +
  157207. +/* User space task master table entry. */
  157208. +typedef struct _gcsTASK_MASTER_ENTRY * gcsTASK_MASTER_ENTRY_PTR;
  157209. +typedef struct _gcsTASK_MASTER_ENTRY
  157210. +{
  157211. + /* Pointers to the head and to the tail of the task chain. */
  157212. + gcsTASK_PTR head;
  157213. + gcsTASK_PTR tail;
  157214. +}
  157215. +gcsTASK_MASTER_ENTRY;
  157216. +
  157217. +/* User space task master table entry. */
  157218. +typedef struct _gcsTASK_MASTER_TABLE
  157219. +{
  157220. + /* Table with one entry per block. */
  157221. + gcsTASK_MASTER_ENTRY table[gcvBLOCK_COUNT];
  157222. +
  157223. + /* The total number of tasks sckeduled. */
  157224. + gctUINT count;
  157225. +
  157226. + /* The total size of event data in bytes. */
  157227. + gctUINT size;
  157228. +
  157229. +#if defined(__QNXNTO__)
  157230. + gctINT32 coid;
  157231. + gctINT32 rcvid;
  157232. +#endif
  157233. +}
  157234. +gcsTASK_MASTER_TABLE;
  157235. +
  157236. +/******************************************************************************\
  157237. +***************************** gckVGINTERRUPT Object ******************************
  157238. +\******************************************************************************/
  157239. +
  157240. +typedef struct _gckVGINTERRUPT * gckVGINTERRUPT;
  157241. +
  157242. +typedef gceSTATUS (* gctINTERRUPT_HANDLER)(
  157243. + IN gckVGKERNEL Kernel
  157244. + );
  157245. +
  157246. +gceSTATUS
  157247. +gckVGINTERRUPT_Construct(
  157248. + IN gckVGKERNEL Kernel,
  157249. + OUT gckVGINTERRUPT * Interrupt
  157250. + );
  157251. +
  157252. +gceSTATUS
  157253. +gckVGINTERRUPT_Destroy(
  157254. + IN gckVGINTERRUPT Interrupt
  157255. + );
  157256. +
  157257. +gceSTATUS
  157258. +gckVGINTERRUPT_Enable(
  157259. + IN gckVGINTERRUPT Interrupt,
  157260. + IN OUT gctINT32_PTR Id,
  157261. + IN gctINTERRUPT_HANDLER Handler
  157262. + );
  157263. +
  157264. +gceSTATUS
  157265. +gckVGINTERRUPT_Disable(
  157266. + IN gckVGINTERRUPT Interrupt,
  157267. + IN gctINT32 Id
  157268. + );
  157269. +
  157270. +#ifndef __QNXNTO__
  157271. +
  157272. +gceSTATUS
  157273. +gckVGINTERRUPT_Enque(
  157274. + IN gckVGINTERRUPT Interrupt
  157275. + );
  157276. +
  157277. +#else
  157278. +
  157279. +gceSTATUS
  157280. +gckVGINTERRUPT_Enque(
  157281. + IN gckVGINTERRUPT Interrupt,
  157282. + OUT gckOS *Os,
  157283. + OUT gctSEMAPHORE *Semaphore
  157284. + );
  157285. +
  157286. +#endif
  157287. +
  157288. +gceSTATUS
  157289. +gckVGINTERRUPT_DumpState(
  157290. + IN gckVGINTERRUPT Interrupt
  157291. + );
  157292. +
  157293. +
  157294. +/******************************************************************************\
  157295. +******************************* gckVGCOMMAND Object *******************************
  157296. +\******************************************************************************/
  157297. +
  157298. +typedef struct _gckVGCOMMAND * gckVGCOMMAND;
  157299. +
  157300. +/* Construct a new gckVGCOMMAND object. */
  157301. +gceSTATUS
  157302. +gckVGCOMMAND_Construct(
  157303. + IN gckVGKERNEL Kernel,
  157304. + IN gctUINT TaskGranularity,
  157305. + IN gctUINT QueueSize,
  157306. + OUT gckVGCOMMAND * Command
  157307. + );
  157308. +
  157309. +/* Destroy an gckVGCOMMAND object. */
  157310. +gceSTATUS
  157311. +gckVGCOMMAND_Destroy(
  157312. + IN gckVGCOMMAND Command
  157313. + );
  157314. +
  157315. +/* Query command buffer attributes. */
  157316. +gceSTATUS
  157317. +gckVGCOMMAND_QueryCommandBuffer(
  157318. + IN gckVGCOMMAND Command,
  157319. + OUT gcsCOMMAND_BUFFER_INFO_PTR Information
  157320. + );
  157321. +
  157322. +/* Allocate a command queue. */
  157323. +gceSTATUS
  157324. +gckVGCOMMAND_Allocate(
  157325. + IN gckVGCOMMAND Command,
  157326. + IN gctSIZE_T Size,
  157327. + OUT gcsCMDBUFFER_PTR * CommandBuffer,
  157328. + OUT gctPOINTER * Data
  157329. + );
  157330. +
  157331. +/* Release memory held by the command queue. */
  157332. +gceSTATUS
  157333. +gckVGCOMMAND_Free(
  157334. + IN gckVGCOMMAND Command,
  157335. + IN gcsCMDBUFFER_PTR CommandBuffer
  157336. + );
  157337. +
  157338. +/* Schedule the command queue for execution. */
  157339. +gceSTATUS
  157340. +gckVGCOMMAND_Execute(
  157341. + IN gckVGCOMMAND Command,
  157342. + IN gcsCMDBUFFER_PTR CommandBuffer
  157343. + );
  157344. +
  157345. +/* Commit a buffer to the command queue. */
  157346. +gceSTATUS
  157347. +gckVGCOMMAND_Commit(
  157348. + IN gckVGCOMMAND Command,
  157349. + IN gcsVGCONTEXT_PTR Context,
  157350. + IN gcsVGCMDQUEUE_PTR Queue,
  157351. + IN gctUINT EntryCount,
  157352. + IN gcsTASK_MASTER_TABLE_PTR TaskTable
  157353. + );
  157354. +
  157355. +/******************************************************************************\
  157356. +********************************* gckVGMMU Object ********************************
  157357. +\******************************************************************************/
  157358. +
  157359. +typedef struct _gckVGMMU * gckVGMMU;
  157360. +
  157361. +/* Construct a new gckVGMMU object. */
  157362. +gceSTATUS
  157363. +gckVGMMU_Construct(
  157364. + IN gckVGKERNEL Kernel,
  157365. + IN gctSIZE_T MmuSize,
  157366. + OUT gckVGMMU * Mmu
  157367. + );
  157368. +
  157369. +/* Destroy an gckVGMMU object. */
  157370. +gceSTATUS
  157371. +gckVGMMU_Destroy(
  157372. + IN gckVGMMU Mmu
  157373. + );
  157374. +
  157375. +/* Allocate pages inside the MMU. */
  157376. +gceSTATUS
  157377. +gckVGMMU_AllocatePages(
  157378. + IN gckVGMMU Mmu,
  157379. + IN gctSIZE_T PageCount,
  157380. + OUT gctPOINTER * PageTable,
  157381. + OUT gctUINT32 * Address
  157382. + );
  157383. +
  157384. +/* Remove a page table from the MMU. */
  157385. +gceSTATUS
  157386. +gckVGMMU_FreePages(
  157387. + IN gckVGMMU Mmu,
  157388. + IN gctPOINTER PageTable,
  157389. + IN gctSIZE_T PageCount
  157390. + );
  157391. +
  157392. +/* Set the MMU page with info. */
  157393. +gceSTATUS
  157394. +gckVGMMU_SetPage(
  157395. + IN gckVGMMU Mmu,
  157396. + IN gctUINT32 PageAddress,
  157397. + IN gctUINT32 *PageEntry
  157398. + );
  157399. +
  157400. +/* Flush MMU */
  157401. +gceSTATUS
  157402. +gckVGMMU_Flush(
  157403. + IN gckVGMMU Mmu
  157404. + );
  157405. +
  157406. +#endif /* gcdENABLE_VG */
  157407. +
  157408. +#ifdef __cplusplus
  157409. +} /* extern "C" */
  157410. +#endif
  157411. +
  157412. +#endif /* __gc_hal_h_ */
  157413. diff -Nur linux-3.14.17/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
  157414. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c 1970-01-01 01:00:00.000000000 +0100
  157415. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c 2014-09-11 18:06:03.126042465 +0200
  157416. @@ -0,0 +1,795 @@
  157417. +/****************************************************************************
  157418. +*
  157419. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  157420. +*
  157421. +* This program is free software; you can redistribute it and/or modify
  157422. +* it under the terms of the GNU General Public License as published by
  157423. +* the Free Software Foundation; either version 2 of the license, or
  157424. +* (at your option) any later version.
  157425. +*
  157426. +* This program is distributed in the hope that it will be useful,
  157427. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  157428. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  157429. +* GNU General Public License for more details.
  157430. +*
  157431. +* You should have received a copy of the GNU General Public License
  157432. +* along with this program; if not write to the Free Software
  157433. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  157434. +*
  157435. +*****************************************************************************/
  157436. +
  157437. +
  157438. +#ifdef MODULE
  157439. +#include <linux/module.h>
  157440. +#endif
  157441. +#include <linux/init.h>
  157442. +#include <linux/debugfs.h>
  157443. +#include <linux/slab.h>
  157444. +#ifdef MODVERSIONS
  157445. +#include <linux/modversions.h>
  157446. +#endif
  157447. +#include <linux/stddef.h>
  157448. +#include <linux/sched.h>
  157449. +#include <linux/kernel.h>
  157450. +#include <linux/timer.h>
  157451. +#include <linux/delay.h>
  157452. +#include <linux/errno.h>
  157453. +#include <linux/mutex.h>
  157454. +#include <linux/vmalloc.h>
  157455. +#include <linux/types.h>
  157456. +#include <linux/fs.h>
  157457. +#include <linux/poll.h>
  157458. +#include <asm/uaccess.h>
  157459. +#include <linux/completion.h>
  157460. +#include "gc_hal_kernel_linux.h"
  157461. +
  157462. +/*
  157463. + Prequsite:
  157464. +
  157465. + 1) Debugfs feature must be enabled in the kernel.
  157466. + 1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
  157467. + you have to enable the debugfs in the kernel hacking part of the menu.
  157468. +
  157469. + HOW TO USE:
  157470. + 1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
  157471. + This gives a circular buffer of 10 MB
  157472. +
  157473. + 2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
  157474. +
  157475. + 2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
  157476. +
  157477. + 3) To read what is being printed in the debugfs file system:
  157478. + Ex : cat /sys/kernel/debug/gpu/galcore_trace
  157479. +
  157480. + 4)To write into the debug file system from user side :
  157481. + Ex: echo "hello" > cat /sys/kernel/debug/gpu/galcore_trace
  157482. +
  157483. + 5)To write into debugfs from kernel side, Use the function called gckDebugFileSystemPrint
  157484. +
  157485. +
  157486. + USECASE Kernel Dump:
  157487. +
  157488. + 1) Go to /hal/inc/gc_hal_options.h, and enable the following flags:
  157489. + - # define gcdDUMP 1
  157490. + - # define gcdDUMP_IN_KERNEL 1
  157491. + - # define gcdDUMP_COMMAND 1
  157492. +
  157493. + 2) Go to /hal/kernel/gc_hal_kernel_command.c and disable the following flag
  157494. + -#define gcdSIMPLE_COMMAND_DUMP 0
  157495. +
  157496. + 3) Compile the driver
  157497. + 4) insmod it with the logFileSize option
  157498. + 5) Run an application
  157499. + 6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
  157500. +
  157501. + */
  157502. +
  157503. +/**/
  157504. +typedef va_list gctDBGARGS ;
  157505. +#define gcmkARGS_START(argument, pointer) va_start(argument, pointer)
  157506. +#define gcmkARGS_END(argument) va_end(argument)
  157507. +
  157508. +#define gcmkDBGFSPRINT(ArgumentSize, Message) \
  157509. + { \
  157510. + gctDBGARGS __arguments__; \
  157511. + gcmkARGS_START(__arguments__, Message); \
  157512. + _DebugFSPrint(ArgumentSize, Message, __arguments__);\
  157513. + gcmkARGS_END(__arguments__); \
  157514. + }
  157515. +
  157516. +/*Debug File System Node Struct*/
  157517. +struct _gcsDebugFileSystemNode
  157518. +{
  157519. + /*wait queues for read and write operations*/
  157520. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  157521. + wait_queue_head_t read_q , write_q ;
  157522. +#else
  157523. + struct wait_queue *read_q , *write_q ;
  157524. +#endif
  157525. + struct dentry *parent ; /*parent directory*/
  157526. + struct dentry *filen ; /*filename*/
  157527. + struct semaphore sem ; /* mutual exclusion semaphore */
  157528. + char *data ; /* The circular buffer data */
  157529. + int size ; /* Size of the buffer pointed to by 'data' */
  157530. + int refcount ; /* Files that have this buffer open */
  157531. + int read_point ; /* Offset in circ. buffer of oldest data */
  157532. + int write_point ; /* Offset in circ. buffer of newest data */
  157533. + int offset ; /* Byte number of read_point in the stream */
  157534. + struct _gcsDebugFileSystemNode *next ;
  157535. +} ;
  157536. +
  157537. +/* amount of data in the queue */
  157538. +#define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \
  157539. + (node)->write_point - (node)->read_point : \
  157540. + (node)->size - (node)->read_point + (node)->write_point)
  157541. +
  157542. +/* byte number of the last byte in the queue */
  157543. +#define gcmkNODE_FIRST_EMPTY_BYTE(node) ((node)->offset + gcmkNODE_QLEN(node))
  157544. +
  157545. +/*Synchronization primitives*/
  157546. +#define gcmkNODE_READQ(node) (&((node)->read_q))
  157547. +#define gcmkNODE_WRITEQ(node) (&((node)->write_q))
  157548. +#define gcmkNODE_SEM(node) (&((node)->sem))
  157549. +
  157550. +/*Utilities*/
  157551. +#define gcmkMIN(x, y) ((x) < (y) ? (x) : y)
  157552. +
  157553. +/*Debug File System Struct*/
  157554. +typedef struct _gcsDebugFileSystem
  157555. +{
  157556. + gcsDebugFileSystemNode* linkedlist ;
  157557. + gcsDebugFileSystemNode* currentNode ;
  157558. + int isInited ;
  157559. +} gcsDebugFileSystem ;
  157560. +
  157561. +
  157562. +/*debug file system*/
  157563. +static gcsDebugFileSystem gc_dbgfs ;
  157564. +
  157565. +
  157566. +
  157567. +/*******************************************************************************
  157568. + **
  157569. + ** READ & WRITE FUNCTIONS (START)
  157570. + **
  157571. + *******************************************************************************/
  157572. +
  157573. +/*******************************************************************************
  157574. + **
  157575. + ** _ReadFromNode
  157576. + **
  157577. + ** 1) reading bytes out of a circular buffer with wraparound.
  157578. + ** 2)returns caddr_t, pointer to data read, which the caller must free.
  157579. + ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
  157580. + ** be the number of bytes actually returned
  157581. + **
  157582. + *******************************************************************************/
  157583. +static caddr_t
  157584. +_ReadFromNode (
  157585. + gcsDebugFileSystemNode* Node ,
  157586. + size_t *Length ,
  157587. + loff_t *Offset
  157588. + )
  157589. +{
  157590. + caddr_t retval ;
  157591. + int bytes_copied = 0 , n , start_point , remaining ;
  157592. +
  157593. + /* is the user trying to read data that has already scrolled off? */
  157594. + if ( *Offset < Node->offset )
  157595. + {
  157596. + *Offset = Node->offset ;
  157597. + }
  157598. +
  157599. + /* is the user trying to read past EOF? */
  157600. + if ( *Offset >= gcmkNODE_FIRST_EMPTY_BYTE ( Node ) )
  157601. + {
  157602. + return NULL ;
  157603. + }
  157604. +
  157605. + /* find the smaller of the total bytes we have available and what
  157606. + * the user is asking for */
  157607. +
  157608. + *Length = gcmkMIN ( *Length , gcmkNODE_FIRST_EMPTY_BYTE ( Node ) - *Offset ) ;
  157609. +
  157610. + remaining = * Length ;
  157611. +
  157612. + /* figure out where to start based on user's Offset */
  157613. + start_point = Node->read_point + ( *Offset - Node->offset ) ;
  157614. +
  157615. + start_point = start_point % Node->size ;
  157616. +
  157617. + /* allocate memory to return */
  157618. + if ( ( retval = kmalloc ( sizeof (char ) * remaining , GFP_KERNEL ) ) == NULL )
  157619. + return NULL ;
  157620. +
  157621. + /* copy the (possibly noncontiguous) data to our buffer */
  157622. + while ( remaining )
  157623. + {
  157624. + n = gcmkMIN ( remaining , Node->size - start_point ) ;
  157625. + memcpy ( retval + bytes_copied , Node->data + start_point , n ) ;
  157626. + bytes_copied += n ;
  157627. + remaining -= n ;
  157628. + start_point = ( start_point + n ) % Node->size ;
  157629. + }
  157630. +
  157631. + /* advance user's file pointer */
  157632. + *Offset += * Length ;
  157633. +
  157634. + return retval ;
  157635. +}
  157636. +
  157637. +/*******************************************************************************
  157638. + **
  157639. + ** _WriteToNode
  157640. + **
  157641. + ** 1) writes to a circular buffer with wraparound.
  157642. + ** 2)in case of an overflow, it overwrites the oldest unread data.
  157643. + **
  157644. + *********************************************************************************/
  157645. +static void
  157646. +_WriteToNode (
  157647. + gcsDebugFileSystemNode* Node ,
  157648. + caddr_t Buf ,
  157649. + int Length
  157650. + )
  157651. +{
  157652. + int bytes_copied = 0 ;
  157653. + int overflow = 0 ;
  157654. + int n ;
  157655. +
  157656. + if ( Length + gcmkNODE_QLEN ( Node ) >= ( Node->size - 1 ) )
  157657. + {
  157658. + overflow = 1 ;
  157659. +
  157660. + /* in case of overflow, figure out where the new buffer will
  157661. + * begin. we start by figuring out where the current buffer ENDS:
  157662. + * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset
  157663. + * by the Length of the current write, and work backwards to
  157664. + * figure out what the oldest unoverwritten data will be (i.e.,
  157665. + * size of the buffer). */
  157666. + Node->offset = Node->offset + gcmkNODE_QLEN ( Node ) + Length
  157667. + - Node->size + 1 ;
  157668. + }
  157669. +
  157670. + while ( Length )
  157671. + {
  157672. + /* how many contiguous bytes are available from the write point to
  157673. + * the end of the circular buffer? */
  157674. + n = gcmkMIN ( Length , Node->size - Node->write_point ) ;
  157675. + memcpy ( Node->data + Node->write_point , Buf + bytes_copied , n ) ;
  157676. + bytes_copied += n ;
  157677. + Length -= n ;
  157678. + Node->write_point = ( Node->write_point + n ) % Node->size ;
  157679. + }
  157680. +
  157681. + /* if there is an overflow, reset the read point to read whatever is
  157682. + * the oldest data that we have, that has not yet been
  157683. + * overwritten. */
  157684. + if ( overflow )
  157685. + {
  157686. + Node->read_point = ( Node->write_point + 1 ) % Node->size ;
  157687. + }
  157688. +}
  157689. +
  157690. +
  157691. +/*******************************************************************************
  157692. + **
  157693. + ** PRINTING UTILITY (START)
  157694. + **
  157695. + *******************************************************************************/
  157696. +
  157697. +/*******************************************************************************
  157698. + **
  157699. + ** _GetArgumentSize
  157700. + **
  157701. + **
  157702. + *******************************************************************************/
  157703. +static gctINT
  157704. +_GetArgumentSize (
  157705. + IN gctCONST_STRING Message
  157706. + )
  157707. +{
  157708. + gctINT i , count ;
  157709. +
  157710. + for ( i = 0 , count = 0 ; Message[i] ; i += 1 )
  157711. + {
  157712. + if ( Message[i] == '%' )
  157713. + {
  157714. + count += 1 ;
  157715. + }
  157716. + }
  157717. + return count * sizeof (unsigned int ) ;
  157718. +}
  157719. +
  157720. +/*******************************************************************************
  157721. + **
  157722. + ** _AppendString
  157723. + **
  157724. + **
  157725. + *******************************************************************************/
  157726. +static ssize_t
  157727. +_AppendString (
  157728. + IN gcsDebugFileSystemNode* Node ,
  157729. + IN gctCONST_STRING String ,
  157730. + IN int Length
  157731. + )
  157732. +{
  157733. + caddr_t message = NULL ;
  157734. + int n ;
  157735. +
  157736. + /* if the message is longer than the buffer, just take the beginning
  157737. + * of it, in hopes that the reader (if any) will have time to read
  157738. + * before we wrap around and obliterate it */
  157739. + n = gcmkMIN ( Length , Node->size - 1 ) ;
  157740. +
  157741. + /* make sure we have the memory for it */
  157742. + if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
  157743. + return - ENOMEM ;
  157744. +
  157745. + /* copy into our temp buffer */
  157746. + memcpy ( message , String , n ) ;
  157747. +
  157748. + /* now copy it into the circular buffer and free our temp copy */
  157749. + _WriteToNode ( Node , message , n ) ;
  157750. + kfree ( message ) ;
  157751. + return n ;
  157752. +}
  157753. +
  157754. +/*******************************************************************************
  157755. + **
  157756. + ** _DebugFSPrint
  157757. + **
  157758. + **
  157759. + *******************************************************************************/
  157760. +static void
  157761. +_DebugFSPrint (
  157762. + IN unsigned int ArgumentSize ,
  157763. + IN const char* Message ,
  157764. + IN gctDBGARGS Arguments
  157765. +
  157766. + )
  157767. +{
  157768. + char buffer[MAX_LINE_SIZE] ;
  157769. + int len ;
  157770. + down ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
  157771. + len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) & Arguments ) ;
  157772. + buffer[len] = '\0' ;
  157773. +
  157774. + /* Add end-of-line if missing. */
  157775. + if ( buffer[len - 1] != '\n' )
  157776. + {
  157777. + buffer[len ++] = '\n' ;
  157778. + buffer[len] = '\0' ;
  157779. + }
  157780. + _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
  157781. + up ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
  157782. + wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/
  157783. +}
  157784. +
  157785. +/*******************************************************************************
  157786. + **
  157787. + ** LINUX SYSTEM FUNCTIONS (START)
  157788. + **
  157789. + *******************************************************************************/
  157790. +
  157791. +/*******************************************************************************
  157792. + **
  157793. + ** find the vivlog structure associated with an inode.
  157794. + ** returns a pointer to the structure if found, NULL if not found
  157795. + **
  157796. + *******************************************************************************/
  157797. +static gcsDebugFileSystemNode*
  157798. +_GetNodeInfo (
  157799. + IN struct inode *Inode
  157800. + )
  157801. +{
  157802. + gcsDebugFileSystemNode* node ;
  157803. +
  157804. + if ( Inode == NULL )
  157805. + return NULL ;
  157806. +
  157807. + for ( node = gc_dbgfs.linkedlist ; node != NULL ; node = node->next )
  157808. + if ( node->filen->d_inode->i_ino == Inode->i_ino )
  157809. + return node ;
  157810. +
  157811. + return NULL ;
  157812. +}
  157813. +
  157814. +/*******************************************************************************
  157815. + **
  157816. + ** _DebugFSRead
  157817. + **
  157818. + *******************************************************************************/
  157819. +static ssize_t
  157820. +_DebugFSRead (
  157821. + struct file *file ,
  157822. + char __user * buffer ,
  157823. + size_t length ,
  157824. + loff_t * offset
  157825. + )
  157826. +{
  157827. + int retval ;
  157828. + caddr_t data_to_return ;
  157829. + gcsDebugFileSystemNode* node ;
  157830. + /* get the metadata about this emlog */
  157831. + if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
  157832. + {
  157833. + printk ( "debugfs_read: record not found\n" ) ;
  157834. + return - EIO ;
  157835. + }
  157836. +
  157837. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  157838. + {
  157839. + return - ERESTARTSYS ;
  157840. + }
  157841. +
  157842. + /* wait until there's data available (unless we do nonblocking reads) */
  157843. + while ( *offset >= gcmkNODE_FIRST_EMPTY_BYTE ( node ) )
  157844. + {
  157845. + up ( gcmkNODE_SEM ( node ) ) ;
  157846. + if ( file->f_flags & O_NONBLOCK )
  157847. + {
  157848. + return - EAGAIN ;
  157849. + }
  157850. + if ( wait_event_interruptible ( ( *( gcmkNODE_READQ ( node ) ) ) , ( *offset < gcmkNODE_FIRST_EMPTY_BYTE ( node ) ) ) )
  157851. + {
  157852. + return - ERESTARTSYS ; /* signal: tell the fs layer to handle it */
  157853. + }
  157854. + /* otherwise loop, but first reacquire the lock */
  157855. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  157856. + {
  157857. + return - ERESTARTSYS ;
  157858. + }
  157859. + }
  157860. + data_to_return = _ReadFromNode ( node , &length , offset ) ;
  157861. + if ( data_to_return == NULL )
  157862. + {
  157863. + retval = 0 ;
  157864. + goto unlock ;
  157865. + }
  157866. + if ( copy_to_user ( buffer , data_to_return , length ) > 0 )
  157867. + {
  157868. + retval = - EFAULT ;
  157869. + }
  157870. + else
  157871. + {
  157872. + retval = length ;
  157873. + }
  157874. + kfree ( data_to_return ) ;
  157875. +unlock:
  157876. + up ( gcmkNODE_SEM ( node ) ) ;
  157877. + wake_up_interruptible ( gcmkNODE_WRITEQ ( node ) ) ;
  157878. + return retval ;
  157879. +}
  157880. +
  157881. +/*******************************************************************************
  157882. + **
  157883. + **_DebugFSWrite
  157884. + **
  157885. + *******************************************************************************/
  157886. +static ssize_t
  157887. +_DebugFSWrite (
  157888. + struct file *file ,
  157889. + const char __user * buffer ,
  157890. + size_t length ,
  157891. + loff_t * offset
  157892. + )
  157893. +{
  157894. + caddr_t message = NULL ;
  157895. + int n ;
  157896. + gcsDebugFileSystemNode*node ;
  157897. +
  157898. + /* get the metadata about this log */
  157899. + if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
  157900. + {
  157901. + return - EIO ;
  157902. + }
  157903. +
  157904. + if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
  157905. + {
  157906. + return - ERESTARTSYS ;
  157907. + }
  157908. +
  157909. + /* if the message is longer than the buffer, just take the beginning
  157910. + * of it, in hopes that the reader (if any) will have time to read
  157911. + * before we wrap around and obliterate it */
  157912. + n = gcmkMIN ( length , node->size - 1 ) ;
  157913. +
  157914. + /* make sure we have the memory for it */
  157915. + if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
  157916. + {
  157917. + up ( gcmkNODE_SEM ( node ) ) ;
  157918. + return - ENOMEM ;
  157919. + }
  157920. +
  157921. + /* copy into our temp buffer */
  157922. + if ( copy_from_user ( message , buffer , n ) > 0 )
  157923. + {
  157924. + up ( gcmkNODE_SEM ( node ) ) ;
  157925. + kfree ( message ) ;
  157926. + return - EFAULT ;
  157927. + }
  157928. +
  157929. + /* now copy it into the circular buffer and free our temp copy */
  157930. + _WriteToNode ( node , message , n ) ;
  157931. +
  157932. + kfree ( message ) ;
  157933. + up ( gcmkNODE_SEM ( node ) ) ;
  157934. +
  157935. + /* wake up any readers that might be waiting for the data. we call
  157936. + * schedule in the vague hope that a reader will run before the
  157937. + * writer's next write, to avoid losing data. */
  157938. + wake_up_interruptible ( gcmkNODE_READQ ( node ) ) ;
  157939. +
  157940. + return n ;
  157941. +}
  157942. +
  157943. +/*******************************************************************************
  157944. + **
  157945. + ** File Operations Table
  157946. + **
  157947. + *******************************************************************************/
  157948. +static const struct file_operations debugfs_operations = {
  157949. + .owner = THIS_MODULE ,
  157950. + .read = _DebugFSRead ,
  157951. + .write = _DebugFSWrite ,
  157952. +} ;
  157953. +
  157954. +/*******************************************************************************
  157955. + **
  157956. + ** INTERFACE FUNCTIONS (START)
  157957. + **
  157958. + *******************************************************************************/
  157959. +
  157960. +/*******************************************************************************
  157961. + **
  157962. + ** gckDebugFileSystemIsEnabled
  157963. + **
  157964. + **
  157965. + ** INPUT:
  157966. + **
  157967. + ** OUTPUT:
  157968. + **
  157969. + *******************************************************************************/
  157970. +
  157971. +
  157972. +gctINT
  157973. +gckDebugFileSystemIsEnabled ( void )
  157974. +{
  157975. + return gc_dbgfs.isInited ;
  157976. +}
  157977. +/*******************************************************************************
  157978. + **
  157979. + ** gckDebugFileSystemInitialize
  157980. + **
  157981. + **
  157982. + ** INPUT:
  157983. + **
  157984. + ** OUTPUT:
  157985. + **
  157986. + *******************************************************************************/
  157987. +
  157988. +gctINT
  157989. +gckDebugFileSystemInitialize ( void )
  157990. +{
  157991. + if ( ! gc_dbgfs.isInited )
  157992. + {
  157993. + gc_dbgfs.linkedlist = gcvNULL ;
  157994. + gc_dbgfs.currentNode = gcvNULL ;
  157995. + gc_dbgfs.isInited = 1 ;
  157996. + }
  157997. + return gc_dbgfs.isInited ;
  157998. +}
  157999. +/*******************************************************************************
  158000. + **
  158001. + ** gckDebugFileSystemTerminate
  158002. + **
  158003. + **
  158004. + ** INPUT:
  158005. + **
  158006. + ** OUTPUT:
  158007. + **
  158008. + *******************************************************************************/
  158009. +
  158010. +gctINT
  158011. +gckDebugFileSystemTerminate ( void )
  158012. +{
  158013. + gcsDebugFileSystemNode * next = gcvNULL ;
  158014. + gcsDebugFileSystemNode * temp = gcvNULL ;
  158015. + if ( gc_dbgfs.isInited )
  158016. + {
  158017. + temp = gc_dbgfs.linkedlist ;
  158018. + while ( temp != gcvNULL )
  158019. + {
  158020. + next = temp->next ;
  158021. + gckDebugFileSystemFreeNode ( temp ) ;
  158022. + kfree ( temp ) ;
  158023. + temp = next ;
  158024. + }
  158025. + gc_dbgfs.isInited = 0 ;
  158026. + }
  158027. + return 0 ;
  158028. +}
  158029. +
  158030. +
  158031. +/*******************************************************************************
  158032. + **
  158033. + ** gckDebugFileSystemCreateNode
  158034. + **
  158035. + **
  158036. + ** INPUT:
  158037. + **
  158038. + ** OUTPUT:
  158039. + **
  158040. + ** gckDebugFileSystemFreeNode * Device
  158041. + ** Pointer to a variable receiving the gcsDebugFileSystemNode object pointer on
  158042. + ** success.
  158043. + *********************************************************************************/
  158044. +
  158045. +gctINT
  158046. +gckDebugFileSystemCreateNode (
  158047. + IN gctINT SizeInKB ,
  158048. + IN gctCONST_STRING ParentName ,
  158049. + IN gctCONST_STRING NodeName ,
  158050. + OUT gcsDebugFileSystemNode **Node
  158051. + )
  158052. +{
  158053. + gcsDebugFileSystemNode*node ;
  158054. + /* allocate space for our metadata and initialize it */
  158055. + if ( ( node = kmalloc ( sizeof (gcsDebugFileSystemNode ) , GFP_KERNEL ) ) == NULL )
  158056. + goto struct_malloc_failed ;
  158057. +
  158058. + /*Zero it out*/
  158059. + memset ( node , 0 , sizeof (gcsDebugFileSystemNode ) ) ;
  158060. +
  158061. + /*Init the sync primitives*/
  158062. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  158063. + init_waitqueue_head ( gcmkNODE_READQ ( node ) ) ;
  158064. +#else
  158065. + init_waitqueue ( gcmkNODE_READQ ( node ) ) ;
  158066. +#endif
  158067. +
  158068. +#if defined(DECLARE_WAIT_QUEUE_HEAD)
  158069. + init_waitqueue_head ( gcmkNODE_WRITEQ ( node ) ) ;
  158070. +#else
  158071. + init_waitqueue ( gcmkNODE_WRITEQ ( node ) ) ;
  158072. +#endif
  158073. + sema_init ( gcmkNODE_SEM ( node ) , 1 ) ;
  158074. + /*End the sync primitives*/
  158075. +
  158076. +
  158077. + /* figure out how much of a buffer this should be and allocate the buffer */
  158078. + node->size = 1024 * SizeInKB ;
  158079. + if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
  158080. + goto data_malloc_failed ;
  158081. +
  158082. + /*creating the debug file system*/
  158083. + node->parent = debugfs_create_dir ( ParentName , NULL ) ;
  158084. +
  158085. + /*creating the file*/
  158086. + node->filen = debugfs_create_file ( NodeName , S_IRUGO | S_IWUSR , node->parent , NULL ,
  158087. + &debugfs_operations ) ;
  158088. +
  158089. + /* add it to our linked list */
  158090. + node->next = gc_dbgfs.linkedlist ;
  158091. + gc_dbgfs.linkedlist = node ;
  158092. +
  158093. + /* pass the struct back */
  158094. + *Node = node ;
  158095. + return 0 ;
  158096. +
  158097. + vfree ( node->data ) ;
  158098. +data_malloc_failed:
  158099. + kfree ( node ) ;
  158100. +struct_malloc_failed:
  158101. + return - ENOMEM ;
  158102. +}
  158103. +
  158104. +/*******************************************************************************
  158105. + **
  158106. + ** gckDebugFileSystemFreeNode
  158107. + **
  158108. + **
  158109. + ** INPUT:
  158110. + **
  158111. + ** OUTPUT:
  158112. + **
  158113. + *******************************************************************************/
  158114. +void
  158115. +gckDebugFileSystemFreeNode (
  158116. + IN gcsDebugFileSystemNode * Node
  158117. + )
  158118. +{
  158119. +
  158120. + gcsDebugFileSystemNode **ptr ;
  158121. +
  158122. + if ( Node == NULL )
  158123. + {
  158124. + printk ( "null passed to free_vinfo\n" ) ;
  158125. + return ;
  158126. + }
  158127. +
  158128. + down ( gcmkNODE_SEM ( Node ) ) ;
  158129. + /*free data*/
  158130. + vfree ( Node->data ) ;
  158131. +
  158132. + /*Close Debug fs*/
  158133. + if ( Node->filen )
  158134. + {
  158135. + debugfs_remove ( Node->filen ) ;
  158136. + }
  158137. + if ( Node->parent )
  158138. + {
  158139. + debugfs_remove ( Node->parent ) ;
  158140. + }
  158141. +
  158142. + /* now delete the node from the linked list */
  158143. + ptr = & ( gc_dbgfs.linkedlist ) ;
  158144. + while ( *ptr != Node )
  158145. + {
  158146. + if ( ! *ptr )
  158147. + {
  158148. + printk ( "corrupt info list!\n" ) ;
  158149. + break ;
  158150. + }
  158151. + else
  158152. + ptr = & ( ( **ptr ).next ) ;
  158153. + }
  158154. + *ptr = Node->next ;
  158155. + up ( gcmkNODE_SEM ( Node ) ) ;
  158156. +}
  158157. +
  158158. +/*******************************************************************************
  158159. + **
  158160. + ** gckDebugFileSystemSetCurrentNode
  158161. + **
  158162. + **
  158163. + ** INPUT:
  158164. + **
  158165. + ** OUTPUT:
  158166. + **
  158167. + *******************************************************************************/
  158168. +void
  158169. +gckDebugFileSystemSetCurrentNode (
  158170. + IN gcsDebugFileSystemNode * Node
  158171. + )
  158172. +{
  158173. + gc_dbgfs.currentNode = Node ;
  158174. +}
  158175. +
  158176. +/*******************************************************************************
  158177. + **
  158178. + ** gckDebugFileSystemGetCurrentNode
  158179. + **
  158180. + **
  158181. + ** INPUT:
  158182. + **
  158183. + ** OUTPUT:
  158184. + **
  158185. + *******************************************************************************/
  158186. +void
  158187. +gckDebugFileSystemGetCurrentNode (
  158188. + OUT gcsDebugFileSystemNode ** Node
  158189. + )
  158190. +{
  158191. + *Node = gc_dbgfs.currentNode ;
  158192. +}
  158193. +
  158194. +/*******************************************************************************
  158195. + **
  158196. + ** gckDebugFileSystemPrint
  158197. + **
  158198. + **
  158199. + ** INPUT:
  158200. + **
  158201. + ** OUTPUT:
  158202. + **
  158203. + *******************************************************************************/
  158204. +void
  158205. +gckDebugFileSystemPrint (
  158206. + IN gctCONST_STRING Message ,
  158207. + ...
  158208. + )
  158209. +{
  158210. + gcmkDBGFSPRINT ( _GetArgumentSize ( Message ) , Message ) ;
  158211. +}
  158212. diff -Nur linux-3.14.17/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
  158213. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h 1970-01-01 01:00:00.000000000 +0100
  158214. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h 2014-09-11 18:06:03.126042465 +0200
  158215. @@ -0,0 +1,84 @@
  158216. +/****************************************************************************
  158217. +*
  158218. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  158219. +*
  158220. +* This program is free software; you can redistribute it and/or modify
  158221. +* it under the terms of the GNU General Public License as published by
  158222. +* the Free Software Foundation; either version 2 of the license, or
  158223. +* (at your option) any later version.
  158224. +*
  158225. +* This program is distributed in the hope that it will be useful,
  158226. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  158227. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  158228. +* GNU General Public License for more details.
  158229. +*
  158230. +* You should have received a copy of the GNU General Public License
  158231. +* along with this program; if not write to the Free Software
  158232. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  158233. +*
  158234. +*****************************************************************************/
  158235. +
  158236. +
  158237. +#include <stdarg.h>
  158238. +
  158239. +#ifndef __gc_hal_kernel_debugfs_h_
  158240. +#define __gc_hal_kernel_debugfs_h_
  158241. +
  158242. + #define MAX_LINE_SIZE 768 /* Max bytes for a line of debug info */
  158243. +
  158244. +
  158245. + typedef struct _gcsDebugFileSystemNode gcsDebugFileSystemNode ;
  158246. +
  158247. +
  158248. +/*******************************************************************************
  158249. + **
  158250. + ** System Related
  158251. + **
  158252. + *******************************************************************************/
  158253. +
  158254. +gctINT gckDebugFileSystemIsEnabled(void);
  158255. +
  158256. +gctINT gckDebugFileSystemInitialize(void);
  158257. +
  158258. +gctINT gckDebugFileSystemTerminate(void);
  158259. +
  158260. +
  158261. +/*******************************************************************************
  158262. + **
  158263. + ** Node Related
  158264. + **
  158265. + *******************************************************************************/
  158266. +
  158267. +gctINT gckDebugFileSystemCreateNode(
  158268. + IN gctINT SizeInKB,
  158269. + IN gctCONST_STRING ParentName ,
  158270. + IN gctCONST_STRING NodeName,
  158271. + OUT gcsDebugFileSystemNode **Node
  158272. + );
  158273. +
  158274. +
  158275. +void gckDebugFileSystemFreeNode(
  158276. + IN gcsDebugFileSystemNode * Node
  158277. + );
  158278. +
  158279. +
  158280. +
  158281. +void gckDebugFileSystemSetCurrentNode(
  158282. + IN gcsDebugFileSystemNode * Node
  158283. + );
  158284. +
  158285. +
  158286. +
  158287. +void gckDebugFileSystemGetCurrentNode(
  158288. + OUT gcsDebugFileSystemNode ** Node
  158289. + );
  158290. +
  158291. +
  158292. +void gckDebugFileSystemPrint(
  158293. + IN gctCONST_STRING Message,
  158294. + ...
  158295. + );
  158296. +
  158297. +#endif
  158298. +
  158299. +
  158300. diff -Nur linux-3.14.17/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
  158301. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h 1970-01-01 01:00:00.000000000 +0100
  158302. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h 2014-09-11 18:06:03.126042465 +0200
  158303. @@ -0,0 +1,102 @@
  158304. +/****************************************************************************
  158305. +*
  158306. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  158307. +*
  158308. +* This program is free software; you can redistribute it and/or modify
  158309. +* it under the terms of the GNU General Public License as published by
  158310. +* the Free Software Foundation; either version 2 of the license, or
  158311. +* (at your option) any later version.
  158312. +*
  158313. +* This program is distributed in the hope that it will be useful,
  158314. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  158315. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  158316. +* GNU General Public License for more details.
  158317. +*
  158318. +* You should have received a copy of the GNU General Public License
  158319. +* along with this program; if not write to the Free Software
  158320. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  158321. +*
  158322. +*****************************************************************************/
  158323. +
  158324. +
  158325. +#ifndef __gc_hal_kernel_debug_h_
  158326. +#define __gc_hal_kernel_debug_h_
  158327. +
  158328. +#include <gc_hal_kernel_linux.h>
  158329. +#include <linux/spinlock.h>
  158330. +#include <linux/time.h>
  158331. +#include <stdarg.h>
  158332. +
  158333. +#ifdef __cplusplus
  158334. +extern "C" {
  158335. +#endif
  158336. +
  158337. +/******************************************************************************\
  158338. +****************************** OS-dependent Macros *****************************
  158339. +\******************************************************************************/
  158340. +
  158341. +typedef va_list gctARGUMENTS;
  158342. +
  158343. +#define gcmkARGUMENTS_START(Arguments, Pointer) \
  158344. + va_start(Arguments, Pointer)
  158345. +
  158346. +#define gcmkARGUMENTS_END(Arguments) \
  158347. + va_end(Arguments)
  158348. +
  158349. +#define gcmkDECLARE_LOCK(__spinLock__) \
  158350. + static DEFINE_SPINLOCK(__spinLock__);
  158351. +
  158352. +#define gcmkLOCKSECTION(__spinLock__) \
  158353. + spin_lock(&__spinLock__)
  158354. +
  158355. +#define gcmkUNLOCKSECTION(__spinLock__) \
  158356. + spin_unlock(&__spinLock__)
  158357. +
  158358. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  158359. +# define gcmkGETPROCESSID() \
  158360. + task_tgid_vnr(current)
  158361. +#else
  158362. +# define gcmkGETPROCESSID() \
  158363. + current->tgid
  158364. +#endif
  158365. +
  158366. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  158367. +# define gcmkGETTHREADID() \
  158368. + task_pid_vnr(current)
  158369. +#else
  158370. +# define gcmkGETTHREADID() \
  158371. + current->pid
  158372. +#endif
  158373. +
  158374. +#define gcmkOUTPUT_STRING(String) \
  158375. + if(gckDebugFileSystemIsEnabled()) \
  158376. + gckDebugFileSystemPrint(String);\
  158377. + else\
  158378. + printk(String); \
  158379. + touch_softlockup_watchdog()
  158380. +
  158381. +
  158382. +#define gcmkSPRINTF(Destination, Size, Message, Value) \
  158383. + snprintf(Destination, Size, Message, Value)
  158384. +
  158385. +#define gcmkSPRINTF2(Destination, Size, Message, Value1, Value2) \
  158386. + snprintf(Destination, Size, Message, Value1, Value2)
  158387. +
  158388. +#define gcmkSPRINTF3(Destination, Size, Message, Value1, Value2, Value3) \
  158389. + snprintf(Destination, Size, Message, Value1, Value2, Value3)
  158390. +
  158391. +#define gcmkVSPRINTF(Destination, Size, Message, Arguments) \
  158392. + vsnprintf(Destination, Size, Message, *(va_list *) &Arguments)
  158393. +
  158394. +#define gcmkSTRCAT(Destination, Size, String) \
  158395. + strncat(Destination, String, Size)
  158396. +
  158397. +/* If not zero, forces data alignment in the variable argument list
  158398. + by its individual size. */
  158399. +#define gcdALIGNBYSIZE 1
  158400. +
  158401. +#ifdef __cplusplus
  158402. +}
  158403. +#endif
  158404. +
  158405. +#endif /* __gc_hal_kernel_debug_h_ */
  158406. diff -Nur linux-3.14.17/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
  158407. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c 1970-01-01 01:00:00.000000000 +0100
  158408. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c 2014-09-11 18:06:03.126042465 +0200
  158409. @@ -0,0 +1,1676 @@
  158410. +/****************************************************************************
  158411. +*
  158412. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  158413. +*
  158414. +* This program is free software; you can redistribute it and/or modify
  158415. +* it under the terms of the GNU General Public License as published by
  158416. +* the Free Software Foundation; either version 2 of the license, or
  158417. +* (at your option) any later version.
  158418. +*
  158419. +* This program is distributed in the hope that it will be useful,
  158420. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  158421. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  158422. +* GNU General Public License for more details.
  158423. +*
  158424. +* You should have received a copy of the GNU General Public License
  158425. +* along with this program; if not write to the Free Software
  158426. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  158427. +*
  158428. +*****************************************************************************/
  158429. +
  158430. +
  158431. +#include "gc_hal_kernel_linux.h"
  158432. +#include <linux/pagemap.h>
  158433. +#include <linux/seq_file.h>
  158434. +#include <linux/mm.h>
  158435. +#include <linux/mman.h>
  158436. +#include <linux/slab.h>
  158437. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  158438. +#include <mach/hardware.h>
  158439. +#endif
  158440. +#include <linux/pm_runtime.h>
  158441. +
  158442. +#define _GC_OBJ_ZONE gcvZONE_DEVICE
  158443. +
  158444. +#define DEBUG_FILE "galcore_trace"
  158445. +#define PARENT_FILE "gpu"
  158446. +
  158447. +
  158448. +#ifdef FLAREON
  158449. + static struct dove_gpio_irq_handler gc500_handle;
  158450. +#endif
  158451. +
  158452. +#define gcmIS_CORE_PRESENT(Device, Core) (Device->irqLines[Core] > 0)
  158453. +
  158454. +/******************************************************************************\
  158455. +*************************** Memory Allocation Wrappers *************************
  158456. +\******************************************************************************/
  158457. +
  158458. +static gceSTATUS
  158459. +_AllocateMemory(
  158460. + IN gckGALDEVICE Device,
  158461. + IN gctSIZE_T Bytes,
  158462. + OUT gctPOINTER *Logical,
  158463. + OUT gctPHYS_ADDR *Physical,
  158464. + OUT gctUINT32 *PhysAddr
  158465. + )
  158466. +{
  158467. + gceSTATUS status;
  158468. +
  158469. + gcmkHEADER_ARG("Device=0x%x Bytes=%lu", Device, Bytes);
  158470. +
  158471. + gcmkVERIFY_ARGUMENT(Device != NULL);
  158472. + gcmkVERIFY_ARGUMENT(Logical != NULL);
  158473. + gcmkVERIFY_ARGUMENT(Physical != NULL);
  158474. + gcmkVERIFY_ARGUMENT(PhysAddr != NULL);
  158475. +
  158476. + gcmkONERROR(gckOS_AllocateContiguous(
  158477. + Device->os, gcvFALSE, &Bytes, Physical, Logical
  158478. + ));
  158479. +
  158480. + *PhysAddr = ((PLINUX_MDL)*Physical)->dmaHandle - Device->baseAddress;
  158481. +
  158482. + /* Success. */
  158483. + gcmkFOOTER_ARG(
  158484. + "*Logical=0x%x *Physical=0x%x *PhysAddr=0x%08x",
  158485. + *Logical, *Physical, *PhysAddr
  158486. + );
  158487. +
  158488. + return gcvSTATUS_OK;
  158489. +
  158490. +OnError:
  158491. + gcmkFOOTER();
  158492. + return status;
  158493. +}
  158494. +
  158495. +static gceSTATUS
  158496. +_FreeMemory(
  158497. + IN gckGALDEVICE Device,
  158498. + IN gctPOINTER Logical,
  158499. + IN gctPHYS_ADDR Physical)
  158500. +{
  158501. + gceSTATUS status;
  158502. +
  158503. + gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x",
  158504. + Device, Logical, Physical);
  158505. +
  158506. + gcmkVERIFY_ARGUMENT(Device != NULL);
  158507. +
  158508. + status = gckOS_FreeContiguous(
  158509. + Device->os, Physical, Logical,
  158510. + ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
  158511. + );
  158512. +
  158513. + gcmkFOOTER();
  158514. + return status;
  158515. +}
  158516. +
  158517. +
  158518. +
  158519. +/******************************************************************************\
  158520. +******************************* Interrupt Handler ******************************
  158521. +\******************************************************************************/
  158522. +static irqreturn_t isrRoutine(int irq, void *ctxt)
  158523. +{
  158524. + gceSTATUS status;
  158525. + gckGALDEVICE device;
  158526. +
  158527. + device = (gckGALDEVICE) ctxt;
  158528. +
  158529. + /* Call kernel interrupt notification. */
  158530. + status = gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvTRUE);
  158531. +
  158532. + if (gcmIS_SUCCESS(status))
  158533. + {
  158534. + device->dataReadys[gcvCORE_MAJOR] = gcvTRUE;
  158535. +
  158536. + up(&device->semas[gcvCORE_MAJOR]);
  158537. +
  158538. + return IRQ_HANDLED;
  158539. + }
  158540. +
  158541. + return IRQ_NONE;
  158542. +}
  158543. +
  158544. +static int threadRoutine(void *ctxt)
  158545. +{
  158546. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  158547. +
  158548. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  158549. + "Starting isr Thread with extension=%p",
  158550. + device);
  158551. +
  158552. + for (;;)
  158553. + {
  158554. + static int down;
  158555. +
  158556. + down = down_interruptible(&device->semas[gcvCORE_MAJOR]);
  158557. + if (down); /*To make gcc 4.6 happye*/
  158558. + device->dataReadys[gcvCORE_MAJOR] = gcvFALSE;
  158559. +
  158560. + if (device->killThread == gcvTRUE)
  158561. + {
  158562. + /* The daemon exits. */
  158563. + while (!kthread_should_stop())
  158564. + {
  158565. + gckOS_Delay(device->os, 1);
  158566. + }
  158567. +
  158568. + return 0;
  158569. + }
  158570. +
  158571. + gckKERNEL_Notify(device->kernels[gcvCORE_MAJOR], gcvNOTIFY_INTERRUPT, gcvFALSE);
  158572. + }
  158573. +}
  158574. +
  158575. +static irqreturn_t isrRoutine2D(int irq, void *ctxt)
  158576. +{
  158577. + gceSTATUS status;
  158578. + gckGALDEVICE device;
  158579. +
  158580. + device = (gckGALDEVICE) ctxt;
  158581. +
  158582. + /* Call kernel interrupt notification. */
  158583. + status = gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvTRUE);
  158584. +
  158585. + if (gcmIS_SUCCESS(status))
  158586. + {
  158587. + device->dataReadys[gcvCORE_2D] = gcvTRUE;
  158588. +
  158589. + up(&device->semas[gcvCORE_2D]);
  158590. +
  158591. + return IRQ_HANDLED;
  158592. + }
  158593. +
  158594. + return IRQ_NONE;
  158595. +}
  158596. +
  158597. +static int threadRoutine2D(void *ctxt)
  158598. +{
  158599. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  158600. +
  158601. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  158602. + "Starting isr Thread with extension=%p",
  158603. + device);
  158604. +
  158605. + for (;;)
  158606. + {
  158607. + static int down;
  158608. +
  158609. + down = down_interruptible(&device->semas[gcvCORE_2D]);
  158610. + if (down); /*To make gcc 4.6 happye*/
  158611. + device->dataReadys[gcvCORE_2D] = gcvFALSE;
  158612. +
  158613. + if (device->killThread == gcvTRUE)
  158614. + {
  158615. + /* The daemon exits. */
  158616. + while (!kthread_should_stop())
  158617. + {
  158618. + gckOS_Delay(device->os, 1);
  158619. + }
  158620. +
  158621. + return 0;
  158622. + }
  158623. +
  158624. + gckKERNEL_Notify(device->kernels[gcvCORE_2D], gcvNOTIFY_INTERRUPT, gcvFALSE);
  158625. + }
  158626. +}
  158627. +
  158628. +static irqreturn_t isrRoutineVG(int irq, void *ctxt)
  158629. +{
  158630. +#if gcdENABLE_VG
  158631. + gceSTATUS status;
  158632. + gckGALDEVICE device;
  158633. +
  158634. + device = (gckGALDEVICE) ctxt;
  158635. +
  158636. + /* Serve the interrupt. */
  158637. + status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt);
  158638. +
  158639. + /* Determine the return value. */
  158640. + return (status == gcvSTATUS_NOT_OUR_INTERRUPT)
  158641. + ? IRQ_RETVAL(0)
  158642. + : IRQ_RETVAL(1);
  158643. +#else
  158644. + return IRQ_NONE;
  158645. +#endif
  158646. +}
  158647. +
  158648. +static int threadRoutineVG(void *ctxt)
  158649. +{
  158650. + gckGALDEVICE device = (gckGALDEVICE) ctxt;
  158651. +
  158652. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  158653. + "Starting isr Thread with extension=%p",
  158654. + device);
  158655. +
  158656. + for (;;)
  158657. + {
  158658. + static int down;
  158659. +
  158660. + down = down_interruptible(&device->semas[gcvCORE_VG]);
  158661. + if (down); /*To make gcc 4.6 happye*/
  158662. + device->dataReadys[gcvCORE_VG] = gcvFALSE;
  158663. +
  158664. + if (device->killThread == gcvTRUE)
  158665. + {
  158666. + /* The daemon exits. */
  158667. + while (!kthread_should_stop())
  158668. + {
  158669. + gckOS_Delay(device->os, 1);
  158670. + }
  158671. +
  158672. + return 0;
  158673. + }
  158674. +
  158675. + gckKERNEL_Notify(device->kernels[gcvCORE_VG], gcvNOTIFY_INTERRUPT, gcvFALSE);
  158676. + }
  158677. +}
  158678. +
  158679. +/******************************************************************************\
  158680. +******************************* gckGALDEVICE Code ******************************
  158681. +\******************************************************************************/
  158682. +
  158683. +/*******************************************************************************
  158684. +**
  158685. +** gckGALDEVICE_Construct
  158686. +**
  158687. +** Constructor.
  158688. +**
  158689. +** INPUT:
  158690. +**
  158691. +** OUTPUT:
  158692. +**
  158693. +** gckGALDEVICE * Device
  158694. +** Pointer to a variable receiving the gckGALDEVICE object pointer on
  158695. +** success.
  158696. +*/
  158697. +gceSTATUS
  158698. +gckGALDEVICE_Construct(
  158699. + IN gctINT IrqLine,
  158700. + IN gctUINT32 RegisterMemBase,
  158701. + IN gctSIZE_T RegisterMemSize,
  158702. + IN gctINT IrqLine2D,
  158703. + IN gctUINT32 RegisterMemBase2D,
  158704. + IN gctSIZE_T RegisterMemSize2D,
  158705. + IN gctINT IrqLineVG,
  158706. + IN gctUINT32 RegisterMemBaseVG,
  158707. + IN gctSIZE_T RegisterMemSizeVG,
  158708. + IN gctUINT32 ContiguousBase,
  158709. + IN gctSIZE_T ContiguousSize,
  158710. + IN gctSIZE_T BankSize,
  158711. + IN gctINT FastClear,
  158712. + IN gctINT Compression,
  158713. + IN gctUINT32 PhysBaseAddr,
  158714. + IN gctUINT32 PhysSize,
  158715. + IN gctINT Signal,
  158716. + IN gctUINT LogFileSize,
  158717. + IN struct device *pdev,
  158718. + IN gctINT PowerManagement,
  158719. + IN gctINT GpuProfiler,
  158720. + OUT gckGALDEVICE *Device
  158721. + )
  158722. +{
  158723. + gctUINT32 internalBaseAddress = 0, internalAlignment = 0;
  158724. + gctUINT32 externalBaseAddress = 0, externalAlignment = 0;
  158725. + gctUINT32 horizontalTileSize, verticalTileSize;
  158726. + struct resource* mem_region;
  158727. + gctUINT32 physAddr;
  158728. + gctUINT32 physical;
  158729. + gckGALDEVICE device;
  158730. + gceSTATUS status;
  158731. + gctINT32 i;
  158732. + gceHARDWARE_TYPE type;
  158733. + gckDB sharedDB = gcvNULL;
  158734. + gckKERNEL kernel = gcvNULL;
  158735. +
  158736. + gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u "
  158737. + "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u "
  158738. + "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u "
  158739. + "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu "
  158740. + "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d",
  158741. + IrqLine, RegisterMemBase, RegisterMemSize,
  158742. + IrqLine2D, RegisterMemBase2D, RegisterMemSize2D,
  158743. + IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG,
  158744. + ContiguousBase, ContiguousSize, BankSize, FastClear, Compression,
  158745. + PhysBaseAddr, PhysSize, Signal);
  158746. +
  158747. + /* Allocate device structure. */
  158748. + device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL);
  158749. +
  158750. + if (!device)
  158751. + {
  158752. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  158753. + }
  158754. +
  158755. + memset(device, 0, sizeof(struct _gckGALDEVICE));
  158756. +
  158757. + device->dbgnode = gcvNULL;
  158758. + if(LogFileSize != 0)
  158759. + {
  158760. + if(gckDebugFileSystemCreateNode(LogFileSize,PARENT_FILE,DEBUG_FILE,&(device->dbgnode)) != 0)
  158761. + {
  158762. + gcmkTRACE_ZONE(
  158763. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158764. + "%s(%d): Failed to create the debug file system %s/%s \n",
  158765. + __FUNCTION__, __LINE__,
  158766. + PARENT_FILE, DEBUG_FILE
  158767. + );
  158768. + }
  158769. + else
  158770. + {
  158771. + /*Everything is OK*/
  158772. + gckDebugFileSystemSetCurrentNode(device->dbgnode);
  158773. + }
  158774. + }
  158775. +#ifdef CONFIG_PM
  158776. + /*Init runtime pm for gpu*/
  158777. + pm_runtime_enable(pdev);
  158778. + device->pmdev = pdev;
  158779. +#endif
  158780. +
  158781. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  158782. + /*get gpu regulator*/
  158783. + device->gpu_regulator = regulator_get(pdev, "cpu_vddgpu");
  158784. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  158785. + device->gpu_regulator = devm_regulator_get(pdev, "pu");
  158786. +#endif
  158787. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  158788. + if (IS_ERR(device->gpu_regulator)) {
  158789. + gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158790. + "%s(%d): Failed to get gpu regulator %s/%s \n",
  158791. + __FUNCTION__, __LINE__,
  158792. + PARENT_FILE, DEBUG_FILE);
  158793. + gcmkONERROR(gcvSTATUS_NOT_FOUND);
  158794. + }
  158795. +#endif
  158796. + /*Initialize the clock structure*/
  158797. + if (IrqLine != -1) {
  158798. + device->clk_3d_core = clk_get(pdev, "gpu3d_clk");
  158799. + if (!IS_ERR(device->clk_3d_core)) {
  158800. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  158801. + if (cpu_is_mx6q()) {
  158802. + device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
  158803. + if (IS_ERR(device->clk_3d_shader)) {
  158804. + IrqLine = -1;
  158805. + clk_put(device->clk_3d_core);
  158806. + device->clk_3d_core = NULL;
  158807. + device->clk_3d_shader = NULL;
  158808. + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
  158809. + }
  158810. + }
  158811. +#else
  158812. + device->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk");
  158813. + device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk");
  158814. + if (IS_ERR(device->clk_3d_shader)) {
  158815. + IrqLine = -1;
  158816. + clk_put(device->clk_3d_core);
  158817. + device->clk_3d_core = NULL;
  158818. + device->clk_3d_shader = NULL;
  158819. + gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n");
  158820. + }
  158821. +#endif
  158822. + } else {
  158823. + IrqLine = -1;
  158824. + device->clk_3d_core = NULL;
  158825. + gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n");
  158826. + }
  158827. + }
  158828. + if ((IrqLine2D != -1) || (IrqLineVG != -1)) {
  158829. + device->clk_2d_core = clk_get(pdev, "gpu2d_clk");
  158830. + if (IS_ERR(device->clk_2d_core)) {
  158831. + IrqLine2D = -1;
  158832. + IrqLineVG = -1;
  158833. + device->clk_2d_core = NULL;
  158834. + gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n");
  158835. + } else {
  158836. + if (IrqLine2D != -1) {
  158837. + device->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk");
  158838. + if (IS_ERR(device->clk_2d_axi)) {
  158839. + device->clk_2d_axi = NULL;
  158840. + IrqLine2D = -1;
  158841. + gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n");
  158842. + }
  158843. + }
  158844. + if (IrqLineVG != -1) {
  158845. + device->clk_vg_axi = clk_get(pdev, "openvg_axi_clk");
  158846. + if (IS_ERR(device->clk_vg_axi)) {
  158847. + IrqLineVG = -1;
  158848. + device->clk_vg_axi = NULL;
  158849. + gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n");
  158850. + }
  158851. + }
  158852. + }
  158853. + }
  158854. +
  158855. + if (IrqLine != -1)
  158856. + {
  158857. + device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
  158858. + device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize;
  158859. + }
  158860. +
  158861. + if (IrqLine2D != -1)
  158862. + {
  158863. + device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D;
  158864. + device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D;
  158865. + }
  158866. +
  158867. + if (IrqLineVG != -1)
  158868. + {
  158869. + device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG;
  158870. + device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG;
  158871. + }
  158872. +
  158873. + device->requestedContiguousBase = 0;
  158874. + device->requestedContiguousSize = 0;
  158875. +
  158876. +
  158877. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  158878. + {
  158879. + physical = device->requestedRegisterMemBases[i];
  158880. +
  158881. + /* Set up register memory region. */
  158882. + if (physical != 0)
  158883. + {
  158884. + mem_region = request_mem_region(
  158885. + physical, device->requestedRegisterMemSizes[i], "galcore register region"
  158886. + );
  158887. +
  158888. + if (mem_region == gcvNULL)
  158889. + {
  158890. + gcmkTRACE_ZONE(
  158891. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158892. + "%s(%d): Failed to claim %lu bytes @ 0x%08X\n",
  158893. + __FUNCTION__, __LINE__,
  158894. + physical, device->requestedRegisterMemSizes[i]
  158895. + );
  158896. +
  158897. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  158898. + }
  158899. +
  158900. + device->registerBases[i] = (gctPOINTER) ioremap_nocache(
  158901. + physical, device->requestedRegisterMemSizes[i]);
  158902. +
  158903. + if (device->registerBases[i] == gcvNULL)
  158904. + {
  158905. + gcmkTRACE_ZONE(
  158906. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158907. + "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
  158908. + __FUNCTION__, __LINE__,
  158909. + physical, device->requestedRegisterMemSizes[i]
  158910. + );
  158911. +
  158912. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  158913. + }
  158914. +
  158915. + physical += device->requestedRegisterMemSizes[i];
  158916. + }
  158917. + else
  158918. + {
  158919. + device->registerBases[i] = gcvNULL;
  158920. + }
  158921. + }
  158922. +
  158923. + /* Set the base address */
  158924. + device->baseAddress = PhysBaseAddr;
  158925. +
  158926. + /* Construct the gckOS object. */
  158927. + gcmkONERROR(gckOS_Construct(device, &device->os));
  158928. +
  158929. + if (IrqLine != -1)
  158930. + {
  158931. + /* Construct the gckKERNEL object. */
  158932. + gcmkONERROR(gckKERNEL_Construct(
  158933. + device->os, gcvCORE_MAJOR, device,
  158934. + gcvNULL, &device->kernels[gcvCORE_MAJOR]));
  158935. +
  158936. + sharedDB = device->kernels[gcvCORE_MAJOR]->db;
  158937. +
  158938. + /* Initialize core mapping */
  158939. + for (i = 0; i < 8; i++)
  158940. + {
  158941. + device->coreMapping[i] = gcvCORE_MAJOR;
  158942. + }
  158943. +
  158944. + /* Setup the ISR manager. */
  158945. + gcmkONERROR(gckHARDWARE_SetIsrManager(
  158946. + device->kernels[gcvCORE_MAJOR]->hardware,
  158947. + (gctISRMANAGERFUNC) gckGALDEVICE_Enable_ISR,
  158948. + (gctISRMANAGERFUNC) gckGALDEVICE_Disable_ISR,
  158949. + device
  158950. + ));
  158951. +
  158952. + gcmkONERROR(gckHARDWARE_SetFastClear(
  158953. + device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
  158954. + ));
  158955. +
  158956. + gcmkONERROR(gckHARDWARE_SetPowerManagement(
  158957. + device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
  158958. + ));
  158959. +
  158960. + gcmkONERROR(gckHARDWARE_SetGpuProfiler(
  158961. + device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler
  158962. + ));
  158963. +
  158964. +#if COMMAND_PROCESSOR_VERSION == 1
  158965. + /* Start the command queue. */
  158966. + gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command));
  158967. +#endif
  158968. + }
  158969. + else
  158970. + {
  158971. + device->kernels[gcvCORE_MAJOR] = gcvNULL;
  158972. + }
  158973. +
  158974. + if (IrqLine2D != -1)
  158975. + {
  158976. + gcmkONERROR(gckKERNEL_Construct(
  158977. + device->os, gcvCORE_2D, device,
  158978. + sharedDB, &device->kernels[gcvCORE_2D]));
  158979. +
  158980. + if (sharedDB == gcvNULL) sharedDB = device->kernels[gcvCORE_2D]->db;
  158981. +
  158982. + /* Verify the hardware type */
  158983. + gcmkONERROR(gckHARDWARE_GetType(device->kernels[gcvCORE_2D]->hardware, &type));
  158984. +
  158985. + if (type != gcvHARDWARE_2D)
  158986. + {
  158987. + gcmkTRACE_ZONE(
  158988. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  158989. + "%s(%d): Unexpected hardware type: %d\n",
  158990. + __FUNCTION__, __LINE__,
  158991. + type
  158992. + );
  158993. +
  158994. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  158995. + }
  158996. +
  158997. + /* Initialize core mapping */
  158998. + if (device->kernels[gcvCORE_MAJOR] == gcvNULL)
  158999. + {
  159000. + for (i = 0; i < 8; i++)
  159001. + {
  159002. + device->coreMapping[i] = gcvCORE_2D;
  159003. + }
  159004. + }
  159005. + else
  159006. + {
  159007. + device->coreMapping[gcvHARDWARE_2D] = gcvCORE_2D;
  159008. + }
  159009. +
  159010. + /* Setup the ISR manager. */
  159011. + gcmkONERROR(gckHARDWARE_SetIsrManager(
  159012. + device->kernels[gcvCORE_2D]->hardware,
  159013. + (gctISRMANAGERFUNC) gckGALDEVICE_Enable_ISR,
  159014. + (gctISRMANAGERFUNC) gckGALDEVICE_Disable_ISR,
  159015. + device
  159016. + ));
  159017. +
  159018. + gcmkONERROR(gckHARDWARE_SetPowerManagement(
  159019. + device->kernels[gcvCORE_2D]->hardware, PowerManagement
  159020. + ));
  159021. +
  159022. +
  159023. +#if COMMAND_PROCESSOR_VERSION == 1
  159024. + /* Start the command queue. */
  159025. + gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command));
  159026. +#endif
  159027. + }
  159028. + else
  159029. + {
  159030. + device->kernels[gcvCORE_2D] = gcvNULL;
  159031. + }
  159032. +
  159033. + if (IrqLineVG != -1)
  159034. + {
  159035. +#if gcdENABLE_VG
  159036. + gcmkONERROR(gckKERNEL_Construct(
  159037. + device->os, gcvCORE_VG, device,
  159038. + sharedDB, &device->kernels[gcvCORE_VG]));
  159039. + /* Initialize core mapping */
  159040. + if (device->kernels[gcvCORE_MAJOR] == gcvNULL
  159041. + && device->kernels[gcvCORE_2D] == gcvNULL
  159042. + )
  159043. + {
  159044. + for (i = 0; i < 8; i++)
  159045. + {
  159046. + device->coreMapping[i] = gcvCORE_VG;
  159047. + }
  159048. + }
  159049. + else
  159050. + {
  159051. + device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG;
  159052. + }
  159053. +
  159054. +
  159055. + gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
  159056. + device->kernels[gcvCORE_VG]->vg->hardware,
  159057. + PowerManagement
  159058. + ));
  159059. +
  159060. +#endif
  159061. + }
  159062. + else
  159063. + {
  159064. + device->kernels[gcvCORE_VG] = gcvNULL;
  159065. + }
  159066. +
  159067. + /* Initialize the ISR. */
  159068. + device->irqLines[gcvCORE_MAJOR] = IrqLine;
  159069. + device->irqLines[gcvCORE_2D] = IrqLine2D;
  159070. + device->irqLines[gcvCORE_VG] = IrqLineVG;
  159071. +
  159072. + /* Initialize the kernel thread semaphores. */
  159073. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159074. + {
  159075. + if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0);
  159076. + }
  159077. +
  159078. + device->signal = Signal;
  159079. +
  159080. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159081. + {
  159082. + if (device->kernels[i] != gcvNULL) break;
  159083. + }
  159084. +
  159085. + if (i == gcdMAX_GPU_COUNT)
  159086. + {
  159087. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  159088. + }
  159089. +
  159090. +#if gcdENABLE_VG
  159091. + if (i == gcvCORE_VG)
  159092. + {
  159093. + /* Query the ceiling of the system memory. */
  159094. + gcmkONERROR(gckVGHARDWARE_QuerySystemMemory(
  159095. + device->kernels[i]->vg->hardware,
  159096. + &device->systemMemorySize,
  159097. + &device->systemMemoryBaseAddress
  159098. + ));
  159099. + /* query the amount of video memory */
  159100. + gcmkONERROR(gckVGHARDWARE_QueryMemory(
  159101. + device->kernels[i]->vg->hardware,
  159102. + &device->internalSize, &internalBaseAddress, &internalAlignment,
  159103. + &device->externalSize, &externalBaseAddress, &externalAlignment,
  159104. + &horizontalTileSize, &verticalTileSize
  159105. + ));
  159106. + }
  159107. + else
  159108. +#endif
  159109. + {
  159110. + /* Query the ceiling of the system memory. */
  159111. + gcmkONERROR(gckHARDWARE_QuerySystemMemory(
  159112. + device->kernels[i]->hardware,
  159113. + &device->systemMemorySize,
  159114. + &device->systemMemoryBaseAddress
  159115. + ));
  159116. +
  159117. + /* query the amount of video memory */
  159118. + gcmkONERROR(gckHARDWARE_QueryMemory(
  159119. + device->kernels[i]->hardware,
  159120. + &device->internalSize, &internalBaseAddress, &internalAlignment,
  159121. + &device->externalSize, &externalBaseAddress, &externalAlignment,
  159122. + &horizontalTileSize, &verticalTileSize
  159123. + ));
  159124. + }
  159125. +
  159126. +
  159127. + /* Grab the first availiable kernel */
  159128. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159129. + {
  159130. + if (device->irqLines[i] != -1)
  159131. + {
  159132. + kernel = device->kernels[i];
  159133. + break;
  159134. + }
  159135. + }
  159136. +
  159137. + /* Set up the internal memory region. */
  159138. + if (device->internalSize > 0)
  159139. + {
  159140. + status = gckVIDMEM_Construct(
  159141. + device->os,
  159142. + internalBaseAddress, device->internalSize, internalAlignment,
  159143. + 0, &device->internalVidMem
  159144. + );
  159145. +
  159146. + if (gcmIS_ERROR(status))
  159147. + {
  159148. + /* Error, disable internal heap. */
  159149. + device->internalSize = 0;
  159150. + }
  159151. + else
  159152. + {
  159153. + /* Map internal memory. */
  159154. + device->internalLogical
  159155. + = (gctPOINTER) ioremap_nocache(physical, device->internalSize);
  159156. +
  159157. + if (device->internalLogical == gcvNULL)
  159158. + {
  159159. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  159160. + }
  159161. +
  159162. + device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
  159163. + device->internalPhysicalName = gcmPTR_TO_NAME(device->internalPhysical);
  159164. + physical += device->internalSize;
  159165. + }
  159166. + }
  159167. +
  159168. + if (device->externalSize > 0)
  159169. + {
  159170. + /* create the external memory heap */
  159171. + status = gckVIDMEM_Construct(
  159172. + device->os,
  159173. + externalBaseAddress, device->externalSize, externalAlignment,
  159174. + 0, &device->externalVidMem
  159175. + );
  159176. +
  159177. + if (gcmIS_ERROR(status))
  159178. + {
  159179. + /* Error, disable internal heap. */
  159180. + device->externalSize = 0;
  159181. + }
  159182. + else
  159183. + {
  159184. + /* Map external memory. */
  159185. + device->externalLogical
  159186. + = (gctPOINTER) ioremap_nocache(physical, device->externalSize);
  159187. +
  159188. + if (device->externalLogical == gcvNULL)
  159189. + {
  159190. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  159191. + }
  159192. +
  159193. + device->externalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
  159194. + device->externalPhysicalName = gcmPTR_TO_NAME(device->externalPhysical);
  159195. + physical += device->externalSize;
  159196. + }
  159197. + }
  159198. +
  159199. + /* set up the contiguous memory */
  159200. + device->contiguousSize = ContiguousSize;
  159201. +
  159202. + if (ContiguousSize > 0)
  159203. + {
  159204. + if (ContiguousBase == 0)
  159205. + {
  159206. + while (device->contiguousSize > 0)
  159207. + {
  159208. + /* Allocate contiguous memory. */
  159209. + status = _AllocateMemory(
  159210. + device,
  159211. + device->contiguousSize,
  159212. + &device->contiguousBase,
  159213. + &device->contiguousPhysical,
  159214. + &physAddr
  159215. + );
  159216. +
  159217. + if (gcmIS_SUCCESS(status))
  159218. + {
  159219. + device->contiguousPhysicalName = gcmPTR_TO_NAME(device->contiguousPhysical);
  159220. + status = gckVIDMEM_Construct(
  159221. + device->os,
  159222. + physAddr | device->systemMemoryBaseAddress,
  159223. + device->contiguousSize,
  159224. + 64,
  159225. + BankSize,
  159226. + &device->contiguousVidMem
  159227. + );
  159228. +
  159229. + if (gcmIS_SUCCESS(status))
  159230. + {
  159231. + break;
  159232. + }
  159233. +
  159234. + gcmkONERROR(_FreeMemory(
  159235. + device,
  159236. + device->contiguousBase,
  159237. + device->contiguousPhysical
  159238. + ));
  159239. +
  159240. + gcmRELEASE_NAME(device->contiguousPhysicalName);
  159241. + device->contiguousBase = gcvNULL;
  159242. + device->contiguousPhysical = gcvNULL;
  159243. + }
  159244. +
  159245. + if (device->contiguousSize <= (4 << 20))
  159246. + {
  159247. + device->contiguousSize = 0;
  159248. + }
  159249. + else
  159250. + {
  159251. + device->contiguousSize -= (4 << 20);
  159252. + }
  159253. + }
  159254. + }
  159255. + else
  159256. + {
  159257. + /* Create the contiguous memory heap. */
  159258. + status = gckVIDMEM_Construct(
  159259. + device->os,
  159260. + ContiguousBase | device->systemMemoryBaseAddress,
  159261. + ContiguousSize,
  159262. + 64, BankSize,
  159263. + &device->contiguousVidMem
  159264. + );
  159265. +
  159266. + if (gcmIS_ERROR(status))
  159267. + {
  159268. + /* Error, disable contiguous memory pool. */
  159269. + device->contiguousVidMem = gcvNULL;
  159270. + device->contiguousSize = 0;
  159271. + }
  159272. + else
  159273. + {
  159274. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  159275. + mem_region = request_mem_region(
  159276. + ContiguousBase, ContiguousSize, "galcore managed memory"
  159277. + );
  159278. +
  159279. + if (mem_region == gcvNULL)
  159280. + {
  159281. + gcmkTRACE_ZONE(
  159282. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  159283. + "%s(%d): Failed to claim %ld bytes @ 0x%08X\n",
  159284. + __FUNCTION__, __LINE__,
  159285. + ContiguousSize, ContiguousBase
  159286. + );
  159287. +
  159288. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  159289. + }
  159290. +#endif
  159291. +
  159292. + device->requestedContiguousBase = ContiguousBase;
  159293. + device->requestedContiguousSize = ContiguousSize;
  159294. +
  159295. +#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  159296. + if (gcmIS_CORE_PRESENT(device, gcvCORE_VG))
  159297. + {
  159298. + device->contiguousBase
  159299. +#if gcdPAGED_MEMORY_CACHEABLE
  159300. + = (gctPOINTER) ioremap_cached(ContiguousBase, ContiguousSize);
  159301. +#else
  159302. + = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize);
  159303. +#endif
  159304. + if (device->contiguousBase == gcvNULL)
  159305. + {
  159306. + device->contiguousVidMem = gcvNULL;
  159307. + device->contiguousSize = 0;
  159308. +
  159309. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  159310. + }
  159311. + }
  159312. +#endif
  159313. +
  159314. + device->contiguousPhysical = gcvNULL;
  159315. + device->contiguousPhysicalName = 0;
  159316. + device->contiguousSize = ContiguousSize;
  159317. + device->contiguousMapped = gcvTRUE;
  159318. + }
  159319. + }
  159320. + }
  159321. +
  159322. + /* Return pointer to the device. */
  159323. + * Device = device;
  159324. +
  159325. + gcmkFOOTER_ARG("*Device=0x%x", * Device);
  159326. + return gcvSTATUS_OK;
  159327. +
  159328. +OnError:
  159329. + /* Roll back. */
  159330. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
  159331. +
  159332. + gcmkFOOTER();
  159333. + return status;
  159334. +}
  159335. +
  159336. +/*******************************************************************************
  159337. +**
  159338. +** gckGALDEVICE_Destroy
  159339. +**
  159340. +** Class destructor.
  159341. +**
  159342. +** INPUT:
  159343. +**
  159344. +** Nothing.
  159345. +**
  159346. +** OUTPUT:
  159347. +**
  159348. +** Nothing.
  159349. +**
  159350. +** RETURNS:
  159351. +**
  159352. +** Nothing.
  159353. +*/
  159354. +gceSTATUS
  159355. +gckGALDEVICE_Destroy(
  159356. + gckGALDEVICE Device)
  159357. +{
  159358. + gctINT i;
  159359. + gceSTATUS status = gcvSTATUS_OK;
  159360. + gckKERNEL kernel = gcvNULL;
  159361. +
  159362. + gcmkHEADER_ARG("Device=0x%x", Device);
  159363. +
  159364. + if (Device != gcvNULL)
  159365. + {
  159366. + /* Grab the first availiable kernel */
  159367. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159368. + {
  159369. + if (Device->irqLines[i] != -1)
  159370. + {
  159371. + kernel = Device->kernels[i];
  159372. + break;
  159373. + }
  159374. + }
  159375. + if (Device->internalPhysicalName != 0)
  159376. + {
  159377. + gcmRELEASE_NAME(Device->internalPhysicalName);
  159378. + Device->internalPhysicalName = 0;
  159379. + }
  159380. + if (Device->externalPhysicalName != 0)
  159381. + {
  159382. + gcmRELEASE_NAME(Device->externalPhysicalName);
  159383. + Device->externalPhysicalName = 0;
  159384. + }
  159385. + if (Device->contiguousPhysicalName != 0)
  159386. + {
  159387. + gcmRELEASE_NAME(Device->contiguousPhysicalName);
  159388. + Device->contiguousPhysicalName = 0;
  159389. + }
  159390. +
  159391. +
  159392. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159393. + {
  159394. + if (Device->kernels[i] != gcvNULL)
  159395. + {
  159396. + /* Destroy the gckKERNEL object. */
  159397. + gcmkVERIFY_OK(gckKERNEL_Destroy(Device->kernels[i]));
  159398. + Device->kernels[i] = gcvNULL;
  159399. + }
  159400. + }
  159401. +
  159402. + {
  159403. + if (Device->internalLogical != gcvNULL)
  159404. + {
  159405. + /* Unmap the internal memory. */
  159406. + iounmap(Device->internalLogical);
  159407. + Device->internalLogical = gcvNULL;
  159408. + }
  159409. +
  159410. + if (Device->internalVidMem != gcvNULL)
  159411. + {
  159412. + /* Destroy the internal heap. */
  159413. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->internalVidMem));
  159414. + Device->internalVidMem = gcvNULL;
  159415. + }
  159416. + }
  159417. +
  159418. + {
  159419. + if (Device->externalLogical != gcvNULL)
  159420. + {
  159421. + /* Unmap the external memory. */
  159422. + iounmap(Device->externalLogical);
  159423. + Device->externalLogical = gcvNULL;
  159424. + }
  159425. +
  159426. + if (Device->externalVidMem != gcvNULL)
  159427. + {
  159428. + /* destroy the external heap */
  159429. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->externalVidMem));
  159430. + Device->externalVidMem = gcvNULL;
  159431. + }
  159432. + }
  159433. +
  159434. + {
  159435. + if (Device->contiguousBase != gcvNULL)
  159436. + {
  159437. + if (Device->contiguousMapped)
  159438. + {
  159439. +#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
  159440. + if (Device->contiguousBase)
  159441. + {
  159442. + /* Unmap the contiguous memory. */
  159443. + iounmap(Device->contiguousBase);
  159444. + }
  159445. +#endif
  159446. + }
  159447. + else
  159448. + {
  159449. + gcmkONERROR(_FreeMemory(
  159450. + Device,
  159451. + Device->contiguousBase,
  159452. + Device->contiguousPhysical
  159453. + ));
  159454. + }
  159455. +
  159456. + Device->contiguousBase = gcvNULL;
  159457. + Device->contiguousPhysical = gcvNULL;
  159458. + }
  159459. +
  159460. + if (Device->requestedContiguousBase != 0)
  159461. + {
  159462. + release_mem_region(Device->requestedContiguousBase, Device->requestedContiguousSize);
  159463. + Device->requestedContiguousBase = 0;
  159464. + Device->requestedContiguousSize = 0;
  159465. + }
  159466. +
  159467. + if (Device->contiguousVidMem != gcvNULL)
  159468. + {
  159469. + /* Destroy the contiguous heap. */
  159470. + gcmkVERIFY_OK(gckVIDMEM_Destroy(Device->contiguousVidMem));
  159471. + Device->contiguousVidMem = gcvNULL;
  159472. + }
  159473. + }
  159474. +
  159475. + {
  159476. + if(gckDebugFileSystemIsEnabled())
  159477. + {
  159478. + gckDebugFileSystemFreeNode(Device->dbgnode);
  159479. + kfree(Device->dbgnode);
  159480. + Device->dbgnode = gcvNULL;
  159481. + }
  159482. + }
  159483. +
  159484. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159485. + {
  159486. + if (Device->registerBases[i] != gcvNULL)
  159487. + {
  159488. + /* Unmap register memory. */
  159489. + iounmap(Device->registerBases[i]);
  159490. + if (Device->requestedRegisterMemBases[i] != 0)
  159491. + {
  159492. + release_mem_region(Device->requestedRegisterMemBases[i], Device->requestedRegisterMemSizes[i]);
  159493. + }
  159494. +
  159495. + Device->registerBases[i] = gcvNULL;
  159496. + Device->requestedRegisterMemBases[i] = 0;
  159497. + Device->requestedRegisterMemSizes[i] = 0;
  159498. + }
  159499. + }
  159500. +
  159501. + /*Disable clock*/
  159502. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  159503. + if (Device->clk_3d_axi) {
  159504. + clk_put(Device->clk_3d_axi);
  159505. + Device->clk_3d_axi = NULL;
  159506. + }
  159507. +#endif
  159508. + if (Device->clk_3d_core) {
  159509. + clk_put(Device->clk_3d_core);
  159510. + Device->clk_3d_core = NULL;
  159511. + }
  159512. + if (Device->clk_3d_shader) {
  159513. + clk_put(Device->clk_3d_shader);
  159514. + Device->clk_3d_shader = NULL;
  159515. + }
  159516. + if (Device->clk_2d_core) {
  159517. + clk_put(Device->clk_2d_core);
  159518. + Device->clk_2d_core = NULL;
  159519. + }
  159520. + if (Device->clk_2d_axi) {
  159521. + clk_put(Device->clk_2d_axi);
  159522. + Device->clk_2d_axi = NULL;
  159523. + }
  159524. + if (Device->clk_vg_axi) {
  159525. + clk_put(Device->clk_vg_axi);
  159526. + Device->clk_vg_axi = NULL;
  159527. + }
  159528. +
  159529. +#ifdef CONFIG_PM
  159530. + if(Device->pmdev)
  159531. + pm_runtime_disable(Device->pmdev);
  159532. +#endif
  159533. +
  159534. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  159535. + if (Device->gpu_regulator) {
  159536. + regulator_put(Device->gpu_regulator);
  159537. + Device->gpu_regulator = NULL;
  159538. + }
  159539. +#endif
  159540. +
  159541. + /* Destroy the gckOS object. */
  159542. + if (Device->os != gcvNULL)
  159543. + {
  159544. + gcmkVERIFY_OK(gckOS_Destroy(Device->os));
  159545. + Device->os = gcvNULL;
  159546. + }
  159547. +
  159548. + /* Free the device. */
  159549. + kfree(Device);
  159550. + }
  159551. +
  159552. + gcmkFOOTER_NO();
  159553. + return gcvSTATUS_OK;
  159554. +
  159555. +OnError:
  159556. + gcmkFOOTER();
  159557. + return status;
  159558. +}
  159559. +
  159560. +/*******************************************************************************
  159561. +**
  159562. +** gckGALDEVICE_Setup_ISR
  159563. +**
  159564. +** Start the ISR routine.
  159565. +**
  159566. +** INPUT:
  159567. +**
  159568. +** gckGALDEVICE Device
  159569. +** Pointer to an gckGALDEVICE object.
  159570. +**
  159571. +** OUTPUT:
  159572. +**
  159573. +** Nothing.
  159574. +**
  159575. +** RETURNS:
  159576. +**
  159577. +** gcvSTATUS_OK
  159578. +** Setup successfully.
  159579. +** gcvSTATUS_GENERIC_IO
  159580. +** Setup failed.
  159581. +*/
  159582. +gceSTATUS
  159583. +gckGALDEVICE_Setup_ISR(
  159584. + IN gckGALDEVICE Device,
  159585. + IN gceCORE Core
  159586. + )
  159587. +{
  159588. + gceSTATUS status;
  159589. + gctINT ret = -1;
  159590. +
  159591. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  159592. +
  159593. + gcmkVERIFY_ARGUMENT(Device != NULL);
  159594. +
  159595. + if (Device->irqLines[Core] < 0)
  159596. + {
  159597. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  159598. + }
  159599. +
  159600. + /* Hook up the isr based on the irq line. */
  159601. +#ifdef FLAREON
  159602. + gc500_handle.dev_name = "galcore interrupt service";
  159603. + gc500_handle.dev_id = Device;
  159604. + switch (Core) {
  159605. + case gcvCORE_MAJOR:
  159606. + gc500_handle.handler = isrRoutine;
  159607. + break;
  159608. + case gcvCORE_2D:
  159609. + gc500_handle.handler = isrRoutine2D;
  159610. + break;
  159611. + case gcvCORE_VG:
  159612. + gc500_handle.handler = isrRoutineVG;
  159613. + break;
  159614. + default:
  159615. + break;
  159616. + }
  159617. + gc500_handle.intr_gen = GPIO_INTR_LEVEL_TRIGGER;
  159618. + gc500_handle.intr_trig = GPIO_TRIG_HIGH_LEVEL;
  159619. +
  159620. + ret = dove_gpio_request(
  159621. + DOVE_GPIO0_7, &gc500_handle
  159622. + );
  159623. +#else
  159624. + switch (Core) {
  159625. + case gcvCORE_MAJOR:
  159626. + ret = request_irq(
  159627. + Device->irqLines[Core], isrRoutine, IRQF_DISABLED,
  159628. + "galcore interrupt service", Device
  159629. + );
  159630. + break;
  159631. + case gcvCORE_2D:
  159632. + ret = request_irq(
  159633. + Device->irqLines[Core], isrRoutine2D, IRQF_DISABLED,
  159634. + "galcore 2D interrupt service", Device
  159635. + );
  159636. + break;
  159637. + case gcvCORE_VG:
  159638. + ret = request_irq(
  159639. + Device->irqLines[Core], isrRoutineVG, IRQF_DISABLED,
  159640. + "galcore VG interrupt service", Device
  159641. + );
  159642. + break;
  159643. + default:
  159644. + break;
  159645. + }
  159646. +#endif
  159647. +
  159648. + if (ret != 0)
  159649. + {
  159650. + gcmkTRACE_ZONE(
  159651. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  159652. + "%s(%d): Could not register irq line %d (error=%d)\n",
  159653. + __FUNCTION__, __LINE__,
  159654. + Device->irqLines[Core], ret
  159655. + );
  159656. +
  159657. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  159658. + }
  159659. +
  159660. + Device->isrEnabled[Core] = 1;
  159661. +
  159662. + /* Mark ISR as initialized. */
  159663. + Device->isrInitializeds[Core] = gcvTRUE;
  159664. +
  159665. + gcmkFOOTER_NO();
  159666. + return gcvSTATUS_OK;
  159667. +
  159668. +OnError:
  159669. + gcmkFOOTER();
  159670. + return status;
  159671. +}
  159672. +
  159673. +gceSTATUS
  159674. +gckGALDEVICE_Enable_ISR(
  159675. + IN gckGALDEVICE Device,
  159676. + IN gceCORE Core
  159677. + )
  159678. +{
  159679. + gceSTATUS status;
  159680. +
  159681. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  159682. +
  159683. + gcmkVERIFY_ARGUMENT(Device != NULL);
  159684. +
  159685. + if (Device->irqLines[Core] < 0)
  159686. + {
  159687. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  159688. + }
  159689. +
  159690. + spin_lock(&Device->kernels[Core]->irq_lock);
  159691. + if (Device->isrEnabled[Core] == 0)
  159692. + {
  159693. + enable_irq(Device->irqLines[Core]);
  159694. + /* Mark ISR as initialized. */
  159695. + Device->isrEnabled[Core] = gcvTRUE;
  159696. + }
  159697. + Device->isrEnabled[Core]++;
  159698. + spin_unlock(&Device->kernels[Core]->irq_lock);
  159699. +
  159700. + gcmkFOOTER_NO();
  159701. + return gcvSTATUS_OK;
  159702. +
  159703. +OnError:
  159704. + gcmkFOOTER();
  159705. + return status;
  159706. +}
  159707. +
  159708. +/*******************************************************************************
  159709. +**
  159710. +** gckGALDEVICE_Release_ISR
  159711. +**
  159712. +** Release the irq line.
  159713. +**
  159714. +** INPUT:
  159715. +**
  159716. +** gckGALDEVICE Device
  159717. +** Pointer to an gckGALDEVICE object.
  159718. +**
  159719. +** OUTPUT:
  159720. +**
  159721. +** Nothing.
  159722. +**
  159723. +** RETURNS:
  159724. +**
  159725. +** Nothing.
  159726. +*/
  159727. +gceSTATUS
  159728. +gckGALDEVICE_Release_ISR(
  159729. + IN gckGALDEVICE Device,
  159730. + IN gceCORE Core
  159731. + )
  159732. +{
  159733. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  159734. +
  159735. + gcmkVERIFY_ARGUMENT(Device != NULL);
  159736. +
  159737. + /* release the irq */
  159738. + if (Device->isrInitializeds[Core])
  159739. + {
  159740. +#ifdef FLAREON
  159741. + dove_gpio_free(DOVE_GPIO0_7, "galcore interrupt service");
  159742. +#else
  159743. + free_irq(Device->irqLines[Core], Device);
  159744. +#endif
  159745. +
  159746. + Device->isrInitializeds[Core] = gcvFALSE;
  159747. + }
  159748. +
  159749. + gcmkFOOTER_NO();
  159750. + return gcvSTATUS_OK;
  159751. +}
  159752. +
  159753. +gceSTATUS
  159754. +gckGALDEVICE_Disable_ISR(
  159755. + IN gckGALDEVICE Device,
  159756. + IN gceCORE Core
  159757. + )
  159758. +{
  159759. + gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
  159760. +
  159761. + gcmkVERIFY_ARGUMENT(Device != NULL);
  159762. +
  159763. + /* disable the irq */
  159764. + spin_lock(&Device->kernels[Core]->irq_lock);
  159765. + if (Device->isrEnabled[Core] > 0)
  159766. + {
  159767. + Device->isrEnabled[Core]--;
  159768. + if (Device->isrEnabled[Core] == 0)
  159769. + disable_irq(Device->irqLines[Core]);
  159770. + }
  159771. + spin_unlock(&Device->kernels[Core]->irq_lock);
  159772. +
  159773. + gcmkFOOTER_NO();
  159774. + return gcvSTATUS_OK;
  159775. +}
  159776. +
  159777. +/*******************************************************************************
  159778. +**
  159779. +** gckGALDEVICE_Start_Threads
  159780. +**
  159781. +** Start the daemon threads.
  159782. +**
  159783. +** INPUT:
  159784. +**
  159785. +** gckGALDEVICE Device
  159786. +** Pointer to an gckGALDEVICE object.
  159787. +**
  159788. +** OUTPUT:
  159789. +**
  159790. +** Nothing.
  159791. +**
  159792. +** RETURNS:
  159793. +**
  159794. +** gcvSTATUS_OK
  159795. +** Start successfully.
  159796. +** gcvSTATUS_GENERIC_IO
  159797. +** Start failed.
  159798. +*/
  159799. +gceSTATUS
  159800. +gckGALDEVICE_Start_Threads(
  159801. + IN gckGALDEVICE Device
  159802. + )
  159803. +{
  159804. + gceSTATUS status;
  159805. + struct task_struct * task;
  159806. +
  159807. + gcmkHEADER_ARG("Device=0x%x", Device);
  159808. +
  159809. + gcmkVERIFY_ARGUMENT(Device != NULL);
  159810. +
  159811. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  159812. + {
  159813. + /* Start the kernel thread. */
  159814. + task = kthread_run(threadRoutine, Device, "galcore daemon thread");
  159815. +
  159816. + if (IS_ERR(task))
  159817. + {
  159818. + gcmkTRACE_ZONE(
  159819. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  159820. + "%s(%d): Could not start the kernel thread.\n",
  159821. + __FUNCTION__, __LINE__
  159822. + );
  159823. +
  159824. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  159825. + }
  159826. +
  159827. + Device->threadCtxts[gcvCORE_MAJOR] = task;
  159828. + Device->threadInitializeds[gcvCORE_MAJOR] = gcvTRUE;
  159829. + }
  159830. +
  159831. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  159832. + {
  159833. + /* Start the kernel thread. */
  159834. + task = kthread_run(threadRoutine2D, Device, "galcore daemon thread for 2D");
  159835. +
  159836. + if (IS_ERR(task))
  159837. + {
  159838. + gcmkTRACE_ZONE(
  159839. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  159840. + "%s(%d): Could not start the kernel thread.\n",
  159841. + __FUNCTION__, __LINE__
  159842. + );
  159843. +
  159844. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  159845. + }
  159846. +
  159847. + Device->threadCtxts[gcvCORE_2D] = task;
  159848. + Device->threadInitializeds[gcvCORE_2D] = gcvTRUE;
  159849. + }
  159850. + else
  159851. + {
  159852. + Device->threadInitializeds[gcvCORE_2D] = gcvFALSE;
  159853. + }
  159854. +
  159855. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  159856. + {
  159857. + /* Start the kernel thread. */
  159858. + task = kthread_run(threadRoutineVG, Device, "galcore daemon thread for VG");
  159859. +
  159860. + if (IS_ERR(task))
  159861. + {
  159862. + gcmkTRACE_ZONE(
  159863. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  159864. + "%s(%d): Could not start the kernel thread.\n",
  159865. + __FUNCTION__, __LINE__
  159866. + );
  159867. +
  159868. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  159869. + }
  159870. +
  159871. + Device->threadCtxts[gcvCORE_VG] = task;
  159872. + Device->threadInitializeds[gcvCORE_VG] = gcvTRUE;
  159873. + }
  159874. + else
  159875. + {
  159876. + Device->threadInitializeds[gcvCORE_VG] = gcvFALSE;
  159877. + }
  159878. +
  159879. + gcmkFOOTER_NO();
  159880. + return gcvSTATUS_OK;
  159881. +
  159882. +OnError:
  159883. + gcmkFOOTER();
  159884. + return status;
  159885. +}
  159886. +
  159887. +/*******************************************************************************
  159888. +**
  159889. +** gckGALDEVICE_Stop_Threads
  159890. +**
  159891. +** Stop the gal device, including the following actions: stop the daemon
  159892. +** thread, release the irq.
  159893. +**
  159894. +** INPUT:
  159895. +**
  159896. +** gckGALDEVICE Device
  159897. +** Pointer to an gckGALDEVICE object.
  159898. +**
  159899. +** OUTPUT:
  159900. +**
  159901. +** Nothing.
  159902. +**
  159903. +** RETURNS:
  159904. +**
  159905. +** Nothing.
  159906. +*/
  159907. +gceSTATUS
  159908. +gckGALDEVICE_Stop_Threads(
  159909. + gckGALDEVICE Device
  159910. + )
  159911. +{
  159912. + gctINT i;
  159913. +
  159914. + gcmkHEADER_ARG("Device=0x%x", Device);
  159915. +
  159916. + gcmkVERIFY_ARGUMENT(Device != NULL);
  159917. +
  159918. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  159919. + {
  159920. + /* Stop the kernel threads. */
  159921. + if (Device->threadInitializeds[i])
  159922. + {
  159923. + Device->killThread = gcvTRUE;
  159924. + up(&Device->semas[i]);
  159925. +
  159926. + kthread_stop(Device->threadCtxts[i]);
  159927. + Device->threadCtxts[i] = gcvNULL;
  159928. + Device->threadInitializeds[i] = gcvFALSE;
  159929. + }
  159930. + }
  159931. +
  159932. + gcmkFOOTER_NO();
  159933. + return gcvSTATUS_OK;
  159934. +}
  159935. +
  159936. +/*******************************************************************************
  159937. +**
  159938. +** gckGALDEVICE_Start
  159939. +**
  159940. +** Start the gal device, including the following actions: setup the isr routine
  159941. +** and start the daemoni thread.
  159942. +**
  159943. +** INPUT:
  159944. +**
  159945. +** gckGALDEVICE Device
  159946. +** Pointer to an gckGALDEVICE object.
  159947. +**
  159948. +** OUTPUT:
  159949. +**
  159950. +** Nothing.
  159951. +**
  159952. +** RETURNS:
  159953. +**
  159954. +** gcvSTATUS_OK
  159955. +** Start successfully.
  159956. +*/
  159957. +gceSTATUS
  159958. +gckGALDEVICE_Start(
  159959. + IN gckGALDEVICE Device
  159960. + )
  159961. +{
  159962. + gceSTATUS status;
  159963. +
  159964. + gcmkHEADER_ARG("Device=0x%x", Device);
  159965. +
  159966. + /* Start the kernel thread. */
  159967. + gcmkONERROR(gckGALDEVICE_Start_Threads(Device));
  159968. +
  159969. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  159970. + {
  159971. + /* Setup the ISR routine. */
  159972. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_MAJOR));
  159973. +
  159974. + /* Switch to SUSPEND power state. */
  159975. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  159976. + Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_OFF_BROADCAST
  159977. + ));
  159978. + }
  159979. +
  159980. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  159981. + {
  159982. + /* Setup the ISR routine. */
  159983. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_2D));
  159984. +
  159985. + /* Switch to SUSPEND power state. */
  159986. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  159987. + Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_OFF_BROADCAST
  159988. + ));
  159989. + }
  159990. +
  159991. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  159992. + {
  159993. + /* Setup the ISR routine. */
  159994. + gcmkONERROR(gckGALDEVICE_Setup_ISR(Device, gcvCORE_VG));
  159995. +
  159996. + /* Switch to SUSPEND power state. */
  159997. + gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
  159998. + Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST
  159999. + ));
  160000. + }
  160001. +
  160002. + gcmkFOOTER_NO();
  160003. + return gcvSTATUS_OK;
  160004. +
  160005. +OnError:
  160006. + gcmkFOOTER();
  160007. + return status;
  160008. +}
  160009. +
  160010. +/*******************************************************************************
  160011. +**
  160012. +** gckGALDEVICE_Stop
  160013. +**
  160014. +** Stop the gal device, including the following actions: stop the daemon
  160015. +** thread, release the irq.
  160016. +**
  160017. +** INPUT:
  160018. +**
  160019. +** gckGALDEVICE Device
  160020. +** Pointer to an gckGALDEVICE object.
  160021. +**
  160022. +** OUTPUT:
  160023. +**
  160024. +** Nothing.
  160025. +**
  160026. +** RETURNS:
  160027. +**
  160028. +** Nothing.
  160029. +*/
  160030. +gceSTATUS
  160031. +gckGALDEVICE_Stop(
  160032. + gckGALDEVICE Device
  160033. + )
  160034. +{
  160035. + gceSTATUS status;
  160036. +
  160037. + gcmkHEADER_ARG("Device=0x%x", Device);
  160038. +
  160039. + gcmkVERIFY_ARGUMENT(Device != NULL);
  160040. +
  160041. + if (Device->kernels[gcvCORE_MAJOR] != gcvNULL)
  160042. + {
  160043. + /* Switch to OFF power state. */
  160044. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  160045. + Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_OFF
  160046. + ));
  160047. +
  160048. + /* Remove the ISR routine. */
  160049. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_MAJOR));
  160050. + }
  160051. +
  160052. + if (Device->kernels[gcvCORE_2D] != gcvNULL)
  160053. + {
  160054. + /* Setup the ISR routine. */
  160055. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_2D));
  160056. +
  160057. + /* Switch to OFF power state. */
  160058. + gcmkONERROR(gckHARDWARE_SetPowerManagementState(
  160059. + Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_OFF
  160060. + ));
  160061. + }
  160062. +
  160063. + if (Device->kernels[gcvCORE_VG] != gcvNULL)
  160064. + {
  160065. + /* Setup the ISR routine. */
  160066. + gcmkONERROR(gckGALDEVICE_Release_ISR(Device, gcvCORE_VG));
  160067. +
  160068. +#if gcdENABLE_VG
  160069. + /* Switch to OFF power state. */
  160070. + gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
  160071. + Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF
  160072. + ));
  160073. +#endif
  160074. + }
  160075. +
  160076. + /* Stop the kernel thread. */
  160077. + gcmkONERROR(gckGALDEVICE_Stop_Threads(Device));
  160078. +
  160079. + gcmkFOOTER_NO();
  160080. + return gcvSTATUS_OK;
  160081. +
  160082. +OnError:
  160083. + gcmkFOOTER();
  160084. + return status;
  160085. +}
  160086. diff -Nur linux-3.14.17/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
  160087. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h 1970-01-01 01:00:00.000000000 +0100
  160088. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h 2014-09-11 18:06:03.126042465 +0200
  160089. @@ -0,0 +1,192 @@
  160090. +/****************************************************************************
  160091. +*
  160092. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  160093. +*
  160094. +* This program is free software; you can redistribute it and/or modify
  160095. +* it under the terms of the GNU General Public License as published by
  160096. +* the Free Software Foundation; either version 2 of the license, or
  160097. +* (at your option) any later version.
  160098. +*
  160099. +* This program is distributed in the hope that it will be useful,
  160100. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  160101. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  160102. +* GNU General Public License for more details.
  160103. +*
  160104. +* You should have received a copy of the GNU General Public License
  160105. +* along with this program; if not write to the Free Software
  160106. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  160107. +*
  160108. +*****************************************************************************/
  160109. +
  160110. +
  160111. +#ifndef __gc_hal_kernel_device_h_
  160112. +#define __gc_hal_kernel_device_h_
  160113. +
  160114. +/******************************************************************************\
  160115. +******************************* gckGALDEVICE Structure *******************************
  160116. +\******************************************************************************/
  160117. +
  160118. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  160119. +struct contiguous_mem_pool {
  160120. + struct dma_attrs attrs;
  160121. + dma_addr_t phys;
  160122. + void *virt;
  160123. + size_t size;
  160124. +};
  160125. +#endif
  160126. +
  160127. +typedef struct _gckGALDEVICE
  160128. +{
  160129. + /* Objects. */
  160130. + gckOS os;
  160131. + gckKERNEL kernels[gcdMAX_GPU_COUNT];
  160132. +
  160133. + /* Attributes. */
  160134. + gctSIZE_T internalSize;
  160135. + gctPHYS_ADDR internalPhysical;
  160136. + gctUINT32 internalPhysicalName;
  160137. + gctPOINTER internalLogical;
  160138. + gckVIDMEM internalVidMem;
  160139. + gctSIZE_T externalSize;
  160140. + gctPHYS_ADDR externalPhysical;
  160141. + gctUINT32 externalPhysicalName;
  160142. + gctPOINTER externalLogical;
  160143. + gckVIDMEM externalVidMem;
  160144. + gckVIDMEM contiguousVidMem;
  160145. + gctPOINTER contiguousBase;
  160146. + gctPHYS_ADDR contiguousPhysical;
  160147. + gctUINT32 contiguousPhysicalName;
  160148. + gctSIZE_T contiguousSize;
  160149. + gctBOOL contiguousMapped;
  160150. + gctPOINTER contiguousMappedUser;
  160151. + gctSIZE_T systemMemorySize;
  160152. + gctUINT32 systemMemoryBaseAddress;
  160153. + gctPOINTER registerBases[gcdMAX_GPU_COUNT];
  160154. + gctSIZE_T registerSizes[gcdMAX_GPU_COUNT];
  160155. + gctUINT32 baseAddress;
  160156. + gctUINT32 requestedRegisterMemBases[gcdMAX_GPU_COUNT];
  160157. + gctSIZE_T requestedRegisterMemSizes[gcdMAX_GPU_COUNT];
  160158. + gctUINT32 requestedContiguousBase;
  160159. + gctSIZE_T requestedContiguousSize;
  160160. +
  160161. + /* IRQ management. */
  160162. + gctINT irqLines[gcdMAX_GPU_COUNT];
  160163. + gctBOOL isrInitializeds[gcdMAX_GPU_COUNT];
  160164. + gctINT isrEnabled[gcdMAX_GPU_COUNT];
  160165. + gctBOOL dataReadys[gcdMAX_GPU_COUNT];
  160166. +
  160167. + /* Thread management. */
  160168. + struct task_struct *threadCtxts[gcdMAX_GPU_COUNT];
  160169. + struct semaphore semas[gcdMAX_GPU_COUNT];
  160170. + gctBOOL threadInitializeds[gcdMAX_GPU_COUNT];
  160171. + gctBOOL killThread;
  160172. +
  160173. + /* Signal management. */
  160174. + gctINT signal;
  160175. +
  160176. + /* Core mapping */
  160177. + gceCORE coreMapping[8];
  160178. +
  160179. + /* States before suspend. */
  160180. + gceCHIPPOWERSTATE statesStored[gcdMAX_GPU_COUNT];
  160181. +
  160182. + /*Device Debug File System Entry in Kernel*/
  160183. + struct _gcsDebugFileSystemNode * dbgnode;
  160184. +
  160185. + /* Clock management.*/
  160186. + struct clk *clk_3d_core;
  160187. + struct clk *clk_3d_shader;
  160188. + struct clk *clk_3d_axi;
  160189. + struct clk *clk_2d_core;
  160190. + struct clk *clk_2d_axi;
  160191. + struct clk *clk_vg_axi;
  160192. +
  160193. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  160194. + /*Power management.*/
  160195. + struct regulator *gpu_regulator;
  160196. +#endif
  160197. + /*Run time pm*/
  160198. + struct device *pmdev;
  160199. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  160200. + struct contiguous_mem_pool *pool;
  160201. + struct reset_control *rstc[gcdMAX_GPU_COUNT];
  160202. +#endif
  160203. +}
  160204. +* gckGALDEVICE;
  160205. +
  160206. +typedef struct _gcsHAL_PRIVATE_DATA
  160207. +{
  160208. + gckGALDEVICE device;
  160209. + gctPOINTER mappedMemory;
  160210. + gctPOINTER contiguousLogical;
  160211. + /* The process opening the device may not be the same as the one that closes it. */
  160212. + gctUINT32 pidOpen;
  160213. +}
  160214. +gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR;
  160215. +
  160216. +gceSTATUS gckGALDEVICE_Enable_ISR(
  160217. + IN gckGALDEVICE Device,
  160218. + IN gceCORE Core
  160219. + );
  160220. +
  160221. +gceSTATUS gckGALDEVICE_Disable_ISR(
  160222. + IN gckGALDEVICE Device,
  160223. + IN gceCORE Core
  160224. + );
  160225. +
  160226. +gceSTATUS gckGALDEVICE_Setup_ISR(
  160227. + IN gckGALDEVICE Device,
  160228. + IN gceCORE Core
  160229. + );
  160230. +
  160231. +gceSTATUS gckGALDEVICE_Release_ISR(
  160232. + IN gckGALDEVICE Device,
  160233. + IN gceCORE Core
  160234. + );
  160235. +
  160236. +gceSTATUS gckGALDEVICE_Start_Threads(
  160237. + IN gckGALDEVICE Device
  160238. + );
  160239. +
  160240. +gceSTATUS gckGALDEVICE_Stop_Threads(
  160241. + gckGALDEVICE Device
  160242. + );
  160243. +
  160244. +gceSTATUS gckGALDEVICE_Start(
  160245. + IN gckGALDEVICE Device
  160246. + );
  160247. +
  160248. +gceSTATUS gckGALDEVICE_Stop(
  160249. + gckGALDEVICE Device
  160250. + );
  160251. +
  160252. +gceSTATUS gckGALDEVICE_Construct(
  160253. + IN gctINT IrqLine,
  160254. + IN gctUINT32 RegisterMemBase,
  160255. + IN gctSIZE_T RegisterMemSize,
  160256. + IN gctINT IrqLine2D,
  160257. + IN gctUINT32 RegisterMemBase2D,
  160258. + IN gctSIZE_T RegisterMemSize2D,
  160259. + IN gctINT IrqLineVG,
  160260. + IN gctUINT32 RegisterMemBaseVG,
  160261. + IN gctSIZE_T RegisterMemSizeVG,
  160262. + IN gctUINT32 ContiguousBase,
  160263. + IN gctSIZE_T ContiguousSize,
  160264. + IN gctSIZE_T BankSize,
  160265. + IN gctINT FastClear,
  160266. + IN gctINT Compression,
  160267. + IN gctUINT32 PhysBaseAddr,
  160268. + IN gctUINT32 PhysSize,
  160269. + IN gctINT Signal,
  160270. + IN gctUINT LogFileSize,
  160271. + IN struct device *pdev,
  160272. + IN gctINT PowerManagement,
  160273. + IN gctINT GpuProfiler,
  160274. + OUT gckGALDEVICE *Device
  160275. + );
  160276. +
  160277. +gceSTATUS gckGALDEVICE_Destroy(
  160278. + IN gckGALDEVICE Device
  160279. + );
  160280. +
  160281. +#endif /* __gc_hal_kernel_device_h_ */
  160282. diff -Nur linux-3.14.17/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
  160283. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c 1970-01-01 01:00:00.000000000 +0100
  160284. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c 2014-09-11 18:06:03.126042465 +0200
  160285. @@ -0,0 +1,1471 @@
  160286. +/****************************************************************************
  160287. +*
  160288. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  160289. +* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  160290. +*
  160291. +* This program is free software; you can redistribute it and/or modify
  160292. +* it under the terms of the GNU General Public License as published by
  160293. +* the Free Software Foundation; either version 2 of the license, or
  160294. +* (at your option) any later version.
  160295. +*
  160296. +* This program is distributed in the hope that it will be useful,
  160297. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  160298. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  160299. +* GNU General Public License for more details.
  160300. +*
  160301. +* You should have received a copy of the GNU General Public License
  160302. +* along with this program; if not write to the Free Software
  160303. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  160304. +*
  160305. +*****************************************************************************/
  160306. +
  160307. +#include <linux/device.h>
  160308. +#include <linux/slab.h>
  160309. +#include <linux/notifier.h>
  160310. +#include "gc_hal_kernel_linux.h"
  160311. +#include "gc_hal_driver.h"
  160312. +
  160313. +#if USE_PLATFORM_DRIVER
  160314. +# include <linux/platform_device.h>
  160315. +#endif
  160316. +
  160317. +#ifdef CONFIG_PXA_DVFM
  160318. +# include <mach/dvfm.h>
  160319. +# include <mach/pxa3xx_dvfm.h>
  160320. +#endif
  160321. +
  160322. +
  160323. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  160324. +# include <linux/resmem_account.h>
  160325. +# include <linux/kernel.h>
  160326. +# include <linux/mm.h>
  160327. +# include <linux/oom.h>
  160328. +# include <linux/sched.h>
  160329. +# include <linux/notifier.h>
  160330. +
  160331. +struct task_struct *lowmem_deathpending;
  160332. +
  160333. +static int
  160334. +task_notify_func(struct notifier_block *self, unsigned long val, void *data);
  160335. +
  160336. +static struct notifier_block task_nb = {
  160337. + .notifier_call = task_notify_func,
  160338. +};
  160339. +
  160340. +static int
  160341. +task_notify_func(struct notifier_block *self, unsigned long val, void *data)
  160342. +{
  160343. + struct task_struct *task = data;
  160344. +
  160345. + if (task == lowmem_deathpending)
  160346. + lowmem_deathpending = NULL;
  160347. +
  160348. + return NOTIFY_OK;
  160349. +}
  160350. +#endif
  160351. +
  160352. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  160353. +#include <mach/viv_gpu.h>
  160354. +#else
  160355. +#include <linux/pm_runtime.h>
  160356. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  160357. +#include <mach/busfreq.h>
  160358. +#else
  160359. +#include <linux/busfreq-imx6.h>
  160360. +#include <linux/reset.h>
  160361. +#endif
  160362. +#endif
  160363. +/* Zone used for header/footer. */
  160364. +#define _GC_OBJ_ZONE gcvZONE_DRIVER
  160365. +
  160366. +#if gcdENABLE_FSCALE_VAL_ADJUST
  160367. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  160368. +#include <linux/device_cooling.h>
  160369. +#define REG_THERMAL_NOTIFIER(a) register_devfreq_cooling_notifier(a);
  160370. +#define UNREG_THERMAL_NOTIFIER(a) unregister_devfreq_cooling_notifier(a);
  160371. +#else
  160372. +extern int register_thermal_notifier(struct notifier_block *nb);
  160373. +extern int unregister_thermal_notifier(struct notifier_block *nb);
  160374. +#define REG_THERMAL_NOTIFIER(a) register_thermal_notifier(a);
  160375. +#define UNREG_THERMAL_NOTIFIER(a) unregister_thermal_notifier(a);
  160376. +#endif
  160377. +#endif
  160378. +
  160379. +MODULE_DESCRIPTION("Vivante Graphics Driver");
  160380. +MODULE_LICENSE("GPL");
  160381. +
  160382. +static struct class* gpuClass;
  160383. +
  160384. +static gckGALDEVICE galDevice;
  160385. +
  160386. +static uint major = 199;
  160387. +module_param(major, uint, 0644);
  160388. +
  160389. +static int irqLine = -1;
  160390. +module_param(irqLine, int, 0644);
  160391. +
  160392. +static ulong registerMemBase = 0x80000000;
  160393. +module_param(registerMemBase, ulong, 0644);
  160394. +
  160395. +static ulong registerMemSize = 2 << 10;
  160396. +module_param(registerMemSize, ulong, 0644);
  160397. +
  160398. +static int irqLine2D = -1;
  160399. +module_param(irqLine2D, int, 0644);
  160400. +
  160401. +static ulong registerMemBase2D = 0x00000000;
  160402. +module_param(registerMemBase2D, ulong, 0644);
  160403. +
  160404. +static ulong registerMemSize2D = 2 << 10;
  160405. +module_param(registerMemSize2D, ulong, 0644);
  160406. +
  160407. +static int irqLineVG = -1;
  160408. +module_param(irqLineVG, int, 0644);
  160409. +
  160410. +static ulong registerMemBaseVG = 0x00000000;
  160411. +module_param(registerMemBaseVG, ulong, 0644);
  160412. +
  160413. +static ulong registerMemSizeVG = 2 << 10;
  160414. +module_param(registerMemSizeVG, ulong, 0644);
  160415. +
  160416. +#if gcdENABLE_FSCALE_VAL_ADJUST
  160417. +static ulong contiguousSize = 128 << 20;
  160418. +#else
  160419. +static ulong contiguousSize = 4 << 20;
  160420. +#endif
  160421. +module_param(contiguousSize, ulong, 0644);
  160422. +
  160423. +static ulong contiguousBase = 0;
  160424. +module_param(contiguousBase, ulong, 0644);
  160425. +
  160426. +static ulong bankSize = 0;
  160427. +module_param(bankSize, ulong, 0644);
  160428. +
  160429. +static int fastClear = -1;
  160430. +module_param(fastClear, int, 0644);
  160431. +
  160432. +static int compression = -1;
  160433. +module_param(compression, int, 0644);
  160434. +
  160435. +static int powerManagement = 1;
  160436. +module_param(powerManagement, int, 0644);
  160437. +
  160438. +static int gpuProfiler = 0;
  160439. +module_param(gpuProfiler, int, 0644);
  160440. +
  160441. +static int signal = 48;
  160442. +module_param(signal, int, 0644);
  160443. +
  160444. +static ulong baseAddress = 0;
  160445. +module_param(baseAddress, ulong, 0644);
  160446. +
  160447. +static ulong physSize = 0;
  160448. +module_param(physSize, ulong, 0644);
  160449. +
  160450. +static uint logFileSize=0;
  160451. +module_param(logFileSize,uint, 0644);
  160452. +
  160453. +static int showArgs = 0;
  160454. +module_param(showArgs, int, 0644);
  160455. +
  160456. +int gpu3DMinClock = 0;
  160457. +module_param(gpu3DMinClock, int, 0644);
  160458. +
  160459. +#if ENABLE_GPU_CLOCK_BY_DRIVER
  160460. + unsigned long coreClock = 156000000;
  160461. + module_param(coreClock, ulong, 0644);
  160462. +#endif
  160463. +
  160464. +static int drv_open(
  160465. + struct inode* inode,
  160466. + struct file* filp
  160467. + );
  160468. +
  160469. +static int drv_release(
  160470. + struct inode* inode,
  160471. + struct file* filp
  160472. + );
  160473. +
  160474. +static long drv_ioctl(
  160475. + struct file* filp,
  160476. + unsigned int ioctlCode,
  160477. + unsigned long arg
  160478. + );
  160479. +
  160480. +static int drv_mmap(
  160481. + struct file* filp,
  160482. + struct vm_area_struct* vma
  160483. + );
  160484. +
  160485. +static struct file_operations driver_fops =
  160486. +{
  160487. + .owner = THIS_MODULE,
  160488. + .open = drv_open,
  160489. + .release = drv_release,
  160490. + .unlocked_ioctl = drv_ioctl,
  160491. +#ifdef HAVE_COMPAT_IOCTL
  160492. + .compat_ioctl = drv_ioctl,
  160493. +#endif
  160494. + .mmap = drv_mmap,
  160495. +};
  160496. +
  160497. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  160498. +static size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m);
  160499. +static struct reserved_memory_account viv_gpu_resmem_handler = {
  160500. + .name = "viv_gpu",
  160501. + .get_page_used_by_process = viv_gpu_resmem_query,
  160502. +};
  160503. +
  160504. +size_t viv_gpu_resmem_query(struct task_struct *p, struct reserved_memory_account *m)
  160505. +{
  160506. + gcuDATABASE_INFO info;
  160507. + unsigned int processid = p->pid;
  160508. + gckKERNEL gpukernel = m->data;
  160509. +
  160510. + /* ignore error happens in this api. */
  160511. + if (gckKERNEL_QueryProcessDB(gpukernel, processid, false, gcvDB_VIDEO_MEMORY, &info) != gcvSTATUS_OK)
  160512. + return 0;
  160513. +
  160514. + /* we return pages. */
  160515. + if (info.counters.bytes > 0)
  160516. + return info.counters.bytes / PAGE_SIZE;
  160517. + return 0;
  160518. +}
  160519. +#endif
  160520. +
  160521. +int drv_open(
  160522. + struct inode* inode,
  160523. + struct file* filp
  160524. + )
  160525. +{
  160526. + gceSTATUS status;
  160527. + gctBOOL attached = gcvFALSE;
  160528. + gcsHAL_PRIVATE_DATA_PTR data = gcvNULL;
  160529. + gctINT i;
  160530. +
  160531. + gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
  160532. +
  160533. + if (filp == gcvNULL)
  160534. + {
  160535. + gcmkTRACE_ZONE(
  160536. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160537. + "%s(%d): filp is NULL\n",
  160538. + __FUNCTION__, __LINE__
  160539. + );
  160540. +
  160541. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160542. + }
  160543. +
  160544. + data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL);
  160545. +
  160546. + if (data == gcvNULL)
  160547. + {
  160548. + gcmkTRACE_ZONE(
  160549. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160550. + "%s(%d): private_data is NULL\n",
  160551. + __FUNCTION__, __LINE__
  160552. + );
  160553. +
  160554. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  160555. + }
  160556. +
  160557. + data->device = galDevice;
  160558. + data->mappedMemory = gcvNULL;
  160559. + data->contiguousLogical = gcvNULL;
  160560. + gcmkONERROR(gckOS_GetProcessID(&data->pidOpen));
  160561. +
  160562. + /* Attached the process. */
  160563. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  160564. + {
  160565. + if (galDevice->kernels[i] != gcvNULL)
  160566. + {
  160567. + gcmkONERROR(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvTRUE));
  160568. + }
  160569. + }
  160570. + attached = gcvTRUE;
  160571. +
  160572. + if (!galDevice->contiguousMapped)
  160573. + {
  160574. + gcmkONERROR(gckOS_MapMemory(
  160575. + galDevice->os,
  160576. + galDevice->contiguousPhysical,
  160577. + galDevice->contiguousSize,
  160578. + &data->contiguousLogical
  160579. + ));
  160580. + }
  160581. +
  160582. + filp->private_data = data;
  160583. +
  160584. + /* Success. */
  160585. + gcmkFOOTER_NO();
  160586. + return 0;
  160587. +
  160588. +OnError:
  160589. + if (data != gcvNULL)
  160590. + {
  160591. + if (data->contiguousLogical != gcvNULL)
  160592. + {
  160593. + gcmkVERIFY_OK(gckOS_UnmapMemory(
  160594. + galDevice->os,
  160595. + galDevice->contiguousPhysical,
  160596. + galDevice->contiguousSize,
  160597. + data->contiguousLogical
  160598. + ));
  160599. + }
  160600. +
  160601. + kfree(data);
  160602. + }
  160603. +
  160604. + if (attached)
  160605. + {
  160606. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  160607. + {
  160608. + if (galDevice->kernels[i] != gcvNULL)
  160609. + {
  160610. + gcmkVERIFY_OK(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvFALSE));
  160611. + }
  160612. + }
  160613. + }
  160614. +
  160615. + gcmkFOOTER();
  160616. + return -ENOTTY;
  160617. +}
  160618. +
  160619. +int drv_release(
  160620. + struct inode* inode,
  160621. + struct file* filp
  160622. + )
  160623. +{
  160624. + gceSTATUS status;
  160625. + gcsHAL_PRIVATE_DATA_PTR data;
  160626. + gckGALDEVICE device;
  160627. + gctINT i;
  160628. +
  160629. + gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
  160630. +
  160631. + if (filp == gcvNULL)
  160632. + {
  160633. + gcmkTRACE_ZONE(
  160634. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160635. + "%s(%d): filp is NULL\n",
  160636. + __FUNCTION__, __LINE__
  160637. + );
  160638. +
  160639. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160640. + }
  160641. +
  160642. + data = filp->private_data;
  160643. +
  160644. + if (data == gcvNULL)
  160645. + {
  160646. + gcmkTRACE_ZONE(
  160647. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160648. + "%s(%d): private_data is NULL\n",
  160649. + __FUNCTION__, __LINE__
  160650. + );
  160651. +
  160652. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160653. + }
  160654. +
  160655. + device = data->device;
  160656. +
  160657. + if (device == gcvNULL)
  160658. + {
  160659. + gcmkTRACE_ZONE(
  160660. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160661. + "%s(%d): device is NULL\n",
  160662. + __FUNCTION__, __LINE__
  160663. + );
  160664. +
  160665. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160666. + }
  160667. +
  160668. + if (!device->contiguousMapped)
  160669. + {
  160670. + if (data->contiguousLogical != gcvNULL)
  160671. + {
  160672. + gcmkONERROR(gckOS_UnmapMemoryEx(
  160673. + galDevice->os,
  160674. + galDevice->contiguousPhysical,
  160675. + galDevice->contiguousSize,
  160676. + data->contiguousLogical,
  160677. + data->pidOpen
  160678. + ));
  160679. +
  160680. + data->contiguousLogical = gcvNULL;
  160681. + }
  160682. + }
  160683. +
  160684. + /* A process gets detached. */
  160685. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  160686. + {
  160687. + if (galDevice->kernels[i] != gcvNULL)
  160688. + {
  160689. + gcmkONERROR(gckKERNEL_AttachProcessEx(galDevice->kernels[i], gcvFALSE, data->pidOpen));
  160690. + }
  160691. + }
  160692. +
  160693. + kfree(data);
  160694. + filp->private_data = NULL;
  160695. +
  160696. + /* Success. */
  160697. + gcmkFOOTER_NO();
  160698. + return 0;
  160699. +
  160700. +OnError:
  160701. + gcmkFOOTER();
  160702. + return -ENOTTY;
  160703. +}
  160704. +
  160705. +long drv_ioctl(
  160706. + struct file* filp,
  160707. + unsigned int ioctlCode,
  160708. + unsigned long arg
  160709. + )
  160710. +{
  160711. + gceSTATUS status;
  160712. + gcsHAL_INTERFACE iface;
  160713. + gctUINT32 copyLen;
  160714. + DRIVER_ARGS drvArgs;
  160715. + gckGALDEVICE device;
  160716. + gcsHAL_PRIVATE_DATA_PTR data;
  160717. + gctINT32 i, count;
  160718. +
  160719. + gcmkHEADER_ARG(
  160720. + "filp=0x%08X ioctlCode=0x%08X arg=0x%08X",
  160721. + filp, ioctlCode, arg
  160722. + );
  160723. +
  160724. + if (filp == gcvNULL)
  160725. + {
  160726. + gcmkTRACE_ZONE(
  160727. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160728. + "%s(%d): filp is NULL\n",
  160729. + __FUNCTION__, __LINE__
  160730. + );
  160731. +
  160732. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160733. + }
  160734. +
  160735. + data = filp->private_data;
  160736. +
  160737. + if (data == gcvNULL)
  160738. + {
  160739. + gcmkTRACE_ZONE(
  160740. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160741. + "%s(%d): private_data is NULL\n",
  160742. + __FUNCTION__, __LINE__
  160743. + );
  160744. +
  160745. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160746. + }
  160747. +
  160748. + device = data->device;
  160749. +
  160750. + if (device == gcvNULL)
  160751. + {
  160752. + gcmkTRACE_ZONE(
  160753. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160754. + "%s(%d): device is NULL\n",
  160755. + __FUNCTION__, __LINE__
  160756. + );
  160757. +
  160758. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160759. + }
  160760. +
  160761. + if ((ioctlCode != IOCTL_GCHAL_INTERFACE)
  160762. + && (ioctlCode != IOCTL_GCHAL_KERNEL_INTERFACE)
  160763. + )
  160764. + {
  160765. + gcmkTRACE_ZONE(
  160766. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160767. + "%s(%d): unknown command %d\n",
  160768. + __FUNCTION__, __LINE__,
  160769. + ioctlCode
  160770. + );
  160771. +
  160772. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160773. + }
  160774. +
  160775. + /* Get the drvArgs. */
  160776. + copyLen = copy_from_user(
  160777. + &drvArgs, (void *) arg, sizeof(DRIVER_ARGS)
  160778. + );
  160779. +
  160780. + if (copyLen != 0)
  160781. + {
  160782. + gcmkTRACE_ZONE(
  160783. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160784. + "%s(%d): error copying of the input arguments.\n",
  160785. + __FUNCTION__, __LINE__
  160786. + );
  160787. +
  160788. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160789. + }
  160790. +
  160791. + /* Now bring in the gcsHAL_INTERFACE structure. */
  160792. + if ((drvArgs.InputBufferSize != sizeof(gcsHAL_INTERFACE))
  160793. + || (drvArgs.OutputBufferSize != sizeof(gcsHAL_INTERFACE))
  160794. + )
  160795. + {
  160796. + gcmkTRACE_ZONE(
  160797. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160798. + "%s(%d): input or/and output structures are invalid.\n",
  160799. + __FUNCTION__, __LINE__
  160800. + );
  160801. +
  160802. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160803. + }
  160804. +
  160805. + copyLen = copy_from_user(
  160806. + &iface, gcmUINT64_TO_PTR(drvArgs.InputBuffer), sizeof(gcsHAL_INTERFACE)
  160807. + );
  160808. +
  160809. + if (copyLen != 0)
  160810. + {
  160811. + gcmkTRACE_ZONE(
  160812. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160813. + "%s(%d): error copying of input HAL interface.\n",
  160814. + __FUNCTION__, __LINE__
  160815. + );
  160816. +
  160817. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160818. + }
  160819. +
  160820. + if (iface.command == gcvHAL_CHIP_INFO)
  160821. + {
  160822. + count = 0;
  160823. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  160824. + {
  160825. + if (device->kernels[i] != gcvNULL)
  160826. + {
  160827. +#if gcdENABLE_VG
  160828. + if (i == gcvCORE_VG)
  160829. + {
  160830. + iface.u.ChipInfo.types[count] = gcvHARDWARE_VG;
  160831. + }
  160832. + else
  160833. +#endif
  160834. + {
  160835. + gcmkVERIFY_OK(gckHARDWARE_GetType(device->kernels[i]->hardware,
  160836. + &iface.u.ChipInfo.types[count]));
  160837. + }
  160838. + count++;
  160839. + }
  160840. + }
  160841. +
  160842. + iface.u.ChipInfo.count = count;
  160843. + iface.status = status = gcvSTATUS_OK;
  160844. + }
  160845. + else
  160846. + {
  160847. + if (iface.hardwareType < 0 || iface.hardwareType > 7)
  160848. + {
  160849. + gcmkTRACE_ZONE(
  160850. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160851. + "%s(%d): unknown hardwareType %d\n",
  160852. + __FUNCTION__, __LINE__,
  160853. + iface.hardwareType
  160854. + );
  160855. +
  160856. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160857. + }
  160858. +
  160859. +#if gcdENABLE_VG
  160860. + if (device->coreMapping[iface.hardwareType] == gcvCORE_VG)
  160861. + {
  160862. + status = gckVGKERNEL_Dispatch(device->kernels[gcvCORE_VG],
  160863. + (ioctlCode == IOCTL_GCHAL_INTERFACE),
  160864. + &iface);
  160865. + }
  160866. + else
  160867. +#endif
  160868. + {
  160869. + status = gckKERNEL_Dispatch(device->kernels[device->coreMapping[iface.hardwareType]],
  160870. + (ioctlCode == IOCTL_GCHAL_INTERFACE),
  160871. + &iface);
  160872. + }
  160873. + }
  160874. +
  160875. + /* Redo system call after pending signal is handled. */
  160876. + if (status == gcvSTATUS_INTERRUPTED)
  160877. + {
  160878. + gcmkFOOTER();
  160879. + return -ERESTARTSYS;
  160880. + }
  160881. +
  160882. + if (gcmIS_SUCCESS(status) && (iface.command == gcvHAL_LOCK_VIDEO_MEMORY))
  160883. + {
  160884. + gcuVIDMEM_NODE_PTR node = gcmUINT64_TO_PTR(iface.u.LockVideoMemory.node);
  160885. + /* Special case for mapped memory. */
  160886. + if ((data->mappedMemory != gcvNULL)
  160887. + && (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
  160888. + )
  160889. + {
  160890. + /* Compute offset into mapped memory. */
  160891. + gctUINT32 offset
  160892. + = (gctUINT8 *) gcmUINT64_TO_PTR(iface.u.LockVideoMemory.memory)
  160893. + - (gctUINT8 *) device->contiguousBase;
  160894. +
  160895. + /* Compute offset into user-mapped region. */
  160896. + iface.u.LockVideoMemory.memory =
  160897. + gcmPTR_TO_UINT64((gctUINT8 *) data->mappedMemory + offset);
  160898. + }
  160899. + }
  160900. +
  160901. + /* Copy data back to the user. */
  160902. + copyLen = copy_to_user(
  160903. + gcmUINT64_TO_PTR(drvArgs.OutputBuffer), &iface, sizeof(gcsHAL_INTERFACE)
  160904. + );
  160905. +
  160906. + if (copyLen != 0)
  160907. + {
  160908. + gcmkTRACE_ZONE(
  160909. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160910. + "%s(%d): error copying of output HAL interface.\n",
  160911. + __FUNCTION__, __LINE__
  160912. + );
  160913. +
  160914. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160915. + }
  160916. +
  160917. + /* Success. */
  160918. + gcmkFOOTER_NO();
  160919. + return 0;
  160920. +
  160921. +OnError:
  160922. + gcmkFOOTER();
  160923. + return -ENOTTY;
  160924. +}
  160925. +
  160926. +static int drv_mmap(
  160927. + struct file* filp,
  160928. + struct vm_area_struct* vma
  160929. + )
  160930. +{
  160931. + gceSTATUS status = gcvSTATUS_OK;
  160932. + gcsHAL_PRIVATE_DATA_PTR data;
  160933. + gckGALDEVICE device;
  160934. +
  160935. + gcmkHEADER_ARG("filp=0x%08X vma=0x%08X", filp, vma);
  160936. +
  160937. + if (filp == gcvNULL)
  160938. + {
  160939. + gcmkTRACE_ZONE(
  160940. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160941. + "%s(%d): filp is NULL\n",
  160942. + __FUNCTION__, __LINE__
  160943. + );
  160944. +
  160945. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160946. + }
  160947. +
  160948. + data = filp->private_data;
  160949. +
  160950. + if (data == gcvNULL)
  160951. + {
  160952. + gcmkTRACE_ZONE(
  160953. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160954. + "%s(%d): private_data is NULL\n",
  160955. + __FUNCTION__, __LINE__
  160956. + );
  160957. +
  160958. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160959. + }
  160960. +
  160961. + device = data->device;
  160962. +
  160963. + if (device == gcvNULL)
  160964. + {
  160965. + gcmkTRACE_ZONE(
  160966. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160967. + "%s(%d): device is NULL\n",
  160968. + __FUNCTION__, __LINE__
  160969. + );
  160970. +
  160971. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160972. + }
  160973. +
  160974. +#if !gcdPAGED_MEMORY_CACHEABLE
  160975. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  160976. + vma->vm_flags |= gcdVM_FLAGS;
  160977. +#endif
  160978. + vma->vm_pgoff = 0;
  160979. +
  160980. + if (device->contiguousMapped)
  160981. + {
  160982. + unsigned long size = vma->vm_end - vma->vm_start;
  160983. + int ret = 0;
  160984. +
  160985. + if (size > device->contiguousSize)
  160986. + {
  160987. + gcmkTRACE_ZONE(
  160988. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  160989. + "%s(%d): Invalid mapping size.\n",
  160990. + __FUNCTION__, __LINE__
  160991. + );
  160992. +
  160993. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  160994. + }
  160995. +
  160996. + ret = io_remap_pfn_range(
  160997. + vma,
  160998. + vma->vm_start,
  160999. + device->requestedContiguousBase >> PAGE_SHIFT,
  161000. + size,
  161001. + vma->vm_page_prot
  161002. + );
  161003. +
  161004. + if (ret != 0)
  161005. + {
  161006. + gcmkTRACE_ZONE(
  161007. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  161008. + "%s(%d): io_remap_pfn_range failed %d\n",
  161009. + __FUNCTION__, __LINE__,
  161010. + ret
  161011. + );
  161012. +
  161013. + data->mappedMemory = gcvNULL;
  161014. +
  161015. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  161016. + }
  161017. +
  161018. + data->mappedMemory = (gctPOINTER) vma->vm_start;
  161019. +
  161020. + /* Success. */
  161021. + gcmkFOOTER_NO();
  161022. + return 0;
  161023. + }
  161024. +
  161025. +
  161026. +OnError:
  161027. + gcmkFOOTER();
  161028. + return -ENOTTY;
  161029. +}
  161030. +
  161031. +
  161032. +#if !USE_PLATFORM_DRIVER
  161033. +static int __init drv_init(void)
  161034. +#else
  161035. +static int drv_init(struct device *pdev)
  161036. +#endif
  161037. +{
  161038. + int ret;
  161039. + int result = -EINVAL;
  161040. + gceSTATUS status;
  161041. + gckGALDEVICE device = gcvNULL;
  161042. + struct class* device_class = gcvNULL;
  161043. +
  161044. + gcmkHEADER();
  161045. +
  161046. +#if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
  161047. + {
  161048. +# if 0
  161049. + struct clk * clk;
  161050. +
  161051. + clk = clk_get(NULL, "GCCLK");
  161052. +
  161053. + if (IS_ERR(clk))
  161054. + {
  161055. + gcmkTRACE_ZONE(
  161056. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  161057. + "%s(%d): clk get error: %d\n",
  161058. + __FUNCTION__, __LINE__,
  161059. + PTR_ERR(clk)
  161060. + );
  161061. +
  161062. + result = -ENODEV;
  161063. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  161064. + }
  161065. +
  161066. + /*
  161067. + * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently.
  161068. + * Use the 2X clock.
  161069. + */
  161070. + if (clk_set_rate(clk, coreClock * 2))
  161071. + {
  161072. + gcmkTRACE_ZONE(
  161073. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  161074. + "%s(%d): Failed to set core clock.\n",
  161075. + __FUNCTION__, __LINE__
  161076. + );
  161077. +
  161078. + result = -EAGAIN;
  161079. + gcmkONERROR(gcvSTATUS_GENERIC_IO);
  161080. + }
  161081. +
  161082. + clk_enable(clk);
  161083. +
  161084. +#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
  161085. + gc_pwr(1);
  161086. +# endif
  161087. +# endif
  161088. + }
  161089. +#endif
  161090. +
  161091. + printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
  161092. + gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
  161093. + /* when enable gpu profiler, we need to turn off gpu powerMangement */
  161094. + if(gpuProfiler)
  161095. + powerManagement = 0;
  161096. + if (showArgs)
  161097. + {
  161098. + printk("galcore options:\n");
  161099. + printk(" irqLine = %d\n", irqLine);
  161100. + printk(" registerMemBase = 0x%08lX\n", registerMemBase);
  161101. + printk(" registerMemSize = 0x%08lX\n", registerMemSize);
  161102. +
  161103. + if (irqLine2D != -1)
  161104. + {
  161105. + printk(" irqLine2D = %d\n", irqLine2D);
  161106. + printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D);
  161107. + printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D);
  161108. + }
  161109. +
  161110. + if (irqLineVG != -1)
  161111. + {
  161112. + printk(" irqLineVG = %d\n", irqLineVG);
  161113. + printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG);
  161114. + printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG);
  161115. + }
  161116. +
  161117. + printk(" contiguousSize = %ld\n", contiguousSize);
  161118. + printk(" contiguousBase = 0x%08lX\n", contiguousBase);
  161119. + printk(" bankSize = 0x%08lX\n", bankSize);
  161120. + printk(" fastClear = %d\n", fastClear);
  161121. + printk(" compression = %d\n", compression);
  161122. + printk(" signal = %d\n", signal);
  161123. + printk(" baseAddress = 0x%08lX\n", baseAddress);
  161124. + printk(" physSize = 0x%08lX\n", physSize);
  161125. + printk(" logFileSize = %d KB \n", logFileSize);
  161126. + printk(" powerManagement = %d\n", powerManagement);
  161127. + printk(" gpuProfiler = %d\n", gpuProfiler);
  161128. +#if ENABLE_GPU_CLOCK_BY_DRIVER
  161129. + printk(" coreClock = %lu\n", coreClock);
  161130. +#endif
  161131. + }
  161132. +
  161133. + if(logFileSize != 0)
  161134. + {
  161135. + gckDebugFileSystemInitialize();
  161136. + }
  161137. +
  161138. + /* Create the GAL device. */
  161139. + gcmkONERROR(gckGALDEVICE_Construct(
  161140. + irqLine,
  161141. + registerMemBase, registerMemSize,
  161142. + irqLine2D,
  161143. + registerMemBase2D, registerMemSize2D,
  161144. + irqLineVG,
  161145. + registerMemBaseVG, registerMemSizeVG,
  161146. + contiguousBase, contiguousSize,
  161147. + bankSize, fastClear, compression, baseAddress, physSize, signal,
  161148. + logFileSize,
  161149. + pdev,
  161150. + powerManagement,
  161151. + gpuProfiler,
  161152. + &device
  161153. + ));
  161154. +
  161155. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  161156. + device->pool = dev_get_drvdata(pdev);
  161157. +#endif
  161158. +
  161159. + /* Start the GAL device. */
  161160. + gcmkONERROR(gckGALDEVICE_Start(device));
  161161. +
  161162. + if ((physSize != 0)
  161163. + && (device->kernels[gcvCORE_MAJOR] != gcvNULL)
  161164. + && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0))
  161165. + {
  161166. + status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, baseAddress, physSize);
  161167. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  161168. + "Enable new MMU: status=%d\n", status);
  161169. +
  161170. + if ((device->kernels[gcvCORE_2D] != gcvNULL)
  161171. + && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0))
  161172. + {
  161173. + status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize);
  161174. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
  161175. + "Enable new MMU for 2D: status=%d\n", status);
  161176. + }
  161177. +
  161178. + /* Reset the base address */
  161179. + device->baseAddress = 0;
  161180. + }
  161181. +
  161182. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  161183. + task_free_register(&task_nb);
  161184. + viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR];
  161185. + register_reserved_memory_account(&viv_gpu_resmem_handler);
  161186. +#endif
  161187. +
  161188. +
  161189. + /* Register the character device. */
  161190. + ret = register_chrdev(major, DRV_NAME, &driver_fops);
  161191. +
  161192. + if (ret < 0)
  161193. + {
  161194. + gcmkTRACE_ZONE(
  161195. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  161196. + "%s(%d): Could not allocate major number for mmap.\n",
  161197. + __FUNCTION__, __LINE__
  161198. + );
  161199. +
  161200. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  161201. + }
  161202. +
  161203. + if (major == 0)
  161204. + {
  161205. + major = ret;
  161206. + }
  161207. +
  161208. + /* Create the device class. */
  161209. + device_class = class_create(THIS_MODULE, "graphics_class");
  161210. +
  161211. + if (IS_ERR(device_class))
  161212. + {
  161213. + gcmkTRACE_ZONE(
  161214. + gcvLEVEL_ERROR, gcvZONE_DRIVER,
  161215. + "%s(%d): Failed to create the class.\n",
  161216. + __FUNCTION__, __LINE__
  161217. + );
  161218. +
  161219. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  161220. + }
  161221. +
  161222. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  161223. + device_create(device_class, NULL, MKDEV(major, 0), NULL, "galcore");
  161224. +#else
  161225. + device_create(device_class, NULL, MKDEV(major, 0), "galcore");
  161226. +#endif
  161227. +
  161228. + galDevice = device;
  161229. + gpuClass = device_class;
  161230. +
  161231. + gcmkTRACE_ZONE(
  161232. + gcvLEVEL_INFO, gcvZONE_DRIVER,
  161233. + "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n",
  161234. + __FUNCTION__, __LINE__,
  161235. + irqLine, contiguousSize, registerMemBase
  161236. + );
  161237. +
  161238. + /* Success. */
  161239. + gcmkFOOTER_NO();
  161240. + return 0;
  161241. +
  161242. +OnError:
  161243. + /* Roll back. */
  161244. + if (device_class != gcvNULL)
  161245. + {
  161246. + device_destroy(device_class, MKDEV(major, 0));
  161247. + class_destroy(device_class);
  161248. + }
  161249. +
  161250. + if (device != gcvNULL)
  161251. + {
  161252. + gcmkVERIFY_OK(gckGALDEVICE_Stop(device));
  161253. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
  161254. + }
  161255. +
  161256. + gcmkFOOTER();
  161257. + return result;
  161258. +}
  161259. +
  161260. +#if !USE_PLATFORM_DRIVER
  161261. +static void __exit drv_exit(void)
  161262. +#else
  161263. +static void drv_exit(void)
  161264. +#endif
  161265. +{
  161266. + gcmkHEADER();
  161267. +
  161268. +#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
  161269. + task_free_unregister(&task_nb);
  161270. + unregister_reserved_memory_account(&viv_gpu_resmem_handler);
  161271. +#endif
  161272. +
  161273. + gcmkASSERT(gpuClass != gcvNULL);
  161274. + device_destroy(gpuClass, MKDEV(major, 0));
  161275. + class_destroy(gpuClass);
  161276. +
  161277. + unregister_chrdev(major, DRV_NAME);
  161278. +
  161279. + gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice));
  161280. + gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice));
  161281. +
  161282. + if(gckDebugFileSystemIsEnabled())
  161283. + {
  161284. + gckDebugFileSystemTerminate();
  161285. + }
  161286. +
  161287. +#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
  161288. + {
  161289. +# if 0
  161290. + struct clk * clk = NULL;
  161291. +
  161292. +#if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
  161293. + gc_pwr(0);
  161294. +#endif
  161295. + clk = clk_get(NULL, "GCCLK");
  161296. + clk_disable(clk);
  161297. +# endif
  161298. + }
  161299. +#endif
  161300. +
  161301. + gcmkFOOTER_NO();
  161302. +}
  161303. +
  161304. +#if !USE_PLATFORM_DRIVER
  161305. + module_init(drv_init);
  161306. + module_exit(drv_exit);
  161307. +#else
  161308. +
  161309. +#ifdef CONFIG_DOVE_GPU
  161310. +# define DEVICE_NAME "dove_gpu"
  161311. +#else
  161312. +# define DEVICE_NAME "galcore"
  161313. +#endif
  161314. +
  161315. +#if gcdENABLE_FSCALE_VAL_ADJUST
  161316. +static int thermal_hot_pm_notify(struct notifier_block *nb, unsigned long event,
  161317. + void *dummy)
  161318. +{
  161319. + static gctUINT orgFscale, minFscale, maxFscale;
  161320. + static gctBOOL bAlreadyTooHot = gcvFALSE;
  161321. + gckHARDWARE hardware = galDevice->kernels[gcvCORE_MAJOR]->hardware;
  161322. +
  161323. + if (event && !bAlreadyTooHot) {
  161324. + gckHARDWARE_GetFscaleValue(hardware,&orgFscale,&minFscale, &maxFscale);
  161325. + gckHARDWARE_SetFscaleValue(hardware, minFscale);
  161326. + bAlreadyTooHot = gcvTRUE;
  161327. + gckOS_Print("System is too hot. GPU3D will work at %d/64 clock.\n", minFscale);
  161328. + } else if (!event && bAlreadyTooHot) {
  161329. + gckHARDWARE_SetFscaleValue(hardware, orgFscale);
  161330. + gckOS_Print("Hot alarm is canceled. GPU3D clock will return to %d/64\n", orgFscale);
  161331. + bAlreadyTooHot = gcvFALSE;
  161332. + }
  161333. + return NOTIFY_OK;
  161334. +}
  161335. +
  161336. +static struct notifier_block thermal_hot_pm_notifier = {
  161337. + .notifier_call = thermal_hot_pm_notify,
  161338. + };
  161339. +#endif
  161340. +
  161341. +
  161342. +
  161343. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  161344. +static int gpu_probe(struct platform_device *pdev)
  161345. +#else
  161346. +static int __devinit gpu_probe(struct platform_device *pdev)
  161347. +#endif
  161348. +{
  161349. + int ret = -ENODEV;
  161350. + struct resource* res;
  161351. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  161352. + struct contiguous_mem_pool *pool;
  161353. + struct reset_control *rstc;
  161354. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  161355. + struct device_node *dn =pdev->dev.of_node;
  161356. + const u32 *prop;
  161357. +#else
  161358. + struct viv_gpu_platform_data *pdata;
  161359. +#endif
  161360. + gcmkHEADER();
  161361. +
  161362. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_baseaddr");
  161363. + if (res)
  161364. + baseAddress = res->start;
  161365. +
  161366. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d");
  161367. + if (res)
  161368. + irqLine = res->start;
  161369. +
  161370. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d");
  161371. + if (res)
  161372. + {
  161373. + registerMemBase = res->start;
  161374. + registerMemSize = res->end - res->start + 1;
  161375. + }
  161376. +
  161377. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d");
  161378. + if (res)
  161379. + irqLine2D = res->start;
  161380. +
  161381. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d");
  161382. + if (res)
  161383. + {
  161384. + registerMemBase2D = res->start;
  161385. + registerMemSize2D = res->end - res->start + 1;
  161386. + }
  161387. +
  161388. + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg");
  161389. + if (res)
  161390. + irqLineVG = res->start;
  161391. +
  161392. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg");
  161393. + if (res)
  161394. + {
  161395. + registerMemBaseVG = res->start;
  161396. + registerMemSizeVG = res->end - res->start + 1;
  161397. + }
  161398. +
  161399. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  161400. + pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL);
  161401. + if (!pool)
  161402. + return -ENOMEM;
  161403. + pool->size = contiguousSize;
  161404. + init_dma_attrs(&pool->attrs);
  161405. + dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs);
  161406. + pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys,
  161407. + GFP_KERNEL, &pool->attrs);
  161408. + if (!pool->virt) {
  161409. + dev_err(&pdev->dev, "Failed to allocate contiguous memory\n");
  161410. + return -ENOMEM;
  161411. + }
  161412. + contiguousBase = pool->phys;
  161413. + dev_set_drvdata(&pdev->dev, pool);
  161414. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  161415. + prop = of_get_property(dn, "contiguousbase", NULL);
  161416. + if(prop)
  161417. + contiguousBase = *prop;
  161418. + of_property_read_u32(dn,"contiguoussize", (u32 *)&contiguousSize);
  161419. +#else
  161420. + pdata = pdev->dev.platform_data;
  161421. + if (pdata) {
  161422. + contiguousBase = pdata->reserved_mem_base;
  161423. + contiguousSize = pdata->reserved_mem_size;
  161424. + }
  161425. +#endif
  161426. + if (contiguousSize == 0)
  161427. + gckOS_Print("Warning: No contiguous memory is reserverd for gpu.!\n ");
  161428. + ret = drv_init(&pdev->dev);
  161429. +
  161430. + if (!ret)
  161431. + {
  161432. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  161433. + rstc = devm_reset_control_get(&pdev->dev, "gpu3d");
  161434. + galDevice->rstc[gcvCORE_MAJOR] = IS_ERR(rstc) ? NULL : rstc;
  161435. +
  161436. + rstc = devm_reset_control_get(&pdev->dev, "gpu2d");
  161437. + galDevice->rstc[gcvCORE_2D] = IS_ERR(rstc) ? NULL : rstc;
  161438. +
  161439. + rstc = devm_reset_control_get(&pdev->dev, "gpuvg");
  161440. + galDevice->rstc[gcvCORE_VG] = IS_ERR(rstc) ? NULL : rstc;
  161441. +#endif
  161442. + platform_set_drvdata(pdev, galDevice);
  161443. +
  161444. +#if gcdENABLE_FSCALE_VAL_ADJUST
  161445. + if (galDevice->kernels[gcvCORE_MAJOR])
  161446. + REG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  161447. +#endif
  161448. + gcmkFOOTER_NO();
  161449. + return ret;
  161450. + }
  161451. +#if gcdENABLE_FSCALE_VAL_ADJUST
  161452. + UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  161453. +#endif
  161454. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  161455. + dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
  161456. + &pool->attrs);
  161457. +#endif
  161458. + gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
  161459. + return ret;
  161460. +}
  161461. +
  161462. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  161463. +static int gpu_remove(struct platform_device *pdev)
  161464. +#else
  161465. +static int __devexit gpu_remove(struct platform_device *pdev)
  161466. +#endif
  161467. +{
  161468. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  161469. + gckGALDEVICE device = platform_get_drvdata(pdev);
  161470. + struct contiguous_mem_pool *pool = device->pool;
  161471. +#endif
  161472. + gcmkHEADER();
  161473. +#if gcdENABLE_FSCALE_VAL_ADJUST
  161474. + if(galDevice->kernels[gcvCORE_MAJOR])
  161475. + UNREG_THERMAL_NOTIFIER(&thermal_hot_pm_notifier);
  161476. +#endif
  161477. + drv_exit();
  161478. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  161479. + dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
  161480. + &pool->attrs);
  161481. +#endif
  161482. + gcmkFOOTER_NO();
  161483. + return 0;
  161484. +}
  161485. +
  161486. +static int gpu_suspend(struct platform_device *dev, pm_message_t state)
  161487. +{
  161488. + gceSTATUS status;
  161489. + gckGALDEVICE device;
  161490. + gctINT i;
  161491. +
  161492. + device = platform_get_drvdata(dev);
  161493. +
  161494. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  161495. + {
  161496. + if (device->kernels[i] != gcvNULL)
  161497. + {
  161498. + /* Store states. */
  161499. +#if gcdENABLE_VG
  161500. + if (i == gcvCORE_VG)
  161501. + {
  161502. + status = gckVGHARDWARE_QueryPowerManagementState(device->kernels[i]->vg->hardware, &device->statesStored[i]);
  161503. + }
  161504. + else
  161505. +#endif
  161506. + {
  161507. + status = gckHARDWARE_QueryPowerManagementState(device->kernels[i]->hardware, &device->statesStored[i]);
  161508. + }
  161509. +
  161510. + if (gcmIS_ERROR(status))
  161511. + {
  161512. + return -1;
  161513. + }
  161514. +
  161515. +#if gcdENABLE_VG
  161516. + if (i == gcvCORE_VG)
  161517. + {
  161518. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_OFF);
  161519. + }
  161520. + else
  161521. +#endif
  161522. + {
  161523. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
  161524. + }
  161525. + if (gcmIS_ERROR(status))
  161526. + {
  161527. + return -1;
  161528. + }
  161529. +
  161530. + }
  161531. + }
  161532. +
  161533. + return 0;
  161534. +}
  161535. +
  161536. +static int gpu_resume(struct platform_device *dev)
  161537. +{
  161538. + gceSTATUS status;
  161539. + gckGALDEVICE device;
  161540. + gctINT i;
  161541. + gceCHIPPOWERSTATE statesStored;
  161542. +
  161543. + device = platform_get_drvdata(dev);
  161544. +
  161545. + for (i = 0; i < gcdMAX_GPU_COUNT; i++)
  161546. + {
  161547. + if (device->kernels[i] != gcvNULL)
  161548. + {
  161549. +#if gcdENABLE_VG
  161550. + if (i == gcvCORE_VG)
  161551. + {
  161552. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
  161553. + }
  161554. + else
  161555. +#endif
  161556. + {
  161557. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
  161558. + }
  161559. +
  161560. + if (gcmIS_ERROR(status))
  161561. + {
  161562. + return -1;
  161563. + }
  161564. +
  161565. + /* Convert global state to crossponding internal state. */
  161566. + switch(device->statesStored[i])
  161567. + {
  161568. + case gcvPOWER_OFF:
  161569. + statesStored = gcvPOWER_OFF_BROADCAST;
  161570. + break;
  161571. + case gcvPOWER_IDLE:
  161572. + statesStored = gcvPOWER_IDLE_BROADCAST;
  161573. + break;
  161574. + case gcvPOWER_SUSPEND:
  161575. + statesStored = gcvPOWER_SUSPEND_BROADCAST;
  161576. + break;
  161577. + case gcvPOWER_ON:
  161578. + statesStored = gcvPOWER_ON_AUTO;
  161579. + break;
  161580. + default:
  161581. + statesStored = device->statesStored[i];
  161582. + break;
  161583. + }
  161584. +
  161585. + /* Restore states. */
  161586. +#if gcdENABLE_VG
  161587. + if (i == gcvCORE_VG)
  161588. + {
  161589. + status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored);
  161590. + }
  161591. + else
  161592. +#endif
  161593. + {
  161594. + status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored);
  161595. + }
  161596. +
  161597. + if (gcmIS_ERROR(status))
  161598. + {
  161599. + return -1;
  161600. + }
  161601. + }
  161602. + }
  161603. +
  161604. + return 0;
  161605. +}
  161606. +
  161607. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  161608. +static const struct of_device_id mxs_gpu_dt_ids[] = {
  161609. + { .compatible = "fsl,imx6q-gpu", },
  161610. + {/* sentinel */}
  161611. +};
  161612. +MODULE_DEVICE_TABLE(of, mxs_gpu_dt_ids);
  161613. +
  161614. +#ifdef CONFIG_PM
  161615. +static int gpu_runtime_suspend(struct device *dev)
  161616. +{
  161617. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
  161618. + release_bus_freq(BUS_FREQ_HIGH);
  161619. +#endif
  161620. + return 0;
  161621. +}
  161622. +
  161623. +static int gpu_runtime_resume(struct device *dev)
  161624. +{
  161625. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 7)
  161626. + request_bus_freq(BUS_FREQ_HIGH);
  161627. +#endif
  161628. + return 0;
  161629. +}
  161630. +
  161631. +static int gpu_system_suspend(struct device *dev)
  161632. +{
  161633. + pm_message_t state={0};
  161634. + return gpu_suspend(to_platform_device(dev), state);
  161635. +}
  161636. +
  161637. +static int gpu_system_resume(struct device *dev)
  161638. +{
  161639. + return gpu_resume(to_platform_device(dev));
  161640. +}
  161641. +
  161642. +static const struct dev_pm_ops gpu_pm_ops = {
  161643. + SET_RUNTIME_PM_OPS(gpu_runtime_suspend, gpu_runtime_resume, NULL)
  161644. + SET_SYSTEM_SLEEP_PM_OPS(gpu_system_suspend, gpu_system_resume)
  161645. +};
  161646. +#endif
  161647. +#endif
  161648. +
  161649. +static struct platform_driver gpu_driver = {
  161650. + .probe = gpu_probe,
  161651. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
  161652. + .remove = gpu_remove,
  161653. +#else
  161654. + .remove = __devexit_p(gpu_remove),
  161655. +#endif
  161656. +
  161657. + .suspend = gpu_suspend,
  161658. + .resume = gpu_resume,
  161659. +
  161660. + .driver = {
  161661. + .name = DEVICE_NAME,
  161662. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  161663. + .of_match_table = mxs_gpu_dt_ids,
  161664. +#if CONFIG_PM
  161665. + .pm = &gpu_pm_ops,
  161666. +#endif
  161667. +#endif
  161668. + }
  161669. +};
  161670. +
  161671. +#if 0 /*CONFIG_DOVE_GPU*/
  161672. +static struct resource gpu_resources[] = {
  161673. + {
  161674. + .name = "gpu_irq",
  161675. + .flags = IORESOURCE_IRQ,
  161676. + },
  161677. + {
  161678. + .name = "gpu_base",
  161679. + .flags = IORESOURCE_MEM,
  161680. + },
  161681. + {
  161682. + .name = "gpu_mem",
  161683. + .flags = IORESOURCE_MEM,
  161684. + },
  161685. +};
  161686. +
  161687. +static struct platform_device * gpu_device;
  161688. +#endif
  161689. +
  161690. +static int __init gpu_init(void)
  161691. +{
  161692. + int ret = 0;
  161693. +
  161694. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  161695. + gpu_resources[0].start = gpu_resources[0].end = irqLine;
  161696. +
  161697. + gpu_resources[1].start = registerMemBase;
  161698. + gpu_resources[1].end = registerMemBase + registerMemSize - 1;
  161699. +
  161700. + gpu_resources[2].start = contiguousBase;
  161701. + gpu_resources[2].end = contiguousBase + contiguousSize - 1;
  161702. +
  161703. + /* Allocate device */
  161704. + gpu_device = platform_device_alloc(DEVICE_NAME, -1);
  161705. + if (!gpu_device)
  161706. + {
  161707. + printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
  161708. + ret = -ENOMEM;
  161709. + goto out;
  161710. + }
  161711. +
  161712. + /* Insert resource */
  161713. + ret = platform_device_add_resources(gpu_device, gpu_resources, 3);
  161714. + if (ret)
  161715. + {
  161716. + printk(KERN_ERR "galcore: platform_device_add_resources failed.\n");
  161717. + goto put_dev;
  161718. + }
  161719. +
  161720. + /* Add device */
  161721. + ret = platform_device_add(gpu_device);
  161722. + if (ret)
  161723. + {
  161724. + printk(KERN_ERR "galcore: platform_device_add failed.\n");
  161725. + goto put_dev;
  161726. + }
  161727. +#endif
  161728. +
  161729. + ret = platform_driver_register(&gpu_driver);
  161730. + if (!ret)
  161731. + {
  161732. + goto out;
  161733. + }
  161734. +
  161735. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  161736. + platform_device_del(gpu_device);
  161737. +put_dev:
  161738. + platform_device_put(gpu_device);
  161739. +#endif
  161740. +
  161741. +out:
  161742. + return ret;
  161743. +}
  161744. +
  161745. +static void __exit gpu_exit(void)
  161746. +{
  161747. + platform_driver_unregister(&gpu_driver);
  161748. +#if 0 /*ndef CONFIG_DOVE_GPU*/
  161749. + platform_device_unregister(gpu_device);
  161750. +#endif
  161751. +}
  161752. +
  161753. +module_init(gpu_init);
  161754. +module_exit(gpu_exit);
  161755. +
  161756. +#endif
  161757. diff -Nur linux-3.14.17/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
  161758. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c 1970-01-01 01:00:00.000000000 +0100
  161759. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c 2014-09-11 18:06:03.126042465 +0200
  161760. @@ -0,0 +1,481 @@
  161761. +/****************************************************************************
  161762. +*
  161763. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  161764. +*
  161765. +* This program is free software; you can redistribute it and/or modify
  161766. +* it under the terms of the GNU General Public License as published by
  161767. +* the Free Software Foundation; either version 2 of the license, or
  161768. +* (at your option) any later version.
  161769. +*
  161770. +* This program is distributed in the hope that it will be useful,
  161771. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  161772. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  161773. +* GNU General Public License for more details.
  161774. +*
  161775. +* You should have received a copy of the GNU General Public License
  161776. +* along with this program; if not write to the Free Software
  161777. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  161778. +*
  161779. +*****************************************************************************/
  161780. +
  161781. +
  161782. +#include "gc_hal_kernel_linux.h"
  161783. +
  161784. +#define _GC_OBJ_ZONE gcvZONE_KERNEL
  161785. +
  161786. +/******************************************************************************\
  161787. +******************************* gckKERNEL API Code ******************************
  161788. +\******************************************************************************/
  161789. +
  161790. +/*******************************************************************************
  161791. +**
  161792. +** gckKERNEL_QueryVideoMemory
  161793. +**
  161794. +** Query the amount of video memory.
  161795. +**
  161796. +** INPUT:
  161797. +**
  161798. +** gckKERNEL Kernel
  161799. +** Pointer to an gckKERNEL object.
  161800. +**
  161801. +** OUTPUT:
  161802. +**
  161803. +** gcsHAL_INTERFACE * Interface
  161804. +** Pointer to an gcsHAL_INTERFACE structure that will be filled in with
  161805. +** the memory information.
  161806. +*/
  161807. +gceSTATUS
  161808. +gckKERNEL_QueryVideoMemory(
  161809. + IN gckKERNEL Kernel,
  161810. + OUT gcsHAL_INTERFACE * Interface
  161811. + )
  161812. +{
  161813. + gckGALDEVICE device;
  161814. +
  161815. + gcmkHEADER_ARG("Kernel=%p", Kernel);
  161816. +
  161817. + /* Verify the arguments. */
  161818. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  161819. + gcmkVERIFY_ARGUMENT(Interface != NULL);
  161820. +
  161821. + /* Extract the pointer to the gckGALDEVICE class. */
  161822. + device = (gckGALDEVICE) Kernel->context;
  161823. +
  161824. + /* Get internal memory size and physical address. */
  161825. + Interface->u.QueryVideoMemory.internalSize = device->internalSize;
  161826. + Interface->u.QueryVideoMemory.internalPhysical = device->internalPhysicalName;
  161827. +
  161828. + /* Get external memory size and physical address. */
  161829. + Interface->u.QueryVideoMemory.externalSize = device->externalSize;
  161830. + Interface->u.QueryVideoMemory.externalPhysical = device->externalPhysicalName;
  161831. +
  161832. + /* Get contiguous memory size and physical address. */
  161833. + Interface->u.QueryVideoMemory.contiguousSize = device->contiguousSize;
  161834. + Interface->u.QueryVideoMemory.contiguousPhysical = device->contiguousPhysicalName;
  161835. +
  161836. + /* Success. */
  161837. + gcmkFOOTER_NO();
  161838. + return gcvSTATUS_OK;
  161839. +}
  161840. +
  161841. +/*******************************************************************************
  161842. +**
  161843. +** gckKERNEL_GetVideoMemoryPool
  161844. +**
  161845. +** Get the gckVIDMEM object belonging to the specified pool.
  161846. +**
  161847. +** INPUT:
  161848. +**
  161849. +** gckKERNEL Kernel
  161850. +** Pointer to an gckKERNEL object.
  161851. +**
  161852. +** gcePOOL Pool
  161853. +** Pool to query gckVIDMEM object for.
  161854. +**
  161855. +** OUTPUT:
  161856. +**
  161857. +** gckVIDMEM * VideoMemory
  161858. +** Pointer to a variable that will hold the pointer to the gckVIDMEM
  161859. +** object belonging to the requested pool.
  161860. +*/
  161861. +gceSTATUS
  161862. +gckKERNEL_GetVideoMemoryPool(
  161863. + IN gckKERNEL Kernel,
  161864. + IN gcePOOL Pool,
  161865. + OUT gckVIDMEM * VideoMemory
  161866. + )
  161867. +{
  161868. + gckGALDEVICE device;
  161869. + gckVIDMEM videoMemory;
  161870. +
  161871. + gcmkHEADER_ARG("Kernel=%p Pool=%d", Kernel, Pool);
  161872. +
  161873. + /* Verify the arguments. */
  161874. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  161875. + gcmkVERIFY_ARGUMENT(VideoMemory != NULL);
  161876. +
  161877. + /* Extract the pointer to the gckGALDEVICE class. */
  161878. + device = (gckGALDEVICE) Kernel->context;
  161879. +
  161880. + /* Dispatch on pool. */
  161881. + switch (Pool)
  161882. + {
  161883. + case gcvPOOL_LOCAL_INTERNAL:
  161884. + /* Internal memory. */
  161885. + videoMemory = device->internalVidMem;
  161886. + break;
  161887. +
  161888. + case gcvPOOL_LOCAL_EXTERNAL:
  161889. + /* External memory. */
  161890. + videoMemory = device->externalVidMem;
  161891. + break;
  161892. +
  161893. + case gcvPOOL_SYSTEM:
  161894. + /* System memory. */
  161895. + videoMemory = device->contiguousVidMem;
  161896. + break;
  161897. +
  161898. + default:
  161899. + /* Unknown pool. */
  161900. + videoMemory = NULL;
  161901. + }
  161902. +
  161903. + /* Return pointer to the gckVIDMEM object. */
  161904. + *VideoMemory = videoMemory;
  161905. +
  161906. + /* Return status. */
  161907. + gcmkFOOTER_ARG("*VideoMemory=%p", *VideoMemory);
  161908. + return (videoMemory == NULL) ? gcvSTATUS_OUT_OF_MEMORY : gcvSTATUS_OK;
  161909. +}
  161910. +
  161911. +/*******************************************************************************
  161912. +**
  161913. +** gckKERNEL_MapMemory
  161914. +**
  161915. +** Map video memory into the current process space.
  161916. +**
  161917. +** INPUT:
  161918. +**
  161919. +** gckKERNEL Kernel
  161920. +** Pointer to an gckKERNEL object.
  161921. +**
  161922. +** gctPHYS_ADDR Physical
  161923. +** Physical address of video memory to map.
  161924. +**
  161925. +** gctSIZE_T Bytes
  161926. +** Number of bytes to map.
  161927. +**
  161928. +** OUTPUT:
  161929. +**
  161930. +** gctPOINTER * Logical
  161931. +** Pointer to a variable that will hold the base address of the mapped
  161932. +** memory region.
  161933. +*/
  161934. +gceSTATUS
  161935. +gckKERNEL_MapMemory(
  161936. + IN gckKERNEL Kernel,
  161937. + IN gctPHYS_ADDR Physical,
  161938. + IN gctSIZE_T Bytes,
  161939. + OUT gctPOINTER * Logical
  161940. + )
  161941. +{
  161942. + gckKERNEL kernel = Kernel;
  161943. + gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
  161944. +
  161945. + return gckOS_MapMemory(Kernel->os, physical, Bytes, Logical);
  161946. +}
  161947. +
  161948. +/*******************************************************************************
  161949. +**
  161950. +** gckKERNEL_UnmapMemory
  161951. +**
  161952. +** Unmap video memory from the current process space.
  161953. +**
  161954. +** INPUT:
  161955. +**
  161956. +** gckKERNEL Kernel
  161957. +** Pointer to an gckKERNEL object.
  161958. +**
  161959. +** gctPHYS_ADDR Physical
  161960. +** Physical address of video memory to map.
  161961. +**
  161962. +** gctSIZE_T Bytes
  161963. +** Number of bytes to map.
  161964. +**
  161965. +** gctPOINTER Logical
  161966. +** Base address of the mapped memory region.
  161967. +**
  161968. +** OUTPUT:
  161969. +**
  161970. +** Nothing.
  161971. +*/
  161972. +gceSTATUS
  161973. +gckKERNEL_UnmapMemory(
  161974. + IN gckKERNEL Kernel,
  161975. + IN gctPHYS_ADDR Physical,
  161976. + IN gctSIZE_T Bytes,
  161977. + IN gctPOINTER Logical
  161978. + )
  161979. +{
  161980. + gckKERNEL kernel = Kernel;
  161981. + gctPHYS_ADDR physical = gcmNAME_TO_PTR(Physical);
  161982. +
  161983. + return gckOS_UnmapMemory(Kernel->os, physical, Bytes, Logical);
  161984. +}
  161985. +
  161986. +/*******************************************************************************
  161987. +**
  161988. +** gckKERNEL_MapVideoMemory
  161989. +**
  161990. +** Get the logical address for a hardware specific memory address for the
  161991. +** current process.
  161992. +**
  161993. +** INPUT:
  161994. +**
  161995. +** gckKERNEL Kernel
  161996. +** Pointer to an gckKERNEL object.
  161997. +**
  161998. +** gctBOOL InUserSpace
  161999. +** gcvTRUE to map the memory into the user space.
  162000. +**
  162001. +** gctUINT32 Address
  162002. +** Hardware specific memory address.
  162003. +**
  162004. +** OUTPUT:
  162005. +**
  162006. +** gctPOINTER * Logical
  162007. +** Pointer to a variable that will hold the logical address of the
  162008. +** specified memory address.
  162009. +*/
  162010. +gceSTATUS
  162011. +gckKERNEL_MapVideoMemoryEx(
  162012. + IN gckKERNEL Kernel,
  162013. + IN gceCORE Core,
  162014. + IN gctBOOL InUserSpace,
  162015. + IN gctUINT32 Address,
  162016. + OUT gctPOINTER * Logical
  162017. + )
  162018. +{
  162019. + gckGALDEVICE device;
  162020. + PLINUX_MDL mdl;
  162021. + PLINUX_MDL_MAP mdlMap;
  162022. + gcePOOL pool;
  162023. + gctUINT32 offset, base;
  162024. + gceSTATUS status;
  162025. + gctPOINTER logical;
  162026. +
  162027. + gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
  162028. + Kernel, InUserSpace, Address);
  162029. +
  162030. + /* Verify the arguments. */
  162031. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  162032. + gcmkVERIFY_ARGUMENT(Logical != NULL);
  162033. +
  162034. + /* Extract the pointer to the gckGALDEVICE class. */
  162035. + device = (gckGALDEVICE) Kernel->context;
  162036. +
  162037. +#if gcdENABLE_VG
  162038. + if (Core == gcvCORE_VG)
  162039. + {
  162040. + /* Split the memory address into a pool type and offset. */
  162041. + gcmkONERROR(
  162042. + gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset));
  162043. + }
  162044. + else
  162045. +#endif
  162046. + {
  162047. + /* Split the memory address into a pool type and offset. */
  162048. + gcmkONERROR(
  162049. + gckHARDWARE_SplitMemory(Kernel->hardware, Address, &pool, &offset));
  162050. + }
  162051. +
  162052. + /* Dispatch on pool. */
  162053. + switch (pool)
  162054. + {
  162055. + case gcvPOOL_LOCAL_INTERNAL:
  162056. + /* Internal memory. */
  162057. + logical = device->internalLogical;
  162058. + break;
  162059. +
  162060. + case gcvPOOL_LOCAL_EXTERNAL:
  162061. + /* External memory. */
  162062. + logical = device->externalLogical;
  162063. + break;
  162064. +
  162065. + case gcvPOOL_SYSTEM:
  162066. + /* System memory. */
  162067. + if (device->contiguousMapped)
  162068. + {
  162069. + logical = device->contiguousBase;
  162070. + }
  162071. + else
  162072. + {
  162073. + gctINT processID;
  162074. + gckOS_GetProcessID(&processID);
  162075. +
  162076. + mdl = (PLINUX_MDL) device->contiguousPhysical;
  162077. +
  162078. + mdlMap = FindMdlMap(mdl, processID);
  162079. + gcmkASSERT(mdlMap);
  162080. +
  162081. + logical = (gctPOINTER) mdlMap->vmaAddr;
  162082. + }
  162083. +#if gcdENABLE_VG
  162084. + if (Core == gcvCORE_VG)
  162085. + {
  162086. + gcmkVERIFY_OK(
  162087. + gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
  162088. + device->contiguousVidMem->baseAddress,
  162089. + &pool,
  162090. + &base));
  162091. + }
  162092. + else
  162093. +#endif
  162094. + {
  162095. + gctUINT32 baseAddress = 0;
  162096. +
  162097. + if (Kernel->hardware->mmuVersion == 0)
  162098. + {
  162099. + gcmkONERROR(gckOS_GetBaseAddress(Kernel->os, &baseAddress));
  162100. + }
  162101. +
  162102. + gcmkVERIFY_OK(
  162103. + gckHARDWARE_SplitMemory(Kernel->hardware,
  162104. + device->contiguousVidMem->baseAddress - baseAddress,
  162105. + &pool,
  162106. + &base));
  162107. + }
  162108. + offset -= base;
  162109. + break;
  162110. +
  162111. + default:
  162112. + /* Invalid memory pool. */
  162113. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  162114. + }
  162115. +
  162116. + /* Build logical address of specified address. */
  162117. + *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset);
  162118. +
  162119. + /* Success. */
  162120. + gcmkFOOTER_ARG("*Logical=%p", *Logical);
  162121. + return gcvSTATUS_OK;
  162122. +
  162123. +OnError:
  162124. + /* Retunn the status. */
  162125. + gcmkFOOTER();
  162126. + return status;
  162127. +}
  162128. +
  162129. +/*******************************************************************************
  162130. +**
  162131. +** gckKERNEL_MapVideoMemory
  162132. +**
  162133. +** Get the logical address for a hardware specific memory address for the
  162134. +** current process.
  162135. +**
  162136. +** INPUT:
  162137. +**
  162138. +** gckKERNEL Kernel
  162139. +** Pointer to an gckKERNEL object.
  162140. +**
  162141. +** gctBOOL InUserSpace
  162142. +** gcvTRUE to map the memory into the user space.
  162143. +**
  162144. +** gctUINT32 Address
  162145. +** Hardware specific memory address.
  162146. +**
  162147. +** OUTPUT:
  162148. +**
  162149. +** gctPOINTER * Logical
  162150. +** Pointer to a variable that will hold the logical address of the
  162151. +** specified memory address.
  162152. +*/
  162153. +gceSTATUS
  162154. +gckKERNEL_MapVideoMemory(
  162155. + IN gckKERNEL Kernel,
  162156. + IN gctBOOL InUserSpace,
  162157. + IN gctUINT32 Address,
  162158. + OUT gctPOINTER * Logical
  162159. + )
  162160. +{
  162161. + return gckKERNEL_MapVideoMemoryEx(Kernel, gcvCORE_MAJOR, InUserSpace, Address, Logical);
  162162. +}
  162163. +/*******************************************************************************
  162164. +**
  162165. +** gckKERNEL_Notify
  162166. +**
  162167. +** This function iscalled by clients to notify the gckKERNRL object of an event.
  162168. +**
  162169. +** INPUT:
  162170. +**
  162171. +** gckKERNEL Kernel
  162172. +** Pointer to an gckKERNEL object.
  162173. +**
  162174. +** gceNOTIFY Notification
  162175. +** Notification event.
  162176. +**
  162177. +** OUTPUT:
  162178. +**
  162179. +** Nothing.
  162180. +*/
  162181. +gceSTATUS
  162182. +gckKERNEL_Notify(
  162183. + IN gckKERNEL Kernel,
  162184. + IN gceNOTIFY Notification,
  162185. + IN gctBOOL Data
  162186. + )
  162187. +{
  162188. + gceSTATUS status;
  162189. +
  162190. + gcmkHEADER_ARG("Kernel=%p Notification=%d Data=%d",
  162191. + Kernel, Notification, Data);
  162192. +
  162193. + /* Verify the arguments. */
  162194. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  162195. +
  162196. + /* Dispatch on notifcation. */
  162197. + switch (Notification)
  162198. + {
  162199. + case gcvNOTIFY_INTERRUPT:
  162200. + /* Process the interrupt. */
  162201. +#if COMMAND_PROCESSOR_VERSION > 1
  162202. + status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
  162203. +#else
  162204. + status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
  162205. +#endif
  162206. + break;
  162207. +
  162208. + default:
  162209. + status = gcvSTATUS_OK;
  162210. + break;
  162211. + }
  162212. +
  162213. + /* Success. */
  162214. + gcmkFOOTER();
  162215. + return status;
  162216. +}
  162217. +
  162218. +gceSTATUS
  162219. +gckKERNEL_QuerySettings(
  162220. + IN gckKERNEL Kernel,
  162221. + OUT gcsKERNEL_SETTINGS * Settings
  162222. + )
  162223. +{
  162224. + gckGALDEVICE device;
  162225. +
  162226. + gcmkHEADER_ARG("Kernel=%p", Kernel);
  162227. +
  162228. + /* Verify the arguments. */
  162229. + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
  162230. + gcmkVERIFY_ARGUMENT(Settings != gcvNULL);
  162231. +
  162232. + /* Extract the pointer to the gckGALDEVICE class. */
  162233. + device = (gckGALDEVICE) Kernel->context;
  162234. +
  162235. + /* Fill in signal. */
  162236. + Settings->signal = device->signal;
  162237. +
  162238. + /* Success. */
  162239. + gcmkFOOTER_ARG("Settings->signal=%d", Settings->signal);
  162240. + return gcvSTATUS_OK;
  162241. +}
  162242. diff -Nur linux-3.14.17/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
  162243. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h 1970-01-01 01:00:00.000000000 +0100
  162244. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h 2014-09-11 18:06:03.126042465 +0200
  162245. @@ -0,0 +1,94 @@
  162246. +/****************************************************************************
  162247. +*
  162248. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  162249. +*
  162250. +* This program is free software; you can redistribute it and/or modify
  162251. +* it under the terms of the GNU General Public License as published by
  162252. +* the Free Software Foundation; either version 2 of the license, or
  162253. +* (at your option) any later version.
  162254. +*
  162255. +* This program is distributed in the hope that it will be useful,
  162256. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  162257. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  162258. +* GNU General Public License for more details.
  162259. +*
  162260. +* You should have received a copy of the GNU General Public License
  162261. +* along with this program; if not write to the Free Software
  162262. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  162263. +*
  162264. +*****************************************************************************/
  162265. +
  162266. +
  162267. +#ifndef __gc_hal_kernel_linux_h_
  162268. +#define __gc_hal_kernel_linux_h_
  162269. +
  162270. +#include <linux/version.h>
  162271. +#include <linux/init.h>
  162272. +#include <linux/module.h>
  162273. +#include <linux/fs.h>
  162274. +#include <linux/mm.h>
  162275. +#include <linux/sched.h>
  162276. +#include <linux/signal.h>
  162277. +#ifdef FLAREON
  162278. +# include <asm/arch-realview/dove_gpio_irq.h>
  162279. +#endif
  162280. +#include <linux/interrupt.h>
  162281. +#include <linux/vmalloc.h>
  162282. +#include <linux/dma-mapping.h>
  162283. +#include <linux/kthread.h>
  162284. +
  162285. +#ifdef MODVERSIONS
  162286. +# include <linux/modversions.h>
  162287. +#endif
  162288. +#include <asm/io.h>
  162289. +#include <asm/uaccess.h>
  162290. +
  162291. +#if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
  162292. +#include <linux/clk.h>
  162293. +#include <linux/regulator/consumer.h>
  162294. +#endif
  162295. +
  162296. +#define NTSTRSAFE_NO_CCH_FUNCTIONS
  162297. +#include "gc_hal.h"
  162298. +#include "gc_hal_driver.h"
  162299. +#include "gc_hal_kernel.h"
  162300. +#include "gc_hal_kernel_device.h"
  162301. +#include "gc_hal_kernel_os.h"
  162302. +#include "gc_hal_kernel_debugfs.h"
  162303. +
  162304. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
  162305. +#define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID)
  162306. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  162307. +#define FIND_TASK_BY_PID(x) find_task_by_vpid(x)
  162308. +#else
  162309. +#define FIND_TASK_BY_PID(x) find_task_by_pid(x)
  162310. +#endif
  162311. +
  162312. +#define _WIDE(string) L##string
  162313. +#define WIDE(string) _WIDE(string)
  162314. +
  162315. +#define countof(a) (sizeof(a) / sizeof(a[0]))
  162316. +
  162317. +#define DRV_NAME "galcore"
  162318. +
  162319. +#define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
  162320. +
  162321. +#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
  162322. +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
  162323. +#else
  162324. +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
  162325. +#endif
  162326. +
  162327. +static inline gctINT
  162328. +GetOrder(
  162329. + IN gctINT numPages
  162330. + )
  162331. +{
  162332. + gctINT order = 0;
  162333. +
  162334. + while ((1 << order) < numPages) order++;
  162335. +
  162336. + return order;
  162337. +}
  162338. +
  162339. +#endif /* __gc_hal_kernel_linux_h_ */
  162340. diff -Nur linux-3.14.17/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
  162341. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c 1970-01-01 01:00:00.000000000 +0100
  162342. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c 2014-09-11 18:06:03.126042465 +0200
  162343. @@ -0,0 +1,32 @@
  162344. +/****************************************************************************
  162345. +*
  162346. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  162347. +*
  162348. +* This program is free software; you can redistribute it and/or modify
  162349. +* it under the terms of the GNU General Public License as published by
  162350. +* the Free Software Foundation; either version 2 of the license, or
  162351. +* (at your option) any later version.
  162352. +*
  162353. +* This program is distributed in the hope that it will be useful,
  162354. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  162355. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  162356. +* GNU General Public License for more details.
  162357. +*
  162358. +* You should have received a copy of the GNU General Public License
  162359. +* along with this program; if not write to the Free Software
  162360. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  162361. +*
  162362. +*****************************************************************************/
  162363. +
  162364. +
  162365. +#include "gc_hal_kernel_linux.h"
  162366. +
  162367. +gctINT
  162368. +gckMATH_ModuloInt(
  162369. + IN gctINT X,
  162370. + IN gctINT Y
  162371. + )
  162372. +{
  162373. + if(Y ==0) {return 0;}
  162374. + else {return X % Y;}
  162375. +}
  162376. diff -Nur linux-3.14.17/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
  162377. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c 1970-01-01 01:00:00.000000000 +0100
  162378. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c 2014-09-11 18:06:03.130042483 +0200
  162379. @@ -0,0 +1,9019 @@
  162380. +/****************************************************************************
  162381. +*
  162382. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  162383. +*
  162384. +* This program is free software; you can redistribute it and/or modify
  162385. +* it under the terms of the GNU General Public License as published by
  162386. +* the Free Software Foundation; either version 2 of the license, or
  162387. +* (at your option) any later version.
  162388. +*
  162389. +* This program is distributed in the hope that it will be useful,
  162390. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  162391. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  162392. +* GNU General Public License for more details.
  162393. +*
  162394. +* You should have received a copy of the GNU General Public License
  162395. +* along with this program; if not write to the Free Software
  162396. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  162397. +*
  162398. +*****************************************************************************/
  162399. +
  162400. +
  162401. +#include "gc_hal_kernel_linux.h"
  162402. +
  162403. +#include <linux/pagemap.h>
  162404. +#include <linux/seq_file.h>
  162405. +#include <linux/mm.h>
  162406. +#include <linux/mman.h>
  162407. +#include <linux/sched.h>
  162408. +#include <asm/atomic.h>
  162409. +#include <linux/dma-mapping.h>
  162410. +#include <linux/slab.h>
  162411. +#include <linux/idr.h>
  162412. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
  162413. +#include <mach/hardware.h>
  162414. +#endif
  162415. +#include <linux/workqueue.h>
  162416. +#include <linux/idr.h>
  162417. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
  162418. +#include <linux/math64.h>
  162419. +#endif
  162420. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  162421. +#include <linux/reset.h>
  162422. +static inline void imx_gpc_power_up_pu(bool flag) {}
  162423. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  162424. +#include <mach/common.h>
  162425. +#endif
  162426. +#include <linux/delay.h>
  162427. +#include <linux/pm_runtime.h>
  162428. +
  162429. +
  162430. +#if gcdANDROID_NATIVE_FENCE_SYNC
  162431. +#include <linux/file.h>
  162432. +#include "gc_hal_kernel_sync.h"
  162433. +#endif
  162434. +
  162435. +
  162436. +#define _GC_OBJ_ZONE gcvZONE_OS
  162437. +
  162438. +/*******************************************************************************
  162439. +***** Version Signature *******************************************************/
  162440. +
  162441. +#ifdef ANDROID
  162442. +const char * _PLATFORM = "\n\0$PLATFORM$Android$\n";
  162443. +#else
  162444. +const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n";
  162445. +#endif
  162446. +
  162447. +#define USER_SIGNAL_TABLE_LEN_INIT 64
  162448. +#define gcdSUPPRESS_OOM_MESSAGE 1
  162449. +
  162450. +#define MEMORY_LOCK(os) \
  162451. + gcmkVERIFY_OK(gckOS_AcquireMutex( \
  162452. + (os), \
  162453. + (os)->memoryLock, \
  162454. + gcvINFINITE))
  162455. +
  162456. +#define MEMORY_UNLOCK(os) \
  162457. + gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryLock))
  162458. +
  162459. +#define MEMORY_MAP_LOCK(os) \
  162460. + gcmkVERIFY_OK(gckOS_AcquireMutex( \
  162461. + (os), \
  162462. + (os)->memoryMapLock, \
  162463. + gcvINFINITE))
  162464. +
  162465. +#define MEMORY_MAP_UNLOCK(os) \
  162466. + gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock))
  162467. +
  162468. +/* Protection bit when mapping memroy to user sapce */
  162469. +#define gcmkPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
  162470. +
  162471. +#if gcdNONPAGED_MEMORY_BUFFERABLE
  162472. +#define gcmkIOREMAP ioremap_wc
  162473. +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
  162474. +#elif !gcdNONPAGED_MEMORY_CACHEABLE
  162475. +#define gcmkIOREMAP ioremap_nocache
  162476. +#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
  162477. +#endif
  162478. +
  162479. +#if gcdSUPPRESS_OOM_MESSAGE
  162480. +#define gcdNOWARN __GFP_NOWARN
  162481. +#else
  162482. +#define gcdNOWARN 0
  162483. +#endif
  162484. +
  162485. +#define gcdINFINITE_TIMEOUT (60 * 1000)
  162486. +#define gcdDETECT_TIMEOUT 0
  162487. +#define gcdDETECT_DMA_ADDRESS 1
  162488. +#define gcdDETECT_DMA_STATE 1
  162489. +
  162490. +#define gcdUSE_NON_PAGED_MEMORY_CACHE 10
  162491. +
  162492. +/******************************************************************************\
  162493. +********************************** Structures **********************************
  162494. +\******************************************************************************/
  162495. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162496. +typedef struct _gcsNonPagedMemoryCache
  162497. +{
  162498. +#ifndef NO_DMA_COHERENT
  162499. + gctINT size;
  162500. + gctSTRING addr;
  162501. + dma_addr_t dmaHandle;
  162502. +#else
  162503. + long order;
  162504. + struct page * page;
  162505. +#endif
  162506. +
  162507. + struct _gcsNonPagedMemoryCache * prev;
  162508. + struct _gcsNonPagedMemoryCache * next;
  162509. +}
  162510. +gcsNonPagedMemoryCache;
  162511. +#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
  162512. +
  162513. +typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
  162514. +typedef struct _gcsUSER_MAPPING
  162515. +{
  162516. + /* Pointer to next mapping structure. */
  162517. + gcsUSER_MAPPING_PTR next;
  162518. +
  162519. + /* Physical address of this mapping. */
  162520. + gctUINT32 physical;
  162521. +
  162522. + /* Logical address of this mapping. */
  162523. + gctPOINTER logical;
  162524. +
  162525. + /* Number of bytes of this mapping. */
  162526. + gctSIZE_T bytes;
  162527. +
  162528. + /* Starting address of this mapping. */
  162529. + gctINT8_PTR start;
  162530. +
  162531. + /* Ending address of this mapping. */
  162532. + gctINT8_PTR end;
  162533. +}
  162534. +gcsUSER_MAPPING;
  162535. +
  162536. +typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
  162537. +typedef struct _gcsINTEGER_DB
  162538. +{
  162539. + struct idr idr;
  162540. + spinlock_t lock;
  162541. + gctINT curr;
  162542. +}
  162543. +gcsINTEGER_DB;
  162544. +
  162545. +struct _gckOS
  162546. +{
  162547. + /* Object. */
  162548. + gcsOBJECT object;
  162549. +
  162550. + /* Heap. */
  162551. + gckHEAP heap;
  162552. +
  162553. + /* Pointer to device */
  162554. + gckGALDEVICE device;
  162555. +
  162556. + /* Memory management */
  162557. + gctPOINTER memoryLock;
  162558. + gctPOINTER memoryMapLock;
  162559. +
  162560. + struct _LINUX_MDL *mdlHead;
  162561. + struct _LINUX_MDL *mdlTail;
  162562. +
  162563. + /* Kernel process ID. */
  162564. + gctUINT32 kernelProcessID;
  162565. +
  162566. + /* Signal management. */
  162567. +
  162568. + /* Lock. */
  162569. + gctPOINTER signalMutex;
  162570. +
  162571. + /* signal id database. */
  162572. + gcsINTEGER_DB signalDB;
  162573. +
  162574. +#if gcdANDROID_NATIVE_FENCE_SYNC
  162575. + /* Lock. */
  162576. + gctPOINTER syncPointMutex;
  162577. +
  162578. + /* sync point id database. */
  162579. + gcsINTEGER_DB syncPointDB;
  162580. +#endif
  162581. +
  162582. + gcsUSER_MAPPING_PTR userMap;
  162583. + gctPOINTER debugLock;
  162584. +
  162585. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162586. + gctUINT cacheSize;
  162587. + gcsNonPagedMemoryCache * cacheHead;
  162588. + gcsNonPagedMemoryCache * cacheTail;
  162589. +#endif
  162590. +
  162591. + /* workqueue for os timer. */
  162592. + struct workqueue_struct * workqueue;
  162593. +};
  162594. +
  162595. +typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
  162596. +typedef struct _gcsSIGNAL
  162597. +{
  162598. + /* Kernel sync primitive. */
  162599. + struct completion obj;
  162600. +
  162601. + /* Manual reset flag. */
  162602. + gctBOOL manualReset;
  162603. +
  162604. + /* The reference counter. */
  162605. + atomic_t ref;
  162606. +
  162607. + /* The owner of the signal. */
  162608. + gctHANDLE process;
  162609. +
  162610. + gckHARDWARE hardware;
  162611. +
  162612. + /* ID. */
  162613. + gctUINT32 id;
  162614. +}
  162615. +gcsSIGNAL;
  162616. +
  162617. +#if gcdANDROID_NATIVE_FENCE_SYNC
  162618. +typedef struct _gcsSYNC_POINT * gcsSYNC_POINT_PTR;
  162619. +typedef struct _gcsSYNC_POINT
  162620. +{
  162621. + /* The reference counter. */
  162622. + atomic_t ref;
  162623. +
  162624. + /* State. */
  162625. + atomic_t state;
  162626. +
  162627. + /* timeline. */
  162628. + struct sync_timeline * timeline;
  162629. +
  162630. + /* ID. */
  162631. + gctUINT32 id;
  162632. +}
  162633. +gcsSYNC_POINT;
  162634. +#endif
  162635. +
  162636. +typedef struct _gcsPageInfo * gcsPageInfo_PTR;
  162637. +typedef struct _gcsPageInfo
  162638. +{
  162639. + struct page **pages;
  162640. + gctUINT32_PTR pageTable;
  162641. +}
  162642. +gcsPageInfo;
  162643. +
  162644. +typedef struct _gcsOSTIMER * gcsOSTIMER_PTR;
  162645. +typedef struct _gcsOSTIMER
  162646. +{
  162647. + struct delayed_work work;
  162648. + gctTIMERFUNCTION function;
  162649. + gctPOINTER data;
  162650. +} gcsOSTIMER;
  162651. +
  162652. +/******************************************************************************\
  162653. +******************************* Private Functions ******************************
  162654. +\******************************************************************************/
  162655. +
  162656. +static gctINT
  162657. +_GetProcessID(
  162658. + void
  162659. + )
  162660. +{
  162661. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  162662. + return task_tgid_vnr(current);
  162663. +#else
  162664. + return current->tgid;
  162665. +#endif
  162666. +}
  162667. +
  162668. +static gctINT
  162669. +_GetThreadID(
  162670. + void
  162671. + )
  162672. +{
  162673. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
  162674. + return task_pid_vnr(current);
  162675. +#else
  162676. + return current->pid;
  162677. +#endif
  162678. +}
  162679. +
  162680. +static PLINUX_MDL
  162681. +_CreateMdl(
  162682. + IN gctINT ProcessID
  162683. + )
  162684. +{
  162685. + PLINUX_MDL mdl;
  162686. +
  162687. + gcmkHEADER_ARG("ProcessID=%d", ProcessID);
  162688. +
  162689. + mdl = (PLINUX_MDL)kzalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | gcdNOWARN);
  162690. + if (mdl == gcvNULL)
  162691. + {
  162692. + gcmkFOOTER_NO();
  162693. + return gcvNULL;
  162694. + }
  162695. +
  162696. + mdl->pid = ProcessID;
  162697. + mdl->maps = gcvNULL;
  162698. + mdl->prev = gcvNULL;
  162699. + mdl->next = gcvNULL;
  162700. +
  162701. + gcmkFOOTER_ARG("0x%X", mdl);
  162702. + return mdl;
  162703. +}
  162704. +
  162705. +static gceSTATUS
  162706. +_DestroyMdlMap(
  162707. + IN PLINUX_MDL Mdl,
  162708. + IN PLINUX_MDL_MAP MdlMap
  162709. + );
  162710. +
  162711. +static gceSTATUS
  162712. +_DestroyMdl(
  162713. + IN PLINUX_MDL Mdl
  162714. + )
  162715. +{
  162716. + PLINUX_MDL_MAP mdlMap, next;
  162717. +
  162718. + gcmkHEADER_ARG("Mdl=0x%X", Mdl);
  162719. +
  162720. + /* Verify the arguments. */
  162721. + gcmkVERIFY_ARGUMENT(Mdl != gcvNULL);
  162722. +
  162723. + mdlMap = Mdl->maps;
  162724. +
  162725. + while (mdlMap != gcvNULL)
  162726. + {
  162727. + next = mdlMap->next;
  162728. +
  162729. + gcmkVERIFY_OK(_DestroyMdlMap(Mdl, mdlMap));
  162730. +
  162731. + mdlMap = next;
  162732. + }
  162733. +
  162734. + kfree(Mdl);
  162735. +
  162736. + gcmkFOOTER_NO();
  162737. + return gcvSTATUS_OK;
  162738. +}
  162739. +
  162740. +static PLINUX_MDL_MAP
  162741. +_CreateMdlMap(
  162742. + IN PLINUX_MDL Mdl,
  162743. + IN gctINT ProcessID
  162744. + )
  162745. +{
  162746. + PLINUX_MDL_MAP mdlMap;
  162747. +
  162748. + gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
  162749. +
  162750. + mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | gcdNOWARN);
  162751. + if (mdlMap == gcvNULL)
  162752. + {
  162753. + gcmkFOOTER_NO();
  162754. + return gcvNULL;
  162755. + }
  162756. +
  162757. + mdlMap->pid = ProcessID;
  162758. + mdlMap->vmaAddr = gcvNULL;
  162759. + mdlMap->vma = gcvNULL;
  162760. + mdlMap->count = 0;
  162761. +
  162762. + mdlMap->next = Mdl->maps;
  162763. + Mdl->maps = mdlMap;
  162764. +
  162765. + gcmkFOOTER_ARG("0x%X", mdlMap);
  162766. + return mdlMap;
  162767. +}
  162768. +
  162769. +static gceSTATUS
  162770. +_DestroyMdlMap(
  162771. + IN PLINUX_MDL Mdl,
  162772. + IN PLINUX_MDL_MAP MdlMap
  162773. + )
  162774. +{
  162775. + PLINUX_MDL_MAP prevMdlMap;
  162776. +
  162777. + gcmkHEADER_ARG("Mdl=0x%X MdlMap=0x%X", Mdl, MdlMap);
  162778. +
  162779. + /* Verify the arguments. */
  162780. + gcmkVERIFY_ARGUMENT(MdlMap != gcvNULL);
  162781. + gcmkASSERT(Mdl->maps != gcvNULL);
  162782. +
  162783. + if (Mdl->maps == MdlMap)
  162784. + {
  162785. + Mdl->maps = MdlMap->next;
  162786. + }
  162787. + else
  162788. + {
  162789. + prevMdlMap = Mdl->maps;
  162790. +
  162791. + while (prevMdlMap->next != MdlMap)
  162792. + {
  162793. + prevMdlMap = prevMdlMap->next;
  162794. +
  162795. + gcmkASSERT(prevMdlMap != gcvNULL);
  162796. + }
  162797. +
  162798. + prevMdlMap->next = MdlMap->next;
  162799. + }
  162800. +
  162801. + kfree(MdlMap);
  162802. +
  162803. + gcmkFOOTER_NO();
  162804. + return gcvSTATUS_OK;
  162805. +}
  162806. +
  162807. +extern PLINUX_MDL_MAP
  162808. +FindMdlMap(
  162809. + IN PLINUX_MDL Mdl,
  162810. + IN gctINT ProcessID
  162811. + )
  162812. +{
  162813. + PLINUX_MDL_MAP mdlMap;
  162814. +
  162815. + gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
  162816. + if(Mdl == gcvNULL)
  162817. + {
  162818. + gcmkFOOTER_NO();
  162819. + return gcvNULL;
  162820. + }
  162821. + mdlMap = Mdl->maps;
  162822. +
  162823. + while (mdlMap != gcvNULL)
  162824. + {
  162825. + if (mdlMap->pid == ProcessID)
  162826. + {
  162827. + gcmkFOOTER_ARG("0x%X", mdlMap);
  162828. + return mdlMap;
  162829. + }
  162830. +
  162831. + mdlMap = mdlMap->next;
  162832. + }
  162833. +
  162834. + gcmkFOOTER_NO();
  162835. + return gcvNULL;
  162836. +}
  162837. +
  162838. +void
  162839. +OnProcessExit(
  162840. + IN gckOS Os,
  162841. + IN gckKERNEL Kernel
  162842. + )
  162843. +{
  162844. +}
  162845. +
  162846. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
  162847. +static inline int
  162848. +is_vmalloc_addr(
  162849. + void *Addr
  162850. + )
  162851. +{
  162852. + unsigned long addr = (unsigned long)Addr;
  162853. +
  162854. + return addr >= VMALLOC_START && addr < VMALLOC_END;
  162855. +}
  162856. +#endif
  162857. +
  162858. +static void
  162859. +_NonContiguousFree(
  162860. + IN struct page ** Pages,
  162861. + IN gctUINT32 NumPages
  162862. + )
  162863. +{
  162864. + gctINT i;
  162865. +
  162866. + gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages);
  162867. +
  162868. + gcmkASSERT(Pages != gcvNULL);
  162869. +
  162870. + for (i = 0; i < NumPages; i++)
  162871. + {
  162872. + __free_page(Pages[i]);
  162873. + }
  162874. +
  162875. + if (is_vmalloc_addr(Pages))
  162876. + {
  162877. + vfree(Pages);
  162878. + }
  162879. + else
  162880. + {
  162881. + kfree(Pages);
  162882. + }
  162883. +
  162884. + gcmkFOOTER_NO();
  162885. +}
  162886. +
  162887. +static struct page **
  162888. +_NonContiguousAlloc(
  162889. + IN gctUINT32 NumPages
  162890. + )
  162891. +{
  162892. + struct page ** pages;
  162893. + struct page *p;
  162894. + gctINT i, size;
  162895. +
  162896. + gcmkHEADER_ARG("NumPages=%lu", NumPages);
  162897. +
  162898. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
  162899. + if (NumPages > totalram_pages)
  162900. +#else
  162901. + if (NumPages > num_physpages)
  162902. +#endif
  162903. + {
  162904. + gcmkFOOTER_NO();
  162905. + return gcvNULL;
  162906. + }
  162907. +
  162908. + size = NumPages * sizeof(struct page *);
  162909. +
  162910. + pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
  162911. +
  162912. + if (!pages)
  162913. + {
  162914. + pages = vmalloc(size);
  162915. +
  162916. + if (!pages)
  162917. + {
  162918. + gcmkFOOTER_NO();
  162919. + return gcvNULL;
  162920. + }
  162921. + }
  162922. +
  162923. + for (i = 0; i < NumPages; i++)
  162924. + {
  162925. + p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN);
  162926. +
  162927. + if (!p)
  162928. + {
  162929. + _NonContiguousFree(pages, i);
  162930. + gcmkFOOTER_NO();
  162931. + return gcvNULL;
  162932. + }
  162933. +
  162934. + pages[i] = p;
  162935. + }
  162936. +
  162937. + gcmkFOOTER_ARG("pages=0x%X", pages);
  162938. + return pages;
  162939. +}
  162940. +
  162941. +static inline struct page *
  162942. +_NonContiguousToPage(
  162943. + IN struct page ** Pages,
  162944. + IN gctUINT32 Index
  162945. + )
  162946. +{
  162947. + gcmkASSERT(Pages != gcvNULL);
  162948. + return Pages[Index];
  162949. +}
  162950. +
  162951. +static inline unsigned long
  162952. +_NonContiguousToPfn(
  162953. + IN struct page ** Pages,
  162954. + IN gctUINT32 Index
  162955. + )
  162956. +{
  162957. + gcmkASSERT(Pages != gcvNULL);
  162958. + return page_to_pfn(_NonContiguousToPage(Pages, Index));
  162959. +}
  162960. +
  162961. +static inline unsigned long
  162962. +_NonContiguousToPhys(
  162963. + IN struct page ** Pages,
  162964. + IN gctUINT32 Index
  162965. + )
  162966. +{
  162967. + gcmkASSERT(Pages != gcvNULL);
  162968. + return page_to_phys(_NonContiguousToPage(Pages, Index));
  162969. +}
  162970. +
  162971. +
  162972. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  162973. +
  162974. +static gctBOOL
  162975. +_AddNonPagedMemoryCache(
  162976. + gckOS Os,
  162977. +#ifndef NO_DMA_COHERENT
  162978. + gctINT Size,
  162979. + gctSTRING Addr,
  162980. + dma_addr_t DmaHandle
  162981. +#else
  162982. + long Order,
  162983. + struct page * Page
  162984. +#endif
  162985. + )
  162986. +{
  162987. + gcsNonPagedMemoryCache *cache;
  162988. +
  162989. + if (Os->cacheSize >= gcdUSE_NON_PAGED_MEMORY_CACHE)
  162990. + {
  162991. + return gcvFALSE;
  162992. + }
  162993. +
  162994. + /* Allocate the cache record */
  162995. + cache = (gcsNonPagedMemoryCache *)kmalloc(sizeof(gcsNonPagedMemoryCache), GFP_ATOMIC);
  162996. +
  162997. + if (cache == gcvNULL) return gcvFALSE;
  162998. +
  162999. +#ifndef NO_DMA_COHERENT
  163000. + cache->size = Size;
  163001. + cache->addr = Addr;
  163002. + cache->dmaHandle = DmaHandle;
  163003. +#else
  163004. + cache->order = Order;
  163005. + cache->page = Page;
  163006. +#endif
  163007. +
  163008. + /* Add to list */
  163009. + if (Os->cacheHead == gcvNULL)
  163010. + {
  163011. + cache->prev = gcvNULL;
  163012. + cache->next = gcvNULL;
  163013. + Os->cacheHead =
  163014. + Os->cacheTail = cache;
  163015. + }
  163016. + else
  163017. + {
  163018. + /* Add to the tail. */
  163019. + cache->prev = Os->cacheTail;
  163020. + cache->next = gcvNULL;
  163021. + Os->cacheTail->next = cache;
  163022. + Os->cacheTail = cache;
  163023. + }
  163024. +
  163025. + Os->cacheSize++;
  163026. +
  163027. + return gcvTRUE;
  163028. +}
  163029. +
  163030. +#ifndef NO_DMA_COHERENT
  163031. +static gctSTRING
  163032. +_GetNonPagedMemoryCache(
  163033. + gckOS Os,
  163034. + gctINT Size,
  163035. + dma_addr_t * DmaHandle
  163036. + )
  163037. +#else
  163038. +static struct page *
  163039. +_GetNonPagedMemoryCache(
  163040. + gckOS Os,
  163041. + long Order
  163042. + )
  163043. +#endif
  163044. +{
  163045. + gcsNonPagedMemoryCache *cache;
  163046. +#ifndef NO_DMA_COHERENT
  163047. + gctSTRING addr;
  163048. +#else
  163049. + struct page * page;
  163050. +#endif
  163051. +
  163052. + if (Os->cacheHead == gcvNULL) return gcvNULL;
  163053. +
  163054. + /* Find the right cache */
  163055. + cache = Os->cacheHead;
  163056. +
  163057. + while (cache != gcvNULL)
  163058. + {
  163059. +#ifndef NO_DMA_COHERENT
  163060. + if (cache->size == Size) break;
  163061. +#else
  163062. + if (cache->order == Order) break;
  163063. +#endif
  163064. +
  163065. + cache = cache->next;
  163066. + }
  163067. +
  163068. + if (cache == gcvNULL) return gcvNULL;
  163069. +
  163070. + /* Remove the cache from list */
  163071. + if (cache == Os->cacheHead)
  163072. + {
  163073. + Os->cacheHead = cache->next;
  163074. +
  163075. + if (Os->cacheHead == gcvNULL)
  163076. + {
  163077. + Os->cacheTail = gcvNULL;
  163078. + }
  163079. + }
  163080. + else
  163081. + {
  163082. + cache->prev->next = cache->next;
  163083. +
  163084. + if (cache == Os->cacheTail)
  163085. + {
  163086. + Os->cacheTail = cache->prev;
  163087. + }
  163088. + else
  163089. + {
  163090. + cache->next->prev = cache->prev;
  163091. + }
  163092. + }
  163093. +
  163094. + /* Destroy cache */
  163095. +#ifndef NO_DMA_COHERENT
  163096. + addr = cache->addr;
  163097. + *DmaHandle = cache->dmaHandle;
  163098. +#else
  163099. + page = cache->page;
  163100. +#endif
  163101. +
  163102. + kfree(cache);
  163103. +
  163104. + Os->cacheSize--;
  163105. +
  163106. +#ifndef NO_DMA_COHERENT
  163107. + return addr;
  163108. +#else
  163109. + return page;
  163110. +#endif
  163111. +}
  163112. +
  163113. +static void
  163114. +_FreeAllNonPagedMemoryCache(
  163115. + gckOS Os
  163116. + )
  163117. +{
  163118. + gcsNonPagedMemoryCache *cache, *nextCache;
  163119. +
  163120. + MEMORY_LOCK(Os);
  163121. +
  163122. + cache = Os->cacheHead;
  163123. +
  163124. + while (cache != gcvNULL)
  163125. + {
  163126. + if (cache != Os->cacheTail)
  163127. + {
  163128. + nextCache = cache->next;
  163129. + }
  163130. + else
  163131. + {
  163132. + nextCache = gcvNULL;
  163133. + }
  163134. +
  163135. + /* Remove the cache from list */
  163136. + if (cache == Os->cacheHead)
  163137. + {
  163138. + Os->cacheHead = cache->next;
  163139. +
  163140. + if (Os->cacheHead == gcvNULL)
  163141. + {
  163142. + Os->cacheTail = gcvNULL;
  163143. + }
  163144. + }
  163145. + else
  163146. + {
  163147. + cache->prev->next = cache->next;
  163148. +
  163149. + if (cache == Os->cacheTail)
  163150. + {
  163151. + Os->cacheTail = cache->prev;
  163152. + }
  163153. + else
  163154. + {
  163155. + cache->next->prev = cache->prev;
  163156. + }
  163157. + }
  163158. +
  163159. +#ifndef NO_DMA_COHERENT
  163160. + dma_free_coherent(gcvNULL,
  163161. + cache->size,
  163162. + cache->addr,
  163163. + cache->dmaHandle);
  163164. +#else
  163165. + free_pages((unsigned long)page_address(cache->page), cache->order);
  163166. +#endif
  163167. +
  163168. + kfree(cache);
  163169. +
  163170. + cache = nextCache;
  163171. + }
  163172. +
  163173. + MEMORY_UNLOCK(Os);
  163174. +}
  163175. +
  163176. +#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
  163177. +
  163178. +/*******************************************************************************
  163179. +** Integer Id Management.
  163180. +*/
  163181. +gceSTATUS
  163182. +_AllocateIntegerId(
  163183. + IN gcsINTEGER_DB_PTR Database,
  163184. + IN gctPOINTER KernelPointer,
  163185. + OUT gctUINT32 *Id
  163186. + )
  163187. +{
  163188. + int result;
  163189. + gctINT next;
  163190. +
  163191. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
  163192. + idr_preload(GFP_KERNEL | gcdNOWARN);
  163193. +
  163194. + spin_lock(&Database->lock);
  163195. +
  163196. + next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
  163197. + result = idr_alloc(&Database->idr, KernelPointer, next, 0, GFP_ATOMIC);
  163198. +
  163199. + if (!result)
  163200. + {
  163201. + Database->curr = *Id;
  163202. + }
  163203. +
  163204. + spin_unlock(&Database->lock);
  163205. +
  163206. + idr_preload_end();
  163207. +
  163208. + if (result < 0)
  163209. + {
  163210. + return gcvSTATUS_OUT_OF_RESOURCES;
  163211. + }
  163212. +
  163213. + *Id = result;
  163214. +#else
  163215. +again:
  163216. + if (idr_pre_get(&Database->idr, GFP_KERNEL | gcdNOWARN) == 0)
  163217. + {
  163218. + return gcvSTATUS_OUT_OF_MEMORY;
  163219. + }
  163220. +
  163221. + spin_lock(&Database->lock);
  163222. +
  163223. + next = (Database->curr + 1 <= 0) ? 1 : Database->curr + 1;
  163224. +
  163225. + /* Try to get a id greater than current id. */
  163226. + result = idr_get_new_above(&Database->idr, KernelPointer, next, Id);
  163227. +
  163228. + if (!result)
  163229. + {
  163230. + Database->curr = *Id;
  163231. + }
  163232. +
  163233. + spin_unlock(&Database->lock);
  163234. +
  163235. + if (result == -EAGAIN)
  163236. + {
  163237. + goto again;
  163238. + }
  163239. +
  163240. + if (result != 0)
  163241. + {
  163242. + return gcvSTATUS_OUT_OF_RESOURCES;
  163243. + }
  163244. +#endif
  163245. +
  163246. + return gcvSTATUS_OK;
  163247. +}
  163248. +
  163249. +gceSTATUS
  163250. +_QueryIntegerId(
  163251. + IN gcsINTEGER_DB_PTR Database,
  163252. + IN gctUINT32 Id,
  163253. + OUT gctPOINTER * KernelPointer
  163254. + )
  163255. +{
  163256. + gctPOINTER pointer;
  163257. +
  163258. + spin_lock(&Database->lock);
  163259. +
  163260. + pointer = idr_find(&Database->idr, Id);
  163261. +
  163262. + spin_unlock(&Database->lock);
  163263. +
  163264. + if(pointer)
  163265. + {
  163266. + *KernelPointer = pointer;
  163267. + return gcvSTATUS_OK;
  163268. + }
  163269. + else
  163270. + {
  163271. + gcmkTRACE_ZONE(
  163272. + gcvLEVEL_ERROR, gcvZONE_OS,
  163273. + "%s(%d) Id = %d is not found",
  163274. + __FUNCTION__, __LINE__, Id);
  163275. +
  163276. + return gcvSTATUS_NOT_FOUND;
  163277. + }
  163278. +}
  163279. +
  163280. +gceSTATUS
  163281. +_DestroyIntegerId(
  163282. + IN gcsINTEGER_DB_PTR Database,
  163283. + IN gctUINT32 Id
  163284. + )
  163285. +{
  163286. + spin_lock(&Database->lock);
  163287. +
  163288. + idr_remove(&Database->idr, Id);
  163289. +
  163290. + spin_unlock(&Database->lock);
  163291. +
  163292. + return gcvSTATUS_OK;
  163293. +}
  163294. +
  163295. +static void
  163296. +_UnmapUserLogical(
  163297. + IN gctINT Pid,
  163298. + IN gctPOINTER Logical,
  163299. + IN gctUINT32 Size
  163300. +)
  163301. +{
  163302. + if (unlikely(current->mm == gcvNULL))
  163303. + {
  163304. + /* Do nothing if process is exiting. */
  163305. + return;
  163306. + }
  163307. +
  163308. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  163309. + if (vm_munmap((unsigned long)Logical, Size) < 0)
  163310. + {
  163311. + gcmkTRACE_ZONE(
  163312. + gcvLEVEL_WARNING, gcvZONE_OS,
  163313. + "%s(%d): vm_munmap failed",
  163314. + __FUNCTION__, __LINE__
  163315. + );
  163316. + }
  163317. +#else
  163318. + down_write(&current->mm->mmap_sem);
  163319. + if (do_munmap(current->mm, (unsigned long)Logical, Size) < 0)
  163320. + {
  163321. + gcmkTRACE_ZONE(
  163322. + gcvLEVEL_WARNING, gcvZONE_OS,
  163323. + "%s(%d): do_munmap failed",
  163324. + __FUNCTION__, __LINE__
  163325. + );
  163326. + }
  163327. + up_write(&current->mm->mmap_sem);
  163328. +#endif
  163329. +}
  163330. +
  163331. +gceSTATUS
  163332. +_QueryProcessPageTable(
  163333. + IN gctPOINTER Logical,
  163334. + OUT gctUINT32 * Address
  163335. + )
  163336. +{
  163337. + spinlock_t *lock;
  163338. + gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
  163339. + pgd_t *pgd;
  163340. + pud_t *pud;
  163341. + pmd_t *pmd;
  163342. + pte_t *pte;
  163343. +
  163344. + if (!current->mm)
  163345. + {
  163346. + return gcvSTATUS_NOT_FOUND;
  163347. + }
  163348. +
  163349. + pgd = pgd_offset(current->mm, logical);
  163350. + if (pgd_none(*pgd) || pgd_bad(*pgd))
  163351. + {
  163352. + return gcvSTATUS_NOT_FOUND;
  163353. + }
  163354. +
  163355. + pud = pud_offset(pgd, logical);
  163356. + if (pud_none(*pud) || pud_bad(*pud))
  163357. + {
  163358. + return gcvSTATUS_NOT_FOUND;
  163359. + }
  163360. +
  163361. + pmd = pmd_offset(pud, logical);
  163362. + if (pmd_none(*pmd) || pmd_bad(*pmd))
  163363. + {
  163364. + return gcvSTATUS_NOT_FOUND;
  163365. + }
  163366. +
  163367. + pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
  163368. + if (!pte)
  163369. + {
  163370. + return gcvSTATUS_NOT_FOUND;
  163371. + }
  163372. +
  163373. + if (!pte_present(*pte))
  163374. + {
  163375. + pte_unmap_unlock(pte, lock);
  163376. + return gcvSTATUS_NOT_FOUND;
  163377. + }
  163378. +
  163379. + *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
  163380. + pte_unmap_unlock(pte, lock);
  163381. +
  163382. + return gcvSTATUS_OK;
  163383. +}
  163384. +
  163385. +/*******************************************************************************
  163386. +**
  163387. +** gckOS_Construct
  163388. +**
  163389. +** Construct a new gckOS object.
  163390. +**
  163391. +** INPUT:
  163392. +**
  163393. +** gctPOINTER Context
  163394. +** Pointer to the gckGALDEVICE class.
  163395. +**
  163396. +** OUTPUT:
  163397. +**
  163398. +** gckOS * Os
  163399. +** Pointer to a variable that will hold the pointer to the gckOS object.
  163400. +*/
  163401. +gceSTATUS
  163402. +gckOS_Construct(
  163403. + IN gctPOINTER Context,
  163404. + OUT gckOS * Os
  163405. + )
  163406. +{
  163407. + gckOS os;
  163408. + gceSTATUS status;
  163409. +
  163410. + gcmkHEADER_ARG("Context=0x%X", Context);
  163411. +
  163412. + /* Verify the arguments. */
  163413. + gcmkVERIFY_ARGUMENT(Os != gcvNULL);
  163414. +
  163415. + /* Allocate the gckOS object. */
  163416. + os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | gcdNOWARN);
  163417. +
  163418. + if (os == gcvNULL)
  163419. + {
  163420. + /* Out of memory. */
  163421. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  163422. + return gcvSTATUS_OUT_OF_MEMORY;
  163423. + }
  163424. +
  163425. + /* Zero the memory. */
  163426. + gckOS_ZeroMemory(os, gcmSIZEOF(struct _gckOS));
  163427. +
  163428. + /* Initialize the gckOS object. */
  163429. + os->object.type = gcvOBJ_OS;
  163430. +
  163431. + /* Set device device. */
  163432. + os->device = Context;
  163433. +
  163434. + /* IMPORTANT! No heap yet. */
  163435. + os->heap = gcvNULL;
  163436. +
  163437. + /* Initialize the memory lock. */
  163438. + gcmkONERROR(gckOS_CreateMutex(os, &os->memoryLock));
  163439. + gcmkONERROR(gckOS_CreateMutex(os, &os->memoryMapLock));
  163440. +
  163441. + /* Create debug lock mutex. */
  163442. + gcmkONERROR(gckOS_CreateMutex(os, &os->debugLock));
  163443. +
  163444. +
  163445. + os->mdlHead = os->mdlTail = gcvNULL;
  163446. +
  163447. + /* Get the kernel process ID. */
  163448. + gcmkONERROR(gckOS_GetProcessID(&os->kernelProcessID));
  163449. +
  163450. + /*
  163451. + * Initialize the signal manager.
  163452. + */
  163453. +
  163454. + /* Initialize mutex. */
  163455. + gcmkONERROR(gckOS_CreateMutex(os, &os->signalMutex));
  163456. +
  163457. + /* Initialize signal id database lock. */
  163458. + spin_lock_init(&os->signalDB.lock);
  163459. +
  163460. + /* Initialize signal id database. */
  163461. + idr_init(&os->signalDB.idr);
  163462. +
  163463. +#if gcdANDROID_NATIVE_FENCE_SYNC
  163464. + /*
  163465. + * Initialize the sync point manager.
  163466. + */
  163467. +
  163468. + /* Initialize mutex. */
  163469. + gcmkONERROR(gckOS_CreateMutex(os, &os->syncPointMutex));
  163470. +
  163471. + /* Initialize sync point id database lock. */
  163472. + spin_lock_init(&os->syncPointDB.lock);
  163473. +
  163474. + /* Initialize sync point id database. */
  163475. + idr_init(&os->syncPointDB.idr);
  163476. +#endif
  163477. +
  163478. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  163479. + os->cacheSize = 0;
  163480. + os->cacheHead = gcvNULL;
  163481. + os->cacheTail = gcvNULL;
  163482. +#endif
  163483. +
  163484. + /* Create a workqueue for os timer. */
  163485. + os->workqueue = create_singlethread_workqueue("galcore workqueue");
  163486. +
  163487. + if (os->workqueue == gcvNULL)
  163488. + {
  163489. + /* Out of memory. */
  163490. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  163491. + }
  163492. +
  163493. + /* Return pointer to the gckOS object. */
  163494. + *Os = os;
  163495. +
  163496. + /* Success. */
  163497. + gcmkFOOTER_ARG("*Os=0x%X", *Os);
  163498. + return gcvSTATUS_OK;
  163499. +
  163500. +OnError:
  163501. +
  163502. +#if gcdANDROID_NATIVE_FENCE_SYNC
  163503. + if (os->syncPointMutex != gcvNULL)
  163504. + {
  163505. + gcmkVERIFY_OK(
  163506. + gckOS_DeleteMutex(os, os->syncPointMutex));
  163507. + }
  163508. +#endif
  163509. +
  163510. + if (os->signalMutex != gcvNULL)
  163511. + {
  163512. + gcmkVERIFY_OK(
  163513. + gckOS_DeleteMutex(os, os->signalMutex));
  163514. + }
  163515. +
  163516. + if (os->heap != gcvNULL)
  163517. + {
  163518. + gcmkVERIFY_OK(
  163519. + gckHEAP_Destroy(os->heap));
  163520. + }
  163521. +
  163522. + if (os->memoryMapLock != gcvNULL)
  163523. + {
  163524. + gcmkVERIFY_OK(
  163525. + gckOS_DeleteMutex(os, os->memoryMapLock));
  163526. + }
  163527. +
  163528. + if (os->memoryLock != gcvNULL)
  163529. + {
  163530. + gcmkVERIFY_OK(
  163531. + gckOS_DeleteMutex(os, os->memoryLock));
  163532. + }
  163533. +
  163534. + if (os->debugLock != gcvNULL)
  163535. + {
  163536. + gcmkVERIFY_OK(
  163537. + gckOS_DeleteMutex(os, os->debugLock));
  163538. + }
  163539. +
  163540. + if (os->workqueue != gcvNULL)
  163541. + {
  163542. + destroy_workqueue(os->workqueue);
  163543. + }
  163544. +
  163545. + kfree(os);
  163546. +
  163547. + /* Return the error. */
  163548. + gcmkFOOTER();
  163549. + return status;
  163550. +}
  163551. +
  163552. +/*******************************************************************************
  163553. +**
  163554. +** gckOS_Destroy
  163555. +**
  163556. +** Destroy an gckOS object.
  163557. +**
  163558. +** INPUT:
  163559. +**
  163560. +** gckOS Os
  163561. +** Pointer to an gckOS object that needs to be destroyed.
  163562. +**
  163563. +** OUTPUT:
  163564. +**
  163565. +** Nothing.
  163566. +*/
  163567. +gceSTATUS
  163568. +gckOS_Destroy(
  163569. + IN gckOS Os
  163570. + )
  163571. +{
  163572. + gckHEAP heap;
  163573. +
  163574. + gcmkHEADER_ARG("Os=0x%X", Os);
  163575. +
  163576. + /* Verify the arguments. */
  163577. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163578. +
  163579. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  163580. + _FreeAllNonPagedMemoryCache(Os);
  163581. +#endif
  163582. +
  163583. +#if gcdANDROID_NATIVE_FENCE_SYNC
  163584. + /*
  163585. + * Destroy the sync point manager.
  163586. + */
  163587. +
  163588. + /* Destroy the mutex. */
  163589. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->syncPointMutex));
  163590. +#endif
  163591. +
  163592. + /*
  163593. + * Destroy the signal manager.
  163594. + */
  163595. +
  163596. + /* Destroy the mutex. */
  163597. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->signalMutex));
  163598. +
  163599. + if (Os->heap != gcvNULL)
  163600. + {
  163601. + /* Mark gckHEAP as gone. */
  163602. + heap = Os->heap;
  163603. + Os->heap = gcvNULL;
  163604. +
  163605. + /* Destroy the gckHEAP object. */
  163606. + gcmkVERIFY_OK(gckHEAP_Destroy(heap));
  163607. + }
  163608. +
  163609. + /* Destroy the memory lock. */
  163610. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryMapLock));
  163611. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->memoryLock));
  163612. +
  163613. + /* Destroy debug lock mutex. */
  163614. + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, Os->debugLock));
  163615. +
  163616. + /* Wait for all works done. */
  163617. + flush_workqueue(Os->workqueue);
  163618. +
  163619. + /* Destory work queue. */
  163620. + destroy_workqueue(Os->workqueue);
  163621. +
  163622. + /* Flush the debug cache. */
  163623. + gcmkDEBUGFLUSH(~0U);
  163624. +
  163625. + /* Mark the gckOS object as unknown. */
  163626. + Os->object.type = gcvOBJ_UNKNOWN;
  163627. +
  163628. + /* Free the gckOS object. */
  163629. + kfree(Os);
  163630. +
  163631. + /* Success. */
  163632. + gcmkFOOTER_NO();
  163633. + return gcvSTATUS_OK;
  163634. +}
  163635. +
  163636. +static gctSTRING
  163637. +_CreateKernelVirtualMapping(
  163638. + IN PLINUX_MDL Mdl
  163639. + )
  163640. +{
  163641. + gctSTRING addr = 0;
  163642. + gctINT numPages = Mdl->numPages;
  163643. +
  163644. +#if gcdNONPAGED_MEMORY_CACHEABLE
  163645. + if (Mdl->contiguous)
  163646. + {
  163647. + addr = page_address(Mdl->u.contiguousPages);
  163648. + }
  163649. + else
  163650. + {
  163651. + addr = vmap(Mdl->u.nonContiguousPages,
  163652. + numPages,
  163653. + 0,
  163654. + PAGE_KERNEL);
  163655. +
  163656. + /* Trigger a page fault. */
  163657. + memset(addr, 0, numPages * PAGE_SIZE);
  163658. + }
  163659. +#else
  163660. + struct page ** pages;
  163661. + gctBOOL free = gcvFALSE;
  163662. + gctINT i;
  163663. +
  163664. + if (Mdl->contiguous)
  163665. + {
  163666. + pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
  163667. +
  163668. + if (!pages)
  163669. + {
  163670. + return gcvNULL;
  163671. + }
  163672. +
  163673. + for (i = 0; i < numPages; i++)
  163674. + {
  163675. + pages[i] = nth_page(Mdl->u.contiguousPages, i);
  163676. + }
  163677. +
  163678. + free = gcvTRUE;
  163679. + }
  163680. + else
  163681. + {
  163682. + pages = Mdl->u.nonContiguousPages;
  163683. + }
  163684. +
  163685. + /* ioremap() can't work on system memory since 2.6.38. */
  163686. + addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
  163687. +
  163688. + /* Trigger a page fault. */
  163689. + memset(addr, 0, numPages * PAGE_SIZE);
  163690. +
  163691. + if (free)
  163692. + {
  163693. + kfree(pages);
  163694. + }
  163695. +
  163696. +#endif
  163697. +
  163698. + return addr;
  163699. +}
  163700. +
  163701. +static void
  163702. +_DestoryKernelVirtualMapping(
  163703. + IN gctSTRING Addr
  163704. + )
  163705. +{
  163706. +#if !gcdNONPAGED_MEMORY_CACHEABLE
  163707. + vunmap(Addr);
  163708. +#endif
  163709. +}
  163710. +
  163711. +gceSTATUS
  163712. +gckOS_CreateKernelVirtualMapping(
  163713. + IN gctPHYS_ADDR Physical,
  163714. + OUT gctSIZE_T * PageCount,
  163715. + OUT gctPOINTER * Logical
  163716. + )
  163717. +{
  163718. + *PageCount = ((PLINUX_MDL)Physical)->numPages;
  163719. + *Logical = _CreateKernelVirtualMapping((PLINUX_MDL)Physical);
  163720. +
  163721. + return gcvSTATUS_OK;
  163722. +}
  163723. +
  163724. +gceSTATUS
  163725. +gckOS_DestroyKernelVirtualMapping(
  163726. + IN gctPOINTER Logical
  163727. + )
  163728. +{
  163729. + _DestoryKernelVirtualMapping((gctSTRING)Logical);
  163730. + return gcvSTATUS_OK;
  163731. +}
  163732. +
  163733. +/*******************************************************************************
  163734. +**
  163735. +** gckOS_Allocate
  163736. +**
  163737. +** Allocate memory.
  163738. +**
  163739. +** INPUT:
  163740. +**
  163741. +** gckOS Os
  163742. +** Pointer to an gckOS object.
  163743. +**
  163744. +** gctSIZE_T Bytes
  163745. +** Number of bytes to allocate.
  163746. +**
  163747. +** OUTPUT:
  163748. +**
  163749. +** gctPOINTER * Memory
  163750. +** Pointer to a variable that will hold the allocated memory location.
  163751. +*/
  163752. +gceSTATUS
  163753. +gckOS_Allocate(
  163754. + IN gckOS Os,
  163755. + IN gctSIZE_T Bytes,
  163756. + OUT gctPOINTER * Memory
  163757. + )
  163758. +{
  163759. + gceSTATUS status;
  163760. +
  163761. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  163762. +
  163763. + /* Verify the arguments. */
  163764. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163765. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  163766. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  163767. +
  163768. + /* Do we have a heap? */
  163769. + if (Os->heap != gcvNULL)
  163770. + {
  163771. + /* Allocate from the heap. */
  163772. + gcmkONERROR(gckHEAP_Allocate(Os->heap, Bytes, Memory));
  163773. + }
  163774. + else
  163775. + {
  163776. + gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory));
  163777. + }
  163778. +
  163779. + /* Success. */
  163780. + gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
  163781. + return gcvSTATUS_OK;
  163782. +
  163783. +OnError:
  163784. + /* Return the status. */
  163785. + gcmkFOOTER();
  163786. + return status;
  163787. +}
  163788. +
  163789. +/*******************************************************************************
  163790. +**
  163791. +** gckOS_Free
  163792. +**
  163793. +** Free allocated memory.
  163794. +**
  163795. +** INPUT:
  163796. +**
  163797. +** gckOS Os
  163798. +** Pointer to an gckOS object.
  163799. +**
  163800. +** gctPOINTER Memory
  163801. +** Pointer to memory allocation to free.
  163802. +**
  163803. +** OUTPUT:
  163804. +**
  163805. +** Nothing.
  163806. +*/
  163807. +gceSTATUS
  163808. +gckOS_Free(
  163809. + IN gckOS Os,
  163810. + IN gctPOINTER Memory
  163811. + )
  163812. +{
  163813. + gceSTATUS status;
  163814. +
  163815. + gcmkHEADER_ARG("Os=0x%X Memory=0x%X", Os, Memory);
  163816. +
  163817. + /* Verify the arguments. */
  163818. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163819. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  163820. +
  163821. + /* Do we have a heap? */
  163822. + if (Os->heap != gcvNULL)
  163823. + {
  163824. + /* Free from the heap. */
  163825. + gcmkONERROR(gckHEAP_Free(Os->heap, Memory));
  163826. + }
  163827. + else
  163828. + {
  163829. + gcmkONERROR(gckOS_FreeMemory(Os, Memory));
  163830. + }
  163831. +
  163832. + /* Success. */
  163833. + gcmkFOOTER_NO();
  163834. + return gcvSTATUS_OK;
  163835. +
  163836. +OnError:
  163837. + /* Return the status. */
  163838. + gcmkFOOTER();
  163839. + return status;
  163840. +}
  163841. +
  163842. +/*******************************************************************************
  163843. +**
  163844. +** gckOS_AllocateMemory
  163845. +**
  163846. +** Allocate memory wrapper.
  163847. +**
  163848. +** INPUT:
  163849. +**
  163850. +** gctSIZE_T Bytes
  163851. +** Number of bytes to allocate.
  163852. +**
  163853. +** OUTPUT:
  163854. +**
  163855. +** gctPOINTER * Memory
  163856. +** Pointer to a variable that will hold the allocated memory location.
  163857. +*/
  163858. +gceSTATUS
  163859. +gckOS_AllocateMemory(
  163860. + IN gckOS Os,
  163861. + IN gctSIZE_T Bytes,
  163862. + OUT gctPOINTER * Memory
  163863. + )
  163864. +{
  163865. + gctPOINTER memory;
  163866. + gceSTATUS status;
  163867. +
  163868. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  163869. +
  163870. + /* Verify the arguments. */
  163871. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  163872. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  163873. +
  163874. + if (Bytes > PAGE_SIZE)
  163875. + {
  163876. + memory = (gctPOINTER) vmalloc(Bytes);
  163877. + }
  163878. + else
  163879. + {
  163880. + memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL | gcdNOWARN);
  163881. + }
  163882. +
  163883. + if (memory == gcvNULL)
  163884. + {
  163885. + /* Out of memory. */
  163886. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  163887. + }
  163888. +
  163889. + /* Return pointer to the memory allocation. */
  163890. + *Memory = memory;
  163891. +
  163892. + /* Success. */
  163893. + gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
  163894. + return gcvSTATUS_OK;
  163895. +
  163896. +OnError:
  163897. + /* Return the status. */
  163898. + gcmkFOOTER();
  163899. + return status;
  163900. +}
  163901. +
  163902. +/*******************************************************************************
  163903. +**
  163904. +** gckOS_FreeMemory
  163905. +**
  163906. +** Free allocated memory wrapper.
  163907. +**
  163908. +** INPUT:
  163909. +**
  163910. +** gctPOINTER Memory
  163911. +** Pointer to memory allocation to free.
  163912. +**
  163913. +** OUTPUT:
  163914. +**
  163915. +** Nothing.
  163916. +*/
  163917. +gceSTATUS
  163918. +gckOS_FreeMemory(
  163919. + IN gckOS Os,
  163920. + IN gctPOINTER Memory
  163921. + )
  163922. +{
  163923. + gcmkHEADER_ARG("Memory=0x%X", Memory);
  163924. +
  163925. + /* Verify the arguments. */
  163926. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  163927. +
  163928. + /* Free the memory from the OS pool. */
  163929. + if (is_vmalloc_addr(Memory))
  163930. + {
  163931. + vfree(Memory);
  163932. + }
  163933. + else
  163934. + {
  163935. + kfree(Memory);
  163936. + }
  163937. +
  163938. + /* Success. */
  163939. + gcmkFOOTER_NO();
  163940. + return gcvSTATUS_OK;
  163941. +}
  163942. +
  163943. +/*******************************************************************************
  163944. +**
  163945. +** gckOS_MapMemory
  163946. +**
  163947. +** Map physical memory into the current process.
  163948. +**
  163949. +** INPUT:
  163950. +**
  163951. +** gckOS Os
  163952. +** Pointer to an gckOS object.
  163953. +**
  163954. +** gctPHYS_ADDR Physical
  163955. +** Start of physical address memory.
  163956. +**
  163957. +** gctSIZE_T Bytes
  163958. +** Number of bytes to map.
  163959. +**
  163960. +** OUTPUT:
  163961. +**
  163962. +** gctPOINTER * Memory
  163963. +** Pointer to a variable that will hold the logical address of the
  163964. +** mapped memory.
  163965. +*/
  163966. +gceSTATUS
  163967. +gckOS_MapMemory(
  163968. + IN gckOS Os,
  163969. + IN gctPHYS_ADDR Physical,
  163970. + IN gctSIZE_T Bytes,
  163971. + OUT gctPOINTER * Logical
  163972. + )
  163973. +{
  163974. + PLINUX_MDL_MAP mdlMap;
  163975. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  163976. +
  163977. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  163978. +
  163979. + /* Verify the arguments. */
  163980. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  163981. + gcmkVERIFY_ARGUMENT(Physical != 0);
  163982. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  163983. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  163984. +
  163985. + MEMORY_LOCK(Os);
  163986. +
  163987. + mdlMap = FindMdlMap(mdl, _GetProcessID());
  163988. +
  163989. + if (mdlMap == gcvNULL)
  163990. + {
  163991. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  163992. +
  163993. + if (mdlMap == gcvNULL)
  163994. + {
  163995. + MEMORY_UNLOCK(Os);
  163996. +
  163997. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  163998. + return gcvSTATUS_OUT_OF_MEMORY;
  163999. + }
  164000. + }
  164001. +
  164002. + if (mdlMap->vmaAddr == gcvNULL)
  164003. + {
  164004. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  164005. + mdlMap->vmaAddr = (char *)vm_mmap(gcvNULL,
  164006. + 0L,
  164007. + mdl->numPages * PAGE_SIZE,
  164008. + PROT_READ | PROT_WRITE,
  164009. + MAP_SHARED,
  164010. + 0);
  164011. +#else
  164012. + down_write(&current->mm->mmap_sem);
  164013. +
  164014. + mdlMap->vmaAddr = (char *)do_mmap_pgoff(gcvNULL,
  164015. + 0L,
  164016. + mdl->numPages * PAGE_SIZE,
  164017. + PROT_READ | PROT_WRITE,
  164018. + MAP_SHARED,
  164019. + 0);
  164020. +
  164021. + up_write(&current->mm->mmap_sem);
  164022. +#endif
  164023. +
  164024. + if (IS_ERR(mdlMap->vmaAddr))
  164025. + {
  164026. + gcmkTRACE(
  164027. + gcvLEVEL_ERROR,
  164028. + "%s(%d): do_mmap_pgoff error",
  164029. + __FUNCTION__, __LINE__
  164030. + );
  164031. +
  164032. + gcmkTRACE(
  164033. + gcvLEVEL_ERROR,
  164034. + "%s(%d): mdl->numPages: %d mdl->vmaAddr: 0x%X",
  164035. + __FUNCTION__, __LINE__,
  164036. + mdl->numPages,
  164037. + mdlMap->vmaAddr
  164038. + );
  164039. +
  164040. + mdlMap->vmaAddr = gcvNULL;
  164041. +
  164042. + MEMORY_UNLOCK(Os);
  164043. +
  164044. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
  164045. + return gcvSTATUS_OUT_OF_MEMORY;
  164046. + }
  164047. +
  164048. + down_write(&current->mm->mmap_sem);
  164049. +
  164050. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  164051. +
  164052. + if (!mdlMap->vma)
  164053. + {
  164054. + gcmkTRACE(
  164055. + gcvLEVEL_ERROR,
  164056. + "%s(%d): find_vma error.",
  164057. + __FUNCTION__, __LINE__
  164058. + );
  164059. +
  164060. + mdlMap->vmaAddr = gcvNULL;
  164061. +
  164062. + up_write(&current->mm->mmap_sem);
  164063. +
  164064. + MEMORY_UNLOCK(Os);
  164065. +
  164066. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  164067. + return gcvSTATUS_OUT_OF_RESOURCES;
  164068. + }
  164069. +
  164070. +#ifndef NO_DMA_COHERENT
  164071. + if (dma_mmap_coherent(gcvNULL,
  164072. + mdlMap->vma,
  164073. + mdl->addr,
  164074. + mdl->dmaHandle,
  164075. + mdl->numPages * PAGE_SIZE) < 0)
  164076. + {
  164077. + up_write(&current->mm->mmap_sem);
  164078. +
  164079. + gcmkTRACE(
  164080. + gcvLEVEL_ERROR,
  164081. + "%s(%d): dma_mmap_coherent error.",
  164082. + __FUNCTION__, __LINE__
  164083. + );
  164084. +
  164085. + mdlMap->vmaAddr = gcvNULL;
  164086. +
  164087. + MEMORY_UNLOCK(Os);
  164088. +
  164089. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  164090. + return gcvSTATUS_OUT_OF_RESOURCES;
  164091. + }
  164092. +#else
  164093. +#if !gcdPAGED_MEMORY_CACHEABLE
  164094. + mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  164095. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  164096. +# endif
  164097. + mdlMap->vma->vm_pgoff = 0;
  164098. +
  164099. + if (remap_pfn_range(mdlMap->vma,
  164100. + mdlMap->vma->vm_start,
  164101. + mdl->dmaHandle >> PAGE_SHIFT,
  164102. + mdl->numPages*PAGE_SIZE,
  164103. + mdlMap->vma->vm_page_prot) < 0)
  164104. + {
  164105. + up_write(&current->mm->mmap_sem);
  164106. +
  164107. + gcmkTRACE(
  164108. + gcvLEVEL_ERROR,
  164109. + "%s(%d): remap_pfn_range error.",
  164110. + __FUNCTION__, __LINE__
  164111. + );
  164112. +
  164113. + mdlMap->vmaAddr = gcvNULL;
  164114. +
  164115. + MEMORY_UNLOCK(Os);
  164116. +
  164117. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  164118. + return gcvSTATUS_OUT_OF_RESOURCES;
  164119. + }
  164120. +#endif
  164121. +
  164122. + up_write(&current->mm->mmap_sem);
  164123. + }
  164124. +
  164125. + MEMORY_UNLOCK(Os);
  164126. +
  164127. + *Logical = mdlMap->vmaAddr;
  164128. +
  164129. + gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
  164130. + return gcvSTATUS_OK;
  164131. +}
  164132. +
  164133. +/*******************************************************************************
  164134. +**
  164135. +** gckOS_UnmapMemory
  164136. +**
  164137. +** Unmap physical memory out of the current process.
  164138. +**
  164139. +** INPUT:
  164140. +**
  164141. +** gckOS Os
  164142. +** Pointer to an gckOS object.
  164143. +**
  164144. +** gctPHYS_ADDR Physical
  164145. +** Start of physical address memory.
  164146. +**
  164147. +** gctSIZE_T Bytes
  164148. +** Number of bytes to unmap.
  164149. +**
  164150. +** gctPOINTER Memory
  164151. +** Pointer to a previously mapped memory region.
  164152. +**
  164153. +** OUTPUT:
  164154. +**
  164155. +** Nothing.
  164156. +*/
  164157. +gceSTATUS
  164158. +gckOS_UnmapMemory(
  164159. + IN gckOS Os,
  164160. + IN gctPHYS_ADDR Physical,
  164161. + IN gctSIZE_T Bytes,
  164162. + IN gctPOINTER Logical
  164163. + )
  164164. +{
  164165. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
  164166. + Os, Physical, Bytes, Logical);
  164167. +
  164168. + /* Verify the arguments. */
  164169. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164170. + gcmkVERIFY_ARGUMENT(Physical != 0);
  164171. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164172. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164173. +
  164174. + gckOS_UnmapMemoryEx(Os, Physical, Bytes, Logical, _GetProcessID());
  164175. +
  164176. + /* Success. */
  164177. + gcmkFOOTER_NO();
  164178. + return gcvSTATUS_OK;
  164179. +}
  164180. +
  164181. +
  164182. +/*******************************************************************************
  164183. +**
  164184. +** gckOS_UnmapMemoryEx
  164185. +**
  164186. +** Unmap physical memory in the specified process.
  164187. +**
  164188. +** INPUT:
  164189. +**
  164190. +** gckOS Os
  164191. +** Pointer to an gckOS object.
  164192. +**
  164193. +** gctPHYS_ADDR Physical
  164194. +** Start of physical address memory.
  164195. +**
  164196. +** gctSIZE_T Bytes
  164197. +** Number of bytes to unmap.
  164198. +**
  164199. +** gctPOINTER Memory
  164200. +** Pointer to a previously mapped memory region.
  164201. +**
  164202. +** gctUINT32 PID
  164203. +** Pid of the process that opened the device and mapped this memory.
  164204. +**
  164205. +** OUTPUT:
  164206. +**
  164207. +** Nothing.
  164208. +*/
  164209. +gceSTATUS
  164210. +gckOS_UnmapMemoryEx(
  164211. + IN gckOS Os,
  164212. + IN gctPHYS_ADDR Physical,
  164213. + IN gctSIZE_T Bytes,
  164214. + IN gctPOINTER Logical,
  164215. + IN gctUINT32 PID
  164216. + )
  164217. +{
  164218. + PLINUX_MDL_MAP mdlMap;
  164219. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  164220. +
  164221. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X PID=%d",
  164222. + Os, Physical, Bytes, Logical, PID);
  164223. +
  164224. + /* Verify the arguments. */
  164225. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164226. + gcmkVERIFY_ARGUMENT(Physical != 0);
  164227. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164228. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164229. + gcmkVERIFY_ARGUMENT(PID != 0);
  164230. +
  164231. + MEMORY_LOCK(Os);
  164232. +
  164233. + if (Logical)
  164234. + {
  164235. + mdlMap = FindMdlMap(mdl, PID);
  164236. +
  164237. + if (mdlMap == gcvNULL || mdlMap->vmaAddr == gcvNULL)
  164238. + {
  164239. + MEMORY_UNLOCK(Os);
  164240. +
  164241. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  164242. + return gcvSTATUS_INVALID_ARGUMENT;
  164243. + }
  164244. +
  164245. + _UnmapUserLogical(PID, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
  164246. +
  164247. + gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
  164248. + }
  164249. +
  164250. + MEMORY_UNLOCK(Os);
  164251. +
  164252. + /* Success. */
  164253. + gcmkFOOTER_NO();
  164254. + return gcvSTATUS_OK;
  164255. +}
  164256. +
  164257. +/*******************************************************************************
  164258. +**
  164259. +** gckOS_UnmapUserLogical
  164260. +**
  164261. +** Unmap user logical memory out of physical memory.
  164262. +**
  164263. +** INPUT:
  164264. +**
  164265. +** gckOS Os
  164266. +** Pointer to an gckOS object.
  164267. +**
  164268. +** gctPHYS_ADDR Physical
  164269. +** Start of physical address memory.
  164270. +**
  164271. +** gctSIZE_T Bytes
  164272. +** Number of bytes to unmap.
  164273. +**
  164274. +** gctPOINTER Memory
  164275. +** Pointer to a previously mapped memory region.
  164276. +**
  164277. +** OUTPUT:
  164278. +**
  164279. +** Nothing.
  164280. +*/
  164281. +gceSTATUS
  164282. +gckOS_UnmapUserLogical(
  164283. + IN gckOS Os,
  164284. + IN gctPHYS_ADDR Physical,
  164285. + IN gctSIZE_T Bytes,
  164286. + IN gctPOINTER Logical
  164287. + )
  164288. +{
  164289. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
  164290. + Os, Physical, Bytes, Logical);
  164291. +
  164292. + /* Verify the arguments. */
  164293. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164294. + gcmkVERIFY_ARGUMENT(Physical != 0);
  164295. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164296. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164297. +
  164298. + gckOS_UnmapMemory(Os, Physical, Bytes, Logical);
  164299. +
  164300. + /* Success. */
  164301. + gcmkFOOTER_NO();
  164302. + return gcvSTATUS_OK;
  164303. +
  164304. +}
  164305. +
  164306. +/*******************************************************************************
  164307. +**
  164308. +** gckOS_AllocateNonPagedMemory
  164309. +**
  164310. +** Allocate a number of pages from non-paged memory.
  164311. +**
  164312. +** INPUT:
  164313. +**
  164314. +** gckOS Os
  164315. +** Pointer to an gckOS object.
  164316. +**
  164317. +** gctBOOL InUserSpace
  164318. +** gcvTRUE if the pages need to be mapped into user space.
  164319. +**
  164320. +** gctSIZE_T * Bytes
  164321. +** Pointer to a variable that holds the number of bytes to allocate.
  164322. +**
  164323. +** OUTPUT:
  164324. +**
  164325. +** gctSIZE_T * Bytes
  164326. +** Pointer to a variable that hold the number of bytes allocated.
  164327. +**
  164328. +** gctPHYS_ADDR * Physical
  164329. +** Pointer to a variable that will hold the physical address of the
  164330. +** allocation.
  164331. +**
  164332. +** gctPOINTER * Logical
  164333. +** Pointer to a variable that will hold the logical address of the
  164334. +** allocation.
  164335. +*/
  164336. +gceSTATUS
  164337. +gckOS_AllocateNonPagedMemory(
  164338. + IN gckOS Os,
  164339. + IN gctBOOL InUserSpace,
  164340. + IN OUT gctSIZE_T * Bytes,
  164341. + OUT gctPHYS_ADDR * Physical,
  164342. + OUT gctPOINTER * Logical
  164343. + )
  164344. +{
  164345. + gctSIZE_T bytes;
  164346. + gctINT numPages;
  164347. + PLINUX_MDL mdl = gcvNULL;
  164348. + PLINUX_MDL_MAP mdlMap = gcvNULL;
  164349. + gctSTRING addr;
  164350. +#ifdef NO_DMA_COHERENT
  164351. + struct page * page;
  164352. + long size, order;
  164353. + gctPOINTER vaddr;
  164354. +#endif
  164355. + gctBOOL locked = gcvFALSE;
  164356. + gceSTATUS status;
  164357. +
  164358. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  164359. + Os, InUserSpace, gcmOPT_VALUE(Bytes));
  164360. +
  164361. + /* Verify the arguments. */
  164362. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164363. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  164364. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  164365. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  164366. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164367. +
  164368. + /* Align number of bytes to page size. */
  164369. + bytes = gcmALIGN(*Bytes, PAGE_SIZE);
  164370. +
  164371. + /* Get total number of pages.. */
  164372. + numPages = GetPageCount(bytes, 0);
  164373. +
  164374. + /* Allocate mdl+vector structure */
  164375. + mdl = _CreateMdl(_GetProcessID());
  164376. + if (mdl == gcvNULL)
  164377. + {
  164378. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164379. + }
  164380. +
  164381. + mdl->pagedMem = 0;
  164382. + mdl->numPages = numPages;
  164383. +
  164384. + MEMORY_LOCK(Os);
  164385. + locked = gcvTRUE;
  164386. +
  164387. +#ifndef NO_DMA_COHERENT
  164388. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  164389. + addr = _GetNonPagedMemoryCache(Os,
  164390. + mdl->numPages * PAGE_SIZE,
  164391. + &mdl->dmaHandle);
  164392. +
  164393. + if (addr == gcvNULL)
  164394. +#endif
  164395. + {
  164396. + addr = dma_alloc_coherent(gcvNULL,
  164397. + mdl->numPages * PAGE_SIZE,
  164398. + &mdl->dmaHandle,
  164399. + GFP_KERNEL | gcdNOWARN);
  164400. + }
  164401. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  164402. + if(addr == gcvNULL)
  164403. + {
  164404. + MEMORY_UNLOCK(Os);
  164405. + locked = gcvFALSE;
  164406. + /*Free all cache and try again*/
  164407. + _FreeAllNonPagedMemoryCache(Os);
  164408. + MEMORY_LOCK(Os);
  164409. + locked = gcvTRUE;
  164410. + addr = dma_alloc_coherent(gcvNULL,
  164411. + mdl->numPages * PAGE_SIZE,
  164412. + &mdl->dmaHandle,
  164413. + GFP_KERNEL | gcdNOWARN);
  164414. + }
  164415. +#endif
  164416. +#else
  164417. + size = mdl->numPages * PAGE_SIZE;
  164418. + order = get_order(size);
  164419. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  164420. + page = _GetNonPagedMemoryCache(Os, order);
  164421. +
  164422. + if (page == gcvNULL)
  164423. +#endif
  164424. + {
  164425. + page = alloc_pages(GFP_KERNEL | gcdNOWARN, order);
  164426. + }
  164427. +
  164428. + if (page == gcvNULL)
  164429. + {
  164430. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164431. + }
  164432. +
  164433. + vaddr = (gctPOINTER)page_address(page);
  164434. + mdl->contiguous = gcvTRUE;
  164435. + mdl->u.contiguousPages = page;
  164436. + addr = _CreateKernelVirtualMapping(mdl);
  164437. + mdl->dmaHandle = virt_to_phys(vaddr);
  164438. + mdl->kaddr = vaddr;
  164439. + mdl->u.contiguousPages = page;
  164440. +
  164441. +#if !defined(CONFIG_PPC)
  164442. + /* Cache invalidate. */
  164443. + dma_sync_single_for_device(
  164444. + gcvNULL,
  164445. + page_to_phys(page),
  164446. + bytes,
  164447. + DMA_FROM_DEVICE);
  164448. +#endif
  164449. +
  164450. + while (size > 0)
  164451. + {
  164452. + SetPageReserved(virt_to_page(vaddr));
  164453. +
  164454. + vaddr += PAGE_SIZE;
  164455. + size -= PAGE_SIZE;
  164456. + }
  164457. +#endif
  164458. +
  164459. + if (addr == gcvNULL)
  164460. + {
  164461. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164462. + }
  164463. +
  164464. + mdl->addr = addr;
  164465. +
  164466. + /* Return allocated memory. */
  164467. + *Bytes = bytes;
  164468. + *Physical = (gctPHYS_ADDR) mdl;
  164469. +
  164470. + if (InUserSpace)
  164471. + {
  164472. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  164473. +
  164474. + if (mdlMap == gcvNULL)
  164475. + {
  164476. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164477. + }
  164478. +
  164479. + /* Only after mmap this will be valid. */
  164480. +
  164481. + /* We need to map this to user space. */
  164482. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  164483. + mdlMap->vmaAddr = (gctSTRING) vm_mmap(gcvNULL,
  164484. + 0L,
  164485. + mdl->numPages * PAGE_SIZE,
  164486. + PROT_READ | PROT_WRITE,
  164487. + MAP_SHARED,
  164488. + 0);
  164489. +#else
  164490. + down_write(&current->mm->mmap_sem);
  164491. +
  164492. + mdlMap->vmaAddr = (gctSTRING) do_mmap_pgoff(gcvNULL,
  164493. + 0L,
  164494. + mdl->numPages * PAGE_SIZE,
  164495. + PROT_READ | PROT_WRITE,
  164496. + MAP_SHARED,
  164497. + 0);
  164498. +
  164499. + up_write(&current->mm->mmap_sem);
  164500. +#endif
  164501. +
  164502. + if (IS_ERR(mdlMap->vmaAddr))
  164503. + {
  164504. + gcmkTRACE_ZONE(
  164505. + gcvLEVEL_WARNING, gcvZONE_OS,
  164506. + "%s(%d): do_mmap_pgoff error",
  164507. + __FUNCTION__, __LINE__
  164508. + );
  164509. +
  164510. + mdlMap->vmaAddr = gcvNULL;
  164511. +
  164512. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  164513. + }
  164514. +
  164515. + down_write(&current->mm->mmap_sem);
  164516. +
  164517. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  164518. +
  164519. + if (mdlMap->vma == gcvNULL)
  164520. + {
  164521. + gcmkTRACE_ZONE(
  164522. + gcvLEVEL_WARNING, gcvZONE_OS,
  164523. + "%s(%d): find_vma error",
  164524. + __FUNCTION__, __LINE__
  164525. + );
  164526. +
  164527. + up_write(&current->mm->mmap_sem);
  164528. +
  164529. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  164530. + }
  164531. +
  164532. +#ifndef NO_DMA_COHERENT
  164533. + if (dma_mmap_coherent(gcvNULL,
  164534. + mdlMap->vma,
  164535. + mdl->addr,
  164536. + mdl->dmaHandle,
  164537. + mdl->numPages * PAGE_SIZE) < 0)
  164538. + {
  164539. + gcmkTRACE_ZONE(
  164540. + gcvLEVEL_WARNING, gcvZONE_OS,
  164541. + "%s(%d): dma_mmap_coherent error",
  164542. + __FUNCTION__, __LINE__
  164543. + );
  164544. +
  164545. + up_write(&current->mm->mmap_sem);
  164546. +
  164547. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  164548. + }
  164549. +#else
  164550. + mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  164551. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  164552. + mdlMap->vma->vm_pgoff = 0;
  164553. +
  164554. + if (remap_pfn_range(mdlMap->vma,
  164555. + mdlMap->vma->vm_start,
  164556. + mdl->dmaHandle >> PAGE_SHIFT,
  164557. + mdl->numPages * PAGE_SIZE,
  164558. + mdlMap->vma->vm_page_prot))
  164559. + {
  164560. + gcmkTRACE_ZONE(
  164561. + gcvLEVEL_WARNING, gcvZONE_OS,
  164562. + "%s(%d): remap_pfn_range error",
  164563. + __FUNCTION__, __LINE__
  164564. + );
  164565. +
  164566. + up_write(&current->mm->mmap_sem);
  164567. +
  164568. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  164569. + }
  164570. +#endif /* NO_DMA_COHERENT */
  164571. +
  164572. + up_write(&current->mm->mmap_sem);
  164573. +
  164574. + *Logical = mdlMap->vmaAddr;
  164575. + }
  164576. + else
  164577. + {
  164578. + *Logical = (gctPOINTER)mdl->addr;
  164579. + }
  164580. +
  164581. + /*
  164582. + * Add this to a global list.
  164583. + * Will be used by get physical address
  164584. + * and mapuser pointer functions.
  164585. + */
  164586. +
  164587. + if (!Os->mdlHead)
  164588. + {
  164589. + /* Initialize the queue. */
  164590. + Os->mdlHead = Os->mdlTail = mdl;
  164591. + }
  164592. + else
  164593. + {
  164594. + /* Add to the tail. */
  164595. + mdl->prev = Os->mdlTail;
  164596. + Os->mdlTail->next = mdl;
  164597. + Os->mdlTail = mdl;
  164598. + }
  164599. +
  164600. + MEMORY_UNLOCK(Os);
  164601. +
  164602. + /* Success. */
  164603. + gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
  164604. + *Bytes, *Physical, *Logical);
  164605. + return gcvSTATUS_OK;
  164606. +
  164607. +OnError:
  164608. + if (mdlMap != gcvNULL)
  164609. + {
  164610. + /* Free LINUX_MDL_MAP. */
  164611. + gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
  164612. + }
  164613. +
  164614. + if (mdl != gcvNULL)
  164615. + {
  164616. + /* Free LINUX_MDL. */
  164617. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  164618. + }
  164619. +
  164620. + if (locked)
  164621. + {
  164622. + /* Unlock memory. */
  164623. + MEMORY_UNLOCK(Os);
  164624. + }
  164625. +
  164626. + /* Return the status. */
  164627. + gcmkFOOTER();
  164628. + return status;
  164629. +}
  164630. +
  164631. +/*******************************************************************************
  164632. +**
  164633. +** gckOS_FreeNonPagedMemory
  164634. +**
  164635. +** Free previously allocated and mapped pages from non-paged memory.
  164636. +**
  164637. +** INPUT:
  164638. +**
  164639. +** gckOS Os
  164640. +** Pointer to an gckOS object.
  164641. +**
  164642. +** gctSIZE_T Bytes
  164643. +** Number of bytes allocated.
  164644. +**
  164645. +** gctPHYS_ADDR Physical
  164646. +** Physical address of the allocated memory.
  164647. +**
  164648. +** gctPOINTER Logical
  164649. +** Logical address of the allocated memory.
  164650. +**
  164651. +** OUTPUT:
  164652. +**
  164653. +** Nothing.
  164654. +*/
  164655. +gceSTATUS gckOS_FreeNonPagedMemory(
  164656. + IN gckOS Os,
  164657. + IN gctSIZE_T Bytes,
  164658. + IN gctPHYS_ADDR Physical,
  164659. + IN gctPOINTER Logical
  164660. + )
  164661. +{
  164662. + PLINUX_MDL mdl;
  164663. + PLINUX_MDL_MAP mdlMap;
  164664. +#ifdef NO_DMA_COHERENT
  164665. + unsigned size;
  164666. + gctPOINTER vaddr;
  164667. +#endif /* NO_DMA_COHERENT */
  164668. +
  164669. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu Physical=0x%X Logical=0x%X",
  164670. + Os, Bytes, Physical, Logical);
  164671. +
  164672. + /* Verify the arguments. */
  164673. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164674. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  164675. + gcmkVERIFY_ARGUMENT(Physical != 0);
  164676. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  164677. +
  164678. + /* Convert physical address into a pointer to a MDL. */
  164679. + mdl = (PLINUX_MDL) Physical;
  164680. +
  164681. + MEMORY_LOCK(Os);
  164682. +
  164683. +#ifndef NO_DMA_COHERENT
  164684. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  164685. + if (!_AddNonPagedMemoryCache(Os,
  164686. + mdl->numPages * PAGE_SIZE,
  164687. + mdl->addr,
  164688. + mdl->dmaHandle))
  164689. +#endif
  164690. + {
  164691. + dma_free_coherent(gcvNULL,
  164692. + mdl->numPages * PAGE_SIZE,
  164693. + mdl->addr,
  164694. + mdl->dmaHandle);
  164695. + }
  164696. +#else
  164697. + size = mdl->numPages * PAGE_SIZE;
  164698. + vaddr = mdl->kaddr;
  164699. +
  164700. + while (size > 0)
  164701. + {
  164702. + ClearPageReserved(virt_to_page(vaddr));
  164703. +
  164704. + vaddr += PAGE_SIZE;
  164705. + size -= PAGE_SIZE;
  164706. + }
  164707. +
  164708. +#if gcdUSE_NON_PAGED_MEMORY_CACHE
  164709. + if (!_AddNonPagedMemoryCache(Os,
  164710. + get_order(mdl->numPages * PAGE_SIZE),
  164711. + virt_to_page(mdl->kaddr)))
  164712. +#endif
  164713. + {
  164714. + free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE));
  164715. + }
  164716. +
  164717. + _DestoryKernelVirtualMapping(mdl->addr);
  164718. +#endif /* NO_DMA_COHERENT */
  164719. +
  164720. + mdlMap = mdl->maps;
  164721. +
  164722. + while (mdlMap != gcvNULL)
  164723. + {
  164724. + if (mdlMap->vmaAddr != gcvNULL)
  164725. + {
  164726. + /* No mapped memory exists when free nonpaged memory */
  164727. + gcmkASSERT(0);
  164728. + }
  164729. +
  164730. + mdlMap = mdlMap->next;
  164731. + }
  164732. +
  164733. + /* Remove the node from global list.. */
  164734. + if (mdl == Os->mdlHead)
  164735. + {
  164736. + if ((Os->mdlHead = mdl->next) == gcvNULL)
  164737. + {
  164738. + Os->mdlTail = gcvNULL;
  164739. + }
  164740. + }
  164741. + else
  164742. + {
  164743. + mdl->prev->next = mdl->next;
  164744. + if (mdl == Os->mdlTail)
  164745. + {
  164746. + Os->mdlTail = mdl->prev;
  164747. + }
  164748. + else
  164749. + {
  164750. + mdl->next->prev = mdl->prev;
  164751. + }
  164752. + }
  164753. +
  164754. + MEMORY_UNLOCK(Os);
  164755. +
  164756. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  164757. +
  164758. + /* Success. */
  164759. + gcmkFOOTER_NO();
  164760. + return gcvSTATUS_OK;
  164761. +}
  164762. +
  164763. +/*******************************************************************************
  164764. +**
  164765. +** gckOS_ReadRegister
  164766. +**
  164767. +** Read data from a register.
  164768. +**
  164769. +** INPUT:
  164770. +**
  164771. +** gckOS Os
  164772. +** Pointer to an gckOS object.
  164773. +**
  164774. +** gctUINT32 Address
  164775. +** Address of register.
  164776. +**
  164777. +** OUTPUT:
  164778. +**
  164779. +** gctUINT32 * Data
  164780. +** Pointer to a variable that receives the data read from the register.
  164781. +*/
  164782. +gceSTATUS
  164783. +gckOS_ReadRegister(
  164784. + IN gckOS Os,
  164785. + IN gctUINT32 Address,
  164786. + OUT gctUINT32 * Data
  164787. + )
  164788. +{
  164789. + return gckOS_ReadRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
  164790. +}
  164791. +
  164792. +gceSTATUS
  164793. +gckOS_ReadRegisterEx(
  164794. + IN gckOS Os,
  164795. + IN gceCORE Core,
  164796. + IN gctUINT32 Address,
  164797. + OUT gctUINT32 * Data
  164798. + )
  164799. +{
  164800. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X", Os, Core, Address);
  164801. +
  164802. + /* Verify the arguments. */
  164803. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164804. + gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
  164805. + gcmkVERIFY_ARGUMENT(Data != gcvNULL);
  164806. +
  164807. + *Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
  164808. +
  164809. + /* Success. */
  164810. + gcmkFOOTER_ARG("*Data=0x%08x", *Data);
  164811. + return gcvSTATUS_OK;
  164812. +}
  164813. +
  164814. +/*******************************************************************************
  164815. +**
  164816. +** gckOS_WriteRegister
  164817. +**
  164818. +** Write data to a register.
  164819. +**
  164820. +** INPUT:
  164821. +**
  164822. +** gckOS Os
  164823. +** Pointer to an gckOS object.
  164824. +**
  164825. +** gctUINT32 Address
  164826. +** Address of register.
  164827. +**
  164828. +** gctUINT32 Data
  164829. +** Data for register.
  164830. +**
  164831. +** OUTPUT:
  164832. +**
  164833. +** Nothing.
  164834. +*/
  164835. +gceSTATUS
  164836. +gckOS_WriteRegister(
  164837. + IN gckOS Os,
  164838. + IN gctUINT32 Address,
  164839. + IN gctUINT32 Data
  164840. + )
  164841. +{
  164842. + return gckOS_WriteRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
  164843. +}
  164844. +
  164845. +gceSTATUS
  164846. +gckOS_WriteRegisterEx(
  164847. + IN gckOS Os,
  164848. + IN gceCORE Core,
  164849. + IN gctUINT32 Address,
  164850. + IN gctUINT32 Data
  164851. + )
  164852. +{
  164853. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%X Data=0x%08x", Os, Core, Address, Data);
  164854. +
  164855. + gcmkVERIFY_ARGUMENT(Address < Os->device->requestedRegisterMemSizes[Core]);
  164856. +
  164857. + writel(Data, (gctUINT8 *)Os->device->registerBases[Core] + Address);
  164858. +
  164859. + /* Success. */
  164860. + gcmkFOOTER_NO();
  164861. + return gcvSTATUS_OK;
  164862. +}
  164863. +
  164864. +/*******************************************************************************
  164865. +**
  164866. +** gckOS_GetPageSize
  164867. +**
  164868. +** Get the system's page size.
  164869. +**
  164870. +** INPUT:
  164871. +**
  164872. +** gckOS Os
  164873. +** Pointer to an gckOS object.
  164874. +**
  164875. +** OUTPUT:
  164876. +**
  164877. +** gctSIZE_T * PageSize
  164878. +** Pointer to a variable that will receive the system's page size.
  164879. +*/
  164880. +gceSTATUS gckOS_GetPageSize(
  164881. + IN gckOS Os,
  164882. + OUT gctSIZE_T * PageSize
  164883. + )
  164884. +{
  164885. + gcmkHEADER_ARG("Os=0x%X", Os);
  164886. +
  164887. + /* Verify the arguments. */
  164888. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164889. + gcmkVERIFY_ARGUMENT(PageSize != gcvNULL);
  164890. +
  164891. + /* Return the page size. */
  164892. + *PageSize = (gctSIZE_T) PAGE_SIZE;
  164893. +
  164894. + /* Success. */
  164895. + gcmkFOOTER_ARG("*PageSize", *PageSize);
  164896. + return gcvSTATUS_OK;
  164897. +}
  164898. +
  164899. +/*******************************************************************************
  164900. +**
  164901. +** gckOS_GetPhysicalAddress
  164902. +**
  164903. +** Get the physical system address of a corresponding virtual address.
  164904. +**
  164905. +** INPUT:
  164906. +**
  164907. +** gckOS Os
  164908. +** Pointer to an gckOS object.
  164909. +**
  164910. +** gctPOINTER Logical
  164911. +** Logical address.
  164912. +**
  164913. +** OUTPUT:
  164914. +**
  164915. +** gctUINT32 * Address
  164916. +** Poinetr to a variable that receives the 32-bit physical adress.
  164917. +*/
  164918. +gceSTATUS
  164919. +gckOS_GetPhysicalAddress(
  164920. + IN gckOS Os,
  164921. + IN gctPOINTER Logical,
  164922. + OUT gctUINT32 * Address
  164923. + )
  164924. +{
  164925. + gceSTATUS status;
  164926. + gctUINT32 processID;
  164927. +
  164928. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X", Os, Logical);
  164929. +
  164930. + /* Verify the arguments. */
  164931. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  164932. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  164933. +
  164934. + /* Query page table of current process first. */
  164935. + status = _QueryProcessPageTable(Logical, Address);
  164936. +
  164937. + if (gcmIS_ERROR(status))
  164938. + {
  164939. + /* Get current process ID. */
  164940. + processID = _GetProcessID();
  164941. +
  164942. + /* Route through other function. */
  164943. + gcmkONERROR(
  164944. + gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
  164945. + }
  164946. +
  164947. + /* Success. */
  164948. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  164949. + return gcvSTATUS_OK;
  164950. +
  164951. +OnError:
  164952. + /* Return the status. */
  164953. + gcmkFOOTER();
  164954. + return status;
  164955. +}
  164956. +
  164957. +#if gcdSECURE_USER
  164958. +static gceSTATUS
  164959. +gckOS_AddMapping(
  164960. + IN gckOS Os,
  164961. + IN gctUINT32 Physical,
  164962. + IN gctPOINTER Logical,
  164963. + IN gctSIZE_T Bytes
  164964. + )
  164965. +{
  164966. + gceSTATUS status;
  164967. + gcsUSER_MAPPING_PTR map;
  164968. +
  164969. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
  164970. + Os, Physical, Logical, Bytes);
  164971. +
  164972. + gcmkONERROR(gckOS_Allocate(Os,
  164973. + gcmSIZEOF(gcsUSER_MAPPING),
  164974. + (gctPOINTER *) &map));
  164975. +
  164976. + map->next = Os->userMap;
  164977. + map->physical = Physical - Os->device->baseAddress;
  164978. + map->logical = Logical;
  164979. + map->bytes = Bytes;
  164980. + map->start = (gctINT8_PTR) Logical;
  164981. + map->end = map->start + Bytes;
  164982. +
  164983. + Os->userMap = map;
  164984. +
  164985. + gcmkFOOTER_NO();
  164986. + return gcvSTATUS_OK;
  164987. +
  164988. +OnError:
  164989. + gcmkFOOTER();
  164990. + return status;
  164991. +}
  164992. +
  164993. +static gceSTATUS
  164994. +gckOS_RemoveMapping(
  164995. + IN gckOS Os,
  164996. + IN gctPOINTER Logical,
  164997. + IN gctSIZE_T Bytes
  164998. + )
  164999. +{
  165000. + gceSTATUS status;
  165001. + gcsUSER_MAPPING_PTR map, prev;
  165002. +
  165003. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
  165004. +
  165005. + for (map = Os->userMap, prev = gcvNULL; map != gcvNULL; map = map->next)
  165006. + {
  165007. + if ((map->logical == Logical)
  165008. + && (map->bytes == Bytes)
  165009. + )
  165010. + {
  165011. + break;
  165012. + }
  165013. +
  165014. + prev = map;
  165015. + }
  165016. +
  165017. + if (map == gcvNULL)
  165018. + {
  165019. + gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
  165020. + }
  165021. +
  165022. + if (prev == gcvNULL)
  165023. + {
  165024. + Os->userMap = map->next;
  165025. + }
  165026. + else
  165027. + {
  165028. + prev->next = map->next;
  165029. + }
  165030. +
  165031. + gcmkONERROR(gcmkOS_SAFE_FREE(Os, map));
  165032. +
  165033. + gcmkFOOTER_NO();
  165034. + return gcvSTATUS_OK;
  165035. +
  165036. +OnError:
  165037. + gcmkFOOTER();
  165038. + return status;
  165039. +}
  165040. +#endif
  165041. +
  165042. +static gceSTATUS
  165043. +_ConvertLogical2Physical(
  165044. + IN gckOS Os,
  165045. + IN gctPOINTER Logical,
  165046. + IN gctUINT32 ProcessID,
  165047. + IN PLINUX_MDL Mdl,
  165048. + OUT gctUINT32_PTR Physical
  165049. + )
  165050. +{
  165051. + gctINT8_PTR base, vBase;
  165052. + gctUINT32 offset;
  165053. + PLINUX_MDL_MAP map;
  165054. + gcsUSER_MAPPING_PTR userMap;
  165055. +
  165056. + base = (Mdl == gcvNULL) ? gcvNULL : (gctINT8_PTR) Mdl->addr;
  165057. +
  165058. + /* Check for the logical address match. */
  165059. + if ((base != gcvNULL)
  165060. + && ((gctINT8_PTR) Logical >= base)
  165061. + && ((gctINT8_PTR) Logical < base + Mdl->numPages * PAGE_SIZE)
  165062. + )
  165063. + {
  165064. + offset = (gctINT8_PTR) Logical - base;
  165065. +
  165066. + if (Mdl->dmaHandle != 0)
  165067. + {
  165068. + /* The memory was from coherent area. */
  165069. + *Physical = (gctUINT32) Mdl->dmaHandle + offset;
  165070. + }
  165071. + else if (Mdl->pagedMem && !Mdl->contiguous)
  165072. + {
  165073. + /* paged memory is not mapped to kernel space. */
  165074. + return gcvSTATUS_INVALID_ADDRESS;
  165075. + }
  165076. + else
  165077. + {
  165078. + *Physical = gcmPTR2INT(virt_to_phys(base)) + offset;
  165079. + }
  165080. +
  165081. + return gcvSTATUS_OK;
  165082. + }
  165083. +
  165084. + /* Walk user maps. */
  165085. + for (userMap = Os->userMap; userMap != gcvNULL; userMap = userMap->next)
  165086. + {
  165087. + if (((gctINT8_PTR) Logical >= userMap->start)
  165088. + && ((gctINT8_PTR) Logical < userMap->end)
  165089. + )
  165090. + {
  165091. + *Physical = userMap->physical
  165092. + + (gctUINT32) ((gctINT8_PTR) Logical - userMap->start);
  165093. +
  165094. + return gcvSTATUS_OK;
  165095. + }
  165096. + }
  165097. +
  165098. + if (ProcessID != Os->kernelProcessID)
  165099. + {
  165100. + map = FindMdlMap(Mdl, (gctINT) ProcessID);
  165101. + vBase = (map == gcvNULL) ? gcvNULL : (gctINT8_PTR) map->vmaAddr;
  165102. +
  165103. + /* Is the given address within that range. */
  165104. + if ((vBase != gcvNULL)
  165105. + && ((gctINT8_PTR) Logical >= vBase)
  165106. + && ((gctINT8_PTR) Logical < vBase + Mdl->numPages * PAGE_SIZE)
  165107. + )
  165108. + {
  165109. + offset = (gctINT8_PTR) Logical - vBase;
  165110. +
  165111. + if (Mdl->dmaHandle != 0)
  165112. + {
  165113. + /* The memory was from coherent area. */
  165114. + *Physical = (gctUINT32) Mdl->dmaHandle + offset;
  165115. + }
  165116. + else if (Mdl->pagedMem && !Mdl->contiguous)
  165117. + {
  165118. + *Physical = _NonContiguousToPhys(Mdl->u.nonContiguousPages, offset/PAGE_SIZE);
  165119. + }
  165120. + else
  165121. + {
  165122. + *Physical = page_to_phys(Mdl->u.contiguousPages) + offset;
  165123. + }
  165124. +
  165125. + return gcvSTATUS_OK;
  165126. + }
  165127. + }
  165128. +
  165129. + /* Address not yet found. */
  165130. + return gcvSTATUS_INVALID_ADDRESS;
  165131. +}
  165132. +
  165133. +/*******************************************************************************
  165134. +**
  165135. +** gckOS_GetPhysicalAddressProcess
  165136. +**
  165137. +** Get the physical system address of a corresponding virtual address for a
  165138. +** given process.
  165139. +**
  165140. +** INPUT:
  165141. +**
  165142. +** gckOS Os
  165143. +** Pointer to gckOS object.
  165144. +**
  165145. +** gctPOINTER Logical
  165146. +** Logical address.
  165147. +**
  165148. +** gctUINT32 ProcessID
  165149. +** Process ID.
  165150. +**
  165151. +** OUTPUT:
  165152. +**
  165153. +** gctUINT32 * Address
  165154. +** Poinetr to a variable that receives the 32-bit physical adress.
  165155. +*/
  165156. +gceSTATUS
  165157. +gckOS_GetPhysicalAddressProcess(
  165158. + IN gckOS Os,
  165159. + IN gctPOINTER Logical,
  165160. + IN gctUINT32 ProcessID,
  165161. + OUT gctUINT32 * Address
  165162. + )
  165163. +{
  165164. + PLINUX_MDL mdl;
  165165. + gctINT8_PTR base;
  165166. + gceSTATUS status = gcvSTATUS_INVALID_ADDRESS;
  165167. +
  165168. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X ProcessID=%d", Os, Logical, ProcessID);
  165169. +
  165170. + /* Verify the arguments. */
  165171. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165172. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  165173. +
  165174. + MEMORY_LOCK(Os);
  165175. +
  165176. + /* First try the contiguous memory pool. */
  165177. + if (Os->device->contiguousMapped)
  165178. + {
  165179. + base = (gctINT8_PTR) Os->device->contiguousBase;
  165180. +
  165181. + if (((gctINT8_PTR) Logical >= base)
  165182. + && ((gctINT8_PTR) Logical < base + Os->device->contiguousSize)
  165183. + )
  165184. + {
  165185. + /* Convert logical address into physical. */
  165186. + *Address = Os->device->contiguousVidMem->baseAddress
  165187. + + (gctINT8_PTR) Logical - base;
  165188. + status = gcvSTATUS_OK;
  165189. + }
  165190. + }
  165191. + else
  165192. + {
  165193. + /* Try the contiguous memory pool. */
  165194. + mdl = (PLINUX_MDL) Os->device->contiguousPhysical;
  165195. + status = _ConvertLogical2Physical(Os,
  165196. + Logical,
  165197. + ProcessID,
  165198. + mdl,
  165199. + Address);
  165200. + }
  165201. +
  165202. + if (gcmIS_ERROR(status))
  165203. + {
  165204. + /* Walk all MDLs. */
  165205. + for (mdl = Os->mdlHead; mdl != gcvNULL; mdl = mdl->next)
  165206. + {
  165207. + /* Try this MDL. */
  165208. + status = _ConvertLogical2Physical(Os,
  165209. + Logical,
  165210. + ProcessID,
  165211. + mdl,
  165212. + Address);
  165213. + if (gcmIS_SUCCESS(status))
  165214. + {
  165215. + break;
  165216. + }
  165217. + }
  165218. + }
  165219. +
  165220. + MEMORY_UNLOCK(Os);
  165221. +
  165222. + gcmkONERROR(status);
  165223. +
  165224. + /* Success. */
  165225. + gcmkFOOTER_ARG("*Address=0x%08x", *Address);
  165226. + return gcvSTATUS_OK;
  165227. +
  165228. +OnError:
  165229. + /* Return the status. */
  165230. + gcmkFOOTER();
  165231. + return status;
  165232. +}
  165233. +
  165234. +/*******************************************************************************
  165235. +**
  165236. +** gckOS_MapPhysical
  165237. +**
  165238. +** Map a physical address into kernel space.
  165239. +**
  165240. +** INPUT:
  165241. +**
  165242. +** gckOS Os
  165243. +** Pointer to an gckOS object.
  165244. +**
  165245. +** gctUINT32 Physical
  165246. +** Physical address of the memory to map.
  165247. +**
  165248. +** gctSIZE_T Bytes
  165249. +** Number of bytes to map.
  165250. +**
  165251. +** OUTPUT:
  165252. +**
  165253. +** gctPOINTER * Logical
  165254. +** Pointer to a variable that receives the base address of the mapped
  165255. +** memory.
  165256. +*/
  165257. +gceSTATUS
  165258. +gckOS_MapPhysical(
  165259. + IN gckOS Os,
  165260. + IN gctUINT32 Physical,
  165261. + IN gctSIZE_T Bytes,
  165262. + OUT gctPOINTER * Logical
  165263. + )
  165264. +{
  165265. + gctPOINTER logical;
  165266. + PLINUX_MDL mdl;
  165267. + gctUINT32 physical = Physical;
  165268. +
  165269. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  165270. +
  165271. + /* Verify the arguments. */
  165272. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165273. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  165274. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  165275. +
  165276. + MEMORY_LOCK(Os);
  165277. +
  165278. + /* Go through our mapping to see if we know this physical address already. */
  165279. + mdl = Os->mdlHead;
  165280. +
  165281. + while (mdl != gcvNULL)
  165282. + {
  165283. + if (mdl->dmaHandle != 0)
  165284. + {
  165285. + if ((physical >= mdl->dmaHandle)
  165286. + && (physical < mdl->dmaHandle + mdl->numPages * PAGE_SIZE)
  165287. + )
  165288. + {
  165289. + *Logical = mdl->addr + (physical - mdl->dmaHandle);
  165290. + break;
  165291. + }
  165292. + }
  165293. +
  165294. + mdl = mdl->next;
  165295. + }
  165296. +
  165297. + if (mdl == gcvNULL)
  165298. + {
  165299. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  165300. + struct contiguous_mem_pool *pool = Os->device->pool;
  165301. +
  165302. + if (Physical >= pool->phys && Physical < pool->phys + pool->size)
  165303. + logical = (gctPOINTER)(Physical - pool->phys + pool->virt);
  165304. + else
  165305. + logical = gcvNULL;
  165306. +#else
  165307. + /* Map memory as cached memory. */
  165308. + request_mem_region(physical, Bytes, "MapRegion");
  165309. + logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
  165310. +#endif
  165311. +
  165312. + if (logical == gcvNULL)
  165313. + {
  165314. + gcmkTRACE_ZONE(
  165315. + gcvLEVEL_INFO, gcvZONE_OS,
  165316. + "%s(%d): Failed to map physical address 0x%08x",
  165317. + __FUNCTION__, __LINE__, Physical
  165318. + );
  165319. +
  165320. + MEMORY_UNLOCK(Os);
  165321. +
  165322. + /* Out of resources. */
  165323. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  165324. + return gcvSTATUS_OUT_OF_RESOURCES;
  165325. + }
  165326. +
  165327. + /* Return pointer to mapped memory. */
  165328. + *Logical = logical;
  165329. + }
  165330. +
  165331. + MEMORY_UNLOCK(Os);
  165332. +
  165333. + /* Success. */
  165334. + gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
  165335. + return gcvSTATUS_OK;
  165336. +}
  165337. +
  165338. +/*******************************************************************************
  165339. +**
  165340. +** gckOS_UnmapPhysical
  165341. +**
  165342. +** Unmap a previously mapped memory region from kernel memory.
  165343. +**
  165344. +** INPUT:
  165345. +**
  165346. +** gckOS Os
  165347. +** Pointer to an gckOS object.
  165348. +**
  165349. +** gctPOINTER Logical
  165350. +** Pointer to the base address of the memory to unmap.
  165351. +**
  165352. +** gctSIZE_T Bytes
  165353. +** Number of bytes to unmap.
  165354. +**
  165355. +** OUTPUT:
  165356. +**
  165357. +** Nothing.
  165358. +*/
  165359. +gceSTATUS
  165360. +gckOS_UnmapPhysical(
  165361. + IN gckOS Os,
  165362. + IN gctPOINTER Logical,
  165363. + IN gctSIZE_T Bytes
  165364. + )
  165365. +{
  165366. + PLINUX_MDL mdl;
  165367. +
  165368. + gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
  165369. +
  165370. + /* Verify the arguments. */
  165371. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165372. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  165373. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  165374. +
  165375. + MEMORY_LOCK(Os);
  165376. +
  165377. + mdl = Os->mdlHead;
  165378. +
  165379. + while (mdl != gcvNULL)
  165380. + {
  165381. + if (mdl->addr != gcvNULL)
  165382. + {
  165383. + if (Logical >= (gctPOINTER)mdl->addr
  165384. + && Logical < (gctPOINTER)((gctSTRING)mdl->addr + mdl->numPages * PAGE_SIZE))
  165385. + {
  165386. + break;
  165387. + }
  165388. + }
  165389. +
  165390. + mdl = mdl->next;
  165391. + }
  165392. +
  165393. + if (mdl == gcvNULL)
  165394. + {
  165395. + /* Unmap the memory. */
  165396. + iounmap(Logical);
  165397. + }
  165398. +
  165399. + MEMORY_UNLOCK(Os);
  165400. +
  165401. + /* Success. */
  165402. + gcmkFOOTER_NO();
  165403. + return gcvSTATUS_OK;
  165404. +}
  165405. +
  165406. +/*******************************************************************************
  165407. +**
  165408. +** gckOS_CreateMutex
  165409. +**
  165410. +** Create a new mutex.
  165411. +**
  165412. +** INPUT:
  165413. +**
  165414. +** gckOS Os
  165415. +** Pointer to an gckOS object.
  165416. +**
  165417. +** OUTPUT:
  165418. +**
  165419. +** gctPOINTER * Mutex
  165420. +** Pointer to a variable that will hold a pointer to the mutex.
  165421. +*/
  165422. +gceSTATUS
  165423. +gckOS_CreateMutex(
  165424. + IN gckOS Os,
  165425. + OUT gctPOINTER * Mutex
  165426. + )
  165427. +{
  165428. + gceSTATUS status;
  165429. +
  165430. + gcmkHEADER_ARG("Os=0x%X", Os);
  165431. +
  165432. + /* Validate the arguments. */
  165433. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165434. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  165435. +
  165436. + /* Allocate the mutex structure. */
  165437. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct mutex), Mutex));
  165438. +
  165439. + /* Initialize the mutex. */
  165440. + mutex_init(*Mutex);
  165441. +
  165442. + /* Return status. */
  165443. + gcmkFOOTER_ARG("*Mutex=0x%X", *Mutex);
  165444. + return gcvSTATUS_OK;
  165445. +
  165446. +OnError:
  165447. + /* Return status. */
  165448. + gcmkFOOTER();
  165449. + return status;
  165450. +}
  165451. +
  165452. +/*******************************************************************************
  165453. +**
  165454. +** gckOS_DeleteMutex
  165455. +**
  165456. +** Delete a mutex.
  165457. +**
  165458. +** INPUT:
  165459. +**
  165460. +** gckOS Os
  165461. +** Pointer to an gckOS object.
  165462. +**
  165463. +** gctPOINTER Mutex
  165464. +** Pointer to the mute to be deleted.
  165465. +**
  165466. +** OUTPUT:
  165467. +**
  165468. +** Nothing.
  165469. +*/
  165470. +gceSTATUS
  165471. +gckOS_DeleteMutex(
  165472. + IN gckOS Os,
  165473. + IN gctPOINTER Mutex
  165474. + )
  165475. +{
  165476. + gceSTATUS status;
  165477. +
  165478. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%X", Os, Mutex);
  165479. +
  165480. + /* Validate the arguments. */
  165481. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165482. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  165483. +
  165484. + /* Destroy the mutex. */
  165485. + mutex_destroy(Mutex);
  165486. +
  165487. + /* Free the mutex structure. */
  165488. + gcmkONERROR(gckOS_Free(Os, Mutex));
  165489. +
  165490. + gcmkFOOTER_NO();
  165491. + return gcvSTATUS_OK;
  165492. +
  165493. +OnError:
  165494. + /* Return status. */
  165495. + gcmkFOOTER();
  165496. + return status;
  165497. +}
  165498. +
  165499. +/*******************************************************************************
  165500. +**
  165501. +** gckOS_AcquireMutex
  165502. +**
  165503. +** Acquire a mutex.
  165504. +**
  165505. +** INPUT:
  165506. +**
  165507. +** gckOS Os
  165508. +** Pointer to an gckOS object.
  165509. +**
  165510. +** gctPOINTER Mutex
  165511. +** Pointer to the mutex to be acquired.
  165512. +**
  165513. +** gctUINT32 Timeout
  165514. +** Timeout value specified in milliseconds.
  165515. +** Specify the value of gcvINFINITE to keep the thread suspended
  165516. +** until the mutex has been acquired.
  165517. +**
  165518. +** OUTPUT:
  165519. +**
  165520. +** Nothing.
  165521. +*/
  165522. +gceSTATUS
  165523. +gckOS_AcquireMutex(
  165524. + IN gckOS Os,
  165525. + IN gctPOINTER Mutex,
  165526. + IN gctUINT32 Timeout
  165527. + )
  165528. +{
  165529. +#if gcdDETECT_TIMEOUT
  165530. + gctUINT32 timeout;
  165531. +#endif
  165532. +
  165533. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x Timeout=%u", Os, Mutex, Timeout);
  165534. +
  165535. + /* Validate the arguments. */
  165536. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165537. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  165538. +
  165539. +#if gcdDETECT_TIMEOUT
  165540. + timeout = 0;
  165541. +
  165542. + for (;;)
  165543. + {
  165544. + /* Try to acquire the mutex. */
  165545. + if (mutex_trylock(Mutex))
  165546. + {
  165547. + /* Success. */
  165548. + gcmkFOOTER_NO();
  165549. + return gcvSTATUS_OK;
  165550. + }
  165551. +
  165552. + /* Advance the timeout. */
  165553. + timeout += 1;
  165554. +
  165555. + if (Timeout == gcvINFINITE)
  165556. + {
  165557. + if (timeout == gcdINFINITE_TIMEOUT)
  165558. + {
  165559. + gctUINT32 dmaAddress1, dmaAddress2;
  165560. + gctUINT32 dmaState1, dmaState2;
  165561. +
  165562. + dmaState1 = dmaState2 =
  165563. + dmaAddress1 = dmaAddress2 = 0;
  165564. +
  165565. + /* Verify whether DMA is running. */
  165566. + gcmkVERIFY_OK(_VerifyDMA(
  165567. + Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  165568. + ));
  165569. +
  165570. +#if gcdDETECT_DMA_ADDRESS
  165571. + /* Dump only if DMA appears stuck. */
  165572. + if (
  165573. + (dmaAddress1 == dmaAddress2)
  165574. +#if gcdDETECT_DMA_STATE
  165575. + && (dmaState1 == dmaState2)
  165576. +# endif
  165577. + )
  165578. +# endif
  165579. + {
  165580. + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
  165581. +
  165582. + gcmkPRINT(
  165583. + "%s(%d): mutex 0x%X; forced message flush.",
  165584. + __FUNCTION__, __LINE__, Mutex
  165585. + );
  165586. +
  165587. + /* Flush the debug cache. */
  165588. + gcmkDEBUGFLUSH(dmaAddress2);
  165589. + }
  165590. +
  165591. + timeout = 0;
  165592. + }
  165593. + }
  165594. + else
  165595. + {
  165596. + /* Timedout? */
  165597. + if (timeout >= Timeout)
  165598. + {
  165599. + break;
  165600. + }
  165601. + }
  165602. +
  165603. + /* Wait for 1 millisecond. */
  165604. + gcmkVERIFY_OK(gckOS_Delay(Os, 1));
  165605. + }
  165606. +#else
  165607. + if (Timeout == gcvINFINITE)
  165608. + {
  165609. + /* Lock the mutex. */
  165610. + mutex_lock(Mutex);
  165611. +
  165612. + /* Success. */
  165613. + gcmkFOOTER_NO();
  165614. + return gcvSTATUS_OK;
  165615. + }
  165616. +
  165617. + for (;;)
  165618. + {
  165619. + /* Try to acquire the mutex. */
  165620. + if (mutex_trylock(Mutex))
  165621. + {
  165622. + /* Success. */
  165623. + gcmkFOOTER_NO();
  165624. + return gcvSTATUS_OK;
  165625. + }
  165626. +
  165627. + if (Timeout-- == 0)
  165628. + {
  165629. + break;
  165630. + }
  165631. +
  165632. + /* Wait for 1 millisecond. */
  165633. + gcmkVERIFY_OK(gckOS_Delay(Os, 1));
  165634. + }
  165635. +#endif
  165636. +
  165637. + /* Timeout. */
  165638. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT);
  165639. + return gcvSTATUS_TIMEOUT;
  165640. +}
  165641. +
  165642. +/*******************************************************************************
  165643. +**
  165644. +** gckOS_ReleaseMutex
  165645. +**
  165646. +** Release an acquired mutex.
  165647. +**
  165648. +** INPUT:
  165649. +**
  165650. +** gckOS Os
  165651. +** Pointer to an gckOS object.
  165652. +**
  165653. +** gctPOINTER Mutex
  165654. +** Pointer to the mutex to be released.
  165655. +**
  165656. +** OUTPUT:
  165657. +**
  165658. +** Nothing.
  165659. +*/
  165660. +gceSTATUS
  165661. +gckOS_ReleaseMutex(
  165662. + IN gckOS Os,
  165663. + IN gctPOINTER Mutex
  165664. + )
  165665. +{
  165666. + gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x", Os, Mutex);
  165667. +
  165668. + /* Validate the arguments. */
  165669. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165670. + gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
  165671. +
  165672. + /* Release the mutex. */
  165673. + mutex_unlock(Mutex);
  165674. +
  165675. + /* Success. */
  165676. + gcmkFOOTER_NO();
  165677. + return gcvSTATUS_OK;
  165678. +}
  165679. +
  165680. +/*******************************************************************************
  165681. +**
  165682. +** gckOS_AtomicExchange
  165683. +**
  165684. +** Atomically exchange a pair of 32-bit values.
  165685. +**
  165686. +** INPUT:
  165687. +**
  165688. +** gckOS Os
  165689. +** Pointer to an gckOS object.
  165690. +**
  165691. +** IN OUT gctINT32_PTR Target
  165692. +** Pointer to the 32-bit value to exchange.
  165693. +**
  165694. +** IN gctINT32 NewValue
  165695. +** Specifies a new value for the 32-bit value pointed to by Target.
  165696. +**
  165697. +** OUT gctINT32_PTR OldValue
  165698. +** The old value of the 32-bit value pointed to by Target.
  165699. +**
  165700. +** OUTPUT:
  165701. +**
  165702. +** Nothing.
  165703. +*/
  165704. +gceSTATUS
  165705. +gckOS_AtomicExchange(
  165706. + IN gckOS Os,
  165707. + IN OUT gctUINT32_PTR Target,
  165708. + IN gctUINT32 NewValue,
  165709. + OUT gctUINT32_PTR OldValue
  165710. + )
  165711. +{
  165712. + gcmkHEADER_ARG("Os=0x%X Target=0x%X NewValue=%u", Os, Target, NewValue);
  165713. +
  165714. + /* Verify the arguments. */
  165715. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165716. +
  165717. + /* Exchange the pair of 32-bit values. */
  165718. + *OldValue = (gctUINT32) atomic_xchg((atomic_t *) Target, (int) NewValue);
  165719. +
  165720. + /* Success. */
  165721. + gcmkFOOTER_ARG("*OldValue=%u", *OldValue);
  165722. + return gcvSTATUS_OK;
  165723. +}
  165724. +
  165725. +/*******************************************************************************
  165726. +**
  165727. +** gckOS_AtomicExchangePtr
  165728. +**
  165729. +** Atomically exchange a pair of pointers.
  165730. +**
  165731. +** INPUT:
  165732. +**
  165733. +** gckOS Os
  165734. +** Pointer to an gckOS object.
  165735. +**
  165736. +** IN OUT gctPOINTER * Target
  165737. +** Pointer to the 32-bit value to exchange.
  165738. +**
  165739. +** IN gctPOINTER NewValue
  165740. +** Specifies a new value for the pointer pointed to by Target.
  165741. +**
  165742. +** OUT gctPOINTER * OldValue
  165743. +** The old value of the pointer pointed to by Target.
  165744. +**
  165745. +** OUTPUT:
  165746. +**
  165747. +** Nothing.
  165748. +*/
  165749. +gceSTATUS
  165750. +gckOS_AtomicExchangePtr(
  165751. + IN gckOS Os,
  165752. + IN OUT gctPOINTER * Target,
  165753. + IN gctPOINTER NewValue,
  165754. + OUT gctPOINTER * OldValue
  165755. + )
  165756. +{
  165757. + gcmkHEADER_ARG("Os=0x%X Target=0x%X NewValue=0x%X", Os, Target, NewValue);
  165758. +
  165759. + /* Verify the arguments. */
  165760. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165761. +
  165762. + /* Exchange the pair of pointers. */
  165763. + *OldValue = (gctPOINTER)(gctUINTPTR_T) atomic_xchg((atomic_t *) Target, (int)(gctUINTPTR_T) NewValue);
  165764. +
  165765. + /* Success. */
  165766. + gcmkFOOTER_ARG("*OldValue=0x%X", *OldValue);
  165767. + return gcvSTATUS_OK;
  165768. +}
  165769. +
  165770. +#if gcdSMP
  165771. +/*******************************************************************************
  165772. +**
  165773. +** gckOS_AtomicSetMask
  165774. +**
  165775. +** Atomically set mask to Atom
  165776. +**
  165777. +** INPUT:
  165778. +** IN OUT gctPOINTER Atom
  165779. +** Pointer to the atom to set.
  165780. +**
  165781. +** IN gctUINT32 Mask
  165782. +** Mask to set.
  165783. +**
  165784. +** OUTPUT:
  165785. +**
  165786. +** Nothing.
  165787. +*/
  165788. +gceSTATUS
  165789. +gckOS_AtomSetMask(
  165790. + IN gctPOINTER Atom,
  165791. + IN gctUINT32 Mask
  165792. + )
  165793. +{
  165794. + gctUINT32 oval, nval;
  165795. +
  165796. + gcmkHEADER_ARG("Atom=0x%0x", Atom);
  165797. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  165798. +
  165799. + do
  165800. + {
  165801. + oval = atomic_read((atomic_t *) Atom);
  165802. + nval = oval | Mask;
  165803. + } while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
  165804. +
  165805. + gcmkFOOTER_NO();
  165806. + return gcvSTATUS_OK;
  165807. +}
  165808. +
  165809. +/*******************************************************************************
  165810. +**
  165811. +** gckOS_AtomClearMask
  165812. +**
  165813. +** Atomically clear mask from Atom
  165814. +**
  165815. +** INPUT:
  165816. +** IN OUT gctPOINTER Atom
  165817. +** Pointer to the atom to clear.
  165818. +**
  165819. +** IN gctUINT32 Mask
  165820. +** Mask to clear.
  165821. +**
  165822. +** OUTPUT:
  165823. +**
  165824. +** Nothing.
  165825. +*/
  165826. +gceSTATUS
  165827. +gckOS_AtomClearMask(
  165828. + IN gctPOINTER Atom,
  165829. + IN gctUINT32 Mask
  165830. + )
  165831. +{
  165832. + gctUINT32 oval, nval;
  165833. +
  165834. + gcmkHEADER_ARG("Atom=0x%0x", Atom);
  165835. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  165836. +
  165837. + do
  165838. + {
  165839. + oval = atomic_read((atomic_t *) Atom);
  165840. + nval = oval & ~Mask;
  165841. + } while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
  165842. +
  165843. + gcmkFOOTER_NO();
  165844. + return gcvSTATUS_OK;
  165845. +}
  165846. +#endif
  165847. +
  165848. +/*******************************************************************************
  165849. +**
  165850. +** gckOS_AtomConstruct
  165851. +**
  165852. +** Create an atom.
  165853. +**
  165854. +** INPUT:
  165855. +**
  165856. +** gckOS Os
  165857. +** Pointer to a gckOS object.
  165858. +**
  165859. +** OUTPUT:
  165860. +**
  165861. +** gctPOINTER * Atom
  165862. +** Pointer to a variable receiving the constructed atom.
  165863. +*/
  165864. +gceSTATUS
  165865. +gckOS_AtomConstruct(
  165866. + IN gckOS Os,
  165867. + OUT gctPOINTER * Atom
  165868. + )
  165869. +{
  165870. + gceSTATUS status;
  165871. +
  165872. + gcmkHEADER_ARG("Os=0x%X", Os);
  165873. +
  165874. + /* Verify the arguments. */
  165875. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165876. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  165877. +
  165878. + /* Allocate the atom. */
  165879. + gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(atomic_t), Atom));
  165880. +
  165881. + /* Initialize the atom. */
  165882. + atomic_set((atomic_t *) *Atom, 0);
  165883. +
  165884. + /* Success. */
  165885. + gcmkFOOTER_ARG("*Atom=0x%X", *Atom);
  165886. + return gcvSTATUS_OK;
  165887. +
  165888. +OnError:
  165889. + /* Return the status. */
  165890. + gcmkFOOTER();
  165891. + return status;
  165892. +}
  165893. +
  165894. +/*******************************************************************************
  165895. +**
  165896. +** gckOS_AtomDestroy
  165897. +**
  165898. +** Destroy an atom.
  165899. +**
  165900. +** INPUT:
  165901. +**
  165902. +** gckOS Os
  165903. +** Pointer to a gckOS object.
  165904. +**
  165905. +** gctPOINTER Atom
  165906. +** Pointer to the atom to destroy.
  165907. +**
  165908. +** OUTPUT:
  165909. +**
  165910. +** Nothing.
  165911. +*/
  165912. +gceSTATUS
  165913. +gckOS_AtomDestroy(
  165914. + IN gckOS Os,
  165915. + OUT gctPOINTER Atom
  165916. + )
  165917. +{
  165918. + gceSTATUS status;
  165919. +
  165920. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  165921. +
  165922. + /* Verify the arguments. */
  165923. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165924. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  165925. +
  165926. + /* Free the atom. */
  165927. + gcmkONERROR(gcmkOS_SAFE_FREE(Os, Atom));
  165928. +
  165929. + /* Success. */
  165930. + gcmkFOOTER_NO();
  165931. + return gcvSTATUS_OK;
  165932. +
  165933. +OnError:
  165934. + /* Return the status. */
  165935. + gcmkFOOTER();
  165936. + return status;
  165937. +}
  165938. +
  165939. +/*******************************************************************************
  165940. +**
  165941. +** gckOS_AtomGet
  165942. +**
  165943. +** Get the 32-bit value protected by an atom.
  165944. +**
  165945. +** INPUT:
  165946. +**
  165947. +** gckOS Os
  165948. +** Pointer to a gckOS object.
  165949. +**
  165950. +** gctPOINTER Atom
  165951. +** Pointer to the atom.
  165952. +**
  165953. +** OUTPUT:
  165954. +**
  165955. +** gctINT32_PTR Value
  165956. +** Pointer to a variable the receives the value of the atom.
  165957. +*/
  165958. +gceSTATUS
  165959. +gckOS_AtomGet(
  165960. + IN gckOS Os,
  165961. + IN gctPOINTER Atom,
  165962. + OUT gctINT32_PTR Value
  165963. + )
  165964. +{
  165965. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  165966. +
  165967. + /* Verify the arguments. */
  165968. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  165969. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  165970. +
  165971. + /* Return the current value of atom. */
  165972. + *Value = atomic_read((atomic_t *) Atom);
  165973. +
  165974. + /* Success. */
  165975. + gcmkFOOTER_ARG("*Value=%d", *Value);
  165976. + return gcvSTATUS_OK;
  165977. +}
  165978. +
  165979. +/*******************************************************************************
  165980. +**
  165981. +** gckOS_AtomSet
  165982. +**
  165983. +** Set the 32-bit value protected by an atom.
  165984. +**
  165985. +** INPUT:
  165986. +**
  165987. +** gckOS Os
  165988. +** Pointer to a gckOS object.
  165989. +**
  165990. +** gctPOINTER Atom
  165991. +** Pointer to the atom.
  165992. +**
  165993. +** gctINT32 Value
  165994. +** The value of the atom.
  165995. +**
  165996. +** OUTPUT:
  165997. +**
  165998. +** Nothing.
  165999. +*/
  166000. +gceSTATUS
  166001. +gckOS_AtomSet(
  166002. + IN gckOS Os,
  166003. + IN gctPOINTER Atom,
  166004. + IN gctINT32 Value
  166005. + )
  166006. +{
  166007. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x Value=%d", Os, Atom);
  166008. +
  166009. + /* Verify the arguments. */
  166010. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166011. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  166012. +
  166013. + /* Set the current value of atom. */
  166014. + atomic_set((atomic_t *) Atom, Value);
  166015. +
  166016. + /* Success. */
  166017. + gcmkFOOTER_NO();
  166018. + return gcvSTATUS_OK;
  166019. +}
  166020. +
  166021. +/*******************************************************************************
  166022. +**
  166023. +** gckOS_AtomIncrement
  166024. +**
  166025. +** Atomically increment the 32-bit integer value inside an atom.
  166026. +**
  166027. +** INPUT:
  166028. +**
  166029. +** gckOS Os
  166030. +** Pointer to a gckOS object.
  166031. +**
  166032. +** gctPOINTER Atom
  166033. +** Pointer to the atom.
  166034. +**
  166035. +** OUTPUT:
  166036. +**
  166037. +** gctINT32_PTR Value
  166038. +** Pointer to a variable that receives the original value of the atom.
  166039. +*/
  166040. +gceSTATUS
  166041. +gckOS_AtomIncrement(
  166042. + IN gckOS Os,
  166043. + IN gctPOINTER Atom,
  166044. + OUT gctINT32_PTR Value
  166045. + )
  166046. +{
  166047. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  166048. +
  166049. + /* Verify the arguments. */
  166050. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166051. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  166052. +
  166053. + /* Increment the atom. */
  166054. + *Value = atomic_inc_return((atomic_t *) Atom) - 1;
  166055. +
  166056. + /* Success. */
  166057. + gcmkFOOTER_ARG("*Value=%d", *Value);
  166058. + return gcvSTATUS_OK;
  166059. +}
  166060. +
  166061. +/*******************************************************************************
  166062. +**
  166063. +** gckOS_AtomDecrement
  166064. +**
  166065. +** Atomically decrement the 32-bit integer value inside an atom.
  166066. +**
  166067. +** INPUT:
  166068. +**
  166069. +** gckOS Os
  166070. +** Pointer to a gckOS object.
  166071. +**
  166072. +** gctPOINTER Atom
  166073. +** Pointer to the atom.
  166074. +**
  166075. +** OUTPUT:
  166076. +**
  166077. +** gctINT32_PTR Value
  166078. +** Pointer to a variable that receives the original value of the atom.
  166079. +*/
  166080. +gceSTATUS
  166081. +gckOS_AtomDecrement(
  166082. + IN gckOS Os,
  166083. + IN gctPOINTER Atom,
  166084. + OUT gctINT32_PTR Value
  166085. + )
  166086. +{
  166087. + gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
  166088. +
  166089. + /* Verify the arguments. */
  166090. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166091. + gcmkVERIFY_ARGUMENT(Atom != gcvNULL);
  166092. +
  166093. + /* Decrement the atom. */
  166094. + *Value = atomic_dec_return((atomic_t *) Atom) + 1;
  166095. +
  166096. + /* Success. */
  166097. + gcmkFOOTER_ARG("*Value=%d", *Value);
  166098. + return gcvSTATUS_OK;
  166099. +}
  166100. +
  166101. +/*******************************************************************************
  166102. +**
  166103. +** gckOS_Delay
  166104. +**
  166105. +** Delay execution of the current thread for a number of milliseconds.
  166106. +**
  166107. +** INPUT:
  166108. +**
  166109. +** gckOS Os
  166110. +** Pointer to an gckOS object.
  166111. +**
  166112. +** gctUINT32 Delay
  166113. +** Delay to sleep, specified in milliseconds.
  166114. +**
  166115. +** OUTPUT:
  166116. +**
  166117. +** Nothing.
  166118. +*/
  166119. +gceSTATUS
  166120. +gckOS_Delay(
  166121. + IN gckOS Os,
  166122. + IN gctUINT32 Delay
  166123. + )
  166124. +{
  166125. + gcmkHEADER_ARG("Os=0x%X Delay=%u", Os, Delay);
  166126. +
  166127. + if (Delay > 0)
  166128. + {
  166129. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
  166130. + ktime_t delay = ktime_set(Delay/1000, (Delay%1000) * NSEC_PER_MSEC);
  166131. + __set_current_state(TASK_UNINTERRUPTIBLE);
  166132. + schedule_hrtimeout(&delay, HRTIMER_MODE_REL);
  166133. +#else
  166134. + msleep(Delay);
  166135. +#endif
  166136. +
  166137. + }
  166138. +
  166139. + /* Success. */
  166140. + gcmkFOOTER_NO();
  166141. + return gcvSTATUS_OK;
  166142. +}
  166143. +
  166144. +/*******************************************************************************
  166145. +**
  166146. +** gckOS_GetTicks
  166147. +**
  166148. +** Get the number of milliseconds since the system started.
  166149. +**
  166150. +** INPUT:
  166151. +**
  166152. +** OUTPUT:
  166153. +**
  166154. +** gctUINT32_PTR Time
  166155. +** Pointer to a variable to get time.
  166156. +**
  166157. +*/
  166158. +gceSTATUS
  166159. +gckOS_GetTicks(
  166160. + OUT gctUINT32_PTR Time
  166161. + )
  166162. +{
  166163. + gcmkHEADER();
  166164. +
  166165. + *Time = jiffies_to_msecs(jiffies);
  166166. +
  166167. + gcmkFOOTER_NO();
  166168. + return gcvSTATUS_OK;
  166169. +}
  166170. +
  166171. +/*******************************************************************************
  166172. +**
  166173. +** gckOS_TicksAfter
  166174. +**
  166175. +** Compare time values got from gckOS_GetTicks.
  166176. +**
  166177. +** INPUT:
  166178. +** gctUINT32 Time1
  166179. +** First time value to be compared.
  166180. +**
  166181. +** gctUINT32 Time2
  166182. +** Second time value to be compared.
  166183. +**
  166184. +** OUTPUT:
  166185. +**
  166186. +** gctBOOL_PTR IsAfter
  166187. +** Pointer to a variable to result.
  166188. +**
  166189. +*/
  166190. +gceSTATUS
  166191. +gckOS_TicksAfter(
  166192. + IN gctUINT32 Time1,
  166193. + IN gctUINT32 Time2,
  166194. + OUT gctBOOL_PTR IsAfter
  166195. + )
  166196. +{
  166197. + gcmkHEADER();
  166198. +
  166199. + *IsAfter = time_after((unsigned long)Time1, (unsigned long)Time2);
  166200. +
  166201. + gcmkFOOTER_NO();
  166202. + return gcvSTATUS_OK;
  166203. +}
  166204. +
  166205. +/*******************************************************************************
  166206. +**
  166207. +** gckOS_GetTime
  166208. +**
  166209. +** Get the number of microseconds since the system started.
  166210. +**
  166211. +** INPUT:
  166212. +**
  166213. +** OUTPUT:
  166214. +**
  166215. +** gctUINT64_PTR Time
  166216. +** Pointer to a variable to get time.
  166217. +**
  166218. +*/
  166219. +gceSTATUS
  166220. +gckOS_GetTime(
  166221. + OUT gctUINT64_PTR Time
  166222. + )
  166223. +{
  166224. + gcmkHEADER();
  166225. +
  166226. + *Time = 0;
  166227. +
  166228. + gcmkFOOTER_NO();
  166229. + return gcvSTATUS_OK;
  166230. +}
  166231. +
  166232. +/*******************************************************************************
  166233. +**
  166234. +** gckOS_MemoryBarrier
  166235. +**
  166236. +** Make sure the CPU has executed everything up to this point and the data got
  166237. +** written to the specified pointer.
  166238. +**
  166239. +** INPUT:
  166240. +**
  166241. +** gckOS Os
  166242. +** Pointer to an gckOS object.
  166243. +**
  166244. +** gctPOINTER Address
  166245. +** Address of memory that needs to be barriered.
  166246. +**
  166247. +** OUTPUT:
  166248. +**
  166249. +** Nothing.
  166250. +*/
  166251. +gceSTATUS
  166252. +gckOS_MemoryBarrier(
  166253. + IN gckOS Os,
  166254. + IN gctPOINTER Address
  166255. + )
  166256. +{
  166257. + gcmkHEADER_ARG("Os=0x%X Address=0x%X", Os, Address);
  166258. +
  166259. + /* Verify the arguments. */
  166260. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166261. +
  166262. +#if gcdNONPAGED_MEMORY_BUFFERABLE \
  166263. + && defined (CONFIG_ARM) \
  166264. + && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34))
  166265. + /* drain write buffer */
  166266. + dsb();
  166267. +
  166268. + /* drain outer cache's write buffer? */
  166269. +#else
  166270. + mb();
  166271. +#endif
  166272. +
  166273. + /* Success. */
  166274. + gcmkFOOTER_NO();
  166275. + return gcvSTATUS_OK;
  166276. +}
  166277. +
  166278. +/*******************************************************************************
  166279. +**
  166280. +** gckOS_AllocatePagedMemory
  166281. +**
  166282. +** Allocate memory from the paged pool.
  166283. +**
  166284. +** INPUT:
  166285. +**
  166286. +** gckOS Os
  166287. +** Pointer to an gckOS object.
  166288. +**
  166289. +** gctSIZE_T Bytes
  166290. +** Number of bytes to allocate.
  166291. +**
  166292. +** OUTPUT:
  166293. +**
  166294. +** gctPHYS_ADDR * Physical
  166295. +** Pointer to a variable that receives the physical address of the
  166296. +** memory allocation.
  166297. +*/
  166298. +gceSTATUS
  166299. +gckOS_AllocatePagedMemory(
  166300. + IN gckOS Os,
  166301. + IN gctSIZE_T Bytes,
  166302. + OUT gctPHYS_ADDR * Physical
  166303. + )
  166304. +{
  166305. + gceSTATUS status;
  166306. +
  166307. + gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
  166308. +
  166309. + /* Verify the arguments. */
  166310. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166311. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166312. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  166313. +
  166314. + /* Allocate the memory. */
  166315. + gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvFALSE, Bytes, Physical));
  166316. +
  166317. + /* Success. */
  166318. + gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
  166319. + return gcvSTATUS_OK;
  166320. +
  166321. +OnError:
  166322. + /* Return the status. */
  166323. + gcmkFOOTER();
  166324. + return status;
  166325. +}
  166326. +
  166327. +/*******************************************************************************
  166328. +**
  166329. +** gckOS_AllocatePagedMemoryEx
  166330. +**
  166331. +** Allocate memory from the paged pool.
  166332. +**
  166333. +** INPUT:
  166334. +**
  166335. +** gckOS Os
  166336. +** Pointer to an gckOS object.
  166337. +**
  166338. +** gctBOOL Contiguous
  166339. +** Need contiguous memory or not.
  166340. +**
  166341. +** gctSIZE_T Bytes
  166342. +** Number of bytes to allocate.
  166343. +**
  166344. +** OUTPUT:
  166345. +**
  166346. +** gctPHYS_ADDR * Physical
  166347. +** Pointer to a variable that receives the physical address of the
  166348. +** memory allocation.
  166349. +*/
  166350. +gceSTATUS
  166351. +gckOS_AllocatePagedMemoryEx(
  166352. + IN gckOS Os,
  166353. + IN gctBOOL Contiguous,
  166354. + IN gctSIZE_T Bytes,
  166355. + OUT gctPHYS_ADDR * Physical
  166356. + )
  166357. +{
  166358. + gctINT numPages;
  166359. + gctINT i;
  166360. + PLINUX_MDL mdl = gcvNULL;
  166361. + gctSIZE_T bytes;
  166362. + gctBOOL locked = gcvFALSE;
  166363. + gceSTATUS status;
  166364. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  166365. + gctPOINTER addr = gcvNULL;
  166366. +#endif
  166367. +
  166368. + gcmkHEADER_ARG("Os=0x%X Contiguous=%d Bytes=%lu", Os, Contiguous, Bytes);
  166369. +
  166370. + /* Verify the arguments. */
  166371. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166372. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166373. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  166374. +
  166375. + bytes = gcmALIGN(Bytes, PAGE_SIZE);
  166376. +
  166377. + numPages = GetPageCount(bytes, 0);
  166378. +
  166379. + MEMORY_LOCK(Os);
  166380. + locked = gcvTRUE;
  166381. +
  166382. + mdl = _CreateMdl(_GetProcessID());
  166383. + if (mdl == gcvNULL)
  166384. + {
  166385. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  166386. + }
  166387. +
  166388. + if (Contiguous)
  166389. + {
  166390. + gctUINT32 order = get_order(bytes);
  166391. +
  166392. + if (order >= MAX_ORDER)
  166393. + {
  166394. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  166395. + }
  166396. +
  166397. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  166398. + addr =
  166399. + alloc_pages_exact(numPages * PAGE_SIZE, GFP_KERNEL | gcdNOWARN | __GFP_NORETRY);
  166400. +
  166401. + mdl->u.contiguousPages = addr
  166402. + ? virt_to_page(addr)
  166403. + : gcvNULL;
  166404. +
  166405. + mdl->exact = gcvTRUE;
  166406. +#else
  166407. + mdl->u.contiguousPages =
  166408. + alloc_pages(GFP_KERNEL | gcdNOWARN | __GFP_NORETRY, order);
  166409. +#endif
  166410. + if (mdl->u.contiguousPages == gcvNULL)
  166411. + {
  166412. + mdl->u.contiguousPages =
  166413. + alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | gcdNOWARN, order);
  166414. +
  166415. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  166416. + mdl->exact = gcvFALSE;
  166417. +#endif
  166418. + }
  166419. + }
  166420. + else
  166421. + {
  166422. + mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages);
  166423. + }
  166424. +
  166425. + if (mdl->u.contiguousPages == gcvNULL && mdl->u.nonContiguousPages == gcvNULL)
  166426. + {
  166427. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  166428. + }
  166429. +
  166430. + mdl->dmaHandle = 0;
  166431. + mdl->addr = 0;
  166432. + mdl->numPages = numPages;
  166433. + mdl->pagedMem = 1;
  166434. + mdl->contiguous = Contiguous;
  166435. +
  166436. + for (i = 0; i < mdl->numPages; i++)
  166437. + {
  166438. + struct page *page;
  166439. +
  166440. + if (mdl->contiguous)
  166441. + {
  166442. + page = nth_page(mdl->u.contiguousPages, i);
  166443. + }
  166444. + else
  166445. + {
  166446. + page = _NonContiguousToPage(mdl->u.nonContiguousPages, i);
  166447. + }
  166448. +
  166449. + SetPageReserved(page);
  166450. +
  166451. + if (!PageHighMem(page) && page_to_phys(page))
  166452. + {
  166453. + gcmkVERIFY_OK(
  166454. + gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
  166455. + (gctPOINTER)(gctUINTPTR_T)page_to_phys(page),
  166456. + page_address(page),
  166457. + PAGE_SIZE));
  166458. + }
  166459. + }
  166460. +
  166461. + /* Return physical address. */
  166462. + *Physical = (gctPHYS_ADDR) mdl;
  166463. +
  166464. + /*
  166465. + * Add this to a global list.
  166466. + * Will be used by get physical address
  166467. + * and mapuser pointer functions.
  166468. + */
  166469. + if (!Os->mdlHead)
  166470. + {
  166471. + /* Initialize the queue. */
  166472. + Os->mdlHead = Os->mdlTail = mdl;
  166473. + }
  166474. + else
  166475. + {
  166476. + /* Add to tail. */
  166477. + mdl->prev = Os->mdlTail;
  166478. + Os->mdlTail->next = mdl;
  166479. + Os->mdlTail = mdl;
  166480. + }
  166481. +
  166482. + MEMORY_UNLOCK(Os);
  166483. +
  166484. + /* Success. */
  166485. + gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
  166486. + return gcvSTATUS_OK;
  166487. +
  166488. +OnError:
  166489. + if (mdl != gcvNULL)
  166490. + {
  166491. + /* Free the memory. */
  166492. + _DestroyMdl(mdl);
  166493. + }
  166494. +
  166495. + if (locked)
  166496. + {
  166497. + /* Unlock the memory. */
  166498. + MEMORY_UNLOCK(Os);
  166499. + }
  166500. +
  166501. + /* Return the status. */
  166502. + gcmkFOOTER();
  166503. + return status;
  166504. +}
  166505. +
  166506. +/*******************************************************************************
  166507. +**
  166508. +** gckOS_FreePagedMemory
  166509. +**
  166510. +** Free memory allocated from the paged pool.
  166511. +**
  166512. +** INPUT:
  166513. +**
  166514. +** gckOS Os
  166515. +** Pointer to an gckOS object.
  166516. +**
  166517. +** gctPHYS_ADDR Physical
  166518. +** Physical address of the allocation.
  166519. +**
  166520. +** gctSIZE_T Bytes
  166521. +** Number of bytes of the allocation.
  166522. +**
  166523. +** OUTPUT:
  166524. +**
  166525. +** Nothing.
  166526. +*/
  166527. +gceSTATUS
  166528. +gckOS_FreePagedMemory(
  166529. + IN gckOS Os,
  166530. + IN gctPHYS_ADDR Physical,
  166531. + IN gctSIZE_T Bytes
  166532. + )
  166533. +{
  166534. + PLINUX_MDL mdl = (PLINUX_MDL) Physical;
  166535. + gctINT i;
  166536. +
  166537. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
  166538. +
  166539. + /* Verify the arguments. */
  166540. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166541. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  166542. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  166543. +
  166544. + /*addr = mdl->addr;*/
  166545. +
  166546. + MEMORY_LOCK(Os);
  166547. +
  166548. + for (i = 0; i < mdl->numPages; i++)
  166549. + {
  166550. + if (mdl->contiguous)
  166551. + {
  166552. + ClearPageReserved(nth_page(mdl->u.contiguousPages, i));
  166553. + }
  166554. + else
  166555. + {
  166556. + ClearPageReserved(_NonContiguousToPage(mdl->u.nonContiguousPages, i));
  166557. + }
  166558. + }
  166559. +
  166560. + if (mdl->contiguous)
  166561. + {
  166562. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  166563. + if (mdl->exact == gcvTRUE)
  166564. + {
  166565. + free_pages_exact(page_address(mdl->u.contiguousPages), mdl->numPages * PAGE_SIZE);
  166566. + }
  166567. + else
  166568. +#endif
  166569. + {
  166570. + __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
  166571. + }
  166572. + }
  166573. + else
  166574. + {
  166575. + _NonContiguousFree(mdl->u.nonContiguousPages, mdl->numPages);
  166576. + }
  166577. +
  166578. + /* Remove the node from global list. */
  166579. + if (mdl == Os->mdlHead)
  166580. + {
  166581. + if ((Os->mdlHead = mdl->next) == gcvNULL)
  166582. + {
  166583. + Os->mdlTail = gcvNULL;
  166584. + }
  166585. + }
  166586. + else
  166587. + {
  166588. + mdl->prev->next = mdl->next;
  166589. +
  166590. + if (mdl == Os->mdlTail)
  166591. + {
  166592. + Os->mdlTail = mdl->prev;
  166593. + }
  166594. + else
  166595. + {
  166596. + mdl->next->prev = mdl->prev;
  166597. + }
  166598. + }
  166599. +
  166600. + MEMORY_UNLOCK(Os);
  166601. +
  166602. + /* Free the structure... */
  166603. + gcmkVERIFY_OK(_DestroyMdl(mdl));
  166604. +
  166605. + /* Success. */
  166606. + gcmkFOOTER_NO();
  166607. + return gcvSTATUS_OK;
  166608. +}
  166609. +
  166610. +/*******************************************************************************
  166611. +**
  166612. +** gckOS_LockPages
  166613. +**
  166614. +** Lock memory allocated from the paged pool.
  166615. +**
  166616. +** INPUT:
  166617. +**
  166618. +** gckOS Os
  166619. +** Pointer to an gckOS object.
  166620. +**
  166621. +** gctPHYS_ADDR Physical
  166622. +** Physical address of the allocation.
  166623. +**
  166624. +** gctSIZE_T Bytes
  166625. +** Number of bytes of the allocation.
  166626. +**
  166627. +** gctBOOL Cacheable
  166628. +** Cache mode of mapping.
  166629. +**
  166630. +** OUTPUT:
  166631. +**
  166632. +** gctPOINTER * Logical
  166633. +** Pointer to a variable that receives the address of the mapped
  166634. +** memory.
  166635. +**
  166636. +** gctSIZE_T * PageCount
  166637. +** Pointer to a variable that receives the number of pages required for
  166638. +** the page table according to the GPU page size.
  166639. +*/
  166640. +gceSTATUS
  166641. +gckOS_LockPages(
  166642. + IN gckOS Os,
  166643. + IN gctPHYS_ADDR Physical,
  166644. + IN gctSIZE_T Bytes,
  166645. + IN gctBOOL Cacheable,
  166646. + OUT gctPOINTER * Logical,
  166647. + OUT gctSIZE_T * PageCount
  166648. + )
  166649. +{
  166650. + PLINUX_MDL mdl;
  166651. + PLINUX_MDL_MAP mdlMap;
  166652. + gctSTRING addr;
  166653. + unsigned long start;
  166654. + unsigned long pfn;
  166655. + gctINT i;
  166656. +
  166657. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical);
  166658. +
  166659. + /* Verify the arguments. */
  166660. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166661. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  166662. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  166663. + gcmkVERIFY_ARGUMENT(PageCount != gcvNULL);
  166664. +
  166665. + mdl = (PLINUX_MDL) Physical;
  166666. +
  166667. + MEMORY_LOCK(Os);
  166668. +
  166669. + mdlMap = FindMdlMap(mdl, _GetProcessID());
  166670. +
  166671. + if (mdlMap == gcvNULL)
  166672. + {
  166673. + mdlMap = _CreateMdlMap(mdl, _GetProcessID());
  166674. +
  166675. + if (mdlMap == gcvNULL)
  166676. + {
  166677. + MEMORY_UNLOCK(Os);
  166678. +
  166679. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  166680. + return gcvSTATUS_OUT_OF_MEMORY;
  166681. + }
  166682. + }
  166683. +
  166684. + if (mdlMap->vmaAddr == gcvNULL)
  166685. + {
  166686. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
  166687. + mdlMap->vmaAddr = (gctSTRING)vm_mmap(gcvNULL,
  166688. + 0L,
  166689. + mdl->numPages * PAGE_SIZE,
  166690. + PROT_READ | PROT_WRITE,
  166691. + MAP_SHARED,
  166692. + 0);
  166693. +#else
  166694. + down_write(&current->mm->mmap_sem);
  166695. +
  166696. + mdlMap->vmaAddr = (gctSTRING)do_mmap_pgoff(gcvNULL,
  166697. + 0L,
  166698. + mdl->numPages * PAGE_SIZE,
  166699. + PROT_READ | PROT_WRITE,
  166700. + MAP_SHARED,
  166701. + 0);
  166702. +
  166703. + up_write(&current->mm->mmap_sem);
  166704. +#endif
  166705. +
  166706. + gcmkTRACE_ZONE(
  166707. + gcvLEVEL_INFO, gcvZONE_OS,
  166708. + "%s(%d): vmaAddr->0x%X for phys_addr->0x%X",
  166709. + __FUNCTION__, __LINE__,
  166710. + (gctUINT32)(gctUINTPTR_T)mdlMap->vmaAddr,
  166711. + (gctUINT32)(gctUINTPTR_T)mdl
  166712. + );
  166713. +
  166714. + if (IS_ERR(mdlMap->vmaAddr))
  166715. + {
  166716. + gcmkTRACE_ZONE(
  166717. + gcvLEVEL_INFO, gcvZONE_OS,
  166718. + "%s(%d): do_mmap_pgoff error",
  166719. + __FUNCTION__, __LINE__
  166720. + );
  166721. +
  166722. + mdlMap->vmaAddr = gcvNULL;
  166723. +
  166724. + MEMORY_UNLOCK(Os);
  166725. +
  166726. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  166727. + return gcvSTATUS_OUT_OF_MEMORY;
  166728. + }
  166729. +
  166730. + down_write(&current->mm->mmap_sem);
  166731. +
  166732. + mdlMap->vma = find_vma(current->mm, (unsigned long)mdlMap->vmaAddr);
  166733. +
  166734. + if (mdlMap->vma == gcvNULL)
  166735. + {
  166736. + up_write(&current->mm->mmap_sem);
  166737. +
  166738. + gcmkTRACE_ZONE(
  166739. + gcvLEVEL_INFO, gcvZONE_OS,
  166740. + "%s(%d): find_vma error",
  166741. + __FUNCTION__, __LINE__
  166742. + );
  166743. +
  166744. + mdlMap->vmaAddr = gcvNULL;
  166745. +
  166746. + MEMORY_UNLOCK(Os);
  166747. +
  166748. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_RESOURCES);
  166749. + return gcvSTATUS_OUT_OF_RESOURCES;
  166750. + }
  166751. +
  166752. + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
  166753. +
  166754. + if (Cacheable == gcvFALSE)
  166755. + {
  166756. + /* Make this mapping non-cached. */
  166757. + mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
  166758. + }
  166759. +
  166760. + addr = mdl->addr;
  166761. +
  166762. + /* Now map all the vmalloc pages to this user address. */
  166763. + if (mdl->contiguous)
  166764. + {
  166765. + /* map kernel memory to user space.. */
  166766. + if (remap_pfn_range(mdlMap->vma,
  166767. + mdlMap->vma->vm_start,
  166768. + page_to_pfn(mdl->u.contiguousPages),
  166769. + mdlMap->vma->vm_end - mdlMap->vma->vm_start,
  166770. + mdlMap->vma->vm_page_prot) < 0)
  166771. + {
  166772. + up_write(&current->mm->mmap_sem);
  166773. +
  166774. + gcmkTRACE_ZONE(
  166775. + gcvLEVEL_INFO, gcvZONE_OS,
  166776. + "%s(%d): unable to mmap ret",
  166777. + __FUNCTION__, __LINE__
  166778. + );
  166779. +
  166780. + mdlMap->vmaAddr = gcvNULL;
  166781. +
  166782. + MEMORY_UNLOCK(Os);
  166783. +
  166784. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  166785. + return gcvSTATUS_OUT_OF_MEMORY;
  166786. + }
  166787. + }
  166788. + else
  166789. + {
  166790. + start = mdlMap->vma->vm_start;
  166791. +
  166792. + for (i = 0; i < mdl->numPages; i++)
  166793. + {
  166794. + pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i);
  166795. +
  166796. + if (remap_pfn_range(mdlMap->vma,
  166797. + start,
  166798. + pfn,
  166799. + PAGE_SIZE,
  166800. + mdlMap->vma->vm_page_prot) < 0)
  166801. + {
  166802. + up_write(&current->mm->mmap_sem);
  166803. +
  166804. + gcmkTRACE_ZONE(
  166805. + gcvLEVEL_INFO, gcvZONE_OS,
  166806. + "%s(%d): gctPHYS_ADDR->0x%X Logical->0x%X Unable to map addr->0x%X to start->0x%X",
  166807. + __FUNCTION__, __LINE__,
  166808. + (gctUINT32)(gctUINTPTR_T)Physical,
  166809. + (gctUINT32)(gctUINTPTR_T)*Logical,
  166810. + (gctUINT32)(gctUINTPTR_T)addr,
  166811. + (gctUINT32)(gctUINTPTR_T)start
  166812. + );
  166813. +
  166814. + mdlMap->vmaAddr = gcvNULL;
  166815. +
  166816. + MEMORY_UNLOCK(Os);
  166817. +
  166818. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  166819. + return gcvSTATUS_OUT_OF_MEMORY;
  166820. + }
  166821. +
  166822. + start += PAGE_SIZE;
  166823. + addr += PAGE_SIZE;
  166824. + }
  166825. + }
  166826. +
  166827. + up_write(&current->mm->mmap_sem);
  166828. + }
  166829. +
  166830. + mdlMap->count++;
  166831. +
  166832. + /* Convert pointer to MDL. */
  166833. + *Logical = mdlMap->vmaAddr;
  166834. +
  166835. + /* Return the page number according to the GPU page size. */
  166836. + gcmkASSERT((PAGE_SIZE % 4096) == 0);
  166837. + gcmkASSERT((PAGE_SIZE / 4096) >= 1);
  166838. +
  166839. + *PageCount = mdl->numPages * (PAGE_SIZE / 4096);
  166840. +
  166841. + MEMORY_UNLOCK(Os);
  166842. +
  166843. + gcmkVERIFY_OK(gckOS_CacheFlush(
  166844. + Os,
  166845. + _GetProcessID(),
  166846. + Physical,
  166847. + gcvNULL,
  166848. + (gctPOINTER)mdlMap->vmaAddr,
  166849. + mdl->numPages * PAGE_SIZE
  166850. + ));
  166851. +
  166852. + /* Success. */
  166853. + gcmkFOOTER_ARG("*Logical=0x%X *PageCount=%lu", *Logical, *PageCount);
  166854. + return gcvSTATUS_OK;
  166855. +}
  166856. +
  166857. +/*******************************************************************************
  166858. +**
  166859. +** gckOS_MapPages
  166860. +**
  166861. +** Map paged memory into a page table.
  166862. +**
  166863. +** INPUT:
  166864. +**
  166865. +** gckOS Os
  166866. +** Pointer to an gckOS object.
  166867. +**
  166868. +** gctPHYS_ADDR Physical
  166869. +** Physical address of the allocation.
  166870. +**
  166871. +** gctSIZE_T PageCount
  166872. +** Number of pages required for the physical address.
  166873. +**
  166874. +** gctPOINTER PageTable
  166875. +** Pointer to the page table to fill in.
  166876. +**
  166877. +** OUTPUT:
  166878. +**
  166879. +** Nothing.
  166880. +*/
  166881. +gceSTATUS
  166882. +gckOS_MapPages(
  166883. + IN gckOS Os,
  166884. + IN gctPHYS_ADDR Physical,
  166885. + IN gctSIZE_T PageCount,
  166886. + IN gctPOINTER PageTable
  166887. + )
  166888. +{
  166889. + return gckOS_MapPagesEx(Os,
  166890. + gcvCORE_MAJOR,
  166891. + Physical,
  166892. + PageCount,
  166893. + PageTable);
  166894. +}
  166895. +
  166896. +gceSTATUS
  166897. +gckOS_MapPagesEx(
  166898. + IN gckOS Os,
  166899. + IN gceCORE Core,
  166900. + IN gctPHYS_ADDR Physical,
  166901. + IN gctSIZE_T PageCount,
  166902. + IN gctPOINTER PageTable
  166903. + )
  166904. +{
  166905. + gceSTATUS status = gcvSTATUS_OK;
  166906. + PLINUX_MDL mdl;
  166907. + gctUINT32* table;
  166908. + gctUINT32 offset;
  166909. +#if gcdNONPAGED_MEMORY_CACHEABLE
  166910. + gckMMU mmu;
  166911. + PLINUX_MDL mmuMdl;
  166912. + gctUINT32 bytes;
  166913. + gctPHYS_ADDR pageTablePhysical;
  166914. +#endif
  166915. +
  166916. + gcmkHEADER_ARG("Os=0x%X Core=%d Physical=0x%X PageCount=%u PageTable=0x%X",
  166917. + Os, Core, Physical, PageCount, PageTable);
  166918. +
  166919. + /* Verify the arguments. */
  166920. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  166921. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  166922. + gcmkVERIFY_ARGUMENT(PageCount > 0);
  166923. + gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
  166924. +
  166925. + /* Convert pointer to MDL. */
  166926. + mdl = (PLINUX_MDL)Physical;
  166927. +
  166928. + gcmkTRACE_ZONE(
  166929. + gcvLEVEL_INFO, gcvZONE_OS,
  166930. + "%s(%d): Physical->0x%X PageCount->0x%X PagedMemory->?%d",
  166931. + __FUNCTION__, __LINE__,
  166932. + (gctUINT32)(gctUINTPTR_T)Physical,
  166933. + (gctUINT32)(gctUINTPTR_T)PageCount,
  166934. + mdl->pagedMem
  166935. + );
  166936. +
  166937. + MEMORY_LOCK(Os);
  166938. +
  166939. + table = (gctUINT32 *)PageTable;
  166940. +#if gcdNONPAGED_MEMORY_CACHEABLE
  166941. + mmu = Os->device->kernels[Core]->mmu;
  166942. + bytes = PageCount * sizeof(*table);
  166943. + mmuMdl = (PLINUX_MDL)mmu->pageTablePhysical;
  166944. +#endif
  166945. +
  166946. + /* Get all the physical addresses and store them in the page table. */
  166947. +
  166948. + offset = 0;
  166949. +
  166950. + if (mdl->pagedMem)
  166951. + {
  166952. + /* Try to get the user pages so DMA can happen. */
  166953. + while (PageCount-- > 0)
  166954. + {
  166955. +#if gcdENABLE_VG
  166956. + if (Core == gcvCORE_VG)
  166957. + {
  166958. + if (mdl->contiguous)
  166959. + {
  166960. + gcmkONERROR(
  166961. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  166962. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  166963. + table));
  166964. + }
  166965. + else
  166966. + {
  166967. + gcmkONERROR(
  166968. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  166969. + _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
  166970. + table));
  166971. + }
  166972. + }
  166973. + else
  166974. +#endif
  166975. + {
  166976. + if (mdl->contiguous)
  166977. + {
  166978. + gcmkONERROR(
  166979. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  166980. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  166981. + table));
  166982. + }
  166983. + else
  166984. + {
  166985. + gcmkONERROR(
  166986. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  166987. + _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
  166988. + table));
  166989. + }
  166990. + }
  166991. +
  166992. + table++;
  166993. + offset += 1;
  166994. + }
  166995. + }
  166996. + else
  166997. + {
  166998. + gcmkTRACE_ZONE(
  166999. + gcvLEVEL_INFO, gcvZONE_OS,
  167000. + "%s(%d): we should not get this call for Non Paged Memory!",
  167001. + __FUNCTION__, __LINE__
  167002. + );
  167003. +
  167004. + while (PageCount-- > 0)
  167005. + {
  167006. +#if gcdENABLE_VG
  167007. + if (Core == gcvCORE_VG)
  167008. + {
  167009. + gcmkONERROR(
  167010. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  167011. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  167012. + table));
  167013. + }
  167014. + else
  167015. +#endif
  167016. + {
  167017. + gcmkONERROR(
  167018. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  167019. + page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
  167020. + table));
  167021. + }
  167022. + table++;
  167023. + offset += 1;
  167024. + }
  167025. + }
  167026. +
  167027. +#if gcdNONPAGED_MEMORY_CACHEABLE
  167028. + /* Get physical address of pageTable */
  167029. + pageTablePhysical = (gctPHYS_ADDR)(mmuMdl->dmaHandle +
  167030. + ((gctUINT32 *)PageTable - mmu->pageTableLogical));
  167031. +
  167032. + /* Flush the mmu page table cache. */
  167033. + gcmkONERROR(gckOS_CacheClean(
  167034. + Os,
  167035. + _GetProcessID(),
  167036. + gcvNULL,
  167037. + pageTablePhysical,
  167038. + PageTable,
  167039. + bytes
  167040. + ));
  167041. +#endif
  167042. +
  167043. +OnError:
  167044. +
  167045. + MEMORY_UNLOCK(Os);
  167046. +
  167047. + /* Return the status. */
  167048. + gcmkFOOTER();
  167049. + return status;
  167050. +}
  167051. +
  167052. +/*******************************************************************************
  167053. +**
  167054. +** gckOS_UnlockPages
  167055. +**
  167056. +** Unlock memory allocated from the paged pool.
  167057. +**
  167058. +** INPUT:
  167059. +**
  167060. +** gckOS Os
  167061. +** Pointer to an gckOS object.
  167062. +**
  167063. +** gctPHYS_ADDR Physical
  167064. +** Physical address of the allocation.
  167065. +**
  167066. +** gctSIZE_T Bytes
  167067. +** Number of bytes of the allocation.
  167068. +**
  167069. +** gctPOINTER Logical
  167070. +** Address of the mapped memory.
  167071. +**
  167072. +** OUTPUT:
  167073. +**
  167074. +** Nothing.
  167075. +*/
  167076. +gceSTATUS
  167077. +gckOS_UnlockPages(
  167078. + IN gckOS Os,
  167079. + IN gctPHYS_ADDR Physical,
  167080. + IN gctSIZE_T Bytes,
  167081. + IN gctPOINTER Logical
  167082. + )
  167083. +{
  167084. + PLINUX_MDL_MAP mdlMap;
  167085. + PLINUX_MDL mdl = (PLINUX_MDL)Physical;
  167086. +
  167087. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%u Logical=0x%X",
  167088. + Os, Physical, Bytes, Logical);
  167089. +
  167090. + /* Verify the arguments. */
  167091. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167092. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  167093. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  167094. +
  167095. + /* Make sure there is already a mapping...*/
  167096. + gcmkVERIFY_ARGUMENT(mdl->u.nonContiguousPages != gcvNULL
  167097. + || mdl->u.contiguousPages != gcvNULL);
  167098. +
  167099. + MEMORY_LOCK(Os);
  167100. +
  167101. + mdlMap = mdl->maps;
  167102. +
  167103. + while (mdlMap != gcvNULL)
  167104. + {
  167105. + if ((mdlMap->vmaAddr != gcvNULL) && (_GetProcessID() == mdlMap->pid))
  167106. + {
  167107. + if (--mdlMap->count == 0)
  167108. + {
  167109. + _UnmapUserLogical(mdlMap->pid, mdlMap->vmaAddr, mdl->numPages * PAGE_SIZE);
  167110. + mdlMap->vmaAddr = gcvNULL;
  167111. + }
  167112. + }
  167113. +
  167114. + mdlMap = mdlMap->next;
  167115. + }
  167116. +
  167117. + MEMORY_UNLOCK(Os);
  167118. +
  167119. + /* Success. */
  167120. + gcmkFOOTER_NO();
  167121. + return gcvSTATUS_OK;
  167122. +}
  167123. +
  167124. +
  167125. +/*******************************************************************************
  167126. +**
  167127. +** gckOS_AllocateContiguous
  167128. +**
  167129. +** Allocate memory from the contiguous pool.
  167130. +**
  167131. +** INPUT:
  167132. +**
  167133. +** gckOS Os
  167134. +** Pointer to an gckOS object.
  167135. +**
  167136. +** gctBOOL InUserSpace
  167137. +** gcvTRUE if the pages need to be mapped into user space.
  167138. +**
  167139. +** gctSIZE_T * Bytes
  167140. +** Pointer to the number of bytes to allocate.
  167141. +**
  167142. +** OUTPUT:
  167143. +**
  167144. +** gctSIZE_T * Bytes
  167145. +** Pointer to a variable that receives the number of bytes allocated.
  167146. +**
  167147. +** gctPHYS_ADDR * Physical
  167148. +** Pointer to a variable that receives the physical address of the
  167149. +** memory allocation.
  167150. +**
  167151. +** gctPOINTER * Logical
  167152. +** Pointer to a variable that receives the logical address of the
  167153. +** memory allocation.
  167154. +*/
  167155. +gceSTATUS
  167156. +gckOS_AllocateContiguous(
  167157. + IN gckOS Os,
  167158. + IN gctBOOL InUserSpace,
  167159. + IN OUT gctSIZE_T * Bytes,
  167160. + OUT gctPHYS_ADDR * Physical,
  167161. + OUT gctPOINTER * Logical
  167162. + )
  167163. +{
  167164. + gceSTATUS status;
  167165. +
  167166. + gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
  167167. + Os, InUserSpace, gcmOPT_VALUE(Bytes));
  167168. +
  167169. + /* Verify the arguments. */
  167170. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167171. + gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
  167172. + gcmkVERIFY_ARGUMENT(*Bytes > 0);
  167173. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  167174. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  167175. +
  167176. + /* Same as non-paged memory for now. */
  167177. + gcmkONERROR(gckOS_AllocateNonPagedMemory(Os,
  167178. + InUserSpace,
  167179. + Bytes,
  167180. + Physical,
  167181. + Logical));
  167182. +
  167183. + /* Success. */
  167184. + gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
  167185. + *Bytes, *Physical, *Logical);
  167186. + return gcvSTATUS_OK;
  167187. +
  167188. +OnError:
  167189. + /* Return the status. */
  167190. + gcmkFOOTER();
  167191. + return status;
  167192. +}
  167193. +
  167194. +/*******************************************************************************
  167195. +**
  167196. +** gckOS_FreeContiguous
  167197. +**
  167198. +** Free memory allocated from the contiguous pool.
  167199. +**
  167200. +** INPUT:
  167201. +**
  167202. +** gckOS Os
  167203. +** Pointer to an gckOS object.
  167204. +**
  167205. +** gctPHYS_ADDR Physical
  167206. +** Physical address of the allocation.
  167207. +**
  167208. +** gctPOINTER Logical
  167209. +** Logicval address of the allocation.
  167210. +**
  167211. +** gctSIZE_T Bytes
  167212. +** Number of bytes of the allocation.
  167213. +**
  167214. +** OUTPUT:
  167215. +**
  167216. +** Nothing.
  167217. +*/
  167218. +gceSTATUS
  167219. +gckOS_FreeContiguous(
  167220. + IN gckOS Os,
  167221. + IN gctPHYS_ADDR Physical,
  167222. + IN gctPOINTER Logical,
  167223. + IN gctSIZE_T Bytes
  167224. + )
  167225. +{
  167226. + gceSTATUS status;
  167227. +
  167228. + gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
  167229. + Os, Physical, Logical, Bytes);
  167230. +
  167231. + /* Verify the arguments. */
  167232. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167233. + gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
  167234. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  167235. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  167236. +
  167237. + /* Same of non-paged memory for now. */
  167238. + gcmkONERROR(gckOS_FreeNonPagedMemory(Os, Bytes, Physical, Logical));
  167239. +
  167240. + /* Success. */
  167241. + gcmkFOOTER_NO();
  167242. + return gcvSTATUS_OK;
  167243. +
  167244. +OnError:
  167245. + /* Return the status. */
  167246. + gcmkFOOTER();
  167247. + return status;
  167248. +}
  167249. +
  167250. +#if gcdENABLE_VG
  167251. +/******************************************************************************
  167252. +**
  167253. +** gckOS_GetKernelLogical
  167254. +**
  167255. +** Return the kernel logical pointer that corresponods to the specified
  167256. +** hardware address.
  167257. +**
  167258. +** INPUT:
  167259. +**
  167260. +** gckOS Os
  167261. +** Pointer to an gckOS object.
  167262. +**
  167263. +** gctUINT32 Address
  167264. +** Hardware physical address.
  167265. +**
  167266. +** OUTPUT:
  167267. +**
  167268. +** gctPOINTER * KernelPointer
  167269. +** Pointer to a variable receiving the pointer in kernel address space.
  167270. +*/
  167271. +gceSTATUS
  167272. +gckOS_GetKernelLogical(
  167273. + IN gckOS Os,
  167274. + IN gctUINT32 Address,
  167275. + OUT gctPOINTER * KernelPointer
  167276. + )
  167277. +{
  167278. + return gckOS_GetKernelLogicalEx(Os, gcvCORE_MAJOR, Address, KernelPointer);
  167279. +}
  167280. +
  167281. +gceSTATUS
  167282. +gckOS_GetKernelLogicalEx(
  167283. + IN gckOS Os,
  167284. + IN gceCORE Core,
  167285. + IN gctUINT32 Address,
  167286. + OUT gctPOINTER * KernelPointer
  167287. + )
  167288. +{
  167289. + gceSTATUS status;
  167290. +
  167291. + gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%08x", Os, Core, Address);
  167292. +
  167293. + do
  167294. + {
  167295. + gckGALDEVICE device;
  167296. + gckKERNEL kernel;
  167297. + gcePOOL pool;
  167298. + gctUINT32 offset;
  167299. + gctPOINTER logical;
  167300. +
  167301. + /* Extract the pointer to the gckGALDEVICE class. */
  167302. + device = (gckGALDEVICE) Os->device;
  167303. +
  167304. + /* Kernel shortcut. */
  167305. + kernel = device->kernels[Core];
  167306. +#if gcdENABLE_VG
  167307. + if (Core == gcvCORE_VG)
  167308. + {
  167309. + gcmkERR_BREAK(gckVGHARDWARE_SplitMemory(
  167310. + kernel->vg->hardware, Address, &pool, &offset
  167311. + ));
  167312. + }
  167313. + else
  167314. +#endif
  167315. + {
  167316. + /* Split the memory address into a pool type and offset. */
  167317. + gcmkERR_BREAK(gckHARDWARE_SplitMemory(
  167318. + kernel->hardware, Address, &pool, &offset
  167319. + ));
  167320. + }
  167321. +
  167322. + /* Dispatch on pool. */
  167323. + switch (pool)
  167324. + {
  167325. + case gcvPOOL_LOCAL_INTERNAL:
  167326. + /* Internal memory. */
  167327. + logical = device->internalLogical;
  167328. + break;
  167329. +
  167330. + case gcvPOOL_LOCAL_EXTERNAL:
  167331. + /* External memory. */
  167332. + logical = device->externalLogical;
  167333. + break;
  167334. +
  167335. + case gcvPOOL_SYSTEM:
  167336. + /* System memory. */
  167337. + logical = device->contiguousBase;
  167338. + break;
  167339. +
  167340. + default:
  167341. + /* Invalid memory pool. */
  167342. + gcmkFOOTER();
  167343. + return gcvSTATUS_INVALID_ARGUMENT;
  167344. + }
  167345. +
  167346. + /* Build logical address of specified address. */
  167347. + * KernelPointer = ((gctUINT8_PTR) logical) + offset;
  167348. +
  167349. + /* Success. */
  167350. + gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
  167351. + return gcvSTATUS_OK;
  167352. + }
  167353. + while (gcvFALSE);
  167354. +
  167355. + /* Return status. */
  167356. + gcmkFOOTER();
  167357. + return status;
  167358. +}
  167359. +#endif
  167360. +
  167361. +/*******************************************************************************
  167362. +**
  167363. +** gckOS_MapUserPointer
  167364. +**
  167365. +** Map a pointer from the user process into the kernel address space.
  167366. +**
  167367. +** INPUT:
  167368. +**
  167369. +** gckOS Os
  167370. +** Pointer to an gckOS object.
  167371. +**
  167372. +** gctPOINTER Pointer
  167373. +** Pointer in user process space that needs to be mapped.
  167374. +**
  167375. +** gctSIZE_T Size
  167376. +** Number of bytes that need to be mapped.
  167377. +**
  167378. +** OUTPUT:
  167379. +**
  167380. +** gctPOINTER * KernelPointer
  167381. +** Pointer to a variable receiving the mapped pointer in kernel address
  167382. +** space.
  167383. +*/
  167384. +gceSTATUS
  167385. +gckOS_MapUserPointer(
  167386. + IN gckOS Os,
  167387. + IN gctPOINTER Pointer,
  167388. + IN gctSIZE_T Size,
  167389. + OUT gctPOINTER * KernelPointer
  167390. + )
  167391. +{
  167392. + gctPOINTER buf = gcvNULL;
  167393. + gctUINT32 len;
  167394. +
  167395. + gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu", Os, Pointer, Size);
  167396. +
  167397. + /* Verify the arguments. */
  167398. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167399. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  167400. + gcmkVERIFY_ARGUMENT(Size > 0);
  167401. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  167402. +
  167403. + buf = kmalloc(Size, GFP_KERNEL | gcdNOWARN);
  167404. + if (buf == gcvNULL)
  167405. + {
  167406. + gcmkTRACE(
  167407. + gcvLEVEL_ERROR,
  167408. + "%s(%d): Failed to allocate memory.",
  167409. + __FUNCTION__, __LINE__
  167410. + );
  167411. +
  167412. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
  167413. + return gcvSTATUS_OUT_OF_MEMORY;
  167414. + }
  167415. +
  167416. + len = copy_from_user(buf, Pointer, Size);
  167417. + if (len != 0)
  167418. + {
  167419. + gcmkTRACE(
  167420. + gcvLEVEL_ERROR,
  167421. + "%s(%d): Failed to copy data from user.",
  167422. + __FUNCTION__, __LINE__
  167423. + );
  167424. +
  167425. + if (buf != gcvNULL)
  167426. + {
  167427. + kfree(buf);
  167428. + }
  167429. +
  167430. + gcmkFOOTER_ARG("*status=%d", gcvSTATUS_GENERIC_IO);
  167431. + return gcvSTATUS_GENERIC_IO;
  167432. + }
  167433. +
  167434. + *KernelPointer = buf;
  167435. +
  167436. + gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
  167437. + return gcvSTATUS_OK;
  167438. +}
  167439. +
  167440. +/*******************************************************************************
  167441. +**
  167442. +** gckOS_UnmapUserPointer
  167443. +**
  167444. +** Unmap a user process pointer from the kernel address space.
  167445. +**
  167446. +** INPUT:
  167447. +**
  167448. +** gckOS Os
  167449. +** Pointer to an gckOS object.
  167450. +**
  167451. +** gctPOINTER Pointer
  167452. +** Pointer in user process space that needs to be unmapped.
  167453. +**
  167454. +** gctSIZE_T Size
  167455. +** Number of bytes that need to be unmapped.
  167456. +**
  167457. +** gctPOINTER KernelPointer
  167458. +** Pointer in kernel address space that needs to be unmapped.
  167459. +**
  167460. +** OUTPUT:
  167461. +**
  167462. +** Nothing.
  167463. +*/
  167464. +gceSTATUS
  167465. +gckOS_UnmapUserPointer(
  167466. + IN gckOS Os,
  167467. + IN gctPOINTER Pointer,
  167468. + IN gctSIZE_T Size,
  167469. + IN gctPOINTER KernelPointer
  167470. + )
  167471. +{
  167472. + gctUINT32 len;
  167473. +
  167474. + gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu KernelPointer=0x%X",
  167475. + Os, Pointer, Size, KernelPointer);
  167476. +
  167477. +
  167478. + /* Verify the arguments. */
  167479. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167480. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  167481. + gcmkVERIFY_ARGUMENT(Size > 0);
  167482. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  167483. +
  167484. + len = copy_to_user(Pointer, KernelPointer, Size);
  167485. +
  167486. + kfree(KernelPointer);
  167487. +
  167488. + if (len != 0)
  167489. + {
  167490. + gcmkTRACE(
  167491. + gcvLEVEL_ERROR,
  167492. + "%s(%d): Failed to copy data to user.",
  167493. + __FUNCTION__, __LINE__
  167494. + );
  167495. +
  167496. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_GENERIC_IO);
  167497. + return gcvSTATUS_GENERIC_IO;
  167498. + }
  167499. +
  167500. + gcmkFOOTER_NO();
  167501. + return gcvSTATUS_OK;
  167502. +}
  167503. +
  167504. +/*******************************************************************************
  167505. +**
  167506. +** gckOS_QueryNeedCopy
  167507. +**
  167508. +** Query whether the memory can be accessed or mapped directly or it has to be
  167509. +** copied.
  167510. +**
  167511. +** INPUT:
  167512. +**
  167513. +** gckOS Os
  167514. +** Pointer to an gckOS object.
  167515. +**
  167516. +** gctUINT32 ProcessID
  167517. +** Process ID of the current process.
  167518. +**
  167519. +** OUTPUT:
  167520. +**
  167521. +** gctBOOL_PTR NeedCopy
  167522. +** Pointer to a boolean receiving gcvTRUE if the memory needs a copy or
  167523. +** gcvFALSE if the memory can be accessed or mapped dircetly.
  167524. +*/
  167525. +gceSTATUS
  167526. +gckOS_QueryNeedCopy(
  167527. + IN gckOS Os,
  167528. + IN gctUINT32 ProcessID,
  167529. + OUT gctBOOL_PTR NeedCopy
  167530. + )
  167531. +{
  167532. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d", Os, ProcessID);
  167533. +
  167534. + /* Verify the arguments. */
  167535. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167536. + gcmkVERIFY_ARGUMENT(NeedCopy != gcvNULL);
  167537. +
  167538. + /* We need to copy data. */
  167539. + *NeedCopy = gcvTRUE;
  167540. +
  167541. + /* Success. */
  167542. + gcmkFOOTER_ARG("*NeedCopy=%d", *NeedCopy);
  167543. + return gcvSTATUS_OK;
  167544. +}
  167545. +
  167546. +/*******************************************************************************
  167547. +**
  167548. +** gckOS_CopyFromUserData
  167549. +**
  167550. +** Copy data from user to kernel memory.
  167551. +**
  167552. +** INPUT:
  167553. +**
  167554. +** gckOS Os
  167555. +** Pointer to an gckOS object.
  167556. +**
  167557. +** gctPOINTER KernelPointer
  167558. +** Pointer to kernel memory.
  167559. +**
  167560. +** gctPOINTER Pointer
  167561. +** Pointer to user memory.
  167562. +**
  167563. +** gctSIZE_T Size
  167564. +** Number of bytes to copy.
  167565. +**
  167566. +** OUTPUT:
  167567. +**
  167568. +** Nothing.
  167569. +*/
  167570. +gceSTATUS
  167571. +gckOS_CopyFromUserData(
  167572. + IN gckOS Os,
  167573. + IN gctPOINTER KernelPointer,
  167574. + IN gctPOINTER Pointer,
  167575. + IN gctSIZE_T Size
  167576. + )
  167577. +{
  167578. + gceSTATUS status;
  167579. +
  167580. + gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
  167581. + Os, KernelPointer, Pointer, Size);
  167582. +
  167583. + /* Verify the arguments. */
  167584. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167585. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  167586. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  167587. + gcmkVERIFY_ARGUMENT(Size > 0);
  167588. +
  167589. + /* Copy data from user. */
  167590. + if (copy_from_user(KernelPointer, Pointer, Size) != 0)
  167591. + {
  167592. + /* Could not copy all the bytes. */
  167593. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  167594. + }
  167595. +
  167596. + /* Success. */
  167597. + gcmkFOOTER_NO();
  167598. + return gcvSTATUS_OK;
  167599. +
  167600. +OnError:
  167601. + /* Return the status. */
  167602. + gcmkFOOTER();
  167603. + return status;
  167604. +}
  167605. +
  167606. +/*******************************************************************************
  167607. +**
  167608. +** gckOS_CopyToUserData
  167609. +**
  167610. +** Copy data from kernel to user memory.
  167611. +**
  167612. +** INPUT:
  167613. +**
  167614. +** gckOS Os
  167615. +** Pointer to an gckOS object.
  167616. +**
  167617. +** gctPOINTER KernelPointer
  167618. +** Pointer to kernel memory.
  167619. +**
  167620. +** gctPOINTER Pointer
  167621. +** Pointer to user memory.
  167622. +**
  167623. +** gctSIZE_T Size
  167624. +** Number of bytes to copy.
  167625. +**
  167626. +** OUTPUT:
  167627. +**
  167628. +** Nothing.
  167629. +*/
  167630. +gceSTATUS
  167631. +gckOS_CopyToUserData(
  167632. + IN gckOS Os,
  167633. + IN gctPOINTER KernelPointer,
  167634. + IN gctPOINTER Pointer,
  167635. + IN gctSIZE_T Size
  167636. + )
  167637. +{
  167638. + gceSTATUS status;
  167639. +
  167640. + gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
  167641. + Os, KernelPointer, Pointer, Size);
  167642. +
  167643. + /* Verify the arguments. */
  167644. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167645. + gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
  167646. + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
  167647. + gcmkVERIFY_ARGUMENT(Size > 0);
  167648. +
  167649. + /* Copy data to user. */
  167650. + if (copy_to_user(Pointer, KernelPointer, Size) != 0)
  167651. + {
  167652. + /* Could not copy all the bytes. */
  167653. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  167654. + }
  167655. +
  167656. + /* Success. */
  167657. + gcmkFOOTER_NO();
  167658. + return gcvSTATUS_OK;
  167659. +
  167660. +OnError:
  167661. + /* Return the status. */
  167662. + gcmkFOOTER();
  167663. + return status;
  167664. +}
  167665. +
  167666. +/*******************************************************************************
  167667. +**
  167668. +** gckOS_WriteMemory
  167669. +**
  167670. +** Write data to a memory.
  167671. +**
  167672. +** INPUT:
  167673. +**
  167674. +** gckOS Os
  167675. +** Pointer to an gckOS object.
  167676. +**
  167677. +** gctPOINTER Address
  167678. +** Address of the memory to write to.
  167679. +**
  167680. +** gctUINT32 Data
  167681. +** Data for register.
  167682. +**
  167683. +** OUTPUT:
  167684. +**
  167685. +** Nothing.
  167686. +*/
  167687. +gceSTATUS
  167688. +gckOS_WriteMemory(
  167689. + IN gckOS Os,
  167690. + IN gctPOINTER Address,
  167691. + IN gctUINT32 Data
  167692. + )
  167693. +{
  167694. + gceSTATUS status;
  167695. + gcmkHEADER_ARG("Os=0x%X Address=0x%X Data=%u", Os, Address, Data);
  167696. +
  167697. + /* Verify the arguments. */
  167698. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  167699. +
  167700. + /* Write memory. */
  167701. + if (access_ok(VERIFY_WRITE, Address, 4))
  167702. + {
  167703. + /* User address. */
  167704. + if(put_user(Data, (gctUINT32*)Address))
  167705. + {
  167706. + gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
  167707. + }
  167708. + }
  167709. + else
  167710. + {
  167711. + /* Kernel address. */
  167712. + *(gctUINT32 *)Address = Data;
  167713. + }
  167714. +
  167715. + /* Success. */
  167716. + gcmkFOOTER_NO();
  167717. + return gcvSTATUS_OK;
  167718. +
  167719. +OnError:
  167720. + gcmkFOOTER();
  167721. + return status;
  167722. +}
  167723. +
  167724. +/*******************************************************************************
  167725. +**
  167726. +** gckOS_MapUserMemory
  167727. +**
  167728. +** Lock down a user buffer and return an DMA'able address to be used by the
  167729. +** hardware to access it.
  167730. +**
  167731. +** INPUT:
  167732. +**
  167733. +** gctPOINTER Memory
  167734. +** Pointer to memory to lock down.
  167735. +**
  167736. +** gctSIZE_T Size
  167737. +** Size in bytes of the memory to lock down.
  167738. +**
  167739. +** OUTPUT:
  167740. +**
  167741. +** gctPOINTER * Info
  167742. +** Pointer to variable receiving the information record required by
  167743. +** gckOS_UnmapUserMemory.
  167744. +**
  167745. +** gctUINT32_PTR Address
  167746. +** Pointer to a variable that will receive the address DMA'able by the
  167747. +** hardware.
  167748. +*/
  167749. +gceSTATUS
  167750. +gckOS_MapUserMemory(
  167751. + IN gckOS Os,
  167752. + IN gceCORE Core,
  167753. + IN gctPOINTER Memory,
  167754. + IN gctUINT32 Physical,
  167755. + IN gctSIZE_T Size,
  167756. + OUT gctPOINTER * Info,
  167757. + OUT gctUINT32_PTR Address
  167758. + )
  167759. +{
  167760. + gceSTATUS status;
  167761. +
  167762. + gcmkHEADER_ARG("Os=0x%x Core=%d Memory=0x%x Size=%lu", Os, Core, Memory, Size);
  167763. +
  167764. +#if gcdSECURE_USER
  167765. + gcmkONERROR(gckOS_AddMapping(Os, *Address, Memory, Size));
  167766. +
  167767. + gcmkFOOTER_NO();
  167768. + return gcvSTATUS_OK;
  167769. +
  167770. +OnError:
  167771. + gcmkFOOTER();
  167772. + return status;
  167773. +#else
  167774. +{
  167775. + gctSIZE_T pageCount, i, j;
  167776. + gctUINT32_PTR pageTable;
  167777. + gctUINT32 address = 0, physical = ~0U;
  167778. + gctUINTPTR_T start, end, memory;
  167779. + gctUINT32 offset;
  167780. + gctINT result = 0;
  167781. +
  167782. + gcsPageInfo_PTR info = gcvNULL;
  167783. + struct page **pages = gcvNULL;
  167784. +
  167785. + /* Verify the arguments. */
  167786. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  167787. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL || Physical != ~0U);
  167788. + gcmkVERIFY_ARGUMENT(Size > 0);
  167789. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  167790. + gcmkVERIFY_ARGUMENT(Address != gcvNULL);
  167791. +
  167792. + do
  167793. + {
  167794. + memory = (gctUINTPTR_T) Memory;
  167795. +
  167796. + /* Get the number of required pages. */
  167797. + end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  167798. + start = memory >> PAGE_SHIFT;
  167799. + pageCount = end - start;
  167800. +
  167801. + gcmkTRACE_ZONE(
  167802. + gcvLEVEL_INFO, gcvZONE_OS,
  167803. + "%s(%d): pageCount: %d.",
  167804. + __FUNCTION__, __LINE__,
  167805. + pageCount
  167806. + );
  167807. +
  167808. + /* Overflow. */
  167809. + if ((memory + Size) < memory)
  167810. + {
  167811. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  167812. + return gcvSTATUS_INVALID_ARGUMENT;
  167813. + }
  167814. +
  167815. + MEMORY_MAP_LOCK(Os);
  167816. +
  167817. + /* Allocate the Info struct. */
  167818. + info = (gcsPageInfo_PTR)kmalloc(sizeof(gcsPageInfo), GFP_KERNEL | gcdNOWARN);
  167819. +
  167820. + if (info == gcvNULL)
  167821. + {
  167822. + status = gcvSTATUS_OUT_OF_MEMORY;
  167823. + break;
  167824. + }
  167825. +
  167826. + /* Allocate the array of page addresses. */
  167827. + pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | gcdNOWARN);
  167828. +
  167829. + if (pages == gcvNULL)
  167830. + {
  167831. + status = gcvSTATUS_OUT_OF_MEMORY;
  167832. + break;
  167833. + }
  167834. +
  167835. + if (Physical != ~0U)
  167836. + {
  167837. + for (i = 0; i < pageCount; i++)
  167838. + {
  167839. + pages[i] = pfn_to_page((Physical >> PAGE_SHIFT) + i);
  167840. + get_page(pages[i]);
  167841. + }
  167842. + }
  167843. + else
  167844. + {
  167845. + /* Get the user pages. */
  167846. + down_read(&current->mm->mmap_sem);
  167847. +
  167848. + result = get_user_pages(current,
  167849. + current->mm,
  167850. + memory & PAGE_MASK,
  167851. + pageCount,
  167852. + 1,
  167853. + 0,
  167854. + pages,
  167855. + gcvNULL
  167856. + );
  167857. +
  167858. + up_read(&current->mm->mmap_sem);
  167859. +
  167860. + if (result <=0 || result < pageCount)
  167861. + {
  167862. + struct vm_area_struct *vma;
  167863. +
  167864. + /* Release the pages if any. */
  167865. + if (result > 0)
  167866. + {
  167867. + for (i = 0; i < result; i++)
  167868. + {
  167869. + if (pages[i] == gcvNULL)
  167870. + {
  167871. + break;
  167872. + }
  167873. +
  167874. + page_cache_release(pages[i]);
  167875. + pages[i] = gcvNULL;
  167876. + }
  167877. +
  167878. + result = 0;
  167879. + }
  167880. +
  167881. + vma = find_vma(current->mm, memory);
  167882. +
  167883. + if (vma && (vma->vm_flags & VM_PFNMAP))
  167884. + {
  167885. + pte_t * pte;
  167886. + spinlock_t * ptl;
  167887. + gctUINTPTR_T logical = memory;
  167888. +
  167889. + for (i = 0; i < pageCount; i++)
  167890. + {
  167891. + pgd_t * pgd = pgd_offset(current->mm, logical);
  167892. + pud_t * pud = pud_offset(pgd, logical);
  167893. +
  167894. + if (pud)
  167895. + {
  167896. + pmd_t * pmd = pmd_offset(pud, logical);
  167897. + pte = pte_offset_map_lock(current->mm, pmd, logical, &ptl);
  167898. + if (!pte)
  167899. + {
  167900. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  167901. + }
  167902. + }
  167903. + else
  167904. + {
  167905. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  167906. + }
  167907. +
  167908. + pages[i] = pte_page(*pte);
  167909. + pte_unmap_unlock(pte, ptl);
  167910. +
  167911. + /* Advance to next. */
  167912. + logical += PAGE_SIZE;
  167913. + }
  167914. + }
  167915. + else
  167916. + {
  167917. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  167918. + }
  167919. +
  167920. + /* Check if this memory is contiguous for old mmu. */
  167921. + if (Os->device->kernels[Core]->hardware->mmuVersion == 0)
  167922. + {
  167923. + for (i = 1; i < pageCount; i++)
  167924. + {
  167925. + if (pages[i] != nth_page(pages[0], i))
  167926. + {
  167927. + /* Non-contiguous. */
  167928. + break;
  167929. + }
  167930. + }
  167931. +
  167932. + if (i == pageCount)
  167933. + {
  167934. + /* Contiguous memory. */
  167935. + physical = page_to_phys(pages[0]) | (memory & ~PAGE_MASK);
  167936. +
  167937. + if (!((physical - Os->device->baseAddress) & 0x80000000))
  167938. + {
  167939. + kfree(pages);
  167940. + pages = gcvNULL;
  167941. +
  167942. + info->pages = gcvNULL;
  167943. + info->pageTable = gcvNULL;
  167944. +
  167945. + MEMORY_MAP_UNLOCK(Os);
  167946. +
  167947. + *Address = physical - Os->device->baseAddress;
  167948. + *Info = info;
  167949. +
  167950. + gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x",
  167951. + *Info, *Address);
  167952. +
  167953. + return gcvSTATUS_OK;
  167954. + }
  167955. + }
  167956. + }
  167957. +
  167958. + /* Reference pages. */
  167959. + for (i = 0; i < pageCount; i++)
  167960. + {
  167961. + get_page(pages[i]);
  167962. + }
  167963. + }
  167964. + }
  167965. +
  167966. + for (i = 0; i < pageCount; i++)
  167967. + {
  167968. +#ifdef CONFIG_ARM
  167969. + gctUINT32 data;
  167970. + get_user(data, (gctUINT32*)((memory & PAGE_MASK) + i * PAGE_SIZE));
  167971. +#endif
  167972. +
  167973. + /* Flush(clean) the data cache. */
  167974. + gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
  167975. + (gctPOINTER)(gctUINTPTR_T)page_to_phys(pages[i]),
  167976. + (gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE,
  167977. + PAGE_SIZE));
  167978. + }
  167979. +
  167980. +#if gcdENABLE_VG
  167981. + if (Core == gcvCORE_VG)
  167982. + {
  167983. + /* Allocate pages inside the page table. */
  167984. + gcmkERR_BREAK(gckVGMMU_AllocatePages(Os->device->kernels[Core]->vg->mmu,
  167985. + pageCount * (PAGE_SIZE/4096),
  167986. + (gctPOINTER *) &pageTable,
  167987. + &address));
  167988. + }
  167989. + else
  167990. +#endif
  167991. + {
  167992. + /* Allocate pages inside the page table. */
  167993. + gcmkERR_BREAK(gckMMU_AllocatePages(Os->device->kernels[Core]->mmu,
  167994. + pageCount * (PAGE_SIZE/4096),
  167995. + (gctPOINTER *) &pageTable,
  167996. + &address));
  167997. + }
  167998. +
  167999. + /* Fill the page table. */
  168000. + for (i = 0; i < pageCount; i++)
  168001. + {
  168002. + gctUINT32 phys;
  168003. + gctUINT32_PTR tab = pageTable + i * (PAGE_SIZE/4096);
  168004. +
  168005. + phys = page_to_phys(pages[i]);
  168006. +
  168007. +#if gcdENABLE_VG
  168008. + if (Core == gcvCORE_VG)
  168009. + {
  168010. + /* Get the physical address from page struct. */
  168011. + gcmkONERROR(
  168012. + gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
  168013. + phys,
  168014. + tab));
  168015. + }
  168016. + else
  168017. +#endif
  168018. + {
  168019. + /* Get the physical address from page struct. */
  168020. + gcmkONERROR(
  168021. + gckMMU_SetPage(Os->device->kernels[Core]->mmu,
  168022. + phys,
  168023. + tab));
  168024. + }
  168025. +
  168026. + for (j = 1; j < (PAGE_SIZE/4096); j++)
  168027. + {
  168028. + pageTable[i * (PAGE_SIZE/4096) + j] = pageTable[i * (PAGE_SIZE/4096)] + 4096 * j;
  168029. + }
  168030. +
  168031. + gcmkTRACE_ZONE(
  168032. + gcvLEVEL_INFO, gcvZONE_OS,
  168033. + "%s(%d): pageTable[%d]: 0x%X 0x%X.",
  168034. + __FUNCTION__, __LINE__,
  168035. + i, phys, pageTable[i]);
  168036. + }
  168037. +
  168038. +#if gcdENABLE_VG
  168039. + if (Core == gcvCORE_VG)
  168040. + {
  168041. + gcmkONERROR(gckVGMMU_Flush(Os->device->kernels[Core]->vg->mmu));
  168042. + }
  168043. + else
  168044. +#endif
  168045. + {
  168046. + gcmkONERROR(gckMMU_Flush(Os->device->kernels[Core]->mmu));
  168047. + }
  168048. +
  168049. + /* Save pointer to page table. */
  168050. + info->pageTable = pageTable;
  168051. + info->pages = pages;
  168052. +
  168053. + *Info = (gctPOINTER) info;
  168054. +
  168055. + gcmkTRACE_ZONE(
  168056. + gcvLEVEL_INFO, gcvZONE_OS,
  168057. + "%s(%d): info->pages: 0x%X, info->pageTable: 0x%X, info: 0x%X.",
  168058. + __FUNCTION__, __LINE__,
  168059. + info->pages,
  168060. + info->pageTable,
  168061. + info
  168062. + );
  168063. +
  168064. + offset = (Physical != ~0U)
  168065. + ? (Physical & ~PAGE_MASK)
  168066. + : (memory & ~PAGE_MASK);
  168067. +
  168068. + /* Return address. */
  168069. + *Address = address + offset;
  168070. +
  168071. + gcmkTRACE_ZONE(
  168072. + gcvLEVEL_INFO, gcvZONE_OS,
  168073. + "%s(%d): Address: 0x%X.",
  168074. + __FUNCTION__, __LINE__,
  168075. + *Address
  168076. + );
  168077. +
  168078. + /* Success. */
  168079. + status = gcvSTATUS_OK;
  168080. + }
  168081. + while (gcvFALSE);
  168082. +
  168083. +OnError:
  168084. +
  168085. + if (gcmIS_ERROR(status))
  168086. + {
  168087. + gcmkTRACE(
  168088. + gcvLEVEL_ERROR,
  168089. + "%s(%d): error occured: %d.",
  168090. + __FUNCTION__, __LINE__,
  168091. + status
  168092. + );
  168093. +
  168094. + /* Release page array. */
  168095. + if (result > 0 && pages != gcvNULL)
  168096. + {
  168097. + gcmkTRACE(
  168098. + gcvLEVEL_ERROR,
  168099. + "%s(%d): error: page table is freed.",
  168100. + __FUNCTION__, __LINE__
  168101. + );
  168102. +
  168103. + for (i = 0; i < result; i++)
  168104. + {
  168105. + if (pages[i] == gcvNULL)
  168106. + {
  168107. + break;
  168108. + }
  168109. + page_cache_release(pages[i]);
  168110. + }
  168111. + }
  168112. +
  168113. + if (info!= gcvNULL && pages != gcvNULL)
  168114. + {
  168115. + gcmkTRACE(
  168116. + gcvLEVEL_ERROR,
  168117. + "%s(%d): error: pages is freed.",
  168118. + __FUNCTION__, __LINE__
  168119. + );
  168120. +
  168121. + /* Free the page table. */
  168122. + kfree(pages);
  168123. + info->pages = gcvNULL;
  168124. + }
  168125. +
  168126. + /* Release page info struct. */
  168127. + if (info != gcvNULL)
  168128. + {
  168129. + gcmkTRACE(
  168130. + gcvLEVEL_ERROR,
  168131. + "%s(%d): error: info is freed.",
  168132. + __FUNCTION__, __LINE__
  168133. + );
  168134. +
  168135. + /* Free the page info struct. */
  168136. + kfree(info);
  168137. + *Info = gcvNULL;
  168138. + }
  168139. + }
  168140. +
  168141. + MEMORY_MAP_UNLOCK(Os);
  168142. +
  168143. + /* Return the status. */
  168144. + if (gcmIS_SUCCESS(status))
  168145. + {
  168146. + gcmkFOOTER_ARG("*Info=0x%X *Address=0x%08x", *Info, *Address);
  168147. + }
  168148. + else
  168149. + {
  168150. + gcmkFOOTER();
  168151. + }
  168152. +
  168153. + return status;
  168154. +}
  168155. +#endif
  168156. +}
  168157. +
  168158. +/*******************************************************************************
  168159. +**
  168160. +** gckOS_UnmapUserMemory
  168161. +**
  168162. +** Unlock a user buffer and that was previously locked down by
  168163. +** gckOS_MapUserMemory.
  168164. +**
  168165. +** INPUT:
  168166. +**
  168167. +** gctPOINTER Memory
  168168. +** Pointer to memory to unlock.
  168169. +**
  168170. +** gctSIZE_T Size
  168171. +** Size in bytes of the memory to unlock.
  168172. +**
  168173. +** gctPOINTER Info
  168174. +** Information record returned by gckOS_MapUserMemory.
  168175. +**
  168176. +** gctUINT32_PTR Address
  168177. +** The address returned by gckOS_MapUserMemory.
  168178. +**
  168179. +** OUTPUT:
  168180. +**
  168181. +** Nothing.
  168182. +*/
  168183. +gceSTATUS
  168184. +gckOS_UnmapUserMemory(
  168185. + IN gckOS Os,
  168186. + IN gceCORE Core,
  168187. + IN gctPOINTER Memory,
  168188. + IN gctSIZE_T Size,
  168189. + IN gctPOINTER Info,
  168190. + IN gctUINT32 Address
  168191. + )
  168192. +{
  168193. + gceSTATUS status;
  168194. +
  168195. + gcmkHEADER_ARG("Os=0x%X Core=%d Memory=0x%X Size=%lu Info=0x%X Address0x%08x",
  168196. + Os, Core, Memory, Size, Info, Address);
  168197. +
  168198. +#if gcdSECURE_USER
  168199. + gcmkONERROR(gckOS_RemoveMapping(Os, Memory, Size));
  168200. +
  168201. + gcmkFOOTER_NO();
  168202. + return gcvSTATUS_OK;
  168203. +
  168204. +OnError:
  168205. + gcmkFOOTER();
  168206. + return status;
  168207. +#else
  168208. +{
  168209. + gctUINTPTR_T memory, start, end;
  168210. + gcsPageInfo_PTR info;
  168211. + gctSIZE_T pageCount, i;
  168212. + struct page **pages;
  168213. +
  168214. + /* Verify the arguments. */
  168215. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168216. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  168217. + gcmkVERIFY_ARGUMENT(Size > 0);
  168218. + gcmkVERIFY_ARGUMENT(Info != gcvNULL);
  168219. +
  168220. + do
  168221. + {
  168222. + info = (gcsPageInfo_PTR) Info;
  168223. +
  168224. + pages = info->pages;
  168225. +
  168226. + gcmkTRACE_ZONE(
  168227. + gcvLEVEL_INFO, gcvZONE_OS,
  168228. + "%s(%d): info=0x%X, pages=0x%X.",
  168229. + __FUNCTION__, __LINE__,
  168230. + info, pages
  168231. + );
  168232. +
  168233. + /* Invalid page array. */
  168234. + if (pages == gcvNULL && info->pageTable == gcvNULL)
  168235. + {
  168236. + kfree(info);
  168237. +
  168238. + gcmkFOOTER_NO();
  168239. + return gcvSTATUS_OK;
  168240. + }
  168241. +
  168242. + memory = (gctUINTPTR_T)Memory;
  168243. + end = (memory + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  168244. + start = memory >> PAGE_SHIFT;
  168245. + pageCount = end - start;
  168246. +
  168247. + /* Overflow. */
  168248. + if ((memory + Size) < memory)
  168249. + {
  168250. + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
  168251. + return gcvSTATUS_INVALID_ARGUMENT;
  168252. + }
  168253. +
  168254. + gcmkTRACE_ZONE(
  168255. + gcvLEVEL_INFO, gcvZONE_OS,
  168256. + "%s(%d): memory: 0x%X, pageCount: %d, pageTable: 0x%X.",
  168257. + __FUNCTION__, __LINE__,
  168258. + memory, pageCount, info->pageTable
  168259. + );
  168260. +
  168261. + MEMORY_MAP_LOCK(Os);
  168262. +
  168263. + gcmkASSERT(info->pageTable != gcvNULL);
  168264. +
  168265. +#if gcdENABLE_VG
  168266. + if (Core == gcvCORE_VG)
  168267. + {
  168268. + /* Free the pages from the MMU. */
  168269. + gcmkERR_BREAK(gckVGMMU_FreePages(Os->device->kernels[Core]->vg->mmu,
  168270. + info->pageTable,
  168271. + pageCount * (PAGE_SIZE/4096)
  168272. + ));
  168273. + }
  168274. + else
  168275. +#endif
  168276. + {
  168277. + /* Free the pages from the MMU. */
  168278. + gcmkERR_BREAK(gckMMU_FreePages(Os->device->kernels[Core]->mmu,
  168279. + info->pageTable,
  168280. + pageCount * (PAGE_SIZE/4096)
  168281. + ));
  168282. + }
  168283. +
  168284. + /* Release the page cache. */
  168285. + if (pages)
  168286. + {
  168287. + for (i = 0; i < pageCount; i++)
  168288. + {
  168289. + gcmkTRACE_ZONE(
  168290. + gcvLEVEL_INFO, gcvZONE_OS,
  168291. + "%s(%d): pages[%d]: 0x%X.",
  168292. + __FUNCTION__, __LINE__,
  168293. + i, pages[i]
  168294. + );
  168295. +
  168296. + if (!PageReserved(pages[i]))
  168297. + {
  168298. + SetPageDirty(pages[i]);
  168299. + }
  168300. +
  168301. + page_cache_release(pages[i]);
  168302. + }
  168303. + }
  168304. +
  168305. + /* Success. */
  168306. + status = gcvSTATUS_OK;
  168307. + }
  168308. + while (gcvFALSE);
  168309. +
  168310. + if (info != gcvNULL)
  168311. + {
  168312. + /* Free the page array. */
  168313. + if (info->pages != gcvNULL)
  168314. + {
  168315. + kfree(info->pages);
  168316. + }
  168317. +
  168318. + kfree(info);
  168319. + }
  168320. +
  168321. + MEMORY_MAP_UNLOCK(Os);
  168322. +
  168323. + /* Return the status. */
  168324. + gcmkFOOTER();
  168325. + return status;
  168326. +}
  168327. +#endif
  168328. +}
  168329. +
  168330. +/*******************************************************************************
  168331. +**
  168332. +** gckOS_GetBaseAddress
  168333. +**
  168334. +** Get the base address for the physical memory.
  168335. +**
  168336. +** INPUT:
  168337. +**
  168338. +** gckOS Os
  168339. +** Pointer to the gckOS object.
  168340. +**
  168341. +** OUTPUT:
  168342. +**
  168343. +** gctUINT32_PTR BaseAddress
  168344. +** Pointer to a variable that will receive the base address.
  168345. +*/
  168346. +gceSTATUS
  168347. +gckOS_GetBaseAddress(
  168348. + IN gckOS Os,
  168349. + OUT gctUINT32_PTR BaseAddress
  168350. + )
  168351. +{
  168352. + gcmkHEADER_ARG("Os=0x%X", Os);
  168353. +
  168354. + /* Verify the arguments. */
  168355. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168356. + gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
  168357. +
  168358. + /* Return base address. */
  168359. + *BaseAddress = Os->device->baseAddress;
  168360. +
  168361. + /* Success. */
  168362. + gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
  168363. + return gcvSTATUS_OK;
  168364. +}
  168365. +
  168366. +gceSTATUS
  168367. +gckOS_SuspendInterrupt(
  168368. + IN gckOS Os
  168369. + )
  168370. +{
  168371. + return gckOS_SuspendInterruptEx(Os, gcvCORE_MAJOR);
  168372. +}
  168373. +
  168374. +gceSTATUS
  168375. +gckOS_SuspendInterruptEx(
  168376. + IN gckOS Os,
  168377. + IN gceCORE Core
  168378. + )
  168379. +{
  168380. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  168381. +
  168382. + /* Verify the arguments. */
  168383. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168384. +
  168385. + disable_irq(Os->device->irqLines[Core]);
  168386. +
  168387. + gcmkFOOTER_NO();
  168388. + return gcvSTATUS_OK;
  168389. +}
  168390. +
  168391. +gceSTATUS
  168392. +gckOS_ResumeInterrupt(
  168393. + IN gckOS Os
  168394. + )
  168395. +{
  168396. + return gckOS_ResumeInterruptEx(Os, gcvCORE_MAJOR);
  168397. +}
  168398. +
  168399. +gceSTATUS
  168400. +gckOS_ResumeInterruptEx(
  168401. + IN gckOS Os,
  168402. + IN gceCORE Core
  168403. + )
  168404. +{
  168405. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  168406. +
  168407. + /* Verify the arguments. */
  168408. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168409. +
  168410. + enable_irq(Os->device->irqLines[Core]);
  168411. +
  168412. + gcmkFOOTER_NO();
  168413. + return gcvSTATUS_OK;
  168414. +}
  168415. +
  168416. +gceSTATUS
  168417. +gckOS_MemCopy(
  168418. + IN gctPOINTER Destination,
  168419. + IN gctCONST_POINTER Source,
  168420. + IN gctSIZE_T Bytes
  168421. + )
  168422. +{
  168423. + gcmkHEADER_ARG("Destination=0x%X Source=0x%X Bytes=%lu",
  168424. + Destination, Source, Bytes);
  168425. +
  168426. + gcmkVERIFY_ARGUMENT(Destination != gcvNULL);
  168427. + gcmkVERIFY_ARGUMENT(Source != gcvNULL);
  168428. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  168429. +
  168430. + memcpy(Destination, Source, Bytes);
  168431. +
  168432. + gcmkFOOTER_NO();
  168433. + return gcvSTATUS_OK;
  168434. +}
  168435. +
  168436. +gceSTATUS
  168437. +gckOS_ZeroMemory(
  168438. + IN gctPOINTER Memory,
  168439. + IN gctSIZE_T Bytes
  168440. + )
  168441. +{
  168442. + gcmkHEADER_ARG("Memory=0x%X Bytes=%lu", Memory, Bytes);
  168443. +
  168444. + gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
  168445. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  168446. +
  168447. + memset(Memory, 0, Bytes);
  168448. +
  168449. + gcmkFOOTER_NO();
  168450. + return gcvSTATUS_OK;
  168451. +}
  168452. +
  168453. +/*******************************************************************************
  168454. +********************************* Cache Control ********************************
  168455. +*******************************************************************************/
  168456. +
  168457. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED && defined(CONFIG_OUTER_CACHE)
  168458. +static inline gceSTATUS
  168459. +outer_func(
  168460. + gceCACHEOPERATION Type,
  168461. + unsigned long Start,
  168462. + unsigned long End
  168463. + )
  168464. +{
  168465. + switch (Type)
  168466. + {
  168467. + case gcvCACHE_CLEAN:
  168468. + outer_clean_range(Start, End);
  168469. + break;
  168470. + case gcvCACHE_INVALIDATE:
  168471. + outer_inv_range(Start, End);
  168472. + break;
  168473. + case gcvCACHE_FLUSH:
  168474. + outer_flush_range(Start, End);
  168475. + break;
  168476. + default:
  168477. + return gcvSTATUS_INVALID_ARGUMENT;
  168478. + break;
  168479. + }
  168480. + return gcvSTATUS_OK;
  168481. +}
  168482. +
  168483. +#if gcdENABLE_OUTER_CACHE_PATCH
  168484. +/*******************************************************************************
  168485. +** _HandleOuterCache
  168486. +**
  168487. +** Handle the outer cache for the specified addresses.
  168488. +**
  168489. +** ARGUMENTS:
  168490. +**
  168491. +** gckOS Os
  168492. +** Pointer to gckOS object.
  168493. +**
  168494. +** gctUINT32 ProcessID
  168495. +** Process ID Logical belongs.
  168496. +**
  168497. +** gctPHYS_ADDR Handle
  168498. +** Physical address handle. If gcvNULL it is video memory.
  168499. +**
  168500. +** gctPOINTER Physical
  168501. +** Physical address to flush.
  168502. +**
  168503. +** gctPOINTER Logical
  168504. +** Logical address to flush.
  168505. +**
  168506. +** gctSIZE_T Bytes
  168507. +** Size of the address range in bytes to flush.
  168508. +**
  168509. +** gceOUTERCACHE_OPERATION Type
  168510. +** Operation need to be execute.
  168511. +*/
  168512. +static gceSTATUS
  168513. +_HandleOuterCache(
  168514. + IN gckOS Os,
  168515. + IN gctUINT32 ProcessID,
  168516. + IN gctPHYS_ADDR Handle,
  168517. + IN gctPOINTER Physical,
  168518. + IN gctPOINTER Logical,
  168519. + IN gctSIZE_T Bytes,
  168520. + IN gceCACHEOPERATION Type
  168521. + )
  168522. +{
  168523. + gceSTATUS status;
  168524. + gctUINT32 i, pageNum;
  168525. + unsigned long paddr;
  168526. + gctPOINTER vaddr;
  168527. +
  168528. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  168529. + Os, ProcessID, Handle, Logical, Bytes);
  168530. +
  168531. + if (Physical != gcvNULL)
  168532. + {
  168533. + /* Non paged memory or gcvPOOL_USER surface */
  168534. + paddr = (unsigned long) Physical;
  168535. + gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
  168536. + }
  168537. + else if ((Handle == gcvNULL)
  168538. + || (Handle != gcvNULL && ((PLINUX_MDL)Handle)->contiguous)
  168539. + )
  168540. + {
  168541. + /* Video Memory or contiguous virtual memory */
  168542. + gcmkONERROR(gckOS_GetPhysicalAddress(Os, Logical, (gctUINT32*)&paddr));
  168543. + gcmkONERROR(outer_func(Type, paddr, paddr + Bytes));
  168544. + }
  168545. + else
  168546. + {
  168547. + /* Non contiguous virtual memory */
  168548. + vaddr = (gctPOINTER)gcmALIGN_BASE((gctUINTPTR_T)Logical, PAGE_SIZE);
  168549. + pageNum = GetPageCount(Bytes, 0);
  168550. +
  168551. + for (i = 0; i < pageNum; i += 1)
  168552. + {
  168553. + gcmkONERROR(_ConvertLogical2Physical(
  168554. + Os,
  168555. + vaddr + PAGE_SIZE * i,
  168556. + ProcessID,
  168557. + (PLINUX_MDL)Handle,
  168558. + (gctUINT32*)&paddr
  168559. + ));
  168560. +
  168561. + gcmkONERROR(outer_func(Type, paddr, paddr + PAGE_SIZE));
  168562. + }
  168563. + }
  168564. +
  168565. + mb();
  168566. +
  168567. + /* Success. */
  168568. + gcmkFOOTER_NO();
  168569. + return gcvSTATUS_OK;
  168570. +
  168571. +OnError:
  168572. + /* Return the status. */
  168573. + gcmkFOOTER();
  168574. + return status;
  168575. +}
  168576. +#endif
  168577. +#endif
  168578. +
  168579. +/*******************************************************************************
  168580. +** gckOS_CacheClean
  168581. +**
  168582. +** Clean the cache for the specified addresses. The GPU is going to need the
  168583. +** data. If the system is allocating memory as non-cachable, this function can
  168584. +** be ignored.
  168585. +**
  168586. +** ARGUMENTS:
  168587. +**
  168588. +** gckOS Os
  168589. +** Pointer to gckOS object.
  168590. +**
  168591. +** gctUINT32 ProcessID
  168592. +** Process ID Logical belongs.
  168593. +**
  168594. +** gctPHYS_ADDR Handle
  168595. +** Physical address handle. If gcvNULL it is video memory.
  168596. +**
  168597. +** gctPOINTER Physical
  168598. +** Physical address to flush.
  168599. +**
  168600. +** gctPOINTER Logical
  168601. +** Logical address to flush.
  168602. +**
  168603. +** gctSIZE_T Bytes
  168604. +** Size of the address range in bytes to flush.
  168605. +*/
  168606. +gceSTATUS
  168607. +gckOS_CacheClean(
  168608. + IN gckOS Os,
  168609. + IN gctUINT32 ProcessID,
  168610. + IN gctPHYS_ADDR Handle,
  168611. + IN gctPOINTER Physical,
  168612. + IN gctPOINTER Logical,
  168613. + IN gctSIZE_T Bytes
  168614. + )
  168615. +{
  168616. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  168617. + Os, ProcessID, Handle, Logical, Bytes);
  168618. +
  168619. + /* Verify the arguments. */
  168620. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168621. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  168622. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  168623. +
  168624. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  168625. +#ifdef CONFIG_ARM
  168626. +
  168627. + /* Inner cache. */
  168628. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
  168629. + dmac_map_area(Logical, Bytes, DMA_TO_DEVICE);
  168630. +# else
  168631. + dmac_clean_range(Logical, Logical + Bytes);
  168632. +# endif
  168633. +
  168634. +#if defined(CONFIG_OUTER_CACHE)
  168635. + /* Outer cache. */
  168636. +#if gcdENABLE_OUTER_CACHE_PATCH
  168637. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_CLEAN);
  168638. +#else
  168639. + outer_clean_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  168640. +#endif
  168641. +#endif
  168642. +
  168643. +#elif defined(CONFIG_MIPS)
  168644. +
  168645. + dma_cache_wback((unsigned long) Logical, Bytes);
  168646. +
  168647. +#elif defined(CONFIG_PPC)
  168648. +
  168649. + /* TODO */
  168650. +
  168651. +#else
  168652. + dma_sync_single_for_device(
  168653. + gcvNULL,
  168654. + (dma_addr_t)Physical,
  168655. + Bytes,
  168656. + DMA_TO_DEVICE);
  168657. +#endif
  168658. +#endif
  168659. +
  168660. + /* Success. */
  168661. + gcmkFOOTER_NO();
  168662. + return gcvSTATUS_OK;
  168663. +}
  168664. +
  168665. +/*******************************************************************************
  168666. +** gckOS_CacheInvalidate
  168667. +**
  168668. +** Invalidate the cache for the specified addresses. The GPU is going to need
  168669. +** data. If the system is allocating memory as non-cachable, this function can
  168670. +** be ignored.
  168671. +**
  168672. +** ARGUMENTS:
  168673. +**
  168674. +** gckOS Os
  168675. +** Pointer to gckOS object.
  168676. +**
  168677. +** gctUINT32 ProcessID
  168678. +** Process ID Logical belongs.
  168679. +**
  168680. +** gctPHYS_ADDR Handle
  168681. +** Physical address handle. If gcvNULL it is video memory.
  168682. +**
  168683. +** gctPOINTER Logical
  168684. +** Logical address to flush.
  168685. +**
  168686. +** gctSIZE_T Bytes
  168687. +** Size of the address range in bytes to flush.
  168688. +*/
  168689. +gceSTATUS
  168690. +gckOS_CacheInvalidate(
  168691. + IN gckOS Os,
  168692. + IN gctUINT32 ProcessID,
  168693. + IN gctPHYS_ADDR Handle,
  168694. + IN gctPOINTER Physical,
  168695. + IN gctPOINTER Logical,
  168696. + IN gctSIZE_T Bytes
  168697. + )
  168698. +{
  168699. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  168700. + Os, ProcessID, Handle, Logical, Bytes);
  168701. +
  168702. + /* Verify the arguments. */
  168703. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168704. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  168705. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  168706. +
  168707. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  168708. +#ifdef CONFIG_ARM
  168709. +
  168710. + /* Inner cache. */
  168711. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
  168712. + dmac_map_area(Logical, Bytes, DMA_FROM_DEVICE);
  168713. +# else
  168714. + dmac_inv_range(Logical, Logical + Bytes);
  168715. +# endif
  168716. +
  168717. +#if defined(CONFIG_OUTER_CACHE)
  168718. + /* Outer cache. */
  168719. +#if gcdENABLE_OUTER_CACHE_PATCH
  168720. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_INVALIDATE);
  168721. +#else
  168722. + outer_inv_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  168723. +#endif
  168724. +#endif
  168725. +
  168726. +#elif defined(CONFIG_MIPS)
  168727. + dma_cache_inv((unsigned long) Logical, Bytes);
  168728. +#elif defined(CONFIG_PPC)
  168729. + /* TODO */
  168730. +#else
  168731. + dma_sync_single_for_device(
  168732. + gcvNULL,
  168733. + (dma_addr_t)Physical,
  168734. + Bytes,
  168735. + DMA_FROM_DEVICE);
  168736. +#endif
  168737. +#endif
  168738. +
  168739. + /* Success. */
  168740. + gcmkFOOTER_NO();
  168741. + return gcvSTATUS_OK;
  168742. +}
  168743. +
  168744. +/*******************************************************************************
  168745. +** gckOS_CacheFlush
  168746. +**
  168747. +** Clean the cache for the specified addresses and invalidate the lines as
  168748. +** well. The GPU is going to need and modify the data. If the system is
  168749. +** allocating memory as non-cachable, this function can be ignored.
  168750. +**
  168751. +** ARGUMENTS:
  168752. +**
  168753. +** gckOS Os
  168754. +** Pointer to gckOS object.
  168755. +**
  168756. +** gctUINT32 ProcessID
  168757. +** Process ID Logical belongs.
  168758. +**
  168759. +** gctPHYS_ADDR Handle
  168760. +** Physical address handle. If gcvNULL it is video memory.
  168761. +**
  168762. +** gctPOINTER Logical
  168763. +** Logical address to flush.
  168764. +**
  168765. +** gctSIZE_T Bytes
  168766. +** Size of the address range in bytes to flush.
  168767. +*/
  168768. +gceSTATUS
  168769. +gckOS_CacheFlush(
  168770. + IN gckOS Os,
  168771. + IN gctUINT32 ProcessID,
  168772. + IN gctPHYS_ADDR Handle,
  168773. + IN gctPOINTER Physical,
  168774. + IN gctPOINTER Logical,
  168775. + IN gctSIZE_T Bytes
  168776. + )
  168777. +{
  168778. + gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=0x%X Bytes=%lu",
  168779. + Os, ProcessID, Handle, Logical, Bytes);
  168780. +
  168781. + /* Verify the arguments. */
  168782. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168783. + gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
  168784. + gcmkVERIFY_ARGUMENT(Bytes > 0);
  168785. +
  168786. +#if !gcdCACHE_FUNCTION_UNIMPLEMENTED
  168787. +#ifdef CONFIG_ARM
  168788. + /* Inner cache. */
  168789. + dmac_flush_range(Logical, Logical + Bytes);
  168790. +
  168791. +#if defined(CONFIG_OUTER_CACHE)
  168792. + /* Outer cache. */
  168793. +#if gcdENABLE_OUTER_CACHE_PATCH
  168794. + _HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_FLUSH);
  168795. +#else
  168796. + outer_flush_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
  168797. +#endif
  168798. +#endif
  168799. +
  168800. +#elif defined(CONFIG_MIPS)
  168801. + dma_cache_wback_inv((unsigned long) Logical, Bytes);
  168802. +#elif defined(CONFIG_PPC)
  168803. + /* TODO */
  168804. +#else
  168805. + dma_sync_single_for_device(
  168806. + gcvNULL,
  168807. + (dma_addr_t)Physical,
  168808. + Bytes,
  168809. + DMA_BIDIRECTIONAL);
  168810. +#endif
  168811. +#endif
  168812. +
  168813. + /* Success. */
  168814. + gcmkFOOTER_NO();
  168815. + return gcvSTATUS_OK;
  168816. +}
  168817. +
  168818. +/*******************************************************************************
  168819. +********************************* Broadcasting *********************************
  168820. +*******************************************************************************/
  168821. +
  168822. +/*******************************************************************************
  168823. +**
  168824. +** gckOS_Broadcast
  168825. +**
  168826. +** System hook for broadcast events from the kernel driver.
  168827. +**
  168828. +** INPUT:
  168829. +**
  168830. +** gckOS Os
  168831. +** Pointer to the gckOS object.
  168832. +**
  168833. +** gckHARDWARE Hardware
  168834. +** Pointer to the gckHARDWARE object.
  168835. +**
  168836. +** gceBROADCAST Reason
  168837. +** Reason for the broadcast. Can be one of the following values:
  168838. +**
  168839. +** gcvBROADCAST_GPU_IDLE
  168840. +** Broadcasted when the kernel driver thinks the GPU might be
  168841. +** idle. This can be used to handle power management.
  168842. +**
  168843. +** gcvBROADCAST_GPU_COMMIT
  168844. +** Broadcasted when any client process commits a command
  168845. +** buffer. This can be used to handle power management.
  168846. +**
  168847. +** gcvBROADCAST_GPU_STUCK
  168848. +** Broadcasted when the kernel driver hits the timeout waiting
  168849. +** for the GPU.
  168850. +**
  168851. +** gcvBROADCAST_FIRST_PROCESS
  168852. +** First process is trying to connect to the kernel.
  168853. +**
  168854. +** gcvBROADCAST_LAST_PROCESS
  168855. +** Last process has detached from the kernel.
  168856. +**
  168857. +** OUTPUT:
  168858. +**
  168859. +** Nothing.
  168860. +*/
  168861. +gceSTATUS
  168862. +gckOS_Broadcast(
  168863. + IN gckOS Os,
  168864. + IN gckHARDWARE Hardware,
  168865. + IN gceBROADCAST Reason
  168866. + )
  168867. +{
  168868. + gceSTATUS status;
  168869. +
  168870. + gcmkHEADER_ARG("Os=0x%X Hardware=0x%X Reason=%d", Os, Hardware, Reason);
  168871. +
  168872. + /* Verify the arguments. */
  168873. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  168874. + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
  168875. +
  168876. + switch (Reason)
  168877. + {
  168878. + case gcvBROADCAST_FIRST_PROCESS:
  168879. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "First process has attached");
  168880. + break;
  168881. +
  168882. + case gcvBROADCAST_LAST_PROCESS:
  168883. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "Last process has detached");
  168884. +
  168885. + /* Put GPU OFF. */
  168886. + gcmkONERROR(
  168887. + gckHARDWARE_SetPowerManagementState(Hardware,
  168888. + gcvPOWER_OFF_BROADCAST));
  168889. + break;
  168890. +
  168891. + case gcvBROADCAST_GPU_IDLE:
  168892. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "GPU idle.");
  168893. +
  168894. + /* Put GPU IDLE. */
  168895. + gcmkONERROR(
  168896. + gckHARDWARE_SetPowerManagementState(Hardware,
  168897. +#if gcdPOWER_SUSNPEND_WHEN_IDLE
  168898. + gcvPOWER_SUSPEND_BROADCAST));
  168899. +#else
  168900. + gcvPOWER_IDLE_BROADCAST));
  168901. +#endif
  168902. +
  168903. + /* Add idle process DB. */
  168904. + gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
  168905. + 1,
  168906. + gcvDB_IDLE,
  168907. + gcvNULL, gcvNULL, 0));
  168908. + break;
  168909. +
  168910. + case gcvBROADCAST_GPU_COMMIT:
  168911. + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "COMMIT has arrived.");
  168912. +
  168913. + /* Add busy process DB. */
  168914. + gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
  168915. + 0,
  168916. + gcvDB_IDLE,
  168917. + gcvNULL, gcvNULL, 0));
  168918. +
  168919. + /* Put GPU ON. */
  168920. + gcmkONERROR(
  168921. + gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON_AUTO));
  168922. + break;
  168923. +
  168924. + case gcvBROADCAST_GPU_STUCK:
  168925. + gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n");
  168926. +#if !gcdENABLE_RECOVERY
  168927. + gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
  168928. +#endif
  168929. + gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
  168930. + break;
  168931. +
  168932. + case gcvBROADCAST_AXI_BUS_ERROR:
  168933. + gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_AXI_BUS_ERROR\n");
  168934. + gcmkONERROR(gckHARDWARE_DumpGPUState(Hardware));
  168935. + gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
  168936. + break;
  168937. + }
  168938. +
  168939. + /* Success. */
  168940. + gcmkFOOTER_NO();
  168941. + return gcvSTATUS_OK;
  168942. +
  168943. +OnError:
  168944. + /* Return the status. */
  168945. + gcmkFOOTER();
  168946. + return status;
  168947. +}
  168948. +
  168949. +/*******************************************************************************
  168950. +**
  168951. +** gckOS_BroadcastHurry
  168952. +**
  168953. +** The GPU is running too slow.
  168954. +**
  168955. +** INPUT:
  168956. +**
  168957. +** gckOS Os
  168958. +** Pointer to the gckOS object.
  168959. +**
  168960. +** gckHARDWARE Hardware
  168961. +** Pointer to the gckHARDWARE object.
  168962. +**
  168963. +** gctUINT Urgency
  168964. +** The higher the number, the higher the urgency to speed up the GPU.
  168965. +** The maximum value is defined by the gcdDYNAMIC_EVENT_THRESHOLD.
  168966. +**
  168967. +** OUTPUT:
  168968. +**
  168969. +** Nothing.
  168970. +*/
  168971. +gceSTATUS
  168972. +gckOS_BroadcastHurry(
  168973. + IN gckOS Os,
  168974. + IN gckHARDWARE Hardware,
  168975. + IN gctUINT Urgency
  168976. + )
  168977. +{
  168978. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Urgency=%u", Os, Hardware, Urgency);
  168979. +
  168980. + /* Do whatever you need to do to speed up the GPU now. */
  168981. +
  168982. + /* Success. */
  168983. + gcmkFOOTER_NO();
  168984. + return gcvSTATUS_OK;
  168985. +}
  168986. +
  168987. +/*******************************************************************************
  168988. +**
  168989. +** gckOS_BroadcastCalibrateSpeed
  168990. +**
  168991. +** Calibrate the speed of the GPU.
  168992. +**
  168993. +** INPUT:
  168994. +**
  168995. +** gckOS Os
  168996. +** Pointer to the gckOS object.
  168997. +**
  168998. +** gckHARDWARE Hardware
  168999. +** Pointer to the gckHARDWARE object.
  169000. +**
  169001. +** gctUINT Idle, Time
  169002. +** Idle/Time will give the percentage the GPU is idle, so you can use
  169003. +** this to calibrate the working point of the GPU.
  169004. +**
  169005. +** OUTPUT:
  169006. +**
  169007. +** Nothing.
  169008. +*/
  169009. +gceSTATUS
  169010. +gckOS_BroadcastCalibrateSpeed(
  169011. + IN gckOS Os,
  169012. + IN gckHARDWARE Hardware,
  169013. + IN gctUINT Idle,
  169014. + IN gctUINT Time
  169015. + )
  169016. +{
  169017. + gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Idle=%u Time=%u",
  169018. + Os, Hardware, Idle, Time);
  169019. +
  169020. + /* Do whatever you need to do to callibrate the GPU speed. */
  169021. +
  169022. + /* Success. */
  169023. + gcmkFOOTER_NO();
  169024. + return gcvSTATUS_OK;
  169025. +}
  169026. +
  169027. +/*******************************************************************************
  169028. +********************************** Semaphores **********************************
  169029. +*******************************************************************************/
  169030. +
  169031. +/*******************************************************************************
  169032. +**
  169033. +** gckOS_CreateSemaphore
  169034. +**
  169035. +** Create a semaphore.
  169036. +**
  169037. +** INPUT:
  169038. +**
  169039. +** gckOS Os
  169040. +** Pointer to the gckOS object.
  169041. +**
  169042. +** OUTPUT:
  169043. +**
  169044. +** gctPOINTER * Semaphore
  169045. +** Pointer to the variable that will receive the created semaphore.
  169046. +*/
  169047. +gceSTATUS
  169048. +gckOS_CreateSemaphore(
  169049. + IN gckOS Os,
  169050. + OUT gctPOINTER * Semaphore
  169051. + )
  169052. +{
  169053. + gceSTATUS status;
  169054. + struct semaphore *sem = gcvNULL;
  169055. +
  169056. + gcmkHEADER_ARG("Os=0x%X", Os);
  169057. +
  169058. + /* Verify the arguments. */
  169059. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169060. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  169061. +
  169062. + /* Allocate the semaphore structure. */
  169063. + sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
  169064. + if (sem == gcvNULL)
  169065. + {
  169066. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  169067. + }
  169068. +
  169069. + /* Initialize the semaphore. */
  169070. + sema_init(sem, 1);
  169071. +
  169072. + /* Return to caller. */
  169073. + *Semaphore = (gctPOINTER) sem;
  169074. +
  169075. + /* Success. */
  169076. + gcmkFOOTER_NO();
  169077. + return gcvSTATUS_OK;
  169078. +
  169079. +OnError:
  169080. + /* Return the status. */
  169081. + gcmkFOOTER();
  169082. + return status;
  169083. +}
  169084. +
  169085. +/*******************************************************************************
  169086. +**
  169087. +** gckOS_AcquireSemaphore
  169088. +**
  169089. +** Acquire a semaphore.
  169090. +**
  169091. +** INPUT:
  169092. +**
  169093. +** gckOS Os
  169094. +** Pointer to the gckOS object.
  169095. +**
  169096. +** gctPOINTER Semaphore
  169097. +** Pointer to the semaphore thet needs to be acquired.
  169098. +**
  169099. +** OUTPUT:
  169100. +**
  169101. +** Nothing.
  169102. +*/
  169103. +gceSTATUS
  169104. +gckOS_AcquireSemaphore(
  169105. + IN gckOS Os,
  169106. + IN gctPOINTER Semaphore
  169107. + )
  169108. +{
  169109. + gceSTATUS status;
  169110. +
  169111. + gcmkHEADER_ARG("Os=0x%08X Semaphore=0x%08X", Os, Semaphore);
  169112. +
  169113. + /* Verify the arguments. */
  169114. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169115. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  169116. +
  169117. + /* Acquire the semaphore. */
  169118. + if (down_interruptible((struct semaphore *) Semaphore))
  169119. + {
  169120. + gcmkONERROR(gcvSTATUS_INTERRUPTED);
  169121. + }
  169122. +
  169123. + /* Success. */
  169124. + gcmkFOOTER_NO();
  169125. + return gcvSTATUS_OK;
  169126. +
  169127. +OnError:
  169128. + /* Return the status. */
  169129. + gcmkFOOTER();
  169130. + return status;
  169131. +}
  169132. +
  169133. +/*******************************************************************************
  169134. +**
  169135. +** gckOS_TryAcquireSemaphore
  169136. +**
  169137. +** Try to acquire a semaphore.
  169138. +**
  169139. +** INPUT:
  169140. +**
  169141. +** gckOS Os
  169142. +** Pointer to the gckOS object.
  169143. +**
  169144. +** gctPOINTER Semaphore
  169145. +** Pointer to the semaphore thet needs to be acquired.
  169146. +**
  169147. +** OUTPUT:
  169148. +**
  169149. +** Nothing.
  169150. +*/
  169151. +gceSTATUS
  169152. +gckOS_TryAcquireSemaphore(
  169153. + IN gckOS Os,
  169154. + IN gctPOINTER Semaphore
  169155. + )
  169156. +{
  169157. + gceSTATUS status;
  169158. +
  169159. + gcmkHEADER_ARG("Os=0x%x", Os);
  169160. +
  169161. + /* Verify the arguments. */
  169162. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169163. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  169164. +
  169165. + /* Acquire the semaphore. */
  169166. + if (down_trylock((struct semaphore *) Semaphore))
  169167. + {
  169168. + /* Timeout. */
  169169. + status = gcvSTATUS_TIMEOUT;
  169170. + gcmkFOOTER();
  169171. + return status;
  169172. + }
  169173. +
  169174. + /* Success. */
  169175. + gcmkFOOTER_NO();
  169176. + return gcvSTATUS_OK;
  169177. +}
  169178. +
  169179. +/*******************************************************************************
  169180. +**
  169181. +** gckOS_ReleaseSemaphore
  169182. +**
  169183. +** Release a previously acquired semaphore.
  169184. +**
  169185. +** INPUT:
  169186. +**
  169187. +** gckOS Os
  169188. +** Pointer to the gckOS object.
  169189. +**
  169190. +** gctPOINTER Semaphore
  169191. +** Pointer to the semaphore thet needs to be released.
  169192. +**
  169193. +** OUTPUT:
  169194. +**
  169195. +** Nothing.
  169196. +*/
  169197. +gceSTATUS
  169198. +gckOS_ReleaseSemaphore(
  169199. + IN gckOS Os,
  169200. + IN gctPOINTER Semaphore
  169201. + )
  169202. +{
  169203. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
  169204. +
  169205. + /* Verify the arguments. */
  169206. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169207. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  169208. +
  169209. + /* Release the semaphore. */
  169210. + up((struct semaphore *) Semaphore);
  169211. +
  169212. + /* Success. */
  169213. + gcmkFOOTER_NO();
  169214. + return gcvSTATUS_OK;
  169215. +}
  169216. +
  169217. +/*******************************************************************************
  169218. +**
  169219. +** gckOS_DestroySemaphore
  169220. +**
  169221. +** Destroy a semaphore.
  169222. +**
  169223. +** INPUT:
  169224. +**
  169225. +** gckOS Os
  169226. +** Pointer to the gckOS object.
  169227. +**
  169228. +** gctPOINTER Semaphore
  169229. +** Pointer to the semaphore thet needs to be destroyed.
  169230. +**
  169231. +** OUTPUT:
  169232. +**
  169233. +** Nothing.
  169234. +*/
  169235. +gceSTATUS
  169236. +gckOS_DestroySemaphore(
  169237. + IN gckOS Os,
  169238. + IN gctPOINTER Semaphore
  169239. + )
  169240. +{
  169241. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
  169242. +
  169243. + /* Verify the arguments. */
  169244. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169245. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  169246. +
  169247. + /* Free the sempahore structure. */
  169248. + kfree(Semaphore);
  169249. +
  169250. + /* Success. */
  169251. + gcmkFOOTER_NO();
  169252. + return gcvSTATUS_OK;
  169253. +}
  169254. +
  169255. +/*******************************************************************************
  169256. +**
  169257. +** gckOS_GetProcessID
  169258. +**
  169259. +** Get current process ID.
  169260. +**
  169261. +** INPUT:
  169262. +**
  169263. +** Nothing.
  169264. +**
  169265. +** OUTPUT:
  169266. +**
  169267. +** gctUINT32_PTR ProcessID
  169268. +** Pointer to the variable that receives the process ID.
  169269. +*/
  169270. +gceSTATUS
  169271. +gckOS_GetProcessID(
  169272. + OUT gctUINT32_PTR ProcessID
  169273. + )
  169274. +{
  169275. + /* Get process ID. */
  169276. + if (ProcessID != gcvNULL)
  169277. + {
  169278. + *ProcessID = _GetProcessID();
  169279. + }
  169280. +
  169281. + /* Success. */
  169282. + return gcvSTATUS_OK;
  169283. +}
  169284. +
  169285. +/*******************************************************************************
  169286. +**
  169287. +** gckOS_GetThreadID
  169288. +**
  169289. +** Get current thread ID.
  169290. +**
  169291. +** INPUT:
  169292. +**
  169293. +** Nothing.
  169294. +**
  169295. +** OUTPUT:
  169296. +**
  169297. +** gctUINT32_PTR ThreadID
  169298. +** Pointer to the variable that receives the thread ID.
  169299. +*/
  169300. +gceSTATUS
  169301. +gckOS_GetThreadID(
  169302. + OUT gctUINT32_PTR ThreadID
  169303. + )
  169304. +{
  169305. + /* Get thread ID. */
  169306. + if (ThreadID != gcvNULL)
  169307. + {
  169308. + *ThreadID = _GetThreadID();
  169309. + }
  169310. +
  169311. + /* Success. */
  169312. + return gcvSTATUS_OK;
  169313. +}
  169314. +
  169315. +/*******************************************************************************
  169316. +**
  169317. +** gckOS_SetGPUPower
  169318. +**
  169319. +** Set the power of the GPU on or off.
  169320. +**
  169321. +** INPUT:
  169322. +**
  169323. +** gckOS Os
  169324. +** Pointer to a gckOS object.
  169325. +**
  169326. +** gckCORE Core
  169327. +** GPU whose power is set.
  169328. +**
  169329. +** gctBOOL Clock
  169330. +** gcvTRUE to turn on the clock, or gcvFALSE to turn off the clock.
  169331. +**
  169332. +** gctBOOL Power
  169333. +** gcvTRUE to turn on the power, or gcvFALSE to turn off the power.
  169334. +**
  169335. +** OUTPUT:
  169336. +**
  169337. +** Nothing.
  169338. +*/
  169339. +gceSTATUS
  169340. +gckOS_SetGPUPower(
  169341. + IN gckOS Os,
  169342. + IN gceCORE Core,
  169343. + IN gctBOOL Clock,
  169344. + IN gctBOOL Power
  169345. + )
  169346. +{
  169347. + struct clk *clk_3dcore = Os->device->clk_3d_core;
  169348. + struct clk *clk_3dshader = Os->device->clk_3d_shader;
  169349. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
  169350. + struct clk *clk_3d_axi = Os->device->clk_3d_axi;
  169351. +#endif
  169352. + struct clk *clk_2dcore = Os->device->clk_2d_core;
  169353. + struct clk *clk_2d_axi = Os->device->clk_2d_axi;
  169354. + struct clk *clk_vg_axi = Os->device->clk_vg_axi;
  169355. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  169356. + int ret;
  169357. +#endif
  169358. +
  169359. + gctBOOL oldClockState = gcvFALSE;
  169360. + gctBOOL oldPowerState = gcvFALSE;
  169361. +
  169362. + gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
  169363. +
  169364. + if (Os->device->kernels[Core] != NULL)
  169365. + {
  169366. +#if gcdENABLE_VG
  169367. + if (Core == gcvCORE_VG)
  169368. + {
  169369. + oldClockState = Os->device->kernels[Core]->vg->hardware->clockState;
  169370. + oldPowerState = Os->device->kernels[Core]->vg->hardware->powerState;
  169371. + }
  169372. + else
  169373. + {
  169374. +#endif
  169375. + oldClockState = Os->device->kernels[Core]->hardware->clockState;
  169376. + oldPowerState = Os->device->kernels[Core]->hardware->powerState;
  169377. +#if gcdENABLE_VG
  169378. + }
  169379. +#endif
  169380. + }
  169381. + if((Power == gcvTRUE) && (oldPowerState == gcvFALSE))
  169382. + {
  169383. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  169384. + if(!IS_ERR(Os->device->gpu_regulator)) {
  169385. + ret = regulator_enable(Os->device->gpu_regulator);
  169386. + if (ret != 0)
  169387. + gckOS_Print("%s(%d): fail to enable pu regulator %d!\n",
  169388. + __FUNCTION__, __LINE__, ret);
  169389. + }
  169390. +#else
  169391. + imx_gpc_power_up_pu(true);
  169392. +#endif
  169393. +
  169394. +#ifdef CONFIG_PM
  169395. + pm_runtime_get_sync(Os->device->pmdev);
  169396. +#endif
  169397. + }
  169398. +
  169399. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  169400. + if (Clock == gcvTRUE) {
  169401. + if (oldClockState == gcvFALSE) {
  169402. + switch (Core) {
  169403. + case gcvCORE_MAJOR:
  169404. + clk_enable(clk_3dcore);
  169405. + if (cpu_is_mx6q())
  169406. + clk_enable(clk_3dshader);
  169407. + break;
  169408. + case gcvCORE_2D:
  169409. + clk_enable(clk_2dcore);
  169410. + clk_enable(clk_2d_axi);
  169411. + break;
  169412. + case gcvCORE_VG:
  169413. + clk_enable(clk_2dcore);
  169414. + clk_enable(clk_vg_axi);
  169415. + break;
  169416. + default:
  169417. + break;
  169418. + }
  169419. + }
  169420. + } else {
  169421. + if (oldClockState == gcvTRUE) {
  169422. + switch (Core) {
  169423. + case gcvCORE_MAJOR:
  169424. + if (cpu_is_mx6q())
  169425. + clk_disable(clk_3dshader);
  169426. + clk_disable(clk_3dcore);
  169427. + break;
  169428. + case gcvCORE_2D:
  169429. + clk_disable(clk_2dcore);
  169430. + clk_disable(clk_2d_axi);
  169431. + break;
  169432. + case gcvCORE_VG:
  169433. + clk_disable(clk_2dcore);
  169434. + clk_disable(clk_vg_axi);
  169435. + break;
  169436. + default:
  169437. + break;
  169438. + }
  169439. + }
  169440. + }
  169441. +#else
  169442. + if (Clock == gcvTRUE) {
  169443. + if (oldClockState == gcvFALSE) {
  169444. + switch (Core) {
  169445. + case gcvCORE_MAJOR:
  169446. + clk_prepare_enable(clk_3dcore);
  169447. + clk_prepare_enable(clk_3dshader);
  169448. + clk_prepare_enable(clk_3d_axi);
  169449. + break;
  169450. + case gcvCORE_2D:
  169451. + clk_prepare_enable(clk_2dcore);
  169452. + clk_prepare_enable(clk_2d_axi);
  169453. + break;
  169454. + case gcvCORE_VG:
  169455. + clk_prepare_enable(clk_2dcore);
  169456. + clk_prepare_enable(clk_vg_axi);
  169457. + break;
  169458. + default:
  169459. + break;
  169460. + }
  169461. + }
  169462. + } else {
  169463. + if (oldClockState == gcvTRUE) {
  169464. + switch (Core) {
  169465. + case gcvCORE_MAJOR:
  169466. + clk_disable_unprepare(clk_3d_axi);
  169467. + clk_disable_unprepare(clk_3dshader);
  169468. + clk_disable_unprepare(clk_3dcore);
  169469. + break;
  169470. + case gcvCORE_2D:
  169471. + clk_disable_unprepare(clk_2d_axi);
  169472. + clk_disable_unprepare(clk_2dcore);
  169473. + break;
  169474. + case gcvCORE_VG:
  169475. + clk_disable_unprepare(clk_vg_axi);
  169476. + clk_disable_unprepare(clk_2dcore);
  169477. + break;
  169478. + default:
  169479. + break;
  169480. + }
  169481. + }
  169482. + }
  169483. +#endif
  169484. + if((Power == gcvFALSE) && (oldPowerState == gcvTRUE))
  169485. + {
  169486. +#ifdef CONFIG_PM
  169487. + pm_runtime_put_sync(Os->device->pmdev);
  169488. +#endif
  169489. +
  169490. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  169491. + if(!IS_ERR(Os->device->gpu_regulator))
  169492. + regulator_disable(Os->device->gpu_regulator);
  169493. +#else
  169494. + imx_gpc_power_up_pu(false);
  169495. +#endif
  169496. +
  169497. + }
  169498. + /* TODO: Put your code here. */
  169499. + gcmkFOOTER_NO();
  169500. + return gcvSTATUS_OK;
  169501. +}
  169502. +
  169503. +/*******************************************************************************
  169504. +**
  169505. +** gckOS_ResetGPU
  169506. +**
  169507. +** Reset the GPU.
  169508. +**
  169509. +** INPUT:
  169510. +**
  169511. +** gckOS Os
  169512. +** Pointer to a gckOS object.
  169513. +**
  169514. +** gckCORE Core
  169515. +** GPU whose power is set.
  169516. +**
  169517. +** OUTPUT:
  169518. +**
  169519. +** Nothing.
  169520. +*/
  169521. +gceSTATUS
  169522. +gckOS_ResetGPU(
  169523. + IN gckOS Os,
  169524. + IN gceCORE Core
  169525. + )
  169526. +{
  169527. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
  169528. +#define SRC_SCR_OFFSET 0
  169529. +#define BP_SRC_SCR_GPU3D_RST 1
  169530. +#define BP_SRC_SCR_GPU2D_RST 4
  169531. + void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
  169532. + gctUINT32 bit_offset,val;
  169533. +
  169534. + gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
  169535. +
  169536. + if(Core == gcvCORE_MAJOR) {
  169537. + bit_offset = BP_SRC_SCR_GPU3D_RST;
  169538. + } else if((Core == gcvCORE_VG)
  169539. + ||(Core == gcvCORE_2D)) {
  169540. + bit_offset = BP_SRC_SCR_GPU2D_RST;
  169541. + } else {
  169542. + return gcvSTATUS_INVALID_CONFIG;
  169543. + }
  169544. + val = __raw_readl(src_base + SRC_SCR_OFFSET);
  169545. + val &= ~(1 << (bit_offset));
  169546. + val |= (1 << (bit_offset));
  169547. + __raw_writel(val, src_base + SRC_SCR_OFFSET);
  169548. +
  169549. + while ((__raw_readl(src_base + SRC_SCR_OFFSET) &
  169550. + (1 << (bit_offset))) != 0) {
  169551. + }
  169552. +
  169553. + gcmkFOOTER_NO();
  169554. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  169555. + struct reset_control *rstc = Os->device->rstc[Core];
  169556. + if (rstc)
  169557. + reset_control_reset(rstc);
  169558. +#else
  169559. + imx_src_reset_gpu((int)Core);
  169560. +#endif
  169561. + return gcvSTATUS_OK;
  169562. +}
  169563. +
  169564. +/*******************************************************************************
  169565. +**
  169566. +** gckOS_PrepareGPUFrequency
  169567. +**
  169568. +** Prepare to set GPU frequency and voltage.
  169569. +**
  169570. +** INPUT:
  169571. +**
  169572. +** gckOS Os
  169573. +** Pointer to a gckOS object.
  169574. +**
  169575. +** gckCORE Core
  169576. +** GPU whose frequency and voltage will be set.
  169577. +**
  169578. +** OUTPUT:
  169579. +**
  169580. +** Nothing.
  169581. +*/
  169582. +gceSTATUS
  169583. +gckOS_PrepareGPUFrequency(
  169584. + IN gckOS Os,
  169585. + IN gceCORE Core
  169586. + )
  169587. +{
  169588. + return gcvSTATUS_OK;
  169589. +}
  169590. +
  169591. +/*******************************************************************************
  169592. +**
  169593. +** gckOS_FinishGPUFrequency
  169594. +**
  169595. +** Finish GPU frequency setting.
  169596. +**
  169597. +** INPUT:
  169598. +**
  169599. +** gckOS Os
  169600. +** Pointer to a gckOS object.
  169601. +**
  169602. +** gckCORE Core
  169603. +** GPU whose frequency and voltage is set.
  169604. +**
  169605. +** OUTPUT:
  169606. +**
  169607. +** Nothing.
  169608. +*/
  169609. +gceSTATUS
  169610. +gckOS_FinishGPUFrequency(
  169611. + IN gckOS Os,
  169612. + IN gceCORE Core
  169613. + )
  169614. +{
  169615. + return gcvSTATUS_OK;
  169616. +}
  169617. +
  169618. +/*******************************************************************************
  169619. +**
  169620. +** gckOS_QueryGPUFrequency
  169621. +**
  169622. +** Query the current frequency of the GPU.
  169623. +**
  169624. +** INPUT:
  169625. +**
  169626. +** gckOS Os
  169627. +** Pointer to a gckOS object.
  169628. +**
  169629. +** gckCORE Core
  169630. +** GPU whose power is set.
  169631. +**
  169632. +** gctUINT32 * Frequency
  169633. +** Pointer to a gctUINT32 to obtain current frequency, in MHz.
  169634. +**
  169635. +** gctUINT8 * Scale
  169636. +** Pointer to a gctUINT8 to obtain current scale(1 - 64).
  169637. +**
  169638. +** OUTPUT:
  169639. +**
  169640. +** Nothing.
  169641. +*/
  169642. +gceSTATUS
  169643. +gckOS_QueryGPUFrequency(
  169644. + IN gckOS Os,
  169645. + IN gceCORE Core,
  169646. + OUT gctUINT32 * Frequency,
  169647. + OUT gctUINT8 * Scale
  169648. + )
  169649. +{
  169650. + return gcvSTATUS_OK;
  169651. +}
  169652. +
  169653. +/*******************************************************************************
  169654. +**
  169655. +** gckOS_SetGPUFrequency
  169656. +**
  169657. +** Set frequency and voltage of the GPU.
  169658. +**
  169659. +** 1. DVFS manager gives the target scale of full frequency, BSP must find
  169660. +** a real frequency according to this scale and board's configure.
  169661. +**
  169662. +** 2. BSP should find a suitable voltage for this frequency.
  169663. +**
  169664. +** 3. BSP must make sure setting take effect before this function returns.
  169665. +**
  169666. +** INPUT:
  169667. +**
  169668. +** gckOS Os
  169669. +** Pointer to a gckOS object.
  169670. +**
  169671. +** gckCORE Core
  169672. +** GPU whose power is set.
  169673. +**
  169674. +** gctUINT8 Scale
  169675. +** Target scale of full frequency, range is [1, 64]. 1 means 1/64 of
  169676. +** full frequency and 64 means 64/64 of full frequency.
  169677. +**
  169678. +** OUTPUT:
  169679. +**
  169680. +** Nothing.
  169681. +*/
  169682. +gceSTATUS
  169683. +gckOS_SetGPUFrequency(
  169684. + IN gckOS Os,
  169685. + IN gceCORE Core,
  169686. + IN gctUINT8 Scale
  169687. + )
  169688. +{
  169689. + return gcvSTATUS_OK;
  169690. +}
  169691. +
  169692. +/*----------------------------------------------------------------------------*/
  169693. +/*----- Profile --------------------------------------------------------------*/
  169694. +
  169695. +gceSTATUS
  169696. +gckOS_GetProfileTick(
  169697. + OUT gctUINT64_PTR Tick
  169698. + )
  169699. +{
  169700. + struct timespec time;
  169701. +
  169702. + ktime_get_ts(&time);
  169703. +
  169704. + *Tick = time.tv_nsec + time.tv_sec * 1000000000ULL;
  169705. +
  169706. + return gcvSTATUS_OK;
  169707. +}
  169708. +
  169709. +gceSTATUS
  169710. +gckOS_QueryProfileTickRate(
  169711. + OUT gctUINT64_PTR TickRate
  169712. + )
  169713. +{
  169714. + struct timespec res;
  169715. +
  169716. + hrtimer_get_res(CLOCK_MONOTONIC, &res);
  169717. +
  169718. + *TickRate = res.tv_nsec + res.tv_sec * 1000000000ULL;
  169719. +
  169720. + return gcvSTATUS_OK;
  169721. +}
  169722. +
  169723. +gctUINT32
  169724. +gckOS_ProfileToMS(
  169725. + IN gctUINT64 Ticks
  169726. + )
  169727. +{
  169728. +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
  169729. + return div_u64(Ticks, 1000000);
  169730. +#else
  169731. + gctUINT64 rem = Ticks;
  169732. + gctUINT64 b = 1000000;
  169733. + gctUINT64 res, d = 1;
  169734. + gctUINT32 high = rem >> 32;
  169735. +
  169736. + /* Reduce the thing a bit first */
  169737. + res = 0;
  169738. + if (high >= 1000000)
  169739. + {
  169740. + high /= 1000000;
  169741. + res = (gctUINT64) high << 32;
  169742. + rem -= (gctUINT64) (high * 1000000) << 32;
  169743. + }
  169744. +
  169745. + while (((gctINT64) b > 0) && (b < rem))
  169746. + {
  169747. + b <<= 1;
  169748. + d <<= 1;
  169749. + }
  169750. +
  169751. + do
  169752. + {
  169753. + if (rem >= b)
  169754. + {
  169755. + rem -= b;
  169756. + res += d;
  169757. + }
  169758. +
  169759. + b >>= 1;
  169760. + d >>= 1;
  169761. + }
  169762. + while (d);
  169763. +
  169764. + return (gctUINT32) res;
  169765. +#endif
  169766. +}
  169767. +
  169768. +/******************************************************************************\
  169769. +******************************* Signal Management ******************************
  169770. +\******************************************************************************/
  169771. +
  169772. +#undef _GC_OBJ_ZONE
  169773. +#define _GC_OBJ_ZONE gcvZONE_SIGNAL
  169774. +
  169775. +/*******************************************************************************
  169776. +**
  169777. +** gckOS_CreateSignal
  169778. +**
  169779. +** Create a new signal.
  169780. +**
  169781. +** INPUT:
  169782. +**
  169783. +** gckOS Os
  169784. +** Pointer to an gckOS object.
  169785. +**
  169786. +** gctBOOL ManualReset
  169787. +** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
  169788. +** order to set the signal to nonsignaled state.
  169789. +** If set to gcvFALSE, the signal will automatically be set to
  169790. +** nonsignaled state by gckOS_WaitSignal function.
  169791. +**
  169792. +** OUTPUT:
  169793. +**
  169794. +** gctSIGNAL * Signal
  169795. +** Pointer to a variable receiving the created gctSIGNAL.
  169796. +*/
  169797. +gceSTATUS
  169798. +gckOS_CreateSignal(
  169799. + IN gckOS Os,
  169800. + IN gctBOOL ManualReset,
  169801. + OUT gctSIGNAL * Signal
  169802. + )
  169803. +{
  169804. + gceSTATUS status;
  169805. + gcsSIGNAL_PTR signal;
  169806. +
  169807. + gcmkHEADER_ARG("Os=0x%X ManualReset=%d", Os, ManualReset);
  169808. +
  169809. + /* Verify the arguments. */
  169810. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169811. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  169812. +
  169813. + /* Create an event structure. */
  169814. + signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL | gcdNOWARN);
  169815. +
  169816. + if (signal == gcvNULL)
  169817. + {
  169818. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  169819. + }
  169820. +
  169821. + /* Save the process ID. */
  169822. + signal->process = (gctHANDLE)(gctUINTPTR_T) _GetProcessID();
  169823. + signal->manualReset = ManualReset;
  169824. + signal->hardware = gcvNULL;
  169825. + init_completion(&signal->obj);
  169826. + atomic_set(&signal->ref, 1);
  169827. +
  169828. + gcmkONERROR(_AllocateIntegerId(&Os->signalDB, signal, &signal->id));
  169829. +
  169830. + *Signal = (gctSIGNAL)(gctUINTPTR_T)signal->id;
  169831. +
  169832. + gcmkFOOTER_ARG("*Signal=0x%X", *Signal);
  169833. + return gcvSTATUS_OK;
  169834. +
  169835. +OnError:
  169836. + if (signal != gcvNULL)
  169837. + {
  169838. + kfree(signal);
  169839. + }
  169840. +
  169841. + gcmkFOOTER_NO();
  169842. + return status;
  169843. +}
  169844. +
  169845. +gceSTATUS
  169846. +gckOS_SignalQueryHardware(
  169847. + IN gckOS Os,
  169848. + IN gctSIGNAL Signal,
  169849. + OUT gckHARDWARE * Hardware
  169850. + )
  169851. +{
  169852. + gceSTATUS status;
  169853. + gcsSIGNAL_PTR signal;
  169854. +
  169855. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
  169856. +
  169857. + /* Verify the arguments. */
  169858. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169859. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  169860. + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
  169861. +
  169862. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  169863. +
  169864. + *Hardware = signal->hardware;
  169865. +
  169866. + gcmkFOOTER_NO();
  169867. + return gcvSTATUS_OK;
  169868. +OnError:
  169869. + gcmkFOOTER();
  169870. + return status;
  169871. +}
  169872. +
  169873. +gceSTATUS
  169874. +gckOS_SignalSetHardware(
  169875. + IN gckOS Os,
  169876. + IN gctSIGNAL Signal,
  169877. + IN gckHARDWARE Hardware
  169878. + )
  169879. +{
  169880. + gceSTATUS status;
  169881. + gcsSIGNAL_PTR signal;
  169882. +
  169883. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
  169884. +
  169885. + /* Verify the arguments. */
  169886. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169887. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  169888. +
  169889. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  169890. +
  169891. + signal->hardware = Hardware;
  169892. +
  169893. + gcmkFOOTER_NO();
  169894. + return gcvSTATUS_OK;
  169895. +OnError:
  169896. + gcmkFOOTER();
  169897. + return status;
  169898. +}
  169899. +
  169900. +/*******************************************************************************
  169901. +**
  169902. +** gckOS_DestroySignal
  169903. +**
  169904. +** Destroy a signal.
  169905. +**
  169906. +** INPUT:
  169907. +**
  169908. +** gckOS Os
  169909. +** Pointer to an gckOS object.
  169910. +**
  169911. +** gctSIGNAL Signal
  169912. +** Pointer to the gctSIGNAL.
  169913. +**
  169914. +** OUTPUT:
  169915. +**
  169916. +** Nothing.
  169917. +*/
  169918. +gceSTATUS
  169919. +gckOS_DestroySignal(
  169920. + IN gckOS Os,
  169921. + IN gctSIGNAL Signal
  169922. + )
  169923. +{
  169924. + gceSTATUS status;
  169925. + gcsSIGNAL_PTR signal;
  169926. + gctBOOL acquired = gcvFALSE;
  169927. +
  169928. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X", Os, Signal);
  169929. +
  169930. + /* Verify the arguments. */
  169931. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  169932. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  169933. +
  169934. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
  169935. + acquired = gcvTRUE;
  169936. +
  169937. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  169938. +
  169939. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  169940. +
  169941. + if (atomic_dec_and_test(&signal->ref))
  169942. + {
  169943. + gcmkVERIFY_OK(_DestroyIntegerId(&Os->signalDB, signal->id));
  169944. +
  169945. + /* Free the sgianl. */
  169946. + kfree(signal);
  169947. + }
  169948. +
  169949. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  169950. + acquired = gcvFALSE;
  169951. +
  169952. + /* Success. */
  169953. + gcmkFOOTER_NO();
  169954. + return gcvSTATUS_OK;
  169955. +
  169956. +OnError:
  169957. + if (acquired)
  169958. + {
  169959. + /* Release the mutex. */
  169960. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  169961. + }
  169962. +
  169963. + gcmkFOOTER();
  169964. + return status;
  169965. +}
  169966. +
  169967. +/*******************************************************************************
  169968. +**
  169969. +** gckOS_Signal
  169970. +**
  169971. +** Set a state of the specified signal.
  169972. +**
  169973. +** INPUT:
  169974. +**
  169975. +** gckOS Os
  169976. +** Pointer to an gckOS object.
  169977. +**
  169978. +** gctSIGNAL Signal
  169979. +** Pointer to the gctSIGNAL.
  169980. +**
  169981. +** gctBOOL State
  169982. +** If gcvTRUE, the signal will be set to signaled state.
  169983. +** If gcvFALSE, the signal will be set to nonsignaled state.
  169984. +**
  169985. +** OUTPUT:
  169986. +**
  169987. +** Nothing.
  169988. +*/
  169989. +gceSTATUS
  169990. +gckOS_Signal(
  169991. + IN gckOS Os,
  169992. + IN gctSIGNAL Signal,
  169993. + IN gctBOOL State
  169994. + )
  169995. +{
  169996. + gceSTATUS status;
  169997. + gcsSIGNAL_PTR signal;
  169998. + gctBOOL acquired = gcvFALSE;
  169999. +
  170000. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X State=%d", Os, Signal, State);
  170001. +
  170002. + /* Verify the arguments. */
  170003. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170004. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  170005. +
  170006. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->signalMutex, gcvINFINITE));
  170007. + acquired = gcvTRUE;
  170008. +
  170009. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  170010. +
  170011. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  170012. +
  170013. + if (State)
  170014. + {
  170015. + /* unbind the signal from hardware. */
  170016. + signal->hardware = gcvNULL;
  170017. +
  170018. + /* Set the event to a signaled state. */
  170019. + complete(&signal->obj);
  170020. + }
  170021. + else
  170022. + {
  170023. + /* Set the event to an unsignaled state. */
  170024. + reinit_completion(&signal->obj);
  170025. + }
  170026. +
  170027. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  170028. + acquired = gcvFALSE;
  170029. +
  170030. + /* Success. */
  170031. + gcmkFOOTER_NO();
  170032. + return gcvSTATUS_OK;
  170033. +
  170034. +OnError:
  170035. + if (acquired)
  170036. + {
  170037. + /* Release the mutex. */
  170038. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->signalMutex));
  170039. + }
  170040. +
  170041. + gcmkFOOTER();
  170042. + return status;
  170043. +}
  170044. +
  170045. +#if gcdENABLE_VG
  170046. +gceSTATUS
  170047. +gckOS_SetSignalVG(
  170048. + IN gckOS Os,
  170049. + IN gctHANDLE Process,
  170050. + IN gctSIGNAL Signal
  170051. + )
  170052. +{
  170053. + gceSTATUS status;
  170054. + gctINT result;
  170055. + struct task_struct * userTask;
  170056. + struct siginfo info;
  170057. +
  170058. + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
  170059. +
  170060. + if (userTask != gcvNULL)
  170061. + {
  170062. + info.si_signo = 48;
  170063. + info.si_code = __SI_CODE(__SI_RT, SI_KERNEL);
  170064. + info.si_pid = 0;
  170065. + info.si_uid = 0;
  170066. + info.si_ptr = (gctPOINTER) Signal;
  170067. +
  170068. + /* Signals with numbers between 32 and 63 are real-time,
  170069. + send a real-time signal to the user process. */
  170070. + result = send_sig_info(48, &info, userTask);
  170071. +
  170072. + printk("gckOS_SetSignalVG:0x%x\n", result);
  170073. + /* Error? */
  170074. + if (result < 0)
  170075. + {
  170076. + status = gcvSTATUS_GENERIC_IO;
  170077. +
  170078. + gcmkTRACE(
  170079. + gcvLEVEL_ERROR,
  170080. + "%s(%d): an error has occurred.\n",
  170081. + __FUNCTION__, __LINE__
  170082. + );
  170083. + }
  170084. + else
  170085. + {
  170086. + status = gcvSTATUS_OK;
  170087. + }
  170088. + }
  170089. + else
  170090. + {
  170091. + status = gcvSTATUS_GENERIC_IO;
  170092. +
  170093. + gcmkTRACE(
  170094. + gcvLEVEL_ERROR,
  170095. + "%s(%d): an error has occurred.\n",
  170096. + __FUNCTION__, __LINE__
  170097. + );
  170098. + }
  170099. +
  170100. + /* Return status. */
  170101. + return status;
  170102. +}
  170103. +#endif
  170104. +
  170105. +/*******************************************************************************
  170106. +**
  170107. +** gckOS_UserSignal
  170108. +**
  170109. +** Set the specified signal which is owned by a process to signaled state.
  170110. +**
  170111. +** INPUT:
  170112. +**
  170113. +** gckOS Os
  170114. +** Pointer to an gckOS object.
  170115. +**
  170116. +** gctSIGNAL Signal
  170117. +** Pointer to the gctSIGNAL.
  170118. +**
  170119. +** gctHANDLE Process
  170120. +** Handle of process owning the signal.
  170121. +**
  170122. +** OUTPUT:
  170123. +**
  170124. +** Nothing.
  170125. +*/
  170126. +gceSTATUS
  170127. +gckOS_UserSignal(
  170128. + IN gckOS Os,
  170129. + IN gctSIGNAL Signal,
  170130. + IN gctHANDLE Process
  170131. + )
  170132. +{
  170133. + gceSTATUS status;
  170134. + gctSIGNAL signal;
  170135. +
  170136. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=%d",
  170137. + Os, Signal, (gctINT32)(gctUINTPTR_T)Process);
  170138. +
  170139. + /* Map the signal into kernel space. */
  170140. + gcmkONERROR(gckOS_MapSignal(Os, Signal, Process, &signal));
  170141. +
  170142. + /* Signal. */
  170143. + status = gckOS_Signal(Os, signal, gcvTRUE);
  170144. +
  170145. + /* Unmap the signal */
  170146. + gcmkVERIFY_OK(gckOS_UnmapSignal(Os, Signal));
  170147. +
  170148. + gcmkFOOTER();
  170149. + return status;
  170150. +
  170151. +OnError:
  170152. + /* Return the status. */
  170153. + gcmkFOOTER();
  170154. + return status;
  170155. +}
  170156. +
  170157. +/*******************************************************************************
  170158. +**
  170159. +** gckOS_WaitSignal
  170160. +**
  170161. +** Wait for a signal to become signaled.
  170162. +**
  170163. +** INPUT:
  170164. +**
  170165. +** gckOS Os
  170166. +** Pointer to an gckOS object.
  170167. +**
  170168. +** gctSIGNAL Signal
  170169. +** Pointer to the gctSIGNAL.
  170170. +**
  170171. +** gctUINT32 Wait
  170172. +** Number of milliseconds to wait.
  170173. +** Pass the value of gcvINFINITE for an infinite wait.
  170174. +**
  170175. +** OUTPUT:
  170176. +**
  170177. +** Nothing.
  170178. +*/
  170179. +gceSTATUS
  170180. +gckOS_WaitSignal(
  170181. + IN gckOS Os,
  170182. + IN gctSIGNAL Signal,
  170183. + IN gctUINT32 Wait
  170184. + )
  170185. +{
  170186. + gceSTATUS status = gcvSTATUS_OK;
  170187. + gcsSIGNAL_PTR signal;
  170188. +
  170189. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Wait=0x%08X", Os, Signal, Wait);
  170190. +
  170191. + /* Verify the arguments. */
  170192. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170193. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  170194. +
  170195. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  170196. +
  170197. + gcmkASSERT(signal->id == (gctUINT32)(gctUINTPTR_T)Signal);
  170198. +
  170199. + might_sleep();
  170200. +
  170201. + spin_lock_irq(&signal->obj.wait.lock);
  170202. +
  170203. + if (signal->obj.done)
  170204. + {
  170205. + if (!signal->manualReset)
  170206. + {
  170207. + signal->obj.done = 0;
  170208. + }
  170209. +
  170210. + status = gcvSTATUS_OK;
  170211. + }
  170212. + else if (Wait == 0)
  170213. + {
  170214. + status = gcvSTATUS_TIMEOUT;
  170215. + }
  170216. + else
  170217. + {
  170218. + /* Convert wait to milliseconds. */
  170219. +#if gcdDETECT_TIMEOUT
  170220. + gctINT timeout = (Wait == gcvINFINITE)
  170221. + ? gcdINFINITE_TIMEOUT * HZ / 1000
  170222. + : Wait * HZ / 1000;
  170223. +
  170224. + gctUINT complained = 0;
  170225. +#else
  170226. + gctINT timeout = (Wait == gcvINFINITE)
  170227. + ? MAX_SCHEDULE_TIMEOUT
  170228. + : Wait * HZ / 1000;
  170229. +#endif
  170230. +
  170231. + DECLARE_WAITQUEUE(wait, current);
  170232. + wait.flags |= WQ_FLAG_EXCLUSIVE;
  170233. + __add_wait_queue_tail(&signal->obj.wait, &wait);
  170234. +
  170235. + while (gcvTRUE)
  170236. + {
  170237. + if (signal_pending(current))
  170238. + {
  170239. + /* Interrupt received. */
  170240. + status = gcvSTATUS_INTERRUPTED;
  170241. + break;
  170242. + }
  170243. +
  170244. + __set_current_state(TASK_INTERRUPTIBLE);
  170245. + spin_unlock_irq(&signal->obj.wait.lock);
  170246. + timeout = schedule_timeout(timeout);
  170247. + spin_lock_irq(&signal->obj.wait.lock);
  170248. +
  170249. + if (signal->obj.done)
  170250. + {
  170251. + if (!signal->manualReset)
  170252. + {
  170253. + signal->obj.done = 0;
  170254. + }
  170255. +
  170256. + status = gcvSTATUS_OK;
  170257. + break;
  170258. + }
  170259. +
  170260. +#if gcdDETECT_TIMEOUT
  170261. + if ((Wait == gcvINFINITE) && (timeout == 0))
  170262. + {
  170263. + gctUINT32 dmaAddress1, dmaAddress2;
  170264. + gctUINT32 dmaState1, dmaState2;
  170265. +
  170266. + dmaState1 = dmaState2 =
  170267. + dmaAddress1 = dmaAddress2 = 0;
  170268. +
  170269. + /* Verify whether DMA is running. */
  170270. + gcmkVERIFY_OK(_VerifyDMA(
  170271. + Os, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
  170272. + ));
  170273. +
  170274. +#if gcdDETECT_DMA_ADDRESS
  170275. + /* Dump only if DMA appears stuck. */
  170276. + if (
  170277. + (dmaAddress1 == dmaAddress2)
  170278. +#if gcdDETECT_DMA_STATE
  170279. + && (dmaState1 == dmaState2)
  170280. +#endif
  170281. + )
  170282. +#endif
  170283. + {
  170284. + /* Increment complain count. */
  170285. + complained += 1;
  170286. +
  170287. + gcmkVERIFY_OK(_DumpGPUState(Os, gcvCORE_MAJOR));
  170288. +
  170289. + gcmkPRINT(
  170290. + "%s(%d): signal 0x%X; forced message flush (%d).",
  170291. + __FUNCTION__, __LINE__, Signal, complained
  170292. + );
  170293. +
  170294. + /* Flush the debug cache. */
  170295. + gcmkDEBUGFLUSH(dmaAddress2);
  170296. + }
  170297. +
  170298. + /* Reset timeout. */
  170299. + timeout = gcdINFINITE_TIMEOUT * HZ / 1000;
  170300. + }
  170301. +#endif
  170302. +
  170303. + if (timeout == 0)
  170304. + {
  170305. +
  170306. + status = gcvSTATUS_TIMEOUT;
  170307. + break;
  170308. + }
  170309. + }
  170310. +
  170311. + __remove_wait_queue(&signal->obj.wait, &wait);
  170312. +
  170313. +#if gcdDETECT_TIMEOUT
  170314. + if (complained)
  170315. + {
  170316. + gcmkPRINT(
  170317. + "%s(%d): signal=0x%X; waiting done; status=%d",
  170318. + __FUNCTION__, __LINE__, Signal, status
  170319. + );
  170320. + }
  170321. +#endif
  170322. + }
  170323. +
  170324. + spin_unlock_irq(&signal->obj.wait.lock);
  170325. +
  170326. +OnError:
  170327. + /* Return status. */
  170328. + gcmkFOOTER_ARG("Signal=0x%X status=%d", Signal, status);
  170329. + return status;
  170330. +}
  170331. +
  170332. +/*******************************************************************************
  170333. +**
  170334. +** gckOS_MapSignal
  170335. +**
  170336. +** Map a signal in to the current process space.
  170337. +**
  170338. +** INPUT:
  170339. +**
  170340. +** gckOS Os
  170341. +** Pointer to an gckOS object.
  170342. +**
  170343. +** gctSIGNAL Signal
  170344. +** Pointer to tha gctSIGNAL to map.
  170345. +**
  170346. +** gctHANDLE Process
  170347. +** Handle of process owning the signal.
  170348. +**
  170349. +** OUTPUT:
  170350. +**
  170351. +** gctSIGNAL * MappedSignal
  170352. +** Pointer to a variable receiving the mapped gctSIGNAL.
  170353. +*/
  170354. +gceSTATUS
  170355. +gckOS_MapSignal(
  170356. + IN gckOS Os,
  170357. + IN gctSIGNAL Signal,
  170358. + IN gctHANDLE Process,
  170359. + OUT gctSIGNAL * MappedSignal
  170360. + )
  170361. +{
  170362. + gceSTATUS status;
  170363. + gcsSIGNAL_PTR signal;
  170364. + gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=0x%X", Os, Signal, Process);
  170365. +
  170366. + gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
  170367. + gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
  170368. +
  170369. + gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)(gctUINTPTR_T)Signal, (gctPOINTER)&signal));
  170370. +
  170371. + if(atomic_inc_return(&signal->ref) <= 1)
  170372. + {
  170373. + /* The previous value is 0, it has been deleted. */
  170374. + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
  170375. + }
  170376. +
  170377. + *MappedSignal = (gctSIGNAL) Signal;
  170378. +
  170379. + /* Success. */
  170380. + gcmkFOOTER_ARG("*MappedSignal=0x%X", *MappedSignal);
  170381. + return gcvSTATUS_OK;
  170382. +
  170383. +OnError:
  170384. + gcmkFOOTER_NO();
  170385. + return status;
  170386. +}
  170387. +
  170388. +/*******************************************************************************
  170389. +**
  170390. +** gckOS_UnmapSignal
  170391. +**
  170392. +** Unmap a signal .
  170393. +**
  170394. +** INPUT:
  170395. +**
  170396. +** gckOS Os
  170397. +** Pointer to an gckOS object.
  170398. +**
  170399. +** gctSIGNAL Signal
  170400. +** Pointer to that gctSIGNAL mapped.
  170401. +*/
  170402. +gceSTATUS
  170403. +gckOS_UnmapSignal(
  170404. + IN gckOS Os,
  170405. + IN gctSIGNAL Signal
  170406. + )
  170407. +{
  170408. + return gckOS_DestroySignal(Os, Signal);
  170409. +}
  170410. +
  170411. +/*******************************************************************************
  170412. +**
  170413. +** gckOS_CreateUserSignal
  170414. +**
  170415. +** Create a new signal to be used in the user space.
  170416. +**
  170417. +** INPUT:
  170418. +**
  170419. +** gckOS Os
  170420. +** Pointer to an gckOS object.
  170421. +**
  170422. +** gctBOOL ManualReset
  170423. +** If set to gcvTRUE, gckOS_Signal with gcvFALSE must be called in
  170424. +** order to set the signal to nonsignaled state.
  170425. +** If set to gcvFALSE, the signal will automatically be set to
  170426. +** nonsignaled state by gckOS_WaitSignal function.
  170427. +**
  170428. +** OUTPUT:
  170429. +**
  170430. +** gctINT * SignalID
  170431. +** Pointer to a variable receiving the created signal's ID.
  170432. +*/
  170433. +gceSTATUS
  170434. +gckOS_CreateUserSignal(
  170435. + IN gckOS Os,
  170436. + IN gctBOOL ManualReset,
  170437. + OUT gctINT * SignalID
  170438. + )
  170439. +{
  170440. + gceSTATUS status;
  170441. + gctSIZE_T signal;
  170442. +
  170443. + /* Create a new signal. */
  170444. + status = gckOS_CreateSignal(Os, ManualReset, (gctSIGNAL *) &signal);
  170445. + *SignalID = (gctINT) signal;
  170446. +
  170447. + return status;
  170448. +}
  170449. +
  170450. +/*******************************************************************************
  170451. +**
  170452. +** gckOS_DestroyUserSignal
  170453. +**
  170454. +** Destroy a signal to be used in the user space.
  170455. +**
  170456. +** INPUT:
  170457. +**
  170458. +** gckOS Os
  170459. +** Pointer to an gckOS object.
  170460. +**
  170461. +** gctINT SignalID
  170462. +** The signal's ID.
  170463. +**
  170464. +** OUTPUT:
  170465. +**
  170466. +** Nothing.
  170467. +*/
  170468. +gceSTATUS
  170469. +gckOS_DestroyUserSignal(
  170470. + IN gckOS Os,
  170471. + IN gctINT SignalID
  170472. + )
  170473. +{
  170474. + return gckOS_DestroySignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID);
  170475. +}
  170476. +
  170477. +/*******************************************************************************
  170478. +**
  170479. +** gckOS_WaitUserSignal
  170480. +**
  170481. +** Wait for a signal used in the user mode to become signaled.
  170482. +**
  170483. +** INPUT:
  170484. +**
  170485. +** gckOS Os
  170486. +** Pointer to an gckOS object.
  170487. +**
  170488. +** gctINT SignalID
  170489. +** Signal ID.
  170490. +**
  170491. +** gctUINT32 Wait
  170492. +** Number of milliseconds to wait.
  170493. +** Pass the value of gcvINFINITE for an infinite wait.
  170494. +**
  170495. +** OUTPUT:
  170496. +**
  170497. +** Nothing.
  170498. +*/
  170499. +gceSTATUS
  170500. +gckOS_WaitUserSignal(
  170501. + IN gckOS Os,
  170502. + IN gctINT SignalID,
  170503. + IN gctUINT32 Wait
  170504. + )
  170505. +{
  170506. + return gckOS_WaitSignal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, Wait);
  170507. +}
  170508. +
  170509. +/*******************************************************************************
  170510. +**
  170511. +** gckOS_SignalUserSignal
  170512. +**
  170513. +** Set a state of the specified signal to be used in the user space.
  170514. +**
  170515. +** INPUT:
  170516. +**
  170517. +** gckOS Os
  170518. +** Pointer to an gckOS object.
  170519. +**
  170520. +** gctINT SignalID
  170521. +** SignalID.
  170522. +**
  170523. +** gctBOOL State
  170524. +** If gcvTRUE, the signal will be set to signaled state.
  170525. +** If gcvFALSE, the signal will be set to nonsignaled state.
  170526. +**
  170527. +** OUTPUT:
  170528. +**
  170529. +** Nothing.
  170530. +*/
  170531. +gceSTATUS
  170532. +gckOS_SignalUserSignal(
  170533. + IN gckOS Os,
  170534. + IN gctINT SignalID,
  170535. + IN gctBOOL State
  170536. + )
  170537. +{
  170538. + return gckOS_Signal(Os, (gctSIGNAL)(gctUINTPTR_T)SignalID, State);
  170539. +}
  170540. +
  170541. +#if gcdENABLE_VG
  170542. +gceSTATUS
  170543. +gckOS_CreateSemaphoreVG(
  170544. + IN gckOS Os,
  170545. + OUT gctSEMAPHORE * Semaphore
  170546. + )
  170547. +{
  170548. + gceSTATUS status;
  170549. + struct semaphore * newSemaphore;
  170550. +
  170551. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  170552. + /* Verify the arguments. */
  170553. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170554. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  170555. +
  170556. + do
  170557. + {
  170558. + /* Allocate the semaphore structure. */
  170559. + newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | gcdNOWARN);
  170560. + if (newSemaphore == gcvNULL)
  170561. + {
  170562. + gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
  170563. + }
  170564. +
  170565. + /* Initialize the semaphore. */
  170566. + sema_init(newSemaphore, 0);
  170567. +
  170568. + /* Set the handle. */
  170569. + * Semaphore = (gctSEMAPHORE) newSemaphore;
  170570. +
  170571. + /* Success. */
  170572. + status = gcvSTATUS_OK;
  170573. + }
  170574. + while (gcvFALSE);
  170575. +
  170576. + gcmkFOOTER();
  170577. + /* Return the status. */
  170578. + return status;
  170579. +}
  170580. +
  170581. +
  170582. +gceSTATUS
  170583. +gckOS_IncrementSemaphore(
  170584. + IN gckOS Os,
  170585. + IN gctSEMAPHORE Semaphore
  170586. + )
  170587. +{
  170588. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  170589. + /* Verify the arguments. */
  170590. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170591. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  170592. +
  170593. + /* Increment the semaphore's count. */
  170594. + up((struct semaphore *) Semaphore);
  170595. +
  170596. + gcmkFOOTER_NO();
  170597. + /* Success. */
  170598. + return gcvSTATUS_OK;
  170599. +}
  170600. +
  170601. +gceSTATUS
  170602. +gckOS_DecrementSemaphore(
  170603. + IN gckOS Os,
  170604. + IN gctSEMAPHORE Semaphore
  170605. + )
  170606. +{
  170607. + gceSTATUS status;
  170608. + gctINT result;
  170609. +
  170610. + gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
  170611. + /* Verify the arguments. */
  170612. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170613. + gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
  170614. +
  170615. + do
  170616. + {
  170617. + /* Decrement the semaphore's count. If the count is zero, wait
  170618. + until it gets incremented. */
  170619. + result = down_interruptible((struct semaphore *) Semaphore);
  170620. +
  170621. + /* Signal received? */
  170622. + if (result != 0)
  170623. + {
  170624. + status = gcvSTATUS_TERMINATE;
  170625. + break;
  170626. + }
  170627. +
  170628. + /* Success. */
  170629. + status = gcvSTATUS_OK;
  170630. + }
  170631. + while (gcvFALSE);
  170632. +
  170633. + gcmkFOOTER();
  170634. + /* Return the status. */
  170635. + return status;
  170636. +}
  170637. +
  170638. +/*******************************************************************************
  170639. +**
  170640. +** gckOS_SetSignal
  170641. +**
  170642. +** Set the specified signal to signaled state.
  170643. +**
  170644. +** INPUT:
  170645. +**
  170646. +** gckOS Os
  170647. +** Pointer to the gckOS object.
  170648. +**
  170649. +** gctHANDLE Process
  170650. +** Handle of process owning the signal.
  170651. +**
  170652. +** gctSIGNAL Signal
  170653. +** Pointer to the gctSIGNAL.
  170654. +**
  170655. +** OUTPUT:
  170656. +**
  170657. +** Nothing.
  170658. +*/
  170659. +gceSTATUS
  170660. +gckOS_SetSignal(
  170661. + IN gckOS Os,
  170662. + IN gctHANDLE Process,
  170663. + IN gctSIGNAL Signal
  170664. + )
  170665. +{
  170666. + gceSTATUS status;
  170667. + gctINT result;
  170668. + struct task_struct * userTask;
  170669. + struct siginfo info;
  170670. +
  170671. + userTask = FIND_TASK_BY_PID((pid_t)(gctUINTPTR_T) Process);
  170672. +
  170673. + if (userTask != gcvNULL)
  170674. + {
  170675. + info.si_signo = 48;
  170676. + info.si_code = __SI_CODE(__SI_RT, SI_KERNEL);
  170677. + info.si_pid = 0;
  170678. + info.si_uid = 0;
  170679. + info.si_ptr = (gctPOINTER) Signal;
  170680. +
  170681. + /* Signals with numbers between 32 and 63 are real-time,
  170682. + send a real-time signal to the user process. */
  170683. + result = send_sig_info(48, &info, userTask);
  170684. +
  170685. + /* Error? */
  170686. + if (result < 0)
  170687. + {
  170688. + status = gcvSTATUS_GENERIC_IO;
  170689. +
  170690. + gcmkTRACE(
  170691. + gcvLEVEL_ERROR,
  170692. + "%s(%d): an error has occurred.\n",
  170693. + __FUNCTION__, __LINE__
  170694. + );
  170695. + }
  170696. + else
  170697. + {
  170698. + status = gcvSTATUS_OK;
  170699. + }
  170700. + }
  170701. + else
  170702. + {
  170703. + status = gcvSTATUS_GENERIC_IO;
  170704. +
  170705. + gcmkTRACE(
  170706. + gcvLEVEL_ERROR,
  170707. + "%s(%d): an error has occurred.\n",
  170708. + __FUNCTION__, __LINE__
  170709. + );
  170710. + }
  170711. +
  170712. + /* Return status. */
  170713. + return status;
  170714. +}
  170715. +
  170716. +/******************************************************************************\
  170717. +******************************** Thread Object *********************************
  170718. +\******************************************************************************/
  170719. +
  170720. +gceSTATUS
  170721. +gckOS_StartThread(
  170722. + IN gckOS Os,
  170723. + IN gctTHREADFUNC ThreadFunction,
  170724. + IN gctPOINTER ThreadParameter,
  170725. + OUT gctTHREAD * Thread
  170726. + )
  170727. +{
  170728. + gceSTATUS status;
  170729. + struct task_struct * thread;
  170730. +
  170731. + gcmkHEADER_ARG("Os=0x%X ", Os);
  170732. + /* Verify the arguments. */
  170733. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170734. + gcmkVERIFY_ARGUMENT(ThreadFunction != gcvNULL);
  170735. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  170736. +
  170737. + do
  170738. + {
  170739. + /* Create the thread. */
  170740. + thread = kthread_create(
  170741. + ThreadFunction,
  170742. + ThreadParameter,
  170743. + "Vivante Kernel Thread"
  170744. + );
  170745. +
  170746. + /* Failed? */
  170747. + if (IS_ERR(thread))
  170748. + {
  170749. + status = gcvSTATUS_GENERIC_IO;
  170750. + break;
  170751. + }
  170752. +
  170753. + /* Start the thread. */
  170754. + wake_up_process(thread);
  170755. +
  170756. + /* Set the thread handle. */
  170757. + * Thread = (gctTHREAD) thread;
  170758. +
  170759. + /* Success. */
  170760. + status = gcvSTATUS_OK;
  170761. + }
  170762. + while (gcvFALSE);
  170763. +
  170764. + gcmkFOOTER();
  170765. + /* Return the status. */
  170766. + return status;
  170767. +}
  170768. +
  170769. +gceSTATUS
  170770. +gckOS_StopThread(
  170771. + IN gckOS Os,
  170772. + IN gctTHREAD Thread
  170773. + )
  170774. +{
  170775. + gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
  170776. + /* Verify the arguments. */
  170777. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170778. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  170779. +
  170780. + /* Thread should have already been enabled to terminate. */
  170781. + kthread_stop((struct task_struct *) Thread);
  170782. +
  170783. + gcmkFOOTER_NO();
  170784. + /* Success. */
  170785. + return gcvSTATUS_OK;
  170786. +}
  170787. +
  170788. +gceSTATUS
  170789. +gckOS_VerifyThread(
  170790. + IN gckOS Os,
  170791. + IN gctTHREAD Thread
  170792. + )
  170793. +{
  170794. + gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
  170795. + /* Verify the arguments. */
  170796. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170797. + gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
  170798. +
  170799. + gcmkFOOTER_NO();
  170800. + /* Success. */
  170801. + return gcvSTATUS_OK;
  170802. +}
  170803. +#endif
  170804. +
  170805. +/******************************************************************************\
  170806. +******************************** Software Timer ********************************
  170807. +\******************************************************************************/
  170808. +
  170809. +void
  170810. +_TimerFunction(
  170811. + struct work_struct * work
  170812. + )
  170813. +{
  170814. + gcsOSTIMER_PTR timer = (gcsOSTIMER_PTR)work;
  170815. +
  170816. + gctTIMERFUNCTION function = timer->function;
  170817. +
  170818. + function(timer->data);
  170819. +}
  170820. +
  170821. +/*******************************************************************************
  170822. +**
  170823. +** gckOS_CreateTimer
  170824. +**
  170825. +** Create a software timer.
  170826. +**
  170827. +** INPUT:
  170828. +**
  170829. +** gckOS Os
  170830. +** Pointer to the gckOS object.
  170831. +**
  170832. +** gctTIMERFUNCTION Function.
  170833. +** Pointer to a call back function which will be called when timer is
  170834. +** expired.
  170835. +**
  170836. +** gctPOINTER Data.
  170837. +** Private data which will be passed to call back function.
  170838. +**
  170839. +** OUTPUT:
  170840. +**
  170841. +** gctPOINTER * Timer
  170842. +** Pointer to a variable receiving the created timer.
  170843. +*/
  170844. +gceSTATUS
  170845. +gckOS_CreateTimer(
  170846. + IN gckOS Os,
  170847. + IN gctTIMERFUNCTION Function,
  170848. + IN gctPOINTER Data,
  170849. + OUT gctPOINTER * Timer
  170850. + )
  170851. +{
  170852. + gceSTATUS status;
  170853. + gcsOSTIMER_PTR pointer;
  170854. + gcmkHEADER_ARG("Os=0x%X Function=0x%X Data=0x%X", Os, Function, Data);
  170855. +
  170856. + /* Verify the arguments. */
  170857. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170858. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  170859. +
  170860. + gcmkONERROR(gckOS_Allocate(Os, sizeof(gcsOSTIMER), (gctPOINTER)&pointer));
  170861. +
  170862. + pointer->function = Function;
  170863. + pointer->data = Data;
  170864. +
  170865. + INIT_DELAYED_WORK(&pointer->work, _TimerFunction);
  170866. +
  170867. + *Timer = pointer;
  170868. +
  170869. + gcmkFOOTER_NO();
  170870. + return gcvSTATUS_OK;
  170871. +
  170872. +OnError:
  170873. + gcmkFOOTER();
  170874. + return status;
  170875. +}
  170876. +
  170877. +/*******************************************************************************
  170878. +**
  170879. +** gckOS_DestroyTimer
  170880. +**
  170881. +** Destory a software timer.
  170882. +**
  170883. +** INPUT:
  170884. +**
  170885. +** gckOS Os
  170886. +** Pointer to the gckOS object.
  170887. +**
  170888. +** gctPOINTER Timer
  170889. +** Pointer to the timer to be destoryed.
  170890. +**
  170891. +** OUTPUT:
  170892. +**
  170893. +** Nothing.
  170894. +*/
  170895. +gceSTATUS
  170896. +gckOS_DestroyTimer(
  170897. + IN gckOS Os,
  170898. + IN gctPOINTER Timer
  170899. + )
  170900. +{
  170901. + gcsOSTIMER_PTR timer;
  170902. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
  170903. +
  170904. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170905. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  170906. +
  170907. + timer = (gcsOSTIMER_PTR)Timer;
  170908. +
  170909. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
  170910. + cancel_delayed_work_sync(&timer->work);
  170911. +#else
  170912. + cancel_delayed_work(&timer->work);
  170913. + flush_workqueue(Os->workqueue);
  170914. +#endif
  170915. +
  170916. + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, Timer));
  170917. +
  170918. + gcmkFOOTER_NO();
  170919. + return gcvSTATUS_OK;
  170920. +}
  170921. +
  170922. +/*******************************************************************************
  170923. +**
  170924. +** gckOS_StartTimer
  170925. +**
  170926. +** Schedule a software timer.
  170927. +**
  170928. +** INPUT:
  170929. +**
  170930. +** gckOS Os
  170931. +** Pointer to the gckOS object.
  170932. +**
  170933. +** gctPOINTER Timer
  170934. +** Pointer to the timer to be scheduled.
  170935. +**
  170936. +** gctUINT32 Delay
  170937. +** Delay in milliseconds.
  170938. +**
  170939. +** OUTPUT:
  170940. +**
  170941. +** Nothing.
  170942. +*/
  170943. +gceSTATUS
  170944. +gckOS_StartTimer(
  170945. + IN gckOS Os,
  170946. + IN gctPOINTER Timer,
  170947. + IN gctUINT32 Delay
  170948. + )
  170949. +{
  170950. + gcsOSTIMER_PTR timer;
  170951. +
  170952. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X Delay=%u", Os, Timer, Delay);
  170953. +
  170954. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  170955. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  170956. + gcmkVERIFY_ARGUMENT(Delay != 0);
  170957. +
  170958. + timer = (gcsOSTIMER_PTR)Timer;
  170959. +
  170960. + if (unlikely(delayed_work_pending(&timer->work)))
  170961. + {
  170962. + if (unlikely(!cancel_delayed_work(&timer->work)))
  170963. + {
  170964. + cancel_work_sync(&timer->work.work);
  170965. +
  170966. + if (unlikely(delayed_work_pending(&timer->work)))
  170967. + {
  170968. + gckOS_Print("gckOS_StartTimer error, the pending worker cannot complete!!!! \n");
  170969. +
  170970. + return gcvSTATUS_INVALID_REQUEST;
  170971. + }
  170972. + }
  170973. + }
  170974. +
  170975. + queue_delayed_work(Os->workqueue, &timer->work, msecs_to_jiffies(Delay));
  170976. +
  170977. + gcmkFOOTER_NO();
  170978. + return gcvSTATUS_OK;
  170979. +}
  170980. +
  170981. +/*******************************************************************************
  170982. +**
  170983. +** gckOS_StopTimer
  170984. +**
  170985. +** Cancel a unscheduled timer.
  170986. +**
  170987. +** INPUT:
  170988. +**
  170989. +** gckOS Os
  170990. +** Pointer to the gckOS object.
  170991. +**
  170992. +** gctPOINTER Timer
  170993. +** Pointer to the timer to be cancel.
  170994. +**
  170995. +** OUTPUT:
  170996. +**
  170997. +** Nothing.
  170998. +*/
  170999. +gceSTATUS
  171000. +gckOS_StopTimer(
  171001. + IN gckOS Os,
  171002. + IN gctPOINTER Timer
  171003. + )
  171004. +{
  171005. + gcsOSTIMER_PTR timer;
  171006. + gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
  171007. +
  171008. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  171009. + gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
  171010. +
  171011. + timer = (gcsOSTIMER_PTR)Timer;
  171012. +
  171013. + cancel_delayed_work(&timer->work);
  171014. +
  171015. + gcmkFOOTER_NO();
  171016. + return gcvSTATUS_OK;
  171017. +}
  171018. +
  171019. +
  171020. +gceSTATUS
  171021. +gckOS_DumpCallStack(
  171022. + IN gckOS Os
  171023. + )
  171024. +{
  171025. + gcmkHEADER_ARG("Os=0x%X", Os);
  171026. +
  171027. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  171028. +
  171029. + dump_stack();
  171030. +
  171031. + gcmkFOOTER_NO();
  171032. + return gcvSTATUS_OK;
  171033. +}
  171034. +
  171035. +
  171036. +gceSTATUS
  171037. +gckOS_GetProcessNameByPid(
  171038. + IN gctINT Pid,
  171039. + IN gctSIZE_T Length,
  171040. + OUT gctUINT8_PTR String
  171041. + )
  171042. +{
  171043. + struct task_struct *task;
  171044. +
  171045. + /* Get the task_struct of the task with pid. */
  171046. + rcu_read_lock();
  171047. +
  171048. + task = FIND_TASK_BY_PID(Pid);
  171049. +
  171050. + if (task == gcvNULL)
  171051. + {
  171052. + rcu_read_unlock();
  171053. + return gcvSTATUS_NOT_FOUND;
  171054. + }
  171055. +
  171056. + /* Get name of process. */
  171057. + strncpy(String, task->comm, Length);
  171058. +
  171059. + rcu_read_unlock();
  171060. +
  171061. + return gcvSTATUS_OK;
  171062. +}
  171063. +
  171064. +#if gcdANDROID_NATIVE_FENCE_SYNC
  171065. +
  171066. +gceSTATUS
  171067. +gckOS_CreateSyncPoint(
  171068. + IN gckOS Os,
  171069. + OUT gctSYNC_POINT * SyncPoint
  171070. + )
  171071. +{
  171072. + gceSTATUS status;
  171073. + gcsSYNC_POINT_PTR syncPoint;
  171074. +
  171075. + gcmkHEADER_ARG("Os=0x%X", Os);
  171076. +
  171077. + /* Verify the arguments. */
  171078. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  171079. +
  171080. + /* Create an sync point structure. */
  171081. + syncPoint = (gcsSYNC_POINT_PTR) kmalloc(
  171082. + sizeof(gcsSYNC_POINT), GFP_KERNEL | gcdNOWARN);
  171083. +
  171084. + if (syncPoint == gcvNULL)
  171085. + {
  171086. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  171087. + }
  171088. +
  171089. + /* Initialize the sync point. */
  171090. + atomic_set(&syncPoint->ref, 1);
  171091. + atomic_set(&syncPoint->state, 0);
  171092. +
  171093. + gcmkONERROR(_AllocateIntegerId(&Os->syncPointDB, syncPoint, &syncPoint->id));
  171094. +
  171095. + *SyncPoint = (gctSYNC_POINT)(gctUINTPTR_T)syncPoint->id;
  171096. +
  171097. + gcmkFOOTER_ARG("*SyncPonint=%d", syncPoint->id);
  171098. + return gcvSTATUS_OK;
  171099. +
  171100. +OnError:
  171101. + if (syncPoint != gcvNULL)
  171102. + {
  171103. + kfree(syncPoint);
  171104. + }
  171105. +
  171106. + gcmkFOOTER();
  171107. + return status;
  171108. +}
  171109. +
  171110. +gceSTATUS
  171111. +gckOS_ReferenceSyncPoint(
  171112. + IN gckOS Os,
  171113. + IN gctSYNC_POINT SyncPoint
  171114. + )
  171115. +{
  171116. + gceSTATUS status;
  171117. + gcsSYNC_POINT_PTR syncPoint;
  171118. +
  171119. + gcmkHEADER_ARG("Os=0x%X", Os);
  171120. +
  171121. + /* Verify the arguments. */
  171122. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  171123. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  171124. +
  171125. + gcmkONERROR(
  171126. + _QueryIntegerId(&Os->syncPointDB,
  171127. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  171128. + (gctPOINTER)&syncPoint));
  171129. +
  171130. + /* Initialize the sync point. */
  171131. + atomic_inc(&syncPoint->ref);
  171132. +
  171133. + gcmkFOOTER_NO();
  171134. + return gcvSTATUS_OK;
  171135. +
  171136. +OnError:
  171137. + gcmkFOOTER();
  171138. + return status;
  171139. +}
  171140. +
  171141. +gceSTATUS
  171142. +gckOS_DestroySyncPoint(
  171143. + IN gckOS Os,
  171144. + IN gctSYNC_POINT SyncPoint
  171145. + )
  171146. +{
  171147. + gceSTATUS status;
  171148. + gcsSYNC_POINT_PTR syncPoint;
  171149. + gctBOOL acquired = gcvFALSE;
  171150. +
  171151. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  171152. +
  171153. + /* Verify the arguments. */
  171154. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  171155. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  171156. +
  171157. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
  171158. + acquired = gcvTRUE;
  171159. +
  171160. + gcmkONERROR(
  171161. + _QueryIntegerId(&Os->syncPointDB,
  171162. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  171163. + (gctPOINTER)&syncPoint));
  171164. +
  171165. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  171166. +
  171167. + if (atomic_dec_and_test(&syncPoint->ref))
  171168. + {
  171169. + gcmkVERIFY_OK(_DestroyIntegerId(&Os->syncPointDB, syncPoint->id));
  171170. +
  171171. + /* Free the sgianl. */
  171172. + syncPoint->timeline = gcvNULL;
  171173. + kfree(syncPoint);
  171174. + }
  171175. +
  171176. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  171177. + acquired = gcvFALSE;
  171178. +
  171179. + /* Success. */
  171180. + gcmkFOOTER_NO();
  171181. + return gcvSTATUS_OK;
  171182. +
  171183. +OnError:
  171184. + if (acquired)
  171185. + {
  171186. + /* Release the mutex. */
  171187. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  171188. + }
  171189. +
  171190. + gcmkFOOTER();
  171191. + return status;
  171192. +}
  171193. +
  171194. +gceSTATUS
  171195. +gckOS_SignalSyncPoint(
  171196. + IN gckOS Os,
  171197. + IN gctSYNC_POINT SyncPoint
  171198. + )
  171199. +{
  171200. + gceSTATUS status;
  171201. + gcsSYNC_POINT_PTR syncPoint;
  171202. + gctBOOL acquired = gcvFALSE;
  171203. +
  171204. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  171205. +
  171206. + /* Verify the arguments. */
  171207. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  171208. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  171209. +
  171210. + gcmkONERROR(gckOS_AcquireMutex(Os, Os->syncPointMutex, gcvINFINITE));
  171211. + acquired = gcvTRUE;
  171212. +
  171213. + gcmkONERROR(
  171214. + _QueryIntegerId(&Os->syncPointDB,
  171215. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  171216. + (gctPOINTER)&syncPoint));
  171217. +
  171218. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  171219. +
  171220. + /* Get state. */
  171221. + atomic_set(&syncPoint->state, gcvTRUE);
  171222. +
  171223. + /* Signal timeline. */
  171224. + if (syncPoint->timeline)
  171225. + {
  171226. + sync_timeline_signal(syncPoint->timeline);
  171227. + }
  171228. +
  171229. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  171230. + acquired = gcvFALSE;
  171231. +
  171232. + /* Success. */
  171233. + gcmkFOOTER_NO();
  171234. + return gcvSTATUS_OK;
  171235. +
  171236. +OnError:
  171237. + if (acquired)
  171238. + {
  171239. + /* Release the mutex. */
  171240. + gcmkVERIFY_OK(gckOS_ReleaseMutex(Os, Os->syncPointMutex));
  171241. + }
  171242. +
  171243. + gcmkFOOTER();
  171244. + return status;
  171245. +}
  171246. +
  171247. +gceSTATUS
  171248. +gckOS_QuerySyncPoint(
  171249. + IN gckOS Os,
  171250. + IN gctSYNC_POINT SyncPoint,
  171251. + OUT gctBOOL_PTR State
  171252. + )
  171253. +{
  171254. + gceSTATUS status;
  171255. + gcsSYNC_POINT_PTR syncPoint;
  171256. +
  171257. + gcmkHEADER_ARG("Os=0x%X SyncPoint=%d", Os, (gctUINT32)(gctUINTPTR_T)SyncPoint);
  171258. +
  171259. + /* Verify the arguments. */
  171260. + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
  171261. + gcmkVERIFY_ARGUMENT(SyncPoint != gcvNULL);
  171262. +
  171263. + gcmkONERROR(
  171264. + _QueryIntegerId(&Os->syncPointDB,
  171265. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  171266. + (gctPOINTER)&syncPoint));
  171267. +
  171268. + gcmkASSERT(syncPoint->id == (gctUINT32)(gctUINTPTR_T)SyncPoint);
  171269. +
  171270. + /* Get state. */
  171271. + *State = atomic_read(&syncPoint->state);
  171272. +
  171273. + /* Success. */
  171274. + gcmkFOOTER_ARG("*State=%d", *State);
  171275. + return gcvSTATUS_OK;
  171276. +
  171277. +OnError:
  171278. + gcmkFOOTER();
  171279. + return status;
  171280. +}
  171281. +
  171282. +gceSTATUS
  171283. +gckOS_CreateSyncTimeline(
  171284. + IN gckOS Os,
  171285. + OUT gctHANDLE * Timeline
  171286. + )
  171287. +{
  171288. + struct viv_sync_timeline * timeline;
  171289. +
  171290. + /* Create viv sync timeline. */
  171291. + timeline = viv_sync_timeline_create("viv timeline", Os);
  171292. +
  171293. + if (timeline == gcvNULL)
  171294. + {
  171295. + /* Out of memory. */
  171296. + return gcvSTATUS_OUT_OF_MEMORY;
  171297. + }
  171298. +
  171299. + *Timeline = (gctHANDLE) timeline;
  171300. + return gcvSTATUS_OK;
  171301. +}
  171302. +
  171303. +gceSTATUS
  171304. +gckOS_DestroySyncTimeline(
  171305. + IN gckOS Os,
  171306. + IN gctHANDLE Timeline
  171307. + )
  171308. +{
  171309. + struct viv_sync_timeline * timeline;
  171310. + gcmkASSERT(Timeline != gcvNULL);
  171311. +
  171312. + /* Destroy timeline. */
  171313. + timeline = (struct viv_sync_timeline *) Timeline;
  171314. + sync_timeline_destroy(&timeline->obj);
  171315. +
  171316. + return gcvSTATUS_OK;
  171317. +}
  171318. +
  171319. +gceSTATUS
  171320. +gckOS_CreateNativeFence(
  171321. + IN gckOS Os,
  171322. + IN gctHANDLE Timeline,
  171323. + IN gctSYNC_POINT SyncPoint,
  171324. + OUT gctINT * FenceFD
  171325. + )
  171326. +{
  171327. + int fd = -1;
  171328. + struct viv_sync_timeline *timeline;
  171329. + struct sync_pt * pt = gcvNULL;
  171330. + struct sync_fence * fence;
  171331. + char name[32];
  171332. + gcsSYNC_POINT_PTR syncPoint;
  171333. + gceSTATUS status;
  171334. +
  171335. + gcmkHEADER_ARG("Os=0x%X Timeline=0x%X SyncPoint=%d",
  171336. + Os, Timeline, (gctUINT)(gctUINTPTR_T)SyncPoint);
  171337. +
  171338. + gcmkONERROR(
  171339. + _QueryIntegerId(&Os->syncPointDB,
  171340. + (gctUINT32)(gctUINTPTR_T)SyncPoint,
  171341. + (gctPOINTER)&syncPoint));
  171342. +
  171343. + /* Cast timeline. */
  171344. + timeline = (struct viv_sync_timeline *) Timeline;
  171345. +
  171346. + fd = get_unused_fd();
  171347. +
  171348. + if (fd < 0)
  171349. + {
  171350. + /* Out of resources. */
  171351. + gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
  171352. + }
  171353. +
  171354. + /* Create viv_sync_pt. */
  171355. + pt = viv_sync_pt_create(timeline, SyncPoint);
  171356. +
  171357. + if (pt == gcvNULL)
  171358. + {
  171359. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  171360. + }
  171361. +
  171362. + /* Reference sync_timeline. */
  171363. + syncPoint->timeline = &timeline->obj;
  171364. +
  171365. + /* Build fence name. */
  171366. + snprintf(name, 32, "viv sync_fence-%u", (gctUINT)(gctUINTPTR_T)SyncPoint);
  171367. +
  171368. + /* Create sync_fence. */
  171369. + fence = sync_fence_create(name, pt);
  171370. +
  171371. + if (fence == NULL)
  171372. + {
  171373. + gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
  171374. + }
  171375. +
  171376. + /* Install fence to fd. */
  171377. + sync_fence_install(fence, fd);
  171378. +
  171379. + *FenceFD = fd;
  171380. + gcmkFOOTER_ARG("*FenceFD=%d", fd);
  171381. + return gcvSTATUS_OK;
  171382. +
  171383. +OnError:
  171384. + /* Error roll back. */
  171385. + if (pt)
  171386. + {
  171387. + sync_pt_free(pt);
  171388. + }
  171389. +
  171390. + if (fd > 0)
  171391. + {
  171392. + put_unused_fd(fd);
  171393. + }
  171394. +
  171395. + gcmkFOOTER();
  171396. + return status;
  171397. +}
  171398. +#endif
  171399. diff -Nur linux-3.14.17/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
  171400. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h 1970-01-01 01:00:00.000000000 +0100
  171401. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h 2014-09-11 18:06:03.130042483 +0200
  171402. @@ -0,0 +1,83 @@
  171403. +/****************************************************************************
  171404. +*
  171405. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  171406. +*
  171407. +* This program is free software; you can redistribute it and/or modify
  171408. +* it under the terms of the GNU General Public License as published by
  171409. +* the Free Software Foundation; either version 2 of the license, or
  171410. +* (at your option) any later version.
  171411. +*
  171412. +* This program is distributed in the hope that it will be useful,
  171413. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  171414. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  171415. +* GNU General Public License for more details.
  171416. +*
  171417. +* You should have received a copy of the GNU General Public License
  171418. +* along with this program; if not write to the Free Software
  171419. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  171420. +*
  171421. +*****************************************************************************/
  171422. +
  171423. +
  171424. +#ifndef __gc_hal_kernel_os_h_
  171425. +#define __gc_hal_kernel_os_h_
  171426. +
  171427. +typedef struct _LINUX_MDL_MAP
  171428. +{
  171429. + gctINT pid;
  171430. + gctPOINTER vmaAddr;
  171431. + gctUINT32 count;
  171432. + struct vm_area_struct * vma;
  171433. + struct _LINUX_MDL_MAP * next;
  171434. +}
  171435. +LINUX_MDL_MAP;
  171436. +
  171437. +typedef struct _LINUX_MDL_MAP * PLINUX_MDL_MAP;
  171438. +
  171439. +typedef struct _LINUX_MDL
  171440. +{
  171441. + gctINT pid;
  171442. + char * addr;
  171443. +
  171444. + union _pages
  171445. + {
  171446. + /* Pointer to a array of pages. */
  171447. + struct page * contiguousPages;
  171448. + /* Pointer to a array of pointers to page. */
  171449. + struct page ** nonContiguousPages;
  171450. + }
  171451. + u;
  171452. +
  171453. +#ifdef NO_DMA_COHERENT
  171454. + gctPOINTER kaddr;
  171455. +#endif /* NO_DMA_COHERENT */
  171456. +
  171457. + gctINT numPages;
  171458. + gctINT pagedMem;
  171459. + gctBOOL contiguous;
  171460. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
  171461. + gctBOOL exact;
  171462. +#endif
  171463. + dma_addr_t dmaHandle;
  171464. + PLINUX_MDL_MAP maps;
  171465. + struct _LINUX_MDL * prev;
  171466. + struct _LINUX_MDL * next;
  171467. +}
  171468. +LINUX_MDL, *PLINUX_MDL;
  171469. +
  171470. +extern PLINUX_MDL_MAP
  171471. +FindMdlMap(
  171472. + IN PLINUX_MDL Mdl,
  171473. + IN gctINT PID
  171474. + );
  171475. +
  171476. +typedef struct _DRIVER_ARGS
  171477. +{
  171478. + gctUINT64 InputBuffer;
  171479. + gctUINT64 InputBufferSize;
  171480. + gctUINT64 OutputBuffer;
  171481. + gctUINT64 OutputBufferSize;
  171482. +}
  171483. +DRIVER_ARGS;
  171484. +
  171485. +#endif /* __gc_hal_kernel_os_h_ */
  171486. diff -Nur linux-3.14.17/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
  171487. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c 1970-01-01 01:00:00.000000000 +0100
  171488. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c 2014-09-11 18:06:03.130042483 +0200
  171489. @@ -0,0 +1,174 @@
  171490. +/****************************************************************************
  171491. +*
  171492. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  171493. +*
  171494. +* This program is free software; you can redistribute it and/or modify
  171495. +* it under the terms of the GNU General Public License as published by
  171496. +* the Free Software Foundation; either version 2 of the license, or
  171497. +* (at your option) any later version.
  171498. +*
  171499. +* This program is distributed in the hope that it will be useful,
  171500. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  171501. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  171502. +* GNU General Public License for more details.
  171503. +*
  171504. +* You should have received a copy of the GNU General Public License
  171505. +* along with this program; if not write to the Free Software
  171506. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  171507. +*
  171508. +*****************************************************************************/
  171509. +
  171510. +
  171511. +#include <linux/kernel.h>
  171512. +#include <linux/file.h>
  171513. +#include <linux/fs.h>
  171514. +#include <linux/miscdevice.h>
  171515. +#include <linux/module.h>
  171516. +#include <linux/syscalls.h>
  171517. +#include <linux/uaccess.h>
  171518. +
  171519. +#include "gc_hal_kernel_sync.h"
  171520. +
  171521. +#if gcdANDROID_NATIVE_FENCE_SYNC
  171522. +
  171523. +static struct sync_pt *
  171524. +viv_sync_pt_dup(
  171525. + struct sync_pt * sync_pt
  171526. + )
  171527. +{
  171528. + gceSTATUS status;
  171529. + struct viv_sync_pt *pt;
  171530. + struct viv_sync_pt *src;
  171531. + struct viv_sync_timeline *obj;
  171532. +
  171533. + src = (struct viv_sync_pt *) sync_pt;
  171534. + obj = (struct viv_sync_timeline *) sync_pt->parent;
  171535. +
  171536. + /* Create the new sync_pt. */
  171537. + pt = (struct viv_sync_pt *)
  171538. + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
  171539. +
  171540. + pt->stamp = src->stamp;
  171541. + pt->sync = src->sync;
  171542. +
  171543. + /* Reference sync point. */
  171544. + status = gckOS_ReferenceSyncPoint(obj->os, pt->sync);
  171545. +
  171546. + if (gcmIS_ERROR(status))
  171547. + {
  171548. + sync_pt_free((struct sync_pt *)pt);
  171549. + return NULL;
  171550. + }
  171551. +
  171552. + return (struct sync_pt *)pt;
  171553. +}
  171554. +
  171555. +static int
  171556. +viv_sync_pt_has_signaled(
  171557. + struct sync_pt * sync_pt
  171558. + )
  171559. +{
  171560. + gceSTATUS status;
  171561. + gctBOOL state;
  171562. + struct viv_sync_pt * pt;
  171563. + struct viv_sync_timeline * obj;
  171564. +
  171565. + pt = (struct viv_sync_pt *)sync_pt;
  171566. + obj = (struct viv_sync_timeline *)sync_pt->parent;
  171567. +
  171568. + status = gckOS_QuerySyncPoint(obj->os, pt->sync, &state);
  171569. +
  171570. + if (gcmIS_ERROR(status))
  171571. + {
  171572. + /* Error. */
  171573. + return -1;
  171574. + }
  171575. +
  171576. + return state;
  171577. +}
  171578. +
  171579. +static int
  171580. +viv_sync_pt_compare(
  171581. + struct sync_pt * a,
  171582. + struct sync_pt * b
  171583. + )
  171584. +{
  171585. + int ret;
  171586. + struct viv_sync_pt * pt1 = (struct viv_sync_pt *) a;
  171587. + struct viv_sync_pt * pt2 = (struct viv_sync_pt *) b;
  171588. +
  171589. + ret = (pt1->stamp < pt2->stamp) ? -1
  171590. + : (pt1->stamp == pt2->stamp) ? 0
  171591. + : 1;
  171592. +
  171593. + return ret;
  171594. +}
  171595. +
  171596. +static void
  171597. +viv_sync_pt_free(
  171598. + struct sync_pt * sync_pt
  171599. + )
  171600. +{
  171601. + struct viv_sync_pt * pt;
  171602. + struct viv_sync_timeline * obj;
  171603. +
  171604. + pt = (struct viv_sync_pt *) sync_pt;
  171605. + obj = (struct viv_sync_timeline *) sync_pt->parent;
  171606. +
  171607. + gckOS_DestroySyncPoint(obj->os, pt->sync);
  171608. +}
  171609. +
  171610. +static struct sync_timeline_ops viv_timeline_ops =
  171611. +{
  171612. + .driver_name = "viv_sync",
  171613. + .dup = viv_sync_pt_dup,
  171614. + .has_signaled = viv_sync_pt_has_signaled,
  171615. + .compare = viv_sync_pt_compare,
  171616. + .free_pt = viv_sync_pt_free,
  171617. +};
  171618. +
  171619. +struct viv_sync_timeline *
  171620. +viv_sync_timeline_create(
  171621. + const char * name,
  171622. + gckOS os
  171623. + )
  171624. +{
  171625. + struct viv_sync_timeline * obj;
  171626. +
  171627. + obj = (struct viv_sync_timeline *)
  171628. + sync_timeline_create(&viv_timeline_ops, sizeof(struct viv_sync_timeline), name);
  171629. +
  171630. + obj->os = os;
  171631. + obj->stamp = 0;
  171632. +
  171633. + return obj;
  171634. +}
  171635. +
  171636. +struct sync_pt *
  171637. +viv_sync_pt_create(
  171638. + struct viv_sync_timeline * obj,
  171639. + gctSYNC_POINT SyncPoint
  171640. + )
  171641. +{
  171642. + gceSTATUS status;
  171643. + struct viv_sync_pt * pt;
  171644. +
  171645. + pt = (struct viv_sync_pt *)
  171646. + sync_pt_create(&obj->obj, sizeof(struct viv_sync_pt));
  171647. +
  171648. + pt->stamp = obj->stamp++;
  171649. + pt->sync = SyncPoint;
  171650. +
  171651. + /* Dup signal. */
  171652. + status = gckOS_ReferenceSyncPoint(obj->os, SyncPoint);
  171653. +
  171654. + if (gcmIS_ERROR(status))
  171655. + {
  171656. + sync_pt_free((struct sync_pt *)pt);
  171657. + return NULL;
  171658. + }
  171659. +
  171660. + return (struct sync_pt *) pt;
  171661. +}
  171662. +
  171663. +#endif
  171664. diff -Nur linux-3.14.17/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
  171665. --- linux-3.14.17/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h 1970-01-01 01:00:00.000000000 +0100
  171666. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h 2014-09-11 18:06:03.130042483 +0200
  171667. @@ -0,0 +1,71 @@
  171668. +/****************************************************************************
  171669. +*
  171670. +* Copyright (C) 2005 - 2013 by Vivante Corp.
  171671. +*
  171672. +* This program is free software; you can redistribute it and/or modify
  171673. +* it under the terms of the GNU General Public License as published by
  171674. +* the Free Software Foundation; either version 2 of the license, or
  171675. +* (at your option) any later version.
  171676. +*
  171677. +* This program is distributed in the hope that it will be useful,
  171678. +* but WITHOUT ANY WARRANTY; without even the implied warranty of
  171679. +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  171680. +* GNU General Public License for more details.
  171681. +*
  171682. +* You should have received a copy of the GNU General Public License
  171683. +* along with this program; if not write to the Free Software
  171684. +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  171685. +*
  171686. +*****************************************************************************/
  171687. +
  171688. +
  171689. +#ifndef __gc_hal_kernel_sync_h_
  171690. +#define __gc_hal_kernel_sync_h_
  171691. +
  171692. +#include <linux/types.h>
  171693. +
  171694. +#include <linux/sync.h>
  171695. +
  171696. +#include <gc_hal.h>
  171697. +#include <gc_hal_base.h>
  171698. +
  171699. +struct viv_sync_timeline
  171700. +{
  171701. + /* Parent object. */
  171702. + struct sync_timeline obj;
  171703. +
  171704. + /* Timestamp when sync_pt is created. */
  171705. + gctUINT stamp;
  171706. +
  171707. + /* Pointer to os struct. */
  171708. + gckOS os;
  171709. +};
  171710. +
  171711. +
  171712. +struct viv_sync_pt
  171713. +{
  171714. + /* Parent object. */
  171715. + struct sync_pt pt;
  171716. +
  171717. + /* Reference sync point*/
  171718. + gctSYNC_POINT sync;
  171719. +
  171720. + /* Timestamp when sync_pt is created. */
  171721. + gctUINT stamp;
  171722. +};
  171723. +
  171724. +/* Create viv_sync_timeline object. */
  171725. +struct viv_sync_timeline *
  171726. +viv_sync_timeline_create(
  171727. + const char * Name,
  171728. + gckOS Os
  171729. + );
  171730. +
  171731. +/* Create viv_sync_pt object. */
  171732. +struct sync_pt *
  171733. +viv_sync_pt_create(
  171734. + struct viv_sync_timeline * Obj,
  171735. + gctSYNC_POINT SyncPoint
  171736. + );
  171737. +
  171738. +#endif /* __gc_hal_kernel_sync_h_ */
  171739. diff -Nur linux-3.14.17/drivers/mxc/gpu-viv/Kbuild linux-imx6-3.14/drivers/mxc/gpu-viv/Kbuild
  171740. --- linux-3.14.17/drivers/mxc/gpu-viv/Kbuild 1970-01-01 01:00:00.000000000 +0100
  171741. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/Kbuild 2014-09-11 18:06:03.078042276 +0200
  171742. @@ -0,0 +1,236 @@
  171743. +##############################################################################
  171744. +#
  171745. +# Copyright (C) 2005 - 2013 by Vivante Corp.
  171746. +#
  171747. +# This program is free software; you can redistribute it and/or modify
  171748. +# it under the terms of the GNU General Public License as published by
  171749. +# the Free Software Foundation; either version 2 of the license, or
  171750. +# (at your option) any later version.
  171751. +#
  171752. +# This program is distributed in the hope that it will be useful,
  171753. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  171754. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  171755. +# GNU General Public License for more details.
  171756. +#
  171757. +# You should have received a copy of the GNU General Public License
  171758. +# along with this program; if not write to the Free Software
  171759. +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  171760. +#
  171761. +##############################################################################
  171762. +
  171763. +
  171764. +#
  171765. +# Linux build file for kernel HAL driver.
  171766. +#
  171767. +
  171768. +AQROOT := $(srctree)/drivers/mxc/gpu-viv
  171769. +AQARCH := $(AQROOT)/arch/XAQ2
  171770. +AQVGARCH := $(AQROOT)/arch/GC350
  171771. +
  171772. +include $(AQROOT)/config
  171773. +
  171774. +KERNEL_DIR ?= $(TOOL_DIR)/kernel
  171775. +
  171776. +OS_KERNEL_DIR := hal/os/linux/kernel
  171777. +ARCH_KERNEL_DIR := arch/$(notdir $(AQARCH))/hal/kernel
  171778. +ARCH_VG_KERNEL_DIR := arch/$(notdir $(AQVGARCH))/hal/kernel
  171779. +HAL_KERNEL_DIR := hal/kernel
  171780. +
  171781. +# EXTRA_CFLAGS += -Werror
  171782. +
  171783. +OBJS := $(OS_KERNEL_DIR)/gc_hal_kernel_device.o \
  171784. + $(OS_KERNEL_DIR)/gc_hal_kernel_driver.o \
  171785. + $(OS_KERNEL_DIR)/gc_hal_kernel_linux.o \
  171786. + $(OS_KERNEL_DIR)/gc_hal_kernel_math.o \
  171787. + $(OS_KERNEL_DIR)/gc_hal_kernel_os.o \
  171788. + $(OS_KERNEL_DIR)/gc_hal_kernel_debugfs.o
  171789. +
  171790. +OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \
  171791. + $(HAL_KERNEL_DIR)/gc_hal_kernel_command.o \
  171792. + $(HAL_KERNEL_DIR)/gc_hal_kernel_db.o \
  171793. + $(HAL_KERNEL_DIR)/gc_hal_kernel_debug.o \
  171794. + $(HAL_KERNEL_DIR)/gc_hal_kernel_event.o \
  171795. + $(HAL_KERNEL_DIR)/gc_hal_kernel_heap.o \
  171796. + $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu.o \
  171797. + $(HAL_KERNEL_DIR)/gc_hal_kernel_video_memory.o \
  171798. + $(HAL_KERNEL_DIR)/gc_hal_kernel_power.o
  171799. +
  171800. +OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_context.o \
  171801. + $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o
  171802. +
  171803. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  171804. +OBJS +=\
  171805. + $(HAL_KERNEL_DIR)/gc_hal_kernel_vg.o\
  171806. + $(HAL_KERNEL_DIR)/gc_hal_kernel_command_vg.o\
  171807. + $(HAL_KERNEL_DIR)/gc_hal_kernel_interrupt_vg.o\
  171808. + $(HAL_KERNEL_DIR)/gc_hal_kernel_mmu_vg.o\
  171809. + $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_command_vg.o\
  171810. + $(ARCH_VG_KERNEL_DIR)/gc_hal_kernel_hardware_vg.o
  171811. +endif
  171812. +
  171813. +ifneq ($(CONFIG_SYNC),)
  171814. +OBJS += $(OS_KERNEL_DIR)/gc_hal_kernel_sync.o
  171815. +endif
  171816. +
  171817. +ifeq ($(KERNELRELEASE), )
  171818. +
  171819. +.PHONY: all clean install
  171820. +
  171821. +# Define targets.
  171822. +all:
  171823. + @make V=$(V) ARCH=$(ARCH_TYPE) -C $(KERNEL_DIR) SUBDIRS=`pwd` modules
  171824. +
  171825. +clean:
  171826. + @rm -rf $(OBJS)
  171827. + @rm -rf modules.order Module.symvers
  171828. + @find $(AQROOT) -name ".gc_*.cmd" | xargs rm -f
  171829. +
  171830. +install: all
  171831. + @mkdir -p $(SDK_DIR)/drivers
  171832. +
  171833. +else
  171834. +
  171835. +
  171836. +EXTRA_CFLAGS += -DLINUX -DDRIVER
  171837. +
  171838. +ifeq ($(ENUM_WORKAROUND), 1)
  171839. +EXTRA_CFLAGS += -DENUM_WORKAROUND=1
  171840. +else
  171841. +EXTRA_CFLAGS += -DENUM_WORKAROUND=0
  171842. +endif
  171843. +
  171844. +ifeq ($(FLAREON),1)
  171845. +EXTRA_CFLAGS += -DFLAREON
  171846. +endif
  171847. +
  171848. +ifeq ($(DEBUG), 1)
  171849. +EXTRA_CFLAGS += -DDBG=1 -DDEBUG -D_DEBUG
  171850. +else
  171851. +EXTRA_CFLAGS += -DDBG=0
  171852. +endif
  171853. +
  171854. +ifeq ($(NO_DMA_COHERENT), 1)
  171855. +EXTRA_CFLAGS += -DNO_DMA_COHERENT
  171856. +endif
  171857. +
  171858. +ifeq ($(CONFIG_DOVE_GPU), 1)
  171859. +EXTRA_CFLAGS += -DCONFIG_DOVE_GPU=1
  171860. +endif
  171861. +
  171862. +ifneq ($(USE_PLATFORM_DRIVER), 0)
  171863. +EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=1
  171864. +else
  171865. +EXTRA_CFLAGS += -DUSE_PLATFORM_DRIVER=0
  171866. +endif
  171867. +
  171868. +
  171869. +EXTRA_CFLAGS += -DVIVANTE_PROFILER=1
  171870. +EXTRA_CFLAGS += -DVIVANTE_PROFILER_CONTEXT=1
  171871. +
  171872. +
  171873. +ifeq ($(ANDROID), 1)
  171874. +EXTRA_CFLAGS += -DANDROID=1
  171875. +endif
  171876. +
  171877. +ifeq ($(ENABLE_GPU_CLOCK_BY_DRIVER), 1)
  171878. +EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=1
  171879. +else
  171880. +EXTRA_CFLAGS += -DENABLE_GPU_CLOCK_BY_DRIVER=0
  171881. +endif
  171882. +
  171883. +ifeq ($(USE_NEW_LINUX_SIGNAL), 1)
  171884. +EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=1
  171885. +else
  171886. +EXTRA_CFLAGS += -DUSE_NEW_LINUX_SIGNAL=0
  171887. +endif
  171888. +
  171889. +ifeq ($(NO_USER_DIRECT_ACCESS_FROM_KERNEL), 1)
  171890. +EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=1
  171891. +else
  171892. +EXTRA_CFLAGS += -DNO_USER_DIRECT_ACCESS_FROM_KERNEL=0
  171893. +endif
  171894. +
  171895. +ifeq ($(FORCE_ALL_VIDEO_MEMORY_CACHED), 1)
  171896. +EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=1
  171897. +else
  171898. +EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=0
  171899. +endif
  171900. +
  171901. +ifeq ($(NONPAGED_MEMORY_CACHEABLE), 1)
  171902. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_CACHEABLE=1
  171903. +else
  171904. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_CACHEABLE=0
  171905. +endif
  171906. +
  171907. +ifeq ($(NONPAGED_MEMORY_BUFFERABLE), 1)
  171908. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_BUFFERABLE=1
  171909. +else
  171910. +EXTRA_CFLAGS += -DgcdNONPAGED_MEMORY_BUFFERABLE=0
  171911. +endif
  171912. +
  171913. +ifeq ($(CACHE_FUNCTION_UNIMPLEMENTED), 1)
  171914. +EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=1
  171915. +else
  171916. +EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=0
  171917. +endif
  171918. +
  171919. +ifeq ($(SUPPORT_SWAP_RECTANGLE), 1)
  171920. +EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=1
  171921. +else
  171922. +EXTRA_CFLAGS += -DgcdSUPPORT_SWAP_RECTANGLE=0
  171923. +endif
  171924. +
  171925. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  171926. +EXTRA_CFLAGS += -DgcdENABLE_VG=1
  171927. +else
  171928. +EXTRA_CFLAGS += -DgcdENABLE_VG=0
  171929. +endif
  171930. +
  171931. +ifeq ($(CONFIG_SMP), y)
  171932. +EXTRA_CFLAGS += -DgcdSMP=1
  171933. +else
  171934. +EXTRA_CFLAGS += -DgcdSMP=0
  171935. +endif
  171936. +
  171937. +ifeq ($(VIVANTE_NO_3D),1)
  171938. +EXTRA_CFLAGS += -DVIVANTE_NO_3D
  171939. +endif
  171940. +
  171941. +ifeq ($(ENABLE_OUTER_CACHE_PATCH), 1)
  171942. +EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=1
  171943. +else
  171944. +EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=0
  171945. +endif
  171946. +
  171947. +ifeq ($(USE_BANK_ALIGNMENT), 1)
  171948. + EXTRA_CFLAGS += -DgcdENABLE_BANK_ALIGNMENT=1
  171949. + ifneq ($(BANK_BIT_START), 0)
  171950. + ifneq ($(BANK_BIT_END), 0)
  171951. + EXTRA_CFLAGS += -DgcdBANK_BIT_START=$(BANK_BIT_START)
  171952. + EXTRA_CFLAGS += -DgcdBANK_BIT_END=$(BANK_BIT_END)
  171953. + endif
  171954. + endif
  171955. +
  171956. + ifneq ($(BANK_CHANNEL_BIT), 0)
  171957. + EXTRA_CFLAGS += -DgcdBANK_CHANNEL_BIT=$(BANK_CHANNEL_BIT)
  171958. + endif
  171959. +endif
  171960. +
  171961. +ifneq ($(CONFIG_SYNC),)
  171962. +EXTRA_CFLAGS += -DgcdANDROID_NATIVE_FENCE_SYNC=1
  171963. +endif
  171964. +
  171965. +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
  171966. +EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel
  171967. +EXTRA_CFLAGS += -I$(AQARCH)/hal/kernel
  171968. +EXTRA_CFLAGS += -I$(AQROOT)/hal/os/linux/kernel
  171969. +
  171970. +ifeq ($(VIVANTE_ENABLE_VG), 1)
  171971. +EXTRA_CFLAGS += -I$(AQVGARCH)/hal/kernel
  171972. +endif
  171973. +
  171974. +obj-$(CONFIG_MXC_GPU_VIV) += galcore.o
  171975. +
  171976. +galcore-objs := $(OBJS)
  171977. +
  171978. +endif
  171979. diff -Nur linux-3.14.17/drivers/mxc/gpu-viv/Kconfig linux-imx6-3.14/drivers/mxc/gpu-viv/Kconfig
  171980. --- linux-3.14.17/drivers/mxc/gpu-viv/Kconfig 1970-01-01 01:00:00.000000000 +0100
  171981. +++ linux-imx6-3.14/drivers/mxc/gpu-viv/Kconfig 2014-09-11 18:06:03.078042276 +0200
  171982. @@ -0,0 +1,9 @@
  171983. +menu "MXC Vivante GPU support"
  171984. + depends on SOC_IMX6Q
  171985. +
  171986. +config MXC_GPU_VIV
  171987. + tristate "MXC Vivante GPU support"
  171988. + ---help---
  171989. + Say Y to get the GPU driver support.
  171990. +
  171991. +endmenu
  171992. diff -Nur linux-3.14.17/drivers/mxc/hdmi-cec/Kconfig linux-imx6-3.14/drivers/mxc/hdmi-cec/Kconfig
  171993. --- linux-3.14.17/drivers/mxc/hdmi-cec/Kconfig 1970-01-01 01:00:00.000000000 +0100
  171994. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/Kconfig 2014-09-11 18:06:03.130042483 +0200
  171995. @@ -0,0 +1,11 @@
  171996. +
  171997. +menu "MXC HDMI CEC (Consumer Electronics Control) support"
  171998. +
  171999. +config MXC_HDMI_CEC
  172000. + tristate "Support for MXC HDMI CEC (Consumer Electronics Control)"
  172001. + depends on MFD_MXC_HDMI
  172002. + depends on FB_MXC_HDMI
  172003. + help
  172004. + The HDMI CEC device implement low level protocol on i.MX6x platforms.
  172005. +
  172006. +endmenu
  172007. diff -Nur linux-3.14.17/drivers/mxc/hdmi-cec/Makefile linux-imx6-3.14/drivers/mxc/hdmi-cec/Makefile
  172008. --- linux-3.14.17/drivers/mxc/hdmi-cec/Makefile 1970-01-01 01:00:00.000000000 +0100
  172009. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/Makefile 2014-09-11 18:06:03.130042483 +0200
  172010. @@ -0,0 +1 @@
  172011. +obj-$(CONFIG_MXC_HDMI_CEC) += mxc_hdmi-cec.o
  172012. diff -Nur linux-3.14.17/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
  172013. --- linux-3.14.17/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 1970-01-01 01:00:00.000000000 +0100
  172014. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c 2014-09-11 18:06:03.130042483 +0200
  172015. @@ -0,0 +1,629 @@
  172016. +/*
  172017. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  172018. + */
  172019. +
  172020. +/*
  172021. + * The code contained herein is licensed under the GNU General Public
  172022. + * License. You may obtain a copy of the GNU General Public License
  172023. + * Version 2 or later at the following locations:
  172024. + *
  172025. + * http://www.opensource.org/licenses/gpl-license.html
  172026. + * http://www.gnu.org/copyleft/gpl.html
  172027. + */
  172028. +
  172029. +/*!
  172030. + * @file mxc_hdmi-cec.c
  172031. + *
  172032. + * @brief HDMI CEC system initialization and file operation implementation
  172033. + *
  172034. + * @ingroup HDMI
  172035. + */
  172036. +
  172037. +#include <linux/module.h>
  172038. +#include <linux/kernel.h>
  172039. +#include <linux/mm.h>
  172040. +#include <linux/fs.h>
  172041. +#include <linux/stat.h>
  172042. +#include <linux/platform_device.h>
  172043. +#include <linux/poll.h>
  172044. +#include <linux/wait.h>
  172045. +#include <linux/list.h>
  172046. +#include <linux/delay.h>
  172047. +#include <linux/fsl_devices.h>
  172048. +#include <linux/uaccess.h>
  172049. +#include <linux/io.h>
  172050. +#include <linux/slab.h>
  172051. +#include <linux/vmalloc.h>
  172052. +#include <linux/workqueue.h>
  172053. +#include <linux/sizes.h>
  172054. +
  172055. +#include <linux/console.h>
  172056. +#include <linux/types.h>
  172057. +#include <linux/mfd/mxc-hdmi-core.h>
  172058. +#include <linux/pinctrl/consumer.h>
  172059. +
  172060. +#include <video/mxc_hdmi.h>
  172061. +
  172062. +#include "mxc_hdmi-cec.h"
  172063. +
  172064. +
  172065. +#define MAX_MESSAGE_LEN 17
  172066. +
  172067. +#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
  172068. +#define MESSAGE_TYPE_NOACK 2
  172069. +#define MESSAGE_TYPE_DISCONNECTED 3
  172070. +#define MESSAGE_TYPE_CONNECTED 4
  172071. +#define MESSAGE_TYPE_SEND_SUCCESS 5
  172072. +
  172073. +#define CEC_TX_INPROGRESS -1
  172074. +#define CEC_TX_AVAIL 0
  172075. +
  172076. +struct hdmi_cec_priv {
  172077. + int receive_error;
  172078. + int send_error;
  172079. + u8 Logical_address;
  172080. + bool cec_state;
  172081. + u8 last_msg[MAX_MESSAGE_LEN];
  172082. + u8 msg_len;
  172083. + int tx_answer;
  172084. + u16 latest_cec_stat;
  172085. + u8 link_status;
  172086. + spinlock_t irq_lock;
  172087. + struct delayed_work hdmi_cec_work;
  172088. + struct mutex lock;
  172089. +};
  172090. +
  172091. +struct hdmi_cec_event {
  172092. + int event_type;
  172093. + int msg_len;
  172094. + u8 msg[MAX_MESSAGE_LEN];
  172095. + struct list_head list;
  172096. +};
  172097. +
  172098. +
  172099. +static LIST_HEAD(head);
  172100. +
  172101. +static int hdmi_cec_ready = 0;
  172102. +static int hdmi_cec_started;
  172103. +static int hdmi_cec_major;
  172104. +static struct class *hdmi_cec_class;
  172105. +static struct hdmi_cec_priv hdmi_cec_data;
  172106. +static u8 open_count;
  172107. +
  172108. +static wait_queue_head_t hdmi_cec_queue;
  172109. +static wait_queue_head_t tx_cec_queue;
  172110. +
  172111. +static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
  172112. +{
  172113. + struct hdmi_cec_priv *hdmi_cec = data;
  172114. + u16 cec_stat = 0;
  172115. + unsigned long flags;
  172116. + u8 phy_stat0;
  172117. + irqreturn_t ret = IRQ_HANDLED;
  172118. +
  172119. + spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
  172120. +
  172121. + hdmi_writeb(0x7f, HDMI_IH_MUTE_CEC_STAT0);
  172122. +
  172123. + cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
  172124. + hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
  172125. + phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
  172126. +
  172127. + if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
  172128. + HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
  172129. + HDMI_IH_CEC_STAT0_DONE)) == 0) {
  172130. + ret = IRQ_NONE;
  172131. + cec_stat = 0;
  172132. + }
  172133. + if (hdmi_cec->link_status ^ phy_stat0) {
  172134. + /* HPD value changed */
  172135. + hdmi_cec->link_status = phy_stat0;
  172136. + if (hdmi_cec->link_status)
  172137. + cec_stat |= 0x80; /* Connected */
  172138. + else
  172139. + cec_stat |= 0x100; /* Disconnected */
  172140. + }
  172141. + pr_debug("HDMI CEC interrupt received\n");
  172142. + hdmi_cec->latest_cec_stat = cec_stat ;
  172143. +
  172144. + schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
  172145. +
  172146. + spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
  172147. +
  172148. + return ret;
  172149. +}
  172150. +
  172151. +void mxc_hdmi_cec_handle(u16 cec_stat)
  172152. +{
  172153. + u8 val = 0, i = 0;
  172154. + struct hdmi_cec_event *event = NULL;
  172155. + /*The current transmission is successful (for initiator only).*/
  172156. + if (!open_count)
  172157. + return;
  172158. +
  172159. + if (cec_stat & HDMI_IH_CEC_STAT0_DONE) {
  172160. + hdmi_cec_data.tx_answer = cec_stat;
  172161. + wake_up(&tx_cec_queue);
  172162. + }
  172163. + /*EOM is detected so that the received data is ready in the receiver data buffer*/
  172164. + if (cec_stat & HDMI_IH_CEC_STAT0_EOM) {
  172165. + hdmi_writeb(0x02, HDMI_IH_CEC_STAT0);
  172166. + event = vmalloc(sizeof(struct hdmi_cec_event));
  172167. + if (NULL == event) {
  172168. + pr_err("%s: Not enough memory!\n", __func__);
  172169. + return;
  172170. + }
  172171. + memset(event, 0, sizeof(struct hdmi_cec_event));
  172172. + event->msg_len = hdmi_readb(HDMI_CEC_RX_CNT);
  172173. + if (!event->msg_len) {
  172174. + pr_err("%s: Invalid CEC message length!\n", __func__);
  172175. + return;
  172176. + }
  172177. + event->event_type = MESSAGE_TYPE_RECEIVE_SUCCESS;
  172178. + for (i = 0; i < event->msg_len; i++)
  172179. + event->msg[i] = hdmi_readb(HDMI_CEC_RX_DATA0+i);
  172180. + hdmi_writeb(0x0, HDMI_CEC_LOCK);
  172181. + mutex_lock(&hdmi_cec_data.lock);
  172182. + list_add_tail(&event->list, &head);
  172183. + mutex_unlock(&hdmi_cec_data.lock);
  172184. + wake_up(&hdmi_cec_queue);
  172185. + }
  172186. + /*An error is detected on cec line (for initiator only). */
  172187. + if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) {
  172188. + mutex_lock(&hdmi_cec_data.lock);
  172189. + hdmi_cec_data.send_error++;
  172190. + if (hdmi_cec_data.send_error > 2) {
  172191. + pr_err("%s:Re-transmission is attempted more than 2 times!\n", __func__);
  172192. + hdmi_cec_data.send_error = 0;
  172193. + mutex_unlock(&hdmi_cec_data.lock);
  172194. + hdmi_cec_data.tx_answer = cec_stat;
  172195. + wake_up(&tx_cec_queue);
  172196. + return;
  172197. + }
  172198. + for (i = 0; i < hdmi_cec_data.msg_len; i++)
  172199. + hdmi_writeb(hdmi_cec_data.last_msg[i], HDMI_CEC_TX_DATA0+i);
  172200. + hdmi_writeb(hdmi_cec_data.msg_len, HDMI_CEC_TX_CNT);
  172201. + val = hdmi_readb(HDMI_CEC_CTRL);
  172202. + val |= 0x01;
  172203. + hdmi_writeb(val, HDMI_CEC_CTRL);
  172204. + mutex_unlock(&hdmi_cec_data.lock);
  172205. + }
  172206. + /*A frame is not acknowledged in a directly addressed message. Or a frame is negatively acknowledged in
  172207. + a broadcast message (for initiator only).*/
  172208. + if (cec_stat & HDMI_IH_CEC_STAT0_NACK) {
  172209. + hdmi_cec_data.tx_answer = cec_stat;
  172210. + wake_up(&tx_cec_queue);
  172211. + }
  172212. + /*An error is notified by a follower. Abnormal logic data bit error (for follower).*/
  172213. + if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_FOLL) {
  172214. + hdmi_cec_data.receive_error++;
  172215. + }
  172216. + /*HDMI cable connected*/
  172217. + if (cec_stat & 0x80) {
  172218. + pr_info("HDMI link connected\n");
  172219. + event = vmalloc(sizeof(struct hdmi_cec_event));
  172220. + if (NULL == event) {
  172221. + pr_err("%s: Not enough memory\n", __func__);
  172222. + return;
  172223. + }
  172224. + memset(event, 0, sizeof(struct hdmi_cec_event));
  172225. + event->event_type = MESSAGE_TYPE_CONNECTED;
  172226. + mutex_lock(&hdmi_cec_data.lock);
  172227. + list_add_tail(&event->list, &head);
  172228. + mutex_unlock(&hdmi_cec_data.lock);
  172229. + wake_up(&hdmi_cec_queue);
  172230. + }
  172231. + /*HDMI cable disconnected*/
  172232. + if (cec_stat & 0x100) {
  172233. + pr_info("HDMI link disconnected\n");
  172234. + event = vmalloc(sizeof(struct hdmi_cec_event));
  172235. + if (NULL == event) {
  172236. + pr_err("%s: Not enough memory!\n", __func__);
  172237. + return;
  172238. + }
  172239. + memset(event, 0, sizeof(struct hdmi_cec_event));
  172240. + event->event_type = MESSAGE_TYPE_DISCONNECTED;
  172241. + mutex_lock(&hdmi_cec_data.lock);
  172242. + list_add_tail(&event->list, &head);
  172243. + mutex_unlock(&hdmi_cec_data.lock);
  172244. + wake_up(&hdmi_cec_queue);
  172245. + }
  172246. + return;
  172247. +}
  172248. +EXPORT_SYMBOL(mxc_hdmi_cec_handle);
  172249. +static void mxc_hdmi_cec_worker(struct work_struct *work)
  172250. +{
  172251. + u8 val;
  172252. + mxc_hdmi_cec_handle(hdmi_cec_data.latest_cec_stat);
  172253. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
  172254. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  172255. +}
  172256. +
  172257. +/*!
  172258. + * @brief open function for cec file operation
  172259. + *
  172260. + * @return 0 on success or negative error code on error
  172261. + */
  172262. +static int hdmi_cec_open(struct inode *inode, struct file *filp)
  172263. +{
  172264. + mutex_lock(&hdmi_cec_data.lock);
  172265. + if (open_count) {
  172266. + mutex_unlock(&hdmi_cec_data.lock);
  172267. + return -EBUSY;
  172268. + }
  172269. + open_count = 1;
  172270. + filp->private_data = (void *)(&hdmi_cec_data);
  172271. + hdmi_cec_data.Logical_address = 15;
  172272. + hdmi_cec_data.cec_state = false;
  172273. + mutex_unlock(&hdmi_cec_data.lock);
  172274. + return 0;
  172275. +}
  172276. +
  172277. +static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
  172278. + loff_t *ppos)
  172279. +{
  172280. + struct hdmi_cec_event *event = NULL;
  172281. + pr_debug("function : %s\n", __func__);
  172282. +
  172283. + if (!open_count)
  172284. + return -ENODEV;
  172285. + mutex_lock(&hdmi_cec_data.lock);
  172286. + if (false == hdmi_cec_data.cec_state) {
  172287. + mutex_unlock(&hdmi_cec_data.lock);
  172288. + return -EACCES;
  172289. + }
  172290. +
  172291. + if (list_empty(&head)) {
  172292. + if (file->f_flags & O_NONBLOCK) {
  172293. + mutex_unlock(&hdmi_cec_data.lock);
  172294. + return -EAGAIN;
  172295. + } else {
  172296. + do {
  172297. + mutex_unlock(&hdmi_cec_data.lock);
  172298. + if (wait_event_interruptible(hdmi_cec_queue, (!list_empty(&head))))
  172299. + return -ERESTARTSYS;
  172300. + mutex_lock(&hdmi_cec_data.lock);
  172301. + } while (list_empty(&head));
  172302. + }
  172303. + }
  172304. +
  172305. + event = list_first_entry(&head, struct hdmi_cec_event, list);
  172306. + list_del(&event->list);
  172307. + mutex_unlock(&hdmi_cec_data.lock);
  172308. + if (copy_to_user(buf, event,
  172309. + sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
  172310. + vfree(event);
  172311. + return -EFAULT;
  172312. + }
  172313. + vfree(event);
  172314. + return (sizeof(struct hdmi_cec_event) - sizeof(struct list_head));
  172315. +}
  172316. +
  172317. +static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
  172318. + size_t count, loff_t *ppos)
  172319. +{
  172320. + int ret = 0 , i = 0;
  172321. + u8 msg[MAX_MESSAGE_LEN];
  172322. + u8 msg_len = 0, val = 0;
  172323. +
  172324. + pr_debug("function : %s\n", __func__);
  172325. +
  172326. + if (!open_count)
  172327. + return -ENODEV;
  172328. + mutex_lock(&hdmi_cec_data.lock);
  172329. + if (false == hdmi_cec_data.cec_state) {
  172330. + mutex_unlock(&hdmi_cec_data.lock);
  172331. + return -EACCES;
  172332. + }
  172333. + /* Ensure that there is only one writer who is the only listener of tx_cec_queue */
  172334. + if (hdmi_cec_data.tx_answer != CEC_TX_AVAIL) {
  172335. + mutex_unlock(&hdmi_cec_data.lock);
  172336. + return -EBUSY;
  172337. + }
  172338. + mutex_unlock(&hdmi_cec_data.lock);
  172339. + if (count > MAX_MESSAGE_LEN)
  172340. + return -EINVAL;
  172341. + memset(&msg, 0, MAX_MESSAGE_LEN);
  172342. + ret = copy_from_user(&msg, buf, count);
  172343. + if (ret)
  172344. + return -EACCES;
  172345. + mutex_lock(&hdmi_cec_data.lock);
  172346. + hdmi_cec_data.send_error = 0;
  172347. + hdmi_cec_data.tx_answer = CEC_TX_INPROGRESS;
  172348. + msg_len = count;
  172349. + hdmi_writeb(msg_len, HDMI_CEC_TX_CNT);
  172350. + for (i = 0; i < msg_len; i++)
  172351. + hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0+i);
  172352. + val = hdmi_readb(HDMI_CEC_CTRL);
  172353. + val |= 0x01;
  172354. + hdmi_writeb(val, HDMI_CEC_CTRL);
  172355. + memcpy(hdmi_cec_data.last_msg, msg, msg_len);
  172356. + hdmi_cec_data.msg_len = msg_len;
  172357. + mutex_unlock(&hdmi_cec_data.lock);
  172358. +
  172359. + ret = wait_event_interruptible_timeout(tx_cec_queue, hdmi_cec_data.tx_answer != CEC_TX_INPROGRESS, HZ);
  172360. +
  172361. + if (ret < 0) {
  172362. + ret = -ERESTARTSYS;
  172363. + goto tx_out;
  172364. + }
  172365. +
  172366. + if (hdmi_cec_data.tx_answer & HDMI_IH_CEC_STAT0_DONE)
  172367. + /* msg correctly sent */
  172368. + ret = msg_len;
  172369. + else
  172370. + ret = -EIO;
  172371. +
  172372. + tx_out:
  172373. + hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
  172374. + return ret;
  172375. +}
  172376. +
  172377. +void hdmi_cec_start_device(void)
  172378. +{
  172379. + u8 val;
  172380. +
  172381. + if (!hdmi_cec_ready || hdmi_cec_started)
  172382. + return;
  172383. +
  172384. + val = hdmi_readb(HDMI_MC_CLKDIS);
  172385. + val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  172386. + hdmi_writeb(val, HDMI_MC_CLKDIS);
  172387. + hdmi_writeb(0x02, HDMI_CEC_CTRL);
  172388. + /* Force read unlock */
  172389. + hdmi_writeb(0x0, HDMI_CEC_LOCK);
  172390. + val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
  172391. + hdmi_writeb(val, HDMI_CEC_POLARITY);
  172392. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
  172393. + hdmi_writeb(val, HDMI_CEC_MASK);
  172394. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  172395. + hdmi_cec_data.link_status = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
  172396. + mutex_lock(&hdmi_cec_data.lock);
  172397. + hdmi_cec_data.cec_state = true;
  172398. + mutex_unlock(&hdmi_cec_data.lock);
  172399. +
  172400. + hdmi_cec_started = 1;
  172401. +}
  172402. +EXPORT_SYMBOL(hdmi_cec_start_device);
  172403. +
  172404. +void hdmi_cec_stop_device(void)
  172405. +{
  172406. + u8 val;
  172407. +
  172408. + if (!hdmi_cec_ready || !hdmi_cec_started)
  172409. + return;
  172410. +
  172411. + hdmi_writeb(0x10, HDMI_CEC_CTRL);
  172412. + val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST | \
  172413. + HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
  172414. + hdmi_writeb(val, HDMI_CEC_MASK);
  172415. + hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
  172416. + hdmi_writeb(0x0, HDMI_CEC_POLARITY);
  172417. + val = hdmi_readb(HDMI_MC_CLKDIS);
  172418. + val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
  172419. + hdmi_writeb(val, HDMI_MC_CLKDIS);
  172420. + mutex_lock(&hdmi_cec_data.lock);
  172421. + hdmi_cec_data.cec_state = false;
  172422. + mutex_unlock(&hdmi_cec_data.lock);
  172423. +
  172424. + hdmi_cec_started = 0;
  172425. +}
  172426. +EXPORT_SYMBOL(hdmi_cec_stop_device);
  172427. +
  172428. +/*!
  172429. + * @brief IO ctrl function for vpu file operation
  172430. + * @param cmd IO ctrl command
  172431. + * @return 0 on success or negative error code on error
  172432. + */
  172433. +static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
  172434. + u_long arg)
  172435. +{
  172436. + int ret = 0, status = 0;
  172437. + u8 val = 0, msg = 0;
  172438. + struct mxc_edid_cfg hdmi_edid_cfg;
  172439. + pr_debug("function : %s\n", __func__);
  172440. + if (!open_count)
  172441. + return -ENODEV;
  172442. + switch (cmd) {
  172443. + case HDMICEC_IOC_SETLOGICALADDRESS:
  172444. + mutex_lock(&hdmi_cec_data.lock);
  172445. + if (false == hdmi_cec_data.cec_state) {
  172446. + mutex_unlock(&hdmi_cec_data.lock);
  172447. + pr_err("Trying to set logical address while not started\n");
  172448. + return -EACCES;
  172449. + }
  172450. + hdmi_cec_data.Logical_address = (u8)arg;
  172451. + if (hdmi_cec_data.Logical_address <= 7) {
  172452. + val = 1 << hdmi_cec_data.Logical_address;
  172453. + hdmi_writeb(val, HDMI_CEC_ADDR_L);
  172454. + hdmi_writeb(0, HDMI_CEC_ADDR_H);
  172455. + } else if (hdmi_cec_data.Logical_address > 7 && hdmi_cec_data.Logical_address <= 15) {
  172456. + val = 1 << (hdmi_cec_data.Logical_address - 8);
  172457. + hdmi_writeb(val, HDMI_CEC_ADDR_H);
  172458. + hdmi_writeb(0, HDMI_CEC_ADDR_L);
  172459. + } else
  172460. + ret = -EINVAL;
  172461. + /*Send Polling message with same source and destination address*/
  172462. + if (0 == ret && 15 != hdmi_cec_data.Logical_address) {
  172463. + msg = (hdmi_cec_data.Logical_address << 4)|hdmi_cec_data.Logical_address;
  172464. + hdmi_writeb(1, HDMI_CEC_TX_CNT);
  172465. + hdmi_writeb(msg, HDMI_CEC_TX_DATA0);
  172466. + val = hdmi_readb(HDMI_CEC_CTRL);
  172467. + val |= 0x01;
  172468. + hdmi_writeb(val, HDMI_CEC_CTRL);
  172469. + }
  172470. + mutex_unlock(&hdmi_cec_data.lock);
  172471. + break;
  172472. + case HDMICEC_IOC_STARTDEVICE:
  172473. + hdmi_cec_start_device();
  172474. + break;
  172475. + case HDMICEC_IOC_STOPDEVICE:
  172476. + hdmi_cec_stop_device();
  172477. + break;
  172478. + case HDMICEC_IOC_GETPHYADDRESS:
  172479. + hdmi_get_edid_cfg(&hdmi_edid_cfg);
  172480. + status = copy_to_user((void __user *)arg,
  172481. + &hdmi_edid_cfg.physical_address,
  172482. + 4*sizeof(u8));
  172483. + if (status)
  172484. + ret = -EFAULT;
  172485. + break;
  172486. + default:
  172487. + ret = -EINVAL;
  172488. + break;
  172489. + }
  172490. + return ret;
  172491. +}
  172492. +
  172493. +/*!
  172494. + * @brief Release function for vpu file operation
  172495. + * @return 0 on success or negative error code on error
  172496. + */
  172497. +static int hdmi_cec_release(struct inode *inode, struct file *filp)
  172498. +{
  172499. + mutex_lock(&hdmi_cec_data.lock);
  172500. + if (open_count) {
  172501. + open_count = 0;
  172502. + hdmi_cec_data.cec_state = false;
  172503. + hdmi_cec_data.Logical_address = 15;
  172504. + }
  172505. + mutex_unlock(&hdmi_cec_data.lock);
  172506. +
  172507. + return 0;
  172508. +}
  172509. +
  172510. +static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
  172511. +{
  172512. + unsigned int mask = 0;
  172513. +
  172514. + pr_debug("function : %s\n", __func__);
  172515. +
  172516. + poll_wait(file, &hdmi_cec_queue, wait);
  172517. +
  172518. + mutex_lock(&hdmi_cec_data.lock);
  172519. + if (hdmi_cec_data.tx_answer == CEC_TX_AVAIL)
  172520. + mask = (POLLOUT | POLLWRNORM);
  172521. + if (!list_empty(&head))
  172522. + mask |= (POLLIN | POLLRDNORM);
  172523. + mutex_unlock(&hdmi_cec_data.lock);
  172524. + return mask;
  172525. +}
  172526. +
  172527. +
  172528. +const struct file_operations hdmi_cec_fops = {
  172529. + .owner = THIS_MODULE,
  172530. + .read = hdmi_cec_read,
  172531. + .write = hdmi_cec_write,
  172532. + .open = hdmi_cec_open,
  172533. + .unlocked_ioctl = hdmi_cec_ioctl,
  172534. + .release = hdmi_cec_release,
  172535. + .poll = hdmi_cec_poll,
  172536. +};
  172537. +
  172538. +static int hdmi_cec_dev_probe(struct platform_device *pdev)
  172539. +{
  172540. + int err = 0;
  172541. + struct device *temp_class;
  172542. + struct resource *res;
  172543. + struct pinctrl *pinctrl;
  172544. + int irq = platform_get_irq(pdev, 0);
  172545. +
  172546. + hdmi_cec_major = register_chrdev(hdmi_cec_major, "mxc_hdmi_cec", &hdmi_cec_fops);
  172547. + if (hdmi_cec_major < 0) {
  172548. + dev_err(&pdev->dev, "hdmi_cec: unable to get a major for HDMI CEC\n");
  172549. + err = -EBUSY;
  172550. + goto out;
  172551. + }
  172552. +
  172553. + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  172554. + if (unlikely(res == NULL)) {
  172555. + dev_err(&pdev->dev, "hdmi_cec:No HDMI irq line provided\n");
  172556. + goto err_out_chrdev;
  172557. + }
  172558. + spin_lock_init(&hdmi_cec_data.irq_lock);
  172559. +
  172560. + err = devm_request_irq(&pdev->dev, irq, mxc_hdmi_cec_isr, IRQF_SHARED,
  172561. + dev_name(&pdev->dev), &hdmi_cec_data);
  172562. + if (err < 0) {
  172563. + dev_err(&pdev->dev, "hdmi_cec:Unable to request irq: %d\n", err);
  172564. + goto err_out_chrdev;
  172565. + }
  172566. +
  172567. + hdmi_cec_class = class_create(THIS_MODULE, "mxc_hdmi_cec");
  172568. + if (IS_ERR(hdmi_cec_class)) {
  172569. + err = PTR_ERR(hdmi_cec_class);
  172570. + goto err_out_chrdev;
  172571. + }
  172572. +
  172573. + temp_class = device_create(hdmi_cec_class, NULL, MKDEV(hdmi_cec_major, 0),
  172574. + NULL, "mxc_hdmi_cec");
  172575. + if (IS_ERR(temp_class)) {
  172576. + err = PTR_ERR(temp_class);
  172577. + goto err_out_class;
  172578. + }
  172579. +
  172580. + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  172581. + if (IS_ERR(pinctrl)) {
  172582. + dev_err(&pdev->dev, "can't get/select CEC pinctrl\n");
  172583. + goto err_out_class;
  172584. + }
  172585. +
  172586. + init_waitqueue_head(&hdmi_cec_queue);
  172587. + init_waitqueue_head(&tx_cec_queue);
  172588. +
  172589. + INIT_LIST_HEAD(&head);
  172590. +
  172591. + mutex_init(&hdmi_cec_data.lock);
  172592. + hdmi_cec_data.Logical_address = 15;
  172593. + hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
  172594. + platform_set_drvdata(pdev, &hdmi_cec_data);
  172595. + INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, mxc_hdmi_cec_worker);
  172596. +
  172597. + dev_info(&pdev->dev, "HDMI CEC initialized\n");
  172598. + hdmi_cec_ready = 1;
  172599. + goto out;
  172600. +
  172601. +err_out_class:
  172602. + device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
  172603. + class_destroy(hdmi_cec_class);
  172604. +err_out_chrdev:
  172605. + unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
  172606. +out:
  172607. + return err;
  172608. +}
  172609. +
  172610. +static int hdmi_cec_dev_remove(struct platform_device *pdev)
  172611. +{
  172612. + if (hdmi_cec_data.cec_state)
  172613. + hdmi_cec_stop_device();
  172614. + if (hdmi_cec_major > 0) {
  172615. + device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
  172616. + class_destroy(hdmi_cec_class);
  172617. + unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
  172618. + hdmi_cec_major = 0;
  172619. +}
  172620. + return 0;
  172621. +}
  172622. +
  172623. +static const struct of_device_id imx_hdmi_cec_match[] = {
  172624. + { .compatible = "fsl,imx6q-hdmi-cec", },
  172625. + { .compatible = "fsl,imx6dl-hdmi-cec", },
  172626. + { /* sentinel */ }
  172627. +};
  172628. +
  172629. +static struct platform_driver mxc_hdmi_cec_driver = {
  172630. + .probe = hdmi_cec_dev_probe,
  172631. + .remove = hdmi_cec_dev_remove,
  172632. + .driver = {
  172633. + .name = "mxc_hdmi_cec",
  172634. + .of_match_table = imx_hdmi_cec_match,
  172635. + },
  172636. +};
  172637. +
  172638. +module_platform_driver(mxc_hdmi_cec_driver);
  172639. +
  172640. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  172641. +MODULE_DESCRIPTION("Linux HDMI CEC driver for Freescale i.MX/MXC");
  172642. +MODULE_LICENSE("GPL");
  172643. +MODULE_ALIAS("platform:mxc_hdmi_cec");
  172644. +
  172645. diff -Nur linux-3.14.17/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h
  172646. --- linux-3.14.17/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h 1970-01-01 01:00:00.000000000 +0100
  172647. +++ linux-imx6-3.14/drivers/mxc/hdmi-cec/mxc_hdmi-cec.h 2014-09-11 18:06:03.130042483 +0200
  172648. @@ -0,0 +1,38 @@
  172649. +/*
  172650. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  172651. + */
  172652. +
  172653. +/*
  172654. + * The code contained herein is licensed under the GNU General Public
  172655. + * License. You may obtain a copy of the GNU General Public License
  172656. + * Version 2 or later at the following locations:
  172657. + *
  172658. + * http://www.opensource.org/licenses/gpl-license.html
  172659. + * http://www.gnu.org/copyleft/gpl.html
  172660. + */
  172661. +#ifndef _HDMICEC_H_
  172662. +#define _HDMICEC_H_
  172663. +#include <linux/ioctl.h>
  172664. +
  172665. +/*
  172666. + * Ioctl definitions
  172667. + */
  172668. +
  172669. +/* Use 'k' as magic number */
  172670. +#define HDMICEC_IOC_MAGIC 'H'
  172671. +/*
  172672. + * S means "Set" through a ptr,
  172673. + * T means "Tell" directly with the argument value
  172674. + * G means "Get": reply by setting through a pointer
  172675. + * Q means "Query": response is on the return value
  172676. + * X means "eXchange": G and S atomically
  172677. + * H means "sHift": T and Q atomically
  172678. + */
  172679. +#define HDMICEC_IOC_SETLOGICALADDRESS \
  172680. + _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char)
  172681. +#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2)
  172682. +#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3)
  172683. +#define HDMICEC_IOC_GETPHYADDRESS \
  172684. + _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4])
  172685. +
  172686. +#endif /* !_HDMICEC_H_ */
  172687. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
  172688. --- linux-3.14.17/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c 1970-01-01 01:00:00.000000000 +0100
  172689. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c 2014-09-11 18:06:03.130042483 +0200
  172690. @@ -0,0 +1,495 @@
  172691. +/*
  172692. + * Copyright 2009-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  172693. + */
  172694. +
  172695. +/*
  172696. + * The code contained herein is licensed under the GNU General Public
  172697. + * License. You may obtain a copy of the GNU General Public License
  172698. + * Version 2 or later at the following locations:
  172699. + *
  172700. + * http://www.opensource.org/licenses/gpl-license.html
  172701. + * http://www.gnu.org/copyleft/gpl.html
  172702. + */
  172703. +
  172704. +/*
  172705. + * @file ipu_calc_stripes_sizes.c
  172706. + *
  172707. + * @brief IPU IC functions
  172708. + *
  172709. + * @ingroup IPU
  172710. + */
  172711. +
  172712. +#include <linux/ipu-v3.h>
  172713. +#include <linux/module.h>
  172714. +#include <linux/math64.h>
  172715. +
  172716. +#define BPP_32 0
  172717. +#define BPP_16 3
  172718. +#define BPP_8 5
  172719. +#define BPP_24 1
  172720. +#define BPP_12 4
  172721. +#define BPP_18 2
  172722. +
  172723. +static u32 truncate(u32 up, /* 0: down; else: up */
  172724. + u64 a, /* must be non-negative */
  172725. + u32 b)
  172726. +{
  172727. + u32 d;
  172728. + u64 div;
  172729. + div = div_u64(a, b);
  172730. + d = b * (div >> 32);
  172731. + if (up && (a > (((u64)d) << 32)))
  172732. + return d+b;
  172733. + else
  172734. + return d;
  172735. +}
  172736. +
  172737. +static unsigned int f_calc(unsigned int pfs, unsigned int bpp, unsigned int *write)
  172738. +{/* return input_f */
  172739. + unsigned int f_calculated = 0;
  172740. + switch (pfs) {
  172741. + case IPU_PIX_FMT_YVU422P:
  172742. + case IPU_PIX_FMT_YUV422P:
  172743. + case IPU_PIX_FMT_YUV420P2:
  172744. + case IPU_PIX_FMT_YUV420P:
  172745. + case IPU_PIX_FMT_YVU420P:
  172746. + case IPU_PIX_FMT_YUV444P:
  172747. + f_calculated = 16;
  172748. + break;
  172749. +
  172750. + case IPU_PIX_FMT_RGB565:
  172751. + case IPU_PIX_FMT_YUYV:
  172752. + case IPU_PIX_FMT_UYVY:
  172753. + f_calculated = 8;
  172754. + break;
  172755. +
  172756. + case IPU_PIX_FMT_NV12:
  172757. + f_calculated = 8;
  172758. + break;
  172759. +
  172760. + default:
  172761. + f_calculated = 0;
  172762. + break;
  172763. +
  172764. + }
  172765. + if (!f_calculated) {
  172766. + switch (bpp) {
  172767. + case BPP_32:
  172768. + f_calculated = 2;
  172769. + break;
  172770. +
  172771. + case BPP_16:
  172772. + f_calculated = 4;
  172773. + break;
  172774. +
  172775. + case BPP_8:
  172776. + case BPP_24:
  172777. + f_calculated = 8;
  172778. + break;
  172779. +
  172780. + case BPP_12:
  172781. + f_calculated = 16;
  172782. + break;
  172783. +
  172784. + case BPP_18:
  172785. + f_calculated = 32;
  172786. + break;
  172787. +
  172788. + default:
  172789. + f_calculated = 0;
  172790. + break;
  172791. + }
  172792. + }
  172793. + return f_calculated;
  172794. +}
  172795. +
  172796. +
  172797. +static unsigned int m_calc(unsigned int pfs)
  172798. +{
  172799. + unsigned int m_calculated = 0;
  172800. + switch (pfs) {
  172801. + case IPU_PIX_FMT_YUV420P2:
  172802. + case IPU_PIX_FMT_YUV420P:
  172803. + case IPU_PIX_FMT_YVU422P:
  172804. + case IPU_PIX_FMT_YUV422P:
  172805. + case IPU_PIX_FMT_YVU420P:
  172806. + case IPU_PIX_FMT_YUV444P:
  172807. + m_calculated = 16;
  172808. + break;
  172809. +
  172810. + case IPU_PIX_FMT_NV12:
  172811. + case IPU_PIX_FMT_YUYV:
  172812. + case IPU_PIX_FMT_UYVY:
  172813. + m_calculated = 8;
  172814. + break;
  172815. +
  172816. + default:
  172817. + m_calculated = 8;
  172818. + break;
  172819. +
  172820. + }
  172821. + return m_calculated;
  172822. +}
  172823. +
  172824. +static int calc_split_resize_coeffs(unsigned int inSize, unsigned int outSize,
  172825. + unsigned int *resizeCoeff,
  172826. + unsigned int *downsizeCoeff)
  172827. +{
  172828. + uint32_t tempSize;
  172829. + uint32_t tempDownsize;
  172830. +
  172831. + if (inSize > 4096) {
  172832. + pr_debug("IC input size(%d) cannot exceed 4096\n",
  172833. + inSize);
  172834. + return -EINVAL;
  172835. + }
  172836. +
  172837. + if (outSize > 1024) {
  172838. + pr_debug("IC output size(%d) cannot exceed 1024\n",
  172839. + outSize);
  172840. + return -EINVAL;
  172841. + }
  172842. +
  172843. + if ((outSize << 3) < inSize) {
  172844. + pr_debug("IC cannot downsize more than 8:1\n");
  172845. + return -EINVAL;
  172846. + }
  172847. +
  172848. + /* Compute downsizing coefficient */
  172849. + /* Output of downsizing unit cannot be more than 1024 */
  172850. + tempDownsize = 0;
  172851. + tempSize = inSize;
  172852. + while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
  172853. + (tempDownsize < 2)) {
  172854. + tempSize >>= 1;
  172855. + tempDownsize++;
  172856. + }
  172857. + *downsizeCoeff = tempDownsize;
  172858. +
  172859. + /* compute resizing coefficient using the following equation:
  172860. + resizeCoeff = M*(SI -1)/(SO - 1)
  172861. + where M = 2^13, SI - input size, SO - output size */
  172862. + *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
  172863. + if (*resizeCoeff >= 16384L) {
  172864. + pr_debug("Overflow on IC resize coefficient.\n");
  172865. + return -EINVAL;
  172866. + }
  172867. +
  172868. + pr_debug("resizing from %u -> %u pixels, "
  172869. + "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
  172870. + *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
  172871. + ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
  172872. +
  172873. + return 0;
  172874. +}
  172875. +
  172876. +/* Stripe parameters calculator */
  172877. +/**************************************************************************
  172878. +Notes:
  172879. +MSW = the maximal width allowed for a stripe
  172880. + i.MX31: 720, i.MX35: 800, i.MX37/51/53: 1024
  172881. +cirr = the maximal inverse resizing ratio for which overlap in the input
  172882. + is requested; typically cirr~2
  172883. +flags
  172884. + bit 0 - equal_stripes
  172885. + 0 each stripe is allowed to have independent parameters
  172886. + for maximal image quality
  172887. + 1 the stripes are requested to have identical parameters
  172888. + (except the base address), for maximal performance
  172889. + bit 1 - vertical/horizontal
  172890. + 0 horizontal
  172891. + 1 vertical
  172892. +
  172893. +If performance is the top priority (above image quality)
  172894. + Avoid overlap, by setting CIRR = 0
  172895. + This will also force effectively identical_stripes = 1
  172896. + Choose IF & OF that corresponds to the same IOX/SX for both stripes
  172897. + Choose IFW & OFW such that
  172898. + IFW/IM, IFW/IF, OFW/OM, OFW/OF are even integers
  172899. + The function returns an error status:
  172900. + 0: no error
  172901. + 1: invalid input parameters -> aborted without result
  172902. + Valid parameters should satisfy the following conditions
  172903. + IFW <= OFW, otherwise downsizing is required
  172904. + - which is not supported yet
  172905. + 4 <= IFW,OFW, so some interpolation may be needed even without overlap
  172906. + IM, OM, IF, OF should not vanish
  172907. + 2*IF <= IFW
  172908. + so the frame can be split to two equal stripes, even without overlap
  172909. + 2*(OF+IF/irr_opt) <= OFW
  172910. + so a valid positive INW exists even for equal stripes
  172911. + OF <= MSW, otherwise, the left stripe cannot be sufficiently large
  172912. + MSW < OFW, so splitting to stripes is required
  172913. + OFW <= 2*MSW, so two stripes are sufficient
  172914. + (this also implies that 2<=MSW)
  172915. + 2: OF is not a multiple of OM - not fully-supported yet
  172916. + Output is produced but OW is not guaranited to be a multiple of OM
  172917. + 4: OFW reduced to be a multiple of OM
  172918. + 8: CIRR > 1: truncated to 1
  172919. + Overlap is not supported (and not needed) y for upsizing)
  172920. +**************************************************************************/
  172921. +int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
  172922. + /* input frame width;>1 */
  172923. + unsigned int output_frame_width, /* output frame width; >1 */
  172924. + const unsigned int maximal_stripe_width,
  172925. + /* the maximal width allowed for a stripe */
  172926. + const unsigned long long cirr, /* see above */
  172927. + const unsigned int flags, /* see above */
  172928. + u32 input_pixelformat,/* pixel format after of read channel*/
  172929. + u32 output_pixelformat,/* pixel format after of write channel*/
  172930. + struct stripe_param *left,
  172931. + struct stripe_param *right)
  172932. +{
  172933. + const unsigned int irr_frac_bits = 13;
  172934. + const unsigned long irr_steps = 1 << irr_frac_bits;
  172935. + const u64 dirr = ((u64)1) << (32 - 2);
  172936. + /* The maximum relative difference allowed between the irrs */
  172937. + const u64 cr = ((u64)4) << 32;
  172938. + /* The importance ratio between the two terms in the cost function below */
  172939. +
  172940. + unsigned int status;
  172941. + unsigned int temp;
  172942. + unsigned int onw_min;
  172943. + unsigned int inw = 0, onw = 0, inw_best = 0;
  172944. + /* number of pixels in the left stripe NOT hidden by the right stripe */
  172945. + u64 irr_opt; /* the optimal inverse resizing ratio */
  172946. + u64 rr_opt; /* the optimal resizing ratio = 1/irr_opt*/
  172947. + u64 dinw; /* the misalignment between the stripes */
  172948. + /* (measured in units of input columns) */
  172949. + u64 difwl, difwr = 0;
  172950. + /* The number of input columns not reflected in the output */
  172951. + /* the resizing ratio used for the right stripe is */
  172952. + /* left->irr and right->irr respectively */
  172953. + u64 cost, cost_min;
  172954. + u64 div; /* result of division */
  172955. + bool equal_stripes = (flags & 0x1) != 0;
  172956. + bool vertical = (flags & 0x2) != 0;
  172957. +
  172958. + unsigned int input_m, input_f, output_m, output_f; /* parameters for upsizing by stripes */
  172959. + unsigned int resize_coeff;
  172960. + unsigned int downsize_coeff;
  172961. +
  172962. + status = 0;
  172963. +
  172964. + if (vertical) {
  172965. + input_f = 2;
  172966. + input_m = 8;
  172967. + output_f = 8;
  172968. + output_m = 2;
  172969. + } else {
  172970. + input_f = f_calc(input_pixelformat, 0, NULL);
  172971. + input_m = m_calc(input_pixelformat);
  172972. + output_f = input_m;
  172973. + output_m = m_calc(output_pixelformat);
  172974. + }
  172975. + if ((input_frame_width < 4) || (output_frame_width < 4))
  172976. + return 1;
  172977. +
  172978. + irr_opt = div_u64((((u64)(input_frame_width - 1)) << 32),
  172979. + (output_frame_width - 1));
  172980. + rr_opt = div_u64((((u64)(output_frame_width - 1)) << 32),
  172981. + (input_frame_width - 1));
  172982. +
  172983. + if ((input_m == 0) || (output_m == 0) || (input_f == 0) || (output_f == 0)
  172984. + || (input_frame_width < (2 * input_f))
  172985. + || ((((u64)output_frame_width) << 32) <
  172986. + (2 * ((((u64)output_f) << 32) + (input_f * rr_opt))))
  172987. + || (maximal_stripe_width < output_f)
  172988. + || ((output_frame_width <= maximal_stripe_width)
  172989. + && (equal_stripes == 0))
  172990. + || ((2 * maximal_stripe_width) < output_frame_width))
  172991. + return 1;
  172992. +
  172993. + if (output_f % output_m)
  172994. + status += 2;
  172995. +
  172996. + temp = truncate(0, (((u64)output_frame_width) << 32), output_m);
  172997. + if (temp < output_frame_width) {
  172998. + output_frame_width = temp;
  172999. + status += 4;
  173000. + }
  173001. +
  173002. + pr_debug("---------------->\n"
  173003. + "if = %d\n"
  173004. + "im = %d\n"
  173005. + "of = %d\n"
  173006. + "om = %d\n"
  173007. + "irr_opt = %llu\n"
  173008. + "rr_opt = %llu\n"
  173009. + "cirr = %llu\n"
  173010. + "pixel in = %08x\n"
  173011. + "pixel out = %08x\n"
  173012. + "ifw = %d\n"
  173013. + "ofwidth = %d\n",
  173014. + input_f,
  173015. + input_m,
  173016. + output_f,
  173017. + output_m,
  173018. + irr_opt,
  173019. + rr_opt,
  173020. + cirr,
  173021. + input_pixelformat,
  173022. + output_pixelformat,
  173023. + input_frame_width,
  173024. + output_frame_width
  173025. + );
  173026. +
  173027. + if (equal_stripes) {
  173028. + if ((irr_opt > cirr) /* overlap in the input is not requested */
  173029. + && ((input_frame_width % (input_m << 1)) == 0)
  173030. + && ((input_frame_width % (input_f << 1)) == 0)
  173031. + && ((output_frame_width % (output_m << 1)) == 0)
  173032. + && ((output_frame_width % (output_f << 1)) == 0)) {
  173033. + /* without overlap */
  173034. + left->input_width = right->input_width = right->input_column =
  173035. + input_frame_width >> 1;
  173036. + left->output_width = right->output_width = right->output_column =
  173037. + output_frame_width >> 1;
  173038. + left->input_column = 0;
  173039. + left->output_column = 0;
  173040. + div = div_u64(((((u64)irr_steps) << 32) *
  173041. + (right->input_width - 1)), (right->output_width - 1));
  173042. + left->irr = right->irr = truncate(0, div, 1);
  173043. + } else { /* with overlap */
  173044. + onw = truncate(0, (((u64)output_frame_width - 1) << 32) >> 1,
  173045. + output_f);
  173046. + inw = truncate(0, onw * irr_opt, input_f);
  173047. + /* this is the maximal inw which allows the same resizing ratio */
  173048. + /* in both stripes */
  173049. + onw = truncate(1, (inw * rr_opt), output_f);
  173050. + div = div_u64((((u64)(irr_steps * inw)) <<
  173051. + 32), onw);
  173052. + left->irr = right->irr = truncate(0, div, 1);
  173053. + left->output_width = right->output_width =
  173054. + output_frame_width - onw;
  173055. + /* These are valid assignments for output_width, */
  173056. + /* assuming output_f is a multiple of output_m */
  173057. + div = (((u64)(left->output_width-1) * (left->irr)) << 32);
  173058. + div = (((u64)1) << 32) + div_u64(div, irr_steps);
  173059. +
  173060. + left->input_width = right->input_width = truncate(1, div, input_m);
  173061. +
  173062. + div = div_u64((((u64)((right->output_width - 1) * right->irr)) <<
  173063. + 32), irr_steps);
  173064. + difwr = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
  173065. + div = div_u64((difwr + (((u64)input_f) << 32)), 2);
  173066. + left->input_column = truncate(0, div, input_f);
  173067. +
  173068. +
  173069. + /* This splits the truncated input columns evenly */
  173070. + /* between the left and right margins */
  173071. + right->input_column = left->input_column + inw;
  173072. + left->output_column = 0;
  173073. + right->output_column = onw;
  173074. + }
  173075. + if (left->input_width > left->output_width) {
  173076. + if (calc_split_resize_coeffs(left->input_width,
  173077. + left->output_width,
  173078. + &resize_coeff,
  173079. + &downsize_coeff) < 0)
  173080. + return -EINVAL;
  173081. +
  173082. + if (downsize_coeff > 0) {
  173083. + left->irr = right->irr =
  173084. + (downsize_coeff << 14) | resize_coeff;
  173085. + }
  173086. + }
  173087. + pr_debug("inw %d, onw %d, ilw %d, ilc %d, olw %d,"
  173088. + " irw %d, irc %d, orw %d, orc %d, "
  173089. + "difwr %llu, lirr %u\n",
  173090. + inw, onw, left->input_width,
  173091. + left->input_column, left->output_width,
  173092. + right->input_width, right->input_column,
  173093. + right->output_width,
  173094. + right->output_column, difwr, left->irr);
  173095. + } else { /* independent stripes */
  173096. + onw_min = output_frame_width - maximal_stripe_width;
  173097. + /* onw is a multiple of output_f, in the range */
  173098. + /* [max(output_f,output_frame_width-maximal_stripe_width),*/
  173099. + /*min(output_frame_width-2,maximal_stripe_width)] */
  173100. + /* definitely beyond the cost of any valid setting */
  173101. + cost_min = (((u64)input_frame_width) << 32) + cr;
  173102. + onw = truncate(0, ((u64)maximal_stripe_width), output_f);
  173103. + if (output_frame_width - onw == 1)
  173104. + onw -= output_f; /* => onw and output_frame_width-1-onw are positive */
  173105. + inw = truncate(0, onw * irr_opt, input_f);
  173106. + /* this is the maximal inw which allows the same resizing ratio */
  173107. + /* in both stripes */
  173108. + onw = truncate(1, inw * rr_opt, output_f);
  173109. + do {
  173110. + div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
  173111. + left->irr = truncate(0, div, 1);
  173112. + div = div_u64((((u64)(onw * left->irr)) << 32),
  173113. + irr_steps);
  173114. + dinw = (((u64)inw) << 32) - div;
  173115. +
  173116. + div = div_u64((((u64)((output_frame_width - 1 - onw) * left->irr)) <<
  173117. + 32), irr_steps);
  173118. +
  173119. + difwl = (((u64)(input_frame_width - 1 - inw)) << 32) - div;
  173120. +
  173121. + cost = difwl + (((u64)(cr * dinw)) >> 32);
  173122. +
  173123. + if (cost < cost_min) {
  173124. + inw_best = inw;
  173125. + cost_min = cost;
  173126. + }
  173127. +
  173128. + inw -= input_f;
  173129. + onw = truncate(1, inw * rr_opt, output_f);
  173130. + /* This is the minimal onw which allows the same resizing ratio */
  173131. + /* in both stripes */
  173132. + } while (onw >= onw_min);
  173133. +
  173134. + inw = inw_best;
  173135. + onw = truncate(1, inw * rr_opt, output_f);
  173136. + div = div_u64((((u64)(irr_steps * inw)) << 32), onw);
  173137. + left->irr = truncate(0, div, 1);
  173138. +
  173139. + left->output_width = onw;
  173140. + right->output_width = output_frame_width - onw;
  173141. + /* These are valid assignments for output_width, */
  173142. + /* assuming output_f is a multiple of output_m */
  173143. + left->input_width = truncate(1, ((u64)(inw + 1)) << 32, input_m);
  173144. + right->input_width = truncate(1, ((u64)(input_frame_width - inw)) <<
  173145. + 32, input_m);
  173146. +
  173147. + div = div_u64((((u64)(irr_steps * (input_frame_width - 1 - inw))) <<
  173148. + 32), (right->output_width - 1));
  173149. + right->irr = truncate(0, div, 1);
  173150. + temp = truncate(0, ((u64)left->irr) * ((((u64)1) << 32) + dirr), 1);
  173151. + if (temp < right->irr)
  173152. + right->irr = temp;
  173153. + div = div_u64(((u64)((right->output_width - 1) * right->irr) <<
  173154. + 32), irr_steps);
  173155. + difwr = (u64)(input_frame_width - 1 - inw) - div;
  173156. +
  173157. +
  173158. + div = div_u64((difwr + (((u64)input_f) << 32)), 2);
  173159. + left->input_column = truncate(0, div, input_f);
  173160. +
  173161. + /* This splits the truncated input columns evenly */
  173162. + /* between the left and right margins */
  173163. + right->input_column = left->input_column + inw;
  173164. + left->output_column = 0;
  173165. + right->output_column = onw;
  173166. + if (left->input_width > left->output_width) {
  173167. + if (calc_split_resize_coeffs(left->input_width,
  173168. + left->output_width,
  173169. + &resize_coeff,
  173170. + &downsize_coeff) < 0)
  173171. + return -EINVAL;
  173172. + left->irr = (downsize_coeff << 14) | resize_coeff;
  173173. + }
  173174. + if (right->input_width > right->output_width) {
  173175. + if (calc_split_resize_coeffs(right->input_width,
  173176. + right->output_width,
  173177. + &resize_coeff,
  173178. + &downsize_coeff) < 0)
  173179. + return -EINVAL;
  173180. + right->irr = (downsize_coeff << 14) | resize_coeff;
  173181. + }
  173182. + }
  173183. + return status;
  173184. +}
  173185. +EXPORT_SYMBOL(ipu_calc_stripes_sizes);
  173186. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_capture.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_capture.c
  173187. --- linux-3.14.17/drivers/mxc/ipu3/ipu_capture.c 1970-01-01 01:00:00.000000000 +0100
  173188. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_capture.c 2014-09-11 18:06:03.130042483 +0200
  173189. @@ -0,0 +1,816 @@
  173190. +/*
  173191. + * Copyright 2008-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  173192. + */
  173193. +
  173194. +/*
  173195. + * The code contained herein is licensed under the GNU General Public
  173196. + * License. You may obtain a copy of the GNU General Public License
  173197. + * Version 2 or later at the following locations:
  173198. + *
  173199. + * http://www.opensource.org/licenses/gpl-license.html
  173200. + * http://www.gnu.org/copyleft/gpl.html
  173201. + */
  173202. +
  173203. +/*!
  173204. + * @file ipu_capture.c
  173205. + *
  173206. + * @brief IPU capture dase functions
  173207. + *
  173208. + * @ingroup IPU
  173209. + */
  173210. +#include <linux/clk.h>
  173211. +#include <linux/delay.h>
  173212. +#include <linux/errno.h>
  173213. +#include <linux/init.h>
  173214. +#include <linux/io.h>
  173215. +#include <linux/ipu-v3.h>
  173216. +#include <linux/module.h>
  173217. +#include <linux/spinlock.h>
  173218. +#include <linux/types.h>
  173219. +
  173220. +#include "ipu_prv.h"
  173221. +#include "ipu_regs.h"
  173222. +
  173223. +/*!
  173224. + * _ipu_csi_mclk_set
  173225. + *
  173226. + * @param ipu ipu handler
  173227. + * @param pixel_clk desired pixel clock frequency in Hz
  173228. + * @param csi csi 0 or csi 1
  173229. + *
  173230. + * @return Returns 0 on success or negative error code on fail
  173231. + */
  173232. +int _ipu_csi_mclk_set(struct ipu_soc *ipu, uint32_t pixel_clk, uint32_t csi)
  173233. +{
  173234. + uint32_t temp;
  173235. + uint32_t div_ratio;
  173236. +
  173237. + div_ratio = (clk_get_rate(ipu->ipu_clk) / pixel_clk) - 1;
  173238. +
  173239. + if (div_ratio > 0xFF || div_ratio < 0) {
  173240. + dev_dbg(ipu->dev, "value of pixel_clk extends normal range\n");
  173241. + return -EINVAL;
  173242. + }
  173243. +
  173244. + temp = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
  173245. + temp &= ~CSI_SENS_CONF_DIVRATIO_MASK;
  173246. + ipu_csi_write(ipu, csi, temp |
  173247. + (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT),
  173248. + CSI_SENS_CONF);
  173249. +
  173250. + return 0;
  173251. +}
  173252. +
  173253. +/*!
  173254. + * ipu_csi_init_interface
  173255. + * Sets initial values for the CSI registers.
  173256. + * The width and height of the sensor and the actual frame size will be
  173257. + * set to the same values.
  173258. + * @param ipu ipu handler
  173259. + * @param width Sensor width
  173260. + * @param height Sensor height
  173261. + * @param pixel_fmt pixel format
  173262. + * @param cfg_param ipu_csi_signal_cfg_t structure
  173263. + * @param csi csi 0 or csi 1
  173264. + *
  173265. + * @return 0 for success, -EINVAL for error
  173266. + */
  173267. +int32_t
  173268. +ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
  173269. + uint32_t pixel_fmt, ipu_csi_signal_cfg_t cfg_param)
  173270. +{
  173271. + uint32_t data = 0;
  173272. + uint32_t csi = cfg_param.csi;
  173273. +
  173274. + /* Set SENS_DATA_FORMAT bits (8, 9 and 10)
  173275. + RGB or YUV444 is 0 which is current value in data so not set
  173276. + explicitly
  173277. + This is also the default value if attempts are made to set it to
  173278. + something invalid. */
  173279. + switch (pixel_fmt) {
  173280. + case IPU_PIX_FMT_YUYV:
  173281. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
  173282. + break;
  173283. + case IPU_PIX_FMT_UYVY:
  173284. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
  173285. + break;
  173286. + case IPU_PIX_FMT_RGB24:
  173287. + case IPU_PIX_FMT_BGR24:
  173288. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB_YUV444;
  173289. + break;
  173290. + case IPU_PIX_FMT_GENERIC:
  173291. + case IPU_PIX_FMT_GENERIC_16:
  173292. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
  173293. + break;
  173294. + case IPU_PIX_FMT_RGB565:
  173295. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565;
  173296. + break;
  173297. + case IPU_PIX_FMT_RGB555:
  173298. + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555;
  173299. + break;
  173300. + default:
  173301. + return -EINVAL;
  173302. + }
  173303. +
  173304. + /* Set the CSI_SENS_CONF register remaining fields */
  173305. + data |= cfg_param.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT |
  173306. + cfg_param.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT |
  173307. + cfg_param.data_pol << CSI_SENS_CONF_DATA_POL_SHIFT |
  173308. + cfg_param.Vsync_pol << CSI_SENS_CONF_VSYNC_POL_SHIFT |
  173309. + cfg_param.Hsync_pol << CSI_SENS_CONF_HSYNC_POL_SHIFT |
  173310. + cfg_param.pixclk_pol << CSI_SENS_CONF_PIX_CLK_POL_SHIFT |
  173311. + cfg_param.ext_vsync << CSI_SENS_CONF_EXT_VSYNC_SHIFT |
  173312. + cfg_param.clk_mode << CSI_SENS_CONF_SENS_PRTCL_SHIFT |
  173313. + cfg_param.pack_tight << CSI_SENS_CONF_PACK_TIGHT_SHIFT |
  173314. + cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT |
  173315. + cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT;
  173316. +
  173317. + _ipu_get(ipu);
  173318. +
  173319. + mutex_lock(&ipu->mutex_lock);
  173320. +
  173321. + ipu_csi_write(ipu, csi, data, CSI_SENS_CONF);
  173322. +
  173323. + /* Setup sensor frame size */
  173324. + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE);
  173325. +
  173326. + /* Set CCIR registers */
  173327. + if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {
  173328. + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
  173329. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  173330. + } else if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) {
  173331. + if (width == 720 && height == 625) {
  173332. + /* PAL case */
  173333. + /*
  173334. + * Field0BlankEnd = 0x6, Field0BlankStart = 0x2,
  173335. + * Field0ActiveEnd = 0x4, Field0ActiveStart = 0
  173336. + */
  173337. + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_1);
  173338. + /*
  173339. + * Field1BlankEnd = 0x7, Field1BlankStart = 0x3,
  173340. + * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1
  173341. + */
  173342. + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_2);
  173343. +
  173344. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  173345. +
  173346. + } else if (width == 720 && height == 525) {
  173347. + /* NTSC case */
  173348. + /*
  173349. + * Field0BlankEnd = 0x7, Field0BlankStart = 0x3,
  173350. + * Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1
  173351. + */
  173352. + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_1);
  173353. + /*
  173354. + * Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
  173355. + * Field1ActiveEnd = 0x4, Field1ActiveStart = 0
  173356. + */
  173357. + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_2);
  173358. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  173359. + } else {
  173360. + dev_err(ipu->dev, "Unsupported CCIR656 interlaced "
  173361. + "video mode\n");
  173362. + mutex_unlock(&ipu->mutex_lock);
  173363. + _ipu_put(ipu);
  173364. + return -EINVAL;
  173365. + }
  173366. + _ipu_csi_ccir_err_detection_enable(ipu, csi);
  173367. + } else if ((cfg_param.clk_mode ==
  173368. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) ||
  173369. + (cfg_param.clk_mode ==
  173370. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR) ||
  173371. + (cfg_param.clk_mode ==
  173372. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR) ||
  173373. + (cfg_param.clk_mode ==
  173374. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR)) {
  173375. + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1);
  173376. + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3);
  173377. + _ipu_csi_ccir_err_detection_enable(ipu, csi);
  173378. + } else if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_GATED_CLK) ||
  173379. + (cfg_param.clk_mode == IPU_CSI_CLK_MODE_NONGATED_CLK)) {
  173380. + _ipu_csi_ccir_err_detection_disable(ipu, csi);
  173381. + }
  173382. +
  173383. + dev_dbg(ipu->dev, "CSI_SENS_CONF = 0x%08X\n",
  173384. + ipu_csi_read(ipu, csi, CSI_SENS_CONF));
  173385. + dev_dbg(ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n",
  173386. + ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE));
  173387. +
  173388. + mutex_unlock(&ipu->mutex_lock);
  173389. +
  173390. + _ipu_put(ipu);
  173391. +
  173392. + return 0;
  173393. +}
  173394. +EXPORT_SYMBOL(ipu_csi_init_interface);
  173395. +
  173396. +/*!
  173397. + * ipu_csi_get_sensor_protocol
  173398. + *
  173399. + * @param ipu ipu handler
  173400. + * @param csi csi 0 or csi 1
  173401. + *
  173402. + * @return Returns sensor protocol
  173403. + */
  173404. +int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi)
  173405. +{
  173406. + int ret;
  173407. + _ipu_get(ipu);
  173408. + ret = (ipu_csi_read(ipu, csi, CSI_SENS_CONF) &
  173409. + CSI_SENS_CONF_SENS_PRTCL_MASK) >>
  173410. + CSI_SENS_CONF_SENS_PRTCL_SHIFT;
  173411. + _ipu_put(ipu);
  173412. + return ret;
  173413. +}
  173414. +EXPORT_SYMBOL(ipu_csi_get_sensor_protocol);
  173415. +
  173416. +/*!
  173417. + * ipu_csi_enable_mclk
  173418. + *
  173419. + * @param ipu ipu handler
  173420. + * @param csi csi 0 or csi 1
  173421. + * @param flag true to enable mclk, false to disable mclk
  173422. + * @param wait true to wait 100ms make clock stable, false not wait
  173423. + *
  173424. + * @return Returns 0 on success
  173425. + */
  173426. +int ipu_csi_enable_mclk(struct ipu_soc *ipu, int csi, bool flag, bool wait)
  173427. +{
  173428. + /* Return immediately if there is no csi_clk to manage */
  173429. + if (ipu->csi_clk[csi] == NULL)
  173430. + return 0;
  173431. +
  173432. + if (flag) {
  173433. + clk_enable(ipu->csi_clk[csi]);
  173434. + if (wait == true)
  173435. + msleep(10);
  173436. + } else {
  173437. + clk_disable(ipu->csi_clk[csi]);
  173438. + }
  173439. +
  173440. + return 0;
  173441. +}
  173442. +EXPORT_SYMBOL(ipu_csi_enable_mclk);
  173443. +
  173444. +/*!
  173445. + * ipu_csi_get_window_size
  173446. + *
  173447. + * @param ipu ipu handler
  173448. + * @param width pointer to window width
  173449. + * @param height pointer to window height
  173450. + * @param csi csi 0 or csi 1
  173451. + */
  173452. +void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi)
  173453. +{
  173454. + uint32_t reg;
  173455. +
  173456. + _ipu_get(ipu);
  173457. +
  173458. + mutex_lock(&ipu->mutex_lock);
  173459. +
  173460. + reg = ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE);
  173461. + *width = (reg & 0xFFFF) + 1;
  173462. + *height = (reg >> 16 & 0xFFFF) + 1;
  173463. +
  173464. + mutex_unlock(&ipu->mutex_lock);
  173465. +
  173466. + _ipu_put(ipu);
  173467. +}
  173468. +EXPORT_SYMBOL(ipu_csi_get_window_size);
  173469. +
  173470. +/*!
  173471. + * ipu_csi_set_window_size
  173472. + *
  173473. + * @param ipu ipu handler
  173474. + * @param width window width
  173475. + * @param height window height
  173476. + * @param csi csi 0 or csi 1
  173477. + */
  173478. +void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi)
  173479. +{
  173480. + _ipu_get(ipu);
  173481. +
  173482. + mutex_lock(&ipu->mutex_lock);
  173483. +
  173484. + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE);
  173485. +
  173486. + mutex_unlock(&ipu->mutex_lock);
  173487. +
  173488. + _ipu_put(ipu);
  173489. +}
  173490. +EXPORT_SYMBOL(ipu_csi_set_window_size);
  173491. +
  173492. +/*!
  173493. + * ipu_csi_set_window_pos
  173494. + *
  173495. + * @param ipu ipu handler
  173496. + * @param left uint32 window x start
  173497. + * @param top uint32 window y start
  173498. + * @param csi csi 0 or csi 1
  173499. + */
  173500. +void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi)
  173501. +{
  173502. + uint32_t temp;
  173503. +
  173504. + _ipu_get(ipu);
  173505. +
  173506. + mutex_lock(&ipu->mutex_lock);
  173507. +
  173508. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  173509. + temp &= ~(CSI_HSC_MASK | CSI_VSC_MASK);
  173510. + temp |= ((top << CSI_VSC_SHIFT) | (left << CSI_HSC_SHIFT));
  173511. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  173512. +
  173513. + mutex_unlock(&ipu->mutex_lock);
  173514. +
  173515. + _ipu_put(ipu);
  173516. +}
  173517. +EXPORT_SYMBOL(ipu_csi_set_window_pos);
  173518. +
  173519. +/*!
  173520. + * _ipu_csi_horizontal_downsize_enable
  173521. + * Enable horizontal downsizing(decimation) by 2.
  173522. + *
  173523. + * @param ipu ipu handler
  173524. + * @param csi csi 0 or csi 1
  173525. + */
  173526. +void _ipu_csi_horizontal_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
  173527. +{
  173528. + uint32_t temp;
  173529. +
  173530. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  173531. + temp |= CSI_HORI_DOWNSIZE_EN;
  173532. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  173533. +}
  173534. +
  173535. +/*!
  173536. + * _ipu_csi_horizontal_downsize_disable
  173537. + * Disable horizontal downsizing(decimation) by 2.
  173538. + *
  173539. + * @param ipu ipu handler
  173540. + * @param csi csi 0 or csi 1
  173541. + */
  173542. +void _ipu_csi_horizontal_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
  173543. +{
  173544. + uint32_t temp;
  173545. +
  173546. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  173547. + temp &= ~CSI_HORI_DOWNSIZE_EN;
  173548. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  173549. +}
  173550. +
  173551. +/*!
  173552. + * _ipu_csi_vertical_downsize_enable
  173553. + * Enable vertical downsizing(decimation) by 2.
  173554. + *
  173555. + * @param ipu ipu handler
  173556. + * @param csi csi 0 or csi 1
  173557. + */
  173558. +void _ipu_csi_vertical_downsize_enable(struct ipu_soc *ipu, uint32_t csi)
  173559. +{
  173560. + uint32_t temp;
  173561. +
  173562. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  173563. + temp |= CSI_VERT_DOWNSIZE_EN;
  173564. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  173565. +}
  173566. +
  173567. +/*!
  173568. + * _ipu_csi_vertical_downsize_disable
  173569. + * Disable vertical downsizing(decimation) by 2.
  173570. + *
  173571. + * @param ipu ipu handler
  173572. + * @param csi csi 0 or csi 1
  173573. + */
  173574. +void _ipu_csi_vertical_downsize_disable(struct ipu_soc *ipu, uint32_t csi)
  173575. +{
  173576. + uint32_t temp;
  173577. +
  173578. + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL);
  173579. + temp &= ~CSI_VERT_DOWNSIZE_EN;
  173580. + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL);
  173581. +}
  173582. +
  173583. +/*!
  173584. + * _ipu_csi_set_test_generator
  173585. + *
  173586. + * @param ipu ipu handler
  173587. + * @param active 1 for active and 0 for inactive
  173588. + * @param r_value red value for the generated pattern of even pixel
  173589. + * @param g_value green value for the generated pattern of even
  173590. + * pixel
  173591. + * @param b_value blue value for the generated pattern of even pixel
  173592. + * @param pixel_clk desired pixel clock frequency in Hz
  173593. + * @param csi csi 0 or csi 1
  173594. + */
  173595. +void _ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
  173596. + uint32_t g_value, uint32_t b_value, uint32_t pix_clk, uint32_t csi)
  173597. +{
  173598. + uint32_t temp;
  173599. +
  173600. + temp = ipu_csi_read(ipu, csi, CSI_TST_CTRL);
  173601. +
  173602. + if (active == false) {
  173603. + temp &= ~CSI_TEST_GEN_MODE_EN;
  173604. + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
  173605. + } else {
  173606. + /* Set sensb_mclk div_ratio*/
  173607. + _ipu_csi_mclk_set(ipu, pix_clk, csi);
  173608. +
  173609. + temp &= ~(CSI_TEST_GEN_R_MASK | CSI_TEST_GEN_G_MASK |
  173610. + CSI_TEST_GEN_B_MASK);
  173611. + temp |= CSI_TEST_GEN_MODE_EN;
  173612. + temp |= (r_value << CSI_TEST_GEN_R_SHIFT) |
  173613. + (g_value << CSI_TEST_GEN_G_SHIFT) |
  173614. + (b_value << CSI_TEST_GEN_B_SHIFT);
  173615. + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL);
  173616. + }
  173617. +}
  173618. +
  173619. +/*!
  173620. + * _ipu_csi_ccir_err_detection_en
  173621. + * Enable error detection and correction for
  173622. + * CCIR interlaced mode with protection bit.
  173623. + *
  173624. + * @param ipu ipu handler
  173625. + * @param csi csi 0 or csi 1
  173626. + */
  173627. +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi)
  173628. +{
  173629. + uint32_t temp;
  173630. +
  173631. + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
  173632. + temp |= CSI_CCIR_ERR_DET_EN;
  173633. + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
  173634. +
  173635. +}
  173636. +
  173637. +/*!
  173638. + * _ipu_csi_ccir_err_detection_disable
  173639. + * Disable error detection and correction for
  173640. + * CCIR interlaced mode with protection bit.
  173641. + *
  173642. + * @param ipu ipu handler
  173643. + * @param csi csi 0 or csi 1
  173644. + */
  173645. +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi)
  173646. +{
  173647. + uint32_t temp;
  173648. +
  173649. + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1);
  173650. + temp &= ~CSI_CCIR_ERR_DET_EN;
  173651. + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1);
  173652. +
  173653. +}
  173654. +
  173655. +/*!
  173656. + * _ipu_csi_set_mipi_di
  173657. + *
  173658. + * @param ipu ipu handler
  173659. + * @param num MIPI data identifier 0-3 handled by CSI
  173660. + * @param di_val data identifier value
  173661. + * @param csi csi 0 or csi 1
  173662. + *
  173663. + * @return Returns 0 on success or negative error code on fail
  173664. + */
  173665. +int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi)
  173666. +{
  173667. + uint32_t temp;
  173668. + int retval = 0;
  173669. +
  173670. + if (di_val > 0xFFL) {
  173671. + retval = -EINVAL;
  173672. + goto err;
  173673. + }
  173674. +
  173675. + temp = ipu_csi_read(ipu, csi, CSI_MIPI_DI);
  173676. +
  173677. + switch (num) {
  173678. + case IPU_CSI_MIPI_DI0:
  173679. + temp &= ~CSI_MIPI_DI0_MASK;
  173680. + temp |= (di_val << CSI_MIPI_DI0_SHIFT);
  173681. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  173682. + break;
  173683. + case IPU_CSI_MIPI_DI1:
  173684. + temp &= ~CSI_MIPI_DI1_MASK;
  173685. + temp |= (di_val << CSI_MIPI_DI1_SHIFT);
  173686. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  173687. + break;
  173688. + case IPU_CSI_MIPI_DI2:
  173689. + temp &= ~CSI_MIPI_DI2_MASK;
  173690. + temp |= (di_val << CSI_MIPI_DI2_SHIFT);
  173691. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  173692. + break;
  173693. + case IPU_CSI_MIPI_DI3:
  173694. + temp &= ~CSI_MIPI_DI3_MASK;
  173695. + temp |= (di_val << CSI_MIPI_DI3_SHIFT);
  173696. + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI);
  173697. + break;
  173698. + default:
  173699. + retval = -EINVAL;
  173700. + }
  173701. +
  173702. +err:
  173703. + return retval;
  173704. +}
  173705. +
  173706. +/*!
  173707. + * _ipu_csi_set_skip_isp
  173708. + *
  173709. + * @param ipu ipu handler
  173710. + * @param skip select frames to be skipped and set the
  173711. + * correspond bits to 1
  173712. + * @param max_ratio number of frames in a skipping set and the
  173713. + * maximum value of max_ratio is 5
  173714. + * @param csi csi 0 or csi 1
  173715. + *
  173716. + * @return Returns 0 on success or negative error code on fail
  173717. + */
  173718. +int _ipu_csi_set_skip_isp(struct ipu_soc *ipu, uint32_t skip, uint32_t max_ratio, uint32_t csi)
  173719. +{
  173720. + uint32_t temp;
  173721. + int retval = 0;
  173722. +
  173723. + if (max_ratio > 5) {
  173724. + retval = -EINVAL;
  173725. + goto err;
  173726. + }
  173727. +
  173728. + temp = ipu_csi_read(ipu, csi, CSI_SKIP);
  173729. + temp &= ~(CSI_MAX_RATIO_SKIP_ISP_MASK | CSI_SKIP_ISP_MASK);
  173730. + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_ISP_SHIFT) |
  173731. + (skip << CSI_SKIP_ISP_SHIFT);
  173732. + ipu_csi_write(ipu, csi, temp, CSI_SKIP);
  173733. +
  173734. +err:
  173735. + return retval;
  173736. +}
  173737. +
  173738. +/*!
  173739. + * _ipu_csi_set_skip_smfc
  173740. + *
  173741. + * @param ipu ipu handler
  173742. + * @param skip select frames to be skipped and set the
  173743. + * correspond bits to 1
  173744. + * @param max_ratio number of frames in a skipping set and the
  173745. + * maximum value of max_ratio is 5
  173746. + * @param id csi to smfc skipping id
  173747. + * @param csi csi 0 or csi 1
  173748. + *
  173749. + * @return Returns 0 on success or negative error code on fail
  173750. + */
  173751. +int _ipu_csi_set_skip_smfc(struct ipu_soc *ipu, uint32_t skip,
  173752. + uint32_t max_ratio, uint32_t id, uint32_t csi)
  173753. +{
  173754. + uint32_t temp;
  173755. + int retval = 0;
  173756. +
  173757. + if (max_ratio > 5 || id > 3) {
  173758. + retval = -EINVAL;
  173759. + goto err;
  173760. + }
  173761. +
  173762. + temp = ipu_csi_read(ipu, csi, CSI_SKIP);
  173763. + temp &= ~(CSI_MAX_RATIO_SKIP_SMFC_MASK | CSI_ID_2_SKIP_MASK |
  173764. + CSI_SKIP_SMFC_MASK);
  173765. + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_SMFC_SHIFT) |
  173766. + (id << CSI_ID_2_SKIP_SHIFT) |
  173767. + (skip << CSI_SKIP_SMFC_SHIFT);
  173768. + ipu_csi_write(ipu, csi, temp, CSI_SKIP);
  173769. +
  173770. +err:
  173771. + return retval;
  173772. +}
  173773. +
  173774. +/*!
  173775. + * _ipu_smfc_init
  173776. + * Map CSI frames to IDMAC channels.
  173777. + *
  173778. + * @param ipu ipu handler
  173779. + * @param channel IDMAC channel 0-3
  173780. + * @param mipi_id mipi id number 0-3
  173781. + * @param csi csi0 or csi1
  173782. + */
  173783. +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi)
  173784. +{
  173785. + uint32_t temp;
  173786. +
  173787. + temp = ipu_smfc_read(ipu, SMFC_MAP);
  173788. +
  173789. + switch (channel) {
  173790. + case CSI_MEM0:
  173791. + temp &= ~SMFC_MAP_CH0_MASK;
  173792. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH0_SHIFT;
  173793. + break;
  173794. + case CSI_MEM1:
  173795. + temp &= ~SMFC_MAP_CH1_MASK;
  173796. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH1_SHIFT;
  173797. + break;
  173798. + case CSI_MEM2:
  173799. + temp &= ~SMFC_MAP_CH2_MASK;
  173800. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH2_SHIFT;
  173801. + break;
  173802. + case CSI_MEM3:
  173803. + temp &= ~SMFC_MAP_CH3_MASK;
  173804. + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH3_SHIFT;
  173805. + break;
  173806. + default:
  173807. + return;
  173808. + }
  173809. +
  173810. + ipu_smfc_write(ipu, temp, SMFC_MAP);
  173811. +}
  173812. +
  173813. +/*!
  173814. + * _ipu_smfc_set_wmc
  173815. + * Caution: The number of required channels, the enabled channels
  173816. + * and the FIFO size per channel are configured restrictedly.
  173817. + *
  173818. + * @param ipu ipu handler
  173819. + * @param channel IDMAC channel 0-3
  173820. + * @param set set 1 or clear 0
  173821. + * @param level water mark level when FIFO is on the
  173822. + * relative size
  173823. + */
  173824. +void _ipu_smfc_set_wmc(struct ipu_soc *ipu, ipu_channel_t channel, bool set, uint32_t level)
  173825. +{
  173826. + uint32_t temp;
  173827. +
  173828. + temp = ipu_smfc_read(ipu, SMFC_WMC);
  173829. +
  173830. + switch (channel) {
  173831. + case CSI_MEM0:
  173832. + if (set == true) {
  173833. + temp &= ~SMFC_WM0_SET_MASK;
  173834. + temp |= level << SMFC_WM0_SET_SHIFT;
  173835. + } else {
  173836. + temp &= ~SMFC_WM0_CLR_MASK;
  173837. + temp |= level << SMFC_WM0_CLR_SHIFT;
  173838. + }
  173839. + break;
  173840. + case CSI_MEM1:
  173841. + if (set == true) {
  173842. + temp &= ~SMFC_WM1_SET_MASK;
  173843. + temp |= level << SMFC_WM1_SET_SHIFT;
  173844. + } else {
  173845. + temp &= ~SMFC_WM1_CLR_MASK;
  173846. + temp |= level << SMFC_WM1_CLR_SHIFT;
  173847. + }
  173848. + break;
  173849. + case CSI_MEM2:
  173850. + if (set == true) {
  173851. + temp &= ~SMFC_WM2_SET_MASK;
  173852. + temp |= level << SMFC_WM2_SET_SHIFT;
  173853. + } else {
  173854. + temp &= ~SMFC_WM2_CLR_MASK;
  173855. + temp |= level << SMFC_WM2_CLR_SHIFT;
  173856. + }
  173857. + break;
  173858. + case CSI_MEM3:
  173859. + if (set == true) {
  173860. + temp &= ~SMFC_WM3_SET_MASK;
  173861. + temp |= level << SMFC_WM3_SET_SHIFT;
  173862. + } else {
  173863. + temp &= ~SMFC_WM3_CLR_MASK;
  173864. + temp |= level << SMFC_WM3_CLR_SHIFT;
  173865. + }
  173866. + break;
  173867. + default:
  173868. + return;
  173869. + }
  173870. +
  173871. + ipu_smfc_write(ipu, temp, SMFC_WMC);
  173872. +}
  173873. +
  173874. +/*!
  173875. + * _ipu_smfc_set_burst_size
  173876. + *
  173877. + * @param ipu ipu handler
  173878. + * @param channel IDMAC channel 0-3
  173879. + * @param bs burst size of IDMAC channel,
  173880. + * the value programmed here shoud be BURST_SIZE-1
  173881. + */
  173882. +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs)
  173883. +{
  173884. + uint32_t temp;
  173885. +
  173886. + temp = ipu_smfc_read(ipu, SMFC_BS);
  173887. +
  173888. + switch (channel) {
  173889. + case CSI_MEM0:
  173890. + temp &= ~SMFC_BS0_MASK;
  173891. + temp |= bs << SMFC_BS0_SHIFT;
  173892. + break;
  173893. + case CSI_MEM1:
  173894. + temp &= ~SMFC_BS1_MASK;
  173895. + temp |= bs << SMFC_BS1_SHIFT;
  173896. + break;
  173897. + case CSI_MEM2:
  173898. + temp &= ~SMFC_BS2_MASK;
  173899. + temp |= bs << SMFC_BS2_SHIFT;
  173900. + break;
  173901. + case CSI_MEM3:
  173902. + temp &= ~SMFC_BS3_MASK;
  173903. + temp |= bs << SMFC_BS3_SHIFT;
  173904. + break;
  173905. + default:
  173906. + return;
  173907. + }
  173908. +
  173909. + ipu_smfc_write(ipu, temp, SMFC_BS);
  173910. +}
  173911. +
  173912. +/*!
  173913. + * _ipu_csi_init
  173914. + *
  173915. + * @param ipu ipu handler
  173916. + * @param channel IDMAC channel
  173917. + * @param csi csi 0 or csi 1
  173918. + *
  173919. + * @return Returns 0 on success or negative error code on fail
  173920. + */
  173921. +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi)
  173922. +{
  173923. + uint32_t csi_sens_conf, csi_dest;
  173924. + int retval = 0;
  173925. +
  173926. + switch (channel) {
  173927. + case CSI_MEM0:
  173928. + case CSI_MEM1:
  173929. + case CSI_MEM2:
  173930. + case CSI_MEM3:
  173931. + csi_dest = CSI_DATA_DEST_IDMAC;
  173932. + break;
  173933. + case CSI_PRP_ENC_MEM:
  173934. + case CSI_PRP_VF_MEM:
  173935. + csi_dest = CSI_DATA_DEST_IC;
  173936. + break;
  173937. + default:
  173938. + retval = -EINVAL;
  173939. + goto err;
  173940. + }
  173941. +
  173942. + csi_sens_conf = ipu_csi_read(ipu, csi, CSI_SENS_CONF);
  173943. + csi_sens_conf &= ~CSI_SENS_CONF_DATA_DEST_MASK;
  173944. + ipu_csi_write(ipu, csi, csi_sens_conf | (csi_dest <<
  173945. + CSI_SENS_CONF_DATA_DEST_SHIFT), CSI_SENS_CONF);
  173946. +err:
  173947. + return retval;
  173948. +}
  173949. +
  173950. +/*!
  173951. + * csi_irq_handler
  173952. + *
  173953. + * @param irq interrupt id
  173954. + * @param dev_id pointer to ipu handler
  173955. + *
  173956. + * @return Returns if irq is handled
  173957. + */
  173958. +static irqreturn_t csi_irq_handler(int irq, void *dev_id)
  173959. +{
  173960. + struct ipu_soc *ipu = dev_id;
  173961. + struct completion *comp = &ipu->csi_comp;
  173962. +
  173963. + complete(comp);
  173964. + return IRQ_HANDLED;
  173965. +}
  173966. +
  173967. +/*!
  173968. + * _ipu_csi_wait4eof
  173969. + *
  173970. + * @param ipu ipu handler
  173971. + * @param channel IDMAC channel
  173972. + *
  173973. + */
  173974. +void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel)
  173975. +{
  173976. + int ret;
  173977. + int irq = 0;
  173978. +
  173979. + if (channel == CSI_MEM0)
  173980. + irq = IPU_IRQ_CSI0_OUT_EOF;
  173981. + else if (channel == CSI_MEM1)
  173982. + irq = IPU_IRQ_CSI1_OUT_EOF;
  173983. + else if (channel == CSI_MEM2)
  173984. + irq = IPU_IRQ_CSI2_OUT_EOF;
  173985. + else if (channel == CSI_MEM3)
  173986. + irq = IPU_IRQ_CSI3_OUT_EOF;
  173987. + else if (channel == CSI_PRP_ENC_MEM)
  173988. + irq = IPU_IRQ_PRP_ENC_OUT_EOF;
  173989. + else if (channel == CSI_PRP_VF_MEM)
  173990. + irq = IPU_IRQ_PRP_VF_OUT_EOF;
  173991. + else{
  173992. + dev_err(ipu->dev, "Not a CSI channel\n");
  173993. + return;
  173994. + }
  173995. +
  173996. + init_completion(&ipu->csi_comp);
  173997. + ret = ipu_request_irq(ipu, irq, csi_irq_handler, 0, NULL, ipu);
  173998. + if (ret < 0) {
  173999. + dev_err(ipu->dev, "CSI irq %d in use\n", irq);
  174000. + return;
  174001. + }
  174002. + ret = wait_for_completion_timeout(&ipu->csi_comp, msecs_to_jiffies(500));
  174003. + ipu_free_irq(ipu, irq, ipu);
  174004. + dev_dbg(ipu->dev, "CSI stop timeout - %d * 10ms\n", 5 - ret);
  174005. +}
  174006. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_common.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_common.c
  174007. --- linux-3.14.17/drivers/mxc/ipu3/ipu_common.c 1970-01-01 01:00:00.000000000 +0100
  174008. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_common.c 2014-09-11 18:06:03.134042499 +0200
  174009. @@ -0,0 +1,3134 @@
  174010. +/*
  174011. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  174012. + */
  174013. +
  174014. +/*
  174015. + * The code contained herein is licensed under the GNU General Public
  174016. + * License. You may obtain a copy of the GNU General Public License
  174017. + * Version 2 or later at the following locations:
  174018. + *
  174019. + * http://www.opensource.org/licenses/gpl-license.html
  174020. + * http://www.gnu.org/copyleft/gpl.html
  174021. + */
  174022. +
  174023. +/*!
  174024. + * @file ipu_common.c
  174025. + *
  174026. + * @brief This file contains the IPU driver common API functions.
  174027. + *
  174028. + * @ingroup IPU
  174029. + */
  174030. +#include <linux/busfreq-imx6.h>
  174031. +#include <linux/clk.h>
  174032. +#include <linux/clk-provider.h>
  174033. +#include <linux/delay.h>
  174034. +#include <linux/err.h>
  174035. +#include <linux/init.h>
  174036. +#include <linux/interrupt.h>
  174037. +#include <linux/io.h>
  174038. +#include <linux/ipu-v3.h>
  174039. +#include <linux/irq.h>
  174040. +#include <linux/irqdesc.h>
  174041. +#include <linux/module.h>
  174042. +#include <linux/mod_devicetable.h>
  174043. +#include <linux/of_device.h>
  174044. +#include <linux/platform_device.h>
  174045. +#include <linux/pm_runtime.h>
  174046. +#include <linux/reset.h>
  174047. +#include <linux/spinlock.h>
  174048. +#include <linux/types.h>
  174049. +
  174050. +#include <asm/cacheflush.h>
  174051. +
  174052. +#include "ipu_param_mem.h"
  174053. +#include "ipu_regs.h"
  174054. +
  174055. +static struct ipu_soc ipu_array[MXC_IPU_MAX_NUM];
  174056. +int g_ipu_hw_rev;
  174057. +
  174058. +/* Static functions */
  174059. +static irqreturn_t ipu_sync_irq_handler(int irq, void *desc);
  174060. +static irqreturn_t ipu_err_irq_handler(int irq, void *desc);
  174061. +
  174062. +static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type)
  174063. +{
  174064. + return ((uint32_t) ch >> (6 * type)) & 0x3F;
  174065. +};
  174066. +
  174067. +static inline int _ipu_is_ic_chan(uint32_t dma_chan)
  174068. +{
  174069. + return (((dma_chan >= 11) && (dma_chan <= 22) && (dma_chan != 17) &&
  174070. + (dma_chan != 18)));
  174071. +}
  174072. +
  174073. +static inline int _ipu_is_vdi_out_chan(uint32_t dma_chan)
  174074. +{
  174075. + return (dma_chan == 5);
  174076. +}
  174077. +
  174078. +static inline int _ipu_is_ic_graphic_chan(uint32_t dma_chan)
  174079. +{
  174080. + return (dma_chan == 14 || dma_chan == 15);
  174081. +}
  174082. +
  174083. +/* Either DP BG or DP FG can be graphic window */
  174084. +static inline int _ipu_is_dp_graphic_chan(uint32_t dma_chan)
  174085. +{
  174086. + return (dma_chan == 23 || dma_chan == 27);
  174087. +}
  174088. +
  174089. +static inline int _ipu_is_irt_chan(uint32_t dma_chan)
  174090. +{
  174091. + return ((dma_chan >= 45) && (dma_chan <= 50));
  174092. +}
  174093. +
  174094. +static inline int _ipu_is_dmfc_chan(uint32_t dma_chan)
  174095. +{
  174096. + return ((dma_chan >= 23) && (dma_chan <= 29));
  174097. +}
  174098. +
  174099. +static inline int _ipu_is_smfc_chan(uint32_t dma_chan)
  174100. +{
  174101. + return ((dma_chan >= 0) && (dma_chan <= 3));
  174102. +}
  174103. +
  174104. +static inline int _ipu_is_trb_chan(uint32_t dma_chan)
  174105. +{
  174106. + return (((dma_chan == 8) || (dma_chan == 9) ||
  174107. + (dma_chan == 10) || (dma_chan == 13) ||
  174108. + (dma_chan == 21) || (dma_chan == 23) ||
  174109. + (dma_chan == 27) || (dma_chan == 28)) &&
  174110. + (g_ipu_hw_rev >= IPU_V3DEX));
  174111. +}
  174112. +
  174113. +/*
  174114. + * We usually use IDMAC 23 as full plane and IDMAC 27 as partial
  174115. + * plane.
  174116. + * IDMAC 23/24/28/41 can drive a display respectively - primary
  174117. + * IDMAC 27 depends on IDMAC 23 - nonprimary
  174118. + */
  174119. +static inline int _ipu_is_primary_disp_chan(uint32_t dma_chan)
  174120. +{
  174121. + return ((dma_chan == 23) || (dma_chan == 24) ||
  174122. + (dma_chan == 28) || (dma_chan == 41));
  174123. +}
  174124. +
  174125. +static inline int _ipu_is_sync_irq(uint32_t irq)
  174126. +{
  174127. + /* sync interrupt register number */
  174128. + int reg_num = irq / 32 + 1;
  174129. +
  174130. + return ((reg_num == 1) || (reg_num == 2) || (reg_num == 3) ||
  174131. + (reg_num == 4) || (reg_num == 7) || (reg_num == 8) ||
  174132. + (reg_num == 11) || (reg_num == 12) || (reg_num == 13) ||
  174133. + (reg_num == 14) || (reg_num == 15));
  174134. +}
  174135. +
  174136. +#define idma_is_valid(ch) (ch != NO_DMA)
  174137. +#define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0)
  174138. +#define idma_is_set(ipu, reg, dma) (ipu_idmac_read(ipu, reg(dma)) & idma_mask(dma))
  174139. +#define tri_cur_buf_mask(ch) (idma_mask(ch*2) * 3)
  174140. +#define tri_cur_buf_shift(ch) (ffs(idma_mask(ch*2)) - 1)
  174141. +
  174142. +static int ipu_clk_setup_enable(struct ipu_soc *ipu,
  174143. + struct ipu_pltfm_data *pdata)
  174144. +{
  174145. + char pixel_clk_0[] = "ipu1_pclk_0";
  174146. + char pixel_clk_1[] = "ipu1_pclk_1";
  174147. + char pixel_clk_0_sel[] = "ipu1_pclk0_sel";
  174148. + char pixel_clk_1_sel[] = "ipu1_pclk1_sel";
  174149. + char pixel_clk_0_div[] = "ipu1_pclk0_div";
  174150. + char pixel_clk_1_div[] = "ipu1_pclk1_div";
  174151. + char *ipu_pixel_clk_sel[] = { "ipu1", "ipu1_di0", "ipu1_di1", };
  174152. + char *pclk_sel;
  174153. + struct clk *clk;
  174154. + int ret;
  174155. + int i;
  174156. +
  174157. + pixel_clk_0[3] += pdata->id;
  174158. + pixel_clk_1[3] += pdata->id;
  174159. + pixel_clk_0_sel[3] += pdata->id;
  174160. + pixel_clk_1_sel[3] += pdata->id;
  174161. + pixel_clk_0_div[3] += pdata->id;
  174162. + pixel_clk_1_div[3] += pdata->id;
  174163. + for (i = 0; i < ARRAY_SIZE(ipu_pixel_clk_sel); i++) {
  174164. + pclk_sel = ipu_pixel_clk_sel[i];
  174165. + pclk_sel[3] += pdata->id;
  174166. + }
  174167. + dev_dbg(ipu->dev, "ipu_clk = %lu\n", clk_get_rate(ipu->ipu_clk));
  174168. +
  174169. + clk = clk_register_mux_pix_clk(ipu->dev, pixel_clk_0_sel,
  174170. + (const char **)ipu_pixel_clk_sel,
  174171. + ARRAY_SIZE(ipu_pixel_clk_sel),
  174172. + 0, pdata->id, 0, 0);
  174173. + if (IS_ERR(clk)) {
  174174. + dev_err(ipu->dev, "clk_register mux di0 failed");
  174175. + return PTR_ERR(clk);
  174176. + }
  174177. + ipu->pixel_clk_sel[0] = clk;
  174178. + clk = clk_register_mux_pix_clk(ipu->dev, pixel_clk_1_sel,
  174179. + (const char **)ipu_pixel_clk_sel,
  174180. + ARRAY_SIZE(ipu_pixel_clk_sel),
  174181. + 0, pdata->id, 1, 0);
  174182. + if (IS_ERR(clk)) {
  174183. + dev_err(ipu->dev, "clk_register mux di1 failed");
  174184. + return PTR_ERR(clk);
  174185. + }
  174186. + ipu->pixel_clk_sel[1] = clk;
  174187. +
  174188. + clk = clk_register_div_pix_clk(ipu->dev, pixel_clk_0_div,
  174189. + pixel_clk_0_sel, 0, pdata->id, 0, 0);
  174190. + if (IS_ERR(clk)) {
  174191. + dev_err(ipu->dev, "clk register di0 div failed");
  174192. + return PTR_ERR(clk);
  174193. + }
  174194. + clk = clk_register_div_pix_clk(ipu->dev, pixel_clk_1_div,
  174195. + pixel_clk_1_sel, CLK_SET_RATE_PARENT, pdata->id, 1, 0);
  174196. + if (IS_ERR(clk)) {
  174197. + dev_err(ipu->dev, "clk register di1 div failed");
  174198. + return PTR_ERR(clk);
  174199. + }
  174200. +
  174201. + ipu->pixel_clk[0] = clk_register_gate_pix_clk(ipu->dev, pixel_clk_0,
  174202. + pixel_clk_0_div, CLK_SET_RATE_PARENT,
  174203. + pdata->id, 0, 0);
  174204. + if (IS_ERR(ipu->pixel_clk[0])) {
  174205. + dev_err(ipu->dev, "clk register di0 gate failed");
  174206. + return PTR_ERR(ipu->pixel_clk[0]);
  174207. + }
  174208. + ipu->pixel_clk[1] = clk_register_gate_pix_clk(ipu->dev, pixel_clk_1,
  174209. + pixel_clk_1_div, CLK_SET_RATE_PARENT,
  174210. + pdata->id, 1, 0);
  174211. + if (IS_ERR(ipu->pixel_clk[1])) {
  174212. + dev_err(ipu->dev, "clk register di1 gate failed");
  174213. + return PTR_ERR(ipu->pixel_clk[1]);
  174214. + }
  174215. +
  174216. + ret = clk_set_parent(ipu->pixel_clk_sel[0], ipu->ipu_clk);
  174217. + if (ret) {
  174218. + dev_err(ipu->dev, "clk set parent failed");
  174219. + return ret;
  174220. + }
  174221. +
  174222. + ret = clk_set_parent(ipu->pixel_clk_sel[1], ipu->ipu_clk);
  174223. + if (ret) {
  174224. + dev_err(ipu->dev, "clk set parent failed");
  174225. + return ret;
  174226. + }
  174227. +
  174228. + ipu->di_clk[0] = devm_clk_get(ipu->dev, "di0");
  174229. + if (IS_ERR(ipu->di_clk[0])) {
  174230. + dev_err(ipu->dev, "clk_get di0 failed");
  174231. + return PTR_ERR(ipu->di_clk[0]);
  174232. + }
  174233. + ipu->di_clk[1] = devm_clk_get(ipu->dev, "di1");
  174234. + if (IS_ERR(ipu->di_clk[1])) {
  174235. + dev_err(ipu->dev, "clk_get di1 failed");
  174236. + return PTR_ERR(ipu->di_clk[1]);
  174237. + }
  174238. +
  174239. + ipu->di_clk_sel[0] = devm_clk_get(ipu->dev, "di0_sel");
  174240. + if (IS_ERR(ipu->di_clk_sel[0])) {
  174241. + dev_err(ipu->dev, "clk_get di0_sel failed");
  174242. + return PTR_ERR(ipu->di_clk_sel[0]);
  174243. + }
  174244. + ipu->di_clk_sel[1] = devm_clk_get(ipu->dev, "di1_sel");
  174245. + if (IS_ERR(ipu->di_clk_sel[1])) {
  174246. + dev_err(ipu->dev, "clk_get di1_sel failed");
  174247. + return PTR_ERR(ipu->di_clk_sel[1]);
  174248. + }
  174249. +
  174250. + return 0;
  174251. +}
  174252. +
  174253. +static int ipu_mem_reset(struct ipu_soc *ipu)
  174254. +{
  174255. + int timeout = 1000;
  174256. +
  174257. + ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
  174258. +
  174259. + while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
  174260. + if (!timeout--)
  174261. + return -ETIME;
  174262. + msleep(1);
  174263. + }
  174264. +
  174265. + return 0;
  174266. +}
  174267. +
  174268. +struct ipu_soc *ipu_get_soc(int id)
  174269. +{
  174270. + if (id >= MXC_IPU_MAX_NUM)
  174271. + return ERR_PTR(-ENODEV);
  174272. + else if (!ipu_array[id].online)
  174273. + return ERR_PTR(-ENODEV);
  174274. + else
  174275. + return &(ipu_array[id]);
  174276. +}
  174277. +EXPORT_SYMBOL_GPL(ipu_get_soc);
  174278. +
  174279. +void _ipu_get(struct ipu_soc *ipu)
  174280. +{
  174281. + int ret;
  174282. +
  174283. + ret = clk_enable(ipu->ipu_clk);
  174284. + if (ret < 0)
  174285. + BUG();
  174286. +}
  174287. +
  174288. +void _ipu_put(struct ipu_soc *ipu)
  174289. +{
  174290. + clk_disable(ipu->ipu_clk);
  174291. +}
  174292. +
  174293. +void ipu_disable_hsp_clk(struct ipu_soc *ipu)
  174294. +{
  174295. + _ipu_put(ipu);
  174296. +}
  174297. +EXPORT_SYMBOL(ipu_disable_hsp_clk);
  174298. +
  174299. +static struct platform_device_id imx_ipu_type[] = {
  174300. + {
  174301. + .name = "ipu-imx6q",
  174302. + .driver_data = IPU_V3H,
  174303. + }, {
  174304. + /* sentinel */
  174305. + }
  174306. +};
  174307. +MODULE_DEVICE_TABLE(platform, imx_ipu_type);
  174308. +
  174309. +static const struct of_device_id imx_ipuv3_dt_ids[] = {
  174310. + { .compatible = "fsl,imx6q-ipu", .data = &imx_ipu_type[IMX6Q_IPU], },
  174311. + { /* sentinel */ }
  174312. +};
  174313. +MODULE_DEVICE_TABLE(of, imx_ipuv3_dt_ids);
  174314. +
  174315. +/*!
  174316. + * This function is called by the driver framework to initialize the IPU
  174317. + * hardware.
  174318. + *
  174319. + * @param dev The device structure for the IPU passed in by the
  174320. + * driver framework.
  174321. + *
  174322. + * @return Returns 0 on success or negative error code on error
  174323. + */
  174324. +static int ipu_probe(struct platform_device *pdev)
  174325. +{
  174326. + struct ipu_soc *ipu;
  174327. + struct resource *res;
  174328. + unsigned long ipu_base;
  174329. + const struct of_device_id *of_id =
  174330. + of_match_device(imx_ipuv3_dt_ids, &pdev->dev);
  174331. + struct ipu_pltfm_data *pltfm_data;
  174332. + int ret = 0;
  174333. + u32 bypass_reset;
  174334. +
  174335. + dev_dbg(&pdev->dev, "<%s>\n", __func__);
  174336. +
  174337. + pltfm_data = devm_kzalloc(&pdev->dev, sizeof(struct ipu_pltfm_data),
  174338. + GFP_KERNEL);
  174339. + if (!pltfm_data)
  174340. + return -ENOMEM;
  174341. +
  174342. + ret = of_property_read_u32(pdev->dev.of_node,
  174343. + "bypass_reset", &bypass_reset);
  174344. + if (ret < 0) {
  174345. + dev_dbg(&pdev->dev, "can not get bypass_reset\n");
  174346. + return ret;
  174347. + }
  174348. + pltfm_data->bypass_reset = (bool)bypass_reset;
  174349. +
  174350. + pltfm_data->id = of_alias_get_id(pdev->dev.of_node, "ipu");
  174351. + if (pltfm_data->id < 0) {
  174352. + dev_dbg(&pdev->dev, "can not get alias id\n");
  174353. + return pltfm_data->id;
  174354. + }
  174355. +
  174356. + if (of_id)
  174357. + pdev->id_entry = of_id->data;
  174358. + pltfm_data->devtype = pdev->id_entry->driver_data;
  174359. + g_ipu_hw_rev = pltfm_data->devtype;
  174360. +
  174361. + ipu = &ipu_array[pltfm_data->id];
  174362. + memset(ipu, 0, sizeof(struct ipu_soc));
  174363. + ipu->dev = &pdev->dev;
  174364. + ipu->pdata = pltfm_data;
  174365. + dev_dbg(ipu->dev, "IPU rev:%d\n", g_ipu_hw_rev);
  174366. + spin_lock_init(&ipu->int_reg_spin_lock);
  174367. + spin_lock_init(&ipu->rdy_reg_spin_lock);
  174368. + mutex_init(&ipu->mutex_lock);
  174369. +
  174370. + ipu->irq_sync = platform_get_irq(pdev, 0);
  174371. + ipu->irq_err = platform_get_irq(pdev, 1);
  174372. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  174373. +
  174374. + if (!res || ipu->irq_sync < 0 || ipu->irq_err < 0) {
  174375. + dev_err(&pdev->dev, "can't get device resources\n");
  174376. + return -ENODEV;
  174377. + }
  174378. +
  174379. + if (!devm_request_mem_region(&pdev->dev, res->start,
  174380. + resource_size(res), pdev->name))
  174381. + return -EBUSY;
  174382. +
  174383. + ret = devm_request_irq(&pdev->dev, ipu->irq_sync,
  174384. + ipu_sync_irq_handler, 0, pdev->name, ipu);
  174385. + if (ret) {
  174386. + dev_err(ipu->dev, "request SYNC interrupt failed\n");
  174387. + return ret;
  174388. + }
  174389. + ret = devm_request_irq(&pdev->dev, ipu->irq_err,
  174390. + ipu_err_irq_handler, 0, pdev->name, ipu);
  174391. + if (ret) {
  174392. + dev_err(ipu->dev, "request ERR interrupt failed\n");
  174393. + return ret;
  174394. + }
  174395. +
  174396. + ipu_base = res->start;
  174397. + /* base fixup */
  174398. + if (g_ipu_hw_rev == IPU_V3H) /* IPUv3H */
  174399. + ipu_base += IPUV3H_REG_BASE;
  174400. + else if (g_ipu_hw_rev == IPU_V3M) /* IPUv3M */
  174401. + ipu_base += IPUV3M_REG_BASE;
  174402. + else /* IPUv3D, v3E, v3EX */
  174403. + ipu_base += IPUV3DEX_REG_BASE;
  174404. +
  174405. + ipu->cm_reg = devm_ioremap(&pdev->dev,
  174406. + ipu_base + IPU_CM_REG_BASE, PAGE_SIZE);
  174407. + ipu->ic_reg = devm_ioremap(&pdev->dev,
  174408. + ipu_base + IPU_IC_REG_BASE, PAGE_SIZE);
  174409. + ipu->idmac_reg = devm_ioremap(&pdev->dev,
  174410. + ipu_base + IPU_IDMAC_REG_BASE, PAGE_SIZE);
  174411. + /* DP Registers are accessed thru the SRM */
  174412. + ipu->dp_reg = devm_ioremap(&pdev->dev,
  174413. + ipu_base + IPU_SRM_REG_BASE, PAGE_SIZE);
  174414. + ipu->dc_reg = devm_ioremap(&pdev->dev,
  174415. + ipu_base + IPU_DC_REG_BASE, PAGE_SIZE);
  174416. + ipu->dmfc_reg = devm_ioremap(&pdev->dev,
  174417. + ipu_base + IPU_DMFC_REG_BASE, PAGE_SIZE);
  174418. + ipu->di_reg[0] = devm_ioremap(&pdev->dev,
  174419. + ipu_base + IPU_DI0_REG_BASE, PAGE_SIZE);
  174420. + ipu->di_reg[1] = devm_ioremap(&pdev->dev,
  174421. + ipu_base + IPU_DI1_REG_BASE, PAGE_SIZE);
  174422. + ipu->smfc_reg = devm_ioremap(&pdev->dev,
  174423. + ipu_base + IPU_SMFC_REG_BASE, PAGE_SIZE);
  174424. + ipu->csi_reg[0] = devm_ioremap(&pdev->dev,
  174425. + ipu_base + IPU_CSI0_REG_BASE, PAGE_SIZE);
  174426. + ipu->csi_reg[1] = devm_ioremap(&pdev->dev,
  174427. + ipu_base + IPU_CSI1_REG_BASE, PAGE_SIZE);
  174428. + ipu->cpmem_base = devm_ioremap(&pdev->dev,
  174429. + ipu_base + IPU_CPMEM_REG_BASE, SZ_128K);
  174430. + ipu->tpmem_base = devm_ioremap(&pdev->dev,
  174431. + ipu_base + IPU_TPM_REG_BASE, SZ_64K);
  174432. + ipu->dc_tmpl_reg = devm_ioremap(&pdev->dev,
  174433. + ipu_base + IPU_DC_TMPL_REG_BASE, SZ_128K);
  174434. + ipu->vdi_reg = devm_ioremap(&pdev->dev,
  174435. + ipu_base + IPU_VDI_REG_BASE, PAGE_SIZE);
  174436. + ipu->disp_base[1] = devm_ioremap(&pdev->dev,
  174437. + ipu_base + IPU_DISP1_BASE, SZ_4K);
  174438. + if (!ipu->cm_reg || !ipu->ic_reg || !ipu->idmac_reg ||
  174439. + !ipu->dp_reg || !ipu->dc_reg || !ipu->dmfc_reg ||
  174440. + !ipu->di_reg[0] || !ipu->di_reg[1] || !ipu->smfc_reg ||
  174441. + !ipu->csi_reg[0] || !ipu->csi_reg[1] || !ipu->cpmem_base ||
  174442. + !ipu->tpmem_base || !ipu->dc_tmpl_reg || !ipu->disp_base[1]
  174443. + || !ipu->vdi_reg)
  174444. + return -ENOMEM;
  174445. +
  174446. + dev_dbg(ipu->dev, "IPU CM Regs = %p\n", ipu->cm_reg);
  174447. + dev_dbg(ipu->dev, "IPU IC Regs = %p\n", ipu->ic_reg);
  174448. + dev_dbg(ipu->dev, "IPU IDMAC Regs = %p\n", ipu->idmac_reg);
  174449. + dev_dbg(ipu->dev, "IPU DP Regs = %p\n", ipu->dp_reg);
  174450. + dev_dbg(ipu->dev, "IPU DC Regs = %p\n", ipu->dc_reg);
  174451. + dev_dbg(ipu->dev, "IPU DMFC Regs = %p\n", ipu->dmfc_reg);
  174452. + dev_dbg(ipu->dev, "IPU DI0 Regs = %p\n", ipu->di_reg[0]);
  174453. + dev_dbg(ipu->dev, "IPU DI1 Regs = %p\n", ipu->di_reg[1]);
  174454. + dev_dbg(ipu->dev, "IPU SMFC Regs = %p\n", ipu->smfc_reg);
  174455. + dev_dbg(ipu->dev, "IPU CSI0 Regs = %p\n", ipu->csi_reg[0]);
  174456. + dev_dbg(ipu->dev, "IPU CSI1 Regs = %p\n", ipu->csi_reg[1]);
  174457. + dev_dbg(ipu->dev, "IPU CPMem = %p\n", ipu->cpmem_base);
  174458. + dev_dbg(ipu->dev, "IPU TPMem = %p\n", ipu->tpmem_base);
  174459. + dev_dbg(ipu->dev, "IPU DC Template Mem = %p\n", ipu->dc_tmpl_reg);
  174460. + dev_dbg(ipu->dev, "IPU Display Region 1 Mem = %p\n", ipu->disp_base[1]);
  174461. + dev_dbg(ipu->dev, "IPU VDI Regs = %p\n", ipu->vdi_reg);
  174462. +
  174463. + ipu->ipu_clk = devm_clk_get(ipu->dev, "bus");
  174464. + if (IS_ERR(ipu->ipu_clk)) {
  174465. + dev_err(ipu->dev, "clk_get ipu failed");
  174466. + return PTR_ERR(ipu->ipu_clk);
  174467. + }
  174468. +
  174469. + /* ipu_clk is always prepared */
  174470. + ret = clk_prepare_enable(ipu->ipu_clk);
  174471. + if (ret < 0) {
  174472. + dev_err(ipu->dev, "ipu clk enable failed\n");
  174473. + return ret;
  174474. + }
  174475. +
  174476. + ipu->online = true;
  174477. +
  174478. + platform_set_drvdata(pdev, ipu);
  174479. +
  174480. + if (!pltfm_data->bypass_reset) {
  174481. + ret = device_reset(&pdev->dev);
  174482. + if (ret) {
  174483. + dev_err(&pdev->dev, "failed to reset: %d\n", ret);
  174484. + return ret;
  174485. + }
  174486. +
  174487. + ipu_mem_reset(ipu);
  174488. +
  174489. + ipu_disp_init(ipu);
  174490. +
  174491. + /* Set MCU_T to divide MCU access window into 2 */
  174492. + ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
  174493. + IPU_DISP_GEN);
  174494. + }
  174495. +
  174496. + /* setup ipu clk tree after ipu reset */
  174497. + ret = ipu_clk_setup_enable(ipu, pltfm_data);
  174498. + if (ret < 0) {
  174499. + dev_err(ipu->dev, "ipu clk setup failed\n");
  174500. + ipu->online = false;
  174501. + return ret;
  174502. + }
  174503. +
  174504. + /* Set sync refresh channels and CSI->mem channel as high priority */
  174505. + ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
  174506. +
  174507. + /* Enable error interrupts by default */
  174508. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
  174509. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
  174510. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
  174511. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
  174512. +
  174513. + if (!pltfm_data->bypass_reset)
  174514. + clk_disable(ipu->ipu_clk);
  174515. +
  174516. + register_ipu_device(ipu, ipu->pdata->id);
  174517. +
  174518. + pm_runtime_enable(&pdev->dev);
  174519. +
  174520. + return ret;
  174521. +}
  174522. +
  174523. +int ipu_remove(struct platform_device *pdev)
  174524. +{
  174525. + struct ipu_soc *ipu = platform_get_drvdata(pdev);
  174526. +
  174527. + unregister_ipu_device(ipu, ipu->pdata->id);
  174528. +
  174529. + clk_put(ipu->ipu_clk);
  174530. +
  174531. + return 0;
  174532. +}
  174533. +
  174534. +void ipu_dump_registers(struct ipu_soc *ipu)
  174535. +{
  174536. + dev_dbg(ipu->dev, "IPU_CONF = \t0x%08X\n", ipu_cm_read(ipu, IPU_CONF));
  174537. + dev_dbg(ipu->dev, "IDMAC_CONF = \t0x%08X\n", ipu_idmac_read(ipu, IDMAC_CONF));
  174538. + dev_dbg(ipu->dev, "IDMAC_CHA_EN1 = \t0x%08X\n",
  174539. + ipu_idmac_read(ipu, IDMAC_CHA_EN(0)));
  174540. + dev_dbg(ipu->dev, "IDMAC_CHA_EN2 = \t0x%08X\n",
  174541. + ipu_idmac_read(ipu, IDMAC_CHA_EN(32)));
  174542. + dev_dbg(ipu->dev, "IDMAC_CHA_PRI1 = \t0x%08X\n",
  174543. + ipu_idmac_read(ipu, IDMAC_CHA_PRI(0)));
  174544. + dev_dbg(ipu->dev, "IDMAC_CHA_PRI2 = \t0x%08X\n",
  174545. + ipu_idmac_read(ipu, IDMAC_CHA_PRI(32)));
  174546. + dev_dbg(ipu->dev, "IDMAC_BAND_EN1 = \t0x%08X\n",
  174547. + ipu_idmac_read(ipu, IDMAC_BAND_EN(0)));
  174548. + dev_dbg(ipu->dev, "IDMAC_BAND_EN2 = \t0x%08X\n",
  174549. + ipu_idmac_read(ipu, IDMAC_BAND_EN(32)));
  174550. + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
  174551. + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(0)));
  174552. + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
  174553. + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(32)));
  174554. + if (g_ipu_hw_rev >= IPU_V3DEX) {
  174555. + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL0 = \t0x%08X\n",
  174556. + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(0)));
  174557. + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL1 = \t0x%08X\n",
  174558. + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(32)));
  174559. + }
  174560. + dev_dbg(ipu->dev, "DMFC_WR_CHAN = \t0x%08X\n",
  174561. + ipu_dmfc_read(ipu, DMFC_WR_CHAN));
  174562. + dev_dbg(ipu->dev, "DMFC_WR_CHAN_DEF = \t0x%08X\n",
  174563. + ipu_dmfc_read(ipu, DMFC_WR_CHAN_DEF));
  174564. + dev_dbg(ipu->dev, "DMFC_DP_CHAN = \t0x%08X\n",
  174565. + ipu_dmfc_read(ipu, DMFC_DP_CHAN));
  174566. + dev_dbg(ipu->dev, "DMFC_DP_CHAN_DEF = \t0x%08X\n",
  174567. + ipu_dmfc_read(ipu, DMFC_DP_CHAN_DEF));
  174568. + dev_dbg(ipu->dev, "DMFC_IC_CTRL = \t0x%08X\n",
  174569. + ipu_dmfc_read(ipu, DMFC_IC_CTRL));
  174570. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW1 = \t0x%08X\n",
  174571. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW1));
  174572. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW2 = \t0x%08X\n",
  174573. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW2));
  174574. + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW3 = \t0x%08X\n",
  174575. + ipu_cm_read(ipu, IPU_FS_PROC_FLOW3));
  174576. + dev_dbg(ipu->dev, "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
  174577. + ipu_cm_read(ipu, IPU_FS_DISP_FLOW1));
  174578. + dev_dbg(ipu->dev, "IPU_VDIC_VDI_FSIZE = \t0x%08X\n",
  174579. + ipu_vdi_read(ipu, VDI_FSIZE));
  174580. + dev_dbg(ipu->dev, "IPU_VDIC_VDI_C = \t0x%08X\n",
  174581. + ipu_vdi_read(ipu, VDI_C));
  174582. + dev_dbg(ipu->dev, "IPU_IC_CONF = \t0x%08X\n",
  174583. + ipu_ic_read(ipu, IC_CONF));
  174584. +}
  174585. +
  174586. +/*!
  174587. + * This function is called to initialize a logical IPU channel.
  174588. + *
  174589. + * @param ipu ipu handler
  174590. + * @param channel Input parameter for the logical channel ID to init.
  174591. + *
  174592. + * @param params Input parameter containing union of channel
  174593. + * initialization parameters.
  174594. + *
  174595. + * @return Returns 0 on success or negative error code on fail
  174596. + */
  174597. +int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
  174598. +{
  174599. + int ret = 0;
  174600. + bool bad_pixfmt;
  174601. + uint32_t ipu_conf, reg, in_g_pixel_fmt, sec_dma;
  174602. +
  174603. + dev_dbg(ipu->dev, "init channel = %d\n", IPU_CHAN_ID(channel));
  174604. +
  174605. + ret = pm_runtime_get_sync(ipu->dev);
  174606. + if (ret < 0) {
  174607. + dev_err(ipu->dev, "ch = %d, pm_runtime_get failed:%d!\n",
  174608. + IPU_CHAN_ID(channel), ret);
  174609. + dump_stack();
  174610. + return ret;
  174611. + }
  174612. + /*
  174613. + * Here, ret could be 1 if the device's runtime PM status was
  174614. + * already 'active', so clear it to be 0.
  174615. + */
  174616. + ret = 0;
  174617. +
  174618. + _ipu_get(ipu);
  174619. +
  174620. + mutex_lock(&ipu->mutex_lock);
  174621. +
  174622. + /* Re-enable error interrupts every time a channel is initialized */
  174623. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(5));
  174624. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(6));
  174625. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(9));
  174626. + ipu_cm_write(ipu, 0xFFFFFFFF, IPU_INT_CTRL(10));
  174627. +
  174628. + if (ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) {
  174629. + dev_warn(ipu->dev, "Warning: channel already initialized %d\n",
  174630. + IPU_CHAN_ID(channel));
  174631. + }
  174632. +
  174633. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  174634. +
  174635. + switch (channel) {
  174636. + case CSI_MEM0:
  174637. + case CSI_MEM1:
  174638. + case CSI_MEM2:
  174639. + case CSI_MEM3:
  174640. + if (params->csi_mem.csi > 1) {
  174641. + ret = -EINVAL;
  174642. + goto err;
  174643. + }
  174644. +
  174645. + if (params->csi_mem.interlaced)
  174646. + ipu->chan_is_interlaced[channel_2_dma(channel,
  174647. + IPU_OUTPUT_BUFFER)] = true;
  174648. + else
  174649. + ipu->chan_is_interlaced[channel_2_dma(channel,
  174650. + IPU_OUTPUT_BUFFER)] = false;
  174651. +
  174652. + ipu->smfc_use_count++;
  174653. + ipu->csi_channel[params->csi_mem.csi] = channel;
  174654. +
  174655. + /*SMFC setting*/
  174656. + if (params->csi_mem.mipi_en) {
  174657. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  174658. + params->csi_mem.csi));
  174659. + _ipu_smfc_init(ipu, channel, params->csi_mem.mipi_vc,
  174660. + params->csi_mem.csi);
  174661. + _ipu_csi_set_mipi_di(ipu, params->csi_mem.mipi_vc,
  174662. + params->csi_mem.mipi_id, params->csi_mem.csi);
  174663. + } else {
  174664. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  174665. + params->csi_mem.csi));
  174666. + _ipu_smfc_init(ipu, channel, 0, params->csi_mem.csi);
  174667. + }
  174668. +
  174669. + /*CSI data (include compander) dest*/
  174670. + _ipu_csi_init(ipu, channel, params->csi_mem.csi);
  174671. + break;
  174672. + case CSI_PRP_ENC_MEM:
  174673. + if (params->csi_prp_enc_mem.csi > 1) {
  174674. + ret = -EINVAL;
  174675. + goto err;
  174676. + }
  174677. + if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  174678. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
  174679. + ret = -EINVAL;
  174680. + goto err;
  174681. + }
  174682. + ipu->using_ic_dirct_ch = CSI_PRP_ENC_MEM;
  174683. +
  174684. + ipu->ic_use_count++;
  174685. + ipu->csi_channel[params->csi_prp_enc_mem.csi] = channel;
  174686. +
  174687. + if (params->csi_prp_enc_mem.mipi_en) {
  174688. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  174689. + params->csi_prp_enc_mem.csi));
  174690. + _ipu_csi_set_mipi_di(ipu,
  174691. + params->csi_prp_enc_mem.mipi_vc,
  174692. + params->csi_prp_enc_mem.mipi_id,
  174693. + params->csi_prp_enc_mem.csi);
  174694. + } else
  174695. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  174696. + params->csi_prp_enc_mem.csi));
  174697. +
  174698. + /*CSI0/1 feed into IC*/
  174699. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  174700. + if (params->csi_prp_enc_mem.csi)
  174701. + ipu_conf |= IPU_CONF_CSI_SEL;
  174702. + else
  174703. + ipu_conf &= ~IPU_CONF_CSI_SEL;
  174704. +
  174705. + /*PRP skip buffer in memory, only valid when RWS_EN is true*/
  174706. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  174707. + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  174708. +
  174709. + /*CSI data (include compander) dest*/
  174710. + _ipu_csi_init(ipu, channel, params->csi_prp_enc_mem.csi);
  174711. + _ipu_ic_init_prpenc(ipu, params, true);
  174712. + break;
  174713. + case CSI_PRP_VF_MEM:
  174714. + if (params->csi_prp_vf_mem.csi > 1) {
  174715. + ret = -EINVAL;
  174716. + goto err;
  174717. + }
  174718. + if ((ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  174719. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM)) {
  174720. + ret = -EINVAL;
  174721. + goto err;
  174722. + }
  174723. + ipu->using_ic_dirct_ch = CSI_PRP_VF_MEM;
  174724. +
  174725. + ipu->ic_use_count++;
  174726. + ipu->csi_channel[params->csi_prp_vf_mem.csi] = channel;
  174727. +
  174728. + if (params->csi_prp_vf_mem.mipi_en) {
  174729. + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  174730. + params->csi_prp_vf_mem.csi));
  174731. + _ipu_csi_set_mipi_di(ipu,
  174732. + params->csi_prp_vf_mem.mipi_vc,
  174733. + params->csi_prp_vf_mem.mipi_id,
  174734. + params->csi_prp_vf_mem.csi);
  174735. + } else
  174736. + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
  174737. + params->csi_prp_vf_mem.csi));
  174738. +
  174739. + /*CSI0/1 feed into IC*/
  174740. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  174741. + if (params->csi_prp_vf_mem.csi)
  174742. + ipu_conf |= IPU_CONF_CSI_SEL;
  174743. + else
  174744. + ipu_conf &= ~IPU_CONF_CSI_SEL;
  174745. +
  174746. + /*PRP skip buffer in memory, only valid when RWS_EN is true*/
  174747. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  174748. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  174749. +
  174750. + /*CSI data (include compander) dest*/
  174751. + _ipu_csi_init(ipu, channel, params->csi_prp_vf_mem.csi);
  174752. + _ipu_ic_init_prpvf(ipu, params, true);
  174753. + break;
  174754. + case MEM_PRP_VF_MEM:
  174755. + if (params->mem_prp_vf_mem.graphics_combine_en) {
  174756. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  174757. + in_g_pixel_fmt = params->mem_prp_vf_mem.in_g_pixel_fmt;
  174758. + bad_pixfmt =
  174759. + _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
  174760. +
  174761. + if (params->mem_prp_vf_mem.alpha_chan_en) {
  174762. + if (bad_pixfmt) {
  174763. + dev_err(ipu->dev, "bad pixel format "
  174764. + "for graphics plane from "
  174765. + "ch%d\n", sec_dma);
  174766. + ret = -EINVAL;
  174767. + goto err;
  174768. + }
  174769. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  174770. + }
  174771. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  174772. + }
  174773. +
  174774. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  174775. + ipu_cm_write(ipu, reg | FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  174776. +
  174777. + _ipu_ic_init_prpvf(ipu, params, false);
  174778. + ipu->ic_use_count++;
  174779. + break;
  174780. + case MEM_VDI_PRP_VF_MEM:
  174781. + if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
  174782. + (ipu->using_ic_dirct_ch == MEM_VDI_MEM) ||
  174783. + (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
  174784. + ret = -EINVAL;
  174785. + goto err;
  174786. + }
  174787. + ipu->using_ic_dirct_ch = MEM_VDI_PRP_VF_MEM;
  174788. + ipu->ic_use_count++;
  174789. + ipu->vdi_use_count++;
  174790. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  174791. + reg &= ~FS_VDI_SRC_SEL_MASK;
  174792. + ipu_cm_write(ipu, reg , IPU_FS_PROC_FLOW1);
  174793. +
  174794. + if (params->mem_prp_vf_mem.graphics_combine_en)
  174795. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  174796. + _ipu_ic_init_prpvf(ipu, params, false);
  174797. + _ipu_vdi_init(ipu, channel, params);
  174798. + break;
  174799. + case MEM_VDI_PRP_VF_MEM_P:
  174800. + case MEM_VDI_PRP_VF_MEM_N:
  174801. + case MEM_VDI_MEM_P:
  174802. + case MEM_VDI_MEM_N:
  174803. + _ipu_vdi_init(ipu, channel, params);
  174804. + break;
  174805. + case MEM_VDI_MEM:
  174806. + if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) ||
  174807. + (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) ||
  174808. + (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) {
  174809. + ret = -EINVAL;
  174810. + goto err;
  174811. + }
  174812. + ipu->using_ic_dirct_ch = MEM_VDI_MEM;
  174813. + ipu->ic_use_count++;
  174814. + ipu->vdi_use_count++;
  174815. + _ipu_vdi_init(ipu, channel, params);
  174816. + break;
  174817. + case MEM_ROT_VF_MEM:
  174818. + ipu->ic_use_count++;
  174819. + ipu->rot_use_count++;
  174820. + _ipu_ic_init_rotate_vf(ipu, params);
  174821. + break;
  174822. + case MEM_PRP_ENC_MEM:
  174823. + ipu->ic_use_count++;
  174824. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  174825. + ipu_cm_write(ipu, reg | FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  174826. + _ipu_ic_init_prpenc(ipu, params, false);
  174827. + break;
  174828. + case MEM_ROT_ENC_MEM:
  174829. + ipu->ic_use_count++;
  174830. + ipu->rot_use_count++;
  174831. + _ipu_ic_init_rotate_enc(ipu, params);
  174832. + break;
  174833. + case MEM_PP_MEM:
  174834. + if (params->mem_pp_mem.graphics_combine_en) {
  174835. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  174836. + in_g_pixel_fmt = params->mem_pp_mem.in_g_pixel_fmt;
  174837. + bad_pixfmt =
  174838. + _ipu_ch_param_bad_alpha_pos(in_g_pixel_fmt);
  174839. +
  174840. + if (params->mem_pp_mem.alpha_chan_en) {
  174841. + if (bad_pixfmt) {
  174842. + dev_err(ipu->dev, "bad pixel format "
  174843. + "for graphics plane from "
  174844. + "ch%d\n", sec_dma);
  174845. + ret = -EINVAL;
  174846. + goto err;
  174847. + }
  174848. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  174849. + }
  174850. +
  174851. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true;
  174852. + }
  174853. +
  174854. + _ipu_ic_init_pp(ipu, params);
  174855. + ipu->ic_use_count++;
  174856. + break;
  174857. + case MEM_ROT_PP_MEM:
  174858. + _ipu_ic_init_rotate_pp(ipu, params);
  174859. + ipu->ic_use_count++;
  174860. + ipu->rot_use_count++;
  174861. + break;
  174862. + case MEM_DC_SYNC:
  174863. + if (params->mem_dc_sync.di > 1) {
  174864. + ret = -EINVAL;
  174865. + goto err;
  174866. + }
  174867. +
  174868. + ipu->dc_di_assignment[1] = params->mem_dc_sync.di;
  174869. + _ipu_dc_init(ipu, 1, params->mem_dc_sync.di,
  174870. + params->mem_dc_sync.interlaced,
  174871. + params->mem_dc_sync.out_pixel_fmt);
  174872. + ipu->di_use_count[params->mem_dc_sync.di]++;
  174873. + ipu->dc_use_count++;
  174874. + ipu->dmfc_use_count++;
  174875. + break;
  174876. + case MEM_BG_SYNC:
  174877. + if (params->mem_dp_bg_sync.di > 1) {
  174878. + ret = -EINVAL;
  174879. + goto err;
  174880. + }
  174881. +
  174882. + if (params->mem_dp_bg_sync.alpha_chan_en)
  174883. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  174884. +
  174885. + ipu->dc_di_assignment[5] = params->mem_dp_bg_sync.di;
  174886. + _ipu_dp_init(ipu, channel, params->mem_dp_bg_sync.in_pixel_fmt,
  174887. + params->mem_dp_bg_sync.out_pixel_fmt);
  174888. + _ipu_dc_init(ipu, 5, params->mem_dp_bg_sync.di,
  174889. + params->mem_dp_bg_sync.interlaced,
  174890. + params->mem_dp_bg_sync.out_pixel_fmt);
  174891. + ipu->di_use_count[params->mem_dp_bg_sync.di]++;
  174892. + ipu->dc_use_count++;
  174893. + ipu->dp_use_count++;
  174894. + ipu->dmfc_use_count++;
  174895. + break;
  174896. + case MEM_FG_SYNC:
  174897. + _ipu_dp_init(ipu, channel, params->mem_dp_fg_sync.in_pixel_fmt,
  174898. + params->mem_dp_fg_sync.out_pixel_fmt);
  174899. +
  174900. + if (params->mem_dp_fg_sync.alpha_chan_en)
  174901. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true;
  174902. +
  174903. + ipu->dc_use_count++;
  174904. + ipu->dp_use_count++;
  174905. + ipu->dmfc_use_count++;
  174906. + break;
  174907. + case DIRECT_ASYNC0:
  174908. + if (params->direct_async.di > 1) {
  174909. + ret = -EINVAL;
  174910. + goto err;
  174911. + }
  174912. +
  174913. + ipu->dc_di_assignment[8] = params->direct_async.di;
  174914. + _ipu_dc_init(ipu, 8, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
  174915. + ipu->di_use_count[params->direct_async.di]++;
  174916. + ipu->dc_use_count++;
  174917. + break;
  174918. + case DIRECT_ASYNC1:
  174919. + if (params->direct_async.di > 1) {
  174920. + ret = -EINVAL;
  174921. + goto err;
  174922. + }
  174923. +
  174924. + ipu->dc_di_assignment[9] = params->direct_async.di;
  174925. + _ipu_dc_init(ipu, 9, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
  174926. + ipu->di_use_count[params->direct_async.di]++;
  174927. + ipu->dc_use_count++;
  174928. + break;
  174929. + default:
  174930. + dev_err(ipu->dev, "Missing channel initialization\n");
  174931. + break;
  174932. + }
  174933. +
  174934. + ipu->channel_init_mask |= 1L << IPU_CHAN_ID(channel);
  174935. +
  174936. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  174937. +
  174938. +err:
  174939. + mutex_unlock(&ipu->mutex_lock);
  174940. + return ret;
  174941. +}
  174942. +EXPORT_SYMBOL(ipu_init_channel);
  174943. +
  174944. +/*!
  174945. + * This function is called to uninitialize a logical IPU channel.
  174946. + *
  174947. + * @param ipu ipu handler
  174948. + * @param channel Input parameter for the logical channel ID to uninit.
  174949. + */
  174950. +void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel)
  174951. +{
  174952. + uint32_t reg;
  174953. + uint32_t in_dma, out_dma = 0;
  174954. + uint32_t ipu_conf;
  174955. + uint32_t dc_chan = 0;
  174956. + int ret;
  174957. +
  174958. + mutex_lock(&ipu->mutex_lock);
  174959. +
  174960. + if ((ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
  174961. + dev_dbg(ipu->dev, "Channel already uninitialized %d\n",
  174962. + IPU_CHAN_ID(channel));
  174963. + mutex_unlock(&ipu->mutex_lock);
  174964. + return;
  174965. + }
  174966. +
  174967. + /* Make sure channel is disabled */
  174968. + /* Get input and output dma channels */
  174969. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  174970. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  174971. +
  174972. + if (idma_is_set(ipu, IDMAC_CHA_EN, in_dma) ||
  174973. + idma_is_set(ipu, IDMAC_CHA_EN, out_dma)) {
  174974. + dev_err(ipu->dev,
  174975. + "Channel %d is not disabled, disable first\n",
  174976. + IPU_CHAN_ID(channel));
  174977. + mutex_unlock(&ipu->mutex_lock);
  174978. + return;
  174979. + }
  174980. +
  174981. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  174982. +
  174983. + /* Reset the double buffer */
  174984. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(in_dma));
  174985. + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma));
  174986. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(out_dma));
  174987. + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma));
  174988. +
  174989. + /* Reset the triple buffer */
  174990. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(in_dma));
  174991. + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_TRB_MODE_SEL(in_dma));
  174992. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(out_dma));
  174993. + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_TRB_MODE_SEL(out_dma));
  174994. +
  174995. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_dp_graphic_chan(in_dma)) {
  174996. + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = false;
  174997. + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = false;
  174998. + }
  174999. +
  175000. + switch (channel) {
  175001. + case CSI_MEM0:
  175002. + case CSI_MEM1:
  175003. + case CSI_MEM2:
  175004. + case CSI_MEM3:
  175005. + ipu->smfc_use_count--;
  175006. + if (ipu->csi_channel[0] == channel) {
  175007. + ipu->csi_channel[0] = CHAN_NONE;
  175008. + } else if (ipu->csi_channel[1] == channel) {
  175009. + ipu->csi_channel[1] = CHAN_NONE;
  175010. + }
  175011. + break;
  175012. + case CSI_PRP_ENC_MEM:
  175013. + ipu->ic_use_count--;
  175014. + if (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)
  175015. + ipu->using_ic_dirct_ch = 0;
  175016. + _ipu_ic_uninit_prpenc(ipu);
  175017. + if (ipu->csi_channel[0] == channel) {
  175018. + ipu->csi_channel[0] = CHAN_NONE;
  175019. + } else if (ipu->csi_channel[1] == channel) {
  175020. + ipu->csi_channel[1] = CHAN_NONE;
  175021. + }
  175022. + break;
  175023. + case CSI_PRP_VF_MEM:
  175024. + ipu->ic_use_count--;
  175025. + if (ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM)
  175026. + ipu->using_ic_dirct_ch = 0;
  175027. + _ipu_ic_uninit_prpvf(ipu);
  175028. + if (ipu->csi_channel[0] == channel) {
  175029. + ipu->csi_channel[0] = CHAN_NONE;
  175030. + } else if (ipu->csi_channel[1] == channel) {
  175031. + ipu->csi_channel[1] = CHAN_NONE;
  175032. + }
  175033. + break;
  175034. + case MEM_PRP_VF_MEM:
  175035. + ipu->ic_use_count--;
  175036. + _ipu_ic_uninit_prpvf(ipu);
  175037. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  175038. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  175039. + break;
  175040. + case MEM_VDI_PRP_VF_MEM:
  175041. + ipu->ic_use_count--;
  175042. + ipu->vdi_use_count--;
  175043. + if (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM)
  175044. + ipu->using_ic_dirct_ch = 0;
  175045. + _ipu_ic_uninit_prpvf(ipu);
  175046. + _ipu_vdi_uninit(ipu);
  175047. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  175048. + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
  175049. + break;
  175050. + case MEM_VDI_MEM:
  175051. + ipu->ic_use_count--;
  175052. + ipu->vdi_use_count--;
  175053. + if (ipu->using_ic_dirct_ch == MEM_VDI_MEM)
  175054. + ipu->using_ic_dirct_ch = 0;
  175055. + _ipu_vdi_uninit(ipu);
  175056. + break;
  175057. + case MEM_VDI_PRP_VF_MEM_P:
  175058. + case MEM_VDI_PRP_VF_MEM_N:
  175059. + case MEM_VDI_MEM_P:
  175060. + case MEM_VDI_MEM_N:
  175061. + break;
  175062. + case MEM_ROT_VF_MEM:
  175063. + ipu->rot_use_count--;
  175064. + ipu->ic_use_count--;
  175065. + _ipu_ic_uninit_rotate_vf(ipu);
  175066. + break;
  175067. + case MEM_PRP_ENC_MEM:
  175068. + ipu->ic_use_count--;
  175069. + _ipu_ic_uninit_prpenc(ipu);
  175070. + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  175071. + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1);
  175072. + break;
  175073. + case MEM_ROT_ENC_MEM:
  175074. + ipu->rot_use_count--;
  175075. + ipu->ic_use_count--;
  175076. + _ipu_ic_uninit_rotate_enc(ipu);
  175077. + break;
  175078. + case MEM_PP_MEM:
  175079. + ipu->ic_use_count--;
  175080. + _ipu_ic_uninit_pp(ipu);
  175081. + break;
  175082. + case MEM_ROT_PP_MEM:
  175083. + ipu->rot_use_count--;
  175084. + ipu->ic_use_count--;
  175085. + _ipu_ic_uninit_rotate_pp(ipu);
  175086. + break;
  175087. + case MEM_DC_SYNC:
  175088. + dc_chan = 1;
  175089. + _ipu_dc_uninit(ipu, 1);
  175090. + ipu->di_use_count[ipu->dc_di_assignment[1]]--;
  175091. + ipu->dc_use_count--;
  175092. + ipu->dmfc_use_count--;
  175093. + break;
  175094. + case MEM_BG_SYNC:
  175095. + dc_chan = 5;
  175096. + _ipu_dp_uninit(ipu, channel);
  175097. + _ipu_dc_uninit(ipu, 5);
  175098. + ipu->di_use_count[ipu->dc_di_assignment[5]]--;
  175099. + ipu->dc_use_count--;
  175100. + ipu->dp_use_count--;
  175101. + ipu->dmfc_use_count--;
  175102. + break;
  175103. + case MEM_FG_SYNC:
  175104. + _ipu_dp_uninit(ipu, channel);
  175105. + ipu->dc_use_count--;
  175106. + ipu->dp_use_count--;
  175107. + ipu->dmfc_use_count--;
  175108. + break;
  175109. + case DIRECT_ASYNC0:
  175110. + dc_chan = 8;
  175111. + _ipu_dc_uninit(ipu, 8);
  175112. + ipu->di_use_count[ipu->dc_di_assignment[8]]--;
  175113. + ipu->dc_use_count--;
  175114. + break;
  175115. + case DIRECT_ASYNC1:
  175116. + dc_chan = 9;
  175117. + _ipu_dc_uninit(ipu, 9);
  175118. + ipu->di_use_count[ipu->dc_di_assignment[9]]--;
  175119. + ipu->dc_use_count--;
  175120. + break;
  175121. + default:
  175122. + break;
  175123. + }
  175124. +
  175125. + if (ipu->ic_use_count == 0)
  175126. + ipu_conf &= ~IPU_CONF_IC_EN;
  175127. + if (ipu->vdi_use_count == 0) {
  175128. + ipu_conf &= ~IPU_CONF_ISP_EN;
  175129. + ipu_conf &= ~IPU_CONF_VDI_EN;
  175130. + ipu_conf &= ~IPU_CONF_IC_INPUT;
  175131. + }
  175132. + if (ipu->rot_use_count == 0)
  175133. + ipu_conf &= ~IPU_CONF_ROT_EN;
  175134. + if (ipu->dc_use_count == 0)
  175135. + ipu_conf &= ~IPU_CONF_DC_EN;
  175136. + if (ipu->dp_use_count == 0)
  175137. + ipu_conf &= ~IPU_CONF_DP_EN;
  175138. + if (ipu->dmfc_use_count == 0)
  175139. + ipu_conf &= ~IPU_CONF_DMFC_EN;
  175140. + if (ipu->di_use_count[0] == 0) {
  175141. + ipu_conf &= ~IPU_CONF_DI0_EN;
  175142. + }
  175143. + if (ipu->di_use_count[1] == 0) {
  175144. + ipu_conf &= ~IPU_CONF_DI1_EN;
  175145. + }
  175146. + if (ipu->smfc_use_count == 0)
  175147. + ipu_conf &= ~IPU_CONF_SMFC_EN;
  175148. +
  175149. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  175150. +
  175151. + ipu->channel_init_mask &= ~(1L << IPU_CHAN_ID(channel));
  175152. +
  175153. + /*
  175154. + * Disable pixel clk and its parent clock(if the parent clock
  175155. + * usecount is 1) after clearing DC/DP/DI bits in IPU_CONF
  175156. + * register to prevent LVDS display channel starvation.
  175157. + */
  175158. + if (_ipu_is_primary_disp_chan(in_dma))
  175159. + clk_disable_unprepare(ipu->pixel_clk[ipu->dc_di_assignment[dc_chan]]);
  175160. +
  175161. + mutex_unlock(&ipu->mutex_lock);
  175162. +
  175163. + _ipu_put(ipu);
  175164. +
  175165. + ret = pm_runtime_put_sync_suspend(ipu->dev);
  175166. + if (ret < 0) {
  175167. + dev_err(ipu->dev, "ch = %d, pm_runtime_put failed:%d!\n",
  175168. + IPU_CHAN_ID(channel), ret);
  175169. + dump_stack();
  175170. + }
  175171. +
  175172. + WARN_ON(ipu->ic_use_count < 0);
  175173. + WARN_ON(ipu->vdi_use_count < 0);
  175174. + WARN_ON(ipu->rot_use_count < 0);
  175175. + WARN_ON(ipu->dc_use_count < 0);
  175176. + WARN_ON(ipu->dp_use_count < 0);
  175177. + WARN_ON(ipu->dmfc_use_count < 0);
  175178. + WARN_ON(ipu->smfc_use_count < 0);
  175179. +}
  175180. +EXPORT_SYMBOL(ipu_uninit_channel);
  175181. +
  175182. +/*!
  175183. + * This function is called to initialize buffer(s) for logical IPU channel.
  175184. + *
  175185. + * @param ipu ipu handler
  175186. + *
  175187. + * @param channel Input parameter for the logical channel ID.
  175188. + *
  175189. + * @param type Input parameter which buffer to initialize.
  175190. + *
  175191. + * @param pixel_fmt Input parameter for pixel format of buffer.
  175192. + * Pixel format is a FOURCC ASCII code.
  175193. + *
  175194. + * @param width Input parameter for width of buffer in pixels.
  175195. + *
  175196. + * @param height Input parameter for height of buffer in pixels.
  175197. + *
  175198. + * @param stride Input parameter for stride length of buffer
  175199. + * in pixels.
  175200. + *
  175201. + * @param rot_mode Input parameter for rotation setting of buffer.
  175202. + * A rotation setting other than
  175203. + * IPU_ROTATE_VERT_FLIP
  175204. + * should only be used for input buffers of
  175205. + * rotation channels.
  175206. + *
  175207. + * @param phyaddr_0 Input parameter buffer 0 physical address.
  175208. + *
  175209. + * @param phyaddr_1 Input parameter buffer 1 physical address.
  175210. + * Setting this to a value other than NULL enables
  175211. + * double buffering mode.
  175212. + *
  175213. + * @param phyaddr_2 Input parameter buffer 2 physical address.
  175214. + * Setting this to a value other than NULL enables
  175215. + * triple buffering mode, phyaddr_1 should not be
  175216. + * NULL then.
  175217. + *
  175218. + * @param u private u offset for additional cropping,
  175219. + * zero if not used.
  175220. + *
  175221. + * @param v private v offset for additional cropping,
  175222. + * zero if not used.
  175223. + *
  175224. + * @return Returns 0 on success or negative error code on fail
  175225. + */
  175226. +int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  175227. + ipu_buffer_t type,
  175228. + uint32_t pixel_fmt,
  175229. + uint16_t width, uint16_t height,
  175230. + uint32_t stride,
  175231. + ipu_rotate_mode_t rot_mode,
  175232. + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
  175233. + dma_addr_t phyaddr_2,
  175234. + uint32_t u, uint32_t v)
  175235. +{
  175236. + uint32_t reg;
  175237. + uint32_t dma_chan;
  175238. + uint32_t burst_size;
  175239. +
  175240. + dma_chan = channel_2_dma(channel, type);
  175241. + if (!idma_is_valid(dma_chan))
  175242. + return -EINVAL;
  175243. +
  175244. + if (stride < width * bytes_per_pixel(pixel_fmt))
  175245. + stride = width * bytes_per_pixel(pixel_fmt);
  175246. +
  175247. + if (stride % 4) {
  175248. + dev_err(ipu->dev,
  175249. + "Stride not 32-bit aligned, stride = %d\n", stride);
  175250. + return -EINVAL;
  175251. + }
  175252. + /* IC & IRT channels' width must be multiple of 8 pixels */
  175253. + if ((_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan))
  175254. + && (width % 8)) {
  175255. + dev_err(ipu->dev, "Width must be 8 pixel multiple\n");
  175256. + return -EINVAL;
  175257. + }
  175258. +
  175259. + if (_ipu_is_vdi_out_chan(dma_chan) &&
  175260. + ((width < 16) || (height < 16) || (width % 2) || (height % 4))) {
  175261. + dev_err(ipu->dev, "vdi width/height limited err\n");
  175262. + return -EINVAL;
  175263. + }
  175264. +
  175265. + /* IPUv3EX and IPUv3M support triple buffer */
  175266. + if ((!_ipu_is_trb_chan(dma_chan)) && phyaddr_2) {
  175267. + dev_err(ipu->dev, "Chan%d doesn't support triple buffer "
  175268. + "mode\n", dma_chan);
  175269. + return -EINVAL;
  175270. + }
  175271. + if (!phyaddr_1 && phyaddr_2) {
  175272. + dev_err(ipu->dev, "Chan%d's buf1 physical addr is NULL for "
  175273. + "triple buffer mode\n", dma_chan);
  175274. + return -EINVAL;
  175275. + }
  175276. +
  175277. + mutex_lock(&ipu->mutex_lock);
  175278. +
  175279. + /* Build parameter memory data for DMA channel */
  175280. + _ipu_ch_param_init(ipu, dma_chan, pixel_fmt, width, height, stride, u, v, 0,
  175281. + phyaddr_0, phyaddr_1, phyaddr_2);
  175282. +
  175283. + /* Set correlative channel parameter of local alpha channel */
  175284. + if ((_ipu_is_ic_graphic_chan(dma_chan) ||
  175285. + _ipu_is_dp_graphic_chan(dma_chan)) &&
  175286. + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] == true)) {
  175287. + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, true);
  175288. + _ipu_ch_param_set_alpha_buffer_memory(ipu, dma_chan);
  175289. + _ipu_ch_param_set_alpha_condition_read(ipu, dma_chan);
  175290. + /* fix alpha width as 8 and burst size as 16*/
  175291. + _ipu_ch_params_set_alpha_width(ipu, dma_chan, 8);
  175292. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
  175293. + } else if (_ipu_is_ic_graphic_chan(dma_chan) &&
  175294. + ipu_pixel_format_has_alpha(pixel_fmt))
  175295. + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, false);
  175296. +
  175297. + if (rot_mode)
  175298. + _ipu_ch_param_set_rotation(ipu, dma_chan, rot_mode);
  175299. +
  175300. + /* IC and ROT channels have restriction of 8 or 16 pix burst length */
  175301. + if (_ipu_is_ic_chan(dma_chan) || _ipu_is_vdi_out_chan(dma_chan)) {
  175302. + if ((width % 16) == 0)
  175303. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16);
  175304. + else
  175305. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
  175306. + } else if (_ipu_is_irt_chan(dma_chan)) {
  175307. + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8);
  175308. + _ipu_ch_param_set_block_mode(ipu, dma_chan);
  175309. + } else if (_ipu_is_dmfc_chan(dma_chan)) {
  175310. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  175311. + _ipu_dmfc_set_wait4eot(ipu, dma_chan, width);
  175312. + _ipu_dmfc_set_burst_size(ipu, dma_chan, burst_size);
  175313. + }
  175314. +
  175315. + if (_ipu_disp_chan_is_interlaced(ipu, channel) ||
  175316. + ipu->chan_is_interlaced[dma_chan])
  175317. + _ipu_ch_param_set_interlaced_scan(ipu, dma_chan);
  175318. +
  175319. + if (_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan) ||
  175320. + _ipu_is_vdi_out_chan(dma_chan)) {
  175321. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  175322. + _ipu_ic_idma_init(ipu, dma_chan, width, height, burst_size,
  175323. + rot_mode);
  175324. + } else if (_ipu_is_smfc_chan(dma_chan)) {
  175325. + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan);
  175326. + /*
  175327. + * This is different from IPUv3 spec, but it is confirmed
  175328. + * in IPUforum that SMFC burst size should be NPB[6:3]
  175329. + * when IDMAC works in 16-bit generic data mode.
  175330. + */
  175331. + if (pixel_fmt == IPU_PIX_FMT_GENERIC)
  175332. + /* 8 bits per pixel */
  175333. + burst_size = burst_size >> 4;
  175334. + else if (pixel_fmt == IPU_PIX_FMT_GENERIC_16)
  175335. + /* 16 bits per pixel */
  175336. + burst_size = burst_size >> 3;
  175337. + else
  175338. + burst_size = burst_size >> 2;
  175339. + _ipu_smfc_set_burst_size(ipu, channel, burst_size-1);
  175340. + }
  175341. +
  175342. + /* AXI-id */
  175343. + if (idma_is_set(ipu, IDMAC_CHA_PRI, dma_chan)) {
  175344. + unsigned reg = IDMAC_CH_LOCK_EN_1;
  175345. + uint32_t value = 0;
  175346. + if (ipu->pdata->devtype == IPU_V3H) {
  175347. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 0);
  175348. + switch (dma_chan) {
  175349. + case 5:
  175350. + value = 0x3;
  175351. + break;
  175352. + case 11:
  175353. + value = 0x3 << 2;
  175354. + break;
  175355. + case 12:
  175356. + value = 0x3 << 4;
  175357. + break;
  175358. + case 14:
  175359. + value = 0x3 << 6;
  175360. + break;
  175361. + case 15:
  175362. + value = 0x3 << 8;
  175363. + break;
  175364. + case 20:
  175365. + value = 0x3 << 10;
  175366. + break;
  175367. + case 21:
  175368. + value = 0x3 << 12;
  175369. + break;
  175370. + case 22:
  175371. + value = 0x3 << 14;
  175372. + break;
  175373. + case 23:
  175374. + value = 0x3 << 16;
  175375. + break;
  175376. + case 27:
  175377. + value = 0x3 << 18;
  175378. + break;
  175379. + case 28:
  175380. + value = 0x3 << 20;
  175381. + break;
  175382. + case 45:
  175383. + reg = IDMAC_CH_LOCK_EN_2;
  175384. + value = 0x3 << 0;
  175385. + break;
  175386. + case 46:
  175387. + reg = IDMAC_CH_LOCK_EN_2;
  175388. + value = 0x3 << 2;
  175389. + break;
  175390. + case 47:
  175391. + reg = IDMAC_CH_LOCK_EN_2;
  175392. + value = 0x3 << 4;
  175393. + break;
  175394. + case 48:
  175395. + reg = IDMAC_CH_LOCK_EN_2;
  175396. + value = 0x3 << 6;
  175397. + break;
  175398. + case 49:
  175399. + reg = IDMAC_CH_LOCK_EN_2;
  175400. + value = 0x3 << 8;
  175401. + break;
  175402. + case 50:
  175403. + reg = IDMAC_CH_LOCK_EN_2;
  175404. + value = 0x3 << 10;
  175405. + break;
  175406. + default:
  175407. + break;
  175408. + }
  175409. + value |= ipu_idmac_read(ipu, reg);
  175410. + ipu_idmac_write(ipu, value, reg);
  175411. + } else
  175412. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
  175413. + } else {
  175414. + if (ipu->pdata->devtype == IPU_V3H)
  175415. + _ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
  175416. + }
  175417. +
  175418. + _ipu_ch_param_dump(ipu, dma_chan);
  175419. +
  175420. + if (phyaddr_2 && g_ipu_hw_rev >= IPU_V3DEX) {
  175421. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
  175422. + reg &= ~idma_mask(dma_chan);
  175423. + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
  175424. +
  175425. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  175426. + reg |= idma_mask(dma_chan);
  175427. + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan));
  175428. +
  175429. + /* Set IDMAC third buffer's cpmem number */
  175430. + /* See __ipu_ch_get_third_buf_cpmem_num() for mapping */
  175431. + ipu_idmac_write(ipu, 0x00444047L, IDMAC_SUB_ADDR_4);
  175432. + ipu_idmac_write(ipu, 0x46004241L, IDMAC_SUB_ADDR_3);
  175433. + ipu_idmac_write(ipu, 0x00000045L, IDMAC_SUB_ADDR_1);
  175434. +
  175435. + /* Reset to buffer 0 */
  175436. + ipu_cm_write(ipu, tri_cur_buf_mask(dma_chan),
  175437. + IPU_CHA_TRIPLE_CUR_BUF(dma_chan));
  175438. + } else {
  175439. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  175440. + reg &= ~idma_mask(dma_chan);
  175441. + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan));
  175442. +
  175443. + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan));
  175444. + if (phyaddr_1)
  175445. + reg |= idma_mask(dma_chan);
  175446. + else
  175447. + reg &= ~idma_mask(dma_chan);
  175448. + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan));
  175449. +
  175450. + /* Reset to buffer 0 */
  175451. + ipu_cm_write(ipu, idma_mask(dma_chan),
  175452. + IPU_CHA_CUR_BUF(dma_chan));
  175453. +
  175454. + }
  175455. +
  175456. + mutex_unlock(&ipu->mutex_lock);
  175457. +
  175458. + return 0;
  175459. +}
  175460. +EXPORT_SYMBOL(ipu_init_channel_buffer);
  175461. +
  175462. +/*!
  175463. + * This function is called to update the physical address of a buffer for
  175464. + * a logical IPU channel.
  175465. + *
  175466. + * @param ipu ipu handler
  175467. + * @param channel Input parameter for the logical channel ID.
  175468. + *
  175469. + * @param type Input parameter which buffer to initialize.
  175470. + *
  175471. + * @param bufNum Input parameter for buffer number to update.
  175472. + * 0 or 1 are the only valid values.
  175473. + *
  175474. + * @param phyaddr Input parameter buffer physical address.
  175475. + *
  175476. + * @return This function returns 0 on success or negative error code on
  175477. + * fail. This function will fail if the buffer is set to ready.
  175478. + */
  175479. +int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  175480. + ipu_buffer_t type, uint32_t bufNum, dma_addr_t phyaddr)
  175481. +{
  175482. + uint32_t reg;
  175483. + int ret = 0;
  175484. + uint32_t dma_chan = channel_2_dma(channel, type);
  175485. + unsigned long lock_flags;
  175486. +
  175487. + if (dma_chan == IDMA_CHAN_INVALID)
  175488. + return -EINVAL;
  175489. +
  175490. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  175491. + if (bufNum == 0)
  175492. + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan));
  175493. + else if (bufNum == 1)
  175494. + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan));
  175495. + else
  175496. + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan));
  175497. +
  175498. + if ((reg & idma_mask(dma_chan)) == 0)
  175499. + _ipu_ch_param_set_buffer(ipu, dma_chan, bufNum, phyaddr);
  175500. + else
  175501. + ret = -EACCES;
  175502. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  175503. +
  175504. + return ret;
  175505. +}
  175506. +EXPORT_SYMBOL(ipu_update_channel_buffer);
  175507. +
  175508. +/*!
  175509. + * This function is called to update the band mode setting for
  175510. + * a logical IPU channel.
  175511. + *
  175512. + * @param ipu ipu handler
  175513. + *
  175514. + * @param channel Input parameter for the logical channel ID.
  175515. + *
  175516. + * @param type Input parameter which buffer to initialize.
  175517. + *
  175518. + * @param band_height Input parameter for band lines:
  175519. + * shoule be log2(4/8/16/32/64/128/256).
  175520. + *
  175521. + * @return This function returns 0 on success or negative error code on
  175522. + * fail.
  175523. + */
  175524. +int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
  175525. + ipu_buffer_t type, uint32_t band_height)
  175526. +{
  175527. + uint32_t reg;
  175528. + int ret = 0;
  175529. + uint32_t dma_chan = channel_2_dma(channel, type);
  175530. +
  175531. + if ((2 > band_height) || (8 < band_height))
  175532. + return -EINVAL;
  175533. +
  175534. + mutex_lock(&ipu->mutex_lock);
  175535. +
  175536. + reg = ipu_idmac_read(ipu, IDMAC_BAND_EN(dma_chan));
  175537. + reg |= 1 << (dma_chan % 32);
  175538. + ipu_idmac_write(ipu, reg, IDMAC_BAND_EN(dma_chan));
  175539. +
  175540. + _ipu_ch_param_set_bandmode(ipu, dma_chan, band_height);
  175541. + dev_dbg(ipu->dev, "dma_chan:%d, band_height:%d.\n\n",
  175542. + dma_chan, 1 << band_height);
  175543. + mutex_unlock(&ipu->mutex_lock);
  175544. +
  175545. + return ret;
  175546. +}
  175547. +EXPORT_SYMBOL(ipu_set_channel_bandmode);
  175548. +
  175549. +/*!
  175550. + * This function is called to initialize a buffer for logical IPU channel.
  175551. + *
  175552. + * @param ipu ipu handler
  175553. + * @param channel Input parameter for the logical channel ID.
  175554. + *
  175555. + * @param type Input parameter which buffer to initialize.
  175556. + *
  175557. + * @param pixel_fmt Input parameter for pixel format of buffer.
  175558. + * Pixel format is a FOURCC ASCII code.
  175559. + *
  175560. + * @param width Input parameter for width of buffer in pixels.
  175561. + *
  175562. + * @param height Input parameter for height of buffer in pixels.
  175563. + *
  175564. + * @param stride Input parameter for stride length of buffer
  175565. + * in pixels.
  175566. + *
  175567. + * @param u predefined private u offset for additional cropping,
  175568. + * zero if not used.
  175569. + *
  175570. + * @param v predefined private v offset for additional cropping,
  175571. + * zero if not used.
  175572. + *
  175573. + * @param vertical_offset vertical offset for Y coordinate
  175574. + * in the existed frame
  175575. + *
  175576. + *
  175577. + * @param horizontal_offset horizontal offset for X coordinate
  175578. + * in the existed frame
  175579. + *
  175580. + *
  175581. + * @return Returns 0 on success or negative error code on fail
  175582. + * This function will fail if any buffer is set to ready.
  175583. + */
  175584. +
  175585. +int32_t ipu_update_channel_offset(struct ipu_soc *ipu,
  175586. + ipu_channel_t channel, ipu_buffer_t type,
  175587. + uint32_t pixel_fmt,
  175588. + uint16_t width, uint16_t height,
  175589. + uint32_t stride,
  175590. + uint32_t u, uint32_t v,
  175591. + uint32_t vertical_offset, uint32_t horizontal_offset)
  175592. +{
  175593. + int ret = 0;
  175594. + uint32_t dma_chan = channel_2_dma(channel, type);
  175595. + unsigned long lock_flags;
  175596. +
  175597. + if (dma_chan == IDMA_CHAN_INVALID)
  175598. + return -EINVAL;
  175599. +
  175600. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  175601. + if ((ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan)) & idma_mask(dma_chan)) ||
  175602. + (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan)) & idma_mask(dma_chan)) ||
  175603. + ((ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan)) & idma_mask(dma_chan)) &&
  175604. + (ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan)) & idma_mask(dma_chan)) &&
  175605. + _ipu_is_trb_chan(dma_chan)))
  175606. + ret = -EACCES;
  175607. + else
  175608. + _ipu_ch_offset_update(ipu, dma_chan, pixel_fmt, width, height, stride,
  175609. + u, v, 0, vertical_offset, horizontal_offset);
  175610. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  175611. +
  175612. + return ret;
  175613. +}
  175614. +EXPORT_SYMBOL(ipu_update_channel_offset);
  175615. +
  175616. +
  175617. +/*!
  175618. + * This function is called to set a channel's buffer as ready.
  175619. + *
  175620. + * @param ipu ipu handler
  175621. + * @param channel Input parameter for the logical channel ID.
  175622. + *
  175623. + * @param type Input parameter which buffer to initialize.
  175624. + *
  175625. + * @param bufNum Input parameter for which buffer number set to
  175626. + * ready state.
  175627. + *
  175628. + * @return Returns 0 on success or negative error code on fail
  175629. + */
  175630. +int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  175631. + ipu_buffer_t type, uint32_t bufNum)
  175632. +{
  175633. + uint32_t dma_chan = channel_2_dma(channel, type);
  175634. + unsigned long lock_flags;
  175635. +
  175636. + if (dma_chan == IDMA_CHAN_INVALID)
  175637. + return -EINVAL;
  175638. +
  175639. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  175640. + /* Mark buffer to be ready. */
  175641. + if (bufNum == 0)
  175642. + ipu_cm_write(ipu, idma_mask(dma_chan),
  175643. + IPU_CHA_BUF0_RDY(dma_chan));
  175644. + else if (bufNum == 1)
  175645. + ipu_cm_write(ipu, idma_mask(dma_chan),
  175646. + IPU_CHA_BUF1_RDY(dma_chan));
  175647. + else
  175648. + ipu_cm_write(ipu, idma_mask(dma_chan),
  175649. + IPU_CHA_BUF2_RDY(dma_chan));
  175650. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  175651. +
  175652. + return 0;
  175653. +}
  175654. +EXPORT_SYMBOL(ipu_select_buffer);
  175655. +
  175656. +/*!
  175657. + * This function is called to set a channel's buffer as ready.
  175658. + *
  175659. + * @param ipu ipu handler
  175660. + * @param bufNum Input parameter for which buffer number set to
  175661. + * ready state.
  175662. + *
  175663. + * @return Returns 0 on success or negative error code on fail
  175664. + */
  175665. +int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum)
  175666. +{
  175667. +
  175668. + uint32_t dma_chan = channel_2_dma(MEM_VDI_PRP_VF_MEM, IPU_INPUT_BUFFER);
  175669. + uint32_t mask_bit =
  175670. + idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_P, IPU_INPUT_BUFFER))|
  175671. + idma_mask(dma_chan)|
  175672. + idma_mask(channel_2_dma(MEM_VDI_PRP_VF_MEM_N, IPU_INPUT_BUFFER));
  175673. + unsigned long lock_flags;
  175674. +
  175675. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  175676. + /* Mark buffers to be ready. */
  175677. + if (bufNum == 0)
  175678. + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF0_RDY(dma_chan));
  175679. + else
  175680. + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF1_RDY(dma_chan));
  175681. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  175682. +
  175683. + return 0;
  175684. +}
  175685. +EXPORT_SYMBOL(ipu_select_multi_vdi_buffer);
  175686. +
  175687. +#define NA -1
  175688. +static int proc_dest_sel[] = {
  175689. + 0, 1, 1, 3, 5, 5, 4, 7, 8, 9, 10, 11, 12, 14, 15, 16,
  175690. + 0, 1, 1, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 14, 31 };
  175691. +static int proc_src_sel[] = { 0, 6, 7, 6, 7, 8, 5, NA, NA, NA,
  175692. + NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, 8, NA };
  175693. +static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA,
  175694. + NA, NA, NA, NA, NA, 1, NA, 2, NA, 3, 4, 4, 4, 4 };
  175695. +
  175696. +
  175697. +/*!
  175698. + * This function links 2 channels together for automatic frame
  175699. + * synchronization. The output of the source channel is linked to the input of
  175700. + * the destination channel.
  175701. + *
  175702. + * @param ipu ipu handler
  175703. + * @param src_ch Input parameter for the logical channel ID of
  175704. + * the source channel.
  175705. + *
  175706. + * @param dest_ch Input parameter for the logical channel ID of
  175707. + * the destination channel.
  175708. + *
  175709. + * @return This function returns 0 on success or negative error code on
  175710. + * fail.
  175711. + */
  175712. +int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
  175713. +{
  175714. + int retval = 0;
  175715. + uint32_t fs_proc_flow1;
  175716. + uint32_t fs_proc_flow2;
  175717. + uint32_t fs_proc_flow3;
  175718. + uint32_t fs_disp_flow1;
  175719. +
  175720. + mutex_lock(&ipu->mutex_lock);
  175721. +
  175722. + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  175723. + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
  175724. + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
  175725. + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
  175726. +
  175727. + switch (src_ch) {
  175728. + case CSI_MEM0:
  175729. + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
  175730. + fs_proc_flow3 |=
  175731. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175732. + FS_SMFC0_DEST_SEL_OFFSET;
  175733. + break;
  175734. + case CSI_MEM1:
  175735. + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
  175736. + fs_proc_flow3 |=
  175737. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175738. + FS_SMFC1_DEST_SEL_OFFSET;
  175739. + break;
  175740. + case CSI_MEM2:
  175741. + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
  175742. + fs_proc_flow3 |=
  175743. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175744. + FS_SMFC2_DEST_SEL_OFFSET;
  175745. + break;
  175746. + case CSI_MEM3:
  175747. + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
  175748. + fs_proc_flow3 |=
  175749. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175750. + FS_SMFC3_DEST_SEL_OFFSET;
  175751. + break;
  175752. + case CSI_PRP_ENC_MEM:
  175753. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  175754. + fs_proc_flow2 |=
  175755. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175756. + FS_PRPENC_DEST_SEL_OFFSET;
  175757. + break;
  175758. + case CSI_PRP_VF_MEM:
  175759. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  175760. + fs_proc_flow2 |=
  175761. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175762. + FS_PRPVF_DEST_SEL_OFFSET;
  175763. + break;
  175764. + case MEM_PP_MEM:
  175765. + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
  175766. + fs_proc_flow2 |=
  175767. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175768. + FS_PP_DEST_SEL_OFFSET;
  175769. + break;
  175770. + case MEM_ROT_PP_MEM:
  175771. + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
  175772. + fs_proc_flow2 |=
  175773. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175774. + FS_PP_ROT_DEST_SEL_OFFSET;
  175775. + break;
  175776. + case MEM_PRP_ENC_MEM:
  175777. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  175778. + fs_proc_flow2 |=
  175779. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175780. + FS_PRPENC_DEST_SEL_OFFSET;
  175781. + break;
  175782. + case MEM_ROT_ENC_MEM:
  175783. + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
  175784. + fs_proc_flow2 |=
  175785. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175786. + FS_PRPENC_ROT_DEST_SEL_OFFSET;
  175787. + break;
  175788. + case MEM_PRP_VF_MEM:
  175789. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  175790. + fs_proc_flow2 |=
  175791. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175792. + FS_PRPVF_DEST_SEL_OFFSET;
  175793. + break;
  175794. + case MEM_VDI_PRP_VF_MEM:
  175795. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  175796. + fs_proc_flow2 |=
  175797. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175798. + FS_PRPVF_DEST_SEL_OFFSET;
  175799. + break;
  175800. + case MEM_ROT_VF_MEM:
  175801. + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
  175802. + fs_proc_flow2 |=
  175803. + proc_dest_sel[IPU_CHAN_ID(dest_ch)] <<
  175804. + FS_PRPVF_ROT_DEST_SEL_OFFSET;
  175805. + break;
  175806. + case MEM_VDOA_MEM:
  175807. + fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
  175808. + if (MEM_VDI_MEM == dest_ch)
  175809. + fs_proc_flow3 |= FS_VDOA_DEST_SEL_VDI;
  175810. + else if (MEM_PP_MEM == dest_ch)
  175811. + fs_proc_flow3 |= FS_VDOA_DEST_SEL_IC;
  175812. + else {
  175813. + retval = -EINVAL;
  175814. + goto err;
  175815. + }
  175816. + break;
  175817. + default:
  175818. + retval = -EINVAL;
  175819. + goto err;
  175820. + }
  175821. +
  175822. + switch (dest_ch) {
  175823. + case MEM_PP_MEM:
  175824. + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
  175825. + if (MEM_VDOA_MEM == src_ch)
  175826. + fs_proc_flow1 |= FS_PP_SRC_SEL_VDOA;
  175827. + else
  175828. + fs_proc_flow1 |= proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  175829. + FS_PP_SRC_SEL_OFFSET;
  175830. + break;
  175831. + case MEM_ROT_PP_MEM:
  175832. + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
  175833. + fs_proc_flow1 |=
  175834. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  175835. + FS_PP_ROT_SRC_SEL_OFFSET;
  175836. + break;
  175837. + case MEM_PRP_ENC_MEM:
  175838. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  175839. + fs_proc_flow1 |=
  175840. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  175841. + break;
  175842. + case MEM_ROT_ENC_MEM:
  175843. + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
  175844. + fs_proc_flow1 |=
  175845. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  175846. + FS_PRPENC_ROT_SRC_SEL_OFFSET;
  175847. + break;
  175848. + case MEM_PRP_VF_MEM:
  175849. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  175850. + fs_proc_flow1 |=
  175851. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  175852. + break;
  175853. + case MEM_VDI_PRP_VF_MEM:
  175854. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  175855. + fs_proc_flow1 |=
  175856. + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET;
  175857. + break;
  175858. + case MEM_ROT_VF_MEM:
  175859. + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
  175860. + fs_proc_flow1 |=
  175861. + proc_src_sel[IPU_CHAN_ID(src_ch)] <<
  175862. + FS_PRPVF_ROT_SRC_SEL_OFFSET;
  175863. + break;
  175864. + case MEM_DC_SYNC:
  175865. + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
  175866. + fs_disp_flow1 |=
  175867. + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC1_SRC_SEL_OFFSET;
  175868. + break;
  175869. + case MEM_BG_SYNC:
  175870. + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
  175871. + fs_disp_flow1 |=
  175872. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  175873. + FS_DP_SYNC0_SRC_SEL_OFFSET;
  175874. + break;
  175875. + case MEM_FG_SYNC:
  175876. + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
  175877. + fs_disp_flow1 |=
  175878. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  175879. + FS_DP_SYNC1_SRC_SEL_OFFSET;
  175880. + break;
  175881. + case MEM_DC_ASYNC:
  175882. + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
  175883. + fs_disp_flow1 |=
  175884. + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC2_SRC_SEL_OFFSET;
  175885. + break;
  175886. + case MEM_BG_ASYNC0:
  175887. + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
  175888. + fs_disp_flow1 |=
  175889. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  175890. + FS_DP_ASYNC0_SRC_SEL_OFFSET;
  175891. + break;
  175892. + case MEM_FG_ASYNC0:
  175893. + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
  175894. + fs_disp_flow1 |=
  175895. + disp_src_sel[IPU_CHAN_ID(src_ch)] <<
  175896. + FS_DP_ASYNC1_SRC_SEL_OFFSET;
  175897. + break;
  175898. + case MEM_VDI_MEM:
  175899. + fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
  175900. + if (MEM_VDOA_MEM == src_ch)
  175901. + fs_proc_flow1 |= FS_VDI_SRC_SEL_VDOA;
  175902. + else {
  175903. + retval = -EINVAL;
  175904. + goto err;
  175905. + }
  175906. + break;
  175907. + default:
  175908. + retval = -EINVAL;
  175909. + goto err;
  175910. + }
  175911. +
  175912. + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
  175913. + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
  175914. + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
  175915. + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
  175916. +
  175917. +err:
  175918. + mutex_unlock(&ipu->mutex_lock);
  175919. + return retval;
  175920. +}
  175921. +EXPORT_SYMBOL(ipu_link_channels);
  175922. +
  175923. +/*!
  175924. + * This function unlinks 2 channels and disables automatic frame
  175925. + * synchronization.
  175926. + *
  175927. + * @param ipu ipu handler
  175928. + * @param src_ch Input parameter for the logical channel ID of
  175929. + * the source channel.
  175930. + *
  175931. + * @param dest_ch Input parameter for the logical channel ID of
  175932. + * the destination channel.
  175933. + *
  175934. + * @return This function returns 0 on success or negative error code on
  175935. + * fail.
  175936. + */
  175937. +int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch)
  175938. +{
  175939. + int retval = 0;
  175940. + uint32_t fs_proc_flow1;
  175941. + uint32_t fs_proc_flow2;
  175942. + uint32_t fs_proc_flow3;
  175943. + uint32_t fs_disp_flow1;
  175944. +
  175945. + mutex_lock(&ipu->mutex_lock);
  175946. +
  175947. + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1);
  175948. + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2);
  175949. + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3);
  175950. + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1);
  175951. +
  175952. + switch (src_ch) {
  175953. + case CSI_MEM0:
  175954. + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK;
  175955. + break;
  175956. + case CSI_MEM1:
  175957. + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK;
  175958. + break;
  175959. + case CSI_MEM2:
  175960. + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK;
  175961. + break;
  175962. + case CSI_MEM3:
  175963. + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK;
  175964. + break;
  175965. + case CSI_PRP_ENC_MEM:
  175966. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  175967. + break;
  175968. + case CSI_PRP_VF_MEM:
  175969. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  175970. + break;
  175971. + case MEM_PP_MEM:
  175972. + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK;
  175973. + break;
  175974. + case MEM_ROT_PP_MEM:
  175975. + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK;
  175976. + break;
  175977. + case MEM_PRP_ENC_MEM:
  175978. + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK;
  175979. + break;
  175980. + case MEM_ROT_ENC_MEM:
  175981. + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK;
  175982. + break;
  175983. + case MEM_PRP_VF_MEM:
  175984. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  175985. + break;
  175986. + case MEM_VDI_PRP_VF_MEM:
  175987. + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK;
  175988. + break;
  175989. + case MEM_ROT_VF_MEM:
  175990. + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK;
  175991. + break;
  175992. + case MEM_VDOA_MEM:
  175993. + fs_proc_flow3 &= ~FS_VDOA_DEST_SEL_MASK;
  175994. + break;
  175995. + default:
  175996. + retval = -EINVAL;
  175997. + goto err;
  175998. + }
  175999. +
  176000. + switch (dest_ch) {
  176001. + case MEM_PP_MEM:
  176002. + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK;
  176003. + break;
  176004. + case MEM_ROT_PP_MEM:
  176005. + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK;
  176006. + break;
  176007. + case MEM_PRP_ENC_MEM:
  176008. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  176009. + break;
  176010. + case MEM_ROT_ENC_MEM:
  176011. + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK;
  176012. + break;
  176013. + case MEM_PRP_VF_MEM:
  176014. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  176015. + break;
  176016. + case MEM_VDI_PRP_VF_MEM:
  176017. + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK;
  176018. + break;
  176019. + case MEM_ROT_VF_MEM:
  176020. + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK;
  176021. + break;
  176022. + case MEM_DC_SYNC:
  176023. + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK;
  176024. + break;
  176025. + case MEM_BG_SYNC:
  176026. + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK;
  176027. + break;
  176028. + case MEM_FG_SYNC:
  176029. + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK;
  176030. + break;
  176031. + case MEM_DC_ASYNC:
  176032. + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK;
  176033. + break;
  176034. + case MEM_BG_ASYNC0:
  176035. + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK;
  176036. + break;
  176037. + case MEM_FG_ASYNC0:
  176038. + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK;
  176039. + break;
  176040. + case MEM_VDI_MEM:
  176041. + fs_proc_flow1 &= ~FS_VDI_SRC_SEL_MASK;
  176042. + break;
  176043. + default:
  176044. + retval = -EINVAL;
  176045. + goto err;
  176046. + }
  176047. +
  176048. + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1);
  176049. + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2);
  176050. + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3);
  176051. + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1);
  176052. +
  176053. +err:
  176054. + mutex_unlock(&ipu->mutex_lock);
  176055. + return retval;
  176056. +}
  176057. +EXPORT_SYMBOL(ipu_unlink_channels);
  176058. +
  176059. +/*!
  176060. + * This function check whether a logical channel was enabled.
  176061. + *
  176062. + * @param ipu ipu handler
  176063. + * @param channel Input parameter for the logical channel ID.
  176064. + *
  176065. + * @return This function returns 1 while request channel is enabled or
  176066. + * 0 for not enabled.
  176067. + */
  176068. +int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel)
  176069. +{
  176070. + uint32_t reg;
  176071. + uint32_t in_dma;
  176072. + uint32_t out_dma;
  176073. +
  176074. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  176075. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  176076. +
  176077. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  176078. + if (reg & idma_mask(in_dma))
  176079. + return 1;
  176080. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  176081. + if (reg & idma_mask(out_dma))
  176082. + return 1;
  176083. + return 0;
  176084. +}
  176085. +EXPORT_SYMBOL(ipu_is_channel_busy);
  176086. +
  176087. +/*!
  176088. + * This function enables a logical channel.
  176089. + *
  176090. + * @param ipu ipu handler
  176091. + * @param channel Input parameter for the logical channel ID.
  176092. + *
  176093. + * @return This function returns 0 on success or negative error code on
  176094. + * fail.
  176095. + */
  176096. +int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel)
  176097. +{
  176098. + uint32_t reg;
  176099. + uint32_t ipu_conf;
  176100. + uint32_t in_dma;
  176101. + uint32_t out_dma;
  176102. + uint32_t sec_dma;
  176103. + uint32_t thrd_dma;
  176104. +
  176105. + mutex_lock(&ipu->mutex_lock);
  176106. +
  176107. + if (ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) {
  176108. + dev_err(ipu->dev, "Warning: channel already enabled %d\n",
  176109. + IPU_CHAN_ID(channel));
  176110. + mutex_unlock(&ipu->mutex_lock);
  176111. + return -EACCES;
  176112. + }
  176113. +
  176114. + /* Get input and output dma channels */
  176115. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  176116. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  176117. +
  176118. + ipu_conf = ipu_cm_read(ipu, IPU_CONF);
  176119. + if (ipu->di_use_count[0] > 0) {
  176120. + ipu_conf |= IPU_CONF_DI0_EN;
  176121. + }
  176122. + if (ipu->di_use_count[1] > 0) {
  176123. + ipu_conf |= IPU_CONF_DI1_EN;
  176124. + }
  176125. + if (ipu->dp_use_count > 0)
  176126. + ipu_conf |= IPU_CONF_DP_EN;
  176127. + if (ipu->dc_use_count > 0)
  176128. + ipu_conf |= IPU_CONF_DC_EN;
  176129. + if (ipu->dmfc_use_count > 0)
  176130. + ipu_conf |= IPU_CONF_DMFC_EN;
  176131. + if (ipu->ic_use_count > 0)
  176132. + ipu_conf |= IPU_CONF_IC_EN;
  176133. + if (ipu->vdi_use_count > 0) {
  176134. + ipu_conf |= IPU_CONF_ISP_EN;
  176135. + ipu_conf |= IPU_CONF_VDI_EN;
  176136. + ipu_conf |= IPU_CONF_IC_INPUT;
  176137. + }
  176138. + if (ipu->rot_use_count > 0)
  176139. + ipu_conf |= IPU_CONF_ROT_EN;
  176140. + if (ipu->smfc_use_count > 0)
  176141. + ipu_conf |= IPU_CONF_SMFC_EN;
  176142. + ipu_cm_write(ipu, ipu_conf, IPU_CONF);
  176143. +
  176144. + if (idma_is_valid(in_dma)) {
  176145. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  176146. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
  176147. + }
  176148. + if (idma_is_valid(out_dma)) {
  176149. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  176150. + ipu_idmac_write(ipu, reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
  176151. + }
  176152. +
  176153. + if ((ipu->sec_chan_en[IPU_CHAN_ID(channel)]) &&
  176154. + ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM) ||
  176155. + (channel == MEM_VDI_PRP_VF_MEM))) {
  176156. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  176157. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
  176158. + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
  176159. + }
  176160. + if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
  176161. + ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM))) {
  176162. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  176163. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  176164. + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  176165. +
  176166. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  176167. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  176168. + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_SEP_ALPHA);
  176169. + } else if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) &&
  176170. + ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))) {
  176171. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  176172. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  176173. + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  176174. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  176175. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_SEP_ALPHA);
  176176. + }
  176177. +
  176178. + if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
  176179. + (channel == MEM_FG_SYNC)) {
  176180. + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
  176181. + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
  176182. +
  176183. + _ipu_dp_dc_enable(ipu, channel);
  176184. + }
  176185. +
  176186. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
  176187. + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
  176188. + _ipu_is_vdi_out_chan(out_dma))
  176189. + _ipu_ic_enable_task(ipu, channel);
  176190. +
  176191. + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(channel);
  176192. +
  176193. + mutex_unlock(&ipu->mutex_lock);
  176194. +
  176195. + return 0;
  176196. +}
  176197. +EXPORT_SYMBOL(ipu_enable_channel);
  176198. +
  176199. +/*!
  176200. + * This function check buffer ready for a logical channel.
  176201. + *
  176202. + * @param ipu ipu handler
  176203. + * @param channel Input parameter for the logical channel ID.
  176204. + *
  176205. + * @param type Input parameter which buffer to clear.
  176206. + *
  176207. + * @param bufNum Input parameter for which buffer number clear
  176208. + * ready state.
  176209. + *
  176210. + */
  176211. +int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  176212. + uint32_t bufNum)
  176213. +{
  176214. + uint32_t dma_chan = channel_2_dma(channel, type);
  176215. + uint32_t reg;
  176216. + unsigned long lock_flags;
  176217. +
  176218. + if (dma_chan == IDMA_CHAN_INVALID)
  176219. + return -EINVAL;
  176220. +
  176221. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  176222. + if (bufNum == 0)
  176223. + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan));
  176224. + else if (bufNum == 1)
  176225. + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan));
  176226. + else
  176227. + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan));
  176228. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  176229. +
  176230. + if (reg & idma_mask(dma_chan))
  176231. + return 1;
  176232. + else
  176233. + return 0;
  176234. +}
  176235. +EXPORT_SYMBOL(ipu_check_buffer_ready);
  176236. +
  176237. +/*!
  176238. + * This function clear buffer ready for a logical channel.
  176239. + *
  176240. + * @param ipu ipu handler
  176241. + * @param channel Input parameter for the logical channel ID.
  176242. + *
  176243. + * @param type Input parameter which buffer to clear.
  176244. + *
  176245. + * @param bufNum Input parameter for which buffer number clear
  176246. + * ready state.
  176247. + *
  176248. + */
  176249. +void _ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  176250. + uint32_t bufNum)
  176251. +{
  176252. + uint32_t dma_ch = channel_2_dma(channel, type);
  176253. +
  176254. + if (!idma_is_valid(dma_ch))
  176255. + return;
  176256. +
  176257. + ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
  176258. + if (bufNum == 0)
  176259. + ipu_cm_write(ipu, idma_mask(dma_ch),
  176260. + IPU_CHA_BUF0_RDY(dma_ch));
  176261. + else if (bufNum == 1)
  176262. + ipu_cm_write(ipu, idma_mask(dma_ch),
  176263. + IPU_CHA_BUF1_RDY(dma_ch));
  176264. + else
  176265. + ipu_cm_write(ipu, idma_mask(dma_ch),
  176266. + IPU_CHA_BUF2_RDY(dma_ch));
  176267. + ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
  176268. +}
  176269. +
  176270. +void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  176271. + uint32_t bufNum)
  176272. +{
  176273. + unsigned long lock_flags;
  176274. +
  176275. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  176276. + _ipu_clear_buffer_ready(ipu, channel, type, bufNum);
  176277. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  176278. +}
  176279. +EXPORT_SYMBOL(ipu_clear_buffer_ready);
  176280. +
  176281. +/*!
  176282. + * This function disables a logical channel.
  176283. + *
  176284. + * @param ipu ipu handler
  176285. + * @param channel Input parameter for the logical channel ID.
  176286. + *
  176287. + * @param wait_for_stop Flag to set whether to wait for channel end
  176288. + * of frame or return immediately.
  176289. + *
  176290. + * @return This function returns 0 on success or negative error code on
  176291. + * fail.
  176292. + */
  176293. +int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop)
  176294. +{
  176295. + uint32_t reg;
  176296. + uint32_t in_dma;
  176297. + uint32_t out_dma;
  176298. + uint32_t sec_dma = NO_DMA;
  176299. + uint32_t thrd_dma = NO_DMA;
  176300. + uint16_t fg_pos_x, fg_pos_y;
  176301. + unsigned long lock_flags;
  176302. +
  176303. + mutex_lock(&ipu->mutex_lock);
  176304. +
  176305. + if ((ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) {
  176306. + dev_dbg(ipu->dev, "Channel already disabled %d\n",
  176307. + IPU_CHAN_ID(channel));
  176308. + mutex_unlock(&ipu->mutex_lock);
  176309. + return -EACCES;
  176310. + }
  176311. +
  176312. + /* Get input and output dma channels */
  176313. + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
  176314. + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
  176315. +
  176316. + if ((idma_is_valid(in_dma) &&
  176317. + !idma_is_set(ipu, IDMAC_CHA_EN, in_dma))
  176318. + && (idma_is_valid(out_dma) &&
  176319. + !idma_is_set(ipu, IDMAC_CHA_EN, out_dma))) {
  176320. + mutex_unlock(&ipu->mutex_lock);
  176321. + return -EINVAL;
  176322. + }
  176323. +
  176324. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)])
  176325. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  176326. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) {
  176327. + sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER);
  176328. + thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER);
  176329. + }
  176330. +
  176331. + if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
  176332. + (channel == MEM_DC_SYNC)) {
  176333. + if (channel == MEM_FG_SYNC) {
  176334. + _ipu_disp_get_window_pos(ipu, channel, &fg_pos_x, &fg_pos_y);
  176335. + _ipu_disp_set_window_pos(ipu, channel, 0, 0);
  176336. + }
  176337. +
  176338. + _ipu_dp_dc_disable(ipu, channel, false);
  176339. +
  176340. + /*
  176341. + * wait for BG channel EOF then disable FG-IDMAC,
  176342. + * it avoid FG NFB4EOF error.
  176343. + */
  176344. + if ((channel == MEM_FG_SYNC) && (ipu_is_channel_busy(ipu, MEM_BG_SYNC))) {
  176345. + int timeout = 50;
  176346. +
  176347. + ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF),
  176348. + IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF));
  176349. + while ((ipu_cm_read(ipu, IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF)) &
  176350. + IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF)) == 0) {
  176351. + msleep(10);
  176352. + timeout -= 10;
  176353. + if (timeout <= 0) {
  176354. + dev_err(ipu->dev, "warning: wait for bg sync eof timeout\n");
  176355. + break;
  176356. + }
  176357. + }
  176358. + }
  176359. + } else if (wait_for_stop && !_ipu_is_smfc_chan(out_dma) &&
  176360. + channel != CSI_PRP_VF_MEM && channel != CSI_PRP_ENC_MEM) {
  176361. + while (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma) ||
  176362. + idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma) ||
  176363. + (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
  176364. + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma)) ||
  176365. + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
  176366. + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma))) {
  176367. + uint32_t irq = 0xffffffff;
  176368. + int timeout = 50000;
  176369. +
  176370. + if (idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma))
  176371. + irq = out_dma;
  176372. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] &&
  176373. + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma))
  176374. + irq = sec_dma;
  176375. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] &&
  176376. + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma))
  176377. + irq = thrd_dma;
  176378. + if (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma))
  176379. + irq = in_dma;
  176380. +
  176381. + if (irq == 0xffffffff) {
  176382. + dev_dbg(ipu->dev, "warning: no channel busy, break\n");
  176383. + break;
  176384. + }
  176385. +
  176386. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq),
  176387. + IPUIRQ_2_STATREG(irq));
  176388. +
  176389. + dev_dbg(ipu->dev, "warning: channel %d busy, need wait\n", irq);
  176390. +
  176391. + while (((ipu_cm_read(ipu, IPUIRQ_2_STATREG(irq))
  176392. + & IPUIRQ_2_MASK(irq)) == 0) &&
  176393. + (idma_is_set(ipu, IDMAC_CHA_BUSY, irq))) {
  176394. + udelay(10);
  176395. + timeout -= 10;
  176396. + if (timeout <= 0) {
  176397. + ipu_dump_registers(ipu);
  176398. + dev_err(ipu->dev, "warning: disable ipu dma channel %d during its busy state\n", irq);
  176399. + break;
  176400. + }
  176401. + }
  176402. + dev_dbg(ipu->dev, "wait_time:%d\n", 50000 - timeout);
  176403. +
  176404. + }
  176405. + }
  176406. +
  176407. + if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
  176408. + (channel == MEM_DC_SYNC)) {
  176409. + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma));
  176410. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_WM_EN(in_dma));
  176411. + }
  176412. +
  176413. + /* Disable IC task */
  176414. + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
  176415. + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma) ||
  176416. + _ipu_is_vdi_out_chan(out_dma))
  176417. + _ipu_ic_disable_task(ipu, channel);
  176418. +
  176419. + /* Disable DMA channel(s) */
  176420. + if (idma_is_valid(in_dma)) {
  176421. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
  176422. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
  176423. + ipu_cm_write(ipu, idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma));
  176424. + ipu_cm_write(ipu, tri_cur_buf_mask(in_dma),
  176425. + IPU_CHA_TRIPLE_CUR_BUF(in_dma));
  176426. + }
  176427. + if (idma_is_valid(out_dma)) {
  176428. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma));
  176429. + ipu_idmac_write(ipu, reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma));
  176430. + ipu_cm_write(ipu, idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma));
  176431. + ipu_cm_write(ipu, tri_cur_buf_mask(out_dma),
  176432. + IPU_CHA_TRIPLE_CUR_BUF(out_dma));
  176433. + }
  176434. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
  176435. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma));
  176436. + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma));
  176437. + ipu_cm_write(ipu, idma_mask(sec_dma), IPU_CHA_CUR_BUF(sec_dma));
  176438. + }
  176439. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
  176440. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma));
  176441. + ipu_idmac_write(ipu, reg & ~idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma));
  176442. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC) {
  176443. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  176444. + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_SEP_ALPHA);
  176445. + } else {
  176446. + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
  176447. + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_SEP_ALPHA);
  176448. + }
  176449. + ipu_cm_write(ipu, idma_mask(thrd_dma), IPU_CHA_CUR_BUF(thrd_dma));
  176450. + }
  176451. +
  176452. + if (channel == MEM_FG_SYNC)
  176453. + _ipu_disp_set_window_pos(ipu, channel, fg_pos_x, fg_pos_y);
  176454. +
  176455. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  176456. + /* Set channel buffers NOT to be ready */
  176457. + if (idma_is_valid(in_dma)) {
  176458. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 0);
  176459. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 1);
  176460. + _ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 2);
  176461. + }
  176462. + if (idma_is_valid(out_dma)) {
  176463. + _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 0);
  176464. + _ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 1);
  176465. + }
  176466. + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) {
  176467. + _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 0);
  176468. + _ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 1);
  176469. + }
  176470. + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) {
  176471. + _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 0);
  176472. + _ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 1);
  176473. + }
  176474. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  176475. +
  176476. + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel));
  176477. +
  176478. + mutex_unlock(&ipu->mutex_lock);
  176479. +
  176480. + return 0;
  176481. +}
  176482. +EXPORT_SYMBOL(ipu_disable_channel);
  176483. +
  176484. +/*!
  176485. + * This function enables CSI.
  176486. + *
  176487. + * @param ipu ipu handler
  176488. + * @param csi csi num 0 or 1
  176489. + *
  176490. + * @return This function returns 0 on success or negative error code on
  176491. + * fail.
  176492. + */
  176493. +int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi)
  176494. +{
  176495. + uint32_t reg;
  176496. +
  176497. + if (csi > 1) {
  176498. + dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
  176499. + return -EINVAL;
  176500. + }
  176501. +
  176502. + _ipu_get(ipu);
  176503. + mutex_lock(&ipu->mutex_lock);
  176504. + ipu->csi_use_count[csi]++;
  176505. +
  176506. + if (ipu->csi_use_count[csi] == 1) {
  176507. + reg = ipu_cm_read(ipu, IPU_CONF);
  176508. + if (csi == 0)
  176509. + ipu_cm_write(ipu, reg | IPU_CONF_CSI0_EN, IPU_CONF);
  176510. + else
  176511. + ipu_cm_write(ipu, reg | IPU_CONF_CSI1_EN, IPU_CONF);
  176512. + }
  176513. + mutex_unlock(&ipu->mutex_lock);
  176514. + _ipu_put(ipu);
  176515. + return 0;
  176516. +}
  176517. +EXPORT_SYMBOL(ipu_enable_csi);
  176518. +
  176519. +/*!
  176520. + * This function disables CSI.
  176521. + *
  176522. + * @param ipu ipu handler
  176523. + * @param csi csi num 0 or 1
  176524. + *
  176525. + * @return This function returns 0 on success or negative error code on
  176526. + * fail.
  176527. + */
  176528. +int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi)
  176529. +{
  176530. + uint32_t reg;
  176531. +
  176532. + if (csi > 1) {
  176533. + dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
  176534. + return -EINVAL;
  176535. + }
  176536. + _ipu_get(ipu);
  176537. + mutex_lock(&ipu->mutex_lock);
  176538. + ipu->csi_use_count[csi]--;
  176539. + if (ipu->csi_use_count[csi] == 0) {
  176540. + _ipu_csi_wait4eof(ipu, ipu->csi_channel[csi]);
  176541. + reg = ipu_cm_read(ipu, IPU_CONF);
  176542. + if (csi == 0)
  176543. + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI0_EN, IPU_CONF);
  176544. + else
  176545. + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI1_EN, IPU_CONF);
  176546. + }
  176547. + mutex_unlock(&ipu->mutex_lock);
  176548. + _ipu_put(ipu);
  176549. + return 0;
  176550. +}
  176551. +EXPORT_SYMBOL(ipu_disable_csi);
  176552. +
  176553. +static irqreturn_t ipu_sync_irq_handler(int irq, void *desc)
  176554. +{
  176555. + struct ipu_soc *ipu = desc;
  176556. + int i;
  176557. + uint32_t line, bit, int_stat, int_ctrl;
  176558. + irqreturn_t result = IRQ_NONE;
  176559. + const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 };
  176560. +
  176561. + spin_lock(&ipu->int_reg_spin_lock);
  176562. +
  176563. + for (i = 0; int_reg[i] != 0; i++) {
  176564. + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i]));
  176565. + int_ctrl = ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i]));
  176566. + int_stat &= int_ctrl;
  176567. + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(int_reg[i]));
  176568. + while ((line = ffs(int_stat)) != 0) {
  176569. + bit = --line;
  176570. + int_stat &= ~(1UL << line);
  176571. + line += (int_reg[i] - 1) * 32;
  176572. + result |=
  176573. + ipu->irq_list[line].handler(line,
  176574. + ipu->irq_list[line].
  176575. + dev_id);
  176576. + if (ipu->irq_list[line].flags & IPU_IRQF_ONESHOT) {
  176577. + int_ctrl &= ~(1UL << bit);
  176578. + ipu_cm_write(ipu, int_ctrl,
  176579. + IPU_INT_CTRL(int_reg[i]));
  176580. + }
  176581. + }
  176582. + }
  176583. +
  176584. + spin_unlock(&ipu->int_reg_spin_lock);
  176585. +
  176586. + return result;
  176587. +}
  176588. +
  176589. +static irqreturn_t ipu_err_irq_handler(int irq, void *desc)
  176590. +{
  176591. + struct ipu_soc *ipu = desc;
  176592. + int i;
  176593. + uint32_t int_stat;
  176594. + const int err_reg[] = { 5, 6, 9, 10, 0 };
  176595. +
  176596. + spin_lock(&ipu->int_reg_spin_lock);
  176597. +
  176598. + for (i = 0; err_reg[i] != 0; i++) {
  176599. + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(err_reg[i]));
  176600. + int_stat &= ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i]));
  176601. + if (int_stat) {
  176602. + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(err_reg[i]));
  176603. + dev_warn(ipu->dev,
  176604. + "IPU Warning - IPU_INT_STAT_%d = 0x%08X\n",
  176605. + err_reg[i], int_stat);
  176606. + /* Disable interrupts so we only get error once */
  176607. + int_stat = ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i])) &
  176608. + ~int_stat;
  176609. + ipu_cm_write(ipu, int_stat, IPU_INT_CTRL(err_reg[i]));
  176610. + }
  176611. + }
  176612. +
  176613. + spin_unlock(&ipu->int_reg_spin_lock);
  176614. +
  176615. + return IRQ_HANDLED;
  176616. +}
  176617. +
  176618. +/*!
  176619. + * This function enables the interrupt for the specified interrupt line.
  176620. + * The interrupt lines are defined in \b ipu_irq_line enum.
  176621. + *
  176622. + * @param ipu ipu handler
  176623. + * @param irq Interrupt line to enable interrupt for.
  176624. + *
  176625. + * @return This function returns 0 on success or negative error code on
  176626. + * fail.
  176627. + */
  176628. +int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq)
  176629. +{
  176630. + uint32_t reg;
  176631. + unsigned long lock_flags;
  176632. + int ret = 0;
  176633. +
  176634. + _ipu_get(ipu);
  176635. +
  176636. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  176637. +
  176638. + /*
  176639. + * Check sync interrupt handler only, since we do nothing for
  176640. + * error interrupts but than print out register values in the
  176641. + * error interrupt source handler.
  176642. + */
  176643. + if (_ipu_is_sync_irq(irq) && (ipu->irq_list[irq].handler == NULL)) {
  176644. + dev_err(ipu->dev, "handler hasn't been registered on sync "
  176645. + "irq %d\n", irq);
  176646. + ret = -EACCES;
  176647. + goto out;
  176648. + }
  176649. +
  176650. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  176651. + reg |= IPUIRQ_2_MASK(irq);
  176652. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  176653. +out:
  176654. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  176655. +
  176656. + _ipu_put(ipu);
  176657. +
  176658. + return ret;
  176659. +}
  176660. +EXPORT_SYMBOL(ipu_enable_irq);
  176661. +
  176662. +/*!
  176663. + * This function disables the interrupt for the specified interrupt line.
  176664. + * The interrupt lines are defined in \b ipu_irq_line enum.
  176665. + *
  176666. + * @param ipu ipu handler
  176667. + * @param irq Interrupt line to disable interrupt for.
  176668. + *
  176669. + */
  176670. +void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq)
  176671. +{
  176672. + uint32_t reg;
  176673. + unsigned long lock_flags;
  176674. +
  176675. + _ipu_get(ipu);
  176676. +
  176677. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  176678. +
  176679. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  176680. + reg &= ~IPUIRQ_2_MASK(irq);
  176681. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  176682. +
  176683. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  176684. +
  176685. + _ipu_put(ipu);
  176686. +}
  176687. +EXPORT_SYMBOL(ipu_disable_irq);
  176688. +
  176689. +/*!
  176690. + * This function clears the interrupt for the specified interrupt line.
  176691. + * The interrupt lines are defined in \b ipu_irq_line enum.
  176692. + *
  176693. + * @param ipu ipu handler
  176694. + * @param irq Interrupt line to clear interrupt for.
  176695. + *
  176696. + */
  176697. +void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq)
  176698. +{
  176699. + unsigned long lock_flags;
  176700. +
  176701. + _ipu_get(ipu);
  176702. +
  176703. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  176704. +
  176705. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
  176706. +
  176707. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  176708. +
  176709. + _ipu_put(ipu);
  176710. +}
  176711. +EXPORT_SYMBOL(ipu_clear_irq);
  176712. +
  176713. +/*!
  176714. + * This function returns the current interrupt status for the specified
  176715. + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
  176716. + *
  176717. + * @param ipu ipu handler
  176718. + * @param irq Interrupt line to get status for.
  176719. + *
  176720. + * @return Returns true if the interrupt is pending/asserted or false if
  176721. + * the interrupt is not pending.
  176722. + */
  176723. +bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq)
  176724. +{
  176725. + uint32_t reg;
  176726. + unsigned long lock_flags;
  176727. +
  176728. + _ipu_get(ipu);
  176729. +
  176730. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  176731. + reg = ipu_cm_read(ipu, IPUIRQ_2_STATREG(irq));
  176732. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  176733. +
  176734. + _ipu_put(ipu);
  176735. +
  176736. + if (reg & IPUIRQ_2_MASK(irq))
  176737. + return true;
  176738. + else
  176739. + return false;
  176740. +}
  176741. +EXPORT_SYMBOL(ipu_get_irq_status);
  176742. +
  176743. +/*!
  176744. + * This function registers an interrupt handler function for the specified
  176745. + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum.
  176746. + *
  176747. + * @param ipu ipu handler
  176748. + * @param irq Interrupt line to get status for.
  176749. + *
  176750. + * @param handler Input parameter for address of the handler
  176751. + * function.
  176752. + *
  176753. + * @param irq_flags Flags for interrupt mode. Currently not used.
  176754. + *
  176755. + * @param devname Input parameter for string name of driver
  176756. + * registering the handler.
  176757. + *
  176758. + * @param dev_id Input parameter for pointer of data to be
  176759. + * passed to the handler.
  176760. + *
  176761. + * @return This function returns 0 on success or negative error code on
  176762. + * fail.
  176763. + */
  176764. +int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
  176765. + irqreturn_t(*handler) (int, void *),
  176766. + uint32_t irq_flags, const char *devname, void *dev_id)
  176767. +{
  176768. + uint32_t reg;
  176769. + unsigned long lock_flags;
  176770. + int ret = 0;
  176771. +
  176772. + BUG_ON(irq >= IPU_IRQ_COUNT);
  176773. +
  176774. + _ipu_get(ipu);
  176775. +
  176776. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  176777. +
  176778. + if (ipu->irq_list[irq].handler != NULL) {
  176779. + dev_err(ipu->dev,
  176780. + "handler already installed on irq %d\n", irq);
  176781. + ret = -EINVAL;
  176782. + goto out;
  176783. + }
  176784. +
  176785. + /*
  176786. + * Check sync interrupt handler only, since we do nothing for
  176787. + * error interrupts but than print out register values in the
  176788. + * error interrupt source handler.
  176789. + */
  176790. + if (_ipu_is_sync_irq(irq) && (handler == NULL)) {
  176791. + dev_err(ipu->dev, "handler is NULL for sync irq %d\n", irq);
  176792. + ret = -EINVAL;
  176793. + goto out;
  176794. + }
  176795. +
  176796. + ipu->irq_list[irq].handler = handler;
  176797. + ipu->irq_list[irq].flags = irq_flags;
  176798. + ipu->irq_list[irq].dev_id = dev_id;
  176799. + ipu->irq_list[irq].name = devname;
  176800. +
  176801. + /* clear irq stat for previous use */
  176802. + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
  176803. + /* enable the interrupt */
  176804. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  176805. + reg |= IPUIRQ_2_MASK(irq);
  176806. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  176807. +out:
  176808. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  176809. +
  176810. + _ipu_put(ipu);
  176811. +
  176812. + return ret;
  176813. +}
  176814. +EXPORT_SYMBOL(ipu_request_irq);
  176815. +
  176816. +/*!
  176817. + * This function unregisters an interrupt handler for the specified interrupt
  176818. + * line. The interrupt lines are defined in \b ipu_irq_line enum.
  176819. + *
  176820. + * @param ipu ipu handler
  176821. + * @param irq Interrupt line to get status for.
  176822. + *
  176823. + * @param dev_id Input parameter for pointer of data to be passed
  176824. + * to the handler. This must match value passed to
  176825. + * ipu_request_irq().
  176826. + *
  176827. + */
  176828. +void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id)
  176829. +{
  176830. + uint32_t reg;
  176831. + unsigned long lock_flags;
  176832. +
  176833. + _ipu_get(ipu);
  176834. +
  176835. + spin_lock_irqsave(&ipu->int_reg_spin_lock, lock_flags);
  176836. +
  176837. + /* disable the interrupt */
  176838. + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
  176839. + reg &= ~IPUIRQ_2_MASK(irq);
  176840. + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
  176841. + if (ipu->irq_list[irq].dev_id == dev_id)
  176842. + memset(&ipu->irq_list[irq], 0, sizeof(ipu->irq_list[irq]));
  176843. +
  176844. + spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
  176845. +
  176846. + _ipu_put(ipu);
  176847. +}
  176848. +EXPORT_SYMBOL(ipu_free_irq);
  176849. +
  176850. +uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type)
  176851. +{
  176852. + uint32_t reg, dma_chan;
  176853. +
  176854. + dma_chan = channel_2_dma(channel, type);
  176855. + if (!idma_is_valid(dma_chan))
  176856. + return -EINVAL;
  176857. +
  176858. + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan));
  176859. + if ((reg & idma_mask(dma_chan)) && _ipu_is_trb_chan(dma_chan)) {
  176860. + reg = ipu_cm_read(ipu, IPU_CHA_TRIPLE_CUR_BUF(dma_chan));
  176861. + return (reg & tri_cur_buf_mask(dma_chan)) >>
  176862. + tri_cur_buf_shift(dma_chan);
  176863. + } else {
  176864. + reg = ipu_cm_read(ipu, IPU_CHA_CUR_BUF(dma_chan));
  176865. + if (reg & idma_mask(dma_chan))
  176866. + return 1;
  176867. + else
  176868. + return 0;
  176869. + }
  176870. +}
  176871. +EXPORT_SYMBOL(ipu_get_cur_buffer_idx);
  176872. +
  176873. +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
  176874. +{
  176875. + uint32_t stat = 0;
  176876. + uint32_t task_stat_reg = ipu_cm_read(ipu, IPU_PROC_TASK_STAT);
  176877. +
  176878. + switch (channel) {
  176879. + case MEM_PRP_VF_MEM:
  176880. + stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
  176881. + break;
  176882. + case MEM_VDI_PRP_VF_MEM:
  176883. + stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET;
  176884. + break;
  176885. + case MEM_ROT_VF_MEM:
  176886. + stat =
  176887. + (task_stat_reg & TSTAT_VF_ROT_MASK) >> TSTAT_VF_ROT_OFFSET;
  176888. + break;
  176889. + case MEM_PRP_ENC_MEM:
  176890. + stat = (task_stat_reg & TSTAT_ENC_MASK) >> TSTAT_ENC_OFFSET;
  176891. + break;
  176892. + case MEM_ROT_ENC_MEM:
  176893. + stat =
  176894. + (task_stat_reg & TSTAT_ENC_ROT_MASK) >>
  176895. + TSTAT_ENC_ROT_OFFSET;
  176896. + break;
  176897. + case MEM_PP_MEM:
  176898. + stat = (task_stat_reg & TSTAT_PP_MASK) >> TSTAT_PP_OFFSET;
  176899. + break;
  176900. + case MEM_ROT_PP_MEM:
  176901. + stat =
  176902. + (task_stat_reg & TSTAT_PP_ROT_MASK) >> TSTAT_PP_ROT_OFFSET;
  176903. + break;
  176904. +
  176905. + default:
  176906. + stat = TASK_STAT_IDLE;
  176907. + break;
  176908. + }
  176909. + return stat;
  176910. +}
  176911. +
  176912. +/*!
  176913. + * This function check for a logical channel status
  176914. + *
  176915. + * @param ipu ipu handler
  176916. + * @param channel Input parameter for the logical channel ID.
  176917. + *
  176918. + * @return This function returns 0 on idle and 1 on busy.
  176919. + *
  176920. + */
  176921. +uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel)
  176922. +{
  176923. + uint32_t dma_status;
  176924. +
  176925. + _ipu_get(ipu);
  176926. + mutex_lock(&ipu->mutex_lock);
  176927. + dma_status = ipu_is_channel_busy(ipu, channel);
  176928. + mutex_unlock(&ipu->mutex_lock);
  176929. + _ipu_put(ipu);
  176930. +
  176931. + dev_dbg(ipu->dev, "%s, dma_status:%d.\n", __func__, dma_status);
  176932. +
  176933. + return dma_status;
  176934. +}
  176935. +EXPORT_SYMBOL(ipu_channel_status);
  176936. +
  176937. +int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch)
  176938. +{
  176939. + uint32_t reg;
  176940. + unsigned long lock_flags;
  176941. + int from_dma = channel_2_dma(from_ch, IPU_INPUT_BUFFER);
  176942. + int to_dma = channel_2_dma(to_ch, IPU_INPUT_BUFFER);
  176943. +
  176944. + mutex_lock(&ipu->mutex_lock);
  176945. +
  176946. + /* enable target channel */
  176947. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(to_dma));
  176948. + ipu_idmac_write(ipu, reg | idma_mask(to_dma), IDMAC_CHA_EN(to_dma));
  176949. +
  176950. + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(to_ch);
  176951. +
  176952. + /* switch dp dc */
  176953. + _ipu_dp_dc_disable(ipu, from_ch, true);
  176954. +
  176955. + /* disable source channel */
  176956. + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(from_dma));
  176957. + ipu_idmac_write(ipu, reg & ~idma_mask(from_dma), IDMAC_CHA_EN(from_dma));
  176958. + ipu_cm_write(ipu, idma_mask(from_dma), IPU_CHA_CUR_BUF(from_dma));
  176959. + ipu_cm_write(ipu, tri_cur_buf_mask(from_dma),
  176960. + IPU_CHA_TRIPLE_CUR_BUF(from_dma));
  176961. +
  176962. + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(from_ch));
  176963. +
  176964. + spin_lock_irqsave(&ipu->rdy_reg_spin_lock, lock_flags);
  176965. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 0);
  176966. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 1);
  176967. + _ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 2);
  176968. + spin_unlock_irqrestore(&ipu->rdy_reg_spin_lock, lock_flags);
  176969. +
  176970. + mutex_unlock(&ipu->mutex_lock);
  176971. +
  176972. + return 0;
  176973. +}
  176974. +EXPORT_SYMBOL(ipu_swap_channel);
  176975. +
  176976. +uint32_t bytes_per_pixel(uint32_t fmt)
  176977. +{
  176978. + switch (fmt) {
  176979. + case IPU_PIX_FMT_GENERIC: /*generic data */
  176980. + case IPU_PIX_FMT_RGB332:
  176981. + case IPU_PIX_FMT_YUV420P:
  176982. + case IPU_PIX_FMT_YVU420P:
  176983. + case IPU_PIX_FMT_YUV422P:
  176984. + case IPU_PIX_FMT_YUV444P:
  176985. + return 1;
  176986. + break;
  176987. + case IPU_PIX_FMT_GENERIC_16: /* generic data */
  176988. + case IPU_PIX_FMT_RGB565:
  176989. + case IPU_PIX_FMT_YUYV:
  176990. + case IPU_PIX_FMT_UYVY:
  176991. + return 2;
  176992. + break;
  176993. + case IPU_PIX_FMT_BGR24:
  176994. + case IPU_PIX_FMT_RGB24:
  176995. + case IPU_PIX_FMT_YUV444:
  176996. + return 3;
  176997. + break;
  176998. + case IPU_PIX_FMT_GENERIC_32: /*generic data */
  176999. + case IPU_PIX_FMT_BGR32:
  177000. + case IPU_PIX_FMT_BGRA32:
  177001. + case IPU_PIX_FMT_RGB32:
  177002. + case IPU_PIX_FMT_RGBA32:
  177003. + case IPU_PIX_FMT_ABGR32:
  177004. + return 4;
  177005. + break;
  177006. + default:
  177007. + return 1;
  177008. + break;
  177009. + }
  177010. + return 0;
  177011. +}
  177012. +EXPORT_SYMBOL(bytes_per_pixel);
  177013. +
  177014. +ipu_color_space_t format_to_colorspace(uint32_t fmt)
  177015. +{
  177016. + switch (fmt) {
  177017. + case IPU_PIX_FMT_RGB666:
  177018. + case IPU_PIX_FMT_RGB565:
  177019. + case IPU_PIX_FMT_BGR24:
  177020. + case IPU_PIX_FMT_RGB24:
  177021. + case IPU_PIX_FMT_GBR24:
  177022. + case IPU_PIX_FMT_BGR32:
  177023. + case IPU_PIX_FMT_BGRA32:
  177024. + case IPU_PIX_FMT_RGB32:
  177025. + case IPU_PIX_FMT_RGBA32:
  177026. + case IPU_PIX_FMT_ABGR32:
  177027. + case IPU_PIX_FMT_LVDS666:
  177028. + case IPU_PIX_FMT_LVDS888:
  177029. + return RGB;
  177030. + break;
  177031. +
  177032. + default:
  177033. + return YCbCr;
  177034. + break;
  177035. + }
  177036. + return RGB;
  177037. +}
  177038. +
  177039. +bool ipu_pixel_format_has_alpha(uint32_t fmt)
  177040. +{
  177041. + switch (fmt) {
  177042. + case IPU_PIX_FMT_RGBA32:
  177043. + case IPU_PIX_FMT_BGRA32:
  177044. + case IPU_PIX_FMT_ABGR32:
  177045. + return true;
  177046. + break;
  177047. + default:
  177048. + return false;
  177049. + break;
  177050. + }
  177051. + return false;
  177052. +}
  177053. +
  177054. +bool ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
  177055. +{
  177056. + return _ipu_ch_param_bad_alpha_pos(pixel_fmt);
  177057. +}
  177058. +EXPORT_SYMBOL(ipu_ch_param_bad_alpha_pos);
  177059. +
  177060. +#ifdef CONFIG_PM
  177061. +static int ipu_suspend(struct device *dev)
  177062. +{
  177063. + struct ipu_soc *ipu = dev_get_drvdata(dev);
  177064. +
  177065. + /* All IDMAC channel and IPU clock should be disabled.*/
  177066. + if (ipu->pdata->pg)
  177067. + ipu->pdata->pg(1);
  177068. +
  177069. + dev_dbg(dev, "ipu suspend.\n");
  177070. + return 0;
  177071. +}
  177072. +
  177073. +static int ipu_resume(struct device *dev)
  177074. +{
  177075. + struct ipu_soc *ipu = dev_get_drvdata(dev);
  177076. +
  177077. + if (ipu->pdata->pg) {
  177078. + ipu->pdata->pg(0);
  177079. +
  177080. + _ipu_get(ipu);
  177081. + _ipu_dmfc_init(ipu, dmfc_type_setup, 1);
  177082. + /* Set sync refresh channels as high priority */
  177083. + ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
  177084. + _ipu_put(ipu);
  177085. + }
  177086. + dev_dbg(dev, "ipu resume.\n");
  177087. + return 0;
  177088. +}
  177089. +
  177090. +int ipu_runtime_suspend(struct device *dev)
  177091. +{
  177092. + release_bus_freq(BUS_FREQ_HIGH);
  177093. + dev_dbg(dev, "ipu busfreq high release.\n");
  177094. +
  177095. + return 0;
  177096. +}
  177097. +
  177098. +int ipu_runtime_resume(struct device *dev)
  177099. +{
  177100. + request_bus_freq(BUS_FREQ_HIGH);
  177101. + dev_dbg(dev, "ipu busfreq high requst.\n");
  177102. +
  177103. + return 0;
  177104. +}
  177105. +
  177106. +static const struct dev_pm_ops ipu_pm_ops = {
  177107. + SET_RUNTIME_PM_OPS(ipu_runtime_suspend, ipu_runtime_resume, NULL)
  177108. + SET_SYSTEM_SLEEP_PM_OPS(ipu_suspend, ipu_resume)
  177109. +};
  177110. +#endif
  177111. +
  177112. +/*!
  177113. + * This structure contains pointers to the power management callback functions.
  177114. + */
  177115. +static struct platform_driver mxcipu_driver = {
  177116. + .driver = {
  177117. + .name = "imx-ipuv3",
  177118. + .of_match_table = imx_ipuv3_dt_ids,
  177119. + #ifdef CONFIG_PM
  177120. + .pm = &ipu_pm_ops,
  177121. + #endif
  177122. + },
  177123. + .probe = ipu_probe,
  177124. + .id_table = imx_ipu_type,
  177125. + .remove = ipu_remove,
  177126. +};
  177127. +
  177128. +int32_t __init ipu_gen_init(void)
  177129. +{
  177130. + int32_t ret;
  177131. +
  177132. + ret = platform_driver_register(&mxcipu_driver);
  177133. + return 0;
  177134. +}
  177135. +
  177136. +subsys_initcall(ipu_gen_init);
  177137. +
  177138. +static void __exit ipu_gen_uninit(void)
  177139. +{
  177140. + platform_driver_unregister(&mxcipu_driver);
  177141. +}
  177142. +
  177143. +module_exit(ipu_gen_uninit);
  177144. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_device.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_device.c
  177145. --- linux-3.14.17/drivers/mxc/ipu3/ipu_device.c 1970-01-01 01:00:00.000000000 +0100
  177146. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_device.c 2014-09-11 18:06:03.134042499 +0200
  177147. @@ -0,0 +1,3717 @@
  177148. +/*
  177149. + * Copyright 2005-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  177150. + */
  177151. +
  177152. +/*
  177153. + * The code contained herein is licensed under the GNU General Public
  177154. + * License. You may obtain a copy of the GNU General Public License
  177155. + * Version 2 or later at the following locations:
  177156. + *
  177157. + * http://www.opensource.org/licenses/gpl-license.html
  177158. + * http://www.gnu.org/copyleft/gpl.html
  177159. + */
  177160. +
  177161. +/*!
  177162. + * @file ipu_device.c
  177163. + *
  177164. + * @brief This file contains the IPUv3 driver device interface and fops functions.
  177165. + *
  177166. + * @ingroup IPU
  177167. + */
  177168. +#include <linux/clk.h>
  177169. +#include <linux/cpumask.h>
  177170. +#include <linux/delay.h>
  177171. +#include <linux/dma-mapping.h>
  177172. +#include <linux/err.h>
  177173. +#include <linux/init.h>
  177174. +#include <linux/io.h>
  177175. +#include <linux/ipu-v3.h>
  177176. +#include <linux/kernel.h>
  177177. +#include <linux/kthread.h>
  177178. +#include <linux/module.h>
  177179. +#include <linux/platform_device.h>
  177180. +#include <linux/poll.h>
  177181. +#include <linux/sched.h>
  177182. +#include <linux/sched/rt.h>
  177183. +#include <linux/slab.h>
  177184. +#include <linux/spinlock.h>
  177185. +#include <linux/time.h>
  177186. +#include <linux/types.h>
  177187. +#include <linux/vmalloc.h>
  177188. +#include <linux/wait.h>
  177189. +
  177190. +#include <asm/cacheflush.h>
  177191. +#include <asm/outercache.h>
  177192. +
  177193. +#include "ipu_param_mem.h"
  177194. +#include "ipu_regs.h"
  177195. +#include "vdoa.h"
  177196. +
  177197. +#define CHECK_RETCODE(cont, str, err, label, ret) \
  177198. +do { \
  177199. + if (cont) { \
  177200. + dev_err(t->dev, "ERR:[0x%p]-no:0x%x "#str" ret:%d," \
  177201. + "line:%d\n", t, t->task_no, ret, __LINE__);\
  177202. + if (ret != -EACCES) { \
  177203. + t->state = err; \
  177204. + goto label; \
  177205. + } \
  177206. + } \
  177207. +} while (0)
  177208. +
  177209. +#define CHECK_RETCODE_CONT(cont, str, err, ret) \
  177210. +do { \
  177211. + if (cont) { \
  177212. + dev_err(t->dev, "ERR:[0x%p]-no:0x%x"#str" ret:%d," \
  177213. + "line:%d\n", t, t->task_no, ret, __LINE__);\
  177214. + if (ret != -EACCES) { \
  177215. + if (t->state == STATE_OK) \
  177216. + t->state = err; \
  177217. + } \
  177218. + } \
  177219. +} while (0)
  177220. +
  177221. +#undef DBG_IPU_PERF
  177222. +#ifdef DBG_IPU_PERF
  177223. +#define CHECK_PERF(ts) \
  177224. +do { \
  177225. + getnstimeofday(ts); \
  177226. +} while (0)
  177227. +
  177228. +#define DECLARE_PERF_VAR \
  177229. + struct timespec ts_queue; \
  177230. + struct timespec ts_dotask; \
  177231. + struct timespec ts_waitirq; \
  177232. + struct timespec ts_sche; \
  177233. + struct timespec ts_rel; \
  177234. + struct timespec ts_frame
  177235. +
  177236. +#define PRINT_TASK_STATISTICS \
  177237. +do { \
  177238. + ts_queue = timespec_sub(tsk->ts_dotask, tsk->ts_queue); \
  177239. + ts_dotask = timespec_sub(tsk->ts_waitirq, tsk->ts_dotask); \
  177240. + ts_waitirq = timespec_sub(tsk->ts_inirq, tsk->ts_waitirq); \
  177241. + ts_sche = timespec_sub(tsk->ts_wakeup, tsk->ts_inirq); \
  177242. + ts_rel = timespec_sub(tsk->ts_rel, tsk->ts_wakeup); \
  177243. + ts_frame = timespec_sub(tsk->ts_rel, tsk->ts_queue); \
  177244. + dev_dbg(tsk->dev, "[0x%p] no-0x%x, ts_q:%ldus, ts_do:%ldus," \
  177245. + "ts_waitirq:%ldus,ts_sche:%ldus, ts_rel:%ldus," \
  177246. + "ts_frame: %ldus\n", tsk, tsk->task_no, \
  177247. + ts_queue.tv_nsec / NSEC_PER_USEC + ts_queue.tv_sec * USEC_PER_SEC,\
  177248. + ts_dotask.tv_nsec / NSEC_PER_USEC + ts_dotask.tv_sec * USEC_PER_SEC,\
  177249. + ts_waitirq.tv_nsec / NSEC_PER_USEC + ts_waitirq.tv_sec * USEC_PER_SEC,\
  177250. + ts_sche.tv_nsec / NSEC_PER_USEC + ts_sche.tv_sec * USEC_PER_SEC,\
  177251. + ts_rel.tv_nsec / NSEC_PER_USEC + ts_rel.tv_sec * USEC_PER_SEC,\
  177252. + ts_frame.tv_nsec / NSEC_PER_USEC + ts_frame.tv_sec * USEC_PER_SEC); \
  177253. + if ((ts_frame.tv_nsec/NSEC_PER_USEC + ts_frame.tv_sec*USEC_PER_SEC) > \
  177254. + 80000) \
  177255. + dev_dbg(tsk->dev, "ts_frame larger than 80ms [0x%p] no-0x%x.\n"\
  177256. + , tsk, tsk->task_no); \
  177257. +} while (0)
  177258. +#else
  177259. +#define CHECK_PERF(ts)
  177260. +#define DECLARE_PERF_VAR
  177261. +#define PRINT_TASK_STATISTICS
  177262. +#endif
  177263. +
  177264. +#define IPU_PP_CH_VF (IPU_TASK_ID_VF - 1)
  177265. +#define IPU_PP_CH_PP (IPU_TASK_ID_PP - 1)
  177266. +#define MAX_PP_CH (IPU_TASK_ID_MAX - 1)
  177267. +#define VDOA_DEF_TIMEOUT_MS (HZ/2)
  177268. +
  177269. +/* Strucutures and variables for exporting MXC IPU as device*/
  177270. +typedef enum {
  177271. + STATE_OK = 0,
  177272. + STATE_QUEUE,
  177273. + STATE_IN_PROGRESS,
  177274. + STATE_ERR,
  177275. + STATE_TIMEOUT,
  177276. + STATE_RES_TIMEOUT,
  177277. + STATE_NO_IPU,
  177278. + STATE_NO_IRQ,
  177279. + STATE_IPU_BUSY,
  177280. + STATE_IRQ_FAIL,
  177281. + STATE_IRQ_TIMEOUT,
  177282. + STATE_ENABLE_CHAN_FAIL,
  177283. + STATE_DISABLE_CHAN_FAIL,
  177284. + STATE_SEL_BUF_FAIL,
  177285. + STATE_INIT_CHAN_FAIL,
  177286. + STATE_LINK_CHAN_FAIL,
  177287. + STATE_UNLINK_CHAN_FAIL,
  177288. + STATE_INIT_CHAN_BUF_FAIL,
  177289. + STATE_INIT_CHAN_BAND_FAIL,
  177290. + STATE_SYS_NO_MEM,
  177291. + STATE_VDOA_IRQ_TIMEOUT,
  177292. + STATE_VDOA_IRQ_FAIL,
  177293. + STATE_VDOA_TASK_FAIL,
  177294. +} ipu_state_t;
  177295. +
  177296. +enum {
  177297. + INPUT_CHAN_VDI_P = 1,
  177298. + INPUT_CHAN,
  177299. + INPUT_CHAN_VDI_N,
  177300. +};
  177301. +
  177302. +struct ipu_state_msg {
  177303. + int state;
  177304. + char *msg;
  177305. +} state_msg[] = {
  177306. + {STATE_OK, "ok"},
  177307. + {STATE_QUEUE, "split queue"},
  177308. + {STATE_IN_PROGRESS, "split in progress"},
  177309. + {STATE_ERR, "error"},
  177310. + {STATE_TIMEOUT, "split task timeout"},
  177311. + {STATE_RES_TIMEOUT, "wait resource timeout"},
  177312. + {STATE_NO_IPU, "no ipu found"},
  177313. + {STATE_NO_IRQ, "no irq found for task"},
  177314. + {STATE_IPU_BUSY, "ipu busy"},
  177315. + {STATE_IRQ_FAIL, "request irq failed"},
  177316. + {STATE_IRQ_TIMEOUT, "wait for irq timeout"},
  177317. + {STATE_ENABLE_CHAN_FAIL, "ipu enable channel fail"},
  177318. + {STATE_DISABLE_CHAN_FAIL, "ipu disable channel fail"},
  177319. + {STATE_SEL_BUF_FAIL, "ipu select buf fail"},
  177320. + {STATE_INIT_CHAN_FAIL, "ipu init channel fail"},
  177321. + {STATE_LINK_CHAN_FAIL, "ipu link channel fail"},
  177322. + {STATE_UNLINK_CHAN_FAIL, "ipu unlink channel fail"},
  177323. + {STATE_INIT_CHAN_BUF_FAIL, "ipu init channel buffer fail"},
  177324. + {STATE_INIT_CHAN_BAND_FAIL, "ipu init channel band mode fail"},
  177325. + {STATE_SYS_NO_MEM, "sys no mem: -ENOMEM"},
  177326. + {STATE_VDOA_IRQ_TIMEOUT, "wait for vdoa irq timeout"},
  177327. + {STATE_VDOA_IRQ_FAIL, "vdoa irq fail"},
  177328. + {STATE_VDOA_TASK_FAIL, "vdoa task fail"},
  177329. +};
  177330. +
  177331. +struct stripe_setting {
  177332. + u32 iw;
  177333. + u32 ih;
  177334. + u32 ow;
  177335. + u32 oh;
  177336. + u32 outh_resize_ratio;
  177337. + u32 outv_resize_ratio;
  177338. + u32 i_left_pos;
  177339. + u32 i_right_pos;
  177340. + u32 i_top_pos;
  177341. + u32 i_bottom_pos;
  177342. + u32 o_left_pos;
  177343. + u32 o_right_pos;
  177344. + u32 o_top_pos;
  177345. + u32 o_bottom_pos;
  177346. + u32 rl_split_line;
  177347. + u32 ud_split_line;
  177348. +};
  177349. +
  177350. +struct task_set {
  177351. +#define NULL_MODE 0x0
  177352. +#define IC_MODE 0x1
  177353. +#define ROT_MODE 0x2
  177354. +#define VDI_MODE 0x4
  177355. +#define IPU_PREPROCESS_MODE_MASK (IC_MODE | ROT_MODE | VDI_MODE)
  177356. +/* VDOA_MODE means this task use vdoa, and VDOA has two modes:
  177357. + * BAND MODE and non-BAND MODE. Non-band mode will do transfer data
  177358. + * to memory. BAND mode needs hareware sync with IPU, it is used default
  177359. + * if connected to VDIC.
  177360. + */
  177361. +#define VDOA_MODE 0x8
  177362. +#define VDOA_BAND_MODE 0x10
  177363. + u8 mode;
  177364. +#define IC_VF 0x1
  177365. +#define IC_PP 0x2
  177366. +#define ROT_VF 0x4
  177367. +#define ROT_PP 0x8
  177368. +#define VDI_VF 0x10
  177369. +#define VDOA_ONLY 0x20
  177370. + u8 task;
  177371. +#define NO_SPLIT 0x0
  177372. +#define RL_SPLIT 0x1
  177373. +#define UD_SPLIT 0x2
  177374. +#define LEFT_STRIPE 0x1
  177375. +#define RIGHT_STRIPE 0x2
  177376. +#define UP_STRIPE 0x4
  177377. +#define DOWN_STRIPE 0x8
  177378. +#define SPLIT_MASK 0xF
  177379. + u8 split_mode;
  177380. + u8 band_lines;
  177381. + ipu_channel_t ic_chan;
  177382. + ipu_channel_t rot_chan;
  177383. + ipu_channel_t vdi_ic_p_chan;
  177384. + ipu_channel_t vdi_ic_n_chan;
  177385. +
  177386. + u32 i_off;
  177387. + u32 i_uoff;
  177388. + u32 i_voff;
  177389. + u32 istride;
  177390. +
  177391. + u32 ov_off;
  177392. + u32 ov_uoff;
  177393. + u32 ov_voff;
  177394. + u32 ovstride;
  177395. +
  177396. + u32 ov_alpha_off;
  177397. + u32 ov_alpha_stride;
  177398. +
  177399. + u32 o_off;
  177400. + u32 o_uoff;
  177401. + u32 o_voff;
  177402. + u32 ostride;
  177403. +
  177404. + u32 r_fmt;
  177405. + u32 r_width;
  177406. + u32 r_height;
  177407. + u32 r_stride;
  177408. + dma_addr_t r_paddr;
  177409. +
  177410. + struct stripe_setting sp_setting;
  177411. +};
  177412. +
  177413. +struct ipu_split_task {
  177414. + struct ipu_task task;
  177415. + struct ipu_task_entry *parent_task;
  177416. + struct ipu_task_entry *child_task;
  177417. + u32 task_no;
  177418. +};
  177419. +
  177420. +struct ipu_task_entry {
  177421. + struct ipu_input input;
  177422. + struct ipu_output output;
  177423. +
  177424. + bool overlay_en;
  177425. + struct ipu_overlay overlay;
  177426. +#define DEF_TIMEOUT_MS 1000
  177427. +#define DEF_DELAY_MS 20
  177428. + int timeout;
  177429. + int irq;
  177430. +
  177431. + u8 task_id;
  177432. + u8 ipu_id;
  177433. + u8 task_in_list;
  177434. + u8 split_done;
  177435. + struct mutex split_lock;
  177436. + struct mutex vdic_lock;
  177437. + wait_queue_head_t split_waitq;
  177438. +
  177439. + struct list_head node;
  177440. + struct list_head split_list;
  177441. + struct ipu_soc *ipu;
  177442. + struct device *dev;
  177443. + struct task_set set;
  177444. + wait_queue_head_t task_waitq;
  177445. + struct completion irq_comp;
  177446. + struct kref refcount;
  177447. + ipu_state_t state;
  177448. + u32 task_no;
  177449. + atomic_t done;
  177450. + atomic_t res_free;
  177451. + atomic_t res_get;
  177452. +
  177453. + struct ipu_task_entry *parent;
  177454. + char *vditmpbuf[2];
  177455. + u32 old_save_lines;
  177456. + u32 old_size;
  177457. + bool buf1filled;
  177458. + bool buf0filled;
  177459. +
  177460. + vdoa_handle_t vdoa_handle;
  177461. + struct vdoa_output_mem {
  177462. + void *vaddr;
  177463. + dma_addr_t paddr;
  177464. + int size;
  177465. + } vdoa_dma;
  177466. +
  177467. +#ifdef DBG_IPU_PERF
  177468. + struct timespec ts_queue;
  177469. + struct timespec ts_dotask;
  177470. + struct timespec ts_waitirq;
  177471. + struct timespec ts_inirq;
  177472. + struct timespec ts_wakeup;
  177473. + struct timespec ts_rel;
  177474. +#endif
  177475. +};
  177476. +
  177477. +struct ipu_channel_tabel {
  177478. + struct mutex lock;
  177479. + u8 used[MXC_IPU_MAX_NUM][MAX_PP_CH];
  177480. + u8 vdoa_used;
  177481. +};
  177482. +
  177483. +struct ipu_thread_data {
  177484. + struct ipu_soc *ipu;
  177485. + u32 id;
  177486. + u32 is_vdoa;
  177487. +};
  177488. +
  177489. +struct ipu_alloc_list {
  177490. + struct list_head list;
  177491. + dma_addr_t phy_addr;
  177492. + void *cpu_addr;
  177493. + u32 size;
  177494. + void *file_index;
  177495. +};
  177496. +
  177497. +static LIST_HEAD(ipu_alloc_list);
  177498. +static DEFINE_MUTEX(ipu_alloc_lock);
  177499. +static struct ipu_channel_tabel ipu_ch_tbl;
  177500. +static LIST_HEAD(ipu_task_list);
  177501. +static DEFINE_SPINLOCK(ipu_task_list_lock);
  177502. +static DECLARE_WAIT_QUEUE_HEAD(thread_waitq);
  177503. +static DECLARE_WAIT_QUEUE_HEAD(res_waitq);
  177504. +static atomic_t req_cnt;
  177505. +static atomic_t file_index = ATOMIC_INIT(1);
  177506. +static int major;
  177507. +static int max_ipu_no;
  177508. +static int thread_id;
  177509. +static atomic_t frame_no;
  177510. +static struct class *ipu_class;
  177511. +static struct device *ipu_dev;
  177512. +static int debug;
  177513. +module_param(debug, int, 0600);
  177514. +#ifdef DBG_IPU_PERF
  177515. +static struct timespec ts_frame_max;
  177516. +static u32 ts_frame_avg;
  177517. +static atomic_t frame_cnt;
  177518. +#endif
  177519. +
  177520. +static bool deinterlace_3_field(struct ipu_task_entry *t)
  177521. +{
  177522. + return ((t->set.mode & VDI_MODE) &&
  177523. + (t->input.deinterlace.motion != HIGH_MOTION));
  177524. +}
  177525. +
  177526. +static u32 tiled_filed_size(struct ipu_task_entry *t)
  177527. +{
  177528. + u32 field_size;
  177529. +
  177530. + /* note: page_align is required by VPU hw ouput buffer */
  177531. + field_size = TILED_NV12_FRAME_SIZE(t->input.width, t->input.height/2);
  177532. + return field_size;
  177533. +}
  177534. +
  177535. +static bool only_ic(u8 mode)
  177536. +{
  177537. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  177538. + return ((mode == IC_MODE) || (mode == VDI_MODE));
  177539. +}
  177540. +
  177541. +static bool only_rot(u8 mode)
  177542. +{
  177543. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  177544. + return (mode == ROT_MODE);
  177545. +}
  177546. +
  177547. +static bool ic_and_rot(u8 mode)
  177548. +{
  177549. + mode = mode & IPU_PREPROCESS_MODE_MASK;
  177550. + return ((mode == (IC_MODE | ROT_MODE)) ||
  177551. + (mode == (VDI_MODE | ROT_MODE)));
  177552. +}
  177553. +
  177554. +static bool need_split(struct ipu_task_entry *t)
  177555. +{
  177556. + return ((t->set.split_mode != NO_SPLIT) || (t->task_no & SPLIT_MASK));
  177557. +}
  177558. +
  177559. +unsigned int fmt_to_bpp(unsigned int pixelformat)
  177560. +{
  177561. + u32 bpp;
  177562. +
  177563. + switch (pixelformat) {
  177564. + case IPU_PIX_FMT_RGB565:
  177565. + /*interleaved 422*/
  177566. + case IPU_PIX_FMT_YUYV:
  177567. + case IPU_PIX_FMT_UYVY:
  177568. + /*non-interleaved 422*/
  177569. + case IPU_PIX_FMT_YUV422P:
  177570. + case IPU_PIX_FMT_YVU422P:
  177571. + bpp = 16;
  177572. + break;
  177573. + case IPU_PIX_FMT_BGR24:
  177574. + case IPU_PIX_FMT_RGB24:
  177575. + case IPU_PIX_FMT_YUV444:
  177576. + case IPU_PIX_FMT_YUV444P:
  177577. + bpp = 24;
  177578. + break;
  177579. + case IPU_PIX_FMT_BGR32:
  177580. + case IPU_PIX_FMT_BGRA32:
  177581. + case IPU_PIX_FMT_RGB32:
  177582. + case IPU_PIX_FMT_RGBA32:
  177583. + case IPU_PIX_FMT_ABGR32:
  177584. + bpp = 32;
  177585. + break;
  177586. + /*non-interleaved 420*/
  177587. + case IPU_PIX_FMT_YUV420P:
  177588. + case IPU_PIX_FMT_YVU420P:
  177589. + case IPU_PIX_FMT_YUV420P2:
  177590. + case IPU_PIX_FMT_NV12:
  177591. + bpp = 12;
  177592. + break;
  177593. + default:
  177594. + bpp = 8;
  177595. + break;
  177596. + }
  177597. + return bpp;
  177598. +}
  177599. +EXPORT_SYMBOL_GPL(fmt_to_bpp);
  177600. +
  177601. +cs_t colorspaceofpixel(int fmt)
  177602. +{
  177603. + switch (fmt) {
  177604. + case IPU_PIX_FMT_RGB565:
  177605. + case IPU_PIX_FMT_BGR24:
  177606. + case IPU_PIX_FMT_RGB24:
  177607. + case IPU_PIX_FMT_BGRA32:
  177608. + case IPU_PIX_FMT_BGR32:
  177609. + case IPU_PIX_FMT_RGBA32:
  177610. + case IPU_PIX_FMT_RGB32:
  177611. + case IPU_PIX_FMT_ABGR32:
  177612. + return RGB_CS;
  177613. + break;
  177614. + case IPU_PIX_FMT_UYVY:
  177615. + case IPU_PIX_FMT_YUYV:
  177616. + case IPU_PIX_FMT_YUV420P2:
  177617. + case IPU_PIX_FMT_YUV420P:
  177618. + case IPU_PIX_FMT_YVU420P:
  177619. + case IPU_PIX_FMT_YVU422P:
  177620. + case IPU_PIX_FMT_YUV422P:
  177621. + case IPU_PIX_FMT_YUV444:
  177622. + case IPU_PIX_FMT_YUV444P:
  177623. + case IPU_PIX_FMT_NV12:
  177624. + case IPU_PIX_FMT_TILED_NV12:
  177625. + case IPU_PIX_FMT_TILED_NV12F:
  177626. + return YUV_CS;
  177627. + break;
  177628. + default:
  177629. + return NULL_CS;
  177630. + }
  177631. +}
  177632. +EXPORT_SYMBOL_GPL(colorspaceofpixel);
  177633. +
  177634. +int need_csc(int ifmt, int ofmt)
  177635. +{
  177636. + cs_t ics, ocs;
  177637. +
  177638. + ics = colorspaceofpixel(ifmt);
  177639. + ocs = colorspaceofpixel(ofmt);
  177640. +
  177641. + if ((ics == NULL_CS) || (ocs == NULL_CS))
  177642. + return -1;
  177643. + else if (ics != ocs)
  177644. + return 1;
  177645. +
  177646. + return 0;
  177647. +}
  177648. +EXPORT_SYMBOL_GPL(need_csc);
  177649. +
  177650. +static int soc_max_in_width(u32 is_vdoa)
  177651. +{
  177652. + return is_vdoa ? 8192 : 4096;
  177653. +}
  177654. +
  177655. +static int soc_max_vdi_in_width(void)
  177656. +{
  177657. + return IPU_MAX_VDI_IN_WIDTH;
  177658. +}
  177659. +static int soc_max_in_height(void)
  177660. +{
  177661. + return 4096;
  177662. +}
  177663. +
  177664. +static int soc_max_out_width(void)
  177665. +{
  177666. + /* mx51/mx53/mx6q is 1024*/
  177667. + return 1024;
  177668. +}
  177669. +
  177670. +static int soc_max_out_height(void)
  177671. +{
  177672. + /* mx51/mx53/mx6q is 1024*/
  177673. + return 1024;
  177674. +}
  177675. +
  177676. +static void dump_task_info(struct ipu_task_entry *t)
  177677. +{
  177678. + if (!debug)
  177679. + return;
  177680. + dev_dbg(t->dev, "[0x%p]input:\n", (void *)t);
  177681. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->input.format);
  177682. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->input.width);
  177683. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->input.height);
  177684. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->input.crop.w);
  177685. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->input.crop.h);
  177686. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  177687. + (void *)t, t->input.crop.pos.x);
  177688. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  177689. + (void *)t, t->input.crop.pos.y);
  177690. + dev_dbg(t->dev, "[0x%p]input buffer:\n", (void *)t);
  177691. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->input.paddr);
  177692. + dev_dbg(t->dev, "[0x%p]\ti_off = 0x%x\n", (void *)t, t->set.i_off);
  177693. + dev_dbg(t->dev, "[0x%p]\ti_uoff = 0x%x\n", (void *)t, t->set.i_uoff);
  177694. + dev_dbg(t->dev, "[0x%p]\ti_voff = 0x%x\n", (void *)t, t->set.i_voff);
  177695. + dev_dbg(t->dev, "[0x%p]\tistride = %d\n", (void *)t, t->set.istride);
  177696. + if (t->input.deinterlace.enable) {
  177697. + dev_dbg(t->dev, "[0x%p]deinterlace enabled with:\n", (void *)t);
  177698. + if (t->input.deinterlace.motion != HIGH_MOTION) {
  177699. + dev_dbg(t->dev, "[0x%p]\tlow/medium motion\n", (void *)t);
  177700. + dev_dbg(t->dev, "[0x%p]\tpaddr_n = 0x%x\n",
  177701. + (void *)t, t->input.paddr_n);
  177702. + } else
  177703. + dev_dbg(t->dev, "[0x%p]\thigh motion\n", (void *)t);
  177704. + }
  177705. +
  177706. + dev_dbg(t->dev, "[0x%p]output:\n", (void *)t);
  177707. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->output.format);
  177708. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->output.width);
  177709. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->output.height);
  177710. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n", (void *)t, t->output.crop.w);
  177711. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n", (void *)t, t->output.crop.h);
  177712. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  177713. + (void *)t, t->output.crop.pos.x);
  177714. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  177715. + (void *)t, t->output.crop.pos.y);
  177716. + dev_dbg(t->dev, "[0x%p]\trotate = %d\n", (void *)t, t->output.rotate);
  177717. + dev_dbg(t->dev, "[0x%p]output buffer:\n", (void *)t);
  177718. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->output.paddr);
  177719. + dev_dbg(t->dev, "[0x%p]\to_off = 0x%x\n", (void *)t, t->set.o_off);
  177720. + dev_dbg(t->dev, "[0x%p]\to_uoff = 0x%x\n", (void *)t, t->set.o_uoff);
  177721. + dev_dbg(t->dev, "[0x%p]\to_voff = 0x%x\n", (void *)t, t->set.o_voff);
  177722. + dev_dbg(t->dev, "[0x%p]\tostride = %d\n", (void *)t, t->set.ostride);
  177723. +
  177724. + if (t->overlay_en) {
  177725. + dev_dbg(t->dev, "[0x%p]overlay:\n", (void *)t);
  177726. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n",
  177727. + (void *)t, t->overlay.format);
  177728. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n",
  177729. + (void *)t, t->overlay.width);
  177730. + dev_dbg(t->dev, "[0x%p]\theight = %d\n",
  177731. + (void *)t, t->overlay.height);
  177732. + dev_dbg(t->dev, "[0x%p]\tcrop.w = %d\n",
  177733. + (void *)t, t->overlay.crop.w);
  177734. + dev_dbg(t->dev, "[0x%p]\tcrop.h = %d\n",
  177735. + (void *)t, t->overlay.crop.h);
  177736. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.x = %d\n",
  177737. + (void *)t, t->overlay.crop.pos.x);
  177738. + dev_dbg(t->dev, "[0x%p]\tcrop.pos.y = %d\n",
  177739. + (void *)t, t->overlay.crop.pos.y);
  177740. + dev_dbg(t->dev, "[0x%p]overlay buffer:\n", (void *)t);
  177741. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
  177742. + (void *)t, t->overlay.paddr);
  177743. + dev_dbg(t->dev, "[0x%p]\tov_off = 0x%x\n",
  177744. + (void *)t, t->set.ov_off);
  177745. + dev_dbg(t->dev, "[0x%p]\tov_uoff = 0x%x\n",
  177746. + (void *)t, t->set.ov_uoff);
  177747. + dev_dbg(t->dev, "[0x%p]\tov_voff = 0x%x\n",
  177748. + (void *)t, t->set.ov_voff);
  177749. + dev_dbg(t->dev, "[0x%p]\tovstride = %d\n",
  177750. + (void *)t, t->set.ovstride);
  177751. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  177752. + dev_dbg(t->dev, "[0x%p]local alpha enabled with:\n",
  177753. + (void *)t);
  177754. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n",
  177755. + (void *)t, t->overlay.alpha.loc_alp_paddr);
  177756. + dev_dbg(t->dev, "[0x%p]\tov_alpha_off = 0x%x\n",
  177757. + (void *)t, t->set.ov_alpha_off);
  177758. + dev_dbg(t->dev, "[0x%p]\tov_alpha_stride = %d\n",
  177759. + (void *)t, t->set.ov_alpha_stride);
  177760. + } else
  177761. + dev_dbg(t->dev, "[0x%p]globle alpha enabled with value 0x%x\n",
  177762. + (void *)t, t->overlay.alpha.gvalue);
  177763. + if (t->overlay.colorkey.enable)
  177764. + dev_dbg(t->dev, "[0x%p]colorkey enabled with value 0x%x\n",
  177765. + (void *)t, t->overlay.colorkey.value);
  177766. + }
  177767. +
  177768. + dev_dbg(t->dev, "[0x%p]want task_id = %d\n", (void *)t, t->task_id);
  177769. + dev_dbg(t->dev, "[0x%p]want task mode is 0x%x\n",
  177770. + (void *)t, t->set.mode);
  177771. + dev_dbg(t->dev, "[0x%p]\tIC_MODE = 0x%x\n", (void *)t, IC_MODE);
  177772. + dev_dbg(t->dev, "[0x%p]\tROT_MODE = 0x%x\n", (void *)t, ROT_MODE);
  177773. + dev_dbg(t->dev, "[0x%p]\tVDI_MODE = 0x%x\n", (void *)t, VDI_MODE);
  177774. + dev_dbg(t->dev, "[0x%p]\tTask_no = 0x%x\n\n\n", (void *)t, t->task_no);
  177775. +}
  177776. +
  177777. +static void dump_check_err(struct device *dev, int err)
  177778. +{
  177779. + switch (err) {
  177780. + case IPU_CHECK_ERR_INPUT_CROP:
  177781. + dev_err(dev, "input crop setting error\n");
  177782. + break;
  177783. + case IPU_CHECK_ERR_OUTPUT_CROP:
  177784. + dev_err(dev, "output crop setting error\n");
  177785. + break;
  177786. + case IPU_CHECK_ERR_OVERLAY_CROP:
  177787. + dev_err(dev, "overlay crop setting error\n");
  177788. + break;
  177789. + case IPU_CHECK_ERR_INPUT_OVER_LIMIT:
  177790. + dev_err(dev, "input over limitation\n");
  177791. + break;
  177792. + case IPU_CHECK_ERR_OVERLAY_WITH_VDI:
  177793. + dev_err(dev, "do not support overlay with deinterlace\n");
  177794. + break;
  177795. + case IPU_CHECK_ERR_OV_OUT_NO_FIT:
  177796. + dev_err(dev,
  177797. + "width/height of overlay and ic output should be same\n");
  177798. + break;
  177799. + case IPU_CHECK_ERR_PROC_NO_NEED:
  177800. + dev_err(dev, "no ipu processing need\n");
  177801. + break;
  177802. + case IPU_CHECK_ERR_SPLIT_INPUTW_OVER:
  177803. + dev_err(dev, "split mode input width overflow\n");
  177804. + break;
  177805. + case IPU_CHECK_ERR_SPLIT_INPUTH_OVER:
  177806. + dev_err(dev, "split mode input height overflow\n");
  177807. + break;
  177808. + case IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER:
  177809. + dev_err(dev, "split mode output width overflow\n");
  177810. + break;
  177811. + case IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER:
  177812. + dev_err(dev, "split mode output height overflow\n");
  177813. + break;
  177814. + case IPU_CHECK_ERR_SPLIT_WITH_ROT:
  177815. + dev_err(dev, "not support split mode with rotation\n");
  177816. + break;
  177817. + case IPU_CHECK_ERR_W_DOWNSIZE_OVER:
  177818. + dev_err(dev, "horizontal downsizing ratio overflow\n");
  177819. + break;
  177820. + case IPU_CHECK_ERR_H_DOWNSIZE_OVER:
  177821. + dev_err(dev, "vertical downsizing ratio overflow\n");
  177822. + break;
  177823. + default:
  177824. + break;
  177825. + }
  177826. +}
  177827. +
  177828. +static void dump_check_warn(struct device *dev, int warn)
  177829. +{
  177830. + if (warn & IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN)
  177831. + dev_warn(dev, "input u/v offset not 8 align\n");
  177832. + if (warn & IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN)
  177833. + dev_warn(dev, "output u/v offset not 8 align\n");
  177834. + if (warn & IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN)
  177835. + dev_warn(dev, "overlay u/v offset not 8 align\n");
  177836. +}
  177837. +
  177838. +static int set_crop(struct ipu_crop *crop, int width, int height, int fmt)
  177839. +{
  177840. + if ((width == 0) || (height == 0)) {
  177841. + pr_err("Invalid param: width=%d, height=%d\n", width, height);
  177842. + return -EINVAL;
  177843. + }
  177844. +
  177845. + if ((IPU_PIX_FMT_TILED_NV12 == fmt) ||
  177846. + (IPU_PIX_FMT_TILED_NV12F == fmt)) {
  177847. + if (crop->w || crop->h) {
  177848. + if (((crop->w + crop->pos.x) > width)
  177849. + || ((crop->h + crop->pos.y) > height)
  177850. + || (0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  177851. + || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  177852. + || (0 != (crop->pos.x % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  177853. + || (0 != (crop->pos.y % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  177854. + ) {
  177855. + pr_err("set_crop error MB align.\n");
  177856. + return -EINVAL;
  177857. + }
  177858. + } else {
  177859. + crop->pos.x = 0;
  177860. + crop->pos.y = 0;
  177861. + crop->w = width;
  177862. + crop->h = height;
  177863. + if ((0 != (crop->w % IPU_PIX_FMT_TILED_NV12_MBALIGN))
  177864. + || (0 != (crop->h % IPU_PIX_FMT_TILED_NV12_MBALIGN))) {
  177865. + pr_err("set_crop error w/h MB align.\n");
  177866. + return -EINVAL;
  177867. + }
  177868. + }
  177869. + } else {
  177870. + if (crop->w || crop->h) {
  177871. + if (((crop->w + crop->pos.x) > (width + 16))
  177872. + || ((crop->h + crop->pos.y) > height + 16)) {
  177873. + pr_err("set_crop error exceeds width/height.\n");
  177874. + return -EINVAL;
  177875. + }
  177876. + } else {
  177877. + crop->pos.x = 0;
  177878. + crop->pos.y = 0;
  177879. + crop->w = width;
  177880. + crop->h = height;
  177881. + }
  177882. + crop->w -= crop->w%8;
  177883. + crop->h -= crop->h%8;
  177884. + }
  177885. +
  177886. + if ((crop->w == 0) || (crop->h == 0)) {
  177887. + pr_err("Invalid crop param: crop.w=%d, crop.h=%d\n",
  177888. + crop->w, crop->h);
  177889. + return -EINVAL;
  177890. + }
  177891. +
  177892. + return 0;
  177893. +}
  177894. +
  177895. +static void update_offset(unsigned int fmt,
  177896. + unsigned int width, unsigned int height,
  177897. + unsigned int pos_x, unsigned int pos_y,
  177898. + int *off, int *uoff, int *voff, int *stride)
  177899. +{
  177900. + /* NOTE: u v offset should based on start point of off*/
  177901. + switch (fmt) {
  177902. + case IPU_PIX_FMT_YUV420P2:
  177903. + case IPU_PIX_FMT_YUV420P:
  177904. + *off = pos_y * width + pos_x;
  177905. + *uoff = (width * (height - pos_y) - pos_x)
  177906. + + (width/2) * (pos_y/2) + pos_x/2;
  177907. + /* In case height is odd, round up to even */
  177908. + *voff = *uoff + (width/2) * ((height+1)/2);
  177909. + break;
  177910. + case IPU_PIX_FMT_YVU420P:
  177911. + *off = pos_y * width + pos_x;
  177912. + *voff = (width * (height - pos_y) - pos_x)
  177913. + + (width/2) * (pos_y/2) + pos_x/2;
  177914. + /* In case height is odd, round up to even */
  177915. + *uoff = *voff + (width/2) * ((height+1)/2);
  177916. + break;
  177917. + case IPU_PIX_FMT_YVU422P:
  177918. + *off = pos_y * width + pos_x;
  177919. + *voff = (width * (height - pos_y) - pos_x)
  177920. + + (width/2) * pos_y + pos_x/2;
  177921. + *uoff = *voff + (width/2) * height;
  177922. + break;
  177923. + case IPU_PIX_FMT_YUV422P:
  177924. + *off = pos_y * width + pos_x;
  177925. + *uoff = (width * (height - pos_y) - pos_x)
  177926. + + (width/2) * pos_y + pos_x/2;
  177927. + *voff = *uoff + (width/2) * height;
  177928. + break;
  177929. + case IPU_PIX_FMT_YUV444P:
  177930. + *off = pos_y * width + pos_x;
  177931. + *uoff = width * height;
  177932. + *voff = width * height * 2;
  177933. + break;
  177934. + case IPU_PIX_FMT_NV12:
  177935. + *off = pos_y * width + pos_x;
  177936. + *uoff = (width * (height - pos_y) - pos_x)
  177937. + + width * (pos_y/2) + pos_x;
  177938. + break;
  177939. + case IPU_PIX_FMT_TILED_NV12:
  177940. + /*
  177941. + * tiled format, progressive:
  177942. + * assuming that line is aligned with MB height (aligned to 16)
  177943. + * offset = line * stride + (pixel / MB_width) * pixels_in_MB
  177944. + * = line * stride + (pixel / 16) * 256
  177945. + * = line * stride + pixel * 16
  177946. + */
  177947. + *off = pos_y * width + (pos_x << 4);
  177948. + *uoff = ALIGN(width * height, SZ_4K) + (*off >> 1) - *off;
  177949. + break;
  177950. + case IPU_PIX_FMT_TILED_NV12F:
  177951. + /*
  177952. + * tiled format, interlaced:
  177953. + * same as above, only number of pixels in MB is 128,
  177954. + * instead of 256
  177955. + */
  177956. + *off = (pos_y >> 1) * width + (pos_x << 3);
  177957. + *uoff = ALIGN(width * height/2, SZ_4K) + (*off >> 1) - *off;
  177958. + break;
  177959. + default:
  177960. + *off = (pos_y * width + pos_x) * fmt_to_bpp(fmt)/8;
  177961. + break;
  177962. + }
  177963. + *stride = width * bytes_per_pixel(fmt);
  177964. +}
  177965. +
  177966. +static int update_split_setting(struct ipu_task_entry *t, bool vdi_split)
  177967. +{
  177968. + struct stripe_param left_stripe;
  177969. + struct stripe_param right_stripe;
  177970. + struct stripe_param up_stripe;
  177971. + struct stripe_param down_stripe;
  177972. + u32 iw, ih, ow, oh;
  177973. + u32 max_width;
  177974. + int ret;
  177975. +
  177976. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
  177977. + return IPU_CHECK_ERR_SPLIT_WITH_ROT;
  177978. +
  177979. + iw = t->input.crop.w;
  177980. + ih = t->input.crop.h;
  177981. +
  177982. + ow = t->output.crop.w;
  177983. + oh = t->output.crop.h;
  177984. +
  177985. + memset(&left_stripe, 0, sizeof(left_stripe));
  177986. + memset(&right_stripe, 0, sizeof(right_stripe));
  177987. + memset(&up_stripe, 0, sizeof(up_stripe));
  177988. + memset(&down_stripe, 0, sizeof(down_stripe));
  177989. +
  177990. + if (t->set.split_mode & RL_SPLIT) {
  177991. + /*
  177992. + * We do want equal strips: initialize stripes in case
  177993. + * calc_stripes returns before actually doing the calculation
  177994. + */
  177995. + left_stripe.input_width = iw / 2;
  177996. + left_stripe.output_width = ow / 2;
  177997. + right_stripe.input_column = iw / 2;
  177998. + right_stripe.output_column = ow / 2;
  177999. +
  178000. + if (vdi_split)
  178001. + max_width = soc_max_vdi_in_width();
  178002. + else
  178003. + max_width = soc_max_out_width();
  178004. + ret = ipu_calc_stripes_sizes(iw,
  178005. + ow,
  178006. + max_width,
  178007. + (((unsigned long long)1) << 32), /* 32bit for fractional*/
  178008. + 1, /* equal stripes */
  178009. + t->input.format,
  178010. + t->output.format,
  178011. + &left_stripe,
  178012. + &right_stripe);
  178013. + if (ret < 0)
  178014. + return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  178015. + else if (ret)
  178016. + dev_dbg(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
  178017. + t->task_no, ret);
  178018. + t->set.sp_setting.iw = left_stripe.input_width;
  178019. + t->set.sp_setting.ow = left_stripe.output_width;
  178020. + t->set.sp_setting.outh_resize_ratio = left_stripe.irr;
  178021. + t->set.sp_setting.i_left_pos = left_stripe.input_column;
  178022. + t->set.sp_setting.o_left_pos = left_stripe.output_column;
  178023. + t->set.sp_setting.i_right_pos = right_stripe.input_column;
  178024. + t->set.sp_setting.o_right_pos = right_stripe.output_column;
  178025. + } else {
  178026. + t->set.sp_setting.iw = iw;
  178027. + t->set.sp_setting.ow = ow;
  178028. + t->set.sp_setting.outh_resize_ratio = 0;
  178029. + t->set.sp_setting.i_left_pos = 0;
  178030. + t->set.sp_setting.o_left_pos = 0;
  178031. + t->set.sp_setting.i_right_pos = 0;
  178032. + t->set.sp_setting.o_right_pos = 0;
  178033. + }
  178034. + if ((t->set.sp_setting.iw + t->set.sp_setting.i_right_pos) > (iw+16))
  178035. + return IPU_CHECK_ERR_SPLIT_INPUTW_OVER;
  178036. + if (((t->set.sp_setting.ow + t->set.sp_setting.o_right_pos) > ow)
  178037. + || (t->set.sp_setting.ow > soc_max_out_width()))
  178038. + return IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER;
  178039. + if (rounddown(t->set.sp_setting.ow, 8) * 8 <=
  178040. + rounddown(t->set.sp_setting.iw, 8))
  178041. + return IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  178042. +
  178043. + if (t->set.split_mode & UD_SPLIT) {
  178044. + /*
  178045. + * We do want equal strips: initialize stripes in case
  178046. + * calc_stripes returns before actually doing the calculation
  178047. + */
  178048. + up_stripe.input_width = ih / 2;
  178049. + up_stripe.output_width = oh / 2;
  178050. + down_stripe.input_column = ih / 2;
  178051. + down_stripe.output_column = oh / 2;
  178052. + ret = ipu_calc_stripes_sizes(ih,
  178053. + oh,
  178054. + soc_max_out_height(),
  178055. + (((unsigned long long)1) << 32), /* 32bit for fractional*/
  178056. + 0x1 | 0x2, /* equal stripes and vertical */
  178057. + t->input.format,
  178058. + t->output.format,
  178059. + &up_stripe,
  178060. + &down_stripe);
  178061. + if (ret < 0)
  178062. + return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  178063. + else if (ret)
  178064. + dev_err(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n",
  178065. + t->task_no, ret);
  178066. + t->set.sp_setting.ih = up_stripe.input_width;
  178067. + t->set.sp_setting.oh = up_stripe.output_width;
  178068. + t->set.sp_setting.outv_resize_ratio = up_stripe.irr;
  178069. + t->set.sp_setting.i_top_pos = up_stripe.input_column;
  178070. + t->set.sp_setting.o_top_pos = up_stripe.output_column;
  178071. + t->set.sp_setting.i_bottom_pos = down_stripe.input_column;
  178072. + t->set.sp_setting.o_bottom_pos = down_stripe.output_column;
  178073. + } else {
  178074. + t->set.sp_setting.ih = ih;
  178075. + t->set.sp_setting.oh = oh;
  178076. + t->set.sp_setting.outv_resize_ratio = 0;
  178077. + t->set.sp_setting.i_top_pos = 0;
  178078. + t->set.sp_setting.o_top_pos = 0;
  178079. + t->set.sp_setting.i_bottom_pos = 0;
  178080. + t->set.sp_setting.o_bottom_pos = 0;
  178081. + }
  178082. +
  178083. + /* downscale case: enforce limits */
  178084. + if (((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos) > (ih))
  178085. + && (t->set.sp_setting.ih >= t->set.sp_setting.oh))
  178086. + return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
  178087. + /* upscale case: relax limits because ipu_calc_stripes_sizes() may
  178088. + create input stripe that falls just outside of the input window */
  178089. + else if ((t->set.sp_setting.ih + t->set.sp_setting.i_bottom_pos)
  178090. + > (ih+16))
  178091. + return IPU_CHECK_ERR_SPLIT_INPUTH_OVER;
  178092. + if (((t->set.sp_setting.oh + t->set.sp_setting.o_bottom_pos) > oh)
  178093. + || (t->set.sp_setting.oh > soc_max_out_height()))
  178094. + return IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER;
  178095. + if (rounddown(t->set.sp_setting.oh, 8) * 8 <=
  178096. + rounddown(t->set.sp_setting.ih, 8))
  178097. + return IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  178098. +
  178099. + return IPU_CHECK_OK;
  178100. +}
  178101. +
  178102. +static int check_task(struct ipu_task_entry *t)
  178103. +{
  178104. + int tmp;
  178105. + int ret = IPU_CHECK_OK;
  178106. + int timeout;
  178107. + bool vdi_split = false;
  178108. + int ocw, och;
  178109. +
  178110. + if ((IPU_PIX_FMT_TILED_NV12 == t->overlay.format) ||
  178111. + (IPU_PIX_FMT_TILED_NV12F == t->overlay.format) ||
  178112. + (IPU_PIX_FMT_TILED_NV12 == t->output.format) ||
  178113. + (IPU_PIX_FMT_TILED_NV12F == t->output.format) ||
  178114. + ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
  178115. + !t->input.deinterlace.enable)) {
  178116. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  178117. + goto done;
  178118. + }
  178119. +
  178120. + /* check input */
  178121. + ret = set_crop(&t->input.crop, t->input.width, t->input.height,
  178122. + t->input.format);
  178123. + if (ret < 0) {
  178124. + ret = IPU_CHECK_ERR_INPUT_CROP;
  178125. + goto done;
  178126. + } else
  178127. + update_offset(t->input.format, t->input.width, t->input.height,
  178128. + t->input.crop.pos.x, t->input.crop.pos.y,
  178129. + &t->set.i_off, &t->set.i_uoff,
  178130. + &t->set.i_voff, &t->set.istride);
  178131. +
  178132. + /* check output */
  178133. + ret = set_crop(&t->output.crop, t->output.width, t->output.height,
  178134. + t->output.format);
  178135. + if (ret < 0) {
  178136. + ret = IPU_CHECK_ERR_OUTPUT_CROP;
  178137. + goto done;
  178138. + } else
  178139. + update_offset(t->output.format,
  178140. + t->output.width, t->output.height,
  178141. + t->output.crop.pos.x, t->output.crop.pos.y,
  178142. + &t->set.o_off, &t->set.o_uoff,
  178143. + &t->set.o_voff, &t->set.ostride);
  178144. +
  178145. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  178146. + /*
  178147. + * Cache output width and height and
  178148. + * swap them so that we may check
  178149. + * downsize overflow correctly.
  178150. + */
  178151. + ocw = t->output.crop.h;
  178152. + och = t->output.crop.w;
  178153. + } else {
  178154. + ocw = t->output.crop.w;
  178155. + och = t->output.crop.h;
  178156. + }
  178157. +
  178158. + if (ocw * 8 <= t->input.crop.w) {
  178159. + ret = IPU_CHECK_ERR_W_DOWNSIZE_OVER;
  178160. + goto done;
  178161. + }
  178162. +
  178163. + if (och * 8 <= t->input.crop.h) {
  178164. + ret = IPU_CHECK_ERR_H_DOWNSIZE_OVER;
  178165. + goto done;
  178166. + }
  178167. +
  178168. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  178169. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  178170. + if ((t->input.crop.w > soc_max_in_width(1)) ||
  178171. + (t->input.crop.h > soc_max_in_height())) {
  178172. + ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
  178173. + goto done;
  178174. + }
  178175. + /* output fmt: NV12 and YUYV, now don't support resize */
  178176. + if (((IPU_PIX_FMT_NV12 != t->output.format) &&
  178177. + (IPU_PIX_FMT_YUYV != t->output.format)) ||
  178178. + (t->input.crop.w != t->output.crop.w) ||
  178179. + (t->input.crop.h != t->output.crop.h)) {
  178180. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  178181. + goto done;
  178182. + }
  178183. + }
  178184. +
  178185. + /* check overlay if there is */
  178186. + if (t->overlay_en) {
  178187. + if (t->input.deinterlace.enable) {
  178188. + ret = IPU_CHECK_ERR_OVERLAY_WITH_VDI;
  178189. + goto done;
  178190. + }
  178191. +
  178192. + ret = set_crop(&t->overlay.crop, t->overlay.width,
  178193. + t->overlay.height, t->overlay.format);
  178194. + if (ret < 0) {
  178195. + ret = IPU_CHECK_ERR_OVERLAY_CROP;
  178196. + goto done;
  178197. + } else {
  178198. + ocw = t->output.crop.w;
  178199. + och = t->output.crop.h;
  178200. +
  178201. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  178202. + ocw = t->output.crop.h;
  178203. + och = t->output.crop.w;
  178204. + }
  178205. + if ((t->overlay.crop.w != ocw) ||
  178206. + (t->overlay.crop.h != och)) {
  178207. + ret = IPU_CHECK_ERR_OV_OUT_NO_FIT;
  178208. + goto done;
  178209. + }
  178210. +
  178211. + update_offset(t->overlay.format,
  178212. + t->overlay.width, t->overlay.height,
  178213. + t->overlay.crop.pos.x, t->overlay.crop.pos.y,
  178214. + &t->set.ov_off, &t->set.ov_uoff,
  178215. + &t->set.ov_voff, &t->set.ovstride);
  178216. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  178217. + t->set.ov_alpha_stride = t->overlay.width;
  178218. + t->set.ov_alpha_off = t->overlay.crop.pos.y *
  178219. + t->overlay.width + t->overlay.crop.pos.x;
  178220. + }
  178221. + }
  178222. + }
  178223. +
  178224. + /* input overflow? */
  178225. + if (!((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  178226. + (IPU_PIX_FMT_TILED_NV12F == t->input.format))) {
  178227. + if ((t->input.crop.w > soc_max_in_width(0)) ||
  178228. + (t->input.crop.h > soc_max_in_height())) {
  178229. + ret = IPU_CHECK_ERR_INPUT_OVER_LIMIT;
  178230. + goto done;
  178231. + }
  178232. + }
  178233. +
  178234. + /* check task mode */
  178235. + t->set.mode = NULL_MODE;
  178236. + t->set.split_mode = NO_SPLIT;
  178237. +
  178238. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  178239. + /*output swap*/
  178240. + tmp = t->output.crop.w;
  178241. + t->output.crop.w = t->output.crop.h;
  178242. + t->output.crop.h = tmp;
  178243. + }
  178244. +
  178245. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT)
  178246. + t->set.mode |= ROT_MODE;
  178247. +
  178248. + /*need resize or CSC?*/
  178249. + if ((t->input.crop.w != t->output.crop.w) ||
  178250. + (t->input.crop.h != t->output.crop.h) ||
  178251. + need_csc(t->input.format, t->output.format))
  178252. + t->set.mode |= IC_MODE;
  178253. +
  178254. + /*need flip?*/
  178255. + if ((t->set.mode == NULL_MODE) && (t->output.rotate > IPU_ROTATE_NONE))
  178256. + t->set.mode |= IC_MODE;
  178257. +
  178258. + /*need IDMAC do format(same color space)?*/
  178259. + if ((t->set.mode == NULL_MODE) && (t->input.format != t->output.format))
  178260. + t->set.mode |= IC_MODE;
  178261. +
  178262. + /*overlay support*/
  178263. + if (t->overlay_en)
  178264. + t->set.mode |= IC_MODE;
  178265. +
  178266. + /*deinterlace*/
  178267. + if (t->input.deinterlace.enable) {
  178268. + t->set.mode &= ~IC_MODE;
  178269. + t->set.mode |= VDI_MODE;
  178270. + }
  178271. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  178272. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  178273. + if (t->set.mode & ROT_MODE) {
  178274. + ret = IPU_CHECK_ERR_NOT_SUPPORT;
  178275. + goto done;
  178276. + }
  178277. + t->set.mode |= VDOA_MODE;
  178278. + if (IPU_PIX_FMT_TILED_NV12F == t->input.format)
  178279. + t->set.mode |= VDOA_BAND_MODE;
  178280. + t->set.mode &= ~IC_MODE;
  178281. + }
  178282. +
  178283. + if ((t->set.mode & (IC_MODE | VDI_MODE)) &&
  178284. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  178285. + if (t->output.crop.w > soc_max_out_width())
  178286. + t->set.split_mode |= RL_SPLIT;
  178287. + if (t->output.crop.h > soc_max_out_height())
  178288. + t->set.split_mode |= UD_SPLIT;
  178289. + if (!t->set.split_mode && (t->set.mode & VDI_MODE) &&
  178290. + (t->input.crop.w > soc_max_vdi_in_width())) {
  178291. + t->set.split_mode |= RL_SPLIT;
  178292. + vdi_split = true;
  178293. + }
  178294. + if (t->set.split_mode) {
  178295. + if ((t->set.split_mode == RL_SPLIT) ||
  178296. + (t->set.split_mode == UD_SPLIT))
  178297. + timeout = DEF_TIMEOUT_MS * 2 + DEF_DELAY_MS;
  178298. + else
  178299. + timeout = DEF_TIMEOUT_MS * 4 + DEF_DELAY_MS;
  178300. + if (t->timeout < timeout)
  178301. + t->timeout = timeout;
  178302. +
  178303. + ret = update_split_setting(t, vdi_split);
  178304. + if (ret > IPU_CHECK_ERR_MIN)
  178305. + goto done;
  178306. + }
  178307. + }
  178308. +
  178309. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  178310. + /*output swap*/
  178311. + tmp = t->output.crop.w;
  178312. + t->output.crop.w = t->output.crop.h;
  178313. + t->output.crop.h = tmp;
  178314. + }
  178315. +
  178316. + if (t->set.mode == NULL_MODE) {
  178317. + ret = IPU_CHECK_ERR_PROC_NO_NEED;
  178318. + goto done;
  178319. + }
  178320. +
  178321. + if ((t->set.i_uoff % 8) || (t->set.i_voff % 8))
  178322. + ret |= IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN;
  178323. + if ((t->set.o_uoff % 8) || (t->set.o_voff % 8))
  178324. + ret |= IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN;
  178325. + if (t->overlay_en && ((t->set.ov_uoff % 8) || (t->set.ov_voff % 8)))
  178326. + ret |= IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN;
  178327. +
  178328. +done:
  178329. + /* dump msg */
  178330. + if (debug) {
  178331. + if (ret > IPU_CHECK_ERR_MIN)
  178332. + dump_check_err(t->dev, ret);
  178333. + else if (ret != IPU_CHECK_OK)
  178334. + dump_check_warn(t->dev, ret);
  178335. + }
  178336. +
  178337. + return ret;
  178338. +}
  178339. +
  178340. +static int prepare_task(struct ipu_task_entry *t)
  178341. +{
  178342. + int ret = 0;
  178343. +
  178344. + ret = check_task(t);
  178345. + if (ret > IPU_CHECK_ERR_MIN)
  178346. + return -EINVAL;
  178347. +
  178348. + if (t->set.mode & VDI_MODE) {
  178349. + t->task_id = IPU_TASK_ID_VF;
  178350. + t->set.task = VDI_VF;
  178351. + if (t->set.mode & ROT_MODE)
  178352. + t->set.task |= ROT_VF;
  178353. + }
  178354. +
  178355. + if (VDOA_MODE == t->set.mode) {
  178356. + if (t->set.task != 0) {
  178357. + dev_err(t->dev, "ERR: vdoa only task:0x%x, [0x%p].\n",
  178358. + t->set.task, t);
  178359. + return -EINVAL;
  178360. + }
  178361. + t->set.task |= VDOA_ONLY;
  178362. + }
  178363. +
  178364. + if (VDOA_BAND_MODE & t->set.mode) {
  178365. + /* to save band size: 1<<3 = 8 lines */
  178366. + t->set.band_lines = 3;
  178367. + }
  178368. +
  178369. + dump_task_info(t);
  178370. +
  178371. + return ret;
  178372. +}
  178373. +
  178374. +static uint32_t ic_vf_pp_is_busy(struct ipu_soc *ipu, bool is_vf)
  178375. +{
  178376. + uint32_t status;
  178377. + uint32_t status_vf;
  178378. + uint32_t status_rot;
  178379. +
  178380. + if (is_vf) {
  178381. + status = ipu_channel_status(ipu, MEM_VDI_PRP_VF_MEM);
  178382. + status_vf = ipu_channel_status(ipu, MEM_PRP_VF_MEM);
  178383. + status_rot = ipu_channel_status(ipu, MEM_ROT_VF_MEM);
  178384. + return status || status_vf || status_rot;
  178385. + } else {
  178386. + status = ipu_channel_status(ipu, MEM_PP_MEM);
  178387. + status_rot = ipu_channel_status(ipu, MEM_ROT_PP_MEM);
  178388. + return status || status_rot;
  178389. + }
  178390. +}
  178391. +
  178392. +static int _get_vdoa_ipu_res(struct ipu_task_entry *t)
  178393. +{
  178394. + int i;
  178395. + struct ipu_soc *ipu;
  178396. + u8 *used;
  178397. + uint32_t found_ipu = 0;
  178398. + uint32_t found_vdoa = 0;
  178399. + struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
  178400. +
  178401. + mutex_lock(&tbl->lock);
  178402. + if (t->set.mode & VDOA_MODE) {
  178403. + if (NULL != t->vdoa_handle)
  178404. + found_vdoa = 1;
  178405. + else {
  178406. + found_vdoa = tbl->vdoa_used ? 0 : 1;
  178407. + if (found_vdoa) {
  178408. + tbl->vdoa_used = 1;
  178409. + vdoa_get_handle(&t->vdoa_handle);
  178410. + } else
  178411. + /* first get vdoa->ipu resource sequence */
  178412. + goto out;
  178413. + if (t->set.task & VDOA_ONLY)
  178414. + goto out;
  178415. + }
  178416. + }
  178417. +
  178418. + for (i = 0; i < max_ipu_no; i++) {
  178419. + ipu = ipu_get_soc(i);
  178420. + if (IS_ERR(ipu))
  178421. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
  178422. + t->task_no, found_vdoa, i);
  178423. +
  178424. + used = &tbl->used[i][IPU_PP_CH_VF];
  178425. + if (t->set.mode & VDI_MODE) {
  178426. + if (0 == *used) {
  178427. + *used = 1;
  178428. + found_ipu = 1;
  178429. + break;
  178430. + }
  178431. + } else if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
  178432. + if (0 == *used) {
  178433. + t->task_id = IPU_TASK_ID_VF;
  178434. + if (t->set.mode & IC_MODE)
  178435. + t->set.task |= IC_VF;
  178436. + if (t->set.mode & ROT_MODE)
  178437. + t->set.task |= ROT_VF;
  178438. + *used = 1;
  178439. + found_ipu = 1;
  178440. + break;
  178441. + }
  178442. + } else
  178443. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, mode:0x%x\n",
  178444. + t->task_no, found_vdoa, t->set.mode);
  178445. + }
  178446. + if (found_ipu)
  178447. + goto next;
  178448. +
  178449. + for (i = 0; i < max_ipu_no; i++) {
  178450. + ipu = ipu_get_soc(i);
  178451. + if (IS_ERR(ipu))
  178452. + dev_err(t->dev, "no:0x%x,found_vdoa:%d, ipu:%d\n",
  178453. + t->task_no, found_vdoa, i);
  178454. +
  178455. + if ((t->set.mode & IC_MODE) || only_rot(t->set.mode)) {
  178456. + used = &tbl->used[i][IPU_PP_CH_PP];
  178457. + if (0 == *used) {
  178458. + t->task_id = IPU_TASK_ID_PP;
  178459. + if (t->set.mode & IC_MODE)
  178460. + t->set.task |= IC_PP;
  178461. + if (t->set.mode & ROT_MODE)
  178462. + t->set.task |= ROT_PP;
  178463. + *used = 1;
  178464. + found_ipu = 1;
  178465. + break;
  178466. + }
  178467. + }
  178468. + }
  178469. +
  178470. +next:
  178471. + if (found_ipu) {
  178472. + t->ipu = ipu;
  178473. + t->ipu_id = i;
  178474. + t->dev = ipu->dev;
  178475. + if (atomic_inc_return(&t->res_get) == 2)
  178476. + dev_err(t->dev,
  178477. + "ERR no:0x%x,found_vdoa:%d,get ipu twice\n",
  178478. + t->task_no, found_vdoa);
  178479. + }
  178480. +out:
  178481. + dev_dbg(t->dev,
  178482. + "%s:no:0x%x,found_vdoa:%d, found_ipu:%d\n",
  178483. + __func__, t->task_no, found_vdoa, found_ipu);
  178484. + mutex_unlock(&tbl->lock);
  178485. + if (t->set.task & VDOA_ONLY)
  178486. + return found_vdoa;
  178487. + else if (t->set.mode & VDOA_MODE)
  178488. + return found_vdoa && found_ipu;
  178489. + else
  178490. + return found_ipu;
  178491. +}
  178492. +
  178493. +static void put_vdoa_ipu_res(struct ipu_task_entry *tsk, int vdoa_only)
  178494. +{
  178495. + int ret;
  178496. + int rel_vdoa = 0, rel_ipu = 0;
  178497. + struct ipu_channel_tabel *tbl = &ipu_ch_tbl;
  178498. +
  178499. + mutex_lock(&tbl->lock);
  178500. + if (tsk->set.mode & VDOA_MODE) {
  178501. + if (!tbl->vdoa_used && tsk->vdoa_handle)
  178502. + dev_err(tsk->dev,
  178503. + "ERR no:0x%x,vdoa not used,mode:0x%x\n",
  178504. + tsk->task_no, tsk->set.mode);
  178505. + if (tbl->vdoa_used && tsk->vdoa_handle) {
  178506. + tbl->vdoa_used = 0;
  178507. + vdoa_put_handle(&tsk->vdoa_handle);
  178508. + if (tsk->ipu)
  178509. + tsk->ipu->vdoa_en = 0;
  178510. + rel_vdoa = 1;
  178511. + if (vdoa_only || (tsk->set.task & VDOA_ONLY))
  178512. + goto out;
  178513. + }
  178514. + }
  178515. +
  178516. + tbl->used[tsk->ipu_id][tsk->task_id - 1] = 0;
  178517. + rel_ipu = 1;
  178518. + ret = atomic_inc_return(&tsk->res_free);
  178519. + if (ret == 2)
  178520. + dev_err(tsk->dev,
  178521. + "ERR no:0x%x,rel_vdoa:%d,put ipu twice\n",
  178522. + tsk->task_no, rel_vdoa);
  178523. +out:
  178524. + dev_dbg(tsk->dev,
  178525. + "%s:no:0x%x,rel_vdoa:%d, rel_ipu:%d\n",
  178526. + __func__, tsk->task_no, rel_vdoa, rel_ipu);
  178527. + mutex_unlock(&tbl->lock);
  178528. +}
  178529. +
  178530. +static int get_vdoa_ipu_res(struct ipu_task_entry *t)
  178531. +{
  178532. + int ret;
  178533. + uint32_t found = 0;
  178534. +
  178535. + found = _get_vdoa_ipu_res(t);
  178536. + if (!found) {
  178537. + t->ipu_id = -1;
  178538. + t->ipu = NULL;
  178539. + /* blocking to get resource */
  178540. + ret = atomic_inc_return(&req_cnt);
  178541. + dev_dbg(t->dev,
  178542. + "wait_res:no:0x%x,req_cnt:%d\n", t->task_no, ret);
  178543. + ret = wait_event_timeout(res_waitq, _get_vdoa_ipu_res(t),
  178544. + msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
  178545. + if (ret == 0) {
  178546. + dev_err(t->dev, "ERR[0x%p,no-0x%x] wait_res timeout:%dms!\n",
  178547. + t, t->task_no, t->timeout - DEF_DELAY_MS);
  178548. + ret = -ETIMEDOUT;
  178549. + t->state = STATE_RES_TIMEOUT;
  178550. + goto out;
  178551. + } else {
  178552. + if (!(t->set.task & VDOA_ONLY) && (!t->ipu))
  178553. + dev_err(t->dev,
  178554. + "ERR[no-0x%x] can not get ipu!\n",
  178555. + t->task_no);
  178556. + ret = atomic_read(&req_cnt);
  178557. + if (ret > 0)
  178558. + ret = atomic_dec_return(&req_cnt);
  178559. + else
  178560. + dev_err(t->dev,
  178561. + "ERR[no-0x%x] req_cnt:%d mismatch!\n",
  178562. + t->task_no, ret);
  178563. + dev_dbg(t->dev, "no-0x%x,[0x%p],req_cnt:%d, got_res!\n",
  178564. + t->task_no, t, ret);
  178565. + found = 1;
  178566. + }
  178567. + }
  178568. +
  178569. +out:
  178570. + return found;
  178571. +}
  178572. +
  178573. +static struct ipu_task_entry *create_task_entry(struct ipu_task *task)
  178574. +{
  178575. + struct ipu_task_entry *tsk;
  178576. +
  178577. + tsk = kzalloc(sizeof(struct ipu_task_entry), GFP_KERNEL);
  178578. + if (!tsk)
  178579. + return ERR_PTR(-ENOMEM);
  178580. + kref_init(&tsk->refcount);
  178581. + tsk->state = -EINVAL;
  178582. + tsk->ipu_id = -1;
  178583. + tsk->dev = ipu_dev;
  178584. + tsk->input = task->input;
  178585. + tsk->output = task->output;
  178586. + tsk->overlay_en = task->overlay_en;
  178587. + if (tsk->overlay_en)
  178588. + tsk->overlay = task->overlay;
  178589. + if (task->timeout > DEF_TIMEOUT_MS)
  178590. + tsk->timeout = task->timeout;
  178591. + else
  178592. + tsk->timeout = DEF_TIMEOUT_MS;
  178593. +
  178594. + return tsk;
  178595. +}
  178596. +
  178597. +static void task_mem_free(struct kref *ref)
  178598. +{
  178599. + struct ipu_task_entry *tsk =
  178600. + container_of(ref, struct ipu_task_entry, refcount);
  178601. + kfree(tsk);
  178602. +}
  178603. +
  178604. +int create_split_child_task(struct ipu_split_task *sp_task)
  178605. +{
  178606. + int ret = 0;
  178607. + struct ipu_task_entry *tsk;
  178608. +
  178609. + tsk = create_task_entry(&sp_task->task);
  178610. + if (IS_ERR(tsk))
  178611. + return PTR_ERR(tsk);
  178612. +
  178613. + sp_task->child_task = tsk;
  178614. + tsk->task_no = sp_task->task_no;
  178615. +
  178616. + ret = prepare_task(tsk);
  178617. + if (ret < 0)
  178618. + goto err;
  178619. +
  178620. + tsk->parent = sp_task->parent_task;
  178621. + tsk->set.sp_setting = sp_task->parent_task->set.sp_setting;
  178622. +
  178623. + list_add(&tsk->node, &tsk->parent->split_list);
  178624. + dev_dbg(tsk->dev, "[0x%p] sp_tsk Q list,no-0x%x\n", tsk, tsk->task_no);
  178625. + tsk->state = STATE_QUEUE;
  178626. + CHECK_PERF(&tsk->ts_queue);
  178627. +err:
  178628. + return ret;
  178629. +}
  178630. +
  178631. +static inline int sp_task_check_done(struct ipu_split_task *sp_task,
  178632. + struct ipu_task_entry *parent, int num, int *idx)
  178633. +{
  178634. + int i;
  178635. + int ret = 0;
  178636. + struct ipu_task_entry *tsk;
  178637. + struct mutex *lock = &parent->split_lock;
  178638. +
  178639. + *idx = -EINVAL;
  178640. + mutex_lock(lock);
  178641. + for (i = 0; i < num; i++) {
  178642. + tsk = sp_task[i].child_task;
  178643. + if (tsk && tsk->split_done) {
  178644. + *idx = i;
  178645. + ret = 1;
  178646. + goto out;
  178647. + }
  178648. + }
  178649. +
  178650. +out:
  178651. + mutex_unlock(lock);
  178652. + return ret;
  178653. +}
  178654. +
  178655. +static int create_split_task(
  178656. + int stripe,
  178657. + struct ipu_split_task *sp_task)
  178658. +{
  178659. + struct ipu_task *task = &(sp_task->task);
  178660. + struct ipu_task_entry *t = sp_task->parent_task;
  178661. + int ret;
  178662. +
  178663. + sp_task->task_no |= stripe;
  178664. +
  178665. + task->input = t->input;
  178666. + task->output = t->output;
  178667. + task->overlay_en = t->overlay_en;
  178668. + if (task->overlay_en)
  178669. + task->overlay = t->overlay;
  178670. + task->task_id = t->task_id;
  178671. + if ((t->set.split_mode == RL_SPLIT) ||
  178672. + (t->set.split_mode == UD_SPLIT))
  178673. + task->timeout = t->timeout / 2;
  178674. + else
  178675. + task->timeout = t->timeout / 4;
  178676. +
  178677. + task->input.crop.w = t->set.sp_setting.iw;
  178678. + task->input.crop.h = t->set.sp_setting.ih;
  178679. + if (task->overlay_en) {
  178680. + task->overlay.crop.w = t->set.sp_setting.ow;
  178681. + task->overlay.crop.h = t->set.sp_setting.oh;
  178682. + }
  178683. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  178684. + task->output.crop.w = t->set.sp_setting.oh;
  178685. + task->output.crop.h = t->set.sp_setting.ow;
  178686. + t->set.sp_setting.rl_split_line = t->set.sp_setting.o_bottom_pos;
  178687. + t->set.sp_setting.ud_split_line = t->set.sp_setting.o_right_pos;
  178688. +
  178689. + } else {
  178690. + task->output.crop.w = t->set.sp_setting.ow;
  178691. + task->output.crop.h = t->set.sp_setting.oh;
  178692. + t->set.sp_setting.rl_split_line = t->set.sp_setting.o_right_pos;
  178693. + t->set.sp_setting.ud_split_line = t->set.sp_setting.o_bottom_pos;
  178694. + }
  178695. +
  178696. + if (stripe & LEFT_STRIPE)
  178697. + task->input.crop.pos.x += t->set.sp_setting.i_left_pos;
  178698. + else if (stripe & RIGHT_STRIPE)
  178699. + task->input.crop.pos.x += t->set.sp_setting.i_right_pos;
  178700. + if (stripe & UP_STRIPE)
  178701. + task->input.crop.pos.y += t->set.sp_setting.i_top_pos;
  178702. + else if (stripe & DOWN_STRIPE)
  178703. + task->input.crop.pos.y += t->set.sp_setting.i_bottom_pos;
  178704. +
  178705. + if (task->overlay_en) {
  178706. + if (stripe & LEFT_STRIPE)
  178707. + task->overlay.crop.pos.x += t->set.sp_setting.o_left_pos;
  178708. + else if (stripe & RIGHT_STRIPE)
  178709. + task->overlay.crop.pos.x += t->set.sp_setting.o_right_pos;
  178710. + if (stripe & UP_STRIPE)
  178711. + task->overlay.crop.pos.y += t->set.sp_setting.o_top_pos;
  178712. + else if (stripe & DOWN_STRIPE)
  178713. + task->overlay.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  178714. + }
  178715. +
  178716. + switch (t->output.rotate) {
  178717. + case IPU_ROTATE_NONE:
  178718. + if (stripe & LEFT_STRIPE)
  178719. + task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
  178720. + else if (stripe & RIGHT_STRIPE)
  178721. + task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
  178722. + if (stripe & UP_STRIPE)
  178723. + task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
  178724. + else if (stripe & DOWN_STRIPE)
  178725. + task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  178726. + break;
  178727. + case IPU_ROTATE_VERT_FLIP:
  178728. + if (stripe & LEFT_STRIPE)
  178729. + task->output.crop.pos.x += t->set.sp_setting.o_left_pos;
  178730. + else if (stripe & RIGHT_STRIPE)
  178731. + task->output.crop.pos.x += t->set.sp_setting.o_right_pos;
  178732. + if (stripe & UP_STRIPE)
  178733. + task->output.crop.pos.y =
  178734. + t->output.crop.pos.y + t->output.crop.h
  178735. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  178736. + else if (stripe & DOWN_STRIPE)
  178737. + task->output.crop.pos.y =
  178738. + t->output.crop.pos.y + t->output.crop.h
  178739. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  178740. + break;
  178741. + case IPU_ROTATE_HORIZ_FLIP:
  178742. + if (stripe & LEFT_STRIPE)
  178743. + task->output.crop.pos.x =
  178744. + t->output.crop.pos.x + t->output.crop.w
  178745. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  178746. + else if (stripe & RIGHT_STRIPE)
  178747. + task->output.crop.pos.x =
  178748. + t->output.crop.pos.x + t->output.crop.w
  178749. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  178750. + if (stripe & UP_STRIPE)
  178751. + task->output.crop.pos.y += t->set.sp_setting.o_top_pos;
  178752. + else if (stripe & DOWN_STRIPE)
  178753. + task->output.crop.pos.y += t->set.sp_setting.o_bottom_pos;
  178754. + break;
  178755. + case IPU_ROTATE_180:
  178756. + if (stripe & LEFT_STRIPE)
  178757. + task->output.crop.pos.x =
  178758. + t->output.crop.pos.x + t->output.crop.w
  178759. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  178760. + else if (stripe & RIGHT_STRIPE)
  178761. + task->output.crop.pos.x =
  178762. + t->output.crop.pos.x + t->output.crop.w
  178763. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  178764. + if (stripe & UP_STRIPE)
  178765. + task->output.crop.pos.y =
  178766. + t->output.crop.pos.y + t->output.crop.h
  178767. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  178768. + else if (stripe & DOWN_STRIPE)
  178769. + task->output.crop.pos.y =
  178770. + t->output.crop.pos.y + t->output.crop.h
  178771. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  178772. + break;
  178773. + case IPU_ROTATE_90_RIGHT:
  178774. + if (stripe & UP_STRIPE)
  178775. + task->output.crop.pos.x =
  178776. + t->output.crop.pos.x + t->output.crop.w
  178777. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  178778. + else if (stripe & DOWN_STRIPE)
  178779. + task->output.crop.pos.x =
  178780. + t->output.crop.pos.x + t->output.crop.w
  178781. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  178782. + if (stripe & LEFT_STRIPE)
  178783. + task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
  178784. + else if (stripe & RIGHT_STRIPE)
  178785. + task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
  178786. + break;
  178787. + case IPU_ROTATE_90_RIGHT_HFLIP:
  178788. + if (stripe & UP_STRIPE)
  178789. + task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
  178790. + else if (stripe & DOWN_STRIPE)
  178791. + task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
  178792. + if (stripe & LEFT_STRIPE)
  178793. + task->output.crop.pos.y += t->set.sp_setting.o_left_pos;
  178794. + else if (stripe & RIGHT_STRIPE)
  178795. + task->output.crop.pos.y += t->set.sp_setting.o_right_pos;
  178796. + break;
  178797. + case IPU_ROTATE_90_RIGHT_VFLIP:
  178798. + if (stripe & UP_STRIPE)
  178799. + task->output.crop.pos.x =
  178800. + t->output.crop.pos.x + t->output.crop.w
  178801. + - t->set.sp_setting.o_top_pos - t->set.sp_setting.oh;
  178802. + else if (stripe & DOWN_STRIPE)
  178803. + task->output.crop.pos.x =
  178804. + t->output.crop.pos.x + t->output.crop.w
  178805. + - t->set.sp_setting.o_bottom_pos - t->set.sp_setting.oh;
  178806. + if (stripe & LEFT_STRIPE)
  178807. + task->output.crop.pos.y =
  178808. + t->output.crop.pos.y + t->output.crop.h
  178809. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  178810. + else if (stripe & RIGHT_STRIPE)
  178811. + task->output.crop.pos.y =
  178812. + t->output.crop.pos.y + t->output.crop.h
  178813. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  178814. + break;
  178815. + case IPU_ROTATE_90_LEFT:
  178816. + if (stripe & UP_STRIPE)
  178817. + task->output.crop.pos.x += t->set.sp_setting.o_top_pos;
  178818. + else if (stripe & DOWN_STRIPE)
  178819. + task->output.crop.pos.x += t->set.sp_setting.o_bottom_pos;
  178820. + if (stripe & LEFT_STRIPE)
  178821. + task->output.crop.pos.y =
  178822. + t->output.crop.pos.y + t->output.crop.h
  178823. + - t->set.sp_setting.o_left_pos - t->set.sp_setting.ow;
  178824. + else if (stripe & RIGHT_STRIPE)
  178825. + task->output.crop.pos.y =
  178826. + t->output.crop.pos.y + t->output.crop.h
  178827. + - t->set.sp_setting.o_right_pos - t->set.sp_setting.ow;
  178828. + break;
  178829. + default:
  178830. + dev_err(t->dev, "ERR:should not be here\n");
  178831. + break;
  178832. + }
  178833. +
  178834. + ret = create_split_child_task(sp_task);
  178835. + if (ret < 0)
  178836. + dev_err(t->dev, "ERR:create_split_child_task() ret:%d\n", ret);
  178837. + return ret;
  178838. +}
  178839. +
  178840. +static int queue_split_task(struct ipu_task_entry *t,
  178841. + struct ipu_split_task *sp_task, uint32_t size)
  178842. +{
  178843. + int err[4];
  178844. + int ret = 0;
  178845. + int i, j;
  178846. + struct ipu_task_entry *tsk = NULL;
  178847. + struct mutex *lock = &t->split_lock;
  178848. + struct mutex *vdic_lock = &t->vdic_lock;
  178849. +
  178850. + dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n",
  178851. + t, t->task_no, size);
  178852. + mutex_init(lock);
  178853. + mutex_init(vdic_lock);
  178854. + init_waitqueue_head(&t->split_waitq);
  178855. + INIT_LIST_HEAD(&t->split_list);
  178856. + for (j = 0; j < size; j++) {
  178857. + memset(&sp_task[j], 0, sizeof(*sp_task));
  178858. + sp_task[j].parent_task = t;
  178859. + sp_task[j].task_no = t->task_no;
  178860. + }
  178861. +
  178862. + if (t->set.split_mode == RL_SPLIT) {
  178863. + i = 0;
  178864. + err[i] = create_split_task(RIGHT_STRIPE, &sp_task[i]);
  178865. + if (err[i] < 0)
  178866. + goto err_start;
  178867. + i = 1;
  178868. + err[i] = create_split_task(LEFT_STRIPE, &sp_task[i]);
  178869. + } else if (t->set.split_mode == UD_SPLIT) {
  178870. + i = 0;
  178871. + err[i] = create_split_task(DOWN_STRIPE, &sp_task[i]);
  178872. + if (err[i] < 0)
  178873. + goto err_start;
  178874. + i = 1;
  178875. + err[i] = create_split_task(UP_STRIPE, &sp_task[i]);
  178876. + } else {
  178877. + i = 0;
  178878. + err[i] = create_split_task(RIGHT_STRIPE | DOWN_STRIPE, &sp_task[i]);
  178879. + if (err[i] < 0)
  178880. + goto err_start;
  178881. + i = 1;
  178882. + err[i] = create_split_task(LEFT_STRIPE | DOWN_STRIPE, &sp_task[i]);
  178883. + if (err[i] < 0)
  178884. + goto err_start;
  178885. + i = 2;
  178886. + err[i] = create_split_task(RIGHT_STRIPE | UP_STRIPE, &sp_task[i]);
  178887. + if (err[i] < 0)
  178888. + goto err_start;
  178889. + i = 3;
  178890. + err[i] = create_split_task(LEFT_STRIPE | UP_STRIPE, &sp_task[i]);
  178891. + }
  178892. +
  178893. +err_start:
  178894. + for (j = 0; j < (i + 1); j++) {
  178895. + if (err[j] < 0) {
  178896. + if (sp_task[j].child_task)
  178897. + dev_err(t->dev,
  178898. + "sp_task[%d],no-0x%x fail state:%d, queue err:%d.\n",
  178899. + j, sp_task[j].child_task->task_no,
  178900. + sp_task[j].child_task->state, err[j]);
  178901. + goto err_exit;
  178902. + }
  178903. + dev_dbg(t->dev, "[0x%p] sp_task[%d], no-0x%x state:%s, queue ret:%d.\n",
  178904. + sp_task[j].child_task, j, sp_task[j].child_task->task_no,
  178905. + state_msg[sp_task[j].child_task->state].msg, err[j]);
  178906. + }
  178907. +
  178908. + return ret;
  178909. +
  178910. +err_exit:
  178911. + for (j = 0; j < (i + 1); j++) {
  178912. + if (err[j] < 0 && !ret)
  178913. + ret = err[j];
  178914. + tsk = sp_task[j].child_task;
  178915. + if (!tsk)
  178916. + continue;
  178917. + kfree(tsk);
  178918. + }
  178919. + t->state = STATE_ERR;
  178920. + return ret;
  178921. +
  178922. +}
  178923. +
  178924. +static int init_tiled_buf(struct ipu_soc *ipu, struct ipu_task_entry *t,
  178925. + ipu_channel_t channel, uint32_t ch_type)
  178926. +{
  178927. + int ret = 0;
  178928. + int i;
  178929. + uint32_t ipu_fmt;
  178930. + dma_addr_t inbuf_base = 0;
  178931. + u32 field_size;
  178932. + struct vdoa_params param;
  178933. + struct vdoa_ipu_buf buf;
  178934. + struct ipu_soc *ipu_idx;
  178935. + u32 ipu_stride, obuf_size;
  178936. + u32 height, width;
  178937. + ipu_buffer_t type;
  178938. +
  178939. + if ((IPU_PIX_FMT_YUYV != t->output.format) &&
  178940. + (IPU_PIX_FMT_NV12 != t->output.format)) {
  178941. + dev_err(t->dev, "ERR:[0x%d] output format\n", t->task_no);
  178942. + return -EINVAL;
  178943. + }
  178944. +
  178945. + memset(&param, 0, sizeof(param));
  178946. + /* init channel tiled bufs */
  178947. + if (deinterlace_3_field(t) &&
  178948. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  178949. + field_size = tiled_filed_size(t);
  178950. + if (INPUT_CHAN_VDI_P == ch_type) {
  178951. + inbuf_base = t->input.paddr + field_size;
  178952. + param.vfield_buf.prev_veba = inbuf_base + t->set.i_off;
  178953. + } else if (INPUT_CHAN == ch_type) {
  178954. + inbuf_base = t->input.paddr_n;
  178955. + param.vfield_buf.cur_veba = inbuf_base + t->set.i_off;
  178956. + } else if (INPUT_CHAN_VDI_N == ch_type) {
  178957. + inbuf_base = t->input.paddr_n + field_size;
  178958. + param.vfield_buf.next_veba = inbuf_base + t->set.i_off;
  178959. + } else
  178960. + return -EINVAL;
  178961. + height = t->input.crop.h >> 1; /* field format for vdoa */
  178962. + width = t->input.crop.w;
  178963. + param.vfield_buf.vubo = t->set.i_uoff;
  178964. + param.interlaced = 1;
  178965. + param.scan_order = 1;
  178966. + type = IPU_INPUT_BUFFER;
  178967. + } else if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) &&
  178968. + (INPUT_CHAN == ch_type)) {
  178969. + height = t->input.crop.h;
  178970. + width = t->input.crop.w;
  178971. + param.vframe_buf.veba = t->input.paddr + t->set.i_off;
  178972. + param.vframe_buf.vubo = t->set.i_uoff;
  178973. + type = IPU_INPUT_BUFFER;
  178974. + } else
  178975. + return -EINVAL;
  178976. +
  178977. + param.band_mode = (t->set.mode & VDOA_BAND_MODE) ? 1 : 0;
  178978. + if (param.band_mode && (t->set.band_lines != 3) &&
  178979. + (t->set.band_lines != 4) && (t->set.band_lines != 5))
  178980. + return -EINVAL;
  178981. + else if (param.band_mode)
  178982. + param.band_lines = (1 << t->set.band_lines);
  178983. + for (i = 0; i < max_ipu_no; i++) {
  178984. + ipu_idx = ipu_get_soc(i);
  178985. + if (!IS_ERR(ipu_idx) && ipu_idx == ipu)
  178986. + break;
  178987. + }
  178988. + if (t->set.task & VDOA_ONLY)
  178989. + /* dummy, didn't need ipu res */
  178990. + i = 0;
  178991. + if (max_ipu_no == i) {
  178992. + dev_err(t->dev, "ERR:[0x%p] get ipu num\n", t);
  178993. + return -EINVAL;
  178994. + }
  178995. +
  178996. + param.ipu_num = i;
  178997. + param.vpu_stride = t->input.width;
  178998. + param.height = height;
  178999. + param.width = width;
  179000. + if (IPU_PIX_FMT_NV12 == t->output.format)
  179001. + param.pfs = VDOA_PFS_NV12;
  179002. + else
  179003. + param.pfs = VDOA_PFS_YUYV;
  179004. + ipu_fmt = (param.pfs == VDOA_PFS_YUYV) ? IPU_PIX_FMT_YUYV :
  179005. + IPU_PIX_FMT_NV12;
  179006. + ipu_stride = param.width * bytes_per_pixel(ipu_fmt);
  179007. + obuf_size = PAGE_ALIGN(param.width * param.height *
  179008. + fmt_to_bpp(ipu_fmt)/8);
  179009. + dev_dbg(t->dev, "band_mode:%d, band_lines:%d\n",
  179010. + param.band_mode, param.band_lines);
  179011. + if (!param.band_mode) {
  179012. + /* note: if only for tiled -> raster convert and
  179013. + no other post-processing, we don't need alloc buf
  179014. + and use output buffer directly.
  179015. + */
  179016. + if (t->set.task & VDOA_ONLY)
  179017. + param.ieba0 = t->output.paddr;
  179018. + else {
  179019. + dev_err(t->dev, "ERR:[0x%d] vdoa task\n", t->task_no);
  179020. + return -EINVAL;
  179021. + }
  179022. + } else {
  179023. + if (IPU_PIX_FMT_TILED_NV12F != t->input.format) {
  179024. + dev_err(t->dev, "ERR [0x%d] vdoa task\n", t->task_no);
  179025. + return -EINVAL;
  179026. + }
  179027. + }
  179028. + ret = vdoa_setup(t->vdoa_handle, &param);
  179029. + if (ret)
  179030. + goto done;
  179031. + vdoa_get_output_buf(t->vdoa_handle, &buf);
  179032. + if (t->set.task & VDOA_ONLY)
  179033. + goto done;
  179034. +
  179035. + ret = ipu_init_channel_buffer(ipu,
  179036. + channel,
  179037. + type,
  179038. + ipu_fmt,
  179039. + width,
  179040. + height,
  179041. + ipu_stride,
  179042. + IPU_ROTATE_NONE,
  179043. + buf.ieba0,
  179044. + buf.ieba1,
  179045. + 0,
  179046. + buf.iubo,
  179047. + 0);
  179048. + if (ret < 0) {
  179049. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179050. + goto done;
  179051. + }
  179052. +
  179053. + if (param.band_mode) {
  179054. + ret = ipu_set_channel_bandmode(ipu, channel,
  179055. + type, t->set.band_lines);
  179056. + if (ret < 0) {
  179057. + t->state = STATE_INIT_CHAN_BAND_FAIL;
  179058. + goto done;
  179059. + }
  179060. + }
  179061. +done:
  179062. + return ret;
  179063. +}
  179064. +
  179065. +static int init_tiled_ch_bufs(struct ipu_soc *ipu, struct ipu_task_entry *t)
  179066. +{
  179067. + int ret = 0;
  179068. +
  179069. + if (IPU_PIX_FMT_TILED_NV12 == t->input.format) {
  179070. + ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
  179071. + CHECK_RETCODE(ret < 0, "init tiled_ch", t->state, done, ret);
  179072. + } else if (IPU_PIX_FMT_TILED_NV12F == t->input.format) {
  179073. + ret = init_tiled_buf(ipu, t, t->set.ic_chan, INPUT_CHAN);
  179074. + CHECK_RETCODE(ret < 0, "init tiled_ch-c", t->state, done, ret);
  179075. + ret = init_tiled_buf(ipu, t, t->set.vdi_ic_p_chan,
  179076. + INPUT_CHAN_VDI_P);
  179077. + CHECK_RETCODE(ret < 0, "init tiled_ch-p", t->state, done, ret);
  179078. + ret = init_tiled_buf(ipu, t, t->set.vdi_ic_n_chan,
  179079. + INPUT_CHAN_VDI_N);
  179080. + CHECK_RETCODE(ret < 0, "init tiled_ch-n", t->state, done, ret);
  179081. + } else {
  179082. + ret = -EINVAL;
  179083. + dev_err(t->dev, "ERR[no-0x%x] invalid fmt:0x%x!\n",
  179084. + t->task_no, t->input.format);
  179085. + }
  179086. +
  179087. +done:
  179088. + return ret;
  179089. +}
  179090. +
  179091. +static int init_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
  179092. +{
  179093. + int ret = 0;
  179094. + ipu_channel_params_t params;
  179095. + dma_addr_t inbuf = 0, ovbuf = 0, ov_alp_buf = 0;
  179096. + dma_addr_t inbuf_p = 0, inbuf_n = 0;
  179097. + dma_addr_t outbuf = 0;
  179098. + int out_uoff = 0, out_voff = 0, out_rot;
  179099. + int out_w = 0, out_h = 0, out_stride;
  179100. + int out_fmt;
  179101. + u32 vdi_frame_idx = 0;
  179102. +
  179103. + memset(&params, 0, sizeof(params));
  179104. +
  179105. + /* is it need link a rot channel */
  179106. + if (ic_and_rot(t->set.mode)) {
  179107. + outbuf = t->set.r_paddr;
  179108. + out_w = t->set.r_width;
  179109. + out_h = t->set.r_height;
  179110. + out_stride = t->set.r_stride;
  179111. + out_fmt = t->set.r_fmt;
  179112. + out_uoff = 0;
  179113. + out_voff = 0;
  179114. + out_rot = IPU_ROTATE_NONE;
  179115. + } else {
  179116. + outbuf = t->output.paddr + t->set.o_off;
  179117. + out_w = t->output.crop.w;
  179118. + out_h = t->output.crop.h;
  179119. + out_stride = t->set.ostride;
  179120. + out_fmt = t->output.format;
  179121. + out_uoff = t->set.o_uoff;
  179122. + out_voff = t->set.o_voff;
  179123. + out_rot = t->output.rotate;
  179124. + }
  179125. +
  179126. + /* settings */
  179127. + params.mem_prp_vf_mem.in_width = t->input.crop.w;
  179128. + params.mem_prp_vf_mem.out_width = out_w;
  179129. + params.mem_prp_vf_mem.in_height = t->input.crop.h;
  179130. + params.mem_prp_vf_mem.out_height = out_h;
  179131. + params.mem_prp_vf_mem.in_pixel_fmt = t->input.format;
  179132. + params.mem_prp_vf_mem.out_pixel_fmt = out_fmt;
  179133. + params.mem_prp_vf_mem.motion_sel = t->input.deinterlace.motion;
  179134. +
  179135. + params.mem_prp_vf_mem.outh_resize_ratio =
  179136. + t->set.sp_setting.outh_resize_ratio;
  179137. + params.mem_prp_vf_mem.outv_resize_ratio =
  179138. + t->set.sp_setting.outv_resize_ratio;
  179139. +
  179140. + if (t->overlay_en) {
  179141. + params.mem_prp_vf_mem.in_g_pixel_fmt = t->overlay.format;
  179142. + params.mem_prp_vf_mem.graphics_combine_en = 1;
  179143. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_GLOBAL)
  179144. + params.mem_prp_vf_mem.global_alpha_en = 1;
  179145. + else if (t->overlay.alpha.loc_alp_paddr)
  179146. + params.mem_prp_vf_mem.alpha_chan_en = 1;
  179147. + /* otherwise, alpha bending per pixel is used. */
  179148. + params.mem_prp_vf_mem.alpha = t->overlay.alpha.gvalue;
  179149. + if (t->overlay.colorkey.enable) {
  179150. + params.mem_prp_vf_mem.key_color_en = 1;
  179151. + params.mem_prp_vf_mem.key_color = t->overlay.colorkey.value;
  179152. + }
  179153. + }
  179154. +
  179155. + if (t->input.deinterlace.enable) {
  179156. + if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_FIELD_MASK)
  179157. + params.mem_prp_vf_mem.field_fmt =
  179158. + IPU_DEINTERLACE_FIELD_BOTTOM;
  179159. + else
  179160. + params.mem_prp_vf_mem.field_fmt =
  179161. + IPU_DEINTERLACE_FIELD_TOP;
  179162. +
  179163. + if (t->input.deinterlace.field_fmt & IPU_DEINTERLACE_RATE_EN)
  179164. + vdi_frame_idx = t->input.deinterlace.field_fmt &
  179165. + IPU_DEINTERLACE_RATE_FRAME1;
  179166. + }
  179167. +
  179168. + if (t->set.mode & VDOA_MODE)
  179169. + ipu->vdoa_en = 1;
  179170. +
  179171. + /* init channels */
  179172. + if (!(t->set.task & VDOA_ONLY)) {
  179173. + ret = ipu_init_channel(ipu, t->set.ic_chan, &params);
  179174. + if (ret < 0) {
  179175. + t->state = STATE_INIT_CHAN_FAIL;
  179176. + goto done;
  179177. + }
  179178. + }
  179179. +
  179180. + if (deinterlace_3_field(t)) {
  179181. + ret = ipu_init_channel(ipu, t->set.vdi_ic_p_chan, &params);
  179182. + if (ret < 0) {
  179183. + t->state = STATE_INIT_CHAN_FAIL;
  179184. + goto done;
  179185. + }
  179186. + ret = ipu_init_channel(ipu, t->set.vdi_ic_n_chan, &params);
  179187. + if (ret < 0) {
  179188. + t->state = STATE_INIT_CHAN_FAIL;
  179189. + goto done;
  179190. + }
  179191. + }
  179192. +
  179193. + /* init channel bufs */
  179194. + if ((IPU_PIX_FMT_TILED_NV12 == t->input.format) ||
  179195. + (IPU_PIX_FMT_TILED_NV12F == t->input.format)) {
  179196. + ret = init_tiled_ch_bufs(ipu, t);
  179197. + if (ret < 0)
  179198. + goto done;
  179199. + } else {
  179200. + if ((deinterlace_3_field(t)) &&
  179201. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  179202. + if (params.mem_prp_vf_mem.field_fmt ==
  179203. + IPU_DEINTERLACE_FIELD_TOP) {
  179204. + if (vdi_frame_idx) {
  179205. + inbuf_p = t->input.paddr + t->set.istride +
  179206. + t->set.i_off;
  179207. + inbuf = t->input.paddr_n + t->set.i_off;
  179208. + inbuf_n = t->input.paddr_n + t->set.istride +
  179209. + t->set.i_off;
  179210. + params.mem_prp_vf_mem.field_fmt =
  179211. + IPU_DEINTERLACE_FIELD_BOTTOM;
  179212. + } else {
  179213. + inbuf_p = t->input.paddr + t->set.i_off;
  179214. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  179215. + inbuf_n = t->input.paddr_n + t->set.i_off;
  179216. + }
  179217. + } else {
  179218. + if (vdi_frame_idx) {
  179219. + inbuf_p = t->input.paddr + t->set.i_off;
  179220. + inbuf = t->input.paddr_n + t->set.istride + t->set.i_off;
  179221. + inbuf_n = t->input.paddr_n + t->set.i_off;
  179222. + params.mem_prp_vf_mem.field_fmt =
  179223. + IPU_DEINTERLACE_FIELD_TOP;
  179224. + } else {
  179225. + inbuf_p = t->input.paddr + t->set.istride +
  179226. + t->set.i_off;
  179227. + inbuf = t->input.paddr + t->set.i_off;
  179228. + inbuf_n = t->input.paddr_n + t->set.istride +
  179229. + t->set.i_off;
  179230. + }
  179231. + }
  179232. + } else {
  179233. + if (t->input.deinterlace.enable) {
  179234. + if (params.mem_prp_vf_mem.field_fmt ==
  179235. + IPU_DEINTERLACE_FIELD_TOP) {
  179236. + if (vdi_frame_idx) {
  179237. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  179238. + params.mem_prp_vf_mem.field_fmt =
  179239. + IPU_DEINTERLACE_FIELD_BOTTOM;
  179240. + } else
  179241. + inbuf = t->input.paddr + t->set.i_off;
  179242. + } else {
  179243. + if (vdi_frame_idx) {
  179244. + inbuf = t->input.paddr + t->set.i_off;
  179245. + params.mem_prp_vf_mem.field_fmt =
  179246. + IPU_DEINTERLACE_FIELD_TOP;
  179247. + } else
  179248. + inbuf = t->input.paddr + t->set.istride + t->set.i_off;
  179249. + }
  179250. + } else
  179251. + inbuf = t->input.paddr + t->set.i_off;
  179252. + }
  179253. +
  179254. + if (t->overlay_en)
  179255. + ovbuf = t->overlay.paddr + t->set.ov_off;
  179256. + }
  179257. + if (t->overlay_en && (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL))
  179258. + ov_alp_buf = t->overlay.alpha.loc_alp_paddr
  179259. + + t->set.ov_alpha_off;
  179260. +
  179261. + if ((IPU_PIX_FMT_TILED_NV12 != t->input.format) &&
  179262. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  179263. + ret = ipu_init_channel_buffer(ipu,
  179264. + t->set.ic_chan,
  179265. + IPU_INPUT_BUFFER,
  179266. + t->input.format,
  179267. + t->input.crop.w,
  179268. + t->input.crop.h,
  179269. + t->set.istride,
  179270. + IPU_ROTATE_NONE,
  179271. + inbuf,
  179272. + 0,
  179273. + 0,
  179274. + t->set.i_uoff,
  179275. + t->set.i_voff);
  179276. + if (ret < 0) {
  179277. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179278. + goto done;
  179279. + }
  179280. + }
  179281. + if (deinterlace_3_field(t) &&
  179282. + (IPU_PIX_FMT_TILED_NV12F != t->input.format)) {
  179283. + ret = ipu_init_channel_buffer(ipu,
  179284. + t->set.vdi_ic_p_chan,
  179285. + IPU_INPUT_BUFFER,
  179286. + t->input.format,
  179287. + t->input.crop.w,
  179288. + t->input.crop.h,
  179289. + t->set.istride,
  179290. + IPU_ROTATE_NONE,
  179291. + inbuf_p,
  179292. + 0,
  179293. + 0,
  179294. + t->set.i_uoff,
  179295. + t->set.i_voff);
  179296. + if (ret < 0) {
  179297. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179298. + goto done;
  179299. + }
  179300. +
  179301. + ret = ipu_init_channel_buffer(ipu,
  179302. + t->set.vdi_ic_n_chan,
  179303. + IPU_INPUT_BUFFER,
  179304. + t->input.format,
  179305. + t->input.crop.w,
  179306. + t->input.crop.h,
  179307. + t->set.istride,
  179308. + IPU_ROTATE_NONE,
  179309. + inbuf_n,
  179310. + 0,
  179311. + 0,
  179312. + t->set.i_uoff,
  179313. + t->set.i_voff);
  179314. + if (ret < 0) {
  179315. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179316. + goto done;
  179317. + }
  179318. + }
  179319. +
  179320. + if (t->overlay_en) {
  179321. + ret = ipu_init_channel_buffer(ipu,
  179322. + t->set.ic_chan,
  179323. + IPU_GRAPH_IN_BUFFER,
  179324. + t->overlay.format,
  179325. + t->overlay.crop.w,
  179326. + t->overlay.crop.h,
  179327. + t->set.ovstride,
  179328. + IPU_ROTATE_NONE,
  179329. + ovbuf,
  179330. + 0,
  179331. + 0,
  179332. + t->set.ov_uoff,
  179333. + t->set.ov_voff);
  179334. + if (ret < 0) {
  179335. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179336. + goto done;
  179337. + }
  179338. + }
  179339. +
  179340. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  179341. + ret = ipu_init_channel_buffer(ipu,
  179342. + t->set.ic_chan,
  179343. + IPU_ALPHA_IN_BUFFER,
  179344. + IPU_PIX_FMT_GENERIC,
  179345. + t->overlay.crop.w,
  179346. + t->overlay.crop.h,
  179347. + t->set.ov_alpha_stride,
  179348. + IPU_ROTATE_NONE,
  179349. + ov_alp_buf,
  179350. + 0,
  179351. + 0,
  179352. + 0, 0);
  179353. + if (ret < 0) {
  179354. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179355. + goto done;
  179356. + }
  179357. + }
  179358. +
  179359. + if (!(t->set.task & VDOA_ONLY)) {
  179360. + ret = ipu_init_channel_buffer(ipu,
  179361. + t->set.ic_chan,
  179362. + IPU_OUTPUT_BUFFER,
  179363. + out_fmt,
  179364. + out_w,
  179365. + out_h,
  179366. + out_stride,
  179367. + out_rot,
  179368. + outbuf,
  179369. + 0,
  179370. + 0,
  179371. + out_uoff,
  179372. + out_voff);
  179373. + if (ret < 0) {
  179374. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179375. + goto done;
  179376. + }
  179377. + }
  179378. +
  179379. + if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
  179380. + ret = ipu_link_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
  179381. + CHECK_RETCODE(ret < 0, "ipu_link_ch vdoa_ic",
  179382. + STATE_LINK_CHAN_FAIL, done, ret);
  179383. + }
  179384. +
  179385. +done:
  179386. + return ret;
  179387. +}
  179388. +
  179389. +static void uninit_ic(struct ipu_soc *ipu, struct ipu_task_entry *t)
  179390. +{
  179391. + int ret;
  179392. +
  179393. + if ((t->set.mode & VDOA_BAND_MODE) && (t->set.task & VDI_VF)) {
  179394. + ret = ipu_unlink_channels(ipu, MEM_VDOA_MEM, t->set.ic_chan);
  179395. + CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch vdoa_ic",
  179396. + STATE_UNLINK_CHAN_FAIL, ret);
  179397. + }
  179398. + ipu_uninit_channel(ipu, t->set.ic_chan);
  179399. + if (deinterlace_3_field(t)) {
  179400. + ipu_uninit_channel(ipu, t->set.vdi_ic_p_chan);
  179401. + ipu_uninit_channel(ipu, t->set.vdi_ic_n_chan);
  179402. + }
  179403. +}
  179404. +
  179405. +static int init_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
  179406. +{
  179407. + int ret = 0;
  179408. + dma_addr_t inbuf = 0, outbuf = 0;
  179409. + int in_uoff = 0, in_voff = 0;
  179410. + int in_fmt, in_width, in_height, in_stride;
  179411. +
  179412. + /* init channel */
  179413. + ret = ipu_init_channel(ipu, t->set.rot_chan, NULL);
  179414. + if (ret < 0) {
  179415. + t->state = STATE_INIT_CHAN_FAIL;
  179416. + goto done;
  179417. + }
  179418. +
  179419. + /* init channel buf */
  179420. + /* is it need link to a ic channel */
  179421. + if (ic_and_rot(t->set.mode)) {
  179422. + in_fmt = t->set.r_fmt;
  179423. + in_width = t->set.r_width;
  179424. + in_height = t->set.r_height;
  179425. + in_stride = t->set.r_stride;
  179426. + inbuf = t->set.r_paddr;
  179427. + in_uoff = 0;
  179428. + in_voff = 0;
  179429. + } else {
  179430. + in_fmt = t->input.format;
  179431. + in_width = t->input.crop.w;
  179432. + in_height = t->input.crop.h;
  179433. + in_stride = t->set.istride;
  179434. + inbuf = t->input.paddr + t->set.i_off;
  179435. + in_uoff = t->set.i_uoff;
  179436. + in_voff = t->set.i_voff;
  179437. + }
  179438. + outbuf = t->output.paddr + t->set.o_off;
  179439. +
  179440. + ret = ipu_init_channel_buffer(ipu,
  179441. + t->set.rot_chan,
  179442. + IPU_INPUT_BUFFER,
  179443. + in_fmt,
  179444. + in_width,
  179445. + in_height,
  179446. + in_stride,
  179447. + t->output.rotate,
  179448. + inbuf,
  179449. + 0,
  179450. + 0,
  179451. + in_uoff,
  179452. + in_voff);
  179453. + if (ret < 0) {
  179454. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179455. + goto done;
  179456. + }
  179457. +
  179458. + ret = ipu_init_channel_buffer(ipu,
  179459. + t->set.rot_chan,
  179460. + IPU_OUTPUT_BUFFER,
  179461. + t->output.format,
  179462. + t->output.crop.w,
  179463. + t->output.crop.h,
  179464. + t->set.ostride,
  179465. + IPU_ROTATE_NONE,
  179466. + outbuf,
  179467. + 0,
  179468. + 0,
  179469. + t->set.o_uoff,
  179470. + t->set.o_voff);
  179471. + if (ret < 0) {
  179472. + t->state = STATE_INIT_CHAN_BUF_FAIL;
  179473. + goto done;
  179474. + }
  179475. +
  179476. +done:
  179477. + return ret;
  179478. +}
  179479. +
  179480. +static void uninit_rot(struct ipu_soc *ipu, struct ipu_task_entry *t)
  179481. +{
  179482. + ipu_uninit_channel(ipu, t->set.rot_chan);
  179483. +}
  179484. +
  179485. +static int get_irq(struct ipu_task_entry *t)
  179486. +{
  179487. + int irq;
  179488. + ipu_channel_t chan;
  179489. +
  179490. + if (only_ic(t->set.mode))
  179491. + chan = t->set.ic_chan;
  179492. + else
  179493. + chan = t->set.rot_chan;
  179494. +
  179495. + switch (chan) {
  179496. + case MEM_ROT_VF_MEM:
  179497. + irq = IPU_IRQ_PRP_VF_ROT_OUT_EOF;
  179498. + break;
  179499. + case MEM_ROT_PP_MEM:
  179500. + irq = IPU_IRQ_PP_ROT_OUT_EOF;
  179501. + break;
  179502. + case MEM_VDI_PRP_VF_MEM:
  179503. + case MEM_PRP_VF_MEM:
  179504. + irq = IPU_IRQ_PRP_VF_OUT_EOF;
  179505. + break;
  179506. + case MEM_PP_MEM:
  179507. + irq = IPU_IRQ_PP_OUT_EOF;
  179508. + break;
  179509. + case MEM_VDI_MEM:
  179510. + irq = IPU_IRQ_VDIC_OUT_EOF;
  179511. + break;
  179512. + default:
  179513. + irq = -EINVAL;
  179514. + }
  179515. +
  179516. + return irq;
  179517. +}
  179518. +
  179519. +static irqreturn_t task_irq_handler(int irq, void *dev_id)
  179520. +{
  179521. + struct ipu_task_entry *prev_tsk = dev_id;
  179522. +
  179523. + CHECK_PERF(&prev_tsk->ts_inirq);
  179524. + complete(&prev_tsk->irq_comp);
  179525. + dev_dbg(prev_tsk->dev, "[0x%p] no-0x%x in-irq!",
  179526. + prev_tsk, prev_tsk->task_no);
  179527. +
  179528. + return IRQ_HANDLED;
  179529. +}
  179530. +
  179531. +/* Fix deinterlace up&down split mode medium line */
  179532. +static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
  179533. +{
  179534. + u32 vdi_size;
  179535. + u32 vdi_save_lines;
  179536. + u32 stripe_mode;
  179537. + u32 task_no;
  179538. + u32 i, offset_addr;
  179539. + u32 line_size;
  179540. + unsigned char *base_off;
  179541. + struct ipu_task_entry *parent = t->parent;
  179542. + struct mutex *lock = &parent->vdic_lock;
  179543. +
  179544. + if (!parent) {
  179545. + dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no);
  179546. + return;
  179547. + }
  179548. + mutex_lock(lock);
  179549. + stripe_mode = t->task_no & 0xf;
  179550. + task_no = t->task_no >> 4;
  179551. +
  179552. + /* Save both luma and chroma part for interleaved YUV(e.g. YUYV).
  179553. + * Save luma part for non-interleaved and partial-interleaved
  179554. + * YUV format (e.g NV12 and YV12). */
  179555. + if (t->output.format == IPU_PIX_FMT_YUYV ||
  179556. + t->output.format == IPU_PIX_FMT_UYVY)
  179557. + line_size = t->output.crop.w * fmt_to_bpp(t->output.format)/8;
  179558. + else
  179559. + line_size = t->output.crop.w;
  179560. +
  179561. + vdi_save_lines = (t->output.crop.h - t->set.sp_setting.ud_split_line)/2;
  179562. + vdi_size = vdi_save_lines * line_size;
  179563. + if (vdi_save_lines <= 0) {
  179564. + dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t);
  179565. + mutex_unlock(lock);
  179566. + return;
  179567. + }
  179568. +
  179569. + /*check vditmpbuf buffer have alloced or buffer size is changed */
  179570. + if ((vdi_save_lines != parent->old_save_lines) ||
  179571. + (vdi_size != parent->old_size)) {
  179572. + if (parent->vditmpbuf[0] != NULL)
  179573. + kfree(parent->vditmpbuf[0]);
  179574. + if (parent->vditmpbuf[1] != NULL)
  179575. + kfree(parent->vditmpbuf[1]);
  179576. +
  179577. + parent->vditmpbuf[0] = kmalloc(vdi_size, GFP_KERNEL);
  179578. + if (parent->vditmpbuf[0] == NULL) {
  179579. + dev_err(t->dev,
  179580. + "[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t);
  179581. + mutex_unlock(lock);
  179582. + return;
  179583. + }
  179584. + memset(parent->vditmpbuf[0], 0, vdi_size);
  179585. +
  179586. + parent->vditmpbuf[1] = kmalloc(vdi_size, GFP_KERNEL);
  179587. + if (parent->vditmpbuf[1] == NULL) {
  179588. + dev_err(t->dev,
  179589. + "[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t);
  179590. + mutex_unlock(lock);
  179591. + return;
  179592. + }
  179593. + memset(parent->vditmpbuf[1], 0, vdi_size);
  179594. +
  179595. + parent->old_save_lines = vdi_save_lines;
  179596. + parent->old_size = vdi_size;
  179597. + }
  179598. +
  179599. + if (pfn_valid(t->output.paddr >> PAGE_SHIFT)) {
  179600. + base_off = page_address(pfn_to_page(t->output.paddr >> PAGE_SHIFT));
  179601. + base_off += t->output.paddr & ((1 << PAGE_SHIFT) - 1);
  179602. + } else {
  179603. + base_off = (char *)ioremap_nocache(t->output.paddr,
  179604. + t->output.width * t->output.height *
  179605. + fmt_to_bpp(t->output.format)/8);
  179606. + }
  179607. + if (base_off == NULL) {
  179608. + dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t);
  179609. + mutex_unlock(lock);
  179610. + return;
  179611. + }
  179612. +
  179613. + /* UP stripe or UP&LEFT stripe */
  179614. + if ((stripe_mode == UP_STRIPE) ||
  179615. + (stripe_mode == (UP_STRIPE | LEFT_STRIPE))) {
  179616. + if (!parent->buf0filled) {
  179617. + offset_addr = t->set.o_off +
  179618. + t->set.sp_setting.ud_split_line*t->set.ostride;
  179619. + dmac_flush_range(base_off + offset_addr,
  179620. + base_off + offset_addr + vdi_size);
  179621. + outer_flush_range(t->output.paddr + offset_addr,
  179622. + t->output.paddr + offset_addr + vdi_size);
  179623. +
  179624. + for (i = 0; i < vdi_save_lines; i++)
  179625. + memcpy(parent->vditmpbuf[0] + i*line_size,
  179626. + base_off + offset_addr +
  179627. + i*t->set.ostride, line_size);
  179628. + parent->buf0filled = true;
  179629. + } else {
  179630. + offset_addr = t->set.o_off + (t->output.crop.h -
  179631. + vdi_save_lines) * t->set.ostride;
  179632. + for (i = 0; i < vdi_save_lines; i++)
  179633. + memcpy(base_off + offset_addr + i*t->set.ostride,
  179634. + parent->vditmpbuf[0] + i*line_size, line_size);
  179635. +
  179636. + dmac_flush_range(base_off + offset_addr,
  179637. + base_off + offset_addr + i*t->set.ostride);
  179638. + outer_flush_range(t->output.paddr + offset_addr,
  179639. + t->output.paddr + offset_addr + i*t->set.ostride);
  179640. + parent->buf0filled = false;
  179641. + }
  179642. + }
  179643. + /*Down stripe or Down&Left stripe*/
  179644. + else if ((stripe_mode == DOWN_STRIPE) ||
  179645. + (stripe_mode == (DOWN_STRIPE | LEFT_STRIPE))) {
  179646. + if (!parent->buf0filled) {
  179647. + offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
  179648. + dmac_flush_range(base_off + offset_addr,
  179649. + base_off + offset_addr + vdi_size);
  179650. + outer_flush_range(t->output.paddr + offset_addr,
  179651. + t->output.paddr + offset_addr + vdi_size);
  179652. +
  179653. + for (i = 0; i < vdi_save_lines; i++)
  179654. + memcpy(parent->vditmpbuf[0] + i*line_size,
  179655. + base_off + offset_addr + i*t->set.ostride,
  179656. + line_size);
  179657. + parent->buf0filled = true;
  179658. + } else {
  179659. + offset_addr = t->set.o_off;
  179660. + for (i = 0; i < vdi_save_lines; i++)
  179661. + memcpy(base_off + offset_addr + i*t->set.ostride,
  179662. + parent->vditmpbuf[0] + i*line_size,
  179663. + line_size);
  179664. +
  179665. + dmac_flush_range(base_off + offset_addr,
  179666. + base_off + offset_addr + i*t->set.ostride);
  179667. + outer_flush_range(t->output.paddr + offset_addr,
  179668. + t->output.paddr + offset_addr + i*t->set.ostride);
  179669. + parent->buf0filled = false;
  179670. + }
  179671. + }
  179672. + /*Up&Right stripe*/
  179673. + else if (stripe_mode == (UP_STRIPE | RIGHT_STRIPE)) {
  179674. + if (!parent->buf1filled) {
  179675. + offset_addr = t->set.o_off +
  179676. + t->set.sp_setting.ud_split_line*t->set.ostride;
  179677. + dmac_flush_range(base_off + offset_addr,
  179678. + base_off + offset_addr + vdi_size);
  179679. + outer_flush_range(t->output.paddr + offset_addr,
  179680. + t->output.paddr + offset_addr + vdi_size);
  179681. +
  179682. + for (i = 0; i < vdi_save_lines; i++)
  179683. + memcpy(parent->vditmpbuf[1] + i*line_size,
  179684. + base_off + offset_addr + i*t->set.ostride,
  179685. + line_size);
  179686. + parent->buf1filled = true;
  179687. + } else {
  179688. + offset_addr = t->set.o_off +
  179689. + (t->output.crop.h - vdi_save_lines)*t->set.ostride;
  179690. + for (i = 0; i < vdi_save_lines; i++)
  179691. + memcpy(base_off + offset_addr + i*t->set.ostride,
  179692. + parent->vditmpbuf[1] + i*line_size,
  179693. + line_size);
  179694. +
  179695. + dmac_flush_range(base_off + offset_addr,
  179696. + base_off + offset_addr + i*t->set.ostride);
  179697. + outer_flush_range(t->output.paddr + offset_addr,
  179698. + t->output.paddr + offset_addr + i*t->set.ostride);
  179699. + parent->buf1filled = false;
  179700. + }
  179701. + }
  179702. + /*Down stripe or Down&Right stript*/
  179703. + else if (stripe_mode == (DOWN_STRIPE | RIGHT_STRIPE)) {
  179704. + if (!parent->buf1filled) {
  179705. + offset_addr = t->set.o_off + vdi_save_lines*t->set.ostride;
  179706. + dmac_flush_range(base_off + offset_addr,
  179707. + base_off + offset_addr + vdi_save_lines*t->set.ostride);
  179708. + outer_flush_range(t->output.paddr + offset_addr,
  179709. + t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
  179710. +
  179711. + for (i = 0; i < vdi_save_lines; i++)
  179712. + memcpy(parent->vditmpbuf[1] + i*line_size,
  179713. + base_off + offset_addr + i*t->set.ostride,
  179714. + line_size);
  179715. + parent->buf1filled = true;
  179716. + } else {
  179717. + offset_addr = t->set.o_off;
  179718. + for (i = 0; i < vdi_save_lines; i++)
  179719. + memcpy(base_off + offset_addr + i*t->set.ostride,
  179720. + parent->vditmpbuf[1] + i*line_size,
  179721. + line_size);
  179722. +
  179723. + dmac_flush_range(base_off + offset_addr,
  179724. + base_off + offset_addr + vdi_save_lines*t->set.ostride);
  179725. + outer_flush_range(t->output.paddr + offset_addr,
  179726. + t->output.paddr + offset_addr + vdi_save_lines*t->set.ostride);
  179727. + parent->buf1filled = false;
  179728. + }
  179729. + }
  179730. + if (!pfn_valid(t->output.paddr >> PAGE_SHIFT))
  179731. + iounmap(base_off);
  179732. + mutex_unlock(lock);
  179733. +}
  179734. +
  179735. +static void do_task_release(struct ipu_task_entry *t, int fail)
  179736. +{
  179737. + int ret;
  179738. + struct ipu_soc *ipu = t->ipu;
  179739. +
  179740. + if (t->input.deinterlace.enable && !fail &&
  179741. + (t->task_no & (UP_STRIPE | DOWN_STRIPE)))
  179742. + vdi_split_process(ipu, t);
  179743. +
  179744. + ipu_free_irq(ipu, t->irq, t);
  179745. +
  179746. + if (t->vdoa_dma.vaddr)
  179747. + dma_free_coherent(t->dev,
  179748. + t->vdoa_dma.size,
  179749. + t->vdoa_dma.vaddr,
  179750. + t->vdoa_dma.paddr);
  179751. +
  179752. + if (only_ic(t->set.mode)) {
  179753. + ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
  179754. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic",
  179755. + STATE_DISABLE_CHAN_FAIL, ret);
  179756. + if (deinterlace_3_field(t)) {
  179757. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
  179758. + true);
  179759. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_p",
  179760. + STATE_DISABLE_CHAN_FAIL, ret);
  179761. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
  179762. + true);
  179763. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_ic_n",
  179764. + STATE_DISABLE_CHAN_FAIL, ret);
  179765. + }
  179766. + } else if (only_rot(t->set.mode)) {
  179767. + ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
  179768. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch only_rot",
  179769. + STATE_DISABLE_CHAN_FAIL, ret);
  179770. + } else if (ic_and_rot(t->set.mode)) {
  179771. + ret = ipu_unlink_channels(ipu, t->set.ic_chan, t->set.rot_chan);
  179772. + CHECK_RETCODE_CONT(ret < 0, "ipu_unlink_ch",
  179773. + STATE_UNLINK_CHAN_FAIL, ret);
  179774. + ret = ipu_disable_channel(ipu, t->set.rot_chan, true);
  179775. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-rot",
  179776. + STATE_DISABLE_CHAN_FAIL, ret);
  179777. + ret = ipu_disable_channel(ipu, t->set.ic_chan, true);
  179778. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch ic_and_rot-ic",
  179779. + STATE_DISABLE_CHAN_FAIL, ret);
  179780. + if (deinterlace_3_field(t)) {
  179781. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_p_chan,
  179782. + true);
  179783. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-p",
  179784. + STATE_DISABLE_CHAN_FAIL, ret);
  179785. + ret = ipu_disable_channel(ipu, t->set.vdi_ic_n_chan,
  179786. + true);
  179787. + CHECK_RETCODE_CONT(ret < 0, "ipu_disable_ch icrot-ic-n",
  179788. + STATE_DISABLE_CHAN_FAIL, ret);
  179789. + }
  179790. + }
  179791. +
  179792. + if (only_ic(t->set.mode))
  179793. + uninit_ic(ipu, t);
  179794. + else if (only_rot(t->set.mode))
  179795. + uninit_rot(ipu, t);
  179796. + else if (ic_and_rot(t->set.mode)) {
  179797. + uninit_ic(ipu, t);
  179798. + uninit_rot(ipu, t);
  179799. + }
  179800. +
  179801. + t->state = STATE_OK;
  179802. + CHECK_PERF(&t->ts_rel);
  179803. + return;
  179804. +}
  179805. +
  179806. +static void do_task_vdoa_only(struct ipu_task_entry *t)
  179807. +{
  179808. + int ret;
  179809. +
  179810. + ret = init_tiled_ch_bufs(NULL, t);
  179811. + CHECK_RETCODE(ret < 0, "do_vdoa_only", STATE_ERR, out, ret);
  179812. + ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
  179813. + vdoa_stop(t->vdoa_handle);
  179814. + CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_only",
  179815. + STATE_VDOA_IRQ_TIMEOUT, out, ret);
  179816. +
  179817. + t->state = STATE_OK;
  179818. +out:
  179819. + return;
  179820. +}
  179821. +
  179822. +static void do_task(struct ipu_task_entry *t)
  179823. +{
  179824. + int r_size;
  179825. + int irq;
  179826. + int ret;
  179827. + uint32_t busy;
  179828. + struct ipu_soc *ipu = t->ipu;
  179829. +
  179830. + CHECK_PERF(&t->ts_dotask);
  179831. +
  179832. + if (!ipu) {
  179833. + t->state = STATE_NO_IPU;
  179834. + return;
  179835. + }
  179836. +
  179837. + init_completion(&t->irq_comp);
  179838. + dev_dbg(ipu->dev, "[0x%p]Do task no:0x%x: id %d\n", (void *)t,
  179839. + t->task_no, t->task_id);
  179840. + dump_task_info(t);
  179841. +
  179842. + if (t->set.task & IC_PP) {
  179843. + t->set.ic_chan = MEM_PP_MEM;
  179844. + dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PP_MEM\n", (void *)t);
  179845. + } else if (t->set.task & IC_VF) {
  179846. + t->set.ic_chan = MEM_PRP_VF_MEM;
  179847. + dev_dbg(ipu->dev, "[0x%p]ic channel MEM_PRP_VF_MEM\n", (void *)t);
  179848. + } else if (t->set.task & VDI_VF) {
  179849. + if (t->set.mode & VDOA_BAND_MODE) {
  179850. + t->set.ic_chan = MEM_VDI_MEM;
  179851. + if (deinterlace_3_field(t)) {
  179852. + t->set.vdi_ic_p_chan = MEM_VDI_MEM_P;
  179853. + t->set.vdi_ic_n_chan = MEM_VDI_MEM_N;
  179854. + }
  179855. + dev_dbg(ipu->dev, "[0x%p]ic ch MEM_VDI_MEM\n",
  179856. + (void *)t);
  179857. + } else {
  179858. + t->set.ic_chan = MEM_VDI_PRP_VF_MEM;
  179859. + if (deinterlace_3_field(t)) {
  179860. + t->set.vdi_ic_p_chan = MEM_VDI_PRP_VF_MEM_P;
  179861. + t->set.vdi_ic_n_chan = MEM_VDI_PRP_VF_MEM_N;
  179862. + }
  179863. + dev_dbg(ipu->dev,
  179864. + "[0x%p]ic ch MEM_VDI_PRP_VF_MEM\n", t);
  179865. + }
  179866. + }
  179867. +
  179868. + if (t->set.task & ROT_PP) {
  179869. + t->set.rot_chan = MEM_ROT_PP_MEM;
  179870. + dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_PP_MEM\n", (void *)t);
  179871. + } else if (t->set.task & ROT_VF) {
  179872. + t->set.rot_chan = MEM_ROT_VF_MEM;
  179873. + dev_dbg(ipu->dev, "[0x%p]rot channel MEM_ROT_VF_MEM\n", (void *)t);
  179874. + }
  179875. +
  179876. + if (t->task_id == IPU_TASK_ID_VF)
  179877. + busy = ic_vf_pp_is_busy(ipu, true);
  179878. + else if (t->task_id == IPU_TASK_ID_PP)
  179879. + busy = ic_vf_pp_is_busy(ipu, false);
  179880. + else {
  179881. + dev_err(ipu->dev, "ERR[no:0x%x]ipu task_id:%d invalid!\n",
  179882. + t->task_no, t->task_id);
  179883. + return;
  179884. + }
  179885. + if (busy) {
  179886. + dev_err(ipu->dev, "ERR[0x%p-no:0x%x]ipu task_id:%d busy!\n",
  179887. + (void *)t, t->task_no, t->task_id);
  179888. + t->state = STATE_IPU_BUSY;
  179889. + return;
  179890. + }
  179891. +
  179892. + irq = get_irq(t);
  179893. + if (irq < 0) {
  179894. + t->state = STATE_NO_IRQ;
  179895. + return;
  179896. + }
  179897. + t->irq = irq;
  179898. +
  179899. + /* channel setup */
  179900. + if (only_ic(t->set.mode)) {
  179901. + dev_dbg(t->dev, "[0x%p]only ic mode\n", (void *)t);
  179902. + ret = init_ic(ipu, t);
  179903. + CHECK_RETCODE(ret < 0, "init_ic only_ic",
  179904. + t->state, chan_setup, ret);
  179905. + } else if (only_rot(t->set.mode)) {
  179906. + dev_dbg(t->dev, "[0x%p]only rot mode\n", (void *)t);
  179907. + ret = init_rot(ipu, t);
  179908. + CHECK_RETCODE(ret < 0, "init_rot only_rot",
  179909. + t->state, chan_setup, ret);
  179910. + } else if (ic_and_rot(t->set.mode)) {
  179911. + int rot_idx = (t->task_id == IPU_TASK_ID_VF) ? 0 : 1;
  179912. +
  179913. + dev_dbg(t->dev, "[0x%p]ic + rot mode\n", (void *)t);
  179914. + t->set.r_fmt = t->output.format;
  179915. + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) {
  179916. + t->set.r_width = t->output.crop.h;
  179917. + t->set.r_height = t->output.crop.w;
  179918. + } else {
  179919. + t->set.r_width = t->output.crop.w;
  179920. + t->set.r_height = t->output.crop.h;
  179921. + }
  179922. + t->set.r_stride = t->set.r_width *
  179923. + bytes_per_pixel(t->set.r_fmt);
  179924. + r_size = PAGE_ALIGN(t->set.r_width * t->set.r_height
  179925. + * fmt_to_bpp(t->set.r_fmt)/8);
  179926. +
  179927. + if (r_size > ipu->rot_dma[rot_idx].size) {
  179928. + dev_dbg(t->dev, "[0x%p]realloc rot buffer\n", (void *)t);
  179929. +
  179930. + if (ipu->rot_dma[rot_idx].vaddr)
  179931. + dma_free_coherent(t->dev,
  179932. + ipu->rot_dma[rot_idx].size,
  179933. + ipu->rot_dma[rot_idx].vaddr,
  179934. + ipu->rot_dma[rot_idx].paddr);
  179935. +
  179936. + ipu->rot_dma[rot_idx].size = r_size;
  179937. + ipu->rot_dma[rot_idx].vaddr = dma_alloc_coherent(t->dev,
  179938. + r_size,
  179939. + &ipu->rot_dma[rot_idx].paddr,
  179940. + GFP_DMA | GFP_KERNEL);
  179941. + CHECK_RETCODE(ipu->rot_dma[rot_idx].vaddr == NULL,
  179942. + "ic_and_rot", STATE_SYS_NO_MEM,
  179943. + chan_setup, -ENOMEM);
  179944. + }
  179945. + t->set.r_paddr = ipu->rot_dma[rot_idx].paddr;
  179946. +
  179947. + dev_dbg(t->dev, "[0x%p]rotation:\n", (void *)t);
  179948. + dev_dbg(t->dev, "[0x%p]\tformat = 0x%x\n", (void *)t, t->set.r_fmt);
  179949. + dev_dbg(t->dev, "[0x%p]\twidth = %d\n", (void *)t, t->set.r_width);
  179950. + dev_dbg(t->dev, "[0x%p]\theight = %d\n", (void *)t, t->set.r_height);
  179951. + dev_dbg(t->dev, "[0x%p]\tpaddr = 0x%x\n", (void *)t, t->set.r_paddr);
  179952. + dev_dbg(t->dev, "[0x%p]\trstride = %d\n", (void *)t, t->set.r_stride);
  179953. +
  179954. + ret = init_ic(ipu, t);
  179955. + CHECK_RETCODE(ret < 0, "init_ic ic_and_rot",
  179956. + t->state, chan_setup, ret);
  179957. + ret = init_rot(ipu, t);
  179958. + CHECK_RETCODE(ret < 0, "init_rot ic_and_rot",
  179959. + t->state, chan_setup, ret);
  179960. + ret = ipu_link_channels(ipu, t->set.ic_chan,
  179961. + t->set.rot_chan);
  179962. + CHECK_RETCODE(ret < 0, "ipu_link_ch ic_and_rot",
  179963. + STATE_LINK_CHAN_FAIL, chan_setup, ret);
  179964. + } else {
  179965. + dev_err(t->dev, "ERR [0x%p]do task: should not be here\n", t);
  179966. + t->state = STATE_ERR;
  179967. + return;
  179968. + }
  179969. +
  179970. + ret = ipu_request_irq(ipu, irq, task_irq_handler, 0, NULL, t);
  179971. + CHECK_RETCODE(ret < 0, "ipu_req_irq",
  179972. + STATE_IRQ_FAIL, chan_setup, ret);
  179973. +
  179974. + /* enable/start channel */
  179975. + if (only_ic(t->set.mode)) {
  179976. + ret = ipu_enable_channel(ipu, t->set.ic_chan);
  179977. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic",
  179978. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  179979. + if (deinterlace_3_field(t)) {
  179980. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
  179981. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_p",
  179982. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  179983. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
  179984. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_ic_n",
  179985. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  179986. + }
  179987. +
  179988. + ret = ipu_select_buffer(ipu, t->set.ic_chan, IPU_OUTPUT_BUFFER,
  179989. + 0);
  179990. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic",
  179991. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  179992. + if (t->overlay_en) {
  179993. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  179994. + IPU_GRAPH_IN_BUFFER, 0);
  179995. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_g",
  179996. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  179997. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  179998. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  179999. + IPU_ALPHA_IN_BUFFER, 0);
  180000. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_a",
  180001. + STATE_SEL_BUF_FAIL, chan_buf,
  180002. + ret);
  180003. + }
  180004. + }
  180005. + if (!(t->set.mode & VDOA_BAND_MODE)) {
  180006. + if (deinterlace_3_field(t))
  180007. + ipu_select_multi_vdi_buffer(ipu, 0);
  180008. + else {
  180009. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  180010. + IPU_INPUT_BUFFER, 0);
  180011. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_ic_i",
  180012. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  180013. + }
  180014. + }
  180015. + } else if (only_rot(t->set.mode)) {
  180016. + ret = ipu_enable_channel(ipu, t->set.rot_chan);
  180017. + CHECK_RETCODE(ret < 0, "ipu_enable_ch only_rot",
  180018. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  180019. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  180020. + IPU_OUTPUT_BUFFER, 0);
  180021. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_o",
  180022. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  180023. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  180024. + IPU_INPUT_BUFFER, 0);
  180025. + CHECK_RETCODE(ret < 0, "ipu_sel_buf only_rot_i",
  180026. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  180027. + } else if (ic_and_rot(t->set.mode)) {
  180028. + ret = ipu_enable_channel(ipu, t->set.rot_chan);
  180029. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-rot",
  180030. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  180031. + ret = ipu_enable_channel(ipu, t->set.ic_chan);
  180032. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-ic",
  180033. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  180034. + if (deinterlace_3_field(t)) {
  180035. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_p_chan);
  180036. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-p",
  180037. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  180038. + ret = ipu_enable_channel(ipu, t->set.vdi_ic_n_chan);
  180039. + CHECK_RETCODE(ret < 0, "ipu_enable_ch ic_and_rot-n",
  180040. + STATE_ENABLE_CHAN_FAIL, chan_en, ret);
  180041. + }
  180042. +
  180043. + ret = ipu_select_buffer(ipu, t->set.rot_chan,
  180044. + IPU_OUTPUT_BUFFER, 0);
  180045. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-rot-o",
  180046. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  180047. + if (t->overlay_en) {
  180048. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  180049. + IPU_GRAPH_IN_BUFFER, 0);
  180050. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-g",
  180051. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  180052. + if (t->overlay.alpha.mode == IPU_ALPHA_MODE_LOCAL) {
  180053. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  180054. + IPU_ALPHA_IN_BUFFER, 0);
  180055. + CHECK_RETCODE(ret < 0, "ipu_sel_buf icrot-ic-a",
  180056. + STATE_SEL_BUF_FAIL,
  180057. + chan_buf, ret);
  180058. + }
  180059. + }
  180060. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  180061. + IPU_OUTPUT_BUFFER, 0);
  180062. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-o",
  180063. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  180064. + if (deinterlace_3_field(t))
  180065. + ipu_select_multi_vdi_buffer(ipu, 0);
  180066. + else {
  180067. + ret = ipu_select_buffer(ipu, t->set.ic_chan,
  180068. + IPU_INPUT_BUFFER, 0);
  180069. + CHECK_RETCODE(ret < 0, "ipu_sel_buf ic_and_rot-ic-i",
  180070. + STATE_SEL_BUF_FAIL, chan_buf, ret);
  180071. + }
  180072. + }
  180073. +
  180074. + if (need_split(t))
  180075. + t->state = STATE_IN_PROGRESS;
  180076. +
  180077. + if (t->set.mode & VDOA_BAND_MODE) {
  180078. + ret = vdoa_start(t->vdoa_handle, VDOA_DEF_TIMEOUT_MS);
  180079. + CHECK_RETCODE(ret < 0, "vdoa_wait4complete, do_vdoa_band",
  180080. + STATE_VDOA_IRQ_TIMEOUT, chan_rel, ret);
  180081. + }
  180082. +
  180083. + CHECK_PERF(&t->ts_waitirq);
  180084. + ret = wait_for_completion_timeout(&t->irq_comp,
  180085. + msecs_to_jiffies(t->timeout - DEF_DELAY_MS));
  180086. + CHECK_PERF(&t->ts_wakeup);
  180087. + CHECK_RETCODE(ret == 0, "wait_for_comp_timeout",
  180088. + STATE_IRQ_TIMEOUT, chan_rel, ret);
  180089. + dev_dbg(t->dev, "[0x%p] no-0x%x ipu irq done!", t, t->task_no);
  180090. +
  180091. +chan_rel:
  180092. +chan_buf:
  180093. +chan_en:
  180094. +chan_setup:
  180095. + if (t->set.mode & VDOA_BAND_MODE)
  180096. + vdoa_stop(t->vdoa_handle);
  180097. + do_task_release(t, t->state >= STATE_ERR);
  180098. + return;
  180099. +}
  180100. +
  180101. +static void do_task_vdoa_vdi(struct ipu_task_entry *t)
  180102. +{
  180103. + int i;
  180104. + int ret;
  180105. + u32 stripe_width;
  180106. +
  180107. + /* FIXME: crop mode not support now */
  180108. + stripe_width = t->input.width >> 1;
  180109. + t->input.crop.pos.x = 0;
  180110. + t->input.crop.pos.y = 0;
  180111. + t->input.crop.w = stripe_width;
  180112. + t->input.crop.h = t->input.height;
  180113. + t->output.crop.w = stripe_width;
  180114. + t->output.crop.h = t->input.height;
  180115. +
  180116. + for (i = 0; i < 2; i++) {
  180117. + t->input.crop.pos.x = t->input.crop.pos.x + i * stripe_width;
  180118. + t->output.crop.pos.x = t->output.crop.pos.x + i * stripe_width;
  180119. + /* check input */
  180120. + ret = set_crop(&t->input.crop, t->input.width, t->input.height,
  180121. + t->input.format);
  180122. + if (ret < 0) {
  180123. + ret = STATE_ERR;
  180124. + goto done;
  180125. + } else
  180126. + update_offset(t->input.format,
  180127. + t->input.width, t->input.height,
  180128. + t->input.crop.pos.x,
  180129. + t->input.crop.pos.y,
  180130. + &t->set.i_off, &t->set.i_uoff,
  180131. + &t->set.i_voff, &t->set.istride);
  180132. + dev_dbg(t->dev, "i_off:0x%x, i_uoff:0x%x, istride:%d.\n",
  180133. + t->set.i_off, t->set.i_uoff, t->set.istride);
  180134. + /* check output */
  180135. + ret = set_crop(&t->output.crop, t->input.width,
  180136. + t->output.height, t->output.format);
  180137. + if (ret < 0) {
  180138. + ret = STATE_ERR;
  180139. + goto done;
  180140. + } else
  180141. + update_offset(t->output.format,
  180142. + t->output.width, t->output.height,
  180143. + t->output.crop.pos.x,
  180144. + t->output.crop.pos.y,
  180145. + &t->set.o_off, &t->set.o_uoff,
  180146. + &t->set.o_voff, &t->set.ostride);
  180147. +
  180148. + dev_dbg(t->dev, "o_off:0x%x, o_uoff:0x%x, ostride:%d.\n",
  180149. + t->set.o_off, t->set.o_uoff, t->set.ostride);
  180150. +
  180151. + do_task(t);
  180152. + }
  180153. +
  180154. + return;
  180155. +done:
  180156. + dev_err(t->dev, "ERR %s set_crop.\n", __func__);
  180157. + t->state = ret;
  180158. + return;
  180159. +}
  180160. +
  180161. +static void get_res_do_task(struct ipu_task_entry *t)
  180162. +{
  180163. + uint32_t found;
  180164. + uint32_t split_child;
  180165. + struct mutex *lock;
  180166. +
  180167. + found = get_vdoa_ipu_res(t);
  180168. + if (!found) {
  180169. + dev_err(t->dev, "ERR:[0x%p] no-0x%x can not get res\n",
  180170. + t, t->task_no);
  180171. + return;
  180172. + } else {
  180173. + if (t->set.task & VDOA_ONLY)
  180174. + do_task_vdoa_only(t);
  180175. + else if ((IPU_PIX_FMT_TILED_NV12F == t->input.format) &&
  180176. + (t->set.mode & VDOA_BAND_MODE) &&
  180177. + (t->input.crop.w > soc_max_vdi_in_width()))
  180178. + do_task_vdoa_vdi(t);
  180179. + else
  180180. + do_task(t);
  180181. + put_vdoa_ipu_res(t, 0);
  180182. + }
  180183. + if (t->state != STATE_OK) {
  180184. + dev_err(t->dev, "ERR:[0x%p] no-0x%x state: %s\n",
  180185. + t, t->task_no, state_msg[t->state].msg);
  180186. + }
  180187. +
  180188. + split_child = need_split(t) && t->parent;
  180189. + if (split_child) {
  180190. + lock = &t->parent->split_lock;
  180191. + mutex_lock(lock);
  180192. + t->split_done = 1;
  180193. + mutex_unlock(lock);
  180194. + wake_up(&t->parent->split_waitq);
  180195. + }
  180196. +
  180197. + return;
  180198. +}
  180199. +
  180200. +static void wait_split_task_complete(struct ipu_task_entry *parent,
  180201. + struct ipu_split_task *sp_task, uint32_t size)
  180202. +{
  180203. + struct ipu_task_entry *tsk = NULL;
  180204. + int ret = 0, rc;
  180205. + int j, idx = -1;
  180206. + unsigned long flags;
  180207. + struct mutex *lock = &parent->split_lock;
  180208. + int k, busy_vf, busy_pp;
  180209. + struct ipu_soc *ipu;
  180210. + DECLARE_PERF_VAR;
  180211. +
  180212. + for (j = 0; j < size; j++) {
  180213. + rc = wait_event_timeout(
  180214. + parent->split_waitq,
  180215. + sp_task_check_done(sp_task, parent, size, &idx),
  180216. + msecs_to_jiffies(parent->timeout - DEF_DELAY_MS));
  180217. + if (!rc) {
  180218. + dev_err(parent->dev,
  180219. + "ERR:[0x%p] no-0x%x, split_task timeout,j:%d,"
  180220. + "size:%d.\n",
  180221. + parent, parent->task_no, j, size);
  180222. + ret = -ETIMEDOUT;
  180223. + goto out;
  180224. + } else {
  180225. + if (idx < 0) {
  180226. + dev_err(parent->dev,
  180227. + "ERR:[0x%p] no-0x%x, invalid task idx:%d\n",
  180228. + parent, parent->task_no, idx);
  180229. + continue;
  180230. + }
  180231. + tsk = sp_task[idx].child_task;
  180232. + mutex_lock(lock);
  180233. + if (!tsk->split_done || !tsk->ipu)
  180234. + dev_err(tsk->dev,
  180235. + "ERR:no-0x%x,split not done:%d/null ipu:0x%p\n",
  180236. + tsk->task_no, tsk->split_done, tsk->ipu);
  180237. + tsk->split_done = 0;
  180238. + mutex_unlock(lock);
  180239. +
  180240. + dev_dbg(tsk->dev,
  180241. + "[0x%p] no-0x%x sp_tsk[%d] done,state:%d.\n",
  180242. + tsk, tsk->task_no, idx, tsk->state);
  180243. + #ifdef DBG_IPU_PERF
  180244. + CHECK_PERF(&tsk->ts_rel);
  180245. + PRINT_TASK_STATISTICS;
  180246. + #endif
  180247. + }
  180248. + }
  180249. +
  180250. +out:
  180251. + if (ret == -ETIMEDOUT) {
  180252. + /* debug */
  180253. + for (k = 0; k < max_ipu_no; k++) {
  180254. + ipu = ipu_get_soc(k);
  180255. + if (IS_ERR(ipu)) {
  180256. + dev_err(parent->dev, "no:0x%x, null ipu:%d\n",
  180257. + parent->task_no, k);
  180258. + } else {
  180259. + busy_vf = ic_vf_pp_is_busy(ipu, true);
  180260. + busy_pp = ic_vf_pp_is_busy(ipu, false);
  180261. + dev_err(parent->dev,
  180262. + "ERR:ipu[%d] busy_vf:%d, busy_pp:%d.\n",
  180263. + k, busy_vf, busy_pp);
  180264. + }
  180265. + }
  180266. + for (k = 0; k < size; k++) {
  180267. + tsk = sp_task[k].child_task;
  180268. + if (!tsk)
  180269. + continue;
  180270. + dev_err(parent->dev,
  180271. + "ERR: sp_task[%d][0x%p] no-0x%x done:%d,"
  180272. + "state:%s,on_list:%d, ipu:0x%p,timeout!\n",
  180273. + k, tsk, tsk->task_no, tsk->split_done,
  180274. + state_msg[tsk->state].msg, tsk->task_in_list,
  180275. + tsk->ipu);
  180276. + }
  180277. + }
  180278. +
  180279. + for (j = 0; j < size; j++) {
  180280. + tsk = sp_task[j].child_task;
  180281. + if (!tsk)
  180282. + continue;
  180283. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  180284. + if (tsk->task_in_list) {
  180285. + list_del(&tsk->node);
  180286. + tsk->task_in_list = 0;
  180287. + dev_dbg(tsk->dev,
  180288. + "[0x%p] no-0x%x,id:%d sp_tsk timeout list_del.\n",
  180289. + tsk, tsk->task_no, tsk->task_id);
  180290. + }
  180291. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  180292. + if (!tsk->ipu)
  180293. + continue;
  180294. + if (tsk->state != STATE_OK) {
  180295. + dev_err(tsk->dev,
  180296. + "ERR:[0x%p] no-0x%x,id:%d, sp_tsk state: %s\n",
  180297. + tsk, tsk->task_no, tsk->task_id,
  180298. + state_msg[tsk->state].msg);
  180299. + }
  180300. + kref_put(&tsk->refcount, task_mem_free);
  180301. + }
  180302. +
  180303. + kfree(parent->vditmpbuf[0]);
  180304. + kfree(parent->vditmpbuf[1]);
  180305. +
  180306. + if (ret < 0)
  180307. + parent->state = STATE_TIMEOUT;
  180308. + else
  180309. + parent->state = STATE_OK;
  180310. + return;
  180311. +}
  180312. +
  180313. +static inline int find_task(struct ipu_task_entry **t, int thread_id)
  180314. +{
  180315. + int found;
  180316. + unsigned long flags;
  180317. + struct ipu_task_entry *tsk;
  180318. + struct list_head *task_list = &ipu_task_list;
  180319. +
  180320. + *t = NULL;
  180321. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  180322. + found = !list_empty(task_list);
  180323. + if (found) {
  180324. + tsk = list_first_entry(task_list, struct ipu_task_entry, node);
  180325. + if (tsk->task_in_list) {
  180326. + list_del(&tsk->node);
  180327. + tsk->task_in_list = 0;
  180328. + *t = tsk;
  180329. + kref_get(&tsk->refcount);
  180330. + dev_dbg(tsk->dev,
  180331. + "thread_id:%d,[0x%p] task_no:0x%x,mode:0x%x list_del\n",
  180332. + thread_id, tsk, tsk->task_no, tsk->set.mode);
  180333. + } else
  180334. + dev_err(tsk->dev,
  180335. + "thread_id:%d,task_no:0x%x,mode:0x%x not on list_del\n",
  180336. + thread_id, tsk->task_no, tsk->set.mode);
  180337. + }
  180338. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  180339. +
  180340. + return found;
  180341. +}
  180342. +
  180343. +static int ipu_task_thread(void *argv)
  180344. +{
  180345. + struct ipu_task_entry *tsk;
  180346. + struct ipu_task_entry *sp_tsk0;
  180347. + struct ipu_split_task sp_task[4];
  180348. + /* priority lower than irq_thread */
  180349. + const struct sched_param param = {
  180350. + .sched_priority = MAX_USER_RT_PRIO/2 - 1,
  180351. + };
  180352. + int ret;
  180353. + int curr_thread_id;
  180354. + uint32_t size;
  180355. + unsigned long flags;
  180356. + unsigned int cpu;
  180357. + struct cpumask cpu_mask;
  180358. + struct ipu_thread_data *data = (struct ipu_thread_data *)argv;
  180359. +
  180360. + thread_id++;
  180361. + curr_thread_id = thread_id;
  180362. + sched_setscheduler(current, SCHED_FIFO, &param);
  180363. +
  180364. + if (!data->is_vdoa) {
  180365. + cpu = cpumask_first(cpu_online_mask);
  180366. + cpumask_set_cpu(cpu, &cpu_mask);
  180367. + ret = sched_setaffinity(data->ipu->thread[data->id]->pid,
  180368. + &cpu_mask);
  180369. + if (ret < 0) {
  180370. + pr_err("%s: sched_setaffinity fail:%d.\n", __func__, ret);
  180371. + }
  180372. + pr_debug("%s: sched_setaffinity cpu:%d.\n", __func__, cpu);
  180373. + }
  180374. +
  180375. + while (!kthread_should_stop()) {
  180376. + int split_fail = 0;
  180377. + int split_parent;
  180378. + int split_child;
  180379. +
  180380. + wait_event_interruptible(thread_waitq, find_task(&tsk, curr_thread_id));
  180381. +
  180382. + if (!tsk) {
  180383. + pr_err("thread:%d can not find task.\n",
  180384. + curr_thread_id);
  180385. + continue;
  180386. + }
  180387. +
  180388. + /* note: other threads run split child task */
  180389. + split_parent = need_split(tsk) && !tsk->parent;
  180390. + split_child = need_split(tsk) && tsk->parent;
  180391. + if (split_parent) {
  180392. + if ((tsk->set.split_mode == RL_SPLIT) ||
  180393. + (tsk->set.split_mode == UD_SPLIT))
  180394. + size = 2;
  180395. + else
  180396. + size = 4;
  180397. + ret = queue_split_task(tsk, sp_task, size);
  180398. + if (ret < 0) {
  180399. + split_fail = 1;
  180400. + } else {
  180401. + struct list_head *pos;
  180402. +
  180403. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  180404. +
  180405. + sp_tsk0 = list_first_entry(&tsk->split_list,
  180406. + struct ipu_task_entry, node);
  180407. + list_del(&sp_tsk0->node);
  180408. +
  180409. + list_for_each(pos, &tsk->split_list) {
  180410. + struct ipu_task_entry *tmp;
  180411. +
  180412. + tmp = list_entry(pos,
  180413. + struct ipu_task_entry, node);
  180414. + tmp->task_in_list = 1;
  180415. + dev_dbg(tmp->dev,
  180416. + "[0x%p] no-0x%x,id:%d sp_tsk "
  180417. + "add_to_list.\n", tmp,
  180418. + tmp->task_no, tmp->task_id);
  180419. + }
  180420. + /* add to global list */
  180421. + list_splice(&tsk->split_list, &ipu_task_list);
  180422. +
  180423. + spin_unlock_irqrestore(&ipu_task_list_lock,
  180424. + flags);
  180425. + /* let the parent thread do the first sp_task */
  180426. + /* FIXME: ensure the correct sequence for split
  180427. + 4size: 5/6->9/a*/
  180428. + if (!sp_tsk0)
  180429. + dev_err(tsk->dev,
  180430. + "ERR: no-0x%x,can not get split_tsk0\n",
  180431. + tsk->task_no);
  180432. + wake_up_interruptible(&thread_waitq);
  180433. + get_res_do_task(sp_tsk0);
  180434. + dev_dbg(sp_tsk0->dev,
  180435. + "thread:%d complete tsk no:0x%x.\n",
  180436. + curr_thread_id, sp_tsk0->task_no);
  180437. + ret = atomic_read(&req_cnt);
  180438. + if (ret > 0) {
  180439. + wake_up(&res_waitq);
  180440. + dev_dbg(sp_tsk0->dev,
  180441. + "sp_tsk0 sche thread:%d no:0x%x,"
  180442. + "req_cnt:%d\n", curr_thread_id,
  180443. + sp_tsk0->task_no, ret);
  180444. + /* For other threads to get_res */
  180445. + schedule();
  180446. + }
  180447. + }
  180448. + } else
  180449. + get_res_do_task(tsk);
  180450. +
  180451. + /* wait for all 4 sp_task finished here or timeout
  180452. + and then release all resources */
  180453. + if (split_parent && !split_fail)
  180454. + wait_split_task_complete(tsk, sp_task, size);
  180455. +
  180456. + if (!split_child) {
  180457. + atomic_inc(&tsk->done);
  180458. + wake_up(&tsk->task_waitq);
  180459. + }
  180460. +
  180461. + dev_dbg(tsk->dev, "thread:%d complete tsk no:0x%x-[0x%p].\n",
  180462. + curr_thread_id, tsk->task_no, tsk);
  180463. + ret = atomic_read(&req_cnt);
  180464. + if (ret > 0) {
  180465. + wake_up(&res_waitq);
  180466. + dev_dbg(tsk->dev, "sche thread:%d no:0x%x,req_cnt:%d\n",
  180467. + curr_thread_id, tsk->task_no, ret);
  180468. + /* note: give cpu to other threads to get_res */
  180469. + schedule();
  180470. + }
  180471. +
  180472. + kref_put(&tsk->refcount, task_mem_free);
  180473. + }
  180474. +
  180475. + pr_info("ERR %s exit.\n", __func__);
  180476. + return 0;
  180477. +}
  180478. +
  180479. +int ipu_check_task(struct ipu_task *task)
  180480. +{
  180481. + struct ipu_task_entry *tsk;
  180482. + int ret = 0;
  180483. +
  180484. + tsk = create_task_entry(task);
  180485. + if (IS_ERR(tsk))
  180486. + return PTR_ERR(tsk);
  180487. +
  180488. + ret = check_task(tsk);
  180489. +
  180490. + task->input = tsk->input;
  180491. + task->output = tsk->output;
  180492. + task->overlay = tsk->overlay;
  180493. + dump_task_info(tsk);
  180494. +
  180495. + kref_put(&tsk->refcount, task_mem_free);
  180496. + if (ret != 0)
  180497. + pr_debug("%s ret:%d.\n", __func__, ret);
  180498. + return ret;
  180499. +}
  180500. +EXPORT_SYMBOL_GPL(ipu_check_task);
  180501. +
  180502. +int ipu_queue_task(struct ipu_task *task)
  180503. +{
  180504. + struct ipu_task_entry *tsk;
  180505. + unsigned long flags;
  180506. + int ret;
  180507. + u32 tmp_task_no;
  180508. + DECLARE_PERF_VAR;
  180509. +
  180510. + tsk = create_task_entry(task);
  180511. + if (IS_ERR(tsk))
  180512. + return PTR_ERR(tsk);
  180513. +
  180514. + CHECK_PERF(&tsk->ts_queue);
  180515. + ret = prepare_task(tsk);
  180516. + if (ret < 0)
  180517. + goto done;
  180518. +
  180519. + if (need_split(tsk)) {
  180520. + CHECK_PERF(&tsk->ts_dotask);
  180521. + CHECK_PERF(&tsk->ts_waitirq);
  180522. + CHECK_PERF(&tsk->ts_inirq);
  180523. + CHECK_PERF(&tsk->ts_wakeup);
  180524. + }
  180525. +
  180526. + /* task_no last four bits for split task type*/
  180527. + tmp_task_no = atomic_inc_return(&frame_no);
  180528. + tsk->task_no = tmp_task_no << 4;
  180529. + init_waitqueue_head(&tsk->task_waitq);
  180530. +
  180531. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  180532. + list_add_tail(&tsk->node, &ipu_task_list);
  180533. + tsk->task_in_list = 1;
  180534. + dev_dbg(tsk->dev, "[0x%p,no-0x%x] list_add_tail\n", tsk, tsk->task_no);
  180535. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  180536. + wake_up_interruptible(&thread_waitq);
  180537. +
  180538. + ret = wait_event_timeout(tsk->task_waitq, atomic_read(&tsk->done),
  180539. + msecs_to_jiffies(tsk->timeout));
  180540. + if (0 == ret) {
  180541. + /* note: the timeout should larger than the internal timeout!*/
  180542. + ret = -ETIMEDOUT;
  180543. + dev_err(tsk->dev, "ERR: [0x%p] no-0x%x, timeout:%dms!\n",
  180544. + tsk, tsk->task_no, tsk->timeout);
  180545. + } else {
  180546. + if (STATE_OK != tsk->state) {
  180547. + dev_err(tsk->dev, "ERR: [0x%p] no-0x%x,state %d: %s\n",
  180548. + tsk, tsk->task_no, tsk->state,
  180549. + state_msg[tsk->state].msg);
  180550. + ret = -ECANCELED;
  180551. + } else
  180552. + ret = 0;
  180553. + }
  180554. +
  180555. + spin_lock_irqsave(&ipu_task_list_lock, flags);
  180556. + if (tsk->task_in_list) {
  180557. + list_del(&tsk->node);
  180558. + tsk->task_in_list = 0;
  180559. + dev_dbg(tsk->dev, "[0x%p] no:0x%x list_del\n",
  180560. + tsk, tsk->task_no);
  180561. + }
  180562. + spin_unlock_irqrestore(&ipu_task_list_lock, flags);
  180563. +
  180564. +#ifdef DBG_IPU_PERF
  180565. + CHECK_PERF(&tsk->ts_rel);
  180566. + PRINT_TASK_STATISTICS;
  180567. + if (ts_frame_avg == 0)
  180568. + ts_frame_avg = ts_frame.tv_nsec / NSEC_PER_USEC +
  180569. + ts_frame.tv_sec * USEC_PER_SEC;
  180570. + else
  180571. + ts_frame_avg = (ts_frame_avg + ts_frame.tv_nsec / NSEC_PER_USEC
  180572. + + ts_frame.tv_sec * USEC_PER_SEC)/2;
  180573. + if (timespec_compare(&ts_frame, &ts_frame_max) > 0)
  180574. + ts_frame_max = ts_frame;
  180575. +
  180576. + atomic_inc(&frame_cnt);
  180577. +
  180578. + if ((atomic_read(&frame_cnt) % 1000) == 0)
  180579. + pr_debug("ipu_dev: max frame time:%ldus, avg frame time:%dus,"
  180580. + "frame_cnt:%d\n", ts_frame_max.tv_nsec / NSEC_PER_USEC
  180581. + + ts_frame_max.tv_sec * USEC_PER_SEC,
  180582. + ts_frame_avg, atomic_read(&frame_cnt));
  180583. +#endif
  180584. +done:
  180585. + if (ret < 0)
  180586. + dev_err(tsk->dev, "ERR: no-0x%x,ipu_queue_task err:%d\n",
  180587. + tsk->task_no, ret);
  180588. +
  180589. + kref_put(&tsk->refcount, task_mem_free);
  180590. +
  180591. + return ret;
  180592. +}
  180593. +EXPORT_SYMBOL_GPL(ipu_queue_task);
  180594. +
  180595. +static int mxc_ipu_open(struct inode *inode, struct file *file)
  180596. +{
  180597. + file->private_data = (void *)atomic_inc_return(&file_index);
  180598. + return 0;
  180599. +}
  180600. +
  180601. +static long mxc_ipu_ioctl(struct file *file,
  180602. + unsigned int cmd, unsigned long arg)
  180603. +{
  180604. + int __user *argp = (void __user *)arg;
  180605. + int ret = 0;
  180606. +
  180607. + switch (cmd) {
  180608. + case IPU_CHECK_TASK:
  180609. + {
  180610. + struct ipu_task task;
  180611. +
  180612. + if (copy_from_user
  180613. + (&task, (struct ipu_task *) arg,
  180614. + sizeof(struct ipu_task)))
  180615. + return -EFAULT;
  180616. + ret = ipu_check_task(&task);
  180617. + if (copy_to_user((struct ipu_task *) arg,
  180618. + &task, sizeof(struct ipu_task)))
  180619. + return -EFAULT;
  180620. + break;
  180621. + }
  180622. + case IPU_QUEUE_TASK:
  180623. + {
  180624. + struct ipu_task task;
  180625. +
  180626. + if (copy_from_user
  180627. + (&task, (struct ipu_task *) arg,
  180628. + sizeof(struct ipu_task)))
  180629. + return -EFAULT;
  180630. + ret = ipu_queue_task(&task);
  180631. + break;
  180632. + }
  180633. + case IPU_ALLOC:
  180634. + {
  180635. + int size;
  180636. + struct ipu_alloc_list *mem;
  180637. +
  180638. + mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  180639. + if (mem == NULL)
  180640. + return -ENOMEM;
  180641. +
  180642. + if (get_user(size, argp))
  180643. + return -EFAULT;
  180644. +
  180645. + mem->size = PAGE_ALIGN(size);
  180646. +
  180647. + mem->cpu_addr = dma_alloc_coherent(ipu_dev, size,
  180648. + &mem->phy_addr,
  180649. + GFP_DMA | GFP_KERNEL);
  180650. + if (mem->cpu_addr == NULL) {
  180651. + kfree(mem);
  180652. + return -ENOMEM;
  180653. + }
  180654. + mem->file_index = file->private_data;
  180655. + mutex_lock(&ipu_alloc_lock);
  180656. + list_add(&mem->list, &ipu_alloc_list);
  180657. + mutex_unlock(&ipu_alloc_lock);
  180658. +
  180659. + dev_dbg(ipu_dev, "allocated %d bytes @ 0x%08X\n",
  180660. + mem->size, mem->phy_addr);
  180661. +
  180662. + if (put_user(mem->phy_addr, argp))
  180663. + return -EFAULT;
  180664. +
  180665. + break;
  180666. + }
  180667. + case IPU_FREE:
  180668. + {
  180669. + unsigned long offset;
  180670. + struct ipu_alloc_list *mem;
  180671. +
  180672. + if (get_user(offset, argp))
  180673. + return -EFAULT;
  180674. +
  180675. + ret = -EINVAL;
  180676. + mutex_lock(&ipu_alloc_lock);
  180677. + list_for_each_entry(mem, &ipu_alloc_list, list) {
  180678. + if (mem->phy_addr == offset) {
  180679. + list_del(&mem->list);
  180680. + dma_free_coherent(ipu_dev,
  180681. + mem->size,
  180682. + mem->cpu_addr,
  180683. + mem->phy_addr);
  180684. + kfree(mem);
  180685. + ret = 0;
  180686. + break;
  180687. + }
  180688. + }
  180689. + mutex_unlock(&ipu_alloc_lock);
  180690. + if (0 == ret)
  180691. + dev_dbg(ipu_dev, "free %d bytes @ 0x%08X\n",
  180692. + mem->size, mem->phy_addr);
  180693. +
  180694. + break;
  180695. + }
  180696. + default:
  180697. + break;
  180698. + }
  180699. + return ret;
  180700. +}
  180701. +
  180702. +static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
  180703. +{
  180704. + bool found = false;
  180705. + u32 len;
  180706. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  180707. + struct ipu_alloc_list *mem;
  180708. +
  180709. + mutex_lock(&ipu_alloc_lock);
  180710. + list_for_each_entry(mem, &ipu_alloc_list, list) {
  180711. + if (offset == mem->phy_addr) {
  180712. + found = true;
  180713. + len = mem->size;
  180714. + break;
  180715. + }
  180716. + }
  180717. + mutex_unlock(&ipu_alloc_lock);
  180718. + if (!found)
  180719. + return -EINVAL;
  180720. +
  180721. + if (vma->vm_end - vma->vm_start > len)
  180722. + return -EINVAL;
  180723. +
  180724. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  180725. +
  180726. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  180727. + vma->vm_end - vma->vm_start,
  180728. + vma->vm_page_prot)) {
  180729. + printk(KERN_ERR
  180730. + "mmap failed!\n");
  180731. + return -ENOBUFS;
  180732. + }
  180733. + return 0;
  180734. +}
  180735. +
  180736. +static int mxc_ipu_release(struct inode *inode, struct file *file)
  180737. +{
  180738. + struct ipu_alloc_list *mem;
  180739. + struct ipu_alloc_list *n;
  180740. +
  180741. + mutex_lock(&ipu_alloc_lock);
  180742. + list_for_each_entry_safe(mem, n, &ipu_alloc_list, list) {
  180743. + if ((mem->cpu_addr != 0) &&
  180744. + (file->private_data == mem->file_index)) {
  180745. + list_del(&mem->list);
  180746. + dma_free_coherent(ipu_dev,
  180747. + mem->size,
  180748. + mem->cpu_addr,
  180749. + mem->phy_addr);
  180750. + dev_dbg(ipu_dev, "rel-free %d bytes @ 0x%08X\n",
  180751. + mem->size, mem->phy_addr);
  180752. + kfree(mem);
  180753. + }
  180754. + }
  180755. + mutex_unlock(&ipu_alloc_lock);
  180756. + atomic_dec(&file_index);
  180757. +
  180758. + return 0;
  180759. +}
  180760. +
  180761. +static struct file_operations mxc_ipu_fops = {
  180762. + .owner = THIS_MODULE,
  180763. + .open = mxc_ipu_open,
  180764. + .mmap = mxc_ipu_mmap,
  180765. + .release = mxc_ipu_release,
  180766. + .unlocked_ioctl = mxc_ipu_ioctl,
  180767. +};
  180768. +
  180769. +int register_ipu_device(struct ipu_soc *ipu, int id)
  180770. +{
  180771. + int ret = 0;
  180772. + static int idx;
  180773. + static struct ipu_thread_data thread_data[5];
  180774. +
  180775. + if (!major) {
  180776. + major = register_chrdev(0, "mxc_ipu", &mxc_ipu_fops);
  180777. + if (major < 0) {
  180778. + printk(KERN_ERR "Unable to register mxc_ipu as a char device\n");
  180779. + ret = major;
  180780. + goto register_cdev_fail;
  180781. + }
  180782. +
  180783. + ipu_class = class_create(THIS_MODULE, "mxc_ipu");
  180784. + if (IS_ERR(ipu_class)) {
  180785. + ret = PTR_ERR(ipu_class);
  180786. + goto ipu_class_fail;
  180787. + }
  180788. +
  180789. + ipu_dev = device_create(ipu_class, NULL, MKDEV(major, 0),
  180790. + NULL, "mxc_ipu");
  180791. + if (IS_ERR(ipu_dev)) {
  180792. + ret = PTR_ERR(ipu_dev);
  180793. + goto dev_create_fail;
  180794. + }
  180795. + ipu_dev->dma_mask = kmalloc(sizeof(*ipu_dev->dma_mask), GFP_KERNEL);
  180796. + *ipu_dev->dma_mask = DMA_BIT_MASK(32);
  180797. + ipu_dev->coherent_dma_mask = DMA_BIT_MASK(32);
  180798. +
  180799. + mutex_init(&ipu_ch_tbl.lock);
  180800. + }
  180801. + max_ipu_no = ++id;
  180802. + ipu->rot_dma[0].size = 0;
  180803. + ipu->rot_dma[1].size = 0;
  180804. +
  180805. + thread_data[idx].ipu = ipu;
  180806. + thread_data[idx].id = 0;
  180807. + thread_data[idx].is_vdoa = 0;
  180808. + ipu->thread[0] = kthread_run(ipu_task_thread, &thread_data[idx++],
  180809. + "ipu%d_task", id);
  180810. + if (IS_ERR(ipu->thread[0])) {
  180811. + ret = PTR_ERR(ipu->thread[0]);
  180812. + goto kthread0_fail;
  180813. + }
  180814. +
  180815. + thread_data[idx].ipu = ipu;
  180816. + thread_data[idx].id = 1;
  180817. + thread_data[idx].is_vdoa = 0;
  180818. + ipu->thread[1] = kthread_run(ipu_task_thread, &thread_data[idx++],
  180819. + "ipu%d_task", id);
  180820. + if (IS_ERR(ipu->thread[1])) {
  180821. + ret = PTR_ERR(ipu->thread[1]);
  180822. + goto kthread1_fail;
  180823. + }
  180824. +
  180825. +
  180826. + return ret;
  180827. +
  180828. +kthread1_fail:
  180829. + kthread_stop(ipu->thread[0]);
  180830. +kthread0_fail:
  180831. + if (id == 0)
  180832. + device_destroy(ipu_class, MKDEV(major, 0));
  180833. +dev_create_fail:
  180834. + if (id == 0) {
  180835. + class_destroy(ipu_class);
  180836. + }
  180837. +ipu_class_fail:
  180838. + if (id == 0)
  180839. + unregister_chrdev(major, "mxc_ipu");
  180840. +register_cdev_fail:
  180841. + return ret;
  180842. +}
  180843. +
  180844. +void unregister_ipu_device(struct ipu_soc *ipu, int id)
  180845. +{
  180846. + int i;
  180847. +
  180848. + kthread_stop(ipu->thread[0]);
  180849. + kthread_stop(ipu->thread[1]);
  180850. + for (i = 0; i < 2; i++) {
  180851. + if (ipu->rot_dma[i].vaddr)
  180852. + dma_free_coherent(ipu_dev,
  180853. + ipu->rot_dma[i].size,
  180854. + ipu->rot_dma[i].vaddr,
  180855. + ipu->rot_dma[i].paddr);
  180856. + }
  180857. +
  180858. + if (major) {
  180859. + device_destroy(ipu_class, MKDEV(major, 0));
  180860. + class_destroy(ipu_class);
  180861. + unregister_chrdev(major, "mxc_ipu");
  180862. + major = 0;
  180863. + }
  180864. +}
  180865. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_disp.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_disp.c
  180866. --- linux-3.14.17/drivers/mxc/ipu3/ipu_disp.c 1970-01-01 01:00:00.000000000 +0100
  180867. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_disp.c 2014-09-11 18:06:03.134042499 +0200
  180868. @@ -0,0 +1,1962 @@
  180869. +/*
  180870. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  180871. + */
  180872. +
  180873. +/*
  180874. + * The code contained herein is licensed under the GNU General Public
  180875. + * License. You may obtain a copy of the GNU General Public License
  180876. + * Version 2 or later at the following locations:
  180877. + *
  180878. + * http://www.opensource.org/licenses/gpl-license.html
  180879. + * http://www.gnu.org/copyleft/gpl.html
  180880. + */
  180881. +
  180882. +/*!
  180883. + * @file ipu_disp.c
  180884. + *
  180885. + * @brief IPU display submodule API functions
  180886. + *
  180887. + * @ingroup IPU
  180888. + */
  180889. +
  180890. +#include <linux/clk.h>
  180891. +#include <linux/clk-provider.h>
  180892. +#include <linux/delay.h>
  180893. +#include <linux/err.h>
  180894. +#include <linux/errno.h>
  180895. +#include <linux/io.h>
  180896. +#include <linux/ipu-v3.h>
  180897. +#include <linux/module.h>
  180898. +#include <linux/spinlock.h>
  180899. +#include <linux/types.h>
  180900. +
  180901. +#include <asm/atomic.h>
  180902. +
  180903. +#include "ipu_param_mem.h"
  180904. +#include "ipu_regs.h"
  180905. +
  180906. +struct dp_csc_param_t {
  180907. + int mode;
  180908. + void *coeff;
  180909. +};
  180910. +
  180911. +#define SYNC_WAVE 0
  180912. +#define NULL_WAVE (-1)
  180913. +#define ASYNC_SER_WAVE 6
  180914. +
  180915. +/* DC display ID assignments */
  180916. +#define DC_DISP_ID_SYNC(di) (di)
  180917. +#define DC_DISP_ID_SERIAL 2
  180918. +#define DC_DISP_ID_ASYNC 3
  180919. +
  180920. +int dmfc_type_setup;
  180921. +
  180922. +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first)
  180923. +{
  180924. + u32 dmfc_wr_chan, dmfc_dp_chan;
  180925. +
  180926. + if (first) {
  180927. + if (dmfc_type_setup > dmfc_type)
  180928. + dmfc_type = dmfc_type_setup;
  180929. + else
  180930. + dmfc_type_setup = dmfc_type;
  180931. +
  180932. + /* disable DMFC-IC channel*/
  180933. + ipu_dmfc_write(ipu, 0x2, DMFC_IC_CTRL);
  180934. + } else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) {
  180935. + dev_dbg(ipu->dev, "DMFC high resolution has set, will not change\n");
  180936. + return;
  180937. + } else
  180938. + dmfc_type_setup = dmfc_type;
  180939. +
  180940. + if (dmfc_type == DMFC_HIGH_RESOLUTION_DC) {
  180941. + /* 1 - segment 0~3;
  180942. + * 5B - segement 4, 5;
  180943. + * 5F - segement 6, 7;
  180944. + * 1C, 2C and 6B, 6F unused;
  180945. + */
  180946. + dev_info(ipu->dev, "IPU DMFC DC HIGH RESOLUTION: 1(0~3), 5B(4,5), 5F(6,7)\n");
  180947. + dmfc_wr_chan = 0x00000088;
  180948. + dmfc_dp_chan = 0x00009694;
  180949. + ipu->dmfc_size_28 = 256*4;
  180950. + ipu->dmfc_size_29 = 0;
  180951. + ipu->dmfc_size_24 = 0;
  180952. + ipu->dmfc_size_27 = 128*4;
  180953. + ipu->dmfc_size_23 = 128*4;
  180954. + } else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) {
  180955. + /* 1 - segment 0, 1;
  180956. + * 5B - segement 2~5;
  180957. + * 5F - segement 6,7;
  180958. + * 1C, 2C and 6B, 6F unused;
  180959. + */
  180960. + dev_info(ipu->dev, "IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)\n");
  180961. + dmfc_wr_chan = 0x00000090;
  180962. + dmfc_dp_chan = 0x0000968a;
  180963. + ipu->dmfc_size_28 = 128*4;
  180964. + ipu->dmfc_size_29 = 0;
  180965. + ipu->dmfc_size_24 = 0;
  180966. + ipu->dmfc_size_27 = 128*4;
  180967. + ipu->dmfc_size_23 = 256*4;
  180968. + } else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) {
  180969. + /* 5B - segement 0~3;
  180970. + * 5F - segement 4~7;
  180971. + * 1, 1C, 2C and 6B, 6F unused;
  180972. + */
  180973. + dev_info(ipu->dev, "IPU DMFC ONLY-DP HIGH RESOLUTION: 5B(0~3), 5F(4~7)\n");
  180974. + dmfc_wr_chan = 0x00000000;
  180975. + dmfc_dp_chan = 0x00008c88;
  180976. + ipu->dmfc_size_28 = 0;
  180977. + ipu->dmfc_size_29 = 0;
  180978. + ipu->dmfc_size_24 = 0;
  180979. + ipu->dmfc_size_27 = 256*4;
  180980. + ipu->dmfc_size_23 = 256*4;
  180981. + } else {
  180982. + /* 1 - segment 0, 1;
  180983. + * 5B - segement 4, 5;
  180984. + * 5F - segement 6, 7;
  180985. + * 1C, 2C and 6B, 6F unused;
  180986. + */
  180987. + dev_info(ipu->dev, "IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n");
  180988. + dmfc_wr_chan = 0x00000090;
  180989. + dmfc_dp_chan = 0x00009694;
  180990. + ipu->dmfc_size_28 = 128*4;
  180991. + ipu->dmfc_size_29 = 0;
  180992. + ipu->dmfc_size_24 = 0;
  180993. + ipu->dmfc_size_27 = 128*4;
  180994. + ipu->dmfc_size_23 = 128*4;
  180995. + }
  180996. + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
  180997. + ipu_dmfc_write(ipu, 0x202020F6, DMFC_WR_CHAN_DEF);
  180998. + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
  180999. + /* Enable chan 5 watermark set at 5 bursts and clear at 7 bursts */
  181000. + ipu_dmfc_write(ipu, 0x2020F6F6, DMFC_DP_CHAN_DEF);
  181001. +}
  181002. +
  181003. +static int __init dmfc_setup(char *options)
  181004. +{
  181005. + get_option(&options, &dmfc_type_setup);
  181006. + if (dmfc_type_setup > DMFC_HIGH_RESOLUTION_ONLY_DP)
  181007. + dmfc_type_setup = DMFC_HIGH_RESOLUTION_ONLY_DP;
  181008. + return 1;
  181009. +}
  181010. +__setup("dmfc=", dmfc_setup);
  181011. +
  181012. +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width)
  181013. +{
  181014. + u32 dmfc_gen1 = ipu_dmfc_read(ipu, DMFC_GENERAL1);
  181015. +
  181016. + if (width >= HIGH_RESOLUTION_WIDTH) {
  181017. + if (dma_chan == 23)
  181018. + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DP, 0);
  181019. + else if (dma_chan == 28)
  181020. + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DC, 0);
  181021. + }
  181022. +
  181023. + if (dma_chan == 23) { /*5B*/
  181024. + if (ipu->dmfc_size_23/width > 3)
  181025. + dmfc_gen1 |= 1UL << 20;
  181026. + else
  181027. + dmfc_gen1 &= ~(1UL << 20);
  181028. + } else if (dma_chan == 24) { /*6B*/
  181029. + if (ipu->dmfc_size_24/width > 1)
  181030. + dmfc_gen1 |= 1UL << 22;
  181031. + else
  181032. + dmfc_gen1 &= ~(1UL << 22);
  181033. + } else if (dma_chan == 27) { /*5F*/
  181034. + if (ipu->dmfc_size_27/width > 2)
  181035. + dmfc_gen1 |= 1UL << 21;
  181036. + else
  181037. + dmfc_gen1 &= ~(1UL << 21);
  181038. + } else if (dma_chan == 28) { /*1*/
  181039. + if (ipu->dmfc_size_28/width > 2)
  181040. + dmfc_gen1 |= 1UL << 16;
  181041. + else
  181042. + dmfc_gen1 &= ~(1UL << 16);
  181043. + } else if (dma_chan == 29) { /*6F*/
  181044. + if (ipu->dmfc_size_29/width > 1)
  181045. + dmfc_gen1 |= 1UL << 23;
  181046. + else
  181047. + dmfc_gen1 &= ~(1UL << 23);
  181048. + }
  181049. +
  181050. + ipu_dmfc_write(ipu, dmfc_gen1, DMFC_GENERAL1);
  181051. +}
  181052. +
  181053. +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size)
  181054. +{
  181055. + u32 dmfc_wr_chan = ipu_dmfc_read(ipu, DMFC_WR_CHAN);
  181056. + u32 dmfc_dp_chan = ipu_dmfc_read(ipu, DMFC_DP_CHAN);
  181057. + int dmfc_bs = 0;
  181058. +
  181059. + switch (burst_size) {
  181060. + case 64:
  181061. + dmfc_bs = 0x40;
  181062. + break;
  181063. + case 32:
  181064. + case 20:
  181065. + dmfc_bs = 0x80;
  181066. + break;
  181067. + case 16:
  181068. + dmfc_bs = 0xc0;
  181069. + break;
  181070. + default:
  181071. + dev_err(ipu->dev, "Unsupported burst size %d\n",
  181072. + burst_size);
  181073. + return;
  181074. + }
  181075. +
  181076. + if (dma_chan == 23) { /*5B*/
  181077. + dmfc_dp_chan &= ~(0xc0);
  181078. + dmfc_dp_chan |= dmfc_bs;
  181079. + } else if (dma_chan == 27) { /*5F*/
  181080. + dmfc_dp_chan &= ~(0xc000);
  181081. + dmfc_dp_chan |= (dmfc_bs << 8);
  181082. + } else if (dma_chan == 28) { /*1*/
  181083. + dmfc_wr_chan &= ~(0xc0);
  181084. + dmfc_wr_chan |= dmfc_bs;
  181085. + }
  181086. +
  181087. + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN);
  181088. + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN);
  181089. +}
  181090. +
  181091. +static void _ipu_di_data_wave_config(struct ipu_soc *ipu,
  181092. + int di, int wave_gen,
  181093. + int access_size, int component_size)
  181094. +{
  181095. + u32 reg;
  181096. + reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) |
  181097. + (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET);
  181098. + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
  181099. +}
  181100. +
  181101. +static void _ipu_di_data_pin_config(struct ipu_soc *ipu,
  181102. + int di, int wave_gen, int di_pin, int set,
  181103. + int up, int down)
  181104. +{
  181105. + u32 reg;
  181106. +
  181107. + reg = ipu_di_read(ipu, di, DI_DW_GEN(wave_gen));
  181108. + reg &= ~(0x3 << (di_pin * 2));
  181109. + reg |= set << (di_pin * 2);
  181110. + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen));
  181111. +
  181112. + ipu_di_write(ipu, di, (down << 16) | up, DI_DW_SET(wave_gen, set));
  181113. +}
  181114. +
  181115. +static void _ipu_di_sync_config(struct ipu_soc *ipu,
  181116. + int di, int wave_gen,
  181117. + int run_count, int run_src,
  181118. + int offset_count, int offset_src,
  181119. + int repeat_count, int cnt_clr_src,
  181120. + int cnt_polarity_gen_en,
  181121. + int cnt_polarity_clr_src,
  181122. + int cnt_polarity_trigger_src,
  181123. + int cnt_up, int cnt_down)
  181124. +{
  181125. + u32 reg;
  181126. +
  181127. + if ((run_count >= 0x1000) || (offset_count >= 0x1000) || (repeat_count >= 0x1000) ||
  181128. + (cnt_up >= 0x400) || (cnt_down >= 0x400)) {
  181129. + dev_err(ipu->dev, "DI%d counters out of range.\n", di);
  181130. + return;
  181131. + }
  181132. +
  181133. + reg = (run_count << 19) | (++run_src << 16) |
  181134. + (offset_count << 3) | ++offset_src;
  181135. + ipu_di_write(ipu, di, reg, DI_SW_GEN0(wave_gen));
  181136. + reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) |
  181137. + (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9);
  181138. + reg |= (cnt_down << 16) | cnt_up;
  181139. + if (repeat_count == 0) {
  181140. + /* Enable auto reload */
  181141. + reg |= 0x10000000;
  181142. + }
  181143. + ipu_di_write(ipu, di, reg, DI_SW_GEN1(wave_gen));
  181144. + reg = ipu_di_read(ipu, di, DI_STP_REP(wave_gen));
  181145. + reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1)));
  181146. + reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1));
  181147. + ipu_di_write(ipu, di, reg, DI_STP_REP(wave_gen));
  181148. +}
  181149. +
  181150. +static void _ipu_dc_map_link(struct ipu_soc *ipu,
  181151. + int current_map,
  181152. + int base_map_0, int buf_num_0,
  181153. + int base_map_1, int buf_num_1,
  181154. + int base_map_2, int buf_num_2)
  181155. +{
  181156. + int ptr_0 = base_map_0 * 3 + buf_num_0;
  181157. + int ptr_1 = base_map_1 * 3 + buf_num_1;
  181158. + int ptr_2 = base_map_2 * 3 + buf_num_2;
  181159. + int ptr;
  181160. + u32 reg;
  181161. + ptr = (ptr_2 << 10) + (ptr_1 << 5) + ptr_0;
  181162. +
  181163. + reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(current_map));
  181164. + reg &= ~(0x1F << ((16 * (current_map & 0x1))));
  181165. + reg |= ptr << ((16 * (current_map & 0x1)));
  181166. + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(current_map));
  181167. +}
  181168. +
  181169. +static void _ipu_dc_map_config(struct ipu_soc *ipu,
  181170. + int map, int byte_num, int offset, int mask)
  181171. +{
  181172. + int ptr = map * 3 + byte_num;
  181173. + u32 reg;
  181174. +
  181175. + reg = ipu_dc_read(ipu, DC_MAP_CONF_VAL(ptr));
  181176. + reg &= ~(0xFFFF << (16 * (ptr & 0x1)));
  181177. + reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1));
  181178. + ipu_dc_write(ipu, reg, DC_MAP_CONF_VAL(ptr));
  181179. +
  181180. + reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
  181181. + reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num)));
  181182. + reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num));
  181183. + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(map));
  181184. +}
  181185. +
  181186. +static void _ipu_dc_map_clear(struct ipu_soc *ipu, int map)
  181187. +{
  181188. + u32 reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map));
  181189. + ipu_dc_write(ipu, reg & ~(0xFFFF << (16 * (map & 0x1))),
  181190. + DC_MAP_CONF_PTR(map));
  181191. +}
  181192. +
  181193. +static void _ipu_dc_write_tmpl(struct ipu_soc *ipu,
  181194. + int word, u32 opcode, u32 operand, int map,
  181195. + int wave, int glue, int sync, int stop)
  181196. +{
  181197. + u32 reg;
  181198. +
  181199. + if (opcode == WRG) {
  181200. + reg = sync;
  181201. + reg |= (glue << 4);
  181202. + reg |= (++wave << 11);
  181203. + reg |= ((operand & 0x1FFFF) << 15);
  181204. + ipu_dc_tmpl_write(ipu, reg, word * 8);
  181205. +
  181206. + reg = (operand >> 17);
  181207. + reg |= opcode << 7;
  181208. + reg |= (stop << 9);
  181209. + ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
  181210. + } else {
  181211. + reg = sync;
  181212. + reg |= (glue << 4);
  181213. + reg |= (++wave << 11);
  181214. + reg |= (++map << 15);
  181215. + reg |= (operand << 20) & 0xFFF00000;
  181216. + ipu_dc_tmpl_write(ipu, reg, word * 8);
  181217. +
  181218. + reg = (operand >> 12);
  181219. + reg |= opcode << 4;
  181220. + reg |= (stop << 9);
  181221. + ipu_dc_tmpl_write(ipu, reg, word * 8 + 4);
  181222. + }
  181223. +}
  181224. +
  181225. +static void _ipu_dc_link_event(struct ipu_soc *ipu,
  181226. + int chan, int event, int addr, int priority)
  181227. +{
  181228. + u32 reg;
  181229. + u32 address_shift;
  181230. + if (event < DC_EVEN_UGDE0) {
  181231. + reg = ipu_dc_read(ipu, DC_RL_CH(chan, event));
  181232. + reg &= ~(0xFFFF << (16 * (event & 0x1)));
  181233. + reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
  181234. + ipu_dc_write(ipu, reg, DC_RL_CH(chan, event));
  181235. + } else {
  181236. + reg = ipu_dc_read(ipu, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
  181237. + if ((event - DC_EVEN_UGDE0) & 0x1) {
  181238. + reg &= ~(0x2FF << 16);
  181239. + reg |= (addr << 16);
  181240. + reg |= priority ? (2 << 24) : 0x0;
  181241. + } else {
  181242. + reg &= ~0xFC00FFFF;
  181243. + if (priority)
  181244. + chan = (chan >> 1) +
  181245. + ((((chan & 0x1) + ((chan & 0x2) >> 1))) | (chan >> 3));
  181246. + else
  181247. + chan = 0x7;
  181248. + address_shift = ((event - DC_EVEN_UGDE0) >> 1) ? 7 : 8;
  181249. + reg |= (addr << address_shift) | (priority << 3) | chan;
  181250. + }
  181251. + ipu_dc_write(ipu, reg, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
  181252. + }
  181253. +}
  181254. +
  181255. +/* Y = R * 1.200 + G * 2.343 + B * .453 + 0.250;
  181256. + U = R * -.672 + G * -1.328 + B * 2.000 + 512.250.;
  181257. + V = R * 2.000 + G * -1.672 + B * -.328 + 512.250.;*/
  181258. +static const int rgb2ycbcr_coeff[5][3] = {
  181259. + {0x4D, 0x96, 0x1D},
  181260. + {-0x2B, -0x55, 0x80},
  181261. + {0x80, -0x6B, -0x15},
  181262. + {0x0000, 0x0200, 0x0200}, /* B0, B1, B2 */
  181263. + {0x2, 0x2, 0x2}, /* S0, S1, S2 */
  181264. +};
  181265. +
  181266. +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  181267. + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  181268. + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
  181269. +static const int ycbcr2rgb_coeff[5][3] = {
  181270. + {0x095, 0x000, 0x0CC},
  181271. + {0x095, 0x3CE, 0x398},
  181272. + {0x095, 0x0FF, 0x000},
  181273. + {0x3E42, 0x010A, 0x3DD6}, /*B0,B1,B2 */
  181274. + {0x1, 0x1, 0x1}, /*S0,S1,S2 */
  181275. +};
  181276. +
  181277. +#define mask_a(a) ((u32)(a) & 0x3FF)
  181278. +#define mask_b(b) ((u32)(b) & 0x3FFF)
  181279. +
  181280. +/* Pls keep S0, S1 and S2 as 0x2 by using this convertion */
  181281. +static int _rgb_to_yuv(int n, int red, int green, int blue)
  181282. +{
  181283. + int c;
  181284. + c = red * rgb2ycbcr_coeff[n][0];
  181285. + c += green * rgb2ycbcr_coeff[n][1];
  181286. + c += blue * rgb2ycbcr_coeff[n][2];
  181287. + c /= 16;
  181288. + c += rgb2ycbcr_coeff[3][n] * 4;
  181289. + c += 8;
  181290. + c /= 16;
  181291. + if (c < 0)
  181292. + c = 0;
  181293. + if (c > 255)
  181294. + c = 255;
  181295. + return c;
  181296. +}
  181297. +
  181298. +/*
  181299. + * Row is for BG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
  181300. + * Column is for FG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE
  181301. + */
  181302. +static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = {
  181303. +{{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} },
  181304. +{{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} },
  181305. +{{0, 0}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} },
  181306. +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {0, 0}, {0, 0}, {0, 0}, {0, 0} },
  181307. +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} }
  181308. +};
  181309. +
  181310. +void __ipu_dp_csc_setup(struct ipu_soc *ipu,
  181311. + int dp, struct dp_csc_param_t dp_csc_param,
  181312. + bool srm_mode_update)
  181313. +{
  181314. + u32 reg;
  181315. + const int (*coeff)[5][3];
  181316. +
  181317. + if (dp_csc_param.mode >= 0) {
  181318. + reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
  181319. + reg &= ~DP_COM_CONF_CSC_DEF_MASK;
  181320. + reg |= dp_csc_param.mode;
  181321. + ipu_dp_write(ipu, reg, DP_COM_CONF(dp));
  181322. + }
  181323. +
  181324. + coeff = dp_csc_param.coeff;
  181325. +
  181326. + if (coeff) {
  181327. + ipu_dp_write(ipu, mask_a((*coeff)[0][0]) |
  181328. + (mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp));
  181329. + ipu_dp_write(ipu, mask_a((*coeff)[0][2]) |
  181330. + (mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp));
  181331. + ipu_dp_write(ipu, mask_a((*coeff)[1][1]) |
  181332. + (mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp));
  181333. + ipu_dp_write(ipu, mask_a((*coeff)[2][0]) |
  181334. + (mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp));
  181335. + ipu_dp_write(ipu, mask_a((*coeff)[2][2]) |
  181336. + (mask_b((*coeff)[3][0]) << 16) |
  181337. + ((*coeff)[4][0] << 30), DP_CSC_0(dp));
  181338. + ipu_dp_write(ipu, mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) |
  181339. + (mask_b((*coeff)[3][2]) << 16) |
  181340. + ((*coeff)[4][2] << 30), DP_CSC_1(dp));
  181341. + }
  181342. +
  181343. + if (srm_mode_update) {
  181344. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  181345. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  181346. + }
  181347. +}
  181348. +
  181349. +int _ipu_dp_init(struct ipu_soc *ipu,
  181350. + ipu_channel_t channel, uint32_t in_pixel_fmt,
  181351. + uint32_t out_pixel_fmt)
  181352. +{
  181353. + int in_fmt, out_fmt;
  181354. + int dp;
  181355. + int partial = false;
  181356. + uint32_t reg;
  181357. +
  181358. + if (channel == MEM_FG_SYNC) {
  181359. + dp = DP_SYNC;
  181360. + partial = true;
  181361. + } else if (channel == MEM_BG_SYNC) {
  181362. + dp = DP_SYNC;
  181363. + partial = false;
  181364. + } else if (channel == MEM_BG_ASYNC0) {
  181365. + dp = DP_ASYNC0;
  181366. + partial = false;
  181367. + } else {
  181368. + return -EINVAL;
  181369. + }
  181370. +
  181371. + in_fmt = format_to_colorspace(in_pixel_fmt);
  181372. + out_fmt = format_to_colorspace(out_pixel_fmt);
  181373. +
  181374. + if (partial) {
  181375. + if (in_fmt == RGB) {
  181376. + if (out_fmt == RGB)
  181377. + ipu->fg_csc_type = RGB2RGB;
  181378. + else
  181379. + ipu->fg_csc_type = RGB2YUV;
  181380. + } else {
  181381. + if (out_fmt == RGB)
  181382. + ipu->fg_csc_type = YUV2RGB;
  181383. + else
  181384. + ipu->fg_csc_type = YUV2YUV;
  181385. + }
  181386. + } else {
  181387. + if (in_fmt == RGB) {
  181388. + if (out_fmt == RGB)
  181389. + ipu->bg_csc_type = RGB2RGB;
  181390. + else
  181391. + ipu->bg_csc_type = RGB2YUV;
  181392. + } else {
  181393. + if (out_fmt == RGB)
  181394. + ipu->bg_csc_type = YUV2RGB;
  181395. + else
  181396. + ipu->bg_csc_type = YUV2YUV;
  181397. + }
  181398. + }
  181399. +
  181400. + /* Transform color key from rgb to yuv if CSC is enabled */
  181401. + reg = ipu_dp_read(ipu, DP_COM_CONF(dp));
  181402. + if (ipu->color_key_4rgb && (reg & DP_COM_CONF_GWCKE) &&
  181403. + (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  181404. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
  181405. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  181406. + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB)))) {
  181407. + int red, green, blue;
  181408. + int y, u, v;
  181409. + uint32_t color_key = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFFFFFFL;
  181410. +
  181411. + dev_dbg(ipu->dev, "_ipu_dp_init color key 0x%x need change to yuv fmt!\n", color_key);
  181412. +
  181413. + red = (color_key >> 16) & 0xFF;
  181414. + green = (color_key >> 8) & 0xFF;
  181415. + blue = color_key & 0xFF;
  181416. +
  181417. + y = _rgb_to_yuv(0, red, green, blue);
  181418. + u = _rgb_to_yuv(1, red, green, blue);
  181419. + v = _rgb_to_yuv(2, red, green, blue);
  181420. + color_key = (y << 16) | (u << 8) | v;
  181421. +
  181422. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L;
  181423. + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(dp));
  181424. + ipu->color_key_4rgb = false;
  181425. +
  181426. + dev_dbg(ipu->dev, "_ipu_dp_init color key change to yuv fmt 0x%x!\n", color_key);
  181427. + }
  181428. +
  181429. + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], true);
  181430. +
  181431. + return 0;
  181432. +}
  181433. +
  181434. +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel)
  181435. +{
  181436. + int dp;
  181437. + int partial = false;
  181438. +
  181439. + if (channel == MEM_FG_SYNC) {
  181440. + dp = DP_SYNC;
  181441. + partial = true;
  181442. + } else if (channel == MEM_BG_SYNC) {
  181443. + dp = DP_SYNC;
  181444. + partial = false;
  181445. + } else if (channel == MEM_BG_ASYNC0) {
  181446. + dp = DP_ASYNC0;
  181447. + partial = false;
  181448. + } else {
  181449. + return;
  181450. + }
  181451. +
  181452. + if (partial)
  181453. + ipu->fg_csc_type = CSC_NONE;
  181454. + else
  181455. + ipu->bg_csc_type = CSC_NONE;
  181456. +
  181457. + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], false);
  181458. +}
  181459. +
  181460. +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt)
  181461. +{
  181462. + u32 reg = 0;
  181463. +
  181464. + if ((dc_chan == 1) || (dc_chan == 5)) {
  181465. + if (interlaced) {
  181466. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 3);
  181467. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 2);
  181468. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 1);
  181469. + } else {
  181470. + if (di) {
  181471. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 2, 3);
  181472. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 3, 2);
  181473. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 1, 1);
  181474. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  181475. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  181476. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  181477. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  181478. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 9, 5);
  181479. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 8, 5);
  181480. + }
  181481. + } else {
  181482. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 5, 3);
  181483. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 6, 2);
  181484. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 12, 1);
  181485. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  181486. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  181487. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  181488. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  181489. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 10, 5);
  181490. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 11, 5);
  181491. + }
  181492. + }
  181493. + }
  181494. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
  181495. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
  181496. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
  181497. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
  181498. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
  181499. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
  181500. +
  181501. + reg = 0x2;
  181502. + reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
  181503. + reg |= di << 2;
  181504. + if (interlaced)
  181505. + reg |= DC_WR_CH_CONF_FIELD_MODE;
  181506. + } else if ((dc_chan == 8) || (dc_chan == 9)) {
  181507. + /* async channels */
  181508. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1);
  181509. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1);
  181510. +
  181511. + reg = 0x3;
  181512. + reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
  181513. + }
  181514. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  181515. +
  181516. + ipu_dc_write(ipu, 0x00000000, DC_WR_CH_ADDR(dc_chan));
  181517. +
  181518. + ipu_dc_write(ipu, 0x00000084, DC_GEN);
  181519. +}
  181520. +
  181521. +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan)
  181522. +{
  181523. + if ((dc_chan == 1) || (dc_chan == 5)) {
  181524. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 0);
  181525. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 0);
  181526. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 0);
  181527. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0);
  181528. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0);
  181529. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0);
  181530. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0);
  181531. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0);
  181532. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0);
  181533. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 0, 0);
  181534. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 0, 0);
  181535. + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 0, 0);
  181536. + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE1, 0, 0);
  181537. + } else if ((dc_chan == 8) || (dc_chan == 9)) {
  181538. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0);
  181539. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0);
  181540. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0);
  181541. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0);
  181542. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0);
  181543. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0);
  181544. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0);
  181545. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0);
  181546. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0);
  181547. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0);
  181548. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0);
  181549. + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0);
  181550. + }
  181551. +}
  181552. +
  181553. +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel)
  181554. +{
  181555. + if (channel == MEM_DC_SYNC)
  181556. + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_1) &
  181557. + DC_WR_CH_CONF_FIELD_MODE);
  181558. + else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))
  181559. + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_5) &
  181560. + DC_WR_CH_CONF_FIELD_MODE);
  181561. + return 0;
  181562. +}
  181563. +
  181564. +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel)
  181565. +{
  181566. + int di;
  181567. + uint32_t reg;
  181568. + uint32_t dc_chan;
  181569. + int irq = 0;
  181570. +
  181571. + if (channel == MEM_FG_SYNC)
  181572. + irq = IPU_IRQ_DP_SF_END;
  181573. + else if (channel == MEM_DC_SYNC)
  181574. + dc_chan = 1;
  181575. + else if (channel == MEM_BG_SYNC)
  181576. + dc_chan = 5;
  181577. + else
  181578. + return;
  181579. +
  181580. + if (channel == MEM_FG_SYNC) {
  181581. + /* Enable FG channel */
  181582. + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
  181583. + ipu_dp_write(ipu, reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC));
  181584. +
  181585. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  181586. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  181587. + return;
  181588. + } else if (channel == MEM_BG_SYNC) {
  181589. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  181590. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  181591. + }
  181592. +
  181593. + di = ipu->dc_di_assignment[dc_chan];
  181594. +
  181595. + /* Make sure other DC sync channel is not assigned same DI */
  181596. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(6 - dc_chan));
  181597. + if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) {
  181598. + reg &= ~DC_WR_CH_CONF_PROG_DI_ID;
  181599. + reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID;
  181600. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
  181601. + }
  181602. +
  181603. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  181604. + reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET;
  181605. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  181606. +
  181607. + clk_prepare_enable(ipu->pixel_clk[di]);
  181608. +}
  181609. +
  181610. +static irqreturn_t dc_irq_handler(int irq, void *dev_id)
  181611. +{
  181612. + struct ipu_soc *ipu = dev_id;
  181613. + struct completion *comp = &ipu->dc_comp;
  181614. + uint32_t reg;
  181615. + uint32_t dc_chan;
  181616. +
  181617. + if (irq == IPU_IRQ_DC_FC_1)
  181618. + dc_chan = 1;
  181619. + else
  181620. + dc_chan = 5;
  181621. +
  181622. + if (!ipu->dc_swap) {
  181623. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  181624. + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
  181625. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  181626. +
  181627. + reg = ipu_cm_read(ipu, IPU_DISP_GEN);
  181628. + if (ipu->dc_di_assignment[dc_chan])
  181629. + reg &= ~DI1_COUNTER_RELEASE;
  181630. + else
  181631. + reg &= ~DI0_COUNTER_RELEASE;
  181632. + ipu_cm_write(ipu, reg, IPU_DISP_GEN);
  181633. + }
  181634. +
  181635. + complete(comp);
  181636. + return IRQ_HANDLED;
  181637. +}
  181638. +
  181639. +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap)
  181640. +{
  181641. + int ret;
  181642. + uint32_t reg;
  181643. + uint32_t csc;
  181644. + uint32_t dc_chan;
  181645. + int irq = 0;
  181646. + int timeout = 50;
  181647. +
  181648. + ipu->dc_swap = swap;
  181649. +
  181650. + if (channel == MEM_DC_SYNC) {
  181651. + dc_chan = 1;
  181652. + irq = IPU_IRQ_DC_FC_1;
  181653. + } else if (channel == MEM_BG_SYNC) {
  181654. + dc_chan = 5;
  181655. + irq = IPU_IRQ_DP_SF_END;
  181656. + } else if (channel == MEM_FG_SYNC) {
  181657. + /* Disable FG channel */
  181658. + dc_chan = 5;
  181659. +
  181660. + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC));
  181661. + csc = reg & DP_COM_CONF_CSC_DEF_MASK;
  181662. + if (csc == DP_COM_CONF_CSC_DEF_FG)
  181663. + reg &= ~DP_COM_CONF_CSC_DEF_MASK;
  181664. +
  181665. + reg &= ~DP_COM_CONF_FG_EN;
  181666. + ipu_dp_write(ipu, reg, DP_COM_CONF(DP_SYNC));
  181667. +
  181668. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  181669. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  181670. +
  181671. + if (ipu_is_channel_busy(ipu, MEM_BG_SYNC)) {
  181672. + ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END),
  181673. + IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END));
  181674. + while ((ipu_cm_read(ipu, IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)) &
  181675. + IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END)) == 0) {
  181676. + msleep(2);
  181677. + timeout -= 2;
  181678. + if (timeout <= 0)
  181679. + break;
  181680. + }
  181681. + }
  181682. + return;
  181683. + } else {
  181684. + return;
  181685. + }
  181686. +
  181687. + init_completion(&ipu->dc_comp);
  181688. + ret = ipu_request_irq(ipu, irq, dc_irq_handler, 0, NULL, ipu);
  181689. + if (ret < 0) {
  181690. + dev_err(ipu->dev, "DC irq %d in use\n", irq);
  181691. + return;
  181692. + }
  181693. + ret = wait_for_completion_timeout(&ipu->dc_comp, msecs_to_jiffies(50));
  181694. + ipu_free_irq(ipu, irq, ipu);
  181695. + dev_dbg(ipu->dev, "DC stop timeout - %d * 10ms\n", 5 - ret);
  181696. +
  181697. + if (ipu->dc_swap) {
  181698. + /* Swap DC channel 1 and 5 settings, and disable old dc chan */
  181699. + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan));
  181700. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan));
  181701. + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
  181702. + reg ^= DC_WR_CH_CONF_PROG_DI_ID;
  181703. + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan));
  181704. + }
  181705. +}
  181706. +
  181707. +void _ipu_init_dc_mappings(struct ipu_soc *ipu)
  181708. +{
  181709. + /* IPU_PIX_FMT_RGB24 */
  181710. + _ipu_dc_map_clear(ipu, 0);
  181711. + _ipu_dc_map_config(ipu, 0, 0, 7, 0xFF);
  181712. + _ipu_dc_map_config(ipu, 0, 1, 15, 0xFF);
  181713. + _ipu_dc_map_config(ipu, 0, 2, 23, 0xFF);
  181714. +
  181715. + /* IPU_PIX_FMT_RGB666 */
  181716. + _ipu_dc_map_clear(ipu, 1);
  181717. + _ipu_dc_map_config(ipu, 1, 0, 5, 0xFC);
  181718. + _ipu_dc_map_config(ipu, 1, 1, 11, 0xFC);
  181719. + _ipu_dc_map_config(ipu, 1, 2, 17, 0xFC);
  181720. +
  181721. + /* IPU_PIX_FMT_YUV444 */
  181722. + _ipu_dc_map_clear(ipu, 2);
  181723. + _ipu_dc_map_config(ipu, 2, 0, 15, 0xFF);
  181724. + _ipu_dc_map_config(ipu, 2, 1, 23, 0xFF);
  181725. + _ipu_dc_map_config(ipu, 2, 2, 7, 0xFF);
  181726. +
  181727. + /* IPU_PIX_FMT_RGB565 */
  181728. + _ipu_dc_map_clear(ipu, 3);
  181729. + _ipu_dc_map_config(ipu, 3, 0, 4, 0xF8);
  181730. + _ipu_dc_map_config(ipu, 3, 1, 10, 0xFC);
  181731. + _ipu_dc_map_config(ipu, 3, 2, 15, 0xF8);
  181732. +
  181733. + /* IPU_PIX_FMT_LVDS666 */
  181734. + _ipu_dc_map_clear(ipu, 4);
  181735. + _ipu_dc_map_config(ipu, 4, 0, 5, 0xFC);
  181736. + _ipu_dc_map_config(ipu, 4, 1, 13, 0xFC);
  181737. + _ipu_dc_map_config(ipu, 4, 2, 21, 0xFC);
  181738. +
  181739. + /* IPU_PIX_FMT_VYUY 16bit width */
  181740. + _ipu_dc_map_clear(ipu, 5);
  181741. + _ipu_dc_map_config(ipu, 5, 0, 7, 0xFF);
  181742. + _ipu_dc_map_config(ipu, 5, 1, 0, 0x0);
  181743. + _ipu_dc_map_config(ipu, 5, 2, 15, 0xFF);
  181744. + _ipu_dc_map_clear(ipu, 6);
  181745. + _ipu_dc_map_config(ipu, 6, 0, 0, 0x0);
  181746. + _ipu_dc_map_config(ipu, 6, 1, 7, 0xFF);
  181747. + _ipu_dc_map_config(ipu, 6, 2, 15, 0xFF);
  181748. +
  181749. + /* IPU_PIX_FMT_UYUV 16bit width */
  181750. + _ipu_dc_map_clear(ipu, 7);
  181751. + _ipu_dc_map_link(ipu, 7, 6, 0, 6, 1, 6, 2);
  181752. + _ipu_dc_map_clear(ipu, 8);
  181753. + _ipu_dc_map_link(ipu, 8, 5, 0, 5, 1, 5, 2);
  181754. +
  181755. + /* IPU_PIX_FMT_YUYV 16bit width */
  181756. + _ipu_dc_map_clear(ipu, 9);
  181757. + _ipu_dc_map_link(ipu, 9, 5, 2, 5, 1, 5, 0);
  181758. + _ipu_dc_map_clear(ipu, 10);
  181759. + _ipu_dc_map_link(ipu, 10, 5, 1, 5, 2, 5, 0);
  181760. +
  181761. + /* IPU_PIX_FMT_YVYU 16bit width */
  181762. + _ipu_dc_map_clear(ipu, 11);
  181763. + _ipu_dc_map_link(ipu, 11, 5, 1, 5, 2, 5, 0);
  181764. + _ipu_dc_map_clear(ipu, 12);
  181765. + _ipu_dc_map_link(ipu, 12, 5, 2, 5, 1, 5, 0);
  181766. +
  181767. + /* IPU_PIX_FMT_GBR24 */
  181768. + /* IPU_PIX_FMT_VYU444 */
  181769. + _ipu_dc_map_clear(ipu, 13);
  181770. + _ipu_dc_map_link(ipu, 13, 0, 2, 0, 0, 0, 1);
  181771. +
  181772. + /* IPU_PIX_FMT_BGR24 */
  181773. + _ipu_dc_map_clear(ipu, 14);
  181774. + _ipu_dc_map_link(ipu, 14, 0, 2, 0, 1, 0, 0);
  181775. +}
  181776. +
  181777. +int _ipu_pixfmt_to_map(uint32_t fmt)
  181778. +{
  181779. + switch (fmt) {
  181780. + case IPU_PIX_FMT_GENERIC:
  181781. + case IPU_PIX_FMT_RGB24:
  181782. + return 0;
  181783. + case IPU_PIX_FMT_RGB666:
  181784. + return 1;
  181785. + case IPU_PIX_FMT_YUV444:
  181786. + return 2;
  181787. + case IPU_PIX_FMT_RGB565:
  181788. + return 3;
  181789. + case IPU_PIX_FMT_LVDS666:
  181790. + return 4;
  181791. + case IPU_PIX_FMT_VYUY:
  181792. + return 6;
  181793. + case IPU_PIX_FMT_UYVY:
  181794. + return 8;
  181795. + case IPU_PIX_FMT_YUYV:
  181796. + return 10;
  181797. + case IPU_PIX_FMT_YVYU:
  181798. + return 12;
  181799. + case IPU_PIX_FMT_GBR24:
  181800. + case IPU_PIX_FMT_VYU444:
  181801. + return 13;
  181802. + case IPU_PIX_FMT_BGR24:
  181803. + return 14;
  181804. + }
  181805. +
  181806. + return -1;
  181807. +}
  181808. +
  181809. +/*!
  181810. + * This function sets the colorspace for of dp.
  181811. + * modes.
  181812. + *
  181813. + * @param ipu ipu handler
  181814. + * @param channel Input parameter for the logical channel ID.
  181815. + *
  181816. + * @param param If it's not NULL, update the csc table
  181817. + * with this parameter.
  181818. + *
  181819. + * @return N/A
  181820. + */
  181821. +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
  181822. +{
  181823. + int dp;
  181824. + struct dp_csc_param_t dp_csc_param;
  181825. +
  181826. + if (channel == MEM_FG_SYNC)
  181827. + dp = DP_SYNC;
  181828. + else if (channel == MEM_BG_SYNC)
  181829. + dp = DP_SYNC;
  181830. + else if (channel == MEM_BG_ASYNC0)
  181831. + dp = DP_ASYNC0;
  181832. + else
  181833. + return;
  181834. +
  181835. + dp_csc_param.mode = -1;
  181836. + dp_csc_param.coeff = param;
  181837. + __ipu_dp_csc_setup(ipu, dp, dp_csc_param, true);
  181838. +}
  181839. +
  181840. +void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3])
  181841. +{
  181842. + _ipu_dp_set_csc_coefficients(ipu, channel, param);
  181843. +}
  181844. +EXPORT_SYMBOL(ipu_set_csc_coefficients);
  181845. +
  181846. +/*!
  181847. + * This function is called to adapt synchronous LCD panel to IPU restriction.
  181848. + *
  181849. + */
  181850. +void adapt_panel_to_ipu_restricitions(struct ipu_soc *ipu, uint16_t *v_start_width,
  181851. + uint16_t *v_sync_width,
  181852. + uint16_t *v_end_width)
  181853. +{
  181854. + if (*v_end_width < 2) {
  181855. + uint16_t diff = 2 - *v_end_width;
  181856. + if (*v_start_width >= diff) {
  181857. + *v_end_width = 2;
  181858. + *v_start_width = *v_start_width - diff;
  181859. + } else if (*v_sync_width > diff) {
  181860. + *v_end_width = 2;
  181861. + *v_sync_width = *v_sync_width - diff;
  181862. + } else
  181863. + dev_err(ipu->dev, "WARNING: try to adapt timming, but failed\n");
  181864. + dev_err(ipu->dev, "WARNING: adapt panel end blank lines\n");
  181865. + }
  181866. +}
  181867. +
  181868. +/*!
  181869. + * This function is called to initialize a synchronous LCD panel.
  181870. + *
  181871. + * @param ipu ipu handler
  181872. + * @param disp The DI the panel is attached to.
  181873. + *
  181874. + * @param pixel_clk Desired pixel clock frequency in Hz.
  181875. + *
  181876. + * @param pixel_fmt Input parameter for pixel format of buffer.
  181877. + * Pixel format is a FOURCC ASCII code.
  181878. + *
  181879. + * @param width The width of panel in pixels.
  181880. + *
  181881. + * @param height The height of panel in pixels.
  181882. + *
  181883. + * @param hStartWidth The number of pixel clocks between the HSYNC
  181884. + * signal pulse and the start of valid data.
  181885. + *
  181886. + * @param hSyncWidth The width of the HSYNC signal in units of pixel
  181887. + * clocks.
  181888. + *
  181889. + * @param hEndWidth The number of pixel clocks between the end of
  181890. + * valid data and the HSYNC signal for next line.
  181891. + *
  181892. + * @param vStartWidth The number of lines between the VSYNC
  181893. + * signal pulse and the start of valid data.
  181894. + *
  181895. + * @param vSyncWidth The width of the VSYNC signal in units of lines
  181896. + *
  181897. + * @param vEndWidth The number of lines between the end of valid
  181898. + * data and the VSYNC signal for next frame.
  181899. + *
  181900. + * @param sig Bitfield of signal polarities for LCD interface.
  181901. + *
  181902. + * @return This function returns 0 on success or negative error code on
  181903. + * fail.
  181904. + */
  181905. +int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp, uint32_t pixel_clk,
  181906. + uint16_t width, uint16_t height,
  181907. + uint32_t pixel_fmt,
  181908. + uint16_t h_start_width, uint16_t h_sync_width,
  181909. + uint16_t h_end_width, uint16_t v_start_width,
  181910. + uint16_t v_sync_width, uint16_t v_end_width,
  181911. + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
  181912. +{
  181913. + uint32_t field0_offset = 0;
  181914. + uint32_t field1_offset;
  181915. + uint32_t reg;
  181916. + uint32_t di_gen, vsync_cnt;
  181917. + uint32_t div, rounded_pixel_clk;
  181918. + uint32_t h_total, v_total;
  181919. + int map;
  181920. + int ret;
  181921. + struct clk *ldb_di0_clk, *ldb_di1_clk;
  181922. + struct clk *di_parent;
  181923. +
  181924. + dev_dbg(ipu->dev, "panel size = %d x %d\n", width, height);
  181925. +
  181926. + if ((v_sync_width == 0) || (h_sync_width == 0))
  181927. + return -EINVAL;
  181928. +
  181929. + adapt_panel_to_ipu_restricitions(ipu, &v_start_width, &v_sync_width, &v_end_width);
  181930. + h_total = width + h_sync_width + h_start_width + h_end_width;
  181931. + v_total = height + v_sync_width + v_start_width + v_end_width;
  181932. +
  181933. + /* Init clocking */
  181934. + dev_dbg(ipu->dev, "pixel clk = %d\n", pixel_clk);
  181935. +
  181936. + di_parent = clk_get_parent(ipu->di_clk_sel[disp]);
  181937. + if (!di_parent) {
  181938. + dev_err(ipu->dev, "get di clk parent fail\n");
  181939. + return -EINVAL;
  181940. + }
  181941. + ldb_di0_clk = clk_get(ipu->dev, "ldb_di0");
  181942. + if (IS_ERR(ldb_di0_clk)) {
  181943. + dev_err(ipu->dev, "clk_get di0 failed");
  181944. + return PTR_ERR(ldb_di0_clk);
  181945. + }
  181946. + ldb_di1_clk = clk_get(ipu->dev, "ldb_di1");
  181947. + if (IS_ERR(ldb_di1_clk)) {
  181948. + dev_err(ipu->dev, "clk_get di1 failed");
  181949. + return PTR_ERR(ldb_di1_clk);
  181950. + }
  181951. +
  181952. + if (ldb_di0_clk == di_parent || ldb_di1_clk == di_parent) {
  181953. + /* if di clk parent is tve/ldb, then keep it;*/
  181954. + dev_dbg(ipu->dev, "use special clk parent\n");
  181955. + ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->di_clk[disp]);
  181956. + if (ret) {
  181957. + dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
  181958. + return ret;
  181959. + }
  181960. + clk_put(ldb_di0_clk);
  181961. + clk_put(ldb_di1_clk);
  181962. + } else {
  181963. + /* try ipu clk first*/
  181964. + dev_dbg(ipu->dev, "try ipu internal clk\n");
  181965. + ret = clk_set_parent(ipu->pixel_clk_sel[disp], ipu->ipu_clk);
  181966. + if (ret) {
  181967. + dev_err(ipu->dev, "set pixel clk error:%d\n", ret);
  181968. + return ret;
  181969. + }
  181970. + rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
  181971. + dev_dbg(ipu->dev, "rounded pix clk:%d\n", rounded_pixel_clk);
  181972. + /*
  181973. + * we will only use 1/2 fraction for ipu clk,
  181974. + * so if the clk rate is not fit, try ext clk.
  181975. + */
  181976. + if (!sig.int_clk &&
  181977. + ((rounded_pixel_clk >= pixel_clk + pixel_clk/200) ||
  181978. + (rounded_pixel_clk <= pixel_clk - pixel_clk/200))) {
  181979. + dev_dbg(ipu->dev, "try ipu ext di clk\n");
  181980. +
  181981. + rounded_pixel_clk =
  181982. + clk_round_rate(ipu->di_clk[disp], pixel_clk);
  181983. + ret = clk_set_rate(ipu->di_clk[disp],
  181984. + rounded_pixel_clk);
  181985. + if (ret) {
  181986. + dev_err(ipu->dev,
  181987. + "set di clk rate error:%d\n", ret);
  181988. + return ret;
  181989. + }
  181990. + dev_dbg(ipu->dev, "di clk:%d\n", rounded_pixel_clk);
  181991. + ret = clk_set_parent(ipu->pixel_clk_sel[disp],
  181992. + ipu->di_clk[disp]);
  181993. + if (ret) {
  181994. + dev_err(ipu->dev,
  181995. + "set pixel clk parent error:%d\n", ret);
  181996. + return ret;
  181997. + }
  181998. + }
  181999. + }
  182000. + rounded_pixel_clk = clk_round_rate(ipu->pixel_clk[disp], pixel_clk);
  182001. + dev_dbg(ipu->dev, "round pixel clk:%d\n", rounded_pixel_clk);
  182002. + ret = clk_set_rate(ipu->pixel_clk[disp], rounded_pixel_clk);
  182003. + if (ret) {
  182004. + dev_err(ipu->dev, "set pixel clk rate error:%d\n", ret);
  182005. + return ret;
  182006. + }
  182007. + msleep(5);
  182008. + /* Get integer portion of divider */
  182009. + div = clk_get_rate(clk_get_parent(ipu->pixel_clk_sel[disp])) / rounded_pixel_clk;
  182010. + dev_dbg(ipu->dev, "div:%d\n", div);
  182011. + if (!div) {
  182012. + dev_err(ipu->dev, "invalid pixel clk div = 0\n");
  182013. + return -EINVAL;
  182014. + }
  182015. +
  182016. +
  182017. + mutex_lock(&ipu->mutex_lock);
  182018. +
  182019. + _ipu_di_data_wave_config(ipu, disp, SYNC_WAVE, div - 1, div - 1);
  182020. + _ipu_di_data_pin_config(ipu, disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
  182021. +
  182022. + map = _ipu_pixfmt_to_map(pixel_fmt);
  182023. + if (map < 0) {
  182024. + dev_dbg(ipu->dev, "IPU_DISP: No MAP\n");
  182025. + mutex_unlock(&ipu->mutex_lock);
  182026. + return -EINVAL;
  182027. + }
  182028. +
  182029. + /*clear DI*/
  182030. + di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
  182031. + di_gen &= (0x3 << 20);
  182032. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  182033. +
  182034. + if (sig.interlaced) {
  182035. + if (g_ipu_hw_rev >= IPU_V3DEX) {
  182036. + /* Setup internal HSYNC waveform */
  182037. + _ipu_di_sync_config(ipu,
  182038. + disp, /* display */
  182039. + 1, /* counter */
  182040. + h_total/2 - 1, /* run count */
  182041. + DI_SYNC_CLK, /* run_resolution */
  182042. + 0, /* offset */
  182043. + DI_SYNC_NONE, /* offset resolution */
  182044. + 0, /* repeat count */
  182045. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  182046. + 0, /* CNT_POLARITY_GEN_EN */
  182047. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182048. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182049. + 0, /* COUNT UP */
  182050. + 0 /* COUNT DOWN */
  182051. + );
  182052. +
  182053. + /* Field 1 VSYNC waveform */
  182054. + _ipu_di_sync_config(ipu,
  182055. + disp, /* display */
  182056. + 2, /* counter */
  182057. + h_total - 1, /* run count */
  182058. + DI_SYNC_CLK, /* run_resolution */
  182059. + 0, /* offset */
  182060. + DI_SYNC_NONE, /* offset resolution */
  182061. + 0, /* repeat count */
  182062. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  182063. + 0, /* CNT_POLARITY_GEN_EN */
  182064. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182065. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182066. + 0, /* COUNT UP */
  182067. + 2*div /* COUNT DOWN */
  182068. + );
  182069. +
  182070. + /* Setup internal HSYNC waveform */
  182071. + _ipu_di_sync_config(ipu,
  182072. + disp, /* display */
  182073. + 3, /* counter */
  182074. + v_total*2 - 1, /* run count */
  182075. + DI_SYNC_INT_HSYNC, /* run_resolution */
  182076. + 1, /* offset */
  182077. + DI_SYNC_INT_HSYNC, /* offset resolution */
  182078. + 0, /* repeat count */
  182079. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  182080. + 0, /* CNT_POLARITY_GEN_EN */
  182081. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182082. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182083. + 0, /* COUNT UP */
  182084. + 2*div /* COUNT DOWN */
  182085. + );
  182086. +
  182087. + /* Active Field ? */
  182088. + _ipu_di_sync_config(ipu,
  182089. + disp, /* display */
  182090. + 4, /* counter */
  182091. + v_total/2 - 1, /* run count */
  182092. + DI_SYNC_HSYNC, /* run_resolution */
  182093. + v_start_width, /* offset */
  182094. + DI_SYNC_HSYNC, /* offset resolution */
  182095. + 2, /* repeat count */
  182096. + DI_SYNC_VSYNC, /* CNT_CLR_SEL */
  182097. + 0, /* CNT_POLARITY_GEN_EN */
  182098. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182099. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182100. + 0, /* COUNT UP */
  182101. + 0 /* COUNT DOWN */
  182102. + );
  182103. +
  182104. + /* Active Line */
  182105. + _ipu_di_sync_config(ipu,
  182106. + disp, /* display */
  182107. + 5, /* counter */
  182108. + 0, /* run count */
  182109. + DI_SYNC_HSYNC, /* run_resolution */
  182110. + 0, /* offset */
  182111. + DI_SYNC_NONE, /* offset resolution */
  182112. + height/2, /* repeat count */
  182113. + 4, /* CNT_CLR_SEL */
  182114. + 0, /* CNT_POLARITY_GEN_EN */
  182115. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182116. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182117. + 0, /* COUNT UP */
  182118. + 0 /* COUNT DOWN */
  182119. + );
  182120. +
  182121. + /* Field 0 VSYNC waveform */
  182122. + _ipu_di_sync_config(ipu,
  182123. + disp, /* display */
  182124. + 6, /* counter */
  182125. + v_total - 1, /* run count */
  182126. + DI_SYNC_HSYNC, /* run_resolution */
  182127. + 0, /* offset */
  182128. + DI_SYNC_NONE, /* offset resolution */
  182129. + 0, /* repeat count */
  182130. + DI_SYNC_NONE, /* CNT_CLR_SEL */
  182131. + 0, /* CNT_POLARITY_GEN_EN */
  182132. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182133. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182134. + 0, /* COUNT UP */
  182135. + 0 /* COUNT DOWN */
  182136. + );
  182137. +
  182138. + /* DC VSYNC waveform */
  182139. + vsync_cnt = 7;
  182140. + _ipu_di_sync_config(ipu,
  182141. + disp, /* display */
  182142. + 7, /* counter */
  182143. + v_total/2 - 1, /* run count */
  182144. + DI_SYNC_HSYNC, /* run_resolution */
  182145. + 9, /* offset */
  182146. + DI_SYNC_HSYNC, /* offset resolution */
  182147. + 2, /* repeat count */
  182148. + DI_SYNC_VSYNC, /* CNT_CLR_SEL */
  182149. + 0, /* CNT_POLARITY_GEN_EN */
  182150. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182151. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182152. + 0, /* COUNT UP */
  182153. + 0 /* COUNT DOWN */
  182154. + );
  182155. +
  182156. + /* active pixel waveform */
  182157. + _ipu_di_sync_config(ipu,
  182158. + disp, /* display */
  182159. + 8, /* counter */
  182160. + 0, /* run count */
  182161. + DI_SYNC_CLK, /* run_resolution */
  182162. + h_start_width, /* offset */
  182163. + DI_SYNC_CLK, /* offset resolution */
  182164. + width, /* repeat count */
  182165. + 5, /* CNT_CLR_SEL */
  182166. + 0, /* CNT_POLARITY_GEN_EN */
  182167. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182168. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182169. + 0, /* COUNT UP */
  182170. + 0 /* COUNT DOWN */
  182171. + );
  182172. +
  182173. + /* Second VSYNC */
  182174. + _ipu_di_sync_config(ipu,
  182175. + disp, /* display */
  182176. + 9, /* counter */
  182177. + v_total - 1, /* run count */
  182178. + DI_SYNC_INT_HSYNC, /* run_resolution */
  182179. + v_total/2, /* offset */
  182180. + DI_SYNC_INT_HSYNC, /* offset resolution */
  182181. + 0, /* repeat count */
  182182. + DI_SYNC_HSYNC, /* CNT_CLR_SEL */
  182183. + 0, /* CNT_POLARITY_GEN_EN */
  182184. + DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */
  182185. + DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */
  182186. + 0, /* COUNT UP */
  182187. + 2*div /* COUNT DOWN */
  182188. + );
  182189. +
  182190. + /* set gentime select and tag sel */
  182191. + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
  182192. + reg &= 0x1FFFFFFF;
  182193. + reg |= (3-1)<<29 | 0x00008000;
  182194. + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
  182195. +
  182196. + ipu_di_write(ipu, disp, v_total / 2 - 1, DI_SCR_CONF);
  182197. +
  182198. + /* set y_sel = 1 */
  182199. + di_gen |= 0x10000000;
  182200. + di_gen |= DI_GEN_POLARITY_5;
  182201. + di_gen |= DI_GEN_POLARITY_8;
  182202. + } else {
  182203. + /* Setup internal HSYNC waveform */
  182204. + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
  182205. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  182206. + DI_SYNC_NONE, 0, 0);
  182207. +
  182208. + field1_offset = v_sync_width + v_start_width + height / 2 +
  182209. + v_end_width;
  182210. + if (sig.odd_field_first) {
  182211. + field0_offset = field1_offset - 1;
  182212. + field1_offset = 0;
  182213. + }
  182214. + v_total += v_start_width + v_end_width;
  182215. +
  182216. + /* Field 1 VSYNC waveform */
  182217. + _ipu_di_sync_config(ipu, disp, 2, v_total - 1, 1,
  182218. + field0_offset,
  182219. + field0_offset ? 1 : DI_SYNC_NONE,
  182220. + 0, DI_SYNC_NONE, 0,
  182221. + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
  182222. +
  182223. + /* Setup internal HSYNC waveform */
  182224. + _ipu_di_sync_config(ipu, disp, 3, h_total - 1, DI_SYNC_CLK,
  182225. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0,
  182226. + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4);
  182227. +
  182228. + /* Active Field ? */
  182229. + _ipu_di_sync_config(ipu, disp, 4,
  182230. + field0_offset ?
  182231. + field0_offset : field1_offset - 2,
  182232. + 1, v_start_width + v_sync_width, 1, 2, 2,
  182233. + 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
  182234. +
  182235. + /* Active Line */
  182236. + _ipu_di_sync_config(ipu, disp, 5, 0, 1,
  182237. + 0, DI_SYNC_NONE,
  182238. + height / 2, 4, 0, DI_SYNC_NONE,
  182239. + DI_SYNC_NONE, 0, 0);
  182240. +
  182241. + /* Field 0 VSYNC waveform */
  182242. + _ipu_di_sync_config(ipu, disp, 6, v_total - 1, 1,
  182243. + 0, DI_SYNC_NONE,
  182244. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  182245. + DI_SYNC_NONE, 0, 0);
  182246. +
  182247. + /* DC VSYNC waveform */
  182248. + vsync_cnt = 7;
  182249. + _ipu_di_sync_config(ipu, disp, 7, 0, 1,
  182250. + field1_offset,
  182251. + field1_offset ? 1 : DI_SYNC_NONE,
  182252. + 1, 2, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0);
  182253. +
  182254. + /* active pixel waveform */
  182255. + _ipu_di_sync_config(ipu, disp, 8, 0, DI_SYNC_CLK,
  182256. + h_sync_width + h_start_width, DI_SYNC_CLK,
  182257. + width, 5, 0, DI_SYNC_NONE, DI_SYNC_NONE,
  182258. + 0, 0);
  182259. +
  182260. + /* ??? */
  182261. + _ipu_di_sync_config(ipu, disp, 9, v_total - 1, 2,
  182262. + 0, DI_SYNC_NONE,
  182263. + 0, DI_SYNC_NONE, 6, DI_SYNC_NONE,
  182264. + DI_SYNC_NONE, 0, 0);
  182265. +
  182266. + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9));
  182267. + reg |= 0x8000;
  182268. + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9));
  182269. +
  182270. + ipu_di_write(ipu, disp, v_sync_width + v_start_width +
  182271. + v_end_width + height / 2 - 1, DI_SCR_CONF);
  182272. + }
  182273. +
  182274. + /* Init template microcode */
  182275. + _ipu_dc_write_tmpl(ipu, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
  182276. +
  182277. + if (sig.Hsync_pol)
  182278. + di_gen |= DI_GEN_POLARITY_3;
  182279. + if (sig.Vsync_pol)
  182280. + di_gen |= DI_GEN_POLARITY_2;
  182281. + } else {
  182282. + /* Setup internal HSYNC waveform */
  182283. + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK,
  182284. + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
  182285. + DI_SYNC_NONE, 0, 0);
  182286. +
  182287. + /* Setup external (delayed) HSYNC waveform */
  182288. + _ipu_di_sync_config(ipu, disp, DI_SYNC_HSYNC, h_total - 1,
  182289. + DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK,
  182290. + 0, DI_SYNC_NONE, 1, DI_SYNC_NONE,
  182291. + DI_SYNC_CLK, 0, h_sync_width * 2);
  182292. + /* Setup VSYNC waveform */
  182293. + vsync_cnt = DI_SYNC_VSYNC;
  182294. + _ipu_di_sync_config(ipu, disp, DI_SYNC_VSYNC, v_total - 1,
  182295. + DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0,
  182296. + DI_SYNC_NONE, 1, DI_SYNC_NONE,
  182297. + DI_SYNC_INT_HSYNC, 0, v_sync_width * 2);
  182298. + ipu_di_write(ipu, disp, v_total - 1, DI_SCR_CONF);
  182299. +
  182300. + /* Setup active data waveform to sync with DC */
  182301. + _ipu_di_sync_config(ipu, disp, 4, 0, DI_SYNC_HSYNC,
  182302. + v_sync_width + v_start_width, DI_SYNC_HSYNC, height,
  182303. + DI_SYNC_VSYNC, 0, DI_SYNC_NONE,
  182304. + DI_SYNC_NONE, 0, 0);
  182305. + _ipu_di_sync_config(ipu, disp, 5, 0, DI_SYNC_CLK,
  182306. + h_sync_width + h_start_width, DI_SYNC_CLK,
  182307. + width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0,
  182308. + 0);
  182309. +
  182310. + /* set VGA delayed hsync/vsync no matter VGA enabled */
  182311. + if (disp) {
  182312. + /* couter 7 for VGA delay HSYNC */
  182313. + _ipu_di_sync_config(ipu, disp, 7,
  182314. + h_total - 1, DI_SYNC_CLK,
  182315. + 18, DI_SYNC_CLK,
  182316. + 0, DI_SYNC_NONE,
  182317. + 1, DI_SYNC_NONE, DI_SYNC_CLK,
  182318. + 0, h_sync_width * 2);
  182319. +
  182320. + /* couter 8 for VGA delay VSYNC */
  182321. + _ipu_di_sync_config(ipu, disp, 8,
  182322. + v_total - 1, DI_SYNC_INT_HSYNC,
  182323. + 1, DI_SYNC_INT_HSYNC,
  182324. + 0, DI_SYNC_NONE,
  182325. + 1, DI_SYNC_NONE, DI_SYNC_INT_HSYNC,
  182326. + 0, v_sync_width * 2);
  182327. + }
  182328. +
  182329. + /* reset all unused counters */
  182330. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(6));
  182331. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(6));
  182332. + if (!disp) {
  182333. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(7));
  182334. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(7));
  182335. + ipu_di_write(ipu, disp, 0, DI_STP_REP(7));
  182336. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(8));
  182337. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(8));
  182338. + ipu_di_write(ipu, disp, 0, DI_STP_REP(8));
  182339. + }
  182340. + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(9));
  182341. + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(9));
  182342. + ipu_di_write(ipu, disp, 0, DI_STP_REP(9));
  182343. +
  182344. + reg = ipu_di_read(ipu, disp, DI_STP_REP(6));
  182345. + reg &= 0x0000FFFF;
  182346. + ipu_di_write(ipu, disp, reg, DI_STP_REP(6));
  182347. +
  182348. + /* Init template microcode */
  182349. + if (disp) {
  182350. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  182351. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  182352. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  182353. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  182354. + _ipu_dc_write_tmpl(ipu, 8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
  182355. + _ipu_dc_write_tmpl(ipu, 9, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  182356. + /* configure user events according to DISP NUM */
  182357. + ipu_dc_write(ipu, (width - 1), DC_UGDE_3(disp));
  182358. + }
  182359. + _ipu_dc_write_tmpl(ipu, 2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
  182360. + _ipu_dc_write_tmpl(ipu, 3, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
  182361. + _ipu_dc_write_tmpl(ipu, 4, WRG, 0, map, NULL_WAVE, 0, 0, 1);
  182362. + _ipu_dc_write_tmpl(ipu, 1, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  182363. +
  182364. + } else {
  182365. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  182366. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  182367. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  182368. + (pixel_fmt == IPU_PIX_FMT_VYUY)) {
  182369. + _ipu_dc_write_tmpl(ipu, 10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
  182370. + _ipu_dc_write_tmpl(ipu, 11, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  182371. + /* configure user events according to DISP NUM */
  182372. + ipu_dc_write(ipu, width - 1, DC_UGDE_3(disp));
  182373. + }
  182374. + _ipu_dc_write_tmpl(ipu, 5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
  182375. + _ipu_dc_write_tmpl(ipu, 6, WROD(0), 0, map, SYNC_WAVE, 4, 5, 0);
  182376. + _ipu_dc_write_tmpl(ipu, 7, WRG, 0, map, NULL_WAVE, 0, 0, 1);
  182377. + _ipu_dc_write_tmpl(ipu, 12, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
  182378. + }
  182379. +
  182380. + if (sig.Hsync_pol) {
  182381. + di_gen |= DI_GEN_POLARITY_2;
  182382. + if (disp)
  182383. + di_gen |= DI_GEN_POLARITY_7;
  182384. + }
  182385. + if (sig.Vsync_pol) {
  182386. + di_gen |= DI_GEN_POLARITY_3;
  182387. + if (disp)
  182388. + di_gen |= DI_GEN_POLARITY_8;
  182389. + }
  182390. + }
  182391. + /* changinc DISP_CLK polarity: it can be wrong for some applications */
  182392. + if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
  182393. + (pixel_fmt == IPU_PIX_FMT_UYVY) ||
  182394. + (pixel_fmt == IPU_PIX_FMT_YVYU) ||
  182395. + (pixel_fmt == IPU_PIX_FMT_VYUY))
  182396. + di_gen |= 0x00020000;
  182397. +
  182398. + if (!sig.clk_pol)
  182399. + di_gen |= DI_GEN_POLARITY_DISP_CLK;
  182400. +
  182401. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  182402. +
  182403. + ipu_di_write(ipu, disp, (--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
  182404. + 0x00000002, DI_SYNC_AS_GEN);
  182405. + reg = ipu_di_read(ipu, disp, DI_POL);
  182406. + reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
  182407. + if (sig.enable_pol)
  182408. + reg |= DI_POL_DRDY_POLARITY_15;
  182409. + if (sig.data_pol)
  182410. + reg |= DI_POL_DRDY_DATA_POLARITY;
  182411. + ipu_di_write(ipu, disp, reg, DI_POL);
  182412. +
  182413. + ipu_dc_write(ipu, width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp)));
  182414. +
  182415. + mutex_unlock(&ipu->mutex_lock);
  182416. +
  182417. + return 0;
  182418. +}
  182419. +EXPORT_SYMBOL(ipu_init_sync_panel);
  182420. +
  182421. +void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp)
  182422. +{
  182423. + uint32_t reg;
  182424. + uint32_t di_gen;
  182425. +
  182426. + if ((disp != 0) || (disp != 1))
  182427. + return;
  182428. +
  182429. + mutex_lock(&ipu->mutex_lock);
  182430. +
  182431. + di_gen = ipu_di_read(ipu, disp, DI_GENERAL);
  182432. + di_gen |= 0x3ff | DI_GEN_POLARITY_DISP_CLK;
  182433. + ipu_di_write(ipu, disp, di_gen, DI_GENERAL);
  182434. +
  182435. + reg = ipu_di_read(ipu, disp, DI_POL);
  182436. + reg |= 0x3ffffff;
  182437. + ipu_di_write(ipu, disp, reg, DI_POL);
  182438. +
  182439. + mutex_unlock(&ipu->mutex_lock);
  182440. +}
  182441. +EXPORT_SYMBOL(ipu_uninit_sync_panel);
  182442. +
  182443. +int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
  182444. + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig)
  182445. +{
  182446. + int map;
  182447. + u32 ser_conf = 0;
  182448. + u32 div;
  182449. + u32 di_clk = clk_get_rate(ipu->ipu_clk);
  182450. +
  182451. + /* round up cycle_time, then calcalate the divider using scaled math */
  182452. + cycle_time += (1000000000UL / di_clk) - 1;
  182453. + div = (cycle_time * (di_clk / 256UL)) / (1000000000UL / 256UL);
  182454. +
  182455. + map = _ipu_pixfmt_to_map(pixel_fmt);
  182456. + if (map < 0)
  182457. + return -EINVAL;
  182458. +
  182459. + mutex_lock(&ipu->mutex_lock);
  182460. +
  182461. + if (type == IPU_PANEL_SERIAL) {
  182462. + ipu_di_write(ipu, disp, (div << 24) | ((sig.ifc_width - 1) << 4),
  182463. + DI_DW_GEN(ASYNC_SER_WAVE));
  182464. +
  182465. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_CS,
  182466. + 0, 0, (div * 2) + 1);
  182467. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_CLK,
  182468. + 1, div, div * 2);
  182469. + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_RS,
  182470. + 2, 0, 0);
  182471. +
  182472. + _ipu_dc_write_tmpl(ipu, 0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0, 1);
  182473. +
  182474. + /* Configure DC for serial panel */
  182475. + ipu_dc_write(ipu, 0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL));
  182476. +
  182477. + if (sig.clk_pol)
  182478. + ser_conf |= DI_SER_CONF_SERIAL_CLK_POL;
  182479. + if (sig.data_pol)
  182480. + ser_conf |= DI_SER_CONF_SERIAL_DATA_POL;
  182481. + if (sig.rs_pol)
  182482. + ser_conf |= DI_SER_CONF_SERIAL_RS_POL;
  182483. + if (sig.cs_pol)
  182484. + ser_conf |= DI_SER_CONF_SERIAL_CS_POL;
  182485. + ipu_di_write(ipu, disp, ser_conf, DI_SER_CONF);
  182486. + }
  182487. +
  182488. + mutex_unlock(&ipu->mutex_lock);
  182489. + return 0;
  182490. +}
  182491. +EXPORT_SYMBOL(ipu_init_async_panel);
  182492. +
  182493. +/*!
  182494. + * This function sets the foreground and background plane global alpha blending
  182495. + * modes. This function also sets the DP graphic plane according to the
  182496. + * parameter of IPUv3 DP channel.
  182497. + *
  182498. + * @param ipu ipu handler
  182499. + * @param channel IPUv3 DP channel
  182500. + *
  182501. + * @param enable Boolean to enable or disable global alpha
  182502. + * blending. If disabled, local blending is used.
  182503. + *
  182504. + * @param alpha Global alpha value.
  182505. + *
  182506. + * @return Returns 0 on success or negative error code on fail
  182507. + */
  182508. +int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel,
  182509. + bool enable, uint8_t alpha)
  182510. +{
  182511. + uint32_t reg;
  182512. + uint32_t flow;
  182513. + bool bg_chan;
  182514. +
  182515. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  182516. + flow = DP_SYNC;
  182517. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  182518. + flow = DP_ASYNC0;
  182519. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  182520. + flow = DP_ASYNC1;
  182521. + else
  182522. + return -EINVAL;
  182523. +
  182524. + if (channel == MEM_BG_SYNC || channel == MEM_BG_ASYNC0 ||
  182525. + channel == MEM_BG_ASYNC1)
  182526. + bg_chan = true;
  182527. + else
  182528. + bg_chan = false;
  182529. +
  182530. + _ipu_get(ipu);
  182531. +
  182532. + mutex_lock(&ipu->mutex_lock);
  182533. +
  182534. + if (bg_chan) {
  182535. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  182536. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
  182537. + } else {
  182538. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  182539. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
  182540. + }
  182541. +
  182542. + if (enable) {
  182543. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL;
  182544. + ipu_dp_write(ipu, reg | ((uint32_t) alpha << 24),
  182545. + DP_GRAPH_WIND_CTRL(flow));
  182546. +
  182547. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  182548. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow));
  182549. + } else {
  182550. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  182551. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow));
  182552. + }
  182553. +
  182554. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  182555. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  182556. +
  182557. + mutex_unlock(&ipu->mutex_lock);
  182558. +
  182559. + _ipu_put(ipu);
  182560. +
  182561. + return 0;
  182562. +}
  182563. +EXPORT_SYMBOL(ipu_disp_set_global_alpha);
  182564. +
  182565. +/*!
  182566. + * This function sets the transparent color key for SDC graphic plane.
  182567. + *
  182568. + * @param ipu ipu handler
  182569. + * @param channel Input parameter for the logical channel ID.
  182570. + *
  182571. + * @param enable Boolean to enable or disable color key
  182572. + *
  182573. + * @param colorKey 24-bit RGB color for transparent color key.
  182574. + *
  182575. + * @return Returns 0 on success or negative error code on fail
  182576. + */
  182577. +int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel,
  182578. + bool enable, uint32_t color_key)
  182579. +{
  182580. + uint32_t reg, flow;
  182581. + int y, u, v;
  182582. + int red, green, blue;
  182583. +
  182584. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  182585. + flow = DP_SYNC;
  182586. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  182587. + flow = DP_ASYNC0;
  182588. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  182589. + flow = DP_ASYNC1;
  182590. + else
  182591. + return -EINVAL;
  182592. +
  182593. + _ipu_get(ipu);
  182594. +
  182595. + mutex_lock(&ipu->mutex_lock);
  182596. +
  182597. + ipu->color_key_4rgb = true;
  182598. + /* Transform color key from rgb to yuv if CSC is enabled */
  182599. + if (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  182600. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) ||
  182601. + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) ||
  182602. + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB))) {
  182603. +
  182604. + dev_dbg(ipu->dev, "color key 0x%x need change to yuv fmt\n", color_key);
  182605. +
  182606. + red = (color_key >> 16) & 0xFF;
  182607. + green = (color_key >> 8) & 0xFF;
  182608. + blue = color_key & 0xFF;
  182609. +
  182610. + y = _rgb_to_yuv(0, red, green, blue);
  182611. + u = _rgb_to_yuv(1, red, green, blue);
  182612. + v = _rgb_to_yuv(2, red, green, blue);
  182613. + color_key = (y << 16) | (u << 8) | v;
  182614. +
  182615. + ipu->color_key_4rgb = false;
  182616. +
  182617. + dev_dbg(ipu->dev, "color key change to yuv fmt 0x%x\n", color_key);
  182618. + }
  182619. +
  182620. + if (enable) {
  182621. + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L;
  182622. + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(flow));
  182623. +
  182624. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  182625. + ipu_dp_write(ipu, reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
  182626. + } else {
  182627. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  182628. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
  182629. + }
  182630. +
  182631. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  182632. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  182633. +
  182634. + mutex_unlock(&ipu->mutex_lock);
  182635. +
  182636. + _ipu_put(ipu);
  182637. +
  182638. + return 0;
  182639. +}
  182640. +EXPORT_SYMBOL(ipu_disp_set_color_key);
  182641. +
  182642. +/*!
  182643. + * This function sets the gamma correction for DP output.
  182644. + *
  182645. + * @param ipu ipu handler
  182646. + * @param channel Input parameter for the logical channel ID.
  182647. + *
  182648. + * @param enable Boolean to enable or disable gamma correction.
  182649. + *
  182650. + * @param constk Gamma piecewise linear approximation constk coeff.
  182651. + *
  182652. + * @param slopek Gamma piecewise linear approximation slopek coeff.
  182653. + *
  182654. + * @return Returns 0 on success or negative error code on fail
  182655. + */
  182656. +int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable, int constk[], int slopek[])
  182657. +{
  182658. + uint32_t reg, flow, i;
  182659. +
  182660. + if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
  182661. + flow = DP_SYNC;
  182662. + else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
  182663. + flow = DP_ASYNC0;
  182664. + else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
  182665. + flow = DP_ASYNC1;
  182666. + else
  182667. + return -EINVAL;
  182668. +
  182669. + _ipu_get(ipu);
  182670. +
  182671. + mutex_lock(&ipu->mutex_lock);
  182672. +
  182673. + for (i = 0; i < 8; i++)
  182674. + ipu_dp_write(ipu, (constk[2*i] & 0x1ff) | ((constk[2*i+1] & 0x1ff) << 16), DP_GAMMA_C(flow, i));
  182675. + for (i = 0; i < 4; i++)
  182676. + ipu_dp_write(ipu, (slopek[4*i] & 0xff) | ((slopek[4*i+1] & 0xff) << 8) |
  182677. + ((slopek[4*i+2] & 0xff) << 16) | ((slopek[4*i+3] & 0xff) << 24), DP_GAMMA_S(flow, i));
  182678. +
  182679. + reg = ipu_dp_read(ipu, DP_COM_CONF(flow));
  182680. + if (enable) {
  182681. + if ((ipu->bg_csc_type == RGB2YUV) || (ipu->bg_csc_type == YUV2YUV))
  182682. + reg |= DP_COM_CONF_GAMMA_YUV_EN;
  182683. + else
  182684. + reg &= ~DP_COM_CONF_GAMMA_YUV_EN;
  182685. + ipu_dp_write(ipu, reg | DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
  182686. + } else
  182687. + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow));
  182688. +
  182689. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8;
  182690. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  182691. +
  182692. + mutex_unlock(&ipu->mutex_lock);
  182693. +
  182694. + _ipu_put(ipu);
  182695. +
  182696. + return 0;
  182697. +}
  182698. +EXPORT_SYMBOL(ipu_disp_set_gamma_correction);
  182699. +
  182700. +/*!
  182701. + * This function sets the window position of the foreground or background plane.
  182702. + * modes.
  182703. + *
  182704. + * @param ipu ipu handler
  182705. + * @param channel Input parameter for the logical channel ID.
  182706. + *
  182707. + * @param x_pos The X coordinate position to place window at.
  182708. + * The position is relative to the top left corner.
  182709. + *
  182710. + * @param y_pos The Y coordinate position to place window at.
  182711. + * The position is relative to the top left corner.
  182712. + *
  182713. + * @return Returns 0 on success or negative error code on fail
  182714. + */
  182715. +int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  182716. + int16_t x_pos, int16_t y_pos)
  182717. +{
  182718. + u32 reg;
  182719. + uint32_t flow = 0;
  182720. + uint32_t dp_srm_shift;
  182721. +
  182722. + if ((channel == MEM_FG_SYNC) || (channel == MEM_BG_SYNC)) {
  182723. + flow = DP_SYNC;
  182724. + dp_srm_shift = 3;
  182725. + } else if (channel == MEM_FG_ASYNC0) {
  182726. + flow = DP_ASYNC0;
  182727. + dp_srm_shift = 5;
  182728. + } else if (channel == MEM_FG_ASYNC1) {
  182729. + flow = DP_ASYNC1;
  182730. + dp_srm_shift = 7;
  182731. + } else
  182732. + return -EINVAL;
  182733. +
  182734. + ipu_dp_write(ipu, (x_pos << 16) | y_pos, DP_FG_POS(flow));
  182735. +
  182736. + if (ipu_is_channel_busy(ipu, channel)) {
  182737. + /* controled by FSU if channel enabled */
  182738. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
  182739. + reg |= (0x1 << dp_srm_shift);
  182740. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  182741. + } else {
  182742. + /* disable auto swap, controled by MCU if channel disabled */
  182743. + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift));
  182744. + ipu_cm_write(ipu, reg, IPU_SRM_PRI2);
  182745. + }
  182746. +
  182747. + return 0;
  182748. +}
  182749. +
  182750. +int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  182751. + int16_t x_pos, int16_t y_pos)
  182752. +{
  182753. + int ret;
  182754. +
  182755. + _ipu_get(ipu);
  182756. + mutex_lock(&ipu->mutex_lock);
  182757. + ret = _ipu_disp_set_window_pos(ipu, channel, x_pos, y_pos);
  182758. + mutex_unlock(&ipu->mutex_lock);
  182759. + _ipu_put(ipu);
  182760. + return ret;
  182761. +}
  182762. +EXPORT_SYMBOL(ipu_disp_set_window_pos);
  182763. +
  182764. +int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  182765. + int16_t *x_pos, int16_t *y_pos)
  182766. +{
  182767. + u32 reg;
  182768. + uint32_t flow = 0;
  182769. +
  182770. + if (channel == MEM_FG_SYNC)
  182771. + flow = DP_SYNC;
  182772. + else if (channel == MEM_FG_ASYNC0)
  182773. + flow = DP_ASYNC0;
  182774. + else if (channel == MEM_FG_ASYNC1)
  182775. + flow = DP_ASYNC1;
  182776. + else
  182777. + return -EINVAL;
  182778. +
  182779. + reg = ipu_dp_read(ipu, DP_FG_POS(flow));
  182780. +
  182781. + *x_pos = (reg >> 16) & 0x7FF;
  182782. + *y_pos = reg & 0x7FF;
  182783. +
  182784. + return 0;
  182785. +}
  182786. +int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  182787. + int16_t *x_pos, int16_t *y_pos)
  182788. +{
  182789. + int ret;
  182790. +
  182791. + _ipu_get(ipu);
  182792. + mutex_lock(&ipu->mutex_lock);
  182793. + ret = _ipu_disp_get_window_pos(ipu, channel, x_pos, y_pos);
  182794. + mutex_unlock(&ipu->mutex_lock);
  182795. + _ipu_put(ipu);
  182796. + return ret;
  182797. +}
  182798. +EXPORT_SYMBOL(ipu_disp_get_window_pos);
  182799. +
  182800. +void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset)
  182801. +{
  182802. + if (channel == DIRECT_ASYNC0)
  182803. + writel(value, ipu->disp_base[0] + offset);
  182804. + else if (channel == DIRECT_ASYNC1)
  182805. + writel(value, ipu->disp_base[1] + offset);
  182806. +}
  182807. +EXPORT_SYMBOL(ipu_disp_direct_write);
  182808. +
  182809. +void ipu_reset_disp_panel(struct ipu_soc *ipu)
  182810. +{
  182811. + uint32_t tmp;
  182812. +
  182813. + tmp = ipu_di_read(ipu, 1, DI_GENERAL);
  182814. + ipu_di_write(ipu, 1, tmp | 0x08, DI_GENERAL);
  182815. + msleep(10); /* tRES >= 100us */
  182816. + tmp = ipu_di_read(ipu, 1, DI_GENERAL);
  182817. + ipu_di_write(ipu, 1, tmp & ~0x08, DI_GENERAL);
  182818. + msleep(60);
  182819. +
  182820. + return;
  182821. +}
  182822. +EXPORT_SYMBOL(ipu_reset_disp_panel);
  182823. +
  182824. +void ipu_disp_init(struct ipu_soc *ipu)
  182825. +{
  182826. + ipu->fg_csc_type = ipu->bg_csc_type = CSC_NONE;
  182827. + ipu->color_key_4rgb = true;
  182828. + _ipu_init_dc_mappings(ipu);
  182829. + _ipu_dmfc_init(ipu, DMFC_NORMAL, 1);
  182830. +}
  182831. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_ic.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_ic.c
  182832. --- linux-3.14.17/drivers/mxc/ipu3/ipu_ic.c 1970-01-01 01:00:00.000000000 +0100
  182833. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_ic.c 2014-09-11 18:06:03.134042499 +0200
  182834. @@ -0,0 +1,924 @@
  182835. +/*
  182836. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  182837. + */
  182838. +
  182839. +/*
  182840. + * The code contained herein is licensed under the GNU General Public
  182841. + * License. You may obtain a copy of the GNU General Public License
  182842. + * Version 2 or later at the following locations:
  182843. + *
  182844. + * http://www.opensource.org/licenses/gpl-license.html
  182845. + * http://www.gnu.org/copyleft/gpl.html
  182846. + */
  182847. +
  182848. +/*
  182849. + * @file ipu_ic.c
  182850. + *
  182851. + * @brief IPU IC functions
  182852. + *
  182853. + * @ingroup IPU
  182854. + */
  182855. +#include <linux/errno.h>
  182856. +#include <linux/init.h>
  182857. +#include <linux/io.h>
  182858. +#include <linux/ipu-v3.h>
  182859. +#include <linux/spinlock.h>
  182860. +#include <linux/types.h>
  182861. +#include <linux/videodev2.h>
  182862. +
  182863. +#include "ipu_param_mem.h"
  182864. +#include "ipu_regs.h"
  182865. +
  182866. +enum {
  182867. + IC_TASK_VIEWFINDER,
  182868. + IC_TASK_ENCODER,
  182869. + IC_TASK_POST_PROCESSOR
  182870. +};
  182871. +
  182872. +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
  182873. + ipu_color_space_t out_format, int csc_index);
  182874. +
  182875. +static int _calc_resize_coeffs(struct ipu_soc *ipu,
  182876. + uint32_t inSize, uint32_t outSize,
  182877. + uint32_t *resizeCoeff,
  182878. + uint32_t *downsizeCoeff);
  182879. +
  182880. +void _ipu_vdi_set_top_field_man(struct ipu_soc *ipu, bool top_field_0)
  182881. +{
  182882. + uint32_t reg;
  182883. +
  182884. + reg = ipu_vdi_read(ipu, VDI_C);
  182885. + if (top_field_0)
  182886. + reg &= ~VDI_C_TOP_FIELD_MAN_1;
  182887. + else
  182888. + reg |= VDI_C_TOP_FIELD_MAN_1;
  182889. + ipu_vdi_write(ipu, reg, VDI_C);
  182890. +}
  182891. +
  182892. +void _ipu_vdi_set_motion(struct ipu_soc *ipu, ipu_motion_sel motion_sel)
  182893. +{
  182894. + uint32_t reg;
  182895. +
  182896. + reg = ipu_vdi_read(ipu, VDI_C);
  182897. + reg &= ~(VDI_C_MOT_SEL_FULL | VDI_C_MOT_SEL_MED | VDI_C_MOT_SEL_LOW);
  182898. + if (motion_sel == HIGH_MOTION)
  182899. + reg |= VDI_C_MOT_SEL_FULL;
  182900. + else if (motion_sel == MED_MOTION)
  182901. + reg |= VDI_C_MOT_SEL_MED;
  182902. + else
  182903. + reg |= VDI_C_MOT_SEL_LOW;
  182904. +
  182905. + ipu_vdi_write(ipu, reg, VDI_C);
  182906. + dev_dbg(ipu->dev, "VDI_C = \t0x%08X\n", reg);
  182907. +}
  182908. +
  182909. +void ic_dump_register(struct ipu_soc *ipu)
  182910. +{
  182911. + printk(KERN_DEBUG "IC_CONF = \t0x%08X\n", ipu_ic_read(ipu, IC_CONF));
  182912. + printk(KERN_DEBUG "IC_PRP_ENC_RSC = \t0x%08X\n",
  182913. + ipu_ic_read(ipu, IC_PRP_ENC_RSC));
  182914. + printk(KERN_DEBUG "IC_PRP_VF_RSC = \t0x%08X\n",
  182915. + ipu_ic_read(ipu, IC_PRP_VF_RSC));
  182916. + printk(KERN_DEBUG "IC_PP_RSC = \t0x%08X\n", ipu_ic_read(ipu, IC_PP_RSC));
  182917. + printk(KERN_DEBUG "IC_IDMAC_1 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_1));
  182918. + printk(KERN_DEBUG "IC_IDMAC_2 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_2));
  182919. + printk(KERN_DEBUG "IC_IDMAC_3 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_3));
  182920. +}
  182921. +
  182922. +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel)
  182923. +{
  182924. + uint32_t ic_conf;
  182925. +
  182926. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  182927. + switch (channel) {
  182928. + case CSI_PRP_VF_MEM:
  182929. + case MEM_PRP_VF_MEM:
  182930. + ic_conf |= IC_CONF_PRPVF_EN;
  182931. + break;
  182932. + case MEM_VDI_PRP_VF_MEM:
  182933. + ic_conf |= IC_CONF_PRPVF_EN;
  182934. + break;
  182935. + case MEM_VDI_MEM:
  182936. + ic_conf |= IC_CONF_PRPVF_EN | IC_CONF_RWS_EN ;
  182937. + break;
  182938. + case MEM_ROT_VF_MEM:
  182939. + ic_conf |= IC_CONF_PRPVF_ROT_EN;
  182940. + break;
  182941. + case CSI_PRP_ENC_MEM:
  182942. + case MEM_PRP_ENC_MEM:
  182943. + ic_conf |= IC_CONF_PRPENC_EN;
  182944. + break;
  182945. + case MEM_ROT_ENC_MEM:
  182946. + ic_conf |= IC_CONF_PRPENC_ROT_EN;
  182947. + break;
  182948. + case MEM_PP_MEM:
  182949. + ic_conf |= IC_CONF_PP_EN;
  182950. + break;
  182951. + case MEM_ROT_PP_MEM:
  182952. + ic_conf |= IC_CONF_PP_ROT_EN;
  182953. + break;
  182954. + default:
  182955. + break;
  182956. + }
  182957. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  182958. +}
  182959. +
  182960. +void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel)
  182961. +{
  182962. + uint32_t ic_conf;
  182963. +
  182964. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  182965. + switch (channel) {
  182966. + case CSI_PRP_VF_MEM:
  182967. + case MEM_PRP_VF_MEM:
  182968. + ic_conf &= ~IC_CONF_PRPVF_EN;
  182969. + break;
  182970. + case MEM_VDI_PRP_VF_MEM:
  182971. + ic_conf &= ~IC_CONF_PRPVF_EN;
  182972. + break;
  182973. + case MEM_VDI_MEM:
  182974. + ic_conf &= ~(IC_CONF_PRPVF_EN | IC_CONF_RWS_EN);
  182975. + break;
  182976. + case MEM_ROT_VF_MEM:
  182977. + ic_conf &= ~IC_CONF_PRPVF_ROT_EN;
  182978. + break;
  182979. + case CSI_PRP_ENC_MEM:
  182980. + case MEM_PRP_ENC_MEM:
  182981. + ic_conf &= ~IC_CONF_PRPENC_EN;
  182982. + break;
  182983. + case MEM_ROT_ENC_MEM:
  182984. + ic_conf &= ~IC_CONF_PRPENC_ROT_EN;
  182985. + break;
  182986. + case MEM_PP_MEM:
  182987. + ic_conf &= ~IC_CONF_PP_EN;
  182988. + break;
  182989. + case MEM_ROT_PP_MEM:
  182990. + ic_conf &= ~IC_CONF_PP_ROT_EN;
  182991. + break;
  182992. + default:
  182993. + break;
  182994. + }
  182995. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  182996. +}
  182997. +
  182998. +void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params)
  182999. +{
  183000. + uint32_t reg;
  183001. + uint32_t pixel_fmt;
  183002. + uint32_t pix_per_burst;
  183003. +
  183004. + reg = ((params->mem_prp_vf_mem.in_height-1) << 16) |
  183005. + (params->mem_prp_vf_mem.in_width-1);
  183006. + ipu_vdi_write(ipu, reg, VDI_FSIZE);
  183007. +
  183008. + /* Full motion, only vertical filter is used
  183009. + Burst size is 4 accesses */
  183010. + if (params->mem_prp_vf_mem.in_pixel_fmt ==
  183011. + IPU_PIX_FMT_UYVY ||
  183012. + params->mem_prp_vf_mem.in_pixel_fmt ==
  183013. + IPU_PIX_FMT_YUYV) {
  183014. + pixel_fmt = VDI_C_CH_422;
  183015. + pix_per_burst = 32;
  183016. + } else {
  183017. + pixel_fmt = VDI_C_CH_420;
  183018. + pix_per_burst = 64;
  183019. + }
  183020. +
  183021. + reg = ipu_vdi_read(ipu, VDI_C);
  183022. + reg |= pixel_fmt;
  183023. + switch (channel) {
  183024. + case MEM_VDI_PRP_VF_MEM:
  183025. + reg |= VDI_C_BURST_SIZE2_4;
  183026. + break;
  183027. + case MEM_VDI_PRP_VF_MEM_P:
  183028. + reg |= VDI_C_BURST_SIZE1_4 | VDI_C_VWM1_SET_1 | VDI_C_VWM1_CLR_2;
  183029. + break;
  183030. + case MEM_VDI_PRP_VF_MEM_N:
  183031. + reg |= VDI_C_BURST_SIZE3_4 | VDI_C_VWM3_SET_1 | VDI_C_VWM3_CLR_2;
  183032. + break;
  183033. +
  183034. + case MEM_VDI_MEM:
  183035. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  183036. + << VDI_C_BURST_SIZE2_OFFSET;
  183037. + break;
  183038. + case MEM_VDI_MEM_P:
  183039. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  183040. + << VDI_C_BURST_SIZE1_OFFSET;
  183041. + reg |= VDI_C_VWM1_SET_2 | VDI_C_VWM1_CLR_2;
  183042. + break;
  183043. + case MEM_VDI_MEM_N:
  183044. + reg |= (((pix_per_burst >> 2) - 1) & VDI_C_BURST_SIZE_MASK)
  183045. + << VDI_C_BURST_SIZE3_OFFSET;
  183046. + reg |= VDI_C_VWM3_SET_2 | VDI_C_VWM3_CLR_2;
  183047. + break;
  183048. + default:
  183049. + break;
  183050. + }
  183051. + ipu_vdi_write(ipu, reg, VDI_C);
  183052. +
  183053. + if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_TOP)
  183054. + _ipu_vdi_set_top_field_man(ipu, true);
  183055. + else if (params->mem_prp_vf_mem.field_fmt == IPU_DEINTERLACE_FIELD_BOTTOM)
  183056. + _ipu_vdi_set_top_field_man(ipu, false);
  183057. +
  183058. + _ipu_vdi_set_motion(ipu, params->mem_prp_vf_mem.motion_sel);
  183059. +
  183060. + reg = ipu_ic_read(ipu, IC_CONF);
  183061. + reg &= ~IC_CONF_RWS_EN;
  183062. + ipu_ic_write(ipu, reg, IC_CONF);
  183063. +}
  183064. +
  183065. +void _ipu_vdi_uninit(struct ipu_soc *ipu)
  183066. +{
  183067. + ipu_vdi_write(ipu, 0, VDI_FSIZE);
  183068. + ipu_vdi_write(ipu, 0, VDI_C);
  183069. +}
  183070. +
  183071. +int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
  183072. + bool src_is_csi)
  183073. +{
  183074. + uint32_t reg, ic_conf;
  183075. + uint32_t downsizeCoeff, resizeCoeff;
  183076. + ipu_color_space_t in_fmt, out_fmt;
  183077. + int ret = 0;
  183078. +
  183079. + /* Setup vertical resizing */
  183080. + if (!params->mem_prp_vf_mem.outv_resize_ratio) {
  183081. + ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_height,
  183082. + params->mem_prp_vf_mem.out_height,
  183083. + &resizeCoeff, &downsizeCoeff);
  183084. + if (ret < 0) {
  183085. + dev_err(ipu->dev, "failed to calculate prpvf height "
  183086. + "scaling coefficients\n");
  183087. + return ret;
  183088. + }
  183089. +
  183090. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  183091. + } else
  183092. + reg = (params->mem_prp_vf_mem.outv_resize_ratio) << 16;
  183093. +
  183094. + /* Setup horizontal resizing */
  183095. + if (!params->mem_prp_vf_mem.outh_resize_ratio) {
  183096. + ret = _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_width,
  183097. + params->mem_prp_vf_mem.out_width,
  183098. + &resizeCoeff, &downsizeCoeff);
  183099. + if (ret < 0) {
  183100. + dev_err(ipu->dev, "failed to calculate prpvf width "
  183101. + "scaling coefficients\n");
  183102. + return ret;
  183103. + }
  183104. +
  183105. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  183106. + } else
  183107. + reg |= params->mem_prp_vf_mem.outh_resize_ratio;
  183108. +
  183109. + ipu_ic_write(ipu, reg, IC_PRP_VF_RSC);
  183110. +
  183111. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  183112. +
  183113. + /* Setup color space conversion */
  183114. + in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_pixel_fmt);
  183115. + out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
  183116. + if (in_fmt == RGB) {
  183117. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  183118. + /* Enable RGB->YCBCR CSC1 */
  183119. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 1);
  183120. + ic_conf |= IC_CONF_PRPVF_CSC1;
  183121. + }
  183122. + }
  183123. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  183124. + if (out_fmt == RGB) {
  183125. + /* Enable YCBCR->RGB CSC1 */
  183126. + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 1);
  183127. + ic_conf |= IC_CONF_PRPVF_CSC1;
  183128. + } else {
  183129. + /* TODO: Support YUV<->YCbCr conversion? */
  183130. + }
  183131. + }
  183132. +
  183133. + if (params->mem_prp_vf_mem.graphics_combine_en) {
  183134. + ic_conf |= IC_CONF_PRPVF_CMB;
  183135. +
  183136. + if (!(ic_conf & IC_CONF_PRPVF_CSC1)) {
  183137. + /* need transparent CSC1 conversion */
  183138. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, RGB, 1);
  183139. + ic_conf |= IC_CONF_PRPVF_CSC1; /* Enable RGB->RGB CSC */
  183140. + }
  183141. + in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_g_pixel_fmt);
  183142. + out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt);
  183143. + if (in_fmt == RGB) {
  183144. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  183145. + /* Enable RGB->YCBCR CSC2 */
  183146. + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 2);
  183147. + ic_conf |= IC_CONF_PRPVF_CSC2;
  183148. + }
  183149. + }
  183150. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  183151. + if (out_fmt == RGB) {
  183152. + /* Enable YCBCR->RGB CSC2 */
  183153. + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 2);
  183154. + ic_conf |= IC_CONF_PRPVF_CSC2;
  183155. + } else {
  183156. + /* TODO: Support YUV<->YCbCr conversion? */
  183157. + }
  183158. + }
  183159. +
  183160. + if (params->mem_prp_vf_mem.global_alpha_en) {
  183161. + ic_conf |= IC_CONF_IC_GLB_LOC_A;
  183162. + reg = ipu_ic_read(ipu, IC_CMBP_1);
  183163. + reg &= ~(0xff);
  183164. + reg |= params->mem_prp_vf_mem.alpha;
  183165. + ipu_ic_write(ipu, reg, IC_CMBP_1);
  183166. + } else
  183167. + ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
  183168. +
  183169. + if (params->mem_prp_vf_mem.key_color_en) {
  183170. + ic_conf |= IC_CONF_KEY_COLOR_EN;
  183171. + ipu_ic_write(ipu, params->mem_prp_vf_mem.key_color,
  183172. + IC_CMBP_2);
  183173. + } else
  183174. + ic_conf &= ~IC_CONF_KEY_COLOR_EN;
  183175. + } else {
  183176. + ic_conf &= ~IC_CONF_PRPVF_CMB;
  183177. + }
  183178. +
  183179. + if (src_is_csi)
  183180. + ic_conf &= ~IC_CONF_RWS_EN;
  183181. + else
  183182. + ic_conf |= IC_CONF_RWS_EN;
  183183. +
  183184. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  183185. +
  183186. + return ret;
  183187. +}
  183188. +
  183189. +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu)
  183190. +{
  183191. + uint32_t reg;
  183192. +
  183193. + reg = ipu_ic_read(ipu, IC_CONF);
  183194. + reg &= ~(IC_CONF_PRPVF_EN | IC_CONF_PRPVF_CMB |
  183195. + IC_CONF_PRPVF_CSC2 | IC_CONF_PRPVF_CSC1);
  183196. + ipu_ic_write(ipu, reg, IC_CONF);
  183197. +}
  183198. +
  183199. +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params)
  183200. +{
  183201. +}
  183202. +
  183203. +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu)
  183204. +{
  183205. + uint32_t reg;
  183206. + reg = ipu_ic_read(ipu, IC_CONF);
  183207. + reg &= ~IC_CONF_PRPVF_ROT_EN;
  183208. + ipu_ic_write(ipu, reg, IC_CONF);
  183209. +}
  183210. +
  183211. +int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
  183212. + bool src_is_csi)
  183213. +{
  183214. + uint32_t reg, ic_conf;
  183215. + uint32_t downsizeCoeff, resizeCoeff;
  183216. + ipu_color_space_t in_fmt, out_fmt;
  183217. + int ret = 0;
  183218. +
  183219. + /* Setup vertical resizing */
  183220. + if (!params->mem_prp_enc_mem.outv_resize_ratio) {
  183221. + ret = _calc_resize_coeffs(ipu,
  183222. + params->mem_prp_enc_mem.in_height,
  183223. + params->mem_prp_enc_mem.out_height,
  183224. + &resizeCoeff, &downsizeCoeff);
  183225. + if (ret < 0) {
  183226. + dev_err(ipu->dev, "failed to calculate prpenc height "
  183227. + "scaling coefficients\n");
  183228. + return ret;
  183229. + }
  183230. +
  183231. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  183232. + } else
  183233. + reg = (params->mem_prp_enc_mem.outv_resize_ratio) << 16;
  183234. +
  183235. + /* Setup horizontal resizing */
  183236. + if (!params->mem_prp_enc_mem.outh_resize_ratio) {
  183237. + ret = _calc_resize_coeffs(ipu, params->mem_prp_enc_mem.in_width,
  183238. + params->mem_prp_enc_mem.out_width,
  183239. + &resizeCoeff, &downsizeCoeff);
  183240. + if (ret < 0) {
  183241. + dev_err(ipu->dev, "failed to calculate prpenc width "
  183242. + "scaling coefficients\n");
  183243. + return ret;
  183244. + }
  183245. +
  183246. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  183247. + } else
  183248. + reg |= params->mem_prp_enc_mem.outh_resize_ratio;
  183249. +
  183250. + ipu_ic_write(ipu, reg, IC_PRP_ENC_RSC);
  183251. +
  183252. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  183253. +
  183254. + /* Setup color space conversion */
  183255. + in_fmt = format_to_colorspace(params->mem_prp_enc_mem.in_pixel_fmt);
  183256. + out_fmt = format_to_colorspace(params->mem_prp_enc_mem.out_pixel_fmt);
  183257. + if (in_fmt == RGB) {
  183258. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  183259. + /* Enable RGB->YCBCR CSC1 */
  183260. + _init_csc(ipu, IC_TASK_ENCODER, RGB, out_fmt, 1);
  183261. + ic_conf |= IC_CONF_PRPENC_CSC1;
  183262. + }
  183263. + }
  183264. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  183265. + if (out_fmt == RGB) {
  183266. + /* Enable YCBCR->RGB CSC1 */
  183267. + _init_csc(ipu, IC_TASK_ENCODER, YCbCr, RGB, 1);
  183268. + ic_conf |= IC_CONF_PRPENC_CSC1;
  183269. + } else {
  183270. + /* TODO: Support YUV<->YCbCr conversion? */
  183271. + }
  183272. + }
  183273. +
  183274. + if (src_is_csi)
  183275. + ic_conf &= ~IC_CONF_RWS_EN;
  183276. + else
  183277. + ic_conf |= IC_CONF_RWS_EN;
  183278. +
  183279. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  183280. +
  183281. + return ret;
  183282. +}
  183283. +
  183284. +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu)
  183285. +{
  183286. + uint32_t reg;
  183287. +
  183288. + reg = ipu_ic_read(ipu, IC_CONF);
  183289. + reg &= ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1);
  183290. + ipu_ic_write(ipu, reg, IC_CONF);
  183291. +}
  183292. +
  183293. +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params)
  183294. +{
  183295. +}
  183296. +
  183297. +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu)
  183298. +{
  183299. + uint32_t reg;
  183300. +
  183301. + reg = ipu_ic_read(ipu, IC_CONF);
  183302. + reg &= ~(IC_CONF_PRPENC_ROT_EN);
  183303. + ipu_ic_write(ipu, reg, IC_CONF);
  183304. +}
  183305. +
  183306. +int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
  183307. +{
  183308. + uint32_t reg, ic_conf;
  183309. + uint32_t downsizeCoeff, resizeCoeff;
  183310. + ipu_color_space_t in_fmt, out_fmt;
  183311. + int ret = 0;
  183312. +
  183313. + /* Setup vertical resizing */
  183314. + if (!params->mem_pp_mem.outv_resize_ratio) {
  183315. + ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_height,
  183316. + params->mem_pp_mem.out_height,
  183317. + &resizeCoeff, &downsizeCoeff);
  183318. + if (ret < 0) {
  183319. + dev_err(ipu->dev, "failed to calculate pp height "
  183320. + "scaling coefficients\n");
  183321. + return ret;
  183322. + }
  183323. +
  183324. + reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
  183325. + } else {
  183326. + reg = (params->mem_pp_mem.outv_resize_ratio) << 16;
  183327. + }
  183328. +
  183329. + /* Setup horizontal resizing */
  183330. + if (!params->mem_pp_mem.outh_resize_ratio) {
  183331. + ret = _calc_resize_coeffs(ipu, params->mem_pp_mem.in_width,
  183332. + params->mem_pp_mem.out_width,
  183333. + &resizeCoeff, &downsizeCoeff);
  183334. + if (ret < 0) {
  183335. + dev_err(ipu->dev, "failed to calculate pp width "
  183336. + "scaling coefficients\n");
  183337. + return ret;
  183338. + }
  183339. +
  183340. + reg |= (downsizeCoeff << 14) | resizeCoeff;
  183341. + } else {
  183342. + reg |= params->mem_pp_mem.outh_resize_ratio;
  183343. + }
  183344. +
  183345. + ipu_ic_write(ipu, reg, IC_PP_RSC);
  183346. +
  183347. + ic_conf = ipu_ic_read(ipu, IC_CONF);
  183348. +
  183349. + /* Setup color space conversion */
  183350. + in_fmt = format_to_colorspace(params->mem_pp_mem.in_pixel_fmt);
  183351. + out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
  183352. + if (in_fmt == RGB) {
  183353. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  183354. + /* Enable RGB->YCBCR CSC1 */
  183355. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 1);
  183356. + ic_conf |= IC_CONF_PP_CSC1;
  183357. + }
  183358. + }
  183359. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  183360. + if (out_fmt == RGB) {
  183361. + /* Enable YCBCR->RGB CSC1 */
  183362. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 1);
  183363. + ic_conf |= IC_CONF_PP_CSC1;
  183364. + } else {
  183365. + /* TODO: Support YUV<->YCbCr conversion? */
  183366. + }
  183367. + }
  183368. +
  183369. + if (params->mem_pp_mem.graphics_combine_en) {
  183370. + ic_conf |= IC_CONF_PP_CMB;
  183371. +
  183372. + if (!(ic_conf & IC_CONF_PP_CSC1)) {
  183373. + /* need transparent CSC1 conversion */
  183374. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, RGB, 1);
  183375. + ic_conf |= IC_CONF_PP_CSC1; /* Enable RGB->RGB CSC */
  183376. + }
  183377. +
  183378. + in_fmt = format_to_colorspace(params->mem_pp_mem.in_g_pixel_fmt);
  183379. + out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt);
  183380. + if (in_fmt == RGB) {
  183381. + if ((out_fmt == YCbCr) || (out_fmt == YUV)) {
  183382. + /* Enable RGB->YCBCR CSC2 */
  183383. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 2);
  183384. + ic_conf |= IC_CONF_PP_CSC2;
  183385. + }
  183386. + }
  183387. + if ((in_fmt == YCbCr) || (in_fmt == YUV)) {
  183388. + if (out_fmt == RGB) {
  183389. + /* Enable YCBCR->RGB CSC2 */
  183390. + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 2);
  183391. + ic_conf |= IC_CONF_PP_CSC2;
  183392. + } else {
  183393. + /* TODO: Support YUV<->YCbCr conversion? */
  183394. + }
  183395. + }
  183396. +
  183397. + if (params->mem_pp_mem.global_alpha_en) {
  183398. + ic_conf |= IC_CONF_IC_GLB_LOC_A;
  183399. + reg = ipu_ic_read(ipu, IC_CMBP_1);
  183400. + reg &= ~(0xff00);
  183401. + reg |= (params->mem_pp_mem.alpha << 8);
  183402. + ipu_ic_write(ipu, reg, IC_CMBP_1);
  183403. + } else
  183404. + ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
  183405. +
  183406. + if (params->mem_pp_mem.key_color_en) {
  183407. + ic_conf |= IC_CONF_KEY_COLOR_EN;
  183408. + ipu_ic_write(ipu, params->mem_pp_mem.key_color,
  183409. + IC_CMBP_2);
  183410. + } else
  183411. + ic_conf &= ~IC_CONF_KEY_COLOR_EN;
  183412. + } else {
  183413. + ic_conf &= ~IC_CONF_PP_CMB;
  183414. + }
  183415. +
  183416. + ipu_ic_write(ipu, ic_conf, IC_CONF);
  183417. +
  183418. + return ret;
  183419. +}
  183420. +
  183421. +void _ipu_ic_uninit_pp(struct ipu_soc *ipu)
  183422. +{
  183423. + uint32_t reg;
  183424. +
  183425. + reg = ipu_ic_read(ipu, IC_CONF);
  183426. + reg &= ~(IC_CONF_PP_EN | IC_CONF_PP_CSC1 | IC_CONF_PP_CSC2 |
  183427. + IC_CONF_PP_CMB);
  183428. + ipu_ic_write(ipu, reg, IC_CONF);
  183429. +}
  183430. +
  183431. +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params)
  183432. +{
  183433. +}
  183434. +
  183435. +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu)
  183436. +{
  183437. + uint32_t reg;
  183438. + reg = ipu_ic_read(ipu, IC_CONF);
  183439. + reg &= ~IC_CONF_PP_ROT_EN;
  183440. + ipu_ic_write(ipu, reg, IC_CONF);
  183441. +}
  183442. +
  183443. +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan,
  183444. + uint16_t width, uint16_t height,
  183445. + int burst_size, ipu_rotate_mode_t rot)
  183446. +{
  183447. + u32 ic_idmac_1, ic_idmac_2, ic_idmac_3;
  183448. + u32 temp_rot = bitrev8(rot) >> 5;
  183449. + bool need_hor_flip = false;
  183450. +
  183451. + if ((burst_size != 8) && (burst_size != 16)) {
  183452. + dev_dbg(ipu->dev, "Illegal burst length for IC\n");
  183453. + return -EINVAL;
  183454. + }
  183455. +
  183456. + width--;
  183457. + height--;
  183458. +
  183459. + if (temp_rot & 0x2) /* Need horizontal flip */
  183460. + need_hor_flip = true;
  183461. +
  183462. + ic_idmac_1 = ipu_ic_read(ipu, IC_IDMAC_1);
  183463. + ic_idmac_2 = ipu_ic_read(ipu, IC_IDMAC_2);
  183464. + ic_idmac_3 = ipu_ic_read(ipu, IC_IDMAC_3);
  183465. + if (dma_chan == 22) { /* PP output - CB2 */
  183466. + if (burst_size == 16)
  183467. + ic_idmac_1 |= IC_IDMAC_1_CB2_BURST_16;
  183468. + else
  183469. + ic_idmac_1 &= ~IC_IDMAC_1_CB2_BURST_16;
  183470. +
  183471. + if (need_hor_flip)
  183472. + ic_idmac_1 |= IC_IDMAC_1_PP_FLIP_RS;
  183473. + else
  183474. + ic_idmac_1 &= ~IC_IDMAC_1_PP_FLIP_RS;
  183475. +
  183476. + ic_idmac_2 &= ~IC_IDMAC_2_PP_HEIGHT_MASK;
  183477. + ic_idmac_2 |= height << IC_IDMAC_2_PP_HEIGHT_OFFSET;
  183478. +
  183479. + ic_idmac_3 &= ~IC_IDMAC_3_PP_WIDTH_MASK;
  183480. + ic_idmac_3 |= width << IC_IDMAC_3_PP_WIDTH_OFFSET;
  183481. + } else if (dma_chan == 11) { /* PP Input - CB5 */
  183482. + if (burst_size == 16)
  183483. + ic_idmac_1 |= IC_IDMAC_1_CB5_BURST_16;
  183484. + else
  183485. + ic_idmac_1 &= ~IC_IDMAC_1_CB5_BURST_16;
  183486. + } else if (dma_chan == 47) { /* PP Rot input */
  183487. + ic_idmac_1 &= ~IC_IDMAC_1_PP_ROT_MASK;
  183488. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PP_ROT_OFFSET;
  183489. + }
  183490. +
  183491. + if (dma_chan == 12) { /* PRP Input - CB6 */
  183492. + if (burst_size == 16)
  183493. + ic_idmac_1 |= IC_IDMAC_1_CB6_BURST_16;
  183494. + else
  183495. + ic_idmac_1 &= ~IC_IDMAC_1_CB6_BURST_16;
  183496. + }
  183497. +
  183498. + if (dma_chan == 20) { /* PRP ENC output - CB0 */
  183499. + if (burst_size == 16)
  183500. + ic_idmac_1 |= IC_IDMAC_1_CB0_BURST_16;
  183501. + else
  183502. + ic_idmac_1 &= ~IC_IDMAC_1_CB0_BURST_16;
  183503. +
  183504. + if (need_hor_flip)
  183505. + ic_idmac_1 |= IC_IDMAC_1_PRPENC_FLIP_RS;
  183506. + else
  183507. + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_FLIP_RS;
  183508. +
  183509. + ic_idmac_2 &= ~IC_IDMAC_2_PRPENC_HEIGHT_MASK;
  183510. + ic_idmac_2 |= height << IC_IDMAC_2_PRPENC_HEIGHT_OFFSET;
  183511. +
  183512. + ic_idmac_3 &= ~IC_IDMAC_3_PRPENC_WIDTH_MASK;
  183513. + ic_idmac_3 |= width << IC_IDMAC_3_PRPENC_WIDTH_OFFSET;
  183514. +
  183515. + } else if (dma_chan == 45) { /* PRP ENC Rot input */
  183516. + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_ROT_MASK;
  183517. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPENC_ROT_OFFSET;
  183518. + }
  183519. +
  183520. + if (dma_chan == 21) { /* PRP VF output - CB1 */
  183521. + if (burst_size == 16)
  183522. + ic_idmac_1 |= IC_IDMAC_1_CB1_BURST_16;
  183523. + else
  183524. + ic_idmac_1 &= ~IC_IDMAC_1_CB1_BURST_16;
  183525. +
  183526. + if (need_hor_flip)
  183527. + ic_idmac_1 |= IC_IDMAC_1_PRPVF_FLIP_RS;
  183528. + else
  183529. + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_FLIP_RS;
  183530. +
  183531. + ic_idmac_2 &= ~IC_IDMAC_2_PRPVF_HEIGHT_MASK;
  183532. + ic_idmac_2 |= height << IC_IDMAC_2_PRPVF_HEIGHT_OFFSET;
  183533. +
  183534. + ic_idmac_3 &= ~IC_IDMAC_3_PRPVF_WIDTH_MASK;
  183535. + ic_idmac_3 |= width << IC_IDMAC_3_PRPVF_WIDTH_OFFSET;
  183536. +
  183537. + } else if (dma_chan == 46) { /* PRP VF Rot input */
  183538. + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_ROT_MASK;
  183539. + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPVF_ROT_OFFSET;
  183540. + }
  183541. +
  183542. + if (dma_chan == 14) { /* PRP VF graphics combining input - CB3 */
  183543. + if (burst_size == 16)
  183544. + ic_idmac_1 |= IC_IDMAC_1_CB3_BURST_16;
  183545. + else
  183546. + ic_idmac_1 &= ~IC_IDMAC_1_CB3_BURST_16;
  183547. + } else if (dma_chan == 15) { /* PP graphics combining input - CB4 */
  183548. + if (burst_size == 16)
  183549. + ic_idmac_1 |= IC_IDMAC_1_CB4_BURST_16;
  183550. + else
  183551. + ic_idmac_1 &= ~IC_IDMAC_1_CB4_BURST_16;
  183552. + } else if (dma_chan == 5) { /* VDIC OUTPUT - CB7 */
  183553. + if (burst_size == 16)
  183554. + ic_idmac_1 |= IC_IDMAC_1_CB7_BURST_16;
  183555. + else
  183556. + ic_idmac_1 &= ~IC_IDMAC_1_CB7_BURST_16;
  183557. + }
  183558. +
  183559. + ipu_ic_write(ipu, ic_idmac_1, IC_IDMAC_1);
  183560. + ipu_ic_write(ipu, ic_idmac_2, IC_IDMAC_2);
  183561. + ipu_ic_write(ipu, ic_idmac_3, IC_IDMAC_3);
  183562. + return 0;
  183563. +}
  183564. +
  183565. +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format,
  183566. + ipu_color_space_t out_format, int csc_index)
  183567. +{
  183568. + /*
  183569. + * Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
  183570. + * U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
  183571. + * V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
  183572. + */
  183573. + static const uint32_t rgb2ycbcr_coeff[4][3] = {
  183574. + {0x0042, 0x0081, 0x0019},
  183575. + {0x01DA, 0x01B6, 0x0070},
  183576. + {0x0070, 0x01A2, 0x01EE},
  183577. + {0x0040, 0x0200, 0x0200}, /* A0, A1, A2 */
  183578. + };
  183579. +
  183580. + /* transparent RGB->RGB matrix for combining
  183581. + */
  183582. + static const uint32_t rgb2rgb_coeff[4][3] = {
  183583. + {0x0080, 0x0000, 0x0000},
  183584. + {0x0000, 0x0080, 0x0000},
  183585. + {0x0000, 0x0000, 0x0080},
  183586. + {0x0000, 0x0000, 0x0000}, /* A0, A1, A2 */
  183587. + };
  183588. +
  183589. +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128));
  183590. + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128));
  183591. + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */
  183592. + static const uint32_t ycbcr2rgb_coeff[4][3] = {
  183593. + {149, 0, 204},
  183594. + {149, 462, 408},
  183595. + {149, 255, 0},
  183596. + {8192 - 446, 266, 8192 - 554}, /* A0, A1, A2 */
  183597. + };
  183598. +
  183599. + uint32_t param;
  183600. + uint32_t *base = NULL;
  183601. +
  183602. + if (ic_task == IC_TASK_ENCODER) {
  183603. + base = (uint32_t *)ipu->tpmem_base + 0x2008 / 4;
  183604. + } else if (ic_task == IC_TASK_VIEWFINDER) {
  183605. + if (csc_index == 1)
  183606. + base = (uint32_t *)ipu->tpmem_base + 0x4028 / 4;
  183607. + else
  183608. + base = (uint32_t *)ipu->tpmem_base + 0x4040 / 4;
  183609. + } else if (ic_task == IC_TASK_POST_PROCESSOR) {
  183610. + if (csc_index == 1)
  183611. + base = (uint32_t *)ipu->tpmem_base + 0x6060 / 4;
  183612. + else
  183613. + base = (uint32_t *)ipu->tpmem_base + 0x6078 / 4;
  183614. + } else {
  183615. + BUG();
  183616. + }
  183617. +
  183618. + if ((in_format == YCbCr) && (out_format == RGB)) {
  183619. + /* Init CSC (YCbCr->RGB) */
  183620. + param = (ycbcr2rgb_coeff[3][0] << 27) |
  183621. + (ycbcr2rgb_coeff[0][0] << 18) |
  183622. + (ycbcr2rgb_coeff[1][1] << 9) | ycbcr2rgb_coeff[2][2];
  183623. + writel(param, base++);
  183624. + /* scale = 2, sat = 0 */
  183625. + param = (ycbcr2rgb_coeff[3][0] >> 5) | (2L << (40 - 32));
  183626. + writel(param, base++);
  183627. +
  183628. + param = (ycbcr2rgb_coeff[3][1] << 27) |
  183629. + (ycbcr2rgb_coeff[0][1] << 18) |
  183630. + (ycbcr2rgb_coeff[1][0] << 9) | ycbcr2rgb_coeff[2][0];
  183631. + writel(param, base++);
  183632. + param = (ycbcr2rgb_coeff[3][1] >> 5);
  183633. + writel(param, base++);
  183634. +
  183635. + param = (ycbcr2rgb_coeff[3][2] << 27) |
  183636. + (ycbcr2rgb_coeff[0][2] << 18) |
  183637. + (ycbcr2rgb_coeff[1][2] << 9) | ycbcr2rgb_coeff[2][1];
  183638. + writel(param, base++);
  183639. + param = (ycbcr2rgb_coeff[3][2] >> 5);
  183640. + writel(param, base++);
  183641. + } else if ((in_format == RGB) && (out_format == YCbCr)) {
  183642. + /* Init CSC (RGB->YCbCr) */
  183643. + param = (rgb2ycbcr_coeff[3][0] << 27) |
  183644. + (rgb2ycbcr_coeff[0][0] << 18) |
  183645. + (rgb2ycbcr_coeff[1][1] << 9) | rgb2ycbcr_coeff[2][2];
  183646. + writel(param, base++);
  183647. + /* scale = 1, sat = 0 */
  183648. + param = (rgb2ycbcr_coeff[3][0] >> 5) | (1UL << 8);
  183649. + writel(param, base++);
  183650. +
  183651. + param = (rgb2ycbcr_coeff[3][1] << 27) |
  183652. + (rgb2ycbcr_coeff[0][1] << 18) |
  183653. + (rgb2ycbcr_coeff[1][0] << 9) | rgb2ycbcr_coeff[2][0];
  183654. + writel(param, base++);
  183655. + param = (rgb2ycbcr_coeff[3][1] >> 5);
  183656. + writel(param, base++);
  183657. +
  183658. + param = (rgb2ycbcr_coeff[3][2] << 27) |
  183659. + (rgb2ycbcr_coeff[0][2] << 18) |
  183660. + (rgb2ycbcr_coeff[1][2] << 9) | rgb2ycbcr_coeff[2][1];
  183661. + writel(param, base++);
  183662. + param = (rgb2ycbcr_coeff[3][2] >> 5);
  183663. + writel(param, base++);
  183664. + } else if ((in_format == RGB) && (out_format == RGB)) {
  183665. + /* Init CSC */
  183666. + param =
  183667. + (rgb2rgb_coeff[3][0] << 27) | (rgb2rgb_coeff[0][0] << 18) |
  183668. + (rgb2rgb_coeff[1][1] << 9) | rgb2rgb_coeff[2][2];
  183669. + writel(param, base++);
  183670. + /* scale = 2, sat = 0 */
  183671. + param = (rgb2rgb_coeff[3][0] >> 5) | (2UL << 8);
  183672. + writel(param, base++);
  183673. +
  183674. + param =
  183675. + (rgb2rgb_coeff[3][1] << 27) | (rgb2rgb_coeff[0][1] << 18) |
  183676. + (rgb2rgb_coeff[1][0] << 9) | rgb2rgb_coeff[2][0];
  183677. + writel(param, base++);
  183678. + param = (rgb2rgb_coeff[3][1] >> 5);
  183679. + writel(param, base++);
  183680. +
  183681. + param =
  183682. + (rgb2rgb_coeff[3][2] << 27) | (rgb2rgb_coeff[0][2] << 18) |
  183683. + (rgb2rgb_coeff[1][2] << 9) | rgb2rgb_coeff[2][1];
  183684. + writel(param, base++);
  183685. + param = (rgb2rgb_coeff[3][2] >> 5);
  183686. + writel(param, base++);
  183687. + } else {
  183688. + dev_err(ipu->dev, "Unsupported color space conversion\n");
  183689. + }
  183690. +}
  183691. +
  183692. +static int _calc_resize_coeffs(struct ipu_soc *ipu,
  183693. + uint32_t inSize, uint32_t outSize,
  183694. + uint32_t *resizeCoeff,
  183695. + uint32_t *downsizeCoeff)
  183696. +{
  183697. + uint32_t tempSize;
  183698. + uint32_t tempDownsize;
  183699. +
  183700. + if (inSize > 4096) {
  183701. + dev_err(ipu->dev, "IC input size(%d) cannot exceed 4096\n",
  183702. + inSize);
  183703. + return -EINVAL;
  183704. + }
  183705. +
  183706. + if (outSize > 1024) {
  183707. + dev_err(ipu->dev, "IC output size(%d) cannot exceed 1024\n",
  183708. + outSize);
  183709. + return -EINVAL;
  183710. + }
  183711. +
  183712. + if ((outSize << 3) < inSize) {
  183713. + dev_err(ipu->dev, "IC cannot downsize more than 8:1\n");
  183714. + return -EINVAL;
  183715. + }
  183716. +
  183717. + /* Compute downsizing coefficient */
  183718. + /* Output of downsizing unit cannot be more than 1024 */
  183719. + tempDownsize = 0;
  183720. + tempSize = inSize;
  183721. + while (((tempSize > 1024) || (tempSize >= outSize * 2)) &&
  183722. + (tempDownsize < 2)) {
  183723. + tempSize >>= 1;
  183724. + tempDownsize++;
  183725. + }
  183726. + *downsizeCoeff = tempDownsize;
  183727. +
  183728. + /* compute resizing coefficient using the following equation:
  183729. + resizeCoeff = M*(SI -1)/(SO - 1)
  183730. + where M = 2^13, SI - input size, SO - output size */
  183731. + *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1);
  183732. + if (*resizeCoeff >= 16384L) {
  183733. + dev_err(ipu->dev, "Overflow on IC resize coefficient.\n");
  183734. + return -EINVAL;
  183735. + }
  183736. +
  183737. + dev_dbg(ipu->dev, "resizing from %u -> %u pixels, "
  183738. + "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize,
  183739. + *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0,
  183740. + ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff);
  183741. +
  183742. + return 0;
  183743. +}
  183744. +
  183745. +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu)
  183746. +{
  183747. + uint32_t reg;
  183748. + uint32_t mask_reg;
  183749. +
  183750. + reg = ipu_vdi_read(ipu, VDI_C);
  183751. + mask_reg = reg & VDI_C_TOP_FIELD_MAN_1;
  183752. + if (mask_reg == VDI_C_TOP_FIELD_MAN_1)
  183753. + reg &= ~VDI_C_TOP_FIELD_MAN_1;
  183754. + else
  183755. + reg |= VDI_C_TOP_FIELD_MAN_1;
  183756. +
  183757. + ipu_vdi_write(ipu, reg, VDI_C);
  183758. +}
  183759. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_param_mem.h linux-imx6-3.14/drivers/mxc/ipu3/ipu_param_mem.h
  183760. --- linux-3.14.17/drivers/mxc/ipu3/ipu_param_mem.h 1970-01-01 01:00:00.000000000 +0100
  183761. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_param_mem.h 2014-09-11 18:06:03.134042499 +0200
  183762. @@ -0,0 +1,921 @@
  183763. +/*
  183764. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  183765. + */
  183766. +
  183767. +/*
  183768. + * The code contained herein is licensed under the GNU General Public
  183769. + * License. You may obtain a copy of the GNU General Public License
  183770. + * Version 2 or later at the following locations:
  183771. + *
  183772. + * http://www.opensource.org/licenses/gpl-license.html
  183773. + * http://www.gnu.org/copyleft/gpl.html
  183774. + */
  183775. +#ifndef __INCLUDE_IPU_PARAM_MEM_H__
  183776. +#define __INCLUDE_IPU_PARAM_MEM_H__
  183777. +
  183778. +#include <linux/bitrev.h>
  183779. +#include <linux/types.h>
  183780. +
  183781. +#include "ipu_prv.h"
  183782. +
  183783. +extern u32 *ipu_cpmem_base;
  183784. +
  183785. +struct ipu_ch_param_word {
  183786. + uint32_t data[5];
  183787. + uint32_t res[3];
  183788. +};
  183789. +
  183790. +struct ipu_ch_param {
  183791. + struct ipu_ch_param_word word[2];
  183792. +};
  183793. +
  183794. +#define ipu_ch_param_addr(ipu, ch) (((struct ipu_ch_param *)ipu->cpmem_base) + (ch))
  183795. +
  183796. +#define _param_word(base, w) \
  183797. + (((struct ipu_ch_param *)(base))->word[(w)].data)
  183798. +
  183799. +#define ipu_ch_param_set_field(base, w, bit, size, v) { \
  183800. + int i = (bit) / 32; \
  183801. + int off = (bit) % 32; \
  183802. + _param_word(base, w)[i] |= (v) << off; \
  183803. + if (((bit)+(size)-1)/32 > i) { \
  183804. + _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \
  183805. + } \
  183806. +}
  183807. +
  183808. +#define ipu_ch_param_set_field_io(base, w, bit, size, v) { \
  183809. + int i = (bit) / 32; \
  183810. + int off = (bit) % 32; \
  183811. + unsigned reg_offset; \
  183812. + u32 temp; \
  183813. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  183814. + reg_offset += i; \
  183815. + temp = readl((u32 *)base + reg_offset); \
  183816. + temp |= (v) << off; \
  183817. + writel(temp, (u32 *)base + reg_offset); \
  183818. + if (((bit)+(size)-1)/32 > i) { \
  183819. + reg_offset++; \
  183820. + temp = readl((u32 *)base + reg_offset); \
  183821. + temp |= (v) >> (off ? (32 - off) : 0); \
  183822. + writel(temp, (u32 *)base + reg_offset); \
  183823. + } \
  183824. +}
  183825. +
  183826. +#define ipu_ch_param_mod_field(base, w, bit, size, v) { \
  183827. + int i = (bit) / 32; \
  183828. + int off = (bit) % 32; \
  183829. + u32 mask = (1UL << size) - 1; \
  183830. + u32 temp = _param_word(base, w)[i]; \
  183831. + temp &= ~(mask << off); \
  183832. + _param_word(base, w)[i] = temp | (v) << off; \
  183833. + if (((bit)+(size)-1)/32 > i) { \
  183834. + temp = _param_word(base, w)[i + 1]; \
  183835. + temp &= ~(mask >> (32 - off)); \
  183836. + _param_word(base, w)[i + 1] = \
  183837. + temp | ((v) >> (off ? (32 - off) : 0)); \
  183838. + } \
  183839. +}
  183840. +
  183841. +#define ipu_ch_param_mod_field_io(base, w, bit, size, v) { \
  183842. + int i = (bit) / 32; \
  183843. + int off = (bit) % 32; \
  183844. + u32 mask = (1UL << size) - 1; \
  183845. + unsigned reg_offset; \
  183846. + u32 temp; \
  183847. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  183848. + reg_offset += i; \
  183849. + temp = readl((u32 *)base + reg_offset); \
  183850. + temp &= ~(mask << off); \
  183851. + temp |= (v) << off; \
  183852. + writel(temp, (u32 *)base + reg_offset); \
  183853. + if (((bit)+(size)-1)/32 > i) { \
  183854. + reg_offset++; \
  183855. + temp = readl((u32 *)base + reg_offset); \
  183856. + temp &= ~(mask >> (32 - off)); \
  183857. + temp |= ((v) >> (off ? (32 - off) : 0)); \
  183858. + writel(temp, (u32 *)base + reg_offset); \
  183859. + } \
  183860. +}
  183861. +
  183862. +#define ipu_ch_param_read_field(base, w, bit, size) ({ \
  183863. + u32 temp2; \
  183864. + int i = (bit) / 32; \
  183865. + int off = (bit) % 32; \
  183866. + u32 mask = (1UL << size) - 1; \
  183867. + u32 temp1 = _param_word(base, w)[i]; \
  183868. + temp1 = mask & (temp1 >> off); \
  183869. + if (((bit)+(size)-1)/32 > i) { \
  183870. + temp2 = _param_word(base, w)[i + 1]; \
  183871. + temp2 &= mask >> (off ? (32 - off) : 0); \
  183872. + temp1 |= temp2 << (off ? (32 - off) : 0); \
  183873. + } \
  183874. + temp1; \
  183875. +})
  183876. +
  183877. +#define ipu_ch_param_read_field_io(base, w, bit, size) ({ \
  183878. + u32 temp1, temp2; \
  183879. + int i = (bit) / 32; \
  183880. + int off = (bit) % 32; \
  183881. + u32 mask = (1UL << size) - 1; \
  183882. + unsigned reg_offset; \
  183883. + reg_offset = sizeof(struct ipu_ch_param_word) * w / 4; \
  183884. + reg_offset += i; \
  183885. + temp1 = readl((u32 *)base + reg_offset); \
  183886. + temp1 = mask & (temp1 >> off); \
  183887. + if (((bit)+(size)-1)/32 > i) { \
  183888. + reg_offset++; \
  183889. + temp2 = readl((u32 *)base + reg_offset); \
  183890. + temp2 &= mask >> (off ? (32 - off) : 0); \
  183891. + temp1 |= temp2 << (off ? (32 - off) : 0); \
  183892. + } \
  183893. + temp1; \
  183894. +})
  183895. +
  183896. +static inline int __ipu_ch_get_third_buf_cpmem_num(int ch)
  183897. +{
  183898. + switch (ch) {
  183899. + case 8:
  183900. + return 64;
  183901. + case 9:
  183902. + return 65;
  183903. + case 10:
  183904. + return 66;
  183905. + case 13:
  183906. + return 67;
  183907. + case 21:
  183908. + return 68;
  183909. + case 23:
  183910. + return 69;
  183911. + case 27:
  183912. + return 70;
  183913. + case 28:
  183914. + return 71;
  183915. + default:
  183916. + return -EINVAL;
  183917. + }
  183918. + return 0;
  183919. +}
  183920. +
  183921. +static inline void _ipu_ch_params_set_packing(struct ipu_ch_param *p,
  183922. + int red_width, int red_offset,
  183923. + int green_width, int green_offset,
  183924. + int blue_width, int blue_offset,
  183925. + int alpha_width, int alpha_offset)
  183926. +{
  183927. + /* Setup red width and offset */
  183928. + ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1);
  183929. + ipu_ch_param_set_field(p, 1, 128, 5, red_offset);
  183930. + /* Setup green width and offset */
  183931. + ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1);
  183932. + ipu_ch_param_set_field(p, 1, 133, 5, green_offset);
  183933. + /* Setup blue width and offset */
  183934. + ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1);
  183935. + ipu_ch_param_set_field(p, 1, 138, 5, blue_offset);
  183936. + /* Setup alpha width and offset */
  183937. + ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1);
  183938. + ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset);
  183939. +}
  183940. +
  183941. +static inline void _ipu_ch_param_dump(struct ipu_soc *ipu, int ch)
  183942. +{
  183943. + struct ipu_ch_param *p = ipu_ch_param_addr(ipu, ch);
  183944. + dev_dbg(ipu->dev, "ch %d word 0 - %08X %08X %08X %08X %08X\n", ch,
  183945. + p->word[0].data[0], p->word[0].data[1], p->word[0].data[2],
  183946. + p->word[0].data[3], p->word[0].data[4]);
  183947. + dev_dbg(ipu->dev, "ch %d word 1 - %08X %08X %08X %08X %08X\n", ch,
  183948. + p->word[1].data[0], p->word[1].data[1], p->word[1].data[2],
  183949. + p->word[1].data[3], p->word[1].data[4]);
  183950. + dev_dbg(ipu->dev, "PFS 0x%x, ",
  183951. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 85, 4));
  183952. + dev_dbg(ipu->dev, "BPP 0x%x, ",
  183953. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3));
  183954. + dev_dbg(ipu->dev, "NPB 0x%x\n",
  183955. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7));
  183956. +
  183957. + dev_dbg(ipu->dev, "FW %d, ",
  183958. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 125, 13));
  183959. + dev_dbg(ipu->dev, "FH %d, ",
  183960. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 138, 12));
  183961. + dev_dbg(ipu->dev, "EBA0 0x%x\n",
  183962. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 0, 29) << 3);
  183963. + dev_dbg(ipu->dev, "EBA1 0x%x\n",
  183964. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 29, 29) << 3);
  183965. + dev_dbg(ipu->dev, "Stride %d\n",
  183966. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14));
  183967. + dev_dbg(ipu->dev, "scan_order %d\n",
  183968. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1));
  183969. + dev_dbg(ipu->dev, "uv_stride %d\n",
  183970. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 14));
  183971. + dev_dbg(ipu->dev, "u_offset 0x%x\n",
  183972. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22) << 3);
  183973. + dev_dbg(ipu->dev, "v_offset 0x%x\n",
  183974. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22) << 3);
  183975. +
  183976. + dev_dbg(ipu->dev, "Width0 %d+1, ",
  183977. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 116, 3));
  183978. + dev_dbg(ipu->dev, "Width1 %d+1, ",
  183979. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 119, 3));
  183980. + dev_dbg(ipu->dev, "Width2 %d+1, ",
  183981. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 122, 3));
  183982. + dev_dbg(ipu->dev, "Width3 %d+1, ",
  183983. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3));
  183984. + dev_dbg(ipu->dev, "Offset0 %d, ",
  183985. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 128, 5));
  183986. + dev_dbg(ipu->dev, "Offset1 %d, ",
  183987. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 133, 5));
  183988. + dev_dbg(ipu->dev, "Offset2 %d, ",
  183989. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 138, 5));
  183990. + dev_dbg(ipu->dev, "Offset3 %d\n",
  183991. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 143, 5));
  183992. +}
  183993. +
  183994. +static inline void fill_cpmem(struct ipu_soc *ipu, int ch, struct ipu_ch_param *params)
  183995. +{
  183996. + int i, w;
  183997. + void *addr = ipu_ch_param_addr(ipu, ch);
  183998. +
  183999. + /* 2 words, 5 valid data */
  184000. + for (w = 0; w < 2; w++) {
  184001. + for (i = 0; i < 5; i++) {
  184002. + writel(params->word[w].data[i], addr);
  184003. + addr += 4;
  184004. + }
  184005. + addr += 12;
  184006. + }
  184007. +}
  184008. +
  184009. +static inline void _ipu_ch_param_init(struct ipu_soc *ipu, int ch,
  184010. + uint32_t pixel_fmt, uint32_t width,
  184011. + uint32_t height, uint32_t stride,
  184012. + uint32_t u, uint32_t v,
  184013. + uint32_t uv_stride, dma_addr_t addr0,
  184014. + dma_addr_t addr1, dma_addr_t addr2)
  184015. +{
  184016. + uint32_t u_offset = 0;
  184017. + uint32_t v_offset = 0;
  184018. + int32_t sub_ch = 0;
  184019. + struct ipu_ch_param params;
  184020. +
  184021. + memset(&params, 0, sizeof(params));
  184022. +
  184023. + ipu_ch_param_set_field(&params, 0, 125, 13, width - 1);
  184024. +
  184025. + if (((ch == 8) || (ch == 9) || (ch == 10)) && !ipu->vdoa_en) {
  184026. + ipu_ch_param_set_field(&params, 0, 138, 12, (height / 2) - 1);
  184027. + ipu_ch_param_set_field(&params, 1, 102, 14, (stride * 2) - 1);
  184028. + } else {
  184029. + /* note: for vdoa+vdi- ch8/9/10, always use band mode */
  184030. + ipu_ch_param_set_field(&params, 0, 138, 12, height - 1);
  184031. + ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
  184032. + }
  184033. +
  184034. + /* EBA is 8-byte aligned */
  184035. + ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
  184036. + ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
  184037. + if (addr0%8)
  184038. + dev_warn(ipu->dev,
  184039. + "IDMAC%d's EBA0 is not 8-byte aligned\n", ch);
  184040. + if (addr1%8)
  184041. + dev_warn(ipu->dev,
  184042. + "IDMAC%d's EBA1 is not 8-byte aligned\n", ch);
  184043. +
  184044. + switch (pixel_fmt) {
  184045. + case IPU_PIX_FMT_GENERIC:
  184046. + /*Represents 8-bit Generic data */
  184047. + ipu_ch_param_set_field(&params, 0, 107, 3, 5); /* bits/pixel */
  184048. + ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
  184049. + ipu_ch_param_set_field(&params, 1, 78, 7, 63); /* burst size */
  184050. +
  184051. + break;
  184052. + case IPU_PIX_FMT_GENERIC_16:
  184053. + /* Represents 16-bit generic data */
  184054. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  184055. + ipu_ch_param_set_field(&params, 1, 85, 4, 6); /* pix format */
  184056. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184057. +
  184058. + break;
  184059. + case IPU_PIX_FMT_GENERIC_32:
  184060. + /*Represents 32-bit Generic data */
  184061. + break;
  184062. + case IPU_PIX_FMT_RGB565:
  184063. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  184064. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  184065. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184066. +
  184067. + _ipu_ch_params_set_packing(&params, 5, 0, 6, 5, 5, 11, 8, 16);
  184068. + break;
  184069. + case IPU_PIX_FMT_BGR24:
  184070. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  184071. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  184072. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  184073. +
  184074. + _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
  184075. + break;
  184076. + case IPU_PIX_FMT_RGB24:
  184077. + case IPU_PIX_FMT_YUV444:
  184078. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  184079. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  184080. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  184081. +
  184082. + _ipu_ch_params_set_packing(&params, 8, 16, 8, 8, 8, 0, 8, 24);
  184083. + break;
  184084. + case IPU_PIX_FMT_VYU444:
  184085. + ipu_ch_param_set_field(&params, 0, 107, 3, 1); /* bits/pixel */
  184086. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  184087. + ipu_ch_param_set_field(&params, 1, 78, 7, 19); /* burst size */
  184088. +
  184089. + _ipu_ch_params_set_packing(&params, 8, 8, 8, 0, 8, 16, 8, 24);
  184090. + break;
  184091. + case IPU_PIX_FMT_BGRA32:
  184092. + case IPU_PIX_FMT_BGR32:
  184093. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
  184094. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  184095. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  184096. +
  184097. + _ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
  184098. + break;
  184099. + case IPU_PIX_FMT_RGBA32:
  184100. + case IPU_PIX_FMT_RGB32:
  184101. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
  184102. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  184103. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  184104. +
  184105. + _ipu_ch_params_set_packing(&params, 8, 24, 8, 16, 8, 8, 8, 0);
  184106. + break;
  184107. + case IPU_PIX_FMT_ABGR32:
  184108. + ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
  184109. + ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
  184110. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  184111. +
  184112. + _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
  184113. + break;
  184114. + case IPU_PIX_FMT_UYVY:
  184115. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  184116. + ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
  184117. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  184118. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  184119. + } else {
  184120. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184121. + }
  184122. + break;
  184123. + case IPU_PIX_FMT_YUYV:
  184124. + ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
  184125. + ipu_ch_param_set_field(&params, 1, 85, 4, 0x8); /* pix format */
  184126. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  184127. + if (ipu->vdoa_en) {
  184128. + ipu_ch_param_set_field(&params, 1, 78, 7, 31);
  184129. + } else {
  184130. + ipu_ch_param_set_field(&params, 1, 78, 7, 15);
  184131. + }
  184132. + } else {
  184133. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184134. + }
  184135. + break;
  184136. + case IPU_PIX_FMT_YUV420P2:
  184137. + case IPU_PIX_FMT_YUV420P:
  184138. + ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
  184139. +
  184140. + if (uv_stride < stride / 2)
  184141. + uv_stride = stride / 2;
  184142. +
  184143. + u_offset = stride * height;
  184144. + v_offset = u_offset + (uv_stride * height / 2);
  184145. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  184146. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  184147. + uv_stride = uv_stride*2;
  184148. + } else {
  184149. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184150. + }
  184151. + break;
  184152. + case IPU_PIX_FMT_YVU420P:
  184153. + ipu_ch_param_set_field(&params, 1, 85, 4, 2); /* pix format */
  184154. +
  184155. + if (uv_stride < stride / 2)
  184156. + uv_stride = stride / 2;
  184157. +
  184158. + v_offset = stride * height;
  184159. + u_offset = v_offset + (uv_stride * height / 2);
  184160. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  184161. + ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
  184162. + uv_stride = uv_stride*2;
  184163. + } else {
  184164. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184165. + }
  184166. + break;
  184167. + case IPU_PIX_FMT_YVU422P:
  184168. + /* BPP & pixel format */
  184169. + ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
  184170. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184171. +
  184172. + if (uv_stride < stride / 2)
  184173. + uv_stride = stride / 2;
  184174. +
  184175. + v_offset = (v == 0) ? stride * height : v;
  184176. + u_offset = (u == 0) ? v_offset + v_offset / 2 : u;
  184177. + break;
  184178. + case IPU_PIX_FMT_YUV422P:
  184179. + /* BPP & pixel format */
  184180. + ipu_ch_param_set_field(&params, 1, 85, 4, 1); /* pix format */
  184181. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184182. +
  184183. + if (uv_stride < stride / 2)
  184184. + uv_stride = stride / 2;
  184185. +
  184186. + u_offset = (u == 0) ? stride * height : u;
  184187. + v_offset = (v == 0) ? u_offset + u_offset / 2 : v;
  184188. + break;
  184189. + case IPU_PIX_FMT_YUV444P:
  184190. + /* BPP & pixel format */
  184191. + ipu_ch_param_set_field(&params, 1, 85, 4, 0); /* pix format */
  184192. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184193. + uv_stride = stride;
  184194. + u_offset = (u == 0) ? stride * height : u;
  184195. + v_offset = (v == 0) ? u_offset * 2 : v;
  184196. + break;
  184197. + case IPU_PIX_FMT_NV12:
  184198. + /* BPP & pixel format */
  184199. + ipu_ch_param_set_field(&params, 1, 85, 4, 4); /* pix format */
  184200. + uv_stride = stride;
  184201. + u_offset = (u == 0) ? stride * height : u;
  184202. + if ((ch == 8) || (ch == 9) || (ch == 10)) {
  184203. + if (ipu->vdoa_en) {
  184204. + /* one field buffer, memory width 64bits */
  184205. + ipu_ch_param_set_field(&params, 1, 78, 7, 63);
  184206. + } else {
  184207. + ipu_ch_param_set_field(&params, 1, 78, 7, 15);
  184208. + /* top/bottom field in one buffer*/
  184209. + uv_stride = uv_stride*2;
  184210. + }
  184211. + } else {
  184212. + ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
  184213. + }
  184214. + break;
  184215. + default:
  184216. + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
  184217. + break;
  184218. + }
  184219. + /*set burst size to 16*/
  184220. +
  184221. +
  184222. + if (uv_stride)
  184223. + ipu_ch_param_set_field(&params, 1, 128, 14, uv_stride - 1);
  184224. +
  184225. + /* Get the uv offset from user when need cropping */
  184226. + if (u || v) {
  184227. + u_offset = u;
  184228. + v_offset = v;
  184229. + }
  184230. +
  184231. + /* UBO and VBO are 22-bit and 8-byte aligned */
  184232. + if (u_offset/8 > 0x3fffff)
  184233. + dev_warn(ipu->dev,
  184234. + "IDMAC%d's U offset exceeds IPU limitation\n", ch);
  184235. + if (v_offset/8 > 0x3fffff)
  184236. + dev_warn(ipu->dev,
  184237. + "IDMAC%d's V offset exceeds IPU limitation\n", ch);
  184238. + if (u_offset%8)
  184239. + dev_warn(ipu->dev,
  184240. + "IDMAC%d's U offset is not 8-byte aligned\n", ch);
  184241. + if (v_offset%8)
  184242. + dev_warn(ipu->dev,
  184243. + "IDMAC%d's V offset is not 8-byte aligned\n", ch);
  184244. +
  184245. + ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
  184246. + ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
  184247. +
  184248. + dev_dbg(ipu->dev, "initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ipu, ch));
  184249. + fill_cpmem(ipu, ch, &params);
  184250. + if (addr2) {
  184251. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184252. + if (sub_ch <= 0)
  184253. + return;
  184254. +
  184255. + ipu_ch_param_set_field(&params, 1, 0, 29, addr2 >> 3);
  184256. + ipu_ch_param_set_field(&params, 1, 29, 29, 0);
  184257. + if (addr2%8)
  184258. + dev_warn(ipu->dev,
  184259. + "IDMAC%d's sub-CPMEM entry%d EBA0 is not "
  184260. + "8-byte aligned\n", ch, sub_ch);
  184261. +
  184262. + dev_dbg(ipu->dev, "initializing idma ch %d @ %p sub cpmem\n", ch,
  184263. + ipu_ch_param_addr(ipu, sub_ch));
  184264. + fill_cpmem(ipu, sub_ch, &params);
  184265. + }
  184266. +};
  184267. +
  184268. +static inline void _ipu_ch_param_set_burst_size(struct ipu_soc *ipu,
  184269. + uint32_t ch,
  184270. + uint16_t burst_pixels)
  184271. +{
  184272. + int32_t sub_ch = 0;
  184273. +
  184274. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7,
  184275. + burst_pixels - 1);
  184276. +
  184277. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184278. + if (sub_ch <= 0)
  184279. + return;
  184280. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 78, 7,
  184281. + burst_pixels - 1);
  184282. +};
  184283. +
  184284. +static inline int _ipu_ch_param_get_burst_size(struct ipu_soc *ipu, uint32_t ch)
  184285. +{
  184286. + return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 78, 7) + 1;
  184287. +};
  184288. +
  184289. +static inline int _ipu_ch_param_get_bpp(struct ipu_soc *ipu, uint32_t ch)
  184290. +{
  184291. + return ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 107, 3);
  184292. +};
  184293. +
  184294. +static inline void _ipu_ch_param_set_buffer(struct ipu_soc *ipu, uint32_t ch,
  184295. + int bufNum, dma_addr_t phyaddr)
  184296. +{
  184297. + if (bufNum == 2) {
  184298. + ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184299. + if (ch <= 0)
  184300. + return;
  184301. + bufNum = 0;
  184302. + }
  184303. +
  184304. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 29 * bufNum, 29,
  184305. + phyaddr / 8);
  184306. +};
  184307. +
  184308. +static inline void _ipu_ch_param_set_rotation(struct ipu_soc *ipu, uint32_t ch,
  184309. + ipu_rotate_mode_t rot)
  184310. +{
  184311. + u32 temp_rot = bitrev8(rot) >> 5;
  184312. + int32_t sub_ch = 0;
  184313. +
  184314. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 119, 3, temp_rot);
  184315. +
  184316. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184317. + if (sub_ch <= 0)
  184318. + return;
  184319. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 119, 3, temp_rot);
  184320. +};
  184321. +
  184322. +static inline void _ipu_ch_param_set_block_mode(struct ipu_soc *ipu, uint32_t ch)
  184323. +{
  184324. + int32_t sub_ch = 0;
  184325. +
  184326. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 117, 2, 1);
  184327. +
  184328. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184329. + if (sub_ch <= 0)
  184330. + return;
  184331. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 117, 2, 1);
  184332. +};
  184333. +
  184334. +static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *ipu,
  184335. + uint32_t ch,
  184336. + bool option)
  184337. +{
  184338. + int32_t sub_ch = 0;
  184339. +
  184340. + if (option) {
  184341. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 1);
  184342. + } else {
  184343. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 0);
  184344. + }
  184345. +
  184346. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184347. + if (sub_ch <= 0)
  184348. + return;
  184349. +
  184350. + if (option) {
  184351. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 1);
  184352. + } else {
  184353. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 0);
  184354. + }
  184355. +};
  184356. +
  184357. +static inline void _ipu_ch_param_set_alpha_condition_read(struct ipu_soc *ipu, uint32_t ch)
  184358. +{
  184359. + int32_t sub_ch = 0;
  184360. +
  184361. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 149, 1, 1);
  184362. +
  184363. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184364. + if (sub_ch <= 0)
  184365. + return;
  184366. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 149, 1, 1);
  184367. +};
  184368. +
  184369. +static inline void _ipu_ch_param_set_alpha_buffer_memory(struct ipu_soc *ipu, uint32_t ch)
  184370. +{
  184371. + int alp_mem_idx;
  184372. + int32_t sub_ch = 0;
  184373. +
  184374. + switch (ch) {
  184375. + case 14: /* PRP graphic */
  184376. + alp_mem_idx = 0;
  184377. + break;
  184378. + case 15: /* PP graphic */
  184379. + alp_mem_idx = 1;
  184380. + break;
  184381. + case 23: /* DP BG SYNC graphic */
  184382. + alp_mem_idx = 4;
  184383. + break;
  184384. + case 27: /* DP FG SYNC graphic */
  184385. + alp_mem_idx = 2;
  184386. + break;
  184387. + default:
  184388. + dev_err(ipu->dev, "unsupported correlative channel of local "
  184389. + "alpha channel\n");
  184390. + return;
  184391. + }
  184392. +
  184393. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 90, 3, alp_mem_idx);
  184394. +
  184395. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184396. + if (sub_ch <= 0)
  184397. + return;
  184398. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 90, 3, alp_mem_idx);
  184399. +};
  184400. +
  184401. +static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32_t ch)
  184402. +{
  184403. + u32 stride;
  184404. + int32_t sub_ch = 0;
  184405. +
  184406. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184407. +
  184408. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 0, 113, 1, 1);
  184409. + if (sub_ch > 0)
  184410. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 113, 1, 1);
  184411. + stride = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14) + 1;
  184412. + /* ILO is 20-bit and 8-byte aligned */
  184413. + if (stride/8 > 0xfffff)
  184414. + dev_warn(ipu->dev,
  184415. + "IDMAC%d's ILO exceeds IPU limitation\n", ch);
  184416. + if (stride%8)
  184417. + dev_warn(ipu->dev,
  184418. + "IDMAC%d's ILO is not 8-byte aligned\n", ch);
  184419. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 58, 20, stride / 8);
  184420. + if (sub_ch > 0)
  184421. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 58, 20,
  184422. + stride / 8);
  184423. + stride *= 2;
  184424. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 102, 14, stride - 1);
  184425. + if (sub_ch > 0)
  184426. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 102, 14,
  184427. + stride - 1);
  184428. +};
  184429. +
  184430. +static inline void _ipu_ch_param_set_axi_id(struct ipu_soc *ipu, uint32_t ch, uint32_t id)
  184431. +{
  184432. + int32_t sub_ch = 0;
  184433. +
  184434. + id %= 4;
  184435. +
  184436. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 1, 93, 2, id);
  184437. +
  184438. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184439. + if (sub_ch <= 0)
  184440. + return;
  184441. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 93, 2, id);
  184442. +};
  184443. +
  184444. +/* IDMAC U/V offset changing support */
  184445. +/* U and V input is not affected, */
  184446. +/* the update is done by new calculation according to */
  184447. +/* vertical_offset and horizontal_offset */
  184448. +static inline void _ipu_ch_offset_update(struct ipu_soc *ipu,
  184449. + int ch,
  184450. + uint32_t pixel_fmt,
  184451. + uint32_t width,
  184452. + uint32_t height,
  184453. + uint32_t stride,
  184454. + uint32_t u,
  184455. + uint32_t v,
  184456. + uint32_t uv_stride,
  184457. + uint32_t vertical_offset,
  184458. + uint32_t horizontal_offset)
  184459. +{
  184460. + uint32_t u_offset = 0;
  184461. + uint32_t v_offset = 0;
  184462. + uint32_t old_offset = 0;
  184463. + uint32_t u_fix = 0;
  184464. + uint32_t v_fix = 0;
  184465. + int32_t sub_ch = 0;
  184466. +
  184467. + switch (pixel_fmt) {
  184468. + case IPU_PIX_FMT_GENERIC:
  184469. + case IPU_PIX_FMT_GENERIC_16:
  184470. + case IPU_PIX_FMT_GENERIC_32:
  184471. + case IPU_PIX_FMT_RGB565:
  184472. + case IPU_PIX_FMT_BGR24:
  184473. + case IPU_PIX_FMT_RGB24:
  184474. + case IPU_PIX_FMT_YUV444:
  184475. + case IPU_PIX_FMT_BGRA32:
  184476. + case IPU_PIX_FMT_BGR32:
  184477. + case IPU_PIX_FMT_RGBA32:
  184478. + case IPU_PIX_FMT_RGB32:
  184479. + case IPU_PIX_FMT_ABGR32:
  184480. + case IPU_PIX_FMT_UYVY:
  184481. + case IPU_PIX_FMT_YUYV:
  184482. + break;
  184483. +
  184484. + case IPU_PIX_FMT_YUV420P2:
  184485. + case IPU_PIX_FMT_YUV420P:
  184486. + if (uv_stride < stride / 2)
  184487. + uv_stride = stride / 2;
  184488. +
  184489. + u_offset = stride * (height - vertical_offset - 1) +
  184490. + (stride - horizontal_offset) +
  184491. + (uv_stride * vertical_offset / 2) +
  184492. + horizontal_offset / 2;
  184493. + v_offset = u_offset + (uv_stride * height / 2);
  184494. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  184495. + (horizontal_offset / 2) -
  184496. + (stride * vertical_offset) - (horizontal_offset)) :
  184497. + u_offset;
  184498. + v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
  184499. + (horizontal_offset / 2) -
  184500. + (stride * vertical_offset) - (horizontal_offset)) :
  184501. + v_offset;
  184502. +
  184503. + break;
  184504. + case IPU_PIX_FMT_YVU420P:
  184505. + if (uv_stride < stride / 2)
  184506. + uv_stride = stride / 2;
  184507. +
  184508. + v_offset = stride * (height - vertical_offset - 1) +
  184509. + (stride - horizontal_offset) +
  184510. + (uv_stride * vertical_offset / 2) +
  184511. + horizontal_offset / 2;
  184512. + u_offset = v_offset + (uv_stride * height / 2);
  184513. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  184514. + (horizontal_offset / 2) -
  184515. + (stride * vertical_offset) - (horizontal_offset)) :
  184516. + u_offset;
  184517. + v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
  184518. + (horizontal_offset / 2) -
  184519. + (stride * vertical_offset) - (horizontal_offset)) :
  184520. + v_offset;
  184521. +
  184522. + break;
  184523. + case IPU_PIX_FMT_YVU422P:
  184524. + if (uv_stride < stride / 2)
  184525. + uv_stride = stride / 2;
  184526. +
  184527. + v_offset = stride * (height - vertical_offset - 1) +
  184528. + (stride - horizontal_offset) +
  184529. + (uv_stride * vertical_offset) +
  184530. + horizontal_offset / 2;
  184531. + u_offset = v_offset + uv_stride * height;
  184532. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  184533. + horizontal_offset / 2 -
  184534. + (stride * vertical_offset) - (horizontal_offset)) :
  184535. + u_offset;
  184536. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  184537. + horizontal_offset / 2 -
  184538. + (stride * vertical_offset) - (horizontal_offset)) :
  184539. + v_offset;
  184540. + break;
  184541. + case IPU_PIX_FMT_YUV422P:
  184542. + if (uv_stride < stride / 2)
  184543. + uv_stride = stride / 2;
  184544. +
  184545. + u_offset = stride * (height - vertical_offset - 1) +
  184546. + (stride - horizontal_offset) +
  184547. + (uv_stride * vertical_offset) +
  184548. + horizontal_offset / 2;
  184549. + v_offset = u_offset + uv_stride * height;
  184550. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  184551. + horizontal_offset / 2 -
  184552. + (stride * vertical_offset) - (horizontal_offset)) :
  184553. + u_offset;
  184554. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  184555. + horizontal_offset / 2 -
  184556. + (stride * vertical_offset) - (horizontal_offset)) :
  184557. + v_offset;
  184558. + break;
  184559. +
  184560. + case IPU_PIX_FMT_YUV444P:
  184561. + uv_stride = stride;
  184562. + u_offset = stride * (height - vertical_offset - 1) +
  184563. + (stride - horizontal_offset) +
  184564. + (uv_stride * vertical_offset) +
  184565. + horizontal_offset;
  184566. + v_offset = u_offset + uv_stride * height;
  184567. + u_fix = u ? (u + (uv_stride * vertical_offset) +
  184568. + horizontal_offset -
  184569. + (stride * vertical_offset) -
  184570. + (horizontal_offset)) :
  184571. + u_offset;
  184572. + v_fix = v ? (v + (uv_stride * vertical_offset) +
  184573. + horizontal_offset -
  184574. + (stride * vertical_offset) -
  184575. + (horizontal_offset)) :
  184576. + v_offset;
  184577. + break;
  184578. + case IPU_PIX_FMT_NV12:
  184579. + uv_stride = stride;
  184580. + u_offset = stride * (height - vertical_offset - 1) +
  184581. + (stride - horizontal_offset) +
  184582. + (uv_stride * vertical_offset / 2) +
  184583. + horizontal_offset;
  184584. + u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
  184585. + horizontal_offset -
  184586. + (stride * vertical_offset) - (horizontal_offset)) :
  184587. + u_offset;
  184588. +
  184589. + break;
  184590. + default:
  184591. + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n");
  184592. + break;
  184593. + }
  184594. +
  184595. +
  184596. +
  184597. + if (u_fix > u_offset)
  184598. + u_offset = u_fix;
  184599. +
  184600. + if (v_fix > v_offset)
  184601. + v_offset = v_fix;
  184602. +
  184603. + /* UBO and VBO are 22-bit and 8-byte aligned */
  184604. + if (u_offset/8 > 0x3fffff)
  184605. + dev_warn(ipu->dev,
  184606. + "IDMAC%d's U offset exceeds IPU limitation\n", ch);
  184607. + if (v_offset/8 > 0x3fffff)
  184608. + dev_warn(ipu->dev,
  184609. + "IDMAC%d's V offset exceeds IPU limitation\n", ch);
  184610. + if (u_offset%8)
  184611. + dev_warn(ipu->dev,
  184612. + "IDMAC%d's U offset is not 8-byte aligned\n", ch);
  184613. + if (v_offset%8)
  184614. + dev_warn(ipu->dev,
  184615. + "IDMAC%d's V offset is not 8-byte aligned\n", ch);
  184616. +
  184617. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22);
  184618. + if (old_offset != u_offset / 8)
  184619. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8);
  184620. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22);
  184621. + if (old_offset != v_offset / 8)
  184622. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8);
  184623. +
  184624. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184625. + if (sub_ch <= 0)
  184626. + return;
  184627. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22);
  184628. + if (old_offset != u_offset / 8)
  184629. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8);
  184630. + old_offset = ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22);
  184631. + if (old_offset != v_offset / 8)
  184632. + ipu_ch_param_mod_field_io(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8);
  184633. +};
  184634. +
  184635. +static inline void _ipu_ch_params_set_alpha_width(struct ipu_soc *ipu, uint32_t ch, int alpha_width)
  184636. +{
  184637. + int32_t sub_ch = 0;
  184638. +
  184639. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch), 1, 125, 3, alpha_width - 1);
  184640. +
  184641. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184642. + if (sub_ch <= 0)
  184643. + return;
  184644. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch), 1, 125, 3, alpha_width - 1);
  184645. +};
  184646. +
  184647. +static inline void _ipu_ch_param_set_bandmode(struct ipu_soc *ipu,
  184648. + uint32_t ch, uint32_t band_height)
  184649. +{
  184650. + int32_t sub_ch = 0;
  184651. +
  184652. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, ch),
  184653. + 0, 114, 3, band_height - 1);
  184654. + sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch);
  184655. + if (sub_ch <= 0)
  184656. + return;
  184657. + ipu_ch_param_set_field_io(ipu_ch_param_addr(ipu, sub_ch),
  184658. + 0, 114, 3, band_height - 1);
  184659. +
  184660. + dev_dbg(ipu->dev, "BNDM 0x%x, ",
  184661. + ipu_ch_param_read_field_io(ipu_ch_param_addr(ipu, ch), 0, 114, 3));
  184662. +}
  184663. +
  184664. +/*
  184665. + * The IPUv3 IDMAC has a bug to read 32bpp pixels from a graphics plane
  184666. + * whose alpha component is at the most significant 8 bits. The bug only
  184667. + * impacts on cases in which the relevant separate alpha channel is enabled.
  184668. + *
  184669. + * Return true on bad alpha component position, otherwise, return false.
  184670. + */
  184671. +static inline bool _ipu_ch_param_bad_alpha_pos(uint32_t pixel_fmt)
  184672. +{
  184673. + switch (pixel_fmt) {
  184674. + case IPU_PIX_FMT_BGRA32:
  184675. + case IPU_PIX_FMT_BGR32:
  184676. + case IPU_PIX_FMT_RGBA32:
  184677. + case IPU_PIX_FMT_RGB32:
  184678. + return true;
  184679. + }
  184680. +
  184681. + return false;
  184682. +}
  184683. +#endif
  184684. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_pixel_clk.c linux-imx6-3.14/drivers/mxc/ipu3/ipu_pixel_clk.c
  184685. --- linux-3.14.17/drivers/mxc/ipu3/ipu_pixel_clk.c 1970-01-01 01:00:00.000000000 +0100
  184686. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_pixel_clk.c 2014-09-11 18:06:03.134042499 +0200
  184687. @@ -0,0 +1,317 @@
  184688. +/*
  184689. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  184690. + */
  184691. +
  184692. +/*
  184693. + * The code contained herein is licensed under the GNU General Public
  184694. + * License. You may obtain a copy of the GNU General Public License
  184695. + * Version 2 or later at the following locations:
  184696. + *
  184697. + * http://www.opensource.org/licenses/gpl-license.html
  184698. + * http://www.gnu.org/copyleft/gpl.html
  184699. + */
  184700. +
  184701. +/*!
  184702. + * @file ipu_pixel_clk.c
  184703. + *
  184704. + * @brief IPU pixel clock implementation
  184705. + *
  184706. + * @ingroup IPU
  184707. + */
  184708. +
  184709. +#include <linux/clk-provider.h>
  184710. +#include <linux/err.h>
  184711. +#include <linux/io.h>
  184712. +#include <linux/ipu-v3.h>
  184713. +#include <linux/module.h>
  184714. +#include <linux/slab.h>
  184715. +#include <linux/string.h>
  184716. +
  184717. +#include "ipu_prv.h"
  184718. +#include "ipu_regs.h"
  184719. +
  184720. + /*
  184721. + * muxd clock implementation
  184722. + */
  184723. +struct clk_di_mux {
  184724. + struct clk_hw hw;
  184725. + u8 ipu_id;
  184726. + u8 di_id;
  184727. + u8 flags;
  184728. + u8 index;
  184729. +};
  184730. +#define to_clk_di_mux(_hw) container_of(_hw, struct clk_di_mux, hw)
  184731. +
  184732. +static int _ipu_pixel_clk_set_parent(struct clk_hw *hw, u8 index)
  184733. +{
  184734. + struct clk_di_mux *mux = to_clk_di_mux(hw);
  184735. + struct ipu_soc *ipu = ipu_get_soc(mux->ipu_id);
  184736. + u32 di_gen;
  184737. +
  184738. + di_gen = ipu_di_read(ipu, mux->di_id, DI_GENERAL);
  184739. + if (index == 0)
  184740. + /* ipu1_clk or ipu2_clk internal clk */
  184741. + di_gen &= ~DI_GEN_DI_CLK_EXT;
  184742. + else
  184743. + di_gen |= DI_GEN_DI_CLK_EXT;
  184744. +
  184745. + ipu_di_write(ipu, mux->di_id, di_gen, DI_GENERAL);
  184746. + mux->index = index;
  184747. + pr_debug("ipu_pixel_clk: di_clk_ext:0x%x, di_gen reg:0x%x.\n",
  184748. + !(di_gen & DI_GEN_DI_CLK_EXT), di_gen);
  184749. + return 0;
  184750. +}
  184751. +
  184752. +static u8 _ipu_pixel_clk_get_parent(struct clk_hw *hw)
  184753. +{
  184754. + struct clk_di_mux *mux = to_clk_di_mux(hw);
  184755. +
  184756. + return mux->index;
  184757. +}
  184758. +
  184759. +const struct clk_ops clk_mux_di_ops = {
  184760. + .get_parent = _ipu_pixel_clk_get_parent,
  184761. + .set_parent = _ipu_pixel_clk_set_parent,
  184762. +};
  184763. +
  184764. +struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
  184765. + const char **parent_names, u8 num_parents, unsigned long flags,
  184766. + u8 ipu_id, u8 di_id, u8 clk_mux_flags)
  184767. +{
  184768. + struct clk_di_mux *mux;
  184769. + struct clk *clk;
  184770. + struct clk_init_data init;
  184771. +
  184772. + mux = kzalloc(sizeof(struct clk_di_mux), GFP_KERNEL);
  184773. + if (!mux)
  184774. + return ERR_PTR(-ENOMEM);
  184775. +
  184776. + init.name = name;
  184777. + init.ops = &clk_mux_di_ops;
  184778. + init.flags = flags;
  184779. + init.parent_names = parent_names;
  184780. + init.num_parents = num_parents;
  184781. +
  184782. + mux->ipu_id = ipu_id;
  184783. + mux->di_id = di_id;
  184784. + mux->flags = clk_mux_flags | CLK_SET_RATE_PARENT;
  184785. + mux->hw.init = &init;
  184786. +
  184787. + clk = clk_register(dev, &mux->hw);
  184788. + if (IS_ERR(clk))
  184789. + kfree(mux);
  184790. +
  184791. + return clk;
  184792. +}
  184793. +
  184794. +/*
  184795. + * Gated clock implementation
  184796. + */
  184797. +struct clk_di_div {
  184798. + struct clk_hw hw;
  184799. + u8 ipu_id;
  184800. + u8 di_id;
  184801. + u8 flags;
  184802. +};
  184803. +#define to_clk_di_div(_hw) container_of(_hw, struct clk_di_div, hw)
  184804. +
  184805. +static unsigned long _ipu_pixel_clk_div_recalc_rate(struct clk_hw *hw,
  184806. + unsigned long parent_rate)
  184807. +{
  184808. + struct clk_di_div *di_div = to_clk_di_div(hw);
  184809. + struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
  184810. + u32 div;
  184811. + u64 final_rate = (unsigned long long)parent_rate * 16;
  184812. +
  184813. + _ipu_get(ipu);
  184814. + div = ipu_di_read(ipu, di_div->di_id, DI_BS_CLKGEN0);
  184815. + _ipu_put(ipu);
  184816. + pr_debug("ipu_di%d read BS_CLKGEN0 div:%d, final_rate:%lld, prate:%ld\n",
  184817. + di_div->di_id, div, final_rate, parent_rate);
  184818. +
  184819. + if (div == 0)
  184820. + return 0;
  184821. + do_div(final_rate, div);
  184822. +
  184823. + return (unsigned long)final_rate;
  184824. +}
  184825. +
  184826. +static long _ipu_pixel_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
  184827. + unsigned long *parent_clk_rate)
  184828. +{
  184829. + u64 div, final_rate;
  184830. + u32 remainder;
  184831. + u64 parent_rate = (unsigned long long)(*parent_clk_rate) * 16;
  184832. +
  184833. + /*
  184834. + * Calculate divider
  184835. + * Fractional part is 4 bits,
  184836. + * so simply multiply by 2^4 to get fractional part.
  184837. + */
  184838. + div = parent_rate;
  184839. + remainder = do_div(div, rate);
  184840. + /* Round the divider value */
  184841. + if (remainder > (rate/2))
  184842. + div++;
  184843. + if (div < 0x10) /* Min DI disp clock divider is 1 */
  184844. + div = 0x10;
  184845. + if (div & ~0xFEF)
  184846. + div &= 0xFF8;
  184847. + else {
  184848. + /* Round up divider if it gets us closer to desired pix clk */
  184849. + if ((div & 0xC) == 0xC) {
  184850. + div += 0x10;
  184851. + div &= ~0xF;
  184852. + }
  184853. + }
  184854. + final_rate = parent_rate;
  184855. + do_div(final_rate, div);
  184856. +
  184857. + return final_rate;
  184858. +}
  184859. +
  184860. +static int _ipu_pixel_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
  184861. + unsigned long parent_clk_rate)
  184862. +{
  184863. + struct clk_di_div *di_div = to_clk_di_div(hw);
  184864. + struct ipu_soc *ipu = ipu_get_soc(di_div->ipu_id);
  184865. + u64 div, parent_rate;
  184866. + u32 remainder;
  184867. +
  184868. + parent_rate = (unsigned long long)parent_clk_rate * 16;
  184869. + div = parent_rate;
  184870. + remainder = do_div(div, rate);
  184871. + /* Round the divider value */
  184872. + if (remainder > (rate/2))
  184873. + div++;
  184874. +
  184875. + /* Round up divider if it gets us closer to desired pix clk */
  184876. + if ((div & 0xC) == 0xC) {
  184877. + div += 0x10;
  184878. + div &= ~0xF;
  184879. + }
  184880. + if (div > 0x1000)
  184881. + pr_err("Overflow, di:%d, DI_BS_CLKGEN0 div:0x%x\n",
  184882. + di_div->di_id, (u32)div);
  184883. + _ipu_get(ipu);
  184884. + ipu_di_write(ipu, di_div->di_id, (u32)div, DI_BS_CLKGEN0);
  184885. +
  184886. + /* Setup pixel clock timing */
  184887. + /* FIXME: needs to be more flexible */
  184888. + /* Down time is half of period */
  184889. + ipu_di_write(ipu, di_div->di_id, ((u32)div / 16) << 16, DI_BS_CLKGEN1);
  184890. + _ipu_put(ipu);
  184891. +
  184892. + return 0;
  184893. +}
  184894. +
  184895. +static struct clk_ops clk_div_ops = {
  184896. + .recalc_rate = _ipu_pixel_clk_div_recalc_rate,
  184897. + .round_rate = _ipu_pixel_clk_div_round_rate,
  184898. + .set_rate = _ipu_pixel_clk_div_set_rate,
  184899. +};
  184900. +
  184901. +struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
  184902. + const char *parent_name, unsigned long flags,
  184903. + u8 ipu_id, u8 di_id, u8 clk_div_flags)
  184904. +{
  184905. + struct clk_di_div *di_div;
  184906. + struct clk *clk;
  184907. + struct clk_init_data init;
  184908. +
  184909. + di_div = kzalloc(sizeof(struct clk_di_div), GFP_KERNEL);
  184910. + if (!di_div)
  184911. + return ERR_PTR(-ENOMEM);
  184912. +
  184913. + /* struct clk_di_div assignments */
  184914. + di_div->ipu_id = ipu_id;
  184915. + di_div->di_id = di_id;
  184916. + di_div->flags = clk_div_flags;
  184917. +
  184918. + init.name = name;
  184919. + init.ops = &clk_div_ops;
  184920. + init.flags = flags | CLK_SET_RATE_PARENT;
  184921. + init.parent_names = parent_name ? &parent_name : NULL;
  184922. + init.num_parents = parent_name ? 1 : 0;
  184923. +
  184924. + di_div->hw.init = &init;
  184925. +
  184926. + clk = clk_register(dev, &di_div->hw);
  184927. + if (IS_ERR(clk))
  184928. + kfree(clk);
  184929. +
  184930. + return clk;
  184931. +}
  184932. +
  184933. +/*
  184934. + * Gated clock implementation
  184935. + */
  184936. +struct clk_di_gate {
  184937. + struct clk_hw hw;
  184938. + u8 ipu_id;
  184939. + u8 di_id;
  184940. + u8 flags;
  184941. +};
  184942. +#define to_clk_di_gate(_hw) container_of(_hw, struct clk_di_gate, hw)
  184943. +
  184944. +static int _ipu_pixel_clk_enable(struct clk_hw *hw)
  184945. +{
  184946. + struct clk_di_gate *gate = to_clk_di_gate(hw);
  184947. + struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
  184948. + u32 disp_gen;
  184949. +
  184950. + disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
  184951. + disp_gen |= gate->di_id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE;
  184952. + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
  184953. +
  184954. + return 0;
  184955. +}
  184956. +
  184957. +static void _ipu_pixel_clk_disable(struct clk_hw *hw)
  184958. +{
  184959. + struct clk_di_gate *gate = to_clk_di_gate(hw);
  184960. + struct ipu_soc *ipu = ipu_get_soc(gate->ipu_id);
  184961. + u32 disp_gen;
  184962. +
  184963. + disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN);
  184964. + disp_gen &= gate->di_id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
  184965. + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN);
  184966. +
  184967. +}
  184968. +
  184969. +
  184970. +static struct clk_ops clk_gate_di_ops = {
  184971. + .enable = _ipu_pixel_clk_enable,
  184972. + .disable = _ipu_pixel_clk_disable,
  184973. +};
  184974. +
  184975. +struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
  184976. + const char *parent_name, unsigned long flags,
  184977. + u8 ipu_id, u8 di_id, u8 clk_gate_flags)
  184978. +{
  184979. + struct clk_di_gate *gate;
  184980. + struct clk *clk;
  184981. + struct clk_init_data init;
  184982. +
  184983. + gate = kzalloc(sizeof(struct clk_di_gate), GFP_KERNEL);
  184984. + if (!gate)
  184985. + return ERR_PTR(-ENOMEM);
  184986. +
  184987. + gate->ipu_id = ipu_id;
  184988. + gate->di_id = di_id;
  184989. + gate->flags = clk_gate_flags;
  184990. +
  184991. + init.name = name;
  184992. + init.ops = &clk_gate_di_ops;
  184993. + init.flags = flags | CLK_SET_RATE_PARENT;
  184994. + init.parent_names = parent_name ? &parent_name : NULL;
  184995. + init.num_parents = parent_name ? 1 : 0;
  184996. +
  184997. + gate->hw.init = &init;
  184998. +
  184999. + clk = clk_register(dev, &gate->hw);
  185000. + if (IS_ERR(clk))
  185001. + kfree(clk);
  185002. +
  185003. + return clk;
  185004. +}
  185005. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_prv.h linux-imx6-3.14/drivers/mxc/ipu3/ipu_prv.h
  185006. --- linux-3.14.17/drivers/mxc/ipu3/ipu_prv.h 1970-01-01 01:00:00.000000000 +0100
  185007. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_prv.h 2014-09-11 18:06:03.138042515 +0200
  185008. @@ -0,0 +1,356 @@
  185009. +/*
  185010. + * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  185011. + */
  185012. +
  185013. +/*
  185014. + * The code contained herein is licensed under the GNU General Public
  185015. + * License. You may obtain a copy of the GNU General Public License
  185016. + * Version 2 or later at the following locations:
  185017. + *
  185018. + * http://www.opensource.org/licenses/gpl-license.html
  185019. + * http://www.gnu.org/copyleft/gpl.html
  185020. + */
  185021. +#ifndef __INCLUDE_IPU_PRV_H__
  185022. +#define __INCLUDE_IPU_PRV_H__
  185023. +
  185024. +#include <linux/clkdev.h>
  185025. +#include <linux/device.h>
  185026. +#include <linux/fsl_devices.h>
  185027. +#include <linux/interrupt.h>
  185028. +#include <linux/types.h>
  185029. +
  185030. +#define MXC_IPU_MAX_NUM 2
  185031. +#define MXC_DI_NUM_PER_IPU 2
  185032. +
  185033. +/* Globals */
  185034. +extern int dmfc_type_setup;
  185035. +
  185036. +#define IDMA_CHAN_INVALID 0xFF
  185037. +#define HIGH_RESOLUTION_WIDTH 1024
  185038. +
  185039. +struct ipu_irq_node {
  185040. + irqreturn_t(*handler) (int, void *); /*!< the ISR */
  185041. + const char *name; /*!< device associated with the interrupt */
  185042. + void *dev_id; /*!< some unique information for the ISR */
  185043. + __u32 flags; /*!< not used */
  185044. +};
  185045. +
  185046. +enum csc_type_t {
  185047. + RGB2YUV = 0,
  185048. + YUV2RGB,
  185049. + RGB2RGB,
  185050. + YUV2YUV,
  185051. + CSC_NONE,
  185052. + CSC_NUM
  185053. +};
  185054. +
  185055. +enum imx_ipu_type {
  185056. + IMX6Q_IPU,
  185057. +};
  185058. +
  185059. +struct ipu_pltfm_data {
  185060. + u32 id;
  185061. + u32 devtype;
  185062. + int (*init) (int);
  185063. + void (*pg) (int);
  185064. +
  185065. + /*
  185066. + * Bypass reset to avoid display channel being
  185067. + * stopped by probe since it may starts to work
  185068. + * in bootloader.
  185069. + */
  185070. + bool bypass_reset;
  185071. +};
  185072. +
  185073. +struct ipu_soc {
  185074. + bool online;
  185075. + struct ipu_pltfm_data *pdata;
  185076. +
  185077. + /*clk*/
  185078. + struct clk *ipu_clk;
  185079. + struct clk *di_clk[2];
  185080. + struct clk *di_clk_sel[2];
  185081. + struct clk *pixel_clk[2];
  185082. + struct clk *pixel_clk_sel[2];
  185083. + struct clk *csi_clk[2];
  185084. +
  185085. + /*irq*/
  185086. + int irq_sync;
  185087. + int irq_err;
  185088. + struct ipu_irq_node irq_list[IPU_IRQ_COUNT];
  185089. +
  185090. + /*reg*/
  185091. + void __iomem *cm_reg;
  185092. + void __iomem *idmac_reg;
  185093. + void __iomem *dp_reg;
  185094. + void __iomem *ic_reg;
  185095. + void __iomem *dc_reg;
  185096. + void __iomem *dc_tmpl_reg;
  185097. + void __iomem *dmfc_reg;
  185098. + void __iomem *di_reg[2];
  185099. + void __iomem *smfc_reg;
  185100. + void __iomem *csi_reg[2];
  185101. + void __iomem *cpmem_base;
  185102. + void __iomem *tpmem_base;
  185103. + void __iomem *disp_base[2];
  185104. + void __iomem *vdi_reg;
  185105. +
  185106. + struct device *dev;
  185107. +
  185108. + ipu_channel_t csi_channel[2];
  185109. + ipu_channel_t using_ic_dirct_ch;
  185110. + unsigned char dc_di_assignment[10];
  185111. + bool sec_chan_en[24];
  185112. + bool thrd_chan_en[24];
  185113. + bool chan_is_interlaced[52];
  185114. + uint32_t channel_init_mask;
  185115. + uint32_t channel_enable_mask;
  185116. +
  185117. + /*use count*/
  185118. + int dc_use_count;
  185119. + int dp_use_count;
  185120. + int dmfc_use_count;
  185121. + int smfc_use_count;
  185122. + int ic_use_count;
  185123. + int rot_use_count;
  185124. + int vdi_use_count;
  185125. + int di_use_count[2];
  185126. + int csi_use_count[2];
  185127. +
  185128. + struct mutex mutex_lock;
  185129. + spinlock_t int_reg_spin_lock;
  185130. + spinlock_t rdy_reg_spin_lock;
  185131. +
  185132. + int dmfc_size_28;
  185133. + int dmfc_size_29;
  185134. + int dmfc_size_24;
  185135. + int dmfc_size_27;
  185136. + int dmfc_size_23;
  185137. +
  185138. + enum csc_type_t fg_csc_type;
  185139. + enum csc_type_t bg_csc_type;
  185140. + bool color_key_4rgb;
  185141. + bool dc_swap;
  185142. + struct completion dc_comp;
  185143. + struct completion csi_comp;
  185144. +
  185145. + struct rot_mem {
  185146. + void *vaddr;
  185147. + dma_addr_t paddr;
  185148. + int size;
  185149. + } rot_dma[2];
  185150. +
  185151. + int vdoa_en;
  185152. + struct task_struct *thread[2];
  185153. +
  185154. +};
  185155. +
  185156. +struct ipu_channel {
  185157. + u8 video_in_dma;
  185158. + u8 alpha_in_dma;
  185159. + u8 graph_in_dma;
  185160. + u8 out_dma;
  185161. +};
  185162. +
  185163. +enum ipu_dmfc_type {
  185164. + DMFC_NORMAL = 0,
  185165. + DMFC_HIGH_RESOLUTION_DC,
  185166. + DMFC_HIGH_RESOLUTION_DP,
  185167. + DMFC_HIGH_RESOLUTION_ONLY_DP,
  185168. +};
  185169. +
  185170. +static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
  185171. +{
  185172. + return readl(ipu->cm_reg + offset);
  185173. +}
  185174. +
  185175. +static inline void ipu_cm_write(struct ipu_soc *ipu,
  185176. + u32 value, unsigned offset)
  185177. +{
  185178. + writel(value, ipu->cm_reg + offset);
  185179. +}
  185180. +
  185181. +static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset)
  185182. +{
  185183. + return readl(ipu->idmac_reg + offset);
  185184. +}
  185185. +
  185186. +static inline void ipu_idmac_write(struct ipu_soc *ipu,
  185187. + u32 value, unsigned offset)
  185188. +{
  185189. + writel(value, ipu->idmac_reg + offset);
  185190. +}
  185191. +
  185192. +static inline u32 ipu_dc_read(struct ipu_soc *ipu, unsigned offset)
  185193. +{
  185194. + return readl(ipu->dc_reg + offset);
  185195. +}
  185196. +
  185197. +static inline void ipu_dc_write(struct ipu_soc *ipu,
  185198. + u32 value, unsigned offset)
  185199. +{
  185200. + writel(value, ipu->dc_reg + offset);
  185201. +}
  185202. +
  185203. +static inline u32 ipu_dc_tmpl_read(struct ipu_soc *ipu, unsigned offset)
  185204. +{
  185205. + return readl(ipu->dc_tmpl_reg + offset);
  185206. +}
  185207. +
  185208. +static inline void ipu_dc_tmpl_write(struct ipu_soc *ipu,
  185209. + u32 value, unsigned offset)
  185210. +{
  185211. + writel(value, ipu->dc_tmpl_reg + offset);
  185212. +}
  185213. +
  185214. +static inline u32 ipu_dmfc_read(struct ipu_soc *ipu, unsigned offset)
  185215. +{
  185216. + return readl(ipu->dmfc_reg + offset);
  185217. +}
  185218. +
  185219. +static inline void ipu_dmfc_write(struct ipu_soc *ipu,
  185220. + u32 value, unsigned offset)
  185221. +{
  185222. + writel(value, ipu->dmfc_reg + offset);
  185223. +}
  185224. +
  185225. +static inline u32 ipu_dp_read(struct ipu_soc *ipu, unsigned offset)
  185226. +{
  185227. + return readl(ipu->dp_reg + offset);
  185228. +}
  185229. +
  185230. +static inline void ipu_dp_write(struct ipu_soc *ipu,
  185231. + u32 value, unsigned offset)
  185232. +{
  185233. + writel(value, ipu->dp_reg + offset);
  185234. +}
  185235. +
  185236. +static inline u32 ipu_di_read(struct ipu_soc *ipu, int di, unsigned offset)
  185237. +{
  185238. + return readl(ipu->di_reg[di] + offset);
  185239. +}
  185240. +
  185241. +static inline void ipu_di_write(struct ipu_soc *ipu, int di,
  185242. + u32 value, unsigned offset)
  185243. +{
  185244. + writel(value, ipu->di_reg[di] + offset);
  185245. +}
  185246. +
  185247. +static inline u32 ipu_csi_read(struct ipu_soc *ipu, int csi, unsigned offset)
  185248. +{
  185249. + return readl(ipu->csi_reg[csi] + offset);
  185250. +}
  185251. +
  185252. +static inline void ipu_csi_write(struct ipu_soc *ipu, int csi,
  185253. + u32 value, unsigned offset)
  185254. +{
  185255. + writel(value, ipu->csi_reg[csi] + offset);
  185256. +}
  185257. +
  185258. +static inline u32 ipu_smfc_read(struct ipu_soc *ipu, unsigned offset)
  185259. +{
  185260. + return readl(ipu->smfc_reg + offset);
  185261. +}
  185262. +
  185263. +static inline void ipu_smfc_write(struct ipu_soc *ipu,
  185264. + u32 value, unsigned offset)
  185265. +{
  185266. + writel(value, ipu->smfc_reg + offset);
  185267. +}
  185268. +
  185269. +static inline u32 ipu_vdi_read(struct ipu_soc *ipu, unsigned offset)
  185270. +{
  185271. + return readl(ipu->vdi_reg + offset);
  185272. +}
  185273. +
  185274. +static inline void ipu_vdi_write(struct ipu_soc *ipu,
  185275. + u32 value, unsigned offset)
  185276. +{
  185277. + writel(value, ipu->vdi_reg + offset);
  185278. +}
  185279. +
  185280. +static inline u32 ipu_ic_read(struct ipu_soc *ipu, unsigned offset)
  185281. +{
  185282. + return readl(ipu->ic_reg + offset);
  185283. +}
  185284. +
  185285. +static inline void ipu_ic_write(struct ipu_soc *ipu,
  185286. + u32 value, unsigned offset)
  185287. +{
  185288. + writel(value, ipu->ic_reg + offset);
  185289. +}
  185290. +
  185291. +int register_ipu_device(struct ipu_soc *ipu, int id);
  185292. +void unregister_ipu_device(struct ipu_soc *ipu, int id);
  185293. +ipu_color_space_t format_to_colorspace(uint32_t fmt);
  185294. +bool ipu_pixel_format_has_alpha(uint32_t fmt);
  185295. +
  185296. +void ipu_dump_registers(struct ipu_soc *ipu);
  185297. +
  185298. +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
  185299. +
  185300. +void ipu_disp_init(struct ipu_soc *ipu);
  185301. +void _ipu_init_dc_mappings(struct ipu_soc *ipu);
  185302. +int _ipu_dp_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t in_pixel_fmt,
  185303. + uint32_t out_pixel_fmt);
  185304. +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel);
  185305. +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
  185306. +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan);
  185307. +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel);
  185308. +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap);
  185309. +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first);
  185310. +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width);
  185311. +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size);
  185312. +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel);
  185313. +
  185314. +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel);
  185315. +void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel);
  185316. +int _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params,
  185317. + bool src_is_csi);
  185318. +void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
  185319. +void _ipu_vdi_uninit(struct ipu_soc *ipu);
  185320. +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu);
  185321. +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params);
  185322. +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu);
  185323. +void _ipu_ic_init_csi(struct ipu_soc *ipu, ipu_channel_params_t *params);
  185324. +void _ipu_ic_uninit_csi(struct ipu_soc *ipu);
  185325. +int _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params,
  185326. + bool src_is_csi);
  185327. +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu);
  185328. +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params);
  185329. +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu);
  185330. +int _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
  185331. +void _ipu_ic_uninit_pp(struct ipu_soc *ipu);
  185332. +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params);
  185333. +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu);
  185334. +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan, uint16_t width, uint16_t height,
  185335. + int burst_size, ipu_rotate_mode_t rot);
  185336. +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu);
  185337. +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi);
  185338. +int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi);
  185339. +void ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value,
  185340. + uint32_t g_value, uint32_t b_value,
  185341. + uint32_t pix_clk, uint32_t csi);
  185342. +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi);
  185343. +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi);
  185344. +void _ipu_csi_wait4eof(struct ipu_soc *ipu, ipu_channel_t channel);
  185345. +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi);
  185346. +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs);
  185347. +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
  185348. +int32_t _ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  185349. + int16_t x_pos, int16_t y_pos);
  185350. +int32_t _ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel,
  185351. + int16_t *x_pos, int16_t *y_pos);
  185352. +void _ipu_get(struct ipu_soc *ipu);
  185353. +void _ipu_put(struct ipu_soc *ipu);
  185354. +
  185355. +struct clk *clk_register_mux_pix_clk(struct device *dev, const char *name,
  185356. + const char **parent_names, u8 num_parents, unsigned long flags,
  185357. + u8 ipu_id, u8 di_id, u8 clk_mux_flags);
  185358. +struct clk *clk_register_div_pix_clk(struct device *dev, const char *name,
  185359. + const char *parent_name, unsigned long flags,
  185360. + u8 ipu_id, u8 di_id, u8 clk_div_flags);
  185361. +struct clk *clk_register_gate_pix_clk(struct device *dev, const char *name,
  185362. + const char *parent_name, unsigned long flags,
  185363. + u8 ipu_id, u8 di_id, u8 clk_gate_flags);
  185364. +#endif /* __INCLUDE_IPU_PRV_H__ */
  185365. diff -Nur linux-3.14.17/drivers/mxc/ipu3/ipu_regs.h linux-imx6-3.14/drivers/mxc/ipu3/ipu_regs.h
  185366. --- linux-3.14.17/drivers/mxc/ipu3/ipu_regs.h 1970-01-01 01:00:00.000000000 +0100
  185367. +++ linux-imx6-3.14/drivers/mxc/ipu3/ipu_regs.h 2014-09-11 18:06:03.138042515 +0200
  185368. @@ -0,0 +1,743 @@
  185369. +/*
  185370. + * Copyright (C) 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  185371. + */
  185372. +
  185373. +/*
  185374. + * The code contained herein is licensed under the GNU General Public
  185375. + * License. You may obtain a copy of the GNU General Public License
  185376. + * Version 2 or later at the following locations:
  185377. + *
  185378. + * http://www.opensource.org/licenses/gpl-license.html
  185379. + * http://www.gnu.org/copyleft/gpl.html
  185380. + */
  185381. +
  185382. +/*
  185383. + * @file ipu_regs.h
  185384. + *
  185385. + * @brief IPU Register definitions
  185386. + *
  185387. + * @ingroup IPU
  185388. + */
  185389. +#ifndef __IPU_REGS_INCLUDED__
  185390. +#define __IPU_REGS_INCLUDED__
  185391. +
  185392. +enum imx_ipu_rev {
  185393. + IPU_V3DEX = 2,
  185394. + IPU_V3M,
  185395. + IPU_V3H,
  185396. +};
  185397. +
  185398. +/*
  185399. + * hw_rev 2: IPUV3DEX
  185400. + * hw_rev 3: IPUV3M
  185401. + * hw_rev 4: IPUV3H
  185402. + */
  185403. +extern int g_ipu_hw_rev;
  185404. +
  185405. +#define IPU_MAX_VDI_IN_WIDTH ({g_ipu_hw_rev >= 3 ? \
  185406. + (968) : \
  185407. + (720); })
  185408. +#define IPU_DISP0_BASE 0x00000000
  185409. +#define IPU_MCU_T_DEFAULT 8
  185410. +#define IPU_DISP1_BASE ({g_ipu_hw_rev < 4 ? \
  185411. + (IPU_MCU_T_DEFAULT << 25) : \
  185412. + (0x00000000); })
  185413. +#define IPUV3DEX_REG_BASE 0x1E000000
  185414. +#define IPUV3M_REG_BASE 0x06000000
  185415. +#define IPUV3H_REG_BASE 0x00200000
  185416. +
  185417. +#define IPU_CM_REG_BASE 0x00000000
  185418. +#define IPU_IDMAC_REG_BASE 0x00008000
  185419. +#define IPU_ISP_REG_BASE 0x00010000
  185420. +#define IPU_DP_REG_BASE 0x00018000
  185421. +#define IPU_IC_REG_BASE 0x00020000
  185422. +#define IPU_IRT_REG_BASE 0x00028000
  185423. +#define IPU_CSI0_REG_BASE 0x00030000
  185424. +#define IPU_CSI1_REG_BASE 0x00038000
  185425. +#define IPU_DI0_REG_BASE 0x00040000
  185426. +#define IPU_DI1_REG_BASE 0x00048000
  185427. +#define IPU_SMFC_REG_BASE 0x00050000
  185428. +#define IPU_DC_REG_BASE 0x00058000
  185429. +#define IPU_DMFC_REG_BASE 0x00060000
  185430. +#define IPU_VDI_REG_BASE 0x00068000
  185431. +#define IPU_CPMEM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  185432. + (0x00100000) : \
  185433. + (0x01000000); })
  185434. +#define IPU_LUT_REG_BASE 0x01020000
  185435. +#define IPU_SRM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  185436. + (0x00140000) : \
  185437. + (0x01040000); })
  185438. +#define IPU_TPM_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  185439. + (0x00160000) : \
  185440. + (0x01060000); })
  185441. +#define IPU_DC_TMPL_REG_BASE ({g_ipu_hw_rev >= 4 ? \
  185442. + (0x00180000) : \
  185443. + (0x01080000); })
  185444. +#define IPU_ISP_TBPR_REG_BASE 0x010C0000
  185445. +
  185446. +/* Register addresses */
  185447. +/* IPU Common registers */
  185448. +#define IPU_CM_REG(offset) (offset)
  185449. +
  185450. +#define IPU_CONF IPU_CM_REG(0)
  185451. +#define IPU_SRM_PRI1 IPU_CM_REG(0x00A0)
  185452. +#define IPU_SRM_PRI2 IPU_CM_REG(0x00A4)
  185453. +#define IPU_FS_PROC_FLOW1 IPU_CM_REG(0x00A8)
  185454. +#define IPU_FS_PROC_FLOW2 IPU_CM_REG(0x00AC)
  185455. +#define IPU_FS_PROC_FLOW3 IPU_CM_REG(0x00B0)
  185456. +#define IPU_FS_DISP_FLOW1 IPU_CM_REG(0x00B4)
  185457. +#define IPU_FS_DISP_FLOW2 IPU_CM_REG(0x00B8)
  185458. +#define IPU_SKIP IPU_CM_REG(0x00BC)
  185459. +#define IPU_DISP_ALT_CONF IPU_CM_REG(0x00C0)
  185460. +#define IPU_DISP_GEN IPU_CM_REG(0x00C4)
  185461. +#define IPU_DISP_ALT1 IPU_CM_REG(0x00C8)
  185462. +#define IPU_DISP_ALT2 IPU_CM_REG(0x00CC)
  185463. +#define IPU_DISP_ALT3 IPU_CM_REG(0x00D0)
  185464. +#define IPU_DISP_ALT4 IPU_CM_REG(0x00D4)
  185465. +#define IPU_SNOOP IPU_CM_REG(0x00D8)
  185466. +#define IPU_MEM_RST IPU_CM_REG(0x00DC)
  185467. +#define IPU_PM IPU_CM_REG(0x00E0)
  185468. +#define IPU_GPR IPU_CM_REG(0x00E4)
  185469. +#define IPU_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0150 + 4 * ((ch) / 32))
  185470. +#define IPU_ALT_CHA_DB_MODE_SEL(ch) IPU_CM_REG(0x0168 + 4 * ((ch) / 32))
  185471. +/*
  185472. + * IPUv3D doesn't support triple buffer, so point
  185473. + * IPU_CHA_TRB_MODE_SEL, IPU_CHA_TRIPLE_CUR_BUF and
  185474. + * IPU_CHA_BUF2_RDY to readonly
  185475. + * IPU_ALT_CUR_BUF0 for IPUv3D.
  185476. + */
  185477. +#define IPU_CHA_TRB_MODE_SEL(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185478. + (0x0178 + 4 * ((ch) / 32)) : \
  185479. + (0x012C); })
  185480. +#define IPU_CHA_TRIPLE_CUR_BUF(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185481. + (0x0258 + \
  185482. + 4 * (((ch) * 2) / 32)) : \
  185483. + (0x012C); })
  185484. +#define IPU_CHA_BUF2_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185485. + (0x0288 + 4 * ((ch) / 32)) : \
  185486. + (0x012C); })
  185487. +#define IPU_CHA_CUR_BUF(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185488. + (0x023C + 4 * ((ch) / 32)) : \
  185489. + (0x0124 + 4 * ((ch) / 32)); })
  185490. +#define IPU_ALT_CUR_BUF0 IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185491. + (0x0244) : \
  185492. + (0x012C); })
  185493. +#define IPU_ALT_CUR_BUF1 IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185494. + (0x0248) : \
  185495. + (0x0130); })
  185496. +#define IPU_SRM_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185497. + (0x024C) : \
  185498. + (0x0134); })
  185499. +#define IPU_PROC_TASK_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185500. + (0x0250) : \
  185501. + (0x0138); })
  185502. +#define IPU_DISP_TASK_STAT IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185503. + (0x0254) : \
  185504. + (0x013C); })
  185505. +#define IPU_CHA_BUF0_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185506. + (0x0268 + 4 * ((ch) / 32)) : \
  185507. + (0x0140 + 4 * ((ch) / 32)); })
  185508. +#define IPU_CHA_BUF1_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185509. + (0x0270 + 4 * ((ch) / 32)) : \
  185510. + (0x0148 + 4 * ((ch) / 32)); })
  185511. +#define IPU_ALT_CHA_BUF0_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185512. + (0x0278 + 4 * ((ch) / 32)) : \
  185513. + (0x0158 + 4 * ((ch) / 32)); })
  185514. +#define IPU_ALT_CHA_BUF1_RDY(ch) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185515. + (0x0280 + 4 * ((ch) / 32)) : \
  185516. + (0x0160 + 4 * ((ch) / 32)); })
  185517. +
  185518. +#define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * ((n) - 1))
  185519. +#define IPU_INT_STAT(n) IPU_CM_REG({g_ipu_hw_rev >= 2 ? \
  185520. + (0x0200 + 4 * ((n) - 1)) : \
  185521. + (0x00E8 + 4 * ((n) - 1)); })
  185522. +
  185523. +#define IPUIRQ_2_STATREG(irq) IPU_CM_REG(IPU_INT_STAT(1) + 4 * ((irq) / 32))
  185524. +#define IPUIRQ_2_CTRLREG(irq) IPU_CM_REG(IPU_INT_CTRL(1) + 4 * ((irq) / 32))
  185525. +#define IPUIRQ_2_MASK(irq) (1UL << ((irq) & 0x1F))
  185526. +
  185527. +/* IPU VDI registers */
  185528. +#define IPU_VDI_REG(offset) (offset)
  185529. +
  185530. +#define VDI_FSIZE IPU_VDI_REG(0)
  185531. +#define VDI_C IPU_VDI_REG(0x0004)
  185532. +
  185533. +/* IPU CSI Registers */
  185534. +#define IPU_CSI_REG(offset) (offset)
  185535. +
  185536. +#define CSI_SENS_CONF IPU_CSI_REG(0)
  185537. +#define CSI_SENS_FRM_SIZE IPU_CSI_REG(0x0004)
  185538. +#define CSI_ACT_FRM_SIZE IPU_CSI_REG(0x0008)
  185539. +#define CSI_OUT_FRM_CTRL IPU_CSI_REG(0x000C)
  185540. +#define CSI_TST_CTRL IPU_CSI_REG(0x0010)
  185541. +#define CSI_CCIR_CODE_1 IPU_CSI_REG(0x0014)
  185542. +#define CSI_CCIR_CODE_2 IPU_CSI_REG(0x0018)
  185543. +#define CSI_CCIR_CODE_3 IPU_CSI_REG(0x001C)
  185544. +#define CSI_MIPI_DI IPU_CSI_REG(0x0020)
  185545. +#define CSI_SKIP IPU_CSI_REG(0x0024)
  185546. +#define CSI_CPD_CTRL IPU_CSI_REG(0x0028)
  185547. +#define CSI_CPD_RC(n) IPU_CSI_REG(0x002C + 4 * (n))
  185548. +#define CSI_CPD_RS(n) IPU_CSI_REG(0x004C + 4 * (n))
  185549. +#define CSI_CPD_GRC(n) IPU_CSI_REG(0x005C + 4 * (n))
  185550. +#define CSI_CPD_GRS(n) IPU_CSI_REG(0x007C + 4 * (n))
  185551. +#define CSI_CPD_GBC(n) IPU_CSI_REG(0x008C + 4 * (n))
  185552. +#define CSI_CPD_GBS(n) IPU_CSI_REG(0x00AC + 4 * (n))
  185553. +#define CSI_CPD_BC(n) IPU_CSI_REG(0x00BC + 4 * (n))
  185554. +#define CSI_CPD_BS(n) IPU_CSI_REG(0x00DC + 4 * (n))
  185555. +#define CSI_CPD_OFFSET1 IPU_CSI_REG(0x00EC)
  185556. +#define CSI_CPD_OFFSET2 IPU_CSI_REG(0x00F0)
  185557. +
  185558. +/* IPU SMFC Registers */
  185559. +#define IPU_SMFC_REG(offset) (offset)
  185560. +
  185561. +#define SMFC_MAP IPU_SMFC_REG(0)
  185562. +#define SMFC_WMC IPU_SMFC_REG(0x0004)
  185563. +#define SMFC_BS IPU_SMFC_REG(0x0008)
  185564. +
  185565. +/* IPU IC Registers */
  185566. +#define IPU_IC_REG(offset) (offset)
  185567. +
  185568. +#define IC_CONF IPU_IC_REG(0)
  185569. +#define IC_PRP_ENC_RSC IPU_IC_REG(0x0004)
  185570. +#define IC_PRP_VF_RSC IPU_IC_REG(0x0008)
  185571. +#define IC_PP_RSC IPU_IC_REG(0x000C)
  185572. +#define IC_CMBP_1 IPU_IC_REG(0x0010)
  185573. +#define IC_CMBP_2 IPU_IC_REG(0x0014)
  185574. +#define IC_IDMAC_1 IPU_IC_REG(0x0018)
  185575. +#define IC_IDMAC_2 IPU_IC_REG(0x001C)
  185576. +#define IC_IDMAC_3 IPU_IC_REG(0x0020)
  185577. +#define IC_IDMAC_4 IPU_IC_REG(0x0024)
  185578. +
  185579. +/* IPU IDMAC Registers */
  185580. +#define IPU_IDMAC_REG(offset) (offset)
  185581. +
  185582. +#define IDMAC_CONF IPU_IDMAC_REG(0x0000)
  185583. +#define IDMAC_CHA_EN(ch) IPU_IDMAC_REG(0x0004 + 4 * ((ch) / 32))
  185584. +#define IDMAC_SEP_ALPHA IPU_IDMAC_REG(0x000C)
  185585. +#define IDMAC_ALT_SEP_ALPHA IPU_IDMAC_REG(0x0010)
  185586. +#define IDMAC_CHA_PRI(ch) IPU_IDMAC_REG(0x0014 + 4 * ((ch) / 32))
  185587. +#define IDMAC_WM_EN(ch) IPU_IDMAC_REG(0x001C + 4 * ((ch) / 32))
  185588. +#define IDMAC_CH_LOCK_EN_1 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185589. + (0x0024) : 0; })
  185590. +#define IDMAC_CH_LOCK_EN_2 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185591. + (0x0028) : \
  185592. + (0x0024); })
  185593. +#define IDMAC_SUB_ADDR_0 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185594. + (0x002C) : \
  185595. + (0x0028); })
  185596. +#define IDMAC_SUB_ADDR_1 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185597. + (0x0030) : \
  185598. + (0x002C); })
  185599. +#define IDMAC_SUB_ADDR_2 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185600. + (0x0034) : \
  185601. + (0x0030); })
  185602. +/*
  185603. + * IPUv3D doesn't support IDMAC_SUB_ADDR_3 and IDMAC_SUB_ADDR_4,
  185604. + * so point them to readonly IDMAC_CHA_BUSY1 for IPUv3D.
  185605. + */
  185606. +#define IDMAC_SUB_ADDR_3 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185607. + (0x0038) : \
  185608. + (0x0040); })
  185609. +#define IDMAC_SUB_ADDR_4 IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185610. + (0x003C) : \
  185611. + (0x0040); })
  185612. +#define IDMAC_BAND_EN(ch) IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185613. + (0x0040 + 4 * ((ch) / 32)) : \
  185614. + (0x0034 + 4 * ((ch) / 32)); })
  185615. +#define IDMAC_CHA_BUSY(ch) IPU_IDMAC_REG({g_ipu_hw_rev >= 2 ? \
  185616. + (0x0100 + 4 * ((ch) / 32)) : \
  185617. + (0x0040 + 4 * ((ch) / 32)); })
  185618. +
  185619. +/* IPU DI Registers */
  185620. +#define IPU_DI_REG(offset) (offset)
  185621. +
  185622. +#define DI_GENERAL IPU_DI_REG(0)
  185623. +#define DI_BS_CLKGEN0 IPU_DI_REG(0x0004)
  185624. +#define DI_BS_CLKGEN1 IPU_DI_REG(0x0008)
  185625. +#define DI_SW_GEN0(gen) IPU_DI_REG(0x000C + 4 * ((gen) - 1))
  185626. +#define DI_SW_GEN1(gen) IPU_DI_REG(0x0030 + 4 * ((gen) - 1))
  185627. +#define DI_STP_REP(gen) IPU_DI_REG(0x0148 + 4 * (((gen) - 1) / 2))
  185628. +#define DI_SYNC_AS_GEN IPU_DI_REG(0x0054)
  185629. +#define DI_DW_GEN(gen) IPU_DI_REG(0x0058 + 4 * (gen))
  185630. +#define DI_DW_SET(gen, set) IPU_DI_REG(0x0088 + 4 * ((gen) + 0xC * (set)))
  185631. +#define DI_SER_CONF IPU_DI_REG(0x015C)
  185632. +#define DI_SSC IPU_DI_REG(0x0160)
  185633. +#define DI_POL IPU_DI_REG(0x0164)
  185634. +#define DI_AW0 IPU_DI_REG(0x0168)
  185635. +#define DI_AW1 IPU_DI_REG(0x016C)
  185636. +#define DI_SCR_CONF IPU_DI_REG(0x0170)
  185637. +#define DI_STAT IPU_DI_REG(0x0174)
  185638. +
  185639. +/* IPU DMFC Registers */
  185640. +#define IPU_DMFC_REG(offset) (offset)
  185641. +
  185642. +#define DMFC_RD_CHAN IPU_DMFC_REG(0)
  185643. +#define DMFC_WR_CHAN IPU_DMFC_REG(0x0004)
  185644. +#define DMFC_WR_CHAN_DEF IPU_DMFC_REG(0x0008)
  185645. +#define DMFC_DP_CHAN IPU_DMFC_REG(0x000C)
  185646. +#define DMFC_DP_CHAN_DEF IPU_DMFC_REG(0x0010)
  185647. +#define DMFC_GENERAL1 IPU_DMFC_REG(0x0014)
  185648. +#define DMFC_GENERAL2 IPU_DMFC_REG(0x0018)
  185649. +#define DMFC_IC_CTRL IPU_DMFC_REG(0x001C)
  185650. +#define DMFC_STAT IPU_DMFC_REG(0x0020)
  185651. +
  185652. +/* IPU DC Registers */
  185653. +#define IPU_DC_REG(offset) (offset)
  185654. +
  185655. +#define DC_MAP_CONF_PTR(n) IPU_DC_REG(0x0108 + ((n) & ~0x1) * 2)
  185656. +#define DC_MAP_CONF_VAL(n) IPU_DC_REG(0x0144 + ((n) & ~0x1) * 2)
  185657. +
  185658. +#define _RL_CH_2_OFFSET(ch) (((ch) == 0) ? 8 : ( \
  185659. + ((ch) == 1) ? 0x24 : ( \
  185660. + ((ch) == 2) ? 0x40 : ( \
  185661. + ((ch) == 5) ? 0x64 : ( \
  185662. + ((ch) == 6) ? 0x80 : ( \
  185663. + ((ch) == 8) ? 0x9C : ( \
  185664. + ((ch) == 9) ? 0xBC : (-1))))))))
  185665. +#define DC_RL_CH(ch, evt) IPU_DC_REG(_RL_CH_2_OFFSET(ch) + \
  185666. + ((evt) & ~0x1) * 2)
  185667. +
  185668. +#define DC_EVT_NF 0
  185669. +#define DC_EVT_NL 1
  185670. +#define DC_EVT_EOF 2
  185671. +#define DC_EVT_NFIELD 3
  185672. +#define DC_EVT_EOL 4
  185673. +#define DC_EVT_EOFIELD 5
  185674. +#define DC_EVT_NEW_ADDR 6
  185675. +#define DC_EVT_NEW_CHAN 7
  185676. +#define DC_EVT_NEW_DATA 8
  185677. +
  185678. +#define DC_EVT_NEW_ADDR_W_0 0
  185679. +#define DC_EVT_NEW_ADDR_W_1 1
  185680. +#define DC_EVT_NEW_CHAN_W_0 2
  185681. +#define DC_EVT_NEW_CHAN_W_1 3
  185682. +#define DC_EVT_NEW_DATA_W_0 4
  185683. +#define DC_EVT_NEW_DATA_W_1 5
  185684. +#define DC_EVT_NEW_ADDR_R_0 6
  185685. +#define DC_EVT_NEW_ADDR_R_1 7
  185686. +#define DC_EVT_NEW_CHAN_R_0 8
  185687. +#define DC_EVT_NEW_CHAN_R_1 9
  185688. +#define DC_EVT_NEW_DATA_R_0 10
  185689. +#define DC_EVT_NEW_DATA_R_1 11
  185690. +#define DC_EVEN_UGDE0 12
  185691. +#define DC_ODD_UGDE0 13
  185692. +#define DC_EVEN_UGDE1 14
  185693. +#define DC_ODD_UGDE1 15
  185694. +#define DC_EVEN_UGDE2 16
  185695. +#define DC_ODD_UGDE2 17
  185696. +#define DC_EVEN_UGDE3 18
  185697. +#define DC_ODD_UGDE3 19
  185698. +
  185699. +#define dc_ch_offset(ch) \
  185700. +({ \
  185701. + const u8 _offset[] = { \
  185702. + 0, 0x1C, 0x38, 0x54, 0x58, 0x5C, 0x78, 0, 0x94, 0xB4}; \
  185703. + _offset[ch]; \
  185704. +})
  185705. +#define DC_WR_CH_CONF(ch) IPU_DC_REG(dc_ch_offset(ch))
  185706. +#define DC_WR_CH_ADDR(ch) IPU_DC_REG(dc_ch_offset(ch) + 4)
  185707. +
  185708. +#define DC_WR_CH_CONF_1 IPU_DC_REG(0x001C)
  185709. +#define DC_WR_CH_ADDR_1 IPU_DC_REG(0x0020)
  185710. +#define DC_WR_CH_CONF_5 IPU_DC_REG(0x005C)
  185711. +#define DC_WR_CH_ADDR_5 IPU_DC_REG(0x0060)
  185712. +#define DC_GEN IPU_DC_REG(0x00D4)
  185713. +#define DC_DISP_CONF1(disp) IPU_DC_REG(0x00D8 + 4 * (disp))
  185714. +#define DC_DISP_CONF2(disp) IPU_DC_REG(0x00E8 + 4 * (disp))
  185715. +#define DC_STAT IPU_DC_REG(0x01C8)
  185716. +#define DC_UGDE_0(evt) IPU_DC_REG(0x0174 + 16 * (evt))
  185717. +#define DC_UGDE_1(evt) IPU_DC_REG(0x0178 + 16 * (evt))
  185718. +#define DC_UGDE_2(evt) IPU_DC_REG(0x017C + 16 * (evt))
  185719. +#define DC_UGDE_3(evt) IPU_DC_REG(0x0180 + 16 * (evt))
  185720. +
  185721. +/* IPU DP Registers */
  185722. +#define IPU_DP_REG(offset) (offset)
  185723. +
  185724. +#define DP_SYNC 0
  185725. +#define DP_ASYNC0 0x60
  185726. +#define DP_ASYNC1 0xBC
  185727. +#define DP_COM_CONF(flow) IPU_DP_REG(flow)
  185728. +#define DP_GRAPH_WIND_CTRL(flow) IPU_DP_REG(0x0004 + (flow))
  185729. +#define DP_FG_POS(flow) IPU_DP_REG(0x0008 + (flow))
  185730. +#define DP_GAMMA_C(flow, i) IPU_DP_REG(0x0014 + (flow) + 4 * (i))
  185731. +#define DP_GAMMA_S(flow, i) IPU_DP_REG(0x0034 + (flow) + 4 * (i))
  185732. +#define DP_CSC_A_0(flow) IPU_DP_REG(0x0044 + (flow))
  185733. +#define DP_CSC_A_1(flow) IPU_DP_REG(0x0048 + (flow))
  185734. +#define DP_CSC_A_2(flow) IPU_DP_REG(0x004C + (flow))
  185735. +#define DP_CSC_A_3(flow) IPU_DP_REG(0x0050 + (flow))
  185736. +#define DP_CSC_0(flow) IPU_DP_REG(0x0054 + (flow))
  185737. +#define DP_CSC_1(flow) IPU_DP_REG(0x0058 + (flow))
  185738. +
  185739. +enum {
  185740. + IPU_CONF_CSI0_EN = 0x00000001,
  185741. + IPU_CONF_CSI1_EN = 0x00000002,
  185742. + IPU_CONF_IC_EN = 0x00000004,
  185743. + IPU_CONF_ROT_EN = 0x00000008,
  185744. + IPU_CONF_ISP_EN = 0x00000010,
  185745. + IPU_CONF_DP_EN = 0x00000020,
  185746. + IPU_CONF_DI0_EN = 0x00000040,
  185747. + IPU_CONF_DI1_EN = 0x00000080,
  185748. + IPU_CONF_DMFC_EN = 0x00000400,
  185749. + IPU_CONF_SMFC_EN = 0x00000100,
  185750. + IPU_CONF_DC_EN = 0x00000200,
  185751. + IPU_CONF_VDI_EN = 0x00001000,
  185752. + IPU_CONF_IDMAC_DIS = 0x00400000,
  185753. + IPU_CONF_IC_DMFC_SEL = 0x02000000,
  185754. + IPU_CONF_IC_DMFC_SYNC = 0x04000000,
  185755. + IPU_CONF_VDI_DMFC_SYNC = 0x08000000,
  185756. + IPU_CONF_CSI0_DATA_SOURCE = 0x10000000,
  185757. + IPU_CONF_CSI0_DATA_SOURCE_OFFSET = 28,
  185758. + IPU_CONF_CSI1_DATA_SOURCE = 0x20000000,
  185759. + IPU_CONF_IC_INPUT = 0x40000000,
  185760. + IPU_CONF_CSI_SEL = 0x80000000,
  185761. +
  185762. + DI0_COUNTER_RELEASE = 0x01000000,
  185763. + DI1_COUNTER_RELEASE = 0x02000000,
  185764. +
  185765. + FS_PRPVF_ROT_SRC_SEL_MASK = 0x00000F00,
  185766. + FS_PRPVF_ROT_SRC_SEL_OFFSET = 8,
  185767. + FS_PRPENC_ROT_SRC_SEL_MASK = 0x0000000F,
  185768. + FS_PRPENC_ROT_SRC_SEL_OFFSET = 0,
  185769. + FS_PP_ROT_SRC_SEL_MASK = 0x000F0000,
  185770. + FS_PP_ROT_SRC_SEL_OFFSET = 16,
  185771. + FS_PP_SRC_SEL_MASK = 0x0000F000,
  185772. + FS_PP_SRC_SEL_VDOA = 0x00008000,
  185773. + FS_PP_SRC_SEL_OFFSET = 12,
  185774. + FS_PRP_SRC_SEL_MASK = 0x0F000000,
  185775. + FS_PRP_SRC_SEL_OFFSET = 24,
  185776. + FS_VF_IN_VALID = 0x80000000,
  185777. + FS_ENC_IN_VALID = 0x40000000,
  185778. + FS_VDI_SRC_SEL_MASK = 0x30000000,
  185779. + FS_VDI_SRC_SEL_VDOA = 0x20000000,
  185780. + FS_VDOA_DEST_SEL_MASK = 0x00030000,
  185781. + FS_VDOA_DEST_SEL_VDI = 0x00020000,
  185782. + FS_VDOA_DEST_SEL_IC = 0x00010000,
  185783. + FS_VDI_SRC_SEL_OFFSET = 28,
  185784. +
  185785. +
  185786. + FS_PRPENC_DEST_SEL_MASK = 0x0000000F,
  185787. + FS_PRPENC_DEST_SEL_OFFSET = 0,
  185788. + FS_PRPVF_DEST_SEL_MASK = 0x000000F0,
  185789. + FS_PRPVF_DEST_SEL_OFFSET = 4,
  185790. + FS_PRPVF_ROT_DEST_SEL_MASK = 0x00000F00,
  185791. + FS_PRPVF_ROT_DEST_SEL_OFFSET = 8,
  185792. + FS_PP_DEST_SEL_MASK = 0x0000F000,
  185793. + FS_PP_DEST_SEL_OFFSET = 12,
  185794. + FS_PP_ROT_DEST_SEL_MASK = 0x000F0000,
  185795. + FS_PP_ROT_DEST_SEL_OFFSET = 16,
  185796. + FS_PRPENC_ROT_DEST_SEL_MASK = 0x00F00000,
  185797. + FS_PRPENC_ROT_DEST_SEL_OFFSET = 20,
  185798. +
  185799. + FS_SMFC0_DEST_SEL_MASK = 0x0000000F,
  185800. + FS_SMFC0_DEST_SEL_OFFSET = 0,
  185801. + FS_SMFC1_DEST_SEL_MASK = 0x00000070,
  185802. + FS_SMFC1_DEST_SEL_OFFSET = 4,
  185803. + FS_SMFC2_DEST_SEL_MASK = 0x00000780,
  185804. + FS_SMFC2_DEST_SEL_OFFSET = 7,
  185805. + FS_SMFC3_DEST_SEL_MASK = 0x00003800,
  185806. + FS_SMFC3_DEST_SEL_OFFSET = 11,
  185807. +
  185808. + FS_DC1_SRC_SEL_MASK = 0x00F00000,
  185809. + FS_DC1_SRC_SEL_OFFSET = 20,
  185810. + FS_DC2_SRC_SEL_MASK = 0x000F0000,
  185811. + FS_DC2_SRC_SEL_OFFSET = 16,
  185812. + FS_DP_SYNC0_SRC_SEL_MASK = 0x0000000F,
  185813. + FS_DP_SYNC0_SRC_SEL_OFFSET = 0,
  185814. + FS_DP_SYNC1_SRC_SEL_MASK = 0x000000F0,
  185815. + FS_DP_SYNC1_SRC_SEL_OFFSET = 4,
  185816. + FS_DP_ASYNC0_SRC_SEL_MASK = 0x00000F00,
  185817. + FS_DP_ASYNC0_SRC_SEL_OFFSET = 8,
  185818. + FS_DP_ASYNC1_SRC_SEL_MASK = 0x0000F000,
  185819. + FS_DP_ASYNC1_SRC_SEL_OFFSET = 12,
  185820. +
  185821. + FS_AUTO_REF_PER_MASK = 0,
  185822. + FS_AUTO_REF_PER_OFFSET = 16,
  185823. +
  185824. + TSTAT_VF_MASK = 0x0000000C,
  185825. + TSTAT_VF_OFFSET = 2,
  185826. + TSTAT_VF_ROT_MASK = 0x00000300,
  185827. + TSTAT_VF_ROT_OFFSET = 8,
  185828. + TSTAT_ENC_MASK = 0x00000003,
  185829. + TSTAT_ENC_OFFSET = 0,
  185830. + TSTAT_ENC_ROT_MASK = 0x000000C0,
  185831. + TSTAT_ENC_ROT_OFFSET = 6,
  185832. + TSTAT_PP_MASK = 0x00000030,
  185833. + TSTAT_PP_OFFSET = 4,
  185834. + TSTAT_PP_ROT_MASK = 0x00000C00,
  185835. + TSTAT_PP_ROT_OFFSET = 10,
  185836. +
  185837. + TASK_STAT_IDLE = 0,
  185838. + TASK_STAT_ACTIVE = 1,
  185839. + TASK_STAT_WAIT4READY = 2,
  185840. +
  185841. + /* Image Converter Register bits */
  185842. + IC_CONF_PRPENC_EN = 0x00000001,
  185843. + IC_CONF_PRPENC_CSC1 = 0x00000002,
  185844. + IC_CONF_PRPENC_ROT_EN = 0x00000004,
  185845. + IC_CONF_PRPVF_EN = 0x00000100,
  185846. + IC_CONF_PRPVF_CSC1 = 0x00000200,
  185847. + IC_CONF_PRPVF_CSC2 = 0x00000400,
  185848. + IC_CONF_PRPVF_CMB = 0x00000800,
  185849. + IC_CONF_PRPVF_ROT_EN = 0x00001000,
  185850. + IC_CONF_PP_EN = 0x00010000,
  185851. + IC_CONF_PP_CSC1 = 0x00020000,
  185852. + IC_CONF_PP_CSC2 = 0x00040000,
  185853. + IC_CONF_PP_CMB = 0x00080000,
  185854. + IC_CONF_PP_ROT_EN = 0x00100000,
  185855. + IC_CONF_IC_GLB_LOC_A = 0x10000000,
  185856. + IC_CONF_KEY_COLOR_EN = 0x20000000,
  185857. + IC_CONF_RWS_EN = 0x40000000,
  185858. + IC_CONF_CSI_MEM_WR_EN = 0x80000000,
  185859. +
  185860. + IC_RSZ_MAX_RESIZE_RATIO = 0x00004000,
  185861. +
  185862. + IC_IDMAC_1_CB0_BURST_16 = 0x00000001,
  185863. + IC_IDMAC_1_CB1_BURST_16 = 0x00000002,
  185864. + IC_IDMAC_1_CB2_BURST_16 = 0x00000004,
  185865. + IC_IDMAC_1_CB3_BURST_16 = 0x00000008,
  185866. + IC_IDMAC_1_CB4_BURST_16 = 0x00000010,
  185867. + IC_IDMAC_1_CB5_BURST_16 = 0x00000020,
  185868. + IC_IDMAC_1_CB6_BURST_16 = 0x00000040,
  185869. + IC_IDMAC_1_CB7_BURST_16 = 0x00000080,
  185870. + IC_IDMAC_1_PRPENC_ROT_MASK = 0x00003800,
  185871. + IC_IDMAC_1_PRPENC_ROT_OFFSET = 11,
  185872. + IC_IDMAC_1_PRPVF_ROT_MASK = 0x0001C000,
  185873. + IC_IDMAC_1_PRPVF_ROT_OFFSET = 14,
  185874. + IC_IDMAC_1_PP_ROT_MASK = 0x000E0000,
  185875. + IC_IDMAC_1_PP_ROT_OFFSET = 17,
  185876. + IC_IDMAC_1_PP_FLIP_RS = 0x00400000,
  185877. + IC_IDMAC_1_PRPVF_FLIP_RS = 0x00200000,
  185878. + IC_IDMAC_1_PRPENC_FLIP_RS = 0x00100000,
  185879. +
  185880. + IC_IDMAC_2_PRPENC_HEIGHT_MASK = 0x000003FF,
  185881. + IC_IDMAC_2_PRPENC_HEIGHT_OFFSET = 0,
  185882. + IC_IDMAC_2_PRPVF_HEIGHT_MASK = 0x000FFC00,
  185883. + IC_IDMAC_2_PRPVF_HEIGHT_OFFSET = 10,
  185884. + IC_IDMAC_2_PP_HEIGHT_MASK = 0x3FF00000,
  185885. + IC_IDMAC_2_PP_HEIGHT_OFFSET = 20,
  185886. +
  185887. + IC_IDMAC_3_PRPENC_WIDTH_MASK = 0x000003FF,
  185888. + IC_IDMAC_3_PRPENC_WIDTH_OFFSET = 0,
  185889. + IC_IDMAC_3_PRPVF_WIDTH_MASK = 0x000FFC00,
  185890. + IC_IDMAC_3_PRPVF_WIDTH_OFFSET = 10,
  185891. + IC_IDMAC_3_PP_WIDTH_MASK = 0x3FF00000,
  185892. + IC_IDMAC_3_PP_WIDTH_OFFSET = 20,
  185893. +
  185894. + CSI_SENS_CONF_DATA_FMT_SHIFT = 8,
  185895. + CSI_SENS_CONF_DATA_FMT_MASK = 0x00000700,
  185896. + CSI_SENS_CONF_DATA_FMT_RGB_YUV444 = 0L,
  185897. + CSI_SENS_CONF_DATA_FMT_YUV422_YUYV = 1L,
  185898. + CSI_SENS_CONF_DATA_FMT_YUV422_UYVY = 2L,
  185899. + CSI_SENS_CONF_DATA_FMT_BAYER = 3L,
  185900. + CSI_SENS_CONF_DATA_FMT_RGB565 = 4L,
  185901. + CSI_SENS_CONF_DATA_FMT_RGB555 = 5L,
  185902. + CSI_SENS_CONF_DATA_FMT_RGB444 = 6L,
  185903. + CSI_SENS_CONF_DATA_FMT_JPEG = 7L,
  185904. +
  185905. + CSI_SENS_CONF_VSYNC_POL_SHIFT = 0,
  185906. + CSI_SENS_CONF_HSYNC_POL_SHIFT = 1,
  185907. + CSI_SENS_CONF_DATA_POL_SHIFT = 2,
  185908. + CSI_SENS_CONF_PIX_CLK_POL_SHIFT = 3,
  185909. + CSI_SENS_CONF_SENS_PRTCL_MASK = 0x00000070L,
  185910. + CSI_SENS_CONF_SENS_PRTCL_SHIFT = 4,
  185911. + CSI_SENS_CONF_PACK_TIGHT_SHIFT = 7,
  185912. + CSI_SENS_CONF_DATA_WIDTH_SHIFT = 11,
  185913. + CSI_SENS_CONF_EXT_VSYNC_SHIFT = 15,
  185914. + CSI_SENS_CONF_DIVRATIO_SHIFT = 16,
  185915. +
  185916. + CSI_SENS_CONF_DIVRATIO_MASK = 0x00FF0000L,
  185917. + CSI_SENS_CONF_DATA_DEST_SHIFT = 24,
  185918. + CSI_SENS_CONF_DATA_DEST_MASK = 0x07000000L,
  185919. + CSI_SENS_CONF_JPEG8_EN_SHIFT = 27,
  185920. + CSI_SENS_CONF_JPEG_EN_SHIFT = 28,
  185921. + CSI_SENS_CONF_FORCE_EOF_SHIFT = 29,
  185922. + CSI_SENS_CONF_DATA_EN_POL_SHIFT = 31,
  185923. +
  185924. + CSI_DATA_DEST_ISP = 1L,
  185925. + CSI_DATA_DEST_IC = 2L,
  185926. + CSI_DATA_DEST_IDMAC = 4L,
  185927. +
  185928. + CSI_CCIR_ERR_DET_EN = 0x01000000L,
  185929. + CSI_HORI_DOWNSIZE_EN = 0x80000000L,
  185930. + CSI_VERT_DOWNSIZE_EN = 0x40000000L,
  185931. + CSI_TEST_GEN_MODE_EN = 0x01000000L,
  185932. +
  185933. + CSI_HSC_MASK = 0x1FFF0000,
  185934. + CSI_HSC_SHIFT = 16,
  185935. + CSI_VSC_MASK = 0x00000FFF,
  185936. + CSI_VSC_SHIFT = 0,
  185937. +
  185938. + CSI_TEST_GEN_R_MASK = 0x000000FFL,
  185939. + CSI_TEST_GEN_R_SHIFT = 0,
  185940. + CSI_TEST_GEN_G_MASK = 0x0000FF00L,
  185941. + CSI_TEST_GEN_G_SHIFT = 8,
  185942. + CSI_TEST_GEN_B_MASK = 0x00FF0000L,
  185943. + CSI_TEST_GEN_B_SHIFT = 16,
  185944. +
  185945. + CSI_MIPI_DI0_MASK = 0x000000FFL,
  185946. + CSI_MIPI_DI0_SHIFT = 0,
  185947. + CSI_MIPI_DI1_MASK = 0x0000FF00L,
  185948. + CSI_MIPI_DI1_SHIFT = 8,
  185949. + CSI_MIPI_DI2_MASK = 0x00FF0000L,
  185950. + CSI_MIPI_DI2_SHIFT = 16,
  185951. + CSI_MIPI_DI3_MASK = 0xFF000000L,
  185952. + CSI_MIPI_DI3_SHIFT = 24,
  185953. +
  185954. + CSI_MAX_RATIO_SKIP_ISP_MASK = 0x00070000L,
  185955. + CSI_MAX_RATIO_SKIP_ISP_SHIFT = 16,
  185956. + CSI_SKIP_ISP_MASK = 0x00F80000L,
  185957. + CSI_SKIP_ISP_SHIFT = 19,
  185958. + CSI_MAX_RATIO_SKIP_SMFC_MASK = 0x00000007L,
  185959. + CSI_MAX_RATIO_SKIP_SMFC_SHIFT = 0,
  185960. + CSI_SKIP_SMFC_MASK = 0x000000F8L,
  185961. + CSI_SKIP_SMFC_SHIFT = 3,
  185962. + CSI_ID_2_SKIP_MASK = 0x00000300L,
  185963. + CSI_ID_2_SKIP_SHIFT = 8,
  185964. +
  185965. + CSI_COLOR_FIRST_ROW_MASK = 0x00000002L,
  185966. + CSI_COLOR_FIRST_COMP_MASK = 0x00000001L,
  185967. +
  185968. + SMFC_MAP_CH0_MASK = 0x00000007L,
  185969. + SMFC_MAP_CH0_SHIFT = 0,
  185970. + SMFC_MAP_CH1_MASK = 0x00000038L,
  185971. + SMFC_MAP_CH1_SHIFT = 3,
  185972. + SMFC_MAP_CH2_MASK = 0x000001C0L,
  185973. + SMFC_MAP_CH2_SHIFT = 6,
  185974. + SMFC_MAP_CH3_MASK = 0x00000E00L,
  185975. + SMFC_MAP_CH3_SHIFT = 9,
  185976. +
  185977. + SMFC_WM0_SET_MASK = 0x00000007L,
  185978. + SMFC_WM0_SET_SHIFT = 0,
  185979. + SMFC_WM1_SET_MASK = 0x000001C0L,
  185980. + SMFC_WM1_SET_SHIFT = 6,
  185981. + SMFC_WM2_SET_MASK = 0x00070000L,
  185982. + SMFC_WM2_SET_SHIFT = 16,
  185983. + SMFC_WM3_SET_MASK = 0x01C00000L,
  185984. + SMFC_WM3_SET_SHIFT = 22,
  185985. +
  185986. + SMFC_WM0_CLR_MASK = 0x00000038L,
  185987. + SMFC_WM0_CLR_SHIFT = 3,
  185988. + SMFC_WM1_CLR_MASK = 0x00000E00L,
  185989. + SMFC_WM1_CLR_SHIFT = 9,
  185990. + SMFC_WM2_CLR_MASK = 0x00380000L,
  185991. + SMFC_WM2_CLR_SHIFT = 19,
  185992. + SMFC_WM3_CLR_MASK = 0x0E000000L,
  185993. + SMFC_WM3_CLR_SHIFT = 25,
  185994. +
  185995. + SMFC_BS0_MASK = 0x0000000FL,
  185996. + SMFC_BS0_SHIFT = 0,
  185997. + SMFC_BS1_MASK = 0x000000F0L,
  185998. + SMFC_BS1_SHIFT = 4,
  185999. + SMFC_BS2_MASK = 0x00000F00L,
  186000. + SMFC_BS2_SHIFT = 8,
  186001. + SMFC_BS3_MASK = 0x0000F000L,
  186002. + SMFC_BS3_SHIFT = 12,
  186003. +
  186004. + PF_CONF_TYPE_MASK = 0x00000007,
  186005. + PF_CONF_TYPE_SHIFT = 0,
  186006. + PF_CONF_PAUSE_EN = 0x00000010,
  186007. + PF_CONF_RESET = 0x00008000,
  186008. + PF_CONF_PAUSE_ROW_MASK = 0x00FF0000,
  186009. + PF_CONF_PAUSE_ROW_SHIFT = 16,
  186010. +
  186011. + DI_DW_GEN_ACCESS_SIZE_OFFSET = 24,
  186012. + DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16,
  186013. +
  186014. + DI_GEN_DI_CLK_EXT = 0x100000,
  186015. + DI_GEN_POLARITY_DISP_CLK = 0x00020000,
  186016. + DI_GEN_POLARITY_1 = 0x00000001,
  186017. + DI_GEN_POLARITY_2 = 0x00000002,
  186018. + DI_GEN_POLARITY_3 = 0x00000004,
  186019. + DI_GEN_POLARITY_4 = 0x00000008,
  186020. + DI_GEN_POLARITY_5 = 0x00000010,
  186021. + DI_GEN_POLARITY_6 = 0x00000020,
  186022. + DI_GEN_POLARITY_7 = 0x00000040,
  186023. + DI_GEN_POLARITY_8 = 0x00000080,
  186024. +
  186025. + DI_POL_DRDY_DATA_POLARITY = 0x00000080,
  186026. + DI_POL_DRDY_POLARITY_15 = 0x00000010,
  186027. +
  186028. + DI_VSYNC_SEL_OFFSET = 13,
  186029. +
  186030. + DC_WR_CH_CONF_FIELD_MODE = 0x00000200,
  186031. + DC_WR_CH_CONF_PROG_TYPE_OFFSET = 5,
  186032. + DC_WR_CH_CONF_PROG_TYPE_MASK = 0x000000E0,
  186033. + DC_WR_CH_CONF_PROG_DI_ID = 0x00000004,
  186034. + DC_WR_CH_CONF_PROG_DISP_ID_OFFSET = 3,
  186035. + DC_WR_CH_CONF_PROG_DISP_ID_MASK = 0x00000018,
  186036. +
  186037. + DC_UGDE_0_ODD_EN = 0x02000000,
  186038. + DC_UGDE_0_ID_CODED_MASK = 0x00000007,
  186039. + DC_UGDE_0_ID_CODED_OFFSET = 0,
  186040. + DC_UGDE_0_EV_PRIORITY_MASK = 0x00000078,
  186041. + DC_UGDE_0_EV_PRIORITY_OFFSET = 3,
  186042. +
  186043. + DP_COM_CONF_FG_EN = 0x00000001,
  186044. + DP_COM_CONF_GWSEL = 0x00000002,
  186045. + DP_COM_CONF_GWAM = 0x00000004,
  186046. + DP_COM_CONF_GWCKE = 0x00000008,
  186047. + DP_COM_CONF_CSC_DEF_MASK = 0x00000300,
  186048. + DP_COM_CONF_CSC_DEF_OFFSET = 8,
  186049. + DP_COM_CONF_CSC_DEF_FG = 0x00000300,
  186050. + DP_COM_CONF_CSC_DEF_BG = 0x00000200,
  186051. + DP_COM_CONF_CSC_DEF_BOTH = 0x00000100,
  186052. + DP_COM_CONF_GAMMA_EN = 0x00001000,
  186053. + DP_COM_CONF_GAMMA_YUV_EN = 0x00002000,
  186054. +
  186055. + DI_SER_CONF_LLA_SER_ACCESS = 0x00000020,
  186056. + DI_SER_CONF_SERIAL_CLK_POL = 0x00000010,
  186057. + DI_SER_CONF_SERIAL_DATA_POL = 0x00000008,
  186058. + DI_SER_CONF_SERIAL_RS_POL = 0x00000004,
  186059. + DI_SER_CONF_SERIAL_CS_POL = 0x00000002,
  186060. + DI_SER_CONF_WAIT4SERIAL = 0x00000001,
  186061. +
  186062. + VDI_C_CH_420 = 0x00000000,
  186063. + VDI_C_CH_422 = 0x00000002,
  186064. + VDI_C_MOT_SEL_FULL = 0x00000008,
  186065. + VDI_C_MOT_SEL_LOW = 0x00000004,
  186066. + VDI_C_MOT_SEL_MED = 0x00000000,
  186067. + VDI_C_BURST_SIZE1_4 = 0x00000030,
  186068. + VDI_C_BURST_SIZE2_4 = 0x00000300,
  186069. + VDI_C_BURST_SIZE3_4 = 0x00003000,
  186070. + VDI_C_BURST_SIZE_MASK = 0xF,
  186071. + VDI_C_BURST_SIZE1_OFFSET = 4,
  186072. + VDI_C_BURST_SIZE2_OFFSET = 8,
  186073. + VDI_C_BURST_SIZE3_OFFSET = 12,
  186074. + VDI_C_VWM1_SET_1 = 0x00000000,
  186075. + VDI_C_VWM1_SET_2 = 0x00010000,
  186076. + VDI_C_VWM1_CLR_2 = 0x00080000,
  186077. + VDI_C_VWM3_SET_1 = 0x00000000,
  186078. + VDI_C_VWM3_SET_2 = 0x00400000,
  186079. + VDI_C_VWM3_CLR_2 = 0x02000000,
  186080. + VDI_C_TOP_FIELD_MAN_1 = 0x40000000,
  186081. + VDI_C_TOP_FIELD_AUTO_1 = 0x80000000,
  186082. +};
  186083. +
  186084. +enum di_pins {
  186085. + DI_PIN11 = 0,
  186086. + DI_PIN12 = 1,
  186087. + DI_PIN13 = 2,
  186088. + DI_PIN14 = 3,
  186089. + DI_PIN15 = 4,
  186090. + DI_PIN16 = 5,
  186091. + DI_PIN17 = 6,
  186092. + DI_PIN_CS = 7,
  186093. +
  186094. + DI_PIN_SER_CLK = 0,
  186095. + DI_PIN_SER_RS = 1,
  186096. +};
  186097. +
  186098. +enum di_sync_wave {
  186099. + DI_SYNC_NONE = -1,
  186100. + DI_SYNC_CLK = 0,
  186101. + DI_SYNC_INT_HSYNC = 1,
  186102. + DI_SYNC_HSYNC = 2,
  186103. + DI_SYNC_VSYNC = 3,
  186104. + DI_SYNC_DE = 5,
  186105. +};
  186106. +
  186107. +/* DC template opcodes */
  186108. +#define WROD(lf) (0x18 | (lf << 1))
  186109. +#define WRG (0x01)
  186110. +
  186111. +#endif
  186112. diff -Nur linux-3.14.17/drivers/mxc/ipu3/Kconfig linux-imx6-3.14/drivers/mxc/ipu3/Kconfig
  186113. --- linux-3.14.17/drivers/mxc/ipu3/Kconfig 1970-01-01 01:00:00.000000000 +0100
  186114. +++ linux-imx6-3.14/drivers/mxc/ipu3/Kconfig 2014-09-11 18:06:03.130042483 +0200
  186115. @@ -0,0 +1,2 @@
  186116. +config MXC_IPU_V3
  186117. + bool
  186118. diff -Nur linux-3.14.17/drivers/mxc/ipu3/Makefile linux-imx6-3.14/drivers/mxc/ipu3/Makefile
  186119. --- linux-3.14.17/drivers/mxc/ipu3/Makefile 1970-01-01 01:00:00.000000000 +0100
  186120. +++ linux-imx6-3.14/drivers/mxc/ipu3/Makefile 2014-09-11 18:06:03.130042483 +0200
  186121. @@ -0,0 +1,4 @@
  186122. +obj-$(CONFIG_MXC_IPU_V3) = mxc_ipu.o
  186123. +
  186124. +mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_device.o \
  186125. + ipu_calc_stripes_sizes.o vdoa.o ipu_pixel_clk.o
  186126. diff -Nur linux-3.14.17/drivers/mxc/ipu3/vdoa.c linux-imx6-3.14/drivers/mxc/ipu3/vdoa.c
  186127. --- linux-3.14.17/drivers/mxc/ipu3/vdoa.c 1970-01-01 01:00:00.000000000 +0100
  186128. +++ linux-imx6-3.14/drivers/mxc/ipu3/vdoa.c 2014-09-11 18:06:03.138042515 +0200
  186129. @@ -0,0 +1,543 @@
  186130. +/*
  186131. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  186132. + *
  186133. + * This program is free software; you can redistribute it and/or modify
  186134. + * it under the terms of the GNU General Public License as published by
  186135. + * the Free Software Foundation; either version 2 of the License, or
  186136. + * (at your option) any later version.
  186137. +
  186138. + * This program is distributed in the hope that it will be useful,
  186139. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  186140. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  186141. + * GNU General Public License for more details.
  186142. +
  186143. + * You should have received a copy of the GNU General Public License along
  186144. + * with this program; if not, write to the Free Software Foundation, Inc.,
  186145. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  186146. + */
  186147. +#include <linux/clk.h>
  186148. +#include <linux/err.h>
  186149. +#include <linux/io.h>
  186150. +#include <linux/ipu.h>
  186151. +#include <linux/genalloc.h>
  186152. +#include <linux/module.h>
  186153. +#include <linux/platform_device.h>
  186154. +#include <linux/slab.h>
  186155. +#include <linux/types.h>
  186156. +
  186157. +#include "vdoa.h"
  186158. +/* 6band(3field* double buffer) * (width*2) * bandline(8)
  186159. + = 6x1024x2x8 = 96k or 72k(1.5byte) */
  186160. +#define MAX_VDOA_IRAM_SIZE (1024*96)
  186161. +#define VDOA_IRAM_SIZE (1024*72)
  186162. +
  186163. +#define VDOAC_BAND_HEIGHT_32LINES (32)
  186164. +#define VDOAC_BAND_HEIGHT_16LINES (16)
  186165. +#define VDOAC_BAND_HEIGHT_8LINES (8)
  186166. +#define VDOAC_THREE_FRAMES (0x1 << 2)
  186167. +#define VDOAC_SYNC_BAND_MODE (0x1 << 3)
  186168. +#define VDOAC_SCAN_ORDER_INTERLACED (0x1 << 4)
  186169. +#define VDOAC_PFS_YUYV (0x1 << 5)
  186170. +#define VDOAC_IPU_SEL_1 (0x1 << 6)
  186171. +#define VDOAFP_FH_MASK (0x1FFF)
  186172. +#define VDOAFP_FH_SHIFT (16)
  186173. +#define VDOAFP_FW_MASK (0x3FFF)
  186174. +#define VDOAFP_FW_SHIFT (0)
  186175. +#define VDOASL_VSLY_MASK (0x3FFF)
  186176. +#define VDOASL_VSLY_SHIFT (16)
  186177. +#define VDOASL_ISLY_MASK (0x7FFF)
  186178. +#define VDOASL_ISLY_SHIFT (0)
  186179. +#define VDOASRR_START_XFER (0x2)
  186180. +#define VDOASRR_SWRST (0x1)
  186181. +#define VDOAIEIST_TRANSFER_ERR (0x2)
  186182. +#define VDOAIEIST_TRANSFER_END (0x1)
  186183. +
  186184. +#define VDOAC (0x0) /* Control Register */
  186185. +#define VDOASRR (0x4) /* Start and Reset Register */
  186186. +#define VDOAIE (0x8) /* Interrupt Enable Register */
  186187. +#define VDOAIST (0xc) /* Interrupt Status Register */
  186188. +#define VDOAFP (0x10) /* Frame Parameters Register */
  186189. +#define VDOAIEBA00 (0x14) /* External Buffer n Frame m Address Register */
  186190. +#define VDOAIEBA01 (0x18) /* External Buffer n Frame m Address Register */
  186191. +#define VDOAIEBA02 (0x1c) /* External Buffer n Frame m Address Register */
  186192. +#define VDOAIEBA10 (0x20) /* External Buffer n Frame m Address Register */
  186193. +#define VDOAIEBA11 (0x24) /* External Buffer n Frame m Address Register */
  186194. +#define VDOAIEBA12 (0x28) /* External Buffer n Frame m Address Register */
  186195. +#define VDOASL (0x2c) /* IPU Stride Line Register */
  186196. +#define VDOAIUBO (0x30) /* IPU Chroma Buffer Offset Register */
  186197. +#define VDOAVEBA0 (0x34) /* External Buffer m Address Register */
  186198. +#define VDOAVEBA1 (0x38) /* External Buffer m Address Register */
  186199. +#define VDOAVEBA2 (0x3c) /* External Buffer m Address Register */
  186200. +#define VDOAVUBO (0x40) /* VPU Chroma Buffer Offset */
  186201. +#define VDOASR (0x44) /* Status Register */
  186202. +#define VDOATD (0x48) /* Test Debug Register */
  186203. +
  186204. +
  186205. +enum {
  186206. + VDOA_INIT = 0x1,
  186207. + VDOA_GET = 0x2,
  186208. + VDOA_SETUP = 0x4,
  186209. + VDOA_GET_OBUF = 0x8,
  186210. + VDOA_START = 0x10,
  186211. + VDOA_INIRQ = 0x20,
  186212. + VDOA_STOP = 0x40,
  186213. + VDOA_PUT = VDOA_INIT,
  186214. +};
  186215. +
  186216. +enum {
  186217. + VDOA_NULL = 0,
  186218. + VDOA_FRAME = 1,
  186219. + VDOA_PREV_FIELD = 2,
  186220. + VDOA_CURR_FIELD = 3,
  186221. + VDOA_NEXT_FIELD = 4,
  186222. +};
  186223. +
  186224. +#define CHECK_STATE(expect, retcode) \
  186225. +do { \
  186226. + if (!((expect) & vdoa->state)) { \
  186227. + dev_err(vdoa->dev, "ERR: %s state:0x%x, expect:0x%x.\n",\
  186228. + __func__, vdoa->state, (expect)); \
  186229. + retcode; \
  186230. + } \
  186231. +} while (0)
  186232. +
  186233. +#define CHECK_NULL_PTR(ptr) \
  186234. +do { \
  186235. + pr_debug("vdoa_ptr:0x%p in %s state:0x%x.\n", \
  186236. + vdoa, __func__, vdoa->state); \
  186237. + if (NULL == (ptr)) { \
  186238. + pr_err("ERR vdoa: %s state:0x%x null ptr.\n", \
  186239. + __func__, vdoa->state); \
  186240. + } \
  186241. +} while (0)
  186242. +
  186243. +struct vdoa_info {
  186244. + int state;
  186245. + struct device *dev;
  186246. + struct clk *vdoa_clk;
  186247. + void __iomem *reg_base;
  186248. + struct gen_pool *iram_pool;
  186249. + unsigned long iram_base;
  186250. + unsigned long iram_paddr;
  186251. + int irq;
  186252. + int field;
  186253. + struct completion comp;
  186254. +};
  186255. +
  186256. +static struct vdoa_info *g_vdoa;
  186257. +static unsigned long iram_size;
  186258. +static DEFINE_MUTEX(vdoa_lock);
  186259. +
  186260. +static inline void vdoa_read_register(struct vdoa_info *vdoa,
  186261. + u32 reg, u32 *val)
  186262. +{
  186263. + *val = ioread32(vdoa->reg_base + reg);
  186264. + dev_dbg(vdoa->dev, "read_reg:0x%02x, val:0x%08x.\n", reg, *val);
  186265. +}
  186266. +
  186267. +static inline void vdoa_write_register(struct vdoa_info *vdoa,
  186268. + u32 reg, u32 val)
  186269. +{
  186270. + iowrite32(val, vdoa->reg_base + reg);
  186271. + dev_dbg(vdoa->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n", reg, val);
  186272. +}
  186273. +
  186274. +static void dump_registers(struct vdoa_info *vdoa)
  186275. +{
  186276. + int i;
  186277. + u32 data;
  186278. +
  186279. + for (i = VDOAC; i < VDOATD; i += 4)
  186280. + vdoa_read_register(vdoa, i, &data);
  186281. +}
  186282. +
  186283. +int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params)
  186284. +{
  186285. + int band_size;
  186286. + int total_band_size = 0;
  186287. + int ipu_stride;
  186288. + u32 data;
  186289. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  186290. +
  186291. + CHECK_NULL_PTR(vdoa);
  186292. + CHECK_STATE(VDOA_GET | VDOA_GET_OBUF | VDOA_STOP, return -EINVAL);
  186293. + if (VDOA_GET == vdoa->state) {
  186294. + dev_dbg(vdoa->dev, "w:%d, h:%d.\n",
  186295. + params->width, params->height);
  186296. + data = (params->band_lines == VDOAC_BAND_HEIGHT_32LINES) ? 2 :
  186297. + ((params->band_lines == VDOAC_BAND_HEIGHT_16LINES) ?
  186298. + 1 : 0);
  186299. + data |= params->scan_order ? VDOAC_SCAN_ORDER_INTERLACED : 0;
  186300. + data |= params->band_mode ? VDOAC_SYNC_BAND_MODE : 0;
  186301. + data |= params->pfs ? VDOAC_PFS_YUYV : 0;
  186302. + data |= params->ipu_num ? VDOAC_IPU_SEL_1 : 0;
  186303. + vdoa_write_register(vdoa, VDOAC, data);
  186304. +
  186305. + data = ((params->width & VDOAFP_FW_MASK) << VDOAFP_FW_SHIFT) |
  186306. + ((params->height & VDOAFP_FH_MASK) << VDOAFP_FH_SHIFT);
  186307. + vdoa_write_register(vdoa, VDOAFP, data);
  186308. +
  186309. + ipu_stride = params->pfs ? params->width << 1 : params->width;
  186310. + data = ((params->vpu_stride & VDOASL_VSLY_MASK) <<
  186311. + VDOASL_VSLY_SHIFT) |
  186312. + ((ipu_stride & VDOASL_ISLY_MASK) << VDOASL_ISLY_SHIFT);
  186313. + vdoa_write_register(vdoa, VDOASL, data);
  186314. +
  186315. + dev_dbg(vdoa->dev, "band_mode:%d, band_line:%d, base:0x%lx.\n",
  186316. + params->band_mode, params->band_lines, vdoa->iram_paddr);
  186317. + }
  186318. + /*
  186319. + * band size = (luma_per_line + chroma_per_line) * bandLines
  186320. + * = width * (3/2 or 2) * bandLines
  186321. + * double buffer mode used.
  186322. + */
  186323. + if (params->pfs)
  186324. + band_size = (params->width << 1) * params->band_lines;
  186325. + else
  186326. + band_size = ((params->width * 3) >> 1) *
  186327. + params->band_lines;
  186328. + if (params->interlaced) {
  186329. + total_band_size = 6 * band_size; /* 3 frames*double buffer */
  186330. + if (iram_size < total_band_size) {
  186331. + dev_err(vdoa->dev, "iram_size:0x%lx is smaller than "
  186332. + "request:0x%x!\n", iram_size, total_band_size);
  186333. + return -EINVAL;
  186334. + }
  186335. + if (params->vfield_buf.prev_veba) {
  186336. + if (params->band_mode) {
  186337. + vdoa_write_register(vdoa, VDOAIEBA00,
  186338. + vdoa->iram_paddr);
  186339. + vdoa_write_register(vdoa, VDOAIEBA10,
  186340. + vdoa->iram_paddr + band_size);
  186341. + } else
  186342. + vdoa_write_register(vdoa, VDOAIEBA00,
  186343. + params->ieba0);
  186344. + vdoa_write_register(vdoa, VDOAVEBA0,
  186345. + params->vfield_buf.prev_veba);
  186346. + vdoa->field = VDOA_PREV_FIELD;
  186347. + }
  186348. + if (params->vfield_buf.cur_veba) {
  186349. + if (params->band_mode) {
  186350. + vdoa_write_register(vdoa, VDOAIEBA01,
  186351. + vdoa->iram_paddr + band_size * 2);
  186352. + vdoa_write_register(vdoa, VDOAIEBA11,
  186353. + vdoa->iram_paddr + band_size * 3);
  186354. + } else
  186355. + vdoa_write_register(vdoa, VDOAIEBA01,
  186356. + params->ieba1);
  186357. + vdoa_write_register(vdoa, VDOAVEBA1,
  186358. + params->vfield_buf.cur_veba);
  186359. + vdoa->field = VDOA_CURR_FIELD;
  186360. + }
  186361. + if (params->vfield_buf.next_veba) {
  186362. + if (params->band_mode) {
  186363. + vdoa_write_register(vdoa, VDOAIEBA02,
  186364. + vdoa->iram_paddr + band_size * 4);
  186365. + vdoa_write_register(vdoa, VDOAIEBA12,
  186366. + vdoa->iram_paddr + band_size * 5);
  186367. + } else
  186368. + vdoa_write_register(vdoa, VDOAIEBA02,
  186369. + params->ieba2);
  186370. + vdoa_write_register(vdoa, VDOAVEBA2,
  186371. + params->vfield_buf.next_veba);
  186372. + vdoa->field = VDOA_NEXT_FIELD;
  186373. + vdoa_read_register(vdoa, VDOAC, &data);
  186374. + data |= VDOAC_THREE_FRAMES;
  186375. + vdoa_write_register(vdoa, VDOAC, data);
  186376. + }
  186377. +
  186378. + if (!params->pfs)
  186379. + vdoa_write_register(vdoa, VDOAIUBO,
  186380. + params->width * params->band_lines);
  186381. + vdoa_write_register(vdoa, VDOAVUBO,
  186382. + params->vfield_buf.vubo);
  186383. + dev_dbg(vdoa->dev, "total band_size:0x%x.\n", band_size*6);
  186384. + } else if (params->band_mode) {
  186385. + /* used for progressive frame resize on PrP channel */
  186386. + BUG(); /* currently not support */
  186387. + /* progressvie frame: band mode */
  186388. + vdoa_write_register(vdoa, VDOAIEBA00, vdoa->iram_paddr);
  186389. + vdoa_write_register(vdoa, VDOAIEBA10,
  186390. + vdoa->iram_paddr + band_size);
  186391. + if (!params->pfs)
  186392. + vdoa_write_register(vdoa, VDOAIUBO,
  186393. + params->width * params->band_lines);
  186394. + dev_dbg(vdoa->dev, "total band_size:0x%x\n", band_size*2);
  186395. + } else {
  186396. + /* progressive frame: mem->mem, non-band mode */
  186397. + vdoa->field = VDOA_FRAME;
  186398. + vdoa_write_register(vdoa, VDOAVEBA0, params->vframe_buf.veba);
  186399. + vdoa_write_register(vdoa, VDOAVUBO, params->vframe_buf.vubo);
  186400. + vdoa_write_register(vdoa, VDOAIEBA00, params->ieba0);
  186401. + if (!params->pfs)
  186402. + /* note: iubo is relative value, based on ieba0 */
  186403. + vdoa_write_register(vdoa, VDOAIUBO,
  186404. + params->width * params->height);
  186405. + }
  186406. + vdoa->state = VDOA_SETUP;
  186407. + return 0;
  186408. +}
  186409. +
  186410. +void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf)
  186411. +{
  186412. + u32 data;
  186413. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  186414. +
  186415. + CHECK_NULL_PTR(vdoa);
  186416. + CHECK_STATE(VDOA_SETUP, return);
  186417. + vdoa->state = VDOA_GET_OBUF;
  186418. + memset(buf, 0, sizeof(*buf));
  186419. +
  186420. + vdoa_read_register(vdoa, VDOAC, &data);
  186421. + switch (vdoa->field) {
  186422. + case VDOA_FRAME:
  186423. + case VDOA_PREV_FIELD:
  186424. + vdoa_read_register(vdoa, VDOAIEBA00, &buf->ieba0);
  186425. + if (data & VDOAC_SYNC_BAND_MODE)
  186426. + vdoa_read_register(vdoa, VDOAIEBA10, &buf->ieba1);
  186427. + break;
  186428. + case VDOA_CURR_FIELD:
  186429. + vdoa_read_register(vdoa, VDOAIEBA01, &buf->ieba0);
  186430. + vdoa_read_register(vdoa, VDOAIEBA11, &buf->ieba1);
  186431. + break;
  186432. + case VDOA_NEXT_FIELD:
  186433. + vdoa_read_register(vdoa, VDOAIEBA02, &buf->ieba0);
  186434. + vdoa_read_register(vdoa, VDOAIEBA12, &buf->ieba1);
  186435. + break;
  186436. + default:
  186437. + BUG();
  186438. + break;
  186439. + }
  186440. + if (!(data & VDOAC_PFS_YUYV))
  186441. + vdoa_read_register(vdoa, VDOAIUBO, &buf->iubo);
  186442. +}
  186443. +
  186444. +int vdoa_start(vdoa_handle_t handle, int timeout_ms)
  186445. +{
  186446. + int ret;
  186447. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  186448. +
  186449. + CHECK_NULL_PTR(vdoa);
  186450. + CHECK_STATE(VDOA_GET_OBUF, return -EINVAL);
  186451. + vdoa->state = VDOA_START;
  186452. + init_completion(&vdoa->comp);
  186453. + vdoa_write_register(vdoa, VDOAIST,
  186454. + VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
  186455. + vdoa_write_register(vdoa, VDOAIE,
  186456. + VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
  186457. +
  186458. + enable_irq(vdoa->irq);
  186459. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_START_XFER);
  186460. + dump_registers(vdoa);
  186461. +
  186462. + ret = wait_for_completion_timeout(&vdoa->comp,
  186463. + msecs_to_jiffies(timeout_ms));
  186464. +
  186465. + return ret > 0 ? 0 : -ETIMEDOUT;
  186466. +}
  186467. +
  186468. +void vdoa_stop(vdoa_handle_t handle)
  186469. +{
  186470. + struct vdoa_info *vdoa = (struct vdoa_info *)handle;
  186471. +
  186472. + CHECK_NULL_PTR(vdoa);
  186473. + CHECK_STATE(VDOA_GET | VDOA_START | VDOA_INIRQ, return);
  186474. + vdoa->state = VDOA_STOP;
  186475. +
  186476. + disable_irq(vdoa->irq);
  186477. +
  186478. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
  186479. +}
  186480. +
  186481. +void vdoa_get_handle(vdoa_handle_t *handle)
  186482. +{
  186483. + struct vdoa_info *vdoa = g_vdoa;
  186484. +
  186485. + CHECK_NULL_PTR(handle);
  186486. + *handle = (vdoa_handle_t *)NULL;
  186487. + CHECK_STATE(VDOA_INIT, return);
  186488. + mutex_lock(&vdoa_lock);
  186489. + clk_prepare_enable(vdoa->vdoa_clk);
  186490. + vdoa->state = VDOA_GET;
  186491. + vdoa->field = VDOA_NULL;
  186492. + vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
  186493. +
  186494. + *handle = (vdoa_handle_t *)vdoa;
  186495. +}
  186496. +
  186497. +void vdoa_put_handle(vdoa_handle_t *handle)
  186498. +{
  186499. + struct vdoa_info *vdoa = (struct vdoa_info *)(*handle);
  186500. +
  186501. + CHECK_NULL_PTR(vdoa);
  186502. + CHECK_STATE(VDOA_STOP, return);
  186503. + if (vdoa != g_vdoa)
  186504. + BUG();
  186505. +
  186506. + clk_disable_unprepare(vdoa->vdoa_clk);
  186507. + vdoa->state = VDOA_PUT;
  186508. + *handle = (vdoa_handle_t *)NULL;
  186509. + mutex_unlock(&vdoa_lock);
  186510. +}
  186511. +
  186512. +static irqreturn_t vdoa_irq_handler(int irq, void *data)
  186513. +{
  186514. + u32 status, mask, val;
  186515. + struct vdoa_info *vdoa = data;
  186516. +
  186517. + CHECK_NULL_PTR(vdoa);
  186518. + CHECK_STATE(VDOA_START, return IRQ_HANDLED);
  186519. + vdoa->state = VDOA_INIRQ;
  186520. + vdoa_read_register(vdoa, VDOAIST, &status);
  186521. + vdoa_read_register(vdoa, VDOAIE, &mask);
  186522. + val = status & mask;
  186523. + vdoa_write_register(vdoa, VDOAIST, val);
  186524. + if (VDOAIEIST_TRANSFER_ERR & val)
  186525. + dev_err(vdoa->dev, "vdoa Transfer err irq!\n");
  186526. + if (VDOAIEIST_TRANSFER_END & val)
  186527. + dev_dbg(vdoa->dev, "vdoa Transfer end irq!\n");
  186528. + if (0 == val) {
  186529. + dev_err(vdoa->dev, "vdoa unknown irq!\n");
  186530. + BUG();
  186531. + }
  186532. +
  186533. + complete(&vdoa->comp);
  186534. + return IRQ_HANDLED;
  186535. +}
  186536. +
  186537. +/* IRAM Size in Kbytes, example:vdoa_iram_size=64, 64KBytes */
  186538. +static int __init vdoa_iram_size_setup(char *options)
  186539. +{
  186540. + int ret;
  186541. +
  186542. + ret = strict_strtoul(options, 0, &iram_size);
  186543. + if (ret)
  186544. + iram_size = 0;
  186545. + else
  186546. + iram_size *= SZ_1K;
  186547. +
  186548. + return 1;
  186549. +}
  186550. +__setup("vdoa_iram_size=", vdoa_iram_size_setup);
  186551. +
  186552. +static const struct of_device_id imx_vdoa_dt_ids[] = {
  186553. + { .compatible = "fsl,imx6q-vdoa", },
  186554. + { /* sentinel */ }
  186555. +};
  186556. +
  186557. +static int vdoa_probe(struct platform_device *pdev)
  186558. +{
  186559. + int ret;
  186560. + struct vdoa_info *vdoa;
  186561. + struct resource *res;
  186562. + struct resource *res_irq;
  186563. + struct device *dev = &pdev->dev;
  186564. + struct device_node *np = pdev->dev.of_node;
  186565. +
  186566. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  186567. + if (!res) {
  186568. + dev_err(dev, "can't get device resources\n");
  186569. + return -ENOENT;
  186570. + }
  186571. +
  186572. + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  186573. + if (!res_irq) {
  186574. + dev_err(dev, "failed to get irq resource\n");
  186575. + return -ENOENT;
  186576. + }
  186577. +
  186578. + vdoa = devm_kzalloc(dev, sizeof(struct vdoa_info), GFP_KERNEL);
  186579. + if (!vdoa)
  186580. + return -ENOMEM;
  186581. + vdoa->dev = dev;
  186582. +
  186583. + vdoa->reg_base = devm_request_and_ioremap(&pdev->dev, res);
  186584. + if (!vdoa->reg_base)
  186585. + return -EBUSY;
  186586. +
  186587. + vdoa->irq = res_irq->start;
  186588. + ret = devm_request_irq(dev, vdoa->irq, vdoa_irq_handler, 0,
  186589. + "vdoa", vdoa);
  186590. + if (ret) {
  186591. + dev_err(dev, "can't claim irq %d\n", vdoa->irq);
  186592. + return ret;
  186593. + }
  186594. + disable_irq(vdoa->irq);
  186595. +
  186596. + vdoa->vdoa_clk = devm_clk_get(dev, NULL);
  186597. + if (IS_ERR(vdoa->vdoa_clk)) {
  186598. + dev_err(dev, "failed to get vdoa_clk\n");
  186599. + return PTR_ERR(vdoa->vdoa_clk);
  186600. + }
  186601. +
  186602. + vdoa->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  186603. + if (!vdoa->iram_pool) {
  186604. + dev_err(&pdev->dev, "iram pool not available\n");
  186605. + return -ENOMEM;
  186606. + }
  186607. +
  186608. + if ((iram_size == 0) || (iram_size > MAX_VDOA_IRAM_SIZE))
  186609. + iram_size = VDOA_IRAM_SIZE;
  186610. +
  186611. + vdoa->iram_base = gen_pool_alloc(vdoa->iram_pool, iram_size);
  186612. + if (!vdoa->iram_base) {
  186613. + dev_err(&pdev->dev, "unable to alloc iram\n");
  186614. + return -ENOMEM;
  186615. + }
  186616. +
  186617. + vdoa->iram_paddr = gen_pool_virt_to_phys(vdoa->iram_pool,
  186618. + vdoa->iram_base);
  186619. +
  186620. + dev_dbg(dev, "iram_base:0x%lx,iram_paddr:0x%lx,size:0x%lx\n",
  186621. + vdoa->iram_base, vdoa->iram_paddr, iram_size);
  186622. +
  186623. + vdoa->state = VDOA_INIT;
  186624. + dev_set_drvdata(dev, vdoa);
  186625. + g_vdoa = vdoa;
  186626. + dev_info(dev, "i.MX Video Data Order Adapter(VDOA) driver probed\n");
  186627. + return 0;
  186628. +}
  186629. +
  186630. +static int vdoa_remove(struct platform_device *pdev)
  186631. +{
  186632. + struct vdoa_info *vdoa = dev_get_drvdata(&pdev->dev);
  186633. +
  186634. + gen_pool_free(vdoa->iram_pool, vdoa->iram_base, iram_size);
  186635. + kfree(vdoa);
  186636. + dev_set_drvdata(&pdev->dev, NULL);
  186637. +
  186638. + return 0;
  186639. +}
  186640. +
  186641. +static struct platform_driver vdoa_driver = {
  186642. + .driver = {
  186643. + .name = "mxc_vdoa",
  186644. + .of_match_table = imx_vdoa_dt_ids,
  186645. + },
  186646. + .probe = vdoa_probe,
  186647. + .remove = vdoa_remove,
  186648. +};
  186649. +
  186650. +static int __init vdoa_init(void)
  186651. +{
  186652. + int err;
  186653. +
  186654. + err = platform_driver_register(&vdoa_driver);
  186655. + if (err) {
  186656. + pr_err("vdoa_driver register failed\n");
  186657. + return -ENODEV;
  186658. + }
  186659. + return 0;
  186660. +}
  186661. +
  186662. +static void __exit vdoa_cleanup(void)
  186663. +{
  186664. + platform_driver_unregister(&vdoa_driver);
  186665. +}
  186666. +
  186667. +module_init(vdoa_init);
  186668. +module_exit(vdoa_cleanup);
  186669. +
  186670. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  186671. +MODULE_DESCRIPTION("i.MX Video Data Order Adapter(VDOA) driver");
  186672. +MODULE_LICENSE("GPL");
  186673. diff -Nur linux-3.14.17/drivers/mxc/ipu3/vdoa.h linux-imx6-3.14/drivers/mxc/ipu3/vdoa.h
  186674. --- linux-3.14.17/drivers/mxc/ipu3/vdoa.h 1970-01-01 01:00:00.000000000 +0100
  186675. +++ linux-imx6-3.14/drivers/mxc/ipu3/vdoa.h 2014-09-11 18:06:03.138042515 +0200
  186676. @@ -0,0 +1,69 @@
  186677. +/*
  186678. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  186679. + *
  186680. + * This program is free software; you can redistribute it and/or modify
  186681. + * it under the terms of the GNU General Public License as published by
  186682. + * the Free Software Foundation; either version 2 of the License, or
  186683. + * (at your option) any later version.
  186684. +
  186685. + * This program is distributed in the hope that it will be useful,
  186686. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  186687. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  186688. + * GNU General Public License for more details.
  186689. +
  186690. + * You should have received a copy of the GNU General Public License along
  186691. + * with this program; if not, write to the Free Software Foundation, Inc.,
  186692. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  186693. + */
  186694. +
  186695. +#ifndef __VDOA_H__
  186696. +#define __VDOA_H__
  186697. +
  186698. +#define VDOA_PFS_YUYV (1)
  186699. +#define VDOA_PFS_NV12 (0)
  186700. +
  186701. +
  186702. +struct vfield_buf {
  186703. + u32 prev_veba;
  186704. + u32 cur_veba;
  186705. + u32 next_veba;
  186706. + u32 vubo;
  186707. +};
  186708. +
  186709. +struct vframe_buf {
  186710. + u32 veba;
  186711. + u32 vubo;
  186712. +};
  186713. +
  186714. +struct vdoa_params {
  186715. + u32 width;
  186716. + u32 height;
  186717. + int vpu_stride;
  186718. + int interlaced;
  186719. + int scan_order;
  186720. + int ipu_num;
  186721. + int band_lines;
  186722. + int band_mode;
  186723. + int pfs;
  186724. + u32 ieba0;
  186725. + u32 ieba1;
  186726. + u32 ieba2;
  186727. + struct vframe_buf vframe_buf;
  186728. + struct vfield_buf vfield_buf;
  186729. +};
  186730. +struct vdoa_ipu_buf {
  186731. + u32 ieba0;
  186732. + u32 ieba1;
  186733. + u32 iubo;
  186734. +};
  186735. +
  186736. +struct vdoa_info;
  186737. +typedef void *vdoa_handle_t;
  186738. +
  186739. +int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params);
  186740. +void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf);
  186741. +int vdoa_start(vdoa_handle_t handle, int timeout_ms);
  186742. +void vdoa_stop(vdoa_handle_t handle);
  186743. +void vdoa_get_handle(vdoa_handle_t *handle);
  186744. +void vdoa_put_handle(vdoa_handle_t *handle);
  186745. +#endif
  186746. diff -Nur linux-3.14.17/drivers/mxc/Kconfig linux-imx6-3.14/drivers/mxc/Kconfig
  186747. --- linux-3.14.17/drivers/mxc/Kconfig 1970-01-01 01:00:00.000000000 +0100
  186748. +++ linux-imx6-3.14/drivers/mxc/Kconfig 2014-09-11 18:06:03.078042276 +0200
  186749. @@ -0,0 +1,24 @@
  186750. +# drivers/mxc/Kconfig
  186751. +
  186752. +if ARCH_MXC
  186753. +
  186754. +menu "MXC support drivers"
  186755. +
  186756. +config MXC_IPU
  186757. + bool "Image Processing Unit Driver"
  186758. + select MXC_IPU_V3
  186759. + help
  186760. + If you plan to use the Image Processing unit, say
  186761. + Y here. IPU is needed by Framebuffer and V4L2 drivers.
  186762. +
  186763. +source "drivers/mxc/gpu-viv/Kconfig"
  186764. +source "drivers/mxc/ipu3/Kconfig"
  186765. +source "drivers/mxc/asrc/Kconfig"
  186766. +source "drivers/mxc/vpu/Kconfig"
  186767. +source "drivers/mxc/hdmi-cec/Kconfig"
  186768. +source "drivers/mxc/mipi/Kconfig"
  186769. +source "drivers/mxc/mlb/Kconfig"
  186770. +
  186771. +endmenu
  186772. +
  186773. +endif
  186774. diff -Nur linux-3.14.17/drivers/mxc/Makefile linux-imx6-3.14/drivers/mxc/Makefile
  186775. --- linux-3.14.17/drivers/mxc/Makefile 1970-01-01 01:00:00.000000000 +0100
  186776. +++ linux-imx6-3.14/drivers/mxc/Makefile 2014-09-11 18:06:03.078042276 +0200
  186777. @@ -0,0 +1,7 @@
  186778. +obj-$(CONFIG_MXC_GPU_VIV) += gpu-viv/
  186779. +obj-$(CONFIG_MXC_IPU_V3) += ipu3/
  186780. +obj-$(CONFIG_MXC_ASRC) += asrc/
  186781. +obj-$(CONFIG_MXC_VPU) += vpu/
  186782. +obj-$(CONFIG_MXC_HDMI_CEC) += hdmi-cec/
  186783. +obj-$(CONFIG_MXC_MIPI_CSI2) += mipi/
  186784. +obj-$(CONFIG_MXC_MLB) += mlb/
  186785. diff -Nur linux-3.14.17/drivers/mxc/mipi/Kconfig linux-imx6-3.14/drivers/mxc/mipi/Kconfig
  186786. --- linux-3.14.17/drivers/mxc/mipi/Kconfig 1970-01-01 01:00:00.000000000 +0100
  186787. +++ linux-imx6-3.14/drivers/mxc/mipi/Kconfig 2014-09-11 18:06:03.138042515 +0200
  186788. @@ -0,0 +1,14 @@
  186789. +#
  186790. +# MIPI configuration
  186791. +#
  186792. +
  186793. +menu "MXC MIPI Support"
  186794. +
  186795. +config MXC_MIPI_CSI2
  186796. + tristate "MIPI CSI2 support"
  186797. + depends on SOC_IMX6Q
  186798. + default n
  186799. + ---help---
  186800. + Say Y to get the MIPI CSI2 support.
  186801. +
  186802. +endmenu
  186803. diff -Nur linux-3.14.17/drivers/mxc/mipi/Makefile linux-imx6-3.14/drivers/mxc/mipi/Makefile
  186804. --- linux-3.14.17/drivers/mxc/mipi/Makefile 1970-01-01 01:00:00.000000000 +0100
  186805. +++ linux-imx6-3.14/drivers/mxc/mipi/Makefile 2014-09-11 18:06:03.138042515 +0200
  186806. @@ -0,0 +1,4 @@
  186807. +#
  186808. +# Makefile for the mipi interface driver
  186809. +#
  186810. +obj-$(CONFIG_MXC_MIPI_CSI2) += mxc_mipi_csi2.o
  186811. diff -Nur linux-3.14.17/drivers/mxc/mipi/mxc_mipi_csi2.c linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.c
  186812. --- linux-3.14.17/drivers/mxc/mipi/mxc_mipi_csi2.c 1970-01-01 01:00:00.000000000 +0100
  186813. +++ linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.c 2014-09-11 18:06:03.138042515 +0200
  186814. @@ -0,0 +1,540 @@
  186815. +/*
  186816. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  186817. + *
  186818. + * This program is free software; you can redistribute it and/or modify
  186819. + * it under the terms of the GNU General Public License as published by
  186820. + * the Free Software Foundation; either version 2 of the License, or
  186821. + * (at your option) any later version.
  186822. +
  186823. + * This program is distributed in the hope that it will be useful,
  186824. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  186825. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  186826. + * GNU General Public License for more details.
  186827. +
  186828. + * You should have received a copy of the GNU General Public License along
  186829. + * with this program; if not, write to the Free Software Foundation, Inc.,
  186830. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  186831. + */
  186832. +
  186833. +#include <linux/module.h>
  186834. +#include <linux/types.h>
  186835. +#include <linux/interrupt.h>
  186836. +#include <linux/irq.h>
  186837. +#include <linux/irqdesc.h>
  186838. +#include <linux/init.h>
  186839. +#include <linux/platform_device.h>
  186840. +#include <linux/err.h>
  186841. +#include <linux/clk.h>
  186842. +#include <linux/console.h>
  186843. +#include <linux/io.h>
  186844. +#include <linux/bitops.h>
  186845. +#include <linux/delay.h>
  186846. +#include <linux/fsl_devices.h>
  186847. +#include <linux/slab.h>
  186848. +#include <linux/of.h>
  186849. +
  186850. +#include <linux/mipi_csi2.h>
  186851. +
  186852. +#include "mxc_mipi_csi2.h"
  186853. +
  186854. +static struct mipi_csi2_info *gmipi_csi2;
  186855. +
  186856. +void _mipi_csi2_lock(struct mipi_csi2_info *info)
  186857. +{
  186858. + if (!in_irq() && !in_softirq())
  186859. + mutex_lock(&info->mutex_lock);
  186860. +}
  186861. +
  186862. +void _mipi_csi2_unlock(struct mipi_csi2_info *info)
  186863. +{
  186864. + if (!in_irq() && !in_softirq())
  186865. + mutex_unlock(&info->mutex_lock);
  186866. +}
  186867. +
  186868. +static inline void mipi_csi2_write(struct mipi_csi2_info *info,
  186869. + unsigned value, unsigned offset)
  186870. +{
  186871. + writel(value, info->mipi_csi2_base + offset);
  186872. +}
  186873. +
  186874. +static inline unsigned int mipi_csi2_read(struct mipi_csi2_info *info,
  186875. + unsigned offset)
  186876. +{
  186877. + return readl(info->mipi_csi2_base + offset);
  186878. +}
  186879. +
  186880. +/*!
  186881. + * This function is called to enable the mipi csi2 interface.
  186882. + *
  186883. + * @param info mipi csi2 hander
  186884. + * @return Returns setted value
  186885. + */
  186886. +bool mipi_csi2_enable(struct mipi_csi2_info *info)
  186887. +{
  186888. + bool status;
  186889. +
  186890. + _mipi_csi2_lock(info);
  186891. +
  186892. + if (!info->mipi_en) {
  186893. + info->mipi_en = true;
  186894. + clk_prepare_enable(info->cfg_clk);
  186895. + clk_prepare_enable(info->dphy_clk);
  186896. + } else
  186897. + mipi_dbg("mipi csi2 already enabled!\n");
  186898. +
  186899. + status = info->mipi_en;
  186900. +
  186901. + _mipi_csi2_unlock(info);
  186902. +
  186903. + return status;
  186904. +}
  186905. +EXPORT_SYMBOL(mipi_csi2_enable);
  186906. +
  186907. +/*!
  186908. + * This function is called to disable the mipi csi2 interface.
  186909. + *
  186910. + * @param info mipi csi2 hander
  186911. + * @return Returns setted value
  186912. + */
  186913. +bool mipi_csi2_disable(struct mipi_csi2_info *info)
  186914. +{
  186915. + bool status;
  186916. +
  186917. + _mipi_csi2_lock(info);
  186918. +
  186919. + if (info->mipi_en) {
  186920. + info->mipi_en = false;
  186921. + clk_disable_unprepare(info->dphy_clk);
  186922. + clk_disable_unprepare(info->cfg_clk);
  186923. + } else
  186924. + mipi_dbg("mipi csi2 already disabled!\n");
  186925. +
  186926. + status = info->mipi_en;
  186927. +
  186928. + _mipi_csi2_unlock(info);
  186929. +
  186930. + return status;
  186931. +}
  186932. +EXPORT_SYMBOL(mipi_csi2_disable);
  186933. +
  186934. +/*!
  186935. + * This function is called to get mipi csi2 disable/enable status.
  186936. + *
  186937. + * @param info mipi csi2 hander
  186938. + * @return Returns mipi csi2 status
  186939. + */
  186940. +bool mipi_csi2_get_status(struct mipi_csi2_info *info)
  186941. +{
  186942. + bool status;
  186943. +
  186944. + _mipi_csi2_lock(info);
  186945. + status = info->mipi_en;
  186946. + _mipi_csi2_unlock(info);
  186947. +
  186948. + return status;
  186949. +}
  186950. +EXPORT_SYMBOL(mipi_csi2_get_status);
  186951. +
  186952. +/*!
  186953. + * This function is called to set mipi lanes.
  186954. + *
  186955. + * @param info mipi csi2 hander
  186956. + * @return Returns setted value
  186957. + */
  186958. +unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info)
  186959. +{
  186960. + unsigned int lanes;
  186961. +
  186962. + _mipi_csi2_lock(info);
  186963. + mipi_csi2_write(info, info->lanes - 1, MIPI_CSI2_N_LANES);
  186964. + lanes = mipi_csi2_read(info, MIPI_CSI2_N_LANES);
  186965. + _mipi_csi2_unlock(info);
  186966. +
  186967. + return lanes;
  186968. +}
  186969. +EXPORT_SYMBOL(mipi_csi2_set_lanes);
  186970. +
  186971. +/*!
  186972. + * This function is called to set mipi data type.
  186973. + *
  186974. + * @param info mipi csi2 hander
  186975. + * @return Returns setted value
  186976. + */
  186977. +unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
  186978. + unsigned int datatype)
  186979. +{
  186980. + unsigned int dtype;
  186981. +
  186982. + _mipi_csi2_lock(info);
  186983. + info->datatype = datatype;
  186984. + dtype = info->datatype;
  186985. + _mipi_csi2_unlock(info);
  186986. +
  186987. + return dtype;
  186988. +}
  186989. +EXPORT_SYMBOL(mipi_csi2_set_datatype);
  186990. +
  186991. +/*!
  186992. + * This function is called to get mipi data type.
  186993. + *
  186994. + * @param info mipi csi2 hander
  186995. + * @return Returns mipi data type
  186996. + */
  186997. +unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info)
  186998. +{
  186999. + unsigned int dtype;
  187000. +
  187001. + _mipi_csi2_lock(info);
  187002. + dtype = info->datatype;
  187003. + _mipi_csi2_unlock(info);
  187004. +
  187005. + return dtype;
  187006. +}
  187007. +EXPORT_SYMBOL(mipi_csi2_get_datatype);
  187008. +
  187009. +/*!
  187010. + * This function is called to get mipi csi2 dphy status.
  187011. + *
  187012. + * @param info mipi csi2 hander
  187013. + * @return Returns dphy status
  187014. + */
  187015. +unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info)
  187016. +{
  187017. + unsigned int status;
  187018. +
  187019. + _mipi_csi2_lock(info);
  187020. + status = mipi_csi2_read(info, MIPI_CSI2_PHY_STATE);
  187021. + _mipi_csi2_unlock(info);
  187022. +
  187023. + return status;
  187024. +}
  187025. +EXPORT_SYMBOL(mipi_csi2_dphy_status);
  187026. +
  187027. +/*!
  187028. + * This function is called to get mipi csi2 error1 status.
  187029. + *
  187030. + * @param info mipi csi2 hander
  187031. + * @return Returns error1 value
  187032. + */
  187033. +unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info)
  187034. +{
  187035. + unsigned int err1;
  187036. +
  187037. + _mipi_csi2_lock(info);
  187038. + err1 = mipi_csi2_read(info, MIPI_CSI2_ERR1);
  187039. + _mipi_csi2_unlock(info);
  187040. +
  187041. + return err1;
  187042. +}
  187043. +EXPORT_SYMBOL(mipi_csi2_get_error1);
  187044. +
  187045. +/*!
  187046. + * This function is called to get mipi csi2 error1 status.
  187047. + *
  187048. + * @param info mipi csi2 hander
  187049. + * @return Returns error1 value
  187050. + */
  187051. +unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info)
  187052. +{
  187053. + unsigned int err2;
  187054. +
  187055. + _mipi_csi2_lock(info);
  187056. + err2 = mipi_csi2_read(info, MIPI_CSI2_ERR2);
  187057. + _mipi_csi2_unlock(info);
  187058. +
  187059. + return err2;
  187060. +}
  187061. +EXPORT_SYMBOL(mipi_csi2_get_error2);
  187062. +
  187063. +/*!
  187064. + * This function is called to enable mipi to ipu pixel clock.
  187065. + *
  187066. + * @param info mipi csi2 hander
  187067. + * @return Returns 0 on success or negative error code on fail
  187068. + */
  187069. +int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info)
  187070. +{
  187071. + return clk_prepare_enable(info->pixel_clk);
  187072. +}
  187073. +EXPORT_SYMBOL(mipi_csi2_pixelclk_enable);
  187074. +
  187075. +/*!
  187076. + * This function is called to disable mipi to ipu pixel clock.
  187077. + *
  187078. + * @param info mipi csi2 hander
  187079. + * @return Returns 0 on success or negative error code on fail
  187080. + */
  187081. +void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info)
  187082. +{
  187083. + clk_disable_unprepare(info->pixel_clk);
  187084. +}
  187085. +EXPORT_SYMBOL(mipi_csi2_pixelclk_disable);
  187086. +
  187087. +/*!
  187088. + * This function is called to power on mipi csi2.
  187089. + *
  187090. + * @param info mipi csi2 hander
  187091. + * @return Returns 0 on success or negative error code on fail
  187092. + */
  187093. +int mipi_csi2_reset(struct mipi_csi2_info *info)
  187094. +{
  187095. + _mipi_csi2_lock(info);
  187096. +
  187097. + mipi_csi2_write(info, 0x0, MIPI_CSI2_PHY_SHUTDOWNZ);
  187098. + mipi_csi2_write(info, 0x0, MIPI_CSI2_DPHY_RSTZ);
  187099. + mipi_csi2_write(info, 0x0, MIPI_CSI2_CSI2_RESETN);
  187100. +
  187101. + mipi_csi2_write(info, 0x00000001, MIPI_CSI2_PHY_TST_CTRL0);
  187102. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL1);
  187103. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  187104. + mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
  187105. + mipi_csi2_write(info, 0x00010044, MIPI_CSI2_PHY_TST_CTRL1);
  187106. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  187107. + mipi_csi2_write(info, 0x00000014, MIPI_CSI2_PHY_TST_CTRL1);
  187108. + mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
  187109. + mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
  187110. +
  187111. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_PHY_SHUTDOWNZ);
  187112. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_DPHY_RSTZ);
  187113. + mipi_csi2_write(info, 0xffffffff, MIPI_CSI2_CSI2_RESETN);
  187114. +
  187115. + _mipi_csi2_unlock(info);
  187116. +
  187117. + return 0;
  187118. +}
  187119. +EXPORT_SYMBOL(mipi_csi2_reset);
  187120. +
  187121. +/*!
  187122. + * This function is called to get mipi csi2 info.
  187123. + *
  187124. + * @return Returns mipi csi2 info struct pointor
  187125. + */
  187126. +struct mipi_csi2_info *mipi_csi2_get_info(void)
  187127. +{
  187128. + return gmipi_csi2;
  187129. +}
  187130. +EXPORT_SYMBOL(mipi_csi2_get_info);
  187131. +
  187132. +/*!
  187133. + * This function is called to get mipi csi2 bind ipu num.
  187134. + *
  187135. + * @return Returns mipi csi2 bind ipu num
  187136. + */
  187137. +int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info)
  187138. +{
  187139. + int ipu_id;
  187140. +
  187141. + _mipi_csi2_lock(info);
  187142. + ipu_id = info->ipu_id;
  187143. + _mipi_csi2_unlock(info);
  187144. +
  187145. + return ipu_id;
  187146. +}
  187147. +EXPORT_SYMBOL(mipi_csi2_get_bind_ipu);
  187148. +
  187149. +/*!
  187150. + * This function is called to get mipi csi2 bind csi num.
  187151. + *
  187152. + * @return Returns mipi csi2 bind csi num
  187153. + */
  187154. +unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info)
  187155. +{
  187156. + unsigned int csi_id;
  187157. +
  187158. + _mipi_csi2_lock(info);
  187159. + csi_id = info->csi_id;
  187160. + _mipi_csi2_unlock(info);
  187161. +
  187162. + return csi_id;
  187163. +}
  187164. +EXPORT_SYMBOL(mipi_csi2_get_bind_csi);
  187165. +
  187166. +/*!
  187167. + * This function is called to get mipi csi2 virtual channel.
  187168. + *
  187169. + * @return Returns mipi csi2 virtual channel num
  187170. + */
  187171. +unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info)
  187172. +{
  187173. + unsigned int v_channel;
  187174. +
  187175. + _mipi_csi2_lock(info);
  187176. + v_channel = info->v_channel;
  187177. + _mipi_csi2_unlock(info);
  187178. +
  187179. + return v_channel;
  187180. +}
  187181. +EXPORT_SYMBOL(mipi_csi2_get_virtual_channel);
  187182. +
  187183. +/**
  187184. + * This function is called by the driver framework to initialize the MIPI CSI2
  187185. + * device.
  187186. + *
  187187. + * @param pdev The device structure for the MIPI CSI2 passed in by the
  187188. + * driver framework.
  187189. + *
  187190. + * @return Returns 0 on success or negative error code on error
  187191. + */
  187192. +static int mipi_csi2_probe(struct platform_device *pdev)
  187193. +{
  187194. + struct device *dev = &pdev->dev;
  187195. + struct device_node *np = pdev->dev.of_node;
  187196. + struct resource *res;
  187197. + u32 mipi_csi2_dphy_ver;
  187198. + int ret;
  187199. +
  187200. + gmipi_csi2 = kmalloc(sizeof(struct mipi_csi2_info), GFP_KERNEL);
  187201. + if (!gmipi_csi2) {
  187202. + ret = -ENOMEM;
  187203. + goto alloc_failed;
  187204. + }
  187205. +
  187206. + ret = of_property_read_u32(np, "ipu_id", &(gmipi_csi2->ipu_id));
  187207. + if (ret) {
  187208. + dev_err(&pdev->dev, "ipu_id missing or invalid\n");
  187209. + goto err;
  187210. + }
  187211. +
  187212. + ret = of_property_read_u32(np, "csi_id", &(gmipi_csi2->csi_id));
  187213. + if (ret) {
  187214. + dev_err(&pdev->dev, "csi_id missing or invalid\n");
  187215. + goto err;
  187216. + }
  187217. +
  187218. + ret = of_property_read_u32(np, "v_channel", &(gmipi_csi2->v_channel));
  187219. + if (ret) {
  187220. + dev_err(&pdev->dev, "v_channel missing or invalid\n");
  187221. + goto err;
  187222. + }
  187223. +
  187224. + ret = of_property_read_u32(np, "lanes", &(gmipi_csi2->lanes));
  187225. + if (ret) {
  187226. + dev_err(&pdev->dev, "lanes missing or invalid\n");
  187227. + goto err;
  187228. + }
  187229. +
  187230. + if ((gmipi_csi2->ipu_id < 0) || (gmipi_csi2->ipu_id > 1) ||
  187231. + (gmipi_csi2->csi_id > 1) || (gmipi_csi2->v_channel > 3) ||
  187232. + (gmipi_csi2->lanes > 4)) {
  187233. + dev_err(&pdev->dev, "invalid param for mipi csi2!\n");
  187234. + ret = -EINVAL;
  187235. + goto err;
  187236. + }
  187237. +
  187238. + /* initialize mutex */
  187239. + mutex_init(&gmipi_csi2->mutex_lock);
  187240. +
  187241. + /* get mipi csi2 informaiton */
  187242. + gmipi_csi2->pdev = pdev;
  187243. + gmipi_csi2->mipi_en = false;
  187244. +
  187245. + gmipi_csi2->cfg_clk = devm_clk_get(dev, "cfg_clk");
  187246. + if (IS_ERR(gmipi_csi2->cfg_clk)) {
  187247. + dev_err(&pdev->dev, "failed to get cfg_clk\n");
  187248. + ret = PTR_ERR(gmipi_csi2->cfg_clk);
  187249. + goto err;
  187250. + }
  187251. +
  187252. + /* get mipi dphy clk */
  187253. + gmipi_csi2->dphy_clk = devm_clk_get(dev, "dphy_clk");
  187254. + if (IS_ERR(gmipi_csi2->dphy_clk)) {
  187255. + dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
  187256. + ret = PTR_ERR(gmipi_csi2->dphy_clk);
  187257. + goto err;
  187258. + }
  187259. +
  187260. + /* get mipi to ipu pixel clk */
  187261. + gmipi_csi2->pixel_clk = devm_clk_get(dev, "pixel_clk");
  187262. + if (IS_ERR(gmipi_csi2->pixel_clk)) {
  187263. + dev_err(&pdev->dev, "failed to get mipi pixel clk\n");
  187264. + ret = PTR_ERR(gmipi_csi2->pixel_clk);
  187265. + goto err;
  187266. + }
  187267. +
  187268. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  187269. + if (!res) {
  187270. + ret = -ENODEV;
  187271. + goto err;
  187272. + }
  187273. +
  187274. + /* mipi register mapping */
  187275. + gmipi_csi2->mipi_csi2_base = ioremap(res->start, PAGE_SIZE);
  187276. + if (!gmipi_csi2->mipi_csi2_base) {
  187277. + ret = -ENOMEM;
  187278. + goto err;
  187279. + }
  187280. +
  187281. + /* mipi dphy clk enable for register access */
  187282. + clk_prepare_enable(gmipi_csi2->dphy_clk);
  187283. + /* get mipi csi2 dphy version */
  187284. + mipi_csi2_dphy_ver = mipi_csi2_read(gmipi_csi2, MIPI_CSI2_VERSION);
  187285. +
  187286. + clk_disable_unprepare(gmipi_csi2->dphy_clk);
  187287. +
  187288. + platform_set_drvdata(pdev, gmipi_csi2);
  187289. +
  187290. + dev_info(&pdev->dev, "i.MX MIPI CSI2 driver probed\n");
  187291. + dev_info(&pdev->dev, "i.MX MIPI CSI2 dphy version is 0x%x\n",
  187292. + mipi_csi2_dphy_ver);
  187293. +
  187294. + return 0;
  187295. +
  187296. +err:
  187297. + kfree(gmipi_csi2);
  187298. +alloc_failed:
  187299. + dev_err(&pdev->dev, "i.MX MIPI CSI2 driver probed - error\n");
  187300. + return ret;
  187301. +}
  187302. +
  187303. +static int mipi_csi2_remove(struct platform_device *pdev)
  187304. +{
  187305. + /* unmapping mipi register */
  187306. + iounmap(gmipi_csi2->mipi_csi2_base);
  187307. +
  187308. + kfree(gmipi_csi2);
  187309. +
  187310. + dev_set_drvdata(&pdev->dev, NULL);
  187311. +
  187312. + return 0;
  187313. +}
  187314. +
  187315. +static const struct of_device_id imx_mipi_csi2_dt_ids[] = {
  187316. + { .compatible = "fsl,imx6q-mipi-csi2", },
  187317. + { /* sentinel */ }
  187318. +};
  187319. +
  187320. +static struct platform_driver mipi_csi2_driver = {
  187321. + .driver = {
  187322. + .name = "mxc_mipi_csi2",
  187323. + .of_match_table = imx_mipi_csi2_dt_ids,
  187324. + },
  187325. + .probe = mipi_csi2_probe,
  187326. + .remove = mipi_csi2_remove,
  187327. +};
  187328. +
  187329. +static int __init mipi_csi2_init(void)
  187330. +{
  187331. + int err;
  187332. +
  187333. + err = platform_driver_register(&mipi_csi2_driver);
  187334. + if (err) {
  187335. + pr_err("mipi_csi2_driver register failed\n");
  187336. + return -ENODEV;
  187337. + }
  187338. +
  187339. + pr_info("MIPI CSI2 driver module loaded\n");
  187340. +
  187341. + return 0;
  187342. +}
  187343. +
  187344. +static void __exit mipi_csi2_cleanup(void)
  187345. +{
  187346. + platform_driver_unregister(&mipi_csi2_driver);
  187347. +}
  187348. +
  187349. +subsys_initcall(mipi_csi2_init);
  187350. +module_exit(mipi_csi2_cleanup);
  187351. +
  187352. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  187353. +MODULE_DESCRIPTION("i.MX MIPI CSI2 driver");
  187354. +MODULE_LICENSE("GPL");
  187355. diff -Nur linux-3.14.17/drivers/mxc/mipi/mxc_mipi_csi2.h linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.h
  187356. --- linux-3.14.17/drivers/mxc/mipi/mxc_mipi_csi2.h 1970-01-01 01:00:00.000000000 +0100
  187357. +++ linux-imx6-3.14/drivers/mxc/mipi/mxc_mipi_csi2.h 2014-09-11 18:06:03.138042515 +0200
  187358. @@ -0,0 +1,46 @@
  187359. +/*
  187360. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  187361. + *
  187362. + * This program is free software; you can redistribute it and/or modify
  187363. + * it under the terms of the GNU General Public License as published by
  187364. + * the Free Software Foundation; either version 2 of the License, or
  187365. + * (at your option) any later version.
  187366. +
  187367. + * This program is distributed in the hope that it will be useful,
  187368. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  187369. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  187370. + * GNU General Public License for more details.
  187371. +
  187372. + * You should have received a copy of the GNU General Public License along
  187373. + * with this program; if not, write to the Free Software Foundation, Inc.,
  187374. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  187375. + */
  187376. +
  187377. +#ifndef __MXC_MIPI_CSI2_H__
  187378. +#define __MXC_MIPI_CSI2_H__
  187379. +
  187380. +#ifdef DEBUG
  187381. +#define mipi_dbg(fmt, ...) \
  187382. + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
  187383. +#else
  187384. +#define mipi_dbg(fmt, ...)
  187385. +#endif
  187386. +
  187387. +/* driver private data */
  187388. +struct mipi_csi2_info {
  187389. + bool mipi_en;
  187390. + int ipu_id;
  187391. + unsigned int csi_id;
  187392. + unsigned int v_channel;
  187393. + unsigned int lanes;
  187394. + unsigned int datatype;
  187395. + struct clk *cfg_clk;
  187396. + struct clk *dphy_clk;
  187397. + struct clk *pixel_clk;
  187398. + void __iomem *mipi_csi2_base;
  187399. + struct platform_device *pdev;
  187400. +
  187401. + struct mutex mutex_lock;
  187402. +};
  187403. +
  187404. +#endif
  187405. diff -Nur linux-3.14.17/drivers/mxc/mlb/Kconfig linux-imx6-3.14/drivers/mxc/mlb/Kconfig
  187406. --- linux-3.14.17/drivers/mxc/mlb/Kconfig 1970-01-01 01:00:00.000000000 +0100
  187407. +++ linux-imx6-3.14/drivers/mxc/mlb/Kconfig 2014-09-11 18:06:03.138042515 +0200
  187408. @@ -0,0 +1,17 @@
  187409. +#
  187410. +# MLB150 configuration
  187411. +#
  187412. +
  187413. +menu "MXC Media Local Bus Driver"
  187414. +
  187415. +config MXC_MLB
  187416. + boolean
  187417. +
  187418. +config MXC_MLB150
  187419. + tristate "MLB150 support"
  187420. + depends on SOC_IMX6Q
  187421. + select MXC_MLB
  187422. + ---help---
  187423. + Say Y to get the MLB150 support.
  187424. +
  187425. +endmenu
  187426. diff -Nur linux-3.14.17/drivers/mxc/mlb/Makefile linux-imx6-3.14/drivers/mxc/mlb/Makefile
  187427. --- linux-3.14.17/drivers/mxc/mlb/Makefile 1970-01-01 01:00:00.000000000 +0100
  187428. +++ linux-imx6-3.14/drivers/mxc/mlb/Makefile 2014-09-11 18:06:03.138042515 +0200
  187429. @@ -0,0 +1,5 @@
  187430. +#
  187431. +# Makefile for the i.MX6Q/DL MLB150 driver
  187432. +#
  187433. +
  187434. +obj-$(CONFIG_MXC_MLB150) += mxc_mlb150.o
  187435. diff -Nur linux-3.14.17/drivers/mxc/mlb/mxc_mlb150.c linux-imx6-3.14/drivers/mxc/mlb/mxc_mlb150.c
  187436. --- linux-3.14.17/drivers/mxc/mlb/mxc_mlb150.c 1970-01-01 01:00:00.000000000 +0100
  187437. +++ linux-imx6-3.14/drivers/mxc/mlb/mxc_mlb150.c 2014-09-11 18:06:03.142042530 +0200
  187438. @@ -0,0 +1,2778 @@
  187439. +/*
  187440. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  187441. + *
  187442. + * This program is free software; you can redistribute it and/or modify
  187443. + * it under the terms of the GNU General Public License as published by
  187444. + * the Free Software Foundation; either version 2 of the License, or
  187445. + * (at your option) any later version.
  187446. + *
  187447. + * This program is distributed in the hope that it will be useful,
  187448. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  187449. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  187450. + * GNU General Public License for more details.
  187451. + *
  187452. + * You should have received a copy of the GNU General Public License along
  187453. + * with this program; if not, write to the Free Software Foundation, Inc.,
  187454. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  187455. + */
  187456. +
  187457. +#include <linux/cdev.h>
  187458. +#include <linux/circ_buf.h>
  187459. +#include <linux/clk.h>
  187460. +#include <linux/delay.h>
  187461. +#include <linux/device.h>
  187462. +#include <linux/errno.h>
  187463. +#include <linux/fs.h>
  187464. +#include <linux/genalloc.h>
  187465. +#include <linux/init.h>
  187466. +#include <linux/interrupt.h>
  187467. +#include <linux/io.h>
  187468. +#include <linux/kernel.h>
  187469. +#include <linux/module.h>
  187470. +#include <linux/mxc_mlb.h>
  187471. +#include <linux/of.h>
  187472. +#include <linux/platform_device.h>
  187473. +#include <linux/poll.h>
  187474. +#include <linux/regulator/consumer.h>
  187475. +#include <linux/sched.h>
  187476. +#include <linux/slab.h>
  187477. +#include <linux/spinlock.h>
  187478. +#include <linux/uaccess.h>
  187479. +
  187480. +#define DRIVER_NAME "mxc_mlb150"
  187481. +
  187482. +/*
  187483. + * MLB module memory map registers define
  187484. + */
  187485. +#define REG_MLBC0 0x0
  187486. +#define MLBC0_MLBEN (0x1)
  187487. +#define MLBC0_MLBCLK_MASK (0x7 << 2)
  187488. +#define MLBC0_MLBCLK_SHIFT (2)
  187489. +#define MLBC0_MLBPEN (0x1 << 5)
  187490. +#define MLBC0_MLBLK (0x1 << 7)
  187491. +#define MLBC0_ASYRETRY (0x1 << 12)
  187492. +#define MLBC0_CTLRETRY (0x1 << 12)
  187493. +#define MLBC0_FCNT_MASK (0x7 << 15)
  187494. +#define MLBC0_FCNT_SHIFT (15)
  187495. +
  187496. +#define REG_MLBPC0 0x8
  187497. +#define MLBPC0_MCLKHYS (0x1 << 11)
  187498. +
  187499. +#define REG_MS0 0xC
  187500. +#define REG_MS1 0x14
  187501. +
  187502. +#define REG_MSS 0x20
  187503. +#define MSS_RSTSYSCMD (0x1)
  187504. +#define MSS_LKSYSCMD (0x1 << 1)
  187505. +#define MSS_ULKSYSCMD (0x1 << 2)
  187506. +#define MSS_CSSYSCMD (0x1 << 3)
  187507. +#define MSS_SWSYSCMD (0x1 << 4)
  187508. +#define MSS_SERVREQ (0x1 << 5)
  187509. +
  187510. +#define REG_MSD 0x24
  187511. +
  187512. +#define REG_MIEN 0x2C
  187513. +#define MIEN_ISOC_PE (0x1)
  187514. +#define MIEN_ISOC_BUFO (0x1 << 1)
  187515. +#define MIEN_SYNC_PE (0x1 << 16)
  187516. +#define MIEN_ARX_DONE (0x1 << 17)
  187517. +#define MIEN_ARX_PE (0x1 << 18)
  187518. +#define MIEN_ARX_BREAK (0x1 << 19)
  187519. +#define MIEN_ATX_DONE (0x1 << 20)
  187520. +#define MIEN_ATX_PE (0x1 << 21)
  187521. +#define MIEN_ATX_BREAK (0x1 << 22)
  187522. +#define MIEN_CRX_DONE (0x1 << 24)
  187523. +#define MIEN_CRX_PE (0x1 << 25)
  187524. +#define MIEN_CRX_BREAK (0x1 << 26)
  187525. +#define MIEN_CTX_DONE (0x1 << 27)
  187526. +#define MIEN_CTX_PE (0x1 << 28)
  187527. +#define MIEN_CTX_BREAK (0x1 << 29)
  187528. +
  187529. +#define REG_MLBPC2 0x34
  187530. +#define REG_MLBPC1 0x38
  187531. +#define MLBPC1_VAL (0x00000888)
  187532. +
  187533. +#define REG_MLBC1 0x3C
  187534. +#define MLBC1_LOCK (0x1 << 6)
  187535. +#define MLBC1_CLKM (0x1 << 7)
  187536. +#define MLBC1_NDA_MASK (0xFF << 8)
  187537. +#define MLBC1_NDA_SHIFT (8)
  187538. +
  187539. +#define REG_HCTL 0x80
  187540. +#define HCTL_RST0 (0x1)
  187541. +#define HCTL_RST1 (0x1 << 1)
  187542. +#define HCTL_EN (0x1 << 15)
  187543. +
  187544. +#define REG_HCMR0 0x88
  187545. +#define REG_HCMR1 0x8C
  187546. +#define REG_HCER0 0x90
  187547. +#define REG_HCER1 0x94
  187548. +#define REG_HCBR0 0x98
  187549. +#define REG_HCBR1 0x9C
  187550. +
  187551. +#define REG_MDAT0 0xC0
  187552. +#define REG_MDAT1 0xC4
  187553. +#define REG_MDAT2 0xC8
  187554. +#define REG_MDAT3 0xCC
  187555. +
  187556. +#define REG_MDWE0 0xD0
  187557. +#define REG_MDWE1 0xD4
  187558. +#define REG_MDWE2 0xD8
  187559. +#define REG_MDWE3 0xDC
  187560. +
  187561. +#define REG_MCTL 0xE0
  187562. +#define MCTL_XCMP (0x1)
  187563. +
  187564. +#define REG_MADR 0xE4
  187565. +#define MADR_WNR (0x1 << 31)
  187566. +#define MADR_TB (0x1 << 30)
  187567. +#define MADR_ADDR_MASK (0x7f << 8)
  187568. +#define MADR_ADDR_SHIFT (0)
  187569. +
  187570. +#define REG_ACTL 0x3C0
  187571. +#define ACTL_MPB (0x1 << 4)
  187572. +#define ACTL_DMAMODE (0x1 << 2)
  187573. +#define ACTL_SMX (0x1 << 1)
  187574. +#define ACTL_SCE (0x1)
  187575. +
  187576. +#define REG_ACSR0 0x3D0
  187577. +#define REG_ACSR1 0x3D4
  187578. +#define REG_ACMR0 0x3D8
  187579. +#define REG_ACMR1 0x3DC
  187580. +
  187581. +#define REG_CAT_MDATn(ch) (REG_MDAT0 + ((ch % 8) >> 1) * 4)
  187582. +#define REG_CAT_MDWEn(ch) (REG_MDWE0 + ((ch % 8) >> 1) * 4)
  187583. +
  187584. +#define INT_AHB0_CH_START (0)
  187585. +#define INT_AHB1_CH_START (32)
  187586. +
  187587. +#define LOGIC_CH_NUM (64)
  187588. +#define BUF_CDT_OFFSET (0x0)
  187589. +#define BUF_ADT_OFFSET (0x40)
  187590. +#define BUF_CAT_MLB_OFFSET (0x80)
  187591. +#define BUF_CAT_HBI_OFFSET (0x88)
  187592. +#define BUF_CTR_END_OFFSET (0x8F)
  187593. +
  187594. +#define CAT_MODE_RX (0x1 << 0)
  187595. +#define CAT_MODE_TX (0x1 << 1)
  187596. +#define CAT_MODE_INBOUND_DMA (0x1 << 8)
  187597. +#define CAT_MODE_OUTBOUND_DMA (0x1 << 9)
  187598. +
  187599. +#define CH_SYNC_DEFAULT_QUAD (1)
  187600. +#define CH_SYNC_MAX_QUAD (15)
  187601. +#define CH_SYNC_CDT_BUF_DEP (CH_SYNC_DEFAULT_QUAD * 4 * 4)
  187602. +#define CH_SYNC_ADT_BUF_MULTI (4)
  187603. +#define CH_SYNC_ADT_BUF_DEP (CH_SYNC_CDT_BUF_DEP * CH_SYNC_ADT_BUF_MULTI)
  187604. +#define CH_SYNC_BUF_SZ (CH_SYNC_MAX_QUAD * 4 * 4 * \
  187605. + CH_SYNC_ADT_BUF_MULTI)
  187606. +#define CH_CTRL_CDT_BUF_DEP (64)
  187607. +#define CH_CTRL_ADT_BUF_DEP (CH_CTRL_CDT_BUF_DEP)
  187608. +#define CH_CTRL_BUF_SZ (CH_CTRL_ADT_BUF_DEP)
  187609. +#define CH_ASYNC_MDP_PACKET_LEN (1024)
  187610. +#define CH_ASYNC_MEP_PACKET_LEN (1536)
  187611. +#define CH_ASYNC_CDT_BUF_DEP (CH_ASYNC_MEP_PACKET_LEN)
  187612. +#define CH_ASYNC_ADT_BUF_DEP (CH_ASYNC_CDT_BUF_DEP)
  187613. +#define CH_ASYNC_BUF_SZ (CH_ASYNC_ADT_BUF_DEP)
  187614. +#define CH_ISOC_BLK_SIZE_188 (188)
  187615. +#define CH_ISOC_BLK_SIZE_196 (196)
  187616. +#define CH_ISOC_BLK_SIZE (CH_ISOC_BLK_SIZE_188)
  187617. +#define CH_ISOC_BLK_NUM (1)
  187618. +#define CH_ISOC_CDT_BUF_DEP (CH_ISOC_BLK_SIZE * CH_ISOC_BLK_NUM)
  187619. +#define CH_ISOC_ADT_BUF_DEP (CH_ISOC_CDT_BUF_DEP)
  187620. +#define CH_ISOC_BUF_SZ (1024)
  187621. +
  187622. +#define CH_SYNC_DBR_BUF_OFFSET (0x0)
  187623. +#define CH_CTRL_DBR_BUF_OFFSET (CH_SYNC_DBR_BUF_OFFSET + \
  187624. + 2 * (CH_SYNC_MAX_QUAD * 4 * 4))
  187625. +#define CH_ASYNC_DBR_BUF_OFFSET (CH_CTRL_DBR_BUF_OFFSET + \
  187626. + 2 * CH_CTRL_CDT_BUF_DEP)
  187627. +#define CH_ISOC_DBR_BUF_OFFSET (CH_ASYNC_DBR_BUF_OFFSET + \
  187628. + 2 * CH_ASYNC_CDT_BUF_DEP)
  187629. +
  187630. +#define DBR_BUF_START 0x00000
  187631. +
  187632. +#define CDT_LEN (16)
  187633. +#define ADT_LEN (16)
  187634. +#define CAT_LEN (2)
  187635. +
  187636. +#define CDT_SZ (CDT_LEN * LOGIC_CH_NUM)
  187637. +#define ADT_SZ (ADT_LEN * LOGIC_CH_NUM)
  187638. +#define CAT_SZ (CAT_LEN * LOGIC_CH_NUM * 2)
  187639. +
  187640. +#define CDT_BASE(base) (base + BUF_CDT_OFFSET)
  187641. +#define ADT_BASE(base) (base + BUF_ADT_OFFSET)
  187642. +#define CAT_MLB_BASE(base) (base + BUF_CAT_MLB_OFFSET)
  187643. +#define CAT_HBI_BASE(base) (base + BUF_CAT_HBI_OFFSET)
  187644. +
  187645. +#define CDTn_ADDR(base, n) (base + BUF_CDT_OFFSET + n * CDT_LEN)
  187646. +#define ADTn_ADDR(base, n) (base + BUF_ADT_OFFSET + n * ADT_LEN)
  187647. +#define CATn_MLB_ADDR(base, n) (base + BUF_CAT_MLB_OFFSET + n * CAT_LEN)
  187648. +#define CATn_HBI_ADDR(base, n) (base + BUF_CAT_HBI_OFFSET + n * CAT_LEN)
  187649. +
  187650. +#define CAT_CL_SHIFT (0x0)
  187651. +#define CAT_CT_SHIFT (8)
  187652. +#define CAT_CE (0x1 << 11)
  187653. +#define CAT_RNW (0x1 << 12)
  187654. +#define CAT_MT (0x1 << 13)
  187655. +#define CAT_FCE (0x1 << 14)
  187656. +#define CAT_MFE (0x1 << 14)
  187657. +
  187658. +#define CDT_WSBC_SHIFT (14)
  187659. +#define CDT_WPC_SHIFT (11)
  187660. +#define CDT_RSBC_SHIFT (30)
  187661. +#define CDT_RPC_SHIFT (27)
  187662. +#define CDT_WPC_1_SHIFT (12)
  187663. +#define CDT_RPC_1_SHIFT (28)
  187664. +#define CDT_WPTR_SHIFT (0)
  187665. +#define CDT_SYNC_WSTS_MASK (0x0000f000)
  187666. +#define CDT_SYNC_WSTS_SHIFT (12)
  187667. +#define CDT_CTRL_ASYNC_WSTS_MASK (0x0000f000)
  187668. +#define CDT_CTRL_ASYNC_WSTS_SHIFT (12)
  187669. +#define CDT_ISOC_WSTS_MASK (0x0000e000)
  187670. +#define CDT_ISOC_WSTS_SHIFT (13)
  187671. +#define CDT_RPTR_SHIFT (16)
  187672. +#define CDT_SYNC_RSTS_MASK (0xf0000000)
  187673. +#define CDT_SYNC_RSTS_SHIFT (28)
  187674. +#define CDT_CTRL_ASYNC_RSTS_MASK (0xf0000000)
  187675. +#define CDT_CTRL_ASYNC_RSTS_SHIFT (28)
  187676. +#define CDT_ISOC_RSTS_MASK (0xe0000000)
  187677. +#define CDT_ISOC_RSTS_SHIFT (29)
  187678. +#define CDT_CTRL_ASYNC_WSTS_1 (0x1 << 14)
  187679. +#define CDT_CTRL_ASYNC_RSTS_1 (0x1 << 15)
  187680. +#define CDT_BD_SHIFT (0)
  187681. +#define CDT_BA_SHIFT (16)
  187682. +#define CDT_BS_SHIFT (0)
  187683. +#define CDT_BF_SHIFT (31)
  187684. +
  187685. +#define ADT_PG (0x1 << 13)
  187686. +#define ADT_LE (0x1 << 14)
  187687. +#define ADT_CE (0x1 << 15)
  187688. +#define ADT_BD1_SHIFT (0)
  187689. +#define ADT_ERR1 (0x1 << 13)
  187690. +#define ADT_DNE1 (0x1 << 14)
  187691. +#define ADT_RDY1 (0x1 << 15)
  187692. +#define ADT_BD2_SHIFT (16)
  187693. +#define ADT_ERR2 (0x1 << 29)
  187694. +#define ADT_DNE2 (0x1 << 30)
  187695. +#define ADT_RDY2 (0x1 << 31)
  187696. +#define ADT_BA1_SHIFT (0x0)
  187697. +#define ADT_BA2_SHIFT (0x0)
  187698. +#define ADT_PS1 (0x1 << 12)
  187699. +#define ADT_PS2 (0x1 << 28)
  187700. +#define ADT_MEP1 (0x1 << 11)
  187701. +#define ADT_MEP2 (0x1 << 27)
  187702. +
  187703. +#define MLB_MINOR_DEVICES 4
  187704. +#define MLB_CONTROL_DEV_NAME "ctrl"
  187705. +#define MLB_ASYNC_DEV_NAME "async"
  187706. +#define MLB_SYNC_DEV_NAME "sync"
  187707. +#define MLB_ISOC_DEV_NAME "isoc"
  187708. +
  187709. +#define TX_CHANNEL 0
  187710. +#define RX_CHANNEL 1
  187711. +
  187712. +#define TRANS_RING_NODES (1 << 3)
  187713. +
  187714. +enum MLB_CTYPE {
  187715. + MLB_CTYPE_SYNC,
  187716. + MLB_CTYPE_CTRL,
  187717. + MLB_CTYPE_ASYNC,
  187718. + MLB_CTYPE_ISOC,
  187719. +};
  187720. +
  187721. +enum CLK_SPEED {
  187722. + CLK_256FS,
  187723. + CLK_512FS,
  187724. + CLK_1024FS,
  187725. + CLK_2048FS,
  187726. + CLK_3072FS,
  187727. + CLK_4096FS,
  187728. + CLK_6144FS,
  187729. + CLK_8192FS,
  187730. +};
  187731. +
  187732. +struct mlb_ringbuf {
  187733. + s8 *virt_bufs[TRANS_RING_NODES];
  187734. + u32 phy_addrs[TRANS_RING_NODES];
  187735. + s32 head;
  187736. + s32 tail;
  187737. + s32 unit_size;
  187738. + s32 total_size;
  187739. + rwlock_t rb_lock ____cacheline_aligned; /* ring index lock */
  187740. +};
  187741. +
  187742. +struct mlb_channel_info {
  187743. + /* Input MLB channel address */
  187744. + u32 address;
  187745. + /* Internal AHB channel label */
  187746. + u32 cl;
  187747. + /* DBR buf head */
  187748. + u32 dbr_buf_head;
  187749. +};
  187750. +
  187751. +struct mlb_dev_info {
  187752. + /* device node name */
  187753. + const char dev_name[20];
  187754. + /* channel type */
  187755. + const unsigned int channel_type;
  187756. + /* ch fps */
  187757. + enum CLK_SPEED fps;
  187758. + /* channel info for tx/rx */
  187759. + struct mlb_channel_info channels[2];
  187760. + /* ring buffer */
  187761. + u8 *rbuf_base_virt;
  187762. + u32 rbuf_base_phy;
  187763. + struct mlb_ringbuf rx_rbuf;
  187764. + struct mlb_ringbuf tx_rbuf;
  187765. + /* exception event */
  187766. + unsigned long ex_event;
  187767. + /* tx busy indicator */
  187768. + unsigned long tx_busy;
  187769. + /* channel started up or not */
  187770. + atomic_t on;
  187771. + /* device open count */
  187772. + atomic_t opencnt;
  187773. + /* wait queue head for channel */
  187774. + wait_queue_head_t rx_wq;
  187775. + wait_queue_head_t tx_wq;
  187776. + /* TX OK */
  187777. + s32 tx_ok;
  187778. + /* spinlock for event access */
  187779. + spinlock_t event_lock;
  187780. + /*
  187781. + * Block size for isoc mode
  187782. + * This variable can be configured in ioctl
  187783. + */
  187784. + u32 isoc_blksz;
  187785. + /*
  187786. + * Quads number for sync mode
  187787. + * This variable can be confifured in ioctl
  187788. + */
  187789. + u32 sync_quad;
  187790. + /* Buffer depth in cdt */
  187791. + u32 cdt_buf_dep;
  187792. + /* Buffer depth in adt */
  187793. + u32 adt_buf_dep;
  187794. + /* Buffer size to hold data */
  187795. + u32 buf_size;
  187796. +};
  187797. +
  187798. +struct mlb_data {
  187799. + struct mlb_dev_info *devinfo;
  187800. + struct clk *clk_mlb3p;
  187801. + struct clk *clk_mlb6p;
  187802. + struct cdev cdev;
  187803. + struct class *class; /* device class */
  187804. + dev_t firstdev;
  187805. +#ifdef CONFIG_REGULATOR
  187806. + struct regulator *nvcc;
  187807. +#endif
  187808. + void __iomem *membase; /* mlb module base address */
  187809. + struct gen_pool *iram_pool;
  187810. + u32 iram_size;
  187811. + u32 irq_ahb0;
  187812. + u32 irq_ahb1;
  187813. + u32 irq_mlb;
  187814. +};
  187815. +
  187816. +/*
  187817. + * For optimization, we use fixed channel label for
  187818. + * input channels of each mode
  187819. + * SYNC: CL = 0 for RX, CL = 64 for TX
  187820. + * CTRL: CL = 1 for RX, CL = 65 for TX
  187821. + * ASYNC: CL = 2 for RX, CL = 66 for TX
  187822. + * ISOC: CL = 3 for RX, CL = 67 for TX
  187823. + */
  187824. +#define SYNC_RX_CL_AHB0 0
  187825. +#define CTRL_RX_CL_AHB0 1
  187826. +#define ASYNC_RX_CL_AHB0 2
  187827. +#define ISOC_RX_CL_AHB0 3
  187828. +#define SYNC_TX_CL_AHB0 4
  187829. +#define CTRL_TX_CL_AHB0 5
  187830. +#define ASYNC_TX_CL_AHB0 6
  187831. +#define ISOC_TX_CL_AHB0 7
  187832. +
  187833. +#define SYNC_RX_CL_AHB1 32
  187834. +#define CTRL_RX_CL_AHB1 33
  187835. +#define ASYNC_RX_CL_AHB1 34
  187836. +#define ISOC_RX_CL_AHB1 35
  187837. +#define SYNC_TX_CL_AHB1 36
  187838. +#define CTRL_TX_CL_AHB1 37
  187839. +#define ASYNC_TX_CL_AHB1 38
  187840. +#define ISOC_TX_CL_AHB1 39
  187841. +
  187842. +#define SYNC_RX_CL SYNC_RX_CL_AHB0
  187843. +#define CTRL_RX_CL CTRL_RX_CL_AHB0
  187844. +#define ASYNC_RX_CL ASYNC_RX_CL_AHB0
  187845. +#define ISOC_RX_CL ISOC_RX_CL_AHB0
  187846. +
  187847. +#define SYNC_TX_CL SYNC_TX_CL_AHB0
  187848. +#define CTRL_TX_CL CTRL_TX_CL_AHB0
  187849. +#define ASYNC_TX_CL ASYNC_TX_CL_AHB0
  187850. +#define ISOC_TX_CL ISOC_TX_CL_AHB0
  187851. +
  187852. +static struct mlb_dev_info mlb_devinfo[MLB_MINOR_DEVICES] = {
  187853. + {
  187854. + .dev_name = MLB_SYNC_DEV_NAME,
  187855. + .channel_type = MLB_CTYPE_SYNC,
  187856. + .channels = {
  187857. + [0] = {
  187858. + .cl = SYNC_TX_CL,
  187859. + .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET,
  187860. + },
  187861. + [1] = {
  187862. + .cl = SYNC_RX_CL,
  187863. + .dbr_buf_head = CH_SYNC_DBR_BUF_OFFSET
  187864. + + CH_SYNC_BUF_SZ,
  187865. + },
  187866. + },
  187867. + .rx_rbuf = {
  187868. + .unit_size = CH_SYNC_BUF_SZ,
  187869. + .rb_lock =
  187870. + __RW_LOCK_UNLOCKED(mlb_devinfo[0].rx_rbuf.rb_lock),
  187871. + },
  187872. + .tx_rbuf = {
  187873. + .unit_size = CH_SYNC_BUF_SZ,
  187874. + .rb_lock =
  187875. + __RW_LOCK_UNLOCKED(mlb_devinfo[0].tx_rbuf.rb_lock),
  187876. + },
  187877. + .cdt_buf_dep = CH_SYNC_CDT_BUF_DEP,
  187878. + .adt_buf_dep = CH_SYNC_ADT_BUF_DEP,
  187879. + .buf_size = CH_SYNC_BUF_SZ,
  187880. + .on = ATOMIC_INIT(0),
  187881. + .opencnt = ATOMIC_INIT(0),
  187882. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[0].event_lock),
  187883. + },
  187884. + {
  187885. + .dev_name = MLB_CONTROL_DEV_NAME,
  187886. + .channel_type = MLB_CTYPE_CTRL,
  187887. + .channels = {
  187888. + [0] = {
  187889. + .cl = CTRL_TX_CL,
  187890. + .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET,
  187891. + },
  187892. + [1] = {
  187893. + .cl = CTRL_RX_CL,
  187894. + .dbr_buf_head = CH_CTRL_DBR_BUF_OFFSET
  187895. + + CH_CTRL_BUF_SZ,
  187896. + },
  187897. + },
  187898. + .rx_rbuf = {
  187899. + .unit_size = CH_CTRL_BUF_SZ,
  187900. + .rb_lock =
  187901. + __RW_LOCK_UNLOCKED(mlb_devinfo[1].rx_rbuf.rb_lock),
  187902. + },
  187903. + .tx_rbuf = {
  187904. + .unit_size = CH_CTRL_BUF_SZ,
  187905. + .rb_lock =
  187906. + __RW_LOCK_UNLOCKED(mlb_devinfo[1].tx_rbuf.rb_lock),
  187907. + },
  187908. + .cdt_buf_dep = CH_CTRL_CDT_BUF_DEP,
  187909. + .adt_buf_dep = CH_CTRL_ADT_BUF_DEP,
  187910. + .buf_size = CH_CTRL_BUF_SZ,
  187911. + .on = ATOMIC_INIT(0),
  187912. + .opencnt = ATOMIC_INIT(0),
  187913. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[1].event_lock),
  187914. + },
  187915. + {
  187916. + .dev_name = MLB_ASYNC_DEV_NAME,
  187917. + .channel_type = MLB_CTYPE_ASYNC,
  187918. + .channels = {
  187919. + [0] = {
  187920. + .cl = ASYNC_TX_CL,
  187921. + .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET,
  187922. + },
  187923. + [1] = {
  187924. + .cl = ASYNC_RX_CL,
  187925. + .dbr_buf_head = CH_ASYNC_DBR_BUF_OFFSET
  187926. + + CH_ASYNC_BUF_SZ,
  187927. + },
  187928. + },
  187929. + .rx_rbuf = {
  187930. + .unit_size = CH_ASYNC_BUF_SZ,
  187931. + .rb_lock =
  187932. + __RW_LOCK_UNLOCKED(mlb_devinfo[2].rx_rbuf.rb_lock),
  187933. + },
  187934. + .tx_rbuf = {
  187935. + .unit_size = CH_ASYNC_BUF_SZ,
  187936. + .rb_lock =
  187937. + __RW_LOCK_UNLOCKED(mlb_devinfo[2].tx_rbuf.rb_lock),
  187938. + },
  187939. + .cdt_buf_dep = CH_ASYNC_CDT_BUF_DEP,
  187940. + .adt_buf_dep = CH_ASYNC_ADT_BUF_DEP,
  187941. + .buf_size = CH_ASYNC_BUF_SZ,
  187942. + .on = ATOMIC_INIT(0),
  187943. + .opencnt = ATOMIC_INIT(0),
  187944. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[2].event_lock),
  187945. + },
  187946. + {
  187947. + .dev_name = MLB_ISOC_DEV_NAME,
  187948. + .channel_type = MLB_CTYPE_ISOC,
  187949. + .channels = {
  187950. + [0] = {
  187951. + .cl = ISOC_TX_CL,
  187952. + .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET,
  187953. + },
  187954. + [1] = {
  187955. + .cl = ISOC_RX_CL,
  187956. + .dbr_buf_head = CH_ISOC_DBR_BUF_OFFSET
  187957. + + CH_ISOC_BUF_SZ,
  187958. + },
  187959. + },
  187960. + .rx_rbuf = {
  187961. + .unit_size = CH_ISOC_BUF_SZ,
  187962. + .rb_lock =
  187963. + __RW_LOCK_UNLOCKED(mlb_devinfo[3].rx_rbuf.rb_lock),
  187964. + },
  187965. + .tx_rbuf = {
  187966. + .unit_size = CH_ISOC_BUF_SZ,
  187967. + .rb_lock =
  187968. + __RW_LOCK_UNLOCKED(mlb_devinfo[3].tx_rbuf.rb_lock),
  187969. + },
  187970. + .cdt_buf_dep = CH_ISOC_CDT_BUF_DEP,
  187971. + .adt_buf_dep = CH_ISOC_ADT_BUF_DEP,
  187972. + .buf_size = CH_ISOC_BUF_SZ,
  187973. + .on = ATOMIC_INIT(0),
  187974. + .opencnt = ATOMIC_INIT(0),
  187975. + .event_lock = __SPIN_LOCK_UNLOCKED(mlb_devinfo[3].event_lock),
  187976. + .isoc_blksz = CH_ISOC_BLK_SIZE_188,
  187977. + },
  187978. +};
  187979. +
  187980. +static void __iomem *mlb_base;
  187981. +
  187982. +DEFINE_SPINLOCK(ctr_lock);
  187983. +
  187984. +#ifdef DEBUG
  187985. +#define DUMP_REG(reg) pr_debug(#reg": 0x%08x\n", __raw_readl(mlb_base + reg))
  187986. +
  187987. +static void mlb150_dev_dump_reg(void)
  187988. +{
  187989. + pr_debug("mxc_mlb150: Dump registers:\n");
  187990. + DUMP_REG(REG_MLBC0);
  187991. + DUMP_REG(REG_MLBPC0);
  187992. + DUMP_REG(REG_MS0);
  187993. + DUMP_REG(REG_MS1);
  187994. + DUMP_REG(REG_MSS);
  187995. + DUMP_REG(REG_MSD);
  187996. + DUMP_REG(REG_MIEN);
  187997. + DUMP_REG(REG_MLBPC2);
  187998. + DUMP_REG(REG_MLBPC1);
  187999. + DUMP_REG(REG_MLBC1);
  188000. + DUMP_REG(REG_HCTL);
  188001. + DUMP_REG(REG_HCMR0);
  188002. + DUMP_REG(REG_HCMR1);
  188003. + DUMP_REG(REG_HCER0);
  188004. + DUMP_REG(REG_HCER1);
  188005. + DUMP_REG(REG_HCBR0);
  188006. + DUMP_REG(REG_HCBR1);
  188007. + DUMP_REG(REG_MDAT0);
  188008. + DUMP_REG(REG_MDAT1);
  188009. + DUMP_REG(REG_MDAT2);
  188010. + DUMP_REG(REG_MDAT3);
  188011. + DUMP_REG(REG_MDWE0);
  188012. + DUMP_REG(REG_MDWE1);
  188013. + DUMP_REG(REG_MDWE2);
  188014. + DUMP_REG(REG_MDWE3);
  188015. + DUMP_REG(REG_MCTL);
  188016. + DUMP_REG(REG_MADR);
  188017. + DUMP_REG(REG_ACTL);
  188018. + DUMP_REG(REG_ACSR0);
  188019. + DUMP_REG(REG_ACSR1);
  188020. + DUMP_REG(REG_ACMR0);
  188021. + DUMP_REG(REG_ACMR1);
  188022. +}
  188023. +
  188024. +static void mlb150_dev_dump_hex(const u8 *buf, u32 len)
  188025. +{
  188026. + print_hex_dump(KERN_DEBUG, "CTR DUMP:",
  188027. + DUMP_PREFIX_OFFSET, 8, 1, buf, len, 0);
  188028. +}
  188029. +#endif
  188030. +
  188031. +static inline void mlb150_dev_enable_ctr_write(u32 mdat0_bits_en,
  188032. + u32 mdat1_bits_en, u32 mdat2_bits_en, u32 mdat3_bits_en)
  188033. +{
  188034. + __raw_writel(mdat0_bits_en, mlb_base + REG_MDWE0);
  188035. + __raw_writel(mdat1_bits_en, mlb_base + REG_MDWE1);
  188036. + __raw_writel(mdat2_bits_en, mlb_base + REG_MDWE2);
  188037. + __raw_writel(mdat3_bits_en, mlb_base + REG_MDWE3);
  188038. +}
  188039. +
  188040. +#ifdef DEBUG
  188041. +static inline u8 mlb150_dev_dbr_read(u32 dbr_addr)
  188042. +{
  188043. + s32 timeout = 1000;
  188044. + u8 dbr_val = 0;
  188045. + unsigned long flags;
  188046. +
  188047. + spin_lock_irqsave(&ctr_lock, flags);
  188048. + __raw_writel(MADR_TB | dbr_addr,
  188049. + mlb_base + REG_MADR);
  188050. +
  188051. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  188052. + & MCTL_XCMP)) &&
  188053. + timeout--)
  188054. + ;
  188055. +
  188056. + if (0 == timeout) {
  188057. + spin_unlock_irqrestore(&ctr_lock, flags);
  188058. + return -ETIME;
  188059. + }
  188060. +
  188061. + dbr_val = __raw_readl(mlb_base + REG_MDAT0) & 0x000000ff;
  188062. +
  188063. + __raw_writel(0, mlb_base + REG_MCTL);
  188064. + spin_unlock_irqrestore(&ctr_lock, flags);
  188065. +
  188066. + return dbr_val;
  188067. +}
  188068. +
  188069. +static inline s32 mlb150_dev_dbr_write(u32 dbr_addr, u8 dbr_val)
  188070. +{
  188071. + s32 timeout = 1000;
  188072. + u32 mdat0 = dbr_val & 0x000000ff;
  188073. + unsigned long flags;
  188074. +
  188075. + spin_lock_irqsave(&ctr_lock, flags);
  188076. + __raw_writel(mdat0, mlb_base + REG_MDAT0);
  188077. +
  188078. + __raw_writel(MADR_WNR | MADR_TB | dbr_addr,
  188079. + mlb_base + REG_MADR);
  188080. +
  188081. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  188082. + & MCTL_XCMP)) &&
  188083. + timeout--)
  188084. + ;
  188085. +
  188086. + if (timeout <= 0) {
  188087. + spin_unlock_irqrestore(&ctr_lock, flags);
  188088. + return -ETIME;
  188089. + }
  188090. +
  188091. + __raw_writel(0, mlb_base + REG_MCTL);
  188092. + spin_unlock_irqrestore(&ctr_lock, flags);
  188093. +
  188094. + return 0;
  188095. +}
  188096. +
  188097. +static inline s32 mlb150_dev_dbr_dump(u32 addr, u32 size)
  188098. +{
  188099. + u8 *dump_buf = NULL;
  188100. + u8 *buf_ptr = NULL;
  188101. + s32 i;
  188102. +
  188103. + dump_buf = kzalloc(size, GFP_KERNEL);
  188104. + if (!dump_buf) {
  188105. + pr_err("can't allocate enough memory\n");
  188106. + return -ENOMEM;
  188107. + }
  188108. +
  188109. + for (i = 0, buf_ptr = dump_buf;
  188110. + i < size; ++i, ++buf_ptr)
  188111. + *buf_ptr = mlb150_dev_dbr_read(addr + i);
  188112. +
  188113. + mlb150_dev_dump_hex(dump_buf, size);
  188114. +
  188115. + kfree(dump_buf);
  188116. +
  188117. + return 0;
  188118. +}
  188119. +#endif
  188120. +
  188121. +static s32 mlb150_dev_ctr_read(u32 ctr_offset, u32 *ctr_val)
  188122. +{
  188123. + s32 timeout = 1000;
  188124. + unsigned long flags;
  188125. +
  188126. + spin_lock_irqsave(&ctr_lock, flags);
  188127. + __raw_writel(ctr_offset, mlb_base + REG_MADR);
  188128. +
  188129. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  188130. + & MCTL_XCMP)) &&
  188131. + timeout--)
  188132. + ;
  188133. +
  188134. + if (timeout <= 0) {
  188135. + spin_unlock_irqrestore(&ctr_lock, flags);
  188136. + pr_debug("mxc_mlb150: Read CTR timeout\n");
  188137. + return -ETIME;
  188138. + }
  188139. +
  188140. + ctr_val[0] = __raw_readl(mlb_base + REG_MDAT0);
  188141. + ctr_val[1] = __raw_readl(mlb_base + REG_MDAT1);
  188142. + ctr_val[2] = __raw_readl(mlb_base + REG_MDAT2);
  188143. + ctr_val[3] = __raw_readl(mlb_base + REG_MDAT3);
  188144. +
  188145. + __raw_writel(0, mlb_base + REG_MCTL);
  188146. +
  188147. + spin_unlock_irqrestore(&ctr_lock, flags);
  188148. +
  188149. + return 0;
  188150. +}
  188151. +
  188152. +static s32 mlb150_dev_ctr_write(u32 ctr_offset, const u32 *ctr_val)
  188153. +{
  188154. + s32 timeout = 1000;
  188155. + unsigned long flags;
  188156. +
  188157. + spin_lock_irqsave(&ctr_lock, flags);
  188158. +
  188159. + __raw_writel(ctr_val[0], mlb_base + REG_MDAT0);
  188160. + __raw_writel(ctr_val[1], mlb_base + REG_MDAT1);
  188161. + __raw_writel(ctr_val[2], mlb_base + REG_MDAT2);
  188162. + __raw_writel(ctr_val[3], mlb_base + REG_MDAT3);
  188163. +
  188164. + __raw_writel(MADR_WNR | ctr_offset,
  188165. + mlb_base + REG_MADR);
  188166. +
  188167. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  188168. + & MCTL_XCMP)) &&
  188169. + timeout--)
  188170. + ;
  188171. +
  188172. + if (timeout <= 0) {
  188173. + spin_unlock_irqrestore(&ctr_lock, flags);
  188174. + pr_debug("mxc_mlb150: Write CTR timeout\n");
  188175. + return -ETIME;
  188176. + }
  188177. +
  188178. + __raw_writel(0, mlb_base + REG_MCTL);
  188179. +
  188180. + spin_unlock_irqrestore(&ctr_lock, flags);
  188181. +
  188182. +#ifdef DEBUG_CTR
  188183. + {
  188184. + u32 ctr_rd[4] = { 0 };
  188185. +
  188186. + if (!mlb150_dev_ctr_read(ctr_offset, ctr_rd)) {
  188187. + if (ctr_val[0] == ctr_rd[0] &&
  188188. + ctr_val[1] == ctr_rd[1] &&
  188189. + ctr_val[2] == ctr_rd[2] &&
  188190. + ctr_val[3] == ctr_rd[3])
  188191. + return 0;
  188192. + else {
  188193. + pr_debug("mxc_mlb150: ctr write failed\n");
  188194. + pr_debug("offset: 0x%x\n", ctr_offset);
  188195. + pr_debug("Write: 0x%x 0x%x 0x%x 0x%x\n",
  188196. + ctr_val[3], ctr_val[2],
  188197. + ctr_val[1], ctr_val[0]);
  188198. + pr_debug("Read: 0x%x 0x%x 0x%x 0x%x\n",
  188199. + ctr_rd[3], ctr_rd[2],
  188200. + ctr_rd[1], ctr_rd[0]);
  188201. + return -EBADE;
  188202. + }
  188203. + } else {
  188204. + pr_debug("mxc_mlb150: ctr read failed\n");
  188205. + return -EBADE;
  188206. + }
  188207. + }
  188208. +#endif
  188209. +
  188210. + return 0;
  188211. +}
  188212. +
  188213. +#ifdef DEBUG
  188214. +static s32 mlb150_dev_cat_read(u32 ctr_offset, u32 ch, u16 *cat_val)
  188215. +{
  188216. + u16 ctr_val[8] = { 0 };
  188217. +
  188218. + if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
  188219. + return -ETIME;
  188220. +
  188221. + /*
  188222. + * Use u16 array to get u32 array value,
  188223. + * need to convert
  188224. + */
  188225. + cat_val = ctr_val[ch % 8];
  188226. +
  188227. + return 0;
  188228. +}
  188229. +#endif
  188230. +
  188231. +static s32 mlb150_dev_cat_write(u32 ctr_offset, u32 ch, const u16 cat_val)
  188232. +{
  188233. + u16 ctr_val[8] = { 0 };
  188234. +
  188235. + if (mlb150_dev_ctr_read(ctr_offset, (u32 *)ctr_val))
  188236. + return -ETIME;
  188237. +
  188238. + ctr_val[ch % 8] = cat_val;
  188239. + if (mlb150_dev_ctr_write(ctr_offset, (u32 *)ctr_val))
  188240. + return -ETIME;
  188241. +
  188242. + return 0;
  188243. +}
  188244. +
  188245. +#define mlb150_dev_cat_mlb_read(ch, cat_val) \
  188246. + mlb150_dev_cat_read(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
  188247. +#define mlb150_dev_cat_mlb_write(ch, cat_val) \
  188248. + mlb150_dev_cat_write(BUF_CAT_MLB_OFFSET + (ch >> 3), ch, cat_val)
  188249. +#define mlb150_dev_cat_hbi_read(ch, cat_val) \
  188250. + mlb150_dev_cat_read(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
  188251. +#define mlb150_dev_cat_hbi_write(ch, cat_val) \
  188252. + mlb150_dev_cat_write(BUF_CAT_HBI_OFFSET + (ch >> 3), ch, cat_val)
  188253. +
  188254. +#define mlb150_dev_cdt_read(ch, cdt_val) \
  188255. + mlb150_dev_ctr_read(BUF_CDT_OFFSET + ch, cdt_val)
  188256. +#define mlb150_dev_cdt_write(ch, cdt_val) \
  188257. + mlb150_dev_ctr_write(BUF_CDT_OFFSET + ch, cdt_val)
  188258. +#define mlb150_dev_adt_read(ch, adt_val) \
  188259. + mlb150_dev_ctr_read(BUF_ADT_OFFSET + ch, adt_val)
  188260. +#define mlb150_dev_adt_write(ch, adt_val) \
  188261. + mlb150_dev_ctr_write(BUF_ADT_OFFSET + ch, adt_val)
  188262. +
  188263. +static s32 mlb150_dev_get_adt_sts(u32 ch)
  188264. +{
  188265. + s32 timeout = 1000;
  188266. + unsigned long flags;
  188267. + u32 reg;
  188268. +
  188269. + spin_lock_irqsave(&ctr_lock, flags);
  188270. + __raw_writel(BUF_ADT_OFFSET + ch,
  188271. + mlb_base + REG_MADR);
  188272. +
  188273. + while ((!(__raw_readl(mlb_base + REG_MCTL)
  188274. + & MCTL_XCMP)) &&
  188275. + timeout--)
  188276. + ;
  188277. +
  188278. + if (timeout <= 0) {
  188279. + spin_unlock_irqrestore(&ctr_lock, flags);
  188280. + pr_debug("mxc_mlb150: Read CTR timeout\n");
  188281. + return -ETIME;
  188282. + }
  188283. +
  188284. + reg = __raw_readl(mlb_base + REG_MDAT1);
  188285. +
  188286. + __raw_writel(0, mlb_base + REG_MCTL);
  188287. + spin_unlock_irqrestore(&ctr_lock, flags);
  188288. +
  188289. +#ifdef DEBUG_ADT
  188290. + pr_debug("mxc_mlb150: Get ch %d adt sts: 0x%08x\n", ch, reg);
  188291. +#endif
  188292. +
  188293. + return reg;
  188294. +}
  188295. +
  188296. +#ifdef DEBUG
  188297. +static void mlb150_dev_dump_ctr_tbl(u32 ch_start, u32 ch_end)
  188298. +{
  188299. + u32 i = 0;
  188300. + u32 ctr_val[4] = { 0 };
  188301. +
  188302. + pr_debug("mxc_mlb150: CDT Table");
  188303. + for (i = BUF_CDT_OFFSET + ch_start;
  188304. + i < BUF_CDT_OFFSET + ch_end;
  188305. + ++i) {
  188306. + mlb150_dev_ctr_read(i, ctr_val);
  188307. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  188308. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  188309. + }
  188310. +
  188311. + pr_debug("mxc_mlb150: ADT Table");
  188312. + for (i = BUF_ADT_OFFSET + ch_start;
  188313. + i < BUF_ADT_OFFSET + ch_end;
  188314. + ++i) {
  188315. + mlb150_dev_ctr_read(i, ctr_val);
  188316. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  188317. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  188318. + }
  188319. +
  188320. + pr_debug("mxc_mlb150: CAT MLB Table");
  188321. + for (i = BUF_CAT_MLB_OFFSET + (ch_start >> 3);
  188322. + i <= BUF_CAT_MLB_OFFSET + ((ch_end + 8) >> 3);
  188323. + ++i) {
  188324. + mlb150_dev_ctr_read(i, ctr_val);
  188325. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  188326. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  188327. + }
  188328. +
  188329. + pr_debug("mxc_mlb150: CAT HBI Table");
  188330. + for (i = BUF_CAT_HBI_OFFSET + (ch_start >> 3);
  188331. + i <= BUF_CAT_HBI_OFFSET + ((ch_end + 8) >> 3);
  188332. + ++i) {
  188333. + mlb150_dev_ctr_read(i, ctr_val);
  188334. + pr_debug("CTR 0x%02x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
  188335. + i, ctr_val[3], ctr_val[2], ctr_val[1], ctr_val[0]);
  188336. + }
  188337. +}
  188338. +#endif
  188339. +
  188340. +/*
  188341. + * Initial the MLB module device
  188342. + */
  188343. +static inline void mlb150_dev_enable_dma_irq(u32 enable)
  188344. +{
  188345. + u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
  188346. + | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
  188347. + | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
  188348. + | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
  188349. + u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188350. + (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188351. + (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188352. + (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188353. + (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  188354. + (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  188355. + (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  188356. + (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
  188357. +
  188358. + if (enable) {
  188359. + __raw_writel(ch_rx_mask, mlb_base + REG_ACMR0);
  188360. + __raw_writel(ch_tx_mask, mlb_base + REG_ACMR1);
  188361. + } else {
  188362. + __raw_writel(0x0, mlb_base + REG_ACMR0);
  188363. + __raw_writel(0x0, mlb_base + REG_ACMR1);
  188364. + }
  188365. +}
  188366. +
  188367. +
  188368. +static void mlb150_dev_init_ir_amba_ahb(void)
  188369. +{
  188370. + u32 reg = 0;
  188371. +
  188372. + /*
  188373. + * Step 1. Program the ACMRn registers to enable interrupts from all
  188374. + * active DMA channels
  188375. + */
  188376. + mlb150_dev_enable_dma_irq(1);
  188377. +
  188378. + /*
  188379. + * Step 2. Select the status clear method:
  188380. + * ACTL.SCE = 0, hardware clears on read
  188381. + * ACTL.SCE = 1, software writes a '1' to clear
  188382. + * We only support DMA MODE 1
  188383. + */
  188384. + reg = __raw_readl(mlb_base + REG_ACTL);
  188385. + reg |= ACTL_DMAMODE;
  188386. +#ifdef MULTIPLE_PACKAGE_MODE
  188387. + reg |= REG_ACTL_MPB;
  188388. +#endif
  188389. +
  188390. + /*
  188391. + * Step 3. Select 1 or 2 interrupt signals:
  188392. + * ACTL.SMX = 0: one interrupt for channels 0 - 31 on ahb_init[0]
  188393. + * and another interrupt for channels 32 - 63 on ahb_init[1]
  188394. + * ACTL.SMX = 1: singel interrupt all channels on ahb_init[0]
  188395. + */
  188396. + reg &= ~ACTL_SMX;
  188397. +
  188398. + __raw_writel(reg, mlb_base + REG_ACTL);
  188399. +}
  188400. +
  188401. +static inline void mlb150_dev_enable_ir_mlb(u32 enable)
  188402. +{
  188403. + /*
  188404. + * Step 1, Select the MSn to be cleared by software,
  188405. + * writing a '0' to the appropriate bits
  188406. + */
  188407. + __raw_writel(0, mlb_base + REG_MS0);
  188408. + __raw_writel(0, mlb_base + REG_MS1);
  188409. +
  188410. + /*
  188411. + * Step 1, Program MIEN to enable protocol error
  188412. + * interrupts for all active MLB channels
  188413. + */
  188414. + if (enable)
  188415. + __raw_writel(MIEN_CTX_PE |
  188416. + MIEN_CRX_PE | MIEN_ATX_PE |
  188417. + MIEN_ARX_PE | MIEN_SYNC_PE |
  188418. + MIEN_ISOC_PE,
  188419. + mlb_base + REG_MIEN);
  188420. + else
  188421. + __raw_writel(0, mlb_base + REG_MIEN);
  188422. +}
  188423. +
  188424. +static inline void mlb150_enable_pll(struct mlb_data *drvdata)
  188425. +{
  188426. + u32 c0_val;
  188427. +
  188428. + __raw_writel(MLBPC1_VAL,
  188429. + drvdata->membase + REG_MLBPC1);
  188430. +
  188431. + c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
  188432. + if (c0_val & MLBC0_MLBPEN) {
  188433. + c0_val &= ~MLBC0_MLBPEN;
  188434. + __raw_writel(c0_val,
  188435. + drvdata->membase + REG_MLBC0);
  188436. + }
  188437. +
  188438. + clk_prepare_enable(drvdata->clk_mlb6p);
  188439. +
  188440. + c0_val |= (MLBC0_MLBPEN);
  188441. + __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
  188442. +}
  188443. +
  188444. +static inline void mlb150_disable_pll(struct mlb_data *drvdata)
  188445. +{
  188446. + u32 c0_val;
  188447. +
  188448. + clk_disable_unprepare(drvdata->clk_mlb6p);
  188449. +
  188450. + c0_val = __raw_readl(drvdata->membase + REG_MLBC0);
  188451. +
  188452. + __raw_writel(0x0, drvdata->membase + REG_MLBPC1);
  188453. +
  188454. + c0_val &= ~MLBC0_MLBPEN;
  188455. + __raw_writel(c0_val, drvdata->membase + REG_MLBC0);
  188456. +}
  188457. +
  188458. +static void mlb150_dev_reset_cdt(void)
  188459. +{
  188460. + int i = 0;
  188461. + u32 ctr_val[4] = { 0 };
  188462. +
  188463. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  188464. + 0xffffffff, 0xffffffff);
  188465. +
  188466. + for (i = 0; i < (LOGIC_CH_NUM); ++i)
  188467. + mlb150_dev_ctr_write(BUF_CDT_OFFSET + i, ctr_val);
  188468. +}
  188469. +
  188470. +static s32 mlb150_dev_init_ch_cdt(struct mlb_dev_info *pdevinfo, u32 ch,
  188471. + enum MLB_CTYPE ctype, u32 ch_func)
  188472. +{
  188473. + u32 cdt_val[4] = { 0 };
  188474. +
  188475. + /* a. Set the 14-bit base address (BA) */
  188476. + pr_debug("mxc_mlb150: ctype: %d, ch: %d, dbr_buf_head: 0x%08x",
  188477. + ctype, ch, pdevinfo->channels[ch_func].dbr_buf_head);
  188478. + cdt_val[3] = (pdevinfo->channels[ch_func].dbr_buf_head)
  188479. + << CDT_BA_SHIFT;
  188480. + /*
  188481. + * b. Set the 12-bit or 13-bit buffer depth (BD)
  188482. + * BD = buffer depth in bytes - 1
  188483. + * For synchronous channels: (BD + 1) = 4 * m * bpf
  188484. + * For control channels: (BD + 1) >= max packet length (64)
  188485. + * For asynchronous channels: (BD + 1) >= max packet length
  188486. + * 1024 for a MOST Data packet (MDP);
  188487. + * 1536 for a MOST Ethernet Packet (MEP)
  188488. + * For isochronous channels: (BD + 1) mod (BS + 1) = 0
  188489. + * BS
  188490. + */
  188491. + if (MLB_CTYPE_ISOC == ctype)
  188492. + cdt_val[1] |= (pdevinfo->isoc_blksz - 1);
  188493. + /* BD */
  188494. + cdt_val[3] |= (pdevinfo->cdt_buf_dep - 1) << CDT_BD_SHIFT;
  188495. +
  188496. + pr_debug("mxc_mlb150: Set CDT val of channel %d, type: %d: "
  188497. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  188498. + ch, ctype, cdt_val[3], cdt_val[2], cdt_val[1], cdt_val[0]);
  188499. +
  188500. + if (mlb150_dev_cdt_write(ch, cdt_val))
  188501. + return -ETIME;
  188502. +
  188503. +#ifdef DEBUG_CTR
  188504. + {
  188505. + u32 cdt_rd[4] = { 0 };
  188506. + if (!mlb150_dev_cdt_read(ch, cdt_rd)) {
  188507. + pr_debug("mxc_mlb150: CDT val of channel %d: "
  188508. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  188509. + ch, cdt_rd[3], cdt_rd[2], cdt_rd[1], cdt_rd[0]);
  188510. + if (cdt_rd[3] == cdt_val[3] &&
  188511. + cdt_rd[2] == cdt_val[2] &&
  188512. + cdt_rd[1] == cdt_val[1] &&
  188513. + cdt_rd[0] == cdt_val[0]) {
  188514. + pr_debug("mxc_mlb150: set cdt succeed!\n");
  188515. + return 0;
  188516. + } else {
  188517. + pr_debug("mxc_mlb150: set cdt failed!\n");
  188518. + return -EBADE;
  188519. + }
  188520. + } else {
  188521. + pr_debug("mxc_mlb150: Read CDT val of channel %d failed\n",
  188522. + ch);
  188523. + return -EBADE;
  188524. + }
  188525. + }
  188526. +#endif
  188527. +
  188528. + return 0;
  188529. +}
  188530. +
  188531. +static s32 mlb150_dev_init_ch_cat(u32 ch, u32 cl,
  188532. + u32 cat_mode, enum MLB_CTYPE ctype)
  188533. +{
  188534. + u16 cat_val = 0;
  188535. +#ifdef DEBUG_CTR
  188536. + u16 cat_rd = 0;
  188537. +#endif
  188538. +
  188539. + cat_val = CAT_CE | (ctype << CAT_CT_SHIFT) | cl;
  188540. +
  188541. + if (cat_mode & CAT_MODE_OUTBOUND_DMA)
  188542. + cat_val |= CAT_RNW;
  188543. +
  188544. + if (MLB_CTYPE_SYNC == ctype)
  188545. + cat_val |= CAT_MT;
  188546. +
  188547. + switch (cat_mode) {
  188548. + case CAT_MODE_RX | CAT_MODE_INBOUND_DMA:
  188549. + case CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA:
  188550. + pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
  188551. + ch, ctype, cat_val);
  188552. +
  188553. + if (mlb150_dev_cat_mlb_write(ch, cat_val))
  188554. + return -ETIME;
  188555. +#ifdef DEBUG_CTR
  188556. + if (!mlb150_dev_cat_mlb_read(ch, &cat_rd))
  188557. + pr_debug("mxc_mlb150: CAT val of mlb channel %d: 0x%04x",
  188558. + ch, cat_rd);
  188559. + else {
  188560. + pr_debug("mxc_mlb150: Read CAT of mlb channel %d failed\n",
  188561. + ch);
  188562. + return -EBADE;
  188563. + }
  188564. +#endif
  188565. + break;
  188566. + case CAT_MODE_TX | CAT_MODE_INBOUND_DMA:
  188567. + case CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA:
  188568. + pr_debug("mxc_mlb150: set CAT val of channel %d, type: %d: 0x%04x\n",
  188569. + cl, ctype, cat_val);
  188570. +
  188571. + if (mlb150_dev_cat_hbi_write(cl, cat_val))
  188572. + return -ETIME;
  188573. +#ifdef DEBUG_CTR
  188574. + if (!mlb150_dev_cat_hbi_read(cl, &cat_rd))
  188575. + pr_debug("mxc_mlb150: CAT val of hbi channel %d: 0x%04x",
  188576. + cl, cat_rd);
  188577. + else {
  188578. + pr_debug("mxc_mlb150: Read CAT of hbi channel %d failed\n",
  188579. + cl);
  188580. + return -EBADE;
  188581. + }
  188582. +#endif
  188583. + break;
  188584. + default:
  188585. + return EBADRQC;
  188586. + }
  188587. +
  188588. +#ifdef DEBUG_CTR
  188589. + {
  188590. + if (cat_val == cat_rd) {
  188591. + pr_debug("mxc_mlb150: set cat succeed!\n");
  188592. + return 0;
  188593. + } else {
  188594. + pr_debug("mxc_mlb150: set cat failed!\n");
  188595. + return -EBADE;
  188596. + }
  188597. + }
  188598. +#endif
  188599. + return 0;
  188600. +}
  188601. +
  188602. +static void mlb150_dev_reset_cat(void)
  188603. +{
  188604. + int i = 0;
  188605. + u32 ctr_val[4] = { 0 };
  188606. +
  188607. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  188608. + 0xffffffff, 0xffffffff);
  188609. +
  188610. + for (i = 0; i < (LOGIC_CH_NUM >> 3); ++i) {
  188611. + mlb150_dev_ctr_write(BUF_CAT_MLB_OFFSET + i, ctr_val);
  188612. + mlb150_dev_ctr_write(BUF_CAT_HBI_OFFSET + i, ctr_val);
  188613. + }
  188614. +}
  188615. +
  188616. +static void mlb150_dev_init_rfb(struct mlb_dev_info *pdevinfo, u32 rx_ch,
  188617. + u32 tx_ch, enum MLB_CTYPE ctype)
  188618. +{
  188619. + u32 rx_cl = pdevinfo->channels[RX_CHANNEL].cl;
  188620. + u32 tx_cl = pdevinfo->channels[TX_CHANNEL].cl;
  188621. + /* Step 1, Initialize all bits of CAT to '0' */
  188622. + mlb150_dev_reset_cat();
  188623. + mlb150_dev_reset_cdt();
  188624. + /*
  188625. + * Step 2, Initialize logical channel
  188626. + * Step 3, Program the CDT for channel N
  188627. + */
  188628. + mlb150_dev_init_ch_cdt(pdevinfo, rx_cl, ctype, RX_CHANNEL);
  188629. + mlb150_dev_init_ch_cdt(pdevinfo, tx_cl, ctype, TX_CHANNEL);
  188630. +
  188631. + /* Step 4&5, Program the CAT for the inbound and outbound DMA */
  188632. + mlb150_dev_init_ch_cat(rx_ch, rx_cl,
  188633. + CAT_MODE_RX | CAT_MODE_INBOUND_DMA,
  188634. + ctype);
  188635. + mlb150_dev_init_ch_cat(rx_ch, rx_cl,
  188636. + CAT_MODE_RX | CAT_MODE_OUTBOUND_DMA,
  188637. + ctype);
  188638. + mlb150_dev_init_ch_cat(tx_ch, tx_cl,
  188639. + CAT_MODE_TX | CAT_MODE_INBOUND_DMA,
  188640. + ctype);
  188641. + mlb150_dev_init_ch_cat(tx_ch, tx_cl,
  188642. + CAT_MODE_TX | CAT_MODE_OUTBOUND_DMA,
  188643. + ctype);
  188644. +}
  188645. +
  188646. +static void mlb150_dev_reset_adt(void)
  188647. +{
  188648. + int i = 0;
  188649. + u32 ctr_val[4] = { 0 };
  188650. +
  188651. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  188652. + 0xffffffff, 0xffffffff);
  188653. +
  188654. + for (i = 0; i < (LOGIC_CH_NUM); ++i)
  188655. + mlb150_dev_ctr_write(BUF_ADT_OFFSET + i, ctr_val);
  188656. +}
  188657. +
  188658. +static void mlb150_dev_reset_whole_ctr(void)
  188659. +{
  188660. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  188661. + 0xffffffff, 0xffffffff);
  188662. + mlb150_dev_reset_cdt();
  188663. + mlb150_dev_reset_adt();
  188664. + mlb150_dev_reset_cat();
  188665. +}
  188666. +
  188667. +#define CLR_REG(reg) __raw_writel(0x0, mlb_base + reg)
  188668. +
  188669. +static void mlb150_dev_reset_all_regs(void)
  188670. +{
  188671. + CLR_REG(REG_MLBC0);
  188672. + CLR_REG(REG_MLBPC0);
  188673. + CLR_REG(REG_MS0);
  188674. + CLR_REG(REG_MS1);
  188675. + CLR_REG(REG_MSS);
  188676. + CLR_REG(REG_MSD);
  188677. + CLR_REG(REG_MIEN);
  188678. + CLR_REG(REG_MLBPC2);
  188679. + CLR_REG(REG_MLBPC1);
  188680. + CLR_REG(REG_MLBC1);
  188681. + CLR_REG(REG_HCTL);
  188682. + CLR_REG(REG_HCMR0);
  188683. + CLR_REG(REG_HCMR1);
  188684. + CLR_REG(REG_HCER0);
  188685. + CLR_REG(REG_HCER1);
  188686. + CLR_REG(REG_HCBR0);
  188687. + CLR_REG(REG_HCBR1);
  188688. + CLR_REG(REG_MDAT0);
  188689. + CLR_REG(REG_MDAT1);
  188690. + CLR_REG(REG_MDAT2);
  188691. + CLR_REG(REG_MDAT3);
  188692. + CLR_REG(REG_MDWE0);
  188693. + CLR_REG(REG_MDWE1);
  188694. + CLR_REG(REG_MDWE2);
  188695. + CLR_REG(REG_MDWE3);
  188696. + CLR_REG(REG_MCTL);
  188697. + CLR_REG(REG_MADR);
  188698. + CLR_REG(REG_ACTL);
  188699. + CLR_REG(REG_ACSR0);
  188700. + CLR_REG(REG_ACSR1);
  188701. + CLR_REG(REG_ACMR0);
  188702. + CLR_REG(REG_ACMR1);
  188703. +}
  188704. +
  188705. +static inline s32 mlb150_dev_pipo_start(struct mlb_ringbuf *rbuf,
  188706. + u32 ahb_ch, u32 buf_addr)
  188707. +{
  188708. + u32 ctr_val[4] = { 0 };
  188709. +
  188710. + ctr_val[1] |= ADT_RDY1;
  188711. + ctr_val[2] = buf_addr;
  188712. +
  188713. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  188714. + return -ETIME;
  188715. +
  188716. + return 0;
  188717. +}
  188718. +
  188719. +static inline s32 mlb150_dev_pipo_next(u32 ahb_ch, enum MLB_CTYPE ctype,
  188720. + u32 dne_sts, u32 buf_addr)
  188721. +{
  188722. + u32 ctr_val[4] = { 0 };
  188723. +
  188724. + if (MLB_CTYPE_ASYNC == ctype ||
  188725. + MLB_CTYPE_CTRL == ctype) {
  188726. + ctr_val[1] |= ADT_PS1;
  188727. + ctr_val[1] |= ADT_PS2;
  188728. + }
  188729. +
  188730. + /*
  188731. + * Clear DNE1 and ERR1
  188732. + * Set the page ready bit (RDY1)
  188733. + */
  188734. + if (dne_sts & ADT_DNE1) {
  188735. + ctr_val[1] |= ADT_RDY2;
  188736. + ctr_val[3] = buf_addr;
  188737. + } else {
  188738. + ctr_val[1] |= ADT_RDY1;
  188739. + ctr_val[2] = buf_addr;
  188740. + }
  188741. +
  188742. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  188743. + return -ETIME;
  188744. +
  188745. + return 0;
  188746. +}
  188747. +
  188748. +static inline s32 mlb150_dev_pipo_stop(struct mlb_ringbuf *rbuf, u32 ahb_ch)
  188749. +{
  188750. + u32 ctr_val[4] = { 0 };
  188751. + unsigned long flags;
  188752. +
  188753. + write_lock_irqsave(&rbuf->rb_lock, flags);
  188754. + rbuf->head = rbuf->tail = 0;
  188755. + write_unlock_irqrestore(&rbuf->rb_lock, flags);
  188756. +
  188757. + if (mlb150_dev_adt_write(ahb_ch, ctr_val))
  188758. + return -ETIME;
  188759. +
  188760. + return 0;
  188761. +}
  188762. +
  188763. +static s32 mlb150_dev_init_ch_amba_ahb(struct mlb_dev_info *pdevinfo,
  188764. + struct mlb_channel_info *chinfo,
  188765. + enum MLB_CTYPE ctype)
  188766. +{
  188767. + u32 ctr_val[4] = { 0 };
  188768. +
  188769. + /* a. Set the 32-bit base address (BA1) */
  188770. + ctr_val[3] = 0;
  188771. + ctr_val[2] = 0;
  188772. + ctr_val[1] = (pdevinfo->adt_buf_dep - 1) << ADT_BD1_SHIFT;
  188773. + ctr_val[1] |= (pdevinfo->adt_buf_dep - 1) << ADT_BD2_SHIFT;
  188774. + if (MLB_CTYPE_ASYNC == ctype ||
  188775. + MLB_CTYPE_CTRL == ctype) {
  188776. + ctr_val[1] |= ADT_PS1;
  188777. + ctr_val[1] |= ADT_PS2;
  188778. + }
  188779. +
  188780. + ctr_val[0] |= (ADT_LE | ADT_CE);
  188781. +
  188782. + pr_debug("mxc_mlb150: Set ADT val of channel %d, ctype: %d: "
  188783. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  188784. + chinfo->cl, ctype, ctr_val[3], ctr_val[2],
  188785. + ctr_val[1], ctr_val[0]);
  188786. +
  188787. + if (mlb150_dev_adt_write(chinfo->cl, ctr_val))
  188788. + return -ETIME;
  188789. +
  188790. +#ifdef DEBUG_CTR
  188791. + {
  188792. + u32 ctr_rd[4] = { 0 };
  188793. + if (!mlb150_dev_adt_read(chinfo->cl, ctr_rd)) {
  188794. + pr_debug("mxc_mlb150: ADT val of channel %d: "
  188795. + "0x%08x 0x%08x 0x%08x 0x%08x\n",
  188796. + chinfo->cl, ctr_rd[3], ctr_rd[2],
  188797. + ctr_rd[1], ctr_rd[0]);
  188798. + if (ctr_rd[3] == ctr_val[3] &&
  188799. + ctr_rd[2] == ctr_val[2] &&
  188800. + ctr_rd[1] == ctr_val[1] &&
  188801. + ctr_rd[0] == ctr_val[0]) {
  188802. + pr_debug("mxc_mlb150: set adt succeed!\n");
  188803. + return 0;
  188804. + } else {
  188805. + pr_debug("mxc_mlb150: set adt failed!\n");
  188806. + return -EBADE;
  188807. + }
  188808. + } else {
  188809. + pr_debug("mxc_mlb150: Read ADT val of channel %d failed\n",
  188810. + chinfo->cl);
  188811. + return -EBADE;
  188812. + }
  188813. + }
  188814. +#endif
  188815. +
  188816. + return 0;
  188817. +}
  188818. +
  188819. +static void mlb150_dev_init_amba_ahb(struct mlb_dev_info *pdevinfo,
  188820. + enum MLB_CTYPE ctype)
  188821. +{
  188822. + struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
  188823. + struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
  188824. +
  188825. + /* Step 1, Initialize all bits of the ADT to '0' */
  188826. + mlb150_dev_reset_adt();
  188827. +
  188828. + /*
  188829. + * Step 2, Select a logic channel
  188830. + * Step 3, Program the AMBA AHB block ping page for channel N
  188831. + * Step 4, Program the AMBA AHB block pong page for channel N
  188832. + */
  188833. + mlb150_dev_init_ch_amba_ahb(pdevinfo, rx_chinfo, ctype);
  188834. + mlb150_dev_init_ch_amba_ahb(pdevinfo, tx_chinfo, ctype);
  188835. +}
  188836. +
  188837. +static void mlb150_dev_exit(void)
  188838. +{
  188839. + u32 c0_val, hctl_val;
  188840. +
  188841. + /* Disable EN bits */
  188842. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  188843. + c0_val &= ~(MLBC0_MLBEN | MLBC0_MLBPEN);
  188844. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  188845. +
  188846. + hctl_val = __raw_readl(mlb_base + REG_HCTL);
  188847. + hctl_val &= ~HCTL_EN;
  188848. + __raw_writel(hctl_val, mlb_base + REG_HCTL);
  188849. +
  188850. + __raw_writel(0x0, mlb_base + REG_HCMR0);
  188851. + __raw_writel(0x0, mlb_base + REG_HCMR1);
  188852. +
  188853. + mlb150_dev_enable_dma_irq(0);
  188854. + mlb150_dev_enable_ir_mlb(0);
  188855. +}
  188856. +
  188857. +static void mlb150_dev_init(void)
  188858. +{
  188859. + u32 c0_val;
  188860. + u32 ch_rx_mask = (1 << SYNC_RX_CL_AHB0) | (1 << CTRL_RX_CL_AHB0)
  188861. + | (1 << ASYNC_RX_CL_AHB0) | (1 << ISOC_RX_CL_AHB0)
  188862. + | (1 << SYNC_TX_CL_AHB0) | (1 << CTRL_TX_CL_AHB0)
  188863. + | (1 << ASYNC_TX_CL_AHB0) | (1 << ISOC_TX_CL_AHB0);
  188864. + u32 ch_tx_mask = (1 << (SYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188865. + (1 << (CTRL_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188866. + (1 << (ASYNC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188867. + (1 << (ISOC_RX_CL_AHB1 - INT_AHB1_CH_START)) |
  188868. + (1 << (SYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  188869. + (1 << (CTRL_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  188870. + (1 << (ASYNC_TX_CL_AHB1 - INT_AHB1_CH_START)) |
  188871. + (1 << (ISOC_TX_CL_AHB1 - INT_AHB1_CH_START));
  188872. +
  188873. + /* Disable EN bits */
  188874. + mlb150_dev_exit();
  188875. +
  188876. + /*
  188877. + * Step 1. Initialize CTR and registers
  188878. + * a. Set all bit of the CTR (CAT, CDT, and ADT) to 0.
  188879. + */
  188880. + mlb150_dev_reset_whole_ctr();
  188881. +
  188882. + /* a. Set all bit of the CTR (CAT, CDT, and ADT) to 0. */
  188883. + mlb150_dev_reset_all_regs();
  188884. +
  188885. + /*
  188886. + * Step 2, Configure the MediaLB interface
  188887. + * Select pin mode and clock, 3-pin and 256fs
  188888. + */
  188889. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  188890. + c0_val &= ~(MLBC0_MLBPEN | MLBC0_MLBCLK_MASK);
  188891. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  188892. +
  188893. + c0_val |= MLBC0_MLBEN;
  188894. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  188895. +
  188896. + /* Step 3, Configure the HBI interface */
  188897. + __raw_writel(ch_rx_mask, mlb_base + REG_HCMR0);
  188898. + __raw_writel(ch_tx_mask, mlb_base + REG_HCMR1);
  188899. + __raw_writel(HCTL_EN, mlb_base + REG_HCTL);
  188900. +
  188901. + mlb150_dev_init_ir_amba_ahb();
  188902. +
  188903. + mlb150_dev_enable_ir_mlb(1);
  188904. +}
  188905. +
  188906. +static s32 mlb150_dev_unmute_syn_ch(u32 rx_ch, u32 rx_cl, u32 tx_ch, u32 tx_cl)
  188907. +{
  188908. + u32 timeout = 10000;
  188909. +
  188910. + /*
  188911. + * Check that MediaLB clock is running (MLBC1.CLKM = 0)
  188912. + * If MLBC1.CLKM = 1, clear the register bit, wait one
  188913. + * APB or I/O clock cycle and repeat the check
  188914. + */
  188915. + while ((__raw_readl(mlb_base + REG_MLBC1) & MLBC1_CLKM)
  188916. + && --timeout)
  188917. + __raw_writel(~MLBC1_CLKM, mlb_base + REG_MLBC1);
  188918. +
  188919. + if (0 == timeout)
  188920. + return -ETIME;
  188921. +
  188922. + timeout = 10000;
  188923. + /* Poll for MLB lock (MLBC0.MLBLK = 1) */
  188924. + while (!(__raw_readl(mlb_base + REG_MLBC0) & MLBC0_MLBLK)
  188925. + && --timeout)
  188926. + ;
  188927. +
  188928. + if (0 == timeout)
  188929. + return -ETIME;
  188930. +
  188931. + /* Unmute synchronous channel(s) */
  188932. + mlb150_dev_cat_mlb_write(rx_ch, CAT_CE | rx_cl);
  188933. + mlb150_dev_cat_mlb_write(tx_ch,
  188934. + CAT_CE | tx_cl | CAT_RNW);
  188935. + mlb150_dev_cat_hbi_write(rx_cl,
  188936. + CAT_CE | rx_cl | CAT_RNW);
  188937. + mlb150_dev_cat_hbi_write(tx_cl, CAT_CE | tx_cl);
  188938. +
  188939. + return 0;
  188940. +}
  188941. +
  188942. +/* In case the user calls channel shutdown, but rx or tx is not completed yet */
  188943. +static s32 mlb150_trans_complete_check(struct mlb_dev_info *pdevinfo)
  188944. +{
  188945. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  188946. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  188947. + s32 timeout = 1024;
  188948. +
  188949. + while (timeout--) {
  188950. + read_lock(&tx_rbuf->rb_lock);
  188951. + if (!CIRC_CNT(tx_rbuf->head, tx_rbuf->tail, TRANS_RING_NODES)) {
  188952. + read_unlock(&tx_rbuf->rb_lock);
  188953. + break;
  188954. + } else
  188955. + read_unlock(&tx_rbuf->rb_lock);
  188956. + }
  188957. +
  188958. + if (timeout <= 0) {
  188959. + pr_debug("TX complete check timeout!\n");
  188960. + return -ETIME;
  188961. + }
  188962. +
  188963. + timeout = 1024;
  188964. + while (timeout--) {
  188965. + read_lock(&rx_rbuf->rb_lock);
  188966. + if (!CIRC_CNT(rx_rbuf->head, rx_rbuf->tail, TRANS_RING_NODES)) {
  188967. + read_unlock(&rx_rbuf->rb_lock);
  188968. + break;
  188969. + } else
  188970. + read_unlock(&rx_rbuf->rb_lock);
  188971. + }
  188972. +
  188973. + if (timeout <= 0) {
  188974. + pr_debug("RX complete check timeout!\n");
  188975. + return -ETIME;
  188976. + }
  188977. +
  188978. + /*
  188979. + * Interrupt from TX can only inform that the data is sent
  188980. + * to AHB bus, not mean that it is sent to MITB. Thus we add
  188981. + * a delay here for data to be completed sent.
  188982. + */
  188983. + udelay(1000);
  188984. +
  188985. + return 0;
  188986. +}
  188987. +
  188988. +/*
  188989. + * Enable/Disable the MLB IRQ
  188990. + */
  188991. +static void mxc_mlb150_irq_enable(struct mlb_data *drvdata, u8 enable)
  188992. +{
  188993. + if (enable) {
  188994. + enable_irq(drvdata->irq_ahb0);
  188995. + enable_irq(drvdata->irq_ahb1);
  188996. + enable_irq(drvdata->irq_mlb);
  188997. + } else {
  188998. + disable_irq(drvdata->irq_ahb0);
  188999. + disable_irq(drvdata->irq_ahb1);
  189000. + disable_irq(drvdata->irq_mlb);
  189001. + }
  189002. +}
  189003. +
  189004. +/*
  189005. + * Enable the MLB channel
  189006. + */
  189007. +static s32 mlb_channel_enable(struct mlb_data *drvdata,
  189008. + int chan_dev_id, int on)
  189009. +{
  189010. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  189011. + struct mlb_channel_info *tx_chinfo = &pdevinfo->channels[TX_CHANNEL];
  189012. + struct mlb_channel_info *rx_chinfo = &pdevinfo->channels[RX_CHANNEL];
  189013. + u32 tx_ch = tx_chinfo->address;
  189014. + u32 rx_ch = rx_chinfo->address;
  189015. + u32 tx_cl = tx_chinfo->cl;
  189016. + u32 rx_cl = rx_chinfo->cl;
  189017. + s32 ret = 0;
  189018. +
  189019. + /*
  189020. + * setup the direction, enable, channel type,
  189021. + * mode select, channel address and mask buf start
  189022. + */
  189023. + if (on) {
  189024. + u32 ctype = pdevinfo->channel_type;
  189025. +
  189026. + mlb150_dev_enable_ctr_write(0xffffffff, 0xffffffff,
  189027. + 0xffffffff, 0xffffffff);
  189028. + mlb150_dev_init_rfb(pdevinfo, rx_ch, tx_ch, ctype);
  189029. +
  189030. + mlb150_dev_init_amba_ahb(pdevinfo, ctype);
  189031. +
  189032. +#ifdef DEBUG
  189033. + mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
  189034. +#endif
  189035. + /* Synchronize and unmute synchrouous channel */
  189036. + if (MLB_CTYPE_SYNC == ctype) {
  189037. + ret = mlb150_dev_unmute_syn_ch(rx_ch, rx_cl,
  189038. + tx_ch, tx_cl);
  189039. + if (ret)
  189040. + return ret;
  189041. + }
  189042. +
  189043. + mlb150_dev_enable_ctr_write(0x0, ADT_RDY1 | ADT_DNE1 |
  189044. + ADT_ERR1 | ADT_PS1 |
  189045. + ADT_RDY2 | ADT_DNE2 | ADT_ERR2 | ADT_PS2,
  189046. + 0xffffffff, 0xffffffff);
  189047. +
  189048. + if (pdevinfo->fps >= CLK_2048FS)
  189049. + mlb150_enable_pll(drvdata);
  189050. +
  189051. + atomic_set(&pdevinfo->on, 1);
  189052. +
  189053. +#ifdef DEBUG
  189054. + mlb150_dev_dump_reg();
  189055. + mlb150_dev_dump_ctr_tbl(0, tx_chinfo->cl + 1);
  189056. +#endif
  189057. + /* Init RX ADT */
  189058. + mlb150_dev_pipo_start(&pdevinfo->rx_rbuf, rx_cl,
  189059. + pdevinfo->rx_rbuf.phy_addrs[0]);
  189060. + } else {
  189061. + mlb150_dev_pipo_stop(&pdevinfo->rx_rbuf, rx_cl);
  189062. +
  189063. + mlb150_dev_enable_dma_irq(0);
  189064. + mlb150_dev_enable_ir_mlb(0);
  189065. +
  189066. + mlb150_dev_reset_cat();
  189067. +
  189068. + atomic_set(&pdevinfo->on, 0);
  189069. +
  189070. + if (pdevinfo->fps >= CLK_2048FS)
  189071. + mlb150_disable_pll(drvdata);
  189072. + }
  189073. +
  189074. + return 0;
  189075. +}
  189076. +
  189077. +/*
  189078. + * MLB interrupt handler
  189079. + */
  189080. +static void mlb_rx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
  189081. +{
  189082. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  189083. + s32 head, tail, adt_sts;
  189084. + u32 rx_buf_ptr;
  189085. +
  189086. +#ifdef DEBUG_RX
  189087. + pr_debug("mxc_mlb150: mlb_rx_isr\n");
  189088. +#endif
  189089. +
  189090. + read_lock(&rx_rbuf->rb_lock);
  189091. +
  189092. + head = (rx_rbuf->head + 1) & (TRANS_RING_NODES - 1);
  189093. + tail = ACCESS_ONCE(rx_rbuf->tail);
  189094. + read_unlock(&rx_rbuf->rb_lock);
  189095. +
  189096. + if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1) {
  189097. + rx_buf_ptr = rx_rbuf->phy_addrs[head];
  189098. +
  189099. + /* commit the item before incrementing the head */
  189100. + smp_wmb();
  189101. +
  189102. + write_lock(&rx_rbuf->rb_lock);
  189103. + rx_rbuf->head = head;
  189104. + write_unlock(&rx_rbuf->rb_lock);
  189105. +
  189106. + /* wake up the reader */
  189107. + wake_up_interruptible(&pdevinfo->rx_wq);
  189108. + } else {
  189109. + rx_buf_ptr = rx_rbuf->phy_addrs[head];
  189110. + pr_debug("drop RX package, due to no space, (%d,%d)\n",
  189111. + head, tail);
  189112. + }
  189113. +
  189114. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  189115. + /* Set ADT for RX */
  189116. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, rx_buf_ptr);
  189117. +}
  189118. +
  189119. +static void mlb_tx_isr(s32 ctype, u32 ahb_ch, struct mlb_dev_info *pdevinfo)
  189120. +{
  189121. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  189122. + s32 head, tail, adt_sts;
  189123. + u32 tx_buf_ptr;
  189124. +
  189125. + read_lock(&tx_rbuf->rb_lock);
  189126. +
  189127. + head = ACCESS_ONCE(tx_rbuf->head);
  189128. + tail = (tx_rbuf->tail + 1) & (TRANS_RING_NODES - 1);
  189129. + read_unlock(&tx_rbuf->rb_lock);
  189130. +
  189131. + smp_mb();
  189132. + write_lock(&tx_rbuf->rb_lock);
  189133. + tx_rbuf->tail = tail;
  189134. + write_unlock(&tx_rbuf->rb_lock);
  189135. +
  189136. + /* check the current tx buffer is available or not */
  189137. + if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1) {
  189138. + /* read index before reading contents at that index */
  189139. + smp_read_barrier_depends();
  189140. +
  189141. + tx_buf_ptr = tx_rbuf->phy_addrs[tail];
  189142. +
  189143. + wake_up_interruptible(&pdevinfo->tx_wq);
  189144. +
  189145. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  189146. + /* Set ADT for TX */
  189147. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
  189148. + }
  189149. +}
  189150. +
  189151. +static irqreturn_t mlb_ahb_isr(int irq, void *dev_id)
  189152. +{
  189153. + u32 acsr0, hcer0;
  189154. + u32 ch_mask = (1 << SYNC_RX_CL) | (1 << CTRL_RX_CL)
  189155. + | (1 << ASYNC_RX_CL) | (1 << ISOC_RX_CL)
  189156. + | (1 << SYNC_TX_CL) | (1 << CTRL_TX_CL)
  189157. + | (1 << ASYNC_TX_CL) | (1 << ISOC_TX_CL);
  189158. +
  189159. + /*
  189160. + * Step 5, Read the ACSRn registers to determine which channel or
  189161. + * channels are causing the interrupt
  189162. + */
  189163. + acsr0 = __raw_readl(mlb_base + REG_ACSR0);
  189164. +
  189165. + hcer0 = __raw_readl(mlb_base + REG_HCER0);
  189166. +
  189167. + /*
  189168. + * Step 6, If ACTL.SCE = 1, write the result of step 5 back to ACSR0
  189169. + * and ACSR1 to clear the interrupt
  189170. + * We'll not set ACTL_SCE
  189171. + */
  189172. +
  189173. + if (ch_mask & hcer0)
  189174. + pr_err("CH encounters an AHB error: 0x%x\n", hcer0);
  189175. +
  189176. + if ((1 << SYNC_RX_CL) & acsr0)
  189177. + mlb_rx_isr(MLB_CTYPE_SYNC, SYNC_RX_CL,
  189178. + &mlb_devinfo[MLB_CTYPE_SYNC]);
  189179. +
  189180. + if ((1 << CTRL_RX_CL) & acsr0)
  189181. + mlb_rx_isr(MLB_CTYPE_CTRL, CTRL_RX_CL,
  189182. + &mlb_devinfo[MLB_CTYPE_CTRL]);
  189183. +
  189184. + if ((1 << ASYNC_RX_CL) & acsr0)
  189185. + mlb_rx_isr(MLB_CTYPE_ASYNC, ASYNC_RX_CL,
  189186. + &mlb_devinfo[MLB_CTYPE_ASYNC]);
  189187. +
  189188. + if ((1 << ISOC_RX_CL) & acsr0)
  189189. + mlb_rx_isr(MLB_CTYPE_ISOC, ISOC_RX_CL,
  189190. + &mlb_devinfo[MLB_CTYPE_ISOC]);
  189191. +
  189192. + if ((1 << SYNC_TX_CL) & acsr0)
  189193. + mlb_tx_isr(MLB_CTYPE_SYNC, SYNC_TX_CL,
  189194. + &mlb_devinfo[MLB_CTYPE_SYNC]);
  189195. +
  189196. + if ((1 << CTRL_TX_CL) & acsr0)
  189197. + mlb_tx_isr(MLB_CTYPE_CTRL, CTRL_TX_CL,
  189198. + &mlb_devinfo[MLB_CTYPE_CTRL]);
  189199. +
  189200. + if ((1 << ASYNC_TX_CL) & acsr0)
  189201. + mlb_tx_isr(MLB_CTYPE_ASYNC, ASYNC_TX_CL,
  189202. + &mlb_devinfo[MLB_CTYPE_ASYNC]);
  189203. +
  189204. + if ((1 << ISOC_TX_CL) & acsr0)
  189205. + mlb_tx_isr(MLB_CTYPE_ASYNC, ISOC_TX_CL,
  189206. + &mlb_devinfo[MLB_CTYPE_ISOC]);
  189207. +
  189208. + return IRQ_HANDLED;
  189209. +}
  189210. +
  189211. +static irqreturn_t mlb_isr(int irq, void *dev_id)
  189212. +{
  189213. + u32 rx_int_sts, tx_int_sts, ms0,
  189214. + ms1, tx_cis, rx_cis, ctype;
  189215. + int minor;
  189216. + u32 cdt_val[4] = { 0 };
  189217. +
  189218. + /*
  189219. + * Step 4, Read the MSn register to determine which channel(s)
  189220. + * are causing the interrupt
  189221. + */
  189222. + ms0 = __raw_readl(mlb_base + REG_MS0);
  189223. + ms1 = __raw_readl(mlb_base + REG_MS1);
  189224. +
  189225. + /*
  189226. + * The MLB150_MS0, MLB150_MS1 registers need to be cleared. In
  189227. + * the spec description, the registers should be cleared when
  189228. + * enabling interrupt. In fact, we also should clear it in ISR.
  189229. + */
  189230. + __raw_writel(0, mlb_base + REG_MS0);
  189231. + __raw_writel(0, mlb_base + REG_MS1);
  189232. +
  189233. + pr_debug("mxc_mlb150: mlb interrupt:0x%08x 0x%08x\n",
  189234. + (u32)ms0, (u32)ms1);
  189235. +
  189236. + for (minor = 0; minor < MLB_MINOR_DEVICES; minor++) {
  189237. + struct mlb_dev_info *pdevinfo = &mlb_devinfo[minor];
  189238. + u32 rx_mlb_ch = pdevinfo->channels[RX_CHANNEL].address;
  189239. + u32 tx_mlb_ch = pdevinfo->channels[TX_CHANNEL].address;
  189240. + u32 rx_mlb_cl = pdevinfo->channels[RX_CHANNEL].cl;
  189241. + u32 tx_mlb_cl = pdevinfo->channels[TX_CHANNEL].cl;
  189242. +
  189243. + tx_cis = rx_cis = 0;
  189244. +
  189245. + ctype = pdevinfo->channel_type;
  189246. + rx_int_sts = (rx_mlb_ch < 31) ? ms0 : ms1;
  189247. + tx_int_sts = (tx_mlb_ch < 31) ? ms0 : ms1;
  189248. +
  189249. + pr_debug("mxc_mlb150: channel interrupt: "
  189250. + "tx %d: 0x%08x, rx %d: 0x%08x\n",
  189251. + tx_mlb_ch, (u32)tx_int_sts, rx_mlb_ch, (u32)rx_int_sts);
  189252. +
  189253. + /* Get tx channel interrupt status */
  189254. + if (tx_int_sts & (1 << (tx_mlb_ch % 32))) {
  189255. + mlb150_dev_cdt_read(tx_mlb_cl, cdt_val);
  189256. + pr_debug("mxc_mlb150: TX_CH: %d, cdt_val[3]: 0x%08x, "
  189257. + "cdt_val[2]: 0x%08x, "
  189258. + "cdt_val[1]: 0x%08x, "
  189259. + "cdt_val[0]: 0x%08x\n",
  189260. + tx_mlb_ch, cdt_val[3], cdt_val[2],
  189261. + cdt_val[1], cdt_val[0]);
  189262. + switch (ctype) {
  189263. + case MLB_CTYPE_SYNC:
  189264. + tx_cis = (cdt_val[2] & ~CDT_SYNC_WSTS_MASK)
  189265. + >> CDT_SYNC_WSTS_SHIFT;
  189266. + /*
  189267. + * Clear RSTS/WSTS errors to resume
  189268. + * channel operation
  189269. + * a. For synchronous channels: WSTS[3] = 0
  189270. + */
  189271. + cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
  189272. + break;
  189273. + case MLB_CTYPE_CTRL:
  189274. + case MLB_CTYPE_ASYNC:
  189275. + tx_cis = (cdt_val[2] &
  189276. + ~CDT_CTRL_ASYNC_WSTS_MASK)
  189277. + >> CDT_CTRL_ASYNC_WSTS_SHIFT;
  189278. + tx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_WSTS_1) ?
  189279. + (tx_cis | (0x1 << 4)) : tx_cis;
  189280. + /*
  189281. + * b. For async and ctrl channels:
  189282. + * RSTS[4]/WSTS[4] = 0
  189283. + * and RSTS[2]/WSTS[2] = 0
  189284. + */
  189285. + cdt_val[3] &= ~CDT_CTRL_ASYNC_WSTS_1;
  189286. + cdt_val[2] &=
  189287. + ~(0x4 << CDT_CTRL_ASYNC_WSTS_SHIFT);
  189288. + break;
  189289. + case MLB_CTYPE_ISOC:
  189290. + tx_cis = (cdt_val[2] & ~CDT_ISOC_WSTS_MASK)
  189291. + >> CDT_ISOC_WSTS_SHIFT;
  189292. + /* c. For isoc channels: WSTS[2:1] = 0x00 */
  189293. + cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
  189294. + break;
  189295. + default:
  189296. + break;
  189297. + }
  189298. + mlb150_dev_cdt_write(tx_mlb_ch, cdt_val);
  189299. + }
  189300. +
  189301. + /* Get rx channel interrupt status */
  189302. + if (rx_int_sts & (1 << (rx_mlb_ch % 32))) {
  189303. + mlb150_dev_cdt_read(rx_mlb_cl, cdt_val);
  189304. + pr_debug("mxc_mlb150: RX_CH: %d, cdt_val[3]: 0x%08x, "
  189305. + "cdt_val[2]: 0x%08x, "
  189306. + "cdt_val[1]: 0x%08x, "
  189307. + "cdt_val[0]: 0x%08x\n",
  189308. + rx_mlb_ch, cdt_val[3], cdt_val[2],
  189309. + cdt_val[1], cdt_val[0]);
  189310. + switch (ctype) {
  189311. + case MLB_CTYPE_SYNC:
  189312. + tx_cis = (cdt_val[2] & ~CDT_SYNC_RSTS_MASK)
  189313. + >> CDT_SYNC_RSTS_SHIFT;
  189314. + cdt_val[2] &= ~(0x8 << CDT_SYNC_WSTS_SHIFT);
  189315. + break;
  189316. + case MLB_CTYPE_CTRL:
  189317. + case MLB_CTYPE_ASYNC:
  189318. + tx_cis =
  189319. + (cdt_val[2] & ~CDT_CTRL_ASYNC_RSTS_MASK)
  189320. + >> CDT_CTRL_ASYNC_RSTS_SHIFT;
  189321. + tx_cis = (cdt_val[3] & CDT_CTRL_ASYNC_RSTS_1) ?
  189322. + (tx_cis | (0x1 << 4)) : tx_cis;
  189323. + cdt_val[3] &= ~CDT_CTRL_ASYNC_RSTS_1;
  189324. + cdt_val[2] &=
  189325. + ~(0x4 << CDT_CTRL_ASYNC_RSTS_SHIFT);
  189326. + break;
  189327. + case MLB_CTYPE_ISOC:
  189328. + tx_cis = (cdt_val[2] & ~CDT_ISOC_RSTS_MASK)
  189329. + >> CDT_ISOC_RSTS_SHIFT;
  189330. + cdt_val[2] &= ~(0x6 << CDT_ISOC_WSTS_SHIFT);
  189331. + break;
  189332. + default:
  189333. + break;
  189334. + }
  189335. + mlb150_dev_cdt_write(rx_mlb_ch, cdt_val);
  189336. + }
  189337. +
  189338. + if (!tx_cis && !rx_cis)
  189339. + continue;
  189340. +
  189341. + /* fill exception event */
  189342. + spin_lock(&pdevinfo->event_lock);
  189343. + pdevinfo->ex_event |= (rx_cis << 16) | tx_cis;
  189344. + spin_unlock(&pdevinfo->event_lock);
  189345. + }
  189346. +
  189347. + return IRQ_HANDLED;
  189348. +}
  189349. +
  189350. +static int mxc_mlb150_open(struct inode *inode, struct file *filp)
  189351. +{
  189352. + int minor, ring_buf_size, buf_size, j, ret;
  189353. + void __iomem *buf_addr;
  189354. + ulong phy_addr;
  189355. + struct mlb_dev_info *pdevinfo = NULL;
  189356. + struct mlb_channel_info *pchinfo = NULL;
  189357. + struct mlb_data *drvdata;
  189358. +
  189359. + minor = MINOR(inode->i_rdev);
  189360. + drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
  189361. +
  189362. + if (minor < 0 || minor >= MLB_MINOR_DEVICES) {
  189363. + pr_err("no device\n");
  189364. + return -ENODEV;
  189365. + }
  189366. +
  189367. + /* open for each channel device */
  189368. + if (atomic_cmpxchg(&mlb_devinfo[minor].opencnt, 0, 1) != 0) {
  189369. + pr_err("busy\n");
  189370. + return -EBUSY;
  189371. + }
  189372. +
  189373. + clk_prepare_enable(drvdata->clk_mlb3p);
  189374. +
  189375. + /* initial MLB module */
  189376. + mlb150_dev_init();
  189377. +
  189378. + pdevinfo = &mlb_devinfo[minor];
  189379. + pchinfo = &pdevinfo->channels[TX_CHANNEL];
  189380. +
  189381. + ring_buf_size = pdevinfo->buf_size;
  189382. + buf_size = ring_buf_size * (TRANS_RING_NODES * 2);
  189383. + buf_addr = (void __iomem *)gen_pool_alloc(drvdata->iram_pool, buf_size);
  189384. + if (buf_addr == NULL) {
  189385. + ret = -ENOMEM;
  189386. + pr_err("can not alloc rx/tx buffers: %d\n", buf_size);
  189387. + return ret;
  189388. + }
  189389. + phy_addr = gen_pool_virt_to_phys(drvdata->iram_pool, (ulong)buf_addr);
  189390. + pr_debug("IRAM Range: Virt 0x%p - 0x%p, Phys 0x%x - 0x%x, size: 0x%x\n",
  189391. + buf_addr, (buf_addr + buf_size - 1), (u32)phy_addr,
  189392. + (u32)(phy_addr + buf_size - 1), buf_size);
  189393. + pdevinfo->rbuf_base_virt = buf_addr;
  189394. + pdevinfo->rbuf_base_phy = phy_addr;
  189395. + drvdata->iram_size = buf_size;
  189396. +
  189397. + memset(buf_addr, 0, buf_size);
  189398. +
  189399. + for (j = 0; j < (TRANS_RING_NODES);
  189400. + ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
  189401. + pdevinfo->rx_rbuf.virt_bufs[j] = buf_addr;
  189402. + pdevinfo->rx_rbuf.phy_addrs[j] = phy_addr;
  189403. + pr_debug("RX Ringbuf[%d]: 0x%p 0x%x\n",
  189404. + j, buf_addr, (u32)phy_addr);
  189405. + }
  189406. + pdevinfo->rx_rbuf.unit_size = ring_buf_size;
  189407. + pdevinfo->rx_rbuf.total_size = buf_size;
  189408. + for (j = 0; j < (TRANS_RING_NODES);
  189409. + ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) {
  189410. + pdevinfo->tx_rbuf.virt_bufs[j] = buf_addr;
  189411. + pdevinfo->tx_rbuf.phy_addrs[j] = phy_addr;
  189412. + pr_debug("TX Ringbuf[%d]: 0x%p 0x%x\n",
  189413. + j, buf_addr, (u32)phy_addr);
  189414. + }
  189415. +
  189416. + pdevinfo->tx_rbuf.unit_size = ring_buf_size;
  189417. + pdevinfo->tx_rbuf.total_size = buf_size;
  189418. +
  189419. + /* reset the buffer read/write ptr */
  189420. + pdevinfo->rx_rbuf.head = pdevinfo->rx_rbuf.tail = 0;
  189421. + pdevinfo->tx_rbuf.head = pdevinfo->tx_rbuf.tail = 0;
  189422. + pdevinfo->ex_event = 0;
  189423. + pdevinfo->tx_ok = 0;
  189424. +
  189425. + init_waitqueue_head(&pdevinfo->rx_wq);
  189426. + init_waitqueue_head(&pdevinfo->tx_wq);
  189427. +
  189428. + drvdata = container_of(inode->i_cdev, struct mlb_data, cdev);
  189429. + drvdata->devinfo = pdevinfo;
  189430. + mxc_mlb150_irq_enable(drvdata, 1);
  189431. + filp->private_data = drvdata;
  189432. +
  189433. + return 0;
  189434. +}
  189435. +
  189436. +static int mxc_mlb150_release(struct inode *inode, struct file *filp)
  189437. +{
  189438. + int minor;
  189439. + struct mlb_data *drvdata = filp->private_data;
  189440. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  189441. +
  189442. + minor = MINOR(inode->i_rdev);
  189443. + mxc_mlb150_irq_enable(drvdata, 0);
  189444. +
  189445. +#ifdef DEBUG
  189446. + mlb150_dev_dump_reg();
  189447. + mlb150_dev_dump_ctr_tbl(0, pdevinfo->channels[TX_CHANNEL].cl + 1);
  189448. +#endif
  189449. +
  189450. + gen_pool_free(drvdata->iram_pool,
  189451. + (ulong)pdevinfo->rbuf_base_virt, drvdata->iram_size);
  189452. +
  189453. + mlb150_dev_exit();
  189454. +
  189455. + if (pdevinfo && atomic_read(&pdevinfo->on)
  189456. + && (pdevinfo->fps >= CLK_2048FS))
  189457. + clk_disable_unprepare(drvdata->clk_mlb6p);
  189458. +
  189459. + atomic_set(&pdevinfo->on, 0);
  189460. +
  189461. + clk_disable_unprepare(drvdata->clk_mlb3p);
  189462. + /* decrease the open count */
  189463. + atomic_set(&pdevinfo->opencnt, 0);
  189464. +
  189465. + drvdata->devinfo = NULL;
  189466. +
  189467. + return 0;
  189468. +}
  189469. +
  189470. +static long mxc_mlb150_ioctl(struct file *filp,
  189471. + unsigned int cmd, unsigned long arg)
  189472. +{
  189473. + struct inode *inode = filp->f_dentry->d_inode;
  189474. + struct mlb_data *drvdata = filp->private_data;
  189475. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  189476. + void __user *argp = (void __user *)arg;
  189477. + unsigned long flags, event;
  189478. + int minor;
  189479. +
  189480. + minor = MINOR(inode->i_rdev);
  189481. +
  189482. + switch (cmd) {
  189483. + case MLB_CHAN_SETADDR:
  189484. + {
  189485. + unsigned int caddr;
  189486. + /* get channel address from user space */
  189487. + if (copy_from_user(&caddr, argp, sizeof(caddr))) {
  189488. + pr_err("mxc_mlb150: copy from user failed\n");
  189489. + return -EFAULT;
  189490. + }
  189491. + pdevinfo->channels[TX_CHANNEL].address =
  189492. + (caddr >> 16) & 0xFFFF;
  189493. + pdevinfo->channels[RX_CHANNEL].address = caddr & 0xFFFF;
  189494. + pr_debug("mxc_mlb150: set ch addr, tx: %d, rx: %d\n",
  189495. + pdevinfo->channels[TX_CHANNEL].address,
  189496. + pdevinfo->channels[RX_CHANNEL].address);
  189497. + break;
  189498. + }
  189499. +
  189500. + case MLB_CHAN_STARTUP:
  189501. + if (atomic_read(&pdevinfo->on)) {
  189502. + pr_debug("mxc_mlb150: channel alreadly startup\n");
  189503. + break;
  189504. + }
  189505. + if (mlb_channel_enable(drvdata, minor, 1))
  189506. + return -EFAULT;
  189507. + break;
  189508. + case MLB_CHAN_SHUTDOWN:
  189509. + if (atomic_read(&pdevinfo->on) == 0) {
  189510. + pr_debug("mxc_mlb150: channel areadly shutdown\n");
  189511. + break;
  189512. + }
  189513. + mlb150_trans_complete_check(pdevinfo);
  189514. + mlb_channel_enable(drvdata, minor, 0);
  189515. + break;
  189516. + case MLB_CHAN_GETEVENT:
  189517. + /* get and clear the ex_event */
  189518. + spin_lock_irqsave(&pdevinfo->event_lock, flags);
  189519. + event = pdevinfo->ex_event;
  189520. + pdevinfo->ex_event = 0;
  189521. + spin_unlock_irqrestore(&pdevinfo->event_lock, flags);
  189522. +
  189523. + if (event) {
  189524. + if (copy_to_user(argp, &event, sizeof(event))) {
  189525. + pr_err("mxc_mlb150: copy to user failed\n");
  189526. + return -EFAULT;
  189527. + }
  189528. + } else
  189529. + return -EAGAIN;
  189530. + break;
  189531. + case MLB_SET_ISOC_BLKSIZE_188:
  189532. + pdevinfo->isoc_blksz = 188;
  189533. + pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
  189534. + pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
  189535. + break;
  189536. + case MLB_SET_ISOC_BLKSIZE_196:
  189537. + pdevinfo->isoc_blksz = 196;
  189538. + pdevinfo->cdt_buf_dep = pdevinfo->adt_buf_dep =
  189539. + pdevinfo->isoc_blksz * CH_ISOC_BLK_NUM;
  189540. + break;
  189541. + case MLB_SET_SYNC_QUAD:
  189542. + {
  189543. + u32 quad;
  189544. +
  189545. + if (copy_from_user(&quad, argp, sizeof(quad))) {
  189546. + pr_err("mxc_mlb150: get quad number "
  189547. + "from user failed\n");
  189548. + return -EFAULT;
  189549. + }
  189550. + if (quad <= 0 || quad > 3) {
  189551. + pr_err("mxc_mlb150: Invalid Quadlets!"
  189552. + "Quadlets in Sync mode can "
  189553. + "only be 1, 2, 3\n");
  189554. + return -EINVAL;
  189555. + }
  189556. + pdevinfo->sync_quad = quad;
  189557. + /* Each quadlets is 4 bytes */
  189558. + pdevinfo->cdt_buf_dep = quad * 4 * 4;
  189559. + pdevinfo->adt_buf_dep =
  189560. + pdevinfo->cdt_buf_dep * CH_SYNC_ADT_BUF_MULTI;
  189561. + }
  189562. + break;
  189563. + case MLB_SET_FPS:
  189564. + {
  189565. + u32 fps, c0_val;
  189566. +
  189567. + /* get fps from user space */
  189568. + if (copy_from_user(&fps, argp, sizeof(fps))) {
  189569. + pr_err("mxc_mlb150: copy from user failed\n");
  189570. + return -EFAULT;
  189571. + }
  189572. +
  189573. + c0_val = __raw_readl(mlb_base + REG_MLBC0);
  189574. + c0_val &= ~MLBC0_MLBCLK_MASK;
  189575. +
  189576. + /* check fps value */
  189577. + switch (fps) {
  189578. + case 256:
  189579. + case 512:
  189580. + case 1024:
  189581. + pdevinfo->fps = fps >> 9;
  189582. + c0_val &= ~MLBC0_MLBPEN;
  189583. + c0_val |= (fps >> 9)
  189584. + << MLBC0_MLBCLK_SHIFT;
  189585. +
  189586. + if (1024 == fps) {
  189587. + /*
  189588. + * Invert output clock phase
  189589. + * in 1024 fps
  189590. + */
  189591. + __raw_writel(0x1,
  189592. + mlb_base + REG_MLBPC2);
  189593. + }
  189594. + break;
  189595. + case 2048:
  189596. + case 3072:
  189597. + case 4096:
  189598. + pdevinfo->fps = (fps >> 10) + 1;
  189599. + c0_val |= ((fps >> 10) + 1)
  189600. + << MLBC0_MLBCLK_SHIFT;
  189601. + break;
  189602. + case 6144:
  189603. + pdevinfo->fps = fps >> 10;
  189604. + c0_val |= ((fps >> 10) + 1)
  189605. + << MLBC0_MLBCLK_SHIFT;
  189606. + break;
  189607. + case 8192:
  189608. + pdevinfo->fps = (fps >> 10) - 1;
  189609. + c0_val |= ((fps >> 10) - 1)
  189610. + << MLBC0_MLBCLK_SHIFT;
  189611. + break;
  189612. + default:
  189613. + pr_debug("mxc_mlb150: invalid fps argument: %d\n",
  189614. + fps);
  189615. + return -EINVAL;
  189616. + }
  189617. +
  189618. + __raw_writel(c0_val, mlb_base + REG_MLBC0);
  189619. +
  189620. + pr_debug("mxc_mlb150: set fps to %d, MLBC0: 0x%08x\n",
  189621. + fps,
  189622. + (u32)__raw_readl(mlb_base + REG_MLBC0));
  189623. +
  189624. + break;
  189625. + }
  189626. +
  189627. + case MLB_GET_VER:
  189628. + {
  189629. + u32 version;
  189630. +
  189631. + /* get MLB device module version */
  189632. + version = 0x03030003;
  189633. +
  189634. + pr_debug("mxc_mlb150: get version: 0x%08x\n",
  189635. + version);
  189636. +
  189637. + if (copy_to_user(argp, &version, sizeof(version))) {
  189638. + pr_err("mxc_mlb150: copy to user failed\n");
  189639. + return -EFAULT;
  189640. + }
  189641. + break;
  189642. + }
  189643. +
  189644. + case MLB_SET_DEVADDR:
  189645. + {
  189646. + u32 c1_val;
  189647. + u8 devaddr;
  189648. +
  189649. + /* get MLB device address from user space */
  189650. + if (copy_from_user
  189651. + (&devaddr, argp, sizeof(unsigned char))) {
  189652. + pr_err("mxc_mlb150: copy from user failed\n");
  189653. + return -EFAULT;
  189654. + }
  189655. +
  189656. + c1_val = __raw_readl(mlb_base + REG_MLBC1);
  189657. + c1_val &= ~MLBC1_NDA_MASK;
  189658. + c1_val |= devaddr << MLBC1_NDA_SHIFT;
  189659. + __raw_writel(c1_val, mlb_base + REG_MLBC1);
  189660. + pr_debug("mxc_mlb150: set dev addr, dev addr: %d, "
  189661. + "MLBC1: 0x%08x\n", devaddr,
  189662. + (u32)__raw_readl(mlb_base + REG_MLBC1));
  189663. +
  189664. + break;
  189665. + }
  189666. +
  189667. + case MLB_IRQ_DISABLE:
  189668. + {
  189669. + disable_irq(drvdata->irq_mlb);
  189670. + break;
  189671. + }
  189672. +
  189673. + case MLB_IRQ_ENABLE:
  189674. + {
  189675. + enable_irq(drvdata->irq_mlb);
  189676. + break;
  189677. + }
  189678. + default:
  189679. + pr_info("mxc_mlb150: Invalid ioctl command\n");
  189680. + return -EINVAL;
  189681. + }
  189682. +
  189683. + return 0;
  189684. +}
  189685. +
  189686. +/*
  189687. + * MLB read routine
  189688. + * Read the current received data from queued buffer,
  189689. + * and free this buffer for hw to fill ingress data.
  189690. + */
  189691. +static ssize_t mxc_mlb150_read(struct file *filp, char __user *buf,
  189692. + size_t count, loff_t *f_pos)
  189693. +{
  189694. + int size;
  189695. + struct mlb_data *drvdata = filp->private_data;
  189696. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  189697. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  189698. + int head, tail;
  189699. + unsigned long flags;
  189700. +
  189701. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  189702. +
  189703. + head = ACCESS_ONCE(rx_rbuf->head);
  189704. + tail = rx_rbuf->tail;
  189705. +
  189706. + read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  189707. +
  189708. + /* check the current rx buffer is available or not */
  189709. + if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
  189710. +
  189711. + if (filp->f_flags & O_NONBLOCK)
  189712. + return -EAGAIN;
  189713. +
  189714. + do {
  189715. + DEFINE_WAIT(__wait);
  189716. +
  189717. + for (;;) {
  189718. + prepare_to_wait(&pdevinfo->rx_wq,
  189719. + &__wait, TASK_INTERRUPTIBLE);
  189720. +
  189721. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  189722. + if (CIRC_CNT(rx_rbuf->head, rx_rbuf->tail,
  189723. + TRANS_RING_NODES) > 0) {
  189724. + read_unlock_irqrestore(&rx_rbuf->rb_lock,
  189725. + flags);
  189726. + break;
  189727. + }
  189728. + read_unlock_irqrestore(&rx_rbuf->rb_lock,
  189729. + flags);
  189730. +
  189731. + if (!signal_pending(current)) {
  189732. + schedule();
  189733. + continue;
  189734. + }
  189735. + return -ERESTARTSYS;
  189736. + }
  189737. + finish_wait(&pdevinfo->rx_wq, &__wait);
  189738. + } while (0);
  189739. + }
  189740. +
  189741. + /* read index before reading contents at that index */
  189742. + smp_read_barrier_depends();
  189743. +
  189744. + size = pdevinfo->adt_buf_dep;
  189745. + if (size > count) {
  189746. + /* the user buffer is too small */
  189747. + pr_warning
  189748. + ("mxc_mlb150: received data size is bigger than "
  189749. + "size: %d, count: %d\n", size, count);
  189750. + return -EINVAL;
  189751. + }
  189752. +
  189753. + /* extract one item from the buffer */
  189754. + if (copy_to_user(buf, rx_rbuf->virt_bufs[tail], size)) {
  189755. + pr_err("mxc_mlb150: copy from user failed\n");
  189756. + return -EFAULT;
  189757. + }
  189758. +
  189759. + /* finish reading descriptor before incrementing tail */
  189760. + smp_mb();
  189761. +
  189762. + write_lock_irqsave(&rx_rbuf->rb_lock, flags);
  189763. + rx_rbuf->tail = (tail + 1) & (TRANS_RING_NODES - 1);
  189764. + write_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  189765. +
  189766. + *f_pos = 0;
  189767. +
  189768. + return size;
  189769. +}
  189770. +
  189771. +/*
  189772. + * MLB write routine
  189773. + * Copy the user data to tx channel buffer,
  189774. + * and prepare the channel current/next buffer ptr.
  189775. + */
  189776. +static ssize_t mxc_mlb150_write(struct file *filp, const char __user *buf,
  189777. + size_t count, loff_t *f_pos)
  189778. +{
  189779. + s32 ret = 0;
  189780. + struct mlb_channel_info *pchinfo = NULL;
  189781. + struct mlb_data *drvdata = filp->private_data;
  189782. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  189783. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  189784. + int head, tail;
  189785. + unsigned long flags;
  189786. +
  189787. + /*
  189788. + * minor = MINOR(filp->f_dentry->d_inode->i_rdev);
  189789. + */
  189790. + pchinfo = &pdevinfo->channels[TX_CHANNEL];
  189791. +
  189792. + if (count > pdevinfo->buf_size) {
  189793. + /* too many data to write */
  189794. + pr_warning("mxc_mlb150: overflow write data\n");
  189795. + return -EFBIG;
  189796. + }
  189797. +
  189798. + *f_pos = 0;
  189799. +
  189800. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  189801. +
  189802. + head = tx_rbuf->head;
  189803. + tail = ACCESS_ONCE(tx_rbuf->tail);
  189804. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  189805. +
  189806. + if (0 == CIRC_SPACE(head, tail, TRANS_RING_NODES)) {
  189807. + if (filp->f_flags & O_NONBLOCK)
  189808. + return -EAGAIN;
  189809. + do {
  189810. + DEFINE_WAIT(__wait);
  189811. +
  189812. + for (;;) {
  189813. + prepare_to_wait(&pdevinfo->tx_wq,
  189814. + &__wait, TASK_INTERRUPTIBLE);
  189815. +
  189816. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  189817. + if (CIRC_SPACE(tx_rbuf->head, tx_rbuf->tail,
  189818. + TRANS_RING_NODES) > 0) {
  189819. + read_unlock_irqrestore(&tx_rbuf->rb_lock,
  189820. + flags);
  189821. + break;
  189822. + }
  189823. + read_unlock_irqrestore(&tx_rbuf->rb_lock,
  189824. + flags);
  189825. +
  189826. + if (!signal_pending(current)) {
  189827. + schedule();
  189828. + continue;
  189829. + }
  189830. + return -ERESTARTSYS;
  189831. + }
  189832. + finish_wait(&pdevinfo->tx_wq, &__wait);
  189833. + } while (0);
  189834. + }
  189835. +
  189836. + if (copy_from_user((void *)tx_rbuf->virt_bufs[head], buf, count)) {
  189837. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  189838. + pr_err("mxc_mlb: copy from user failed\n");
  189839. + ret = -EFAULT;
  189840. + goto out;
  189841. + }
  189842. +
  189843. + write_lock_irqsave(&tx_rbuf->rb_lock, flags);
  189844. + smp_wmb();
  189845. + tx_rbuf->head = (head + 1) & (TRANS_RING_NODES - 1);
  189846. + write_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  189847. +
  189848. + if (0 == CIRC_CNT(head, tail, TRANS_RING_NODES)) {
  189849. + u32 tx_buf_ptr, ahb_ch;
  189850. + s32 adt_sts;
  189851. + u32 ctype = pdevinfo->channel_type;
  189852. +
  189853. + /* read index before reading contents at that index */
  189854. + smp_read_barrier_depends();
  189855. +
  189856. + tx_buf_ptr = tx_rbuf->phy_addrs[tail];
  189857. +
  189858. + ahb_ch = pdevinfo->channels[TX_CHANNEL].cl;
  189859. + adt_sts = mlb150_dev_get_adt_sts(ahb_ch);
  189860. +
  189861. + /* Set ADT for TX */
  189862. + mlb150_dev_pipo_next(ahb_ch, ctype, adt_sts, tx_buf_ptr);
  189863. + }
  189864. +
  189865. + ret = count;
  189866. +out:
  189867. + return ret;
  189868. +}
  189869. +
  189870. +static unsigned int mxc_mlb150_poll(struct file *filp,
  189871. + struct poll_table_struct *wait)
  189872. +{
  189873. + int minor;
  189874. + unsigned int ret = 0;
  189875. + struct mlb_data *drvdata = filp->private_data;
  189876. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  189877. + struct mlb_ringbuf *tx_rbuf = &pdevinfo->tx_rbuf;
  189878. + struct mlb_ringbuf *rx_rbuf = &pdevinfo->rx_rbuf;
  189879. + int head, tail;
  189880. + unsigned long flags;
  189881. +
  189882. +
  189883. + minor = MINOR(filp->f_dentry->d_inode->i_rdev);
  189884. +
  189885. + poll_wait(filp, &pdevinfo->rx_wq, wait);
  189886. + poll_wait(filp, &pdevinfo->tx_wq, wait);
  189887. +
  189888. + read_lock_irqsave(&tx_rbuf->rb_lock, flags);
  189889. + head = tx_rbuf->head;
  189890. + tail = tx_rbuf->tail;
  189891. + read_unlock_irqrestore(&tx_rbuf->rb_lock, flags);
  189892. +
  189893. + /* check the tx buffer is avaiable or not */
  189894. + if (CIRC_SPACE(head, tail, TRANS_RING_NODES) >= 1)
  189895. + ret |= POLLOUT | POLLWRNORM;
  189896. +
  189897. + read_lock_irqsave(&rx_rbuf->rb_lock, flags);
  189898. + head = rx_rbuf->head;
  189899. + tail = rx_rbuf->tail;
  189900. + read_unlock_irqrestore(&rx_rbuf->rb_lock, flags);
  189901. +
  189902. + /* check the rx buffer filled or not */
  189903. + if (CIRC_CNT(head, tail, TRANS_RING_NODES) >= 1)
  189904. + ret |= POLLIN | POLLRDNORM;
  189905. +
  189906. +
  189907. + /* check the exception event */
  189908. + if (pdevinfo->ex_event)
  189909. + ret |= POLLIN | POLLRDNORM;
  189910. +
  189911. + return ret;
  189912. +}
  189913. +
  189914. +/*
  189915. + * char dev file operations structure
  189916. + */
  189917. +static const struct file_operations mxc_mlb150_fops = {
  189918. +
  189919. + .owner = THIS_MODULE,
  189920. + .open = mxc_mlb150_open,
  189921. + .release = mxc_mlb150_release,
  189922. + .unlocked_ioctl = mxc_mlb150_ioctl,
  189923. + .poll = mxc_mlb150_poll,
  189924. + .read = mxc_mlb150_read,
  189925. + .write = mxc_mlb150_write,
  189926. +};
  189927. +
  189928. +static struct platform_device_id imx_mlb150_devtype[] = {
  189929. + {
  189930. + .name = "imx6q-mlb150",
  189931. + .driver_data = 0,
  189932. + }, {
  189933. + /* sentinel */
  189934. + }
  189935. +};
  189936. +MODULE_DEVICE_TABLE(platform, imx_mlb150_devtype);
  189937. +
  189938. +static const struct of_device_id mlb150_imx_dt_ids[] = {
  189939. + { .compatible = "fsl,imx6q-mlb150", .data = &imx_mlb150_devtype[0], },
  189940. + { /* sentinel */ }
  189941. +};
  189942. +
  189943. +/*
  189944. + * This function is called whenever the MLB device is detected.
  189945. + */
  189946. +static int mxc_mlb150_probe(struct platform_device *pdev)
  189947. +{
  189948. + int ret, mlb_major, i;
  189949. + struct mlb_data *drvdata;
  189950. + struct resource *res;
  189951. + struct device_node *np = pdev->dev.of_node;
  189952. +
  189953. + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct mlb_data),
  189954. + GFP_KERNEL);
  189955. + if (!drvdata) {
  189956. + dev_err(&pdev->dev, "can't allocate enough memory\n");
  189957. + return -ENOMEM;
  189958. + }
  189959. +
  189960. + /*
  189961. + * Register MLB lld as four character devices
  189962. + */
  189963. + ret = alloc_chrdev_region(&drvdata->firstdev, 0,
  189964. + MLB_MINOR_DEVICES, "mxc_mlb150");
  189965. + if (ret < 0) {
  189966. + dev_err(&pdev->dev, "alloc region error\n");
  189967. + goto err_reg;
  189968. + }
  189969. + mlb_major = MAJOR(drvdata->firstdev);
  189970. + dev_dbg(&pdev->dev, "MLB device major: %d\n", mlb_major);
  189971. +
  189972. + cdev_init(&drvdata->cdev, &mxc_mlb150_fops);
  189973. + drvdata->cdev.owner = THIS_MODULE;
  189974. +
  189975. + ret = cdev_add(&drvdata->cdev, drvdata->firstdev, MLB_MINOR_DEVICES);
  189976. + if (ret) {
  189977. + dev_err(&pdev->dev, "can't add cdev\n");
  189978. + goto err_reg;
  189979. + }
  189980. +
  189981. + /* create class and device for udev information */
  189982. + drvdata->class = class_create(THIS_MODULE, "mlb150");
  189983. + if (IS_ERR(drvdata->class)) {
  189984. + dev_err(&pdev->dev, "failed to create device class\n");
  189985. + ret = -ENOMEM;
  189986. + goto err_class;
  189987. + }
  189988. +
  189989. + for (i = 0; i < MLB_MINOR_DEVICES; i++) {
  189990. + struct device *class_dev;
  189991. +
  189992. + class_dev = device_create(drvdata->class, NULL,
  189993. + MKDEV(mlb_major, i),
  189994. + NULL, mlb_devinfo[i].dev_name);
  189995. + if (IS_ERR(class_dev)) {
  189996. + dev_err(&pdev->dev, "failed to create mlb150 %s"
  189997. + " class device\n", mlb_devinfo[i].dev_name);
  189998. + ret = -ENOMEM;
  189999. + goto err_dev;
  190000. + }
  190001. + }
  190002. +
  190003. + /* ahb0 irq */
  190004. + drvdata->irq_ahb0 = platform_get_irq(pdev, 1);
  190005. + if (drvdata->irq_ahb0 < 0) {
  190006. + dev_err(&pdev->dev, "No ahb0 irq line provided\n");
  190007. + goto err_dev;
  190008. + }
  190009. + dev_dbg(&pdev->dev, "ahb0_irq: %d\n", drvdata->irq_ahb0);
  190010. + if (devm_request_irq(&pdev->dev, drvdata->irq_ahb0, mlb_ahb_isr,
  190011. + 0, "mlb_ahb0", NULL)) {
  190012. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb0);
  190013. + goto err_dev;
  190014. + }
  190015. +
  190016. + /* ahb1 irq */
  190017. + drvdata->irq_ahb1 = platform_get_irq(pdev, 2);
  190018. + if (drvdata->irq_ahb1 < 0) {
  190019. + dev_err(&pdev->dev, "No ahb1 irq line provided\n");
  190020. + goto err_dev;
  190021. + }
  190022. + dev_dbg(&pdev->dev, "ahb1_irq: %d\n", drvdata->irq_ahb1);
  190023. + if (devm_request_irq(&pdev->dev, drvdata->irq_ahb1, mlb_ahb_isr,
  190024. + 0, "mlb_ahb1", NULL)) {
  190025. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_ahb1);
  190026. + goto err_dev;
  190027. + }
  190028. +
  190029. + /* mlb irq */
  190030. + drvdata->irq_mlb = platform_get_irq(pdev, 0);
  190031. + if (drvdata->irq_mlb < 0) {
  190032. + dev_err(&pdev->dev, "No mlb irq line provided\n");
  190033. + goto err_dev;
  190034. + }
  190035. + dev_dbg(&pdev->dev, "mlb_irq: %d\n", drvdata->irq_mlb);
  190036. + if (devm_request_irq(&pdev->dev, drvdata->irq_mlb, mlb_isr,
  190037. + 0, "mlb", NULL)) {
  190038. + dev_err(&pdev->dev, "can't claim irq %d\n", drvdata->irq_mlb);
  190039. + goto err_dev;
  190040. + }
  190041. +
  190042. + /* ioremap from phy mlb to kernel space */
  190043. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  190044. + if (!res) {
  190045. + dev_err(&pdev->dev, "can't get device resources\n");
  190046. + ret = -ENOENT;
  190047. + goto err_dev;
  190048. + }
  190049. + mlb_base = devm_request_and_ioremap(&pdev->dev, res);
  190050. + dev_dbg(&pdev->dev, "mapped base address: 0x%08x\n", (u32)mlb_base);
  190051. + if (IS_ERR(mlb_base)) {
  190052. + dev_err(&pdev->dev,
  190053. + "failed to get ioremap base\n");
  190054. + ret = PTR_ERR(mlb_base);
  190055. + goto err_dev;
  190056. + }
  190057. + drvdata->membase = mlb_base;
  190058. +
  190059. +#ifdef CONFIG_REGULATOR
  190060. + drvdata->nvcc = devm_regulator_get(&pdev->dev, "reg_nvcc");
  190061. + if (!IS_ERR(drvdata->nvcc)) {
  190062. + regulator_set_voltage(drvdata->nvcc, 2500000, 2500000);
  190063. + dev_err(&pdev->dev, "enalbe regulator\n");
  190064. + ret = regulator_enable(drvdata->nvcc);
  190065. + if (ret) {
  190066. + dev_err(&pdev->dev, "vdd set voltage error\n");
  190067. + goto err_dev;
  190068. + }
  190069. + }
  190070. +#endif
  190071. +
  190072. + /* enable clock */
  190073. + drvdata->clk_mlb3p = devm_clk_get(&pdev->dev, "mlb");
  190074. + if (IS_ERR(drvdata->clk_mlb3p)) {
  190075. + dev_err(&pdev->dev, "unable to get mlb clock\n");
  190076. + ret = PTR_ERR(drvdata->clk_mlb3p);
  190077. + goto err_dev;
  190078. + }
  190079. +
  190080. + drvdata->clk_mlb6p = devm_clk_get(&pdev->dev, "pll8_mlb");
  190081. + if (IS_ERR(drvdata->clk_mlb6p)) {
  190082. + dev_err(&pdev->dev, "unable to get mlb pll clock\n");
  190083. + ret = PTR_ERR(drvdata->clk_mlb6p);
  190084. + goto err_dev;
  190085. + }
  190086. +
  190087. +
  190088. + drvdata->iram_pool = of_get_named_gen_pool(np, "iram", 0);
  190089. + if (!drvdata->iram_pool) {
  190090. + dev_err(&pdev->dev, "iram pool not available\n");
  190091. + ret = -ENOMEM;
  190092. + goto err_dev;
  190093. + }
  190094. +
  190095. + drvdata->devinfo = NULL;
  190096. + mxc_mlb150_irq_enable(drvdata, 0);
  190097. + platform_set_drvdata(pdev, drvdata);
  190098. + return 0;
  190099. +
  190100. +err_dev:
  190101. + for (--i; i >= 0; i--)
  190102. + device_destroy(drvdata->class, MKDEV(mlb_major, i));
  190103. +
  190104. + class_destroy(drvdata->class);
  190105. +err_class:
  190106. + cdev_del(&drvdata->cdev);
  190107. +err_reg:
  190108. + unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
  190109. +
  190110. + return ret;
  190111. +}
  190112. +
  190113. +static int mxc_mlb150_remove(struct platform_device *pdev)
  190114. +{
  190115. + int i;
  190116. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  190117. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  190118. +
  190119. + if (pdevinfo && atomic_read(&pdevinfo->on)
  190120. + && (pdevinfo->fps >= CLK_2048FS))
  190121. + clk_disable_unprepare(drvdata->clk_mlb6p);
  190122. +
  190123. + if (pdevinfo && atomic_read(&pdevinfo->opencnt))
  190124. + clk_disable_unprepare(drvdata->clk_mlb3p);
  190125. +
  190126. + /* disable mlb power */
  190127. +#ifdef CONFIG_REGULATOR
  190128. + if (!IS_ERR(drvdata->nvcc))
  190129. + regulator_disable(drvdata->nvcc);
  190130. +#endif
  190131. +
  190132. + /* destroy mlb device class */
  190133. + for (i = MLB_MINOR_DEVICES - 1; i >= 0; i--)
  190134. + device_destroy(drvdata->class,
  190135. + MKDEV(MAJOR(drvdata->firstdev), i));
  190136. + class_destroy(drvdata->class);
  190137. +
  190138. + cdev_del(&drvdata->cdev);
  190139. +
  190140. + /* Unregister the two MLB devices */
  190141. + unregister_chrdev_region(drvdata->firstdev, MLB_MINOR_DEVICES);
  190142. +
  190143. + return 0;
  190144. +}
  190145. +
  190146. +#ifdef CONFIG_PM
  190147. +static int mxc_mlb150_suspend(struct platform_device *pdev, pm_message_t state)
  190148. +{
  190149. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  190150. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  190151. +
  190152. + if (pdevinfo && atomic_read(&pdevinfo->on)
  190153. + && (pdevinfo->fps >= CLK_2048FS))
  190154. + clk_disable_unprepare(drvdata->clk_mlb6p);
  190155. +
  190156. + if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
  190157. + mlb150_dev_exit();
  190158. + clk_disable_unprepare(drvdata->clk_mlb3p);
  190159. + }
  190160. +
  190161. + return 0;
  190162. +}
  190163. +
  190164. +static int mxc_mlb150_resume(struct platform_device *pdev)
  190165. +{
  190166. + struct mlb_data *drvdata = platform_get_drvdata(pdev);
  190167. + struct mlb_dev_info *pdevinfo = drvdata->devinfo;
  190168. +
  190169. + if (pdevinfo && atomic_read(&pdevinfo->opencnt)) {
  190170. + clk_prepare_enable(drvdata->clk_mlb3p);
  190171. + mlb150_dev_init();
  190172. + }
  190173. +
  190174. + if (pdevinfo && atomic_read(&pdevinfo->on) &&
  190175. + (pdevinfo->fps >= CLK_2048FS))
  190176. + clk_prepare_enable(drvdata->clk_mlb6p);
  190177. +
  190178. + return 0;
  190179. +}
  190180. +#else
  190181. +#define mxc_mlb150_suspend NULL
  190182. +#define mxc_mlb150_resume NULL
  190183. +#endif
  190184. +
  190185. +/*
  190186. + * platform driver structure for MLB
  190187. + */
  190188. +static struct platform_driver mxc_mlb150_driver = {
  190189. + .driver = {
  190190. + .name = DRIVER_NAME,
  190191. + .owner = THIS_MODULE,
  190192. + .of_match_table = mlb150_imx_dt_ids,
  190193. + },
  190194. + .probe = mxc_mlb150_probe,
  190195. + .remove = mxc_mlb150_remove,
  190196. + .suspend = mxc_mlb150_suspend,
  190197. + .resume = mxc_mlb150_resume,
  190198. + .id_table = imx_mlb150_devtype,
  190199. +};
  190200. +
  190201. +static int __init mxc_mlb150_init(void)
  190202. +{
  190203. + return platform_driver_register(&mxc_mlb150_driver);
  190204. +}
  190205. +
  190206. +static void __exit mxc_mlb150_exit(void)
  190207. +{
  190208. + platform_driver_unregister(&mxc_mlb150_driver);
  190209. +}
  190210. +
  190211. +module_init(mxc_mlb150_init);
  190212. +module_exit(mxc_mlb150_exit);
  190213. +
  190214. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  190215. +MODULE_DESCRIPTION("MLB150 low level driver");
  190216. +MODULE_LICENSE("GPL");
  190217. diff -Nur linux-3.14.17/drivers/mxc/vpu/Kconfig linux-imx6-3.14/drivers/mxc/vpu/Kconfig
  190218. --- linux-3.14.17/drivers/mxc/vpu/Kconfig 1970-01-01 01:00:00.000000000 +0100
  190219. +++ linux-imx6-3.14/drivers/mxc/vpu/Kconfig 2014-09-11 18:06:03.142042530 +0200
  190220. @@ -0,0 +1,31 @@
  190221. +#
  190222. +# Codec configuration
  190223. +#
  190224. +
  190225. +menu "MXC VPU(Video Processing Unit) support"
  190226. +
  190227. +config MXC_VPU
  190228. + tristate "Support for MXC VPU(Video Processing Unit)"
  190229. + depends on (SOC_IMX27 || SOC_IMX5 || SOC_IMX6Q)
  190230. + default y
  190231. + ---help---
  190232. + The VPU codec device provides codec function for H.264/MPEG4/H.263,
  190233. + as well as MPEG2/VC-1/DivX on some platforms.
  190234. +
  190235. +config MXC_VPU_DEBUG
  190236. + bool "MXC VPU debugging"
  190237. + depends on MXC_VPU != n
  190238. + help
  190239. + This is an option for the developers; most people should
  190240. + say N here. This enables MXC VPU driver debugging.
  190241. +
  190242. +config MX6_VPU_352M
  190243. + bool "MX6 VPU 352M"
  190244. + depends on MXC_VPU
  190245. + default n
  190246. + help
  190247. + Increase VPU frequncy to 352M, the config will disable bus frequency
  190248. + adjust dynamic, and CPU lowest setpoint will be 352Mhz.
  190249. + This config is used for special VPU use case.
  190250. +
  190251. +endmenu
  190252. diff -Nur linux-3.14.17/drivers/mxc/vpu/Makefile linux-imx6-3.14/drivers/mxc/vpu/Makefile
  190253. --- linux-3.14.17/drivers/mxc/vpu/Makefile 1970-01-01 01:00:00.000000000 +0100
  190254. +++ linux-imx6-3.14/drivers/mxc/vpu/Makefile 2014-09-11 18:06:03.142042530 +0200
  190255. @@ -0,0 +1,9 @@
  190256. +#
  190257. +# Makefile for the VPU drivers.
  190258. +#
  190259. +
  190260. +obj-$(CONFIG_MXC_VPU) += mxc_vpu.o
  190261. +
  190262. +ifeq ($(CONFIG_MXC_VPU_DEBUG),y)
  190263. +EXTRA_CFLAGS += -DDEBUG
  190264. +endif
  190265. diff -Nur linux-3.14.17/drivers/mxc/vpu/mxc_vpu.c linux-imx6-3.14/drivers/mxc/vpu/mxc_vpu.c
  190266. --- linux-3.14.17/drivers/mxc/vpu/mxc_vpu.c 1970-01-01 01:00:00.000000000 +0100
  190267. +++ linux-imx6-3.14/drivers/mxc/vpu/mxc_vpu.c 2014-09-11 18:06:03.142042530 +0200
  190268. @@ -0,0 +1,1342 @@
  190269. +/*
  190270. + * Copyright 2006-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  190271. + */
  190272. +
  190273. +/*
  190274. + * The code contained herein is licensed under the GNU General Public
  190275. + * License. You may obtain a copy of the GNU General Public License
  190276. + * Version 2 or later at the following locations:
  190277. + *
  190278. + * http://www.opensource.org/licenses/gpl-license.html
  190279. + * http://www.gnu.org/copyleft/gpl.html
  190280. + */
  190281. +
  190282. +/*!
  190283. + * @file mxc_vpu.c
  190284. + *
  190285. + * @brief VPU system initialization and file operation implementation
  190286. + *
  190287. + * @ingroup VPU
  190288. + */
  190289. +
  190290. +#include <linux/kernel.h>
  190291. +#include <linux/mm.h>
  190292. +#include <linux/interrupt.h>
  190293. +#include <linux/ioport.h>
  190294. +#include <linux/stat.h>
  190295. +#include <linux/platform_device.h>
  190296. +#include <linux/kdev_t.h>
  190297. +#include <linux/dma-mapping.h>
  190298. +#include <linux/wait.h>
  190299. +#include <linux/list.h>
  190300. +#include <linux/clk.h>
  190301. +#include <linux/delay.h>
  190302. +#include <linux/fsl_devices.h>
  190303. +#include <linux/uaccess.h>
  190304. +#include <linux/io.h>
  190305. +#include <linux/slab.h>
  190306. +#include <linux/workqueue.h>
  190307. +#include <linux/sched.h>
  190308. +#include <linux/vmalloc.h>
  190309. +#include <linux/regulator/consumer.h>
  190310. +#include <linux/page-flags.h>
  190311. +#include <linux/mm_types.h>
  190312. +#include <linux/types.h>
  190313. +#include <linux/memblock.h>
  190314. +#include <linux/memory.h>
  190315. +#include <linux/version.h>
  190316. +#include <asm/page.h>
  190317. +
  190318. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  190319. +#include <linux/module.h>
  190320. +#include <linux/pm_runtime.h>
  190321. +#include <linux/sizes.h>
  190322. +#endif
  190323. +
  190324. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
  190325. +#include <linux/iram_alloc.h>
  190326. +#include <mach/clock.h>
  190327. +#include <mach/hardware.h>
  190328. +#include <mach/mxc_vpu.h>
  190329. +#endif
  190330. +
  190331. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  190332. +#include <linux/busfreq-imx6.h>
  190333. +#include <linux/clk.h>
  190334. +#include <linux/genalloc.h>
  190335. +#include <linux/mxc_vpu.h>
  190336. +#include <linux/of.h>
  190337. +#include <linux/reset.h>
  190338. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  190339. +#include <mach/busfreq.h>
  190340. +#include <mach/common.h>
  190341. +#else
  190342. +#include <asm/sizes.h>
  190343. +#endif
  190344. +
  190345. +/* Define one new pgprot which combined uncached and XN(never executable) */
  190346. +#define pgprot_noncachedxn(prot) \
  190347. + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
  190348. +
  190349. +struct vpu_priv {
  190350. + struct fasync_struct *async_queue;
  190351. + struct work_struct work;
  190352. + struct workqueue_struct *workqueue;
  190353. + struct mutex lock;
  190354. +};
  190355. +
  190356. +/* To track the allocated memory buffer */
  190357. +struct memalloc_record {
  190358. + struct list_head list;
  190359. + struct vpu_mem_desc mem;
  190360. +};
  190361. +
  190362. +struct iram_setting {
  190363. + u32 start;
  190364. + u32 end;
  190365. +};
  190366. +
  190367. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  190368. +static struct gen_pool *iram_pool;
  190369. +static u32 iram_base;
  190370. +#endif
  190371. +
  190372. +static LIST_HEAD(head);
  190373. +
  190374. +static int vpu_major;
  190375. +static int vpu_clk_usercount;
  190376. +static struct class *vpu_class;
  190377. +static struct vpu_priv vpu_data;
  190378. +static u8 open_count;
  190379. +static struct clk *vpu_clk;
  190380. +static struct vpu_mem_desc bitwork_mem = { 0 };
  190381. +static struct vpu_mem_desc pic_para_mem = { 0 };
  190382. +static struct vpu_mem_desc user_data_mem = { 0 };
  190383. +static struct vpu_mem_desc share_mem = { 0 };
  190384. +static struct vpu_mem_desc vshare_mem = { 0 };
  190385. +
  190386. +static void __iomem *vpu_base;
  190387. +static int vpu_ipi_irq;
  190388. +static u32 phy_vpu_base_addr;
  190389. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  190390. +static phys_addr_t top_address_DRAM;
  190391. +static struct mxc_vpu_platform_data *vpu_plat;
  190392. +#endif
  190393. +
  190394. +static struct device *vpu_dev;
  190395. +
  190396. +/* IRAM setting */
  190397. +static struct iram_setting iram;
  190398. +
  190399. +/* implement the blocking ioctl */
  190400. +static int irq_status;
  190401. +static int codec_done;
  190402. +static wait_queue_head_t vpu_queue;
  190403. +
  190404. +#ifdef CONFIG_SOC_IMX6Q
  190405. +#define MXC_VPU_HAS_JPU
  190406. +#endif
  190407. +
  190408. +#ifdef MXC_VPU_HAS_JPU
  190409. +static int vpu_jpu_irq;
  190410. +#endif
  190411. +
  190412. +#ifdef CONFIG_PM
  190413. +static unsigned int regBk[64];
  190414. +static unsigned int pc_before_suspend;
  190415. +#endif
  190416. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  190417. +static struct regulator *vpu_regulator;
  190418. +#endif
  190419. +static atomic_t clk_cnt_from_ioc = ATOMIC_INIT(0);
  190420. +
  190421. +#define READ_REG(x) readl_relaxed(vpu_base + x)
  190422. +#define WRITE_REG(val, x) writel_relaxed(val, vpu_base + x)
  190423. +
  190424. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  190425. +/* redirect to static functions */
  190426. +static int cpu_is_mx6dl(void)
  190427. +{
  190428. + int ret;
  190429. + ret = of_machine_is_compatible("fsl,imx6dl");
  190430. + return ret;
  190431. +}
  190432. +
  190433. +static int cpu_is_mx6q(void)
  190434. +{
  190435. + int ret;
  190436. + ret = of_machine_is_compatible("fsl,imx6q");
  190437. + return ret;
  190438. +}
  190439. +#endif
  190440. +
  190441. +static void vpu_reset(void)
  190442. +{
  190443. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  190444. + device_reset(vpu_dev);
  190445. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  190446. + imx_src_reset_vpu();
  190447. +#else
  190448. + if (vpu_plat->reset)
  190449. + vpu_plat->reset();
  190450. +#endif
  190451. +}
  190452. +
  190453. +static long vpu_power_get(bool on)
  190454. +{
  190455. + long ret = 0;
  190456. +
  190457. + if (on) {
  190458. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  190459. + vpu_regulator = regulator_get(NULL, "cpu_vddvpu");
  190460. + ret = IS_ERR(vpu_regulator);
  190461. +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  190462. + vpu_regulator = devm_regulator_get(vpu_dev, "pu");
  190463. + ret = IS_ERR(vpu_regulator);
  190464. +#endif
  190465. + } else {
  190466. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  190467. + if (!IS_ERR(vpu_regulator))
  190468. + regulator_put(vpu_regulator);
  190469. +#endif
  190470. + }
  190471. + return ret;
  190472. +}
  190473. +
  190474. +static void vpu_power_up(bool on)
  190475. +{
  190476. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  190477. + int ret = 0;
  190478. +
  190479. + if (on) {
  190480. + if (!IS_ERR(vpu_regulator)) {
  190481. + ret = regulator_enable(vpu_regulator);
  190482. + if (ret)
  190483. + dev_err(vpu_dev, "failed to power up vpu\n");
  190484. + }
  190485. + } else {
  190486. + if (!IS_ERR(vpu_regulator)) {
  190487. + ret = regulator_disable(vpu_regulator);
  190488. + if (ret)
  190489. + dev_err(vpu_dev, "failed to power down vpu\n");
  190490. + }
  190491. + }
  190492. +#else
  190493. + imx_gpc_power_up_pu(on);
  190494. +#endif
  190495. +}
  190496. +
  190497. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  190498. +static int cpu_is_mx53(void)
  190499. +{
  190500. + return 0;
  190501. +}
  190502. +
  190503. +static int cpu_is_mx51(void)
  190504. +{
  190505. + return 0;
  190506. +}
  190507. +
  190508. +#define VM_RESERVED 0
  190509. +#endif
  190510. +
  190511. +/*!
  190512. + * Private function to alloc dma buffer
  190513. + * @return status 0 success.
  190514. + */
  190515. +static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem)
  190516. +{
  190517. + mem->cpu_addr = (unsigned long)
  190518. + dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size),
  190519. + (dma_addr_t *) (&mem->phy_addr),
  190520. + GFP_DMA | GFP_KERNEL);
  190521. + dev_dbg(vpu_dev, "[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr);
  190522. + if ((void *)(mem->cpu_addr) == NULL) {
  190523. + dev_err(vpu_dev, "Physical memory allocation error!\n");
  190524. + return -1;
  190525. + }
  190526. + return 0;
  190527. +}
  190528. +
  190529. +/*!
  190530. + * Private function to free dma buffer
  190531. + */
  190532. +static void vpu_free_dma_buffer(struct vpu_mem_desc *mem)
  190533. +{
  190534. + if (mem->cpu_addr != 0) {
  190535. + dma_free_coherent(0, PAGE_ALIGN(mem->size),
  190536. + (void *)mem->cpu_addr, mem->phy_addr);
  190537. + }
  190538. +}
  190539. +
  190540. +/*!
  190541. + * Private function to free buffers
  190542. + * @return status 0 success.
  190543. + */
  190544. +static int vpu_free_buffers(void)
  190545. +{
  190546. + struct memalloc_record *rec, *n;
  190547. + struct vpu_mem_desc mem;
  190548. +
  190549. + list_for_each_entry_safe(rec, n, &head, list) {
  190550. + mem = rec->mem;
  190551. + if (mem.cpu_addr != 0) {
  190552. + vpu_free_dma_buffer(&mem);
  190553. + dev_dbg(vpu_dev, "[FREE] freed paddr=0x%08X\n", mem.phy_addr);
  190554. + /* delete from list */
  190555. + list_del(&rec->list);
  190556. + kfree(rec);
  190557. + }
  190558. + }
  190559. +
  190560. + return 0;
  190561. +}
  190562. +
  190563. +static inline void vpu_worker_callback(struct work_struct *w)
  190564. +{
  190565. + struct vpu_priv *dev = container_of(w, struct vpu_priv,
  190566. + work);
  190567. +
  190568. + if (dev->async_queue)
  190569. + kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
  190570. +
  190571. + irq_status = 1;
  190572. + /*
  190573. + * Clock is gated on when dec/enc started, gate it off when
  190574. + * codec is done.
  190575. + */
  190576. + if (codec_done)
  190577. + codec_done = 0;
  190578. +
  190579. + wake_up_interruptible(&vpu_queue);
  190580. +}
  190581. +
  190582. +/*!
  190583. + * @brief vpu interrupt handler
  190584. + */
  190585. +static irqreturn_t vpu_ipi_irq_handler(int irq, void *dev_id)
  190586. +{
  190587. + struct vpu_priv *dev = dev_id;
  190588. + unsigned long reg;
  190589. +
  190590. + reg = READ_REG(BIT_INT_REASON);
  190591. + if (reg & 0x8)
  190592. + codec_done = 1;
  190593. + WRITE_REG(0x1, BIT_INT_CLEAR);
  190594. +
  190595. + queue_work(dev->workqueue, &dev->work);
  190596. +
  190597. + return IRQ_HANDLED;
  190598. +}
  190599. +
  190600. +/*!
  190601. + * @brief vpu jpu interrupt handler
  190602. + */
  190603. +#ifdef MXC_VPU_HAS_JPU
  190604. +static irqreturn_t vpu_jpu_irq_handler(int irq, void *dev_id)
  190605. +{
  190606. + struct vpu_priv *dev = dev_id;
  190607. + unsigned long reg;
  190608. +
  190609. + reg = READ_REG(MJPEG_PIC_STATUS_REG);
  190610. + if (reg & 0x3)
  190611. + codec_done = 1;
  190612. +
  190613. + queue_work(dev->workqueue, &dev->work);
  190614. +
  190615. + return IRQ_HANDLED;
  190616. +}
  190617. +#endif
  190618. +
  190619. +/*!
  190620. + * @brief check phy memory prepare to pass to vpu is valid or not, we
  190621. + * already address some issue that if pass a wrong address to vpu
  190622. + * (like virtual address), system will hang.
  190623. + *
  190624. + * @return true return is a valid phy memory address, false return not.
  190625. + */
  190626. +bool vpu_is_valid_phy_memory(u32 paddr)
  190627. +{
  190628. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  190629. + if (paddr > top_address_DRAM)
  190630. + return false;
  190631. +#endif
  190632. +
  190633. + return true;
  190634. +}
  190635. +
  190636. +/*!
  190637. + * @brief open function for vpu file operation
  190638. + *
  190639. + * @return 0 on success or negative error code on error
  190640. + */
  190641. +static int vpu_open(struct inode *inode, struct file *filp)
  190642. +{
  190643. +
  190644. + mutex_lock(&vpu_data.lock);
  190645. +
  190646. + if (open_count++ == 0) {
  190647. +
  190648. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  190649. + pm_runtime_get_sync(vpu_dev);
  190650. +#endif
  190651. + vpu_power_up(true);
  190652. +
  190653. +#ifdef CONFIG_SOC_IMX6Q
  190654. + clk_prepare(vpu_clk);
  190655. + clk_enable(vpu_clk);
  190656. + if (READ_REG(BIT_CUR_PC))
  190657. + dev_dbg(vpu_dev, "Not power off before vpu open!\n");
  190658. + clk_disable(vpu_clk);
  190659. + clk_unprepare(vpu_clk);
  190660. +#endif
  190661. + }
  190662. +
  190663. + filp->private_data = (void *)(&vpu_data);
  190664. + mutex_unlock(&vpu_data.lock);
  190665. + return 0;
  190666. +}
  190667. +
  190668. +/*!
  190669. + * @brief IO ctrl function for vpu file operation
  190670. + * @param cmd IO ctrl command
  190671. + * @return 0 on success or negative error code on error
  190672. + */
  190673. +static long vpu_ioctl(struct file *filp, u_int cmd,
  190674. + u_long arg)
  190675. +{
  190676. + int ret = 0;
  190677. +
  190678. + switch (cmd) {
  190679. + case VPU_IOC_PHYMEM_ALLOC:
  190680. + {
  190681. + struct memalloc_record *rec;
  190682. +
  190683. + rec = kzalloc(sizeof(*rec), GFP_KERNEL);
  190684. + if (!rec)
  190685. + return -ENOMEM;
  190686. +
  190687. + ret = copy_from_user(&(rec->mem),
  190688. + (struct vpu_mem_desc *)arg,
  190689. + sizeof(struct vpu_mem_desc));
  190690. + if (ret) {
  190691. + kfree(rec);
  190692. + return -EFAULT;
  190693. + }
  190694. +
  190695. + dev_dbg(vpu_dev, "[ALLOC] mem alloc size = 0x%x\n",
  190696. + rec->mem.size);
  190697. +
  190698. + ret = vpu_alloc_dma_buffer(&(rec->mem));
  190699. + if (ret == -1) {
  190700. + kfree(rec);
  190701. + dev_err(vpu_dev,
  190702. + "Physical memory allocation error!\n");
  190703. + break;
  190704. + }
  190705. + ret = copy_to_user((void __user *)arg, &(rec->mem),
  190706. + sizeof(struct vpu_mem_desc));
  190707. + if (ret) {
  190708. + kfree(rec);
  190709. + ret = -EFAULT;
  190710. + break;
  190711. + }
  190712. +
  190713. + mutex_lock(&vpu_data.lock);
  190714. + list_add(&rec->list, &head);
  190715. + mutex_unlock(&vpu_data.lock);
  190716. +
  190717. + break;
  190718. + }
  190719. + case VPU_IOC_PHYMEM_FREE:
  190720. + {
  190721. + struct memalloc_record *rec, *n;
  190722. + struct vpu_mem_desc vpu_mem;
  190723. +
  190724. + ret = copy_from_user(&vpu_mem,
  190725. + (struct vpu_mem_desc *)arg,
  190726. + sizeof(struct vpu_mem_desc));
  190727. + if (ret)
  190728. + return -EACCES;
  190729. +
  190730. + dev_dbg(vpu_dev, "[FREE] mem freed cpu_addr = 0x%x\n",
  190731. + vpu_mem.cpu_addr);
  190732. + if ((void *)vpu_mem.cpu_addr != NULL)
  190733. + vpu_free_dma_buffer(&vpu_mem);
  190734. +
  190735. + mutex_lock(&vpu_data.lock);
  190736. + list_for_each_entry_safe(rec, n, &head, list) {
  190737. + if (rec->mem.cpu_addr == vpu_mem.cpu_addr) {
  190738. + /* delete from list */
  190739. + list_del(&rec->list);
  190740. + kfree(rec);
  190741. + break;
  190742. + }
  190743. + }
  190744. + mutex_unlock(&vpu_data.lock);
  190745. +
  190746. + break;
  190747. + }
  190748. + case VPU_IOC_WAIT4INT:
  190749. + {
  190750. + u_long timeout = (u_long) arg;
  190751. + if (!wait_event_interruptible_timeout
  190752. + (vpu_queue, irq_status != 0,
  190753. + msecs_to_jiffies(timeout))) {
  190754. + dev_warn(vpu_dev, "VPU blocking: timeout.\n");
  190755. + ret = -ETIME;
  190756. + } else if (signal_pending(current)) {
  190757. + dev_warn(vpu_dev, "VPU interrupt received.\n");
  190758. + ret = -ERESTARTSYS;
  190759. + } else
  190760. + irq_status = 0;
  190761. + break;
  190762. + }
  190763. + case VPU_IOC_IRAM_SETTING:
  190764. + {
  190765. + ret = copy_to_user((void __user *)arg, &iram,
  190766. + sizeof(struct iram_setting));
  190767. + if (ret)
  190768. + ret = -EFAULT;
  190769. +
  190770. + break;
  190771. + }
  190772. + case VPU_IOC_CLKGATE_SETTING:
  190773. + {
  190774. + u32 clkgate_en;
  190775. +
  190776. + if (get_user(clkgate_en, (u32 __user *) arg))
  190777. + return -EFAULT;
  190778. +
  190779. + if (clkgate_en) {
  190780. + clk_prepare(vpu_clk);
  190781. + clk_enable(vpu_clk);
  190782. + atomic_inc(&clk_cnt_from_ioc);
  190783. + } else {
  190784. + clk_disable(vpu_clk);
  190785. + clk_unprepare(vpu_clk);
  190786. + atomic_dec(&clk_cnt_from_ioc);
  190787. + }
  190788. +
  190789. + break;
  190790. + }
  190791. + case VPU_IOC_GET_SHARE_MEM:
  190792. + {
  190793. + mutex_lock(&vpu_data.lock);
  190794. + if (share_mem.cpu_addr != 0) {
  190795. + ret = copy_to_user((void __user *)arg,
  190796. + &share_mem,
  190797. + sizeof(struct vpu_mem_desc));
  190798. + mutex_unlock(&vpu_data.lock);
  190799. + break;
  190800. + } else {
  190801. + if (copy_from_user(&share_mem,
  190802. + (struct vpu_mem_desc *)arg,
  190803. + sizeof(struct vpu_mem_desc))) {
  190804. + mutex_unlock(&vpu_data.lock);
  190805. + return -EFAULT;
  190806. + }
  190807. + if (vpu_alloc_dma_buffer(&share_mem) == -1)
  190808. + ret = -EFAULT;
  190809. + else {
  190810. + if (copy_to_user((void __user *)arg,
  190811. + &share_mem,
  190812. + sizeof(struct
  190813. + vpu_mem_desc)))
  190814. + ret = -EFAULT;
  190815. + }
  190816. + }
  190817. + mutex_unlock(&vpu_data.lock);
  190818. + break;
  190819. + }
  190820. + case VPU_IOC_REQ_VSHARE_MEM:
  190821. + {
  190822. + mutex_lock(&vpu_data.lock);
  190823. + if (vshare_mem.cpu_addr != 0) {
  190824. + ret = copy_to_user((void __user *)arg,
  190825. + &vshare_mem,
  190826. + sizeof(struct vpu_mem_desc));
  190827. + mutex_unlock(&vpu_data.lock);
  190828. + break;
  190829. + } else {
  190830. + if (copy_from_user(&vshare_mem,
  190831. + (struct vpu_mem_desc *)arg,
  190832. + sizeof(struct
  190833. + vpu_mem_desc))) {
  190834. + mutex_unlock(&vpu_data.lock);
  190835. + return -EFAULT;
  190836. + }
  190837. + /* vmalloc shared memory if not allocated */
  190838. + if (!vshare_mem.cpu_addr)
  190839. + vshare_mem.cpu_addr =
  190840. + (unsigned long)
  190841. + vmalloc_user(vshare_mem.size);
  190842. + if (copy_to_user
  190843. + ((void __user *)arg, &vshare_mem,
  190844. + sizeof(struct vpu_mem_desc)))
  190845. + ret = -EFAULT;
  190846. + }
  190847. + mutex_unlock(&vpu_data.lock);
  190848. + break;
  190849. + }
  190850. + case VPU_IOC_GET_WORK_ADDR:
  190851. + {
  190852. + if (bitwork_mem.cpu_addr != 0) {
  190853. + ret =
  190854. + copy_to_user((void __user *)arg,
  190855. + &bitwork_mem,
  190856. + sizeof(struct vpu_mem_desc));
  190857. + break;
  190858. + } else {
  190859. + if (copy_from_user(&bitwork_mem,
  190860. + (struct vpu_mem_desc *)arg,
  190861. + sizeof(struct vpu_mem_desc)))
  190862. + return -EFAULT;
  190863. +
  190864. + if (vpu_alloc_dma_buffer(&bitwork_mem) == -1)
  190865. + ret = -EFAULT;
  190866. + else if (copy_to_user((void __user *)arg,
  190867. + &bitwork_mem,
  190868. + sizeof(struct
  190869. + vpu_mem_desc)))
  190870. + ret = -EFAULT;
  190871. + }
  190872. + break;
  190873. + }
  190874. + /*
  190875. + * The following two ioctl is used when user allocates working buffer
  190876. + * and register it to vpu driver.
  190877. + */
  190878. + case VPU_IOC_QUERY_BITWORK_MEM:
  190879. + {
  190880. + if (copy_to_user((void __user *)arg,
  190881. + &bitwork_mem,
  190882. + sizeof(struct vpu_mem_desc)))
  190883. + ret = -EFAULT;
  190884. + break;
  190885. + }
  190886. + case VPU_IOC_SET_BITWORK_MEM:
  190887. + {
  190888. + if (copy_from_user(&bitwork_mem,
  190889. + (struct vpu_mem_desc *)arg,
  190890. + sizeof(struct vpu_mem_desc)))
  190891. + ret = -EFAULT;
  190892. + break;
  190893. + }
  190894. + case VPU_IOC_SYS_SW_RESET:
  190895. + {
  190896. + vpu_reset();
  190897. + break;
  190898. + }
  190899. + case VPU_IOC_REG_DUMP:
  190900. + break;
  190901. + case VPU_IOC_PHYMEM_DUMP:
  190902. + break;
  190903. + case VPU_IOC_PHYMEM_CHECK:
  190904. + {
  190905. + struct vpu_mem_desc check_memory;
  190906. + ret = copy_from_user(&check_memory,
  190907. + (void __user *)arg,
  190908. + sizeof(struct vpu_mem_desc));
  190909. + if (ret != 0) {
  190910. + dev_err(vpu_dev, "copy from user failure:%d\n", ret);
  190911. + ret = -EFAULT;
  190912. + break;
  190913. + }
  190914. + ret = vpu_is_valid_phy_memory((u32)check_memory.phy_addr);
  190915. +
  190916. + dev_dbg(vpu_dev, "vpu: memory phy:0x%x %s phy memory\n",
  190917. + check_memory.phy_addr, (ret ? "is" : "isn't"));
  190918. + /* borrow .size to pass back the result. */
  190919. + check_memory.size = ret;
  190920. + ret = copy_to_user((void __user *)arg, &check_memory,
  190921. + sizeof(struct vpu_mem_desc));
  190922. + if (ret) {
  190923. + ret = -EFAULT;
  190924. + break;
  190925. + }
  190926. + break;
  190927. + }
  190928. + case VPU_IOC_LOCK_DEV:
  190929. + {
  190930. + u32 lock_en;
  190931. +
  190932. + if (get_user(lock_en, (u32 __user *) arg))
  190933. + return -EFAULT;
  190934. +
  190935. + if (lock_en)
  190936. + mutex_lock(&vpu_data.lock);
  190937. + else
  190938. + mutex_unlock(&vpu_data.lock);
  190939. +
  190940. + break;
  190941. + }
  190942. + default:
  190943. + {
  190944. + dev_err(vpu_dev, "No such IOCTL, cmd is %d\n", cmd);
  190945. + ret = -EINVAL;
  190946. + break;
  190947. + }
  190948. + }
  190949. + return ret;
  190950. +}
  190951. +
  190952. +/*!
  190953. + * @brief Release function for vpu file operation
  190954. + * @return 0 on success or negative error code on error
  190955. + */
  190956. +static int vpu_release(struct inode *inode, struct file *filp)
  190957. +{
  190958. + int i;
  190959. + unsigned long timeout;
  190960. +
  190961. + mutex_lock(&vpu_data.lock);
  190962. +
  190963. + if (open_count > 0 && !(--open_count)) {
  190964. +
  190965. + /* Wait for vpu go to idle state */
  190966. + clk_prepare(vpu_clk);
  190967. + clk_enable(vpu_clk);
  190968. + if (READ_REG(BIT_CUR_PC)) {
  190969. +
  190970. + timeout = jiffies + HZ;
  190971. + while (READ_REG(BIT_BUSY_FLAG)) {
  190972. + msleep(1);
  190973. + if (time_after(jiffies, timeout)) {
  190974. + dev_warn(vpu_dev, "VPU timeout during release\n");
  190975. + break;
  190976. + }
  190977. + }
  190978. + clk_disable(vpu_clk);
  190979. + clk_unprepare(vpu_clk);
  190980. +
  190981. + /* Clean up interrupt */
  190982. + cancel_work_sync(&vpu_data.work);
  190983. + flush_workqueue(vpu_data.workqueue);
  190984. + irq_status = 0;
  190985. +
  190986. + clk_prepare(vpu_clk);
  190987. + clk_enable(vpu_clk);
  190988. + if (READ_REG(BIT_BUSY_FLAG)) {
  190989. +
  190990. + if (cpu_is_mx51() || cpu_is_mx53()) {
  190991. + dev_err(vpu_dev,
  190992. + "fatal error: can't gate/power off when VPU is busy\n");
  190993. + clk_disable(vpu_clk);
  190994. + clk_unprepare(vpu_clk);
  190995. + mutex_unlock(&vpu_data.lock);
  190996. + return -EFAULT;
  190997. + }
  190998. +
  190999. +#ifdef CONFIG_SOC_IMX6Q
  191000. + if (cpu_is_mx6dl() || cpu_is_mx6q()) {
  191001. + WRITE_REG(0x11, 0x10F0);
  191002. + timeout = jiffies + HZ;
  191003. + while (READ_REG(0x10F4) != 0x77) {
  191004. + msleep(1);
  191005. + if (time_after(jiffies, timeout))
  191006. + break;
  191007. + }
  191008. +
  191009. + if (READ_REG(0x10F4) != 0x77) {
  191010. + dev_err(vpu_dev,
  191011. + "fatal error: can't gate/power off when VPU is busy\n");
  191012. + WRITE_REG(0x0, 0x10F0);
  191013. + clk_disable(vpu_clk);
  191014. + clk_unprepare(vpu_clk);
  191015. + mutex_unlock(&vpu_data.lock);
  191016. + return -EFAULT;
  191017. + } else
  191018. + vpu_reset();
  191019. + }
  191020. +#endif
  191021. + }
  191022. + }
  191023. + clk_disable(vpu_clk);
  191024. + clk_unprepare(vpu_clk);
  191025. +
  191026. + vpu_free_buffers();
  191027. +
  191028. + /* Free shared memory when vpu device is idle */
  191029. + vpu_free_dma_buffer(&share_mem);
  191030. + share_mem.cpu_addr = 0;
  191031. + vfree((void *)vshare_mem.cpu_addr);
  191032. + vshare_mem.cpu_addr = 0;
  191033. +
  191034. + vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
  191035. + for (i = 0; i < vpu_clk_usercount; i++) {
  191036. + clk_disable(vpu_clk);
  191037. + clk_unprepare(vpu_clk);
  191038. + atomic_dec(&clk_cnt_from_ioc);
  191039. + }
  191040. +
  191041. + vpu_power_up(false);
  191042. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191043. + pm_runtime_put_sync_suspend(vpu_dev);
  191044. +#endif
  191045. +
  191046. + }
  191047. + mutex_unlock(&vpu_data.lock);
  191048. +
  191049. + return 0;
  191050. +}
  191051. +
  191052. +/*!
  191053. + * @brief fasync function for vpu file operation
  191054. + * @return 0 on success or negative error code on error
  191055. + */
  191056. +static int vpu_fasync(int fd, struct file *filp, int mode)
  191057. +{
  191058. + struct vpu_priv *dev = (struct vpu_priv *)filp->private_data;
  191059. + return fasync_helper(fd, filp, mode, &dev->async_queue);
  191060. +}
  191061. +
  191062. +/*!
  191063. + * @brief memory map function of harware registers for vpu file operation
  191064. + * @return 0 on success or negative error code on error
  191065. + */
  191066. +static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
  191067. +{
  191068. + unsigned long pfn;
  191069. +
  191070. + vm->vm_flags |= VM_IO | VM_RESERVED;
  191071. + /*
  191072. + * Since vpu registers have been mapped with ioremap() at probe
  191073. + * which L_PTE_XN is 1, and the same physical address must be
  191074. + * mapped multiple times with same type, so set L_PTE_XN to 1 here.
  191075. + * Otherwise, there may be unexpected result in video codec.
  191076. + */
  191077. + vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
  191078. + pfn = phy_vpu_base_addr >> PAGE_SHIFT;
  191079. + dev_dbg(vpu_dev, "size=0x%x, page no.=0x%x\n",
  191080. + (int)(vm->vm_end - vm->vm_start), (int)pfn);
  191081. + return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start,
  191082. + vm->vm_page_prot) ? -EAGAIN : 0;
  191083. +}
  191084. +
  191085. +/*!
  191086. + * @brief memory map function of memory for vpu file operation
  191087. + * @return 0 on success or negative error code on error
  191088. + */
  191089. +static int vpu_map_dma_mem(struct file *fp, struct vm_area_struct *vm)
  191090. +{
  191091. + int request_size;
  191092. + request_size = vm->vm_end - vm->vm_start;
  191093. +
  191094. + dev_dbg(vpu_dev, "start=0x%x, pgoff=0x%x, size=0x%x\n",
  191095. + (unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff),
  191096. + request_size);
  191097. +
  191098. + vm->vm_flags |= VM_IO | VM_RESERVED;
  191099. + vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot);
  191100. +
  191101. + return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff,
  191102. + request_size, vm->vm_page_prot) ? -EAGAIN : 0;
  191103. +
  191104. +}
  191105. +
  191106. +/* !
  191107. + * @brief memory map function of vmalloced share memory
  191108. + * @return 0 on success or negative error code on error
  191109. + */
  191110. +static int vpu_map_vshare_mem(struct file *fp, struct vm_area_struct *vm)
  191111. +{
  191112. + int ret = -EINVAL;
  191113. +
  191114. + ret = remap_vmalloc_range(vm, (void *)(vm->vm_pgoff << PAGE_SHIFT), 0);
  191115. + vm->vm_flags |= VM_IO;
  191116. +
  191117. + return ret;
  191118. +}
  191119. +/*!
  191120. + * @brief memory map interface for vpu file operation
  191121. + * @return 0 on success or negative error code on error
  191122. + */
  191123. +static int vpu_mmap(struct file *fp, struct vm_area_struct *vm)
  191124. +{
  191125. + unsigned long offset;
  191126. +
  191127. + offset = vshare_mem.cpu_addr >> PAGE_SHIFT;
  191128. +
  191129. + if (vm->vm_pgoff && (vm->vm_pgoff == offset))
  191130. + return vpu_map_vshare_mem(fp, vm);
  191131. + else if (vm->vm_pgoff)
  191132. + return vpu_map_dma_mem(fp, vm);
  191133. + else
  191134. + return vpu_map_hwregs(fp, vm);
  191135. +}
  191136. +
  191137. +const struct file_operations vpu_fops = {
  191138. + .owner = THIS_MODULE,
  191139. + .open = vpu_open,
  191140. + .unlocked_ioctl = vpu_ioctl,
  191141. + .release = vpu_release,
  191142. + .fasync = vpu_fasync,
  191143. + .mmap = vpu_mmap,
  191144. +};
  191145. +
  191146. +/*!
  191147. + * This function is called by the driver framework to initialize the vpu device.
  191148. + * @param dev The device structure for the vpu passed in by the framework.
  191149. + * @return 0 on success or negative error code on error
  191150. + */
  191151. +static int vpu_dev_probe(struct platform_device *pdev)
  191152. +{
  191153. + int err = 0;
  191154. + struct device *temp_class;
  191155. + struct resource *res;
  191156. + unsigned long addr = 0;
  191157. +
  191158. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191159. + struct device_node *np = pdev->dev.of_node;
  191160. + u32 iramsize;
  191161. +
  191162. + err = of_property_read_u32(np, "iramsize", (u32 *)&iramsize);
  191163. + if (!err && iramsize)
  191164. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  191165. + {
  191166. + iram_pool = of_get_named_gen_pool(np, "iram", 0);
  191167. + if (!iram_pool) {
  191168. + dev_err(&pdev->dev, "iram pool not available\n");
  191169. + return -ENOMEM;
  191170. + }
  191171. +
  191172. + iram_base = gen_pool_alloc(iram_pool, iramsize);
  191173. + if (!iram_base) {
  191174. + dev_err(&pdev->dev, "unable to alloc iram\n");
  191175. + return -ENOMEM;
  191176. + }
  191177. +
  191178. + addr = gen_pool_virt_to_phys(iram_pool, iram_base);
  191179. + }
  191180. +#else
  191181. + iram_alloc(iramsize, &addr);
  191182. +#endif
  191183. + if (addr == 0)
  191184. + iram.start = iram.end = 0;
  191185. + else {
  191186. + iram.start = addr;
  191187. + iram.end = addr + iramsize - 1;
  191188. + }
  191189. +#else
  191190. +
  191191. + vpu_plat = pdev->dev.platform_data;
  191192. +
  191193. + if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
  191194. + iram_alloc(vpu_plat->iram_size, &addr);
  191195. + if (addr == 0)
  191196. + iram.start = iram.end = 0;
  191197. + else {
  191198. + iram.start = addr;
  191199. + iram.end = addr + vpu_plat->iram_size - 1;
  191200. + }
  191201. +#endif
  191202. +
  191203. + vpu_dev = &pdev->dev;
  191204. +
  191205. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu_regs");
  191206. + if (!res) {
  191207. + dev_err(vpu_dev, "vpu: unable to get vpu base addr\n");
  191208. + return -ENODEV;
  191209. + }
  191210. + phy_vpu_base_addr = res->start;
  191211. + vpu_base = ioremap(res->start, res->end - res->start);
  191212. +
  191213. + vpu_major = register_chrdev(vpu_major, "mxc_vpu", &vpu_fops);
  191214. + if (vpu_major < 0) {
  191215. + dev_err(vpu_dev, "vpu: unable to get a major for VPU\n");
  191216. + err = -EBUSY;
  191217. + goto error;
  191218. + }
  191219. +
  191220. + vpu_class = class_create(THIS_MODULE, "mxc_vpu");
  191221. + if (IS_ERR(vpu_class)) {
  191222. + err = PTR_ERR(vpu_class);
  191223. + goto err_out_chrdev;
  191224. + }
  191225. +
  191226. + temp_class = device_create(vpu_class, NULL, MKDEV(vpu_major, 0),
  191227. + NULL, "mxc_vpu");
  191228. + if (IS_ERR(temp_class)) {
  191229. + err = PTR_ERR(temp_class);
  191230. + goto err_out_class;
  191231. + }
  191232. +
  191233. + vpu_clk = clk_get(&pdev->dev, "vpu_clk");
  191234. + if (IS_ERR(vpu_clk)) {
  191235. + err = -ENOENT;
  191236. + goto err_out_class;
  191237. + }
  191238. +
  191239. + vpu_ipi_irq = platform_get_irq_byname(pdev, "vpu_ipi_irq");
  191240. + if (vpu_ipi_irq < 0) {
  191241. + dev_err(vpu_dev, "vpu: unable to get vpu interrupt\n");
  191242. + err = -ENXIO;
  191243. + goto err_out_class;
  191244. + }
  191245. + err = request_irq(vpu_ipi_irq, vpu_ipi_irq_handler, 0, "VPU_CODEC_IRQ",
  191246. + (void *)(&vpu_data));
  191247. + if (err)
  191248. + goto err_out_class;
  191249. + if (vpu_power_get(true)) {
  191250. + if (!(cpu_is_mx51() || cpu_is_mx53())) {
  191251. + dev_err(vpu_dev, "failed to get vpu power\n");
  191252. + goto err_out_class;
  191253. + } else {
  191254. + /* regulator_get will return error on MX5x,
  191255. + * just igore it everywhere*/
  191256. + dev_warn(vpu_dev, "failed to get vpu power\n");
  191257. + }
  191258. + }
  191259. +
  191260. +#ifdef MXC_VPU_HAS_JPU
  191261. + vpu_jpu_irq = platform_get_irq_byname(pdev, "vpu_jpu_irq");
  191262. + if (vpu_jpu_irq < 0) {
  191263. + dev_err(vpu_dev, "vpu: unable to get vpu jpu interrupt\n");
  191264. + err = -ENXIO;
  191265. + free_irq(vpu_ipi_irq, &vpu_data);
  191266. + goto err_out_class;
  191267. + }
  191268. + err = request_irq(vpu_jpu_irq, vpu_jpu_irq_handler, IRQF_TRIGGER_RISING,
  191269. + "VPU_JPG_IRQ", (void *)(&vpu_data));
  191270. + if (err) {
  191271. + free_irq(vpu_ipi_irq, &vpu_data);
  191272. + goto err_out_class;
  191273. + }
  191274. +#endif
  191275. +
  191276. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191277. + pm_runtime_enable(&pdev->dev);
  191278. +#endif
  191279. +
  191280. + vpu_data.workqueue = create_workqueue("vpu_wq");
  191281. + INIT_WORK(&vpu_data.work, vpu_worker_callback);
  191282. + mutex_init(&vpu_data.lock);
  191283. + dev_info(vpu_dev, "VPU initialized\n");
  191284. + goto out;
  191285. +
  191286. +err_out_class:
  191287. + device_destroy(vpu_class, MKDEV(vpu_major, 0));
  191288. + class_destroy(vpu_class);
  191289. +err_out_chrdev:
  191290. + unregister_chrdev(vpu_major, "mxc_vpu");
  191291. +error:
  191292. + iounmap(vpu_base);
  191293. +out:
  191294. + return err;
  191295. +}
  191296. +
  191297. +static int vpu_dev_remove(struct platform_device *pdev)
  191298. +{
  191299. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191300. + pm_runtime_disable(&pdev->dev);
  191301. +#endif
  191302. + free_irq(vpu_ipi_irq, &vpu_data);
  191303. +#ifdef MXC_VPU_HAS_JPU
  191304. + free_irq(vpu_jpu_irq, &vpu_data);
  191305. +#endif
  191306. + cancel_work_sync(&vpu_data.work);
  191307. + flush_workqueue(vpu_data.workqueue);
  191308. + destroy_workqueue(vpu_data.workqueue);
  191309. +
  191310. + iounmap(vpu_base);
  191311. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191312. + if (iram.start)
  191313. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
  191314. + gen_pool_free(iram_pool, iram_base, iram.end-iram.start+1);
  191315. +#else
  191316. + iram_free(iram.start, iram.end-iram.start+1);
  191317. +#endif
  191318. +#else
  191319. + if (vpu_plat && vpu_plat->iram_enable && vpu_plat->iram_size)
  191320. + iram_free(iram.start, vpu_plat->iram_size);
  191321. +#endif
  191322. +
  191323. + vpu_power_get(false);
  191324. + return 0;
  191325. +}
  191326. +
  191327. +#ifdef CONFIG_PM
  191328. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191329. +static int vpu_suspend(struct device *dev)
  191330. +#else
  191331. +static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
  191332. +#endif
  191333. +{
  191334. + int i;
  191335. + unsigned long timeout;
  191336. +
  191337. + mutex_lock(&vpu_data.lock);
  191338. + if (open_count == 0) {
  191339. + /* VPU is released (all instances are freed),
  191340. + * clock is already off, context is no longer needed,
  191341. + * power is already off on MX6,
  191342. + * gate power on MX51 */
  191343. + if (cpu_is_mx51()) {
  191344. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  191345. + if (vpu_plat->pg)
  191346. + vpu_plat->pg(1);
  191347. +#endif
  191348. + }
  191349. + } else {
  191350. + /* Wait for vpu go to idle state, suspect vpu cannot be changed
  191351. + to idle state after about 1 sec */
  191352. + timeout = jiffies + HZ;
  191353. + clk_prepare(vpu_clk);
  191354. + clk_enable(vpu_clk);
  191355. + while (READ_REG(BIT_BUSY_FLAG)) {
  191356. + msleep(1);
  191357. + if (time_after(jiffies, timeout)) {
  191358. + clk_disable(vpu_clk);
  191359. + clk_unprepare(vpu_clk);
  191360. + mutex_unlock(&vpu_data.lock);
  191361. + return -EAGAIN;
  191362. + }
  191363. + }
  191364. + clk_disable(vpu_clk);
  191365. + clk_unprepare(vpu_clk);
  191366. +
  191367. + /* Make sure clock is disabled before suspend */
  191368. + vpu_clk_usercount = atomic_read(&clk_cnt_from_ioc);
  191369. + for (i = 0; i < vpu_clk_usercount; i++) {
  191370. + clk_disable(vpu_clk);
  191371. + clk_unprepare(vpu_clk);
  191372. + }
  191373. +
  191374. + if (cpu_is_mx53()) {
  191375. + mutex_unlock(&vpu_data.lock);
  191376. + return 0;
  191377. + }
  191378. +
  191379. + if (bitwork_mem.cpu_addr != 0) {
  191380. + clk_prepare(vpu_clk);
  191381. + clk_enable(vpu_clk);
  191382. + /* Save 64 registers from BIT_CODE_BUF_ADDR */
  191383. + for (i = 0; i < 64; i++)
  191384. + regBk[i] = READ_REG(BIT_CODE_BUF_ADDR + (i * 4));
  191385. + pc_before_suspend = READ_REG(BIT_CUR_PC);
  191386. + clk_disable(vpu_clk);
  191387. + clk_unprepare(vpu_clk);
  191388. + }
  191389. +
  191390. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  191391. + if (vpu_plat->pg)
  191392. + vpu_plat->pg(1);
  191393. +#endif
  191394. +
  191395. + /* If VPU is working before suspend, disable
  191396. + * regulator to make usecount right. */
  191397. + vpu_power_up(false);
  191398. + }
  191399. +
  191400. + mutex_unlock(&vpu_data.lock);
  191401. + return 0;
  191402. +}
  191403. +
  191404. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191405. +static int vpu_resume(struct device *dev)
  191406. +#else
  191407. +static int vpu_resume(struct platform_device *pdev)
  191408. +#endif
  191409. +{
  191410. + int i;
  191411. +
  191412. + mutex_lock(&vpu_data.lock);
  191413. + if (open_count == 0) {
  191414. + /* VPU is released (all instances are freed),
  191415. + * clock should be kept off, context is no longer needed,
  191416. + * power should be kept off on MX6,
  191417. + * disable power gating on MX51 */
  191418. + if (cpu_is_mx51()) {
  191419. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  191420. + if (vpu_plat->pg)
  191421. + vpu_plat->pg(0);
  191422. +#endif
  191423. + }
  191424. + } else {
  191425. + if (cpu_is_mx53())
  191426. + goto recover_clk;
  191427. +
  191428. + /* If VPU is working before suspend, enable
  191429. + * regulator to make usecount right. */
  191430. + vpu_power_up(true);
  191431. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  191432. + if (vpu_plat->pg)
  191433. + vpu_plat->pg(0);
  191434. +#endif
  191435. +
  191436. + if (bitwork_mem.cpu_addr != 0) {
  191437. + u32 *p = (u32 *) bitwork_mem.cpu_addr;
  191438. + u32 data, pc;
  191439. + u16 data_hi;
  191440. + u16 data_lo;
  191441. +
  191442. + clk_prepare(vpu_clk);
  191443. + clk_enable(vpu_clk);
  191444. +
  191445. + pc = READ_REG(BIT_CUR_PC);
  191446. + if (pc) {
  191447. + dev_warn(vpu_dev, "Not power off after suspend (PC=0x%x)\n", pc);
  191448. + clk_disable(vpu_clk);
  191449. + clk_unprepare(vpu_clk);
  191450. + goto recover_clk;
  191451. + }
  191452. +
  191453. + /* Restore registers */
  191454. + for (i = 0; i < 64; i++)
  191455. + WRITE_REG(regBk[i], BIT_CODE_BUF_ADDR + (i * 4));
  191456. +
  191457. + WRITE_REG(0x0, BIT_RESET_CTRL);
  191458. + WRITE_REG(0x0, BIT_CODE_RUN);
  191459. + /* MX6 RTL has a bug not to init MBC_SET_SUBBLK_EN on reset */
  191460. +#ifdef CONFIG_SOC_IMX6Q
  191461. + WRITE_REG(0x0, MBC_SET_SUBBLK_EN);
  191462. +#endif
  191463. +
  191464. + /*
  191465. + * Re-load boot code, from the codebuffer in external RAM.
  191466. + * Thankfully, we only need 4096 bytes, same for all platforms.
  191467. + */
  191468. + for (i = 0; i < 2048; i += 4) {
  191469. + data = p[(i / 2) + 1];
  191470. + data_hi = (data >> 16) & 0xFFFF;
  191471. + data_lo = data & 0xFFFF;
  191472. + WRITE_REG((i << 16) | data_hi, BIT_CODE_DOWN);
  191473. + WRITE_REG(((i + 1) << 16) | data_lo,
  191474. + BIT_CODE_DOWN);
  191475. +
  191476. + data = p[i / 2];
  191477. + data_hi = (data >> 16) & 0xFFFF;
  191478. + data_lo = data & 0xFFFF;
  191479. + WRITE_REG(((i + 2) << 16) | data_hi,
  191480. + BIT_CODE_DOWN);
  191481. + WRITE_REG(((i + 3) << 16) | data_lo,
  191482. + BIT_CODE_DOWN);
  191483. + }
  191484. +
  191485. + if (pc_before_suspend) {
  191486. + WRITE_REG(0x1, BIT_BUSY_FLAG);
  191487. + WRITE_REG(0x1, BIT_CODE_RUN);
  191488. + while (READ_REG(BIT_BUSY_FLAG))
  191489. + ;
  191490. + } else {
  191491. + dev_warn(vpu_dev, "PC=0 before suspend\n");
  191492. + }
  191493. + clk_disable(vpu_clk);
  191494. + clk_unprepare(vpu_clk);
  191495. + }
  191496. +
  191497. +recover_clk:
  191498. + /* Recover vpu clock */
  191499. + for (i = 0; i < vpu_clk_usercount; i++) {
  191500. + clk_prepare(vpu_clk);
  191501. + clk_enable(vpu_clk);
  191502. + }
  191503. + }
  191504. +
  191505. + mutex_unlock(&vpu_data.lock);
  191506. + return 0;
  191507. +}
  191508. +
  191509. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191510. +static int vpu_runtime_suspend(struct device *dev)
  191511. +{
  191512. + release_bus_freq(BUS_FREQ_HIGH);
  191513. + return 0;
  191514. +}
  191515. +
  191516. +static int vpu_runtime_resume(struct device *dev)
  191517. +{
  191518. + request_bus_freq(BUS_FREQ_HIGH);
  191519. + return 0;
  191520. +}
  191521. +
  191522. +static const struct dev_pm_ops vpu_pm_ops = {
  191523. + SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
  191524. + SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
  191525. +};
  191526. +#endif
  191527. +
  191528. +#else
  191529. +#define vpu_suspend NULL
  191530. +#define vpu_resume NULL
  191531. +#endif /* !CONFIG_PM */
  191532. +
  191533. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191534. +static const struct of_device_id vpu_of_match[] = {
  191535. + { .compatible = "fsl,imx6-vpu", },
  191536. + {/* sentinel */}
  191537. +};
  191538. +MODULE_DEVICE_TABLE(of, vpu_of_match);
  191539. +#endif
  191540. +
  191541. +/*! Driver definition
  191542. + *
  191543. + */
  191544. +static struct platform_driver mxcvpu_driver = {
  191545. + .driver = {
  191546. + .name = "mxc_vpu",
  191547. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
  191548. + .of_match_table = vpu_of_match,
  191549. +#ifdef CONFIG_PM
  191550. + .pm = &vpu_pm_ops,
  191551. +#endif
  191552. +#endif
  191553. + },
  191554. + .probe = vpu_dev_probe,
  191555. + .remove = vpu_dev_remove,
  191556. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  191557. + .suspend = vpu_suspend,
  191558. + .resume = vpu_resume,
  191559. +#endif
  191560. +};
  191561. +
  191562. +static int __init vpu_init(void)
  191563. +{
  191564. + int ret = platform_driver_register(&mxcvpu_driver);
  191565. +
  191566. + init_waitqueue_head(&vpu_queue);
  191567. +
  191568. +
  191569. +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
  191570. + memblock_analyze();
  191571. + top_address_DRAM = memblock_end_of_DRAM_with_reserved();
  191572. +#endif
  191573. +
  191574. + return ret;
  191575. +}
  191576. +
  191577. +static void __exit vpu_exit(void)
  191578. +{
  191579. + if (vpu_major > 0) {
  191580. + device_destroy(vpu_class, MKDEV(vpu_major, 0));
  191581. + class_destroy(vpu_class);
  191582. + unregister_chrdev(vpu_major, "mxc_vpu");
  191583. + vpu_major = 0;
  191584. + }
  191585. +
  191586. + vpu_free_dma_buffer(&bitwork_mem);
  191587. + vpu_free_dma_buffer(&pic_para_mem);
  191588. + vpu_free_dma_buffer(&user_data_mem);
  191589. +
  191590. + /* reset VPU state */
  191591. + vpu_power_up(true);
  191592. + clk_prepare(vpu_clk);
  191593. + clk_enable(vpu_clk);
  191594. + vpu_reset();
  191595. + clk_disable(vpu_clk);
  191596. + clk_unprepare(vpu_clk);
  191597. + vpu_power_up(false);
  191598. +
  191599. + clk_put(vpu_clk);
  191600. +
  191601. + platform_driver_unregister(&mxcvpu_driver);
  191602. + return;
  191603. +}
  191604. +
  191605. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  191606. +MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
  191607. +MODULE_LICENSE("GPL");
  191608. +
  191609. +module_init(vpu_init);
  191610. +module_exit(vpu_exit);
  191611. diff -Nur linux-3.14.17/drivers/net/bonding/bonding.h linux-imx6-3.14/drivers/net/bonding/bonding.h
  191612. --- linux-3.14.17/drivers/net/bonding/bonding.h 2014-08-14 03:38:34.000000000 +0200
  191613. +++ linux-imx6-3.14/drivers/net/bonding/bonding.h 2014-09-11 18:06:03.218042834 +0200
  191614. @@ -188,7 +188,8 @@
  191615. struct net_device *dev; /* first - useful for panic debug */
  191616. struct bonding *bond; /* our master */
  191617. int delay;
  191618. - unsigned long jiffies;
  191619. + /* all three in jiffies */
  191620. + unsigned long last_link_up;
  191621. unsigned long last_arp_rx;
  191622. unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
  191623. s8 link; /* one of BOND_LINK_XXXX */
  191624. diff -Nur linux-3.14.17/drivers/net/bonding/bond_main.c linux-imx6-3.14/drivers/net/bonding/bond_main.c
  191625. --- linux-3.14.17/drivers/net/bonding/bond_main.c 2014-08-14 03:38:34.000000000 +0200
  191626. +++ linux-imx6-3.14/drivers/net/bonding/bond_main.c 2014-09-11 18:06:03.218042834 +0200
  191627. @@ -798,7 +798,7 @@
  191628. return;
  191629. if (new_active) {
  191630. - new_active->jiffies = jiffies;
  191631. + new_active->last_link_up = jiffies;
  191632. if (new_active->link == BOND_LINK_BACK) {
  191633. if (USES_PRIMARY(bond->params.mode)) {
  191634. @@ -1457,7 +1457,7 @@
  191635. }
  191636. if (new_slave->link != BOND_LINK_DOWN)
  191637. - new_slave->jiffies = jiffies;
  191638. + new_slave->last_link_up = jiffies;
  191639. pr_debug("Initial state of slave_dev is BOND_LINK_%s\n",
  191640. new_slave->link == BOND_LINK_DOWN ? "DOWN" :
  191641. (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
  191642. @@ -1908,7 +1908,7 @@
  191643. * recovered before downdelay expired
  191644. */
  191645. slave->link = BOND_LINK_UP;
  191646. - slave->jiffies = jiffies;
  191647. + slave->last_link_up = jiffies;
  191648. pr_info("%s: link status up again after %d ms for interface %s.\n",
  191649. bond->dev->name,
  191650. (bond->params.downdelay - slave->delay) *
  191651. @@ -1983,7 +1983,7 @@
  191652. case BOND_LINK_UP:
  191653. slave->link = BOND_LINK_UP;
  191654. - slave->jiffies = jiffies;
  191655. + slave->last_link_up = jiffies;
  191656. if (bond->params.mode == BOND_MODE_8023AD) {
  191657. /* prevent it from being the active one */
  191658. @@ -2268,6 +2268,7 @@
  191659. struct slave *slave)
  191660. {
  191661. struct arphdr *arp = (struct arphdr *)skb->data;
  191662. + struct slave *curr_active_slave;
  191663. unsigned char *arp_ptr;
  191664. __be32 sip, tip;
  191665. int alen;
  191666. @@ -2312,6 +2313,8 @@
  191667. bond->params.arp_validate, slave_do_arp_validate(bond, slave),
  191668. &sip, &tip);
  191669. + curr_active_slave = rcu_dereference(bond->curr_active_slave);
  191670. +
  191671. /*
  191672. * Backup slaves won't see the ARP reply, but do come through
  191673. * here for each ARP probe (so we swap the sip/tip to validate
  191674. @@ -2325,11 +2328,12 @@
  191675. * is done to avoid endless looping when we can't reach the
  191676. * arp_ip_target and fool ourselves with our own arp requests.
  191677. */
  191678. +
  191679. if (bond_is_active_slave(slave))
  191680. bond_validate_arp(bond, slave, sip, tip);
  191681. - else if (bond->curr_active_slave &&
  191682. - time_after(slave_last_rx(bond, bond->curr_active_slave),
  191683. - bond->curr_active_slave->jiffies))
  191684. + else if (curr_active_slave &&
  191685. + time_after(slave_last_rx(bond, curr_active_slave),
  191686. + curr_active_slave->last_link_up))
  191687. bond_validate_arp(bond, slave, tip, sip);
  191688. out_unlock:
  191689. @@ -2376,9 +2380,9 @@
  191690. oldcurrent = ACCESS_ONCE(bond->curr_active_slave);
  191691. /* see if any of the previous devices are up now (i.e. they have
  191692. * xmt and rcv traffic). the curr_active_slave does not come into
  191693. - * the picture unless it is null. also, slave->jiffies is not needed
  191694. - * here because we send an arp on each slave and give a slave as
  191695. - * long as it needs to get the tx/rx within the delta.
  191696. + * the picture unless it is null. also, slave->last_link_up is not
  191697. + * needed here because we send an arp on each slave and give a slave
  191698. + * as long as it needs to get the tx/rx within the delta.
  191699. * TODO: what about up/down delay in arp mode? it wasn't here before
  191700. * so it can wait
  191701. */
  191702. @@ -2505,7 +2509,7 @@
  191703. * active. This avoids bouncing, as the last receive
  191704. * times need a full ARP monitor cycle to be updated.
  191705. */
  191706. - if (bond_time_in_interval(bond, slave->jiffies, 2))
  191707. + if (bond_time_in_interval(bond, slave->last_link_up, 2))
  191708. continue;
  191709. /*
  191710. @@ -2698,7 +2702,7 @@
  191711. new_slave->link = BOND_LINK_BACK;
  191712. bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);
  191713. bond_arp_send_all(bond, new_slave);
  191714. - new_slave->jiffies = jiffies;
  191715. + new_slave->last_link_up = jiffies;
  191716. rcu_assign_pointer(bond->current_arp_slave, new_slave);
  191717. check_state:
  191718. diff -Nur linux-3.14.17/drivers/net/can/flexcan.c linux-imx6-3.14/drivers/net/can/flexcan.c
  191719. --- linux-3.14.17/drivers/net/can/flexcan.c 2014-08-14 03:38:34.000000000 +0200
  191720. +++ linux-imx6-3.14/drivers/net/can/flexcan.c 2014-09-11 18:06:03.246042945 +0200
  191721. @@ -125,7 +125,8 @@
  191722. FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
  191723. /* FLEXCAN interrupt flag register (IFLAG) bits */
  191724. -#define FLEXCAN_TX_BUF_ID 8
  191725. +#define FLEXCAN_RESERVED_BUF_ID 8
  191726. +#define FLEXCAN_TX_BUF_ID 13
  191727. #define FLEXCAN_IFLAG_BUF(x) BIT(x)
  191728. #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
  191729. #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
  191730. @@ -162,6 +163,7 @@
  191731. */
  191732. #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
  191733. #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
  191734. +#define FLEXCAN_HAS_ERR005829 BIT(3) /* have errata ERR005829 */
  191735. /* Structure of the message buffer */
  191736. struct flexcan_mb {
  191737. @@ -221,7 +223,7 @@
  191738. };
  191739. static struct flexcan_devtype_data fsl_imx28_devtype_data;
  191740. static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
  191741. - .features = FLEXCAN_HAS_V10_FEATURES,
  191742. + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_ERR005829,
  191743. };
  191744. static const struct can_bittiming_const flexcan_bittiming_const = {
  191745. @@ -428,6 +430,11 @@
  191746. flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
  191747. flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
  191748. + if (priv->devtype_data->features & FLEXCAN_HAS_ERR005829) {
  191749. + writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
  191750. + writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
  191751. + }
  191752. +
  191753. return NETDEV_TX_OK;
  191754. }
  191755. diff -Nur linux-3.14.17/drivers/net/ethernet/adi/bfin_mac.c linux-imx6-3.14/drivers/net/ethernet/adi/bfin_mac.c
  191756. --- linux-3.14.17/drivers/net/ethernet/adi/bfin_mac.c 2014-08-14 03:38:34.000000000 +0200
  191757. +++ linux-imx6-3.14/drivers/net/ethernet/adi/bfin_mac.c 2014-09-11 18:06:03.270043041 +0200
  191758. @@ -1040,6 +1040,7 @@
  191759. .n_alarm = 0,
  191760. .n_ext_ts = 0,
  191761. .n_per_out = 0,
  191762. + .n_pins = 0,
  191763. .pps = 0,
  191764. .adjfreq = bfin_ptp_adjfreq,
  191765. .adjtime = bfin_ptp_adjtime,
  191766. diff -Nur linux-3.14.17/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c linux-imx6-3.14/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
  191767. --- linux-3.14.17/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c 2014-08-14 03:38:34.000000000 +0200
  191768. +++ linux-imx6-3.14/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c 2014-09-11 18:06:03.362043409 +0200
  191769. @@ -223,12 +223,6 @@
  191770. --nbd;
  191771. bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
  191772. - if (tx_buf->flags & BNX2X_HAS_SECOND_PBD) {
  191773. - /* Skip second parse bd... */
  191774. - --nbd;
  191775. - bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
  191776. - }
  191777. -
  191778. /* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
  191779. if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
  191780. tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
  191781. @@ -3874,9 +3868,6 @@
  191782. /* set encapsulation flag in start BD */
  191783. SET_FLAG(tx_start_bd->general_data,
  191784. ETH_TX_START_BD_TUNNEL_EXIST, 1);
  191785. -
  191786. - tx_buf->flags |= BNX2X_HAS_SECOND_PBD;
  191787. -
  191788. nbd++;
  191789. } else if (xmit_type & XMIT_CSUM) {
  191790. /* Set PBD in checksum offload case w/o encapsulation */
  191791. diff -Nur linux-3.14.17/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h linux-imx6-3.14/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
  191792. --- linux-3.14.17/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h 2014-08-14 03:38:34.000000000 +0200
  191793. +++ linux-imx6-3.14/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h 2014-09-11 18:06:03.362043409 +0200
  191794. @@ -337,7 +337,6 @@
  191795. u8 flags;
  191796. /* Set on the first BD descriptor when there is a split BD */
  191797. #define BNX2X_TSO_SPLIT_BD (1<<0)
  191798. -#define BNX2X_HAS_SECOND_PBD (1<<1)
  191799. };
  191800. struct sw_rx_page {
  191801. diff -Nur linux-3.14.17/drivers/net/ethernet/broadcom/tg3.c linux-imx6-3.14/drivers/net/ethernet/broadcom/tg3.c
  191802. --- linux-3.14.17/drivers/net/ethernet/broadcom/tg3.c 2014-08-14 03:38:34.000000000 +0200
  191803. +++ linux-imx6-3.14/drivers/net/ethernet/broadcom/tg3.c 2014-09-11 18:06:03.422043649 +0200
  191804. @@ -6322,6 +6322,7 @@
  191805. .n_alarm = 0,
  191806. .n_ext_ts = 0,
  191807. .n_per_out = 1,
  191808. + .n_pins = 0,
  191809. .pps = 0,
  191810. .adjfreq = tg3_ptp_adjfreq,
  191811. .adjtime = tg3_ptp_adjtime,
  191812. diff -Nur linux-3.14.17/drivers/net/ethernet/brocade/bna/bnad.c linux-imx6-3.14/drivers/net/ethernet/brocade/bna/bnad.c
  191813. --- linux-3.14.17/drivers/net/ethernet/brocade/bna/bnad.c 2014-08-14 03:38:34.000000000 +0200
  191814. +++ linux-imx6-3.14/drivers/net/ethernet/brocade/bna/bnad.c 2014-09-11 18:06:03.426043665 +0200
  191815. @@ -600,9 +600,9 @@
  191816. prefetch(bnad->netdev);
  191817. cq = ccb->sw_q;
  191818. + cmpl = &cq[ccb->producer_index];
  191819. while (packets < budget) {
  191820. - cmpl = &cq[ccb->producer_index];
  191821. if (!cmpl->valid)
  191822. break;
  191823. /* The 'valid' field is set by the adapter, only after writing
  191824. diff -Nur linux-3.14.17/drivers/net/ethernet/cadence/macb.c linux-imx6-3.14/drivers/net/ethernet/cadence/macb.c
  191825. --- linux-3.14.17/drivers/net/ethernet/cadence/macb.c 2014-08-14 03:38:34.000000000 +0200
  191826. +++ linux-imx6-3.14/drivers/net/ethernet/cadence/macb.c 2014-09-11 18:06:03.430043681 +0200
  191827. @@ -605,25 +605,16 @@
  191828. {
  191829. unsigned int entry;
  191830. struct sk_buff *skb;
  191831. - struct macb_dma_desc *desc;
  191832. dma_addr_t paddr;
  191833. while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail, RX_RING_SIZE) > 0) {
  191834. - u32 addr, ctrl;
  191835. -
  191836. entry = macb_rx_ring_wrap(bp->rx_prepared_head);
  191837. - desc = &bp->rx_ring[entry];
  191838. /* Make hw descriptor updates visible to CPU */
  191839. rmb();
  191840. - addr = desc->addr;
  191841. - ctrl = desc->ctrl;
  191842. bp->rx_prepared_head++;
  191843. - if ((addr & MACB_BIT(RX_USED)))
  191844. - continue;
  191845. -
  191846. if (bp->rx_skbuff[entry] == NULL) {
  191847. /* allocate sk_buff for this free entry in ring */
  191848. skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size);
  191849. @@ -704,7 +695,6 @@
  191850. if (!(addr & MACB_BIT(RX_USED)))
  191851. break;
  191852. - desc->addr &= ~MACB_BIT(RX_USED);
  191853. bp->rx_tail++;
  191854. count++;
  191855. diff -Nur linux-3.14.17/drivers/net/ethernet/chelsio/cxgb4vf/sge.c linux-imx6-3.14/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
  191856. --- linux-3.14.17/drivers/net/ethernet/chelsio/cxgb4vf/sge.c 2014-08-14 03:38:34.000000000 +0200
  191857. +++ linux-imx6-3.14/drivers/net/ethernet/chelsio/cxgb4vf/sge.c 2014-09-11 18:06:03.478043873 +0200
  191858. @@ -1510,7 +1510,8 @@
  191859. {
  191860. struct sk_buff *skb;
  191861. const struct cpl_rx_pkt *pkt = (void *)rsp;
  191862. - bool csum_ok = pkt->csum_calc && !pkt->err_vec;
  191863. + bool csum_ok = pkt->csum_calc && !pkt->err_vec &&
  191864. + (rspq->netdev->features & NETIF_F_RXCSUM);
  191865. struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);
  191866. /*
  191867. @@ -1538,8 +1539,8 @@
  191868. skb_record_rx_queue(skb, rspq->idx);
  191869. rxq->stats.pkts++;
  191870. - if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) &&
  191871. - !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
  191872. + if (csum_ok && !pkt->err_vec &&
  191873. + (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
  191874. if (!pkt->ip_frag)
  191875. skb->ip_summed = CHECKSUM_UNNECESSARY;
  191876. else {
  191877. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/fec.h linux-imx6-3.14/drivers/net/ethernet/freescale/fec.h
  191878. --- linux-3.14.17/drivers/net/ethernet/freescale/fec.h 2014-08-14 03:38:34.000000000 +0200
  191879. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fec.h 2014-09-11 18:06:03.498043952 +0200
  191880. @@ -221,7 +221,7 @@
  191881. #define BD_ENET_TX_RCMASK ((ushort)0x003c)
  191882. #define BD_ENET_TX_UN ((ushort)0x0002)
  191883. #define BD_ENET_TX_CSL ((ushort)0x0001)
  191884. -#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */
  191885. +#define BD_ENET_TX_STATS ((ushort)0x0fff) /* All status bits */
  191886. /*enhanced buffer descriptor control/status used by Ethernet transmit*/
  191887. #define BD_ENET_TX_INT 0x40000000
  191888. @@ -246,8 +246,8 @@
  191889. #define RX_RING_SIZE (FEC_ENET_RX_FRPPG * FEC_ENET_RX_PAGES)
  191890. #define FEC_ENET_TX_FRSIZE 2048
  191891. #define FEC_ENET_TX_FRPPG (PAGE_SIZE / FEC_ENET_TX_FRSIZE)
  191892. -#define TX_RING_SIZE 16 /* Must be power of two */
  191893. -#define TX_RING_MOD_MASK 15 /* for this to work */
  191894. +#define TX_RING_SIZE 512 /* Must be power of two */
  191895. +#define TX_RING_MOD_MASK 511 /* for this to work */
  191896. #define BD_ENET_RX_INT 0x00800000
  191897. #define BD_ENET_RX_PTP ((ushort)0x0400)
  191898. @@ -256,12 +256,6 @@
  191899. #define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
  191900. #define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
  191901. -struct fec_enet_delayed_work {
  191902. - struct delayed_work delay_work;
  191903. - bool timeout;
  191904. - bool trig_tx;
  191905. -};
  191906. -
  191907. /* The FEC buffer descriptors track the ring buffers. The rx_bd_base and
  191908. * tx_bd_base always point to the base of the buffer descriptors. The
  191909. * cur_rx and cur_tx point to the currently available buffer.
  191910. @@ -296,12 +290,18 @@
  191911. /* The ring entries to be free()ed */
  191912. struct bufdesc *dirty_tx;
  191913. + unsigned short bufdesc_size;
  191914. unsigned short tx_ring_size;
  191915. unsigned short rx_ring_size;
  191916. + unsigned short tx_stop_threshold;
  191917. + unsigned short tx_wake_threshold;
  191918. +
  191919. + /* Software TSO */
  191920. + char *tso_hdrs;
  191921. + dma_addr_t tso_hdrs_dma;
  191922. struct platform_device *pdev;
  191923. - int opened;
  191924. int dev_id;
  191925. /* Phylib and MDIO interface */
  191926. @@ -321,6 +321,8 @@
  191927. struct napi_struct napi;
  191928. int csum_flags;
  191929. + struct work_struct tx_timeout_work;
  191930. +
  191931. struct ptp_clock *ptp_clock;
  191932. struct ptp_clock_info ptp_caps;
  191933. unsigned long last_overflow_check;
  191934. @@ -333,7 +335,6 @@
  191935. int hwts_rx_en;
  191936. int hwts_tx_en;
  191937. struct timer_list time_keep;
  191938. - struct fec_enet_delayed_work delay_work;
  191939. struct regulator *reg_phy;
  191940. };
  191941. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/fec_main.c linux-imx6-3.14/drivers/net/ethernet/freescale/fec_main.c
  191942. --- linux-3.14.17/drivers/net/ethernet/freescale/fec_main.c 2014-08-14 03:38:34.000000000 +0200
  191943. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fec_main.c 2014-09-11 18:06:03.498043952 +0200
  191944. @@ -36,6 +36,7 @@
  191945. #include <linux/in.h>
  191946. #include <linux/ip.h>
  191947. #include <net/ip.h>
  191948. +#include <net/tso.h>
  191949. #include <linux/tcp.h>
  191950. #include <linux/udp.h>
  191951. #include <linux/icmp.h>
  191952. @@ -54,6 +55,10 @@
  191953. #include <linux/of_net.h>
  191954. #include <linux/regulator/consumer.h>
  191955. #include <linux/if_vlan.h>
  191956. +#include <linux/pinctrl/consumer.h>
  191957. +#include <linux/busfreq-imx6.h>
  191958. +#include <linux/pm_runtime.h>
  191959. +#include <linux/pm_qos.h>
  191960. #include <asm/cacheflush.h>
  191961. @@ -91,6 +96,8 @@
  191962. #define FEC_QUIRK_HAS_CSUM (1 << 5)
  191963. /* Controller has hardware vlan support */
  191964. #define FEC_QUIRK_HAS_VLAN (1 << 6)
  191965. +/* Controller is FEC-MAC */
  191966. +#define FEC_QUIRK_FEC_MAC (1 << 7)
  191967. /* ENET IP errata ERR006358
  191968. *
  191969. * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
  191970. @@ -100,7 +107,13 @@
  191971. * frames not being transmitted until there is a 0-to-1 transition on
  191972. * ENET_TDAR[TDAR].
  191973. */
  191974. -#define FEC_QUIRK_ERR006358 (1 << 7)
  191975. +#define FEC_QUIRK_ERR006358 (1 << 8)
  191976. +/*
  191977. + * i.MX6Q/DL ENET cannot wake up system in wait mode because ENET tx & rx
  191978. + * interrupt signal don't connect to GPC. So use pm qos to avoid cpu enter
  191979. + * to wait mode.
  191980. + */
  191981. +#define FEC_QUIRK_BUG_WAITMODE (1 << 9)
  191982. static struct platform_device_id fec_devtype[] = {
  191983. {
  191984. @@ -109,7 +122,7 @@
  191985. .driver_data = 0,
  191986. }, {
  191987. .name = "imx25-fec",
  191988. - .driver_data = FEC_QUIRK_USE_GASKET,
  191989. + .driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_FEC_MAC,
  191990. }, {
  191991. .name = "imx27-fec",
  191992. .driver_data = 0,
  191993. @@ -120,7 +133,8 @@
  191994. .name = "imx6q-fec",
  191995. .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
  191996. FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
  191997. - FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358,
  191998. + FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
  191999. + FEC_QUIRK_BUG_WAITMODE,
  192000. }, {
  192001. .name = "mvf600-fec",
  192002. .driver_data = FEC_QUIRK_ENET_MAC,
  192003. @@ -172,10 +186,6 @@
  192004. #endif
  192005. #endif /* CONFIG_M5272 */
  192006. -#if (((RX_RING_SIZE + TX_RING_SIZE) * 32) > PAGE_SIZE)
  192007. -#error "FEC: descriptor ring size constants too large"
  192008. -#endif
  192009. -
  192010. /* Interrupt events/masks. */
  192011. #define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
  192012. #define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
  192013. @@ -231,6 +241,15 @@
  192014. #define FEC_PAUSE_FLAG_AUTONEG 0x1
  192015. #define FEC_PAUSE_FLAG_ENABLE 0x2
  192016. +#define TSO_HEADER_SIZE 128
  192017. +/* Max number of allowed TCP segments for software TSO */
  192018. +#define FEC_MAX_TSO_SEGS 100
  192019. +#define FEC_MAX_SKB_DESCS (FEC_MAX_TSO_SEGS * 2 + MAX_SKB_FRAGS)
  192020. +
  192021. +#define IS_TSO_HEADER(txq, addr) \
  192022. + ((addr >= txq->tso_hdrs_dma) && \
  192023. + (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE))
  192024. +
  192025. static int mii_cnt;
  192026. static inline
  192027. @@ -286,6 +305,22 @@
  192028. return (new_bd < base) ? (new_bd + ring_size) : new_bd;
  192029. }
  192030. +static int fec_enet_get_bd_index(struct bufdesc *base, struct bufdesc *bdp,
  192031. + struct fec_enet_private *fep)
  192032. +{
  192033. + return ((const char *)bdp - (const char *)base) / fep->bufdesc_size;
  192034. +}
  192035. +
  192036. +static int fec_enet_get_free_txdesc_num(struct fec_enet_private *fep)
  192037. +{
  192038. + int entries;
  192039. +
  192040. + entries = ((const char *)fep->dirty_tx -
  192041. + (const char *)fep->cur_tx) / fep->bufdesc_size - 1;
  192042. +
  192043. + return entries > 0 ? entries : entries + fep->tx_ring_size;
  192044. +}
  192045. +
  192046. static void *swap_buffer(void *bufaddr, int len)
  192047. {
  192048. int i;
  192049. @@ -297,6 +332,32 @@
  192050. return bufaddr;
  192051. }
  192052. +static void fec_dump(struct net_device *ndev)
  192053. +{
  192054. + struct fec_enet_private *fep = netdev_priv(ndev);
  192055. + struct bufdesc *bdp = fep->tx_bd_base;
  192056. + unsigned int index = 0;
  192057. +
  192058. + netdev_info(ndev, "TX ring dump\n");
  192059. + pr_info("Nr SC addr len SKB\n");
  192060. +
  192061. + do {
  192062. + pr_info("%3u %c%c 0x%04x 0x%08lx %4u %p\n",
  192063. + index,
  192064. + bdp == fep->cur_tx ? 'S' : ' ',
  192065. + bdp == fep->dirty_tx ? 'H' : ' ',
  192066. + bdp->cbd_sc, bdp->cbd_bufaddr, bdp->cbd_datlen,
  192067. + fep->tx_skbuff[index]);
  192068. + bdp = fec_enet_get_nextdesc(bdp, fep);
  192069. + index++;
  192070. + } while (bdp != fep->tx_bd_base);
  192071. +}
  192072. +
  192073. +static inline bool is_ipv4_pkt(struct sk_buff *skb)
  192074. +{
  192075. + return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
  192076. +}
  192077. +
  192078. static int
  192079. fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
  192080. {
  192081. @@ -307,137 +368,419 @@
  192082. if (unlikely(skb_cow_head(skb, 0)))
  192083. return -1;
  192084. + if (is_ipv4_pkt(skb))
  192085. + ip_hdr(skb)->check = 0;
  192086. *(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) = 0;
  192087. return 0;
  192088. }
  192089. -static netdev_tx_t
  192090. -fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  192091. +static int
  192092. +fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
  192093. {
  192094. struct fec_enet_private *fep = netdev_priv(ndev);
  192095. const struct platform_device_id *id_entry =
  192096. platform_get_device_id(fep->pdev);
  192097. - struct bufdesc *bdp, *bdp_pre;
  192098. - void *bufaddr;
  192099. - unsigned short status;
  192100. + struct bufdesc *bdp = fep->cur_tx;
  192101. + struct bufdesc_ex *ebdp;
  192102. + int nr_frags = skb_shinfo(skb)->nr_frags;
  192103. + int frag, frag_len;
  192104. + unsigned short status;
  192105. + unsigned int estatus = 0;
  192106. + skb_frag_t *this_frag;
  192107. unsigned int index;
  192108. + void *bufaddr;
  192109. + dma_addr_t addr;
  192110. + int i;
  192111. - /* Fill in a Tx ring entry */
  192112. + for (frag = 0; frag < nr_frags; frag++) {
  192113. + this_frag = &skb_shinfo(skb)->frags[frag];
  192114. + bdp = fec_enet_get_nextdesc(bdp, fep);
  192115. + ebdp = (struct bufdesc_ex *)bdp;
  192116. +
  192117. + status = bdp->cbd_sc;
  192118. + status &= ~BD_ENET_TX_STATS;
  192119. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  192120. + frag_len = skb_shinfo(skb)->frags[frag].size;
  192121. +
  192122. + /* Handle the last BD specially */
  192123. + if (frag == nr_frags - 1) {
  192124. + status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST);
  192125. + if (fep->bufdesc_ex) {
  192126. + estatus |= BD_ENET_TX_INT;
  192127. + if (unlikely(skb_shinfo(skb)->tx_flags &
  192128. + SKBTX_HW_TSTAMP && fep->hwts_tx_en))
  192129. + estatus |= BD_ENET_TX_TS;
  192130. + }
  192131. + }
  192132. +
  192133. + if (fep->bufdesc_ex) {
  192134. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  192135. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  192136. + ebdp->cbd_bdu = 0;
  192137. + ebdp->cbd_esc = estatus;
  192138. + }
  192139. +
  192140. + bufaddr = page_address(this_frag->page.p) + this_frag->page_offset;
  192141. +
  192142. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  192143. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  192144. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  192145. + memcpy(fep->tx_bounce[index], bufaddr, frag_len);
  192146. + bufaddr = fep->tx_bounce[index];
  192147. +
  192148. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  192149. + swap_buffer(bufaddr, frag_len);
  192150. + }
  192151. +
  192152. + addr = dma_map_single(&fep->pdev->dev, bufaddr, frag_len,
  192153. + DMA_TO_DEVICE);
  192154. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  192155. + dev_kfree_skb_any(skb);
  192156. + if (net_ratelimit())
  192157. + netdev_err(ndev, "Tx DMA memory map failed\n");
  192158. + goto dma_mapping_error;
  192159. + }
  192160. +
  192161. + bdp->cbd_bufaddr = addr;
  192162. + bdp->cbd_datlen = frag_len;
  192163. + bdp->cbd_sc = status;
  192164. + }
  192165. +
  192166. + fep->cur_tx = bdp;
  192167. +
  192168. + return 0;
  192169. +
  192170. +dma_mapping_error:
  192171. bdp = fep->cur_tx;
  192172. + for (i = 0; i < frag; i++) {
  192173. + bdp = fec_enet_get_nextdesc(bdp, fep);
  192174. + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  192175. + bdp->cbd_datlen, DMA_TO_DEVICE);
  192176. + }
  192177. + return NETDEV_TX_OK;
  192178. +}
  192179. - status = bdp->cbd_sc;
  192180. +static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
  192181. +{
  192182. + struct fec_enet_private *fep = netdev_priv(ndev);
  192183. + const struct platform_device_id *id_entry =
  192184. + platform_get_device_id(fep->pdev);
  192185. + int nr_frags = skb_shinfo(skb)->nr_frags;
  192186. + struct bufdesc *bdp, *last_bdp;
  192187. + void *bufaddr;
  192188. + dma_addr_t addr;
  192189. + unsigned short status;
  192190. + unsigned short buflen;
  192191. + unsigned int estatus = 0;
  192192. + unsigned int index;
  192193. + int entries_free;
  192194. + int ret;
  192195. - if (status & BD_ENET_TX_READY) {
  192196. - /* Ooops. All transmit buffers are full. Bail out.
  192197. - * This should not happen, since ndev->tbusy should be set.
  192198. - */
  192199. - netdev_err(ndev, "tx queue full!\n");
  192200. - return NETDEV_TX_BUSY;
  192201. + entries_free = fec_enet_get_free_txdesc_num(fep);
  192202. + if (entries_free < MAX_SKB_FRAGS + 1) {
  192203. + dev_kfree_skb_any(skb);
  192204. + if (net_ratelimit())
  192205. + netdev_err(ndev, "NOT enough BD for SG!\n");
  192206. + return NETDEV_TX_OK;
  192207. }
  192208. /* Protocol checksum off-load for TCP and UDP. */
  192209. if (fec_enet_clear_csum(skb, ndev)) {
  192210. - kfree_skb(skb);
  192211. + dev_kfree_skb_any(skb);
  192212. return NETDEV_TX_OK;
  192213. }
  192214. - /* Clear all of the status flags */
  192215. + /* Fill in a Tx ring entry */
  192216. + bdp = fep->cur_tx;
  192217. + status = bdp->cbd_sc;
  192218. status &= ~BD_ENET_TX_STATS;
  192219. /* Set buffer length and buffer pointer */
  192220. bufaddr = skb->data;
  192221. - bdp->cbd_datlen = skb->len;
  192222. + buflen = skb_headlen(skb);
  192223. - /*
  192224. - * On some FEC implementations data must be aligned on
  192225. - * 4-byte boundaries. Use bounce buffers to copy data
  192226. - * and get it aligned. Ugh.
  192227. - */
  192228. - if (fep->bufdesc_ex)
  192229. - index = (struct bufdesc_ex *)bdp -
  192230. - (struct bufdesc_ex *)fep->tx_bd_base;
  192231. - else
  192232. - index = bdp - fep->tx_bd_base;
  192233. -
  192234. - if (((unsigned long) bufaddr) & FEC_ALIGNMENT) {
  192235. - memcpy(fep->tx_bounce[index], skb->data, skb->len);
  192236. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  192237. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  192238. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  192239. + memcpy(fep->tx_bounce[index], skb->data, buflen);
  192240. bufaddr = fep->tx_bounce[index];
  192241. - }
  192242. - /*
  192243. - * Some design made an incorrect assumption on endian mode of
  192244. - * the system that it's running on. As the result, driver has to
  192245. - * swap every frame going to and coming from the controller.
  192246. - */
  192247. - if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  192248. - swap_buffer(bufaddr, skb->len);
  192249. -
  192250. - /* Save skb pointer */
  192251. - fep->tx_skbuff[index] = skb;
  192252. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  192253. + swap_buffer(bufaddr, buflen);
  192254. + }
  192255. - /* Push the data cache so the CPM does not get stale memory
  192256. - * data.
  192257. - */
  192258. - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr,
  192259. - skb->len, DMA_TO_DEVICE);
  192260. - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
  192261. - bdp->cbd_bufaddr = 0;
  192262. - fep->tx_skbuff[index] = NULL;
  192263. + /* Push the data cache so the CPM does not get stale memory data. */
  192264. + addr = dma_map_single(&fep->pdev->dev, bufaddr, buflen, DMA_TO_DEVICE);
  192265. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  192266. dev_kfree_skb_any(skb);
  192267. if (net_ratelimit())
  192268. netdev_err(ndev, "Tx DMA memory map failed\n");
  192269. return NETDEV_TX_OK;
  192270. }
  192271. + if (nr_frags) {
  192272. + ret = fec_enet_txq_submit_frag_skb(skb, ndev);
  192273. + if (ret)
  192274. + return ret;
  192275. + } else {
  192276. + status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST);
  192277. + if (fep->bufdesc_ex) {
  192278. + estatus = BD_ENET_TX_INT;
  192279. + if (unlikely(skb_shinfo(skb)->tx_flags &
  192280. + SKBTX_HW_TSTAMP && fep->hwts_tx_en))
  192281. + estatus |= BD_ENET_TX_TS;
  192282. + }
  192283. + }
  192284. +
  192285. if (fep->bufdesc_ex) {
  192286. struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  192287. - ebdp->cbd_bdu = 0;
  192288. +
  192289. if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
  192290. - fep->hwts_tx_en)) {
  192291. - ebdp->cbd_esc = (BD_ENET_TX_TS | BD_ENET_TX_INT);
  192292. + fep->hwts_tx_en))
  192293. skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
  192294. - } else {
  192295. - ebdp->cbd_esc = BD_ENET_TX_INT;
  192296. - /* Enable protocol checksum flags
  192297. - * We do not bother with the IP Checksum bits as they
  192298. - * are done by the kernel
  192299. - */
  192300. - if (skb->ip_summed == CHECKSUM_PARTIAL)
  192301. - ebdp->cbd_esc |= BD_ENET_TX_PINS;
  192302. - }
  192303. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  192304. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  192305. +
  192306. + ebdp->cbd_bdu = 0;
  192307. + ebdp->cbd_esc = estatus;
  192308. }
  192309. + last_bdp = fep->cur_tx;
  192310. + index = fec_enet_get_bd_index(fep->tx_bd_base, last_bdp, fep);
  192311. + /* Save skb pointer */
  192312. + fep->tx_skbuff[index] = skb;
  192313. +
  192314. + bdp->cbd_datlen = buflen;
  192315. + bdp->cbd_bufaddr = addr;
  192316. +
  192317. /* Send it on its way. Tell FEC it's ready, interrupt when done,
  192318. * it's the last BD of the frame, and to put the CRC on the end.
  192319. */
  192320. - status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
  192321. - | BD_ENET_TX_LAST | BD_ENET_TX_TC);
  192322. + status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
  192323. bdp->cbd_sc = status;
  192324. - bdp_pre = fec_enet_get_prevdesc(bdp, fep);
  192325. - if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
  192326. - !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
  192327. - fep->delay_work.trig_tx = true;
  192328. - schedule_delayed_work(&(fep->delay_work.delay_work),
  192329. - msecs_to_jiffies(1));
  192330. - }
  192331. -
  192332. /* If this was the last BD in the ring, start at the beginning again. */
  192333. - bdp = fec_enet_get_nextdesc(bdp, fep);
  192334. + bdp = fec_enet_get_nextdesc(last_bdp, fep);
  192335. skb_tx_timestamp(skb);
  192336. fep->cur_tx = bdp;
  192337. - if (fep->cur_tx == fep->dirty_tx)
  192338. - netif_stop_queue(ndev);
  192339. + /* Trigger transmission start */
  192340. + writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  192341. +
  192342. + return 0;
  192343. +}
  192344. +
  192345. +static int
  192346. +fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
  192347. + struct bufdesc *bdp, int index, char *data,
  192348. + int size, bool last_tcp, bool is_last)
  192349. +{
  192350. + struct fec_enet_private *fep = netdev_priv(ndev);
  192351. + const struct platform_device_id *id_entry =
  192352. + platform_get_device_id(fep->pdev);
  192353. + struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  192354. + unsigned short status;
  192355. + unsigned int estatus = 0;
  192356. + dma_addr_t addr;
  192357. +
  192358. + status = bdp->cbd_sc;
  192359. + status &= ~BD_ENET_TX_STATS;
  192360. +
  192361. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  192362. +
  192363. + if (((unsigned long) data) & FEC_ALIGNMENT ||
  192364. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  192365. + memcpy(fep->tx_bounce[index], data, size);
  192366. + data = fep->tx_bounce[index];
  192367. +
  192368. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  192369. + swap_buffer(data, size);
  192370. + }
  192371. +
  192372. + addr = dma_map_single(&fep->pdev->dev, data, size, DMA_TO_DEVICE);
  192373. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  192374. + dev_kfree_skb_any(skb);
  192375. + if (net_ratelimit())
  192376. + netdev_err(ndev, "Tx DMA memory map failed\n");
  192377. + return NETDEV_TX_BUSY;
  192378. + }
  192379. +
  192380. + bdp->cbd_datlen = size;
  192381. + bdp->cbd_bufaddr = addr;
  192382. +
  192383. + if (fep->bufdesc_ex) {
  192384. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  192385. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  192386. + ebdp->cbd_bdu = 0;
  192387. + ebdp->cbd_esc = estatus;
  192388. + }
  192389. +
  192390. + /* Handle the last BD specially */
  192391. + if (last_tcp)
  192392. + status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC);
  192393. + if (is_last) {
  192394. + status |= BD_ENET_TX_INTR;
  192395. + if (fep->bufdesc_ex)
  192396. + ebdp->cbd_esc |= BD_ENET_TX_INT;
  192397. + }
  192398. +
  192399. + bdp->cbd_sc = status;
  192400. +
  192401. + return 0;
  192402. +}
  192403. +
  192404. +static int
  192405. +fec_enet_txq_put_hdr_tso(struct sk_buff *skb, struct net_device *ndev,
  192406. + struct bufdesc *bdp, int index)
  192407. +{
  192408. + struct fec_enet_private *fep = netdev_priv(ndev);
  192409. + const struct platform_device_id *id_entry =
  192410. + platform_get_device_id(fep->pdev);
  192411. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  192412. + struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  192413. + void *bufaddr;
  192414. + unsigned long dmabuf;
  192415. + unsigned short status;
  192416. + unsigned int estatus = 0;
  192417. +
  192418. + status = bdp->cbd_sc;
  192419. + status &= ~BD_ENET_TX_STATS;
  192420. + status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
  192421. +
  192422. + bufaddr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
  192423. + dmabuf = fep->tso_hdrs_dma + index * TSO_HEADER_SIZE;
  192424. + if (((unsigned long) bufaddr) & FEC_ALIGNMENT ||
  192425. + id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
  192426. + memcpy(fep->tx_bounce[index], skb->data, hdr_len);
  192427. + bufaddr = fep->tx_bounce[index];
  192428. +
  192429. + if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
  192430. + swap_buffer(bufaddr, hdr_len);
  192431. +
  192432. + dmabuf = dma_map_single(&fep->pdev->dev, bufaddr,
  192433. + hdr_len, DMA_TO_DEVICE);
  192434. + if (dma_mapping_error(&fep->pdev->dev, dmabuf)) {
  192435. + dev_kfree_skb_any(skb);
  192436. + if (net_ratelimit())
  192437. + netdev_err(ndev, "Tx DMA memory map failed\n");
  192438. + return NETDEV_TX_BUSY;
  192439. + }
  192440. + }
  192441. +
  192442. + bdp->cbd_bufaddr = dmabuf;
  192443. + bdp->cbd_datlen = hdr_len;
  192444. +
  192445. + if (fep->bufdesc_ex) {
  192446. + if (skb->ip_summed == CHECKSUM_PARTIAL)
  192447. + estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
  192448. + ebdp->cbd_bdu = 0;
  192449. + ebdp->cbd_esc = estatus;
  192450. + }
  192451. +
  192452. + bdp->cbd_sc = status;
  192453. +
  192454. + return 0;
  192455. +}
  192456. +
  192457. +static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
  192458. +{
  192459. + struct fec_enet_private *fep = netdev_priv(ndev);
  192460. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  192461. + int total_len, data_left;
  192462. + struct bufdesc *bdp = fep->cur_tx;
  192463. + struct tso_t tso;
  192464. + unsigned int index = 0;
  192465. + int ret;
  192466. +
  192467. + if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep)) {
  192468. + dev_kfree_skb_any(skb);
  192469. + if (net_ratelimit())
  192470. + netdev_err(ndev, "NOT enough BD for TSO!\n");
  192471. + return NETDEV_TX_OK;
  192472. + }
  192473. +
  192474. + /* Protocol checksum off-load for TCP and UDP. */
  192475. + if (fec_enet_clear_csum(skb, ndev)) {
  192476. + dev_kfree_skb_any(skb);
  192477. + return NETDEV_TX_OK;
  192478. + }
  192479. +
  192480. + /* Initialize the TSO handler, and prepare the first payload */
  192481. + tso_start(skb, &tso);
  192482. +
  192483. + total_len = skb->len - hdr_len;
  192484. + while (total_len > 0) {
  192485. + char *hdr;
  192486. +
  192487. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  192488. + data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len);
  192489. + total_len -= data_left;
  192490. +
  192491. + /* prepare packet headers: MAC + IP + TCP */
  192492. + hdr = fep->tso_hdrs + index * TSO_HEADER_SIZE;
  192493. + tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0);
  192494. + ret = fec_enet_txq_put_hdr_tso(skb, ndev, bdp, index);
  192495. + if (ret)
  192496. + goto err_release;
  192497. +
  192498. + while (data_left > 0) {
  192499. + int size;
  192500. +
  192501. + size = min_t(int, tso.size, data_left);
  192502. + bdp = fec_enet_get_nextdesc(bdp, fep);
  192503. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  192504. + ret = fec_enet_txq_put_data_tso(skb, ndev, bdp, index, tso.data,
  192505. + size, size == data_left,
  192506. + total_len == 0);
  192507. + if (ret)
  192508. + goto err_release;
  192509. +
  192510. + data_left -= size;
  192511. + tso_build_data(skb, &tso, size);
  192512. + }
  192513. +
  192514. + bdp = fec_enet_get_nextdesc(bdp, fep);
  192515. + }
  192516. +
  192517. + /* Save skb pointer */
  192518. + fep->tx_skbuff[index] = skb;
  192519. +
  192520. + skb_tx_timestamp(skb);
  192521. + fep->cur_tx = bdp;
  192522. /* Trigger transmission start */
  192523. writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  192524. + return 0;
  192525. +
  192526. +err_release:
  192527. + /* TODO: Release all used data descriptors for TSO */
  192528. + return ret;
  192529. +}
  192530. +
  192531. +static netdev_tx_t
  192532. +fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  192533. +{
  192534. + struct fec_enet_private *fep = netdev_priv(ndev);
  192535. + int entries_free;
  192536. + int ret;
  192537. +
  192538. + if (skb_is_gso(skb))
  192539. + ret = fec_enet_txq_submit_tso(skb, ndev);
  192540. + else
  192541. + ret = fec_enet_txq_submit_skb(skb, ndev);
  192542. + if (ret)
  192543. + return ret;
  192544. +
  192545. + entries_free = fec_enet_get_free_txdesc_num(fep);
  192546. + if (entries_free <= fep->tx_stop_threshold)
  192547. + netif_stop_queue(ndev);
  192548. +
  192549. return NETDEV_TX_OK;
  192550. }
  192551. @@ -474,7 +817,7 @@
  192552. /* Initialize the BD for every fragment in the page. */
  192553. bdp->cbd_sc = 0;
  192554. - if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) {
  192555. + if (fep->tx_skbuff[i]) {
  192556. dev_kfree_skb_any(fep->tx_skbuff[i]);
  192557. fep->tx_skbuff[i] = NULL;
  192558. }
  192559. @@ -488,12 +831,13 @@
  192560. fep->dirty_tx = bdp;
  192561. }
  192562. -/* This function is called to start or restart the FEC during a link
  192563. - * change. This only happens when switching between half and full
  192564. - * duplex.
  192565. +/*
  192566. + * This function is called to start or restart the FEC during a link
  192567. + * change, transmit timeout, or to reconfigure the FEC. The network
  192568. + * packet processing for this device must be stopped before this call.
  192569. */
  192570. static void
  192571. -fec_restart(struct net_device *ndev, int duplex)
  192572. +fec_restart(struct net_device *ndev)
  192573. {
  192574. struct fec_enet_private *fep = netdev_priv(ndev);
  192575. const struct platform_device_id *id_entry =
  192576. @@ -504,13 +848,6 @@
  192577. u32 rcntl = OPT_FRAME_SIZE | 0x04;
  192578. u32 ecntl = 0x2; /* ETHEREN */
  192579. - if (netif_running(ndev)) {
  192580. - netif_device_detach(ndev);
  192581. - napi_disable(&fep->napi);
  192582. - netif_stop_queue(ndev);
  192583. - netif_tx_lock_bh(ndev);
  192584. - }
  192585. -
  192586. /* Whack a reset. We should wait for this. */
  192587. writel(1, fep->hwp + FEC_ECNTRL);
  192588. udelay(10);
  192589. @@ -519,7 +856,8 @@
  192590. * enet-mac reset will reset mac address registers too,
  192591. * so need to reconfigure it.
  192592. */
  192593. - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
  192594. + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC ||
  192595. + id_entry->driver_data & FEC_QUIRK_FEC_MAC) {
  192596. memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
  192597. writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
  192598. writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
  192599. @@ -551,7 +889,7 @@
  192600. }
  192601. /* Enable MII mode */
  192602. - if (duplex) {
  192603. + if (fep->full_duplex == DUPLEX_FULL) {
  192604. /* FD enable */
  192605. writel(0x04, fep->hwp + FEC_X_CNTRL);
  192606. } else {
  192607. @@ -560,8 +898,6 @@
  192608. writel(0x0, fep->hwp + FEC_X_CNTRL);
  192609. }
  192610. - fep->full_duplex = duplex;
  192611. -
  192612. /* Set MII speed */
  192613. writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
  192614. @@ -679,13 +1015,6 @@
  192615. /* Enable interrupts we wish to service */
  192616. writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
  192617. -
  192618. - if (netif_running(ndev)) {
  192619. - netif_tx_unlock_bh(ndev);
  192620. - netif_wake_queue(ndev);
  192621. - napi_enable(&fep->napi);
  192622. - netif_device_attach(ndev);
  192623. - }
  192624. }
  192625. static void
  192626. @@ -723,29 +1052,44 @@
  192627. {
  192628. struct fec_enet_private *fep = netdev_priv(ndev);
  192629. + fec_dump(ndev);
  192630. +
  192631. ndev->stats.tx_errors++;
  192632. - fep->delay_work.timeout = true;
  192633. - schedule_delayed_work(&(fep->delay_work.delay_work), 0);
  192634. + schedule_work(&fep->tx_timeout_work);
  192635. }
  192636. -static void fec_enet_work(struct work_struct *work)
  192637. +static void fec_enet_timeout_work(struct work_struct *work)
  192638. {
  192639. struct fec_enet_private *fep =
  192640. - container_of(work,
  192641. - struct fec_enet_private,
  192642. - delay_work.delay_work.work);
  192643. -
  192644. - if (fep->delay_work.timeout) {
  192645. - fep->delay_work.timeout = false;
  192646. - fec_restart(fep->netdev, fep->full_duplex);
  192647. - netif_wake_queue(fep->netdev);
  192648. - }
  192649. + container_of(work, struct fec_enet_private, tx_timeout_work);
  192650. + struct net_device *ndev = fep->netdev;
  192651. - if (fep->delay_work.trig_tx) {
  192652. - fep->delay_work.trig_tx = false;
  192653. - writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  192654. + rtnl_lock();
  192655. + if (netif_device_present(ndev) || netif_running(ndev)) {
  192656. + napi_disable(&fep->napi);
  192657. + netif_tx_lock_bh(ndev);
  192658. + fec_restart(ndev);
  192659. + netif_wake_queue(ndev);
  192660. + netif_tx_unlock_bh(ndev);
  192661. + napi_enable(&fep->napi);
  192662. }
  192663. + rtnl_unlock();
  192664. +}
  192665. +
  192666. +static void
  192667. +fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
  192668. + struct skb_shared_hwtstamps *hwtstamps)
  192669. +{
  192670. + unsigned long flags;
  192671. + u64 ns;
  192672. +
  192673. + spin_lock_irqsave(&fep->tmreg_lock, flags);
  192674. + ns = timecounter_cyc2time(&fep->tc, ts);
  192675. + spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  192676. +
  192677. + memset(hwtstamps, 0, sizeof(*hwtstamps));
  192678. + hwtstamps->hwtstamp = ns_to_ktime(ns);
  192679. }
  192680. static void
  192681. @@ -756,6 +1100,7 @@
  192682. unsigned short status;
  192683. struct sk_buff *skb;
  192684. int index = 0;
  192685. + int entries_free;
  192686. fep = netdev_priv(ndev);
  192687. bdp = fep->dirty_tx;
  192688. @@ -769,16 +1114,18 @@
  192689. if (bdp == fep->cur_tx)
  192690. break;
  192691. - if (fep->bufdesc_ex)
  192692. - index = (struct bufdesc_ex *)bdp -
  192693. - (struct bufdesc_ex *)fep->tx_bd_base;
  192694. - else
  192695. - index = bdp - fep->tx_bd_base;
  192696. + index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
  192697. skb = fep->tx_skbuff[index];
  192698. - dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, skb->len,
  192699. - DMA_TO_DEVICE);
  192700. + fep->tx_skbuff[index] = NULL;
  192701. + if (!IS_TSO_HEADER(fep, bdp->cbd_bufaddr))
  192702. + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  192703. + bdp->cbd_datlen, DMA_TO_DEVICE);
  192704. bdp->cbd_bufaddr = 0;
  192705. + if (!skb) {
  192706. + bdp = fec_enet_get_nextdesc(bdp, fep);
  192707. + continue;
  192708. + }
  192709. /* Check for errors. */
  192710. if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
  192711. @@ -797,26 +1144,18 @@
  192712. ndev->stats.tx_carrier_errors++;
  192713. } else {
  192714. ndev->stats.tx_packets++;
  192715. - ndev->stats.tx_bytes += bdp->cbd_datlen;
  192716. + ndev->stats.tx_bytes += skb->len;
  192717. }
  192718. if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) &&
  192719. fep->bufdesc_ex) {
  192720. struct skb_shared_hwtstamps shhwtstamps;
  192721. - unsigned long flags;
  192722. struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
  192723. - memset(&shhwtstamps, 0, sizeof(shhwtstamps));
  192724. - spin_lock_irqsave(&fep->tmreg_lock, flags);
  192725. - shhwtstamps.hwtstamp = ns_to_ktime(
  192726. - timecounter_cyc2time(&fep->tc, ebdp->ts));
  192727. - spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  192728. + fec_enet_hwtstamp(fep, ebdp->ts, &shhwtstamps);
  192729. skb_tstamp_tx(skb, &shhwtstamps);
  192730. }
  192731. - if (status & BD_ENET_TX_READY)
  192732. - netdev_err(ndev, "HEY! Enet xmit interrupt and TX_READY\n");
  192733. -
  192734. /* Deferred means some collisions occurred during transmit,
  192735. * but we eventually sent the packet OK.
  192736. */
  192737. @@ -825,7 +1164,6 @@
  192738. /* Free the sk buffer associated with this last transmit */
  192739. dev_kfree_skb_any(skb);
  192740. - fep->tx_skbuff[index] = NULL;
  192741. fep->dirty_tx = bdp;
  192742. @@ -834,14 +1172,17 @@
  192743. /* Since we have freed up a buffer, the ring is no longer full
  192744. */
  192745. - if (fep->dirty_tx != fep->cur_tx) {
  192746. - if (netif_queue_stopped(ndev))
  192747. + if (netif_queue_stopped(ndev)) {
  192748. + entries_free = fec_enet_get_free_txdesc_num(fep);
  192749. + if (entries_free >= fep->tx_wake_threshold)
  192750. netif_wake_queue(ndev);
  192751. }
  192752. }
  192753. - return;
  192754. -}
  192755. + /* ERR006538: Keep the transmitter going */
  192756. + if (bdp != fep->cur_tx && readl(fep->hwp + FEC_X_DES_ACTIVE) == 0)
  192757. + writel(0, fep->hwp + FEC_X_DES_ACTIVE);
  192758. +}
  192759. /* During a receive, the cur_rx points to the current incoming buffer.
  192760. * When we update through the ring, if the next incoming buffer has
  192761. @@ -876,8 +1217,11 @@
  192762. while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
  192763. - if (pkt_received >= budget)
  192764. + if (pkt_received >= budget) {
  192765. + /* overwhelmed take a breath */
  192766. + udelay(210);
  192767. break;
  192768. + }
  192769. pkt_received++;
  192770. /* Since we have allocated space to hold a complete frame,
  192771. @@ -886,8 +1230,7 @@
  192772. if ((status & BD_ENET_RX_LAST) == 0)
  192773. netdev_err(ndev, "rcv is not +last\n");
  192774. - if (!fep->opened)
  192775. - goto rx_processing_done;
  192776. + writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
  192777. /* Check for errors. */
  192778. if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
  192779. @@ -920,11 +1263,7 @@
  192780. pkt_len = bdp->cbd_datlen;
  192781. ndev->stats.rx_bytes += pkt_len;
  192782. - if (fep->bufdesc_ex)
  192783. - index = (struct bufdesc_ex *)bdp -
  192784. - (struct bufdesc_ex *)fep->rx_bd_base;
  192785. - else
  192786. - index = bdp - fep->rx_bd_base;
  192787. + index = fec_enet_get_bd_index(fep->rx_bd_base, bdp, fep);
  192788. data = fep->rx_skbuff[index]->data;
  192789. dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr,
  192790. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  192791. @@ -975,18 +1314,9 @@
  192792. skb->protocol = eth_type_trans(skb, ndev);
  192793. /* Get receive timestamp from the skb */
  192794. - if (fep->hwts_rx_en && fep->bufdesc_ex) {
  192795. - struct skb_shared_hwtstamps *shhwtstamps =
  192796. - skb_hwtstamps(skb);
  192797. - unsigned long flags;
  192798. -
  192799. - memset(shhwtstamps, 0, sizeof(*shhwtstamps));
  192800. -
  192801. - spin_lock_irqsave(&fep->tmreg_lock, flags);
  192802. - shhwtstamps->hwtstamp = ns_to_ktime(
  192803. - timecounter_cyc2time(&fep->tc, ebdp->ts));
  192804. - spin_unlock_irqrestore(&fep->tmreg_lock, flags);
  192805. - }
  192806. + if (fep->hwts_rx_en && fep->bufdesc_ex)
  192807. + fec_enet_hwtstamp(fep, ebdp->ts,
  192808. + skb_hwtstamps(skb));
  192809. if (fep->bufdesc_ex &&
  192810. (fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
  192811. @@ -1044,29 +1374,25 @@
  192812. {
  192813. struct net_device *ndev = dev_id;
  192814. struct fec_enet_private *fep = netdev_priv(ndev);
  192815. + const unsigned napi_mask = FEC_ENET_RXF | FEC_ENET_TXF;
  192816. uint int_events;
  192817. irqreturn_t ret = IRQ_NONE;
  192818. - do {
  192819. - int_events = readl(fep->hwp + FEC_IEVENT);
  192820. - writel(int_events, fep->hwp + FEC_IEVENT);
  192821. + int_events = readl(fep->hwp + FEC_IEVENT);
  192822. + writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT);
  192823. - if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
  192824. - ret = IRQ_HANDLED;
  192825. + if (int_events & napi_mask) {
  192826. + ret = IRQ_HANDLED;
  192827. - /* Disable the RX interrupt */
  192828. - if (napi_schedule_prep(&fep->napi)) {
  192829. - writel(FEC_RX_DISABLED_IMASK,
  192830. - fep->hwp + FEC_IMASK);
  192831. - __napi_schedule(&fep->napi);
  192832. - }
  192833. - }
  192834. + /* Disable the NAPI interrupts */
  192835. + writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
  192836. + napi_schedule(&fep->napi);
  192837. + }
  192838. - if (int_events & FEC_ENET_MII) {
  192839. - ret = IRQ_HANDLED;
  192840. - complete(&fep->mdio_done);
  192841. - }
  192842. - } while (int_events);
  192843. + if (int_events & FEC_ENET_MII) {
  192844. + ret = IRQ_HANDLED;
  192845. + complete(&fep->mdio_done);
  192846. + }
  192847. return ret;
  192848. }
  192849. @@ -1074,8 +1400,16 @@
  192850. static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
  192851. {
  192852. struct net_device *ndev = napi->dev;
  192853. - int pkts = fec_enet_rx(ndev, budget);
  192854. struct fec_enet_private *fep = netdev_priv(ndev);
  192855. + int pkts;
  192856. +
  192857. + /*
  192858. + * Clear any pending transmit or receive interrupts before
  192859. + * processing the rings to avoid racing with the hardware.
  192860. + */
  192861. + writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT);
  192862. +
  192863. + pkts = fec_enet_rx(ndev, budget);
  192864. fec_enet_tx(ndev);
  192865. @@ -1173,14 +1507,23 @@
  192866. return;
  192867. }
  192868. - if (phy_dev->link) {
  192869. + /*
  192870. + * If the netdev is down, or is going down, we're not interested
  192871. + * in link state events, so just mark our idea of the link as down
  192872. + * and ignore the event.
  192873. + */
  192874. + if (!netif_running(ndev) || !netif_device_present(ndev)) {
  192875. + fep->link = 0;
  192876. + } else if (phy_dev->link) {
  192877. if (!fep->link) {
  192878. fep->link = phy_dev->link;
  192879. status_change = 1;
  192880. }
  192881. - if (fep->full_duplex != phy_dev->duplex)
  192882. + if (fep->full_duplex != phy_dev->duplex) {
  192883. + fep->full_duplex = phy_dev->duplex;
  192884. status_change = 1;
  192885. + }
  192886. if (phy_dev->speed != fep->speed) {
  192887. fep->speed = phy_dev->speed;
  192888. @@ -1188,11 +1531,21 @@
  192889. }
  192890. /* if any of the above changed restart the FEC */
  192891. - if (status_change)
  192892. - fec_restart(ndev, phy_dev->duplex);
  192893. + if (status_change) {
  192894. + napi_disable(&fep->napi);
  192895. + netif_tx_lock_bh(ndev);
  192896. + fec_restart(ndev);
  192897. + netif_wake_queue(ndev);
  192898. + netif_tx_unlock_bh(ndev);
  192899. + napi_enable(&fep->napi);
  192900. + }
  192901. } else {
  192902. if (fep->link) {
  192903. + napi_disable(&fep->napi);
  192904. + netif_tx_lock_bh(ndev);
  192905. fec_stop(ndev);
  192906. + netif_tx_unlock_bh(ndev);
  192907. + napi_enable(&fep->napi);
  192908. fep->link = phy_dev->link;
  192909. status_change = 1;
  192910. }
  192911. @@ -1255,9 +1608,51 @@
  192912. return 0;
  192913. }
  192914. -static int fec_enet_mdio_reset(struct mii_bus *bus)
  192915. +static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
  192916. {
  192917. + struct fec_enet_private *fep = netdev_priv(ndev);
  192918. + int ret;
  192919. +
  192920. + if (enable) {
  192921. + pm_runtime_enable(&fep->pdev->dev);
  192922. +
  192923. + ret = clk_prepare_enable(fep->clk_ahb);
  192924. + if (ret)
  192925. + return ret;
  192926. + ret = clk_prepare_enable(fep->clk_ipg);
  192927. + if (ret)
  192928. + goto failed_clk_ipg;
  192929. + if (fep->clk_enet_out) {
  192930. + ret = clk_prepare_enable(fep->clk_enet_out);
  192931. + if (ret)
  192932. + goto failed_clk_enet_out;
  192933. + }
  192934. + if (fep->clk_ptp) {
  192935. + ret = clk_prepare_enable(fep->clk_ptp);
  192936. + if (ret)
  192937. + goto failed_clk_ptp;
  192938. + }
  192939. + } else {
  192940. + clk_disable_unprepare(fep->clk_ahb);
  192941. + clk_disable_unprepare(fep->clk_ipg);
  192942. + if (fep->clk_enet_out)
  192943. + clk_disable_unprepare(fep->clk_enet_out);
  192944. + if (fep->clk_ptp)
  192945. + clk_disable_unprepare(fep->clk_ptp);
  192946. +
  192947. + pm_runtime_disable(&fep->pdev->dev);
  192948. + }
  192949. +
  192950. return 0;
  192951. +failed_clk_ptp:
  192952. + if (fep->clk_enet_out)
  192953. + clk_disable_unprepare(fep->clk_enet_out);
  192954. +failed_clk_enet_out:
  192955. + clk_disable_unprepare(fep->clk_ipg);
  192956. +failed_clk_ipg:
  192957. + clk_disable_unprepare(fep->clk_ahb);
  192958. +
  192959. + return ret;
  192960. }
  192961. static int fec_enet_mii_probe(struct net_device *ndev)
  192962. @@ -1304,6 +1699,7 @@
  192963. /* mask with MAC supported features */
  192964. if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) {
  192965. phy_dev->supported &= PHY_GBIT_FEATURES;
  192966. + phy_dev->supported &= ~SUPPORTED_1000baseT_Half;
  192967. #if !defined(CONFIG_M5272)
  192968. phy_dev->supported |= SUPPORTED_Pause;
  192969. #endif
  192970. @@ -1369,7 +1765,7 @@
  192971. * Reference Manual has an error on this, and gets fixed on i.MX6Q
  192972. * document.
  192973. */
  192974. - fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ahb), 5000000);
  192975. + fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ipg), 5000000);
  192976. if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
  192977. fep->phy_speed--;
  192978. fep->phy_speed <<= 1;
  192979. @@ -1384,7 +1780,6 @@
  192980. fep->mii_bus->name = "fec_enet_mii_bus";
  192981. fep->mii_bus->read = fec_enet_mdio_read;
  192982. fep->mii_bus->write = fec_enet_mdio_write;
  192983. - fep->mii_bus->reset = fec_enet_mdio_reset;
  192984. snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
  192985. pdev->name, fep->dev_id + 1);
  192986. fep->mii_bus->priv = fep;
  192987. @@ -1508,6 +1903,9 @@
  192988. {
  192989. struct fec_enet_private *fep = netdev_priv(ndev);
  192990. + if (!fep->phy_dev)
  192991. + return -ENODEV;
  192992. +
  192993. if (pause->tx_pause != pause->rx_pause) {
  192994. netdev_info(ndev,
  192995. "hardware only support enable/disable both tx and rx");
  192996. @@ -1533,8 +1931,14 @@
  192997. fec_stop(ndev);
  192998. phy_start_aneg(fep->phy_dev);
  192999. }
  193000. - if (netif_running(ndev))
  193001. - fec_restart(ndev, 0);
  193002. + if (netif_running(ndev)) {
  193003. + napi_disable(&fep->napi);
  193004. + netif_tx_lock_bh(ndev);
  193005. + fec_restart(ndev);
  193006. + netif_wake_queue(ndev);
  193007. + netif_tx_unlock_bh(ndev);
  193008. + napi_enable(&fep->napi);
  193009. + }
  193010. return 0;
  193011. }
  193012. @@ -1651,21 +2055,19 @@
  193013. }
  193014. static const struct ethtool_ops fec_enet_ethtool_ops = {
  193015. -#if !defined(CONFIG_M5272)
  193016. - .get_pauseparam = fec_enet_get_pauseparam,
  193017. - .set_pauseparam = fec_enet_set_pauseparam,
  193018. -#endif
  193019. .get_settings = fec_enet_get_settings,
  193020. .set_settings = fec_enet_set_settings,
  193021. .get_drvinfo = fec_enet_get_drvinfo,
  193022. - .get_link = ethtool_op_get_link,
  193023. - .get_ts_info = fec_enet_get_ts_info,
  193024. .nway_reset = fec_enet_nway_reset,
  193025. + .get_link = ethtool_op_get_link,
  193026. #ifndef CONFIG_M5272
  193027. - .get_ethtool_stats = fec_enet_get_ethtool_stats,
  193028. + .get_pauseparam = fec_enet_get_pauseparam,
  193029. + .set_pauseparam = fec_enet_set_pauseparam,
  193030. .get_strings = fec_enet_get_strings,
  193031. + .get_ethtool_stats = fec_enet_get_ethtool_stats,
  193032. .get_sset_count = fec_enet_get_sset_count,
  193033. #endif
  193034. + .get_ts_info = fec_enet_get_ts_info,
  193035. };
  193036. static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
  193037. @@ -1699,18 +2101,23 @@
  193038. bdp = fep->rx_bd_base;
  193039. for (i = 0; i < fep->rx_ring_size; i++) {
  193040. skb = fep->rx_skbuff[i];
  193041. -
  193042. - if (bdp->cbd_bufaddr)
  193043. + fep->rx_skbuff[i] = NULL;
  193044. + if (skb) {
  193045. dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
  193046. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  193047. - if (skb)
  193048. dev_kfree_skb(skb);
  193049. + }
  193050. bdp = fec_enet_get_nextdesc(bdp, fep);
  193051. }
  193052. bdp = fep->tx_bd_base;
  193053. - for (i = 0; i < fep->tx_ring_size; i++)
  193054. + for (i = 0; i < fep->tx_ring_size; i++) {
  193055. kfree(fep->tx_bounce[i]);
  193056. + fep->tx_bounce[i] = NULL;
  193057. + skb = fep->tx_skbuff[i];
  193058. + fep->tx_skbuff[i] = NULL;
  193059. + dev_kfree_skb(skb);
  193060. + }
  193061. }
  193062. static int fec_enet_alloc_buffers(struct net_device *ndev)
  193063. @@ -1722,21 +2129,23 @@
  193064. bdp = fep->rx_bd_base;
  193065. for (i = 0; i < fep->rx_ring_size; i++) {
  193066. + dma_addr_t addr;
  193067. +
  193068. skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
  193069. - if (!skb) {
  193070. - fec_enet_free_buffers(ndev);
  193071. - return -ENOMEM;
  193072. - }
  193073. - fep->rx_skbuff[i] = skb;
  193074. + if (!skb)
  193075. + goto err_alloc;
  193076. - bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
  193077. + addr = dma_map_single(&fep->pdev->dev, skb->data,
  193078. FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
  193079. - if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
  193080. - fec_enet_free_buffers(ndev);
  193081. + if (dma_mapping_error(&fep->pdev->dev, addr)) {
  193082. + dev_kfree_skb(skb);
  193083. if (net_ratelimit())
  193084. netdev_err(ndev, "Rx DMA memory map failed\n");
  193085. - return -ENOMEM;
  193086. + goto err_alloc;
  193087. }
  193088. +
  193089. + fep->rx_skbuff[i] = skb;
  193090. + bdp->cbd_bufaddr = addr;
  193091. bdp->cbd_sc = BD_ENET_RX_EMPTY;
  193092. if (fep->bufdesc_ex) {
  193093. @@ -1754,6 +2163,8 @@
  193094. bdp = fep->tx_bd_base;
  193095. for (i = 0; i < fep->tx_ring_size; i++) {
  193096. fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
  193097. + if (!fep->tx_bounce[i])
  193098. + goto err_alloc;
  193099. bdp->cbd_sc = 0;
  193100. bdp->cbd_bufaddr = 0;
  193101. @@ -1771,14 +2182,35 @@
  193102. bdp->cbd_sc |= BD_SC_WRAP;
  193103. return 0;
  193104. +
  193105. + err_alloc:
  193106. + fec_enet_free_buffers(ndev);
  193107. + return -ENOMEM;
  193108. }
  193109. static int
  193110. fec_enet_open(struct net_device *ndev)
  193111. {
  193112. struct fec_enet_private *fep = netdev_priv(ndev);
  193113. + const struct platform_device_id *id_entry =
  193114. + platform_get_device_id(fep->pdev);
  193115. int ret;
  193116. + if (id_entry->driver_data & FEC_QUIRK_BUG_WAITMODE)
  193117. + pm_qos_add_request(&ndev->pm_qos_req,
  193118. + PM_QOS_CPU_DMA_LATENCY,
  193119. + 0);
  193120. + else
  193121. + pm_qos_add_request(&ndev->pm_qos_req,
  193122. + PM_QOS_CPU_DMA_LATENCY,
  193123. + PM_QOS_DEFAULT_VALUE);
  193124. +
  193125. +
  193126. + pinctrl_pm_select_default_state(&fep->pdev->dev);
  193127. + ret = fec_enet_clk_enable(ndev, true);
  193128. + if (ret)
  193129. + return ret;
  193130. +
  193131. /* I should reset the ring buffers here, but I don't yet know
  193132. * a simple way to do that.
  193133. */
  193134. @@ -1794,10 +2226,12 @@
  193135. return ret;
  193136. }
  193137. + pm_runtime_get_sync(&fep->pdev->dev);
  193138. +
  193139. + fec_restart(ndev);
  193140. napi_enable(&fep->napi);
  193141. phy_start(fep->phy_dev);
  193142. netif_start_queue(ndev);
  193143. - fep->opened = 1;
  193144. return 0;
  193145. }
  193146. @@ -1806,17 +2240,22 @@
  193147. {
  193148. struct fec_enet_private *fep = netdev_priv(ndev);
  193149. - /* Don't know what to do yet. */
  193150. - napi_disable(&fep->napi);
  193151. - fep->opened = 0;
  193152. - netif_stop_queue(ndev);
  193153. - fec_stop(ndev);
  193154. + phy_stop(fep->phy_dev);
  193155. - if (fep->phy_dev) {
  193156. - phy_stop(fep->phy_dev);
  193157. - phy_disconnect(fep->phy_dev);
  193158. + if (netif_device_present(ndev)) {
  193159. + napi_disable(&fep->napi);
  193160. + netif_tx_disable(ndev);
  193161. + fec_stop(ndev);
  193162. }
  193163. + phy_disconnect(fep->phy_dev);
  193164. + fep->phy_dev = NULL;
  193165. +
  193166. + fec_enet_clk_enable(ndev, false);
  193167. + pinctrl_pm_select_sleep_state(&fep->pdev->dev);
  193168. + pm_qos_remove_request(&ndev->pm_qos_req);
  193169. + pm_runtime_put_sync_suspend(&fep->pdev->dev);
  193170. +
  193171. fec_enet_free_buffers(ndev);
  193172. return 0;
  193173. @@ -1904,10 +2343,11 @@
  193174. struct fec_enet_private *fep = netdev_priv(ndev);
  193175. struct sockaddr *addr = p;
  193176. - if (!is_valid_ether_addr(addr->sa_data))
  193177. - return -EADDRNOTAVAIL;
  193178. -
  193179. - memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
  193180. + if (addr) {
  193181. + if (!is_valid_ether_addr(addr->sa_data))
  193182. + return -EADDRNOTAVAIL;
  193183. + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
  193184. + }
  193185. writel(ndev->dev_addr[3] | (ndev->dev_addr[2] << 8) |
  193186. (ndev->dev_addr[1] << 16) | (ndev->dev_addr[0] << 24),
  193187. @@ -1940,12 +2380,21 @@
  193188. }
  193189. #endif
  193190. +#define FEATURES_NEED_QUIESCE NETIF_F_RXCSUM
  193191. +
  193192. static int fec_set_features(struct net_device *netdev,
  193193. netdev_features_t features)
  193194. {
  193195. struct fec_enet_private *fep = netdev_priv(netdev);
  193196. netdev_features_t changed = features ^ netdev->features;
  193197. + /* Quiesce the device if necessary */
  193198. + if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
  193199. + napi_disable(&fep->napi);
  193200. + netif_tx_lock_bh(netdev);
  193201. + fec_stop(netdev);
  193202. + }
  193203. +
  193204. netdev->features = features;
  193205. /* Receive checksum has been changed */
  193206. @@ -1954,14 +2403,14 @@
  193207. fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
  193208. else
  193209. fep->csum_flags &= ~FLAG_RX_CSUM_ENABLED;
  193210. + }
  193211. - if (netif_running(netdev)) {
  193212. - fec_stop(netdev);
  193213. - fec_restart(netdev, fep->phy_dev->duplex);
  193214. - netif_wake_queue(netdev);
  193215. - } else {
  193216. - fec_restart(netdev, fep->phy_dev->duplex);
  193217. - }
  193218. + /* Resume the device after updates */
  193219. + if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
  193220. + fec_restart(netdev);
  193221. + netif_wake_queue(netdev);
  193222. + netif_tx_unlock_bh(netdev);
  193223. + napi_enable(&fep->napi);
  193224. }
  193225. return 0;
  193226. @@ -1993,23 +2442,43 @@
  193227. const struct platform_device_id *id_entry =
  193228. platform_get_device_id(fep->pdev);
  193229. struct bufdesc *cbd_base;
  193230. + int bd_size;
  193231. +
  193232. + /* init the tx & rx ring size */
  193233. + fep->tx_ring_size = TX_RING_SIZE;
  193234. + fep->rx_ring_size = RX_RING_SIZE;
  193235. +
  193236. + fep->tx_stop_threshold = FEC_MAX_SKB_DESCS;
  193237. + fep->tx_wake_threshold = (fep->tx_ring_size - fep->tx_stop_threshold) / 2;
  193238. +
  193239. + if (fep->bufdesc_ex)
  193240. + fep->bufdesc_size = sizeof(struct bufdesc_ex);
  193241. + else
  193242. + fep->bufdesc_size = sizeof(struct bufdesc);
  193243. + bd_size = (fep->tx_ring_size + fep->rx_ring_size) *
  193244. + fep->bufdesc_size;
  193245. /* Allocate memory for buffer descriptors. */
  193246. - cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
  193247. + cbd_base = dma_alloc_coherent(NULL, bd_size, &fep->bd_dma,
  193248. GFP_KERNEL);
  193249. if (!cbd_base)
  193250. return -ENOMEM;
  193251. + fep->tso_hdrs = dma_alloc_coherent(NULL, fep->tx_ring_size * TSO_HEADER_SIZE,
  193252. + &fep->tso_hdrs_dma, GFP_KERNEL);
  193253. + if (!fep->tso_hdrs) {
  193254. + dma_free_coherent(NULL, bd_size, cbd_base, fep->bd_dma);
  193255. + return -ENOMEM;
  193256. + }
  193257. +
  193258. memset(cbd_base, 0, PAGE_SIZE);
  193259. fep->netdev = ndev;
  193260. /* Get the Ethernet address */
  193261. fec_get_mac(ndev);
  193262. -
  193263. - /* init the tx & rx ring size */
  193264. - fep->tx_ring_size = TX_RING_SIZE;
  193265. - fep->rx_ring_size = RX_RING_SIZE;
  193266. + /* make sure MAC we just acquired is programmed into the hw */
  193267. + fec_set_mac_address(ndev, NULL);
  193268. /* Set receive and transmit descriptor base. */
  193269. fep->rx_bd_base = cbd_base;
  193270. @@ -2027,22 +2496,22 @@
  193271. writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
  193272. netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);
  193273. - if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN) {
  193274. + if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN)
  193275. /* enable hw VLAN support */
  193276. ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  193277. - ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
  193278. - }
  193279. if (id_entry->driver_data & FEC_QUIRK_HAS_CSUM) {
  193280. + ndev->gso_max_segs = FEC_MAX_TSO_SEGS;
  193281. +
  193282. /* enable hw accelerator */
  193283. ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
  193284. - | NETIF_F_RXCSUM);
  193285. - ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
  193286. - | NETIF_F_RXCSUM);
  193287. + | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO);
  193288. fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
  193289. }
  193290. - fec_restart(ndev, 0);
  193291. + ndev->hw_features = ndev->features;
  193292. +
  193293. + fec_restart(ndev);
  193294. return 0;
  193295. }
  193296. @@ -2117,6 +2586,9 @@
  193297. fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
  193298. #endif
  193299. + /* Select default pin state */
  193300. + pinctrl_pm_select_default_state(&pdev->dev);
  193301. +
  193302. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  193303. fep->hwp = devm_ioremap_resource(&pdev->dev, r);
  193304. if (IS_ERR(fep->hwp)) {
  193305. @@ -2167,26 +2639,10 @@
  193306. fep->bufdesc_ex = 0;
  193307. }
  193308. - ret = clk_prepare_enable(fep->clk_ahb);
  193309. + ret = fec_enet_clk_enable(ndev, true);
  193310. if (ret)
  193311. goto failed_clk;
  193312. - ret = clk_prepare_enable(fep->clk_ipg);
  193313. - if (ret)
  193314. - goto failed_clk_ipg;
  193315. -
  193316. - if (fep->clk_enet_out) {
  193317. - ret = clk_prepare_enable(fep->clk_enet_out);
  193318. - if (ret)
  193319. - goto failed_clk_enet_out;
  193320. - }
  193321. -
  193322. - if (fep->clk_ptp) {
  193323. - ret = clk_prepare_enable(fep->clk_ptp);
  193324. - if (ret)
  193325. - goto failed_clk_ptp;
  193326. - }
  193327. -
  193328. fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
  193329. if (!IS_ERR(fep->reg_phy)) {
  193330. ret = regulator_enable(fep->reg_phy);
  193331. @@ -2228,6 +2684,8 @@
  193332. /* Carrier starts down, phylib will bring it up */
  193333. netif_carrier_off(ndev);
  193334. + fec_enet_clk_enable(ndev, false);
  193335. + pinctrl_pm_select_sleep_state(&pdev->dev);
  193336. ret = register_netdev(ndev);
  193337. if (ret)
  193338. @@ -2236,7 +2694,7 @@
  193339. if (fep->bufdesc_ex && fep->ptp_clock)
  193340. netdev_info(ndev, "registered PHC device %d\n", fep->dev_id);
  193341. - INIT_DELAYED_WORK(&(fep->delay_work.delay_work), fec_enet_work);
  193342. + INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work);
  193343. return 0;
  193344. failed_register:
  193345. @@ -2247,15 +2705,7 @@
  193346. if (fep->reg_phy)
  193347. regulator_disable(fep->reg_phy);
  193348. failed_regulator:
  193349. - if (fep->clk_ptp)
  193350. - clk_disable_unprepare(fep->clk_ptp);
  193351. -failed_clk_ptp:
  193352. - if (fep->clk_enet_out)
  193353. - clk_disable_unprepare(fep->clk_enet_out);
  193354. -failed_clk_enet_out:
  193355. - clk_disable_unprepare(fep->clk_ipg);
  193356. -failed_clk_ipg:
  193357. - clk_disable_unprepare(fep->clk_ahb);
  193358. + fec_enet_clk_enable(ndev, false);
  193359. failed_clk:
  193360. failed_ioremap:
  193361. free_netdev(ndev);
  193362. @@ -2269,42 +2719,40 @@
  193363. struct net_device *ndev = platform_get_drvdata(pdev);
  193364. struct fec_enet_private *fep = netdev_priv(ndev);
  193365. - cancel_delayed_work_sync(&(fep->delay_work.delay_work));
  193366. + cancel_work_sync(&fep->tx_timeout_work);
  193367. unregister_netdev(ndev);
  193368. fec_enet_mii_remove(fep);
  193369. del_timer_sync(&fep->time_keep);
  193370. if (fep->reg_phy)
  193371. regulator_disable(fep->reg_phy);
  193372. - if (fep->clk_ptp)
  193373. - clk_disable_unprepare(fep->clk_ptp);
  193374. if (fep->ptp_clock)
  193375. ptp_clock_unregister(fep->ptp_clock);
  193376. - if (fep->clk_enet_out)
  193377. - clk_disable_unprepare(fep->clk_enet_out);
  193378. - clk_disable_unprepare(fep->clk_ipg);
  193379. - clk_disable_unprepare(fep->clk_ahb);
  193380. + fec_enet_clk_enable(ndev, false);
  193381. free_netdev(ndev);
  193382. return 0;
  193383. }
  193384. -#ifdef CONFIG_PM_SLEEP
  193385. +#ifdef CONFIG_PM
  193386. static int
  193387. fec_suspend(struct device *dev)
  193388. {
  193389. struct net_device *ndev = dev_get_drvdata(dev);
  193390. struct fec_enet_private *fep = netdev_priv(ndev);
  193391. + rtnl_lock();
  193392. if (netif_running(ndev)) {
  193393. - fec_stop(ndev);
  193394. + phy_stop(fep->phy_dev);
  193395. + napi_disable(&fep->napi);
  193396. + netif_tx_lock_bh(ndev);
  193397. netif_device_detach(ndev);
  193398. + netif_tx_unlock_bh(ndev);
  193399. + fec_stop(ndev);
  193400. }
  193401. - if (fep->clk_ptp)
  193402. - clk_disable_unprepare(fep->clk_ptp);
  193403. - if (fep->clk_enet_out)
  193404. - clk_disable_unprepare(fep->clk_enet_out);
  193405. - clk_disable_unprepare(fep->clk_ipg);
  193406. - clk_disable_unprepare(fep->clk_ahb);
  193407. + rtnl_unlock();
  193408. +
  193409. + fec_enet_clk_enable(ndev, false);
  193410. + pinctrl_pm_select_sleep_state(&fep->pdev->dev);
  193411. if (fep->reg_phy)
  193412. regulator_disable(fep->reg_phy);
  193413. @@ -2325,48 +2773,49 @@
  193414. return ret;
  193415. }
  193416. - ret = clk_prepare_enable(fep->clk_ahb);
  193417. - if (ret)
  193418. - goto failed_clk_ahb;
  193419. -
  193420. - ret = clk_prepare_enable(fep->clk_ipg);
  193421. + pinctrl_pm_select_default_state(&fep->pdev->dev);
  193422. + ret = fec_enet_clk_enable(ndev, true);
  193423. if (ret)
  193424. - goto failed_clk_ipg;
  193425. -
  193426. - if (fep->clk_enet_out) {
  193427. - ret = clk_prepare_enable(fep->clk_enet_out);
  193428. - if (ret)
  193429. - goto failed_clk_enet_out;
  193430. - }
  193431. -
  193432. - if (fep->clk_ptp) {
  193433. - ret = clk_prepare_enable(fep->clk_ptp);
  193434. - if (ret)
  193435. - goto failed_clk_ptp;
  193436. - }
  193437. + goto failed_clk;
  193438. + rtnl_lock();
  193439. if (netif_running(ndev)) {
  193440. - fec_restart(ndev, fep->full_duplex);
  193441. + fec_restart(ndev);
  193442. + netif_tx_lock_bh(ndev);
  193443. netif_device_attach(ndev);
  193444. + netif_tx_unlock_bh(ndev);
  193445. + napi_enable(&fep->napi);
  193446. + phy_start(fep->phy_dev);
  193447. }
  193448. + rtnl_unlock();
  193449. return 0;
  193450. -failed_clk_ptp:
  193451. - if (fep->clk_enet_out)
  193452. - clk_disable_unprepare(fep->clk_enet_out);
  193453. -failed_clk_enet_out:
  193454. - clk_disable_unprepare(fep->clk_ipg);
  193455. -failed_clk_ipg:
  193456. - clk_disable_unprepare(fep->clk_ahb);
  193457. -failed_clk_ahb:
  193458. +failed_clk:
  193459. if (fep->reg_phy)
  193460. regulator_disable(fep->reg_phy);
  193461. return ret;
  193462. }
  193463. +
  193464. +static int fec_runtime_suspend(struct device *dev)
  193465. +{
  193466. + release_bus_freq(BUS_FREQ_HIGH);
  193467. + return 0;
  193468. +}
  193469. +
  193470. +static int fec_runtime_resume(struct device *dev)
  193471. +{
  193472. + request_bus_freq(BUS_FREQ_HIGH);
  193473. + return 0;
  193474. +}
  193475. +
  193476. +static const struct dev_pm_ops fec_pm_ops = {
  193477. + SET_RUNTIME_PM_OPS(fec_runtime_suspend, fec_runtime_resume, NULL)
  193478. + SET_SYSTEM_SLEEP_PM_OPS(fec_suspend, fec_resume)
  193479. +};
  193480. +
  193481. #endif /* CONFIG_PM_SLEEP */
  193482. -static SIMPLE_DEV_PM_OPS(fec_pm_ops, fec_suspend, fec_resume);
  193483. static struct platform_driver fec_driver = {
  193484. .driver = {
  193485. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/fec_ptp.c linux-imx6-3.14/drivers/net/ethernet/freescale/fec_ptp.c
  193486. --- linux-3.14.17/drivers/net/ethernet/freescale/fec_ptp.c 2014-08-14 03:38:34.000000000 +0200
  193487. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fec_ptp.c 2014-09-11 18:06:03.498043952 +0200
  193488. @@ -372,6 +372,7 @@
  193489. fep->ptp_caps.n_alarm = 0;
  193490. fep->ptp_caps.n_ext_ts = 0;
  193491. fep->ptp_caps.n_per_out = 0;
  193492. + fep->ptp_caps.n_pins = 0;
  193493. fep->ptp_caps.pps = 0;
  193494. fep->ptp_caps.adjfreq = fec_ptp_adjfreq;
  193495. fep->ptp_caps.adjtime = fec_ptp_adjtime;
  193496. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
  193497. --- linux-3.14.17/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 2014-08-14 03:38:34.000000000 +0200
  193498. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c 2014-09-11 18:06:03.498043952 +0200
  193499. @@ -91,6 +91,9 @@
  193500. u16 pkt_len, sc;
  193501. int curidx;
  193502. + if (budget <= 0)
  193503. + return received;
  193504. +
  193505. /*
  193506. * First, grab all of the stats for the incoming packet.
  193507. * These get messed up if we get called due to a busy condition.
  193508. @@ -789,10 +792,6 @@
  193509. phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0,
  193510. iface);
  193511. if (!phydev) {
  193512. - phydev = of_phy_connect_fixed_link(dev, &fs_adjust_link,
  193513. - iface);
  193514. - }
  193515. - if (!phydev) {
  193516. dev_err(&dev->dev, "Could not attach to PHY\n");
  193517. return -ENODEV;
  193518. }
  193519. @@ -1026,9 +1025,16 @@
  193520. fpi->use_napi = 1;
  193521. fpi->napi_weight = 17;
  193522. fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
  193523. - if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link",
  193524. - NULL)))
  193525. - goto out_free_fpi;
  193526. + if (!fpi->phy_node && of_phy_is_fixed_link(ofdev->dev.of_node)) {
  193527. + err = of_phy_register_fixed_link(ofdev->dev.of_node);
  193528. + if (err)
  193529. + goto out_free_fpi;
  193530. +
  193531. + /* In the case of a fixed PHY, the DT node associated
  193532. + * to the PHY is the Ethernet MAC DT node.
  193533. + */
  193534. + fpi->phy_node = ofdev->dev.of_node;
  193535. + }
  193536. if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) {
  193537. phy_connection_type = of_get_property(ofdev->dev.of_node,
  193538. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/fs_enet/mii-fec.c linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
  193539. --- linux-3.14.17/drivers/net/ethernet/freescale/fs_enet/mii-fec.c 2014-08-14 03:38:34.000000000 +0200
  193540. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/fs_enet/mii-fec.c 2014-09-11 18:06:03.498043952 +0200
  193541. @@ -95,12 +95,6 @@
  193542. }
  193543. -static int fs_enet_fec_mii_reset(struct mii_bus *bus)
  193544. -{
  193545. - /* nothing here - for now */
  193546. - return 0;
  193547. -}
  193548. -
  193549. static struct of_device_id fs_enet_mdio_fec_match[];
  193550. static int fs_enet_mdio_probe(struct platform_device *ofdev)
  193551. {
  193552. @@ -128,7 +122,6 @@
  193553. new_bus->name = "FEC MII Bus";
  193554. new_bus->read = &fs_enet_fec_mii_read;
  193555. new_bus->write = &fs_enet_fec_mii_write;
  193556. - new_bus->reset = &fs_enet_fec_mii_reset;
  193557. ret = of_address_to_resource(ofdev->dev.of_node, 0, &res);
  193558. if (ret)
  193559. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/gianfar.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.c
  193560. --- linux-3.14.17/drivers/net/ethernet/freescale/gianfar.c 2014-08-14 03:38:34.000000000 +0200
  193561. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.c 2014-09-11 18:06:03.502043969 +0200
  193562. @@ -9,7 +9,7 @@
  193563. * Maintainer: Kumar Gala
  193564. * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  193565. *
  193566. - * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
  193567. + * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
  193568. * Copyright 2007 MontaVista Software, Inc.
  193569. *
  193570. * This program is free software; you can redistribute it and/or modify it
  193571. @@ -121,7 +121,7 @@
  193572. static irqreturn_t gfar_transmit(int irq, void *dev_id);
  193573. static irqreturn_t gfar_interrupt(int irq, void *dev_id);
  193574. static void adjust_link(struct net_device *dev);
  193575. -static void init_registers(struct net_device *dev);
  193576. +static noinline void gfar_update_link_state(struct gfar_private *priv);
  193577. static int init_phy(struct net_device *dev);
  193578. static int gfar_probe(struct platform_device *ofdev);
  193579. static int gfar_remove(struct platform_device *ofdev);
  193580. @@ -129,8 +129,10 @@
  193581. static void gfar_set_multi(struct net_device *dev);
  193582. static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
  193583. static void gfar_configure_serdes(struct net_device *dev);
  193584. -static int gfar_poll(struct napi_struct *napi, int budget);
  193585. -static int gfar_poll_sq(struct napi_struct *napi, int budget);
  193586. +static int gfar_poll_rx(struct napi_struct *napi, int budget);
  193587. +static int gfar_poll_tx(struct napi_struct *napi, int budget);
  193588. +static int gfar_poll_rx_sq(struct napi_struct *napi, int budget);
  193589. +static int gfar_poll_tx_sq(struct napi_struct *napi, int budget);
  193590. #ifdef CONFIG_NET_POLL_CONTROLLER
  193591. static void gfar_netpoll(struct net_device *dev);
  193592. #endif
  193593. @@ -138,9 +140,7 @@
  193594. static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
  193595. static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
  193596. int amount_pull, struct napi_struct *napi);
  193597. -void gfar_halt(struct net_device *dev);
  193598. -static void gfar_halt_nodisable(struct net_device *dev);
  193599. -void gfar_start(struct net_device *dev);
  193600. +static void gfar_halt_nodisable(struct gfar_private *priv);
  193601. static void gfar_clear_exact_match(struct net_device *dev);
  193602. static void gfar_set_mac_for_addr(struct net_device *dev, int num,
  193603. const u8 *addr);
  193604. @@ -332,72 +332,76 @@
  193605. }
  193606. }
  193607. -static void gfar_init_mac(struct net_device *ndev)
  193608. +static void gfar_rx_buff_size_config(struct gfar_private *priv)
  193609. {
  193610. - struct gfar_private *priv = netdev_priv(ndev);
  193611. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193612. - u32 rctrl = 0;
  193613. - u32 tctrl = 0;
  193614. - u32 attrs = 0;
  193615. -
  193616. - /* write the tx/rx base registers */
  193617. - gfar_init_tx_rx_base(priv);
  193618. -
  193619. - /* Configure the coalescing support */
  193620. - gfar_configure_coalescing_all(priv);
  193621. + int frame_size = priv->ndev->mtu + ETH_HLEN;
  193622. /* set this when rx hw offload (TOE) functions are being used */
  193623. priv->uses_rxfcb = 0;
  193624. + if (priv->ndev->features & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX))
  193625. + priv->uses_rxfcb = 1;
  193626. +
  193627. + if (priv->hwts_rx_en)
  193628. + priv->uses_rxfcb = 1;
  193629. +
  193630. + if (priv->uses_rxfcb)
  193631. + frame_size += GMAC_FCB_LEN;
  193632. +
  193633. + frame_size += priv->padding;
  193634. +
  193635. + frame_size = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
  193636. + INCREMENTAL_BUFFER_SIZE;
  193637. +
  193638. + priv->rx_buffer_size = frame_size;
  193639. +}
  193640. +
  193641. +static void gfar_mac_rx_config(struct gfar_private *priv)
  193642. +{
  193643. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193644. + u32 rctrl = 0;
  193645. +
  193646. if (priv->rx_filer_enable) {
  193647. rctrl |= RCTRL_FILREN;
  193648. /* Program the RIR0 reg with the required distribution */
  193649. - gfar_write(&regs->rir0, DEFAULT_RIR0);
  193650. + if (priv->poll_mode == GFAR_SQ_POLLING)
  193651. + gfar_write(&regs->rir0, DEFAULT_2RXQ_RIR0);
  193652. + else /* GFAR_MQ_POLLING */
  193653. + gfar_write(&regs->rir0, DEFAULT_8RXQ_RIR0);
  193654. }
  193655. /* Restore PROMISC mode */
  193656. - if (ndev->flags & IFF_PROMISC)
  193657. + if (priv->ndev->flags & IFF_PROMISC)
  193658. rctrl |= RCTRL_PROM;
  193659. - if (ndev->features & NETIF_F_RXCSUM) {
  193660. + if (priv->ndev->features & NETIF_F_RXCSUM)
  193661. rctrl |= RCTRL_CHECKSUMMING;
  193662. - priv->uses_rxfcb = 1;
  193663. - }
  193664. -
  193665. - if (priv->extended_hash) {
  193666. - rctrl |= RCTRL_EXTHASH;
  193667. - gfar_clear_exact_match(ndev);
  193668. - rctrl |= RCTRL_EMEN;
  193669. - }
  193670. + if (priv->extended_hash)
  193671. + rctrl |= RCTRL_EXTHASH | RCTRL_EMEN;
  193672. if (priv->padding) {
  193673. rctrl &= ~RCTRL_PAL_MASK;
  193674. rctrl |= RCTRL_PADDING(priv->padding);
  193675. }
  193676. - /* Insert receive time stamps into padding alignment bytes */
  193677. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) {
  193678. - rctrl &= ~RCTRL_PAL_MASK;
  193679. - rctrl |= RCTRL_PADDING(8);
  193680. - priv->padding = 8;
  193681. - }
  193682. -
  193683. /* Enable HW time stamping if requested from user space */
  193684. - if (priv->hwts_rx_en) {
  193685. + if (priv->hwts_rx_en)
  193686. rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE;
  193687. - priv->uses_rxfcb = 1;
  193688. - }
  193689. - if (ndev->features & NETIF_F_HW_VLAN_CTAG_RX) {
  193690. + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)
  193691. rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
  193692. - priv->uses_rxfcb = 1;
  193693. - }
  193694. /* Init rctrl based on our settings */
  193695. gfar_write(&regs->rctrl, rctrl);
  193696. +}
  193697. - if (ndev->features & NETIF_F_IP_CSUM)
  193698. +static void gfar_mac_tx_config(struct gfar_private *priv)
  193699. +{
  193700. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193701. + u32 tctrl = 0;
  193702. +
  193703. + if (priv->ndev->features & NETIF_F_IP_CSUM)
  193704. tctrl |= TCTRL_INIT_CSUM;
  193705. if (priv->prio_sched_en)
  193706. @@ -408,30 +412,51 @@
  193707. gfar_write(&regs->tr47wt, DEFAULT_WRRS_WEIGHT);
  193708. }
  193709. - gfar_write(&regs->tctrl, tctrl);
  193710. + if (priv->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
  193711. + tctrl |= TCTRL_VLINS;
  193712. - /* Set the extraction length and index */
  193713. - attrs = ATTRELI_EL(priv->rx_stash_size) |
  193714. - ATTRELI_EI(priv->rx_stash_index);
  193715. + gfar_write(&regs->tctrl, tctrl);
  193716. +}
  193717. - gfar_write(&regs->attreli, attrs);
  193718. +static void gfar_configure_coalescing(struct gfar_private *priv,
  193719. + unsigned long tx_mask, unsigned long rx_mask)
  193720. +{
  193721. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  193722. + u32 __iomem *baddr;
  193723. - /* Start with defaults, and add stashing or locking
  193724. - * depending on the approprate variables
  193725. - */
  193726. - attrs = ATTR_INIT_SETTINGS;
  193727. + if (priv->mode == MQ_MG_MODE) {
  193728. + int i = 0;
  193729. - if (priv->bd_stash_en)
  193730. - attrs |= ATTR_BDSTASH;
  193731. + baddr = &regs->txic0;
  193732. + for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
  193733. + gfar_write(baddr + i, 0);
  193734. + if (likely(priv->tx_queue[i]->txcoalescing))
  193735. + gfar_write(baddr + i, priv->tx_queue[i]->txic);
  193736. + }
  193737. - if (priv->rx_stash_size != 0)
  193738. - attrs |= ATTR_BUFSTASH;
  193739. + baddr = &regs->rxic0;
  193740. + for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
  193741. + gfar_write(baddr + i, 0);
  193742. + if (likely(priv->rx_queue[i]->rxcoalescing))
  193743. + gfar_write(baddr + i, priv->rx_queue[i]->rxic);
  193744. + }
  193745. + } else {
  193746. + /* Backward compatible case -- even if we enable
  193747. + * multiple queues, there's only single reg to program
  193748. + */
  193749. + gfar_write(&regs->txic, 0);
  193750. + if (likely(priv->tx_queue[0]->txcoalescing))
  193751. + gfar_write(&regs->txic, priv->tx_queue[0]->txic);
  193752. - gfar_write(&regs->attr, attrs);
  193753. + gfar_write(&regs->rxic, 0);
  193754. + if (unlikely(priv->rx_queue[0]->rxcoalescing))
  193755. + gfar_write(&regs->rxic, priv->rx_queue[0]->rxic);
  193756. + }
  193757. +}
  193758. - gfar_write(&regs->fifo_tx_thr, priv->fifo_threshold);
  193759. - gfar_write(&regs->fifo_tx_starve, priv->fifo_starve);
  193760. - gfar_write(&regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
  193761. +void gfar_configure_coalescing_all(struct gfar_private *priv)
  193762. +{
  193763. + gfar_configure_coalescing(priv, 0xFF, 0xFF);
  193764. }
  193765. static struct net_device_stats *gfar_get_stats(struct net_device *dev)
  193766. @@ -479,12 +504,27 @@
  193767. #endif
  193768. };
  193769. -void lock_rx_qs(struct gfar_private *priv)
  193770. +static void gfar_ints_disable(struct gfar_private *priv)
  193771. {
  193772. int i;
  193773. + for (i = 0; i < priv->num_grps; i++) {
  193774. + struct gfar __iomem *regs = priv->gfargrp[i].regs;
  193775. + /* Clear IEVENT */
  193776. + gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  193777. - for (i = 0; i < priv->num_rx_queues; i++)
  193778. - spin_lock(&priv->rx_queue[i]->rxlock);
  193779. + /* Initialize IMASK */
  193780. + gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  193781. + }
  193782. +}
  193783. +
  193784. +static void gfar_ints_enable(struct gfar_private *priv)
  193785. +{
  193786. + int i;
  193787. + for (i = 0; i < priv->num_grps; i++) {
  193788. + struct gfar __iomem *regs = priv->gfargrp[i].regs;
  193789. + /* Unmask the interrupts we look for */
  193790. + gfar_write(&regs->imask, IMASK_DEFAULT);
  193791. + }
  193792. }
  193793. void lock_tx_qs(struct gfar_private *priv)
  193794. @@ -495,23 +535,50 @@
  193795. spin_lock(&priv->tx_queue[i]->txlock);
  193796. }
  193797. -void unlock_rx_qs(struct gfar_private *priv)
  193798. +void unlock_tx_qs(struct gfar_private *priv)
  193799. {
  193800. int i;
  193801. - for (i = 0; i < priv->num_rx_queues; i++)
  193802. - spin_unlock(&priv->rx_queue[i]->rxlock);
  193803. + for (i = 0; i < priv->num_tx_queues; i++)
  193804. + spin_unlock(&priv->tx_queue[i]->txlock);
  193805. }
  193806. -void unlock_tx_qs(struct gfar_private *priv)
  193807. +static int gfar_alloc_tx_queues(struct gfar_private *priv)
  193808. {
  193809. int i;
  193810. - for (i = 0; i < priv->num_tx_queues; i++)
  193811. - spin_unlock(&priv->tx_queue[i]->txlock);
  193812. + for (i = 0; i < priv->num_tx_queues; i++) {
  193813. + priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
  193814. + GFP_KERNEL);
  193815. + if (!priv->tx_queue[i])
  193816. + return -ENOMEM;
  193817. +
  193818. + priv->tx_queue[i]->tx_skbuff = NULL;
  193819. + priv->tx_queue[i]->qindex = i;
  193820. + priv->tx_queue[i]->dev = priv->ndev;
  193821. + spin_lock_init(&(priv->tx_queue[i]->txlock));
  193822. + }
  193823. + return 0;
  193824. +}
  193825. +
  193826. +static int gfar_alloc_rx_queues(struct gfar_private *priv)
  193827. +{
  193828. + int i;
  193829. +
  193830. + for (i = 0; i < priv->num_rx_queues; i++) {
  193831. + priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
  193832. + GFP_KERNEL);
  193833. + if (!priv->rx_queue[i])
  193834. + return -ENOMEM;
  193835. +
  193836. + priv->rx_queue[i]->rx_skbuff = NULL;
  193837. + priv->rx_queue[i]->qindex = i;
  193838. + priv->rx_queue[i]->dev = priv->ndev;
  193839. + }
  193840. + return 0;
  193841. }
  193842. -static void free_tx_pointers(struct gfar_private *priv)
  193843. +static void gfar_free_tx_queues(struct gfar_private *priv)
  193844. {
  193845. int i;
  193846. @@ -519,7 +586,7 @@
  193847. kfree(priv->tx_queue[i]);
  193848. }
  193849. -static void free_rx_pointers(struct gfar_private *priv)
  193850. +static void gfar_free_rx_queues(struct gfar_private *priv)
  193851. {
  193852. int i;
  193853. @@ -553,23 +620,26 @@
  193854. {
  193855. int i;
  193856. - for (i = 0; i < priv->num_grps; i++)
  193857. - napi_disable(&priv->gfargrp[i].napi);
  193858. + for (i = 0; i < priv->num_grps; i++) {
  193859. + napi_disable(&priv->gfargrp[i].napi_rx);
  193860. + napi_disable(&priv->gfargrp[i].napi_tx);
  193861. + }
  193862. }
  193863. static void enable_napi(struct gfar_private *priv)
  193864. {
  193865. int i;
  193866. - for (i = 0; i < priv->num_grps; i++)
  193867. - napi_enable(&priv->gfargrp[i].napi);
  193868. + for (i = 0; i < priv->num_grps; i++) {
  193869. + napi_enable(&priv->gfargrp[i].napi_rx);
  193870. + napi_enable(&priv->gfargrp[i].napi_tx);
  193871. + }
  193872. }
  193873. static int gfar_parse_group(struct device_node *np,
  193874. struct gfar_private *priv, const char *model)
  193875. {
  193876. struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps];
  193877. - u32 *queue_mask;
  193878. int i;
  193879. for (i = 0; i < GFAR_NUM_IRQS; i++) {
  193880. @@ -598,16 +668,52 @@
  193881. grp->priv = priv;
  193882. spin_lock_init(&grp->grplock);
  193883. if (priv->mode == MQ_MG_MODE) {
  193884. - queue_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL);
  193885. - grp->rx_bit_map = queue_mask ?
  193886. - *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
  193887. - queue_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL);
  193888. - grp->tx_bit_map = queue_mask ?
  193889. - *queue_mask : (DEFAULT_MAPPING >> priv->num_grps);
  193890. + u32 *rxq_mask, *txq_mask;
  193891. + rxq_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL);
  193892. + txq_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL);
  193893. +
  193894. + if (priv->poll_mode == GFAR_SQ_POLLING) {
  193895. + /* One Q per interrupt group: Q0 to G0, Q1 to G1 */
  193896. + grp->rx_bit_map = (DEFAULT_MAPPING >> priv->num_grps);
  193897. + grp->tx_bit_map = (DEFAULT_MAPPING >> priv->num_grps);
  193898. + } else { /* GFAR_MQ_POLLING */
  193899. + grp->rx_bit_map = rxq_mask ?
  193900. + *rxq_mask : (DEFAULT_MAPPING >> priv->num_grps);
  193901. + grp->tx_bit_map = txq_mask ?
  193902. + *txq_mask : (DEFAULT_MAPPING >> priv->num_grps);
  193903. + }
  193904. } else {
  193905. grp->rx_bit_map = 0xFF;
  193906. grp->tx_bit_map = 0xFF;
  193907. }
  193908. +
  193909. + /* bit_map's MSB is q0 (from q0 to q7) but, for_each_set_bit parses
  193910. + * right to left, so we need to revert the 8 bits to get the q index
  193911. + */
  193912. + grp->rx_bit_map = bitrev8(grp->rx_bit_map);
  193913. + grp->tx_bit_map = bitrev8(grp->tx_bit_map);
  193914. +
  193915. + /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
  193916. + * also assign queues to groups
  193917. + */
  193918. + for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
  193919. + if (!grp->rx_queue)
  193920. + grp->rx_queue = priv->rx_queue[i];
  193921. + grp->num_rx_queues++;
  193922. + grp->rstat |= (RSTAT_CLEAR_RHALT >> i);
  193923. + priv->rqueue |= ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
  193924. + priv->rx_queue[i]->grp = grp;
  193925. + }
  193926. +
  193927. + for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
  193928. + if (!grp->tx_queue)
  193929. + grp->tx_queue = priv->tx_queue[i];
  193930. + grp->num_tx_queues++;
  193931. + grp->tstat |= (TSTAT_CLEAR_THALT >> i);
  193932. + priv->tqueue |= (TQUEUE_EN0 >> i);
  193933. + priv->tx_queue[i]->grp = grp;
  193934. + }
  193935. +
  193936. priv->num_grps++;
  193937. return 0;
  193938. @@ -628,13 +734,45 @@
  193939. const u32 *stash_idx;
  193940. unsigned int num_tx_qs, num_rx_qs;
  193941. u32 *tx_queues, *rx_queues;
  193942. + unsigned short mode, poll_mode;
  193943. if (!np || !of_device_is_available(np))
  193944. return -ENODEV;
  193945. - /* parse the num of tx and rx queues */
  193946. + if (of_device_is_compatible(np, "fsl,etsec2")) {
  193947. + mode = MQ_MG_MODE;
  193948. + poll_mode = GFAR_SQ_POLLING;
  193949. + } else {
  193950. + mode = SQ_SG_MODE;
  193951. + poll_mode = GFAR_SQ_POLLING;
  193952. + }
  193953. +
  193954. + /* parse the num of HW tx and rx queues */
  193955. tx_queues = (u32 *)of_get_property(np, "fsl,num_tx_queues", NULL);
  193956. - num_tx_qs = tx_queues ? *tx_queues : 1;
  193957. + rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
  193958. +
  193959. + if (mode == SQ_SG_MODE) {
  193960. + num_tx_qs = 1;
  193961. + num_rx_qs = 1;
  193962. + } else { /* MQ_MG_MODE */
  193963. + /* get the actual number of supported groups */
  193964. + unsigned int num_grps = of_get_available_child_count(np);
  193965. +
  193966. + if (num_grps == 0 || num_grps > MAXGROUPS) {
  193967. + dev_err(&ofdev->dev, "Invalid # of int groups(%d)\n",
  193968. + num_grps);
  193969. + pr_err("Cannot do alloc_etherdev, aborting\n");
  193970. + return -EINVAL;
  193971. + }
  193972. +
  193973. + if (poll_mode == GFAR_SQ_POLLING) {
  193974. + num_tx_qs = num_grps; /* one txq per int group */
  193975. + num_rx_qs = num_grps; /* one rxq per int group */
  193976. + } else { /* GFAR_MQ_POLLING */
  193977. + num_tx_qs = tx_queues ? *tx_queues : 1;
  193978. + num_rx_qs = rx_queues ? *rx_queues : 1;
  193979. + }
  193980. + }
  193981. if (num_tx_qs > MAX_TX_QS) {
  193982. pr_err("num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n",
  193983. @@ -643,9 +781,6 @@
  193984. return -EINVAL;
  193985. }
  193986. - rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
  193987. - num_rx_qs = rx_queues ? *rx_queues : 1;
  193988. -
  193989. if (num_rx_qs > MAX_RX_QS) {
  193990. pr_err("num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n",
  193991. num_rx_qs, MAX_RX_QS);
  193992. @@ -661,10 +796,20 @@
  193993. priv = netdev_priv(dev);
  193994. priv->ndev = dev;
  193995. + priv->mode = mode;
  193996. + priv->poll_mode = poll_mode;
  193997. +
  193998. priv->num_tx_queues = num_tx_qs;
  193999. netif_set_real_num_rx_queues(dev, num_rx_qs);
  194000. priv->num_rx_queues = num_rx_qs;
  194001. - priv->num_grps = 0x0;
  194002. +
  194003. + err = gfar_alloc_tx_queues(priv);
  194004. + if (err)
  194005. + goto tx_alloc_failed;
  194006. +
  194007. + err = gfar_alloc_rx_queues(priv);
  194008. + if (err)
  194009. + goto rx_alloc_failed;
  194010. /* Init Rx queue filer rule set linked list */
  194011. INIT_LIST_HEAD(&priv->rx_list.list);
  194012. @@ -677,52 +822,18 @@
  194013. priv->gfargrp[i].regs = NULL;
  194014. /* Parse and initialize group specific information */
  194015. - if (of_device_is_compatible(np, "fsl,etsec2")) {
  194016. - priv->mode = MQ_MG_MODE;
  194017. + if (priv->mode == MQ_MG_MODE) {
  194018. for_each_child_of_node(np, child) {
  194019. err = gfar_parse_group(child, priv, model);
  194020. if (err)
  194021. goto err_grp_init;
  194022. }
  194023. - } else {
  194024. - priv->mode = SQ_SG_MODE;
  194025. + } else { /* SQ_SG_MODE */
  194026. err = gfar_parse_group(np, priv, model);
  194027. if (err)
  194028. goto err_grp_init;
  194029. }
  194030. - for (i = 0; i < priv->num_tx_queues; i++)
  194031. - priv->tx_queue[i] = NULL;
  194032. - for (i = 0; i < priv->num_rx_queues; i++)
  194033. - priv->rx_queue[i] = NULL;
  194034. -
  194035. - for (i = 0; i < priv->num_tx_queues; i++) {
  194036. - priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
  194037. - GFP_KERNEL);
  194038. - if (!priv->tx_queue[i]) {
  194039. - err = -ENOMEM;
  194040. - goto tx_alloc_failed;
  194041. - }
  194042. - priv->tx_queue[i]->tx_skbuff = NULL;
  194043. - priv->tx_queue[i]->qindex = i;
  194044. - priv->tx_queue[i]->dev = dev;
  194045. - spin_lock_init(&(priv->tx_queue[i]->txlock));
  194046. - }
  194047. -
  194048. - for (i = 0; i < priv->num_rx_queues; i++) {
  194049. - priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
  194050. - GFP_KERNEL);
  194051. - if (!priv->rx_queue[i]) {
  194052. - err = -ENOMEM;
  194053. - goto rx_alloc_failed;
  194054. - }
  194055. - priv->rx_queue[i]->rx_skbuff = NULL;
  194056. - priv->rx_queue[i]->qindex = i;
  194057. - priv->rx_queue[i]->dev = dev;
  194058. - spin_lock_init(&(priv->rx_queue[i]->rxlock));
  194059. - }
  194060. -
  194061. -
  194062. stash = of_get_property(np, "bd-stash", NULL);
  194063. if (stash) {
  194064. @@ -749,17 +860,16 @@
  194065. memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
  194066. if (model && !strcasecmp(model, "TSEC"))
  194067. - priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
  194068. + priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
  194069. FSL_GIANFAR_DEV_HAS_COALESCE |
  194070. FSL_GIANFAR_DEV_HAS_RMON |
  194071. FSL_GIANFAR_DEV_HAS_MULTI_INTR;
  194072. if (model && !strcasecmp(model, "eTSEC"))
  194073. - priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
  194074. + priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
  194075. FSL_GIANFAR_DEV_HAS_COALESCE |
  194076. FSL_GIANFAR_DEV_HAS_RMON |
  194077. FSL_GIANFAR_DEV_HAS_MULTI_INTR |
  194078. - FSL_GIANFAR_DEV_HAS_PADDING |
  194079. FSL_GIANFAR_DEV_HAS_CSUM |
  194080. FSL_GIANFAR_DEV_HAS_VLAN |
  194081. FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
  194082. @@ -779,17 +889,28 @@
  194083. priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
  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. + goto err_grp_init;
  194091. +
  194092. + priv->phy_node = np;
  194093. + }
  194094. +
  194095. /* Find the TBI PHY. If it's not there, we don't support SGMII */
  194096. priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
  194097. return 0;
  194098. -rx_alloc_failed:
  194099. - free_rx_pointers(priv);
  194100. -tx_alloc_failed:
  194101. - free_tx_pointers(priv);
  194102. err_grp_init:
  194103. unmap_group_regs(priv);
  194104. +rx_alloc_failed:
  194105. + gfar_free_rx_queues(priv);
  194106. +tx_alloc_failed:
  194107. + gfar_free_tx_queues(priv);
  194108. free_gfar_dev(priv);
  194109. return err;
  194110. }
  194111. @@ -822,18 +943,16 @@
  194112. switch (config.rx_filter) {
  194113. case HWTSTAMP_FILTER_NONE:
  194114. if (priv->hwts_rx_en) {
  194115. - stop_gfar(netdev);
  194116. priv->hwts_rx_en = 0;
  194117. - startup_gfar(netdev);
  194118. + reset_gfar(netdev);
  194119. }
  194120. break;
  194121. default:
  194122. if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER))
  194123. return -ERANGE;
  194124. if (!priv->hwts_rx_en) {
  194125. - stop_gfar(netdev);
  194126. priv->hwts_rx_en = 1;
  194127. - startup_gfar(netdev);
  194128. + reset_gfar(netdev);
  194129. }
  194130. config.rx_filter = HWTSTAMP_FILTER_ALL;
  194131. break;
  194132. @@ -875,19 +994,6 @@
  194133. return phy_mii_ioctl(priv->phydev, rq, cmd);
  194134. }
  194135. -static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs)
  194136. -{
  194137. - unsigned int new_bit_map = 0x0;
  194138. - int mask = 0x1 << (max_qs - 1), i;
  194139. -
  194140. - for (i = 0; i < max_qs; i++) {
  194141. - if (bit_map & mask)
  194142. - new_bit_map = new_bit_map + (1 << i);
  194143. - mask = mask >> 0x1;
  194144. - }
  194145. - return new_bit_map;
  194146. -}
  194147. -
  194148. static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
  194149. u32 class)
  194150. {
  194151. @@ -1005,100 +1111,141 @@
  194152. priv->errata);
  194153. }
  194154. -/* Set up the ethernet device structure, private data,
  194155. - * and anything else we need before we start
  194156. - */
  194157. -static int gfar_probe(struct platform_device *ofdev)
  194158. +void gfar_mac_reset(struct gfar_private *priv)
  194159. {
  194160. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194161. u32 tempval;
  194162. - struct net_device *dev = NULL;
  194163. - struct gfar_private *priv = NULL;
  194164. - struct gfar __iomem *regs = NULL;
  194165. - int err = 0, i, grp_idx = 0;
  194166. - u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0;
  194167. - u32 isrg = 0;
  194168. - u32 __iomem *baddr;
  194169. -
  194170. - err = gfar_of_init(ofdev, &dev);
  194171. -
  194172. - if (err)
  194173. - return err;
  194174. -
  194175. - priv = netdev_priv(dev);
  194176. - priv->ndev = dev;
  194177. - priv->ofdev = ofdev;
  194178. - priv->dev = &ofdev->dev;
  194179. - SET_NETDEV_DEV(dev, &ofdev->dev);
  194180. -
  194181. - spin_lock_init(&priv->bflock);
  194182. - INIT_WORK(&priv->reset_task, gfar_reset_task);
  194183. -
  194184. - platform_set_drvdata(ofdev, priv);
  194185. - regs = priv->gfargrp[0].regs;
  194186. -
  194187. - gfar_detect_errata(priv);
  194188. -
  194189. - /* Stop the DMA engine now, in case it was running before
  194190. - * (The firmware could have used it, and left it running).
  194191. - */
  194192. - gfar_halt(dev);
  194193. /* Reset MAC layer */
  194194. gfar_write(&regs->maccfg1, MACCFG1_SOFT_RESET);
  194195. /* We need to delay at least 3 TX clocks */
  194196. - udelay(2);
  194197. + udelay(3);
  194198. - tempval = 0;
  194199. - if (!priv->pause_aneg_en && priv->tx_pause_en)
  194200. - tempval |= MACCFG1_TX_FLOW;
  194201. - if (!priv->pause_aneg_en && priv->rx_pause_en)
  194202. - tempval |= MACCFG1_RX_FLOW;
  194203. /* the soft reset bit is not self-resetting, so we need to
  194204. * clear it before resuming normal operation
  194205. */
  194206. - gfar_write(&regs->maccfg1, tempval);
  194207. + gfar_write(&regs->maccfg1, 0);
  194208. - /* Initialize MACCFG2. */
  194209. - tempval = MACCFG2_INIT_SETTINGS;
  194210. - if (gfar_has_errata(priv, GFAR_ERRATA_74))
  194211. - tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
  194212. - gfar_write(&regs->maccfg2, tempval);
  194213. + udelay(3);
  194214. - /* Initialize ECNTRL */
  194215. - gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
  194216. + /* Compute rx_buff_size based on config flags */
  194217. + gfar_rx_buff_size_config(priv);
  194218. - /* Set the dev->base_addr to the gfar reg region */
  194219. - dev->base_addr = (unsigned long) regs;
  194220. + /* Initialize the max receive frame/buffer lengths */
  194221. + gfar_write(&regs->maxfrm, priv->rx_buffer_size);
  194222. + gfar_write(&regs->mrblr, priv->rx_buffer_size);
  194223. - /* Fill in the dev structure */
  194224. - dev->watchdog_timeo = TX_TIMEOUT;
  194225. - dev->mtu = 1500;
  194226. - dev->netdev_ops = &gfar_netdev_ops;
  194227. - dev->ethtool_ops = &gfar_ethtool_ops;
  194228. + /* Initialize the Minimum Frame Length Register */
  194229. + gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
  194230. - /* Register for napi ...We are registering NAPI for each grp */
  194231. - if (priv->mode == SQ_SG_MODE)
  194232. - netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq,
  194233. - GFAR_DEV_WEIGHT);
  194234. - else
  194235. - for (i = 0; i < priv->num_grps; i++)
  194236. - netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
  194237. - GFAR_DEV_WEIGHT);
  194238. + /* Initialize MACCFG2. */
  194239. + tempval = MACCFG2_INIT_SETTINGS;
  194240. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
  194241. - dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
  194242. - NETIF_F_RXCSUM;
  194243. - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
  194244. - NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
  194245. - }
  194246. + /* If the mtu is larger than the max size for standard
  194247. + * ethernet frames (ie, a jumbo frame), then set maccfg2
  194248. + * to allow huge frames, and to check the length
  194249. + */
  194250. + if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
  194251. + gfar_has_errata(priv, GFAR_ERRATA_74))
  194252. + tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
  194253. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
  194254. - dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
  194255. - NETIF_F_HW_VLAN_CTAG_RX;
  194256. - dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  194257. + gfar_write(&regs->maccfg2, tempval);
  194258. +
  194259. + /* Clear mac addr hash registers */
  194260. + gfar_write(&regs->igaddr0, 0);
  194261. + gfar_write(&regs->igaddr1, 0);
  194262. + gfar_write(&regs->igaddr2, 0);
  194263. + gfar_write(&regs->igaddr3, 0);
  194264. + gfar_write(&regs->igaddr4, 0);
  194265. + gfar_write(&regs->igaddr5, 0);
  194266. + gfar_write(&regs->igaddr6, 0);
  194267. + gfar_write(&regs->igaddr7, 0);
  194268. +
  194269. + gfar_write(&regs->gaddr0, 0);
  194270. + gfar_write(&regs->gaddr1, 0);
  194271. + gfar_write(&regs->gaddr2, 0);
  194272. + gfar_write(&regs->gaddr3, 0);
  194273. + gfar_write(&regs->gaddr4, 0);
  194274. + gfar_write(&regs->gaddr5, 0);
  194275. + gfar_write(&regs->gaddr6, 0);
  194276. + gfar_write(&regs->gaddr7, 0);
  194277. +
  194278. + if (priv->extended_hash)
  194279. + gfar_clear_exact_match(priv->ndev);
  194280. +
  194281. + gfar_mac_rx_config(priv);
  194282. +
  194283. + gfar_mac_tx_config(priv);
  194284. +
  194285. + gfar_set_mac_address(priv->ndev);
  194286. +
  194287. + gfar_set_multi(priv->ndev);
  194288. +
  194289. + /* clear ievent and imask before configuring coalescing */
  194290. + gfar_ints_disable(priv);
  194291. +
  194292. + /* Configure the coalescing support */
  194293. + gfar_configure_coalescing_all(priv);
  194294. +}
  194295. +
  194296. +static void gfar_hw_init(struct gfar_private *priv)
  194297. +{
  194298. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194299. + u32 attrs;
  194300. +
  194301. + /* Stop the DMA engine now, in case it was running before
  194302. + * (The firmware could have used it, and left it running).
  194303. + */
  194304. + gfar_halt(priv);
  194305. +
  194306. + gfar_mac_reset(priv);
  194307. +
  194308. + /* Zero out the rmon mib registers if it has them */
  194309. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
  194310. + memset_io(&(regs->rmon), 0, sizeof(struct rmon_mib));
  194311. +
  194312. + /* Mask off the CAM interrupts */
  194313. + gfar_write(&regs->rmon.cam1, 0xffffffff);
  194314. + gfar_write(&regs->rmon.cam2, 0xffffffff);
  194315. }
  194316. + /* Initialize ECNTRL */
  194317. + gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
  194318. +
  194319. + /* Set the extraction length and index */
  194320. + attrs = ATTRELI_EL(priv->rx_stash_size) |
  194321. + ATTRELI_EI(priv->rx_stash_index);
  194322. +
  194323. + gfar_write(&regs->attreli, attrs);
  194324. +
  194325. + /* Start with defaults, and add stashing
  194326. + * depending on driver parameters
  194327. + */
  194328. + attrs = ATTR_INIT_SETTINGS;
  194329. +
  194330. + if (priv->bd_stash_en)
  194331. + attrs |= ATTR_BDSTASH;
  194332. +
  194333. + if (priv->rx_stash_size != 0)
  194334. + attrs |= ATTR_BUFSTASH;
  194335. +
  194336. + gfar_write(&regs->attr, attrs);
  194337. +
  194338. + /* FIFO configs */
  194339. + gfar_write(&regs->fifo_tx_thr, DEFAULT_FIFO_TX_THR);
  194340. + gfar_write(&regs->fifo_tx_starve, DEFAULT_FIFO_TX_STARVE);
  194341. + gfar_write(&regs->fifo_tx_starve_shutoff, DEFAULT_FIFO_TX_STARVE_OFF);
  194342. +
  194343. + /* Program the interrupt steering regs, only for MG devices */
  194344. + if (priv->num_grps > 1)
  194345. + gfar_write_isrg(priv);
  194346. +}
  194347. +
  194348. +static void gfar_init_addr_hash_table(struct gfar_private *priv)
  194349. +{
  194350. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194351. +
  194352. if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
  194353. priv->extended_hash = 1;
  194354. priv->hash_width = 9;
  194355. @@ -1133,68 +1280,81 @@
  194356. priv->hash_regs[6] = &regs->gaddr6;
  194357. priv->hash_regs[7] = &regs->gaddr7;
  194358. }
  194359. +}
  194360. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING)
  194361. - priv->padding = DEFAULT_PADDING;
  194362. - else
  194363. - priv->padding = 0;
  194364. +/* Set up the ethernet device structure, private data,
  194365. + * and anything else we need before we start
  194366. + */
  194367. +static int gfar_probe(struct platform_device *ofdev)
  194368. +{
  194369. + struct net_device *dev = NULL;
  194370. + struct gfar_private *priv = NULL;
  194371. + int err = 0, i;
  194372. - if (dev->features & NETIF_F_IP_CSUM ||
  194373. - priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  194374. - dev->needed_headroom = GMAC_FCB_LEN;
  194375. + err = gfar_of_init(ofdev, &dev);
  194376. - /* Program the isrg regs only if number of grps > 1 */
  194377. - if (priv->num_grps > 1) {
  194378. - baddr = &regs->isrg0;
  194379. - for (i = 0; i < priv->num_grps; i++) {
  194380. - isrg |= (priv->gfargrp[i].rx_bit_map << ISRG_SHIFT_RX);
  194381. - isrg |= (priv->gfargrp[i].tx_bit_map << ISRG_SHIFT_TX);
  194382. - gfar_write(baddr, isrg);
  194383. - baddr++;
  194384. - isrg = 0x0;
  194385. + if (err)
  194386. + return err;
  194387. +
  194388. + priv = netdev_priv(dev);
  194389. + priv->ndev = dev;
  194390. + priv->ofdev = ofdev;
  194391. + priv->dev = &ofdev->dev;
  194392. + SET_NETDEV_DEV(dev, &ofdev->dev);
  194393. +
  194394. + spin_lock_init(&priv->bflock);
  194395. + INIT_WORK(&priv->reset_task, gfar_reset_task);
  194396. +
  194397. + platform_set_drvdata(ofdev, priv);
  194398. +
  194399. + gfar_detect_errata(priv);
  194400. +
  194401. + /* Set the dev->base_addr to the gfar reg region */
  194402. + dev->base_addr = (unsigned long) priv->gfargrp[0].regs;
  194403. +
  194404. + /* Fill in the dev structure */
  194405. + dev->watchdog_timeo = TX_TIMEOUT;
  194406. + dev->mtu = 1500;
  194407. + dev->netdev_ops = &gfar_netdev_ops;
  194408. + dev->ethtool_ops = &gfar_ethtool_ops;
  194409. +
  194410. + /* Register for napi ...We are registering NAPI for each grp */
  194411. + for (i = 0; i < priv->num_grps; i++) {
  194412. + if (priv->poll_mode == GFAR_SQ_POLLING) {
  194413. + netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
  194414. + gfar_poll_rx_sq, GFAR_DEV_WEIGHT);
  194415. + netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
  194416. + gfar_poll_tx_sq, 2);
  194417. + } else {
  194418. + netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
  194419. + gfar_poll_rx, GFAR_DEV_WEIGHT);
  194420. + netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
  194421. + gfar_poll_tx, 2);
  194422. }
  194423. }
  194424. - /* Need to reverse the bit maps as bit_map's MSB is q0
  194425. - * but, for_each_set_bit parses from right to left, which
  194426. - * basically reverses the queue numbers
  194427. - */
  194428. - for (i = 0; i< priv->num_grps; i++) {
  194429. - priv->gfargrp[i].tx_bit_map =
  194430. - reverse_bitmap(priv->gfargrp[i].tx_bit_map, MAX_TX_QS);
  194431. - priv->gfargrp[i].rx_bit_map =
  194432. - reverse_bitmap(priv->gfargrp[i].rx_bit_map, MAX_RX_QS);
  194433. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
  194434. + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
  194435. + NETIF_F_RXCSUM;
  194436. + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
  194437. + NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
  194438. }
  194439. - /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
  194440. - * also assign queues to groups
  194441. - */
  194442. - for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
  194443. - priv->gfargrp[grp_idx].num_rx_queues = 0x0;
  194444. -
  194445. - for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
  194446. - priv->num_rx_queues) {
  194447. - priv->gfargrp[grp_idx].num_rx_queues++;
  194448. - priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
  194449. - rstat = rstat | (RSTAT_CLEAR_RHALT >> i);
  194450. - rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
  194451. - }
  194452. - priv->gfargrp[grp_idx].num_tx_queues = 0x0;
  194453. -
  194454. - for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map,
  194455. - priv->num_tx_queues) {
  194456. - priv->gfargrp[grp_idx].num_tx_queues++;
  194457. - priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
  194458. - tstat = tstat | (TSTAT_CLEAR_THALT >> i);
  194459. - tqueue = tqueue | (TQUEUE_EN0 >> i);
  194460. - }
  194461. - priv->gfargrp[grp_idx].rstat = rstat;
  194462. - priv->gfargrp[grp_idx].tstat = tstat;
  194463. - rstat = tstat =0;
  194464. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
  194465. + dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
  194466. + NETIF_F_HW_VLAN_CTAG_RX;
  194467. + dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
  194468. }
  194469. - gfar_write(&regs->rqueue, rqueue);
  194470. - gfar_write(&regs->tqueue, tqueue);
  194471. + gfar_init_addr_hash_table(priv);
  194472. +
  194473. + /* Insert receive time stamps into padding alignment bytes */
  194474. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  194475. + priv->padding = 8;
  194476. +
  194477. + if (dev->features & NETIF_F_IP_CSUM ||
  194478. + priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
  194479. + dev->needed_headroom = GMAC_FCB_LEN;
  194480. priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
  194481. @@ -1220,6 +1380,10 @@
  194482. if (priv->num_tx_queues == 1)
  194483. priv->prio_sched_en = 1;
  194484. + set_bit(GFAR_DOWN, &priv->state);
  194485. +
  194486. + gfar_hw_init(priv);
  194487. +
  194488. /* Carrier starts down, phylib will bring it up */
  194489. netif_carrier_off(dev);
  194490. @@ -1251,9 +1415,6 @@
  194491. /* Initialize the filer table */
  194492. gfar_init_filer_table(priv);
  194493. - /* Create all the sysfs files */
  194494. - gfar_init_sysfs(dev);
  194495. -
  194496. /* Print out the device info */
  194497. netdev_info(dev, "mac: %pM\n", dev->dev_addr);
  194498. @@ -1272,8 +1433,8 @@
  194499. register_fail:
  194500. unmap_group_regs(priv);
  194501. - free_tx_pointers(priv);
  194502. - free_rx_pointers(priv);
  194503. + gfar_free_rx_queues(priv);
  194504. + gfar_free_tx_queues(priv);
  194505. if (priv->phy_node)
  194506. of_node_put(priv->phy_node);
  194507. if (priv->tbi_node)
  194508. @@ -1293,6 +1454,8 @@
  194509. unregister_netdev(priv->ndev);
  194510. unmap_group_regs(priv);
  194511. + gfar_free_rx_queues(priv);
  194512. + gfar_free_tx_queues(priv);
  194513. free_gfar_dev(priv);
  194514. return 0;
  194515. @@ -1318,9 +1481,8 @@
  194516. local_irq_save(flags);
  194517. lock_tx_qs(priv);
  194518. - lock_rx_qs(priv);
  194519. - gfar_halt_nodisable(ndev);
  194520. + gfar_halt_nodisable(priv);
  194521. /* Disable Tx, and Rx if wake-on-LAN is disabled. */
  194522. tempval = gfar_read(&regs->maccfg1);
  194523. @@ -1332,7 +1494,6 @@
  194524. gfar_write(&regs->maccfg1, tempval);
  194525. - unlock_rx_qs(priv);
  194526. unlock_tx_qs(priv);
  194527. local_irq_restore(flags);
  194528. @@ -1378,15 +1539,13 @@
  194529. */
  194530. local_irq_save(flags);
  194531. lock_tx_qs(priv);
  194532. - lock_rx_qs(priv);
  194533. tempval = gfar_read(&regs->maccfg2);
  194534. tempval &= ~MACCFG2_MPEN;
  194535. gfar_write(&regs->maccfg2, tempval);
  194536. - gfar_start(ndev);
  194537. + gfar_start(priv);
  194538. - unlock_rx_qs(priv);
  194539. unlock_tx_qs(priv);
  194540. local_irq_restore(flags);
  194541. @@ -1413,10 +1572,11 @@
  194542. return -ENOMEM;
  194543. }
  194544. - init_registers(ndev);
  194545. - gfar_set_mac_address(ndev);
  194546. - gfar_init_mac(ndev);
  194547. - gfar_start(ndev);
  194548. + gfar_mac_reset(priv);
  194549. +
  194550. + gfar_init_tx_rx_base(priv);
  194551. +
  194552. + gfar_start(priv);
  194553. priv->oldlink = 0;
  194554. priv->oldspeed = 0;
  194555. @@ -1511,9 +1671,6 @@
  194556. priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,
  194557. interface);
  194558. - if (!priv->phydev)
  194559. - priv->phydev = of_phy_connect_fixed_link(dev, &adjust_link,
  194560. - interface);
  194561. if (!priv->phydev) {
  194562. dev_err(&dev->dev, "could not attach to PHY\n");
  194563. return -ENODEV;
  194564. @@ -1574,57 +1731,6 @@
  194565. BMCR_SPEED1000);
  194566. }
  194567. -static void init_registers(struct net_device *dev)
  194568. -{
  194569. - struct gfar_private *priv = netdev_priv(dev);
  194570. - struct gfar __iomem *regs = NULL;
  194571. - int i;
  194572. -
  194573. - for (i = 0; i < priv->num_grps; i++) {
  194574. - regs = priv->gfargrp[i].regs;
  194575. - /* Clear IEVENT */
  194576. - gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  194577. -
  194578. - /* Initialize IMASK */
  194579. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  194580. - }
  194581. -
  194582. - regs = priv->gfargrp[0].regs;
  194583. - /* Init hash registers to zero */
  194584. - gfar_write(&regs->igaddr0, 0);
  194585. - gfar_write(&regs->igaddr1, 0);
  194586. - gfar_write(&regs->igaddr2, 0);
  194587. - gfar_write(&regs->igaddr3, 0);
  194588. - gfar_write(&regs->igaddr4, 0);
  194589. - gfar_write(&regs->igaddr5, 0);
  194590. - gfar_write(&regs->igaddr6, 0);
  194591. - gfar_write(&regs->igaddr7, 0);
  194592. -
  194593. - gfar_write(&regs->gaddr0, 0);
  194594. - gfar_write(&regs->gaddr1, 0);
  194595. - gfar_write(&regs->gaddr2, 0);
  194596. - gfar_write(&regs->gaddr3, 0);
  194597. - gfar_write(&regs->gaddr4, 0);
  194598. - gfar_write(&regs->gaddr5, 0);
  194599. - gfar_write(&regs->gaddr6, 0);
  194600. - gfar_write(&regs->gaddr7, 0);
  194601. -
  194602. - /* Zero out the rmon mib registers if it has them */
  194603. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
  194604. - memset_io(&(regs->rmon), 0, sizeof (struct rmon_mib));
  194605. -
  194606. - /* Mask off the CAM interrupts */
  194607. - gfar_write(&regs->rmon.cam1, 0xffffffff);
  194608. - gfar_write(&regs->rmon.cam2, 0xffffffff);
  194609. - }
  194610. -
  194611. - /* Initialize the max receive buffer length */
  194612. - gfar_write(&regs->mrblr, priv->rx_buffer_size);
  194613. -
  194614. - /* Initialize the Minimum Frame Length Register */
  194615. - gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
  194616. -}
  194617. -
  194618. static int __gfar_is_rx_idle(struct gfar_private *priv)
  194619. {
  194620. u32 res;
  194621. @@ -1648,23 +1754,13 @@
  194622. }
  194623. /* Halt the receive and transmit queues */
  194624. -static void gfar_halt_nodisable(struct net_device *dev)
  194625. +static void gfar_halt_nodisable(struct gfar_private *priv)
  194626. {
  194627. - struct gfar_private *priv = netdev_priv(dev);
  194628. - struct gfar __iomem *regs = NULL;
  194629. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194630. u32 tempval;
  194631. - int i;
  194632. -
  194633. - for (i = 0; i < priv->num_grps; i++) {
  194634. - regs = priv->gfargrp[i].regs;
  194635. - /* Mask all interrupts */
  194636. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  194637. - /* Clear all interrupts */
  194638. - gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
  194639. - }
  194640. + gfar_ints_disable(priv);
  194641. - regs = priv->gfargrp[0].regs;
  194642. /* Stop the DMA, and wait for it to stop */
  194643. tempval = gfar_read(&regs->dmactrl);
  194644. if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) !=
  194645. @@ -1685,56 +1781,41 @@
  194646. }
  194647. /* Halt the receive and transmit queues */
  194648. -void gfar_halt(struct net_device *dev)
  194649. +void gfar_halt(struct gfar_private *priv)
  194650. {
  194651. - struct gfar_private *priv = netdev_priv(dev);
  194652. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194653. u32 tempval;
  194654. - gfar_halt_nodisable(dev);
  194655. + /* Dissable the Rx/Tx hw queues */
  194656. + gfar_write(&regs->rqueue, 0);
  194657. + gfar_write(&regs->tqueue, 0);
  194658. - /* Disable Rx and Tx */
  194659. + mdelay(10);
  194660. +
  194661. + gfar_halt_nodisable(priv);
  194662. +
  194663. + /* Disable Rx/Tx DMA */
  194664. tempval = gfar_read(&regs->maccfg1);
  194665. tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
  194666. gfar_write(&regs->maccfg1, tempval);
  194667. }
  194668. -static void free_grp_irqs(struct gfar_priv_grp *grp)
  194669. -{
  194670. - free_irq(gfar_irq(grp, TX)->irq, grp);
  194671. - free_irq(gfar_irq(grp, RX)->irq, grp);
  194672. - free_irq(gfar_irq(grp, ER)->irq, grp);
  194673. -}
  194674. -
  194675. void stop_gfar(struct net_device *dev)
  194676. {
  194677. struct gfar_private *priv = netdev_priv(dev);
  194678. - unsigned long flags;
  194679. - int i;
  194680. -
  194681. - phy_stop(priv->phydev);
  194682. + netif_tx_stop_all_queues(dev);
  194683. - /* Lock it down */
  194684. - local_irq_save(flags);
  194685. - lock_tx_qs(priv);
  194686. - lock_rx_qs(priv);
  194687. + smp_mb__before_clear_bit();
  194688. + set_bit(GFAR_DOWN, &priv->state);
  194689. + smp_mb__after_clear_bit();
  194690. - gfar_halt(dev);
  194691. + disable_napi(priv);
  194692. - unlock_rx_qs(priv);
  194693. - unlock_tx_qs(priv);
  194694. - local_irq_restore(flags);
  194695. + /* disable ints and gracefully shut down Rx/Tx DMA */
  194696. + gfar_halt(priv);
  194697. - /* Free the IRQs */
  194698. - if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
  194699. - for (i = 0; i < priv->num_grps; i++)
  194700. - free_grp_irqs(&priv->gfargrp[i]);
  194701. - } else {
  194702. - for (i = 0; i < priv->num_grps; i++)
  194703. - free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
  194704. - &priv->gfargrp[i]);
  194705. - }
  194706. + phy_stop(priv->phydev);
  194707. free_skb_resources(priv);
  194708. }
  194709. @@ -1825,17 +1906,15 @@
  194710. priv->tx_queue[0]->tx_bd_dma_base);
  194711. }
  194712. -void gfar_start(struct net_device *dev)
  194713. +void gfar_start(struct gfar_private *priv)
  194714. {
  194715. - struct gfar_private *priv = netdev_priv(dev);
  194716. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194717. u32 tempval;
  194718. int i = 0;
  194719. - /* Enable Rx and Tx in MACCFG1 */
  194720. - tempval = gfar_read(&regs->maccfg1);
  194721. - tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
  194722. - gfar_write(&regs->maccfg1, tempval);
  194723. + /* Enable Rx/Tx hw queues */
  194724. + gfar_write(&regs->rqueue, priv->rqueue);
  194725. + gfar_write(&regs->tqueue, priv->tqueue);
  194726. /* Initialize DMACTRL to have WWR and WOP */
  194727. tempval = gfar_read(&regs->dmactrl);
  194728. @@ -1852,52 +1931,23 @@
  194729. /* Clear THLT/RHLT, so that the DMA starts polling now */
  194730. gfar_write(&regs->tstat, priv->gfargrp[i].tstat);
  194731. gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
  194732. - /* Unmask the interrupts we look for */
  194733. - gfar_write(&regs->imask, IMASK_DEFAULT);
  194734. }
  194735. - dev->trans_start = jiffies; /* prevent tx timeout */
  194736. -}
  194737. -
  194738. -static void gfar_configure_coalescing(struct gfar_private *priv,
  194739. - unsigned long tx_mask, unsigned long rx_mask)
  194740. -{
  194741. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194742. - u32 __iomem *baddr;
  194743. + /* Enable Rx/Tx DMA */
  194744. + tempval = gfar_read(&regs->maccfg1);
  194745. + tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
  194746. + gfar_write(&regs->maccfg1, tempval);
  194747. - if (priv->mode == MQ_MG_MODE) {
  194748. - int i = 0;
  194749. + gfar_ints_enable(priv);
  194750. - baddr = &regs->txic0;
  194751. - for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
  194752. - gfar_write(baddr + i, 0);
  194753. - if (likely(priv->tx_queue[i]->txcoalescing))
  194754. - gfar_write(baddr + i, priv->tx_queue[i]->txic);
  194755. - }
  194756. -
  194757. - baddr = &regs->rxic0;
  194758. - for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
  194759. - gfar_write(baddr + i, 0);
  194760. - if (likely(priv->rx_queue[i]->rxcoalescing))
  194761. - gfar_write(baddr + i, priv->rx_queue[i]->rxic);
  194762. - }
  194763. - } else {
  194764. - /* Backward compatible case -- even if we enable
  194765. - * multiple queues, there's only single reg to program
  194766. - */
  194767. - gfar_write(&regs->txic, 0);
  194768. - if (likely(priv->tx_queue[0]->txcoalescing))
  194769. - gfar_write(&regs->txic, priv->tx_queue[0]->txic);
  194770. -
  194771. - gfar_write(&regs->rxic, 0);
  194772. - if (unlikely(priv->rx_queue[0]->rxcoalescing))
  194773. - gfar_write(&regs->rxic, priv->rx_queue[0]->rxic);
  194774. - }
  194775. + priv->ndev->trans_start = jiffies; /* prevent tx timeout */
  194776. }
  194777. -void gfar_configure_coalescing_all(struct gfar_private *priv)
  194778. +static void free_grp_irqs(struct gfar_priv_grp *grp)
  194779. {
  194780. - gfar_configure_coalescing(priv, 0xFF, 0xFF);
  194781. + free_irq(gfar_irq(grp, TX)->irq, grp);
  194782. + free_irq(gfar_irq(grp, RX)->irq, grp);
  194783. + free_irq(gfar_irq(grp, ER)->irq, grp);
  194784. }
  194785. static int register_grp_irqs(struct gfar_priv_grp *grp)
  194786. @@ -1956,46 +2006,65 @@
  194787. }
  194788. -/* Bring the controller up and running */
  194789. -int startup_gfar(struct net_device *ndev)
  194790. +static void gfar_free_irq(struct gfar_private *priv)
  194791. {
  194792. - struct gfar_private *priv = netdev_priv(ndev);
  194793. - struct gfar __iomem *regs = NULL;
  194794. - int err, i, j;
  194795. + int i;
  194796. - for (i = 0; i < priv->num_grps; i++) {
  194797. - regs= priv->gfargrp[i].regs;
  194798. - gfar_write(&regs->imask, IMASK_INIT_CLEAR);
  194799. + /* Free the IRQs */
  194800. + if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
  194801. + for (i = 0; i < priv->num_grps; i++)
  194802. + free_grp_irqs(&priv->gfargrp[i]);
  194803. + } else {
  194804. + for (i = 0; i < priv->num_grps; i++)
  194805. + free_irq(gfar_irq(&priv->gfargrp[i], TX)->irq,
  194806. + &priv->gfargrp[i]);
  194807. }
  194808. +}
  194809. - regs= priv->gfargrp[0].regs;
  194810. - err = gfar_alloc_skb_resources(ndev);
  194811. - if (err)
  194812. - return err;
  194813. -
  194814. - gfar_init_mac(ndev);
  194815. +static int gfar_request_irq(struct gfar_private *priv)
  194816. +{
  194817. + int err, i, j;
  194818. for (i = 0; i < priv->num_grps; i++) {
  194819. err = register_grp_irqs(&priv->gfargrp[i]);
  194820. if (err) {
  194821. for (j = 0; j < i; j++)
  194822. free_grp_irqs(&priv->gfargrp[j]);
  194823. - goto irq_fail;
  194824. + return err;
  194825. }
  194826. }
  194827. - /* Start the controller */
  194828. - gfar_start(ndev);
  194829. + return 0;
  194830. +}
  194831. +
  194832. +/* Bring the controller up and running */
  194833. +int startup_gfar(struct net_device *ndev)
  194834. +{
  194835. + struct gfar_private *priv = netdev_priv(ndev);
  194836. + int err;
  194837. +
  194838. + gfar_mac_reset(priv);
  194839. +
  194840. + err = gfar_alloc_skb_resources(ndev);
  194841. + if (err)
  194842. + return err;
  194843. +
  194844. + gfar_init_tx_rx_base(priv);
  194845. +
  194846. + smp_mb__before_clear_bit();
  194847. + clear_bit(GFAR_DOWN, &priv->state);
  194848. + smp_mb__after_clear_bit();
  194849. +
  194850. + /* Start Rx/Tx DMA and enable the interrupts */
  194851. + gfar_start(priv);
  194852. phy_start(priv->phydev);
  194853. - gfar_configure_coalescing_all(priv);
  194854. + enable_napi(priv);
  194855. - return 0;
  194856. + netif_tx_wake_all_queues(ndev);
  194857. -irq_fail:
  194858. - free_skb_resources(priv);
  194859. - return err;
  194860. + return 0;
  194861. }
  194862. /* Called when something needs to use the ethernet device
  194863. @@ -2006,27 +2075,17 @@
  194864. struct gfar_private *priv = netdev_priv(dev);
  194865. int err;
  194866. - enable_napi(priv);
  194867. -
  194868. - /* Initialize a bunch of registers */
  194869. - init_registers(dev);
  194870. -
  194871. - gfar_set_mac_address(dev);
  194872. -
  194873. err = init_phy(dev);
  194874. + if (err)
  194875. + return err;
  194876. - if (err) {
  194877. - disable_napi(priv);
  194878. + err = gfar_request_irq(priv);
  194879. + if (err)
  194880. return err;
  194881. - }
  194882. err = startup_gfar(dev);
  194883. - if (err) {
  194884. - disable_napi(priv);
  194885. + if (err)
  194886. return err;
  194887. - }
  194888. -
  194889. - netif_tx_start_all_queues(dev);
  194890. device_set_wakeup_enable(&dev->dev, priv->wol_en);
  194891. @@ -2152,13 +2211,13 @@
  194892. skb_new = skb_realloc_headroom(skb, fcb_len);
  194893. if (!skb_new) {
  194894. dev->stats.tx_errors++;
  194895. - kfree_skb(skb);
  194896. + dev_kfree_skb_any(skb);
  194897. return NETDEV_TX_OK;
  194898. }
  194899. if (skb->sk)
  194900. skb_set_owner_w(skb_new, skb->sk);
  194901. - consume_skb(skb);
  194902. + dev_consume_skb_any(skb);
  194903. skb = skb_new;
  194904. }
  194905. @@ -2351,8 +2410,6 @@
  194906. {
  194907. struct gfar_private *priv = netdev_priv(dev);
  194908. - disable_napi(priv);
  194909. -
  194910. cancel_work_sync(&priv->reset_task);
  194911. stop_gfar(dev);
  194912. @@ -2360,7 +2417,7 @@
  194913. phy_disconnect(priv->phydev);
  194914. priv->phydev = NULL;
  194915. - netif_tx_stop_all_queues(dev);
  194916. + gfar_free_irq(priv);
  194917. return 0;
  194918. }
  194919. @@ -2373,77 +2430,9 @@
  194920. return 0;
  194921. }
  194922. -/* Check if rx parser should be activated */
  194923. -void gfar_check_rx_parser_mode(struct gfar_private *priv)
  194924. -{
  194925. - struct gfar __iomem *regs;
  194926. - u32 tempval;
  194927. -
  194928. - regs = priv->gfargrp[0].regs;
  194929. -
  194930. - tempval = gfar_read(&regs->rctrl);
  194931. - /* If parse is no longer required, then disable parser */
  194932. - if (tempval & RCTRL_REQ_PARSER) {
  194933. - tempval |= RCTRL_PRSDEP_INIT;
  194934. - priv->uses_rxfcb = 1;
  194935. - } else {
  194936. - tempval &= ~RCTRL_PRSDEP_INIT;
  194937. - priv->uses_rxfcb = 0;
  194938. - }
  194939. - gfar_write(&regs->rctrl, tempval);
  194940. -}
  194941. -
  194942. -/* Enables and disables VLAN insertion/extraction */
  194943. -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features)
  194944. -{
  194945. - struct gfar_private *priv = netdev_priv(dev);
  194946. - struct gfar __iomem *regs = NULL;
  194947. - unsigned long flags;
  194948. - u32 tempval;
  194949. -
  194950. - regs = priv->gfargrp[0].regs;
  194951. - local_irq_save(flags);
  194952. - lock_rx_qs(priv);
  194953. -
  194954. - if (features & NETIF_F_HW_VLAN_CTAG_TX) {
  194955. - /* Enable VLAN tag insertion */
  194956. - tempval = gfar_read(&regs->tctrl);
  194957. - tempval |= TCTRL_VLINS;
  194958. - gfar_write(&regs->tctrl, tempval);
  194959. - } else {
  194960. - /* Disable VLAN tag insertion */
  194961. - tempval = gfar_read(&regs->tctrl);
  194962. - tempval &= ~TCTRL_VLINS;
  194963. - gfar_write(&regs->tctrl, tempval);
  194964. - }
  194965. -
  194966. - if (features & NETIF_F_HW_VLAN_CTAG_RX) {
  194967. - /* Enable VLAN tag extraction */
  194968. - tempval = gfar_read(&regs->rctrl);
  194969. - tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
  194970. - gfar_write(&regs->rctrl, tempval);
  194971. - priv->uses_rxfcb = 1;
  194972. - } else {
  194973. - /* Disable VLAN tag extraction */
  194974. - tempval = gfar_read(&regs->rctrl);
  194975. - tempval &= ~RCTRL_VLEX;
  194976. - gfar_write(&regs->rctrl, tempval);
  194977. -
  194978. - gfar_check_rx_parser_mode(priv);
  194979. - }
  194980. -
  194981. - gfar_change_mtu(dev, dev->mtu);
  194982. -
  194983. - unlock_rx_qs(priv);
  194984. - local_irq_restore(flags);
  194985. -}
  194986. -
  194987. static int gfar_change_mtu(struct net_device *dev, int new_mtu)
  194988. {
  194989. - int tempsize, tempval;
  194990. struct gfar_private *priv = netdev_priv(dev);
  194991. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  194992. - int oldsize = priv->rx_buffer_size;
  194993. int frame_size = new_mtu + ETH_HLEN;
  194994. if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
  194995. @@ -2451,45 +2440,33 @@
  194996. return -EINVAL;
  194997. }
  194998. - if (priv->uses_rxfcb)
  194999. - frame_size += GMAC_FCB_LEN;
  195000. -
  195001. - frame_size += priv->padding;
  195002. -
  195003. - tempsize = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
  195004. - INCREMENTAL_BUFFER_SIZE;
  195005. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  195006. + cpu_relax();
  195007. - /* Only stop and start the controller if it isn't already
  195008. - * stopped, and we changed something
  195009. - */
  195010. - if ((oldsize != tempsize) && (dev->flags & IFF_UP))
  195011. + if (dev->flags & IFF_UP)
  195012. stop_gfar(dev);
  195013. - priv->rx_buffer_size = tempsize;
  195014. -
  195015. dev->mtu = new_mtu;
  195016. - gfar_write(&regs->mrblr, priv->rx_buffer_size);
  195017. - gfar_write(&regs->maxfrm, priv->rx_buffer_size);
  195018. + if (dev->flags & IFF_UP)
  195019. + startup_gfar(dev);
  195020. - /* If the mtu is larger than the max size for standard
  195021. - * ethernet frames (ie, a jumbo frame), then set maccfg2
  195022. - * to allow huge frames, and to check the length
  195023. - */
  195024. - tempval = gfar_read(&regs->maccfg2);
  195025. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  195026. - if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
  195027. - gfar_has_errata(priv, GFAR_ERRATA_74))
  195028. - tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
  195029. - else
  195030. - tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK);
  195031. + return 0;
  195032. +}
  195033. - gfar_write(&regs->maccfg2, tempval);
  195034. +void reset_gfar(struct net_device *ndev)
  195035. +{
  195036. + struct gfar_private *priv = netdev_priv(ndev);
  195037. - if ((oldsize != tempsize) && (dev->flags & IFF_UP))
  195038. - startup_gfar(dev);
  195039. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  195040. + cpu_relax();
  195041. - return 0;
  195042. + stop_gfar(ndev);
  195043. + startup_gfar(ndev);
  195044. +
  195045. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  195046. }
  195047. /* gfar_reset_task gets scheduled when a packet has not been
  195048. @@ -2501,16 +2478,7 @@
  195049. {
  195050. struct gfar_private *priv = container_of(work, struct gfar_private,
  195051. reset_task);
  195052. - struct net_device *dev = priv->ndev;
  195053. -
  195054. - if (dev->flags & IFF_UP) {
  195055. - netif_tx_stop_all_queues(dev);
  195056. - stop_gfar(dev);
  195057. - startup_gfar(dev);
  195058. - netif_tx_start_all_queues(dev);
  195059. - }
  195060. -
  195061. - netif_tx_schedule_all(dev);
  195062. + reset_gfar(priv->ndev);
  195063. }
  195064. static void gfar_timeout(struct net_device *dev)
  195065. @@ -2623,8 +2591,10 @@
  195066. }
  195067. /* If we freed a buffer, we can restart transmission, if necessary */
  195068. - if (netif_tx_queue_stopped(txq) && tx_queue->num_txbdfree)
  195069. - netif_wake_subqueue(dev, tqi);
  195070. + if (tx_queue->num_txbdfree &&
  195071. + netif_tx_queue_stopped(txq) &&
  195072. + !(test_bit(GFAR_DOWN, &priv->state)))
  195073. + netif_wake_subqueue(priv->ndev, tqi);
  195074. /* Update dirty indicators */
  195075. tx_queue->skb_dirtytx = skb_dirtytx;
  195076. @@ -2633,31 +2603,6 @@
  195077. netdev_tx_completed_queue(txq, howmany, bytes_sent);
  195078. }
  195079. -static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp)
  195080. -{
  195081. - unsigned long flags;
  195082. -
  195083. - spin_lock_irqsave(&gfargrp->grplock, flags);
  195084. - if (napi_schedule_prep(&gfargrp->napi)) {
  195085. - gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED);
  195086. - __napi_schedule(&gfargrp->napi);
  195087. - } else {
  195088. - /* Clear IEVENT, so interrupts aren't called again
  195089. - * because of the packets that have already arrived.
  195090. - */
  195091. - gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK);
  195092. - }
  195093. - spin_unlock_irqrestore(&gfargrp->grplock, flags);
  195094. -
  195095. -}
  195096. -
  195097. -/* Interrupt Handler for Transmit complete */
  195098. -static irqreturn_t gfar_transmit(int irq, void *grp_id)
  195099. -{
  195100. - gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
  195101. - return IRQ_HANDLED;
  195102. -}
  195103. -
  195104. static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
  195105. struct sk_buff *skb)
  195106. {
  195107. @@ -2728,7 +2673,48 @@
  195108. irqreturn_t gfar_receive(int irq, void *grp_id)
  195109. {
  195110. - gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id);
  195111. + struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
  195112. + unsigned long flags;
  195113. + u32 imask;
  195114. +
  195115. + if (likely(napi_schedule_prep(&grp->napi_rx))) {
  195116. + spin_lock_irqsave(&grp->grplock, flags);
  195117. + imask = gfar_read(&grp->regs->imask);
  195118. + imask &= IMASK_RX_DISABLED;
  195119. + gfar_write(&grp->regs->imask, imask);
  195120. + spin_unlock_irqrestore(&grp->grplock, flags);
  195121. + __napi_schedule(&grp->napi_rx);
  195122. + } else {
  195123. + /* Clear IEVENT, so interrupts aren't called again
  195124. + * because of the packets that have already arrived.
  195125. + */
  195126. + gfar_write(&grp->regs->ievent, IEVENT_RX_MASK);
  195127. + }
  195128. +
  195129. + return IRQ_HANDLED;
  195130. +}
  195131. +
  195132. +/* Interrupt Handler for Transmit complete */
  195133. +static irqreturn_t gfar_transmit(int irq, void *grp_id)
  195134. +{
  195135. + struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
  195136. + unsigned long flags;
  195137. + u32 imask;
  195138. +
  195139. + if (likely(napi_schedule_prep(&grp->napi_tx))) {
  195140. + spin_lock_irqsave(&grp->grplock, flags);
  195141. + imask = gfar_read(&grp->regs->imask);
  195142. + imask &= IMASK_TX_DISABLED;
  195143. + gfar_write(&grp->regs->imask, imask);
  195144. + spin_unlock_irqrestore(&grp->grplock, flags);
  195145. + __napi_schedule(&grp->napi_tx);
  195146. + } else {
  195147. + /* Clear IEVENT, so interrupts aren't called again
  195148. + * because of the packets that have already arrived.
  195149. + */
  195150. + gfar_write(&grp->regs->ievent, IEVENT_TX_MASK);
  195151. + }
  195152. +
  195153. return IRQ_HANDLED;
  195154. }
  195155. @@ -2852,7 +2838,7 @@
  195156. rx_queue->stats.rx_bytes += pkt_len;
  195157. skb_record_rx_queue(skb, rx_queue->qindex);
  195158. gfar_process_frame(dev, skb, amount_pull,
  195159. - &rx_queue->grp->napi);
  195160. + &rx_queue->grp->napi_rx);
  195161. } else {
  195162. netif_warn(priv, rx_err, dev, "Missing skb!\n");
  195163. @@ -2881,66 +2867,81 @@
  195164. return howmany;
  195165. }
  195166. -static int gfar_poll_sq(struct napi_struct *napi, int budget)
  195167. +static int gfar_poll_rx_sq(struct napi_struct *napi, int budget)
  195168. {
  195169. struct gfar_priv_grp *gfargrp =
  195170. - container_of(napi, struct gfar_priv_grp, napi);
  195171. + container_of(napi, struct gfar_priv_grp, napi_rx);
  195172. struct gfar __iomem *regs = gfargrp->regs;
  195173. - struct gfar_priv_tx_q *tx_queue = gfargrp->priv->tx_queue[0];
  195174. - struct gfar_priv_rx_q *rx_queue = gfargrp->priv->rx_queue[0];
  195175. + struct gfar_priv_rx_q *rx_queue = gfargrp->rx_queue;
  195176. int work_done = 0;
  195177. /* Clear IEVENT, so interrupts aren't called again
  195178. * because of the packets that have already arrived
  195179. */
  195180. - gfar_write(&regs->ievent, IEVENT_RTX_MASK);
  195181. -
  195182. - /* run Tx cleanup to completion */
  195183. - if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx])
  195184. - gfar_clean_tx_ring(tx_queue);
  195185. + gfar_write(&regs->ievent, IEVENT_RX_MASK);
  195186. work_done = gfar_clean_rx_ring(rx_queue, budget);
  195187. if (work_done < budget) {
  195188. + u32 imask;
  195189. napi_complete(napi);
  195190. /* Clear the halt bit in RSTAT */
  195191. gfar_write(&regs->rstat, gfargrp->rstat);
  195192. - gfar_write(&regs->imask, IMASK_DEFAULT);
  195193. -
  195194. - /* If we are coalescing interrupts, update the timer
  195195. - * Otherwise, clear it
  195196. - */
  195197. - gfar_write(&regs->txic, 0);
  195198. - if (likely(tx_queue->txcoalescing))
  195199. - gfar_write(&regs->txic, tx_queue->txic);
  195200. -
  195201. - gfar_write(&regs->rxic, 0);
  195202. - if (unlikely(rx_queue->rxcoalescing))
  195203. - gfar_write(&regs->rxic, rx_queue->rxic);
  195204. + spin_lock_irq(&gfargrp->grplock);
  195205. + imask = gfar_read(&regs->imask);
  195206. + imask |= IMASK_RX_DEFAULT;
  195207. + gfar_write(&regs->imask, imask);
  195208. + spin_unlock_irq(&gfargrp->grplock);
  195209. }
  195210. return work_done;
  195211. }
  195212. -static int gfar_poll(struct napi_struct *napi, int budget)
  195213. +static int gfar_poll_tx_sq(struct napi_struct *napi, int budget)
  195214. +{
  195215. + struct gfar_priv_grp *gfargrp =
  195216. + container_of(napi, struct gfar_priv_grp, napi_tx);
  195217. + struct gfar __iomem *regs = gfargrp->regs;
  195218. + struct gfar_priv_tx_q *tx_queue = gfargrp->tx_queue;
  195219. + u32 imask;
  195220. +
  195221. + /* Clear IEVENT, so interrupts aren't called again
  195222. + * because of the packets that have already arrived
  195223. + */
  195224. + gfar_write(&regs->ievent, IEVENT_TX_MASK);
  195225. +
  195226. + /* run Tx cleanup to completion */
  195227. + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx])
  195228. + gfar_clean_tx_ring(tx_queue);
  195229. +
  195230. + napi_complete(napi);
  195231. +
  195232. + spin_lock_irq(&gfargrp->grplock);
  195233. + imask = gfar_read(&regs->imask);
  195234. + imask |= IMASK_TX_DEFAULT;
  195235. + gfar_write(&regs->imask, imask);
  195236. + spin_unlock_irq(&gfargrp->grplock);
  195237. +
  195238. + return 0;
  195239. +}
  195240. +
  195241. +static int gfar_poll_rx(struct napi_struct *napi, int budget)
  195242. {
  195243. struct gfar_priv_grp *gfargrp =
  195244. - container_of(napi, struct gfar_priv_grp, napi);
  195245. + container_of(napi, struct gfar_priv_grp, napi_rx);
  195246. struct gfar_private *priv = gfargrp->priv;
  195247. struct gfar __iomem *regs = gfargrp->regs;
  195248. - struct gfar_priv_tx_q *tx_queue = NULL;
  195249. struct gfar_priv_rx_q *rx_queue = NULL;
  195250. int work_done = 0, work_done_per_q = 0;
  195251. int i, budget_per_q = 0;
  195252. - int has_tx_work = 0;
  195253. unsigned long rstat_rxf;
  195254. int num_act_queues;
  195255. /* Clear IEVENT, so interrupts aren't called again
  195256. * because of the packets that have already arrived
  195257. */
  195258. - gfar_write(&regs->ievent, IEVENT_RTX_MASK);
  195259. + gfar_write(&regs->ievent, IEVENT_RX_MASK);
  195260. rstat_rxf = gfar_read(&regs->rstat) & RSTAT_RXF_MASK;
  195261. @@ -2948,15 +2949,6 @@
  195262. if (num_act_queues)
  195263. budget_per_q = budget/num_act_queues;
  195264. - for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
  195265. - tx_queue = priv->tx_queue[i];
  195266. - /* run Tx cleanup to completion */
  195267. - if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
  195268. - gfar_clean_tx_ring(tx_queue);
  195269. - has_tx_work = 1;
  195270. - }
  195271. - }
  195272. -
  195273. for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
  195274. /* skip queue if not active */
  195275. if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i)))
  195276. @@ -2979,25 +2971,62 @@
  195277. }
  195278. }
  195279. - if (!num_act_queues && !has_tx_work) {
  195280. -
  195281. + if (!num_act_queues) {
  195282. + u32 imask;
  195283. napi_complete(napi);
  195284. /* Clear the halt bit in RSTAT */
  195285. gfar_write(&regs->rstat, gfargrp->rstat);
  195286. - gfar_write(&regs->imask, IMASK_DEFAULT);
  195287. -
  195288. - /* If we are coalescing interrupts, update the timer
  195289. - * Otherwise, clear it
  195290. - */
  195291. - gfar_configure_coalescing(priv, gfargrp->rx_bit_map,
  195292. - gfargrp->tx_bit_map);
  195293. + spin_lock_irq(&gfargrp->grplock);
  195294. + imask = gfar_read(&regs->imask);
  195295. + imask |= IMASK_RX_DEFAULT;
  195296. + gfar_write(&regs->imask, imask);
  195297. + spin_unlock_irq(&gfargrp->grplock);
  195298. }
  195299. return work_done;
  195300. }
  195301. +static int gfar_poll_tx(struct napi_struct *napi, int budget)
  195302. +{
  195303. + struct gfar_priv_grp *gfargrp =
  195304. + container_of(napi, struct gfar_priv_grp, napi_tx);
  195305. + struct gfar_private *priv = gfargrp->priv;
  195306. + struct gfar __iomem *regs = gfargrp->regs;
  195307. + struct gfar_priv_tx_q *tx_queue = NULL;
  195308. + int has_tx_work = 0;
  195309. + int i;
  195310. +
  195311. + /* Clear IEVENT, so interrupts aren't called again
  195312. + * because of the packets that have already arrived
  195313. + */
  195314. + gfar_write(&regs->ievent, IEVENT_TX_MASK);
  195315. +
  195316. + for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
  195317. + tx_queue = priv->tx_queue[i];
  195318. + /* run Tx cleanup to completion */
  195319. + if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
  195320. + gfar_clean_tx_ring(tx_queue);
  195321. + has_tx_work = 1;
  195322. + }
  195323. + }
  195324. +
  195325. + if (!has_tx_work) {
  195326. + u32 imask;
  195327. + napi_complete(napi);
  195328. +
  195329. + spin_lock_irq(&gfargrp->grplock);
  195330. + imask = gfar_read(&regs->imask);
  195331. + imask |= IMASK_TX_DEFAULT;
  195332. + gfar_write(&regs->imask, imask);
  195333. + spin_unlock_irq(&gfargrp->grplock);
  195334. + }
  195335. +
  195336. + return 0;
  195337. +}
  195338. +
  195339. +
  195340. #ifdef CONFIG_NET_POLL_CONTROLLER
  195341. /* Polling 'interrupt' - used by things like netconsole to send skbs
  195342. * without having to re-enable interrupts. It's not called while
  195343. @@ -3056,41 +3085,6 @@
  195344. return IRQ_HANDLED;
  195345. }
  195346. -static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
  195347. -{
  195348. - struct phy_device *phydev = priv->phydev;
  195349. - u32 val = 0;
  195350. -
  195351. - if (!phydev->duplex)
  195352. - return val;
  195353. -
  195354. - if (!priv->pause_aneg_en) {
  195355. - if (priv->tx_pause_en)
  195356. - val |= MACCFG1_TX_FLOW;
  195357. - if (priv->rx_pause_en)
  195358. - val |= MACCFG1_RX_FLOW;
  195359. - } else {
  195360. - u16 lcl_adv, rmt_adv;
  195361. - u8 flowctrl;
  195362. - /* get link partner capabilities */
  195363. - rmt_adv = 0;
  195364. - if (phydev->pause)
  195365. - rmt_adv = LPA_PAUSE_CAP;
  195366. - if (phydev->asym_pause)
  195367. - rmt_adv |= LPA_PAUSE_ASYM;
  195368. -
  195369. - lcl_adv = mii_advertise_flowctrl(phydev->advertising);
  195370. -
  195371. - flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
  195372. - if (flowctrl & FLOW_CTRL_TX)
  195373. - val |= MACCFG1_TX_FLOW;
  195374. - if (flowctrl & FLOW_CTRL_RX)
  195375. - val |= MACCFG1_RX_FLOW;
  195376. - }
  195377. -
  195378. - return val;
  195379. -}
  195380. -
  195381. /* Called every time the controller might need to be made
  195382. * aware of new link state. The PHY code conveys this
  195383. * information through variables in the phydev structure, and this
  195384. @@ -3100,86 +3094,12 @@
  195385. static void adjust_link(struct net_device *dev)
  195386. {
  195387. struct gfar_private *priv = netdev_priv(dev);
  195388. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  195389. - unsigned long flags;
  195390. struct phy_device *phydev = priv->phydev;
  195391. - int new_state = 0;
  195392. -
  195393. - local_irq_save(flags);
  195394. - lock_tx_qs(priv);
  195395. -
  195396. - if (phydev->link) {
  195397. - u32 tempval1 = gfar_read(&regs->maccfg1);
  195398. - u32 tempval = gfar_read(&regs->maccfg2);
  195399. - u32 ecntrl = gfar_read(&regs->ecntrl);
  195400. -
  195401. - /* Now we make sure that we can be in full duplex mode.
  195402. - * If not, we operate in half-duplex mode.
  195403. - */
  195404. - if (phydev->duplex != priv->oldduplex) {
  195405. - new_state = 1;
  195406. - if (!(phydev->duplex))
  195407. - tempval &= ~(MACCFG2_FULL_DUPLEX);
  195408. - else
  195409. - tempval |= MACCFG2_FULL_DUPLEX;
  195410. -
  195411. - priv->oldduplex = phydev->duplex;
  195412. - }
  195413. -
  195414. - if (phydev->speed != priv->oldspeed) {
  195415. - new_state = 1;
  195416. - switch (phydev->speed) {
  195417. - case 1000:
  195418. - tempval =
  195419. - ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
  195420. -
  195421. - ecntrl &= ~(ECNTRL_R100);
  195422. - break;
  195423. - case 100:
  195424. - case 10:
  195425. - tempval =
  195426. - ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
  195427. -
  195428. - /* Reduced mode distinguishes
  195429. - * between 10 and 100
  195430. - */
  195431. - if (phydev->speed == SPEED_100)
  195432. - ecntrl |= ECNTRL_R100;
  195433. - else
  195434. - ecntrl &= ~(ECNTRL_R100);
  195435. - break;
  195436. - default:
  195437. - netif_warn(priv, link, dev,
  195438. - "Ack! Speed (%d) is not 10/100/1000!\n",
  195439. - phydev->speed);
  195440. - break;
  195441. - }
  195442. -
  195443. - priv->oldspeed = phydev->speed;
  195444. - }
  195445. -
  195446. - tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
  195447. - tempval1 |= gfar_get_flowctrl_cfg(priv);
  195448. -
  195449. - gfar_write(&regs->maccfg1, tempval1);
  195450. - gfar_write(&regs->maccfg2, tempval);
  195451. - gfar_write(&regs->ecntrl, ecntrl);
  195452. -
  195453. - if (!priv->oldlink) {
  195454. - new_state = 1;
  195455. - priv->oldlink = 1;
  195456. - }
  195457. - } else if (priv->oldlink) {
  195458. - new_state = 1;
  195459. - priv->oldlink = 0;
  195460. - priv->oldspeed = 0;
  195461. - priv->oldduplex = -1;
  195462. - }
  195463. - if (new_state && netif_msg_link(priv))
  195464. - phy_print_status(phydev);
  195465. - unlock_tx_qs(priv);
  195466. - local_irq_restore(flags);
  195467. + if (unlikely(phydev->link != priv->oldlink ||
  195468. + phydev->duplex != priv->oldduplex ||
  195469. + phydev->speed != priv->oldspeed))
  195470. + gfar_update_link_state(priv);
  195471. }
  195472. /* Update the hash table based on the current list of multicast
  195473. @@ -3425,6 +3345,114 @@
  195474. return IRQ_HANDLED;
  195475. }
  195476. +static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
  195477. +{
  195478. + struct phy_device *phydev = priv->phydev;
  195479. + u32 val = 0;
  195480. +
  195481. + if (!phydev->duplex)
  195482. + return val;
  195483. +
  195484. + if (!priv->pause_aneg_en) {
  195485. + if (priv->tx_pause_en)
  195486. + val |= MACCFG1_TX_FLOW;
  195487. + if (priv->rx_pause_en)
  195488. + val |= MACCFG1_RX_FLOW;
  195489. + } else {
  195490. + u16 lcl_adv, rmt_adv;
  195491. + u8 flowctrl;
  195492. + /* get link partner capabilities */
  195493. + rmt_adv = 0;
  195494. + if (phydev->pause)
  195495. + rmt_adv = LPA_PAUSE_CAP;
  195496. + if (phydev->asym_pause)
  195497. + rmt_adv |= LPA_PAUSE_ASYM;
  195498. +
  195499. + lcl_adv = mii_advertise_flowctrl(phydev->advertising);
  195500. +
  195501. + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
  195502. + if (flowctrl & FLOW_CTRL_TX)
  195503. + val |= MACCFG1_TX_FLOW;
  195504. + if (flowctrl & FLOW_CTRL_RX)
  195505. + val |= MACCFG1_RX_FLOW;
  195506. + }
  195507. +
  195508. + return val;
  195509. +}
  195510. +
  195511. +static noinline void gfar_update_link_state(struct gfar_private *priv)
  195512. +{
  195513. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  195514. + struct phy_device *phydev = priv->phydev;
  195515. +
  195516. + if (unlikely(test_bit(GFAR_RESETTING, &priv->state)))
  195517. + return;
  195518. +
  195519. + if (phydev->link) {
  195520. + u32 tempval1 = gfar_read(&regs->maccfg1);
  195521. + u32 tempval = gfar_read(&regs->maccfg2);
  195522. + u32 ecntrl = gfar_read(&regs->ecntrl);
  195523. +
  195524. + if (phydev->duplex != priv->oldduplex) {
  195525. + if (!(phydev->duplex))
  195526. + tempval &= ~(MACCFG2_FULL_DUPLEX);
  195527. + else
  195528. + tempval |= MACCFG2_FULL_DUPLEX;
  195529. +
  195530. + priv->oldduplex = phydev->duplex;
  195531. + }
  195532. +
  195533. + if (phydev->speed != priv->oldspeed) {
  195534. + switch (phydev->speed) {
  195535. + case 1000:
  195536. + tempval =
  195537. + ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
  195538. +
  195539. + ecntrl &= ~(ECNTRL_R100);
  195540. + break;
  195541. + case 100:
  195542. + case 10:
  195543. + tempval =
  195544. + ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
  195545. +
  195546. + /* Reduced mode distinguishes
  195547. + * between 10 and 100
  195548. + */
  195549. + if (phydev->speed == SPEED_100)
  195550. + ecntrl |= ECNTRL_R100;
  195551. + else
  195552. + ecntrl &= ~(ECNTRL_R100);
  195553. + break;
  195554. + default:
  195555. + netif_warn(priv, link, priv->ndev,
  195556. + "Ack! Speed (%d) is not 10/100/1000!\n",
  195557. + phydev->speed);
  195558. + break;
  195559. + }
  195560. +
  195561. + priv->oldspeed = phydev->speed;
  195562. + }
  195563. +
  195564. + tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
  195565. + tempval1 |= gfar_get_flowctrl_cfg(priv);
  195566. +
  195567. + gfar_write(&regs->maccfg1, tempval1);
  195568. + gfar_write(&regs->maccfg2, tempval);
  195569. + gfar_write(&regs->ecntrl, ecntrl);
  195570. +
  195571. + if (!priv->oldlink)
  195572. + priv->oldlink = 1;
  195573. +
  195574. + } else if (priv->oldlink) {
  195575. + priv->oldlink = 0;
  195576. + priv->oldspeed = 0;
  195577. + priv->oldduplex = -1;
  195578. + }
  195579. +
  195580. + if (netif_msg_link(priv))
  195581. + phy_print_status(phydev);
  195582. +}
  195583. +
  195584. static struct of_device_id gfar_match[] =
  195585. {
  195586. {
  195587. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/gianfar_ethtool.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ethtool.c
  195588. --- linux-3.14.17/drivers/net/ethernet/freescale/gianfar_ethtool.c 2014-08-14 03:38:34.000000000 +0200
  195589. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ethtool.c 2014-09-11 18:06:03.502043969 +0200
  195590. @@ -44,10 +44,6 @@
  195591. #include "gianfar.h"
  195592. -extern void gfar_start(struct net_device *dev);
  195593. -extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue,
  195594. - int rx_work_limit);
  195595. -
  195596. #define GFAR_MAX_COAL_USECS 0xffff
  195597. #define GFAR_MAX_COAL_FRAMES 0xff
  195598. static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
  195599. @@ -364,25 +360,11 @@
  195600. struct ethtool_coalesce *cvals)
  195601. {
  195602. struct gfar_private *priv = netdev_priv(dev);
  195603. - int i = 0;
  195604. + int i, err = 0;
  195605. if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
  195606. return -EOPNOTSUPP;
  195607. - /* Set up rx coalescing */
  195608. - /* As of now, we will enable/disable coalescing for all
  195609. - * queues together in case of eTSEC2, this will be modified
  195610. - * along with the ethtool interface
  195611. - */
  195612. - if ((cvals->rx_coalesce_usecs == 0) ||
  195613. - (cvals->rx_max_coalesced_frames == 0)) {
  195614. - for (i = 0; i < priv->num_rx_queues; i++)
  195615. - priv->rx_queue[i]->rxcoalescing = 0;
  195616. - } else {
  195617. - for (i = 0; i < priv->num_rx_queues; i++)
  195618. - priv->rx_queue[i]->rxcoalescing = 1;
  195619. - }
  195620. -
  195621. if (NULL == priv->phydev)
  195622. return -ENODEV;
  195623. @@ -399,6 +381,32 @@
  195624. return -EINVAL;
  195625. }
  195626. + /* Check the bounds of the values */
  195627. + if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
  195628. + netdev_info(dev, "Coalescing is limited to %d microseconds\n",
  195629. + GFAR_MAX_COAL_USECS);
  195630. + return -EINVAL;
  195631. + }
  195632. +
  195633. + if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
  195634. + netdev_info(dev, "Coalescing is limited to %d frames\n",
  195635. + GFAR_MAX_COAL_FRAMES);
  195636. + return -EINVAL;
  195637. + }
  195638. +
  195639. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  195640. + cpu_relax();
  195641. +
  195642. + /* Set up rx coalescing */
  195643. + if ((cvals->rx_coalesce_usecs == 0) ||
  195644. + (cvals->rx_max_coalesced_frames == 0)) {
  195645. + for (i = 0; i < priv->num_rx_queues; i++)
  195646. + priv->rx_queue[i]->rxcoalescing = 0;
  195647. + } else {
  195648. + for (i = 0; i < priv->num_rx_queues; i++)
  195649. + priv->rx_queue[i]->rxcoalescing = 1;
  195650. + }
  195651. +
  195652. for (i = 0; i < priv->num_rx_queues; i++) {
  195653. priv->rx_queue[i]->rxic = mk_ic_value(
  195654. cvals->rx_max_coalesced_frames,
  195655. @@ -415,28 +423,22 @@
  195656. priv->tx_queue[i]->txcoalescing = 1;
  195657. }
  195658. - /* Check the bounds of the values */
  195659. - if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
  195660. - netdev_info(dev, "Coalescing is limited to %d microseconds\n",
  195661. - GFAR_MAX_COAL_USECS);
  195662. - return -EINVAL;
  195663. - }
  195664. -
  195665. - if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
  195666. - netdev_info(dev, "Coalescing is limited to %d frames\n",
  195667. - GFAR_MAX_COAL_FRAMES);
  195668. - return -EINVAL;
  195669. - }
  195670. -
  195671. for (i = 0; i < priv->num_tx_queues; i++) {
  195672. priv->tx_queue[i]->txic = mk_ic_value(
  195673. cvals->tx_max_coalesced_frames,
  195674. gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
  195675. }
  195676. - gfar_configure_coalescing_all(priv);
  195677. + if (dev->flags & IFF_UP) {
  195678. + stop_gfar(dev);
  195679. + err = startup_gfar(dev);
  195680. + } else {
  195681. + gfar_mac_reset(priv);
  195682. + }
  195683. +
  195684. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  195685. - return 0;
  195686. + return err;
  195687. }
  195688. /* Fills in rvals with the current ring parameters. Currently,
  195689. @@ -467,15 +469,13 @@
  195690. }
  195691. /* Change the current ring parameters, stopping the controller if
  195692. - * necessary so that we don't mess things up while we're in
  195693. - * motion. We wait for the ring to be clean before reallocating
  195694. - * the rings.
  195695. + * necessary so that we don't mess things up while we're in motion.
  195696. */
  195697. static int gfar_sringparam(struct net_device *dev,
  195698. struct ethtool_ringparam *rvals)
  195699. {
  195700. struct gfar_private *priv = netdev_priv(dev);
  195701. - int err = 0, i = 0;
  195702. + int err = 0, i;
  195703. if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE)
  195704. return -EINVAL;
  195705. @@ -493,44 +493,25 @@
  195706. return -EINVAL;
  195707. }
  195708. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  195709. + cpu_relax();
  195710. - if (dev->flags & IFF_UP) {
  195711. - unsigned long flags;
  195712. -
  195713. - /* Halt TX and RX, and process the frames which
  195714. - * have already been received
  195715. - */
  195716. - local_irq_save(flags);
  195717. - lock_tx_qs(priv);
  195718. - lock_rx_qs(priv);
  195719. -
  195720. - gfar_halt(dev);
  195721. -
  195722. - unlock_rx_qs(priv);
  195723. - unlock_tx_qs(priv);
  195724. - local_irq_restore(flags);
  195725. -
  195726. - for (i = 0; i < priv->num_rx_queues; i++)
  195727. - gfar_clean_rx_ring(priv->rx_queue[i],
  195728. - priv->rx_queue[i]->rx_ring_size);
  195729. -
  195730. - /* Now we take down the rings to rebuild them */
  195731. + if (dev->flags & IFF_UP)
  195732. stop_gfar(dev);
  195733. - }
  195734. - /* Change the size */
  195735. - for (i = 0; i < priv->num_rx_queues; i++) {
  195736. + /* Change the sizes */
  195737. + for (i = 0; i < priv->num_rx_queues; i++)
  195738. priv->rx_queue[i]->rx_ring_size = rvals->rx_pending;
  195739. +
  195740. + for (i = 0; i < priv->num_tx_queues; i++)
  195741. priv->tx_queue[i]->tx_ring_size = rvals->tx_pending;
  195742. - priv->tx_queue[i]->num_txbdfree =
  195743. - priv->tx_queue[i]->tx_ring_size;
  195744. - }
  195745. /* Rebuild the rings with the new size */
  195746. - if (dev->flags & IFF_UP) {
  195747. + if (dev->flags & IFF_UP)
  195748. err = startup_gfar(dev);
  195749. - netif_tx_wake_all_queues(dev);
  195750. - }
  195751. +
  195752. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  195753. +
  195754. return err;
  195755. }
  195756. @@ -552,6 +533,9 @@
  195757. struct gfar __iomem *regs = priv->gfargrp[0].regs;
  195758. u32 oldadv, newadv;
  195759. + if (!phydev)
  195760. + return -ENODEV;
  195761. +
  195762. if (!(phydev->supported & SUPPORTED_Pause) ||
  195763. (!(phydev->supported & SUPPORTED_Asym_Pause) &&
  195764. (epause->rx_pause != epause->tx_pause)))
  195765. @@ -608,43 +592,29 @@
  195766. int gfar_set_features(struct net_device *dev, netdev_features_t features)
  195767. {
  195768. - struct gfar_private *priv = netdev_priv(dev);
  195769. - unsigned long flags;
  195770. - int err = 0, i = 0;
  195771. netdev_features_t changed = dev->features ^ features;
  195772. + struct gfar_private *priv = netdev_priv(dev);
  195773. + int err = 0;
  195774. - if (changed & (NETIF_F_HW_VLAN_CTAG_TX|NETIF_F_HW_VLAN_CTAG_RX))
  195775. - gfar_vlan_mode(dev, features);
  195776. -
  195777. - if (!(changed & NETIF_F_RXCSUM))
  195778. + if (!(changed & (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
  195779. + NETIF_F_RXCSUM)))
  195780. return 0;
  195781. - if (dev->flags & IFF_UP) {
  195782. - /* Halt TX and RX, and process the frames which
  195783. - * have already been received
  195784. - */
  195785. - local_irq_save(flags);
  195786. - lock_tx_qs(priv);
  195787. - lock_rx_qs(priv);
  195788. -
  195789. - gfar_halt(dev);
  195790. -
  195791. - unlock_tx_qs(priv);
  195792. - unlock_rx_qs(priv);
  195793. - local_irq_restore(flags);
  195794. + while (test_and_set_bit_lock(GFAR_RESETTING, &priv->state))
  195795. + cpu_relax();
  195796. - for (i = 0; i < priv->num_rx_queues; i++)
  195797. - gfar_clean_rx_ring(priv->rx_queue[i],
  195798. - priv->rx_queue[i]->rx_ring_size);
  195799. + dev->features = features;
  195800. + if (dev->flags & IFF_UP) {
  195801. /* Now we take down the rings to rebuild them */
  195802. stop_gfar(dev);
  195803. -
  195804. - dev->features = features;
  195805. -
  195806. err = startup_gfar(dev);
  195807. - netif_tx_wake_all_queues(dev);
  195808. + } else {
  195809. + gfar_mac_reset(priv);
  195810. }
  195811. +
  195812. + clear_bit_unlock(GFAR_RESETTING, &priv->state);
  195813. +
  195814. return err;
  195815. }
  195816. @@ -1610,9 +1580,6 @@
  195817. if (tab->index > MAX_FILER_IDX - 1)
  195818. return -EBUSY;
  195819. - /* Avoid inconsistent filer table to be processed */
  195820. - lock_rx_qs(priv);
  195821. -
  195822. /* Fill regular entries */
  195823. for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl);
  195824. i++)
  195825. @@ -1625,8 +1592,6 @@
  195826. */
  195827. gfar_write_filer(priv, i, 0x20, 0x0);
  195828. - unlock_rx_qs(priv);
  195829. -
  195830. return 0;
  195831. }
  195832. @@ -1831,6 +1796,9 @@
  195833. struct gfar_private *priv = netdev_priv(dev);
  195834. int ret = 0;
  195835. + if (test_bit(GFAR_RESETTING, &priv->state))
  195836. + return -EBUSY;
  195837. +
  195838. mutex_lock(&priv->rx_queue_access);
  195839. switch (cmd->cmd) {
  195840. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/gianfar.h linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.h
  195841. --- linux-3.14.17/drivers/net/ethernet/freescale/gianfar.h 2014-08-14 03:38:34.000000000 +0200
  195842. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar.h 2014-09-11 18:06:03.502043969 +0200
  195843. @@ -9,7 +9,7 @@
  195844. * Maintainer: Kumar Gala
  195845. * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  195846. *
  195847. - * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
  195848. + * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
  195849. *
  195850. * This program is free software; you can redistribute it and/or modify it
  195851. * under the terms of the GNU General Public License as published by the
  195852. @@ -377,8 +377,11 @@
  195853. IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \
  195854. IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
  195855. | IMASK_PERR)
  195856. -#define IMASK_RTX_DISABLED ((~(IMASK_RXFEN0 | IMASK_TXFEN | IMASK_BSY)) \
  195857. - & IMASK_DEFAULT)
  195858. +#define IMASK_RX_DEFAULT (IMASK_RXFEN0 | IMASK_BSY)
  195859. +#define IMASK_TX_DEFAULT (IMASK_TXFEN | IMASK_TXBEN)
  195860. +
  195861. +#define IMASK_RX_DISABLED ((~(IMASK_RX_DEFAULT)) & IMASK_DEFAULT)
  195862. +#define IMASK_TX_DISABLED ((~(IMASK_TX_DEFAULT)) & IMASK_DEFAULT)
  195863. /* Fifo management */
  195864. #define FIFO_TX_THR_MASK 0x01ff
  195865. @@ -409,7 +412,9 @@
  195866. /* This default RIR value directly corresponds
  195867. * to the 3-bit hash value generated */
  195868. -#define DEFAULT_RIR0 0x05397700
  195869. +#define DEFAULT_8RXQ_RIR0 0x05397700
  195870. +/* Map even hash values to Q0, and odd ones to Q1 */
  195871. +#define DEFAULT_2RXQ_RIR0 0x04104100
  195872. /* RQFCR register bits */
  195873. #define RQFCR_GPI 0x80000000
  195874. @@ -880,7 +885,6 @@
  195875. #define FSL_GIANFAR_DEV_HAS_CSUM 0x00000010
  195876. #define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020
  195877. #define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040
  195878. -#define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080
  195879. #define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET 0x00000100
  195880. #define FSL_GIANFAR_DEV_HAS_BD_STASHING 0x00000200
  195881. #define FSL_GIANFAR_DEV_HAS_BUF_STASHING 0x00000400
  195882. @@ -892,8 +896,8 @@
  195883. #define DEFAULT_MAPPING 0xFF
  195884. #endif
  195885. -#define ISRG_SHIFT_TX 0x10
  195886. -#define ISRG_SHIFT_RX 0x18
  195887. +#define ISRG_RR0 0x80000000
  195888. +#define ISRG_TR0 0x00800000
  195889. /* The same driver can operate in two modes */
  195890. /* SQ_SG_MODE: Single Queue Single Group Mode
  195891. @@ -905,6 +909,22 @@
  195892. MQ_MG_MODE
  195893. };
  195894. +/* GFAR_SQ_POLLING: Single Queue NAPI polling mode
  195895. + * The driver supports a single pair of RX/Tx queues
  195896. + * per interrupt group (Rx/Tx int line). MQ_MG mode
  195897. + * devices have 2 interrupt groups, so the device will
  195898. + * have a total of 2 Tx and 2 Rx queues in this case.
  195899. + * GFAR_MQ_POLLING: Multi Queue NAPI polling mode
  195900. + * The driver supports all the 8 Rx and Tx HW queues
  195901. + * each queue mapped by the Device Tree to one of
  195902. + * the 2 interrupt groups. This mode implies significant
  195903. + * processing overhead (CPU and controller level).
  195904. + */
  195905. +enum gfar_poll_mode {
  195906. + GFAR_SQ_POLLING = 0,
  195907. + GFAR_MQ_POLLING
  195908. +};
  195909. +
  195910. /*
  195911. * Per TX queue stats
  195912. */
  195913. @@ -966,7 +986,6 @@
  195914. /**
  195915. * struct gfar_priv_rx_q - per rx queue structure
  195916. - * @rxlock: per queue rx spin lock
  195917. * @rx_skbuff: skb pointers
  195918. * @skb_currx: currently use skb pointer
  195919. * @rx_bd_base: First rx buffer descriptor
  195920. @@ -979,8 +998,7 @@
  195921. */
  195922. struct gfar_priv_rx_q {
  195923. - spinlock_t rxlock __attribute__ ((aligned (SMP_CACHE_BYTES)));
  195924. - struct sk_buff ** rx_skbuff;
  195925. + struct sk_buff **rx_skbuff __aligned(SMP_CACHE_BYTES);
  195926. dma_addr_t rx_bd_dma_base;
  195927. struct rxbd8 *rx_bd_base;
  195928. struct rxbd8 *cur_rx;
  195929. @@ -1016,17 +1034,20 @@
  195930. */
  195931. struct gfar_priv_grp {
  195932. - spinlock_t grplock __attribute__ ((aligned (SMP_CACHE_BYTES)));
  195933. - struct napi_struct napi;
  195934. - struct gfar_private *priv;
  195935. + spinlock_t grplock __aligned(SMP_CACHE_BYTES);
  195936. + struct napi_struct napi_rx;
  195937. + struct napi_struct napi_tx;
  195938. struct gfar __iomem *regs;
  195939. - unsigned int rstat;
  195940. - unsigned long num_rx_queues;
  195941. - unsigned long rx_bit_map;
  195942. - /* cacheline 3 */
  195943. + struct gfar_priv_tx_q *tx_queue;
  195944. + struct gfar_priv_rx_q *rx_queue;
  195945. unsigned int tstat;
  195946. + unsigned int rstat;
  195947. +
  195948. + struct gfar_private *priv;
  195949. unsigned long num_tx_queues;
  195950. unsigned long tx_bit_map;
  195951. + unsigned long num_rx_queues;
  195952. + unsigned long rx_bit_map;
  195953. struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS];
  195954. };
  195955. @@ -1041,6 +1062,11 @@
  195956. GFAR_ERRATA_12 = 0x08, /* a.k.a errata eTSEC49 */
  195957. };
  195958. +enum gfar_dev_state {
  195959. + GFAR_DOWN = 1,
  195960. + GFAR_RESETTING
  195961. +};
  195962. +
  195963. /* Struct stolen almost completely (and shamelessly) from the FCC enet source
  195964. * (Ok, that's not so true anymore, but there is a family resemblance)
  195965. * The GFAR buffer descriptors track the ring buffers. The rx_bd_base
  195966. @@ -1051,8 +1077,6 @@
  195967. * the buffer descriptor determines the actual condition.
  195968. */
  195969. struct gfar_private {
  195970. - unsigned int num_rx_queues;
  195971. -
  195972. struct device *dev;
  195973. struct net_device *ndev;
  195974. enum gfar_errata errata;
  195975. @@ -1060,6 +1084,7 @@
  195976. u16 uses_rxfcb;
  195977. u16 padding;
  195978. + u32 device_flags;
  195979. /* HW time stamping enabled flag */
  195980. int hwts_rx_en;
  195981. @@ -1069,10 +1094,12 @@
  195982. struct gfar_priv_rx_q *rx_queue[MAX_RX_QS];
  195983. struct gfar_priv_grp gfargrp[MAXGROUPS];
  195984. - u32 device_flags;
  195985. + unsigned long state;
  195986. - unsigned int mode;
  195987. + unsigned short mode;
  195988. + unsigned short poll_mode;
  195989. unsigned int num_tx_queues;
  195990. + unsigned int num_rx_queues;
  195991. unsigned int num_grps;
  195992. /* Network Statistics */
  195993. @@ -1113,6 +1140,9 @@
  195994. unsigned int total_tx_ring_size;
  195995. unsigned int total_rx_ring_size;
  195996. + u32 rqueue;
  195997. + u32 tqueue;
  195998. +
  195999. /* RX per device parameters */
  196000. unsigned int rx_stash_size;
  196001. unsigned int rx_stash_index;
  196002. @@ -1127,11 +1157,6 @@
  196003. u32 __iomem *hash_regs[16];
  196004. int hash_width;
  196005. - /* global parameters */
  196006. - unsigned int fifo_threshold;
  196007. - unsigned int fifo_starve;
  196008. - unsigned int fifo_starve_off;
  196009. -
  196010. /*Filer table*/
  196011. unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
  196012. unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
  196013. @@ -1176,21 +1201,42 @@
  196014. *fpr = gfar_read(&regs->rqfpr);
  196015. }
  196016. -void lock_rx_qs(struct gfar_private *priv);
  196017. -void lock_tx_qs(struct gfar_private *priv);
  196018. -void unlock_rx_qs(struct gfar_private *priv);
  196019. -void unlock_tx_qs(struct gfar_private *priv);
  196020. +static inline void gfar_write_isrg(struct gfar_private *priv)
  196021. +{
  196022. + struct gfar __iomem *regs = priv->gfargrp[0].regs;
  196023. + u32 __iomem *baddr = &regs->isrg0;
  196024. + u32 isrg = 0;
  196025. + int grp_idx, i;
  196026. +
  196027. + for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
  196028. + struct gfar_priv_grp *grp = &priv->gfargrp[grp_idx];
  196029. +
  196030. + for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
  196031. + isrg |= (ISRG_RR0 >> i);
  196032. + }
  196033. +
  196034. + for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
  196035. + isrg |= (ISRG_TR0 >> i);
  196036. + }
  196037. +
  196038. + gfar_write(baddr, isrg);
  196039. +
  196040. + baddr++;
  196041. + isrg = 0;
  196042. + }
  196043. +}
  196044. +
  196045. irqreturn_t gfar_receive(int irq, void *dev_id);
  196046. int startup_gfar(struct net_device *dev);
  196047. void stop_gfar(struct net_device *dev);
  196048. -void gfar_halt(struct net_device *dev);
  196049. +void reset_gfar(struct net_device *dev);
  196050. +void gfar_mac_reset(struct gfar_private *priv);
  196051. +void gfar_halt(struct gfar_private *priv);
  196052. +void gfar_start(struct gfar_private *priv);
  196053. void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable,
  196054. u32 regnum, u32 read);
  196055. void gfar_configure_coalescing_all(struct gfar_private *priv);
  196056. -void gfar_init_sysfs(struct net_device *dev);
  196057. int gfar_set_features(struct net_device *dev, netdev_features_t features);
  196058. -void gfar_check_rx_parser_mode(struct gfar_private *priv);
  196059. -void gfar_vlan_mode(struct net_device *dev, netdev_features_t features);
  196060. extern const struct ethtool_ops gfar_ethtool_ops;
  196061. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/gianfar_ptp.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ptp.c
  196062. --- linux-3.14.17/drivers/net/ethernet/freescale/gianfar_ptp.c 2014-08-14 03:38:34.000000000 +0200
  196063. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_ptp.c 2014-09-11 18:06:03.502043969 +0200
  196064. @@ -414,6 +414,7 @@
  196065. .n_alarm = 0,
  196066. .n_ext_ts = N_EXT_TS,
  196067. .n_per_out = 0,
  196068. + .n_pins = 0,
  196069. .pps = 1,
  196070. .adjfreq = ptp_gianfar_adjfreq,
  196071. .adjtime = ptp_gianfar_adjtime,
  196072. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/gianfar_sysfs.c linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_sysfs.c
  196073. --- linux-3.14.17/drivers/net/ethernet/freescale/gianfar_sysfs.c 2014-08-14 03:38:34.000000000 +0200
  196074. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/gianfar_sysfs.c 1970-01-01 01:00:00.000000000 +0100
  196075. @@ -1,340 +0,0 @@
  196076. -/*
  196077. - * drivers/net/ethernet/freescale/gianfar_sysfs.c
  196078. - *
  196079. - * Gianfar Ethernet Driver
  196080. - * This driver is designed for the non-CPM ethernet controllers
  196081. - * on the 85xx and 83xx family of integrated processors
  196082. - * Based on 8260_io/fcc_enet.c
  196083. - *
  196084. - * Author: Andy Fleming
  196085. - * Maintainer: Kumar Gala (galak@kernel.crashing.org)
  196086. - * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  196087. - *
  196088. - * Copyright 2002-2009 Freescale Semiconductor, Inc.
  196089. - *
  196090. - * This program is free software; you can redistribute it and/or modify it
  196091. - * under the terms of the GNU General Public License as published by the
  196092. - * Free Software Foundation; either version 2 of the License, or (at your
  196093. - * option) any later version.
  196094. - *
  196095. - * Sysfs file creation and management
  196096. - */
  196097. -
  196098. -#include <linux/kernel.h>
  196099. -#include <linux/string.h>
  196100. -#include <linux/errno.h>
  196101. -#include <linux/unistd.h>
  196102. -#include <linux/delay.h>
  196103. -#include <linux/etherdevice.h>
  196104. -#include <linux/spinlock.h>
  196105. -#include <linux/mm.h>
  196106. -#include <linux/device.h>
  196107. -
  196108. -#include <asm/uaccess.h>
  196109. -#include <linux/module.h>
  196110. -
  196111. -#include "gianfar.h"
  196112. -
  196113. -static ssize_t gfar_show_bd_stash(struct device *dev,
  196114. - struct device_attribute *attr, char *buf)
  196115. -{
  196116. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196117. -
  196118. - return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off");
  196119. -}
  196120. -
  196121. -static ssize_t gfar_set_bd_stash(struct device *dev,
  196122. - struct device_attribute *attr,
  196123. - const char *buf, size_t count)
  196124. -{
  196125. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196126. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  196127. - int new_setting = 0;
  196128. - u32 temp;
  196129. - unsigned long flags;
  196130. -
  196131. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
  196132. - return count;
  196133. -
  196134. -
  196135. - /* Find out the new setting */
  196136. - if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
  196137. - new_setting = 1;
  196138. - else if (!strncmp("off", buf, count - 1) ||
  196139. - !strncmp("0", buf, count - 1))
  196140. - new_setting = 0;
  196141. - else
  196142. - return count;
  196143. -
  196144. -
  196145. - local_irq_save(flags);
  196146. - lock_rx_qs(priv);
  196147. -
  196148. - /* Set the new stashing value */
  196149. - priv->bd_stash_en = new_setting;
  196150. -
  196151. - temp = gfar_read(&regs->attr);
  196152. -
  196153. - if (new_setting)
  196154. - temp |= ATTR_BDSTASH;
  196155. - else
  196156. - temp &= ~(ATTR_BDSTASH);
  196157. -
  196158. - gfar_write(&regs->attr, temp);
  196159. -
  196160. - unlock_rx_qs(priv);
  196161. - local_irq_restore(flags);
  196162. -
  196163. - return count;
  196164. -}
  196165. -
  196166. -static DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
  196167. -
  196168. -static ssize_t gfar_show_rx_stash_size(struct device *dev,
  196169. - struct device_attribute *attr, char *buf)
  196170. -{
  196171. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196172. -
  196173. - return sprintf(buf, "%d\n", priv->rx_stash_size);
  196174. -}
  196175. -
  196176. -static ssize_t gfar_set_rx_stash_size(struct device *dev,
  196177. - struct device_attribute *attr,
  196178. - const char *buf, size_t count)
  196179. -{
  196180. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196181. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  196182. - unsigned int length = simple_strtoul(buf, NULL, 0);
  196183. - u32 temp;
  196184. - unsigned long flags;
  196185. -
  196186. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
  196187. - return count;
  196188. -
  196189. - local_irq_save(flags);
  196190. - lock_rx_qs(priv);
  196191. -
  196192. - if (length > priv->rx_buffer_size)
  196193. - goto out;
  196194. -
  196195. - if (length == priv->rx_stash_size)
  196196. - goto out;
  196197. -
  196198. - priv->rx_stash_size = length;
  196199. -
  196200. - temp = gfar_read(&regs->attreli);
  196201. - temp &= ~ATTRELI_EL_MASK;
  196202. - temp |= ATTRELI_EL(length);
  196203. - gfar_write(&regs->attreli, temp);
  196204. -
  196205. - /* Turn stashing on/off as appropriate */
  196206. - temp = gfar_read(&regs->attr);
  196207. -
  196208. - if (length)
  196209. - temp |= ATTR_BUFSTASH;
  196210. - else
  196211. - temp &= ~(ATTR_BUFSTASH);
  196212. -
  196213. - gfar_write(&regs->attr, temp);
  196214. -
  196215. -out:
  196216. - unlock_rx_qs(priv);
  196217. - local_irq_restore(flags);
  196218. -
  196219. - return count;
  196220. -}
  196221. -
  196222. -static DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
  196223. - gfar_set_rx_stash_size);
  196224. -
  196225. -/* Stashing will only be enabled when rx_stash_size != 0 */
  196226. -static ssize_t gfar_show_rx_stash_index(struct device *dev,
  196227. - struct device_attribute *attr,
  196228. - char *buf)
  196229. -{
  196230. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196231. -
  196232. - return sprintf(buf, "%d\n", priv->rx_stash_index);
  196233. -}
  196234. -
  196235. -static ssize_t gfar_set_rx_stash_index(struct device *dev,
  196236. - struct device_attribute *attr,
  196237. - const char *buf, size_t count)
  196238. -{
  196239. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196240. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  196241. - unsigned short index = simple_strtoul(buf, NULL, 0);
  196242. - u32 temp;
  196243. - unsigned long flags;
  196244. -
  196245. - if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
  196246. - return count;
  196247. -
  196248. - local_irq_save(flags);
  196249. - lock_rx_qs(priv);
  196250. -
  196251. - if (index > priv->rx_stash_size)
  196252. - goto out;
  196253. -
  196254. - if (index == priv->rx_stash_index)
  196255. - goto out;
  196256. -
  196257. - priv->rx_stash_index = index;
  196258. -
  196259. - temp = gfar_read(&regs->attreli);
  196260. - temp &= ~ATTRELI_EI_MASK;
  196261. - temp |= ATTRELI_EI(index);
  196262. - gfar_write(&regs->attreli, temp);
  196263. -
  196264. -out:
  196265. - unlock_rx_qs(priv);
  196266. - local_irq_restore(flags);
  196267. -
  196268. - return count;
  196269. -}
  196270. -
  196271. -static DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
  196272. - gfar_set_rx_stash_index);
  196273. -
  196274. -static ssize_t gfar_show_fifo_threshold(struct device *dev,
  196275. - struct device_attribute *attr,
  196276. - char *buf)
  196277. -{
  196278. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196279. -
  196280. - return sprintf(buf, "%d\n", priv->fifo_threshold);
  196281. -}
  196282. -
  196283. -static ssize_t gfar_set_fifo_threshold(struct device *dev,
  196284. - struct device_attribute *attr,
  196285. - const char *buf, size_t count)
  196286. -{
  196287. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196288. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  196289. - unsigned int length = simple_strtoul(buf, NULL, 0);
  196290. - u32 temp;
  196291. - unsigned long flags;
  196292. -
  196293. - if (length > GFAR_MAX_FIFO_THRESHOLD)
  196294. - return count;
  196295. -
  196296. - local_irq_save(flags);
  196297. - lock_tx_qs(priv);
  196298. -
  196299. - priv->fifo_threshold = length;
  196300. -
  196301. - temp = gfar_read(&regs->fifo_tx_thr);
  196302. - temp &= ~FIFO_TX_THR_MASK;
  196303. - temp |= length;
  196304. - gfar_write(&regs->fifo_tx_thr, temp);
  196305. -
  196306. - unlock_tx_qs(priv);
  196307. - local_irq_restore(flags);
  196308. -
  196309. - return count;
  196310. -}
  196311. -
  196312. -static DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
  196313. - gfar_set_fifo_threshold);
  196314. -
  196315. -static ssize_t gfar_show_fifo_starve(struct device *dev,
  196316. - struct device_attribute *attr, char *buf)
  196317. -{
  196318. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196319. -
  196320. - return sprintf(buf, "%d\n", priv->fifo_starve);
  196321. -}
  196322. -
  196323. -static ssize_t gfar_set_fifo_starve(struct device *dev,
  196324. - struct device_attribute *attr,
  196325. - const char *buf, size_t count)
  196326. -{
  196327. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196328. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  196329. - unsigned int num = simple_strtoul(buf, NULL, 0);
  196330. - u32 temp;
  196331. - unsigned long flags;
  196332. -
  196333. - if (num > GFAR_MAX_FIFO_STARVE)
  196334. - return count;
  196335. -
  196336. - local_irq_save(flags);
  196337. - lock_tx_qs(priv);
  196338. -
  196339. - priv->fifo_starve = num;
  196340. -
  196341. - temp = gfar_read(&regs->fifo_tx_starve);
  196342. - temp &= ~FIFO_TX_STARVE_MASK;
  196343. - temp |= num;
  196344. - gfar_write(&regs->fifo_tx_starve, temp);
  196345. -
  196346. - unlock_tx_qs(priv);
  196347. - local_irq_restore(flags);
  196348. -
  196349. - return count;
  196350. -}
  196351. -
  196352. -static DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve,
  196353. - gfar_set_fifo_starve);
  196354. -
  196355. -static ssize_t gfar_show_fifo_starve_off(struct device *dev,
  196356. - struct device_attribute *attr,
  196357. - char *buf)
  196358. -{
  196359. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196360. -
  196361. - return sprintf(buf, "%d\n", priv->fifo_starve_off);
  196362. -}
  196363. -
  196364. -static ssize_t gfar_set_fifo_starve_off(struct device *dev,
  196365. - struct device_attribute *attr,
  196366. - const char *buf, size_t count)
  196367. -{
  196368. - struct gfar_private *priv = netdev_priv(to_net_dev(dev));
  196369. - struct gfar __iomem *regs = priv->gfargrp[0].regs;
  196370. - unsigned int num = simple_strtoul(buf, NULL, 0);
  196371. - u32 temp;
  196372. - unsigned long flags;
  196373. -
  196374. - if (num > GFAR_MAX_FIFO_STARVE_OFF)
  196375. - return count;
  196376. -
  196377. - local_irq_save(flags);
  196378. - lock_tx_qs(priv);
  196379. -
  196380. - priv->fifo_starve_off = num;
  196381. -
  196382. - temp = gfar_read(&regs->fifo_tx_starve_shutoff);
  196383. - temp &= ~FIFO_TX_STARVE_OFF_MASK;
  196384. - temp |= num;
  196385. - gfar_write(&regs->fifo_tx_starve_shutoff, temp);
  196386. -
  196387. - unlock_tx_qs(priv);
  196388. - local_irq_restore(flags);
  196389. -
  196390. - return count;
  196391. -}
  196392. -
  196393. -static DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
  196394. - gfar_set_fifo_starve_off);
  196395. -
  196396. -void gfar_init_sysfs(struct net_device *dev)
  196397. -{
  196398. - struct gfar_private *priv = netdev_priv(dev);
  196399. - int rc;
  196400. -
  196401. - /* Initialize the default values */
  196402. - priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
  196403. - priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
  196404. - priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
  196405. -
  196406. - /* Create our sysfs files */
  196407. - rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
  196408. - rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size);
  196409. - rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index);
  196410. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold);
  196411. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve);
  196412. - rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off);
  196413. - if (rc)
  196414. - dev_err(&dev->dev, "Error creating gianfar sysfs files\n");
  196415. -}
  196416. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/Kconfig linux-imx6-3.14/drivers/net/ethernet/freescale/Kconfig
  196417. --- linux-3.14.17/drivers/net/ethernet/freescale/Kconfig 2014-08-14 03:38:34.000000000 +0200
  196418. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/Kconfig 2014-09-11 18:06:03.498043952 +0200
  196419. @@ -67,6 +67,7 @@
  196420. tristate "Freescale XGMAC MDIO"
  196421. depends on FSL_SOC
  196422. select PHYLIB
  196423. + select OF_MDIO
  196424. ---help---
  196425. This driver supports the MDIO bus on the Fman 10G Ethernet MACs.
  196426. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/Makefile linux-imx6-3.14/drivers/net/ethernet/freescale/Makefile
  196427. --- linux-3.14.17/drivers/net/ethernet/freescale/Makefile 2014-08-14 03:38:34.000000000 +0200
  196428. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/Makefile 2014-09-11 18:06:03.498043952 +0200
  196429. @@ -14,7 +14,6 @@
  196430. obj-$(CONFIG_GIANFAR) += gianfar_driver.o
  196431. obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
  196432. gianfar_driver-objs := gianfar.o \
  196433. - gianfar_ethtool.o \
  196434. - gianfar_sysfs.o
  196435. + gianfar_ethtool.o
  196436. obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
  196437. ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
  196438. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/ucc_geth.c linux-imx6-3.14/drivers/net/ethernet/freescale/ucc_geth.c
  196439. --- linux-3.14.17/drivers/net/ethernet/freescale/ucc_geth.c 2014-08-14 03:38:34.000000000 +0200
  196440. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/ucc_geth.c 2014-09-11 18:06:03.502043969 +0200
  196441. @@ -1728,9 +1728,6 @@
  196442. phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
  196443. priv->phy_interface);
  196444. - if (!phydev)
  196445. - phydev = of_phy_connect_fixed_link(dev, &adjust_link,
  196446. - priv->phy_interface);
  196447. if (!phydev) {
  196448. dev_err(&dev->dev, "Could not attach to PHY\n");
  196449. return -ENODEV;
  196450. @@ -3261,7 +3258,7 @@
  196451. dev->stats.tx_packets++;
  196452. - dev_kfree_skb(skb);
  196453. + dev_consume_skb_any(skb);
  196454. ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
  196455. ugeth->skb_dirtytx[txQ] =
  196456. @@ -3790,6 +3787,17 @@
  196457. ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
  196458. ug_info->phy_node = of_parse_phandle(np, "phy-handle", 0);
  196459. + if (!ug_info->phy_node) {
  196460. + /* In the case of a fixed PHY, the DT node associated
  196461. + * to the PHY is the Ethernet MAC DT node.
  196462. + */
  196463. + if (of_phy_is_fixed_link(np)) {
  196464. + err = of_phy_register_fixed_link(np);
  196465. + if (err)
  196466. + return err;
  196467. + }
  196468. + ug_info->phy_node = np;
  196469. + }
  196470. /* Find the TBI PHY node. If it's not there, we don't support SGMII */
  196471. ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
  196472. diff -Nur linux-3.14.17/drivers/net/ethernet/freescale/xgmac_mdio.c linux-imx6-3.14/drivers/net/ethernet/freescale/xgmac_mdio.c
  196473. --- linux-3.14.17/drivers/net/ethernet/freescale/xgmac_mdio.c 2014-08-14 03:38:34.000000000 +0200
  196474. +++ linux-imx6-3.14/drivers/net/ethernet/freescale/xgmac_mdio.c 2014-09-11 18:06:03.502043969 +0200
  196475. @@ -162,7 +162,9 @@
  196476. /* Return all Fs if nothing was there */
  196477. if (in_be32(&regs->mdio_stat) & MDIO_STAT_RD_ER) {
  196478. - dev_err(&bus->dev, "MDIO read error\n");
  196479. + dev_err(&bus->dev,
  196480. + "Error while reading PHY%d reg at %d.%d\n",
  196481. + phy_id, dev_addr, regnum);
  196482. return 0xffff;
  196483. }
  196484. diff -Nur linux-3.14.17/drivers/net/ethernet/intel/e1000e/ptp.c linux-imx6-3.14/drivers/net/ethernet/intel/e1000e/ptp.c
  196485. --- linux-3.14.17/drivers/net/ethernet/intel/e1000e/ptp.c 2014-08-14 03:38:34.000000000 +0200
  196486. +++ linux-imx6-3.14/drivers/net/ethernet/intel/e1000e/ptp.c 2014-09-11 18:06:03.558044192 +0200
  196487. @@ -191,6 +191,7 @@
  196488. .n_alarm = 0,
  196489. .n_ext_ts = 0,
  196490. .n_per_out = 0,
  196491. + .n_pins = 0,
  196492. .pps = 0,
  196493. .adjfreq = e1000e_phc_adjfreq,
  196494. .adjtime = e1000e_phc_adjtime,
  196495. diff -Nur linux-3.14.17/drivers/net/ethernet/mellanox/mlx4/en_clock.c linux-imx6-3.14/drivers/net/ethernet/mellanox/mlx4/en_clock.c
  196496. --- linux-3.14.17/drivers/net/ethernet/mellanox/mlx4/en_clock.c 2014-08-14 03:38:34.000000000 +0200
  196497. +++ linux-imx6-3.14/drivers/net/ethernet/mellanox/mlx4/en_clock.c 2014-09-11 18:06:03.614044416 +0200
  196498. @@ -276,6 +276,7 @@
  196499. .n_alarm = 0,
  196500. .n_ext_ts = 0,
  196501. .n_per_out = 0,
  196502. + .n_pins = 0,
  196503. .pps = 0,
  196504. .adjfreq = mlx4_en_phc_adjfreq,
  196505. .adjtime = mlx4_en_phc_adjtime,
  196506. diff -Nur linux-3.14.17/drivers/net/ethernet/sfc/ptp.c linux-imx6-3.14/drivers/net/ethernet/sfc/ptp.c
  196507. --- linux-3.14.17/drivers/net/ethernet/sfc/ptp.c 2014-08-14 03:38:34.000000000 +0200
  196508. +++ linux-imx6-3.14/drivers/net/ethernet/sfc/ptp.c 2014-09-11 18:06:03.674044656 +0200
  196509. @@ -1208,6 +1208,7 @@
  196510. .n_alarm = 0,
  196511. .n_ext_ts = 0,
  196512. .n_per_out = 0,
  196513. + .n_pins = 0,
  196514. .pps = 1,
  196515. .adjfreq = efx_phc_adjfreq,
  196516. .adjtime = efx_phc_adjtime,
  196517. diff -Nur linux-3.14.17/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c linux-imx6-3.14/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
  196518. --- linux-3.14.17/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 2014-08-14 03:38:34.000000000 +0200
  196519. +++ linux-imx6-3.14/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 2014-09-11 18:06:03.690044720 +0200
  196520. @@ -164,6 +164,7 @@
  196521. .n_alarm = 0,
  196522. .n_ext_ts = 0,
  196523. .n_per_out = 0,
  196524. + .n_pins = 0,
  196525. .pps = 0,
  196526. .adjfreq = stmmac_adjust_freq,
  196527. .adjtime = stmmac_adjust_time,
  196528. diff -Nur linux-3.14.17/drivers/net/ethernet/ti/cpts.c linux-imx6-3.14/drivers/net/ethernet/ti/cpts.c
  196529. --- linux-3.14.17/drivers/net/ethernet/ti/cpts.c 2014-08-14 03:38:34.000000000 +0200
  196530. +++ linux-imx6-3.14/drivers/net/ethernet/ti/cpts.c 2014-09-11 18:06:03.698044751 +0200
  196531. @@ -217,6 +217,7 @@
  196532. .name = "CTPS timer",
  196533. .max_adj = 1000000,
  196534. .n_ext_ts = 0,
  196535. + .n_pins = 0,
  196536. .pps = 0,
  196537. .adjfreq = cpts_ptp_adjfreq,
  196538. .adjtime = cpts_ptp_adjtime,
  196539. diff -Nur linux-3.14.17/drivers/net/ethernet/tile/tilegx.c linux-imx6-3.14/drivers/net/ethernet/tile/tilegx.c
  196540. --- linux-3.14.17/drivers/net/ethernet/tile/tilegx.c 2014-08-14 03:38:34.000000000 +0200
  196541. +++ linux-imx6-3.14/drivers/net/ethernet/tile/tilegx.c 2014-09-11 18:06:03.702044768 +0200
  196542. @@ -870,6 +870,7 @@
  196543. .name = "mPIPE clock",
  196544. .max_adj = 999999999,
  196545. .n_ext_ts = 0,
  196546. + .n_pins = 0,
  196547. .pps = 0,
  196548. .adjfreq = ptp_mpipe_adjfreq,
  196549. .adjtime = ptp_mpipe_adjtime,
  196550. diff -Nur linux-3.14.17/drivers/net/ieee802154/Kconfig linux-imx6-3.14/drivers/net/ieee802154/Kconfig
  196551. --- linux-3.14.17/drivers/net/ieee802154/Kconfig 2014-08-14 03:38:34.000000000 +0200
  196552. +++ linux-imx6-3.14/drivers/net/ieee802154/Kconfig 2014-09-11 18:06:03.730044879 +0200
  196553. @@ -15,9 +15,9 @@
  196554. depends on IEEE802154_DRIVERS
  196555. ---help---
  196556. Say Y here to enable the fake driver that serves as an example
  196557. - of HardMAC device driver.
  196558. + of HardMAC device driver.
  196559. - This driver can also be built as a module. To do so say M here.
  196560. + This driver can also be built as a module. To do so say M here.
  196561. The module will be called 'fakehard'.
  196562. config IEEE802154_FAKELB
  196563. @@ -31,17 +31,17 @@
  196564. The module will be called 'fakelb'.
  196565. config IEEE802154_AT86RF230
  196566. - depends on IEEE802154_DRIVERS && MAC802154
  196567. - tristate "AT86RF230/231 transceiver driver"
  196568. - depends on SPI
  196569. + depends on IEEE802154_DRIVERS && MAC802154
  196570. + tristate "AT86RF230/231 transceiver driver"
  196571. + depends on SPI
  196572. config IEEE802154_MRF24J40
  196573. - tristate "Microchip MRF24J40 transceiver driver"
  196574. - depends on IEEE802154_DRIVERS && MAC802154
  196575. - depends on SPI
  196576. - ---help---
  196577. - Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
  196578. - controller.
  196579. + tristate "Microchip MRF24J40 transceiver driver"
  196580. + depends on IEEE802154_DRIVERS && MAC802154
  196581. + depends on SPI
  196582. + ---help---
  196583. + Say Y here to enable the MRF24J20 SPI 802.15.4 wireless
  196584. + controller.
  196585. - This driver can also be built as a module. To do so, say M here.
  196586. - the module will be called 'mrf24j40'.
  196587. + This driver can also be built as a module. To do so, say M here.
  196588. + the module will be called 'mrf24j40'.
  196589. diff -Nur linux-3.14.17/drivers/net/macvlan.c linux-imx6-3.14/drivers/net/macvlan.c
  196590. --- linux-3.14.17/drivers/net/macvlan.c 2014-08-14 03:38:34.000000000 +0200
  196591. +++ linux-imx6-3.14/drivers/net/macvlan.c 2014-09-11 18:06:03.746044943 +0200
  196592. @@ -548,7 +548,6 @@
  196593. (lowerdev->state & MACVLAN_STATE_MASK);
  196594. dev->features = lowerdev->features & MACVLAN_FEATURES;
  196595. dev->features |= ALWAYS_ON_FEATURES;
  196596. - dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES;
  196597. dev->gso_max_size = lowerdev->gso_max_size;
  196598. dev->iflink = lowerdev->ifindex;
  196599. dev->hard_header_len = lowerdev->hard_header_len;
  196600. diff -Nur linux-3.14.17/drivers/net/phy/at803x.c linux-imx6-3.14/drivers/net/phy/at803x.c
  196601. --- linux-3.14.17/drivers/net/phy/at803x.c 2014-08-14 03:38:34.000000000 +0200
  196602. +++ linux-imx6-3.14/drivers/net/phy/at803x.c 2014-09-11 18:06:03.746044943 +0200
  196603. @@ -27,6 +27,9 @@
  196604. #define AT803X_MMD_ACCESS_CONTROL 0x0D
  196605. #define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
  196606. #define AT803X_FUNC_DATA 0x4003
  196607. +#define AT803X_INER 0x0012
  196608. +#define AT803X_INER_INIT 0xec00
  196609. +#define AT803X_INSR 0x0013
  196610. #define AT803X_DEBUG_ADDR 0x1D
  196611. #define AT803X_DEBUG_DATA 0x1E
  196612. #define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
  196613. @@ -141,41 +144,11 @@
  196614. static int at803x_config_init(struct phy_device *phydev)
  196615. {
  196616. - int val;
  196617. int ret;
  196618. - u32 features;
  196619. - features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
  196620. - SUPPORTED_FIBRE | SUPPORTED_BNC;
  196621. -
  196622. - val = phy_read(phydev, MII_BMSR);
  196623. - if (val < 0)
  196624. - return val;
  196625. -
  196626. - if (val & BMSR_ANEGCAPABLE)
  196627. - features |= SUPPORTED_Autoneg;
  196628. - if (val & BMSR_100FULL)
  196629. - features |= SUPPORTED_100baseT_Full;
  196630. - if (val & BMSR_100HALF)
  196631. - features |= SUPPORTED_100baseT_Half;
  196632. - if (val & BMSR_10FULL)
  196633. - features |= SUPPORTED_10baseT_Full;
  196634. - if (val & BMSR_10HALF)
  196635. - features |= SUPPORTED_10baseT_Half;
  196636. -
  196637. - if (val & BMSR_ESTATEN) {
  196638. - val = phy_read(phydev, MII_ESTATUS);
  196639. - if (val < 0)
  196640. - return val;
  196641. -
  196642. - if (val & ESTATUS_1000_TFULL)
  196643. - features |= SUPPORTED_1000baseT_Full;
  196644. - if (val & ESTATUS_1000_THALF)
  196645. - features |= SUPPORTED_1000baseT_Half;
  196646. - }
  196647. -
  196648. - phydev->supported = features;
  196649. - phydev->advertising = features;
  196650. + ret = genphy_config_init(phydev);
  196651. + if (ret < 0)
  196652. + return ret;
  196653. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
  196654. ret = phy_write(phydev, AT803X_DEBUG_ADDR,
  196655. @@ -191,6 +164,31 @@
  196656. return 0;
  196657. }
  196658. +static int at803x_ack_interrupt(struct phy_device *phydev)
  196659. +{
  196660. + int err;
  196661. +
  196662. + err = phy_read(phydev, AT803X_INSR);
  196663. +
  196664. + return (err < 0) ? err : 0;
  196665. +}
  196666. +
  196667. +static int at803x_config_intr(struct phy_device *phydev)
  196668. +{
  196669. + int err;
  196670. + int value;
  196671. +
  196672. + value = phy_read(phydev, AT803X_INER);
  196673. +
  196674. + if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
  196675. + err = phy_write(phydev, AT803X_INER,
  196676. + value | AT803X_INER_INIT);
  196677. + else
  196678. + err = phy_write(phydev, AT803X_INER, 0);
  196679. +
  196680. + return err;
  196681. +}
  196682. +
  196683. static struct phy_driver at803x_driver[] = {
  196684. {
  196685. /* ATHEROS 8035 */
  196686. @@ -240,6 +238,8 @@
  196687. .flags = PHY_HAS_INTERRUPT,
  196688. .config_aneg = genphy_config_aneg,
  196689. .read_status = genphy_read_status,
  196690. + .ack_interrupt = &at803x_ack_interrupt,
  196691. + .config_intr = &at803x_config_intr,
  196692. .driver = {
  196693. .owner = THIS_MODULE,
  196694. },
  196695. @@ -253,8 +253,7 @@
  196696. static void __exit atheros_exit(void)
  196697. {
  196698. - return phy_drivers_unregister(at803x_driver,
  196699. - ARRAY_SIZE(at803x_driver));
  196700. + phy_drivers_unregister(at803x_driver, ARRAY_SIZE(at803x_driver));
  196701. }
  196702. module_init(atheros_init);
  196703. diff -Nur linux-3.14.17/drivers/net/phy/phy_device.c linux-imx6-3.14/drivers/net/phy/phy_device.c
  196704. --- linux-3.14.17/drivers/net/phy/phy_device.c 2014-08-14 03:38:34.000000000 +0200
  196705. +++ linux-imx6-3.14/drivers/net/phy/phy_device.c 2014-09-11 18:06:03.750044960 +0200
  196706. @@ -353,7 +353,7 @@
  196707. phydev->bus->phy_map[phydev->addr] = phydev;
  196708. /* Run all of the fixups for this PHY */
  196709. - err = phy_scan_fixups(phydev);
  196710. + err = phy_init_hw(phydev);
  196711. if (err) {
  196712. pr_err("PHY %d failed to initialize\n", phydev->addr);
  196713. goto out;
  196714. @@ -1029,7 +1029,7 @@
  196715. return 0;
  196716. }
  196717. -static int genphy_config_init(struct phy_device *phydev)
  196718. +int genphy_config_init(struct phy_device *phydev)
  196719. {
  196720. int val;
  196721. u32 features;
  196722. @@ -1075,6 +1075,8 @@
  196723. return 0;
  196724. }
  196725. +EXPORT_SYMBOL(genphy_config_init);
  196726. +
  196727. static int gen10g_config_init(struct phy_device *phydev)
  196728. {
  196729. /* Temporarily just say we support everything */
  196730. diff -Nur linux-3.14.17/drivers/net/phy/smsc.c linux-imx6-3.14/drivers/net/phy/smsc.c
  196731. --- linux-3.14.17/drivers/net/phy/smsc.c 2014-08-14 03:38:34.000000000 +0200
  196732. +++ linux-imx6-3.14/drivers/net/phy/smsc.c 2014-09-11 18:06:03.750044960 +0200
  196733. @@ -249,8 +249,7 @@
  196734. static void __exit smsc_exit(void)
  196735. {
  196736. - return phy_drivers_unregister(smsc_phy_driver,
  196737. - ARRAY_SIZE(smsc_phy_driver));
  196738. + phy_drivers_unregister(smsc_phy_driver, ARRAY_SIZE(smsc_phy_driver));
  196739. }
  196740. MODULE_DESCRIPTION("SMSC PHY driver");
  196741. diff -Nur linux-3.14.17/drivers/net/phy/vitesse.c linux-imx6-3.14/drivers/net/phy/vitesse.c
  196742. --- linux-3.14.17/drivers/net/phy/vitesse.c 2014-08-14 03:38:34.000000000 +0200
  196743. +++ linux-imx6-3.14/drivers/net/phy/vitesse.c 2014-09-11 18:06:03.750044960 +0200
  196744. @@ -319,8 +319,7 @@
  196745. static void __exit vsc82xx_exit(void)
  196746. {
  196747. - return phy_drivers_unregister(vsc82xx_driver,
  196748. - ARRAY_SIZE(vsc82xx_driver));
  196749. + phy_drivers_unregister(vsc82xx_driver, ARRAY_SIZE(vsc82xx_driver));
  196750. }
  196751. module_init(vsc82xx_init);
  196752. diff -Nur linux-3.14.17/drivers/net/ppp/pptp.c linux-imx6-3.14/drivers/net/ppp/pptp.c
  196753. --- linux-3.14.17/drivers/net/ppp/pptp.c 2014-08-14 03:38:34.000000000 +0200
  196754. +++ linux-imx6-3.14/drivers/net/ppp/pptp.c 2014-09-11 18:06:03.754044975 +0200
  196755. @@ -281,7 +281,7 @@
  196756. nf_reset(skb);
  196757. skb->ip_summed = CHECKSUM_NONE;
  196758. - ip_select_ident(skb, NULL);
  196759. + ip_select_ident(skb, &rt->dst, NULL);
  196760. ip_send_check(iph);
  196761. ip_local_out(skb);
  196762. diff -Nur linux-3.14.17/drivers/net/veth.c linux-imx6-3.14/drivers/net/veth.c
  196763. --- linux-3.14.17/drivers/net/veth.c 2014-08-14 03:38:34.000000000 +0200
  196764. +++ linux-imx6-3.14/drivers/net/veth.c 2014-09-11 18:06:03.790045119 +0200
  196765. @@ -14,6 +14,7 @@
  196766. #include <linux/etherdevice.h>
  196767. #include <linux/u64_stats_sync.h>
  196768. +#include <net/rtnetlink.h>
  196769. #include <net/dst.h>
  196770. #include <net/xfrm.h>
  196771. #include <linux/veth.h>
  196772. @@ -336,10 +337,9 @@
  196773. nla_peer = data[VETH_INFO_PEER];
  196774. ifmp = nla_data(nla_peer);
  196775. - err = nla_parse(peer_tb, IFLA_MAX,
  196776. - nla_data(nla_peer) + sizeof(struct ifinfomsg),
  196777. - nla_len(nla_peer) - sizeof(struct ifinfomsg),
  196778. - ifla_policy);
  196779. + err = rtnl_nla_parse_ifla(peer_tb,
  196780. + nla_data(nla_peer) + sizeof(struct ifinfomsg),
  196781. + nla_len(nla_peer) - sizeof(struct ifinfomsg));
  196782. if (err < 0)
  196783. return err;
  196784. diff -Nur linux-3.14.17/drivers/net/wireless/ath/ar5523/ar5523.c linux-imx6-3.14/drivers/net/wireless/ath/ar5523/ar5523.c
  196785. --- linux-3.14.17/drivers/net/wireless/ath/ar5523/ar5523.c 2014-08-14 03:38:34.000000000 +0200
  196786. +++ linux-imx6-3.14/drivers/net/wireless/ath/ar5523/ar5523.c 2014-09-11 18:06:03.806045183 +0200
  196787. @@ -1090,7 +1090,8 @@
  196788. return ret;
  196789. }
  196790. -static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  196791. +static void ar5523_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  196792. + u32 queues, bool drop)
  196793. {
  196794. struct ar5523 *ar = hw->priv;
  196795. diff -Nur linux-3.14.17/drivers/net/wireless/ath/ath10k/mac.c linux-imx6-3.14/drivers/net/wireless/ath/ath10k/mac.c
  196796. --- linux-3.14.17/drivers/net/wireless/ath/ath10k/mac.c 2014-08-14 03:38:34.000000000 +0200
  196797. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath10k/mac.c 2014-09-11 18:06:03.818045231 +0200
  196798. @@ -3183,7 +3183,8 @@
  196799. return ret;
  196800. }
  196801. -static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  196802. +static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  196803. + u32 queues, bool drop)
  196804. {
  196805. struct ath10k *ar = hw->priv;
  196806. bool skip;
  196807. diff -Nur linux-3.14.17/drivers/net/wireless/ath/ath6kl/cfg80211.c linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/cfg80211.c
  196808. --- linux-3.14.17/drivers/net/wireless/ath/ath6kl/cfg80211.c 2014-08-14 03:38:34.000000000 +0200
  196809. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/cfg80211.c 2014-09-11 18:06:03.850045358 +0200
  196810. @@ -790,7 +790,7 @@
  196811. if (nw_type & ADHOC_NETWORK) {
  196812. ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
  196813. nw_type & ADHOC_CREATOR ? "creator" : "joiner");
  196814. - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
  196815. + cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
  196816. cfg80211_put_bss(ar->wiphy, bss);
  196817. return;
  196818. }
  196819. @@ -861,13 +861,9 @@
  196820. }
  196821. if (vif->nw_type & ADHOC_NETWORK) {
  196822. - if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
  196823. + if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
  196824. ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
  196825. "%s: ath6k not in ibss mode\n", __func__);
  196826. - return;
  196827. - }
  196828. - memset(bssid, 0, ETH_ALEN);
  196829. - cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
  196830. return;
  196831. }
  196832. diff -Nur linux-3.14.17/drivers/net/wireless/ath/ath6kl/hif.h linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/hif.h
  196833. --- linux-3.14.17/drivers/net/wireless/ath/ath6kl/hif.h 2014-08-14 03:38:34.000000000 +0200
  196834. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/hif.h 2014-09-11 18:06:03.850045358 +0200
  196835. @@ -197,9 +197,9 @@
  196836. /* bounce buffer for upper layers to copy to/from */
  196837. u8 *virt_dma_buf;
  196838. - struct hif_scatter_item scat_list[1];
  196839. -
  196840. u32 scat_q_depth;
  196841. +
  196842. + struct hif_scatter_item scat_list[0];
  196843. };
  196844. struct ath6kl_irq_proc_registers {
  196845. diff -Nur linux-3.14.17/drivers/net/wireless/ath/ath6kl/sdio.c linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/sdio.c
  196846. --- linux-3.14.17/drivers/net/wireless/ath/ath6kl/sdio.c 2014-08-14 03:38:34.000000000 +0200
  196847. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath6kl/sdio.c 2014-09-11 18:06:03.850045358 +0200
  196848. @@ -222,6 +222,7 @@
  196849. struct mmc_data *data)
  196850. {
  196851. struct scatterlist *sg;
  196852. + struct hif_scatter_item *scat_list;
  196853. int i;
  196854. data->blksz = HIF_MBOX_BLOCK_SIZE;
  196855. @@ -240,14 +241,14 @@
  196856. sg = scat_req->sgentries;
  196857. sg_init_table(sg, scat_req->scat_entries);
  196858. + scat_list = &scat_req->scat_list[0];
  196859. +
  196860. /* assemble SG list */
  196861. - for (i = 0; i < scat_req->scat_entries; i++, sg++) {
  196862. + for (i = 0; i < scat_req->scat_entries; i++, sg++, scat_list++) {
  196863. ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
  196864. - i, scat_req->scat_list[i].buf,
  196865. - scat_req->scat_list[i].len);
  196866. + i, scat_list->buf, scat_list->len);
  196867. - sg_set_buf(sg, scat_req->scat_list[i].buf,
  196868. - scat_req->scat_list[i].len);
  196869. + sg_set_buf(sg, scat_list->buf, scat_list->len);
  196870. }
  196871. /* set scatter-gather table for request */
  196872. @@ -348,7 +349,7 @@
  196873. int i, scat_req_sz, scat_list_sz, size;
  196874. u8 *virt_buf;
  196875. - scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
  196876. + scat_list_sz = n_scat_entry * sizeof(struct hif_scatter_item);
  196877. scat_req_sz = sizeof(*s_req) + scat_list_sz;
  196878. if (!virt_scat)
  196879. diff -Nur linux-3.14.17/drivers/net/wireless/ath/ath9k/main.c linux-imx6-3.14/drivers/net/wireless/ath/ath9k/main.c
  196880. --- linux-3.14.17/drivers/net/wireless/ath/ath9k/main.c 2014-08-14 03:38:34.000000000 +0200
  196881. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath9k/main.c 2014-09-11 18:06:03.870045438 +0200
  196882. @@ -1883,7 +1883,8 @@
  196883. return !!npend;
  196884. }
  196885. -static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  196886. +static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  196887. + u32 queues, bool drop)
  196888. {
  196889. struct ath_softc *sc = hw->priv;
  196890. struct ath_hw *ah = sc->sc_ah;
  196891. diff -Nur linux-3.14.17/drivers/net/wireless/ath/ath9k/xmit.c linux-imx6-3.14/drivers/net/wireless/ath/ath9k/xmit.c
  196892. --- linux-3.14.17/drivers/net/wireless/ath/ath9k/xmit.c 2014-08-14 03:38:34.000000000 +0200
  196893. +++ linux-imx6-3.14/drivers/net/wireless/ath/ath9k/xmit.c 2014-09-11 18:06:03.874045454 +0200
  196894. @@ -890,15 +890,6 @@
  196895. tx_info = IEEE80211_SKB_CB(skb);
  196896. tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
  196897. -
  196898. - /*
  196899. - * No aggregation session is running, but there may be frames
  196900. - * from a previous session or a failed attempt in the queue.
  196901. - * Send them out as normal data frames
  196902. - */
  196903. - if (!tid->active)
  196904. - tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
  196905. -
  196906. if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
  196907. bf->bf_state.bf_type = 0;
  196908. return bf;
  196909. diff -Nur linux-3.14.17/drivers/net/wireless/ath/carl9170/main.c linux-imx6-3.14/drivers/net/wireless/ath/carl9170/main.c
  196910. --- linux-3.14.17/drivers/net/wireless/ath/carl9170/main.c 2014-08-14 03:38:34.000000000 +0200
  196911. +++ linux-imx6-3.14/drivers/net/wireless/ath/carl9170/main.c 2014-09-11 18:06:03.878045470 +0200
  196912. @@ -1707,7 +1707,9 @@
  196913. return 0;
  196914. }
  196915. -static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  196916. +static void carl9170_op_flush(struct ieee80211_hw *hw,
  196917. + struct ieee80211_vif *vif,
  196918. + u32 queues, bool drop)
  196919. {
  196920. struct ar9170 *ar = hw->priv;
  196921. unsigned int vid;
  196922. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
  196923. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c 2014-08-14 03:38:34.000000000 +0200
  196924. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c 2014-09-11 18:06:03.902045566 +0200
  196925. @@ -43,7 +43,6 @@
  196926. #include "dhd_bus.h"
  196927. #include "dhd_dbg.h"
  196928. #include "sdio_host.h"
  196929. -#include "sdio_chip.h"
  196930. #define SDIOH_API_ACCESS_RETRY_LIMIT 2
  196931. @@ -54,6 +53,12 @@
  196932. /* Maximum milliseconds to wait for F2 to come up */
  196933. #define SDIO_WAIT_F2RDY 3000
  196934. +#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
  196935. +#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
  196936. +
  196937. +static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
  196938. +module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
  196939. +MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
  196940. static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
  196941. {
  196942. @@ -264,26 +269,17 @@
  196943. break;
  196944. }
  196945. - if (ret) {
  196946. - /*
  196947. - * SleepCSR register access can fail when
  196948. - * waking up the device so reduce this noise
  196949. - * in the logs.
  196950. - */
  196951. - if (addr != SBSDIO_FUNC1_SLEEPCSR)
  196952. - brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
  196953. - write ? "write" : "read", fn, addr, ret);
  196954. - else
  196955. - brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  196956. - write ? "write" : "read", fn, addr, ret);
  196957. - }
  196958. + if (ret)
  196959. + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  196960. + write ? "write" : "read", fn, addr, ret);
  196961. +
  196962. return ret;
  196963. }
  196964. static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
  196965. u8 regsz, void *data, bool write)
  196966. {
  196967. - u8 func_num;
  196968. + u8 func;
  196969. s32 retry = 0;
  196970. int ret;
  196971. @@ -297,9 +293,9 @@
  196972. * The rest: function 1 silicon backplane core registers
  196973. */
  196974. if ((addr & ~REG_F0_REG_MASK) == 0)
  196975. - func_num = SDIO_FUNC_0;
  196976. + func = SDIO_FUNC_0;
  196977. else
  196978. - func_num = SDIO_FUNC_1;
  196979. + func = SDIO_FUNC_1;
  196980. do {
  196981. if (!write)
  196982. @@ -307,16 +303,26 @@
  196983. /* for retry wait for 1 ms till bus get settled down */
  196984. if (retry)
  196985. usleep_range(1000, 2000);
  196986. - ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz,
  196987. + ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz,
  196988. data, write);
  196989. } while (ret != 0 && ret != -ENOMEDIUM &&
  196990. retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
  196991. if (ret == -ENOMEDIUM)
  196992. brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM);
  196993. - else if (ret != 0)
  196994. - brcmf_err("failed with %d\n", ret);
  196995. -
  196996. + else if (ret != 0) {
  196997. + /*
  196998. + * SleepCSR register access can fail when
  196999. + * waking up the device so reduce this noise
  197000. + * in the logs.
  197001. + */
  197002. + if (addr != SBSDIO_FUNC1_SLEEPCSR)
  197003. + brcmf_err("failed to %s data F%d@0x%05x, err: %d\n",
  197004. + write ? "write" : "read", func, addr, ret);
  197005. + else
  197006. + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n",
  197007. + write ? "write" : "read", func, addr, ret);
  197008. + }
  197009. return ret;
  197010. }
  197011. @@ -488,7 +494,6 @@
  197012. struct mmc_request mmc_req;
  197013. struct mmc_command mmc_cmd;
  197014. struct mmc_data mmc_dat;
  197015. - struct sg_table st;
  197016. struct scatterlist *sgl;
  197017. int ret = 0;
  197018. @@ -533,16 +538,11 @@
  197019. pkt_offset = 0;
  197020. pkt_next = target_list->next;
  197021. - if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) {
  197022. - ret = -ENOMEM;
  197023. - goto exit;
  197024. - }
  197025. -
  197026. memset(&mmc_req, 0, sizeof(struct mmc_request));
  197027. memset(&mmc_cmd, 0, sizeof(struct mmc_command));
  197028. memset(&mmc_dat, 0, sizeof(struct mmc_data));
  197029. - mmc_dat.sg = st.sgl;
  197030. + mmc_dat.sg = sdiodev->sgtable.sgl;
  197031. mmc_dat.blksz = func_blk_sz;
  197032. mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
  197033. mmc_cmd.opcode = SD_IO_RW_EXTENDED;
  197034. @@ -558,7 +558,7 @@
  197035. while (seg_sz) {
  197036. req_sz = 0;
  197037. sg_cnt = 0;
  197038. - sgl = st.sgl;
  197039. + sgl = sdiodev->sgtable.sgl;
  197040. /* prep sg table */
  197041. while (pkt_next != (struct sk_buff *)target_list) {
  197042. pkt_data = pkt_next->data + pkt_offset;
  197043. @@ -640,7 +640,7 @@
  197044. }
  197045. exit:
  197046. - sg_free_table(&st);
  197047. + sg_init_table(sdiodev->sgtable.sgl, sdiodev->sgtable.orig_nents);
  197048. while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
  197049. brcmu_pkt_buf_free_skb(pkt_next);
  197050. @@ -827,7 +827,7 @@
  197051. }
  197052. if (!write)
  197053. memcpy(data, pkt->data, dsize);
  197054. - skb_trim(pkt, dsize);
  197055. + skb_trim(pkt, 0);
  197056. /* Adjust for next transfer (if any) */
  197057. size -= dsize;
  197058. @@ -864,6 +864,29 @@
  197059. return 0;
  197060. }
  197061. +static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
  197062. +{
  197063. + uint nents;
  197064. + int err;
  197065. +
  197066. + if (!sdiodev->sg_support)
  197067. + return;
  197068. +
  197069. + nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
  197070. + nents += (nents >> 4) + 1;
  197071. +
  197072. + WARN_ON(nents > sdiodev->max_segment_count);
  197073. +
  197074. + brcmf_dbg(TRACE, "nents=%d\n", nents);
  197075. + err = sg_alloc_table(&sdiodev->sgtable, nents, GFP_KERNEL);
  197076. + if (err < 0) {
  197077. + brcmf_err("allocation failed: disable scatter-gather");
  197078. + sdiodev->sg_support = false;
  197079. + }
  197080. +
  197081. + sdiodev->txglomsz = brcmf_sdiod_txglomsz;
  197082. +}
  197083. +
  197084. static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
  197085. {
  197086. if (sdiodev->bus) {
  197087. @@ -881,6 +904,7 @@
  197088. sdio_disable_func(sdiodev->func[1]);
  197089. sdio_release_host(sdiodev->func[1]);
  197090. + sg_free_table(&sdiodev->sgtable);
  197091. sdiodev->sbwad = 0;
  197092. return 0;
  197093. @@ -936,6 +960,11 @@
  197094. SG_MAX_SINGLE_ALLOC);
  197095. sdiodev->max_segment_size = host->max_seg_size;
  197096. + /* allocate scatter-gather table. sg support
  197097. + * will be disabled upon allocation failure.
  197098. + */
  197099. + brcmf_sdiod_sgtable_alloc(sdiodev);
  197100. +
  197101. /* try to attach to the target device */
  197102. sdiodev->bus = brcmf_sdio_probe(sdiodev);
  197103. if (!sdiodev->bus) {
  197104. @@ -960,6 +989,7 @@
  197105. {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)},
  197106. {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
  197107. SDIO_DEVICE_ID_BROADCOM_4335_4339)},
  197108. + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)},
  197109. { /* end: all zeroes */ },
  197110. };
  197111. MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
  197112. @@ -1073,9 +1103,7 @@
  197113. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  197114. int ret = 0;
  197115. - brcmf_dbg(SDIO, "\n");
  197116. -
  197117. - atomic_set(&sdiodev->suspend, true);
  197118. + brcmf_dbg(SDIO, "Enter\n");
  197119. sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
  197120. if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
  197121. @@ -1083,9 +1111,12 @@
  197122. return -EINVAL;
  197123. }
  197124. + atomic_set(&sdiodev->suspend, true);
  197125. +
  197126. ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
  197127. if (ret) {
  197128. brcmf_err("Failed to set pm_flags\n");
  197129. + atomic_set(&sdiodev->suspend, false);
  197130. return ret;
  197131. }
  197132. @@ -1099,6 +1130,7 @@
  197133. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  197134. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  197135. + brcmf_dbg(SDIO, "Enter\n");
  197136. brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
  197137. atomic_set(&sdiodev->suspend, false);
  197138. return 0;
  197139. @@ -1115,14 +1147,15 @@
  197140. .remove = brcmf_ops_sdio_remove,
  197141. .name = BRCMFMAC_SDIO_PDATA_NAME,
  197142. .id_table = brcmf_sdmmc_ids,
  197143. -#ifdef CONFIG_PM_SLEEP
  197144. .drv = {
  197145. + .owner = THIS_MODULE,
  197146. +#ifdef CONFIG_PM_SLEEP
  197147. .pm = &brcmf_sdio_pm_ops,
  197148. - },
  197149. #endif /* CONFIG_PM_SLEEP */
  197150. + },
  197151. };
  197152. -static int brcmf_sdio_pd_probe(struct platform_device *pdev)
  197153. +static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
  197154. {
  197155. brcmf_dbg(SDIO, "Enter\n");
  197156. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/chip.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.c
  197157. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/chip.c 1970-01-01 01:00:00.000000000 +0100
  197158. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.c 2014-09-11 18:06:03.902045566 +0200
  197159. @@ -0,0 +1,1035 @@
  197160. +/*
  197161. + * Copyright (c) 2014 Broadcom Corporation
  197162. + *
  197163. + * Permission to use, copy, modify, and/or distribute this software for any
  197164. + * purpose with or without fee is hereby granted, provided that the above
  197165. + * copyright notice and this permission notice appear in all copies.
  197166. + *
  197167. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  197168. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  197169. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  197170. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  197171. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  197172. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  197173. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  197174. + */
  197175. +#include <linux/kernel.h>
  197176. +#include <linux/delay.h>
  197177. +#include <linux/list.h>
  197178. +#include <linux/ssb/ssb_regs.h>
  197179. +#include <linux/bcma/bcma.h>
  197180. +#include <linux/bcma/bcma_regs.h>
  197181. +
  197182. +#include <defs.h>
  197183. +#include <soc.h>
  197184. +#include <brcm_hw_ids.h>
  197185. +#include <brcmu_utils.h>
  197186. +#include <chipcommon.h>
  197187. +#include "dhd_dbg.h"
  197188. +#include "chip.h"
  197189. +
  197190. +/* SOC Interconnect types (aka chip types) */
  197191. +#define SOCI_SB 0
  197192. +#define SOCI_AI 1
  197193. +
  197194. +/* PL-368 DMP definitions */
  197195. +#define DMP_DESC_TYPE_MSK 0x0000000F
  197196. +#define DMP_DESC_EMPTY 0x00000000
  197197. +#define DMP_DESC_VALID 0x00000001
  197198. +#define DMP_DESC_COMPONENT 0x00000001
  197199. +#define DMP_DESC_MASTER_PORT 0x00000003
  197200. +#define DMP_DESC_ADDRESS 0x00000005
  197201. +#define DMP_DESC_ADDRSIZE_GT32 0x00000008
  197202. +#define DMP_DESC_EOT 0x0000000F
  197203. +
  197204. +#define DMP_COMP_DESIGNER 0xFFF00000
  197205. +#define DMP_COMP_DESIGNER_S 20
  197206. +#define DMP_COMP_PARTNUM 0x000FFF00
  197207. +#define DMP_COMP_PARTNUM_S 8
  197208. +#define DMP_COMP_CLASS 0x000000F0
  197209. +#define DMP_COMP_CLASS_S 4
  197210. +#define DMP_COMP_REVISION 0xFF000000
  197211. +#define DMP_COMP_REVISION_S 24
  197212. +#define DMP_COMP_NUM_SWRAP 0x00F80000
  197213. +#define DMP_COMP_NUM_SWRAP_S 19
  197214. +#define DMP_COMP_NUM_MWRAP 0x0007C000
  197215. +#define DMP_COMP_NUM_MWRAP_S 14
  197216. +#define DMP_COMP_NUM_SPORT 0x00003E00
  197217. +#define DMP_COMP_NUM_SPORT_S 9
  197218. +#define DMP_COMP_NUM_MPORT 0x000001F0
  197219. +#define DMP_COMP_NUM_MPORT_S 4
  197220. +
  197221. +#define DMP_MASTER_PORT_UID 0x0000FF00
  197222. +#define DMP_MASTER_PORT_UID_S 8
  197223. +#define DMP_MASTER_PORT_NUM 0x000000F0
  197224. +#define DMP_MASTER_PORT_NUM_S 4
  197225. +
  197226. +#define DMP_SLAVE_ADDR_BASE 0xFFFFF000
  197227. +#define DMP_SLAVE_ADDR_BASE_S 12
  197228. +#define DMP_SLAVE_PORT_NUM 0x00000F00
  197229. +#define DMP_SLAVE_PORT_NUM_S 8
  197230. +#define DMP_SLAVE_TYPE 0x000000C0
  197231. +#define DMP_SLAVE_TYPE_S 6
  197232. +#define DMP_SLAVE_TYPE_SLAVE 0
  197233. +#define DMP_SLAVE_TYPE_BRIDGE 1
  197234. +#define DMP_SLAVE_TYPE_SWRAP 2
  197235. +#define DMP_SLAVE_TYPE_MWRAP 3
  197236. +#define DMP_SLAVE_SIZE_TYPE 0x00000030
  197237. +#define DMP_SLAVE_SIZE_TYPE_S 4
  197238. +#define DMP_SLAVE_SIZE_4K 0
  197239. +#define DMP_SLAVE_SIZE_8K 1
  197240. +#define DMP_SLAVE_SIZE_16K 2
  197241. +#define DMP_SLAVE_SIZE_DESC 3
  197242. +
  197243. +/* EROM CompIdentB */
  197244. +#define CIB_REV_MASK 0xff000000
  197245. +#define CIB_REV_SHIFT 24
  197246. +
  197247. +/* ARM CR4 core specific control flag bits */
  197248. +#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  197249. +
  197250. +/* D11 core specific control flag bits */
  197251. +#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  197252. +#define D11_BCMA_IOCTL_PHYRESET 0x0008
  197253. +
  197254. +/* chip core base & ramsize */
  197255. +/* bcm4329 */
  197256. +/* SDIO device core, ID 0x829 */
  197257. +#define BCM4329_CORE_BUS_BASE 0x18011000
  197258. +/* internal memory core, ID 0x80e */
  197259. +#define BCM4329_CORE_SOCRAM_BASE 0x18003000
  197260. +/* ARM Cortex M3 core, ID 0x82a */
  197261. +#define BCM4329_CORE_ARM_BASE 0x18002000
  197262. +#define BCM4329_RAMSIZE 0x48000
  197263. +
  197264. +/* bcm43143 */
  197265. +/* SDIO device core */
  197266. +#define BCM43143_CORE_BUS_BASE 0x18002000
  197267. +/* internal memory core */
  197268. +#define BCM43143_CORE_SOCRAM_BASE 0x18004000
  197269. +/* ARM Cortex M3 core, ID 0x82a */
  197270. +#define BCM43143_CORE_ARM_BASE 0x18003000
  197271. +#define BCM43143_RAMSIZE 0x70000
  197272. +
  197273. +#define CORE_SB(base, field) \
  197274. + (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
  197275. +#define SBCOREREV(sbidh) \
  197276. + ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
  197277. + ((sbidh) & SSB_IDHIGH_RCLO))
  197278. +
  197279. +struct sbconfig {
  197280. + u32 PAD[2];
  197281. + u32 sbipsflag; /* initiator port ocp slave flag */
  197282. + u32 PAD[3];
  197283. + u32 sbtpsflag; /* target port ocp slave flag */
  197284. + u32 PAD[11];
  197285. + u32 sbtmerrloga; /* (sonics >= 2.3) */
  197286. + u32 PAD;
  197287. + u32 sbtmerrlog; /* (sonics >= 2.3) */
  197288. + u32 PAD[3];
  197289. + u32 sbadmatch3; /* address match3 */
  197290. + u32 PAD;
  197291. + u32 sbadmatch2; /* address match2 */
  197292. + u32 PAD;
  197293. + u32 sbadmatch1; /* address match1 */
  197294. + u32 PAD[7];
  197295. + u32 sbimstate; /* initiator agent state */
  197296. + u32 sbintvec; /* interrupt mask */
  197297. + u32 sbtmstatelow; /* target state */
  197298. + u32 sbtmstatehigh; /* target state */
  197299. + u32 sbbwa0; /* bandwidth allocation table0 */
  197300. + u32 PAD;
  197301. + u32 sbimconfiglow; /* initiator configuration */
  197302. + u32 sbimconfighigh; /* initiator configuration */
  197303. + u32 sbadmatch0; /* address match0 */
  197304. + u32 PAD;
  197305. + u32 sbtmconfiglow; /* target configuration */
  197306. + u32 sbtmconfighigh; /* target configuration */
  197307. + u32 sbbconfig; /* broadcast configuration */
  197308. + u32 PAD;
  197309. + u32 sbbstate; /* broadcast state */
  197310. + u32 PAD[3];
  197311. + u32 sbactcnfg; /* activate configuration */
  197312. + u32 PAD[3];
  197313. + u32 sbflagst; /* current sbflags */
  197314. + u32 PAD[3];
  197315. + u32 sbidlow; /* identification */
  197316. + u32 sbidhigh; /* identification */
  197317. +};
  197318. +
  197319. +struct brcmf_core_priv {
  197320. + struct brcmf_core pub;
  197321. + u32 wrapbase;
  197322. + struct list_head list;
  197323. + struct brcmf_chip_priv *chip;
  197324. +};
  197325. +
  197326. +/* ARM CR4 core specific control flag bits */
  197327. +#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  197328. +
  197329. +/* D11 core specific control flag bits */
  197330. +#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  197331. +#define D11_BCMA_IOCTL_PHYRESET 0x0008
  197332. +
  197333. +struct brcmf_chip_priv {
  197334. + struct brcmf_chip pub;
  197335. + const struct brcmf_buscore_ops *ops;
  197336. + void *ctx;
  197337. + /* assured first core is chipcommon, second core is buscore */
  197338. + struct list_head cores;
  197339. + u16 num_cores;
  197340. +
  197341. + bool (*iscoreup)(struct brcmf_core_priv *core);
  197342. + void (*coredisable)(struct brcmf_core_priv *core, u32 prereset,
  197343. + u32 reset);
  197344. + void (*resetcore)(struct brcmf_core_priv *core, u32 prereset, u32 reset,
  197345. + u32 postreset);
  197346. +};
  197347. +
  197348. +static void brcmf_chip_sb_corerev(struct brcmf_chip_priv *ci,
  197349. + struct brcmf_core *core)
  197350. +{
  197351. + u32 regdata;
  197352. +
  197353. + regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
  197354. + core->rev = SBCOREREV(regdata);
  197355. +}
  197356. +
  197357. +static bool brcmf_chip_sb_iscoreup(struct brcmf_core_priv *core)
  197358. +{
  197359. + struct brcmf_chip_priv *ci;
  197360. + u32 regdata;
  197361. + u32 address;
  197362. +
  197363. + ci = core->chip;
  197364. + address = CORE_SB(core->pub.base, sbtmstatelow);
  197365. + regdata = ci->ops->read32(ci->ctx, address);
  197366. + regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
  197367. + SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
  197368. + return SSB_TMSLOW_CLOCK == regdata;
  197369. +}
  197370. +
  197371. +static bool brcmf_chip_ai_iscoreup(struct brcmf_core_priv *core)
  197372. +{
  197373. + struct brcmf_chip_priv *ci;
  197374. + u32 regdata;
  197375. + bool ret;
  197376. +
  197377. + ci = core->chip;
  197378. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  197379. + ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
  197380. +
  197381. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
  197382. + ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
  197383. +
  197384. + return ret;
  197385. +}
  197386. +
  197387. +static void brcmf_chip_sb_coredisable(struct brcmf_core_priv *core,
  197388. + u32 prereset, u32 reset)
  197389. +{
  197390. + struct brcmf_chip_priv *ci;
  197391. + u32 val, base;
  197392. +
  197393. + ci = core->chip;
  197394. + base = core->pub.base;
  197395. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197396. + if (val & SSB_TMSLOW_RESET)
  197397. + return;
  197398. +
  197399. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197400. + if ((val & SSB_TMSLOW_CLOCK) != 0) {
  197401. + /*
  197402. + * set target reject and spin until busy is clear
  197403. + * (preserve core-specific bits)
  197404. + */
  197405. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197406. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  197407. + val | SSB_TMSLOW_REJECT);
  197408. +
  197409. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197410. + udelay(1);
  197411. + SPINWAIT((ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh))
  197412. + & SSB_TMSHIGH_BUSY), 100000);
  197413. +
  197414. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
  197415. + if (val & SSB_TMSHIGH_BUSY)
  197416. + brcmf_err("core state still busy\n");
  197417. +
  197418. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
  197419. + if (val & SSB_IDLOW_INITIATOR) {
  197420. + val = ci->ops->read32(ci->ctx,
  197421. + CORE_SB(base, sbimstate));
  197422. + val |= SSB_IMSTATE_REJECT;
  197423. + ci->ops->write32(ci->ctx,
  197424. + CORE_SB(base, sbimstate), val);
  197425. + val = ci->ops->read32(ci->ctx,
  197426. + CORE_SB(base, sbimstate));
  197427. + udelay(1);
  197428. + SPINWAIT((ci->ops->read32(ci->ctx,
  197429. + CORE_SB(base, sbimstate)) &
  197430. + SSB_IMSTATE_BUSY), 100000);
  197431. + }
  197432. +
  197433. + /* set reset and reject while enabling the clocks */
  197434. + val = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  197435. + SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
  197436. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow), val);
  197437. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197438. + udelay(10);
  197439. +
  197440. + /* clear the initiator reject bit */
  197441. + val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
  197442. + if (val & SSB_IDLOW_INITIATOR) {
  197443. + val = ci->ops->read32(ci->ctx,
  197444. + CORE_SB(base, sbimstate));
  197445. + val &= ~SSB_IMSTATE_REJECT;
  197446. + ci->ops->write32(ci->ctx,
  197447. + CORE_SB(base, sbimstate), val);
  197448. + }
  197449. + }
  197450. +
  197451. + /* leave reset and reject asserted */
  197452. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  197453. + (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
  197454. + udelay(1);
  197455. +}
  197456. +
  197457. +static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
  197458. + u32 prereset, u32 reset)
  197459. +{
  197460. + struct brcmf_chip_priv *ci;
  197461. + u32 regdata;
  197462. +
  197463. + ci = core->chip;
  197464. +
  197465. + /* if core is already in reset, skip reset */
  197466. + regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
  197467. + if ((regdata & BCMA_RESET_CTL_RESET) != 0)
  197468. + goto in_reset_configure;
  197469. +
  197470. + /* configure reset */
  197471. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  197472. + prereset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
  197473. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  197474. +
  197475. + /* put in reset */
  197476. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL,
  197477. + BCMA_RESET_CTL_RESET);
  197478. + usleep_range(10, 20);
  197479. +
  197480. + /* wait till reset is 1 */
  197481. + SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) !=
  197482. + BCMA_RESET_CTL_RESET, 300);
  197483. +
  197484. +in_reset_configure:
  197485. + /* in-reset configure */
  197486. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  197487. + reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
  197488. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  197489. +}
  197490. +
  197491. +static void brcmf_chip_sb_resetcore(struct brcmf_core_priv *core, u32 prereset,
  197492. + u32 reset, u32 postreset)
  197493. +{
  197494. + struct brcmf_chip_priv *ci;
  197495. + u32 regdata;
  197496. + u32 base;
  197497. +
  197498. + ci = core->chip;
  197499. + base = core->pub.base;
  197500. + /*
  197501. + * Must do the disable sequence first to work for
  197502. + * arbitrary current core state.
  197503. + */
  197504. + brcmf_chip_sb_coredisable(core, 0, 0);
  197505. +
  197506. + /*
  197507. + * Now do the initialization sequence.
  197508. + * set reset while enabling the clock and
  197509. + * forcing them on throughout the core
  197510. + */
  197511. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  197512. + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  197513. + SSB_TMSLOW_RESET);
  197514. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197515. + udelay(1);
  197516. +
  197517. + /* clear any serror */
  197518. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
  197519. + if (regdata & SSB_TMSHIGH_SERR)
  197520. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatehigh), 0);
  197521. +
  197522. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbimstate));
  197523. + if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
  197524. + regdata &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
  197525. + ci->ops->write32(ci->ctx, CORE_SB(base, sbimstate), regdata);
  197526. + }
  197527. +
  197528. + /* clear reset and allow it to propagate throughout the core */
  197529. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  197530. + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
  197531. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197532. + udelay(1);
  197533. +
  197534. + /* leave clock enabled */
  197535. + ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
  197536. + SSB_TMSLOW_CLOCK);
  197537. + regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
  197538. + udelay(1);
  197539. +}
  197540. +
  197541. +static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
  197542. + u32 reset, u32 postreset)
  197543. +{
  197544. + struct brcmf_chip_priv *ci;
  197545. + int count;
  197546. +
  197547. + ci = core->chip;
  197548. +
  197549. + /* must disable first to work for arbitrary current core state */
  197550. + brcmf_chip_ai_coredisable(core, prereset, reset);
  197551. +
  197552. + count = 0;
  197553. + while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
  197554. + BCMA_RESET_CTL_RESET) {
  197555. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL, 0);
  197556. + count++;
  197557. + if (count > 50)
  197558. + break;
  197559. + usleep_range(40, 60);
  197560. + }
  197561. +
  197562. + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
  197563. + postreset | BCMA_IOCTL_CLK);
  197564. + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
  197565. +}
  197566. +
  197567. +static char *brcmf_chip_name(uint chipid, char *buf, uint len)
  197568. +{
  197569. + const char *fmt;
  197570. +
  197571. + fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
  197572. + snprintf(buf, len, fmt, chipid);
  197573. + return buf;
  197574. +}
  197575. +
  197576. +static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci,
  197577. + u16 coreid, u32 base,
  197578. + u32 wrapbase)
  197579. +{
  197580. + struct brcmf_core_priv *core;
  197581. +
  197582. + core = kzalloc(sizeof(*core), GFP_KERNEL);
  197583. + if (!core)
  197584. + return ERR_PTR(-ENOMEM);
  197585. +
  197586. + core->pub.id = coreid;
  197587. + core->pub.base = base;
  197588. + core->chip = ci;
  197589. + core->wrapbase = wrapbase;
  197590. +
  197591. + list_add_tail(&core->list, &ci->cores);
  197592. + return &core->pub;
  197593. +}
  197594. +
  197595. +#ifdef DEBUG
  197596. +/* safety check for chipinfo */
  197597. +static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
  197598. +{
  197599. + struct brcmf_core_priv *core;
  197600. + bool need_socram = false;
  197601. + bool has_socram = false;
  197602. + int idx = 1;
  197603. +
  197604. + list_for_each_entry(core, &ci->cores, list) {
  197605. + brcmf_dbg(INFO, " [%-2d] core 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
  197606. + idx++, core->pub.id, core->pub.rev, core->pub.base,
  197607. + core->wrapbase);
  197608. +
  197609. + switch (core->pub.id) {
  197610. + case BCMA_CORE_ARM_CM3:
  197611. + need_socram = true;
  197612. + break;
  197613. + case BCMA_CORE_INTERNAL_MEM:
  197614. + has_socram = true;
  197615. + break;
  197616. + case BCMA_CORE_ARM_CR4:
  197617. + if (ci->pub.rambase == 0) {
  197618. + brcmf_err("RAM base not provided with ARM CR4 core\n");
  197619. + return -ENOMEM;
  197620. + }
  197621. + break;
  197622. + default:
  197623. + break;
  197624. + }
  197625. + }
  197626. +
  197627. + /* check RAM core presence for ARM CM3 core */
  197628. + if (need_socram && !has_socram) {
  197629. + brcmf_err("RAM core not provided with ARM CM3 core\n");
  197630. + return -ENODEV;
  197631. + }
  197632. + return 0;
  197633. +}
  197634. +#else /* DEBUG */
  197635. +static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
  197636. +{
  197637. + return 0;
  197638. +}
  197639. +#endif
  197640. +
  197641. +static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
  197642. +{
  197643. + switch (ci->pub.chip) {
  197644. + case BCM4329_CHIP_ID:
  197645. + ci->pub.ramsize = BCM4329_RAMSIZE;
  197646. + break;
  197647. + case BCM43143_CHIP_ID:
  197648. + ci->pub.ramsize = BCM43143_RAMSIZE;
  197649. + break;
  197650. + case BCM43241_CHIP_ID:
  197651. + ci->pub.ramsize = 0x90000;
  197652. + break;
  197653. + case BCM4330_CHIP_ID:
  197654. + ci->pub.ramsize = 0x48000;
  197655. + break;
  197656. + case BCM4334_CHIP_ID:
  197657. + ci->pub.ramsize = 0x80000;
  197658. + break;
  197659. + case BCM4335_CHIP_ID:
  197660. + ci->pub.ramsize = 0xc0000;
  197661. + ci->pub.rambase = 0x180000;
  197662. + break;
  197663. + case BCM43362_CHIP_ID:
  197664. + ci->pub.ramsize = 0x3c000;
  197665. + break;
  197666. + case BCM4339_CHIP_ID:
  197667. + case BCM4354_CHIP_ID:
  197668. + ci->pub.ramsize = 0xc0000;
  197669. + ci->pub.rambase = 0x180000;
  197670. + break;
  197671. + default:
  197672. + brcmf_err("unknown chip: %s\n", ci->pub.name);
  197673. + break;
  197674. + }
  197675. +}
  197676. +
  197677. +static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
  197678. + u8 *type)
  197679. +{
  197680. + u32 val;
  197681. +
  197682. + /* read next descriptor */
  197683. + val = ci->ops->read32(ci->ctx, *eromaddr);
  197684. + *eromaddr += 4;
  197685. +
  197686. + if (!type)
  197687. + return val;
  197688. +
  197689. + /* determine descriptor type */
  197690. + *type = (val & DMP_DESC_TYPE_MSK);
  197691. + if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)
  197692. + *type = DMP_DESC_ADDRESS;
  197693. +
  197694. + return val;
  197695. +}
  197696. +
  197697. +static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
  197698. + u32 *regbase, u32 *wrapbase)
  197699. +{
  197700. + u8 desc;
  197701. + u32 val;
  197702. + u8 mpnum = 0;
  197703. + u8 stype, sztype, wraptype;
  197704. +
  197705. + *regbase = 0;
  197706. + *wrapbase = 0;
  197707. +
  197708. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
  197709. + if (desc == DMP_DESC_MASTER_PORT) {
  197710. + mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
  197711. + wraptype = DMP_SLAVE_TYPE_MWRAP;
  197712. + } else if (desc == DMP_DESC_ADDRESS) {
  197713. + /* revert erom address */
  197714. + *eromaddr -= 4;
  197715. + wraptype = DMP_SLAVE_TYPE_SWRAP;
  197716. + } else {
  197717. + *eromaddr -= 4;
  197718. + return -EILSEQ;
  197719. + }
  197720. +
  197721. + do {
  197722. + /* locate address descriptor */
  197723. + do {
  197724. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
  197725. + /* unexpected table end */
  197726. + if (desc == DMP_DESC_EOT) {
  197727. + *eromaddr -= 4;
  197728. + return -EFAULT;
  197729. + }
  197730. + } while (desc != DMP_DESC_ADDRESS);
  197731. +
  197732. + /* skip upper 32-bit address descriptor */
  197733. + if (val & DMP_DESC_ADDRSIZE_GT32)
  197734. + brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  197735. +
  197736. + sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;
  197737. +
  197738. + /* next size descriptor can be skipped */
  197739. + if (sztype == DMP_SLAVE_SIZE_DESC) {
  197740. + val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  197741. + /* skip upper size descriptor if present */
  197742. + if (val & DMP_DESC_ADDRSIZE_GT32)
  197743. + brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
  197744. + }
  197745. +
  197746. + /* only look for 4K register regions */
  197747. + if (sztype != DMP_SLAVE_SIZE_4K)
  197748. + continue;
  197749. +
  197750. + stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
  197751. +
  197752. + /* only regular slave and wrapper */
  197753. + if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)
  197754. + *regbase = val & DMP_SLAVE_ADDR_BASE;
  197755. + if (*wrapbase == 0 && stype == wraptype)
  197756. + *wrapbase = val & DMP_SLAVE_ADDR_BASE;
  197757. + } while (*regbase == 0 || *wrapbase == 0);
  197758. +
  197759. + return 0;
  197760. +}
  197761. +
  197762. +static
  197763. +int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
  197764. +{
  197765. + struct brcmf_core *core;
  197766. + u32 eromaddr;
  197767. + u8 desc_type = 0;
  197768. + u32 val;
  197769. + u16 id;
  197770. + u8 nmp, nsp, nmw, nsw, rev;
  197771. + u32 base, wrap;
  197772. + int err;
  197773. +
  197774. + eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, eromptr));
  197775. +
  197776. + while (desc_type != DMP_DESC_EOT) {
  197777. + val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
  197778. + if (!(val & DMP_DESC_VALID))
  197779. + continue;
  197780. +
  197781. + if (desc_type == DMP_DESC_EMPTY)
  197782. + continue;
  197783. +
  197784. + /* need a component descriptor */
  197785. + if (desc_type != DMP_DESC_COMPONENT)
  197786. + continue;
  197787. +
  197788. + id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;
  197789. +
  197790. + /* next descriptor must be component as well */
  197791. + val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
  197792. + if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))
  197793. + return -EFAULT;
  197794. +
  197795. + /* only look at cores with master port(s) */
  197796. + nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
  197797. + nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
  197798. + nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
  197799. + nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
  197800. + rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
  197801. +
  197802. + /* need core with ports */
  197803. + if (nmw + nsw == 0)
  197804. + continue;
  197805. +
  197806. + /* try to obtain register address info */
  197807. + err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);
  197808. + if (err)
  197809. + continue;
  197810. +
  197811. + /* finally a core to be added */
  197812. + core = brcmf_chip_add_core(ci, id, base, wrap);
  197813. + if (IS_ERR(core))
  197814. + return PTR_ERR(core);
  197815. +
  197816. + core->rev = rev;
  197817. + }
  197818. +
  197819. + return 0;
  197820. +}
  197821. +
  197822. +static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
  197823. +{
  197824. + struct brcmf_core *core;
  197825. + u32 regdata;
  197826. + u32 socitype;
  197827. +
  197828. + /* Get CC core rev
  197829. + * Chipid is assume to be at offset 0 from SI_ENUM_BASE
  197830. + * For different chiptypes or old sdio hosts w/o chipcommon,
  197831. + * other ways of recognition should be added here.
  197832. + */
  197833. + regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
  197834. + ci->pub.chip = regdata & CID_ID_MASK;
  197835. + ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  197836. + socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  197837. +
  197838. + brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name));
  197839. + brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n",
  197840. + socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name,
  197841. + ci->pub.chiprev);
  197842. +
  197843. + if (socitype == SOCI_SB) {
  197844. + if (ci->pub.chip != BCM4329_CHIP_ID) {
  197845. + brcmf_err("SB chip is not supported\n");
  197846. + return -ENODEV;
  197847. + }
  197848. + ci->iscoreup = brcmf_chip_sb_iscoreup;
  197849. + ci->coredisable = brcmf_chip_sb_coredisable;
  197850. + ci->resetcore = brcmf_chip_sb_resetcore;
  197851. +
  197852. + core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
  197853. + SI_ENUM_BASE, 0);
  197854. + brcmf_chip_sb_corerev(ci, core);
  197855. + core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
  197856. + BCM4329_CORE_BUS_BASE, 0);
  197857. + brcmf_chip_sb_corerev(ci, core);
  197858. + core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
  197859. + BCM4329_CORE_SOCRAM_BASE, 0);
  197860. + brcmf_chip_sb_corerev(ci, core);
  197861. + core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
  197862. + BCM4329_CORE_ARM_BASE, 0);
  197863. + brcmf_chip_sb_corerev(ci, core);
  197864. +
  197865. + core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
  197866. + brcmf_chip_sb_corerev(ci, core);
  197867. + } else if (socitype == SOCI_AI) {
  197868. + ci->iscoreup = brcmf_chip_ai_iscoreup;
  197869. + ci->coredisable = brcmf_chip_ai_coredisable;
  197870. + ci->resetcore = brcmf_chip_ai_resetcore;
  197871. +
  197872. + brcmf_chip_dmp_erom_scan(ci);
  197873. + } else {
  197874. + brcmf_err("chip backplane type %u is not supported\n",
  197875. + socitype);
  197876. + return -ENODEV;
  197877. + }
  197878. +
  197879. + brcmf_chip_get_raminfo(ci);
  197880. +
  197881. + return brcmf_chip_cores_check(ci);
  197882. +}
  197883. +
  197884. +static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
  197885. +{
  197886. + struct brcmf_core *core;
  197887. + struct brcmf_core_priv *cr4;
  197888. + u32 val;
  197889. +
  197890. +
  197891. + core = brcmf_chip_get_core(&chip->pub, id);
  197892. + if (!core)
  197893. + return;
  197894. +
  197895. + switch (id) {
  197896. + case BCMA_CORE_ARM_CM3:
  197897. + brcmf_chip_coredisable(core, 0, 0);
  197898. + break;
  197899. + case BCMA_CORE_ARM_CR4:
  197900. + cr4 = container_of(core, struct brcmf_core_priv, pub);
  197901. +
  197902. + /* clear all IOCTL bits except HALT bit */
  197903. + val = chip->ops->read32(chip->ctx, cr4->wrapbase + BCMA_IOCTL);
  197904. + val &= ARMCR4_BCMA_IOCTL_CPUHALT;
  197905. + brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
  197906. + ARMCR4_BCMA_IOCTL_CPUHALT);
  197907. + break;
  197908. + default:
  197909. + brcmf_err("unknown id: %u\n", id);
  197910. + break;
  197911. + }
  197912. +}
  197913. +
  197914. +static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
  197915. +{
  197916. + struct brcmf_chip *pub;
  197917. + struct brcmf_core_priv *cc;
  197918. + u32 base;
  197919. + u32 val;
  197920. + int ret = 0;
  197921. +
  197922. + pub = &chip->pub;
  197923. + cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
  197924. + base = cc->pub.base;
  197925. +
  197926. + /* get chipcommon capabilites */
  197927. + pub->cc_caps = chip->ops->read32(chip->ctx,
  197928. + CORE_CC_REG(base, capabilities));
  197929. +
  197930. + /* get pmu caps & rev */
  197931. + if (pub->cc_caps & CC_CAP_PMU) {
  197932. + val = chip->ops->read32(chip->ctx,
  197933. + CORE_CC_REG(base, pmucapabilities));
  197934. + pub->pmurev = val & PCAP_REV_MASK;
  197935. + pub->pmucaps = val;
  197936. + }
  197937. +
  197938. + brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
  197939. + cc->pub.rev, pub->pmurev, pub->pmucaps);
  197940. +
  197941. + /* execute bus core specific setup */
  197942. + if (chip->ops->setup)
  197943. + ret = chip->ops->setup(chip->ctx, pub);
  197944. +
  197945. + /*
  197946. + * Make sure any on-chip ARM is off (in case strapping is wrong),
  197947. + * or downloaded code was already running.
  197948. + */
  197949. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
  197950. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
  197951. + return ret;
  197952. +}
  197953. +
  197954. +struct brcmf_chip *brcmf_chip_attach(void *ctx,
  197955. + const struct brcmf_buscore_ops *ops)
  197956. +{
  197957. + struct brcmf_chip_priv *chip;
  197958. + int err = 0;
  197959. +
  197960. + if (WARN_ON(!ops->read32))
  197961. + err = -EINVAL;
  197962. + if (WARN_ON(!ops->write32))
  197963. + err = -EINVAL;
  197964. + if (WARN_ON(!ops->prepare))
  197965. + err = -EINVAL;
  197966. + if (WARN_ON(!ops->exit_dl))
  197967. + err = -EINVAL;
  197968. + if (err < 0)
  197969. + return ERR_PTR(-EINVAL);
  197970. +
  197971. + chip = kzalloc(sizeof(*chip), GFP_KERNEL);
  197972. + if (!chip)
  197973. + return ERR_PTR(-ENOMEM);
  197974. +
  197975. + INIT_LIST_HEAD(&chip->cores);
  197976. + chip->num_cores = 0;
  197977. + chip->ops = ops;
  197978. + chip->ctx = ctx;
  197979. +
  197980. + err = ops->prepare(ctx);
  197981. + if (err < 0)
  197982. + goto fail;
  197983. +
  197984. + err = brcmf_chip_recognition(chip);
  197985. + if (err < 0)
  197986. + goto fail;
  197987. +
  197988. + err = brcmf_chip_setup(chip);
  197989. + if (err < 0)
  197990. + goto fail;
  197991. +
  197992. + return &chip->pub;
  197993. +
  197994. +fail:
  197995. + brcmf_chip_detach(&chip->pub);
  197996. + return ERR_PTR(err);
  197997. +}
  197998. +
  197999. +void brcmf_chip_detach(struct brcmf_chip *pub)
  198000. +{
  198001. + struct brcmf_chip_priv *chip;
  198002. + struct brcmf_core_priv *core;
  198003. + struct brcmf_core_priv *tmp;
  198004. +
  198005. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  198006. + list_for_each_entry_safe(core, tmp, &chip->cores, list) {
  198007. + list_del(&core->list);
  198008. + kfree(core);
  198009. + }
  198010. + kfree(chip);
  198011. +}
  198012. +
  198013. +struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
  198014. +{
  198015. + struct brcmf_chip_priv *chip;
  198016. + struct brcmf_core_priv *core;
  198017. +
  198018. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  198019. + list_for_each_entry(core, &chip->cores, list)
  198020. + if (core->pub.id == coreid)
  198021. + return &core->pub;
  198022. +
  198023. + return NULL;
  198024. +}
  198025. +
  198026. +struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)
  198027. +{
  198028. + struct brcmf_chip_priv *chip;
  198029. + struct brcmf_core_priv *cc;
  198030. +
  198031. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  198032. + cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
  198033. + if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))
  198034. + return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);
  198035. + return &cc->pub;
  198036. +}
  198037. +
  198038. +bool brcmf_chip_iscoreup(struct brcmf_core *pub)
  198039. +{
  198040. + struct brcmf_core_priv *core;
  198041. +
  198042. + core = container_of(pub, struct brcmf_core_priv, pub);
  198043. + return core->chip->iscoreup(core);
  198044. +}
  198045. +
  198046. +void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)
  198047. +{
  198048. + struct brcmf_core_priv *core;
  198049. +
  198050. + core = container_of(pub, struct brcmf_core_priv, pub);
  198051. + core->chip->coredisable(core, prereset, reset);
  198052. +}
  198053. +
  198054. +void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
  198055. + u32 postreset)
  198056. +{
  198057. + struct brcmf_core_priv *core;
  198058. +
  198059. + core = container_of(pub, struct brcmf_core_priv, pub);
  198060. + core->chip->resetcore(core, prereset, reset, postreset);
  198061. +}
  198062. +
  198063. +static void
  198064. +brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip)
  198065. +{
  198066. + struct brcmf_core *core;
  198067. +
  198068. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
  198069. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
  198070. + brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
  198071. + D11_BCMA_IOCTL_PHYCLOCKEN,
  198072. + D11_BCMA_IOCTL_PHYCLOCKEN,
  198073. + D11_BCMA_IOCTL_PHYCLOCKEN);
  198074. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
  198075. + brcmf_chip_resetcore(core, 0, 0, 0);
  198076. +}
  198077. +
  198078. +static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
  198079. +{
  198080. + struct brcmf_core *core;
  198081. +
  198082. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
  198083. + if (!brcmf_chip_iscoreup(core)) {
  198084. + brcmf_err("SOCRAM core is down after reset?\n");
  198085. + return false;
  198086. + }
  198087. +
  198088. + chip->ops->exit_dl(chip->ctx, &chip->pub, 0);
  198089. +
  198090. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
  198091. + brcmf_chip_resetcore(core, 0, 0, 0);
  198092. +
  198093. + return true;
  198094. +}
  198095. +
  198096. +static inline void
  198097. +brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip)
  198098. +{
  198099. + struct brcmf_core *core;
  198100. +
  198101. + brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
  198102. +
  198103. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
  198104. + brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
  198105. + D11_BCMA_IOCTL_PHYCLOCKEN,
  198106. + D11_BCMA_IOCTL_PHYCLOCKEN,
  198107. + D11_BCMA_IOCTL_PHYCLOCKEN);
  198108. +}
  198109. +
  198110. +static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec)
  198111. +{
  198112. + struct brcmf_core *core;
  198113. +
  198114. + chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec);
  198115. +
  198116. + /* restore ARM */
  198117. + core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
  198118. + brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
  198119. +
  198120. + return true;
  198121. +}
  198122. +
  198123. +void brcmf_chip_enter_download(struct brcmf_chip *pub)
  198124. +{
  198125. + struct brcmf_chip_priv *chip;
  198126. + struct brcmf_core *arm;
  198127. +
  198128. + brcmf_dbg(TRACE, "Enter\n");
  198129. +
  198130. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  198131. + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
  198132. + if (arm) {
  198133. + brcmf_chip_cr4_enterdl(chip);
  198134. + return;
  198135. + }
  198136. +
  198137. + brcmf_chip_cm3_enterdl(chip);
  198138. +}
  198139. +
  198140. +bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec)
  198141. +{
  198142. + struct brcmf_chip_priv *chip;
  198143. + struct brcmf_core *arm;
  198144. +
  198145. + brcmf_dbg(TRACE, "Enter\n");
  198146. +
  198147. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  198148. + arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
  198149. + if (arm)
  198150. + return brcmf_chip_cr4_exitdl(chip, rstvec);
  198151. +
  198152. + return brcmf_chip_cm3_exitdl(chip);
  198153. +}
  198154. +
  198155. +bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
  198156. +{
  198157. + u32 base, addr, reg, pmu_cc3_mask = ~0;
  198158. + struct brcmf_chip_priv *chip;
  198159. +
  198160. + brcmf_dbg(TRACE, "Enter\n");
  198161. +
  198162. + /* old chips with PMU version less than 17 don't support save restore */
  198163. + if (pub->pmurev < 17)
  198164. + return false;
  198165. +
  198166. + base = brcmf_chip_get_chipcommon(pub)->base;
  198167. + chip = container_of(pub, struct brcmf_chip_priv, pub);
  198168. +
  198169. + switch (pub->chip) {
  198170. + case BCM4354_CHIP_ID:
  198171. + /* explicitly check SR engine enable bit */
  198172. + pmu_cc3_mask = BIT(2);
  198173. + /* fall-through */
  198174. + case BCM43241_CHIP_ID:
  198175. + case BCM4335_CHIP_ID:
  198176. + case BCM4339_CHIP_ID:
  198177. + /* read PMU chipcontrol register 3 */
  198178. + addr = CORE_CC_REG(base, chipcontrol_addr);
  198179. + chip->ops->write32(chip->ctx, addr, 3);
  198180. + addr = CORE_CC_REG(base, chipcontrol_data);
  198181. + reg = chip->ops->read32(chip->ctx, addr);
  198182. + return (reg & pmu_cc3_mask) != 0;
  198183. + default:
  198184. + addr = CORE_CC_REG(base, pmucapabilities_ext);
  198185. + reg = chip->ops->read32(chip->ctx, addr);
  198186. + if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
  198187. + return false;
  198188. +
  198189. + addr = CORE_CC_REG(base, retention_ctl);
  198190. + reg = chip->ops->read32(chip->ctx, addr);
  198191. + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
  198192. + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
  198193. + }
  198194. +}
  198195. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/chip.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.h
  198196. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/chip.h 1970-01-01 01:00:00.000000000 +0100
  198197. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/chip.h 2014-09-11 18:06:03.902045566 +0200
  198198. @@ -0,0 +1,91 @@
  198199. +/*
  198200. + * Copyright (c) 2014 Broadcom Corporation
  198201. + *
  198202. + * Permission to use, copy, modify, and/or distribute this software for any
  198203. + * purpose with or without fee is hereby granted, provided that the above
  198204. + * copyright notice and this permission notice appear in all copies.
  198205. + *
  198206. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  198207. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  198208. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  198209. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  198210. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  198211. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  198212. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  198213. + */
  198214. +#ifndef BRCMF_CHIP_H
  198215. +#define BRCMF_CHIP_H
  198216. +
  198217. +#include <linux/types.h>
  198218. +
  198219. +#define CORE_CC_REG(base, field) \
  198220. + (base + offsetof(struct chipcregs, field))
  198221. +
  198222. +/**
  198223. + * struct brcmf_chip - chip level information.
  198224. + *
  198225. + * @chip: chip identifier.
  198226. + * @chiprev: chip revision.
  198227. + * @cc_caps: chipcommon core capabilities.
  198228. + * @pmucaps: PMU capabilities.
  198229. + * @pmurev: PMU revision.
  198230. + * @rambase: RAM base address (only applicable for ARM CR4 chips).
  198231. + * @ramsize: amount of RAM on chip.
  198232. + * @name: string representation of the chip identifier.
  198233. + */
  198234. +struct brcmf_chip {
  198235. + u32 chip;
  198236. + u32 chiprev;
  198237. + u32 cc_caps;
  198238. + u32 pmucaps;
  198239. + u32 pmurev;
  198240. + u32 rambase;
  198241. + u32 ramsize;
  198242. + char name[8];
  198243. +};
  198244. +
  198245. +/**
  198246. + * struct brcmf_core - core related information.
  198247. + *
  198248. + * @id: core identifier.
  198249. + * @rev: core revision.
  198250. + * @base: base address of core register space.
  198251. + */
  198252. +struct brcmf_core {
  198253. + u16 id;
  198254. + u16 rev;
  198255. + u32 base;
  198256. +};
  198257. +
  198258. +/**
  198259. + * struct brcmf_buscore_ops - buscore specific callbacks.
  198260. + *
  198261. + * @read32: read 32-bit value over bus.
  198262. + * @write32: write 32-bit value over bus.
  198263. + * @prepare: prepare bus for core configuration.
  198264. + * @setup: bus-specific core setup.
  198265. + * @exit_dl: exit download state.
  198266. + * The callback should use the provided @rstvec when non-zero.
  198267. + */
  198268. +struct brcmf_buscore_ops {
  198269. + u32 (*read32)(void *ctx, u32 addr);
  198270. + void (*write32)(void *ctx, u32 addr, u32 value);
  198271. + int (*prepare)(void *ctx);
  198272. + int (*setup)(void *ctx, struct brcmf_chip *chip);
  198273. + void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
  198274. +};
  198275. +
  198276. +struct brcmf_chip *brcmf_chip_attach(void *ctx,
  198277. + const struct brcmf_buscore_ops *ops);
  198278. +void brcmf_chip_detach(struct brcmf_chip *chip);
  198279. +struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
  198280. +struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
  198281. +bool brcmf_chip_iscoreup(struct brcmf_core *core);
  198282. +void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
  198283. +void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
  198284. + u32 postreset);
  198285. +void brcmf_chip_enter_download(struct brcmf_chip *ci);
  198286. +bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec);
  198287. +bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
  198288. +
  198289. +#endif /* BRCMF_AXIDMP_H */
  198290. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
  198291. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-08-14 03:38:34.000000000 +0200
  198292. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h 2014-09-11 18:06:03.902045566 +0200
  198293. @@ -63,7 +63,6 @@
  198294. */
  198295. struct brcmf_bus_ops {
  198296. int (*preinit)(struct device *dev);
  198297. - int (*init)(struct device *dev);
  198298. void (*stop)(struct device *dev);
  198299. int (*txdata)(struct device *dev, struct sk_buff *skb);
  198300. int (*txctl)(struct device *dev, unsigned char *msg, uint len);
  198301. @@ -99,6 +98,7 @@
  198302. unsigned long tx_realloc;
  198303. u32 chip;
  198304. u32 chiprev;
  198305. + bool always_use_fws_queue;
  198306. struct brcmf_bus_ops *ops;
  198307. };
  198308. @@ -113,11 +113,6 @@
  198309. return bus->ops->preinit(bus->dev);
  198310. }
  198311. -static inline int brcmf_bus_init(struct brcmf_bus *bus)
  198312. -{
  198313. - return bus->ops->init(bus->dev);
  198314. -}
  198315. -
  198316. static inline void brcmf_bus_stop(struct brcmf_bus *bus)
  198317. {
  198318. bus->ops->stop(bus->dev);
  198319. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
  198320. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c 2014-08-14 03:38:34.000000000 +0200
  198321. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c 2014-09-11 18:06:03.902045566 +0200
  198322. @@ -32,6 +32,9 @@
  198323. #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
  198324. #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
  198325. +/* boost value for RSSI_DELTA in preferred join selection */
  198326. +#define BRCMF_JOIN_PREF_RSSI_BOOST 8
  198327. +
  198328. bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
  198329. struct sk_buff *pkt, int prec)
  198330. @@ -246,6 +249,7 @@
  198331. {
  198332. s8 eventmask[BRCMF_EVENTING_MASK_LEN];
  198333. u8 buf[BRCMF_DCMD_SMLEN];
  198334. + struct brcmf_join_pref_params join_pref_params[2];
  198335. char *ptr;
  198336. s32 err;
  198337. @@ -298,6 +302,20 @@
  198338. goto done;
  198339. }
  198340. + /* Setup join_pref to select target by RSSI(with boost on 5GHz) */
  198341. + join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
  198342. + join_pref_params[0].len = 2;
  198343. + join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
  198344. + join_pref_params[0].band = WLC_BAND_5G;
  198345. + join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
  198346. + join_pref_params[1].len = 2;
  198347. + join_pref_params[1].rssi_gain = 0;
  198348. + join_pref_params[1].band = 0;
  198349. + err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
  198350. + sizeof(join_pref_params));
  198351. + if (err)
  198352. + brcmf_err("Set join_pref error (%d)\n", err);
  198353. +
  198354. /* Setup event_msgs, enable E_IF */
  198355. err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
  198356. BRCMF_EVENTING_MASK_LEN);
  198357. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
  198358. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd.h 2014-08-14 03:38:34.000000000 +0200
  198359. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd.h 2014-09-11 18:06:03.902045566 +0200
  198360. @@ -186,7 +186,7 @@
  198361. void brcmf_txflowblock_if(struct brcmf_if *ifp,
  198362. enum brcmf_netif_stop_reason reason, bool state);
  198363. u32 brcmf_get_chip_info(struct brcmf_if *ifp);
  198364. -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
  198365. +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
  198366. bool success);
  198367. /* Sets dongle media info (drv_version, mac address). */
  198368. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
  198369. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-08-14 03:38:34.000000000 +0200
  198370. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c 2014-09-11 18:06:03.902045566 +0200
  198371. @@ -190,7 +190,7 @@
  198372. int ret;
  198373. struct brcmf_if *ifp = netdev_priv(ndev);
  198374. struct brcmf_pub *drvr = ifp->drvr;
  198375. - struct ethhdr *eh;
  198376. + struct ethhdr *eh = (struct ethhdr *)(skb->data);
  198377. brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
  198378. @@ -236,6 +236,9 @@
  198379. goto done;
  198380. }
  198381. + if (eh->h_proto == htons(ETH_P_PAE))
  198382. + atomic_inc(&ifp->pend_8021x_cnt);
  198383. +
  198384. ret = brcmf_fws_process_skb(ifp, skb);
  198385. done:
  198386. @@ -538,31 +541,26 @@
  198387. brcmf_netif_rx(ifp, skb);
  198388. }
  198389. -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
  198390. +void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
  198391. bool success)
  198392. {
  198393. struct brcmf_if *ifp;
  198394. struct ethhdr *eh;
  198395. - u8 ifidx;
  198396. u16 type;
  198397. - int res;
  198398. -
  198399. - res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
  198400. ifp = drvr->iflist[ifidx];
  198401. if (!ifp)
  198402. goto done;
  198403. - if (res == 0) {
  198404. - eh = (struct ethhdr *)(txp->data);
  198405. - type = ntohs(eh->h_proto);
  198406. -
  198407. - if (type == ETH_P_PAE) {
  198408. - atomic_dec(&ifp->pend_8021x_cnt);
  198409. - if (waitqueue_active(&ifp->pend_8021x_wait))
  198410. - wake_up(&ifp->pend_8021x_wait);
  198411. - }
  198412. + eh = (struct ethhdr *)(txp->data);
  198413. + type = ntohs(eh->h_proto);
  198414. +
  198415. + if (type == ETH_P_PAE) {
  198416. + atomic_dec(&ifp->pend_8021x_cnt);
  198417. + if (waitqueue_active(&ifp->pend_8021x_wait))
  198418. + wake_up(&ifp->pend_8021x_wait);
  198419. }
  198420. +
  198421. if (!success)
  198422. ifp->stats.tx_errors++;
  198423. done:
  198424. @@ -573,13 +571,17 @@
  198425. {
  198426. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  198427. struct brcmf_pub *drvr = bus_if->drvr;
  198428. + u8 ifidx;
  198429. /* await txstatus signal for firmware if active */
  198430. if (brcmf_fws_fc_active(drvr->fws)) {
  198431. if (!success)
  198432. brcmf_fws_bustxfail(drvr->fws, txp);
  198433. } else {
  198434. - brcmf_txfinalize(drvr, txp, success);
  198435. + if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
  198436. + brcmu_pkt_buf_free_skb(txp);
  198437. + else
  198438. + brcmf_txfinalize(drvr, txp, ifidx, success);
  198439. }
  198440. }
  198441. @@ -914,13 +916,6 @@
  198442. brcmf_dbg(TRACE, "\n");
  198443. - /* Bring up the bus */
  198444. - ret = brcmf_bus_init(bus_if);
  198445. - if (ret != 0) {
  198446. - brcmf_err("brcmf_sdbrcm_bus_init failed %d\n", ret);
  198447. - return ret;
  198448. - }
  198449. -
  198450. /* add primary networking interface */
  198451. ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
  198452. if (IS_ERR(ifp))
  198453. @@ -1040,12 +1035,12 @@
  198454. brcmf_cfg80211_detach(drvr->config);
  198455. + brcmf_fws_deinit(drvr);
  198456. +
  198457. brcmf_bus_detach(drvr);
  198458. brcmf_proto_detach(drvr);
  198459. - brcmf_fws_deinit(drvr);
  198460. -
  198461. brcmf_debugfs_detach(drvr);
  198462. bus_if->drvr = NULL;
  198463. kfree(drvr);
  198464. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
  198465. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-08-14 03:38:34.000000000 +0200
  198466. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c 2014-09-11 18:06:03.906045582 +0200
  198467. @@ -23,6 +23,7 @@
  198468. #include <linux/interrupt.h>
  198469. #include <linux/sched.h>
  198470. #include <linux/mmc/sdio.h>
  198471. +#include <linux/mmc/sdio_ids.h>
  198472. #include <linux/mmc/sdio_func.h>
  198473. #include <linux/mmc/card.h>
  198474. #include <linux/semaphore.h>
  198475. @@ -40,8 +41,8 @@
  198476. #include <brcm_hw_ids.h>
  198477. #include <soc.h>
  198478. #include "sdio_host.h"
  198479. -#include "sdio_chip.h"
  198480. -#include "nvram.h"
  198481. +#include "chip.h"
  198482. +#include "firmware.h"
  198483. #define DCMD_RESP_TIMEOUT 2000 /* In milli second */
  198484. @@ -112,8 +113,6 @@
  198485. #define BRCMF_TXBOUND 20 /* Default for max tx frames in
  198486. one scheduling */
  198487. -#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
  198488. -
  198489. #define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
  198490. #define MEMBLOCK 2048 /* Block size used for downloading
  198491. @@ -156,6 +155,34 @@
  198492. /* manfid tuple length, include tuple, link bytes */
  198493. #define SBSDIO_CIS_MANFID_TUPLE_LEN 6
  198494. +#define CORE_BUS_REG(base, field) \
  198495. + (base + offsetof(struct sdpcmd_regs, field))
  198496. +
  198497. +/* SDIO function 1 register CHIPCLKCSR */
  198498. +/* Force ALP request to backplane */
  198499. +#define SBSDIO_FORCE_ALP 0x01
  198500. +/* Force HT request to backplane */
  198501. +#define SBSDIO_FORCE_HT 0x02
  198502. +/* Force ILP request to backplane */
  198503. +#define SBSDIO_FORCE_ILP 0x04
  198504. +/* Make ALP ready (power up xtal) */
  198505. +#define SBSDIO_ALP_AVAIL_REQ 0x08
  198506. +/* Make HT ready (power up PLL) */
  198507. +#define SBSDIO_HT_AVAIL_REQ 0x10
  198508. +/* Squelch clock requests from HW */
  198509. +#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
  198510. +/* Status: ALP is ready */
  198511. +#define SBSDIO_ALP_AVAIL 0x40
  198512. +/* Status: HT is ready */
  198513. +#define SBSDIO_HT_AVAIL 0x80
  198514. +#define SBSDIO_CSR_MASK 0x1F
  198515. +#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
  198516. +#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
  198517. +#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
  198518. +#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
  198519. +#define SBSDIO_CLKAV(regval, alponly) \
  198520. + (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
  198521. +
  198522. /* intstatus */
  198523. #define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */
  198524. #define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */
  198525. @@ -276,7 +303,6 @@
  198526. /* Flags for SDH calls */
  198527. #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
  198528. -#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
  198529. #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
  198530. * when idle
  198531. */
  198532. @@ -433,10 +459,11 @@
  198533. bool alp_only; /* Don't use HT clock (ALP only) */
  198534. u8 *ctrl_frame_buf;
  198535. - u32 ctrl_frame_len;
  198536. + u16 ctrl_frame_len;
  198537. bool ctrl_frame_stat;
  198538. - spinlock_t txqlock;
  198539. + spinlock_t txq_lock; /* protect bus->txq */
  198540. + struct semaphore tx_seq_lock; /* protect bus->tx_seq */
  198541. wait_queue_head_t ctrl_wait;
  198542. wait_queue_head_t dcmd_resp_wait;
  198543. @@ -483,16 +510,58 @@
  198544. #define ALIGNMENT 4
  198545. -static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
  198546. -module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
  198547. -MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
  198548. -
  198549. enum brcmf_sdio_frmtype {
  198550. BRCMF_SDIO_FT_NORMAL,
  198551. BRCMF_SDIO_FT_SUPER,
  198552. BRCMF_SDIO_FT_SUB,
  198553. };
  198554. +#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
  198555. +
  198556. +/* SDIO Pad drive strength to select value mappings */
  198557. +struct sdiod_drive_str {
  198558. + u8 strength; /* Pad Drive Strength in mA */
  198559. + u8 sel; /* Chip-specific select value */
  198560. +};
  198561. +
  198562. +/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
  198563. +static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
  198564. + {32, 0x6},
  198565. + {26, 0x7},
  198566. + {22, 0x4},
  198567. + {16, 0x5},
  198568. + {12, 0x2},
  198569. + {8, 0x3},
  198570. + {4, 0x0},
  198571. + {0, 0x1}
  198572. +};
  198573. +
  198574. +/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
  198575. +static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
  198576. + {6, 0x7},
  198577. + {5, 0x6},
  198578. + {4, 0x5},
  198579. + {3, 0x4},
  198580. + {2, 0x2},
  198581. + {1, 0x1},
  198582. + {0, 0x0}
  198583. +};
  198584. +
  198585. +/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
  198586. +static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
  198587. + {3, 0x3},
  198588. + {2, 0x2},
  198589. + {1, 0x1},
  198590. + {0, 0x0} };
  198591. +
  198592. +/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
  198593. +static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
  198594. + {16, 0x7},
  198595. + {12, 0x5},
  198596. + {8, 0x3},
  198597. + {4, 0x1}
  198598. +};
  198599. +
  198600. #define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin"
  198601. #define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt"
  198602. #define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin"
  198603. @@ -511,6 +580,8 @@
  198604. #define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"
  198605. #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
  198606. #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
  198607. +#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin"
  198608. +#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt"
  198609. MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
  198610. MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
  198611. @@ -530,6 +601,8 @@
  198612. MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
  198613. MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
  198614. MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
  198615. +MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
  198616. +MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
  198617. struct brcmf_firmware_names {
  198618. u32 chipid;
  198619. @@ -555,46 +628,32 @@
  198620. { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
  198621. { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
  198622. { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
  198623. - { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }
  198624. + { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
  198625. + { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
  198626. };
  198627. -
  198628. -static const struct firmware *brcmf_sdio_get_fw(struct brcmf_sdio *bus,
  198629. - enum brcmf_firmware_type type)
  198630. +static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci,
  198631. + enum brcmf_firmware_type type)
  198632. {
  198633. - const struct firmware *fw;
  198634. - const char *name;
  198635. - int err, i;
  198636. + int i;
  198637. for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
  198638. - if (brcmf_fwname_data[i].chipid == bus->ci->chip &&
  198639. - brcmf_fwname_data[i].revmsk & BIT(bus->ci->chiprev)) {
  198640. + if (brcmf_fwname_data[i].chipid == ci->chip &&
  198641. + brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) {
  198642. switch (type) {
  198643. case BRCMF_FIRMWARE_BIN:
  198644. - name = brcmf_fwname_data[i].bin;
  198645. - break;
  198646. + return brcmf_fwname_data[i].bin;
  198647. case BRCMF_FIRMWARE_NVRAM:
  198648. - name = brcmf_fwname_data[i].nv;
  198649. - break;
  198650. + return brcmf_fwname_data[i].nv;
  198651. default:
  198652. brcmf_err("invalid firmware type (%d)\n", type);
  198653. return NULL;
  198654. }
  198655. - goto found;
  198656. }
  198657. }
  198658. brcmf_err("Unknown chipid %d [%d]\n",
  198659. - bus->ci->chip, bus->ci->chiprev);
  198660. + ci->chip, ci->chiprev);
  198661. return NULL;
  198662. -
  198663. -found:
  198664. - err = request_firmware(&fw, name, &bus->sdiodev->func[2]->dev);
  198665. - if ((err) || (!fw)) {
  198666. - brcmf_err("fail to request firmware %s (%d)\n", name, err);
  198667. - return NULL;
  198668. - }
  198669. -
  198670. - return fw;
  198671. }
  198672. static void pkt_align(struct sk_buff *p, int len, int align)
  198673. @@ -618,27 +677,24 @@
  198674. * Reads a register in the SDIO hardware block. This block occupies a series of
  198675. * adresses on the 32 bit backplane bus.
  198676. */
  198677. -static int
  198678. -r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
  198679. +static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
  198680. {
  198681. - u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  198682. + struct brcmf_core *core;
  198683. int ret;
  198684. - *regvar = brcmf_sdiod_regrl(bus->sdiodev,
  198685. - bus->ci->c_inf[idx].base + offset, &ret);
  198686. + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  198687. + *regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret);
  198688. return ret;
  198689. }
  198690. -static int
  198691. -w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
  198692. +static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
  198693. {
  198694. - u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  198695. + struct brcmf_core *core;
  198696. int ret;
  198697. - brcmf_sdiod_regwl(bus->sdiodev,
  198698. - bus->ci->c_inf[idx].base + reg_offset,
  198699. - regval, &ret);
  198700. + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  198701. + brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret);
  198702. return ret;
  198703. }
  198704. @@ -650,16 +706,12 @@
  198705. int err = 0;
  198706. int try_cnt = 0;
  198707. - brcmf_dbg(TRACE, "Enter\n");
  198708. + brcmf_dbg(TRACE, "Enter: on=%d\n", on);
  198709. wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
  198710. /* 1st KSO write goes to AOS wake up core if device is asleep */
  198711. brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
  198712. wr_val, &err);
  198713. - if (err) {
  198714. - brcmf_err("SDIO_AOS KSO write error: %d\n", err);
  198715. - return err;
  198716. - }
  198717. if (on) {
  198718. /* device WAKEUP through KSO:
  198719. @@ -689,18 +741,22 @@
  198720. &err);
  198721. if (((rd_val & bmask) == cmp_val) && !err)
  198722. break;
  198723. - brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n",
  198724. - try_cnt, MAX_KSO_ATTEMPTS, err);
  198725. +
  198726. udelay(KSO_WAIT_US);
  198727. brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
  198728. wr_val, &err);
  198729. } while (try_cnt++ < MAX_KSO_ATTEMPTS);
  198730. + if (try_cnt > 2)
  198731. + brcmf_dbg(SDIO, "try_cnt=%d rd_val=0x%x err=%d\n", try_cnt,
  198732. + rd_val, err);
  198733. +
  198734. + if (try_cnt > MAX_KSO_ATTEMPTS)
  198735. + brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err);
  198736. +
  198737. return err;
  198738. }
  198739. -#define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
  198740. -
  198741. #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
  198742. /* Turn backplane clock on or off */
  198743. @@ -799,7 +855,6 @@
  198744. }
  198745. #endif /* defined (DEBUG) */
  198746. - bus->activity = true;
  198747. } else {
  198748. clkreq = 0;
  198749. @@ -899,8 +954,9 @@
  198750. brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
  198751. {
  198752. int err = 0;
  198753. - brcmf_dbg(TRACE, "Enter\n");
  198754. - brcmf_dbg(SDIO, "request %s currently %s\n",
  198755. + u8 clkcsr;
  198756. +
  198757. + brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
  198758. (sleep ? "SLEEP" : "WAKE"),
  198759. (bus->sleeping ? "SLEEP" : "WAKE"));
  198760. @@ -917,8 +973,20 @@
  198761. atomic_read(&bus->ipend) > 0 ||
  198762. (!atomic_read(&bus->fcstate) &&
  198763. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
  198764. - data_ok(bus)))
  198765. - return -EBUSY;
  198766. + data_ok(bus))) {
  198767. + err = -EBUSY;
  198768. + goto done;
  198769. + }
  198770. +
  198771. + clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
  198772. + SBSDIO_FUNC1_CHIPCLKCSR,
  198773. + &err);
  198774. + if ((clkcsr & SBSDIO_CSR_MASK) == 0) {
  198775. + brcmf_dbg(SDIO, "no clock, set ALP\n");
  198776. + brcmf_sdiod_regwb(bus->sdiodev,
  198777. + SBSDIO_FUNC1_CHIPCLKCSR,
  198778. + SBSDIO_ALP_AVAIL_REQ, &err);
  198779. + }
  198780. err = brcmf_sdio_kso_control(bus, false);
  198781. /* disable watchdog */
  198782. if (!err)
  198783. @@ -935,7 +1003,7 @@
  198784. } else {
  198785. brcmf_err("error while changing bus sleep state %d\n",
  198786. err);
  198787. - return err;
  198788. + goto done;
  198789. }
  198790. }
  198791. @@ -947,11 +1015,92 @@
  198792. } else {
  198793. brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
  198794. }
  198795. -
  198796. +done:
  198797. + brcmf_dbg(SDIO, "Exit: err=%d\n", err);
  198798. return err;
  198799. }
  198800. +#ifdef DEBUG
  198801. +static inline bool brcmf_sdio_valid_shared_address(u32 addr)
  198802. +{
  198803. + return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
  198804. +}
  198805. +
  198806. +static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
  198807. + struct sdpcm_shared *sh)
  198808. +{
  198809. + u32 addr;
  198810. + int rv;
  198811. + u32 shaddr = 0;
  198812. + struct sdpcm_shared_le sh_le;
  198813. + __le32 addr_le;
  198814. +
  198815. + shaddr = bus->ci->rambase + bus->ramsize - 4;
  198816. +
  198817. + /*
  198818. + * Read last word in socram to determine
  198819. + * address of sdpcm_shared structure
  198820. + */
  198821. + sdio_claim_host(bus->sdiodev->func[1]);
  198822. + brcmf_sdio_bus_sleep(bus, false, false);
  198823. + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
  198824. + sdio_release_host(bus->sdiodev->func[1]);
  198825. + if (rv < 0)
  198826. + return rv;
  198827. +
  198828. + addr = le32_to_cpu(addr_le);
  198829. +
  198830. + brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
  198831. +
  198832. + /*
  198833. + * Check if addr is valid.
  198834. + * NVRAM length at the end of memory should have been overwritten.
  198835. + */
  198836. + if (!brcmf_sdio_valid_shared_address(addr)) {
  198837. + brcmf_err("invalid sdpcm_shared address 0x%08X\n",
  198838. + addr);
  198839. + return -EINVAL;
  198840. + }
  198841. +
  198842. + /* Read hndrte_shared structure */
  198843. + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
  198844. + sizeof(struct sdpcm_shared_le));
  198845. + if (rv < 0)
  198846. + return rv;
  198847. +
  198848. + /* Endianness */
  198849. + sh->flags = le32_to_cpu(sh_le.flags);
  198850. + sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
  198851. + sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
  198852. + sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
  198853. + sh->assert_line = le32_to_cpu(sh_le.assert_line);
  198854. + sh->console_addr = le32_to_cpu(sh_le.console_addr);
  198855. + sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
  198856. +
  198857. + if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
  198858. + brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
  198859. + SDPCM_SHARED_VERSION,
  198860. + sh->flags & SDPCM_SHARED_VERSION_MASK);
  198861. + return -EPROTO;
  198862. + }
  198863. +
  198864. + return 0;
  198865. +}
  198866. +
  198867. +static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
  198868. +{
  198869. + struct sdpcm_shared sh;
  198870. +
  198871. + if (brcmf_sdio_readshared(bus, &sh) == 0)
  198872. + bus->console_addr = sh.console_addr;
  198873. +}
  198874. +#else
  198875. +static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
  198876. +{
  198877. +}
  198878. +#endif /* DEBUG */
  198879. +
  198880. static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus)
  198881. {
  198882. u32 intstatus = 0;
  198883. @@ -995,6 +1144,12 @@
  198884. else
  198885. brcmf_dbg(SDIO, "Dongle ready, protocol version %d\n",
  198886. bus->sdpcm_ver);
  198887. +
  198888. + /*
  198889. + * Retrieve console state address now that firmware should have
  198890. + * updated it.
  198891. + */
  198892. + brcmf_sdio_get_console_addr(bus);
  198893. }
  198894. /*
  198895. @@ -1083,6 +1238,28 @@
  198896. bus->cur_read.len = 0;
  198897. }
  198898. +static void brcmf_sdio_txfail(struct brcmf_sdio *bus)
  198899. +{
  198900. + struct brcmf_sdio_dev *sdiodev = bus->sdiodev;
  198901. + u8 i, hi, lo;
  198902. +
  198903. + /* On failure, abort the command and terminate the frame */
  198904. + brcmf_err("sdio error, abort command and terminate frame\n");
  198905. + bus->sdcnt.tx_sderrs++;
  198906. +
  198907. + brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2);
  198908. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL);
  198909. + bus->sdcnt.f1regdata++;
  198910. +
  198911. + for (i = 0; i < 3; i++) {
  198912. + hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  198913. + lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  198914. + bus->sdcnt.f1regdata += 2;
  198915. + if ((hi == 0) && (lo == 0))
  198916. + break;
  198917. + }
  198918. +}
  198919. +
  198920. /* return total length of buffer chain */
  198921. static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus)
  198922. {
  198923. @@ -1955,7 +2132,7 @@
  198924. memcpy(pkt_pad->data,
  198925. pkt->data + pkt->len - tail_chop,
  198926. tail_chop);
  198927. - *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
  198928. + *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
  198929. skb_trim(pkt, pkt->len - tail_chop);
  198930. skb_trim(pkt_pad, tail_pad + tail_chop);
  198931. __skb_queue_after(pktq, pkt, pkt_pad);
  198932. @@ -2003,7 +2180,7 @@
  198933. * already properly aligned and does not
  198934. * need an sdpcm header.
  198935. */
  198936. - if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
  198937. + if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
  198938. continue;
  198939. /* align packet data pointer */
  198940. @@ -2037,10 +2214,10 @@
  198941. if (BRCMF_BYTES_ON() &&
  198942. ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
  198943. (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
  198944. - brcmf_dbg_hex_dump(true, pkt_next, hd_info.len,
  198945. + brcmf_dbg_hex_dump(true, pkt_next->data, hd_info.len,
  198946. "Tx Frame:\n");
  198947. else if (BRCMF_HDRS_ON())
  198948. - brcmf_dbg_hex_dump(true, pkt_next,
  198949. + brcmf_dbg_hex_dump(true, pkt_next->data,
  198950. head_pad + bus->tx_hdrlen,
  198951. "Tx Header:\n");
  198952. }
  198953. @@ -2067,11 +2244,11 @@
  198954. u8 *hdr;
  198955. u32 dat_offset;
  198956. u16 tail_pad;
  198957. - u32 dummy_flags, chop_len;
  198958. + u16 dummy_flags, chop_len;
  198959. struct sk_buff *pkt_next, *tmp, *pkt_prev;
  198960. skb_queue_walk_safe(pktq, pkt_next, tmp) {
  198961. - dummy_flags = *(u32 *)(pkt_next->cb);
  198962. + dummy_flags = *(u16 *)(pkt_next->cb);
  198963. if (dummy_flags & ALIGN_SKB_FLAG) {
  198964. chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
  198965. if (chop_len) {
  198966. @@ -2100,7 +2277,6 @@
  198967. uint chan)
  198968. {
  198969. int ret;
  198970. - int i;
  198971. struct sk_buff *pkt_next, *tmp;
  198972. brcmf_dbg(TRACE, "Enter\n");
  198973. @@ -2113,28 +2289,9 @@
  198974. ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq);
  198975. bus->sdcnt.f2txdata++;
  198976. - if (ret < 0) {
  198977. - /* On failure, abort the command and terminate the frame */
  198978. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  198979. - ret);
  198980. - bus->sdcnt.tx_sderrs++;
  198981. + if (ret < 0)
  198982. + brcmf_sdio_txfail(bus);
  198983. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  198984. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  198985. - SFC_WF_TERM, NULL);
  198986. - bus->sdcnt.f1regdata++;
  198987. -
  198988. - for (i = 0; i < 3; i++) {
  198989. - u8 hi, lo;
  198990. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  198991. - SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  198992. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  198993. - SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  198994. - bus->sdcnt.f1regdata += 2;
  198995. - if ((hi == 0) && (lo == 0))
  198996. - break;
  198997. - }
  198998. - }
  198999. sdio_release_host(bus->sdiodev->func[1]);
  199000. done:
  199001. @@ -2164,13 +2321,15 @@
  199002. /* Send frames until the limit or some other event */
  199003. for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
  199004. pkt_num = 1;
  199005. - __skb_queue_head_init(&pktq);
  199006. + if (down_interruptible(&bus->tx_seq_lock))
  199007. + return cnt;
  199008. if (bus->txglom)
  199009. pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
  199010. - brcmf_sdio_txglomsz);
  199011. + bus->sdiodev->txglomsz);
  199012. pkt_num = min_t(u32, pkt_num,
  199013. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
  199014. - spin_lock_bh(&bus->txqlock);
  199015. + __skb_queue_head_init(&pktq);
  199016. + spin_lock_bh(&bus->txq_lock);
  199017. for (i = 0; i < pkt_num; i++) {
  199018. pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
  199019. &prec_out);
  199020. @@ -2178,15 +2337,19 @@
  199021. break;
  199022. __skb_queue_tail(&pktq, pkt);
  199023. }
  199024. - spin_unlock_bh(&bus->txqlock);
  199025. - if (i == 0)
  199026. + spin_unlock_bh(&bus->txq_lock);
  199027. + if (i == 0) {
  199028. + up(&bus->tx_seq_lock);
  199029. break;
  199030. + }
  199031. ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
  199032. + up(&bus->tx_seq_lock);
  199033. +
  199034. cnt += i;
  199035. /* In poll mode, need to check for other events */
  199036. - if (!bus->intr && cnt) {
  199037. + if (!bus->intr) {
  199038. /* Check device status, signal pending interrupt */
  199039. sdio_claim_host(bus->sdiodev->func[1]);
  199040. ret = r_sdreg32(bus, &intstatus,
  199041. @@ -2211,6 +2374,68 @@
  199042. return cnt;
  199043. }
  199044. +static int brcmf_sdio_tx_ctrlframe(struct brcmf_sdio *bus, u8 *frame, u16 len)
  199045. +{
  199046. + u8 doff;
  199047. + u16 pad;
  199048. + uint retries = 0;
  199049. + struct brcmf_sdio_hdrinfo hd_info = {0};
  199050. + int ret;
  199051. +
  199052. + brcmf_dbg(TRACE, "Enter\n");
  199053. +
  199054. + /* Back the pointer to make room for bus header */
  199055. + frame -= bus->tx_hdrlen;
  199056. + len += bus->tx_hdrlen;
  199057. +
  199058. + /* Add alignment padding (optional for ctl frames) */
  199059. + doff = ((unsigned long)frame % bus->head_align);
  199060. + if (doff) {
  199061. + frame -= doff;
  199062. + len += doff;
  199063. + memset(frame + bus->tx_hdrlen, 0, doff);
  199064. + }
  199065. +
  199066. + /* Round send length to next SDIO block */
  199067. + pad = 0;
  199068. + if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
  199069. + pad = bus->blocksize - (len % bus->blocksize);
  199070. + if ((pad > bus->roundup) || (pad >= bus->blocksize))
  199071. + pad = 0;
  199072. + } else if (len % bus->head_align) {
  199073. + pad = bus->head_align - (len % bus->head_align);
  199074. + }
  199075. + len += pad;
  199076. +
  199077. + hd_info.len = len - pad;
  199078. + hd_info.channel = SDPCM_CONTROL_CHANNEL;
  199079. + hd_info.dat_offset = doff + bus->tx_hdrlen;
  199080. + hd_info.seq_num = bus->tx_seq;
  199081. + hd_info.lastfrm = true;
  199082. + hd_info.tail_pad = pad;
  199083. + brcmf_sdio_hdpack(bus, frame, &hd_info);
  199084. +
  199085. + if (bus->txglom)
  199086. + brcmf_sdio_update_hwhdr(frame, len);
  199087. +
  199088. + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
  199089. + frame, len, "Tx Frame:\n");
  199090. + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
  199091. + BRCMF_HDRS_ON(),
  199092. + frame, min_t(u16, len, 16), "TxHdr:\n");
  199093. +
  199094. + do {
  199095. + ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
  199096. +
  199097. + if (ret < 0)
  199098. + brcmf_sdio_txfail(bus);
  199099. + else
  199100. + bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  199101. + } while (ret < 0 && retries++ < TXRETRIES);
  199102. +
  199103. + return ret;
  199104. +}
  199105. +
  199106. static void brcmf_sdio_bus_stop(struct device *dev)
  199107. {
  199108. u32 local_hostintmask;
  199109. @@ -2292,21 +2517,29 @@
  199110. }
  199111. }
  199112. +static void atomic_orr(int val, atomic_t *v)
  199113. +{
  199114. + int old_val;
  199115. +
  199116. + old_val = atomic_read(v);
  199117. + while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
  199118. + old_val = atomic_read(v);
  199119. +}
  199120. +
  199121. static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
  199122. {
  199123. - u8 idx;
  199124. + struct brcmf_core *buscore;
  199125. u32 addr;
  199126. unsigned long val;
  199127. - int n, ret;
  199128. + int ret;
  199129. - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  199130. - addr = bus->ci->c_inf[idx].base +
  199131. - offsetof(struct sdpcmd_regs, intstatus);
  199132. + buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV);
  199133. + addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus);
  199134. val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret);
  199135. bus->sdcnt.f1regdata++;
  199136. if (ret != 0)
  199137. - val = 0;
  199138. + return ret;
  199139. val &= bus->hostintmask;
  199140. atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
  199141. @@ -2315,13 +2548,7 @@
  199142. if (val) {
  199143. brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
  199144. bus->sdcnt.f1regdata++;
  199145. - }
  199146. -
  199147. - if (ret) {
  199148. - atomic_set(&bus->intstatus, 0);
  199149. - } else if (val) {
  199150. - for_each_set_bit(n, &val, 32)
  199151. - set_bit(n, (unsigned long *)&bus->intstatus.counter);
  199152. + atomic_orr(val, &bus->intstatus);
  199153. }
  199154. return ret;
  199155. @@ -2331,10 +2558,9 @@
  199156. {
  199157. u32 newstatus = 0;
  199158. unsigned long intstatus;
  199159. - uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
  199160. uint txlimit = bus->txbound; /* Tx frames to send before resched */
  199161. - uint framecnt = 0; /* Temporary counter of tx/rx frames */
  199162. - int err = 0, n;
  199163. + uint framecnt; /* Temporary counter of tx/rx frames */
  199164. + int err = 0;
  199165. brcmf_dbg(TRACE, "Enter\n");
  199166. @@ -2431,70 +2657,38 @@
  199167. intstatus &= ~I_HMB_FRAME_IND;
  199168. /* On frame indication, read available frames */
  199169. - if (PKT_AVAILABLE() && bus->clkstate == CLK_AVAIL) {
  199170. - framecnt = brcmf_sdio_readframes(bus, rxlimit);
  199171. + if ((intstatus & I_HMB_FRAME_IND) && (bus->clkstate == CLK_AVAIL)) {
  199172. + brcmf_sdio_readframes(bus, bus->rxbound);
  199173. if (!bus->rxpending)
  199174. intstatus &= ~I_HMB_FRAME_IND;
  199175. - rxlimit -= min(framecnt, rxlimit);
  199176. }
  199177. /* Keep still-pending events for next scheduling */
  199178. - if (intstatus) {
  199179. - for_each_set_bit(n, &intstatus, 32)
  199180. - set_bit(n, (unsigned long *)&bus->intstatus.counter);
  199181. - }
  199182. + if (intstatus)
  199183. + atomic_orr(intstatus, &bus->intstatus);
  199184. brcmf_sdio_clrintr(bus);
  199185. - if (data_ok(bus) && bus->ctrl_frame_stat &&
  199186. - (bus->clkstate == CLK_AVAIL)) {
  199187. - int i;
  199188. -
  199189. - sdio_claim_host(bus->sdiodev->func[1]);
  199190. - err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf,
  199191. - (u32)bus->ctrl_frame_len);
  199192. -
  199193. - if (err < 0) {
  199194. - /* On failure, abort the command and
  199195. - terminate the frame */
  199196. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  199197. - err);
  199198. - bus->sdcnt.tx_sderrs++;
  199199. -
  199200. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  199201. -
  199202. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  199203. - SFC_WF_TERM, &err);
  199204. - bus->sdcnt.f1regdata++;
  199205. -
  199206. - for (i = 0; i < 3; i++) {
  199207. - u8 hi, lo;
  199208. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  199209. - SBSDIO_FUNC1_WFRAMEBCHI,
  199210. - &err);
  199211. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  199212. - SBSDIO_FUNC1_WFRAMEBCLO,
  199213. - &err);
  199214. - bus->sdcnt.f1regdata += 2;
  199215. - if ((hi == 0) && (lo == 0))
  199216. - break;
  199217. - }
  199218. + if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
  199219. + (down_interruptible(&bus->tx_seq_lock) == 0)) {
  199220. + if (data_ok(bus)) {
  199221. + sdio_claim_host(bus->sdiodev->func[1]);
  199222. + err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
  199223. + bus->ctrl_frame_len);
  199224. + sdio_release_host(bus->sdiodev->func[1]);
  199225. - } else {
  199226. - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  199227. + bus->ctrl_frame_stat = false;
  199228. + brcmf_sdio_wait_event_wakeup(bus);
  199229. }
  199230. - sdio_release_host(bus->sdiodev->func[1]);
  199231. - bus->ctrl_frame_stat = false;
  199232. - brcmf_sdio_wait_event_wakeup(bus);
  199233. + up(&bus->tx_seq_lock);
  199234. }
  199235. /* Send queued frames (limit 1 if rx may still be pending) */
  199236. - else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
  199237. - brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
  199238. - && data_ok(bus)) {
  199239. + if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
  199240. + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit &&
  199241. + data_ok(bus)) {
  199242. framecnt = bus->rxpending ? min(txlimit, bus->txminmax) :
  199243. txlimit;
  199244. - framecnt = brcmf_sdio_sendfromq(bus, framecnt);
  199245. - txlimit -= framecnt;
  199246. + brcmf_sdio_sendfromq(bus, framecnt);
  199247. }
  199248. if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {
  199249. @@ -2504,19 +2698,9 @@
  199250. atomic_read(&bus->ipend) > 0 ||
  199251. (!atomic_read(&bus->fcstate) &&
  199252. brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
  199253. - data_ok(bus)) || PKT_AVAILABLE()) {
  199254. + data_ok(bus))) {
  199255. atomic_inc(&bus->dpc_tskcnt);
  199256. }
  199257. -
  199258. - /* If we're done for now, turn off clock request. */
  199259. - if ((bus->clkstate != CLK_PENDING)
  199260. - && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
  199261. - bus->activity = false;
  199262. - brcmf_dbg(SDIO, "idle state\n");
  199263. - sdio_claim_host(bus->sdiodev->func[1]);
  199264. - brcmf_sdio_bus_sleep(bus, true, false);
  199265. - sdio_release_host(bus->sdiodev->func[1]);
  199266. - }
  199267. }
  199268. static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev)
  199269. @@ -2531,15 +2715,12 @@
  199270. static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
  199271. {
  199272. int ret = -EBADE;
  199273. - uint datalen, prec;
  199274. + uint prec;
  199275. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  199276. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  199277. struct brcmf_sdio *bus = sdiodev->bus;
  199278. - ulong flags;
  199279. -
  199280. - brcmf_dbg(TRACE, "Enter\n");
  199281. - datalen = pkt->len;
  199282. + brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len);
  199283. /* Add space for the header */
  199284. skb_push(pkt, bus->tx_hdrlen);
  199285. @@ -2553,7 +2734,9 @@
  199286. bus->sdcnt.fcqueued++;
  199287. /* Priority based enq */
  199288. - spin_lock_irqsave(&bus->txqlock, flags);
  199289. + spin_lock_bh(&bus->txq_lock);
  199290. + /* reset bus_flags in packet cb */
  199291. + *(u16 *)(pkt->cb) = 0;
  199292. if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
  199293. skb_pull(pkt, bus->tx_hdrlen);
  199294. brcmf_err("out of bus->txq !!!\n");
  199295. @@ -2566,7 +2749,7 @@
  199296. bus->txoff = true;
  199297. brcmf_txflowblock(bus->sdiodev->dev, true);
  199298. }
  199299. - spin_unlock_irqrestore(&bus->txqlock, flags);
  199300. + spin_unlock_bh(&bus->txq_lock);
  199301. #ifdef DEBUG
  199302. if (pktq_plen(&bus->txq, prec) > qcount[prec])
  199303. @@ -2661,110 +2844,27 @@
  199304. }
  199305. #endif /* DEBUG */
  199306. -static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
  199307. -{
  199308. - int i;
  199309. - int ret;
  199310. -
  199311. - bus->ctrl_frame_stat = false;
  199312. - ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len);
  199313. -
  199314. - if (ret < 0) {
  199315. - /* On failure, abort the command and terminate the frame */
  199316. - brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
  199317. - ret);
  199318. - bus->sdcnt.tx_sderrs++;
  199319. -
  199320. - brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2);
  199321. -
  199322. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
  199323. - SFC_WF_TERM, NULL);
  199324. - bus->sdcnt.f1regdata++;
  199325. -
  199326. - for (i = 0; i < 3; i++) {
  199327. - u8 hi, lo;
  199328. - hi = brcmf_sdiod_regrb(bus->sdiodev,
  199329. - SBSDIO_FUNC1_WFRAMEBCHI, NULL);
  199330. - lo = brcmf_sdiod_regrb(bus->sdiodev,
  199331. - SBSDIO_FUNC1_WFRAMEBCLO, NULL);
  199332. - bus->sdcnt.f1regdata += 2;
  199333. - if (hi == 0 && lo == 0)
  199334. - break;
  199335. - }
  199336. - return ret;
  199337. - }
  199338. -
  199339. - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
  199340. -
  199341. - return ret;
  199342. -}
  199343. -
  199344. static int
  199345. brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
  199346. {
  199347. - u8 *frame;
  199348. - u16 len, pad;
  199349. - uint retries = 0;
  199350. - u8 doff = 0;
  199351. - int ret = -1;
  199352. struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  199353. struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  199354. struct brcmf_sdio *bus = sdiodev->bus;
  199355. - struct brcmf_sdio_hdrinfo hd_info = {0};
  199356. + int ret = -1;
  199357. brcmf_dbg(TRACE, "Enter\n");
  199358. - /* Back the pointer to make a room for bus header */
  199359. - frame = msg - bus->tx_hdrlen;
  199360. - len = (msglen += bus->tx_hdrlen);
  199361. + if (down_interruptible(&bus->tx_seq_lock))
  199362. + return -EINTR;
  199363. - /* Add alignment padding (optional for ctl frames) */
  199364. - doff = ((unsigned long)frame % bus->head_align);
  199365. - if (doff) {
  199366. - frame -= doff;
  199367. - len += doff;
  199368. - msglen += doff;
  199369. - memset(frame, 0, doff + bus->tx_hdrlen);
  199370. - }
  199371. - /* precondition: doff < bus->head_align */
  199372. - doff += bus->tx_hdrlen;
  199373. -
  199374. - /* Round send length to next SDIO block */
  199375. - pad = 0;
  199376. - if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
  199377. - pad = bus->blocksize - (len % bus->blocksize);
  199378. - if ((pad > bus->roundup) || (pad >= bus->blocksize))
  199379. - pad = 0;
  199380. - } else if (len % bus->head_align) {
  199381. - pad = bus->head_align - (len % bus->head_align);
  199382. - }
  199383. - len += pad;
  199384. -
  199385. - /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
  199386. -
  199387. - /* Make sure backplane clock is on */
  199388. - sdio_claim_host(bus->sdiodev->func[1]);
  199389. - brcmf_sdio_bus_sleep(bus, false, false);
  199390. - sdio_release_host(bus->sdiodev->func[1]);
  199391. -
  199392. - hd_info.len = (u16)msglen;
  199393. - hd_info.channel = SDPCM_CONTROL_CHANNEL;
  199394. - hd_info.dat_offset = doff;
  199395. - hd_info.seq_num = bus->tx_seq;
  199396. - hd_info.lastfrm = true;
  199397. - hd_info.tail_pad = pad;
  199398. - brcmf_sdio_hdpack(bus, frame, &hd_info);
  199399. -
  199400. - if (bus->txglom)
  199401. - brcmf_sdio_update_hwhdr(frame, len);
  199402. -
  199403. - if (!data_ok(bus)) {
  199404. - brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
  199405. - bus->tx_max, bus->tx_seq);
  199406. - bus->ctrl_frame_stat = true;
  199407. - /* Send from dpc */
  199408. - bus->ctrl_frame_buf = frame;
  199409. - bus->ctrl_frame_len = len;
  199410. + if (!data_ok(bus)) {
  199411. + brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
  199412. + bus->tx_max, bus->tx_seq);
  199413. + up(&bus->tx_seq_lock);
  199414. + /* Send from dpc */
  199415. + bus->ctrl_frame_buf = msg;
  199416. + bus->ctrl_frame_len = msglen;
  199417. + bus->ctrl_frame_stat = true;
  199418. wait_event_interruptible_timeout(bus->ctrl_wait,
  199419. !bus->ctrl_frame_stat,
  199420. @@ -2775,31 +2875,18 @@
  199421. ret = 0;
  199422. } else {
  199423. brcmf_dbg(SDIO, "ctrl_frame_stat == true\n");
  199424. + bus->ctrl_frame_stat = false;
  199425. + if (down_interruptible(&bus->tx_seq_lock))
  199426. + return -EINTR;
  199427. ret = -1;
  199428. }
  199429. }
  199430. -
  199431. if (ret == -1) {
  199432. - brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
  199433. - frame, len, "Tx Frame:\n");
  199434. - brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
  199435. - BRCMF_HDRS_ON(),
  199436. - frame, min_t(u16, len, 16), "TxHdr:\n");
  199437. -
  199438. - do {
  199439. - sdio_claim_host(bus->sdiodev->func[1]);
  199440. - ret = brcmf_sdio_tx_frame(bus, frame, len);
  199441. - sdio_release_host(bus->sdiodev->func[1]);
  199442. - } while (ret < 0 && retries++ < TXRETRIES);
  199443. - }
  199444. -
  199445. - if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
  199446. - atomic_read(&bus->dpc_tskcnt) == 0) {
  199447. - bus->activity = false;
  199448. sdio_claim_host(bus->sdiodev->func[1]);
  199449. - brcmf_dbg(INFO, "idle\n");
  199450. - brcmf_sdio_clkctl(bus, CLK_NONE, true);
  199451. + brcmf_sdio_bus_sleep(bus, false, false);
  199452. + ret = brcmf_sdio_tx_ctrlframe(bus, msg, msglen);
  199453. sdio_release_host(bus->sdiodev->func[1]);
  199454. + up(&bus->tx_seq_lock);
  199455. }
  199456. if (ret)
  199457. @@ -2811,72 +2898,6 @@
  199458. }
  199459. #ifdef DEBUG
  199460. -static inline bool brcmf_sdio_valid_shared_address(u32 addr)
  199461. -{
  199462. - return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
  199463. -}
  199464. -
  199465. -static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
  199466. - struct sdpcm_shared *sh)
  199467. -{
  199468. - u32 addr;
  199469. - int rv;
  199470. - u32 shaddr = 0;
  199471. - struct sdpcm_shared_le sh_le;
  199472. - __le32 addr_le;
  199473. -
  199474. - shaddr = bus->ci->rambase + bus->ramsize - 4;
  199475. -
  199476. - /*
  199477. - * Read last word in socram to determine
  199478. - * address of sdpcm_shared structure
  199479. - */
  199480. - sdio_claim_host(bus->sdiodev->func[1]);
  199481. - brcmf_sdio_bus_sleep(bus, false, false);
  199482. - rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
  199483. - sdio_release_host(bus->sdiodev->func[1]);
  199484. - if (rv < 0)
  199485. - return rv;
  199486. -
  199487. - addr = le32_to_cpu(addr_le);
  199488. -
  199489. - brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
  199490. -
  199491. - /*
  199492. - * Check if addr is valid.
  199493. - * NVRAM length at the end of memory should have been overwritten.
  199494. - */
  199495. - if (!brcmf_sdio_valid_shared_address(addr)) {
  199496. - brcmf_err("invalid sdpcm_shared address 0x%08X\n",
  199497. - addr);
  199498. - return -EINVAL;
  199499. - }
  199500. -
  199501. - /* Read hndrte_shared structure */
  199502. - rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
  199503. - sizeof(struct sdpcm_shared_le));
  199504. - if (rv < 0)
  199505. - return rv;
  199506. -
  199507. - /* Endianness */
  199508. - sh->flags = le32_to_cpu(sh_le.flags);
  199509. - sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
  199510. - sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
  199511. - sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
  199512. - sh->assert_line = le32_to_cpu(sh_le.assert_line);
  199513. - sh->console_addr = le32_to_cpu(sh_le.console_addr);
  199514. - sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
  199515. -
  199516. - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) > SDPCM_SHARED_VERSION) {
  199517. - brcmf_err("sdpcm shared version unsupported: dhd %d dongle %d\n",
  199518. - SDPCM_SHARED_VERSION,
  199519. - sh->flags & SDPCM_SHARED_VERSION_MASK);
  199520. - return -EPROTO;
  199521. - }
  199522. -
  199523. - return 0;
  199524. -}
  199525. -
  199526. static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
  199527. struct sdpcm_shared *sh, char __user *data,
  199528. size_t count)
  199529. @@ -3106,6 +3127,8 @@
  199530. debugfs_create_file("forensics", S_IRUGO, dentry, bus,
  199531. &brcmf_sdio_forensic_ops);
  199532. brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
  199533. + debugfs_create_u32("console_interval", 0644, dentry,
  199534. + &bus->console_interval);
  199535. }
  199536. #else
  199537. static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
  199538. @@ -3224,51 +3247,29 @@
  199539. const struct firmware *fw)
  199540. {
  199541. int err;
  199542. - int offset;
  199543. - int address;
  199544. - int len;
  199545. brcmf_dbg(TRACE, "Enter\n");
  199546. - err = 0;
  199547. - offset = 0;
  199548. - address = bus->ci->rambase;
  199549. - while (offset < fw->size) {
  199550. - len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK :
  199551. - fw->size - offset;
  199552. - err = brcmf_sdiod_ramrw(bus->sdiodev, true, address,
  199553. - (u8 *)&fw->data[offset], len);
  199554. - if (err) {
  199555. - brcmf_err("error %d on writing %d membytes at 0x%08x\n",
  199556. - err, len, address);
  199557. - return err;
  199558. - }
  199559. - offset += len;
  199560. - address += len;
  199561. - }
  199562. - if (!err)
  199563. - if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
  199564. - (u8 *)fw->data, fw->size))
  199565. - err = -EIO;
  199566. + err = brcmf_sdiod_ramrw(bus->sdiodev, true, bus->ci->rambase,
  199567. + (u8 *)fw->data, fw->size);
  199568. + if (err)
  199569. + brcmf_err("error %d on writing %d membytes at 0x%08x\n",
  199570. + err, (int)fw->size, bus->ci->rambase);
  199571. + else if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,
  199572. + (u8 *)fw->data, fw->size))
  199573. + err = -EIO;
  199574. return err;
  199575. }
  199576. static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus,
  199577. - const struct firmware *nv)
  199578. + void *vars, u32 varsz)
  199579. {
  199580. - void *vars;
  199581. - u32 varsz;
  199582. int address;
  199583. int err;
  199584. brcmf_dbg(TRACE, "Enter\n");
  199585. - vars = brcmf_nvram_strip(nv, &varsz);
  199586. -
  199587. - if (vars == NULL)
  199588. - return -EINVAL;
  199589. -
  199590. address = bus->ci->ramsize - varsz + bus->ci->rambase;
  199591. err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, vars, varsz);
  199592. if (err)
  199593. @@ -3277,28 +3278,21 @@
  199594. else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz))
  199595. err = -EIO;
  199596. - brcmf_nvram_free(vars);
  199597. -
  199598. return err;
  199599. }
  199600. -static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)
  199601. +static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
  199602. + const struct firmware *fw,
  199603. + void *nvram, u32 nvlen)
  199604. {
  199605. int bcmerror = -EFAULT;
  199606. - const struct firmware *fw;
  199607. u32 rstvec;
  199608. sdio_claim_host(bus->sdiodev->func[1]);
  199609. brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  199610. /* Keep arm in reset */
  199611. - brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci);
  199612. -
  199613. - fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);
  199614. - if (fw == NULL) {
  199615. - bcmerror = -ENOENT;
  199616. - goto err;
  199617. - }
  199618. + brcmf_chip_enter_download(bus->ci);
  199619. rstvec = get_unaligned_le32(fw->data);
  199620. brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
  199621. @@ -3307,24 +3301,19 @@
  199622. release_firmware(fw);
  199623. if (bcmerror) {
  199624. brcmf_err("dongle image file download failed\n");
  199625. + brcmf_fw_nvram_free(nvram);
  199626. goto err;
  199627. }
  199628. - fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM);
  199629. - if (fw == NULL) {
  199630. - bcmerror = -ENOENT;
  199631. - goto err;
  199632. - }
  199633. -
  199634. - bcmerror = brcmf_sdio_download_nvram(bus, fw);
  199635. - release_firmware(fw);
  199636. + bcmerror = brcmf_sdio_download_nvram(bus, nvram, nvlen);
  199637. + brcmf_fw_nvram_free(nvram);
  199638. if (bcmerror) {
  199639. brcmf_err("dongle nvram file download failed\n");
  199640. goto err;
  199641. }
  199642. /* Take arm out of reset */
  199643. - if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) {
  199644. + if (!brcmf_chip_exit_download(bus->ci, rstvec)) {
  199645. brcmf_err("error getting out of ARM core reset\n");
  199646. goto err;
  199647. }
  199648. @@ -3339,40 +3328,6 @@
  199649. return bcmerror;
  199650. }
  199651. -static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus)
  199652. -{
  199653. - u32 addr, reg, pmu_cc3_mask = ~0;
  199654. - int err;
  199655. -
  199656. - brcmf_dbg(TRACE, "Enter\n");
  199657. -
  199658. - /* old chips with PMU version less than 17 don't support save restore */
  199659. - if (bus->ci->pmurev < 17)
  199660. - return false;
  199661. -
  199662. - switch (bus->ci->chip) {
  199663. - case BCM43241_CHIP_ID:
  199664. - case BCM4335_CHIP_ID:
  199665. - case BCM4339_CHIP_ID:
  199666. - /* read PMU chipcontrol register 3 */
  199667. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr);
  199668. - brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL);
  199669. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data);
  199670. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
  199671. - return (reg & pmu_cc3_mask) != 0;
  199672. - default:
  199673. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucapabilities_ext);
  199674. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, &err);
  199675. - if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
  199676. - return false;
  199677. -
  199678. - addr = CORE_CC_REG(bus->ci->c_inf[0].base, retention_ctl);
  199679. - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL);
  199680. - return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
  199681. - PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
  199682. - }
  199683. -}
  199684. -
  199685. static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
  199686. {
  199687. int err = 0;
  199688. @@ -3424,7 +3379,7 @@
  199689. brcmf_dbg(TRACE, "Enter\n");
  199690. /* KSO bit added in SDIO core rev 12 */
  199691. - if (bus->ci->c_inf[1].rev < 12)
  199692. + if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12)
  199693. return 0;
  199694. val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err);
  199695. @@ -3455,15 +3410,13 @@
  199696. struct brcmf_sdio *bus = sdiodev->bus;
  199697. uint pad_size;
  199698. u32 value;
  199699. - u8 idx;
  199700. int err;
  199701. /* the commands below use the terms tx and rx from
  199702. * a device perspective, ie. bus:txglom affects the
  199703. * bus transfers from device to host.
  199704. */
  199705. - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
  199706. - if (bus->ci->c_inf[idx].rev < 12) {
  199707. + if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) {
  199708. /* for sdio core rev < 12, disable txgloming */
  199709. value = 0;
  199710. err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
  199711. @@ -3503,97 +3456,6 @@
  199712. return err;
  199713. }
  199714. -static int brcmf_sdio_bus_init(struct device *dev)
  199715. -{
  199716. - struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  199717. - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  199718. - struct brcmf_sdio *bus = sdiodev->bus;
  199719. - int err, ret = 0;
  199720. - u8 saveclk;
  199721. -
  199722. - brcmf_dbg(TRACE, "Enter\n");
  199723. -
  199724. - /* try to download image and nvram to the dongle */
  199725. - if (bus_if->state == BRCMF_BUS_DOWN) {
  199726. - bus->alp_only = true;
  199727. - err = brcmf_sdio_download_firmware(bus);
  199728. - if (err)
  199729. - return err;
  199730. - bus->alp_only = false;
  199731. - }
  199732. -
  199733. - if (!bus->sdiodev->bus_if->drvr)
  199734. - return 0;
  199735. -
  199736. - /* Start the watchdog timer */
  199737. - bus->sdcnt.tickcnt = 0;
  199738. - brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
  199739. -
  199740. - sdio_claim_host(bus->sdiodev->func[1]);
  199741. -
  199742. - /* Make sure backplane clock is on, needed to generate F2 interrupt */
  199743. - brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  199744. - if (bus->clkstate != CLK_AVAIL)
  199745. - goto exit;
  199746. -
  199747. - /* Force clocks on backplane to be sure F2 interrupt propagates */
  199748. - saveclk = brcmf_sdiod_regrb(bus->sdiodev,
  199749. - SBSDIO_FUNC1_CHIPCLKCSR, &err);
  199750. - if (!err) {
  199751. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  199752. - (saveclk | SBSDIO_FORCE_HT), &err);
  199753. - }
  199754. - if (err) {
  199755. - brcmf_err("Failed to force clock for F2: err %d\n", err);
  199756. - goto exit;
  199757. - }
  199758. -
  199759. - /* Enable function 2 (frame transfers) */
  199760. - w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
  199761. - offsetof(struct sdpcmd_regs, tosbmailboxdata));
  199762. - err = sdio_enable_func(bus->sdiodev->func[SDIO_FUNC_2]);
  199763. -
  199764. -
  199765. - brcmf_dbg(INFO, "enable F2: err=%d\n", err);
  199766. -
  199767. - /* If F2 successfully enabled, set core and enable interrupts */
  199768. - if (!err) {
  199769. - /* Set up the interrupt mask and enable interrupts */
  199770. - bus->hostintmask = HOSTINTMASK;
  199771. - w_sdreg32(bus, bus->hostintmask,
  199772. - offsetof(struct sdpcmd_regs, hostintmask));
  199773. -
  199774. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
  199775. - } else {
  199776. - /* Disable F2 again */
  199777. - sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);
  199778. - ret = -ENODEV;
  199779. - }
  199780. -
  199781. - if (brcmf_sdio_sr_capable(bus)) {
  199782. - brcmf_sdio_sr_init(bus);
  199783. - } else {
  199784. - /* Restore previous clock setting */
  199785. - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  199786. - saveclk, &err);
  199787. - }
  199788. -
  199789. - if (ret == 0) {
  199790. - ret = brcmf_sdiod_intr_register(bus->sdiodev);
  199791. - if (ret != 0)
  199792. - brcmf_err("intr register failed:%d\n", ret);
  199793. - }
  199794. -
  199795. - /* If we didn't come up, turn off backplane clock */
  199796. - if (ret != 0)
  199797. - brcmf_sdio_clkctl(bus, CLK_NONE, false);
  199798. -
  199799. -exit:
  199800. - sdio_release_host(bus->sdiodev->func[1]);
  199801. -
  199802. - return ret;
  199803. -}
  199804. -
  199805. void brcmf_sdio_isr(struct brcmf_sdio *bus)
  199806. {
  199807. brcmf_dbg(TRACE, "Enter\n");
  199808. @@ -3714,11 +3576,175 @@
  199809. datawork);
  199810. while (atomic_read(&bus->dpc_tskcnt)) {
  199811. + atomic_set(&bus->dpc_tskcnt, 0);
  199812. brcmf_sdio_dpc(bus);
  199813. - atomic_dec(&bus->dpc_tskcnt);
  199814. }
  199815. }
  199816. +static void
  199817. +brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  199818. + struct brcmf_chip *ci, u32 drivestrength)
  199819. +{
  199820. + const struct sdiod_drive_str *str_tab = NULL;
  199821. + u32 str_mask;
  199822. + u32 str_shift;
  199823. + u32 base;
  199824. + u32 i;
  199825. + u32 drivestrength_sel = 0;
  199826. + u32 cc_data_temp;
  199827. + u32 addr;
  199828. +
  199829. + if (!(ci->cc_caps & CC_CAP_PMU))
  199830. + return;
  199831. +
  199832. + switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
  199833. + case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
  199834. + str_tab = sdiod_drvstr_tab1_1v8;
  199835. + str_mask = 0x00003800;
  199836. + str_shift = 11;
  199837. + break;
  199838. + case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
  199839. + str_tab = sdiod_drvstr_tab6_1v8;
  199840. + str_mask = 0x00001800;
  199841. + str_shift = 11;
  199842. + break;
  199843. + case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
  199844. + /* note: 43143 does not support tristate */
  199845. + i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
  199846. + if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
  199847. + str_tab = sdiod_drvstr_tab2_3v3;
  199848. + str_mask = 0x00000007;
  199849. + str_shift = 0;
  199850. + } else
  199851. + brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
  199852. + ci->name, drivestrength);
  199853. + break;
  199854. + case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
  199855. + str_tab = sdiod_drive_strength_tab5_1v8;
  199856. + str_mask = 0x00003800;
  199857. + str_shift = 11;
  199858. + break;
  199859. + default:
  199860. + brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
  199861. + ci->name, ci->chiprev, ci->pmurev);
  199862. + break;
  199863. + }
  199864. +
  199865. + if (str_tab != NULL) {
  199866. + for (i = 0; str_tab[i].strength != 0; i++) {
  199867. + if (drivestrength >= str_tab[i].strength) {
  199868. + drivestrength_sel = str_tab[i].sel;
  199869. + break;
  199870. + }
  199871. + }
  199872. + base = brcmf_chip_get_chipcommon(ci)->base;
  199873. + addr = CORE_CC_REG(base, chipcontrol_addr);
  199874. + brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
  199875. + cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  199876. + cc_data_temp &= ~str_mask;
  199877. + drivestrength_sel <<= str_shift;
  199878. + cc_data_temp |= drivestrength_sel;
  199879. + brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
  199880. +
  199881. + brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
  199882. + str_tab[i].strength, drivestrength, cc_data_temp);
  199883. + }
  199884. +}
  199885. +
  199886. +static int brcmf_sdio_buscoreprep(void *ctx)
  199887. +{
  199888. + struct brcmf_sdio_dev *sdiodev = ctx;
  199889. + int err = 0;
  199890. + u8 clkval, clkset;
  199891. +
  199892. + /* Try forcing SDIO core to do ALPAvail request only */
  199893. + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  199894. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  199895. + if (err) {
  199896. + brcmf_err("error writing for HT off\n");
  199897. + return err;
  199898. + }
  199899. +
  199900. + /* If register supported, wait for ALPAvail and then force ALP */
  199901. + /* This may take up to 15 milliseconds */
  199902. + clkval = brcmf_sdiod_regrb(sdiodev,
  199903. + SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  199904. +
  199905. + if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  199906. + brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  199907. + clkset, clkval);
  199908. + return -EACCES;
  199909. + }
  199910. +
  199911. + SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
  199912. + SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  199913. + !SBSDIO_ALPAV(clkval)),
  199914. + PMU_MAX_TRANSITION_DLY);
  199915. + if (!SBSDIO_ALPAV(clkval)) {
  199916. + brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
  199917. + clkval);
  199918. + return -EBUSY;
  199919. + }
  199920. +
  199921. + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  199922. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  199923. + udelay(65);
  199924. +
  199925. + /* Also, disable the extra SDIO pull-ups */
  199926. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  199927. +
  199928. + return 0;
  199929. +}
  199930. +
  199931. +static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
  199932. + u32 rstvec)
  199933. +{
  199934. + struct brcmf_sdio_dev *sdiodev = ctx;
  199935. + struct brcmf_core *core;
  199936. + u32 reg_addr;
  199937. +
  199938. + /* clear all interrupts */
  199939. + core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV);
  199940. + reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus);
  199941. + brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  199942. +
  199943. + if (rstvec)
  199944. + /* Write reset vector to address 0 */
  199945. + brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
  199946. + sizeof(rstvec));
  199947. +}
  199948. +
  199949. +static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
  199950. +{
  199951. + struct brcmf_sdio_dev *sdiodev = ctx;
  199952. + u32 val, rev;
  199953. +
  199954. + val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  199955. + if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
  199956. + addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
  199957. + rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
  199958. + if (rev >= 2) {
  199959. + val &= ~CID_ID_MASK;
  199960. + val |= BCM4339_CHIP_ID;
  199961. + }
  199962. + }
  199963. + return val;
  199964. +}
  199965. +
  199966. +static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val)
  199967. +{
  199968. + struct brcmf_sdio_dev *sdiodev = ctx;
  199969. +
  199970. + brcmf_sdiod_regwl(sdiodev, addr, val, NULL);
  199971. +}
  199972. +
  199973. +static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
  199974. + .prepare = brcmf_sdio_buscoreprep,
  199975. + .exit_dl = brcmf_sdio_buscore_exitdl,
  199976. + .read32 = brcmf_sdio_buscore_read32,
  199977. + .write32 = brcmf_sdio_buscore_write32,
  199978. +};
  199979. +
  199980. static bool
  199981. brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
  199982. {
  199983. @@ -3734,7 +3760,7 @@
  199984. brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
  199985. /*
  199986. - * Force PLL off until brcmf_sdio_chip_attach()
  199987. + * Force PLL off until brcmf_chip_attach()
  199988. * programs PLL control regs
  199989. */
  199990. @@ -3755,8 +3781,10 @@
  199991. */
  199992. brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);
  199993. - if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) {
  199994. - brcmf_err("brcmf_sdio_chip_attach failed!\n");
  199995. + bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops);
  199996. + if (IS_ERR(bus->ci)) {
  199997. + brcmf_err("brcmf_chip_attach failed!\n");
  199998. + bus->ci = NULL;
  199999. goto fail;
  200000. }
  200001. @@ -3769,7 +3797,7 @@
  200002. drivestrength = bus->sdiodev->pdata->drive_strength;
  200003. else
  200004. drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
  200005. - brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
  200006. + brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
  200007. /* Get info on the SOCRAM cores... */
  200008. bus->ramsize = bus->ci->ramsize;
  200009. @@ -3792,24 +3820,18 @@
  200010. goto fail;
  200011. /* set PMUControl so a backplane reset does PMU state reload */
  200012. - reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base,
  200013. + reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base,
  200014. pmucontrol);
  200015. - reg_val = brcmf_sdiod_regrl(bus->sdiodev,
  200016. - reg_addr,
  200017. - &err);
  200018. + reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err);
  200019. if (err)
  200020. goto fail;
  200021. reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
  200022. - brcmf_sdiod_regwl(bus->sdiodev,
  200023. - reg_addr,
  200024. - reg_val,
  200025. - &err);
  200026. + brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err);
  200027. if (err)
  200028. goto fail;
  200029. -
  200030. sdio_release_host(bus->sdiodev->func[1]);
  200031. brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
  200032. @@ -3849,6 +3871,7 @@
  200033. brcmf_sdio_bus_watchdog(bus);
  200034. /* Count the tick for reference */
  200035. bus->sdcnt.tickcnt++;
  200036. + reinit_completion(&bus->watchdog_wait);
  200037. } else
  200038. break;
  200039. }
  200040. @@ -3872,13 +3895,114 @@
  200041. static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
  200042. .stop = brcmf_sdio_bus_stop,
  200043. .preinit = brcmf_sdio_bus_preinit,
  200044. - .init = brcmf_sdio_bus_init,
  200045. .txdata = brcmf_sdio_bus_txdata,
  200046. .txctl = brcmf_sdio_bus_txctl,
  200047. .rxctl = brcmf_sdio_bus_rxctl,
  200048. .gettxq = brcmf_sdio_bus_gettxq,
  200049. };
  200050. +static void brcmf_sdio_firmware_callback(struct device *dev,
  200051. + const struct firmware *code,
  200052. + void *nvram, u32 nvram_len)
  200053. +{
  200054. + struct brcmf_bus *bus_if = dev_get_drvdata(dev);
  200055. + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
  200056. + struct brcmf_sdio *bus = sdiodev->bus;
  200057. + int err = 0;
  200058. + u8 saveclk;
  200059. +
  200060. + brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev));
  200061. +
  200062. + /* try to download image and nvram to the dongle */
  200063. + if (bus_if->state == BRCMF_BUS_DOWN) {
  200064. + bus->alp_only = true;
  200065. + err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
  200066. + if (err)
  200067. + goto fail;
  200068. + bus->alp_only = false;
  200069. + }
  200070. +
  200071. + if (!bus_if->drvr)
  200072. + return;
  200073. +
  200074. + /* Start the watchdog timer */
  200075. + bus->sdcnt.tickcnt = 0;
  200076. + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
  200077. +
  200078. + sdio_claim_host(sdiodev->func[1]);
  200079. +
  200080. + /* Make sure backplane clock is on, needed to generate F2 interrupt */
  200081. + brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
  200082. + if (bus->clkstate != CLK_AVAIL)
  200083. + goto release;
  200084. +
  200085. + /* Force clocks on backplane to be sure F2 interrupt propagates */
  200086. + saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err);
  200087. + if (!err) {
  200088. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  200089. + (saveclk | SBSDIO_FORCE_HT), &err);
  200090. + }
  200091. + if (err) {
  200092. + brcmf_err("Failed to force clock for F2: err %d\n", err);
  200093. + goto release;
  200094. + }
  200095. +
  200096. + /* Enable function 2 (frame transfers) */
  200097. + w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
  200098. + offsetof(struct sdpcmd_regs, tosbmailboxdata));
  200099. + err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]);
  200100. +
  200101. +
  200102. + brcmf_dbg(INFO, "enable F2: err=%d\n", err);
  200103. +
  200104. + /* If F2 successfully enabled, set core and enable interrupts */
  200105. + if (!err) {
  200106. + /* Set up the interrupt mask and enable interrupts */
  200107. + bus->hostintmask = HOSTINTMASK;
  200108. + w_sdreg32(bus, bus->hostintmask,
  200109. + offsetof(struct sdpcmd_regs, hostintmask));
  200110. +
  200111. + brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err);
  200112. + } else {
  200113. + /* Disable F2 again */
  200114. + sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);
  200115. + goto release;
  200116. + }
  200117. +
  200118. + if (brcmf_chip_sr_capable(bus->ci)) {
  200119. + brcmf_sdio_sr_init(bus);
  200120. + } else {
  200121. + /* Restore previous clock setting */
  200122. + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
  200123. + saveclk, &err);
  200124. + }
  200125. +
  200126. + if (err == 0) {
  200127. + err = brcmf_sdiod_intr_register(sdiodev);
  200128. + if (err != 0)
  200129. + brcmf_err("intr register failed:%d\n", err);
  200130. + }
  200131. +
  200132. + /* If we didn't come up, turn off backplane clock */
  200133. + if (err != 0)
  200134. + brcmf_sdio_clkctl(bus, CLK_NONE, false);
  200135. +
  200136. + sdio_release_host(sdiodev->func[1]);
  200137. +
  200138. + err = brcmf_bus_start(dev);
  200139. + if (err != 0) {
  200140. + brcmf_err("dongle is not responding\n");
  200141. + goto fail;
  200142. + }
  200143. + return;
  200144. +
  200145. +release:
  200146. + sdio_release_host(sdiodev->func[1]);
  200147. +fail:
  200148. + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
  200149. + device_release_driver(dev);
  200150. +}
  200151. +
  200152. struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
  200153. {
  200154. int ret;
  200155. @@ -3925,7 +4049,8 @@
  200156. }
  200157. spin_lock_init(&bus->rxctl_lock);
  200158. - spin_lock_init(&bus->txqlock);
  200159. + spin_lock_init(&bus->txq_lock);
  200160. + sema_init(&bus->tx_seq_lock, 1);
  200161. init_waitqueue_head(&bus->ctrl_wait);
  200162. init_waitqueue_head(&bus->dcmd_resp_wait);
  200163. @@ -3961,8 +4086,13 @@
  200164. goto fail;
  200165. }
  200166. + /* Query the F2 block size, set roundup accordingly */
  200167. + bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
  200168. + bus->roundup = min(max_roundup, bus->blocksize);
  200169. +
  200170. /* Allocate buffers */
  200171. if (bus->sdiodev->bus_if->maxctl) {
  200172. + bus->sdiodev->bus_if->maxctl += bus->roundup;
  200173. bus->rxblen =
  200174. roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
  200175. ALIGNMENT) + bus->head_align;
  200176. @@ -3990,10 +4120,6 @@
  200177. bus->idletime = BRCMF_IDLE_INTERVAL;
  200178. bus->idleclock = BRCMF_IDLE_ACTIVE;
  200179. - /* Query the F2 block size, set roundup accordingly */
  200180. - bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
  200181. - bus->roundup = min(max_roundup, bus->blocksize);
  200182. -
  200183. /* SR state */
  200184. bus->sleeping = false;
  200185. bus->sr_enabled = false;
  200186. @@ -4001,10 +4127,14 @@
  200187. brcmf_sdio_debugfs_create(bus);
  200188. brcmf_dbg(INFO, "completed!!\n");
  200189. - /* if firmware path present try to download and bring up bus */
  200190. - ret = brcmf_bus_start(bus->sdiodev->dev);
  200191. + ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
  200192. + brcmf_sdio_get_fwname(bus->ci,
  200193. + BRCMF_FIRMWARE_BIN),
  200194. + brcmf_sdio_get_fwname(bus->ci,
  200195. + BRCMF_FIRMWARE_NVRAM),
  200196. + brcmf_sdio_firmware_callback);
  200197. if (ret != 0) {
  200198. - brcmf_err("dongle is not responding\n");
  200199. + brcmf_err("async firmware request failed: %d\n", ret);
  200200. goto fail;
  200201. }
  200202. @@ -4024,14 +4154,12 @@
  200203. /* De-register interrupt handler */
  200204. brcmf_sdiod_intr_unregister(bus->sdiodev);
  200205. + brcmf_detach(bus->sdiodev->dev);
  200206. +
  200207. cancel_work_sync(&bus->datawork);
  200208. if (bus->brcmf_wq)
  200209. destroy_workqueue(bus->brcmf_wq);
  200210. - if (bus->sdiodev->bus_if->drvr) {
  200211. - brcmf_detach(bus->sdiodev->dev);
  200212. - }
  200213. -
  200214. if (bus->ci) {
  200215. if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
  200216. sdio_claim_host(bus->sdiodev->func[1]);
  200217. @@ -4042,12 +4170,11 @@
  200218. * all necessary cores.
  200219. */
  200220. msleep(20);
  200221. - brcmf_sdio_chip_enter_download(bus->sdiodev,
  200222. - bus->ci);
  200223. + brcmf_chip_enter_download(bus->ci);
  200224. brcmf_sdio_clkctl(bus, CLK_NONE, false);
  200225. sdio_release_host(bus->sdiodev->func[1]);
  200226. }
  200227. - brcmf_sdio_chip_detach(&bus->ci);
  200228. + brcmf_chip_detach(bus->ci);
  200229. }
  200230. kfree(bus->rxbuf);
  200231. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/firmware.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
  200232. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/firmware.c 1970-01-01 01:00:00.000000000 +0100
  200233. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.c 2014-09-11 18:06:03.906045582 +0200
  200234. @@ -0,0 +1,332 @@
  200235. +/*
  200236. + * Copyright (c) 2013 Broadcom Corporation
  200237. + *
  200238. + * Permission to use, copy, modify, and/or distribute this software for any
  200239. + * purpose with or without fee is hereby granted, provided that the above
  200240. + * copyright notice and this permission notice appear in all copies.
  200241. + *
  200242. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  200243. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  200244. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  200245. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  200246. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  200247. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  200248. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  200249. + */
  200250. +
  200251. +#include <linux/kernel.h>
  200252. +#include <linux/slab.h>
  200253. +#include <linux/device.h>
  200254. +#include <linux/firmware.h>
  200255. +
  200256. +#include "dhd_dbg.h"
  200257. +#include "firmware.h"
  200258. +
  200259. +enum nvram_parser_state {
  200260. + IDLE,
  200261. + KEY,
  200262. + VALUE,
  200263. + COMMENT,
  200264. + END
  200265. +};
  200266. +
  200267. +/**
  200268. + * struct nvram_parser - internal info for parser.
  200269. + *
  200270. + * @state: current parser state.
  200271. + * @fwnv: input buffer being parsed.
  200272. + * @nvram: output buffer with parse result.
  200273. + * @nvram_len: lenght of parse result.
  200274. + * @line: current line.
  200275. + * @column: current column in line.
  200276. + * @pos: byte offset in input buffer.
  200277. + * @entry: start position of key,value entry.
  200278. + */
  200279. +struct nvram_parser {
  200280. + enum nvram_parser_state state;
  200281. + const struct firmware *fwnv;
  200282. + u8 *nvram;
  200283. + u32 nvram_len;
  200284. + u32 line;
  200285. + u32 column;
  200286. + u32 pos;
  200287. + u32 entry;
  200288. +};
  200289. +
  200290. +static bool is_nvram_char(char c)
  200291. +{
  200292. + /* comment marker excluded */
  200293. + if (c == '#')
  200294. + return false;
  200295. +
  200296. + /* key and value may have any other readable character */
  200297. + return (c > 0x20 && c < 0x7f);
  200298. +}
  200299. +
  200300. +static bool is_whitespace(char c)
  200301. +{
  200302. + return (c == ' ' || c == '\r' || c == '\n' || c == '\t');
  200303. +}
  200304. +
  200305. +static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp)
  200306. +{
  200307. + char c;
  200308. +
  200309. + c = nvp->fwnv->data[nvp->pos];
  200310. + if (c == '\n')
  200311. + return COMMENT;
  200312. + if (is_whitespace(c))
  200313. + goto proceed;
  200314. + if (c == '#')
  200315. + return COMMENT;
  200316. + if (is_nvram_char(c)) {
  200317. + nvp->entry = nvp->pos;
  200318. + return KEY;
  200319. + }
  200320. + brcmf_dbg(INFO, "warning: ln=%d:col=%d: ignoring invalid character\n",
  200321. + nvp->line, nvp->column);
  200322. +proceed:
  200323. + nvp->column++;
  200324. + nvp->pos++;
  200325. + return IDLE;
  200326. +}
  200327. +
  200328. +static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
  200329. +{
  200330. + enum nvram_parser_state st = nvp->state;
  200331. + char c;
  200332. +
  200333. + c = nvp->fwnv->data[nvp->pos];
  200334. + if (c == '=') {
  200335. + st = VALUE;
  200336. + } else if (!is_nvram_char(c)) {
  200337. + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
  200338. + nvp->line, nvp->column);
  200339. + return COMMENT;
  200340. + }
  200341. +
  200342. + nvp->column++;
  200343. + nvp->pos++;
  200344. + return st;
  200345. +}
  200346. +
  200347. +static enum nvram_parser_state
  200348. +brcmf_nvram_handle_value(struct nvram_parser *nvp)
  200349. +{
  200350. + char c;
  200351. + char *skv;
  200352. + char *ekv;
  200353. + u32 cplen;
  200354. +
  200355. + c = nvp->fwnv->data[nvp->pos];
  200356. + if (!is_nvram_char(c)) {
  200357. + /* key,value pair complete */
  200358. + ekv = (u8 *)&nvp->fwnv->data[nvp->pos];
  200359. + skv = (u8 *)&nvp->fwnv->data[nvp->entry];
  200360. + cplen = ekv - skv;
  200361. + /* copy to output buffer */
  200362. + memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen);
  200363. + nvp->nvram_len += cplen;
  200364. + nvp->nvram[nvp->nvram_len] = '\0';
  200365. + nvp->nvram_len++;
  200366. + return IDLE;
  200367. + }
  200368. + nvp->pos++;
  200369. + nvp->column++;
  200370. + return VALUE;
  200371. +}
  200372. +
  200373. +static enum nvram_parser_state
  200374. +brcmf_nvram_handle_comment(struct nvram_parser *nvp)
  200375. +{
  200376. + char *eol, *sol;
  200377. +
  200378. + sol = (char *)&nvp->fwnv->data[nvp->pos];
  200379. + eol = strchr(sol, '\n');
  200380. + if (eol == NULL)
  200381. + return END;
  200382. +
  200383. + /* eat all moving to next line */
  200384. + nvp->line++;
  200385. + nvp->column = 1;
  200386. + nvp->pos += (eol - sol) + 1;
  200387. + return IDLE;
  200388. +}
  200389. +
  200390. +static enum nvram_parser_state brcmf_nvram_handle_end(struct nvram_parser *nvp)
  200391. +{
  200392. + /* final state */
  200393. + return END;
  200394. +}
  200395. +
  200396. +static enum nvram_parser_state
  200397. +(*nv_parser_states[])(struct nvram_parser *nvp) = {
  200398. + brcmf_nvram_handle_idle,
  200399. + brcmf_nvram_handle_key,
  200400. + brcmf_nvram_handle_value,
  200401. + brcmf_nvram_handle_comment,
  200402. + brcmf_nvram_handle_end
  200403. +};
  200404. +
  200405. +static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
  200406. + const struct firmware *nv)
  200407. +{
  200408. + memset(nvp, 0, sizeof(*nvp));
  200409. + nvp->fwnv = nv;
  200410. + /* Alloc for extra 0 byte + roundup by 4 + length field */
  200411. + nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL);
  200412. + if (!nvp->nvram)
  200413. + return -ENOMEM;
  200414. +
  200415. + nvp->line = 1;
  200416. + nvp->column = 1;
  200417. + return 0;
  200418. +}
  200419. +
  200420. +/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
  200421. + * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
  200422. + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
  200423. + * End of buffer is completed with token identifying length of buffer.
  200424. + */
  200425. +static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length)
  200426. +{
  200427. + struct nvram_parser nvp;
  200428. + u32 pad;
  200429. + u32 token;
  200430. + __le32 token_le;
  200431. +
  200432. + if (brcmf_init_nvram_parser(&nvp, nv) < 0)
  200433. + return NULL;
  200434. +
  200435. + while (nvp.pos < nv->size) {
  200436. + nvp.state = nv_parser_states[nvp.state](&nvp);
  200437. + if (nvp.state == END)
  200438. + break;
  200439. + }
  200440. + pad = nvp.nvram_len;
  200441. + *new_length = roundup(nvp.nvram_len + 1, 4);
  200442. + while (pad != *new_length) {
  200443. + nvp.nvram[pad] = 0;
  200444. + pad++;
  200445. + }
  200446. +
  200447. + token = *new_length / 4;
  200448. + token = (~token << 16) | (token & 0x0000FFFF);
  200449. + token_le = cpu_to_le32(token);
  200450. +
  200451. + memcpy(&nvp.nvram[*new_length], &token_le, sizeof(token_le));
  200452. + *new_length += sizeof(token_le);
  200453. +
  200454. + return nvp.nvram;
  200455. +}
  200456. +
  200457. +void brcmf_fw_nvram_free(void *nvram)
  200458. +{
  200459. + kfree(nvram);
  200460. +}
  200461. +
  200462. +struct brcmf_fw {
  200463. + struct device *dev;
  200464. + u16 flags;
  200465. + const struct firmware *code;
  200466. + const char *nvram_name;
  200467. + void (*done)(struct device *dev, const struct firmware *fw,
  200468. + void *nvram_image, u32 nvram_len);
  200469. +};
  200470. +
  200471. +static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
  200472. +{
  200473. + struct brcmf_fw *fwctx = ctx;
  200474. + u32 nvram_length = 0;
  200475. + void *nvram = NULL;
  200476. +
  200477. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
  200478. + if (!fw && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
  200479. + goto fail;
  200480. +
  200481. + if (fw) {
  200482. + nvram = brcmf_fw_nvram_strip(fw, &nvram_length);
  200483. + release_firmware(fw);
  200484. + if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
  200485. + goto fail;
  200486. + }
  200487. +
  200488. + fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
  200489. + kfree(fwctx);
  200490. + return;
  200491. +
  200492. +fail:
  200493. + brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
  200494. + if (fwctx->code)
  200495. + release_firmware(fwctx->code);
  200496. + device_release_driver(fwctx->dev);
  200497. + kfree(fwctx);
  200498. +}
  200499. +
  200500. +static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
  200501. +{
  200502. + struct brcmf_fw *fwctx = ctx;
  200503. + int ret;
  200504. +
  200505. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
  200506. + if (!fw)
  200507. + goto fail;
  200508. +
  200509. + /* only requested code so done here */
  200510. + if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
  200511. + fwctx->done(fwctx->dev, fw, NULL, 0);
  200512. + kfree(fwctx);
  200513. + return;
  200514. + }
  200515. + fwctx->code = fw;
  200516. + ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
  200517. + fwctx->dev, GFP_KERNEL, fwctx,
  200518. + brcmf_fw_request_nvram_done);
  200519. +
  200520. + if (!ret)
  200521. + return;
  200522. +
  200523. + /* when nvram is optional call .done() callback here */
  200524. + if (fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL) {
  200525. + fwctx->done(fwctx->dev, fw, NULL, 0);
  200526. + kfree(fwctx);
  200527. + return;
  200528. + }
  200529. +
  200530. + /* failed nvram request */
  200531. + release_firmware(fw);
  200532. +fail:
  200533. + brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
  200534. + device_release_driver(fwctx->dev);
  200535. + kfree(fwctx);
  200536. +}
  200537. +
  200538. +int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
  200539. + const char *code, const char *nvram,
  200540. + void (*fw_cb)(struct device *dev,
  200541. + const struct firmware *fw,
  200542. + void *nvram_image, u32 nvram_len))
  200543. +{
  200544. + struct brcmf_fw *fwctx;
  200545. +
  200546. + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
  200547. + if (!fw_cb || !code)
  200548. + return -EINVAL;
  200549. +
  200550. + if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram)
  200551. + return -EINVAL;
  200552. +
  200553. + fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL);
  200554. + if (!fwctx)
  200555. + return -ENOMEM;
  200556. +
  200557. + fwctx->dev = dev;
  200558. + fwctx->flags = flags;
  200559. + fwctx->done = fw_cb;
  200560. + if (flags & BRCMF_FW_REQUEST_NVRAM)
  200561. + fwctx->nvram_name = nvram;
  200562. +
  200563. + return request_firmware_nowait(THIS_MODULE, true, code, dev,
  200564. + GFP_KERNEL, fwctx,
  200565. + brcmf_fw_request_code_done);
  200566. +}
  200567. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/firmware.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
  200568. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/firmware.h 1970-01-01 01:00:00.000000000 +0100
  200569. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/firmware.h 2014-09-11 18:06:03.906045582 +0200
  200570. @@ -0,0 +1,36 @@
  200571. +/*
  200572. + * Copyright (c) 2013 Broadcom Corporation
  200573. + *
  200574. + * Permission to use, copy, modify, and/or distribute this software for any
  200575. + * purpose with or without fee is hereby granted, provided that the above
  200576. + * copyright notice and this permission notice appear in all copies.
  200577. + *
  200578. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  200579. + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  200580. + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  200581. + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  200582. + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  200583. + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  200584. + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  200585. + */
  200586. +#ifndef BRCMFMAC_FIRMWARE_H
  200587. +#define BRCMFMAC_FIRMWARE_H
  200588. +
  200589. +#define BRCMF_FW_REQUEST 0x000F
  200590. +#define BRCMF_FW_REQUEST_NVRAM 0x0001
  200591. +#define BRCMF_FW_REQ_FLAGS 0x00F0
  200592. +#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
  200593. +
  200594. +void brcmf_fw_nvram_free(void *nvram);
  200595. +/*
  200596. + * Request firmware(s) asynchronously. When the asynchronous request
  200597. + * fails it will not use the callback, but call device_release_driver()
  200598. + * instead which will call the driver .remove() callback.
  200599. + */
  200600. +int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
  200601. + const char *code, const char *nvram,
  200602. + void (*fw_cb)(struct device *dev,
  200603. + const struct firmware *fw,
  200604. + void *nvram_image, u32 nvram_len));
  200605. +
  200606. +#endif /* BRCMFMAC_FIRMWARE_H */
  200607. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwil.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
  200608. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwil.c 2014-08-14 03:38:34.000000000 +0200
  200609. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.c 2014-09-11 18:06:03.906045582 +0200
  200610. @@ -124,7 +124,8 @@
  200611. }
  200612. static u32
  200613. -brcmf_create_iovar(char *name, char *data, u32 datalen, char *buf, u32 buflen)
  200614. +brcmf_create_iovar(char *name, const char *data, u32 datalen,
  200615. + char *buf, u32 buflen)
  200616. {
  200617. u32 len;
  200618. @@ -144,7 +145,7 @@
  200619. s32
  200620. -brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
  200621. +brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
  200622. u32 len)
  200623. {
  200624. struct brcmf_pub *drvr = ifp->drvr;
  200625. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwil.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
  200626. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwil.h 2014-08-14 03:38:34.000000000 +0200
  200627. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil.h 2014-09-11 18:06:03.906045582 +0200
  200628. @@ -83,7 +83,7 @@
  200629. s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
  200630. s32 brcmf_fil_cmd_int_get(struct brcmf_if *ifp, u32 cmd, u32 *data);
  200631. -s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data,
  200632. +s32 brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
  200633. u32 len);
  200634. s32 brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
  200635. u32 len);
  200636. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
  200637. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h 2014-08-14 03:38:34.000000000 +0200
  200638. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h 2014-09-11 18:06:03.906045582 +0200
  200639. @@ -48,6 +48,19 @@
  200640. #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
  200641. +/* OBSS Coex Auto/On/Off */
  200642. +#define BRCMF_OBSS_COEX_AUTO (-1)
  200643. +#define BRCMF_OBSS_COEX_OFF 0
  200644. +#define BRCMF_OBSS_COEX_ON 1
  200645. +
  200646. +/* join preference types for join_pref iovar */
  200647. +enum brcmf_join_pref_types {
  200648. + BRCMF_JOIN_PREF_RSSI = 1,
  200649. + BRCMF_JOIN_PREF_WPA,
  200650. + BRCMF_JOIN_PREF_BAND,
  200651. + BRCMF_JOIN_PREF_RSSI_DELTA,
  200652. +};
  200653. +
  200654. enum brcmf_fil_p2p_if_types {
  200655. BRCMF_FIL_P2P_IF_CLIENT,
  200656. BRCMF_FIL_P2P_IF_GO,
  200657. @@ -87,6 +100,11 @@
  200658. __le32 enable;
  200659. };
  200660. +struct brcmf_fil_bwcap_le {
  200661. + __le32 band;
  200662. + __le32 bw_cap;
  200663. +};
  200664. +
  200665. /**
  200666. * struct tdls_iovar - common structure for tdls iovars.
  200667. *
  200668. @@ -272,6 +290,22 @@
  200669. __le16 chanspec_list[1];
  200670. };
  200671. +/**
  200672. + * struct join_pref params - parameters for preferred join selection.
  200673. + *
  200674. + * @type: preference type (see enum brcmf_join_pref_types).
  200675. + * @len: length of bytes following (currently always 2).
  200676. + * @rssi_gain: signal gain for selection (only when @type is RSSI_DELTA).
  200677. + * @band: band to which selection preference applies.
  200678. + * This is used if @type is BAND or RSSI_DELTA.
  200679. + */
  200680. +struct brcmf_join_pref_params {
  200681. + u8 type;
  200682. + u8 len;
  200683. + u8 rssi_gain;
  200684. + u8 band;
  200685. +};
  200686. +
  200687. /* used for join with or without a specific bssid and channel list */
  200688. struct brcmf_join_params {
  200689. struct brcmf_ssid_le ssid_le;
  200690. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
  200691. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c 2014-08-14 03:38:34.000000000 +0200
  200692. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c 2014-09-11 18:06:03.906045582 +0200
  200693. @@ -476,6 +476,7 @@
  200694. bool bus_flow_blocked;
  200695. bool creditmap_received;
  200696. u8 mode;
  200697. + bool avoid_queueing;
  200698. };
  200699. /*
  200700. @@ -1369,13 +1370,12 @@
  200701. }
  200702. static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
  200703. - struct sk_buff *skb, u32 genbit,
  200704. - u16 seq)
  200705. + struct sk_buff *skb, u8 ifidx,
  200706. + u32 genbit, u16 seq)
  200707. {
  200708. struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
  200709. u32 hslot;
  200710. int ret;
  200711. - u8 ifidx;
  200712. hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
  200713. @@ -1389,29 +1389,21 @@
  200714. entry->generation = genbit;
  200715. - ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
  200716. - if (ret == 0) {
  200717. - brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
  200718. - brcmf_skbcb(skb)->htod_seq = seq;
  200719. - if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
  200720. - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
  200721. - brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
  200722. - } else {
  200723. - brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
  200724. - }
  200725. - ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
  200726. - skb);
  200727. + brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
  200728. + brcmf_skbcb(skb)->htod_seq = seq;
  200729. + if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
  200730. + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
  200731. + brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
  200732. + } else {
  200733. + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
  200734. }
  200735. + ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
  200736. if (ret != 0) {
  200737. - /* suppress q is full or hdrpull failed, drop this packet */
  200738. - brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
  200739. - true);
  200740. + /* suppress q is full drop this packet */
  200741. + brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true);
  200742. } else {
  200743. - /*
  200744. - * Mark suppressed to avoid a double free during
  200745. - * wlfc cleanup
  200746. - */
  200747. + /* Mark suppressed to avoid a double free during wlfc cleanup */
  200748. brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot);
  200749. }
  200750. @@ -1428,6 +1420,7 @@
  200751. struct sk_buff *skb;
  200752. struct brcmf_skbuff_cb *skcb;
  200753. struct brcmf_fws_mac_descriptor *entry = NULL;
  200754. + u8 ifidx;
  200755. brcmf_dbg(DATA, "flags %d\n", flags);
  200756. @@ -1476,12 +1469,15 @@
  200757. }
  200758. brcmf_fws_macdesc_return_req_credit(skb);
  200759. + if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
  200760. + brcmu_pkt_buf_free_skb(skb);
  200761. + return -EINVAL;
  200762. + }
  200763. if (!remove_from_hanger)
  200764. - ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
  200765. - seq);
  200766. -
  200767. + ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
  200768. + genbit, seq);
  200769. if (remove_from_hanger || ret)
  200770. - brcmf_txfinalize(fws->drvr, skb, true);
  200771. + brcmf_txfinalize(fws->drvr, skb, ifidx, true);
  200772. return 0;
  200773. }
  200774. @@ -1868,7 +1864,7 @@
  200775. struct ethhdr *eh = (struct ethhdr *)(skb->data);
  200776. int fifo = BRCMF_FWS_FIFO_BCMC;
  200777. bool multicast = is_multicast_ether_addr(eh->h_dest);
  200778. - bool pae = eh->h_proto == htons(ETH_P_PAE);
  200779. + int rc = 0;
  200780. brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
  200781. /* determine the priority */
  200782. @@ -1876,8 +1872,13 @@
  200783. skb->priority = cfg80211_classify8021d(skb, NULL);
  200784. drvr->tx_multicast += !!multicast;
  200785. - if (pae)
  200786. - atomic_inc(&ifp->pend_8021x_cnt);
  200787. +
  200788. + if (fws->avoid_queueing) {
  200789. + rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
  200790. + if (rc < 0)
  200791. + brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
  200792. + return rc;
  200793. + }
  200794. /* set control buffer information */
  200795. skcb->if_flags = 0;
  200796. @@ -1899,15 +1900,12 @@
  200797. brcmf_fws_schedule_deq(fws);
  200798. } else {
  200799. brcmf_err("drop skb: no hanger slot\n");
  200800. - if (pae) {
  200801. - atomic_dec(&ifp->pend_8021x_cnt);
  200802. - if (waitqueue_active(&ifp->pend_8021x_wait))
  200803. - wake_up(&ifp->pend_8021x_wait);
  200804. - }
  200805. - brcmu_pkt_buf_free_skb(skb);
  200806. + brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
  200807. + rc = -ENOMEM;
  200808. }
  200809. brcmf_fws_unlock(fws);
  200810. - return 0;
  200811. +
  200812. + return rc;
  200813. }
  200814. void brcmf_fws_reset_interface(struct brcmf_if *ifp)
  200815. @@ -1982,7 +1980,8 @@
  200816. ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
  200817. brcmf_fws_lock(fws);
  200818. if (ret < 0)
  200819. - brcmf_txfinalize(drvr, skb, false);
  200820. + brcmf_txfinalize(drvr, skb, ifidx,
  200821. + false);
  200822. if (fws->bus_flow_blocked)
  200823. break;
  200824. }
  200825. @@ -2039,6 +2038,13 @@
  200826. fws->drvr = drvr;
  200827. fws->fcmode = fcmode;
  200828. + if ((drvr->bus_if->always_use_fws_queue == false) &&
  200829. + (fcmode == BRCMF_FWS_FCMODE_NONE)) {
  200830. + fws->avoid_queueing = true;
  200831. + brcmf_dbg(INFO, "FWS queueing will be avoided\n");
  200832. + return 0;
  200833. + }
  200834. +
  200835. fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq");
  200836. if (fws->fws_wq == NULL) {
  200837. brcmf_err("workqueue creation failed\n");
  200838. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/Makefile linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/Makefile
  200839. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/Makefile 2014-08-14 03:38:34.000000000 +0200
  200840. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/Makefile 2014-09-11 18:06:03.902045566 +0200
  200841. @@ -24,6 +24,7 @@
  200842. obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
  200843. brcmfmac-objs += \
  200844. wl_cfg80211.o \
  200845. + chip.o \
  200846. fwil.o \
  200847. fweh.o \
  200848. fwsignal.o \
  200849. @@ -32,12 +33,11 @@
  200850. bcdc.o \
  200851. dhd_common.o \
  200852. dhd_linux.o \
  200853. - nvram.o \
  200854. + firmware.o \
  200855. btcoex.o
  200856. brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
  200857. dhd_sdio.o \
  200858. - bcmsdh.o \
  200859. - sdio_chip.o
  200860. + bcmsdh.o
  200861. brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
  200862. usb.o
  200863. brcmfmac-$(CONFIG_BRCMDBG) += \
  200864. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/nvram.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
  200865. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/nvram.c 2014-08-14 03:38:34.000000000 +0200
  200866. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.c 1970-01-01 01:00:00.000000000 +0100
  200867. @@ -1,94 +0,0 @@
  200868. -/*
  200869. - * Copyright (c) 2013 Broadcom Corporation
  200870. - *
  200871. - * Permission to use, copy, modify, and/or distribute this software for any
  200872. - * purpose with or without fee is hereby granted, provided that the above
  200873. - * copyright notice and this permission notice appear in all copies.
  200874. - *
  200875. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  200876. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  200877. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  200878. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  200879. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  200880. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  200881. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  200882. - */
  200883. -
  200884. -#include <linux/kernel.h>
  200885. -#include <linux/slab.h>
  200886. -#include <linux/firmware.h>
  200887. -
  200888. -#include "nvram.h"
  200889. -
  200890. -/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file
  200891. - * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
  200892. - * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
  200893. - * End of buffer is completed with token identifying length of buffer.
  200894. - */
  200895. -void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)
  200896. -{
  200897. - u8 *nvram;
  200898. - u32 i;
  200899. - u32 len;
  200900. - u32 column;
  200901. - u8 val;
  200902. - bool comment;
  200903. - u32 token;
  200904. - __le32 token_le;
  200905. -
  200906. - /* Alloc for extra 0 byte + roundup by 4 + length field */
  200907. - nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);
  200908. - if (!nvram)
  200909. - return NULL;
  200910. -
  200911. - len = 0;
  200912. - column = 0;
  200913. - comment = false;
  200914. - for (i = 0; i < nv->size; i++) {
  200915. - val = nv->data[i];
  200916. - if (val == 0)
  200917. - break;
  200918. - if (val == '\r')
  200919. - continue;
  200920. - if (comment && (val != '\n'))
  200921. - continue;
  200922. - comment = false;
  200923. - if (val == '#') {
  200924. - comment = true;
  200925. - continue;
  200926. - }
  200927. - if (val == '\n') {
  200928. - if (column == 0)
  200929. - continue;
  200930. - nvram[len] = 0;
  200931. - len++;
  200932. - column = 0;
  200933. - continue;
  200934. - }
  200935. - nvram[len] = val;
  200936. - len++;
  200937. - column++;
  200938. - }
  200939. - column = len;
  200940. - *new_length = roundup(len + 1, 4);
  200941. - while (column != *new_length) {
  200942. - nvram[column] = 0;
  200943. - column++;
  200944. - }
  200945. -
  200946. - token = *new_length / 4;
  200947. - token = (~token << 16) | (token & 0x0000FFFF);
  200948. - token_le = cpu_to_le32(token);
  200949. -
  200950. - memcpy(&nvram[*new_length], &token_le, sizeof(token_le));
  200951. - *new_length += sizeof(token_le);
  200952. -
  200953. - return nvram;
  200954. -}
  200955. -
  200956. -void brcmf_nvram_free(void *nvram)
  200957. -{
  200958. - kfree(nvram);
  200959. -}
  200960. -
  200961. -
  200962. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/nvram.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.h
  200963. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/nvram.h 2014-08-14 03:38:34.000000000 +0200
  200964. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/nvram.h 1970-01-01 01:00:00.000000000 +0100
  200965. @@ -1,24 +0,0 @@
  200966. -/*
  200967. - * Copyright (c) 2013 Broadcom Corporation
  200968. - *
  200969. - * Permission to use, copy, modify, and/or distribute this software for any
  200970. - * purpose with or without fee is hereby granted, provided that the above
  200971. - * copyright notice and this permission notice appear in all copies.
  200972. - *
  200973. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  200974. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  200975. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  200976. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  200977. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  200978. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  200979. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  200980. - */
  200981. -#ifndef BRCMFMAC_NVRAM_H
  200982. -#define BRCMFMAC_NVRAM_H
  200983. -
  200984. -
  200985. -void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length);
  200986. -void brcmf_nvram_free(void *nvram);
  200987. -
  200988. -
  200989. -#endif /* BRCMFMAC_NVRAM_H */
  200990. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/p2p.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
  200991. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/p2p.c 2014-08-14 03:38:34.000000000 +0200
  200992. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/p2p.c 2014-09-11 18:06:03.906045582 +0200
  200993. @@ -797,7 +797,8 @@
  200994. /* SOCIAL CHANNELS 1, 6, 11 */
  200995. search_state = WL_P2P_DISC_ST_SEARCH;
  200996. brcmf_dbg(INFO, "P2P SEARCH PHASE START\n");
  200997. - } else if (dev != NULL && vif->mode == WL_MODE_AP) {
  200998. + } else if (dev != NULL &&
  200999. + vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
  201000. /* If you are already a GO, then do SEARCH only */
  201001. brcmf_dbg(INFO, "Already a GO. Do SEARCH Only\n");
  201002. search_state = WL_P2P_DISC_ST_SEARCH;
  201003. @@ -2256,7 +2257,6 @@
  201004. struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
  201005. struct brcmf_cfg80211_vif *vif;
  201006. enum brcmf_fil_p2p_if_types iftype;
  201007. - enum wl_mode mode;
  201008. int err;
  201009. if (brcmf_cfg80211_vif_event_armed(cfg))
  201010. @@ -2267,11 +2267,9 @@
  201011. switch (type) {
  201012. case NL80211_IFTYPE_P2P_CLIENT:
  201013. iftype = BRCMF_FIL_P2P_IF_CLIENT;
  201014. - mode = WL_MODE_BSS;
  201015. break;
  201016. case NL80211_IFTYPE_P2P_GO:
  201017. iftype = BRCMF_FIL_P2P_IF_GO;
  201018. - mode = WL_MODE_AP;
  201019. break;
  201020. case NL80211_IFTYPE_P2P_DEVICE:
  201021. return brcmf_p2p_create_p2pdev(&cfg->p2p, wiphy,
  201022. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
  201023. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c 2014-08-14 03:38:34.000000000 +0200
  201024. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c 1970-01-01 01:00:00.000000000 +0100
  201025. @@ -1,973 +0,0 @@
  201026. -/*
  201027. - * Copyright (c) 2011 Broadcom Corporation
  201028. - *
  201029. - * Permission to use, copy, modify, and/or distribute this software for any
  201030. - * purpose with or without fee is hereby granted, provided that the above
  201031. - * copyright notice and this permission notice appear in all copies.
  201032. - *
  201033. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  201034. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  201035. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  201036. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  201037. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  201038. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  201039. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  201040. - */
  201041. -/* ***** SDIO interface chip backplane handle functions ***** */
  201042. -
  201043. -#include <linux/types.h>
  201044. -#include <linux/netdevice.h>
  201045. -#include <linux/mmc/card.h>
  201046. -#include <linux/mmc/sdio_func.h>
  201047. -#include <linux/mmc/sdio_ids.h>
  201048. -#include <linux/ssb/ssb_regs.h>
  201049. -#include <linux/bcma/bcma.h>
  201050. -
  201051. -#include <chipcommon.h>
  201052. -#include <brcm_hw_ids.h>
  201053. -#include <brcmu_wifi.h>
  201054. -#include <brcmu_utils.h>
  201055. -#include <soc.h>
  201056. -#include "dhd_dbg.h"
  201057. -#include "sdio_host.h"
  201058. -#include "sdio_chip.h"
  201059. -
  201060. -/* chip core base & ramsize */
  201061. -/* bcm4329 */
  201062. -/* SDIO device core, ID 0x829 */
  201063. -#define BCM4329_CORE_BUS_BASE 0x18011000
  201064. -/* internal memory core, ID 0x80e */
  201065. -#define BCM4329_CORE_SOCRAM_BASE 0x18003000
  201066. -/* ARM Cortex M3 core, ID 0x82a */
  201067. -#define BCM4329_CORE_ARM_BASE 0x18002000
  201068. -#define BCM4329_RAMSIZE 0x48000
  201069. -
  201070. -/* bcm43143 */
  201071. -/* SDIO device core */
  201072. -#define BCM43143_CORE_BUS_BASE 0x18002000
  201073. -/* internal memory core */
  201074. -#define BCM43143_CORE_SOCRAM_BASE 0x18004000
  201075. -/* ARM Cortex M3 core, ID 0x82a */
  201076. -#define BCM43143_CORE_ARM_BASE 0x18003000
  201077. -#define BCM43143_RAMSIZE 0x70000
  201078. -
  201079. -/* All D11 cores, ID 0x812 */
  201080. -#define BCM43xx_CORE_D11_BASE 0x18001000
  201081. -
  201082. -#define SBCOREREV(sbidh) \
  201083. - ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
  201084. - ((sbidh) & SSB_IDHIGH_RCLO))
  201085. -
  201086. -/* SOC Interconnect types (aka chip types) */
  201087. -#define SOCI_SB 0
  201088. -#define SOCI_AI 1
  201089. -
  201090. -/* EROM CompIdentB */
  201091. -#define CIB_REV_MASK 0xff000000
  201092. -#define CIB_REV_SHIFT 24
  201093. -
  201094. -/* ARM CR4 core specific control flag bits */
  201095. -#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
  201096. -
  201097. -/* D11 core specific control flag bits */
  201098. -#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
  201099. -#define D11_BCMA_IOCTL_PHYRESET 0x0008
  201100. -
  201101. -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
  201102. -/* SDIO Pad drive strength to select value mappings */
  201103. -struct sdiod_drive_str {
  201104. - u8 strength; /* Pad Drive Strength in mA */
  201105. - u8 sel; /* Chip-specific select value */
  201106. -};
  201107. -/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
  201108. -static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
  201109. - {32, 0x6},
  201110. - {26, 0x7},
  201111. - {22, 0x4},
  201112. - {16, 0x5},
  201113. - {12, 0x2},
  201114. - {8, 0x3},
  201115. - {4, 0x0},
  201116. - {0, 0x1}
  201117. -};
  201118. -
  201119. -/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
  201120. -static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
  201121. - {6, 0x7},
  201122. - {5, 0x6},
  201123. - {4, 0x5},
  201124. - {3, 0x4},
  201125. - {2, 0x2},
  201126. - {1, 0x1},
  201127. - {0, 0x0}
  201128. -};
  201129. -
  201130. -/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
  201131. -static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
  201132. - {3, 0x3},
  201133. - {2, 0x2},
  201134. - {1, 0x1},
  201135. - {0, 0x0} };
  201136. -
  201137. -/* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
  201138. -static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
  201139. - {16, 0x7},
  201140. - {12, 0x5},
  201141. - {8, 0x3},
  201142. - {4, 0x1}
  201143. -};
  201144. -
  201145. -u8
  201146. -brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid)
  201147. -{
  201148. - u8 idx;
  201149. -
  201150. - for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
  201151. - if (coreid == ci->c_inf[idx].id)
  201152. - return idx;
  201153. -
  201154. - return BRCMF_MAX_CORENUM;
  201155. -}
  201156. -
  201157. -static u32
  201158. -brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
  201159. - struct brcmf_chip *ci, u16 coreid)
  201160. -{
  201161. - u32 regdata;
  201162. - u8 idx;
  201163. -
  201164. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201165. -
  201166. - regdata = brcmf_sdiod_regrl(sdiodev,
  201167. - CORE_SB(ci->c_inf[idx].base, sbidhigh),
  201168. - NULL);
  201169. - return SBCOREREV(regdata);
  201170. -}
  201171. -
  201172. -static u32
  201173. -brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
  201174. - struct brcmf_chip *ci, u16 coreid)
  201175. -{
  201176. - u8 idx;
  201177. -
  201178. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201179. -
  201180. - return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
  201181. -}
  201182. -
  201183. -static bool
  201184. -brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
  201185. - struct brcmf_chip *ci, u16 coreid)
  201186. -{
  201187. - u32 regdata;
  201188. - u8 idx;
  201189. -
  201190. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201191. - if (idx == BRCMF_MAX_CORENUM)
  201192. - return false;
  201193. -
  201194. - regdata = brcmf_sdiod_regrl(sdiodev,
  201195. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  201196. - NULL);
  201197. - regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
  201198. - SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
  201199. - return (SSB_TMSLOW_CLOCK == regdata);
  201200. -}
  201201. -
  201202. -static bool
  201203. -brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
  201204. - struct brcmf_chip *ci, u16 coreid)
  201205. -{
  201206. - u32 regdata;
  201207. - u8 idx;
  201208. - bool ret;
  201209. -
  201210. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201211. - if (idx == BRCMF_MAX_CORENUM)
  201212. - return false;
  201213. -
  201214. - regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
  201215. - NULL);
  201216. - ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
  201217. -
  201218. - regdata = brcmf_sdiod_regrl(sdiodev,
  201219. - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
  201220. - NULL);
  201221. - ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
  201222. -
  201223. - return ret;
  201224. -}
  201225. -
  201226. -static void
  201227. -brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
  201228. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  201229. - u32 in_resetbits)
  201230. -{
  201231. - u32 regdata, base;
  201232. - u8 idx;
  201233. -
  201234. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201235. - base = ci->c_inf[idx].base;
  201236. -
  201237. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
  201238. - if (regdata & SSB_TMSLOW_RESET)
  201239. - return;
  201240. -
  201241. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
  201242. - if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
  201243. - /*
  201244. - * set target reject and spin until busy is clear
  201245. - * (preserve core-specific bits)
  201246. - */
  201247. - regdata = brcmf_sdiod_regrl(sdiodev,
  201248. - CORE_SB(base, sbtmstatelow), NULL);
  201249. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  201250. - regdata | SSB_TMSLOW_REJECT, NULL);
  201251. -
  201252. - regdata = brcmf_sdiod_regrl(sdiodev,
  201253. - CORE_SB(base, sbtmstatelow), NULL);
  201254. - udelay(1);
  201255. - SPINWAIT((brcmf_sdiod_regrl(sdiodev,
  201256. - CORE_SB(base, sbtmstatehigh),
  201257. - NULL) &
  201258. - SSB_TMSHIGH_BUSY), 100000);
  201259. -
  201260. - regdata = brcmf_sdiod_regrl(sdiodev,
  201261. - CORE_SB(base, sbtmstatehigh),
  201262. - NULL);
  201263. - if (regdata & SSB_TMSHIGH_BUSY)
  201264. - brcmf_err("core state still busy\n");
  201265. -
  201266. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
  201267. - NULL);
  201268. - if (regdata & SSB_IDLOW_INITIATOR) {
  201269. - regdata = brcmf_sdiod_regrl(sdiodev,
  201270. - CORE_SB(base, sbimstate),
  201271. - NULL);
  201272. - regdata |= SSB_IMSTATE_REJECT;
  201273. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
  201274. - regdata, NULL);
  201275. - regdata = brcmf_sdiod_regrl(sdiodev,
  201276. - CORE_SB(base, sbimstate),
  201277. - NULL);
  201278. - udelay(1);
  201279. - SPINWAIT((brcmf_sdiod_regrl(sdiodev,
  201280. - CORE_SB(base, sbimstate),
  201281. - NULL) &
  201282. - SSB_IMSTATE_BUSY), 100000);
  201283. - }
  201284. -
  201285. - /* set reset and reject while enabling the clocks */
  201286. - regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
  201287. - SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
  201288. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  201289. - regdata, NULL);
  201290. - regdata = brcmf_sdiod_regrl(sdiodev,
  201291. - CORE_SB(base, sbtmstatelow), NULL);
  201292. - udelay(10);
  201293. -
  201294. - /* clear the initiator reject bit */
  201295. - regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
  201296. - NULL);
  201297. - if (regdata & SSB_IDLOW_INITIATOR) {
  201298. - regdata = brcmf_sdiod_regrl(sdiodev,
  201299. - CORE_SB(base, sbimstate),
  201300. - NULL);
  201301. - regdata &= ~SSB_IMSTATE_REJECT;
  201302. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
  201303. - regdata, NULL);
  201304. - }
  201305. - }
  201306. -
  201307. - /* leave reset and reject asserted */
  201308. - brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
  201309. - (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
  201310. - udelay(1);
  201311. -}
  201312. -
  201313. -static void
  201314. -brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
  201315. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  201316. - u32 in_resetbits)
  201317. -{
  201318. - u8 idx;
  201319. - u32 regdata;
  201320. - u32 wrapbase;
  201321. -
  201322. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201323. - if (idx == BRCMF_MAX_CORENUM)
  201324. - return;
  201325. -
  201326. - wrapbase = ci->c_inf[idx].wrapbase;
  201327. -
  201328. - /* if core is already in reset, skip reset */
  201329. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL);
  201330. - if ((regdata & BCMA_RESET_CTL_RESET) != 0)
  201331. - goto post_reset_config;
  201332. -
  201333. - /* configure reset */
  201334. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
  201335. - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
  201336. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  201337. -
  201338. - /* put in reset */
  201339. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL,
  201340. - BCMA_RESET_CTL_RESET, NULL);
  201341. - usleep_range(10, 20);
  201342. -
  201343. - /* wait till reset is 1 */
  201344. - SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) !=
  201345. - BCMA_RESET_CTL_RESET, 300);
  201346. -
  201347. -post_reset_config:
  201348. - /* post reset configure */
  201349. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits |
  201350. - BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
  201351. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  201352. -}
  201353. -
  201354. -static void
  201355. -brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
  201356. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  201357. - u32 in_resetbits, u32 post_resetbits)
  201358. -{
  201359. - u32 regdata;
  201360. - u8 idx;
  201361. -
  201362. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201363. - if (idx == BRCMF_MAX_CORENUM)
  201364. - return;
  201365. -
  201366. - /*
  201367. - * Must do the disable sequence first to work for
  201368. - * arbitrary current core state.
  201369. - */
  201370. - brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
  201371. - in_resetbits);
  201372. -
  201373. - /*
  201374. - * Now do the initialization sequence.
  201375. - * set reset while enabling the clock and
  201376. - * forcing them on throughout the core
  201377. - */
  201378. - brcmf_sdiod_regwl(sdiodev,
  201379. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  201380. - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
  201381. - NULL);
  201382. - regdata = brcmf_sdiod_regrl(sdiodev,
  201383. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  201384. - NULL);
  201385. - udelay(1);
  201386. -
  201387. - /* clear any serror */
  201388. - regdata = brcmf_sdiod_regrl(sdiodev,
  201389. - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
  201390. - NULL);
  201391. - if (regdata & SSB_TMSHIGH_SERR)
  201392. - brcmf_sdiod_regwl(sdiodev,
  201393. - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
  201394. - 0, NULL);
  201395. -
  201396. - regdata = brcmf_sdiod_regrl(sdiodev,
  201397. - CORE_SB(ci->c_inf[idx].base, sbimstate),
  201398. - NULL);
  201399. - if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
  201400. - brcmf_sdiod_regwl(sdiodev,
  201401. - CORE_SB(ci->c_inf[idx].base, sbimstate),
  201402. - regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
  201403. - NULL);
  201404. -
  201405. - /* clear reset and allow it to propagate throughout the core */
  201406. - brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  201407. - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
  201408. - regdata = brcmf_sdiod_regrl(sdiodev,
  201409. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  201410. - NULL);
  201411. - udelay(1);
  201412. -
  201413. - /* leave clock enabled */
  201414. - brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  201415. - SSB_TMSLOW_CLOCK, NULL);
  201416. - regdata = brcmf_sdiod_regrl(sdiodev,
  201417. - CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
  201418. - NULL);
  201419. - udelay(1);
  201420. -}
  201421. -
  201422. -static void
  201423. -brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
  201424. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  201425. - u32 in_resetbits, u32 post_resetbits)
  201426. -{
  201427. - u8 idx;
  201428. - u32 regdata;
  201429. - u32 wrapbase;
  201430. -
  201431. - idx = brcmf_sdio_chip_getinfidx(ci, coreid);
  201432. - if (idx == BRCMF_MAX_CORENUM)
  201433. - return;
  201434. -
  201435. - wrapbase = ci->c_inf[idx].wrapbase;
  201436. -
  201437. - /* must disable first to work for arbitrary current core state */
  201438. - brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits,
  201439. - in_resetbits);
  201440. -
  201441. - while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) &
  201442. - BCMA_RESET_CTL_RESET) {
  201443. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL);
  201444. - usleep_range(40, 60);
  201445. - }
  201446. -
  201447. - brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits |
  201448. - BCMA_IOCTL_CLK, NULL);
  201449. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  201450. -}
  201451. -
  201452. -#ifdef DEBUG
  201453. -/* safety check for chipinfo */
  201454. -static int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
  201455. -{
  201456. - u8 core_idx;
  201457. -
  201458. - /* check RAM core presence for ARM CM3 core */
  201459. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  201460. - if (BRCMF_MAX_CORENUM != core_idx) {
  201461. - core_idx = brcmf_sdio_chip_getinfidx(ci,
  201462. - BCMA_CORE_INTERNAL_MEM);
  201463. - if (BRCMF_MAX_CORENUM == core_idx) {
  201464. - brcmf_err("RAM core not provided with ARM CM3 core\n");
  201465. - return -ENODEV;
  201466. - }
  201467. - }
  201468. -
  201469. - /* check RAM base for ARM CR4 core */
  201470. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
  201471. - if (BRCMF_MAX_CORENUM != core_idx) {
  201472. - if (ci->rambase == 0) {
  201473. - brcmf_err("RAM base not provided with ARM CR4 core\n");
  201474. - return -ENOMEM;
  201475. - }
  201476. - }
  201477. -
  201478. - return 0;
  201479. -}
  201480. -#else /* DEBUG */
  201481. -static inline int brcmf_sdio_chip_cichk(struct brcmf_chip *ci)
  201482. -{
  201483. - return 0;
  201484. -}
  201485. -#endif
  201486. -
  201487. -static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
  201488. - struct brcmf_chip *ci)
  201489. -{
  201490. - u32 regdata;
  201491. - u32 socitype;
  201492. -
  201493. - /* Get CC core rev
  201494. - * Chipid is assume to be at offset 0 from SI_ENUM_BASE
  201495. - * For different chiptypes or old sdio hosts w/o chipcommon,
  201496. - * other ways of recognition should be added here.
  201497. - */
  201498. - regdata = brcmf_sdiod_regrl(sdiodev,
  201499. - CORE_CC_REG(SI_ENUM_BASE, chipid),
  201500. - NULL);
  201501. - ci->chip = regdata & CID_ID_MASK;
  201502. - ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
  201503. - if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
  201504. - ci->chiprev >= 2)
  201505. - ci->chip = BCM4339_CHIP_ID;
  201506. - socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  201507. -
  201508. - brcmf_dbg(INFO, "found %s chip: id=0x%x, rev=%d\n",
  201509. - socitype == SOCI_SB ? "SB" : "AXI", ci->chip, ci->chiprev);
  201510. -
  201511. - if (socitype == SOCI_SB) {
  201512. - if (ci->chip != BCM4329_CHIP_ID) {
  201513. - brcmf_err("SB chip is not supported\n");
  201514. - return -ENODEV;
  201515. - }
  201516. - ci->iscoreup = brcmf_sdio_sb_iscoreup;
  201517. - ci->corerev = brcmf_sdio_sb_corerev;
  201518. - ci->coredisable = brcmf_sdio_sb_coredisable;
  201519. - ci->resetcore = brcmf_sdio_sb_resetcore;
  201520. -
  201521. - ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
  201522. - ci->c_inf[0].base = SI_ENUM_BASE;
  201523. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201524. - ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
  201525. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  201526. - ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
  201527. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  201528. - ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
  201529. - ci->c_inf[4].id = BCMA_CORE_80211;
  201530. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  201531. - ci->ramsize = BCM4329_RAMSIZE;
  201532. - } else if (socitype == SOCI_AI) {
  201533. - ci->iscoreup = brcmf_sdio_ai_iscoreup;
  201534. - ci->corerev = brcmf_sdio_ai_corerev;
  201535. - ci->coredisable = brcmf_sdio_ai_coredisable;
  201536. - ci->resetcore = brcmf_sdio_ai_resetcore;
  201537. -
  201538. - ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
  201539. - ci->c_inf[0].base = SI_ENUM_BASE;
  201540. -
  201541. - /* Address of cores for new chips should be added here */
  201542. - switch (ci->chip) {
  201543. - case BCM43143_CHIP_ID:
  201544. - ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000;
  201545. - ci->c_inf[0].cib = 0x2b000000;
  201546. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201547. - ci->c_inf[1].base = BCM43143_CORE_BUS_BASE;
  201548. - ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000;
  201549. - ci->c_inf[1].cib = 0x18000000;
  201550. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  201551. - ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE;
  201552. - ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000;
  201553. - ci->c_inf[2].cib = 0x14000000;
  201554. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  201555. - ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
  201556. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  201557. - ci->c_inf[3].cib = 0x07000000;
  201558. - ci->c_inf[4].id = BCMA_CORE_80211;
  201559. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  201560. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  201561. - ci->ramsize = BCM43143_RAMSIZE;
  201562. - break;
  201563. - case BCM43241_CHIP_ID:
  201564. - ci->c_inf[0].wrapbase = 0x18100000;
  201565. - ci->c_inf[0].cib = 0x2a084411;
  201566. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201567. - ci->c_inf[1].base = 0x18002000;
  201568. - ci->c_inf[1].wrapbase = 0x18102000;
  201569. - ci->c_inf[1].cib = 0x0e004211;
  201570. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  201571. - ci->c_inf[2].base = 0x18004000;
  201572. - ci->c_inf[2].wrapbase = 0x18104000;
  201573. - ci->c_inf[2].cib = 0x14080401;
  201574. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  201575. - ci->c_inf[3].base = 0x18003000;
  201576. - ci->c_inf[3].wrapbase = 0x18103000;
  201577. - ci->c_inf[3].cib = 0x07004211;
  201578. - ci->c_inf[4].id = BCMA_CORE_80211;
  201579. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  201580. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  201581. - ci->ramsize = 0x90000;
  201582. - break;
  201583. - case BCM4330_CHIP_ID:
  201584. - ci->c_inf[0].wrapbase = 0x18100000;
  201585. - ci->c_inf[0].cib = 0x27004211;
  201586. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201587. - ci->c_inf[1].base = 0x18002000;
  201588. - ci->c_inf[1].wrapbase = 0x18102000;
  201589. - ci->c_inf[1].cib = 0x07004211;
  201590. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  201591. - ci->c_inf[2].base = 0x18004000;
  201592. - ci->c_inf[2].wrapbase = 0x18104000;
  201593. - ci->c_inf[2].cib = 0x0d080401;
  201594. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  201595. - ci->c_inf[3].base = 0x18003000;
  201596. - ci->c_inf[3].wrapbase = 0x18103000;
  201597. - ci->c_inf[3].cib = 0x03004211;
  201598. - ci->c_inf[4].id = BCMA_CORE_80211;
  201599. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  201600. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  201601. - ci->ramsize = 0x48000;
  201602. - break;
  201603. - case BCM4334_CHIP_ID:
  201604. - ci->c_inf[0].wrapbase = 0x18100000;
  201605. - ci->c_inf[0].cib = 0x29004211;
  201606. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201607. - ci->c_inf[1].base = 0x18002000;
  201608. - ci->c_inf[1].wrapbase = 0x18102000;
  201609. - ci->c_inf[1].cib = 0x0d004211;
  201610. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  201611. - ci->c_inf[2].base = 0x18004000;
  201612. - ci->c_inf[2].wrapbase = 0x18104000;
  201613. - ci->c_inf[2].cib = 0x13080401;
  201614. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  201615. - ci->c_inf[3].base = 0x18003000;
  201616. - ci->c_inf[3].wrapbase = 0x18103000;
  201617. - ci->c_inf[3].cib = 0x07004211;
  201618. - ci->c_inf[4].id = BCMA_CORE_80211;
  201619. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  201620. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  201621. - ci->ramsize = 0x80000;
  201622. - break;
  201623. - case BCM4335_CHIP_ID:
  201624. - ci->c_inf[0].wrapbase = 0x18100000;
  201625. - ci->c_inf[0].cib = 0x2b084411;
  201626. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201627. - ci->c_inf[1].base = 0x18005000;
  201628. - ci->c_inf[1].wrapbase = 0x18105000;
  201629. - ci->c_inf[1].cib = 0x0f004211;
  201630. - ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
  201631. - ci->c_inf[2].base = 0x18002000;
  201632. - ci->c_inf[2].wrapbase = 0x18102000;
  201633. - ci->c_inf[2].cib = 0x01084411;
  201634. - ci->c_inf[3].id = BCMA_CORE_80211;
  201635. - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
  201636. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  201637. - ci->ramsize = 0xc0000;
  201638. - ci->rambase = 0x180000;
  201639. - break;
  201640. - case BCM43362_CHIP_ID:
  201641. - ci->c_inf[0].wrapbase = 0x18100000;
  201642. - ci->c_inf[0].cib = 0x27004211;
  201643. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201644. - ci->c_inf[1].base = 0x18002000;
  201645. - ci->c_inf[1].wrapbase = 0x18102000;
  201646. - ci->c_inf[1].cib = 0x0a004211;
  201647. - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
  201648. - ci->c_inf[2].base = 0x18004000;
  201649. - ci->c_inf[2].wrapbase = 0x18104000;
  201650. - ci->c_inf[2].cib = 0x08080401;
  201651. - ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
  201652. - ci->c_inf[3].base = 0x18003000;
  201653. - ci->c_inf[3].wrapbase = 0x18103000;
  201654. - ci->c_inf[3].cib = 0x03004211;
  201655. - ci->c_inf[4].id = BCMA_CORE_80211;
  201656. - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE;
  201657. - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000;
  201658. - ci->ramsize = 0x3C000;
  201659. - break;
  201660. - case BCM4339_CHIP_ID:
  201661. - ci->c_inf[0].wrapbase = 0x18100000;
  201662. - ci->c_inf[0].cib = 0x2e084411;
  201663. - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
  201664. - ci->c_inf[1].base = 0x18005000;
  201665. - ci->c_inf[1].wrapbase = 0x18105000;
  201666. - ci->c_inf[1].cib = 0x15004211;
  201667. - ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
  201668. - ci->c_inf[2].base = 0x18002000;
  201669. - ci->c_inf[2].wrapbase = 0x18102000;
  201670. - ci->c_inf[2].cib = 0x04084411;
  201671. - ci->c_inf[3].id = BCMA_CORE_80211;
  201672. - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE;
  201673. - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
  201674. - ci->ramsize = 0xc0000;
  201675. - ci->rambase = 0x180000;
  201676. - break;
  201677. - default:
  201678. - brcmf_err("AXI chip is not supported\n");
  201679. - return -ENODEV;
  201680. - }
  201681. - } else {
  201682. - brcmf_err("chip backplane type %u is not supported\n",
  201683. - socitype);
  201684. - return -ENODEV;
  201685. - }
  201686. -
  201687. - return brcmf_sdio_chip_cichk(ci);
  201688. -}
  201689. -
  201690. -static int
  201691. -brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
  201692. -{
  201693. - int err = 0;
  201694. - u8 clkval, clkset;
  201695. -
  201696. - /* Try forcing SDIO core to do ALPAvail request only */
  201697. - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  201698. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  201699. - if (err) {
  201700. - brcmf_err("error writing for HT off\n");
  201701. - return err;
  201702. - }
  201703. -
  201704. - /* If register supported, wait for ALPAvail and then force ALP */
  201705. - /* This may take up to 15 milliseconds */
  201706. - clkval = brcmf_sdiod_regrb(sdiodev,
  201707. - SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  201708. -
  201709. - if ((clkval & ~SBSDIO_AVBITS) != clkset) {
  201710. - brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
  201711. - clkset, clkval);
  201712. - return -EACCES;
  201713. - }
  201714. -
  201715. - SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
  201716. - SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
  201717. - !SBSDIO_ALPAV(clkval)),
  201718. - PMU_MAX_TRANSITION_DLY);
  201719. - if (!SBSDIO_ALPAV(clkval)) {
  201720. - brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
  201721. - clkval);
  201722. - return -EBUSY;
  201723. - }
  201724. -
  201725. - clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  201726. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  201727. - udelay(65);
  201728. -
  201729. - /* Also, disable the extra SDIO pull-ups */
  201730. - brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  201731. -
  201732. - return 0;
  201733. -}
  201734. -
  201735. -static void
  201736. -brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
  201737. - struct brcmf_chip *ci)
  201738. -{
  201739. - u32 base = ci->c_inf[0].base;
  201740. -
  201741. - /* get chipcommon rev */
  201742. - ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
  201743. -
  201744. - /* get chipcommon capabilites */
  201745. - ci->c_inf[0].caps = brcmf_sdiod_regrl(sdiodev,
  201746. - CORE_CC_REG(base, capabilities),
  201747. - NULL);
  201748. -
  201749. - /* get pmu caps & rev */
  201750. - if (ci->c_inf[0].caps & CC_CAP_PMU) {
  201751. - ci->pmucaps =
  201752. - brcmf_sdiod_regrl(sdiodev,
  201753. - CORE_CC_REG(base, pmucapabilities),
  201754. - NULL);
  201755. - ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
  201756. - }
  201757. -
  201758. - ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
  201759. -
  201760. - brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
  201761. - ci->c_inf[0].rev, ci->pmurev,
  201762. - ci->c_inf[1].rev, ci->c_inf[1].id);
  201763. -
  201764. - /*
  201765. - * Make sure any on-chip ARM is off (in case strapping is wrong),
  201766. - * or downloaded code was already running.
  201767. - */
  201768. - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
  201769. -}
  201770. -
  201771. -int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  201772. - struct brcmf_chip **ci_ptr)
  201773. -{
  201774. - int ret;
  201775. - struct brcmf_chip *ci;
  201776. -
  201777. - brcmf_dbg(TRACE, "Enter\n");
  201778. -
  201779. - ci = kzalloc(sizeof(*ci), GFP_ATOMIC);
  201780. - if (!ci)
  201781. - return -ENOMEM;
  201782. -
  201783. - ret = brcmf_sdio_chip_buscoreprep(sdiodev);
  201784. - if (ret != 0)
  201785. - goto err;
  201786. -
  201787. - ret = brcmf_sdio_chip_recognition(sdiodev, ci);
  201788. - if (ret != 0)
  201789. - goto err;
  201790. -
  201791. - brcmf_sdio_chip_buscoresetup(sdiodev, ci);
  201792. -
  201793. - brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
  201794. - 0, NULL);
  201795. - brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
  201796. - 0, NULL);
  201797. -
  201798. - *ci_ptr = ci;
  201799. - return 0;
  201800. -
  201801. -err:
  201802. - kfree(ci);
  201803. - return ret;
  201804. -}
  201805. -
  201806. -void
  201807. -brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr)
  201808. -{
  201809. - brcmf_dbg(TRACE, "Enter\n");
  201810. -
  201811. - kfree(*ci_ptr);
  201812. - *ci_ptr = NULL;
  201813. -}
  201814. -
  201815. -static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
  201816. -{
  201817. - const char *fmt;
  201818. -
  201819. - fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
  201820. - snprintf(buf, len, fmt, chipid);
  201821. - return buf;
  201822. -}
  201823. -
  201824. -void
  201825. -brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  201826. - struct brcmf_chip *ci, u32 drivestrength)
  201827. -{
  201828. - const struct sdiod_drive_str *str_tab = NULL;
  201829. - u32 str_mask;
  201830. - u32 str_shift;
  201831. - char chn[8];
  201832. - u32 base = ci->c_inf[0].base;
  201833. - u32 i;
  201834. - u32 drivestrength_sel = 0;
  201835. - u32 cc_data_temp;
  201836. - u32 addr;
  201837. -
  201838. - if (!(ci->c_inf[0].caps & CC_CAP_PMU))
  201839. - return;
  201840. -
  201841. - switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
  201842. - case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
  201843. - str_tab = sdiod_drvstr_tab1_1v8;
  201844. - str_mask = 0x00003800;
  201845. - str_shift = 11;
  201846. - break;
  201847. - case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
  201848. - str_tab = sdiod_drvstr_tab6_1v8;
  201849. - str_mask = 0x00001800;
  201850. - str_shift = 11;
  201851. - break;
  201852. - case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
  201853. - /* note: 43143 does not support tristate */
  201854. - i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
  201855. - if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
  201856. - str_tab = sdiod_drvstr_tab2_3v3;
  201857. - str_mask = 0x00000007;
  201858. - str_shift = 0;
  201859. - } else
  201860. - brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
  201861. - brcmf_sdio_chip_name(ci->chip, chn, 8),
  201862. - drivestrength);
  201863. - break;
  201864. - case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
  201865. - str_tab = sdiod_drive_strength_tab5_1v8;
  201866. - str_mask = 0x00003800;
  201867. - str_shift = 11;
  201868. - break;
  201869. - default:
  201870. - brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
  201871. - brcmf_sdio_chip_name(ci->chip, chn, 8),
  201872. - ci->chiprev, ci->pmurev);
  201873. - break;
  201874. - }
  201875. -
  201876. - if (str_tab != NULL) {
  201877. - for (i = 0; str_tab[i].strength != 0; i++) {
  201878. - if (drivestrength >= str_tab[i].strength) {
  201879. - drivestrength_sel = str_tab[i].sel;
  201880. - break;
  201881. - }
  201882. - }
  201883. - addr = CORE_CC_REG(base, chipcontrol_addr);
  201884. - brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
  201885. - cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
  201886. - cc_data_temp &= ~str_mask;
  201887. - drivestrength_sel <<= str_shift;
  201888. - cc_data_temp |= drivestrength_sel;
  201889. - brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
  201890. -
  201891. - brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
  201892. - str_tab[i].strength, drivestrength, cc_data_temp);
  201893. - }
  201894. -}
  201895. -
  201896. -static void
  201897. -brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
  201898. - struct brcmf_chip *ci)
  201899. -{
  201900. - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0);
  201901. - ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
  201902. - D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
  201903. - D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
  201904. - ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0);
  201905. -}
  201906. -
  201907. -static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev,
  201908. - struct brcmf_chip *ci)
  201909. -{
  201910. - u8 core_idx;
  201911. - u32 reg_addr;
  201912. -
  201913. - if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
  201914. - brcmf_err("SOCRAM core is down after reset?\n");
  201915. - return false;
  201916. - }
  201917. -
  201918. - /* clear all interrupts */
  201919. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
  201920. - reg_addr = ci->c_inf[core_idx].base;
  201921. - reg_addr += offsetof(struct sdpcmd_regs, intstatus);
  201922. - brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  201923. -
  201924. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0);
  201925. -
  201926. - return true;
  201927. -}
  201928. -
  201929. -static inline void
  201930. -brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
  201931. - struct brcmf_chip *ci)
  201932. -{
  201933. - u8 idx;
  201934. - u32 regdata;
  201935. - u32 wrapbase;
  201936. - idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
  201937. -
  201938. - if (idx == BRCMF_MAX_CORENUM)
  201939. - return;
  201940. -
  201941. - wrapbase = ci->c_inf[idx].wrapbase;
  201942. - regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL);
  201943. - regdata &= ARMCR4_BCMA_IOCTL_CPUHALT;
  201944. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata,
  201945. - ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT);
  201946. - ci->resetcore(sdiodev, ci, BCMA_CORE_80211,
  201947. - D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN,
  201948. - D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN);
  201949. -}
  201950. -
  201951. -static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev,
  201952. - struct brcmf_chip *ci, u32 rstvec)
  201953. -{
  201954. - u8 core_idx;
  201955. - u32 reg_addr;
  201956. -
  201957. - /* clear all interrupts */
  201958. - core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
  201959. - reg_addr = ci->c_inf[core_idx].base;
  201960. - reg_addr += offsetof(struct sdpcmd_regs, intstatus);
  201961. - brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
  201962. -
  201963. - /* Write reset vector to address 0 */
  201964. - brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec,
  201965. - sizeof(rstvec));
  201966. -
  201967. - /* restore ARM */
  201968. - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT,
  201969. - 0, 0);
  201970. -
  201971. - return true;
  201972. -}
  201973. -
  201974. -void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
  201975. - struct brcmf_chip *ci)
  201976. -{
  201977. - u8 arm_core_idx;
  201978. -
  201979. - arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  201980. - if (BRCMF_MAX_CORENUM != arm_core_idx) {
  201981. - brcmf_sdio_chip_cm3_enterdl(sdiodev, ci);
  201982. - return;
  201983. - }
  201984. -
  201985. - brcmf_sdio_chip_cr4_enterdl(sdiodev, ci);
  201986. -}
  201987. -
  201988. -bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
  201989. - struct brcmf_chip *ci, u32 rstvec)
  201990. -{
  201991. - u8 arm_core_idx;
  201992. -
  201993. - arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
  201994. - if (BRCMF_MAX_CORENUM != arm_core_idx)
  201995. - return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci);
  201996. -
  201997. - return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, rstvec);
  201998. -}
  201999. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
  202000. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h 2014-08-14 03:38:34.000000000 +0200
  202001. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h 1970-01-01 01:00:00.000000000 +0100
  202002. @@ -1,231 +0,0 @@
  202003. -/*
  202004. - * Copyright (c) 2011 Broadcom Corporation
  202005. - *
  202006. - * Permission to use, copy, modify, and/or distribute this software for any
  202007. - * purpose with or without fee is hereby granted, provided that the above
  202008. - * copyright notice and this permission notice appear in all copies.
  202009. - *
  202010. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  202011. - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  202012. - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  202013. - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  202014. - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  202015. - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  202016. - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  202017. - */
  202018. -
  202019. -#ifndef _BRCMFMAC_SDIO_CHIP_H_
  202020. -#define _BRCMFMAC_SDIO_CHIP_H_
  202021. -
  202022. -/*
  202023. - * Core reg address translation.
  202024. - * Both macro's returns a 32 bits byte address on the backplane bus.
  202025. - */
  202026. -#define CORE_CC_REG(base, field) \
  202027. - (base + offsetof(struct chipcregs, field))
  202028. -#define CORE_BUS_REG(base, field) \
  202029. - (base + offsetof(struct sdpcmd_regs, field))
  202030. -#define CORE_SB(base, field) \
  202031. - (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
  202032. -
  202033. -/* SDIO function 1 register CHIPCLKCSR */
  202034. -/* Force ALP request to backplane */
  202035. -#define SBSDIO_FORCE_ALP 0x01
  202036. -/* Force HT request to backplane */
  202037. -#define SBSDIO_FORCE_HT 0x02
  202038. -/* Force ILP request to backplane */
  202039. -#define SBSDIO_FORCE_ILP 0x04
  202040. -/* Make ALP ready (power up xtal) */
  202041. -#define SBSDIO_ALP_AVAIL_REQ 0x08
  202042. -/* Make HT ready (power up PLL) */
  202043. -#define SBSDIO_HT_AVAIL_REQ 0x10
  202044. -/* Squelch clock requests from HW */
  202045. -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
  202046. -/* Status: ALP is ready */
  202047. -#define SBSDIO_ALP_AVAIL 0x40
  202048. -/* Status: HT is ready */
  202049. -#define SBSDIO_HT_AVAIL 0x80
  202050. -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
  202051. -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS)
  202052. -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
  202053. -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
  202054. -#define SBSDIO_CLKAV(regval, alponly) \
  202055. - (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
  202056. -
  202057. -#define BRCMF_MAX_CORENUM 6
  202058. -
  202059. -struct brcmf_core {
  202060. - u16 id;
  202061. - u16 rev;
  202062. - u32 base;
  202063. - u32 wrapbase;
  202064. - u32 caps;
  202065. - u32 cib;
  202066. -};
  202067. -
  202068. -struct brcmf_chip {
  202069. - u32 chip;
  202070. - u32 chiprev;
  202071. - /* core info */
  202072. - /* always put chipcommon core at 0, bus core at 1 */
  202073. - struct brcmf_core c_inf[BRCMF_MAX_CORENUM];
  202074. - u32 pmurev;
  202075. - u32 pmucaps;
  202076. - u32 ramsize;
  202077. - u32 rambase;
  202078. - u32 rst_vec; /* reset vertor for ARM CR4 core */
  202079. -
  202080. - bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
  202081. - u16 coreid);
  202082. - u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci,
  202083. - u16 coreid);
  202084. - void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
  202085. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  202086. - u32 in_resetbits);
  202087. - void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
  202088. - struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits,
  202089. - u32 in_resetbits, u32 post_resetbits);
  202090. -};
  202091. -
  202092. -struct sbconfig {
  202093. - u32 PAD[2];
  202094. - u32 sbipsflag; /* initiator port ocp slave flag */
  202095. - u32 PAD[3];
  202096. - u32 sbtpsflag; /* target port ocp slave flag */
  202097. - u32 PAD[11];
  202098. - u32 sbtmerrloga; /* (sonics >= 2.3) */
  202099. - u32 PAD;
  202100. - u32 sbtmerrlog; /* (sonics >= 2.3) */
  202101. - u32 PAD[3];
  202102. - u32 sbadmatch3; /* address match3 */
  202103. - u32 PAD;
  202104. - u32 sbadmatch2; /* address match2 */
  202105. - u32 PAD;
  202106. - u32 sbadmatch1; /* address match1 */
  202107. - u32 PAD[7];
  202108. - u32 sbimstate; /* initiator agent state */
  202109. - u32 sbintvec; /* interrupt mask */
  202110. - u32 sbtmstatelow; /* target state */
  202111. - u32 sbtmstatehigh; /* target state */
  202112. - u32 sbbwa0; /* bandwidth allocation table0 */
  202113. - u32 PAD;
  202114. - u32 sbimconfiglow; /* initiator configuration */
  202115. - u32 sbimconfighigh; /* initiator configuration */
  202116. - u32 sbadmatch0; /* address match0 */
  202117. - u32 PAD;
  202118. - u32 sbtmconfiglow; /* target configuration */
  202119. - u32 sbtmconfighigh; /* target configuration */
  202120. - u32 sbbconfig; /* broadcast configuration */
  202121. - u32 PAD;
  202122. - u32 sbbstate; /* broadcast state */
  202123. - u32 PAD[3];
  202124. - u32 sbactcnfg; /* activate configuration */
  202125. - u32 PAD[3];
  202126. - u32 sbflagst; /* current sbflags */
  202127. - u32 PAD[3];
  202128. - u32 sbidlow; /* identification */
  202129. - u32 sbidhigh; /* identification */
  202130. -};
  202131. -
  202132. -/* sdio core registers */
  202133. -struct sdpcmd_regs {
  202134. - u32 corecontrol; /* 0x00, rev8 */
  202135. - u32 corestatus; /* rev8 */
  202136. - u32 PAD[1];
  202137. - u32 biststatus; /* rev8 */
  202138. -
  202139. - /* PCMCIA access */
  202140. - u16 pcmciamesportaladdr; /* 0x010, rev8 */
  202141. - u16 PAD[1];
  202142. - u16 pcmciamesportalmask; /* rev8 */
  202143. - u16 PAD[1];
  202144. - u16 pcmciawrframebc; /* rev8 */
  202145. - u16 PAD[1];
  202146. - u16 pcmciaunderflowtimer; /* rev8 */
  202147. - u16 PAD[1];
  202148. -
  202149. - /* interrupt */
  202150. - u32 intstatus; /* 0x020, rev8 */
  202151. - u32 hostintmask; /* rev8 */
  202152. - u32 intmask; /* rev8 */
  202153. - u32 sbintstatus; /* rev8 */
  202154. - u32 sbintmask; /* rev8 */
  202155. - u32 funcintmask; /* rev4 */
  202156. - u32 PAD[2];
  202157. - u32 tosbmailbox; /* 0x040, rev8 */
  202158. - u32 tohostmailbox; /* rev8 */
  202159. - u32 tosbmailboxdata; /* rev8 */
  202160. - u32 tohostmailboxdata; /* rev8 */
  202161. -
  202162. - /* synchronized access to registers in SDIO clock domain */
  202163. - u32 sdioaccess; /* 0x050, rev8 */
  202164. - u32 PAD[3];
  202165. -
  202166. - /* PCMCIA frame control */
  202167. - u8 pcmciaframectrl; /* 0x060, rev8 */
  202168. - u8 PAD[3];
  202169. - u8 pcmciawatermark; /* rev8 */
  202170. - u8 PAD[155];
  202171. -
  202172. - /* interrupt batching control */
  202173. - u32 intrcvlazy; /* 0x100, rev8 */
  202174. - u32 PAD[3];
  202175. -
  202176. - /* counters */
  202177. - u32 cmd52rd; /* 0x110, rev8 */
  202178. - u32 cmd52wr; /* rev8 */
  202179. - u32 cmd53rd; /* rev8 */
  202180. - u32 cmd53wr; /* rev8 */
  202181. - u32 abort; /* rev8 */
  202182. - u32 datacrcerror; /* rev8 */
  202183. - u32 rdoutofsync; /* rev8 */
  202184. - u32 wroutofsync; /* rev8 */
  202185. - u32 writebusy; /* rev8 */
  202186. - u32 readwait; /* rev8 */
  202187. - u32 readterm; /* rev8 */
  202188. - u32 writeterm; /* rev8 */
  202189. - u32 PAD[40];
  202190. - u32 clockctlstatus; /* rev8 */
  202191. - u32 PAD[7];
  202192. -
  202193. - u32 PAD[128]; /* DMA engines */
  202194. -
  202195. - /* SDIO/PCMCIA CIS region */
  202196. - char cis[512]; /* 0x400-0x5ff, rev6 */
  202197. -
  202198. - /* PCMCIA function control registers */
  202199. - char pcmciafcr[256]; /* 0x600-6ff, rev6 */
  202200. - u16 PAD[55];
  202201. -
  202202. - /* PCMCIA backplane access */
  202203. - u16 backplanecsr; /* 0x76E, rev6 */
  202204. - u16 backplaneaddr0; /* rev6 */
  202205. - u16 backplaneaddr1; /* rev6 */
  202206. - u16 backplaneaddr2; /* rev6 */
  202207. - u16 backplaneaddr3; /* rev6 */
  202208. - u16 backplanedata0; /* rev6 */
  202209. - u16 backplanedata1; /* rev6 */
  202210. - u16 backplanedata2; /* rev6 */
  202211. - u16 backplanedata3; /* rev6 */
  202212. - u16 PAD[31];
  202213. -
  202214. - /* sprom "size" & "blank" info */
  202215. - u16 spromstatus; /* 0x7BE, rev2 */
  202216. - u32 PAD[464];
  202217. -
  202218. - u16 PAD[0x80];
  202219. -};
  202220. -
  202221. -int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
  202222. - struct brcmf_chip **ci_ptr);
  202223. -void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr);
  202224. -void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
  202225. - struct brcmf_chip *ci,
  202226. - u32 drivestrength);
  202227. -u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid);
  202228. -void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
  202229. - struct brcmf_chip *ci);
  202230. -bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
  202231. - struct brcmf_chip *ci, u32 rstvec);
  202232. -
  202233. -#endif /* _BRCMFMAC_SDIO_CHIP_H_ */
  202234. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
  202235. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h 2014-08-14 03:38:34.000000000 +0200
  202236. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h 2014-09-11 18:06:03.906045582 +0200
  202237. @@ -180,6 +180,97 @@
  202238. uint max_request_size;
  202239. ushort max_segment_count;
  202240. uint max_segment_size;
  202241. + uint txglomsz;
  202242. + struct sg_table sgtable;
  202243. +};
  202244. +
  202245. +/* sdio core registers */
  202246. +struct sdpcmd_regs {
  202247. + u32 corecontrol; /* 0x00, rev8 */
  202248. + u32 corestatus; /* rev8 */
  202249. + u32 PAD[1];
  202250. + u32 biststatus; /* rev8 */
  202251. +
  202252. + /* PCMCIA access */
  202253. + u16 pcmciamesportaladdr; /* 0x010, rev8 */
  202254. + u16 PAD[1];
  202255. + u16 pcmciamesportalmask; /* rev8 */
  202256. + u16 PAD[1];
  202257. + u16 pcmciawrframebc; /* rev8 */
  202258. + u16 PAD[1];
  202259. + u16 pcmciaunderflowtimer; /* rev8 */
  202260. + u16 PAD[1];
  202261. +
  202262. + /* interrupt */
  202263. + u32 intstatus; /* 0x020, rev8 */
  202264. + u32 hostintmask; /* rev8 */
  202265. + u32 intmask; /* rev8 */
  202266. + u32 sbintstatus; /* rev8 */
  202267. + u32 sbintmask; /* rev8 */
  202268. + u32 funcintmask; /* rev4 */
  202269. + u32 PAD[2];
  202270. + u32 tosbmailbox; /* 0x040, rev8 */
  202271. + u32 tohostmailbox; /* rev8 */
  202272. + u32 tosbmailboxdata; /* rev8 */
  202273. + u32 tohostmailboxdata; /* rev8 */
  202274. +
  202275. + /* synchronized access to registers in SDIO clock domain */
  202276. + u32 sdioaccess; /* 0x050, rev8 */
  202277. + u32 PAD[3];
  202278. +
  202279. + /* PCMCIA frame control */
  202280. + u8 pcmciaframectrl; /* 0x060, rev8 */
  202281. + u8 PAD[3];
  202282. + u8 pcmciawatermark; /* rev8 */
  202283. + u8 PAD[155];
  202284. +
  202285. + /* interrupt batching control */
  202286. + u32 intrcvlazy; /* 0x100, rev8 */
  202287. + u32 PAD[3];
  202288. +
  202289. + /* counters */
  202290. + u32 cmd52rd; /* 0x110, rev8 */
  202291. + u32 cmd52wr; /* rev8 */
  202292. + u32 cmd53rd; /* rev8 */
  202293. + u32 cmd53wr; /* rev8 */
  202294. + u32 abort; /* rev8 */
  202295. + u32 datacrcerror; /* rev8 */
  202296. + u32 rdoutofsync; /* rev8 */
  202297. + u32 wroutofsync; /* rev8 */
  202298. + u32 writebusy; /* rev8 */
  202299. + u32 readwait; /* rev8 */
  202300. + u32 readterm; /* rev8 */
  202301. + u32 writeterm; /* rev8 */
  202302. + u32 PAD[40];
  202303. + u32 clockctlstatus; /* rev8 */
  202304. + u32 PAD[7];
  202305. +
  202306. + u32 PAD[128]; /* DMA engines */
  202307. +
  202308. + /* SDIO/PCMCIA CIS region */
  202309. + char cis[512]; /* 0x400-0x5ff, rev6 */
  202310. +
  202311. + /* PCMCIA function control registers */
  202312. + char pcmciafcr[256]; /* 0x600-6ff, rev6 */
  202313. + u16 PAD[55];
  202314. +
  202315. + /* PCMCIA backplane access */
  202316. + u16 backplanecsr; /* 0x76E, rev6 */
  202317. + u16 backplaneaddr0; /* rev6 */
  202318. + u16 backplaneaddr1; /* rev6 */
  202319. + u16 backplaneaddr2; /* rev6 */
  202320. + u16 backplaneaddr3; /* rev6 */
  202321. + u16 backplanedata0; /* rev6 */
  202322. + u16 backplanedata1; /* rev6 */
  202323. + u16 backplanedata2; /* rev6 */
  202324. + u16 backplanedata3; /* rev6 */
  202325. + u16 PAD[31];
  202326. +
  202327. + /* sprom "size" & "blank" info */
  202328. + u16 spromstatus; /* 0x7BE, rev2 */
  202329. + u32 PAD[464];
  202330. +
  202331. + u16 PAD[0x80];
  202332. };
  202333. /* Register/deregister interrupt handler. */
  202334. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/usb.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/usb.c
  202335. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-08-14 03:38:34.000000000 +0200
  202336. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/usb.c 2014-09-11 18:06:03.906045582 +0200
  202337. @@ -25,6 +25,7 @@
  202338. #include <dhd_bus.h>
  202339. #include <dhd_dbg.h>
  202340. +#include "firmware.h"
  202341. #include "usb_rdl.h"
  202342. #include "usb.h"
  202343. @@ -61,12 +62,6 @@
  202344. u8 *image;
  202345. int image_len;
  202346. };
  202347. -static struct list_head fw_image_list;
  202348. -
  202349. -struct intr_transfer_buf {
  202350. - u32 notification;
  202351. - u32 reserved;
  202352. -};
  202353. struct brcmf_usbdev_info {
  202354. struct brcmf_usbdev bus_pub; /* MUST BE FIRST */
  202355. @@ -75,7 +70,7 @@
  202356. struct list_head rx_postq;
  202357. struct list_head tx_freeq;
  202358. struct list_head tx_postq;
  202359. - uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
  202360. + uint rx_pipe, tx_pipe, rx_pipe2;
  202361. int rx_low_watermark;
  202362. int tx_low_watermark;
  202363. @@ -87,7 +82,7 @@
  202364. struct brcmf_usbreq *tx_reqs;
  202365. struct brcmf_usbreq *rx_reqs;
  202366. - u8 *image; /* buffer for combine fw and nvram */
  202367. + const u8 *image; /* buffer for combine fw and nvram */
  202368. int image_len;
  202369. struct usb_device *usbdev;
  202370. @@ -104,10 +99,6 @@
  202371. ulong ctl_op;
  202372. struct urb *bulk_urb; /* used for FW download */
  202373. - struct urb *intr_urb; /* URB for interrupt endpoint */
  202374. - int intr_size; /* Size of interrupt message */
  202375. - int interval; /* Interrupt polling interval */
  202376. - struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
  202377. };
  202378. static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
  202379. @@ -531,39 +522,6 @@
  202380. }
  202381. }
  202382. -static void
  202383. -brcmf_usb_intr_complete(struct urb *urb)
  202384. -{
  202385. - struct brcmf_usbdev_info *devinfo =
  202386. - (struct brcmf_usbdev_info *)urb->context;
  202387. - int err;
  202388. -
  202389. - brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
  202390. -
  202391. - if (devinfo == NULL)
  202392. - return;
  202393. -
  202394. - if (unlikely(urb->status)) {
  202395. - if (urb->status == -ENOENT ||
  202396. - urb->status == -ESHUTDOWN ||
  202397. - urb->status == -ENODEV) {
  202398. - brcmf_usb_state_change(devinfo,
  202399. - BRCMFMAC_USB_STATE_DOWN);
  202400. - }
  202401. - }
  202402. -
  202403. - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) {
  202404. - brcmf_err("intr cb when DBUS down, ignoring\n");
  202405. - return;
  202406. - }
  202407. -
  202408. - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
  202409. - err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
  202410. - if (err)
  202411. - brcmf_err("usb_submit_urb, err=%d\n", err);
  202412. - }
  202413. -}
  202414. -
  202415. static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
  202416. {
  202417. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
  202418. @@ -619,7 +577,6 @@
  202419. {
  202420. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
  202421. u16 ifnum;
  202422. - int ret;
  202423. brcmf_dbg(USB, "Enter\n");
  202424. if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)
  202425. @@ -628,23 +585,6 @@
  202426. /* Success, indicate devinfo is fully up */
  202427. brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP);
  202428. - if (devinfo->intr_urb) {
  202429. - usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
  202430. - devinfo->intr_pipe,
  202431. - &devinfo->intr,
  202432. - devinfo->intr_size,
  202433. - (usb_complete_t)brcmf_usb_intr_complete,
  202434. - devinfo,
  202435. - devinfo->interval);
  202436. -
  202437. - ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
  202438. - if (ret) {
  202439. - brcmf_err("USB_SUBMIT_URB failed with status %d\n",
  202440. - ret);
  202441. - return -EINVAL;
  202442. - }
  202443. - }
  202444. -
  202445. if (devinfo->ctl_urb) {
  202446. devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
  202447. devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
  202448. @@ -681,8 +621,6 @@
  202449. return;
  202450. brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);
  202451. - if (devinfo->intr_urb)
  202452. - usb_kill_urb(devinfo->intr_urb);
  202453. if (devinfo->ctl_urb)
  202454. usb_kill_urb(devinfo->ctl_urb);
  202455. @@ -1021,7 +959,7 @@
  202456. }
  202457. err = brcmf_usb_dlstart(devinfo,
  202458. - devinfo->image, devinfo->image_len);
  202459. + (u8 *)devinfo->image, devinfo->image_len);
  202460. if (err == 0)
  202461. err = brcmf_usb_dlrun(devinfo);
  202462. return err;
  202463. @@ -1036,7 +974,6 @@
  202464. brcmf_usb_free_q(&devinfo->rx_freeq, false);
  202465. brcmf_usb_free_q(&devinfo->tx_freeq, false);
  202466. - usb_free_urb(devinfo->intr_urb);
  202467. usb_free_urb(devinfo->ctl_urb);
  202468. usb_free_urb(devinfo->bulk_urb);
  202469. @@ -1080,68 +1017,20 @@
  202470. return -1;
  202471. }
  202472. -static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
  202473. +static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
  202474. {
  202475. - s8 *fwname;
  202476. - const struct firmware *fw;
  202477. - struct brcmf_usb_image *fw_image;
  202478. - int err;
  202479. -
  202480. - brcmf_dbg(USB, "Enter\n");
  202481. switch (devinfo->bus_pub.devid) {
  202482. case 43143:
  202483. - fwname = BRCMF_USB_43143_FW_NAME;
  202484. - break;
  202485. + return BRCMF_USB_43143_FW_NAME;
  202486. case 43235:
  202487. case 43236:
  202488. case 43238:
  202489. - fwname = BRCMF_USB_43236_FW_NAME;
  202490. - break;
  202491. + return BRCMF_USB_43236_FW_NAME;
  202492. case 43242:
  202493. - fwname = BRCMF_USB_43242_FW_NAME;
  202494. - break;
  202495. + return BRCMF_USB_43242_FW_NAME;
  202496. default:
  202497. - return -EINVAL;
  202498. - break;
  202499. - }
  202500. - brcmf_dbg(USB, "Loading FW %s\n", fwname);
  202501. - list_for_each_entry(fw_image, &fw_image_list, list) {
  202502. - if (fw_image->fwname == fwname) {
  202503. - devinfo->image = fw_image->image;
  202504. - devinfo->image_len = fw_image->image_len;
  202505. - return 0;
  202506. - }
  202507. - }
  202508. - /* fw image not yet loaded. Load it now and add to list */
  202509. - err = request_firmware(&fw, fwname, devinfo->dev);
  202510. - if (!fw) {
  202511. - brcmf_err("fail to request firmware %s\n", fwname);
  202512. - return err;
  202513. - }
  202514. - if (check_file(fw->data) < 0) {
  202515. - brcmf_err("invalid firmware %s\n", fwname);
  202516. - return -EINVAL;
  202517. + return NULL;
  202518. }
  202519. -
  202520. - fw_image = kzalloc(sizeof(*fw_image), GFP_ATOMIC);
  202521. - if (!fw_image)
  202522. - return -ENOMEM;
  202523. - INIT_LIST_HEAD(&fw_image->list);
  202524. - list_add_tail(&fw_image->list, &fw_image_list);
  202525. - fw_image->fwname = fwname;
  202526. - fw_image->image = vmalloc(fw->size);
  202527. - if (!fw_image->image)
  202528. - return -ENOMEM;
  202529. -
  202530. - memcpy(fw_image->image, fw->data, fw->size);
  202531. - fw_image->image_len = fw->size;
  202532. -
  202533. - release_firmware(fw);
  202534. -
  202535. - devinfo->image = fw_image->image;
  202536. - devinfo->image_len = fw_image->image_len;
  202537. -
  202538. - return 0;
  202539. }
  202540. @@ -1186,11 +1075,6 @@
  202541. goto error;
  202542. devinfo->tx_freecount = ntxq;
  202543. - devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
  202544. - if (!devinfo->intr_urb) {
  202545. - brcmf_err("usb_alloc_urb (intr) failed\n");
  202546. - goto error;
  202547. - }
  202548. devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
  202549. if (!devinfo->ctl_urb) {
  202550. brcmf_err("usb_alloc_urb (ctl) failed\n");
  202551. @@ -1202,16 +1086,6 @@
  202552. goto error;
  202553. }
  202554. - if (!brcmf_usb_dlneeded(devinfo))
  202555. - return &devinfo->bus_pub;
  202556. -
  202557. - brcmf_dbg(USB, "Start fw downloading\n");
  202558. - if (brcmf_usb_get_fw(devinfo))
  202559. - goto error;
  202560. -
  202561. - if (brcmf_usb_fw_download(devinfo))
  202562. - goto error;
  202563. -
  202564. return &devinfo->bus_pub;
  202565. error:
  202566. @@ -1222,18 +1096,77 @@
  202567. static struct brcmf_bus_ops brcmf_usb_bus_ops = {
  202568. .txdata = brcmf_usb_tx,
  202569. - .init = brcmf_usb_up,
  202570. .stop = brcmf_usb_down,
  202571. .txctl = brcmf_usb_tx_ctlpkt,
  202572. .rxctl = brcmf_usb_rx_ctlpkt,
  202573. };
  202574. +static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
  202575. +{
  202576. + int ret;
  202577. +
  202578. + /* Attach to the common driver interface */
  202579. + ret = brcmf_attach(devinfo->dev);
  202580. + if (ret) {
  202581. + brcmf_err("brcmf_attach failed\n");
  202582. + return ret;
  202583. + }
  202584. +
  202585. + ret = brcmf_usb_up(devinfo->dev);
  202586. + if (ret)
  202587. + goto fail;
  202588. +
  202589. + ret = brcmf_bus_start(devinfo->dev);
  202590. + if (ret)
  202591. + goto fail;
  202592. +
  202593. + return 0;
  202594. +fail:
  202595. + brcmf_detach(devinfo->dev);
  202596. + return ret;
  202597. +}
  202598. +
  202599. +static void brcmf_usb_probe_phase2(struct device *dev,
  202600. + const struct firmware *fw,
  202601. + void *nvram, u32 nvlen)
  202602. +{
  202603. + struct brcmf_bus *bus = dev_get_drvdata(dev);
  202604. + struct brcmf_usbdev_info *devinfo;
  202605. + int ret;
  202606. +
  202607. + brcmf_dbg(USB, "Start fw downloading\n");
  202608. + ret = check_file(fw->data);
  202609. + if (ret < 0) {
  202610. + brcmf_err("invalid firmware\n");
  202611. + release_firmware(fw);
  202612. + goto error;
  202613. + }
  202614. +
  202615. + devinfo = bus->bus_priv.usb->devinfo;
  202616. + devinfo->image = fw->data;
  202617. + devinfo->image_len = fw->size;
  202618. +
  202619. + ret = brcmf_usb_fw_download(devinfo);
  202620. + release_firmware(fw);
  202621. + if (ret)
  202622. + goto error;
  202623. +
  202624. + ret = brcmf_usb_bus_setup(devinfo);
  202625. + if (ret)
  202626. + goto error;
  202627. +
  202628. + return;
  202629. +error:
  202630. + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);
  202631. + device_release_driver(dev);
  202632. +}
  202633. +
  202634. static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
  202635. {
  202636. struct brcmf_bus *bus = NULL;
  202637. struct brcmf_usbdev *bus_pub = NULL;
  202638. - int ret;
  202639. struct device *dev = devinfo->dev;
  202640. + int ret;
  202641. brcmf_dbg(USB, "Enter\n");
  202642. bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
  202643. @@ -1254,22 +1187,18 @@
  202644. bus->chip = bus_pub->devid;
  202645. bus->chiprev = bus_pub->chiprev;
  202646. bus->proto_type = BRCMF_PROTO_BCDC;
  202647. + bus->always_use_fws_queue = true;
  202648. - /* Attach to the common driver interface */
  202649. - ret = brcmf_attach(dev);
  202650. - if (ret) {
  202651. - brcmf_err("brcmf_attach failed\n");
  202652. - goto fail;
  202653. - }
  202654. -
  202655. - ret = brcmf_bus_start(dev);
  202656. - if (ret) {
  202657. - brcmf_err("dongle is not responding\n");
  202658. - brcmf_detach(dev);
  202659. - goto fail;
  202660. + if (!brcmf_usb_dlneeded(devinfo)) {
  202661. + ret = brcmf_usb_bus_setup(devinfo);
  202662. + if (ret)
  202663. + goto fail;
  202664. }
  202665. -
  202666. + /* request firmware here */
  202667. + brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
  202668. + brcmf_usb_probe_phase2);
  202669. return 0;
  202670. +
  202671. fail:
  202672. /* Release resources in reverse order */
  202673. kfree(bus);
  202674. @@ -1357,9 +1286,6 @@
  202675. goto fail;
  202676. }
  202677. - endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
  202678. - devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);
  202679. -
  202680. devinfo->rx_pipe = 0;
  202681. devinfo->rx_pipe2 = 0;
  202682. devinfo->tx_pipe = 0;
  202683. @@ -1391,16 +1317,9 @@
  202684. }
  202685. }
  202686. - /* Allocate interrupt URB and data buffer */
  202687. - /* RNDIS says 8-byte intr, our old drivers used 4-byte */
  202688. - if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
  202689. - devinfo->intr_size = 8;
  202690. - else
  202691. - devinfo->intr_size = 4;
  202692. -
  202693. - devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
  202694. -
  202695. - if (usb->speed == USB_SPEED_HIGH)
  202696. + if (usb->speed == USB_SPEED_SUPER)
  202697. + brcmf_dbg(USB, "Broadcom super speed USB wireless device detected\n");
  202698. + else if (usb->speed == USB_SPEED_HIGH)
  202699. brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n");
  202700. else
  202701. brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n");
  202702. @@ -1455,23 +1374,18 @@
  202703. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
  202704. brcmf_dbg(USB, "Enter\n");
  202705. - if (!brcmf_attach(devinfo->dev))
  202706. - return brcmf_bus_start(&usb->dev);
  202707. -
  202708. - return 0;
  202709. + return brcmf_usb_bus_setup(devinfo);
  202710. }
  202711. static int brcmf_usb_reset_resume(struct usb_interface *intf)
  202712. {
  202713. struct usb_device *usb = interface_to_usbdev(intf);
  202714. struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
  202715. -
  202716. brcmf_dbg(USB, "Enter\n");
  202717. - if (!brcmf_usb_fw_download(devinfo))
  202718. - return brcmf_usb_resume(intf);
  202719. -
  202720. - return -EIO;
  202721. + return brcmf_fw_get_firmwares(&usb->dev, 0,
  202722. + brcmf_usb_get_fwname(devinfo), NULL,
  202723. + brcmf_usb_probe_phase2);
  202724. }
  202725. #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
  202726. @@ -1506,16 +1420,6 @@
  202727. .disable_hub_initiated_lpm = 1,
  202728. };
  202729. -static void brcmf_release_fw(struct list_head *q)
  202730. -{
  202731. - struct brcmf_usb_image *fw_image, *next;
  202732. -
  202733. - list_for_each_entry_safe(fw_image, next, q, list) {
  202734. - vfree(fw_image->image);
  202735. - list_del_init(&fw_image->list);
  202736. - }
  202737. -}
  202738. -
  202739. static int brcmf_usb_reset_device(struct device *dev, void *notused)
  202740. {
  202741. /* device past is the usb interface so we
  202742. @@ -1534,12 +1438,10 @@
  202743. ret = driver_for_each_device(drv, NULL, NULL,
  202744. brcmf_usb_reset_device);
  202745. usb_deregister(&brcmf_usbdrvr);
  202746. - brcmf_release_fw(&fw_image_list);
  202747. }
  202748. void brcmf_usb_register(void)
  202749. {
  202750. brcmf_dbg(USB, "Enter\n");
  202751. - INIT_LIST_HEAD(&fw_image_list);
  202752. usb_register(&brcmf_usbdrvr);
  202753. }
  202754. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
  202755. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 2014-08-14 03:38:34.000000000 +0200
  202756. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 2014-09-11 18:06:03.910045599 +0200
  202757. @@ -18,6 +18,7 @@
  202758. #include <linux/kernel.h>
  202759. #include <linux/etherdevice.h>
  202760. +#include <linux/module.h>
  202761. #include <net/cfg80211.h>
  202762. #include <net/netlink.h>
  202763. @@ -190,6 +191,7 @@
  202764. .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
  202765. .bitrates = wl_g_rates,
  202766. .n_bitrates = wl_g_rates_size,
  202767. + .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
  202768. };
  202769. static struct ieee80211_supported_band __wl_band_5ghz_a = {
  202770. @@ -219,9 +221,9 @@
  202771. */
  202772. REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
  202773. /* IEEE 802.11a, channel 36..64 */
  202774. - REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
  202775. + REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
  202776. /* IEEE 802.11a, channel 100..165 */
  202777. - REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
  202778. + REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
  202779. };
  202780. static const u32 __wl_cipher_suites[] = {
  202781. @@ -251,6 +253,10 @@
  202782. struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
  202783. };
  202784. +static int brcmf_roamoff;
  202785. +module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
  202786. +MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
  202787. +
  202788. /* Quarter dBm units to mW
  202789. * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
  202790. * Table is offset so the last entry is largest mW value that fits in
  202791. @@ -335,6 +341,60 @@
  202792. return qdbm;
  202793. }
  202794. +static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
  202795. + struct cfg80211_chan_def *ch)
  202796. +{
  202797. + struct brcmu_chan ch_inf;
  202798. + s32 primary_offset;
  202799. +
  202800. + brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
  202801. + ch->chan->center_freq, ch->center_freq1, ch->width);
  202802. + ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
  202803. + primary_offset = ch->center_freq1 - ch->chan->center_freq;
  202804. + switch (ch->width) {
  202805. + case NL80211_CHAN_WIDTH_20:
  202806. + ch_inf.bw = BRCMU_CHAN_BW_20;
  202807. + WARN_ON(primary_offset != 0);
  202808. + break;
  202809. + case NL80211_CHAN_WIDTH_40:
  202810. + ch_inf.bw = BRCMU_CHAN_BW_40;
  202811. + if (primary_offset < 0)
  202812. + ch_inf.sb = BRCMU_CHAN_SB_U;
  202813. + else
  202814. + ch_inf.sb = BRCMU_CHAN_SB_L;
  202815. + break;
  202816. + case NL80211_CHAN_WIDTH_80:
  202817. + ch_inf.bw = BRCMU_CHAN_BW_80;
  202818. + if (primary_offset < 0) {
  202819. + if (primary_offset < -CH_10MHZ_APART)
  202820. + ch_inf.sb = BRCMU_CHAN_SB_UU;
  202821. + else
  202822. + ch_inf.sb = BRCMU_CHAN_SB_UL;
  202823. + } else {
  202824. + if (primary_offset > CH_10MHZ_APART)
  202825. + ch_inf.sb = BRCMU_CHAN_SB_LL;
  202826. + else
  202827. + ch_inf.sb = BRCMU_CHAN_SB_LU;
  202828. + }
  202829. + break;
  202830. + default:
  202831. + WARN_ON_ONCE(1);
  202832. + }
  202833. + switch (ch->chan->band) {
  202834. + case IEEE80211_BAND_2GHZ:
  202835. + ch_inf.band = BRCMU_CHAN_BAND_2G;
  202836. + break;
  202837. + case IEEE80211_BAND_5GHZ:
  202838. + ch_inf.band = BRCMU_CHAN_BAND_5G;
  202839. + break;
  202840. + default:
  202841. + WARN_ON_ONCE(1);
  202842. + }
  202843. + d11inf->encchspec(&ch_inf);
  202844. +
  202845. + return ch_inf.chspec;
  202846. +}
  202847. +
  202848. u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  202849. struct ieee80211_channel *ch)
  202850. {
  202851. @@ -351,13 +411,11 @@
  202852. * triples, returning a pointer to the substring whose first element
  202853. * matches tag
  202854. */
  202855. -struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
  202856. +const struct brcmf_tlv *
  202857. +brcmf_parse_tlvs(const void *buf, int buflen, uint key)
  202858. {
  202859. - struct brcmf_tlv *elt;
  202860. - int totlen;
  202861. -
  202862. - elt = (struct brcmf_tlv *)buf;
  202863. - totlen = buflen;
  202864. + const struct brcmf_tlv *elt = buf;
  202865. + int totlen = buflen;
  202866. /* find tagged parameter */
  202867. while (totlen >= TLV_HDR_LEN) {
  202868. @@ -378,8 +436,8 @@
  202869. * not update the tlvs buffer pointer/length.
  202870. */
  202871. static bool
  202872. -brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
  202873. - u8 *oui, u32 oui_len, u8 type)
  202874. +brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
  202875. + const u8 *oui, u32 oui_len, u8 type)
  202876. {
  202877. /* If the contents match the OUI and the type */
  202878. if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
  202879. @@ -401,12 +459,12 @@
  202880. }
  202881. static struct brcmf_vs_tlv *
  202882. -brcmf_find_wpaie(u8 *parse, u32 len)
  202883. +brcmf_find_wpaie(const u8 *parse, u32 len)
  202884. {
  202885. - struct brcmf_tlv *ie;
  202886. + const struct brcmf_tlv *ie;
  202887. while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
  202888. - if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
  202889. + if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
  202890. WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
  202891. return (struct brcmf_vs_tlv *)ie;
  202892. }
  202893. @@ -414,9 +472,9 @@
  202894. }
  202895. static struct brcmf_vs_tlv *
  202896. -brcmf_find_wpsie(u8 *parse, u32 len)
  202897. +brcmf_find_wpsie(const u8 *parse, u32 len)
  202898. {
  202899. - struct brcmf_tlv *ie;
  202900. + const struct brcmf_tlv *ie;
  202901. while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
  202902. if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
  202903. @@ -491,6 +549,19 @@
  202904. return err;
  202905. }
  202906. +static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
  202907. +{
  202908. + enum nl80211_iftype iftype;
  202909. +
  202910. + iftype = vif->wdev.iftype;
  202911. + return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
  202912. +}
  202913. +
  202914. +static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
  202915. +{
  202916. + return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
  202917. +}
  202918. +
  202919. static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
  202920. const char *name,
  202921. enum nl80211_iftype type,
  202922. @@ -569,6 +640,9 @@
  202923. if (err)
  202924. brcmf_err("Scan abort failed\n");
  202925. }
  202926. +
  202927. + brcmf_set_mpc(ifp, 1);
  202928. +
  202929. /*
  202930. * e-scan can be initiated by scheduled scan
  202931. * which takes precedence.
  202932. @@ -578,12 +652,10 @@
  202933. cfg->sched_escan = false;
  202934. if (!aborted)
  202935. cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
  202936. - brcmf_set_mpc(ifp, 1);
  202937. } else if (scan_request) {
  202938. brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
  202939. aborted ? "Aborted" : "Done");
  202940. cfg80211_scan_done(scan_request, aborted);
  202941. - brcmf_set_mpc(ifp, 1);
  202942. }
  202943. if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
  202944. brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
  202945. @@ -651,7 +723,6 @@
  202946. type);
  202947. return -EOPNOTSUPP;
  202948. case NL80211_IFTYPE_ADHOC:
  202949. - vif->mode = WL_MODE_IBSS;
  202950. infra = 0;
  202951. break;
  202952. case NL80211_IFTYPE_STATION:
  202953. @@ -667,12 +738,10 @@
  202954. */
  202955. return 0;
  202956. }
  202957. - vif->mode = WL_MODE_BSS;
  202958. infra = 1;
  202959. break;
  202960. case NL80211_IFTYPE_AP:
  202961. case NL80211_IFTYPE_P2P_GO:
  202962. - vif->mode = WL_MODE_AP;
  202963. ap = 1;
  202964. break;
  202965. default:
  202966. @@ -696,7 +765,7 @@
  202967. err = -EAGAIN;
  202968. goto done;
  202969. }
  202970. - brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
  202971. + brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
  202972. "Adhoc" : "Infra");
  202973. }
  202974. ndev->ieee80211_ptr->iftype = type;
  202975. @@ -1222,8 +1291,8 @@
  202976. params->chandef.chan->center_freq);
  202977. if (params->channel_fixed) {
  202978. /* adding chanspec */
  202979. - chanspec = channel_to_chanspec(&cfg->d11inf,
  202980. - params->chandef.chan);
  202981. + chanspec = chandef_to_chanspec(&cfg->d11inf,
  202982. + &params->chandef);
  202983. join_params.params_le.chanspec_list[0] =
  202984. cpu_to_le16(chanspec);
  202985. join_params.params_le.chanspec_num = cpu_to_le32(1);
  202986. @@ -1340,13 +1409,14 @@
  202987. }
  202988. static s32
  202989. -brcmf_set_set_cipher(struct net_device *ndev,
  202990. - struct cfg80211_connect_params *sme)
  202991. +brcmf_set_wsec_mode(struct net_device *ndev,
  202992. + struct cfg80211_connect_params *sme, bool mfp)
  202993. {
  202994. struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
  202995. struct brcmf_cfg80211_security *sec;
  202996. s32 pval = 0;
  202997. s32 gval = 0;
  202998. + s32 wsec;
  202999. s32 err = 0;
  203000. if (sme->crypto.n_ciphers_pairwise) {
  203001. @@ -1398,7 +1468,12 @@
  203002. if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
  203003. sme->privacy)
  203004. pval = AES_ENABLED;
  203005. - err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
  203006. +
  203007. + if (mfp)
  203008. + wsec = pval | gval | MFP_CAPABLE;
  203009. + else
  203010. + wsec = pval | gval;
  203011. + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
  203012. if (err) {
  203013. brcmf_err("error (%d)\n", err);
  203014. return err;
  203015. @@ -1562,13 +1637,12 @@
  203016. struct ieee80211_channel *chan = sme->channel;
  203017. struct brcmf_join_params join_params;
  203018. size_t join_params_size;
  203019. - struct brcmf_tlv *rsn_ie;
  203020. - struct brcmf_vs_tlv *wpa_ie;
  203021. - void *ie;
  203022. + const struct brcmf_tlv *rsn_ie;
  203023. + const struct brcmf_vs_tlv *wpa_ie;
  203024. + const void *ie;
  203025. u32 ie_len;
  203026. struct brcmf_ext_join_params_le *ext_join_params;
  203027. u16 chanspec;
  203028. -
  203029. s32 err = 0;
  203030. brcmf_dbg(TRACE, "Enter\n");
  203031. @@ -1591,7 +1665,8 @@
  203032. ie_len = wpa_ie->len + TLV_HDR_LEN;
  203033. } else {
  203034. /* find the RSN_IE */
  203035. - rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
  203036. + rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
  203037. + sme->ie_len,
  203038. WLAN_EID_RSN);
  203039. if (rsn_ie) {
  203040. ie = rsn_ie;
  203041. @@ -1636,7 +1711,7 @@
  203042. goto done;
  203043. }
  203044. - err = brcmf_set_set_cipher(ndev, sme);
  203045. + err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
  203046. if (err) {
  203047. brcmf_err("wl_set_set_cipher failed (%d)\n", err);
  203048. goto done;
  203049. @@ -1678,22 +1753,9 @@
  203050. ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
  203051. memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
  203052. profile->ssid.SSID_len);
  203053. - /*increase dwell time to receive probe response or detect Beacon
  203054. - * from target AP at a noisy air only during connect command
  203055. - */
  203056. - ext_join_params->scan_le.active_time =
  203057. - cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
  203058. - ext_join_params->scan_le.passive_time =
  203059. - cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
  203060. +
  203061. /* Set up join scan parameters */
  203062. ext_join_params->scan_le.scan_type = -1;
  203063. - /* to sync with presence period of VSDB GO.
  203064. - * Send probe request more frequently. Probe request will be stopped
  203065. - * when it gets probe response from target AP/GO.
  203066. - */
  203067. - ext_join_params->scan_le.nprobes =
  203068. - cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
  203069. - BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
  203070. ext_join_params->scan_le.home_time = cpu_to_le32(-1);
  203071. if (sme->bssid)
  203072. @@ -1706,6 +1768,25 @@
  203073. ext_join_params->assoc_le.chanspec_list[0] =
  203074. cpu_to_le16(chanspec);
  203075. + /* Increase dwell time to receive probe response or detect
  203076. + * beacon from target AP at a noisy air only during connect
  203077. + * command.
  203078. + */
  203079. + ext_join_params->scan_le.active_time =
  203080. + cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
  203081. + ext_join_params->scan_le.passive_time =
  203082. + cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
  203083. + /* To sync with presence period of VSDB GO send probe request
  203084. + * more frequently. Probe request will be stopped when it gets
  203085. + * probe response from target AP/GO.
  203086. + */
  203087. + ext_join_params->scan_le.nprobes =
  203088. + cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
  203089. + BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
  203090. + } else {
  203091. + ext_join_params->scan_le.active_time = cpu_to_le32(-1);
  203092. + ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
  203093. + ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
  203094. }
  203095. err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
  203096. @@ -1913,7 +1994,7 @@
  203097. brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
  203098. memcpy(key.data, params->key, key.len);
  203099. - if ((ifp->vif->mode != WL_MODE_AP) &&
  203100. + if (!brcmf_is_apmode(ifp->vif) &&
  203101. (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
  203102. brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
  203103. memcpy(keybuf, &key.data[24], sizeof(keybuf));
  203104. @@ -1981,7 +2062,9 @@
  203105. if (!check_vif_up(ifp->vif))
  203106. return -EIO;
  203107. - if (mac_addr) {
  203108. + if (mac_addr &&
  203109. + (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
  203110. + (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
  203111. brcmf_dbg(TRACE, "Exit");
  203112. return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
  203113. }
  203114. @@ -2010,7 +2093,7 @@
  203115. brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
  203116. break;
  203117. case WLAN_CIPHER_SUITE_TKIP:
  203118. - if (ifp->vif->mode != WL_MODE_AP) {
  203119. + if (!brcmf_is_apmode(ifp->vif)) {
  203120. brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
  203121. memcpy(keybuf, &key.data[24], sizeof(keybuf));
  203122. memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
  203123. @@ -2164,12 +2247,14 @@
  203124. s32 err = 0;
  203125. u8 *bssid = profile->bssid;
  203126. struct brcmf_sta_info_le sta_info_le;
  203127. + u32 beacon_period;
  203128. + u32 dtim_period;
  203129. brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
  203130. if (!check_vif_up(ifp->vif))
  203131. return -EIO;
  203132. - if (ifp->vif->mode == WL_MODE_AP) {
  203133. + if (brcmf_is_apmode(ifp->vif)) {
  203134. memcpy(&sta_info_le, mac, ETH_ALEN);
  203135. err = brcmf_fil_iovar_data_get(ifp, "sta_info",
  203136. &sta_info_le,
  203137. @@ -2186,7 +2271,7 @@
  203138. }
  203139. brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
  203140. sinfo->inactive_time, sinfo->connected_time);
  203141. - } else if (ifp->vif->mode == WL_MODE_BSS) {
  203142. + } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
  203143. if (memcmp(mac, bssid, ETH_ALEN)) {
  203144. brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
  203145. mac, bssid);
  203146. @@ -2218,6 +2303,30 @@
  203147. sinfo->signal = rssi;
  203148. brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
  203149. }
  203150. + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
  203151. + &beacon_period);
  203152. + if (err) {
  203153. + brcmf_err("Could not get beacon period (%d)\n",
  203154. + err);
  203155. + goto done;
  203156. + } else {
  203157. + sinfo->bss_param.beacon_interval =
  203158. + beacon_period;
  203159. + brcmf_dbg(CONN, "Beacon peroid %d\n",
  203160. + beacon_period);
  203161. + }
  203162. + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
  203163. + &dtim_period);
  203164. + if (err) {
  203165. + brcmf_err("Could not get DTIM period (%d)\n",
  203166. + err);
  203167. + goto done;
  203168. + } else {
  203169. + sinfo->bss_param.dtim_period = dtim_period;
  203170. + brcmf_dbg(CONN, "DTIM peroid %d\n",
  203171. + dtim_period);
  203172. + }
  203173. + sinfo->filled |= STATION_INFO_BSS_PARAM;
  203174. }
  203175. } else
  203176. err = -EPERM;
  203177. @@ -2444,18 +2553,13 @@
  203178. return err;
  203179. }
  203180. -static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
  203181. -{
  203182. - return vif->mode == WL_MODE_IBSS;
  203183. -}
  203184. -
  203185. static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
  203186. struct brcmf_if *ifp)
  203187. {
  203188. struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
  203189. struct brcmf_bss_info_le *bi;
  203190. struct brcmf_ssid *ssid;
  203191. - struct brcmf_tlv *tim;
  203192. + const struct brcmf_tlv *tim;
  203193. u16 beacon_interval;
  203194. u8 dtim_period;
  203195. size_t ie_len;
  203196. @@ -3075,7 +3179,7 @@
  203197. }
  203198. if (!request->n_ssids || !request->n_match_sets) {
  203199. - brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
  203200. + brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
  203201. request->n_ssids);
  203202. return -EINVAL;
  203203. }
  203204. @@ -3220,8 +3324,9 @@
  203205. }
  203206. static s32
  203207. -brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
  203208. - bool is_rsn_ie)
  203209. +brcmf_configure_wpaie(struct net_device *ndev,
  203210. + const struct brcmf_vs_tlv *wpa_ie,
  203211. + bool is_rsn_ie)
  203212. {
  203213. struct brcmf_if *ifp = netdev_priv(ndev);
  203214. u32 auth = 0; /* d11 open authentication */
  203215. @@ -3684,42 +3789,26 @@
  203216. }
  203217. static s32
  203218. -brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
  203219. - struct brcmf_if *ifp,
  203220. - struct ieee80211_channel *channel)
  203221. -{
  203222. - u16 chanspec;
  203223. - s32 err;
  203224. -
  203225. - brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
  203226. - channel->center_freq);
  203227. -
  203228. - chanspec = channel_to_chanspec(&cfg->d11inf, channel);
  203229. - err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  203230. -
  203231. - return err;
  203232. -}
  203233. -
  203234. -static s32
  203235. brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
  203236. struct cfg80211_ap_settings *settings)
  203237. {
  203238. s32 ie_offset;
  203239. struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
  203240. struct brcmf_if *ifp = netdev_priv(ndev);
  203241. - struct brcmf_tlv *ssid_ie;
  203242. + const struct brcmf_tlv *ssid_ie;
  203243. struct brcmf_ssid_le ssid_le;
  203244. s32 err = -EPERM;
  203245. - struct brcmf_tlv *rsn_ie;
  203246. - struct brcmf_vs_tlv *wpa_ie;
  203247. + const struct brcmf_tlv *rsn_ie;
  203248. + const struct brcmf_vs_tlv *wpa_ie;
  203249. struct brcmf_join_params join_params;
  203250. enum nl80211_iftype dev_role;
  203251. struct brcmf_fil_bss_enable_le bss_enable;
  203252. + u16 chanspec;
  203253. - brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
  203254. - cfg80211_get_chandef_type(&settings->chandef),
  203255. - settings->beacon_interval,
  203256. - settings->dtim_period);
  203257. + brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
  203258. + settings->chandef.chan->hw_value,
  203259. + settings->chandef.center_freq1, settings->chandef.width,
  203260. + settings->beacon_interval, settings->dtim_period);
  203261. brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
  203262. settings->ssid, settings->ssid_len, settings->auth_type,
  203263. settings->inactivity_timeout);
  203264. @@ -3776,9 +3865,10 @@
  203265. brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
  203266. - err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
  203267. + chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
  203268. + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  203269. if (err < 0) {
  203270. - brcmf_err("Set Channel failed, %d\n", err);
  203271. + brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
  203272. goto exit;
  203273. }
  203274. @@ -4220,32 +4310,6 @@
  203275. CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
  203276. };
  203277. -static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
  203278. -{
  203279. - switch (type) {
  203280. - case NL80211_IFTYPE_AP_VLAN:
  203281. - case NL80211_IFTYPE_WDS:
  203282. - case NL80211_IFTYPE_MONITOR:
  203283. - case NL80211_IFTYPE_MESH_POINT:
  203284. - return -ENOTSUPP;
  203285. - case NL80211_IFTYPE_ADHOC:
  203286. - return WL_MODE_IBSS;
  203287. - case NL80211_IFTYPE_STATION:
  203288. - case NL80211_IFTYPE_P2P_CLIENT:
  203289. - return WL_MODE_BSS;
  203290. - case NL80211_IFTYPE_AP:
  203291. - case NL80211_IFTYPE_P2P_GO:
  203292. - return WL_MODE_AP;
  203293. - case NL80211_IFTYPE_P2P_DEVICE:
  203294. - return WL_MODE_P2P;
  203295. - case NL80211_IFTYPE_UNSPECIFIED:
  203296. - default:
  203297. - break;
  203298. - }
  203299. -
  203300. - return -EINVAL;
  203301. -}
  203302. -
  203303. static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
  203304. {
  203305. /* scheduled scan settings */
  203306. @@ -4340,6 +4404,8 @@
  203307. WIPHY_FLAG_OFFCHAN_TX |
  203308. WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
  203309. WIPHY_FLAG_SUPPORTS_TDLS;
  203310. + if (!brcmf_roamoff)
  203311. + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
  203312. wiphy->mgmt_stypes = brcmf_txrx_stypes;
  203313. wiphy->max_remain_on_channel_duration = 5000;
  203314. brcmf_wiphy_pno_params(wiphy);
  203315. @@ -4370,7 +4436,6 @@
  203316. vif->wdev.wiphy = cfg->wiphy;
  203317. vif->wdev.iftype = type;
  203318. - vif->mode = brcmf_nl80211_iftype_to_mode(type);
  203319. vif->pm_block = pm_block;
  203320. vif->roam_off = -1;
  203321. @@ -4416,7 +4481,9 @@
  203322. u32 event = e->event_code;
  203323. u16 flags = e->flags;
  203324. - if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
  203325. + if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
  203326. + (event == BRCMF_E_DISASSOC_IND) ||
  203327. + ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
  203328. brcmf_dbg(CONN, "Processing link down\n");
  203329. return true;
  203330. }
  203331. @@ -4658,16 +4725,18 @@
  203332. struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
  203333. struct net_device *ndev = ifp->ndev;
  203334. struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
  203335. + struct ieee80211_channel *chan;
  203336. s32 err = 0;
  203337. - if (ifp->vif->mode == WL_MODE_AP) {
  203338. + if (brcmf_is_apmode(ifp->vif)) {
  203339. err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
  203340. } else if (brcmf_is_linkup(e)) {
  203341. brcmf_dbg(CONN, "Linkup\n");
  203342. if (brcmf_is_ibssmode(ifp->vif)) {
  203343. + chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
  203344. memcpy(profile->bssid, e->addr, ETH_ALEN);
  203345. wl_inform_ibss(cfg, ndev, e->addr);
  203346. - cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
  203347. + cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
  203348. clear_bit(BRCMF_VIF_STATUS_CONNECTING,
  203349. &ifp->vif->sme_state);
  203350. set_bit(BRCMF_VIF_STATUS_CONNECTED,
  203351. @@ -4678,10 +4747,6 @@
  203352. brcmf_dbg(CONN, "Linkdown\n");
  203353. if (!brcmf_is_ibssmode(ifp->vif)) {
  203354. brcmf_bss_connect_done(cfg, ndev, e, false);
  203355. - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
  203356. - &ifp->vif->sme_state))
  203357. - cfg80211_disconnected(ndev, 0, NULL, 0,
  203358. - GFP_KERNEL);
  203359. }
  203360. brcmf_link_down(ifp->vif);
  203361. brcmf_init_prof(ndev_to_prof(ndev));
  203362. @@ -4875,11 +4940,8 @@
  203363. cfg->scan_request = NULL;
  203364. cfg->pwr_save = true;
  203365. - cfg->roam_on = true; /* roam on & off switch.
  203366. - we enable roam per default */
  203367. - cfg->active_scan = true; /* we do active scan for
  203368. - specific scan per default */
  203369. - cfg->dongle_up = false; /* dongle is not up yet */
  203370. + cfg->active_scan = true; /* we do active scan per default */
  203371. + cfg->dongle_up = false; /* dongle is not up yet */
  203372. err = brcmf_init_priv_mem(cfg);
  203373. if (err)
  203374. return err;
  203375. @@ -4904,6 +4966,30 @@
  203376. mutex_init(&event->vif_event_lock);
  203377. }
  203378. +static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
  203379. +{
  203380. + struct brcmf_fil_bwcap_le band_bwcap;
  203381. + u32 val;
  203382. + int err;
  203383. +
  203384. + /* verify support for bw_cap command */
  203385. + val = WLC_BAND_5G;
  203386. + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
  203387. +
  203388. + if (!err) {
  203389. + /* only set 2G bandwidth using bw_cap command */
  203390. + band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
  203391. + band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
  203392. + err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
  203393. + sizeof(band_bwcap));
  203394. + } else {
  203395. + brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
  203396. + val = WLC_N_BW_40ALL;
  203397. + err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
  203398. + }
  203399. + return err;
  203400. +}
  203401. +
  203402. struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
  203403. struct device *busdev)
  203404. {
  203405. @@ -4961,6 +5047,17 @@
  203406. goto cfg80211_p2p_attach_out;
  203407. }
  203408. + /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
  203409. + * setup 40MHz in 2GHz band and enable OBSS scanning.
  203410. + */
  203411. + if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
  203412. + IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
  203413. + err = brcmf_enable_bw40_2g(ifp);
  203414. + if (!err)
  203415. + err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
  203416. + BRCMF_OBSS_COEX_AUTO);
  203417. + }
  203418. +
  203419. err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
  203420. if (err) {
  203421. brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
  203422. @@ -4999,7 +5096,7 @@
  203423. }
  203424. static s32
  203425. -brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
  203426. +brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
  203427. {
  203428. s32 err = 0;
  203429. __le32 roamtrigger[2];
  203430. @@ -5009,7 +5106,7 @@
  203431. * Setup timeout if Beacons are lost and roam is
  203432. * off to report link down
  203433. */
  203434. - if (roamvar) {
  203435. + if (brcmf_roamoff) {
  203436. err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
  203437. if (err) {
  203438. brcmf_err("bcn_timeout error (%d)\n", err);
  203439. @@ -5021,8 +5118,9 @@
  203440. * Enable/Disable built-in roaming to allow supplicant
  203441. * to take care of roaming
  203442. */
  203443. - brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
  203444. - err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
  203445. + brcmf_dbg(INFO, "Internal Roaming = %s\n",
  203446. + brcmf_roamoff ? "Off" : "On");
  203447. + err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
  203448. if (err) {
  203449. brcmf_err("roam_off error (%d)\n", err);
  203450. goto dongle_rom_out;
  203451. @@ -5148,6 +5246,9 @@
  203452. if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
  203453. ch.bw == BRCMU_CHAN_BW_40)
  203454. continue;
  203455. + if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
  203456. + ch.bw == BRCMU_CHAN_BW_80)
  203457. + continue;
  203458. update = false;
  203459. for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
  203460. if (band_chan_arr[j].hw_value == ch.chnum) {
  203461. @@ -5164,13 +5265,13 @@
  203462. ieee80211_channel_to_frequency(ch.chnum, band);
  203463. band_chan_arr[index].hw_value = ch.chnum;
  203464. - brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
  203465. - ch.chnum, band_chan_arr[index].center_freq,
  203466. - ch.bw, ch.sb);
  203467. - if (ch.bw == BRCMU_CHAN_BW_40) {
  203468. - /* assuming the order is HT20, HT40 Upper,
  203469. - * HT40 lower from chanspecs
  203470. - */
  203471. + /* assuming the chanspecs order is HT20,
  203472. + * HT40 upper, HT40 lower, and VHT80.
  203473. + */
  203474. + if (ch.bw == BRCMU_CHAN_BW_80) {
  203475. + band_chan_arr[index].flags &=
  203476. + ~IEEE80211_CHAN_NO_80MHZ;
  203477. + } else if (ch.bw == BRCMU_CHAN_BW_40) {
  203478. ht40_flag = band_chan_arr[index].flags &
  203479. IEEE80211_CHAN_NO_HT40;
  203480. if (ch.sb == BRCMU_CHAN_SB_U) {
  203481. @@ -5191,8 +5292,13 @@
  203482. IEEE80211_CHAN_NO_HT40MINUS;
  203483. }
  203484. } else {
  203485. + /* disable other bandwidths for now as mentioned
  203486. + * order assure they are enabled for subsequent
  203487. + * chanspecs.
  203488. + */
  203489. band_chan_arr[index].flags =
  203490. - IEEE80211_CHAN_NO_HT40;
  203491. + IEEE80211_CHAN_NO_HT40 |
  203492. + IEEE80211_CHAN_NO_80MHZ;
  203493. ch.bw = BRCMU_CHAN_BW_20;
  203494. cfg->d11inf.encchspec(&ch);
  203495. channel = ch.chspec;
  203496. @@ -5259,14 +5365,66 @@
  203497. }
  203498. }
  203499. +static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
  203500. + u32 bw_cap[2], u32 nchain)
  203501. +{
  203502. + band->ht_cap.ht_supported = true;
  203503. + if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
  203504. + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
  203505. + band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
  203506. + }
  203507. + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
  203508. + band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
  203509. + band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
  203510. + band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
  203511. + memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
  203512. + band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  203513. +}
  203514. +
  203515. +static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
  203516. +{
  203517. + u16 mcs_map;
  203518. + int i;
  203519. +
  203520. + for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
  203521. + mcs_map = (mcs_map << 2) | supp;
  203522. +
  203523. + return cpu_to_le16(mcs_map);
  203524. +}
  203525. +
  203526. +static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
  203527. + u32 bw_cap[2], u32 nchain)
  203528. +{
  203529. + __le16 mcs_map;
  203530. +
  203531. + /* not allowed in 2.4G band */
  203532. + if (band->band == IEEE80211_BAND_2GHZ)
  203533. + return;
  203534. +
  203535. + band->vht_cap.vht_supported = true;
  203536. + /* 80MHz is mandatory */
  203537. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
  203538. + if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
  203539. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
  203540. + band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
  203541. + }
  203542. + /* all support 256-QAM */
  203543. + mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
  203544. + band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
  203545. + band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
  203546. +}
  203547. +
  203548. static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
  203549. {
  203550. struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
  203551. struct wiphy *wiphy;
  203552. s32 phy_list;
  203553. u32 band_list[3];
  203554. - u32 nmode;
  203555. + u32 nmode = 0;
  203556. + u32 vhtmode = 0;
  203557. u32 bw_cap[2] = { 0, 0 };
  203558. + u32 rxchain;
  203559. + u32 nchain;
  203560. s8 phy;
  203561. s32 err;
  203562. u32 nband;
  203563. @@ -5294,14 +5452,26 @@
  203564. brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
  203565. band_list[0], band_list[1], band_list[2]);
  203566. + (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
  203567. err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
  203568. if (err) {
  203569. brcmf_err("nmode error (%d)\n", err);
  203570. } else {
  203571. brcmf_get_bwcap(ifp, bw_cap);
  203572. }
  203573. - brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
  203574. - bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
  203575. + brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
  203576. + nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
  203577. + bw_cap[IEEE80211_BAND_5GHZ]);
  203578. +
  203579. + err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
  203580. + if (err) {
  203581. + brcmf_err("rxchain error (%d)\n", err);
  203582. + nchain = 1;
  203583. + } else {
  203584. + for (nchain = 0; rxchain; nchain++)
  203585. + rxchain = rxchain & (rxchain - 1);
  203586. + }
  203587. + brcmf_dbg(INFO, "nchain=%d\n", nchain);
  203588. err = brcmf_construct_reginfo(cfg, bw_cap);
  203589. if (err) {
  203590. @@ -5322,20 +5492,10 @@
  203591. else
  203592. continue;
  203593. - if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
  203594. - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
  203595. - band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
  203596. - }
  203597. - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
  203598. - band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
  203599. - band->ht_cap.ht_supported = true;
  203600. - band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
  203601. - band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
  203602. - /* An HT shall support all EQM rates for one spatial
  203603. - * stream
  203604. - */
  203605. - band->ht_cap.mcs.rx_mask[0] = 0xff;
  203606. - band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  203607. + if (nmode)
  203608. + brcmf_update_ht_cap(band, bw_cap, nchain);
  203609. + if (vhtmode)
  203610. + brcmf_update_vht_cap(band, bw_cap, nchain);
  203611. bands[band->band] = band;
  203612. }
  203613. @@ -5381,7 +5541,7 @@
  203614. brcmf_dbg(INFO, "power save set to %s\n",
  203615. (power_mode ? "enabled" : "disabled"));
  203616. - err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
  203617. + err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
  203618. if (err)
  203619. goto default_conf_out;
  203620. err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
  203621. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
  203622. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h 2014-08-14 03:38:34.000000000 +0200
  203623. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h 2014-09-11 18:06:03.910045599 +0200
  203624. @@ -89,21 +89,6 @@
  203625. BRCMF_SCAN_STATUS_SUPPRESS,
  203626. };
  203627. -/**
  203628. - * enum wl_mode - driver mode of virtual interface.
  203629. - *
  203630. - * @WL_MODE_BSS: connects to BSS.
  203631. - * @WL_MODE_IBSS: operate as ad-hoc.
  203632. - * @WL_MODE_AP: operate as access-point.
  203633. - * @WL_MODE_P2P: provide P2P discovery.
  203634. - */
  203635. -enum wl_mode {
  203636. - WL_MODE_BSS,
  203637. - WL_MODE_IBSS,
  203638. - WL_MODE_AP,
  203639. - WL_MODE_P2P
  203640. -};
  203641. -
  203642. /* dongle configuration */
  203643. struct brcmf_cfg80211_conf {
  203644. u32 frag_threshold;
  203645. @@ -193,7 +178,6 @@
  203646. * @ifp: lower layer interface pointer
  203647. * @wdev: wireless device.
  203648. * @profile: profile information.
  203649. - * @mode: operating mode.
  203650. * @roam_off: roaming state.
  203651. * @sme_state: SME state using enum brcmf_vif_status bits.
  203652. * @pm_block: power-management blocked.
  203653. @@ -204,7 +188,6 @@
  203654. struct brcmf_if *ifp;
  203655. struct wireless_dev wdev;
  203656. struct brcmf_cfg80211_profile profile;
  203657. - s32 mode;
  203658. s32 roam_off;
  203659. unsigned long sme_state;
  203660. bool pm_block;
  203661. @@ -402,7 +385,6 @@
  203662. bool ibss_starter;
  203663. bool pwr_save;
  203664. bool dongle_up;
  203665. - bool roam_on;
  203666. bool scan_tried;
  203667. u8 *dcmd_buf;
  203668. u8 *extra_buf;
  203669. @@ -491,7 +473,8 @@
  203670. s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
  203671. const u8 *vndr_ie_buf, u32 vndr_ie_len);
  203672. s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
  203673. -struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key);
  203674. +const struct brcmf_tlv *
  203675. +brcmf_parse_tlvs(const void *buf, int buflen, uint key);
  203676. u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  203677. struct ieee80211_channel *ch);
  203678. u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state);
  203679. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
  203680. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-08-14 03:38:34.000000000 +0200
  203681. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c 2014-09-11 18:06:03.914045614 +0200
  203682. @@ -897,7 +897,8 @@
  203683. return result;
  203684. }
  203685. -static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  203686. +static void brcms_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  203687. + u32 queues, bool drop)
  203688. {
  203689. struct brcms_info *wl = hw->priv;
  203690. int ret;
  203691. @@ -1092,12 +1093,6 @@
  203692. * Attach to the WL device identified by vendor and device parameters.
  203693. * regs is a host accessible memory address pointing to WL device registers.
  203694. *
  203695. - * brcms_attach is not defined as static because in the case where no bus
  203696. - * is defined, wl_attach will never be called, and thus, gcc will issue
  203697. - * a warning that this function is defined but not used if we declare
  203698. - * it as static.
  203699. - *
  203700. - *
  203701. * is called in brcms_bcma_probe() context, therefore no locking required.
  203702. */
  203703. static struct brcms_info *brcms_attach(struct bcma_device *pdev)
  203704. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmsmac/main.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/main.c
  203705. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmsmac/main.c 2014-08-14 03:38:34.000000000 +0200
  203706. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmsmac/main.c 2014-09-11 18:06:03.914045614 +0200
  203707. @@ -4870,14 +4870,11 @@
  203708. /*
  203709. * low level detach
  203710. */
  203711. -static int brcms_b_detach(struct brcms_c_info *wlc)
  203712. +static void brcms_b_detach(struct brcms_c_info *wlc)
  203713. {
  203714. uint i;
  203715. struct brcms_hw_band *band;
  203716. struct brcms_hardware *wlc_hw = wlc->hw;
  203717. - int callbacks;
  203718. -
  203719. - callbacks = 0;
  203720. brcms_b_detach_dmapio(wlc_hw);
  203721. @@ -4900,9 +4897,6 @@
  203722. ai_detach(wlc_hw->sih);
  203723. wlc_hw->sih = NULL;
  203724. }
  203725. -
  203726. - return callbacks;
  203727. -
  203728. }
  203729. /*
  203730. @@ -4917,14 +4911,15 @@
  203731. */
  203732. uint brcms_c_detach(struct brcms_c_info *wlc)
  203733. {
  203734. - uint callbacks = 0;
  203735. + uint callbacks;
  203736. if (wlc == NULL)
  203737. return 0;
  203738. - callbacks += brcms_b_detach(wlc);
  203739. + brcms_b_detach(wlc);
  203740. /* delete software timers */
  203741. + callbacks = 0;
  203742. if (!brcms_c_radio_monitor_stop(wlc))
  203743. callbacks++;
  203744. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/brcmutil/d11.c linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmutil/d11.c
  203745. --- linux-3.14.17/drivers/net/wireless/brcm80211/brcmutil/d11.c 2014-08-14 03:38:34.000000000 +0200
  203746. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/brcmutil/d11.c 2014-09-11 18:06:03.922045646 +0200
  203747. @@ -21,19 +21,46 @@
  203748. #include <brcmu_wifi.h>
  203749. #include <brcmu_d11.h>
  203750. -static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
  203751. +static u16 d11n_sb(enum brcmu_chan_sb sb)
  203752. {
  203753. - ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK;
  203754. + switch (sb) {
  203755. + case BRCMU_CHAN_SB_NONE:
  203756. + return BRCMU_CHSPEC_D11N_SB_N;
  203757. + case BRCMU_CHAN_SB_L:
  203758. + return BRCMU_CHSPEC_D11N_SB_L;
  203759. + case BRCMU_CHAN_SB_U:
  203760. + return BRCMU_CHSPEC_D11N_SB_U;
  203761. + default:
  203762. + WARN_ON(1);
  203763. + }
  203764. + return 0;
  203765. +}
  203766. - switch (ch->bw) {
  203767. +static u16 d11n_bw(enum brcmu_chan_bw bw)
  203768. +{
  203769. + switch (bw) {
  203770. case BRCMU_CHAN_BW_20:
  203771. - ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N;
  203772. - break;
  203773. + return BRCMU_CHSPEC_D11N_BW_20;
  203774. case BRCMU_CHAN_BW_40:
  203775. + return BRCMU_CHSPEC_D11N_BW_40;
  203776. default:
  203777. - WARN_ON_ONCE(1);
  203778. - break;
  203779. + WARN_ON(1);
  203780. }
  203781. + return 0;
  203782. +}
  203783. +
  203784. +static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
  203785. +{
  203786. + if (ch->bw == BRCMU_CHAN_BW_20)
  203787. + ch->sb = BRCMU_CHAN_SB_NONE;
  203788. +
  203789. + ch->chspec = 0;
  203790. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
  203791. + BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
  203792. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_SB_MASK,
  203793. + 0, d11n_sb(ch->sb));
  203794. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_BW_MASK,
  203795. + 0, d11n_bw(ch->bw));
  203796. if (ch->chnum <= CH_MAX_2G_CHANNEL)
  203797. ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G;
  203798. @@ -41,23 +68,34 @@
  203799. ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G;
  203800. }
  203801. -static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
  203802. +static u16 d11ac_bw(enum brcmu_chan_bw bw)
  203803. {
  203804. - ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK;
  203805. -
  203806. - switch (ch->bw) {
  203807. + switch (bw) {
  203808. case BRCMU_CHAN_BW_20:
  203809. - ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20;
  203810. - break;
  203811. + return BRCMU_CHSPEC_D11AC_BW_20;
  203812. case BRCMU_CHAN_BW_40:
  203813. + return BRCMU_CHSPEC_D11AC_BW_40;
  203814. case BRCMU_CHAN_BW_80:
  203815. - case BRCMU_CHAN_BW_80P80:
  203816. - case BRCMU_CHAN_BW_160:
  203817. + return BRCMU_CHSPEC_D11AC_BW_80;
  203818. default:
  203819. - WARN_ON_ONCE(1);
  203820. - break;
  203821. + WARN_ON(1);
  203822. }
  203823. + return 0;
  203824. +}
  203825. +static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
  203826. +{
  203827. + if (ch->bw == BRCMU_CHAN_BW_20 || ch->sb == BRCMU_CHAN_SB_NONE)
  203828. + ch->sb = BRCMU_CHAN_SB_L;
  203829. +
  203830. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
  203831. + BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
  203832. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
  203833. + BRCMU_CHSPEC_D11AC_SB_SHIFT, ch->sb);
  203834. + brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_BW_MASK,
  203835. + 0, d11ac_bw(ch->bw));
  203836. +
  203837. + ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK;
  203838. if (ch->chnum <= CH_MAX_2G_CHANNEL)
  203839. ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G;
  203840. else
  203841. @@ -73,6 +111,7 @@
  203842. switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
  203843. case BRCMU_CHSPEC_D11N_BW_20:
  203844. ch->bw = BRCMU_CHAN_BW_20;
  203845. + ch->sb = BRCMU_CHAN_SB_NONE;
  203846. break;
  203847. case BRCMU_CHSPEC_D11N_BW_40:
  203848. ch->bw = BRCMU_CHAN_BW_40;
  203849. @@ -112,6 +151,7 @@
  203850. switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
  203851. case BRCMU_CHSPEC_D11AC_BW_20:
  203852. ch->bw = BRCMU_CHAN_BW_20;
  203853. + ch->sb = BRCMU_CHAN_SB_NONE;
  203854. break;
  203855. case BRCMU_CHSPEC_D11AC_BW_40:
  203856. ch->bw = BRCMU_CHAN_BW_40;
  203857. @@ -128,6 +168,25 @@
  203858. break;
  203859. case BRCMU_CHSPEC_D11AC_BW_80:
  203860. ch->bw = BRCMU_CHAN_BW_80;
  203861. + ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
  203862. + BRCMU_CHSPEC_D11AC_SB_SHIFT);
  203863. + switch (ch->sb) {
  203864. + case BRCMU_CHAN_SB_LL:
  203865. + ch->chnum -= CH_30MHZ_APART;
  203866. + break;
  203867. + case BRCMU_CHAN_SB_LU:
  203868. + ch->chnum -= CH_10MHZ_APART;
  203869. + break;
  203870. + case BRCMU_CHAN_SB_UL:
  203871. + ch->chnum += CH_10MHZ_APART;
  203872. + break;
  203873. + case BRCMU_CHAN_SB_UU:
  203874. + ch->chnum += CH_30MHZ_APART;
  203875. + break;
  203876. + default:
  203877. + WARN_ON_ONCE(1);
  203878. + break;
  203879. + }
  203880. break;
  203881. case BRCMU_CHSPEC_D11AC_BW_8080:
  203882. case BRCMU_CHSPEC_D11AC_BW_160:
  203883. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
  203884. --- linux-3.14.17/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h 2014-08-14 03:38:34.000000000 +0200
  203885. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h 2014-09-11 18:06:03.926045662 +0200
  203886. @@ -43,5 +43,6 @@
  203887. #define BCM4335_CHIP_ID 0x4335
  203888. #define BCM43362_CHIP_ID 43362
  203889. #define BCM4339_CHIP_ID 0x4339
  203890. +#define BCM4354_CHIP_ID 0x4354
  203891. #endif /* _BRCM_HW_IDS_H_ */
  203892. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/include/brcmu_d11.h linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_d11.h
  203893. --- linux-3.14.17/drivers/net/wireless/brcm80211/include/brcmu_d11.h 2014-08-14 03:38:34.000000000 +0200
  203894. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_d11.h 2014-09-11 18:06:03.926045662 +0200
  203895. @@ -108,13 +108,7 @@
  203896. };
  203897. enum brcmu_chan_sb {
  203898. - BRCMU_CHAN_SB_NONE = 0,
  203899. - BRCMU_CHAN_SB_L,
  203900. - BRCMU_CHAN_SB_U,
  203901. - BRCMU_CHAN_SB_LL,
  203902. - BRCMU_CHAN_SB_LU,
  203903. - BRCMU_CHAN_SB_UL,
  203904. - BRCMU_CHAN_SB_UU,
  203905. + BRCMU_CHAN_SB_NONE = -1,
  203906. BRCMU_CHAN_SB_LLL,
  203907. BRCMU_CHAN_SB_LLU,
  203908. BRCMU_CHAN_SB_LUL,
  203909. @@ -123,6 +117,12 @@
  203910. BRCMU_CHAN_SB_ULU,
  203911. BRCMU_CHAN_SB_UUL,
  203912. BRCMU_CHAN_SB_UUU,
  203913. + BRCMU_CHAN_SB_L = BRCMU_CHAN_SB_LLL,
  203914. + BRCMU_CHAN_SB_U = BRCMU_CHAN_SB_LLU,
  203915. + BRCMU_CHAN_SB_LL = BRCMU_CHAN_SB_LLL,
  203916. + BRCMU_CHAN_SB_LU = BRCMU_CHAN_SB_LLU,
  203917. + BRCMU_CHAN_SB_UL = BRCMU_CHAN_SB_LUL,
  203918. + BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
  203919. };
  203920. struct brcmu_chan {
  203921. diff -Nur linux-3.14.17/drivers/net/wireless/brcm80211/include/brcmu_wifi.h linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
  203922. --- linux-3.14.17/drivers/net/wireless/brcm80211/include/brcmu_wifi.h 2014-08-14 03:38:34.000000000 +0200
  203923. +++ linux-imx6-3.14/drivers/net/wireless/brcm80211/include/brcmu_wifi.h 2014-09-11 18:06:03.926045662 +0200
  203924. @@ -29,6 +29,7 @@
  203925. #define CH_UPPER_SB 0x01
  203926. #define CH_LOWER_SB 0x02
  203927. #define CH_EWA_VALID 0x04
  203928. +#define CH_30MHZ_APART 6
  203929. #define CH_20MHZ_APART 4
  203930. #define CH_10MHZ_APART 2
  203931. #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
  203932. @@ -217,6 +218,9 @@
  203933. #define WSEC_SWFLAG 0x0008
  203934. /* to go into transition mode without setting wep */
  203935. #define SES_OW_ENABLED 0x0040
  203936. +/* MFP */
  203937. +#define MFP_CAPABLE 0x0200
  203938. +#define MFP_REQUIRED 0x0400
  203939. /* WPA authentication mode bitvec */
  203940. #define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */
  203941. diff -Nur linux-3.14.17/drivers/net/wireless/cw1200/sta.c linux-imx6-3.14/drivers/net/wireless/cw1200/sta.c
  203942. --- linux-3.14.17/drivers/net/wireless/cw1200/sta.c 2014-08-14 03:38:34.000000000 +0200
  203943. +++ linux-imx6-3.14/drivers/net/wireless/cw1200/sta.c 2014-09-11 18:06:03.926045662 +0200
  203944. @@ -936,7 +936,8 @@
  203945. return ret;
  203946. }
  203947. -void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  203948. +void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  203949. + u32 queues, bool drop)
  203950. {
  203951. struct cw1200_common *priv = hw->priv;
  203952. diff -Nur linux-3.14.17/drivers/net/wireless/cw1200/sta.h linux-imx6-3.14/drivers/net/wireless/cw1200/sta.h
  203953. --- linux-3.14.17/drivers/net/wireless/cw1200/sta.h 2014-08-14 03:38:34.000000000 +0200
  203954. +++ linux-imx6-3.14/drivers/net/wireless/cw1200/sta.h 2014-09-11 18:06:03.926045662 +0200
  203955. @@ -40,7 +40,8 @@
  203956. int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
  203957. -void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  203958. +void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  203959. + u32 queues, bool drop);
  203960. u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
  203961. struct netdev_hw_addr_list *mc_list);
  203962. diff -Nur linux-3.14.17/drivers/net/wireless/iwlegacy/common.c linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.c
  203963. --- linux-3.14.17/drivers/net/wireless/iwlegacy/common.c 2014-08-14 03:38:34.000000000 +0200
  203964. +++ linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.c 2014-09-11 18:06:03.942045725 +0200
  203965. @@ -4701,7 +4701,8 @@
  203966. }
  203967. EXPORT_SYMBOL(il_mac_change_interface);
  203968. -void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  203969. +void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  203970. + u32 queues, bool drop)
  203971. {
  203972. struct il_priv *il = hw->priv;
  203973. unsigned long timeout = jiffies + msecs_to_jiffies(500);
  203974. diff -Nur linux-3.14.17/drivers/net/wireless/iwlegacy/common.h linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.h
  203975. --- linux-3.14.17/drivers/net/wireless/iwlegacy/common.h 2014-08-14 03:38:34.000000000 +0200
  203976. +++ linux-imx6-3.14/drivers/net/wireless/iwlegacy/common.h 2014-09-11 18:06:03.946045742 +0200
  203977. @@ -1722,7 +1722,8 @@
  203978. struct ieee80211_vif *vif);
  203979. int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  203980. enum nl80211_iftype newtype, bool newp2p);
  203981. -void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  203982. +void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  203983. + u32 queues, bool drop);
  203984. int il_alloc_txq_mem(struct il_priv *il);
  203985. void il_free_txq_mem(struct il_priv *il);
  203986. diff -Nur linux-3.14.17/drivers/net/wireless/iwlwifi/dvm/mac80211.c linux-imx6-3.14/drivers/net/wireless/iwlwifi/dvm/mac80211.c
  203987. --- linux-3.14.17/drivers/net/wireless/iwlwifi/dvm/mac80211.c 2014-08-14 03:38:34.000000000 +0200
  203988. +++ linux-imx6-3.14/drivers/net/wireless/iwlwifi/dvm/mac80211.c 2014-09-11 18:06:03.950045758 +0200
  203989. @@ -1091,7 +1091,8 @@
  203990. FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
  203991. }
  203992. -static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  203993. +static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  203994. + u32 queues, bool drop)
  203995. {
  203996. struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
  203997. diff -Nur linux-3.14.17/drivers/net/wireless/libertas/cfg.c linux-imx6-3.14/drivers/net/wireless/libertas/cfg.c
  203998. --- linux-3.14.17/drivers/net/wireless/libertas/cfg.c 2014-08-14 03:38:34.000000000 +0200
  203999. +++ linux-imx6-3.14/drivers/net/wireless/libertas/cfg.c 2014-09-11 18:06:04.002045966 +0200
  204000. @@ -1766,7 +1766,8 @@
  204001. memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
  204002. priv->wdev->ssid_len = params->ssid_len;
  204003. - cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
  204004. + cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
  204005. + GFP_KERNEL);
  204006. /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
  204007. priv->connect_status = LBS_CONNECTED;
  204008. diff -Nur linux-3.14.17/drivers/net/wireless/mac80211_hwsim.c linux-imx6-3.14/drivers/net/wireless/mac80211_hwsim.c
  204009. --- linux-3.14.17/drivers/net/wireless/mac80211_hwsim.c 2014-08-14 03:38:34.000000000 +0200
  204010. +++ linux-imx6-3.14/drivers/net/wireless/mac80211_hwsim.c 2014-09-11 18:06:04.014046014 +0200
  204011. @@ -1671,7 +1671,9 @@
  204012. return 0;
  204013. }
  204014. -static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  204015. +static void mac80211_hwsim_flush(struct ieee80211_hw *hw,
  204016. + struct ieee80211_vif *vif,
  204017. + u32 queues, bool drop)
  204018. {
  204019. /* Not implemented, queues only on kernel side */
  204020. }
  204021. diff -Nur linux-3.14.17/drivers/net/wireless/mwifiex/cfg80211.c linux-imx6-3.14/drivers/net/wireless/mwifiex/cfg80211.c
  204022. --- linux-3.14.17/drivers/net/wireless/mwifiex/cfg80211.c 2014-08-14 03:38:34.000000000 +0200
  204023. +++ linux-imx6-3.14/drivers/net/wireless/mwifiex/cfg80211.c 2014-09-11 18:06:04.014046014 +0200
  204024. @@ -1881,7 +1881,8 @@
  204025. params->privacy);
  204026. done:
  204027. if (!ret) {
  204028. - cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
  204029. + cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
  204030. + params->chandef.chan, GFP_KERNEL);
  204031. dev_dbg(priv->adapter->dev,
  204032. "info: joined/created adhoc network with bssid"
  204033. " %pM successfully\n", priv->cfg_bssid);
  204034. diff -Nur linux-3.14.17/drivers/net/wireless/mwifiex/main.h linux-imx6-3.14/drivers/net/wireless/mwifiex/main.h
  204035. --- linux-3.14.17/drivers/net/wireless/mwifiex/main.h 2014-08-14 03:38:34.000000000 +0200
  204036. +++ linux-imx6-3.14/drivers/net/wireless/mwifiex/main.h 2014-09-11 18:06:04.026046061 +0200
  204037. @@ -1078,7 +1078,7 @@
  204038. const u8 *key, int key_len, u8 key_index,
  204039. const u8 *mac_addr, int disable);
  204040. -int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
  204041. +int mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len);
  204042. int mwifiex_get_ver_ext(struct mwifiex_private *priv);
  204043. diff -Nur linux-3.14.17/drivers/net/wireless/mwifiex/sta_ioctl.c linux-imx6-3.14/drivers/net/wireless/mwifiex/sta_ioctl.c
  204044. --- linux-3.14.17/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-08-14 03:38:34.000000000 +0200
  204045. +++ linux-imx6-3.14/drivers/net/wireless/mwifiex/sta_ioctl.c 2014-09-11 18:06:04.034046094 +0200
  204046. @@ -1391,7 +1391,7 @@
  204047. * with requisite parameters and calls the IOCTL handler.
  204048. */
  204049. int
  204050. -mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
  204051. +mwifiex_set_gen_ie(struct mwifiex_private *priv, const u8 *ie, int ie_len)
  204052. {
  204053. struct mwifiex_ds_misc_gen_ie gen_ie;
  204054. diff -Nur linux-3.14.17/drivers/net/wireless/p54/main.c linux-imx6-3.14/drivers/net/wireless/p54/main.c
  204055. --- linux-3.14.17/drivers/net/wireless/p54/main.c 2014-08-14 03:38:34.000000000 +0200
  204056. +++ linux-imx6-3.14/drivers/net/wireless/p54/main.c 2014-09-11 18:06:04.054046173 +0200
  204057. @@ -669,7 +669,8 @@
  204058. return total;
  204059. }
  204060. -static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop)
  204061. +static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
  204062. + u32 queues, bool drop)
  204063. {
  204064. struct p54_common *priv = dev->priv;
  204065. unsigned int total, i;
  204066. diff -Nur linux-3.14.17/drivers/net/wireless/rndis_wlan.c linux-imx6-3.14/drivers/net/wireless/rndis_wlan.c
  204067. --- linux-3.14.17/drivers/net/wireless/rndis_wlan.c 2014-08-14 03:38:34.000000000 +0200
  204068. +++ linux-imx6-3.14/drivers/net/wireless/rndis_wlan.c 2014-09-11 18:06:04.062046206 +0200
  204069. @@ -2835,7 +2835,9 @@
  204070. bssid, req_ie, req_ie_len,
  204071. resp_ie, resp_ie_len, GFP_KERNEL);
  204072. } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
  204073. - cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
  204074. + cfg80211_ibss_joined(usbdev->net, bssid,
  204075. + get_current_channel(usbdev, NULL),
  204076. + GFP_KERNEL);
  204077. kfree(info);
  204078. diff -Nur linux-3.14.17/drivers/net/wireless/rt2x00/rt2x00.h linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00.h
  204079. --- linux-3.14.17/drivers/net/wireless/rt2x00/rt2x00.h 2014-08-14 03:38:34.000000000 +0200
  204080. +++ linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00.h 2014-09-11 18:06:04.086046302 +0200
  204081. @@ -1449,7 +1449,8 @@
  204082. struct ieee80211_vif *vif, u16 queue,
  204083. const struct ieee80211_tx_queue_params *params);
  204084. void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
  204085. -void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
  204086. +void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  204087. + u32 queues, bool drop);
  204088. int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
  204089. int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
  204090. void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
  204091. diff -Nur linux-3.14.17/drivers/net/wireless/rt2x00/rt2x00mac.c linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00mac.c
  204092. --- linux-3.14.17/drivers/net/wireless/rt2x00/rt2x00mac.c 2014-08-14 03:38:34.000000000 +0200
  204093. +++ linux-imx6-3.14/drivers/net/wireless/rt2x00/rt2x00mac.c 2014-09-11 18:06:04.086046302 +0200
  204094. @@ -751,7 +751,8 @@
  204095. }
  204096. EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
  204097. -void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  204098. +void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  204099. + u32 queues, bool drop)
  204100. {
  204101. struct rt2x00_dev *rt2x00dev = hw->priv;
  204102. struct data_queue *queue;
  204103. diff -Nur linux-3.14.17/drivers/net/wireless/rtl818x/rtl8187/dev.c linux-imx6-3.14/drivers/net/wireless/rtl818x/rtl8187/dev.c
  204104. --- linux-3.14.17/drivers/net/wireless/rtl818x/rtl8187/dev.c 2014-08-14 03:38:34.000000000 +0200
  204105. +++ linux-imx6-3.14/drivers/net/wireless/rtl818x/rtl8187/dev.c 2014-09-11 18:06:04.110046397 +0200
  204106. @@ -1636,10 +1636,10 @@
  204107. err_free_dmabuf:
  204108. kfree(priv->io_dmabuf);
  204109. - err_free_dev:
  204110. - ieee80211_free_hw(dev);
  204111. usb_set_intfdata(intf, NULL);
  204112. usb_put_dev(udev);
  204113. + err_free_dev:
  204114. + ieee80211_free_hw(dev);
  204115. return err;
  204116. }
  204117. diff -Nur linux-3.14.17/drivers/net/wireless/rtlwifi/core.c linux-imx6-3.14/drivers/net/wireless/rtlwifi/core.c
  204118. --- linux-3.14.17/drivers/net/wireless/rtlwifi/core.c 2014-08-14 03:38:34.000000000 +0200
  204119. +++ linux-imx6-3.14/drivers/net/wireless/rtlwifi/core.c 2014-09-11 18:06:04.110046397 +0200
  204120. @@ -1309,7 +1309,8 @@
  204121. * before switch channel or power save, or tx buffer packet
  204122. * maybe send after offchannel or rf sleep, this may cause
  204123. * dis-association by AP */
  204124. -static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  204125. +static void rtl_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  204126. + u32 queues, bool drop)
  204127. {
  204128. struct rtl_priv *rtlpriv = rtl_priv(hw);
  204129. diff -Nur linux-3.14.17/drivers/net/wireless/ti/wlcore/main.c linux-imx6-3.14/drivers/net/wireless/ti/wlcore/main.c
  204130. --- linux-3.14.17/drivers/net/wireless/ti/wlcore/main.c 2014-08-14 03:38:34.000000000 +0200
  204131. +++ linux-imx6-3.14/drivers/net/wireless/ti/wlcore/main.c 2014-09-11 18:06:04.150046556 +0200
  204132. @@ -5156,7 +5156,8 @@
  204133. mutex_unlock(&wl->mutex);
  204134. }
  204135. -static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  204136. +static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  204137. + u32 queues, bool drop)
  204138. {
  204139. struct wl1271 *wl = hw->priv;
  204140. diff -Nur linux-3.14.17/drivers/parport/Kconfig linux-imx6-3.14/drivers/parport/Kconfig
  204141. --- linux-3.14.17/drivers/parport/Kconfig 2014-08-14 03:38:34.000000000 +0200
  204142. +++ linux-imx6-3.14/drivers/parport/Kconfig 2014-09-11 18:06:04.270047036 +0200
  204143. @@ -5,12 +5,6 @@
  204144. # Parport configuration.
  204145. #
  204146. -config ARCH_MIGHT_HAVE_PC_PARPORT
  204147. - bool
  204148. - help
  204149. - Select this config option from the architecture Kconfig if
  204150. - the architecture might have PC parallel port hardware.
  204151. -
  204152. menuconfig PARPORT
  204153. tristate "Parallel port support"
  204154. depends on HAS_IOMEM
  204155. @@ -37,6 +31,12 @@
  204156. If unsure, say Y.
  204157. +config ARCH_MIGHT_HAVE_PC_PARPORT
  204158. + bool
  204159. + help
  204160. + Select this config option from the architecture Kconfig if
  204161. + the architecture might have PC parallel port hardware.
  204162. +
  204163. if PARPORT
  204164. config PARPORT_PC
  204165. diff -Nur linux-3.14.17/drivers/pci/host/Kconfig linux-imx6-3.14/drivers/pci/host/Kconfig
  204166. --- linux-3.14.17/drivers/pci/host/Kconfig 2014-08-14 03:38:34.000000000 +0200
  204167. +++ linux-imx6-3.14/drivers/pci/host/Kconfig 2014-09-11 18:06:04.274047051 +0200
  204168. @@ -21,6 +21,23 @@
  204169. select PCIEPORTBUS
  204170. select PCIE_DW
  204171. +config EP_MODE_IN_EP_RC_SYS
  204172. + bool "PCI Express EP mode in the IMX6 RC/EP interconnection system"
  204173. + depends on PCI_IMX6
  204174. +
  204175. +config EP_SELF_IO_TEST
  204176. + bool "PCI Express EP_SELF_IO_TEST in EP mode"
  204177. + depends on EP_MODE_IN_EP_RC_SYS
  204178. +
  204179. +config RC_MODE_IN_EP_RC_SYS
  204180. + bool "PCI Express RC mode in the IMX6 RC/EP interconnection system"
  204181. + depends on PCI_IMX6
  204182. +
  204183. +config PCI_IMX_EP_DRV
  204184. + bool "i.MX6 PCI Express EP skeleton driver"
  204185. + depends on RC_MODE_IN_EP_RC_SYS
  204186. + default y
  204187. +
  204188. config PCI_TEGRA
  204189. bool "NVIDIA Tegra PCIe controller"
  204190. depends on ARCH_TEGRA
  204191. diff -Nur linux-3.14.17/drivers/pci/host/Makefile linux-imx6-3.14/drivers/pci/host/Makefile
  204192. --- linux-3.14.17/drivers/pci/host/Makefile 2014-08-14 03:38:34.000000000 +0200
  204193. +++ linux-imx6-3.14/drivers/pci/host/Makefile 2014-09-11 18:06:04.274047051 +0200
  204194. @@ -1,6 +1,7 @@
  204195. obj-$(CONFIG_PCIE_DW) += pcie-designware.o
  204196. obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
  204197. obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
  204198. +obj-$(CONFIG_PCI_IMX_EP_DRV) += pci-imx6-ep-driver.o
  204199. obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
  204200. obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
  204201. obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
  204202. diff -Nur linux-3.14.17/drivers/pci/host/pcie-designware.c linux-imx6-3.14/drivers/pci/host/pcie-designware.c
  204203. --- linux-3.14.17/drivers/pci/host/pcie-designware.c 2014-08-14 03:38:34.000000000 +0200
  204204. +++ linux-imx6-3.14/drivers/pci/host/pcie-designware.c 2014-09-11 18:06:04.274047051 +0200
  204205. @@ -23,48 +23,6 @@
  204206. #include "pcie-designware.h"
  204207. -/* Synopsis specific PCIE configuration registers */
  204208. -#define PCIE_PORT_LINK_CONTROL 0x710
  204209. -#define PORT_LINK_MODE_MASK (0x3f << 16)
  204210. -#define PORT_LINK_MODE_1_LANES (0x1 << 16)
  204211. -#define PORT_LINK_MODE_2_LANES (0x3 << 16)
  204212. -#define PORT_LINK_MODE_4_LANES (0x7 << 16)
  204213. -
  204214. -#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
  204215. -#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
  204216. -#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
  204217. -#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
  204218. -#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
  204219. -#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
  204220. -
  204221. -#define PCIE_MSI_ADDR_LO 0x820
  204222. -#define PCIE_MSI_ADDR_HI 0x824
  204223. -#define PCIE_MSI_INTR0_ENABLE 0x828
  204224. -#define PCIE_MSI_INTR0_MASK 0x82C
  204225. -#define PCIE_MSI_INTR0_STATUS 0x830
  204226. -
  204227. -#define PCIE_ATU_VIEWPORT 0x900
  204228. -#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
  204229. -#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
  204230. -#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
  204231. -#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
  204232. -#define PCIE_ATU_CR1 0x904
  204233. -#define PCIE_ATU_TYPE_MEM (0x0 << 0)
  204234. -#define PCIE_ATU_TYPE_IO (0x2 << 0)
  204235. -#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
  204236. -#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
  204237. -#define PCIE_ATU_CR2 0x908
  204238. -#define PCIE_ATU_ENABLE (0x1 << 31)
  204239. -#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
  204240. -#define PCIE_ATU_LOWER_BASE 0x90C
  204241. -#define PCIE_ATU_UPPER_BASE 0x910
  204242. -#define PCIE_ATU_LIMIT 0x914
  204243. -#define PCIE_ATU_LOWER_TARGET 0x918
  204244. -#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
  204245. -#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
  204246. -#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
  204247. -#define PCIE_ATU_UPPER_TARGET 0x91C
  204248. -
  204249. static struct hw_pci dw_pci;
  204250. static unsigned long global_io_offset;
  204251. @@ -332,23 +290,28 @@
  204252. return -EINVAL;
  204253. }
  204254. - pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
  204255. - &msg_ctr);
  204256. - msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
  204257. - if (msgvec == 0)
  204258. - msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
  204259. - if (msgvec > 5)
  204260. - msgvec = 0;
  204261. -
  204262. - irq = assign_irq((1 << msgvec), desc, &pos);
  204263. - if (irq < 0)
  204264. - return irq;
  204265. -
  204266. - /*
  204267. - * write_msi_msg() will update PCI_MSI_FLAGS so there is
  204268. - * no need to explicitly call pci_write_config_word().
  204269. - */
  204270. - desc->msi_attrib.multiple = msgvec;
  204271. + if (pp->quirks & DW_PCIE_QUIRK_NO_MSI_VEC) {
  204272. + irq = assign_irq(1, desc, &pos);
  204273. + set_irq_flags(irq, IRQF_VALID);
  204274. + } else {
  204275. + pci_read_config_word(pdev, desc->msi_attrib.pos+PCI_MSI_FLAGS,
  204276. + &msg_ctr);
  204277. + msgvec = (msg_ctr&PCI_MSI_FLAGS_QSIZE) >> 4;
  204278. + if (msgvec == 0)
  204279. + msgvec = (msg_ctr & PCI_MSI_FLAGS_QMASK) >> 1;
  204280. + if (msgvec > 5)
  204281. + msgvec = 0;
  204282. +
  204283. + irq = assign_irq((1 << msgvec), desc, &pos);
  204284. + if (irq < 0)
  204285. + return irq;
  204286. +
  204287. + msg_ctr &= ~PCI_MSI_FLAGS_QSIZE;
  204288. + msg_ctr |= msgvec << 4;
  204289. + pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
  204290. + msg_ctr);
  204291. + desc->msi_attrib.multiple = msgvec;
  204292. + }
  204293. msg.address_lo = virt_to_phys((void *)pp->msi_data);
  204294. msg.address_hi = 0x0;
  204295. @@ -363,9 +326,30 @@
  204296. clear_irq(irq);
  204297. }
  204298. +static int dw_msi_check_device(struct msi_chip *chip, struct pci_dev *pdev,
  204299. + int nvec, int type)
  204300. +{
  204301. + struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
  204302. + u32 val;
  204303. +
  204304. + if (pp->quirks & DW_PCIE_QUIRK_MSI_SELF_EN) {
  204305. + if ((type == PCI_CAP_ID_MSI) || (type == PCI_CAP_ID_MSIX)) {
  204306. + /* Set MSI enable of RC here */
  204307. + val = readl(pp->dbi_base + 0x50);
  204308. + if ((val & (PCI_MSI_FLAGS_ENABLE << 16)) == 0) {
  204309. + val |= PCI_MSI_FLAGS_ENABLE << 16;
  204310. + writel(val, pp->dbi_base + 0x50);
  204311. + }
  204312. + }
  204313. + }
  204314. +
  204315. + return 0;
  204316. +}
  204317. +
  204318. static struct msi_chip dw_pcie_msi_chip = {
  204319. .setup_irq = dw_msi_setup_irq,
  204320. .teardown_irq = dw_msi_teardown_irq,
  204321. + .check_device = dw_msi_check_device,
  204322. };
  204323. int dw_pcie_link_up(struct pcie_port *pp)
  204324. @@ -531,38 +515,6 @@
  204325. dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  204326. }
  204327. -static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
  204328. -{
  204329. - /* Program viewport 0 : OUTBOUND : MEM */
  204330. - dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
  204331. - PCIE_ATU_VIEWPORT);
  204332. - dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
  204333. - dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
  204334. - dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
  204335. - dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
  204336. - PCIE_ATU_LIMIT);
  204337. - dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
  204338. - dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
  204339. - PCIE_ATU_UPPER_TARGET);
  204340. - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  204341. -}
  204342. -
  204343. -static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
  204344. -{
  204345. - /* Program viewport 1 : OUTBOUND : IO */
  204346. - dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
  204347. - PCIE_ATU_VIEWPORT);
  204348. - dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
  204349. - dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
  204350. - dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
  204351. - dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
  204352. - PCIE_ATU_LIMIT);
  204353. - dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
  204354. - dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
  204355. - PCIE_ATU_UPPER_TARGET);
  204356. - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
  204357. -}
  204358. -
  204359. static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
  204360. u32 devfn, int where, int size, u32 *val)
  204361. {
  204362. @@ -577,12 +529,10 @@
  204363. dw_pcie_prog_viewport_cfg0(pp, busdev);
  204364. ret = dw_pcie_cfg_read(pp->va_cfg0_base + address, where, size,
  204365. val);
  204366. - dw_pcie_prog_viewport_mem_outbound(pp);
  204367. } else {
  204368. dw_pcie_prog_viewport_cfg1(pp, busdev);
  204369. ret = dw_pcie_cfg_read(pp->va_cfg1_base + address, where, size,
  204370. val);
  204371. - dw_pcie_prog_viewport_io_outbound(pp);
  204372. }
  204373. return ret;
  204374. @@ -602,12 +552,10 @@
  204375. dw_pcie_prog_viewport_cfg0(pp, busdev);
  204376. ret = dw_pcie_cfg_write(pp->va_cfg0_base + address, where, size,
  204377. val);
  204378. - dw_pcie_prog_viewport_mem_outbound(pp);
  204379. } else {
  204380. dw_pcie_prog_viewport_cfg1(pp, busdev);
  204381. ret = dw_pcie_cfg_write(pp->va_cfg1_base + address, where, size,
  204382. val);
  204383. - dw_pcie_prog_viewport_io_outbound(pp);
  204384. }
  204385. return ret;
  204386. @@ -739,7 +687,13 @@
  204387. {
  204388. struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
  204389. - return pp->irq;
  204390. + switch (pin) {
  204391. + case 1: return pp->irq;
  204392. + case 2: return pp->irq - 1;
  204393. + case 3: return pp->irq - 2;
  204394. + case 4: return pp->irq - 3;
  204395. + default: return -1;
  204396. + }
  204397. }
  204398. static void dw_pcie_add_bus(struct pci_bus *bus)
  204399. diff -Nur linux-3.14.17/drivers/pci/host/pcie-designware.h linux-imx6-3.14/drivers/pci/host/pcie-designware.h
  204400. --- linux-3.14.17/drivers/pci/host/pcie-designware.h 2014-08-14 03:38:34.000000000 +0200
  204401. +++ linux-imx6-3.14/drivers/pci/host/pcie-designware.h 2014-09-11 18:06:04.274047051 +0200
  204402. @@ -14,6 +14,48 @@
  204403. #ifndef _PCIE_DESIGNWARE_H
  204404. #define _PCIE_DESIGNWARE_H
  204405. +/* Synopsis specific PCIE configuration registers */
  204406. +#define PCIE_PORT_LINK_CONTROL 0x710
  204407. +#define PORT_LINK_MODE_MASK (0x3f << 16)
  204408. +#define PORT_LINK_MODE_1_LANES (0x1 << 16)
  204409. +#define PORT_LINK_MODE_2_LANES (0x3 << 16)
  204410. +#define PORT_LINK_MODE_4_LANES (0x7 << 16)
  204411. +
  204412. +#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
  204413. +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
  204414. +#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
  204415. +#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
  204416. +#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
  204417. +#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
  204418. +
  204419. +#define PCIE_MSI_ADDR_LO 0x820
  204420. +#define PCIE_MSI_ADDR_HI 0x824
  204421. +#define PCIE_MSI_INTR0_ENABLE 0x828
  204422. +#define PCIE_MSI_INTR0_MASK 0x82C
  204423. +#define PCIE_MSI_INTR0_STATUS 0x830
  204424. +
  204425. +#define PCIE_ATU_VIEWPORT 0x900
  204426. +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
  204427. +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
  204428. +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
  204429. +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
  204430. +#define PCIE_ATU_CR1 0x904
  204431. +#define PCIE_ATU_TYPE_MEM (0x0 << 0)
  204432. +#define PCIE_ATU_TYPE_IO (0x2 << 0)
  204433. +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
  204434. +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
  204435. +#define PCIE_ATU_CR2 0x908
  204436. +#define PCIE_ATU_ENABLE (0x1 << 31)
  204437. +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
  204438. +#define PCIE_ATU_LOWER_BASE 0x90C
  204439. +#define PCIE_ATU_UPPER_BASE 0x910
  204440. +#define PCIE_ATU_LIMIT 0x914
  204441. +#define PCIE_ATU_LOWER_TARGET 0x918
  204442. +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
  204443. +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
  204444. +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
  204445. +#define PCIE_ATU_UPPER_TARGET 0x91C
  204446. +
  204447. struct pcie_port_info {
  204448. u32 cfg0_size;
  204449. u32 cfg1_size;
  204450. @@ -49,6 +91,11 @@
  204451. int irq;
  204452. u32 lanes;
  204453. struct pcie_host_ops *ops;
  204454. + u32 quirks; /* Deviations from spec. */
  204455. +/* Controller doesn't support MSI VEC */
  204456. +#define DW_PCIE_QUIRK_NO_MSI_VEC (1<<0)
  204457. +/* MSI EN of Controller should be configured when MSI is enabled */
  204458. +#define DW_PCIE_QUIRK_MSI_SELF_EN (1<<1)
  204459. int msi_irq;
  204460. struct irq_domain *irq_domain;
  204461. unsigned long msi_data;
  204462. diff -Nur linux-3.14.17/drivers/pci/host/pci-imx6.c linux-imx6-3.14/drivers/pci/host/pci-imx6.c
  204463. --- linux-3.14.17/drivers/pci/host/pci-imx6.c 2014-08-14 03:38:34.000000000 +0200
  204464. +++ linux-imx6-3.14/drivers/pci/host/pci-imx6.c 2014-09-11 18:06:04.274047051 +0200
  204465. @@ -1,6 +1,7 @@
  204466. /*
  204467. * PCIe host controller driver for Freescale i.MX6 SoCs
  204468. *
  204469. + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  204470. * Copyright (C) 2013 Kosagi
  204471. * http://www.kosagi.com
  204472. *
  204473. @@ -14,6 +15,7 @@
  204474. #include <linux/clk.h>
  204475. #include <linux/delay.h>
  204476. #include <linux/gpio.h>
  204477. +#include <linux/interrupt.h>
  204478. #include <linux/kernel.h>
  204479. #include <linux/mfd/syscon.h>
  204480. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  204481. @@ -25,11 +27,21 @@
  204482. #include <linux/resource.h>
  204483. #include <linux/signal.h>
  204484. #include <linux/types.h>
  204485. +#include <linux/busfreq-imx6.h>
  204486. #include "pcie-designware.h"
  204487. #define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp)
  204488. +/*
  204489. + * The default value of the reserved ddr memory
  204490. + * used to verify EP/RC memory space access operations.
  204491. + * BTW, here is the layout of the 1G ddr on SD boards
  204492. + * 0x1000_0000 ~ 0x4FFF_FFFF
  204493. + */
  204494. +static u32 ddr_test_region = 0x40000000;
  204495. +static u32 test_region_size = SZ_2M;
  204496. +
  204497. struct imx6_pcie {
  204498. int reset_gpio;
  204499. int power_on_gpio;
  204500. @@ -52,6 +64,9 @@
  204501. /* PCIe Port Logic registers (memory-mapped) */
  204502. #define PL_OFFSET 0x700
  204503. +#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
  204504. +#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
  204505. +#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)
  204506. #define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
  204507. #define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
  204508. #define PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING (1 << 29)
  204509. @@ -216,14 +231,14 @@
  204510. static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
  204511. {
  204512. - struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  204513. + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  204514. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204515. - IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
  204516. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204517. - IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
  204518. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204519. + IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
  204520. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204521. + IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
  204522. - return 0;
  204523. + return 0;
  204524. }
  204525. static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
  204526. @@ -234,10 +249,7 @@
  204527. if (gpio_is_valid(imx6_pcie->power_on_gpio))
  204528. gpio_set_value(imx6_pcie->power_on_gpio, 1);
  204529. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204530. - IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
  204531. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204532. - IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
  204533. + request_bus_freq(BUS_FREQ_HIGH);
  204534. ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
  204535. if (ret) {
  204536. @@ -251,10 +263,13 @@
  204537. goto err_pcie_ref;
  204538. }
  204539. - ret = clk_prepare_enable(imx6_pcie->lvds_gate);
  204540. - if (ret) {
  204541. - dev_err(pp->dev, "unable to enable lvds_gate\n");
  204542. - goto err_lvds_gate;
  204543. + if (!IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)
  204544. + && !IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)) {
  204545. + ret = clk_prepare_enable(imx6_pcie->lvds_gate);
  204546. + if (ret) {
  204547. + dev_err(pp->dev, "unable to enable lvds_gate\n");
  204548. + goto err_lvds_gate;
  204549. + }
  204550. }
  204551. ret = clk_prepare_enable(imx6_pcie->pcie_axi);
  204552. @@ -266,6 +281,12 @@
  204553. /* allow the clocks to stabilize */
  204554. usleep_range(200, 500);
  204555. + /* power up core phy and enable ref clock */
  204556. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204557. + IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
  204558. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
  204559. + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
  204560. +
  204561. /* Some boards don't have PCIe reset GPIO. */
  204562. if (gpio_is_valid(imx6_pcie->reset_gpio)) {
  204563. gpio_set_value(imx6_pcie->reset_gpio, 0);
  204564. @@ -281,6 +302,7 @@
  204565. err_pcie_ref:
  204566. clk_disable_unprepare(imx6_pcie->sata_ref_100m);
  204567. err_sata_ref:
  204568. + release_bus_freq(BUS_FREQ_HIGH);
  204569. return ret;
  204570. }
  204571. @@ -288,13 +310,44 @@
  204572. static void imx6_pcie_init_phy(struct pcie_port *pp)
  204573. {
  204574. struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
  204575. + u32 val, gpr1, gpr12;
  204576. +
  204577. + /*
  204578. + * If the bootloader already enabled the link we need some special
  204579. + * handling to get the core back into a state where it is safe to
  204580. + * touch it for configuration. As there is no dedicated reset signal
  204581. + * wired up for MX6QDL, we need to manually force LTSSM into "detect"
  204582. + * state before completely disabling LTSSM, which is a prerequisite
  204583. + * for core configuration.
  204584. + * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
  204585. + * indication that the bootloader activated the link.
  204586. + */
  204587. + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1);
  204588. + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12);
  204589. +
  204590. + if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) &&
  204591. + (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) {
  204592. + val = readl(pp->dbi_base + PCIE_PL_PFLR);
  204593. + val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
  204594. + val |= PCIE_PL_PFLR_FORCE_LINK;
  204595. + writel(val, pp->dbi_base + PCIE_PL_PFLR);
  204596. +
  204597. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  204598. + IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
  204599. + }
  204600. regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  204601. IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
  204602. /* configure constant input signal to the pcie ctrl and phy */
  204603. - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  204604. - IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
  204605. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS))
  204606. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  204607. + IMX6Q_GPR12_DEVICE_TYPE,
  204608. + PCI_EXP_TYPE_ENDPOINT << 12);
  204609. + else
  204610. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  204611. + IMX6Q_GPR12_DEVICE_TYPE,
  204612. + PCI_EXP_TYPE_ROOT_PORT << 12);
  204613. regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  204614. IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
  204615. @@ -326,6 +379,12 @@
  204616. return -EINVAL;
  204617. }
  204618. + if (IS_ENABLED(CONFIG_PCI_MSI)) {
  204619. + pp->quirks |= DW_PCIE_QUIRK_NO_MSI_VEC;
  204620. + pp->quirks |= DW_PCIE_QUIRK_MSI_SELF_EN;
  204621. + dw_pcie_msi_init(pp);
  204622. + }
  204623. +
  204624. return 0;
  204625. }
  204626. @@ -392,6 +451,15 @@
  204627. return ret;
  204628. }
  204629. +static irqreturn_t imx_pcie_msi_irq_handler(int irq, void *arg)
  204630. +{
  204631. + struct pcie_port *pp = arg;
  204632. +
  204633. + dw_handle_msi_irq(pp);
  204634. +
  204635. + return IRQ_HANDLED;
  204636. +}
  204637. +
  204638. static void imx6_pcie_host_init(struct pcie_port *pp)
  204639. {
  204640. imx6_pcie_assert_core_reset(pp);
  204641. @@ -498,6 +566,22 @@
  204642. return -ENODEV;
  204643. }
  204644. + if (IS_ENABLED(CONFIG_PCI_MSI)) {
  204645. + pp->msi_irq = pp->irq - 3;
  204646. + if (!pp->msi_irq) {
  204647. + dev_err(&pdev->dev, "failed to get msi irq\n");
  204648. + return -ENODEV;
  204649. + }
  204650. +
  204651. + ret = devm_request_irq(&pdev->dev, pp->msi_irq,
  204652. + imx_pcie_msi_irq_handler,
  204653. + IRQF_SHARED, "imx6q-pcie", pp);
  204654. + if (ret) {
  204655. + dev_err(&pdev->dev, "failed to request msi irq\n");
  204656. + return ret;
  204657. + }
  204658. + }
  204659. +
  204660. pp->root_bus_nr = -1;
  204661. pp->ops = &imx6_pcie_host_ops;
  204662. @@ -511,29 +595,188 @@
  204663. return 0;
  204664. }
  204665. +static ssize_t imx_pcie_bar0_addr_info(struct device *dev,
  204666. + struct device_attribute *devattr, char *buf)
  204667. +{
  204668. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  204669. + struct pcie_port *pp = &imx6_pcie->pp;
  204670. +
  204671. + return sprintf(buf, "imx-pcie-bar0-addr-info start 0x%08x\n",
  204672. + readl(pp->dbi_base + PCI_BASE_ADDRESS_0));
  204673. +}
  204674. +
  204675. +static ssize_t imx_pcie_bar0_addr_start(struct device *dev,
  204676. + struct device_attribute *attr, const char *buf, size_t count)
  204677. +{
  204678. + u32 bar_start;
  204679. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  204680. + struct pcie_port *pp = &imx6_pcie->pp;
  204681. +
  204682. + sscanf(buf, "%x\n", &bar_start);
  204683. + writel(bar_start, pp->dbi_base + PCI_BASE_ADDRESS_0);
  204684. +
  204685. + return count;
  204686. +}
  204687. +
  204688. +static void imx_pcie_regions_setup(struct device *dev)
  204689. +{
  204690. + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
  204691. + struct pcie_port *pp = &imx6_pcie->pp;
  204692. +
  204693. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  204694. + /*
  204695. + * region2 outbound used to access rc mem
  204696. + * in imx6 pcie ep/rc validation system
  204697. + */
  204698. + writel(0, pp->dbi_base + PCIE_ATU_VIEWPORT);
  204699. + writel(0x01000000, pp->dbi_base + PCIE_ATU_LOWER_BASE);
  204700. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_BASE);
  204701. + writel(0x01000000 + test_region_size,
  204702. + pp->dbi_base + PCIE_ATU_LIMIT);
  204703. +
  204704. + writel(ddr_test_region,
  204705. + pp->dbi_base + PCIE_ATU_LOWER_TARGET);
  204706. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_TARGET);
  204707. + writel(PCIE_ATU_TYPE_MEM, pp->dbi_base + PCIE_ATU_CR1);
  204708. + writel(PCIE_ATU_ENABLE, pp->dbi_base + PCIE_ATU_CR2);
  204709. + }
  204710. +
  204711. + if (IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)) {
  204712. + /*
  204713. + * region2 outbound used to access ep mem
  204714. + * in imx6 pcie ep/rc validation system
  204715. + */
  204716. + writel(2, pp->dbi_base + PCIE_ATU_VIEWPORT);
  204717. + writel(0x01000000, pp->dbi_base + PCIE_ATU_LOWER_BASE);
  204718. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_BASE);
  204719. + writel(0x01000000 + test_region_size,
  204720. + pp->dbi_base + PCIE_ATU_LIMIT);
  204721. +
  204722. + writel(ddr_test_region,
  204723. + pp->dbi_base + PCIE_ATU_LOWER_TARGET);
  204724. + writel(0, pp->dbi_base + PCIE_ATU_UPPER_TARGET);
  204725. + writel(PCIE_ATU_TYPE_MEM, pp->dbi_base + PCIE_ATU_CR1);
  204726. + writel(PCIE_ATU_ENABLE, pp->dbi_base + PCIE_ATU_CR2);
  204727. + }
  204728. +}
  204729. +
  204730. +static ssize_t imx_pcie_memw_info(struct device *dev,
  204731. + struct device_attribute *devattr, char *buf)
  204732. +{
  204733. + return sprintf(buf, "imx-pcie-rc-memw-info start 0x%08x, size 0x%08x\n",
  204734. + ddr_test_region, test_region_size);
  204735. +}
  204736. +
  204737. +static ssize_t
  204738. +imx_pcie_memw_start(struct device *dev, struct device_attribute *attr,
  204739. + const char *buf, size_t count)
  204740. +{
  204741. + u32 memw_start;
  204742. +
  204743. + sscanf(buf, "%x\n", &memw_start);
  204744. +
  204745. + if (memw_start < 0x10000000) {
  204746. + dev_err(dev, "Invalid memory start address.\n");
  204747. + dev_info(dev, "For example: echo 0x41000000 > /sys/...");
  204748. + return -1;
  204749. + }
  204750. +
  204751. + if (ddr_test_region != memw_start) {
  204752. + ddr_test_region = memw_start;
  204753. + /* Re-setup the iATU */
  204754. + imx_pcie_regions_setup(dev);
  204755. + }
  204756. +
  204757. + return count;
  204758. +}
  204759. +
  204760. +static ssize_t
  204761. +imx_pcie_memw_size(struct device *dev, struct device_attribute *attr,
  204762. + const char *buf, size_t count)
  204763. +{
  204764. + u32 memw_size;
  204765. +
  204766. + sscanf(buf, "%x\n", &memw_size);
  204767. +
  204768. + if ((memw_size > (SZ_16M - SZ_1M)) || (memw_size < SZ_64K)) {
  204769. + dev_err(dev, "Invalid, should be [SZ_64K,SZ_16M - SZ_1MB].\n");
  204770. + dev_info(dev, "For example: echo 0x800000 > /sys/...");
  204771. + return -1;
  204772. + }
  204773. +
  204774. + if (test_region_size != memw_size) {
  204775. + test_region_size = memw_size;
  204776. + /* Re-setup the iATU */
  204777. + imx_pcie_regions_setup(dev);
  204778. + }
  204779. +
  204780. + return count;
  204781. +}
  204782. +
  204783. +static DEVICE_ATTR(memw_info, S_IRUGO, imx_pcie_memw_info, NULL);
  204784. +static DEVICE_ATTR(memw_start_set, S_IWUGO, NULL, imx_pcie_memw_start);
  204785. +static DEVICE_ATTR(memw_size_set, S_IWUGO, NULL, imx_pcie_memw_size);
  204786. +static DEVICE_ATTR(ep_bar0_addr, S_IRWXUGO, imx_pcie_bar0_addr_info,
  204787. + imx_pcie_bar0_addr_start);
  204788. +
  204789. +static struct attribute *imx_pcie_attrs[] = {
  204790. + /*
  204791. + * The start address, and the limitation (64KB ~ (16MB - 1MB))
  204792. + * of the ddr mem window reserved by RC, and used for EP to access.
  204793. + * BTW, these attrs are only configured at EP side.
  204794. + */
  204795. + &dev_attr_memw_info.attr,
  204796. + &dev_attr_memw_start_set.attr,
  204797. + &dev_attr_memw_size_set.attr,
  204798. + &dev_attr_ep_bar0_addr.attr,
  204799. + NULL
  204800. +};
  204801. +
  204802. +static struct attribute_group imx_pcie_attrgroup = {
  204803. + .attrs = imx_pcie_attrs,
  204804. +};
  204805. +
  204806. static int __init imx6_pcie_probe(struct platform_device *pdev)
  204807. {
  204808. struct imx6_pcie *imx6_pcie;
  204809. struct pcie_port *pp;
  204810. struct device_node *np = pdev->dev.of_node;
  204811. struct resource *dbi_base;
  204812. - int ret;
  204813. + int ret = 0;
  204814. + int i;
  204815. + void *test_reg1, *test_reg2;
  204816. + void __iomem *pcie_arb_base_addr;
  204817. + struct timeval tv1, tv2, tv3;
  204818. + u32 tv_count1, tv_count2;
  204819. imx6_pcie = devm_kzalloc(&pdev->dev, sizeof(*imx6_pcie), GFP_KERNEL);
  204820. - if (!imx6_pcie)
  204821. - return -ENOMEM;
  204822. + if (!imx6_pcie) {
  204823. + ret = -ENOMEM;
  204824. + goto err;
  204825. + }
  204826. pp = &imx6_pcie->pp;
  204827. pp->dev = &pdev->dev;
  204828. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  204829. + /* add attributes for device */
  204830. + ret = sysfs_create_group(&pdev->dev.kobj, &imx_pcie_attrgroup);
  204831. + if (ret) {
  204832. + ret = -EINVAL;
  204833. + goto err;
  204834. + }
  204835. + }
  204836. +
  204837. /* Added for PCI abort handling */
  204838. hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
  204839. "imprecise external abort");
  204840. dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  204841. pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base);
  204842. - if (IS_ERR(pp->dbi_base))
  204843. - return PTR_ERR(pp->dbi_base);
  204844. + if (IS_ERR(pp->dbi_base)) {
  204845. + ret = PTR_ERR(pp->dbi_base);
  204846. + goto err;
  204847. + }
  204848. /* Fetch GPIOs */
  204849. imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
  204850. @@ -542,7 +785,7 @@
  204851. GPIOF_OUT_INIT_LOW, "PCIe reset");
  204852. if (ret) {
  204853. dev_err(&pdev->dev, "unable to get reset gpio\n");
  204854. - return ret;
  204855. + goto err;
  204856. }
  204857. }
  204858. @@ -554,7 +797,7 @@
  204859. "PCIe power enable");
  204860. if (ret) {
  204861. dev_err(&pdev->dev, "unable to get power-on gpio\n");
  204862. - return ret;
  204863. + goto err;
  204864. }
  204865. }
  204866. @@ -566,7 +809,7 @@
  204867. "PCIe wake up");
  204868. if (ret) {
  204869. dev_err(&pdev->dev, "unable to get wake-up gpio\n");
  204870. - return ret;
  204871. + goto err;
  204872. }
  204873. }
  204874. @@ -578,7 +821,7 @@
  204875. "PCIe disable endpoint");
  204876. if (ret) {
  204877. dev_err(&pdev->dev, "unable to get disable-ep gpio\n");
  204878. - return ret;
  204879. + goto err;
  204880. }
  204881. }
  204882. @@ -587,28 +830,32 @@
  204883. if (IS_ERR(imx6_pcie->lvds_gate)) {
  204884. dev_err(&pdev->dev,
  204885. "lvds_gate clock select missing or invalid\n");
  204886. - return PTR_ERR(imx6_pcie->lvds_gate);
  204887. + ret = PTR_ERR(imx6_pcie->lvds_gate);
  204888. + goto err;
  204889. }
  204890. imx6_pcie->sata_ref_100m = devm_clk_get(&pdev->dev, "sata_ref_100m");
  204891. if (IS_ERR(imx6_pcie->sata_ref_100m)) {
  204892. dev_err(&pdev->dev,
  204893. "sata_ref_100m clock source missing or invalid\n");
  204894. - return PTR_ERR(imx6_pcie->sata_ref_100m);
  204895. + ret = PTR_ERR(imx6_pcie->sata_ref_100m);
  204896. + goto err;
  204897. }
  204898. imx6_pcie->pcie_ref_125m = devm_clk_get(&pdev->dev, "pcie_ref_125m");
  204899. if (IS_ERR(imx6_pcie->pcie_ref_125m)) {
  204900. dev_err(&pdev->dev,
  204901. "pcie_ref_125m clock source missing or invalid\n");
  204902. - return PTR_ERR(imx6_pcie->pcie_ref_125m);
  204903. + ret = PTR_ERR(imx6_pcie->pcie_ref_125m);
  204904. + goto err;
  204905. }
  204906. imx6_pcie->pcie_axi = devm_clk_get(&pdev->dev, "pcie_axi");
  204907. if (IS_ERR(imx6_pcie->pcie_axi)) {
  204908. dev_err(&pdev->dev,
  204909. "pcie_axi clock source missing or invalid\n");
  204910. - return PTR_ERR(imx6_pcie->pcie_axi);
  204911. + ret = PTR_ERR(imx6_pcie->pcie_axi);
  204912. + goto err;
  204913. }
  204914. /* Grab GPR config register range */
  204915. @@ -616,15 +863,175 @@
  204916. syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
  204917. if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
  204918. dev_err(&pdev->dev, "unable to find iomuxc registers\n");
  204919. - return PTR_ERR(imx6_pcie->iomuxc_gpr);
  204920. + ret = PTR_ERR(imx6_pcie->iomuxc_gpr);
  204921. + goto err;
  204922. }
  204923. - ret = imx6_add_pcie_port(pp, pdev);
  204924. - if (ret < 0)
  204925. - return ret;
  204926. + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) {
  204927. + if (IS_ENABLED(CONFIG_EP_SELF_IO_TEST)) {
  204928. + /* Prepare the test regions and data */
  204929. + test_reg1 = devm_kzalloc(&pdev->dev,
  204930. + test_region_size, GFP_KERNEL);
  204931. + if (!test_reg1) {
  204932. + pr_err("pcie ep: can't alloc the test reg1.\n");
  204933. + ret = PTR_ERR(test_reg1);
  204934. + goto err;
  204935. + }
  204936. +
  204937. + test_reg2 = devm_kzalloc(&pdev->dev,
  204938. + test_region_size, GFP_KERNEL);
  204939. + if (!test_reg2) {
  204940. + pr_err("pcie ep: can't alloc the test reg2.\n");
  204941. + ret = PTR_ERR(test_reg1);
  204942. + goto err;
  204943. + }
  204944. +
  204945. + pcie_arb_base_addr = ioremap_cache(0x01000000,
  204946. + test_region_size);
  204947. +
  204948. + if (!pcie_arb_base_addr) {
  204949. + pr_err("error with ioremap in ep selftest\n");
  204950. + ret = PTR_ERR(pcie_arb_base_addr);
  204951. + goto err;
  204952. + }
  204953. +
  204954. + for (i = 0; i < test_region_size; i = i + 4) {
  204955. + writel(0xE6600D00 + i, test_reg1 + i);
  204956. + writel(0xDEADBEAF, test_reg2 + i);
  204957. + }
  204958. + }
  204959. - platform_set_drvdata(pdev, imx6_pcie);
  204960. - return 0;
  204961. + imx6_pcie_init_phy(pp);
  204962. +
  204963. + imx6_pcie_deassert_core_reset(pp);
  204964. +
  204965. + /* assert LTSSM enable */
  204966. + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
  204967. + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
  204968. +
  204969. +
  204970. + dev_info(&pdev->dev, "PCIe EP: waiting for link up...\n");
  204971. +
  204972. + platform_set_drvdata(pdev, imx6_pcie);
  204973. + /* link is indicated by the bit4 of DB_R1 register */
  204974. + do {
  204975. + usleep_range(10, 20);
  204976. + } while ((readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & 0x10) == 0);
  204977. +
  204978. + /* CMD reg:I/O space, MEM space, and Bus Master Enable */
  204979. + writel(readl(pp->dbi_base + PCI_COMMAND)
  204980. + | PCI_COMMAND_IO
  204981. + | PCI_COMMAND_MEMORY
  204982. + | PCI_COMMAND_MASTER,
  204983. + pp->dbi_base + PCI_COMMAND);
  204984. +
  204985. + /*
  204986. + * configure the class_rev(emaluate one memory ram ep device),
  204987. + * bar0 and bar1 of ep
  204988. + */
  204989. + writel(0xdeadbeaf, pp->dbi_base + PCI_VENDOR_ID);
  204990. + writel(readl(pp->dbi_base + PCI_CLASS_REVISION)
  204991. + | (PCI_CLASS_MEMORY_RAM << 16),
  204992. + pp->dbi_base + PCI_CLASS_REVISION);
  204993. + writel(0xdeadbeaf, pp->dbi_base
  204994. + + PCI_SUBSYSTEM_VENDOR_ID);
  204995. +
  204996. + /* 32bit none-prefetchable 8M bytes memory on bar0 */
  204997. + writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_0);
  204998. + writel(SZ_8M - 1, pp->dbi_base + (1 << 12)
  204999. + + PCI_BASE_ADDRESS_0);
  205000. +
  205001. + /* None used bar1 */
  205002. + writel(0x0, pp->dbi_base + PCI_BASE_ADDRESS_1);
  205003. + writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_1);
  205004. +
  205005. + /* 4K bytes IO on bar2 */
  205006. + writel(0x1, pp->dbi_base + PCI_BASE_ADDRESS_2);
  205007. + writel(SZ_4K - 1, pp->dbi_base + (1 << 12) +
  205008. + PCI_BASE_ADDRESS_2);
  205009. +
  205010. + /*
  205011. + * 32bit prefetchable 1M bytes memory on bar3
  205012. + * FIXME BAR MASK3 is not changable, the size
  205013. + * is fixed to 256 bytes.
  205014. + */
  205015. + writel(0x8, pp->dbi_base + PCI_BASE_ADDRESS_3);
  205016. + writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
  205017. + + PCI_BASE_ADDRESS_3);
  205018. +
  205019. + /*
  205020. + * 64bit prefetchable 1M bytes memory on bar4-5.
  205021. + * FIXME BAR4,5 are not enabled yet
  205022. + */
  205023. + writel(0xc, pp->dbi_base + PCI_BASE_ADDRESS_4);
  205024. + writel(SZ_1M - 1, pp->dbi_base + (1 << 12)
  205025. + + PCI_BASE_ADDRESS_4);
  205026. + writel(0, pp->dbi_base + (1 << 12) + PCI_BASE_ADDRESS_5);
  205027. +
  205028. + /* Re-setup the iATU */
  205029. + imx_pcie_regions_setup(&pdev->dev);
  205030. +
  205031. + if (IS_ENABLED(CONFIG_EP_SELF_IO_TEST)) {
  205032. + /* PCIe EP start the data transfer after link up */
  205033. + pr_info("pcie ep: Starting data transfer...\n");
  205034. + do_gettimeofday(&tv1);
  205035. +
  205036. + memcpy((unsigned long *)pcie_arb_base_addr,
  205037. + (unsigned long *)test_reg1,
  205038. + test_region_size);
  205039. +
  205040. + do_gettimeofday(&tv2);
  205041. +
  205042. + memcpy((unsigned long *)test_reg2,
  205043. + (unsigned long *)pcie_arb_base_addr,
  205044. + test_region_size);
  205045. +
  205046. + do_gettimeofday(&tv3);
  205047. +
  205048. + if (memcmp(test_reg2, test_reg1, test_region_size) == 0) {
  205049. + tv_count1 = (tv2.tv_sec - tv1.tv_sec)
  205050. + * USEC_PER_SEC
  205051. + + tv2.tv_usec - tv1.tv_usec;
  205052. + tv_count2 = (tv3.tv_sec - tv2.tv_sec)
  205053. + * USEC_PER_SEC
  205054. + + tv3.tv_usec - tv2.tv_usec;
  205055. +
  205056. + pr_info("pcie ep: Data transfer is successful."
  205057. + " tv_count1 %dus,"
  205058. + " tv_count2 %dus.\n",
  205059. + tv_count1, tv_count2);
  205060. + pr_info("pcie ep: Data write speed:%ldMB/s.\n",
  205061. + ((test_region_size/1024)
  205062. + * MSEC_PER_SEC)
  205063. + /(tv_count1));
  205064. + pr_info("pcie ep: Data read speed:%ldMB/s.\n",
  205065. + ((test_region_size/1024)
  205066. + * MSEC_PER_SEC)
  205067. + /(tv_count2));
  205068. + } else {
  205069. + pr_info("pcie ep: Data transfer is failed.\n");
  205070. + }
  205071. + }
  205072. + } else {
  205073. + ret = imx6_add_pcie_port(pp, pdev);
  205074. + if (ret < 0)
  205075. + goto err;
  205076. + platform_set_drvdata(pdev, imx6_pcie);
  205077. +
  205078. + /* Re-setup the iATU */
  205079. + imx_pcie_regions_setup(&pdev->dev);
  205080. + }
  205081. +
  205082. +err:
  205083. + return ret;
  205084. +}
  205085. +
  205086. +static void imx6_pcie_shutdown(struct platform_device *pdev)
  205087. +{
  205088. + struct imx6_pcie *imx6_pcie = platform_get_drvdata(pdev);
  205089. +
  205090. + /* bring down link, so bootloader gets clean state in case of reboot */
  205091. + imx6_pcie_assert_core_reset(&imx6_pcie->pp);
  205092. }
  205093. static const struct of_device_id imx6_pcie_of_match[] = {
  205094. @@ -639,6 +1046,7 @@
  205095. .owner = THIS_MODULE,
  205096. .of_match_table = imx6_pcie_of_match,
  205097. },
  205098. + .shutdown = imx6_pcie_shutdown,
  205099. };
  205100. /* Freescale PCIe driver does not allow module unload */
  205101. diff -Nur linux-3.14.17/drivers/pci/host/pci-imx6-ep-driver.c linux-imx6-3.14/drivers/pci/host/pci-imx6-ep-driver.c
  205102. --- linux-3.14.17/drivers/pci/host/pci-imx6-ep-driver.c 1970-01-01 01:00:00.000000000 +0100
  205103. +++ linux-imx6-3.14/drivers/pci/host/pci-imx6-ep-driver.c 2014-09-11 18:06:04.274047051 +0200
  205104. @@ -0,0 +1,159 @@
  205105. +/*
  205106. + * PCIe endpoint skeleton driver for IMX6 SOCs
  205107. + *
  205108. + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  205109. + *
  205110. + * This program is free software; you can redistribute it and/or modify
  205111. + * it under the terms of the GNU General Public License as published by
  205112. + * the Free Software Foundation; either version 2 of the License, or
  205113. + * (at your option) any later version.
  205114. +
  205115. + * This program is distributed in the hope that it will be useful,
  205116. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  205117. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  205118. + * GNU General Public License for more details.
  205119. +
  205120. + * You should have received a copy of the GNU General Public License along
  205121. + * with this program; if not, write to the Free Software Foundation, Inc.,
  205122. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  205123. + */
  205124. +
  205125. +#include <linux/kernel.h>
  205126. +#include <linux/module.h>
  205127. +#include <linux/init.h>
  205128. +#include <linux/pci.h>
  205129. +#include <linux/pci-aspm.h>
  205130. +#include <linux/slab.h>
  205131. +#include <linux/dma-mapping.h>
  205132. +#include <linux/delay.h>
  205133. +#include <linux/sched.h>
  205134. +#include <linux/interrupt.h>
  205135. +
  205136. +#define DRV_DESCRIPTION "i.MX PCIE endpoint device driver"
  205137. +#define DRV_VERSION "version 0.1"
  205138. +#define DRV_NAME "imx_pcie_ep"
  205139. +
  205140. +struct imx_pcie_ep_priv {
  205141. + struct pci_dev *pci_dev;
  205142. + void __iomem *hw_base;
  205143. +};
  205144. +
  205145. +/**
  205146. + * imx_pcie_ep_probe - Device Initialization Routine
  205147. + * @pdev: PCI device information struct
  205148. + * @id: entry in id_tbl
  205149. + *
  205150. + * Returns 0 on success, negative on failure
  205151. + **/
  205152. +static int imx_pcie_ep_probe(struct pci_dev *pdev,
  205153. + const struct pci_device_id *id)
  205154. +{
  205155. + int ret = 0;
  205156. + struct device *dev = &pdev->dev;
  205157. + struct imx_pcie_ep_priv *priv;
  205158. +
  205159. + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  205160. + if (!priv) {
  205161. + dev_err(dev, "can't alloc imx pcie priv\n");
  205162. + return -ENOMEM;
  205163. + }
  205164. +
  205165. + priv->pci_dev = pdev;
  205166. +
  205167. + if (pci_enable_device(pdev)) {
  205168. + ret = -ENODEV;
  205169. + goto out;
  205170. + }
  205171. + pci_set_master(pdev);
  205172. +
  205173. + pci_set_drvdata(pdev, priv);
  205174. +
  205175. + priv->hw_base = pci_iomap(pdev, 0, 0);
  205176. + if (!priv->hw_base) {
  205177. + ret = -ENODEV;
  205178. + goto out;
  205179. + }
  205180. +
  205181. + pr_info("pci_resource_len = 0x%08llx\n",
  205182. + (unsigned long long) pci_resource_len(pdev, 0));
  205183. + pr_info("pci_resource_base = %p\n", priv->hw_base);
  205184. +
  205185. + ret = pci_enable_msi(priv->pci_dev);
  205186. + if (ret < 0) {
  205187. + dev_err(dev, "can't enable msi\n");
  205188. + return ret;
  205189. + }
  205190. +
  205191. + /*
  205192. + * Force to use 0x01FF8000 as the MSI address,
  205193. + * to do the MSI demo
  205194. + */
  205195. + pci_bus_write_config_dword(pdev->bus, 0, 0x54, 0x01FF8000);
  205196. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x820, 0x01FF8000);
  205197. +
  205198. + /* configure rc's msi cap */
  205199. + pci_bus_read_config_dword(pdev->bus->parent, 0, 0x50, &ret);
  205200. + ret |= (PCI_MSI_FLAGS_ENABLE << 16);
  205201. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x50, ret);
  205202. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x828, 0x1);
  205203. + pci_bus_write_config_dword(pdev->bus->parent, 0, 0x82C, 0xFFFFFFFE);
  205204. +
  205205. + return 0;
  205206. +
  205207. +out:
  205208. + return ret;
  205209. +}
  205210. +
  205211. +static void imx_pcie_ep_remove(struct pci_dev *pdev)
  205212. +{
  205213. + struct imx_pcie_ep_priv *priv = pci_get_drvdata(pdev);
  205214. +
  205215. + if (!priv)
  205216. + return;
  205217. + pr_info("***imx pcie ep driver unload***\n");
  205218. +}
  205219. +
  205220. +static struct pci_device_id imx_pcie_ep_ids[] = {
  205221. + {
  205222. + .class = PCI_CLASS_MEMORY_RAM << 8,
  205223. + .class_mask = ~0,
  205224. + .vendor = 0xbeaf,
  205225. + .device = 0xdead,
  205226. + .subvendor = PCI_ANY_ID,
  205227. + .subdevice = PCI_ANY_ID,
  205228. + },
  205229. + { } /* terminate list */
  205230. +};
  205231. +MODULE_DEVICE_TABLE(pci, imx_pcie_ep_ids);
  205232. +
  205233. +static struct pci_driver imx_pcie_ep_driver = {
  205234. + .name = DRV_NAME,
  205235. + .id_table = imx_pcie_ep_ids,
  205236. + .probe = imx_pcie_ep_probe,
  205237. + .remove = imx_pcie_ep_remove,
  205238. +};
  205239. +
  205240. +static int __init imx_pcie_ep_init(void)
  205241. +{
  205242. + int ret;
  205243. + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
  205244. +
  205245. + ret = pci_register_driver(&imx_pcie_ep_driver);
  205246. + if (ret)
  205247. + pr_err("Unable to initialize PCI module\n");
  205248. +
  205249. + return ret;
  205250. +}
  205251. +
  205252. +static void __exit imx_pcie_ep_exit(void)
  205253. +{
  205254. + pci_unregister_driver(&imx_pcie_ep_driver);
  205255. +}
  205256. +
  205257. +module_exit(imx_pcie_ep_exit);
  205258. +module_init(imx_pcie_ep_init);
  205259. +
  205260. +MODULE_DESCRIPTION(DRV_DESCRIPTION);
  205261. +MODULE_VERSION(DRV_VERSION);
  205262. +MODULE_LICENSE("GPL");
  205263. +MODULE_ALIAS("imx_pcie_ep");
  205264. diff -Nur linux-3.14.17/drivers/pinctrl/devicetree.c linux-imx6-3.14/drivers/pinctrl/devicetree.c
  205265. --- linux-3.14.17/drivers/pinctrl/devicetree.c 2014-08-14 03:38:34.000000000 +0200
  205266. +++ linux-imx6-3.14/drivers/pinctrl/devicetree.c 2014-09-11 18:06:04.358047388 +0200
  205267. @@ -18,6 +18,7 @@
  205268. #include <linux/device.h>
  205269. #include <linux/of.h>
  205270. +#include <linux/of_gpio.h>
  205271. #include <linux/pinctrl/pinctrl.h>
  205272. #include <linux/slab.h>
  205273. @@ -172,6 +173,43 @@
  205274. return dt_remember_or_free_map(p, statename, NULL, map, 1);
  205275. }
  205276. +static int dt_gpio_assert_pinctrl(struct pinctrl *p)
  205277. +{
  205278. + struct device_node *np = p->dev->of_node;
  205279. + enum of_gpio_flags flags;
  205280. + int gpio;
  205281. + int index = 0;
  205282. + int ret;
  205283. +
  205284. + if (!of_find_property(np, "pinctrl-assert-gpios", NULL))
  205285. + return 0; /* Missing the property, so nothing to be done */
  205286. +
  205287. + for (;; index++) {
  205288. + gpio = of_get_named_gpio_flags(np, "pinctrl-assert-gpios",
  205289. + index, &flags);
  205290. + if (gpio < 0)
  205291. + break; /* End of the phandle list */
  205292. +
  205293. + if (!gpio_is_valid(gpio))
  205294. + return -EINVAL;
  205295. +
  205296. + ret = devm_gpio_request_one(p->dev, gpio, GPIOF_OUT_INIT_LOW,
  205297. + NULL);
  205298. + if (ret < 0)
  205299. + return ret;
  205300. +
  205301. + if (flags & OF_GPIO_ACTIVE_LOW)
  205302. + continue;
  205303. +
  205304. + if (gpio_cansleep(gpio))
  205305. + gpio_set_value_cansleep(gpio, 1);
  205306. + else
  205307. + gpio_set_value(gpio, 1);
  205308. + }
  205309. +
  205310. + return 0;
  205311. +}
  205312. +
  205313. int pinctrl_dt_to_map(struct pinctrl *p)
  205314. {
  205315. struct device_node *np = p->dev->of_node;
  205316. @@ -190,6 +228,12 @@
  205317. return 0;
  205318. }
  205319. + ret = dt_gpio_assert_pinctrl(p);
  205320. + if (ret) {
  205321. + dev_dbg(p->dev, "failed to assert pinctrl setting: %d\n", ret);
  205322. + return ret;
  205323. + }
  205324. +
  205325. /* We may store pointers to property names within the node */
  205326. of_node_get(np);
  205327. diff -Nur linux-3.14.17/drivers/pinctrl/pinctrl-imx6sl.c linux-imx6-3.14/drivers/pinctrl/pinctrl-imx6sl.c
  205328. --- linux-3.14.17/drivers/pinctrl/pinctrl-imx6sl.c 2014-08-14 03:38:34.000000000 +0200
  205329. +++ linux-imx6-3.14/drivers/pinctrl/pinctrl-imx6sl.c 2014-09-11 18:06:04.390047515 +0200
  205330. @@ -384,6 +384,10 @@
  205331. },
  205332. .probe = imx6sl_pinctrl_probe,
  205333. .remove = imx_pinctrl_remove,
  205334. +#ifdef CONFIG_PM
  205335. + .suspend = imx_pinctrl_suspend,
  205336. + .resume = imx_pinctrl_resume,
  205337. +#endif
  205338. };
  205339. static int __init imx6sl_pinctrl_init(void)
  205340. diff -Nur linux-3.14.17/drivers/pinctrl/pinctrl-imx.c linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.c
  205341. --- linux-3.14.17/drivers/pinctrl/pinctrl-imx.c 2014-08-14 03:38:34.000000000 +0200
  205342. +++ linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.c 2014-09-11 18:06:04.370047435 +0200
  205343. @@ -1,7 +1,7 @@
  205344. /*
  205345. * Core driver for the imx pin controller
  205346. *
  205347. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  205348. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  205349. * Copyright (C) 2012 Linaro Ltd.
  205350. *
  205351. * Author: Dong Aisheng <dong.aisheng@linaro.org>
  205352. @@ -628,3 +628,25 @@
  205353. return 0;
  205354. }
  205355. +
  205356. +#ifdef CONFIG_PM
  205357. +int imx_pinctrl_suspend(struct platform_device *pdev, pm_message_t state)
  205358. +{
  205359. + struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
  205360. +
  205361. + if (!ipctl)
  205362. + return -EINVAL;
  205363. +
  205364. + return pinctrl_force_sleep(ipctl->pctl);
  205365. +}
  205366. +
  205367. +int imx_pinctrl_resume(struct platform_device *pdev)
  205368. +{
  205369. + struct imx_pinctrl *ipctl = platform_get_drvdata(pdev);
  205370. +
  205371. + if (!ipctl)
  205372. + return -EINVAL;
  205373. +
  205374. + return pinctrl_force_default(ipctl->pctl);
  205375. +}
  205376. +#endif
  205377. diff -Nur linux-3.14.17/drivers/pinctrl/pinctrl-imx.h linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.h
  205378. --- linux-3.14.17/drivers/pinctrl/pinctrl-imx.h 2014-08-14 03:38:34.000000000 +0200
  205379. +++ linux-imx6-3.14/drivers/pinctrl/pinctrl-imx.h 2014-09-11 18:06:04.370047435 +0200
  205380. @@ -1,7 +1,7 @@
  205381. /*
  205382. * IMX pinmux core definitions
  205383. *
  205384. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  205385. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  205386. * Copyright (C) 2012 Linaro Ltd.
  205387. *
  205388. * Author: Dong Aisheng <dong.aisheng@linaro.org>
  205389. @@ -98,4 +98,8 @@
  205390. int imx_pinctrl_probe(struct platform_device *pdev,
  205391. struct imx_pinctrl_soc_info *info);
  205392. int imx_pinctrl_remove(struct platform_device *pdev);
  205393. +#ifdef CONFIG_PM
  205394. +int imx_pinctrl_suspend(struct platform_device *pdev, pm_message_t state);
  205395. +int imx_pinctrl_resume(struct platform_device *pdev);
  205396. +#endif
  205397. #endif /* __DRIVERS_PINCTRL_IMX_H */
  205398. diff -Nur linux-3.14.17/drivers/pnp/pnpacpi/core.c linux-imx6-3.14/drivers/pnp/pnpacpi/core.c
  205399. --- linux-3.14.17/drivers/pnp/pnpacpi/core.c 2014-08-14 03:38:34.000000000 +0200
  205400. +++ linux-imx6-3.14/drivers/pnp/pnpacpi/core.c 2014-09-11 18:06:04.434047691 +0200
  205401. @@ -339,7 +339,8 @@
  205402. struct pnp_dev *pnp = _pnp;
  205403. /* true means it matched */
  205404. - return pnp->data == acpi;
  205405. + return !acpi->physical_node_count
  205406. + && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
  205407. }
  205408. static struct acpi_device * __init acpi_pnp_find_companion(struct device *dev)
  205409. diff -Nur linux-3.14.17/drivers/power/imx6_usb_charger.c linux-imx6-3.14/drivers/power/imx6_usb_charger.c
  205410. --- linux-3.14.17/drivers/power/imx6_usb_charger.c 1970-01-01 01:00:00.000000000 +0100
  205411. +++ linux-imx6-3.14/drivers/power/imx6_usb_charger.c 2014-09-11 18:06:04.446047739 +0200
  205412. @@ -0,0 +1,294 @@
  205413. +/*
  205414. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  205415. + *
  205416. + * The code contained herein is licensed under the GNU General Public
  205417. + * License. You may obtain a copy of the GNU General Public License
  205418. + * Version 2 or later at the following locations:
  205419. + *
  205420. + * http://www.opensource.org/licenses/gpl-license.html
  205421. + * http://www.gnu.org/copyleft/gpl.html
  205422. + */
  205423. +
  205424. +#include <linux/delay.h>
  205425. +#include <linux/device.h>
  205426. +#include <linux/power/imx6_usb_charger.h>
  205427. +#include <linux/regmap.h>
  205428. +
  205429. +#define HW_ANADIG_REG_3P0_SET (0x00000124)
  205430. +#define HW_ANADIG_REG_3P0_CLR (0x00000128)
  205431. +#define BM_ANADIG_REG_3P0_ENABLE_ILIMIT 0x00000004
  205432. +#define BM_ANADIG_REG_3P0_ENABLE_LINREG 0x00000001
  205433. +
  205434. +#define HW_ANADIG_USB1_CHRG_DETECT_SET (0x000001b4)
  205435. +#define HW_ANADIG_USB1_CHRG_DETECT_CLR (0x000001b8)
  205436. +
  205437. +#define BM_ANADIG_USB1_CHRG_DETECT_EN_B 0x00100000
  205438. +#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B 0x00080000
  205439. +#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT 0x00040000
  205440. +
  205441. +#define HW_ANADIG_USB1_VBUS_DET_STAT (0x000001c0)
  205442. +
  205443. +#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID 0x00000008
  205444. +
  205445. +#define HW_ANADIG_USB1_CHRG_DET_STAT (0x000001d0)
  205446. +
  205447. +#define BM_ANADIG_USB1_CHRG_DET_STAT_DM_STATE 0x00000004
  205448. +#define BM_ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED 0x00000002
  205449. +#define BM_ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT 0x00000001
  205450. +
  205451. +static char *imx6_usb_charger_supplied_to[] = {
  205452. + "imx6_usb_charger",
  205453. +};
  205454. +
  205455. +static enum power_supply_property imx6_usb_charger_power_props[] = {
  205456. + POWER_SUPPLY_PROP_PRESENT, /* Charger detected */
  205457. + POWER_SUPPLY_PROP_ONLINE, /* VBUS online */
  205458. + POWER_SUPPLY_PROP_CURRENT_MAX, /* Maximum current in mA */
  205459. +};
  205460. +
  205461. +static int imx6_usb_charger_get_property(struct power_supply *psy,
  205462. + enum power_supply_property psp,
  205463. + union power_supply_propval *val)
  205464. +{
  205465. + struct usb_charger *charger =
  205466. + container_of(psy, struct usb_charger, psy);
  205467. +
  205468. + switch (psp) {
  205469. + case POWER_SUPPLY_PROP_PRESENT:
  205470. + val->intval = charger->present;
  205471. + break;
  205472. + case POWER_SUPPLY_PROP_ONLINE:
  205473. + val->intval = charger->online;
  205474. + break;
  205475. + case POWER_SUPPLY_PROP_CURRENT_MAX:
  205476. + val->intval = charger->max_current;
  205477. + break;
  205478. + default:
  205479. + return -EINVAL;
  205480. + }
  205481. + return 0;
  205482. +}
  205483. +
  205484. +static void disable_charger_detector(struct regmap *regmap)
  205485. +{
  205486. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_SET,
  205487. + BM_ANADIG_USB1_CHRG_DETECT_EN_B |
  205488. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  205489. +}
  205490. +
  205491. +static void disable_current_limiter(struct regmap *regmap)
  205492. +{
  205493. + /* Disable the vdd3p0 current limiter */
  205494. + regmap_write(regmap, HW_ANADIG_REG_3P0_CLR,
  205495. + BM_ANADIG_REG_3P0_ENABLE_ILIMIT);
  205496. +}
  205497. +
  205498. +/* Return value if the charger is present */
  205499. +static int imx6_usb_charger_detect(struct usb_charger *charger)
  205500. +{
  205501. + struct regmap *regmap = charger->anatop;
  205502. + u32 val;
  205503. + int i, data_pin_contact_count = 0;
  205504. +
  205505. + /* Enable the vdd3p0 curret limiter */
  205506. + regmap_write(regmap, HW_ANADIG_REG_3P0_SET,
  205507. + BM_ANADIG_REG_3P0_ENABLE_LINREG |
  205508. + BM_ANADIG_REG_3P0_ENABLE_ILIMIT);
  205509. +
  205510. + /* check if vbus is valid */
  205511. + regmap_read(regmap, HW_ANADIG_USB1_VBUS_DET_STAT, &val);
  205512. + if (!(val & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)) {
  205513. + dev_err(charger->dev, "vbus is error\n");
  205514. + disable_current_limiter(regmap);
  205515. + return -EINVAL;
  205516. + }
  205517. +
  205518. + /* Enable charger detector */
  205519. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_CLR,
  205520. + BM_ANADIG_USB1_CHRG_DETECT_EN_B);
  205521. + /*
  205522. + * - Do not check whether a charger is connected to the USB port
  205523. + * - Check whether the USB plug has been in contact with each other
  205524. + */
  205525. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_SET,
  205526. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
  205527. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  205528. +
  205529. + /* Check if plug is connected */
  205530. + for (i = 0; i < 100; i = i + 1) {
  205531. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  205532. + if (val & BM_ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT) {
  205533. + if (data_pin_contact_count++ > 5)
  205534. + /* Data pin makes contact */
  205535. + break;
  205536. + } else {
  205537. + msleep(20);
  205538. + }
  205539. + }
  205540. +
  205541. + if (i == 100) {
  205542. + dev_err(charger->dev,
  205543. + "VBUS is coming from a dedicated power supply.\n");
  205544. + disable_current_limiter(regmap);
  205545. + disable_charger_detector(regmap);
  205546. + return -ENXIO;
  205547. + }
  205548. +
  205549. + /*
  205550. + * - Do check whether a charger is connected to the USB port
  205551. + * - Do not Check whether the USB plug has been in contact with
  205552. + * each other
  205553. + */
  205554. + regmap_write(regmap, HW_ANADIG_USB1_CHRG_DETECT_CLR,
  205555. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
  205556. + BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
  205557. + msleep(45);
  205558. +
  205559. + /* Check if it is a charger */
  205560. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  205561. + if (!(val & BM_ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED)) {
  205562. + dev_dbg(charger->dev, "It is a stardard downstream port\n");
  205563. + charger->psy.type = POWER_SUPPLY_TYPE_USB;
  205564. + charger->max_current = 500;
  205565. + disable_charger_detector(regmap);
  205566. + } else {
  205567. + /* It is a charger */
  205568. + disable_charger_detector(regmap);
  205569. + msleep(45);
  205570. + }
  205571. +
  205572. + disable_current_limiter(regmap);
  205573. +
  205574. + return 0;
  205575. +}
  205576. +
  205577. +/*
  205578. + * imx6_usb_vbus_connect - inform about VBUS connection
  205579. + * @charger: the usb charger
  205580. + *
  205581. + * Inform the charger VBUS is connected, vbus detect supplier should call it.
  205582. + * Besides, the USB device controller is expected to keep the dataline
  205583. + * pullups disabled.
  205584. + */
  205585. +int imx6_usb_vbus_connect(struct usb_charger *charger)
  205586. +{
  205587. + int ret;
  205588. +
  205589. + charger->online = 1;
  205590. +
  205591. + mutex_lock(&charger->lock);
  205592. +
  205593. + /* Start the 1st period charger detection. */
  205594. + ret = imx6_usb_charger_detect(charger);
  205595. + if (ret)
  205596. + dev_err(charger->dev,
  205597. + "Error occurs during detection: %d\n",
  205598. + ret);
  205599. + else
  205600. + charger->present = 1;
  205601. +
  205602. + mutex_unlock(&charger->lock);
  205603. +
  205604. + return ret;
  205605. +}
  205606. +EXPORT_SYMBOL(imx6_usb_vbus_connect);
  205607. +
  205608. +/*
  205609. + * It must be called after dp is pulled up (from USB controller driver),
  205610. + * That is used to differentiate DCP and CDP
  205611. + */
  205612. +int imx6_usb_charger_detect_post(struct usb_charger *charger)
  205613. +{
  205614. + struct regmap *regmap = charger->anatop;
  205615. + int val;
  205616. +
  205617. + mutex_lock(&charger->lock);
  205618. +
  205619. + msleep(40);
  205620. +
  205621. + regmap_read(regmap, HW_ANADIG_USB1_CHRG_DET_STAT, &val);
  205622. + if (val & BM_ANADIG_USB1_CHRG_DET_STAT_DM_STATE) {
  205623. + dev_dbg(charger->dev, "It is a dedicate charging port\n");
  205624. + charger->psy.type = POWER_SUPPLY_TYPE_USB_DCP;
  205625. + charger->max_current = 1500;
  205626. + } else {
  205627. + dev_dbg(charger->dev, "It is a charging downstream port\n");
  205628. + charger->psy.type = POWER_SUPPLY_TYPE_USB_CDP;
  205629. + charger->max_current = 900;
  205630. + }
  205631. +
  205632. + power_supply_changed(&charger->psy);
  205633. +
  205634. + mutex_unlock(&charger->lock);
  205635. +
  205636. + return 0;
  205637. +}
  205638. +EXPORT_SYMBOL(imx6_usb_charger_detect_post);
  205639. +
  205640. +/*
  205641. + * imx6_usb_vbus_disconnect - inform about VBUS disconnection
  205642. + * @charger: the usb charger
  205643. + *
  205644. + * Inform the charger that VBUS is disconnected. The charging will be
  205645. + * stopped and the charger properties cleared.
  205646. + */
  205647. +int imx6_usb_vbus_disconnect(struct usb_charger *charger)
  205648. +{
  205649. + charger->online = 0;
  205650. + charger->present = 0;
  205651. + charger->max_current = 0;
  205652. + charger->psy.type = POWER_SUPPLY_TYPE_MAINS;
  205653. +
  205654. + power_supply_changed(&charger->psy);
  205655. +
  205656. + return 0;
  205657. +}
  205658. +EXPORT_SYMBOL(imx6_usb_vbus_disconnect);
  205659. +
  205660. +/*
  205661. + * imx6_usb_create_charger - create a USB charger
  205662. + * @charger: the charger to be initialized
  205663. + * @name: name for the power supply
  205664. +
  205665. + * Registers a power supply for the charger. The USB Controller
  205666. + * driver will call this after filling struct usb_charger.
  205667. + */
  205668. +int imx6_usb_create_charger(struct usb_charger *charger,
  205669. + const char *name)
  205670. +{
  205671. + struct power_supply *psy = &charger->psy;
  205672. +
  205673. + if (!charger->dev)
  205674. + return -EINVAL;
  205675. +
  205676. + if (name)
  205677. + psy->name = name;
  205678. + else
  205679. + psy->name = "imx6_usb_charger";
  205680. +
  205681. + charger->bc = BATTERY_CHARGING_SPEC_1_2;
  205682. + mutex_init(&charger->lock);
  205683. +
  205684. + psy->type = POWER_SUPPLY_TYPE_MAINS;
  205685. + psy->properties = imx6_usb_charger_power_props;
  205686. + psy->num_properties = ARRAY_SIZE(imx6_usb_charger_power_props);
  205687. + psy->get_property = imx6_usb_charger_get_property;
  205688. + psy->supplied_to = imx6_usb_charger_supplied_to;
  205689. + psy->num_supplicants = sizeof(imx6_usb_charger_supplied_to)
  205690. + / sizeof(char *);
  205691. +
  205692. + return power_supply_register(charger->dev, psy);
  205693. +}
  205694. +EXPORT_SYMBOL(imx6_usb_create_charger);
  205695. +
  205696. +/*
  205697. + * imx6_usb_remove_charger - remove a USB charger
  205698. + * @charger: the charger to be removed
  205699. + *
  205700. + * Unregister the chargers power supply.
  205701. + */
  205702. +void imx6_usb_remove_charger(struct usb_charger *charger)
  205703. +{
  205704. + power_supply_unregister(&charger->psy);
  205705. +}
  205706. +EXPORT_SYMBOL(imx6_usb_remove_charger);
  205707. diff -Nur linux-3.14.17/drivers/power/Kconfig linux-imx6-3.14/drivers/power/Kconfig
  205708. --- linux-3.14.17/drivers/power/Kconfig 2014-08-14 03:38:34.000000000 +0200
  205709. +++ linux-imx6-3.14/drivers/power/Kconfig 2014-09-11 18:06:04.438047706 +0200
  205710. @@ -389,6 +389,12 @@
  205711. Say Y to enable support for the battery and AC power in the
  205712. Goldfish emulator.
  205713. +config IMX6_USB_CHARGER
  205714. + bool "Freescale imx6 USB Charger"
  205715. + depends on SOC_IMX6Q || SOC_IMX6SL
  205716. + help
  205717. + Say Y to enable Freescale imx6 USB Charger Detect.
  205718. +
  205719. source "drivers/power/reset/Kconfig"
  205720. endif # POWER_SUPPLY
  205721. diff -Nur linux-3.14.17/drivers/power/Makefile linux-imx6-3.14/drivers/power/Makefile
  205722. --- linux-3.14.17/drivers/power/Makefile 2014-08-14 03:38:34.000000000 +0200
  205723. +++ linux-imx6-3.14/drivers/power/Makefile 2014-09-11 18:06:04.438047706 +0200
  205724. @@ -58,3 +58,4 @@
  205725. obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
  205726. obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
  205727. obj-$(CONFIG_POWER_RESET) += reset/
  205728. +obj-$(CONFIG_IMX6_USB_CHARGER) += imx6_usb_charger.o
  205729. diff -Nur linux-3.14.17/drivers/ptp/ptp_chardev.c linux-imx6-3.14/drivers/ptp/ptp_chardev.c
  205730. --- linux-3.14.17/drivers/ptp/ptp_chardev.c 2014-08-14 03:38:34.000000000 +0200
  205731. +++ linux-imx6-3.14/drivers/ptp/ptp_chardev.c 2014-09-11 18:06:04.482047883 +0200
  205732. @@ -25,6 +25,96 @@
  205733. #include "ptp_private.h"
  205734. +static int ptp_disable_pinfunc(struct ptp_clock_info *ops,
  205735. + enum ptp_pin_function func, unsigned int chan)
  205736. +{
  205737. + struct ptp_clock_request rq;
  205738. + int err = 0;
  205739. +
  205740. + memset(&rq, 0, sizeof(rq));
  205741. +
  205742. + switch (func) {
  205743. + case PTP_PF_NONE:
  205744. + break;
  205745. + case PTP_PF_EXTTS:
  205746. + rq.type = PTP_CLK_REQ_EXTTS;
  205747. + rq.extts.index = chan;
  205748. + err = ops->enable(ops, &rq, 0);
  205749. + break;
  205750. + case PTP_PF_PEROUT:
  205751. + rq.type = PTP_CLK_REQ_PEROUT;
  205752. + rq.perout.index = chan;
  205753. + err = ops->enable(ops, &rq, 0);
  205754. + break;
  205755. + case PTP_PF_PHYSYNC:
  205756. + break;
  205757. + default:
  205758. + return -EINVAL;
  205759. + }
  205760. +
  205761. + return err;
  205762. +}
  205763. +
  205764. +int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
  205765. + enum ptp_pin_function func, unsigned int chan)
  205766. +{
  205767. + struct ptp_clock_info *info = ptp->info;
  205768. + struct ptp_pin_desc *pin1 = NULL, *pin2 = &info->pin_config[pin];
  205769. + unsigned int i;
  205770. +
  205771. + /* Check to see if any other pin previously had this function. */
  205772. + for (i = 0; i < info->n_pins; i++) {
  205773. + if (info->pin_config[i].func == func &&
  205774. + info->pin_config[i].chan == chan) {
  205775. + pin1 = &info->pin_config[i];
  205776. + break;
  205777. + }
  205778. + }
  205779. + if (pin1 && i == pin)
  205780. + return 0;
  205781. +
  205782. + /* Check the desired function and channel. */
  205783. + switch (func) {
  205784. + case PTP_PF_NONE:
  205785. + break;
  205786. + case PTP_PF_EXTTS:
  205787. + if (chan >= info->n_ext_ts)
  205788. + return -EINVAL;
  205789. + break;
  205790. + case PTP_PF_PEROUT:
  205791. + if (chan >= info->n_per_out)
  205792. + return -EINVAL;
  205793. + break;
  205794. + case PTP_PF_PHYSYNC:
  205795. + pr_err("sorry, cannot reassign the calibration pin\n");
  205796. + return -EINVAL;
  205797. + default:
  205798. + return -EINVAL;
  205799. + }
  205800. +
  205801. + if (pin2->func == PTP_PF_PHYSYNC) {
  205802. + pr_err("sorry, cannot reprogram the calibration pin\n");
  205803. + return -EINVAL;
  205804. + }
  205805. +
  205806. + if (info->verify(info, pin, func, chan)) {
  205807. + pr_err("driver cannot use function %u on pin %u\n", func, chan);
  205808. + return -EOPNOTSUPP;
  205809. + }
  205810. +
  205811. + /* Disable whatever function was previously assigned. */
  205812. + if (pin1) {
  205813. + ptp_disable_pinfunc(info, func, chan);
  205814. + pin1->func = PTP_PF_NONE;
  205815. + pin1->chan = 0;
  205816. + }
  205817. + ptp_disable_pinfunc(info, pin2->func, pin2->chan);
  205818. + pin2->func = func;
  205819. + pin2->chan = chan;
  205820. +
  205821. + return 0;
  205822. +}
  205823. +
  205824. int ptp_open(struct posix_clock *pc, fmode_t fmode)
  205825. {
  205826. return 0;
  205827. @@ -35,12 +125,13 @@
  205828. struct ptp_clock_caps caps;
  205829. struct ptp_clock_request req;
  205830. struct ptp_sys_offset *sysoff = NULL;
  205831. + struct ptp_pin_desc pd;
  205832. struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
  205833. struct ptp_clock_info *ops = ptp->info;
  205834. struct ptp_clock_time *pct;
  205835. struct timespec ts;
  205836. int enable, err = 0;
  205837. - unsigned int i;
  205838. + unsigned int i, pin_index;
  205839. switch (cmd) {
  205840. @@ -51,6 +142,7 @@
  205841. caps.n_ext_ts = ptp->info->n_ext_ts;
  205842. caps.n_per_out = ptp->info->n_per_out;
  205843. caps.pps = ptp->info->pps;
  205844. + caps.n_pins = ptp->info->n_pins;
  205845. if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
  205846. err = -EFAULT;
  205847. break;
  205848. @@ -126,6 +218,40 @@
  205849. err = -EFAULT;
  205850. break;
  205851. + case PTP_PIN_GETFUNC:
  205852. + if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
  205853. + err = -EFAULT;
  205854. + break;
  205855. + }
  205856. + pin_index = pd.index;
  205857. + if (pin_index >= ops->n_pins) {
  205858. + err = -EINVAL;
  205859. + break;
  205860. + }
  205861. + if (mutex_lock_interruptible(&ptp->pincfg_mux))
  205862. + return -ERESTARTSYS;
  205863. + pd = ops->pin_config[pin_index];
  205864. + mutex_unlock(&ptp->pincfg_mux);
  205865. + if (!err && copy_to_user((void __user *)arg, &pd, sizeof(pd)))
  205866. + err = -EFAULT;
  205867. + break;
  205868. +
  205869. + case PTP_PIN_SETFUNC:
  205870. + if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
  205871. + err = -EFAULT;
  205872. + break;
  205873. + }
  205874. + pin_index = pd.index;
  205875. + if (pin_index >= ops->n_pins) {
  205876. + err = -EINVAL;
  205877. + break;
  205878. + }
  205879. + if (mutex_lock_interruptible(&ptp->pincfg_mux))
  205880. + return -ERESTARTSYS;
  205881. + err = ptp_set_pinfunc(ptp, pin_index, pd.func, pd.chan);
  205882. + mutex_unlock(&ptp->pincfg_mux);
  205883. + break;
  205884. +
  205885. default:
  205886. err = -ENOTTY;
  205887. break;
  205888. diff -Nur linux-3.14.17/drivers/ptp/ptp_clock.c linux-imx6-3.14/drivers/ptp/ptp_clock.c
  205889. --- linux-3.14.17/drivers/ptp/ptp_clock.c 2014-08-14 03:38:34.000000000 +0200
  205890. +++ linux-imx6-3.14/drivers/ptp/ptp_clock.c 2014-09-11 18:06:04.482047883 +0200
  205891. @@ -169,6 +169,7 @@
  205892. struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
  205893. mutex_destroy(&ptp->tsevq_mux);
  205894. + mutex_destroy(&ptp->pincfg_mux);
  205895. ida_simple_remove(&ptp_clocks_map, ptp->index);
  205896. kfree(ptp);
  205897. }
  205898. @@ -203,6 +204,7 @@
  205899. ptp->index = index;
  205900. spin_lock_init(&ptp->tsevq.lock);
  205901. mutex_init(&ptp->tsevq_mux);
  205902. + mutex_init(&ptp->pincfg_mux);
  205903. init_waitqueue_head(&ptp->tsev_wq);
  205904. /* Create a new device in our class. */
  205905. @@ -249,6 +251,7 @@
  205906. device_destroy(ptp_class, ptp->devid);
  205907. no_device:
  205908. mutex_destroy(&ptp->tsevq_mux);
  205909. + mutex_destroy(&ptp->pincfg_mux);
  205910. no_slot:
  205911. kfree(ptp);
  205912. no_memory:
  205913. @@ -305,6 +308,26 @@
  205914. }
  205915. EXPORT_SYMBOL(ptp_clock_index);
  205916. +int ptp_find_pin(struct ptp_clock *ptp,
  205917. + enum ptp_pin_function func, unsigned int chan)
  205918. +{
  205919. + struct ptp_pin_desc *pin = NULL;
  205920. + int i;
  205921. +
  205922. + mutex_lock(&ptp->pincfg_mux);
  205923. + for (i = 0; i < ptp->info->n_pins; i++) {
  205924. + if (ptp->info->pin_config[i].func == func &&
  205925. + ptp->info->pin_config[i].chan == chan) {
  205926. + pin = &ptp->info->pin_config[i];
  205927. + break;
  205928. + }
  205929. + }
  205930. + mutex_unlock(&ptp->pincfg_mux);
  205931. +
  205932. + return pin ? i : -1;
  205933. +}
  205934. +EXPORT_SYMBOL(ptp_find_pin);
  205935. +
  205936. /* module operations */
  205937. static void __exit ptp_exit(void)
  205938. diff -Nur linux-3.14.17/drivers/ptp/ptp_ixp46x.c linux-imx6-3.14/drivers/ptp/ptp_ixp46x.c
  205939. --- linux-3.14.17/drivers/ptp/ptp_ixp46x.c 2014-08-14 03:38:34.000000000 +0200
  205940. +++ linux-imx6-3.14/drivers/ptp/ptp_ixp46x.c 2014-09-11 18:06:04.482047883 +0200
  205941. @@ -244,6 +244,7 @@
  205942. .name = "IXP46X timer",
  205943. .max_adj = 66666655,
  205944. .n_ext_ts = N_EXT_TS,
  205945. + .n_pins = 0,
  205946. .pps = 0,
  205947. .adjfreq = ptp_ixp_adjfreq,
  205948. .adjtime = ptp_ixp_adjtime,
  205949. diff -Nur linux-3.14.17/drivers/ptp/ptp_pch.c linux-imx6-3.14/drivers/ptp/ptp_pch.c
  205950. --- linux-3.14.17/drivers/ptp/ptp_pch.c 2014-08-14 03:38:34.000000000 +0200
  205951. +++ linux-imx6-3.14/drivers/ptp/ptp_pch.c 2014-09-11 18:06:04.482047883 +0200
  205952. @@ -514,6 +514,7 @@
  205953. .name = "PCH timer",
  205954. .max_adj = 50000000,
  205955. .n_ext_ts = N_EXT_TS,
  205956. + .n_pins = 0,
  205957. .pps = 0,
  205958. .adjfreq = ptp_pch_adjfreq,
  205959. .adjtime = ptp_pch_adjtime,
  205960. diff -Nur linux-3.14.17/drivers/ptp/ptp_private.h linux-imx6-3.14/drivers/ptp/ptp_private.h
  205961. --- linux-3.14.17/drivers/ptp/ptp_private.h 2014-08-14 03:38:34.000000000 +0200
  205962. +++ linux-imx6-3.14/drivers/ptp/ptp_private.h 2014-09-11 18:06:04.482047883 +0200
  205963. @@ -48,6 +48,7 @@
  205964. long dialed_frequency; /* remembers the frequency adjustment */
  205965. struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
  205966. struct mutex tsevq_mux; /* one process at a time reading the fifo */
  205967. + struct mutex pincfg_mux; /* protect concurrent info->pin_config access */
  205968. wait_queue_head_t tsev_wq;
  205969. int defunct; /* tells readers to go away when clock is being removed */
  205970. };
  205971. @@ -69,6 +70,10 @@
  205972. * see ptp_chardev.c
  205973. */
  205974. +/* caller must hold pincfg_mux */
  205975. +int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
  205976. + enum ptp_pin_function func, unsigned int chan);
  205977. +
  205978. long ptp_ioctl(struct posix_clock *pc,
  205979. unsigned int cmd, unsigned long arg);
  205980. diff -Nur linux-3.14.17/drivers/pwm/pwm-imx.c linux-imx6-3.14/drivers/pwm/pwm-imx.c
  205981. --- linux-3.14.17/drivers/pwm/pwm-imx.c 2014-08-14 03:38:34.000000000 +0200
  205982. +++ linux-imx6-3.14/drivers/pwm/pwm-imx.c 2014-09-11 18:06:04.482047883 +0200
  205983. @@ -1,4 +1,5 @@
  205984. /*
  205985. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  205986. * simple driver for PWM (Pulse Width Modulator) controller
  205987. *
  205988. * This program is free software; you can redistribute it and/or modify
  205989. @@ -293,11 +294,34 @@
  205990. return pwmchip_remove(&imx->chip);
  205991. }
  205992. +#ifdef CONFIG_PM
  205993. +static int imx_pwm_suspend(struct device *dev)
  205994. +{
  205995. + pinctrl_pm_select_sleep_state(dev);
  205996. +
  205997. + return 0;
  205998. +}
  205999. +
  206000. +static int imx_pwm_resume(struct device *dev)
  206001. +{
  206002. + pinctrl_pm_select_default_state(dev);
  206003. +
  206004. + return 0;
  206005. +}
  206006. +
  206007. +static const struct dev_pm_ops imx_pwm_pm_ops = {
  206008. + SET_SYSTEM_SLEEP_PM_OPS(imx_pwm_suspend, imx_pwm_resume)
  206009. +};
  206010. +#endif
  206011. +
  206012. static struct platform_driver imx_pwm_driver = {
  206013. .driver = {
  206014. .name = "imx-pwm",
  206015. .owner = THIS_MODULE,
  206016. .of_match_table = imx_pwm_dt_ids,
  206017. +#ifdef CONFIG_PM
  206018. + .pm = &imx_pwm_pm_ops,
  206019. +#endif
  206020. },
  206021. .probe = imx_pwm_probe,
  206022. .remove = imx_pwm_remove,
  206023. diff -Nur linux-3.14.17/drivers/rapidio/devices/tsi721_dma.c linux-imx6-3.14/drivers/rapidio/devices/tsi721_dma.c
  206024. --- linux-3.14.17/drivers/rapidio/devices/tsi721_dma.c 2014-08-14 03:38:34.000000000 +0200
  206025. +++ linux-imx6-3.14/drivers/rapidio/devices/tsi721_dma.c 2014-09-11 18:06:04.486047898 +0200
  206026. @@ -287,12 +287,6 @@
  206027. "desc %p not ACKed\n", tx_desc);
  206028. }
  206029. - if (ret == NULL) {
  206030. - dev_dbg(bdma_chan->dchan.device->dev,
  206031. - "%s: unable to obtain tx descriptor\n", __func__);
  206032. - goto err_out;
  206033. - }
  206034. -
  206035. i = bdma_chan->wr_count_next % bdma_chan->bd_num;
  206036. if (i == bdma_chan->bd_num - 1) {
  206037. i = 0;
  206038. @@ -303,7 +297,7 @@
  206039. tx_desc->txd.phys = bdma_chan->bd_phys +
  206040. i * sizeof(struct tsi721_dma_desc);
  206041. tx_desc->hw_desc = &((struct tsi721_dma_desc *)bdma_chan->bd_base)[i];
  206042. -err_out:
  206043. +
  206044. spin_unlock_bh(&bdma_chan->lock);
  206045. return ret;
  206046. diff -Nur linux-3.14.17/drivers/regulator/anatop-regulator.c linux-imx6-3.14/drivers/regulator/anatop-regulator.c
  206047. --- linux-3.14.17/drivers/regulator/anatop-regulator.c 2014-08-14 03:38:34.000000000 +0200
  206048. +++ linux-imx6-3.14/drivers/regulator/anatop-regulator.c 2014-09-11 18:06:04.490047915 +0200
  206049. @@ -1,5 +1,5 @@
  206050. /*
  206051. - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
  206052. + * Copyright (C) 2011, 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  206053. */
  206054. /*
  206055. @@ -34,6 +34,22 @@
  206056. #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */
  206057. #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */
  206058. +#define REG_SET 0x4
  206059. +#define REG_CLR 0x8
  206060. +#define SOC_PU_FIELD_OFFSET 0x9
  206061. +
  206062. +/*
  206063. + * for CORE, SOC and PU regulator, the register field
  206064. + * has following definition: 00001 -- Target core voltage
  206065. + * = 0.725V, which means the lowest setting in this
  206066. + * field is 0.725V once the regulator is enabled. So
  206067. + * when these regulators are turned on from off status,
  206068. + * we need to count the voltage step of 0V to 0.7V, it will
  206069. + * need additional delay, so the additional step number is
  206070. + * 700mV / 25mV = 28.
  206071. + */
  206072. +#define CORE_REG_ENABLE_STEP_ADD 28
  206073. +
  206074. struct anatop_regulator {
  206075. const char *name;
  206076. u32 control_reg;
  206077. @@ -97,12 +113,86 @@
  206078. return regulator_get_voltage_sel_regmap(reg);
  206079. }
  206080. +/*
  206081. + * currently on anatop regulators, only PU regulator supports
  206082. + * enable/disable function, and its voltage must be equal
  206083. + * to SOC voltage, so we need to get SOC voltage then set
  206084. + * into PU regulator. Other regulators are always on due
  206085. + * to hardware design, so enable/disable/is_enabled/enable_time
  206086. + * functions are only used by PU regulator.
  206087. + */
  206088. +static int anatop_regmap_enable(struct regulator_dev *reg)
  206089. +{
  206090. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  206091. + u32 val;
  206092. +
  206093. + if (!anatop_reg->control_reg)
  206094. + return -ENOTSUPP;
  206095. +
  206096. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  206097. + val &= ((1 << anatop_reg->vol_bit_width) - 1) <<
  206098. + (anatop_reg->vol_bit_shift + SOC_PU_FIELD_OFFSET);
  206099. + regmap_write(anatop_reg->anatop, anatop_reg->control_reg +
  206100. + REG_SET, val >> SOC_PU_FIELD_OFFSET);
  206101. +
  206102. + return 0;
  206103. +}
  206104. +
  206105. +static int anatop_regmap_disable(struct regulator_dev *reg)
  206106. +{
  206107. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  206108. +
  206109. + if (!anatop_reg->control_reg)
  206110. + return -ENOTSUPP;
  206111. +
  206112. + regmap_write(anatop_reg->anatop, anatop_reg->control_reg +
  206113. + REG_CLR, ((1 << anatop_reg->vol_bit_width) - 1) <<
  206114. + anatop_reg->vol_bit_shift);
  206115. +
  206116. + return 0;
  206117. +}
  206118. +
  206119. +static int anatop_regmap_is_enabled(struct regulator_dev *reg)
  206120. +{
  206121. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  206122. + u32 val;
  206123. +
  206124. + if (!anatop_reg->control_reg)
  206125. + return -ENOTSUPP;
  206126. +
  206127. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  206128. +
  206129. + return (val >> anatop_reg->vol_bit_shift) &
  206130. + ((1 << anatop_reg->vol_bit_width) - 1) ? 1 : 0;
  206131. +}
  206132. +
  206133. +static int anatop_regmap_enable_time(struct regulator_dev *reg)
  206134. +{
  206135. + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
  206136. + u32 val, soc_val;
  206137. +
  206138. + if (!anatop_reg->control_reg)
  206139. + return -ENOTSUPP;
  206140. +
  206141. + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
  206142. + soc_val = (val >> (anatop_reg->vol_bit_shift +
  206143. + SOC_PU_FIELD_OFFSET)) &
  206144. + ((1 << anatop_reg->vol_bit_width) - 1);
  206145. +
  206146. + return anatop_regmap_set_voltage_time_sel(reg, 0,
  206147. + soc_val + CORE_REG_ENABLE_STEP_ADD);
  206148. +}
  206149. +
  206150. static struct regulator_ops anatop_rops = {
  206151. .set_voltage_sel = anatop_regmap_set_voltage_sel,
  206152. .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel,
  206153. .get_voltage_sel = anatop_regmap_get_voltage_sel,
  206154. + .enable = anatop_regmap_enable,
  206155. + .disable = anatop_regmap_disable,
  206156. + .is_enabled = anatop_regmap_is_enabled,
  206157. .list_voltage = regulator_list_voltage_linear,
  206158. .map_voltage = regulator_map_voltage_linear,
  206159. + .enable_time = anatop_regmap_enable_time,
  206160. };
  206161. static int anatop_regulator_probe(struct platform_device *pdev)
  206162. @@ -196,6 +286,7 @@
  206163. config.driver_data = sreg;
  206164. config.of_node = pdev->dev.of_node;
  206165. config.regmap = sreg->anatop;
  206166. + config.ena_gpio = -EINVAL;
  206167. /* register regulator */
  206168. rdev = devm_regulator_register(dev, rdesc, &config);
  206169. diff -Nur linux-3.14.17/drivers/regulator/core.c linux-imx6-3.14/drivers/regulator/core.c
  206170. --- linux-3.14.17/drivers/regulator/core.c 2014-08-14 03:38:34.000000000 +0200
  206171. +++ linux-imx6-3.14/drivers/regulator/core.c 2014-09-11 18:06:04.490047915 +0200
  206172. @@ -3,6 +3,7 @@
  206173. *
  206174. * Copyright 2007, 2008 Wolfson Microelectronics PLC.
  206175. * Copyright 2008 SlimLogic Ltd.
  206176. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  206177. *
  206178. * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  206179. *
  206180. @@ -24,6 +25,7 @@
  206181. #include <linux/suspend.h>
  206182. #include <linux/delay.h>
  206183. #include <linux/gpio.h>
  206184. +#include <linux/gpio/consumer.h>
  206185. #include <linux/of.h>
  206186. #include <linux/regmap.h>
  206187. #include <linux/regulator/of_regulator.h>
  206188. @@ -77,7 +79,7 @@
  206189. */
  206190. struct regulator_enable_gpio {
  206191. struct list_head list;
  206192. - int gpio;
  206193. + struct gpio_desc *gpiod;
  206194. u32 enable_count; /* a number of enabled shared GPIO */
  206195. u32 request_count; /* a number of requested shared GPIO */
  206196. unsigned int ena_gpio_invert:1;
  206197. @@ -1653,10 +1655,13 @@
  206198. const struct regulator_config *config)
  206199. {
  206200. struct regulator_enable_gpio *pin;
  206201. + struct gpio_desc *gpiod;
  206202. int ret;
  206203. + gpiod = gpio_to_desc(config->ena_gpio);
  206204. +
  206205. list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
  206206. - if (pin->gpio == config->ena_gpio) {
  206207. + if (pin->gpiod == gpiod) {
  206208. rdev_dbg(rdev, "GPIO %d is already used\n",
  206209. config->ena_gpio);
  206210. goto update_ena_gpio_to_rdev;
  206211. @@ -1675,7 +1680,7 @@
  206212. return -ENOMEM;
  206213. }
  206214. - pin->gpio = config->ena_gpio;
  206215. + pin->gpiod = gpiod;
  206216. pin->ena_gpio_invert = config->ena_gpio_invert;
  206217. list_add(&pin->list, &regulator_ena_gpio_list);
  206218. @@ -1694,10 +1699,10 @@
  206219. /* Free the GPIO only in case of no use */
  206220. list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
  206221. - if (pin->gpio == rdev->ena_pin->gpio) {
  206222. + if (pin->gpiod == rdev->ena_pin->gpiod) {
  206223. if (pin->request_count <= 1) {
  206224. pin->request_count = 0;
  206225. - gpio_free(pin->gpio);
  206226. + gpiod_put(pin->gpiod);
  206227. list_del(&pin->list);
  206228. kfree(pin);
  206229. } else {
  206230. @@ -1725,8 +1730,8 @@
  206231. if (enable) {
  206232. /* Enable GPIO at initial use */
  206233. if (pin->enable_count == 0)
  206234. - gpio_set_value_cansleep(pin->gpio,
  206235. - !pin->ena_gpio_invert);
  206236. + gpiod_set_value_cansleep(pin->gpiod,
  206237. + !pin->ena_gpio_invert);
  206238. pin->enable_count++;
  206239. } else {
  206240. @@ -1737,8 +1742,8 @@
  206241. /* Disable GPIO if not used */
  206242. if (pin->enable_count <= 1) {
  206243. - gpio_set_value_cansleep(pin->gpio,
  206244. - pin->ena_gpio_invert);
  206245. + gpiod_set_value_cansleep(pin->gpiod,
  206246. + pin->ena_gpio_invert);
  206247. pin->enable_count = 0;
  206248. }
  206249. }
  206250. @@ -1815,6 +1820,7 @@
  206251. }
  206252. trace_regulator_enable_complete(rdev_get_name(rdev));
  206253. + _notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE, NULL);
  206254. return 0;
  206255. }
  206256. @@ -1892,6 +1898,7 @@
  206257. {
  206258. int ret;
  206259. + _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_DISABLE, NULL);
  206260. trace_regulator_disable(rdev_get_name(rdev));
  206261. if (rdev->ena_pin) {
  206262. @@ -2138,7 +2145,7 @@
  206263. * @regulator: regulator source
  206264. *
  206265. * Returns positive if the regulator driver backing the source/client
  206266. - * can change its voltage, false otherwise. Usefull for detecting fixed
  206267. + * can change its voltage, false otherwise. Useful for detecting fixed
  206268. * or dummy regulators and disabling voltage change logic in the client
  206269. * driver.
  206270. */
  206271. @@ -3445,7 +3452,7 @@
  206272. dev_set_drvdata(&rdev->dev, rdev);
  206273. - if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
  206274. + if (gpio_is_valid(config->ena_gpio)) {
  206275. ret = regulator_ena_gpio_request(rdev, config);
  206276. if (ret != 0) {
  206277. rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
  206278. diff -Nur linux-3.14.17/drivers/regulator/dummy.c linux-imx6-3.14/drivers/regulator/dummy.c
  206279. --- linux-3.14.17/drivers/regulator/dummy.c 2014-08-14 03:38:34.000000000 +0200
  206280. +++ linux-imx6-3.14/drivers/regulator/dummy.c 2014-09-11 18:06:04.510047994 +0200
  206281. @@ -44,6 +44,7 @@
  206282. config.dev = &pdev->dev;
  206283. config.init_data = &dummy_initdata;
  206284. + config.ena_gpio = -EINVAL;
  206285. dummy_regulator_rdev = regulator_register(&dummy_desc, &config);
  206286. if (IS_ERR(dummy_regulator_rdev)) {
  206287. diff -Nur linux-3.14.17/drivers/regulator/fixed.c linux-imx6-3.14/drivers/regulator/fixed.c
  206288. --- linux-3.14.17/drivers/regulator/fixed.c 2014-08-14 03:38:34.000000000 +0200
  206289. +++ linux-imx6-3.14/drivers/regulator/fixed.c 2014-09-11 18:06:04.510047994 +0200
  206290. @@ -163,9 +163,7 @@
  206291. drvdata->desc.n_voltages = 1;
  206292. drvdata->desc.fixed_uV = config->microvolts;
  206293. -
  206294. - if (config->gpio >= 0)
  206295. - cfg.ena_gpio = config->gpio;
  206296. + cfg.ena_gpio = config->gpio;
  206297. cfg.ena_gpio_invert = !config->enable_high;
  206298. if (config->enabled_at_boot) {
  206299. if (config->enable_high)
  206300. diff -Nur linux-3.14.17/drivers/reset/gpio-reset.c linux-imx6-3.14/drivers/reset/gpio-reset.c
  206301. --- linux-3.14.17/drivers/reset/gpio-reset.c 1970-01-01 01:00:00.000000000 +0100
  206302. +++ linux-imx6-3.14/drivers/reset/gpio-reset.c 2014-09-11 18:06:04.530048075 +0200
  206303. @@ -0,0 +1,187 @@
  206304. +/*
  206305. + * GPIO Reset Controller driver
  206306. + *
  206307. + * Copyright 2013 Philipp Zabel, Pengutronix
  206308. + *
  206309. + * This program is free software; you can redistribute it and/or modify
  206310. + * it under the terms of the GNU General Public License as published by
  206311. + * the Free Software Foundation; either version 2 of the License, or
  206312. + * (at your option) any later version.
  206313. + */
  206314. +#include <linux/delay.h>
  206315. +#include <linux/err.h>
  206316. +#include <linux/gpio.h>
  206317. +#include <linux/module.h>
  206318. +#include <linux/of_gpio.h>
  206319. +#include <linux/platform_device.h>
  206320. +#include <linux/reset-controller.h>
  206321. +
  206322. +struct gpio_reset_data {
  206323. + struct reset_controller_dev rcdev;
  206324. + unsigned int gpio;
  206325. + bool active_low;
  206326. + s32 delay_us;
  206327. +};
  206328. +
  206329. +static void gpio_reset_set(struct reset_controller_dev *rcdev, int asserted)
  206330. +{
  206331. + struct gpio_reset_data *drvdata = container_of(rcdev,
  206332. + struct gpio_reset_data, rcdev);
  206333. + int value = asserted;
  206334. +
  206335. + if (drvdata->active_low)
  206336. + value = !value;
  206337. +
  206338. + if (gpio_cansleep(drvdata->gpio))
  206339. + gpio_set_value_cansleep(drvdata->gpio, value);
  206340. + else
  206341. + gpio_set_value(drvdata->gpio, value);
  206342. +}
  206343. +
  206344. +static int gpio_reset(struct reset_controller_dev *rcdev, unsigned long id)
  206345. +{
  206346. + struct gpio_reset_data *drvdata = container_of(rcdev,
  206347. + struct gpio_reset_data, rcdev);
  206348. +
  206349. + if (drvdata->delay_us < 0)
  206350. + return -ENOSYS;
  206351. +
  206352. + gpio_reset_set(rcdev, 1);
  206353. + udelay(drvdata->delay_us);
  206354. + gpio_reset_set(rcdev, 0);
  206355. +
  206356. + return 0;
  206357. +}
  206358. +
  206359. +static int gpio_reset_assert(struct reset_controller_dev *rcdev,
  206360. + unsigned long id)
  206361. +{
  206362. + gpio_reset_set(rcdev, 1);
  206363. +
  206364. + return 0;
  206365. +}
  206366. +
  206367. +static int gpio_reset_deassert(struct reset_controller_dev *rcdev,
  206368. + unsigned long id)
  206369. +{
  206370. + gpio_reset_set(rcdev, 0);
  206371. +
  206372. + return 0;
  206373. +}
  206374. +
  206375. +static struct reset_control_ops gpio_reset_ops = {
  206376. + .reset = gpio_reset,
  206377. + .assert = gpio_reset_assert,
  206378. + .deassert = gpio_reset_deassert,
  206379. +};
  206380. +
  206381. +static int of_gpio_reset_xlate(struct reset_controller_dev *rcdev,
  206382. + const struct of_phandle_args *reset_spec)
  206383. +{
  206384. + if (WARN_ON(reset_spec->args_count != 0))
  206385. + return -EINVAL;
  206386. +
  206387. + return 0;
  206388. +}
  206389. +
  206390. +static int gpio_reset_probe(struct platform_device *pdev)
  206391. +{
  206392. + struct device_node *np = pdev->dev.of_node;
  206393. + struct gpio_reset_data *drvdata;
  206394. + enum of_gpio_flags flags;
  206395. + unsigned long gpio_flags;
  206396. + bool initially_in_reset;
  206397. + int ret;
  206398. +
  206399. + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
  206400. + if (drvdata == NULL)
  206401. + return -ENOMEM;
  206402. +
  206403. + if (of_gpio_named_count(np, "reset-gpios") != 1) {
  206404. + dev_err(&pdev->dev,
  206405. + "reset-gpios property missing, or not a single gpio\n");
  206406. + return -EINVAL;
  206407. + }
  206408. +
  206409. + drvdata->gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
  206410. + if (drvdata->gpio == -EPROBE_DEFER) {
  206411. + return drvdata->gpio;
  206412. + } else if (!gpio_is_valid(drvdata->gpio)) {
  206413. + dev_err(&pdev->dev, "invalid reset gpio: %d\n", drvdata->gpio);
  206414. + return drvdata->gpio;
  206415. + }
  206416. +
  206417. + drvdata->active_low = flags & OF_GPIO_ACTIVE_LOW;
  206418. +
  206419. + ret = of_property_read_u32(np, "reset-delay-us", &drvdata->delay_us);
  206420. + if (ret < 0)
  206421. + drvdata->delay_us = -1;
  206422. + else if (drvdata->delay_us < 0)
  206423. + dev_warn(&pdev->dev, "reset delay too high\n");
  206424. +
  206425. + initially_in_reset = of_property_read_bool(np, "initially-in-reset");
  206426. + if (drvdata->active_low ^ initially_in_reset)
  206427. + gpio_flags = GPIOF_OUT_INIT_HIGH;
  206428. + else
  206429. + gpio_flags = GPIOF_OUT_INIT_LOW;
  206430. +
  206431. + ret = devm_gpio_request_one(&pdev->dev, drvdata->gpio, gpio_flags, NULL);
  206432. + if (ret < 0) {
  206433. + dev_err(&pdev->dev, "failed to request gpio %d: %d\n",
  206434. + drvdata->gpio, ret);
  206435. + return ret;
  206436. + }
  206437. +
  206438. + platform_set_drvdata(pdev, drvdata);
  206439. +
  206440. + drvdata->rcdev.of_node = np;
  206441. + drvdata->rcdev.owner = THIS_MODULE;
  206442. + drvdata->rcdev.nr_resets = 1;
  206443. + drvdata->rcdev.ops = &gpio_reset_ops;
  206444. + drvdata->rcdev.of_xlate = of_gpio_reset_xlate;
  206445. + reset_controller_register(&drvdata->rcdev);
  206446. +
  206447. + return 0;
  206448. +}
  206449. +
  206450. +static int gpio_reset_remove(struct platform_device *pdev)
  206451. +{
  206452. + struct gpio_reset_data *drvdata = platform_get_drvdata(pdev);
  206453. +
  206454. + reset_controller_unregister(&drvdata->rcdev);
  206455. +
  206456. + return 0;
  206457. +}
  206458. +
  206459. +static struct of_device_id gpio_reset_dt_ids[] = {
  206460. + { .compatible = "gpio-reset" },
  206461. + { }
  206462. +};
  206463. +
  206464. +static struct platform_driver gpio_reset_driver = {
  206465. + .probe = gpio_reset_probe,
  206466. + .remove = gpio_reset_remove,
  206467. + .driver = {
  206468. + .name = "gpio-reset",
  206469. + .owner = THIS_MODULE,
  206470. + .of_match_table = of_match_ptr(gpio_reset_dt_ids),
  206471. + },
  206472. +};
  206473. +
  206474. +static int __init gpio_reset_init(void)
  206475. +{
  206476. + return platform_driver_register(&gpio_reset_driver);
  206477. +}
  206478. +arch_initcall(gpio_reset_init);
  206479. +
  206480. +static void __exit gpio_reset_exit(void)
  206481. +{
  206482. + platform_driver_unregister(&gpio_reset_driver);
  206483. +}
  206484. +module_exit(gpio_reset_exit);
  206485. +
  206486. +MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
  206487. +MODULE_DESCRIPTION("gpio reset controller");
  206488. +MODULE_LICENSE("GPL");
  206489. +MODULE_ALIAS("platform:gpio-reset");
  206490. +MODULE_DEVICE_TABLE(of, gpio_reset_dt_ids);
  206491. diff -Nur linux-3.14.17/drivers/reset/Kconfig linux-imx6-3.14/drivers/reset/Kconfig
  206492. --- linux-3.14.17/drivers/reset/Kconfig 2014-08-14 03:38:34.000000000 +0200
  206493. +++ linux-imx6-3.14/drivers/reset/Kconfig 2014-09-11 18:06:04.530048075 +0200
  206494. @@ -11,3 +11,15 @@
  206495. via GPIOs or SoC-internal reset controller modules.
  206496. If unsure, say no.
  206497. +
  206498. +if RESET_CONTROLLER
  206499. +
  206500. +config RESET_GPIO
  206501. + tristate "GPIO reset controller support"
  206502. + default y
  206503. + depends on GPIOLIB && OF
  206504. + help
  206505. + This driver provides support for reset lines that are controlled
  206506. + directly by GPIOs.
  206507. +
  206508. +endif
  206509. diff -Nur linux-3.14.17/drivers/reset/Makefile linux-imx6-3.14/drivers/reset/Makefile
  206510. --- linux-3.14.17/drivers/reset/Makefile 2014-08-14 03:38:34.000000000 +0200
  206511. +++ linux-imx6-3.14/drivers/reset/Makefile 2014-09-11 18:06:04.530048075 +0200
  206512. @@ -1,2 +1,3 @@
  206513. obj-$(CONFIG_RESET_CONTROLLER) += core.o
  206514. +obj-$(CONFIG_RESET_GPIO) += gpio-reset.o
  206515. obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
  206516. diff -Nur linux-3.14.17/drivers/rtc/rtc-pcf8523.c linux-imx6-3.14/drivers/rtc/rtc-pcf8523.c
  206517. --- linux-3.14.17/drivers/rtc/rtc-pcf8523.c 2014-08-14 03:38:34.000000000 +0200
  206518. +++ linux-imx6-3.14/drivers/rtc/rtc-pcf8523.c 2014-09-11 18:06:04.546048138 +0200
  206519. @@ -7,6 +7,7 @@
  206520. */
  206521. #include <linux/bcd.h>
  206522. +#include <linux/delay.h>
  206523. #include <linux/i2c.h>
  206524. #include <linux/module.h>
  206525. #include <linux/rtc.h>
  206526. @@ -82,24 +83,85 @@
  206527. return 0;
  206528. }
  206529. -static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
  206530. +static int pcf8523_rtc_check_oscillator(struct i2c_client *client)
  206531. {
  206532. u8 value;
  206533. int err;
  206534. - err = pcf8523_read(client, REG_CONTROL1, &value);
  206535. + err = pcf8523_read(client, REG_SECONDS, &value);
  206536. if (err < 0)
  206537. return err;
  206538. - if (!high)
  206539. - value &= ~REG_CONTROL1_CAP_SEL;
  206540. - else
  206541. - value |= REG_CONTROL1_CAP_SEL;
  206542. + if (value & REG_SECONDS_OS) {
  206543. + /*
  206544. + * If the oscillator was stopped, try to clear the flag. Upon
  206545. + * power-up the flag is always set, but if we cannot clear it
  206546. + * the oscillator isn't running properly for some reason. The
  206547. + * sensible thing therefore is to return an error, signalling
  206548. + * that the clock cannot be assumed to be correct.
  206549. + */
  206550. +
  206551. + value &= ~REG_SECONDS_OS;
  206552. +
  206553. + err = pcf8523_write(client, REG_SECONDS, value);
  206554. + if (err < 0)
  206555. + return err;
  206556. +
  206557. + err = pcf8523_read(client, REG_SECONDS, &value);
  206558. + if (err < 0)
  206559. + return err;
  206560. +
  206561. + if (value & REG_SECONDS_OS)
  206562. + return -EAGAIN;
  206563. + }
  206564. +
  206565. + return 0;
  206566. +}
  206567. +
  206568. +static int pcf8523_switch_capacitance(struct i2c_client *client)
  206569. +{
  206570. + u8 value;
  206571. + int err;
  206572. +
  206573. + err = pcf8523_read(client, REG_CONTROL1, &value);
  206574. + if (err < 0)
  206575. + goto out;
  206576. +
  206577. + value ^= REG_CONTROL1_CAP_SEL;
  206578. err = pcf8523_write(client, REG_CONTROL1, value);
  206579. +
  206580. +out:
  206581. + return err;
  206582. +}
  206583. +
  206584. +static int pcf8523_enable_oscillator(struct i2c_client *client)
  206585. +{
  206586. + int err, loop;
  206587. +
  206588. + loop = 0;
  206589. + while (loop < 200) {
  206590. + err = pcf8523_rtc_check_oscillator(client);
  206591. + if (!err)
  206592. + return 0;
  206593. + loop++;
  206594. + msleep(10);
  206595. + }
  206596. +
  206597. + err = pcf8523_switch_capacitance(client);
  206598. if (err < 0)
  206599. - return err;
  206600. + goto out;
  206601. +
  206602. + loop = 0;
  206603. + while (loop < 200) {
  206604. + err = pcf8523_rtc_check_oscillator(client);
  206605. + if (!err)
  206606. + return 0;
  206607. + loop++;
  206608. + msleep(10);
  206609. + }
  206610. +out:
  206611. return err;
  206612. }
  206613. @@ -290,6 +352,7 @@
  206614. const struct i2c_device_id *id)
  206615. {
  206616. struct pcf8523 *pcf;
  206617. + u8 value;
  206618. int err;
  206619. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  206620. @@ -299,10 +362,20 @@
  206621. if (!pcf)
  206622. return -ENOMEM;
  206623. - err = pcf8523_select_capacitance(client, true);
  206624. + /* Check whether the RTC reports battery low */
  206625. + err = pcf8523_read(client, REG_CONTROL3, &value);
  206626. if (err < 0)
  206627. return err;
  206628. + if (value & REG_CONTROL3_BLF)
  206629. + dev_warn(&client->dev, "RTC reports battery is low\n");
  206630. +
  206631. + err = pcf8523_enable_oscillator(client);
  206632. + if (err < 0) {
  206633. + dev_warn(&client->dev, "RTC reports oscillator is not running\n");
  206634. + return err;
  206635. + }
  206636. +
  206637. err = pcf8523_set_pm(client, 0);
  206638. if (err < 0)
  206639. return err;
  206640. diff -Nur linux-3.14.17/drivers/rtc/rtc-snvs.c linux-imx6-3.14/drivers/rtc/rtc-snvs.c
  206641. --- linux-3.14.17/drivers/rtc/rtc-snvs.c 2014-08-14 03:38:34.000000000 +0200
  206642. +++ linux-imx6-3.14/drivers/rtc/rtc-snvs.c 2014-09-11 18:06:04.550048154 +0200
  206643. @@ -1,5 +1,5 @@
  206644. /*
  206645. - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
  206646. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  206647. *
  206648. * The code contained herein is licensed under the GNU General Public
  206649. * License. You may obtain a copy of the GNU General Public License
  206650. @@ -41,6 +41,8 @@
  206651. spinlock_t lock;
  206652. };
  206653. +static void __iomem *snvs_base;
  206654. +
  206655. static u32 rtc_read_lp_counter(void __iomem *ioaddr)
  206656. {
  206657. u64 read1, read2;
  206658. @@ -241,6 +243,15 @@
  206659. return events ? IRQ_HANDLED : IRQ_NONE;
  206660. }
  206661. +static void snvs_poweroff(void)
  206662. +{
  206663. + u32 value;
  206664. +
  206665. + value = readl(snvs_base + SNVS_LPCR);
  206666. + /* set TOP and DP_EN bit */
  206667. + writel(value | 0x60, snvs_base + SNVS_LPCR);
  206668. +}
  206669. +
  206670. static int snvs_rtc_probe(struct platform_device *pdev)
  206671. {
  206672. struct snvs_rtc_data *data;
  206673. @@ -270,13 +281,15 @@
  206674. /* Clear interrupt status */
  206675. writel(0xffffffff, data->ioaddr + SNVS_LPSR);
  206676. + snvs_base = data->ioaddr;
  206677. /* Enable RTC */
  206678. snvs_rtc_enable(data, true);
  206679. device_init_wakeup(&pdev->dev, true);
  206680. ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler,
  206681. - IRQF_SHARED, "rtc alarm", &pdev->dev);
  206682. + IRQF_SHARED | IRQF_NO_SUSPEND,
  206683. + "rtc alarm", &pdev->dev);
  206684. if (ret) {
  206685. dev_err(&pdev->dev, "failed to request irq %d: %d\n",
  206686. data->irq, ret);
  206687. @@ -290,6 +303,12 @@
  206688. dev_err(&pdev->dev, "failed to register rtc: %d\n", ret);
  206689. return ret;
  206690. }
  206691. + /*
  206692. + * if no specific power off function in board file, power off system by
  206693. + * SNVS
  206694. + */
  206695. + if (!pm_power_off)
  206696. + pm_power_off = snvs_poweroff;
  206697. return 0;
  206698. }
  206699. diff -Nur linux-3.14.17/drivers/sbus/char/bbc_envctrl.c linux-imx6-3.14/drivers/sbus/char/bbc_envctrl.c
  206700. --- linux-3.14.17/drivers/sbus/char/bbc_envctrl.c 2014-08-14 03:38:34.000000000 +0200
  206701. +++ linux-imx6-3.14/drivers/sbus/char/bbc_envctrl.c 2014-09-11 18:06:04.622048441 +0200
  206702. @@ -452,9 +452,6 @@
  206703. if (!tp)
  206704. return;
  206705. - INIT_LIST_HEAD(&tp->bp_list);
  206706. - INIT_LIST_HEAD(&tp->glob_list);
  206707. -
  206708. tp->client = bbc_i2c_attach(bp, op);
  206709. if (!tp->client) {
  206710. kfree(tp);
  206711. @@ -500,9 +497,6 @@
  206712. if (!fp)
  206713. return;
  206714. - INIT_LIST_HEAD(&fp->bp_list);
  206715. - INIT_LIST_HEAD(&fp->glob_list);
  206716. -
  206717. fp->client = bbc_i2c_attach(bp, op);
  206718. if (!fp->client) {
  206719. kfree(fp);
  206720. diff -Nur linux-3.14.17/drivers/sbus/char/bbc_i2c.c linux-imx6-3.14/drivers/sbus/char/bbc_i2c.c
  206721. --- linux-3.14.17/drivers/sbus/char/bbc_i2c.c 2014-08-14 03:38:34.000000000 +0200
  206722. +++ linux-imx6-3.14/drivers/sbus/char/bbc_i2c.c 2014-09-11 18:06:04.622048441 +0200
  206723. @@ -300,18 +300,13 @@
  206724. if (!bp)
  206725. return NULL;
  206726. - INIT_LIST_HEAD(&bp->temps);
  206727. - INIT_LIST_HEAD(&bp->fans);
  206728. -
  206729. bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs");
  206730. if (!bp->i2c_control_regs)
  206731. goto fail;
  206732. - if (op->num_resources == 2) {
  206733. - bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
  206734. - if (!bp->i2c_bussel_reg)
  206735. - goto fail;
  206736. - }
  206737. + bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
  206738. + if (!bp->i2c_bussel_reg)
  206739. + goto fail;
  206740. bp->waiting = 0;
  206741. init_waitqueue_head(&bp->wq);
  206742. diff -Nur linux-3.14.17/drivers/scsi/scsi_lib.c linux-imx6-3.14/drivers/scsi/scsi_lib.c
  206743. --- linux-3.14.17/drivers/scsi/scsi_lib.c 2014-08-14 03:38:34.000000000 +0200
  206744. +++ linux-imx6-3.14/drivers/scsi/scsi_lib.c 2014-09-11 18:06:07.698060725 +0200
  206745. @@ -831,14 +831,6 @@
  206746. scsi_next_command(cmd);
  206747. return;
  206748. }
  206749. - } else if (blk_rq_bytes(req) == 0 && result && !sense_deferred) {
  206750. - /*
  206751. - * Certain non BLOCK_PC requests are commands that don't
  206752. - * actually transfer anything (FLUSH), so cannot use
  206753. - * good_bytes != blk_rq_bytes(req) as the signal for an error.
  206754. - * This sets the error explicitly for the problem case.
  206755. - */
  206756. - error = __scsi_error_from_host_byte(cmd, result);
  206757. }
  206758. /* no bidi support for !REQ_TYPE_BLOCK_PC yet */
  206759. diff -Nur linux-3.14.17/drivers/scsi/scsi_transport_iscsi.c linux-imx6-3.14/drivers/scsi/scsi_transport_iscsi.c
  206760. --- linux-3.14.17/drivers/scsi/scsi_transport_iscsi.c 2014-08-14 03:38:34.000000000 +0200
  206761. +++ linux-imx6-3.14/drivers/scsi/scsi_transport_iscsi.c 2014-09-11 18:06:07.698060725 +0200
  206762. @@ -1225,7 +1225,7 @@
  206763. * Adds a sysfs entry for the flashnode session attributes
  206764. *
  206765. * Returns:
  206766. - * pointer to allocated flashnode sess on sucess
  206767. + * pointer to allocated flashnode sess on success
  206768. * %NULL on failure
  206769. */
  206770. struct iscsi_bus_flash_session *
  206771. @@ -1423,7 +1423,7 @@
  206772. }
  206773. /**
  206774. - * iscsi_destroy_flashnode_sess - destory flashnode session entry
  206775. + * iscsi_destroy_flashnode_sess - destroy flashnode session entry
  206776. * @fnode_sess: pointer to flashnode session entry to be destroyed
  206777. *
  206778. * Deletes the flashnode session entry and all children flashnode connection
  206779. @@ -1453,7 +1453,7 @@
  206780. }
  206781. /**
  206782. - * iscsi_destroy_all_flashnode - destory all flashnode session entries
  206783. + * iscsi_destroy_all_flashnode - destroy all flashnode session entries
  206784. * @shost: pointer to host data
  206785. *
  206786. * Destroys all the flashnode session entries and all corresponding children
  206787. diff -Nur linux-3.14.17/drivers/staging/bcm/Typedefs.h linux-imx6-3.14/drivers/staging/bcm/Typedefs.h
  206788. --- linux-3.14.17/drivers/staging/bcm/Typedefs.h 2014-08-14 03:38:34.000000000 +0200
  206789. +++ linux-imx6-3.14/drivers/staging/bcm/Typedefs.h 2014-09-11 18:06:08.118062401 +0200
  206790. @@ -25,16 +25,16 @@
  206791. typedef unsigned long ULONG;
  206792. typedef unsigned long DWORD;
  206793. -typedef char* PCHAR;
  206794. -typedef short* PSHORT;
  206795. -typedef int* PINT;
  206796. -typedef long* PLONG;
  206797. -typedef void* PVOID;
  206798. +typedef char *PCHAR;
  206799. +typedef short *PSHORT;
  206800. +typedef int *PINT;
  206801. +typedef long *PLONG;
  206802. +typedef void *PVOID;
  206803. -typedef unsigned char* PUCHAR;
  206804. -typedef unsigned short* PUSHORT;
  206805. -typedef unsigned int* PUINT;
  206806. -typedef unsigned long* PULONG;
  206807. +typedef unsigned char *PUCHAR;
  206808. +typedef unsigned short *PUSHORT;
  206809. +typedef unsigned int *PUINT;
  206810. +typedef unsigned long *PULONG;
  206811. typedef unsigned long long ULONG64;
  206812. typedef unsigned long long LARGE_INTEGER;
  206813. typedef unsigned int UINT32;
  206814. diff -Nur linux-3.14.17/drivers/staging/media/omap4iss/Kconfig linux-imx6-3.14/drivers/staging/media/omap4iss/Kconfig
  206815. --- linux-3.14.17/drivers/staging/media/omap4iss/Kconfig 2014-08-14 03:38:34.000000000 +0200
  206816. +++ linux-imx6-3.14/drivers/staging/media/omap4iss/Kconfig 2014-09-11 18:06:08.558064158 +0200
  206817. @@ -1,6 +1,6 @@
  206818. config VIDEO_OMAP4
  206819. bool "OMAP 4 Camera support"
  206820. - depends on VIDEO_V4L2=y && VIDEO_V4L2_SUBDEV_API && I2C=y && ARCH_OMAP4
  206821. + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && I2C && ARCH_OMAP4
  206822. select VIDEOBUF2_DMA_CONTIG
  206823. ---help---
  206824. Driver for an OMAP 4 ISS controller.
  206825. diff -Nur linux-3.14.17/drivers/staging/octeon/ethernet-rgmii.c linux-imx6-3.14/drivers/staging/octeon/ethernet-rgmii.c
  206826. --- linux-3.14.17/drivers/staging/octeon/ethernet-rgmii.c 2014-08-14 03:38:34.000000000 +0200
  206827. +++ linux-imx6-3.14/drivers/staging/octeon/ethernet-rgmii.c 2014-09-11 18:06:08.570064206 +0200
  206828. @@ -166,9 +166,8 @@
  206829. if (use_global_register_lock)
  206830. spin_unlock_irqrestore(&global_register_lock, flags);
  206831. - else {
  206832. + else
  206833. mutex_unlock(&priv->phydev->bus->mdio_lock);
  206834. - }
  206835. if (priv->phydev == NULL) {
  206836. /* Tell core. */
  206837. diff -Nur linux-3.14.17/drivers/staging/rtl8821ae/core.c linux-imx6-3.14/drivers/staging/rtl8821ae/core.c
  206838. --- linux-3.14.17/drivers/staging/rtl8821ae/core.c 2014-08-14 03:38:34.000000000 +0200
  206839. +++ linux-imx6-3.14/drivers/staging/rtl8821ae/core.c 2014-09-11 18:06:08.650064525 +0200
  206840. @@ -1414,23 +1414,15 @@
  206841. * before switch channle or power save, or tx buffer packet
  206842. * maybe send after offchannel or rf sleep, this may cause
  206843. * dis-association by AP */
  206844. -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
  206845. -static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
  206846. +static void rtl_op_flush(struct ieee80211_hw *hw,
  206847. + struct ieee80211_vif *vif,
  206848. + u32 queues, bool drop)
  206849. {
  206850. struct rtl_priv *rtlpriv = rtl_priv(hw);
  206851. if (rtlpriv->intf_ops->flush)
  206852. rtlpriv->intf_ops->flush(hw, queues, drop);
  206853. }
  206854. -#else
  206855. -static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
  206856. -{
  206857. - struct rtl_priv *rtlpriv = rtl_priv(hw);
  206858. -
  206859. - if (rtlpriv->intf_ops->flush)
  206860. - rtlpriv->intf_ops->flush(hw, drop);
  206861. -}
  206862. -#endif
  206863. const struct ieee80211_ops rtl_ops = {
  206864. .start = rtl_op_start,
  206865. diff -Nur linux-3.14.17/drivers/staging/vt6655/bssdb.c linux-imx6-3.14/drivers/staging/vt6655/bssdb.c
  206866. --- linux-3.14.17/drivers/staging/vt6655/bssdb.c 2014-08-14 03:38:34.000000000 +0200
  206867. +++ linux-imx6-3.14/drivers/staging/vt6655/bssdb.c 2014-09-11 18:06:08.798065116 +0200
  206868. @@ -983,7 +983,7 @@
  206869. pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
  206870. }
  206871. - if (pDevice->eCommandState == WLAN_ASSOCIATE_WAIT) {
  206872. + {
  206873. pDevice->byReAssocCount++;
  206874. /* 10 sec timeout */
  206875. if ((pDevice->byReAssocCount > 10) && (!pDevice->bLinkPass)) {
  206876. diff -Nur linux-3.14.17/drivers/staging/vt6655/device_main.c linux-imx6-3.14/drivers/staging/vt6655/device_main.c
  206877. --- linux-3.14.17/drivers/staging/vt6655/device_main.c 2014-08-14 03:38:34.000000000 +0200
  206878. +++ linux-imx6-3.14/drivers/staging/vt6655/device_main.c 2014-09-11 18:06:08.802065132 +0200
  206879. @@ -2430,7 +2430,6 @@
  206880. int handled = 0;
  206881. unsigned char byData = 0;
  206882. int ii = 0;
  206883. - unsigned long flags;
  206884. // unsigned char byRSSI;
  206885. MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
  206886. @@ -2456,8 +2455,7 @@
  206887. handled = 1;
  206888. MACvIntDisable(pDevice->PortOffset);
  206889. -
  206890. - spin_lock_irqsave(&pDevice->lock, flags);
  206891. + spin_lock_irq(&pDevice->lock);
  206892. //Make sure current page is 0
  206893. VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
  206894. @@ -2698,8 +2696,7 @@
  206895. MACvSelectPage1(pDevice->PortOffset);
  206896. }
  206897. - spin_unlock_irqrestore(&pDevice->lock, flags);
  206898. -
  206899. + spin_unlock_irq(&pDevice->lock);
  206900. MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
  206901. return IRQ_RETVAL(handled);
  206902. diff -Nur linux-3.14.17/drivers/thermal/device_cooling.c linux-imx6-3.14/drivers/thermal/device_cooling.c
  206903. --- linux-3.14.17/drivers/thermal/device_cooling.c 1970-01-01 01:00:00.000000000 +0100
  206904. +++ linux-imx6-3.14/drivers/thermal/device_cooling.c 2014-09-11 18:06:08.970065802 +0200
  206905. @@ -0,0 +1,151 @@
  206906. +/*
  206907. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  206908. + *
  206909. + * This program is free software; you can redistribute it and/or modify
  206910. + * it under the terms of the GNU General Public License version 2 as
  206911. + * published by the Free Software Foundation.
  206912. + *
  206913. + */
  206914. +
  206915. +#include <linux/module.h>
  206916. +#include <linux/thermal.h>
  206917. +#include <linux/err.h>
  206918. +#include <linux/slab.h>
  206919. +
  206920. +struct devfreq_cooling_device {
  206921. + int id;
  206922. + struct thermal_cooling_device *cool_dev;
  206923. + unsigned int devfreq_state;
  206924. +};
  206925. +
  206926. +static DEFINE_IDR(devfreq_idr);
  206927. +static DEFINE_MUTEX(devfreq_cooling_lock);
  206928. +
  206929. +#define MAX_STATE 1
  206930. +
  206931. +static BLOCKING_NOTIFIER_HEAD(devfreq_cooling_chain_head);
  206932. +
  206933. +int register_devfreq_cooling_notifier(struct notifier_block *nb)
  206934. +{
  206935. + return blocking_notifier_chain_register(
  206936. + &devfreq_cooling_chain_head, nb);
  206937. +}
  206938. +EXPORT_SYMBOL_GPL(register_devfreq_cooling_notifier);
  206939. +
  206940. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
  206941. +{
  206942. + return blocking_notifier_chain_unregister(
  206943. + &devfreq_cooling_chain_head, nb);
  206944. +}
  206945. +EXPORT_SYMBOL_GPL(unregister_devfreq_cooling_notifier);
  206946. +
  206947. +static int devfreq_cooling_notifier_call_chain(unsigned long val)
  206948. +{
  206949. + return (blocking_notifier_call_chain(
  206950. + &devfreq_cooling_chain_head, val, NULL)
  206951. + == NOTIFY_BAD) ? -EINVAL : 0;
  206952. +}
  206953. +
  206954. +static int devfreq_set_cur_state(struct thermal_cooling_device *cdev,
  206955. + unsigned long state)
  206956. +{
  206957. + struct devfreq_cooling_device *devfreq_device = cdev->devdata;
  206958. + int ret;
  206959. +
  206960. + ret = devfreq_cooling_notifier_call_chain(state);
  206961. + if (ret)
  206962. + return -EINVAL;
  206963. + devfreq_device->devfreq_state = state;
  206964. +
  206965. + return 0;
  206966. +}
  206967. +
  206968. +static int devfreq_get_max_state(struct thermal_cooling_device *cdev,
  206969. + unsigned long *state)
  206970. +{
  206971. + *state = MAX_STATE;
  206972. +
  206973. + return 0;
  206974. +}
  206975. +
  206976. +static int devfreq_get_cur_state(struct thermal_cooling_device *cdev,
  206977. + unsigned long *state)
  206978. +{
  206979. + struct devfreq_cooling_device *devfreq_device = cdev->devdata;
  206980. +
  206981. + *state = devfreq_device->devfreq_state;
  206982. +
  206983. + return 0;
  206984. +}
  206985. +
  206986. +static struct thermal_cooling_device_ops const devfreq_cooling_ops = {
  206987. + .get_max_state = devfreq_get_max_state,
  206988. + .get_cur_state = devfreq_get_cur_state,
  206989. + .set_cur_state = devfreq_set_cur_state,
  206990. +};
  206991. +
  206992. +static int get_idr(struct idr *idr, int *id)
  206993. +{
  206994. + int ret;
  206995. +
  206996. + mutex_lock(&devfreq_cooling_lock);
  206997. + ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
  206998. + mutex_unlock(&devfreq_cooling_lock);
  206999. + if (unlikely(ret < 0))
  207000. + return ret;
  207001. + *id = ret;
  207002. +
  207003. + return 0;
  207004. +}
  207005. +
  207006. +static void release_idr(struct idr *idr, int id)
  207007. +{
  207008. + mutex_lock(&devfreq_cooling_lock);
  207009. + idr_remove(idr, id);
  207010. + mutex_unlock(&devfreq_cooling_lock);
  207011. +}
  207012. +
  207013. +struct thermal_cooling_device *devfreq_cooling_register(void)
  207014. +{
  207015. + struct thermal_cooling_device *cool_dev;
  207016. + struct devfreq_cooling_device *devfreq_dev = NULL;
  207017. + char dev_name[THERMAL_NAME_LENGTH];
  207018. + int ret = 0;
  207019. +
  207020. + devfreq_dev = kzalloc(sizeof(struct devfreq_cooling_device),
  207021. + GFP_KERNEL);
  207022. + if (!devfreq_dev)
  207023. + return ERR_PTR(-ENOMEM);
  207024. +
  207025. + ret = get_idr(&devfreq_idr, &devfreq_dev->id);
  207026. + if (ret) {
  207027. + kfree(devfreq_dev);
  207028. + return ERR_PTR(-EINVAL);
  207029. + }
  207030. +
  207031. + snprintf(dev_name, sizeof(dev_name), "thermal-devfreq-%d",
  207032. + devfreq_dev->id);
  207033. +
  207034. + cool_dev = thermal_cooling_device_register(dev_name, devfreq_dev,
  207035. + &devfreq_cooling_ops);
  207036. + if (!cool_dev) {
  207037. + release_idr(&devfreq_idr, devfreq_dev->id);
  207038. + kfree(devfreq_dev);
  207039. + return ERR_PTR(-EINVAL);
  207040. + }
  207041. + devfreq_dev->cool_dev = cool_dev;
  207042. + devfreq_dev->devfreq_state = 0;
  207043. +
  207044. + return cool_dev;
  207045. +}
  207046. +EXPORT_SYMBOL_GPL(devfreq_cooling_register);
  207047. +
  207048. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
  207049. +{
  207050. + struct devfreq_cooling_device *devfreq_dev = cdev->devdata;
  207051. +
  207052. + thermal_cooling_device_unregister(devfreq_dev->cool_dev);
  207053. + release_idr(&devfreq_idr, devfreq_dev->id);
  207054. + kfree(devfreq_dev);
  207055. +}
  207056. +EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
  207057. diff -Nur linux-3.14.17/drivers/thermal/imx_thermal.c linux-imx6-3.14/drivers/thermal/imx_thermal.c
  207058. --- linux-3.14.17/drivers/thermal/imx_thermal.c 2014-08-14 03:38:34.000000000 +0200
  207059. +++ linux-imx6-3.14/drivers/thermal/imx_thermal.c 2014-09-11 18:06:08.970065802 +0200
  207060. @@ -12,6 +12,7 @@
  207061. #include <linux/cpufreq.h>
  207062. #include <linux/delay.h>
  207063. #include <linux/device.h>
  207064. +#include <linux/device_cooling.h>
  207065. #include <linux/init.h>
  207066. #include <linux/interrupt.h>
  207067. #include <linux/io.h>
  207068. @@ -58,13 +59,14 @@
  207069. * that will trigger cooling action when crossed.
  207070. */
  207071. #define IMX_TEMP_PASSIVE 85000
  207072. +#define IMX_TEMP_PASSIVE_COOL_DELTA 10000
  207073. #define IMX_POLLING_DELAY 2000 /* millisecond */
  207074. #define IMX_PASSIVE_DELAY 1000
  207075. struct imx_thermal_data {
  207076. struct thermal_zone_device *tz;
  207077. - struct thermal_cooling_device *cdev;
  207078. + struct thermal_cooling_device *cdev[2];
  207079. enum thermal_device_mode mode;
  207080. struct regmap *tempmon;
  207081. int c1, c2; /* See formula in imx_get_sensor_data() */
  207082. @@ -286,6 +288,24 @@
  207083. return 0;
  207084. }
  207085. + int imx_get_trend(struct thermal_zone_device *tz,
  207086. + int trip, enum thermal_trend *trend)
  207087. +{
  207088. + int ret;
  207089. + unsigned long trip_temp;
  207090. +
  207091. + ret = imx_get_trip_temp(tz, trip, &trip_temp);
  207092. + if (ret < 0)
  207093. + return ret;
  207094. +
  207095. + if (tz->temperature >= (trip_temp - IMX_TEMP_PASSIVE_COOL_DELTA))
  207096. + *trend = THERMAL_TREND_RAISE_FULL;
  207097. + else
  207098. + *trend = THERMAL_TREND_DROP_FULL;
  207099. +
  207100. + return 0;
  207101. +}
  207102. +
  207103. static struct thermal_zone_device_ops imx_tz_ops = {
  207104. .bind = imx_bind,
  207105. .unbind = imx_unbind,
  207106. @@ -295,6 +315,7 @@
  207107. .get_trip_type = imx_get_trip_type,
  207108. .get_trip_temp = imx_get_trip_temp,
  207109. .get_crit_temp = imx_get_crit_temp,
  207110. + .get_trend = imx_get_trend,
  207111. .set_trip_temp = imx_set_trip_temp,
  207112. };
  207113. @@ -437,9 +458,17 @@
  207114. regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
  207115. cpumask_set_cpu(0, &clip_cpus);
  207116. - data->cdev = cpufreq_cooling_register(&clip_cpus);
  207117. - if (IS_ERR(data->cdev)) {
  207118. - ret = PTR_ERR(data->cdev);
  207119. + data->cdev[0] = cpufreq_cooling_register(&clip_cpus);
  207120. + if (IS_ERR(data->cdev[0])) {
  207121. + ret = PTR_ERR(data->cdev[0]);
  207122. + dev_err(&pdev->dev,
  207123. + "failed to register cpufreq cooling device: %d\n", ret);
  207124. + return ret;
  207125. + }
  207126. +
  207127. + data->cdev[1] = cpufreq_cooling_register(&clip_cpus);
  207128. + if (IS_ERR(data->cdev[1])) {
  207129. + ret = PTR_ERR(data->cdev[1]);
  207130. dev_err(&pdev->dev,
  207131. "failed to register cpufreq cooling device: %d\n", ret);
  207132. return ret;
  207133. @@ -455,7 +484,8 @@
  207134. ret = PTR_ERR(data->tz);
  207135. dev_err(&pdev->dev,
  207136. "failed to register thermal zone device %d\n", ret);
  207137. - cpufreq_cooling_unregister(data->cdev);
  207138. + cpufreq_cooling_unregister(data->cdev[0]);
  207139. + devfreq_cooling_unregister(data->cdev[1]);
  207140. return ret;
  207141. }
  207142. @@ -500,7 +530,8 @@
  207143. clk_disable_unprepare(data->thermal_clk);
  207144. thermal_zone_device_unregister(data->tz);
  207145. - cpufreq_cooling_unregister(data->cdev);
  207146. + cpufreq_cooling_unregister(data->cdev[0]);
  207147. + devfreq_cooling_unregister(data->cdev[1]);
  207148. return 0;
  207149. }
  207150. diff -Nur linux-3.14.17/drivers/thermal/Kconfig linux-imx6-3.14/drivers/thermal/Kconfig
  207151. --- linux-3.14.17/drivers/thermal/Kconfig 2014-08-14 03:38:34.000000000 +0200
  207152. +++ linux-imx6-3.14/drivers/thermal/Kconfig 2014-09-11 18:06:08.966065786 +0200
  207153. @@ -125,6 +125,13 @@
  207154. cpufreq is used as the cooling device to throttle CPUs when the
  207155. passive trip is crossed.
  207156. +config DEVICE_THERMAL
  207157. + tristate "generic device cooling support"
  207158. + help
  207159. + Support for device cooling.
  207160. + It supports notification of crossing passive trip for devices,
  207161. + devices need to do their own actions to cool down the SOC.
  207162. +
  207163. config SPEAR_THERMAL
  207164. bool "SPEAr thermal sensor driver"
  207165. depends on PLAT_SPEAR
  207166. diff -Nur linux-3.14.17/drivers/thermal/Makefile linux-imx6-3.14/drivers/thermal/Makefile
  207167. --- linux-3.14.17/drivers/thermal/Makefile 2014-08-14 03:38:34.000000000 +0200
  207168. +++ linux-imx6-3.14/drivers/thermal/Makefile 2014-09-11 18:06:08.966065786 +0200
  207169. @@ -26,6 +26,7 @@
  207170. obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
  207171. obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
  207172. obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
  207173. +obj-$(CONFIG_DEVICE_THERMAL) += device_cooling.o
  207174. obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
  207175. obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
  207176. obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
  207177. diff -Nur linux-3.14.17/drivers/tty/serial/earlycon.c linux-imx6-3.14/drivers/tty/serial/earlycon.c
  207178. --- linux-3.14.17/drivers/tty/serial/earlycon.c 1970-01-01 01:00:00.000000000 +0100
  207179. +++ linux-imx6-3.14/drivers/tty/serial/earlycon.c 2014-09-11 18:06:09.002065930 +0200
  207180. @@ -0,0 +1,152 @@
  207181. +/*
  207182. + * Copyright (C) 2014 Linaro Ltd.
  207183. + * Author: Rob Herring <robh@kernel.org>
  207184. + *
  207185. + * Based on 8250 earlycon:
  207186. + * (c) Copyright 2004 Hewlett-Packard Development Company, L.P.
  207187. + * Bjorn Helgaas <bjorn.helgaas@hp.com>
  207188. + *
  207189. + * This program is free software: you can redistribute it and/or modify
  207190. + * it under the terms of the GNU General Public License version 2 as
  207191. + * published by the Free Software Foundation.
  207192. + */
  207193. +#include <linux/console.h>
  207194. +#include <linux/kernel.h>
  207195. +#include <linux/init.h>
  207196. +#include <linux/io.h>
  207197. +#include <linux/serial_core.h>
  207198. +
  207199. +#ifdef CONFIG_FIX_EARLYCON_MEM
  207200. +#include <asm/fixmap.h>
  207201. +#endif
  207202. +
  207203. +#include <asm/serial.h>
  207204. +
  207205. +static struct console early_con = {
  207206. + .name = "earlycon",
  207207. + .flags = CON_PRINTBUFFER | CON_BOOT,
  207208. + .index = -1,
  207209. +};
  207210. +
  207211. +static struct earlycon_device early_console_dev = {
  207212. + .con = &early_con,
  207213. +};
  207214. +
  207215. +static void __iomem * __init earlycon_map(unsigned long paddr, size_t size)
  207216. +{
  207217. + void __iomem *base;
  207218. +#ifdef CONFIG_FIX_EARLYCON_MEM
  207219. + set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr & PAGE_MASK);
  207220. + base = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE);
  207221. + base += paddr & ~PAGE_MASK;
  207222. +#else
  207223. + base = ioremap(paddr, size);
  207224. +#endif
  207225. + if (!base)
  207226. + pr_err("%s: Couldn't map 0x%llx\n", __func__,
  207227. + (unsigned long long)paddr);
  207228. +
  207229. + return base;
  207230. +}
  207231. +
  207232. +static int __init parse_options(struct earlycon_device *device,
  207233. + char *options)
  207234. +{
  207235. + struct uart_port *port = &device->port;
  207236. + int mmio, mmio32, length, ret;
  207237. + unsigned long addr;
  207238. +
  207239. + if (!options)
  207240. + return -ENODEV;
  207241. +
  207242. + mmio = !strncmp(options, "mmio,", 5);
  207243. + mmio32 = !strncmp(options, "mmio32,", 7);
  207244. + if (mmio || mmio32) {
  207245. + port->iotype = (mmio ? UPIO_MEM : UPIO_MEM32);
  207246. + options += mmio ? 5 : 7;
  207247. + ret = kstrtoul(options, 0, &addr);
  207248. + if (ret)
  207249. + return ret;
  207250. + port->mapbase = addr;
  207251. + if (mmio32)
  207252. + port->regshift = 2;
  207253. + } else if (!strncmp(options, "io,", 3)) {
  207254. + port->iotype = UPIO_PORT;
  207255. + options += 3;
  207256. + ret = kstrtoul(options, 0, &addr);
  207257. + if (ret)
  207258. + return ret;
  207259. + port->iobase = addr;
  207260. + mmio = 0;
  207261. + } else if (!strncmp(options, "0x", 2)) {
  207262. + port->iotype = UPIO_MEM;
  207263. + ret = kstrtoul(options, 0, &addr);
  207264. + if (ret)
  207265. + return ret;
  207266. + port->mapbase = addr;
  207267. + } else {
  207268. + return -EINVAL;
  207269. + }
  207270. +
  207271. + port->uartclk = BASE_BAUD * 16;
  207272. +
  207273. + options = strchr(options, ',');
  207274. + if (options) {
  207275. + options++;
  207276. + ret = kstrtouint(options, 0, &device->baud);
  207277. + if (ret)
  207278. + return ret;
  207279. + length = min(strcspn(options, " ") + 1,
  207280. + (size_t)(sizeof(device->options)));
  207281. + strlcpy(device->options, options, length);
  207282. + }
  207283. +
  207284. + if (mmio || mmio32)
  207285. + pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n",
  207286. + mmio32 ? "32" : "",
  207287. + (unsigned long long)port->mapbase,
  207288. + device->options);
  207289. + else
  207290. + pr_info("Early serial console at I/O port 0x%lx (options '%s')\n",
  207291. + port->iobase,
  207292. + device->options);
  207293. +
  207294. + return 0;
  207295. +}
  207296. +
  207297. +int __init setup_earlycon(char *buf, const char *match,
  207298. + int (*setup)(struct earlycon_device *, const char *))
  207299. +{
  207300. + int err;
  207301. + size_t len;
  207302. + struct uart_port *port = &early_console_dev.port;
  207303. +
  207304. + if (!buf || !match || !setup)
  207305. + return 0;
  207306. +
  207307. + len = strlen(match);
  207308. + if (strncmp(buf, match, len))
  207309. + return 0;
  207310. + if (buf[len] && (buf[len] != ','))
  207311. + return 0;
  207312. +
  207313. + buf += len + 1;
  207314. +
  207315. + err = parse_options(&early_console_dev, buf);
  207316. + /* On parsing error, pass the options buf to the setup function */
  207317. + if (!err)
  207318. + buf = NULL;
  207319. +
  207320. + if (port->mapbase)
  207321. + port->membase = earlycon_map(port->mapbase, 64);
  207322. +
  207323. + early_console_dev.con->data = &early_console_dev;
  207324. + err = setup(&early_console_dev, buf);
  207325. + if (err < 0)
  207326. + return err;
  207327. + if (!early_console_dev.con->write)
  207328. + return -ENODEV;
  207329. +
  207330. + register_console(early_console_dev.con);
  207331. + return 0;
  207332. +}
  207333. diff -Nur linux-3.14.17/drivers/tty/serial/Kconfig linux-imx6-3.14/drivers/tty/serial/Kconfig
  207334. --- linux-3.14.17/drivers/tty/serial/Kconfig 2014-08-14 03:38:34.000000000 +0200
  207335. +++ linux-imx6-3.14/drivers/tty/serial/Kconfig 2014-09-11 18:06:08.994065898 +0200
  207336. @@ -7,6 +7,13 @@
  207337. menu "Serial drivers"
  207338. depends on HAS_IOMEM
  207339. +config SERIAL_EARLYCON
  207340. + bool
  207341. + help
  207342. + Support for early consoles with the earlycon parameter. This enables
  207343. + the console before standard serial driver is probed. The console is
  207344. + enabled when early_param is processed.
  207345. +
  207346. source "drivers/tty/serial/8250/Kconfig"
  207347. comment "Non-8250 serial port support"
  207348. diff -Nur linux-3.14.17/drivers/tty/serial/Makefile linux-imx6-3.14/drivers/tty/serial/Makefile
  207349. --- linux-3.14.17/drivers/tty/serial/Makefile 2014-08-14 03:38:34.000000000 +0200
  207350. +++ linux-imx6-3.14/drivers/tty/serial/Makefile 2014-09-11 18:06:08.994065898 +0200
  207351. @@ -5,6 +5,8 @@
  207352. obj-$(CONFIG_SERIAL_CORE) += serial_core.o
  207353. obj-$(CONFIG_SERIAL_21285) += 21285.o
  207354. +obj-$(CONFIG_SERIAL_EARLYCON) += earlycon.o
  207355. +
  207356. # These Sparc drivers have to appear before others such as 8250
  207357. # which share ttySx minor node space. Otherwise console device
  207358. # names change and other unplesantries.
  207359. diff -Nur linux-3.14.17/drivers/tty/serial/sunsab.c linux-imx6-3.14/drivers/tty/serial/sunsab.c
  207360. --- linux-3.14.17/drivers/tty/serial/sunsab.c 2014-08-14 03:38:34.000000000 +0200
  207361. +++ linux-imx6-3.14/drivers/tty/serial/sunsab.c 2014-09-11 18:06:09.018065994 +0200
  207362. @@ -157,15 +157,6 @@
  207363. (up->port.line == up->port.cons->index))
  207364. saw_console_brk = 1;
  207365. - if (count == 0) {
  207366. - if (unlikely(stat->sreg.isr1 & SAB82532_ISR1_BRK)) {
  207367. - stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR |
  207368. - SAB82532_ISR0_FERR);
  207369. - up->port.icount.brk++;
  207370. - uart_handle_break(&up->port);
  207371. - }
  207372. - }
  207373. -
  207374. for (i = 0; i < count; i++) {
  207375. unsigned char ch = buf[i], flag;
  207376. diff -Nur linux-3.14.17/drivers/usb/chipidea/ci.h linux-imx6-3.14/drivers/usb/chipidea/ci.h
  207377. --- linux-3.14.17/drivers/usb/chipidea/ci.h 2014-08-14 03:38:34.000000000 +0200
  207378. +++ linux-imx6-3.14/drivers/usb/chipidea/ci.h 2014-09-11 18:06:09.078066233 +0200
  207379. @@ -139,8 +139,8 @@
  207380. * @roles: array of supported roles for this controller
  207381. * @role: current role
  207382. * @is_otg: if the device is otg-capable
  207383. - * @work: work for role changing
  207384. - * @wq: workqueue thread
  207385. + * @otg_task: the thread for handling otg task
  207386. + * @otg_wait: the otg event waitqueue head
  207387. * @qh_pool: allocation pool for queue heads
  207388. * @td_pool: allocation pool for transfer descriptors
  207389. * @gadget: device side representation for peripheral controller
  207390. @@ -165,6 +165,10 @@
  207391. * @b_sess_valid_event: indicates there is a vbus event, and handled
  207392. * at ci_otg_work
  207393. * @imx28_write_fix: Freescale imx28 needs swp instruction for writing
  207394. + * @supports_runtime_pm: if runtime pm is supported
  207395. + * @in_lpm: if the core in low power mode
  207396. + * @wakeup_int: if wakeup interrupt occur
  207397. + * @timer: timer to delay clock closing
  207398. */
  207399. struct ci_hdrc {
  207400. struct device *dev;
  207401. @@ -174,8 +178,8 @@
  207402. struct ci_role_driver *roles[CI_ROLE_END];
  207403. enum ci_role role;
  207404. bool is_otg;
  207405. - struct work_struct work;
  207406. - struct workqueue_struct *wq;
  207407. + struct task_struct *otg_task;
  207408. + wait_queue_head_t otg_wait;
  207409. struct dma_pool *qh_pool;
  207410. struct dma_pool *td_pool;
  207411. @@ -204,6 +208,10 @@
  207412. bool id_event;
  207413. bool b_sess_valid_event;
  207414. bool imx28_write_fix;
  207415. + bool supports_runtime_pm;
  207416. + bool in_lpm;
  207417. + bool wakeup_int;
  207418. + struct timer_list timer;
  207419. };
  207420. static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
  207421. diff -Nur linux-3.14.17/drivers/usb/chipidea/ci_hdrc_imx.c linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.c
  207422. --- linux-3.14.17/drivers/usb/chipidea/ci_hdrc_imx.c 2014-08-14 03:38:34.000000000 +0200
  207423. +++ linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.c 2014-09-11 18:06:09.078066233 +0200
  207424. @@ -19,11 +19,14 @@
  207425. #include <linux/dma-mapping.h>
  207426. #include <linux/usb/chipidea.h>
  207427. #include <linux/clk.h>
  207428. +#include <linux/busfreq-imx6.h>
  207429. #include "ci.h"
  207430. #include "ci_hdrc_imx.h"
  207431. -#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
  207432. +#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
  207433. +#define CI_HDRC_IMX_SUPPORT_RUNTIME_PM BIT(1)
  207434. +#define CI_HDRC_IMX_HOST_QUIRK BIT(2)
  207435. struct ci_hdrc_imx_platform_flag {
  207436. unsigned int flags;
  207437. @@ -32,12 +35,30 @@
  207438. static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
  207439. };
  207440. +static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
  207441. + .flags = CI_HDRC_IMX_HOST_QUIRK,
  207442. +};
  207443. +
  207444. static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
  207445. - .flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
  207446. + .flags = CI_HDRC_IMX_IMX28_WRITE_FIX |
  207447. + CI_HDRC_IMX_HOST_QUIRK,
  207448. +};
  207449. +
  207450. +static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
  207451. + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
  207452. + CI_HDRC_IMX_HOST_QUIRK,
  207453. +};
  207454. +
  207455. +static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
  207456. + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
  207457. + CI_HDRC_IMX_HOST_QUIRK,
  207458. };
  207459. static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
  207460. + { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
  207461. + { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
  207462. { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
  207463. + { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
  207464. { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
  207465. { /* sentinel */ }
  207466. };
  207467. @@ -48,6 +69,8 @@
  207468. struct platform_device *ci_pdev;
  207469. struct clk *clk;
  207470. struct imx_usbmisc_data *usbmisc_data;
  207471. + bool supports_runtime_pm;
  207472. + bool in_lpm;
  207473. };
  207474. /* Common functions shared by usbmisc drivers */
  207475. @@ -123,8 +146,10 @@
  207476. return PTR_ERR(data->clk);
  207477. }
  207478. + request_bus_freq(BUS_FREQ_HIGH);
  207479. ret = clk_prepare_enable(data->clk);
  207480. if (ret) {
  207481. + release_bus_freq(BUS_FREQ_HIGH);
  207482. dev_err(&pdev->dev,
  207483. "Failed to prepare or enable clock, err=%d\n", ret);
  207484. return ret;
  207485. @@ -145,6 +170,14 @@
  207486. if (ret)
  207487. goto err_clk;
  207488. + if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
  207489. + pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
  207490. + data->supports_runtime_pm = true;
  207491. + }
  207492. +
  207493. + if (imx_platform_flag->flags & CI_HDRC_IMX_HOST_QUIRK)
  207494. + pdata.flags |= CI_HDRC_IMX_EHCI_QUIRK;
  207495. +
  207496. if (data->usbmisc_data) {
  207497. ret = imx_usbmisc_init(data->usbmisc_data);
  207498. if (ret) {
  207499. @@ -165,6 +198,11 @@
  207500. goto err_clk;
  207501. }
  207502. + /* usbmisc needs to know dr mode to choose wakeup setting */
  207503. + if (data->usbmisc_data)
  207504. + data->usbmisc_data->available_role =
  207505. + ci_hdrc_query_available_role(data->ci_pdev);
  207506. +
  207507. if (data->usbmisc_data) {
  207508. ret = imx_usbmisc_init_post(data->usbmisc_data);
  207509. if (ret) {
  207510. @@ -174,10 +212,23 @@
  207511. }
  207512. }
  207513. + if (data->usbmisc_data) {
  207514. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
  207515. + if (ret) {
  207516. + dev_err(&pdev->dev, "usbmisc set_wakeup failed, ret=%d\n",
  207517. + ret);
  207518. + goto disable_device;
  207519. + }
  207520. + }
  207521. +
  207522. platform_set_drvdata(pdev, data);
  207523. - pm_runtime_no_callbacks(&pdev->dev);
  207524. - pm_runtime_enable(&pdev->dev);
  207525. + device_set_wakeup_capable(&pdev->dev, true);
  207526. +
  207527. + if (data->supports_runtime_pm) {
  207528. + pm_runtime_set_active(&pdev->dev);
  207529. + pm_runtime_enable(&pdev->dev);
  207530. + }
  207531. return 0;
  207532. @@ -185,6 +236,7 @@
  207533. ci_hdrc_remove_device(data->ci_pdev);
  207534. err_clk:
  207535. clk_disable_unprepare(data->clk);
  207536. + release_bus_freq(BUS_FREQ_HIGH);
  207537. return ret;
  207538. }
  207539. @@ -195,10 +247,119 @@
  207540. pm_runtime_disable(&pdev->dev);
  207541. ci_hdrc_remove_device(data->ci_pdev);
  207542. clk_disable_unprepare(data->clk);
  207543. + release_bus_freq(BUS_FREQ_HIGH);
  207544. return 0;
  207545. }
  207546. +#ifdef CONFIG_PM
  207547. +static int imx_controller_suspend(struct device *dev)
  207548. +{
  207549. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  207550. + int ret;
  207551. +
  207552. + dev_dbg(dev, "at %s\n", __func__);
  207553. +
  207554. + if (data->in_lpm)
  207555. + return 0;
  207556. +
  207557. + if (data->usbmisc_data) {
  207558. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
  207559. + if (ret) {
  207560. + dev_err(dev,
  207561. + "usbmisc set_wakeup failed, ret=%d\n",
  207562. + ret);
  207563. + return ret;
  207564. + }
  207565. + }
  207566. +
  207567. + clk_disable_unprepare(data->clk);
  207568. + release_bus_freq(BUS_FREQ_HIGH);
  207569. + data->in_lpm = true;
  207570. +
  207571. + return 0;
  207572. +}
  207573. +
  207574. +static int imx_controller_resume(struct device *dev)
  207575. +{
  207576. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  207577. + int ret = 0;
  207578. +
  207579. + dev_dbg(dev, "at %s\n", __func__);
  207580. +
  207581. + if (!data->in_lpm)
  207582. + return 0;
  207583. +
  207584. + request_bus_freq(BUS_FREQ_HIGH);
  207585. + ret = clk_prepare_enable(data->clk);
  207586. + if (ret) {
  207587. + release_bus_freq(BUS_FREQ_HIGH);
  207588. + return ret;
  207589. + }
  207590. +
  207591. + data->in_lpm = false;
  207592. +
  207593. + if (data->usbmisc_data) {
  207594. + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
  207595. + if (ret) {
  207596. + dev_err(dev,
  207597. + "usbmisc set_wakeup failed, ret=%d\n",
  207598. + ret);
  207599. + ret = -EINVAL;
  207600. + goto clk_disable;
  207601. + }
  207602. + }
  207603. +
  207604. + return 0;
  207605. +
  207606. +clk_disable:
  207607. + clk_disable_unprepare(data->clk);
  207608. + release_bus_freq(BUS_FREQ_HIGH);
  207609. +
  207610. + return ret;
  207611. +}
  207612. +
  207613. +#ifdef CONFIG_PM_SLEEP
  207614. +static int ci_hdrc_imx_suspend(struct device *dev)
  207615. +{
  207616. + return imx_controller_suspend(dev);
  207617. +}
  207618. +
  207619. +static int ci_hdrc_imx_resume(struct device *dev)
  207620. +{
  207621. + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
  207622. + int ret;
  207623. +
  207624. + ret = imx_controller_resume(dev);
  207625. + if (!ret && data->supports_runtime_pm) {
  207626. + pm_runtime_disable(dev);
  207627. + pm_runtime_set_active(dev);
  207628. + pm_runtime_enable(dev);
  207629. + }
  207630. +
  207631. + return ret;
  207632. +}
  207633. +#endif /* CONFIG_PM_SLEEP */
  207634. +
  207635. +#ifdef CONFIG_PM_RUNTIME
  207636. +static int ci_hdrc_imx_runtime_suspend(struct device *dev)
  207637. +{
  207638. + return imx_controller_suspend(dev);
  207639. +}
  207640. +
  207641. +static int ci_hdrc_imx_runtime_resume(struct device *dev)
  207642. +{
  207643. + return imx_controller_resume(dev);
  207644. +}
  207645. +#endif /* CONFIG_PM_RUNTIME */
  207646. +
  207647. +#endif /* CONFIG_PM */
  207648. +static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
  207649. + SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
  207650. + SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
  207651. + ci_hdrc_imx_runtime_resume, NULL)
  207652. +};
  207653. +
  207654. static struct platform_driver ci_hdrc_imx_driver = {
  207655. .probe = ci_hdrc_imx_probe,
  207656. .remove = ci_hdrc_imx_remove,
  207657. @@ -206,6 +367,7 @@
  207658. .name = "imx_usb",
  207659. .owner = THIS_MODULE,
  207660. .of_match_table = ci_hdrc_imx_dt_ids,
  207661. + .pm = &ci_hdrc_imx_pm_ops,
  207662. },
  207663. };
  207664. diff -Nur linux-3.14.17/drivers/usb/chipidea/ci_hdrc_imx.h linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.h
  207665. --- linux-3.14.17/drivers/usb/chipidea/ci_hdrc_imx.h 2014-08-14 03:38:34.000000000 +0200
  207666. +++ linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_imx.h 2014-09-11 18:06:09.078066233 +0200
  207667. @@ -1,5 +1,5 @@
  207668. /*
  207669. - * Copyright 2012 Freescale Semiconductor, Inc.
  207670. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  207671. *
  207672. * The code contained herein is licensed under the GNU General Public
  207673. * License. You may obtain a copy of the GNU General Public License
  207674. @@ -12,14 +12,18 @@
  207675. #ifndef __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
  207676. #define __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
  207677. +#include <linux/usb/otg.h>
  207678. +
  207679. struct imx_usbmisc_data {
  207680. int index;
  207681. unsigned int disable_oc:1; /* over current detect disabled */
  207682. unsigned int evdo:1; /* set external vbus divider option */
  207683. + enum usb_dr_mode available_role;
  207684. };
  207685. int imx_usbmisc_init(struct imx_usbmisc_data *);
  207686. int imx_usbmisc_init_post(struct imx_usbmisc_data *);
  207687. +int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *, bool);
  207688. #endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */
  207689. diff -Nur linux-3.14.17/drivers/usb/chipidea/ci_hdrc_msm.c linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_msm.c
  207690. --- linux-3.14.17/drivers/usb/chipidea/ci_hdrc_msm.c 2014-08-14 03:38:34.000000000 +0200
  207691. +++ linux-imx6-3.14/drivers/usb/chipidea/ci_hdrc_msm.c 2014-09-11 18:06:09.078066233 +0200
  207692. @@ -17,7 +17,7 @@
  207693. #define MSM_USB_BASE (ci->hw_bank.abs)
  207694. -static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
  207695. +static int ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
  207696. {
  207697. struct device *dev = ci->gadget.dev.parent;
  207698. int val;
  207699. @@ -43,6 +43,8 @@
  207700. dev_dbg(dev, "unknown ci_hdrc event\n");
  207701. break;
  207702. }
  207703. +
  207704. + return 0;
  207705. }
  207706. static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
  207707. diff -Nur linux-3.14.17/drivers/usb/chipidea/core.c linux-imx6-3.14/drivers/usb/chipidea/core.c
  207708. --- linux-3.14.17/drivers/usb/chipidea/core.c 2014-08-14 03:38:34.000000000 +0200
  207709. +++ linux-imx6-3.14/drivers/usb/chipidea/core.c 2014-09-11 18:06:09.078066233 +0200
  207710. @@ -165,25 +165,30 @@
  207711. return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC);
  207712. }
  207713. +static void hw_wait_phy_stable(void)
  207714. +{
  207715. + /* The controller needs at least 1ms to reflect PHY's status */
  207716. + usleep_range(2000, 2500);
  207717. +}
  207718. +
  207719. +static void delay_runtime_pm_put_timer(unsigned long arg)
  207720. +{
  207721. + struct ci_hdrc *ci = (struct ci_hdrc *)arg;
  207722. +
  207723. + pm_runtime_put(ci->dev);
  207724. +}
  207725. +
  207726. /* The PHY enters/leaves low power mode */
  207727. static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
  207728. {
  207729. enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC;
  207730. bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm)));
  207731. - if (enable && !lpm) {
  207732. + if (enable && !lpm)
  207733. hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
  207734. PORTSC_PHCD(ci->hw_bank.lpm));
  207735. - } else if (!enable && lpm) {
  207736. - hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
  207737. - 0);
  207738. - /*
  207739. - * The controller needs at least 1ms to reflect
  207740. - * PHY's status, the PHY also needs some time (less
  207741. - * than 1ms) to leave low power mode.
  207742. - */
  207743. - usleep_range(1500, 2000);
  207744. - }
  207745. + else if (!enable && lpm)
  207746. + hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), 0);
  207747. }
  207748. static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
  207749. @@ -351,6 +356,13 @@
  207750. irqreturn_t ret = IRQ_NONE;
  207751. u32 otgsc = 0;
  207752. + if (ci->in_lpm) {
  207753. + disable_irq_nosync(irq);
  207754. + ci->wakeup_int = true;
  207755. + pm_runtime_get(ci->dev);
  207756. + return IRQ_HANDLED;
  207757. + }
  207758. +
  207759. if (ci->is_otg)
  207760. otgsc = hw_read(ci, OP_OTGSC, ~0);
  207761. @@ -362,7 +374,7 @@
  207762. ci->id_event = true;
  207763. ci_clear_otg_interrupt(ci, OTGSC_IDIS);
  207764. disable_irq_nosync(ci->irq);
  207765. - queue_work(ci->wq, &ci->work);
  207766. + wake_up(&ci->otg_wait);
  207767. return IRQ_HANDLED;
  207768. }
  207769. @@ -374,7 +386,7 @@
  207770. ci->b_sess_valid_event = true;
  207771. ci_clear_otg_interrupt(ci, OTGSC_BSVIS);
  207772. disable_irq_nosync(ci->irq);
  207773. - queue_work(ci->wq, &ci->work);
  207774. + wake_up(&ci->otg_wait);
  207775. return IRQ_HANDLED;
  207776. }
  207777. @@ -473,6 +485,33 @@
  207778. }
  207779. EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);
  207780. +/**
  207781. + * ci_hdrc_query_available_role: get runtime available operation mode
  207782. + *
  207783. + * The glue layer can get current operation mode (host/peripheral/otg)
  207784. + * This function should be called after ci core device has created.
  207785. + *
  207786. + * @pdev: the platform device of ci core.
  207787. + *
  207788. + * Return USB_DR_MODE_XXX.
  207789. + */
  207790. +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev)
  207791. +{
  207792. + struct ci_hdrc *ci = platform_get_drvdata(pdev);
  207793. +
  207794. + if (!ci)
  207795. + return USB_DR_MODE_UNKNOWN;
  207796. + if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET])
  207797. + return USB_DR_MODE_OTG;
  207798. + else if (ci->roles[CI_ROLE_HOST])
  207799. + return USB_DR_MODE_HOST;
  207800. + else if (ci->roles[CI_ROLE_GADGET])
  207801. + return USB_DR_MODE_PERIPHERAL;
  207802. + else
  207803. + return USB_DR_MODE_UNKNOWN;
  207804. +}
  207805. +EXPORT_SYMBOL_GPL(ci_hdrc_query_available_role);
  207806. +
  207807. static inline void ci_role_destroy(struct ci_hdrc *ci)
  207808. {
  207809. ci_hdrc_gadget_destroy(ci);
  207810. @@ -498,9 +537,14 @@
  207811. static int ci_usb_phy_init(struct ci_hdrc *ci)
  207812. {
  207813. + int ret;
  207814. +
  207815. if (ci->platdata->phy) {
  207816. ci->transceiver = ci->platdata->phy;
  207817. - return usb_phy_init(ci->transceiver);
  207818. + ret = usb_phy_init(ci->transceiver);
  207819. + if (!ret)
  207820. + hw_wait_phy_stable();
  207821. + return ret;
  207822. } else {
  207823. ci->global_phy = true;
  207824. ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
  207825. @@ -559,8 +603,6 @@
  207826. return -ENODEV;
  207827. }
  207828. - hw_phymode_configure(ci);
  207829. -
  207830. ret = ci_usb_phy_init(ci);
  207831. if (ret) {
  207832. dev_err(dev, "unable to init phy: %d\n", ret);
  207833. @@ -578,7 +620,13 @@
  207834. ci_get_otg_capable(ci);
  207835. + hw_phymode_configure(ci);
  207836. +
  207837. dr_mode = ci->platdata->dr_mode;
  207838. +
  207839. + ci->supports_runtime_pm = !!(ci->platdata->flags &
  207840. + CI_HDRC_SUPPORTS_RUNTIME_PM);
  207841. +
  207842. /* initialize role(s) before the interrupt is requested */
  207843. if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
  207844. ret = ci_hdrc_host_init(ci);
  207845. @@ -619,11 +667,6 @@
  207846. if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
  207847. if (ci->is_otg) {
  207848. - /*
  207849. - * ID pin needs 1ms debouce time,
  207850. - * we delay 2ms for safe.
  207851. - */
  207852. - mdelay(2);
  207853. ci->role = ci_otg_role(ci);
  207854. ci_enable_otg_interrupt(ci, OTGSC_IDIE);
  207855. } else {
  207856. @@ -656,6 +699,15 @@
  207857. if (ret)
  207858. goto stop;
  207859. + device_set_wakeup_capable(&pdev->dev, true);
  207860. +
  207861. + if (ci->supports_runtime_pm) {
  207862. + pm_runtime_set_active(&pdev->dev);
  207863. + pm_runtime_enable(&pdev->dev);
  207864. + }
  207865. +
  207866. + setup_timer(&ci->timer, delay_runtime_pm_put_timer,
  207867. + (unsigned long)ci);
  207868. ret = dbg_create_files(ci);
  207869. if (!ret)
  207870. return 0;
  207871. @@ -673,6 +725,11 @@
  207872. {
  207873. struct ci_hdrc *ci = platform_get_drvdata(pdev);
  207874. + if (ci->supports_runtime_pm) {
  207875. + pm_runtime_get_sync(&pdev->dev);
  207876. + pm_runtime_disable(&pdev->dev);
  207877. + pm_runtime_put_noidle(&pdev->dev);
  207878. + }
  207879. dbg_remove_files(ci);
  207880. free_irq(ci->irq, ci);
  207881. ci_role_destroy(ci);
  207882. @@ -682,11 +739,120 @@
  207883. return 0;
  207884. }
  207885. +#ifdef CONFIG_PM
  207886. +static int ci_controller_suspend(struct device *dev)
  207887. +{
  207888. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  207889. +
  207890. + dev_dbg(dev, "at %s\n", __func__);
  207891. +
  207892. + if (ci->in_lpm)
  207893. + return 0;
  207894. +
  207895. + disable_irq(ci->irq);
  207896. +
  207897. + if (ci->transceiver)
  207898. + usb_phy_set_wakeup(ci->transceiver, true);
  207899. +
  207900. + ci_hdrc_enter_lpm(ci, true);
  207901. +
  207902. + if (ci->transceiver)
  207903. + usb_phy_set_suspend(ci->transceiver, 1);
  207904. +
  207905. + ci->in_lpm = true;
  207906. +
  207907. + enable_irq(ci->irq);
  207908. +
  207909. + return 0;
  207910. +}
  207911. +
  207912. +static int ci_controller_resume(struct device *dev)
  207913. +{
  207914. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  207915. +
  207916. + dev_dbg(dev, "at %s\n", __func__);
  207917. +
  207918. + if (!ci->in_lpm)
  207919. + return 0;
  207920. +
  207921. + ci_hdrc_enter_lpm(ci, false);
  207922. +
  207923. + if (ci->transceiver) {
  207924. + usb_phy_set_suspend(ci->transceiver, 0);
  207925. + usb_phy_set_wakeup(ci->transceiver, false);
  207926. + hw_wait_phy_stable();
  207927. + }
  207928. +
  207929. + ci->in_lpm = false;
  207930. +
  207931. + if (ci->wakeup_int) {
  207932. + ci->wakeup_int = false;
  207933. + enable_irq(ci->irq);
  207934. + mod_timer(&ci->timer, jiffies + msecs_to_jiffies(2000));
  207935. + }
  207936. +
  207937. + return 0;
  207938. +}
  207939. +
  207940. +#ifdef CONFIG_PM_SLEEP
  207941. +static int ci_suspend(struct device *dev)
  207942. +{
  207943. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  207944. + int ret;
  207945. +
  207946. + ret = ci_controller_suspend(dev);
  207947. + if (ret)
  207948. + return ret;
  207949. +
  207950. + if (device_may_wakeup(dev))
  207951. + enable_irq_wake(ci->irq);
  207952. +
  207953. + return ret;
  207954. +}
  207955. +
  207956. +static int ci_resume(struct device *dev)
  207957. +{
  207958. + struct ci_hdrc *ci = dev_get_drvdata(dev);
  207959. + int ret;
  207960. +
  207961. + if (device_may_wakeup(dev))
  207962. + disable_irq_wake(ci->irq);
  207963. +
  207964. + ret = ci_controller_resume(dev);
  207965. + if (!ret && ci->supports_runtime_pm) {
  207966. + pm_runtime_disable(dev);
  207967. + pm_runtime_set_active(dev);
  207968. + pm_runtime_enable(dev);
  207969. + }
  207970. +
  207971. + return ret;
  207972. +}
  207973. +#endif /* CONFIG_PM_SLEEP */
  207974. +
  207975. +#ifdef CONFIG_PM_RUNTIME
  207976. +static int ci_runtime_suspend(struct device *dev)
  207977. +{
  207978. + return ci_controller_suspend(dev);
  207979. +}
  207980. +
  207981. +static int ci_runtime_resume(struct device *dev)
  207982. +{
  207983. + return ci_controller_resume(dev);
  207984. +}
  207985. +#endif /* CONFIG_PM_RUNTIME */
  207986. +
  207987. +#endif /* CONFIG_PM */
  207988. +static const struct dev_pm_ops ci_pm_ops = {
  207989. + SET_SYSTEM_SLEEP_PM_OPS(ci_suspend, ci_resume)
  207990. + SET_RUNTIME_PM_OPS(ci_runtime_suspend, ci_runtime_resume, NULL)
  207991. +};
  207992. +
  207993. static struct platform_driver ci_hdrc_driver = {
  207994. .probe = ci_hdrc_probe,
  207995. .remove = ci_hdrc_remove,
  207996. .driver = {
  207997. .name = "ci_hdrc",
  207998. + .pm = &ci_pm_ops,
  207999. },
  208000. };
  208001. diff -Nur linux-3.14.17/drivers/usb/chipidea/host.c linux-imx6-3.14/drivers/usb/chipidea/host.c
  208002. --- linux-3.14.17/drivers/usb/chipidea/host.c 2014-08-14 03:38:34.000000000 +0200
  208003. +++ linux-imx6-3.14/drivers/usb/chipidea/host.c 2014-09-11 18:06:09.078066233 +0200
  208004. @@ -33,6 +33,176 @@
  208005. #include "host.h"
  208006. static struct hc_driver __read_mostly ci_ehci_hc_driver;
  208007. +static int (*orig_bus_suspend)(struct usb_hcd *hcd);
  208008. +static int (*orig_bus_resume)(struct usb_hcd *hcd);
  208009. +static int (*orig_hub_control)(struct usb_hcd *hcd,
  208010. + u16 typeReq, u16 wValue, u16 wIndex,
  208011. + char *buf, u16 wLength);
  208012. +
  208013. +static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
  208014. +{
  208015. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  208016. + int port;
  208017. + u32 tmp;
  208018. +
  208019. + int ret = orig_bus_suspend(hcd);
  208020. +
  208021. + if (ret)
  208022. + return ret;
  208023. +
  208024. + port = HCS_N_PORTS(ehci->hcs_params);
  208025. + while (port--) {
  208026. + u32 __iomem *reg = &ehci->regs->port_status[port];
  208027. + u32 portsc = ehci_readl(ehci, reg);
  208028. +
  208029. + if (portsc & PORT_CONNECT) {
  208030. + /*
  208031. + * For chipidea, the resume signal will be ended
  208032. + * automatically, so for remote wakeup case, the
  208033. + * usbcmd.rs may not be set before the resume has
  208034. + * ended if other resume path consumes too much
  208035. + * time (~23ms-24ms), in that case, the SOF will not
  208036. + * send out within 3ms after resume ends, then the
  208037. + * device will enter suspend again.
  208038. + */
  208039. + if (hcd->self.root_hub->do_remote_wakeup) {
  208040. + ehci_dbg(ehci,
  208041. + "Remote wakeup is enabled, "
  208042. + "and device is on the port\n");
  208043. +
  208044. + tmp = ehci_readl(ehci, &ehci->regs->command);
  208045. + tmp |= CMD_RUN;
  208046. + ehci_writel(ehci, tmp, &ehci->regs->command);
  208047. + /*
  208048. + * It needs a short delay between set RUNSTOP
  208049. + * and set PHCD.
  208050. + */
  208051. + udelay(125);
  208052. + }
  208053. + if (hcd->phy && test_bit(port, &ehci->bus_suspended)
  208054. + && (ehci_port_speed(ehci, portsc) ==
  208055. + USB_PORT_STAT_HIGH_SPEED))
  208056. + /*
  208057. + * notify the USB PHY, it is for global
  208058. + * suspend case.
  208059. + */
  208060. + usb_phy_notify_suspend(hcd->phy,
  208061. + USB_SPEED_HIGH);
  208062. + }
  208063. + }
  208064. +
  208065. + return 0;
  208066. +}
  208067. +
  208068. +static int ci_imx_ehci_bus_resume(struct usb_hcd *hcd)
  208069. +{
  208070. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  208071. + int port;
  208072. +
  208073. + int ret = orig_bus_resume(hcd);
  208074. +
  208075. + if (ret)
  208076. + return ret;
  208077. +
  208078. + port = HCS_N_PORTS(ehci->hcs_params);
  208079. + while (port--) {
  208080. + u32 __iomem *reg = &ehci->regs->port_status[port];
  208081. + u32 portsc = ehci_readl(ehci, reg);
  208082. + /*
  208083. + * Notify PHY after resume signal has finished, it is
  208084. + * for global suspend case.
  208085. + */
  208086. + if (hcd->phy
  208087. + && test_bit(port, &ehci->bus_suspended)
  208088. + && (portsc & PORT_CONNECT)
  208089. + && (ehci_port_speed(ehci, portsc) ==
  208090. + USB_PORT_STAT_HIGH_SPEED))
  208091. + /* notify the USB PHY */
  208092. + usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
  208093. + }
  208094. +
  208095. + return 0;
  208096. +}
  208097. +
  208098. +/* The below code is based on tegra ehci driver */
  208099. +static int ci_imx_ehci_hub_control(
  208100. + struct usb_hcd *hcd,
  208101. + u16 typeReq,
  208102. + u16 wValue,
  208103. + u16 wIndex,
  208104. + char *buf,
  208105. + u16 wLength
  208106. +)
  208107. +{
  208108. + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
  208109. + u32 __iomem *status_reg;
  208110. + u32 temp;
  208111. + unsigned long flags;
  208112. + int retval = 0;
  208113. +
  208114. + status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
  208115. +
  208116. + spin_lock_irqsave(&ehci->lock, flags);
  208117. +
  208118. + if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
  208119. + temp = ehci_readl(ehci, status_reg);
  208120. + if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
  208121. + retval = -EPIPE;
  208122. + goto done;
  208123. + }
  208124. +
  208125. + temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
  208126. + temp |= PORT_WKDISC_E | PORT_WKOC_E;
  208127. + ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
  208128. +
  208129. + /*
  208130. + * If a transaction is in progress, there may be a delay in
  208131. + * suspending the port. Poll until the port is suspended.
  208132. + */
  208133. + if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
  208134. + PORT_SUSPEND, 5000))
  208135. + ehci_err(ehci, "timeout waiting for SUSPEND\n");
  208136. +
  208137. + spin_unlock_irqrestore(&ehci->lock, flags);
  208138. + if (ehci_port_speed(ehci, temp) ==
  208139. + USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
  208140. + /* notify the USB PHY */
  208141. + usb_phy_notify_suspend(hcd->phy, USB_SPEED_HIGH);
  208142. + }
  208143. + spin_lock_irqsave(&ehci->lock, flags);
  208144. +
  208145. + set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
  208146. + goto done;
  208147. + }
  208148. +
  208149. + /*
  208150. + * After resume has finished, it needs do some post resume
  208151. + * operation for some SoCs.
  208152. + */
  208153. + else if (typeReq == ClearPortFeature &&
  208154. + wValue == USB_PORT_FEAT_C_SUSPEND) {
  208155. +
  208156. + /* Make sure the resume has finished, it should be finished */
  208157. + if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
  208158. + ehci_err(ehci, "timeout waiting for resume\n");
  208159. +
  208160. + temp = ehci_readl(ehci, status_reg);
  208161. +
  208162. + if (ehci_port_speed(ehci, temp) ==
  208163. + USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
  208164. + /* notify the USB PHY */
  208165. + usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
  208166. + }
  208167. + }
  208168. +
  208169. + spin_unlock_irqrestore(&ehci->lock, flags);
  208170. +
  208171. + /* Handle the hub control events here */
  208172. + return orig_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
  208173. +done:
  208174. + spin_unlock_irqrestore(&ehci->lock, flags);
  208175. + return retval;
  208176. +}
  208177. static irqreturn_t host_irq(struct ci_hdrc *ci)
  208178. {
  208179. @@ -64,7 +234,6 @@
  208180. ehci = hcd_to_ehci(hcd);
  208181. ehci->caps = ci->hw_bank.cap;
  208182. ehci->has_hostpc = ci->hw_bank.lpm;
  208183. - ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
  208184. ehci->imx28_write_fix = ci->imx28_write_fix;
  208185. if (ci->platdata->reg_vbus) {
  208186. @@ -136,5 +305,15 @@
  208187. ehci_init_driver(&ci_ehci_hc_driver, NULL);
  208188. + orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
  208189. + orig_bus_resume = ci_ehci_hc_driver.bus_resume;
  208190. + orig_hub_control = ci_ehci_hc_driver.hub_control;
  208191. +
  208192. + ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
  208193. + if (ci->platdata->flags & CI_HDRC_IMX_EHCI_QUIRK) {
  208194. + ci_ehci_hc_driver.bus_resume = ci_imx_ehci_bus_resume;
  208195. + ci_ehci_hc_driver.hub_control = ci_imx_ehci_hub_control;
  208196. + }
  208197. +
  208198. return 0;
  208199. }
  208200. diff -Nur linux-3.14.17/drivers/usb/chipidea/otg.c linux-imx6-3.14/drivers/usb/chipidea/otg.c
  208201. --- linux-3.14.17/drivers/usb/chipidea/otg.c 2014-08-14 03:38:34.000000000 +0200
  208202. +++ linux-imx6-3.14/drivers/usb/chipidea/otg.c 2014-09-11 18:06:09.078066233 +0200
  208203. @@ -18,6 +18,8 @@
  208204. #include <linux/usb/otg.h>
  208205. #include <linux/usb/gadget.h>
  208206. #include <linux/usb/chipidea.h>
  208207. +#include <linux/kthread.h>
  208208. +#include <linux/freezer.h>
  208209. #include "ci.h"
  208210. #include "bits.h"
  208211. @@ -68,26 +70,53 @@
  208212. ci_role_start(ci, role);
  208213. }
  208214. }
  208215. +
  208216. +/* If there is pending otg event */
  208217. +static inline bool ci_otg_event_is_pending(struct ci_hdrc *ci)
  208218. +{
  208219. + return ci->id_event || ci->b_sess_valid_event;
  208220. +}
  208221. +
  208222. /**
  208223. - * ci_otg_work - perform otg (vbus/id) event handle
  208224. - * @work: work struct
  208225. + * ci_otg_event - perform otg (vbus/id) event handle
  208226. + * @ci: ci_hdrc struct
  208227. */
  208228. -static void ci_otg_work(struct work_struct *work)
  208229. +static void ci_otg_event(struct ci_hdrc *ci)
  208230. {
  208231. - struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work);
  208232. -
  208233. if (ci->id_event) {
  208234. ci->id_event = false;
  208235. + /* Keep controller active during id switch */
  208236. + pm_runtime_get_sync(ci->dev);
  208237. ci_handle_id_switch(ci);
  208238. + pm_runtime_put_sync(ci->dev);
  208239. } else if (ci->b_sess_valid_event) {
  208240. ci->b_sess_valid_event = false;
  208241. + pm_runtime_get_sync(ci->dev);
  208242. ci_handle_vbus_change(ci);
  208243. + pm_runtime_put_sync(ci->dev);
  208244. } else
  208245. - dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
  208246. + dev_dbg(ci->dev, "it should be quit event\n");
  208247. enable_irq(ci->irq);
  208248. }
  208249. +static int ci_otg_thread(void *ptr)
  208250. +{
  208251. + struct ci_hdrc *ci = ptr;
  208252. +
  208253. + set_freezable();
  208254. +
  208255. + do {
  208256. + wait_event_freezable(ci->otg_wait,
  208257. + ci_otg_event_is_pending(ci) ||
  208258. + kthread_should_stop());
  208259. + ci_otg_event(ci);
  208260. + } while (!kthread_should_stop());
  208261. +
  208262. + dev_warn(ci->dev, "ci_otg_thread quits\n");
  208263. +
  208264. + return 0;
  208265. +}
  208266. /**
  208267. * ci_hdrc_otg_init - initialize otg struct
  208268. @@ -95,11 +124,11 @@
  208269. */
  208270. int ci_hdrc_otg_init(struct ci_hdrc *ci)
  208271. {
  208272. - INIT_WORK(&ci->work, ci_otg_work);
  208273. - ci->wq = create_singlethread_workqueue("ci_otg");
  208274. - if (!ci->wq) {
  208275. - dev_err(ci->dev, "can't create workqueue\n");
  208276. - return -ENODEV;
  208277. + init_waitqueue_head(&ci->otg_wait);
  208278. + ci->otg_task = kthread_run(ci_otg_thread, ci, "ci otg thread");
  208279. + if (IS_ERR(ci->otg_task)) {
  208280. + dev_err(ci->dev, "error to create otg thread\n");
  208281. + return PTR_ERR(ci->otg_task);
  208282. }
  208283. return 0;
  208284. @@ -111,10 +140,7 @@
  208285. */
  208286. void ci_hdrc_otg_destroy(struct ci_hdrc *ci)
  208287. {
  208288. - if (ci->wq) {
  208289. - flush_workqueue(ci->wq);
  208290. - destroy_workqueue(ci->wq);
  208291. - }
  208292. + kthread_stop(ci->otg_task);
  208293. ci_disable_otg_interrupt(ci, OTGSC_INT_EN_BITS);
  208294. ci_clear_otg_interrupt(ci, OTGSC_INT_STATUS_BITS);
  208295. }
  208296. diff -Nur linux-3.14.17/drivers/usb/chipidea/udc.c linux-imx6-3.14/drivers/usb/chipidea/udc.c
  208297. --- linux-3.14.17/drivers/usb/chipidea/udc.c 2014-08-14 03:38:34.000000000 +0200
  208298. +++ linux-imx6-3.14/drivers/usb/chipidea/udc.c 2014-09-11 18:06:09.134066455 +0200
  208299. @@ -681,12 +681,6 @@
  208300. struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
  208301. unsigned long flags;
  208302. - spin_lock_irqsave(&ci->lock, flags);
  208303. - ci->gadget.speed = USB_SPEED_UNKNOWN;
  208304. - ci->remote_wakeup = 0;
  208305. - ci->suspended = 0;
  208306. - spin_unlock_irqrestore(&ci->lock, flags);
  208307. -
  208308. /* flush all endpoints */
  208309. gadget_for_each_ep(ep, gadget) {
  208310. usb_ep_fifo_flush(ep);
  208311. @@ -704,6 +698,12 @@
  208312. ci->status = NULL;
  208313. }
  208314. + spin_lock_irqsave(&ci->lock, flags);
  208315. + ci->gadget.speed = USB_SPEED_UNKNOWN;
  208316. + ci->remote_wakeup = 0;
  208317. + ci->suspended = 0;
  208318. + spin_unlock_irqrestore(&ci->lock, flags);
  208319. +
  208320. return 0;
  208321. }
  208322. @@ -1222,6 +1222,10 @@
  208323. return -EBUSY;
  208324. spin_lock_irqsave(hwep->lock, flags);
  208325. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  208326. + spin_unlock_irqrestore(hwep->lock, flags);
  208327. + return 0;
  208328. + }
  208329. /* only internal SW should disable ctrl endpts */
  208330. @@ -1311,6 +1315,10 @@
  208331. return -EINVAL;
  208332. spin_lock_irqsave(hwep->lock, flags);
  208333. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  208334. + spin_unlock_irqrestore(hwep->lock, flags);
  208335. + return 0;
  208336. + }
  208337. retval = _ep_queue(ep, req, gfp_flags);
  208338. spin_unlock_irqrestore(hwep->lock, flags);
  208339. return retval;
  208340. @@ -1334,8 +1342,8 @@
  208341. return -EINVAL;
  208342. spin_lock_irqsave(hwep->lock, flags);
  208343. -
  208344. - hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  208345. + if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN)
  208346. + hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  208347. list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) {
  208348. dma_pool_free(hwep->td_pool, node->ptr, node->dma);
  208349. @@ -1379,6 +1387,10 @@
  208350. spin_lock_irqsave(hwep->lock, flags);
  208351. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  208352. + spin_unlock_irqrestore(hwep->lock, flags);
  208353. + return 0;
  208354. + }
  208355. #ifndef STALL_IN
  208356. /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
  208357. if (value && hwep->type == USB_ENDPOINT_XFER_BULK && hwep->dir == TX &&
  208358. @@ -1440,6 +1452,10 @@
  208359. }
  208360. spin_lock_irqsave(hwep->lock, flags);
  208361. + if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
  208362. + spin_unlock_irqrestore(hwep->lock, flags);
  208363. + return;
  208364. + }
  208365. hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
  208366. @@ -1506,6 +1522,10 @@
  208367. int ret = 0;
  208368. spin_lock_irqsave(&ci->lock, flags);
  208369. + if (ci->gadget.speed == USB_SPEED_UNKNOWN) {
  208370. + spin_unlock_irqrestore(&ci->lock, flags);
  208371. + return 0;
  208372. + }
  208373. if (!ci->remote_wakeup) {
  208374. ret = -EOPNOTSUPP;
  208375. goto out;
  208376. diff -Nur linux-3.14.17/drivers/usb/chipidea/usbmisc_imx.c linux-imx6-3.14/drivers/usb/chipidea/usbmisc_imx.c
  208377. --- linux-3.14.17/drivers/usb/chipidea/usbmisc_imx.c 2014-08-14 03:38:34.000000000 +0200
  208378. +++ linux-imx6-3.14/drivers/usb/chipidea/usbmisc_imx.c 2014-09-11 18:06:09.134066455 +0200
  208379. @@ -1,5 +1,5 @@
  208380. /*
  208381. - * Copyright 2012 Freescale Semiconductor, Inc.
  208382. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  208383. *
  208384. * The code contained herein is licensed under the GNU General Public
  208385. * License. You may obtain a copy of the GNU General Public License
  208386. @@ -11,10 +11,10 @@
  208387. #include <linux/module.h>
  208388. #include <linux/of_platform.h>
  208389. -#include <linux/clk.h>
  208390. #include <linux/err.h>
  208391. #include <linux/io.h>
  208392. #include <linux/delay.h>
  208393. +#include <linux/regulator/consumer.h>
  208394. #include "ci_hdrc_imx.h"
  208395. @@ -33,22 +33,28 @@
  208396. #define MX53_BM_OVER_CUR_DIS_UHx BIT(30)
  208397. #define MX6_BM_OVER_CUR_DIS BIT(7)
  208398. +#define MX6_BM_WAKEUP_ENABLE BIT(10)
  208399. +#define MX6_BM_ID_WAKEUP BIT(16)
  208400. +#define MX6_BM_VBUS_WAKEUP BIT(17)
  208401. +#define MX6_BM_WAKEUP_INTR BIT(31)
  208402. struct usbmisc_ops {
  208403. /* It's called once when probe a usb device */
  208404. int (*init)(struct imx_usbmisc_data *data);
  208405. /* It's called once after adding a usb device */
  208406. int (*post)(struct imx_usbmisc_data *data);
  208407. + /* It's called when we need to enable usb wakeup */
  208408. + int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
  208409. };
  208410. struct imx_usbmisc {
  208411. void __iomem *base;
  208412. spinlock_t lock;
  208413. - struct clk *clk;
  208414. const struct usbmisc_ops *ops;
  208415. };
  208416. static struct imx_usbmisc *usbmisc;
  208417. +static struct regulator *vbus_wakeup_reg;
  208418. static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
  208419. {
  208420. @@ -158,6 +164,47 @@
  208421. return 0;
  208422. }
  208423. +static u32 imx6q_finalize_wakeup_setting(struct imx_usbmisc_data *data)
  208424. +{
  208425. + if (data->available_role == USB_DR_MODE_PERIPHERAL)
  208426. + return MX6_BM_VBUS_WAKEUP;
  208427. + else if (data->available_role == USB_DR_MODE_OTG)
  208428. + return MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP;
  208429. +
  208430. + return 0;
  208431. +}
  208432. +
  208433. +static int usbmisc_imx6q_set_wakeup
  208434. + (struct imx_usbmisc_data *data, bool enabled)
  208435. +{
  208436. + unsigned long flags;
  208437. + u32 reg, val = MX6_BM_WAKEUP_ENABLE;
  208438. + int ret = 0;
  208439. +
  208440. + if (data->index > 3)
  208441. + return -EINVAL;
  208442. +
  208443. + spin_lock_irqsave(&usbmisc->lock, flags);
  208444. + reg = readl(usbmisc->base + data->index * 4);
  208445. + if (enabled) {
  208446. + val |= imx6q_finalize_wakeup_setting(data);
  208447. + writel(reg | val, usbmisc->base + data->index * 4);
  208448. + if (vbus_wakeup_reg)
  208449. + ret = regulator_enable(vbus_wakeup_reg);
  208450. + } else {
  208451. + if (reg & MX6_BM_WAKEUP_INTR)
  208452. + pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
  208453. + val = MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP
  208454. + | MX6_BM_ID_WAKEUP;
  208455. + writel(reg & ~val, usbmisc->base + data->index * 4);
  208456. + if (vbus_wakeup_reg && regulator_is_enabled(vbus_wakeup_reg))
  208457. + regulator_disable(vbus_wakeup_reg);
  208458. + }
  208459. + spin_unlock_irqrestore(&usbmisc->lock, flags);
  208460. +
  208461. + return ret;
  208462. +}
  208463. +
  208464. static const struct usbmisc_ops imx25_usbmisc_ops = {
  208465. .post = usbmisc_imx25_post,
  208466. };
  208467. @@ -172,6 +219,7 @@
  208468. static const struct usbmisc_ops imx6q_usbmisc_ops = {
  208469. .init = usbmisc_imx6q_init,
  208470. + .set_wakeup = usbmisc_imx6q_set_wakeup,
  208471. };
  208472. int imx_usbmisc_init(struct imx_usbmisc_data *data)
  208473. @@ -194,6 +242,16 @@
  208474. }
  208475. EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
  208476. +int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
  208477. +{
  208478. + if (!usbmisc)
  208479. + return -ENODEV;
  208480. + if (!usbmisc->ops->set_wakeup)
  208481. + return 0;
  208482. + return usbmisc->ops->set_wakeup(data, enabled);
  208483. +}
  208484. +EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup);
  208485. +
  208486. static const struct of_device_id usbmisc_imx_dt_ids[] = {
  208487. {
  208488. .compatible = "fsl,imx25-usbmisc",
  208489. @@ -223,7 +281,6 @@
  208490. {
  208491. struct resource *res;
  208492. struct imx_usbmisc *data;
  208493. - int ret;
  208494. struct of_device_id *tmp_dev;
  208495. if (usbmisc)
  208496. @@ -240,31 +297,28 @@
  208497. if (IS_ERR(data->base))
  208498. return PTR_ERR(data->base);
  208499. - data->clk = devm_clk_get(&pdev->dev, NULL);
  208500. - if (IS_ERR(data->clk)) {
  208501. - dev_err(&pdev->dev,
  208502. - "failed to get clock, err=%ld\n", PTR_ERR(data->clk));
  208503. - return PTR_ERR(data->clk);
  208504. - }
  208505. -
  208506. - ret = clk_prepare_enable(data->clk);
  208507. - if (ret) {
  208508. - dev_err(&pdev->dev,
  208509. - "clk_prepare_enable failed, err=%d\n", ret);
  208510. - return ret;
  208511. - }
  208512. -
  208513. tmp_dev = (struct of_device_id *)
  208514. of_match_device(usbmisc_imx_dt_ids, &pdev->dev);
  208515. data->ops = (const struct usbmisc_ops *)tmp_dev->data;
  208516. usbmisc = data;
  208517. + vbus_wakeup_reg = devm_regulator_get(&pdev->dev, "vbus-wakeup");
  208518. + if (PTR_ERR(vbus_wakeup_reg) == -EPROBE_DEFER)
  208519. + return -EPROBE_DEFER;
  208520. + else if (PTR_ERR(vbus_wakeup_reg) == -ENODEV)
  208521. + /* no vbus regualator is needed */
  208522. + vbus_wakeup_reg = NULL;
  208523. + else if (IS_ERR(vbus_wakeup_reg)) {
  208524. + dev_err(&pdev->dev, "Getting regulator error: %ld\n",
  208525. + PTR_ERR(vbus_wakeup_reg));
  208526. + return PTR_ERR(vbus_wakeup_reg);
  208527. + }
  208528. +
  208529. return 0;
  208530. }
  208531. static int usbmisc_imx_remove(struct platform_device *pdev)
  208532. {
  208533. - clk_disable_unprepare(usbmisc->clk);
  208534. usbmisc = NULL;
  208535. return 0;
  208536. }
  208537. diff -Nur linux-3.14.17/drivers/usb/core/hub.c linux-imx6-3.14/drivers/usb/core/hub.c
  208538. --- linux-3.14.17/drivers/usb/core/hub.c 2014-08-14 03:38:34.000000000 +0200
  208539. +++ linux-imx6-3.14/drivers/usb/core/hub.c 2014-09-11 18:06:09.138066472 +0200
  208540. @@ -3867,6 +3867,12 @@
  208541. void usb_enable_ltm(struct usb_device *udev) { }
  208542. EXPORT_SYMBOL_GPL(usb_enable_ltm);
  208543. +static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
  208544. + u16 portstatus, u16 portchange)
  208545. +{
  208546. + return 0;
  208547. +}
  208548. +
  208549. #endif /* CONFIG_PM */
  208550. @@ -4460,8 +4466,7 @@
  208551. /* Disconnect any existing devices under this port */
  208552. if (udev) {
  208553. - if (hcd->phy && !hdev->parent &&
  208554. - !(portstatus & USB_PORT_STAT_CONNECTION))
  208555. + if (hcd->phy && !hdev->parent)
  208556. usb_phy_notify_disconnect(hcd->phy, udev->speed);
  208557. usb_disconnect(&hub->ports[port1 - 1]->child);
  208558. }
  208559. diff -Nur linux-3.14.17/drivers/usb/core/message.c linux-imx6-3.14/drivers/usb/core/message.c
  208560. --- linux-3.14.17/drivers/usb/core/message.c 2014-08-14 03:38:34.000000000 +0200
  208561. +++ linux-imx6-3.14/drivers/usb/core/message.c 2014-09-11 18:06:09.138066472 +0200
  208562. @@ -178,7 +178,7 @@
  208563. *
  208564. * Return:
  208565. * If successful, 0. Otherwise a negative error number. The number of actual
  208566. - * bytes transferred will be stored in the @actual_length paramater.
  208567. + * bytes transferred will be stored in the @actual_length parameter.
  208568. */
  208569. int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
  208570. void *data, int len, int *actual_length, int timeout)
  208571. diff -Nur linux-3.14.17/drivers/usb/core/urb.c linux-imx6-3.14/drivers/usb/core/urb.c
  208572. --- linux-3.14.17/drivers/usb/core/urb.c 2014-08-14 03:38:34.000000000 +0200
  208573. +++ linux-imx6-3.14/drivers/usb/core/urb.c 2014-09-11 18:06:09.142066489 +0200
  208574. @@ -831,7 +831,7 @@
  208575. *
  208576. * this allows all outstanding URBs to be unlinked starting
  208577. * from the back of the queue. This function is asynchronous.
  208578. - * The unlinking is just tiggered. It may happen after this
  208579. + * The unlinking is just triggered. It may happen after this
  208580. * function has returned.
  208581. *
  208582. * This routine should not be called by a driver after its disconnect
  208583. diff -Nur linux-3.14.17/drivers/usb/gadget/f_mass_storage.c linux-imx6-3.14/drivers/usb/gadget/f_mass_storage.c
  208584. --- linux-3.14.17/drivers/usb/gadget/f_mass_storage.c 2014-08-14 03:38:34.000000000 +0200
  208585. +++ linux-imx6-3.14/drivers/usb/gadget/f_mass_storage.c 2014-09-11 18:06:09.154066537 +0200
  208586. @@ -336,8 +336,15 @@
  208587. struct usb_ep *bulk_in;
  208588. struct usb_ep *bulk_out;
  208589. +#ifdef CONFIG_FSL_UTP
  208590. + void *utp;
  208591. +#endif
  208592. };
  208593. +#ifdef CONFIG_FSL_UTP
  208594. +#include "fsl_updater.h"
  208595. +#endif
  208596. +
  208597. static inline int __fsg_is_set(struct fsg_common *common,
  208598. const char *func, unsigned line)
  208599. {
  208600. @@ -1131,6 +1138,13 @@
  208601. }
  208602. #endif
  208603. +#ifdef CONFIG_FSL_UTP
  208604. + if (utp_get_sense(common->fsg) == 0) { /* got the sense from the UTP */
  208605. + sd = UTP_CTX(common->fsg)->sd;
  208606. + sdinfo = UTP_CTX(common->fsg)->sdinfo;
  208607. + valid = 0;
  208608. + } else
  208609. +#endif
  208610. if (!curlun) { /* Unsupported LUNs are okay */
  208611. common->bad_lun_okay = 1;
  208612. sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
  208613. @@ -1152,6 +1166,9 @@
  208614. buf[7] = 18 - 8; /* Additional sense length */
  208615. buf[12] = ASC(sd);
  208616. buf[13] = ASCQ(sd);
  208617. +#ifdef CONFIG_FSL_UTP
  208618. + put_unaligned_be32(UTP_CTX(common->fsg)->sdinfo_h, &buf[8]);
  208619. +#endif
  208620. return 18;
  208621. }
  208622. @@ -1645,7 +1662,18 @@
  208623. sd = SS_INVALID_COMMAND;
  208624. } else if (sd != SS_NO_SENSE) {
  208625. DBG(common, "sending command-failure status\n");
  208626. +#ifdef CONFIG_FSL_UTP
  208627. +/*
  208628. + * mfgtool host frequently reset bus during transfer
  208629. + * - the response in csw to request sense will be 1 due to UTP change
  208630. + * some storage information
  208631. + * - host will reset the bus if response to request sense is 1
  208632. + * - change the response to 0 if CONFIG_FSL_UTP is defined
  208633. + */
  208634. + status = US_BULK_STAT_OK;
  208635. +#else
  208636. status = US_BULK_STAT_FAIL;
  208637. +#endif
  208638. VDBG(common, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
  208639. " info x%x\n",
  208640. SK(sd), ASC(sd), ASCQ(sd), sdinfo);
  208641. @@ -1836,6 +1864,13 @@
  208642. common->phase_error = 0;
  208643. common->short_packet_received = 0;
  208644. +#ifdef CONFIG_FSL_UTP
  208645. + reply = utp_handle_message(common->fsg, common->cmnd, reply);
  208646. +
  208647. + if (reply != -EINVAL)
  208648. + return reply;
  208649. +#endif
  208650. +
  208651. down_read(&common->filesem); /* We're using the backing file */
  208652. switch (common->cmnd[0]) {
  208653. @@ -2502,12 +2537,14 @@
  208654. /* Allow the thread to be frozen */
  208655. set_freezable();
  208656. +#ifndef CONFIG_FSL_UTP
  208657. /*
  208658. * Arrange for userspace references to be interpreted as kernel
  208659. * pointers. That way we can pass a kernel pointer to a routine
  208660. * that expects a __user pointer and it will work okay.
  208661. */
  208662. set_fs(get_ds());
  208663. +#endif
  208664. /* The main loop */
  208665. while (common->state != FSG_STATE_TERMINATED) {
  208666. @@ -3096,6 +3133,10 @@
  208667. /*-------------------------------------------------------------------------*/
  208668. +#ifdef CONFIG_FSL_UTP
  208669. +#include "fsl_updater.c"
  208670. +#endif
  208671. +
  208672. static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
  208673. {
  208674. struct fsg_dev *fsg = fsg_from_func(f);
  208675. @@ -3127,6 +3168,10 @@
  208676. fsg_intf_desc.bInterfaceNumber = i;
  208677. fsg->interface_number = i;
  208678. +#ifdef CONFIG_FSL_UTP
  208679. + utp_init(fsg);
  208680. +#endif
  208681. +
  208682. /* Find all the endpoints we will use */
  208683. ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
  208684. if (!ep)
  208685. @@ -3185,6 +3230,10 @@
  208686. }
  208687. usb_free_all_descriptors(&fsg->function);
  208688. +
  208689. +#ifdef CONFIG_FSL_UTP
  208690. + utp_exit(fsg);
  208691. +#endif
  208692. }
  208693. static inline struct fsg_lun_opts *to_fsg_lun_opts(struct config_item *item)
  208694. diff -Nur linux-3.14.17/drivers/usb/gadget/fsl_updater.c linux-imx6-3.14/drivers/usb/gadget/fsl_updater.c
  208695. --- linux-3.14.17/drivers/usb/gadget/fsl_updater.c 1970-01-01 01:00:00.000000000 +0100
  208696. +++ linux-imx6-3.14/drivers/usb/gadget/fsl_updater.c 2014-09-11 18:06:09.158066553 +0200
  208697. @@ -0,0 +1,594 @@
  208698. +/*
  208699. + * Freescale UUT driver
  208700. + *
  208701. + * Copyright 2008-2013 Freescale Semiconductor, Inc.
  208702. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  208703. + */
  208704. +
  208705. +/*
  208706. + * The code contained herein is licensed under the GNU General Public
  208707. + * License. You may obtain a copy of the GNU General Public License
  208708. + * Version 2 or later at the following locations:
  208709. + *
  208710. + * http://www.opensource.org/licenses/gpl-license.html
  208711. + * http://www.gnu.org/copyleft/gpl.html
  208712. + */
  208713. +
  208714. +static u64 get_be64(u8 *buf)
  208715. +{
  208716. + return ((u64)get_unaligned_be32(buf) << 32) |
  208717. + get_unaligned_be32(buf + 4);
  208718. +}
  208719. +
  208720. +static int utp_init(struct fsg_dev *fsg)
  208721. +{
  208722. + init_waitqueue_head(&utp_context.wq);
  208723. + init_waitqueue_head(&utp_context.list_full_wq);
  208724. +
  208725. + INIT_LIST_HEAD(&utp_context.read);
  208726. + INIT_LIST_HEAD(&utp_context.write);
  208727. + mutex_init(&utp_context.lock);
  208728. +
  208729. + /* the max message is 64KB */
  208730. + utp_context.buffer = vmalloc(0x10000);
  208731. + if (!utp_context.buffer)
  208732. + return -EIO;
  208733. + utp_context.utp_version = 0x1ull;
  208734. + fsg->utp = &utp_context;
  208735. + return misc_register(&utp_dev);
  208736. +}
  208737. +
  208738. +static void utp_exit(struct fsg_dev *fsg)
  208739. +{
  208740. + vfree(utp_context.buffer);
  208741. + misc_deregister(&utp_dev);
  208742. +}
  208743. +
  208744. +static struct utp_user_data *utp_user_data_alloc(size_t size)
  208745. +{
  208746. + struct utp_user_data *uud;
  208747. +
  208748. + uud = vmalloc(size + sizeof(*uud));
  208749. + if (!uud)
  208750. + return uud;
  208751. + memset(uud, 0, size + sizeof(*uud));
  208752. + uud->data.size = size + sizeof(uud->data);
  208753. + INIT_LIST_HEAD(&uud->link);
  208754. + return uud;
  208755. +}
  208756. +
  208757. +static void utp_user_data_free(struct utp_user_data *uud)
  208758. +{
  208759. + mutex_lock(&utp_context.lock);
  208760. + list_del(&uud->link);
  208761. + mutex_unlock(&utp_context.lock);
  208762. + vfree(uud);
  208763. +}
  208764. +
  208765. +/* Get the number of element for list */
  208766. +static u32 count_list(struct list_head *l)
  208767. +{
  208768. + u32 count = 0;
  208769. + struct list_head *tmp;
  208770. +
  208771. + mutex_lock(&utp_context.lock);
  208772. + list_for_each(tmp, l) {
  208773. + count++;
  208774. + }
  208775. + mutex_unlock(&utp_context.lock);
  208776. +
  208777. + return count;
  208778. +}
  208779. +/* The routine will not go on if utp_context.queue is empty */
  208780. +#define WAIT_ACTIVITY(queue) \
  208781. + wait_event_interruptible(utp_context.wq, !list_empty(&utp_context.queue))
  208782. +
  208783. +/* Called by userspace program (uuc) */
  208784. +static ssize_t utp_file_read(struct file *file,
  208785. + char __user *buf,
  208786. + size_t size,
  208787. + loff_t *off)
  208788. +{
  208789. + struct utp_user_data *uud;
  208790. + size_t size_to_put;
  208791. + int free = 0;
  208792. +
  208793. + WAIT_ACTIVITY(read);
  208794. +
  208795. + mutex_lock(&utp_context.lock);
  208796. + uud = list_first_entry(&utp_context.read, struct utp_user_data, link);
  208797. + mutex_unlock(&utp_context.lock);
  208798. + size_to_put = uud->data.size;
  208799. +
  208800. + if (size >= size_to_put)
  208801. + free = !0;
  208802. + if (copy_to_user(buf, &uud->data, size_to_put)) {
  208803. + printk(KERN_INFO "[ %s ] copy error\n", __func__);
  208804. + return -EACCES;
  208805. + }
  208806. + if (free)
  208807. + utp_user_data_free(uud);
  208808. + else {
  208809. + pr_info("sizeof = %d, size = %d\n",
  208810. + sizeof(uud->data),
  208811. + uud->data.size);
  208812. +
  208813. + pr_err("Will not free utp_user_data, because buffer size = %d,"
  208814. + "need to put %d\n", size, size_to_put);
  208815. + }
  208816. +
  208817. + /*
  208818. + * The user program has already finished data process,
  208819. + * go on getting data from the host
  208820. + */
  208821. + wake_up(&utp_context.list_full_wq);
  208822. +
  208823. + return size_to_put;
  208824. +}
  208825. +
  208826. +static ssize_t utp_file_write(struct file *file, const char __user *buf,
  208827. + size_t size, loff_t *off)
  208828. +{
  208829. + struct utp_user_data *uud;
  208830. +
  208831. + if (size < sizeof(uud->data))
  208832. + return -EINVAL;
  208833. + uud = utp_user_data_alloc(size);
  208834. + if (uud == NULL)
  208835. + return -ENOMEM;
  208836. + if (copy_from_user(&uud->data, buf, size)) {
  208837. + printk(KERN_INFO "[ %s ] copy error!\n", __func__);
  208838. + vfree(uud);
  208839. + return -EACCES;
  208840. + }
  208841. + mutex_lock(&utp_context.lock);
  208842. + list_add_tail(&uud->link, &utp_context.write);
  208843. + /* Go on EXEC routine process */
  208844. + wake_up(&utp_context.wq);
  208845. + mutex_unlock(&utp_context.lock);
  208846. + return size;
  208847. +}
  208848. +
  208849. +/*
  208850. + * uuc should change to use soc bus infrastructure to soc information
  208851. + * /sys/devices/soc0/soc_id
  208852. + * this function can be removed.
  208853. + */
  208854. +static long
  208855. +utp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  208856. +{
  208857. + int cpu_id = 0;
  208858. +
  208859. + switch (cmd) {
  208860. + case UTP_GET_CPU_ID:
  208861. + return put_user(cpu_id, (int __user *)arg);
  208862. + default:
  208863. + return -ENOIOCTLCMD;
  208864. + }
  208865. +}
  208866. +
  208867. +/* Will be called when the host wants to get the sense data */
  208868. +static int utp_get_sense(struct fsg_dev *fsg)
  208869. +{
  208870. + if (UTP_CTX(fsg)->processed == 0)
  208871. + return -1;
  208872. +
  208873. + UTP_CTX(fsg)->processed = 0;
  208874. + return 0;
  208875. +}
  208876. +
  208877. +static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size)
  208878. +{
  208879. + struct fsg_buffhd *bh;
  208880. + int rc;
  208881. + u32 amount_left;
  208882. + unsigned int amount;
  208883. +
  208884. + /* Get the starting Logical Block Address and check that it's
  208885. + * not too big */
  208886. +
  208887. + amount_left = size;
  208888. + if (unlikely(amount_left == 0))
  208889. + return -EIO; /* No default reply*/
  208890. +
  208891. + pr_debug("%s: sending %d\n", __func__, size);
  208892. + for (;;) {
  208893. + /* Figure out how much we need to read:
  208894. + * Try to read the remaining amount.
  208895. + * But don't read more than the buffer size.
  208896. + * And don't try to read past the end of the file.
  208897. + * Finally, if we're not at a page boundary, don't read past
  208898. + * the next page.
  208899. + * If this means reading 0 then we were asked to read past
  208900. + * the end of file. */
  208901. + amount = min((unsigned int) amount_left, FSG_BUFLEN);
  208902. +
  208903. + /* Wait for the next buffer to become available */
  208904. + bh = fsg->common->next_buffhd_to_fill;
  208905. + while (bh->state != BUF_STATE_EMPTY) {
  208906. + rc = sleep_thread(fsg->common);
  208907. + if (rc)
  208908. + return rc;
  208909. + }
  208910. +
  208911. + /* If we were asked to read past the end of file,
  208912. + * end with an empty buffer. */
  208913. + if (amount == 0) {
  208914. + bh->inreq->length = 0;
  208915. + bh->state = BUF_STATE_FULL;
  208916. + break;
  208917. + }
  208918. +
  208919. + /* Perform the read */
  208920. + pr_info("Copied to %p, %d bytes started from %d\n",
  208921. + bh->buf, amount, size - amount_left);
  208922. + /* from upt buffer to file_storeage buffer */
  208923. + memcpy(bh->buf, data + size - amount_left, amount);
  208924. + amount_left -= amount;
  208925. + fsg->common->residue -= amount;
  208926. +
  208927. + bh->inreq->length = amount;
  208928. + bh->state = BUF_STATE_FULL;
  208929. +
  208930. + /* Send this buffer and go read some more */
  208931. + bh->inreq->zero = 0;
  208932. +
  208933. + /* USB Physical transfer: Data from device to host */
  208934. + start_transfer(fsg, fsg->bulk_in, bh->inreq,
  208935. + &bh->inreq_busy, &bh->state);
  208936. +
  208937. + fsg->common->next_buffhd_to_fill = bh->next;
  208938. +
  208939. + if (amount_left <= 0)
  208940. + break;
  208941. + }
  208942. +
  208943. + return size - amount_left;
  208944. +}
  208945. +
  208946. +static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size)
  208947. +{
  208948. + struct fsg_buffhd *bh;
  208949. + int get_some_more;
  208950. + u32 amount_left_to_req, amount_left_to_write;
  208951. + unsigned int amount;
  208952. + int rc;
  208953. + loff_t offset;
  208954. +
  208955. + /* Carry out the file writes */
  208956. + get_some_more = 1;
  208957. + amount_left_to_req = amount_left_to_write = size;
  208958. +
  208959. + if (unlikely(amount_left_to_write == 0))
  208960. + return -EIO;
  208961. +
  208962. + offset = 0;
  208963. + while (amount_left_to_write > 0) {
  208964. +
  208965. + /* Queue a request for more data from the host */
  208966. + bh = fsg->common->next_buffhd_to_fill;
  208967. + if (bh->state == BUF_STATE_EMPTY && get_some_more) {
  208968. +
  208969. + /* Figure out how much we want to get:
  208970. + * Try to get the remaining amount.
  208971. + * But don't get more than the buffer size.
  208972. + * And don't try to go past the end of the file.
  208973. + * If we're not at a page boundary,
  208974. + * don't go past the next page.
  208975. + * If this means getting 0, then we were asked
  208976. + * to write past the end of file.
  208977. + * Finally, round down to a block boundary. */
  208978. + amount = min(amount_left_to_req, FSG_BUFLEN);
  208979. +
  208980. + if (amount == 0) {
  208981. + get_some_more = 0;
  208982. + /* cry now */
  208983. + continue;
  208984. + }
  208985. +
  208986. + /* Get the next buffer */
  208987. + amount_left_to_req -= amount;
  208988. + if (amount_left_to_req == 0)
  208989. + get_some_more = 0;
  208990. +
  208991. + /* amount is always divisible by 512, hence by
  208992. + * the bulk-out maxpacket size */
  208993. + bh->outreq->length = bh->bulk_out_intended_length =
  208994. + amount;
  208995. + bh->outreq->short_not_ok = 1;
  208996. + start_transfer(fsg, fsg->bulk_out, bh->outreq,
  208997. + &bh->outreq_busy, &bh->state);
  208998. + fsg->common->next_buffhd_to_fill = bh->next;
  208999. + continue;
  209000. + }
  209001. +
  209002. + /* Write the received data to the backing file */
  209003. + bh = fsg->common->next_buffhd_to_drain;
  209004. + if (bh->state == BUF_STATE_EMPTY && !get_some_more)
  209005. + break; /* We stopped early */
  209006. + if (bh->state == BUF_STATE_FULL) {
  209007. + smp_rmb();
  209008. + fsg->common->next_buffhd_to_drain = bh->next;
  209009. + bh->state = BUF_STATE_EMPTY;
  209010. +
  209011. + /* Did something go wrong with the transfer? */
  209012. + if (bh->outreq->status != 0)
  209013. + /* cry again, COMMUNICATION_FAILURE */
  209014. + break;
  209015. +
  209016. + amount = bh->outreq->actual;
  209017. +
  209018. + /* Perform the write */
  209019. + memcpy(data + offset, bh->buf, amount);
  209020. +
  209021. + offset += amount;
  209022. + if (signal_pending(current))
  209023. + return -EINTR; /* Interrupted!*/
  209024. + amount_left_to_write -= amount;
  209025. + fsg->common->residue -= amount;
  209026. +
  209027. + /* Did the host decide to stop early? */
  209028. + if (bh->outreq->actual != bh->outreq->length) {
  209029. + fsg->common->short_packet_received = 1;
  209030. + break;
  209031. + }
  209032. + continue;
  209033. + }
  209034. +
  209035. + /* Wait for something to happen */
  209036. + rc = sleep_thread(fsg->common);
  209037. + if (rc)
  209038. + return rc;
  209039. + }
  209040. +
  209041. + return -EIO;
  209042. +}
  209043. +
  209044. +static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply)
  209045. +{
  209046. + UTP_CTX(fsg)->processed = true;
  209047. + UTP_CTX(fsg)->sdinfo = reply & 0xFFFFFFFF;
  209048. + UTP_CTX(fsg)->sdinfo_h = (reply >> 32) & 0xFFFFFFFF;
  209049. + UTP_CTX(fsg)->sd = (UTP_SENSE_KEY << 16) | code;
  209050. +}
  209051. +
  209052. +static void utp_poll(struct fsg_dev *fsg)
  209053. +{
  209054. + struct utp_context *ctx = UTP_CTX(fsg);
  209055. + struct utp_user_data *uud = NULL;
  209056. +
  209057. + mutex_lock(&ctx->lock);
  209058. + if (!list_empty(&ctx->write))
  209059. + uud = list_first_entry(&ctx->write, struct utp_user_data, link);
  209060. + mutex_unlock(&ctx->lock);
  209061. +
  209062. + if (uud) {
  209063. + if (uud->data.flags & UTP_FLAG_STATUS) {
  209064. + printk(KERN_WARNING "%s: exit with status %d\n",
  209065. + __func__, uud->data.status);
  209066. + UTP_SS_EXIT(fsg, uud->data.status);
  209067. + } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
  209068. + UTP_SS_BUSY(fsg, --ctx->counter);
  209069. + } else {
  209070. + printk("%s: pass returned.\n", __func__);
  209071. + UTP_SS_PASS(fsg);
  209072. + }
  209073. + utp_user_data_free(uud);
  209074. + } else {
  209075. + if (utp_context.cur_state & UTP_FLAG_DATA) {
  209076. + if (count_list(&ctx->read) < 7) {
  209077. + pr_debug("%s: pass returned in POLL stage. \n", __func__);
  209078. + UTP_SS_PASS(fsg);
  209079. + utp_context.cur_state = 0;
  209080. + return;
  209081. + }
  209082. + }
  209083. + UTP_SS_BUSY(fsg, --ctx->counter);
  209084. + }
  209085. +}
  209086. +
  209087. +static int utp_exec(struct fsg_dev *fsg,
  209088. + char *command,
  209089. + int cmdsize,
  209090. + unsigned long long payload)
  209091. +{
  209092. + struct utp_user_data *uud = NULL, *uud2r;
  209093. + struct utp_context *ctx = UTP_CTX(fsg);
  209094. +
  209095. + ctx->counter = 0xFFFF;
  209096. + uud2r = utp_user_data_alloc(cmdsize + 1);
  209097. + if (!uud2r)
  209098. + return -ENOMEM;
  209099. + uud2r->data.flags = UTP_FLAG_COMMAND;
  209100. + uud2r->data.payload = payload;
  209101. + strncpy(uud2r->data.command, command, cmdsize);
  209102. +
  209103. + mutex_lock(&ctx->lock);
  209104. + list_add_tail(&uud2r->link, &ctx->read);
  209105. + mutex_unlock(&ctx->lock);
  209106. + /* wake up the read routine */
  209107. + wake_up(&ctx->wq);
  209108. +
  209109. + if (command[0] == '!') /* there will be no response */
  209110. + return 0;
  209111. +
  209112. + /*
  209113. + * the user program (uuc) will return utp_message
  209114. + * and add list to write list
  209115. + */
  209116. + WAIT_ACTIVITY(write);
  209117. +
  209118. + mutex_lock(&ctx->lock);
  209119. + if (!list_empty(&ctx->write)) {
  209120. + uud = list_first_entry(&ctx->write, struct utp_user_data, link);
  209121. +#ifdef DEBUG
  209122. + pr_info("UUD:\n\tFlags = %02X\n", uud->data.flags);
  209123. + if (uud->data.flags & UTP_FLAG_DATA) {
  209124. + pr_info("\tbufsize = %d\n", uud->data.bufsize);
  209125. + print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_NONE,
  209126. + 16, 2, uud->data.data, uud->data.bufsize, true);
  209127. + }
  209128. + if (uud->data.flags & UTP_FLAG_REPORT_BUSY)
  209129. + pr_info("\tBUSY\n");
  209130. +#endif
  209131. + }
  209132. + mutex_unlock(&ctx->lock);
  209133. +
  209134. + if (uud->data.flags & UTP_FLAG_DATA) {
  209135. + memcpy(ctx->buffer, uud->data.data, uud->data.bufsize);
  209136. + UTP_SS_SIZE(fsg, uud->data.bufsize);
  209137. + } else if (uud->data.flags & UTP_FLAG_REPORT_BUSY) {
  209138. + UTP_SS_BUSY(fsg, ctx->counter);
  209139. + } else if (uud->data.flags & UTP_FLAG_STATUS) {
  209140. + printk(KERN_WARNING "%s: exit with status %d\n", __func__,
  209141. + uud->data.status);
  209142. + UTP_SS_EXIT(fsg, uud->data.status);
  209143. + } else {
  209144. + pr_debug("%s: pass returned in EXEC stage. \n", __func__);
  209145. + UTP_SS_PASS(fsg);
  209146. + }
  209147. + utp_user_data_free(uud);
  209148. + return 0;
  209149. +}
  209150. +
  209151. +static int utp_send_status(struct fsg_dev *fsg)
  209152. +{
  209153. + struct fsg_buffhd *bh;
  209154. + u8 status = US_BULK_STAT_OK;
  209155. + struct bulk_cs_wrap *csw;
  209156. + int rc;
  209157. +
  209158. + /* Wait for the next buffer to become available */
  209159. + bh = fsg->common->next_buffhd_to_fill;
  209160. + while (bh->state != BUF_STATE_EMPTY) {
  209161. + rc = sleep_thread(fsg->common);
  209162. + if (rc)
  209163. + return rc;
  209164. + }
  209165. +
  209166. + if (fsg->common->phase_error) {
  209167. + DBG(fsg, "sending phase-error status\n");
  209168. + status = US_BULK_STAT_PHASE;
  209169. +
  209170. + } else if ((UTP_CTX(fsg)->sd & 0xFFFF) != UTP_REPLY_PASS) {
  209171. + status = US_BULK_STAT_FAIL;
  209172. + }
  209173. +
  209174. + csw = bh->buf;
  209175. +
  209176. + /* Store and send the Bulk-only CSW */
  209177. + csw->Signature = __constant_cpu_to_le32(US_BULK_CS_SIGN);
  209178. + csw->Tag = fsg->common->tag;
  209179. + csw->Residue = cpu_to_le32(fsg->common->residue);
  209180. + csw->Status = status;
  209181. +
  209182. + bh->inreq->length = US_BULK_CS_WRAP_LEN;
  209183. + bh->inreq->zero = 0;
  209184. + start_transfer(fsg, fsg->bulk_in, bh->inreq,
  209185. + &bh->inreq_busy, &bh->state);
  209186. + fsg->common->next_buffhd_to_fill = bh->next;
  209187. + return 0;
  209188. +}
  209189. +
  209190. +static int utp_handle_message(struct fsg_dev *fsg,
  209191. + char *cdb_data,
  209192. + int default_reply)
  209193. +{
  209194. + struct utp_msg *m = (struct utp_msg *)cdb_data;
  209195. + void *data = NULL;
  209196. + int r;
  209197. + struct utp_user_data *uud2r;
  209198. + unsigned long long param;
  209199. + unsigned long tag;
  209200. +
  209201. + if (m->f0 != 0xF0)
  209202. + return default_reply;
  209203. +
  209204. + tag = get_unaligned_be32((void *)&m->utp_msg_tag);
  209205. + param = get_be64((void *)&m->param);
  209206. + pr_debug("Type 0x%x, tag 0x%08lx, param %llx\n",
  209207. + m->utp_msg_type, tag, param);
  209208. +
  209209. + switch ((enum utp_msg_type)m->utp_msg_type) {
  209210. +
  209211. + case UTP_POLL:
  209212. + if (get_be64((void *)&m->param) == 1) {
  209213. + pr_debug("%s: version request\n", __func__);
  209214. + UTP_SS_EXIT(fsg, UTP_CTX(fsg)->utp_version);
  209215. + break;
  209216. + }
  209217. + utp_poll(fsg);
  209218. + break;
  209219. + case UTP_EXEC:
  209220. + pr_debug("%s: EXEC\n", __func__);
  209221. + data = vmalloc(fsg->common->data_size);
  209222. + memset(data, 0, fsg->common->data_size);
  209223. + /* copy data from usb buffer to utp buffer */
  209224. + utp_do_write(fsg, data, fsg->common->data_size);
  209225. + utp_exec(fsg, data, fsg->common->data_size, param);
  209226. + vfree(data);
  209227. + break;
  209228. + case UTP_GET: /* data from device to host */
  209229. + pr_debug("%s: GET, %d bytes\n", __func__,
  209230. + fsg->common->data_size);
  209231. + r = utp_do_read(fsg, UTP_CTX(fsg)->buffer,
  209232. + fsg->common->data_size);
  209233. + UTP_SS_PASS(fsg);
  209234. + break;
  209235. + case UTP_PUT:
  209236. + utp_context.cur_state = UTP_FLAG_DATA;
  209237. + pr_debug("%s: PUT, Received %d bytes\n", __func__, fsg->common->data_size);/* data from host to device */
  209238. + uud2r = utp_user_data_alloc(fsg->common->data_size);
  209239. + if (!uud2r)
  209240. + return -ENOMEM;
  209241. + uud2r->data.bufsize = fsg->common->data_size;
  209242. + uud2r->data.flags = UTP_FLAG_DATA;
  209243. + utp_do_write(fsg, uud2r->data.data, fsg->common->data_size);
  209244. + /* don't know what will be written */
  209245. + mutex_lock(&UTP_CTX(fsg)->lock);
  209246. + list_add_tail(&uud2r->link, &UTP_CTX(fsg)->read);
  209247. + mutex_unlock(&UTP_CTX(fsg)->lock);
  209248. + wake_up(&UTP_CTX(fsg)->wq);
  209249. + /*
  209250. + * Return PASS or FAIL according to uuc's status
  209251. + * Please open it if need to check uuc's status
  209252. + * and use another version uuc
  209253. + */
  209254. +#if 0
  209255. + struct utp_user_data *uud = NULL;
  209256. + struct utp_context *ctx;
  209257. + WAIT_ACTIVITY(write);
  209258. + ctx = UTP_CTX(fsg);
  209259. + mutex_lock(&ctx->lock);
  209260. +
  209261. + if (!list_empty(&ctx->write))
  209262. + uud = list_first_entry(&ctx->write,
  209263. + struct utp_user_data, link);
  209264. +
  209265. + mutex_unlock(&ctx->lock);
  209266. + if (uud) {
  209267. + if (uud->data.flags & UTP_FLAG_STATUS) {
  209268. + printk(KERN_WARNING "%s: exit with status %d\n",
  209269. + __func__, uud->data.status);
  209270. + UTP_SS_EXIT(fsg, uud->data.status);
  209271. + } else {
  209272. + pr_debug("%s: pass\n", __func__);
  209273. + UTP_SS_PASS(fsg);
  209274. + }
  209275. + utp_user_data_free(uud);
  209276. + } else{
  209277. + UTP_SS_PASS(fsg);
  209278. + }
  209279. +#endif
  209280. + if (count_list(&UTP_CTX(fsg)->read) < 7) {
  209281. + utp_context.cur_state = 0;
  209282. + UTP_SS_PASS(fsg);
  209283. + } else
  209284. + UTP_SS_BUSY(fsg, UTP_CTX(fsg)->counter);
  209285. +
  209286. + break;
  209287. + }
  209288. +
  209289. + utp_send_status(fsg);
  209290. + return -1;
  209291. +}
  209292. diff -Nur linux-3.14.17/drivers/usb/gadget/fsl_updater.h linux-imx6-3.14/drivers/usb/gadget/fsl_updater.h
  209293. --- linux-3.14.17/drivers/usb/gadget/fsl_updater.h 1970-01-01 01:00:00.000000000 +0100
  209294. +++ linux-imx6-3.14/drivers/usb/gadget/fsl_updater.h 2014-09-11 18:06:09.158066553 +0200
  209295. @@ -0,0 +1,150 @@
  209296. +/*
  209297. + * Freescale UUT driver
  209298. + *
  209299. + * Copyright 2008-2013 Freescale Semiconductor, Inc.
  209300. + * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
  209301. + */
  209302. +
  209303. +/*
  209304. + * The code contained herein is licensed under the GNU General Public
  209305. + * License. You may obtain a copy of the GNU General Public License
  209306. + * Version 2 or later at the following locations:
  209307. + *
  209308. + * http://www.opensource.org/licenses/gpl-license.html
  209309. + * http://www.gnu.org/copyleft/gpl.html
  209310. + */
  209311. +
  209312. +#ifndef __FSL_UPDATER_H
  209313. +#define __FSL_UPDATER_H
  209314. +
  209315. +#include <linux/miscdevice.h>
  209316. +#include <linux/list.h>
  209317. +#include <linux/vmalloc.h>
  209318. +#include <linux/ioctl.h>
  209319. +/* #include <mach/hardware.h> */
  209320. +
  209321. +static int utp_init(struct fsg_dev *fsg);
  209322. +static void utp_exit(struct fsg_dev *fsg);
  209323. +static ssize_t utp_file_read(struct file *file,
  209324. + char __user *buf,
  209325. + size_t size,
  209326. + loff_t *off);
  209327. +
  209328. +static ssize_t utp_file_write(struct file *file,
  209329. + const char __user *buf,
  209330. + size_t size,
  209331. + loff_t *off);
  209332. +
  209333. +static long utp_ioctl(struct file *file,
  209334. + unsigned int cmd, unsigned long arg);
  209335. +static struct utp_user_data *utp_user_data_alloc(size_t size);
  209336. +static void utp_user_data_free(struct utp_user_data *uud);
  209337. +static int utp_get_sense(struct fsg_dev *fsg);
  209338. +static int utp_do_read(struct fsg_dev *fsg, void *data, size_t size);
  209339. +static int utp_do_write(struct fsg_dev *fsg, void *data, size_t size);
  209340. +static inline void utp_set_sense(struct fsg_dev *fsg, u16 code, u64 reply);
  209341. +static int utp_handle_message(struct fsg_dev *fsg,
  209342. + char *cdb_data,
  209343. + int default_reply);
  209344. +
  209345. +#define UTP_REPLY_PASS 0
  209346. +#define UTP_REPLY_EXIT 0x8001
  209347. +#define UTP_REPLY_BUSY 0x8002
  209348. +#define UTP_REPLY_SIZE 0x8003
  209349. +#define UTP_SENSE_KEY 9
  209350. +
  209351. +#define UTP_MINOR 222
  209352. +/* MISC_DYNAMIC_MINOR would be better, but... */
  209353. +
  209354. +#define UTP_COMMAND_SIZE 80
  209355. +
  209356. +#define UTP_SS_EXIT(fsg, r) utp_set_sense(fsg, UTP_REPLY_EXIT, (u64)r)
  209357. +#define UTP_SS_PASS(fsg) utp_set_sense(fsg, UTP_REPLY_PASS, 0)
  209358. +#define UTP_SS_BUSY(fsg, r) utp_set_sense(fsg, UTP_REPLY_BUSY, (u64)r)
  209359. +#define UTP_SS_SIZE(fsg, r) utp_set_sense(fsg, UTP_REPLY_SIZE, (u64)r)
  209360. +
  209361. +#define UTP_IOCTL_BASE 'U'
  209362. +#define UTP_GET_CPU_ID _IOR(UTP_IOCTL_BASE, 0, int)
  209363. +/* the structure of utp message which is mapped to 16-byte SCSI CBW's CDB */
  209364. +#pragma pack(1)
  209365. +struct utp_msg {
  209366. + u8 f0;
  209367. + u8 utp_msg_type;
  209368. + u32 utp_msg_tag;
  209369. + union {
  209370. + struct {
  209371. + u32 param_lsb;
  209372. + u32 param_msb;
  209373. + };
  209374. + u64 param;
  209375. + };
  209376. +};
  209377. +
  209378. +enum utp_msg_type {
  209379. + UTP_POLL = 0,
  209380. + UTP_EXEC,
  209381. + UTP_GET,
  209382. + UTP_PUT,
  209383. +};
  209384. +
  209385. +static struct utp_context {
  209386. + wait_queue_head_t wq;
  209387. + wait_queue_head_t list_full_wq;
  209388. + struct mutex lock;
  209389. + struct list_head read;
  209390. + struct list_head write;
  209391. + u32 sd, sdinfo, sdinfo_h; /* sense data */
  209392. + int processed;
  209393. + u8 *buffer;
  209394. + u32 counter;
  209395. + u64 utp_version;
  209396. + u32 cur_state;
  209397. +} utp_context;
  209398. +
  209399. +static const struct file_operations utp_fops = {
  209400. + .open = nonseekable_open,
  209401. + .read = utp_file_read,
  209402. + .write = utp_file_write,
  209403. + /* .ioctl = utp_ioctl, */
  209404. + .unlocked_ioctl = utp_ioctl,
  209405. +};
  209406. +
  209407. +static struct miscdevice utp_dev = {
  209408. + .minor = UTP_MINOR,
  209409. + .name = "utp",
  209410. + .fops = &utp_fops,
  209411. +};
  209412. +
  209413. +#define UTP_FLAG_COMMAND 0x00000001
  209414. +#define UTP_FLAG_DATA 0x00000002
  209415. +#define UTP_FLAG_STATUS 0x00000004
  209416. +#define UTP_FLAG_REPORT_BUSY 0x10000000
  209417. +struct utp_message {
  209418. + u32 flags;
  209419. + size_t size;
  209420. + union {
  209421. + struct {
  209422. + u64 payload;
  209423. + char command[1];
  209424. + };
  209425. + struct {
  209426. + size_t bufsize;
  209427. + u8 data[1];
  209428. + };
  209429. + u32 status;
  209430. + };
  209431. +};
  209432. +
  209433. +struct utp_user_data {
  209434. + struct list_head link;
  209435. + struct utp_message data;
  209436. +};
  209437. +#pragma pack()
  209438. +
  209439. +static inline struct utp_context *UTP_CTX(struct fsg_dev *fsg)
  209440. +{
  209441. + return (struct utp_context *)fsg->utp;
  209442. +}
  209443. +
  209444. +#endif /* __FSL_UPDATER_H */
  209445. +
  209446. diff -Nur linux-3.14.17/drivers/usb/gadget/Kconfig linux-imx6-3.14/drivers/usb/gadget/Kconfig
  209447. --- linux-3.14.17/drivers/usb/gadget/Kconfig 2014-08-14 03:38:34.000000000 +0200
  209448. +++ linux-imx6-3.14/drivers/usb/gadget/Kconfig 2014-09-11 18:06:09.146066506 +0200
  209449. @@ -952,6 +952,12 @@
  209450. Say "y" to link the driver statically, or "m" to build
  209451. a dynamically linked module called "g_mass_storage".
  209452. +config FSL_UTP
  209453. + bool "UTP over Storage Gadget"
  209454. + depends on USB_MASS_STORAGE
  209455. + help
  209456. + Freescale's extension to MSC protocol
  209457. +
  209458. config USB_GADGET_TARGET
  209459. tristate "USB Gadget Target Fabric Module"
  209460. depends on TARGET_CORE
  209461. diff -Nur linux-3.14.17/drivers/usb/gadget/mass_storage.c linux-imx6-3.14/drivers/usb/gadget/mass_storage.c
  209462. --- linux-3.14.17/drivers/usb/gadget/mass_storage.c 2014-08-14 03:38:34.000000000 +0200
  209463. +++ linux-imx6-3.14/drivers/usb/gadget/mass_storage.c 2014-09-11 18:06:09.162066569 +0200
  209464. @@ -266,7 +266,7 @@
  209465. {
  209466. return usb_composite_probe(&msg_driver);
  209467. }
  209468. -module_init(msg_init);
  209469. +late_initcall(msg_init);
  209470. static void msg_cleanup(void)
  209471. {
  209472. diff -Nur linux-3.14.17/drivers/usb/host/ehci-h20ahb.c linux-imx6-3.14/drivers/usb/host/ehci-h20ahb.c
  209473. --- linux-3.14.17/drivers/usb/host/ehci-h20ahb.c 1970-01-01 01:00:00.000000000 +0100
  209474. +++ linux-imx6-3.14/drivers/usb/host/ehci-h20ahb.c 2014-09-11 18:06:09.170066601 +0200
  209475. @@ -0,0 +1,341 @@
  209476. +/*
  209477. + * Copyright (C) 2007-2013 Texas Instruments, Inc.
  209478. + * Author: Vikram Pandita <vikram.pandita@ti.com>
  209479. + * Author: Anand Gadiyar <gadiyar@ti.com>
  209480. + * Author: Keshava Munegowda <keshava_mgowda@ti.com>
  209481. + * Author: Roger Quadros <rogerq@ti.com>
  209482. + *
  209483. + * Copyright (C) 2009 Nokia Corporation
  209484. + * Contact: Felipe Balbi <felipe.balbi@nokia.com>
  209485. + *
  209486. + * Based on ehci-omap.c - driver for USBHOST on OMAP3/4 processors
  209487. + *
  209488. + * This file is subject to the terms and conditions of the GNU General Public
  209489. + * License. See the file COPYING in the main directory of this archive
  209490. + * for more details.
  209491. + *
  209492. + */
  209493. +
  209494. +#include <linux/kernel.h>
  209495. +#include <linux/module.h>
  209496. +#include <linux/io.h>
  209497. +#include <linux/platform_device.h>
  209498. +#include <linux/slab.h>
  209499. +#include <linux/usb/ulpi.h>
  209500. +#include <linux/pm_runtime.h>
  209501. +#include <linux/gpio.h>
  209502. +#include <linux/clk.h>
  209503. +#include <linux/usb.h>
  209504. +#include <linux/usb/hcd.h>
  209505. +#include <linux/of.h>
  209506. +#include <linux/dma-mapping.h>
  209507. +
  209508. +#include "ehci.h"
  209509. +
  209510. +#define H20AHB_HS_USB_PORTS 1
  209511. +
  209512. +/* EHCI Synopsys-specific Register Set */
  209513. +#define EHCI_INSNREG04 (0xA0)
  209514. +#define EHCI_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
  209515. +#define EHCI_INSNREG05_ULPI (0xA4)
  209516. +#define EHCI_INSNREG05_ULPI_CONTROL_SHIFT 31
  209517. +#define EHCI_INSNREG05_ULPI_PORTSEL_SHIFT 24
  209518. +#define EHCI_INSNREG05_ULPI_OPSEL_SHIFT 22
  209519. +#define EHCI_INSNREG05_ULPI_REGADD_SHIFT 16
  209520. +#define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8
  209521. +#define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0
  209522. +
  209523. +#define DRIVER_DESC "H20AHB-EHCI Host Controller driver"
  209524. +
  209525. +static const char hcd_name[] = "ehci-h20ahb";
  209526. +
  209527. +/*-------------------------------------------------------------------------*/
  209528. +
  209529. +struct h20ahb_hcd {
  209530. + struct usb_phy *phy[H20AHB_HS_USB_PORTS]; /* one PHY for each port */
  209531. + int nports;
  209532. +};
  209533. +
  209534. +static inline void ehci_write(void __iomem *base, u32 reg, u32 val)
  209535. +{
  209536. + __raw_writel(val, base + reg);
  209537. +}
  209538. +
  209539. +static inline u32 ehci_read(void __iomem *base, u32 reg)
  209540. +{
  209541. + return __raw_readl(base + reg);
  209542. +}
  209543. +
  209544. +/* configure so an HC device and id are always provided */
  209545. +/* always called with process context; sleeping is OK */
  209546. +
  209547. +static struct hc_driver __read_mostly ehci_h20ahb_hc_driver;
  209548. +
  209549. +static const struct ehci_driver_overrides ehci_h20ahb_overrides __initdata = {
  209550. + .extra_priv_size = sizeof(struct h20ahb_hcd),
  209551. +};
  209552. +
  209553. +static int ehci_h20ahb_phy_read(struct usb_phy *x, u32 reg)
  209554. +{
  209555. + u32 val = (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |
  209556. + (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |
  209557. + (3 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |
  209558. + (reg << EHCI_INSNREG05_ULPI_REGADD_SHIFT);
  209559. + ehci_write(x->io_priv, 0, val);
  209560. + while ((val = ehci_read(x->io_priv, 0)) &
  209561. + (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT));
  209562. + return val & 0xff;
  209563. +}
  209564. +
  209565. +static int ehci_h20ahb_phy_write(struct usb_phy *x, u32 val, u32 reg)
  209566. +{
  209567. + u32 v = (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |
  209568. + (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |
  209569. + (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |
  209570. + (reg << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |
  209571. + (val & 0xff);
  209572. + ehci_write(x->io_priv, 0, v);
  209573. + while ((v = ehci_read(x->io_priv, 0)) &
  209574. + (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT));
  209575. + return 0;
  209576. +}
  209577. +
  209578. +static struct usb_phy_io_ops ehci_h20ahb_phy_io_ops = {
  209579. + .read = ehci_h20ahb_phy_read,
  209580. + .write = ehci_h20ahb_phy_write,
  209581. +};
  209582. +
  209583. +
  209584. +/**
  209585. + * ehci_hcd_h20ahb_probe - initialize Synopsis-based HCDs
  209586. + *
  209587. + * Allocates basic resources for this USB host controller, and
  209588. + * then invokes the start() method for the HCD associated with it
  209589. + * through the hotplug entry's driver_data.
  209590. + */
  209591. +static int ehci_hcd_h20ahb_probe(struct platform_device *pdev)
  209592. +{
  209593. + struct device *dev = &pdev->dev;
  209594. + struct resource *res;
  209595. + struct usb_hcd *hcd;
  209596. + void __iomem *regs;
  209597. + int ret;
  209598. + int irq;
  209599. + int i;
  209600. + struct h20ahb_hcd *h20ahb;
  209601. +
  209602. + if (usb_disabled())
  209603. + return -ENODEV;
  209604. +
  209605. + /* if (!dev->parent) {
  209606. + dev_err(dev, "Missing parent device\n");
  209607. + return -ENODEV;
  209608. + }*/
  209609. +
  209610. + /* For DT boot, get platform data from parent. i.e. usbhshost */
  209611. + /*if (dev->of_node) {
  209612. + pdata = dev_get_platdata(dev->parent);
  209613. + dev->platform_data = pdata;
  209614. + }
  209615. +
  209616. + if (!pdata) {
  209617. + dev_err(dev, "Missing platform data\n");
  209618. + return -ENODEV;
  209619. + }*/
  209620. +
  209621. + irq = platform_get_irq(pdev, 0);
  209622. + if (irq < 0) {
  209623. + dev_err(dev, "EHCI irq failed\n");
  209624. + return -ENODEV;
  209625. + }
  209626. +
  209627. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  209628. + regs = devm_ioremap_resource(dev, res);
  209629. + if (IS_ERR(regs))
  209630. + return PTR_ERR(regs);
  209631. +
  209632. + /*
  209633. + * Right now device-tree probed devices don't get dma_mask set.
  209634. + * Since shared usb code relies on it, set it here for now.
  209635. + * Once we have dma capability bindings this can go away.
  209636. + */
  209637. + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
  209638. + if (ret)
  209639. + return ret;
  209640. +
  209641. + ret = -ENODEV;
  209642. + hcd = usb_create_hcd(&ehci_h20ahb_hc_driver, dev,
  209643. + dev_name(dev));
  209644. + if (!hcd) {
  209645. + dev_err(dev, "Failed to create HCD\n");
  209646. + return -ENOMEM;
  209647. + }
  209648. +
  209649. + hcd->rsrc_start = res->start;
  209650. + hcd->rsrc_len = resource_size(res);
  209651. + hcd->regs = regs;
  209652. + hcd_to_ehci(hcd)->caps = regs;
  209653. +
  209654. + h20ahb = (struct h20ahb_hcd *)hcd_to_ehci(hcd)->priv;
  209655. + h20ahb->nports = 1;
  209656. +
  209657. + platform_set_drvdata(pdev, hcd);
  209658. +
  209659. + /* get the PHY devices if needed */
  209660. + for (i = 0 ; i < h20ahb->nports ; i++) {
  209661. + struct usb_phy *phy;
  209662. +
  209663. + /* get the PHY device */
  209664. +#if 0
  209665. + if (dev->of_node)
  209666. + phy = devm_usb_get_phy_by_phandle(dev, "phys", i);
  209667. + else
  209668. + phy = devm_usb_get_phy_dev(dev, i);
  209669. +#endif
  209670. + phy = otg_ulpi_create(&ehci_h20ahb_phy_io_ops, 0);
  209671. + if (IS_ERR(phy)) {
  209672. + ret = PTR_ERR(phy);
  209673. + dev_err(dev, "Can't get PHY device for port %d: %d\n",
  209674. + i, ret);
  209675. + goto err_phy;
  209676. + }
  209677. + phy->dev = dev;
  209678. + usb_add_phy_dev(phy);
  209679. +
  209680. + h20ahb->phy[i] = phy;
  209681. + phy->io_priv = hcd->regs + EHCI_INSNREG05_ULPI;
  209682. +
  209683. +#if 0
  209684. + usb_phy_init(h20ahb->phy[i]);
  209685. + /* bring PHY out of suspend */
  209686. + usb_phy_set_suspend(h20ahb->phy[i], 0);
  209687. +#endif
  209688. + }
  209689. +
  209690. + /* make the first port's phy the one used by hcd as well */
  209691. + hcd->phy = h20ahb->phy[0];
  209692. +
  209693. + pm_runtime_enable(dev);
  209694. + pm_runtime_get_sync(dev);
  209695. +
  209696. + /*
  209697. + * An undocumented "feature" in the H20AHB EHCI controller,
  209698. + * causes suspended ports to be taken out of suspend when
  209699. + * the USBCMD.Run/Stop bit is cleared (for example when
  209700. + * we do ehci_bus_suspend).
  209701. + * This breaks suspend-resume if the root-hub is allowed
  209702. + * to suspend. Writing 1 to this undocumented register bit
  209703. + * disables this feature and restores normal behavior.
  209704. + */
  209705. + ehci_write(regs, EHCI_INSNREG04,
  209706. + EHCI_INSNREG04_DISABLE_UNSUSPEND);
  209707. +
  209708. + ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
  209709. + if (ret) {
  209710. + dev_err(dev, "failed to add hcd with err %d\n", ret);
  209711. + goto err_pm_runtime;
  209712. + }
  209713. + device_wakeup_enable(hcd->self.controller);
  209714. +
  209715. + /*
  209716. + * Bring PHYs out of reset for non PHY modes.
  209717. + * Even though HSIC mode is a PHY-less mode, the reset
  209718. + * line exists between the chips and can be modelled
  209719. + * as a PHY device for reset control.
  209720. + */
  209721. + for (i = 0; i < h20ahb->nports; i++) {
  209722. + usb_phy_init(h20ahb->phy[i]);
  209723. + /* bring PHY out of suspend */
  209724. + usb_phy_set_suspend(h20ahb->phy[i], 0);
  209725. + }
  209726. +
  209727. + return 0;
  209728. +
  209729. +err_pm_runtime:
  209730. + pm_runtime_put_sync(dev);
  209731. +
  209732. +err_phy:
  209733. + for (i = 0; i < h20ahb->nports; i++) {
  209734. + if (h20ahb->phy[i])
  209735. + usb_phy_shutdown(h20ahb->phy[i]);
  209736. + }
  209737. +
  209738. + usb_put_hcd(hcd);
  209739. +
  209740. + return ret;
  209741. +}
  209742. +
  209743. +
  209744. +/**
  209745. + * ehci_hcd_h20ahb_remove - shutdown processing for EHCI HCDs
  209746. + * @pdev: USB Host Controller being removed
  209747. + *
  209748. + * Reverses the effect of usb_ehci_hcd_h20ahb_probe(), first invoking
  209749. + * the HCD's stop() method. It is always called from a thread
  209750. + * context, normally "rmmod", "apmd", or something similar.
  209751. + */
  209752. +static int ehci_hcd_h20ahb_remove(struct platform_device *pdev)
  209753. +{
  209754. + struct device *dev = &pdev->dev;
  209755. + struct usb_hcd *hcd = dev_get_drvdata(dev);
  209756. + struct h20ahb_hcd *h20ahb = (struct h20ahb_hcd *)hcd_to_ehci(hcd)->priv;
  209757. + int i;
  209758. +
  209759. + usb_remove_hcd(hcd);
  209760. +
  209761. + for (i = 0; i < h20ahb->nports; i++) {
  209762. + if (h20ahb->phy[i])
  209763. + usb_phy_shutdown(h20ahb->phy[i]);
  209764. + }
  209765. +
  209766. + usb_put_hcd(hcd);
  209767. + pm_runtime_put_sync(dev);
  209768. + pm_runtime_disable(dev);
  209769. +
  209770. + return 0;
  209771. +}
  209772. +
  209773. +static const struct of_device_id h20ahb_ehci_dt_ids[] = {
  209774. + { .compatible = "snps,ehci-h20ahb" },
  209775. + { }
  209776. +};
  209777. +
  209778. +MODULE_DEVICE_TABLE(of, h20ahb_ehci_dt_ids);
  209779. +
  209780. +static struct platform_driver ehci_hcd_h20ahb_driver = {
  209781. + .probe = ehci_hcd_h20ahb_probe,
  209782. + .remove = ehci_hcd_h20ahb_remove,
  209783. + .shutdown = usb_hcd_platform_shutdown,
  209784. + /*.suspend = ehci_hcd_h20ahb_suspend, */
  209785. + /*.resume = ehci_hcd_h20ahb_resume, */
  209786. + .driver = {
  209787. + .name = hcd_name,
  209788. + .of_match_table = h20ahb_ehci_dt_ids,
  209789. + }
  209790. +};
  209791. +
  209792. +/*-------------------------------------------------------------------------*/
  209793. +
  209794. +static int __init ehci_h20ahb_init(void)
  209795. +{
  209796. + if (usb_disabled())
  209797. + return -ENODEV;
  209798. +
  209799. + pr_info("%s: " DRIVER_DESC "\n", hcd_name);
  209800. +
  209801. + ehci_init_driver(&ehci_h20ahb_hc_driver, &ehci_h20ahb_overrides);
  209802. + return platform_driver_register(&ehci_hcd_h20ahb_driver);
  209803. +}
  209804. +module_init(ehci_h20ahb_init);
  209805. +
  209806. +static void __exit ehci_h20ahb_cleanup(void)
  209807. +{
  209808. + platform_driver_unregister(&ehci_hcd_h20ahb_driver);
  209809. +}
  209810. +module_exit(ehci_h20ahb_cleanup);
  209811. +
  209812. +MODULE_ALIAS("platform:ehci-h20ahb");
  209813. +MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
  209814. +
  209815. +MODULE_DESCRIPTION(DRIVER_DESC);
  209816. +MODULE_LICENSE("GPL");
  209817. diff -Nur linux-3.14.17/drivers/usb/host/ehci-hcd.c linux-imx6-3.14/drivers/usb/host/ehci-hcd.c
  209818. --- linux-3.14.17/drivers/usb/host/ehci-hcd.c 2014-08-14 03:38:34.000000000 +0200
  209819. +++ linux-imx6-3.14/drivers/usb/host/ehci-hcd.c 2014-09-11 18:06:09.174066617 +0200
  209820. @@ -590,11 +590,16 @@
  209821. */
  209822. hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
  209823. if (HCC_64BIT_ADDR(hcc_params)) {
  209824. - ehci_writel(ehci, 0, &ehci->regs->segment);
  209825. -#if 0
  209826. -// this is deeply broken on almost all architectures
  209827. +#ifdef CONFIG_ARM64
  209828. + ehci_writel(ehci, ehci->periodic_dma >> 32, &ehci->regs->segment);
  209829. + /*
  209830. + * this is deeply broken on almost all architectures
  209831. + * but arm64 can use it so enable it
  209832. + */
  209833. if (!dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)))
  209834. ehci_info(ehci, "enabled 64bit DMA\n");
  209835. +#else
  209836. + ehci_writel(ehci, 0, &ehci->regs->segment);
  209837. #endif
  209838. }
  209839. diff -Nur linux-3.14.17/drivers/usb/host/ehci-hub.c linux-imx6-3.14/drivers/usb/host/ehci-hub.c
  209840. --- linux-3.14.17/drivers/usb/host/ehci-hub.c 2014-08-14 03:38:34.000000000 +0200
  209841. +++ linux-imx6-3.14/drivers/usb/host/ehci-hub.c 2014-09-11 18:06:09.174066617 +0200
  209842. @@ -313,6 +313,15 @@
  209843. USB_PORT_STAT_HIGH_SPEED)
  209844. fs_idle_delay = true;
  209845. ehci_writel(ehci, t2, reg);
  209846. + if ((t2 & PORT_WKDISC_E)
  209847. + && (ehci_port_speed(ehci, t2) ==
  209848. + USB_PORT_STAT_HIGH_SPEED))
  209849. + /*
  209850. + * If the high-speed device has not switched
  209851. + * to full-speed idle before WKDISC_E has
  209852. + * effected, there will be a WKDISC event.
  209853. + */
  209854. + mdelay(4);
  209855. changed = 1;
  209856. }
  209857. }
  209858. diff -Nur linux-3.14.17/drivers/usb/host/Kconfig linux-imx6-3.14/drivers/usb/host/Kconfig
  209859. --- linux-3.14.17/drivers/usb/host/Kconfig 2014-08-14 03:38:34.000000000 +0200
  209860. +++ linux-imx6-3.14/drivers/usb/host/Kconfig 2014-09-11 18:06:09.170066601 +0200
  209861. @@ -158,6 +158,13 @@
  209862. Enables support for the on-chip EHCI controller on
  209863. ST SPEAr chips.
  209864. +config USB_EHCI_HCD_SYNOPSYS
  209865. + tristate "Support for Synopsys Host-AHB USB 2.0 controller"
  209866. + depends on USB_EHCI_HCD && USB_PHY
  209867. + ---help---
  209868. + Enable support for onchip USB controllers based on DesignWare USB 2.0
  209869. + Host-AHB Controller IP from Synopsys.
  209870. +
  209871. config USB_EHCI_HCD_AT91
  209872. tristate "Support for Atmel on-chip EHCI USB controller"
  209873. depends on USB_EHCI_HCD && ARCH_AT91
  209874. diff -Nur linux-3.14.17/drivers/usb/host/Makefile linux-imx6-3.14/drivers/usb/host/Makefile
  209875. --- linux-3.14.17/drivers/usb/host/Makefile 2014-08-14 03:38:34.000000000 +0200
  209876. +++ linux-imx6-3.14/drivers/usb/host/Makefile 2014-09-11 18:06:09.170066601 +0200
  209877. @@ -33,6 +33,8 @@
  209878. obj-$(CONFIG_USB_EHCI_HCD_ORION) += ehci-orion.o
  209879. obj-$(CONFIG_USB_EHCI_HCD_SPEAR) += ehci-spear.o
  209880. obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
  209881. +obj-$(CONFIG_USB_EHCI_S5P) += ehci-s5p.o
  209882. +obj-$(CONFIG_USB_EHCI_HCD_SYNOPSYS) += ehci-h20ahb.o
  209883. obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
  209884. obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
  209885. obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
  209886. diff -Nur linux-3.14.17/drivers/usb/phy/Kconfig linux-imx6-3.14/drivers/usb/phy/Kconfig
  209887. --- linux-3.14.17/drivers/usb/phy/Kconfig 2014-08-14 03:38:34.000000000 +0200
  209888. +++ linux-imx6-3.14/drivers/usb/phy/Kconfig 2014-09-11 18:06:09.250066921 +0200
  209889. @@ -253,7 +253,7 @@
  209890. config USB_ULPI
  209891. bool "Generic ULPI Transceiver Driver"
  209892. - depends on ARM
  209893. + depends on ARM || ARM64
  209894. help
  209895. Enable this to support ULPI connected USB OTG transceivers which
  209896. are likely found on embedded boards.
  209897. diff -Nur linux-3.14.17/drivers/usb/phy/phy-mxs-usb.c linux-imx6-3.14/drivers/usb/phy/phy-mxs-usb.c
  209898. --- linux-3.14.17/drivers/usb/phy/phy-mxs-usb.c 2014-08-14 03:38:34.000000000 +0200
  209899. +++ linux-imx6-3.14/drivers/usb/phy/phy-mxs-usb.c 2014-09-11 18:06:09.254066936 +0200
  209900. @@ -1,5 +1,5 @@
  209901. /*
  209902. - * Copyright 2012 Freescale Semiconductor, Inc.
  209903. + * Copyright 2012-2013 Freescale Semiconductor, Inc.
  209904. * Copyright (C) 2012 Marek Vasut <marex@denx.de>
  209905. * on behalf of DENX Software Engineering GmbH
  209906. *
  209907. @@ -20,6 +20,9 @@
  209908. #include <linux/delay.h>
  209909. #include <linux/err.h>
  209910. #include <linux/io.h>
  209911. +#include <linux/of_device.h>
  209912. +#include <linux/regmap.h>
  209913. +#include <linux/mfd/syscon.h>
  209914. #define DRIVER_NAME "mxs_phy"
  209915. @@ -28,18 +31,137 @@
  209916. #define HW_USBPHY_CTRL_SET 0x34
  209917. #define HW_USBPHY_CTRL_CLR 0x38
  209918. +#define HW_USBPHY_DEBUG_SET 0x54
  209919. +#define HW_USBPHY_DEBUG_CLR 0x58
  209920. +
  209921. +#define HW_USBPHY_IP 0x90
  209922. +#define HW_USBPHY_IP_SET 0x94
  209923. +#define HW_USBPHY_IP_CLR 0x98
  209924. +
  209925. #define BM_USBPHY_CTRL_SFTRST BIT(31)
  209926. #define BM_USBPHY_CTRL_CLKGATE BIT(30)
  209927. +#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26)
  209928. +#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25)
  209929. +#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23)
  209930. +#define BM_USBPHY_CTRL_ENIDCHG_WKUP BIT(22)
  209931. +#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP BIT(21)
  209932. +#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD BIT(20)
  209933. +#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE BIT(19)
  209934. +#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL BIT(18)
  209935. #define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15)
  209936. #define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
  209937. #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
  209938. +#define BM_USBPHY_IP_FIX (BIT(17) | BIT(18))
  209939. +
  209940. +#define BM_USBPHY_DEBUG_CLKGATE BIT(30)
  209941. +
  209942. +/* Anatop Registers */
  209943. +#define ANADIG_ANA_MISC0 0x150
  209944. +#define ANADIG_ANA_MISC0_SET 0x154
  209945. +#define ANADIG_ANA_MISC0_CLR 0x158
  209946. +
  209947. +#define ANADIG_USB1_VBUS_DET_STAT 0x1c0
  209948. +#define ANADIG_USB2_VBUS_DET_STAT 0x220
  209949. +
  209950. +#define ANADIG_USB1_LOOPBACK_SET 0x1e4
  209951. +#define ANADIG_USB1_LOOPBACK_CLR 0x1e8
  209952. +#define ANADIG_USB2_LOOPBACK_SET 0x244
  209953. +#define ANADIG_USB2_LOOPBACK_CLR 0x248
  209954. +
  209955. +#define ANADIG_USB1_MISC 0x1f0
  209956. +#define ANADIG_USB2_MISC 0x250
  209957. +
  209958. +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12)
  209959. +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11)
  209960. +
  209961. +#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
  209962. +#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3)
  209963. +
  209964. +#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 BIT(2)
  209965. +#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN BIT(5)
  209966. +#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2)
  209967. +#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5)
  209968. +
  209969. +#define BM_ANADIG_USB1_MISC_RX_VPIN_FS BIT(29)
  209970. +#define BM_ANADIG_USB1_MISC_RX_VMIN_FS BIT(28)
  209971. +#define BM_ANADIG_USB2_MISC_RX_VPIN_FS BIT(29)
  209972. +#define BM_ANADIG_USB2_MISC_RX_VMIN_FS BIT(28)
  209973. +
  209974. +#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
  209975. +
  209976. +/* Do disconnection between PHY and controller without vbus */
  209977. +#define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS BIT(0)
  209978. +
  209979. +/*
  209980. + * The PHY will be in messy if there is an wakeup after putting
  209981. + * bus to suspend (set portsc.suspendM) but before setting PHY to low
  209982. + * power mode (set portsc.phcd).
  209983. + */
  209984. +#define MXS_PHY_ABNORAML_IN_SUSPEND BIT(1)
  209985. +
  209986. +/*
  209987. + * The SOF sends too fast after resuming, it will cause disconnection
  209988. + * between host and high speed device.
  209989. + */
  209990. +#define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2)
  209991. +
  209992. +/* The SoCs who have anatop module */
  209993. +#define MXS_PHY_HAS_ANATOP BIT(3)
  209994. +
  209995. +struct mxs_phy_data {
  209996. + unsigned int flags;
  209997. +};
  209998. +
  209999. +static const struct mxs_phy_data imx23_phy_data = {
  210000. + .flags = MXS_PHY_ABNORAML_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
  210001. +};
  210002. +
  210003. +static const struct mxs_phy_data imx6q_phy_data = {
  210004. + .flags = MXS_PHY_SENDING_SOF_TOO_FAST |
  210005. + MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
  210006. + MXS_PHY_HAS_ANATOP,
  210007. +};
  210008. +
  210009. +static const struct mxs_phy_data imx6sl_phy_data = {
  210010. + .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
  210011. + MXS_PHY_HAS_ANATOP,
  210012. +};
  210013. +
  210014. +static const struct of_device_id mxs_phy_dt_ids[] = {
  210015. + { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
  210016. + { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
  210017. + { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
  210018. + { /* sentinel */ }
  210019. +};
  210020. +MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
  210021. +
  210022. struct mxs_phy {
  210023. struct usb_phy phy;
  210024. struct clk *clk;
  210025. + const struct mxs_phy_data *data;
  210026. + struct regmap *regmap_anatop;
  210027. + int port_id;
  210028. };
  210029. -#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
  210030. +static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
  210031. +{
  210032. + return mxs_phy->data == &imx6q_phy_data;
  210033. +}
  210034. +
  210035. +static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
  210036. +{
  210037. + return mxs_phy->data == &imx6sl_phy_data;
  210038. +}
  210039. +
  210040. +/*
  210041. + * PHY needs some 32K cycles to switch from 32K clock to
  210042. + * bus (such as AHB/AXI, etc) clock.
  210043. + */
  210044. +static void mxs_phy_clock_switch(void)
  210045. +{
  210046. + usleep_range(300, 400);
  210047. +}
  210048. static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
  210049. {
  210050. @@ -53,19 +175,122 @@
  210051. /* Power up the PHY */
  210052. writel(0, base + HW_USBPHY_PWD);
  210053. - /* enable FS/LS device */
  210054. - writel(BM_USBPHY_CTRL_ENUTMILEVEL2 |
  210055. - BM_USBPHY_CTRL_ENUTMILEVEL3,
  210056. + /*
  210057. + * USB PHY Ctrl Setting
  210058. + * - Auto clock/power on
  210059. + * - Enable full/low speed support
  210060. + */
  210061. + writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
  210062. + BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
  210063. + BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
  210064. + BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
  210065. + BM_USBPHY_CTRL_ENAUTO_PWRON_PLL |
  210066. + BM_USBPHY_CTRL_ENUTMILEVEL2 |
  210067. + BM_USBPHY_CTRL_ENUTMILEVEL3,
  210068. base + HW_USBPHY_CTRL_SET);
  210069. + /* Enable IC solution */
  210070. + if (is_imx6q_phy(mxs_phy) || is_imx6sl_phy(mxs_phy))
  210071. + writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
  210072. +
  210073. return 0;
  210074. }
  210075. +/* Return true if the vbus is there */
  210076. +static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
  210077. +{
  210078. + unsigned int vbus_value;
  210079. +
  210080. + if (mxs_phy->port_id == 0)
  210081. + regmap_read(mxs_phy->regmap_anatop,
  210082. + ANADIG_USB1_VBUS_DET_STAT,
  210083. + &vbus_value);
  210084. + else if (mxs_phy->port_id == 1)
  210085. + regmap_read(mxs_phy->regmap_anatop,
  210086. + ANADIG_USB2_VBUS_DET_STAT,
  210087. + &vbus_value);
  210088. +
  210089. + if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)
  210090. + return true;
  210091. + else
  210092. + return false;
  210093. +}
  210094. +
  210095. +static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
  210096. +{
  210097. + void __iomem *base = mxs_phy->phy.io_priv;
  210098. + u32 reg;
  210099. +
  210100. + if (disconnect)
  210101. + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
  210102. + base + HW_USBPHY_DEBUG_CLR);
  210103. +
  210104. + if (mxs_phy->port_id == 0) {
  210105. + reg = disconnect ? ANADIG_USB1_LOOPBACK_SET
  210106. + : ANADIG_USB1_LOOPBACK_CLR;
  210107. + regmap_write(mxs_phy->regmap_anatop, reg,
  210108. + BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 |
  210109. + BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN);
  210110. + } else if (mxs_phy->port_id == 1) {
  210111. + reg = disconnect ? ANADIG_USB2_LOOPBACK_SET
  210112. + : ANADIG_USB2_LOOPBACK_CLR;
  210113. + regmap_write(mxs_phy->regmap_anatop, reg,
  210114. + BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 |
  210115. + BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN);
  210116. + }
  210117. +
  210118. + if (!disconnect)
  210119. + writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
  210120. + base + HW_USBPHY_DEBUG_SET);
  210121. +
  210122. + /* Delay some time, and let Linestate be SE0 for controller */
  210123. + if (disconnect)
  210124. + usleep_range(500, 1000);
  210125. +}
  210126. +
  210127. +static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
  210128. +{
  210129. + bool vbus_is_on = false;
  210130. +
  210131. + /* If the SoCs don't need to disconnect line without vbus, quit */
  210132. + if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
  210133. + return;
  210134. +
  210135. + /* If the SoCs don't have anatop, quit */
  210136. + if (!mxs_phy->regmap_anatop)
  210137. + return;
  210138. +
  210139. + vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
  210140. +
  210141. + if (on && !vbus_is_on)
  210142. + __mxs_phy_disconnect_line(mxs_phy, true);
  210143. + else
  210144. + __mxs_phy_disconnect_line(mxs_phy, false);
  210145. +
  210146. +}
  210147. +
  210148. +static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
  210149. +{
  210150. + unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
  210151. +
  210152. + /* If the SoCs don't have anatop, quit */
  210153. + if (!mxs_phy->regmap_anatop)
  210154. + return;
  210155. +
  210156. + if (is_imx6q_phy(mxs_phy))
  210157. + regmap_write(mxs_phy->regmap_anatop, reg,
  210158. + BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
  210159. + else if (is_imx6sl_phy(mxs_phy))
  210160. + regmap_write(mxs_phy->regmap_anatop,
  210161. + reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
  210162. +}
  210163. +
  210164. static int mxs_phy_init(struct usb_phy *phy)
  210165. {
  210166. int ret;
  210167. struct mxs_phy *mxs_phy = to_mxs_phy(phy);
  210168. + mxs_phy_clock_switch();
  210169. ret = clk_prepare_enable(mxs_phy->clk);
  210170. if (ret)
  210171. return ret;
  210172. @@ -83,17 +308,62 @@
  210173. clk_disable_unprepare(mxs_phy->clk);
  210174. }
  210175. +static bool mxs_phy_is_low_speed_connection(struct mxs_phy *mxs_phy)
  210176. +{
  210177. + unsigned int line_state;
  210178. + /* bit definition is the same for all controllers */
  210179. + unsigned int dp_bit = BM_ANADIG_USB1_MISC_RX_VPIN_FS,
  210180. + dm_bit = BM_ANADIG_USB1_MISC_RX_VMIN_FS;
  210181. + unsigned int reg = ANADIG_USB1_MISC;
  210182. +
  210183. + /* If the SoCs don't have anatop, quit */
  210184. + if (!mxs_phy->regmap_anatop)
  210185. + return false;
  210186. +
  210187. + if (mxs_phy->port_id == 0)
  210188. + reg = ANADIG_USB1_MISC;
  210189. + else if (mxs_phy->port_id == 1)
  210190. + reg = ANADIG_USB2_MISC;
  210191. +
  210192. + regmap_read(mxs_phy->regmap_anatop, reg, &line_state);
  210193. +
  210194. + if ((line_state & (dp_bit | dm_bit)) == dm_bit)
  210195. + return true;
  210196. + else
  210197. + return false;
  210198. +}
  210199. +
  210200. static int mxs_phy_suspend(struct usb_phy *x, int suspend)
  210201. {
  210202. int ret;
  210203. struct mxs_phy *mxs_phy = to_mxs_phy(x);
  210204. + bool low_speed_connection, vbus_is_on;
  210205. +
  210206. + low_speed_connection = mxs_phy_is_low_speed_connection(mxs_phy);
  210207. + vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
  210208. if (suspend) {
  210209. writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
  210210. + /*
  210211. + * FIXME: Do not power down RXPWD1PT1 bit for low speed
  210212. + * connect. The low speed connection will have problem at
  210213. + * very rare cases during usb suspend and resume process.
  210214. + */
  210215. + if (low_speed_connection & vbus_is_on) {
  210216. + /*
  210217. + * If value to be set as pwd value is not 0xffffffff,
  210218. + * several 32Khz cycles are needed.
  210219. + */
  210220. + mxs_phy_clock_switch();
  210221. + writel(0xffbfffff, x->io_priv + HW_USBPHY_PWD);
  210222. + } else {
  210223. + writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
  210224. + }
  210225. writel(BM_USBPHY_CTRL_CLKGATE,
  210226. x->io_priv + HW_USBPHY_CTRL_SET);
  210227. clk_disable_unprepare(mxs_phy->clk);
  210228. } else {
  210229. + mxs_phy_clock_switch();
  210230. ret = clk_prepare_enable(mxs_phy->clk);
  210231. if (ret)
  210232. return ret;
  210233. @@ -105,11 +375,28 @@
  210234. return 0;
  210235. }
  210236. +static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled)
  210237. +{
  210238. + struct mxs_phy *mxs_phy = to_mxs_phy(x);
  210239. + u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
  210240. + BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
  210241. + BM_USBPHY_CTRL_ENIDCHG_WKUP;
  210242. + if (enabled) {
  210243. + mxs_phy_disconnect_line(mxs_phy, true);
  210244. + writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET);
  210245. + } else {
  210246. + writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR);
  210247. + mxs_phy_disconnect_line(mxs_phy, false);
  210248. + }
  210249. +
  210250. + return 0;
  210251. +}
  210252. +
  210253. static int mxs_phy_on_connect(struct usb_phy *phy,
  210254. enum usb_device_speed speed)
  210255. {
  210256. - dev_dbg(phy->dev, "%s speed device has connected\n",
  210257. - (speed == USB_SPEED_HIGH) ? "high" : "non-high");
  210258. + dev_dbg(phy->dev, "%s device has connected\n",
  210259. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  210260. if (speed == USB_SPEED_HIGH)
  210261. writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  210262. @@ -121,8 +408,8 @@
  210263. static int mxs_phy_on_disconnect(struct usb_phy *phy,
  210264. enum usb_device_speed speed)
  210265. {
  210266. - dev_dbg(phy->dev, "%s speed device has disconnected\n",
  210267. - (speed == USB_SPEED_HIGH) ? "high" : "non-high");
  210268. + dev_dbg(phy->dev, "%s device has disconnected\n",
  210269. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  210270. if (speed == USB_SPEED_HIGH)
  210271. writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  210272. @@ -131,6 +418,48 @@
  210273. return 0;
  210274. }
  210275. +static int mxs_phy_on_suspend(struct usb_phy *phy,
  210276. + enum usb_device_speed speed)
  210277. +{
  210278. + struct mxs_phy *mxs_phy = to_mxs_phy(phy);
  210279. +
  210280. + dev_dbg(phy->dev, "%s device has suspended\n",
  210281. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  210282. +
  210283. + /* delay 4ms to wait bus entering idle */
  210284. + usleep_range(4000, 5000);
  210285. +
  210286. + if (mxs_phy->data->flags & MXS_PHY_ABNORAML_IN_SUSPEND) {
  210287. + writel_relaxed(0xffffffff, phy->io_priv + HW_USBPHY_PWD);
  210288. + writel_relaxed(0, phy->io_priv + HW_USBPHY_PWD);
  210289. + }
  210290. +
  210291. + if (speed == USB_SPEED_HIGH)
  210292. + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  210293. + phy->io_priv + HW_USBPHY_CTRL_CLR);
  210294. +
  210295. + return 0;
  210296. +}
  210297. +
  210298. +/*
  210299. + * The resume signal must be finished here.
  210300. + */
  210301. +static int mxs_phy_on_resume(struct usb_phy *phy,
  210302. + enum usb_device_speed speed)
  210303. +{
  210304. + dev_dbg(phy->dev, "%s device has resumed\n",
  210305. + (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
  210306. +
  210307. + if (speed == USB_SPEED_HIGH) {
  210308. + /* Make sure the device has switched to High-Speed mode */
  210309. + udelay(500);
  210310. + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
  210311. + phy->io_priv + HW_USBPHY_CTRL_SET);
  210312. + }
  210313. +
  210314. + return 0;
  210315. +}
  210316. +
  210317. static int mxs_phy_probe(struct platform_device *pdev)
  210318. {
  210319. struct resource *res;
  210320. @@ -138,6 +467,9 @@
  210321. struct clk *clk;
  210322. struct mxs_phy *mxs_phy;
  210323. int ret;
  210324. + const struct of_device_id *of_id =
  210325. + of_match_device(mxs_phy_dt_ids, &pdev->dev);
  210326. + struct device_node *np = pdev->dev.of_node;
  210327. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  210328. base = devm_ioremap_resource(&pdev->dev, res);
  210329. @@ -157,6 +489,13 @@
  210330. return -ENOMEM;
  210331. }
  210332. + ret = of_alias_get_id(np, "usbphy");
  210333. + if (ret < 0) {
  210334. + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
  210335. + return ret;
  210336. + }
  210337. + mxs_phy->port_id = ret;
  210338. +
  210339. mxs_phy->phy.io_priv = base;
  210340. mxs_phy->phy.dev = &pdev->dev;
  210341. mxs_phy->phy.label = DRIVER_NAME;
  210342. @@ -166,11 +505,30 @@
  210343. mxs_phy->phy.notify_connect = mxs_phy_on_connect;
  210344. mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect;
  210345. mxs_phy->phy.type = USB_PHY_TYPE_USB2;
  210346. + mxs_phy->phy.set_wakeup = mxs_phy_set_wakeup;
  210347. mxs_phy->clk = clk;
  210348. + mxs_phy->data = of_id->data;
  210349. +
  210350. + if (mxs_phy->data->flags & MXS_PHY_SENDING_SOF_TOO_FAST) {
  210351. + mxs_phy->phy.notify_suspend = mxs_phy_on_suspend;
  210352. + mxs_phy->phy.notify_resume = mxs_phy_on_resume;
  210353. + }
  210354. platform_set_drvdata(pdev, mxs_phy);
  210355. + if (mxs_phy->data->flags & MXS_PHY_HAS_ANATOP) {
  210356. + mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
  210357. + (np, "fsl,anatop");
  210358. + if (IS_ERR(mxs_phy->regmap_anatop)) {
  210359. + dev_dbg(&pdev->dev,
  210360. + "failed to find regmap for anatop\n");
  210361. + return PTR_ERR(mxs_phy->regmap_anatop);
  210362. + }
  210363. + }
  210364. +
  210365. + device_set_wakeup_capable(&pdev->dev, true);
  210366. +
  210367. ret = usb_add_phy_dev(&mxs_phy->phy);
  210368. if (ret)
  210369. return ret;
  210370. @@ -187,11 +545,27 @@
  210371. return 0;
  210372. }
  210373. -static const struct of_device_id mxs_phy_dt_ids[] = {
  210374. - { .compatible = "fsl,imx23-usbphy", },
  210375. - { /* sentinel */ }
  210376. -};
  210377. -MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
  210378. +static int mxs_phy_system_suspend(struct device *dev)
  210379. +{
  210380. + struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
  210381. +
  210382. + if (device_may_wakeup(dev))
  210383. + mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
  210384. +
  210385. + return 0;
  210386. +}
  210387. +
  210388. +static int mxs_phy_system_resume(struct device *dev)
  210389. +{
  210390. + struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
  210391. +
  210392. + if (device_may_wakeup(dev))
  210393. + mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
  210394. +
  210395. + return 0;
  210396. +}
  210397. +
  210398. +SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend, mxs_phy_system_resume);
  210399. static struct platform_driver mxs_phy_driver = {
  210400. .probe = mxs_phy_probe,
  210401. @@ -200,6 +574,7 @@
  210402. .name = DRIVER_NAME,
  210403. .owner = THIS_MODULE,
  210404. .of_match_table = mxs_phy_dt_ids,
  210405. + .pm = &mxs_phy_pm,
  210406. },
  210407. };
  210408. diff -Nur linux-3.14.17/drivers/usb/phy/phy-ulpi.c linux-imx6-3.14/drivers/usb/phy/phy-ulpi.c
  210409. --- linux-3.14.17/drivers/usb/phy/phy-ulpi.c 2014-08-14 03:38:34.000000000 +0200
  210410. +++ linux-imx6-3.14/drivers/usb/phy/phy-ulpi.c 2014-09-11 18:06:09.254066936 +0200
  210411. @@ -48,6 +48,7 @@
  210412. ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"),
  210413. ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"),
  210414. ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"),
  210415. + ULPI_INFO(ULPI_ID(0x0424, 0x0009), "SMSC USB334x"),
  210416. ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"),
  210417. };
  210418. diff -Nur linux-3.14.17/drivers/usb/serial/option.c linux-imx6-3.14/drivers/usb/serial/option.c
  210419. --- linux-3.14.17/drivers/usb/serial/option.c 2014-08-14 03:38:34.000000000 +0200
  210420. +++ linux-imx6-3.14/drivers/usb/serial/option.c 2014-09-11 18:06:09.274067016 +0200
  210421. @@ -1917,6 +1917,8 @@
  210422. dev_dbg(dev, "%s: type %x req %x\n", __func__,
  210423. req_pkt->bRequestType, req_pkt->bRequest);
  210424. }
  210425. + } else if (status == -ENOENT || status == -ESHUTDOWN) {
  210426. + dev_dbg(dev, "%s: urb stopped: %d\n", __func__, status);
  210427. } else
  210428. dev_err(dev, "%s: error %d\n", __func__, status);
  210429. diff -Nur linux-3.14.17/drivers/video/amba-clcd.c linux-imx6-3.14/drivers/video/amba-clcd.c
  210430. --- linux-3.14.17/drivers/video/amba-clcd.c 2014-08-14 03:38:34.000000000 +0200
  210431. +++ linux-imx6-3.14/drivers/video/amba-clcd.c 2014-09-11 18:06:09.354067336 +0200
  210432. @@ -17,7 +17,10 @@
  210433. #include <linux/string.h>
  210434. #include <linux/slab.h>
  210435. #include <linux/delay.h>
  210436. +#include <linux/dma-mapping.h>
  210437. +#include <linux/memblock.h>
  210438. #include <linux/mm.h>
  210439. +#include <linux/of.h>
  210440. #include <linux/fb.h>
  210441. #include <linux/init.h>
  210442. #include <linux/ioport.h>
  210443. @@ -31,8 +34,20 @@
  210444. #define to_clcd(info) container_of(info, struct clcd_fb, fb)
  210445. +#ifdef CONFIG_ARM
  210446. +#define clcdfb_dma_alloc dma_alloc_writecombine
  210447. +#define clcdfb_dma_free dma_free_writecombine
  210448. +#define clcdfb_dma_mmap dma_mmap_writecombine
  210449. +#else
  210450. +#define clcdfb_dma_alloc dma_alloc_coherent
  210451. +#define clcdfb_dma_free dma_free_coherent
  210452. +#define clcdfb_dma_mmap dma_mmap_coherent
  210453. +#endif
  210454. +
  210455. /* This is limited to 16 characters when displayed by X startup */
  210456. static const char *clcd_name = "CLCD FB";
  210457. +static char *def_mode;
  210458. +module_param_named(mode, def_mode, charp, 0);
  210459. /*
  210460. * Unfortunately, the enable/disable functions may be called either from
  210461. @@ -234,6 +249,17 @@
  210462. bgr = caps & CLCD_CAP_BGR && var->blue.offset == 0;
  210463. rgb = caps & CLCD_CAP_RGB && var->red.offset == 0;
  210464. + /*
  210465. + * Seems that for 32-bit mode there is confusion about RGB
  210466. + * ordering somewhere between user-side, kernel and hardware.
  210467. + * The following hack seems get things working, at least on
  210468. + * vexpress hardware and models...
  210469. + */
  210470. + if (var->bits_per_pixel == 32) {
  210471. + bgr = false;
  210472. + rgb = true;
  210473. + }
  210474. +
  210475. if (!bgr && !rgb)
  210476. /*
  210477. * The requested format was not possible, try just
  210478. @@ -393,6 +419,44 @@
  210479. return 0;
  210480. }
  210481. +int clcdfb_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
  210482. +{
  210483. + return clcdfb_dma_mmap(&fb->dev->dev, vma,
  210484. + fb->fb.screen_base,
  210485. + fb->fb.fix.smem_start,
  210486. + fb->fb.fix.smem_len);
  210487. +}
  210488. +
  210489. +int clcdfb_mmap_io(struct clcd_fb *fb, struct vm_area_struct *vma)
  210490. +{
  210491. + unsigned long user_count, count, pfn, off;
  210492. +
  210493. + user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
  210494. + count = PAGE_ALIGN(fb->fb.fix.smem_len) >> PAGE_SHIFT;
  210495. + pfn = fb->fb.fix.smem_start >> PAGE_SHIFT;
  210496. + off = vma->vm_pgoff;
  210497. +
  210498. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  210499. +
  210500. + if (off < count && user_count <= (count - off))
  210501. + return remap_pfn_range(vma, vma->vm_start, pfn + off,
  210502. + user_count << PAGE_SHIFT,
  210503. + vma->vm_page_prot);
  210504. +
  210505. + return -ENXIO;
  210506. +}
  210507. +
  210508. +void clcdfb_remove_dma(struct clcd_fb *fb)
  210509. +{
  210510. + clcdfb_dma_free(&fb->dev->dev, fb->fb.fix.smem_len,
  210511. + fb->fb.screen_base, fb->fb.fix.smem_start);
  210512. +}
  210513. +
  210514. +void clcdfb_remove_io(struct clcd_fb *fb)
  210515. +{
  210516. + iounmap(fb->fb.screen_base);
  210517. +}
  210518. +
  210519. static int clcdfb_mmap(struct fb_info *info,
  210520. struct vm_area_struct *vma)
  210521. {
  210522. @@ -543,14 +607,247 @@
  210523. return ret;
  210524. }
  210525. +struct string_lookup {
  210526. + const char *string;
  210527. + const u32 val;
  210528. +};
  210529. +
  210530. +static struct string_lookup vmode_lookups[] = {
  210531. + { "FB_VMODE_NONINTERLACED", FB_VMODE_NONINTERLACED},
  210532. + { "FB_VMODE_INTERLACED", FB_VMODE_INTERLACED},
  210533. + { "FB_VMODE_DOUBLE", FB_VMODE_DOUBLE},
  210534. + { "FB_VMODE_ODD_FLD_FIRST", FB_VMODE_ODD_FLD_FIRST},
  210535. + { NULL, 0 },
  210536. +};
  210537. +
  210538. +static struct string_lookup tim2_lookups[] = {
  210539. + { "TIM2_CLKSEL", TIM2_CLKSEL},
  210540. + { "TIM2_IVS", TIM2_IVS},
  210541. + { "TIM2_IHS", TIM2_IHS},
  210542. + { "TIM2_IPC", TIM2_IPC},
  210543. + { "TIM2_IOE", TIM2_IOE},
  210544. + { "TIM2_BCD", TIM2_BCD},
  210545. + { NULL, 0},
  210546. +};
  210547. +static struct string_lookup cntl_lookups[] = {
  210548. + {"CNTL_LCDEN", CNTL_LCDEN},
  210549. + {"CNTL_LCDBPP1", CNTL_LCDBPP1},
  210550. + {"CNTL_LCDBPP2", CNTL_LCDBPP2},
  210551. + {"CNTL_LCDBPP4", CNTL_LCDBPP4},
  210552. + {"CNTL_LCDBPP8", CNTL_LCDBPP8},
  210553. + {"CNTL_LCDBPP16", CNTL_LCDBPP16},
  210554. + {"CNTL_LCDBPP16_565", CNTL_LCDBPP16_565},
  210555. + {"CNTL_LCDBPP16_444", CNTL_LCDBPP16_444},
  210556. + {"CNTL_LCDBPP24", CNTL_LCDBPP24},
  210557. + {"CNTL_LCDBW", CNTL_LCDBW},
  210558. + {"CNTL_LCDTFT", CNTL_LCDTFT},
  210559. + {"CNTL_LCDMONO8", CNTL_LCDMONO8},
  210560. + {"CNTL_LCDDUAL", CNTL_LCDDUAL},
  210561. + {"CNTL_BGR", CNTL_BGR},
  210562. + {"CNTL_BEBO", CNTL_BEBO},
  210563. + {"CNTL_BEPO", CNTL_BEPO},
  210564. + {"CNTL_LCDPWR", CNTL_LCDPWR},
  210565. + {"CNTL_LCDVCOMP(1)", CNTL_LCDVCOMP(1)},
  210566. + {"CNTL_LCDVCOMP(2)", CNTL_LCDVCOMP(2)},
  210567. + {"CNTL_LCDVCOMP(3)", CNTL_LCDVCOMP(3)},
  210568. + {"CNTL_LCDVCOMP(4)", CNTL_LCDVCOMP(4)},
  210569. + {"CNTL_LCDVCOMP(5)", CNTL_LCDVCOMP(5)},
  210570. + {"CNTL_LCDVCOMP(6)", CNTL_LCDVCOMP(6)},
  210571. + {"CNTL_LCDVCOMP(7)", CNTL_LCDVCOMP(7)},
  210572. + {"CNTL_LDMAFIFOTIME", CNTL_LDMAFIFOTIME},
  210573. + {"CNTL_WATERMARK", CNTL_WATERMARK},
  210574. + { NULL, 0},
  210575. +};
  210576. +static struct string_lookup caps_lookups[] = {
  210577. + {"CLCD_CAP_RGB444", CLCD_CAP_RGB444},
  210578. + {"CLCD_CAP_RGB5551", CLCD_CAP_RGB5551},
  210579. + {"CLCD_CAP_RGB565", CLCD_CAP_RGB565},
  210580. + {"CLCD_CAP_RGB888", CLCD_CAP_RGB888},
  210581. + {"CLCD_CAP_BGR444", CLCD_CAP_BGR444},
  210582. + {"CLCD_CAP_BGR5551", CLCD_CAP_BGR5551},
  210583. + {"CLCD_CAP_BGR565", CLCD_CAP_BGR565},
  210584. + {"CLCD_CAP_BGR888", CLCD_CAP_BGR888},
  210585. + {"CLCD_CAP_444", CLCD_CAP_444},
  210586. + {"CLCD_CAP_5551", CLCD_CAP_5551},
  210587. + {"CLCD_CAP_565", CLCD_CAP_565},
  210588. + {"CLCD_CAP_888", CLCD_CAP_888},
  210589. + {"CLCD_CAP_RGB", CLCD_CAP_RGB},
  210590. + {"CLCD_CAP_BGR", CLCD_CAP_BGR},
  210591. + {"CLCD_CAP_ALL", CLCD_CAP_ALL},
  210592. + { NULL, 0},
  210593. +};
  210594. +
  210595. +u32 parse_setting(struct string_lookup *lookup, const char *name)
  210596. +{
  210597. + int i = 0;
  210598. + while (lookup[i].string != NULL) {
  210599. + if (strcmp(lookup[i].string, name) == 0)
  210600. + return lookup[i].val;
  210601. + ++i;
  210602. + }
  210603. + return -EINVAL;
  210604. +}
  210605. +
  210606. +u32 get_string_lookup(struct device_node *node, const char *name,
  210607. + struct string_lookup *lookup)
  210608. +{
  210609. + const char *string;
  210610. + int count, i, ret = 0;
  210611. +
  210612. + count = of_property_count_strings(node, name);
  210613. + if (count >= 0)
  210614. + for (i = 0; i < count; i++)
  210615. + if (of_property_read_string_index(node, name, i,
  210616. + &string) == 0)
  210617. + ret |= parse_setting(lookup, string);
  210618. + return ret;
  210619. +}
  210620. +
  210621. +int get_val(struct device_node *node, const char *string)
  210622. +{
  210623. + u32 ret = 0;
  210624. +
  210625. + if (of_property_read_u32(node, string, &ret))
  210626. + ret = -1;
  210627. + return ret;
  210628. +}
  210629. +
  210630. +struct clcd_panel *getPanel(struct device_node *node)
  210631. +{
  210632. + static struct clcd_panel panel;
  210633. +
  210634. + panel.mode.refresh = get_val(node, "refresh");
  210635. + panel.mode.xres = get_val(node, "xres");
  210636. + panel.mode.yres = get_val(node, "yres");
  210637. + panel.mode.pixclock = get_val(node, "pixclock");
  210638. + panel.mode.left_margin = get_val(node, "left_margin");
  210639. + panel.mode.right_margin = get_val(node, "right_margin");
  210640. + panel.mode.upper_margin = get_val(node, "upper_margin");
  210641. + panel.mode.lower_margin = get_val(node, "lower_margin");
  210642. + panel.mode.hsync_len = get_val(node, "hsync_len");
  210643. + panel.mode.vsync_len = get_val(node, "vsync_len");
  210644. + panel.mode.sync = get_val(node, "sync");
  210645. + panel.bpp = get_val(node, "bpp");
  210646. + panel.width = (signed short) get_val(node, "width");
  210647. + panel.height = (signed short) get_val(node, "height");
  210648. +
  210649. + panel.mode.vmode = get_string_lookup(node, "vmode", vmode_lookups);
  210650. + panel.tim2 = get_string_lookup(node, "tim2", tim2_lookups);
  210651. + panel.cntl = get_string_lookup(node, "cntl", cntl_lookups);
  210652. + panel.caps = get_string_lookup(node, "caps", caps_lookups);
  210653. +
  210654. + return &panel;
  210655. +}
  210656. +
  210657. +struct clcd_panel *clcdfb_get_panel(const char *name)
  210658. +{
  210659. + struct device_node *node = NULL;
  210660. + const char *mode;
  210661. + struct clcd_panel *panel = NULL;
  210662. +
  210663. + do {
  210664. + node = of_find_compatible_node(node, NULL, "panel");
  210665. + if (node)
  210666. + if (of_property_read_string(node, "mode", &mode) == 0)
  210667. + if (strcmp(mode, name) == 0) {
  210668. + panel = getPanel(node);
  210669. + panel->mode.name = name;
  210670. + }
  210671. + } while (node != NULL);
  210672. +
  210673. + return panel;
  210674. +}
  210675. +
  210676. +#ifdef CONFIG_OF
  210677. +static int clcdfb_dt_init(struct clcd_fb *fb)
  210678. +{
  210679. + int err = 0;
  210680. + struct device_node *node;
  210681. + const char *mode;
  210682. + dma_addr_t dma;
  210683. + u32 use_dma;
  210684. + const __be32 *prop;
  210685. + int len, na, ns;
  210686. + phys_addr_t fb_base, fb_size;
  210687. +
  210688. + node = fb->dev->dev.of_node;
  210689. + if (!node)
  210690. + return -ENODEV;
  210691. +
  210692. + na = of_n_addr_cells(node);
  210693. + ns = of_n_size_cells(node);
  210694. +
  210695. + if (def_mode && strlen(def_mode) > 0) {
  210696. + fb->panel = clcdfb_get_panel(def_mode);
  210697. + if (!fb->panel)
  210698. + printk(KERN_ERR "CLCD: invalid mode specified on the command line (%s)\n", def_mode);
  210699. + }
  210700. +
  210701. + if (!fb->panel) {
  210702. + if (WARN_ON(of_property_read_string(node, "mode", &mode)))
  210703. + return -ENODEV;
  210704. + fb->panel = clcdfb_get_panel(mode);
  210705. + }
  210706. +
  210707. + if (!fb->panel)
  210708. + return -EINVAL;
  210709. + fb->fb.fix.smem_len = fb->panel->mode.xres * fb->panel->mode.yres * 4;
  210710. +
  210711. + fb->board->name = "Device Tree CLCD PL111";
  210712. + fb->board->caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888;
  210713. + fb->board->check = clcdfb_check;
  210714. + fb->board->decode = clcdfb_decode;
  210715. +
  210716. + if (of_property_read_u32(node, "use_dma", &use_dma))
  210717. + use_dma = 0;
  210718. +
  210719. + if (use_dma) {
  210720. + fb->fb.screen_base = clcdfb_dma_alloc(&fb->dev->dev,
  210721. + fb->fb.fix.smem_len,
  210722. + &dma, GFP_KERNEL);
  210723. + if (!fb->fb.screen_base) {
  210724. + pr_err("CLCD: unable to map framebuffer\n");
  210725. + return -ENOMEM;
  210726. + }
  210727. +
  210728. + fb->fb.fix.smem_start = dma;
  210729. + fb->board->mmap = clcdfb_mmap_dma;
  210730. + fb->board->remove = clcdfb_remove_dma;
  210731. + } else {
  210732. + prop = of_get_property(node, "framebuffer", &len);
  210733. + if (WARN_ON(!prop || len < (na + ns) * sizeof(*prop)))
  210734. + return -EINVAL;
  210735. +
  210736. + fb_base = of_read_number(prop, na);
  210737. + fb_size = of_read_number(prop + na, ns);
  210738. +
  210739. + fb->fb.fix.smem_start = fb_base;
  210740. + fb->fb.screen_base = ioremap_wc(fb_base, fb_size);
  210741. + fb->board->mmap = clcdfb_mmap_io;
  210742. + fb->board->remove = clcdfb_remove_io;
  210743. + }
  210744. +
  210745. + return err;
  210746. +}
  210747. +#endif /* CONFIG_OF */
  210748. +
  210749. static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
  210750. {
  210751. struct clcd_board *board = dev_get_platdata(&dev->dev);
  210752. struct clcd_fb *fb;
  210753. int ret;
  210754. - if (!board)
  210755. - return -EINVAL;
  210756. + if (!board) {
  210757. +#ifdef CONFIG_OF
  210758. + if (dev->dev.of_node) {
  210759. + board = kzalloc(sizeof(struct clcd_board), GFP_KERNEL);
  210760. + if (!board)
  210761. + return -ENOMEM;
  210762. + board->setup = clcdfb_dt_init;
  210763. + } else
  210764. +#endif
  210765. + return -EINVAL;
  210766. + }
  210767. ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
  210768. if (ret)
  210769. diff -Nur linux-3.14.17/drivers/video/arm-hdlcd.c linux-imx6-3.14/drivers/video/arm-hdlcd.c
  210770. --- linux-3.14.17/drivers/video/arm-hdlcd.c 1970-01-01 01:00:00.000000000 +0100
  210771. +++ linux-imx6-3.14/drivers/video/arm-hdlcd.c 2014-09-11 18:06:09.354067336 +0200
  210772. @@ -0,0 +1,844 @@
  210773. +/*
  210774. + * drivers/video/arm-hdlcd.c
  210775. + *
  210776. + * Copyright (C) 2011 ARM Limited
  210777. + *
  210778. + * This file is subject to the terms and conditions of the GNU General Public
  210779. + * License. See the file COPYING in the main directory of this archive
  210780. + * for more details.
  210781. + *
  210782. + * ARM HDLCD Controller
  210783. + */
  210784. +
  210785. +#include <linux/module.h>
  210786. +#include <linux/kernel.h>
  210787. +#include <linux/errno.h>
  210788. +#include <linux/string.h>
  210789. +#include <linux/ctype.h>
  210790. +#include <linux/mm.h>
  210791. +#include <linux/delay.h>
  210792. +#include <linux/of.h>
  210793. +#include <linux/fb.h>
  210794. +#include <linux/clk.h>
  210795. +#include <linux/init.h>
  210796. +#include <linux/interrupt.h>
  210797. +#include <linux/ioport.h>
  210798. +#include <linux/dma-mapping.h>
  210799. +#include <linux/platform_device.h>
  210800. +#include <linux/memblock.h>
  210801. +#include <linux/arm-hdlcd.h>
  210802. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  210803. +#include <linux/proc_fs.h>
  210804. +#include <linux/seq_file.h>
  210805. +#endif
  210806. +
  210807. +#include "edid.h"
  210808. +
  210809. +#ifdef CONFIG_SERIAL_AMBA_PCU_UART
  210810. +int get_edid(u8 *msgbuf);
  210811. +#else
  210812. +#endif
  210813. +
  210814. +#define to_hdlcd_device(info) container_of(info, struct hdlcd_device, fb)
  210815. +
  210816. +static struct of_device_id hdlcd_of_matches[] = {
  210817. + { .compatible = "arm,hdlcd" },
  210818. + {},
  210819. +};
  210820. +
  210821. +/* Framebuffer size. */
  210822. +static unsigned long framebuffer_size;
  210823. +
  210824. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  210825. +static unsigned long buffer_underrun_events;
  210826. +static DEFINE_SPINLOCK(hdlcd_underrun_lock);
  210827. +
  210828. +static void hdlcd_underrun_set(unsigned long val)
  210829. +{
  210830. + spin_lock(&hdlcd_underrun_lock);
  210831. + buffer_underrun_events = val;
  210832. + spin_unlock(&hdlcd_underrun_lock);
  210833. +}
  210834. +
  210835. +static unsigned long hdlcd_underrun_get(void)
  210836. +{
  210837. + unsigned long val;
  210838. + spin_lock(&hdlcd_underrun_lock);
  210839. + val = buffer_underrun_events;
  210840. + spin_unlock(&hdlcd_underrun_lock);
  210841. + return val;
  210842. +}
  210843. +
  210844. +#ifdef CONFIG_PROC_FS
  210845. +static int hdlcd_underrun_show(struct seq_file *m, void *v)
  210846. +{
  210847. + unsigned char underrun_string[32];
  210848. + snprintf(underrun_string, 32, "%lu\n", hdlcd_underrun_get());
  210849. + seq_puts(m, underrun_string);
  210850. + return 0;
  210851. +}
  210852. +
  210853. +static int proc_hdlcd_underrun_open(struct inode *inode, struct file *file)
  210854. +{
  210855. + return single_open(file, hdlcd_underrun_show, NULL);
  210856. +}
  210857. +
  210858. +static const struct file_operations proc_hdlcd_underrun_operations = {
  210859. + .open = proc_hdlcd_underrun_open,
  210860. + .read = seq_read,
  210861. + .llseek = seq_lseek,
  210862. + .release = single_release,
  210863. +};
  210864. +
  210865. +static int hdlcd_underrun_init(void)
  210866. +{
  210867. + hdlcd_underrun_set(0);
  210868. + proc_create("hdlcd_underrun", 0, NULL, &proc_hdlcd_underrun_operations);
  210869. + return 0;
  210870. +}
  210871. +static void hdlcd_underrun_close(void)
  210872. +{
  210873. + remove_proc_entry("hdlcd_underrun", NULL);
  210874. +}
  210875. +#else
  210876. +static int hdlcd_underrun_init(void) { return 0; }
  210877. +static void hdlcd_underrun_close(void) { }
  210878. +#endif
  210879. +#endif
  210880. +
  210881. +static char *fb_mode = "1680x1050-32@60\0\0\0\0\0";
  210882. +
  210883. +static struct fb_var_screeninfo cached_var_screeninfo;
  210884. +
  210885. +static struct fb_videomode hdlcd_default_mode = {
  210886. + .refresh = 60,
  210887. + .xres = 1680,
  210888. + .yres = 1050,
  210889. + .pixclock = 8403,
  210890. + .left_margin = 80,
  210891. + .right_margin = 48,
  210892. + .upper_margin = 21,
  210893. + .lower_margin = 3,
  210894. + .hsync_len = 32,
  210895. + .vsync_len = 6,
  210896. + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  210897. + .vmode = FB_VMODE_NONINTERLACED
  210898. +};
  210899. +
  210900. +static inline void hdlcd_enable(struct hdlcd_device *hdlcd)
  210901. +{
  210902. + dev_dbg(hdlcd->dev, "HDLCD: output enabled\n");
  210903. + writel(1, hdlcd->base + HDLCD_REG_COMMAND);
  210904. +}
  210905. +
  210906. +static inline void hdlcd_disable(struct hdlcd_device *hdlcd)
  210907. +{
  210908. + dev_dbg(hdlcd->dev, "HDLCD: output disabled\n");
  210909. + writel(0, hdlcd->base + HDLCD_REG_COMMAND);
  210910. +}
  210911. +
  210912. +static int hdlcd_set_bitfields(struct hdlcd_device *hdlcd,
  210913. + struct fb_var_screeninfo *var)
  210914. +{
  210915. + int ret = 0;
  210916. +
  210917. + memset(&var->transp, 0, sizeof(var->transp));
  210918. + var->red.msb_right = 0;
  210919. + var->green.msb_right = 0;
  210920. + var->blue.msb_right = 0;
  210921. + var->blue.offset = 0;
  210922. +
  210923. + switch (var->bits_per_pixel) {
  210924. + case 8:
  210925. + /* pseudocolor */
  210926. + var->red.length = 8;
  210927. + var->green.length = 8;
  210928. + var->blue.length = 8;
  210929. + break;
  210930. + case 16:
  210931. + /* 565 format */
  210932. + var->red.length = 5;
  210933. + var->green.length = 6;
  210934. + var->blue.length = 5;
  210935. + break;
  210936. + case 32:
  210937. + var->transp.length = 8;
  210938. + case 24:
  210939. + var->red.length = 8;
  210940. + var->green.length = 8;
  210941. + var->blue.length = 8;
  210942. + break;
  210943. + default:
  210944. + ret = -EINVAL;
  210945. + break;
  210946. + }
  210947. +
  210948. + if (!ret) {
  210949. + if(var->bits_per_pixel != 32)
  210950. + {
  210951. + var->green.offset = var->blue.length;
  210952. + var->red.offset = var->green.offset + var->green.length;
  210953. + }
  210954. + else
  210955. + {
  210956. + /* Previously, the byte ordering for 32-bit color was
  210957. + * (msb)<alpha><red><green><blue>(lsb)
  210958. + * but this does not match what android expects and
  210959. + * the colors are odd. Instead, use
  210960. + * <alpha><blue><green><red>
  210961. + * Since we tell fb what we are doing, console
  210962. + * , X and directfb access should work fine.
  210963. + */
  210964. + var->green.offset = var->red.length;
  210965. + var->blue.offset = var->green.offset + var->green.length;
  210966. + var->transp.offset = var->blue.offset + var->blue.length;
  210967. + }
  210968. + }
  210969. +
  210970. + return ret;
  210971. +}
  210972. +
  210973. +static int hdlcd_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  210974. +{
  210975. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  210976. + int bytes_per_pixel = var->bits_per_pixel / 8;
  210977. +
  210978. +#ifdef HDLCD_NO_VIRTUAL_SCREEN
  210979. + var->yres_virtual = var->yres;
  210980. +#else
  210981. + var->yres_virtual = 2 * var->yres;
  210982. +#endif
  210983. +
  210984. + if ((var->xres_virtual * bytes_per_pixel * var->yres_virtual) > hdlcd->fb.fix.smem_len)
  210985. + return -ENOMEM;
  210986. +
  210987. + if (var->xres > HDLCD_MAX_XRES || var->yres > HDLCD_MAX_YRES)
  210988. + return -EINVAL;
  210989. +
  210990. + /* make sure the bitfields are set appropriately */
  210991. + return hdlcd_set_bitfields(hdlcd, var);
  210992. +}
  210993. +
  210994. +/* prototype */
  210995. +static int hdlcd_pan_display(struct fb_var_screeninfo *var,
  210996. + struct fb_info *info);
  210997. +
  210998. +#define WRITE_HDLCD_REG(reg, value) writel((value), hdlcd->base + (reg))
  210999. +#define READ_HDLCD_REG(reg) readl(hdlcd->base + (reg))
  211000. +
  211001. +static int hdlcd_set_par(struct fb_info *info)
  211002. +{
  211003. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  211004. + int bytes_per_pixel = hdlcd->fb.var.bits_per_pixel / 8;
  211005. + int polarities;
  211006. + int old_yoffset;
  211007. +
  211008. + /* check for shortcuts */
  211009. + old_yoffset = cached_var_screeninfo.yoffset;
  211010. + cached_var_screeninfo.yoffset = info->var.yoffset;
  211011. + if (!memcmp(&info->var, &cached_var_screeninfo,
  211012. + sizeof(struct fb_var_screeninfo))) {
  211013. + if(old_yoffset != info->var.yoffset) {
  211014. + /* we only changed yoffset, and we already
  211015. + * already recorded it a couple lines up
  211016. + */
  211017. + hdlcd_pan_display(&info->var, info);
  211018. + }
  211019. + /* or no change */
  211020. + return 0;
  211021. + }
  211022. +
  211023. + hdlcd->fb.fix.line_length = hdlcd->fb.var.xres * bytes_per_pixel;
  211024. +
  211025. + if (hdlcd->fb.var.bits_per_pixel >= 16)
  211026. + hdlcd->fb.fix.visual = FB_VISUAL_TRUECOLOR;
  211027. + else
  211028. + hdlcd->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
  211029. +
  211030. + memcpy(&cached_var_screeninfo, &info->var, sizeof(struct fb_var_screeninfo));
  211031. +
  211032. + polarities = HDLCD_POLARITY_DATAEN |
  211033. +#ifndef CONFIG_ARCH_TUSCAN
  211034. + HDLCD_POLARITY_PIXELCLK |
  211035. +#endif
  211036. + HDLCD_POLARITY_DATA;
  211037. + polarities |= (hdlcd->fb.var.sync & FB_SYNC_HOR_HIGH_ACT) ? HDLCD_POLARITY_HSYNC : 0;
  211038. + polarities |= (hdlcd->fb.var.sync & FB_SYNC_VERT_HIGH_ACT) ? HDLCD_POLARITY_VSYNC : 0;
  211039. +
  211040. + hdlcd_disable(hdlcd);
  211041. +
  211042. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_LENGTH, hdlcd->fb.var.xres * bytes_per_pixel);
  211043. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_PITCH, hdlcd->fb.var.xres * bytes_per_pixel);
  211044. + WRITE_HDLCD_REG(HDLCD_REG_FB_LINE_COUNT, hdlcd->fb.var.yres - 1);
  211045. + WRITE_HDLCD_REG(HDLCD_REG_V_SYNC, hdlcd->fb.var.vsync_len - 1);
  211046. + WRITE_HDLCD_REG(HDLCD_REG_V_BACK_PORCH, hdlcd->fb.var.upper_margin - 1);
  211047. + WRITE_HDLCD_REG(HDLCD_REG_V_DATA, hdlcd->fb.var.yres - 1);
  211048. + WRITE_HDLCD_REG(HDLCD_REG_V_FRONT_PORCH, hdlcd->fb.var.lower_margin - 1);
  211049. + WRITE_HDLCD_REG(HDLCD_REG_H_SYNC, hdlcd->fb.var.hsync_len - 1);
  211050. + WRITE_HDLCD_REG(HDLCD_REG_H_BACK_PORCH, hdlcd->fb.var.left_margin - 1);
  211051. + WRITE_HDLCD_REG(HDLCD_REG_H_DATA, hdlcd->fb.var.xres - 1);
  211052. + WRITE_HDLCD_REG(HDLCD_REG_H_FRONT_PORCH, hdlcd->fb.var.right_margin - 1);
  211053. + WRITE_HDLCD_REG(HDLCD_REG_POLARITIES, polarities);
  211054. + WRITE_HDLCD_REG(HDLCD_REG_PIXEL_FORMAT, (bytes_per_pixel - 1) << 3);
  211055. +#ifdef HDLCD_RED_DEFAULT_COLOUR
  211056. + WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, (0x00ff0000 | (hdlcd->fb.var.red.length & 0xf) << 8) \
  211057. + | hdlcd->fb.var.red.offset);
  211058. +#else
  211059. + WRITE_HDLCD_REG(HDLCD_REG_RED_SELECT, ((hdlcd->fb.var.red.length & 0xf) << 8) | hdlcd->fb.var.red.offset);
  211060. +#endif
  211061. + WRITE_HDLCD_REG(HDLCD_REG_GREEN_SELECT, ((hdlcd->fb.var.green.length & 0xf) << 8) | hdlcd->fb.var.green.offset);
  211062. + WRITE_HDLCD_REG(HDLCD_REG_BLUE_SELECT, ((hdlcd->fb.var.blue.length & 0xf) << 8) | hdlcd->fb.var.blue.offset);
  211063. +
  211064. + clk_set_rate(hdlcd->clk, (1000000000 / hdlcd->fb.var.pixclock) * 1000);
  211065. + clk_enable(hdlcd->clk);
  211066. +
  211067. + hdlcd_enable(hdlcd);
  211068. +
  211069. + return 0;
  211070. +}
  211071. +
  211072. +static int hdlcd_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
  211073. + unsigned int blue, unsigned int transp, struct fb_info *info)
  211074. +{
  211075. + if (regno < 16) {
  211076. + u32 *pal = info->pseudo_palette;
  211077. +
  211078. + pal[regno] = ((red >> 8) << info->var.red.offset) |
  211079. + ((green >> 8) << info->var.green.offset) |
  211080. + ((blue >> 8) << info->var.blue.offset);
  211081. + }
  211082. +
  211083. + return 0;
  211084. +}
  211085. +
  211086. +static irqreturn_t hdlcd_irq(int irq, void *data)
  211087. +{
  211088. + struct hdlcd_device *hdlcd = data;
  211089. + unsigned long irq_mask, irq_status;
  211090. +
  211091. + irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
  211092. + irq_status = READ_HDLCD_REG(HDLCD_REG_INT_STATUS);
  211093. +
  211094. + /* acknowledge interrupt(s) */
  211095. + WRITE_HDLCD_REG(HDLCD_REG_INT_CLEAR, irq_status);
  211096. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  211097. + if (irq_status & HDLCD_INTERRUPT_UNDERRUN) {
  211098. + /* increment the count */
  211099. + hdlcd_underrun_set(hdlcd_underrun_get() + 1);
  211100. + }
  211101. +#endif
  211102. + if (irq_status & HDLCD_INTERRUPT_VSYNC) {
  211103. + /* disable future VSYNC interrupts */
  211104. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask & ~HDLCD_INTERRUPT_VSYNC);
  211105. +
  211106. + complete(&hdlcd->vsync_completion);
  211107. + }
  211108. +
  211109. + return IRQ_HANDLED;
  211110. +}
  211111. +
  211112. +static int hdlcd_wait_for_vsync(struct fb_info *info)
  211113. +{
  211114. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  211115. + unsigned long irq_mask;
  211116. + int err;
  211117. +
  211118. + /* enable VSYNC interrupt */
  211119. + irq_mask = READ_HDLCD_REG(HDLCD_REG_INT_MASK);
  211120. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, irq_mask | HDLCD_INTERRUPT_VSYNC);
  211121. +
  211122. + err = wait_for_completion_interruptible_timeout(&hdlcd->vsync_completion,
  211123. + msecs_to_jiffies(100));
  211124. +
  211125. + if (!err)
  211126. + return -ETIMEDOUT;
  211127. +
  211128. + return 0;
  211129. +}
  211130. +
  211131. +static int hdlcd_blank(int blank_mode, struct fb_info *info)
  211132. +{
  211133. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  211134. +
  211135. + switch (blank_mode) {
  211136. + case FB_BLANK_POWERDOWN:
  211137. + clk_disable(hdlcd->clk);
  211138. + case FB_BLANK_NORMAL:
  211139. + hdlcd_disable(hdlcd);
  211140. + break;
  211141. + case FB_BLANK_UNBLANK:
  211142. + clk_enable(hdlcd->clk);
  211143. + hdlcd_enable(hdlcd);
  211144. + break;
  211145. + case FB_BLANK_VSYNC_SUSPEND:
  211146. + case FB_BLANK_HSYNC_SUSPEND:
  211147. + default:
  211148. + return 1;
  211149. + }
  211150. +
  211151. + return 0;
  211152. +}
  211153. +
  211154. +static void hdlcd_mmap_open(struct vm_area_struct *vma)
  211155. +{
  211156. +}
  211157. +
  211158. +static void hdlcd_mmap_close(struct vm_area_struct *vma)
  211159. +{
  211160. +}
  211161. +
  211162. +static struct vm_operations_struct hdlcd_mmap_ops = {
  211163. + .open = hdlcd_mmap_open,
  211164. + .close = hdlcd_mmap_close,
  211165. +};
  211166. +
  211167. +static int hdlcd_mmap(struct fb_info *info, struct vm_area_struct *vma)
  211168. +{
  211169. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  211170. + unsigned long off;
  211171. + unsigned long start;
  211172. + unsigned long len = hdlcd->fb.fix.smem_len;
  211173. +
  211174. + if (vma->vm_end - vma->vm_start == 0)
  211175. + return 0;
  211176. + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
  211177. + return -EINVAL;
  211178. +
  211179. + off = vma->vm_pgoff << PAGE_SHIFT;
  211180. + if ((off >= len) || (vma->vm_end - vma->vm_start + off) > len)
  211181. + return -EINVAL;
  211182. +
  211183. + start = hdlcd->fb.fix.smem_start;
  211184. + off += start;
  211185. +
  211186. + vma->vm_pgoff = off >> PAGE_SHIFT;
  211187. + vma->vm_flags |= VM_IO;
  211188. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  211189. + vma->vm_ops = &hdlcd_mmap_ops;
  211190. + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
  211191. + vma->vm_end - vma->vm_start,
  211192. + vma->vm_page_prot))
  211193. + return -EAGAIN;
  211194. +
  211195. + return 0;
  211196. +}
  211197. +
  211198. +static int hdlcd_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
  211199. +{
  211200. + struct hdlcd_device *hdlcd = to_hdlcd_device(info);
  211201. +
  211202. + hdlcd->fb.var.yoffset = var->yoffset;
  211203. + WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start +
  211204. + (var->yoffset * hdlcd->fb.fix.line_length));
  211205. +
  211206. + hdlcd_wait_for_vsync(info);
  211207. +
  211208. + return 0;
  211209. +}
  211210. +
  211211. +static int hdlcd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  211212. +{
  211213. + int err;
  211214. +
  211215. + switch (cmd) {
  211216. + case FBIO_WAITFORVSYNC:
  211217. + err = hdlcd_wait_for_vsync(info);
  211218. + break;
  211219. + default:
  211220. + err = -ENOIOCTLCMD;
  211221. + break;
  211222. + }
  211223. +
  211224. + return err;
  211225. +}
  211226. +
  211227. +static struct fb_ops hdlcd_ops = {
  211228. + .owner = THIS_MODULE,
  211229. + .fb_check_var = hdlcd_check_var,
  211230. + .fb_set_par = hdlcd_set_par,
  211231. + .fb_setcolreg = hdlcd_setcolreg,
  211232. + .fb_blank = hdlcd_blank,
  211233. + .fb_fillrect = cfb_fillrect,
  211234. + .fb_copyarea = cfb_copyarea,
  211235. + .fb_imageblit = cfb_imageblit,
  211236. + .fb_mmap = hdlcd_mmap,
  211237. + .fb_pan_display = hdlcd_pan_display,
  211238. + .fb_ioctl = hdlcd_ioctl,
  211239. + .fb_compat_ioctl = hdlcd_ioctl
  211240. +};
  211241. +
  211242. +static int hdlcd_setup(struct hdlcd_device *hdlcd)
  211243. +{
  211244. + u32 version;
  211245. + int err = -EFAULT;
  211246. +
  211247. + hdlcd->fb.device = hdlcd->dev;
  211248. +
  211249. + hdlcd->clk = clk_get(hdlcd->dev, NULL);
  211250. + if (IS_ERR(hdlcd->clk)) {
  211251. + dev_err(hdlcd->dev, "HDLCD: unable to find clock data\n");
  211252. + return PTR_ERR(hdlcd->clk);
  211253. + }
  211254. +
  211255. + err = clk_prepare(hdlcd->clk);
  211256. + if (err)
  211257. + goto clk_prepare_err;
  211258. +
  211259. + hdlcd->base = ioremap_nocache(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
  211260. + if (!hdlcd->base) {
  211261. + dev_err(hdlcd->dev, "HDLCD: unable to map registers\n");
  211262. + goto remap_err;
  211263. + }
  211264. +
  211265. + hdlcd->fb.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
  211266. + if (!hdlcd->fb.pseudo_palette) {
  211267. + dev_err(hdlcd->dev, "HDLCD: unable to allocate pseudo_palette memory\n");
  211268. + err = -ENOMEM;
  211269. + goto kmalloc_err;
  211270. + }
  211271. +
  211272. + version = readl(hdlcd->base + HDLCD_REG_VERSION);
  211273. + if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) {
  211274. + dev_err(hdlcd->dev, "HDLCD: unknown product id: 0x%x\n", version);
  211275. + err = -EINVAL;
  211276. + goto kmalloc_err;
  211277. + }
  211278. + dev_info(hdlcd->dev, "HDLCD: found ARM HDLCD version r%dp%d\n",
  211279. + (version & HDLCD_VERSION_MAJOR_MASK) >> 8,
  211280. + version & HDLCD_VERSION_MINOR_MASK);
  211281. +
  211282. + strcpy(hdlcd->fb.fix.id, "hdlcd");
  211283. + hdlcd->fb.fbops = &hdlcd_ops;
  211284. + hdlcd->fb.flags = FBINFO_FLAG_DEFAULT/* | FBINFO_VIRTFB*/;
  211285. +
  211286. + hdlcd->fb.fix.type = FB_TYPE_PACKED_PIXELS;
  211287. + hdlcd->fb.fix.type_aux = 0;
  211288. + hdlcd->fb.fix.xpanstep = 0;
  211289. + hdlcd->fb.fix.ypanstep = 1;
  211290. + hdlcd->fb.fix.ywrapstep = 0;
  211291. + hdlcd->fb.fix.accel = FB_ACCEL_NONE;
  211292. +
  211293. + hdlcd->fb.var.nonstd = 0;
  211294. + hdlcd->fb.var.activate = FB_ACTIVATE_NOW;
  211295. + hdlcd->fb.var.height = -1;
  211296. + hdlcd->fb.var.width = -1;
  211297. + hdlcd->fb.var.accel_flags = 0;
  211298. +
  211299. + init_completion(&hdlcd->vsync_completion);
  211300. +
  211301. + if (hdlcd->edid) {
  211302. + /* build modedb from EDID */
  211303. + fb_edid_to_monspecs(hdlcd->edid, &hdlcd->fb.monspecs);
  211304. + fb_videomode_to_modelist(hdlcd->fb.monspecs.modedb,
  211305. + hdlcd->fb.monspecs.modedb_len,
  211306. + &hdlcd->fb.modelist);
  211307. + fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode,
  211308. + hdlcd->fb.monspecs.modedb,
  211309. + hdlcd->fb.monspecs.modedb_len,
  211310. + &hdlcd_default_mode, 32);
  211311. + } else {
  211312. + hdlcd->fb.monspecs.hfmin = 0;
  211313. + hdlcd->fb.monspecs.hfmax = 100000;
  211314. + hdlcd->fb.monspecs.vfmin = 0;
  211315. + hdlcd->fb.monspecs.vfmax = 400;
  211316. + hdlcd->fb.monspecs.dclkmin = 1000000;
  211317. + hdlcd->fb.monspecs.dclkmax = 100000000;
  211318. + fb_find_mode(&hdlcd->fb.var, &hdlcd->fb, fb_mode, NULL, 0, &hdlcd_default_mode, 32);
  211319. + }
  211320. +
  211321. + dev_info(hdlcd->dev, "using %dx%d-%d@%d mode\n", hdlcd->fb.var.xres,
  211322. + hdlcd->fb.var.yres, hdlcd->fb.var.bits_per_pixel,
  211323. + hdlcd->fb.mode ? hdlcd->fb.mode->refresh : 60);
  211324. + hdlcd->fb.var.xres_virtual = hdlcd->fb.var.xres;
  211325. +#ifdef HDLCD_NO_VIRTUAL_SCREEN
  211326. + hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres;
  211327. +#else
  211328. + hdlcd->fb.var.yres_virtual = hdlcd->fb.var.yres * 2;
  211329. +#endif
  211330. +
  211331. + /* initialise and set the palette */
  211332. + if (fb_alloc_cmap(&hdlcd->fb.cmap, NR_PALETTE, 0)) {
  211333. + dev_err(hdlcd->dev, "failed to allocate cmap memory\n");
  211334. + err = -ENOMEM;
  211335. + goto setup_err;
  211336. + }
  211337. + fb_set_cmap(&hdlcd->fb.cmap, &hdlcd->fb);
  211338. +
  211339. + /* Allow max number of outstanding requests with the largest beat burst */
  211340. + WRITE_HDLCD_REG(HDLCD_REG_BUS_OPTIONS, HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
  211341. + /* Set the framebuffer base to start of allocated memory */
  211342. + WRITE_HDLCD_REG(HDLCD_REG_FB_BASE, hdlcd->fb.fix.smem_start);
  211343. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  211344. + /* turn on underrun interrupt for counting */
  211345. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, HDLCD_INTERRUPT_UNDERRUN);
  211346. +#else
  211347. + /* Ensure interrupts are disabled */
  211348. + WRITE_HDLCD_REG(HDLCD_REG_INT_MASK, 0);
  211349. +#endif
  211350. + fb_set_var(&hdlcd->fb, &hdlcd->fb.var);
  211351. +
  211352. + if (!register_framebuffer(&hdlcd->fb)) {
  211353. + return 0;
  211354. + }
  211355. +
  211356. + dev_err(hdlcd->dev, "HDLCD: cannot register framebuffer\n");
  211357. +
  211358. + fb_dealloc_cmap(&hdlcd->fb.cmap);
  211359. +setup_err:
  211360. + iounmap(hdlcd->base);
  211361. +kmalloc_err:
  211362. + kfree(hdlcd->fb.pseudo_palette);
  211363. +remap_err:
  211364. + clk_unprepare(hdlcd->clk);
  211365. +clk_prepare_err:
  211366. + clk_put(hdlcd->clk);
  211367. + return err;
  211368. +}
  211369. +
  211370. +static inline unsigned char atohex(u8 data)
  211371. +{
  211372. + if (!isxdigit(data))
  211373. + return 0;
  211374. + /* truncate the upper nibble and add 9 to non-digit values */
  211375. + return (data > 0x39) ? ((data & 0xf) + 9) : (data & 0xf);
  211376. +}
  211377. +
  211378. +/* EDID data is passed from devicetree in a literal string that can contain spaces and
  211379. + the hexadecimal dump of the data */
  211380. +static int parse_edid_data(struct hdlcd_device *hdlcd, const u8 *edid_data, int data_len)
  211381. +{
  211382. + int i, j;
  211383. +
  211384. + if (!edid_data)
  211385. + return -EINVAL;
  211386. +
  211387. + hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
  211388. + if (!hdlcd->edid)
  211389. + return -ENOMEM;
  211390. +
  211391. + for (i = 0, j = 0; i < data_len; i++) {
  211392. + if (isspace(edid_data[i]))
  211393. + continue;
  211394. + hdlcd->edid[j++] = atohex(edid_data[i]);
  211395. + if (j >= EDID_LENGTH)
  211396. + break;
  211397. + }
  211398. +
  211399. + if (j < EDID_LENGTH) {
  211400. + kfree(hdlcd->edid);
  211401. + hdlcd->edid = NULL;
  211402. + return -EINVAL;
  211403. + }
  211404. +
  211405. + return 0;
  211406. +}
  211407. +
  211408. +static int hdlcd_probe(struct platform_device *pdev)
  211409. +{
  211410. + int err = 0, i;
  211411. + struct hdlcd_device *hdlcd;
  211412. + struct resource *mem;
  211413. +#ifdef CONFIG_OF
  211414. + struct device_node *of_node;
  211415. +#endif
  211416. +
  211417. + memset(&cached_var_screeninfo, 0, sizeof(struct fb_var_screeninfo));
  211418. +
  211419. + dev_dbg(&pdev->dev, "HDLCD: probing\n");
  211420. +
  211421. + hdlcd = kzalloc(sizeof(*hdlcd), GFP_KERNEL);
  211422. + if (!hdlcd)
  211423. + return -ENOMEM;
  211424. +
  211425. +#ifdef CONFIG_OF
  211426. + of_node = pdev->dev.of_node;
  211427. + if (of_node) {
  211428. + int len;
  211429. + const u8 *edid;
  211430. + const __be32 *prop = of_get_property(of_node, "mode", &len);
  211431. + if (prop)
  211432. + strncpy(fb_mode, (char *)prop, len);
  211433. + prop = of_get_property(of_node, "framebuffer", &len);
  211434. + if (prop) {
  211435. + hdlcd->fb.fix.smem_start = of_read_ulong(prop,
  211436. + of_n_addr_cells(of_node));
  211437. + prop += of_n_addr_cells(of_node);
  211438. + framebuffer_size = of_read_ulong(prop,
  211439. + of_n_size_cells(of_node));
  211440. + if (framebuffer_size > HDLCD_MAX_FRAMEBUFFER_SIZE)
  211441. + framebuffer_size = HDLCD_MAX_FRAMEBUFFER_SIZE;
  211442. + dev_dbg(&pdev->dev, "HDLCD: phys_addr = 0x%lx, size = 0x%lx\n",
  211443. + hdlcd->fb.fix.smem_start, framebuffer_size);
  211444. + }
  211445. + edid = of_get_property(of_node, "edid", &len);
  211446. + if (edid) {
  211447. + err = parse_edid_data(hdlcd, edid, len);
  211448. +#ifdef CONFIG_SERIAL_AMBA_PCU_UART
  211449. + } else {
  211450. + /* ask the firmware to fetch the EDID */
  211451. + dev_dbg(&pdev->dev, "HDLCD: Requesting EDID data\n");
  211452. + hdlcd->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
  211453. + if (!hdlcd->edid)
  211454. + return -ENOMEM;
  211455. + err = get_edid(hdlcd->edid);
  211456. +#endif /* CONFIG_SERIAL_AMBA_PCU_UART */
  211457. + }
  211458. + if (err)
  211459. + dev_info(&pdev->dev, "HDLCD: Failed to parse EDID data\n");
  211460. + }
  211461. +#endif /* CONFIG_OF */
  211462. +
  211463. + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  211464. + if (!mem) {
  211465. + dev_err(&pdev->dev, "HDLCD: cannot get platform resources\n");
  211466. + err = -EINVAL;
  211467. + goto resource_err;
  211468. + }
  211469. +
  211470. + i = platform_get_irq(pdev, 0);
  211471. + if (i < 0) {
  211472. + dev_err(&pdev->dev, "HDLCD: no irq defined for vsync\n");
  211473. + err = -ENOENT;
  211474. + goto resource_err;
  211475. + } else {
  211476. + err = request_irq(i, hdlcd_irq, 0, dev_name(&pdev->dev), hdlcd);
  211477. + if (err) {
  211478. + dev_err(&pdev->dev, "HDLCD: unable to request irq\n");
  211479. + goto resource_err;
  211480. + }
  211481. + hdlcd->irq = i;
  211482. + }
  211483. +
  211484. + if (!request_mem_region(mem->start, resource_size(mem), dev_name(&pdev->dev))) {
  211485. + err = -ENXIO;
  211486. + goto request_err;
  211487. + }
  211488. +
  211489. + if (!hdlcd->fb.fix.smem_start) {
  211490. + dev_err(&pdev->dev, "platform did not allocate frame buffer memory\n");
  211491. + err = -ENOMEM;
  211492. + goto memalloc_err;
  211493. + }
  211494. + hdlcd->fb.screen_base = ioremap_wc(hdlcd->fb.fix.smem_start, framebuffer_size);
  211495. + if (!hdlcd->fb.screen_base) {
  211496. + dev_err(&pdev->dev, "unable to ioremap framebuffer\n");
  211497. + err = -ENOMEM;
  211498. + goto probe_err;
  211499. + }
  211500. +
  211501. + hdlcd->fb.screen_size = framebuffer_size;
  211502. + hdlcd->fb.fix.smem_len = framebuffer_size;
  211503. + hdlcd->fb.fix.mmio_start = mem->start;
  211504. + hdlcd->fb.fix.mmio_len = resource_size(mem);
  211505. +
  211506. + /* Clear the framebuffer */
  211507. + memset(hdlcd->fb.screen_base, 0, framebuffer_size);
  211508. +
  211509. + hdlcd->dev = &pdev->dev;
  211510. +
  211511. + dev_dbg(&pdev->dev, "HDLCD: framebuffer virt base %p, phys base 0x%lX\n",
  211512. + hdlcd->fb.screen_base, (unsigned long)hdlcd->fb.fix.smem_start);
  211513. +
  211514. + err = hdlcd_setup(hdlcd);
  211515. +
  211516. + if (err)
  211517. + goto probe_err;
  211518. +
  211519. + platform_set_drvdata(pdev, hdlcd);
  211520. + return 0;
  211521. +
  211522. +probe_err:
  211523. + iounmap(hdlcd->fb.screen_base);
  211524. + memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
  211525. +
  211526. +memalloc_err:
  211527. + release_mem_region(mem->start, resource_size(mem));
  211528. +
  211529. +request_err:
  211530. + free_irq(hdlcd->irq, hdlcd);
  211531. +
  211532. +resource_err:
  211533. + kfree(hdlcd);
  211534. +
  211535. + return err;
  211536. +}
  211537. +
  211538. +static int hdlcd_remove(struct platform_device *pdev)
  211539. +{
  211540. + struct hdlcd_device *hdlcd = platform_get_drvdata(pdev);
  211541. +
  211542. + clk_disable(hdlcd->clk);
  211543. + clk_unprepare(hdlcd->clk);
  211544. + clk_put(hdlcd->clk);
  211545. +
  211546. + /* unmap memory */
  211547. + iounmap(hdlcd->fb.screen_base);
  211548. + iounmap(hdlcd->base);
  211549. +
  211550. + /* deallocate fb memory */
  211551. + fb_dealloc_cmap(&hdlcd->fb.cmap);
  211552. + kfree(hdlcd->fb.pseudo_palette);
  211553. + memblock_free(hdlcd->fb.fix.smem_start, hdlcd->fb.fix.smem_start);
  211554. + release_mem_region(hdlcd->fb.fix.mmio_start, hdlcd->fb.fix.mmio_len);
  211555. +
  211556. + free_irq(hdlcd->irq, NULL);
  211557. + kfree(hdlcd);
  211558. +
  211559. + return 0;
  211560. +}
  211561. +
  211562. +#ifdef CONFIG_PM
  211563. +static int hdlcd_suspend(struct platform_device *pdev, pm_message_t state)
  211564. +{
  211565. + /* not implemented yet */
  211566. + return 0;
  211567. +}
  211568. +
  211569. +static int hdlcd_resume(struct platform_device *pdev)
  211570. +{
  211571. + /* not implemented yet */
  211572. + return 0;
  211573. +}
  211574. +#else
  211575. +#define hdlcd_suspend NULL
  211576. +#define hdlcd_resume NULL
  211577. +#endif
  211578. +
  211579. +static struct platform_driver hdlcd_driver = {
  211580. + .probe = hdlcd_probe,
  211581. + .remove = hdlcd_remove,
  211582. + .suspend = hdlcd_suspend,
  211583. + .resume = hdlcd_resume,
  211584. + .driver = {
  211585. + .name = "hdlcd",
  211586. + .owner = THIS_MODULE,
  211587. + .of_match_table = hdlcd_of_matches,
  211588. + },
  211589. +};
  211590. +
  211591. +static int __init hdlcd_init(void)
  211592. +{
  211593. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  211594. + int err = platform_driver_register(&hdlcd_driver);
  211595. + if (!err)
  211596. + hdlcd_underrun_init();
  211597. + return err;
  211598. +#else
  211599. + return platform_driver_register(&hdlcd_driver);
  211600. +#endif
  211601. +}
  211602. +
  211603. +void __exit hdlcd_exit(void)
  211604. +{
  211605. +#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
  211606. + hdlcd_underrun_close();
  211607. +#endif
  211608. + platform_driver_unregister(&hdlcd_driver);
  211609. +}
  211610. +
  211611. +module_init(hdlcd_init);
  211612. +module_exit(hdlcd_exit);
  211613. +
  211614. +MODULE_AUTHOR("Liviu Dudau");
  211615. +MODULE_DESCRIPTION("ARM HDLCD core driver");
  211616. +MODULE_LICENSE("GPL v2");
  211617. diff -Nur linux-3.14.17/drivers/video/backlight/backlight.c linux-imx6-3.14/drivers/video/backlight/backlight.c
  211618. --- linux-3.14.17/drivers/video/backlight/backlight.c 2014-08-14 03:38:34.000000000 +0200
  211619. +++ linux-imx6-3.14/drivers/video/backlight/backlight.c 2014-09-11 18:06:09.362067367 +0200
  211620. @@ -41,6 +41,8 @@
  211621. {
  211622. struct backlight_device *bd;
  211623. struct fb_event *evdata = data;
  211624. + int node = evdata->info->node;
  211625. + int fb_blank = 0;
  211626. /* If we aren't interested in this event, skip it immediately ... */
  211627. if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
  211628. @@ -51,12 +53,24 @@
  211629. if (bd->ops)
  211630. if (!bd->ops->check_fb ||
  211631. bd->ops->check_fb(bd, evdata->info)) {
  211632. - bd->props.fb_blank = *(int *)evdata->data;
  211633. - if (bd->props.fb_blank == FB_BLANK_UNBLANK)
  211634. - bd->props.state &= ~BL_CORE_FBBLANK;
  211635. - else
  211636. - bd->props.state |= BL_CORE_FBBLANK;
  211637. - backlight_update_status(bd);
  211638. + fb_blank = *(int *)evdata->data;
  211639. + if (fb_blank == FB_BLANK_UNBLANK &&
  211640. + !bd->fb_bl_on[node]) {
  211641. + bd->fb_bl_on[node] = true;
  211642. + if (!bd->use_count++) {
  211643. + bd->props.state &= ~BL_CORE_FBBLANK;
  211644. + bd->props.fb_blank = FB_BLANK_UNBLANK;
  211645. + backlight_update_status(bd);
  211646. + }
  211647. + } else if (fb_blank != FB_BLANK_UNBLANK &&
  211648. + bd->fb_bl_on[node]) {
  211649. + bd->fb_bl_on[node] = false;
  211650. + if (!(--bd->use_count)) {
  211651. + bd->props.state |= BL_CORE_FBBLANK;
  211652. + bd->props.fb_blank = FB_BLANK_POWERDOWN;
  211653. + backlight_update_status(bd);
  211654. + }
  211655. + }
  211656. }
  211657. mutex_unlock(&bd->ops_lock);
  211658. return 0;
  211659. diff -Nur linux-3.14.17/drivers/video/Kconfig linux-imx6-3.14/drivers/video/Kconfig
  211660. --- linux-3.14.17/drivers/video/Kconfig 2014-08-14 03:38:34.000000000 +0200
  211661. +++ linux-imx6-3.14/drivers/video/Kconfig 2014-09-11 18:06:09.354067336 +0200
  211662. @@ -39,6 +39,11 @@
  211663. config HDMI
  211664. bool
  211665. +config VEXPRESS_DVI_CONTROL
  211666. + bool "Versatile Express DVI control"
  211667. + depends on FB && VEXPRESS_CONFIG
  211668. + default y
  211669. +
  211670. menuconfig FB
  211671. tristate "Support for frame buffer devices"
  211672. ---help---
  211673. @@ -327,6 +332,21 @@
  211674. here and read <file:Documentation/kbuild/modules.txt>. The module
  211675. will be called amba-clcd.
  211676. +config FB_ARMHDLCD
  211677. + tristate "ARM High Definition LCD support"
  211678. + depends on FB && ARM
  211679. + select FB_CFB_FILLRECT
  211680. + select FB_CFB_COPYAREA
  211681. + select FB_CFB_IMAGEBLIT
  211682. + help
  211683. + This framebuffer device driver is for the ARM High Definition
  211684. + Colour LCD controller.
  211685. +
  211686. + If you want to compile this as a module (=code which can be
  211687. + inserted into and removed from the running kernel), say M
  211688. + here and read <file:Documentation/kbuild/modules.txt>. The module
  211689. + will be called arm-hdlcd.
  211690. +
  211691. config FB_ACORN
  211692. bool "Acorn VIDC support"
  211693. depends on (FB = y) && ARM && ARCH_ACORN
  211694. @@ -2491,6 +2511,10 @@
  211695. source "drivers/video/mmp/Kconfig"
  211696. source "drivers/video/backlight/Kconfig"
  211697. +if ARCH_MXC
  211698. +source "drivers/video/mxc/Kconfig"
  211699. +endif
  211700. +
  211701. if VT
  211702. source "drivers/video/console/Kconfig"
  211703. endif
  211704. diff -Nur linux-3.14.17/drivers/video/Makefile linux-imx6-3.14/drivers/video/Makefile
  211705. --- linux-3.14.17/drivers/video/Makefile 2014-08-14 03:38:34.000000000 +0200
  211706. +++ linux-imx6-3.14/drivers/video/Makefile 2014-09-11 18:06:09.354067336 +0200
  211707. @@ -53,6 +53,7 @@
  211708. obj-$(CONFIG_FB_SAVAGE) += savage/
  211709. obj-$(CONFIG_FB_GEODE) += geode/
  211710. obj-$(CONFIG_FB_MBX) += mbx/
  211711. +obj-$(CONFIG_FB_MXC) += mxc/
  211712. obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
  211713. obj-$(CONFIG_FB_3DFX) += tdfxfb.o
  211714. obj-$(CONFIG_FB_CONTROL) += controlfb.o
  211715. @@ -99,6 +100,7 @@
  211716. obj-$(CONFIG_FB_PVR2) += pvr2fb.o
  211717. obj-$(CONFIG_FB_VOODOO1) += sstfb.o
  211718. obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
  211719. +obj-$(CONFIG_FB_ARMHDLCD) += arm-hdlcd.o
  211720. obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
  211721. obj-$(CONFIG_FB_68328) += 68328fb.o
  211722. obj-$(CONFIG_FB_GBE) += gbefb.o
  211723. @@ -178,3 +180,6 @@
  211724. ifeq ($(CONFIG_OF),y)
  211725. obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o
  211726. endif
  211727. +
  211728. +# platform specific output drivers
  211729. +obj-$(CONFIG_VEXPRESS_DVI_CONTROL) += vexpress-dvi.o
  211730. diff -Nur linux-3.14.17/drivers/video/mxc/Kconfig linux-imx6-3.14/drivers/video/mxc/Kconfig
  211731. --- linux-3.14.17/drivers/video/mxc/Kconfig 1970-01-01 01:00:00.000000000 +0100
  211732. +++ linux-imx6-3.14/drivers/video/mxc/Kconfig 2014-09-11 18:06:09.534068054 +0200
  211733. @@ -0,0 +1,48 @@
  211734. +config FB_MXC
  211735. + tristate "MXC Framebuffer support"
  211736. + depends on FB
  211737. + select FB_CFB_FILLRECT
  211738. + select FB_CFB_COPYAREA
  211739. + select FB_CFB_IMAGEBLIT
  211740. + select FB_MODE_HELPERS
  211741. + default y
  211742. + help
  211743. + This is a framebuffer device for the MXC LCD Controller.
  211744. + See <http://www.linux-fbdev.org/> for information on framebuffer
  211745. + devices.
  211746. +
  211747. + If you plan to use the LCD display with your MXC system, say
  211748. + Y here.
  211749. +
  211750. +config FB_MXC_SYNC_PANEL
  211751. + depends on FB_MXC
  211752. + tristate "Synchronous Panel Framebuffer"
  211753. +
  211754. +config FB_MXC_LDB
  211755. + tristate "MXC LDB"
  211756. + depends on FB_MXC_SYNC_PANEL
  211757. + depends on MXC_IPU_V3
  211758. +
  211759. +config FB_MXC_MIPI_DSI
  211760. + tristate "MXC MIPI_DSI"
  211761. + depends on FB_MXC_SYNC_PANEL
  211762. + depends on MXC_IPU_V3
  211763. +
  211764. +config FB_MXC_TRULY_WVGA_SYNC_PANEL
  211765. + tristate "TRULY WVGA Panel"
  211766. + depends on FB_MXC_SYNC_PANEL
  211767. + depends on FB_MXC_MIPI_DSI
  211768. +
  211769. +config FB_MXC_HDMI
  211770. + depends on FB_MXC_SYNC_PANEL
  211771. + depends on MXC_IPU_V3
  211772. + depends on I2C
  211773. + tristate "MXC HDMI driver support"
  211774. + select MFD_MXC_HDMI
  211775. + help
  211776. + Driver for the on-chip MXC HDMI controller.
  211777. +
  211778. +config FB_MXC_EDID
  211779. + depends on FB_MXC && I2C
  211780. + tristate "MXC EDID support"
  211781. + default y
  211782. diff -Nur linux-3.14.17/drivers/video/mxc/ldb.c linux-imx6-3.14/drivers/video/mxc/ldb.c
  211783. --- linux-3.14.17/drivers/video/mxc/ldb.c 1970-01-01 01:00:00.000000000 +0100
  211784. +++ linux-imx6-3.14/drivers/video/mxc/ldb.c 2014-09-11 18:06:09.534068054 +0200
  211785. @@ -0,0 +1,1036 @@
  211786. +/*
  211787. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  211788. + */
  211789. +
  211790. +/*
  211791. + * This program is free software; you can redistribute it and/or modify
  211792. + * it under the terms of the GNU General Public License as published by
  211793. + * the Free Software Foundation; either version 2 of the License, or
  211794. + * (at your option) any later version.
  211795. +
  211796. + * This program is distributed in the hope that it will be useful,
  211797. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  211798. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  211799. + * GNU General Public License for more details.
  211800. +
  211801. + * You should have received a copy of the GNU General Public License along
  211802. + * with this program; if not, write to the Free Software Foundation, Inc.,
  211803. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  211804. + */
  211805. +
  211806. +/*!
  211807. + * @file mxc_ldb.c
  211808. + *
  211809. + * @brief This file contains the LDB driver device interface and fops
  211810. + * functions.
  211811. + */
  211812. +#include <linux/types.h>
  211813. +#include <linux/init.h>
  211814. +#include <linux/module.h>
  211815. +#include <linux/platform_device.h>
  211816. +#include <linux/err.h>
  211817. +#include <linux/clk.h>
  211818. +#include <linux/console.h>
  211819. +#include <linux/io.h>
  211820. +#include <linux/ipu.h>
  211821. +#include <linux/mxcfb.h>
  211822. +#include <linux/regulator/consumer.h>
  211823. +#include <linux/spinlock.h>
  211824. +#include <linux/of_device.h>
  211825. +#include <linux/mod_devicetable.h>
  211826. +#include "mxc_dispdrv.h"
  211827. +
  211828. +#define DISPDRV_LDB "ldb"
  211829. +
  211830. +#define LDB_BGREF_RMODE_MASK 0x00008000
  211831. +#define LDB_BGREF_RMODE_INT 0x00008000
  211832. +#define LDB_BGREF_RMODE_EXT 0x0
  211833. +
  211834. +#define LDB_DI1_VS_POL_MASK 0x00000400
  211835. +#define LDB_DI1_VS_POL_ACT_LOW 0x00000400
  211836. +#define LDB_DI1_VS_POL_ACT_HIGH 0x0
  211837. +#define LDB_DI0_VS_POL_MASK 0x00000200
  211838. +#define LDB_DI0_VS_POL_ACT_LOW 0x00000200
  211839. +#define LDB_DI0_VS_POL_ACT_HIGH 0x0
  211840. +
  211841. +#define LDB_BIT_MAP_CH1_MASK 0x00000100
  211842. +#define LDB_BIT_MAP_CH1_JEIDA 0x00000100
  211843. +#define LDB_BIT_MAP_CH1_SPWG 0x0
  211844. +#define LDB_BIT_MAP_CH0_MASK 0x00000040
  211845. +#define LDB_BIT_MAP_CH0_JEIDA 0x00000040
  211846. +#define LDB_BIT_MAP_CH0_SPWG 0x0
  211847. +
  211848. +#define LDB_DATA_WIDTH_CH1_MASK 0x00000080
  211849. +#define LDB_DATA_WIDTH_CH1_24 0x00000080
  211850. +#define LDB_DATA_WIDTH_CH1_18 0x0
  211851. +#define LDB_DATA_WIDTH_CH0_MASK 0x00000020
  211852. +#define LDB_DATA_WIDTH_CH0_24 0x00000020
  211853. +#define LDB_DATA_WIDTH_CH0_18 0x0
  211854. +
  211855. +#define LDB_CH1_MODE_MASK 0x0000000C
  211856. +#define LDB_CH1_MODE_EN_TO_DI1 0x0000000C
  211857. +#define LDB_CH1_MODE_EN_TO_DI0 0x00000004
  211858. +#define LDB_CH1_MODE_DISABLE 0x0
  211859. +#define LDB_CH0_MODE_MASK 0x00000003
  211860. +#define LDB_CH0_MODE_EN_TO_DI1 0x00000003
  211861. +#define LDB_CH0_MODE_EN_TO_DI0 0x00000001
  211862. +#define LDB_CH0_MODE_DISABLE 0x0
  211863. +
  211864. +#define LDB_SPLIT_MODE_EN 0x00000010
  211865. +
  211866. +enum {
  211867. + IMX6_LDB,
  211868. +};
  211869. +
  211870. +enum {
  211871. + LDB_IMX6 = 1,
  211872. +};
  211873. +
  211874. +struct fsl_mxc_ldb_platform_data {
  211875. + int devtype;
  211876. + u32 ext_ref;
  211877. +#define LDB_SPL_DI0 1
  211878. +#define LDB_SPL_DI1 2
  211879. +#define LDB_DUL_DI0 3
  211880. +#define LDB_DUL_DI1 4
  211881. +#define LDB_SIN0 5
  211882. +#define LDB_SIN1 6
  211883. +#define LDB_SEP0 7
  211884. +#define LDB_SEP1 8
  211885. + int mode;
  211886. + int ipu_id;
  211887. + int disp_id;
  211888. +
  211889. + /*only work for separate mode*/
  211890. + int sec_ipu_id;
  211891. + int sec_disp_id;
  211892. +};
  211893. +
  211894. +struct ldb_data {
  211895. + struct platform_device *pdev;
  211896. + struct mxc_dispdrv_handle *disp_ldb;
  211897. + uint32_t *reg;
  211898. + uint32_t *control_reg;
  211899. + uint32_t *gpr3_reg;
  211900. + uint32_t control_reg_data;
  211901. + struct regulator *lvds_bg_reg;
  211902. + int mode;
  211903. + bool inited;
  211904. + struct ldb_setting {
  211905. + struct clk *di_clk;
  211906. + struct clk *ldb_di_clk;
  211907. + struct clk *div_3_5_clk;
  211908. + struct clk *div_7_clk;
  211909. + struct clk *div_sel_clk;
  211910. + bool active;
  211911. + bool clk_en;
  211912. + int ipu;
  211913. + int di;
  211914. + uint32_t ch_mask;
  211915. + uint32_t ch_val;
  211916. + } setting[2];
  211917. + struct notifier_block nb;
  211918. +};
  211919. +
  211920. +static int g_ldb_mode;
  211921. +
  211922. +static struct fb_videomode ldb_modedb[] = {
  211923. + {
  211924. + "LDB-WXGA", 60, 1280, 800, 14065,
  211925. + 40, 40,
  211926. + 10, 3,
  211927. + 80, 10,
  211928. + 0,
  211929. + FB_VMODE_NONINTERLACED,
  211930. + FB_MODE_IS_DETAILED,},
  211931. + {
  211932. + "LDB-XGA", 60, 1024, 768, 15385,
  211933. + 220, 40,
  211934. + 21, 7,
  211935. + 60, 10,
  211936. + 0,
  211937. + FB_VMODE_NONINTERLACED,
  211938. + FB_MODE_IS_DETAILED,},
  211939. + {
  211940. + "LDB-1080P60", 60, 1920, 1080, 7692,
  211941. + 100, 40,
  211942. + 30, 3,
  211943. + 10, 2,
  211944. + 0,
  211945. + FB_VMODE_NONINTERLACED,
  211946. + FB_MODE_IS_DETAILED,},
  211947. +};
  211948. +static int ldb_modedb_sz = ARRAY_SIZE(ldb_modedb);
  211949. +
  211950. +static inline int is_imx6_ldb(struct fsl_mxc_ldb_platform_data *plat_data)
  211951. +{
  211952. + return (plat_data->devtype == LDB_IMX6);
  211953. +}
  211954. +
  211955. +static int bits_per_pixel(int pixel_fmt)
  211956. +{
  211957. + switch (pixel_fmt) {
  211958. + case IPU_PIX_FMT_BGR24:
  211959. + case IPU_PIX_FMT_RGB24:
  211960. + return 24;
  211961. + break;
  211962. + case IPU_PIX_FMT_BGR666:
  211963. + case IPU_PIX_FMT_RGB666:
  211964. + case IPU_PIX_FMT_LVDS666:
  211965. + return 18;
  211966. + break;
  211967. + default:
  211968. + break;
  211969. + }
  211970. + return 0;
  211971. +}
  211972. +
  211973. +static int valid_mode(int pixel_fmt)
  211974. +{
  211975. + return ((pixel_fmt == IPU_PIX_FMT_RGB24) ||
  211976. + (pixel_fmt == IPU_PIX_FMT_BGR24) ||
  211977. + (pixel_fmt == IPU_PIX_FMT_LVDS666) ||
  211978. + (pixel_fmt == IPU_PIX_FMT_RGB666) ||
  211979. + (pixel_fmt == IPU_PIX_FMT_BGR666));
  211980. +}
  211981. +
  211982. +static int parse_ldb_mode(char *mode)
  211983. +{
  211984. + int ldb_mode;
  211985. +
  211986. + if (!strcmp(mode, "spl0"))
  211987. + ldb_mode = LDB_SPL_DI0;
  211988. + else if (!strcmp(mode, "spl1"))
  211989. + ldb_mode = LDB_SPL_DI1;
  211990. + else if (!strcmp(mode, "dul0"))
  211991. + ldb_mode = LDB_DUL_DI0;
  211992. + else if (!strcmp(mode, "dul1"))
  211993. + ldb_mode = LDB_DUL_DI1;
  211994. + else if (!strcmp(mode, "sin0"))
  211995. + ldb_mode = LDB_SIN0;
  211996. + else if (!strcmp(mode, "sin1"))
  211997. + ldb_mode = LDB_SIN1;
  211998. + else if (!strcmp(mode, "sep0"))
  211999. + ldb_mode = LDB_SEP0;
  212000. + else if (!strcmp(mode, "sep1"))
  212001. + ldb_mode = LDB_SEP1;
  212002. + else
  212003. + ldb_mode = -EINVAL;
  212004. +
  212005. + return ldb_mode;
  212006. +}
  212007. +
  212008. +#ifndef MODULE
  212009. +/*
  212010. + * "ldb=spl0/1" -- split mode on DI0/1
  212011. + * "ldb=dul0/1" -- dual mode on DI0/1
  212012. + * "ldb=sin0/1" -- single mode on LVDS0/1
  212013. + * "ldb=sep0/1" -- separate mode begin from LVDS0/1
  212014. + *
  212015. + * there are two LVDS channels(LVDS0 and LVDS1) which can transfer video
  212016. + * datas, there two channels can be used as split/dual/single/separate mode.
  212017. + *
  212018. + * split mode means display data from DI0 or DI1 will send to both channels
  212019. + * LVDS0+LVDS1.
  212020. + * dual mode means display data from DI0 or DI1 will be duplicated on LVDS0
  212021. + * and LVDS1, it said, LVDS0 and LVDS1 has the same content.
  212022. + * single mode means only work for DI0/DI1->LVDS0 or DI0/DI1->LVDS1.
  212023. + * separate mode means you can make DI0/DI1->LVDS0 and DI0/DI1->LVDS1 work
  212024. + * at the same time.
  212025. + */
  212026. +static int __init ldb_setup(char *options)
  212027. +{
  212028. + g_ldb_mode = parse_ldb_mode(options);
  212029. + return (g_ldb_mode < 0) ? 0 : 1;
  212030. +}
  212031. +__setup("ldb=", ldb_setup);
  212032. +#endif
  212033. +
  212034. +static int ldb_get_of_property(struct platform_device *pdev,
  212035. + struct fsl_mxc_ldb_platform_data *plat_data)
  212036. +{
  212037. + struct device_node *np = pdev->dev.of_node;
  212038. + int err;
  212039. + u32 ipu_id, disp_id;
  212040. + u32 sec_ipu_id, sec_disp_id;
  212041. + char *mode;
  212042. + u32 ext_ref;
  212043. +
  212044. + err = of_property_read_string(np, "mode", (const char **)&mode);
  212045. + if (err) {
  212046. + dev_dbg(&pdev->dev, "get of property mode fail\n");
  212047. + return err;
  212048. + }
  212049. + err = of_property_read_u32(np, "ext_ref", &ext_ref);
  212050. + if (err) {
  212051. + dev_dbg(&pdev->dev, "get of property ext_ref fail\n");
  212052. + return err;
  212053. + }
  212054. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  212055. + if (err) {
  212056. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  212057. + return err;
  212058. + }
  212059. + err = of_property_read_u32(np, "disp_id", &disp_id);
  212060. + if (err) {
  212061. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  212062. + return err;
  212063. + }
  212064. + err = of_property_read_u32(np, "sec_ipu_id", &sec_ipu_id);
  212065. + if (err) {
  212066. + dev_dbg(&pdev->dev, "get of property sec_ipu_id fail\n");
  212067. + return err;
  212068. + }
  212069. + err = of_property_read_u32(np, "sec_disp_id", &sec_disp_id);
  212070. + if (err) {
  212071. + dev_dbg(&pdev->dev, "get of property sec_disp_id fail\n");
  212072. + return err;
  212073. + }
  212074. +
  212075. + plat_data->mode = parse_ldb_mode(mode);
  212076. + plat_data->ext_ref = ext_ref;
  212077. + plat_data->ipu_id = ipu_id;
  212078. + plat_data->disp_id = disp_id;
  212079. + plat_data->sec_ipu_id = sec_ipu_id;
  212080. + plat_data->sec_disp_id = sec_disp_id;
  212081. +
  212082. + return err;
  212083. +}
  212084. +
  212085. +static int find_ldb_setting(struct ldb_data *ldb, struct fb_info *fbi)
  212086. +{
  212087. + char *id_di[] = {
  212088. + "DISP3 BG",
  212089. + "DISP3 BG - DI1",
  212090. + };
  212091. + char id[16];
  212092. + int i;
  212093. +
  212094. + for (i = 0; i < 2; i++) {
  212095. + if (ldb->setting[i].active) {
  212096. + memset(id, 0, 16);
  212097. + memcpy(id, id_di[ldb->setting[i].di],
  212098. + strlen(id_di[ldb->setting[i].di]));
  212099. + id[4] += ldb->setting[i].ipu;
  212100. + if (!strcmp(id, fbi->fix.id))
  212101. + return i;
  212102. + }
  212103. + }
  212104. + return -EINVAL;
  212105. +}
  212106. +
  212107. +static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi)
  212108. +{
  212109. + uint32_t reg, val;
  212110. + uint32_t pixel_clk, rounded_pixel_clk;
  212111. + struct clk *ldb_clk_parent;
  212112. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  212113. + int setting_idx, di;
  212114. + int ret;
  212115. +
  212116. + setting_idx = find_ldb_setting(ldb, fbi);
  212117. + if (setting_idx < 0)
  212118. + return setting_idx;
  212119. +
  212120. + di = ldb->setting[setting_idx].di;
  212121. +
  212122. + /* restore channel mode setting */
  212123. + val = readl(ldb->control_reg);
  212124. + val |= ldb->setting[setting_idx].ch_val;
  212125. + writel(val, ldb->control_reg);
  212126. + dev_dbg(&ldb->pdev->dev, "LDB setup, control reg:0x%x\n",
  212127. + readl(ldb->control_reg));
  212128. +
  212129. + /* vsync setup */
  212130. + reg = readl(ldb->control_reg);
  212131. + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) {
  212132. + if (di == 0)
  212133. + reg = (reg & ~LDB_DI0_VS_POL_MASK)
  212134. + | LDB_DI0_VS_POL_ACT_HIGH;
  212135. + else
  212136. + reg = (reg & ~LDB_DI1_VS_POL_MASK)
  212137. + | LDB_DI1_VS_POL_ACT_HIGH;
  212138. + } else {
  212139. + if (di == 0)
  212140. + reg = (reg & ~LDB_DI0_VS_POL_MASK)
  212141. + | LDB_DI0_VS_POL_ACT_LOW;
  212142. + else
  212143. + reg = (reg & ~LDB_DI1_VS_POL_MASK)
  212144. + | LDB_DI1_VS_POL_ACT_LOW;
  212145. + }
  212146. + writel(reg, ldb->control_reg);
  212147. +
  212148. + /* clk setup */
  212149. + if (ldb->setting[setting_idx].clk_en)
  212150. + clk_disable_unprepare(ldb->setting[setting_idx].ldb_di_clk);
  212151. + pixel_clk = (PICOS2KHZ(fbi->var.pixclock)) * 1000UL;
  212152. + ldb_clk_parent = clk_get_parent(ldb->setting[setting_idx].ldb_di_clk);
  212153. + if (IS_ERR(ldb_clk_parent)) {
  212154. + dev_err(&ldb->pdev->dev, "get ldb di parent clk fail\n");
  212155. + return PTR_ERR(ldb_clk_parent);
  212156. + }
  212157. + if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1))
  212158. + ret = clk_set_rate(ldb_clk_parent, pixel_clk * 7 / 2);
  212159. + else
  212160. + ret = clk_set_rate(ldb_clk_parent, pixel_clk * 7);
  212161. + if (ret < 0) {
  212162. + dev_err(&ldb->pdev->dev, "set ldb parent clk fail:%d\n", ret);
  212163. + return ret;
  212164. + }
  212165. + rounded_pixel_clk = clk_round_rate(ldb->setting[setting_idx].ldb_di_clk,
  212166. + pixel_clk);
  212167. + dev_dbg(&ldb->pdev->dev, "pixel_clk:%d, rounded_pixel_clk:%d\n",
  212168. + pixel_clk, rounded_pixel_clk);
  212169. + ret = clk_set_rate(ldb->setting[setting_idx].ldb_di_clk,
  212170. + rounded_pixel_clk);
  212171. + if (ret < 0) {
  212172. + dev_err(&ldb->pdev->dev, "set ldb di clk fail:%d\n", ret);
  212173. + return ret;
  212174. + }
  212175. + ret = clk_prepare_enable(ldb->setting[setting_idx].ldb_di_clk);
  212176. + if (ret < 0) {
  212177. + dev_err(&ldb->pdev->dev, "enable ldb di clk fail:%d\n", ret);
  212178. + return ret;
  212179. + }
  212180. +
  212181. + if (!ldb->setting[setting_idx].clk_en)
  212182. + ldb->setting[setting_idx].clk_en = true;
  212183. +
  212184. + return 0;
  212185. +}
  212186. +
  212187. +int ldb_fb_event(struct notifier_block *nb, unsigned long val, void *v)
  212188. +{
  212189. + struct ldb_data *ldb = container_of(nb, struct ldb_data, nb);
  212190. + struct fb_event *event = v;
  212191. + struct fb_info *fbi = event->info;
  212192. + int index;
  212193. + uint32_t data;
  212194. +
  212195. + index = find_ldb_setting(ldb, fbi);
  212196. + if (index < 0)
  212197. + return 0;
  212198. +
  212199. + fbi->mode = (struct fb_videomode *)fb_match_mode(&fbi->var,
  212200. + &fbi->modelist);
  212201. +
  212202. + if (!fbi->mode) {
  212203. + dev_warn(&ldb->pdev->dev,
  212204. + "LDB: can not find mode for xres=%d, yres=%d\n",
  212205. + fbi->var.xres, fbi->var.yres);
  212206. + if (ldb->setting[index].clk_en) {
  212207. + clk_disable(ldb->setting[index].ldb_di_clk);
  212208. + ldb->setting[index].clk_en = false;
  212209. + data = readl(ldb->control_reg);
  212210. + data &= ~ldb->setting[index].ch_mask;
  212211. + writel(data, ldb->control_reg);
  212212. + }
  212213. + return 0;
  212214. + }
  212215. +
  212216. + switch (val) {
  212217. + case FB_EVENT_BLANK:
  212218. + {
  212219. + if (*((int *)event->data) == FB_BLANK_UNBLANK) {
  212220. + if (!ldb->setting[index].clk_en) {
  212221. + clk_enable(ldb->setting[index].ldb_di_clk);
  212222. + ldb->setting[index].clk_en = true;
  212223. + }
  212224. + } else {
  212225. + if (ldb->setting[index].clk_en) {
  212226. + clk_disable(ldb->setting[index].ldb_di_clk);
  212227. + ldb->setting[index].clk_en = false;
  212228. + data = readl(ldb->control_reg);
  212229. + data &= ~ldb->setting[index].ch_mask;
  212230. + writel(data, ldb->control_reg);
  212231. + dev_dbg(&ldb->pdev->dev,
  212232. + "LDB blank, control reg:0x%x\n",
  212233. + readl(ldb->control_reg));
  212234. + }
  212235. + }
  212236. + break;
  212237. + }
  212238. + case FB_EVENT_SUSPEND:
  212239. + if (ldb->setting[index].clk_en) {
  212240. + clk_disable(ldb->setting[index].ldb_di_clk);
  212241. + ldb->setting[index].clk_en = false;
  212242. + }
  212243. + break;
  212244. + default:
  212245. + break;
  212246. + }
  212247. + return 0;
  212248. +}
  212249. +
  212250. +#define LVDS_MUX_CTL_WIDTH 2
  212251. +#define LVDS_MUX_CTL_MASK 3
  212252. +#define LVDS0_MUX_CTL_OFFS 6
  212253. +#define LVDS1_MUX_CTL_OFFS 8
  212254. +#define LVDS0_MUX_CTL_MASK (LVDS_MUX_CTL_MASK << 6)
  212255. +#define LVDS1_MUX_CTL_MASK (LVDS_MUX_CTL_MASK << 8)
  212256. +#define ROUTE_IPU_DI(ipu, di) (((ipu << 1) | di) & LVDS_MUX_CTL_MASK)
  212257. +static int ldb_ipu_ldb_route(int ipu, int di, struct ldb_data *ldb)
  212258. +{
  212259. + uint32_t reg;
  212260. + int channel;
  212261. + int shift;
  212262. + int mode = ldb->mode;
  212263. +
  212264. + reg = readl(ldb->gpr3_reg);
  212265. + if (mode < LDB_SIN0) {
  212266. + reg &= ~(LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);
  212267. + reg |= (ROUTE_IPU_DI(ipu, di) << LVDS0_MUX_CTL_OFFS) |
  212268. + (ROUTE_IPU_DI(ipu, di) << LVDS1_MUX_CTL_OFFS);
  212269. + dev_dbg(&ldb->pdev->dev,
  212270. + "Dual/Split mode both channels route to IPU%d-DI%d\n",
  212271. + ipu, di);
  212272. + } else if ((mode == LDB_SIN0) || (mode == LDB_SIN1)) {
  212273. + reg &= ~(LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);
  212274. + channel = mode - LDB_SIN0;
  212275. + shift = LVDS0_MUX_CTL_OFFS + channel * LVDS_MUX_CTL_WIDTH;
  212276. + reg |= ROUTE_IPU_DI(ipu, di) << shift;
  212277. + dev_dbg(&ldb->pdev->dev,
  212278. + "Single mode channel %d route to IPU%d-DI%d\n",
  212279. + channel, ipu, di);
  212280. + } else {
  212281. + static bool first = true;
  212282. +
  212283. + if (first) {
  212284. + if (mode == LDB_SEP0) {
  212285. + reg &= ~LVDS0_MUX_CTL_MASK;
  212286. + channel = 0;
  212287. + } else {
  212288. + reg &= ~LVDS1_MUX_CTL_MASK;
  212289. + channel = 1;
  212290. + }
  212291. + first = false;
  212292. + } else {
  212293. + if (mode == LDB_SEP0) {
  212294. + reg &= ~LVDS1_MUX_CTL_MASK;
  212295. + channel = 1;
  212296. + } else {
  212297. + reg &= ~LVDS0_MUX_CTL_MASK;
  212298. + channel = 0;
  212299. + }
  212300. + }
  212301. +
  212302. + shift = LVDS0_MUX_CTL_OFFS + channel * LVDS_MUX_CTL_WIDTH;
  212303. + reg |= ROUTE_IPU_DI(ipu, di) << shift;
  212304. +
  212305. + dev_dbg(&ldb->pdev->dev,
  212306. + "Separate mode channel %d route to IPU%d-DI%d\n",
  212307. + channel, ipu, di);
  212308. + }
  212309. + writel(reg, ldb->gpr3_reg);
  212310. +
  212311. + return 0;
  212312. +}
  212313. +
  212314. +static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
  212315. + struct mxc_dispdrv_setting *setting)
  212316. +{
  212317. + int ret = 0, i, lvds_channel = 0;
  212318. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  212319. + struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data;
  212320. + struct resource *res;
  212321. + uint32_t reg, setting_idx;
  212322. + uint32_t ch_mask = 0, ch_val = 0;
  212323. + uint32_t ipu_id, disp_id;
  212324. + char di_clk[] = "ipu1_di0_sel";
  212325. + char ldb_clk[] = "ldb_di0";
  212326. + char div_3_5_clk[] = "di0_div_3_5";
  212327. + char div_7_clk[] = "di0_div_7";
  212328. + char div_sel_clk[] = "di0_div_sel";
  212329. +
  212330. + /* if input format not valid, make RGB666 as default*/
  212331. + if (!valid_mode(setting->if_fmt)) {
  212332. + dev_warn(&ldb->pdev->dev, "Input pixel format not valid"
  212333. + " use default RGB666\n");
  212334. + setting->if_fmt = IPU_PIX_FMT_RGB666;
  212335. + }
  212336. +
  212337. + if (!ldb->inited) {
  212338. + setting_idx = 0;
  212339. + res = platform_get_resource(ldb->pdev, IORESOURCE_MEM, 0);
  212340. + if (!res) {
  212341. + dev_err(&ldb->pdev->dev, "get iomem fail.\n");
  212342. + return -ENOMEM;
  212343. + }
  212344. +
  212345. + ldb->reg = devm_ioremap(&ldb->pdev->dev, res->start,
  212346. + resource_size(res));
  212347. + ldb->control_reg = ldb->reg + 2;
  212348. + ldb->gpr3_reg = ldb->reg + 3;
  212349. +
  212350. + /* ipu selected by platform data setting */
  212351. + setting->dev_id = plat_data->ipu_id;
  212352. +
  212353. + reg = readl(ldb->control_reg);
  212354. +
  212355. + /* refrence resistor select */
  212356. + reg &= ~LDB_BGREF_RMODE_MASK;
  212357. + if (plat_data->ext_ref)
  212358. + reg |= LDB_BGREF_RMODE_EXT;
  212359. + else
  212360. + reg |= LDB_BGREF_RMODE_INT;
  212361. +
  212362. + /* TODO: now only use SPWG data mapping for both channel */
  212363. + reg &= ~(LDB_BIT_MAP_CH0_MASK | LDB_BIT_MAP_CH1_MASK);
  212364. + reg |= LDB_BIT_MAP_CH0_SPWG | LDB_BIT_MAP_CH1_SPWG;
  212365. +
  212366. + /* channel mode setting */
  212367. + reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  212368. + reg &= ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK);
  212369. +
  212370. + if (bits_per_pixel(setting->if_fmt) == 24)
  212371. + reg |= LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24;
  212372. + else
  212373. + reg |= LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18;
  212374. +
  212375. + if (g_ldb_mode >= LDB_SPL_DI0)
  212376. + ldb->mode = g_ldb_mode;
  212377. + else
  212378. + ldb->mode = plat_data->mode;
  212379. +
  212380. + if ((ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) {
  212381. + ret = ldb->mode - LDB_SIN0;
  212382. + if (plat_data->disp_id != ret) {
  212383. + dev_warn(&ldb->pdev->dev,
  212384. + "change IPU DI%d to IPU DI%d for LDB "
  212385. + "channel%d.\n",
  212386. + plat_data->disp_id, ret, ret);
  212387. + plat_data->disp_id = ret;
  212388. + }
  212389. + } else if (((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))
  212390. + && is_imx6_ldb(plat_data)) {
  212391. + if (plat_data->disp_id == plat_data->sec_disp_id) {
  212392. + dev_err(&ldb->pdev->dev,
  212393. + "For LVDS separate mode,"
  212394. + "two DIs should be different!\n");
  212395. + return -EINVAL;
  212396. + }
  212397. +
  212398. + if (((!plat_data->disp_id) && (ldb->mode == LDB_SEP1))
  212399. + || ((plat_data->disp_id) &&
  212400. + (ldb->mode == LDB_SEP0))) {
  212401. + dev_dbg(&ldb->pdev->dev,
  212402. + "LVDS separate mode:"
  212403. + "swap DI configuration!\n");
  212404. + ipu_id = plat_data->ipu_id;
  212405. + disp_id = plat_data->disp_id;
  212406. + plat_data->ipu_id = plat_data->sec_ipu_id;
  212407. + plat_data->disp_id = plat_data->sec_disp_id;
  212408. + plat_data->sec_ipu_id = ipu_id;
  212409. + plat_data->sec_disp_id = disp_id;
  212410. + }
  212411. + }
  212412. +
  212413. + if (ldb->mode == LDB_SPL_DI0) {
  212414. + reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0
  212415. + | LDB_CH1_MODE_EN_TO_DI0;
  212416. + setting->disp_id = 0;
  212417. + } else if (ldb->mode == LDB_SPL_DI1) {
  212418. + reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1
  212419. + | LDB_CH1_MODE_EN_TO_DI1;
  212420. + setting->disp_id = 1;
  212421. + } else if (ldb->mode == LDB_DUL_DI0) {
  212422. + reg &= ~LDB_SPLIT_MODE_EN;
  212423. + reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0;
  212424. + setting->disp_id = 0;
  212425. + } else if (ldb->mode == LDB_DUL_DI1) {
  212426. + reg &= ~LDB_SPLIT_MODE_EN;
  212427. + reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1;
  212428. + setting->disp_id = 1;
  212429. + } else if (ldb->mode == LDB_SIN0) {
  212430. + reg &= ~LDB_SPLIT_MODE_EN;
  212431. + setting->disp_id = plat_data->disp_id;
  212432. + if (setting->disp_id == 0)
  212433. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  212434. + else
  212435. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  212436. + ch_mask = LDB_CH0_MODE_MASK;
  212437. + ch_val = reg & LDB_CH0_MODE_MASK;
  212438. + } else if (ldb->mode == LDB_SIN1) {
  212439. + reg &= ~LDB_SPLIT_MODE_EN;
  212440. + setting->disp_id = plat_data->disp_id;
  212441. + if (setting->disp_id == 0)
  212442. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  212443. + else
  212444. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  212445. + ch_mask = LDB_CH1_MODE_MASK;
  212446. + ch_val = reg & LDB_CH1_MODE_MASK;
  212447. + } else { /* separate mode*/
  212448. + setting->disp_id = plat_data->disp_id;
  212449. +
  212450. + /* first output is LVDS0 or LVDS1 */
  212451. + if (ldb->mode == LDB_SEP0)
  212452. + lvds_channel = 0;
  212453. + else
  212454. + lvds_channel = 1;
  212455. +
  212456. + reg &= ~LDB_SPLIT_MODE_EN;
  212457. +
  212458. + if ((lvds_channel == 0) && (setting->disp_id == 0))
  212459. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  212460. + else if ((lvds_channel == 0) && (setting->disp_id == 1))
  212461. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  212462. + else if ((lvds_channel == 1) && (setting->disp_id == 0))
  212463. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  212464. + else
  212465. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  212466. + ch_mask = lvds_channel ? LDB_CH1_MODE_MASK :
  212467. + LDB_CH0_MODE_MASK;
  212468. + ch_val = reg & ch_mask;
  212469. +
  212470. + if (bits_per_pixel(setting->if_fmt) == 24) {
  212471. + if (lvds_channel == 0)
  212472. + reg &= ~LDB_DATA_WIDTH_CH1_24;
  212473. + else
  212474. + reg &= ~LDB_DATA_WIDTH_CH0_24;
  212475. + } else {
  212476. + if (lvds_channel == 0)
  212477. + reg &= ~LDB_DATA_WIDTH_CH1_18;
  212478. + else
  212479. + reg &= ~LDB_DATA_WIDTH_CH0_18;
  212480. + }
  212481. + }
  212482. +
  212483. + writel(reg, ldb->control_reg);
  212484. + if (ldb->mode < LDB_SIN0) {
  212485. + ch_mask = LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK;
  212486. + ch_val = reg & (LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  212487. + }
  212488. + } else { /* second time for separate mode */
  212489. + if ((ldb->mode == LDB_SPL_DI0) ||
  212490. + (ldb->mode == LDB_SPL_DI1) ||
  212491. + (ldb->mode == LDB_DUL_DI0) ||
  212492. + (ldb->mode == LDB_DUL_DI1) ||
  212493. + (ldb->mode == LDB_SIN0) ||
  212494. + (ldb->mode == LDB_SIN1)) {
  212495. + dev_err(&ldb->pdev->dev, "for second ldb disp"
  212496. + "ldb mode should in separate mode\n");
  212497. + return -EINVAL;
  212498. + }
  212499. +
  212500. + setting_idx = 1;
  212501. + if (is_imx6_ldb(plat_data)) {
  212502. + setting->dev_id = plat_data->sec_ipu_id;
  212503. + setting->disp_id = plat_data->sec_disp_id;
  212504. + } else {
  212505. + setting->dev_id = plat_data->ipu_id;
  212506. + setting->disp_id = !plat_data->disp_id;
  212507. + }
  212508. + if (setting->disp_id == ldb->setting[0].di) {
  212509. + dev_err(&ldb->pdev->dev, "Err: for second ldb disp in"
  212510. + "separate mode, DI should be different!\n");
  212511. + return -EINVAL;
  212512. + }
  212513. +
  212514. + /* second output is LVDS0 or LVDS1 */
  212515. + if (ldb->mode == LDB_SEP0)
  212516. + lvds_channel = 1;
  212517. + else
  212518. + lvds_channel = 0;
  212519. +
  212520. + reg = readl(ldb->control_reg);
  212521. + if ((lvds_channel == 0) && (setting->disp_id == 0))
  212522. + reg |= LDB_CH0_MODE_EN_TO_DI0;
  212523. + else if ((lvds_channel == 0) && (setting->disp_id == 1))
  212524. + reg |= LDB_CH0_MODE_EN_TO_DI1;
  212525. + else if ((lvds_channel == 1) && (setting->disp_id == 0))
  212526. + reg |= LDB_CH1_MODE_EN_TO_DI0;
  212527. + else
  212528. + reg |= LDB_CH1_MODE_EN_TO_DI1;
  212529. + ch_mask = lvds_channel ? LDB_CH1_MODE_MASK :
  212530. + LDB_CH0_MODE_MASK;
  212531. + ch_val = reg & ch_mask;
  212532. +
  212533. + if (bits_per_pixel(setting->if_fmt) == 24) {
  212534. + if (lvds_channel == 0)
  212535. + reg |= LDB_DATA_WIDTH_CH0_24;
  212536. + else
  212537. + reg |= LDB_DATA_WIDTH_CH1_24;
  212538. + } else {
  212539. + if (lvds_channel == 0)
  212540. + reg |= LDB_DATA_WIDTH_CH0_18;
  212541. + else
  212542. + reg |= LDB_DATA_WIDTH_CH1_18;
  212543. + }
  212544. + writel(reg, ldb->control_reg);
  212545. + }
  212546. +
  212547. + /* get clocks */
  212548. + if (is_imx6_ldb(plat_data) &&
  212549. + ((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))) {
  212550. + ldb_clk[6] += lvds_channel;
  212551. + div_3_5_clk[2] += lvds_channel;
  212552. + div_7_clk[2] += lvds_channel;
  212553. + div_sel_clk[2] += lvds_channel;
  212554. + } else {
  212555. + ldb_clk[6] += setting->disp_id;
  212556. + div_3_5_clk[2] += setting->disp_id;
  212557. + div_7_clk[2] += setting->disp_id;
  212558. + div_sel_clk[2] += setting->disp_id;
  212559. + }
  212560. + ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev,
  212561. + ldb_clk);
  212562. + if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) {
  212563. + dev_err(&ldb->pdev->dev, "get ldb clk failed\n");
  212564. + return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk);
  212565. + }
  212566. +
  212567. + ldb->setting[setting_idx].div_3_5_clk = clk_get(&ldb->pdev->dev,
  212568. + div_3_5_clk);
  212569. + if (IS_ERR(ldb->setting[setting_idx].div_3_5_clk)) {
  212570. + dev_err(&ldb->pdev->dev, "get div 3.5 clk failed\n");
  212571. + return PTR_ERR(ldb->setting[setting_idx].div_3_5_clk);
  212572. + }
  212573. + ldb->setting[setting_idx].div_7_clk = clk_get(&ldb->pdev->dev,
  212574. + div_7_clk);
  212575. + if (IS_ERR(ldb->setting[setting_idx].div_7_clk)) {
  212576. + dev_err(&ldb->pdev->dev, "get div 7 clk failed\n");
  212577. + return PTR_ERR(ldb->setting[setting_idx].div_7_clk);
  212578. + }
  212579. +
  212580. + ldb->setting[setting_idx].div_sel_clk = clk_get(&ldb->pdev->dev,
  212581. + div_sel_clk);
  212582. + if (IS_ERR(ldb->setting[setting_idx].div_sel_clk)) {
  212583. + dev_err(&ldb->pdev->dev, "get div sel clk failed\n");
  212584. + return PTR_ERR(ldb->setting[setting_idx].div_sel_clk);
  212585. + }
  212586. +
  212587. + di_clk[3] += setting->dev_id;
  212588. + di_clk[7] += setting->disp_id;
  212589. + ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev,
  212590. + di_clk);
  212591. + if (IS_ERR(ldb->setting[setting_idx].di_clk)) {
  212592. + dev_err(&ldb->pdev->dev, "get di clk failed\n");
  212593. + return PTR_ERR(ldb->setting[setting_idx].di_clk);
  212594. + }
  212595. +
  212596. + ldb->setting[setting_idx].ch_mask = ch_mask;
  212597. + ldb->setting[setting_idx].ch_val = ch_val;
  212598. +
  212599. + if (is_imx6_ldb(plat_data))
  212600. + ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb);
  212601. +
  212602. + /* must use spec video mode defined by driver */
  212603. + ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
  212604. + ldb_modedb, ldb_modedb_sz, NULL, setting->default_bpp);
  212605. + if (ret != 1)
  212606. + fb_videomode_to_var(&setting->fbi->var, &ldb_modedb[0]);
  212607. +
  212608. + INIT_LIST_HEAD(&setting->fbi->modelist);
  212609. + for (i = 0; i < ldb_modedb_sz; i++) {
  212610. + struct fb_videomode m;
  212611. + fb_var_to_videomode(&m, &setting->fbi->var);
  212612. + if (fb_mode_is_equal(&m, &ldb_modedb[i])) {
  212613. + fb_add_videomode(&ldb_modedb[i],
  212614. + &setting->fbi->modelist);
  212615. + break;
  212616. + }
  212617. + }
  212618. +
  212619. + ldb->setting[setting_idx].ipu = setting->dev_id;
  212620. + ldb->setting[setting_idx].di = setting->disp_id;
  212621. +
  212622. + return ret;
  212623. +}
  212624. +
  212625. +static int ldb_post_disp_init(struct mxc_dispdrv_handle *disp,
  212626. + int ipu_id, int disp_id)
  212627. +{
  212628. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  212629. + int setting_idx = ldb->inited ? 1 : 0;
  212630. + int ret = 0;
  212631. +
  212632. + if (!ldb->inited) {
  212633. + ldb->nb.notifier_call = ldb_fb_event;
  212634. + fb_register_client(&ldb->nb);
  212635. + }
  212636. +
  212637. + ret = clk_set_parent(ldb->setting[setting_idx].di_clk,
  212638. + ldb->setting[setting_idx].ldb_di_clk);
  212639. + if (ret) {
  212640. + dev_err(&ldb->pdev->dev, "fail to set ldb_di clk as"
  212641. + "the parent of ipu_di clk\n");
  212642. + return ret;
  212643. + }
  212644. +
  212645. + if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1)) {
  212646. + ret = clk_set_parent(ldb->setting[setting_idx].div_sel_clk,
  212647. + ldb->setting[setting_idx].div_3_5_clk);
  212648. + if (ret) {
  212649. + dev_err(&ldb->pdev->dev, "fail to set div 3.5 clk as"
  212650. + "the parent of div sel clk\n");
  212651. + return ret;
  212652. + }
  212653. + } else {
  212654. + ret = clk_set_parent(ldb->setting[setting_idx].div_sel_clk,
  212655. + ldb->setting[setting_idx].div_7_clk);
  212656. + if (ret) {
  212657. + dev_err(&ldb->pdev->dev, "fail to set div 7 clk as"
  212658. + "the parent of div sel clk\n");
  212659. + return ret;
  212660. + }
  212661. + }
  212662. +
  212663. + /* save active ldb setting for fb notifier */
  212664. + ldb->setting[setting_idx].active = true;
  212665. +
  212666. + ldb->inited = true;
  212667. + return ret;
  212668. +}
  212669. +
  212670. +static void ldb_disp_deinit(struct mxc_dispdrv_handle *disp)
  212671. +{
  212672. + struct ldb_data *ldb = mxc_dispdrv_getdata(disp);
  212673. + int i;
  212674. +
  212675. + writel(0, ldb->control_reg);
  212676. +
  212677. + for (i = 0; i < 2; i++) {
  212678. + clk_disable(ldb->setting[i].ldb_di_clk);
  212679. + clk_put(ldb->setting[i].ldb_di_clk);
  212680. + clk_put(ldb->setting[i].div_3_5_clk);
  212681. + clk_put(ldb->setting[i].div_7_clk);
  212682. + clk_put(ldb->setting[i].div_sel_clk);
  212683. + }
  212684. +
  212685. + fb_unregister_client(&ldb->nb);
  212686. +}
  212687. +
  212688. +static struct mxc_dispdrv_driver ldb_drv = {
  212689. + .name = DISPDRV_LDB,
  212690. + .init = ldb_disp_init,
  212691. + .post_init = ldb_post_disp_init,
  212692. + .deinit = ldb_disp_deinit,
  212693. + .setup = ldb_disp_setup,
  212694. +};
  212695. +
  212696. +static int ldb_suspend(struct platform_device *pdev, pm_message_t state)
  212697. +{
  212698. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  212699. + uint32_t data;
  212700. +
  212701. + if (!ldb->inited)
  212702. + return 0;
  212703. + data = readl(ldb->control_reg);
  212704. + ldb->control_reg_data = data;
  212705. + data &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
  212706. + writel(data, ldb->control_reg);
  212707. +
  212708. + return 0;
  212709. +}
  212710. +
  212711. +static int ldb_resume(struct platform_device *pdev)
  212712. +{
  212713. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  212714. +
  212715. + if (!ldb->inited)
  212716. + return 0;
  212717. + writel(ldb->control_reg_data, ldb->control_reg);
  212718. +
  212719. + return 0;
  212720. +}
  212721. +
  212722. +static struct platform_device_id imx_ldb_devtype[] = {
  212723. + {
  212724. + .name = "ldb-imx6",
  212725. + .driver_data = LDB_IMX6,
  212726. + }, {
  212727. + /* sentinel */
  212728. + }
  212729. +};
  212730. +
  212731. +static const struct of_device_id imx_ldb_dt_ids[] = {
  212732. + { .compatible = "fsl,imx6q-ldb", .data = &imx_ldb_devtype[IMX6_LDB],},
  212733. + { /* sentinel */ }
  212734. +};
  212735. +
  212736. +/*!
  212737. + * This function is called by the driver framework to initialize the LDB
  212738. + * device.
  212739. + *
  212740. + * @param dev The device structure for the LDB passed in by the
  212741. + * driver framework.
  212742. + *
  212743. + * @return Returns 0 on success or negative error code on error
  212744. + */
  212745. +static int ldb_probe(struct platform_device *pdev)
  212746. +{
  212747. + int ret = 0;
  212748. + struct ldb_data *ldb;
  212749. + struct fsl_mxc_ldb_platform_data *plat_data;
  212750. + const struct of_device_id *of_id =
  212751. + of_match_device(imx_ldb_dt_ids, &pdev->dev);
  212752. +
  212753. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  212754. + ldb = devm_kzalloc(&pdev->dev, sizeof(struct ldb_data), GFP_KERNEL);
  212755. + if (!ldb)
  212756. + return -ENOMEM;
  212757. +
  212758. + plat_data = devm_kzalloc(&pdev->dev,
  212759. + sizeof(struct fsl_mxc_ldb_platform_data),
  212760. + GFP_KERNEL);
  212761. + if (!plat_data)
  212762. + return -ENOMEM;
  212763. + pdev->dev.platform_data = plat_data;
  212764. + if (of_id)
  212765. + pdev->id_entry = of_id->data;
  212766. + plat_data->devtype = pdev->id_entry->driver_data;
  212767. +
  212768. + ret = ldb_get_of_property(pdev, plat_data);
  212769. + if (ret < 0) {
  212770. + dev_err(&pdev->dev, "get ldb of property fail\n");
  212771. + return ret;
  212772. + }
  212773. +
  212774. + ldb->pdev = pdev;
  212775. + ldb->disp_ldb = mxc_dispdrv_register(&ldb_drv);
  212776. + mxc_dispdrv_setdata(ldb->disp_ldb, ldb);
  212777. +
  212778. + dev_set_drvdata(&pdev->dev, ldb);
  212779. +
  212780. + dev_dbg(&pdev->dev, "%s exit\n", __func__);
  212781. + return ret;
  212782. +}
  212783. +
  212784. +static int ldb_remove(struct platform_device *pdev)
  212785. +{
  212786. + struct ldb_data *ldb = dev_get_drvdata(&pdev->dev);
  212787. +
  212788. + if (!ldb->inited)
  212789. + return 0;
  212790. + mxc_dispdrv_puthandle(ldb->disp_ldb);
  212791. + mxc_dispdrv_unregister(ldb->disp_ldb);
  212792. + return 0;
  212793. +}
  212794. +
  212795. +static struct platform_driver mxcldb_driver = {
  212796. + .driver = {
  212797. + .name = "mxc_ldb",
  212798. + .of_match_table = imx_ldb_dt_ids,
  212799. + },
  212800. + .probe = ldb_probe,
  212801. + .remove = ldb_remove,
  212802. + .suspend = ldb_suspend,
  212803. + .resume = ldb_resume,
  212804. +};
  212805. +
  212806. +static int __init ldb_init(void)
  212807. +{
  212808. + return platform_driver_register(&mxcldb_driver);
  212809. +}
  212810. +
  212811. +static void __exit ldb_uninit(void)
  212812. +{
  212813. + platform_driver_unregister(&mxcldb_driver);
  212814. +}
  212815. +
  212816. +module_init(ldb_init);
  212817. +module_exit(ldb_uninit);
  212818. +
  212819. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  212820. +MODULE_DESCRIPTION("MXC LDB driver");
  212821. +MODULE_LICENSE("GPL");
  212822. diff -Nur linux-3.14.17/drivers/video/mxc/Makefile linux-imx6-3.14/drivers/video/mxc/Makefile
  212823. --- linux-3.14.17/drivers/video/mxc/Makefile 1970-01-01 01:00:00.000000000 +0100
  212824. +++ linux-imx6-3.14/drivers/video/mxc/Makefile 2014-09-11 18:06:09.534068054 +0200
  212825. @@ -0,0 +1,6 @@
  212826. +obj-$(CONFIG_FB_MXC_LDB) += ldb.o
  212827. +obj-$(CONFIG_FB_MXC_MIPI_DSI) += mipi_dsi.o
  212828. +obj-$(CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL) += mxcfb_hx8369_wvga.o
  212829. +obj-$(CONFIG_FB_MXC_HDMI) += mxc_hdmi.o
  212830. +obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o
  212831. +obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_dispdrv.o mxc_lcdif.o mxc_ipuv3_fb.o
  212832. diff -Nur linux-3.14.17/drivers/video/mxc/mipi_dsi.c linux-imx6-3.14/drivers/video/mxc/mipi_dsi.c
  212833. --- linux-3.14.17/drivers/video/mxc/mipi_dsi.c 1970-01-01 01:00:00.000000000 +0100
  212834. +++ linux-imx6-3.14/drivers/video/mxc/mipi_dsi.c 2014-09-11 18:06:09.534068054 +0200
  212835. @@ -0,0 +1,953 @@
  212836. +/*
  212837. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  212838. + *
  212839. + * This program is free software; you can redistribute it and/or modify
  212840. + * it under the terms of the GNU General Public License as published by
  212841. + * the Free Software Foundation; either version 2 of the License, or
  212842. + * (at your option) any later version.
  212843. +
  212844. + * This program is distributed in the hope that it will be useful,
  212845. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  212846. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  212847. + * GNU General Public License for more details.
  212848. +
  212849. + * You should have received a copy of the GNU General Public License along
  212850. + * with this program; if not, write to the Free Software Foundation, Inc.,
  212851. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  212852. + */
  212853. +
  212854. +#include <linux/types.h>
  212855. +#include <linux/init.h>
  212856. +#include <linux/platform_device.h>
  212857. +#include <linux/err.h>
  212858. +#include <linux/clk.h>
  212859. +#include <linux/console.h>
  212860. +#include <linux/io.h>
  212861. +#include <linux/bitops.h>
  212862. +#include <linux/ipu.h>
  212863. +#include <linux/mfd/syscon.h>
  212864. +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  212865. +#include <linux/mipi_dsi.h>
  212866. +#include <linux/module.h>
  212867. +#include <linux/mxcfb.h>
  212868. +#include <linux/backlight.h>
  212869. +#include <linux/of_device.h>
  212870. +#include <linux/regulator/consumer.h>
  212871. +#include <linux/reset.h>
  212872. +#include <linux/spinlock.h>
  212873. +#include <linux/delay.h>
  212874. +#include <video/mipi_display.h>
  212875. +
  212876. +#include "mxc_dispdrv.h"
  212877. +#include "mipi_dsi.h"
  212878. +
  212879. +#define DISPDRV_MIPI "mipi_dsi"
  212880. +#define ROUND_UP(x) ((x)+1)
  212881. +#define NS2PS_RATIO (1000)
  212882. +#define NUMBER_OF_CHUNKS (0x8)
  212883. +#define NULL_PKT_SIZE (0x8)
  212884. +#define PHY_BTA_MAXTIME (0xd00)
  212885. +#define PHY_LP2HS_MAXTIME (0x40)
  212886. +#define PHY_HS2LP_MAXTIME (0x40)
  212887. +#define PHY_STOP_WAIT_TIME (0x20)
  212888. +#define DSI_CLKMGR_CFG_CLK_DIV (0x107)
  212889. +#define DSI_GEN_PLD_DATA_BUF_ENTRY (0x10)
  212890. +#define MIPI_MUX_CTRL(v) (((v) & 0x3) << 4)
  212891. +#define MIPI_LCD_SLEEP_MODE_DELAY (120)
  212892. +#define MIPI_DSI_REG_RW_TIMEOUT (20)
  212893. +#define MIPI_DSI_PHY_TIMEOUT (10)
  212894. +
  212895. +static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
  212896. +#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  212897. + {
  212898. + "TRULY-WVGA",
  212899. + {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup}
  212900. + },
  212901. +#endif
  212902. + {
  212903. + "", {NULL, NULL}
  212904. + }
  212905. +};
  212906. +
  212907. +struct _mipi_dsi_phy_pll_clk {
  212908. + u32 max_phy_clk;
  212909. + u32 config;
  212910. +};
  212911. +
  212912. +/* configure data for DPHY PLL 27M reference clk out */
  212913. +static const struct _mipi_dsi_phy_pll_clk mipi_dsi_phy_pll_clk_table[] = {
  212914. + {1000, 0x74}, /* 950-1000MHz */
  212915. + {950, 0x54}, /* 900-950Mhz */
  212916. + {900, 0x34}, /* 850-900Mhz */
  212917. + {850, 0x14}, /* 800-850MHz */
  212918. + {800, 0x32}, /* 750-800MHz */
  212919. + {750, 0x12}, /* 700-750Mhz */
  212920. + {700, 0x30}, /* 650-700Mhz */
  212921. + {650, 0x10}, /* 600-650MHz */
  212922. + {600, 0x2e}, /* 550-600MHz */
  212923. + {550, 0x0e}, /* 500-550Mhz */
  212924. + {500, 0x2c}, /* 450-500Mhz */
  212925. + {450, 0x0c}, /* 400-450MHz */
  212926. + {400, 0x4a}, /* 360-400MHz */
  212927. + {360, 0x2a}, /* 330-360Mhz */
  212928. + {330, 0x48}, /* 300-330Mhz */
  212929. + {300, 0x28}, /* 270-300MHz */
  212930. + {270, 0x08}, /* 250-270MHz */
  212931. + {250, 0x46}, /* 240-250Mhz */
  212932. + {240, 0x26}, /* 210-240Mhz */
  212933. + {210, 0x06}, /* 200-210MHz */
  212934. + {200, 0x44}, /* 180-200MHz */
  212935. + {180, 0x24}, /* 160-180MHz */
  212936. + {160, 0x04}, /* 150-160MHz */
  212937. +};
  212938. +
  212939. +static int valid_mode(int pixel_fmt)
  212940. +{
  212941. + return ((pixel_fmt == IPU_PIX_FMT_RGB24) ||
  212942. + (pixel_fmt == IPU_PIX_FMT_BGR24) ||
  212943. + (pixel_fmt == IPU_PIX_FMT_RGB666) ||
  212944. + (pixel_fmt == IPU_PIX_FMT_RGB565) ||
  212945. + (pixel_fmt == IPU_PIX_FMT_BGR666) ||
  212946. + (pixel_fmt == IPU_PIX_FMT_RGB332));
  212947. +}
  212948. +
  212949. +static inline void mipi_dsi_read_register(struct mipi_dsi_info *mipi_dsi,
  212950. + u32 reg, u32 *val)
  212951. +{
  212952. + *val = ioread32(mipi_dsi->mmio_base + reg);
  212953. + dev_dbg(&mipi_dsi->pdev->dev, "read_reg:0x%02x, val:0x%08x.\n",
  212954. + reg, *val);
  212955. +}
  212956. +
  212957. +static inline void mipi_dsi_write_register(struct mipi_dsi_info *mipi_dsi,
  212958. + u32 reg, u32 val)
  212959. +{
  212960. + iowrite32(val, mipi_dsi->mmio_base + reg);
  212961. + dev_dbg(&mipi_dsi->pdev->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n",
  212962. + reg, val);
  212963. +}
  212964. +
  212965. +int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
  212966. + u8 data_type, const u32 *buf, int len)
  212967. +{
  212968. + u32 val;
  212969. + u32 status = 0;
  212970. + int write_len = len;
  212971. + uint32_t timeout = 0;
  212972. +
  212973. + if (len) {
  212974. + /* generic long write command */
  212975. + while (len / DSI_GEN_PLD_DATA_BUF_SIZE) {
  212976. + mipi_dsi_write_register(mipi_dsi,
  212977. + MIPI_DSI_GEN_PLD_DATA, *buf);
  212978. + buf++;
  212979. + len -= DSI_GEN_PLD_DATA_BUF_SIZE;
  212980. + mipi_dsi_read_register(mipi_dsi,
  212981. + MIPI_DSI_CMD_PKT_STATUS, &status);
  212982. + while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
  212983. + DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
  212984. + msleep(1);
  212985. + timeout++;
  212986. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  212987. + return -EIO;
  212988. + mipi_dsi_read_register(mipi_dsi,
  212989. + MIPI_DSI_CMD_PKT_STATUS, &status);
  212990. + }
  212991. + }
  212992. + /* write the remainder bytes */
  212993. + if (len > 0) {
  212994. + while ((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) ==
  212995. + DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL) {
  212996. + msleep(1);
  212997. + timeout++;
  212998. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  212999. + return -EIO;
  213000. + mipi_dsi_read_register(mipi_dsi,
  213001. + MIPI_DSI_CMD_PKT_STATUS, &status);
  213002. + }
  213003. + mipi_dsi_write_register(mipi_dsi,
  213004. + MIPI_DSI_GEN_PLD_DATA, *buf);
  213005. + }
  213006. +
  213007. + val = data_type | ((write_len & DSI_GEN_HDR_DATA_MASK)
  213008. + << DSI_GEN_HDR_DATA_SHIFT);
  213009. + } else {
  213010. + /* generic short write command */
  213011. + val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
  213012. + << DSI_GEN_HDR_DATA_SHIFT);
  213013. + }
  213014. +
  213015. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
  213016. + while ((status & DSI_CMD_PKT_STATUS_GEN_CMD_FULL) ==
  213017. + DSI_CMD_PKT_STATUS_GEN_CMD_FULL) {
  213018. + msleep(1);
  213019. + timeout++;
  213020. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  213021. + return -EIO;
  213022. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  213023. + &status);
  213024. + }
  213025. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
  213026. +
  213027. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &status);
  213028. + while (!((status & DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ==
  213029. + DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY) ||
  213030. + !((status & DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY) ==
  213031. + DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY)) {
  213032. + msleep(1);
  213033. + timeout++;
  213034. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  213035. + return -EIO;
  213036. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  213037. + &status);
  213038. + }
  213039. +
  213040. + return 0;
  213041. +}
  213042. +
  213043. +int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
  213044. + u8 data_type, u32 *buf, int len)
  213045. +{
  213046. + u32 val;
  213047. + int read_len = 0;
  213048. + uint32_t timeout = 0;
  213049. +
  213050. + if (!len) {
  213051. + mipi_dbg("%s, len = 0 invalid error!\n", __func__);
  213052. + return -EINVAL;
  213053. + }
  213054. +
  213055. + val = data_type | ((*buf & DSI_GEN_HDR_DATA_MASK)
  213056. + << DSI_GEN_HDR_DATA_SHIFT);
  213057. + memset(buf, 0, len);
  213058. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_GEN_HDR, val);
  213059. +
  213060. + /* wait for cmd to sent out */
  213061. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
  213062. + while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) !=
  213063. + DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
  213064. + msleep(1);
  213065. + timeout++;
  213066. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  213067. + return -EIO;
  213068. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  213069. + &val);
  213070. + }
  213071. + /* wait for entire response stroed in FIFO */
  213072. + while ((val & DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) ==
  213073. + DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY) {
  213074. + msleep(1);
  213075. + timeout++;
  213076. + if (timeout == MIPI_DSI_REG_RW_TIMEOUT)
  213077. + return -EIO;
  213078. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  213079. + &val);
  213080. + }
  213081. +
  213082. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS, &val);
  213083. + while (!(val & DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY)) {
  213084. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_GEN_PLD_DATA, buf);
  213085. + read_len += DSI_GEN_PLD_DATA_BUF_SIZE;
  213086. + buf++;
  213087. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_PKT_STATUS,
  213088. + &val);
  213089. + if (read_len == (DSI_GEN_PLD_DATA_BUF_ENTRY *
  213090. + DSI_GEN_PLD_DATA_BUF_SIZE))
  213091. + break;
  213092. + }
  213093. +
  213094. + if ((len <= read_len) &&
  213095. + ((len + DSI_GEN_PLD_DATA_BUF_SIZE) >= read_len))
  213096. + return 0;
  213097. + else {
  213098. + dev_err(&mipi_dsi->pdev->dev,
  213099. + "actually read_len:%d != len:%d.\n", read_len, len);
  213100. + return -ERANGE;
  213101. + }
  213102. +}
  213103. +
  213104. +int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
  213105. + u8 cmd, const u32 *param, int num)
  213106. +{
  213107. + int err = 0;
  213108. + u32 buf[DSI_CMD_BUF_MAXSIZE];
  213109. +
  213110. + switch (cmd) {
  213111. + case MIPI_DCS_EXIT_SLEEP_MODE:
  213112. + case MIPI_DCS_ENTER_SLEEP_MODE:
  213113. + case MIPI_DCS_SET_DISPLAY_ON:
  213114. + case MIPI_DCS_SET_DISPLAY_OFF:
  213115. + buf[0] = cmd;
  213116. + err = mipi_dsi_pkt_write(mipi_dsi,
  213117. + MIPI_DSI_DCS_SHORT_WRITE, buf, 0);
  213118. + break;
  213119. +
  213120. + default:
  213121. + dev_err(&mipi_dsi->pdev->dev,
  213122. + "MIPI DSI DCS Command:0x%x Not supported!\n", cmd);
  213123. + break;
  213124. + }
  213125. +
  213126. + return err;
  213127. +}
  213128. +
  213129. +static void mipi_dsi_dphy_init(struct mipi_dsi_info *mipi_dsi,
  213130. + u32 cmd, u32 data)
  213131. +{
  213132. + u32 val;
  213133. + u32 timeout = 0;
  213134. +
  213135. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  213136. + DSI_PHY_IF_CTRL_RESET);
  213137. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_POWERUP);
  213138. +
  213139. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  213140. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1,
  213141. + (0x10000 | cmd));
  213142. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
  213143. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  213144. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL1, (0 | data));
  213145. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 2);
  213146. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TST_CTRL0, 0);
  213147. + val = DSI_PHY_RSTZ_EN_CLK | DSI_PHY_RSTZ_DISABLE_RST |
  213148. + DSI_PHY_RSTZ_DISABLE_SHUTDOWN;
  213149. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, val);
  213150. +
  213151. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  213152. + while ((val & DSI_PHY_STATUS_LOCK) != DSI_PHY_STATUS_LOCK) {
  213153. + msleep(1);
  213154. + timeout++;
  213155. + if (timeout == MIPI_DSI_PHY_TIMEOUT) {
  213156. + dev_err(&mipi_dsi->pdev->dev,
  213157. + "Error: phy lock timeout!\n");
  213158. + break;
  213159. + }
  213160. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  213161. + }
  213162. + timeout = 0;
  213163. + while ((val & DSI_PHY_STATUS_STOPSTATE_CLK_LANE) !=
  213164. + DSI_PHY_STATUS_STOPSTATE_CLK_LANE) {
  213165. + msleep(1);
  213166. + timeout++;
  213167. + if (timeout == MIPI_DSI_PHY_TIMEOUT) {
  213168. + dev_err(&mipi_dsi->pdev->dev,
  213169. + "Error: phy lock lane timeout!\n");
  213170. + break;
  213171. + }
  213172. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_PHY_STATUS, &val);
  213173. + }
  213174. +}
  213175. +
  213176. +static void mipi_dsi_enable_controller(struct mipi_dsi_info *mipi_dsi,
  213177. + bool init)
  213178. +{
  213179. + u32 val;
  213180. + u32 lane_byte_clk_period;
  213181. + struct fb_videomode *mode = mipi_dsi->mode;
  213182. + struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
  213183. +
  213184. + if (init) {
  213185. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  213186. + DSI_PWRUP_RESET);
  213187. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ,
  213188. + DSI_PHY_RSTZ_RST);
  213189. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CLKMGR_CFG,
  213190. + DSI_CLKMGR_CFG_CLK_DIV);
  213191. +
  213192. + if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
  213193. + val = DSI_DPI_CFG_VSYNC_ACT_LOW;
  213194. + if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
  213195. + val |= DSI_DPI_CFG_HSYNC_ACT_LOW;
  213196. + if ((mode->sync & FB_SYNC_OE_LOW_ACT))
  213197. + val |= DSI_DPI_CFG_DATAEN_ACT_LOW;
  213198. + if (MIPI_RGB666_LOOSELY == lcd_config->dpi_fmt)
  213199. + val |= DSI_DPI_CFG_EN18LOOSELY;
  213200. + val |= (lcd_config->dpi_fmt & DSI_DPI_CFG_COLORCODE_MASK)
  213201. + << DSI_DPI_CFG_COLORCODE_SHIFT;
  213202. + val |= (lcd_config->virtual_ch & DSI_DPI_CFG_VID_MASK)
  213203. + << DSI_DPI_CFG_VID_SHIFT;
  213204. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_DPI_CFG, val);
  213205. +
  213206. + val = DSI_PCKHDL_CFG_EN_BTA |
  213207. + DSI_PCKHDL_CFG_EN_ECC_RX |
  213208. + DSI_PCKHDL_CFG_EN_CRC_RX;
  213209. +
  213210. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PCKHDL_CFG, val);
  213211. +
  213212. + val = (mode->xres & DSI_VID_PKT_CFG_VID_PKT_SZ_MASK)
  213213. + << DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT;
  213214. + val |= (NUMBER_OF_CHUNKS & DSI_VID_PKT_CFG_NUM_CHUNKS_MASK)
  213215. + << DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT;
  213216. + val |= (NULL_PKT_SIZE & DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK)
  213217. + << DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT;
  213218. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_PKT_CFG, val);
  213219. +
  213220. + /* enable LP mode when TX DCS cmd and enable DSI command mode */
  213221. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG,
  213222. + MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER);
  213223. +
  213224. + /* mipi lane byte clk period in ns unit */
  213225. + lane_byte_clk_period = NS2PS_RATIO /
  213226. + (lcd_config->max_phy_clk / BITS_PER_BYTE);
  213227. + val = ROUND_UP(mode->hsync_len * mode->pixclock /
  213228. + NS2PS_RATIO / lane_byte_clk_period)
  213229. + << DSI_TME_LINE_CFG_HSA_TIME_SHIFT;
  213230. + val |= ROUND_UP(mode->left_margin * mode->pixclock /
  213231. + NS2PS_RATIO / lane_byte_clk_period)
  213232. + << DSI_TME_LINE_CFG_HBP_TIME_SHIFT;
  213233. + val |= ROUND_UP((mode->left_margin + mode->right_margin +
  213234. + mode->hsync_len + mode->xres) * mode->pixclock
  213235. + / NS2PS_RATIO / lane_byte_clk_period)
  213236. + << DSI_TME_LINE_CFG_HLINE_TIME_SHIFT;
  213237. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_TMR_LINE_CFG, val);
  213238. +
  213239. + val = ((mode->vsync_len & DSI_VTIMING_CFG_VSA_LINES_MASK)
  213240. + << DSI_VTIMING_CFG_VSA_LINES_SHIFT);
  213241. + val |= ((mode->upper_margin & DSI_VTIMING_CFG_VBP_LINES_MASK)
  213242. + << DSI_VTIMING_CFG_VBP_LINES_SHIFT);
  213243. + val |= ((mode->lower_margin & DSI_VTIMING_CFG_VFP_LINES_MASK)
  213244. + << DSI_VTIMING_CFG_VFP_LINES_SHIFT);
  213245. + val |= ((mode->yres & DSI_VTIMING_CFG_V_ACT_LINES_MASK)
  213246. + << DSI_VTIMING_CFG_V_ACT_LINES_SHIFT);
  213247. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VTIMING_CFG, val);
  213248. +
  213249. + val = ((PHY_BTA_MAXTIME & DSI_PHY_TMR_CFG_BTA_TIME_MASK)
  213250. + << DSI_PHY_TMR_CFG_BTA_TIME_SHIFT);
  213251. + val |= ((PHY_LP2HS_MAXTIME & DSI_PHY_TMR_CFG_LP2HS_TIME_MASK)
  213252. + << DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT);
  213253. + val |= ((PHY_HS2LP_MAXTIME & DSI_PHY_TMR_CFG_HS2LP_TIME_MASK)
  213254. + << DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT);
  213255. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_TMR_CFG, val);
  213256. +
  213257. + val = (((lcd_config->data_lane_num - 1) &
  213258. + DSI_PHY_IF_CFG_N_LANES_MASK)
  213259. + << DSI_PHY_IF_CFG_N_LANES_SHIFT);
  213260. + val |= ((PHY_STOP_WAIT_TIME & DSI_PHY_IF_CFG_WAIT_TIME_MASK)
  213261. + << DSI_PHY_IF_CFG_WAIT_TIME_SHIFT);
  213262. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CFG, val);
  213263. +
  213264. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &val);
  213265. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &val);
  213266. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, 0);
  213267. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, 0);
  213268. +
  213269. + mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
  213270. + mipi_dsi->dphy_pll_config);
  213271. + } else {
  213272. + mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
  213273. + mipi_dsi->dphy_pll_config);
  213274. + }
  213275. +}
  213276. +
  213277. +static void mipi_dsi_disable_controller(struct mipi_dsi_info *mipi_dsi)
  213278. +{
  213279. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  213280. + DSI_PHY_IF_CTRL_RESET);
  213281. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP, DSI_PWRUP_RESET);
  213282. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_RSTZ, DSI_PHY_RSTZ_RST);
  213283. +}
  213284. +
  213285. +static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
  213286. +{
  213287. + u32 mask0;
  213288. + u32 mask1;
  213289. + u32 status0;
  213290. + u32 status1;
  213291. + struct mipi_dsi_info *mipi_dsi;
  213292. +
  213293. + mipi_dsi = (struct mipi_dsi_info *)data;
  213294. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST0, &status0);
  213295. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_ST1, &status1);
  213296. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK0, &mask0);
  213297. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_ERROR_MSK1, &mask1);
  213298. +
  213299. + if ((status0 & (~mask0)) || (status1 & (~mask1))) {
  213300. + dev_err(&mipi_dsi->pdev->dev,
  213301. + "mipi_dsi IRQ status0:0x%x, status1:0x%x!\n",
  213302. + status0, status1);
  213303. + }
  213304. +
  213305. + return IRQ_HANDLED;
  213306. +}
  213307. +
  213308. +static inline void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
  213309. + bool cmd_mode)
  213310. +{
  213311. + u32 val;
  213312. +
  213313. + if (cmd_mode) {
  213314. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  213315. + DSI_PWRUP_RESET);
  213316. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
  213317. + val |= MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
  213318. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
  213319. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, 0);
  213320. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  213321. + DSI_PWRUP_POWERUP);
  213322. + } else {
  213323. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  213324. + DSI_PWRUP_RESET);
  213325. + /* Disable Command mode when tranfering video data */
  213326. + mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
  213327. + val &= ~MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
  213328. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
  213329. + val = DSI_VID_MODE_CFG_EN | DSI_VID_MODE_CFG_EN_BURSTMODE |
  213330. + DSI_VID_MODE_CFG_EN_LP_MODE;
  213331. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
  213332. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
  213333. + DSI_PWRUP_POWERUP);
  213334. + mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
  213335. + DSI_PHY_IF_CTRL_TX_REQ_CLK_HS);
  213336. + }
  213337. +}
  213338. +
  213339. +static int mipi_dsi_power_on(struct mxc_dispdrv_handle *disp)
  213340. +{
  213341. + int err;
  213342. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  213343. +
  213344. + if (!mipi_dsi->dsi_power_on) {
  213345. + clk_prepare_enable(mipi_dsi->dphy_clk);
  213346. + clk_prepare_enable(mipi_dsi->cfg_clk);
  213347. + mipi_dsi_enable_controller(mipi_dsi, false);
  213348. + mipi_dsi_set_mode(mipi_dsi, false);
  213349. + /* host send pclk/hsync/vsync for two frames before sleep-out */
  213350. + msleep((1000/mipi_dsi->mode->refresh + 1) << 1);
  213351. + mipi_dsi_set_mode(mipi_dsi, true);
  213352. + err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
  213353. + NULL, 0);
  213354. + if (err) {
  213355. + dev_err(&mipi_dsi->pdev->dev,
  213356. + "MIPI DSI DCS Command sleep-in error!\n");
  213357. + }
  213358. + msleep(MIPI_LCD_SLEEP_MODE_DELAY);
  213359. + mipi_dsi_set_mode(mipi_dsi, false);
  213360. + mipi_dsi->dsi_power_on = 1;
  213361. + }
  213362. +
  213363. + return 0;
  213364. +}
  213365. +
  213366. +void mipi_dsi_power_off(struct mxc_dispdrv_handle *disp)
  213367. +{
  213368. + int err;
  213369. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  213370. +
  213371. + if (mipi_dsi->dsi_power_on) {
  213372. + mipi_dsi_set_mode(mipi_dsi, true);
  213373. + err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
  213374. + NULL, 0);
  213375. + if (err) {
  213376. + dev_err(&mipi_dsi->pdev->dev,
  213377. + "MIPI DSI DCS Command display on error!\n");
  213378. + }
  213379. + /* To allow time for the supply voltages
  213380. + * and clock circuits to stabilize.
  213381. + */
  213382. + msleep(5);
  213383. + /* video stream timing on */
  213384. + mipi_dsi_set_mode(mipi_dsi, false);
  213385. + msleep(MIPI_LCD_SLEEP_MODE_DELAY);
  213386. +
  213387. + mipi_dsi_set_mode(mipi_dsi, true);
  213388. + mipi_dsi_disable_controller(mipi_dsi);
  213389. + mipi_dsi->dsi_power_on = 0;
  213390. + clk_disable_unprepare(mipi_dsi->dphy_clk);
  213391. + clk_disable_unprepare(mipi_dsi->cfg_clk);
  213392. + }
  213393. +}
  213394. +
  213395. +static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
  213396. + struct mxc_dispdrv_setting *setting)
  213397. +{
  213398. + int err;
  213399. + int size;
  213400. + int i;
  213401. + struct fb_videomode *mipi_lcd_modedb;
  213402. + struct fb_videomode mode;
  213403. + struct device *dev = &mipi_dsi->pdev->dev;
  213404. +
  213405. + for (i = 0; i < ARRAY_SIZE(mipi_dsi_lcd_db); i++) {
  213406. + if (!strcmp(mipi_dsi->lcd_panel,
  213407. + mipi_dsi_lcd_db[i].lcd_panel)) {
  213408. + mipi_dsi->lcd_callback =
  213409. + &mipi_dsi_lcd_db[i].lcd_callback;
  213410. + break;
  213411. + }
  213412. + }
  213413. + if (i == ARRAY_SIZE(mipi_dsi_lcd_db)) {
  213414. + dev_err(dev, "failed to find supported lcd panel.\n");
  213415. + return -EINVAL;
  213416. + }
  213417. + /* get the videomode in the order: cmdline->platform data->driver */
  213418. + mipi_dsi->lcd_callback->get_mipi_lcd_videomode(&mipi_lcd_modedb, &size,
  213419. + &mipi_dsi->lcd_config);
  213420. + err = fb_find_mode(&setting->fbi->var, setting->fbi,
  213421. + setting->dft_mode_str,
  213422. + mipi_lcd_modedb, size, NULL,
  213423. + setting->default_bpp);
  213424. + if (err != 1)
  213425. + fb_videomode_to_var(&setting->fbi->var, mipi_lcd_modedb);
  213426. +
  213427. + INIT_LIST_HEAD(&setting->fbi->modelist);
  213428. + for (i = 0; i < size; i++) {
  213429. + fb_var_to_videomode(&mode, &setting->fbi->var);
  213430. + if (fb_mode_is_equal(&mode, mipi_lcd_modedb + i)) {
  213431. + err = fb_add_videomode(mipi_lcd_modedb + i,
  213432. + &setting->fbi->modelist);
  213433. + /* Note: only support fb mode from driver */
  213434. + mipi_dsi->mode = mipi_lcd_modedb + i;
  213435. + break;
  213436. + }
  213437. + }
  213438. + if ((err < 0) || (size == i)) {
  213439. + dev_err(dev, "failed to add videomode.\n");
  213440. + return err;
  213441. + }
  213442. +
  213443. + for (i = 0; i < ARRAY_SIZE(mipi_dsi_phy_pll_clk_table); i++) {
  213444. + if (mipi_dsi_phy_pll_clk_table[i].max_phy_clk <
  213445. + mipi_dsi->lcd_config->max_phy_clk)
  213446. + break;
  213447. + }
  213448. + if ((i == ARRAY_SIZE(mipi_dsi_phy_pll_clk_table)) ||
  213449. + (mipi_dsi->lcd_config->max_phy_clk >
  213450. + mipi_dsi_phy_pll_clk_table[0].max_phy_clk)) {
  213451. + dev_err(dev, "failed to find data in"
  213452. + "mipi_dsi_phy_pll_clk_table.\n");
  213453. + return -EINVAL;
  213454. + }
  213455. + mipi_dsi->dphy_pll_config = mipi_dsi_phy_pll_clk_table[--i].config;
  213456. + dev_dbg(dev, "dphy_pll_config:0x%x.\n", mipi_dsi->dphy_pll_config);
  213457. +
  213458. + return 0;
  213459. +}
  213460. +
  213461. +int mipi_dsi_enable(struct mxc_dispdrv_handle *disp)
  213462. +{
  213463. + int err;
  213464. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  213465. +
  213466. + if (!mipi_dsi->lcd_inited) {
  213467. + err = clk_prepare_enable(mipi_dsi->dphy_clk);
  213468. + err |= clk_prepare_enable(mipi_dsi->cfg_clk);
  213469. + if (err)
  213470. + dev_err(&mipi_dsi->pdev->dev,
  213471. + "clk enable error:%d!\n", err);
  213472. + mipi_dsi_enable_controller(mipi_dsi, true);
  213473. + err = mipi_dsi->lcd_callback->mipi_lcd_setup(
  213474. + mipi_dsi);
  213475. + if (err < 0) {
  213476. + dev_err(&mipi_dsi->pdev->dev,
  213477. + "failed to init mipi lcd.");
  213478. + clk_disable_unprepare(mipi_dsi->dphy_clk);
  213479. + clk_disable_unprepare(mipi_dsi->cfg_clk);
  213480. + return err;
  213481. + }
  213482. + mipi_dsi_set_mode(mipi_dsi, false);
  213483. + mipi_dsi->dsi_power_on = 1;
  213484. + mipi_dsi->lcd_inited = 1;
  213485. + }
  213486. + mipi_dsi_power_on(mipi_dsi->disp_mipi);
  213487. +
  213488. + return 0;
  213489. +}
  213490. +
  213491. +static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
  213492. + struct mxc_dispdrv_setting *setting)
  213493. +{
  213494. + struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
  213495. + struct device *dev = &mipi_dsi->pdev->dev;
  213496. + int ret = 0;
  213497. +
  213498. + if (!valid_mode(setting->if_fmt)) {
  213499. + dev_warn(dev, "Input pixel format not valid"
  213500. + "use default RGB24\n");
  213501. + setting->if_fmt = IPU_PIX_FMT_RGB24;
  213502. + }
  213503. +
  213504. + setting->dev_id = mipi_dsi->dev_id;
  213505. + setting->disp_id = mipi_dsi->disp_id;
  213506. +
  213507. + ret = mipi_dsi_lcd_init(mipi_dsi, setting);
  213508. + if (ret) {
  213509. + dev_err(dev, "failed to init mipi dsi lcd\n");
  213510. + return ret;
  213511. + }
  213512. +
  213513. + dev_dbg(dev, "MIPI DSI dispdrv inited!\n");
  213514. + return ret;
  213515. +}
  213516. +
  213517. +static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
  213518. +{
  213519. + struct mipi_dsi_info *mipi_dsi;
  213520. +
  213521. + mipi_dsi = mxc_dispdrv_getdata(disp);
  213522. +
  213523. + mipi_dsi_power_off(mipi_dsi->disp_mipi);
  213524. + if (mipi_dsi->bl)
  213525. + backlight_device_unregister(mipi_dsi->bl);
  213526. +}
  213527. +
  213528. +static struct mxc_dispdrv_driver mipi_dsi_drv = {
  213529. + .name = DISPDRV_MIPI,
  213530. + .init = mipi_dsi_disp_init,
  213531. + .deinit = mipi_dsi_disp_deinit,
  213532. + .enable = mipi_dsi_enable,
  213533. + .disable = mipi_dsi_power_off,
  213534. +};
  213535. +
  213536. +static int imx6q_mipi_dsi_get_mux(int dev_id, int disp_id)
  213537. +{
  213538. + if (dev_id > 1 || disp_id > 1)
  213539. + return -EINVAL;
  213540. +
  213541. + return (dev_id << 5) | (disp_id << 4);
  213542. +}
  213543. +
  213544. +static struct mipi_dsi_bus_mux imx6q_mipi_dsi_mux[] = {
  213545. + {
  213546. + .reg = IOMUXC_GPR3,
  213547. + .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
  213548. + .get_mux = imx6q_mipi_dsi_get_mux,
  213549. + },
  213550. +};
  213551. +
  213552. +static int imx6dl_mipi_dsi_get_mux(int dev_id, int disp_id)
  213553. +{
  213554. + if (dev_id > 1 || disp_id > 1)
  213555. + return -EINVAL;
  213556. +
  213557. + /* MIPI DSI source is LCDIF */
  213558. + if (dev_id)
  213559. + disp_id = 0;
  213560. +
  213561. + return (dev_id << 5) | (disp_id << 4);
  213562. +}
  213563. +
  213564. +static struct mipi_dsi_bus_mux imx6dl_mipi_dsi_mux[] = {
  213565. + {
  213566. + .reg = IOMUXC_GPR3,
  213567. + .mask = IMX6Q_GPR3_MIPI_MUX_CTL_MASK,
  213568. + .get_mux = imx6dl_mipi_dsi_get_mux,
  213569. + },
  213570. +};
  213571. +
  213572. +static const struct of_device_id imx_mipi_dsi_dt_ids[] = {
  213573. + { .compatible = "fsl,imx6q-mipi-dsi", .data = imx6q_mipi_dsi_mux, },
  213574. + { .compatible = "fsl,imx6dl-mipi-dsi", .data = imx6dl_mipi_dsi_mux, },
  213575. + { }
  213576. +};
  213577. +MODULE_DEVICE_TABLE(of, imx_mipi_dsi_dt_ids);
  213578. +
  213579. +/**
  213580. + * This function is called by the driver framework to initialize the MIPI DSI
  213581. + * device.
  213582. + *
  213583. + * @param pdev The device structure for the MIPI DSI passed in by the
  213584. + * driver framework.
  213585. + *
  213586. + * @return Returns 0 on success or negative error code on error
  213587. + */
  213588. +static int mipi_dsi_probe(struct platform_device *pdev)
  213589. +{
  213590. + struct device_node *np = pdev->dev.of_node;
  213591. + const struct of_device_id *of_id =
  213592. + of_match_device(of_match_ptr(imx_mipi_dsi_dt_ids),
  213593. + &pdev->dev);
  213594. + struct mipi_dsi_info *mipi_dsi;
  213595. + struct resource *res;
  213596. + u32 dev_id, disp_id;
  213597. + const char *lcd_panel;
  213598. + unsigned int mux;
  213599. + int ret = 0;
  213600. +
  213601. + mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
  213602. + if (!mipi_dsi)
  213603. + return -ENOMEM;
  213604. +
  213605. + ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
  213606. + if (ret) {
  213607. + dev_err(&pdev->dev, "failed to read of property lcd_panel\n");
  213608. + return ret;
  213609. + }
  213610. +
  213611. + ret = of_property_read_u32(np, "dev_id", &dev_id);
  213612. + if (ret) {
  213613. + dev_err(&pdev->dev, "failed to read of property dev_id\n");
  213614. + return ret;
  213615. + }
  213616. + ret = of_property_read_u32(np, "disp_id", &disp_id);
  213617. + if (ret) {
  213618. + dev_err(&pdev->dev, "failed to read of property disp_id\n");
  213619. + return ret;
  213620. + }
  213621. + mipi_dsi->dev_id = dev_id;
  213622. + mipi_dsi->disp_id = disp_id;
  213623. +
  213624. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  213625. + if (!res) {
  213626. + dev_err(&pdev->dev, "failed to get platform resource 0\n");
  213627. + return -ENODEV;
  213628. + }
  213629. +
  213630. + if (!devm_request_mem_region(&pdev->dev, res->start,
  213631. + resource_size(res), pdev->name))
  213632. + return -EBUSY;
  213633. +
  213634. + mipi_dsi->mmio_base = devm_ioremap(&pdev->dev, res->start,
  213635. + resource_size(res));
  213636. + if (!mipi_dsi->mmio_base)
  213637. + return -EBUSY;
  213638. +
  213639. + mipi_dsi->irq = platform_get_irq(pdev, 0);
  213640. + if (mipi_dsi->irq < 0) {
  213641. + dev_err(&pdev->dev, "failed get device irq\n");
  213642. + return -ENODEV;
  213643. + }
  213644. +
  213645. + ret = devm_request_irq(&pdev->dev, mipi_dsi->irq,
  213646. + mipi_dsi_irq_handler,
  213647. + 0, "mipi_dsi", mipi_dsi);
  213648. + if (ret) {
  213649. + dev_err(&pdev->dev, "failed to request irq\n");
  213650. + return ret;
  213651. + }
  213652. +
  213653. + mipi_dsi->dphy_clk = devm_clk_get(&pdev->dev, "mipi_pllref_clk");
  213654. + if (IS_ERR(mipi_dsi->dphy_clk)) {
  213655. + dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
  213656. + return PTR_ERR(mipi_dsi->dphy_clk);
  213657. + }
  213658. +
  213659. + mipi_dsi->cfg_clk = devm_clk_get(&pdev->dev, "mipi_cfg_clk");
  213660. + if (IS_ERR(mipi_dsi->cfg_clk)) {
  213661. + dev_err(&pdev->dev, "failed to get cfg_clk\n");
  213662. + return PTR_ERR(mipi_dsi->cfg_clk);
  213663. + }
  213664. +
  213665. + mipi_dsi->disp_power_on = devm_regulator_get(&pdev->dev,
  213666. + "disp-power-on");
  213667. + if (!IS_ERR(mipi_dsi->disp_power_on)) {
  213668. + ret = regulator_enable(mipi_dsi->disp_power_on);
  213669. + if (ret) {
  213670. + dev_err(&pdev->dev, "failed to enable display "
  213671. + "power regulator, err=%d\n", ret);
  213672. + return ret;
  213673. + }
  213674. + } else {
  213675. + mipi_dsi->disp_power_on = NULL;
  213676. + }
  213677. +
  213678. + ret = device_reset(&pdev->dev);
  213679. + if (ret) {
  213680. + dev_err(&pdev->dev, "failed to reset: %d\n", ret);
  213681. + goto dev_reset_fail;
  213682. + }
  213683. +
  213684. + if (of_id)
  213685. + mipi_dsi->bus_mux = of_id->data;
  213686. +
  213687. + mipi_dsi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
  213688. + if (IS_ERR(mipi_dsi->regmap)) {
  213689. + dev_err(&pdev->dev, "failed to get parent regmap\n");
  213690. + ret = PTR_ERR(mipi_dsi->regmap);
  213691. + goto get_parent_regmap_fail;
  213692. + }
  213693. +
  213694. + mux = mipi_dsi->bus_mux->get_mux(dev_id, disp_id);
  213695. + if (mux >= 0)
  213696. + regmap_update_bits(mipi_dsi->regmap, mipi_dsi->bus_mux->reg,
  213697. + mipi_dsi->bus_mux->mask, mux);
  213698. + else
  213699. + dev_warn(&pdev->dev, "invalid dev_id or disp_id muxing\n");
  213700. +
  213701. + mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL);
  213702. + if (!mipi_dsi->lcd_panel) {
  213703. + dev_err(&pdev->dev, "failed to allocate lcd panel name\n");
  213704. + ret = -ENOMEM;
  213705. + goto kstrdup_fail;
  213706. + }
  213707. +
  213708. + mipi_dsi->pdev = pdev;
  213709. + mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
  213710. + if (IS_ERR(mipi_dsi->disp_mipi)) {
  213711. + dev_err(&pdev->dev, "mxc_dispdrv_register error\n");
  213712. + ret = PTR_ERR(mipi_dsi->disp_mipi);
  213713. + goto dispdrv_reg_fail;
  213714. + }
  213715. +
  213716. + mxc_dispdrv_setdata(mipi_dsi->disp_mipi, mipi_dsi);
  213717. + dev_set_drvdata(&pdev->dev, mipi_dsi);
  213718. +
  213719. + dev_info(&pdev->dev, "i.MX MIPI DSI driver probed\n");
  213720. + return ret;
  213721. +
  213722. +dispdrv_reg_fail:
  213723. + kfree(mipi_dsi->lcd_panel);
  213724. +kstrdup_fail:
  213725. +get_parent_regmap_fail:
  213726. +dev_reset_fail:
  213727. + if (mipi_dsi->disp_power_on)
  213728. + regulator_disable(mipi_dsi->disp_power_on);
  213729. + return ret;
  213730. +}
  213731. +
  213732. +static void mipi_dsi_shutdown(struct platform_device *pdev)
  213733. +{
  213734. + struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
  213735. +
  213736. + mipi_dsi_power_off(mipi_dsi->disp_mipi);
  213737. +}
  213738. +
  213739. +static int mipi_dsi_remove(struct platform_device *pdev)
  213740. +{
  213741. + struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
  213742. +
  213743. + mxc_dispdrv_puthandle(mipi_dsi->disp_mipi);
  213744. + mxc_dispdrv_unregister(mipi_dsi->disp_mipi);
  213745. +
  213746. + if (mipi_dsi->disp_power_on)
  213747. + regulator_disable(mipi_dsi->disp_power_on);
  213748. +
  213749. + kfree(mipi_dsi->lcd_panel);
  213750. + dev_set_drvdata(&pdev->dev, NULL);
  213751. +
  213752. + return 0;
  213753. +}
  213754. +
  213755. +static struct platform_driver mipi_dsi_driver = {
  213756. + .driver = {
  213757. + .of_match_table = imx_mipi_dsi_dt_ids,
  213758. + .name = "mxc_mipi_dsi",
  213759. + },
  213760. + .probe = mipi_dsi_probe,
  213761. + .remove = mipi_dsi_remove,
  213762. + .shutdown = mipi_dsi_shutdown,
  213763. +};
  213764. +
  213765. +static int __init mipi_dsi_init(void)
  213766. +{
  213767. + int err;
  213768. +
  213769. + err = platform_driver_register(&mipi_dsi_driver);
  213770. + if (err) {
  213771. + pr_err("mipi_dsi_driver register failed\n");
  213772. + return -ENODEV;
  213773. + }
  213774. + pr_info("MIPI DSI driver module loaded\n");
  213775. + return 0;
  213776. +}
  213777. +
  213778. +static void __exit mipi_dsi_cleanup(void)
  213779. +{
  213780. + platform_driver_unregister(&mipi_dsi_driver);
  213781. +}
  213782. +
  213783. +module_init(mipi_dsi_init);
  213784. +module_exit(mipi_dsi_cleanup);
  213785. +
  213786. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  213787. +MODULE_DESCRIPTION("i.MX MIPI DSI driver");
  213788. +MODULE_LICENSE("GPL");
  213789. diff -Nur linux-3.14.17/drivers/video/mxc/mipi_dsi.h linux-imx6-3.14/drivers/video/mxc/mipi_dsi.h
  213790. --- linux-3.14.17/drivers/video/mxc/mipi_dsi.h 1970-01-01 01:00:00.000000000 +0100
  213791. +++ linux-imx6-3.14/drivers/video/mxc/mipi_dsi.h 2014-09-11 18:06:09.534068054 +0200
  213792. @@ -0,0 +1,112 @@
  213793. +/*
  213794. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  213795. + *
  213796. + * This program is free software; you can redistribute it and/or modify
  213797. + * it under the terms of the GNU General Public License as published by
  213798. + * the Free Software Foundation; either version 2 of the License, or
  213799. + * (at your option) any later version.
  213800. +
  213801. + * This program is distributed in the hope that it will be useful,
  213802. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  213803. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  213804. + * GNU General Public License for more details.
  213805. +
  213806. + * You should have received a copy of the GNU General Public License along
  213807. + * with this program; if not, write to the Free Software Foundation, Inc.,
  213808. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  213809. + */
  213810. +
  213811. +#ifndef __MIPI_DSI_H__
  213812. +#define __MIPI_DSI_H__
  213813. +
  213814. +#include <linux/regmap.h>
  213815. +
  213816. +#ifdef DEBUG
  213817. +#define mipi_dbg(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
  213818. +#else
  213819. +#define mipi_dbg(fmt, ...)
  213820. +#endif
  213821. +
  213822. +#define DSI_CMD_BUF_MAXSIZE (32)
  213823. +
  213824. +/* DPI interface pixel color coding map */
  213825. +enum mipi_dsi_dpi_fmt {
  213826. + MIPI_RGB565_PACKED = 0,
  213827. + MIPI_RGB565_LOOSELY,
  213828. + MIPI_RGB565_CONFIG3,
  213829. + MIPI_RGB666_PACKED,
  213830. + MIPI_RGB666_LOOSELY,
  213831. + MIPI_RGB888,
  213832. +};
  213833. +
  213834. +struct mipi_lcd_config {
  213835. + u32 virtual_ch;
  213836. + u32 data_lane_num;
  213837. + /* device max DPHY clock in MHz unit */
  213838. + u32 max_phy_clk;
  213839. + enum mipi_dsi_dpi_fmt dpi_fmt;
  213840. +};
  213841. +
  213842. +struct mipi_dsi_info;
  213843. +struct mipi_dsi_lcd_callback {
  213844. + /* callback for lcd panel operation */
  213845. + void (*get_mipi_lcd_videomode)(struct fb_videomode **, int *,
  213846. + struct mipi_lcd_config **);
  213847. + int (*mipi_lcd_setup)(struct mipi_dsi_info *);
  213848. +
  213849. +};
  213850. +
  213851. +struct mipi_dsi_match_lcd {
  213852. + char *lcd_panel;
  213853. + struct mipi_dsi_lcd_callback lcd_callback;
  213854. +};
  213855. +
  213856. +struct mipi_dsi_bus_mux {
  213857. + int reg;
  213858. + int mask;
  213859. + int (*get_mux) (int dev_id, int disp_id);
  213860. +};
  213861. +
  213862. +/* driver private data */
  213863. +struct mipi_dsi_info {
  213864. + struct platform_device *pdev;
  213865. + void __iomem *mmio_base;
  213866. + struct regmap *regmap;
  213867. + const struct mipi_dsi_bus_mux *bus_mux;
  213868. + int dsi_power_on;
  213869. + int lcd_inited;
  213870. + u32 dphy_pll_config;
  213871. + int dev_id;
  213872. + int disp_id;
  213873. + char *lcd_panel;
  213874. + int irq;
  213875. + struct clk *dphy_clk;
  213876. + struct clk *cfg_clk;
  213877. + struct mxc_dispdrv_handle *disp_mipi;
  213878. + struct fb_videomode *mode;
  213879. + struct regulator *disp_power_on;
  213880. + struct mipi_lcd_config *lcd_config;
  213881. + /* board related power control */
  213882. + struct backlight_device *bl;
  213883. + /* callback for lcd panel operation */
  213884. + struct mipi_dsi_lcd_callback *lcd_callback;
  213885. +};
  213886. +
  213887. +int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi,
  213888. + u8 data_type, const u32 *buf, int len);
  213889. +int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi,
  213890. + u8 data_type, u32 *buf, int len);
  213891. +int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi,
  213892. + u8 cmd, const u32 *param, int num);
  213893. +
  213894. +#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  213895. +void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
  213896. + struct mipi_lcd_config **data);
  213897. +int mipid_hx8369_lcd_setup(struct mipi_dsi_info *);
  213898. +#endif
  213899. +
  213900. +#ifndef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
  213901. +#error "Please configure MIPI LCD panel, we cannot find one!"
  213902. +#endif
  213903. +
  213904. +#endif
  213905. diff -Nur linux-3.14.17/drivers/video/mxc/mxc_dispdrv.c linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.c
  213906. --- linux-3.14.17/drivers/video/mxc/mxc_dispdrv.c 1970-01-01 01:00:00.000000000 +0100
  213907. +++ linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.c 2014-09-11 18:06:09.534068054 +0200
  213908. @@ -0,0 +1,150 @@
  213909. +/*
  213910. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  213911. + */
  213912. +
  213913. +/*
  213914. + * The code contained herein is licensed under the GNU General Public
  213915. + * License. You may obtain a copy of the GNU General Public License
  213916. + * Version 2 or later at the following locations:
  213917. + *
  213918. + * http://www.opensource.org/licenses/gpl-license.html
  213919. + * http://www.gnu.org/copyleft/gpl.html
  213920. + */
  213921. +
  213922. +/*!
  213923. + * @file mxc_dispdrv.c
  213924. + * @brief mxc display driver framework.
  213925. + *
  213926. + * A display device driver could call mxc_dispdrv_register(drv) in its dev_probe() function.
  213927. + * Move all dev_probe() things into mxc_dispdrv_driver->init(), init() function should init
  213928. + * and feedback setting;
  213929. + * Necessary deferred operations can be done in mxc_dispdrv_driver->post_init(),
  213930. + * after dev_id and disp_id pass usage check;
  213931. + * Move all dev_remove() things into mxc_dispdrv_driver->deinit();
  213932. + * Move all dev_suspend() things into fb_notifier for SUSPEND, if there is;
  213933. + * Move all dev_resume() things into fb_notifier for RESUME, if there is;
  213934. + *
  213935. + * ipuv3 fb driver could call mxc_dispdrv_gethandle(name, setting) before a fb
  213936. + * need be added, with fbi param passing by setting, after
  213937. + * mxc_dispdrv_gethandle() return, FB driver should get the basic setting
  213938. + * about fbi info and ipuv3-hw (ipu_id and disp_id).
  213939. + *
  213940. + * @ingroup Framebuffer
  213941. + */
  213942. +
  213943. +#include <linux/kernel.h>
  213944. +#include <linux/module.h>
  213945. +#include <linux/list.h>
  213946. +#include <linux/mutex.h>
  213947. +#include <linux/slab.h>
  213948. +#include <linux/err.h>
  213949. +#include <linux/string.h>
  213950. +#include "mxc_dispdrv.h"
  213951. +
  213952. +static LIST_HEAD(dispdrv_list);
  213953. +static DEFINE_MUTEX(dispdrv_lock);
  213954. +
  213955. +struct mxc_dispdrv_entry {
  213956. + /* Note: drv always the first element */
  213957. + struct mxc_dispdrv_driver *drv;
  213958. + bool active;
  213959. + void *priv;
  213960. + struct list_head list;
  213961. +};
  213962. +
  213963. +struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv)
  213964. +{
  213965. + struct mxc_dispdrv_entry *new;
  213966. +
  213967. + mutex_lock(&dispdrv_lock);
  213968. +
  213969. + new = kzalloc(sizeof(struct mxc_dispdrv_entry), GFP_KERNEL);
  213970. + if (!new) {
  213971. + mutex_unlock(&dispdrv_lock);
  213972. + return ERR_PTR(-ENOMEM);
  213973. + }
  213974. +
  213975. + new->drv = drv;
  213976. + list_add_tail(&new->list, &dispdrv_list);
  213977. +
  213978. + mutex_unlock(&dispdrv_lock);
  213979. +
  213980. + return (struct mxc_dispdrv_handle *)new;
  213981. +}
  213982. +EXPORT_SYMBOL_GPL(mxc_dispdrv_register);
  213983. +
  213984. +int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle)
  213985. +{
  213986. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  213987. +
  213988. + if (entry) {
  213989. + mutex_lock(&dispdrv_lock);
  213990. + list_del(&entry->list);
  213991. + mutex_unlock(&dispdrv_lock);
  213992. + kfree(entry);
  213993. + return 0;
  213994. + } else
  213995. + return -EINVAL;
  213996. +}
  213997. +EXPORT_SYMBOL_GPL(mxc_dispdrv_unregister);
  213998. +
  213999. +struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
  214000. + struct mxc_dispdrv_setting *setting)
  214001. +{
  214002. + int ret, found = 0;
  214003. + struct mxc_dispdrv_entry *entry;
  214004. +
  214005. + mutex_lock(&dispdrv_lock);
  214006. + list_for_each_entry(entry, &dispdrv_list, list) {
  214007. + if (!strcmp(entry->drv->name, name) && (entry->drv->init)) {
  214008. + ret = entry->drv->init((struct mxc_dispdrv_handle *)
  214009. + entry, setting);
  214010. + if (ret >= 0) {
  214011. + entry->active = true;
  214012. + found = 1;
  214013. + break;
  214014. + }
  214015. + }
  214016. + }
  214017. + mutex_unlock(&dispdrv_lock);
  214018. +
  214019. + return found ? (struct mxc_dispdrv_handle *)entry:ERR_PTR(-ENODEV);
  214020. +}
  214021. +EXPORT_SYMBOL_GPL(mxc_dispdrv_gethandle);
  214022. +
  214023. +void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle)
  214024. +{
  214025. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  214026. +
  214027. + mutex_lock(&dispdrv_lock);
  214028. + if (entry && entry->active && entry->drv->deinit) {
  214029. + entry->drv->deinit(handle);
  214030. + entry->active = false;
  214031. + }
  214032. + mutex_unlock(&dispdrv_lock);
  214033. +
  214034. +}
  214035. +EXPORT_SYMBOL_GPL(mxc_dispdrv_puthandle);
  214036. +
  214037. +int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data)
  214038. +{
  214039. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  214040. +
  214041. + if (entry) {
  214042. + entry->priv = data;
  214043. + return 0;
  214044. + } else
  214045. + return -EINVAL;
  214046. +}
  214047. +EXPORT_SYMBOL_GPL(mxc_dispdrv_setdata);
  214048. +
  214049. +void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle)
  214050. +{
  214051. + struct mxc_dispdrv_entry *entry = (struct mxc_dispdrv_entry *)handle;
  214052. +
  214053. + if (entry) {
  214054. + return entry->priv;
  214055. + } else
  214056. + return ERR_PTR(-EINVAL);
  214057. +}
  214058. +EXPORT_SYMBOL_GPL(mxc_dispdrv_getdata);
  214059. diff -Nur linux-3.14.17/drivers/video/mxc/mxc_dispdrv.h linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.h
  214060. --- linux-3.14.17/drivers/video/mxc/mxc_dispdrv.h 1970-01-01 01:00:00.000000000 +0100
  214061. +++ linux-imx6-3.14/drivers/video/mxc/mxc_dispdrv.h 2014-09-11 18:06:09.534068054 +0200
  214062. @@ -0,0 +1,54 @@
  214063. +/*
  214064. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  214065. + */
  214066. +
  214067. +/*
  214068. + * The code contained herein is licensed under the GNU General Public
  214069. + * License. You may obtain a copy of the GNU General Public License
  214070. + * Version 2 or later at the following locations:
  214071. + *
  214072. + * http://www.opensource.org/licenses/gpl-license.html
  214073. + * http://www.gnu.org/copyleft/gpl.html
  214074. + */
  214075. +#ifndef __MXC_DISPDRV_H__
  214076. +#define __MXC_DISPDRV_H__
  214077. +#include <linux/fb.h>
  214078. +
  214079. +struct mxc_dispdrv_handle {
  214080. + struct mxc_dispdrv_driver *drv;
  214081. +};
  214082. +
  214083. +struct mxc_dispdrv_setting {
  214084. + /*input-feedback parameter*/
  214085. + struct fb_info *fbi;
  214086. + int if_fmt;
  214087. + int default_bpp;
  214088. + char *dft_mode_str;
  214089. +
  214090. + /*feedback parameter*/
  214091. + int dev_id;
  214092. + int disp_id;
  214093. +};
  214094. +
  214095. +struct mxc_dispdrv_driver {
  214096. + const char *name;
  214097. + int (*init) (struct mxc_dispdrv_handle *, struct mxc_dispdrv_setting *);
  214098. + /* deferred operations after dev_id and disp_id pass usage check */
  214099. + int (*post_init) (struct mxc_dispdrv_handle *, int dev_id, int disp_id);
  214100. + void (*deinit) (struct mxc_dispdrv_handle *);
  214101. + /* display driver enable function for extension */
  214102. + int (*enable) (struct mxc_dispdrv_handle *);
  214103. + /* display driver disable function, called at early part of fb_blank */
  214104. + void (*disable) (struct mxc_dispdrv_handle *);
  214105. + /* display driver setup function, called at early part of fb_set_par */
  214106. + int (*setup) (struct mxc_dispdrv_handle *, struct fb_info *fbi);
  214107. +};
  214108. +
  214109. +struct mxc_dispdrv_handle *mxc_dispdrv_register(struct mxc_dispdrv_driver *drv);
  214110. +int mxc_dispdrv_unregister(struct mxc_dispdrv_handle *handle);
  214111. +struct mxc_dispdrv_handle *mxc_dispdrv_gethandle(char *name,
  214112. + struct mxc_dispdrv_setting *setting);
  214113. +void mxc_dispdrv_puthandle(struct mxc_dispdrv_handle *handle);
  214114. +int mxc_dispdrv_setdata(struct mxc_dispdrv_handle *handle, void *data);
  214115. +void *mxc_dispdrv_getdata(struct mxc_dispdrv_handle *handle);
  214116. +#endif
  214117. diff -Nur linux-3.14.17/drivers/video/mxc/mxc_edid.c linux-imx6-3.14/drivers/video/mxc/mxc_edid.c
  214118. --- linux-3.14.17/drivers/video/mxc/mxc_edid.c 1970-01-01 01:00:00.000000000 +0100
  214119. +++ linux-imx6-3.14/drivers/video/mxc/mxc_edid.c 2014-09-11 18:06:09.534068054 +0200
  214120. @@ -0,0 +1,762 @@
  214121. +/*
  214122. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  214123. + */
  214124. +
  214125. +/*
  214126. + * The code contained herein is licensed under the GNU General Public
  214127. + * License. You may obtain a copy of the GNU General Public License
  214128. + * Version 2 or later at the following locations:
  214129. + *
  214130. + * http://www.opensource.org/licenses/gpl-license.html
  214131. + * http://www.gnu.org/copyleft/gpl.html
  214132. + */
  214133. +
  214134. +/*!
  214135. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  214136. + */
  214137. +
  214138. +/*!
  214139. + * @file mxc_edid.c
  214140. + *
  214141. + * @brief MXC EDID driver
  214142. + *
  214143. + * @ingroup Framebuffer
  214144. + */
  214145. +
  214146. +/*!
  214147. + * Include files
  214148. + */
  214149. +#include <linux/i2c.h>
  214150. +#include <linux/fb.h>
  214151. +#include <video/mxc_edid.h>
  214152. +#include "../edid.h"
  214153. +
  214154. +#undef DEBUG /* define this for verbose EDID parsing output */
  214155. +#ifdef DEBUG
  214156. +#define DPRINTK(fmt, args...) printk(fmt, ## args)
  214157. +#else
  214158. +#define DPRINTK(fmt, args...)
  214159. +#endif
  214160. +
  214161. +const struct fb_videomode mxc_cea_mode[64] = {
  214162. + /* #1: 640x480p@59.94/60Hz 4:3 */
  214163. + [1] = {
  214164. + NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
  214165. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214166. + },
  214167. + /* #2: 720x480p@59.94/60Hz 4:3 */
  214168. + [2] = {
  214169. + NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
  214170. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214171. + },
  214172. + /* #3: 720x480p@59.94/60Hz 16:9 */
  214173. + [3] = {
  214174. + NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
  214175. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214176. + },
  214177. + /* #4: 1280x720p@59.94/60Hz 16:9 */
  214178. + [4] = {
  214179. + NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
  214180. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214181. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  214182. + },
  214183. + /* #5: 1920x1080i@59.94/60Hz 16:9 */
  214184. + [5] = {
  214185. + NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
  214186. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214187. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214188. + },
  214189. + /* #6: 720(1440)x480iH@59.94/60Hz 4:3 */
  214190. + [6] = {
  214191. + NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
  214192. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214193. + },
  214194. + /* #7: 720(1440)x480iH@59.94/60Hz 16:9 */
  214195. + [7] = {
  214196. + NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
  214197. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214198. + },
  214199. + /* #8: 720(1440)x240pH@59.94/60Hz 4:3 */
  214200. + [8] = {
  214201. + NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
  214202. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214203. + },
  214204. + /* #9: 720(1440)x240pH@59.94/60Hz 16:9 */
  214205. + [9] = {
  214206. + NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
  214207. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214208. + },
  214209. + /* #14: 1440x480p@59.94/60Hz 4:3 */
  214210. + [14] = {
  214211. + NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
  214212. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214213. + },
  214214. + /* #15: 1440x480p@59.94/60Hz 16:9 */
  214215. + [15] = {
  214216. + NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
  214217. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214218. + },
  214219. + /* #16: 1920x1080p@60Hz 16:9 */
  214220. + [16] = {
  214221. + NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
  214222. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214223. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214224. + },
  214225. + /* #17: 720x576pH@50Hz 4:3 */
  214226. + [17] = {
  214227. + NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
  214228. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214229. + },
  214230. + /* #18: 720x576pH@50Hz 16:9 */
  214231. + [18] = {
  214232. + NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
  214233. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214234. + },
  214235. + /* #19: 1280x720p@50Hz */
  214236. + [19] = {
  214237. + NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
  214238. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214239. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214240. + },
  214241. + /* #20: 1920x1080i@50Hz */
  214242. + [20] = {
  214243. + NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
  214244. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214245. + FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214246. + },
  214247. + /* #23: 720(1440)x288pH@50Hz 4:3 */
  214248. + [23] = {
  214249. + NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
  214250. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214251. + },
  214252. + /* #24: 720(1440)x288pH@50Hz 16:9 */
  214253. + [24] = {
  214254. + NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
  214255. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214256. + },
  214257. + /* #29: 720(1440)x576pH@50Hz 4:3 */
  214258. + [29] = {
  214259. + NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
  214260. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
  214261. + },
  214262. + /* #30: 720(1440)x576pH@50Hz 16:9 */
  214263. + [30] = {
  214264. + NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
  214265. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214266. + },
  214267. + /* #31: 1920x1080p@50Hz */
  214268. + [31] = {
  214269. + NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5,
  214270. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214271. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214272. + },
  214273. + /* #32: 1920x1080p@23.98/24Hz */
  214274. + [32] = {
  214275. + NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
  214276. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214277. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214278. + },
  214279. + /* #33: 1920x1080p@25Hz */
  214280. + [33] = {
  214281. + NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5,
  214282. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214283. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214284. + },
  214285. + /* #34: 1920x1080p@30Hz */
  214286. + [34] = {
  214287. + NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5,
  214288. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214289. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
  214290. + },
  214291. + /* #41: 1280x720p@100Hz 16:9 */
  214292. + [41] = {
  214293. + NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5,
  214294. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214295. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  214296. + },
  214297. + /* #47: 1280x720p@119.88/120Hz 16:9 */
  214298. + [47] = {
  214299. + NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5,
  214300. + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  214301. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
  214302. + },
  214303. +};
  214304. +
  214305. +/*
  214306. + * We have a special version of fb_mode_is_equal that ignores
  214307. + * pixclock, since for many CEA modes, 2 frequencies are supported
  214308. + * e.g. 640x480 @ 60Hz or 59.94Hz
  214309. + */
  214310. +int mxc_edid_fb_mode_is_equal(bool use_aspect,
  214311. + const struct fb_videomode *mode1,
  214312. + const struct fb_videomode *mode2)
  214313. +{
  214314. + u32 mask;
  214315. +
  214316. + if (use_aspect)
  214317. + mask = ~0;
  214318. + else
  214319. + mask = ~FB_VMODE_ASPECT_MASK;
  214320. +
  214321. + return (mode1->xres == mode2->xres &&
  214322. + mode1->yres == mode2->yres &&
  214323. + mode1->hsync_len == mode2->hsync_len &&
  214324. + mode1->vsync_len == mode2->vsync_len &&
  214325. + mode1->left_margin == mode2->left_margin &&
  214326. + mode1->right_margin == mode2->right_margin &&
  214327. + mode1->upper_margin == mode2->upper_margin &&
  214328. + mode1->lower_margin == mode2->lower_margin &&
  214329. + mode1->sync == mode2->sync &&
  214330. + /* refresh check, 59.94Hz and 60Hz have the same parameter
  214331. + * in struct of mxc_cea_mode */
  214332. + abs(mode1->refresh - mode2->refresh) <= 1 &&
  214333. + (mode1->vmode & mask) == (mode2->vmode & mask));
  214334. +}
  214335. +
  214336. +static void get_detailed_timing(unsigned char *block,
  214337. + struct fb_videomode *mode)
  214338. +{
  214339. + mode->xres = H_ACTIVE;
  214340. + mode->yres = V_ACTIVE;
  214341. + mode->pixclock = PIXEL_CLOCK;
  214342. + mode->pixclock /= 1000;
  214343. + mode->pixclock = KHZ2PICOS(mode->pixclock);
  214344. + mode->right_margin = H_SYNC_OFFSET;
  214345. + mode->left_margin = (H_ACTIVE + H_BLANKING) -
  214346. + (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
  214347. + mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
  214348. + V_SYNC_WIDTH;
  214349. + mode->lower_margin = V_SYNC_OFFSET;
  214350. + mode->hsync_len = H_SYNC_WIDTH;
  214351. + mode->vsync_len = V_SYNC_WIDTH;
  214352. + if (HSYNC_POSITIVE)
  214353. + mode->sync |= FB_SYNC_HOR_HIGH_ACT;
  214354. + if (VSYNC_POSITIVE)
  214355. + mode->sync |= FB_SYNC_VERT_HIGH_ACT;
  214356. + mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
  214357. + (V_ACTIVE + V_BLANKING));
  214358. + if (INTERLACED) {
  214359. + mode->yres *= 2;
  214360. + mode->upper_margin *= 2;
  214361. + mode->lower_margin *= 2;
  214362. + mode->vsync_len *= 2;
  214363. + mode->vmode |= FB_VMODE_INTERLACED;
  214364. + }
  214365. + mode->flag = FB_MODE_IS_DETAILED;
  214366. +
  214367. + if ((H_SIZE / 16) == (V_SIZE / 9))
  214368. + mode->vmode |= FB_VMODE_ASPECT_16_9;
  214369. + else if ((H_SIZE / 4) == (V_SIZE / 3))
  214370. + mode->vmode |= FB_VMODE_ASPECT_4_3;
  214371. + else if ((mode->xres / 16) == (mode->yres / 9))
  214372. + mode->vmode |= FB_VMODE_ASPECT_16_9;
  214373. + else if ((mode->xres / 4) == (mode->yres / 3))
  214374. + mode->vmode |= FB_VMODE_ASPECT_4_3;
  214375. +
  214376. + if (mode->vmode & FB_VMODE_ASPECT_16_9)
  214377. + DPRINTK("Aspect ratio: 16:9\n");
  214378. + if (mode->vmode & FB_VMODE_ASPECT_4_3)
  214379. + DPRINTK("Aspect ratio: 4:3\n");
  214380. + DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
  214381. + DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
  214382. + H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
  214383. + DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
  214384. + V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
  214385. + DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
  214386. + (VSYNC_POSITIVE) ? "+" : "-");
  214387. +}
  214388. +
  214389. +int mxc_edid_parse_ext_blk(unsigned char *edid,
  214390. + struct mxc_edid_cfg *cfg,
  214391. + struct fb_monspecs *specs)
  214392. +{
  214393. + char detail_timing_desc_offset;
  214394. + struct fb_videomode *mode, *m;
  214395. + unsigned char index = 0x0;
  214396. + unsigned char *block;
  214397. + int i, num = 0, revision;
  214398. +
  214399. + if (edid[index++] != 0x2) /* only support cea ext block now */
  214400. + return -1;
  214401. + revision = edid[index++];
  214402. + DPRINTK("cea extent revision %d\n", revision);
  214403. + mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
  214404. + if (mode == NULL)
  214405. + return -1;
  214406. +
  214407. + detail_timing_desc_offset = edid[index++];
  214408. +
  214409. + if (revision >= 2) {
  214410. + cfg->cea_underscan = (edid[index] >> 7) & 0x1;
  214411. + cfg->cea_basicaudio = (edid[index] >> 6) & 0x1;
  214412. + cfg->cea_ycbcr444 = (edid[index] >> 5) & 0x1;
  214413. + cfg->cea_ycbcr422 = (edid[index] >> 4) & 0x1;
  214414. +
  214415. + DPRINTK("CEA underscan %d\n", cfg->cea_underscan);
  214416. + DPRINTK("CEA basicaudio %d\n", cfg->cea_basicaudio);
  214417. + DPRINTK("CEA ycbcr444 %d\n", cfg->cea_ycbcr444);
  214418. + DPRINTK("CEA ycbcr422 %d\n", cfg->cea_ycbcr422);
  214419. + }
  214420. +
  214421. + if (revision >= 3) {
  214422. + /* short desc */
  214423. + DPRINTK("CEA Short desc timmings\n");
  214424. + index++;
  214425. + while (index < detail_timing_desc_offset) {
  214426. + unsigned char tagcode, blklen;
  214427. +
  214428. + tagcode = (edid[index] >> 5) & 0x7;
  214429. + blklen = (edid[index]) & 0x1f;
  214430. +
  214431. + DPRINTK("Tagcode %x Len %d\n", tagcode, blklen);
  214432. +
  214433. + switch (tagcode) {
  214434. + case 0x2: /*Video data block*/
  214435. + {
  214436. + int cea_idx;
  214437. + i = 0;
  214438. + while (i < blklen) {
  214439. + index++;
  214440. + cea_idx = edid[index] & 0x7f;
  214441. + if (cea_idx < ARRAY_SIZE(mxc_cea_mode) &&
  214442. + (mxc_cea_mode[cea_idx].xres)) {
  214443. + DPRINTK("Support CEA Format #%d\n", cea_idx);
  214444. + mode[num] = mxc_cea_mode[cea_idx];
  214445. + mode[num].flag |= FB_MODE_IS_STANDARD;
  214446. + num++;
  214447. + }
  214448. + i++;
  214449. + }
  214450. + break;
  214451. + }
  214452. + case 0x3: /*Vendor specific data*/
  214453. + {
  214454. + unsigned char IEEE_reg_iden[3];
  214455. + unsigned char deep_color;
  214456. + unsigned char latency_present;
  214457. + unsigned char I_latency_present;
  214458. + unsigned char hdmi_video_present;
  214459. + unsigned char hdmi_3d_present;
  214460. + unsigned char hdmi_3d_multi_present;
  214461. + unsigned char hdmi_vic_len;
  214462. + unsigned char hdmi_3d_len;
  214463. + unsigned char index_inc = 0;
  214464. + unsigned char vsd_end;
  214465. +
  214466. + vsd_end = index + blklen;
  214467. +
  214468. + IEEE_reg_iden[0] = edid[index+1];
  214469. + IEEE_reg_iden[1] = edid[index+2];
  214470. + IEEE_reg_iden[2] = edid[index+3];
  214471. + cfg->physical_address[0] = (edid[index+4] & 0xf0) >> 4;
  214472. + cfg->physical_address[1] = (edid[index+4] & 0x0f);
  214473. + cfg->physical_address[2] = (edid[index+5] & 0xf0) >> 4;
  214474. + cfg->physical_address[3] = (edid[index+5] & 0x0f);
  214475. +
  214476. + if ((IEEE_reg_iden[0] == 0x03) &&
  214477. + (IEEE_reg_iden[1] == 0x0c) &&
  214478. + (IEEE_reg_iden[2] == 0x00))
  214479. + cfg->hdmi_cap = 1;
  214480. +
  214481. + if (blklen > 5) {
  214482. + deep_color = edid[index+6];
  214483. + if (deep_color & 0x80)
  214484. + cfg->vsd_support_ai = true;
  214485. + if (deep_color & 0x40)
  214486. + cfg->vsd_dc_48bit = true;
  214487. + if (deep_color & 0x20)
  214488. + cfg->vsd_dc_36bit = true;
  214489. + if (deep_color & 0x10)
  214490. + cfg->vsd_dc_30bit = true;
  214491. + if (deep_color & 0x08)
  214492. + cfg->vsd_dc_y444 = true;
  214493. + if (deep_color & 0x01)
  214494. + cfg->vsd_dvi_dual = true;
  214495. + }
  214496. +
  214497. + DPRINTK("VSD hdmi capability %d\n", cfg->hdmi_cap);
  214498. + DPRINTK("VSD support ai %d\n", cfg->vsd_support_ai);
  214499. + DPRINTK("VSD support deep color 48bit %d\n", cfg->vsd_dc_48bit);
  214500. + DPRINTK("VSD support deep color 36bit %d\n", cfg->vsd_dc_36bit);
  214501. + DPRINTK("VSD support deep color 30bit %d\n", cfg->vsd_dc_30bit);
  214502. + DPRINTK("VSD support deep color y444 %d\n", cfg->vsd_dc_y444);
  214503. + DPRINTK("VSD support dvi dual %d\n", cfg->vsd_dvi_dual);
  214504. +
  214505. + if (blklen > 6)
  214506. + cfg->vsd_max_tmdsclk_rate = edid[index+7] * 5;
  214507. + DPRINTK("VSD MAX TMDS CLOCK RATE %d\n", cfg->vsd_max_tmdsclk_rate);
  214508. +
  214509. + if (blklen > 7) {
  214510. + latency_present = edid[index+8] >> 7;
  214511. + I_latency_present = (edid[index+8] & 0x40) >> 6;
  214512. + hdmi_video_present = (edid[index+8] & 0x20) >> 5;
  214513. + cfg->vsd_cnc3 = (edid[index+8] & 0x8) >> 3;
  214514. + cfg->vsd_cnc2 = (edid[index+8] & 0x4) >> 2;
  214515. + cfg->vsd_cnc1 = (edid[index+8] & 0x2) >> 1;
  214516. + cfg->vsd_cnc0 = edid[index+8] & 0x1;
  214517. +
  214518. + DPRINTK("VSD cnc0 %d\n", cfg->vsd_cnc0);
  214519. + DPRINTK("VSD cnc1 %d\n", cfg->vsd_cnc1);
  214520. + DPRINTK("VSD cnc2 %d\n", cfg->vsd_cnc2);
  214521. + DPRINTK("VSD cnc3 %d\n", cfg->vsd_cnc3);
  214522. + DPRINTK("latency_present %d\n", latency_present);
  214523. + DPRINTK("I_latency_present %d\n", I_latency_present);
  214524. + DPRINTK("hdmi_video_present %d\n", hdmi_video_present);
  214525. +
  214526. + } else {
  214527. + index += blklen;
  214528. + break;
  214529. + }
  214530. +
  214531. + index += 9;
  214532. +
  214533. + /*latency present */
  214534. + if (latency_present) {
  214535. + cfg->vsd_video_latency = edid[index++];
  214536. + cfg->vsd_audio_latency = edid[index++];
  214537. +
  214538. + if (I_latency_present) {
  214539. + cfg->vsd_I_video_latency = edid[index++];
  214540. + cfg->vsd_I_audio_latency = edid[index++];
  214541. + } else {
  214542. + cfg->vsd_I_video_latency = cfg->vsd_video_latency;
  214543. + cfg->vsd_I_audio_latency = cfg->vsd_audio_latency;
  214544. + }
  214545. +
  214546. + DPRINTK("VSD latency video_latency %d\n", cfg->vsd_video_latency);
  214547. + DPRINTK("VSD latency audio_latency %d\n", cfg->vsd_audio_latency);
  214548. + DPRINTK("VSD latency I_video_latency %d\n", cfg->vsd_I_video_latency);
  214549. + DPRINTK("VSD latency I_audio_latency %d\n", cfg->vsd_I_audio_latency);
  214550. + }
  214551. +
  214552. + if (hdmi_video_present) {
  214553. + hdmi_3d_present = edid[index] >> 7;
  214554. + hdmi_3d_multi_present = (edid[index] & 0x60) >> 5;
  214555. + index++;
  214556. + hdmi_vic_len = (edid[index] & 0xe0) >> 5;
  214557. + hdmi_3d_len = edid[index] & 0x1f;
  214558. + index++;
  214559. +
  214560. + DPRINTK("hdmi_3d_present %d\n", hdmi_3d_present);
  214561. + DPRINTK("hdmi_3d_multi_present %d\n", hdmi_3d_multi_present);
  214562. + DPRINTK("hdmi_vic_len %d\n", hdmi_vic_len);
  214563. + DPRINTK("hdmi_3d_len %d\n", hdmi_3d_len);
  214564. +
  214565. + if (hdmi_vic_len > 0) {
  214566. + for (i = 0; i < hdmi_vic_len; i++) {
  214567. + cfg->hdmi_vic[i] = edid[index++];
  214568. + DPRINTK("HDMI_vic=%d\n", cfg->hdmi_vic[i]);
  214569. + }
  214570. + }
  214571. +
  214572. + if (hdmi_3d_len > 0) {
  214573. + if (hdmi_3d_present) {
  214574. + if (hdmi_3d_multi_present == 0x1) {
  214575. + cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
  214576. + index_inc = 2;
  214577. + } else if (hdmi_3d_multi_present == 0x2) {
  214578. + cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
  214579. + cfg->hdmi_3d_mask_all = (edid[index+2] << 8) | edid[index+3];
  214580. + index_inc = 4;
  214581. + } else
  214582. + index_inc = 0;
  214583. + }
  214584. +
  214585. + DPRINTK("HDMI 3d struct all =0x%x\n", cfg->hdmi_3d_struct_all);
  214586. + DPRINTK("HDMI 3d mask all =0x%x\n", cfg->hdmi_3d_mask_all);
  214587. +
  214588. + /* Read 2D vic 3D_struct */
  214589. + if ((hdmi_3d_len - index_inc) > 0) {
  214590. + DPRINTK("Support 3D video format\n");
  214591. + i = 0;
  214592. + while ((hdmi_3d_len - index_inc) > 0) {
  214593. +
  214594. + cfg->hdmi_3d_format[i].vic_order_2d = edid[index+index_inc] >> 4;
  214595. + cfg->hdmi_3d_format[i].struct_3d = edid[index+index_inc] & 0x0f;
  214596. + index_inc++;
  214597. +
  214598. + if (cfg->hdmi_3d_format[i].struct_3d == 8) {
  214599. + cfg->hdmi_3d_format[i].detail_3d = edid[index+index_inc] >> 4;
  214600. + index_inc++;
  214601. + } else if (cfg->hdmi_3d_format[i].struct_3d > 8) {
  214602. + cfg->hdmi_3d_format[i].detail_3d = 0;
  214603. + index_inc++;
  214604. + }
  214605. +
  214606. + DPRINTK("vic_order_2d=%d, 3d_struct=%d, 3d_detail=0x%x\n",
  214607. + cfg->hdmi_3d_format[i].vic_order_2d,
  214608. + cfg->hdmi_3d_format[i].struct_3d,
  214609. + cfg->hdmi_3d_format[i].detail_3d);
  214610. + i++;
  214611. + }
  214612. + }
  214613. + index += index_inc;
  214614. + }
  214615. + }
  214616. +
  214617. + index = vsd_end;
  214618. +
  214619. + break;
  214620. + }
  214621. + case 0x1: /*Audio data block*/
  214622. + {
  214623. + u8 audio_format, max_ch, byte1, byte2, byte3;
  214624. +
  214625. + i = 0;
  214626. + cfg->max_channels = 0;
  214627. + cfg->sample_rates = 0;
  214628. + cfg->sample_sizes = 0;
  214629. +
  214630. + while (i < blklen) {
  214631. + byte1 = edid[index + 1];
  214632. + byte2 = edid[index + 2];
  214633. + byte3 = edid[index + 3];
  214634. + index += 3;
  214635. + i += 3;
  214636. +
  214637. + audio_format = byte1 >> 3;
  214638. + max_ch = (byte1 & 0x07) + 1;
  214639. +
  214640. + DPRINTK("Audio Format Descriptor : %2d\n", audio_format);
  214641. + DPRINTK("Max Number of Channels : %2d\n", max_ch);
  214642. + DPRINTK("Sample Rates : %02x\n", byte2);
  214643. +
  214644. + /* ALSA can't specify specific compressed
  214645. + * formats, so only care about PCM for now. */
  214646. + if (audio_format == AUDIO_CODING_TYPE_LPCM) {
  214647. + if (max_ch > cfg->max_channels)
  214648. + cfg->max_channels = max_ch;
  214649. +
  214650. + cfg->sample_rates |= byte2;
  214651. + cfg->sample_sizes |= byte3 & 0x7;
  214652. + DPRINTK("Sample Sizes : %02x\n",
  214653. + byte3 & 0x7);
  214654. + }
  214655. + }
  214656. + break;
  214657. + }
  214658. + case 0x4: /*Speaker allocation block*/
  214659. + {
  214660. + i = 0;
  214661. + while (i < blklen) {
  214662. + cfg->speaker_alloc = edid[index + 1];
  214663. + index += 3;
  214664. + i += 3;
  214665. + DPRINTK("Speaker Alloc : %02x\n", cfg->speaker_alloc);
  214666. + }
  214667. + break;
  214668. + }
  214669. + case 0x7: /*User extended block*/
  214670. + default:
  214671. + /* skip */
  214672. + DPRINTK("Not handle block, tagcode = 0x%x\n", tagcode);
  214673. + index += blklen;
  214674. + break;
  214675. + }
  214676. +
  214677. + index++;
  214678. + }
  214679. + }
  214680. +
  214681. + /* long desc */
  214682. + DPRINTK("CEA long desc timmings\n");
  214683. + index = detail_timing_desc_offset;
  214684. + block = edid + index;
  214685. + while (index < (EDID_LENGTH - DETAILED_TIMING_DESCRIPTION_SIZE)) {
  214686. + if (!(block[0] == 0x00 && block[1] == 0x00)) {
  214687. + get_detailed_timing(block, &mode[num]);
  214688. + num++;
  214689. + }
  214690. + block += DETAILED_TIMING_DESCRIPTION_SIZE;
  214691. + index += DETAILED_TIMING_DESCRIPTION_SIZE;
  214692. + }
  214693. +
  214694. + if (!num) {
  214695. + kfree(mode);
  214696. + return 0;
  214697. + }
  214698. +
  214699. + m = kmalloc((num + specs->modedb_len) *
  214700. + sizeof(struct fb_videomode), GFP_KERNEL);
  214701. + if (!m)
  214702. + return 0;
  214703. +
  214704. + if (specs->modedb_len) {
  214705. + memmove(m, specs->modedb,
  214706. + specs->modedb_len * sizeof(struct fb_videomode));
  214707. + kfree(specs->modedb);
  214708. + }
  214709. + memmove(m+specs->modedb_len, mode,
  214710. + num * sizeof(struct fb_videomode));
  214711. + kfree(mode);
  214712. +
  214713. + specs->modedb_len += num;
  214714. + specs->modedb = m;
  214715. +
  214716. + return 0;
  214717. +}
  214718. +EXPORT_SYMBOL(mxc_edid_parse_ext_blk);
  214719. +
  214720. +static int mxc_edid_readblk(struct i2c_adapter *adp,
  214721. + unsigned short addr, unsigned char *edid)
  214722. +{
  214723. + int ret = 0, extblknum = 0;
  214724. + unsigned char regaddr = 0x0;
  214725. + struct i2c_msg msg[2] = {
  214726. + {
  214727. + .addr = addr,
  214728. + .flags = 0,
  214729. + .len = 1,
  214730. + .buf = &regaddr,
  214731. + }, {
  214732. + .addr = addr,
  214733. + .flags = I2C_M_RD,
  214734. + .len = EDID_LENGTH,
  214735. + .buf = edid,
  214736. + },
  214737. + };
  214738. +
  214739. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  214740. + if (ret != ARRAY_SIZE(msg)) {
  214741. + DPRINTK("unable to read EDID block\n");
  214742. + return -EIO;
  214743. + }
  214744. +
  214745. + if (edid[1] == 0x00)
  214746. + return -ENOENT;
  214747. +
  214748. + extblknum = edid[0x7E];
  214749. +
  214750. + if (extblknum) {
  214751. + regaddr = 128;
  214752. + msg[1].buf = edid + EDID_LENGTH;
  214753. +
  214754. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  214755. + if (ret != ARRAY_SIZE(msg)) {
  214756. + DPRINTK("unable to read EDID ext block\n");
  214757. + return -EIO;
  214758. + }
  214759. + }
  214760. +
  214761. + return extblknum;
  214762. +}
  214763. +
  214764. +static int mxc_edid_readsegblk(struct i2c_adapter *adp, unsigned short addr,
  214765. + unsigned char *edid, int seg_num)
  214766. +{
  214767. + int ret = 0;
  214768. + unsigned char segment = 0x1, regaddr = 0;
  214769. + struct i2c_msg msg[3] = {
  214770. + {
  214771. + .addr = 0x30,
  214772. + .flags = 0,
  214773. + .len = 1,
  214774. + .buf = &segment,
  214775. + }, {
  214776. + .addr = addr,
  214777. + .flags = 0,
  214778. + .len = 1,
  214779. + .buf = &regaddr,
  214780. + }, {
  214781. + .addr = addr,
  214782. + .flags = I2C_M_RD,
  214783. + .len = EDID_LENGTH,
  214784. + .buf = edid,
  214785. + },
  214786. + };
  214787. +
  214788. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  214789. + if (ret != ARRAY_SIZE(msg)) {
  214790. + DPRINTK("unable to read EDID block\n");
  214791. + return -EIO;
  214792. + }
  214793. +
  214794. + if (seg_num == 2) {
  214795. + regaddr = 128;
  214796. + msg[2].buf = edid + EDID_LENGTH;
  214797. +
  214798. + ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
  214799. + if (ret != ARRAY_SIZE(msg)) {
  214800. + DPRINTK("unable to read EDID block\n");
  214801. + return -EIO;
  214802. + }
  214803. + }
  214804. +
  214805. + return ret;
  214806. +}
  214807. +
  214808. +int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
  214809. +{
  214810. + int i;
  214811. + struct fb_videomode m;
  214812. +
  214813. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  214814. + fb_var_to_videomode(&m, var);
  214815. + if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i]))
  214816. + break;
  214817. + }
  214818. +
  214819. + if (i == ARRAY_SIZE(mxc_cea_mode))
  214820. + return 0;
  214821. +
  214822. + return i;
  214823. +}
  214824. +EXPORT_SYMBOL(mxc_edid_var_to_vic);
  214825. +
  214826. +int mxc_edid_mode_to_vic(const struct fb_videomode *mode)
  214827. +{
  214828. + int i;
  214829. + bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK);
  214830. +
  214831. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  214832. + if (mxc_edid_fb_mode_is_equal(use_aspect, mode, &mxc_cea_mode[i]))
  214833. + break;
  214834. + }
  214835. +
  214836. + if (i == ARRAY_SIZE(mxc_cea_mode))
  214837. + return 0;
  214838. +
  214839. + return i;
  214840. +}
  214841. +EXPORT_SYMBOL(mxc_edid_mode_to_vic);
  214842. +
  214843. +/* make sure edid has 512 bytes*/
  214844. +int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
  214845. + unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi)
  214846. +{
  214847. + int ret = 0, extblknum;
  214848. + if (!adp || !edid || !cfg || !fbi)
  214849. + return -EINVAL;
  214850. +
  214851. + memset(edid, 0, EDID_LENGTH*4);
  214852. + memset(cfg, 0, sizeof(struct mxc_edid_cfg));
  214853. +
  214854. + extblknum = mxc_edid_readblk(adp, addr, edid);
  214855. + if (extblknum < 0)
  214856. + return extblknum;
  214857. +
  214858. + /* edid first block parsing */
  214859. + memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
  214860. + fb_edid_to_monspecs(edid, &fbi->monspecs);
  214861. +
  214862. + if (extblknum) {
  214863. + int i;
  214864. +
  214865. + /* need read segment block? */
  214866. + if (extblknum > 1) {
  214867. + ret = mxc_edid_readsegblk(adp, addr,
  214868. + edid + EDID_LENGTH*2, extblknum - 1);
  214869. + if (ret < 0)
  214870. + return ret;
  214871. + }
  214872. +
  214873. + for (i = 1; i <= extblknum; i++)
  214874. + /* edid ext block parsing */
  214875. + mxc_edid_parse_ext_blk(edid + i*EDID_LENGTH,
  214876. + cfg, &fbi->monspecs);
  214877. + }
  214878. +
  214879. + return 0;
  214880. +}
  214881. +EXPORT_SYMBOL(mxc_edid_read);
  214882. +
  214883. diff -Nur linux-3.14.17/drivers/video/mxc/mxcfb_hx8369_wvga.c linux-imx6-3.14/drivers/video/mxc/mxcfb_hx8369_wvga.c
  214884. --- linux-3.14.17/drivers/video/mxc/mxcfb_hx8369_wvga.c 1970-01-01 01:00:00.000000000 +0100
  214885. +++ linux-imx6-3.14/drivers/video/mxc/mxcfb_hx8369_wvga.c 2014-09-11 18:06:09.534068054 +0200
  214886. @@ -0,0 +1,449 @@
  214887. +/*
  214888. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  214889. + *
  214890. + * This program is free software; you can redistribute it and/or modify
  214891. + * it under the terms of the GNU General Public License as published by
  214892. + * the Free Software Foundation; either version 2 of the License, or
  214893. + * (at your option) any later version.
  214894. +
  214895. + * This program is distributed in the hope that it will be useful,
  214896. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  214897. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  214898. + * GNU General Public License for more details.
  214899. +
  214900. + * You should have received a copy of the GNU General Public License along
  214901. + * with this program; if not, write to the Free Software Foundation, Inc.,
  214902. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  214903. + */
  214904. +
  214905. +#include <linux/types.h>
  214906. +#include <linux/init.h>
  214907. +#include <linux/delay.h>
  214908. +#include <linux/platform_device.h>
  214909. +#include <linux/err.h>
  214910. +#include <linux/clk.h>
  214911. +#include <linux/console.h>
  214912. +#include <linux/io.h>
  214913. +#include <linux/bitops.h>
  214914. +#include <linux/spinlock.h>
  214915. +#include <linux/mipi_dsi.h>
  214916. +#include <linux/mxcfb.h>
  214917. +#include <linux/backlight.h>
  214918. +#include <video/mipi_display.h>
  214919. +
  214920. +#include "mipi_dsi.h"
  214921. +
  214922. +#define MIPI_DSI_MAX_RET_PACK_SIZE (0x4)
  214923. +
  214924. +#define HX8369BL_MAX_BRIGHT (255)
  214925. +#define HX8369BL_DEF_BRIGHT (255)
  214926. +
  214927. +#define HX8369_MAX_DPHY_CLK (800)
  214928. +#define HX8369_ONE_DATA_LANE (0x1)
  214929. +#define HX8369_TWO_DATA_LANE (0x2)
  214930. +
  214931. +#define HX8369_CMD_SETEXTC (0xB9)
  214932. +#define HX8369_CMD_SETEXTC_LEN (0x4)
  214933. +#define HX8369_CMD_SETEXTC_PARAM_1 (0x6983ff)
  214934. +
  214935. +#define HX8369_CMD_GETHXID (0xF4)
  214936. +#define HX8369_CMD_GETHXID_LEN (0x4)
  214937. +#define HX8369_ID (0x69)
  214938. +#define HX8369_ID_MASK (0xFF)
  214939. +
  214940. +#define HX8369_CMD_SETDISP (0xB2)
  214941. +#define HX8369_CMD_SETDISP_LEN (16)
  214942. +#define HX8369_CMD_SETDISP_1_HALT (0x00)
  214943. +#define HX8369_CMD_SETDISP_2_RES_MODE (0x23)
  214944. +#define HX8369_CMD_SETDISP_3_BP (0x03)
  214945. +#define HX8369_CMD_SETDISP_4_FP (0x03)
  214946. +#define HX8369_CMD_SETDISP_5_SAP (0x70)
  214947. +#define HX8369_CMD_SETDISP_6_GENON (0x00)
  214948. +#define HX8369_CMD_SETDISP_7_GENOFF (0xff)
  214949. +#define HX8369_CMD_SETDISP_8_RTN (0x00)
  214950. +#define HX8369_CMD_SETDISP_9_TEI (0x00)
  214951. +#define HX8369_CMD_SETDISP_10_TEP_UP (0x00)
  214952. +#define HX8369_CMD_SETDISP_11_TEP_LOW (0x00)
  214953. +#define HX8369_CMD_SETDISP_12_BP_PE (0x03)
  214954. +#define HX8369_CMD_SETDISP_13_FP_PE (0x03)
  214955. +#define HX8369_CMD_SETDISP_14_RTN_PE (0x00)
  214956. +#define HX8369_CMD_SETDISP_15_GON (0x01)
  214957. +
  214958. +#define HX8369_CMD_SETCYC (0xB4)
  214959. +#define HX8369_CMD_SETCYC_LEN (6)
  214960. +#define HX8369_CMD_SETCYC_PARAM_1 (0x5f1d00)
  214961. +#define HX8369_CMD_SETCYC_PARAM_2 (0x060e)
  214962. +
  214963. +#define HX8369_CMD_SETGIP (0xD5)
  214964. +#define HX8369_CMD_SETGIP_LEN (27)
  214965. +#define HX8369_CMD_SETGIP_PARAM_1 (0x030400)
  214966. +#define HX8369_CMD_SETGIP_PARAM_2 (0x1c050100)
  214967. +#define HX8369_CMD_SETGIP_PARAM_3 (0x00030170)
  214968. +#define HX8369_CMD_SETGIP_PARAM_4 (0x51064000)
  214969. +#define HX8369_CMD_SETGIP_PARAM_5 (0x41000007)
  214970. +#define HX8369_CMD_SETGIP_PARAM_6 (0x07075006)
  214971. +#define HX8369_CMD_SETGIP_PARAM_7 (0x040f)
  214972. +
  214973. +#define HX8369_CMD_SETPOWER (0xB1)
  214974. +#define HX8369_CMD_SETPOWER_LEN (20)
  214975. +#define HX8369_CMD_SETPOWER_PARAM_1 (0x340001)
  214976. +#define HX8369_CMD_SETPOWER_PARAM_2 (0x0f0f0006)
  214977. +#define HX8369_CMD_SETPOWER_PARAM_3 (0x3f3f322a)
  214978. +#define HX8369_CMD_SETPOWER_PARAM_4 (0xe6013a07)
  214979. +#define HX8369_CMD_SETPOWER_PARAM_5 (0xe6e6e6e6)
  214980. +
  214981. +#define HX8369_CMD_SETVCOM (0xB6)
  214982. +#define HX8369_CMD_SETVCOM_LEN (3)
  214983. +#define HX8369_CMD_SETVCOM_PARAM_1 (0x5656)
  214984. +
  214985. +#define HX8369_CMD_SETPANEL (0xCC)
  214986. +#define HX8369_CMD_SETPANEL_PARAM_1 (0x02)
  214987. +
  214988. +#define HX8369_CMD_SETGAMMA (0xE0)
  214989. +#define HX8369_CMD_SETGAMMA_LEN (35)
  214990. +#define HX8369_CMD_SETGAMMA_PARAM_1 (0x221d00)
  214991. +#define HX8369_CMD_SETGAMMA_PARAM_2 (0x2e3f3d38)
  214992. +#define HX8369_CMD_SETGAMMA_PARAM_3 (0x0f0d064a)
  214993. +#define HX8369_CMD_SETGAMMA_PARAM_4 (0x16131513)
  214994. +#define HX8369_CMD_SETGAMMA_PARAM_5 (0x1d001910)
  214995. +#define HX8369_CMD_SETGAMMA_PARAM_6 (0x3f3d3822)
  214996. +#define HX8369_CMD_SETGAMMA_PARAM_7 (0x0d064a2e)
  214997. +#define HX8369_CMD_SETGAMMA_PARAM_8 (0x1315130f)
  214998. +#define HX8369_CMD_SETGAMMA_PARAM_9 (0x191016)
  214999. +
  215000. +#define HX8369_CMD_SETMIPI (0xBA)
  215001. +#define HX8369_CMD_SETMIPI_LEN (14)
  215002. +#define HX8369_CMD_SETMIPI_PARAM_1 (0xc6a000)
  215003. +#define HX8369_CMD_SETMIPI_PARAM_2 (0x10000a00)
  215004. +#define HX8369_CMD_SETMIPI_ONELANE (0x10 << 24)
  215005. +#define HX8369_CMD_SETMIPI_TWOLANE (0x11 << 24)
  215006. +#define HX8369_CMD_SETMIPI_PARAM_3 (0x00026f30)
  215007. +#define HX8369_CMD_SETMIPI_PARAM_4 (0x4018)
  215008. +
  215009. +#define HX8369_CMD_SETPIXEL_FMT (0x3A)
  215010. +#define HX8369_CMD_SETPIXEL_FMT_24BPP (0x77)
  215011. +#define HX8369_CMD_SETPIXEL_FMT_18BPP (0x66)
  215012. +#define HX8369_CMD_SETPIXEL_FMT_16BPP (0x55)
  215013. +
  215014. +#define HX8369_CMD_SETCLUMN_ADDR (0x2A)
  215015. +#define HX8369_CMD_SETCLUMN_ADDR_LEN (5)
  215016. +#define HX8369_CMD_SETCLUMN_ADDR_PARAM_1 (0xdf0000)
  215017. +#define HX8369_CMD_SETCLUMN_ADDR_PARAM_2 (0x01)
  215018. +
  215019. +#define HX8369_CMD_SETPAGE_ADDR (0x2B)
  215020. +#define HX8369_CMD_SETPAGE_ADDR_LEN (5)
  215021. +#define HX8369_CMD_SETPAGE_ADDR_PARAM_1 (0x1f0000)
  215022. +#define HX8369_CMD_SETPAGE_ADDR_PARAM_2 (0x03)
  215023. +
  215024. +#define HX8369_CMD_WRT_DISP_BRIGHT (0x51)
  215025. +#define HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 (0xFF)
  215026. +
  215027. +#define HX8369_CMD_WRT_CABC_MIN_BRIGHT (0x5E)
  215028. +#define HX8369_CMD_WRT_CABC_MIN_BRIGHT_PARAM_1 (0x20)
  215029. +
  215030. +#define HX8369_CMD_WRT_CABC_CTRL (0x55)
  215031. +#define HX8369_CMD_WRT_CABC_CTRL_PARAM_1 (0x1)
  215032. +
  215033. +#define HX8369_CMD_WRT_CTRL_DISP (0x53)
  215034. +#define HX8369_CMD_WRT_CTRL_DISP_PARAM_1 (0x24)
  215035. +
  215036. +#define CHECK_RETCODE(ret) \
  215037. +do { \
  215038. + if (ret < 0) { \
  215039. + dev_err(&mipi_dsi->pdev->dev, \
  215040. + "%s ERR: ret:%d, line:%d.\n", \
  215041. + __func__, ret, __LINE__); \
  215042. + return ret; \
  215043. + } \
  215044. +} while (0)
  215045. +
  215046. +static int hx8369bl_brightness;
  215047. +static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi);
  215048. +
  215049. +static struct fb_videomode truly_lcd_modedb[] = {
  215050. + {
  215051. + "TRULY-WVGA", 64, 480, 800, 37880,
  215052. + 8, 8,
  215053. + 6, 6,
  215054. + 8, 6,
  215055. + FB_SYNC_OE_LOW_ACT,
  215056. + FB_VMODE_NONINTERLACED,
  215057. + 0,
  215058. + },
  215059. +};
  215060. +
  215061. +static struct mipi_lcd_config lcd_config = {
  215062. + .virtual_ch = 0x0,
  215063. + .data_lane_num = HX8369_TWO_DATA_LANE,
  215064. + .max_phy_clk = HX8369_MAX_DPHY_CLK,
  215065. + .dpi_fmt = MIPI_RGB888,
  215066. +};
  215067. +void mipid_hx8369_get_lcd_videomode(struct fb_videomode **mode, int *size,
  215068. + struct mipi_lcd_config **data)
  215069. +{
  215070. + *mode = &truly_lcd_modedb[0];
  215071. + *size = ARRAY_SIZE(truly_lcd_modedb);
  215072. + *data = &lcd_config;
  215073. +}
  215074. +
  215075. +int mipid_hx8369_lcd_setup(struct mipi_dsi_info *mipi_dsi)
  215076. +{
  215077. + u32 buf[DSI_CMD_BUF_MAXSIZE];
  215078. + int err;
  215079. +
  215080. + dev_dbg(&mipi_dsi->pdev->dev, "MIPI DSI LCD setup.\n");
  215081. + buf[0] = HX8369_CMD_SETEXTC | (HX8369_CMD_SETEXTC_PARAM_1 << 8);
  215082. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  215083. + buf, HX8369_CMD_SETEXTC_LEN);
  215084. + CHECK_RETCODE(err);
  215085. + buf[0] = MIPI_DSI_MAX_RET_PACK_SIZE;
  215086. + err = mipi_dsi_pkt_write(mipi_dsi,
  215087. + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
  215088. + buf, 0);
  215089. + CHECK_RETCODE(err);
  215090. + buf[0] = HX8369_CMD_GETHXID;
  215091. + err = mipi_dsi_pkt_read(mipi_dsi,
  215092. + MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM,
  215093. + buf, HX8369_CMD_GETHXID_LEN);
  215094. + if (!err && ((buf[0] & HX8369_ID_MASK) == HX8369_ID)) {
  215095. + dev_info(&mipi_dsi->pdev->dev,
  215096. + "MIPI DSI LCD ID:0x%x.\n", buf[0]);
  215097. + } else {
  215098. + dev_err(&mipi_dsi->pdev->dev,
  215099. + "mipi_dsi_pkt_read err:%d, data:0x%x.\n",
  215100. + err, buf[0]);
  215101. + dev_info(&mipi_dsi->pdev->dev,
  215102. + "MIPI DSI LCD not detected!\n");
  215103. + return err;
  215104. + }
  215105. +
  215106. + /* set LCD resolution as 480RGBx800, DPI interface,
  215107. + * display operation mode: RGB data bypass GRAM mode.
  215108. + */
  215109. + buf[0] = HX8369_CMD_SETDISP | (HX8369_CMD_SETDISP_1_HALT << 8) |
  215110. + (HX8369_CMD_SETDISP_2_RES_MODE << 16) |
  215111. + (HX8369_CMD_SETDISP_3_BP << 24);
  215112. + buf[1] = HX8369_CMD_SETDISP_4_FP | (HX8369_CMD_SETDISP_5_SAP << 8) |
  215113. + (HX8369_CMD_SETDISP_6_GENON << 16) |
  215114. + (HX8369_CMD_SETDISP_7_GENOFF << 24);
  215115. + buf[2] = HX8369_CMD_SETDISP_8_RTN | (HX8369_CMD_SETDISP_9_TEI << 8) |
  215116. + (HX8369_CMD_SETDISP_10_TEP_UP << 16) |
  215117. + (HX8369_CMD_SETDISP_11_TEP_LOW << 24);
  215118. + buf[3] = HX8369_CMD_SETDISP_12_BP_PE |
  215119. + (HX8369_CMD_SETDISP_13_FP_PE << 8) |
  215120. + (HX8369_CMD_SETDISP_14_RTN_PE << 16) |
  215121. + (HX8369_CMD_SETDISP_15_GON << 24);
  215122. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  215123. + buf, HX8369_CMD_SETDISP_LEN);
  215124. + CHECK_RETCODE(err);
  215125. +
  215126. + /* Set display waveform cycle */
  215127. + buf[0] = HX8369_CMD_SETCYC | (HX8369_CMD_SETCYC_PARAM_1 << 8);
  215128. + buf[1] = HX8369_CMD_SETCYC_PARAM_2;
  215129. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  215130. + buf, HX8369_CMD_SETCYC_LEN);
  215131. + CHECK_RETCODE(err);
  215132. +
  215133. + /* Set GIP timing output control */
  215134. + buf[0] = HX8369_CMD_SETGIP | (HX8369_CMD_SETGIP_PARAM_1 << 8);
  215135. + buf[1] = HX8369_CMD_SETGIP_PARAM_2;
  215136. + buf[2] = HX8369_CMD_SETGIP_PARAM_3;
  215137. + buf[3] = HX8369_CMD_SETGIP_PARAM_4;
  215138. + buf[4] = HX8369_CMD_SETGIP_PARAM_5;
  215139. + buf[5] = HX8369_CMD_SETGIP_PARAM_6;
  215140. + buf[6] = HX8369_CMD_SETGIP_PARAM_7;
  215141. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  215142. + HX8369_CMD_SETGIP_LEN);
  215143. + CHECK_RETCODE(err);
  215144. +
  215145. + /* Set power: standby, DC etc. */
  215146. + buf[0] = HX8369_CMD_SETPOWER | (HX8369_CMD_SETPOWER_PARAM_1 << 8);
  215147. + buf[1] = HX8369_CMD_SETPOWER_PARAM_2;
  215148. + buf[2] = HX8369_CMD_SETPOWER_PARAM_3;
  215149. + buf[3] = HX8369_CMD_SETPOWER_PARAM_4;
  215150. + buf[4] = HX8369_CMD_SETPOWER_PARAM_5;
  215151. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  215152. + HX8369_CMD_SETPOWER_LEN);
  215153. + CHECK_RETCODE(err);
  215154. +
  215155. + /* Set VCOM voltage. */
  215156. + buf[0] = HX8369_CMD_SETVCOM | (HX8369_CMD_SETVCOM_PARAM_1 << 8);
  215157. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  215158. + HX8369_CMD_SETVCOM_LEN);
  215159. + CHECK_RETCODE(err);
  215160. +
  215161. + /* Set Panel: BGR/RGB or Inversion. */
  215162. + buf[0] = HX8369_CMD_SETPANEL | (HX8369_CMD_SETPANEL_PARAM_1 << 8);
  215163. + err = mipi_dsi_pkt_write(mipi_dsi,
  215164. + MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM, buf, 0);
  215165. + CHECK_RETCODE(err);
  215166. +
  215167. + /* Set gamma curve related setting */
  215168. + buf[0] = HX8369_CMD_SETGAMMA | (HX8369_CMD_SETGAMMA_PARAM_1 << 8);
  215169. + buf[1] = HX8369_CMD_SETGAMMA_PARAM_2;
  215170. + buf[2] = HX8369_CMD_SETGAMMA_PARAM_3;
  215171. + buf[3] = HX8369_CMD_SETGAMMA_PARAM_4;
  215172. + buf[4] = HX8369_CMD_SETGAMMA_PARAM_5;
  215173. + buf[5] = HX8369_CMD_SETGAMMA_PARAM_6;
  215174. + buf[7] = HX8369_CMD_SETGAMMA_PARAM_7;
  215175. + buf[7] = HX8369_CMD_SETGAMMA_PARAM_8;
  215176. + buf[8] = HX8369_CMD_SETGAMMA_PARAM_9;
  215177. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  215178. + HX8369_CMD_SETGAMMA_LEN);
  215179. + CHECK_RETCODE(err);
  215180. +
  215181. + /* Set MIPI: DPHYCMD & DSICMD, data lane number */
  215182. + buf[0] = HX8369_CMD_SETMIPI | (HX8369_CMD_SETMIPI_PARAM_1 << 8);
  215183. + buf[1] = HX8369_CMD_SETMIPI_PARAM_2;
  215184. + buf[2] = HX8369_CMD_SETMIPI_PARAM_3;
  215185. + if (lcd_config.data_lane_num == HX8369_ONE_DATA_LANE)
  215186. + buf[2] |= HX8369_CMD_SETMIPI_ONELANE;
  215187. + else
  215188. + buf[2] |= HX8369_CMD_SETMIPI_TWOLANE;
  215189. + buf[3] = HX8369_CMD_SETMIPI_PARAM_4;
  215190. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE, buf,
  215191. + HX8369_CMD_SETMIPI_LEN);
  215192. + CHECK_RETCODE(err);
  215193. +
  215194. + /* Set pixel format:24bpp */
  215195. + buf[0] = HX8369_CMD_SETPIXEL_FMT;
  215196. + switch (lcd_config.dpi_fmt) {
  215197. + case MIPI_RGB565_PACKED:
  215198. + case MIPI_RGB565_LOOSELY:
  215199. + case MIPI_RGB565_CONFIG3:
  215200. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_16BPP << 8);
  215201. + break;
  215202. +
  215203. + case MIPI_RGB666_LOOSELY:
  215204. + case MIPI_RGB666_PACKED:
  215205. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_18BPP << 8);
  215206. + break;
  215207. +
  215208. + case MIPI_RGB888:
  215209. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
  215210. + break;
  215211. +
  215212. + default:
  215213. + buf[0] |= (HX8369_CMD_SETPIXEL_FMT_24BPP << 8);
  215214. + break;
  215215. + }
  215216. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  215217. + buf, 0);
  215218. + CHECK_RETCODE(err);
  215219. +
  215220. + /* Set column address: 0~479 */
  215221. + buf[0] = HX8369_CMD_SETCLUMN_ADDR |
  215222. + (HX8369_CMD_SETCLUMN_ADDR_PARAM_1 << 8);
  215223. + buf[1] = HX8369_CMD_SETCLUMN_ADDR_PARAM_2;
  215224. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  215225. + buf, HX8369_CMD_SETCLUMN_ADDR_LEN);
  215226. + CHECK_RETCODE(err);
  215227. +
  215228. + /* Set page address: 0~799 */
  215229. + buf[0] = HX8369_CMD_SETPAGE_ADDR |
  215230. + (HX8369_CMD_SETPAGE_ADDR_PARAM_1 << 8);
  215231. + buf[1] = HX8369_CMD_SETPAGE_ADDR_PARAM_2;
  215232. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_LONG_WRITE,
  215233. + buf, HX8369_CMD_SETPAGE_ADDR_LEN);
  215234. + CHECK_RETCODE(err);
  215235. +
  215236. + /* Set display brightness related */
  215237. + buf[0] = HX8369_CMD_WRT_DISP_BRIGHT |
  215238. + (HX8369_CMD_WRT_DISP_BRIGHT_PARAM_1 << 8);
  215239. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  215240. + buf, 0);
  215241. + CHECK_RETCODE(err);
  215242. +
  215243. + buf[0] = HX8369_CMD_WRT_CABC_CTRL |
  215244. + (HX8369_CMD_WRT_CABC_CTRL_PARAM_1 << 8);
  215245. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  215246. + buf, 0);
  215247. + CHECK_RETCODE(err);
  215248. +
  215249. + buf[0] = HX8369_CMD_WRT_CTRL_DISP |
  215250. + (HX8369_CMD_WRT_CTRL_DISP_PARAM_1 << 8);
  215251. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  215252. + buf, 0);
  215253. + CHECK_RETCODE(err);
  215254. +
  215255. + /* exit sleep mode and set display on */
  215256. + buf[0] = MIPI_DCS_EXIT_SLEEP_MODE;
  215257. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
  215258. + buf, 0);
  215259. + CHECK_RETCODE(err);
  215260. + /* To allow time for the supply voltages
  215261. + * and clock circuits to stabilize.
  215262. + */
  215263. + msleep(5);
  215264. + buf[0] = MIPI_DCS_SET_DISPLAY_ON;
  215265. + err = mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
  215266. + buf, 0);
  215267. + CHECK_RETCODE(err);
  215268. +
  215269. + err = mipid_init_backlight(mipi_dsi);
  215270. + return err;
  215271. +}
  215272. +
  215273. +static int mipid_bl_update_status(struct backlight_device *bl)
  215274. +{
  215275. + u32 buf;
  215276. + int brightness = bl->props.brightness;
  215277. + struct mipi_dsi_info *mipi_dsi = bl_get_data(bl);
  215278. +
  215279. + if (bl->props.power != FB_BLANK_UNBLANK ||
  215280. + bl->props.fb_blank != FB_BLANK_UNBLANK)
  215281. + brightness = 0;
  215282. +
  215283. + buf = HX8369_CMD_WRT_DISP_BRIGHT |
  215284. + ((brightness & HX8369BL_MAX_BRIGHT) << 8);
  215285. + mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM,
  215286. + &buf, 0);
  215287. +
  215288. + hx8369bl_brightness = brightness & HX8369BL_MAX_BRIGHT;
  215289. +
  215290. + dev_dbg(&bl->dev, "mipid backlight bringtness:%d.\n", brightness);
  215291. + return 0;
  215292. +}
  215293. +
  215294. +static int mipid_bl_get_brightness(struct backlight_device *bl)
  215295. +{
  215296. + return hx8369bl_brightness;
  215297. +}
  215298. +
  215299. +static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
  215300. +{
  215301. + return 0;
  215302. +}
  215303. +
  215304. +static const struct backlight_ops mipid_lcd_bl_ops = {
  215305. + .update_status = mipid_bl_update_status,
  215306. + .get_brightness = mipid_bl_get_brightness,
  215307. + .check_fb = mipi_bl_check_fb,
  215308. +};
  215309. +
  215310. +static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi)
  215311. +{
  215312. + struct backlight_properties props;
  215313. + struct backlight_device *bl;
  215314. +
  215315. + if (mipi_dsi->bl) {
  215316. + pr_debug("mipid backlight already init!\n");
  215317. + return 0;
  215318. + }
  215319. + memset(&props, 0, sizeof(struct backlight_properties));
  215320. + props.max_brightness = HX8369BL_MAX_BRIGHT;
  215321. + props.type = BACKLIGHT_RAW;
  215322. + bl = backlight_device_register("mipid-bl", &mipi_dsi->pdev->dev,
  215323. + mipi_dsi, &mipid_lcd_bl_ops, &props);
  215324. + if (IS_ERR(bl)) {
  215325. + pr_err("error %ld on backlight register\n", PTR_ERR(bl));
  215326. + return PTR_ERR(bl);
  215327. + }
  215328. + mipi_dsi->bl = bl;
  215329. + bl->props.power = FB_BLANK_UNBLANK;
  215330. + bl->props.fb_blank = FB_BLANK_UNBLANK;
  215331. + bl->props.brightness = HX8369BL_DEF_BRIGHT;
  215332. +
  215333. + mipid_bl_update_status(bl);
  215334. + return 0;
  215335. +}
  215336. diff -Nur linux-3.14.17/drivers/video/mxc/mxc_hdmi.c linux-imx6-3.14/drivers/video/mxc/mxc_hdmi.c
  215337. --- linux-3.14.17/drivers/video/mxc/mxc_hdmi.c 1970-01-01 01:00:00.000000000 +0100
  215338. +++ linux-imx6-3.14/drivers/video/mxc/mxc_hdmi.c 2014-09-11 18:06:09.534068054 +0200
  215339. @@ -0,0 +1,3022 @@
  215340. +/*
  215341. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  215342. + *
  215343. + * This program is free software; you can redistribute it and/or modify
  215344. + * it under the terms of the GNU General Public License as published by
  215345. + * the Free Software Foundation; either version 2 of the License, or
  215346. + * (at your option) any later version.
  215347. + *
  215348. + * This program is distributed in the hope that it will be useful,
  215349. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  215350. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  215351. + * GNU General Public License for more details.
  215352. + *
  215353. + * You should have received a copy of the GNU General Public License
  215354. + * along with this program; if not, write to the Free Software
  215355. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  215356. + *
  215357. + */
  215358. +/*
  215359. + * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
  215360. + * for SLISHDMI13T and SLIPHDMIT IP cores
  215361. + *
  215362. + * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  215363. + *
  215364. + * This program is free software; you can redistribute it and/or modify
  215365. + * it under the terms of the GNU General Public License version 2 as
  215366. + * published by the Free Software Foundation.
  215367. + */
  215368. +
  215369. +#include <linux/module.h>
  215370. +#include <linux/kernel.h>
  215371. +#include <linux/device.h>
  215372. +#include <linux/platform_device.h>
  215373. +#include <linux/input.h>
  215374. +#include <linux/interrupt.h>
  215375. +#include <linux/irq.h>
  215376. +#include <linux/io.h>
  215377. +#include <linux/fb.h>
  215378. +#include <linux/init.h>
  215379. +#include <linux/list.h>
  215380. +#include <linux/delay.h>
  215381. +#include <linux/dma-mapping.h>
  215382. +#include <linux/err.h>
  215383. +#include <linux/clk.h>
  215384. +#include <linux/uaccess.h>
  215385. +#include <linux/cpufreq.h>
  215386. +#include <linux/firmware.h>
  215387. +#include <linux/kthread.h>
  215388. +#include <linux/regulator/driver.h>
  215389. +#include <linux/fsl_devices.h>
  215390. +#include <linux/ipu.h>
  215391. +#include <linux/regmap.h>
  215392. +#include <linux/pinctrl/consumer.h>
  215393. +#include <linux/of_device.h>
  215394. +
  215395. +#include <linux/console.h>
  215396. +#include <linux/types.h>
  215397. +
  215398. +#include "../edid.h"
  215399. +#include <video/mxc_edid.h>
  215400. +#include <video/mxc_hdmi.h>
  215401. +#include "mxc_dispdrv.h"
  215402. +
  215403. +#include <linux/mfd/mxc-hdmi-core.h>
  215404. +
  215405. +#define DISPDRV_HDMI "hdmi"
  215406. +#define HDMI_EDID_LEN 512
  215407. +
  215408. +/* status codes for reading edid */
  215409. +#define HDMI_EDID_SUCCESS 0
  215410. +#define HDMI_EDID_FAIL -1
  215411. +#define HDMI_EDID_SAME -2
  215412. +#define HDMI_EDID_NO_MODES -3
  215413. +
  215414. +#define NUM_CEA_VIDEO_MODES 64
  215415. +#define DEFAULT_VIDEO_MODE 16 /* 1080P */
  215416. +
  215417. +#define RGB 0
  215418. +#define YCBCR444 1
  215419. +#define YCBCR422_16BITS 2
  215420. +#define YCBCR422_8BITS 3
  215421. +#define XVYCC444 4
  215422. +
  215423. +/*
  215424. + * We follow a flowchart which is in the "Synopsys DesignWare Courses
  215425. + * HDMI Transmitter Controller User Guide, 1.30a", section 3.1
  215426. + * (dwc_hdmi_tx_user.pdf)
  215427. + *
  215428. + * Below are notes that say "HDMI Initialization Step X"
  215429. + * These correspond to the flowchart.
  215430. + */
  215431. +
  215432. +/*
  215433. + * We are required to configure VGA mode before reading edid
  215434. + * in HDMI Initialization Step B
  215435. + */
  215436. +static const struct fb_videomode vga_mode = {
  215437. + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
  215438. + NULL, 60, 640, 480, 39721, 48, 16, 33, 10, 96, 2, 0,
  215439. + FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, FB_MODE_IS_VESA,
  215440. +};
  215441. +
  215442. +enum hdmi_datamap {
  215443. + RGB444_8B = 0x01,
  215444. + RGB444_10B = 0x03,
  215445. + RGB444_12B = 0x05,
  215446. + RGB444_16B = 0x07,
  215447. + YCbCr444_8B = 0x09,
  215448. + YCbCr444_10B = 0x0B,
  215449. + YCbCr444_12B = 0x0D,
  215450. + YCbCr444_16B = 0x0F,
  215451. + YCbCr422_8B = 0x16,
  215452. + YCbCr422_10B = 0x14,
  215453. + YCbCr422_12B = 0x12,
  215454. +};
  215455. +
  215456. +enum hdmi_colorimetry {
  215457. + eITU601,
  215458. + eITU709,
  215459. +};
  215460. +
  215461. +struct hdmi_vmode {
  215462. + bool mDVI;
  215463. + bool mHSyncPolarity;
  215464. + bool mVSyncPolarity;
  215465. + bool mInterlaced;
  215466. + bool mDataEnablePolarity;
  215467. +
  215468. + unsigned int mPixelClock;
  215469. + unsigned int mPixelRepetitionInput;
  215470. + unsigned int mPixelRepetitionOutput;
  215471. +};
  215472. +
  215473. +struct hdmi_data_info {
  215474. + unsigned int enc_in_format;
  215475. + unsigned int enc_out_format;
  215476. + unsigned int enc_color_depth;
  215477. + unsigned int colorimetry;
  215478. + unsigned int pix_repet_factor;
  215479. + unsigned int hdcp_enable;
  215480. + unsigned int rgb_out_enable;
  215481. + unsigned int rgb_quant_range;
  215482. + struct hdmi_vmode video_mode;
  215483. +};
  215484. +
  215485. +struct hdmi_phy_reg_config {
  215486. + /* HDMI PHY register config for pass HCT */
  215487. + u16 reg_vlev;
  215488. + u16 reg_cksymtx;
  215489. +};
  215490. +
  215491. +struct mxc_hdmi {
  215492. + struct platform_device *pdev;
  215493. + struct platform_device *core_pdev;
  215494. + struct mxc_dispdrv_handle *disp_mxc_hdmi;
  215495. + struct fb_info *fbi;
  215496. + struct clk *hdmi_isfr_clk;
  215497. + struct clk *hdmi_iahb_clk;
  215498. + struct timer_list jitter_timer;
  215499. + struct work_struct hotplug_work;
  215500. + struct delayed_work hdcp_hdp_work;
  215501. +
  215502. + struct notifier_block nb;
  215503. +
  215504. + struct hdmi_data_info hdmi_data;
  215505. + int vic;
  215506. + int edid_status;
  215507. + struct mxc_edid_cfg edid_cfg;
  215508. + u8 edid[HDMI_EDID_LEN];
  215509. + bool fb_reg;
  215510. + bool cable_plugin;
  215511. + u8 blank;
  215512. + bool dft_mode_set;
  215513. + char *dft_mode_str;
  215514. + int default_bpp;
  215515. + u8 latest_intr_stat;
  215516. + u8 plug_event;
  215517. + u8 plug_mask;
  215518. + bool irq_enabled;
  215519. + spinlock_t irq_lock;
  215520. + bool phy_enabled;
  215521. + struct fb_videomode default_mode;
  215522. + struct fb_videomode previous_non_vga_mode;
  215523. + bool requesting_vga_for_initialization;
  215524. +
  215525. + int *gpr_base;
  215526. + int *gpr_hdmi_base;
  215527. + int *gpr_sdma_base;
  215528. + int cpu_type;
  215529. + int cpu_version;
  215530. + struct hdmi_phy_reg_config phy_config;
  215531. +
  215532. + struct pinctrl *pinctrl;
  215533. +};
  215534. +
  215535. +static int hdmi_major;
  215536. +static struct class *hdmi_class;
  215537. +
  215538. +struct i2c_client *hdmi_i2c;
  215539. +struct mxc_hdmi *g_hdmi;
  215540. +
  215541. +static bool hdmi_inited;
  215542. +static bool hdcp_init;
  215543. +
  215544. +extern const struct fb_videomode mxc_cea_mode[64];
  215545. +extern void mxc_hdmi_cec_handle(u16 cec_stat);
  215546. +
  215547. +static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event);
  215548. +static void hdmi_enable_overflow_interrupts(void);
  215549. +static void hdmi_disable_overflow_interrupts(void);
  215550. +
  215551. +static char *rgb_quant_range = "default";
  215552. +module_param(rgb_quant_range, charp, S_IRUGO);
  215553. +MODULE_PARM_DESC(rgb_quant_range, "RGB Quant Range (default, limited, full)");
  215554. +
  215555. +static struct platform_device_id imx_hdmi_devtype[] = {
  215556. + {
  215557. + .name = "hdmi-imx6DL",
  215558. + .driver_data = IMX6DL_HDMI,
  215559. + }, {
  215560. + .name = "hdmi-imx6Q",
  215561. + .driver_data = IMX6Q_HDMI,
  215562. + }, {
  215563. + /* sentinel */
  215564. + }
  215565. +};
  215566. +MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
  215567. +
  215568. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  215569. + { .compatible = "fsl,imx6dl-hdmi-video", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
  215570. + { .compatible = "fsl,imx6q-hdmi-video", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
  215571. + { /* sentinel */ }
  215572. +};
  215573. +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
  215574. +
  215575. +static inline int cpu_is_imx6dl(struct mxc_hdmi *hdmi)
  215576. +{
  215577. + return hdmi->cpu_type == IMX6DL_HDMI;
  215578. +}
  215579. +#ifdef DEBUG
  215580. +static void dump_fb_videomode(struct fb_videomode *m)
  215581. +{
  215582. + pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
  215583. + m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
  215584. + m->right_margin, m->upper_margin, m->lower_margin,
  215585. + m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
  215586. +}
  215587. +#else
  215588. +static void dump_fb_videomode(struct fb_videomode *m)
  215589. +{}
  215590. +#endif
  215591. +
  215592. +static ssize_t mxc_hdmi_show_name(struct device *dev,
  215593. + struct device_attribute *attr, char *buf)
  215594. +{
  215595. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215596. +
  215597. + strcpy(buf, hdmi->fbi->fix.id);
  215598. + sprintf(buf+strlen(buf), "\n");
  215599. +
  215600. + return strlen(buf);
  215601. +}
  215602. +
  215603. +static DEVICE_ATTR(fb_name, S_IRUGO, mxc_hdmi_show_name, NULL);
  215604. +
  215605. +static ssize_t mxc_hdmi_show_state(struct device *dev,
  215606. + struct device_attribute *attr, char *buf)
  215607. +{
  215608. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215609. +
  215610. + if (hdmi->cable_plugin == false)
  215611. + strcpy(buf, "plugout\n");
  215612. + else
  215613. + strcpy(buf, "plugin\n");
  215614. +
  215615. + return strlen(buf);
  215616. +}
  215617. +
  215618. +static DEVICE_ATTR(cable_state, S_IRUGO, mxc_hdmi_show_state, NULL);
  215619. +
  215620. +static ssize_t mxc_hdmi_show_edid(struct device *dev,
  215621. + struct device_attribute *attr, char *buf)
  215622. +{
  215623. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215624. + int i, j, len = 0;
  215625. +
  215626. + for (j = 0; j < HDMI_EDID_LEN/16; j++) {
  215627. + for (i = 0; i < 16; i++)
  215628. + len += sprintf(buf+len, "0x%02X ",
  215629. + hdmi->edid[j*16 + i]);
  215630. + len += sprintf(buf+len, "\n");
  215631. + }
  215632. +
  215633. + return len;
  215634. +}
  215635. +
  215636. +static DEVICE_ATTR(edid, S_IRUGO, mxc_hdmi_show_edid, NULL);
  215637. +
  215638. +static ssize_t mxc_hdmi_show_rgb_out_enable(struct device *dev,
  215639. + struct device_attribute *attr, char *buf)
  215640. +{
  215641. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215642. +
  215643. + if (hdmi->hdmi_data.rgb_out_enable == true)
  215644. + strcpy(buf, "RGB out\n");
  215645. + else
  215646. + strcpy(buf, "YCbCr out\n");
  215647. +
  215648. + return strlen(buf);
  215649. +}
  215650. +
  215651. +static ssize_t mxc_hdmi_store_rgb_out_enable(struct device *dev,
  215652. + struct device_attribute *attr, const char *buf, size_t count)
  215653. +{
  215654. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215655. + unsigned long value;
  215656. + int ret;
  215657. +
  215658. + ret = strict_strtoul(buf, 10, &value);
  215659. + if (ret)
  215660. + return ret;
  215661. +
  215662. + hdmi->hdmi_data.rgb_out_enable = value;
  215663. +
  215664. + /* Reconfig HDMI for output color space change */
  215665. + mxc_hdmi_setup(hdmi, 0);
  215666. +
  215667. + return count;
  215668. +}
  215669. +
  215670. +static DEVICE_ATTR(rgb_out_enable, S_IRUGO | S_IWUSR,
  215671. + mxc_hdmi_show_rgb_out_enable,
  215672. + mxc_hdmi_store_rgb_out_enable);
  215673. +
  215674. +static ssize_t mxc_hdmi_show_rgb_quant_range(struct device *dev,
  215675. + struct device_attribute *attr, char *buf)
  215676. +{
  215677. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215678. +
  215679. + switch (hdmi->hdmi_data.rgb_quant_range) {
  215680. + case HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE:
  215681. + strcpy(buf, "limited\n");
  215682. + break;
  215683. + case HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE:
  215684. + strcpy(buf, "full\n");
  215685. + break;
  215686. + case HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT:
  215687. + default:
  215688. + strcpy(buf, "default\n");
  215689. + break;
  215690. + };
  215691. +
  215692. + return strlen(buf);
  215693. +}
  215694. +
  215695. +static ssize_t mxc_hdmi_store_rgb_quant_range(struct device *dev,
  215696. + struct device_attribute *attr, const char *buf, size_t count)
  215697. +{
  215698. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215699. + int ret = count;
  215700. +
  215701. + if (sysfs_streq("limited", buf)) {
  215702. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE;
  215703. + } else if (sysfs_streq("full", buf)) {
  215704. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE;
  215705. + } else if (sysfs_streq("default", buf)) {
  215706. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT;
  215707. + } else {
  215708. + ret = -EINVAL;
  215709. + goto out;
  215710. + }
  215711. +
  215712. + /* Reconfig HDMI for output RGB Quant Range change if using RGB out */
  215713. + if(hdmi->hdmi_data.rgb_out_enable)
  215714. + mxc_hdmi_setup(hdmi, 0);
  215715. +out:
  215716. + return ret;
  215717. +}
  215718. +
  215719. +static DEVICE_ATTR(rgb_quant_range, S_IRUGO | S_IWUSR,
  215720. + mxc_hdmi_show_rgb_quant_range,
  215721. + mxc_hdmi_store_rgb_quant_range);
  215722. +
  215723. +static ssize_t mxc_hdmi_show_hdcp_enable(struct device *dev,
  215724. + struct device_attribute *attr, char *buf)
  215725. +{
  215726. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215727. +
  215728. + if (hdmi->hdmi_data.hdcp_enable == false)
  215729. + strcpy(buf, "hdcp disable\n");
  215730. + else
  215731. + strcpy(buf, "hdcp enable\n");
  215732. +
  215733. + return strlen(buf);
  215734. +
  215735. +}
  215736. +
  215737. +static ssize_t mxc_hdmi_store_hdcp_enable(struct device *dev,
  215738. + struct device_attribute *attr, const char *buf, size_t count)
  215739. +{
  215740. + struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
  215741. + char event_string[32];
  215742. + char *envp[] = { event_string, NULL };
  215743. + unsigned long value;
  215744. + int ret;
  215745. +
  215746. + ret = strict_strtoul(buf, 10, &value);
  215747. + if (ret)
  215748. + return ret;
  215749. +
  215750. + hdmi->hdmi_data.hdcp_enable = value;
  215751. +
  215752. + /* Reconfig HDMI for HDCP */
  215753. + mxc_hdmi_setup(hdmi, 0);
  215754. +
  215755. + if (hdmi->hdmi_data.hdcp_enable == false) {
  215756. + sprintf(event_string, "EVENT=hdcpdisable");
  215757. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  215758. + } else {
  215759. + sprintf(event_string, "EVENT=hdcpenable");
  215760. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  215761. + }
  215762. +
  215763. + return count;
  215764. +
  215765. +}
  215766. +
  215767. +static DEVICE_ATTR(hdcp_enable, S_IRUGO | S_IWUSR,
  215768. + mxc_hdmi_show_hdcp_enable, mxc_hdmi_store_hdcp_enable);
  215769. +
  215770. +/*!
  215771. + * this submodule is responsible for the video data synchronization.
  215772. + * for example, for RGB 4:4:4 input, the data map is defined as
  215773. + * pin{47~40} <==> R[7:0]
  215774. + * pin{31~24} <==> G[7:0]
  215775. + * pin{15~8} <==> B[7:0]
  215776. + */
  215777. +static void hdmi_video_sample(struct mxc_hdmi *hdmi)
  215778. +{
  215779. + int color_format = 0;
  215780. + u8 val;
  215781. +
  215782. + if (hdmi->hdmi_data.enc_in_format == RGB) {
  215783. + if (hdmi->hdmi_data.enc_color_depth == 8)
  215784. + color_format = 0x01;
  215785. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  215786. + color_format = 0x03;
  215787. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  215788. + color_format = 0x05;
  215789. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  215790. + color_format = 0x07;
  215791. + else
  215792. + return;
  215793. + } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
  215794. + if (hdmi->hdmi_data.enc_color_depth == 8)
  215795. + color_format = 0x09;
  215796. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  215797. + color_format = 0x0B;
  215798. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  215799. + color_format = 0x0D;
  215800. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  215801. + color_format = 0x0F;
  215802. + else
  215803. + return;
  215804. + } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
  215805. + if (hdmi->hdmi_data.enc_color_depth == 8)
  215806. + color_format = 0x16;
  215807. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  215808. + color_format = 0x14;
  215809. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  215810. + color_format = 0x12;
  215811. + else
  215812. + return;
  215813. + }
  215814. +
  215815. + val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
  215816. + ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
  215817. + HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
  215818. + hdmi_writeb(val, HDMI_TX_INVID0);
  215819. +
  215820. + /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
  215821. + val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
  215822. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
  215823. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
  215824. + hdmi_writeb(val, HDMI_TX_INSTUFFING);
  215825. + hdmi_writeb(0x0, HDMI_TX_GYDATA0);
  215826. + hdmi_writeb(0x0, HDMI_TX_GYDATA1);
  215827. + hdmi_writeb(0x0, HDMI_TX_RCRDATA0);
  215828. + hdmi_writeb(0x0, HDMI_TX_RCRDATA1);
  215829. + hdmi_writeb(0x0, HDMI_TX_BCBDATA0);
  215830. + hdmi_writeb(0x0, HDMI_TX_BCBDATA1);
  215831. +}
  215832. +
  215833. +static int isColorSpaceConversion(struct mxc_hdmi *hdmi)
  215834. +{
  215835. + return (hdmi->hdmi_data.enc_in_format !=
  215836. + hdmi->hdmi_data.enc_out_format);
  215837. +}
  215838. +
  215839. +static int isColorSpaceDecimation(struct mxc_hdmi *hdmi)
  215840. +{
  215841. + return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) &&
  215842. + (hdmi->hdmi_data.enc_in_format == RGB ||
  215843. + hdmi->hdmi_data.enc_in_format == YCBCR444));
  215844. +}
  215845. +
  215846. +static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi)
  215847. +{
  215848. + return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) &&
  215849. + (hdmi->hdmi_data.enc_out_format == RGB
  215850. + || hdmi->hdmi_data.enc_out_format == YCBCR444));
  215851. +}
  215852. +
  215853. +/*!
  215854. + * update the color space conversion coefficients.
  215855. + */
  215856. +static void update_csc_coeffs(struct mxc_hdmi *hdmi)
  215857. +{
  215858. + unsigned short csc_coeff[3][4];
  215859. + unsigned int csc_scale = 1;
  215860. + u8 val;
  215861. + bool coeff_selected = false;
  215862. +
  215863. + if (isColorSpaceConversion(hdmi)) { /* csc needed */
  215864. + if (hdmi->hdmi_data.enc_out_format == RGB) {
  215865. + if (hdmi->hdmi_data.colorimetry == eITU601) {
  215866. + csc_coeff[0][0] = 0x2000;
  215867. + csc_coeff[0][1] = 0x6926;
  215868. + csc_coeff[0][2] = 0x74fd;
  215869. + csc_coeff[0][3] = 0x010e;
  215870. +
  215871. + csc_coeff[1][0] = 0x2000;
  215872. + csc_coeff[1][1] = 0x2cdd;
  215873. + csc_coeff[1][2] = 0x0000;
  215874. + csc_coeff[1][3] = 0x7e9a;
  215875. +
  215876. + csc_coeff[2][0] = 0x2000;
  215877. + csc_coeff[2][1] = 0x0000;
  215878. + csc_coeff[2][2] = 0x38b4;
  215879. + csc_coeff[2][3] = 0x7e3b;
  215880. +
  215881. + csc_scale = 1;
  215882. + coeff_selected = true;
  215883. + } else if (hdmi->hdmi_data.colorimetry == eITU709) {
  215884. + csc_coeff[0][0] = 0x2000;
  215885. + csc_coeff[0][1] = 0x7106;
  215886. + csc_coeff[0][2] = 0x7a02;
  215887. + csc_coeff[0][3] = 0x00a7;
  215888. +
  215889. + csc_coeff[1][0] = 0x2000;
  215890. + csc_coeff[1][1] = 0x3264;
  215891. + csc_coeff[1][2] = 0x0000;
  215892. + csc_coeff[1][3] = 0x7e6d;
  215893. +
  215894. + csc_coeff[2][0] = 0x2000;
  215895. + csc_coeff[2][1] = 0x0000;
  215896. + csc_coeff[2][2] = 0x3b61;
  215897. + csc_coeff[2][3] = 0x7e25;
  215898. +
  215899. + csc_scale = 1;
  215900. + coeff_selected = true;
  215901. + }
  215902. + } else if (hdmi->hdmi_data.enc_in_format == RGB) {
  215903. + if (hdmi->hdmi_data.colorimetry == eITU601) {
  215904. + csc_coeff[0][0] = 0x2591;
  215905. + csc_coeff[0][1] = 0x1322;
  215906. + csc_coeff[0][2] = 0x074b;
  215907. + csc_coeff[0][3] = 0x0000;
  215908. +
  215909. + csc_coeff[1][0] = 0x6535;
  215910. + csc_coeff[1][1] = 0x2000;
  215911. + csc_coeff[1][2] = 0x7acc;
  215912. + csc_coeff[1][3] = 0x0200;
  215913. +
  215914. + csc_coeff[2][0] = 0x6acd;
  215915. + csc_coeff[2][1] = 0x7534;
  215916. + csc_coeff[2][2] = 0x2000;
  215917. + csc_coeff[2][3] = 0x0200;
  215918. +
  215919. + csc_scale = 0;
  215920. + coeff_selected = true;
  215921. + } else if (hdmi->hdmi_data.colorimetry == eITU709) {
  215922. + csc_coeff[0][0] = 0x2dc5;
  215923. + csc_coeff[0][1] = 0x0d9b;
  215924. + csc_coeff[0][2] = 0x049e;
  215925. + csc_coeff[0][3] = 0x0000;
  215926. +
  215927. + csc_coeff[1][0] = 0x62f0;
  215928. + csc_coeff[1][1] = 0x2000;
  215929. + csc_coeff[1][2] = 0x7d11;
  215930. + csc_coeff[1][3] = 0x0200;
  215931. +
  215932. + csc_coeff[2][0] = 0x6756;
  215933. + csc_coeff[2][1] = 0x78ab;
  215934. + csc_coeff[2][2] = 0x2000;
  215935. + csc_coeff[2][3] = 0x0200;
  215936. +
  215937. + csc_scale = 0;
  215938. + coeff_selected = true;
  215939. + }
  215940. + }
  215941. + }
  215942. +
  215943. + if (!coeff_selected) {
  215944. + csc_coeff[0][0] = 0x2000;
  215945. + csc_coeff[0][1] = 0x0000;
  215946. + csc_coeff[0][2] = 0x0000;
  215947. + csc_coeff[0][3] = 0x0000;
  215948. +
  215949. + csc_coeff[1][0] = 0x0000;
  215950. + csc_coeff[1][1] = 0x2000;
  215951. + csc_coeff[1][2] = 0x0000;
  215952. + csc_coeff[1][3] = 0x0000;
  215953. +
  215954. + csc_coeff[2][0] = 0x0000;
  215955. + csc_coeff[2][1] = 0x0000;
  215956. + csc_coeff[2][2] = 0x2000;
  215957. + csc_coeff[2][3] = 0x0000;
  215958. +
  215959. + csc_scale = 1;
  215960. + }
  215961. +
  215962. + /* Update CSC parameters in HDMI CSC registers */
  215963. + hdmi_writeb((unsigned char)(csc_coeff[0][0] & 0xFF),
  215964. + HDMI_CSC_COEF_A1_LSB);
  215965. + hdmi_writeb((unsigned char)(csc_coeff[0][0] >> 8),
  215966. + HDMI_CSC_COEF_A1_MSB);
  215967. + hdmi_writeb((unsigned char)(csc_coeff[0][1] & 0xFF),
  215968. + HDMI_CSC_COEF_A2_LSB);
  215969. + hdmi_writeb((unsigned char)(csc_coeff[0][1] >> 8),
  215970. + HDMI_CSC_COEF_A2_MSB);
  215971. + hdmi_writeb((unsigned char)(csc_coeff[0][2] & 0xFF),
  215972. + HDMI_CSC_COEF_A3_LSB);
  215973. + hdmi_writeb((unsigned char)(csc_coeff[0][2] >> 8),
  215974. + HDMI_CSC_COEF_A3_MSB);
  215975. + hdmi_writeb((unsigned char)(csc_coeff[0][3] & 0xFF),
  215976. + HDMI_CSC_COEF_A4_LSB);
  215977. + hdmi_writeb((unsigned char)(csc_coeff[0][3] >> 8),
  215978. + HDMI_CSC_COEF_A4_MSB);
  215979. +
  215980. + hdmi_writeb((unsigned char)(csc_coeff[1][0] & 0xFF),
  215981. + HDMI_CSC_COEF_B1_LSB);
  215982. + hdmi_writeb((unsigned char)(csc_coeff[1][0] >> 8),
  215983. + HDMI_CSC_COEF_B1_MSB);
  215984. + hdmi_writeb((unsigned char)(csc_coeff[1][1] & 0xFF),
  215985. + HDMI_CSC_COEF_B2_LSB);
  215986. + hdmi_writeb((unsigned char)(csc_coeff[1][1] >> 8),
  215987. + HDMI_CSC_COEF_B2_MSB);
  215988. + hdmi_writeb((unsigned char)(csc_coeff[1][2] & 0xFF),
  215989. + HDMI_CSC_COEF_B3_LSB);
  215990. + hdmi_writeb((unsigned char)(csc_coeff[1][2] >> 8),
  215991. + HDMI_CSC_COEF_B3_MSB);
  215992. + hdmi_writeb((unsigned char)(csc_coeff[1][3] & 0xFF),
  215993. + HDMI_CSC_COEF_B4_LSB);
  215994. + hdmi_writeb((unsigned char)(csc_coeff[1][3] >> 8),
  215995. + HDMI_CSC_COEF_B4_MSB);
  215996. +
  215997. + hdmi_writeb((unsigned char)(csc_coeff[2][0] & 0xFF),
  215998. + HDMI_CSC_COEF_C1_LSB);
  215999. + hdmi_writeb((unsigned char)(csc_coeff[2][0] >> 8),
  216000. + HDMI_CSC_COEF_C1_MSB);
  216001. + hdmi_writeb((unsigned char)(csc_coeff[2][1] & 0xFF),
  216002. + HDMI_CSC_COEF_C2_LSB);
  216003. + hdmi_writeb((unsigned char)(csc_coeff[2][1] >> 8),
  216004. + HDMI_CSC_COEF_C2_MSB);
  216005. + hdmi_writeb((unsigned char)(csc_coeff[2][2] & 0xFF),
  216006. + HDMI_CSC_COEF_C3_LSB);
  216007. + hdmi_writeb((unsigned char)(csc_coeff[2][2] >> 8),
  216008. + HDMI_CSC_COEF_C3_MSB);
  216009. + hdmi_writeb((unsigned char)(csc_coeff[2][3] & 0xFF),
  216010. + HDMI_CSC_COEF_C4_LSB);
  216011. + hdmi_writeb((unsigned char)(csc_coeff[2][3] >> 8),
  216012. + HDMI_CSC_COEF_C4_MSB);
  216013. +
  216014. + val = hdmi_readb(HDMI_CSC_SCALE);
  216015. + val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK;
  216016. + val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK;
  216017. + hdmi_writeb(val, HDMI_CSC_SCALE);
  216018. +}
  216019. +
  216020. +static void hdmi_video_csc(struct mxc_hdmi *hdmi)
  216021. +{
  216022. + int color_depth = 0;
  216023. + int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
  216024. + int decimation = 0;
  216025. + u8 val;
  216026. +
  216027. + /* YCC422 interpolation to 444 mode */
  216028. + if (isColorSpaceInterpolation(hdmi))
  216029. + interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
  216030. + else if (isColorSpaceDecimation(hdmi))
  216031. + decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
  216032. +
  216033. + if (hdmi->hdmi_data.enc_color_depth == 8)
  216034. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
  216035. + else if (hdmi->hdmi_data.enc_color_depth == 10)
  216036. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
  216037. + else if (hdmi->hdmi_data.enc_color_depth == 12)
  216038. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
  216039. + else if (hdmi->hdmi_data.enc_color_depth == 16)
  216040. + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
  216041. + else
  216042. + return;
  216043. +
  216044. + /*configure the CSC registers */
  216045. + hdmi_writeb(interpolation | decimation, HDMI_CSC_CFG);
  216046. + val = hdmi_readb(HDMI_CSC_SCALE);
  216047. + val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK;
  216048. + val |= color_depth;
  216049. + hdmi_writeb(val, HDMI_CSC_SCALE);
  216050. +
  216051. + update_csc_coeffs(hdmi);
  216052. +}
  216053. +
  216054. +/*!
  216055. + * HDMI video packetizer is used to packetize the data.
  216056. + * for example, if input is YCC422 mode or repeater is used,
  216057. + * data should be repacked this module can be bypassed.
  216058. + */
  216059. +static void hdmi_video_packetize(struct mxc_hdmi *hdmi)
  216060. +{
  216061. + unsigned int color_depth = 0;
  216062. + unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
  216063. + unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
  216064. + struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
  216065. + u8 val;
  216066. +
  216067. + if (hdmi_data->enc_out_format == RGB
  216068. + || hdmi_data->enc_out_format == YCBCR444) {
  216069. + if (hdmi_data->enc_color_depth == 0)
  216070. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  216071. + else if (hdmi_data->enc_color_depth == 8) {
  216072. + color_depth = 4;
  216073. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  216074. + } else if (hdmi_data->enc_color_depth == 10)
  216075. + color_depth = 5;
  216076. + else if (hdmi_data->enc_color_depth == 12)
  216077. + color_depth = 6;
  216078. + else if (hdmi_data->enc_color_depth == 16)
  216079. + color_depth = 7;
  216080. + else
  216081. + return;
  216082. + } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
  216083. + if (hdmi_data->enc_color_depth == 0 ||
  216084. + hdmi_data->enc_color_depth == 8)
  216085. + remap_size = HDMI_VP_REMAP_YCC422_16bit;
  216086. + else if (hdmi_data->enc_color_depth == 10)
  216087. + remap_size = HDMI_VP_REMAP_YCC422_20bit;
  216088. + else if (hdmi_data->enc_color_depth == 12)
  216089. + remap_size = HDMI_VP_REMAP_YCC422_24bit;
  216090. + else
  216091. + return;
  216092. + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
  216093. + } else
  216094. + return;
  216095. +
  216096. + /* HDMI not support deep color,
  216097. + * because IPU MAX support color depth is 24bit */
  216098. + color_depth = 0;
  216099. +
  216100. + /* set the packetizer registers */
  216101. + val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
  216102. + HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
  216103. + ((hdmi_data->pix_repet_factor <<
  216104. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
  216105. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
  216106. + hdmi_writeb(val, HDMI_VP_PR_CD);
  216107. +
  216108. + val = hdmi_readb(HDMI_VP_STUFF);
  216109. + val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK;
  216110. + val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE;
  216111. + hdmi_writeb(val, HDMI_VP_STUFF);
  216112. +
  216113. + /* Data from pixel repeater block */
  216114. + if (hdmi_data->pix_repet_factor > 1) {
  216115. + val = hdmi_readb(HDMI_VP_CONF);
  216116. + val &= ~(HDMI_VP_CONF_PR_EN_MASK |
  216117. + HDMI_VP_CONF_BYPASS_SELECT_MASK);
  216118. + val |= HDMI_VP_CONF_PR_EN_ENABLE |
  216119. + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
  216120. + hdmi_writeb(val, HDMI_VP_CONF);
  216121. + } else { /* data from packetizer block */
  216122. + val = hdmi_readb(HDMI_VP_CONF);
  216123. + val &= ~(HDMI_VP_CONF_PR_EN_MASK |
  216124. + HDMI_VP_CONF_BYPASS_SELECT_MASK);
  216125. + val |= HDMI_VP_CONF_PR_EN_DISABLE |
  216126. + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
  216127. + hdmi_writeb(val, HDMI_VP_CONF);
  216128. + }
  216129. +
  216130. + val = hdmi_readb(HDMI_VP_STUFF);
  216131. + val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK;
  216132. + val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET;
  216133. + hdmi_writeb(val, HDMI_VP_STUFF);
  216134. +
  216135. + hdmi_writeb(remap_size, HDMI_VP_REMAP);
  216136. +
  216137. + if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
  216138. + val = hdmi_readb(HDMI_VP_CONF);
  216139. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  216140. + HDMI_VP_CONF_PP_EN_ENMASK |
  216141. + HDMI_VP_CONF_YCC422_EN_MASK);
  216142. + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
  216143. + HDMI_VP_CONF_PP_EN_ENABLE |
  216144. + HDMI_VP_CONF_YCC422_EN_DISABLE;
  216145. + hdmi_writeb(val, HDMI_VP_CONF);
  216146. + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
  216147. + val = hdmi_readb(HDMI_VP_CONF);
  216148. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  216149. + HDMI_VP_CONF_PP_EN_ENMASK |
  216150. + HDMI_VP_CONF_YCC422_EN_MASK);
  216151. + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
  216152. + HDMI_VP_CONF_PP_EN_DISABLE |
  216153. + HDMI_VP_CONF_YCC422_EN_ENABLE;
  216154. + hdmi_writeb(val, HDMI_VP_CONF);
  216155. + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
  216156. + val = hdmi_readb(HDMI_VP_CONF);
  216157. + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
  216158. + HDMI_VP_CONF_PP_EN_ENMASK |
  216159. + HDMI_VP_CONF_YCC422_EN_MASK);
  216160. + val |= HDMI_VP_CONF_BYPASS_EN_ENABLE |
  216161. + HDMI_VP_CONF_PP_EN_DISABLE |
  216162. + HDMI_VP_CONF_YCC422_EN_DISABLE;
  216163. + hdmi_writeb(val, HDMI_VP_CONF);
  216164. + } else {
  216165. + return;
  216166. + }
  216167. +
  216168. + val = hdmi_readb(HDMI_VP_STUFF);
  216169. + val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK |
  216170. + HDMI_VP_STUFF_YCC422_STUFFING_MASK);
  216171. + val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
  216172. + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE;
  216173. + hdmi_writeb(val, HDMI_VP_STUFF);
  216174. +
  216175. + val = hdmi_readb(HDMI_VP_CONF);
  216176. + val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK;
  216177. + val |= output_select;
  216178. + hdmi_writeb(val, HDMI_VP_CONF);
  216179. +}
  216180. +
  216181. +#if 0
  216182. +/* Force a fixed color screen */
  216183. +static void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force)
  216184. +{
  216185. + u8 val;
  216186. +
  216187. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  216188. +
  216189. + if (force) {
  216190. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
  216191. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
  216192. + hdmi_writeb(0xFF, HDMI_FC_DBGTMDS0); /* B */
  216193. + val = hdmi_readb(HDMI_FC_DBGFORCE);
  216194. + val |= HDMI_FC_DBGFORCE_FORCEVIDEO;
  216195. + hdmi_writeb(val, HDMI_FC_DBGFORCE);
  216196. + } else {
  216197. + val = hdmi_readb(HDMI_FC_DBGFORCE);
  216198. + val &= ~HDMI_FC_DBGFORCE_FORCEVIDEO;
  216199. + hdmi_writeb(val, HDMI_FC_DBGFORCE);
  216200. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
  216201. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
  216202. + hdmi_writeb(0x00, HDMI_FC_DBGTMDS0); /* B */
  216203. + }
  216204. +}
  216205. +#endif
  216206. +
  216207. +static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi,
  216208. + unsigned char bit)
  216209. +{
  216210. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  216211. + val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
  216212. + val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
  216213. + HDMI_PHY_TST0_TSTCLR_MASK;
  216214. + hdmi_writeb(val, HDMI_PHY_TST0);
  216215. +}
  216216. +
  216217. +static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi,
  216218. + unsigned char bit)
  216219. +{
  216220. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  216221. + val &= ~HDMI_PHY_TST0_TSTEN_MASK;
  216222. + val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) &
  216223. + HDMI_PHY_TST0_TSTEN_MASK;
  216224. + hdmi_writeb(val, HDMI_PHY_TST0);
  216225. +}
  216226. +
  216227. +static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi,
  216228. + unsigned char bit)
  216229. +{
  216230. + u8 val = hdmi_readb(HDMI_PHY_TST0);
  216231. + val &= ~HDMI_PHY_TST0_TSTCLK_MASK;
  216232. + val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) &
  216233. + HDMI_PHY_TST0_TSTCLK_MASK;
  216234. + hdmi_writeb(val, HDMI_PHY_TST0);
  216235. +}
  216236. +
  216237. +static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi,
  216238. + unsigned char bit)
  216239. +{
  216240. + hdmi_writeb(bit, HDMI_PHY_TST1);
  216241. +}
  216242. +
  216243. +static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi,
  216244. + unsigned char bit)
  216245. +{
  216246. + hdmi_writeb(bit, HDMI_PHY_TST2);
  216247. +}
  216248. +
  216249. +static bool hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
  216250. +{
  216251. + unsigned char val = 0;
  216252. + val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
  216253. + while (val == 0) {
  216254. + udelay(1000);
  216255. + if (msec-- == 0)
  216256. + return false;
  216257. + val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
  216258. + }
  216259. + return true;
  216260. +}
  216261. +
  216262. +static void hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data,
  216263. + unsigned char addr)
  216264. +{
  216265. + hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
  216266. + hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
  216267. + hdmi_writeb((unsigned char)(data >> 8),
  216268. + HDMI_PHY_I2CM_DATAO_1_ADDR);
  216269. + hdmi_writeb((unsigned char)(data >> 0),
  216270. + HDMI_PHY_I2CM_DATAO_0_ADDR);
  216271. + hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
  216272. + HDMI_PHY_I2CM_OPERATION_ADDR);
  216273. + hdmi_phy_wait_i2c_done(hdmi, 1000);
  216274. +}
  216275. +
  216276. +#if 0
  216277. +static unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi,
  216278. + unsigned char addr)
  216279. +{
  216280. + unsigned short data;
  216281. + unsigned char msb = 0, lsb = 0;
  216282. + hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
  216283. + hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
  216284. + hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_READ,
  216285. + HDMI_PHY_I2CM_OPERATION_ADDR);
  216286. + hdmi_phy_wait_i2c_done(hdmi, 1000);
  216287. + msb = hdmi_readb(HDMI_PHY_I2CM_DATAI_1_ADDR);
  216288. + lsb = hdmi_readb(HDMI_PHY_I2CM_DATAI_0_ADDR);
  216289. + data = (msb << 8) | lsb;
  216290. + return data;
  216291. +}
  216292. +
  216293. +static int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data,
  216294. + unsigned char addr)
  216295. +{
  216296. + unsigned short val = 0;
  216297. + hdmi_phy_i2c_write(hdmi, data, addr);
  216298. + val = hdmi_phy_i2c_read(hdmi, addr);
  216299. + return (val == data);
  216300. +}
  216301. +#endif
  216302. +
  216303. +static bool hdmi_edid_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
  216304. +{
  216305. + unsigned char val = 0;
  216306. + val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
  216307. + while (val == 0) {
  216308. +
  216309. + udelay(1000);
  216310. + if (msec-- == 0) {
  216311. + dev_dbg(&hdmi->pdev->dev,
  216312. + "HDMI EDID i2c operation time out!!\n");
  216313. + return false;
  216314. + }
  216315. + val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
  216316. + }
  216317. + return true;
  216318. +}
  216319. +
  216320. +static u8 hdmi_edid_i2c_read(struct mxc_hdmi *hdmi,
  216321. + u8 addr, u8 blockno)
  216322. +{
  216323. + u8 spointer = blockno / 2;
  216324. + u8 edidaddress = ((blockno % 2) * 0x80) + addr;
  216325. + u8 data;
  216326. +
  216327. + hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
  216328. + hdmi_writeb(edidaddress, HDMI_I2CM_ADDRESS);
  216329. + hdmi_writeb(spointer, HDMI_I2CM_SEGADDR);
  216330. + if (spointer == 0)
  216331. + hdmi_writeb(HDMI_I2CM_OPERATION_READ,
  216332. + HDMI_I2CM_OPERATION);
  216333. + else
  216334. + hdmi_writeb(HDMI_I2CM_OPERATION_READ_EXT,
  216335. + HDMI_I2CM_OPERATION);
  216336. +
  216337. + hdmi_edid_wait_i2c_done(hdmi, 1000);
  216338. + data = hdmi_readb(HDMI_I2CM_DATAI);
  216339. + hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
  216340. + return data;
  216341. +}
  216342. +
  216343. +
  216344. +/* "Power-down enable (active low)"
  216345. + * That mean that power up == 1! */
  216346. +static void mxc_hdmi_phy_enable_power(u8 enable)
  216347. +{
  216348. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  216349. + HDMI_PHY_CONF0_PDZ_OFFSET,
  216350. + HDMI_PHY_CONF0_PDZ_MASK);
  216351. +}
  216352. +
  216353. +static void mxc_hdmi_phy_enable_tmds(u8 enable)
  216354. +{
  216355. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  216356. + HDMI_PHY_CONF0_ENTMDS_OFFSET,
  216357. + HDMI_PHY_CONF0_ENTMDS_MASK);
  216358. +}
  216359. +
  216360. +static void mxc_hdmi_phy_gen2_pddq(u8 enable)
  216361. +{
  216362. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  216363. + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
  216364. + HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
  216365. +}
  216366. +
  216367. +static void mxc_hdmi_phy_gen2_txpwron(u8 enable)
  216368. +{
  216369. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  216370. + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
  216371. + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
  216372. +}
  216373. +
  216374. +#if 0
  216375. +static void mxc_hdmi_phy_gen2_enhpdrxsense(u8 enable)
  216376. +{
  216377. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  216378. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET,
  216379. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK);
  216380. +}
  216381. +#endif
  216382. +
  216383. +static void mxc_hdmi_phy_sel_data_en_pol(u8 enable)
  216384. +{
  216385. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  216386. + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
  216387. + HDMI_PHY_CONF0_SELDATAENPOL_MASK);
  216388. +}
  216389. +
  216390. +static void mxc_hdmi_phy_sel_interface_control(u8 enable)
  216391. +{
  216392. + hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
  216393. + HDMI_PHY_CONF0_SELDIPIF_OFFSET,
  216394. + HDMI_PHY_CONF0_SELDIPIF_MASK);
  216395. +}
  216396. +
  216397. +static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep,
  216398. + unsigned char cRes, int cscOn)
  216399. +{
  216400. + u8 val;
  216401. + u8 msec;
  216402. +
  216403. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  216404. +
  216405. + /* color resolution 0 is 8 bit colour depth */
  216406. + if (cRes == 0)
  216407. + cRes = 8;
  216408. +
  216409. + if (pRep != 0)
  216410. + return false;
  216411. + else if (cRes != 8 && cRes != 12)
  216412. + return false;
  216413. +
  216414. + /* Enable csc path */
  216415. + if (cscOn)
  216416. + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
  216417. + else
  216418. + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
  216419. +
  216420. + hdmi_writeb(val, HDMI_MC_FLOWCTRL);
  216421. +
  216422. + /* gen2 tx power off */
  216423. + mxc_hdmi_phy_gen2_txpwron(0);
  216424. +
  216425. + /* gen2 pddq */
  216426. + mxc_hdmi_phy_gen2_pddq(1);
  216427. +
  216428. + /* PHY reset */
  216429. + hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
  216430. + hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
  216431. +
  216432. + hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
  216433. +
  216434. + hdmi_phy_test_clear(hdmi, 1);
  216435. + hdmi_writeb(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
  216436. + HDMI_PHY_I2CM_SLAVE_ADDR);
  216437. + hdmi_phy_test_clear(hdmi, 0);
  216438. +
  216439. + if (hdmi->hdmi_data.video_mode.mPixelClock < 0) {
  216440. + dev_dbg(&hdmi->pdev->dev, "Pixel clock (%d) must be positive\n",
  216441. + hdmi->hdmi_data.video_mode.mPixelClock);
  216442. + return false;
  216443. + }
  216444. +
  216445. + if (hdmi->hdmi_data.video_mode.mPixelClock <= 45250000) {
  216446. + switch (cRes) {
  216447. + case 8:
  216448. + /* PLL/MPLL Cfg */
  216449. + hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
  216450. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */
  216451. + break;
  216452. + case 10:
  216453. + hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
  216454. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
  216455. + break;
  216456. + case 12:
  216457. + hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
  216458. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
  216459. + break;
  216460. + default:
  216461. + return false;
  216462. + }
  216463. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 92500000) {
  216464. + switch (cRes) {
  216465. + case 8:
  216466. + hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
  216467. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  216468. + break;
  216469. + case 10:
  216470. + hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
  216471. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  216472. + break;
  216473. + case 12:
  216474. + hdmi_phy_i2c_write(hdmi, 0x4142, 0x06);
  216475. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
  216476. + default:
  216477. + return false;
  216478. + }
  216479. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 148500000) {
  216480. + switch (cRes) {
  216481. + case 8:
  216482. + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
  216483. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  216484. + break;
  216485. + case 10:
  216486. + hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
  216487. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  216488. + break;
  216489. + case 12:
  216490. + hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
  216491. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  216492. + default:
  216493. + return false;
  216494. + }
  216495. + } else {
  216496. + switch (cRes) {
  216497. + case 8:
  216498. + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
  216499. + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
  216500. + break;
  216501. + case 10:
  216502. + hdmi_phy_i2c_write(hdmi, 0x2001, 0x06);
  216503. + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
  216504. + break;
  216505. + case 12:
  216506. + hdmi_phy_i2c_write(hdmi, 0x4002, 0x06);
  216507. + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
  216508. + default:
  216509. + return false;
  216510. + }
  216511. + }
  216512. +
  216513. + if (hdmi->hdmi_data.video_mode.mPixelClock <= 54000000) {
  216514. + switch (cRes) {
  216515. + case 8:
  216516. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */
  216517. + break;
  216518. + case 10:
  216519. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  216520. + break;
  216521. + case 12:
  216522. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216523. + break;
  216524. + default:
  216525. + return false;
  216526. + }
  216527. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 58400000) {
  216528. + switch (cRes) {
  216529. + case 8:
  216530. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  216531. + break;
  216532. + case 10:
  216533. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216534. + break;
  216535. + case 12:
  216536. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216537. + break;
  216538. + default:
  216539. + return false;
  216540. + }
  216541. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 72000000) {
  216542. + switch (cRes) {
  216543. + case 8:
  216544. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216545. + break;
  216546. + case 10:
  216547. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216548. + break;
  216549. + case 12:
  216550. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  216551. + break;
  216552. + default:
  216553. + return false;
  216554. + }
  216555. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 74250000) {
  216556. + switch (cRes) {
  216557. + case 8:
  216558. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216559. + break;
  216560. + case 10:
  216561. + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
  216562. + break;
  216563. + case 12:
  216564. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  216565. + break;
  216566. + default:
  216567. + return false;
  216568. + }
  216569. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 118800000) {
  216570. + switch (cRes) {
  216571. + case 8:
  216572. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  216573. + break;
  216574. + case 10:
  216575. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  216576. + break;
  216577. + case 12:
  216578. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216579. + break;
  216580. + default:
  216581. + return false;
  216582. + }
  216583. + } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 216000000) {
  216584. + switch (cRes) {
  216585. + case 8:
  216586. + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
  216587. + break;
  216588. + case 10:
  216589. + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
  216590. + break;
  216591. + case 12:
  216592. + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
  216593. + break;
  216594. + default:
  216595. + return false;
  216596. + }
  216597. + } else {
  216598. + dev_err(&hdmi->pdev->dev,
  216599. + "Pixel clock %d - unsupported by HDMI\n",
  216600. + hdmi->hdmi_data.video_mode.mPixelClock);
  216601. + return false;
  216602. + }
  216603. +
  216604. + hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
  216605. + hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
  216606. + /* RESISTANCE TERM 133Ohm Cfg */
  216607. + hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
  216608. + /* PREEMP Cgf 0.00 */
  216609. + hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */
  216610. + /* TX/CK LVL 10 */
  216611. + hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */
  216612. +
  216613. + /* Board specific setting for PHY register 0x09, 0x0e to pass HCT */
  216614. + if (hdmi->phy_config.reg_cksymtx != 0)
  216615. + hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_cksymtx, 0x09);
  216616. +
  216617. + if (hdmi->phy_config.reg_vlev != 0)
  216618. + hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_vlev, 0x0E);
  216619. +
  216620. + /* REMOVE CLK TERM */
  216621. + hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
  216622. +
  216623. + if (hdmi->hdmi_data.video_mode.mPixelClock > 148500000) {
  216624. + hdmi_phy_i2c_write(hdmi, 0x800b, 0x09);
  216625. + hdmi_phy_i2c_write(hdmi, 0x0129, 0x0E);
  216626. + }
  216627. +
  216628. + mxc_hdmi_phy_enable_power(1);
  216629. +
  216630. + /* toggle TMDS enable */
  216631. + mxc_hdmi_phy_enable_tmds(0);
  216632. + mxc_hdmi_phy_enable_tmds(1);
  216633. +
  216634. + /* gen2 tx power on */
  216635. + mxc_hdmi_phy_gen2_txpwron(1);
  216636. + mxc_hdmi_phy_gen2_pddq(0);
  216637. +
  216638. + /*Wait for PHY PLL lock */
  216639. + msec = 4;
  216640. + val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
  216641. + while (val == 0) {
  216642. + udelay(1000);
  216643. + if (msec-- == 0) {
  216644. + dev_dbg(&hdmi->pdev->dev, "PHY PLL not locked\n");
  216645. + return false;
  216646. + }
  216647. + val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
  216648. + }
  216649. +
  216650. + return true;
  216651. +}
  216652. +
  216653. +static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi)
  216654. +{
  216655. + int i;
  216656. + bool cscon = false;
  216657. +
  216658. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  216659. +
  216660. + /* Never do phy init if pixel clock is gated.
  216661. + * Otherwise HDMI PHY will get messed up and generate an overflow
  216662. + * interrupt that can't be cleared or detected by accessing the
  216663. + * status register. */
  216664. + if (!hdmi->fb_reg || !hdmi->cable_plugin
  216665. + || (hdmi->blank != FB_BLANK_UNBLANK))
  216666. + return;
  216667. +
  216668. + /*check csc whether needed activated in HDMI mode */
  216669. + cscon = (isColorSpaceConversion(hdmi) &&
  216670. + !hdmi->hdmi_data.video_mode.mDVI);
  216671. +
  216672. + /* HDMI Phy spec says to do the phy initialization sequence twice */
  216673. + for (i = 0 ; i < 2 ; i++) {
  216674. + mxc_hdmi_phy_sel_data_en_pol(1);
  216675. + mxc_hdmi_phy_sel_interface_control(0);
  216676. + mxc_hdmi_phy_enable_tmds(0);
  216677. + mxc_hdmi_phy_enable_power(0);
  216678. +
  216679. + /* Enable CSC */
  216680. + hdmi_phy_configure(hdmi, 0, 8, cscon);
  216681. + }
  216682. +
  216683. + hdmi->phy_enabled = true;
  216684. + if (!hdmi->hdmi_data.video_mode.mDVI)
  216685. + hdmi_enable_overflow_interrupts();
  216686. +}
  216687. +
  216688. +static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
  216689. +{
  216690. + u8 val;
  216691. + u8 pix_fmt;
  216692. + u8 under_scan;
  216693. + u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
  216694. + struct fb_videomode mode;
  216695. + const struct fb_videomode *edid_mode;
  216696. + bool aspect_16_9;
  216697. +
  216698. + dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n");
  216699. +
  216700. + fb_var_to_videomode(&mode, &hdmi->fbi->var);
  216701. + /* Use mode from list extracted from EDID to get aspect ratio */
  216702. + if (!list_empty(&hdmi->fbi->modelist)) {
  216703. + edid_mode = fb_find_nearest_mode(&mode, &hdmi->fbi->modelist);
  216704. + if (edid_mode->vmode & FB_VMODE_ASPECT_16_9)
  216705. + aspect_16_9 = true;
  216706. + else
  216707. + aspect_16_9 = false;
  216708. + } else
  216709. + aspect_16_9 = false;
  216710. +
  216711. + /********************************************
  216712. + * AVI Data Byte 1
  216713. + ********************************************/
  216714. + if (hdmi->hdmi_data.enc_out_format == YCBCR444)
  216715. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
  216716. + else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
  216717. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
  216718. + else
  216719. + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
  216720. +
  216721. + if (hdmi->edid_cfg.cea_underscan)
  216722. + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN;
  216723. + else
  216724. + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
  216725. +
  216726. + /*
  216727. + * Active format identification data is present in the AVI InfoFrame.
  216728. + * Under scan info, no bar data
  216729. + */
  216730. + val = pix_fmt | under_scan |
  216731. + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
  216732. + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
  216733. +
  216734. + hdmi_writeb(val, HDMI_FC_AVICONF0);
  216735. +
  216736. + /********************************************
  216737. + * AVI Data Byte 2
  216738. + ********************************************/
  216739. +
  216740. + /* Set the Aspect Ratio */
  216741. + if (aspect_16_9) {
  216742. + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
  216743. + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
  216744. + } else {
  216745. + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
  216746. + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
  216747. + }
  216748. +
  216749. + /* Set up colorimetry */
  216750. + if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
  216751. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
  216752. + if (hdmi->hdmi_data.colorimetry == eITU601)
  216753. + ext_colorimetry =
  216754. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  216755. + else /* hdmi->hdmi_data.colorimetry == eITU709 */
  216756. + ext_colorimetry =
  216757. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
  216758. + } else if (hdmi->hdmi_data.enc_out_format != RGB) {
  216759. + if (hdmi->hdmi_data.colorimetry == eITU601)
  216760. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
  216761. + else /* hdmi->hdmi_data.colorimetry == eITU709 */
  216762. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
  216763. + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  216764. + } else { /* Carries no data */
  216765. + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
  216766. + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  216767. + }
  216768. +
  216769. + val = colorimetry | coded_ratio | act_ratio;
  216770. + hdmi_writeb(val, HDMI_FC_AVICONF1);
  216771. +
  216772. + /********************************************
  216773. + * AVI Data Byte 3
  216774. + ********************************************/
  216775. +
  216776. + val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
  216777. + hdmi->hdmi_data.rgb_quant_range |
  216778. + HDMI_FC_AVICONF2_SCALING_NONE;
  216779. + hdmi_writeb(val, HDMI_FC_AVICONF2);
  216780. +
  216781. + /********************************************
  216782. + * AVI Data Byte 4
  216783. + ********************************************/
  216784. + hdmi_writeb(hdmi->vic, HDMI_FC_AVIVID);
  216785. +
  216786. + /********************************************
  216787. + * AVI Data Byte 5
  216788. + ********************************************/
  216789. +
  216790. + /* Set up input and output pixel repetition */
  216791. + val = (((hdmi->hdmi_data.video_mode.mPixelRepetitionInput + 1) <<
  216792. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
  216793. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
  216794. + ((hdmi->hdmi_data.video_mode.mPixelRepetitionOutput <<
  216795. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
  216796. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
  216797. + hdmi_writeb(val, HDMI_FC_PRCONF);
  216798. +
  216799. + /* IT Content and quantization range = don't care */
  216800. + val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
  216801. + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
  216802. + hdmi_writeb(val, HDMI_FC_AVICONF3);
  216803. +
  216804. + /********************************************
  216805. + * AVI Data Bytes 6-13
  216806. + ********************************************/
  216807. + hdmi_writeb(0, HDMI_FC_AVIETB0);
  216808. + hdmi_writeb(0, HDMI_FC_AVIETB1);
  216809. + hdmi_writeb(0, HDMI_FC_AVISBB0);
  216810. + hdmi_writeb(0, HDMI_FC_AVISBB1);
  216811. + hdmi_writeb(0, HDMI_FC_AVIELB0);
  216812. + hdmi_writeb(0, HDMI_FC_AVIELB1);
  216813. + hdmi_writeb(0, HDMI_FC_AVISRB0);
  216814. + hdmi_writeb(0, HDMI_FC_AVISRB1);
  216815. +}
  216816. +
  216817. +/*!
  216818. + * this submodule is responsible for the video/audio data composition.
  216819. + */
  216820. +static void hdmi_av_composer(struct mxc_hdmi *hdmi)
  216821. +{
  216822. + u8 inv_val;
  216823. + struct fb_info *fbi = hdmi->fbi;
  216824. + struct fb_videomode fb_mode;
  216825. + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
  216826. + int hblank, vblank;
  216827. +
  216828. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  216829. +
  216830. + fb_var_to_videomode(&fb_mode, &fbi->var);
  216831. +
  216832. + vmode->mHSyncPolarity = ((fb_mode.sync & FB_SYNC_HOR_HIGH_ACT) != 0);
  216833. + vmode->mVSyncPolarity = ((fb_mode.sync & FB_SYNC_VERT_HIGH_ACT) != 0);
  216834. + vmode->mInterlaced = ((fb_mode.vmode & FB_VMODE_INTERLACED) != 0);
  216835. + vmode->mPixelClock = (fb_mode.xres + fb_mode.left_margin +
  216836. + fb_mode.right_margin + fb_mode.hsync_len) * (fb_mode.yres +
  216837. + fb_mode.upper_margin + fb_mode.lower_margin +
  216838. + fb_mode.vsync_len) * fb_mode.refresh;
  216839. +
  216840. + dev_dbg(&hdmi->pdev->dev, "final pixclk = %d\n", vmode->mPixelClock);
  216841. +
  216842. + /* Set up HDMI_FC_INVIDCONF */
  216843. + inv_val = (vmode->mVSyncPolarity ?
  216844. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
  216845. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
  216846. +
  216847. + inv_val |= (vmode->mHSyncPolarity ?
  216848. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
  216849. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
  216850. +
  216851. + inv_val |= (vmode->mDataEnablePolarity ?
  216852. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
  216853. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
  216854. +
  216855. + if (hdmi->vic == 39)
  216856. + inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
  216857. + else
  216858. + inv_val |= (vmode->mInterlaced ?
  216859. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
  216860. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
  216861. +
  216862. + inv_val |= (vmode->mInterlaced ?
  216863. + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
  216864. + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
  216865. +
  216866. + inv_val |= (vmode->mDVI ?
  216867. + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
  216868. + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
  216869. +
  216870. + hdmi_writeb(inv_val, HDMI_FC_INVIDCONF);
  216871. +
  216872. + /* Set up horizontal active pixel region width */
  216873. + hdmi_writeb(fb_mode.xres >> 8, HDMI_FC_INHACTV1);
  216874. + hdmi_writeb(fb_mode.xres, HDMI_FC_INHACTV0);
  216875. +
  216876. + /* Set up vertical blanking pixel region width */
  216877. + hdmi_writeb(fb_mode.yres >> 8, HDMI_FC_INVACTV1);
  216878. + hdmi_writeb(fb_mode.yres, HDMI_FC_INVACTV0);
  216879. +
  216880. + /* Set up horizontal blanking pixel region width */
  216881. + hblank = fb_mode.left_margin + fb_mode.right_margin +
  216882. + fb_mode.hsync_len;
  216883. + hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1);
  216884. + hdmi_writeb(hblank, HDMI_FC_INHBLANK0);
  216885. +
  216886. + /* Set up vertical blanking pixel region width */
  216887. + vblank = fb_mode.upper_margin + fb_mode.lower_margin +
  216888. + fb_mode.vsync_len;
  216889. + hdmi_writeb(vblank, HDMI_FC_INVBLANK);
  216890. +
  216891. + /* Set up HSYNC active edge delay width (in pixel clks) */
  216892. + hdmi_writeb(fb_mode.right_margin >> 8, HDMI_FC_HSYNCINDELAY1);
  216893. + hdmi_writeb(fb_mode.right_margin, HDMI_FC_HSYNCINDELAY0);
  216894. +
  216895. + /* Set up VSYNC active edge delay (in pixel clks) */
  216896. + hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY);
  216897. +
  216898. + /* Set up HSYNC active pulse width (in pixel clks) */
  216899. + hdmi_writeb(fb_mode.hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
  216900. + hdmi_writeb(fb_mode.hsync_len, HDMI_FC_HSYNCINWIDTH0);
  216901. +
  216902. + /* Set up VSYNC active edge delay (in pixel clks) */
  216903. + hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH);
  216904. +
  216905. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  216906. +}
  216907. +
  216908. +static int mxc_edid_read_internal(struct mxc_hdmi *hdmi, unsigned char *edid,
  216909. + struct mxc_edid_cfg *cfg, struct fb_info *fbi)
  216910. +{
  216911. + int extblknum;
  216912. + int i, j, ret;
  216913. + unsigned char *ediddata = edid;
  216914. + unsigned char tmpedid[EDID_LENGTH];
  216915. +
  216916. + dev_info(&hdmi->pdev->dev, "%s\n", __func__);
  216917. +
  216918. + if (!edid || !cfg || !fbi)
  216919. + return -EINVAL;
  216920. +
  216921. + /* init HDMI I2CM for read edid*/
  216922. + hdmi_writeb(0x0, HDMI_I2CM_DIV);
  216923. + hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_HCNT_1_ADDR);
  216924. + hdmi_writeb(0x79, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
  216925. + hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_LCNT_1_ADDR);
  216926. + hdmi_writeb(0x91, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
  216927. +
  216928. + hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_HCNT_1_ADDR);
  216929. + hdmi_writeb(0x0F, HDMI_I2CM_FS_SCL_HCNT_0_ADDR);
  216930. + hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_LCNT_1_ADDR);
  216931. + hdmi_writeb(0x21, HDMI_I2CM_FS_SCL_LCNT_0_ADDR);
  216932. +
  216933. + hdmi_writeb(0x50, HDMI_I2CM_SLAVE);
  216934. + hdmi_writeb(0x30, HDMI_I2CM_SEGADDR);
  216935. +
  216936. + /* Umask edid interrupt */
  216937. + hdmi_writeb(HDMI_I2CM_INT_DONE_POL,
  216938. + HDMI_I2CM_INT);
  216939. +
  216940. + hdmi_writeb(HDMI_I2CM_CTLINT_NAC_POL |
  216941. + HDMI_I2CM_CTLINT_ARBITRATION_POL,
  216942. + HDMI_I2CM_CTLINT);
  216943. +
  216944. + /* reset edid data zero */
  216945. + memset(edid, 0, EDID_LENGTH*4);
  216946. + memset(cfg, 0, sizeof(struct mxc_edid_cfg));
  216947. +
  216948. + /* Check first three byte of EDID head */
  216949. + if (!(hdmi_edid_i2c_read(hdmi, 0, 0) == 0x00) ||
  216950. + !(hdmi_edid_i2c_read(hdmi, 1, 0) == 0xFF) ||
  216951. + !(hdmi_edid_i2c_read(hdmi, 2, 0) == 0xFF)) {
  216952. + dev_info(&hdmi->pdev->dev, "EDID head check failed!");
  216953. + return -ENOENT;
  216954. + }
  216955. +
  216956. + for (i = 0; i < 128; i++) {
  216957. + *ediddata = hdmi_edid_i2c_read(hdmi, i, 0);
  216958. + ediddata++;
  216959. + }
  216960. +
  216961. + extblknum = edid[0x7E];
  216962. + if (extblknum < 0)
  216963. + return extblknum;
  216964. +
  216965. + if (extblknum) {
  216966. + ediddata = edid + EDID_LENGTH;
  216967. + for (i = 0; i < 128; i++) {
  216968. + *ediddata = hdmi_edid_i2c_read(hdmi, i, 1);
  216969. + ediddata++;
  216970. + }
  216971. + }
  216972. +
  216973. + /* edid first block parsing */
  216974. + memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
  216975. + fb_edid_to_monspecs(edid, &fbi->monspecs);
  216976. +
  216977. + ret = mxc_edid_parse_ext_blk(edid + EDID_LENGTH,
  216978. + cfg, &fbi->monspecs);
  216979. + if (ret < 0) {
  216980. + fb_edid_add_monspecs(edid + EDID_LENGTH, &fbi->monspecs);
  216981. + if (fbi->monspecs.modedb_len > 0)
  216982. + hdmi->edid_cfg.hdmi_cap = false;
  216983. + else
  216984. + return -ENOENT;
  216985. + }
  216986. +
  216987. + /* need read segment block? */
  216988. + if (extblknum > 1) {
  216989. + for (j = 1; j <= extblknum; j++) {
  216990. + for (i = 0; i < 128; i++)
  216991. + *(tmpedid + 1) = hdmi_edid_i2c_read(hdmi, i, j);
  216992. +
  216993. + /* edid ext block parsing */
  216994. + ret = mxc_edid_parse_ext_blk(tmpedid + EDID_LENGTH,
  216995. + cfg, &fbi->monspecs);
  216996. + if (ret < 0)
  216997. + return -ENOENT;
  216998. + }
  216999. + }
  217000. +
  217001. + return 0;
  217002. +}
  217003. +
  217004. +static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi)
  217005. +{
  217006. + int ret;
  217007. + u8 edid_old[HDMI_EDID_LEN];
  217008. + u8 clkdis;
  217009. +
  217010. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217011. +
  217012. + /* save old edid */
  217013. + memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN);
  217014. +
  217015. + /* Read EDID via HDMI DDC when HDCP Enable */
  217016. + if (!hdcp_init)
  217017. + ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
  217018. + hdmi->edid, &hdmi->edid_cfg, hdmi->fbi);
  217019. + else {
  217020. +
  217021. + /* Disable HDCP clk */
  217022. + if (hdmi->hdmi_data.hdcp_enable) {
  217023. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  217024. + clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
  217025. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  217026. + }
  217027. +
  217028. + ret = mxc_edid_read_internal(hdmi, hdmi->edid,
  217029. + &hdmi->edid_cfg, hdmi->fbi);
  217030. +
  217031. + /* Enable HDCP clk */
  217032. + if (hdmi->hdmi_data.hdcp_enable) {
  217033. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  217034. + clkdis &= ~HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
  217035. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  217036. + }
  217037. +
  217038. + }
  217039. +
  217040. + if (ret < 0)
  217041. + return HDMI_EDID_FAIL;
  217042. +
  217043. + dev_info(&hdmi->pdev->dev, "%s HDMI in %s mode\n", __func__, hdmi->edid_cfg.hdmi_cap?"HDMI":"DVI");
  217044. + hdmi->plug_event = hdmi->edid_cfg.hdmi_cap?HDMI_IH_PHY_STAT0_HPD:HDMI_DVI_IH_STAT;
  217045. + hdmi->plug_mask = hdmi->edid_cfg.hdmi_cap?HDMI_PHY_HPD:HDMI_DVI_STAT;
  217046. +
  217047. + if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN)) {
  217048. + dev_info(&hdmi->pdev->dev, "same edid\n");
  217049. + return HDMI_EDID_SAME;
  217050. + }
  217051. +
  217052. + if (hdmi->fbi->monspecs.modedb_len == 0) {
  217053. + dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
  217054. + return HDMI_EDID_NO_MODES;
  217055. + }
  217056. +
  217057. + return HDMI_EDID_SUCCESS;
  217058. +}
  217059. +
  217060. +static void mxc_hdmi_phy_disable(struct mxc_hdmi *hdmi)
  217061. +{
  217062. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217063. +
  217064. + if (!hdmi->phy_enabled)
  217065. + return;
  217066. +
  217067. + hdmi_disable_overflow_interrupts();
  217068. +
  217069. + /* Setting PHY to reset status */
  217070. + hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
  217071. +
  217072. + /* Power down PHY */
  217073. + mxc_hdmi_phy_enable_tmds(0);
  217074. + mxc_hdmi_phy_enable_power(0);
  217075. + mxc_hdmi_phy_gen2_txpwron(0);
  217076. + mxc_hdmi_phy_gen2_pddq(1);
  217077. +
  217078. + hdmi->phy_enabled = false;
  217079. + dev_dbg(&hdmi->pdev->dev, "%s - exit\n", __func__);
  217080. +}
  217081. +
  217082. +/* HDMI Initialization Step B.4 */
  217083. +static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi)
  217084. +{
  217085. + u8 clkdis;
  217086. +
  217087. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217088. +
  217089. + /* control period minimum duration */
  217090. + hdmi_writeb(12, HDMI_FC_CTRLDUR);
  217091. + hdmi_writeb(32, HDMI_FC_EXCTRLDUR);
  217092. + hdmi_writeb(1, HDMI_FC_EXCTRLSPAC);
  217093. +
  217094. + /* Set to fill TMDS data channels */
  217095. + hdmi_writeb(0x0B, HDMI_FC_CH0PREAM);
  217096. + hdmi_writeb(0x16, HDMI_FC_CH1PREAM);
  217097. + hdmi_writeb(0x21, HDMI_FC_CH2PREAM);
  217098. +
  217099. + /* Save CEC clock */
  217100. + clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
  217101. + clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  217102. +
  217103. + /* Enable pixel clock and tmds data path */
  217104. + clkdis = 0x7F & clkdis;
  217105. + clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
  217106. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  217107. +
  217108. + clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
  217109. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  217110. +
  217111. + /* Enable csc path */
  217112. + if (isColorSpaceConversion(hdmi)) {
  217113. + clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
  217114. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  217115. + }
  217116. +}
  217117. +
  217118. +static void hdmi_enable_audio_clk(struct mxc_hdmi *hdmi)
  217119. +{
  217120. + u8 clkdis;
  217121. +
  217122. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217123. +
  217124. + clkdis = hdmi_readb(HDMI_MC_CLKDIS);
  217125. + clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
  217126. + hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
  217127. +}
  217128. +
  217129. +/* Workaround to clear the overflow condition */
  217130. +static void mxc_hdmi_clear_overflow(struct mxc_hdmi *hdmi)
  217131. +{
  217132. + int count;
  217133. + u8 val;
  217134. +
  217135. + /* TMDS software reset */
  217136. + hdmi_writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
  217137. +
  217138. + val = hdmi_readb(HDMI_FC_INVIDCONF);
  217139. +
  217140. + if (cpu_is_imx6dl(hdmi)) {
  217141. + hdmi_writeb(val, HDMI_FC_INVIDCONF);
  217142. + return;
  217143. + }
  217144. +
  217145. + for (count = 0 ; count < 5 ; count++)
  217146. + hdmi_writeb(val, HDMI_FC_INVIDCONF);
  217147. +}
  217148. +
  217149. +static void hdmi_enable_overflow_interrupts(void)
  217150. +{
  217151. + pr_debug("%s\n", __func__);
  217152. + hdmi_writeb(0, HDMI_FC_MASK2);
  217153. + hdmi_writeb(0, HDMI_IH_MUTE_FC_STAT2);
  217154. +}
  217155. +
  217156. +static void hdmi_disable_overflow_interrupts(void)
  217157. +{
  217158. + pr_debug("%s\n", __func__);
  217159. + hdmi_writeb(HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
  217160. + HDMI_IH_MUTE_FC_STAT2);
  217161. + hdmi_writeb(0xff, HDMI_FC_MASK2);
  217162. +}
  217163. +
  217164. +static void mxc_hdmi_notify_fb(struct mxc_hdmi *hdmi)
  217165. +{
  217166. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217167. +
  217168. + /* Don't notify if we aren't registered yet */
  217169. + WARN_ON(!hdmi->fb_reg);
  217170. +
  217171. + /* disable the phy before ipu changes mode */
  217172. + mxc_hdmi_phy_disable(hdmi);
  217173. +
  217174. + /*
  217175. + * Note that fb_set_var will block. During this time,
  217176. + * FB_EVENT_MODE_CHANGE callback will happen.
  217177. + * So by the end of this function, mxc_hdmi_setup()
  217178. + * will be done.
  217179. + */
  217180. + hdmi->fbi->var.activate |= FB_ACTIVATE_FORCE;
  217181. + console_lock();
  217182. + hdmi->fbi->flags |= FBINFO_MISC_USEREVENT;
  217183. + fb_set_var(hdmi->fbi, &hdmi->fbi->var);
  217184. + hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
  217185. + console_unlock();
  217186. +
  217187. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  217188. +}
  217189. +
  217190. +static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
  217191. +{
  217192. + int i;
  217193. + struct fb_videomode *mode;
  217194. +
  217195. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217196. +
  217197. + console_lock();
  217198. +
  217199. + fb_destroy_modelist(&hdmi->fbi->modelist);
  217200. + fb_add_videomode(&vga_mode, &hdmi->fbi->modelist);
  217201. +
  217202. + for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
  217203. + /*
  217204. + * We might check here if mode is supported by HDMI.
  217205. + * We do not currently support interlaced modes.
  217206. + * And add CEA modes in the modelist.
  217207. + */
  217208. + mode = &hdmi->fbi->monspecs.modedb[i];
  217209. +
  217210. + if ((mode->vmode & FB_VMODE_INTERLACED) ||
  217211. + (hdmi->edid_cfg.hdmi_cap &&
  217212. + (mxc_edid_mode_to_vic(mode) == 0)))
  217213. + continue;
  217214. +
  217215. + dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i);
  217216. + dev_dbg(&hdmi->pdev->dev,
  217217. + "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
  217218. + hdmi->fbi->monspecs.modedb[i].xres,
  217219. + hdmi->fbi->monspecs.modedb[i].yres,
  217220. + hdmi->fbi->monspecs.modedb[i].refresh,
  217221. + hdmi->fbi->monspecs.modedb[i].vmode,
  217222. + hdmi->fbi->monspecs.modedb[i].flag);
  217223. +
  217224. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  217225. + }
  217226. +
  217227. + console_unlock();
  217228. +}
  217229. +
  217230. +static void mxc_hdmi_default_edid_cfg(struct mxc_hdmi *hdmi)
  217231. +{
  217232. + /* Default setting HDMI working in HDMI mode */
  217233. + hdmi->edid_cfg.hdmi_cap = true;
  217234. +}
  217235. +
  217236. +static void mxc_hdmi_default_modelist(struct mxc_hdmi *hdmi)
  217237. +{
  217238. + u32 i;
  217239. + const struct fb_videomode *mode;
  217240. +
  217241. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217242. +
  217243. + /* If not EDID data read, set up default modelist */
  217244. + dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
  217245. + dev_info(&hdmi->pdev->dev, "create default modelist\n");
  217246. +
  217247. + console_lock();
  217248. +
  217249. + fb_destroy_modelist(&hdmi->fbi->modelist);
  217250. +
  217251. + /*Add all no interlaced CEA mode to default modelist */
  217252. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  217253. + mode = &mxc_cea_mode[i];
  217254. + if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
  217255. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  217256. + }
  217257. +
  217258. + console_unlock();
  217259. +}
  217260. +
  217261. +static void mxc_hdmi_set_mode_to_vga_dvi(struct mxc_hdmi *hdmi)
  217262. +{
  217263. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217264. +
  217265. + hdmi_disable_overflow_interrupts();
  217266. +
  217267. + fb_videomode_to_var(&hdmi->fbi->var, &vga_mode);
  217268. +
  217269. + hdmi->requesting_vga_for_initialization = true;
  217270. + mxc_hdmi_notify_fb(hdmi);
  217271. + hdmi->requesting_vga_for_initialization = false;
  217272. +}
  217273. +
  217274. +static void mxc_hdmi_set_mode(struct mxc_hdmi *hdmi)
  217275. +{
  217276. + const struct fb_videomode *mode;
  217277. + struct fb_videomode m;
  217278. + struct fb_var_screeninfo var;
  217279. +
  217280. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217281. +
  217282. + /* Set the default mode only once. */
  217283. + if (!hdmi->dft_mode_set) {
  217284. + fb_videomode_to_var(&var, &hdmi->default_mode);
  217285. + hdmi->dft_mode_set = true;
  217286. + } else
  217287. + fb_videomode_to_var(&var, &hdmi->previous_non_vga_mode);
  217288. +
  217289. + fb_var_to_videomode(&m, &var);
  217290. + dump_fb_videomode(&m);
  217291. +
  217292. + mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  217293. + if (!mode) {
  217294. + pr_err("%s: could not find mode in modelist\n", __func__);
  217295. + return;
  217296. + }
  217297. +
  217298. + /* If video mode same as previous, init HDMI again */
  217299. + if (fb_mode_is_equal(&hdmi->previous_non_vga_mode, mode)) {
  217300. + dev_dbg(&hdmi->pdev->dev,
  217301. + "%s: Video mode same as previous\n", __func__);
  217302. + /* update fbi mode in case modelist is updated */
  217303. + hdmi->fbi->mode = (struct fb_videomode *)mode;
  217304. + /* update hdmi setting in case EDID data updated */
  217305. + mxc_hdmi_setup(hdmi, 0);
  217306. + } else {
  217307. + dev_dbg(&hdmi->pdev->dev, "%s: New video mode\n", __func__);
  217308. + mxc_hdmi_set_mode_to_vga_dvi(hdmi);
  217309. + fb_videomode_to_var(&hdmi->fbi->var, mode);
  217310. + dump_fb_videomode((struct fb_videomode *)mode);
  217311. + mxc_hdmi_notify_fb(hdmi);
  217312. + }
  217313. +
  217314. +}
  217315. +
  217316. +static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
  217317. +{
  217318. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217319. +
  217320. + hdmi->cable_plugin = true;
  217321. +
  217322. + /* HDMI Initialization Step C */
  217323. + hdmi->edid_status = mxc_hdmi_read_edid(hdmi);
  217324. +
  217325. + /* Read EDID again if first EDID read failed */
  217326. + if (hdmi->edid_status == HDMI_EDID_NO_MODES ||
  217327. + hdmi->edid_status == HDMI_EDID_FAIL) {
  217328. + dev_info(&hdmi->pdev->dev, "Read EDID again\n");
  217329. + hdmi->edid_status = mxc_hdmi_read_edid(hdmi);
  217330. + }
  217331. +
  217332. + /* HDMI Initialization Steps D, E, F */
  217333. + switch (hdmi->edid_status) {
  217334. + case HDMI_EDID_SUCCESS:
  217335. + mxc_hdmi_edid_rebuild_modelist(hdmi);
  217336. + break;
  217337. +
  217338. + /* Nothing to do if EDID same */
  217339. + case HDMI_EDID_SAME:
  217340. + break;
  217341. +
  217342. + case HDMI_EDID_FAIL:
  217343. + mxc_hdmi_default_edid_cfg(hdmi);
  217344. + /* No break here */
  217345. + case HDMI_EDID_NO_MODES:
  217346. + default:
  217347. + mxc_hdmi_default_modelist(hdmi);
  217348. + break;
  217349. + }
  217350. +
  217351. + /* Save edid cfg for audio driver */
  217352. + hdmi_set_edid_cfg(hdmi->edid_status, &hdmi->edid_cfg);
  217353. +
  217354. + /* Setting video mode */
  217355. + mxc_hdmi_set_mode(hdmi);
  217356. +
  217357. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  217358. +}
  217359. +
  217360. +static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp)
  217361. +{
  217362. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  217363. + mxc_hdmi_phy_init(hdmi);
  217364. + return 0;
  217365. +}
  217366. +
  217367. +static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)
  217368. +{
  217369. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  217370. + mxc_hdmi_phy_disable(hdmi);
  217371. +}
  217372. +
  217373. +static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
  217374. +{
  217375. + u8 clkdis;
  217376. +
  217377. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217378. +
  217379. + /* Save CEC clock */
  217380. + clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
  217381. + clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
  217382. +
  217383. + /* Disable All HDMI clock */
  217384. + hdmi_writeb(0xff & clkdis, HDMI_MC_CLKDIS);
  217385. +
  217386. + mxc_hdmi_phy_disable(hdmi);
  217387. +
  217388. + hdmi_disable_overflow_interrupts();
  217389. +
  217390. + hdmi->cable_plugin = false;
  217391. +}
  217392. +
  217393. +static void hotplug_worker(struct work_struct *work)
  217394. +{
  217395. + struct mxc_hdmi *hdmi =
  217396. + container_of(work, struct mxc_hdmi, hotplug_work);
  217397. + u32 hdmi_phy_stat0, hdmi_phy_pol0, hdmi_phy_mask0;
  217398. + unsigned long flags;
  217399. + char event_string[32];
  217400. + char *envp[] = { event_string, NULL };
  217401. +
  217402. + hdmi_phy_stat0 = hdmi_readb(HDMI_PHY_STAT0);
  217403. + hdmi_phy_pol0 = hdmi_readb(HDMI_PHY_POL0);
  217404. +
  217405. + if (hdmi->latest_intr_stat & hdmi->plug_event) {
  217406. + /* Make HPD intr active low to capture unplug event or
  217407. + * active high to capture plugin event */
  217408. + hdmi_writeb((hdmi->plug_mask & ~hdmi_phy_pol0), HDMI_PHY_POL0);
  217409. +
  217410. + /* check cable status */
  217411. + if (hdmi_phy_stat0 & hdmi->plug_mask) {
  217412. + /* Plugin event */
  217413. + dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n");
  217414. + mxc_hdmi_cable_connected(hdmi);
  217415. +
  217416. + sprintf(event_string, "EVENT=plugin");
  217417. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  217418. +#ifdef CONFIG_MXC_HDMI_CEC
  217419. + mxc_hdmi_cec_handle(0x80);
  217420. +#endif
  217421. + hdmi_set_cable_state(1);
  217422. + } else {
  217423. + /* Plugout event */
  217424. + dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
  217425. + hdmi_set_cable_state(0);
  217426. + mxc_hdmi_abort_stream();
  217427. + mxc_hdmi_cable_disconnected(hdmi);
  217428. +
  217429. + sprintf(event_string, "EVENT=plugout");
  217430. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  217431. +#ifdef CONFIG_MXC_HDMI_CEC
  217432. + mxc_hdmi_cec_handle(0x100);
  217433. +#endif
  217434. + }
  217435. + }
  217436. +
  217437. + /* Lock here to ensure full powerdown sequence
  217438. + * completed before next interrupt processed */
  217439. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  217440. +
  217441. + /* Re-enable HPD interrupts */
  217442. + hdmi_phy_mask0 = hdmi_readb(HDMI_PHY_MASK0);
  217443. + hdmi_phy_mask0 &= ~hdmi->plug_mask;
  217444. + hdmi_writeb(hdmi_phy_mask0, HDMI_PHY_MASK0);
  217445. +
  217446. + /* Unmute interrupts */
  217447. + hdmi_writeb(~hdmi->plug_event, HDMI_IH_MUTE_PHY_STAT0);
  217448. +
  217449. + if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)
  217450. + mxc_hdmi_clear_overflow(hdmi);
  217451. +
  217452. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  217453. +}
  217454. +
  217455. +static void hotplug_work_launch(unsigned long data)
  217456. +{
  217457. + struct mxc_hdmi *hdmi = (struct mxc_hdmi *)data;
  217458. + pr_debug("%s\n", __func__);
  217459. + schedule_work(&hdmi->hotplug_work);
  217460. +}
  217461. +
  217462. +static void hdcp_hdp_worker(struct work_struct *work)
  217463. +{
  217464. + struct delayed_work *delay_work = to_delayed_work(work);
  217465. + struct mxc_hdmi *hdmi =
  217466. + container_of(delay_work, struct mxc_hdmi, hdcp_hdp_work);
  217467. + char event_string[32];
  217468. + char *envp[] = { event_string, NULL };
  217469. +
  217470. + /* HDCP interrupt */
  217471. + sprintf(event_string, "EVENT=hdcpint");
  217472. + kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
  217473. +
  217474. + /* Unmute interrupts in HDCP application*/
  217475. +}
  217476. +
  217477. +static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
  217478. +{
  217479. + struct mxc_hdmi *hdmi = data;
  217480. + u8 val, intr_stat;
  217481. + unsigned long flags;
  217482. +
  217483. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  217484. +
  217485. + /* Check and clean packet overflow interrupt.*/
  217486. + if (hdmi_readb(HDMI_IH_FC_STAT2) &
  217487. + HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
  217488. + mxc_hdmi_clear_overflow(hdmi);
  217489. +
  217490. + dev_dbg(&hdmi->pdev->dev, "Overflow interrupt received\n");
  217491. + /* clear irq status */
  217492. + hdmi_writeb(HDMI_IH_FC_STAT2_OVERFLOW_MASK,
  217493. + HDMI_IH_FC_STAT2);
  217494. + }
  217495. +
  217496. + /*
  217497. + * We could not disable the irq. Probably the audio driver
  217498. + * has enabled it. Masking off the HDMI interrupts using
  217499. + * HDMI registers.
  217500. + */
  217501. + /* Capture status - used in hotplug_worker ISR */
  217502. + intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0);
  217503. + if (intr_stat & hdmi->plug_event) {
  217504. +
  217505. + dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
  217506. + dev_dbg(&hdmi->pdev->dev, "intr_stat %u plug_event %u\n", intr_stat, hdmi->plug_event);
  217507. + hdmi->latest_intr_stat = intr_stat;
  217508. +
  217509. + /* Mute interrupts until handled */
  217510. +
  217511. + val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
  217512. + val |= hdmi->plug_event;
  217513. + hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
  217514. +
  217515. + val = hdmi_readb(HDMI_PHY_MASK0);
  217516. + val |= hdmi->plug_mask;
  217517. + hdmi_writeb(val, HDMI_PHY_MASK0);
  217518. +
  217519. + /* Clear Hotplug interrupts */
  217520. + hdmi_writeb(hdmi->plug_event, HDMI_IH_PHY_STAT0);
  217521. +
  217522. + if(hdmi_inited) {
  217523. + mod_timer(&hdmi->jitter_timer, jiffies + HZ);
  217524. + }
  217525. + }
  217526. +
  217527. + /* Check HDCP interrupt state */
  217528. + if (hdmi->hdmi_data.hdcp_enable) {
  217529. + val = hdmi_readb(HDMI_A_APIINTSTAT);
  217530. + if (val != 0) {
  217531. + /* Mute interrupts until interrupt handled */
  217532. + val = 0xFF;
  217533. + hdmi_writeb(val, HDMI_A_APIINTMSK);
  217534. + schedule_delayed_work(&(hdmi->hdcp_hdp_work), msecs_to_jiffies(50));
  217535. + }
  217536. + }
  217537. +
  217538. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  217539. + return IRQ_HANDLED;
  217540. +}
  217541. +
  217542. +static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event)
  217543. +{
  217544. + struct fb_videomode m;
  217545. + const struct fb_videomode *edid_mode;
  217546. +
  217547. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217548. +
  217549. + fb_var_to_videomode(&m, &hdmi->fbi->var);
  217550. + dump_fb_videomode(&m);
  217551. +
  217552. + dev_dbg(&hdmi->pdev->dev, "%s - video mode changed\n", __func__);
  217553. +
  217554. + hdmi->vic = 0;
  217555. + if (!hdmi->requesting_vga_for_initialization) {
  217556. + /* Save mode if this isn't the result of requesting
  217557. + * vga default. */
  217558. + memcpy(&hdmi->previous_non_vga_mode, &m,
  217559. + sizeof(struct fb_videomode));
  217560. + if (!list_empty(&hdmi->fbi->modelist)) {
  217561. + edid_mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  217562. + pr_debug("edid mode ");
  217563. + dump_fb_videomode((struct fb_videomode *)edid_mode);
  217564. + /* update fbi mode */
  217565. + hdmi->fbi->mode = (struct fb_videomode *)edid_mode;
  217566. + hdmi->vic = mxc_edid_mode_to_vic(edid_mode);
  217567. + }
  217568. + }
  217569. +
  217570. + hdmi_disable_overflow_interrupts();
  217571. +
  217572. + dev_dbg(&hdmi->pdev->dev, "CEA mode used vic=%d\n", hdmi->vic);
  217573. + if (hdmi->edid_cfg.hdmi_cap || !hdmi->edid_status) {
  217574. + hdmi_set_dvi_mode(0);
  217575. + hdmi->hdmi_data.video_mode.mDVI = false;
  217576. + } else {
  217577. + hdmi_set_dvi_mode(1);
  217578. + dev_dbg(&hdmi->pdev->dev, "CEA mode vic=%d work in DVI\n", hdmi->vic);
  217579. + hdmi->hdmi_data.video_mode.mDVI = true;
  217580. + }
  217581. +
  217582. + if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
  217583. + (hdmi->vic == 21) || (hdmi->vic == 22) ||
  217584. + (hdmi->vic == 2) || (hdmi->vic == 3) ||
  217585. + (hdmi->vic == 17) || (hdmi->vic == 18))
  217586. + hdmi->hdmi_data.colorimetry = eITU601;
  217587. + else
  217588. + hdmi->hdmi_data.colorimetry = eITU709;
  217589. +
  217590. + if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
  217591. + (hdmi->vic == 12) || (hdmi->vic == 13) ||
  217592. + (hdmi->vic == 14) || (hdmi->vic == 15) ||
  217593. + (hdmi->vic == 25) || (hdmi->vic == 26) ||
  217594. + (hdmi->vic == 27) || (hdmi->vic == 28) ||
  217595. + (hdmi->vic == 29) || (hdmi->vic == 30) ||
  217596. + (hdmi->vic == 35) || (hdmi->vic == 36) ||
  217597. + (hdmi->vic == 37) || (hdmi->vic == 38))
  217598. + hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 1;
  217599. + else
  217600. + hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 0;
  217601. +
  217602. + hdmi->hdmi_data.video_mode.mPixelRepetitionInput = 0;
  217603. +
  217604. + /* TODO: Get input format from IPU (via FB driver iface) */
  217605. + hdmi->hdmi_data.enc_in_format = RGB;
  217606. +
  217607. + hdmi->hdmi_data.enc_out_format = RGB;
  217608. +
  217609. + /* YCbCr only enabled in HDMI mode */
  217610. + if (!hdmi->hdmi_data.video_mode.mDVI &&
  217611. + !hdmi->hdmi_data.rgb_out_enable) {
  217612. + if (hdmi->edid_cfg.cea_ycbcr444)
  217613. + hdmi->hdmi_data.enc_out_format = YCBCR444;
  217614. + else if (hdmi->edid_cfg.cea_ycbcr422)
  217615. + hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS;
  217616. + }
  217617. +
  217618. + /* IPU not support depth color output */
  217619. + hdmi->hdmi_data.enc_color_depth = 8;
  217620. + hdmi->hdmi_data.pix_repet_factor = 0;
  217621. + hdmi->hdmi_data.video_mode.mDataEnablePolarity = true;
  217622. +
  217623. + /* HDMI Initialization Step B.1 */
  217624. + hdmi_av_composer(hdmi);
  217625. +
  217626. + /* HDMI Initializateion Step B.2 */
  217627. + mxc_hdmi_phy_init(hdmi);
  217628. +
  217629. + /* HDMI Initialization Step B.3 */
  217630. + mxc_hdmi_enable_video_path(hdmi);
  217631. +
  217632. + /* not for DVI mode */
  217633. + if (hdmi->hdmi_data.video_mode.mDVI)
  217634. + dev_dbg(&hdmi->pdev->dev, "%s DVI mode\n", __func__);
  217635. + else {
  217636. + dev_dbg(&hdmi->pdev->dev, "%s CEA mode\n", __func__);
  217637. +
  217638. + /* HDMI Initialization Step E - Configure audio */
  217639. + hdmi_clk_regenerator_update_pixel_clock(hdmi->fbi->var.pixclock);
  217640. + hdmi_enable_audio_clk(hdmi);
  217641. +
  217642. + /* HDMI Initialization Step F - Configure AVI InfoFrame */
  217643. + hdmi_config_AVI(hdmi);
  217644. + }
  217645. +
  217646. + hdmi_video_packetize(hdmi);
  217647. + hdmi_video_csc(hdmi);
  217648. + hdmi_video_sample(hdmi);
  217649. +
  217650. + mxc_hdmi_clear_overflow(hdmi);
  217651. +
  217652. + dev_dbg(&hdmi->pdev->dev, "%s exit\n\n", __func__);
  217653. +
  217654. +}
  217655. +
  217656. +/* Wait until we are registered to enable interrupts */
  217657. +static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi)
  217658. +{
  217659. + unsigned long flags;
  217660. +
  217661. + if (hdmi->fb_reg)
  217662. + return;
  217663. +
  217664. + spin_lock_irqsave(&hdmi->irq_lock, flags);
  217665. +
  217666. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217667. +
  217668. + hdmi_writeb(HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
  217669. + HDMI_PHY_I2CM_INT_ADDR);
  217670. +
  217671. + hdmi_writeb(HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
  217672. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
  217673. + HDMI_PHY_I2CM_CTLINT_ADDR);
  217674. +
  217675. + /* enable cable hot plug irq */
  217676. + hdmi_writeb(~hdmi->plug_mask, HDMI_PHY_MASK0);
  217677. +
  217678. + /* Clear Hotplug interrupts */
  217679. + hdmi_writeb(hdmi->plug_event, HDMI_IH_PHY_STAT0);
  217680. +
  217681. + /* Unmute interrupts */
  217682. + hdmi_writeb(~hdmi->plug_event, HDMI_IH_MUTE_PHY_STAT0);
  217683. +
  217684. + hdmi->fb_reg = true;
  217685. +
  217686. + spin_unlock_irqrestore(&hdmi->irq_lock, flags);
  217687. +
  217688. +}
  217689. +
  217690. +static int mxc_hdmi_fb_event(struct notifier_block *nb,
  217691. + unsigned long val, void *v)
  217692. +{
  217693. + struct fb_event *event = v;
  217694. + struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
  217695. +
  217696. + if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
  217697. + return 0;
  217698. +
  217699. + switch (val) {
  217700. + case FB_EVENT_FB_REGISTERED:
  217701. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_REGISTERED\n");
  217702. + mxc_hdmi_fb_registered(hdmi);
  217703. + hdmi_set_registered(1);
  217704. + break;
  217705. +
  217706. + case FB_EVENT_FB_UNREGISTERED:
  217707. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_UNREGISTERED\n");
  217708. + hdmi->fb_reg = false;
  217709. + hdmi_set_registered(0);
  217710. + break;
  217711. +
  217712. + case FB_EVENT_MODE_CHANGE:
  217713. + dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_MODE_CHANGE\n");
  217714. + if (hdmi->fb_reg)
  217715. + mxc_hdmi_setup(hdmi, val);
  217716. + break;
  217717. +
  217718. + case FB_EVENT_BLANK:
  217719. + if ((*((int *)event->data) == FB_BLANK_UNBLANK) &&
  217720. + (*((int *)event->data) != hdmi->blank)) {
  217721. + dev_dbg(&hdmi->pdev->dev,
  217722. + "event=FB_EVENT_BLANK - UNBLANK\n");
  217723. +
  217724. + hdmi->blank = *((int *)event->data);
  217725. +
  217726. + /* Re-enable HPD interrupts */
  217727. + val = hdmi_readb(HDMI_PHY_MASK0);
  217728. + val &= ~hdmi->plug_mask;
  217729. + hdmi_writeb(val, HDMI_PHY_MASK0);
  217730. +
  217731. + /* Unmute interrupts */
  217732. + hdmi_writeb(~hdmi->plug_event, HDMI_IH_MUTE_PHY_STAT0);
  217733. +
  217734. + if (hdmi->fb_reg && hdmi->cable_plugin)
  217735. + mxc_hdmi_setup(hdmi, val);
  217736. + hdmi_set_blank_state(1);
  217737. + } else if (*((int *)event->data) != hdmi->blank) {
  217738. + dev_dbg(&hdmi->pdev->dev,
  217739. + "event=FB_EVENT_BLANK - BLANK\n");
  217740. + hdmi_set_blank_state(0);
  217741. + mxc_hdmi_abort_stream();
  217742. +
  217743. + mxc_hdmi_phy_disable(hdmi);
  217744. +
  217745. + if(hdmi->plug_mask == HDMI_DVI_STAT) {
  217746. + u8 val;
  217747. + pr_info("In DVI Mode disable interrupts\n");
  217748. + val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
  217749. + val |= hdmi->plug_event;
  217750. + hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
  217751. +
  217752. + val = hdmi_readb(HDMI_PHY_MASK0);
  217753. + val |= hdmi->plug_mask;
  217754. + hdmi_writeb(val, HDMI_PHY_MASK0);
  217755. +
  217756. + hdmi_set_dvi_mode(1);
  217757. + }
  217758. +
  217759. + hdmi->blank = *((int *)event->data);
  217760. + } else
  217761. + dev_dbg(&hdmi->pdev->dev,
  217762. + "FB BLANK state no changed!\n");
  217763. +
  217764. + break;
  217765. +
  217766. + case FB_EVENT_SUSPEND:
  217767. + dev_dbg(&hdmi->pdev->dev,
  217768. + "event=FB_EVENT_SUSPEND\n");
  217769. +
  217770. + if (hdmi->blank == FB_BLANK_UNBLANK) {
  217771. + mxc_hdmi_phy_disable(hdmi);
  217772. + clk_disable(hdmi->hdmi_iahb_clk);
  217773. + clk_disable(hdmi->hdmi_isfr_clk);
  217774. + }
  217775. + break;
  217776. +
  217777. + case FB_EVENT_RESUME:
  217778. + dev_dbg(&hdmi->pdev->dev,
  217779. + "event=FB_EVENT_RESUME\n");
  217780. +
  217781. + if (hdmi->blank == FB_BLANK_UNBLANK) {
  217782. + clk_enable(hdmi->hdmi_iahb_clk);
  217783. + clk_enable(hdmi->hdmi_isfr_clk);
  217784. + mxc_hdmi_phy_init(hdmi);
  217785. + }
  217786. + break;
  217787. +
  217788. + }
  217789. + return 0;
  217790. +}
  217791. +
  217792. +static void hdmi_init_route(struct mxc_hdmi *hdmi)
  217793. +{
  217794. + uint32_t hdmi_mux_setting, reg;
  217795. + int ipu_id, disp_id;
  217796. +
  217797. + ipu_id = mxc_hdmi_ipu_id;
  217798. + disp_id = mxc_hdmi_disp_id;
  217799. +
  217800. + if ((ipu_id > 1) || (ipu_id < 0)) {
  217801. + pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
  217802. + ipu_id = 0;
  217803. + }
  217804. +
  217805. + if ((disp_id > 1) || (disp_id < 0)) {
  217806. + pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
  217807. + disp_id = 0;
  217808. + }
  217809. +
  217810. + reg = readl(hdmi->gpr_hdmi_base);
  217811. +
  217812. + /* Configure the connection between IPU1/2 and HDMI */
  217813. + hdmi_mux_setting = 2*ipu_id + disp_id;
  217814. +
  217815. + /* GPR3, bits 2-3 = HDMI_MUX_CTL */
  217816. + reg &= ~0xd;
  217817. + reg |= hdmi_mux_setting << 2;
  217818. +
  217819. + writel(reg, hdmi->gpr_hdmi_base);
  217820. +
  217821. + /* Set HDMI event as SDMA event2 for HDMI audio */
  217822. + reg = readl(hdmi->gpr_sdma_base);
  217823. + reg |= 0x1;
  217824. + writel(reg, hdmi->gpr_sdma_base);
  217825. +}
  217826. +
  217827. +static void hdmi_hdcp_get_property(struct platform_device *pdev)
  217828. +{
  217829. + struct device_node *np = pdev->dev.of_node;
  217830. +
  217831. + /* Check hdcp enable by dts.*/
  217832. + hdcp_init = of_property_read_bool(np, "fsl,hdcp");
  217833. + if (hdcp_init)
  217834. + dev_dbg(&pdev->dev, "hdcp enable\n");
  217835. + else
  217836. + dev_dbg(&pdev->dev, "hdcp disable\n");
  217837. +}
  217838. +
  217839. +static void hdmi_get_of_property(struct mxc_hdmi *hdmi)
  217840. +{
  217841. + struct platform_device *pdev = hdmi->pdev;
  217842. + struct device_node *np = pdev->dev.of_node;
  217843. + const struct of_device_id *of_id =
  217844. + of_match_device(imx_hdmi_dt_ids, &pdev->dev);
  217845. + int ret;
  217846. + u32 phy_reg_vlev = 0, phy_reg_cksymtx = 0;
  217847. +
  217848. + if (of_id) {
  217849. + pdev->id_entry = of_id->data;
  217850. + hdmi->cpu_type = pdev->id_entry->driver_data;
  217851. + }
  217852. +
  217853. + /* HDMI PHY register vlev and cksymtx preperty is optional.
  217854. + * It is for specific board to pass HCT electrical part.
  217855. + * Default value will been setting in HDMI PHY config function
  217856. + * if it is not define in device tree.
  217857. + */
  217858. + ret = of_property_read_u32(np, "fsl,phy_reg_vlev", &phy_reg_vlev);
  217859. + if (ret)
  217860. + dev_dbg(&pdev->dev, "No board specific HDMI PHY vlev\n");
  217861. +
  217862. + ret = of_property_read_u32(np, "fsl,phy_reg_cksymtx", &phy_reg_cksymtx);
  217863. + if (ret)
  217864. + dev_dbg(&pdev->dev, "No board specific HDMI PHY cksymtx\n");
  217865. +
  217866. + /* Specific phy config */
  217867. + hdmi->phy_config.reg_cksymtx = phy_reg_cksymtx;
  217868. + hdmi->phy_config.reg_vlev = phy_reg_vlev;
  217869. +
  217870. +}
  217871. +
  217872. +/* HDMI Initialization Step A */
  217873. +static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
  217874. + struct mxc_dispdrv_setting *setting)
  217875. +{
  217876. + int ret = 0;
  217877. + u32 i;
  217878. + const struct fb_videomode *mode;
  217879. + struct fb_videomode m;
  217880. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  217881. + int irq = platform_get_irq(hdmi->pdev, 0);
  217882. +
  217883. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  217884. +
  217885. + /* Check hdmi disp init once */
  217886. + if (hdmi_inited) {
  217887. + dev_err(&hdmi->pdev->dev,
  217888. + "Error only one HDMI output support now!\n");
  217889. + return -1;
  217890. + }
  217891. +
  217892. + hdmi_get_of_property(hdmi);
  217893. +
  217894. + if (irq < 0)
  217895. + return -ENODEV;
  217896. +
  217897. + /* Setting HDMI default to blank state */
  217898. + hdmi->blank = FB_BLANK_POWERDOWN;
  217899. +
  217900. + setting->dev_id = mxc_hdmi_ipu_id;
  217901. + setting->disp_id = mxc_hdmi_disp_id;
  217902. + setting->if_fmt = IPU_PIX_FMT_RGB24;
  217903. +
  217904. + hdmi->dft_mode_str = setting->dft_mode_str;
  217905. + hdmi->default_bpp = setting->default_bpp;
  217906. + dev_dbg(&hdmi->pdev->dev, "%s - default mode %s bpp=%d\n",
  217907. + __func__, hdmi->dft_mode_str, hdmi->default_bpp);
  217908. +
  217909. + hdmi->fbi = setting->fbi;
  217910. +
  217911. + hdmi_init_route(hdmi);
  217912. +
  217913. + hdmi->hdmi_isfr_clk = clk_get(&hdmi->pdev->dev, "hdmi_isfr");
  217914. + if (IS_ERR(hdmi->hdmi_isfr_clk)) {
  217915. + ret = PTR_ERR(hdmi->hdmi_isfr_clk);
  217916. + dev_err(&hdmi->pdev->dev,
  217917. + "Unable to get HDMI clk: %d\n", ret);
  217918. + goto egetclk1;
  217919. + }
  217920. +
  217921. + ret = clk_prepare_enable(hdmi->hdmi_isfr_clk);
  217922. + if (ret < 0) {
  217923. + dev_err(&hdmi->pdev->dev,
  217924. + "Cannot enable HDMI isfr clock: %d\n", ret);
  217925. + goto erate1;
  217926. + }
  217927. +
  217928. + hdmi->hdmi_iahb_clk = clk_get(&hdmi->pdev->dev, "hdmi_iahb");
  217929. + if (IS_ERR(hdmi->hdmi_iahb_clk)) {
  217930. + ret = PTR_ERR(hdmi->hdmi_iahb_clk);
  217931. + dev_err(&hdmi->pdev->dev,
  217932. + "Unable to get HDMI clk: %d\n", ret);
  217933. + goto egetclk2;
  217934. + }
  217935. +
  217936. + ret = clk_prepare_enable(hdmi->hdmi_iahb_clk);
  217937. + if (ret < 0) {
  217938. + dev_err(&hdmi->pdev->dev,
  217939. + "Cannot enable HDMI iahb clock: %d\n", ret);
  217940. + goto erate2;
  217941. + }
  217942. +
  217943. + dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n");
  217944. +
  217945. + /* Init DDC pins for HDCP */
  217946. + if (hdcp_init) {
  217947. + hdmi->pinctrl = devm_pinctrl_get_select_default(&hdmi->pdev->dev);
  217948. + if (IS_ERR(hdmi->pinctrl)) {
  217949. + dev_err(&hdmi->pdev->dev, "can't get/select DDC pinctrl\n");
  217950. + goto erate2;
  217951. + }
  217952. + }
  217953. +
  217954. + /* Product and revision IDs */
  217955. + dev_info(&hdmi->pdev->dev,
  217956. + "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
  217957. + hdmi_readb(HDMI_DESIGN_ID),
  217958. + hdmi_readb(HDMI_REVISION_ID),
  217959. + hdmi_readb(HDMI_PRODUCT_ID0),
  217960. + hdmi_readb(HDMI_PRODUCT_ID1));
  217961. +
  217962. + /* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
  217963. + * N and cts values before enabling phy */
  217964. + hdmi_init_clk_regenerator();
  217965. +
  217966. + INIT_LIST_HEAD(&hdmi->fbi->modelist);
  217967. +
  217968. + spin_lock_init(&hdmi->irq_lock);
  217969. +
  217970. + /* Set the default mode and modelist when disp init. */
  217971. + fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
  217972. + hdmi->dft_mode_str, NULL, 0, NULL,
  217973. + hdmi->default_bpp);
  217974. +
  217975. + console_lock();
  217976. +
  217977. + fb_destroy_modelist(&hdmi->fbi->modelist);
  217978. +
  217979. + /*Add all no interlaced CEA mode to default modelist */
  217980. + for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
  217981. + mode = &mxc_cea_mode[i];
  217982. + if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
  217983. + fb_add_videomode(mode, &hdmi->fbi->modelist);
  217984. + }
  217985. +
  217986. + console_unlock();
  217987. +
  217988. + /* Find a nearest mode in default modelist */
  217989. + fb_var_to_videomode(&m, &hdmi->fbi->var);
  217990. + dump_fb_videomode(&m);
  217991. +
  217992. + hdmi->dft_mode_set = false;
  217993. + /* Save default video mode */
  217994. + memcpy(&hdmi->default_mode, &m, sizeof(struct fb_videomode));
  217995. +
  217996. + mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
  217997. + if (!mode) {
  217998. + pr_err("%s: could not find mode in modelist\n", __func__);
  217999. + return -1;
  218000. + }
  218001. +
  218002. + fb_videomode_to_var(&hdmi->fbi->var, mode);
  218003. +
  218004. + /* update fbi mode */
  218005. + hdmi->fbi->mode = (struct fb_videomode *)mode;
  218006. +
  218007. + /* Default setting HDMI working in HDMI mode*/
  218008. + hdmi->edid_cfg.hdmi_cap = true;
  218009. +
  218010. + hdmi->plug_event = HDMI_DVI_IH_STAT;
  218011. + hdmi->plug_mask = HDMI_DVI_STAT;
  218012. +
  218013. + setup_timer(&hdmi->jitter_timer, hotplug_work_launch, (unsigned long)hdmi);
  218014. + INIT_WORK(&hdmi->hotplug_work, hotplug_worker);
  218015. + INIT_DELAYED_WORK(&hdmi->hdcp_hdp_work, hdcp_hdp_worker);
  218016. +
  218017. + /* Configure registers related to HDMI interrupt
  218018. + * generation before registering IRQ. */
  218019. + hdmi_writeb(hdmi->plug_mask, HDMI_PHY_POL0);
  218020. +
  218021. + /* Clear Hotplug interrupts */
  218022. + hdmi_writeb(hdmi->plug_event, HDMI_IH_PHY_STAT0);
  218023. +
  218024. + hdmi->nb.notifier_call = mxc_hdmi_fb_event;
  218025. + ret = fb_register_client(&hdmi->nb);
  218026. + if (ret < 0)
  218027. + goto efbclient;
  218028. +
  218029. + memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info));
  218030. +
  218031. + /* Default HDMI working in RGB mode */
  218032. + hdmi->hdmi_data.rgb_out_enable = true;
  218033. +
  218034. + if (!strcasecmp(rgb_quant_range, "limited")) {
  218035. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE;
  218036. + } else if (!strcasecmp(rgb_quant_range, "full")) {
  218037. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE;
  218038. + } else {
  218039. + hdmi->hdmi_data.rgb_quant_range = HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT;
  218040. + }
  218041. +
  218042. + ret = devm_request_irq(&hdmi->pdev->dev, irq, mxc_hdmi_hotplug, IRQF_SHARED,
  218043. + dev_name(&hdmi->pdev->dev), hdmi);
  218044. + if (ret < 0) {
  218045. + dev_err(&hdmi->pdev->dev,
  218046. + "Unable to request irq: %d\n", ret);
  218047. + goto ereqirq;
  218048. + }
  218049. +
  218050. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_fb_name);
  218051. + if (ret < 0)
  218052. + dev_warn(&hdmi->pdev->dev,
  218053. + "cound not create sys node for fb name\n");
  218054. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_cable_state);
  218055. + if (ret < 0)
  218056. + dev_warn(&hdmi->pdev->dev,
  218057. + "cound not create sys node for cable state\n");
  218058. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_edid);
  218059. + if (ret < 0)
  218060. + dev_warn(&hdmi->pdev->dev,
  218061. + "cound not create sys node for edid\n");
  218062. +
  218063. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_out_enable);
  218064. + if (ret < 0)
  218065. + dev_warn(&hdmi->pdev->dev,
  218066. + "cound not create sys node for rgb out enable\n");
  218067. +
  218068. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_quant_range);
  218069. + if (ret < 0)
  218070. + dev_warn(&hdmi->pdev->dev,
  218071. + "cound not create sys node for rgb quant range\n");
  218072. +
  218073. + ret = device_create_file(&hdmi->pdev->dev, &dev_attr_hdcp_enable);
  218074. + if (ret < 0)
  218075. + dev_warn(&hdmi->pdev->dev,
  218076. + "cound not create sys node for hdcp enable\n");
  218077. +
  218078. + dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
  218079. +
  218080. + hdmi_inited = true;
  218081. +
  218082. + return ret;
  218083. +
  218084. +efbclient:
  218085. + free_irq(irq, hdmi);
  218086. +ereqirq:
  218087. + clk_disable_unprepare(hdmi->hdmi_iahb_clk);
  218088. +erate2:
  218089. + clk_put(hdmi->hdmi_iahb_clk);
  218090. +egetclk2:
  218091. + clk_disable_unprepare(hdmi->hdmi_isfr_clk);
  218092. +erate1:
  218093. + clk_put(hdmi->hdmi_isfr_clk);
  218094. +egetclk1:
  218095. + dev_dbg(&hdmi->pdev->dev, "%s error exit\n", __func__);
  218096. +
  218097. + return ret;
  218098. +}
  218099. +
  218100. +static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_handle *disp)
  218101. +{
  218102. + struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
  218103. +
  218104. + dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
  218105. +
  218106. + fb_unregister_client(&hdmi->nb);
  218107. +
  218108. + clk_disable_unprepare(hdmi->hdmi_isfr_clk);
  218109. + clk_put(hdmi->hdmi_isfr_clk);
  218110. + clk_disable_unprepare(hdmi->hdmi_iahb_clk);
  218111. + clk_put(hdmi->hdmi_iahb_clk);
  218112. +
  218113. + platform_device_unregister(hdmi->pdev);
  218114. +
  218115. + hdmi_inited = false;
  218116. +}
  218117. +
  218118. +static struct mxc_dispdrv_driver mxc_hdmi_drv = {
  218119. + .name = DISPDRV_HDMI,
  218120. + .init = mxc_hdmi_disp_init,
  218121. + .deinit = mxc_hdmi_disp_deinit,
  218122. + .enable = mxc_hdmi_power_on,
  218123. + .disable = mxc_hdmi_power_off,
  218124. +};
  218125. +
  218126. +
  218127. +static int mxc_hdmi_open(struct inode *inode, struct file *file)
  218128. +{
  218129. + return 0;
  218130. +}
  218131. +
  218132. +static long mxc_hdmi_ioctl(struct file *file,
  218133. + unsigned int cmd, unsigned long arg)
  218134. +{
  218135. + int __user *argp = (void __user *)arg;
  218136. + int ret = 0;
  218137. +
  218138. + switch (cmd) {
  218139. + case HDMI_IOC_GET_RESOURCE:
  218140. + ret = copy_to_user(argp, &g_hdmi->hdmi_data,
  218141. + sizeof(g_hdmi->hdmi_data)) ? -EFAULT : 0;
  218142. + break;
  218143. + case HDMI_IOC_GET_CPU_TYPE:
  218144. + *argp = g_hdmi->cpu_type;
  218145. + break;
  218146. + default:
  218147. + pr_debug("Unsupport cmd %d\n", cmd);
  218148. + break;
  218149. + }
  218150. + return ret;
  218151. +}
  218152. +
  218153. +static int mxc_hdmi_release(struct inode *inode, struct file *file)
  218154. +{
  218155. + return 0;
  218156. +}
  218157. +
  218158. +static const struct file_operations mxc_hdmi_fops = {
  218159. + .owner = THIS_MODULE,
  218160. + .open = mxc_hdmi_open,
  218161. + .release = mxc_hdmi_release,
  218162. + .unlocked_ioctl = mxc_hdmi_ioctl,
  218163. +};
  218164. +
  218165. +
  218166. +static int mxc_hdmi_probe(struct platform_device *pdev)
  218167. +{
  218168. + struct mxc_hdmi *hdmi;
  218169. + struct device *temp_class;
  218170. + struct resource *res;
  218171. + int ret = 0;
  218172. +
  218173. + /* Check I2C driver is loaded and available
  218174. + * check hdcp function is enable by dts */
  218175. + hdmi_hdcp_get_property(pdev);
  218176. + if (!hdmi_i2c && !hdcp_init)
  218177. + return -ENODEV;
  218178. +
  218179. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  218180. + if (!res)
  218181. + return -ENOENT;
  218182. +
  218183. + hdmi = devm_kzalloc(&pdev->dev,
  218184. + sizeof(struct mxc_hdmi),
  218185. + GFP_KERNEL);
  218186. + if (!hdmi) {
  218187. + dev_err(&pdev->dev, "Cannot allocate device data\n");
  218188. + ret = -ENOMEM;
  218189. + goto ealloc;
  218190. + }
  218191. + g_hdmi = hdmi;
  218192. +
  218193. + hdmi_major = register_chrdev(hdmi_major, "mxc_hdmi", &mxc_hdmi_fops);
  218194. + if (hdmi_major < 0) {
  218195. + printk(KERN_ERR "HDMI: unable to get a major for HDMI\n");
  218196. + ret = -EBUSY;
  218197. + goto ealloc;
  218198. + }
  218199. +
  218200. + hdmi_class = class_create(THIS_MODULE, "mxc_hdmi");
  218201. + if (IS_ERR(hdmi_class)) {
  218202. + ret = PTR_ERR(hdmi_class);
  218203. + goto err_out_chrdev;
  218204. + }
  218205. +
  218206. + temp_class = device_create(hdmi_class, NULL, MKDEV(hdmi_major, 0),
  218207. + NULL, "mxc_hdmi");
  218208. + if (IS_ERR(temp_class)) {
  218209. + ret = PTR_ERR(temp_class);
  218210. + goto err_out_class;
  218211. + }
  218212. +
  218213. + hdmi->pdev = pdev;
  218214. +
  218215. + hdmi->core_pdev = platform_device_alloc("mxc_hdmi_core", -1);
  218216. + if (!hdmi->core_pdev) {
  218217. + pr_err("%s failed platform_device_alloc for hdmi core\n",
  218218. + __func__);
  218219. + ret = -ENOMEM;
  218220. + goto ecore;
  218221. + }
  218222. +
  218223. + hdmi->gpr_base = ioremap(res->start, resource_size(res));
  218224. + if (!hdmi->gpr_base) {
  218225. + dev_err(&pdev->dev, "ioremap failed\n");
  218226. + ret = -ENOMEM;
  218227. + goto eiomap;
  218228. + }
  218229. +
  218230. + hdmi->gpr_hdmi_base = hdmi->gpr_base + 3;
  218231. + hdmi->gpr_sdma_base = hdmi->gpr_base;
  218232. +
  218233. + hdmi_inited = false;
  218234. +
  218235. + hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv);
  218236. + if (IS_ERR(hdmi->disp_mxc_hdmi)) {
  218237. + dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n",
  218238. + (int)hdmi->disp_mxc_hdmi);
  218239. + ret = (int)hdmi->disp_mxc_hdmi;
  218240. + goto edispdrv;
  218241. + }
  218242. + mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi);
  218243. +
  218244. + platform_set_drvdata(pdev, hdmi);
  218245. +
  218246. + return 0;
  218247. +edispdrv:
  218248. + iounmap(hdmi->gpr_base);
  218249. +eiomap:
  218250. + platform_device_put(hdmi->core_pdev);
  218251. +ecore:
  218252. + kfree(hdmi);
  218253. +err_out_class:
  218254. + device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
  218255. + class_destroy(hdmi_class);
  218256. +err_out_chrdev:
  218257. + unregister_chrdev(hdmi_major, "mxc_hdmi");
  218258. +ealloc:
  218259. + return ret;
  218260. +}
  218261. +
  218262. +static int mxc_hdmi_remove(struct platform_device *pdev)
  218263. +{
  218264. + struct mxc_hdmi *hdmi = platform_get_drvdata(pdev);
  218265. + int irq = platform_get_irq(pdev, 0);
  218266. +
  218267. + fb_unregister_client(&hdmi->nb);
  218268. +
  218269. + mxc_dispdrv_puthandle(hdmi->disp_mxc_hdmi);
  218270. + mxc_dispdrv_unregister(hdmi->disp_mxc_hdmi);
  218271. + iounmap(hdmi->gpr_base);
  218272. + /* No new work will be scheduled, wait for running ISR */
  218273. + free_irq(irq, hdmi);
  218274. + kfree(hdmi);
  218275. + g_hdmi = NULL;
  218276. +
  218277. + return 0;
  218278. +}
  218279. +
  218280. +static struct platform_driver mxc_hdmi_driver = {
  218281. + .probe = mxc_hdmi_probe,
  218282. + .remove = mxc_hdmi_remove,
  218283. + .driver = {
  218284. + .name = "mxc_hdmi",
  218285. + .of_match_table = imx_hdmi_dt_ids,
  218286. + .owner = THIS_MODULE,
  218287. + },
  218288. +};
  218289. +
  218290. +static int __init mxc_hdmi_init(void)
  218291. +{
  218292. + return platform_driver_register(&mxc_hdmi_driver);
  218293. +}
  218294. +module_init(mxc_hdmi_init);
  218295. +
  218296. +static void __exit mxc_hdmi_exit(void)
  218297. +{
  218298. + if (hdmi_major > 0) {
  218299. + device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
  218300. + class_destroy(hdmi_class);
  218301. + unregister_chrdev(hdmi_major, "mxc_hdmi");
  218302. + hdmi_major = 0;
  218303. + }
  218304. +
  218305. + platform_driver_unregister(&mxc_hdmi_driver);
  218306. +}
  218307. +module_exit(mxc_hdmi_exit);
  218308. +
  218309. +static int mxc_hdmi_i2c_probe(struct i2c_client *client,
  218310. + const struct i2c_device_id *id)
  218311. +{
  218312. + if (!i2c_check_functionality(client->adapter,
  218313. + I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
  218314. + return -ENODEV;
  218315. +
  218316. + hdmi_i2c = client;
  218317. +
  218318. + return 0;
  218319. +}
  218320. +
  218321. +static int mxc_hdmi_i2c_remove(struct i2c_client *client)
  218322. +{
  218323. + hdmi_i2c = NULL;
  218324. + return 0;
  218325. +}
  218326. +
  218327. +static const struct of_device_id imx_hdmi_i2c_match[] = {
  218328. + { .compatible = "fsl,imx6-hdmi-i2c", },
  218329. + { /* sentinel */ }
  218330. +};
  218331. +
  218332. +static const struct i2c_device_id mxc_hdmi_i2c_id[] = {
  218333. + { "mxc_hdmi_i2c", 0 },
  218334. + {},
  218335. +};
  218336. +MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id);
  218337. +
  218338. +static struct i2c_driver mxc_hdmi_i2c_driver = {
  218339. + .driver = {
  218340. + .name = "mxc_hdmi_i2c",
  218341. + .of_match_table = imx_hdmi_i2c_match,
  218342. + },
  218343. + .probe = mxc_hdmi_i2c_probe,
  218344. + .remove = mxc_hdmi_i2c_remove,
  218345. + .id_table = mxc_hdmi_i2c_id,
  218346. +};
  218347. +
  218348. +static int __init mxc_hdmi_i2c_init(void)
  218349. +{
  218350. + return i2c_add_driver(&mxc_hdmi_i2c_driver);
  218351. +}
  218352. +
  218353. +static void __exit mxc_hdmi_i2c_exit(void)
  218354. +{
  218355. + i2c_del_driver(&mxc_hdmi_i2c_driver);
  218356. +}
  218357. +
  218358. +module_init(mxc_hdmi_i2c_init);
  218359. +module_exit(mxc_hdmi_i2c_exit);
  218360. +
  218361. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  218362. diff -Nur linux-3.14.17/drivers/video/mxc/mxc_ipuv3_fb.c linux-imx6-3.14/drivers/video/mxc/mxc_ipuv3_fb.c
  218363. --- linux-3.14.17/drivers/video/mxc/mxc_ipuv3_fb.c 1970-01-01 01:00:00.000000000 +0100
  218364. +++ linux-imx6-3.14/drivers/video/mxc/mxc_ipuv3_fb.c 2014-09-11 18:06:09.534068054 +0200
  218365. @@ -0,0 +1,2578 @@
  218366. +/*
  218367. + * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  218368. + */
  218369. +
  218370. +/*
  218371. + * The code contained herein is licensed under the GNU General Public
  218372. + * License. You may obtain a copy of the GNU General Public License
  218373. + * Version 2 or later at the following locations:
  218374. + *
  218375. + * http://www.opensource.org/licenses/gpl-license.html
  218376. + * http://www.gnu.org/copyleft/gpl.html
  218377. + */
  218378. +
  218379. +/*!
  218380. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  218381. + */
  218382. +
  218383. +/*!
  218384. + * @file mxcfb.c
  218385. + *
  218386. + * @brief MXC Frame buffer driver for SDC
  218387. + *
  218388. + * @ingroup Framebuffer
  218389. + */
  218390. +
  218391. +/*!
  218392. + * Include files
  218393. + */
  218394. +#include <linux/clk.h>
  218395. +#include <linux/console.h>
  218396. +#include <linux/delay.h>
  218397. +#include <linux/dma-mapping.h>
  218398. +#include <linux/errno.h>
  218399. +#include <linux/fb.h>
  218400. +#include <linux/fsl_devices.h>
  218401. +#include <linux/init.h>
  218402. +#include <linux/interrupt.h>
  218403. +#include <linux/io.h>
  218404. +#include <linux/ioport.h>
  218405. +#include <linux/ipu.h>
  218406. +#include <linux/ipu-v3.h>
  218407. +#include <linux/kernel.h>
  218408. +#include <linux/module.h>
  218409. +#include <linux/mxcfb.h>
  218410. +#include <linux/of_device.h>
  218411. +#include <linux/platform_device.h>
  218412. +#include <linux/sched.h>
  218413. +#include <linux/slab.h>
  218414. +#include <linux/string.h>
  218415. +#include <linux/uaccess.h>
  218416. +
  218417. +#include "mxc_dispdrv.h"
  218418. +
  218419. +/*
  218420. + * Driver name
  218421. + */
  218422. +#define MXCFB_NAME "mxc_sdc_fb"
  218423. +
  218424. +/* Display port number */
  218425. +#define MXCFB_PORT_NUM 2
  218426. +/*!
  218427. + * Structure containing the MXC specific framebuffer information.
  218428. + */
  218429. +struct mxcfb_info {
  218430. + int default_bpp;
  218431. + int cur_blank;
  218432. + int next_blank;
  218433. + ipu_channel_t ipu_ch;
  218434. + int ipu_id;
  218435. + int ipu_di;
  218436. + u32 ipu_di_pix_fmt;
  218437. + bool ipu_int_clk;
  218438. + bool overlay;
  218439. + bool alpha_chan_en;
  218440. + bool late_init;
  218441. + bool first_set_par;
  218442. + dma_addr_t alpha_phy_addr0;
  218443. + dma_addr_t alpha_phy_addr1;
  218444. + void *alpha_virt_addr0;
  218445. + void *alpha_virt_addr1;
  218446. + uint32_t alpha_mem_len;
  218447. + uint32_t ipu_ch_irq;
  218448. + uint32_t ipu_ch_nf_irq;
  218449. + uint32_t ipu_alp_ch_irq;
  218450. + uint32_t cur_ipu_buf;
  218451. + uint32_t cur_ipu_alpha_buf;
  218452. +
  218453. + u32 pseudo_palette[16];
  218454. +
  218455. + bool mode_found;
  218456. + struct completion flip_complete;
  218457. + struct completion alpha_flip_complete;
  218458. + struct completion vsync_complete;
  218459. +
  218460. + void *ipu;
  218461. + struct fb_info *ovfbi;
  218462. +
  218463. + struct mxc_dispdrv_handle *dispdrv;
  218464. +
  218465. + struct fb_var_screeninfo cur_var;
  218466. +};
  218467. +
  218468. +struct mxcfb_pfmt {
  218469. + u32 fb_pix_fmt;
  218470. + int bpp;
  218471. + struct fb_bitfield red;
  218472. + struct fb_bitfield green;
  218473. + struct fb_bitfield blue;
  218474. + struct fb_bitfield transp;
  218475. +};
  218476. +
  218477. +static const struct mxcfb_pfmt mxcfb_pfmts[] = {
  218478. + /* pixel bpp red green blue transp */
  218479. + {IPU_PIX_FMT_RGB565, 16, {11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0} },
  218480. + {IPU_PIX_FMT_RGB24, 24, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, { 0, 0, 0} },
  218481. + {IPU_PIX_FMT_BGR24, 24, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0} },
  218482. + {IPU_PIX_FMT_RGB32, 32, { 0, 8, 0}, { 8, 8, 0}, {16, 8, 0}, {24, 8, 0} },
  218483. + {IPU_PIX_FMT_BGR32, 32, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, {24, 8, 0} },
  218484. + {IPU_PIX_FMT_ABGR32, 32, {24, 8, 0}, {16, 8, 0}, { 8, 8, 0}, { 0, 8, 0} },
  218485. +};
  218486. +
  218487. +struct mxcfb_alloc_list {
  218488. + struct list_head list;
  218489. + dma_addr_t phy_addr;
  218490. + void *cpu_addr;
  218491. + u32 size;
  218492. +};
  218493. +
  218494. +enum {
  218495. + BOTH_ON,
  218496. + SRC_ON,
  218497. + TGT_ON,
  218498. + BOTH_OFF
  218499. +};
  218500. +
  218501. +static bool g_dp_in_use[2];
  218502. +LIST_HEAD(fb_alloc_list);
  218503. +
  218504. +/* Return default standard(RGB) pixel format */
  218505. +static uint32_t bpp_to_pixfmt(int bpp)
  218506. +{
  218507. + uint32_t pixfmt = 0;
  218508. +
  218509. + switch (bpp) {
  218510. + case 24:
  218511. + pixfmt = IPU_PIX_FMT_BGR24;
  218512. + break;
  218513. + case 32:
  218514. + pixfmt = IPU_PIX_FMT_BGR32;
  218515. + break;
  218516. + case 16:
  218517. + pixfmt = IPU_PIX_FMT_RGB565;
  218518. + break;
  218519. + }
  218520. + return pixfmt;
  218521. +}
  218522. +
  218523. +static inline int bitfield_is_equal(struct fb_bitfield f1,
  218524. + struct fb_bitfield f2)
  218525. +{
  218526. + return !memcmp(&f1, &f2, sizeof(f1));
  218527. +}
  218528. +
  218529. +static int pixfmt_to_var(uint32_t pixfmt, struct fb_var_screeninfo *var)
  218530. +{
  218531. + int i, ret = -1;
  218532. +
  218533. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  218534. + if (pixfmt == mxcfb_pfmts[i].fb_pix_fmt) {
  218535. + var->red = mxcfb_pfmts[i].red;
  218536. + var->green = mxcfb_pfmts[i].green;
  218537. + var->blue = mxcfb_pfmts[i].blue;
  218538. + var->transp = mxcfb_pfmts[i].transp;
  218539. + var->bits_per_pixel = mxcfb_pfmts[i].bpp;
  218540. + ret = 0;
  218541. + break;
  218542. + }
  218543. + }
  218544. + return ret;
  218545. +}
  218546. +
  218547. +static int bpp_to_var(int bpp, struct fb_var_screeninfo *var)
  218548. +{
  218549. + uint32_t pixfmt = 0;
  218550. +
  218551. + pixfmt = bpp_to_pixfmt(bpp);
  218552. + if (pixfmt)
  218553. + return pixfmt_to_var(pixfmt, var);
  218554. + else
  218555. + return -1;
  218556. +}
  218557. +
  218558. +static int check_var_pixfmt(struct fb_var_screeninfo *var)
  218559. +{
  218560. + int i, ret = -1;
  218561. +
  218562. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  218563. + if (bitfield_is_equal(var->red, mxcfb_pfmts[i].red) &&
  218564. + bitfield_is_equal(var->green, mxcfb_pfmts[i].green) &&
  218565. + bitfield_is_equal(var->blue, mxcfb_pfmts[i].blue) &&
  218566. + bitfield_is_equal(var->transp, mxcfb_pfmts[i].transp) &&
  218567. + var->bits_per_pixel == mxcfb_pfmts[i].bpp) {
  218568. + ret = 0;
  218569. + break;
  218570. + }
  218571. + }
  218572. + return ret;
  218573. +}
  218574. +
  218575. +static uint32_t fbi_to_pixfmt(struct fb_info *fbi)
  218576. +{
  218577. + int i;
  218578. + uint32_t pixfmt = 0;
  218579. +
  218580. + if (fbi->var.nonstd)
  218581. + return fbi->var.nonstd;
  218582. +
  218583. + for (i = 0; i < ARRAY_SIZE(mxcfb_pfmts); i++) {
  218584. + if (bitfield_is_equal(fbi->var.red, mxcfb_pfmts[i].red) &&
  218585. + bitfield_is_equal(fbi->var.green, mxcfb_pfmts[i].green) &&
  218586. + bitfield_is_equal(fbi->var.blue, mxcfb_pfmts[i].blue) &&
  218587. + bitfield_is_equal(fbi->var.transp, mxcfb_pfmts[i].transp)) {
  218588. + pixfmt = mxcfb_pfmts[i].fb_pix_fmt;
  218589. + break;
  218590. + }
  218591. + }
  218592. +
  218593. + if (pixfmt == 0)
  218594. + dev_err(fbi->device, "cannot get pixel format\n");
  218595. +
  218596. + return pixfmt;
  218597. +}
  218598. +
  218599. +static struct fb_info *found_registered_fb(ipu_channel_t ipu_ch, int ipu_id)
  218600. +{
  218601. + int i;
  218602. + struct mxcfb_info *mxc_fbi;
  218603. + struct fb_info *fbi = NULL;
  218604. +
  218605. + for (i = 0; i < num_registered_fb; i++) {
  218606. + mxc_fbi =
  218607. + ((struct mxcfb_info *)(registered_fb[i]->par));
  218608. +
  218609. + if ((mxc_fbi->ipu_ch == ipu_ch) &&
  218610. + (mxc_fbi->ipu_id == ipu_id)) {
  218611. + fbi = registered_fb[i];
  218612. + break;
  218613. + }
  218614. + }
  218615. + return fbi;
  218616. +}
  218617. +
  218618. +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id);
  218619. +static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id);
  218620. +static int mxcfb_blank(int blank, struct fb_info *info);
  218621. +static int mxcfb_map_video_memory(struct fb_info *fbi);
  218622. +static int mxcfb_unmap_video_memory(struct fb_info *fbi);
  218623. +
  218624. +/*
  218625. + * Set fixed framebuffer parameters based on variable settings.
  218626. + *
  218627. + * @param info framebuffer information pointer
  218628. + */
  218629. +static int mxcfb_set_fix(struct fb_info *info)
  218630. +{
  218631. + struct fb_fix_screeninfo *fix = &info->fix;
  218632. + struct fb_var_screeninfo *var = &info->var;
  218633. +
  218634. + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
  218635. +
  218636. + fix->type = FB_TYPE_PACKED_PIXELS;
  218637. + fix->accel = FB_ACCEL_NONE;
  218638. + fix->visual = FB_VISUAL_TRUECOLOR;
  218639. + fix->xpanstep = 1;
  218640. + fix->ywrapstep = 1;
  218641. + fix->ypanstep = 1;
  218642. +
  218643. + return 0;
  218644. +}
  218645. +
  218646. +static int _setup_disp_channel1(struct fb_info *fbi)
  218647. +{
  218648. + ipu_channel_params_t params;
  218649. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  218650. +
  218651. + memset(&params, 0, sizeof(params));
  218652. +
  218653. + if (mxc_fbi->ipu_ch == MEM_DC_SYNC) {
  218654. + params.mem_dc_sync.di = mxc_fbi->ipu_di;
  218655. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  218656. + params.mem_dc_sync.interlaced = true;
  218657. + params.mem_dc_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  218658. + params.mem_dc_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
  218659. + } else {
  218660. + params.mem_dp_bg_sync.di = mxc_fbi->ipu_di;
  218661. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  218662. + params.mem_dp_bg_sync.interlaced = true;
  218663. + params.mem_dp_bg_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  218664. + params.mem_dp_bg_sync.in_pixel_fmt = fbi_to_pixfmt(fbi);
  218665. + if (mxc_fbi->alpha_chan_en)
  218666. + params.mem_dp_bg_sync.alpha_chan_en = true;
  218667. + }
  218668. + ipu_init_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, &params);
  218669. +
  218670. + return 0;
  218671. +}
  218672. +
  218673. +static int _setup_disp_channel2(struct fb_info *fbi)
  218674. +{
  218675. + int retval = 0;
  218676. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  218677. + int fb_stride;
  218678. + unsigned long base;
  218679. + unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
  218680. +
  218681. + switch (fbi_to_pixfmt(fbi)) {
  218682. + case IPU_PIX_FMT_YUV420P2:
  218683. + case IPU_PIX_FMT_YVU420P:
  218684. + case IPU_PIX_FMT_NV12:
  218685. + case IPU_PIX_FMT_YUV422P:
  218686. + case IPU_PIX_FMT_YVU422P:
  218687. + case IPU_PIX_FMT_YUV420P:
  218688. + case IPU_PIX_FMT_YUV444P:
  218689. + fb_stride = fbi->var.xres_virtual;
  218690. + break;
  218691. + default:
  218692. + fb_stride = fbi->fix.line_length;
  218693. + }
  218694. +
  218695. + base = fbi->fix.smem_start;
  218696. + fr_xoff = fbi->var.xoffset;
  218697. + fr_w = fbi->var.xres_virtual;
  218698. + if (!(fbi->var.vmode & FB_VMODE_YWRAP)) {
  218699. + dev_dbg(fbi->device, "Y wrap disabled\n");
  218700. + fr_yoff = fbi->var.yoffset % fbi->var.yres;
  218701. + fr_h = fbi->var.yres;
  218702. + base += fbi->fix.line_length * fbi->var.yres *
  218703. + (fbi->var.yoffset / fbi->var.yres);
  218704. + } else {
  218705. + dev_dbg(fbi->device, "Y wrap enabled\n");
  218706. + fr_yoff = fbi->var.yoffset;
  218707. + fr_h = fbi->var.yres_virtual;
  218708. + }
  218709. + base += fr_yoff * fb_stride + fr_xoff;
  218710. +
  218711. + mxc_fbi->cur_ipu_buf = 2;
  218712. + init_completion(&mxc_fbi->flip_complete);
  218713. + /*
  218714. + * We don't need to wait for vsync at the first time
  218715. + * we do pan display after fb is initialized, as IPU will
  218716. + * switch to the newly selected buffer automatically,
  218717. + * so we call complete() for both mxc_fbi->flip_complete
  218718. + * and mxc_fbi->alpha_flip_complete.
  218719. + */
  218720. + complete(&mxc_fbi->flip_complete);
  218721. + if (mxc_fbi->alpha_chan_en) {
  218722. + mxc_fbi->cur_ipu_alpha_buf = 1;
  218723. + init_completion(&mxc_fbi->alpha_flip_complete);
  218724. + complete(&mxc_fbi->alpha_flip_complete);
  218725. + }
  218726. +
  218727. + retval = ipu_init_channel_buffer(mxc_fbi->ipu,
  218728. + mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  218729. + fbi_to_pixfmt(fbi),
  218730. + fbi->var.xres, fbi->var.yres,
  218731. + fb_stride,
  218732. + fbi->var.rotate,
  218733. + base,
  218734. + base,
  218735. + fbi->var.accel_flags &
  218736. + FB_ACCEL_DOUBLE_FLAG ? 0 : base,
  218737. + 0, 0);
  218738. + if (retval) {
  218739. + dev_err(fbi->device,
  218740. + "ipu_init_channel_buffer error %d\n", retval);
  218741. + return retval;
  218742. + }
  218743. +
  218744. + /* update u/v offset */
  218745. + ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  218746. + IPU_INPUT_BUFFER,
  218747. + fbi_to_pixfmt(fbi),
  218748. + fr_w,
  218749. + fr_h,
  218750. + fr_w,
  218751. + 0, 0,
  218752. + fr_yoff,
  218753. + fr_xoff);
  218754. +
  218755. + if (mxc_fbi->alpha_chan_en) {
  218756. + retval = ipu_init_channel_buffer(mxc_fbi->ipu,
  218757. + mxc_fbi->ipu_ch,
  218758. + IPU_ALPHA_IN_BUFFER,
  218759. + IPU_PIX_FMT_GENERIC,
  218760. + fbi->var.xres, fbi->var.yres,
  218761. + fbi->var.xres,
  218762. + fbi->var.rotate,
  218763. + mxc_fbi->alpha_phy_addr1,
  218764. + mxc_fbi->alpha_phy_addr0,
  218765. + 0,
  218766. + 0, 0);
  218767. + if (retval) {
  218768. + dev_err(fbi->device,
  218769. + "ipu_init_channel_buffer error %d\n", retval);
  218770. + return retval;
  218771. + }
  218772. + }
  218773. +
  218774. + return retval;
  218775. +}
  218776. +
  218777. +static bool mxcfb_need_to_set_par(struct fb_info *fbi)
  218778. +{
  218779. + struct mxcfb_info *mxc_fbi = fbi->par;
  218780. +
  218781. + if ((fbi->var.activate & FB_ACTIVATE_FORCE) &&
  218782. + (fbi->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
  218783. + return true;
  218784. +
  218785. + /*
  218786. + * Ignore xoffset and yoffset update,
  218787. + * because pan display handles this case.
  218788. + */
  218789. + mxc_fbi->cur_var.xoffset = fbi->var.xoffset;
  218790. + mxc_fbi->cur_var.yoffset = fbi->var.yoffset;
  218791. +
  218792. + return !!memcmp(&mxc_fbi->cur_var, &fbi->var,
  218793. + sizeof(struct fb_var_screeninfo));
  218794. +}
  218795. +
  218796. +/*
  218797. + * Set framebuffer parameters and change the operating mode.
  218798. + *
  218799. + * @param info framebuffer information pointer
  218800. + */
  218801. +static int mxcfb_set_par(struct fb_info *fbi)
  218802. +{
  218803. + int retval = 0;
  218804. + u32 mem_len, alpha_mem_len;
  218805. + ipu_di_signal_cfg_t sig_cfg;
  218806. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  218807. +
  218808. + int16_t ov_pos_x = 0, ov_pos_y = 0;
  218809. + int ov_pos_ret = 0;
  218810. + struct mxcfb_info *mxc_fbi_fg = NULL;
  218811. + bool ovfbi_enable = false;
  218812. +
  218813. + if (ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi)) &&
  218814. + mxc_fbi->alpha_chan_en) {
  218815. + dev_err(fbi->device, "Bad pixel format for "
  218816. + "graphics plane fb\n");
  218817. + return -EINVAL;
  218818. + }
  218819. +
  218820. + if (mxc_fbi->ovfbi)
  218821. + mxc_fbi_fg = (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  218822. +
  218823. + if (mxc_fbi->ovfbi && mxc_fbi_fg)
  218824. + if (mxc_fbi_fg->next_blank == FB_BLANK_UNBLANK)
  218825. + ovfbi_enable = true;
  218826. +
  218827. + if (!mxcfb_need_to_set_par(fbi))
  218828. + return 0;
  218829. +
  218830. + dev_dbg(fbi->device, "Reconfiguring framebuffer\n");
  218831. +
  218832. + if (fbi->var.xres == 0 || fbi->var.yres == 0)
  218833. + return 0;
  218834. +
  218835. + if (ovfbi_enable) {
  218836. + ov_pos_ret = ipu_disp_get_window_pos(
  218837. + mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
  218838. + &ov_pos_x, &ov_pos_y);
  218839. + if (ov_pos_ret < 0)
  218840. + dev_err(fbi->device, "Get overlay pos failed, dispdrv:%s.\n",
  218841. + mxc_fbi->dispdrv->drv->name);
  218842. +
  218843. + ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
  218844. + ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_irq);
  218845. + ipu_clear_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
  218846. + ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq);
  218847. + ipu_disable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch, true);
  218848. + ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  218849. + }
  218850. +
  218851. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  218852. + ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  218853. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  218854. + ipu_disable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  218855. + ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
  218856. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  218857. +
  218858. + /*
  218859. + * Disable IPU hsp clock if it is enabled for an
  218860. + * additional time in ipu common driver.
  218861. + */
  218862. + if (mxc_fbi->first_set_par && mxc_fbi->late_init)
  218863. + ipu_disable_hsp_clk(mxc_fbi->ipu);
  218864. +
  218865. + mxcfb_set_fix(fbi);
  218866. +
  218867. + mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
  218868. + if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) {
  218869. + if (fbi->fix.smem_start)
  218870. + mxcfb_unmap_video_memory(fbi);
  218871. +
  218872. + if (mxcfb_map_video_memory(fbi) < 0)
  218873. + return -ENOMEM;
  218874. + }
  218875. +
  218876. + if (mxc_fbi->first_set_par) {
  218877. + /*
  218878. + * Clear the screen in case uboot fb pixel format is not
  218879. + * the same to kernel fb pixel format.
  218880. + */
  218881. + if (mxc_fbi->late_init)
  218882. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  218883. +
  218884. + mxc_fbi->first_set_par = false;
  218885. + }
  218886. +
  218887. + if (mxc_fbi->alpha_chan_en) {
  218888. + alpha_mem_len = fbi->var.xres * fbi->var.yres;
  218889. + if ((!mxc_fbi->alpha_phy_addr0 && !mxc_fbi->alpha_phy_addr1) ||
  218890. + (alpha_mem_len > mxc_fbi->alpha_mem_len)) {
  218891. + if (mxc_fbi->alpha_phy_addr0)
  218892. + dma_free_coherent(fbi->device,
  218893. + mxc_fbi->alpha_mem_len,
  218894. + mxc_fbi->alpha_virt_addr0,
  218895. + mxc_fbi->alpha_phy_addr0);
  218896. + if (mxc_fbi->alpha_phy_addr1)
  218897. + dma_free_coherent(fbi->device,
  218898. + mxc_fbi->alpha_mem_len,
  218899. + mxc_fbi->alpha_virt_addr1,
  218900. + mxc_fbi->alpha_phy_addr1);
  218901. +
  218902. + mxc_fbi->alpha_virt_addr0 =
  218903. + dma_alloc_coherent(fbi->device,
  218904. + alpha_mem_len,
  218905. + &mxc_fbi->alpha_phy_addr0,
  218906. + GFP_DMA | GFP_KERNEL);
  218907. +
  218908. + mxc_fbi->alpha_virt_addr1 =
  218909. + dma_alloc_coherent(fbi->device,
  218910. + alpha_mem_len,
  218911. + &mxc_fbi->alpha_phy_addr1,
  218912. + GFP_DMA | GFP_KERNEL);
  218913. + if (mxc_fbi->alpha_virt_addr0 == NULL ||
  218914. + mxc_fbi->alpha_virt_addr1 == NULL) {
  218915. + dev_err(fbi->device, "mxcfb: dma alloc for"
  218916. + " alpha buffer failed.\n");
  218917. + if (mxc_fbi->alpha_virt_addr0)
  218918. + dma_free_coherent(fbi->device,
  218919. + mxc_fbi->alpha_mem_len,
  218920. + mxc_fbi->alpha_virt_addr0,
  218921. + mxc_fbi->alpha_phy_addr0);
  218922. + if (mxc_fbi->alpha_virt_addr1)
  218923. + dma_free_coherent(fbi->device,
  218924. + mxc_fbi->alpha_mem_len,
  218925. + mxc_fbi->alpha_virt_addr1,
  218926. + mxc_fbi->alpha_phy_addr1);
  218927. + return -ENOMEM;
  218928. + }
  218929. + mxc_fbi->alpha_mem_len = alpha_mem_len;
  218930. + }
  218931. + }
  218932. +
  218933. + if (mxc_fbi->next_blank != FB_BLANK_UNBLANK)
  218934. + return retval;
  218935. +
  218936. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->setup) {
  218937. + retval = mxc_fbi->dispdrv->drv->setup(mxc_fbi->dispdrv, fbi);
  218938. + if (retval < 0) {
  218939. + dev_err(fbi->device, "setup error, dispdrv:%s.\n",
  218940. + mxc_fbi->dispdrv->drv->name);
  218941. + return -EINVAL;
  218942. + }
  218943. + }
  218944. +
  218945. + _setup_disp_channel1(fbi);
  218946. + if (ovfbi_enable)
  218947. + _setup_disp_channel1(mxc_fbi->ovfbi);
  218948. +
  218949. + if (!mxc_fbi->overlay) {
  218950. + uint32_t out_pixel_fmt;
  218951. +
  218952. + memset(&sig_cfg, 0, sizeof(sig_cfg));
  218953. + if (fbi->var.vmode & FB_VMODE_INTERLACED)
  218954. + sig_cfg.interlaced = true;
  218955. + out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt;
  218956. + if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */
  218957. + sig_cfg.odd_field_first = true;
  218958. + if (mxc_fbi->ipu_int_clk)
  218959. + sig_cfg.int_clk = true;
  218960. + if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
  218961. + sig_cfg.Hsync_pol = true;
  218962. + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
  218963. + sig_cfg.Vsync_pol = true;
  218964. + if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL))
  218965. + sig_cfg.clk_pol = true;
  218966. + if (fbi->var.sync & FB_SYNC_DATA_INVERT)
  218967. + sig_cfg.data_pol = true;
  218968. + if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT))
  218969. + sig_cfg.enable_pol = true;
  218970. + if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
  218971. + sig_cfg.clkidle_en = true;
  218972. +
  218973. + dev_dbg(fbi->device, "pixclock = %ul Hz\n",
  218974. + (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
  218975. +
  218976. + if (ipu_init_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di,
  218977. + (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
  218978. + fbi->var.xres, fbi->var.yres,
  218979. + out_pixel_fmt,
  218980. + fbi->var.left_margin,
  218981. + fbi->var.hsync_len,
  218982. + fbi->var.right_margin,
  218983. + fbi->var.upper_margin,
  218984. + fbi->var.vsync_len,
  218985. + fbi->var.lower_margin,
  218986. + 0, sig_cfg) != 0) {
  218987. + dev_err(fbi->device,
  218988. + "mxcfb: Error initializing panel.\n");
  218989. + return -EINVAL;
  218990. + }
  218991. +
  218992. + fbi->mode =
  218993. + (struct fb_videomode *)fb_match_mode(&fbi->var,
  218994. + &fbi->modelist);
  218995. +
  218996. + ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, 0, 0);
  218997. + }
  218998. +
  218999. + retval = _setup_disp_channel2(fbi);
  219000. + if (retval) {
  219001. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  219002. + return retval;
  219003. + }
  219004. +
  219005. + if (ovfbi_enable) {
  219006. + if (ov_pos_ret >= 0)
  219007. + ipu_disp_set_window_pos(
  219008. + mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch,
  219009. + ov_pos_x, ov_pos_y);
  219010. + retval = _setup_disp_channel2(mxc_fbi->ovfbi);
  219011. + if (retval) {
  219012. + ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  219013. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  219014. + return retval;
  219015. + }
  219016. + }
  219017. +
  219018. + ipu_enable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  219019. + if (ovfbi_enable)
  219020. + ipu_enable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch);
  219021. +
  219022. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->enable) {
  219023. + retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv);
  219024. + if (retval < 0) {
  219025. + dev_err(fbi->device, "enable error, dispdrv:%s.\n",
  219026. + mxc_fbi->dispdrv->drv->name);
  219027. + return -EINVAL;
  219028. + }
  219029. + }
  219030. +
  219031. + mxc_fbi->cur_var = fbi->var;
  219032. +
  219033. + return retval;
  219034. +}
  219035. +
  219036. +static int _swap_channels(struct fb_info *fbi_from,
  219037. + struct fb_info *fbi_to, bool both_on)
  219038. +{
  219039. + int retval, tmp;
  219040. + ipu_channel_t old_ch;
  219041. + struct fb_info *ovfbi;
  219042. + struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
  219043. + struct mxcfb_info *mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
  219044. +
  219045. + if (both_on) {
  219046. + ipu_disable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch, true);
  219047. + ipu_uninit_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
  219048. + }
  219049. +
  219050. + /* switch the mxc fbi parameters */
  219051. + old_ch = mxc_fbi_from->ipu_ch;
  219052. + mxc_fbi_from->ipu_ch = mxc_fbi_to->ipu_ch;
  219053. + mxc_fbi_to->ipu_ch = old_ch;
  219054. + tmp = mxc_fbi_from->ipu_ch_irq;
  219055. + mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
  219056. + mxc_fbi_to->ipu_ch_irq = tmp;
  219057. + tmp = mxc_fbi_from->ipu_ch_nf_irq;
  219058. + mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
  219059. + mxc_fbi_to->ipu_ch_nf_irq = tmp;
  219060. + ovfbi = mxc_fbi_from->ovfbi;
  219061. + mxc_fbi_from->ovfbi = mxc_fbi_to->ovfbi;
  219062. + mxc_fbi_to->ovfbi = ovfbi;
  219063. +
  219064. + _setup_disp_channel1(fbi_from);
  219065. + retval = _setup_disp_channel2(fbi_from);
  219066. + if (retval)
  219067. + return retval;
  219068. +
  219069. + /* switch between dp and dc, disable old idmac, enable new idmac */
  219070. + retval = ipu_swap_channel(mxc_fbi_from->ipu, old_ch, mxc_fbi_from->ipu_ch);
  219071. + ipu_uninit_channel(mxc_fbi_from->ipu, old_ch);
  219072. +
  219073. + if (both_on) {
  219074. + _setup_disp_channel1(fbi_to);
  219075. + retval = _setup_disp_channel2(fbi_to);
  219076. + if (retval)
  219077. + return retval;
  219078. + ipu_enable_channel(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch);
  219079. + }
  219080. +
  219081. + return retval;
  219082. +}
  219083. +
  219084. +static int swap_channels(struct fb_info *fbi_from)
  219085. +{
  219086. + int i;
  219087. + int swap_mode;
  219088. + ipu_channel_t ch_to;
  219089. + struct mxcfb_info *mxc_fbi_from = (struct mxcfb_info *)fbi_from->par;
  219090. + struct fb_info *fbi_to = NULL;
  219091. + struct mxcfb_info *mxc_fbi_to;
  219092. +
  219093. + /* what's the target channel? */
  219094. + if (mxc_fbi_from->ipu_ch == MEM_BG_SYNC)
  219095. + ch_to = MEM_DC_SYNC;
  219096. + else
  219097. + ch_to = MEM_BG_SYNC;
  219098. +
  219099. + fbi_to = found_registered_fb(ch_to, mxc_fbi_from->ipu_id);
  219100. + if (!fbi_to)
  219101. + return -1;
  219102. + mxc_fbi_to = (struct mxcfb_info *)fbi_to->par;
  219103. +
  219104. + ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
  219105. + ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
  219106. + ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq, fbi_from);
  219107. + ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq, fbi_to);
  219108. + ipu_clear_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
  219109. + ipu_clear_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
  219110. + ipu_free_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq, fbi_from);
  219111. + ipu_free_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq, fbi_to);
  219112. +
  219113. + if (mxc_fbi_from->cur_blank == FB_BLANK_UNBLANK) {
  219114. + if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
  219115. + swap_mode = BOTH_ON;
  219116. + else
  219117. + swap_mode = SRC_ON;
  219118. + } else {
  219119. + if (mxc_fbi_to->cur_blank == FB_BLANK_UNBLANK)
  219120. + swap_mode = TGT_ON;
  219121. + else
  219122. + swap_mode = BOTH_OFF;
  219123. + }
  219124. +
  219125. + switch (swap_mode) {
  219126. + case BOTH_ON:
  219127. + /* disable target->switch src->enable target */
  219128. + _swap_channels(fbi_from, fbi_to, true);
  219129. + break;
  219130. + case SRC_ON:
  219131. + /* just switch src */
  219132. + _swap_channels(fbi_from, fbi_to, false);
  219133. + break;
  219134. + case TGT_ON:
  219135. + /* just switch target */
  219136. + _swap_channels(fbi_to, fbi_from, false);
  219137. + break;
  219138. + case BOTH_OFF:
  219139. + /* switch directly, no more need to do */
  219140. + mxc_fbi_to->ipu_ch = mxc_fbi_from->ipu_ch;
  219141. + mxc_fbi_from->ipu_ch = ch_to;
  219142. + i = mxc_fbi_from->ipu_ch_irq;
  219143. + mxc_fbi_from->ipu_ch_irq = mxc_fbi_to->ipu_ch_irq;
  219144. + mxc_fbi_to->ipu_ch_irq = i;
  219145. + i = mxc_fbi_from->ipu_ch_nf_irq;
  219146. + mxc_fbi_from->ipu_ch_nf_irq = mxc_fbi_to->ipu_ch_nf_irq;
  219147. + mxc_fbi_to->ipu_ch_nf_irq = i;
  219148. + break;
  219149. + default:
  219150. + break;
  219151. + }
  219152. +
  219153. + if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq,
  219154. + mxcfb_irq_handler, IPU_IRQF_ONESHOT,
  219155. + MXCFB_NAME, fbi_from) != 0) {
  219156. + dev_err(fbi_from->device, "Error registering irq %d\n",
  219157. + mxc_fbi_from->ipu_ch_irq);
  219158. + return -EBUSY;
  219159. + }
  219160. + ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_irq);
  219161. + if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq,
  219162. + mxcfb_irq_handler, IPU_IRQF_ONESHOT,
  219163. + MXCFB_NAME, fbi_to) != 0) {
  219164. + dev_err(fbi_to->device, "Error registering irq %d\n",
  219165. + mxc_fbi_to->ipu_ch_irq);
  219166. + return -EBUSY;
  219167. + }
  219168. + ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_irq);
  219169. + if (ipu_request_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq,
  219170. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
  219171. + MXCFB_NAME, fbi_from) != 0) {
  219172. + dev_err(fbi_from->device, "Error registering irq %d\n",
  219173. + mxc_fbi_from->ipu_ch_nf_irq);
  219174. + return -EBUSY;
  219175. + }
  219176. + ipu_disable_irq(mxc_fbi_from->ipu, mxc_fbi_from->ipu_ch_nf_irq);
  219177. + if (ipu_request_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq,
  219178. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT,
  219179. + MXCFB_NAME, fbi_to) != 0) {
  219180. + dev_err(fbi_to->device, "Error registering irq %d\n",
  219181. + mxc_fbi_to->ipu_ch_nf_irq);
  219182. + return -EBUSY;
  219183. + }
  219184. + ipu_disable_irq(mxc_fbi_to->ipu, mxc_fbi_to->ipu_ch_nf_irq);
  219185. +
  219186. + return 0;
  219187. +}
  219188. +
  219189. +/*
  219190. + * Check framebuffer variable parameters and adjust to valid values.
  219191. + *
  219192. + * @param var framebuffer variable parameters
  219193. + *
  219194. + * @param info framebuffer information pointer
  219195. + */
  219196. +static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  219197. +{
  219198. + u32 vtotal;
  219199. + u32 htotal;
  219200. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
  219201. +
  219202. +
  219203. + if (var->xres == 0 || var->yres == 0)
  219204. + return 0;
  219205. +
  219206. + /* fg should not bigger than bg */
  219207. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  219208. + struct fb_info *fbi_tmp;
  219209. + int bg_xres = 0, bg_yres = 0;
  219210. + int16_t pos_x, pos_y;
  219211. +
  219212. + bg_xres = var->xres;
  219213. + bg_yres = var->yres;
  219214. +
  219215. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  219216. + if (fbi_tmp) {
  219217. + bg_xres = fbi_tmp->var.xres;
  219218. + bg_yres = fbi_tmp->var.yres;
  219219. + }
  219220. +
  219221. + ipu_disp_get_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch, &pos_x, &pos_y);
  219222. +
  219223. + if ((var->xres + pos_x) > bg_xres)
  219224. + var->xres = bg_xres - pos_x;
  219225. + if ((var->yres + pos_y) > bg_yres)
  219226. + var->yres = bg_yres - pos_y;
  219227. + }
  219228. +
  219229. + if (var->rotate > IPU_ROTATE_VERT_FLIP)
  219230. + var->rotate = IPU_ROTATE_NONE;
  219231. +
  219232. + if (var->xres_virtual < var->xres)
  219233. + var->xres_virtual = var->xres;
  219234. +
  219235. + if (var->yres_virtual < var->yres)
  219236. + var->yres_virtual = var->yres * 3;
  219237. +
  219238. + if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
  219239. + (var->bits_per_pixel != 16) && (var->bits_per_pixel != 12) &&
  219240. + (var->bits_per_pixel != 8))
  219241. + var->bits_per_pixel = 16;
  219242. +
  219243. + if (check_var_pixfmt(var))
  219244. + /* Fall back to default */
  219245. + bpp_to_var(var->bits_per_pixel, var);
  219246. +
  219247. + if (var->pixclock < 1000) {
  219248. + htotal = var->xres + var->right_margin + var->hsync_len +
  219249. + var->left_margin;
  219250. + vtotal = var->yres + var->lower_margin + var->vsync_len +
  219251. + var->upper_margin;
  219252. + var->pixclock = (vtotal * htotal * 6UL) / 100UL;
  219253. + var->pixclock = KHZ2PICOS(var->pixclock);
  219254. + dev_dbg(info->device,
  219255. + "pixclock set for 60Hz refresh = %u ps\n",
  219256. + var->pixclock);
  219257. + }
  219258. +
  219259. + var->height = -1;
  219260. + var->width = -1;
  219261. + var->grayscale = 0;
  219262. +
  219263. + return 0;
  219264. +}
  219265. +
  219266. +static inline u_int _chan_to_field(u_int chan, struct fb_bitfield *bf)
  219267. +{
  219268. + chan &= 0xffff;
  219269. + chan >>= 16 - bf->length;
  219270. + return chan << bf->offset;
  219271. +}
  219272. +
  219273. +static int mxcfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  219274. + u_int trans, struct fb_info *fbi)
  219275. +{
  219276. + unsigned int val;
  219277. + int ret = 1;
  219278. +
  219279. + /*
  219280. + * If greyscale is true, then we convert the RGB value
  219281. + * to greyscale no matter what visual we are using.
  219282. + */
  219283. + if (fbi->var.grayscale)
  219284. + red = green = blue = (19595 * red + 38470 * green +
  219285. + 7471 * blue) >> 16;
  219286. + switch (fbi->fix.visual) {
  219287. + case FB_VISUAL_TRUECOLOR:
  219288. + /*
  219289. + * 16-bit True Colour. We encode the RGB value
  219290. + * according to the RGB bitfield information.
  219291. + */
  219292. + if (regno < 16) {
  219293. + u32 *pal = fbi->pseudo_palette;
  219294. +
  219295. + val = _chan_to_field(red, &fbi->var.red);
  219296. + val |= _chan_to_field(green, &fbi->var.green);
  219297. + val |= _chan_to_field(blue, &fbi->var.blue);
  219298. +
  219299. + pal[regno] = val;
  219300. + ret = 0;
  219301. + }
  219302. + break;
  219303. +
  219304. + case FB_VISUAL_STATIC_PSEUDOCOLOR:
  219305. + case FB_VISUAL_PSEUDOCOLOR:
  219306. + break;
  219307. + }
  219308. +
  219309. + return ret;
  219310. +}
  219311. +
  219312. +/*
  219313. + * Function to handle custom ioctls for MXC framebuffer.
  219314. + *
  219315. + * @param inode inode struct
  219316. + *
  219317. + * @param file file struct
  219318. + *
  219319. + * @param cmd Ioctl command to handle
  219320. + *
  219321. + * @param arg User pointer to command arguments
  219322. + *
  219323. + * @param fbi framebuffer information pointer
  219324. + */
  219325. +static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
  219326. +{
  219327. + int retval = 0;
  219328. + int __user *argp = (void __user *)arg;
  219329. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  219330. +
  219331. + switch (cmd) {
  219332. + case MXCFB_SET_GBL_ALPHA:
  219333. + {
  219334. + struct mxcfb_gbl_alpha ga;
  219335. +
  219336. + if (copy_from_user(&ga, (void *)arg, sizeof(ga))) {
  219337. + retval = -EFAULT;
  219338. + break;
  219339. + }
  219340. +
  219341. + if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
  219342. + mxc_fbi->ipu_ch,
  219343. + (bool)ga.enable,
  219344. + ga.alpha)) {
  219345. + retval = -EINVAL;
  219346. + break;
  219347. + }
  219348. +
  219349. + if (ga.enable)
  219350. + mxc_fbi->alpha_chan_en = false;
  219351. +
  219352. + if (ga.enable)
  219353. + dev_dbg(fbi->device,
  219354. + "Set global alpha of %s to %d\n",
  219355. + fbi->fix.id, ga.alpha);
  219356. + break;
  219357. + }
  219358. + case MXCFB_SET_LOC_ALPHA:
  219359. + {
  219360. + struct mxcfb_loc_alpha la;
  219361. + bool bad_pixfmt =
  219362. + ipu_ch_param_bad_alpha_pos(fbi_to_pixfmt(fbi));
  219363. +
  219364. + if (copy_from_user(&la, (void *)arg, sizeof(la))) {
  219365. + retval = -EFAULT;
  219366. + break;
  219367. + }
  219368. +
  219369. + if (la.enable && !la.alpha_in_pixel) {
  219370. + struct fb_info *fbi_tmp;
  219371. + ipu_channel_t ipu_ch;
  219372. +
  219373. + if (bad_pixfmt) {
  219374. + dev_err(fbi->device, "Bad pixel format "
  219375. + "for graphics plane fb\n");
  219376. + retval = -EINVAL;
  219377. + break;
  219378. + }
  219379. +
  219380. + mxc_fbi->alpha_chan_en = true;
  219381. +
  219382. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
  219383. + ipu_ch = MEM_BG_SYNC;
  219384. + else if (mxc_fbi->ipu_ch == MEM_BG_SYNC)
  219385. + ipu_ch = MEM_FG_SYNC;
  219386. + else {
  219387. + retval = -EINVAL;
  219388. + break;
  219389. + }
  219390. +
  219391. + fbi_tmp = found_registered_fb(ipu_ch, mxc_fbi->ipu_id);
  219392. + if (fbi_tmp)
  219393. + ((struct mxcfb_info *)(fbi_tmp->par))->alpha_chan_en = false;
  219394. + } else
  219395. + mxc_fbi->alpha_chan_en = false;
  219396. +
  219397. + if (ipu_disp_set_global_alpha(mxc_fbi->ipu,
  219398. + mxc_fbi->ipu_ch,
  219399. + !(bool)la.enable, 0)) {
  219400. + retval = -EINVAL;
  219401. + break;
  219402. + }
  219403. +
  219404. + fbi->var.activate = (fbi->var.activate & ~FB_ACTIVATE_MASK) |
  219405. + FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
  219406. + mxcfb_set_par(fbi);
  219407. +
  219408. + la.alpha_phy_addr0 = mxc_fbi->alpha_phy_addr0;
  219409. + la.alpha_phy_addr1 = mxc_fbi->alpha_phy_addr1;
  219410. + if (copy_to_user((void *)arg, &la, sizeof(la))) {
  219411. + retval = -EFAULT;
  219412. + break;
  219413. + }
  219414. +
  219415. + if (la.enable)
  219416. + dev_dbg(fbi->device,
  219417. + "Enable DP local alpha for %s\n",
  219418. + fbi->fix.id);
  219419. + break;
  219420. + }
  219421. + case MXCFB_SET_LOC_ALP_BUF:
  219422. + {
  219423. + unsigned long base;
  219424. + uint32_t ipu_alp_ch_irq;
  219425. +
  219426. + if (!(((mxc_fbi->ipu_ch == MEM_FG_SYNC) ||
  219427. + (mxc_fbi->ipu_ch == MEM_BG_SYNC)) &&
  219428. + (mxc_fbi->alpha_chan_en))) {
  219429. + dev_err(fbi->device,
  219430. + "Should use background or overlay "
  219431. + "framebuffer to set the alpha buffer "
  219432. + "number\n");
  219433. + return -EINVAL;
  219434. + }
  219435. +
  219436. + if (get_user(base, argp))
  219437. + return -EFAULT;
  219438. +
  219439. + if (base != mxc_fbi->alpha_phy_addr0 &&
  219440. + base != mxc_fbi->alpha_phy_addr1) {
  219441. + dev_err(fbi->device,
  219442. + "Wrong alpha buffer physical address "
  219443. + "%lu\n", base);
  219444. + return -EINVAL;
  219445. + }
  219446. +
  219447. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC)
  219448. + ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
  219449. + else
  219450. + ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
  219451. +
  219452. + retval = wait_for_completion_timeout(
  219453. + &mxc_fbi->alpha_flip_complete, HZ/2);
  219454. + if (retval == 0) {
  219455. + dev_err(fbi->device, "timeout when waiting for alpha flip irq\n");
  219456. + retval = -ETIMEDOUT;
  219457. + break;
  219458. + }
  219459. +
  219460. + mxc_fbi->cur_ipu_alpha_buf =
  219461. + !mxc_fbi->cur_ipu_alpha_buf;
  219462. + if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219463. + IPU_ALPHA_IN_BUFFER,
  219464. + mxc_fbi->
  219465. + cur_ipu_alpha_buf,
  219466. + base) == 0) {
  219467. + ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219468. + IPU_ALPHA_IN_BUFFER,
  219469. + mxc_fbi->cur_ipu_alpha_buf);
  219470. + ipu_clear_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
  219471. + ipu_enable_irq(mxc_fbi->ipu, ipu_alp_ch_irq);
  219472. + } else {
  219473. + dev_err(fbi->device,
  219474. + "Error updating %s SDC alpha buf %d "
  219475. + "to address=0x%08lX\n",
  219476. + fbi->fix.id,
  219477. + mxc_fbi->cur_ipu_alpha_buf, base);
  219478. + }
  219479. + break;
  219480. + }
  219481. + case MXCFB_SET_CLR_KEY:
  219482. + {
  219483. + struct mxcfb_color_key key;
  219484. + if (copy_from_user(&key, (void *)arg, sizeof(key))) {
  219485. + retval = -EFAULT;
  219486. + break;
  219487. + }
  219488. + retval = ipu_disp_set_color_key(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219489. + key.enable,
  219490. + key.color_key);
  219491. + dev_dbg(fbi->device, "Set color key to 0x%08X\n",
  219492. + key.color_key);
  219493. + break;
  219494. + }
  219495. + case MXCFB_SET_GAMMA:
  219496. + {
  219497. + struct mxcfb_gamma gamma;
  219498. + if (copy_from_user(&gamma, (void *)arg, sizeof(gamma))) {
  219499. + retval = -EFAULT;
  219500. + break;
  219501. + }
  219502. + retval = ipu_disp_set_gamma_correction(mxc_fbi->ipu,
  219503. + mxc_fbi->ipu_ch,
  219504. + gamma.enable,
  219505. + gamma.constk,
  219506. + gamma.slopek);
  219507. + break;
  219508. + }
  219509. + case MXCFB_WAIT_FOR_VSYNC:
  219510. + {
  219511. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  219512. + /* BG should poweron */
  219513. + struct mxcfb_info *bg_mxcfbi = NULL;
  219514. + struct fb_info *fbi_tmp;
  219515. +
  219516. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  219517. + if (fbi_tmp)
  219518. + bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
  219519. +
  219520. + if (!bg_mxcfbi) {
  219521. + retval = -EINVAL;
  219522. + break;
  219523. + }
  219524. + if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK) {
  219525. + retval = -EINVAL;
  219526. + break;
  219527. + }
  219528. + }
  219529. + if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK) {
  219530. + retval = -EINVAL;
  219531. + break;
  219532. + }
  219533. +
  219534. + init_completion(&mxc_fbi->vsync_complete);
  219535. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  219536. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_nf_irq);
  219537. + retval = wait_for_completion_interruptible_timeout(
  219538. + &mxc_fbi->vsync_complete, 1 * HZ);
  219539. + if (retval == 0) {
  219540. + dev_err(fbi->device,
  219541. + "MXCFB_WAIT_FOR_VSYNC: timeout %d\n",
  219542. + retval);
  219543. + retval = -ETIME;
  219544. + } else if (retval > 0) {
  219545. + retval = 0;
  219546. + }
  219547. + break;
  219548. + }
  219549. + case FBIO_ALLOC:
  219550. + {
  219551. + int size;
  219552. + struct mxcfb_alloc_list *mem;
  219553. +
  219554. + mem = kzalloc(sizeof(*mem), GFP_KERNEL);
  219555. + if (mem == NULL)
  219556. + return -ENOMEM;
  219557. +
  219558. + if (get_user(size, argp))
  219559. + return -EFAULT;
  219560. +
  219561. + mem->size = PAGE_ALIGN(size);
  219562. +
  219563. + mem->cpu_addr = dma_alloc_coherent(fbi->device, size,
  219564. + &mem->phy_addr,
  219565. + GFP_KERNEL);
  219566. + if (mem->cpu_addr == NULL) {
  219567. + kfree(mem);
  219568. + return -ENOMEM;
  219569. + }
  219570. +
  219571. + list_add(&mem->list, &fb_alloc_list);
  219572. +
  219573. + dev_dbg(fbi->device, "allocated %d bytes @ 0x%08X\n",
  219574. + mem->size, mem->phy_addr);
  219575. +
  219576. + if (put_user(mem->phy_addr, argp))
  219577. + return -EFAULT;
  219578. +
  219579. + break;
  219580. + }
  219581. + case FBIO_FREE:
  219582. + {
  219583. + unsigned long offset;
  219584. + struct mxcfb_alloc_list *mem;
  219585. +
  219586. + if (get_user(offset, argp))
  219587. + return -EFAULT;
  219588. +
  219589. + retval = -EINVAL;
  219590. + list_for_each_entry(mem, &fb_alloc_list, list) {
  219591. + if (mem->phy_addr == offset) {
  219592. + list_del(&mem->list);
  219593. + dma_free_coherent(fbi->device,
  219594. + mem->size,
  219595. + mem->cpu_addr,
  219596. + mem->phy_addr);
  219597. + kfree(mem);
  219598. + retval = 0;
  219599. + break;
  219600. + }
  219601. + }
  219602. +
  219603. + break;
  219604. + }
  219605. + case MXCFB_SET_OVERLAY_POS:
  219606. + {
  219607. + struct mxcfb_pos pos;
  219608. + struct fb_info *bg_fbi = NULL;
  219609. + struct mxcfb_info *bg_mxcfbi = NULL;
  219610. +
  219611. + if (mxc_fbi->ipu_ch != MEM_FG_SYNC) {
  219612. + dev_err(fbi->device, "Should use the overlay "
  219613. + "framebuffer to set the position of "
  219614. + "the overlay window\n");
  219615. + retval = -EINVAL;
  219616. + break;
  219617. + }
  219618. +
  219619. + if (copy_from_user(&pos, (void *)arg, sizeof(pos))) {
  219620. + retval = -EFAULT;
  219621. + break;
  219622. + }
  219623. +
  219624. + bg_fbi = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  219625. + if (bg_fbi)
  219626. + bg_mxcfbi = ((struct mxcfb_info *)(bg_fbi->par));
  219627. +
  219628. + if (bg_fbi == NULL) {
  219629. + dev_err(fbi->device, "Cannot find the "
  219630. + "background framebuffer\n");
  219631. + retval = -ENOENT;
  219632. + break;
  219633. + }
  219634. +
  219635. + /* if fb is unblank, check if the pos fit the display */
  219636. + if (mxc_fbi->cur_blank == FB_BLANK_UNBLANK) {
  219637. + if (fbi->var.xres + pos.x > bg_fbi->var.xres) {
  219638. + if (bg_fbi->var.xres < fbi->var.xres)
  219639. + pos.x = 0;
  219640. + else
  219641. + pos.x = bg_fbi->var.xres - fbi->var.xres;
  219642. + }
  219643. + if (fbi->var.yres + pos.y > bg_fbi->var.yres) {
  219644. + if (bg_fbi->var.yres < fbi->var.yres)
  219645. + pos.y = 0;
  219646. + else
  219647. + pos.y = bg_fbi->var.yres - fbi->var.yres;
  219648. + }
  219649. + }
  219650. +
  219651. + retval = ipu_disp_set_window_pos(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219652. + pos.x, pos.y);
  219653. +
  219654. + if (copy_to_user((void *)arg, &pos, sizeof(pos))) {
  219655. + retval = -EFAULT;
  219656. + break;
  219657. + }
  219658. + break;
  219659. + }
  219660. + case MXCFB_GET_FB_IPU_CHAN:
  219661. + {
  219662. + struct mxcfb_info *mxc_fbi =
  219663. + (struct mxcfb_info *)fbi->par;
  219664. +
  219665. + if (put_user(mxc_fbi->ipu_ch, argp))
  219666. + return -EFAULT;
  219667. + break;
  219668. + }
  219669. + case MXCFB_GET_DIFMT:
  219670. + {
  219671. + struct mxcfb_info *mxc_fbi =
  219672. + (struct mxcfb_info *)fbi->par;
  219673. +
  219674. + if (put_user(mxc_fbi->ipu_di_pix_fmt, argp))
  219675. + return -EFAULT;
  219676. + break;
  219677. + }
  219678. + case MXCFB_GET_FB_IPU_DI:
  219679. + {
  219680. + struct mxcfb_info *mxc_fbi =
  219681. + (struct mxcfb_info *)fbi->par;
  219682. +
  219683. + if (put_user(mxc_fbi->ipu_di, argp))
  219684. + return -EFAULT;
  219685. + break;
  219686. + }
  219687. + case MXCFB_GET_FB_BLANK:
  219688. + {
  219689. + struct mxcfb_info *mxc_fbi =
  219690. + (struct mxcfb_info *)fbi->par;
  219691. +
  219692. + if (put_user(mxc_fbi->cur_blank, argp))
  219693. + return -EFAULT;
  219694. + break;
  219695. + }
  219696. + case MXCFB_SET_DIFMT:
  219697. + {
  219698. + struct mxcfb_info *mxc_fbi =
  219699. + (struct mxcfb_info *)fbi->par;
  219700. +
  219701. + if (get_user(mxc_fbi->ipu_di_pix_fmt, argp))
  219702. + return -EFAULT;
  219703. +
  219704. + break;
  219705. + }
  219706. + case MXCFB_CSC_UPDATE:
  219707. + {
  219708. + struct mxcfb_csc_matrix csc;
  219709. +
  219710. + if (copy_from_user(&csc, (void *) arg, sizeof(csc)))
  219711. + return -EFAULT;
  219712. +
  219713. + if ((mxc_fbi->ipu_ch != MEM_FG_SYNC) &&
  219714. + (mxc_fbi->ipu_ch != MEM_BG_SYNC) &&
  219715. + (mxc_fbi->ipu_ch != MEM_BG_ASYNC0))
  219716. + return -EFAULT;
  219717. + ipu_set_csc_coefficients(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219718. + csc.param);
  219719. + }
  219720. + default:
  219721. + retval = -EINVAL;
  219722. + }
  219723. + return retval;
  219724. +}
  219725. +
  219726. +/*
  219727. + * mxcfb_blank():
  219728. + * Blank the display.
  219729. + */
  219730. +static int mxcfb_blank(int blank, struct fb_info *info)
  219731. +{
  219732. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par;
  219733. + int ret = 0;
  219734. +
  219735. + dev_dbg(info->device, "blank = %d\n", blank);
  219736. +
  219737. + if (mxc_fbi->cur_blank == blank)
  219738. + return 0;
  219739. +
  219740. + mxc_fbi->next_blank = blank;
  219741. +
  219742. + switch (blank) {
  219743. + case FB_BLANK_POWERDOWN:
  219744. + case FB_BLANK_VSYNC_SUSPEND:
  219745. + case FB_BLANK_HSYNC_SUSPEND:
  219746. + case FB_BLANK_NORMAL:
  219747. + if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->disable)
  219748. + mxc_fbi->dispdrv->drv->disable(mxc_fbi->dispdrv);
  219749. + ipu_disable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch, true);
  219750. + if (mxc_fbi->ipu_di >= 0)
  219751. + ipu_uninit_sync_panel(mxc_fbi->ipu, mxc_fbi->ipu_di);
  219752. + ipu_uninit_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
  219753. + break;
  219754. + case FB_BLANK_UNBLANK:
  219755. + info->var.activate = (info->var.activate & ~FB_ACTIVATE_MASK) |
  219756. + FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
  219757. + ret = mxcfb_set_par(info);
  219758. + break;
  219759. + }
  219760. + if (!ret)
  219761. + mxc_fbi->cur_blank = blank;
  219762. + return ret;
  219763. +}
  219764. +
  219765. +/*
  219766. + * Pan or Wrap the Display
  219767. + *
  219768. + * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
  219769. + *
  219770. + * @param var Variable screen buffer information
  219771. + * @param info Framebuffer information pointer
  219772. + */
  219773. +static int
  219774. +mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
  219775. +{
  219776. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par,
  219777. + *mxc_graphic_fbi = NULL;
  219778. + u_int y_bottom;
  219779. + unsigned int fr_xoff, fr_yoff, fr_w, fr_h;
  219780. + unsigned long base, active_alpha_phy_addr = 0;
  219781. + bool loc_alpha_en = false;
  219782. + int fb_stride;
  219783. + int i;
  219784. + int ret;
  219785. +
  219786. + /* no pan display during fb blank */
  219787. + if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  219788. + struct mxcfb_info *bg_mxcfbi = NULL;
  219789. + struct fb_info *fbi_tmp;
  219790. +
  219791. + fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
  219792. + if (fbi_tmp)
  219793. + bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
  219794. + if (!bg_mxcfbi)
  219795. + return -EINVAL;
  219796. + if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK)
  219797. + return -EINVAL;
  219798. + }
  219799. + if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK)
  219800. + return -EINVAL;
  219801. +
  219802. + y_bottom = var->yoffset;
  219803. +
  219804. + if (y_bottom > info->var.yres_virtual)
  219805. + return -EINVAL;
  219806. +
  219807. + switch (fbi_to_pixfmt(info)) {
  219808. + case IPU_PIX_FMT_YUV420P2:
  219809. + case IPU_PIX_FMT_YVU420P:
  219810. + case IPU_PIX_FMT_NV12:
  219811. + case IPU_PIX_FMT_YUV422P:
  219812. + case IPU_PIX_FMT_YVU422P:
  219813. + case IPU_PIX_FMT_YUV420P:
  219814. + case IPU_PIX_FMT_YUV444P:
  219815. + fb_stride = info->var.xres_virtual;
  219816. + break;
  219817. + default:
  219818. + fb_stride = info->fix.line_length;
  219819. + }
  219820. +
  219821. + base = info->fix.smem_start;
  219822. + fr_xoff = var->xoffset;
  219823. + fr_w = info->var.xres_virtual;
  219824. + if (!(var->vmode & FB_VMODE_YWRAP)) {
  219825. + dev_dbg(info->device, "Y wrap disabled\n");
  219826. + fr_yoff = var->yoffset % info->var.yres;
  219827. + fr_h = info->var.yres;
  219828. + base += info->fix.line_length * info->var.yres *
  219829. + (var->yoffset / info->var.yres);
  219830. + } else {
  219831. + dev_dbg(info->device, "Y wrap enabled\n");
  219832. + fr_yoff = var->yoffset;
  219833. + fr_h = info->var.yres_virtual;
  219834. + }
  219835. + base += fr_yoff * fb_stride + fr_xoff;
  219836. +
  219837. + /* Check if DP local alpha is enabled and find the graphic fb */
  219838. + if (mxc_fbi->ipu_ch == MEM_BG_SYNC || mxc_fbi->ipu_ch == MEM_FG_SYNC) {
  219839. + for (i = 0; i < num_registered_fb; i++) {
  219840. + char bg_id[] = "DISP3 BG";
  219841. + char fg_id[] = "DISP3 FG";
  219842. + char *idstr = registered_fb[i]->fix.id;
  219843. + bg_id[4] += mxc_fbi->ipu_id;
  219844. + fg_id[4] += mxc_fbi->ipu_id;
  219845. + if ((strcmp(idstr, bg_id) == 0 ||
  219846. + strcmp(idstr, fg_id) == 0) &&
  219847. + ((struct mxcfb_info *)
  219848. + (registered_fb[i]->par))->alpha_chan_en) {
  219849. + loc_alpha_en = true;
  219850. + mxc_graphic_fbi = (struct mxcfb_info *)
  219851. + (registered_fb[i]->par);
  219852. + active_alpha_phy_addr =
  219853. + mxc_fbi->cur_ipu_alpha_buf ?
  219854. + mxc_graphic_fbi->alpha_phy_addr1 :
  219855. + mxc_graphic_fbi->alpha_phy_addr0;
  219856. + dev_dbg(info->device, "Updating SDC alpha "
  219857. + "buf %d address=0x%08lX\n",
  219858. + !mxc_fbi->cur_ipu_alpha_buf,
  219859. + active_alpha_phy_addr);
  219860. + break;
  219861. + }
  219862. + }
  219863. + }
  219864. +
  219865. + ret = wait_for_completion_timeout(&mxc_fbi->flip_complete, HZ/2);
  219866. + if (ret == 0) {
  219867. + dev_err(info->device, "timeout when waiting for flip irq\n");
  219868. + return -ETIMEDOUT;
  219869. + }
  219870. +
  219871. + ++mxc_fbi->cur_ipu_buf;
  219872. + mxc_fbi->cur_ipu_buf %= 3;
  219873. + mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
  219874. +
  219875. + dev_dbg(info->device, "Updating SDC %s buf %d address=0x%08lX\n",
  219876. + info->fix.id, mxc_fbi->cur_ipu_buf, base);
  219877. +
  219878. + if (ipu_update_channel_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  219879. + mxc_fbi->cur_ipu_buf, base) == 0) {
  219880. + /* Update the DP local alpha buffer only for graphic plane */
  219881. + if (loc_alpha_en && mxc_graphic_fbi == mxc_fbi &&
  219882. + ipu_update_channel_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
  219883. + IPU_ALPHA_IN_BUFFER,
  219884. + mxc_fbi->cur_ipu_alpha_buf,
  219885. + active_alpha_phy_addr) == 0) {
  219886. + ipu_select_buffer(mxc_graphic_fbi->ipu, mxc_graphic_fbi->ipu_ch,
  219887. + IPU_ALPHA_IN_BUFFER,
  219888. + mxc_fbi->cur_ipu_alpha_buf);
  219889. + }
  219890. +
  219891. + /* update u/v offset */
  219892. + ipu_update_channel_offset(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219893. + IPU_INPUT_BUFFER,
  219894. + fbi_to_pixfmt(info),
  219895. + fr_w,
  219896. + fr_h,
  219897. + fr_w,
  219898. + 0, 0,
  219899. + fr_yoff,
  219900. + fr_xoff);
  219901. +
  219902. + ipu_select_buffer(mxc_fbi->ipu, mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
  219903. + mxc_fbi->cur_ipu_buf);
  219904. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  219905. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  219906. + } else {
  219907. + dev_err(info->device,
  219908. + "Error updating SDC buf %d to address=0x%08lX, "
  219909. + "current buf %d, buf0 ready %d, buf1 ready %d, "
  219910. + "buf2 ready %d\n", mxc_fbi->cur_ipu_buf, base,
  219911. + ipu_get_cur_buffer_idx(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219912. + IPU_INPUT_BUFFER),
  219913. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219914. + IPU_INPUT_BUFFER, 0),
  219915. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219916. + IPU_INPUT_BUFFER, 1),
  219917. + ipu_check_buffer_ready(mxc_fbi->ipu, mxc_fbi->ipu_ch,
  219918. + IPU_INPUT_BUFFER, 2));
  219919. + ++mxc_fbi->cur_ipu_buf;
  219920. + mxc_fbi->cur_ipu_buf %= 3;
  219921. + ++mxc_fbi->cur_ipu_buf;
  219922. + mxc_fbi->cur_ipu_buf %= 3;
  219923. + mxc_fbi->cur_ipu_alpha_buf = !mxc_fbi->cur_ipu_alpha_buf;
  219924. + ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  219925. + ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
  219926. + return -EBUSY;
  219927. + }
  219928. +
  219929. + dev_dbg(info->device, "Update complete\n");
  219930. +
  219931. + info->var.yoffset = var->yoffset;
  219932. +
  219933. + return 0;
  219934. +}
  219935. +
  219936. +/*
  219937. + * Function to handle custom mmap for MXC framebuffer.
  219938. + *
  219939. + * @param fbi framebuffer information pointer
  219940. + *
  219941. + * @param vma Pointer to vm_area_struct
  219942. + */
  219943. +static int mxcfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
  219944. +{
  219945. + bool found = false;
  219946. + u32 len;
  219947. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  219948. + struct mxcfb_alloc_list *mem;
  219949. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  219950. +
  219951. + if (offset < fbi->fix.smem_len) {
  219952. + /* mapping framebuffer memory */
  219953. + len = fbi->fix.smem_len - offset;
  219954. + vma->vm_pgoff = (fbi->fix.smem_start + offset) >> PAGE_SHIFT;
  219955. + } else if ((vma->vm_pgoff ==
  219956. + (mxc_fbi->alpha_phy_addr0 >> PAGE_SHIFT)) ||
  219957. + (vma->vm_pgoff ==
  219958. + (mxc_fbi->alpha_phy_addr1 >> PAGE_SHIFT))) {
  219959. + len = mxc_fbi->alpha_mem_len;
  219960. + } else {
  219961. + list_for_each_entry(mem, &fb_alloc_list, list) {
  219962. + if (offset == mem->phy_addr) {
  219963. + found = true;
  219964. + len = mem->size;
  219965. + break;
  219966. + }
  219967. + }
  219968. + if (!found)
  219969. + return -EINVAL;
  219970. + }
  219971. +
  219972. + len = PAGE_ALIGN(len);
  219973. + if (vma->vm_end - vma->vm_start > len)
  219974. + return -EINVAL;
  219975. +
  219976. + /* make buffers bufferable */
  219977. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  219978. +
  219979. + vma->vm_flags |= VM_IO;
  219980. +
  219981. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  219982. + vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
  219983. + dev_dbg(fbi->device, "mmap remap_pfn_range failed\n");
  219984. + return -ENOBUFS;
  219985. + }
  219986. +
  219987. + return 0;
  219988. +}
  219989. +
  219990. +/*!
  219991. + * This structure contains the pointers to the control functions that are
  219992. + * invoked by the core framebuffer driver to perform operations like
  219993. + * blitting, rectangle filling, copy regions and cursor definition.
  219994. + */
  219995. +static struct fb_ops mxcfb_ops = {
  219996. + .owner = THIS_MODULE,
  219997. + .fb_set_par = mxcfb_set_par,
  219998. + .fb_check_var = mxcfb_check_var,
  219999. + .fb_setcolreg = mxcfb_setcolreg,
  220000. + .fb_pan_display = mxcfb_pan_display,
  220001. + .fb_ioctl = mxcfb_ioctl,
  220002. + .fb_mmap = mxcfb_mmap,
  220003. + .fb_fillrect = cfb_fillrect,
  220004. + .fb_copyarea = cfb_copyarea,
  220005. + .fb_imageblit = cfb_imageblit,
  220006. + .fb_blank = mxcfb_blank,
  220007. +};
  220008. +
  220009. +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id)
  220010. +{
  220011. + struct fb_info *fbi = dev_id;
  220012. + struct mxcfb_info *mxc_fbi = fbi->par;
  220013. +
  220014. + complete(&mxc_fbi->flip_complete);
  220015. + return IRQ_HANDLED;
  220016. +}
  220017. +
  220018. +static irqreturn_t mxcfb_nf_irq_handler(int irq, void *dev_id)
  220019. +{
  220020. + struct fb_info *fbi = dev_id;
  220021. + struct mxcfb_info *mxc_fbi = fbi->par;
  220022. +
  220023. + complete(&mxc_fbi->vsync_complete);
  220024. + return IRQ_HANDLED;
  220025. +}
  220026. +
  220027. +static irqreturn_t mxcfb_alpha_irq_handler(int irq, void *dev_id)
  220028. +{
  220029. + struct fb_info *fbi = dev_id;
  220030. + struct mxcfb_info *mxc_fbi = fbi->par;
  220031. +
  220032. + complete(&mxc_fbi->alpha_flip_complete);
  220033. + return IRQ_HANDLED;
  220034. +}
  220035. +
  220036. +/*
  220037. + * Suspends the framebuffer and blanks the screen. Power management support
  220038. + */
  220039. +static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
  220040. +{
  220041. + struct fb_info *fbi = platform_get_drvdata(pdev);
  220042. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  220043. + int saved_blank;
  220044. +#ifdef CONFIG_FB_MXC_LOW_PWR_DISPLAY
  220045. + void *fbmem;
  220046. +#endif
  220047. +
  220048. + if (mxc_fbi->ovfbi) {
  220049. + struct mxcfb_info *mxc_fbi_fg =
  220050. + (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  220051. +
  220052. + console_lock();
  220053. + fb_set_suspend(mxc_fbi->ovfbi, 1);
  220054. + saved_blank = mxc_fbi_fg->cur_blank;
  220055. + mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
  220056. + mxc_fbi_fg->next_blank = saved_blank;
  220057. + console_unlock();
  220058. + }
  220059. +
  220060. + console_lock();
  220061. + fb_set_suspend(fbi, 1);
  220062. + saved_blank = mxc_fbi->cur_blank;
  220063. + mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
  220064. + mxc_fbi->next_blank = saved_blank;
  220065. + console_unlock();
  220066. +
  220067. + return 0;
  220068. +}
  220069. +
  220070. +/*
  220071. + * Resumes the framebuffer and unblanks the screen. Power management support
  220072. + */
  220073. +static int mxcfb_resume(struct platform_device *pdev)
  220074. +{
  220075. + struct fb_info *fbi = platform_get_drvdata(pdev);
  220076. + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
  220077. +
  220078. + console_lock();
  220079. + mxcfb_blank(mxc_fbi->next_blank, fbi);
  220080. + fb_set_suspend(fbi, 0);
  220081. + console_unlock();
  220082. +
  220083. + if (mxc_fbi->ovfbi) {
  220084. + struct mxcfb_info *mxc_fbi_fg =
  220085. + (struct mxcfb_info *)mxc_fbi->ovfbi->par;
  220086. + console_lock();
  220087. + mxcfb_blank(mxc_fbi_fg->next_blank, mxc_fbi->ovfbi);
  220088. + fb_set_suspend(mxc_fbi->ovfbi, 0);
  220089. + console_unlock();
  220090. + }
  220091. +
  220092. + return 0;
  220093. +}
  220094. +
  220095. +/*
  220096. + * Main framebuffer functions
  220097. + */
  220098. +
  220099. +/*!
  220100. + * Allocates the DRAM memory for the frame buffer. This buffer is remapped
  220101. + * into a non-cached, non-buffered, memory region to allow palette and pixel
  220102. + * writes to occur without flushing the cache. Once this area is remapped,
  220103. + * all virtual memory access to the video memory should occur at the new region.
  220104. + *
  220105. + * @param fbi framebuffer information pointer
  220106. + *
  220107. + * @return Error code indicating success or failure
  220108. + */
  220109. +static int mxcfb_map_video_memory(struct fb_info *fbi)
  220110. +{
  220111. + if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
  220112. + fbi->fix.smem_len = fbi->var.yres_virtual *
  220113. + fbi->fix.line_length;
  220114. +
  220115. + fbi->screen_base = dma_alloc_writecombine(fbi->device,
  220116. + fbi->fix.smem_len,
  220117. + (dma_addr_t *)&fbi->fix.smem_start,
  220118. + GFP_DMA | GFP_KERNEL);
  220119. + if (fbi->screen_base == 0) {
  220120. + dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
  220121. + fbi->fix.smem_len = 0;
  220122. + fbi->fix.smem_start = 0;
  220123. + return -EBUSY;
  220124. + }
  220125. +
  220126. + dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
  220127. + (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
  220128. +
  220129. + fbi->screen_size = fbi->fix.smem_len;
  220130. +
  220131. + /* Clear the screen */
  220132. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  220133. +
  220134. + return 0;
  220135. +}
  220136. +
  220137. +/*!
  220138. + * De-allocates the DRAM memory for the frame buffer.
  220139. + *
  220140. + * @param fbi framebuffer information pointer
  220141. + *
  220142. + * @return Error code indicating success or failure
  220143. + */
  220144. +static int mxcfb_unmap_video_memory(struct fb_info *fbi)
  220145. +{
  220146. + dma_free_writecombine(fbi->device, fbi->fix.smem_len,
  220147. + fbi->screen_base, fbi->fix.smem_start);
  220148. + fbi->screen_base = 0;
  220149. + fbi->fix.smem_start = 0;
  220150. + fbi->fix.smem_len = 0;
  220151. + return 0;
  220152. +}
  220153. +
  220154. +/*!
  220155. + * Initializes the framebuffer information pointer. After allocating
  220156. + * sufficient memory for the framebuffer structure, the fields are
  220157. + * filled with custom information passed in from the configurable
  220158. + * structures. This includes information such as bits per pixel,
  220159. + * color maps, screen width/height and RGBA offsets.
  220160. + *
  220161. + * @return Framebuffer structure initialized with our information
  220162. + */
  220163. +static struct fb_info *mxcfb_init_fbinfo(struct device *dev, struct fb_ops *ops)
  220164. +{
  220165. + struct fb_info *fbi;
  220166. + struct mxcfb_info *mxcfbi;
  220167. +
  220168. + /*
  220169. + * Allocate sufficient memory for the fb structure
  220170. + */
  220171. + fbi = framebuffer_alloc(sizeof(struct mxcfb_info), dev);
  220172. + if (!fbi)
  220173. + return NULL;
  220174. +
  220175. + mxcfbi = (struct mxcfb_info *)fbi->par;
  220176. +
  220177. + fbi->var.activate = FB_ACTIVATE_NOW;
  220178. +
  220179. + fbi->fbops = ops;
  220180. + fbi->flags = FBINFO_FLAG_DEFAULT;
  220181. + fbi->pseudo_palette = mxcfbi->pseudo_palette;
  220182. +
  220183. + /*
  220184. + * Allocate colormap
  220185. + */
  220186. + fb_alloc_cmap(&fbi->cmap, 16, 0);
  220187. +
  220188. + return fbi;
  220189. +}
  220190. +
  220191. +static ssize_t show_disp_chan(struct device *dev,
  220192. + struct device_attribute *attr, char *buf)
  220193. +{
  220194. + struct fb_info *info = dev_get_drvdata(dev);
  220195. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  220196. +
  220197. + if (mxcfbi->ipu_ch == MEM_BG_SYNC)
  220198. + return sprintf(buf, "2-layer-fb-bg\n");
  220199. + else if (mxcfbi->ipu_ch == MEM_FG_SYNC)
  220200. + return sprintf(buf, "2-layer-fb-fg\n");
  220201. + else if (mxcfbi->ipu_ch == MEM_DC_SYNC)
  220202. + return sprintf(buf, "1-layer-fb\n");
  220203. + else
  220204. + return sprintf(buf, "err: no display chan\n");
  220205. +}
  220206. +
  220207. +static ssize_t swap_disp_chan(struct device *dev,
  220208. + struct device_attribute *attr,
  220209. + const char *buf, size_t count)
  220210. +{
  220211. + struct fb_info *info = dev_get_drvdata(dev);
  220212. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  220213. + struct mxcfb_info *fg_mxcfbi = NULL;
  220214. +
  220215. + console_lock();
  220216. + /* swap only happen between DP-BG and DC, while DP-FG disable */
  220217. + if (((mxcfbi->ipu_ch == MEM_BG_SYNC) &&
  220218. + (strstr(buf, "1-layer-fb") != NULL)) ||
  220219. + ((mxcfbi->ipu_ch == MEM_DC_SYNC) &&
  220220. + (strstr(buf, "2-layer-fb-bg") != NULL))) {
  220221. + struct fb_info *fbi_fg;
  220222. +
  220223. + fbi_fg = found_registered_fb(MEM_FG_SYNC, mxcfbi->ipu_id);
  220224. + if (fbi_fg)
  220225. + fg_mxcfbi = (struct mxcfb_info *)fbi_fg->par;
  220226. +
  220227. + if (!fg_mxcfbi ||
  220228. + fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {
  220229. + dev_err(dev,
  220230. + "Can not switch while fb2(fb-fg) is on.\n");
  220231. + console_unlock();
  220232. + return count;
  220233. + }
  220234. +
  220235. + if (swap_channels(info) < 0)
  220236. + dev_err(dev, "Swap display channel failed.\n");
  220237. + }
  220238. +
  220239. + console_unlock();
  220240. + return count;
  220241. +}
  220242. +static DEVICE_ATTR(fsl_disp_property, S_IWUSR | S_IRUGO,
  220243. + show_disp_chan, swap_disp_chan);
  220244. +
  220245. +static ssize_t show_disp_dev(struct device *dev,
  220246. + struct device_attribute *attr, char *buf)
  220247. +{
  220248. + struct fb_info *info = dev_get_drvdata(dev);
  220249. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
  220250. +
  220251. + if (mxcfbi->ipu_ch == MEM_FG_SYNC)
  220252. + return sprintf(buf, "overlay\n");
  220253. + else
  220254. + return sprintf(buf, "%s\n", mxcfbi->dispdrv->drv->name);
  220255. +}
  220256. +static DEVICE_ATTR(fsl_disp_dev_property, S_IRUGO, show_disp_dev, NULL);
  220257. +
  220258. +static int mxcfb_dispdrv_init(struct platform_device *pdev,
  220259. + struct fb_info *fbi)
  220260. +{
  220261. + struct ipuv3_fb_platform_data *plat_data = pdev->dev.platform_data;
  220262. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  220263. + struct mxc_dispdrv_setting setting;
  220264. + char disp_dev[32], *default_dev = "lcd";
  220265. + int ret = 0;
  220266. +
  220267. + setting.if_fmt = plat_data->interface_pix_fmt;
  220268. + setting.dft_mode_str = plat_data->mode_str;
  220269. + setting.default_bpp = plat_data->default_bpp;
  220270. + if (!setting.default_bpp)
  220271. + setting.default_bpp = 16;
  220272. + setting.fbi = fbi;
  220273. + if (!strlen(plat_data->disp_dev)) {
  220274. + memcpy(disp_dev, default_dev, strlen(default_dev));
  220275. + disp_dev[strlen(default_dev)] = '\0';
  220276. + } else {
  220277. + memcpy(disp_dev, plat_data->disp_dev,
  220278. + strlen(plat_data->disp_dev));
  220279. + disp_dev[strlen(plat_data->disp_dev)] = '\0';
  220280. + }
  220281. +
  220282. + dev_info(&pdev->dev, "register mxc display driver %s\n", disp_dev);
  220283. +
  220284. + mxcfbi->dispdrv = mxc_dispdrv_gethandle(disp_dev, &setting);
  220285. + if (IS_ERR(mxcfbi->dispdrv)) {
  220286. + ret = PTR_ERR(mxcfbi->dispdrv);
  220287. + dev_err(&pdev->dev, "NO mxc display driver found!\n");
  220288. + return ret;
  220289. + } else {
  220290. + /* fix-up */
  220291. + mxcfbi->ipu_di_pix_fmt = setting.if_fmt;
  220292. + mxcfbi->default_bpp = setting.default_bpp;
  220293. +
  220294. + /* setting */
  220295. + mxcfbi->ipu_id = setting.dev_id;
  220296. + mxcfbi->ipu_di = setting.disp_id;
  220297. + dev_dbg(&pdev->dev, "di_pixfmt:0x%x, bpp:0x%x, di:%d, ipu:%d\n",
  220298. + setting.if_fmt, setting.default_bpp,
  220299. + setting.disp_id, setting.dev_id);
  220300. + }
  220301. +
  220302. + return ret;
  220303. +}
  220304. +
  220305. +/*
  220306. + * Parse user specified options (`video=trident:')
  220307. + * example:
  220308. + * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,bpp=16,noaccel
  220309. + * video=mxcfb0:dev=lcd,800x480M-16@55,if=RGB565,fbpix=RGB565
  220310. + */
  220311. +static int mxcfb_option_setup(struct platform_device *pdev, struct fb_info *fbi)
  220312. +{
  220313. + struct ipuv3_fb_platform_data *pdata = pdev->dev.platform_data;
  220314. + char *options, *opt, *fb_mode_str = NULL;
  220315. + char name[] = "mxcfb0";
  220316. + uint32_t fb_pix_fmt = 0;
  220317. +
  220318. + name[5] += pdev->id;
  220319. + if (fb_get_options(name, &options)) {
  220320. + dev_err(&pdev->dev, "Can't get fb option for %s!\n", name);
  220321. + return -ENODEV;
  220322. + }
  220323. +
  220324. + if (!options || !*options)
  220325. + return 0;
  220326. +
  220327. + while ((opt = strsep(&options, ",")) != NULL) {
  220328. + if (!*opt)
  220329. + continue;
  220330. +
  220331. + if (!strncmp(opt, "dev=", 4)) {
  220332. + memcpy(pdata->disp_dev, opt + 4, strlen(opt) - 4);
  220333. + pdata->disp_dev[strlen(opt) - 4] = '\0';
  220334. + } else if (!strncmp(opt, "if=", 3)) {
  220335. + if (!strncmp(opt+3, "RGB24", 5))
  220336. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB24;
  220337. + else if (!strncmp(opt+3, "BGR24", 5))
  220338. + pdata->interface_pix_fmt = IPU_PIX_FMT_BGR24;
  220339. + else if (!strncmp(opt+3, "GBR24", 5))
  220340. + pdata->interface_pix_fmt = IPU_PIX_FMT_GBR24;
  220341. + else if (!strncmp(opt+3, "RGB565", 6))
  220342. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB565;
  220343. + else if (!strncmp(opt+3, "RGB666", 6))
  220344. + pdata->interface_pix_fmt = IPU_PIX_FMT_RGB666;
  220345. + else if (!strncmp(opt+3, "YUV444", 6))
  220346. + pdata->interface_pix_fmt = IPU_PIX_FMT_YUV444;
  220347. + else if (!strncmp(opt+3, "LVDS666", 7))
  220348. + pdata->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
  220349. + else if (!strncmp(opt+3, "YUYV16", 6))
  220350. + pdata->interface_pix_fmt = IPU_PIX_FMT_YUYV;
  220351. + else if (!strncmp(opt+3, "UYVY16", 6))
  220352. + pdata->interface_pix_fmt = IPU_PIX_FMT_UYVY;
  220353. + else if (!strncmp(opt+3, "YVYU16", 6))
  220354. + pdata->interface_pix_fmt = IPU_PIX_FMT_YVYU;
  220355. + else if (!strncmp(opt+3, "VYUY16", 6))
  220356. + pdata->interface_pix_fmt = IPU_PIX_FMT_VYUY;
  220357. + } else if (!strncmp(opt, "fbpix=", 6)) {
  220358. + if (!strncmp(opt+6, "RGB24", 5))
  220359. + fb_pix_fmt = IPU_PIX_FMT_RGB24;
  220360. + else if (!strncmp(opt+6, "BGR24", 5))
  220361. + fb_pix_fmt = IPU_PIX_FMT_BGR24;
  220362. + else if (!strncmp(opt+6, "RGB32", 5))
  220363. + fb_pix_fmt = IPU_PIX_FMT_RGB32;
  220364. + else if (!strncmp(opt+6, "BGR32", 5))
  220365. + fb_pix_fmt = IPU_PIX_FMT_BGR32;
  220366. + else if (!strncmp(opt+6, "ABGR32", 6))
  220367. + fb_pix_fmt = IPU_PIX_FMT_ABGR32;
  220368. + else if (!strncmp(opt+6, "RGB565", 6))
  220369. + fb_pix_fmt = IPU_PIX_FMT_RGB565;
  220370. +
  220371. + if (fb_pix_fmt) {
  220372. + pixfmt_to_var(fb_pix_fmt, &fbi->var);
  220373. + pdata->default_bpp =
  220374. + fbi->var.bits_per_pixel;
  220375. + }
  220376. + } else if (!strncmp(opt, "int_clk", 7)) {
  220377. + pdata->int_clk = true;
  220378. + continue;
  220379. + } else if (!strncmp(opt, "bpp=", 4)) {
  220380. + /* bpp setting cannot overwirte fbpix setting */
  220381. + if (fb_pix_fmt)
  220382. + continue;
  220383. +
  220384. + pdata->default_bpp =
  220385. + simple_strtoul(opt + 4, NULL, 0);
  220386. +
  220387. + fb_pix_fmt = bpp_to_pixfmt(pdata->default_bpp);
  220388. + if (fb_pix_fmt)
  220389. + pixfmt_to_var(fb_pix_fmt, &fbi->var);
  220390. + } else
  220391. + fb_mode_str = opt;
  220392. + }
  220393. +
  220394. + if (fb_mode_str)
  220395. + pdata->mode_str = fb_mode_str;
  220396. +
  220397. + return 0;
  220398. +}
  220399. +
  220400. +static int mxcfb_register(struct fb_info *fbi)
  220401. +{
  220402. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  220403. + struct fb_videomode m;
  220404. + int ret = 0;
  220405. + char bg0_id[] = "DISP3 BG";
  220406. + char bg1_id[] = "DISP3 BG - DI1";
  220407. + char fg_id[] = "DISP3 FG";
  220408. +
  220409. + if (mxcfbi->ipu_di == 0) {
  220410. + bg0_id[4] += mxcfbi->ipu_id;
  220411. + strcpy(fbi->fix.id, bg0_id);
  220412. + } else if (mxcfbi->ipu_di == 1) {
  220413. + bg1_id[4] += mxcfbi->ipu_id;
  220414. + strcpy(fbi->fix.id, bg1_id);
  220415. + } else { /* Overlay */
  220416. + fg_id[4] += mxcfbi->ipu_id;
  220417. + strcpy(fbi->fix.id, fg_id);
  220418. + }
  220419. +
  220420. + mxcfb_check_var(&fbi->var, fbi);
  220421. +
  220422. + mxcfb_set_fix(fbi);
  220423. +
  220424. + /* Added first mode to fbi modelist. */
  220425. + if (!fbi->modelist.next || !fbi->modelist.prev)
  220426. + INIT_LIST_HEAD(&fbi->modelist);
  220427. + fb_var_to_videomode(&m, &fbi->var);
  220428. + fb_add_videomode(&m, &fbi->modelist);
  220429. +
  220430. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq,
  220431. + mxcfb_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
  220432. + dev_err(fbi->device, "Error registering EOF irq handler.\n");
  220433. + ret = -EBUSY;
  220434. + goto err0;
  220435. + }
  220436. + ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq);
  220437. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq,
  220438. + mxcfb_nf_irq_handler, IPU_IRQF_ONESHOT, MXCFB_NAME, fbi) != 0) {
  220439. + dev_err(fbi->device, "Error registering NFACK irq handler.\n");
  220440. + ret = -EBUSY;
  220441. + goto err1;
  220442. + }
  220443. + ipu_disable_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq);
  220444. +
  220445. + if (mxcfbi->ipu_alp_ch_irq != -1)
  220446. + if (ipu_request_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq,
  220447. + mxcfb_alpha_irq_handler, IPU_IRQF_ONESHOT,
  220448. + MXCFB_NAME, fbi) != 0) {
  220449. + dev_err(fbi->device, "Error registering alpha irq "
  220450. + "handler.\n");
  220451. + ret = -EBUSY;
  220452. + goto err2;
  220453. + }
  220454. +
  220455. + if (!mxcfbi->late_init) {
  220456. + fbi->var.activate |= FB_ACTIVATE_FORCE;
  220457. + console_lock();
  220458. + fbi->flags |= FBINFO_MISC_USEREVENT;
  220459. + ret = fb_set_var(fbi, &fbi->var);
  220460. + fbi->flags &= ~FBINFO_MISC_USEREVENT;
  220461. + console_unlock();
  220462. + if (ret < 0) {
  220463. + dev_err(fbi->device, "Error fb_set_var ret:%d\n", ret);
  220464. + goto err3;
  220465. + }
  220466. +
  220467. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  220468. + console_lock();
  220469. + ret = fb_blank(fbi, FB_BLANK_UNBLANK);
  220470. + console_unlock();
  220471. + if (ret < 0) {
  220472. + dev_err(fbi->device,
  220473. + "Error fb_blank ret:%d\n", ret);
  220474. + goto err4;
  220475. + }
  220476. + }
  220477. + } else {
  220478. + /*
  220479. + * Setup the channel again though bootloader
  220480. + * has done this, then set_par() can stop the
  220481. + * channel neatly and re-initialize it .
  220482. + */
  220483. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  220484. + console_lock();
  220485. + _setup_disp_channel1(fbi);
  220486. + ipu_enable_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
  220487. + console_unlock();
  220488. + }
  220489. + }
  220490. +
  220491. +
  220492. + ret = register_framebuffer(fbi);
  220493. + if (ret < 0)
  220494. + goto err5;
  220495. +
  220496. + return ret;
  220497. +err5:
  220498. + if (mxcfbi->next_blank == FB_BLANK_UNBLANK) {
  220499. + console_lock();
  220500. + if (!mxcfbi->late_init)
  220501. + fb_blank(fbi, FB_BLANK_POWERDOWN);
  220502. + else {
  220503. + ipu_disable_channel(mxcfbi->ipu, mxcfbi->ipu_ch,
  220504. + true);
  220505. + ipu_uninit_channel(mxcfbi->ipu, mxcfbi->ipu_ch);
  220506. + }
  220507. + console_unlock();
  220508. + }
  220509. +err4:
  220510. +err3:
  220511. + if (mxcfbi->ipu_alp_ch_irq != -1)
  220512. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
  220513. +err2:
  220514. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
  220515. +err1:
  220516. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
  220517. +err0:
  220518. + return ret;
  220519. +}
  220520. +
  220521. +static void mxcfb_unregister(struct fb_info *fbi)
  220522. +{
  220523. + struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
  220524. +
  220525. + if (mxcfbi->ipu_alp_ch_irq != -1)
  220526. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_alp_ch_irq, fbi);
  220527. + if (mxcfbi->ipu_ch_irq)
  220528. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_irq, fbi);
  220529. + if (mxcfbi->ipu_ch_nf_irq)
  220530. + ipu_free_irq(mxcfbi->ipu, mxcfbi->ipu_ch_nf_irq, fbi);
  220531. +
  220532. + unregister_framebuffer(fbi);
  220533. +}
  220534. +
  220535. +static int mxcfb_setup_overlay(struct platform_device *pdev,
  220536. + struct fb_info *fbi_bg, struct resource *res)
  220537. +{
  220538. + struct fb_info *ovfbi;
  220539. + struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
  220540. + struct mxcfb_info *mxcfbi_fg;
  220541. + int ret = 0;
  220542. +
  220543. + ovfbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
  220544. + if (!ovfbi) {
  220545. + ret = -ENOMEM;
  220546. + goto init_ovfbinfo_failed;
  220547. + }
  220548. + mxcfbi_fg = (struct mxcfb_info *)ovfbi->par;
  220549. +
  220550. + mxcfbi_fg->ipu = ipu_get_soc(mxcfbi_bg->ipu_id);
  220551. + if (IS_ERR(mxcfbi_fg->ipu)) {
  220552. + ret = -ENODEV;
  220553. + goto get_ipu_failed;
  220554. + }
  220555. + mxcfbi_fg->ipu_id = mxcfbi_bg->ipu_id;
  220556. + mxcfbi_fg->ipu_ch_irq = IPU_IRQ_FG_SYNC_EOF;
  220557. + mxcfbi_fg->ipu_ch_nf_irq = IPU_IRQ_FG_SYNC_NFACK;
  220558. + mxcfbi_fg->ipu_alp_ch_irq = IPU_IRQ_FG_ALPHA_SYNC_EOF;
  220559. + mxcfbi_fg->ipu_ch = MEM_FG_SYNC;
  220560. + mxcfbi_fg->ipu_di = -1;
  220561. + mxcfbi_fg->ipu_di_pix_fmt = mxcfbi_bg->ipu_di_pix_fmt;
  220562. + mxcfbi_fg->overlay = true;
  220563. + mxcfbi_fg->cur_blank = mxcfbi_fg->next_blank = FB_BLANK_POWERDOWN;
  220564. +
  220565. + /* Need dummy values until real panel is configured */
  220566. + ovfbi->var.xres = 240;
  220567. + ovfbi->var.yres = 320;
  220568. +
  220569. + if (res && res->start && res->end) {
  220570. + ovfbi->fix.smem_len = res->end - res->start + 1;
  220571. + ovfbi->fix.smem_start = res->start;
  220572. + ovfbi->screen_base = ioremap(
  220573. + ovfbi->fix.smem_start,
  220574. + ovfbi->fix.smem_len);
  220575. + }
  220576. +
  220577. + ret = mxcfb_register(ovfbi);
  220578. + if (ret < 0)
  220579. + goto register_ov_failed;
  220580. +
  220581. + mxcfbi_bg->ovfbi = ovfbi;
  220582. +
  220583. + return ret;
  220584. +
  220585. +register_ov_failed:
  220586. +get_ipu_failed:
  220587. + fb_dealloc_cmap(&ovfbi->cmap);
  220588. + framebuffer_release(ovfbi);
  220589. +init_ovfbinfo_failed:
  220590. + return ret;
  220591. +}
  220592. +
  220593. +static void mxcfb_unsetup_overlay(struct fb_info *fbi_bg)
  220594. +{
  220595. + struct mxcfb_info *mxcfbi_bg = (struct mxcfb_info *)fbi_bg->par;
  220596. + struct fb_info *ovfbi = mxcfbi_bg->ovfbi;
  220597. +
  220598. + mxcfb_unregister(ovfbi);
  220599. +
  220600. + if (&ovfbi->cmap)
  220601. + fb_dealloc_cmap(&ovfbi->cmap);
  220602. + framebuffer_release(ovfbi);
  220603. +}
  220604. +
  220605. +static bool ipu_usage[2][2];
  220606. +static int ipu_test_set_usage(int ipu, int di)
  220607. +{
  220608. + if (ipu_usage[ipu][di])
  220609. + return -EBUSY;
  220610. + else
  220611. + ipu_usage[ipu][di] = true;
  220612. + return 0;
  220613. +}
  220614. +
  220615. +static void ipu_clear_usage(int ipu, int di)
  220616. +{
  220617. + ipu_usage[ipu][di] = false;
  220618. +}
  220619. +
  220620. +static int mxcfb_get_of_property(struct platform_device *pdev,
  220621. + struct ipuv3_fb_platform_data *plat_data)
  220622. +{
  220623. + struct device_node *np = pdev->dev.of_node;
  220624. + const char *disp_dev;
  220625. + const char *mode_str;
  220626. + const char *pixfmt;
  220627. + int err;
  220628. + int len;
  220629. + u32 bpp, int_clk;
  220630. + u32 late_init;
  220631. +
  220632. + err = of_property_read_string(np, "disp_dev", &disp_dev);
  220633. + if (err < 0) {
  220634. + dev_dbg(&pdev->dev, "get of property disp_dev fail\n");
  220635. + return err;
  220636. + }
  220637. + err = of_property_read_string(np, "mode_str", &mode_str);
  220638. + if (err < 0) {
  220639. + dev_dbg(&pdev->dev, "get of property mode_str fail\n");
  220640. + return err;
  220641. + }
  220642. + err = of_property_read_string(np, "interface_pix_fmt", &pixfmt);
  220643. + if (err) {
  220644. + dev_dbg(&pdev->dev, "get of property pix fmt fail\n");
  220645. + return err;
  220646. + }
  220647. + err = of_property_read_u32(np, "default_bpp", &bpp);
  220648. + if (err) {
  220649. + dev_dbg(&pdev->dev, "get of property bpp fail\n");
  220650. + return err;
  220651. + }
  220652. + err = of_property_read_u32(np, "int_clk", &int_clk);
  220653. + if (err) {
  220654. + dev_dbg(&pdev->dev, "get of property int_clk fail\n");
  220655. + return err;
  220656. + }
  220657. + err = of_property_read_u32(np, "late_init", &late_init);
  220658. + if (err) {
  220659. + dev_dbg(&pdev->dev, "get of property late_init fail\n");
  220660. + return err;
  220661. + }
  220662. +
  220663. + if (!strncmp(pixfmt, "RGB24", 5))
  220664. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB24;
  220665. + else if (!strncmp(pixfmt, "BGR24", 5))
  220666. + plat_data->interface_pix_fmt = IPU_PIX_FMT_BGR24;
  220667. + else if (!strncmp(pixfmt, "GBR24", 5))
  220668. + plat_data->interface_pix_fmt = IPU_PIX_FMT_GBR24;
  220669. + else if (!strncmp(pixfmt, "RGB565", 6))
  220670. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB565;
  220671. + else if (!strncmp(pixfmt, "RGB666", 6))
  220672. + plat_data->interface_pix_fmt = IPU_PIX_FMT_RGB666;
  220673. + else if (!strncmp(pixfmt, "YUV444", 6))
  220674. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YUV444;
  220675. + else if (!strncmp(pixfmt, "LVDS666", 7))
  220676. + plat_data->interface_pix_fmt = IPU_PIX_FMT_LVDS666;
  220677. + else if (!strncmp(pixfmt, "YUYV16", 6))
  220678. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YUYV;
  220679. + else if (!strncmp(pixfmt, "UYVY16", 6))
  220680. + plat_data->interface_pix_fmt = IPU_PIX_FMT_UYVY;
  220681. + else if (!strncmp(pixfmt, "YVYU16", 6))
  220682. + plat_data->interface_pix_fmt = IPU_PIX_FMT_YVYU;
  220683. + else if (!strncmp(pixfmt, "VYUY16", 6))
  220684. + plat_data->interface_pix_fmt = IPU_PIX_FMT_VYUY;
  220685. + else {
  220686. + dev_err(&pdev->dev, "err interface_pix_fmt!\n");
  220687. + return -ENOENT;
  220688. + }
  220689. +
  220690. + len = min(sizeof(plat_data->disp_dev) - 1, strlen(disp_dev));
  220691. + memcpy(plat_data->disp_dev, disp_dev, len);
  220692. + plat_data->disp_dev[len] = '\0';
  220693. + plat_data->mode_str = (char *)mode_str;
  220694. + plat_data->default_bpp = bpp;
  220695. + plat_data->int_clk = (bool)int_clk;
  220696. + plat_data->late_init = (bool)late_init;
  220697. + return err;
  220698. +}
  220699. +
  220700. +/*!
  220701. + * Probe routine for the framebuffer driver. It is called during the
  220702. + * driver binding process. The following functions are performed in
  220703. + * this routine: Framebuffer initialization, Memory allocation and
  220704. + * mapping, Framebuffer registration, IPU initialization.
  220705. + *
  220706. + * @return Appropriate error code to the kernel common code
  220707. + */
  220708. +static int mxcfb_probe(struct platform_device *pdev)
  220709. +{
  220710. + struct ipuv3_fb_platform_data *plat_data;
  220711. + struct fb_info *fbi;
  220712. + struct mxcfb_info *mxcfbi;
  220713. + struct resource *res;
  220714. + int ret = 0;
  220715. +
  220716. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  220717. + pdev->id = of_alias_get_id(pdev->dev.of_node, "mxcfb");
  220718. + if (pdev->id < 0) {
  220719. + dev_err(&pdev->dev, "can not get alias id\n");
  220720. + return pdev->id;
  220721. + }
  220722. +
  220723. + plat_data = devm_kzalloc(&pdev->dev, sizeof(struct
  220724. + ipuv3_fb_platform_data), GFP_KERNEL);
  220725. + if (!plat_data)
  220726. + return -ENOMEM;
  220727. + pdev->dev.platform_data = plat_data;
  220728. +
  220729. + ret = mxcfb_get_of_property(pdev, plat_data);
  220730. + if (ret < 0) {
  220731. + dev_err(&pdev->dev, "get mxcfb of property fail\n");
  220732. + return ret;
  220733. + }
  220734. +
  220735. + /* Initialize FB structures */
  220736. + fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
  220737. + if (!fbi) {
  220738. + ret = -ENOMEM;
  220739. + goto init_fbinfo_failed;
  220740. + }
  220741. +
  220742. + ret = mxcfb_option_setup(pdev, fbi);
  220743. + if (ret)
  220744. + goto get_fb_option_failed;
  220745. +
  220746. + mxcfbi = (struct mxcfb_info *)fbi->par;
  220747. + mxcfbi->ipu_int_clk = plat_data->int_clk;
  220748. + mxcfbi->late_init = plat_data->late_init;
  220749. + mxcfbi->first_set_par = true;
  220750. + ret = mxcfb_dispdrv_init(pdev, fbi);
  220751. + if (ret < 0)
  220752. + goto init_dispdrv_failed;
  220753. +
  220754. + ret = ipu_test_set_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
  220755. + if (ret < 0) {
  220756. + dev_err(&pdev->dev, "ipu%d-di%d already in use\n",
  220757. + mxcfbi->ipu_id, mxcfbi->ipu_di);
  220758. + goto ipu_in_busy;
  220759. + }
  220760. +
  220761. + if (mxcfbi->dispdrv->drv->post_init) {
  220762. + ret = mxcfbi->dispdrv->drv->post_init(mxcfbi->dispdrv,
  220763. + mxcfbi->ipu_id,
  220764. + mxcfbi->ipu_di);
  220765. + if (ret < 0) {
  220766. + dev_err(&pdev->dev, "post init failed\n");
  220767. + goto post_init_failed;
  220768. + }
  220769. + }
  220770. +
  220771. + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  220772. + if (res && res->start && res->end) {
  220773. + fbi->fix.smem_len = res->end - res->start + 1;
  220774. + fbi->fix.smem_start = res->start;
  220775. + fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len);
  220776. + /* Do not clear the fb content drawn in bootloader. */
  220777. + if (!mxcfbi->late_init)
  220778. + memset(fbi->screen_base, 0, fbi->fix.smem_len);
  220779. + }
  220780. +
  220781. + mxcfbi->ipu = ipu_get_soc(mxcfbi->ipu_id);
  220782. + if (IS_ERR(mxcfbi->ipu)) {
  220783. + ret = -ENODEV;
  220784. + goto get_ipu_failed;
  220785. + }
  220786. +
  220787. + /* first user uses DP with alpha feature */
  220788. + if (!g_dp_in_use[mxcfbi->ipu_id]) {
  220789. + mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF;
  220790. + mxcfbi->ipu_ch_nf_irq = IPU_IRQ_BG_SYNC_NFACK;
  220791. + mxcfbi->ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
  220792. + mxcfbi->ipu_ch = MEM_BG_SYNC;
  220793. + /* Unblank the primary fb only by default */
  220794. + if (pdev->id == 0)
  220795. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
  220796. + else
  220797. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
  220798. +
  220799. + ret = mxcfb_register(fbi);
  220800. + if (ret < 0)
  220801. + goto mxcfb_register_failed;
  220802. +
  220803. + ipu_disp_set_global_alpha(mxcfbi->ipu, mxcfbi->ipu_ch,
  220804. + true, 0x80);
  220805. + ipu_disp_set_color_key(mxcfbi->ipu, mxcfbi->ipu_ch, false, 0);
  220806. +
  220807. + res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  220808. + ret = mxcfb_setup_overlay(pdev, fbi, res);
  220809. +
  220810. + if (ret < 0) {
  220811. + mxcfb_unregister(fbi);
  220812. + goto mxcfb_setupoverlay_failed;
  220813. + }
  220814. +
  220815. + g_dp_in_use[mxcfbi->ipu_id] = true;
  220816. +
  220817. + ret = device_create_file(mxcfbi->ovfbi->dev,
  220818. + &dev_attr_fsl_disp_property);
  220819. + if (ret)
  220820. + dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
  220821. + "file for disp property\n",
  220822. + ret);
  220823. +
  220824. + ret = device_create_file(mxcfbi->ovfbi->dev,
  220825. + &dev_attr_fsl_disp_dev_property);
  220826. + if (ret)
  220827. + dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
  220828. + "file for disp device "
  220829. + "propety\n", ret);
  220830. + } else {
  220831. + mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF;
  220832. + mxcfbi->ipu_ch_nf_irq = IPU_IRQ_DC_SYNC_NFACK;
  220833. + mxcfbi->ipu_alp_ch_irq = -1;
  220834. + mxcfbi->ipu_ch = MEM_DC_SYNC;
  220835. + mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
  220836. +
  220837. + ret = mxcfb_register(fbi);
  220838. + if (ret < 0)
  220839. + goto mxcfb_register_failed;
  220840. + }
  220841. +
  220842. + platform_set_drvdata(pdev, fbi);
  220843. +
  220844. + ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_property);
  220845. + if (ret)
  220846. + dev_err(&pdev->dev, "Error %d on creating file for disp "
  220847. + "property\n", ret);
  220848. +
  220849. + ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
  220850. + if (ret)
  220851. + dev_err(&pdev->dev, "Error %d on creating file for disp "
  220852. + " device propety\n", ret);
  220853. +
  220854. + return 0;
  220855. +
  220856. +mxcfb_setupoverlay_failed:
  220857. +mxcfb_register_failed:
  220858. +get_ipu_failed:
  220859. +post_init_failed:
  220860. + ipu_clear_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
  220861. +ipu_in_busy:
  220862. +init_dispdrv_failed:
  220863. + fb_dealloc_cmap(&fbi->cmap);
  220864. + framebuffer_release(fbi);
  220865. +get_fb_option_failed:
  220866. +init_fbinfo_failed:
  220867. + return ret;
  220868. +}
  220869. +
  220870. +static int mxcfb_remove(struct platform_device *pdev)
  220871. +{
  220872. + struct fb_info *fbi = platform_get_drvdata(pdev);
  220873. + struct mxcfb_info *mxc_fbi = fbi->par;
  220874. +
  220875. + if (!fbi)
  220876. + return 0;
  220877. +
  220878. + device_remove_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
  220879. + device_remove_file(fbi->dev, &dev_attr_fsl_disp_property);
  220880. + mxcfb_blank(FB_BLANK_POWERDOWN, fbi);
  220881. + mxcfb_unregister(fbi);
  220882. + mxcfb_unmap_video_memory(fbi);
  220883. +
  220884. + if (mxc_fbi->ovfbi) {
  220885. + device_remove_file(mxc_fbi->ovfbi->dev,
  220886. + &dev_attr_fsl_disp_dev_property);
  220887. + device_remove_file(mxc_fbi->ovfbi->dev,
  220888. + &dev_attr_fsl_disp_property);
  220889. + mxcfb_blank(FB_BLANK_POWERDOWN, mxc_fbi->ovfbi);
  220890. + mxcfb_unsetup_overlay(fbi);
  220891. + mxcfb_unmap_video_memory(mxc_fbi->ovfbi);
  220892. + }
  220893. +
  220894. + ipu_clear_usage(mxc_fbi->ipu_id, mxc_fbi->ipu_di);
  220895. + if (&fbi->cmap)
  220896. + fb_dealloc_cmap(&fbi->cmap);
  220897. + framebuffer_release(fbi);
  220898. + return 0;
  220899. +}
  220900. +
  220901. +static const struct of_device_id imx_mxcfb_dt_ids[] = {
  220902. + { .compatible = "fsl,mxc_sdc_fb"},
  220903. + { /* sentinel */ }
  220904. +};
  220905. +
  220906. +/*!
  220907. + * This structure contains pointers to the power management callback functions.
  220908. + */
  220909. +static struct platform_driver mxcfb_driver = {
  220910. + .driver = {
  220911. + .name = MXCFB_NAME,
  220912. + .of_match_table = imx_mxcfb_dt_ids,
  220913. + },
  220914. + .probe = mxcfb_probe,
  220915. + .remove = mxcfb_remove,
  220916. + .suspend = mxcfb_suspend,
  220917. + .resume = mxcfb_resume,
  220918. +};
  220919. +
  220920. +/*!
  220921. + * Main entry function for the framebuffer. The function registers the power
  220922. + * management callback functions with the kernel and also registers the MXCFB
  220923. + * callback functions with the core Linux framebuffer driver \b fbmem.c
  220924. + *
  220925. + * @return Error code indicating success or failure
  220926. + */
  220927. +int __init mxcfb_init(void)
  220928. +{
  220929. + return platform_driver_register(&mxcfb_driver);
  220930. +}
  220931. +
  220932. +void mxcfb_exit(void)
  220933. +{
  220934. + platform_driver_unregister(&mxcfb_driver);
  220935. +}
  220936. +
  220937. +module_init(mxcfb_init);
  220938. +module_exit(mxcfb_exit);
  220939. +
  220940. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  220941. +MODULE_DESCRIPTION("MXC framebuffer driver");
  220942. +MODULE_LICENSE("GPL");
  220943. +MODULE_SUPPORTED_DEVICE("fb");
  220944. diff -Nur linux-3.14.17/drivers/video/mxc/mxc_lcdif.c linux-imx6-3.14/drivers/video/mxc/mxc_lcdif.c
  220945. --- linux-3.14.17/drivers/video/mxc/mxc_lcdif.c 1970-01-01 01:00:00.000000000 +0100
  220946. +++ linux-imx6-3.14/drivers/video/mxc/mxc_lcdif.c 2014-09-11 18:06:09.534068054 +0200
  220947. @@ -0,0 +1,235 @@
  220948. +/*
  220949. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  220950. + */
  220951. +
  220952. +/*
  220953. + * The code contained herein is licensed under the GNU General Public
  220954. + * License. You may obtain a copy of the GNU General Public License
  220955. + * Version 2 or later at the following locations:
  220956. + *
  220957. + * http://www.opensource.org/licenses/gpl-license.html
  220958. + * http://www.gnu.org/copyleft/gpl.html
  220959. + */
  220960. +
  220961. +#include <linux/init.h>
  220962. +#include <linux/ipu.h>
  220963. +#include <linux/kernel.h>
  220964. +#include <linux/module.h>
  220965. +#include <linux/mxcfb.h>
  220966. +#include <linux/of_device.h>
  220967. +#include <linux/pinctrl/consumer.h>
  220968. +#include <linux/platform_device.h>
  220969. +
  220970. +#include "mxc_dispdrv.h"
  220971. +
  220972. +struct mxc_lcd_platform_data {
  220973. + u32 default_ifmt;
  220974. + u32 ipu_id;
  220975. + u32 disp_id;
  220976. +};
  220977. +
  220978. +struct mxc_lcdif_data {
  220979. + struct platform_device *pdev;
  220980. + struct mxc_dispdrv_handle *disp_lcdif;
  220981. +};
  220982. +
  220983. +#define DISPDRV_LCD "lcd"
  220984. +
  220985. +static struct fb_videomode lcdif_modedb[] = {
  220986. + {
  220987. + /* 800x480 @ 57 Hz , pixel clk @ 27MHz */
  220988. + "CLAA-WVGA", 57, 800, 480, 37037, 40, 60, 10, 10, 20, 10,
  220989. + FB_SYNC_CLK_LAT_FALL,
  220990. + FB_VMODE_NONINTERLACED,
  220991. + 0,},
  220992. + {
  220993. + /* 800x480 @ 60 Hz , pixel clk @ 32MHz */
  220994. + "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
  220995. + FB_SYNC_CLK_LAT_FALL,
  220996. + FB_VMODE_NONINTERLACED,
  220997. + 0,},
  220998. +};
  220999. +static int lcdif_modedb_sz = ARRAY_SIZE(lcdif_modedb);
  221000. +
  221001. +static int lcdif_init(struct mxc_dispdrv_handle *disp,
  221002. + struct mxc_dispdrv_setting *setting)
  221003. +{
  221004. + int ret, i;
  221005. + struct mxc_lcdif_data *lcdif = mxc_dispdrv_getdata(disp);
  221006. + struct mxc_lcd_platform_data *plat_data
  221007. + = lcdif->pdev->dev.platform_data;
  221008. + struct fb_videomode *modedb = lcdif_modedb;
  221009. + int modedb_sz = lcdif_modedb_sz;
  221010. +
  221011. + /* use platform defined ipu/di */
  221012. + setting->dev_id = plat_data->ipu_id;
  221013. + setting->disp_id = plat_data->disp_id;
  221014. +
  221015. + ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str,
  221016. + modedb, modedb_sz, NULL, setting->default_bpp);
  221017. + if (!ret) {
  221018. + fb_videomode_to_var(&setting->fbi->var, &modedb[0]);
  221019. + setting->if_fmt = plat_data->default_ifmt;
  221020. + }
  221021. +
  221022. + INIT_LIST_HEAD(&setting->fbi->modelist);
  221023. + for (i = 0; i < modedb_sz; i++) {
  221024. + struct fb_videomode m;
  221025. + fb_var_to_videomode(&m, &setting->fbi->var);
  221026. + if (fb_mode_is_equal(&m, &modedb[i])) {
  221027. + fb_add_videomode(&modedb[i],
  221028. + &setting->fbi->modelist);
  221029. + break;
  221030. + }
  221031. + }
  221032. +
  221033. + return ret;
  221034. +}
  221035. +
  221036. +void lcdif_deinit(struct mxc_dispdrv_handle *disp)
  221037. +{
  221038. + /*TODO*/
  221039. +}
  221040. +
  221041. +static struct mxc_dispdrv_driver lcdif_drv = {
  221042. + .name = DISPDRV_LCD,
  221043. + .init = lcdif_init,
  221044. + .deinit = lcdif_deinit,
  221045. +};
  221046. +
  221047. +static int lcd_get_of_property(struct platform_device *pdev,
  221048. + struct mxc_lcd_platform_data *plat_data)
  221049. +{
  221050. + struct device_node *np = pdev->dev.of_node;
  221051. + int err;
  221052. + u32 ipu_id, disp_id;
  221053. + const char *default_ifmt;
  221054. +
  221055. + err = of_property_read_string(np, "default_ifmt", &default_ifmt);
  221056. + if (err) {
  221057. + dev_dbg(&pdev->dev, "get of property default_ifmt fail\n");
  221058. + return err;
  221059. + }
  221060. + err = of_property_read_u32(np, "ipu_id", &ipu_id);
  221061. + if (err) {
  221062. + dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
  221063. + return err;
  221064. + }
  221065. + err = of_property_read_u32(np, "disp_id", &disp_id);
  221066. + if (err) {
  221067. + dev_dbg(&pdev->dev, "get of property disp_id fail\n");
  221068. + return err;
  221069. + }
  221070. +
  221071. + plat_data->ipu_id = ipu_id;
  221072. + plat_data->disp_id = disp_id;
  221073. + if (!strncmp(default_ifmt, "RGB24", 5))
  221074. + plat_data->default_ifmt = IPU_PIX_FMT_RGB24;
  221075. + else if (!strncmp(default_ifmt, "BGR24", 5))
  221076. + plat_data->default_ifmt = IPU_PIX_FMT_BGR24;
  221077. + else if (!strncmp(default_ifmt, "GBR24", 5))
  221078. + plat_data->default_ifmt = IPU_PIX_FMT_GBR24;
  221079. + else if (!strncmp(default_ifmt, "RGB565", 6))
  221080. + plat_data->default_ifmt = IPU_PIX_FMT_RGB565;
  221081. + else if (!strncmp(default_ifmt, "RGB666", 6))
  221082. + plat_data->default_ifmt = IPU_PIX_FMT_RGB666;
  221083. + else if (!strncmp(default_ifmt, "YUV444", 6))
  221084. + plat_data->default_ifmt = IPU_PIX_FMT_YUV444;
  221085. + else if (!strncmp(default_ifmt, "LVDS666", 7))
  221086. + plat_data->default_ifmt = IPU_PIX_FMT_LVDS666;
  221087. + else if (!strncmp(default_ifmt, "YUYV16", 6))
  221088. + plat_data->default_ifmt = IPU_PIX_FMT_YUYV;
  221089. + else if (!strncmp(default_ifmt, "UYVY16", 6))
  221090. + plat_data->default_ifmt = IPU_PIX_FMT_UYVY;
  221091. + else if (!strncmp(default_ifmt, "YVYU16", 6))
  221092. + plat_data->default_ifmt = IPU_PIX_FMT_YVYU;
  221093. + else if (!strncmp(default_ifmt, "VYUY16", 6))
  221094. + plat_data->default_ifmt = IPU_PIX_FMT_VYUY;
  221095. + else {
  221096. + dev_err(&pdev->dev, "err default_ifmt!\n");
  221097. + return -ENOENT;
  221098. + }
  221099. +
  221100. + return err;
  221101. +}
  221102. +
  221103. +static int mxc_lcdif_probe(struct platform_device *pdev)
  221104. +{
  221105. + int ret;
  221106. + struct pinctrl *pinctrl;
  221107. + struct mxc_lcdif_data *lcdif;
  221108. + struct mxc_lcd_platform_data *plat_data;
  221109. +
  221110. + dev_dbg(&pdev->dev, "%s enter\n", __func__);
  221111. + lcdif = devm_kzalloc(&pdev->dev, sizeof(struct mxc_lcdif_data),
  221112. + GFP_KERNEL);
  221113. + if (!lcdif)
  221114. + return -ENOMEM;
  221115. + plat_data = devm_kzalloc(&pdev->dev,
  221116. + sizeof(struct mxc_lcd_platform_data),
  221117. + GFP_KERNEL);
  221118. + if (!plat_data)
  221119. + return -ENOMEM;
  221120. + pdev->dev.platform_data = plat_data;
  221121. +
  221122. + ret = lcd_get_of_property(pdev, plat_data);
  221123. + if (ret < 0) {
  221124. + dev_err(&pdev->dev, "get lcd of property fail\n");
  221125. + return ret;
  221126. + }
  221127. +
  221128. + pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  221129. + if (IS_ERR(pinctrl)) {
  221130. + dev_err(&pdev->dev, "can't get/select pinctrl\n");
  221131. + return PTR_ERR(pinctrl);
  221132. + }
  221133. +
  221134. + lcdif->pdev = pdev;
  221135. + lcdif->disp_lcdif = mxc_dispdrv_register(&lcdif_drv);
  221136. + mxc_dispdrv_setdata(lcdif->disp_lcdif, lcdif);
  221137. +
  221138. + dev_set_drvdata(&pdev->dev, lcdif);
  221139. + dev_dbg(&pdev->dev, "%s exit\n", __func__);
  221140. +
  221141. + return ret;
  221142. +}
  221143. +
  221144. +static int mxc_lcdif_remove(struct platform_device *pdev)
  221145. +{
  221146. + struct mxc_lcdif_data *lcdif = dev_get_drvdata(&pdev->dev);
  221147. +
  221148. + mxc_dispdrv_puthandle(lcdif->disp_lcdif);
  221149. + mxc_dispdrv_unregister(lcdif->disp_lcdif);
  221150. + kfree(lcdif);
  221151. + return 0;
  221152. +}
  221153. +
  221154. +static const struct of_device_id imx_lcd_dt_ids[] = {
  221155. + { .compatible = "fsl,lcd"},
  221156. + { /* sentinel */ }
  221157. +};
  221158. +static struct platform_driver mxc_lcdif_driver = {
  221159. + .driver = {
  221160. + .name = "mxc_lcdif",
  221161. + .of_match_table = imx_lcd_dt_ids,
  221162. + },
  221163. + .probe = mxc_lcdif_probe,
  221164. + .remove = mxc_lcdif_remove,
  221165. +};
  221166. +
  221167. +static int __init mxc_lcdif_init(void)
  221168. +{
  221169. + return platform_driver_register(&mxc_lcdif_driver);
  221170. +}
  221171. +
  221172. +static void __exit mxc_lcdif_exit(void)
  221173. +{
  221174. + platform_driver_unregister(&mxc_lcdif_driver);
  221175. +}
  221176. +
  221177. +module_init(mxc_lcdif_init);
  221178. +module_exit(mxc_lcdif_exit);
  221179. +
  221180. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  221181. +MODULE_DESCRIPTION("i.MX ipuv3 LCD extern port driver");
  221182. +MODULE_LICENSE("GPL");
  221183. diff -Nur linux-3.14.17/drivers/video/mxsfb.c linux-imx6-3.14/drivers/video/mxsfb.c
  221184. --- linux-3.14.17/drivers/video/mxsfb.c 2014-08-14 03:38:34.000000000 +0200
  221185. +++ linux-imx6-3.14/drivers/video/mxsfb.c 2014-09-11 18:06:09.534068054 +0200
  221186. @@ -96,9 +96,10 @@
  221187. #define CTRL_DF24 (1 << 1)
  221188. #define CTRL_RUN (1 << 0)
  221189. -#define CTRL1_FIFO_CLEAR (1 << 21)
  221190. -#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
  221191. -#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
  221192. +#define CTRL1_RECOVERY_ON_UNDERFLOW (1 << 24)
  221193. +#define CTRL1_FIFO_CLEAR (1 << 21)
  221194. +#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
  221195. +#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
  221196. #define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
  221197. #define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
  221198. @@ -149,8 +150,8 @@
  221199. #define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
  221200. #define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
  221201. -#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
  221202. -#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negtive edge sampling */
  221203. +#define FB_SYNC_OE_LOW_ACT 0x80000000
  221204. +#define FB_SYNC_CLK_LAT_FALL 0x40000000
  221205. enum mxsfb_devtype {
  221206. MXSFB_V3,
  221207. @@ -178,7 +179,6 @@
  221208. unsigned ld_intf_width;
  221209. unsigned dotclk_delay;
  221210. const struct mxsfb_devdata *devdata;
  221211. - u32 sync;
  221212. struct regulator *reg_lcd;
  221213. };
  221214. @@ -275,9 +275,15 @@
  221215. if (var->yres < MIN_YRES)
  221216. var->yres = MIN_YRES;
  221217. - var->xres_virtual = var->xres;
  221218. + if (var->xres_virtual > var->xres) {
  221219. + dev_dbg(fb_info->device, "stride not supported\n");
  221220. + return -EINVAL;
  221221. + }
  221222. - var->yres_virtual = var->yres;
  221223. + if (var->xres_virtual < var->xres)
  221224. + var->xres_virtual = var->xres;
  221225. + if (var->yres_virtual < var->yres)
  221226. + var->yres_virtual = var->yres;
  221227. switch (var->bits_per_pixel) {
  221228. case 16:
  221229. @@ -344,6 +350,9 @@
  221230. writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);
  221231. + /* Recovery on underflow */
  221232. + writel(CTRL1_RECOVERY_ON_UNDERFLOW, host->base + LCDC_CTRL1 + REG_SET);
  221233. +
  221234. host->enabled = 1;
  221235. }
  221236. @@ -392,14 +401,6 @@
  221237. int line_size, fb_size;
  221238. int reenable = 0;
  221239. - line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
  221240. - fb_size = fb_info->var.yres_virtual * line_size;
  221241. -
  221242. - if (fb_size > fb_info->fix.smem_len)
  221243. - return -ENOMEM;
  221244. -
  221245. - fb_info->fix.line_length = line_size;
  221246. -
  221247. /*
  221248. * It seems, you can't re-program the controller if it is still running.
  221249. * This may lead into shifted pictures (FIFO issue?).
  221250. @@ -413,6 +414,19 @@
  221251. /* clear the FIFOs */
  221252. writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
  221253. + line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
  221254. + fb_info->fix.line_length = line_size;
  221255. + fb_size = fb_info->var.yres_virtual * line_size;
  221256. +
  221257. + /* Reallocate memory */
  221258. + if (!fb_info->fix.smem_start || (fb_size > fb_info->fix.smem_len)) {
  221259. + if (fb_info->fix.smem_start)
  221260. + mxsfb_unmap_videomem(fb_info);
  221261. +
  221262. + if (mxsfb_map_videomem(fb_info) < 0)
  221263. + return -ENOMEM;
  221264. + }
  221265. +
  221266. ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER |
  221267. CTRL_SET_BUS_WIDTH(host->ld_intf_width);
  221268. @@ -459,9 +473,9 @@
  221269. vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
  221270. if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
  221271. vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
  221272. - if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
  221273. + if (!(fb_info->var.sync & FB_SYNC_OE_LOW_ACT))
  221274. vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
  221275. - if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT)
  221276. + if (fb_info->var.sync & FB_SYNC_CLK_LAT_FALL)
  221277. vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
  221278. writel(vdctrl0, host->base + LCDC_VDCTRL0);
  221279. @@ -578,6 +592,34 @@
  221280. return 0;
  221281. }
  221282. +static int mxsfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
  221283. +{
  221284. + u32 len;
  221285. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  221286. +
  221287. + if (offset < info->fix.smem_len) {
  221288. + /* mapping framebuffer memory */
  221289. + len = info->fix.smem_len - offset;
  221290. + vma->vm_pgoff = (info->fix.smem_start + offset) >> PAGE_SHIFT;
  221291. + } else
  221292. + return -EINVAL;
  221293. +
  221294. + len = PAGE_ALIGN(len);
  221295. + if (vma->vm_end - vma->vm_start > len)
  221296. + return -EINVAL;
  221297. +
  221298. + /* make buffers bufferable */
  221299. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  221300. +
  221301. + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  221302. + vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
  221303. + dev_dbg(info->device, "mmap remap_pfn_range failed\n");
  221304. + return -ENOBUFS;
  221305. + }
  221306. +
  221307. + return 0;
  221308. +}
  221309. +
  221310. static struct fb_ops mxsfb_ops = {
  221311. .owner = THIS_MODULE,
  221312. .fb_check_var = mxsfb_check_var,
  221313. @@ -585,6 +627,7 @@
  221314. .fb_setcolreg = mxsfb_setcolreg,
  221315. .fb_blank = mxsfb_blank,
  221316. .fb_pan_display = mxsfb_pan_display,
  221317. + .fb_mmap = mxsfb_mmap,
  221318. .fb_fillrect = cfb_fillrect,
  221319. .fb_copyarea = cfb_copyarea,
  221320. .fb_imageblit = cfb_imageblit,
  221321. @@ -800,7 +843,62 @@
  221322. {
  221323. struct fb_info *fb_info = &host->fb_info;
  221324. - free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
  221325. + mxsfb_unmap_videomem(fb_info);
  221326. +}
  221327. +
  221328. +/*!
  221329. + * Allocates the DRAM memory for the frame buffer. This buffer is remapped
  221330. + * into a non-cached, non-buffered, memory region to allow palette and pixel
  221331. + * writes to occur without flushing the cache. Once this area is remapped,
  221332. + * all virtual memory access to the video memory should occur at the new region.
  221333. + *
  221334. + * @param fbi framebuffer information pointer
  221335. + *
  221336. + * @return Error code indicating success or failure
  221337. + */
  221338. +static int mxsfb_map_videomem(struct fb_info *fbi)
  221339. +{
  221340. + if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length)
  221341. + fbi->fix.smem_len = fbi->var.yres_virtual *
  221342. + fbi->fix.line_length;
  221343. +
  221344. + fbi->screen_base = dma_alloc_writecombine(fbi->device,
  221345. + fbi->fix.smem_len,
  221346. + (dma_addr_t *)&fbi->fix.smem_start,
  221347. + GFP_DMA | GFP_KERNEL);
  221348. + if (fbi->screen_base == 0) {
  221349. + dev_err(fbi->device, "Unable to allocate framebuffer memory\n");
  221350. + fbi->fix.smem_len = 0;
  221351. + fbi->fix.smem_start = 0;
  221352. + return -EBUSY;
  221353. + }
  221354. +
  221355. + dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n",
  221356. + (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
  221357. +
  221358. + fbi->screen_size = fbi->fix.smem_len;
  221359. +
  221360. + /* Clear the screen */
  221361. + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
  221362. +
  221363. + return 0;
  221364. +}
  221365. +
  221366. +/*!
  221367. + * De-allocates the DRAM memory for the frame buffer.
  221368. + *
  221369. + * @param fbi framebuffer information pointer
  221370. + *
  221371. + * @return Error code indicating success or failure
  221372. + */
  221373. +static int mxsfb_unmap_videomem(struct fb_info *fbi)
  221374. +{
  221375. + dma_free_writecombine(fbi->device, fbi->fix.smem_len,
  221376. + fbi->screen_base, fbi->fix.smem_start);
  221377. + fbi->screen_base = 0;
  221378. + fbi->fix.smem_start = 0;
  221379. + fbi->fix.smem_len = 0;
  221380. + return 0;
  221381. }
  221382. static struct platform_device_id mxsfb_devtype[] = {
  221383. diff -Nur linux-3.14.17/drivers/video/vexpress-dvi.c linux-imx6-3.14/drivers/video/vexpress-dvi.c
  221384. --- linux-3.14.17/drivers/video/vexpress-dvi.c 1970-01-01 01:00:00.000000000 +0100
  221385. +++ linux-imx6-3.14/drivers/video/vexpress-dvi.c 2014-09-11 18:06:09.850069315 +0200
  221386. @@ -0,0 +1,220 @@
  221387. +/*
  221388. + * This program is free software; you can redistribute it and/or modify
  221389. + * it under the terms of the GNU General Public License version 2 as
  221390. + * published by the Free Software Foundation.
  221391. + *
  221392. + * This program is distributed in the hope that it will be useful,
  221393. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  221394. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  221395. + * GNU General Public License for more details.
  221396. + *
  221397. + * Copyright (C) 2012 ARM Limited
  221398. + */
  221399. +
  221400. +#define pr_fmt(fmt) "vexpress-dvi: " fmt
  221401. +
  221402. +#include <linux/fb.h>
  221403. +#include <linux/of.h>
  221404. +#include <linux/of_device.h>
  221405. +#include <linux/vexpress.h>
  221406. +
  221407. +
  221408. +static struct vexpress_config_func *vexpress_dvimode_func;
  221409. +
  221410. +static struct {
  221411. + u32 xres, yres, mode;
  221412. +} vexpress_dvi_dvimodes[] = {
  221413. + { 640, 480, 0 }, /* VGA */
  221414. + { 800, 600, 1 }, /* SVGA */
  221415. + { 1024, 768, 2 }, /* XGA */
  221416. + { 1280, 1024, 3 }, /* SXGA */
  221417. + { 1600, 1200, 4 }, /* UXGA */
  221418. + { 1920, 1080, 5 }, /* HD1080 */
  221419. +};
  221420. +
  221421. +static void vexpress_dvi_mode_set(struct fb_info *info, u32 xres, u32 yres)
  221422. +{
  221423. + int err = -ENOENT;
  221424. + int i;
  221425. +
  221426. + if (!vexpress_dvimode_func)
  221427. + return;
  221428. +
  221429. + for (i = 0; i < ARRAY_SIZE(vexpress_dvi_dvimodes); i++) {
  221430. + if (vexpress_dvi_dvimodes[i].xres == xres &&
  221431. + vexpress_dvi_dvimodes[i].yres == yres) {
  221432. + pr_debug("mode: %ux%u = %d\n", xres, yres,
  221433. + vexpress_dvi_dvimodes[i].mode);
  221434. + err = vexpress_config_write(vexpress_dvimode_func, 0,
  221435. + vexpress_dvi_dvimodes[i].mode);
  221436. + break;
  221437. + }
  221438. + }
  221439. +
  221440. + if (err)
  221441. + pr_warn("Failed to set %ux%u mode! (%d)\n", xres, yres, err);
  221442. +}
  221443. +
  221444. +
  221445. +static struct vexpress_config_func *vexpress_muxfpga_func;
  221446. +static int vexpress_dvi_fb = -1;
  221447. +
  221448. +static int vexpress_dvi_mux_set(struct fb_info *info)
  221449. +{
  221450. + int err;
  221451. + u32 site = vexpress_get_site_by_dev(info->device);
  221452. +
  221453. + if (!vexpress_muxfpga_func)
  221454. + return -ENXIO;
  221455. +
  221456. + err = vexpress_config_write(vexpress_muxfpga_func, 0, site);
  221457. + if (!err) {
  221458. + pr_debug("Selected MUXFPGA input %d (fb%d)\n", site,
  221459. + info->node);
  221460. + vexpress_dvi_fb = info->node;
  221461. + vexpress_dvi_mode_set(info, info->var.xres,
  221462. + info->var.yres);
  221463. + } else {
  221464. + pr_warn("Failed to select MUXFPGA input %d (fb%d)! (%d)\n",
  221465. + site, info->node, err);
  221466. + }
  221467. +
  221468. + return err;
  221469. +}
  221470. +
  221471. +static int vexpress_dvi_fb_select(int fb)
  221472. +{
  221473. + int err;
  221474. + struct fb_info *info;
  221475. +
  221476. + /* fb0 is the default */
  221477. + if (fb < 0)
  221478. + fb = 0;
  221479. +
  221480. + info = registered_fb[fb];
  221481. + if (!info || !lock_fb_info(info))
  221482. + return -ENODEV;
  221483. +
  221484. + err = vexpress_dvi_mux_set(info);
  221485. +
  221486. + unlock_fb_info(info);
  221487. +
  221488. + return err;
  221489. +}
  221490. +
  221491. +static ssize_t vexpress_dvi_fb_show(struct device *dev,
  221492. + struct device_attribute *attr, char *buf)
  221493. +{
  221494. + return sprintf(buf, "%d\n", vexpress_dvi_fb);
  221495. +}
  221496. +
  221497. +static ssize_t vexpress_dvi_fb_store(struct device *dev,
  221498. + struct device_attribute *attr, const char *buf, size_t count)
  221499. +{
  221500. + long value;
  221501. + int err = kstrtol(buf, 0, &value);
  221502. +
  221503. + if (!err)
  221504. + err = vexpress_dvi_fb_select(value);
  221505. +
  221506. + return err ? err : count;
  221507. +}
  221508. +
  221509. +DEVICE_ATTR(fb, S_IRUGO | S_IWUSR, vexpress_dvi_fb_show,
  221510. + vexpress_dvi_fb_store);
  221511. +
  221512. +
  221513. +static int vexpress_dvi_fb_event_notify(struct notifier_block *self,
  221514. + unsigned long action, void *data)
  221515. +{
  221516. + struct fb_event *event = data;
  221517. + struct fb_info *info = event->info;
  221518. + struct fb_videomode *mode = event->data;
  221519. +
  221520. + switch (action) {
  221521. + case FB_EVENT_FB_REGISTERED:
  221522. + if (vexpress_dvi_fb < 0)
  221523. + vexpress_dvi_mux_set(info);
  221524. + break;
  221525. + case FB_EVENT_MODE_CHANGE:
  221526. + case FB_EVENT_MODE_CHANGE_ALL:
  221527. + if (info->node == vexpress_dvi_fb)
  221528. + vexpress_dvi_mode_set(info, mode->xres, mode->yres);
  221529. + break;
  221530. + }
  221531. +
  221532. + return NOTIFY_OK;
  221533. +}
  221534. +
  221535. +static struct notifier_block vexpress_dvi_fb_notifier = {
  221536. + .notifier_call = vexpress_dvi_fb_event_notify,
  221537. +};
  221538. +static bool vexpress_dvi_fb_notifier_registered;
  221539. +
  221540. +
  221541. +enum vexpress_dvi_func { FUNC_MUXFPGA, FUNC_DVIMODE };
  221542. +
  221543. +static struct of_device_id vexpress_dvi_of_match[] = {
  221544. + {
  221545. + .compatible = "arm,vexpress-muxfpga",
  221546. + .data = (void *)FUNC_MUXFPGA,
  221547. + }, {
  221548. + .compatible = "arm,vexpress-dvimode",
  221549. + .data = (void *)FUNC_DVIMODE,
  221550. + },
  221551. + {}
  221552. +};
  221553. +
  221554. +static int vexpress_dvi_probe(struct platform_device *pdev)
  221555. +{
  221556. + enum vexpress_dvi_func func;
  221557. + const struct of_device_id *match =
  221558. + of_match_device(vexpress_dvi_of_match, &pdev->dev);
  221559. +
  221560. + if (match)
  221561. + func = (enum vexpress_dvi_func)match->data;
  221562. + else
  221563. + func = pdev->id_entry->driver_data;
  221564. +
  221565. + switch (func) {
  221566. + case FUNC_MUXFPGA:
  221567. + vexpress_muxfpga_func =
  221568. + vexpress_config_func_get_by_dev(&pdev->dev);
  221569. + device_create_file(&pdev->dev, &dev_attr_fb);
  221570. + break;
  221571. + case FUNC_DVIMODE:
  221572. + vexpress_dvimode_func =
  221573. + vexpress_config_func_get_by_dev(&pdev->dev);
  221574. + break;
  221575. + }
  221576. +
  221577. + if (!vexpress_dvi_fb_notifier_registered) {
  221578. + fb_register_client(&vexpress_dvi_fb_notifier);
  221579. + vexpress_dvi_fb_notifier_registered = true;
  221580. + }
  221581. +
  221582. + vexpress_dvi_fb_select(vexpress_dvi_fb);
  221583. +
  221584. + return 0;
  221585. +}
  221586. +
  221587. +static const struct platform_device_id vexpress_dvi_id_table[] = {
  221588. + { .name = "vexpress-muxfpga", .driver_data = FUNC_MUXFPGA, },
  221589. + { .name = "vexpress-dvimode", .driver_data = FUNC_DVIMODE, },
  221590. + {}
  221591. +};
  221592. +
  221593. +static struct platform_driver vexpress_dvi_driver = {
  221594. + .probe = vexpress_dvi_probe,
  221595. + .driver = {
  221596. + .name = "vexpress-dvi",
  221597. + .of_match_table = vexpress_dvi_of_match,
  221598. + },
  221599. + .id_table = vexpress_dvi_id_table,
  221600. +};
  221601. +
  221602. +static int __init vexpress_dvi_init(void)
  221603. +{
  221604. + return platform_driver_register(&vexpress_dvi_driver);
  221605. +}
  221606. +device_initcall(vexpress_dvi_init);
  221607. diff -Nur linux-3.14.17/firmware/imx/sdma/sdma-imx6q.bin.ihex linux-imx6-3.14/firmware/imx/sdma/sdma-imx6q.bin.ihex
  221608. --- linux-3.14.17/firmware/imx/sdma/sdma-imx6q.bin.ihex 1970-01-01 01:00:00.000000000 +0100
  221609. +++ linux-imx6-3.14/firmware/imx/sdma/sdma-imx6q.bin.ihex 2014-09-11 18:06:10.050070113 +0200
  221610. @@ -0,0 +1,116 @@
  221611. +:1000000053444D4101000000010000001C000000AD
  221612. +:1000100026000000B40000007A0600008202000002
  221613. +:10002000FFFFFFFF00000000FFFFFFFFFFFFFFFFDC
  221614. +:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
  221615. +:10004000FFFFFFFFFFFFFFFF6A1A0000FFFFFFFF38
  221616. +:10005000EB020000BB180000FFFFFFFF08040000D8
  221617. +:10006000FFFFFFFFC0030000FFFFFFFFFFFFFFFFD9
  221618. +:10007000FFFFFFFFAB020000FFFFFFFF7B0300005D
  221619. +:10008000FFFFFFFFFFFFFFFF4C0400006E040000B6
  221620. +:10009000FFFFFFFF00180000FFFFFFFFFFFFFFFF54
  221621. +:1000A000000000000018000062180000161A00008E
  221622. +:1000B000061B0000E3C1DB57E35FE357F352016A1D
  221623. +:1000C0008F00D500017D8D00A005EB5D7804037DD8
  221624. +:1000D00079042C7D367C79041F7CEE56000F600677
  221625. +:1000E000057D0965437E0A62417E20980A623E7E54
  221626. +:1000F00009653C7E12051205AD026007037DFB55C4
  221627. +:10010000D36D2B98FB55041DD36DC86A2F7F011F3B
  221628. +:1001100003200048E47C5398FB55D76D1500057803
  221629. +:100120000962C86A0962C86AD76D5298FB55D76DD3
  221630. +:100130001500150005780A62C86A0A62C86AD76D98
  221631. +:100140005298FB55D76D15001500150005780B6208
  221632. +:10015000C86A0B62C86AD76D097CDF6D077F000033
  221633. +:10016000EB55004D077DFAC1E35706980700CC68B0
  221634. +:100170000C6813C20AC20398D9C1E3C1DB57E35F1D
  221635. +:10018000E357F352216A8F00D500017D8D00A00551
  221636. +:10019000EB5DFB567804037D79042A7D317C79047C
  221637. +:1001A000207C700B1103EB53000F6003057D096584
  221638. +:1001B000377E0A62357E86980A62327E0965307E15
  221639. +:1001C00012051205AD026007027C065A8E98265A67
  221640. +:1001D000277F011F03200048E87C700B1103135395
  221641. +:1001E000AF98150004780962065A0962265AAE983B
  221642. +:1001F0001500150004780A62065A0A62265AAE985B
  221643. +:1002000015001500150004780B62065A0B62265A79
  221644. +:10021000077C0000EB55004D067DFAC1E357699855
  221645. +:1002200007000C6813C20AC26698700B11031353BF
  221646. +:100230006C07017CD9C1FB5E8A066B07017CD9C1C2
  221647. +:10024000F35EDB59D3588F0110010F398B003CC18D
  221648. +:100250002B7DC05AC85B4EC1277C88038906E35CAE
  221649. +:10026000FF0D1105FF1DBC053E07004D187D7008F0
  221650. +:1002700011007E07097D7D07027D2852E698F8521D
  221651. +:10028000DB54BC02CC02097C7C07027D2852EF982B
  221652. +:10029000F852D354BC02CC02097D0004DD988B00D7
  221653. +:1002A000C052C85359C1D67D0002CD98FF08BF0087
  221654. +:1002B0007F07157D8804D500017D8D00A005EB5DCD
  221655. +:1002C0008F0212021202FF3ADA05027C3E071899E9
  221656. +:1002D000A402DD02027D3E0718995E071899EB55CE
  221657. +:1002E0009805EB5DF352FB546A07267D6C07017D90
  221658. +:1002F00055996B07577C6907047D6807027D010EDD
  221659. +:100300002F999358D600017D8E009355A005935DDB
  221660. +:10031000A00602780255045D1D7C004E087C69072A
  221661. +:10032000037D0255177E3C99045D147F8906935026
  221662. +:100330000048017D2799A099150006780255045DB3
  221663. +:100340004F070255245D2F07017CA09917006F0706
  221664. +:10035000017C012093559D000700A7D9F598D36C27
  221665. +:100360006907047D6807027D010E64999358D600E1
  221666. +:10037000017D8E009355A005935DA006027802557D
  221667. +:10038000C86D0F7C004E087C6907037D0255097E0D
  221668. +:100390007199C86D067F890693500048017D5C996C
  221669. +:1003A000A0999A99C36A6907047D6807027D010EC6
  221670. +:1003B00087999358D600017D8E009355A005935DD3
  221671. +:1003C000A0060278C865045D0F7C004E087C6907B2
  221672. +:1003D000037DC865097E9499045D067F8906935064
  221673. +:1003E0000048017D7F99A09993559D000700FF6CFF
  221674. +:1003F000A7D9F5980000E354EB55004D017CF59822
  221675. +:10040000DD98E354EB55FF0A1102FF1A7F07027CC7
  221676. +:10041000A005B4999D008C05BA05A0051002BA0488
  221677. +:10042000AD0454040600E3C1DB57FB52C36AF35228
  221678. +:10043000056A8F00D500017D8D00A005EB5D780475
  221679. +:10044000037D79042B7D1E7C7904337CEE56000FEE
  221680. +:10045000FB556007027DC36DD599041DC36DC8624D
  221681. +:100460003B7E6006027D10021202096A357F12028D
  221682. +:10047000096A327F1202096A2F7F011F0320004898
  221683. +:10048000E77C099AFB55C76D150015001500057826
  221684. +:10049000C8620B6AC8620B6AC76D089AFB55C76DC4
  221685. +:1004A000150015000578C8620A6AC8620A6AC76D35
  221686. +:1004B000089AFB55C76D15000578C862096AC862BD
  221687. +:1004C000096AC76D097C286A077F0000EB55004D5B
  221688. +:1004D000057DFAC1DB57BF9977C254040AC2BA99A5
  221689. +:1004E000D9C1E3C1DB57F352056A8F00D500017D06
  221690. +:1004F0008D00A005FB567804037D7904297D1F7CBF
  221691. +:1005000079042E7CE35D700D1105ED55000F600739
  221692. +:10051000027D0652329A2652337E6005027D100219
  221693. +:100520001202096A2D7F1202096A2A7F1202096AE1
  221694. +:10053000277F011F03200048EA7CE3555D9A1500E0
  221695. +:1005400015001500047806520B6A26520B6A5C9A55
  221696. +:1005500015001500047806520A6A26520A6A5C9A47
  221697. +:10056000150004780652096A2652096A097C286A2D
  221698. +:10057000077F0000DB57004D057DFAC1DB571B9A52
  221699. +:1005800077C254040AC2189AE3C1DB57F352056AD2
  221700. +:10059000FB568E02941AC36AC8626902247D941EB7
  221701. +:1005A000C36ED36EC8624802C86A9426981EC36E92
  221702. +:1005B000D36EC8624C02C86A9826C36E981EC36E7A
  221703. +:1005C000C8629826C36E6002097CC8626E02247DF0
  221704. +:1005D000096A1E7F0125004D257D849A286A187FAF
  221705. +:1005E00004627AC2B89AE36E8F00D805017D8D004F
  221706. +:1005F000A005C8626E02107D096A0A7F0120F97C9D
  221707. +:10060000286A067F0000004D0D7DFAC1DB576E9A07
  221708. +:10061000070004620C6AB59A286AFA7F04627AC2FB
  221709. +:1006200058045404286AF47F0AC26B9AD9C1E3C102
  221710. +:10063000DB57F352056AFB568E02941A0252690286
  221711. +:100640001D7D941E06524802065A9426981E065294
  221712. +:100650004C02065A9826981E065260020A7C98267A
  221713. +:1006600006526E02237D096A1D7F0125004D247DFF
  221714. +:10067000D19A286A177F04627AC2029B8F00D8053C
  221715. +:10068000017D8D00A00506526E02107D096A0A7F69
  221716. +:100690000120F97C286A067F0000004D0D7DFAC11B
  221717. +:1006A000DB57C19A070004620C6AFF9A286AFA7F36
  221718. +:1006B00004627AC258045404286AF47F0AC2BE9ABB
  221719. +:1006C000016E0B612F7E0B622D7E0B632B7E0C0D5A
  221720. +:1006D0001704170417049D04081DCC05017C0C0D9C
  221721. +:1006E000D16A000F4207C86FDD6F1C7F8E009D002E
  221722. +:1006F00001680B67177ED56B04080278C86F120774
  221723. +:10070000117C0B670F7E04080278C86F12070A7C01
  221724. +:10071000DD6F087FD169010FC86FDD6F037F0101B5
  221725. +:0E0720000004129B0700FF680C680002129B89
  221726. +:00000001FF
  221727. diff -Nur linux-3.14.17/firmware/Makefile linux-imx6-3.14/firmware/Makefile
  221728. --- linux-3.14.17/firmware/Makefile 2014-08-14 03:38:34.000000000 +0200
  221729. +++ linux-imx6-3.14/firmware/Makefile 2014-09-11 18:06:09.998069907 +0200
  221730. @@ -61,6 +61,7 @@
  221731. radeon/RV770_pfp.bin radeon/RV770_me.bin \
  221732. radeon/RV730_pfp.bin radeon/RV730_me.bin \
  221733. radeon/RV710_pfp.bin radeon/RV710_me.bin
  221734. +fw-shipped-$(CONFIG_IMX_SDMA) += imx/sdma/sdma-imx6q.bin
  221735. fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin
  221736. fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
  221737. fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
  221738. @@ -210,6 +211,8 @@
  221739. $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %)
  221740. $(call cmd,ihex)
  221741. +.NOTPARALLEL: $(obj)/%
  221742. +
  221743. # Don't depend on ihex2fw if we're installing and it already exists.
  221744. # Putting it after | in the dependencies doesn't seem sufficient when
  221745. # we're installing after a cross-compile, because ihex2fw has dependencies
  221746. diff -Nur linux-3.14.17/fs/btrfs/Kconfig linux-imx6-3.14/fs/btrfs/Kconfig
  221747. --- linux-3.14.17/fs/btrfs/Kconfig 2014-08-14 03:38:34.000000000 +0200
  221748. +++ linux-imx6-3.14/fs/btrfs/Kconfig 2014-09-11 18:06:10.122070401 +0200
  221749. @@ -1,5 +1,6 @@
  221750. config BTRFS_FS
  221751. tristate "Btrfs filesystem support"
  221752. + select LIBCRC32C
  221753. select CRYPTO
  221754. select CRYPTO_CRC32C
  221755. select ZLIB_INFLATE
  221756. diff -Nur linux-3.14.17/fs/buffer.c linux-imx6-3.14/fs/buffer.c
  221757. --- linux-3.14.17/fs/buffer.c 2014-08-14 03:38:34.000000000 +0200
  221758. +++ linux-imx6-3.14/fs/buffer.c 2014-09-11 18:06:10.218070784 +0200
  221759. @@ -3088,7 +3088,7 @@
  221760. * until the buffer gets unlocked).
  221761. *
  221762. * ll_rw_block sets b_end_io to simple completion handler that marks
  221763. - * the buffer up-to-date (if approriate), unlocks the buffer and wakes
  221764. + * the buffer up-to-date (if appropriate), unlocks the buffer and wakes
  221765. * any waiters.
  221766. *
  221767. * All of the buffers must be for the same device, and must also be a
  221768. diff -Nur linux-3.14.17/fs/compat_binfmt_elf.c linux-imx6-3.14/fs/compat_binfmt_elf.c
  221769. --- linux-3.14.17/fs/compat_binfmt_elf.c 2014-08-14 03:38:34.000000000 +0200
  221770. +++ linux-imx6-3.14/fs/compat_binfmt_elf.c 2014-09-11 18:06:10.286071055 +0200
  221771. @@ -88,6 +88,11 @@
  221772. #define ELF_HWCAP COMPAT_ELF_HWCAP
  221773. #endif
  221774. +#ifdef COMPAT_ELF_HWCAP2
  221775. +#undef ELF_HWCAP2
  221776. +#define ELF_HWCAP2 COMPAT_ELF_HWCAP2
  221777. +#endif
  221778. +
  221779. #ifdef COMPAT_ARCH_DLINFO
  221780. #undef ARCH_DLINFO
  221781. #define ARCH_DLINFO COMPAT_ARCH_DLINFO
  221782. diff -Nur linux-3.14.17/fs/coredump.c linux-imx6-3.14/fs/coredump.c
  221783. --- linux-3.14.17/fs/coredump.c 2014-08-14 03:38:34.000000000 +0200
  221784. +++ linux-imx6-3.14/fs/coredump.c 2014-09-11 18:06:10.290071071 +0200
  221785. @@ -306,7 +306,7 @@
  221786. if (unlikely(nr < 0))
  221787. return nr;
  221788. - tsk->flags |= PF_DUMPCORE;
  221789. + tsk->flags = PF_DUMPCORE;
  221790. if (atomic_read(&mm->mm_users) == nr + 1)
  221791. goto done;
  221792. /*
  221793. diff -Nur linux-3.14.17/fs/debugfs/inode.c linux-imx6-3.14/fs/debugfs/inode.c
  221794. --- linux-3.14.17/fs/debugfs/inode.c 2014-08-14 03:38:34.000000000 +0200
  221795. +++ linux-imx6-3.14/fs/debugfs/inode.c 2014-09-11 18:06:10.294071087 +0200
  221796. @@ -358,7 +358,7 @@
  221797. * @name: a pointer to a string containing the name of the file to create.
  221798. * @mode: the permission that the file should have.
  221799. * @parent: a pointer to the parent dentry for this file. This should be a
  221800. - * directory dentry if set. If this paramater is NULL, then the
  221801. + * directory dentry if set. If this parameter is NULL, then the
  221802. * file will be created in the root of the debugfs filesystem.
  221803. * @data: a pointer to something that the caller will want to get to later
  221804. * on. The inode.i_private pointer will point to this value on
  221805. @@ -400,7 +400,7 @@
  221806. * @name: a pointer to a string containing the name of the directory to
  221807. * create.
  221808. * @parent: a pointer to the parent dentry for this file. This should be a
  221809. - * directory dentry if set. If this paramater is NULL, then the
  221810. + * directory dentry if set. If this parameter is NULL, then the
  221811. * directory will be created in the root of the debugfs filesystem.
  221812. *
  221813. * This function creates a directory in debugfs with the given name.
  221814. @@ -425,7 +425,7 @@
  221815. * @name: a pointer to a string containing the name of the symbolic link to
  221816. * create.
  221817. * @parent: a pointer to the parent dentry for this symbolic link. This
  221818. - * should be a directory dentry if set. If this paramater is NULL,
  221819. + * should be a directory dentry if set. If this parameter is NULL,
  221820. * then the symbolic link will be created in the root of the debugfs
  221821. * filesystem.
  221822. * @target: a pointer to a string containing the path to the target of the
  221823. diff -Nur linux-3.14.17/fs/namei.c linux-imx6-3.14/fs/namei.c
  221824. --- linux-3.14.17/fs/namei.c 2014-08-14 03:38:34.000000000 +0200
  221825. +++ linux-imx6-3.14/fs/namei.c 2014-09-11 18:06:10.446071695 +0200
  221826. @@ -2247,10 +2247,9 @@
  221827. goto out;
  221828. }
  221829. path->dentry = dentry;
  221830. - path->mnt = nd->path.mnt;
  221831. + path->mnt = mntget(nd->path.mnt);
  221832. if (should_follow_link(dentry, nd->flags & LOOKUP_FOLLOW))
  221833. return 1;
  221834. - mntget(path->mnt);
  221835. follow_mount(path);
  221836. error = 0;
  221837. out:
  221838. diff -Nur linux-3.14.17/fs/nfs/nfs3acl.c linux-imx6-3.14/fs/nfs/nfs3acl.c
  221839. --- linux-3.14.17/fs/nfs/nfs3acl.c 2014-08-14 03:38:34.000000000 +0200
  221840. +++ linux-imx6-3.14/fs/nfs/nfs3acl.c 2014-09-11 18:06:10.458071742 +0200
  221841. @@ -247,46 +247,3 @@
  221842. &posix_acl_default_xattr_handler,
  221843. NULL,
  221844. };
  221845. -
  221846. -static int
  221847. -nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data,
  221848. - size_t size, ssize_t *result)
  221849. -{
  221850. - struct posix_acl *acl;
  221851. - char *p = data + *result;
  221852. -
  221853. - acl = get_acl(inode, type);
  221854. - if (!acl)
  221855. - return 0;
  221856. -
  221857. - posix_acl_release(acl);
  221858. -
  221859. - *result += strlen(name);
  221860. - *result += 1;
  221861. - if (!size)
  221862. - return 0;
  221863. - if (*result > size)
  221864. - return -ERANGE;
  221865. -
  221866. - strcpy(p, name);
  221867. - return 0;
  221868. -}
  221869. -
  221870. -ssize_t
  221871. -nfs3_listxattr(struct dentry *dentry, char *data, size_t size)
  221872. -{
  221873. - struct inode *inode = dentry->d_inode;
  221874. - ssize_t result = 0;
  221875. - int error;
  221876. -
  221877. - error = nfs3_list_one_acl(inode, ACL_TYPE_ACCESS,
  221878. - POSIX_ACL_XATTR_ACCESS, data, size, &result);
  221879. - if (error)
  221880. - return error;
  221881. -
  221882. - error = nfs3_list_one_acl(inode, ACL_TYPE_DEFAULT,
  221883. - POSIX_ACL_XATTR_DEFAULT, data, size, &result);
  221884. - if (error)
  221885. - return error;
  221886. - return result;
  221887. -}
  221888. diff -Nur linux-3.14.17/fs/nfs/nfs3proc.c linux-imx6-3.14/fs/nfs/nfs3proc.c
  221889. --- linux-3.14.17/fs/nfs/nfs3proc.c 2014-08-14 03:38:34.000000000 +0200
  221890. +++ linux-imx6-3.14/fs/nfs/nfs3proc.c 2014-09-11 18:06:10.458071742 +0200
  221891. @@ -926,7 +926,7 @@
  221892. .getattr = nfs_getattr,
  221893. .setattr = nfs_setattr,
  221894. #ifdef CONFIG_NFS_V3_ACL
  221895. - .listxattr = nfs3_listxattr,
  221896. + .listxattr = generic_listxattr,
  221897. .getxattr = generic_getxattr,
  221898. .setxattr = generic_setxattr,
  221899. .removexattr = generic_removexattr,
  221900. @@ -940,7 +940,7 @@
  221901. .getattr = nfs_getattr,
  221902. .setattr = nfs_setattr,
  221903. #ifdef CONFIG_NFS_V3_ACL
  221904. - .listxattr = nfs3_listxattr,
  221905. + .listxattr = generic_listxattr,
  221906. .getxattr = generic_getxattr,
  221907. .setxattr = generic_setxattr,
  221908. .removexattr = generic_removexattr,
  221909. diff -Nur linux-3.14.17/fs/xfs/xfs_log_cil.c linux-imx6-3.14/fs/xfs/xfs_log_cil.c
  221910. --- linux-3.14.17/fs/xfs/xfs_log_cil.c 2014-08-14 03:38:34.000000000 +0200
  221911. +++ linux-imx6-3.14/fs/xfs/xfs_log_cil.c 2014-09-11 18:06:10.606072333 +0200
  221912. @@ -97,7 +97,7 @@
  221913. {
  221914. /* Account for the new LV being passed in */
  221915. if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED) {
  221916. - *diff_len += lv->lv_bytes;
  221917. + *diff_len += lv->lv_buf_len;
  221918. *diff_iovecs += lv->lv_niovecs;
  221919. }
  221920. @@ -111,7 +111,7 @@
  221921. else if (old_lv != lv) {
  221922. ASSERT(lv->lv_buf_len != XFS_LOG_VEC_ORDERED);
  221923. - *diff_len -= old_lv->lv_bytes;
  221924. + *diff_len -= old_lv->lv_buf_len;
  221925. *diff_iovecs -= old_lv->lv_niovecs;
  221926. kmem_free(old_lv);
  221927. }
  221928. @@ -239,7 +239,7 @@
  221929. * that the space reservation accounting is correct.
  221930. */
  221931. *diff_iovecs -= lv->lv_niovecs;
  221932. - *diff_len -= lv->lv_bytes;
  221933. + *diff_len -= lv->lv_buf_len;
  221934. } else {
  221935. /* allocate new data chunk */
  221936. lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS);
  221937. @@ -259,7 +259,6 @@
  221938. /* The allocated data region lies beyond the iovec region */
  221939. lv->lv_buf_len = 0;
  221940. - lv->lv_bytes = 0;
  221941. lv->lv_buf = (char *)lv + buf_size - nbytes;
  221942. ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t)));
  221943. diff -Nur linux-3.14.17/fs/xfs/xfs_log.h linux-imx6-3.14/fs/xfs/xfs_log.h
  221944. --- linux-3.14.17/fs/xfs/xfs_log.h 2014-08-14 03:38:34.000000000 +0200
  221945. +++ linux-imx6-3.14/fs/xfs/xfs_log.h 2014-09-11 18:06:10.602072317 +0200
  221946. @@ -24,8 +24,7 @@
  221947. struct xfs_log_iovec *lv_iovecp; /* iovec array */
  221948. struct xfs_log_item *lv_item; /* owner */
  221949. char *lv_buf; /* formatted buffer */
  221950. - int lv_bytes; /* accounted space in buffer */
  221951. - int lv_buf_len; /* aligned size of buffer */
  221952. + int lv_buf_len; /* size of formatted buffer */
  221953. int lv_size; /* size of allocated lv */
  221954. };
  221955. @@ -53,21 +52,15 @@
  221956. return vec->i_addr;
  221957. }
  221958. -/*
  221959. - * We need to make sure the next buffer is naturally aligned for the biggest
  221960. - * basic data type we put into it. We already accounted for this padding when
  221961. - * sizing the buffer.
  221962. - *
  221963. - * However, this padding does not get written into the log, and hence we have to
  221964. - * track the space used by the log vectors separately to prevent log space hangs
  221965. - * due to inaccurate accounting (i.e. a leak) of the used log space through the
  221966. - * CIL context ticket.
  221967. - */
  221968. static inline void
  221969. xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len)
  221970. {
  221971. + /*
  221972. + * We need to make sure the next buffer is naturally aligned for the
  221973. + * biggest basic data type we put into it. We already accounted for
  221974. + * this when sizing the buffer.
  221975. + */
  221976. lv->lv_buf_len += round_up(len, sizeof(uint64_t));
  221977. - lv->lv_bytes += len;
  221978. vec->i_len = len;
  221979. }
  221980. diff -Nur linux-3.14.17/include/asm-generic/word-at-a-time.h linux-imx6-3.14/include/asm-generic/word-at-a-time.h
  221981. --- linux-3.14.17/include/asm-generic/word-at-a-time.h 2014-08-14 03:38:34.000000000 +0200
  221982. +++ linux-imx6-3.14/include/asm-generic/word-at-a-time.h 2014-09-11 18:06:10.650072508 +0200
  221983. @@ -50,7 +50,7 @@
  221984. }
  221985. #ifndef zero_bytemask
  221986. -#define zero_bytemask(mask) (~0ul << __fls(mask) << 1)
  221987. +#define zero_bytemask(mask) (~1ul << __fls(mask))
  221988. #endif
  221989. #endif /* _ASM_WORD_AT_A_TIME_H */
  221990. diff -Nur linux-3.14.17/include/crypto/algapi.h linux-imx6-3.14/include/crypto/algapi.h
  221991. --- linux-3.14.17/include/crypto/algapi.h 2014-08-14 03:38:34.000000000 +0200
  221992. +++ linux-imx6-3.14/include/crypto/algapi.h 2014-09-11 18:06:10.650072508 +0200
  221993. @@ -100,9 +100,12 @@
  221994. void *page;
  221995. u8 *buffer;
  221996. u8 *iv;
  221997. + unsigned int ivsize;
  221998. int flags;
  221999. - unsigned int blocksize;
  222000. + unsigned int walk_blocksize;
  222001. + unsigned int cipher_blocksize;
  222002. + unsigned int alignmask;
  222003. };
  222004. struct ablkcipher_walk {
  222005. @@ -192,6 +195,10 @@
  222006. int blkcipher_walk_virt_block(struct blkcipher_desc *desc,
  222007. struct blkcipher_walk *walk,
  222008. unsigned int blocksize);
  222009. +int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
  222010. + struct blkcipher_walk *walk,
  222011. + struct crypto_aead *tfm,
  222012. + unsigned int blocksize);
  222013. int ablkcipher_walk_done(struct ablkcipher_request *req,
  222014. struct ablkcipher_walk *walk, int err);
  222015. diff -Nur linux-3.14.17/include/drm/drm_fb_helper.h linux-imx6-3.14/include/drm/drm_fb_helper.h
  222016. --- linux-3.14.17/include/drm/drm_fb_helper.h 2014-08-14 03:38:34.000000000 +0200
  222017. +++ linux-imx6-3.14/include/drm/drm_fb_helper.h 2014-09-11 18:06:10.674072603 +0200
  222018. @@ -55,7 +55,7 @@
  222019. * save the current lut when force-restoring the fbdev for e.g.
  222020. * kdbg.
  222021. * @fb_probe: Driver callback to allocate and initialize the fbdev info
  222022. - * structure. Futhermore it also needs to allocate the drm
  222023. + * structure. Furthermore it also needs to allocate the drm
  222024. * framebuffer used to back the fbdev.
  222025. * @initial_config: Setup an initial fbdev display configuration
  222026. *
  222027. diff -Nur linux-3.14.17/include/dt-bindings/clock/imx6sl-clock.h linux-imx6-3.14/include/dt-bindings/clock/imx6sl-clock.h
  222028. --- linux-3.14.17/include/dt-bindings/clock/imx6sl-clock.h 2014-08-14 03:38:34.000000000 +0200
  222029. +++ linux-imx6-3.14/include/dt-bindings/clock/imx6sl-clock.h 2014-09-11 18:06:10.686072652 +0200
  222030. @@ -1,5 +1,5 @@
  222031. /*
  222032. - * Copyright 2013 Freescale Semiconductor, Inc.
  222033. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  222034. *
  222035. * This program is free software; you can redistribute it and/or modify
  222036. * it under the terms of the GNU General Public License version 2 as
  222037. @@ -71,8 +71,8 @@
  222038. #define IMX6SL_CLK_PERIPH 58
  222039. #define IMX6SL_CLK_PERIPH2 59
  222040. #define IMX6SL_CLK_OCRAM_PODF 60
  222041. -#define IMX6SL_CLK_PERIPH_CLK2_PODF 61
  222042. -#define IMX6SL_CLK_PERIPH2_CLK2_PODF 62
  222043. +#define IMX6SL_CLK_PERIPH_CLK2 61
  222044. +#define IMX6SL_CLK_PERIPH2_CLK2 62
  222045. #define IMX6SL_CLK_IPG 63
  222046. #define IMX6SL_CLK_CSI_PODF 64
  222047. #define IMX6SL_CLK_LCDIF_AXI_PODF 65
  222048. @@ -145,6 +145,7 @@
  222049. #define IMX6SL_CLK_USDHC4 132
  222050. #define IMX6SL_CLK_PLL4_AUDIO_DIV 133
  222051. #define IMX6SL_CLK_SPBA 134
  222052. -#define IMX6SL_CLK_END 135
  222053. +#define IMX6SL_CLK_UART_OSC_4M 135
  222054. +#define IMX6SL_CLK_END 136
  222055. #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
  222056. diff -Nur linux-3.14.17/include/dt-bindings/pinctrl/dra.h linux-imx6-3.14/include/dt-bindings/pinctrl/dra.h
  222057. --- linux-3.14.17/include/dt-bindings/pinctrl/dra.h 2014-08-14 03:38:34.000000000 +0200
  222058. +++ linux-imx6-3.14/include/dt-bindings/pinctrl/dra.h 2014-09-11 18:06:10.702072715 +0200
  222059. @@ -30,8 +30,7 @@
  222060. #define MUX_MODE14 0xe
  222061. #define MUX_MODE15 0xf
  222062. -#define PULL_ENA (0 << 16)
  222063. -#define PULL_DIS (1 << 16)
  222064. +#define PULL_ENA (1 << 16)
  222065. #define PULL_UP (1 << 17)
  222066. #define INPUT_EN (1 << 18)
  222067. #define SLEWCONTROL (1 << 19)
  222068. @@ -39,10 +38,10 @@
  222069. #define WAKEUP_EVENT (1 << 25)
  222070. /* Active pin states */
  222071. -#define PIN_OUTPUT (0 | PULL_DIS)
  222072. +#define PIN_OUTPUT 0
  222073. #define PIN_OUTPUT_PULLUP (PIN_OUTPUT | PULL_ENA | PULL_UP)
  222074. #define PIN_OUTPUT_PULLDOWN (PIN_OUTPUT | PULL_ENA)
  222075. -#define PIN_INPUT (INPUT_EN | PULL_DIS)
  222076. +#define PIN_INPUT INPUT_EN
  222077. #define PIN_INPUT_SLEW (INPUT_EN | SLEWCONTROL)
  222078. #define PIN_INPUT_PULLUP (PULL_ENA | INPUT_EN | PULL_UP)
  222079. #define PIN_INPUT_PULLDOWN (PULL_ENA | INPUT_EN)
  222080. diff -Nur linux-3.14.17/include/linux/ahci_platform.h linux-imx6-3.14/include/linux/ahci_platform.h
  222081. --- linux-3.14.17/include/linux/ahci_platform.h 2014-08-14 03:38:34.000000000 +0200
  222082. +++ linux-imx6-3.14/include/linux/ahci_platform.h 2014-09-11 18:06:10.706072732 +0200
  222083. @@ -19,15 +19,38 @@
  222084. struct device;
  222085. struct ata_port_info;
  222086. +struct ahci_host_priv;
  222087. +struct platform_device;
  222088. +/*
  222089. + * Note ahci_platform_data is deprecated, it is only kept around for use
  222090. + * by the old da850 and spear13xx ahci code.
  222091. + * New drivers should instead declare their own platform_driver struct, and
  222092. + * use ahci_platform* functions in their own probe, suspend and resume methods.
  222093. + */
  222094. struct ahci_platform_data {
  222095. int (*init)(struct device *dev, void __iomem *addr);
  222096. void (*exit)(struct device *dev);
  222097. int (*suspend)(struct device *dev);
  222098. int (*resume)(struct device *dev);
  222099. - const struct ata_port_info *ata_port_info;
  222100. - unsigned int force_port_map;
  222101. - unsigned int mask_port_map;
  222102. };
  222103. +int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
  222104. +void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
  222105. +int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
  222106. +void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
  222107. +struct ahci_host_priv *ahci_platform_get_resources(
  222108. + struct platform_device *pdev);
  222109. +int ahci_platform_init_host(struct platform_device *pdev,
  222110. + struct ahci_host_priv *hpriv,
  222111. + const struct ata_port_info *pi_template,
  222112. + unsigned long host_flags,
  222113. + unsigned int force_port_map,
  222114. + unsigned int mask_port_map);
  222115. +
  222116. +int ahci_platform_suspend_host(struct device *dev);
  222117. +int ahci_platform_resume_host(struct device *dev);
  222118. +int ahci_platform_suspend(struct device *dev);
  222119. +int ahci_platform_resume(struct device *dev);
  222120. +
  222121. #endif /* _AHCI_PLATFORM_H */
  222122. diff -Nur linux-3.14.17/include/linux/amba/clcd.h linux-imx6-3.14/include/linux/amba/clcd.h
  222123. --- linux-3.14.17/include/linux/amba/clcd.h 2014-08-14 03:38:34.000000000 +0200
  222124. +++ linux-imx6-3.14/include/linux/amba/clcd.h 2014-09-11 18:06:10.706072732 +0200
  222125. @@ -243,6 +243,9 @@
  222126. val |= CNTL_BGR;
  222127. }
  222128. + /* Reset the current colour depth */
  222129. + val &= ~CNTL_LCDBPP16_444;
  222130. +
  222131. switch (var->bits_per_pixel) {
  222132. case 1:
  222133. val |= CNTL_LCDBPP1;
  222134. @@ -264,14 +267,15 @@
  222135. */
  222136. if (amba_part(fb->dev) == 0x110 ||
  222137. var->green.length == 5)
  222138. - val |= CNTL_LCDBPP16;
  222139. + val |= CNTL_LCDBPP16 | CNTL_BGR;
  222140. else if (var->green.length == 6)
  222141. - val |= CNTL_LCDBPP16_565;
  222142. + val |= CNTL_LCDBPP16_565 | CNTL_BGR;
  222143. else
  222144. - val |= CNTL_LCDBPP16_444;
  222145. + val |= CNTL_LCDBPP16_444 | CNTL_BGR;
  222146. break;
  222147. case 32:
  222148. val |= CNTL_LCDBPP24;
  222149. + val &= ~CNTL_BGR;
  222150. break;
  222151. }
  222152. diff -Nur linux-3.14.17/include/linux/arm-hdlcd.h linux-imx6-3.14/include/linux/arm-hdlcd.h
  222153. --- linux-3.14.17/include/linux/arm-hdlcd.h 1970-01-01 01:00:00.000000000 +0100
  222154. +++ linux-imx6-3.14/include/linux/arm-hdlcd.h 2014-09-11 18:06:10.710072748 +0200
  222155. @@ -0,0 +1,122 @@
  222156. +/*
  222157. + * include/linux/arm-hdlcd.h
  222158. + *
  222159. + * Copyright (C) 2011 ARM Limited
  222160. + *
  222161. + * This file is subject to the terms and conditions of the GNU General Public
  222162. + * License. See the file COPYING in the main directory of this archive
  222163. + * for more details.
  222164. + *
  222165. + * ARM HDLCD Controller register definition
  222166. + */
  222167. +
  222168. +#include <linux/fb.h>
  222169. +#include <linux/completion.h>
  222170. +
  222171. +/* register offsets */
  222172. +#define HDLCD_REG_VERSION 0x0000 /* ro */
  222173. +#define HDLCD_REG_INT_RAWSTAT 0x0010 /* rw */
  222174. +#define HDLCD_REG_INT_CLEAR 0x0014 /* wo */
  222175. +#define HDLCD_REG_INT_MASK 0x0018 /* rw */
  222176. +#define HDLCD_REG_INT_STATUS 0x001c /* ro */
  222177. +#define HDLCD_REG_USER_OUT 0x0020 /* rw */
  222178. +#define HDLCD_REG_FB_BASE 0x0100 /* rw */
  222179. +#define HDLCD_REG_FB_LINE_LENGTH 0x0104 /* rw */
  222180. +#define HDLCD_REG_FB_LINE_COUNT 0x0108 /* rw */
  222181. +#define HDLCD_REG_FB_LINE_PITCH 0x010c /* rw */
  222182. +#define HDLCD_REG_BUS_OPTIONS 0x0110 /* rw */
  222183. +#define HDLCD_REG_V_SYNC 0x0200 /* rw */
  222184. +#define HDLCD_REG_V_BACK_PORCH 0x0204 /* rw */
  222185. +#define HDLCD_REG_V_DATA 0x0208 /* rw */
  222186. +#define HDLCD_REG_V_FRONT_PORCH 0x020c /* rw */
  222187. +#define HDLCD_REG_H_SYNC 0x0210 /* rw */
  222188. +#define HDLCD_REG_H_BACK_PORCH 0x0214 /* rw */
  222189. +#define HDLCD_REG_H_DATA 0x0218 /* rw */
  222190. +#define HDLCD_REG_H_FRONT_PORCH 0x021c /* rw */
  222191. +#define HDLCD_REG_POLARITIES 0x0220 /* rw */
  222192. +#define HDLCD_REG_COMMAND 0x0230 /* rw */
  222193. +#define HDLCD_REG_PIXEL_FORMAT 0x0240 /* rw */
  222194. +#define HDLCD_REG_BLUE_SELECT 0x0244 /* rw */
  222195. +#define HDLCD_REG_GREEN_SELECT 0x0248 /* rw */
  222196. +#define HDLCD_REG_RED_SELECT 0x024c /* rw */
  222197. +
  222198. +/* version */
  222199. +#define HDLCD_PRODUCT_ID 0x1CDC0000
  222200. +#define HDLCD_PRODUCT_MASK 0xFFFF0000
  222201. +#define HDLCD_VERSION_MAJOR_MASK 0x0000FF00
  222202. +#define HDLCD_VERSION_MINOR_MASK 0x000000FF
  222203. +
  222204. +/* interrupts */
  222205. +#define HDLCD_INTERRUPT_DMA_END (1 << 0)
  222206. +#define HDLCD_INTERRUPT_BUS_ERROR (1 << 1)
  222207. +#define HDLCD_INTERRUPT_VSYNC (1 << 2)
  222208. +#define HDLCD_INTERRUPT_UNDERRUN (1 << 3)
  222209. +
  222210. +/* polarity */
  222211. +#define HDLCD_POLARITY_VSYNC (1 << 0)
  222212. +#define HDLCD_POLARITY_HSYNC (1 << 1)
  222213. +#define HDLCD_POLARITY_DATAEN (1 << 2)
  222214. +#define HDLCD_POLARITY_DATA (1 << 3)
  222215. +#define HDLCD_POLARITY_PIXELCLK (1 << 4)
  222216. +
  222217. +/* commands */
  222218. +#define HDLCD_COMMAND_DISABLE (0 << 0)
  222219. +#define HDLCD_COMMAND_ENABLE (1 << 0)
  222220. +
  222221. +/* pixel format */
  222222. +#define HDLCD_PIXEL_FMT_LITTLE_ENDIAN (0 << 31)
  222223. +#define HDLCD_PIXEL_FMT_BIG_ENDIAN (1 << 31)
  222224. +#define HDLCD_BYTES_PER_PIXEL_MASK (3 << 3)
  222225. +
  222226. +/* bus options */
  222227. +#define HDLCD_BUS_BURST_MASK 0x01f
  222228. +#define HDLCD_BUS_MAX_OUTSTAND 0xf00
  222229. +#define HDLCD_BUS_BURST_NONE (0 << 0)
  222230. +#define HDLCD_BUS_BURST_1 (1 << 0)
  222231. +#define HDLCD_BUS_BURST_2 (1 << 1)
  222232. +#define HDLCD_BUS_BURST_4 (1 << 2)
  222233. +#define HDLCD_BUS_BURST_8 (1 << 3)
  222234. +#define HDLCD_BUS_BURST_16 (1 << 4)
  222235. +
  222236. +/* Max resolution supported is 4096x4096, 8 bit per color component,
  222237. + 8 bit alpha, but we are going to choose the usual hardware default
  222238. + (2048x2048, 32 bpp) and enable double buffering */
  222239. +#define HDLCD_MAX_XRES 2048
  222240. +#define HDLCD_MAX_YRES 2048
  222241. +#define HDLCD_MAX_FRAMEBUFFER_SIZE (HDLCD_MAX_XRES * HDLCD_MAX_YRES << 2)
  222242. +
  222243. +#define HDLCD_MEM_BASE (CONFIG_PAGE_OFFSET - 0x1000000)
  222244. +
  222245. +#define NR_PALETTE 256
  222246. +
  222247. +/* OEMs using HDLCD may wish to enable these settings if
  222248. + * display disruption is apparent and you suspect HDLCD
  222249. + * access to RAM may be starved.
  222250. + */
  222251. +/* Turn HDLCD default color red instead of black so
  222252. + * that it's easy to see pixel clock data underruns
  222253. + * (compared to other visual disruption)
  222254. + */
  222255. +//#define HDLCD_RED_DEFAULT_COLOUR
  222256. +/* Add a counter in the IRQ handler to count buffer underruns
  222257. + * and /proc/hdlcd_underrun to read the counter
  222258. + */
  222259. +//#define HDLCD_COUNT_BUFFERUNDERRUNS
  222260. +/* Restrict height to 1x screen size
  222261. + *
  222262. + */
  222263. +//#define HDLCD_NO_VIRTUAL_SCREEN
  222264. +
  222265. +#ifdef CONFIG_ANDROID
  222266. +#define HDLCD_NO_VIRTUAL_SCREEN
  222267. +#endif
  222268. +
  222269. +struct hdlcd_device {
  222270. + struct fb_info fb;
  222271. + struct device *dev;
  222272. + struct clk *clk;
  222273. + void __iomem *base;
  222274. + int irq;
  222275. + struct completion vsync_completion;
  222276. + unsigned char *edid;
  222277. +};
  222278. diff -Nur linux-3.14.17/include/linux/backlight.h linux-imx6-3.14/include/linux/backlight.h
  222279. --- linux-3.14.17/include/linux/backlight.h 2014-08-14 03:38:34.000000000 +0200
  222280. +++ linux-imx6-3.14/include/linux/backlight.h 2014-09-11 18:06:10.722072796 +0200
  222281. @@ -9,6 +9,7 @@
  222282. #define _LINUX_BACKLIGHT_H
  222283. #include <linux/device.h>
  222284. +#include <linux/fb.h>
  222285. #include <linux/mutex.h>
  222286. #include <linux/notifier.h>
  222287. @@ -104,6 +105,11 @@
  222288. struct list_head entry;
  222289. struct device dev;
  222290. +
  222291. + /* Multiple framebuffers may share one backlight device */
  222292. + bool fb_bl_on[FB_MAX];
  222293. +
  222294. + int use_count;
  222295. };
  222296. static inline void backlight_update_status(struct backlight_device *bd)
  222297. diff -Nur linux-3.14.17/include/linux/busfreq-imx6.h linux-imx6-3.14/include/linux/busfreq-imx6.h
  222298. --- linux-3.14.17/include/linux/busfreq-imx6.h 1970-01-01 01:00:00.000000000 +0100
  222299. +++ linux-imx6-3.14/include/linux/busfreq-imx6.h 2014-09-11 18:06:10.730072828 +0200
  222300. @@ -0,0 +1,23 @@
  222301. +/*
  222302. + * Copyright 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  222303. + *
  222304. + * This program is free software; you can redistribute it and/or modify
  222305. + * it under the terms of the GNU General Public License version 2 as
  222306. + * published by the Free Software Foundation.
  222307. + */
  222308. +
  222309. +#ifndef __ASM_ARCH_MXC_BUSFREQ_H__
  222310. +#define __ASM_ARCH_MXC_BUSFREQ_H__
  222311. +
  222312. +/*
  222313. + * This enumerates busfreq mode.
  222314. + */
  222315. +enum bus_freq_mode {
  222316. + BUS_FREQ_HIGH,
  222317. + BUS_FREQ_MED,
  222318. + BUS_FREQ_AUDIO,
  222319. + BUS_FREQ_LOW,
  222320. +};
  222321. +void request_bus_freq(enum bus_freq_mode mode);
  222322. +void release_bus_freq(enum bus_freq_mode mode);
  222323. +#endif
  222324. diff -Nur linux-3.14.17/include/linux/cgroup_subsys.h linux-imx6-3.14/include/linux/cgroup_subsys.h
  222325. --- linux-3.14.17/include/linux/cgroup_subsys.h 2014-08-14 03:38:34.000000000 +0200
  222326. +++ linux-imx6-3.14/include/linux/cgroup_subsys.h 2014-09-11 18:06:10.734072844 +0200
  222327. @@ -39,6 +39,10 @@
  222328. SUBSYS(blkio)
  222329. #endif
  222330. +#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_BFQIO)
  222331. +SUBSYS(bfqio)
  222332. +#endif
  222333. +
  222334. #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF)
  222335. SUBSYS(perf)
  222336. #endif
  222337. diff -Nur linux-3.14.17/include/linux/clk-provider.h linux-imx6-3.14/include/linux/clk-provider.h
  222338. --- linux-3.14.17/include/linux/clk-provider.h 2014-08-14 03:38:34.000000000 +0200
  222339. +++ linux-imx6-3.14/include/linux/clk-provider.h 2014-09-11 18:06:10.734072844 +0200
  222340. @@ -30,6 +30,13 @@
  222341. #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
  222342. #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
  222343. #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
  222344. +/*
  222345. + * Basic mux clk, can't switch parent while there is another basic mux clk
  222346. + * being its child. Otherwise, a glitch might be propagated to downstream
  222347. + * clocks through this child mux.
  222348. + */
  222349. +#define CLK_IS_BASIC_MUX BIT(9)
  222350. +
  222351. struct clk_hw;
  222352. diff -Nur linux-3.14.17/include/linux/cma.h linux-imx6-3.14/include/linux/cma.h
  222353. --- linux-3.14.17/include/linux/cma.h 1970-01-01 01:00:00.000000000 +0100
  222354. +++ linux-imx6-3.14/include/linux/cma.h 2014-09-11 18:06:10.758072940 +0200
  222355. @@ -0,0 +1,27 @@
  222356. +#ifndef __CMA_H__
  222357. +#define __CMA_H__
  222358. +
  222359. +/*
  222360. + * There is always at least global CMA area and a few optional
  222361. + * areas configured in kernel .config.
  222362. + */
  222363. +#ifdef CONFIG_CMA_AREAS
  222364. +#define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS)
  222365. +
  222366. +#else
  222367. +#define MAX_CMA_AREAS (0)
  222368. +
  222369. +#endif
  222370. +
  222371. +struct cma;
  222372. +
  222373. +extern phys_addr_t cma_get_base(struct cma *cma);
  222374. +extern unsigned long cma_get_size(struct cma *cma);
  222375. +
  222376. +extern int __init cma_declare_contiguous(phys_addr_t size,
  222377. + phys_addr_t base, phys_addr_t limit,
  222378. + phys_addr_t alignment, unsigned int order_per_bit,
  222379. + bool fixed, struct cma **res_cma);
  222380. +extern struct page *cma_alloc(struct cma *cma, int count, unsigned int align);
  222381. +extern bool cma_release(struct cma *cma, struct page *pages, int count);
  222382. +#endif
  222383. diff -Nur linux-3.14.17/include/linux/cpufeature.h linux-imx6-3.14/include/linux/cpufeature.h
  222384. --- linux-3.14.17/include/linux/cpufeature.h 1970-01-01 01:00:00.000000000 +0100
  222385. +++ linux-imx6-3.14/include/linux/cpufeature.h 2014-09-11 18:06:10.762072955 +0200
  222386. @@ -0,0 +1,60 @@
  222387. +/*
  222388. + * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
  222389. + *
  222390. + * This program is free software; you can redistribute it and/or modify
  222391. + * it under the terms of the GNU General Public License version 2 as
  222392. + * published by the Free Software Foundation.
  222393. + */
  222394. +
  222395. +#ifndef __LINUX_CPUFEATURE_H
  222396. +#define __LINUX_CPUFEATURE_H
  222397. +
  222398. +#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
  222399. +
  222400. +#include <linux/mod_devicetable.h>
  222401. +#include <asm/cpufeature.h>
  222402. +
  222403. +/*
  222404. + * Macros imported from <asm/cpufeature.h>:
  222405. + * - cpu_feature(x) ordinal value of feature called 'x'
  222406. + * - cpu_have_feature(u32 n) whether feature #n is available
  222407. + * - MAX_CPU_FEATURES upper bound for feature ordinal values
  222408. + * Optional:
  222409. + * - CPU_FEATURE_TYPEFMT format string fragment for printing the cpu type
  222410. + * - CPU_FEATURE_TYPEVAL set of values matching the format string above
  222411. + */
  222412. +
  222413. +#ifndef CPU_FEATURE_TYPEFMT
  222414. +#define CPU_FEATURE_TYPEFMT "%s"
  222415. +#endif
  222416. +
  222417. +#ifndef CPU_FEATURE_TYPEVAL
  222418. +#define CPU_FEATURE_TYPEVAL ELF_PLATFORM
  222419. +#endif
  222420. +
  222421. +/*
  222422. + * Use module_cpu_feature_match(feature, module_init_function) to
  222423. + * declare that
  222424. + * a) the module shall be probed upon discovery of CPU feature 'feature'
  222425. + * (typically at boot time using udev)
  222426. + * b) the module must not be loaded if CPU feature 'feature' is not present
  222427. + * (not even by manual insmod).
  222428. + *
  222429. + * For a list of legal values for 'feature', please consult the file
  222430. + * 'asm/cpufeature.h' of your favorite architecture.
  222431. + */
  222432. +#define module_cpu_feature_match(x, __init) \
  222433. +static struct cpu_feature const cpu_feature_match_ ## x[] = \
  222434. + { { .feature = cpu_feature(x) }, { } }; \
  222435. +MODULE_DEVICE_TABLE(cpu, cpu_feature_match_ ## x); \
  222436. + \
  222437. +static int cpu_feature_match_ ## x ## _init(void) \
  222438. +{ \
  222439. + if (!cpu_have_feature(cpu_feature(x))) \
  222440. + return -ENODEV; \
  222441. + return __init(); \
  222442. +} \
  222443. +module_init(cpu_feature_match_ ## x ## _init)
  222444. +
  222445. +#endif
  222446. +#endif
  222447. diff -Nur linux-3.14.17/include/linux/cpufreq.h linux-imx6-3.14/include/linux/cpufreq.h
  222448. --- linux-3.14.17/include/linux/cpufreq.h 2014-08-14 03:38:34.000000000 +0200
  222449. +++ linux-imx6-3.14/include/linux/cpufreq.h 2014-09-11 18:06:10.762072955 +0200
  222450. @@ -429,6 +429,9 @@
  222451. #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND)
  222452. extern struct cpufreq_governor cpufreq_gov_ondemand;
  222453. #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_ondemand)
  222454. +#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE)
  222455. +extern struct cpufreq_governor cpufreq_gov_interactive;
  222456. +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_interactive)
  222457. #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE)
  222458. extern struct cpufreq_governor cpufreq_gov_conservative;
  222459. #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative)
  222460. diff -Nur linux-3.14.17/include/linux/cpu.h linux-imx6-3.14/include/linux/cpu.h
  222461. --- linux-3.14.17/include/linux/cpu.h 2014-08-14 03:38:34.000000000 +0200
  222462. +++ linux-imx6-3.14/include/linux/cpu.h 2014-09-11 18:06:10.762072955 +0200
  222463. @@ -226,4 +226,11 @@
  222464. void arch_cpu_idle_exit(void);
  222465. void arch_cpu_idle_dead(void);
  222466. +#define IDLE_START 1
  222467. +#define IDLE_END 2
  222468. +
  222469. +void idle_notifier_register(struct notifier_block *n);
  222470. +void idle_notifier_unregister(struct notifier_block *n);
  222471. +void idle_notifier_call_chain(unsigned long val);
  222472. +
  222473. #endif /* _LINUX_CPU_H_ */
  222474. diff -Nur linux-3.14.17/include/linux/device_cooling.h linux-imx6-3.14/include/linux/device_cooling.h
  222475. --- linux-3.14.17/include/linux/device_cooling.h 1970-01-01 01:00:00.000000000 +0100
  222476. +++ linux-imx6-3.14/include/linux/device_cooling.h 2014-09-11 18:06:10.770072987 +0200
  222477. @@ -0,0 +1,45 @@
  222478. +/*
  222479. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  222480. + *
  222481. + * This program is free software; you can redistribute it and/or modify
  222482. + * it under the terms of the GNU General Public License version 2 as
  222483. + * published by the Free Software Foundation.
  222484. + *
  222485. + */
  222486. +
  222487. +#ifndef __DEVICE_THERMAL_H__
  222488. +#define __DEVICE_THERMAL_H__
  222489. +
  222490. +#include <linux/thermal.h>
  222491. +
  222492. +#ifdef CONFIG_DEVICE_THERMAL
  222493. +int register_devfreq_cooling_notifier(struct notifier_block *nb);
  222494. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb);
  222495. +struct thermal_cooling_device *devfreq_cooling_register(void);
  222496. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev);
  222497. +#else
  222498. +static inline
  222499. +int register_devfreq_cooling_notifier(struct notifier_block *nb)
  222500. +{
  222501. + return 0;
  222502. +}
  222503. +
  222504. +static inline
  222505. +int unregister_devfreq_cooling_notifier(struct notifier_block *nb)
  222506. +{
  222507. + return 0;
  222508. +}
  222509. +
  222510. +static inline
  222511. +struct thermal_cooling_device *devfreq_cooling_register(void)
  222512. +{
  222513. + return NULL;
  222514. +}
  222515. +
  222516. +static inline
  222517. +void devfreq_cooling_unregister(struct thermal_cooling_device *cdev)
  222518. +{
  222519. + return;
  222520. +}
  222521. +#endif
  222522. +#endif /* __DEVICE_THERMAL_H__ */
  222523. diff -Nur linux-3.14.17/include/linux/dma-contiguous.h linux-imx6-3.14/include/linux/dma-contiguous.h
  222524. --- linux-3.14.17/include/linux/dma-contiguous.h 2014-08-14 03:38:34.000000000 +0200
  222525. +++ linux-imx6-3.14/include/linux/dma-contiguous.h 2014-09-11 18:06:10.770072987 +0200
  222526. @@ -53,18 +53,13 @@
  222527. #ifdef __KERNEL__
  222528. +#include <linux/device.h>
  222529. +
  222530. struct cma;
  222531. struct page;
  222532. -struct device;
  222533. #ifdef CONFIG_DMA_CMA
  222534. -/*
  222535. - * There is always at least global CMA area and a few optional device
  222536. - * private areas configured in kernel .config.
  222537. - */
  222538. -#define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS)
  222539. -
  222540. extern struct cma *dma_contiguous_default_area;
  222541. static inline struct cma *dev_get_cma_area(struct device *dev)
  222542. @@ -88,7 +83,8 @@
  222543. void dma_contiguous_reserve(phys_addr_t addr_limit);
  222544. int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  222545. - phys_addr_t limit, struct cma **res_cma);
  222546. + phys_addr_t limit, struct cma **res_cma,
  222547. + bool fixed);
  222548. /**
  222549. * dma_declare_contiguous() - reserve area for contiguous memory handling
  222550. @@ -108,7 +104,7 @@
  222551. {
  222552. struct cma *cma;
  222553. int ret;
  222554. - ret = dma_contiguous_reserve_area(size, base, limit, &cma);
  222555. + ret = dma_contiguous_reserve_area(size, base, limit, &cma, true);
  222556. if (ret == 0)
  222557. dev_set_cma_area(dev, cma);
  222558. @@ -122,8 +118,6 @@
  222559. #else
  222560. -#define MAX_CMA_AREAS (0)
  222561. -
  222562. static inline struct cma *dev_get_cma_area(struct device *dev)
  222563. {
  222564. return NULL;
  222565. @@ -136,7 +130,9 @@
  222566. static inline void dma_contiguous_reserve(phys_addr_t limit) { }
  222567. static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
  222568. - phys_addr_t limit, struct cma **res_cma) {
  222569. + phys_addr_t limit, struct cma **res_cma,
  222570. + bool fixed)
  222571. +{
  222572. return -ENOSYS;
  222573. }
  222574. diff -Nur linux-3.14.17/include/linux/dmaengine.h linux-imx6-3.14/include/linux/dmaengine.h
  222575. --- linux-3.14.17/include/linux/dmaengine.h 2014-08-14 03:38:34.000000000 +0200
  222576. +++ linux-imx6-3.14/include/linux/dmaengine.h 2014-09-11 18:06:10.774073003 +0200
  222577. @@ -333,6 +333,8 @@
  222578. * @slave_id: Slave requester id. Only valid for slave channels. The dma
  222579. * slave peripheral will have unique id as dma requester which need to be
  222580. * pass as slave config.
  222581. + * @dma_request0: this is the first dma request of this dma channel.
  222582. + * @dma_request1: this is the second dma request of this dma channel.
  222583. *
  222584. * This struct is passed in as configuration data to a DMA engine
  222585. * in order to set up a certain channel for DMA transport at runtime.
  222586. @@ -361,6 +363,8 @@
  222587. u32 dst_maxburst;
  222588. bool device_fc;
  222589. unsigned int slave_id;
  222590. + int dma_request0;
  222591. + int dma_request1;
  222592. };
  222593. /**
  222594. diff -Nur linux-3.14.17/include/linux/ftrace.h linux-imx6-3.14/include/linux/ftrace.h
  222595. --- linux-3.14.17/include/linux/ftrace.h 2014-08-14 03:38:34.000000000 +0200
  222596. +++ linux-imx6-3.14/include/linux/ftrace.h 2014-09-11 18:06:10.794073083 +0200
  222597. @@ -605,25 +605,27 @@
  222598. #endif
  222599. }
  222600. -#ifndef HAVE_ARCH_CALLER_ADDR
  222601. +/* All archs should have this, but we define it for consistency */
  222602. +#ifndef ftrace_return_address0
  222603. +# define ftrace_return_address0 __builtin_return_address(0)
  222604. +#endif
  222605. +
  222606. +/* Archs may use other ways for ADDR1 and beyond */
  222607. +#ifndef ftrace_return_address
  222608. # ifdef CONFIG_FRAME_POINTER
  222609. -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  222610. -# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
  222611. -# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
  222612. -# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
  222613. -# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
  222614. -# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
  222615. -# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
  222616. +# define ftrace_return_address(n) __builtin_return_address(n)
  222617. # else
  222618. -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  222619. -# define CALLER_ADDR1 0UL
  222620. -# define CALLER_ADDR2 0UL
  222621. -# define CALLER_ADDR3 0UL
  222622. -# define CALLER_ADDR4 0UL
  222623. -# define CALLER_ADDR5 0UL
  222624. -# define CALLER_ADDR6 0UL
  222625. +# define ftrace_return_address(n) 0UL
  222626. # endif
  222627. -#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
  222628. +#endif
  222629. +
  222630. +#define CALLER_ADDR0 ((unsigned long)ftrace_return_address0)
  222631. +#define CALLER_ADDR1 ((unsigned long)ftrace_return_address(1))
  222632. +#define CALLER_ADDR2 ((unsigned long)ftrace_return_address(2))
  222633. +#define CALLER_ADDR3 ((unsigned long)ftrace_return_address(3))
  222634. +#define CALLER_ADDR4 ((unsigned long)ftrace_return_address(4))
  222635. +#define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
  222636. +#define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
  222637. #ifdef CONFIG_IRQSOFF_TRACER
  222638. extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
  222639. diff -Nur linux-3.14.17/include/linux/hardirq.h linux-imx6-3.14/include/linux/hardirq.h
  222640. --- linux-3.14.17/include/linux/hardirq.h 2014-08-14 03:38:34.000000000 +0200
  222641. +++ linux-imx6-3.14/include/linux/hardirq.h 2014-09-11 18:06:10.794073083 +0200
  222642. @@ -9,6 +9,7 @@
  222643. extern void synchronize_irq(unsigned int irq);
  222644. +extern void synchronize_hardirq(unsigned int irq);
  222645. #if defined(CONFIG_TINY_RCU)
  222646. diff -Nur linux-3.14.17/include/linux/hsi/hsi.h linux-imx6-3.14/include/linux/hsi/hsi.h
  222647. --- linux-3.14.17/include/linux/hsi/hsi.h 2014-08-14 03:38:34.000000000 +0200
  222648. +++ linux-imx6-3.14/include/linux/hsi/hsi.h 2014-09-11 18:06:10.798073099 +0200
  222649. @@ -178,7 +178,7 @@
  222650. * @complete: Transfer completion callback
  222651. * @destructor: Destructor to free resources when flushing
  222652. * @status: Status of the transfer when completed
  222653. - * @actual_len: Actual length of data transfered on completion
  222654. + * @actual_len: Actual length of data transferred on completion
  222655. * @channel: Channel were to TX/RX the message
  222656. * @ttype: Transfer type (TX if set, RX otherwise)
  222657. * @break_frame: if true HSI will send/receive a break frame. Data buffers are
  222658. diff -Nur linux-3.14.17/include/linux/ipu.h linux-imx6-3.14/include/linux/ipu.h
  222659. --- linux-3.14.17/include/linux/ipu.h 1970-01-01 01:00:00.000000000 +0100
  222660. +++ linux-imx6-3.14/include/linux/ipu.h 2014-09-11 18:06:10.850073307 +0200
  222661. @@ -0,0 +1,38 @@
  222662. +/*
  222663. + * Copyright 2005-2013 Freescale Semiconductor, Inc.
  222664. + */
  222665. +
  222666. +/*
  222667. + * The code contained herein is licensed under the GNU Lesser General
  222668. + * Public License. You may obtain a copy of the GNU Lesser General
  222669. + * Public License Version 2.1 or later at the following locations:
  222670. + *
  222671. + * http://www.opensource.org/licenses/lgpl-license.html
  222672. + * http://www.gnu.org/copyleft/lgpl.html
  222673. + */
  222674. +
  222675. +/*!
  222676. + * @defgroup IPU MXC Image Processing Unit (IPU) Driver
  222677. + */
  222678. +/*!
  222679. + * @file linux/ipu.h
  222680. + *
  222681. + * @brief This file contains the IPU driver API declarations.
  222682. + *
  222683. + * @ingroup IPU
  222684. + */
  222685. +
  222686. +#ifndef __LINUX_IPU_H__
  222687. +#define __LINUX_IPU_H__
  222688. +
  222689. +#include <linux/interrupt.h>
  222690. +#include <uapi/linux/ipu.h>
  222691. +
  222692. +unsigned int fmt_to_bpp(unsigned int pixelformat);
  222693. +cs_t colorspaceofpixel(int fmt);
  222694. +int need_csc(int ifmt, int ofmt);
  222695. +
  222696. +int ipu_queue_task(struct ipu_task *task);
  222697. +int ipu_check_task(struct ipu_task *task);
  222698. +
  222699. +#endif
  222700. diff -Nur linux-3.14.17/include/linux/ipu-v3.h linux-imx6-3.14/include/linux/ipu-v3.h
  222701. --- linux-3.14.17/include/linux/ipu-v3.h 1970-01-01 01:00:00.000000000 +0100
  222702. +++ linux-imx6-3.14/include/linux/ipu-v3.h 2014-09-11 18:06:10.850073307 +0200
  222703. @@ -0,0 +1,752 @@
  222704. +/*
  222705. + * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
  222706. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  222707. + *
  222708. + * This program is free software; you can redistribute it and/or modify it
  222709. + * under the terms of the GNU General Public License as published by the
  222710. + * Free Software Foundation; either version 2 of the License, or (at your
  222711. + * option) any later version.
  222712. + *
  222713. + * This program is distributed in the hope that it will be useful, but
  222714. + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  222715. + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  222716. + * for more details.
  222717. + */
  222718. +
  222719. +#ifndef __LINUX_IPU_V3_H_
  222720. +#define __LINUX_IPU_V3_H_
  222721. +
  222722. +#include <linux/ipu.h>
  222723. +
  222724. +/* IPU Driver channels definitions. */
  222725. +/* Note these are different from IDMA channels */
  222726. +#define IPU_MAX_CH 32
  222727. +#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
  222728. + ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
  222729. +#define _MAKE_ALT_CHAN(ch) (ch | (IPU_MAX_CH << 24))
  222730. +#define IPU_CHAN_ID(ch) (ch >> 24)
  222731. +#define IPU_CHAN_ALT(ch) (ch & 0x02000000)
  222732. +#define IPU_CHAN_ALPHA_IN_DMA(ch) ((uint32_t) (ch >> 6) & 0x3F)
  222733. +#define IPU_CHAN_GRAPH_IN_DMA(ch) ((uint32_t) (ch >> 12) & 0x3F)
  222734. +#define IPU_CHAN_VIDEO_IN_DMA(ch) ((uint32_t) (ch >> 18) & 0x3F)
  222735. +#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch & 0x3F))
  222736. +#define NO_DMA 0x3F
  222737. +#define ALT 1
  222738. +/*!
  222739. + * Enumeration of IPU logical channels. An IPU logical channel is defined as a
  222740. + * combination of an input (memory to IPU), output (IPU to memory), and/or
  222741. + * secondary input IDMA channels and in some cases an Image Converter task.
  222742. + * Some channels consist of only an input or output.
  222743. + */
  222744. +typedef enum {
  222745. + CHAN_NONE = -1,
  222746. + MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48),
  222747. + MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49),
  222748. + MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50),
  222749. +
  222750. + MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20),
  222751. + MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21),
  222752. + MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22),
  222753. +
  222754. + MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
  222755. + MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
  222756. + MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
  222757. + MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
  222758. +
  222759. + MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
  222760. + MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
  222761. + MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
  222762. + MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
  222763. +
  222764. + DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  222765. + DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  222766. +
  222767. + CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0),
  222768. + CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1),
  222769. + CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2),
  222770. + CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3),
  222771. +
  222772. + CSI_MEM = CSI_MEM0,
  222773. +
  222774. + CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20),
  222775. + CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21),
  222776. +
  222777. + /* for vdi mem->vdi->ic->mem , add graphics plane and alpha*/
  222778. + MEM_VDI_PRP_VF_MEM_P = _MAKE_CHAN(21, 8, 14, 17, 21),
  222779. + MEM_VDI_PRP_VF_MEM = _MAKE_CHAN(22, 9, 14, 17, 21),
  222780. + MEM_VDI_PRP_VF_MEM_N = _MAKE_CHAN(23, 10, 14, 17, 21),
  222781. +
  222782. + /* for vdi mem->vdi->mem */
  222783. + MEM_VDI_MEM_P = _MAKE_CHAN(24, 8, NO_DMA, NO_DMA, 5),
  222784. + MEM_VDI_MEM = _MAKE_CHAN(25, 9, NO_DMA, NO_DMA, 5),
  222785. + MEM_VDI_MEM_N = _MAKE_CHAN(26, 10, NO_DMA, NO_DMA, 5),
  222786. +
  222787. + /* fake channel for vdoa to link with IPU */
  222788. + MEM_VDOA_MEM = _MAKE_CHAN(27, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
  222789. +
  222790. + MEM_PP_ADC = CHAN_NONE,
  222791. + ADC_SYS2 = CHAN_NONE,
  222792. +
  222793. +} ipu_channel_t;
  222794. +
  222795. +/*!
  222796. + * Enumeration of types of buffers for a logical channel.
  222797. + */
  222798. +typedef enum {
  222799. + IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */
  222800. + IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */
  222801. + IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */
  222802. + IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */
  222803. + IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
  222804. + IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
  222805. +} ipu_buffer_t;
  222806. +
  222807. +#define IPU_PANEL_SERIAL 1
  222808. +#define IPU_PANEL_PARALLEL 2
  222809. +
  222810. +/*!
  222811. + * Enumeration of ADC channel operation mode.
  222812. + */
  222813. +typedef enum {
  222814. + Disable,
  222815. + WriteTemplateNonSeq,
  222816. + ReadTemplateNonSeq,
  222817. + WriteTemplateUnCon,
  222818. + ReadTemplateUnCon,
  222819. + WriteDataWithRS,
  222820. + WriteDataWoRS,
  222821. + WriteCmd
  222822. +} mcu_mode_t;
  222823. +
  222824. +/*!
  222825. + * Enumeration of ADC channel addressing mode.
  222826. + */
  222827. +typedef enum {
  222828. + FullWoBE,
  222829. + FullWithBE,
  222830. + XY
  222831. +} display_addressing_t;
  222832. +
  222833. +/*!
  222834. + * Union of initialization parameters for a logical channel.
  222835. + */
  222836. +typedef union {
  222837. + struct {
  222838. + uint32_t csi;
  222839. + uint32_t mipi_id;
  222840. + uint32_t mipi_vc;
  222841. + bool mipi_en;
  222842. + bool interlaced;
  222843. + } csi_mem;
  222844. + struct {
  222845. + uint32_t in_width;
  222846. + uint32_t in_height;
  222847. + uint32_t in_pixel_fmt;
  222848. + uint32_t out_width;
  222849. + uint32_t out_height;
  222850. + uint32_t out_pixel_fmt;
  222851. + uint32_t outh_resize_ratio;
  222852. + uint32_t outv_resize_ratio;
  222853. + uint32_t csi;
  222854. + uint32_t mipi_id;
  222855. + uint32_t mipi_vc;
  222856. + bool mipi_en;
  222857. + } csi_prp_enc_mem;
  222858. + struct {
  222859. + uint32_t in_width;
  222860. + uint32_t in_height;
  222861. + uint32_t in_pixel_fmt;
  222862. + uint32_t out_width;
  222863. + uint32_t out_height;
  222864. + uint32_t out_pixel_fmt;
  222865. + uint32_t outh_resize_ratio;
  222866. + uint32_t outv_resize_ratio;
  222867. + } mem_prp_enc_mem;
  222868. + struct {
  222869. + uint32_t in_width;
  222870. + uint32_t in_height;
  222871. + uint32_t in_pixel_fmt;
  222872. + uint32_t out_width;
  222873. + uint32_t out_height;
  222874. + uint32_t out_pixel_fmt;
  222875. + } mem_rot_enc_mem;
  222876. + struct {
  222877. + uint32_t in_width;
  222878. + uint32_t in_height;
  222879. + uint32_t in_pixel_fmt;
  222880. + uint32_t out_width;
  222881. + uint32_t out_height;
  222882. + uint32_t out_pixel_fmt;
  222883. + uint32_t outh_resize_ratio;
  222884. + uint32_t outv_resize_ratio;
  222885. + bool graphics_combine_en;
  222886. + bool global_alpha_en;
  222887. + bool key_color_en;
  222888. + uint32_t in_g_pixel_fmt;
  222889. + uint8_t alpha;
  222890. + uint32_t key_color;
  222891. + bool alpha_chan_en;
  222892. + ipu_motion_sel motion_sel;
  222893. + enum v4l2_field field_fmt;
  222894. + uint32_t csi;
  222895. + uint32_t mipi_id;
  222896. + uint32_t mipi_vc;
  222897. + bool mipi_en;
  222898. + } csi_prp_vf_mem;
  222899. + struct {
  222900. + uint32_t in_width;
  222901. + uint32_t in_height;
  222902. + uint32_t in_pixel_fmt;
  222903. + uint32_t out_width;
  222904. + uint32_t out_height;
  222905. + uint32_t out_pixel_fmt;
  222906. + bool graphics_combine_en;
  222907. + bool global_alpha_en;
  222908. + bool key_color_en;
  222909. + display_port_t disp;
  222910. + uint32_t out_left;
  222911. + uint32_t out_top;
  222912. + } csi_prp_vf_adc;
  222913. + struct {
  222914. + uint32_t in_width;
  222915. + uint32_t in_height;
  222916. + uint32_t in_pixel_fmt;
  222917. + uint32_t out_width;
  222918. + uint32_t out_height;
  222919. + uint32_t out_pixel_fmt;
  222920. + uint32_t outh_resize_ratio;
  222921. + uint32_t outv_resize_ratio;
  222922. + bool graphics_combine_en;
  222923. + bool global_alpha_en;
  222924. + bool key_color_en;
  222925. + uint32_t in_g_pixel_fmt;
  222926. + uint8_t alpha;
  222927. + uint32_t key_color;
  222928. + bool alpha_chan_en;
  222929. + ipu_motion_sel motion_sel;
  222930. + enum v4l2_field field_fmt;
  222931. + } mem_prp_vf_mem;
  222932. + struct {
  222933. + uint32_t temp;
  222934. + } mem_prp_vf_adc;
  222935. + struct {
  222936. + uint32_t temp;
  222937. + } mem_rot_vf_mem;
  222938. + struct {
  222939. + uint32_t in_width;
  222940. + uint32_t in_height;
  222941. + uint32_t in_pixel_fmt;
  222942. + uint32_t out_width;
  222943. + uint32_t out_height;
  222944. + uint32_t out_pixel_fmt;
  222945. + uint32_t outh_resize_ratio;
  222946. + uint32_t outv_resize_ratio;
  222947. + bool graphics_combine_en;
  222948. + bool global_alpha_en;
  222949. + bool key_color_en;
  222950. + uint32_t in_g_pixel_fmt;
  222951. + uint8_t alpha;
  222952. + uint32_t key_color;
  222953. + bool alpha_chan_en;
  222954. + } mem_pp_mem;
  222955. + struct {
  222956. + uint32_t temp;
  222957. + } mem_rot_mem;
  222958. + struct {
  222959. + uint32_t in_width;
  222960. + uint32_t in_height;
  222961. + uint32_t in_pixel_fmt;
  222962. + uint32_t out_width;
  222963. + uint32_t out_height;
  222964. + uint32_t out_pixel_fmt;
  222965. + bool graphics_combine_en;
  222966. + bool global_alpha_en;
  222967. + bool key_color_en;
  222968. + display_port_t disp;
  222969. + uint32_t out_left;
  222970. + uint32_t out_top;
  222971. + } mem_pp_adc;
  222972. + struct {
  222973. + uint32_t di;
  222974. + bool interlaced;
  222975. + uint32_t in_pixel_fmt;
  222976. + uint32_t out_pixel_fmt;
  222977. + } mem_dc_sync;
  222978. + struct {
  222979. + uint32_t temp;
  222980. + } mem_sdc_fg;
  222981. + struct {
  222982. + uint32_t di;
  222983. + bool interlaced;
  222984. + uint32_t in_pixel_fmt;
  222985. + uint32_t out_pixel_fmt;
  222986. + bool alpha_chan_en;
  222987. + } mem_dp_bg_sync;
  222988. + struct {
  222989. + uint32_t temp;
  222990. + } mem_sdc_bg;
  222991. + struct {
  222992. + uint32_t di;
  222993. + bool interlaced;
  222994. + uint32_t in_pixel_fmt;
  222995. + uint32_t out_pixel_fmt;
  222996. + bool alpha_chan_en;
  222997. + } mem_dp_fg_sync;
  222998. + struct {
  222999. + uint32_t di;
  223000. + } direct_async;
  223001. + struct {
  223002. + display_port_t disp;
  223003. + mcu_mode_t ch_mode;
  223004. + uint32_t out_left;
  223005. + uint32_t out_top;
  223006. + } adc_sys1;
  223007. + struct {
  223008. + display_port_t disp;
  223009. + mcu_mode_t ch_mode;
  223010. + uint32_t out_left;
  223011. + uint32_t out_top;
  223012. + } adc_sys2;
  223013. +} ipu_channel_params_t;
  223014. +
  223015. +/*
  223016. + * IPU_IRQF_ONESHOT - Interrupt is not reenabled after the irq handler finished.
  223017. + */
  223018. +#define IPU_IRQF_NONE 0x00000000
  223019. +#define IPU_IRQF_ONESHOT 0x00000001
  223020. +
  223021. +/*!
  223022. + * Enumeration of IPU interrupt sources.
  223023. + */
  223024. +enum ipu_irq_line {
  223025. + IPU_IRQ_CSI0_OUT_EOF = 0,
  223026. + IPU_IRQ_CSI1_OUT_EOF = 1,
  223027. + IPU_IRQ_CSI2_OUT_EOF = 2,
  223028. + IPU_IRQ_CSI3_OUT_EOF = 3,
  223029. + IPU_IRQ_VDIC_OUT_EOF = 5,
  223030. + IPU_IRQ_VDI_P_IN_EOF = 8,
  223031. + IPU_IRQ_VDI_C_IN_EOF = 9,
  223032. + IPU_IRQ_VDI_N_IN_EOF = 10,
  223033. + IPU_IRQ_PP_IN_EOF = 11,
  223034. + IPU_IRQ_PRP_IN_EOF = 12,
  223035. + IPU_IRQ_PRP_GRAPH_IN_EOF = 14,
  223036. + IPU_IRQ_PP_GRAPH_IN_EOF = 15,
  223037. + IPU_IRQ_PRP_ALPHA_IN_EOF = 17,
  223038. + IPU_IRQ_PP_ALPHA_IN_EOF = 18,
  223039. + IPU_IRQ_PRP_ENC_OUT_EOF = 20,
  223040. + IPU_IRQ_PRP_VF_OUT_EOF = 21,
  223041. + IPU_IRQ_PP_OUT_EOF = 22,
  223042. + IPU_IRQ_BG_SYNC_EOF = 23,
  223043. + IPU_IRQ_BG_ASYNC_EOF = 24,
  223044. + IPU_IRQ_FG_SYNC_EOF = 27,
  223045. + IPU_IRQ_DC_SYNC_EOF = 28,
  223046. + IPU_IRQ_FG_ASYNC_EOF = 29,
  223047. + IPU_IRQ_FG_ALPHA_SYNC_EOF = 31,
  223048. +
  223049. + IPU_IRQ_FG_ALPHA_ASYNC_EOF = 33,
  223050. + IPU_IRQ_DC_READ_EOF = 40,
  223051. + IPU_IRQ_DC_ASYNC_EOF = 41,
  223052. + IPU_IRQ_DC_CMD1_EOF = 42,
  223053. + IPU_IRQ_DC_CMD2_EOF = 43,
  223054. + IPU_IRQ_DC_MASK_EOF = 44,
  223055. + IPU_IRQ_PRP_ENC_ROT_IN_EOF = 45,
  223056. + IPU_IRQ_PRP_VF_ROT_IN_EOF = 46,
  223057. + IPU_IRQ_PP_ROT_IN_EOF = 47,
  223058. + IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 48,
  223059. + IPU_IRQ_PRP_VF_ROT_OUT_EOF = 49,
  223060. + IPU_IRQ_PP_ROT_OUT_EOF = 50,
  223061. + IPU_IRQ_BG_ALPHA_SYNC_EOF = 51,
  223062. + IPU_IRQ_BG_ALPHA_ASYNC_EOF = 52,
  223063. +
  223064. + IPU_IRQ_BG_SYNC_NFACK = 64 + 23,
  223065. + IPU_IRQ_FG_SYNC_NFACK = 64 + 27,
  223066. + IPU_IRQ_DC_SYNC_NFACK = 64 + 28,
  223067. +
  223068. + IPU_IRQ_DP_SF_START = 448 + 2,
  223069. + IPU_IRQ_DP_SF_END = 448 + 3,
  223070. + IPU_IRQ_BG_SF_END = IPU_IRQ_DP_SF_END,
  223071. + IPU_IRQ_DC_FC_0 = 448 + 8,
  223072. + IPU_IRQ_DC_FC_1 = 448 + 9,
  223073. + IPU_IRQ_DC_FC_2 = 448 + 10,
  223074. + IPU_IRQ_DC_FC_3 = 448 + 11,
  223075. + IPU_IRQ_DC_FC_4 = 448 + 12,
  223076. + IPU_IRQ_DC_FC_6 = 448 + 13,
  223077. + IPU_IRQ_VSYNC_PRE_0 = 448 + 14,
  223078. + IPU_IRQ_VSYNC_PRE_1 = 448 + 15,
  223079. +
  223080. + IPU_IRQ_COUNT
  223081. +};
  223082. +
  223083. +/*!
  223084. + * Bitfield of Display Interface signal polarities.
  223085. + */
  223086. +typedef struct {
  223087. + unsigned datamask_en:1;
  223088. + unsigned int_clk:1;
  223089. + unsigned interlaced:1;
  223090. + unsigned odd_field_first:1;
  223091. + unsigned clksel_en:1;
  223092. + unsigned clkidle_en:1;
  223093. + unsigned data_pol:1; /* true = inverted */
  223094. + unsigned clk_pol:1; /* true = rising edge */
  223095. + unsigned enable_pol:1;
  223096. + unsigned Hsync_pol:1; /* true = active high */
  223097. + unsigned Vsync_pol:1;
  223098. +} ipu_di_signal_cfg_t;
  223099. +
  223100. +/*!
  223101. + * Bitfield of CSI signal polarities and modes.
  223102. + */
  223103. +
  223104. +typedef struct {
  223105. + unsigned data_width:4;
  223106. + unsigned clk_mode:3;
  223107. + unsigned ext_vsync:1;
  223108. + unsigned Vsync_pol:1;
  223109. + unsigned Hsync_pol:1;
  223110. + unsigned pixclk_pol:1;
  223111. + unsigned data_pol:1;
  223112. + unsigned sens_clksrc:1;
  223113. + unsigned pack_tight:1;
  223114. + unsigned force_eof:1;
  223115. + unsigned data_en_pol:1;
  223116. + unsigned data_fmt;
  223117. + unsigned csi;
  223118. + unsigned mclk;
  223119. +} ipu_csi_signal_cfg_t;
  223120. +
  223121. +/*!
  223122. + * Enumeration of CSI data bus widths.
  223123. + */
  223124. +enum {
  223125. + IPU_CSI_DATA_WIDTH_4 = 0,
  223126. + IPU_CSI_DATA_WIDTH_8 = 1,
  223127. + IPU_CSI_DATA_WIDTH_10 = 3,
  223128. + IPU_CSI_DATA_WIDTH_16 = 9,
  223129. +};
  223130. +
  223131. +/*!
  223132. + * Enumeration of CSI clock modes.
  223133. + */
  223134. +enum {
  223135. + IPU_CSI_CLK_MODE_GATED_CLK,
  223136. + IPU_CSI_CLK_MODE_NONGATED_CLK,
  223137. + IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE,
  223138. + IPU_CSI_CLK_MODE_CCIR656_INTERLACED,
  223139. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR,
  223140. + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR,
  223141. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR,
  223142. + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR,
  223143. +};
  223144. +
  223145. +enum {
  223146. + IPU_CSI_MIPI_DI0,
  223147. + IPU_CSI_MIPI_DI1,
  223148. + IPU_CSI_MIPI_DI2,
  223149. + IPU_CSI_MIPI_DI3,
  223150. +};
  223151. +
  223152. +typedef enum {
  223153. + RGB,
  223154. + YCbCr,
  223155. + YUV
  223156. +} ipu_color_space_t;
  223157. +
  223158. +/*!
  223159. + * Enumeration of ADC vertical sync mode.
  223160. + */
  223161. +typedef enum {
  223162. + VsyncNone,
  223163. + VsyncInternal,
  223164. + VsyncCSI,
  223165. + VsyncExternal
  223166. +} vsync_t;
  223167. +
  223168. +typedef enum {
  223169. + DAT,
  223170. + CMD
  223171. +} cmddata_t;
  223172. +
  223173. +/*!
  223174. + * Enumeration of ADC display update mode.
  223175. + */
  223176. +typedef enum {
  223177. + IPU_ADC_REFRESH_NONE,
  223178. + IPU_ADC_AUTO_REFRESH,
  223179. + IPU_ADC_AUTO_REFRESH_SNOOP,
  223180. + IPU_ADC_SNOOPING,
  223181. +} ipu_adc_update_mode_t;
  223182. +
  223183. +/*!
  223184. + * Enumeration of ADC display interface types (serial or parallel).
  223185. + */
  223186. +enum {
  223187. + IPU_ADC_IFC_MODE_SYS80_TYPE1,
  223188. + IPU_ADC_IFC_MODE_SYS80_TYPE2,
  223189. + IPU_ADC_IFC_MODE_SYS68K_TYPE1,
  223190. + IPU_ADC_IFC_MODE_SYS68K_TYPE2,
  223191. + IPU_ADC_IFC_MODE_3WIRE_SERIAL,
  223192. + IPU_ADC_IFC_MODE_4WIRE_SERIAL,
  223193. + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK,
  223194. + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CS,
  223195. +};
  223196. +
  223197. +enum {
  223198. + IPU_ADC_IFC_WIDTH_8,
  223199. + IPU_ADC_IFC_WIDTH_16,
  223200. +};
  223201. +
  223202. +/*!
  223203. + * Enumeration of ADC display interface burst mode.
  223204. + */
  223205. +enum {
  223206. + IPU_ADC_BURST_WCS,
  223207. + IPU_ADC_BURST_WBLCK,
  223208. + IPU_ADC_BURST_NONE,
  223209. + IPU_ADC_BURST_SERIAL,
  223210. +};
  223211. +
  223212. +/*!
  223213. + * Enumeration of ADC display interface RW signal timing modes.
  223214. + */
  223215. +enum {
  223216. + IPU_ADC_SER_NO_RW,
  223217. + IPU_ADC_SER_RW_BEFORE_RS,
  223218. + IPU_ADC_SER_RW_AFTER_RS,
  223219. +};
  223220. +
  223221. +/*!
  223222. + * Bitfield of ADC signal polarities and modes.
  223223. + */
  223224. +typedef struct {
  223225. + unsigned data_pol:1;
  223226. + unsigned clk_pol:1;
  223227. + unsigned cs_pol:1;
  223228. + unsigned rs_pol:1;
  223229. + unsigned addr_pol:1;
  223230. + unsigned read_pol:1;
  223231. + unsigned write_pol:1;
  223232. + unsigned Vsync_pol:1;
  223233. + unsigned burst_pol:1;
  223234. + unsigned burst_mode:2;
  223235. + unsigned ifc_mode:3;
  223236. + unsigned ifc_width:5;
  223237. + unsigned ser_preamble_len:4;
  223238. + unsigned ser_preamble:8;
  223239. + unsigned ser_rw_mode:2;
  223240. +} ipu_adc_sig_cfg_t;
  223241. +
  223242. +/*!
  223243. + * Enumeration of ADC template commands.
  223244. + */
  223245. +enum {
  223246. + RD_DATA,
  223247. + RD_ACK,
  223248. + RD_WAIT,
  223249. + WR_XADDR,
  223250. + WR_YADDR,
  223251. + WR_ADDR,
  223252. + WR_CMND,
  223253. + WR_DATA,
  223254. +};
  223255. +
  223256. +/*!
  223257. + * Enumeration of ADC template command flow control.
  223258. + */
  223259. +enum {
  223260. + SINGLE_STEP,
  223261. + PAUSE,
  223262. + STOP,
  223263. +};
  223264. +
  223265. +
  223266. +/*Define template constants*/
  223267. +#define ATM_ADDR_RANGE 0x20 /*offset address of DISP */
  223268. +#define TEMPLATE_BUF_SIZE 0x20 /*size of template */
  223269. +
  223270. +/*!
  223271. + * Define to create ADC template command entry.
  223272. + */
  223273. +#define ipu_adc_template_gen(oc, rs, fc, dat) (((rs) << 29) | ((fc) << 27) | \
  223274. + ((oc) << 24) | (dat))
  223275. +
  223276. +typedef struct {
  223277. + u32 reg;
  223278. + u32 value;
  223279. +} ipu_lpmc_reg_t;
  223280. +
  223281. +#define IPU_LPMC_REG_READ 0x80000000L
  223282. +
  223283. +#define CSI_MCLK_VF 1
  223284. +#define CSI_MCLK_ENC 2
  223285. +#define CSI_MCLK_RAW 4
  223286. +#define CSI_MCLK_I2C 8
  223287. +
  223288. +struct ipu_soc;
  223289. +/* Common IPU API */
  223290. +struct ipu_soc *ipu_get_soc(int id);
  223291. +int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
  223292. +void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel);
  223293. +void ipu_disable_hsp_clk(struct ipu_soc *ipu);
  223294. +
  223295. +static inline bool ipu_can_rotate_in_place(ipu_rotate_mode_t rot)
  223296. +{
  223297. +#ifdef CONFIG_MXC_IPU_V3D
  223298. + return (rot < IPU_ROTATE_HORIZ_FLIP);
  223299. +#else
  223300. + return (rot < IPU_ROTATE_90_RIGHT);
  223301. +#endif
  223302. +}
  223303. +
  223304. +int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  223305. + uint32_t pixel_fmt,
  223306. + uint16_t width, uint16_t height,
  223307. + uint32_t stride,
  223308. + ipu_rotate_mode_t rot_mode,
  223309. + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
  223310. + dma_addr_t phyaddr_2,
  223311. + uint32_t u_offset, uint32_t v_offset);
  223312. +
  223313. +int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  223314. + uint32_t bufNum, dma_addr_t phyaddr);
  223315. +
  223316. +int32_t ipu_update_channel_offset(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  223317. + uint32_t pixel_fmt,
  223318. + uint16_t width, uint16_t height,
  223319. + uint32_t stride,
  223320. + uint32_t u, uint32_t v,
  223321. + uint32_t vertical_offset, uint32_t horizontal_offset);
  223322. +
  223323. +int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
  223324. + ipu_buffer_t type, uint32_t bufNum);
  223325. +int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum);
  223326. +
  223327. +int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
  223328. +int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
  223329. +
  223330. +int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel);
  223331. +int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  223332. + uint32_t bufNum);
  223333. +void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
  223334. + uint32_t bufNum);
  223335. +uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type);
  223336. +int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel);
  223337. +int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop);
  223338. +int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch);
  223339. +uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
  223340. +
  223341. +int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi);
  223342. +int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi);
  223343. +
  223344. +int ipu_lowpwr_display_enable(void);
  223345. +int ipu_lowpwr_display_disable(void);
  223346. +
  223347. +int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq);
  223348. +void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq);
  223349. +void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq);
  223350. +int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
  223351. + irqreturn_t(*handler) (int, void *),
  223352. + uint32_t irq_flags, const char *devname, void *dev_id);
  223353. +void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id);
  223354. +bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq);
  223355. +void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
  223356. +int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
  223357. + ipu_buffer_t type, uint32_t band_height);
  223358. +
  223359. +/* two stripe calculations */
  223360. +struct stripe_param{
  223361. + unsigned int input_width; /* width of the input stripe */
  223362. + unsigned int output_width; /* width of the output stripe */
  223363. + unsigned int input_column; /* the first column on the input stripe */
  223364. + unsigned int output_column; /* the first column on the output stripe */
  223365. + unsigned int idr;
  223366. + /* inverse downisizing ratio parameter; expressed as a power of 2 */
  223367. + unsigned int irr;
  223368. + /* inverse resizing ratio parameter; expressed as a multiple of 2^-13 */
  223369. +};
  223370. +int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
  223371. + unsigned int output_frame_width,
  223372. + const unsigned int maximal_stripe_width,
  223373. + const unsigned long long cirr,
  223374. + const unsigned int equal_stripes,
  223375. + u32 input_pixelformat,
  223376. + u32 output_pixelformat,
  223377. + struct stripe_param *left,
  223378. + struct stripe_param *right);
  223379. +
  223380. +/* SDC API */
  223381. +int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp,
  223382. + uint32_t pixel_clk,
  223383. + uint16_t width, uint16_t height,
  223384. + uint32_t pixel_fmt,
  223385. + uint16_t h_start_width, uint16_t h_sync_width,
  223386. + uint16_t h_end_width, uint16_t v_start_width,
  223387. + uint16_t v_sync_width, uint16_t v_end_width,
  223388. + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig);
  223389. +
  223390. +void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp);
  223391. +
  223392. +int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t x_pos,
  223393. + int16_t y_pos);
  223394. +int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t *x_pos,
  223395. + int16_t *y_pos);
  223396. +int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  223397. + uint8_t alpha);
  223398. +int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  223399. + uint32_t colorKey);
  223400. +int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
  223401. + int constk[], int slopek[]);
  223402. +
  223403. +int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
  223404. + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig);
  223405. +void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset);
  223406. +void ipu_reset_disp_panel(struct ipu_soc *ipu);
  223407. +
  223408. +/* CMOS Sensor Interface API */
  223409. +int32_t ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
  223410. + uint32_t pixel_fmt, ipu_csi_signal_cfg_t sig);
  223411. +
  223412. +int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi);
  223413. +
  223414. +int32_t ipu_csi_enable_mclk(struct ipu_soc *ipu, int src, bool flag, bool wait);
  223415. +
  223416. +static inline int32_t ipu_csi_enable_mclk_if(struct ipu_soc *ipu, int src, uint32_t csi,
  223417. + bool flag, bool wait)
  223418. +{
  223419. + return ipu_csi_enable_mclk(ipu, csi, flag, wait);
  223420. +}
  223421. +
  223422. +int ipu_csi_read_mclk_flag(void);
  223423. +
  223424. +void ipu_csi_flash_strobe(bool flag);
  223425. +
  223426. +void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi);
  223427. +
  223428. +void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi);
  223429. +
  223430. +void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi);
  223431. +
  223432. +uint32_t bytes_per_pixel(uint32_t fmt);
  223433. +
  223434. +bool ipu_ch_param_bad_alpha_pos(uint32_t fmt);
  223435. +
  223436. +struct ipuv3_fb_platform_data {
  223437. + char disp_dev[32];
  223438. + u32 interface_pix_fmt;
  223439. + char *mode_str;
  223440. + int default_bpp;
  223441. + bool int_clk;
  223442. +
  223443. + /* reserved mem */
  223444. + resource_size_t res_base[2];
  223445. + resource_size_t res_size[2];
  223446. +
  223447. + /*
  223448. + * Late init to avoid display channel being
  223449. + * re-initialized as we've probably setup the
  223450. + * channel in bootloader.
  223451. + */
  223452. + bool late_init;
  223453. +};
  223454. +
  223455. +#endif /* __LINUX_IPU_V3_H_ */
  223456. diff -Nur linux-3.14.17/include/linux/isl29023.h linux-imx6-3.14/include/linux/isl29023.h
  223457. --- linux-3.14.17/include/linux/isl29023.h 1970-01-01 01:00:00.000000000 +0100
  223458. +++ linux-imx6-3.14/include/linux/isl29023.h 2014-09-11 18:06:10.854073322 +0200
  223459. @@ -0,0 +1,47 @@
  223460. +/*
  223461. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223462. + */
  223463. +
  223464. +/*
  223465. + * This program is free software; you can redistribute it and/or modify
  223466. + * it under the terms of the GNU General Public License as published by
  223467. + * the Free Software Foundation; either version 2 of the License, or
  223468. + * (at your option) any later version.
  223469. +
  223470. + * This program is distributed in the hope that it will be useful,
  223471. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223472. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223473. + * GNU General Public License for more details.
  223474. +
  223475. + * You should have received a copy of the GNU General Public License along
  223476. + * with this program; if not, write to the Free Software Foundation, Inc.,
  223477. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  223478. + */
  223479. +
  223480. +#ifndef __ISL29023_H__
  223481. +#define __ISL29023_H__
  223482. +
  223483. +#include <linux/types.h>
  223484. +
  223485. +#define ISL29023_PD_MODE 0x0
  223486. +#define ISL29023_ALS_ONCE_MODE 0x1
  223487. +#define ISL29023_IR_ONCE_MODE 0x2
  223488. +#define ISL29023_ALS_CONT_MODE 0x5
  223489. +#define ISL29023_IR_CONT_MODE 0x6
  223490. +
  223491. +#define ISL29023_INT_PERSISTS_1 0x0
  223492. +#define ISL29023_INT_PERSISTS_4 0x1
  223493. +#define ISL29023_INT_PERSISTS_8 0x2
  223494. +#define ISL29023_INT_PERSISTS_16 0x3
  223495. +
  223496. +#define ISL29023_RES_16 0x0
  223497. +#define ISL29023_RES_12 0x1
  223498. +#define ISL29023_RES_8 0x2
  223499. +#define ISL29023_RES_4 0x3
  223500. +
  223501. +#define ISL29023_RANGE_1K 0x0
  223502. +#define ISL29023_RANGE_4K 0x1
  223503. +#define ISL29023_RANGE_16K 0x2
  223504. +#define ISL29023_RANGE_64K 0x3
  223505. +
  223506. +#endif
  223507. diff -Nur linux-3.14.17/include/linux/kfifo.h linux-imx6-3.14/include/linux/kfifo.h
  223508. --- linux-3.14.17/include/linux/kfifo.h 2014-08-14 03:38:34.000000000 +0200
  223509. +++ linux-imx6-3.14/include/linux/kfifo.h 2014-09-11 18:06:10.858073338 +0200
  223510. @@ -722,7 +722,7 @@
  223511. /**
  223512. * kfifo_dma_out_finish - finish a DMA OUT operation
  223513. * @fifo: address of the fifo to be used
  223514. - * @len: number of bytes transferd
  223515. + * @len: number of bytes transferrd
  223516. *
  223517. * This macro finish a DMA OUT operation. The out counter will be updated by
  223518. * the len parameter. No error checking will be done.
  223519. diff -Nur linux-3.14.17/include/linux/libata.h linux-imx6-3.14/include/linux/libata.h
  223520. --- linux-3.14.17/include/linux/libata.h 2014-08-14 03:38:34.000000000 +0200
  223521. +++ linux-imx6-3.14/include/linux/libata.h 2014-09-11 18:06:10.862073355 +0200
  223522. @@ -593,7 +593,6 @@
  223523. struct device *dev;
  223524. void __iomem * const *iomap;
  223525. unsigned int n_ports;
  223526. - unsigned int n_tags; /* nr of NCQ tags */
  223527. void *private_data;
  223528. struct ata_port_operations *ops;
  223529. unsigned long flags;
  223530. diff -Nur linux-3.14.17/include/linux/mailbox_client.h linux-imx6-3.14/include/linux/mailbox_client.h
  223531. --- linux-3.14.17/include/linux/mailbox_client.h 1970-01-01 01:00:00.000000000 +0100
  223532. +++ linux-imx6-3.14/include/linux/mailbox_client.h 2014-09-11 18:06:10.866073370 +0200
  223533. @@ -0,0 +1,46 @@
  223534. +/*
  223535. + * Copyright (C) 2014 Linaro Ltd.
  223536. + * Author: Jassi Brar <jassisinghbrar@gmail.com>
  223537. + *
  223538. + * This program is free software; you can redistribute it and/or modify
  223539. + * it under the terms of the GNU General Public License version 2 as
  223540. + * published by the Free Software Foundation.
  223541. + */
  223542. +
  223543. +#ifndef __MAILBOX_CLIENT_H
  223544. +#define __MAILBOX_CLIENT_H
  223545. +
  223546. +#include <linux/of.h>
  223547. +
  223548. +struct mbox_chan;
  223549. +
  223550. +/**
  223551. + * struct mbox_client - User of a mailbox
  223552. + * @dev: The client device
  223553. + * @chan_name: The "controller:channel" this client wants
  223554. + * @rx_callback: Atomic callback to provide client the data received
  223555. + * @tx_done: Atomic callback to tell client of data transmission
  223556. + * @tx_block: If the mbox_send_message should block until data is
  223557. + * transmitted.
  223558. + * @tx_tout: Max block period in ms before TX is assumed failure
  223559. + * @knows_txdone: if the client could run the TX state machine. Usually
  223560. + * if the client receives some ACK packet for transmission.
  223561. + * Unused if the controller already has TX_Done/RTR IRQ.
  223562. + */
  223563. +struct mbox_client {
  223564. + struct device *dev;
  223565. + const char *chan_name;
  223566. + void (*rx_callback)(struct mbox_client *cl, void *mssg);
  223567. + void (*tx_done)(struct mbox_client *cl, void *mssg, int r);
  223568. + bool tx_block;
  223569. + unsigned long tx_tout;
  223570. + bool knows_txdone;
  223571. +};
  223572. +
  223573. +struct mbox_chan *mbox_request_channel(struct mbox_client *cl);
  223574. +int mbox_send_message(struct mbox_chan *chan, void *mssg);
  223575. +void mbox_client_txdone(struct mbox_chan *chan, int r);
  223576. +bool mbox_client_peek_data(struct mbox_chan *chan);
  223577. +void mbox_free_channel(struct mbox_chan *chan);
  223578. +
  223579. +#endif /* __MAILBOX_CLIENT_H */
  223580. diff -Nur linux-3.14.17/include/linux/mailbox_controller.h linux-imx6-3.14/include/linux/mailbox_controller.h
  223581. --- linux-3.14.17/include/linux/mailbox_controller.h 1970-01-01 01:00:00.000000000 +0100
  223582. +++ linux-imx6-3.14/include/linux/mailbox_controller.h 2014-09-11 18:06:10.866073370 +0200
  223583. @@ -0,0 +1,121 @@
  223584. +/*
  223585. + * This program is free software; you can redistribute it and/or modify
  223586. + * it under the terms of the GNU General Public License version 2 as
  223587. + * published by the Free Software Foundation.
  223588. + */
  223589. +
  223590. +#ifndef __MAILBOX_CONTROLLER_H
  223591. +#define __MAILBOX_CONTROLLER_H
  223592. +
  223593. +#include <linux/of.h>
  223594. +
  223595. +struct mbox_chan;
  223596. +
  223597. +/**
  223598. + * struct mbox_chan_ops - s/w representation of a communication chan
  223599. + * @send_data: The API asks the MBOX controller driver, in atomic
  223600. + * context try to transmit a message on the bus. Returns 0 if
  223601. + * data is accepted for transmission, -EBUSY while rejecting
  223602. + * if the remote hasn't yet read the last data sent. Actual
  223603. + * transmission of data is reported by the controller via
  223604. + * mbox_chan_txdone (if it has some TX ACK irq). It must not
  223605. + * block.
  223606. + * @startup: Called when a client requests the chan. The controller
  223607. + * could ask clients for additional parameters of communication
  223608. + * to be provided via client's chan_data. This call may
  223609. + * block. After this call the Controller must forward any
  223610. + * data received on the chan by calling mbox_chan_received_data.
  223611. + * @shutdown: Called when a client relinquishes control of a chan.
  223612. + * This call may block too. The controller must not forwared
  223613. + * any received data anymore.
  223614. + * @last_tx_done: If the controller sets 'txdone_poll', the API calls
  223615. + * this to poll status of last TX. The controller must
  223616. + * give priority to IRQ method over polling and never
  223617. + * set both txdone_poll and txdone_irq. Only in polling
  223618. + * mode 'send_data' is expected to return -EBUSY.
  223619. + * Used only if txdone_poll:=true && txdone_irq:=false
  223620. + * @peek_data: Atomic check for any received data. Return true if controller
  223621. + * has some data to push to the client. False otherwise.
  223622. + */
  223623. +struct mbox_chan_ops {
  223624. + int (*send_data)(struct mbox_chan *chan, void *data);
  223625. + int (*startup)(struct mbox_chan *chan);
  223626. + void (*shutdown)(struct mbox_chan *chan);
  223627. + bool (*last_tx_done)(struct mbox_chan *chan);
  223628. + bool (*peek_data)(struct mbox_chan *chan);
  223629. +};
  223630. +
  223631. +/**
  223632. + * struct mbox_controller - Controller of a class of communication chans
  223633. + * @dev: Device backing this controller
  223634. + * @controller_name: Literal name of the controller.
  223635. + * @ops: Operators that work on each communication chan
  223636. + * @chans: Null terminated array of chans.
  223637. + * @txdone_irq: Indicates if the controller can report to API when
  223638. + * the last transmitted data was read by the remote.
  223639. + * Eg, if it has some TX ACK irq.
  223640. + * @txdone_poll: If the controller can read but not report the TX
  223641. + * done. Ex, some register shows the TX status but
  223642. + * no interrupt rises. Ignored if 'txdone_irq' is set.
  223643. + * @txpoll_period: If 'txdone_poll' is in effect, the API polls for
  223644. + * last TX's status after these many millisecs
  223645. + */
  223646. +struct mbox_controller {
  223647. + struct device *dev;
  223648. + struct mbox_chan_ops *ops;
  223649. + struct mbox_chan *chans;
  223650. + int num_chans;
  223651. + bool txdone_irq;
  223652. + bool txdone_poll;
  223653. + unsigned txpoll_period;
  223654. + struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
  223655. + const struct of_phandle_args *sp);
  223656. + /*
  223657. + * If the controller supports only TXDONE_BY_POLL,
  223658. + * this timer polls all the links for txdone.
  223659. + */
  223660. + struct timer_list poll;
  223661. + unsigned period;
  223662. + /* Hook to add to the global controller list */
  223663. + struct list_head node;
  223664. +};
  223665. +
  223666. +/*
  223667. + * The length of circular buffer for queuing messages from a client.
  223668. + * 'msg_count' tracks the number of buffered messages while 'msg_free'
  223669. + * is the index where the next message would be buffered.
  223670. + * We shouldn't need it too big because every transferr is interrupt
  223671. + * triggered and if we have lots of data to transfer, the interrupt
  223672. + * latencies are going to be the bottleneck, not the buffer length.
  223673. + * Besides, mbox_send_message could be called from atomic context and
  223674. + * the client could also queue another message from the notifier 'tx_done'
  223675. + * of the last transfer done.
  223676. + * REVIST: If too many platforms see the "Try increasing MBOX_TX_QUEUE_LEN"
  223677. + * print, it needs to be taken from config option or somesuch.
  223678. + */
  223679. +#define MBOX_TX_QUEUE_LEN 20
  223680. +
  223681. +struct mbox_chan {
  223682. + struct mbox_controller *mbox; /* Parent Controller */
  223683. + unsigned txdone_method;
  223684. +
  223685. + /* client */
  223686. + struct mbox_client *cl;
  223687. + struct completion tx_complete;
  223688. +
  223689. + void *active_req;
  223690. + unsigned msg_count, msg_free;
  223691. + void *msg_data[MBOX_TX_QUEUE_LEN];
  223692. + /* Access to the channel */
  223693. + spinlock_t lock;
  223694. +
  223695. + /* Private data for controller */
  223696. + void *con_priv;
  223697. +};
  223698. +
  223699. +int mbox_controller_register(struct mbox_controller *mbox);
  223700. +void mbox_chan_received_data(struct mbox_chan *chan, void *data);
  223701. +void mbox_chan_txdone(struct mbox_chan *chan, int r);
  223702. +void mbox_controller_unregister(struct mbox_controller *mbox);
  223703. +
  223704. +#endif /* __MAILBOX_CONTROLLER_H */
  223705. diff -Nur linux-3.14.17/include/linux/mailbox.h linux-imx6-3.14/include/linux/mailbox.h
  223706. --- linux-3.14.17/include/linux/mailbox.h 2014-08-14 03:38:34.000000000 +0200
  223707. +++ linux-imx6-3.14/include/linux/mailbox.h 1970-01-01 01:00:00.000000000 +0100
  223708. @@ -1,17 +0,0 @@
  223709. -/*
  223710. - * This program is free software; you can redistribute it and/or modify it
  223711. - * under the terms and conditions of the GNU General Public License,
  223712. - * version 2, as published by the Free Software Foundation.
  223713. - *
  223714. - * This program is distributed in the hope it will be useful, but WITHOUT
  223715. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  223716. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  223717. - * more details.
  223718. - *
  223719. - * You should have received a copy of the GNU General Public License along with
  223720. - * this program. If not, see <http://www.gnu.org/licenses/>.
  223721. - */
  223722. -
  223723. -int pl320_ipc_transmit(u32 *data);
  223724. -int pl320_ipc_register_notifier(struct notifier_block *nb);
  223725. -int pl320_ipc_unregister_notifier(struct notifier_block *nb);
  223726. diff -Nur linux-3.14.17/include/linux/memblock.h linux-imx6-3.14/include/linux/memblock.h
  223727. --- linux-3.14.17/include/linux/memblock.h 2014-08-14 03:38:34.000000000 +0200
  223728. +++ linux-imx6-3.14/include/linux/memblock.h 2014-09-11 18:06:10.866073370 +0200
  223729. @@ -221,6 +221,8 @@
  223730. #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0)
  223731. #define MEMBLOCK_ALLOC_ACCESSIBLE 0
  223732. +phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
  223733. + phys_addr_t start, phys_addr_t end);
  223734. phys_addr_t memblock_alloc_base(phys_addr_t size, phys_addr_t align,
  223735. phys_addr_t max_addr);
  223736. phys_addr_t __memblock_alloc_base(phys_addr_t size, phys_addr_t align,
  223737. diff -Nur linux-3.14.17/include/linux/mfd/abx500/ab8500.h linux-imx6-3.14/include/linux/mfd/abx500/ab8500.h
  223738. --- linux-3.14.17/include/linux/mfd/abx500/ab8500.h 2014-08-14 03:38:34.000000000 +0200
  223739. +++ linux-imx6-3.14/include/linux/mfd/abx500/ab8500.h 2014-09-11 18:06:10.870073386 +0200
  223740. @@ -347,7 +347,6 @@
  223741. struct mutex lock;
  223742. struct mutex irq_lock;
  223743. atomic_t transfer_ongoing;
  223744. - int irq_base;
  223745. int irq;
  223746. struct irq_domain *domain;
  223747. enum ab8500_version version;
  223748. @@ -378,7 +377,6 @@
  223749. * @regulator: machine-specific constraints for regulators
  223750. */
  223751. struct ab8500_platform_data {
  223752. - int irq_base;
  223753. void (*init) (struct ab8500 *);
  223754. struct ab8500_regulator_platform_data *regulator;
  223755. struct ab8500_codec_platform_data *codec;
  223756. diff -Nur linux-3.14.17/include/linux/mfd/dbx500-prcmu.h linux-imx6-3.14/include/linux/mfd/dbx500-prcmu.h
  223757. --- linux-3.14.17/include/linux/mfd/dbx500-prcmu.h 2014-08-14 03:38:34.000000000 +0200
  223758. +++ linux-imx6-3.14/include/linux/mfd/dbx500-prcmu.h 2014-09-11 18:06:10.874073403 +0200
  223759. @@ -183,8 +183,6 @@
  223760. bool enable_set_ddr_opp;
  223761. bool enable_ape_opp_100_voltage;
  223762. struct ab8500_platform_data *ab_platdata;
  223763. - int ab_irq;
  223764. - int irq_base;
  223765. u32 version_offset;
  223766. u32 legacy_offset;
  223767. u32 adt_offset;
  223768. diff -Nur linux-3.14.17/include/linux/mfd/mxc-hdmi-core.h linux-imx6-3.14/include/linux/mfd/mxc-hdmi-core.h
  223769. --- linux-3.14.17/include/linux/mfd/mxc-hdmi-core.h 1970-01-01 01:00:00.000000000 +0100
  223770. +++ linux-imx6-3.14/include/linux/mfd/mxc-hdmi-core.h 2014-09-11 18:06:10.878073418 +0200
  223771. @@ -0,0 +1,68 @@
  223772. +/*
  223773. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223774. + *
  223775. + * This program is free software; you can redistribute it and/or modify
  223776. + * it under the terms of the GNU General Public License as published by
  223777. + * the Free Software Foundation; either version 2 of the License, or
  223778. + * (at your option) any later version.
  223779. + *
  223780. + * This program is distributed in the hope that it will be useful,
  223781. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223782. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223783. + * GNU General Public License for more details.
  223784. + *
  223785. + * You should have received a copy of the GNU General Public License
  223786. + * along with this program; if not, write to the Free Software
  223787. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  223788. + *
  223789. + */
  223790. +#ifndef __LINUX_MXC_HDMI_CORE_H_
  223791. +#define __LINUX_MXC_HDMI_CORE_H_
  223792. +
  223793. +#include <video/mxc_edid.h>
  223794. +
  223795. +#include <sound/core.h>
  223796. +#include <sound/pcm.h>
  223797. +#include <sound/pcm_params.h>
  223798. +#include <sound/soc.h>
  223799. +
  223800. +#define IRQ_DISABLE_SUCCEED 0
  223801. +#define IRQ_DISABLE_FAIL 1
  223802. +
  223803. +bool hdmi_check_overflow(void);
  223804. +
  223805. +u8 hdmi_readb(unsigned int reg);
  223806. +void hdmi_writeb(u8 value, unsigned int reg);
  223807. +void hdmi_mask_writeb(u8 data, unsigned int addr, u8 shift, u8 mask);
  223808. +unsigned int hdmi_read4(unsigned int reg);
  223809. +void hdmi_write4(unsigned int value, unsigned int reg);
  223810. +
  223811. +void hdmi_irq_init(void);
  223812. +void hdmi_irq_enable(int irq);
  223813. +unsigned int hdmi_irq_disable(int irq);
  223814. +
  223815. +void hdmi_set_sample_rate(unsigned int rate);
  223816. +void hdmi_set_dma_mode(unsigned int dma_running);
  223817. +void hdmi_init_clk_regenerator(void);
  223818. +void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock);
  223819. +
  223820. +void hdmi_set_edid_cfg(int edid_status, struct mxc_edid_cfg *cfg);
  223821. +int hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);
  223822. +
  223823. +extern int mxc_hdmi_ipu_id;
  223824. +extern int mxc_hdmi_disp_id;
  223825. +
  223826. +void hdmi_set_registered(int registered);
  223827. +int hdmi_get_registered(void);
  223828. +int mxc_hdmi_abort_stream(void);
  223829. +int mxc_hdmi_register_audio(struct snd_pcm_substream *substream);
  223830. +void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream);
  223831. +void hdmi_set_dvi_mode(unsigned int state);
  223832. +unsigned int hdmi_set_cable_state(unsigned int state);
  223833. +unsigned int hdmi_set_blank_state(unsigned int state);
  223834. +int check_hdmi_state(void);
  223835. +
  223836. +void hdmi_cec_start_device(void);
  223837. +void hdmi_cec_stop_device(void);
  223838. +
  223839. +#endif
  223840. diff -Nur linux-3.14.17/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h linux-imx6-3.14/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
  223841. --- linux-3.14.17/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h 2014-08-14 03:38:34.000000000 +0200
  223842. +++ linux-imx6-3.14/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h 2014-09-11 18:06:10.882073433 +0200
  223843. @@ -1,5 +1,5 @@
  223844. /*
  223845. - * Copyright (C) 2012 Freescale Semiconductor, Inc.
  223846. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc.
  223847. *
  223848. * This program is free software; you can redistribute it and/or modify
  223849. * it under the terms of the GNU General Public License version 2 as
  223850. @@ -122,7 +122,9 @@
  223851. #define IMX6Q_GPR1_USB_OTG_ID_SEL_MASK BIT(13)
  223852. #define IMX6Q_GPR1_USB_OTG_ID_SEL_ENET_RX_ER 0x0
  223853. #define IMX6Q_GPR1_USB_OTG_ID_SEL_GPIO_1 BIT(13)
  223854. -#define IMX6Q_GPR1_GINT BIT(12)
  223855. +#define IMX6Q_GPR1_GINT_MASK BIT(12)
  223856. +#define IMX6Q_GPR1_GINT_CLEAR 0x0
  223857. +#define IMX6Q_GPR1_GINT_ASSERT BIT(12)
  223858. #define IMX6Q_GPR1_ADDRS3_MASK (0x3 << 10)
  223859. #define IMX6Q_GPR1_ADDRS3_32MB (0x0 << 10)
  223860. #define IMX6Q_GPR1_ADDRS3_64MB (0x1 << 10)
  223861. diff -Nur linux-3.14.17/include/linux/mipi_csi2.h linux-imx6-3.14/include/linux/mipi_csi2.h
  223862. --- linux-3.14.17/include/linux/mipi_csi2.h 1970-01-01 01:00:00.000000000 +0100
  223863. +++ linux-imx6-3.14/include/linux/mipi_csi2.h 2014-09-11 18:06:10.890073466 +0200
  223864. @@ -0,0 +1,93 @@
  223865. +/*
  223866. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223867. + *
  223868. + * This program is free software; you can redistribute it and/or modify
  223869. + * it under the terms of the GNU General Public License as published by
  223870. + * the Free Software Foundation; either version 2 of the License, or
  223871. + * (at your option) any later version.
  223872. + *
  223873. + * This program is distributed in the hope that it will be useful,
  223874. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223875. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223876. + * GNU General Public License for more details.
  223877. + *
  223878. + * You should have received a copy of the GNU General Public License along
  223879. + * with this program; if not, write to the Free Software Foundation, Inc.,
  223880. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  223881. + */
  223882. +
  223883. +#ifndef __INCLUDE_MIPI_CSI2_H
  223884. +#define __INCLUDE_MIPI_CSI2_H
  223885. +
  223886. +/* MIPI CSI2 registers */
  223887. +#define MIPI_CSI2_REG(offset) (offset)
  223888. +
  223889. +#define MIPI_CSI2_VERSION MIPI_CSI2_REG(0x000)
  223890. +#define MIPI_CSI2_N_LANES MIPI_CSI2_REG(0x004)
  223891. +#define MIPI_CSI2_PHY_SHUTDOWNZ MIPI_CSI2_REG(0x008)
  223892. +#define MIPI_CSI2_DPHY_RSTZ MIPI_CSI2_REG(0x00c)
  223893. +#define MIPI_CSI2_CSI2_RESETN MIPI_CSI2_REG(0x010)
  223894. +#define MIPI_CSI2_PHY_STATE MIPI_CSI2_REG(0x014)
  223895. +#define MIPI_CSI2_DATA_IDS_1 MIPI_CSI2_REG(0x018)
  223896. +#define MIPI_CSI2_DATA_IDS_2 MIPI_CSI2_REG(0x01c)
  223897. +#define MIPI_CSI2_ERR1 MIPI_CSI2_REG(0x020)
  223898. +#define MIPI_CSI2_ERR2 MIPI_CSI2_REG(0x024)
  223899. +#define MIPI_CSI2_MASK1 MIPI_CSI2_REG(0x028)
  223900. +#define MIPI_CSI2_MASK2 MIPI_CSI2_REG(0x02c)
  223901. +#define MIPI_CSI2_PHY_TST_CTRL0 MIPI_CSI2_REG(0x030)
  223902. +#define MIPI_CSI2_PHY_TST_CTRL1 MIPI_CSI2_REG(0x034)
  223903. +#define MIPI_CSI2_SFT_RESET MIPI_CSI2_REG(0xf00)
  223904. +
  223905. +/* mipi data type */
  223906. +#define MIPI_DT_YUV420 0x18 /* YYY.../UYVY.... */
  223907. +#define MIPI_DT_YUV420_LEGACY 0x1a /* UYY.../VYY... */
  223908. +#define MIPI_DT_YUV422 0x1e /* UYVY... */
  223909. +#define MIPI_DT_RGB444 0x20
  223910. +#define MIPI_DT_RGB555 0x21
  223911. +#define MIPI_DT_RGB565 0x22
  223912. +#define MIPI_DT_RGB666 0x23
  223913. +#define MIPI_DT_RGB888 0x24
  223914. +#define MIPI_DT_RAW6 0x28
  223915. +#define MIPI_DT_RAW7 0x29
  223916. +#define MIPI_DT_RAW8 0x2a
  223917. +#define MIPI_DT_RAW10 0x2b
  223918. +#define MIPI_DT_RAW12 0x2c
  223919. +#define MIPI_DT_RAW14 0x2d
  223920. +
  223921. +
  223922. +struct mipi_csi2_info;
  223923. +/* mipi csi2 API */
  223924. +struct mipi_csi2_info *mipi_csi2_get_info(void);
  223925. +
  223926. +bool mipi_csi2_enable(struct mipi_csi2_info *info);
  223927. +
  223928. +bool mipi_csi2_disable(struct mipi_csi2_info *info);
  223929. +
  223930. +bool mipi_csi2_get_status(struct mipi_csi2_info *info);
  223931. +
  223932. +int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info);
  223933. +
  223934. +unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info);
  223935. +
  223936. +unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info);
  223937. +
  223938. +unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info);
  223939. +
  223940. +unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
  223941. + unsigned int datatype);
  223942. +
  223943. +unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info);
  223944. +
  223945. +unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info);
  223946. +
  223947. +unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info);
  223948. +
  223949. +unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info);
  223950. +
  223951. +int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info);
  223952. +
  223953. +void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info);
  223954. +
  223955. +int mipi_csi2_reset(struct mipi_csi2_info *info);
  223956. +
  223957. +#endif
  223958. diff -Nur linux-3.14.17/include/linux/mipi_dsi.h linux-imx6-3.14/include/linux/mipi_dsi.h
  223959. --- linux-3.14.17/include/linux/mipi_dsi.h 1970-01-01 01:00:00.000000000 +0100
  223960. +++ linux-imx6-3.14/include/linux/mipi_dsi.h 2014-09-11 18:06:10.890073466 +0200
  223961. @@ -0,0 +1,171 @@
  223962. +/*
  223963. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  223964. + *
  223965. + * This program is free software; you can redistribute it and/or modify
  223966. + * it under the terms of the GNU General Public License as published by
  223967. + * the Free Software Foundation; either version 2 of the License, or
  223968. + * (at your option) any later version.
  223969. + *
  223970. + * This program is distributed in the hope that it will be useful,
  223971. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  223972. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  223973. + * GNU General Public License for more details.
  223974. + *
  223975. + * You should have received a copy of the GNU General Public License along
  223976. + * with this program; if not, write to the Free Software Foundation, Inc.,
  223977. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  223978. + */
  223979. +
  223980. +#ifndef __INCLUDE_MIPI_DSI_H
  223981. +#define __INCLUDE_MIPI_DSI_H
  223982. +
  223983. +#define MIPI_DSI_VERSION (0x000)
  223984. +#define MIPI_DSI_PWR_UP (0x004)
  223985. +#define MIPI_DSI_CLKMGR_CFG (0x008)
  223986. +#define MIPI_DSI_DPI_CFG (0x00c)
  223987. +#define MIPI_DSI_DBI_CFG (0x010)
  223988. +#define MIPI_DSI_DBIS_CMDSIZE (0x014)
  223989. +#define MIPI_DSI_PCKHDL_CFG (0x018)
  223990. +#define MIPI_DSI_VID_MODE_CFG (0x01c)
  223991. +#define MIPI_DSI_VID_PKT_CFG (0x020)
  223992. +#define MIPI_DSI_CMD_MODE_CFG (0x024)
  223993. +#define MIPI_DSI_TMR_LINE_CFG (0x028)
  223994. +#define MIPI_DSI_VTIMING_CFG (0x02c)
  223995. +#define MIPI_DSI_PHY_TMR_CFG (0x030)
  223996. +#define MIPI_DSI_GEN_HDR (0x034)
  223997. +#define MIPI_DSI_GEN_PLD_DATA (0x038)
  223998. +#define MIPI_DSI_CMD_PKT_STATUS (0x03c)
  223999. +#define MIPI_DSI_TO_CNT_CFG (0x040)
  224000. +#define MIPI_DSI_ERROR_ST0 (0x044)
  224001. +#define MIPI_DSI_ERROR_ST1 (0x048)
  224002. +#define MIPI_DSI_ERROR_MSK0 (0x04c)
  224003. +#define MIPI_DSI_ERROR_MSK1 (0x050)
  224004. +#define MIPI_DSI_PHY_RSTZ (0x054)
  224005. +#define MIPI_DSI_PHY_IF_CFG (0x058)
  224006. +#define MIPI_DSI_PHY_IF_CTRL (0x05c)
  224007. +#define MIPI_DSI_PHY_STATUS (0x060)
  224008. +#define MIPI_DSI_PHY_TST_CTRL0 (0x064)
  224009. +#define MIPI_DSI_PHY_TST_CTRL1 (0x068)
  224010. +
  224011. +#define DSI_PWRUP_RESET (0x0 << 0)
  224012. +#define DSI_PWRUP_POWERUP (0x1 << 0)
  224013. +
  224014. +#define DSI_DPI_CFG_VID_SHIFT (0)
  224015. +#define DSI_DPI_CFG_VID_MASK (0x3)
  224016. +#define DSI_DPI_CFG_COLORCODE_SHIFT (2)
  224017. +#define DSI_DPI_CFG_COLORCODE_MASK (0x7)
  224018. +#define DSI_DPI_CFG_DATAEN_ACT_LOW (0x1 << 5)
  224019. +#define DSI_DPI_CFG_DATAEN_ACT_HIGH (0x0 << 5)
  224020. +#define DSI_DPI_CFG_VSYNC_ACT_LOW (0x1 << 6)
  224021. +#define DSI_DPI_CFG_VSYNC_ACT_HIGH (0x0 << 6)
  224022. +#define DSI_DPI_CFG_HSYNC_ACT_LOW (0x1 << 7)
  224023. +#define DSI_DPI_CFG_HSYNC_ACT_HIGH (0x0 << 7)
  224024. +#define DSI_DPI_CFG_SHUTD_ACT_LOW (0x1 << 8)
  224025. +#define DSI_DPI_CFG_SHUTD_ACT_HIGH (0x0 << 8)
  224026. +#define DSI_DPI_CFG_COLORMODE_ACT_LOW (0x1 << 9)
  224027. +#define DSI_DPI_CFG_COLORMODE_ACT_HIGH (0x0 << 9)
  224028. +#define DSI_DPI_CFG_EN18LOOSELY (0x1 << 10)
  224029. +
  224030. +#define DSI_PCKHDL_CFG_EN_EOTP_TX (0x1 << 0)
  224031. +#define DSI_PCKHDL_CFG_EN_EOTP_RX (0x1 << 1)
  224032. +#define DSI_PCKHDL_CFG_EN_BTA (0x1 << 2)
  224033. +#define DSI_PCKHDL_CFG_EN_ECC_RX (0x1 << 3)
  224034. +#define DSI_PCKHDL_CFG_EN_CRC_RX (0x1 << 4)
  224035. +#define DSI_PCKHDL_CFG_GEN_VID_RX_MASK (0x3)
  224036. +#define DSI_PCKHDL_CFG_GEN_VID_RX_SHIFT (5)
  224037. +
  224038. +#define DSI_VID_MODE_CFG_EN (0x1 << 0)
  224039. +#define DSI_VID_MODE_CFG_EN_BURSTMODE (0x3 << 1)
  224040. +#define DSI_VID_MODE_CFG_TYPE_MASK (0x3)
  224041. +#define DSI_VID_MODE_CFG_TYPE_SHIFT (1)
  224042. +#define DSI_VID_MODE_CFG_EN_LP_VSA (0x1 << 3)
  224043. +#define DSI_VID_MODE_CFG_EN_LP_VBP (0x1 << 4)
  224044. +#define DSI_VID_MODE_CFG_EN_LP_VFP (0x1 << 5)
  224045. +#define DSI_VID_MODE_CFG_EN_LP_VACT (0x1 << 6)
  224046. +#define DSI_VID_MODE_CFG_EN_LP_HBP (0x1 << 7)
  224047. +#define DSI_VID_MODE_CFG_EN_LP_HFP (0x1 << 8)
  224048. +#define DSI_VID_MODE_CFG_EN_MULTI_PKT (0x1 << 9)
  224049. +#define DSI_VID_MODE_CFG_EN_NULL_PKT (0x1 << 10)
  224050. +#define DSI_VID_MODE_CFG_EN_FRAME_ACK (0x1 << 11)
  224051. +#define DSI_VID_MODE_CFG_EN_LP_MODE (DSI_VID_MODE_CFG_EN_LP_VSA | \
  224052. + DSI_VID_MODE_CFG_EN_LP_VBP | \
  224053. + DSI_VID_MODE_CFG_EN_LP_VFP | \
  224054. + DSI_VID_MODE_CFG_EN_LP_HFP | \
  224055. + DSI_VID_MODE_CFG_EN_LP_HBP | \
  224056. + DSI_VID_MODE_CFG_EN_LP_VACT)
  224057. +
  224058. +
  224059. +
  224060. +#define DSI_VID_PKT_CFG_VID_PKT_SZ_MASK (0x7ff)
  224061. +#define DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT (0)
  224062. +#define DSI_VID_PKT_CFG_NUM_CHUNKS_MASK (0x3ff)
  224063. +#define DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT (11)
  224064. +#define DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK (0x3ff)
  224065. +#define DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT (21)
  224066. +
  224067. +#define MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER (0x1FFF)
  224068. +#define MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE (0x1 << 0)
  224069. +
  224070. +#define DSI_TME_LINE_CFG_HSA_TIME_MASK (0x1ff)
  224071. +#define DSI_TME_LINE_CFG_HSA_TIME_SHIFT (0)
  224072. +#define DSI_TME_LINE_CFG_HBP_TIME_MASK (0x1ff)
  224073. +#define DSI_TME_LINE_CFG_HBP_TIME_SHIFT (9)
  224074. +#define DSI_TME_LINE_CFG_HLINE_TIME_MASK (0x3fff)
  224075. +#define DSI_TME_LINE_CFG_HLINE_TIME_SHIFT (18)
  224076. +
  224077. +#define DSI_VTIMING_CFG_VSA_LINES_MASK (0xf)
  224078. +#define DSI_VTIMING_CFG_VSA_LINES_SHIFT (0)
  224079. +#define DSI_VTIMING_CFG_VBP_LINES_MASK (0x3f)
  224080. +#define DSI_VTIMING_CFG_VBP_LINES_SHIFT (4)
  224081. +#define DSI_VTIMING_CFG_VFP_LINES_MASK (0x3f)
  224082. +#define DSI_VTIMING_CFG_VFP_LINES_SHIFT (10)
  224083. +#define DSI_VTIMING_CFG_V_ACT_LINES_MASK (0x7ff)
  224084. +#define DSI_VTIMING_CFG_V_ACT_LINES_SHIFT (16)
  224085. +
  224086. +#define DSI_PHY_TMR_CFG_BTA_TIME_MASK (0xfff)
  224087. +#define DSI_PHY_TMR_CFG_BTA_TIME_SHIFT (0)
  224088. +#define DSI_PHY_TMR_CFG_LP2HS_TIME_MASK (0xff)
  224089. +#define DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT (12)
  224090. +#define DSI_PHY_TMR_CFG_HS2LP_TIME_MASK (0xff)
  224091. +#define DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT (20)
  224092. +
  224093. +#define DSI_PHY_IF_CFG_N_LANES_MASK (0x3)
  224094. +#define DSI_PHY_IF_CFG_N_LANES_SHIFT (0)
  224095. +#define DSI_PHY_IF_CFG_WAIT_TIME_MASK (0xff)
  224096. +#define DSI_PHY_IF_CFG_WAIT_TIME_SHIFT (2)
  224097. +
  224098. +#define DSI_PHY_RSTZ_EN_CLK (0x1 << 2)
  224099. +#define DSI_PHY_RSTZ_DISABLE_RST (0x1 << 1)
  224100. +#define DSI_PHY_RSTZ_DISABLE_SHUTDOWN (0x1 << 0)
  224101. +#define DSI_PHY_RSTZ_RST (0x0)
  224102. +
  224103. +#define DSI_PHY_STATUS_LOCK (0x1 << 0)
  224104. +#define DSI_PHY_STATUS_STOPSTATE_CLK_LANE (0x1 << 2)
  224105. +
  224106. +#define DSI_GEN_HDR_TYPE_MASK (0xff)
  224107. +#define DSI_GEN_HDR_TYPE_SHIFT (0)
  224108. +#define DSI_GEN_HDR_DATA_MASK (0xffff)
  224109. +#define DSI_GEN_HDR_DATA_SHIFT (8)
  224110. +
  224111. +#define DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY (0x1 << 0)
  224112. +#define DSI_CMD_PKT_STATUS_GEN_CMD_FULL (0x1 << 1)
  224113. +#define DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY (0x1 << 2)
  224114. +#define DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL (0x1 << 3)
  224115. +#define DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY (0x1 << 4)
  224116. +#define DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY (0x1 << 6)
  224117. +
  224118. +#define DSI_ERROR_MSK0_ALL_MASK (0x1fffff)
  224119. +#define DSI_ERROR_MSK1_ALL_MASK (0x3ffff)
  224120. +
  224121. +#define DSI_PHY_IF_CTRL_RESET (0x0)
  224122. +#define DSI_PHY_IF_CTRL_TX_REQ_CLK_HS (0x1 << 0)
  224123. +#define DSI_PHY_IF_CTRL_TX_REQ_CLK_ULPS (0x1 << 1)
  224124. +#define DSI_PHY_IF_CTRL_TX_EXIT_CLK_ULPS (0x1 << 2)
  224125. +#define DSI_PHY_IF_CTRL_TX_REQ_DATA_ULPS (0x1 << 3)
  224126. +#define DSI_PHY_IF_CTRL_TX_EXIT_DATA_ULPS (0x1 << 4)
  224127. +#define DSI_PHY_IF_CTRL_TX_TRIG_MASK (0xF)
  224128. +#define DSI_PHY_IF_CTRL_TX_TRIG_SHIFT (5)
  224129. +
  224130. +#define DSI_PHY_CLK_INIT_COMMAND (0x44)
  224131. +#define DSI_GEN_PLD_DATA_BUF_SIZE (0x4)
  224132. +#endif
  224133. diff -Nur linux-3.14.17/include/linux/mmc/card.h linux-imx6-3.14/include/linux/mmc/card.h
  224134. --- linux-3.14.17/include/linux/mmc/card.h 2014-08-14 03:38:34.000000000 +0200
  224135. +++ linux-imx6-3.14/include/linux/mmc/card.h 2014-09-11 18:06:10.890073466 +0200
  224136. @@ -86,10 +86,13 @@
  224137. unsigned int data_sector_size; /* 512 bytes or 4KB */
  224138. unsigned int data_tag_unit_size; /* DATA TAG UNIT size */
  224139. unsigned int boot_ro_lock; /* ro lock support */
  224140. + unsigned int boot_size;
  224141. bool boot_ro_lockable;
  224142. u8 raw_exception_status; /* 54 */
  224143. u8 raw_partition_support; /* 160 */
  224144. u8 raw_rpmb_size_mult; /* 168 */
  224145. + u8 boot_bus_width; /* 177 */
  224146. + u8 boot_config; /* 179 */
  224147. u8 raw_erased_mem_count; /* 181 */
  224148. u8 raw_ext_csd_structure; /* 194 */
  224149. u8 raw_card_type; /* 196 */
  224150. @@ -102,6 +105,7 @@
  224151. u8 raw_hc_erase_gap_size; /* 221 */
  224152. u8 raw_erase_timeout_mult; /* 223 */
  224153. u8 raw_hc_erase_grp_size; /* 224 */
  224154. + u8 boot_info; /* 228 */
  224155. u8 raw_sec_trim_mult; /* 229 */
  224156. u8 raw_sec_erase_mult; /* 230 */
  224157. u8 raw_sec_feature_support;/* 231 */
  224158. diff -Nur linux-3.14.17/include/linux/mmc/host.h linux-imx6-3.14/include/linux/mmc/host.h
  224159. --- linux-3.14.17/include/linux/mmc/host.h 2014-08-14 03:38:34.000000000 +0200
  224160. +++ linux-imx6-3.14/include/linux/mmc/host.h 2014-09-11 18:06:10.890073466 +0200
  224161. @@ -282,6 +282,7 @@
  224162. MMC_CAP2_PACKED_WR)
  224163. #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
  224164. #define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */
  224165. +#define MMC_CAP2_SDIO_NOTHREAD (1 << 16)
  224166. mmc_pm_flag_t pm_caps; /* supported pm features */
  224167. @@ -297,6 +298,11 @@
  224168. unsigned long clkgate_delay;
  224169. #endif
  224170. + /* card specific properties to deal with power and reset */
  224171. + struct regulator *card_regulator; /* External VCC needed by the card */
  224172. + struct gpio_desc *card_reset_gpios[2]; /* External resets, active low */
  224173. + struct clk *card_clk; /* External clock needed by the card */
  224174. +
  224175. /* host specific block data */
  224176. unsigned int max_seg_size; /* see blk_queue_max_segment_size */
  224177. unsigned short max_segs; /* see blk_queue_max_segments */
  224178. @@ -397,6 +403,8 @@
  224179. wake_up_process(host->sdio_irq_thread);
  224180. }
  224181. +void sdio_run_irqs(struct mmc_host *host);
  224182. +
  224183. #ifdef CONFIG_REGULATOR
  224184. int mmc_regulator_get_ocrmask(struct regulator *supply);
  224185. int mmc_regulator_set_ocr(struct mmc_host *mmc,
  224186. diff -Nur linux-3.14.17/include/linux/mmc/mmc.h linux-imx6-3.14/include/linux/mmc/mmc.h
  224187. --- linux-3.14.17/include/linux/mmc/mmc.h 2014-08-14 03:38:34.000000000 +0200
  224188. +++ linux-imx6-3.14/include/linux/mmc/mmc.h 2014-09-11 18:06:10.890073466 +0200
  224189. @@ -292,6 +292,7 @@
  224190. #define EXT_CSD_RPMB_MULT 168 /* RO */
  224191. #define EXT_CSD_BOOT_WP 173 /* R/W */
  224192. #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
  224193. +#define EXT_CSD_BOOT_BUS_WIDTH 177 /* R/W */
  224194. #define EXT_CSD_PART_CONFIG 179 /* R/W */
  224195. #define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
  224196. #define EXT_CSD_BUS_WIDTH 183 /* R/W */
  224197. @@ -313,6 +314,7 @@
  224198. #define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
  224199. #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
  224200. #define EXT_CSD_BOOT_MULT 226 /* RO */
  224201. +#define EXT_CSD_BOOT_INFO 228 /* RO, 1 bytes */
  224202. #define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
  224203. #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
  224204. #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
  224205. @@ -378,6 +380,29 @@
  224206. #define EXT_CSD_SEC_GB_CL_EN BIT(4)
  224207. #define EXT_CSD_SEC_SANITIZE BIT(6) /* v4.5 only */
  224208. +#define EXT_CSD_BOOT_BUS_WIDTH_MASK (0x1F)
  224209. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_MASK (0x3 << 3)
  224210. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_NORMAL (0x0)
  224211. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_SDR_HIGH (0x1)
  224212. +#define EXT_CSD_BOOT_BUS_WIDTH_MODE_DDR (0x2)
  224213. +#define EXT_CSD_BOOT_BUS_WIDTH_RST_WIDTH (1 << 2)
  224214. +#define EXT_CSD_BOOT_BUS_WIDTH_WIDTH_MASK (0x3)
  224215. +#define EXT_CSD_BOOT_BUS_WIDTH_1_SDR_4_DDR (0x0)
  224216. +#define EXT_CSD_BOOT_BUS_WIDTH_4_SDR_4_DDR (0x1)
  224217. +#define EXT_CSD_BOOT_BUS_WIDTH_8_SDR_8_DDR (0x2)
  224218. +
  224219. +#define EXT_CSD_BOOT_ACK_ENABLE (0x1 << 6)
  224220. +#define EXT_CSD_BOOT_PARTITION_ENABLE_MASK (0x7 << 3)
  224221. +#define EXT_CSD_BOOT_PARTITION_DISABLE (0x0)
  224222. +#define EXT_CSD_BOOT_PARTITION_PART1 (0x1 << 3)
  224223. +#define EXT_CSD_BOOT_PARTITION_PART2 (0x2 << 3)
  224224. +#define EXT_CSD_BOOT_PARTITION_USER (0x7 << 3)
  224225. +
  224226. +#define EXT_CSD_BOOT_PARTITION_ACCESS_MASK (0x7)
  224227. +#define EXT_CSD_BOOT_PARTITION_ACCESS_DISABLE (0x0)
  224228. +#define EXT_CSD_BOOT_PARTITION_ACCESS_PART1 (0x1)
  224229. +#define EXT_CSD_BOOT_PARTITION_ACCESS_PART2 (0x2)
  224230. +
  224231. #define EXT_CSD_RST_N_EN_MASK 0x3
  224232. #define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
  224233. diff -Nur linux-3.14.17/include/linux/mmc/sdhci.h linux-imx6-3.14/include/linux/mmc/sdhci.h
  224234. --- linux-3.14.17/include/linux/mmc/sdhci.h 2014-08-14 03:38:34.000000000 +0200
  224235. +++ linux-imx6-3.14/include/linux/mmc/sdhci.h 2014-09-11 18:06:10.890073466 +0200
  224236. @@ -57,12 +57,8 @@
  224237. #define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15)
  224238. /* Controller reports inverted write-protect state */
  224239. #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16)
  224240. -/* Controller has nonstandard clock management */
  224241. -#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1<<17)
  224242. /* Controller does not like fast PIO transfers */
  224243. #define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18)
  224244. -/* Controller losing signal/interrupt enable states after reset */
  224245. -#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<19)
  224246. /* Controller has to be forced to use block size of 2048 bytes */
  224247. #define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20)
  224248. /* Controller cannot do multi-block transfers */
  224249. @@ -100,6 +96,7 @@
  224250. #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
  224251. /* Controller does not support HS200 */
  224252. #define SDHCI_QUIRK2_BROKEN_HS200 (1<<6)
  224253. +#define SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER (1<<7)
  224254. int irq; /* Device IRQ */
  224255. void __iomem *ioaddr; /* Mapped address */
  224256. @@ -145,6 +142,7 @@
  224257. bool runtime_suspended; /* Host is runtime suspended */
  224258. bool bus_on; /* Bus power prevents runtime suspend */
  224259. + bool preset_enabled; /* Preset is enabled */
  224260. struct mmc_request *mrq; /* Current request */
  224261. struct mmc_command *cmd; /* Current command */
  224262. @@ -162,8 +160,7 @@
  224263. dma_addr_t adma_addr; /* Mapped ADMA descr. table */
  224264. dma_addr_t align_addr; /* Mapped bounce buffer */
  224265. - struct tasklet_struct card_tasklet; /* Tasklet structures */
  224266. - struct tasklet_struct finish_tasklet;
  224267. + struct tasklet_struct finish_tasklet; /* Tasklet structures */
  224268. struct timer_list timer; /* Timer for timeouts */
  224269. @@ -175,6 +172,13 @@
  224270. unsigned int ocr_avail_mmc;
  224271. u32 ocr_mask; /* available voltages */
  224272. + unsigned timing; /* Current timing */
  224273. +
  224274. + u32 thread_isr;
  224275. +
  224276. + /* cached registers */
  224277. + u32 ier;
  224278. +
  224279. wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */
  224280. unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */
  224281. diff -Nur linux-3.14.17/include/linux/mmc/sdio_ids.h linux-imx6-3.14/include/linux/mmc/sdio_ids.h
  224282. --- linux-3.14.17/include/linux/mmc/sdio_ids.h 2014-08-14 03:38:34.000000000 +0200
  224283. +++ linux-imx6-3.14/include/linux/mmc/sdio_ids.h 2014-09-11 18:06:10.894073482 +0200
  224284. @@ -31,6 +31,7 @@
  224285. #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
  224286. #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
  224287. #define SDIO_DEVICE_ID_BROADCOM_43362 43362
  224288. +#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
  224289. #define SDIO_VENDOR_ID_INTEL 0x0089
  224290. #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
  224291. diff -Nur linux-3.14.17/include/linux/mod_devicetable.h linux-imx6-3.14/include/linux/mod_devicetable.h
  224292. --- linux-3.14.17/include/linux/mod_devicetable.h 2014-08-14 03:38:34.000000000 +0200
  224293. +++ linux-imx6-3.14/include/linux/mod_devicetable.h 2014-09-11 18:06:10.894073482 +0200
  224294. @@ -564,6 +564,15 @@
  224295. #define X86_MODEL_ANY 0
  224296. #define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
  224297. +/*
  224298. + * Generic table type for matching CPU features.
  224299. + * @feature: the bit number of the feature (0 - 65535)
  224300. + */
  224301. +
  224302. +struct cpu_feature {
  224303. + __u16 feature;
  224304. +};
  224305. +
  224306. #define IPACK_ANY_FORMAT 0xff
  224307. #define IPACK_ANY_ID (~0)
  224308. struct ipack_device_id {
  224309. diff -Nur linux-3.14.17/include/linux/mtd/map.h linux-imx6-3.14/include/linux/mtd/map.h
  224310. --- linux-3.14.17/include/linux/mtd/map.h 2014-08-14 03:38:34.000000000 +0200
  224311. +++ linux-imx6-3.14/include/linux/mtd/map.h 2014-09-11 18:06:10.894073482 +0200
  224312. @@ -438,7 +438,7 @@
  224313. if (map->cached)
  224314. memcpy(to, (char *)map->cached + from, len);
  224315. else
  224316. - memcpy_fromio(to, map->virt + from, len);
  224317. + memcpy(to, map->virt + from, len);
  224318. }
  224319. static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  224320. diff -Nur linux-3.14.17/include/linux/mxc_asrc.h linux-imx6-3.14/include/linux/mxc_asrc.h
  224321. --- linux-3.14.17/include/linux/mxc_asrc.h 1970-01-01 01:00:00.000000000 +0100
  224322. +++ linux-imx6-3.14/include/linux/mxc_asrc.h 2014-09-11 18:06:10.898073499 +0200
  224323. @@ -0,0 +1,386 @@
  224324. +/*
  224325. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224326. + *
  224327. + * The code contained herein is licensed under the GNU General Public
  224328. + * License. You may obtain a copy of the GNU General Public License
  224329. + * Version 2 or later at the following locations:
  224330. + *
  224331. + * http://www.opensource.org/licenses/gpl-license.html
  224332. + * http://www.gnu.org/copyleft/gpl.html
  224333. + *
  224334. + * @file mxc_asrc.h
  224335. + *
  224336. + * @brief i.MX Asynchronous Sample Rate Converter
  224337. + *
  224338. + * @ingroup Audio
  224339. + */
  224340. +
  224341. +#ifndef __MXC_ASRC_H__
  224342. +#define __MXC_ASRC_H__
  224343. +
  224344. +#include <uapi/linux/mxc_asrc.h>
  224345. +#include <linux/scatterlist.h>
  224346. +
  224347. +#define ASRC_DMA_BUFFER_NUM 2
  224348. +#define ASRC_INPUTFIFO_THRESHOLD 32
  224349. +#define ASRC_OUTPUTFIFO_THRESHOLD 32
  224350. +#define ASRC_FIFO_THRESHOLD_MIN 0
  224351. +#define ASRC_FIFO_THRESHOLD_MAX 63
  224352. +#define ASRC_DMA_BUFFER_SIZE (1024 * 48 * 4)
  224353. +#define ASRC_MAX_BUFFER_SIZE (1024 * 48)
  224354. +#define ASRC_OUTPUT_LAST_SAMPLE_DEFAULT 8
  224355. +
  224356. +
  224357. +/* Ideal Ratio mode doesn't care the outclk frequency, so be fixed */
  224358. +#define ASRC_PRESCALER_IDEAL_RATIO 5
  224359. +/* SPDIF rxclk pulse rate is 128 * samplerate, so 2 ^ 7 */
  224360. +#define ASRC_PRESCALER_SPDIF_RX 7
  224361. +/* SPDIF txclk pulse rate is 64 * samplerate, so 2 ^ 6 */
  224362. +#define ASRC_PRESCALER_SPDIF_TX 6
  224363. +/* I2S bclk is 16 * 2 = 32, so 2 ^ 5 */
  224364. +#define ASRC_PRESCALER_I2S_16BIT 5
  224365. +/* I2S bclk is 24 * 2 = 48 -> 64, so 2 ^ 6 */
  224366. +#define ASRC_PRESCALER_I2S_24BIT 6
  224367. +
  224368. +
  224369. +#define REG_ASRCTR 0x00
  224370. +#define REG_ASRIER 0x04
  224371. +#define REG_ASRCNCR 0x0C
  224372. +#define REG_ASRCFG 0x10
  224373. +#define REG_ASRCSR 0x14
  224374. +
  224375. +#define REG_ASRCDR1 0x18
  224376. +#define REG_ASRCDR2 0x1C
  224377. +#define REG_ASRCDR(x) ((x < 2) ? REG_ASRCDR1 : REG_ASRCDR2)
  224378. +
  224379. +#define REG_ASRSTR 0x20
  224380. +#define REG_ASRRA 0x24
  224381. +#define REG_ASRRB 0x28
  224382. +#define REG_ASRRC 0x2C
  224383. +#define REG_ASRPM1 0x40
  224384. +#define REG_ASRPM2 0x44
  224385. +#define REG_ASRPM3 0x48
  224386. +#define REG_ASRPM4 0x4C
  224387. +#define REG_ASRPM5 0x50
  224388. +#define REG_ASRTFR1 0x54
  224389. +#define REG_ASRCCR 0x5C
  224390. +
  224391. +#define REG_ASRDIA 0x60
  224392. +#define REG_ASRDOA 0x64
  224393. +#define REG_ASRDIB 0x68
  224394. +#define REG_ASRDOB 0x6C
  224395. +#define REG_ASRDIC 0x70
  224396. +#define REG_ASRDOC 0x74
  224397. +#define REG_ASRDI(x) (REG_ASRDIA + (x << 3))
  224398. +#define REG_ASRDO(x) (REG_ASRDOA + (x << 3))
  224399. +
  224400. +#define REG_ASRIDRHA 0x80
  224401. +#define REG_ASRIDRLA 0x84
  224402. +#define REG_ASRIDRHB 0x88
  224403. +#define REG_ASRIDRLB 0x8C
  224404. +#define REG_ASRIDRHC 0x90
  224405. +#define REG_ASRIDRLC 0x94
  224406. +#define REG_ASRIDRH(x) (REG_ASRIDRHA + (x << 3))
  224407. +#define REG_ASRIDRL(x) (REG_ASRIDRLA + (x << 3))
  224408. +
  224409. +#define REG_ASR76K 0x98
  224410. +#define REG_ASR56K 0x9C
  224411. +
  224412. +#define REG_ASRMCRA 0xA0
  224413. +#define REG_ASRFSTA 0xA4
  224414. +#define REG_ASRMCRB 0xA8
  224415. +#define REG_ASRFSTB 0xAC
  224416. +#define REG_ASRMCRC 0xB0
  224417. +#define REG_ASRFSTC 0xB4
  224418. +#define REG_ASRMCR(x) (REG_ASRMCRA + (x << 3))
  224419. +#define REG_ASRFST(x) (REG_ASRFSTA + (x << 3))
  224420. +
  224421. +#define REG_ASRMCR1A 0xC0
  224422. +#define REG_ASRMCR1B 0xC4
  224423. +#define REG_ASRMCR1C 0xC8
  224424. +#define REG_ASRMCR1(x) (REG_ASRMCR1A + (x << 2))
  224425. +
  224426. +
  224427. +/* REG0 0x00 REG_ASRCTR */
  224428. +#define ASRCTR_ATSx_SHIFT(x) (20 + x)
  224429. +#define ASRCTR_ATSx_MASK(x) (1 << ASRCTR_ATSx_SHIFT(x))
  224430. +#define ASRCTR_ATS(x) (1 << ASRCTR_ATSx_SHIFT(x))
  224431. +#define ASRCTR_USRx_SHIFT(x) (14 + (x << 1))
  224432. +#define ASRCTR_USRx_MASK(x) (1 << ASRCTR_USRx_SHIFT(x))
  224433. +#define ASRCTR_USR(x) (1 << ASRCTR_USRx_SHIFT(x))
  224434. +#define ASRCTR_IDRx_SHIFT(x) (13 + (x << 1))
  224435. +#define ASRCTR_IDRx_MASK(x) (1 << ASRCTR_IDRx_SHIFT(x))
  224436. +#define ASRCTR_IDR(x) (1 << ASRCTR_IDRx_SHIFT(x))
  224437. +#define ASRCTR_SRST_SHIFT 4
  224438. +#define ASRCTR_SRST_MASK (1 << ASRCTR_SRST_SHIFT)
  224439. +#define ASRCTR_SRST (1 << ASRCTR_SRST_SHIFT)
  224440. +#define ASRCTR_ASRCEx_SHIFT(x) (1 + x)
  224441. +#define ASRCTR_ASRCEx_MASK(x) (1 << ASRCTR_ASRCEx_SHIFT(x))
  224442. +#define ASRCTR_ASRCE(x) (1 << ASRCTR_ASRCEx_SHIFT(x))
  224443. +#define ASRCTR_ASRCEN_SHIFT 0
  224444. +#define ASRCTR_ASRCEN_MASK (1 << ASRCTR_ASRCEN_SHIFT)
  224445. +#define ASRCTR_ASRCEN (1 << ASRCTR_ASRCEN_SHIFT)
  224446. +
  224447. +/* REG1 0x04 REG_ASRIER */
  224448. +#define ASRIER_AFPWE_SHIFT 7
  224449. +#define ASRIER_AFPWE_MASK (1 << ASRIER_AFPWE_SHIFT)
  224450. +#define ASRIER_AFPWE (1 << ASRIER_AFPWE_SHIFT)
  224451. +#define ASRIER_AOLIE_SHIFT 6
  224452. +#define ASRIER_AOLIE_MASK (1 << ASRIER_AOLIE_SHIFT)
  224453. +#define ASRIER_AOLIE (1 << ASRIER_AOLIE_SHIFT)
  224454. +#define ASRIER_ADOEx_SHIFT(x) (3 + x)
  224455. +#define ASRIER_ADOEx_MASK(x) (1 << ASRIER_ADOEx_SHIFT(x))
  224456. +#define ASRIER_ADOE(x) (1 << ASRIER_ADOEx_SHIFT(x))
  224457. +#define ASRIER_ADIEx_SHIFT(x) (0 + x)
  224458. +#define ASRIER_ADIEx_MASK(x) (1 << ASRIER_ADIEx_SHIFT(x))
  224459. +#define ASRIER_ADIE(x) (1 << ASRIER_ADIEx_SHIFT(x))
  224460. +
  224461. +/* REG2 0x0C REG_ASRCNCR */
  224462. +#define ASRCNCR_ANCx_SHIFT(x, b) (b * x)
  224463. +#define ASRCNCR_ANCx_MASK(x, b) (((1 << b) - 1) << ASRCNCR_ANCx_SHIFT(x, b))
  224464. +#define ASRCNCR_ANCx_get(x, v, b) ((v & ASRCNCR_ANCx_MASK(x, b)) >> ASRCNCR_ANCx_SHIFT(x, b))
  224465. +#define ASRCNCR_ANCx_set(x, v, b) ((v << ASRCNCR_ANCx_SHIFT(x, b)) & ASRCNCR_ANCx_MASK(x, b))
  224466. +
  224467. +/* REG3 0x10 REG_ASRCFG */
  224468. +#define ASRCFG_INIRQx_SHIFT(x) (21 + x)
  224469. +#define ASRCFG_INIRQx_MASK(x) (1 << ASRCFG_INIRQx_SHIFT(x))
  224470. +#define ASRCFG_INIRQx (1 << ASRCFG_INIRQx_SHIFT(x))
  224471. +#define ASRCFG_NDPRx_SHIFT(x) (18 + x)
  224472. +#define ASRCFG_NDPRx_MASK(x) (1 << ASRCFG_NDPRx_SHIFT(x))
  224473. +#define ASRCFG_NDPRx (1 << ASRCFG_NDPRx_SHIFT(x))
  224474. +#define ASRCFG_POSTMODx_SHIFT(x) (8 + (x << 2))
  224475. +#define ASRCFG_POSTMODx_WIDTH 2
  224476. +#define ASRCFG_POSTMODx_MASK(x) (((1 << ASRCFG_POSTMODx_WIDTH) - 1) << ASRCFG_POSTMODx_SHIFT(x))
  224477. +#define ASRCFG_POSTMOD(x, v) ((v) << ASRCFG_POSTMODx_SHIFT(x))
  224478. +#define ASRCFG_POSTMODx_UP(x) (0 << ASRCFG_POSTMODx_SHIFT(x))
  224479. +#define ASRCFG_POSTMODx_DCON(x) (1 << ASRCFG_POSTMODx_SHIFT(x))
  224480. +#define ASRCFG_POSTMODx_DOWN(x) (2 << ASRCFG_POSTMODx_SHIFT(x))
  224481. +#define ASRCFG_PREMODx_SHIFT(x) (6 + (x << 2))
  224482. +#define ASRCFG_PREMODx_WIDTH 2
  224483. +#define ASRCFG_PREMODx_MASK(x) (((1 << ASRCFG_PREMODx_WIDTH) - 1) << ASRCFG_PREMODx_SHIFT(x))
  224484. +#define ASRCFG_PREMOD(x, v) ((v) << ASRCFG_PREMODx_SHIFT(x))
  224485. +#define ASRCFG_PREMODx_UP(x) (0 << ASRCFG_PREMODx_SHIFT(x))
  224486. +#define ASRCFG_PREMODx_DCON(x) (1 << ASRCFG_PREMODx_SHIFT(x))
  224487. +#define ASRCFG_PREMODx_DOWN(x) (2 << ASRCFG_PREMODx_SHIFT(x))
  224488. +#define ASRCFG_PREMODx_BYPASS(x) (3 << ASRCFG_PREMODx_SHIFT(x))
  224489. +
  224490. +/* REG4 0x14 REG_ASRCSR */
  224491. +#define ASRCSR_AxCSx_WIDTH 4
  224492. +#define ASRCSR_AxCSx_MASK ((1 << ASRCSR_AxCSx_WIDTH) - 1)
  224493. +#define ASRCSR_AOCSx_SHIFT(x) (12 + (x << 2))
  224494. +#define ASRCSR_AOCSx_MASK(x) (((1 << ASRCSR_AxCSx_WIDTH) - 1) << ASRCSR_AOCSx_SHIFT(x))
  224495. +#define ASRCSR_AOCS(x, v) ((v) << ASRCSR_AOCSx_SHIFT(x))
  224496. +#define ASRCSR_AICSx_SHIFT(x) (x << 2)
  224497. +#define ASRCSR_AICSx_MASK(x) (((1 << ASRCSR_AxCSx_WIDTH) - 1) << ASRCSR_AICSx_SHIFT(x))
  224498. +#define ASRCSR_AICS(x, v) ((v) << ASRCSR_AICSx_SHIFT(x))
  224499. +
  224500. +/* REG5&6 0x18 & 0x1C REG_ASRCDR1 & ASRCDR2 */
  224501. +#define ASRCDRx_AxCPx_WIDTH 3
  224502. +#define ASRCDRx_AICPx_SHIFT(x) (0 + (x % 2) * 6)
  224503. +#define ASRCDRx_AICPx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AICPx_SHIFT(x))
  224504. +#define ASRCDRx_AICP(x, v) ((v) << ASRCDRx_AICPx_SHIFT(x))
  224505. +#define ASRCDRx_AICDx_SHIFT(x) (3 + (x % 2) * 6)
  224506. +#define ASRCDRx_AICDx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AICDx_SHIFT(x))
  224507. +#define ASRCDRx_AICD(x, v) ((v) << ASRCDRx_AICDx_SHIFT(x))
  224508. +#define ASRCDRx_AOCPx_SHIFT(x) ((x < 2) ? 12 + x * 6 : 6)
  224509. +#define ASRCDRx_AOCPx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AOCPx_SHIFT(x))
  224510. +#define ASRCDRx_AOCP(x, v) ((v) << ASRCDRx_AOCPx_SHIFT(x))
  224511. +#define ASRCDRx_AOCDx_SHIFT(x) ((x < 2) ? 15 + x * 6 : 9)
  224512. +#define ASRCDRx_AOCDx_MASK(x) (((1 << ASRCDRx_AxCPx_WIDTH) - 1) << ASRCDRx_AOCDx_SHIFT(x))
  224513. +#define ASRCDRx_AOCD(x, v) ((v) << ASRCDRx_AOCDx_SHIFT(x))
  224514. +
  224515. +/* REG7 0x20 REG_ASRSTR */
  224516. +#define ASRSTR_DSLCNT_SHIFT 21
  224517. +#define ASRSTR_DSLCNT_MASK (1 << ASRSTR_DSLCNT_SHIFT)
  224518. +#define ASRSTR_DSLCNT (1 << ASRSTR_DSLCNT_SHIFT)
  224519. +#define ASRSTR_ATQOL_SHIFT 20
  224520. +#define ASRSTR_ATQOL_MASK (1 << ASRSTR_ATQOL_SHIFT)
  224521. +#define ASRSTR_ATQOL (1 << ASRSTR_ATQOL_SHIFT)
  224522. +#define ASRSTR_AOOLx_SHIFT(x) (17 + x)
  224523. +#define ASRSTR_AOOLx_MASK(x) (1 << ASRSTR_AOOLx_SHIFT(x))
  224524. +#define ASRSTR_AOOL(x) (1 << ASRSTR_AOOLx_SHIFT(x))
  224525. +#define ASRSTR_AIOLx_SHIFT(x) (14 + x)
  224526. +#define ASRSTR_AIOLx_MASK(x) (1 << ASRSTR_AIOLx_SHIFT(x))
  224527. +#define ASRSTR_AIOL(x) (1 << ASRSTR_AIOLx_SHIFT(x))
  224528. +#define ASRSTR_AODOx_SHIFT(x) (11 + x)
  224529. +#define ASRSTR_AODOx_MASK(x) (1 << ASRSTR_AODOx_SHIFT(x))
  224530. +#define ASRSTR_AODO(x) (1 << ASRSTR_AODOx_SHIFT(x))
  224531. +#define ASRSTR_AIDUx_SHIFT(x) (8 + x)
  224532. +#define ASRSTR_AIDUx_MASK(x) (1 << ASRSTR_AIDUx_SHIFT(x))
  224533. +#define ASRSTR_AIDU(x) (1 << ASRSTR_AIDUx_SHIFT(x))
  224534. +#define ASRSTR_FPWT_SHIFT 7
  224535. +#define ASRSTR_FPWT_MASK (1 << ASRSTR_FPWT_SHIFT)
  224536. +#define ASRSTR_FPWT (1 << ASRSTR_FPWT_SHIFT)
  224537. +#define ASRSTR_AOLE_SHIFT 6
  224538. +#define ASRSTR_AOLE_MASK (1 << ASRSTR_AOLE_SHIFT)
  224539. +#define ASRSTR_AOLE (1 << ASRSTR_AOLE_SHIFT)
  224540. +#define ASRSTR_AODEx_SHIFT(x) (3 + x)
  224541. +#define ASRSTR_AODFx_MASK(x) (1 << ASRSTR_AODEx_SHIFT(x))
  224542. +#define ASRSTR_AODF(x) (1 << ASRSTR_AODEx_SHIFT(x))
  224543. +#define ASRSTR_AIDEx_SHIFT(x) (0 + x)
  224544. +#define ASRSTR_AIDEx_MASK(x) (1 << ASRSTR_AIDEx_SHIFT(x))
  224545. +#define ASRSTR_AIDE(x) (1 << ASRSTR_AIDEx_SHIFT(x))
  224546. +
  224547. +/* REG10 0x54 REG_ASRTFR1 */
  224548. +#define ASRTFR1_TF_BASE_WIDTH 7
  224549. +#define ASRTFR1_TF_BASE_SHIFT 6
  224550. +#define ASRTFR1_TF_BASE_MASK (((1 << ASRTFR1_TF_BASE_WIDTH) - 1) << ASRTFR1_TF_BASE_SHIFT)
  224551. +#define ASRTFR1_TF_BASE(x) ((x) << ASRTFR1_TF_BASE_SHIFT)
  224552. +
  224553. +/*
  224554. + * REG22 0xA0 REG_ASRMCRA
  224555. + * REG24 0xA8 REG_ASRMCRB
  224556. + * REG26 0xB0 REG_ASRMCRC
  224557. + */
  224558. +#define ASRMCRx_ZEROBUFx_SHIFT 23
  224559. +#define ASRMCRx_ZEROBUFxCLR_MASK (1 << ASRMCRx_ZEROBUFx_SHIFT)
  224560. +#define ASRMCRx_ZEROBUFxCLR (1 << ASRMCRx_ZEROBUFx_SHIFT)
  224561. +#define ASRMCRx_EXTTHRSHx_SHIFT 22
  224562. +#define ASRMCRx_EXTTHRSHx_MASK (1 << ASRMCRx_EXTTHRSHx_SHIFT)
  224563. +#define ASRMCRx_EXTTHRSHx (1 << ASRMCRx_EXTTHRSHx_SHIFT)
  224564. +#define ASRMCRx_BUFSTALLx_SHIFT 21
  224565. +#define ASRMCRx_BUFSTALLx_MASK (1 << ASRMCRx_BUFSTALLx_SHIFT)
  224566. +#define ASRMCRx_BUFSTALLx (1 << ASRMCRx_BUFSTALLx_SHIFT)
  224567. +#define ASRMCRx_BYPASSPOLYx_SHIFT 20
  224568. +#define ASRMCRx_BYPASSPOLYx_MASK (1 << ASRMCRx_BYPASSPOLYx_SHIFT)
  224569. +#define ASRMCRx_BYPASSPOLYx (1 << ASRMCRx_BYPASSPOLYx_SHIFT)
  224570. +#define ASRMCRx_OUTFIFO_THRESHOLD_WIDTH 6
  224571. +#define ASRMCRx_OUTFIFO_THRESHOLD_SHIFT 12
  224572. +#define ASRMCRx_OUTFIFO_THRESHOLD_MASK (((1 << ASRMCRx_OUTFIFO_THRESHOLD_WIDTH) - 1) << ASRMCRx_OUTFIFO_THRESHOLD_SHIFT)
  224573. +#define ASRMCRx_OUTFIFO_THRESHOLD(v) (((v) << ASRMCRx_OUTFIFO_THRESHOLD_SHIFT) & ASRMCRx_OUTFIFO_THRESHOLD_MASK)
  224574. +#define ASRMCRx_RSYNIFx_SHIFT 11
  224575. +#define ASRMCRx_RSYNIFx_MASK (1 << ASRMCRx_RSYNIFx_SHIFT)
  224576. +#define ASRMCRx_RSYNIFx (1 << ASRMCRx_RSYNIFx_SHIFT)
  224577. +#define ASRMCRx_RSYNOFx_SHIFT 10
  224578. +#define ASRMCRx_RSYNOFx_MASK (1 << ASRMCRx_RSYNOFx_SHIFT)
  224579. +#define ASRMCRx_RSYNOFx (1 << ASRMCRx_RSYNOFx_SHIFT)
  224580. +#define ASRMCRx_INFIFO_THRESHOLD_WIDTH 6
  224581. +#define ASRMCRx_INFIFO_THRESHOLD_SHIFT 0
  224582. +#define ASRMCRx_INFIFO_THRESHOLD_MASK (((1 << ASRMCRx_INFIFO_THRESHOLD_WIDTH) - 1) << ASRMCRx_INFIFO_THRESHOLD_SHIFT)
  224583. +#define ASRMCRx_INFIFO_THRESHOLD(v) (((v) << ASRMCRx_INFIFO_THRESHOLD_SHIFT) & ASRMCRx_INFIFO_THRESHOLD_MASK)
  224584. +
  224585. +/*
  224586. + * REG23 0xA4 REG_ASRFSTA
  224587. + * REG25 0xAC REG_ASRFSTB
  224588. + * REG27 0xB4 REG_ASRFSTC
  224589. + */
  224590. +#define ASRFSTx_OAFx_SHIFT 23
  224591. +#define ASRFSTx_OAFx_MASK (1 << ASRFSTx_OAFx_SHIFT)
  224592. +#define ASRFSTx_OAFx (1 << ASRFSTx_OAFx_SHIFT)
  224593. +#define ASRFSTx_OUTPUT_FIFO_WIDTH 7
  224594. +#define ASRFSTx_OUTPUT_FIFO_SHIFT 12
  224595. +#define ASRFSTx_OUTPUT_FIFO_MASK (((1 << ASRFSTx_OUTPUT_FIFO_WIDTH) - 1) << ASRFSTx_OUTPUT_FIFO_SHIFT)
  224596. +#define ASRFSTx_IAEx_SHIFT 11
  224597. +#define ASRFSTx_IAEx_MASK (1 << ASRFSTx_OAFx_SHIFT)
  224598. +#define ASRFSTx_IAEx (1 << ASRFSTx_OAFx_SHIFT)
  224599. +#define ASRFSTx_INPUT_FIFO_WIDTH 7
  224600. +#define ASRFSTx_INPUT_FIFO_SHIFT 0
  224601. +#define ASRFSTx_INPUT_FIFO_MASK ((1 << ASRFSTx_INPUT_FIFO_WIDTH) - 1)
  224602. +
  224603. +/* REG28 0xC0 & 0xC4 & 0xC8 REG_ASRMCR1x */
  224604. +#define ASRMCR1x_IWD_WIDTH 3
  224605. +#define ASRMCR1x_IWD_SHIFT 9
  224606. +#define ASRMCR1x_IWD_MASK (((1 << ASRMCR1x_IWD_WIDTH) - 1) << ASRMCR1x_IWD_SHIFT)
  224607. +#define ASRMCR1x_IWD(v) ((v) << ASRMCR1x_IWD_SHIFT)
  224608. +#define ASRMCR1x_IMSB_SHIFT 8
  224609. +#define ASRMCR1x_IMSB_MASK (1 << ASRMCR1x_IMSB_SHIFT)
  224610. +#define ASRMCR1x_IMSB_MSB (1 << ASRMCR1x_IMSB_SHIFT)
  224611. +#define ASRMCR1x_IMSB_LSB (0 << ASRMCR1x_IMSB_SHIFT)
  224612. +#define ASRMCR1x_OMSB_SHIFT 2
  224613. +#define ASRMCR1x_OMSB_MASK (1 << ASRMCR1x_OMSB_SHIFT)
  224614. +#define ASRMCR1x_OMSB_MSB (1 << ASRMCR1x_OMSB_SHIFT)
  224615. +#define ASRMCR1x_OMSB_LSB (0 << ASRMCR1x_OMSB_SHIFT)
  224616. +#define ASRMCR1x_OSGN_SHIFT 1
  224617. +#define ASRMCR1x_OSGN_MASK (1 << ASRMCR1x_OSGN_SHIFT)
  224618. +#define ASRMCR1x_OSGN (1 << ASRMCR1x_OSGN_SHIFT)
  224619. +#define ASRMCR1x_OW16_SHIFT 0
  224620. +#define ASRMCR1x_OW16_MASK (1 << ASRMCR1x_OW16_SHIFT)
  224621. +#define ASRMCR1x_OW16(v) ((v) << ASRMCR1x_OW16_SHIFT)
  224622. +
  224623. +
  224624. +struct dma_block {
  224625. + unsigned int index;
  224626. + unsigned int length;
  224627. + void *dma_vaddr;
  224628. + dma_addr_t dma_paddr;
  224629. + struct list_head queue;
  224630. +};
  224631. +
  224632. +struct asrc_p2p_params {
  224633. + u32 p2p_rate; /* ASRC output rate for p2p */
  224634. + enum asrc_word_width p2p_width; /* ASRC output wordwidth for p2p */
  224635. +};
  224636. +
  224637. +struct asrc_pair_params {
  224638. + enum asrc_pair_index index;
  224639. + struct completion input_complete;
  224640. + struct completion output_complete;
  224641. + struct completion lastperiod_complete;
  224642. + struct dma_chan *input_dma_channel;
  224643. + struct dma_chan *output_dma_channel;
  224644. + unsigned int input_buffer_size;
  224645. + unsigned int output_buffer_size;
  224646. + unsigned int buffer_num;
  224647. + unsigned int pair_hold;
  224648. + unsigned int asrc_active;
  224649. + unsigned int channel_nums;
  224650. + struct dma_block input_dma_total;
  224651. + struct dma_block input_dma[ASRC_DMA_BUFFER_NUM];
  224652. + struct dma_block output_dma_total;
  224653. + struct dma_block output_dma[ASRC_DMA_BUFFER_NUM];
  224654. + struct dma_block output_last_period;
  224655. + struct dma_async_tx_descriptor *desc_in;
  224656. + struct dma_async_tx_descriptor *desc_out;
  224657. + struct work_struct task_output_work;
  224658. + unsigned int input_sg_nodes;
  224659. + unsigned int output_sg_nodes;
  224660. + struct scatterlist input_sg[4], output_sg[4];
  224661. + enum asrc_word_width input_word_width;
  224662. + enum asrc_word_width output_word_width;
  224663. + u32 input_sample_rate;
  224664. + u32 output_sample_rate;
  224665. + u32 input_wm;
  224666. + u32 output_wm;
  224667. + unsigned int last_period_sample;
  224668. +};
  224669. +
  224670. +struct asrc_data {
  224671. + struct asrc_pair asrc_pair[ASRC_PAIR_MAX_NUM];
  224672. + struct proc_dir_entry *proc_asrc;
  224673. + struct class *asrc_class;
  224674. + struct regmap *regmap;
  224675. + struct clk *asrc_clk;
  224676. + struct clk *dma_clk;
  224677. + unsigned long paddr;
  224678. + unsigned int channel_bits;
  224679. + int asrc_major;
  224680. + int irq;
  224681. + struct device *dev;
  224682. +};
  224683. +
  224684. +struct asrc_p2p_ops {
  224685. + void (*asrc_p2p_start_conv)(enum asrc_pair_index);
  224686. + void (*asrc_p2p_stop_conv)(enum asrc_pair_index);
  224687. + int (*asrc_p2p_get_dma_request)(enum asrc_pair_index, bool);
  224688. + u32 (*asrc_p2p_per_addr)(enum asrc_pair_index, bool);
  224689. + int (*asrc_p2p_req_pair)(int, enum asrc_pair_index *index);
  224690. + int (*asrc_p2p_config_pair)(struct asrc_config *config);
  224691. + void (*asrc_p2p_release_pair)(enum asrc_pair_index);
  224692. + void (*asrc_p2p_finish_conv)(enum asrc_pair_index);
  224693. +};
  224694. +
  224695. +extern void asrc_p2p_hook(struct asrc_p2p_ops *asrc_p2p_ct);
  224696. +
  224697. +extern int asrc_req_pair(int chn_num, enum asrc_pair_index *index);
  224698. +extern void asrc_release_pair(enum asrc_pair_index index);
  224699. +extern int asrc_config_pair(struct asrc_config *config);
  224700. +extern void asrc_get_status(struct asrc_status_flags *flags);
  224701. +extern void asrc_start_conv(enum asrc_pair_index index);
  224702. +extern void asrc_stop_conv(enum asrc_pair_index index);
  224703. +extern u32 asrc_get_per_addr(enum asrc_pair_index index, bool i);
  224704. +extern int asrc_get_dma_request(enum asrc_pair_index index, bool i);
  224705. +extern void asrc_finish_conv(enum asrc_pair_index index);
  224706. +extern int asrc_set_watermark(enum asrc_pair_index index,
  224707. + u32 in_wm, u32 out_wm);
  224708. +
  224709. +#endif/* __MXC_ASRC_H__ */
  224710. diff -Nur linux-3.14.17/include/linux/mxcfb.h linux-imx6-3.14/include/linux/mxcfb.h
  224711. --- linux-3.14.17/include/linux/mxcfb.h 1970-01-01 01:00:00.000000000 +0100
  224712. +++ linux-imx6-3.14/include/linux/mxcfb.h 2014-09-11 18:06:10.898073499 +0200
  224713. @@ -0,0 +1,46 @@
  224714. +/*
  224715. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224716. + */
  224717. +
  224718. +/*
  224719. + * The code contained herein is licensed under the GNU Lesser General
  224720. + * Public License. You may obtain a copy of the GNU Lesser General
  224721. + * Public License Version 2.1 or later at the following locations:
  224722. + *
  224723. + * http://www.opensource.org/licenses/lgpl-license.html
  224724. + * http://www.gnu.org/copyleft/lgpl.html
  224725. + */
  224726. +
  224727. +/*
  224728. + * @file linux/mxcfb.h
  224729. + *
  224730. + * @brief Global header file for the MXC Frame buffer
  224731. + *
  224732. + * @ingroup Framebuffer
  224733. + */
  224734. +#ifndef __LINUX_MXCFB_H__
  224735. +#define __LINUX_MXCFB_H__
  224736. +
  224737. +#include <uapi/linux/mxcfb.h>
  224738. +
  224739. +extern struct fb_videomode mxcfb_modedb[];
  224740. +extern int mxcfb_modedb_sz;
  224741. +
  224742. +enum {
  224743. + MXC_DISP_SPEC_DEV = 0,
  224744. + MXC_DISP_DDC_DEV = 1,
  224745. +};
  224746. +
  224747. +enum {
  224748. + MXCFB_REFRESH_OFF,
  224749. + MXCFB_REFRESH_AUTO,
  224750. + MXCFB_REFRESH_PARTIAL,
  224751. +};
  224752. +
  224753. +int mxcfb_set_refresh_mode(struct fb_info *fbi, int mode,
  224754. + struct mxcfb_rect *update_region);
  224755. +int mxc_elcdif_frame_addr_setup(dma_addr_t phys);
  224756. +void mxcfb_elcdif_register_mode(const struct fb_videomode *modedb,
  224757. + int num_modes, int dev_mode);
  224758. +
  224759. +#endif
  224760. diff -Nur linux-3.14.17/include/linux/mxc_mlb.h linux-imx6-3.14/include/linux/mxc_mlb.h
  224761. --- linux-3.14.17/include/linux/mxc_mlb.h 1970-01-01 01:00:00.000000000 +0100
  224762. +++ linux-imx6-3.14/include/linux/mxc_mlb.h 2014-09-11 18:06:10.898073499 +0200
  224763. @@ -0,0 +1,55 @@
  224764. +/*
  224765. + * mxc_mlb.h
  224766. + *
  224767. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224768. + */
  224769. +
  224770. +/*
  224771. + * The code contained herein is licensed under the GNU General Public
  224772. + * License. You may obtain a copy of the GNU General Public License
  224773. + * Version 2 or later at the following locations:
  224774. + *
  224775. + * http://www.opensource.org/licenses/gpl-license.html
  224776. + * http://www.gnu.org/copyleft/gpl.html
  224777. + */
  224778. +
  224779. +#ifndef _MXC_MLB_H
  224780. +#define _MXC_MLB_H
  224781. +
  224782. +/* define IOCTL command */
  224783. +#define MLB_DBG_RUNTIME _IO('S', 0x09)
  224784. +#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
  224785. +#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
  224786. +#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
  224787. +
  224788. +/*!
  224789. + * set channel address for each logical channel
  224790. + * the MSB 16bits is for tx channel, the left LSB is for rx channel
  224791. + */
  224792. +#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
  224793. +#define MLB_CHAN_STARTUP _IO('S', 0x14)
  224794. +#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
  224795. +#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
  224796. +
  224797. +#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
  224798. +#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
  224799. +#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
  224800. +#define MLB_IRQ_ENABLE _IO('S', 0x20)
  224801. +#define MLB_IRQ_DISABLE _IO('S', 0x21)
  224802. +
  224803. +/*!
  224804. + * MLB event define
  224805. + */
  224806. +enum {
  224807. + MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
  224808. + MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
  224809. + MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
  224810. + MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
  224811. + MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
  224812. + MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
  224813. + MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
  224814. + MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
  224815. +};
  224816. +
  224817. +
  224818. +#endif /* _MXC_MLB_H */
  224819. diff -Nur linux-3.14.17/include/linux/mxc_v4l2.h linux-imx6-3.14/include/linux/mxc_v4l2.h
  224820. --- linux-3.14.17/include/linux/mxc_v4l2.h 1970-01-01 01:00:00.000000000 +0100
  224821. +++ linux-imx6-3.14/include/linux/mxc_v4l2.h 2014-09-11 18:06:10.898073499 +0200
  224822. @@ -0,0 +1,27 @@
  224823. +/*
  224824. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224825. + */
  224826. +
  224827. +/*
  224828. + * The code contained herein is licensed under the GNU Lesser General
  224829. + * Public License. You may obtain a copy of the GNU Lesser General
  224830. + * Public License Version 2.1 or later at the following locations:
  224831. + *
  224832. + * http://www.opensource.org/licenses/lgpl-license.html
  224833. + * http://www.gnu.org/copyleft/lgpl.html
  224834. + */
  224835. +
  224836. +/*!
  224837. + * @file linux/mxc_v4l2.h
  224838. + *
  224839. + * @brief MXC V4L2 private header file
  224840. + *
  224841. + * @ingroup MXC V4L2
  224842. + */
  224843. +
  224844. +#ifndef __LINUX_MXC_V4L2_H__
  224845. +#define __LINUX_MXC_V4L2_H__
  224846. +
  224847. +#include <uapi/linux/mxc_v4l2.h>
  224848. +
  224849. +#endif
  224850. diff -Nur linux-3.14.17/include/linux/mxc_vpu.h linux-imx6-3.14/include/linux/mxc_vpu.h
  224851. --- linux-3.14.17/include/linux/mxc_vpu.h 1970-01-01 01:00:00.000000000 +0100
  224852. +++ linux-imx6-3.14/include/linux/mxc_vpu.h 2014-09-11 18:06:10.898073499 +0200
  224853. @@ -0,0 +1,118 @@
  224854. +/*
  224855. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  224856. + */
  224857. +
  224858. +/*
  224859. + * The code contained herein is licensed under the GNU Lesser General
  224860. + * Public License. You may obtain a copy of the GNU Lesser General
  224861. + * Public License Version 2.1 or later at the following locations:
  224862. + *
  224863. + * http://www.opensource.org/licenses/lgpl-license.html
  224864. + * http://www.gnu.org/copyleft/lgpl.html
  224865. + */
  224866. +
  224867. +/*!
  224868. + * @defgroup VPU Video Processor Unit Driver
  224869. + */
  224870. +
  224871. +/*!
  224872. + * @file linux/mxc_vpu.h
  224873. + *
  224874. + * @brief VPU system initialization and file operation definition
  224875. + *
  224876. + * @ingroup VPU
  224877. + */
  224878. +
  224879. +#ifndef __LINUX_MXC_VPU_H__
  224880. +#define __LINUX_MXC_VPU_H__
  224881. +
  224882. +#include <linux/fs.h>
  224883. +
  224884. +struct mxc_vpu_platform_data {
  224885. + bool iram_enable;
  224886. + int iram_size;
  224887. + void (*reset) (void);
  224888. + void (*pg) (int);
  224889. +};
  224890. +
  224891. +struct vpu_mem_desc {
  224892. + u32 size;
  224893. + dma_addr_t phy_addr;
  224894. + u32 cpu_addr; /* cpu address to free the dma mem */
  224895. + u32 virt_uaddr; /* virtual user space address */
  224896. +};
  224897. +
  224898. +#define VPU_IOC_MAGIC 'V'
  224899. +
  224900. +#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0)
  224901. +#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1)
  224902. +#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2)
  224903. +#define VPU_IOC_PHYMEM_DUMP _IO(VPU_IOC_MAGIC, 3)
  224904. +#define VPU_IOC_REG_DUMP _IO(VPU_IOC_MAGIC, 4)
  224905. +#define VPU_IOC_IRAM_SETTING _IO(VPU_IOC_MAGIC, 6)
  224906. +#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 7)
  224907. +#define VPU_IOC_GET_WORK_ADDR _IO(VPU_IOC_MAGIC, 8)
  224908. +#define VPU_IOC_REQ_VSHARE_MEM _IO(VPU_IOC_MAGIC, 9)
  224909. +#define VPU_IOC_SYS_SW_RESET _IO(VPU_IOC_MAGIC, 11)
  224910. +#define VPU_IOC_GET_SHARE_MEM _IO(VPU_IOC_MAGIC, 12)
  224911. +#define VPU_IOC_QUERY_BITWORK_MEM _IO(VPU_IOC_MAGIC, 13)
  224912. +#define VPU_IOC_SET_BITWORK_MEM _IO(VPU_IOC_MAGIC, 14)
  224913. +#define VPU_IOC_PHYMEM_CHECK _IO(VPU_IOC_MAGIC, 15)
  224914. +#define VPU_IOC_LOCK_DEV _IO(VPU_IOC_MAGIC, 16)
  224915. +
  224916. +#define BIT_CODE_RUN 0x000
  224917. +#define BIT_CODE_DOWN 0x004
  224918. +#define BIT_INT_CLEAR 0x00C
  224919. +#define BIT_INT_STATUS 0x010
  224920. +#define BIT_CUR_PC 0x018
  224921. +#define BIT_INT_REASON 0x174
  224922. +
  224923. +#define MJPEG_PIC_STATUS_REG 0x3004
  224924. +#define MBC_SET_SUBBLK_EN 0x4A0
  224925. +
  224926. +#define BIT_WORK_CTRL_BUF_BASE 0x100
  224927. +#define BIT_WORK_CTRL_BUF_REG(i) (BIT_WORK_CTRL_BUF_BASE + i * 4)
  224928. +#define BIT_CODE_BUF_ADDR BIT_WORK_CTRL_BUF_REG(0)
  224929. +#define BIT_WORK_BUF_ADDR BIT_WORK_CTRL_BUF_REG(1)
  224930. +#define BIT_PARA_BUF_ADDR BIT_WORK_CTRL_BUF_REG(2)
  224931. +#define BIT_BIT_STREAM_CTRL BIT_WORK_CTRL_BUF_REG(3)
  224932. +#define BIT_FRAME_MEM_CTRL BIT_WORK_CTRL_BUF_REG(4)
  224933. +#define BIT_BIT_STREAM_PARAM BIT_WORK_CTRL_BUF_REG(5)
  224934. +
  224935. +#ifndef CONFIG_SOC_IMX6Q
  224936. +#define BIT_RESET_CTRL 0x11C
  224937. +#else
  224938. +#define BIT_RESET_CTRL 0x128
  224939. +#endif
  224940. +
  224941. +/* i could be 0, 1, 2, 3 */
  224942. +#define BIT_RD_PTR_BASE 0x120
  224943. +#define BIT_RD_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8)
  224944. +#define BIT_WR_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8 + 4)
  224945. +
  224946. +/* i could be 0, 1, 2, 3 */
  224947. +#define BIT_FRM_DIS_FLG_BASE (cpu_is_mx51() ? 0x150 : 0x140)
  224948. +#define BIT_FRM_DIS_FLG_REG(i) (BIT_FRM_DIS_FLG_BASE + i * 4)
  224949. +
  224950. +#define BIT_BUSY_FLAG 0x160
  224951. +#define BIT_RUN_COMMAND 0x164
  224952. +#define BIT_INT_ENABLE 0x170
  224953. +
  224954. +#define BITVAL_PIC_RUN 8
  224955. +
  224956. +#define VPU_SLEEP_REG_VALUE 10
  224957. +#define VPU_WAKE_REG_VALUE 11
  224958. +
  224959. +int vl2cc_init(u32 vl2cc_hw_base);
  224960. +void vl2cc_enable(void);
  224961. +void vl2cc_flush(void);
  224962. +void vl2cc_disable(void);
  224963. +void vl2cc_cleanup(void);
  224964. +
  224965. +int vl2cc_init(u32 vl2cc_hw_base);
  224966. +void vl2cc_enable(void);
  224967. +void vl2cc_flush(void);
  224968. +void vl2cc_disable(void);
  224969. +void vl2cc_cleanup(void);
  224970. +
  224971. +#endif
  224972. diff -Nur linux-3.14.17/include/linux/phy.h linux-imx6-3.14/include/linux/phy.h
  224973. --- linux-3.14.17/include/linux/phy.h 2014-08-14 03:38:34.000000000 +0200
  224974. +++ linux-imx6-3.14/include/linux/phy.h 2014-09-11 18:06:10.970073785 +0200
  224975. @@ -609,6 +609,7 @@
  224976. return phydev->drv->read_status(phydev);
  224977. }
  224978. +int genphy_config_init(struct phy_device *phydev);
  224979. int genphy_setup_forced(struct phy_device *phydev);
  224980. int genphy_restart_aneg(struct phy_device *phydev);
  224981. int genphy_config_aneg(struct phy_device *phydev);
  224982. diff -Nur linux-3.14.17/include/linux/pipe_fs_i.h linux-imx6-3.14/include/linux/pipe_fs_i.h
  224983. --- linux-3.14.17/include/linux/pipe_fs_i.h 2014-08-14 03:38:34.000000000 +0200
  224984. +++ linux-imx6-3.14/include/linux/pipe_fs_i.h 2014-09-11 18:06:10.974073802 +0200
  224985. @@ -35,7 +35,7 @@
  224986. * @tmp_page: cached released page
  224987. * @readers: number of current readers of this pipe
  224988. * @writers: number of current writers of this pipe
  224989. - * @files: number of struct file refering this pipe (protected by ->i_lock)
  224990. + * @files: number of struct file referring this pipe (protected by ->i_lock)
  224991. * @waiting_writers: number of writers blocked waiting for room
  224992. * @r_counter: reader counter
  224993. * @w_counter: writer counter
  224994. diff -Nur linux-3.14.17/include/linux/pl320-ipc.h linux-imx6-3.14/include/linux/pl320-ipc.h
  224995. --- linux-3.14.17/include/linux/pl320-ipc.h 1970-01-01 01:00:00.000000000 +0100
  224996. +++ linux-imx6-3.14/include/linux/pl320-ipc.h 2014-09-11 18:06:10.978073817 +0200
  224997. @@ -0,0 +1,17 @@
  224998. +/*
  224999. + * This program is free software; you can redistribute it and/or modify it
  225000. + * under the terms and conditions of the GNU General Public License,
  225001. + * version 2, as published by the Free Software Foundation.
  225002. + *
  225003. + * This program is distributed in the hope it will be useful, but WITHOUT
  225004. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  225005. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  225006. + * more details.
  225007. + *
  225008. + * You should have received a copy of the GNU General Public License along with
  225009. + * this program. If not, see <http://www.gnu.org/licenses/>.
  225010. + */
  225011. +
  225012. +int pl320_ipc_transmit(u32 *data);
  225013. +int pl320_ipc_register_notifier(struct notifier_block *nb);
  225014. +int pl320_ipc_unregister_notifier(struct notifier_block *nb);
  225015. diff -Nur linux-3.14.17/include/linux/platform_data/dma-imx.h linux-imx6-3.14/include/linux/platform_data/dma-imx.h
  225016. --- linux-3.14.17/include/linux/platform_data/dma-imx.h 2014-08-14 03:38:34.000000000 +0200
  225017. +++ linux-imx6-3.14/include/linux/platform_data/dma-imx.h 2014-09-11 18:06:10.982073833 +0200
  225018. @@ -1,5 +1,5 @@
  225019. /*
  225020. - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
  225021. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  225022. *
  225023. * This program is free software; you can redistribute it and/or modify
  225024. * it under the terms of the GNU General Public License version 2 as
  225025. @@ -40,6 +40,7 @@
  225026. IMX_DMATYPE_ASRC, /* ASRC */
  225027. IMX_DMATYPE_ESAI, /* ESAI */
  225028. IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */
  225029. + IMX_DMATYPE_HDMI, /* HDMI Audio */
  225030. };
  225031. enum imx_dma_prio {
  225032. @@ -49,9 +50,11 @@
  225033. };
  225034. struct imx_dma_data {
  225035. - int dma_request; /* DMA request line */
  225036. + int dma_request0; /* DMA request line */
  225037. + int dma_request1;
  225038. enum sdma_peripheral_type peripheral_type;
  225039. int priority;
  225040. + void *data_addr1, *data_addr2;
  225041. };
  225042. static inline int imx_dma_is_ipu(struct dma_chan *chan)
  225043. @@ -59,6 +62,11 @@
  225044. return !strcmp(dev_name(chan->device->dev), "ipu-core");
  225045. }
  225046. +static inline int imx_dma_is_pxp(struct dma_chan *chan)
  225047. +{
  225048. + return strstr(dev_name(chan->device->dev), "pxp") != NULL;
  225049. +}
  225050. +
  225051. static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
  225052. {
  225053. return !strcmp(chan->device->dev->driver->name, "imx-sdma") ||
  225054. diff -Nur linux-3.14.17/include/linux/power/imx6_usb_charger.h linux-imx6-3.14/include/linux/power/imx6_usb_charger.h
  225055. --- linux-3.14.17/include/linux/power/imx6_usb_charger.h 1970-01-01 01:00:00.000000000 +0100
  225056. +++ linux-imx6-3.14/include/linux/power/imx6_usb_charger.h 2014-09-11 18:06:10.994073881 +0200
  225057. @@ -0,0 +1,80 @@
  225058. +/*
  225059. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
  225060. + *
  225061. + * The code contained herein is licensed under the GNU General Public
  225062. + * License. You may obtain a copy of the GNU General Public License
  225063. + * Version 2 or later at the following locations:
  225064. + *
  225065. + * http://www.opensource.org/licenses/gpl-license.html
  225066. + * http://www.gnu.org/copyleft/gpl.html
  225067. + */
  225068. +
  225069. +#ifndef __IMXUSB6_CHARGER_H
  225070. +#define __IMXUSB6_CHARGER_H
  225071. +
  225072. +#include <linux/power_supply.h>
  225073. +enum battery_charging_spec {
  225074. + BATTERY_CHARGING_SPEC_NONE = 0,
  225075. + BATTERY_CHARGING_SPEC_UNKNOWN,
  225076. + BATTERY_CHARGING_SPEC_1_0,
  225077. + BATTERY_CHARGING_SPEC_1_1,
  225078. + BATTERY_CHARGING_SPEC_1_2,
  225079. +};
  225080. +
  225081. +struct usb_charger {
  225082. + /* The anatop regmap */
  225083. + struct regmap *anatop;
  225084. + /* USB controller */
  225085. + struct device *dev;
  225086. + struct power_supply psy;
  225087. + struct mutex lock;
  225088. +
  225089. + /* Compliant with Battery Charging Specification version (if any) */
  225090. + enum battery_charging_spec bc;
  225091. +
  225092. + /* properties */
  225093. + unsigned present:1;
  225094. + unsigned online:1;
  225095. + unsigned max_current;
  225096. + int (*connect)(struct usb_charger *charger);
  225097. + int (*disconnect)(struct usb_charger *charger);
  225098. + int (*set_power)(struct usb_charger *charger, unsigned mA);
  225099. +
  225100. + int (*detect)(struct usb_charger *charger);
  225101. +};
  225102. +
  225103. +#ifdef CONFIG_IMX6_USB_CHARGER
  225104. +extern void imx6_usb_remove_charger(struct usb_charger *charger);
  225105. +extern int imx6_usb_create_charger(struct usb_charger *charger,
  225106. + const char *name);
  225107. +extern int imx6_usb_vbus_disconnect(struct usb_charger *charger);
  225108. +extern int imx6_usb_vbus_connect(struct usb_charger *charger);
  225109. +extern int imx6_usb_charger_detect_post(struct usb_charger *charger);
  225110. +#else
  225111. +void imx6_usb_remove_charger(struct usb_charger *charger)
  225112. +{
  225113. +
  225114. +}
  225115. +
  225116. +int imx6_usb_create_charger(struct usb_charger *charger,
  225117. + const char *name)
  225118. +{
  225119. + return -ENODEV;
  225120. +}
  225121. +
  225122. +int imx6_usb_vbus_disconnect(struct usb_charger *charger)
  225123. +{
  225124. + return -ENODEV;
  225125. +}
  225126. +
  225127. +int imx6_usb_vbus_connect(struct usb_charger *charger)
  225128. +{
  225129. + return -ENODEV;
  225130. +}
  225131. +int imx6_usb_charger_detect_post(struct usb_charger *charger)
  225132. +{
  225133. + return -ENODEV;
  225134. +}
  225135. +#endif
  225136. +
  225137. +#endif /* __IMXUSB6_CHARGER_H */
  225138. diff -Nur linux-3.14.17/include/linux/printk.h linux-imx6-3.14/include/linux/printk.h
  225139. --- linux-3.14.17/include/linux/printk.h 2014-08-14 03:38:34.000000000 +0200
  225140. +++ linux-imx6-3.14/include/linux/printk.h 2014-09-11 18:06:10.994073881 +0200
  225141. @@ -132,9 +132,9 @@
  225142. int printk(const char *fmt, ...);
  225143. /*
  225144. - * Special printk facility for scheduler/timekeeping use only, _DO_NOT_USE_ !
  225145. + * Special printk facility for scheduler use only, _DO_NOT_USE_ !
  225146. */
  225147. -__printf(1, 2) __cold int printk_deferred(const char *fmt, ...);
  225148. +__printf(1, 2) __cold int printk_sched(const char *fmt, ...);
  225149. /*
  225150. * Please don't use printk_ratelimit(), because it shares ratelimiting state
  225151. @@ -169,7 +169,7 @@
  225152. return 0;
  225153. }
  225154. static inline __printf(1, 2) __cold
  225155. -int printk_deferred(const char *s, ...)
  225156. +int printk_sched(const char *s, ...)
  225157. {
  225158. return 0;
  225159. }
  225160. diff -Nur linux-3.14.17/include/linux/ptp_clock_kernel.h linux-imx6-3.14/include/linux/ptp_clock_kernel.h
  225161. --- linux-3.14.17/include/linux/ptp_clock_kernel.h 2014-08-14 03:38:34.000000000 +0200
  225162. +++ linux-imx6-3.14/include/linux/ptp_clock_kernel.h 2014-09-11 18:06:10.998073898 +0200
  225163. @@ -49,7 +49,11 @@
  225164. * @n_alarm: The number of programmable alarms.
  225165. * @n_ext_ts: The number of external time stamp channels.
  225166. * @n_per_out: The number of programmable periodic signals.
  225167. + * @n_pins: The number of programmable pins.
  225168. * @pps: Indicates whether the clock supports a PPS callback.
  225169. + * @pin_config: Array of length 'n_pins'. If the number of
  225170. + * programmable pins is nonzero, then drivers must
  225171. + * allocate and initialize this array.
  225172. *
  225173. * clock operations
  225174. *
  225175. @@ -70,6 +74,18 @@
  225176. * parameter request: Desired resource to enable or disable.
  225177. * parameter on: Caller passes one to enable or zero to disable.
  225178. *
  225179. + * @verify: Confirm that a pin can perform a given function. The PTP
  225180. + * Hardware Clock subsystem maintains the 'pin_config'
  225181. + * array on behalf of the drivers, but the PHC subsystem
  225182. + * assumes that every pin can perform every function. This
  225183. + * hook gives drivers a way of telling the core about
  225184. + * limitations on specific pins. This function must return
  225185. + * zero if the function can be assigned to this pin, and
  225186. + * nonzero otherwise.
  225187. + * parameter pin: index of the pin in question.
  225188. + * parameter func: the desired function to use.
  225189. + * parameter chan: the function channel index to use.
  225190. + *
  225191. * Drivers should embed their ptp_clock_info within a private
  225192. * structure, obtaining a reference to it using container_of().
  225193. *
  225194. @@ -83,13 +99,17 @@
  225195. int n_alarm;
  225196. int n_ext_ts;
  225197. int n_per_out;
  225198. + int n_pins;
  225199. int pps;
  225200. + struct ptp_pin_desc *pin_config;
  225201. int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
  225202. int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
  225203. int (*gettime)(struct ptp_clock_info *ptp, struct timespec *ts);
  225204. int (*settime)(struct ptp_clock_info *ptp, const struct timespec *ts);
  225205. int (*enable)(struct ptp_clock_info *ptp,
  225206. struct ptp_clock_request *request, int on);
  225207. + int (*verify)(struct ptp_clock_info *ptp, unsigned int pin,
  225208. + enum ptp_pin_function func, unsigned int chan);
  225209. };
  225210. struct ptp_clock;
  225211. @@ -156,4 +176,17 @@
  225212. extern int ptp_clock_index(struct ptp_clock *ptp);
  225213. +/**
  225214. + * ptp_find_pin() - obtain the pin index of a given auxiliary function
  225215. + *
  225216. + * @ptp: The clock obtained from ptp_clock_register().
  225217. + * @func: One of the ptp_pin_function enumerated values.
  225218. + * @chan: The particular functional channel to find.
  225219. + * Return: Pin index in the range of zero to ptp_clock_caps.n_pins - 1,
  225220. + * or -1 if the auxiliary function cannot be found.
  225221. + */
  225222. +
  225223. +int ptp_find_pin(struct ptp_clock *ptp,
  225224. + enum ptp_pin_function func, unsigned int chan);
  225225. +
  225226. #endif
  225227. diff -Nur linux-3.14.17/include/linux/pxp_device.h linux-imx6-3.14/include/linux/pxp_device.h
  225228. --- linux-3.14.17/include/linux/pxp_device.h 1970-01-01 01:00:00.000000000 +0100
  225229. +++ linux-imx6-3.14/include/linux/pxp_device.h 2014-09-11 18:06:10.998073898 +0200
  225230. @@ -0,0 +1,68 @@
  225231. +/*
  225232. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  225233. + *
  225234. + * This program is free software; you can redistribute it and/or modify
  225235. + * it under the terms of the GNU General Public License as published by
  225236. + * the Free Software Foundation; either version 2 of the License, or
  225237. + * (at your option) any later version.
  225238. + *
  225239. + * This program is distributed in the hope that it will be useful,
  225240. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  225241. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  225242. + * GNU General Public License for more details.
  225243. + *
  225244. + * You should have received a copy of the GNU General Public License
  225245. + * along with this program; if not, write to the Free Software
  225246. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  225247. + *
  225248. + */
  225249. +#ifndef _PXP_DEVICE
  225250. +#define _PXP_DEVICE
  225251. +
  225252. +#include <linux/idr.h>
  225253. +#include <linux/hash.h>
  225254. +#include <uapi/linux/pxp_device.h>
  225255. +
  225256. +struct pxp_irq_info {
  225257. + wait_queue_head_t waitq;
  225258. + atomic_t irq_pending;
  225259. + int hist_status;
  225260. +};
  225261. +
  225262. +struct pxp_buffer_hash {
  225263. + struct hlist_head *hash_table;
  225264. + u32 order;
  225265. + spinlock_t hash_lock;
  225266. +};
  225267. +
  225268. +struct pxp_buf_obj {
  225269. + uint32_t handle;
  225270. +
  225271. + uint32_t size;
  225272. + uint32_t mem_type;
  225273. +
  225274. + unsigned long offset;
  225275. + void *virtual;
  225276. +
  225277. + struct hlist_node item;
  225278. +};
  225279. +
  225280. +struct pxp_chan_obj {
  225281. + uint32_t handle;
  225282. + struct dma_chan *chan;
  225283. +};
  225284. +
  225285. +/* File private data */
  225286. +struct pxp_file {
  225287. + struct file *filp;
  225288. +
  225289. + /* record allocated dma buffer */
  225290. + struct idr buffer_idr;
  225291. + spinlock_t buffer_lock;
  225292. +
  225293. + /* record allocated dma channel */
  225294. + struct idr channel_idr;
  225295. + spinlock_t channel_lock;
  225296. +};
  225297. +
  225298. +#endif
  225299. diff -Nur linux-3.14.17/include/linux/pxp_dma.h linux-imx6-3.14/include/linux/pxp_dma.h
  225300. --- linux-3.14.17/include/linux/pxp_dma.h 1970-01-01 01:00:00.000000000 +0100
  225301. +++ linux-imx6-3.14/include/linux/pxp_dma.h 2014-09-11 18:06:10.998073898 +0200
  225302. @@ -0,0 +1,72 @@
  225303. +/*
  225304. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  225305. + *
  225306. + * This program is free software; you can redistribute it and/or modify
  225307. + * it under the terms of the GNU General Public License as published by
  225308. + * the Free Software Foundation; either version 2 of the License, or
  225309. + * (at your option) any later version.
  225310. + *
  225311. + * This program is distributed in the hope that it will be useful,
  225312. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  225313. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  225314. + * GNU General Public License for more details.
  225315. + *
  225316. + * You should have received a copy of the GNU General Public License
  225317. + * along with this program; if not, write to the Free Software
  225318. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  225319. + *
  225320. + */
  225321. +#ifndef _PXP_DMA
  225322. +#define _PXP_DMA
  225323. +
  225324. +#include <uapi/linux/pxp_dma.h>
  225325. +
  225326. +struct pxp_tx_desc {
  225327. + struct dma_async_tx_descriptor txd;
  225328. + struct list_head tx_list;
  225329. + struct list_head list;
  225330. + int len;
  225331. + union {
  225332. + struct pxp_layer_param s0_param;
  225333. + struct pxp_layer_param out_param;
  225334. + struct pxp_layer_param ol_param;
  225335. + } layer_param;
  225336. + struct pxp_proc_data proc_data;
  225337. +
  225338. + u32 hist_status; /* Histogram output status */
  225339. +
  225340. + struct pxp_tx_desc *next;
  225341. +};
  225342. +
  225343. +struct pxp_channel {
  225344. + struct dma_chan dma_chan;
  225345. + dma_cookie_t completed; /* last completed cookie */
  225346. + enum pxp_channel_status status;
  225347. + void *client; /* Only one client per channel */
  225348. + unsigned int n_tx_desc;
  225349. + struct pxp_tx_desc *desc; /* allocated tx-descriptors */
  225350. + struct list_head queue; /* queued tx-descriptors */
  225351. + struct list_head list; /* track queued channel number */
  225352. + spinlock_t lock; /* protects sg[0,1], queue,
  225353. + * status, cookie, free_list
  225354. + */
  225355. + int active_buffer;
  225356. + unsigned int eof_irq;
  225357. + char eof_name[16]; /* EOF IRQ name for request_irq() */
  225358. +};
  225359. +
  225360. +#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
  225361. +#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
  225362. +
  225363. +void pxp_txd_ack(struct dma_async_tx_descriptor *txd,
  225364. + struct pxp_channel *pxp_chan);
  225365. +
  225366. +#ifdef CONFIG_MXC_PXP_CLIENT_DEVICE
  225367. +int register_pxp_device(void);
  225368. +void unregister_pxp_device(void);
  225369. +#else
  225370. +int register_pxp_device(void) { return 0; }
  225371. +void unregister_pxp_device(void) {}
  225372. +#endif
  225373. +
  225374. +#endif
  225375. diff -Nur linux-3.14.17/include/linux/regulator/consumer.h linux-imx6-3.14/include/linux/regulator/consumer.h
  225376. --- linux-3.14.17/include/linux/regulator/consumer.h 2014-08-14 03:38:34.000000000 +0200
  225377. +++ linux-imx6-3.14/include/linux/regulator/consumer.h 2014-09-11 18:06:11.002073913 +0200
  225378. @@ -2,6 +2,7 @@
  225379. * consumer.h -- SoC Regulator consumer support.
  225380. *
  225381. * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
  225382. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  225383. *
  225384. * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  225385. *
  225386. @@ -105,6 +106,8 @@
  225387. #define REGULATOR_EVENT_FORCE_DISABLE 0x20
  225388. #define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
  225389. #define REGULATOR_EVENT_DISABLE 0x80
  225390. +#define REGULATOR_EVENT_PRE_DISABLE 0x100
  225391. +#define REGULATOR_EVENT_ENABLE 0x200
  225392. struct regulator;
  225393. diff -Nur linux-3.14.17/include/linux/reset.h linux-imx6-3.14/include/linux/reset.h
  225394. --- linux-3.14.17/include/linux/reset.h 2014-08-14 03:38:34.000000000 +0200
  225395. +++ linux-imx6-3.14/include/linux/reset.h 2014-09-11 18:06:11.002073913 +0200
  225396. @@ -12,6 +12,13 @@
  225397. void reset_control_put(struct reset_control *rstc);
  225398. struct reset_control *devm_reset_control_get(struct device *dev, const char *id);
  225399. +#ifdef CONFIG_RESET_CONTROLLER
  225400. int device_reset(struct device *dev);
  225401. +#else
  225402. +static inline int device_reset(struct device *dev)
  225403. +{
  225404. + return 0;
  225405. +}
  225406. +#endif /* CONFIG_RESET_CONTROLLER */
  225407. #endif
  225408. diff -Nur linux-3.14.17/include/linux/serial_core.h linux-imx6-3.14/include/linux/serial_core.h
  225409. --- linux-3.14.17/include/linux/serial_core.h 2014-08-14 03:38:34.000000000 +0200
  225410. +++ linux-imx6-3.14/include/linux/serial_core.h 2014-09-11 18:06:11.010073945 +0200
  225411. @@ -285,6 +285,22 @@
  225412. /*
  225413. * Console helpers.
  225414. */
  225415. +struct earlycon_device {
  225416. + struct console *con;
  225417. + struct uart_port port;
  225418. + char options[16]; /* e.g., 115200n8 */
  225419. + unsigned int baud;
  225420. +};
  225421. +int setup_earlycon(char *buf, const char *match,
  225422. + int (*setup)(struct earlycon_device *, const char *));
  225423. +
  225424. +#define EARLYCON_DECLARE(name, func) \
  225425. +static int __init name ## _setup_earlycon(char *buf) \
  225426. +{ \
  225427. + return setup_earlycon(buf, __stringify(name), func); \
  225428. +} \
  225429. +early_param("earlycon", name ## _setup_earlycon);
  225430. +
  225431. struct uart_port *uart_get_console(struct uart_port *ports, int nr,
  225432. struct console *c);
  225433. void uart_parse_options(char *options, int *baud, int *parity, int *bits,
  225434. diff -Nur linux-3.14.17/include/linux/skbuff.h linux-imx6-3.14/include/linux/skbuff.h
  225435. --- linux-3.14.17/include/linux/skbuff.h 2014-08-14 03:38:34.000000000 +0200
  225436. +++ linux-imx6-3.14/include/linux/skbuff.h 2014-09-11 18:06:11.010073945 +0200
  225437. @@ -2038,7 +2038,7 @@
  225438. }
  225439. /**
  225440. - * skb_frag_page - retrieve the page refered to by a paged fragment
  225441. + * skb_frag_page - retrieve the page referred to by a paged fragment
  225442. * @frag: the paged fragment
  225443. *
  225444. * Returns the &struct page associated with @frag.
  225445. diff -Nur linux-3.14.17/include/linux/spi/spi.h linux-imx6-3.14/include/linux/spi/spi.h
  225446. --- linux-3.14.17/include/linux/spi/spi.h 2014-08-14 03:38:34.000000000 +0200
  225447. +++ linux-imx6-3.14/include/linux/spi/spi.h 2014-09-11 18:06:11.014073961 +0200
  225448. @@ -234,7 +234,7 @@
  225449. * @mode_bits: flags understood by this controller driver
  225450. * @bits_per_word_mask: A mask indicating which values of bits_per_word are
  225451. * supported by the driver. Bit n indicates that a bits_per_word n+1 is
  225452. - * suported. If set, the SPI core will reject any transfer with an
  225453. + * supported. If set, the SPI core will reject any transfer with an
  225454. * unsupported bits_per_word. If not set, this value is simply ignored,
  225455. * and it's up to the individual driver to perform any validation.
  225456. * @min_speed_hz: Lowest supported transfer speed
  225457. @@ -259,7 +259,7 @@
  225458. * @cur_msg: the currently in-flight message
  225459. * @cur_msg_prepared: spi_prepare_message was called for the currently
  225460. * in-flight message
  225461. - * @xfer_completion: used by core tranfer_one_message()
  225462. + * @xfer_completion: used by core transfer_one_message()
  225463. * @busy: message pump is busy
  225464. * @running: message pump is running
  225465. * @rt: whether this queue is set to run as a realtime task
  225466. @@ -498,7 +498,7 @@
  225467. * @rx_buf: data to be read (dma-safe memory), or NULL
  225468. * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
  225469. * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped
  225470. - * @tx_nbits: number of bits used for writting. If 0 the default
  225471. + * @tx_nbits: number of bits used for writing. If 0 the default
  225472. * (SPI_NBITS_SINGLE) is used.
  225473. * @rx_nbits: number of bits used for reading. If 0 the default
  225474. * (SPI_NBITS_SINGLE) is used.
  225475. @@ -556,7 +556,7 @@
  225476. * by the results of previous messages and where the whole transaction
  225477. * ends when the chipselect goes intactive.
  225478. *
  225479. - * When SPI can transfer in 1x,2x or 4x. It can get this tranfer information
  225480. + * When SPI can transfer in 1x,2x or 4x. It can get this transfer information
  225481. * from device through @tx_nbits and @rx_nbits. In Bi-direction, these
  225482. * two should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x)
  225483. * SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer.
  225484. diff -Nur linux-3.14.17/include/linux/syscalls.h linux-imx6-3.14/include/linux/syscalls.h
  225485. --- linux-3.14.17/include/linux/syscalls.h 2014-08-14 03:38:34.000000000 +0200
  225486. +++ linux-imx6-3.14/include/linux/syscalls.h 2014-09-11 18:06:11.022073994 +0200
  225487. @@ -744,6 +744,9 @@
  225488. int newdfd, const char __user *newname, int flags);
  225489. asmlinkage long sys_renameat(int olddfd, const char __user * oldname,
  225490. int newdfd, const char __user * newname);
  225491. +asmlinkage long sys_renameat2(int olddfd, const char __user *oldname,
  225492. + int newdfd, const char __user *newname,
  225493. + unsigned int flags);
  225494. asmlinkage long sys_futimesat(int dfd, const char __user *filename,
  225495. struct timeval __user *utimes);
  225496. asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
  225497. diff -Nur linux-3.14.17/include/linux/usb/chipidea.h linux-imx6-3.14/include/linux/usb/chipidea.h
  225498. --- linux-3.14.17/include/linux/usb/chipidea.h 2014-08-14 03:38:34.000000000 +0200
  225499. +++ linux-imx6-3.14/include/linux/usb/chipidea.h 2014-09-11 18:06:11.030074024 +0200
  225500. @@ -18,6 +18,7 @@
  225501. unsigned long flags;
  225502. #define CI_HDRC_REGS_SHARED BIT(0)
  225503. #define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1)
  225504. +#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2)
  225505. #define CI_HDRC_DISABLE_STREAMING BIT(3)
  225506. /*
  225507. * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
  225508. @@ -25,6 +26,7 @@
  225509. */
  225510. #define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4)
  225511. #define CI_HDRC_IMX28_WRITE_FIX BIT(5)
  225512. +#define CI_HDRC_IMX_EHCI_QUIRK BIT(6)
  225513. enum usb_dr_mode dr_mode;
  225514. #define CI_HDRC_CONTROLLER_RESET_EVENT 0
  225515. #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
  225516. @@ -42,4 +44,6 @@
  225517. /* Remove ci hdrc device */
  225518. void ci_hdrc_remove_device(struct platform_device *pdev);
  225519. +/* Get current available role */
  225520. +enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev);
  225521. #endif
  225522. diff -Nur linux-3.14.17/include/linux/usb/composite.h linux-imx6-3.14/include/linux/usb/composite.h
  225523. --- linux-3.14.17/include/linux/usb/composite.h 2014-08-14 03:38:34.000000000 +0200
  225524. +++ linux-imx6-3.14/include/linux/usb/composite.h 2014-09-11 18:06:11.034074040 +0200
  225525. @@ -92,7 +92,7 @@
  225526. * @suspend: Notifies functions when the host stops sending USB traffic.
  225527. * @resume: Notifies functions when the host restarts USB traffic.
  225528. * @get_status: Returns function status as a reply to
  225529. - * GetStatus() request when the recepient is Interface.
  225530. + * GetStatus() request when the recipient is Interface.
  225531. * @func_suspend: callback to be called when
  225532. * SetFeature(FUNCTION_SUSPEND) is reseived
  225533. *
  225534. diff -Nur linux-3.14.17/include/linux/usb/phy.h linux-imx6-3.14/include/linux/usb/phy.h
  225535. --- linux-3.14.17/include/linux/usb/phy.h 2014-08-14 03:38:34.000000000 +0200
  225536. +++ linux-imx6-3.14/include/linux/usb/phy.h 2014-09-11 18:06:11.034074040 +0200
  225537. @@ -111,11 +111,23 @@
  225538. int (*set_suspend)(struct usb_phy *x,
  225539. int suspend);
  225540. + /*
  225541. + * Set wakeup enable for PHY, in that case, the PHY can be
  225542. + * waken up from suspend status due to external events,
  225543. + * like vbus change, dp/dm change and id.
  225544. + */
  225545. + int (*set_wakeup)(struct usb_phy *x, bool enabled);
  225546. +
  225547. /* notify phy connect status change */
  225548. int (*notify_connect)(struct usb_phy *x,
  225549. enum usb_device_speed speed);
  225550. int (*notify_disconnect)(struct usb_phy *x,
  225551. enum usb_device_speed speed);
  225552. + int (*notify_suspend)(struct usb_phy *x,
  225553. + enum usb_device_speed speed);
  225554. + int (*notify_resume)(struct usb_phy *x,
  225555. + enum usb_device_speed speed);
  225556. +
  225557. };
  225558. /**
  225559. @@ -265,6 +277,15 @@
  225560. }
  225561. static inline int
  225562. +usb_phy_set_wakeup(struct usb_phy *x, bool enabled)
  225563. +{
  225564. + if (x && x->set_wakeup)
  225565. + return x->set_wakeup(x, enabled);
  225566. + else
  225567. + return 0;
  225568. +}
  225569. +
  225570. +static inline int
  225571. usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed)
  225572. {
  225573. if (x && x->notify_connect)
  225574. @@ -281,6 +302,24 @@
  225575. else
  225576. return 0;
  225577. }
  225578. +
  225579. +static inline int usb_phy_notify_suspend
  225580. + (struct usb_phy *x, enum usb_device_speed speed)
  225581. +{
  225582. + if (x && x->notify_suspend)
  225583. + return x->notify_suspend(x, speed);
  225584. + else
  225585. + return 0;
  225586. +}
  225587. +
  225588. +static inline int usb_phy_notify_resume
  225589. + (struct usb_phy *x, enum usb_device_speed speed)
  225590. +{
  225591. + if (x && x->notify_resume)
  225592. + return x->notify_resume(x, speed);
  225593. + else
  225594. + return 0;
  225595. +}
  225596. /* notifiers */
  225597. static inline int
  225598. diff -Nur linux-3.14.17/include/net/cfg80211.h linux-imx6-3.14/include/net/cfg80211.h
  225599. --- linux-3.14.17/include/net/cfg80211.h 2014-08-14 03:38:34.000000000 +0200
  225600. +++ linux-imx6-3.14/include/net/cfg80211.h 2014-09-11 18:06:14.058086106 +0200
  225601. @@ -1729,7 +1729,7 @@
  225602. u8 *ssid;
  225603. size_t ssid_len;
  225604. enum nl80211_auth_type auth_type;
  225605. - u8 *ie;
  225606. + const u8 *ie;
  225607. size_t ie_len;
  225608. bool privacy;
  225609. enum nl80211_mfp mfp;
  225610. @@ -3888,6 +3888,7 @@
  225611. *
  225612. * @dev: network device
  225613. * @bssid: the BSSID of the IBSS joined
  225614. + * @channel: the channel of the IBSS joined
  225615. * @gfp: allocation flags
  225616. *
  225617. * This function notifies cfg80211 that the device joined an IBSS or
  225618. @@ -3897,7 +3898,8 @@
  225619. * with the locally generated beacon -- this guarantees that there is
  225620. * always a scan result for this IBSS. cfg80211 will handle the rest.
  225621. */
  225622. -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
  225623. +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  225624. + struct ieee80211_channel *channel, gfp_t gfp);
  225625. /**
  225626. * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
  225627. diff -Nur linux-3.14.17/include/net/inetpeer.h linux-imx6-3.14/include/net/inetpeer.h
  225628. --- linux-3.14.17/include/net/inetpeer.h 2014-08-14 03:38:34.000000000 +0200
  225629. +++ linux-imx6-3.14/include/net/inetpeer.h 2014-09-11 18:06:14.066086140 +0200
  225630. @@ -41,13 +41,14 @@
  225631. struct rcu_head gc_rcu;
  225632. };
  225633. /*
  225634. - * Once inet_peer is queued for deletion (refcnt == -1), following field
  225635. - * is not available: rid
  225636. + * Once inet_peer is queued for deletion (refcnt == -1), following fields
  225637. + * are not available: rid, ip_id_count
  225638. * We can share memory with rcu_head to help keep inet_peer small.
  225639. */
  225640. union {
  225641. struct {
  225642. atomic_t rid; /* Frag reception counter */
  225643. + atomic_t ip_id_count; /* IP ID for the next packet */
  225644. };
  225645. struct rcu_head rcu;
  225646. struct inet_peer *gc_next;
  225647. @@ -164,7 +165,7 @@
  225648. void inetpeer_invalidate_tree(struct inet_peer_base *);
  225649. /*
  225650. - * temporary check to make sure we dont access rid, tcp_ts,
  225651. + * temporary check to make sure we dont access rid, ip_id_count, tcp_ts,
  225652. * tcp_ts_stamp if no refcount is taken on inet_peer
  225653. */
  225654. static inline void inet_peer_refcheck(const struct inet_peer *p)
  225655. @@ -172,4 +173,13 @@
  225656. WARN_ON_ONCE(atomic_read(&p->refcnt) <= 0);
  225657. }
  225658. +
  225659. +/* can be called with or without local BH being disabled */
  225660. +static inline int inet_getid(struct inet_peer *p, int more)
  225661. +{
  225662. + more++;
  225663. + inet_peer_refcheck(p);
  225664. + return atomic_add_return(more, &p->ip_id_count) - more;
  225665. +}
  225666. +
  225667. #endif /* _NET_INETPEER_H */
  225668. diff -Nur linux-3.14.17/include/net/ip.h linux-imx6-3.14/include/net/ip.h
  225669. --- linux-3.14.17/include/net/ip.h 2014-08-14 03:38:34.000000000 +0200
  225670. +++ linux-imx6-3.14/include/net/ip.h 2014-09-11 18:06:14.066086140 +0200
  225671. @@ -297,10 +297,9 @@
  225672. }
  225673. }
  225674. -u32 ip_idents_reserve(u32 hash, int segs);
  225675. -void __ip_select_ident(struct iphdr *iph, int segs);
  225676. +void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);
  225677. -static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, int segs)
  225678. +static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk)
  225679. {
  225680. struct iphdr *iph = ip_hdr(skb);
  225681. @@ -310,20 +309,24 @@
  225682. * does not change, they drop every other packet in
  225683. * a TCP stream using header compression.
  225684. */
  225685. - if (sk && inet_sk(sk)->inet_daddr) {
  225686. - iph->id = htons(inet_sk(sk)->inet_id);
  225687. - inet_sk(sk)->inet_id += segs;
  225688. - } else {
  225689. - iph->id = 0;
  225690. - }
  225691. - } else {
  225692. - __ip_select_ident(iph, segs);
  225693. - }
  225694. + iph->id = (sk && inet_sk(sk)->inet_daddr) ?
  225695. + htons(inet_sk(sk)->inet_id++) : 0;
  225696. + } else
  225697. + __ip_select_ident(iph, dst, 0);
  225698. }
  225699. -static inline void ip_select_ident(struct sk_buff *skb, struct sock *sk)
  225700. +static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more)
  225701. {
  225702. - ip_select_ident_segs(skb, sk, 1);
  225703. + struct iphdr *iph = ip_hdr(skb);
  225704. +
  225705. + if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) {
  225706. + if (sk && inet_sk(sk)->inet_daddr) {
  225707. + iph->id = htons(inet_sk(sk)->inet_id);
  225708. + inet_sk(sk)->inet_id += 1 + more;
  225709. + } else
  225710. + iph->id = 0;
  225711. + } else
  225712. + __ip_select_ident(iph, dst, more);
  225713. }
  225714. /*
  225715. diff -Nur linux-3.14.17/include/net/ip_tunnels.h linux-imx6-3.14/include/net/ip_tunnels.h
  225716. --- linux-3.14.17/include/net/ip_tunnels.h 2014-08-14 03:38:34.000000000 +0200
  225717. +++ linux-imx6-3.14/include/net/ip_tunnels.h 2014-09-11 18:06:14.066086140 +0200
  225718. @@ -40,7 +40,6 @@
  225719. struct ip_tunnel_dst {
  225720. struct dst_entry __rcu *dst;
  225721. - __be32 saddr;
  225722. };
  225723. struct ip_tunnel {
  225724. diff -Nur linux-3.14.17/include/net/ipv6.h linux-imx6-3.14/include/net/ipv6.h
  225725. --- linux-3.14.17/include/net/ipv6.h 2014-08-14 03:38:34.000000000 +0200
  225726. +++ linux-imx6-3.14/include/net/ipv6.h 2014-09-11 18:06:14.066086140 +0200
  225727. @@ -660,6 +660,8 @@
  225728. return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
  225729. }
  225730. +void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);
  225731. +
  225732. int ip6_dst_hoplimit(struct dst_entry *dst);
  225733. /*
  225734. diff -Nur linux-3.14.17/include/net/mac80211.h linux-imx6-3.14/include/net/mac80211.h
  225735. --- linux-3.14.17/include/net/mac80211.h 2014-08-14 03:38:34.000000000 +0200
  225736. +++ linux-imx6-3.14/include/net/mac80211.h 2014-09-11 18:06:14.082086204 +0200
  225737. @@ -1895,7 +1895,7 @@
  225738. *
  225739. * Driver informs U-APSD client support by enabling
  225740. * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the
  225741. - * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS
  225742. + * uapsd parameter in conf_tx() operation. Hardware needs to send the QoS
  225743. * Nullfunc frames and stay awake until the service period has ended. To
  225744. * utilize U-APSD, dynamic powersave is disabled for voip AC and all frames
  225745. * from that AC are transmitted with powersave enabled.
  225746. @@ -2101,7 +2101,7 @@
  225747. * with the number of frames to be released and which TIDs they are
  225748. * to come from. In this case, the driver is responsible for setting
  225749. * the EOSP (for uAPSD) and MORE_DATA bits in the released frames,
  225750. - * to help the @more_data paramter is passed to tell the driver if
  225751. + * to help the @more_data parameter is passed to tell the driver if
  225752. * there is more data on other TIDs -- the TIDs to release frames
  225753. * from are ignored since mac80211 doesn't know how many frames the
  225754. * buffers for those TIDs contain.
  225755. @@ -2616,6 +2616,7 @@
  225756. * of queues to flush, which is useful if different virtual interfaces
  225757. * use different hardware queues; it may also indicate all queues.
  225758. * If the parameter @drop is set to %true, pending frames may be dropped.
  225759. + * Note that vif can be NULL.
  225760. * The callback can sleep.
  225761. *
  225762. * @channel_switch: Drivers that need (or want) to offload the channel
  225763. @@ -2662,7 +2663,7 @@
  225764. * parameters. In the case where the driver buffers some frames for
  225765. * sleeping stations mac80211 will use this callback to tell the driver
  225766. * to release some frames, either for PS-poll or uAPSD.
  225767. - * Note that if the @more_data paramter is %false the driver must check
  225768. + * Note that if the @more_data parameter is %false the driver must check
  225769. * if there are more frames on the given TIDs, and if there are more than
  225770. * the frames being released then it must still set the more-data bit in
  225771. * the frame. If the @more_data parameter is %true, then of course the
  225772. @@ -2878,7 +2879,8 @@
  225773. struct netlink_callback *cb,
  225774. void *data, int len);
  225775. #endif
  225776. - void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop);
  225777. + void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  225778. + u32 queues, bool drop);
  225779. void (*channel_switch)(struct ieee80211_hw *hw,
  225780. struct ieee80211_channel_switch *ch_switch);
  225781. int (*napi_poll)(struct ieee80211_hw *hw, int budget);
  225782. diff -Nur linux-3.14.17/include/net/rtnetlink.h linux-imx6-3.14/include/net/rtnetlink.h
  225783. --- linux-3.14.17/include/net/rtnetlink.h 2014-08-14 03:38:34.000000000 +0200
  225784. +++ linux-imx6-3.14/include/net/rtnetlink.h 2014-09-11 18:06:14.118086347 +0200
  225785. @@ -140,7 +140,7 @@
  225786. struct nlattr *tb[]);
  225787. int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm);
  225788. -extern const struct nla_policy ifla_policy[IFLA_MAX+1];
  225789. +int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len);
  225790. #define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
  225791. diff -Nur linux-3.14.17/include/net/secure_seq.h linux-imx6-3.14/include/net/secure_seq.h
  225792. --- linux-3.14.17/include/net/secure_seq.h 2014-08-14 03:38:34.000000000 +0200
  225793. +++ linux-imx6-3.14/include/net/secure_seq.h 2014-09-11 18:06:14.142086442 +0200
  225794. @@ -3,6 +3,8 @@
  225795. #include <linux/types.h>
  225796. +__u32 secure_ip_id(__be32 daddr);
  225797. +__u32 secure_ipv6_id(const __be32 daddr[4]);
  225798. u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
  225799. u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
  225800. __be16 dport);
  225801. diff -Nur linux-3.14.17/include/net/tso.h linux-imx6-3.14/include/net/tso.h
  225802. --- linux-3.14.17/include/net/tso.h 1970-01-01 01:00:00.000000000 +0100
  225803. +++ linux-imx6-3.14/include/net/tso.h 2014-09-11 18:06:14.142086442 +0200
  225804. @@ -0,0 +1,20 @@
  225805. +#ifndef _TSO_H
  225806. +#define _TSO_H
  225807. +
  225808. +#include <net/ip.h>
  225809. +
  225810. +struct tso_t {
  225811. + int next_frag_idx;
  225812. + void *data;
  225813. + size_t size;
  225814. + u16 ip_id;
  225815. + u32 tcp_seq;
  225816. +};
  225817. +
  225818. +int tso_count_descs(struct sk_buff *skb);
  225819. +void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
  225820. + int size, bool is_last);
  225821. +void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size);
  225822. +void tso_start(struct sk_buff *skb, struct tso_t *tso);
  225823. +
  225824. +#endif /* _TSO_H */
  225825. diff -Nur linux-3.14.17/include/sound/wm8962.h linux-imx6-3.14/include/sound/wm8962.h
  225826. --- linux-3.14.17/include/sound/wm8962.h 2014-08-14 03:38:34.000000000 +0200
  225827. +++ linux-imx6-3.14/include/sound/wm8962.h 2014-09-11 18:06:14.210086714 +0200
  225828. @@ -55,6 +55,9 @@
  225829. * in a DC measurement configuration.
  225830. */
  225831. bool in4_dc_measure;
  225832. +
  225833. + /* MCLK for wm8962 */
  225834. + struct clk *codec_mclk;
  225835. };
  225836. #endif
  225837. diff -Nur linux-3.14.17/include/trace/events/cpufreq_interactive.h linux-imx6-3.14/include/trace/events/cpufreq_interactive.h
  225838. --- linux-3.14.17/include/trace/events/cpufreq_interactive.h 1970-01-01 01:00:00.000000000 +0100
  225839. +++ linux-imx6-3.14/include/trace/events/cpufreq_interactive.h 2014-09-11 18:06:14.210086714 +0200
  225840. @@ -0,0 +1,112 @@
  225841. +#undef TRACE_SYSTEM
  225842. +#define TRACE_SYSTEM cpufreq_interactive
  225843. +
  225844. +#if !defined(_TRACE_CPUFREQ_INTERACTIVE_H) || defined(TRACE_HEADER_MULTI_READ)
  225845. +#define _TRACE_CPUFREQ_INTERACTIVE_H
  225846. +
  225847. +#include <linux/tracepoint.h>
  225848. +
  225849. +DECLARE_EVENT_CLASS(set,
  225850. + TP_PROTO(u32 cpu_id, unsigned long targfreq,
  225851. + unsigned long actualfreq),
  225852. + TP_ARGS(cpu_id, targfreq, actualfreq),
  225853. +
  225854. + TP_STRUCT__entry(
  225855. + __field( u32, cpu_id )
  225856. + __field(unsigned long, targfreq )
  225857. + __field(unsigned long, actualfreq )
  225858. + ),
  225859. +
  225860. + TP_fast_assign(
  225861. + __entry->cpu_id = (u32) cpu_id;
  225862. + __entry->targfreq = targfreq;
  225863. + __entry->actualfreq = actualfreq;
  225864. + ),
  225865. +
  225866. + TP_printk("cpu=%u targ=%lu actual=%lu",
  225867. + __entry->cpu_id, __entry->targfreq,
  225868. + __entry->actualfreq)
  225869. +);
  225870. +
  225871. +DEFINE_EVENT(set, cpufreq_interactive_setspeed,
  225872. + TP_PROTO(u32 cpu_id, unsigned long targfreq,
  225873. + unsigned long actualfreq),
  225874. + TP_ARGS(cpu_id, targfreq, actualfreq)
  225875. +);
  225876. +
  225877. +DECLARE_EVENT_CLASS(loadeval,
  225878. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  225879. + unsigned long curtarg, unsigned long curactual,
  225880. + unsigned long newtarg),
  225881. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg),
  225882. +
  225883. + TP_STRUCT__entry(
  225884. + __field(unsigned long, cpu_id )
  225885. + __field(unsigned long, load )
  225886. + __field(unsigned long, curtarg )
  225887. + __field(unsigned long, curactual )
  225888. + __field(unsigned long, newtarg )
  225889. + ),
  225890. +
  225891. + TP_fast_assign(
  225892. + __entry->cpu_id = cpu_id;
  225893. + __entry->load = load;
  225894. + __entry->curtarg = curtarg;
  225895. + __entry->curactual = curactual;
  225896. + __entry->newtarg = newtarg;
  225897. + ),
  225898. +
  225899. + TP_printk("cpu=%lu load=%lu cur=%lu actual=%lu targ=%lu",
  225900. + __entry->cpu_id, __entry->load, __entry->curtarg,
  225901. + __entry->curactual, __entry->newtarg)
  225902. +);
  225903. +
  225904. +DEFINE_EVENT(loadeval, cpufreq_interactive_target,
  225905. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  225906. + unsigned long curtarg, unsigned long curactual,
  225907. + unsigned long newtarg),
  225908. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  225909. +);
  225910. +
  225911. +DEFINE_EVENT(loadeval, cpufreq_interactive_already,
  225912. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  225913. + unsigned long curtarg, unsigned long curactual,
  225914. + unsigned long newtarg),
  225915. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  225916. +);
  225917. +
  225918. +DEFINE_EVENT(loadeval, cpufreq_interactive_notyet,
  225919. + TP_PROTO(unsigned long cpu_id, unsigned long load,
  225920. + unsigned long curtarg, unsigned long curactual,
  225921. + unsigned long newtarg),
  225922. + TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
  225923. +);
  225924. +
  225925. +TRACE_EVENT(cpufreq_interactive_boost,
  225926. + TP_PROTO(const char *s),
  225927. + TP_ARGS(s),
  225928. + TP_STRUCT__entry(
  225929. + __string(s, s)
  225930. + ),
  225931. + TP_fast_assign(
  225932. + __assign_str(s, s);
  225933. + ),
  225934. + TP_printk("%s", __get_str(s))
  225935. +);
  225936. +
  225937. +TRACE_EVENT(cpufreq_interactive_unboost,
  225938. + TP_PROTO(const char *s),
  225939. + TP_ARGS(s),
  225940. + TP_STRUCT__entry(
  225941. + __string(s, s)
  225942. + ),
  225943. + TP_fast_assign(
  225944. + __assign_str(s, s);
  225945. + ),
  225946. + TP_printk("%s", __get_str(s))
  225947. +);
  225948. +
  225949. +#endif /* _TRACE_CPUFREQ_INTERACTIVE_H */
  225950. +
  225951. +/* This part must be outside protection */
  225952. +#include <trace/define_trace.h>
  225953. diff -Nur linux-3.14.17/include/uapi/linux/ipu.h linux-imx6-3.14/include/uapi/linux/ipu.h
  225954. --- linux-3.14.17/include/uapi/linux/ipu.h 1970-01-01 01:00:00.000000000 +0100
  225955. +++ linux-imx6-3.14/include/uapi/linux/ipu.h 2014-09-11 18:06:14.378087384 +0200
  225956. @@ -0,0 +1,282 @@
  225957. +/*
  225958. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  225959. + */
  225960. +
  225961. +/*
  225962. + * This program is free software; you can redistribute it and/or modify
  225963. + * it under the terms of the GNU General Public License as published by
  225964. + * the Free Software Foundation; either version 2 of the License, or
  225965. + * (at your option) any later version.
  225966. + *
  225967. + * This program is distributed in the hope that it will be useful,
  225968. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  225969. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  225970. + * GNU General Public License for more details.
  225971. + *
  225972. + * You should have received a copy of the GNU General Public License along
  225973. + * with this program; if not, write to the Free Software Foundation, Inc.,
  225974. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  225975. + */
  225976. +
  225977. +/*!
  225978. + * @defgroup IPU MXC Image Processing Unit (IPU) Driver
  225979. + */
  225980. +/*!
  225981. + * @file uapi/linux/ipu.h
  225982. + *
  225983. + * @brief This file contains the IPU driver API declarations.
  225984. + *
  225985. + * @ingroup IPU
  225986. + */
  225987. +
  225988. +#ifndef __ASM_ARCH_IPU_H__
  225989. +#define __ASM_ARCH_IPU_H__
  225990. +
  225991. +#include <linux/types.h>
  225992. +#include <linux/videodev2.h>
  225993. +
  225994. +#ifndef __KERNEL__
  225995. +#ifndef __cplusplus
  225996. +typedef unsigned char bool;
  225997. +#endif
  225998. +#define irqreturn_t int
  225999. +#define dma_addr_t int
  226000. +#define uint32_t unsigned int
  226001. +#define uint16_t unsigned short
  226002. +#define uint8_t unsigned char
  226003. +#define u32 unsigned int
  226004. +#define u8 unsigned char
  226005. +#define __u32 u32
  226006. +#endif
  226007. +
  226008. +/*!
  226009. + * Enumeration of IPU rotation modes
  226010. + */
  226011. +typedef enum {
  226012. + /* Note the enum values correspond to BAM value */
  226013. + IPU_ROTATE_NONE = 0,
  226014. + IPU_ROTATE_VERT_FLIP = 1,
  226015. + IPU_ROTATE_HORIZ_FLIP = 2,
  226016. + IPU_ROTATE_180 = 3,
  226017. + IPU_ROTATE_90_RIGHT = 4,
  226018. + IPU_ROTATE_90_RIGHT_VFLIP = 5,
  226019. + IPU_ROTATE_90_RIGHT_HFLIP = 6,
  226020. + IPU_ROTATE_90_LEFT = 7,
  226021. +} ipu_rotate_mode_t;
  226022. +
  226023. +/*!
  226024. + * Enumeration of VDI MOTION select
  226025. + */
  226026. +typedef enum {
  226027. + MED_MOTION = 0,
  226028. + LOW_MOTION = 1,
  226029. + HIGH_MOTION = 2,
  226030. +} ipu_motion_sel;
  226031. +
  226032. +/*!
  226033. + * Enumeration of DI ports for ADC.
  226034. + */
  226035. +typedef enum {
  226036. + DISP0,
  226037. + DISP1,
  226038. + DISP2,
  226039. + DISP3
  226040. +} display_port_t;
  226041. +
  226042. +/* IPU Pixel format definitions */
  226043. +/* Four-character-code (FOURCC) */
  226044. +#define fourcc(a, b, c, d)\
  226045. + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
  226046. +
  226047. +/*!
  226048. + * @name IPU Pixel Formats
  226049. + *
  226050. + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
  226051. + * the same used by V4L2 API.
  226052. + */
  226053. +
  226054. +/*! @{ */
  226055. +/*! @name Generic or Raw Data Formats */
  226056. +/*! @{ */
  226057. +#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') /*!< IPU Generic Data */
  226058. +#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') /*!< IPU Generic Data */
  226059. +#define IPU_PIX_FMT_GENERIC_16 fourcc('I', 'P', 'U', '2') /*!< IPU Generic Data */
  226060. +#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6') /*!< IPU Generic Data */
  226061. +#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8') /*!< IPU Generic Data */
  226062. +/*! @} */
  226063. +/*! @name RGB Formats */
  226064. +/*! @{ */
  226065. +#define IPU_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
  226066. +#define IPU_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
  226067. +#define IPU_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
  226068. +#define IPU_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
  226069. +#define IPU_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
  226070. +#define IPU_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
  226071. +#define IPU_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
  226072. +#define IPU_PIX_FMT_GBR24 fourcc('G', 'B', 'R', '3') /*!< 24 GBR-8-8-8 */
  226073. +#define IPU_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
  226074. +#define IPU_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
  226075. +#define IPU_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
  226076. +#define IPU_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
  226077. +#define IPU_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
  226078. +/*! @} */
  226079. +/*! @name YUV Interleaved Formats */
  226080. +/*! @{ */
  226081. +#define IPU_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
  226082. +#define IPU_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
  226083. +#define IPU_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVYU 4:2:2 */
  226084. +#define IPU_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 VYYU 4:2:2 */
  226085. +#define IPU_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
  226086. +#define IPU_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
  226087. +#define IPU_PIX_FMT_VYU444 fourcc('V', '4', '4', '4') /*!< 24 VYU 4:4:4 */
  226088. +/* two planes -- one Y, one Cb + Cr interleaved */
  226089. +#define IPU_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
  226090. +/* two planes -- 12 tiled Y/CbCr 4:2:0 */
  226091. +#define IPU_PIX_FMT_TILED_NV12 fourcc('T', 'N', 'V', 'P')
  226092. +#define IPU_PIX_FMT_TILED_NV12F fourcc('T', 'N', 'V', 'F')
  226093. +
  226094. +/*! @} */
  226095. +/*! @name YUV Planar Formats */
  226096. +/*! @{ */
  226097. +#define IPU_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
  226098. +#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
  226099. +#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
  226100. +#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
  226101. +#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
  226102. +#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
  226103. +#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
  226104. +#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
  226105. +/* non-interleaved 4:4:4 */
  226106. +#define IPU_PIX_FMT_YUV444P fourcc('4', '4', '4', 'P') /*!< 24 YUV 4:4:4 */
  226107. +/*! @} */
  226108. +#define IPU_PIX_FMT_TILED_NV12_MBALIGN (16)
  226109. +#define TILED_NV12_FRAME_SIZE(w, h) \
  226110. + (ALIGN((w) * (h), SZ_4K) + ALIGN((w) * (h) / 2, SZ_4K))
  226111. +/* IPU device */
  226112. +typedef enum {
  226113. + RGB_CS,
  226114. + YUV_CS,
  226115. + NULL_CS
  226116. +} cs_t;
  226117. +
  226118. +struct ipu_pos {
  226119. + u32 x;
  226120. + u32 y;
  226121. +};
  226122. +
  226123. +struct ipu_crop {
  226124. + struct ipu_pos pos;
  226125. + u32 w;
  226126. + u32 h;
  226127. +};
  226128. +
  226129. +struct ipu_deinterlace {
  226130. + bool enable;
  226131. + u8 motion; /*see ipu_motion_sel*/
  226132. +#define IPU_DEINTERLACE_FIELD_TOP 0
  226133. +#define IPU_DEINTERLACE_FIELD_BOTTOM 1
  226134. +#define IPU_DEINTERLACE_FIELD_MASK \
  226135. + (IPU_DEINTERLACE_FIELD_TOP | IPU_DEINTERLACE_FIELD_BOTTOM)
  226136. + /* deinterlace frame rate double flags */
  226137. +#define IPU_DEINTERLACE_RATE_EN 0x80
  226138. +#define IPU_DEINTERLACE_RATE_FRAME1 0x40
  226139. +#define IPU_DEINTERLACE_RATE_MASK \
  226140. + (IPU_DEINTERLACE_RATE_EN | IPU_DEINTERLACE_RATE_FRAME1)
  226141. +#define IPU_DEINTERLACE_MAX_FRAME 2
  226142. + u8 field_fmt;
  226143. +};
  226144. +
  226145. +struct ipu_input {
  226146. + u32 width;
  226147. + u32 height;
  226148. + u32 format;
  226149. + struct ipu_crop crop;
  226150. + dma_addr_t paddr;
  226151. +
  226152. + struct ipu_deinterlace deinterlace;
  226153. + dma_addr_t paddr_n; /*valid when deinterlace enable*/
  226154. +};
  226155. +
  226156. +struct ipu_alpha {
  226157. +#define IPU_ALPHA_MODE_GLOBAL 0
  226158. +#define IPU_ALPHA_MODE_LOCAL 1
  226159. + u8 mode;
  226160. + u8 gvalue; /* 0~255 */
  226161. + dma_addr_t loc_alp_paddr;
  226162. +};
  226163. +
  226164. +struct ipu_colorkey {
  226165. + bool enable;
  226166. + u32 value; /* RGB 24bit */
  226167. +};
  226168. +
  226169. +struct ipu_overlay {
  226170. + u32 width;
  226171. + u32 height;
  226172. + u32 format;
  226173. + struct ipu_crop crop;
  226174. + struct ipu_alpha alpha;
  226175. + struct ipu_colorkey colorkey;
  226176. + dma_addr_t paddr;
  226177. +};
  226178. +
  226179. +struct ipu_output {
  226180. + u32 width;
  226181. + u32 height;
  226182. + u32 format;
  226183. + u8 rotate;
  226184. + struct ipu_crop crop;
  226185. + dma_addr_t paddr;
  226186. +};
  226187. +
  226188. +struct ipu_task {
  226189. + struct ipu_input input;
  226190. + struct ipu_output output;
  226191. +
  226192. + bool overlay_en;
  226193. + struct ipu_overlay overlay;
  226194. +
  226195. +#define IPU_TASK_PRIORITY_NORMAL 0
  226196. +#define IPU_TASK_PRIORITY_HIGH 1
  226197. + u8 priority;
  226198. +
  226199. +#define IPU_TASK_ID_ANY 0
  226200. +#define IPU_TASK_ID_VF 1
  226201. +#define IPU_TASK_ID_PP 2
  226202. +#define IPU_TASK_ID_MAX 3
  226203. + u8 task_id;
  226204. +
  226205. + int timeout;
  226206. +};
  226207. +
  226208. +enum {
  226209. + IPU_CHECK_OK = 0,
  226210. + IPU_CHECK_WARN_INPUT_OFFS_NOT8ALIGN = 0x1,
  226211. + IPU_CHECK_WARN_OUTPUT_OFFS_NOT8ALIGN = 0x2,
  226212. + IPU_CHECK_WARN_OVERLAY_OFFS_NOT8ALIGN = 0x4,
  226213. + IPU_CHECK_ERR_MIN,
  226214. + IPU_CHECK_ERR_INPUT_CROP,
  226215. + IPU_CHECK_ERR_OUTPUT_CROP,
  226216. + IPU_CHECK_ERR_OVERLAY_CROP,
  226217. + IPU_CHECK_ERR_INPUT_OVER_LIMIT,
  226218. + IPU_CHECK_ERR_OV_OUT_NO_FIT,
  226219. + IPU_CHECK_ERR_OVERLAY_WITH_VDI,
  226220. + IPU_CHECK_ERR_PROC_NO_NEED,
  226221. + IPU_CHECK_ERR_SPLIT_INPUTW_OVER,
  226222. + IPU_CHECK_ERR_SPLIT_INPUTH_OVER,
  226223. + IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER,
  226224. + IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER,
  226225. + IPU_CHECK_ERR_SPLIT_WITH_ROT,
  226226. + IPU_CHECK_ERR_NOT_SUPPORT,
  226227. + IPU_CHECK_ERR_NOT16ALIGN,
  226228. + IPU_CHECK_ERR_W_DOWNSIZE_OVER,
  226229. + IPU_CHECK_ERR_H_DOWNSIZE_OVER,
  226230. +};
  226231. +
  226232. +/* IOCTL commands */
  226233. +#define IPU_CHECK_TASK _IOWR('I', 0x1, struct ipu_task)
  226234. +#define IPU_QUEUE_TASK _IOW('I', 0x2, struct ipu_task)
  226235. +#define IPU_ALLOC _IOWR('I', 0x3, int)
  226236. +#define IPU_FREE _IOW('I', 0x4, int)
  226237. +
  226238. +#endif
  226239. diff -Nur linux-3.14.17/include/uapi/linux/isl29023.h linux-imx6-3.14/include/uapi/linux/isl29023.h
  226240. --- linux-3.14.17/include/uapi/linux/isl29023.h 1970-01-01 01:00:00.000000000 +0100
  226241. +++ linux-imx6-3.14/include/uapi/linux/isl29023.h 2014-09-11 18:06:14.378087384 +0200
  226242. @@ -0,0 +1,47 @@
  226243. +/*
  226244. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  226245. + */
  226246. +
  226247. +/*
  226248. + * This program is free software; you can redistribute it and/or modify
  226249. + * it under the terms of the GNU General Public License as published by
  226250. + * the Free Software Foundation; either version 2 of the License, or
  226251. + * (at your option) any later version.
  226252. +
  226253. + * This program is distributed in the hope that it will be useful,
  226254. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  226255. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  226256. + * GNU General Public License for more details.
  226257. +
  226258. + * You should have received a copy of the GNU General Public License along
  226259. + * with this program; if not, write to the Free Software Foundation, Inc.,
  226260. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  226261. + */
  226262. +
  226263. +#ifndef __UAPI_LINUX_ISL29023_H__
  226264. +#define __UAPI_LINUX_ISL29023_H__
  226265. +
  226266. +#include <linux/types.h>
  226267. +
  226268. +#define ISL29023_PD_MODE 0x0
  226269. +#define ISL29023_ALS_ONCE_MODE 0x1
  226270. +#define ISL29023_IR_ONCE_MODE 0x2
  226271. +#define ISL29023_ALS_CONT_MODE 0x5
  226272. +#define ISL29023_IR_CONT_MODE 0x6
  226273. +
  226274. +#define ISL29023_INT_PERSISTS_1 0x0
  226275. +#define ISL29023_INT_PERSISTS_4 0x1
  226276. +#define ISL29023_INT_PERSISTS_8 0x2
  226277. +#define ISL29023_INT_PERSISTS_16 0x3
  226278. +
  226279. +#define ISL29023_RES_16 0x0
  226280. +#define ISL29023_RES_12 0x1
  226281. +#define ISL29023_RES_8 0x2
  226282. +#define ISL29023_RES_4 0x3
  226283. +
  226284. +#define ISL29023_RANGE_1K 0x0
  226285. +#define ISL29023_RANGE_4K 0x1
  226286. +#define ISL29023_RANGE_16K 0x2
  226287. +#define ISL29023_RANGE_64K 0x3
  226288. +
  226289. +#endif
  226290. diff -Nur linux-3.14.17/include/uapi/linux/Kbuild linux-imx6-3.14/include/uapi/linux/Kbuild
  226291. --- linux-3.14.17/include/uapi/linux/Kbuild 2014-08-14 03:38:34.000000000 +0200
  226292. +++ linux-imx6-3.14/include/uapi/linux/Kbuild 2014-09-11 18:06:14.290087032 +0200
  226293. @@ -226,6 +226,7 @@
  226294. header-y += kvm_para.h
  226295. endif
  226296. +header-y += ipu.h
  226297. header-y += l2tp.h
  226298. header-y += libc-compat.h
  226299. header-y += limits.h
  226300. @@ -253,6 +254,9 @@
  226301. header-y += msdos_fs.h
  226302. header-y += msg.h
  226303. header-y += mtio.h
  226304. +header-y += mxcfb.h
  226305. +header-y += mxc_asrc.h
  226306. +header-y += mxc_v4l2.h
  226307. header-y += n_r3964.h
  226308. header-y += nbd.h
  226309. header-y += ncp.h
  226310. @@ -318,6 +322,8 @@
  226311. header-y += prctl.h
  226312. header-y += ptp_clock.h
  226313. header-y += ptrace.h
  226314. +header-y += pxp_dma.h
  226315. +header-y += pxp_device.h
  226316. header-y += qnx4_fs.h
  226317. header-y += qnxtypes.h
  226318. header-y += quota.h
  226319. diff -Nur linux-3.14.17/include/uapi/linux/mxc_asrc.h linux-imx6-3.14/include/uapi/linux/mxc_asrc.h
  226320. --- linux-3.14.17/include/uapi/linux/mxc_asrc.h 1970-01-01 01:00:00.000000000 +0100
  226321. +++ linux-imx6-3.14/include/uapi/linux/mxc_asrc.h 2014-09-11 18:06:14.386087416 +0200
  226322. @@ -0,0 +1,143 @@
  226323. +/*
  226324. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  226325. + *
  226326. + * The code contained herein is licensed under the GNU General Public
  226327. + * License. You may obtain a copy of the GNU General Public License
  226328. + * Version 2 or later at the following locations:
  226329. + *
  226330. + * http://www.opensource.org/licenses/gpl-license.html
  226331. + * http://www.gnu.org/copyleft/gpl.html
  226332. + *
  226333. + * @file mxc_asrc.h
  226334. + *
  226335. + * @brief i.MX Asynchronous Sample Rate Converter
  226336. + *
  226337. + * @ingroup Audio
  226338. + */
  226339. +
  226340. +#ifndef __MXC_ASRC_UAPI_H__
  226341. +#define __MXC_ASRC_UAPI_H__
  226342. +
  226343. +#define ASRC_IOC_MAGIC 'C'
  226344. +
  226345. +#define ASRC_REQ_PAIR _IOWR(ASRC_IOC_MAGIC, 0, struct asrc_req)
  226346. +#define ASRC_CONFIG_PAIR _IOWR(ASRC_IOC_MAGIC, 1, struct asrc_config)
  226347. +#define ASRC_RELEASE_PAIR _IOW(ASRC_IOC_MAGIC, 2, enum asrc_pair_index)
  226348. +#define ASRC_CONVERT _IOW(ASRC_IOC_MAGIC, 3, struct asrc_convert_buffer)
  226349. +#define ASRC_START_CONV _IOW(ASRC_IOC_MAGIC, 4, enum asrc_pair_index)
  226350. +#define ASRC_STOP_CONV _IOW(ASRC_IOC_MAGIC, 5, enum asrc_pair_index)
  226351. +#define ASRC_STATUS _IOW(ASRC_IOC_MAGIC, 6, struct asrc_status_flags)
  226352. +#define ASRC_FLUSH _IOW(ASRC_IOC_MAGIC, 7, enum asrc_pair_index)
  226353. +
  226354. +enum asrc_pair_index {
  226355. + ASRC_UNVALID_PAIR = -1,
  226356. + ASRC_PAIR_A = 0,
  226357. + ASRC_PAIR_B = 1,
  226358. + ASRC_PAIR_C = 2,
  226359. +};
  226360. +
  226361. +#define ASRC_PAIR_MAX_NUM (ASRC_PAIR_C + 1)
  226362. +
  226363. +enum asrc_inclk {
  226364. + INCLK_NONE = 0x03,
  226365. + INCLK_ESAI_RX = 0x00,
  226366. + INCLK_SSI1_RX = 0x01,
  226367. + INCLK_SSI2_RX = 0x02,
  226368. + INCLK_SSI3_RX = 0x07,
  226369. + INCLK_SPDIF_RX = 0x04,
  226370. + INCLK_MLB_CLK = 0x05,
  226371. + INCLK_PAD = 0x06,
  226372. + INCLK_ESAI_TX = 0x08,
  226373. + INCLK_SSI1_TX = 0x09,
  226374. + INCLK_SSI2_TX = 0x0a,
  226375. + INCLK_SSI3_TX = 0x0b,
  226376. + INCLK_SPDIF_TX = 0x0c,
  226377. + INCLK_ASRCK1_CLK = 0x0f,
  226378. +};
  226379. +
  226380. +enum asrc_outclk {
  226381. + OUTCLK_NONE = 0x03,
  226382. + OUTCLK_ESAI_TX = 0x00,
  226383. + OUTCLK_SSI1_TX = 0x01,
  226384. + OUTCLK_SSI2_TX = 0x02,
  226385. + OUTCLK_SSI3_TX = 0x07,
  226386. + OUTCLK_SPDIF_TX = 0x04,
  226387. + OUTCLK_MLB_CLK = 0x05,
  226388. + OUTCLK_PAD = 0x06,
  226389. + OUTCLK_ESAI_RX = 0x08,
  226390. + OUTCLK_SSI1_RX = 0x09,
  226391. + OUTCLK_SSI2_RX = 0x0a,
  226392. + OUTCLK_SSI3_RX = 0x0b,
  226393. + OUTCLK_SPDIF_RX = 0x0c,
  226394. + OUTCLK_ASRCK1_CLK = 0x0f,
  226395. +};
  226396. +
  226397. +enum asrc_word_width {
  226398. + ASRC_WIDTH_24_BIT = 0,
  226399. + ASRC_WIDTH_16_BIT = 1,
  226400. + ASRC_WIDTH_8_BIT = 2,
  226401. +};
  226402. +
  226403. +struct asrc_config {
  226404. + enum asrc_pair_index pair;
  226405. + unsigned int channel_num;
  226406. + unsigned int buffer_num;
  226407. + unsigned int dma_buffer_size;
  226408. + unsigned int input_sample_rate;
  226409. + unsigned int output_sample_rate;
  226410. + enum asrc_word_width input_word_width;
  226411. + enum asrc_word_width output_word_width;
  226412. + enum asrc_inclk inclk;
  226413. + enum asrc_outclk outclk;
  226414. +};
  226415. +
  226416. +struct asrc_pair {
  226417. + unsigned int start_channel;
  226418. + unsigned int chn_num;
  226419. + unsigned int chn_max;
  226420. + unsigned int active;
  226421. + unsigned int overload_error;
  226422. +};
  226423. +
  226424. +struct asrc_req {
  226425. + unsigned int chn_num;
  226426. + enum asrc_pair_index index;
  226427. +};
  226428. +
  226429. +struct asrc_querybuf {
  226430. + unsigned int buffer_index;
  226431. + unsigned int input_length;
  226432. + unsigned int output_length;
  226433. + unsigned long input_offset;
  226434. + unsigned long output_offset;
  226435. +};
  226436. +
  226437. +struct asrc_convert_buffer {
  226438. + void *input_buffer_vaddr;
  226439. + void *output_buffer_vaddr;
  226440. + unsigned int input_buffer_length;
  226441. + unsigned int output_buffer_length;
  226442. +};
  226443. +
  226444. +struct asrc_buffer {
  226445. + unsigned int index;
  226446. + unsigned int length;
  226447. + unsigned int output_last_length;
  226448. + int buf_valid;
  226449. +};
  226450. +
  226451. +struct asrc_status_flags {
  226452. + enum asrc_pair_index index;
  226453. + unsigned int overload_error;
  226454. +};
  226455. +
  226456. +#define ASRC_BUF_NA -35 /* ASRC DQ's buffer is NOT available */
  226457. +#define ASRC_BUF_AV 35 /* ASRC DQ's buffer is available */
  226458. +enum asrc_error_status {
  226459. + ASRC_TASK_Q_OVERLOAD = 0x01,
  226460. + ASRC_OUTPUT_TASK_OVERLOAD = 0x02,
  226461. + ASRC_INPUT_TASK_OVERLOAD = 0x04,
  226462. + ASRC_OUTPUT_BUFFER_OVERFLOW = 0x08,
  226463. + ASRC_INPUT_BUFFER_UNDERRUN = 0x10,
  226464. +};
  226465. +#endif/* __MXC_ASRC_UAPI_H__ */
  226466. diff -Nur linux-3.14.17/include/uapi/linux/mxcfb.h linux-imx6-3.14/include/uapi/linux/mxcfb.h
  226467. --- linux-3.14.17/include/uapi/linux/mxcfb.h 1970-01-01 01:00:00.000000000 +0100
  226468. +++ linux-imx6-3.14/include/uapi/linux/mxcfb.h 2014-09-11 18:06:14.386087416 +0200
  226469. @@ -0,0 +1,174 @@
  226470. +/*
  226471. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  226472. + */
  226473. +
  226474. +/*
  226475. + * This program is free software; you can redistribute it and/or modify
  226476. + * it under the terms of the GNU General Public License as published by
  226477. + * the Free Software Foundation; either version 2 of the License, or
  226478. + * (at your option) any later version.
  226479. + *
  226480. + * This program is distributed in the hope that it will be useful,
  226481. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  226482. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  226483. + * GNU General Public License for more details.
  226484. + *
  226485. + * You should have received a copy of the GNU General Public License along
  226486. + * with this program; if not, write to the Free Software Foundation, Inc.,
  226487. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  226488. + */
  226489. +
  226490. +/*
  226491. + * @file uapi/linux/mxcfb.h
  226492. + *
  226493. + * @brief Global header file for the MXC frame buffer
  226494. + *
  226495. + * @ingroup Framebuffer
  226496. + */
  226497. +#ifndef __ASM_ARCH_MXCFB_H__
  226498. +#define __ASM_ARCH_MXCFB_H__
  226499. +
  226500. +#include <linux/fb.h>
  226501. +
  226502. +#define FB_SYNC_OE_LOW_ACT 0x80000000
  226503. +#define FB_SYNC_CLK_LAT_FALL 0x40000000
  226504. +#define FB_SYNC_DATA_INVERT 0x20000000
  226505. +#define FB_SYNC_CLK_IDLE_EN 0x10000000
  226506. +#define FB_SYNC_SHARP_MODE 0x08000000
  226507. +#define FB_SYNC_SWAP_RGB 0x04000000
  226508. +#define FB_ACCEL_TRIPLE_FLAG 0x00000000
  226509. +#define FB_ACCEL_DOUBLE_FLAG 0x00000001
  226510. +
  226511. +struct mxcfb_gbl_alpha {
  226512. + int enable;
  226513. + int alpha;
  226514. +};
  226515. +
  226516. +struct mxcfb_loc_alpha {
  226517. + int enable;
  226518. + int alpha_in_pixel;
  226519. + unsigned long alpha_phy_addr0;
  226520. + unsigned long alpha_phy_addr1;
  226521. +};
  226522. +
  226523. +struct mxcfb_color_key {
  226524. + int enable;
  226525. + __u32 color_key;
  226526. +};
  226527. +
  226528. +struct mxcfb_pos {
  226529. + __u16 x;
  226530. + __u16 y;
  226531. +};
  226532. +
  226533. +struct mxcfb_gamma {
  226534. + int enable;
  226535. + int constk[16];
  226536. + int slopek[16];
  226537. +};
  226538. +
  226539. +struct mxcfb_rect {
  226540. + __u32 top;
  226541. + __u32 left;
  226542. + __u32 width;
  226543. + __u32 height;
  226544. +};
  226545. +
  226546. +#define GRAYSCALE_8BIT 0x1
  226547. +#define GRAYSCALE_8BIT_INVERTED 0x2
  226548. +#define GRAYSCALE_4BIT 0x3
  226549. +#define GRAYSCALE_4BIT_INVERTED 0x4
  226550. +
  226551. +#define AUTO_UPDATE_MODE_REGION_MODE 0
  226552. +#define AUTO_UPDATE_MODE_AUTOMATIC_MODE 1
  226553. +
  226554. +#define UPDATE_SCHEME_SNAPSHOT 0
  226555. +#define UPDATE_SCHEME_QUEUE 1
  226556. +#define UPDATE_SCHEME_QUEUE_AND_MERGE 2
  226557. +
  226558. +#define UPDATE_MODE_PARTIAL 0x0
  226559. +#define UPDATE_MODE_FULL 0x1
  226560. +
  226561. +#define WAVEFORM_MODE_AUTO 257
  226562. +
  226563. +#define TEMP_USE_AMBIENT 0x1000
  226564. +
  226565. +#define EPDC_FLAG_ENABLE_INVERSION 0x01
  226566. +#define EPDC_FLAG_FORCE_MONOCHROME 0x02
  226567. +#define EPDC_FLAG_USE_CMAP 0x04
  226568. +#define EPDC_FLAG_USE_ALT_BUFFER 0x100
  226569. +#define EPDC_FLAG_TEST_COLLISION 0x200
  226570. +#define EPDC_FLAG_GROUP_UPDATE 0x400
  226571. +#define EPDC_FLAG_USE_DITHERING_Y1 0x2000
  226572. +#define EPDC_FLAG_USE_DITHERING_Y4 0x4000
  226573. +
  226574. +#define FB_POWERDOWN_DISABLE -1
  226575. +
  226576. +struct mxcfb_alt_buffer_data {
  226577. + __u32 phys_addr;
  226578. + __u32 width; /* width of entire buffer */
  226579. + __u32 height; /* height of entire buffer */
  226580. + struct mxcfb_rect alt_update_region; /* region within buffer to update */
  226581. +};
  226582. +
  226583. +struct mxcfb_update_data {
  226584. + struct mxcfb_rect update_region;
  226585. + __u32 waveform_mode;
  226586. + __u32 update_mode;
  226587. + __u32 update_marker;
  226588. + int temp;
  226589. + unsigned int flags;
  226590. + struct mxcfb_alt_buffer_data alt_buffer_data;
  226591. +};
  226592. +
  226593. +struct mxcfb_update_marker_data {
  226594. + __u32 update_marker;
  226595. + __u32 collision_test;
  226596. +};
  226597. +
  226598. +/*
  226599. + * Structure used to define waveform modes for driver
  226600. + * Needed for driver to perform auto-waveform selection
  226601. + */
  226602. +struct mxcfb_waveform_modes {
  226603. + int mode_init;
  226604. + int mode_du;
  226605. + int mode_gc4;
  226606. + int mode_gc8;
  226607. + int mode_gc16;
  226608. + int mode_gc32;
  226609. +};
  226610. +
  226611. +/*
  226612. + * Structure used to define a 5*3 matrix of parameters for
  226613. + * setting IPU DP CSC module related to this framebuffer.
  226614. + */
  226615. +struct mxcfb_csc_matrix {
  226616. + int param[5][3];
  226617. +};
  226618. +
  226619. +#define MXCFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t)
  226620. +#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha)
  226621. +#define MXCFB_SET_CLR_KEY _IOW('F', 0x22, struct mxcfb_color_key)
  226622. +#define MXCFB_SET_OVERLAY_POS _IOWR('F', 0x24, struct mxcfb_pos)
  226623. +#define MXCFB_GET_FB_IPU_CHAN _IOR('F', 0x25, u_int32_t)
  226624. +#define MXCFB_SET_LOC_ALPHA _IOWR('F', 0x26, struct mxcfb_loc_alpha)
  226625. +#define MXCFB_SET_LOC_ALP_BUF _IOW('F', 0x27, unsigned long)
  226626. +#define MXCFB_SET_GAMMA _IOW('F', 0x28, struct mxcfb_gamma)
  226627. +#define MXCFB_GET_FB_IPU_DI _IOR('F', 0x29, u_int32_t)
  226628. +#define MXCFB_GET_DIFMT _IOR('F', 0x2A, u_int32_t)
  226629. +#define MXCFB_GET_FB_BLANK _IOR('F', 0x2B, u_int32_t)
  226630. +#define MXCFB_SET_DIFMT _IOW('F', 0x2C, u_int32_t)
  226631. +#define MXCFB_CSC_UPDATE _IOW('F', 0x2D, struct mxcfb_csc_matrix)
  226632. +
  226633. +/* IOCTLs for E-ink panel updates */
  226634. +#define MXCFB_SET_WAVEFORM_MODES _IOW('F', 0x2B, struct mxcfb_waveform_modes)
  226635. +#define MXCFB_SET_TEMPERATURE _IOW('F', 0x2C, int32_t)
  226636. +#define MXCFB_SET_AUTO_UPDATE_MODE _IOW('F', 0x2D, __u32)
  226637. +#define MXCFB_SEND_UPDATE _IOW('F', 0x2E, struct mxcfb_update_data)
  226638. +#define MXCFB_WAIT_FOR_UPDATE_COMPLETE _IOWR('F', 0x2F, struct mxcfb_update_marker_data)
  226639. +#define MXCFB_SET_PWRDOWN_DELAY _IOW('F', 0x30, int32_t)
  226640. +#define MXCFB_GET_PWRDOWN_DELAY _IOR('F', 0x31, int32_t)
  226641. +#define MXCFB_SET_UPDATE_SCHEME _IOW('F', 0x32, __u32)
  226642. +#define MXCFB_GET_WORK_BUFFER _IOWR('F', 0x34, unsigned long)
  226643. +#endif
  226644. diff -Nur linux-3.14.17/include/uapi/linux/mxc_mlb.h linux-imx6-3.14/include/uapi/linux/mxc_mlb.h
  226645. --- linux-3.14.17/include/uapi/linux/mxc_mlb.h 1970-01-01 01:00:00.000000000 +0100
  226646. +++ linux-imx6-3.14/include/uapi/linux/mxc_mlb.h 2014-09-11 18:06:14.386087416 +0200
  226647. @@ -0,0 +1,55 @@
  226648. +/*
  226649. + * mxc_mlb.h
  226650. + *
  226651. + * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  226652. + */
  226653. +
  226654. +/*
  226655. + * The code contained herein is licensed under the GNU General Public
  226656. + * License. You may obtain a copy of the GNU General Public License
  226657. + * Version 2 or later at the following locations:
  226658. + *
  226659. + * http://www.opensource.org/licenses/gpl-license.html
  226660. + * http://www.gnu.org/copyleft/gpl.html
  226661. + */
  226662. +
  226663. +#ifndef _MXC_MLB_UAPI_H
  226664. +#define _MXC_MLB_UAPI_H
  226665. +
  226666. +/* define IOCTL command */
  226667. +#define MLB_DBG_RUNTIME _IO('S', 0x09)
  226668. +#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
  226669. +#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
  226670. +#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
  226671. +
  226672. +/*!
  226673. + * set channel address for each logical channel
  226674. + * the MSB 16bits is for tx channel, the left LSB is for rx channel
  226675. + */
  226676. +#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
  226677. +#define MLB_CHAN_STARTUP _IO('S', 0x14)
  226678. +#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
  226679. +#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
  226680. +
  226681. +#define MLB_SET_ISOC_BLKSIZE_188 _IO('S', 0x17)
  226682. +#define MLB_SET_ISOC_BLKSIZE_196 _IO('S', 0x18)
  226683. +#define MLB_SET_SYNC_QUAD _IOW('S', 0x19, unsigned int)
  226684. +#define MLB_IRQ_ENABLE _IO('S', 0x20)
  226685. +#define MLB_IRQ_DISABLE _IO('S', 0x21)
  226686. +
  226687. +/*!
  226688. + * MLB event define
  226689. + */
  226690. +enum {
  226691. + MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
  226692. + MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
  226693. + MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
  226694. + MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
  226695. + MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
  226696. + MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
  226697. + MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
  226698. + MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
  226699. +};
  226700. +
  226701. +
  226702. +#endif /* _MXC_MLB_H */
  226703. diff -Nur linux-3.14.17/include/uapi/linux/mxc_v4l2.h linux-imx6-3.14/include/uapi/linux/mxc_v4l2.h
  226704. --- linux-3.14.17/include/uapi/linux/mxc_v4l2.h 1970-01-01 01:00:00.000000000 +0100
  226705. +++ linux-imx6-3.14/include/uapi/linux/mxc_v4l2.h 2014-09-11 18:06:14.386087416 +0200
  226706. @@ -0,0 +1,56 @@
  226707. +/*
  226708. + * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved
  226709. + */
  226710. +
  226711. +/*
  226712. + * This program is free software; you can redistribute it and/or modify
  226713. + * it under the terms of the GNU General Public License as published by
  226714. + * the Free Software Foundation; either version 2 of the License, or
  226715. + * (at your option) any later version.
  226716. + *
  226717. + * This program is distributed in the hope that it will be useful,
  226718. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  226719. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  226720. + * GNU General Public License for more details.
  226721. + *
  226722. + * You should have received a copy of the GNU General Public License along
  226723. + * with this program; if not, write to the Free Software Foundation, Inc.,
  226724. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  226725. + */
  226726. +
  226727. +/*!
  226728. + * @file uapi/linux/mxc_v4l2.h
  226729. + *
  226730. + * @brief MXC V4L2 private header file
  226731. + *
  226732. + * @ingroup MXC V4L2
  226733. + */
  226734. +
  226735. +#ifndef __ASM_ARCH_MXC_V4L2_H__
  226736. +#define __ASM_ARCH_MXC_V4L2_H__
  226737. +
  226738. +/*
  226739. + * For IPUv1 and IPUv3, V4L2_CID_MXC_ROT means encoder ioctl ID.
  226740. + * And V4L2_CID_MXC_VF_ROT is viewfinder ioctl ID only for IPUv1 and IPUv3.
  226741. + */
  226742. +#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0)
  226743. +#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1)
  226744. +#define V4L2_CID_MXC_VF_ROT (V4L2_CID_PRIVATE_BASE + 2)
  226745. +#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
  226746. +#define V4L2_CID_MXC_SWITCH_CAM (V4L2_CID_PRIVATE_BASE + 6)
  226747. +
  226748. +#define V4L2_MXC_ROTATE_NONE 0
  226749. +#define V4L2_MXC_ROTATE_VERT_FLIP 1
  226750. +#define V4L2_MXC_ROTATE_HORIZ_FLIP 2
  226751. +#define V4L2_MXC_ROTATE_180 3
  226752. +#define V4L2_MXC_ROTATE_90_RIGHT 4
  226753. +#define V4L2_MXC_ROTATE_90_RIGHT_VFLIP 5
  226754. +#define V4L2_MXC_ROTATE_90_RIGHT_HFLIP 6
  226755. +#define V4L2_MXC_ROTATE_90_LEFT 7
  226756. +
  226757. +struct v4l2_mxc_offset {
  226758. + uint32_t u_offset;
  226759. + uint32_t v_offset;
  226760. +};
  226761. +
  226762. +#endif
  226763. diff -Nur linux-3.14.17/include/uapi/linux/ptp_clock.h linux-imx6-3.14/include/uapi/linux/ptp_clock.h
  226764. --- linux-3.14.17/include/uapi/linux/ptp_clock.h 2014-08-14 03:38:34.000000000 +0200
  226765. +++ linux-imx6-3.14/include/uapi/linux/ptp_clock.h 2014-09-11 18:06:14.414087528 +0200
  226766. @@ -50,7 +50,8 @@
  226767. int n_ext_ts; /* Number of external time stamp channels. */
  226768. int n_per_out; /* Number of programmable periodic signals. */
  226769. int pps; /* Whether the clock supports a PPS callback. */
  226770. - int rsv[15]; /* Reserved for future use. */
  226771. + int n_pins; /* Number of input/output pins. */
  226772. + int rsv[14]; /* Reserved for future use. */
  226773. };
  226774. struct ptp_extts_request {
  226775. @@ -80,6 +81,40 @@
  226776. struct ptp_clock_time ts[2 * PTP_MAX_SAMPLES + 1];
  226777. };
  226778. +enum ptp_pin_function {
  226779. + PTP_PF_NONE,
  226780. + PTP_PF_EXTTS,
  226781. + PTP_PF_PEROUT,
  226782. + PTP_PF_PHYSYNC,
  226783. +};
  226784. +
  226785. +struct ptp_pin_desc {
  226786. + /*
  226787. + * Hardware specific human readable pin name. This field is
  226788. + * set by the kernel during the PTP_PIN_GETFUNC ioctl and is
  226789. + * ignored for the PTP_PIN_SETFUNC ioctl.
  226790. + */
  226791. + char name[64];
  226792. + /*
  226793. + * Pin index in the range of zero to ptp_clock_caps.n_pins - 1.
  226794. + */
  226795. + unsigned int index;
  226796. + /*
  226797. + * Which of the PTP_PF_xxx functions to use on this pin.
  226798. + */
  226799. + unsigned int func;
  226800. + /*
  226801. + * The specific channel to use for this function.
  226802. + * This corresponds to the 'index' field of the
  226803. + * PTP_EXTTS_REQUEST and PTP_PEROUT_REQUEST ioctls.
  226804. + */
  226805. + unsigned int chan;
  226806. + /*
  226807. + * Reserved for future use.
  226808. + */
  226809. + unsigned int rsv[5];
  226810. +};
  226811. +
  226812. #define PTP_CLK_MAGIC '='
  226813. #define PTP_CLOCK_GETCAPS _IOR(PTP_CLK_MAGIC, 1, struct ptp_clock_caps)
  226814. @@ -87,6 +122,8 @@
  226815. #define PTP_PEROUT_REQUEST _IOW(PTP_CLK_MAGIC, 3, struct ptp_perout_request)
  226816. #define PTP_ENABLE_PPS _IOW(PTP_CLK_MAGIC, 4, int)
  226817. #define PTP_SYS_OFFSET _IOW(PTP_CLK_MAGIC, 5, struct ptp_sys_offset)
  226818. +#define PTP_PIN_GETFUNC _IOWR(PTP_CLK_MAGIC, 6, struct ptp_pin_desc)
  226819. +#define PTP_PIN_SETFUNC _IOW(PTP_CLK_MAGIC, 7, struct ptp_pin_desc)
  226820. struct ptp_extts_event {
  226821. struct ptp_clock_time t; /* Time event occured. */
  226822. diff -Nur linux-3.14.17/include/uapi/linux/pxp_device.h linux-imx6-3.14/include/uapi/linux/pxp_device.h
  226823. --- linux-3.14.17/include/uapi/linux/pxp_device.h 1970-01-01 01:00:00.000000000 +0100
  226824. +++ linux-imx6-3.14/include/uapi/linux/pxp_device.h 2014-09-11 18:06:14.414087528 +0200
  226825. @@ -0,0 +1,63 @@
  226826. +/*
  226827. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  226828. + *
  226829. + * This program is free software; you can redistribute it and/or modify
  226830. + * it under the terms of the GNU General Public License as published by
  226831. + * the Free Software Foundation; either version 2 of the License, or
  226832. + * (at your option) any later version.
  226833. + *
  226834. + * This program is distributed in the hope that it will be useful,
  226835. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  226836. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  226837. + * GNU General Public License for more details.
  226838. + *
  226839. + * You should have received a copy of the GNU General Public License
  226840. + * along with this program; if not, write to the Free Software
  226841. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  226842. + *
  226843. + */
  226844. +#ifndef _UAPI_PXP_DEVICE
  226845. +#define _UAPI_PXP_DEVICE
  226846. +
  226847. +#include <linux/pxp_dma.h>
  226848. +
  226849. +struct pxp_chan_handle {
  226850. + unsigned int handle;
  226851. + int hist_status;
  226852. +};
  226853. +
  226854. +struct pxp_mem_desc {
  226855. + unsigned int handle;
  226856. + unsigned int size;
  226857. + dma_addr_t phys_addr;
  226858. + unsigned int virt_uaddr; /* virtual user space address */
  226859. + unsigned int mtype;
  226860. +};
  226861. +
  226862. +struct pxp_mem_flush {
  226863. + unsigned int handle;
  226864. + unsigned int type;
  226865. +};
  226866. +
  226867. +#define PXP_IOC_MAGIC 'P'
  226868. +
  226869. +#define PXP_IOC_GET_CHAN _IOR(PXP_IOC_MAGIC, 0, struct pxp_mem_desc)
  226870. +#define PXP_IOC_PUT_CHAN _IOW(PXP_IOC_MAGIC, 1, struct pxp_mem_desc)
  226871. +#define PXP_IOC_CONFIG_CHAN _IOW(PXP_IOC_MAGIC, 2, struct pxp_mem_desc)
  226872. +#define PXP_IOC_START_CHAN _IOW(PXP_IOC_MAGIC, 3, struct pxp_mem_desc)
  226873. +#define PXP_IOC_GET_PHYMEM _IOWR(PXP_IOC_MAGIC, 4, struct pxp_mem_desc)
  226874. +#define PXP_IOC_PUT_PHYMEM _IOW(PXP_IOC_MAGIC, 5, struct pxp_mem_desc)
  226875. +#define PXP_IOC_WAIT4CMPLT _IOWR(PXP_IOC_MAGIC, 6, struct pxp_mem_desc)
  226876. +#define PXP_IOC_FLUSH_PHYMEM _IOR(PXP_IOC_MAGIC, 7, struct pxp_mem_flush)
  226877. +
  226878. +/* Memory types supported*/
  226879. +#define MEMORY_TYPE_UNCACHED 0x0
  226880. +#define MEMORY_TYPE_WC 0x1
  226881. +#define MEMORY_TYPE_CACHED 0x2
  226882. +
  226883. +/* Cache flush operations */
  226884. +#define CACHE_CLEAN 0x1
  226885. +#define CACHE_INVALIDATE 0x2
  226886. +#define CACHE_FLUSH 0x4
  226887. +
  226888. +#endif
  226889. diff -Nur linux-3.14.17/include/uapi/linux/pxp_dma.h linux-imx6-3.14/include/uapi/linux/pxp_dma.h
  226890. --- linux-3.14.17/include/uapi/linux/pxp_dma.h 1970-01-01 01:00:00.000000000 +0100
  226891. +++ linux-imx6-3.14/include/uapi/linux/pxp_dma.h 2014-09-11 18:06:14.414087528 +0200
  226892. @@ -0,0 +1,173 @@
  226893. +/*
  226894. + * Copyright (C) 2013-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  226895. + *
  226896. + * This program is free software; you can redistribute it and/or modify
  226897. + * it under the terms of the GNU General Public License as published by
  226898. + * the Free Software Foundation; either version 2 of the License, or
  226899. + * (at your option) any later version.
  226900. + *
  226901. + * This program is distributed in the hope that it will be useful,
  226902. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  226903. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  226904. + * GNU General Public License for more details.
  226905. + *
  226906. + * You should have received a copy of the GNU General Public License
  226907. + * along with this program; if not, write to the Free Software
  226908. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  226909. + *
  226910. + */
  226911. +#ifndef _UAPI_PXP_DMA
  226912. +#define _UAPI_PXP_DMA
  226913. +
  226914. +#include <linux/posix_types.h>
  226915. +#include <linux/types.h>
  226916. +
  226917. +#ifndef __KERNEL__
  226918. +typedef unsigned long dma_addr_t;
  226919. +typedef unsigned char bool;
  226920. +#endif
  226921. +
  226922. +/* PXP Pixel format definitions */
  226923. +/* Four-character-code (FOURCC) */
  226924. +#define fourcc(a, b, c, d)\
  226925. + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
  226926. +
  226927. +/*!
  226928. + * @name PXP Pixel Formats
  226929. + *
  226930. + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
  226931. + * the same used by V4L2 API.
  226932. + */
  226933. +
  226934. +/*! @} */
  226935. +/*! @name RGB Formats */
  226936. +/*! @{ */
  226937. +#define PXP_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
  226938. +#define PXP_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
  226939. +#define PXP_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
  226940. +#define PXP_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
  226941. +#define PXP_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
  226942. +#define PXP_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
  226943. +#define PXP_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
  226944. +#define PXP_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
  226945. +#define PXP_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
  226946. +#define PXP_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
  226947. +#define PXP_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
  226948. +#define PXP_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
  226949. +/*! @} */
  226950. +/*! @name YUV Interleaved Formats */
  226951. +/*! @{ */
  226952. +#define PXP_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
  226953. +#define PXP_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
  226954. +#define PXP_PIX_FMT_VYUY fourcc('V', 'Y', 'U', 'Y') /*!< 16 YVU 4:2:2 */
  226955. +#define PXP_PIX_FMT_YVYU fourcc('Y', 'V', 'Y', 'U') /*!< 16 YVU 4:2:2 */
  226956. +#define PXP_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
  226957. +#define PXP_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
  226958. +/* two planes -- one Y, one Cb + Cr interleaved */
  226959. +#define PXP_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
  226960. +#define PXP_PIX_FMT_NV21 fourcc('N', 'V', '2', '1') /* 12 Y/CbCr 4:2:0 */
  226961. +#define PXP_PIX_FMT_NV16 fourcc('N', 'V', '1', '6') /* 12 Y/CbCr 4:2:2 */
  226962. +#define PXP_PIX_FMT_NV61 fourcc('N', 'V', '6', '1') /* 12 Y/CbCr 4:2:2 */
  226963. +/*! @} */
  226964. +/*! @name YUV Planar Formats */
  226965. +/*! @{ */
  226966. +#define PXP_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
  226967. +#define PXP_PIX_FMT_GY04 fourcc('G', 'Y', '0', '4') /*!< 4 Greyscale */
  226968. +#define PXP_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
  226969. +#define PXP_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
  226970. +#define PXP_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
  226971. +#define PXP_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
  226972. +#define PXP_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
  226973. +#define PXP_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
  226974. +#define PXP_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
  226975. +/*! @} */
  226976. +
  226977. +#define PXP_LUT_NONE 0x0
  226978. +#define PXP_LUT_INVERT 0x1
  226979. +#define PXP_LUT_BLACK_WHITE 0x2
  226980. +#define PXP_LUT_USE_CMAP 0x4
  226981. +
  226982. +#define NR_PXP_VIRT_CHANNEL 16
  226983. +
  226984. +/* Order significant! */
  226985. +enum pxp_channel_status {
  226986. + PXP_CHANNEL_FREE,
  226987. + PXP_CHANNEL_INITIALIZED,
  226988. + PXP_CHANNEL_READY,
  226989. +};
  226990. +
  226991. +struct rect {
  226992. + int top; /* Upper left coordinate of rectangle */
  226993. + int left;
  226994. + int width;
  226995. + int height;
  226996. +};
  226997. +
  226998. +struct pxp_layer_param {
  226999. + unsigned short width;
  227000. + unsigned short height;
  227001. + unsigned short stride; /* aka pitch */
  227002. + unsigned int pixel_fmt;
  227003. +
  227004. + /* layers combining parameters
  227005. + * (these are ignored for S0 and output
  227006. + * layers, and only apply for OL layer)
  227007. + */
  227008. + bool combine_enable;
  227009. + unsigned int color_key_enable;
  227010. + unsigned int color_key;
  227011. + bool global_alpha_enable;
  227012. + /* global alpha is either override or multiply */
  227013. + bool global_override;
  227014. + unsigned char global_alpha;
  227015. + bool alpha_invert;
  227016. + bool local_alpha_enable;
  227017. +
  227018. + dma_addr_t paddr;
  227019. +};
  227020. +
  227021. +struct pxp_proc_data {
  227022. + /* S0 Transformation Info */
  227023. + int scaling;
  227024. + int hflip;
  227025. + int vflip;
  227026. + int rotate;
  227027. + int rot_pos;
  227028. + int yuv;
  227029. +
  227030. + /* Source rectangle (srect) defines the sub-rectangle
  227031. + * within S0 to undergo processing.
  227032. + */
  227033. + struct rect srect;
  227034. + /* Dest rect (drect) defines how to position the processed
  227035. + * source rectangle (after resizing) within the output frame,
  227036. + * whose dimensions are defined in pxp->pxp_conf_state.out_param
  227037. + */
  227038. + struct rect drect;
  227039. +
  227040. + /* Current S0 configuration */
  227041. + unsigned int bgcolor;
  227042. +
  227043. + /* Output overlay support */
  227044. + int overlay_state;
  227045. +
  227046. + /* LUT transformation on Y data */
  227047. + int lut_transform;
  227048. + unsigned char *lut_map; /* 256 entries */
  227049. + bool lut_map_updated; /* Map recently changed */
  227050. + bool combine_enable;
  227051. +};
  227052. +
  227053. +struct pxp_config_data {
  227054. + struct pxp_layer_param s0_param;
  227055. + struct pxp_layer_param ol_param[8];
  227056. + struct pxp_layer_param out_param;
  227057. + struct pxp_proc_data proc_data;
  227058. + int layer_nr;
  227059. +
  227060. + /* Users don't touch */
  227061. + int handle;
  227062. +};
  227063. +
  227064. +
  227065. +#endif
  227066. diff -Nur linux-3.14.17/include/video/mxc_edid.h linux-imx6-3.14/include/video/mxc_edid.h
  227067. --- linux-3.14.17/include/video/mxc_edid.h 1970-01-01 01:00:00.000000000 +0100
  227068. +++ linux-imx6-3.14/include/video/mxc_edid.h 2014-09-11 18:06:14.438087624 +0200
  227069. @@ -0,0 +1,105 @@
  227070. +/*
  227071. + * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  227072. + */
  227073. +
  227074. +/*
  227075. + * The code contained herein is licensed under the GNU General Public
  227076. + * License. You may obtain a copy of the GNU General Public License
  227077. + * Version 2 or later at the following locations:
  227078. + *
  227079. + * http://www.opensource.org/licenses/gpl-license.html
  227080. + * http://www.gnu.org/copyleft/gpl.html
  227081. + */
  227082. +
  227083. +/*!
  227084. + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
  227085. + */
  227086. +
  227087. +/*!
  227088. + * @file mxc_edid.h
  227089. + *
  227090. + * @brief MXC EDID tools
  227091. + *
  227092. + * @ingroup Framebuffer
  227093. + */
  227094. +
  227095. +#ifndef MXC_EDID_H
  227096. +#define MXC_EDID_H
  227097. +
  227098. +#include <linux/fb.h>
  227099. +
  227100. +#define FB_VMODE_ASPECT_4_3 0x10
  227101. +#define FB_VMODE_ASPECT_16_9 0x20
  227102. +#define FB_VMODE_ASPECT_MASK (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9)
  227103. +
  227104. +enum cea_audio_coding_types {
  227105. + AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
  227106. + AUDIO_CODING_TYPE_LPCM = 1,
  227107. + AUDIO_CODING_TYPE_AC3 = 2,
  227108. + AUDIO_CODING_TYPE_MPEG1 = 3,
  227109. + AUDIO_CODING_TYPE_MP3 = 4,
  227110. + AUDIO_CODING_TYPE_MPEG2 = 5,
  227111. + AUDIO_CODING_TYPE_AACLC = 6,
  227112. + AUDIO_CODING_TYPE_DTS = 7,
  227113. + AUDIO_CODING_TYPE_ATRAC = 8,
  227114. + AUDIO_CODING_TYPE_SACD = 9,
  227115. + AUDIO_CODING_TYPE_EAC3 = 10,
  227116. + AUDIO_CODING_TYPE_DTS_HD = 11,
  227117. + AUDIO_CODING_TYPE_MLP = 12,
  227118. + AUDIO_CODING_TYPE_DST = 13,
  227119. + AUDIO_CODING_TYPE_WMAPRO = 14,
  227120. + AUDIO_CODING_TYPE_RESERVED = 15,
  227121. +};
  227122. +
  227123. +struct mxc_hdmi_3d_format {
  227124. + unsigned char vic_order_2d;
  227125. + unsigned char struct_3d;
  227126. + unsigned char detail_3d;
  227127. + unsigned char reserved;
  227128. +};
  227129. +
  227130. +struct mxc_edid_cfg {
  227131. + bool cea_underscan;
  227132. + bool cea_basicaudio;
  227133. + bool cea_ycbcr444;
  227134. + bool cea_ycbcr422;
  227135. + bool hdmi_cap;
  227136. +
  227137. + /*VSD*/
  227138. + bool vsd_support_ai;
  227139. + bool vsd_dc_48bit;
  227140. + bool vsd_dc_36bit;
  227141. + bool vsd_dc_30bit;
  227142. + bool vsd_dc_y444;
  227143. + bool vsd_dvi_dual;
  227144. +
  227145. + bool vsd_cnc0;
  227146. + bool vsd_cnc1;
  227147. + bool vsd_cnc2;
  227148. + bool vsd_cnc3;
  227149. +
  227150. + u8 vsd_video_latency;
  227151. + u8 vsd_audio_latency;
  227152. + u8 vsd_I_video_latency;
  227153. + u8 vsd_I_audio_latency;
  227154. +
  227155. + u8 physical_address[4];
  227156. + u8 hdmi_vic[64];
  227157. + struct mxc_hdmi_3d_format hdmi_3d_format[64];
  227158. + u16 hdmi_3d_mask_all;
  227159. + u16 hdmi_3d_struct_all;
  227160. + u32 vsd_max_tmdsclk_rate;
  227161. +
  227162. + u8 max_channels;
  227163. + u8 sample_sizes;
  227164. + u8 sample_rates;
  227165. + u8 speaker_alloc;
  227166. +};
  227167. +
  227168. +int mxc_edid_var_to_vic(struct fb_var_screeninfo *var);
  227169. +int mxc_edid_mode_to_vic(const struct fb_videomode *mode);
  227170. +int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
  227171. + unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi);
  227172. +int mxc_edid_parse_ext_blk(unsigned char *edid, struct mxc_edid_cfg *cfg,
  227173. + struct fb_monspecs *specs);
  227174. +#endif
  227175. diff -Nur linux-3.14.17/include/video/mxc_hdmi.h linux-imx6-3.14/include/video/mxc_hdmi.h
  227176. --- linux-3.14.17/include/video/mxc_hdmi.h 1970-01-01 01:00:00.000000000 +0100
  227177. +++ linux-imx6-3.14/include/video/mxc_hdmi.h 2014-09-11 18:06:14.438087624 +0200
  227178. @@ -0,0 +1,1027 @@
  227179. +/*
  227180. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  227181. + */
  227182. +
  227183. +/*
  227184. + * This program is free software; you can redistribute it and/or modify
  227185. + * it under the terms of the GNU General Public License as published by
  227186. + * the Free Software Foundation; either version 2 of the License, or
  227187. + * (at your option) any later version.
  227188. + *
  227189. + * This program is distributed in the hope that it will be useful,
  227190. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  227191. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  227192. + * GNU General Public License for more details.
  227193. + *
  227194. + * You should have received a copy of the GNU General Public License along
  227195. + * with this program; if not, write to the Free Software Foundation, Inc.,
  227196. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  227197. + */
  227198. +
  227199. +#ifndef __MXC_HDMI_H__
  227200. +#define __MXC_HDMI_H__
  227201. +
  227202. +/*
  227203. + * Hdmi controller registers
  227204. + */
  227205. +
  227206. +/* Identification Registers */
  227207. +#define HDMI_DESIGN_ID 0x0000
  227208. +#define HDMI_REVISION_ID 0x0001
  227209. +#define HDMI_PRODUCT_ID0 0x0002
  227210. +#define HDMI_PRODUCT_ID1 0x0003
  227211. +#define HDMI_CONFIG0_ID 0x0004
  227212. +#define HDMI_CONFIG1_ID 0x0005
  227213. +#define HDMI_CONFIG2_ID 0x0006
  227214. +#define HDMI_CONFIG3_ID 0x0007
  227215. +
  227216. +/* Interrupt Registers */
  227217. +#define HDMI_IH_FC_STAT0 0x0100
  227218. +#define HDMI_IH_FC_STAT1 0x0101
  227219. +#define HDMI_IH_FC_STAT2 0x0102
  227220. +#define HDMI_IH_AS_STAT0 0x0103
  227221. +#define HDMI_IH_PHY_STAT0 0x0104
  227222. +#define HDMI_IH_I2CM_STAT0 0x0105
  227223. +#define HDMI_IH_CEC_STAT0 0x0106
  227224. +#define HDMI_IH_VP_STAT0 0x0107
  227225. +#define HDMI_IH_I2CMPHY_STAT0 0x0108
  227226. +#define HDMI_IH_AHBDMAAUD_STAT0 0x0109
  227227. +
  227228. +#define HDMI_IH_MUTE_FC_STAT0 0x0180
  227229. +#define HDMI_IH_MUTE_FC_STAT1 0x0181
  227230. +#define HDMI_IH_MUTE_FC_STAT2 0x0182
  227231. +#define HDMI_IH_MUTE_AS_STAT0 0x0183
  227232. +#define HDMI_IH_MUTE_PHY_STAT0 0x0184
  227233. +#define HDMI_IH_MUTE_I2CM_STAT0 0x0185
  227234. +#define HDMI_IH_MUTE_CEC_STAT0 0x0186
  227235. +#define HDMI_IH_MUTE_VP_STAT0 0x0187
  227236. +#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188
  227237. +#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189
  227238. +#define HDMI_IH_MUTE 0x01FF
  227239. +
  227240. +/* Video Sample Registers */
  227241. +#define HDMI_TX_INVID0 0x0200
  227242. +#define HDMI_TX_INSTUFFING 0x0201
  227243. +#define HDMI_TX_GYDATA0 0x0202
  227244. +#define HDMI_TX_GYDATA1 0x0203
  227245. +#define HDMI_TX_RCRDATA0 0x0204
  227246. +#define HDMI_TX_RCRDATA1 0x0205
  227247. +#define HDMI_TX_BCBDATA0 0x0206
  227248. +#define HDMI_TX_BCBDATA1 0x0207
  227249. +
  227250. +/* Video Packetizer Registers */
  227251. +#define HDMI_VP_STATUS 0x0800
  227252. +#define HDMI_VP_PR_CD 0x0801
  227253. +#define HDMI_VP_STUFF 0x0802
  227254. +#define HDMI_VP_REMAP 0x0803
  227255. +#define HDMI_VP_CONF 0x0804
  227256. +#define HDMI_VP_STAT 0x0805
  227257. +#define HDMI_VP_INT 0x0806
  227258. +#define HDMI_VP_MASK 0x0807
  227259. +#define HDMI_VP_POL 0x0808
  227260. +
  227261. +/* Frame Composer Registers */
  227262. +#define HDMI_FC_INVIDCONF 0x1000
  227263. +#define HDMI_FC_INHACTV0 0x1001
  227264. +#define HDMI_FC_INHACTV1 0x1002
  227265. +#define HDMI_FC_INHBLANK0 0x1003
  227266. +#define HDMI_FC_INHBLANK1 0x1004
  227267. +#define HDMI_FC_INVACTV0 0x1005
  227268. +#define HDMI_FC_INVACTV1 0x1006
  227269. +#define HDMI_FC_INVBLANK 0x1007
  227270. +#define HDMI_FC_HSYNCINDELAY0 0x1008
  227271. +#define HDMI_FC_HSYNCINDELAY1 0x1009
  227272. +#define HDMI_FC_HSYNCINWIDTH0 0x100A
  227273. +#define HDMI_FC_HSYNCINWIDTH1 0x100B
  227274. +#define HDMI_FC_VSYNCINDELAY 0x100C
  227275. +#define HDMI_FC_VSYNCINWIDTH 0x100D
  227276. +#define HDMI_FC_INFREQ0 0x100E
  227277. +#define HDMI_FC_INFREQ1 0x100F
  227278. +#define HDMI_FC_INFREQ2 0x1010
  227279. +#define HDMI_FC_CTRLDUR 0x1011
  227280. +#define HDMI_FC_EXCTRLDUR 0x1012
  227281. +#define HDMI_FC_EXCTRLSPAC 0x1013
  227282. +#define HDMI_FC_CH0PREAM 0x1014
  227283. +#define HDMI_FC_CH1PREAM 0x1015
  227284. +#define HDMI_FC_CH2PREAM 0x1016
  227285. +#define HDMI_FC_AVICONF3 0x1017
  227286. +#define HDMI_FC_GCP 0x1018
  227287. +#define HDMI_FC_AVICONF0 0x1019
  227288. +#define HDMI_FC_AVICONF1 0x101A
  227289. +#define HDMI_FC_AVICONF2 0x101B
  227290. +#define HDMI_FC_AVIVID 0x101C
  227291. +#define HDMI_FC_AVIETB0 0x101D
  227292. +#define HDMI_FC_AVIETB1 0x101E
  227293. +#define HDMI_FC_AVISBB0 0x101F
  227294. +#define HDMI_FC_AVISBB1 0x1020
  227295. +#define HDMI_FC_AVIELB0 0x1021
  227296. +#define HDMI_FC_AVIELB1 0x1022
  227297. +#define HDMI_FC_AVISRB0 0x1023
  227298. +#define HDMI_FC_AVISRB1 0x1024
  227299. +#define HDMI_FC_AUDICONF0 0x1025
  227300. +#define HDMI_FC_AUDICONF1 0x1026
  227301. +#define HDMI_FC_AUDICONF2 0x1027
  227302. +#define HDMI_FC_AUDICONF3 0x1028
  227303. +#define HDMI_FC_VSDIEEEID0 0x1029
  227304. +#define HDMI_FC_VSDSIZE 0x102A
  227305. +#define HDMI_FC_VSDIEEEID1 0x1030
  227306. +#define HDMI_FC_VSDIEEEID2 0x1031
  227307. +#define HDMI_FC_VSDPAYLOAD0 0x1032
  227308. +#define HDMI_FC_VSDPAYLOAD1 0x1033
  227309. +#define HDMI_FC_VSDPAYLOAD2 0x1034
  227310. +#define HDMI_FC_VSDPAYLOAD3 0x1035
  227311. +#define HDMI_FC_VSDPAYLOAD4 0x1036
  227312. +#define HDMI_FC_VSDPAYLOAD5 0x1037
  227313. +#define HDMI_FC_VSDPAYLOAD6 0x1038
  227314. +#define HDMI_FC_VSDPAYLOAD7 0x1039
  227315. +#define HDMI_FC_VSDPAYLOAD8 0x103A
  227316. +#define HDMI_FC_VSDPAYLOAD9 0x103B
  227317. +#define HDMI_FC_VSDPAYLOAD10 0x103C
  227318. +#define HDMI_FC_VSDPAYLOAD11 0x103D
  227319. +#define HDMI_FC_VSDPAYLOAD12 0x103E
  227320. +#define HDMI_FC_VSDPAYLOAD13 0x103F
  227321. +#define HDMI_FC_VSDPAYLOAD14 0x1040
  227322. +#define HDMI_FC_VSDPAYLOAD15 0x1041
  227323. +#define HDMI_FC_VSDPAYLOAD16 0x1042
  227324. +#define HDMI_FC_VSDPAYLOAD17 0x1043
  227325. +#define HDMI_FC_VSDPAYLOAD18 0x1044
  227326. +#define HDMI_FC_VSDPAYLOAD19 0x1045
  227327. +#define HDMI_FC_VSDPAYLOAD20 0x1046
  227328. +#define HDMI_FC_VSDPAYLOAD21 0x1047
  227329. +#define HDMI_FC_VSDPAYLOAD22 0x1048
  227330. +#define HDMI_FC_VSDPAYLOAD23 0x1049
  227331. +#define HDMI_FC_SPDVENDORNAME0 0x104A
  227332. +#define HDMI_FC_SPDVENDORNAME1 0x104B
  227333. +#define HDMI_FC_SPDVENDORNAME2 0x104C
  227334. +#define HDMI_FC_SPDVENDORNAME3 0x104D
  227335. +#define HDMI_FC_SPDVENDORNAME4 0x104E
  227336. +#define HDMI_FC_SPDVENDORNAME5 0x104F
  227337. +#define HDMI_FC_SPDVENDORNAME6 0x1050
  227338. +#define HDMI_FC_SPDVENDORNAME7 0x1051
  227339. +#define HDMI_FC_SDPPRODUCTNAME0 0x1052
  227340. +#define HDMI_FC_SDPPRODUCTNAME1 0x1053
  227341. +#define HDMI_FC_SDPPRODUCTNAME2 0x1054
  227342. +#define HDMI_FC_SDPPRODUCTNAME3 0x1055
  227343. +#define HDMI_FC_SDPPRODUCTNAME4 0x1056
  227344. +#define HDMI_FC_SDPPRODUCTNAME5 0x1057
  227345. +#define HDMI_FC_SDPPRODUCTNAME6 0x1058
  227346. +#define HDMI_FC_SDPPRODUCTNAME7 0x1059
  227347. +#define HDMI_FC_SDPPRODUCTNAME8 0x105A
  227348. +#define HDMI_FC_SDPPRODUCTNAME9 0x105B
  227349. +#define HDMI_FC_SDPPRODUCTNAME10 0x105C
  227350. +#define HDMI_FC_SDPPRODUCTNAME11 0x105D
  227351. +#define HDMI_FC_SDPPRODUCTNAME12 0x105E
  227352. +#define HDMI_FC_SDPPRODUCTNAME13 0x105F
  227353. +#define HDMI_FC_SDPPRODUCTNAME14 0x1060
  227354. +#define HDMI_FC_SPDPRODUCTNAME15 0x1061
  227355. +#define HDMI_FC_SPDDEVICEINF 0x1062
  227356. +#define HDMI_FC_AUDSCONF 0x1063
  227357. +#define HDMI_FC_AUDSSTAT 0x1064
  227358. +#define HDMI_FC_DATACH0FILL 0x1070
  227359. +#define HDMI_FC_DATACH1FILL 0x1071
  227360. +#define HDMI_FC_DATACH2FILL 0x1072
  227361. +#define HDMI_FC_CTRLQHIGH 0x1073
  227362. +#define HDMI_FC_CTRLQLOW 0x1074
  227363. +#define HDMI_FC_ACP0 0x1075
  227364. +#define HDMI_FC_ACP28 0x1076
  227365. +#define HDMI_FC_ACP27 0x1077
  227366. +#define HDMI_FC_ACP26 0x1078
  227367. +#define HDMI_FC_ACP25 0x1079
  227368. +#define HDMI_FC_ACP24 0x107A
  227369. +#define HDMI_FC_ACP23 0x107B
  227370. +#define HDMI_FC_ACP22 0x107C
  227371. +#define HDMI_FC_ACP21 0x107D
  227372. +#define HDMI_FC_ACP20 0x107E
  227373. +#define HDMI_FC_ACP19 0x107F
  227374. +#define HDMI_FC_ACP18 0x1080
  227375. +#define HDMI_FC_ACP17 0x1081
  227376. +#define HDMI_FC_ACP16 0x1082
  227377. +#define HDMI_FC_ACP15 0x1083
  227378. +#define HDMI_FC_ACP14 0x1084
  227379. +#define HDMI_FC_ACP13 0x1085
  227380. +#define HDMI_FC_ACP12 0x1086
  227381. +#define HDMI_FC_ACP11 0x1087
  227382. +#define HDMI_FC_ACP10 0x1088
  227383. +#define HDMI_FC_ACP9 0x1089
  227384. +#define HDMI_FC_ACP8 0x108A
  227385. +#define HDMI_FC_ACP7 0x108B
  227386. +#define HDMI_FC_ACP6 0x108C
  227387. +#define HDMI_FC_ACP5 0x108D
  227388. +#define HDMI_FC_ACP4 0x108E
  227389. +#define HDMI_FC_ACP3 0x108F
  227390. +#define HDMI_FC_ACP2 0x1090
  227391. +#define HDMI_FC_ACP1 0x1091
  227392. +#define HDMI_FC_ISCR1_0 0x1092
  227393. +#define HDMI_FC_ISCR1_16 0x1093
  227394. +#define HDMI_FC_ISCR1_15 0x1094
  227395. +#define HDMI_FC_ISCR1_14 0x1095
  227396. +#define HDMI_FC_ISCR1_13 0x1096
  227397. +#define HDMI_FC_ISCR1_12 0x1097
  227398. +#define HDMI_FC_ISCR1_11 0x1098
  227399. +#define HDMI_FC_ISCR1_10 0x1099
  227400. +#define HDMI_FC_ISCR1_9 0x109A
  227401. +#define HDMI_FC_ISCR1_8 0x109B
  227402. +#define HDMI_FC_ISCR1_7 0x109C
  227403. +#define HDMI_FC_ISCR1_6 0x109D
  227404. +#define HDMI_FC_ISCR1_5 0x109E
  227405. +#define HDMI_FC_ISCR1_4 0x109F
  227406. +#define HDMI_FC_ISCR1_3 0x10A0
  227407. +#define HDMI_FC_ISCR1_2 0x10A1
  227408. +#define HDMI_FC_ISCR1_1 0x10A2
  227409. +#define HDMI_FC_ISCR2_15 0x10A3
  227410. +#define HDMI_FC_ISCR2_14 0x10A4
  227411. +#define HDMI_FC_ISCR2_13 0x10A5
  227412. +#define HDMI_FC_ISCR2_12 0x10A6
  227413. +#define HDMI_FC_ISCR2_11 0x10A7
  227414. +#define HDMI_FC_ISCR2_10 0x10A8
  227415. +#define HDMI_FC_ISCR2_9 0x10A9
  227416. +#define HDMI_FC_ISCR2_8 0x10AA
  227417. +#define HDMI_FC_ISCR2_7 0x10AB
  227418. +#define HDMI_FC_ISCR2_6 0x10AC
  227419. +#define HDMI_FC_ISCR2_5 0x10AD
  227420. +#define HDMI_FC_ISCR2_4 0x10AE
  227421. +#define HDMI_FC_ISCR2_3 0x10AF
  227422. +#define HDMI_FC_ISCR2_2 0x10B0
  227423. +#define HDMI_FC_ISCR2_1 0x10B1
  227424. +#define HDMI_FC_ISCR2_0 0x10B2
  227425. +#define HDMI_FC_DATAUTO0 0x10B3
  227426. +#define HDMI_FC_DATAUTO1 0x10B4
  227427. +#define HDMI_FC_DATAUTO2 0x10B5
  227428. +#define HDMI_FC_DATMAN 0x10B6
  227429. +#define HDMI_FC_DATAUTO3 0x10B7
  227430. +#define HDMI_FC_RDRB0 0x10B8
  227431. +#define HDMI_FC_RDRB1 0x10B9
  227432. +#define HDMI_FC_RDRB2 0x10BA
  227433. +#define HDMI_FC_RDRB3 0x10BB
  227434. +#define HDMI_FC_RDRB4 0x10BC
  227435. +#define HDMI_FC_RDRB5 0x10BD
  227436. +#define HDMI_FC_RDRB6 0x10BE
  227437. +#define HDMI_FC_RDRB7 0x10BF
  227438. +#define HDMI_FC_STAT0 0x10D0
  227439. +#define HDMI_FC_INT0 0x10D1
  227440. +#define HDMI_FC_MASK0 0x10D2
  227441. +#define HDMI_FC_POL0 0x10D3
  227442. +#define HDMI_FC_STAT1 0x10D4
  227443. +#define HDMI_FC_INT1 0x10D5
  227444. +#define HDMI_FC_MASK1 0x10D6
  227445. +#define HDMI_FC_POL1 0x10D7
  227446. +#define HDMI_FC_STAT2 0x10D8
  227447. +#define HDMI_FC_INT2 0x10D9
  227448. +#define HDMI_FC_MASK2 0x10DA
  227449. +#define HDMI_FC_POL2 0x10DB
  227450. +#define HDMI_FC_PRCONF 0x10E0
  227451. +
  227452. +#define HDMI_FC_GMD_STAT 0x1100
  227453. +#define HDMI_FC_GMD_EN 0x1101
  227454. +#define HDMI_FC_GMD_UP 0x1102
  227455. +#define HDMI_FC_GMD_CONF 0x1103
  227456. +#define HDMI_FC_GMD_HB 0x1104
  227457. +#define HDMI_FC_GMD_PB0 0x1105
  227458. +#define HDMI_FC_GMD_PB1 0x1106
  227459. +#define HDMI_FC_GMD_PB2 0x1107
  227460. +#define HDMI_FC_GMD_PB3 0x1108
  227461. +#define HDMI_FC_GMD_PB4 0x1109
  227462. +#define HDMI_FC_GMD_PB5 0x110A
  227463. +#define HDMI_FC_GMD_PB6 0x110B
  227464. +#define HDMI_FC_GMD_PB7 0x110C
  227465. +#define HDMI_FC_GMD_PB8 0x110D
  227466. +#define HDMI_FC_GMD_PB9 0x110E
  227467. +#define HDMI_FC_GMD_PB10 0x110F
  227468. +#define HDMI_FC_GMD_PB11 0x1110
  227469. +#define HDMI_FC_GMD_PB12 0x1111
  227470. +#define HDMI_FC_GMD_PB13 0x1112
  227471. +#define HDMI_FC_GMD_PB14 0x1113
  227472. +#define HDMI_FC_GMD_PB15 0x1114
  227473. +#define HDMI_FC_GMD_PB16 0x1115
  227474. +#define HDMI_FC_GMD_PB17 0x1116
  227475. +#define HDMI_FC_GMD_PB18 0x1117
  227476. +#define HDMI_FC_GMD_PB19 0x1118
  227477. +#define HDMI_FC_GMD_PB20 0x1119
  227478. +#define HDMI_FC_GMD_PB21 0x111A
  227479. +#define HDMI_FC_GMD_PB22 0x111B
  227480. +#define HDMI_FC_GMD_PB23 0x111C
  227481. +#define HDMI_FC_GMD_PB24 0x111D
  227482. +#define HDMI_FC_GMD_PB25 0x111E
  227483. +#define HDMI_FC_GMD_PB26 0x111F
  227484. +#define HDMI_FC_GMD_PB27 0x1120
  227485. +
  227486. +#define HDMI_FC_DBGFORCE 0x1200
  227487. +#define HDMI_FC_DBGAUD0CH0 0x1201
  227488. +#define HDMI_FC_DBGAUD1CH0 0x1202
  227489. +#define HDMI_FC_DBGAUD2CH0 0x1203
  227490. +#define HDMI_FC_DBGAUD0CH1 0x1204
  227491. +#define HDMI_FC_DBGAUD1CH1 0x1205
  227492. +#define HDMI_FC_DBGAUD2CH1 0x1206
  227493. +#define HDMI_FC_DBGAUD0CH2 0x1207
  227494. +#define HDMI_FC_DBGAUD1CH2 0x1208
  227495. +#define HDMI_FC_DBGAUD2CH2 0x1209
  227496. +#define HDMI_FC_DBGAUD0CH3 0x120A
  227497. +#define HDMI_FC_DBGAUD1CH3 0x120B
  227498. +#define HDMI_FC_DBGAUD2CH3 0x120C
  227499. +#define HDMI_FC_DBGAUD0CH4 0x120D
  227500. +#define HDMI_FC_DBGAUD1CH4 0x120E
  227501. +#define HDMI_FC_DBGAUD2CH4 0x120F
  227502. +#define HDMI_FC_DBGAUD0CH5 0x1210
  227503. +#define HDMI_FC_DBGAUD1CH5 0x1211
  227504. +#define HDMI_FC_DBGAUD2CH5 0x1212
  227505. +#define HDMI_FC_DBGAUD0CH6 0x1213
  227506. +#define HDMI_FC_DBGAUD1CH6 0x1214
  227507. +#define HDMI_FC_DBGAUD2CH6 0x1215
  227508. +#define HDMI_FC_DBGAUD0CH7 0x1216
  227509. +#define HDMI_FC_DBGAUD1CH7 0x1217
  227510. +#define HDMI_FC_DBGAUD2CH7 0x1218
  227511. +#define HDMI_FC_DBGTMDS0 0x1219
  227512. +#define HDMI_FC_DBGTMDS1 0x121A
  227513. +#define HDMI_FC_DBGTMDS2 0x121B
  227514. +
  227515. +/* HDMI Source PHY Registers */
  227516. +#define HDMI_PHY_CONF0 0x3000
  227517. +#define HDMI_PHY_TST0 0x3001
  227518. +#define HDMI_PHY_TST1 0x3002
  227519. +#define HDMI_PHY_TST2 0x3003
  227520. +#define HDMI_PHY_STAT0 0x3004
  227521. +#define HDMI_PHY_INT0 0x3005
  227522. +#define HDMI_PHY_MASK0 0x3006
  227523. +#define HDMI_PHY_POL0 0x3007
  227524. +
  227525. +/* HDMI Master PHY Registers */
  227526. +#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020
  227527. +#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021
  227528. +#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022
  227529. +#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023
  227530. +#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024
  227531. +#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025
  227532. +#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026
  227533. +#define HDMI_PHY_I2CM_INT_ADDR 0x3027
  227534. +#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028
  227535. +#define HDMI_PHY_I2CM_DIV_ADDR 0x3029
  227536. +#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a
  227537. +#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b
  227538. +#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c
  227539. +#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d
  227540. +#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e
  227541. +#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f
  227542. +#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030
  227543. +#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031
  227544. +#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032
  227545. +
  227546. +/* Audio Sampler Registers */
  227547. +#define HDMI_AUD_CONF0 0x3100
  227548. +#define HDMI_AUD_CONF1 0x3101
  227549. +#define HDMI_AUD_INT 0x3102
  227550. +#define HDMI_AUD_CONF2 0x3103
  227551. +#define HDMI_AUD_N1 0x3200
  227552. +#define HDMI_AUD_N2 0x3201
  227553. +#define HDMI_AUD_N3 0x3202
  227554. +#define HDMI_AUD_CTS1 0x3203
  227555. +#define HDMI_AUD_CTS2 0x3204
  227556. +#define HDMI_AUD_CTS3 0x3205
  227557. +#define HDMI_AUD_INPUTCLKFS 0x3206
  227558. +#define HDMI_AUD_SPDIFINT 0x3302
  227559. +#define HDMI_AUD_CONF0_HBR 0x3400
  227560. +#define HDMI_AUD_HBR_STATUS 0x3401
  227561. +#define HDMI_AUD_HBR_INT 0x3402
  227562. +#define HDMI_AUD_HBR_POL 0x3403
  227563. +#define HDMI_AUD_HBR_MASK 0x3404
  227564. +
  227565. +/* Generic Parallel Audio Interface Registers */
  227566. +/* Not used as GPAUD interface is not enabled in hw */
  227567. +#define HDMI_GP_CONF0 0x3500
  227568. +#define HDMI_GP_CONF1 0x3501
  227569. +#define HDMI_GP_CONF2 0x3502
  227570. +#define HDMI_GP_STAT 0x3503
  227571. +#define HDMI_GP_INT 0x3504
  227572. +#define HDMI_GP_MASK 0x3505
  227573. +#define HDMI_GP_POL 0x3506
  227574. +
  227575. +/* Audio DMA Registers */
  227576. +#define HDMI_AHB_DMA_CONF0 0x3600
  227577. +#define HDMI_AHB_DMA_START 0x3601
  227578. +#define HDMI_AHB_DMA_STOP 0x3602
  227579. +#define HDMI_AHB_DMA_THRSLD 0x3603
  227580. +#define HDMI_AHB_DMA_STRADDR0 0x3604
  227581. +#define HDMI_AHB_DMA_STRADDR1 0x3605
  227582. +#define HDMI_AHB_DMA_STRADDR2 0x3606
  227583. +#define HDMI_AHB_DMA_STRADDR3 0x3607
  227584. +#define HDMI_AHB_DMA_STPADDR0 0x3608
  227585. +#define HDMI_AHB_DMA_STPADDR1 0x3609
  227586. +#define HDMI_AHB_DMA_STPADDR2 0x360a
  227587. +#define HDMI_AHB_DMA_STPADDR3 0x360b
  227588. +#define HDMI_AHB_DMA_BSTADDR0 0x360c
  227589. +#define HDMI_AHB_DMA_BSTADDR1 0x360d
  227590. +#define HDMI_AHB_DMA_BSTADDR2 0x360e
  227591. +#define HDMI_AHB_DMA_BSTADDR3 0x360f
  227592. +#define HDMI_AHB_DMA_MBLENGTH0 0x3610
  227593. +#define HDMI_AHB_DMA_MBLENGTH1 0x3611
  227594. +#define HDMI_AHB_DMA_STAT 0x3612
  227595. +#define HDMI_AHB_DMA_INT 0x3613
  227596. +#define HDMI_AHB_DMA_MASK 0x3614
  227597. +#define HDMI_AHB_DMA_POL 0x3615
  227598. +#define HDMI_AHB_DMA_CONF1 0x3616
  227599. +#define HDMI_AHB_DMA_BUFFSTAT 0x3617
  227600. +#define HDMI_AHB_DMA_BUFFINT 0x3618
  227601. +#define HDMI_AHB_DMA_BUFFMASK 0x3619
  227602. +#define HDMI_AHB_DMA_BUFFPOL 0x361a
  227603. +
  227604. +/* Main Controller Registers */
  227605. +#define HDMI_MC_SFRDIV 0x4000
  227606. +#define HDMI_MC_CLKDIS 0x4001
  227607. +#define HDMI_MC_SWRSTZ 0x4002
  227608. +#define HDMI_MC_OPCTRL 0x4003
  227609. +#define HDMI_MC_FLOWCTRL 0x4004
  227610. +#define HDMI_MC_PHYRSTZ 0x4005
  227611. +#define HDMI_MC_LOCKONCLOCK 0x4006
  227612. +#define HDMI_MC_HEACPHY_RST 0x4007
  227613. +
  227614. +/* Color Space Converter Registers */
  227615. +#define HDMI_CSC_CFG 0x4100
  227616. +#define HDMI_CSC_SCALE 0x4101
  227617. +#define HDMI_CSC_COEF_A1_MSB 0x4102
  227618. +#define HDMI_CSC_COEF_A1_LSB 0x4103
  227619. +#define HDMI_CSC_COEF_A2_MSB 0x4104
  227620. +#define HDMI_CSC_COEF_A2_LSB 0x4105
  227621. +#define HDMI_CSC_COEF_A3_MSB 0x4106
  227622. +#define HDMI_CSC_COEF_A3_LSB 0x4107
  227623. +#define HDMI_CSC_COEF_A4_MSB 0x4108
  227624. +#define HDMI_CSC_COEF_A4_LSB 0x4109
  227625. +#define HDMI_CSC_COEF_B1_MSB 0x410A
  227626. +#define HDMI_CSC_COEF_B1_LSB 0x410B
  227627. +#define HDMI_CSC_COEF_B2_MSB 0x410C
  227628. +#define HDMI_CSC_COEF_B2_LSB 0x410D
  227629. +#define HDMI_CSC_COEF_B3_MSB 0x410E
  227630. +#define HDMI_CSC_COEF_B3_LSB 0x410F
  227631. +#define HDMI_CSC_COEF_B4_MSB 0x4110
  227632. +#define HDMI_CSC_COEF_B4_LSB 0x4111
  227633. +#define HDMI_CSC_COEF_C1_MSB 0x4112
  227634. +#define HDMI_CSC_COEF_C1_LSB 0x4113
  227635. +#define HDMI_CSC_COEF_C2_MSB 0x4114
  227636. +#define HDMI_CSC_COEF_C2_LSB 0x4115
  227637. +#define HDMI_CSC_COEF_C3_MSB 0x4116
  227638. +#define HDMI_CSC_COEF_C3_LSB 0x4117
  227639. +#define HDMI_CSC_COEF_C4_MSB 0x4118
  227640. +#define HDMI_CSC_COEF_C4_LSB 0x4119
  227641. +
  227642. +/* HDCP Interrupt Registers */
  227643. +#define HDMI_A_APIINTCLR 0x5006
  227644. +#define HDMI_A_APIINTSTAT 0x5007
  227645. +#define HDMI_A_APIINTMSK 0x5008
  227646. +
  227647. +/* CEC Engine Registers */
  227648. +#define HDMI_CEC_CTRL 0x7D00
  227649. +#define HDMI_CEC_STAT 0x7D01
  227650. +#define HDMI_CEC_MASK 0x7D02
  227651. +#define HDMI_CEC_POLARITY 0x7D03
  227652. +#define HDMI_CEC_INT 0x7D04
  227653. +#define HDMI_CEC_ADDR_L 0x7D05
  227654. +#define HDMI_CEC_ADDR_H 0x7D06
  227655. +#define HDMI_CEC_TX_CNT 0x7D07
  227656. +#define HDMI_CEC_RX_CNT 0x7D08
  227657. +#define HDMI_CEC_TX_DATA0 0x7D10
  227658. +#define HDMI_CEC_TX_DATA1 0x7D11
  227659. +#define HDMI_CEC_TX_DATA2 0x7D12
  227660. +#define HDMI_CEC_TX_DATA3 0x7D13
  227661. +#define HDMI_CEC_TX_DATA4 0x7D14
  227662. +#define HDMI_CEC_TX_DATA5 0x7D15
  227663. +#define HDMI_CEC_TX_DATA6 0x7D16
  227664. +#define HDMI_CEC_TX_DATA7 0x7D17
  227665. +#define HDMI_CEC_TX_DATA8 0x7D18
  227666. +#define HDMI_CEC_TX_DATA9 0x7D19
  227667. +#define HDMI_CEC_TX_DATA10 0x7D1a
  227668. +#define HDMI_CEC_TX_DATA11 0x7D1b
  227669. +#define HDMI_CEC_TX_DATA12 0x7D1c
  227670. +#define HDMI_CEC_TX_DATA13 0x7D1d
  227671. +#define HDMI_CEC_TX_DATA14 0x7D1e
  227672. +#define HDMI_CEC_TX_DATA15 0x7D1f
  227673. +#define HDMI_CEC_RX_DATA0 0x7D20
  227674. +#define HDMI_CEC_RX_DATA1 0x7D21
  227675. +#define HDMI_CEC_RX_DATA2 0x7D22
  227676. +#define HDMI_CEC_RX_DATA3 0x7D23
  227677. +#define HDMI_CEC_RX_DATA4 0x7D24
  227678. +#define HDMI_CEC_RX_DATA5 0x7D25
  227679. +#define HDMI_CEC_RX_DATA6 0x7D26
  227680. +#define HDMI_CEC_RX_DATA7 0x7D27
  227681. +#define HDMI_CEC_RX_DATA8 0x7D28
  227682. +#define HDMI_CEC_RX_DATA9 0x7D29
  227683. +#define HDMI_CEC_RX_DATA10 0x7D2a
  227684. +#define HDMI_CEC_RX_DATA11 0x7D2b
  227685. +#define HDMI_CEC_RX_DATA12 0x7D2c
  227686. +#define HDMI_CEC_RX_DATA13 0x7D2d
  227687. +#define HDMI_CEC_RX_DATA14 0x7D2e
  227688. +#define HDMI_CEC_RX_DATA15 0x7D2f
  227689. +#define HDMI_CEC_LOCK 0x7D30
  227690. +#define HDMI_CEC_WKUPCTRL 0x7D31
  227691. +
  227692. +/* I2C Master Registers (E-DDC) */
  227693. +#define HDMI_I2CM_SLAVE 0x7E00
  227694. +#define HDMI_I2CM_ADDRESS 0x7E01
  227695. +#define HDMI_I2CM_DATAO 0x7E02
  227696. +#define HDMI_I2CM_DATAI 0x7E03
  227697. +#define HDMI_I2CM_OPERATION 0x7E04
  227698. +#define HDMI_I2CM_INT 0x7E05
  227699. +#define HDMI_I2CM_CTLINT 0x7E06
  227700. +#define HDMI_I2CM_DIV 0x7E07
  227701. +#define HDMI_I2CM_SEGADDR 0x7E08
  227702. +#define HDMI_I2CM_SOFTRSTZ 0x7E09
  227703. +#define HDMI_I2CM_SEGPTR 0x7E0A
  227704. +#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B
  227705. +#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C
  227706. +#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D
  227707. +#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E
  227708. +#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F
  227709. +#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10
  227710. +#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11
  227711. +#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12
  227712. +
  227713. +/* Random Number Generator Registers (RNG) */
  227714. +#define HDMI_RNG_BASE 0x8000
  227715. +
  227716. +
  227717. +/*
  227718. + * Register field definitions
  227719. + */
  227720. +enum {
  227721. +/* IH_FC_INT2 field values */
  227722. + HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
  227723. + HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
  227724. + HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  227725. +
  227726. +/* IH_FC_STAT2 field values */
  227727. + HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03,
  227728. + HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  227729. + HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  227730. +
  227731. +/* IH_PHY_STAT0 field values */
  227732. + HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20,
  227733. + HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10,
  227734. + HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8,
  227735. + HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4,
  227736. + HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
  227737. + HDMI_IH_PHY_STAT0_HPD = 0x1,
  227738. +
  227739. +/* IH_CEC_STAT0 field values */
  227740. + HDMI_IH_CEC_STAT0_WAKEUP = 0x40,
  227741. + HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20,
  227742. + HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10,
  227743. + HDMI_IH_CEC_STAT0_ARB_LOST = 0x8,
  227744. + HDMI_IH_CEC_STAT0_NACK = 0x4,
  227745. + HDMI_IH_CEC_STAT0_EOM = 0x2,
  227746. + HDMI_IH_CEC_STAT0_DONE = 0x1,
  227747. +
  227748. +
  227749. +/* IH_MUTE_I2CMPHY_STAT0 field values */
  227750. + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
  227751. + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
  227752. +
  227753. +/* IH_PHY_STAT0 field values */
  227754. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20,
  227755. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10,
  227756. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8,
  227757. + HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4,
  227758. + HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,
  227759. + HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1,
  227760. +
  227761. +/* IH and IH_MUTE convenience macro RX_SENSE | HPD*/
  227762. + HDMI_DVI_IH_STAT = 0x3D,
  227763. +
  227764. +
  227765. +/* IH_AHBDMAAUD_STAT0 field values */
  227766. + HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
  227767. + HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
  227768. + HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08,
  227769. + HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04,
  227770. + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
  227771. + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
  227772. +
  227773. +/* IH_MUTE_FC_STAT2 field values */
  227774. + HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03,
  227775. + HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  227776. + HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  227777. +
  227778. +/* IH_MUTE_AHBDMAAUD_STAT0 field values */
  227779. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20,
  227780. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10,
  227781. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08,
  227782. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04,
  227783. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
  227784. + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
  227785. +
  227786. +/* IH_MUTE field values */
  227787. + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2,
  227788. + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1,
  227789. +
  227790. +/* TX_INVID0 field values */
  227791. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80,
  227792. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80,
  227793. + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00,
  227794. + HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F,
  227795. + HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0,
  227796. +
  227797. +/* TX_INSTUFFING field values */
  227798. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4,
  227799. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4,
  227800. + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0,
  227801. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2,
  227802. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2,
  227803. + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0,
  227804. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1,
  227805. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1,
  227806. + HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0,
  227807. +
  227808. +/* VP_PR_CD field values */
  227809. + HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0,
  227810. + HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4,
  227811. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F,
  227812. + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0,
  227813. +
  227814. +/* VP_STUFF field values */
  227815. + HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20,
  227816. + HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5,
  227817. + HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10,
  227818. + HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4,
  227819. + HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8,
  227820. + HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3,
  227821. + HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4,
  227822. + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4,
  227823. + HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0,
  227824. + HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2,
  227825. + HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2,
  227826. + HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0,
  227827. + HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1,
  227828. + HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1,
  227829. + HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0,
  227830. +
  227831. +/* VP_CONF field values */
  227832. + HDMI_VP_CONF_BYPASS_EN_MASK = 0x40,
  227833. + HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40,
  227834. + HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00,
  227835. + HDMI_VP_CONF_PP_EN_ENMASK = 0x20,
  227836. + HDMI_VP_CONF_PP_EN_ENABLE = 0x20,
  227837. + HDMI_VP_CONF_PP_EN_DISABLE = 0x00,
  227838. + HDMI_VP_CONF_PR_EN_MASK = 0x10,
  227839. + HDMI_VP_CONF_PR_EN_ENABLE = 0x10,
  227840. + HDMI_VP_CONF_PR_EN_DISABLE = 0x00,
  227841. + HDMI_VP_CONF_YCC422_EN_MASK = 0x8,
  227842. + HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8,
  227843. + HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0,
  227844. + HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4,
  227845. + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4,
  227846. + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0,
  227847. + HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3,
  227848. + HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3,
  227849. + HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1,
  227850. + HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0,
  227851. +
  227852. +/* VP_REMAP field values */
  227853. + HDMI_VP_REMAP_MASK = 0x3,
  227854. + HDMI_VP_REMAP_YCC422_24bit = 0x2,
  227855. + HDMI_VP_REMAP_YCC422_20bit = 0x1,
  227856. + HDMI_VP_REMAP_YCC422_16bit = 0x0,
  227857. +
  227858. +/* FC_INVIDCONF field values */
  227859. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40,
  227860. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40,
  227861. + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
  227862. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20,
  227863. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20,
  227864. + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
  227865. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10,
  227866. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10,
  227867. + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00,
  227868. + HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8,
  227869. + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8,
  227870. + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0,
  227871. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2,
  227872. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2,
  227873. + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0,
  227874. + HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1,
  227875. + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
  227876. + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
  227877. +
  227878. +/* FC_AUDICONF0 field values */
  227879. + HDMI_FC_AUDICONF0_CC_OFFSET = 4,
  227880. + HDMI_FC_AUDICONF0_CC_MASK = 0x70,
  227881. + HDMI_FC_AUDICONF0_CT_OFFSET = 0,
  227882. + HDMI_FC_AUDICONF0_CT_MASK = 0xF,
  227883. +
  227884. +/* FC_AUDICONF1 field values */
  227885. + HDMI_FC_AUDICONF1_SS_OFFSET = 3,
  227886. + HDMI_FC_AUDICONF1_SS_MASK = 0x18,
  227887. + HDMI_FC_AUDICONF1_SF_OFFSET = 0,
  227888. + HDMI_FC_AUDICONF1_SF_MASK = 0x7,
  227889. +
  227890. +/* FC_AUDICONF3 field values */
  227891. + HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5,
  227892. + HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60,
  227893. + HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4,
  227894. + HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10,
  227895. + HDMI_FC_AUDICONF3_LSV_OFFSET = 0,
  227896. + HDMI_FC_AUDICONF3_LSV_MASK = 0xF,
  227897. +
  227898. +/* FC_AUDSCHNLS0 field values */
  227899. + HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4,
  227900. + HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30,
  227901. + HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0,
  227902. + HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01,
  227903. +
  227904. +/* FC_AUDSCHNLS3-6 field values */
  227905. + HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0,
  227906. + HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f,
  227907. + HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4,
  227908. + HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0,
  227909. + HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0,
  227910. + HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f,
  227911. + HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4,
  227912. + HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0,
  227913. +
  227914. + HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0,
  227915. + HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f,
  227916. + HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4,
  227917. + HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0,
  227918. + HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0,
  227919. + HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f,
  227920. + HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4,
  227921. + HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0,
  227922. +
  227923. +/* HDMI_FC_AUDSCHNLS7 field values */
  227924. + HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
  227925. + HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
  227926. +
  227927. +/* HDMI_FC_AUDSCHNLS8 field values */
  227928. + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
  227929. + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4,
  227930. + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f,
  227931. + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0,
  227932. +
  227933. +/* FC_AUDSCONF field values */
  227934. + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0,
  227935. + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4,
  227936. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1,
  227937. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0,
  227938. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1,
  227939. + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0,
  227940. +
  227941. +/* FC_STAT2 field values */
  227942. + HDMI_FC_STAT2_OVERFLOW_MASK = 0x03,
  227943. + HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
  227944. + HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  227945. +
  227946. +/* FC_INT2 field values */
  227947. + HDMI_FC_INT2_OVERFLOW_MASK = 0x03,
  227948. + HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
  227949. + HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
  227950. +
  227951. +/* FC_MASK2 field values */
  227952. + HDMI_FC_MASK2_OVERFLOW_MASK = 0x03,
  227953. + HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02,
  227954. + HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01,
  227955. +
  227956. +/* FC_PRCONF field values */
  227957. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0,
  227958. + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4,
  227959. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
  227960. + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,
  227961. +
  227962. +/* FC_AVICONF0-FC_AVICONF3 field values */
  227963. + HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
  227964. + HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
  227965. + HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01,
  227966. + HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02,
  227967. + HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40,
  227968. + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40,
  227969. + HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00,
  227970. + HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C,
  227971. + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00,
  227972. + HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04,
  227973. + HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08,
  227974. + HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C,
  227975. + HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30,
  227976. + HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10,
  227977. + HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20,
  227978. + HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00,
  227979. +
  227980. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F,
  227981. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08,
  227982. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09,
  227983. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A,
  227984. + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B,
  227985. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30,
  227986. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00,
  227987. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10,
  227988. + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20,
  227989. + HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0,
  227990. + HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00,
  227991. + HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40,
  227992. + HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80,
  227993. + HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0,
  227994. +
  227995. + HDMI_FC_AVICONF2_SCALING_MASK = 0x03,
  227996. + HDMI_FC_AVICONF2_SCALING_NONE = 0x00,
  227997. + HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01,
  227998. + HDMI_FC_AVICONF2_SCALING_VERT = 0x02,
  227999. + HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03,
  228000. + HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C,
  228001. + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00,
  228002. + HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04,
  228003. + HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08,
  228004. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70,
  228005. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00,
  228006. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10,
  228007. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20,
  228008. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30,
  228009. + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40,
  228010. + HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80,
  228011. + HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00,
  228012. + HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80,
  228013. +
  228014. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03,
  228015. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00,
  228016. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01,
  228017. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02,
  228018. + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03,
  228019. + HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C,
  228020. + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
  228021. + HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
  228022. +
  228023. +/* FC_DBGFORCE field values */
  228024. + HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
  228025. + HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
  228026. +
  228027. +/* PHY_CONF0 field values */
  228028. + HDMI_PHY_CONF0_PDZ_MASK = 0x80,
  228029. + HDMI_PHY_CONF0_PDZ_OFFSET = 7,
  228030. + HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
  228031. + HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
  228032. + HDMI_PHY_CONF0_SPARECTRL = 0x20,
  228033. + HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
  228034. + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
  228035. + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
  228036. + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3,
  228037. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4,
  228038. + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2,
  228039. + HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2,
  228040. + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1,
  228041. + HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1,
  228042. + HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0,
  228043. +
  228044. +/* PHY_TST0 field values */
  228045. + HDMI_PHY_TST0_TSTCLR_MASK = 0x20,
  228046. + HDMI_PHY_TST0_TSTCLR_OFFSET = 5,
  228047. + HDMI_PHY_TST0_TSTEN_MASK = 0x10,
  228048. + HDMI_PHY_TST0_TSTEN_OFFSET = 4,
  228049. + HDMI_PHY_TST0_TSTCLK_MASK = 0x1,
  228050. + HDMI_PHY_TST0_TSTCLK_OFFSET = 0,
  228051. +
  228052. +/* PHY_STAT0 field values */
  228053. + HDMI_PHY_RX_SENSE3 = 0x80,
  228054. + HDMI_PHY_RX_SENSE2 = 0x40,
  228055. + HDMI_PHY_RX_SENSE1 = 0x20,
  228056. + HDMI_PHY_RX_SENSE0 = 0x10,
  228057. + HDMI_PHY_HPD = 0x02,
  228058. + HDMI_PHY_TX_PHY_LOCK = 0x01,
  228059. +
  228060. +/* HDMI STAT convenience RX_SENSE | HPD */
  228061. + HDMI_DVI_STAT = 0xF2,
  228062. +
  228063. +/* PHY_I2CM_SLAVE_ADDR field values */
  228064. + HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
  228065. + HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
  228066. +
  228067. +/* PHY_I2CM_OPERATION_ADDR field values */
  228068. + HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10,
  228069. + HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1,
  228070. +
  228071. +/* HDMI_PHY_I2CM_INT_ADDR */
  228072. + HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08,
  228073. + HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04,
  228074. +
  228075. +/* HDMI_PHY_I2CM_CTLINT_ADDR */
  228076. + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80,
  228077. + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40,
  228078. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08,
  228079. + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04,
  228080. +
  228081. +/* AUD_CTS3 field values */
  228082. + HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
  228083. + HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
  228084. + HDMI_AUD_CTS3_N_SHIFT_1 = 0,
  228085. + HDMI_AUD_CTS3_N_SHIFT_16 = 0x20,
  228086. + HDMI_AUD_CTS3_N_SHIFT_32 = 0x40,
  228087. + HDMI_AUD_CTS3_N_SHIFT_64 = 0x60,
  228088. + HDMI_AUD_CTS3_N_SHIFT_128 = 0x80,
  228089. + HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0,
  228090. + /* note that the CTS3 MANUAL bit has been removed
  228091. + from our part. Can't set it, will read as 0. */
  228092. + HDMI_AUD_CTS3_CTS_MANUAL = 0x10,
  228093. + HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f,
  228094. +
  228095. +/* AHB_DMA_CONF0 field values */
  228096. + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7,
  228097. + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,
  228098. + HDMI_AHB_DMA_CONF0_HBR_OFFSET = 4,
  228099. + HDMI_AHB_DMA_CONF0_HBR_MASK = 0x10,
  228100. + HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3,
  228101. + HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08,
  228102. + HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1,
  228103. + HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06,
  228104. + HDMI_AHB_DMA_CONF0_INCR4 = 0x0,
  228105. + HDMI_AHB_DMA_CONF0_INCR8 = 0x2,
  228106. + HDMI_AHB_DMA_CONF0_INCR16 = 0x4,
  228107. + HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1,
  228108. +
  228109. +/* HDMI_AHB_DMA_START field values */
  228110. + HDMI_AHB_DMA_START_START_OFFSET = 0,
  228111. + HDMI_AHB_DMA_START_START_MASK = 0x01,
  228112. +
  228113. +/* HDMI_AHB_DMA_STOP field values */
  228114. + HDMI_AHB_DMA_STOP_STOP_OFFSET = 0,
  228115. + HDMI_AHB_DMA_STOP_STOP_MASK = 0x01,
  228116. +
  228117. +/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */
  228118. + HDMI_AHB_DMA_DONE = 0x80,
  228119. + HDMI_AHB_DMA_RETRY_SPLIT = 0x40,
  228120. + HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20,
  228121. + HDMI_AHB_DMA_ERROR = 0x10,
  228122. + HDMI_AHB_DMA_FIFO_THREMPTY = 0x04,
  228123. + HDMI_AHB_DMA_FIFO_FULL = 0x02,
  228124. + HDMI_AHB_DMA_FIFO_EMPTY = 0x01,
  228125. +
  228126. +/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT, AHB_DMA_BUFFMASK, AHB_DMA_BUFFPOL field values */
  228127. + HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02,
  228128. + HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01,
  228129. +
  228130. +/* MC_CLKDIS field values */
  228131. + HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40,
  228132. + HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20,
  228133. + HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10,
  228134. + HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8,
  228135. + HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4,
  228136. + HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2,
  228137. + HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
  228138. +
  228139. +/* MC_SWRSTZ field values */
  228140. + HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
  228141. +
  228142. +/* MC_FLOWCTRL field values */
  228143. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1,
  228144. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1,
  228145. + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0,
  228146. +
  228147. +/* MC_PHYRSTZ field values */
  228148. + HDMI_MC_PHYRSTZ_ASSERT = 0x0,
  228149. + HDMI_MC_PHYRSTZ_DEASSERT = 0x1,
  228150. +
  228151. +/* MC_HEACPHY_RST field values */
  228152. + HDMI_MC_HEACPHY_RST_ASSERT = 0x1,
  228153. + HDMI_MC_HEACPHY_RST_DEASSERT = 0x0,
  228154. +
  228155. +/* CSC_CFG field values */
  228156. + HDMI_CSC_CFG_INTMODE_MASK = 0x30,
  228157. + HDMI_CSC_CFG_INTMODE_OFFSET = 4,
  228158. + HDMI_CSC_CFG_INTMODE_DISABLE = 0x00,
  228159. + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10,
  228160. + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20,
  228161. + HDMI_CSC_CFG_DECMODE_MASK = 0x3,
  228162. + HDMI_CSC_CFG_DECMODE_OFFSET = 0,
  228163. + HDMI_CSC_CFG_DECMODE_DISABLE = 0x0,
  228164. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1,
  228165. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2,
  228166. + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3,
  228167. +
  228168. +/* CSC_SCALE field values */
  228169. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0,
  228170. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00,
  228171. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50,
  228172. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60,
  228173. + HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70,
  228174. + HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03,
  228175. +
  228176. +/* I2CM_OPERATION field values */
  228177. + HDMI_I2CM_OPERATION_WRITE = 0x10,
  228178. + HDMI_I2CM_OPERATION_READ_EXT = 0x2,
  228179. + HDMI_I2CM_OPERATION_READ = 0x1,
  228180. +
  228181. +/* HDMI_I2CM_INT */
  228182. + HDMI_I2CM_INT_DONE_POL = 0x08,
  228183. + HDMI_I2CM_INT_DONE_MASK = 0x04,
  228184. +
  228185. +/* HDMI_I2CM_CTLINT */
  228186. + HDMI_I2CM_CTLINT_NAC_POL = 0x80,
  228187. + HDMI_I2CM_CTLINT_NAC_MASK = 0x40,
  228188. + HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08,
  228189. + HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04,
  228190. +
  228191. +};
  228192. +
  228193. +enum imx_hdmi_type {
  228194. + IMX6DL_HDMI,
  228195. + IMX6Q_HDMI,
  228196. +};
  228197. +
  228198. +/* IOCTL commands */
  228199. +#define HDMI_IOC_MAGIC 'H'
  228200. +
  228201. +#define HDMI_IOC_GET_RESOURCE _IO(HDMI_IOC_MAGIC, 0)
  228202. +#define HDMI_IOC_GET_CPU_TYPE _IO(HDMI_IOC_MAGIC, 1)
  228203. +
  228204. +
  228205. +#endif /* __MXC_HDMI_H__ */
  228206. diff -Nur linux-3.14.17/init/main.c linux-imx6-3.14/init/main.c
  228207. --- linux-3.14.17/init/main.c 2014-08-14 03:38:34.000000000 +0200
  228208. +++ linux-imx6-3.14/init/main.c 2014-09-11 18:06:14.446087655 +0200
  228209. @@ -617,10 +617,6 @@
  228210. if (efi_enabled(EFI_RUNTIME_SERVICES))
  228211. efi_enter_virtual_mode();
  228212. #endif
  228213. -#ifdef CONFIG_X86_ESPFIX64
  228214. - /* Should be run before the first non-init thread is created */
  228215. - init_espfix_bsp();
  228216. -#endif
  228217. thread_info_cache_init();
  228218. cred_init();
  228219. fork_init(totalram_pages);
  228220. diff -Nur linux-3.14.17/kernel/cpu.c linux-imx6-3.14/kernel/cpu.c
  228221. --- linux-3.14.17/kernel/cpu.c 2014-08-14 03:38:34.000000000 +0200
  228222. +++ linux-imx6-3.14/kernel/cpu.c 2014-09-11 18:06:14.486087815 +0200
  228223. @@ -722,3 +722,22 @@
  228224. {
  228225. cpumask_copy(to_cpumask(cpu_online_bits), src);
  228226. }
  228227. +
  228228. +static ATOMIC_NOTIFIER_HEAD(idle_notifier);
  228229. +void idle_notifier_register(struct notifier_block *n)
  228230. +{
  228231. + atomic_notifier_chain_register(&idle_notifier, n);
  228232. +}
  228233. +EXPORT_SYMBOL_GPL(idle_notifier_register);
  228234. +
  228235. +void idle_notifier_unregister(struct notifier_block *n)
  228236. +{
  228237. + atomic_notifier_chain_unregister(&idle_notifier, n);
  228238. +}
  228239. +EXPORT_SYMBOL_GPL(idle_notifier_unregister);
  228240. +
  228241. +void idle_notifier_call_chain(unsigned long val)
  228242. +{
  228243. + atomic_notifier_call_chain(&idle_notifier, val, NULL);
  228244. +}
  228245. +EXPORT_SYMBOL_GPL(idle_notifier_call_chain);
  228246. diff -Nur linux-3.14.17/kernel/irq/manage.c linux-imx6-3.14/kernel/irq/manage.c
  228247. --- linux-3.14.17/kernel/irq/manage.c 2014-08-14 03:38:34.000000000 +0200
  228248. +++ linux-imx6-3.14/kernel/irq/manage.c 2014-09-11 18:06:14.630088390 +0200
  228249. @@ -32,24 +32,10 @@
  228250. early_param("threadirqs", setup_forced_irqthreads);
  228251. #endif
  228252. -/**
  228253. - * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  228254. - * @irq: interrupt number to wait for
  228255. - *
  228256. - * This function waits for any pending IRQ handlers for this interrupt
  228257. - * to complete before returning. If you use this function while
  228258. - * holding a resource the IRQ handler may need you will deadlock.
  228259. - *
  228260. - * This function may be called - with care - from IRQ context.
  228261. - */
  228262. -void synchronize_irq(unsigned int irq)
  228263. +static void __synchronize_hardirq(struct irq_desc *desc)
  228264. {
  228265. - struct irq_desc *desc = irq_to_desc(irq);
  228266. bool inprogress;
  228267. - if (!desc)
  228268. - return;
  228269. -
  228270. do {
  228271. unsigned long flags;
  228272. @@ -67,12 +53,56 @@
  228273. /* Oops, that failed? */
  228274. } while (inprogress);
  228275. +}
  228276. +
  228277. +/**
  228278. + * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
  228279. + * @irq: interrupt number to wait for
  228280. + *
  228281. + * This function waits for any pending hard IRQ handlers for this
  228282. + * interrupt to complete before returning. If you use this
  228283. + * function while holding a resource the IRQ handler may need you
  228284. + * will deadlock. It does not take associated threaded handlers
  228285. + * into account.
  228286. + *
  228287. + * Do not use this for shutdown scenarios where you must be sure
  228288. + * that all parts (hardirq and threaded handler) have completed.
  228289. + *
  228290. + * This function may be called - with care - from IRQ context.
  228291. + */
  228292. +void synchronize_hardirq(unsigned int irq)
  228293. +{
  228294. + struct irq_desc *desc = irq_to_desc(irq);
  228295. - /*
  228296. - * We made sure that no hardirq handler is running. Now verify
  228297. - * that no threaded handlers are active.
  228298. - */
  228299. - wait_event(desc->wait_for_threads, !atomic_read(&desc->threads_active));
  228300. + if (desc)
  228301. + __synchronize_hardirq(desc);
  228302. +}
  228303. +EXPORT_SYMBOL(synchronize_hardirq);
  228304. +
  228305. +/**
  228306. + * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
  228307. + * @irq: interrupt number to wait for
  228308. + *
  228309. + * This function waits for any pending IRQ handlers for this interrupt
  228310. + * to complete before returning. If you use this function while
  228311. + * holding a resource the IRQ handler may need you will deadlock.
  228312. + *
  228313. + * This function may be called - with care - from IRQ context.
  228314. + */
  228315. +void synchronize_irq(unsigned int irq)
  228316. +{
  228317. + struct irq_desc *desc = irq_to_desc(irq);
  228318. +
  228319. + if (desc) {
  228320. + __synchronize_hardirq(desc);
  228321. + /*
  228322. + * We made sure that no hardirq handler is
  228323. + * running. Now verify that no threaded handlers are
  228324. + * active.
  228325. + */
  228326. + wait_event(desc->wait_for_threads,
  228327. + !atomic_read(&desc->threads_active));
  228328. + }
  228329. }
  228330. EXPORT_SYMBOL(synchronize_irq);
  228331. diff -Nur linux-3.14.17/kernel/printk/printk.c linux-imx6-3.14/kernel/printk/printk.c
  228332. --- linux-3.14.17/kernel/printk/printk.c 2014-08-14 03:38:34.000000000 +0200
  228333. +++ linux-imx6-3.14/kernel/printk/printk.c 2014-09-11 18:06:14.678088581 +0200
  228334. @@ -2468,7 +2468,7 @@
  228335. preempt_enable();
  228336. }
  228337. -int printk_deferred(const char *fmt, ...)
  228338. +int printk_sched(const char *fmt, ...)
  228339. {
  228340. unsigned long flags;
  228341. va_list args;
  228342. diff -Nur linux-3.14.17/kernel/relay.c linux-imx6-3.14/kernel/relay.c
  228343. --- linux-3.14.17/kernel/relay.c 2014-08-14 03:38:34.000000000 +0200
  228344. +++ linux-imx6-3.14/kernel/relay.c 2014-09-11 18:06:14.746088855 +0200
  228345. @@ -227,7 +227,7 @@
  228346. * relay_remove_buf - remove a channel buffer
  228347. * @kref: target kernel reference that contains the relay buffer
  228348. *
  228349. - * Removes the file from the fileystem, which also frees the
  228350. + * Removes the file from the filesystem, which also frees the
  228351. * rchan_buf_struct and the channel buffer. Should only be called from
  228352. * kref_put().
  228353. */
  228354. diff -Nur linux-3.14.17/kernel/sched/core.c linux-imx6-3.14/kernel/sched/core.c
  228355. --- linux-3.14.17/kernel/sched/core.c 2014-08-14 03:38:34.000000000 +0200
  228356. +++ linux-imx6-3.14/kernel/sched/core.c 2014-09-11 18:06:14.750088870 +0200
  228357. @@ -1322,7 +1322,7 @@
  228358. * leave kernel.
  228359. */
  228360. if (p->mm && printk_ratelimit()) {
  228361. - printk_deferred("process %d (%s) no longer affine to cpu%d\n",
  228362. + printk_sched("process %d (%s) no longer affine to cpu%d\n",
  228363. task_pid_nr(p), p->comm, cpu);
  228364. }
  228365. }
  228366. diff -Nur linux-3.14.17/kernel/sched/deadline.c linux-imx6-3.14/kernel/sched/deadline.c
  228367. --- linux-3.14.17/kernel/sched/deadline.c 2014-08-14 03:38:34.000000000 +0200
  228368. +++ linux-imx6-3.14/kernel/sched/deadline.c 2014-09-11 18:06:14.754088885 +0200
  228369. @@ -329,7 +329,7 @@
  228370. if (!lag_once) {
  228371. lag_once = true;
  228372. - printk_deferred("sched: DL replenish lagged to much\n");
  228373. + printk_sched("sched: DL replenish lagged to much\n");
  228374. }
  228375. dl_se->deadline = rq_clock(rq) + pi_se->dl_deadline;
  228376. dl_se->runtime = pi_se->dl_runtime;
  228377. diff -Nur linux-3.14.17/kernel/sched/rt.c linux-imx6-3.14/kernel/sched/rt.c
  228378. --- linux-3.14.17/kernel/sched/rt.c 2014-08-14 03:38:34.000000000 +0200
  228379. +++ linux-imx6-3.14/kernel/sched/rt.c 2014-09-11 18:06:14.754088885 +0200
  228380. @@ -837,7 +837,7 @@
  228381. if (!once) {
  228382. once = true;
  228383. - printk_deferred("sched: RT throttling activated\n");
  228384. + printk_sched("sched: RT throttling activated\n");
  228385. }
  228386. } else {
  228387. /*
  228388. diff -Nur linux-3.14.17/kernel/signal.c linux-imx6-3.14/kernel/signal.c
  228389. --- linux-3.14.17/kernel/signal.c 2014-08-14 03:38:34.000000000 +0200
  228390. +++ linux-imx6-3.14/kernel/signal.c 2014-09-11 18:06:14.754088885 +0200
  228391. @@ -2382,7 +2382,7 @@
  228392. * @regs: user register state
  228393. * @stepping: nonzero if debugger single-step or block-step in use
  228394. *
  228395. - * This function should be called when a signal has succesfully been
  228396. + * This function should be called when a signal has successfully been
  228397. * delivered. It updates the blocked signals accordingly (@ka->sa.sa_mask
  228398. * is always blocked, and the signal itself is blocked unless %SA_NODEFER
  228399. * is set in @ka->sa.sa_flags. Tracing is notified.
  228400. diff -Nur linux-3.14.17/kernel/time/clockevents.c linux-imx6-3.14/kernel/time/clockevents.c
  228401. --- linux-3.14.17/kernel/time/clockevents.c 2014-08-14 03:38:34.000000000 +0200
  228402. +++ linux-imx6-3.14/kernel/time/clockevents.c 2014-09-11 18:06:14.758088900 +0200
  228403. @@ -146,8 +146,7 @@
  228404. {
  228405. /* Nothing to do if we already reached the limit */
  228406. if (dev->min_delta_ns >= MIN_DELTA_LIMIT) {
  228407. - printk_deferred(KERN_WARNING
  228408. - "CE: Reprogramming failure. Giving up\n");
  228409. + printk(KERN_WARNING "CE: Reprogramming failure. Giving up\n");
  228410. dev->next_event.tv64 = KTIME_MAX;
  228411. return -ETIME;
  228412. }
  228413. @@ -160,10 +159,9 @@
  228414. if (dev->min_delta_ns > MIN_DELTA_LIMIT)
  228415. dev->min_delta_ns = MIN_DELTA_LIMIT;
  228416. - printk_deferred(KERN_WARNING
  228417. - "CE: %s increased min_delta_ns to %llu nsec\n",
  228418. - dev->name ? dev->name : "?",
  228419. - (unsigned long long) dev->min_delta_ns);
  228420. + printk(KERN_WARNING "CE: %s increased min_delta_ns to %llu nsec\n",
  228421. + dev->name ? dev->name : "?",
  228422. + (unsigned long long) dev->min_delta_ns);
  228423. return 0;
  228424. }
  228425. diff -Nur linux-3.14.17/kernel/time/sched_clock.c linux-imx6-3.14/kernel/time/sched_clock.c
  228426. --- linux-3.14.17/kernel/time/sched_clock.c 2014-08-14 03:38:34.000000000 +0200
  228427. +++ linux-imx6-3.14/kernel/time/sched_clock.c 2014-09-11 18:06:15.154090207 +0200
  228428. @@ -204,8 +204,7 @@
  228429. static int sched_clock_suspend(void)
  228430. {
  228431. - update_sched_clock();
  228432. - hrtimer_cancel(&sched_clock_timer);
  228433. + sched_clock_poll(&sched_clock_timer);
  228434. cd.suspended = true;
  228435. return 0;
  228436. }
  228437. @@ -213,7 +212,6 @@
  228438. static void sched_clock_resume(void)
  228439. {
  228440. cd.epoch_cyc = read_sched_clock();
  228441. - hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
  228442. cd.suspended = false;
  228443. }
  228444. diff -Nur linux-3.14.17/kernel/trace/trace.c linux-imx6-3.14/kernel/trace/trace.c
  228445. --- linux-3.14.17/kernel/trace/trace.c 2014-08-14 03:38:34.000000000 +0200
  228446. +++ linux-imx6-3.14/kernel/trace/trace.c 2014-09-11 18:06:15.162090371 +0200
  228447. @@ -811,7 +811,7 @@
  228448. { trace_clock_local, "local", 1 },
  228449. { trace_clock_global, "global", 1 },
  228450. { trace_clock_counter, "counter", 0 },
  228451. - { trace_clock_jiffies, "uptime", 0 },
  228452. + { trace_clock_jiffies, "uptime", 1 },
  228453. { trace_clock, "perf", 1 },
  228454. ARCH_TRACE_CLOCKS
  228455. };
  228456. diff -Nur linux-3.14.17/kernel/trace/trace_clock.c linux-imx6-3.14/kernel/trace/trace_clock.c
  228457. --- linux-3.14.17/kernel/trace/trace_clock.c 2014-08-14 03:38:34.000000000 +0200
  228458. +++ linux-imx6-3.14/kernel/trace/trace_clock.c 2014-09-11 18:06:15.162090371 +0200
  228459. @@ -59,14 +59,13 @@
  228460. /*
  228461. * trace_jiffy_clock(): Simply use jiffies as a clock counter.
  228462. - * Note that this use of jiffies_64 is not completely safe on
  228463. - * 32-bit systems. But the window is tiny, and the effect if
  228464. - * we are affected is that we will have an obviously bogus
  228465. - * timestamp on a trace event - i.e. not life threatening.
  228466. */
  228467. u64 notrace trace_clock_jiffies(void)
  228468. {
  228469. - return jiffies_64_to_clock_t(jiffies_64 - INITIAL_JIFFIES);
  228470. + u64 jiffy = jiffies - INITIAL_JIFFIES;
  228471. +
  228472. + /* Return nsecs */
  228473. + return (u64)jiffies_to_usecs(jiffy) * 1000ULL;
  228474. }
  228475. /*
  228476. diff -Nur linux-3.14.17/lib/btree.c linux-imx6-3.14/lib/btree.c
  228477. --- linux-3.14.17/lib/btree.c 2014-08-14 03:38:34.000000000 +0200
  228478. +++ linux-imx6-3.14/lib/btree.c 2014-09-11 18:06:15.278090964 +0200
  228479. @@ -198,7 +198,6 @@
  228480. void btree_destroy(struct btree_head *head)
  228481. {
  228482. - mempool_free(head->node, head->mempool);
  228483. mempool_destroy(head->mempool);
  228484. head->mempool = NULL;
  228485. }
  228486. diff -Nur linux-3.14.17/linaro/configs/android.conf linux-imx6-3.14/linaro/configs/android.conf
  228487. --- linux-3.14.17/linaro/configs/android.conf 1970-01-01 01:00:00.000000000 +0100
  228488. +++ linux-imx6-3.14/linaro/configs/android.conf 2014-09-11 18:06:15.338091214 +0200
  228489. @@ -0,0 +1,42 @@
  228490. +CONFIG_IPV6=y
  228491. +# CONFIG_IPV6_SIT is not set
  228492. +CONFIG_PANIC_TIMEOUT=0
  228493. +CONFIG_HAS_WAKELOCK=y
  228494. +CONFIG_WAKELOCK=y
  228495. +CONFIG_BLK_DEV_LOOP=y
  228496. +CONFIG_DM_CRYPT=y
  228497. +CONFIG_POWER_SUPPLY=y
  228498. +CONFIG_ANDROID_PARANOID_NETWORK=y
  228499. +CONFIG_NET_ACTIVITY_STATS=y
  228500. +CONFIG_INPUT_MISC=y
  228501. +CONFIG_INPUT_UINPUT=y
  228502. +CONFIG_INPUT_GPIO=y
  228503. +CONFIG_USB_G_ANDROID=y
  228504. +CONFIG_SWITCH=y
  228505. +CONFIG_STAGING=y
  228506. +CONFIG_ANDROID=y
  228507. +CONFIG_ANDROID_BINDER_IPC=y
  228508. +CONFIG_ASHMEM=y
  228509. +CONFIG_ANDROID_LOGGER=y
  228510. +CONFIG_ANDROID_TIMED_OUTPUT=y
  228511. +CONFIG_ANDROID_TIMED_GPIO=y
  228512. +CONFIG_ANDROID_LOW_MEMORY_KILLER=y
  228513. +CONFIG_ANDROID_INTF_ALARM_DEV=y
  228514. +CONFIG_CRYPTO_TWOFISH=y
  228515. +CONFIG_BLK_DEV_RAM=y
  228516. +CONFIG_BLK_DEV_RAM_COUNT=16
  228517. +CONFIG_BLK_DEV_RAM_SIZE=16384
  228518. +CONFIG_FUSE_FS=y
  228519. +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
  228520. +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y
  228521. +CONFIG_ION=y
  228522. +CONFIG_SYNC=y
  228523. +CONFIG_SW_SYNC=y
  228524. +CONFIG_SW_SYNC_USER=y
  228525. +CONFIG_ION_TEST=y
  228526. +CONFIG_ION_DUMMY=y
  228527. +CONFIG_ADF=y
  228528. +CONFIG_ADF_FBDEV=y
  228529. +CONFIG_ADF_MEMBLOCK=y
  228530. +CONFIG_DMA_SHARED_BUFFER=y
  228531. +CONFIG_TUN=y
  228532. diff -Nur linux-3.14.17/linaro/configs/arndale.conf linux-imx6-3.14/linaro/configs/arndale.conf
  228533. --- linux-3.14.17/linaro/configs/arndale.conf 1970-01-01 01:00:00.000000000 +0100
  228534. +++ linux-imx6-3.14/linaro/configs/arndale.conf 2014-09-11 18:06:15.342091230 +0200
  228535. @@ -0,0 +1,66 @@
  228536. +CONFIG_KALLSYMS_ALL=y
  228537. +CONFIG_PARTITION_ADVANCED=y
  228538. +CONFIG_BSD_DISKLABEL=y
  228539. +CONFIG_SOLARIS_X86_PARTITION=y
  228540. +CONFIG_ARCH_EXYNOS=y
  228541. +CONFIG_S3C_LOWLEVEL_UART_PORT=2
  228542. +CONFIG_ARCH_EXYNOS5=y
  228543. +# CONFIG_EXYNOS_ATAGS is not set
  228544. +CONFIG_MACH_EXYNOS4_DT=y
  228545. +CONFIG_VMSPLIT_2G=y
  228546. +CONFIG_NR_CPUS=2
  228547. +CONFIG_HIGHMEM=y
  228548. +# CONFIG_COMPACTION is not set
  228549. +CONFIG_ARM_APPENDED_DTB=y
  228550. +CONFIG_ARM_ATAG_DTB_COMPAT=y
  228551. +CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init= mem=256M"
  228552. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  228553. +CONFIG_VFP=y
  228554. +CONFIG_NEON=y
  228555. +CONFIG_PM_RUNTIME=y
  228556. +CONFIG_BLK_DEV_LOOP=y
  228557. +CONFIG_BLK_DEV_SD=y
  228558. +CONFIG_CHR_DEV_SG=y
  228559. +CONFIG_ATA=y
  228560. +CONFIG_SATA_AHCI_PLATFORM=y
  228561. +CONFIG_SATA_EXYNOS=y
  228562. +CONFIG_AX88796=y
  228563. +CONFIG_AX88796_93CX6=y
  228564. +CONFIG_INPUT_EVDEV=y
  228565. +CONFIG_KEYBOARD_GPIO=y
  228566. +CONFIG_INPUT_TOUCHSCREEN=y
  228567. +CONFIG_SERIAL_8250=y
  228568. +CONFIG_SERIAL_SAMSUNG=y
  228569. +CONFIG_SERIAL_SAMSUNG_CONSOLE=y
  228570. +CONFIG_HW_RANDOM=y
  228571. +CONFIG_I2C=y
  228572. +CONFIG_I2C_S3C2410=y
  228573. +CONFIG_THERMAL=y
  228574. +CONFIG_CPU_THERMAL=y
  228575. +CONFIG_EXYNOS_THERMAL=y
  228576. +CONFIG_MFD_SEC_CORE=y
  228577. +CONFIG_REGULATOR=y
  228578. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  228579. +CONFIG_REGULATOR_S5M8767=y
  228580. +CONFIG_DRM=y
  228581. +CONFIG_DRM_LOAD_EDID_FIRMWARE=y
  228582. +CONFIG_DRM_EXYNOS=y
  228583. +CONFIG_DRM_EXYNOS_DMABUF=y
  228584. +CONFIG_DRM_EXYNOS_HDMI=y
  228585. +CONFIG_FRAMEBUFFER_CONSOLE=y
  228586. +CONFIG_LOGO=y
  228587. +CONFIG_MMC=y
  228588. +CONFIG_MMC_UNSAFE_RESUME=y
  228589. +CONFIG_MMC_DW=y
  228590. +CONFIG_MMC_DW_IDMAC=y
  228591. +CONFIG_MMC_DW_EXYNOS=y
  228592. +CONFIG_RTC_CLASS=y
  228593. +CONFIG_RTC_DRV_S3C=y
  228594. +CONFIG_DEBUG_KERNEL=y
  228595. +CONFIG_DETECT_HUNG_TASK=y
  228596. +CONFIG_DEBUG_RT_MUTEXES=y
  228597. +CONFIG_DEBUG_SPINLOCK=y
  228598. +CONFIG_DEBUG_INFO=y
  228599. +CONFIG_RCU_CPU_STALL_TIMEOUT=60
  228600. +CONFIG_DEBUG_USER=y
  228601. +CONFIG_TUN=y
  228602. diff -Nur linux-3.14.17/linaro/configs/bigendian.conf linux-imx6-3.14/linaro/configs/bigendian.conf
  228603. --- linux-3.14.17/linaro/configs/bigendian.conf 1970-01-01 01:00:00.000000000 +0100
  228604. +++ linux-imx6-3.14/linaro/configs/bigendian.conf 2014-09-11 18:06:15.342091230 +0200
  228605. @@ -0,0 +1,4 @@
  228606. +CONFIG_CPU_BIG_ENDIAN=y
  228607. +CONFIG_CPU_ENDIAN_BE8=y
  228608. +# CONFIG_VIRTUALIZATION is not set
  228609. +# CONFIG_MMC_DW_IDMAC is not set
  228610. diff -Nur linux-3.14.17/linaro/configs/big-LITTLE-IKS.conf linux-imx6-3.14/linaro/configs/big-LITTLE-IKS.conf
  228611. --- linux-3.14.17/linaro/configs/big-LITTLE-IKS.conf 1970-01-01 01:00:00.000000000 +0100
  228612. +++ linux-imx6-3.14/linaro/configs/big-LITTLE-IKS.conf 2014-09-11 18:06:15.342091230 +0200
  228613. @@ -0,0 +1,5 @@
  228614. +CONFIG_BIG_LITTLE=y
  228615. +CONFIG_BL_SWITCHER=y
  228616. +CONFIG_ARM_DT_BL_CPUFREQ=y
  228617. +CONFIG_ARM_VEXPRESS_BL_CPUFREQ=y
  228618. +CONFIG_CPU_FREQ_GOV_USERSPACE=y
  228619. diff -Nur linux-3.14.17/linaro/configs/debug.conf linux-imx6-3.14/linaro/configs/debug.conf
  228620. --- linux-3.14.17/linaro/configs/debug.conf 1970-01-01 01:00:00.000000000 +0100
  228621. +++ linux-imx6-3.14/linaro/configs/debug.conf 2014-09-11 18:06:15.342091230 +0200
  228622. @@ -0,0 +1 @@
  228623. +CONFIG_PROVE_LOCKING=y
  228624. diff -Nur linux-3.14.17/linaro/configs/distribution.conf linux-imx6-3.14/linaro/configs/distribution.conf
  228625. --- linux-3.14.17/linaro/configs/distribution.conf 1970-01-01 01:00:00.000000000 +0100
  228626. +++ linux-imx6-3.14/linaro/configs/distribution.conf 2014-09-11 18:06:15.342091230 +0200
  228627. @@ -0,0 +1,49 @@
  228628. +# CONFIG_LOCALVERSION_AUTO is not set
  228629. +CONFIG_CGROUPS=y
  228630. +# CONFIG_COMPAT_BRK is not set
  228631. +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
  228632. +CONFIG_SECCOMP=y
  228633. +CONFIG_CC_STACKPROTECTOR=y
  228634. +CONFIG_SYN_COOKIES=y
  228635. +CONFIG_IPV6=y
  228636. +CONFIG_NETLABEL=y
  228637. +CONFIG_BRIDGE_NETFILTER=y
  228638. +CONFIG_NF_CONNTRACK=m
  228639. +CONFIG_NETFILTER_XT_CONNMARK=m
  228640. +CONFIG_NETFILTER_XT_MARK=m
  228641. +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
  228642. +CONFIG_NF_CONNTRACK_IPV4=m
  228643. +CONFIG_NF_NAT_IPV4=m
  228644. +CONFIG_IP_NF_IPTABLES=m
  228645. +CONFIG_IP_NF_FILTER=m
  228646. +CONFIG_IP_NF_MANGLE=m
  228647. +CONFIG_NF_CONNTRACK_IPV6=m
  228648. +CONFIG_NF_NAT_IPV6=m
  228649. +CONFIG_IP6_NF_IPTABLES=m
  228650. +CONFIG_IP6_NF_FILTER=m
  228651. +CONFIG_IP6_NF_MANGLE=m
  228652. +CONFIG_BRIDGE_NF_EBTABLES=m
  228653. +CONFIG_BRIDGE_EBT_MARK_T=m
  228654. +CONFIG_BRIDGE=m
  228655. +CONFIG_TUN=y
  228656. +CONFIG_DEVTMPFS=y
  228657. +CONFIG_DEVTMPFS_MOUNT=y
  228658. +CONFIG_BLK_DEV_RAM=y
  228659. +CONFIG_BLK_DEV_RAM_SIZE=65536
  228660. +CONFIG_INPUT_MISC=y
  228661. +CONFIG_INPUT_UINPUT=y
  228662. +# CONFIG_DEVKMEM is not set
  228663. +CONFIG_FRAMEBUFFER_CONSOLE=y
  228664. +CONFIG_AUTOFS4_FS=y
  228665. +CONFIG_TMPFS_POSIX_ACL=y
  228666. +CONFIG_STRICT_DEVMEM=y
  228667. +CONFIG_SECURITY=y
  228668. +CONFIG_LSM_MMAP_MIN_ADDR=0
  228669. +CONFIG_SECURITY_SELINUX=y
  228670. +CONFIG_SECURITY_SMACK=y
  228671. +CONFIG_SECURITY_APPARMOR=y
  228672. +CONFIG_DEFAULT_SECURITY_APPARMOR=y
  228673. +CONFIG_HUGETLBFS=y
  228674. +CONFIG_HUGETLB_PAGE=y
  228675. +CONFIG_TRANSPARENT_HUGEPAGE=y
  228676. +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
  228677. diff -Nur linux-3.14.17/linaro/configs/highbank.conf linux-imx6-3.14/linaro/configs/highbank.conf
  228678. --- linux-3.14.17/linaro/configs/highbank.conf 1970-01-01 01:00:00.000000000 +0100
  228679. +++ linux-imx6-3.14/linaro/configs/highbank.conf 2014-09-11 18:06:15.342091230 +0200
  228680. @@ -0,0 +1,40 @@
  228681. +CONFIG_EXPERIMENTAL=y
  228682. +CONFIG_NO_HZ=y
  228683. +CONFIG_HIGH_RES_TIMERS=y
  228684. +CONFIG_ARCH_HIGHBANK=y
  228685. +CONFIG_ARM_ERRATA_754322=y
  228686. +CONFIG_SMP=y
  228687. +CONFIG_SCHED_MC=y
  228688. +CONFIG_AEABI=y
  228689. +CONFIG_CMDLINE="console=ttyAMA0"
  228690. +CONFIG_CPU_IDLE=y
  228691. +CONFIG_VFP=y
  228692. +CONFIG_NEON=y
  228693. +CONFIG_NET=y
  228694. +CONFIG_SCSI=y
  228695. +CONFIG_BLK_DEV_SD=y
  228696. +CONFIG_ATA=y
  228697. +CONFIG_SATA_AHCI_PLATFORM=y
  228698. +CONFIG_SATA_HIGHBANK=y
  228699. +CONFIG_NETDEVICES=y
  228700. +CONFIG_NET_CALXEDA_XGMAC=y
  228701. +CONFIG_SERIAL_AMBA_PL011=y
  228702. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  228703. +CONFIG_IPMI_HANDLER=y
  228704. +CONFIG_IPMI_SI=y
  228705. +CONFIG_I2C=y
  228706. +CONFIG_I2C_DESIGNWARE_PLATFORM=y
  228707. +CONFIG_SPI=y
  228708. +CONFIG_SPI_PL022=y
  228709. +CONFIG_GPIO_PL061=y
  228710. +CONFIG_MMC=y
  228711. +CONFIG_MMC_SDHCI=y
  228712. +CONFIG_MMC_SDHCI_PLTFM=y
  228713. +CONFIG_EDAC=y
  228714. +CONFIG_EDAC_MM_EDAC=y
  228715. +CONFIG_EDAC_HIGHBANK_MC=y
  228716. +CONFIG_EDAC_HIGHBANK_L2=y
  228717. +CONFIG_RTC_CLASS=y
  228718. +CONFIG_RTC_DRV_PL031=y
  228719. +CONFIG_DMADEVICES=y
  228720. +CONFIG_PL330_DMA=y
  228721. diff -Nur linux-3.14.17/linaro/configs/kvm-guest.conf linux-imx6-3.14/linaro/configs/kvm-guest.conf
  228722. --- linux-3.14.17/linaro/configs/kvm-guest.conf 1970-01-01 01:00:00.000000000 +0100
  228723. +++ linux-imx6-3.14/linaro/configs/kvm-guest.conf 2014-09-11 18:06:15.342091230 +0200
  228724. @@ -0,0 +1,11 @@
  228725. +CONFIG_BALLOON_COMPACTION=y
  228726. +CONFIG_VIRTIO_BLK=y
  228727. +CONFIG_VIRTIO_NET=y
  228728. +CONFIG_HVC_DRIVER=y
  228729. +CONFIG_VIRTIO_CONSOLE=y
  228730. +CONFIG_VIRTIO=y
  228731. +CONFIG_VIRTIO_BALLOON=y
  228732. +CONFIG_VIRTIO_MMIO=y
  228733. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
  228734. +CONFIG_VIRTUALIZATION=y
  228735. +# CONFIG_THUMB2_KERNEL is not set
  228736. diff -Nur linux-3.14.17/linaro/configs/kvm-host.conf linux-imx6-3.14/linaro/configs/kvm-host.conf
  228737. --- linux-3.14.17/linaro/configs/kvm-host.conf 1970-01-01 01:00:00.000000000 +0100
  228738. +++ linux-imx6-3.14/linaro/configs/kvm-host.conf 2014-09-11 18:06:15.342091230 +0200
  228739. @@ -0,0 +1,11 @@
  228740. +CONFIG_VIRTUALIZATION=y
  228741. +CONFIG_ARM_LPAE=y
  228742. +CONFIG_ARM_VIRT_EXT=y
  228743. +CONFIG_HAVE_KVM_IRQCHIP=y
  228744. +CONFIG_KVM_ARM_HOST=y
  228745. +CONFIG_KVM_ARM_MAX_VCPUS=4
  228746. +CONFIG_KVM_ARM_TIMER=y
  228747. +CONFIG_KVM_ARM_VGIC=y
  228748. +CONFIG_KVM_MMIO=y
  228749. +CONFIG_KVM=y
  228750. +CONFIG_BLK_DEV_NBD=m
  228751. diff -Nur linux-3.14.17/linaro/configs/linaro-base.conf linux-imx6-3.14/linaro/configs/linaro-base.conf
  228752. --- linux-3.14.17/linaro/configs/linaro-base.conf 1970-01-01 01:00:00.000000000 +0100
  228753. +++ linux-imx6-3.14/linaro/configs/linaro-base.conf 2014-09-11 18:06:15.342091230 +0200
  228754. @@ -0,0 +1,115 @@
  228755. +CONFIG_SYSVIPC=y
  228756. +CONFIG_POSIX_MQUEUE=y
  228757. +CONFIG_BSD_PROCESS_ACCT=y
  228758. +CONFIG_IKCONFIG=y
  228759. +CONFIG_IKCONFIG_PROC=y
  228760. +CONFIG_LOG_BUF_SHIFT=16
  228761. +CONFIG_BLK_DEV_INITRD=y
  228762. +CONFIG_EMBEDDED=y
  228763. +CONFIG_HOTPLUG=y
  228764. +CONFIG_PERF_EVENTS=y
  228765. +CONFIG_SLAB=y
  228766. +CONFIG_PROFILING=y
  228767. +CONFIG_OPROFILE=y
  228768. +CONFIG_MODULES=y
  228769. +CONFIG_MODULE_UNLOAD=y
  228770. +CONFIG_NO_HZ=y
  228771. +CONFIG_HIGH_RES_TIMERS=y
  228772. +CONFIG_SMP=y
  228773. +CONFIG_SCHED_MC=y
  228774. +CONFIG_SCHED_SMT=y
  228775. +CONFIG_THUMB2_KERNEL=y
  228776. +CONFIG_AEABI=y
  228777. +# CONFIG_OABI_COMPAT is not set
  228778. +CONFIG_CPU_FREQ=y
  228779. +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
  228780. +CONFIG_CPU_IDLE=y
  228781. +CONFIG_BINFMT_MISC=y
  228782. +CONFIG_MD=y
  228783. +CONFIG_BLK_DEV_DM=y
  228784. +CONFIG_NET=y
  228785. +CONFIG_PACKET=y
  228786. +CONFIG_UNIX=y
  228787. +CONFIG_XFRM_USER=y
  228788. +CONFIG_NET_KEY=y
  228789. +CONFIG_NET_KEY_MIGRATE=y
  228790. +CONFIG_INET=y
  228791. +CONFIG_IP_MULTICAST=y
  228792. +CONFIG_IP_PNP=y
  228793. +CONFIG_IP_PNP_DHCP=y
  228794. +CONFIG_IP_PNP_BOOTP=y
  228795. +CONFIG_IP_PNP_RARP=y
  228796. +# CONFIG_INET_LRO is not set
  228797. +CONFIG_NETFILTER=y
  228798. +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
  228799. +CONFIG_CONNECTOR=y
  228800. +CONFIG_MTD=y
  228801. +CONFIG_MTD_CMDLINE_PARTS=y
  228802. +CONFIG_MTD_BLOCK=y
  228803. +CONFIG_MTD_OOPS=y
  228804. +CONFIG_MTD_CFI=y
  228805. +CONFIG_MTD_CFI_INTELEXT=y
  228806. +CONFIG_MTD_NAND=y
  228807. +CONFIG_NETDEVICES=y
  228808. +CONFIG_EXT2_FS=y
  228809. +CONFIG_EXT3_FS=y
  228810. +CONFIG_EXT4_FS=y
  228811. +CONFIG_BTRFS_FS=y
  228812. +CONFIG_QUOTA=y
  228813. +CONFIG_QFMT_V2=y
  228814. +CONFIG_MSDOS_FS=y
  228815. +CONFIG_VFAT_FS=y
  228816. +CONFIG_TMPFS=y
  228817. +CONFIG_ECRYPT_FS=y
  228818. +CONFIG_JFFS2_FS=y
  228819. +CONFIG_JFFS2_SUMMARY=y
  228820. +CONFIG_JFFS2_FS_XATTR=y
  228821. +CONFIG_JFFS2_COMPRESSION_OPTIONS=y
  228822. +CONFIG_JFFS2_LZO=y
  228823. +CONFIG_JFFS2_RUBIN=y
  228824. +CONFIG_CRAMFS=y
  228825. +CONFIG_NETWORK_FILESYSTEMS=y
  228826. +CONFIG_NFS_FS=y
  228827. +# CONFIG_NFS_V2 is not set
  228828. +CONFIG_NFS_V3=y
  228829. +CONFIG_NFS_V3_ACL=y
  228830. +CONFIG_NFS_V4=y
  228831. +CONFIG_ROOT_NFS=y
  228832. +CONFIG_NLS_CODEPAGE_437=y
  228833. +CONFIG_NLS_ISO8859_1=y
  228834. +CONFIG_PRINTK_TIME=y
  228835. +CONFIG_MAGIC_SYSRQ=y
  228836. +CONFIG_DEBUG_FS=y
  228837. +CONFIG_SCHEDSTATS=y
  228838. +CONFIG_TIMER_STATS=y
  228839. +CONFIG_KEYS=y
  228840. +CONFIG_CRYPTO_MICHAEL_MIC=y
  228841. +CONFIG_CRC_CCITT=y
  228842. +CONFIG_CRC_T10DIF=y
  228843. +CONFIG_CRC_ITU_T=y
  228844. +CONFIG_CRC7=y
  228845. +CONFIG_HW_PERF_EVENTS=y
  228846. +CONFIG_FUNCTION_TRACER=y
  228847. +CONFIG_ENABLE_DEFAULT_TRACERS=y
  228848. +CONFIG_PROC_DEVICETREE=y
  228849. +CONFIG_JUMP_LABEL=y
  228850. +CONFIG_STRICT_DEVMEM=y
  228851. +CONFIG_KGDB=y
  228852. +CONFIG_KGDB_TESTS=y
  228853. +CONFIG_OF_IDLE_STATES=y
  228854. +CONFIG_FTRACE=y
  228855. +CONFIG_FUNCTION_TRACER=y
  228856. +CONFIG_FTRACE_SYSCALLS=y
  228857. +CONFIG_STACK_TRACER=y
  228858. +CONFIG_FUNCTION_PROFILER=y
  228859. +CONFIG_MAILBOX=y
  228860. +CONFIG_AUDIT=y
  228861. +CONFIG_NF_CONNTRACK_SECMARK=y
  228862. +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
  228863. +CONFIG_NETFILTER_XT_TARGET_SECMARK=y
  228864. +CONFIG_IP_NF_SECURITY=y
  228865. +CONFIG_SECURITY=y
  228866. +CONFIG_SECURITY_NETWORK=y
  228867. +CONFIG_LSM_MMAP_MIN_ADDR=4096
  228868. +CONFIG_SECURITY_SELINUX=y
  228869. +CONFIG_EXT4_FS_SECURITY=y
  228870. diff -Nur linux-3.14.17/linaro/configs/omap4.conf linux-imx6-3.14/linaro/configs/omap4.conf
  228871. --- linux-3.14.17/linaro/configs/omap4.conf 1970-01-01 01:00:00.000000000 +0100
  228872. +++ linux-imx6-3.14/linaro/configs/omap4.conf 2014-09-11 18:06:15.342091230 +0200
  228873. @@ -0,0 +1,196 @@
  228874. +CONFIG_EXPERT=y
  228875. +CONFIG_KPROBES=y
  228876. +CONFIG_MODULE_FORCE_LOAD=y
  228877. +CONFIG_MODULE_FORCE_UNLOAD=y
  228878. +CONFIG_MODVERSIONS=y
  228879. +CONFIG_MODULE_SRCVERSION_ALL=y
  228880. +# CONFIG_BLK_DEV_BSG is not set
  228881. +CONFIG_PARTITION_ADVANCED=y
  228882. +CONFIG_GPIO_PCA953X=y
  228883. +CONFIG_OMAP_RESET_CLOCKS=y
  228884. +CONFIG_OMAP_MUX_DEBUG=y
  228885. +CONFIG_ARCH_OMAP3=y
  228886. +CONFIG_ARCH_OMAP4=y
  228887. +CONFIG_ARCH_OMAP2PLUS=y
  228888. +CONFIG_SOC_OMAP5=y
  228889. +# CONFIG_ARCH_OMAP2 is not set
  228890. +CONFIG_ARCH_VEXPRESS_CA9X4=y
  228891. +CONFIG_ARM_THUMBEE=y
  228892. +CONFIG_ARM_ERRATA_411920=y
  228893. +CONFIG_NR_CPUS=2
  228894. +CONFIG_ZBOOT_ROM_TEXT=0x0
  228895. +CONFIG_ZBOOT_ROM_BSS=0x0
  228896. +CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
  228897. +CONFIG_KEXEC=y
  228898. +CONFIG_PM_DEBUG=y
  228899. +CONFIG_CAN=m
  228900. +CONFIG_CAN_C_CAN=m
  228901. +CONFIG_CAN_C_CAN_PLATFORM=m
  228902. +CONFIG_BT=m
  228903. +CONFIG_BT_HCIUART=m
  228904. +CONFIG_BT_HCIUART_H4=y
  228905. +CONFIG_BT_HCIUART_BCSP=y
  228906. +CONFIG_BT_HCIUART_LL=y
  228907. +CONFIG_BT_HCIBCM203X=m
  228908. +CONFIG_BT_HCIBPA10X=m
  228909. +CONFIG_CFG80211=m
  228910. +CONFIG_MAC80211=m
  228911. +CONFIG_MAC80211_RC_PID=y
  228912. +CONFIG_MAC80211_RC_DEFAULT_PID=y
  228913. +CONFIG_CMA=y
  228914. +CONFIG_MTD_NAND_OMAP2=y
  228915. +CONFIG_MTD_ONENAND=y
  228916. +CONFIG_MTD_ONENAND_VERIFY_WRITE=y
  228917. +CONFIG_MTD_ONENAND_OMAP2=y
  228918. +CONFIG_MTD_UBI=y
  228919. +CONFIG_BLK_DEV_LOOP=y
  228920. +CONFIG_BLK_DEV_RAM_SIZE=16384
  228921. +CONFIG_SENSORS_TSL2550=m
  228922. +CONFIG_SENSORS_LIS3_I2C=m
  228923. +CONFIG_SCSI=y
  228924. +CONFIG_BLK_DEV_SD=y
  228925. +CONFIG_SCSI_MULTI_LUN=y
  228926. +CONFIG_SCSI_SCAN_ASYNC=y
  228927. +CONFIG_KS8851=y
  228928. +CONFIG_KS8851_MLL=y
  228929. +CONFIG_SMC91X=y
  228930. +CONFIG_SMSC911X=y
  228931. +CONFIG_TI_CPSW=y
  228932. +CONFIG_SMSC_PHY=y
  228933. +CONFIG_USB_USBNET=y
  228934. +CONFIG_USB_NET_SMSC95XX=y
  228935. +CONFIG_USB_ALI_M5632=y
  228936. +CONFIG_USB_AN2720=y
  228937. +CONFIG_USB_EPSON2888=y
  228938. +CONFIG_USB_KC2190=y
  228939. +CONFIG_LIBERTAS=m
  228940. +CONFIG_LIBERTAS_USB=m
  228941. +CONFIG_LIBERTAS_SDIO=m
  228942. +CONFIG_LIBERTAS_DEBUG=y
  228943. +CONFIG_INPUT_JOYDEV=y
  228944. +CONFIG_INPUT_EVDEV=y
  228945. +CONFIG_KEYBOARD_GPIO=y
  228946. +CONFIG_KEYBOARD_MATRIX=m
  228947. +CONFIG_KEYBOARD_TWL4030=y
  228948. +CONFIG_INPUT_TOUCHSCREEN=y
  228949. +CONFIG_TOUCHSCREEN_ADS7846=y
  228950. +CONFIG_INPUT_TWL4030_PWRBUTTON=y
  228951. +CONFIG_VT_HW_CONSOLE_BINDING=y
  228952. +# CONFIG_LEGACY_PTYS is not set
  228953. +CONFIG_SERIAL_8250=y
  228954. +CONFIG_SERIAL_8250_CONSOLE=y
  228955. +CONFIG_SERIAL_8250_NR_UARTS=32
  228956. +CONFIG_SERIAL_8250_EXTENDED=y
  228957. +CONFIG_SERIAL_8250_MANY_PORTS=y
  228958. +CONFIG_SERIAL_8250_SHARE_IRQ=y
  228959. +CONFIG_SERIAL_8250_DETECT_IRQ=y
  228960. +CONFIG_SERIAL_8250_RSA=y
  228961. +CONFIG_SERIAL_AMBA_PL011=y
  228962. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  228963. +CONFIG_SERIAL_OMAP=y
  228964. +CONFIG_SERIAL_OMAP_CONSOLE=y
  228965. +CONFIG_HW_RANDOM=y
  228966. +CONFIG_I2C_CHARDEV=y
  228967. +CONFIG_SPI=y
  228968. +CONFIG_SPI_OMAP24XX=y
  228969. +CONFIG_PINCTRL_SINGLE=y
  228970. +CONFIG_DEBUG_GPIO=y
  228971. +CONFIG_GPIO_SYSFS=y
  228972. +CONFIG_GPIO_TWL4030=y
  228973. +CONFIG_W1=y
  228974. +CONFIG_SENSORS_LM75=m
  228975. +CONFIG_WATCHDOG=y
  228976. +CONFIG_OMAP_WATCHDOG=y
  228977. +CONFIG_TWL4030_WATCHDOG=y
  228978. +CONFIG_MFD_TPS65217=y
  228979. +CONFIG_MFD_TPS65910=y
  228980. +CONFIG_TWL6040_CORE=y
  228981. +CONFIG_REGULATOR_TPS65023=y
  228982. +CONFIG_REGULATOR_TPS6507X=y
  228983. +CONFIG_REGULATOR_TPS65217=y
  228984. +CONFIG_REGULATOR_TPS65910=y
  228985. +CONFIG_REGULATOR_TWL4030=y
  228986. +CONFIG_FB=y
  228987. +CONFIG_FIRMWARE_EDID=y
  228988. +CONFIG_FB_MODE_HELPERS=y
  228989. +CONFIG_FB_TILEBLITTING=y
  228990. +CONFIG_OMAP2_DSS=m
  228991. +CONFIG_OMAP2_DSS_RFBI=y
  228992. +CONFIG_OMAP2_DSS_SDI=y
  228993. +CONFIG_OMAP2_DSS_DSI=y
  228994. +CONFIG_FB_OMAP2=m
  228995. +CONFIG_PANEL_GENERIC_DPI=m
  228996. +CONFIG_PANEL_TFP410=m
  228997. +CONFIG_PANEL_SHARP_LS037V7DW01=m
  228998. +CONFIG_PANEL_NEC_NL8048HL11_01B=m
  228999. +CONFIG_PANEL_TAAL=m
  229000. +CONFIG_PANEL_TPO_TD043MTEA1=m
  229001. +CONFIG_PANEL_ACX565AKM=m
  229002. +CONFIG_BACKLIGHT_LCD_SUPPORT=y
  229003. +CONFIG_LCD_CLASS_DEVICE=y
  229004. +CONFIG_LCD_PLATFORM=y
  229005. +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
  229006. +CONFIG_FONTS=y
  229007. +CONFIG_FONT_8x8=y
  229008. +CONFIG_FONT_8x16=y
  229009. +CONFIG_LOGO=y
  229010. +CONFIG_SOUND=m
  229011. +CONFIG_SND=m
  229012. +CONFIG_SND_VERBOSE_PRINTK=y
  229013. +CONFIG_SND_DEBUG=y
  229014. +CONFIG_SND_USB_AUDIO=m
  229015. +CONFIG_SND_SOC=m
  229016. +CONFIG_SND_OMAP_SOC=m
  229017. +CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
  229018. +CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
  229019. +CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
  229020. +CONFIG_USB=y
  229021. +CONFIG_USB_DEBUG=y
  229022. +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
  229023. +CONFIG_USB_MON=y
  229024. +CONFIG_USB_EHCI_HCD=y
  229025. +CONFIG_USB_OHCI_HCD=y
  229026. +CONFIG_USB_WDM=y
  229027. +CONFIG_USB_STORAGE=y
  229028. +CONFIG_USB_TEST=y
  229029. +CONFIG_USB_PHY=y
  229030. +CONFIG_NOP_USB_XCEIV=y
  229031. +CONFIG_USB_GADGET=y
  229032. +CONFIG_USB_GADGET_DEBUG=y
  229033. +CONFIG_USB_GADGET_DEBUG_FILES=y
  229034. +CONFIG_USB_GADGET_DEBUG_FS=y
  229035. +CONFIG_USB_ZERO=m
  229036. +CONFIG_MMC=y
  229037. +CONFIG_MMC_UNSAFE_RESUME=y
  229038. +CONFIG_SDIO_UART=y
  229039. +CONFIG_MMC_ARMMMCI=y
  229040. +CONFIG_MMC_OMAP=y
  229041. +CONFIG_MMC_OMAP_HS=y
  229042. +CONFIG_NEW_LEDS=y
  229043. +CONFIG_LEDS_CLASS=y
  229044. +CONFIG_LEDS_GPIO=y
  229045. +CONFIG_LEDS_TRIGGERS=y
  229046. +CONFIG_LEDS_TRIGGER_TIMER=y
  229047. +CONFIG_LEDS_TRIGGER_ONESHOT=y
  229048. +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
  229049. +CONFIG_LEDS_TRIGGER_BACKLIGHT=y
  229050. +CONFIG_LEDS_TRIGGER_CPU=y
  229051. +CONFIG_LEDS_TRIGGER_GPIO=y
  229052. +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
  229053. +CONFIG_RTC_CLASS=y
  229054. +CONFIG_RTC_DRV_TWL92330=y
  229055. +CONFIG_RTC_DRV_TWL4030=y
  229056. +CONFIG_RTC_DRV_OMAP=y
  229057. +CONFIG_DMADEVICES=y
  229058. +CONFIG_DMA_OMAP=y
  229059. +# CONFIG_EXT3_FS_XATTR is not set
  229060. +CONFIG_UBIFS_FS=y
  229061. +CONFIG_NFS_FS=y
  229062. +CONFIG_NFS_V3_ACL=y
  229063. +CONFIG_NFS_V4=y
  229064. +CONFIG_ROOT_NFS=y
  229065. +# CONFIG_DEBUG_BUGVERBOSE is not set
  229066. +CONFIG_DEBUG_INFO=y
  229067. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  229068. +CONFIG_LIBCRC32C=y
  229069. +# CONFIG_CPU_FREQ is not set
  229070. diff -Nur linux-3.14.17/linaro/configs/preempt-rt.conf linux-imx6-3.14/linaro/configs/preempt-rt.conf
  229071. --- linux-3.14.17/linaro/configs/preempt-rt.conf 1970-01-01 01:00:00.000000000 +0100
  229072. +++ linux-imx6-3.14/linaro/configs/preempt-rt.conf 2014-09-11 18:06:15.342091230 +0200
  229073. @@ -0,0 +1,4 @@
  229074. +CONFIG_PREEMPT=y
  229075. +CONFIG_PREEMPT_RT_FULL=y
  229076. +CONFIG_SLUB=y
  229077. +# CONFIG_CPU_FREQ is not set
  229078. diff -Nur linux-3.14.17/linaro/configs/vexpress64.conf linux-imx6-3.14/linaro/configs/vexpress64.conf
  229079. --- linux-3.14.17/linaro/configs/vexpress64.conf 1970-01-01 01:00:00.000000000 +0100
  229080. +++ linux-imx6-3.14/linaro/configs/vexpress64.conf 2014-09-11 18:06:15.342091230 +0200
  229081. @@ -0,0 +1,56 @@
  229082. +CONFIG_ARCH_VEXPRESS=y
  229083. +CONFIG_SMP=y
  229084. +CONFIG_NR_CPUS=8
  229085. +CONFIG_CMDLINE="console=ttyAMA0"
  229086. +CONFIG_COMPAT=y
  229087. +CONFIG_SMC91X=y
  229088. +CONFIG_INPUT_EVDEV=y
  229089. +CONFIG_SERIO_AMBAKMI=y
  229090. +CONFIG_SERIAL_AMBA_PL011=y
  229091. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  229092. +# CONFIG_SERIO_I8042 is not set
  229093. +CONFIG_FB=y
  229094. +CONFIG_FB_ARMCLCD=y
  229095. +CONFIG_FRAMEBUFFER_CONSOLE=y
  229096. +# CONFIG_VGA_CONSOLE is not set
  229097. +CONFIG_LOGO=y
  229098. +# CONFIG_LOGO_LINUX_MONO is not set
  229099. +# CONFIG_LOGO_LINUX_VGA16 is not set
  229100. +CONFIG_MMC=y
  229101. +CONFIG_MMC_ARMMMCI=y
  229102. +CONFIG_RTC_CLASS=y
  229103. +CONFIG_RTC_DRV_PL031=y
  229104. +CONFIG_NFS_FS=y
  229105. +CONFIG_NFS_V3=y
  229106. +CONFIG_NFS_V3_ACL=y
  229107. +CONFIG_NFS_V4=y
  229108. +CONFIG_ROOT_NFS=y
  229109. +CONFIG_VIRTIO=y
  229110. +CONFIG_VIRTIO_BLK=y
  229111. +CONFIG_VIRTIO_MMIO=y
  229112. +CONFIG_REGULATOR=y
  229113. +CONFIG_REGULATOR_FIXED_VOLTAGE=y
  229114. +CONFIG_CMA=y
  229115. +CONFIG_DMA_CMA=y
  229116. +CONFIG_COMMON_CLK_SCPI=y
  229117. +CONFIG_SMSC911X=y
  229118. +CONFIG_I2C=y
  229119. +CONFIG_ARM_MHU_MBOX=y
  229120. +CONFIG_ARM_SCPI_PROTOCOL=y
  229121. +CONFIG_USB_HIDDEV=y
  229122. +CONFIG_SCSI=y
  229123. +CONFIG_BLK_DEV_SD=y
  229124. +CONFIG_USB_STORAGE=y
  229125. +CONFIG_USB=y
  229126. +CONFIG_USB_ULPI=y
  229127. +CONFIG_USB_EHCI_HCD=y
  229128. +CONFIG_USB_EHCI_HCD_SYNOPSYS=y
  229129. +CONFIG_USB_OHCI_HCD=y
  229130. +CONFIG_USB_PHY=y
  229131. +CONFIG_USB_ISP1301=y
  229132. +CONFIG_PM_OPP=y
  229133. +CONFIG_GENERIC_CPUFREQ_CPU0=y
  229134. +CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
  229135. +CONFIG_ARM_DT_BL_CPUFREQ=y
  229136. +CONFIG_ARM64_CPUIDLE=y
  229137. +CONFIG_ARM64_CRYPTO=y
  229138. diff -Nur linux-3.14.17/linaro/configs/vexpress.conf linux-imx6-3.14/linaro/configs/vexpress.conf
  229139. --- linux-3.14.17/linaro/configs/vexpress.conf 1970-01-01 01:00:00.000000000 +0100
  229140. +++ linux-imx6-3.14/linaro/configs/vexpress.conf 2014-09-11 18:06:15.342091230 +0200
  229141. @@ -0,0 +1,64 @@
  229142. +CONFIG_ARCH_VEXPRESS=y
  229143. +CONFIG_ARCH_VEXPRESS_CA9X4=y
  229144. +CONFIG_HAVE_ARM_ARCH_TIMER=y
  229145. +CONFIG_NR_CPUS=8
  229146. +CONFIG_HIGHMEM=y
  229147. +CONFIG_HIGHPTE=y
  229148. +CONFIG_ARM_PSCI=y
  229149. +CONFIG_MCPM=y
  229150. +CONFIG_ARCH_VEXPRESS_DCSCB=y
  229151. +CONFIG_ARCH_VEXPRESS_TC2_PM=y
  229152. +CONFIG_ARM_BIG_LITTLE_CPUIDLE=y
  229153. +CONFIG_BIG_LITTLE=y
  229154. +CONFIG_ARM_VEXPRESS_SPC_CPUFREQ=y
  229155. +CONFIG_PM_OPP=y
  229156. +CONFIG_CPU_FREQ=y
  229157. +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  229158. +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
  229159. +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
  229160. +CONFIG_CMDLINE="console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait mmci.fmax=4000000"
  229161. +CONFIG_VFP=y
  229162. +CONFIG_NEON=y
  229163. +CONFIG_SCSI=y
  229164. +CONFIG_BLK_DEV_SD=y
  229165. +CONFIG_SMSC911X=y
  229166. +CONFIG_SMC91X=y
  229167. +CONFIG_INPUT_EVDEV=y
  229168. +CONFIG_SERIO_AMBAKMI=y
  229169. +CONFIG_SERIAL_AMBA_PL011=y
  229170. +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
  229171. +CONFIG_FB=y
  229172. +CONFIG_FB_ARMCLCD=y
  229173. +CONFIG_FB_ARMHDLCD=y
  229174. +CONFIG_LOGO=y
  229175. +# CONFIG_LOGO_LINUX_MONO is not set
  229176. +# CONFIG_LOGO_LINUX_VGA16 is not set
  229177. +CONFIG_SOUND=y
  229178. +CONFIG_SND=y
  229179. +CONFIG_SND_ARMAACI=y
  229180. +CONFIG_USB=y
  229181. +CONFIG_USB_ISP1760_HCD=y
  229182. +CONFIG_USB_STORAGE=y
  229183. +CONFIG_MMC=y
  229184. +CONFIG_MMC_ARMMMCI=y
  229185. +CONFIG_RTC_CLASS=y
  229186. +CONFIG_RTC_DRV_PL031=y
  229187. +CONFIG_NFS_FS=y
  229188. +CONFIG_NFS_V3=y
  229189. +CONFIG_NFS_V3_ACL=y
  229190. +CONFIG_NFS_V4=y
  229191. +CONFIG_ROOT_NFS=y
  229192. +CONFIG_VEXPRESS_CONFIG=y
  229193. +CONFIG_SENSORS_VEXPRESS=y
  229194. +CONFIG_REGULATOR=y
  229195. +CONFIG_REGULATOR_VEXPRESS=y
  229196. +CONFIG_NEW_LEDS=y
  229197. +CONFIG_LEDS_CLASS=y
  229198. +CONFIG_LEDS_GPIO=y
  229199. +CONFIG_LEDS_TRIGGERS=y
  229200. +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
  229201. +CONFIG_LEDS_TRIGGER_CPU=y
  229202. +CONFIG_VIRTIO=y
  229203. +CONFIG_VIRTIO_BLK=y
  229204. +CONFIG_VIRTIO_MMIO=y
  229205. +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
  229206. diff -Nur linux-3.14.17/linaro/configs/vexpress-tuning.conf linux-imx6-3.14/linaro/configs/vexpress-tuning.conf
  229207. --- linux-3.14.17/linaro/configs/vexpress-tuning.conf 1970-01-01 01:00:00.000000000 +0100
  229208. +++ linux-imx6-3.14/linaro/configs/vexpress-tuning.conf 2014-09-11 18:06:15.342091230 +0200
  229209. @@ -0,0 +1 @@
  229210. +# CONFIG_PROVE_LOCKING is not set
  229211. diff -Nur linux-3.14.17/linaro/configs/xen.conf linux-imx6-3.14/linaro/configs/xen.conf
  229212. --- linux-3.14.17/linaro/configs/xen.conf 1970-01-01 01:00:00.000000000 +0100
  229213. +++ linux-imx6-3.14/linaro/configs/xen.conf 2014-09-11 18:06:15.342091230 +0200
  229214. @@ -0,0 +1,7 @@
  229215. +CONFIG_XEN=y
  229216. +CONFIG_XEN_NETDEV_FRONTEND=y
  229217. +CONFIG_XEN_NETDEV_BACKEND=y
  229218. +CONFIG_XEN_BLKDEV_FRONTEND=y
  229219. +CONFIG_XEN_BLKDEV_BACKEND=y
  229220. +CONFIG_XENFS=y
  229221. +CONFIG_XEN_COMPAT_XENFS=y
  229222. diff -Nur linux-3.14.17/MAINTAINERS linux-imx6-3.14/MAINTAINERS
  229223. --- linux-3.14.17/MAINTAINERS 2014-08-14 03:38:34.000000000 +0200
  229224. +++ linux-imx6-3.14/MAINTAINERS 2014-09-11 18:05:52.461999847 +0200
  229225. @@ -5511,6 +5511,14 @@
  229226. F: drivers/net/macvlan.c
  229227. F: include/linux/if_macvlan.h
  229228. +MAILBOX API
  229229. +M: Jassi Brar <jassisinghbrar@gmail.com>
  229230. +L: linux-kernel@vger.kernel.org
  229231. +S: Maintained
  229232. +F: drivers/mailbox/
  229233. +F: include/linux/mailbox_client.h
  229234. +F: include/linux/mailbox_controller.h
  229235. +
  229236. MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
  229237. M: Michael Kerrisk <mtk.manpages@gmail.com>
  229238. W: http://www.kernel.org/doc/man-pages
  229239. diff -Nur linux-3.14.17/Makefile linux-imx6-3.14/Makefile
  229240. --- linux-3.14.17/Makefile 2014-08-14 03:38:34.000000000 +0200
  229241. +++ linux-imx6-3.14/Makefile 2014-09-11 18:09:02.718753157 +0200
  229242. @@ -639,8 +639,6 @@
  229243. endif
  229244. endif
  229245. -KBUILD_CFLAGS += $(call cc-option, -fno-var-tracking-assignments)
  229246. -
  229247. ifdef CONFIG_DEBUG_INFO
  229248. KBUILD_CFLAGS += -g
  229249. KBUILD_AFLAGS += -Wa,--gdwarf-2
  229250. diff -Nur linux-3.14.17/mm/cma.c linux-imx6-3.14/mm/cma.c
  229251. --- linux-3.14.17/mm/cma.c 1970-01-01 01:00:00.000000000 +0100
  229252. +++ linux-imx6-3.14/mm/cma.c 2014-09-11 18:06:15.342091230 +0200
  229253. @@ -0,0 +1,356 @@
  229254. +/*
  229255. + * Contiguous Memory Allocator
  229256. + *
  229257. + * Copyright (c) 2010-2011 by Samsung Electronics.
  229258. + * Copyright IBM Corporation, 2013
  229259. + * Copyright LG Electronics Inc., 2014
  229260. + * Written by:
  229261. + * Marek Szyprowski <m.szyprowski@samsung.com>
  229262. + * Michal Nazarewicz <mina86@mina86.com>
  229263. + * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  229264. + * Joonsoo Kim <iamjoonsoo.kim@lge.com>
  229265. + *
  229266. + * This program is free software; you can redistribute it and/or
  229267. + * modify it under the terms of the GNU General Public License as
  229268. + * published by the Free Software Foundation; either version 2 of the
  229269. + * License or (at your optional) any later version of the license.
  229270. + */
  229271. +
  229272. +#define pr_fmt(fmt) "cma: " fmt
  229273. +
  229274. +#ifdef CONFIG_CMA_DEBUG
  229275. +#ifndef DEBUG
  229276. +# define DEBUG
  229277. +#endif
  229278. +#endif
  229279. +
  229280. +#include <linux/memblock.h>
  229281. +#include <linux/err.h>
  229282. +#include <linux/mm.h>
  229283. +#include <linux/mutex.h>
  229284. +#include <linux/sizes.h>
  229285. +#include <linux/slab.h>
  229286. +#include <linux/log2.h>
  229287. +#include <linux/cma.h>
  229288. +#include <linux/highmem.h>
  229289. +
  229290. +struct cma {
  229291. + unsigned long base_pfn;
  229292. + unsigned long count;
  229293. + unsigned long *bitmap;
  229294. + unsigned int order_per_bit; /* Order of pages represented by one bit */
  229295. + struct mutex lock;
  229296. +};
  229297. +
  229298. +static struct cma cma_areas[MAX_CMA_AREAS];
  229299. +static unsigned cma_area_count;
  229300. +static DEFINE_MUTEX(cma_mutex);
  229301. +
  229302. +phys_addr_t cma_get_base(struct cma *cma)
  229303. +{
  229304. + return PFN_PHYS(cma->base_pfn);
  229305. +}
  229306. +
  229307. +unsigned long cma_get_size(struct cma *cma)
  229308. +{
  229309. + return cma->count << PAGE_SHIFT;
  229310. +}
  229311. +
  229312. +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order)
  229313. +{
  229314. + return (1UL << (align_order >> cma->order_per_bit)) - 1;
  229315. +}
  229316. +
  229317. +static unsigned long cma_bitmap_maxno(struct cma *cma)
  229318. +{
  229319. + return cma->count >> cma->order_per_bit;
  229320. +}
  229321. +
  229322. +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma,
  229323. + unsigned long pages)
  229324. +{
  229325. + return ALIGN(pages, 1UL << cma->order_per_bit) >> cma->order_per_bit;
  229326. +}
  229327. +
  229328. +static void cma_clear_bitmap(struct cma *cma, unsigned long pfn, int count)
  229329. +{
  229330. + unsigned long bitmap_no, bitmap_count;
  229331. +
  229332. + bitmap_no = (pfn - cma->base_pfn) >> cma->order_per_bit;
  229333. + bitmap_count = cma_bitmap_pages_to_bits(cma, count);
  229334. +
  229335. + mutex_lock(&cma->lock);
  229336. + bitmap_clear(cma->bitmap, bitmap_no, bitmap_count);
  229337. + mutex_unlock(&cma->lock);
  229338. +}
  229339. +
  229340. +static int __init cma_activate_area(struct cma *cma)
  229341. +{
  229342. + int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long);
  229343. + unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
  229344. + unsigned i = cma->count >> pageblock_order;
  229345. + struct zone *zone;
  229346. +
  229347. + cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
  229348. +
  229349. + if (!cma->bitmap)
  229350. + return -ENOMEM;
  229351. +
  229352. + WARN_ON_ONCE(!pfn_valid(pfn));
  229353. + zone = page_zone(pfn_to_page(pfn));
  229354. +
  229355. + do {
  229356. + unsigned j;
  229357. +
  229358. + base_pfn = pfn;
  229359. + for (j = pageblock_nr_pages; j; --j, pfn++) {
  229360. + WARN_ON_ONCE(!pfn_valid(pfn));
  229361. + /*
  229362. + * alloc_contig_range requires the pfn range
  229363. + * specified to be in the same zone. Make this
  229364. + * simple by forcing the entire CMA resv range
  229365. + * to be in the same zone.
  229366. + */
  229367. + if (page_zone(pfn_to_page(pfn)) != zone)
  229368. + goto err;
  229369. + }
  229370. + init_cma_reserved_pageblock(pfn_to_page(base_pfn));
  229371. + } while (--i);
  229372. +
  229373. + mutex_init(&cma->lock);
  229374. + return 0;
  229375. +
  229376. +err:
  229377. + kfree(cma->bitmap);
  229378. + return -EINVAL;
  229379. +}
  229380. +
  229381. +static int __init cma_init_reserved_areas(void)
  229382. +{
  229383. + int i;
  229384. +
  229385. + for (i = 0; i < cma_area_count; i++) {
  229386. + int ret = cma_activate_area(&cma_areas[i]);
  229387. +
  229388. + if (ret)
  229389. + return ret;
  229390. + }
  229391. +
  229392. + return 0;
  229393. +}
  229394. +core_initcall(cma_init_reserved_areas);
  229395. +
  229396. +/**
  229397. + * cma_declare_contiguous() - reserve custom contiguous area
  229398. + * @base: Base address of the reserved area optional, use 0 for any
  229399. + * @size: Size of the reserved area (in bytes),
  229400. + * @limit: End address of the reserved memory (optional, 0 for any).
  229401. + * @alignment: Alignment for the CMA area, should be power of 2 or zero
  229402. + * @order_per_bit: Order of pages represented by one bit on bitmap.
  229403. + * @fixed: hint about where to place the reserved area
  229404. + * @res_cma: Pointer to store the created cma region.
  229405. + *
  229406. + * This function reserves memory from early allocator. It should be
  229407. + * called by arch specific code once the early allocator (memblock or bootmem)
  229408. + * has been activated and all other subsystems have already allocated/reserved
  229409. + * memory. This function allows to create custom reserved areas.
  229410. + *
  229411. + * If @fixed is true, reserve contiguous area at exactly @base. If false,
  229412. + * reserve in range from @base to @limit.
  229413. + */
  229414. +int __init cma_declare_contiguous(phys_addr_t base,
  229415. + phys_addr_t size, phys_addr_t limit,
  229416. + phys_addr_t alignment, unsigned int order_per_bit,
  229417. + bool fixed, struct cma **res_cma)
  229418. +{
  229419. + struct cma *cma;
  229420. + phys_addr_t memblock_end = memblock_end_of_DRAM();
  229421. + phys_addr_t highmem_start = __pa(high_memory);
  229422. + int ret = 0;
  229423. +
  229424. + pr_debug("%s(size %lx, base %08lx, limit %08lx alignment %08lx)\n",
  229425. + __func__, (unsigned long)size, (unsigned long)base,
  229426. + (unsigned long)limit, (unsigned long)alignment);
  229427. +
  229428. + if (cma_area_count == ARRAY_SIZE(cma_areas)) {
  229429. + pr_err("Not enough slots for CMA reserved regions!\n");
  229430. + return -ENOSPC;
  229431. + }
  229432. +
  229433. + if (!size)
  229434. + return -EINVAL;
  229435. +
  229436. + if (alignment && !is_power_of_2(alignment))
  229437. + return -EINVAL;
  229438. +
  229439. + /*
  229440. + * Sanitise input arguments.
  229441. + * Pages both ends in CMA area could be merged into adjacent unmovable
  229442. + * migratetype page by page allocator's buddy algorithm. In the case,
  229443. + * you couldn't get a contiguous memory, which is not what we want.
  229444. + */
  229445. + alignment = max(alignment,
  229446. + (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order));
  229447. + base = ALIGN(base, alignment);
  229448. + size = ALIGN(size, alignment);
  229449. + limit &= ~(alignment - 1);
  229450. +
  229451. + /* size should be aligned with order_per_bit */
  229452. + if (!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit))
  229453. + return -EINVAL;
  229454. +
  229455. + /*
  229456. + * adjust limit to avoid crossing low/high memory boundary for
  229457. + * automatically allocated regions
  229458. + */
  229459. + if (((limit == 0 || limit > memblock_end) &&
  229460. + (memblock_end - size < highmem_start &&
  229461. + memblock_end > highmem_start)) ||
  229462. + (!fixed && limit > highmem_start && limit - size < highmem_start)) {
  229463. + limit = highmem_start;
  229464. + }
  229465. +
  229466. + if (fixed && base < highmem_start && base+size > highmem_start) {
  229467. + ret = -EINVAL;
  229468. + pr_err("Region at %08lx defined on low/high memory boundary (%08lx)\n",
  229469. + (unsigned long)base, (unsigned long)highmem_start);
  229470. + goto err;
  229471. + }
  229472. +
  229473. + /* Reserve memory */
  229474. + if (base && fixed) {
  229475. + if (memblock_is_region_reserved(base, size) ||
  229476. + memblock_reserve(base, size) < 0) {
  229477. + ret = -EBUSY;
  229478. + goto err;
  229479. + }
  229480. + } else {
  229481. + phys_addr_t addr = memblock_alloc_range(size, alignment, base,
  229482. + limit);
  229483. + if (!addr) {
  229484. + ret = -ENOMEM;
  229485. + goto err;
  229486. + } else {
  229487. + base = addr;
  229488. + }
  229489. + }
  229490. +
  229491. + /*
  229492. + * Each reserved area must be initialised later, when more kernel
  229493. + * subsystems (like slab allocator) are available.
  229494. + */
  229495. + cma = &cma_areas[cma_area_count];
  229496. + cma->base_pfn = PFN_DOWN(base);
  229497. + cma->count = size >> PAGE_SHIFT;
  229498. + cma->order_per_bit = order_per_bit;
  229499. + *res_cma = cma;
  229500. + cma_area_count++;
  229501. +
  229502. + pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
  229503. + (unsigned long)base);
  229504. + return 0;
  229505. +
  229506. +err:
  229507. + pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
  229508. + return ret;
  229509. +}
  229510. +
  229511. +/**
  229512. + * cma_alloc() - allocate pages from contiguous area
  229513. + * @cma: Contiguous memory region for which the allocation is performed.
  229514. + * @count: Requested number of pages.
  229515. + * @align: Requested alignment of pages (in PAGE_SIZE order).
  229516. + *
  229517. + * This function allocates part of contiguous memory on specific
  229518. + * contiguous memory area.
  229519. + */
  229520. +struct page *cma_alloc(struct cma *cma, int count, unsigned int align)
  229521. +{
  229522. + unsigned long mask, pfn, start = 0;
  229523. + unsigned long bitmap_maxno, bitmap_no, bitmap_count;
  229524. + struct page *page = NULL;
  229525. + int ret;
  229526. +
  229527. + if (!cma || !cma->count)
  229528. + return NULL;
  229529. +
  229530. + pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
  229531. + count, align);
  229532. +
  229533. + if (!count)
  229534. + return NULL;
  229535. +
  229536. + mask = cma_bitmap_aligned_mask(cma, align);
  229537. + bitmap_maxno = cma_bitmap_maxno(cma);
  229538. + bitmap_count = cma_bitmap_pages_to_bits(cma, count);
  229539. +
  229540. + for (;;) {
  229541. + mutex_lock(&cma->lock);
  229542. + bitmap_no = bitmap_find_next_zero_area(cma->bitmap,
  229543. + bitmap_maxno, start, bitmap_count, mask);
  229544. + if (bitmap_no >= bitmap_maxno) {
  229545. + mutex_unlock(&cma->lock);
  229546. + break;
  229547. + }
  229548. + bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
  229549. + /*
  229550. + * It's safe to drop the lock here. We've marked this region for
  229551. + * our exclusive use. If the migration fails we will take the
  229552. + * lock again and unmark it.
  229553. + */
  229554. + mutex_unlock(&cma->lock);
  229555. +
  229556. + pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
  229557. + mutex_lock(&cma_mutex);
  229558. + ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
  229559. + mutex_unlock(&cma_mutex);
  229560. + if (ret == 0) {
  229561. + page = pfn_to_page(pfn);
  229562. + break;
  229563. + }
  229564. +
  229565. + cma_clear_bitmap(cma, pfn, count);
  229566. + if (ret != -EBUSY)
  229567. + break;
  229568. +
  229569. + pr_debug("%s(): memory range at %p is busy, retrying\n",
  229570. + __func__, pfn_to_page(pfn));
  229571. + /* try again with a bit different memory target */
  229572. + start = bitmap_no + mask + 1;
  229573. + }
  229574. +
  229575. + pr_debug("%s(): returned %p\n", __func__, page);
  229576. + return page;
  229577. +}
  229578. +
  229579. +/**
  229580. + * cma_release() - release allocated pages
  229581. + * @cma: Contiguous memory region for which the allocation is performed.
  229582. + * @pages: Allocated pages.
  229583. + * @count: Number of allocated pages.
  229584. + *
  229585. + * This function releases memory allocated by alloc_cma().
  229586. + * It returns false when provided pages do not belong to contiguous area and
  229587. + * true otherwise.
  229588. + */
  229589. +bool cma_release(struct cma *cma, struct page *pages, int count)
  229590. +{
  229591. + unsigned long pfn;
  229592. +
  229593. + if (!cma || !pages)
  229594. + return false;
  229595. +
  229596. + pr_debug("%s(page %p)\n", __func__, (void *)pages);
  229597. +
  229598. + pfn = page_to_pfn(pages);
  229599. +
  229600. + if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
  229601. + return false;
  229602. +
  229603. + VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
  229604. +
  229605. + free_contig_range(pfn, count);
  229606. + cma_clear_bitmap(cma, pfn, count);
  229607. +
  229608. + return true;
  229609. +}
  229610. diff -Nur linux-3.14.17/mm/hugetlb.c linux-imx6-3.14/mm/hugetlb.c
  229611. --- linux-3.14.17/mm/hugetlb.c 2014-08-14 03:38:34.000000000 +0200
  229612. +++ linux-imx6-3.14/mm/hugetlb.c 2014-09-11 18:06:15.346091247 +0200
  229613. @@ -2422,7 +2422,6 @@
  229614. } else {
  229615. if (cow)
  229616. huge_ptep_set_wrprotect(src, addr, src_pte);
  229617. - entry = huge_ptep_get(src_pte);
  229618. ptepage = pte_page(entry);
  229619. get_page(ptepage);
  229620. page_dup_rmap(ptepage);
  229621. diff -Nur linux-3.14.17/mm/Kconfig linux-imx6-3.14/mm/Kconfig
  229622. --- linux-3.14.17/mm/Kconfig 2014-08-14 03:38:34.000000000 +0200
  229623. +++ linux-imx6-3.14/mm/Kconfig 2014-09-11 18:06:15.342091230 +0200
  229624. @@ -514,6 +514,17 @@
  229625. processing calls such as dma_alloc_from_contiguous().
  229626. This option does not affect warning and error messages.
  229627. +config CMA_AREAS
  229628. + int "Maximum count of the CMA areas"
  229629. + depends on CMA
  229630. + default 7
  229631. + help
  229632. + CMA allows to create CMA areas for particular purpose, mainly,
  229633. + used as device private area. This parameter sets the maximum
  229634. + number of CMA area in the system.
  229635. +
  229636. + If unsure, leave the default value "7".
  229637. +
  229638. config ZBUD
  229639. tristate
  229640. default n
  229641. diff -Nur linux-3.14.17/mm/Makefile linux-imx6-3.14/mm/Makefile
  229642. --- linux-3.14.17/mm/Makefile 2014-08-14 03:38:34.000000000 +0200
  229643. +++ linux-imx6-3.14/mm/Makefile 2014-09-11 18:06:15.342091230 +0200
  229644. @@ -61,3 +61,4 @@
  229645. obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
  229646. obj-$(CONFIG_ZBUD) += zbud.o
  229647. obj-$(CONFIG_ZSMALLOC) += zsmalloc.o
  229648. +obj-$(CONFIG_CMA) += cma.o
  229649. diff -Nur linux-3.14.17/mm/memblock.c linux-imx6-3.14/mm/memblock.c
  229650. --- linux-3.14.17/mm/memblock.c 2014-08-14 03:38:34.000000000 +0200
  229651. +++ linux-imx6-3.14/mm/memblock.c 2014-09-11 18:06:15.346091247 +0200
  229652. @@ -975,22 +975,35 @@
  229653. }
  229654. #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
  229655. -static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
  229656. - phys_addr_t align, phys_addr_t max_addr,
  229657. - int nid)
  229658. +static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
  229659. + phys_addr_t align, phys_addr_t start,
  229660. + phys_addr_t end, int nid)
  229661. {
  229662. phys_addr_t found;
  229663. if (!align)
  229664. align = SMP_CACHE_BYTES;
  229665. - found = memblock_find_in_range_node(size, align, 0, max_addr, nid);
  229666. + found = memblock_find_in_range_node(size, align, start, end, nid);
  229667. if (found && !memblock_reserve(found, size))
  229668. return found;
  229669. return 0;
  229670. }
  229671. +phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align,
  229672. + phys_addr_t start, phys_addr_t end)
  229673. +{
  229674. + return memblock_alloc_range_nid(size, align, start, end, NUMA_NO_NODE);
  229675. +}
  229676. +
  229677. +static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
  229678. + phys_addr_t align, phys_addr_t max_addr,
  229679. + int nid)
  229680. +{
  229681. + return memblock_alloc_range_nid(size, align, 0, max_addr, nid);
  229682. +}
  229683. +
  229684. phys_addr_t __init memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid)
  229685. {
  229686. return memblock_alloc_base_nid(size, align, MEMBLOCK_ALLOC_ACCESSIBLE, nid);
  229687. diff -Nur linux-3.14.17/mm/memcontrol.c linux-imx6-3.14/mm/memcontrol.c
  229688. --- linux-3.14.17/mm/memcontrol.c 2014-08-14 03:38:34.000000000 +0200
  229689. +++ linux-imx6-3.14/mm/memcontrol.c 2014-09-11 18:06:15.346091247 +0200
  229690. @@ -5670,12 +5670,8 @@
  229691. {
  229692. struct mem_cgroup_eventfd_list *ev;
  229693. - spin_lock(&memcg_oom_lock);
  229694. -
  229695. list_for_each_entry(ev, &memcg->oom_notify, list)
  229696. eventfd_signal(ev->eventfd, 1);
  229697. -
  229698. - spin_unlock(&memcg_oom_lock);
  229699. return 0;
  229700. }
  229701. diff -Nur linux-3.14.17/mm/page_alloc.c linux-imx6-3.14/mm/page_alloc.c
  229702. --- linux-3.14.17/mm/page_alloc.c 2014-08-14 03:38:34.000000000 +0200
  229703. +++ linux-imx6-3.14/mm/page_alloc.c 2014-09-11 18:06:15.354091278 +0200
  229704. @@ -2434,7 +2434,7 @@
  229705. gfp_to_alloc_flags(gfp_t gfp_mask)
  229706. {
  229707. int alloc_flags = ALLOC_WMARK_MIN | ALLOC_CPUSET;
  229708. - const bool atomic = !(gfp_mask & (__GFP_WAIT | __GFP_NO_KSWAPD));
  229709. + const gfp_t wait = gfp_mask & __GFP_WAIT;
  229710. /* __GFP_HIGH is assumed to be the same as ALLOC_HIGH to save a branch. */
  229711. BUILD_BUG_ON(__GFP_HIGH != (__force gfp_t) ALLOC_HIGH);
  229712. @@ -2443,20 +2443,20 @@
  229713. * The caller may dip into page reserves a bit more if the caller
  229714. * cannot run direct reclaim, or if the caller has realtime scheduling
  229715. * policy or is asking for __GFP_HIGH memory. GFP_ATOMIC requests will
  229716. - * set both ALLOC_HARDER (atomic == true) and ALLOC_HIGH (__GFP_HIGH).
  229717. + * set both ALLOC_HARDER (!wait) and ALLOC_HIGH (__GFP_HIGH).
  229718. */
  229719. alloc_flags |= (__force int) (gfp_mask & __GFP_HIGH);
  229720. - if (atomic) {
  229721. + if (!wait) {
  229722. /*
  229723. - * Not worth trying to allocate harder for __GFP_NOMEMALLOC even
  229724. - * if it can't schedule.
  229725. + * Not worth trying to allocate harder for
  229726. + * __GFP_NOMEMALLOC even if it can't schedule.
  229727. */
  229728. - if (!(gfp_mask & __GFP_NOMEMALLOC))
  229729. + if (!(gfp_mask & __GFP_NOMEMALLOC))
  229730. alloc_flags |= ALLOC_HARDER;
  229731. /*
  229732. - * Ignore cpuset mems for GFP_ATOMIC rather than fail, see the
  229733. - * comment for __cpuset_node_allowed_softwall().
  229734. + * Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc.
  229735. + * See also cpuset_zone_allowed() comment in kernel/cpuset.c.
  229736. */
  229737. alloc_flags &= ~ALLOC_CPUSET;
  229738. } else if (unlikely(rt_task(current)) && !in_interrupt())
  229739. diff -Nur linux-3.14.17/mm/page-writeback.c linux-imx6-3.14/mm/page-writeback.c
  229740. --- linux-3.14.17/mm/page-writeback.c 2014-08-14 03:38:34.000000000 +0200
  229741. +++ linux-imx6-3.14/mm/page-writeback.c 2014-09-11 18:06:15.354091278 +0200
  229742. @@ -1324,9 +1324,9 @@
  229743. *bdi_thresh = bdi_dirty_limit(bdi, dirty_thresh);
  229744. if (bdi_bg_thresh)
  229745. - *bdi_bg_thresh = dirty_thresh ? div_u64((u64)*bdi_thresh *
  229746. - background_thresh,
  229747. - dirty_thresh) : 0;
  229748. + *bdi_bg_thresh = div_u64((u64)*bdi_thresh *
  229749. + background_thresh,
  229750. + dirty_thresh);
  229751. /*
  229752. * In order to avoid the stacked BDI deadlock we need
  229753. diff -Nur linux-3.14.17/mm/slab_common.c linux-imx6-3.14/mm/slab_common.c
  229754. --- linux-3.14.17/mm/slab_common.c 2014-08-14 03:38:34.000000000 +0200
  229755. +++ linux-imx6-3.14/mm/slab_common.c 2014-09-11 18:06:15.358091295 +0200
  229756. @@ -56,7 +56,7 @@
  229757. continue;
  229758. }
  229759. -#if !defined(CONFIG_SLUB)
  229760. +#if !defined(CONFIG_SLUB) || !defined(CONFIG_SLUB_DEBUG_ON)
  229761. /*
  229762. * For simplicity, we won't check this in the list of memcg
  229763. * caches. We have control over memcg naming, and if there
  229764. diff -Nur linux-3.14.17/net/atm/svc.c linux-imx6-3.14/net/atm/svc.c
  229765. --- linux-3.14.17/net/atm/svc.c 2014-08-14 03:38:34.000000000 +0200
  229766. +++ linux-imx6-3.14/net/atm/svc.c 2014-09-11 18:06:15.426091565 +0200
  229767. @@ -263,17 +263,11 @@
  229768. goto out;
  229769. }
  229770. }
  229771. -/*
  229772. - * Not supported yet
  229773. - *
  229774. - * #ifndef CONFIG_SINGLE_SIGITF
  229775. - */
  229776. +
  229777. vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp);
  229778. vcc->qos.txtp.pcr = 0;
  229779. vcc->qos.txtp.min_pcr = 0;
  229780. -/*
  229781. - * #endif
  229782. - */
  229783. +
  229784. error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci);
  229785. if (!error)
  229786. sock->state = SS_CONNECTED;
  229787. diff -Nur linux-3.14.17/net/batman-adv/fragmentation.c linux-imx6-3.14/net/batman-adv/fragmentation.c
  229788. --- linux-3.14.17/net/batman-adv/fragmentation.c 2014-08-14 03:38:34.000000000 +0200
  229789. +++ linux-imx6-3.14/net/batman-adv/fragmentation.c 2014-09-11 18:06:15.434091598 +0200
  229790. @@ -128,7 +128,6 @@
  229791. {
  229792. struct batadv_frag_table_entry *chain;
  229793. struct batadv_frag_list_entry *frag_entry_new = NULL, *frag_entry_curr;
  229794. - struct batadv_frag_list_entry *frag_entry_last = NULL;
  229795. struct batadv_frag_packet *frag_packet;
  229796. uint8_t bucket;
  229797. uint16_t seqno, hdr_size = sizeof(struct batadv_frag_packet);
  229798. @@ -181,14 +180,11 @@
  229799. ret = true;
  229800. goto out;
  229801. }
  229802. -
  229803. - /* store current entry because it could be the last in list */
  229804. - frag_entry_last = frag_entry_curr;
  229805. }
  229806. - /* Reached the end of the list, so insert after 'frag_entry_last'. */
  229807. - if (likely(frag_entry_last)) {
  229808. - hlist_add_after(&frag_entry_last->list, &frag_entry_new->list);
  229809. + /* Reached the end of the list, so insert after 'frag_entry_curr'. */
  229810. + if (likely(frag_entry_curr)) {
  229811. + hlist_add_after(&frag_entry_curr->list, &frag_entry_new->list);
  229812. chain->size += skb->len - hdr_size;
  229813. chain->timestamp = jiffies;
  229814. ret = true;
  229815. diff -Nur linux-3.14.17/net/compat.c linux-imx6-3.14/net/compat.c
  229816. --- linux-3.14.17/net/compat.c 2014-08-14 03:38:34.000000000 +0200
  229817. +++ linux-imx6-3.14/net/compat.c 2014-09-11 18:06:15.510091900 +0200
  229818. @@ -85,7 +85,7 @@
  229819. {
  229820. int tot_len;
  229821. - if (kern_msg->msg_name && kern_msg->msg_namelen) {
  229822. + if (kern_msg->msg_namelen) {
  229823. if (mode == VERIFY_READ) {
  229824. int err = move_addr_to_kernel(kern_msg->msg_name,
  229825. kern_msg->msg_namelen,
  229826. @@ -93,11 +93,10 @@
  229827. if (err < 0)
  229828. return err;
  229829. }
  229830. - kern_msg->msg_name = kern_address;
  229831. - } else {
  229832. + if (kern_msg->msg_name)
  229833. + kern_msg->msg_name = kern_address;
  229834. + } else
  229835. kern_msg->msg_name = NULL;
  229836. - kern_msg->msg_namelen = 0;
  229837. - }
  229838. tot_len = iov_from_user_compat_to_kern(kern_iov,
  229839. (struct compat_iovec __user *)kern_msg->msg_iov,
  229840. diff -Nur linux-3.14.17/net/core/dev.c linux-imx6-3.14/net/core/dev.c
  229841. --- linux-3.14.17/net/core/dev.c 2014-08-14 03:38:34.000000000 +0200
  229842. +++ linux-imx6-3.14/net/core/dev.c 2014-09-11 18:06:15.510091900 +0200
  229843. @@ -3453,7 +3453,7 @@
  229844. * @rx_handler: receive handler to register
  229845. * @rx_handler_data: data pointer that is used by rx handler
  229846. *
  229847. - * Register a receive hander for a device. This handler will then be
  229848. + * Register a receive handler for a device. This handler will then be
  229849. * called from __netif_receive_skb. A negative errno code is returned
  229850. * on a failure.
  229851. *
  229852. diff -Nur linux-3.14.17/net/core/iovec.c linux-imx6-3.14/net/core/iovec.c
  229853. --- linux-3.14.17/net/core/iovec.c 2014-08-14 03:38:34.000000000 +0200
  229854. +++ linux-imx6-3.14/net/core/iovec.c 2014-09-11 18:06:15.514091916 +0200
  229855. @@ -39,7 +39,7 @@
  229856. {
  229857. int size, ct, err;
  229858. - if (m->msg_name && m->msg_namelen) {
  229859. + if (m->msg_namelen) {
  229860. if (mode == VERIFY_READ) {
  229861. void __user *namep;
  229862. namep = (void __user __force *) m->msg_name;
  229863. @@ -48,10 +48,10 @@
  229864. if (err < 0)
  229865. return err;
  229866. }
  229867. - m->msg_name = address;
  229868. + if (m->msg_name)
  229869. + m->msg_name = address;
  229870. } else {
  229871. m->msg_name = NULL;
  229872. - m->msg_namelen = 0;
  229873. }
  229874. size = m->msg_iovlen * sizeof(struct iovec);
  229875. @@ -107,10 +107,6 @@
  229876. int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
  229877. int offset, int len)
  229878. {
  229879. - /* No data? Done! */
  229880. - if (len == 0)
  229881. - return 0;
  229882. -
  229883. /* Skip over the finished iovecs */
  229884. while (offset >= iov->iov_len) {
  229885. offset -= iov->iov_len;
  229886. diff -Nur linux-3.14.17/net/core/Makefile linux-imx6-3.14/net/core/Makefile
  229887. --- linux-3.14.17/net/core/Makefile 2014-08-14 03:38:34.000000000 +0200
  229888. +++ linux-imx6-3.14/net/core/Makefile 2014-09-11 18:06:15.510091900 +0200
  229889. @@ -9,7 +9,7 @@
  229890. obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \
  229891. neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
  229892. - sock_diag.o dev_ioctl.o
  229893. + sock_diag.o dev_ioctl.o tso.o
  229894. obj-$(CONFIG_XFRM) += flow.o
  229895. obj-y += net-sysfs.o
  229896. diff -Nur linux-3.14.17/net/core/rtnetlink.c linux-imx6-3.14/net/core/rtnetlink.c
  229897. --- linux-3.14.17/net/core/rtnetlink.c 2014-08-14 03:38:34.000000000 +0200
  229898. +++ linux-imx6-3.14/net/core/rtnetlink.c 2014-09-11 18:06:15.518091933 +0200
  229899. @@ -1156,73 +1156,7 @@
  229900. return -EMSGSIZE;
  229901. }
  229902. -static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
  229903. -{
  229904. - struct net *net = sock_net(skb->sk);
  229905. - int h, s_h;
  229906. - int idx = 0, s_idx;
  229907. - struct net_device *dev;
  229908. - struct hlist_head *head;
  229909. - struct nlattr *tb[IFLA_MAX+1];
  229910. - u32 ext_filter_mask = 0;
  229911. - int err;
  229912. - int hdrlen;
  229913. -
  229914. - s_h = cb->args[0];
  229915. - s_idx = cb->args[1];
  229916. -
  229917. - rcu_read_lock();
  229918. - cb->seq = net->dev_base_seq;
  229919. -
  229920. - /* A hack to preserve kernel<->userspace interface.
  229921. - * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
  229922. - * However, before Linux v3.9 the code here assumed rtgenmsg and that's
  229923. - * what iproute2 < v3.9.0 used.
  229924. - * We can detect the old iproute2. Even including the IFLA_EXT_MASK
  229925. - * attribute, its netlink message is shorter than struct ifinfomsg.
  229926. - */
  229927. - hdrlen = nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg) ?
  229928. - sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
  229929. -
  229930. - if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy) >= 0) {
  229931. -
  229932. - if (tb[IFLA_EXT_MASK])
  229933. - ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
  229934. - }
  229935. -
  229936. - for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
  229937. - idx = 0;
  229938. - head = &net->dev_index_head[h];
  229939. - hlist_for_each_entry_rcu(dev, head, index_hlist) {
  229940. - if (idx < s_idx)
  229941. - goto cont;
  229942. - err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
  229943. - NETLINK_CB(cb->skb).portid,
  229944. - cb->nlh->nlmsg_seq, 0,
  229945. - NLM_F_MULTI,
  229946. - ext_filter_mask);
  229947. - /* If we ran out of room on the first message,
  229948. - * we're in trouble
  229949. - */
  229950. - WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
  229951. -
  229952. - if (err <= 0)
  229953. - goto out;
  229954. -
  229955. - nl_dump_check_consistent(cb, nlmsg_hdr(skb));
  229956. -cont:
  229957. - idx++;
  229958. - }
  229959. - }
  229960. -out:
  229961. - rcu_read_unlock();
  229962. - cb->args[1] = idx;
  229963. - cb->args[0] = h;
  229964. -
  229965. - return skb->len;
  229966. -}
  229967. -
  229968. -const struct nla_policy ifla_policy[IFLA_MAX+1] = {
  229969. +static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
  229970. [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
  229971. [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  229972. [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  229973. @@ -1249,7 +1183,6 @@
  229974. [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
  229975. [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
  229976. };
  229977. -EXPORT_SYMBOL(ifla_policy);
  229978. static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
  229979. [IFLA_INFO_KIND] = { .type = NLA_STRING },
  229980. @@ -1287,6 +1220,61 @@
  229981. [IFLA_PORT_RESPONSE] = { .type = NLA_U16, },
  229982. };
  229983. +static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
  229984. +{
  229985. + struct net *net = sock_net(skb->sk);
  229986. + int h, s_h;
  229987. + int idx = 0, s_idx;
  229988. + struct net_device *dev;
  229989. + struct hlist_head *head;
  229990. + struct nlattr *tb[IFLA_MAX+1];
  229991. + u32 ext_filter_mask = 0;
  229992. +
  229993. + s_h = cb->args[0];
  229994. + s_idx = cb->args[1];
  229995. +
  229996. + rcu_read_lock();
  229997. + cb->seq = net->dev_base_seq;
  229998. +
  229999. + if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
  230000. + ifla_policy) >= 0) {
  230001. +
  230002. + if (tb[IFLA_EXT_MASK])
  230003. + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
  230004. + }
  230005. +
  230006. + for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
  230007. + idx = 0;
  230008. + head = &net->dev_index_head[h];
  230009. + hlist_for_each_entry_rcu(dev, head, index_hlist) {
  230010. + if (idx < s_idx)
  230011. + goto cont;
  230012. + if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
  230013. + NETLINK_CB(cb->skb).portid,
  230014. + cb->nlh->nlmsg_seq, 0,
  230015. + NLM_F_MULTI,
  230016. + ext_filter_mask) <= 0)
  230017. + goto out;
  230018. +
  230019. + nl_dump_check_consistent(cb, nlmsg_hdr(skb));
  230020. +cont:
  230021. + idx++;
  230022. + }
  230023. + }
  230024. +out:
  230025. + rcu_read_unlock();
  230026. + cb->args[1] = idx;
  230027. + cb->args[0] = h;
  230028. +
  230029. + return skb->len;
  230030. +}
  230031. +
  230032. +int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len)
  230033. +{
  230034. + return nla_parse(tb, IFLA_MAX, head, len, ifla_policy);
  230035. +}
  230036. +EXPORT_SYMBOL(rtnl_nla_parse_ifla);
  230037. +
  230038. struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
  230039. {
  230040. struct net *net;
  230041. diff -Nur linux-3.14.17/net/core/secure_seq.c linux-imx6-3.14/net/core/secure_seq.c
  230042. --- linux-3.14.17/net/core/secure_seq.c 2014-08-14 03:38:34.000000000 +0200
  230043. +++ linux-imx6-3.14/net/core/secure_seq.c 2014-09-11 18:06:15.518091933 +0200
  230044. @@ -85,6 +85,31 @@
  230045. #endif
  230046. #ifdef CONFIG_INET
  230047. +__u32 secure_ip_id(__be32 daddr)
  230048. +{
  230049. + u32 hash[MD5_DIGEST_WORDS];
  230050. +
  230051. + net_secret_init();
  230052. + hash[0] = (__force __u32) daddr;
  230053. + hash[1] = net_secret[13];
  230054. + hash[2] = net_secret[14];
  230055. + hash[3] = net_secret[15];
  230056. +
  230057. + md5_transform(hash, net_secret);
  230058. +
  230059. + return hash[0];
  230060. +}
  230061. +
  230062. +__u32 secure_ipv6_id(const __be32 daddr[4])
  230063. +{
  230064. + __u32 hash[4];
  230065. +
  230066. + net_secret_init();
  230067. + memcpy(hash, daddr, 16);
  230068. + md5_transform(hash, net_secret);
  230069. +
  230070. + return hash[0];
  230071. +}
  230072. __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
  230073. __be16 sport, __be16 dport)
  230074. diff -Nur linux-3.14.17/net/core/skbuff.c linux-imx6-3.14/net/core/skbuff.c
  230075. --- linux-3.14.17/net/core/skbuff.c 2014-08-14 03:38:34.000000000 +0200
  230076. +++ linux-imx6-3.14/net/core/skbuff.c 2014-09-11 18:06:15.518091933 +0200
  230077. @@ -2968,9 +2968,9 @@
  230078. tail = nskb;
  230079. __copy_skb_header(nskb, head_skb);
  230080. + nskb->mac_len = head_skb->mac_len;
  230081. skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom);
  230082. - skb_reset_mac_len(nskb);
  230083. skb_copy_from_linear_data_offset(head_skb, -tnl_hlen,
  230084. nskb->data - tnl_hlen,
  230085. diff -Nur linux-3.14.17/net/core/tso.c linux-imx6-3.14/net/core/tso.c
  230086. --- linux-3.14.17/net/core/tso.c 1970-01-01 01:00:00.000000000 +0100
  230087. +++ linux-imx6-3.14/net/core/tso.c 2014-09-11 18:06:15.522091948 +0200
  230088. @@ -0,0 +1,72 @@
  230089. +#include <net/ip.h>
  230090. +#include <net/tso.h>
  230091. +
  230092. +/* Calculate expected number of TX descriptors */
  230093. +int tso_count_descs(struct sk_buff *skb)
  230094. +{
  230095. + /* The Marvell Way */
  230096. + return skb_shinfo(skb)->gso_segs * 2 + skb_shinfo(skb)->nr_frags;
  230097. +}
  230098. +
  230099. +void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
  230100. + int size, bool is_last)
  230101. +{
  230102. + struct iphdr *iph;
  230103. + struct tcphdr *tcph;
  230104. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  230105. + int mac_hdr_len = skb_network_offset(skb);
  230106. +
  230107. + memcpy(hdr, skb->data, hdr_len);
  230108. + iph = (struct iphdr *)(hdr + mac_hdr_len);
  230109. + iph->id = htons(tso->ip_id);
  230110. + iph->tot_len = htons(size + hdr_len - mac_hdr_len);
  230111. + tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
  230112. + tcph->seq = htonl(tso->tcp_seq);
  230113. + tso->ip_id++;
  230114. +
  230115. + if (!is_last) {
  230116. + /* Clear all special flags for not last packet */
  230117. + tcph->psh = 0;
  230118. + tcph->fin = 0;
  230119. + tcph->rst = 0;
  230120. + }
  230121. +}
  230122. +
  230123. +void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size)
  230124. +{
  230125. + tso->tcp_seq += size;
  230126. + tso->size -= size;
  230127. + tso->data += size;
  230128. +
  230129. + if ((tso->size == 0) &&
  230130. + (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
  230131. + skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
  230132. +
  230133. + /* Move to next segment */
  230134. + tso->size = frag->size;
  230135. + tso->data = page_address(frag->page.p) + frag->page_offset;
  230136. + tso->next_frag_idx++;
  230137. + }
  230138. +}
  230139. +
  230140. +void tso_start(struct sk_buff *skb, struct tso_t *tso)
  230141. +{
  230142. + int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
  230143. +
  230144. + tso->ip_id = ntohs(ip_hdr(skb)->id);
  230145. + tso->tcp_seq = ntohl(tcp_hdr(skb)->seq);
  230146. + tso->next_frag_idx = 0;
  230147. +
  230148. + /* Build first data */
  230149. + tso->size = skb_headlen(skb) - hdr_len;
  230150. + tso->data = skb->data + hdr_len;
  230151. + if ((tso->size == 0) &&
  230152. + (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
  230153. + skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
  230154. +
  230155. + /* Move to next segment */
  230156. + tso->size = frag->size;
  230157. + tso->data = page_address(frag->page.p) + frag->page_offset;
  230158. + tso->next_frag_idx++;
  230159. + }
  230160. +}
  230161. diff -Nur linux-3.14.17/net/ieee802154/Kconfig linux-imx6-3.14/net/ieee802154/Kconfig
  230162. --- linux-3.14.17/net/ieee802154/Kconfig 2014-08-14 03:38:34.000000000 +0200
  230163. +++ linux-imx6-3.14/net/ieee802154/Kconfig 2014-09-11 18:06:15.578092171 +0200
  230164. @@ -15,7 +15,7 @@
  230165. depends on IEEE802154 && IPV6
  230166. select 6LOWPAN_IPHC
  230167. ---help---
  230168. - IPv6 compression over IEEE 802.15.4.
  230169. + IPv6 compression over IEEE 802.15.4.
  230170. config 6LOWPAN_IPHC
  230171. tristate
  230172. diff -Nur linux-3.14.17/net/ipv4/igmp.c linux-imx6-3.14/net/ipv4/igmp.c
  230173. --- linux-3.14.17/net/ipv4/igmp.c 2014-08-14 03:38:34.000000000 +0200
  230174. +++ linux-imx6-3.14/net/ipv4/igmp.c 2014-09-11 18:06:15.586092204 +0200
  230175. @@ -369,7 +369,7 @@
  230176. pip->saddr = fl4.saddr;
  230177. pip->protocol = IPPROTO_IGMP;
  230178. pip->tot_len = 0; /* filled in later */
  230179. - ip_select_ident(skb, NULL);
  230180. + ip_select_ident(skb, &rt->dst, NULL);
  230181. ((u8 *)&pip[1])[0] = IPOPT_RA;
  230182. ((u8 *)&pip[1])[1] = 4;
  230183. ((u8 *)&pip[1])[2] = 0;
  230184. @@ -714,7 +714,7 @@
  230185. iph->daddr = dst;
  230186. iph->saddr = fl4.saddr;
  230187. iph->protocol = IPPROTO_IGMP;
  230188. - ip_select_ident(skb, NULL);
  230189. + ip_select_ident(skb, &rt->dst, NULL);
  230190. ((u8 *)&iph[1])[0] = IPOPT_RA;
  230191. ((u8 *)&iph[1])[1] = 4;
  230192. ((u8 *)&iph[1])[2] = 0;
  230193. diff -Nur linux-3.14.17/net/ipv4/inetpeer.c linux-imx6-3.14/net/ipv4/inetpeer.c
  230194. --- linux-3.14.17/net/ipv4/inetpeer.c 2014-08-14 03:38:34.000000000 +0200
  230195. +++ linux-imx6-3.14/net/ipv4/inetpeer.c 2014-09-11 18:06:15.586092204 +0200
  230196. @@ -26,7 +26,20 @@
  230197. * Theory of operations.
  230198. * We keep one entry for each peer IP address. The nodes contains long-living
  230199. * information about the peer which doesn't depend on routes.
  230200. + * At this moment this information consists only of ID field for the next
  230201. + * outgoing IP packet. This field is incremented with each packet as encoded
  230202. + * in inet_getid() function (include/net/inetpeer.h).
  230203. + * At the moment of writing this notes identifier of IP packets is generated
  230204. + * to be unpredictable using this code only for packets subjected
  230205. + * (actually or potentially) to defragmentation. I.e. DF packets less than
  230206. + * PMTU in size when local fragmentation is disabled use a constant ID and do
  230207. + * not use this code (see ip_select_ident() in include/net/ip.h).
  230208. *
  230209. + * Route cache entries hold references to our nodes.
  230210. + * New cache entries get references via lookup by destination IP address in
  230211. + * the avl tree. The reference is grabbed only when it's needed i.e. only
  230212. + * when we try to output IP packet which needs an unpredictable ID (see
  230213. + * __ip_select_ident() in net/ipv4/route.c).
  230214. * Nodes are removed only when reference counter goes to 0.
  230215. * When it's happened the node may be removed when a sufficient amount of
  230216. * time has been passed since its last use. The less-recently-used entry can
  230217. @@ -49,6 +62,7 @@
  230218. * refcnt: atomically against modifications on other CPU;
  230219. * usually under some other lock to prevent node disappearing
  230220. * daddr: unchangeable
  230221. + * ip_id_count: atomic value (no lock needed)
  230222. */
  230223. static struct kmem_cache *peer_cachep __read_mostly;
  230224. @@ -483,6 +497,10 @@
  230225. p->daddr = *daddr;
  230226. atomic_set(&p->refcnt, 1);
  230227. atomic_set(&p->rid, 0);
  230228. + atomic_set(&p->ip_id_count,
  230229. + (daddr->family == AF_INET) ?
  230230. + secure_ip_id(daddr->addr.a4) :
  230231. + secure_ipv6_id(daddr->addr.a6));
  230232. p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
  230233. p->rate_tokens = 0;
  230234. /* 60*HZ is arbitrary, but chosen enough high so that the first
  230235. diff -Nur linux-3.14.17/net/ipv4/ipmr.c linux-imx6-3.14/net/ipv4/ipmr.c
  230236. --- linux-3.14.17/net/ipv4/ipmr.c 2014-08-14 03:38:34.000000000 +0200
  230237. +++ linux-imx6-3.14/net/ipv4/ipmr.c 2014-09-11 18:06:15.590092220 +0200
  230238. @@ -1663,7 +1663,7 @@
  230239. iph->protocol = IPPROTO_IPIP;
  230240. iph->ihl = 5;
  230241. iph->tot_len = htons(skb->len);
  230242. - ip_select_ident(skb, NULL);
  230243. + ip_select_ident(skb, skb_dst(skb), NULL);
  230244. ip_send_check(iph);
  230245. memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
  230246. diff -Nur linux-3.14.17/net/ipv4/ip_output.c linux-imx6-3.14/net/ipv4/ip_output.c
  230247. --- linux-3.14.17/net/ipv4/ip_output.c 2014-08-14 03:38:34.000000000 +0200
  230248. +++ linux-imx6-3.14/net/ipv4/ip_output.c 2014-09-11 18:06:15.590092220 +0200
  230249. @@ -148,7 +148,7 @@
  230250. iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr);
  230251. iph->saddr = saddr;
  230252. iph->protocol = sk->sk_protocol;
  230253. - ip_select_ident(skb, sk);
  230254. + ip_select_ident(skb, &rt->dst, sk);
  230255. if (opt && opt->opt.optlen) {
  230256. iph->ihl += opt->opt.optlen>>2;
  230257. @@ -386,7 +386,8 @@
  230258. ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0);
  230259. }
  230260. - ip_select_ident_segs(skb, sk, skb_shinfo(skb)->gso_segs ?: 1);
  230261. + ip_select_ident_more(skb, &rt->dst, sk,
  230262. + (skb_shinfo(skb)->gso_segs ?: 1) - 1);
  230263. skb->priority = sk->sk_priority;
  230264. skb->mark = sk->sk_mark;
  230265. @@ -1337,7 +1338,7 @@
  230266. iph->ttl = ttl;
  230267. iph->protocol = sk->sk_protocol;
  230268. ip_copy_addrs(iph, fl4);
  230269. - ip_select_ident(skb, sk);
  230270. + ip_select_ident(skb, &rt->dst, sk);
  230271. if (opt) {
  230272. iph->ihl += opt->optlen>>2;
  230273. diff -Nur linux-3.14.17/net/ipv4/ip_tunnel.c linux-imx6-3.14/net/ipv4/ip_tunnel.c
  230274. --- linux-3.14.17/net/ipv4/ip_tunnel.c 2014-08-14 03:38:34.000000000 +0200
  230275. +++ linux-imx6-3.14/net/ipv4/ip_tunnel.c 2014-09-11 18:06:15.590092220 +0200
  230276. @@ -69,25 +69,23 @@
  230277. }
  230278. static void __tunnel_dst_set(struct ip_tunnel_dst *idst,
  230279. - struct dst_entry *dst, __be32 saddr)
  230280. + struct dst_entry *dst)
  230281. {
  230282. struct dst_entry *old_dst;
  230283. dst_clone(dst);
  230284. old_dst = xchg((__force struct dst_entry **)&idst->dst, dst);
  230285. dst_release(old_dst);
  230286. - idst->saddr = saddr;
  230287. }
  230288. -static void tunnel_dst_set(struct ip_tunnel *t,
  230289. - struct dst_entry *dst, __be32 saddr)
  230290. +static void tunnel_dst_set(struct ip_tunnel *t, struct dst_entry *dst)
  230291. {
  230292. - __tunnel_dst_set(this_cpu_ptr(t->dst_cache), dst, saddr);
  230293. + __tunnel_dst_set(this_cpu_ptr(t->dst_cache), dst);
  230294. }
  230295. static void tunnel_dst_reset(struct ip_tunnel *t)
  230296. {
  230297. - tunnel_dst_set(t, NULL, 0);
  230298. + tunnel_dst_set(t, NULL);
  230299. }
  230300. void ip_tunnel_dst_reset_all(struct ip_tunnel *t)
  230301. @@ -95,25 +93,20 @@
  230302. int i;
  230303. for_each_possible_cpu(i)
  230304. - __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL, 0);
  230305. + __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL);
  230306. }
  230307. EXPORT_SYMBOL(ip_tunnel_dst_reset_all);
  230308. -static struct rtable *tunnel_rtable_get(struct ip_tunnel *t,
  230309. - u32 cookie, __be32 *saddr)
  230310. +static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie)
  230311. {
  230312. - struct ip_tunnel_dst *idst;
  230313. struct dst_entry *dst;
  230314. rcu_read_lock();
  230315. - idst = this_cpu_ptr(t->dst_cache);
  230316. - dst = rcu_dereference(idst->dst);
  230317. + dst = rcu_dereference(this_cpu_ptr(t->dst_cache)->dst);
  230318. if (dst && !atomic_inc_not_zero(&dst->__refcnt))
  230319. dst = NULL;
  230320. if (dst) {
  230321. - if (!dst->obsolete || dst->ops->check(dst, cookie)) {
  230322. - *saddr = idst->saddr;
  230323. - } else {
  230324. + if (dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
  230325. tunnel_dst_reset(t);
  230326. dst_release(dst);
  230327. dst = NULL;
  230328. @@ -369,7 +362,7 @@
  230329. if (!IS_ERR(rt)) {
  230330. tdev = rt->dst.dev;
  230331. - tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
  230332. + tunnel_dst_set(tunnel, &rt->dst);
  230333. ip_rt_put(rt);
  230334. }
  230335. if (dev->type != ARPHRD_ETHER)
  230336. @@ -613,7 +606,7 @@
  230337. init_tunnel_flow(&fl4, protocol, dst, tnl_params->saddr,
  230338. tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link);
  230339. - rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL;
  230340. + rt = connected ? tunnel_rtable_get(tunnel, 0) : NULL;
  230341. if (!rt) {
  230342. rt = ip_route_output_key(tunnel->net, &fl4);
  230343. @@ -623,7 +616,7 @@
  230344. goto tx_error;
  230345. }
  230346. if (connected)
  230347. - tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
  230348. + tunnel_dst_set(tunnel, &rt->dst);
  230349. }
  230350. if (rt->dst.dev == dev) {
  230351. diff -Nur linux-3.14.17/net/ipv4/ip_tunnel_core.c linux-imx6-3.14/net/ipv4/ip_tunnel_core.c
  230352. --- linux-3.14.17/net/ipv4/ip_tunnel_core.c 2014-08-14 03:38:34.000000000 +0200
  230353. +++ linux-imx6-3.14/net/ipv4/ip_tunnel_core.c 2014-09-11 18:06:15.590092220 +0200
  230354. @@ -74,7 +74,7 @@
  230355. iph->daddr = dst;
  230356. iph->saddr = src;
  230357. iph->ttl = ttl;
  230358. - __ip_select_ident(iph, skb_shinfo(skb)->gso_segs ?: 1);
  230359. + __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1);
  230360. err = ip_local_out(skb);
  230361. if (unlikely(net_xmit_eval(err)))
  230362. diff -Nur linux-3.14.17/net/ipv4/raw.c linux-imx6-3.14/net/ipv4/raw.c
  230363. --- linux-3.14.17/net/ipv4/raw.c 2014-08-14 03:38:34.000000000 +0200
  230364. +++ linux-imx6-3.14/net/ipv4/raw.c 2014-09-11 18:06:15.626092363 +0200
  230365. @@ -389,7 +389,7 @@
  230366. iph->check = 0;
  230367. iph->tot_len = htons(length);
  230368. if (!iph->id)
  230369. - ip_select_ident(skb, NULL);
  230370. + ip_select_ident(skb, &rt->dst, NULL);
  230371. iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
  230372. }
  230373. diff -Nur linux-3.14.17/net/ipv4/route.c linux-imx6-3.14/net/ipv4/route.c
  230374. --- linux-3.14.17/net/ipv4/route.c 2014-08-14 03:38:34.000000000 +0200
  230375. +++ linux-imx6-3.14/net/ipv4/route.c 2014-09-11 18:06:15.630092380 +0200
  230376. @@ -89,7 +89,6 @@
  230377. #include <linux/rcupdate.h>
  230378. #include <linux/times.h>
  230379. #include <linux/slab.h>
  230380. -#include <linux/jhash.h>
  230381. #include <net/dst.h>
  230382. #include <net/net_namespace.h>
  230383. #include <net/protocol.h>
  230384. @@ -463,45 +462,39 @@
  230385. return neigh_create(&arp_tbl, pkey, dev);
  230386. }
  230387. -#define IP_IDENTS_SZ 2048u
  230388. -struct ip_ident_bucket {
  230389. - atomic_t id;
  230390. - u32 stamp32;
  230391. -};
  230392. -
  230393. -static struct ip_ident_bucket *ip_idents __read_mostly;
  230394. -
  230395. -/* In order to protect privacy, we add a perturbation to identifiers
  230396. - * if one generator is seldom used. This makes hard for an attacker
  230397. - * to infer how many packets were sent between two points in time.
  230398. +/*
  230399. + * Peer allocation may fail only in serious out-of-memory conditions. However
  230400. + * we still can generate some output.
  230401. + * Random ID selection looks a bit dangerous because we have no chances to
  230402. + * select ID being unique in a reasonable period of time.
  230403. + * But broken packet identifier may be better than no packet at all.
  230404. */
  230405. -u32 ip_idents_reserve(u32 hash, int segs)
  230406. +static void ip_select_fb_ident(struct iphdr *iph)
  230407. {
  230408. - struct ip_ident_bucket *bucket = ip_idents + hash % IP_IDENTS_SZ;
  230409. - u32 old = ACCESS_ONCE(bucket->stamp32);
  230410. - u32 now = (u32)jiffies;
  230411. - u32 delta = 0;
  230412. -
  230413. - if (old != now && cmpxchg(&bucket->stamp32, old, now) == old)
  230414. - delta = prandom_u32_max(now - old);
  230415. + static DEFINE_SPINLOCK(ip_fb_id_lock);
  230416. + static u32 ip_fallback_id;
  230417. + u32 salt;
  230418. - return atomic_add_return(segs + delta, &bucket->id) - segs;
  230419. + spin_lock_bh(&ip_fb_id_lock);
  230420. + salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr);
  230421. + iph->id = htons(salt & 0xFFFF);
  230422. + ip_fallback_id = salt;
  230423. + spin_unlock_bh(&ip_fb_id_lock);
  230424. }
  230425. -EXPORT_SYMBOL(ip_idents_reserve);
  230426. -void __ip_select_ident(struct iphdr *iph, int segs)
  230427. +void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
  230428. {
  230429. - static u32 ip_idents_hashrnd __read_mostly;
  230430. - u32 hash, id;
  230431. + struct net *net = dev_net(dst->dev);
  230432. + struct inet_peer *peer;
  230433. - net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd));
  230434. + peer = inet_getpeer_v4(net->ipv4.peers, iph->daddr, 1);
  230435. + if (peer) {
  230436. + iph->id = htons(inet_getid(peer, more));
  230437. + inet_putpeer(peer);
  230438. + return;
  230439. + }
  230440. - hash = jhash_3words((__force u32)iph->daddr,
  230441. - (__force u32)iph->saddr,
  230442. - iph->protocol,
  230443. - ip_idents_hashrnd);
  230444. - id = ip_idents_reserve(hash, segs);
  230445. - iph->id = htons(id);
  230446. + ip_select_fb_ident(iph);
  230447. }
  230448. EXPORT_SYMBOL(__ip_select_ident);
  230449. @@ -2725,12 +2718,6 @@
  230450. {
  230451. int rc = 0;
  230452. - ip_idents = kmalloc(IP_IDENTS_SZ * sizeof(*ip_idents), GFP_KERNEL);
  230453. - if (!ip_idents)
  230454. - panic("IP: failed to allocate ip_idents\n");
  230455. -
  230456. - prandom_bytes(ip_idents, IP_IDENTS_SZ * sizeof(*ip_idents));
  230457. -
  230458. #ifdef CONFIG_IP_ROUTE_CLASSID
  230459. ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), __alignof__(struct ip_rt_acct));
  230460. if (!ip_rt_acct)
  230461. diff -Nur linux-3.14.17/net/ipv4/tcp_vegas.c linux-imx6-3.14/net/ipv4/tcp_vegas.c
  230462. --- linux-3.14.17/net/ipv4/tcp_vegas.c 2014-08-14 03:38:34.000000000 +0200
  230463. +++ linux-imx6-3.14/net/ipv4/tcp_vegas.c 2014-09-11 18:06:15.642092428 +0200
  230464. @@ -219,8 +219,7 @@
  230465. * This is:
  230466. * (actual rate in segments) * baseRTT
  230467. */
  230468. - target_cwnd = (u64)tp->snd_cwnd * vegas->baseRTT;
  230469. - do_div(target_cwnd, rtt);
  230470. + target_cwnd = tp->snd_cwnd * vegas->baseRTT / rtt;
  230471. /* Calculate the difference between the window we had,
  230472. * and the window we would like to have. This quantity
  230473. diff -Nur linux-3.14.17/net/ipv4/tcp_veno.c linux-imx6-3.14/net/ipv4/tcp_veno.c
  230474. --- linux-3.14.17/net/ipv4/tcp_veno.c 2014-08-14 03:38:34.000000000 +0200
  230475. +++ linux-imx6-3.14/net/ipv4/tcp_veno.c 2014-09-11 18:06:15.642092428 +0200
  230476. @@ -145,7 +145,7 @@
  230477. rtt = veno->minrtt;
  230478. - target_cwnd = (u64)tp->snd_cwnd * veno->basertt;
  230479. + target_cwnd = (tp->snd_cwnd * veno->basertt);
  230480. target_cwnd <<= V_PARAM_SHIFT;
  230481. do_div(target_cwnd, rtt);
  230482. diff -Nur linux-3.14.17/net/ipv4/xfrm4_mode_tunnel.c linux-imx6-3.14/net/ipv4/xfrm4_mode_tunnel.c
  230483. --- linux-3.14.17/net/ipv4/xfrm4_mode_tunnel.c 2014-08-14 03:38:34.000000000 +0200
  230484. +++ linux-imx6-3.14/net/ipv4/xfrm4_mode_tunnel.c 2014-09-11 18:06:15.642092428 +0200
  230485. @@ -117,12 +117,12 @@
  230486. top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
  230487. 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF));
  230488. + ip_select_ident(skb, dst->child, NULL);
  230489. top_iph->ttl = ip4_dst_hoplimit(dst->child);
  230490. top_iph->saddr = x->props.saddr.a4;
  230491. top_iph->daddr = x->id.daddr.a4;
  230492. - ip_select_ident(skb, NULL);
  230493. return 0;
  230494. }
  230495. diff -Nur linux-3.14.17/net/ipv6/ip6_output.c linux-imx6-3.14/net/ipv6/ip6_output.c
  230496. --- linux-3.14.17/net/ipv6/ip6_output.c 2014-08-14 03:38:34.000000000 +0200
  230497. +++ linux-imx6-3.14/net/ipv6/ip6_output.c 2014-09-11 18:06:15.654092474 +0200
  230498. @@ -537,20 +537,6 @@
  230499. skb_copy_secmark(to, from);
  230500. }
  230501. -static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
  230502. -{
  230503. - static u32 ip6_idents_hashrnd __read_mostly;
  230504. - u32 hash, id;
  230505. -
  230506. - net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
  230507. -
  230508. - hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd);
  230509. - hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash);
  230510. -
  230511. - id = ip_idents_reserve(hash, 1);
  230512. - fhdr->identification = htonl(id);
  230513. -}
  230514. -
  230515. int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
  230516. {
  230517. struct sk_buff *frag;
  230518. diff -Nur linux-3.14.17/net/ipv6/output_core.c linux-imx6-3.14/net/ipv6/output_core.c
  230519. --- linux-3.14.17/net/ipv6/output_core.c 2014-08-14 03:38:34.000000000 +0200
  230520. +++ linux-imx6-3.14/net/ipv6/output_core.c 2014-09-11 18:06:15.662092507 +0200
  230521. @@ -7,6 +7,29 @@
  230522. #include <net/ip6_fib.h>
  230523. #include <net/addrconf.h>
  230524. +void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
  230525. +{
  230526. + static atomic_t ipv6_fragmentation_id;
  230527. + int ident;
  230528. +
  230529. +#if IS_ENABLED(CONFIG_IPV6)
  230530. + if (rt && !(rt->dst.flags & DST_NOPEER)) {
  230531. + struct inet_peer *peer;
  230532. + struct net *net;
  230533. +
  230534. + net = dev_net(rt->dst.dev);
  230535. + peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1);
  230536. + if (peer) {
  230537. + fhdr->identification = htonl(inet_getid(peer, 0));
  230538. + inet_putpeer(peer);
  230539. + return;
  230540. + }
  230541. + }
  230542. +#endif
  230543. + ident = atomic_inc_return(&ipv6_fragmentation_id);
  230544. + fhdr->identification = htonl(ident);
  230545. +}
  230546. +EXPORT_SYMBOL(ipv6_select_ident);
  230547. int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
  230548. {
  230549. diff -Nur linux-3.14.17/net/l2tp/l2tp_ppp.c linux-imx6-3.14/net/l2tp/l2tp_ppp.c
  230550. --- linux-3.14.17/net/l2tp/l2tp_ppp.c 2014-08-14 03:38:34.000000000 +0200
  230551. +++ linux-imx6-3.14/net/l2tp/l2tp_ppp.c 2014-09-11 18:06:15.742092826 +0200
  230552. @@ -1368,7 +1368,7 @@
  230553. int err;
  230554. if (level != SOL_PPPOL2TP)
  230555. - return -EINVAL;
  230556. + return udp_prot.setsockopt(sk, level, optname, optval, optlen);
  230557. if (optlen < sizeof(int))
  230558. return -EINVAL;
  230559. @@ -1494,7 +1494,7 @@
  230560. struct pppol2tp_session *ps;
  230561. if (level != SOL_PPPOL2TP)
  230562. - return -EINVAL;
  230563. + return udp_prot.getsockopt(sk, level, optname, optval, optlen);
  230564. if (get_user(len, optlen))
  230565. return -EFAULT;
  230566. diff -Nur linux-3.14.17/net/mac80211/driver-ops.h linux-imx6-3.14/net/mac80211/driver-ops.h
  230567. --- linux-3.14.17/net/mac80211/driver-ops.h 2014-08-14 03:38:34.000000000 +0200
  230568. +++ linux-imx6-3.14/net/mac80211/driver-ops.h 2014-09-11 18:06:15.754092874 +0200
  230569. @@ -722,13 +722,19 @@
  230570. }
  230571. static inline void drv_flush(struct ieee80211_local *local,
  230572. + struct ieee80211_sub_if_data *sdata,
  230573. u32 queues, bool drop)
  230574. {
  230575. + struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
  230576. +
  230577. might_sleep();
  230578. + if (sdata)
  230579. + check_sdata_in_driver(sdata);
  230580. +
  230581. trace_drv_flush(local, queues, drop);
  230582. if (local->ops->flush)
  230583. - local->ops->flush(&local->hw, queues, drop);
  230584. + local->ops->flush(&local->hw, vif, queues, drop);
  230585. trace_drv_return_void(local);
  230586. }
  230587. diff -Nur linux-3.14.17/net/mac80211/ibss.c linux-imx6-3.14/net/mac80211/ibss.c
  230588. --- linux-3.14.17/net/mac80211/ibss.c 2014-08-14 03:38:34.000000000 +0200
  230589. +++ linux-imx6-3.14/net/mac80211/ibss.c 2014-09-11 18:06:15.754092874 +0200
  230590. @@ -386,7 +386,7 @@
  230591. presp->head_len, 0, GFP_KERNEL);
  230592. cfg80211_put_bss(local->hw.wiphy, bss);
  230593. netif_carrier_on(sdata->dev);
  230594. - cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
  230595. + cfg80211_ibss_joined(sdata->dev, ifibss->bssid, chan, GFP_KERNEL);
  230596. }
  230597. static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
  230598. diff -Nur linux-3.14.17/net/mac80211/tx.c linux-imx6-3.14/net/mac80211/tx.c
  230599. --- linux-3.14.17/net/mac80211/tx.c 2014-08-14 03:38:34.000000000 +0200
  230600. +++ linux-imx6-3.14/net/mac80211/tx.c 2014-09-11 18:06:15.778092969 +0200
  230601. @@ -414,9 +414,6 @@
  230602. if (ieee80211_has_order(hdr->frame_control))
  230603. return TX_CONTINUE;
  230604. - if (ieee80211_is_probe_req(hdr->frame_control))
  230605. - return TX_CONTINUE;
  230606. -
  230607. if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
  230608. info->hw_queue = tx->sdata->vif.cab_queue;
  230609. @@ -467,7 +464,6 @@
  230610. {
  230611. struct sta_info *sta = tx->sta;
  230612. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
  230613. - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
  230614. struct ieee80211_local *local = tx->local;
  230615. if (unlikely(!sta))
  230616. @@ -478,15 +474,6 @@
  230617. !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
  230618. int ac = skb_get_queue_mapping(tx->skb);
  230619. - /* only deauth, disassoc and action are bufferable MMPDUs */
  230620. - if (ieee80211_is_mgmt(hdr->frame_control) &&
  230621. - !ieee80211_is_deauth(hdr->frame_control) &&
  230622. - !ieee80211_is_disassoc(hdr->frame_control) &&
  230623. - !ieee80211_is_action(hdr->frame_control)) {
  230624. - info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
  230625. - return TX_CONTINUE;
  230626. - }
  230627. -
  230628. ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n",
  230629. sta->sta.addr, sta->sta.aid, ac);
  230630. if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
  230631. @@ -545,8 +532,22 @@
  230632. static ieee80211_tx_result debug_noinline
  230633. ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
  230634. {
  230635. + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
  230636. + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
  230637. +
  230638. if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED))
  230639. return TX_CONTINUE;
  230640. +
  230641. + /* only deauth, disassoc and action are bufferable MMPDUs */
  230642. + if (ieee80211_is_mgmt(hdr->frame_control) &&
  230643. + !ieee80211_is_deauth(hdr->frame_control) &&
  230644. + !ieee80211_is_disassoc(hdr->frame_control) &&
  230645. + !ieee80211_is_action(hdr->frame_control)) {
  230646. + if (tx->flags & IEEE80211_TX_UNICAST)
  230647. + info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
  230648. + return TX_CONTINUE;
  230649. + }
  230650. +
  230651. if (tx->flags & IEEE80211_TX_UNICAST)
  230652. return ieee80211_tx_h_unicast_ps_buf(tx);
  230653. else
  230654. diff -Nur linux-3.14.17/net/mac80211/util.c linux-imx6-3.14/net/mac80211/util.c
  230655. --- linux-3.14.17/net/mac80211/util.c 2014-08-14 03:38:34.000000000 +0200
  230656. +++ linux-imx6-3.14/net/mac80211/util.c 2014-09-11 18:06:15.778092969 +0200
  230657. @@ -554,7 +554,7 @@
  230658. ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
  230659. IEEE80211_QUEUE_STOP_REASON_FLUSH);
  230660. - drv_flush(local, queues, false);
  230661. + drv_flush(local, sdata, queues, false);
  230662. ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
  230663. IEEE80211_QUEUE_STOP_REASON_FLUSH);
  230664. diff -Nur linux-3.14.17/net/netfilter/ipvs/ip_vs_xmit.c linux-imx6-3.14/net/netfilter/ipvs/ip_vs_xmit.c
  230665. --- linux-3.14.17/net/netfilter/ipvs/ip_vs_xmit.c 2014-08-14 03:38:34.000000000 +0200
  230666. +++ linux-imx6-3.14/net/netfilter/ipvs/ip_vs_xmit.c 2014-09-11 18:06:15.790093017 +0200
  230667. @@ -883,7 +883,7 @@
  230668. iph->daddr = cp->daddr.ip;
  230669. iph->saddr = saddr;
  230670. iph->ttl = old_iph->ttl;
  230671. - ip_select_ident(skb, NULL);
  230672. + ip_select_ident(skb, &rt->dst, NULL);
  230673. /* Another hack: avoid icmp_send in ip_fragment */
  230674. skb->local_df = 1;
  230675. diff -Nur linux-3.14.17/net/sctp/associola.c linux-imx6-3.14/net/sctp/associola.c
  230676. --- linux-3.14.17/net/sctp/associola.c 2014-08-14 03:38:34.000000000 +0200
  230677. +++ linux-imx6-3.14/net/sctp/associola.c 2014-09-11 18:06:16.074094150 +0200
  230678. @@ -1151,7 +1151,6 @@
  230679. asoc->c = new->c;
  230680. asoc->peer.rwnd = new->peer.rwnd;
  230681. asoc->peer.sack_needed = new->peer.sack_needed;
  230682. - asoc->peer.auth_capable = new->peer.auth_capable;
  230683. asoc->peer.i = new->peer.i;
  230684. sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
  230685. asoc->peer.i.initial_tsn, GFP_ATOMIC);
  230686. diff -Nur linux-3.14.17/net/sctp/output.c linux-imx6-3.14/net/sctp/output.c
  230687. --- linux-3.14.17/net/sctp/output.c 2014-08-14 03:38:34.000000000 +0200
  230688. +++ linux-imx6-3.14/net/sctp/output.c 2014-09-11 18:06:16.074094150 +0200
  230689. @@ -599,7 +599,7 @@
  230690. return err;
  230691. no_route:
  230692. kfree_skb(nskb);
  230693. - IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
  230694. + IP_INC_STATS_BH(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
  230695. /* FIXME: Returning the 'err' will effect all the associations
  230696. * associated with a socket, although only one of the paths of the
  230697. diff -Nur linux-3.14.17/net/wireless/core.h linux-imx6-3.14/net/wireless/core.h
  230698. --- linux-3.14.17/net/wireless/core.h 2014-08-14 03:38:34.000000000 +0200
  230699. +++ linux-imx6-3.14/net/wireless/core.h 2014-09-11 18:06:16.190094613 +0200
  230700. @@ -211,6 +211,7 @@
  230701. } dc;
  230702. struct {
  230703. u8 bssid[ETH_ALEN];
  230704. + struct ieee80211_channel *channel;
  230705. } ij;
  230706. };
  230707. };
  230708. @@ -258,7 +259,8 @@
  230709. struct net_device *dev, bool nowext);
  230710. int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
  230711. struct net_device *dev, bool nowext);
  230712. -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
  230713. +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  230714. + struct ieee80211_channel *channel);
  230715. int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
  230716. struct wireless_dev *wdev);
  230717. diff -Nur linux-3.14.17/net/wireless/ibss.c linux-imx6-3.14/net/wireless/ibss.c
  230718. --- linux-3.14.17/net/wireless/ibss.c 2014-08-14 03:38:34.000000000 +0200
  230719. +++ linux-imx6-3.14/net/wireless/ibss.c 2014-09-11 18:06:16.190094613 +0200
  230720. @@ -14,7 +14,8 @@
  230721. #include "rdev-ops.h"
  230722. -void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
  230723. +void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  230724. + struct ieee80211_channel *channel)
  230725. {
  230726. struct wireless_dev *wdev = dev->ieee80211_ptr;
  230727. struct cfg80211_bss *bss;
  230728. @@ -28,8 +29,7 @@
  230729. if (!wdev->ssid_len)
  230730. return;
  230731. - bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
  230732. - wdev->ssid, wdev->ssid_len,
  230733. + bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0,
  230734. WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
  230735. if (WARN_ON(!bss))
  230736. @@ -54,21 +54,26 @@
  230737. #endif
  230738. }
  230739. -void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
  230740. +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
  230741. + struct ieee80211_channel *channel, gfp_t gfp)
  230742. {
  230743. struct wireless_dev *wdev = dev->ieee80211_ptr;
  230744. struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  230745. struct cfg80211_event *ev;
  230746. unsigned long flags;
  230747. - trace_cfg80211_ibss_joined(dev, bssid);
  230748. + trace_cfg80211_ibss_joined(dev, bssid, channel);
  230749. +
  230750. + if (WARN_ON(!channel))
  230751. + return;
  230752. ev = kzalloc(sizeof(*ev), gfp);
  230753. if (!ev)
  230754. return;
  230755. ev->type = EVENT_IBSS_JOINED;
  230756. - memcpy(ev->cr.bssid, bssid, ETH_ALEN);
  230757. + memcpy(ev->ij.bssid, bssid, ETH_ALEN);
  230758. + ev->ij.channel = channel;
  230759. spin_lock_irqsave(&wdev->event_lock, flags);
  230760. list_add_tail(&ev->list, &wdev->event_list);
  230761. diff -Nur linux-3.14.17/net/wireless/nl80211.c linux-imx6-3.14/net/wireless/nl80211.c
  230762. --- linux-3.14.17/net/wireless/nl80211.c 2014-08-14 03:38:34.000000000 +0200
  230763. +++ linux-imx6-3.14/net/wireless/nl80211.c 2014-09-11 18:06:16.198094644 +0200
  230764. @@ -1450,17 +1450,18 @@
  230765. }
  230766. CMD(start_p2p_device, START_P2P_DEVICE);
  230767. CMD(set_mcast_rate, SET_MCAST_RATE);
  230768. -#ifdef CONFIG_NL80211_TESTMODE
  230769. - CMD(testmode_cmd, TESTMODE);
  230770. -#endif
  230771. if (state->split) {
  230772. CMD(crit_proto_start, CRIT_PROTOCOL_START);
  230773. CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
  230774. if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
  230775. CMD(channel_switch, CHANNEL_SWITCH);
  230776. - CMD(set_qos_map, SET_QOS_MAP);
  230777. }
  230778. - /* add into the if now */
  230779. + CMD(set_qos_map, SET_QOS_MAP);
  230780. +
  230781. +#ifdef CONFIG_NL80211_TESTMODE
  230782. + CMD(testmode_cmd, TESTMODE);
  230783. +#endif
  230784. +
  230785. #undef CMD
  230786. if (dev->ops->connect || dev->ops->auth) {
  230787. diff -Nur linux-3.14.17/net/wireless/trace.h linux-imx6-3.14/net/wireless/trace.h
  230788. --- linux-3.14.17/net/wireless/trace.h 2014-08-14 03:38:34.000000000 +0200
  230789. +++ linux-imx6-3.14/net/wireless/trace.h 2014-09-11 18:06:16.202094661 +0200
  230790. @@ -2068,8 +2068,7 @@
  230791. MAC_ASSIGN(addr, addr);
  230792. __entry->key_type = key_type;
  230793. __entry->key_id = key_id;
  230794. - if (tsc)
  230795. - memcpy(__entry->tsc, tsc, 6);
  230796. + memcpy(__entry->tsc, tsc, 6);
  230797. ),
  230798. TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm",
  230799. NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type,
  230800. @@ -2279,11 +2278,6 @@
  230801. TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT, NETDEV_PR_ARG, MAC_PR_ARG(addr))
  230802. );
  230803. -DEFINE_EVENT(cfg80211_rx_evt, cfg80211_ibss_joined,
  230804. - TP_PROTO(struct net_device *netdev, const u8 *addr),
  230805. - TP_ARGS(netdev, addr)
  230806. -);
  230807. -
  230808. DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
  230809. TP_PROTO(struct net_device *netdev, const u8 *addr),
  230810. TP_ARGS(netdev, addr)
  230811. @@ -2294,6 +2288,24 @@
  230812. TP_ARGS(netdev, addr)
  230813. );
  230814. +TRACE_EVENT(cfg80211_ibss_joined,
  230815. + TP_PROTO(struct net_device *netdev, const u8 *bssid,
  230816. + struct ieee80211_channel *channel),
  230817. + TP_ARGS(netdev, bssid, channel),
  230818. + TP_STRUCT__entry(
  230819. + NETDEV_ENTRY
  230820. + MAC_ENTRY(bssid)
  230821. + CHAN_ENTRY
  230822. + ),
  230823. + TP_fast_assign(
  230824. + NETDEV_ASSIGN;
  230825. + MAC_ASSIGN(bssid, bssid);
  230826. + CHAN_ASSIGN(channel);
  230827. + ),
  230828. + TP_printk(NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", " CHAN_PR_FMT,
  230829. + NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
  230830. +);
  230831. +
  230832. TRACE_EVENT(cfg80211_probe_status,
  230833. TP_PROTO(struct net_device *netdev, const u8 *addr, u64 cookie,
  230834. bool acked),
  230835. diff -Nur linux-3.14.17/net/wireless/util.c linux-imx6-3.14/net/wireless/util.c
  230836. --- linux-3.14.17/net/wireless/util.c 2014-08-14 03:38:34.000000000 +0200
  230837. +++ linux-imx6-3.14/net/wireless/util.c 2014-09-11 18:06:16.202094661 +0200
  230838. @@ -820,7 +820,8 @@
  230839. ev->dc.reason, true);
  230840. break;
  230841. case EVENT_IBSS_JOINED:
  230842. - __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
  230843. + __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
  230844. + ev->ij.channel);
  230845. break;
  230846. }
  230847. wdev_unlock(wdev);
  230848. diff -Nur linux-3.14.17/net/xfrm/xfrm_user.c linux-imx6-3.14/net/xfrm/xfrm_user.c
  230849. --- linux-3.14.17/net/xfrm/xfrm_user.c 2014-08-14 03:38:34.000000000 +0200
  230850. +++ linux-imx6-3.14/net/xfrm/xfrm_user.c 2014-09-11 18:06:16.218094725 +0200
  230851. @@ -176,7 +176,9 @@
  230852. attrs[XFRMA_ALG_AEAD] ||
  230853. attrs[XFRMA_ALG_CRYPT] ||
  230854. attrs[XFRMA_ALG_COMP] ||
  230855. - attrs[XFRMA_TFCPAD])
  230856. + attrs[XFRMA_TFCPAD] ||
  230857. + (ntohl(p->id.spi) >= 0x10000))
  230858. +
  230859. goto out;
  230860. break;
  230861. @@ -204,8 +206,7 @@
  230862. attrs[XFRMA_ALG_AUTH] ||
  230863. attrs[XFRMA_ALG_AUTH_TRUNC] ||
  230864. attrs[XFRMA_ALG_CRYPT] ||
  230865. - attrs[XFRMA_TFCPAD] ||
  230866. - (ntohl(p->id.spi) >= 0x10000))
  230867. + attrs[XFRMA_TFCPAD])
  230868. goto out;
  230869. break;
  230870. diff -Nur linux-3.14.17/scripts/Makefile.lib linux-imx6-3.14/scripts/Makefile.lib
  230871. --- linux-3.14.17/scripts/Makefile.lib 2014-08-14 03:38:34.000000000 +0200
  230872. +++ linux-imx6-3.14/scripts/Makefile.lib 2014-09-11 18:06:16.334095188 +0200
  230873. @@ -153,6 +153,7 @@
  230874. -I$(srctree)/arch/$(SRCARCH)/boot/dts \
  230875. -I$(srctree)/arch/$(SRCARCH)/boot/dts/include \
  230876. -I$(srctree)/drivers/of/testcase-data \
  230877. + -I$(srctree)/include \
  230878. -undef -D__DTS__
  230879. # Finds the multi-part object the current object will be linked into
  230880. diff -Nur linux-3.14.17/scripts/mod/devicetable-offsets.c linux-imx6-3.14/scripts/mod/devicetable-offsets.c
  230881. --- linux-3.14.17/scripts/mod/devicetable-offsets.c 2014-08-14 03:38:34.000000000 +0200
  230882. +++ linux-imx6-3.14/scripts/mod/devicetable-offsets.c 2014-09-11 18:06:16.482095778 +0200
  230883. @@ -174,6 +174,9 @@
  230884. DEVID_FIELD(x86_cpu_id, model);
  230885. DEVID_FIELD(x86_cpu_id, vendor);
  230886. + DEVID(cpu_feature);
  230887. + DEVID_FIELD(cpu_feature, feature);
  230888. +
  230889. DEVID(mei_cl_device_id);
  230890. DEVID_FIELD(mei_cl_device_id, name);
  230891. diff -Nur linux-3.14.17/scripts/mod/file2alias.c linux-imx6-3.14/scripts/mod/file2alias.c
  230892. --- linux-3.14.17/scripts/mod/file2alias.c 2014-08-14 03:38:34.000000000 +0200
  230893. +++ linux-imx6-3.14/scripts/mod/file2alias.c 2014-09-11 18:06:16.486095794 +0200
  230894. @@ -1135,6 +1135,16 @@
  230895. }
  230896. ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry);
  230897. +/* LOOKS like cpu:type:*:feature:*FEAT* */
  230898. +static int do_cpu_entry(const char *filename, void *symval, char *alias)
  230899. +{
  230900. + DEF_FIELD(symval, cpu_feature, feature);
  230901. +
  230902. + sprintf(alias, "cpu:type:*:feature:*%04X*", feature);
  230903. + return 1;
  230904. +}
  230905. +ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry);
  230906. +
  230907. /* Looks like: mei:S */
  230908. static int do_mei_entry(const char *filename, void *symval,
  230909. char *alias)
  230910. diff -Nur linux-3.14.17/scripts/recordmcount.c linux-imx6-3.14/scripts/recordmcount.c
  230911. --- linux-3.14.17/scripts/recordmcount.c 2014-08-14 03:38:34.000000000 +0200
  230912. +++ linux-imx6-3.14/scripts/recordmcount.c 2014-09-11 18:06:16.490095810 +0200
  230913. @@ -40,6 +40,11 @@
  230914. #define R_METAG_NONE 3
  230915. #endif
  230916. +#ifndef EM_AARCH64
  230917. +#define EM_AARCH64 183
  230918. +#define R_AARCH64_ABS64 257
  230919. +#endif
  230920. +
  230921. static int fd_map; /* File descriptor for file being modified. */
  230922. static int mmap_failed; /* Boolean flag. */
  230923. static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */
  230924. @@ -347,6 +352,8 @@
  230925. case EM_ARM: reltype = R_ARM_ABS32;
  230926. altmcount = "__gnu_mcount_nc";
  230927. break;
  230928. + case EM_AARCH64:
  230929. + reltype = R_AARCH64_ABS64; gpfx = '_'; break;
  230930. case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break;
  230931. case EM_METAG: reltype = R_METAG_ADDR32;
  230932. altmcount = "_mcount_wrapper";
  230933. diff -Nur linux-3.14.17/scripts/recordmcount.pl linux-imx6-3.14/scripts/recordmcount.pl
  230934. --- linux-3.14.17/scripts/recordmcount.pl 2014-08-14 03:38:34.000000000 +0200
  230935. +++ linux-imx6-3.14/scripts/recordmcount.pl 2014-09-11 18:06:16.490095810 +0200
  230936. @@ -279,6 +279,11 @@
  230937. $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_ARM_(CALL|PC24|THM_CALL)" .
  230938. "\\s+(__gnu_mcount_nc|mcount)\$";
  230939. +} elsif ($arch eq "arm64") {
  230940. + $alignment = 3;
  230941. + $section_type = '%progbits';
  230942. + $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_AARCH64_CALL26\\s+_mcount\$";
  230943. + $type = ".quad";
  230944. } elsif ($arch eq "ia64") {
  230945. $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
  230946. $type = "data8";
  230947. diff -Nur linux-3.14.17/sound/soc/codecs/cs42888.c linux-imx6-3.14/sound/soc/codecs/cs42888.c
  230948. --- linux-3.14.17/sound/soc/codecs/cs42888.c 1970-01-01 01:00:00.000000000 +0100
  230949. +++ linux-imx6-3.14/sound/soc/codecs/cs42888.c 2014-09-11 18:06:18.638104376 +0200
  230950. @@ -0,0 +1,934 @@
  230951. +/*
  230952. + * cs42888.c -- CS42888 ALSA SoC Audio Driver
  230953. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  230954. + */
  230955. +/*
  230956. + * The code contained herein is licensed under the GNU General Public
  230957. + * License. You may obtain a copy of the GNU General Public License
  230958. + * Version 2 or later at the following locations:
  230959. + *
  230960. + * http://www.opensource.org/licenses/gpl-license.html
  230961. + * http://www.gnu.org/copyleft/gpl.html
  230962. + */
  230963. +
  230964. +#include <linux/module.h>
  230965. +#include <linux/moduleparam.h>
  230966. +#include <linux/kernel.h>
  230967. +#include <linux/init.h>
  230968. +#include <linux/clk.h>
  230969. +#include <linux/delay.h>
  230970. +#include <linux/pm.h>
  230971. +#include <linux/i2c.h>
  230972. +#include <linux/spi/spi.h>
  230973. +#include <linux/platform_device.h>
  230974. +#include <linux/regulator/consumer.h>
  230975. +
  230976. +#include <sound/core.h>
  230977. +#include <sound/pcm.h>
  230978. +#include <sound/pcm_params.h>
  230979. +#include <sound/soc.h>
  230980. +#include <sound/soc-dapm.h>
  230981. +#include <sound/tlv.h>
  230982. +#include <sound/initval.h>
  230983. +#include <asm/div64.h>
  230984. +#include "cs42888.h"
  230985. +
  230986. +#define CS42888_NUM_SUPPLIES 4
  230987. +static const char *cs42888_supply_names[CS42888_NUM_SUPPLIES] = {
  230988. + "VA",
  230989. + "VD",
  230990. + "VLS",
  230991. + "VLC",
  230992. +};
  230993. +
  230994. +#define CS42888_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  230995. + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  230996. +
  230997. +/* Private data for the CS42888 */
  230998. +struct cs42888_private {
  230999. + struct clk *clk;
  231000. + struct snd_soc_codec *codec;
  231001. + u8 reg_cache[CS42888_NUMREGS + 1];
  231002. + unsigned int mclk; /* Input frequency of the MCLK pin */
  231003. + unsigned int slave_mode;
  231004. + struct regulator_bulk_data supplies[CS42888_NUM_SUPPLIES];
  231005. +};
  231006. +
  231007. +/**
  231008. + * cs42888_fill_cache - pre-fill the CS42888 register cache.
  231009. + * @codec: the codec for this CS42888
  231010. + *
  231011. + * This function fills in the CS42888 register cache by reading the register
  231012. + * values from the hardware.
  231013. + *
  231014. + * This CS42888 registers are cached to avoid excessive I2C I/O operations.
  231015. + * After the initial read to pre-fill the cache, the CS42888 never updates
  231016. + * the register values, so we won't have a cache coherency problem.
  231017. + *
  231018. + * We use the auto-increment feature of the CS42888 to read all registers in
  231019. + * one shot.
  231020. + */
  231021. +static int cs42888_fill_cache(struct snd_soc_codec *codec)
  231022. +{
  231023. + u8 *cache = codec->reg_cache;
  231024. + struct i2c_client *i2c_client = to_i2c_client(codec->dev);
  231025. + s32 length;
  231026. +
  231027. + length = i2c_smbus_read_i2c_block_data(i2c_client,
  231028. + CS42888_FIRSTREG | CS42888_I2C_INCR, CS42888_NUMREGS, \
  231029. + cache + 1);
  231030. +
  231031. + if (length != CS42888_NUMREGS) {
  231032. + dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
  231033. + i2c_client->addr);
  231034. + return -EIO;
  231035. + }
  231036. + return 0;
  231037. +}
  231038. +
  231039. +#ifdef DEBUG
  231040. +static void dump_reg(struct snd_soc_codec *codec)
  231041. +{
  231042. + int i, reg;
  231043. + int ret;
  231044. + u8 *cache = codec->reg_cache + 1;
  231045. +
  231046. + dev_dbg(codec->dev, "dump begin\n");
  231047. + dev_dbg(codec->dev, "reg value in cache\n");
  231048. + for (i = 0; i < CS42888_NUMREGS; i++)
  231049. + dev_dbg(codec->dev, "reg[%d] = 0x%x\n", i, cache[i]);
  231050. +
  231051. + dev_dbg(codec->dev, "real reg value\n");
  231052. + ret = cs42888_fill_cache(codec);
  231053. + if (ret < 0) {
  231054. + dev_err(codec->dev, "failed to fill register cache\n");
  231055. + return ret;
  231056. + }
  231057. + for (i = 0; i < CS42888_NUMREGS; i++)
  231058. + dev_dbg(codec->dev, "reg[%d] = 0x%x\n", i, cache[i]);
  231059. +
  231060. + dev_dbg(codec->dev, "dump end\n");
  231061. +}
  231062. +#else
  231063. +static void dump_reg(struct snd_soc_codec *codec)
  231064. +{
  231065. +}
  231066. +#endif
  231067. +
  231068. +/* -127.5dB to 0dB with step of 0.5dB */
  231069. +static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
  231070. +/* -64dB to 24dB with step of 0.5dB */
  231071. +static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 1);
  231072. +
  231073. +static int cs42888_out_vu(struct snd_kcontrol *kcontrol,
  231074. + struct snd_ctl_elem_value *ucontrol)
  231075. +{
  231076. + return snd_soc_put_volsw_2r(kcontrol, ucontrol);
  231077. +}
  231078. +
  231079. +static int cs42888_info_volsw_s8(struct snd_kcontrol *kcontrol,
  231080. + struct snd_ctl_elem_info *uinfo)
  231081. +{
  231082. + struct soc_mixer_control *mc =
  231083. + (struct soc_mixer_control *)kcontrol->private_value;
  231084. +
  231085. + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  231086. + uinfo->count = 2;
  231087. + uinfo->value.integer.min = 0;
  231088. + uinfo->value.integer.max = mc->max - mc->min;
  231089. + return 0;
  231090. +}
  231091. +
  231092. +static int cs42888_get_volsw_s8(struct snd_kcontrol *kcontrol,
  231093. + struct snd_ctl_elem_value *ucontrol)
  231094. +{
  231095. + struct soc_mixer_control *mc =
  231096. + (struct soc_mixer_control *)kcontrol->private_value;
  231097. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  231098. + s8 val = snd_soc_read(codec, mc->reg);
  231099. + ucontrol->value.integer.value[0] = val - mc->min;
  231100. +
  231101. + val = snd_soc_read(codec, mc->rreg);
  231102. + ucontrol->value.integer.value[1] = val - mc->min;
  231103. + return 0;
  231104. +}
  231105. +
  231106. +int cs42888_put_volsw_s8(struct snd_kcontrol *kcontrol,
  231107. + struct snd_ctl_elem_value *ucontrol)
  231108. +{
  231109. + struct soc_mixer_control *mc =
  231110. + (struct soc_mixer_control *)kcontrol->private_value;
  231111. + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  231112. + unsigned short val;
  231113. + int ret;
  231114. +
  231115. + val = ucontrol->value.integer.value[0] + mc->min;
  231116. + ret = snd_soc_write(codec, mc->reg, val);
  231117. + if (ret < 0) {
  231118. + dev_err(codec->dev, "i2c write failed\n");
  231119. + return ret;
  231120. + }
  231121. +
  231122. + val = ucontrol->value.integer.value[1] + mc->min;
  231123. + ret = snd_soc_write(codec, mc->rreg, val);
  231124. + if (ret < 0) {
  231125. + dev_err(codec->dev, "i2c write failed\n");
  231126. + return ret;
  231127. + }
  231128. + return 0;
  231129. +}
  231130. +
  231131. +#define SOC_CS42888_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
  231132. + xinvert, tlv_array) \
  231133. +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  231134. + .name = (xname), \
  231135. + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
  231136. + SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  231137. + .tlv.p = (tlv_array), \
  231138. + .info = snd_soc_info_volsw, \
  231139. + .get = snd_soc_get_volsw, \
  231140. + .put = cs42888_out_vu, \
  231141. + .private_value = (unsigned long)&(struct soc_mixer_control) \
  231142. + {.reg = reg_left, \
  231143. + .rreg = reg_right, \
  231144. + .shift = xshift, \
  231145. + .max = xmax, \
  231146. + .invert = xinvert} \
  231147. +}
  231148. +
  231149. +#define SOC_CS42888_DOUBLE_R_S8_TLV(xname, reg_left, reg_right, xmin, xmax, \
  231150. + tlv_array) \
  231151. +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
  231152. + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
  231153. + SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  231154. + .tlv.p = (tlv_array), \
  231155. + .info = cs42888_info_volsw_s8, \
  231156. + .get = cs42888_get_volsw_s8, \
  231157. + .put = cs42888_put_volsw_s8, \
  231158. + .private_value = (unsigned long)&(struct soc_mixer_control) \
  231159. + {.reg = reg_left, \
  231160. + .rreg = reg_right, \
  231161. + .min = xmin, \
  231162. + .max = xmax} \
  231163. +}
  231164. +
  231165. +static const char *cs42888_adcfilter[] = { "None", "High Pass" };
  231166. +static const char *cs42888_dacinvert[] = { "Disabled", "Enabled" };
  231167. +static const char *cs42888_adcinvert[] = { "Disabled", "Enabled" };
  231168. +static const char *cs42888_dacamute[] = { "Disabled", "AutoMute" };
  231169. +static const char *cs42888_dac_sngvol[] = { "Disabled", "Enabled" };
  231170. +static const char *cs42888_dac_szc[] = { "Immediate Change", "Zero Cross",
  231171. + "Soft Ramp", "Soft Ramp on Zero Cross" };
  231172. +static const char *cs42888_mute_adc[] = { "UnMute", "Mute" };
  231173. +static const char *cs42888_adc_sngvol[] = { "Disabled", "Enabled" };
  231174. +static const char *cs42888_adc_szc[] = { "Immediate Change", "Zero Cross",
  231175. + "Soft Ramp", "Soft Ramp on Zero Cross" };
  231176. +static const char *cs42888_dac_dem[] = { "No-De-Emphasis", "De-Emphasis" };
  231177. +static const char *cs42888_adc_single[] = { "Differential", "Single-Ended" };
  231178. +
  231179. +static const struct soc_enum cs42888_enum[] = {
  231180. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 7, 2, cs42888_adcfilter),
  231181. + SOC_ENUM_DOUBLE(CS42888_DACINV, 0, 1, 2, cs42888_dacinvert),
  231182. + SOC_ENUM_DOUBLE(CS42888_DACINV, 2, 3, 2, cs42888_dacinvert),
  231183. + SOC_ENUM_DOUBLE(CS42888_DACINV, 4, 5, 2, cs42888_dacinvert),
  231184. + SOC_ENUM_DOUBLE(CS42888_DACINV, 6, 7, 2, cs42888_dacinvert),
  231185. + SOC_ENUM_DOUBLE(CS42888_ADCINV, 0, 1, 2, cs42888_adcinvert),
  231186. + SOC_ENUM_DOUBLE(CS42888_ADCINV, 2, 3, 2, cs42888_adcinvert),
  231187. + SOC_ENUM_SINGLE(CS42888_TRANS, 4, 2, cs42888_dacamute),
  231188. + SOC_ENUM_SINGLE(CS42888_TRANS, 7, 2, cs42888_dac_sngvol),
  231189. + SOC_ENUM_SINGLE(CS42888_TRANS, 5, 4, cs42888_dac_szc),
  231190. + SOC_ENUM_SINGLE(CS42888_TRANS, 3, 2, cs42888_mute_adc),
  231191. + SOC_ENUM_SINGLE(CS42888_TRANS, 2, 2, cs42888_adc_sngvol),
  231192. + SOC_ENUM_SINGLE(CS42888_TRANS, 0, 4, cs42888_adc_szc),
  231193. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 5, 2, cs42888_dac_dem),
  231194. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 4, 2, cs42888_adc_single),
  231195. + SOC_ENUM_SINGLE(CS42888_ADCCTL, 3, 2, cs42888_adc_single),
  231196. +};
  231197. +
  231198. +static const struct snd_kcontrol_new cs42888_snd_controls[] = {
  231199. + SOC_CS42888_DOUBLE_R_TLV("DAC1 Playback Volume", CS42888_VOLAOUT1,
  231200. + CS42888_VOLAOUT2, 0, 0xff, 1, dac_tlv),
  231201. + SOC_CS42888_DOUBLE_R_TLV("DAC2 Playback Volume", CS42888_VOLAOUT3,
  231202. + CS42888_VOLAOUT4, 0, 0xff, 1, dac_tlv),
  231203. + SOC_CS42888_DOUBLE_R_TLV("DAC3 Playback Volume", CS42888_VOLAOUT5,
  231204. + CS42888_VOLAOUT6, 0, 0xff, 1, dac_tlv),
  231205. + SOC_CS42888_DOUBLE_R_TLV("DAC4 Playback Volume", CS42888_VOLAOUT7,
  231206. + CS42888_VOLAOUT8, 0, 0xff, 1, dac_tlv),
  231207. + SOC_CS42888_DOUBLE_R_S8_TLV("ADC1 Capture Volume", CS42888_VOLAIN1,
  231208. + CS42888_VOLAIN2, -128, 48, adc_tlv),
  231209. + SOC_CS42888_DOUBLE_R_S8_TLV("ADC2 Capture Volume", CS42888_VOLAIN3,
  231210. + CS42888_VOLAIN4, -128, 48, adc_tlv),
  231211. + SOC_ENUM("ADC High-Pass Filter Switch", cs42888_enum[0]),
  231212. + SOC_ENUM("DAC1 Invert Switch", cs42888_enum[1]),
  231213. + SOC_ENUM("DAC2 Invert Switch", cs42888_enum[2]),
  231214. + SOC_ENUM("DAC3 Invert Switch", cs42888_enum[3]),
  231215. + SOC_ENUM("DAC4 Invert Switch", cs42888_enum[4]),
  231216. + SOC_ENUM("ADC1 Invert Switch", cs42888_enum[5]),
  231217. + SOC_ENUM("ADC2 Invert Switch", cs42888_enum[6]),
  231218. + SOC_ENUM("DAC Auto Mute Switch", cs42888_enum[7]),
  231219. + SOC_ENUM("DAC Single Volume Control Switch", cs42888_enum[8]),
  231220. + SOC_ENUM("DAC Soft Ramp and Zero Cross Control Switch", cs42888_enum[9]),
  231221. + SOC_ENUM("Mute ADC Serial Port Switch", cs42888_enum[10]),
  231222. + SOC_ENUM("ADC Single Volume Control Switch", cs42888_enum[11]),
  231223. + SOC_ENUM("ADC Soft Ramp and Zero Cross Control Switch", cs42888_enum[12]),
  231224. + SOC_ENUM("DAC Deemphasis Switch", cs42888_enum[13]),
  231225. + SOC_ENUM("ADC1 Single Ended Mode Switch", cs42888_enum[14]),
  231226. + SOC_ENUM("ADC2 Single Ended Mode Switch", cs42888_enum[15]),
  231227. +};
  231228. +
  231229. +
  231230. +static const struct snd_soc_dapm_widget cs42888_dapm_widgets[] = {
  231231. + SND_SOC_DAPM_DAC("DAC1", "codec-Playback", CS42888_PWRCTL, 1, 1),
  231232. + SND_SOC_DAPM_DAC("DAC2", "codec-Playback", CS42888_PWRCTL, 2, 1),
  231233. + SND_SOC_DAPM_DAC("DAC3", "codec-Playback", CS42888_PWRCTL, 3, 1),
  231234. + SND_SOC_DAPM_DAC("DAC4", "codec-Playback", CS42888_PWRCTL, 4, 1),
  231235. +
  231236. + SND_SOC_DAPM_OUTPUT("AOUT1L"),
  231237. + SND_SOC_DAPM_OUTPUT("AOUT1R"),
  231238. + SND_SOC_DAPM_OUTPUT("AOUT2L"),
  231239. + SND_SOC_DAPM_OUTPUT("AOUT2R"),
  231240. + SND_SOC_DAPM_OUTPUT("AOUT3L"),
  231241. + SND_SOC_DAPM_OUTPUT("AOUT3R"),
  231242. + SND_SOC_DAPM_OUTPUT("AOUT4L"),
  231243. + SND_SOC_DAPM_OUTPUT("AOUT4R"),
  231244. +
  231245. + SND_SOC_DAPM_ADC("ADC1", "codec-Capture", CS42888_PWRCTL, 5, 1),
  231246. + SND_SOC_DAPM_ADC("ADC2", "codec-Capture", CS42888_PWRCTL, 6, 1),
  231247. +
  231248. + SND_SOC_DAPM_INPUT("AIN1L"),
  231249. + SND_SOC_DAPM_INPUT("AIN1R"),
  231250. + SND_SOC_DAPM_INPUT("AIN2L"),
  231251. + SND_SOC_DAPM_INPUT("AIN2R"),
  231252. +
  231253. + SND_SOC_DAPM_PGA_E("PWR", CS42888_PWRCTL, 0, 1, NULL, 0,
  231254. + NULL, 0),
  231255. +};
  231256. +
  231257. +static const struct snd_soc_dapm_route audio_map[] = {
  231258. + /* Playback */
  231259. + { "PWR", NULL, "DAC1" },
  231260. + { "PWR", NULL, "DAC1" },
  231261. +
  231262. + { "PWR", NULL, "DAC2" },
  231263. + { "PWR", NULL, "DAC2" },
  231264. +
  231265. + { "PWR", NULL, "DAC3" },
  231266. + { "PWR", NULL, "DAC3" },
  231267. +
  231268. + { "PWR", NULL, "DAC4" },
  231269. + { "PWR", NULL, "DAC4" },
  231270. +
  231271. + { "AOUT1L", NULL, "PWR" },
  231272. + { "AOUT1R", NULL, "PWR" },
  231273. +
  231274. + { "AOUT2L", NULL, "PWR" },
  231275. + { "AOUT2R", NULL, "PWR" },
  231276. +
  231277. + { "AOUT3L", NULL, "PWR" },
  231278. + { "AOUT3R", NULL, "PWR" },
  231279. +
  231280. + { "AOUT4L", NULL, "PWR" },
  231281. + { "AOUT4R", NULL, "PWR" },
  231282. +
  231283. + /* Capture */
  231284. + { "PWR", NULL, "AIN1L" },
  231285. + { "PWR", NULL, "AIN1R" },
  231286. +
  231287. + { "PWR", NULL, "AIN2L" },
  231288. + { "PWR", NULL, "AIN2R" },
  231289. +
  231290. + { "ADC1", NULL, "PWR" },
  231291. + { "ADC1", NULL, "PWR" },
  231292. +
  231293. + { "ADC2", NULL, "PWR" },
  231294. + { "ADC2", NULL, "PWR" },
  231295. +};
  231296. +
  231297. +
  231298. +static int cs42888_add_widgets(struct snd_soc_codec *codec)
  231299. +{
  231300. + snd_soc_dapm_new_controls(&codec->dapm, cs42888_dapm_widgets,
  231301. + ARRAY_SIZE(cs42888_dapm_widgets));
  231302. +
  231303. + snd_soc_dapm_add_routes(&codec->dapm, audio_map, ARRAY_SIZE(audio_map));
  231304. +
  231305. + snd_soc_dapm_new_widgets(&codec->dapm);
  231306. + return 0;
  231307. +}
  231308. +
  231309. +/**
  231310. + * struct cs42888_mode_ratios - clock ratio tables
  231311. + * @ratio: the ratio of MCLK to the sample rate
  231312. + * @speed_mode: the Speed Mode bits to set in the Mode Control register for
  231313. + * this ratio
  231314. + * @mclk: the Ratio Select bits to set in the Mode Control register for this
  231315. + * ratio
  231316. + *
  231317. + * The data for this chart is taken from Table 10 of the CS42888 reference
  231318. + * manual.
  231319. + *
  231320. + * This table is used to determine how to program the Functional Mode register.
  231321. + * It is also used by cs42888_set_dai_sysclk() to tell ALSA which sampling
  231322. + * rates the CS42888 currently supports.
  231323. + *
  231324. + * @speed_mode is the corresponding bit pattern to be written to the
  231325. + * MODE bits of the Mode Control Register
  231326. + *
  231327. + * @mclk is the corresponding bit pattern to be wirten to the MCLK bits of
  231328. + * the Mode Control Register.
  231329. + *
  231330. + */
  231331. +struct cs42888_mode_ratios {
  231332. + unsigned int ratio;
  231333. + u8 speed_mode;
  231334. + u8 mclk;
  231335. +};
  231336. +
  231337. +static struct cs42888_mode_ratios cs42888_mode_ratios[] = {
  231338. + {64, CS42888_MODE_4X, CS42888_MODE_DIV1},
  231339. + {96, CS42888_MODE_4X, CS42888_MODE_DIV2},
  231340. + {128, CS42888_MODE_2X, CS42888_MODE_DIV1},
  231341. + {192, CS42888_MODE_2X, CS42888_MODE_DIV2},
  231342. + {256, CS42888_MODE_1X, CS42888_MODE_DIV1},
  231343. + {384, CS42888_MODE_2X, CS42888_MODE_DIV4},
  231344. + {512, CS42888_MODE_1X, CS42888_MODE_DIV3},
  231345. + {768, CS42888_MODE_1X, CS42888_MODE_DIV4},
  231346. + {1024, CS42888_MODE_1X, CS42888_MODE_DIV5}
  231347. +};
  231348. +
  231349. +/* The number of MCLK/LRCK ratios supported by the CS42888 */
  231350. +#define NUM_MCLK_RATIOS ARRAY_SIZE(cs42888_mode_ratios)
  231351. +
  231352. +/**
  231353. + * cs42888_set_dai_sysclk - determine the CS42888 samples rates.
  231354. + * @codec_dai: the codec DAI
  231355. + * @clk_id: the clock ID (ignored)
  231356. + * @freq: the MCLK input frequency
  231357. + * @dir: the clock direction (ignored)
  231358. + *
  231359. + * This function is used to tell the codec driver what the input MCLK
  231360. + * frequency is.
  231361. + *
  231362. + */
  231363. +static int cs42888_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  231364. + int clk_id, unsigned int freq, int dir)
  231365. +{
  231366. + struct snd_soc_codec *codec = codec_dai->codec;
  231367. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  231368. +
  231369. + cs42888->mclk = freq;
  231370. + return 0;
  231371. +}
  231372. +
  231373. +/**
  231374. + * cs42888_set_dai_fmt - configure the codec for the selected audio format
  231375. + * @codec_dai: the codec DAI
  231376. + * @format: a SND_SOC_DAIFMT_x value indicating the data format
  231377. + *
  231378. + * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
  231379. + * codec accordingly.
  231380. + *
  231381. + * Currently, this function only supports SND_SOC_DAIFMT_I2S and
  231382. + * SND_SOC_DAIFMT_LEFT_J. The CS42888 codec also supports right-justified
  231383. + * data for playback only, but ASoC currently does not support different
  231384. + * formats for playback vs. record.
  231385. + */
  231386. +static int cs42888_set_dai_fmt(struct snd_soc_dai *codec_dai,
  231387. + unsigned int format)
  231388. +{
  231389. + struct snd_soc_codec *codec = codec_dai->codec;
  231390. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  231391. + int ret = 0;
  231392. + u8 val;
  231393. +
  231394. + val = snd_soc_read(codec, CS42888_FORMAT);
  231395. + val &= ~CS42888_FORMAT_DAC_DIF_MASK;
  231396. + val &= ~CS42888_FORMAT_ADC_DIF_MASK;
  231397. + /* set DAI format */
  231398. + switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
  231399. + case SND_SOC_DAIFMT_LEFT_J:
  231400. + val |= DIF_LEFT_J << CS42888_FORMAT_DAC_DIF_OFFSET;
  231401. + val |= DIF_LEFT_J << CS42888_FORMAT_ADC_DIF_OFFSET;
  231402. + break;
  231403. + case SND_SOC_DAIFMT_I2S:
  231404. + val |= DIF_I2S << CS42888_FORMAT_DAC_DIF_OFFSET;
  231405. + val |= DIF_I2S << CS42888_FORMAT_ADC_DIF_OFFSET;
  231406. + break;
  231407. + case SND_SOC_DAIFMT_RIGHT_J:
  231408. + val |= DIF_RIGHT_J << CS42888_FORMAT_DAC_DIF_OFFSET;
  231409. + val |= DIF_RIGHT_J << CS42888_FORMAT_ADC_DIF_OFFSET;
  231410. + break;
  231411. + default:
  231412. + dev_err(codec->dev, "invalid dai format\n");
  231413. + return -EINVAL;
  231414. + }
  231415. +
  231416. + ret = snd_soc_write(codec, CS42888_FORMAT, val);
  231417. + if (ret < 0) {
  231418. + dev_err(codec->dev, "i2c write failed\n");
  231419. + return ret;
  231420. + }
  231421. +
  231422. + val = snd_soc_read(codec, CS42888_MODE);
  231423. + /* set master/slave audio interface */
  231424. + switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
  231425. + case SND_SOC_DAIFMT_CBS_CFS:
  231426. + cs42888->slave_mode = 1;
  231427. + val &= ~CS42888_MODE_SPEED_MASK;
  231428. + val |= CS42888_MODE_SLAVE;
  231429. + break;
  231430. + case SND_SOC_DAIFMT_CBM_CFM:
  231431. + cs42888->slave_mode = 0;
  231432. + break;
  231433. + default:
  231434. + /* all other modes are unsupported by the hardware */
  231435. + return -EINVAL;
  231436. + }
  231437. +
  231438. + ret = snd_soc_write(codec, CS42888_MODE, val);
  231439. + if (ret < 0) {
  231440. + dev_err(codec->dev, "i2c write failed\n");
  231441. + return ret;
  231442. + }
  231443. +
  231444. + dump_reg(codec);
  231445. + return ret;
  231446. +}
  231447. +
  231448. +/**
  231449. + * cs42888_hw_params - program the CS42888 with the given hardware parameters.
  231450. + * @substream: the audio stream
  231451. + * @params: the hardware parameters to set
  231452. +
  231453. + * @dai: the SOC DAI (ignored)
  231454. + *
  231455. + * This function programs the hardware with the values provided.
  231456. + * Specifically, the sample rate and the data format.
  231457. + *
  231458. + * The .ops functions are used to provide board-specific data, like input
  231459. + * frequencies, to this driver. This function takes that information,
  231460. + * combines it with the hardware parameters provided, and programs the
  231461. + * hardware accordingly.
  231462. + */
  231463. +static int cs42888_hw_params(struct snd_pcm_substream *substream,
  231464. + struct snd_pcm_hw_params *params,
  231465. + struct snd_soc_dai *dai)
  231466. +{
  231467. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231468. + struct snd_soc_codec *codec = rtd->codec;
  231469. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  231470. + int ret;
  231471. + u32 i, rate, ratio, val;
  231472. +
  231473. + rate = params_rate(params); /* Sampling rate, in Hz */
  231474. + ratio = cs42888->mclk / rate; /* MCLK/LRCK ratio */
  231475. + for (i = 0; i < NUM_MCLK_RATIOS; i++) {
  231476. + if (cs42888_mode_ratios[i].ratio == ratio)
  231477. + break;
  231478. + }
  231479. +
  231480. + if (i == NUM_MCLK_RATIOS) {
  231481. + /* We did not find a matching ratio */
  231482. + dev_err(codec->dev, "could not find matching ratio\n");
  231483. + return -EINVAL;
  231484. + }
  231485. +
  231486. + if (!cs42888->slave_mode) {
  231487. + val = snd_soc_read(codec, CS42888_MODE);
  231488. + val &= ~CS42888_MODE_SPEED_MASK;
  231489. + val |= cs42888_mode_ratios[i].speed_mode;
  231490. + val &= ~CS42888_MODE_DIV_MASK;
  231491. + val |= cs42888_mode_ratios[i].mclk;
  231492. + } else {
  231493. + val = snd_soc_read(codec, CS42888_MODE);
  231494. + val &= ~CS42888_MODE_SPEED_MASK;
  231495. + val |= CS42888_MODE_SLAVE;
  231496. + val &= ~CS42888_MODE_DIV_MASK;
  231497. + val |= cs42888_mode_ratios[i].mclk;
  231498. + }
  231499. + ret = snd_soc_write(codec, CS42888_MODE, val);
  231500. + if (ret < 0) {
  231501. + dev_err(codec->dev, "i2c write failed\n");
  231502. + return ret;
  231503. + }
  231504. +
  231505. + /* Unmute all the channels */
  231506. + val = snd_soc_read(codec, CS42888_MUTE);
  231507. + val &= ~CS42888_MUTE_ALL;
  231508. + ret = snd_soc_write(codec, CS42888_MUTE, val);
  231509. + if (ret < 0) {
  231510. + dev_err(codec->dev, "i2c write failed\n");
  231511. + return ret;
  231512. + }
  231513. +
  231514. + ret = cs42888_fill_cache(codec);
  231515. + if (ret < 0) {
  231516. + dev_err(codec->dev, "failed to fill register cache\n");
  231517. + return ret;
  231518. + }
  231519. +
  231520. + dump_reg(codec);
  231521. + return ret;
  231522. +}
  231523. +
  231524. +/**
  231525. + * cs42888_shutdown - cs42888 enters into low power mode again.
  231526. + * @substream: the audio stream
  231527. + * @dai: the SOC DAI (ignored)
  231528. + *
  231529. + * The .ops functions are used to provide board-specific data, like input
  231530. + * frequencies, to this driver. This function takes that information,
  231531. + * combines it with the hardware parameters provided, and programs the
  231532. + * hardware accordingly.
  231533. + */
  231534. +static void cs42888_shutdown(struct snd_pcm_substream *substream,
  231535. + struct snd_soc_dai *dai)
  231536. +{
  231537. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231538. + struct snd_soc_codec *codec = rtd->codec;
  231539. + int ret;
  231540. + u8 val;
  231541. +
  231542. + /* Mute all the channels */
  231543. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  231544. + val = snd_soc_read(codec, CS42888_MUTE);
  231545. + val |= CS42888_MUTE_ALL;
  231546. + ret = snd_soc_write(codec, CS42888_MUTE, val);
  231547. + if (ret < 0)
  231548. + dev_err(codec->dev, "i2c write failed\n");
  231549. + }
  231550. +}
  231551. +
  231552. +static int cs42888_prepare(struct snd_pcm_substream *substream,
  231553. + struct snd_soc_dai *dai)
  231554. +{
  231555. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  231556. + struct snd_soc_card *card = rtd->card;
  231557. + struct snd_soc_dai *tmp_codec_dai;
  231558. + struct snd_soc_pcm_runtime *tmp_rtd;
  231559. + u32 i;
  231560. +
  231561. + for (i = 0; i < card->num_rtd; i++) {
  231562. + tmp_codec_dai = card->rtd[i].codec_dai;
  231563. + tmp_rtd = (struct snd_soc_pcm_runtime *)(card->rtd + i);
  231564. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  231565. + cancel_delayed_work(&tmp_rtd->delayed_work);
  231566. + }
  231567. + return 0;
  231568. +}
  231569. +
  231570. +static struct snd_soc_dai_ops cs42888_dai_ops = {
  231571. + .set_fmt = cs42888_set_dai_fmt,
  231572. + .set_sysclk = cs42888_set_dai_sysclk,
  231573. + .hw_params = cs42888_hw_params,
  231574. + .shutdown = cs42888_shutdown,
  231575. + .prepare = cs42888_prepare,
  231576. +};
  231577. +
  231578. +
  231579. +static struct snd_soc_dai_driver cs42888_dai = {
  231580. + .name = "CS42888",
  231581. + .playback = {
  231582. + .stream_name = "codec-Playback",
  231583. + .channels_min = 2,
  231584. + .channels_max = 8,
  231585. + .rates = SNDRV_PCM_RATE_8000_192000,
  231586. + .formats = CS42888_FORMATS,
  231587. + },
  231588. + .capture = {
  231589. + .stream_name = "codec-Capture",
  231590. + .channels_min = 2,
  231591. + .channels_max = 4,
  231592. + .rates = SNDRV_PCM_RATE_8000_192000,
  231593. + .formats = CS42888_FORMATS,
  231594. + },
  231595. + .ops = &cs42888_dai_ops,
  231596. +};
  231597. +
  231598. +/**
  231599. + * cs42888_probe - ASoC probe function
  231600. + * @pdev: platform device
  231601. + *
  231602. + * This function is called when ASoC has all the pieces it needs to
  231603. + * instantiate a sound driver.
  231604. + */
  231605. +static int cs42888_probe(struct snd_soc_codec *codec)
  231606. +{
  231607. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  231608. + int ret, i, val;
  231609. +
  231610. + cs42888->codec = codec;
  231611. + /* setup i2c data ops */
  231612. + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
  231613. + if (ret < 0) {
  231614. + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
  231615. + return ret;
  231616. + }
  231617. +
  231618. + for (i = 0; i < ARRAY_SIZE(cs42888->supplies); i++)
  231619. + cs42888->supplies[i].supply = cs42888_supply_names[i];
  231620. +
  231621. + ret = devm_regulator_bulk_get(codec->dev,
  231622. + ARRAY_SIZE(cs42888->supplies), cs42888->supplies);
  231623. + if (ret) {
  231624. + dev_err(codec->dev, "Failed to request supplies: %d\n",
  231625. + ret);
  231626. + return ret;
  231627. + }
  231628. +
  231629. + ret = regulator_bulk_enable(ARRAY_SIZE(cs42888->supplies),
  231630. + cs42888->supplies);
  231631. + if (ret) {
  231632. + dev_err(codec->dev, "Failed to enable supplies: %d\n",
  231633. + ret);
  231634. + goto err;
  231635. + }
  231636. + msleep(1);
  231637. +
  231638. + /* The I2C interface is set up, so pre-fill our register cache */
  231639. + ret = cs42888_fill_cache(codec);
  231640. + if (ret < 0) {
  231641. + dev_err(codec->dev, "failed to fill register cache\n");
  231642. + goto err;
  231643. + }
  231644. +
  231645. + /* Enter low power state */
  231646. + val = snd_soc_read(codec, CS42888_PWRCTL);
  231647. + val |= CS42888_PWRCTL_PDN_MASK;
  231648. + ret = snd_soc_write(codec, CS42888_PWRCTL, val);
  231649. + if (ret < 0) {
  231650. + dev_err(codec->dev, "i2c write failed\n");
  231651. + goto err;
  231652. + }
  231653. +
  231654. + /* Disable auto-mute */
  231655. + val = snd_soc_read(codec, CS42888_TRANS);
  231656. + val &= ~CS42888_TRANS_AMUTE_MASK;
  231657. + val &= ~CS42888_TRANS_DAC_SZC_MASK;
  231658. + val |= CS42888_TRANS_DAC_SZC_SR;
  231659. + ret = snd_soc_write(codec, CS42888_TRANS, val);
  231660. + if (ret < 0) {
  231661. + dev_err(codec->dev, "i2c write failed\n");
  231662. + goto err;
  231663. + }
  231664. + /* Add the non-DAPM controls */
  231665. + snd_soc_add_codec_controls(codec, cs42888_snd_controls,
  231666. + ARRAY_SIZE(cs42888_snd_controls));
  231667. +
  231668. + /* Add DAPM controls */
  231669. + cs42888_add_widgets(codec);
  231670. + return 0;
  231671. +err:
  231672. + regulator_bulk_disable(ARRAY_SIZE(cs42888->supplies),
  231673. + cs42888->supplies);
  231674. + return ret;
  231675. +}
  231676. +
  231677. +/**
  231678. + * cs42888_remove - ASoC remove function
  231679. + * @pdev: platform device
  231680. + *
  231681. + * This function is the counterpart to cs42888_probe().
  231682. + */
  231683. +static int cs42888_remove(struct snd_soc_codec *codec)
  231684. +{
  231685. + struct cs42888_private *cs42888 = snd_soc_codec_get_drvdata(codec);
  231686. +
  231687. + regulator_bulk_disable(ARRAY_SIZE(cs42888->supplies),
  231688. + cs42888->supplies);
  231689. +
  231690. + return 0;
  231691. +};
  231692. +
  231693. +/*
  231694. + * ASoC codec device structure
  231695. + *
  231696. + * Assign this variable to the codec_dev field of the machine driver's
  231697. + * snd_soc_device structure.
  231698. + */
  231699. +static struct snd_soc_codec_driver cs42888_driver = {
  231700. + .probe = cs42888_probe,
  231701. + .remove = cs42888_remove,
  231702. + .reg_cache_size = CS42888_NUMREGS + 1,
  231703. + .reg_word_size = sizeof(u8),
  231704. + .reg_cache_step = 1,
  231705. +};
  231706. +
  231707. +/**
  231708. + * cs42888_i2c_probe - initialize the I2C interface of the CS42888
  231709. + * @i2c_client: the I2C client object
  231710. + * @id: the I2C device ID (ignored)
  231711. + *
  231712. + * This function is called whenever the I2C subsystem finds a device that
  231713. + * matches the device ID given via a prior call to i2c_add_driver().
  231714. + */
  231715. +static int cs42888_i2c_probe(struct i2c_client *i2c_client,
  231716. + const struct i2c_device_id *id)
  231717. +{
  231718. + struct cs42888_private *cs42888;
  231719. + int ret, val;
  231720. +
  231721. + /* Verify that we have a CS42888 */
  231722. + val = i2c_smbus_read_byte_data(i2c_client, CS42888_CHIPID);
  231723. + if (val < 0) {
  231724. + dev_err(&i2c_client->dev, "Device with ID register %x is not a CS42888", val);
  231725. + return -ENODEV;
  231726. + }
  231727. + /* The top four bits of the chip ID should be 0000. */
  231728. + if ((val & CS42888_CHIPID_ID_MASK) != 0x00) {
  231729. + dev_err(&i2c_client->dev, "device is not a CS42888\n");
  231730. + return -ENODEV;
  231731. + }
  231732. +
  231733. + dev_info(&i2c_client->dev, "found device at i2c address %X\n",
  231734. + i2c_client->addr);
  231735. + dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
  231736. +
  231737. + /* Allocate enough space for the snd_soc_codec structure
  231738. + and our private data together. */
  231739. + cs42888 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42888_private), GFP_KERNEL);
  231740. + if (!cs42888) {
  231741. + dev_err(&i2c_client->dev, "could not allocate codec\n");
  231742. + return -ENOMEM;
  231743. + }
  231744. +
  231745. + i2c_set_clientdata(i2c_client, cs42888);
  231746. +
  231747. + cs42888->clk = devm_clk_get(&i2c_client->dev, NULL);
  231748. + if (IS_ERR(cs42888->clk)) {
  231749. + ret = PTR_ERR(cs42888->clk);
  231750. + dev_err(&i2c_client->dev, "Cannot get the clock: %d\n", ret);
  231751. + return ret;
  231752. + }
  231753. +
  231754. + cs42888->mclk = clk_get_rate(cs42888->clk);
  231755. + switch (cs42888->mclk) {
  231756. + case 24576000:
  231757. + cs42888_dai.playback.rates = SNDRV_PCM_RATE_48000 |
  231758. + SNDRV_PCM_RATE_96000 |
  231759. + SNDRV_PCM_RATE_192000;
  231760. + cs42888_dai.capture.rates = SNDRV_PCM_RATE_48000 |
  231761. + SNDRV_PCM_RATE_96000 |
  231762. + SNDRV_PCM_RATE_192000;
  231763. + break;
  231764. + case 16934400:
  231765. + cs42888_dai.playback.rates = SNDRV_PCM_RATE_44100 |
  231766. + SNDRV_PCM_RATE_88200 |
  231767. + SNDRV_PCM_RATE_176400;
  231768. + cs42888_dai.capture.rates = SNDRV_PCM_RATE_44100 |
  231769. + SNDRV_PCM_RATE_88200 |
  231770. + SNDRV_PCM_RATE_176400;
  231771. + break;
  231772. + default:
  231773. + dev_err(&i2c_client->dev, "codec mclk is not supported %d\n", cs42888->mclk);
  231774. + break;
  231775. + }
  231776. +
  231777. + ret = snd_soc_register_codec(&i2c_client->dev,
  231778. + &cs42888_driver, &cs42888_dai, 1);
  231779. + if (ret) {
  231780. + dev_err(&i2c_client->dev, "Failed to register codec:%d\n", ret);
  231781. + return ret;
  231782. + }
  231783. + return 0;
  231784. +}
  231785. +
  231786. +/**
  231787. + * cs42888_i2c_remove - remove an I2C device
  231788. + * @i2c_client: the I2C client object
  231789. + *
  231790. + * This function is the counterpart to cs42888_i2c_probe().
  231791. + */
  231792. +static int cs42888_i2c_remove(struct i2c_client *i2c_client)
  231793. +{
  231794. + snd_soc_unregister_codec(&i2c_client->dev);
  231795. + return 0;
  231796. +}
  231797. +
  231798. +/*
  231799. + * cs42888_i2c_id - I2C device IDs supported by this driver
  231800. + */
  231801. +static struct i2c_device_id cs42888_i2c_id[] = {
  231802. + {"cs42888", 0},
  231803. + {}
  231804. +};
  231805. +MODULE_DEVICE_TABLE(i2c, cs42888_i2c_id);
  231806. +
  231807. +#ifdef CONFIG_PM
  231808. +/* This suspend/resume implementation can handle both - a simple standby
  231809. + * where the codec remains powered, and a full suspend, where the voltage
  231810. + * domain the codec is connected to is teared down and/or any other hardware
  231811. + * reset condition is asserted.
  231812. + *
  231813. + * The codec's own power saving features are enabled in the suspend callback,
  231814. + * and all registers are written back to the hardware when resuming.
  231815. + */
  231816. +
  231817. +static int cs42888_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
  231818. +{
  231819. + struct cs42888_private *cs42888 = i2c_get_clientdata(client);
  231820. + struct snd_soc_codec *codec = cs42888->codec;
  231821. + int reg = snd_soc_read(codec, CS42888_PWRCTL) | CS42888_PWRCTL_PDN_MASK;
  231822. + return snd_soc_write(codec, CS42888_PWRCTL, reg);
  231823. +}
  231824. +
  231825. +static int cs42888_i2c_resume(struct i2c_client *client)
  231826. +{
  231827. + struct cs42888_private *cs42888 = i2c_get_clientdata(client);
  231828. + struct snd_soc_codec *codec = cs42888->codec;
  231829. + int reg;
  231830. +
  231831. + /* In case the device was put to hard reset during sleep, we need to
  231832. + * wait 500ns here before any I2C communication. */
  231833. + ndelay(500);
  231834. +
  231835. + /* first restore the entire register cache ... */
  231836. + for (reg = CS42888_FIRSTREG; reg <= CS42888_LASTREG; reg++) {
  231837. + u8 val = snd_soc_read(codec, reg);
  231838. +
  231839. + if (i2c_smbus_write_byte_data(client, reg, val)) {
  231840. + dev_err(codec->dev, "i2c write failed\n");
  231841. + return -EIO;
  231842. + }
  231843. + }
  231844. +
  231845. + /* ... then disable the power-down bits */
  231846. + reg = snd_soc_read(codec, CS42888_PWRCTL);
  231847. + reg &= ~CS42888_PWRCTL_PDN_MASK;
  231848. + return snd_soc_write(codec, CS42888_PWRCTL, reg);
  231849. +}
  231850. +#else
  231851. +#define cs42888_i2c_suspend NULL
  231852. +#define cs42888_i2c_resume NULL
  231853. +#endif /* CONFIG_PM */
  231854. +
  231855. +/*
  231856. + * cs42888_i2c_driver - I2C device identification
  231857. + *
  231858. + * This structure tells the I2C subsystem how to identify and support a
  231859. + * given I2C device type.
  231860. + */
  231861. +
  231862. +static const struct of_device_id cs42888_dt_ids[] = {
  231863. + { .compatible = "cirrus,cs42888", },
  231864. + { /* sentinel */ }
  231865. +};
  231866. +
  231867. +static struct i2c_driver cs42888_i2c_driver = {
  231868. + .driver = {
  231869. + .name = "cs42888",
  231870. + .owner = THIS_MODULE,
  231871. + .of_match_table = cs42888_dt_ids,
  231872. + },
  231873. + .probe = cs42888_i2c_probe,
  231874. + .remove = cs42888_i2c_remove,
  231875. + .suspend = cs42888_i2c_suspend,
  231876. + .resume = cs42888_i2c_resume,
  231877. + .id_table = cs42888_i2c_id,
  231878. +};
  231879. +
  231880. +module_i2c_driver(cs42888_i2c_driver);
  231881. +
  231882. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  231883. +MODULE_DESCRIPTION("Cirrus Logic CS42888 ALSA SoC Codec Driver");
  231884. +MODULE_LICENSE("GPL");
  231885. diff -Nur linux-3.14.17/sound/soc/codecs/cs42888.h linux-imx6-3.14/sound/soc/codecs/cs42888.h
  231886. --- linux-3.14.17/sound/soc/codecs/cs42888.h 1970-01-01 01:00:00.000000000 +0100
  231887. +++ linux-imx6-3.14/sound/soc/codecs/cs42888.h 2014-09-11 18:06:18.638104376 +0200
  231888. @@ -0,0 +1,123 @@
  231889. +/*
  231890. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  231891. + */
  231892. +
  231893. +/*
  231894. + * The code contained herein is licensed under the GNU General Public
  231895. + * License. You may obtain a copy of the GNU General Public License
  231896. + * Version 2 or later at the following locations:
  231897. + *
  231898. + * http://www.opensource.org/licenses/gpl-license.html
  231899. + * http://www.gnu.org/copyleft/gpl.html
  231900. + */
  231901. +
  231902. +#ifndef _CS42888_H
  231903. +#define _CS42888_H
  231904. +
  231905. +/* CS42888 registers addresses */
  231906. +#define CS42888_CHIPID 0x01 /* Chip ID */
  231907. +#define CS42888_PWRCTL 0x02 /* Power Control */
  231908. +#define CS42888_MODE 0x03 /* Functional Mode */
  231909. +#define CS42888_FORMAT 0x04 /* Interface Formats */
  231910. +#define CS42888_ADCCTL 0x05 /* ADC Control */
  231911. +#define CS42888_TRANS 0x06 /* Transition Control */
  231912. +#define CS42888_MUTE 0x07 /* Mute Control */
  231913. +#define CS42888_VOLAOUT1 0x08 /* Volume Control AOUT1*/
  231914. +#define CS42888_VOLAOUT2 0x09 /* Volume Control AOUT2*/
  231915. +#define CS42888_VOLAOUT3 0x0A /* Volume Control AOUT3*/
  231916. +#define CS42888_VOLAOUT4 0x0B /* Volume Control AOUT4*/
  231917. +#define CS42888_VOLAOUT5 0x0C /* Volume Control AOUT5*/
  231918. +#define CS42888_VOLAOUT6 0x0D /* Volume Control AOUT6*/
  231919. +#define CS42888_VOLAOUT7 0x0E /* Volume Control AOUT7*/
  231920. +#define CS42888_VOLAOUT8 0x0F /* Volume Control AOUT8*/
  231921. +#define CS42888_DACINV 0x10 /* DAC Channel Invert */
  231922. +#define CS42888_VOLAIN1 0x11 /* Volume Control AIN1 */
  231923. +#define CS42888_VOLAIN2 0x12 /* Volume Control AIN2 */
  231924. +#define CS42888_VOLAIN3 0x13 /* Volume Control AIN3 */
  231925. +#define CS42888_VOLAIN4 0x14 /* Volume Control AIN4 */
  231926. +#define CS42888_ADCINV 0x17 /* ADC Channel Invert */
  231927. +#define CS42888_STATUSCTL 0x18 /* Status Control */
  231928. +#define CS42888_STATUS 0x19 /* Status */
  231929. +#define CS42888_STATUSMASK 0x1A /* Status Mask */
  231930. +
  231931. +#define CS42888_FIRSTREG 0x01
  231932. +#define CS42888_LASTREG 0x1A
  231933. +#define CS42888_NUMREGS (CS42888_LASTREG - CS42888_FIRSTREG + 1)
  231934. +#define CS42888_I2C_INCR 0x80
  231935. +
  231936. +/* Bit masks for the CS42888 registers */
  231937. +#define CS42888_CHIPID_ID_MASK 0xF0
  231938. +#define CS42888_CHIPID_REV 0x0F
  231939. +#define CS42888_PWRCTL_PDN_ADC2_OFFSET 6
  231940. +#define CS42888_PWRCTL_PDN_ADC1_OFFSET 5
  231941. +#define CS42888_PWRCTL_PDN_DAC4_OFFSET 4
  231942. +#define CS42888_PWRCTL_PDN_DAC3_OFFSET 3
  231943. +#define CS42888_PWRCTL_PDN_DAC2_OFFSET 2
  231944. +#define CS42888_PWRCTL_PDN_DAC1_OFFSET 1
  231945. +#define CS42888_PWRCTL_PDN_OFFSET 0
  231946. +#define CS42888_PWRCTL_PDN_ADC2_MASK (1 << CS42888_PWRCTL_PDN_ADC2_OFFSET)
  231947. +#define CS42888_PWRCTL_PDN_ADC1_MASK (1 << CS42888_PWRCTL_PDN_ADC1_OFFSET)
  231948. +#define CS42888_PWRCTL_PDN_DAC4_MASK (1 << CS42888_PWRCTL_PDN_DAC4_OFFSET)
  231949. +#define CS42888_PWRCTL_PDN_DAC3_MASK (1 << CS42888_PWRCTL_PDN_DAC3_OFFSET)
  231950. +#define CS42888_PWRCTL_PDN_DAC2_MASK (1 << CS42888_PWRCTL_PDN_DAC2_OFFSET)
  231951. +#define CS42888_PWRCTL_PDN_DAC1_MASK (1 << CS42888_PWRCTL_PDN_DAC1_OFFSET)
  231952. +#define CS42888_PWRCTL_PDN_MASK (1 << CS42888_PWRCTL_PDN_OFFSET)
  231953. +
  231954. +#define CS42888_MODE_SPEED_MASK 0xF0
  231955. +#define CS42888_MODE_1X 0x00
  231956. +#define CS42888_MODE_2X 0x50
  231957. +#define CS42888_MODE_4X 0xA0
  231958. +#define CS42888_MODE_SLAVE 0xF0
  231959. +#define CS42888_MODE_DIV_MASK 0x0E
  231960. +#define CS42888_MODE_DIV1 0x00
  231961. +#define CS42888_MODE_DIV2 0x02
  231962. +#define CS42888_MODE_DIV3 0x04
  231963. +#define CS42888_MODE_DIV4 0x06
  231964. +#define CS42888_MODE_DIV5 0x08
  231965. +
  231966. +#define CS42888_FORMAT_FREEZE_OFFSET 7
  231967. +#define CS42888_FORMAT_AUX_DIF_OFFSET 6
  231968. +#define CS42888_FORMAT_DAC_DIF_OFFSET 3
  231969. +#define CS42888_FORMAT_ADC_DIF_OFFSET 0
  231970. +#define CS42888_FORMAT_FREEZE_MASK (1 << CS42888_FORMAT_FREEZE_OFFSET)
  231971. +#define CS42888_FORMAT_AUX_DIF_MASK (1 << CS42888_FORMAT_AUX_DIF_OFFSET)
  231972. +#define CS42888_FORMAT_DAC_DIF_MASK (7 << CS42888_FORMAT_DAC_DIF_OFFSET)
  231973. +#define CS42888_FORMAT_ADC_DIF_MASK (7 << CS42888_FORMAT_ADC_DIF_OFFSET)
  231974. +
  231975. +#define CS42888_TRANS_DAC_SNGVOL_OFFSET 7
  231976. +#define CS42888_TRANS_DAC_SZC_OFFSET 5
  231977. +#define CS42888_TRANS_AMUTE_OFFSET 4
  231978. +#define CS42888_TRANS_MUTE_ADC_SP_OFFSET 3
  231979. +#define CS42888_TRANS_ADC_SNGVOL_OFFSET 2
  231980. +#define CS42888_TRANS_ADC_SZC_OFFSET 0
  231981. +#define CS42888_TRANS_DAC_SNGVOL_MASK (1 << CS42888_TRANS_DAC_SNGVOL_OFFSET)
  231982. +#define CS42888_TRANS_DAC_SZC_MASK (3 << CS42888_TRANS_DAC_SZC_OFFSET)
  231983. +#define CS42888_TRANS_AMUTE_MASK (1 << CS42888_TRANS_AMUTE_OFFSET)
  231984. +#define CS42888_TRANS_MUTE_ADC_SP_MASK (1 << CS42888_TRANS_MUTE_ADC_SP_OFFSET)
  231985. +#define CS42888_TRANS_ADC_SNGVOL_MASK (1 << CS42888_TRANS_ADC_SNGVOL_OFFSET)
  231986. +#define CS42888_TRANS_ADC_SZC_MASK (3 << CS42888_TRANS_ADC_SZC_OFFSET)
  231987. +#define CS42888_TRANS_DAC_SZC_IC (0 << CS42888_TRANS_DAC_SZC_OFFSET)
  231988. +#define CS42888_TRANS_DAC_SZC_ZC (1 << CS42888_TRANS_DAC_SZC_OFFSET)
  231989. +#define CS42888_TRANS_DAC_SZC_SR (2 << CS42888_TRANS_DAC_SZC_OFFSET)
  231990. +#define CS42888_TRANS_DAC_SZC_SRZC (3 << CS42888_TRANS_DAC_SZC_OFFSET)
  231991. +
  231992. +#define CS42888_MUTE_AOUT8 (0x1 << 7)
  231993. +#define CS42888_MUTE_AOUT7 (0x1 << 6)
  231994. +#define CS42888_MUTE_AOUT6 (0x1 << 5)
  231995. +#define CS42888_MUTE_AOUT5 (0x1 << 4)
  231996. +#define CS42888_MUTE_AOUT4 (0x1 << 3)
  231997. +#define CS42888_MUTE_AOUT3 (0x1 << 2)
  231998. +#define CS42888_MUTE_AOUT2 (0x1 << 1)
  231999. +#define CS42888_MUTE_AOUT1 (0x1 << 0)
  232000. +#define CS42888_MUTE_ALL (CS42888_MUTE_AOUT1 | CS42888_MUTE_AOUT2 | \
  232001. + CS42888_MUTE_AOUT3 | CS42888_MUTE_AOUT4 | \
  232002. + CS42888_MUTE_AOUT5 | CS42888_MUTE_AOUT6 | \
  232003. + CS42888_MUTE_AOUT7 | CS42888_MUTE_AOUT8)
  232004. +
  232005. +#define DIF_LEFT_J 0
  232006. +#define DIF_I2S 1
  232007. +#define DIF_RIGHT_J 2
  232008. +#define DIF_TDM 6
  232009. +
  232010. +
  232011. +#endif
  232012. diff -Nur linux-3.14.17/sound/soc/codecs/Kconfig linux-imx6-3.14/sound/soc/codecs/Kconfig
  232013. --- linux-3.14.17/sound/soc/codecs/Kconfig 2014-08-14 03:38:34.000000000 +0200
  232014. +++ linux-imx6-3.14/sound/soc/codecs/Kconfig 2014-09-11 18:06:18.630104344 +0200
  232015. @@ -37,6 +37,7 @@
  232016. select SND_SOC_CS42L73 if I2C
  232017. select SND_SOC_CS4270 if I2C
  232018. select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
  232019. + select SND_SOC_CS42888 if I2C
  232020. select SND_SOC_CX20442 if TTY
  232021. select SND_SOC_DA7210 if I2C
  232022. select SND_SOC_DA7213 if I2C
  232023. @@ -254,6 +255,9 @@
  232024. config SND_SOC_CS4271
  232025. tristate
  232026. +config SND_SOC_CS42888
  232027. + tristate
  232028. +
  232029. config SND_SOC_CX20442
  232030. tristate
  232031. depends on TTY
  232032. diff -Nur linux-3.14.17/sound/soc/codecs/Makefile linux-imx6-3.14/sound/soc/codecs/Makefile
  232033. --- linux-3.14.17/sound/soc/codecs/Makefile 2014-08-14 03:38:34.000000000 +0200
  232034. +++ linux-imx6-3.14/sound/soc/codecs/Makefile 2014-09-11 18:06:18.630104344 +0200
  232035. @@ -23,6 +23,7 @@
  232036. snd-soc-cs42l73-objs := cs42l73.o
  232037. snd-soc-cs4270-objs := cs4270.o
  232038. snd-soc-cs4271-objs := cs4271.o
  232039. +snd-soc-cs42888-objs := cs42888.o
  232040. snd-soc-cx20442-objs := cx20442.o
  232041. snd-soc-da7210-objs := da7210.o
  232042. snd-soc-da7213-objs := da7213.o
  232043. @@ -156,6 +157,7 @@
  232044. obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
  232045. obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
  232046. obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
  232047. +obj-$(CONFIG_SND_SOC_CS42888) += snd-soc-cs42888.o
  232048. obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
  232049. obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
  232050. obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
  232051. diff -Nur linux-3.14.17/sound/soc/codecs/sgtl5000.c linux-imx6-3.14/sound/soc/codecs/sgtl5000.c
  232052. --- linux-3.14.17/sound/soc/codecs/sgtl5000.c 2014-08-14 03:38:34.000000000 +0200
  232053. +++ linux-imx6-3.14/sound/soc/codecs/sgtl5000.c 2014-09-11 18:06:18.646104409 +0200
  232054. @@ -756,7 +756,7 @@
  232055. struct ldo_regulator *ldo = rdev_get_drvdata(dev);
  232056. struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
  232057. int reg;
  232058. -
  232059. +dev_info(codec->dev, "%s(): enabled %u\n", __func__, ldo->enabled);
  232060. if (ldo_regulator_is_enabled(dev))
  232061. return 0;
  232062. @@ -788,10 +788,16 @@
  232063. {
  232064. struct ldo_regulator *ldo = rdev_get_drvdata(dev);
  232065. struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
  232066. +dev_info(codec->dev, "%s(): enabled %u\n", __func__, ldo->enabled);
  232067. +
  232068. + snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  232069. + SGTL5000_LINREG_SIMPLE_POWERUP,
  232070. + SGTL5000_LINREG_SIMPLE_POWERUP);
  232071. snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  232072. SGTL5000_LINEREG_D_POWERUP,
  232073. 0);
  232074. +dev_info(codec->dev, "%s: ANA_POWER = 0x%04x\n", __func__, snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER));
  232075. /* clear voltage info */
  232076. snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
  232077. @@ -849,6 +855,7 @@
  232078. config.dev = codec->dev;
  232079. config.driver_data = ldo;
  232080. config.init_data = init_data;
  232081. + config.ena_gpio = -EINVAL;
  232082. ldo->dev = regulator_register(&ldo->desc, &config);
  232083. if (IS_ERR(ldo->dev)) {
  232084. @@ -1202,8 +1209,11 @@
  232085. * if vddio and vddd > 3.1v,
  232086. * charge pump should be clean before set ana_pwr
  232087. */
  232088. - snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  232089. - SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
  232090. +// FIXME: this is total crap - we have read this register above into
  232091. +// ana_pwr, which we then modify (above), and then write back to the
  232092. +// register below. This modification just gets completely overwritten.
  232093. +// snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
  232094. +// SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
  232095. /* VDDC use VDDIO rail */
  232096. lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
  232097. @@ -1320,7 +1330,7 @@
  232098. return ret;
  232099. }
  232100. - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
  232101. + ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
  232102. sgtl5000->supplies);
  232103. if (ret)
  232104. goto err_ldo_remove;
  232105. @@ -1328,16 +1338,13 @@
  232106. ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
  232107. sgtl5000->supplies);
  232108. if (ret)
  232109. - goto err_regulator_free;
  232110. + goto err_ldo_remove;
  232111. /* wait for all power rails bring up */
  232112. udelay(10);
  232113. return 0;
  232114. -err_regulator_free:
  232115. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  232116. - sgtl5000->supplies);
  232117. err_ldo_remove:
  232118. if (!external_vddd)
  232119. ldo_regulator_remove(codec);
  232120. @@ -1358,6 +1365,9 @@
  232121. return ret;
  232122. }
  232123. + if (!devres_open_group(codec->dev, NULL, GFP_KERNEL))
  232124. + return -ENOMEM;
  232125. +
  232126. ret = sgtl5000_enable_regulators(codec);
  232127. if (ret)
  232128. return ret;
  232129. @@ -1415,8 +1425,9 @@
  232130. err:
  232131. regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
  232132. sgtl5000->supplies);
  232133. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  232134. - sgtl5000->supplies);
  232135. +
  232136. + devres_release_group(codec->dev, NULL);
  232137. +
  232138. ldo_regulator_remove(codec);
  232139. return ret;
  232140. @@ -1430,8 +1441,9 @@
  232141. regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
  232142. sgtl5000->supplies);
  232143. - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
  232144. - sgtl5000->supplies);
  232145. +
  232146. + devres_release_group(codec->dev, NULL);
  232147. +
  232148. ldo_regulator_remove(codec);
  232149. return 0;
  232150. diff -Nur linux-3.14.17/sound/soc/codecs/spdif_transmitter.c linux-imx6-3.14/sound/soc/codecs/spdif_transmitter.c
  232151. --- linux-3.14.17/sound/soc/codecs/spdif_transmitter.c 2014-08-14 03:38:34.000000000 +0200
  232152. +++ linux-imx6-3.14/sound/soc/codecs/spdif_transmitter.c 2014-09-11 18:06:18.646104409 +0200
  232153. @@ -24,7 +24,7 @@
  232154. #define DRV_NAME "spdif-dit"
  232155. -#define STUB_RATES SNDRV_PCM_RATE_8000_96000
  232156. +#define STUB_RATES SNDRV_PCM_RATE_8000_192000
  232157. #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
  232158. SNDRV_PCM_FMTBIT_S20_3LE | \
  232159. SNDRV_PCM_FMTBIT_S24_LE)
  232160. diff -Nur linux-3.14.17/sound/soc/codecs/wm8962.c linux-imx6-3.14/sound/soc/codecs/wm8962.c
  232161. --- linux-3.14.17/sound/soc/codecs/wm8962.c 2014-08-14 03:38:34.000000000 +0200
  232162. +++ linux-imx6-3.14/sound/soc/codecs/wm8962.c 2014-09-11 18:06:18.674104519 +0200
  232163. @@ -16,6 +16,7 @@
  232164. #include <linux/init.h>
  232165. #include <linux/delay.h>
  232166. #include <linux/pm.h>
  232167. +#include <linux/clk.h>
  232168. #include <linux/gcd.h>
  232169. #include <linux/gpio.h>
  232170. #include <linux/i2c.h>
  232171. @@ -2942,7 +2943,8 @@
  232172. WM8962_DAC_MUTE, val);
  232173. }
  232174. -#define WM8962_RATES SNDRV_PCM_RATE_8000_96000
  232175. +#define WM8962_RATES (SNDRV_PCM_RATE_8000_48000 |\
  232176. + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
  232177. #define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  232178. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  232179. @@ -3536,6 +3538,15 @@
  232180. pdata->gpio_init[i] = 0x0;
  232181. }
  232182. + pdata->codec_mclk = devm_clk_get(&i2c->dev, NULL);
  232183. +
  232184. + /*
  232185. + * If clk_get() failed, we assume that clock's enabled by default.
  232186. + * Otherwise, we let driver prepare and control the clock source.
  232187. + */
  232188. + if (IS_ERR(pdata->codec_mclk))
  232189. + pdata->codec_mclk = NULL;
  232190. +
  232191. return 0;
  232192. }
  232193. @@ -3567,6 +3578,9 @@
  232194. return ret;
  232195. }
  232196. + if (wm8962->pdata.codec_mclk)
  232197. + clk_prepare(wm8962->pdata.codec_mclk);
  232198. +
  232199. for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
  232200. wm8962->supplies[i].supply = wm8962_supply_names[i];
  232201. @@ -3669,6 +3683,27 @@
  232202. WM8962_MICBIAS_LVL,
  232203. wm8962->pdata.mic_cfg);
  232204. + /* set the default volume for playback and record*/
  232205. + snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME,
  232206. + WM8962_HPOUTL_VOL_MASK, 0x5d);
  232207. + snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
  232208. + WM8962_HPOUTR_VOL_MASK, 0x5d);
  232209. + snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME,
  232210. + WM8962_SPKOUTL_VOL_MASK, 0x72);
  232211. + snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME,
  232212. + WM8962_SPKOUTR_VOL_MASK, 0x72);
  232213. +
  232214. + snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
  232215. + WM8962_INL_VOL_MASK, 0x3f);
  232216. + snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME,
  232217. + WM8962_INR_VOL_MASK, 0x3f);
  232218. + snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME,
  232219. + WM8962_ADCL_VOL_MASK, 0xd8);
  232220. + snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME,
  232221. + WM8962_ADCR_VOL_MASK, 0xd8);
  232222. + snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_MIXER_VOLUME,
  232223. + WM8962_IN3R_MIXINR_VOL_MASK, 0x7);
  232224. +
  232225. /* Latch volume update bits */
  232226. regmap_update_bits(wm8962->regmap, WM8962_LEFT_INPUT_VOLUME,
  232227. WM8962_IN_VU, WM8962_IN_VU);
  232228. @@ -3752,6 +3787,9 @@
  232229. regcache_cache_only(wm8962->regmap, true);
  232230. + /* The cache-only should be turned on before we power down the codec */
  232231. + regcache_cache_only(wm8962->regmap, true);
  232232. +
  232233. /* The drivers should power up as needed */
  232234. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
  232235. @@ -3760,11 +3798,19 @@
  232236. err_enable:
  232237. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
  232238. err:
  232239. + if (wm8962->pdata.codec_mclk)
  232240. + clk_unprepare(wm8962->pdata.codec_mclk);
  232241. +
  232242. return ret;
  232243. }
  232244. static int wm8962_i2c_remove(struct i2c_client *client)
  232245. {
  232246. + struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
  232247. +
  232248. + if (wm8962->pdata.codec_mclk)
  232249. + clk_unprepare(wm8962->pdata.codec_mclk);
  232250. +
  232251. snd_soc_unregister_codec(&client->dev);
  232252. return 0;
  232253. }
  232254. @@ -3775,6 +3821,9 @@
  232255. struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
  232256. int ret;
  232257. + if (wm8962->pdata.codec_mclk)
  232258. + clk_enable(wm8962->pdata.codec_mclk);
  232259. +
  232260. ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
  232261. wm8962->supplies);
  232262. if (ret != 0) {
  232263. @@ -3834,6 +3883,10 @@
  232264. regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
  232265. wm8962->supplies);
  232266. + if (wm8962->pdata.codec_mclk)
  232267. + clk_disable(wm8962->pdata.codec_mclk);
  232268. +
  232269. +
  232270. return 0;
  232271. }
  232272. #endif
  232273. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_asrc.c linux-imx6-3.14/sound/soc/fsl/fsl_asrc.c
  232274. --- linux-3.14.17/sound/soc/fsl/fsl_asrc.c 1970-01-01 01:00:00.000000000 +0100
  232275. +++ linux-imx6-3.14/sound/soc/fsl/fsl_asrc.c 2014-09-11 18:06:18.690104584 +0200
  232276. @@ -0,0 +1,498 @@
  232277. +/*
  232278. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  232279. + *
  232280. + * The code contained herein is licensed under the GNU General Public
  232281. + * License. You may obtain a copy of the GNU General Public License
  232282. + * Version 2 or later at the following locations:
  232283. + *
  232284. + * http://www.opensource.org/licenses/gpl-license.html
  232285. + * http://www.gnu.org/copyleft/gpl.html
  232286. + */
  232287. +
  232288. +#include <linux/module.h>
  232289. +#include <linux/of.h>
  232290. +#include <linux/of_platform.h>
  232291. +#include <linux/slab.h>
  232292. +#include <linux/device.h>
  232293. +#include <linux/i2c.h>
  232294. +#include <linux/clk.h>
  232295. +#include <linux/delay.h>
  232296. +#include <linux/mxc_asrc.h>
  232297. +#include <sound/core.h>
  232298. +#include <sound/pcm.h>
  232299. +#include <sound/pcm_params.h>
  232300. +#include <sound/soc.h>
  232301. +#include <sound/initval.h>
  232302. +#include <sound/dmaengine_pcm.h>
  232303. +
  232304. +#include "fsl_asrc.h"
  232305. +#include "imx-pcm.h"
  232306. +
  232307. +static bool filter(struct dma_chan *chan, void *param)
  232308. +{
  232309. + if (!imx_dma_is_general_purpose(chan))
  232310. + return false;
  232311. +
  232312. + chan->private = param;
  232313. +
  232314. + return true;
  232315. +}
  232316. +
  232317. +static int asrc_p2p_request_channel(struct snd_pcm_substream *substream)
  232318. +{
  232319. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232320. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  232321. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  232322. + enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  232323. + struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
  232324. + struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
  232325. + struct imx_dma_data *fe_filter_data = NULL;
  232326. + struct imx_dma_data *be_filter_data = NULL;
  232327. +
  232328. + struct dma_slave_config slave_config;
  232329. + dma_cap_mask_t mask;
  232330. + struct dma_chan *chan;
  232331. + int ret;
  232332. + struct snd_soc_dpcm *dpcm;
  232333. +
  232334. + /* find the be for this fe stream */
  232335. + list_for_each_entry(dpcm, &rtd->dpcm[substream->stream].be_clients, list_be) {
  232336. + if (dpcm->fe == rtd) {
  232337. + struct snd_soc_pcm_runtime *be = dpcm->be;
  232338. + struct snd_soc_dai *dai = be->cpu_dai;
  232339. + struct snd_pcm_substream *be_substream;
  232340. + be_substream = snd_soc_dpcm_get_substream(be, substream->stream);
  232341. + dma_params_be = snd_soc_dai_get_dma_data(dai, be_substream);
  232342. + break;
  232343. + }
  232344. + }
  232345. +
  232346. + if (!dma_params_be) {
  232347. + dev_err(rtd->card->dev, "can not get be substream\n");
  232348. + return -EINVAL;
  232349. + }
  232350. +
  232351. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  232352. + dma_params_fe = &asrc_p2p->dma_params_tx;
  232353. + else
  232354. + dma_params_fe = &asrc_p2p->dma_params_rx;
  232355. +
  232356. + fe_filter_data = dma_params_fe->filter_data;
  232357. + be_filter_data = dma_params_be->filter_data;
  232358. +
  232359. + if (asrc_p2p->output_width == 16)
  232360. + buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
  232361. + else
  232362. + buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
  232363. +
  232364. + /* reconfig memory to FIFO dma request */
  232365. + dma_params_fe->addr = asrc_p2p->asrc_ops.asrc_p2p_per_addr(
  232366. + asrc_p2p->asrc_index, 1);
  232367. + fe_filter_data->dma_request0 = asrc_p2p->dmarx[asrc_p2p->asrc_index];
  232368. + dma_params_fe->maxburst = dma_params_be->maxburst;
  232369. +
  232370. + dma_cap_zero(mask);
  232371. + dma_cap_set(DMA_SLAVE, mask);
  232372. + dma_cap_set(DMA_CYCLIC, mask);
  232373. +
  232374. + /* config p2p dma channel */
  232375. + asrc_p2p->asrc_p2p_dma_data.peripheral_type = IMX_DMATYPE_ASRC;
  232376. + asrc_p2p->asrc_p2p_dma_data.priority = DMA_PRIO_HIGH;
  232377. + asrc_p2p->asrc_p2p_dma_data.dma_request1 = asrc_p2p->dmatx[asrc_p2p->asrc_index];
  232378. + /* need to get target device's dma dma_addr, burstsize */
  232379. + asrc_p2p->asrc_p2p_dma_data.dma_request0 = be_filter_data->dma_request0;
  232380. +
  232381. + /* Request channel */
  232382. + asrc_p2p->asrc_p2p_dma_chan =
  232383. + dma_request_channel(mask, filter, &asrc_p2p->asrc_p2p_dma_data);
  232384. +
  232385. + if (!asrc_p2p->asrc_p2p_dma_chan) {
  232386. + dev_err(rtd->card->dev, "can not request dma channel\n");
  232387. + goto error;
  232388. + }
  232389. + chan = asrc_p2p->asrc_p2p_dma_chan;
  232390. +
  232391. + /*
  232392. + * Buswidth is not used in the sdma for p2p. Here we set the maxburst fix to
  232393. + * twice of dma_params's burstsize.
  232394. + */
  232395. + slave_config.direction = DMA_DEV_TO_DEV;
  232396. + slave_config.src_addr = asrc_p2p->asrc_ops.asrc_p2p_per_addr(asrc_p2p->asrc_index, 0);
  232397. + slave_config.src_addr_width = buswidth;
  232398. + slave_config.src_maxburst = dma_params_be->maxburst * 2;
  232399. + slave_config.dst_addr = dma_params_be->addr;
  232400. + slave_config.dst_addr_width = buswidth;
  232401. + slave_config.dst_maxburst = dma_params_be->maxburst * 2;
  232402. + slave_config.dma_request0 = be_filter_data->dma_request0;
  232403. + slave_config.dma_request1 = asrc_p2p->dmatx[asrc_p2p->asrc_index];
  232404. +
  232405. + ret = dmaengine_slave_config(asrc_p2p->asrc_p2p_dma_chan,
  232406. + &slave_config);
  232407. + if (ret) {
  232408. + dev_err(rtd->card->dev, "can not config dma channel\n");
  232409. + goto error;
  232410. + }
  232411. +
  232412. + return 0;
  232413. +error:
  232414. + if (asrc_p2p->asrc_p2p_dma_chan) {
  232415. + dma_release_channel(asrc_p2p->asrc_p2p_dma_chan);
  232416. + asrc_p2p->asrc_p2p_dma_chan = NULL;
  232417. + }
  232418. +
  232419. + return -EINVAL;
  232420. +}
  232421. +
  232422. +static int config_asrc(struct snd_pcm_substream *substream,
  232423. + struct snd_pcm_hw_params *params)
  232424. +{
  232425. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232426. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  232427. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  232428. + unsigned int rate = params_rate(params);
  232429. + unsigned int channel = params_channels(params);
  232430. + struct asrc_config config = {0};
  232431. + int output_word_width = 0;
  232432. + int input_word_width = 0;
  232433. + int ret = 0;
  232434. + if ((channel != 2) && (channel != 4) && (channel != 6)) {
  232435. + dev_err(cpu_dai->dev, "param channel is not correct\n");
  232436. + return -EINVAL;
  232437. + }
  232438. +
  232439. + ret = asrc_p2p->asrc_ops.asrc_p2p_req_pair(channel, &asrc_p2p->asrc_index);
  232440. + if (ret < 0) {
  232441. + dev_err(cpu_dai->dev, "Fail to request asrc pair\n");
  232442. + return -EINVAL;
  232443. + }
  232444. +
  232445. + if (asrc_p2p->output_width == 16)
  232446. + output_word_width = ASRC_WIDTH_16_BIT;
  232447. + else
  232448. + output_word_width = ASRC_WIDTH_24_BIT;
  232449. +
  232450. + switch (params_format(params)) {
  232451. + case SNDRV_PCM_FORMAT_U16:
  232452. + case SNDRV_PCM_FORMAT_S16_LE:
  232453. + case SNDRV_PCM_FORMAT_S16_BE:
  232454. + input_word_width = ASRC_WIDTH_16_BIT;
  232455. + break;
  232456. + case SNDRV_PCM_FORMAT_S20_3LE:
  232457. + case SNDRV_PCM_FORMAT_S20_3BE:
  232458. + case SNDRV_PCM_FORMAT_S24_3LE:
  232459. + case SNDRV_PCM_FORMAT_S24_3BE:
  232460. + case SNDRV_PCM_FORMAT_S24_BE:
  232461. + case SNDRV_PCM_FORMAT_S24_LE:
  232462. + case SNDRV_PCM_FORMAT_U24_BE:
  232463. + case SNDRV_PCM_FORMAT_U24_LE:
  232464. + case SNDRV_PCM_FORMAT_U24_3BE:
  232465. + case SNDRV_PCM_FORMAT_U24_3LE:
  232466. + input_word_width = ASRC_WIDTH_24_BIT;
  232467. + break;
  232468. + case SNDRV_PCM_FORMAT_S8:
  232469. + case SNDRV_PCM_FORMAT_U8:
  232470. + case SNDRV_PCM_FORMAT_S32:
  232471. + case SNDRV_PCM_FORMAT_U32:
  232472. + default:
  232473. + dev_err(cpu_dai->dev, "Format is not support!\n");
  232474. + return -EINVAL;
  232475. + }
  232476. +
  232477. + config.input_word_width = input_word_width;
  232478. + config.output_word_width = output_word_width;
  232479. + config.pair = asrc_p2p->asrc_index;
  232480. + config.channel_num = channel;
  232481. + config.input_sample_rate = rate;
  232482. + config.output_sample_rate = asrc_p2p->output_rate;
  232483. + config.inclk = INCLK_NONE;
  232484. +
  232485. + switch (asrc_p2p->per_dev) {
  232486. + case SSI1:
  232487. + config.outclk = OUTCLK_SSI1_TX;
  232488. + break;
  232489. + case SSI2:
  232490. + config.outclk = OUTCLK_SSI2_TX;
  232491. + break;
  232492. + case SSI3:
  232493. + config.outclk = OUTCLK_SSI3_TX;
  232494. + break;
  232495. + case ESAI:
  232496. + config.outclk = OUTCLK_ESAI_TX;
  232497. + break;
  232498. + default:
  232499. + dev_err(cpu_dai->dev, "peripheral device is not correct\n");
  232500. + return -EINVAL;
  232501. + }
  232502. +
  232503. + ret = asrc_p2p->asrc_ops.asrc_p2p_config_pair(&config);
  232504. + if (ret < 0) {
  232505. + dev_err(cpu_dai->dev, "Fail to config asrc\n");
  232506. + return ret;
  232507. + }
  232508. +
  232509. + return 0;
  232510. +}
  232511. +
  232512. +static int fsl_asrc_p2p_hw_params(struct snd_pcm_substream *substream,
  232513. + struct snd_pcm_hw_params *params,
  232514. + struct snd_soc_dai *cpu_dai)
  232515. +{
  232516. + int ret = 0;
  232517. +
  232518. + ret = config_asrc(substream, params);
  232519. + if (ret < 0)
  232520. + return ret;
  232521. +
  232522. + return asrc_p2p_request_channel(substream);
  232523. +}
  232524. +
  232525. +static int fsl_asrc_p2p_hw_free(struct snd_pcm_substream *substream,
  232526. + struct snd_soc_dai *cpu_dai)
  232527. +{
  232528. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  232529. +
  232530. + if (asrc_p2p->asrc_p2p_dma_chan) {
  232531. + /* Release p2p dma resource */
  232532. + dma_release_channel(asrc_p2p->asrc_p2p_dma_chan);
  232533. + asrc_p2p->asrc_p2p_dma_chan = NULL;
  232534. + }
  232535. +
  232536. + if (asrc_p2p->asrc_index != -1) {
  232537. + asrc_p2p->asrc_ops.asrc_p2p_release_pair(asrc_p2p->asrc_index);
  232538. + asrc_p2p->asrc_ops.asrc_p2p_finish_conv(asrc_p2p->asrc_index);
  232539. + }
  232540. + asrc_p2p->asrc_index = -1;
  232541. +
  232542. + return 0;
  232543. +}
  232544. +
  232545. +static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream,
  232546. + struct fsl_asrc_p2p *asrc_p2p)
  232547. +{
  232548. + struct dma_async_tx_descriptor *desc = asrc_p2p->asrc_p2p_desc;
  232549. + struct dma_chan *chan = asrc_p2p->asrc_p2p_dma_chan;
  232550. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  232551. + struct device *dev = rtd->platform->dev;
  232552. +
  232553. + desc = dmaengine_prep_dma_cyclic(chan, 0xffff, 64, 64, DMA_DEV_TO_DEV, 0);
  232554. + if (!desc) {
  232555. + dev_err(dev, "failed to prepare slave dma\n");
  232556. + return -EINVAL;
  232557. + }
  232558. +
  232559. + dmaengine_submit(desc);
  232560. +
  232561. + return 0;
  232562. +}
  232563. +
  232564. +static int fsl_asrc_p2p_trigger(struct snd_pcm_substream *substream, int cmd,
  232565. + struct snd_soc_dai *cpu_dai)
  232566. +{
  232567. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(cpu_dai);
  232568. + int ret;
  232569. +
  232570. + switch (cmd) {
  232571. + case SNDRV_PCM_TRIGGER_START:
  232572. + case SNDRV_PCM_TRIGGER_RESUME:
  232573. + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  232574. + ret = fsl_asrc_dma_prepare_and_submit(substream, asrc_p2p);
  232575. + if (ret)
  232576. + return ret;
  232577. + dma_async_issue_pending(asrc_p2p->asrc_p2p_dma_chan);
  232578. + asrc_p2p->asrc_ops.asrc_p2p_start_conv(asrc_p2p->asrc_index);
  232579. + break;
  232580. + case SNDRV_PCM_TRIGGER_SUSPEND:
  232581. + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  232582. + case SNDRV_PCM_TRIGGER_STOP:
  232583. + dmaengine_terminate_all(asrc_p2p->asrc_p2p_dma_chan);
  232584. + asrc_p2p->asrc_ops.asrc_p2p_stop_conv(asrc_p2p->asrc_index);
  232585. + break;
  232586. + default:
  232587. + return -EINVAL;
  232588. + }
  232589. +
  232590. + return 0;
  232591. +}
  232592. +
  232593. +#define IMX_ASRC_RATES SNDRV_PCM_RATE_8000_192000
  232594. +
  232595. +#define IMX_ASRC_FORMATS \
  232596. + (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE | \
  232597. + SNDRV_PCM_FORMAT_S20_3LE)
  232598. +
  232599. +static struct snd_soc_dai_ops fsl_asrc_p2p_dai_ops = {
  232600. + .trigger = fsl_asrc_p2p_trigger,
  232601. + .hw_params = fsl_asrc_p2p_hw_params,
  232602. + .hw_free = fsl_asrc_p2p_hw_free,
  232603. +};
  232604. +
  232605. +static int fsl_asrc_p2p_dai_probe(struct snd_soc_dai *dai)
  232606. +{
  232607. + struct fsl_asrc_p2p *asrc_p2p = snd_soc_dai_get_drvdata(dai);
  232608. +
  232609. + dai->playback_dma_data = &asrc_p2p->dma_params_tx;
  232610. + dai->capture_dma_data = &asrc_p2p->dma_params_rx;
  232611. +
  232612. + return 0;
  232613. +}
  232614. +
  232615. +static struct snd_soc_dai_driver fsl_asrc_p2p_dai = {
  232616. + .probe = fsl_asrc_p2p_dai_probe,
  232617. + .playback = {
  232618. + .stream_name = "asrc-Playback",
  232619. + .channels_min = 1,
  232620. + .channels_max = 10,
  232621. + .rates = IMX_ASRC_RATES,
  232622. + .formats = IMX_ASRC_FORMATS,
  232623. + },
  232624. + .capture = {
  232625. + .stream_name = "asrc-Capture",
  232626. + .channels_min = 1,
  232627. + .channels_max = 4,
  232628. + .rates = IMX_ASRC_RATES,
  232629. + .formats = IMX_ASRC_FORMATS,
  232630. + },
  232631. + .ops = &fsl_asrc_p2p_dai_ops,
  232632. +};
  232633. +
  232634. +static const struct snd_soc_component_driver fsl_asrc_p2p_component = {
  232635. + .name = "fsl-asrc-p2p",
  232636. +};
  232637. +
  232638. +/*
  232639. + * This function will register the snd_soc_pcm_link drivers.
  232640. + */
  232641. +static int fsl_asrc_p2p_probe(struct platform_device *pdev)
  232642. +{
  232643. + struct fsl_asrc_p2p *asrc_p2p;
  232644. + struct device_node *np = pdev->dev.of_node;
  232645. + const char *p;
  232646. + const uint32_t *iprop_rate, *iprop_width;
  232647. + int ret = 0;
  232648. +
  232649. + if (!of_device_is_available(np)) {
  232650. + dev_err(&pdev->dev, "There is no device node\n");
  232651. + return -ENODEV;
  232652. + }
  232653. +
  232654. + asrc_p2p = devm_kzalloc(&pdev->dev, sizeof(struct fsl_asrc_p2p), GFP_KERNEL);
  232655. + if (!asrc_p2p) {
  232656. + dev_err(&pdev->dev, "can not alloc memory\n");
  232657. + return -ENOMEM;
  232658. + }
  232659. + asrc_p2p->asrc_ops.asrc_p2p_start_conv = asrc_start_conv;
  232660. + asrc_p2p->asrc_ops.asrc_p2p_stop_conv = asrc_stop_conv;
  232661. + asrc_p2p->asrc_ops.asrc_p2p_per_addr = asrc_get_per_addr;
  232662. + asrc_p2p->asrc_ops.asrc_p2p_req_pair = asrc_req_pair;
  232663. + asrc_p2p->asrc_ops.asrc_p2p_config_pair = asrc_config_pair;
  232664. + asrc_p2p->asrc_ops.asrc_p2p_release_pair = asrc_release_pair;
  232665. + asrc_p2p->asrc_ops.asrc_p2p_finish_conv = asrc_finish_conv;
  232666. +
  232667. + asrc_p2p->asrc_index = -1;
  232668. +
  232669. + iprop_rate = of_get_property(np, "fsl,output-rate", NULL);
  232670. + if (iprop_rate)
  232671. + asrc_p2p->output_rate = be32_to_cpup(iprop_rate);
  232672. + else {
  232673. + dev_err(&pdev->dev, "There is no output-rate in dts\n");
  232674. + return -EINVAL;
  232675. + }
  232676. + iprop_width = of_get_property(np, "fsl,output-width", NULL);
  232677. + if (iprop_width)
  232678. + asrc_p2p->output_width = be32_to_cpup(iprop_width);
  232679. +
  232680. + if (asrc_p2p->output_width != 16 && asrc_p2p->output_width != 24) {
  232681. + dev_err(&pdev->dev, "output_width is not acceptable\n");
  232682. + return -EINVAL;
  232683. + }
  232684. +
  232685. + ret = of_property_read_u32_array(np,
  232686. + "fsl,asrc-dma-tx-events", asrc_p2p->dmatx, 3);
  232687. + if (ret) {
  232688. + dev_err(&pdev->dev, "Failed to get fsl,asrc-dma-tx-events.\n");
  232689. + return -EINVAL;
  232690. + }
  232691. +
  232692. + ret = of_property_read_u32_array(np,
  232693. + "fsl,asrc-dma-rx-events", asrc_p2p->dmarx, 3);
  232694. + if (ret) {
  232695. + dev_err(&pdev->dev, "Failed to get fsl,asrc-dma-rx-events.\n");
  232696. + return -EINVAL;
  232697. + }
  232698. +
  232699. + asrc_p2p->filter_data_tx.peripheral_type = IMX_DMATYPE_ASRC;
  232700. + asrc_p2p->filter_data_rx.peripheral_type = IMX_DMATYPE_ASRC;
  232701. +
  232702. + asrc_p2p->dma_params_tx.filter_data = &asrc_p2p->filter_data_tx;
  232703. + asrc_p2p->dma_params_rx.filter_data = &asrc_p2p->filter_data_rx;
  232704. +
  232705. + platform_set_drvdata(pdev, asrc_p2p);
  232706. +
  232707. + p = strrchr(np->full_name, '/') + 1;
  232708. + strcpy(asrc_p2p->name, p);
  232709. + fsl_asrc_p2p_dai.name = asrc_p2p->name;
  232710. +
  232711. + ret = snd_soc_register_component(&pdev->dev, &fsl_asrc_p2p_component,
  232712. + &fsl_asrc_p2p_dai, 1);
  232713. + if (ret) {
  232714. + dev_err(&pdev->dev, "register DAI failed\n");
  232715. + goto failed_register;
  232716. + }
  232717. +
  232718. + asrc_p2p->soc_platform_pdev = platform_device_register_simple(
  232719. + "imx-pcm-asrc", -1, NULL, 0);
  232720. + if (IS_ERR(asrc_p2p->soc_platform_pdev)) {
  232721. + ret = PTR_ERR(asrc_p2p->soc_platform_pdev);
  232722. + goto failed_pdev_alloc;
  232723. + }
  232724. +
  232725. + ret = imx_pcm_dma_init(asrc_p2p->soc_platform_pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
  232726. + SND_DMAENGINE_PCM_FLAG_NO_DT |
  232727. + SND_DMAENGINE_PCM_FLAG_COMPAT,
  232728. + IMX_ASRC_DMABUF_SIZE);
  232729. + if (ret) {
  232730. + dev_err(&pdev->dev, "init pcm dma failed\n");
  232731. + goto failed_pcm_init;
  232732. + }
  232733. +
  232734. + return 0;
  232735. +
  232736. +failed_pcm_init:
  232737. + platform_device_unregister(asrc_p2p->soc_platform_pdev);
  232738. +failed_pdev_alloc:
  232739. + snd_soc_unregister_component(&pdev->dev);
  232740. +failed_register:
  232741. +
  232742. + return ret;
  232743. +}
  232744. +
  232745. +static int fsl_asrc_p2p_remove(struct platform_device *pdev)
  232746. +{
  232747. + struct fsl_asrc_p2p *asrc_p2p = platform_get_drvdata(pdev);
  232748. +
  232749. + platform_device_unregister(asrc_p2p->soc_platform_pdev);
  232750. + snd_soc_unregister_component(&pdev->dev);
  232751. +
  232752. + return 0;
  232753. +}
  232754. +
  232755. +static const struct of_device_id fsl_asrc_p2p_dt_ids[] = {
  232756. + { .compatible = "fsl,imx6q-asrc-p2p", },
  232757. + { /* sentinel */ }
  232758. +};
  232759. +
  232760. +static struct platform_driver fsl_asrc_p2p_driver = {
  232761. + .probe = fsl_asrc_p2p_probe,
  232762. + .remove = fsl_asrc_p2p_remove,
  232763. + .driver = {
  232764. + .name = "fsl-asrc-p2p",
  232765. + .owner = THIS_MODULE,
  232766. + .of_match_table = fsl_asrc_p2p_dt_ids,
  232767. + },
  232768. +};
  232769. +module_platform_driver(fsl_asrc_p2p_driver);
  232770. +
  232771. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  232772. +MODULE_DESCRIPTION("i.MX ASoC ASRC P2P driver");
  232773. +MODULE_ALIAS("platform:fsl-asrc-p2p");
  232774. +MODULE_LICENSE("GPL");
  232775. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_asrc.h linux-imx6-3.14/sound/soc/fsl/fsl_asrc.h
  232776. --- linux-3.14.17/sound/soc/fsl/fsl_asrc.h 1970-01-01 01:00:00.000000000 +0100
  232777. +++ linux-imx6-3.14/sound/soc/fsl/fsl_asrc.h 2014-09-11 18:06:18.690104584 +0200
  232778. @@ -0,0 +1,48 @@
  232779. +/*
  232780. + * fsl_asrc.h - ALSA ASRC interface
  232781. + *
  232782. + * Copyright (C) 2013 Freescale Semiconductor, Inc. This file is licensed
  232783. + * under the terms of the GNU General Public License version 2. This
  232784. + * program is licensed "as is" without any warranty of any kind, whether
  232785. + * express or implied.
  232786. + */
  232787. +
  232788. +#ifndef _FSL_ASRC_P2P_H
  232789. +#define _FSL_ASRC_P2P_H
  232790. +
  232791. +#include <linux/mxc_asrc.h>
  232792. +#include <sound/dmaengine_pcm.h>
  232793. +#include <linux/platform_data/dma-imx.h>
  232794. +
  232795. +enum peripheral_device_type {
  232796. + UNKNOWN,
  232797. + SSI1,
  232798. + SSI2,
  232799. + SSI3,
  232800. + ESAI,
  232801. +};
  232802. +
  232803. +struct fsl_asrc_p2p {
  232804. + int output_rate;
  232805. + int output_width;
  232806. + enum asrc_pair_index asrc_index;
  232807. + enum peripheral_device_type per_dev;
  232808. + struct asrc_p2p_ops asrc_ops;
  232809. +
  232810. + struct snd_dmaengine_dai_dma_data dma_params_rx;
  232811. + struct snd_dmaengine_dai_dma_data dma_params_tx;
  232812. + struct imx_dma_data filter_data_tx;
  232813. + struct imx_dma_data filter_data_rx;
  232814. +
  232815. + struct dma_async_tx_descriptor *asrc_p2p_desc;
  232816. + struct dma_chan *asrc_p2p_dma_chan;
  232817. + struct imx_dma_data asrc_p2p_dma_data;
  232818. + struct platform_device *soc_platform_pdev;
  232819. +
  232820. + int dmarx[3];
  232821. + int dmatx[3];
  232822. +
  232823. + char name[32];
  232824. +};
  232825. +
  232826. +#endif
  232827. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_asrc_pcm.c linux-imx6-3.14/sound/soc/fsl/fsl_asrc_pcm.c
  232828. --- linux-3.14.17/sound/soc/fsl/fsl_asrc_pcm.c 1970-01-01 01:00:00.000000000 +0100
  232829. +++ linux-imx6-3.14/sound/soc/fsl/fsl_asrc_pcm.c 2014-09-11 18:06:18.690104584 +0200
  232830. @@ -0,0 +1,41 @@
  232831. +/*
  232832. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
  232833. + *
  232834. + * The code contained herein is licensed under the GNU General Public
  232835. + * License. You may obtain a copy of the GNU General Public License
  232836. + * Version 2 or later at the following locations:
  232837. + *
  232838. + * http://www.opensource.org/licenses/gpl-license.html
  232839. + * http://www.gnu.org/copyleft/gpl.html
  232840. + */
  232841. +
  232842. +#include <linux/module.h>
  232843. +#include <linux/platform_device.h>
  232844. +
  232845. +
  232846. +/*
  232847. + * Here add one platform module "imx-pcm-asrc" as pcm platform module.
  232848. + * If we use the asrc_p2p node as the pcm platform, there will be one issue.
  232849. + * snd_soc_dapm_new_dai_widgets will be called twice, one in probe link_dais,
  232850. + * one in probe platform. so there will be two dai_widgets added to widget list.
  232851. + * but only the seconed one will be recorded in dai->playback_widget.
  232852. + * Machine driver will add the audio route, but when it go through the
  232853. + * widget list, it will found the cpu_dai widget is the first one in the list.
  232854. + * add use the first one to link the audio route.
  232855. + * when use the fe/be architecture for asrc p2p, it need to go through from
  232856. + * the fe->cpu_dai->playback_widget. but this is the second widget, so the
  232857. + * result is that it can't find a availble audio route for p2p case. So here
  232858. + * use another pcm platform to avoid this issue.
  232859. + */
  232860. +static struct platform_driver imx_pcm_driver = {
  232861. + .driver = {
  232862. + .name = "imx-pcm-asrc",
  232863. + .owner = THIS_MODULE,
  232864. + },
  232865. +};
  232866. +
  232867. +module_platform_driver(imx_pcm_driver);
  232868. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  232869. +MODULE_DESCRIPTION("i.MX ASoC PCM driver");
  232870. +MODULE_ALIAS("platform:imx-pcm-asrc");
  232871. +MODULE_LICENSE("GPL");
  232872. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_esai.c linux-imx6-3.14/sound/soc/fsl/fsl_esai.c
  232873. --- linux-3.14.17/sound/soc/fsl/fsl_esai.c 2014-08-14 03:38:34.000000000 +0200
  232874. +++ linux-imx6-3.14/sound/soc/fsl/fsl_esai.c 2014-09-11 18:06:18.690104584 +0200
  232875. @@ -785,7 +785,7 @@
  232876. return ret;
  232877. }
  232878. - ret = imx_pcm_dma_init(pdev);
  232879. + ret = imx_pcm_dma_init(pdev, NULL, IMX_ESAI_DMABUF_SIZE);
  232880. if (ret)
  232881. dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
  232882. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_hdmi.c linux-imx6-3.14/sound/soc/fsl/fsl_hdmi.c
  232883. --- linux-3.14.17/sound/soc/fsl/fsl_hdmi.c 1970-01-01 01:00:00.000000000 +0100
  232884. +++ linux-imx6-3.14/sound/soc/fsl/fsl_hdmi.c 2014-09-11 18:06:18.690104584 +0200
  232885. @@ -0,0 +1,614 @@
  232886. +/*
  232887. + * ALSA SoC HDMI Audio Layer for Freescale i.MX
  232888. + *
  232889. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  232890. + *
  232891. + * Some code from patch_hdmi.c
  232892. + * Copyright (c) 2008-2010 Intel Corporation. All rights reserved.
  232893. + * Copyright (c) 2006 ATI Technologies Inc.
  232894. + * Copyright (c) 2008 NVIDIA Corp. All rights reserved.
  232895. + * Copyright (c) 2008 Wei Ni <wni@nvidia.com>
  232896. + *
  232897. + * This program is free software; you can redistribute it and/or modify
  232898. + * it under the terms of the GNU General Public License as published by
  232899. + * the Free Software Foundation; either version 2 of the License, or
  232900. + * (at your option) any later version.
  232901. + *
  232902. + * This program is distributed in the hope that it will be useful,
  232903. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  232904. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  232905. + * GNU General Public License for more details.
  232906. + *
  232907. + * You should have received a copy of the GNU General Public License along
  232908. + * with this program; if not, write to the Free Software Foundation, Inc.,
  232909. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  232910. + */
  232911. +
  232912. +#include <linux/init.h>
  232913. +#include <linux/module.h>
  232914. +#include <linux/dma-mapping.h>
  232915. +#include <linux/slab.h>
  232916. +#include <linux/clk.h>
  232917. +#include <linux/delay.h>
  232918. +#include <linux/mfd/mxc-hdmi-core.h>
  232919. +#include <sound/pcm.h>
  232920. +#include <sound/soc.h>
  232921. +#include <sound/asoundef.h>
  232922. +
  232923. +#include <video/mxc_hdmi.h>
  232924. +
  232925. +#include "imx-hdmi.h"
  232926. +
  232927. +
  232928. +static struct mxc_edid_cfg edid_cfg;
  232929. +
  232930. +static u32 playback_rates[HDMI_MAX_RATES];
  232931. +static u32 playback_sample_size[HDMI_MAX_SAMPLE_SIZE];
  232932. +static u32 playback_channels[HDMI_MAX_CHANNEL_CONSTRAINTS];
  232933. +
  232934. +static struct snd_pcm_hw_constraint_list playback_constraint_rates;
  232935. +static struct snd_pcm_hw_constraint_list playback_constraint_bits;
  232936. +static struct snd_pcm_hw_constraint_list playback_constraint_channels;
  232937. +
  232938. +#ifdef DEBUG
  232939. +static void dumpregs(struct snd_soc_dai *dai)
  232940. +{
  232941. + u32 n, cts;
  232942. +
  232943. + cts = (hdmi_readb(HDMI_AUD_CTS3) << 16) |
  232944. + (hdmi_readb(HDMI_AUD_CTS2) << 8) |
  232945. + hdmi_readb(HDMI_AUD_CTS1);
  232946. +
  232947. + n = (hdmi_readb(HDMI_AUD_N3) << 16) |
  232948. + (hdmi_readb(HDMI_AUD_N2) << 8) |
  232949. + hdmi_readb(HDMI_AUD_N1);
  232950. +
  232951. + dev_dbg(dai->dev, "HDMI_PHY_CONF0 0x%02x\n",
  232952. + hdmi_readb(HDMI_PHY_CONF0));
  232953. + dev_dbg(dai->dev, "HDMI_MC_CLKDIS 0x%02x\n",
  232954. + hdmi_readb(HDMI_MC_CLKDIS));
  232955. + dev_dbg(dai->dev, "HDMI_AUD_N[1-3] 0x%06x (%d)\n",
  232956. + n, n);
  232957. + dev_dbg(dai->dev, "HDMI_AUD_CTS[1-3] 0x%06x (%d)\n",
  232958. + cts, cts);
  232959. + dev_dbg(dai->dev, "HDMI_FC_AUDSCONF 0x%02x\n",
  232960. + hdmi_readb(HDMI_FC_AUDSCONF));
  232961. +}
  232962. +#else
  232963. +static void dumpregs(struct snd_soc_dai *dai) {}
  232964. +#endif
  232965. +
  232966. +enum cea_speaker_placement {
  232967. + FL = (1 << 0), /* Front Left */
  232968. + FC = (1 << 1), /* Front Center */
  232969. + FR = (1 << 2), /* Front Right */
  232970. + FLC = (1 << 3), /* Front Left Center */
  232971. + FRC = (1 << 4), /* Front Right Center */
  232972. + RL = (1 << 5), /* Rear Left */
  232973. + RC = (1 << 6), /* Rear Center */
  232974. + RR = (1 << 7), /* Rear Right */
  232975. + RLC = (1 << 8), /* Rear Left Center */
  232976. + RRC = (1 << 9), /* Rear Right Center */
  232977. + LFE = (1 << 10), /* Low Frequency Effect */
  232978. + FLW = (1 << 11), /* Front Left Wide */
  232979. + FRW = (1 << 12), /* Front Right Wide */
  232980. + FLH = (1 << 13), /* Front Left High */
  232981. + FCH = (1 << 14), /* Front Center High */
  232982. + FRH = (1 << 15), /* Front Right High */
  232983. + TC = (1 << 16), /* Top Center */
  232984. +};
  232985. +
  232986. +/*
  232987. + * EDID SA bits in the CEA Speaker Allocation data block
  232988. + */
  232989. +static int edid_speaker_allocation_bits[] = {
  232990. + [0] = FL | FR,
  232991. + [1] = LFE,
  232992. + [2] = FC,
  232993. + [3] = RL | RR,
  232994. + [4] = RC,
  232995. + [5] = FLC | FRC,
  232996. + [6] = RLC | RRC,
  232997. + [7] = FLW | FRW,
  232998. + [8] = FLH | FRH,
  232999. + [9] = TC,
  233000. + [10] = FCH,
  233001. +};
  233002. +
  233003. +struct cea_channel_speaker_allocation {
  233004. + int ca_index;
  233005. + int speakers[8];
  233006. +
  233007. + /* Derived values, just for convenience */
  233008. + int channels;
  233009. + int spk_mask;
  233010. +};
  233011. +
  233012. +/*
  233013. + * This is an ordered list!
  233014. + *
  233015. + * The preceding ones have better chances to be selected by
  233016. + * hdmi_channel_allocation().
  233017. + */
  233018. +static struct cea_channel_speaker_allocation channel_allocations[] = {
  233019. + /* channel: 7 6 5 4 3 2 1 0 */
  233020. + { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL },},
  233021. + /* 2.1 */
  233022. + { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL },},
  233023. + /* Dolby Surround */
  233024. + { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL },}, /* Prefer FL/FR/RL/RR over FL/FR/LFE/FC */
  233025. + { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL },},
  233026. + { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL },},
  233027. + { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL },},
  233028. + { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL },},
  233029. + { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL },},
  233030. + { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL },},
  233031. + { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL },},
  233032. + { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL },},
  233033. + /* surround51 */
  233034. + { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL },},
  233035. + { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL },},
  233036. + { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL },},
  233037. + { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL },},
  233038. + /* 6.1 */
  233039. + { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL },},
  233040. + { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL },},
  233041. + { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL },},
  233042. + { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL },},
  233043. + /* surround71 */
  233044. + { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL },},
  233045. + { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL },},
  233046. + { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL },},
  233047. + { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL },},
  233048. + { .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL },},
  233049. + { .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL },},
  233050. + { .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL },},
  233051. + { .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL },},
  233052. + { .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL },},
  233053. + { .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL },},
  233054. + { .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL },},
  233055. + { .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL },},
  233056. + { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL },},
  233057. + { .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL },},
  233058. + { .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL },},
  233059. + { .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL },},
  233060. + { .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL },},
  233061. + { .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL },},
  233062. + { .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL },},
  233063. + { .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL },},
  233064. + { .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL },},
  233065. + { .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL },},
  233066. + { .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL },},
  233067. + { .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL },},
  233068. + { .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL },},
  233069. + { .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL },},
  233070. + { .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL },},
  233071. + { .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL },},
  233072. + { .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL },},
  233073. + { .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL },},
  233074. + { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL },},
  233075. +};
  233076. +
  233077. +/* Compute derived values in channel_allocations[] */
  233078. +static void init_channel_allocations(void)
  233079. +{
  233080. + struct cea_channel_speaker_allocation *p;
  233081. + int i, j;
  233082. +
  233083. + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  233084. + p = channel_allocations + i;
  233085. + p->channels = 0;
  233086. + p->spk_mask = 0;
  233087. + for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
  233088. + if (p->speakers[j]) {
  233089. + p->channels++;
  233090. + p->spk_mask |= p->speakers[j];
  233091. + }
  233092. + }
  233093. +}
  233094. +
  233095. +/*
  233096. + * The transformation takes two steps:
  233097. + *
  233098. + * speaker_alloc => (edid_speaker_allocation_bits[]) => spk_mask
  233099. + * spk_mask => (channel_allocations[]) => CA
  233100. + *
  233101. + * TODO: it could select the wrong CA from multiple candidates.
  233102. +*/
  233103. +static int hdmi_channel_allocation(int channels)
  233104. +{
  233105. + int spk_mask = 0, ca = 0, i, tmpchn, tmpspk;
  233106. +
  233107. + /* CA defaults to 0 for basic stereo audio */
  233108. + if (channels <= 2)
  233109. + return 0;
  233110. +
  233111. + /*
  233112. + * Expand EDID's speaker allocation mask
  233113. + *
  233114. + * EDID tells the speaker mask in a compact(paired) form,
  233115. + * expand EDID's notions to match the ones used by Audio InfoFrame.
  233116. + */
  233117. + for (i = 0; i < ARRAY_SIZE(edid_speaker_allocation_bits); i++) {
  233118. + if (edid_cfg.speaker_alloc & (1 << i))
  233119. + spk_mask |= edid_speaker_allocation_bits[i];
  233120. + }
  233121. +
  233122. + /* Search for the first working match in the CA table */
  233123. + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
  233124. + tmpchn = channel_allocations[i].channels;
  233125. + tmpspk = channel_allocations[i].spk_mask;
  233126. +
  233127. + if (channels == tmpchn && (spk_mask & tmpspk) == tmpspk) {
  233128. + ca = channel_allocations[i].ca_index;
  233129. + break;
  233130. + }
  233131. + }
  233132. +
  233133. + return ca;
  233134. +}
  233135. +
  233136. +static void hdmi_set_audio_infoframe(unsigned int channels)
  233137. +{
  233138. + u8 audiconf0, audiconf2;
  233139. +
  233140. + /*
  233141. + * From CEA-861-D spec:
  233142. + * HDMI requires the CT, SS and SF fields to be set to 0 ("Refer
  233143. + * to Stream Header") as these items are carried in the audio stream.
  233144. + *
  233145. + * So we only set the CC and CA fields.
  233146. + */
  233147. + audiconf0 = ((channels - 1) << HDMI_FC_AUDICONF0_CC_OFFSET) &
  233148. + HDMI_FC_AUDICONF0_CC_MASK;
  233149. +
  233150. + audiconf2 = hdmi_channel_allocation(channels);
  233151. +
  233152. + hdmi_writeb(audiconf0, HDMI_FC_AUDICONF0);
  233153. + hdmi_writeb(0, HDMI_FC_AUDICONF1);
  233154. + hdmi_writeb(audiconf2, HDMI_FC_AUDICONF2);
  233155. + hdmi_writeb(0, HDMI_FC_AUDICONF3);
  233156. +}
  233157. +
  233158. +static int cea_audio_rates[HDMI_MAX_RATES] = {
  233159. + 32000, 44100, 48000, 88200, 96000, 176400, 192000,
  233160. +};
  233161. +
  233162. +static void fsl_hdmi_get_playback_rates(void)
  233163. +{
  233164. + int i, count = 0;
  233165. + u8 rates;
  233166. +
  233167. + /* Always assume basic audio support */
  233168. + rates = edid_cfg.sample_rates | 0x7;
  233169. +
  233170. + for (i = 0 ; i < HDMI_MAX_RATES ; i++)
  233171. + if ((rates & (1 << i)) != 0)
  233172. + playback_rates[count++] = cea_audio_rates[i];
  233173. +
  233174. + playback_constraint_rates.list = playback_rates;
  233175. + playback_constraint_rates.count = count;
  233176. +
  233177. + for (i = 0 ; i < playback_constraint_rates.count ; i++)
  233178. + pr_debug("%s: constraint = %d Hz\n", __func__, playback_rates[i]);
  233179. +}
  233180. +
  233181. +static void fsl_hdmi_get_playback_sample_size(void)
  233182. +{
  233183. + int i = 0;
  233184. +
  233185. + /* Always assume basic audio support */
  233186. + playback_sample_size[i++] = 16;
  233187. +
  233188. + if (edid_cfg.sample_sizes & 0x4)
  233189. + playback_sample_size[i++] = 32;
  233190. +
  233191. + playback_constraint_bits.list = playback_sample_size;
  233192. + playback_constraint_bits.count = i;
  233193. +
  233194. + for (i = 0 ; i < playback_constraint_bits.count ; i++)
  233195. + pr_debug("%s: constraint = %d bits\n", __func__, playback_sample_size[i]);
  233196. +}
  233197. +
  233198. +static void fsl_hdmi_get_playback_channels(void)
  233199. +{
  233200. + int channels = 2, i = 0;
  233201. +
  233202. + /* Always assume basic audio support */
  233203. + playback_channels[i++] = channels;
  233204. + channels += 2;
  233205. +
  233206. + while ((i < HDMI_MAX_CHANNEL_CONSTRAINTS) &&
  233207. + (channels <= edid_cfg.max_channels)) {
  233208. + playback_channels[i++] = channels;
  233209. + channels += 2;
  233210. + }
  233211. +
  233212. + playback_constraint_channels.list = playback_channels;
  233213. + playback_constraint_channels.count = i;
  233214. +
  233215. + for (i = 0 ; i < playback_constraint_channels.count ; i++)
  233216. + pr_debug("%s: constraint = %d channels\n", __func__, playback_channels[i]);
  233217. +}
  233218. +
  233219. +static int fsl_hdmi_update_constraints(struct snd_pcm_substream *substream)
  233220. +{
  233221. + struct snd_pcm_runtime *runtime = substream->runtime;
  233222. + int edid_status, ret;
  233223. +
  233224. + edid_status = hdmi_get_edid_cfg(&edid_cfg);
  233225. +
  233226. + if (edid_status && !edid_cfg.hdmi_cap)
  233227. + return -1;
  233228. +
  233229. + fsl_hdmi_get_playback_rates();
  233230. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  233231. + &playback_constraint_rates);
  233232. + if (ret)
  233233. + return ret;
  233234. +
  233235. + fsl_hdmi_get_playback_sample_size();
  233236. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
  233237. + &playback_constraint_bits);
  233238. + if (ret)
  233239. + return ret;
  233240. +
  233241. + fsl_hdmi_get_playback_channels();
  233242. + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
  233243. + &playback_constraint_channels);
  233244. + if (ret)
  233245. + return ret;
  233246. +
  233247. + ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
  233248. + if (ret)
  233249. + return ret;
  233250. +
  233251. + return 0;
  233252. +}
  233253. +
  233254. +static int fsl_hdmi_soc_startup(struct snd_pcm_substream *substream,
  233255. + struct snd_soc_dai *dai)
  233256. +{
  233257. + struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
  233258. + int ret;
  233259. +
  233260. + ret = fsl_hdmi_update_constraints(substream);
  233261. + if (ret < 0)
  233262. + return ret;
  233263. +
  233264. + clk_prepare_enable(hdmi_data->isfr_clk);
  233265. + clk_prepare_enable(hdmi_data->iahb_clk);
  233266. +
  233267. + dev_dbg(dai->dev, "%s hdmi clks: isfr:%d iahb:%d\n", __func__,
  233268. + (int)clk_get_rate(hdmi_data->isfr_clk),
  233269. + (int)clk_get_rate(hdmi_data->iahb_clk));
  233270. +
  233271. + /* Indicates the subpacket represents a flatline sample */
  233272. + hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_SAMPFIT, 0x0);
  233273. +
  233274. + return 0;
  233275. +}
  233276. +
  233277. +static void fsl_hdmi_soc_shutdown(struct snd_pcm_substream *substream,
  233278. + struct snd_soc_dai *dai)
  233279. +{
  233280. + struct imx_hdmi *hdmi_data = snd_soc_dai_get_drvdata(dai);
  233281. +
  233282. + clk_disable_unprepare(hdmi_data->iahb_clk);
  233283. + clk_disable_unprepare(hdmi_data->isfr_clk);
  233284. +}
  233285. +
  233286. +static int fsl_hdmi_soc_prepare(struct snd_pcm_substream *substream,
  233287. + struct snd_soc_dai *dai)
  233288. +{
  233289. + struct snd_pcm_runtime *runtime = substream->runtime;
  233290. +
  233291. + hdmi_set_audio_infoframe(runtime->channels);
  233292. + hdmi_audio_writeb(FC_AUDSCONF, AUD_PACKET_LAYOUT,
  233293. + (runtime->channels > 2) ? 0x1 : 0x0);
  233294. + hdmi_set_sample_rate(runtime->rate);
  233295. + dumpregs(dai);
  233296. +
  233297. + return 0;
  233298. +}
  233299. +
  233300. +static struct snd_soc_dai_ops fsl_hdmi_soc_dai_ops = {
  233301. + .startup = fsl_hdmi_soc_startup,
  233302. + .shutdown = fsl_hdmi_soc_shutdown,
  233303. + .prepare = fsl_hdmi_soc_prepare,
  233304. +};
  233305. +
  233306. +/* IEC60958 status functions */
  233307. +static int fsl_hdmi_iec_info(struct snd_kcontrol *kcontrol,
  233308. + struct snd_ctl_elem_info *uinfo)
  233309. +{
  233310. + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
  233311. + uinfo->count = 1;
  233312. +
  233313. + return 0;
  233314. +}
  233315. +
  233316. +
  233317. +static int fsl_hdmi_iec_get(struct snd_kcontrol *kcontrol,
  233318. + struct snd_ctl_elem_value *uvalue)
  233319. +{
  233320. + int i;
  233321. +
  233322. + for (i = 0 ; i < 6 ; i++)
  233323. + uvalue->value.iec958.status[i] = iec_header.status[i];
  233324. +
  233325. + return 0;
  233326. +}
  233327. +
  233328. +static int fsl_hdmi_iec_put(struct snd_kcontrol *kcontrol,
  233329. + struct snd_ctl_elem_value *uvalue)
  233330. +{
  233331. + int i;
  233332. +
  233333. + /* Do not allow professional mode */
  233334. + if (uvalue->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL)
  233335. + return -EPERM;
  233336. +
  233337. + for (i = 0 ; i < 6 ; i++) {
  233338. + iec_header.status[i] = uvalue->value.iec958.status[i];
  233339. + pr_debug("%s status[%d]=0x%02x\n", __func__, i, iec_header.status[i]);
  233340. + }
  233341. +
  233342. + return 0;
  233343. +}
  233344. +
  233345. +static struct snd_kcontrol_new fsl_hdmi_ctrls[] = {
  233346. + /* Status cchanel controller */
  233347. + {
  233348. + .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  233349. + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
  233350. + .access = SNDRV_CTL_ELEM_ACCESS_READ |
  233351. + SNDRV_CTL_ELEM_ACCESS_WRITE |
  233352. + SNDRV_CTL_ELEM_ACCESS_VOLATILE,
  233353. + .info = fsl_hdmi_iec_info,
  233354. + .get = fsl_hdmi_iec_get,
  233355. + .put = fsl_hdmi_iec_put,
  233356. + },
  233357. +};
  233358. +
  233359. +static int fsl_hdmi_soc_dai_probe(struct snd_soc_dai *dai)
  233360. +{
  233361. + int ret;
  233362. +
  233363. + init_channel_allocations();
  233364. +
  233365. + ret = snd_soc_add_dai_controls(dai, fsl_hdmi_ctrls,
  233366. + ARRAY_SIZE(fsl_hdmi_ctrls));
  233367. + if (ret)
  233368. + dev_warn(dai->dev, "failed to add dai controls\n");
  233369. +
  233370. + return 0;
  233371. +}
  233372. +
  233373. +static struct snd_soc_dai_driver fsl_hdmi_dai = {
  233374. + .probe = &fsl_hdmi_soc_dai_probe,
  233375. + .playback = {
  233376. + .channels_min = 2,
  233377. + .channels_max = 8,
  233378. + .rates = MXC_HDMI_RATES_PLAYBACK,
  233379. + .formats = MXC_HDMI_FORMATS_PLAYBACK,
  233380. + },
  233381. + .ops = &fsl_hdmi_soc_dai_ops,
  233382. +};
  233383. +
  233384. +static const struct snd_soc_component_driver fsl_hdmi_component = {
  233385. + .name = "fsl-hdmi",
  233386. +};
  233387. +
  233388. +static int fsl_hdmi_dai_probe(struct platform_device *pdev)
  233389. +{
  233390. + struct device_node *np = pdev->dev.of_node;
  233391. + struct imx_hdmi *hdmi_data;
  233392. + int ret = 0;
  233393. +
  233394. + if (!np)
  233395. + return -ENODEV;
  233396. +
  233397. + if (!hdmi_get_registered()) {
  233398. + dev_err(&pdev->dev, "failed to probe. Load HDMI-video first.\n");
  233399. + return -ENOMEM;
  233400. + }
  233401. +
  233402. + hdmi_data = devm_kzalloc(&pdev->dev, sizeof(*hdmi_data), GFP_KERNEL);
  233403. + if (!hdmi_data) {
  233404. + dev_err(&pdev->dev, "failed to alloc hdmi_data\n");
  233405. + return -ENOMEM;
  233406. + }
  233407. +
  233408. + hdmi_data->pdev = pdev;
  233409. +
  233410. + memcpy(&hdmi_data->cpu_dai_drv, &fsl_hdmi_dai, sizeof(fsl_hdmi_dai));
  233411. + hdmi_data->cpu_dai_drv.name = np->name;
  233412. +
  233413. + hdmi_data->isfr_clk = devm_clk_get(&pdev->dev, "hdmi_isfr");
  233414. + if (IS_ERR(hdmi_data->isfr_clk)) {
  233415. + ret = PTR_ERR(hdmi_data->isfr_clk);
  233416. + dev_err(&pdev->dev, "failed to get HDMI isfr clk: %d\n", ret);
  233417. + return -EINVAL;
  233418. + }
  233419. +
  233420. + hdmi_data->iahb_clk = devm_clk_get(&pdev->dev, "hdmi_iahb");
  233421. + if (IS_ERR(hdmi_data->iahb_clk)) {
  233422. + ret = PTR_ERR(hdmi_data->iahb_clk);
  233423. + dev_err(&pdev->dev, "failed to get HDMI ahb clk: %d\n", ret);
  233424. + return -EINVAL;
  233425. + }
  233426. +
  233427. + dev_set_drvdata(&pdev->dev, hdmi_data);
  233428. + ret = snd_soc_register_component(&pdev->dev, &fsl_hdmi_component,
  233429. + &hdmi_data->cpu_dai_drv, 1);
  233430. + if (ret) {
  233431. + dev_err(&pdev->dev, "register DAI failed\n");
  233432. + return ret;
  233433. + }
  233434. +
  233435. + hdmi_data->codec_dev = platform_device_register_simple(
  233436. + "hdmi-audio-codec", -1, NULL, 0);
  233437. + if (IS_ERR(hdmi_data->codec_dev)) {
  233438. + dev_err(&pdev->dev, "failed to register HDMI audio codec\n");
  233439. + ret = PTR_ERR(hdmi_data->codec_dev);
  233440. + goto fail;
  233441. + }
  233442. +
  233443. + hdmi_data->dma_dev = platform_device_alloc("imx-hdmi-audio", -1);
  233444. + if (IS_ERR(hdmi_data->dma_dev)) {
  233445. + ret = PTR_ERR(hdmi_data->dma_dev);
  233446. + goto fail_dma;
  233447. + }
  233448. +
  233449. + platform_set_drvdata(hdmi_data->dma_dev, hdmi_data);
  233450. +
  233451. + ret = platform_device_add(hdmi_data->dma_dev);
  233452. + if (ret) {
  233453. + platform_device_put(hdmi_data->dma_dev);
  233454. + goto fail_dma;
  233455. + }
  233456. +
  233457. + return 0;
  233458. +
  233459. +fail_dma:
  233460. + platform_device_unregister(hdmi_data->codec_dev);
  233461. +fail:
  233462. + snd_soc_unregister_component(&pdev->dev);
  233463. +
  233464. + return ret;
  233465. +}
  233466. +
  233467. +static int fsl_hdmi_dai_remove(struct platform_device *pdev)
  233468. +{
  233469. + struct imx_hdmi *hdmi_data = platform_get_drvdata(pdev);
  233470. +
  233471. + platform_device_unregister(hdmi_data->dma_dev);
  233472. + platform_device_unregister(hdmi_data->codec_dev);
  233473. + snd_soc_unregister_component(&pdev->dev);
  233474. +
  233475. + return 0;
  233476. +}
  233477. +
  233478. +static const struct of_device_id fsl_hdmi_dai_dt_ids[] = {
  233479. + { .compatible = "fsl,imx6dl-hdmi-audio", },
  233480. + { .compatible = "fsl,imx6q-hdmi-audio", },
  233481. + { /* sentinel */ }
  233482. +};
  233483. +MODULE_DEVICE_TABLE(of, fsl_hdmi_dai_dt_ids);
  233484. +
  233485. +static struct platform_driver fsl_hdmi_driver = {
  233486. + .probe = fsl_hdmi_dai_probe,
  233487. + .remove = fsl_hdmi_dai_remove,
  233488. + .driver = {
  233489. + .name = "fsl-hdmi-dai",
  233490. + .owner = THIS_MODULE,
  233491. + .of_match_table = fsl_hdmi_dai_dt_ids,
  233492. + },
  233493. +};
  233494. +module_platform_driver(fsl_hdmi_driver);
  233495. +
  233496. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  233497. +MODULE_DESCRIPTION("IMX HDMI TX DAI");
  233498. +MODULE_LICENSE("GPL");
  233499. +MODULE_ALIAS("platform:fsl-hdmi-dai");
  233500. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_spdif.c linux-imx6-3.14/sound/soc/fsl/fsl_spdif.c
  233501. --- linux-3.14.17/sound/soc/fsl/fsl_spdif.c 2014-08-14 03:38:34.000000000 +0200
  233502. +++ linux-imx6-3.14/sound/soc/fsl/fsl_spdif.c 2014-09-11 18:06:18.690104584 +0200
  233503. @@ -21,6 +21,8 @@
  233504. #include <linux/of_address.h>
  233505. #include <linux/of_device.h>
  233506. #include <linux/of_irq.h>
  233507. +#include <linux/pm_runtime.h>
  233508. +#include <linux/busfreq-imx6.h>
  233509. #include <sound/asoundef.h>
  233510. #include <sound/soc.h>
  233511. @@ -53,7 +55,7 @@
  233512. spinlock_t ctl_lock;
  233513. /* IEC958 channel tx status bit */
  233514. - unsigned char ch_status[4];
  233515. + unsigned char ch_status[6];
  233516. /* User bits */
  233517. unsigned char subcode[2 * SPDIF_UBITS_SIZE];
  233518. @@ -80,6 +82,7 @@
  233519. u8 rxclk_src;
  233520. struct clk *txclk[SPDIF_TXRATE_MAX];
  233521. struct clk *rxclk;
  233522. + struct clk *sysclk;
  233523. struct snd_dmaengine_dai_dma_data dma_params_tx;
  233524. struct snd_dmaengine_dai_dma_data dma_params_rx;
  233525. @@ -295,11 +298,11 @@
  233526. return -EBUSY;
  233527. }
  233528. -static void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
  233529. - u8 mask, u8 cstatus)
  233530. +static inline void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
  233531. + u8 byteno, u8 mask, u8 cstatus)
  233532. {
  233533. - ctrl->ch_status[3] &= ~mask;
  233534. - ctrl->ch_status[3] |= cstatus & mask;
  233535. + ctrl->ch_status[byteno] &= ~mask;
  233536. + ctrl->ch_status[byteno] |= cstatus & mask;
  233537. }
  233538. static void spdif_write_channel_status(struct fsl_spdif_priv *spdif_priv)
  233539. @@ -316,10 +319,16 @@
  233540. dev_dbg(&pdev->dev, "STCSCH: 0x%06x\n", ch_status);
  233541. - ch_status = bitrev8(ctrl->ch_status[3]) << 16;
  233542. + ch_status = bitrev8(ctrl->ch_status[3]) << 16 |
  233543. + (bitrev8(ctrl->ch_status[4]) << 8) |
  233544. + bitrev8(ctrl->ch_status[5]);
  233545. regmap_write(regmap, REG_SPDIF_STCSCL, ch_status);
  233546. dev_dbg(&pdev->dev, "STCSCL: 0x%06x\n", ch_status);
  233547. +
  233548. + /* Set outgoing validity (0: pcm, 1: non-audio) */
  233549. + regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_VAL_MASK,
  233550. + (ctrl->ch_status[0] & IEC958_AES0_NONAUDIO) ? 0 : SCR_VAL_CLEAR);
  233551. }
  233552. /* Set SPDIF PhaseConfig register for rx clock */
  233553. @@ -347,23 +356,45 @@
  233554. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  233555. struct regmap *regmap = spdif_priv->regmap;
  233556. struct platform_device *pdev = spdif_priv->pdev;
  233557. - unsigned long csfs = 0;
  233558. u32 stc, mask, rate;
  233559. - u8 clk, div;
  233560. + u8 clk, div, csfs, csofs;
  233561. int ret;
  233562. switch (sample_rate) {
  233563. case 32000:
  233564. rate = SPDIF_TXRATE_32000;
  233565. csfs = IEC958_AES3_CON_FS_32000;
  233566. + csofs = IEC958_AES4_CON_ORIGFS_32000;
  233567. break;
  233568. case 44100:
  233569. rate = SPDIF_TXRATE_44100;
  233570. csfs = IEC958_AES3_CON_FS_44100;
  233571. + csofs = IEC958_AES4_CON_ORIGFS_44100;
  233572. break;
  233573. case 48000:
  233574. rate = SPDIF_TXRATE_48000;
  233575. csfs = IEC958_AES3_CON_FS_48000;
  233576. + csofs = IEC958_AES4_CON_ORIGFS_48000;
  233577. + break;
  233578. + case 88200:
  233579. + rate = SPDIF_TXRATE_88200;
  233580. + csfs = IEC958_AES3_CON_FS_88200;
  233581. + csofs = IEC958_AES4_CON_ORIGFS_88200;
  233582. + break;
  233583. + case 96000:
  233584. + rate = SPDIF_TXRATE_96000;
  233585. + csfs = IEC958_AES3_CON_FS_96000;
  233586. + csofs = IEC958_AES4_CON_ORIGFS_96000;
  233587. + break;
  233588. + case 176400:
  233589. + rate = SPDIF_TXRATE_176400;
  233590. + csfs = IEC958_AES3_CON_FS_176400;
  233591. + csofs = IEC958_AES4_CON_ORIGFS_176400;
  233592. + break;
  233593. + case 192000:
  233594. + rate = SPDIF_TXRATE_192000;
  233595. + csfs = IEC958_AES3_CON_FS_192000;
  233596. + csofs = IEC958_AES4_CON_ORIGFS_192000;
  233597. break;
  233598. default:
  233599. dev_err(&pdev->dev, "unsupported sample rate %d\n", sample_rate);
  233600. @@ -399,7 +430,8 @@
  233601. clk_get_rate(spdif_priv->txclk[rate]));
  233602. /* set fs field in consumer channel status */
  233603. - spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs);
  233604. + spdif_set_cstatus(ctrl, 3, IEC958_AES3_CON_FS, csfs);
  233605. + spdif_set_cstatus(ctrl, 4, IEC958_AES4_CON_ORIGFS, csofs);
  233606. /* select clock source and divisor */
  233607. stc = STC_TXCLK_ALL_EN | STC_TXCLK_SRC_SET(clk) | STC_TXCLK_DIV(div);
  233608. @@ -421,6 +453,8 @@
  233609. u32 scr, mask, i;
  233610. int ret;
  233611. + pm_runtime_get_sync(cpu_dai->dev);
  233612. +
  233613. /* Reset module and interrupts only for first initialization */
  233614. if (!cpu_dai->active) {
  233615. ret = spdif_softreset(spdif_priv);
  233616. @@ -485,6 +519,8 @@
  233617. regmap_update_bits(regmap, REG_SPDIF_SCR,
  233618. SCR_LOW_POWER, SCR_LOW_POWER);
  233619. }
  233620. +
  233621. + pm_runtime_put_sync(cpu_dai->dev);
  233622. }
  233623. static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
  233624. @@ -505,8 +541,8 @@
  233625. __func__, sample_rate);
  233626. return ret;
  233627. }
  233628. - spdif_set_cstatus(ctrl, IEC958_AES3_CON_CLOCK,
  233629. - IEC958_AES3_CON_CLOCK_1000PPM);
  233630. + spdif_set_cstatus(ctrl, 3, IEC958_AES3_CON_CLOCK,
  233631. + IEC958_AES3_CON_CLOCK_1000PPM);
  233632. spdif_write_channel_status(spdif_priv);
  233633. } else {
  233634. /* Setup rx clock source */
  233635. @@ -576,14 +612,13 @@
  233636. static int fsl_spdif_pb_get(struct snd_kcontrol *kcontrol,
  233637. struct snd_ctl_elem_value *uvalue)
  233638. {
  233639. + int i;
  233640. struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
  233641. struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
  233642. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  233643. - uvalue->value.iec958.status[0] = ctrl->ch_status[0];
  233644. - uvalue->value.iec958.status[1] = ctrl->ch_status[1];
  233645. - uvalue->value.iec958.status[2] = ctrl->ch_status[2];
  233646. - uvalue->value.iec958.status[3] = ctrl->ch_status[3];
  233647. + for (i = 0; i < ARRAY_SIZE(ctrl->ch_status); i++)
  233648. + uvalue->value.iec958.status[i] = ctrl->ch_status[i];
  233649. return 0;
  233650. }
  233651. @@ -591,14 +626,13 @@
  233652. static int fsl_spdif_pb_put(struct snd_kcontrol *kcontrol,
  233653. struct snd_ctl_elem_value *uvalue)
  233654. {
  233655. + int i;
  233656. struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
  233657. struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
  233658. struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
  233659. - ctrl->ch_status[0] = uvalue->value.iec958.status[0];
  233660. - ctrl->ch_status[1] = uvalue->value.iec958.status[1];
  233661. - ctrl->ch_status[2] = uvalue->value.iec958.status[2];
  233662. - ctrl->ch_status[3] = uvalue->value.iec958.status[3];
  233663. + for (i = 0; i < ARRAY_SIZE(ctrl->ch_status); i++)
  233664. + ctrl->ch_status[i] = uvalue->value.iec958.status[i];
  233665. spdif_write_channel_status(spdif_priv);
  233666. @@ -754,7 +788,7 @@
  233667. clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0xf;
  233668. if (srpc_dpll_locked[clksrc] && (phaseconf & SRPC_DPLL_LOCKED)) {
  233669. /* Get bus clock from system */
  233670. - busclk_freq = clk_get_rate(spdif_priv->rxclk);
  233671. + busclk_freq = clk_get_rate(spdif_priv->sysclk);
  233672. }
  233673. /* FreqMeas_CLK = (BUS_CLK * FreqMeas) / 2 ^ 10 / GAINSEL / 128 */
  233674. @@ -999,7 +1033,7 @@
  233675. struct clk *clk, u64 savesub,
  233676. enum spdif_txrate index)
  233677. {
  233678. - const u32 rate[] = { 32000, 44100, 48000 };
  233679. + const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
  233680. u64 rate_ideal, rate_actual, sub;
  233681. u32 div, arate;
  233682. @@ -1017,7 +1051,7 @@
  233683. break;
  233684. } else if (arate / rate[index] == 1) {
  233685. /* A little bigger than expect */
  233686. - sub = (arate - rate[index]) * 100000;
  233687. + sub = (u64)(arate - rate[index]) * 100000;
  233688. do_div(sub, rate[index]);
  233689. if (sub < savesub) {
  233690. savesub = sub;
  233691. @@ -1025,7 +1059,7 @@
  233692. }
  233693. } else if (rate[index] / arate == 1) {
  233694. /* A little smaller than expect */
  233695. - sub = (rate[index] - arate) * 100000;
  233696. + sub = (u64)(rate[index] - arate) * 100000;
  233697. do_div(sub, rate[index]);
  233698. if (sub < savesub) {
  233699. savesub = sub;
  233700. @@ -1040,7 +1074,7 @@
  233701. static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
  233702. enum spdif_txrate index)
  233703. {
  233704. - const u32 rate[] = { 32000, 44100, 48000 };
  233705. + const u32 rate[] = { 32000, 44100, 48000, 88200, 96000, 176400, 192000 };
  233706. struct platform_device *pdev = spdif_priv->pdev;
  233707. struct device *dev = &pdev->dev;
  233708. u64 savesub = 100000, ret;
  233709. @@ -1058,6 +1092,13 @@
  233710. if (!clk_get_rate(clk))
  233711. continue;
  233712. + /* TODO: We here ignore sysclk source due to imperfect clock
  233713. + * selecting mechanism: sysclk is a bit different which we can
  233714. + * not change its clock rate but use another inner divider to
  233715. + * derive a proper clock rate. */
  233716. + if (i == SPDIF_CLK_SRC_SYSCLK)
  233717. + continue;
  233718. +
  233719. ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index);
  233720. if (savesub == ret)
  233721. continue;
  233722. @@ -1131,6 +1172,13 @@
  233723. return ret;
  233724. }
  233725. + /* Get system clock for rx clock rate calculation */
  233726. + spdif_priv->sysclk = devm_clk_get(&pdev->dev, "rxtx5");
  233727. + if (IS_ERR(spdif_priv->sysclk)) {
  233728. + dev_err(&pdev->dev, "no system clock(rxtx5) in devicetree\n");
  233729. + return PTR_ERR(spdif_priv->sysclk);
  233730. + }
  233731. +
  233732. /* Select clock source for rx/tx clock */
  233733. spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
  233734. if (IS_ERR(spdif_priv->rxclk)) {
  233735. @@ -1150,12 +1198,13 @@
  233736. spin_lock_init(&ctrl->ctl_lock);
  233737. /* Init tx channel status default value */
  233738. - ctrl->ch_status[0] =
  233739. - IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_5015;
  233740. + ctrl->ch_status[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
  233741. ctrl->ch_status[1] = IEC958_AES1_CON_DIGDIGCONV_ID;
  233742. ctrl->ch_status[2] = 0x00;
  233743. ctrl->ch_status[3] =
  233744. IEC958_AES3_CON_FS_44100 | IEC958_AES3_CON_CLOCK_1000PPM;
  233745. + ctrl->ch_status[4] = IEC958_AES4_CON_ORIGFS_44100;
  233746. + ctrl->ch_status[5] = IEC958_AES5_CON_CGMSA_COPYFREELY;
  233747. spdif_priv->dpll_locked = false;
  233748. @@ -1164,6 +1213,8 @@
  233749. spdif_priv->dma_params_tx.addr = res->start + REG_SPDIF_STL;
  233750. spdif_priv->dma_params_rx.addr = res->start + REG_SPDIF_SRL;
  233751. + pm_runtime_enable(&pdev->dev);
  233752. +
  233753. /* Register with ASoC */
  233754. dev_set_drvdata(&pdev->dev, spdif_priv);
  233755. @@ -1174,13 +1225,34 @@
  233756. return ret;
  233757. }
  233758. - ret = imx_pcm_dma_init(pdev);
  233759. + ret = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_COMPAT,
  233760. + IMX_SPDIF_DMABUF_SIZE);
  233761. if (ret)
  233762. dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
  233763. return ret;
  233764. }
  233765. +#ifdef CONFIG_PM_RUNTIME
  233766. +static int fsl_spdif_runtime_resume(struct device *dev)
  233767. +{
  233768. + request_bus_freq(BUS_FREQ_HIGH);
  233769. + return 0;
  233770. +}
  233771. +
  233772. +static int fsl_spdif_runtime_suspend(struct device *dev)
  233773. +{
  233774. + release_bus_freq(BUS_FREQ_HIGH);
  233775. + return 0;
  233776. +}
  233777. +#endif
  233778. +
  233779. +static const struct dev_pm_ops fsl_spdif_pm = {
  233780. + SET_RUNTIME_PM_OPS(fsl_spdif_runtime_suspend,
  233781. + fsl_spdif_runtime_resume,
  233782. + NULL)
  233783. +};
  233784. +
  233785. static const struct of_device_id fsl_spdif_dt_ids[] = {
  233786. { .compatible = "fsl,imx35-spdif", },
  233787. {}
  233788. @@ -1192,6 +1264,7 @@
  233789. .name = "fsl-spdif-dai",
  233790. .owner = THIS_MODULE,
  233791. .of_match_table = fsl_spdif_dt_ids,
  233792. + .pm = &fsl_spdif_pm,
  233793. },
  233794. .probe = fsl_spdif_probe,
  233795. };
  233796. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_spdif.h linux-imx6-3.14/sound/soc/fsl/fsl_spdif.h
  233797. --- linux-3.14.17/sound/soc/fsl/fsl_spdif.h 2014-08-14 03:38:34.000000000 +0200
  233798. +++ linux-imx6-3.14/sound/soc/fsl/fsl_spdif.h 2014-09-11 18:06:18.690104584 +0200
  233799. @@ -157,13 +157,19 @@
  233800. #define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK)
  233801. #define STC_TXCLK_SRC_MAX 8
  233802. +#define SPDIF_CLK_SRC_SYSCLK 5
  233803. +
  233804. /* SPDIF tx rate */
  233805. enum spdif_txrate {
  233806. SPDIF_TXRATE_32000 = 0,
  233807. SPDIF_TXRATE_44100,
  233808. SPDIF_TXRATE_48000,
  233809. + SPDIF_TXRATE_88200,
  233810. + SPDIF_TXRATE_96000,
  233811. + SPDIF_TXRATE_176400,
  233812. + SPDIF_TXRATE_192000,
  233813. };
  233814. -#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_48000 + 1)
  233815. +#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_192000 + 1)
  233816. #define SPDIF_CSTATUS_BYTE 6
  233817. @@ -173,7 +179,11 @@
  233818. #define FSL_SPDIF_RATES_PLAYBACK (SNDRV_PCM_RATE_32000 | \
  233819. SNDRV_PCM_RATE_44100 | \
  233820. - SNDRV_PCM_RATE_48000)
  233821. + SNDRV_PCM_RATE_48000 | \
  233822. + SNDRV_PCM_RATE_88200 | \
  233823. + SNDRV_PCM_RATE_96000 | \
  233824. + SNDRV_PCM_RATE_176400| \
  233825. + SNDRV_PCM_RATE_192000)
  233826. #define FSL_SPDIF_RATES_CAPTURE (SNDRV_PCM_RATE_16000 | \
  233827. SNDRV_PCM_RATE_32000 | \
  233828. diff -Nur linux-3.14.17/sound/soc/fsl/fsl_ssi.c linux-imx6-3.14/sound/soc/fsl/fsl_ssi.c
  233829. --- linux-3.14.17/sound/soc/fsl/fsl_ssi.c 2014-08-14 03:38:34.000000000 +0200
  233830. +++ linux-imx6-3.14/sound/soc/fsl/fsl_ssi.c 2014-09-11 18:06:18.690104584 +0200
  233831. @@ -3,7 +3,7 @@
  233832. *
  233833. * Author: Timur Tabi <timur@freescale.com>
  233834. *
  233835. - * Copyright 2007-2010 Freescale Semiconductor, Inc.
  233836. + * Copyright (C) 2007-2013 Freescale Semiconductor, Inc.
  233837. *
  233838. * This file is licensed under the terms of the GNU General Public License
  233839. * version 2. This program is licensed "as is" without any warranty of any
  233840. @@ -30,6 +30,7 @@
  233841. * around this by not polling these bits but only wait a fixed delay.
  233842. */
  233843. +#include <linux/busfreq-imx6.h>
  233844. #include <linux/init.h>
  233845. #include <linux/io.h>
  233846. #include <linux/module.h>
  233847. @@ -43,6 +44,7 @@
  233848. #include <linux/of_address.h>
  233849. #include <linux/of_irq.h>
  233850. #include <linux/of_platform.h>
  233851. +#include <linux/pm_runtime.h>
  233852. #include <sound/core.h>
  233853. #include <sound/pcm.h>
  233854. @@ -73,6 +75,24 @@
  233855. }
  233856. #endif
  233857. +#ifdef DEBUG
  233858. +#define NUM_OF_SSI_REG (sizeof(struct ccsr_ssi) / sizeof(__be32))
  233859. +
  233860. +void dump_reg(struct ccsr_ssi __iomem *ssi)
  233861. +{
  233862. + u32 val, i;
  233863. +
  233864. + for (i = 0; i < NUM_OF_SSI_REG; i++) {
  233865. + if (&ssi->stx0 + i == NULL)
  233866. + continue;
  233867. + val = read_ssi(&ssi->stx0 + i);
  233868. + pr_debug("REG %x = %x\n", (u32)(&ssi->stx0 + i) & 0xff, val);
  233869. + }
  233870. +}
  233871. +#else
  233872. +void dump_reg(struct ccsr_ssi __iomem *ssi) {}
  233873. +#endif
  233874. +
  233875. /**
  233876. * FSLSSI_I2S_RATES: sample rates supported by the I2S
  233877. *
  233878. @@ -171,8 +191,6 @@
  233879. struct clk *clk;
  233880. struct snd_dmaengine_dai_dma_data dma_params_tx;
  233881. struct snd_dmaengine_dai_dma_data dma_params_rx;
  233882. - struct imx_dma_data filter_data_tx;
  233883. - struct imx_dma_data filter_data_rx;
  233884. struct imx_pcm_fiq_params fiq_params;
  233885. /* Register values for rx/tx configuration */
  233886. struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
  233887. @@ -206,6 +224,26 @@
  233888. char name[1];
  233889. };
  233890. +#ifdef CONFIG_PM_RUNTIME
  233891. +static int fsl_ssi_runtime_resume(struct device *dev)
  233892. +{
  233893. + request_bus_freq(BUS_FREQ_AUDIO);
  233894. + return 0;
  233895. +}
  233896. +
  233897. +static int fsl_ssi_runtime_suspend(struct device *dev)
  233898. +{
  233899. + release_bus_freq(BUS_FREQ_AUDIO);
  233900. + return 0;
  233901. +}
  233902. +#endif
  233903. +
  233904. +static const struct dev_pm_ops fsl_ssi_pm = {
  233905. + SET_RUNTIME_PM_OPS(fsl_ssi_runtime_suspend,
  233906. + fsl_ssi_runtime_resume,
  233907. + NULL)
  233908. +};
  233909. +
  233910. static const struct of_device_id fsl_ssi_ids[] = {
  233911. { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
  233912. { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
  233913. @@ -489,6 +527,23 @@
  233914. }
  233915. }
  233916. +static void fsl_ssi_clk_ctrl(struct fsl_ssi_private *ssi_private, bool enable)
  233917. +{
  233918. + if (enable) {
  233919. + if (ssi_private->ssi_on_imx) {
  233920. + if (!IS_ERR(ssi_private->baudclk))
  233921. + clk_enable(ssi_private->baudclk);
  233922. + clk_enable(ssi_private->clk);
  233923. + }
  233924. + } else {
  233925. + if (ssi_private->ssi_on_imx) {
  233926. + if (!IS_ERR(ssi_private->baudclk))
  233927. + clk_disable(ssi_private->baudclk);
  233928. + clk_disable(ssi_private->clk);
  233929. + }
  233930. + }
  233931. +}
  233932. +
  233933. /*
  233934. * Enable/Disable a ssi configuration. You have to pass either
  233935. * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
  233936. @@ -509,6 +564,8 @@
  233937. else
  233938. avals = &ssi_private->rxtx_reg_val.rx;
  233939. + fsl_ssi_clk_ctrl(ssi_private, enable);
  233940. +
  233941. /* If vals should be disabled, start with disabling the unit */
  233942. if (!enable) {
  233943. u32 scr = vals->scr & (vals->scr ^ avals->scr);
  233944. @@ -748,6 +805,8 @@
  233945. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  233946. unsigned long flags;
  233947. + pm_runtime_get_sync(dai->dev);
  233948. +
  233949. /* First, we only do fsl_ssi_setup() when SSI is going to be active.
  233950. * Second, fsl_ssi_setup was already called by ac97_init earlier if
  233951. * the driver is in ac97 mode.
  233952. @@ -1083,14 +1142,17 @@
  233953. switch (cmd) {
  233954. case SNDRV_PCM_TRIGGER_START:
  233955. + case SNDRV_PCM_TRIGGER_RESUME:
  233956. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  233957. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  233958. fsl_ssi_tx_config(ssi_private, true);
  233959. else
  233960. fsl_ssi_rx_config(ssi_private, true);
  233961. + dump_reg(ssi);
  233962. break;
  233963. case SNDRV_PCM_TRIGGER_STOP:
  233964. + case SNDRV_PCM_TRIGGER_SUSPEND:
  233965. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  233966. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  233967. fsl_ssi_tx_config(ssi_private, false);
  233968. @@ -1119,6 +1181,12 @@
  233969. return 0;
  233970. }
  233971. +static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
  233972. + struct snd_soc_dai *dai)
  233973. +{
  233974. + pm_runtime_put_sync(dai->dev);
  233975. +}
  233976. +
  233977. static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
  233978. {
  233979. struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
  233980. @@ -1138,6 +1206,7 @@
  233981. .set_sysclk = fsl_ssi_set_dai_sysclk,
  233982. .set_tdm_slot = fsl_ssi_set_dai_tdm_slot,
  233983. .trigger = fsl_ssi_trigger,
  233984. + .shutdown = fsl_ssi_shutdown,
  233985. };
  233986. /* Template for the CPU dai driver structure */
  233987. @@ -1257,13 +1326,13 @@
  233988. int ret = 0;
  233989. struct device_attribute *dev_attr = NULL;
  233990. struct device_node *np = pdev->dev.of_node;
  233991. + u32 dmas[4];
  233992. const struct of_device_id *of_id;
  233993. enum fsl_ssi_type hw_type;
  233994. const char *p, *sprop;
  233995. const uint32_t *iprop;
  233996. struct resource res;
  233997. char name[64];
  233998. - bool shared;
  233999. bool ac97 = false;
  234000. /* SSIs that are not connected on the board should have a
  234001. @@ -1381,7 +1450,6 @@
  234002. if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
  234003. hw_type == FSL_SSI_MX35) {
  234004. - u32 dma_events[2], dmas[4];
  234005. ssi_private->ssi_on_imx = true;
  234006. ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
  234007. @@ -1390,9 +1458,9 @@
  234008. dev_err(&pdev->dev, "could not get clock: %d\n", ret);
  234009. goto error_irqmap;
  234010. }
  234011. - ret = clk_prepare_enable(ssi_private->clk);
  234012. + ret = clk_prepare(ssi_private->clk);
  234013. if (ret) {
  234014. - dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n",
  234015. + dev_err(&pdev->dev, "clk_prepare failed: %d\n",
  234016. ret);
  234017. goto error_irqmap;
  234018. }
  234019. @@ -1405,41 +1473,21 @@
  234020. dev_dbg(&pdev->dev, "could not get baud clock: %ld\n",
  234021. PTR_ERR(ssi_private->baudclk));
  234022. else
  234023. - clk_prepare_enable(ssi_private->baudclk);
  234024. + clk_prepare(ssi_private->baudclk);
  234025. /*
  234026. * We have burstsize be "fifo_depth - 2" to match the SSI
  234027. * watermark setting in fsl_ssi_startup().
  234028. */
  234029. - ssi_private->dma_params_tx.maxburst =
  234030. - ssi_private->fifo_depth - 2;
  234031. - ssi_private->dma_params_rx.maxburst =
  234032. - ssi_private->fifo_depth - 2;
  234033. + ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2;
  234034. + ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2;
  234035. ssi_private->dma_params_tx.addr =
  234036. ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
  234037. ssi_private->dma_params_rx.addr =
  234038. ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
  234039. - ssi_private->dma_params_tx.filter_data =
  234040. - &ssi_private->filter_data_tx;
  234041. - ssi_private->dma_params_rx.filter_data =
  234042. - &ssi_private->filter_data_rx;
  234043. - if (!of_property_read_bool(pdev->dev.of_node, "dmas") &&
  234044. - ssi_private->use_dma) {
  234045. - /*
  234046. - * FIXME: This is a temporary solution until all
  234047. - * necessary dma drivers support the generic dma
  234048. - * bindings.
  234049. - */
  234050. - ret = of_property_read_u32_array(pdev->dev.of_node,
  234051. - "fsl,ssi-dma-events", dma_events, 2);
  234052. - if (ret && ssi_private->use_dma) {
  234053. - dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n");
  234054. - goto error_clk;
  234055. - }
  234056. - }
  234057. - /* Should this be merge with the above? */
  234058. - if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4)
  234059. - && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
  234060. +
  234061. + ret = !of_property_read_u32_array(np, "dmas", dmas, 4);
  234062. + if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) {
  234063. ssi_private->use_dual_fifo = true;
  234064. /* When using dual fifo mode, we need to keep watermark
  234065. * as even numbers due to dma script limitation.
  234066. @@ -1447,14 +1495,6 @@
  234067. ssi_private->dma_params_tx.maxburst &= ~0x1;
  234068. ssi_private->dma_params_rx.maxburst &= ~0x1;
  234069. }
  234070. -
  234071. - shared = of_device_is_compatible(of_get_parent(np),
  234072. - "fsl,spba-bus");
  234073. -
  234074. - imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
  234075. - dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
  234076. - imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
  234077. - dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
  234078. }
  234079. /*
  234080. @@ -1474,6 +1514,8 @@
  234081. }
  234082. }
  234083. + pm_runtime_enable(&pdev->dev);
  234084. +
  234085. /* Register with ASoC */
  234086. dev_set_drvdata(&pdev->dev, ssi_private);
  234087. @@ -1509,7 +1551,8 @@
  234088. if (ret)
  234089. goto error_pcm;
  234090. } else {
  234091. - ret = imx_pcm_dma_init(pdev);
  234092. + ret = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE,
  234093. + IMX_SSI_DMABUF_SIZE);
  234094. if (ret)
  234095. goto error_pcm;
  234096. }
  234097. @@ -1565,12 +1608,16 @@
  234098. error_dev:
  234099. device_remove_file(&pdev->dev, dev_attr);
  234100. -error_clk:
  234101. if (ssi_private->ssi_on_imx) {
  234102. if (!IS_ERR(ssi_private->baudclk))
  234103. - clk_disable_unprepare(ssi_private->baudclk);
  234104. - clk_disable_unprepare(ssi_private->clk);
  234105. + clk_unprepare(ssi_private->baudclk);
  234106. + clk_unprepare(ssi_private->clk);
  234107. }
  234108. +error_clk:
  234109. + if (!IS_ERR(ssi_private->baudclk))
  234110. + clk_unprepare(ssi_private->baudclk);
  234111. + if (!IS_ERR(ssi_private->clk))
  234112. + clk_unprepare(ssi_private->clk);
  234113. error_irqmap:
  234114. if (ssi_private->irq_stats)
  234115. @@ -1590,8 +1637,8 @@
  234116. snd_soc_unregister_component(&pdev->dev);
  234117. if (ssi_private->ssi_on_imx) {
  234118. if (!IS_ERR(ssi_private->baudclk))
  234119. - clk_disable_unprepare(ssi_private->baudclk);
  234120. - clk_disable_unprepare(ssi_private->clk);
  234121. + clk_unprepare(ssi_private->baudclk);
  234122. + clk_unprepare(ssi_private->clk);
  234123. }
  234124. if (ssi_private->irq_stats)
  234125. irq_dispose_mapping(ssi_private->irq);
  234126. @@ -1604,6 +1651,7 @@
  234127. .name = "fsl-ssi-dai",
  234128. .owner = THIS_MODULE,
  234129. .of_match_table = fsl_ssi_ids,
  234130. + .pm = &fsl_ssi_pm,
  234131. },
  234132. .probe = fsl_ssi_probe,
  234133. .remove = fsl_ssi_remove,
  234134. diff -Nur linux-3.14.17/sound/soc/fsl/imx-cs42888.c linux-imx6-3.14/sound/soc/fsl/imx-cs42888.c
  234135. --- linux-3.14.17/sound/soc/fsl/imx-cs42888.c 1970-01-01 01:00:00.000000000 +0100
  234136. +++ linux-imx6-3.14/sound/soc/fsl/imx-cs42888.c 2014-09-11 18:06:18.714104678 +0200
  234137. @@ -0,0 +1,369 @@
  234138. +/*
  234139. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. All Rights Reserved.
  234140. + */
  234141. +
  234142. +/*
  234143. + * The code contained herein is licensed under the GNU General Public
  234144. + * License. You may obtain a copy of the GNU General Public License
  234145. + * Version 2 or later at the following locations:
  234146. + *
  234147. + * http://www.opensource.org/licenses/gpl-license.html
  234148. + * http://www.gnu.org/copyleft/gpl.html
  234149. + */
  234150. +
  234151. +#include <linux/module.h>
  234152. +#include <linux/of.h>
  234153. +#include <linux/of_platform.h>
  234154. +#include <linux/slab.h>
  234155. +#include <linux/device.h>
  234156. +#include <linux/i2c.h>
  234157. +#include <linux/clk.h>
  234158. +#include <linux/delay.h>
  234159. +#include <sound/core.h>
  234160. +#include <sound/pcm.h>
  234161. +#include <sound/soc.h>
  234162. +#include <sound/initval.h>
  234163. +#include <sound/pcm_params.h>
  234164. +
  234165. +#include "fsl_esai.h"
  234166. +#include "fsl_asrc.h"
  234167. +
  234168. +#define CODEC_CLK_EXTER_OSC 1
  234169. +#define CODEC_CLK_ESAI_HCKT 2
  234170. +
  234171. +struct imx_priv {
  234172. + int hw;
  234173. + int fe_output_rate;
  234174. + int fe_output_width;
  234175. + unsigned int mclk_freq;
  234176. + unsigned int codec_mclk;
  234177. + struct platform_device *pdev;
  234178. +};
  234179. +
  234180. +static struct imx_priv card_priv;
  234181. +
  234182. +static int imx_cs42888_startup(struct snd_pcm_substream *substream)
  234183. +{
  234184. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  234185. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  234186. + struct imx_priv *priv = &card_priv;
  234187. +
  234188. + if (!cpu_dai->active)
  234189. + priv->hw = 0;
  234190. + return 0;
  234191. +}
  234192. +
  234193. +static void imx_cs42888_shutdown(struct snd_pcm_substream *substream)
  234194. +{
  234195. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  234196. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  234197. + struct imx_priv *priv = &card_priv;
  234198. +
  234199. + if (!cpu_dai->active)
  234200. + priv->hw = 0;
  234201. +}
  234202. +
  234203. +static const struct {
  234204. + int rate;
  234205. + int ratio1;
  234206. + int ratio2;
  234207. +} sr_vals[] = {
  234208. + { 32000, 5, 3 },
  234209. + { 48000, 5, 3 },
  234210. + { 64000, 2, 1 },
  234211. + { 96000, 2, 1 },
  234212. + { 128000, 2, 1 },
  234213. + { 44100, 5, 3 },
  234214. + { 88200, 2, 1 },
  234215. + { 176400, 0, 0 },
  234216. + { 192000, 0, 0 },
  234217. +};
  234218. +
  234219. +static int imx_cs42888_surround_hw_params(struct snd_pcm_substream *substream,
  234220. + struct snd_pcm_hw_params *params)
  234221. +{
  234222. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  234223. + struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  234224. + struct snd_soc_dai *codec_dai = rtd->codec_dai;
  234225. + struct imx_priv *priv = &card_priv;
  234226. + unsigned int rate = params_rate(params);
  234227. + unsigned int lrclk_ratio = 0, i;
  234228. + u32 dai_format = 0;
  234229. +
  234230. + if (priv->hw)
  234231. + return 0;
  234232. +
  234233. + priv->hw = 1;
  234234. +
  234235. + if (priv->codec_mclk & CODEC_CLK_ESAI_HCKT) {
  234236. + for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
  234237. + if (sr_vals[i].rate == rate) {
  234238. + lrclk_ratio = sr_vals[i].ratio1;
  234239. + break;
  234240. + }
  234241. + }
  234242. + if (i == ARRAY_SIZE(sr_vals)) {
  234243. + dev_err(&priv->pdev->dev, "Unsupported rate %dHz\n", rate);
  234244. + return -EINVAL;
  234245. + }
  234246. +
  234247. + dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
  234248. + SND_SOC_DAIFMT_CBS_CFS;
  234249. +
  234250. + /* set the ESAI system clock as output */
  234251. + snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL_DIV,
  234252. + priv->mclk_freq, SND_SOC_CLOCK_OUT);
  234253. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 2);
  234254. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 2);
  234255. + /* set codec Master clock */
  234256. + snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq,\
  234257. + SND_SOC_CLOCK_IN);
  234258. + } else if (priv->codec_mclk & CODEC_CLK_EXTER_OSC) {
  234259. + for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
  234260. + if (sr_vals[i].rate == rate) {
  234261. + lrclk_ratio = sr_vals[i].ratio2;
  234262. + break;
  234263. + }
  234264. + }
  234265. + if (i == ARRAY_SIZE(sr_vals)) {
  234266. + dev_err(&priv->pdev->dev, "Unsupported rate %dHz\n", rate);
  234267. + return -EINVAL;
  234268. + }
  234269. +
  234270. + dai_format = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
  234271. + SND_SOC_DAIFMT_CBS_CFS;
  234272. +
  234273. + snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL,
  234274. + priv->mclk_freq, SND_SOC_CLOCK_OUT);
  234275. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 0);
  234276. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 0);
  234277. + snd_soc_dai_set_sysclk(codec_dai, 0, priv->mclk_freq,\
  234278. + SND_SOC_CLOCK_IN);
  234279. + }
  234280. +
  234281. + /* set cpu DAI configuration */
  234282. + snd_soc_dai_set_fmt(cpu_dai, dai_format);
  234283. + /* set i.MX active slot mask */
  234284. + snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 32);
  234285. + /* set the ratio */
  234286. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PSR, 1);
  234287. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_FP, lrclk_ratio);
  234288. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PSR, 1);
  234289. + snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_FP, lrclk_ratio);
  234290. +
  234291. + /* set codec DAI configuration */
  234292. + snd_soc_dai_set_fmt(codec_dai, dai_format);
  234293. + return 0;
  234294. +}
  234295. +
  234296. +static struct snd_soc_ops imx_cs42888_surround_ops = {
  234297. + .startup = imx_cs42888_startup,
  234298. + .shutdown = imx_cs42888_shutdown,
  234299. + .hw_params = imx_cs42888_surround_hw_params,
  234300. +};
  234301. +
  234302. +static const struct snd_soc_dapm_widget imx_cs42888_dapm_widgets[] = {
  234303. + SND_SOC_DAPM_LINE("Line Out Jack", NULL),
  234304. + SND_SOC_DAPM_LINE("Line In Jack", NULL),
  234305. +};
  234306. +
  234307. +static const struct snd_soc_dapm_route audio_map[] = {
  234308. + /* Line out jack */
  234309. + {"Line Out Jack", NULL, "AOUT1L"},
  234310. + {"Line Out Jack", NULL, "AOUT1R"},
  234311. + {"Line Out Jack", NULL, "AOUT2L"},
  234312. + {"Line Out Jack", NULL, "AOUT2R"},
  234313. + {"Line Out Jack", NULL, "AOUT3L"},
  234314. + {"Line Out Jack", NULL, "AOUT3R"},
  234315. + {"Line Out Jack", NULL, "AOUT4L"},
  234316. + {"Line Out Jack", NULL, "AOUT4R"},
  234317. + {"AIN1L", NULL, "Line In Jack"},
  234318. + {"AIN1R", NULL, "Line In Jack"},
  234319. + {"AIN2L", NULL, "Line In Jack"},
  234320. + {"AIN2R", NULL, "Line In Jack"},
  234321. + {"esai-Playback", NULL, "asrc-Playback"},
  234322. + {"codec-Playback", NULL, "esai-Playback"},/*Playback is the codec dai*/
  234323. +};
  234324. +
  234325. +static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
  234326. + struct snd_pcm_hw_params *params) {
  234327. +
  234328. + struct imx_priv *priv = &card_priv;
  234329. +
  234330. + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = priv->fe_output_rate;
  234331. + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max = priv->fe_output_rate;
  234332. + snd_mask_none(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT));
  234333. + if (priv->fe_output_width == 16)
  234334. + snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  234335. + SNDRV_PCM_FORMAT_S16_LE);
  234336. + else
  234337. + snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
  234338. + SNDRV_PCM_FORMAT_S24_LE);
  234339. + return 0;
  234340. +}
  234341. +
  234342. +static struct snd_soc_dai_link imx_cs42888_dai[] = {
  234343. + {
  234344. + .name = "HiFi",
  234345. + .stream_name = "HiFi",
  234346. + .codec_dai_name = "CS42888",
  234347. + .ops = &imx_cs42888_surround_ops,
  234348. + },
  234349. + {
  234350. + .name = "HiFi-ASRC-FE",
  234351. + .stream_name = "HiFi-ASRC-FE",
  234352. + .codec_name = "snd-soc-dummy",
  234353. + .codec_dai_name = "snd-soc-dummy-dai",
  234354. + .dynamic = 1,
  234355. + },
  234356. + {
  234357. + .name = "HiFi-ASRC-BE",
  234358. + .stream_name = "HiFi-ASRC-BE",
  234359. + .codec_dai_name = "CS42888",
  234360. + .platform_name = "snd-soc-dummy",
  234361. + .no_pcm = 1,
  234362. + .ops = &imx_cs42888_surround_ops,
  234363. + .be_hw_params_fixup = be_hw_params_fixup,
  234364. + },
  234365. +};
  234366. +
  234367. +static struct snd_soc_card snd_soc_card_imx_cs42888 = {
  234368. + .name = "cs42888-audio",
  234369. + .dai_link = imx_cs42888_dai,
  234370. + .dapm_widgets = imx_cs42888_dapm_widgets,
  234371. + .num_dapm_widgets = ARRAY_SIZE(imx_cs42888_dapm_widgets),
  234372. + .dapm_routes = audio_map,
  234373. + .num_dapm_routes = ARRAY_SIZE(audio_map),
  234374. +};
  234375. +
  234376. +/*
  234377. + * This function will register the snd_soc_pcm_link drivers.
  234378. + */
  234379. +static int imx_cs42888_probe(struct platform_device *pdev)
  234380. +{
  234381. + struct device_node *esai_np, *codec_np;
  234382. + struct device_node *asrc_np;
  234383. + struct platform_device *esai_pdev;
  234384. + struct platform_device *asrc_pdev = NULL;
  234385. + struct i2c_client *codec_dev;
  234386. + struct imx_priv *priv = &card_priv;
  234387. + struct clk *codec_clk = NULL;
  234388. + const char *mclk_name;
  234389. + int ret;
  234390. +
  234391. + priv->pdev = pdev;
  234392. +
  234393. + esai_np = of_parse_phandle(pdev->dev.of_node, "esai-controller", 0);
  234394. + codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
  234395. + if (!esai_np || !codec_np) {
  234396. + dev_err(&pdev->dev, "phandle missing or invalid\n");
  234397. + ret = -EINVAL;
  234398. + goto fail;
  234399. + }
  234400. +
  234401. + asrc_np = of_parse_phandle(pdev->dev.of_node, "asrc-controller", 0);
  234402. + if (asrc_np) {
  234403. + asrc_pdev = of_find_device_by_node(asrc_np);
  234404. + if (asrc_pdev) {
  234405. + struct fsl_asrc_p2p *asrc_p2p;
  234406. + asrc_p2p = platform_get_drvdata(asrc_pdev);
  234407. + asrc_p2p->per_dev = ESAI;
  234408. + priv->fe_output_rate = asrc_p2p->output_rate;
  234409. + priv->fe_output_width = asrc_p2p->output_width;
  234410. + }
  234411. + }
  234412. +
  234413. + esai_pdev = of_find_device_by_node(esai_np);
  234414. + if (!esai_pdev) {
  234415. + dev_err(&pdev->dev, "failed to find ESAI platform device\n");
  234416. + ret = -EINVAL;
  234417. + goto fail;
  234418. + }
  234419. + codec_dev = of_find_i2c_device_by_node(codec_np);
  234420. + if (!codec_dev) {
  234421. + dev_err(&pdev->dev, "failed to find codec platform device\n");
  234422. + ret = -EINVAL;
  234423. + goto fail;
  234424. + }
  234425. +
  234426. + /*if there is no asrc controller, we only enable one device*/
  234427. + if (!asrc_pdev) {
  234428. + imx_cs42888_dai[0].codec_of_node = codec_np;
  234429. + imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
  234430. + imx_cs42888_dai[0].platform_of_node = esai_np;
  234431. + snd_soc_card_imx_cs42888.num_links = 1;
  234432. + } else {
  234433. + imx_cs42888_dai[0].codec_of_node = codec_np;
  234434. + imx_cs42888_dai[0].cpu_dai_name = dev_name(&esai_pdev->dev);
  234435. + imx_cs42888_dai[0].platform_of_node = esai_np;
  234436. + imx_cs42888_dai[1].cpu_dai_name = dev_name(&asrc_pdev->dev);
  234437. + imx_cs42888_dai[1].platform_name = "imx-pcm-asrc";
  234438. + imx_cs42888_dai[2].codec_of_node = codec_np;
  234439. + imx_cs42888_dai[2].cpu_dai_name = dev_name(&esai_pdev->dev);
  234440. + snd_soc_card_imx_cs42888.num_links = 3;
  234441. + }
  234442. +
  234443. + codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  234444. + if (IS_ERR(codec_clk)) {
  234445. + ret = PTR_ERR(codec_clk);
  234446. + dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
  234447. + goto fail;
  234448. + }
  234449. + priv->mclk_freq = clk_get_rate(codec_clk);
  234450. +
  234451. + ret = of_property_read_string(codec_np, "clock-names", &mclk_name);
  234452. + if (ret) {
  234453. + dev_err(&pdev->dev, "%s: failed to get mclk source\n", __func__);
  234454. + goto fail;
  234455. + }
  234456. + if (!strcmp(mclk_name, "codec_osc"))
  234457. + priv->codec_mclk = CODEC_CLK_EXTER_OSC;
  234458. + else if (!strcmp(mclk_name, "esai"))
  234459. + priv->codec_mclk = CODEC_CLK_ESAI_HCKT;
  234460. + else {
  234461. + dev_err(&pdev->dev, "mclk source is not correct %s\n", mclk_name);
  234462. + goto fail;
  234463. + }
  234464. +
  234465. + snd_soc_card_imx_cs42888.dev = &pdev->dev;
  234466. +
  234467. + platform_set_drvdata(pdev, &snd_soc_card_imx_cs42888);
  234468. +
  234469. + ret = snd_soc_register_card(&snd_soc_card_imx_cs42888);
  234470. + if (ret)
  234471. + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  234472. +fail:
  234473. + if (esai_np)
  234474. + of_node_put(esai_np);
  234475. + if (codec_np)
  234476. + of_node_put(codec_np);
  234477. + return ret;
  234478. +}
  234479. +
  234480. +static int imx_cs42888_remove(struct platform_device *pdev)
  234481. +{
  234482. + snd_soc_unregister_card(&snd_soc_card_imx_cs42888);
  234483. + return 0;
  234484. +}
  234485. +
  234486. +static const struct of_device_id imx_cs42888_dt_ids[] = {
  234487. + { .compatible = "fsl,imx-audio-cs42888", },
  234488. + { /* sentinel */ }
  234489. +};
  234490. +
  234491. +static struct platform_driver imx_cs42888_driver = {
  234492. + .probe = imx_cs42888_probe,
  234493. + .remove = imx_cs42888_remove,
  234494. + .driver = {
  234495. + .name = "imx-cs42888",
  234496. + .owner = THIS_MODULE,
  234497. + .pm = &snd_soc_pm_ops,
  234498. + .of_match_table = imx_cs42888_dt_ids,
  234499. + },
  234500. +};
  234501. +module_platform_driver(imx_cs42888_driver);
  234502. +
  234503. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  234504. +MODULE_DESCRIPTION("ALSA SoC cs42888 Machine Layer Driver");
  234505. +MODULE_ALIAS("platform:imx-cs42888");
  234506. +MODULE_LICENSE("GPL");
  234507. diff -Nur linux-3.14.17/sound/soc/fsl/imx-hdmi.c linux-imx6-3.14/sound/soc/fsl/imx-hdmi.c
  234508. --- linux-3.14.17/sound/soc/fsl/imx-hdmi.c 1970-01-01 01:00:00.000000000 +0100
  234509. +++ linux-imx6-3.14/sound/soc/fsl/imx-hdmi.c 2014-09-11 18:06:18.714104678 +0200
  234510. @@ -0,0 +1,113 @@
  234511. +/*
  234512. + * ASoC HDMI Transmitter driver for IMX development boards
  234513. + *
  234514. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  234515. + *
  234516. + * based on stmp3780_devb_hdmi.c
  234517. + *
  234518. + * Vladimir Barinov <vbarinov@embeddedalley.com>
  234519. + *
  234520. + * Copyright 2008 SigmaTel, Inc
  234521. + * Copyright 2008 Embedded Alley Solutions, Inc
  234522. + *
  234523. + * This file is licensed under the terms of the GNU General Public License
  234524. + * version 2. This program is licensed "as is" without any warranty of any
  234525. + * kind, whether express or implied.
  234526. + */
  234527. +
  234528. +#include <linux/module.h>
  234529. +#include <linux/of_platform.h>
  234530. +#include <linux/mfd/mxc-hdmi-core.h>
  234531. +#include <sound/soc.h>
  234532. +
  234533. +#include "imx-hdmi.h"
  234534. +
  234535. +/* imx digital audio interface glue - connects codec <--> CPU */
  234536. +static struct snd_soc_dai_link imx_hdmi_dai_link = {
  234537. + .name = "i.MX HDMI Audio Tx",
  234538. + .stream_name = "i.MX HDMI Audio Tx",
  234539. + .codec_dai_name = "hdmi-hifi",
  234540. + .codec_name = "hdmi-audio-codec",
  234541. + .platform_name = "imx-hdmi-audio",
  234542. +};
  234543. +
  234544. +static struct snd_soc_card snd_soc_card_imx_hdmi = {
  234545. + .name = "imx-hdmi-soc",
  234546. + .dai_link = &imx_hdmi_dai_link,
  234547. + .num_links = 1,
  234548. +};
  234549. +
  234550. +static int imx_hdmi_audio_probe(struct platform_device *pdev)
  234551. +{
  234552. + struct device_node *hdmi_np, *np = pdev->dev.of_node;
  234553. + struct snd_soc_card *card = &snd_soc_card_imx_hdmi;
  234554. + struct platform_device *hdmi_pdev;
  234555. + int ret = 0;
  234556. +
  234557. + if (!hdmi_get_registered()) {
  234558. + dev_err(&pdev->dev, "initialize HDMI-audio failed. load HDMI-video first!\n");
  234559. + return -ENODEV;
  234560. + }
  234561. +
  234562. + hdmi_np = of_parse_phandle(np, "hdmi-controller", 0);
  234563. + if (!hdmi_np) {
  234564. + dev_err(&pdev->dev, "failed to find hdmi-audio cpudai\n");
  234565. + ret = -EINVAL;
  234566. + goto end;
  234567. + }
  234568. +
  234569. + hdmi_pdev = of_find_device_by_node(hdmi_np);
  234570. + if (!hdmi_pdev) {
  234571. + dev_err(&pdev->dev, "failed to find SSI platform device\n");
  234572. + ret = -EINVAL;
  234573. + goto end;
  234574. + }
  234575. +
  234576. + card->dev = &pdev->dev;
  234577. + card->dai_link->cpu_dai_name = dev_name(&hdmi_pdev->dev);
  234578. +
  234579. + platform_set_drvdata(pdev, card);
  234580. +
  234581. + ret = snd_soc_register_card(card);
  234582. + if (ret)
  234583. + dev_err(&pdev->dev, "failed to register card: %d\n", ret);
  234584. +
  234585. +end:
  234586. + if (hdmi_np)
  234587. + of_node_put(hdmi_np);
  234588. +
  234589. + return ret;
  234590. +}
  234591. +
  234592. +static int imx_hdmi_audio_remove(struct platform_device *pdev)
  234593. +{
  234594. + struct snd_soc_card *card = platform_get_drvdata(pdev);
  234595. +
  234596. + snd_soc_unregister_card(card);
  234597. +
  234598. + return 0;
  234599. +}
  234600. +
  234601. +static const struct of_device_id imx_hdmi_dt_ids[] = {
  234602. + { .compatible = "fsl,imx-audio-hdmi", },
  234603. + { /* sentinel */ }
  234604. +};
  234605. +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
  234606. +
  234607. +static struct platform_driver imx_hdmi_audio_driver = {
  234608. + .probe = imx_hdmi_audio_probe,
  234609. + .remove = imx_hdmi_audio_remove,
  234610. + .driver = {
  234611. + .of_match_table = imx_hdmi_dt_ids,
  234612. + .name = "imx-audio-hdmi",
  234613. + .owner = THIS_MODULE,
  234614. + .pm = &snd_soc_pm_ops,
  234615. + },
  234616. +};
  234617. +
  234618. +module_platform_driver(imx_hdmi_audio_driver);
  234619. +
  234620. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  234621. +MODULE_DESCRIPTION("IMX HDMI TX ASoC driver");
  234622. +MODULE_LICENSE("GPL");
  234623. +MODULE_ALIAS("platform:imx-audio-hdmi");
  234624. diff -Nur linux-3.14.17/sound/soc/fsl/imx-hdmi-dma.c linux-imx6-3.14/sound/soc/fsl/imx-hdmi-dma.c
  234625. --- linux-3.14.17/sound/soc/fsl/imx-hdmi-dma.c 1970-01-01 01:00:00.000000000 +0100
  234626. +++ linux-imx6-3.14/sound/soc/fsl/imx-hdmi-dma.c 2014-09-11 18:06:18.714104678 +0200
  234627. @@ -0,0 +1,1240 @@
  234628. +/*
  234629. + * imx-hdmi-dma.c -- HDMI DMA driver for ALSA Soc Audio Layer
  234630. + *
  234631. + * Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
  234632. + *
  234633. + * based on imx-pcm-dma-mx2.c
  234634. + * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
  234635. + *
  234636. + * This code is based on code copyrighted by Freescale,
  234637. + * Liam Girdwood, Javier Martin and probably others.
  234638. + *
  234639. + * This program is free software; you can redistribute it and/or modify it
  234640. + * under the terms of the GNU General Public License as published by the
  234641. + * Free Software Foundation; either version 2 of the License, or (at your
  234642. + * option) any later version.
  234643. + */
  234644. +
  234645. +#include <linux/module.h>
  234646. +#include <linux/delay.h>
  234647. +#include <linux/dma-mapping.h>
  234648. +#include <linux/mfd/mxc-hdmi-core.h>
  234649. +#include <linux/platform_data/dma-imx.h>
  234650. +
  234651. +#include <video/mxc_hdmi.h>
  234652. +
  234653. +#include "imx-hdmi.h"
  234654. +
  234655. +#define HDMI_DMA_BURST_UNSPECIFIED_LEGNTH 0
  234656. +#define HDMI_DMA_BURST_INCR4 1
  234657. +#define HDMI_DMA_BURST_INCR8 2
  234658. +#define HDMI_DMA_BURST_INCR16 3
  234659. +
  234660. +#define HDMI_BASE_ADDR 0x00120000
  234661. +
  234662. +struct hdmi_sdma_script {
  234663. + int control_reg_addr;
  234664. + int status_reg_addr;
  234665. + int dma_start_addr;
  234666. + u32 buffer[20];
  234667. +};
  234668. +
  234669. +struct hdmi_dma_priv {
  234670. + struct snd_pcm_substream *substream;
  234671. + struct platform_device *pdev;
  234672. +
  234673. + struct snd_dma_buffer hw_buffer;
  234674. + unsigned long buffer_bytes;
  234675. + unsigned long appl_bytes;
  234676. +
  234677. + int periods;
  234678. + int period_time;
  234679. + int period_bytes;
  234680. + int dma_period_bytes;
  234681. + int buffer_ratio;
  234682. +
  234683. + unsigned long offset;
  234684. +
  234685. + snd_pcm_format_t format;
  234686. + int sample_align;
  234687. + int sample_bits;
  234688. + int channels;
  234689. + int rate;
  234690. +
  234691. + int frame_idx;
  234692. +
  234693. + bool tx_active;
  234694. + spinlock_t irq_lock;
  234695. +
  234696. + /* SDMA part */
  234697. + dma_addr_t phy_hdmi_sdma_t;
  234698. + struct hdmi_sdma_script *hdmi_sdma_t;
  234699. + struct dma_chan *dma_channel;
  234700. + struct imx_dma_data dma_data;
  234701. + struct dma_async_tx_descriptor *desc;
  234702. + struct imx_hdmi_sdma_params sdma_params;
  234703. +};
  234704. +
  234705. +/* bit 0:0:0:b:p(0):c:(u)0:(v)0 */
  234706. +/* max 8 channels supported; channels are interleaved */
  234707. +static u8 g_packet_head_table[48 * 8];
  234708. +
  234709. +/* channel remapping for hdmi_dma_copy_xxxx() */
  234710. +static u8 g_channel_remap_table[24];
  234711. +
  234712. +/* default mapping tables */
  234713. +static const u8 channel_maps_alsa_cea[5][8] = {
  234714. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 0CH: no remapping */
  234715. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 2CH: no remapping */
  234716. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 4CH: no remapping */
  234717. + { 0, 1, 4, 5, 3, 2, 6, 7 }, /* 6CH: ALSA5.1 to CEA */
  234718. + { 0, 1, 6, 7, 3, 2, 4, 5 } /* 8CH: ALSA7.1 to CEA */
  234719. +};
  234720. +
  234721. +static const u8 channel_maps_cea_alsa[5][8] = {
  234722. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 0CH: no remapping */
  234723. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 2CH: no remapping */
  234724. + { 0, 1, 2, 3, 4, 5, 6, 7 }, /* 4CH: no remapping */
  234725. + { 0, 1, 5, 4, 2, 3, 6, 7 }, /* 6CH: CEA to ALSA5.1 */
  234726. + { 0, 1, 5, 4, 6, 7, 2, 3 } /* 8CH: CEA to ALSA7.1 */
  234727. +};
  234728. +
  234729. +union hdmi_audio_header_t iec_header;
  234730. +EXPORT_SYMBOL(iec_header);
  234731. +
  234732. +/*
  234733. + * Note that the period size for DMA != period size for ALSA because the
  234734. + * driver adds iec frame info to the audio samples (in hdmi_dma_copy).
  234735. + *
  234736. + * Each 4 byte subframe = 1 byte of iec data + 3 byte audio sample.
  234737. + *
  234738. + * A 16 bit audio sample becomes 32 bits including the frame info. Ratio=2
  234739. + * A 24 bit audio sample becomes 32 bits including the frame info. Ratio=3:4
  234740. + * If the 24 bit raw audio is in 32 bit words, the
  234741. + *
  234742. + * Original Packed into subframe Ratio of size Format
  234743. + * sample how many size of DMA buffer
  234744. + * (bits) bits to ALSA buffer
  234745. + * -------- ----------- -------- -------------- ------------------------
  234746. + * 16 16 32 2 SNDRV_PCM_FORMAT_S16_LE
  234747. + * 24 24 32 1.33 SNDRV_PCM_FORMAT_S24_3LE*
  234748. + * 24 32 32 1 SNDRV_PCM_FORMAT_S24_LE
  234749. + *
  234750. + * *so SNDRV_PCM_FORMAT_S24_3LE is not supported.
  234751. + */
  234752. +
  234753. +/*
  234754. + * The minimum dma period is one IEC audio frame (192 * 4 * channels).
  234755. + * The maximum dma period for the HDMI DMA is 8K.
  234756. + *
  234757. + * channels minimum maximum
  234758. + * dma period dma period
  234759. + * -------- ------------------ ----------
  234760. + * 2 192 * 4 * 2 = 1536 * 4 = 6144
  234761. + * 4 192 * 4 * 4 = 3072 * 2 = 6144
  234762. + * 6 192 * 4 * 6 = 4608 * 1 = 4608
  234763. + * 8 192 * 4 * 8 = 6144 * 1 = 6144
  234764. + *
  234765. + * Bottom line:
  234766. + * 1. Must keep the ratio of DMA buffer to ALSA buffer consistent.
  234767. + * 2. frame_idx is saved in the private data, so even if a frame cannot be
  234768. + * transmitted in a period, it can be continued in the next period. This
  234769. + * is necessary for 6 ch.
  234770. + */
  234771. +#define HDMI_DMA_PERIOD_BYTES (12288)
  234772. +#define HDMI_DMA_BUF_SIZE (1280 * 1024)
  234773. +#define HDMI_PCM_BUF_SIZE (1280 * 1024)
  234774. +
  234775. +#define hdmi_audio_debug(dev, reg) \
  234776. + dev_dbg(dev, #reg ": 0x%02x\n", hdmi_readb(reg))
  234777. +
  234778. +#ifdef DEBUG
  234779. +static void dumpregs(struct device *dev)
  234780. +{
  234781. + hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF0);
  234782. + hdmi_audio_debug(dev, HDMI_AHB_DMA_START);
  234783. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STOP);
  234784. + hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
  234785. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STRADDR0);
  234786. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STPADDR0);
  234787. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BSTADDR0);
  234788. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH0);
  234789. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MBLENGTH1);
  234790. + hdmi_audio_debug(dev, HDMI_AHB_DMA_STAT);
  234791. + hdmi_audio_debug(dev, HDMI_AHB_DMA_INT);
  234792. + hdmi_audio_debug(dev, HDMI_AHB_DMA_MASK);
  234793. + hdmi_audio_debug(dev, HDMI_AHB_DMA_POL);
  234794. + hdmi_audio_debug(dev, HDMI_AHB_DMA_CONF1);
  234795. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFSTAT);
  234796. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFINT);
  234797. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFMASK);
  234798. + hdmi_audio_debug(dev, HDMI_AHB_DMA_BUFFPOL);
  234799. + hdmi_audio_debug(dev, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  234800. + hdmi_audio_debug(dev, HDMI_IH_AHBDMAAUD_STAT0);
  234801. + hdmi_audio_debug(dev, HDMI_IH_MUTE);
  234802. +}
  234803. +
  234804. +static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv)
  234805. +{
  234806. + dev_dbg(dev, "channels = %d\n", priv->channels);
  234807. + dev_dbg(dev, "periods = %d\n", priv->periods);
  234808. + dev_dbg(dev, "period_bytes = %d\n", priv->period_bytes);
  234809. + dev_dbg(dev, "dma period_bytes = %d\n", priv->dma_period_bytes);
  234810. + dev_dbg(dev, "buffer_ratio = %d\n", priv->buffer_ratio);
  234811. + dev_dbg(dev, "hw dma buffer = 0x%08x\n", (int)priv->hw_buffer.addr);
  234812. + dev_dbg(dev, "dma buf size = %d\n", (int)priv->buffer_bytes);
  234813. + dev_dbg(dev, "sample_rate = %d\n", (int)priv->rate);
  234814. +}
  234815. +#else
  234816. +static void dumpregs(struct device *dev) {}
  234817. +static void dumppriv(struct device *dev, struct hdmi_dma_priv *priv) {}
  234818. +#endif
  234819. +
  234820. +/*
  234821. + * Conditions for DMA to work:
  234822. + * ((final_addr - initial_addr)>>2)+1) < 2k. So max period is 8k.
  234823. + * (inital_addr & 0x3) == 0
  234824. + * (final_addr & 0x3) == 0x3
  234825. + *
  234826. + * The DMA Period should be an integer multiple of the IEC 60958 audio
  234827. + * frame size, which is 768 bytes (192 * 4).
  234828. + */
  234829. +static void hdmi_dma_set_addr(int start_addr, int dma_period_bytes)
  234830. +{
  234831. + int final_addr = start_addr + dma_period_bytes - 1;
  234832. +
  234833. + hdmi_write4(start_addr, HDMI_AHB_DMA_STRADDR0);
  234834. + hdmi_write4(final_addr, HDMI_AHB_DMA_STPADDR0);
  234835. +}
  234836. +
  234837. +static void hdmi_dma_irq_set(bool set)
  234838. +{
  234839. + u8 val = hdmi_readb(HDMI_AHB_DMA_MASK);
  234840. +
  234841. + if (set)
  234842. + val |= HDMI_AHB_DMA_DONE;
  234843. + else
  234844. + val &= (u8)~HDMI_AHB_DMA_DONE;
  234845. +
  234846. + hdmi_writeb(val, HDMI_AHB_DMA_MASK);
  234847. +}
  234848. +
  234849. +static void hdmi_mask(int mask)
  234850. +{
  234851. + u8 regval = hdmi_readb(HDMI_AHB_DMA_MASK);
  234852. +
  234853. + if (mask)
  234854. + regval |= HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY;
  234855. + else
  234856. + regval &= (u8)~(HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY);
  234857. +
  234858. + hdmi_writeb(regval, HDMI_AHB_DMA_MASK);
  234859. +}
  234860. +
  234861. +static inline int odd_ones(unsigned a)
  234862. +{
  234863. + a ^= a >> 16;
  234864. + a ^= a >> 8;
  234865. + a ^= a >> 4;
  234866. + a ^= a >> 2;
  234867. + a ^= a >> 1;
  234868. +
  234869. + return a & 1;
  234870. +}
  234871. +
  234872. +/* Add frame information for one pcm subframe */
  234873. +static u32 hdmi_dma_add_frame_info(struct hdmi_dma_priv *priv,
  234874. + u32 pcm_data, int subframe_idx)
  234875. +{
  234876. + union hdmi_audio_dma_data_t subframe;
  234877. + union hdmi_audio_header_t tmp_header;
  234878. +
  234879. + subframe.U = 0;
  234880. +
  234881. + if (priv->frame_idx < 42) {
  234882. + tmp_header = iec_header;
  234883. +
  234884. + /* fill v (validity) */
  234885. + subframe.B.v = tmp_header.B.linear_pcm;
  234886. +
  234887. + /* fill c (channel status) */
  234888. + if (tmp_header.B.linear_pcm == 0)
  234889. + tmp_header.B.channel = subframe_idx + 1;
  234890. + subframe.B.c = tmp_header.U >> priv->frame_idx;
  234891. + } else {
  234892. + /* fill v (validity), c is always zero */
  234893. + subframe.B.v = iec_header.B.linear_pcm;
  234894. + }
  234895. +
  234896. + /* fill data */
  234897. + if (priv->sample_bits == 16)
  234898. + pcm_data <<= 8;
  234899. + subframe.B.data = pcm_data;
  234900. +
  234901. + /* fill p (parity) Note: Do not include b ! */
  234902. + subframe.B.p = odd_ones(subframe.U);
  234903. +
  234904. + /* fill b (start-of-block) */
  234905. + if (priv->frame_idx == 0)
  234906. + subframe.B.b = 1;
  234907. +
  234908. + return subframe.U;
  234909. +}
  234910. +
  234911. +static void init_table(int channels)
  234912. +{
  234913. + int i, map_sel, ch;
  234914. + unsigned char *p = g_packet_head_table;
  234915. + union hdmi_audio_header_t tmp_header = iec_header;
  234916. +
  234917. + for (i = 0; i < 48; i++) {
  234918. + int b = 0;
  234919. + if (i == 0)
  234920. + b = 1;
  234921. +
  234922. + for (ch = 0; ch < channels; ch++) {
  234923. + int c = 0;
  234924. + if (i < 42) {
  234925. + tmp_header.B.channel = ch + 1;
  234926. + c = (tmp_header.U >> i) & 0x1;
  234927. + }
  234928. + /* preset bit p as c */
  234929. + *p++ = (b << 4) | (c << 2) | (c << 3);
  234930. + }
  234931. + }
  234932. +
  234933. + map_sel = channels / 2;
  234934. + for (i = 0; i < 24; i++) {
  234935. + g_channel_remap_table[i] = (i / channels) * channels +
  234936. + channel_maps_cea_alsa[map_sel][i % channels];
  234937. + }
  234938. +}
  234939. +
  234940. +/* Optimization for IEC head */
  234941. +static void hdmi_dma_copy_16_c_lut(u16 *src, u32 *dst, int samples,
  234942. + u8 *lookup_table)
  234943. +{
  234944. + u32 sample, head;
  234945. + int i = 0;
  234946. +
  234947. + while (samples--) {
  234948. + /* get source sample */
  234949. + sample = src[g_channel_remap_table[i]];
  234950. +
  234951. + /* get packet header and p-bit */
  234952. + head = *lookup_table++ ^ (odd_ones(sample) << 3);
  234953. +
  234954. + /* store sample and header */
  234955. + *dst++ = (head << 24) | (sample << 8);
  234956. +
  234957. + if (++i == 24) {
  234958. + src += 24;
  234959. + i = 0;
  234960. + }
  234961. + }
  234962. +}
  234963. +
  234964. +static void hdmi_dma_copy_16_c_fast(u16 *src, u32 *dst, int samples)
  234965. +{
  234966. + u32 sample;
  234967. + int i = 0;
  234968. +
  234969. + while (samples--) {
  234970. + /* get source sample */
  234971. + sample = src[g_channel_remap_table[i]];
  234972. +
  234973. + /* store sample and p-bit */
  234974. + *dst++ = (odd_ones(sample) << (3+24)) | (sample << 8);
  234975. +
  234976. + if (++i == 24) {
  234977. + src += 24;
  234978. + i = 0;
  234979. + }
  234980. + }
  234981. +}
  234982. +
  234983. +static void hdmi_dma_copy_24_c_lut(u32 *src, u32 *dst, int samples,
  234984. + u8 *lookup_table)
  234985. +{
  234986. + u32 sample, head;
  234987. + int i = 0;
  234988. +
  234989. + while (samples--) {
  234990. + /* get source sample */
  234991. + sample = src[g_channel_remap_table[i]] & 0x00ffffff;
  234992. +
  234993. + /* get packet header and p-bit */
  234994. + head = *lookup_table++ ^ (odd_ones(sample) << 3);
  234995. +
  234996. + /* store sample and header */
  234997. + *dst++ = (head << 24) | sample;
  234998. +
  234999. + if (++i == 24) {
  235000. + src += 24;
  235001. + i = 0;
  235002. + }
  235003. + }
  235004. +}
  235005. +
  235006. +static void hdmi_dma_copy_24_c_fast(u32 *src, u32 *dst, int samples)
  235007. +{
  235008. + u32 sample;
  235009. + int i = 0;
  235010. +
  235011. + while (samples--) {
  235012. + /* get source sample */
  235013. + sample = src[g_channel_remap_table[i]] & 0x00ffffff;
  235014. +
  235015. + /* store sample and p-bit */
  235016. + *dst++ = (odd_ones(sample) << (3+24)) | sample;
  235017. +
  235018. + if (++i == 24) {
  235019. + src += 24;
  235020. + i = 0;
  235021. + }
  235022. + }
  235023. +}
  235024. +
  235025. +static void hdmi_mmap_copy(u8 *src, int samplesize, u32 *dst, int framecnt, int channelcnt)
  235026. +{
  235027. + /* split input frames into 192-frame each */
  235028. + int count_in_192 = (framecnt + 191) / 192;
  235029. + int i;
  235030. +
  235031. + typedef void (*fn_copy_lut)(u8 *src, u32 *dst, int samples, u8 *lookup_table);
  235032. + typedef void (*fn_copy_fast)(u8 *src, u32 *dst, int samples);
  235033. + fn_copy_lut copy_lut;
  235034. + fn_copy_fast copy_fast;
  235035. +
  235036. + if (samplesize == 4) {
  235037. + copy_lut = (fn_copy_lut)hdmi_dma_copy_24_c_lut;
  235038. + copy_fast = (fn_copy_fast)hdmi_dma_copy_24_c_fast;
  235039. + } else {
  235040. + copy_lut = (fn_copy_lut)hdmi_dma_copy_16_c_lut;
  235041. + copy_fast = (fn_copy_fast)hdmi_dma_copy_16_c_fast;
  235042. + }
  235043. +
  235044. + for (i = 0; i < count_in_192; i++) {
  235045. + int count, samples;
  235046. +
  235047. + /* handles frame index [0, 48) */
  235048. + count = (framecnt < 48) ? framecnt : 48;
  235049. + samples = count * channelcnt;
  235050. + copy_lut(src, dst, samples, g_packet_head_table);
  235051. + framecnt -= count;
  235052. + if (framecnt == 0)
  235053. + break;
  235054. +
  235055. + src += samples * samplesize;
  235056. + dst += samples;
  235057. +
  235058. + /* handles frame index [48, 192) */
  235059. + count = (framecnt < 192 - 48) ? framecnt : 192 - 48;
  235060. + samples = count * channelcnt;
  235061. + copy_fast(src, dst, samples);
  235062. + framecnt -= count;
  235063. + src += samples * samplesize;
  235064. + dst += samples;
  235065. + }
  235066. +}
  235067. +
  235068. +static void hdmi_dma_mmap_copy(struct snd_pcm_substream *substream,
  235069. + int offset, int count)
  235070. +{
  235071. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  235072. + struct snd_pcm_runtime *runtime = substream->runtime;
  235073. + struct hdmi_dma_priv *priv = runtime->private_data;
  235074. + struct device *dev = rtd->platform->dev;
  235075. + u32 framecount, *dst;
  235076. +
  235077. + framecount = count / (priv->sample_align * priv->channels);
  235078. +
  235079. + /* hw_buffer is the destination for pcm data plus frame info. */
  235080. + dst = (u32 *)(priv->hw_buffer.area + (offset * priv->buffer_ratio));
  235081. +
  235082. + switch (priv->format) {
  235083. + case SNDRV_PCM_FORMAT_S16_LE:
  235084. + case SNDRV_PCM_FORMAT_S24_LE:
  235085. + /* dma_buffer is the mmapped buffer we are copying pcm from. */
  235086. + hdmi_mmap_copy(runtime->dma_area + offset,
  235087. + priv->sample_align, dst, framecount, priv->channels);
  235088. + break;
  235089. + default:
  235090. + dev_err(dev, "unsupported sample format %s\n",
  235091. + snd_pcm_format_name(priv->format));
  235092. + return;
  235093. + }
  235094. +}
  235095. +
  235096. +static void hdmi_dma_data_copy(struct snd_pcm_substream *substream,
  235097. + struct hdmi_dma_priv *priv, char type)
  235098. +{
  235099. + struct snd_pcm_runtime *runtime = substream->runtime;
  235100. + unsigned long offset, count, appl_bytes, space_to_end;
  235101. +
  235102. + if (runtime->access != SNDRV_PCM_ACCESS_MMAP_INTERLEAVED)
  235103. + return;
  235104. +
  235105. + appl_bytes = frames_to_bytes(runtime, runtime->status->hw_ptr);
  235106. +
  235107. + switch (type) {
  235108. + case 'p':
  235109. + offset = (appl_bytes + 2 * priv->period_bytes) % priv->buffer_bytes;
  235110. + count = priv->period_bytes;
  235111. + space_to_end = priv->period_bytes;
  235112. + break;
  235113. + case 'b':
  235114. + offset = appl_bytes % priv->buffer_bytes;
  235115. + count = priv->buffer_bytes;
  235116. + space_to_end = priv->buffer_bytes - offset;
  235117. + break;
  235118. + default:
  235119. + return;
  235120. + }
  235121. +
  235122. + if (count <= space_to_end) {
  235123. + hdmi_dma_mmap_copy(substream, offset, count);
  235124. + } else {
  235125. + hdmi_dma_mmap_copy(substream, offset, space_to_end);
  235126. + hdmi_dma_mmap_copy(substream, 0, count - space_to_end);
  235127. + }
  235128. +}
  235129. +
  235130. +static void hdmi_sdma_callback(void *data)
  235131. +{
  235132. + struct hdmi_dma_priv *priv = (struct hdmi_dma_priv *)data;
  235133. + struct snd_pcm_substream *substream = priv->substream;
  235134. + struct snd_pcm_runtime *runtime = substream->runtime;
  235135. + unsigned long flags;
  235136. +
  235137. + spin_lock_irqsave(&priv->irq_lock, flags);
  235138. +
  235139. + if (runtime && runtime->dma_area && priv->tx_active) {
  235140. + priv->offset += priv->period_bytes;
  235141. + priv->offset %= priv->period_bytes * priv->periods;
  235142. +
  235143. + /* Copy data by period_bytes */
  235144. + hdmi_dma_data_copy(substream, priv, 'p');
  235145. +
  235146. + snd_pcm_period_elapsed(substream);
  235147. + }
  235148. +
  235149. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  235150. +
  235151. + return;
  235152. +}
  235153. +
  235154. +static int hdmi_dma_set_thrsld_incrtype(struct device *dev, int channels)
  235155. +{
  235156. + u8 mask = HDMI_AHB_DMA_CONF0_BURST_MODE | HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK;
  235157. + u8 val = hdmi_readb(HDMI_AHB_DMA_CONF0) & ~mask;
  235158. + int incr_type, threshold;
  235159. +
  235160. + switch (hdmi_readb(HDMI_REVISION_ID)) {
  235161. + case 0x0a:
  235162. + incr_type = HDMI_DMA_BURST_INCR4;
  235163. + if (channels == 2)
  235164. + threshold = 126;
  235165. + else
  235166. + threshold = 124;
  235167. + break;
  235168. + case 0x1a:
  235169. + incr_type = HDMI_DMA_BURST_INCR8;
  235170. + threshold = 128;
  235171. + break;
  235172. + default:
  235173. + dev_err(dev, "unknown hdmi controller!\n");
  235174. + return -ENODEV;
  235175. + }
  235176. +
  235177. + hdmi_writeb(threshold, HDMI_AHB_DMA_THRSLD);
  235178. +
  235179. + switch (incr_type) {
  235180. + case HDMI_DMA_BURST_UNSPECIFIED_LEGNTH:
  235181. + break;
  235182. + case HDMI_DMA_BURST_INCR4:
  235183. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE;
  235184. + break;
  235185. + case HDMI_DMA_BURST_INCR8:
  235186. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
  235187. + HDMI_AHB_DMA_CONF0_INCR8;
  235188. + break;
  235189. + case HDMI_DMA_BURST_INCR16:
  235190. + val |= HDMI_AHB_DMA_CONF0_BURST_MODE |
  235191. + HDMI_AHB_DMA_CONF0_INCR16;
  235192. + break;
  235193. + default:
  235194. + dev_err(dev, "invalid increment type: %d!", incr_type);
  235195. + return -EINVAL;
  235196. + }
  235197. +
  235198. + hdmi_writeb(val, HDMI_AHB_DMA_CONF0);
  235199. +
  235200. + hdmi_audio_debug(dev, HDMI_AHB_DMA_THRSLD);
  235201. +
  235202. + return 0;
  235203. +}
  235204. +
  235205. +static int hdmi_dma_configure_dma(struct device *dev, int channels)
  235206. +{
  235207. + int ret;
  235208. + static u8 chan_enable[] = { 0x00, 0x03, 0x33, 0x3f, 0xff };
  235209. +
  235210. + if (channels <= 0 || channels > 8 || channels % 2 != 0) {
  235211. + dev_err(dev, "unsupported channel number: %d\n", channels);
  235212. + return -EINVAL;
  235213. + }
  235214. +
  235215. + hdmi_audio_writeb(AHB_DMA_CONF0, EN_HLOCK, 0x1);
  235216. +
  235217. + ret = hdmi_dma_set_thrsld_incrtype(dev, channels);
  235218. + if (ret)
  235219. + return ret;
  235220. +
  235221. + hdmi_writeb(chan_enable[channels / 2], HDMI_AHB_DMA_CONF1);
  235222. +
  235223. + return 0;
  235224. +}
  235225. +
  235226. +static void hdmi_dma_init_iec_header(void)
  235227. +{
  235228. + iec_header.U = 0;
  235229. +
  235230. + iec_header.B.consumer = 0; /* Consumer use */
  235231. + iec_header.B.linear_pcm = 0; /* linear pcm audio */
  235232. + iec_header.B.copyright = 1; /* no copyright */
  235233. + iec_header.B.pre_emphasis = 0; /* 2 channels without pre-emphasis */
  235234. + iec_header.B.mode = 0; /* Mode 0 */
  235235. +
  235236. + iec_header.B.category_code = 0;
  235237. +
  235238. + iec_header.B.source = 2; /* stereo */
  235239. + iec_header.B.channel = 0;
  235240. +
  235241. + iec_header.B.sample_freq = 0x02; /* 48 KHz */
  235242. + iec_header.B.clock_acc = 0; /* Level II */
  235243. +
  235244. + iec_header.B.word_length = 0x02; /* 16 bits */
  235245. + iec_header.B.org_sample_freq = 0x0D; /* 48 KHz */
  235246. +
  235247. + iec_header.B.cgms_a = 0; /* Copying is permitted without restriction */
  235248. +}
  235249. +
  235250. +static int hdmi_dma_update_iec_header(struct snd_pcm_substream *substream)
  235251. +{
  235252. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  235253. + struct snd_pcm_runtime *runtime = substream->runtime;
  235254. + struct hdmi_dma_priv *priv = runtime->private_data;
  235255. + struct device *dev = rtd->platform->dev;
  235256. +
  235257. + iec_header.B.source = priv->channels;
  235258. +
  235259. + switch (priv->rate) {
  235260. + case 32000:
  235261. + iec_header.B.sample_freq = 0x03;
  235262. + iec_header.B.org_sample_freq = 0x0C;
  235263. + break;
  235264. + case 44100:
  235265. + iec_header.B.sample_freq = 0x00;
  235266. + iec_header.B.org_sample_freq = 0x0F;
  235267. + break;
  235268. + case 48000:
  235269. + iec_header.B.sample_freq = 0x02;
  235270. + iec_header.B.org_sample_freq = 0x0D;
  235271. + break;
  235272. + case 88200:
  235273. + iec_header.B.sample_freq = 0x08;
  235274. + iec_header.B.org_sample_freq = 0x07;
  235275. + break;
  235276. + case 96000:
  235277. + iec_header.B.sample_freq = 0x0A;
  235278. + iec_header.B.org_sample_freq = 0x05;
  235279. + break;
  235280. + case 176400:
  235281. + iec_header.B.sample_freq = 0x0C;
  235282. + iec_header.B.org_sample_freq = 0x03;
  235283. + break;
  235284. + case 192000:
  235285. + iec_header.B.sample_freq = 0x0E;
  235286. + iec_header.B.org_sample_freq = 0x01;
  235287. + break;
  235288. + default:
  235289. + dev_err(dev, "unsupported sample rate\n");
  235290. + return -EFAULT;
  235291. + }
  235292. +
  235293. + switch (priv->format) {
  235294. + case SNDRV_PCM_FORMAT_S16_LE:
  235295. + iec_header.B.word_length = 0x02;
  235296. + break;
  235297. + case SNDRV_PCM_FORMAT_S24_LE:
  235298. + iec_header.B.word_length = 0x0b;
  235299. + break;
  235300. + default:
  235301. + return -EFAULT;
  235302. + }
  235303. +
  235304. + return 0;
  235305. +}
  235306. +
  235307. +/*
  235308. + * The HDMI block transmits the audio data without adding any of the audio
  235309. + * frame bits. So we have to copy the raw dma data from the ALSA buffer
  235310. + * to the DMA buffer, adding the frame information.
  235311. + */
  235312. +static int hdmi_dma_copy(struct snd_pcm_substream *substream, int channel,
  235313. + snd_pcm_uframes_t pos, void __user *buf,
  235314. + snd_pcm_uframes_t frames)
  235315. +{
  235316. + struct snd_pcm_runtime *runtime = substream->runtime;
  235317. + struct hdmi_dma_priv *priv = runtime->private_data;
  235318. + unsigned int count = frames_to_bytes(runtime, frames);
  235319. + unsigned int pos_bytes = frames_to_bytes(runtime, pos);
  235320. + int channel_no, pcm_idx, subframe_idx, bits_left, sample_bits, map_sel;
  235321. + u32 pcm_data[8], pcm_temp, *hw_buf, sample_block, inc_mask;
  235322. +
  235323. + /* Adding frame info to pcm data from userspace and copy to hw_buffer */
  235324. + hw_buf = (u32 *)(priv->hw_buffer.area + (pos_bytes * priv->buffer_ratio));
  235325. +
  235326. + sample_bits = priv->sample_align * 8;
  235327. + sample_block = priv->sample_align * priv->channels;
  235328. +
  235329. + if (iec_header.B.linear_pcm == 0) {
  235330. + map_sel = priv->channels / 2;
  235331. + inc_mask = 1 << (priv->channels - 1);
  235332. + } else {
  235333. + map_sel = 0;
  235334. + inc_mask = 0xaa;
  235335. + }
  235336. +
  235337. + while (count > 0) {
  235338. + if (copy_from_user(pcm_data, buf, sample_block))
  235339. + return -EFAULT;
  235340. +
  235341. + buf += sample_block;
  235342. + count -= sample_block;
  235343. +
  235344. + channel_no = pcm_idx = 0;
  235345. + do {
  235346. + pcm_temp = pcm_data[pcm_idx++];
  235347. + bits_left = 32;
  235348. + for (;;) {
  235349. + /* re-map channels */
  235350. + subframe_idx = channel_maps_alsa_cea[map_sel][channel_no];
  235351. +
  235352. + /* Save the header info to the audio dma buffer */
  235353. + hw_buf[subframe_idx] = hdmi_dma_add_frame_info(
  235354. + priv, pcm_temp, subframe_idx);
  235355. +
  235356. + if (inc_mask & (1 << channel_no)) {
  235357. + if (++priv->frame_idx == 192)
  235358. + priv->frame_idx = 0;
  235359. + }
  235360. +
  235361. + channel_no++;
  235362. +
  235363. + if (bits_left <= sample_bits)
  235364. + break;
  235365. +
  235366. + bits_left -= sample_bits;
  235367. + pcm_temp >>= sample_bits;
  235368. + }
  235369. + } while (channel_no < priv->channels);
  235370. +
  235371. + hw_buf += priv->channels;
  235372. + }
  235373. +
  235374. + return 0;
  235375. +}
  235376. +
  235377. +static int hdmi_sdma_initbuf(struct device *dev, struct hdmi_dma_priv *priv)
  235378. +{
  235379. + struct hdmi_sdma_script *hdmi_sdma_t = priv->hdmi_sdma_t;
  235380. + u32 *head, *tail, i;
  235381. +
  235382. + if (!hdmi_sdma_t) {
  235383. + dev_err(dev, "hdmi private addr invalid!!!\n");
  235384. + return -EINVAL;
  235385. + }
  235386. +
  235387. + hdmi_sdma_t->control_reg_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_START;
  235388. + hdmi_sdma_t->status_reg_addr = HDMI_BASE_ADDR + HDMI_IH_AHBDMAAUD_STAT0;
  235389. + hdmi_sdma_t->dma_start_addr = HDMI_BASE_ADDR + HDMI_AHB_DMA_STRADDR0;
  235390. +
  235391. + head = &hdmi_sdma_t->buffer[0];
  235392. + tail = &hdmi_sdma_t->buffer[1];
  235393. +
  235394. + for (i = 0; i < priv->sdma_params.buffer_num; i++) {
  235395. + *head = priv->hw_buffer.addr + i * priv->period_bytes * priv->buffer_ratio;
  235396. + *tail = *head + priv->dma_period_bytes - 1;
  235397. + head += 2;
  235398. + tail += 2;
  235399. + }
  235400. +
  235401. + return 0;
  235402. +}
  235403. +
  235404. +static int hdmi_sdma_config(struct snd_pcm_substream *substream,
  235405. + struct hdmi_dma_priv *priv)
  235406. +{
  235407. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  235408. + struct device *dai_dev = &priv->pdev->dev;
  235409. + struct device *dev = rtd->platform->dev;
  235410. + struct dma_slave_config slave_config;
  235411. + int ret;
  235412. +
  235413. + priv->dma_channel = dma_request_slave_channel(dai_dev, "tx");
  235414. + if (priv->dma_channel == NULL) {
  235415. + dev_err(dev, "failed to alloc dma channel\n");
  235416. + return -EBUSY;
  235417. + }
  235418. +
  235419. + priv->dma_data.data_addr1 = &priv->sdma_params.buffer_num;
  235420. + priv->dma_data.data_addr2 = &priv->sdma_params.phyaddr;
  235421. + priv->dma_channel->private = &priv->dma_data;
  235422. +
  235423. + slave_config.direction = DMA_TRANS_NONE;
  235424. + slave_config.dma_request0 = 0;
  235425. + slave_config.dma_request1 = 0;
  235426. +
  235427. + ret = dmaengine_slave_config(priv->dma_channel, &slave_config);
  235428. + if (ret) {
  235429. + dev_err(dev, "failed to config slave dma\n");
  235430. + return -EINVAL;
  235431. + }
  235432. +
  235433. + return 0;
  235434. +}
  235435. +
  235436. +static int hdmi_dma_hw_free(struct snd_pcm_substream *substream)
  235437. +{
  235438. + struct snd_pcm_runtime *runtime = substream->runtime;
  235439. + struct hdmi_dma_priv *priv = runtime->private_data;
  235440. +
  235441. + if (priv->dma_channel) {
  235442. + dma_release_channel(priv->dma_channel);
  235443. + priv->dma_channel = NULL;
  235444. + }
  235445. +
  235446. + return 0;
  235447. +}
  235448. +
  235449. +static int hdmi_dma_hw_params(struct snd_pcm_substream *substream,
  235450. + struct snd_pcm_hw_params *params)
  235451. +{
  235452. + struct snd_pcm_runtime *runtime = substream->runtime;
  235453. + struct hdmi_dma_priv *priv = runtime->private_data;
  235454. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  235455. + struct device *dev = rtd->platform->dev;
  235456. + int ret;
  235457. +
  235458. + priv->buffer_bytes = params_buffer_bytes(params);
  235459. + priv->periods = params_periods(params);
  235460. + priv->period_bytes = params_period_bytes(params);
  235461. + priv->channels = params_channels(params);
  235462. + priv->format = params_format(params);
  235463. + priv->rate = params_rate(params);
  235464. +
  235465. + priv->offset = 0;
  235466. + priv->period_time = HZ / (priv->rate / params_period_size(params));
  235467. +
  235468. + switch (priv->format) {
  235469. + case SNDRV_PCM_FORMAT_S16_LE:
  235470. + priv->buffer_ratio = 2;
  235471. + priv->sample_align = 2;
  235472. + priv->sample_bits = 16;
  235473. + break;
  235474. + case SNDRV_PCM_FORMAT_S24_LE:
  235475. + /* 24 bit audio in 32 bit word */
  235476. + priv->buffer_ratio = 1;
  235477. + priv->sample_align = 4;
  235478. + priv->sample_bits = 24;
  235479. + break;
  235480. + default:
  235481. + dev_err(dev, "unsupported sample format: %d\n", priv->format);
  235482. + return -EINVAL;
  235483. + }
  235484. +
  235485. + priv->dma_period_bytes = priv->period_bytes * priv->buffer_ratio;
  235486. + priv->sdma_params.buffer_num = priv->periods;
  235487. + priv->sdma_params.phyaddr = priv->phy_hdmi_sdma_t;
  235488. +
  235489. + ret = hdmi_sdma_initbuf(dev, priv);
  235490. + if (ret)
  235491. + return ret;
  235492. +
  235493. + ret = hdmi_sdma_config(substream, priv);
  235494. + if (ret)
  235495. + return ret;
  235496. +
  235497. + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  235498. +
  235499. + ret = hdmi_dma_configure_dma(dev, priv->channels);
  235500. + if (ret)
  235501. + return ret;
  235502. +
  235503. + hdmi_dma_set_addr(priv->hw_buffer.addr, priv->dma_period_bytes);
  235504. +
  235505. + dumppriv(dev, priv);
  235506. +
  235507. + hdmi_dma_update_iec_header(substream);
  235508. +
  235509. + /* Init par for mmap optimizate */
  235510. + init_table(priv->channels);
  235511. +
  235512. + priv->appl_bytes = 0;
  235513. + priv->frame_idx = 0;
  235514. +
  235515. + return 0;
  235516. +}
  235517. +
  235518. +static void hdmi_dma_trigger_init(struct snd_pcm_substream *substream,
  235519. + struct hdmi_dma_priv *priv)
  235520. +{
  235521. + unsigned long status;
  235522. + bool hbr;
  235523. +
  235524. + /*
  235525. + * Set HBR mode (>192kHz IEC-61937 HD audio bitstreaming).
  235526. + * This is done this late because userspace may alter the AESx
  235527. + * parameters until the stream is finally prepared.
  235528. + */
  235529. + hbr = (iec_header.B.linear_pcm != 0 && priv->channels == 8);
  235530. + hdmi_audio_writeb(AHB_DMA_CONF0, HBR, !!hbr);
  235531. +
  235532. + /*
  235533. + * Override AES3 - parameter: This is a temporary hack for
  235534. + * callers that provide incorrect information when opening
  235535. + * the device. 0x09 (i.e. 768K) is the only acceptable value.
  235536. + */
  235537. + if (hbr) {
  235538. + iec_header.B.sample_freq = 0x09;
  235539. + iec_header.B.org_sample_freq = 0x00;
  235540. + }
  235541. +
  235542. + priv->offset = 0;
  235543. +
  235544. + /* Copy data by buffer_bytes */
  235545. + hdmi_dma_data_copy(substream, priv, 'b');
  235546. +
  235547. + hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
  235548. +
  235549. + /* Delay after reset */
  235550. + udelay(1);
  235551. +
  235552. + status = hdmi_readb(HDMI_IH_AHBDMAAUD_STAT0);
  235553. + hdmi_writeb(status, HDMI_IH_AHBDMAAUD_STAT0);
  235554. +}
  235555. +
  235556. +static int hdmi_dma_prepare_and_submit(struct snd_pcm_substream *substream,
  235557. + struct hdmi_dma_priv *priv)
  235558. +{
  235559. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  235560. + struct device *dev = rtd->platform->dev;
  235561. +
  235562. + priv->desc = dmaengine_prep_dma_cyclic(priv->dma_channel, 0, 0, 0,
  235563. + DMA_TRANS_NONE, 0);
  235564. + if (!priv->desc) {
  235565. + dev_err(dev, "failed to prepare slave dma\n");
  235566. + return -EINVAL;
  235567. + }
  235568. +
  235569. + priv->desc->callback = hdmi_sdma_callback;
  235570. + priv->desc->callback_param = (void *)priv;
  235571. + dmaengine_submit(priv->desc);
  235572. +
  235573. + return 0;
  235574. +}
  235575. +
  235576. +static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
  235577. +{
  235578. + struct snd_pcm_runtime *runtime = substream->runtime;
  235579. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  235580. + struct hdmi_dma_priv *priv = runtime->private_data;
  235581. + struct device *dev = rtd->platform->dev;
  235582. + int ret;
  235583. +
  235584. + switch (cmd) {
  235585. + case SNDRV_PCM_TRIGGER_START:
  235586. + case SNDRV_PCM_TRIGGER_RESUME:
  235587. + if (!check_hdmi_state())
  235588. + return 0;
  235589. + hdmi_dma_trigger_init(substream, priv);
  235590. +
  235591. + dumpregs(dev);
  235592. +
  235593. + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  235594. + priv->tx_active = true;
  235595. + hdmi_audio_writeb(AHB_DMA_START, START, 0x1);
  235596. + hdmi_dma_irq_set(false);
  235597. + hdmi_set_dma_mode(1);
  235598. + ret = hdmi_dma_prepare_and_submit(substream, priv);
  235599. + if (ret)
  235600. + return ret;
  235601. + dma_async_issue_pending(priv->desc->chan);
  235602. + break;
  235603. + case SNDRV_PCM_TRIGGER_STOP:
  235604. + case SNDRV_PCM_TRIGGER_SUSPEND:
  235605. + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  235606. + dmaengine_terminate_all(priv->dma_channel);
  235607. + hdmi_set_dma_mode(0);
  235608. + hdmi_dma_irq_set(true);
  235609. + hdmi_audio_writeb(AHB_DMA_STOP, STOP, 0x1);
  235610. + priv->tx_active = false;
  235611. + break;
  235612. + default:
  235613. + return -EINVAL;
  235614. + }
  235615. +
  235616. + return 0;
  235617. +}
  235618. +
  235619. +static snd_pcm_uframes_t hdmi_dma_pointer(struct snd_pcm_substream *substream)
  235620. +{
  235621. + struct snd_pcm_runtime *runtime = substream->runtime;
  235622. + struct hdmi_dma_priv *priv = runtime->private_data;
  235623. +
  235624. + return bytes_to_frames(runtime, priv->offset);
  235625. +}
  235626. +
  235627. +static struct snd_pcm_hardware snd_imx_hardware = {
  235628. + .info = SNDRV_PCM_INFO_INTERLEAVED |
  235629. + SNDRV_PCM_INFO_BLOCK_TRANSFER |
  235630. + SNDRV_PCM_INFO_MMAP |
  235631. + SNDRV_PCM_INFO_MMAP_VALID |
  235632. + SNDRV_PCM_INFO_PAUSE |
  235633. + SNDRV_PCM_INFO_RESUME,
  235634. + .formats = MXC_HDMI_FORMATS_PLAYBACK,
  235635. + .rate_min = 32000,
  235636. + .channels_min = 2,
  235637. + .channels_max = 8,
  235638. + .buffer_bytes_max = HDMI_PCM_BUF_SIZE,
  235639. + .period_bytes_min = HDMI_DMA_PERIOD_BYTES / 2,
  235640. + .period_bytes_max = HDMI_DMA_PERIOD_BYTES / 2,
  235641. + .periods_min = 8,
  235642. + .periods_max = HDMI_DMA_BUF_SIZE / HDMI_DMA_PERIOD_BYTES,
  235643. + .fifo_size = 0,
  235644. +};
  235645. +
  235646. +static void hdmi_dma_irq_enable(struct hdmi_dma_priv *priv)
  235647. +{
  235648. + unsigned long flags;
  235649. +
  235650. + hdmi_writeb(0xff, HDMI_AHB_DMA_POL);
  235651. + hdmi_writeb(0xff, HDMI_AHB_DMA_BUFFPOL);
  235652. +
  235653. + spin_lock_irqsave(&priv->irq_lock, flags);
  235654. +
  235655. + hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
  235656. + hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  235657. + hdmi_dma_irq_set(false);
  235658. + hdmi_mask(0);
  235659. +
  235660. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  235661. +}
  235662. +
  235663. +static void hdmi_dma_irq_disable(struct hdmi_dma_priv *priv)
  235664. +{
  235665. + unsigned long flags;
  235666. +
  235667. + spin_lock_irqsave(&priv->irq_lock, flags);
  235668. +
  235669. + hdmi_dma_irq_set(true);
  235670. + hdmi_writeb(0x0, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  235671. + hdmi_writeb(0xff, HDMI_IH_AHBDMAAUD_STAT0);
  235672. + hdmi_mask(1);
  235673. +
  235674. + spin_unlock_irqrestore(&priv->irq_lock, flags);
  235675. +}
  235676. +
  235677. +static int hdmi_dma_open(struct snd_pcm_substream *substream)
  235678. +{
  235679. + struct snd_pcm_runtime *runtime = substream->runtime;
  235680. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  235681. + struct device *dev = rtd->platform->dev;
  235682. + struct hdmi_dma_priv *priv = dev_get_drvdata(dev);
  235683. + int ret;
  235684. +
  235685. + runtime->private_data = priv;
  235686. +
  235687. + ret = mxc_hdmi_register_audio(substream);
  235688. + if (ret < 0) {
  235689. + dev_err(dev, "HDMI Video is not ready!\n");
  235690. + return ret;
  235691. + }
  235692. +
  235693. + hdmi_audio_writeb(AHB_DMA_CONF0, SW_FIFO_RST, 0x1);
  235694. +
  235695. + ret = snd_pcm_hw_constraint_integer(substream->runtime,
  235696. + SNDRV_PCM_HW_PARAM_PERIODS);
  235697. + if (ret < 0)
  235698. + return ret;
  235699. +
  235700. + snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
  235701. +
  235702. + hdmi_dma_irq_enable(priv);
  235703. +
  235704. + return 0;
  235705. +}
  235706. +
  235707. +static int hdmi_dma_close(struct snd_pcm_substream *substream)
  235708. +{
  235709. + struct snd_pcm_runtime *runtime = substream->runtime;
  235710. + struct hdmi_dma_priv *priv = runtime->private_data;
  235711. +
  235712. + hdmi_dma_irq_disable(priv);
  235713. + mxc_hdmi_unregister_audio(substream);
  235714. +
  235715. + return 0;
  235716. +}
  235717. +
  235718. +static struct snd_pcm_ops imx_hdmi_dma_pcm_ops = {
  235719. + .open = hdmi_dma_open,
  235720. + .close = hdmi_dma_close,
  235721. + .ioctl = snd_pcm_lib_ioctl,
  235722. + .hw_params = hdmi_dma_hw_params,
  235723. + .hw_free = hdmi_dma_hw_free,
  235724. + .trigger = hdmi_dma_trigger,
  235725. + .pointer = hdmi_dma_pointer,
  235726. + .copy = hdmi_dma_copy,
  235727. +};
  235728. +
  235729. +static int imx_hdmi_dma_pcm_new(struct snd_soc_pcm_runtime *rtd)
  235730. +{
  235731. + struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
  235732. + struct snd_card *card = rtd->card->snd_card;
  235733. + struct snd_pcm_substream *substream;
  235734. + struct snd_pcm *pcm = rtd->pcm;
  235735. + u64 dma_mask = DMA_BIT_MASK(32);
  235736. + int ret = 0;
  235737. +
  235738. + if (!card->dev->dma_mask)
  235739. + card->dev->dma_mask = &dma_mask;
  235740. + if (!card->dev->coherent_dma_mask)
  235741. + card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
  235742. +
  235743. + substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
  235744. +
  235745. + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  235746. + HDMI_PCM_BUF_SIZE, &substream->dma_buffer);
  235747. + if (ret) {
  235748. + dev_err(card->dev, "failed to alloc playback dma buffer\n");
  235749. + return ret;
  235750. + }
  235751. +
  235752. + priv->substream = substream;
  235753. +
  235754. + /* Alloc the hw_buffer */
  235755. + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  235756. + HDMI_DMA_BUF_SIZE, &priv->hw_buffer);
  235757. + if (ret) {
  235758. + dev_err(card->dev, "failed to alloc hw dma buffer\n");
  235759. + return ret;
  235760. + }
  235761. +
  235762. + return ret;
  235763. +}
  235764. +
  235765. +static void imx_hdmi_dma_pcm_free(struct snd_pcm *pcm)
  235766. +{
  235767. + int stream = SNDRV_PCM_STREAM_PLAYBACK;
  235768. + struct snd_pcm_substream *substream = pcm->streams[stream].substream;
  235769. + struct snd_soc_pcm_runtime *rtd = pcm->private_data;
  235770. + struct hdmi_dma_priv *priv = dev_get_drvdata(rtd->platform->dev);
  235771. +
  235772. + if (substream) {
  235773. + snd_dma_free_pages(&substream->dma_buffer);
  235774. + substream->dma_buffer.area = NULL;
  235775. + substream->dma_buffer.addr = 0;
  235776. + }
  235777. +
  235778. + /* Free the hw_buffer */
  235779. + snd_dma_free_pages(&priv->hw_buffer);
  235780. + priv->hw_buffer.area = NULL;
  235781. + priv->hw_buffer.addr = 0;
  235782. +}
  235783. +
  235784. +static struct snd_soc_platform_driver imx_hdmi_platform = {
  235785. + .ops = &imx_hdmi_dma_pcm_ops,
  235786. + .pcm_new = imx_hdmi_dma_pcm_new,
  235787. + .pcm_free = imx_hdmi_dma_pcm_free,
  235788. +};
  235789. +
  235790. +static int imx_soc_platform_probe(struct platform_device *pdev)
  235791. +{
  235792. + struct imx_hdmi *hdmi_drvdata = platform_get_drvdata(pdev);
  235793. + struct hdmi_dma_priv *priv;
  235794. + int ret = 0;
  235795. +
  235796. + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  235797. + if (!priv) {
  235798. + dev_err(&pdev->dev, "Failed to alloc hdmi_dma\n");
  235799. + return -ENOMEM;
  235800. + }
  235801. +
  235802. + priv->hdmi_sdma_t = dma_alloc_coherent(NULL,
  235803. + sizeof(struct hdmi_sdma_script),
  235804. + &priv->phy_hdmi_sdma_t, GFP_KERNEL);
  235805. + if (!priv->hdmi_sdma_t) {
  235806. + dev_err(&pdev->dev, "Failed to alloc hdmi_sdma_t\n");
  235807. + return -ENOMEM;
  235808. + }
  235809. +
  235810. + priv->tx_active = false;
  235811. + spin_lock_init(&priv->irq_lock);
  235812. +
  235813. + priv->pdev = hdmi_drvdata->pdev;
  235814. +
  235815. + hdmi_dma_init_iec_header();
  235816. +
  235817. + dev_set_drvdata(&pdev->dev, priv);
  235818. +
  235819. + switch (hdmi_readb(HDMI_REVISION_ID)) {
  235820. + case 0x0a:
  235821. + snd_imx_hardware.period_bytes_max = HDMI_DMA_PERIOD_BYTES / 4;
  235822. + snd_imx_hardware.period_bytes_min = HDMI_DMA_PERIOD_BYTES / 4;
  235823. + snd_imx_hardware.periods_max = HDMI_DMA_BUF_SIZE / (HDMI_DMA_PERIOD_BYTES / 2);
  235824. + break;
  235825. + default:
  235826. + break;
  235827. + }
  235828. +
  235829. + ret = snd_soc_register_platform(&pdev->dev, &imx_hdmi_platform);
  235830. + if (ret)
  235831. + goto err_plat;
  235832. +
  235833. + return 0;
  235834. +
  235835. +err_plat:
  235836. + dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
  235837. + priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
  235838. +
  235839. + return ret;
  235840. +}
  235841. +
  235842. +static int imx_soc_platform_remove(struct platform_device *pdev)
  235843. +{
  235844. + struct hdmi_dma_priv *priv = dev_get_drvdata(&pdev->dev);
  235845. +
  235846. + dma_free_coherent(NULL, sizeof(struct hdmi_sdma_script),
  235847. + priv->hdmi_sdma_t, priv->phy_hdmi_sdma_t);
  235848. +
  235849. + snd_soc_unregister_platform(&pdev->dev);
  235850. +
  235851. + return 0;
  235852. +}
  235853. +
  235854. +static struct platform_driver imx_hdmi_dma_driver = {
  235855. + .driver = {
  235856. + .name = "imx-hdmi-audio",
  235857. + .owner = THIS_MODULE,
  235858. + },
  235859. + .probe = imx_soc_platform_probe,
  235860. + .remove = imx_soc_platform_remove,
  235861. +};
  235862. +
  235863. +module_platform_driver(imx_hdmi_dma_driver);
  235864. +
  235865. +MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  235866. +MODULE_DESCRIPTION("i.MX HDMI audio DMA");
  235867. +MODULE_LICENSE("GPL");
  235868. diff -Nur linux-3.14.17/sound/soc/fsl/imx-hdmi.h linux-imx6-3.14/sound/soc/fsl/imx-hdmi.h
  235869. --- linux-3.14.17/sound/soc/fsl/imx-hdmi.h 1970-01-01 01:00:00.000000000 +0100
  235870. +++ linux-imx6-3.14/sound/soc/fsl/imx-hdmi.h 2014-09-11 18:06:18.714104678 +0200
  235871. @@ -0,0 +1,105 @@
  235872. +/*
  235873. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  235874. + *
  235875. + * This program is free software; you can redistribute it and/or modify
  235876. + * it under the terms of the GNU General Public License as published by
  235877. + * the Free Software Foundation; either version 2 of the License, or
  235878. + * (at your option) any later version.
  235879. + *
  235880. + * This program is distributed in the hope that it will be useful,
  235881. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  235882. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  235883. + * GNU General Public License for more details.
  235884. + *
  235885. + * You should have received a copy of the GNU General Public License along
  235886. + * with this program; if not, write to the Free Software Foundation, Inc.,
  235887. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  235888. + */
  235889. +
  235890. +#ifndef __IMX_HDMI_H
  235891. +#define __IMX_HDMI_H
  235892. +
  235893. +struct imx_hdmi_sdma_params {
  235894. + dma_addr_t phyaddr;
  235895. + u32 buffer_num;
  235896. + int dma;
  235897. +};
  235898. +
  235899. +struct imx_hdmi {
  235900. + struct snd_soc_dai_driver cpu_dai_drv;
  235901. + struct platform_device *codec_dev;
  235902. + struct platform_device *dma_dev;
  235903. + struct platform_device *pdev;
  235904. + struct clk *isfr_clk;
  235905. + struct clk *iahb_clk;
  235906. +};
  235907. +
  235908. +#define HDMI_MAX_RATES 7
  235909. +#define HDMI_MAX_SAMPLE_SIZE 3
  235910. +#define HDMI_MAX_CHANNEL_CONSTRAINTS 4
  235911. +
  235912. +#define MXC_HDMI_RATES_PLAYBACK \
  235913. + (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
  235914. + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
  235915. + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
  235916. +
  235917. +#define MXC_HDMI_FORMATS_PLAYBACK \
  235918. + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
  235919. +
  235920. +union hdmi_audio_header_t {
  235921. + uint64_t U;
  235922. + struct {
  235923. + unsigned consumer:1;
  235924. + unsigned linear_pcm:1;
  235925. + unsigned copyright:1;
  235926. + unsigned pre_emphasis:3;
  235927. + unsigned mode:2;
  235928. +
  235929. + unsigned category_code:8;
  235930. +
  235931. + unsigned source:4;
  235932. + unsigned channel:4;
  235933. +
  235934. + unsigned sample_freq:4;
  235935. + unsigned clock_acc:2;
  235936. + unsigned reserved0:2;
  235937. +
  235938. + unsigned word_length:4;
  235939. + unsigned org_sample_freq:4;
  235940. +
  235941. + unsigned cgms_a:2;
  235942. + unsigned reserved1:6;
  235943. +
  235944. + unsigned reserved2:8;
  235945. +
  235946. + unsigned reserved3:8;
  235947. + } B;
  235948. + unsigned char status[8];
  235949. +};
  235950. +
  235951. +union hdmi_audio_dma_data_t {
  235952. + uint32_t U;
  235953. + struct {
  235954. + unsigned data:24;
  235955. + unsigned v:1;
  235956. + unsigned u:1;
  235957. + unsigned c:1;
  235958. + unsigned p:1;
  235959. + unsigned b:1;
  235960. + unsigned reserved:3;
  235961. + } B;
  235962. +};
  235963. +
  235964. +extern union hdmi_audio_header_t iec_header;
  235965. +
  235966. +#define hdmi_audio_writeb(reg, bit, val) \
  235967. + do { \
  235968. + hdmi_mask_writeb(val, HDMI_ ## reg, \
  235969. + HDMI_ ## reg ## _ ## bit ## _OFFSET, \
  235970. + HDMI_ ## reg ## _ ## bit ## _MASK); \
  235971. + pr_debug("Set reg: HDMI_" #reg " (0x%x) "\
  235972. + "bit: HDMI_" #reg "_" #bit " (%d) to val: %x\n", \
  235973. + HDMI_ ## reg, HDMI_ ## reg ## _ ## bit ## _OFFSET, val); \
  235974. + } while (0)
  235975. +
  235976. +#endif /* __IMX_HDMI_H */
  235977. diff -Nur linux-3.14.17/sound/soc/fsl/imx-pcm-dma.c linux-imx6-3.14/sound/soc/fsl/imx-pcm-dma.c
  235978. --- linux-3.14.17/sound/soc/fsl/imx-pcm-dma.c 2014-08-14 03:38:34.000000000 +0200
  235979. +++ linux-imx6-3.14/sound/soc/fsl/imx-pcm-dma.c 2014-09-11 18:06:18.714104678 +0200
  235980. @@ -11,6 +11,10 @@
  235981. * Free Software Foundation; either version 2 of the License, or (at your
  235982. * option) any later version.
  235983. */
  235984. +#include <linux/init.h>
  235985. +#include <linux/kernel.h>
  235986. +#include <linux/module.h>
  235987. +#include <linux/device.h>
  235988. #include <linux/platform_device.h>
  235989. #include <linux/dmaengine.h>
  235990. #include <linux/types.h>
  235991. @@ -20,6 +24,7 @@
  235992. #include <sound/pcm.h>
  235993. #include <sound/soc.h>
  235994. #include <sound/dmaengine_pcm.h>
  235995. +#include <linux/platform_data/dma-imx.h>
  235996. #include "imx-pcm.h"
  235997. @@ -40,28 +45,97 @@
  235998. SNDRV_PCM_INFO_MMAP_VALID |
  235999. SNDRV_PCM_INFO_PAUSE |
  236000. SNDRV_PCM_INFO_RESUME,
  236001. - .formats = SNDRV_PCM_FMTBIT_S16_LE,
  236002. - .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
  236003. + .formats = SNDRV_PCM_FMTBIT_S16_LE |
  236004. + SNDRV_PCM_FMTBIT_S24_LE |
  236005. + SNDRV_PCM_FMTBIT_S20_3LE,
  236006. + .buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
  236007. .period_bytes_min = 128,
  236008. .period_bytes_max = 65535, /* Limited by SDMA engine */
  236009. - .periods_min = 2,
  236010. + .periods_min = 4,
  236011. .periods_max = 255,
  236012. .fifo_size = 0,
  236013. };
  236014. +static void imx_pcm_dma_set_config_from_dai_data(
  236015. + const struct snd_pcm_substream *substream,
  236016. + const struct snd_dmaengine_dai_dma_data *dma_data,
  236017. + struct dma_slave_config *slave_config)
  236018. +{
  236019. + struct imx_dma_data *filter_data = dma_data->filter_data;
  236020. +
  236021. + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  236022. + slave_config->dst_addr = dma_data->addr;
  236023. + slave_config->dst_maxburst = dma_data->maxburst;
  236024. + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
  236025. + slave_config->dst_addr_width = dma_data->addr_width;
  236026. + } else {
  236027. + slave_config->src_addr = dma_data->addr;
  236028. + slave_config->src_maxburst = dma_data->maxburst;
  236029. + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
  236030. + slave_config->src_addr_width = dma_data->addr_width;
  236031. + }
  236032. +
  236033. + slave_config->slave_id = dma_data->slave_id;
  236034. +
  236035. + /*
  236036. + * In dma binding mode, there is no filter_data, so dma_request need to be
  236037. + * set to zero.
  236038. + */
  236039. + if (filter_data) {
  236040. + slave_config->dma_request0 = filter_data->dma_request0;
  236041. + slave_config->dma_request1 = filter_data->dma_request1;
  236042. + } else {
  236043. + slave_config->dma_request0 = 0;
  236044. + slave_config->dma_request1 = 0;
  236045. + }
  236046. +}
  236047. +
  236048. +static int imx_pcm_dma_prepare_slave_config(struct snd_pcm_substream *substream,
  236049. + struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config)
  236050. +{
  236051. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  236052. + struct snd_dmaengine_dai_dma_data *dma_data;
  236053. + int ret;
  236054. +
  236055. + dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
  236056. +
  236057. + ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
  236058. + if (ret)
  236059. + return ret;
  236060. +
  236061. + imx_pcm_dma_set_config_from_dai_data(substream, dma_data,
  236062. + slave_config);
  236063. +
  236064. + return 0;
  236065. +}
  236066. +
  236067. static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
  236068. .pcm_hardware = &imx_pcm_hardware,
  236069. - .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
  236070. + .prepare_slave_config = imx_pcm_dma_prepare_slave_config,
  236071. .compat_filter_fn = filter,
  236072. - .prealloc_buffer_size = IMX_SSI_DMABUF_SIZE,
  236073. + .prealloc_buffer_size = IMX_DEFAULT_DMABUF_SIZE,
  236074. };
  236075. -int imx_pcm_dma_init(struct platform_device *pdev)
  236076. +int imx_pcm_dma_init(struct platform_device *pdev, unsigned int flags, size_t size)
  236077. {
  236078. - return devm_snd_dmaengine_pcm_register(&pdev->dev,
  236079. - &imx_dmaengine_pcm_config,
  236080. - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
  236081. - SND_DMAENGINE_PCM_FLAG_COMPAT);
  236082. + struct snd_dmaengine_pcm_config *config;
  236083. + struct snd_pcm_hardware *pcm_hardware;
  236084. +
  236085. + config = devm_kzalloc(&pdev->dev,
  236086. + sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL);
  236087. + *config = imx_dmaengine_pcm_config;
  236088. + if (size)
  236089. + config->prealloc_buffer_size = size;
  236090. +
  236091. + pcm_hardware = devm_kzalloc(&pdev->dev,
  236092. + sizeof(struct snd_pcm_hardware), GFP_KERNEL);
  236093. + *pcm_hardware = imx_pcm_hardware;
  236094. + if (size)
  236095. + pcm_hardware->buffer_bytes_max = size;
  236096. +
  236097. + config->pcm_hardware = pcm_hardware;
  236098. +
  236099. + return devm_snd_dmaengine_pcm_register(&pdev->dev, config, flags);
  236100. }
  236101. EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
  236102. diff -Nur linux-3.14.17/sound/soc/fsl/imx-pcm.h linux-imx6-3.14/sound/soc/fsl/imx-pcm.h
  236103. --- linux-3.14.17/sound/soc/fsl/imx-pcm.h 2014-08-14 03:38:34.000000000 +0200
  236104. +++ linux-imx6-3.14/sound/soc/fsl/imx-pcm.h 2014-09-11 18:06:18.714104678 +0200
  236105. @@ -18,13 +18,17 @@
  236106. /*
  236107. * Do not change this as the FIQ handler depends on this size
  236108. */
  236109. +#define IMX_DEFAULT_DMABUF_SIZE (256 * 1024)
  236110. #define IMX_SSI_DMABUF_SIZE (64 * 1024)
  236111. +#define IMX_SPDIF_DMABUF_SIZE (64 * 1024)
  236112. +#define IMX_ESAI_DMABUF_SIZE (256 * 1024)
  236113. +#define IMX_ASRC_DMABUF_SIZE (256 * 1024)
  236114. static inline void
  236115. imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
  236116. int dma, enum sdma_peripheral_type peripheral_type)
  236117. {
  236118. - dma_data->dma_request = dma;
  236119. + dma_data->dma_request0 = dma;
  236120. dma_data->priority = DMA_PRIO_HIGH;
  236121. dma_data->peripheral_type = peripheral_type;
  236122. }
  236123. @@ -39,9 +43,10 @@
  236124. };
  236125. #if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)
  236126. -int imx_pcm_dma_init(struct platform_device *pdev);
  236127. +int imx_pcm_dma_init(struct platform_device *pdev, unsigned int flags, size_t size);
  236128. #else
  236129. -static inline int imx_pcm_dma_init(struct platform_device *pdev)
  236130. +static inline int imx_pcm_dma_init(struct platform_device *pdev,
  236131. + unsigned int flags, size_t size)
  236132. {
  236133. return -ENODEV;
  236134. }
  236135. diff -Nur linux-3.14.17/sound/soc/fsl/imx-spdif.c linux-imx6-3.14/sound/soc/fsl/imx-spdif.c
  236136. --- linux-3.14.17/sound/soc/fsl/imx-spdif.c 2014-08-14 03:38:34.000000000 +0200
  236137. +++ linux-imx6-3.14/sound/soc/fsl/imx-spdif.c 2014-09-11 18:06:18.714104678 +0200
  236138. @@ -65,14 +65,15 @@
  236139. if (ret)
  236140. goto end;
  236141. + platform_set_drvdata(pdev, &data->card);
  236142. + snd_soc_card_set_drvdata(&data->card, data);
  236143. +
  236144. ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
  236145. if (ret) {
  236146. dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
  236147. goto end;
  236148. }
  236149. - platform_set_drvdata(pdev, data);
  236150. -
  236151. end:
  236152. if (spdif_np)
  236153. of_node_put(spdif_np);
  236154. @@ -90,6 +91,7 @@
  236155. .driver = {
  236156. .name = "imx-spdif",
  236157. .owner = THIS_MODULE,
  236158. + .pm = &snd_soc_pm_ops,
  236159. .of_match_table = imx_spdif_dt_ids,
  236160. },
  236161. .probe = imx_spdif_audio_probe,
  236162. diff -Nur linux-3.14.17/sound/soc/fsl/imx-ssi.c linux-imx6-3.14/sound/soc/fsl/imx-ssi.c
  236163. --- linux-3.14.17/sound/soc/fsl/imx-ssi.c 2014-08-14 03:38:34.000000000 +0200
  236164. +++ linux-imx6-3.14/sound/soc/fsl/imx-ssi.c 2014-09-11 18:06:18.714104678 +0200
  236165. @@ -602,7 +602,8 @@
  236166. ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx;
  236167. ssi->fiq_init = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
  236168. - ssi->dma_init = imx_pcm_dma_init(pdev);
  236169. + ssi->dma_init = imx_pcm_dma_init(pdev, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE,
  236170. + IMX_SSI_DMABUF_SIZE);
  236171. if (ssi->fiq_init && ssi->dma_init) {
  236172. ret = ssi->fiq_init;
  236173. diff -Nur linux-3.14.17/sound/soc/fsl/imx-wm8962.c linux-imx6-3.14/sound/soc/fsl/imx-wm8962.c
  236174. --- linux-3.14.17/sound/soc/fsl/imx-wm8962.c 2014-08-14 03:38:34.000000000 +0200
  236175. +++ linux-imx6-3.14/sound/soc/fsl/imx-wm8962.c 2014-09-11 18:06:18.718104695 +0200
  236176. @@ -1,9 +1,9 @@
  236177. /*
  236178. - * Copyright 2013 Freescale Semiconductor, Inc.
  236179. + * Copyright (C) 2013 Freescale Semiconductor, Inc.
  236180. *
  236181. * Based on imx-sgtl5000.c
  236182. - * Copyright 2012 Freescale Semiconductor, Inc.
  236183. - * Copyright 2012 Linaro Ltd.
  236184. + * Copyright (C) 2012 Freescale Semiconductor, Inc.
  236185. + * Copyright (C) 2012 Linaro Ltd.
  236186. *
  236187. * The code contained herein is licensed under the GNU General Public
  236188. * License. You may obtain a copy of the GNU General Public License
  236189. @@ -16,9 +16,12 @@
  236190. #include <linux/module.h>
  236191. #include <linux/of_platform.h>
  236192. #include <linux/i2c.h>
  236193. +#include <linux/of_gpio.h>
  236194. #include <linux/slab.h>
  236195. +#include <linux/gpio.h>
  236196. #include <linux/clk.h>
  236197. #include <sound/soc.h>
  236198. +#include <sound/jack.h>
  236199. #include <sound/pcm_params.h>
  236200. #include <sound/soc-dapm.h>
  236201. #include <linux/pinctrl/consumer.h>
  236202. @@ -33,15 +36,134 @@
  236203. struct snd_soc_card card;
  236204. char codec_dai_name[DAI_NAME_SIZE];
  236205. char platform_name[DAI_NAME_SIZE];
  236206. - struct clk *codec_clk;
  236207. unsigned int clk_frequency;
  236208. };
  236209. struct imx_priv {
  236210. + int hp_gpio;
  236211. + int hp_active_low;
  236212. + int mic_gpio;
  236213. + int mic_active_low;
  236214. + bool amic_mono;
  236215. + bool dmic_mono;
  236216. + struct snd_soc_codec *codec;
  236217. struct platform_device *pdev;
  236218. + struct snd_pcm_substream *first_stream;
  236219. + struct snd_pcm_substream *second_stream;
  236220. };
  236221. static struct imx_priv card_priv;
  236222. +static struct snd_soc_jack imx_hp_jack;
  236223. +static struct snd_soc_jack_pin imx_hp_jack_pins[] = {
  236224. + {
  236225. + .pin = "Headphone Jack",
  236226. + .mask = SND_JACK_HEADPHONE,
  236227. + },
  236228. +};
  236229. +static struct snd_soc_jack_gpio imx_hp_jack_gpio = {
  236230. + .name = "headphone detect",
  236231. + .report = SND_JACK_HEADPHONE,
  236232. + .debounce_time = 250,
  236233. + .invert = 0,
  236234. +};
  236235. +
  236236. +static struct snd_soc_jack imx_mic_jack;
  236237. +static struct snd_soc_jack_pin imx_mic_jack_pins[] = {
  236238. + {
  236239. + .pin = "AMIC",
  236240. + .mask = SND_JACK_MICROPHONE,
  236241. + },
  236242. +};
  236243. +static struct snd_soc_jack_gpio imx_mic_jack_gpio = {
  236244. + .name = "microphone detect",
  236245. + .report = SND_JACK_MICROPHONE,
  236246. + .debounce_time = 250,
  236247. + .invert = 0,
  236248. +};
  236249. +
  236250. +static int hpjack_status_check(void)
  236251. +{
  236252. + struct imx_priv *priv = &card_priv;
  236253. + struct platform_device *pdev = priv->pdev;
  236254. + char *envp[3], *buf;
  236255. + int hp_status, ret;
  236256. +
  236257. + if (!gpio_is_valid(priv->hp_gpio))
  236258. + return 0;
  236259. +
  236260. + hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
  236261. +
  236262. + buf = kmalloc(32, GFP_ATOMIC);
  236263. + if (!buf) {
  236264. + dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
  236265. + return -ENOMEM;
  236266. + }
  236267. +
  236268. + if (hp_status != priv->hp_active_low) {
  236269. + snprintf(buf, 32, "STATE=%d", 2);
  236270. + snd_soc_dapm_disable_pin(&priv->codec->dapm, "Ext Spk");
  236271. + ret = imx_hp_jack_gpio.report;
  236272. + } else {
  236273. + snprintf(buf, 32, "STATE=%d", 0);
  236274. + snd_soc_dapm_enable_pin(&priv->codec->dapm, "Ext Spk");
  236275. + ret = 0;
  236276. + }
  236277. +
  236278. + envp[0] = "NAME=headphone";
  236279. + envp[1] = buf;
  236280. + envp[2] = NULL;
  236281. + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
  236282. + kfree(buf);
  236283. +
  236284. + return ret;
  236285. +}
  236286. +
  236287. +static int micjack_status_check(void)
  236288. +{
  236289. + struct imx_priv *priv = &card_priv;
  236290. + struct platform_device *pdev = priv->pdev;
  236291. + char *envp[3], *buf;
  236292. + int mic_status, ret;
  236293. +
  236294. + if (!gpio_is_valid(priv->mic_gpio))
  236295. + return 0;
  236296. +
  236297. + mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
  236298. +
  236299. + if ((mic_status != priv->mic_active_low && priv->amic_mono)
  236300. + || (mic_status == priv->mic_active_low && priv->dmic_mono))
  236301. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  236302. + WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
  236303. + else
  236304. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  236305. + WM8962_ADC_MONOMIX_MASK, 0);
  236306. +
  236307. + buf = kmalloc(32, GFP_ATOMIC);
  236308. + if (!buf) {
  236309. + dev_err(&pdev->dev, "%s kmalloc failed\n", __func__);
  236310. + return -ENOMEM;
  236311. + }
  236312. +
  236313. + if (mic_status != priv->mic_active_low) {
  236314. + snprintf(buf, 32, "STATE=%d", 2);
  236315. + snd_soc_dapm_disable_pin(&priv->codec->dapm, "DMIC");
  236316. + ret = imx_mic_jack_gpio.report;
  236317. + } else {
  236318. + snprintf(buf, 32, "STATE=%d", 0);
  236319. + snd_soc_dapm_enable_pin(&priv->codec->dapm, "DMIC");
  236320. + ret = 0;
  236321. + }
  236322. +
  236323. + envp[0] = "NAME=microphone";
  236324. + envp[1] = buf;
  236325. + envp[2] = NULL;
  236326. + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
  236327. + kfree(buf);
  236328. +
  236329. + return ret;
  236330. +}
  236331. +
  236332. +
  236333. static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
  236334. SND_SOC_DAPM_HP("Headphone Jack", NULL),
  236335. SND_SOC_DAPM_SPK("Ext Spk", NULL),
  236336. @@ -49,14 +171,57 @@
  236337. SND_SOC_DAPM_MIC("DMIC", NULL),
  236338. };
  236339. -static int sample_rate = 44100;
  236340. -static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
  236341. -
  236342. static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
  236343. - struct snd_pcm_hw_params *params)
  236344. + struct snd_pcm_hw_params *params)
  236345. {
  236346. - sample_rate = params_rate(params);
  236347. - sample_format = params_format(params);
  236348. + struct snd_soc_pcm_runtime *rtd = substream->private_data;
  236349. + struct snd_soc_dai *codec_dai = rtd->codec_dai;
  236350. + struct imx_priv *priv = &card_priv;
  236351. + struct device *dev = &priv->pdev->dev;
  236352. + struct snd_soc_card *card = codec_dai->codec->card;
  236353. + struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
  236354. + unsigned int sample_rate = params_rate(params);
  236355. + snd_pcm_format_t sample_format = params_format(params);
  236356. + u32 dai_format, pll_out;
  236357. + int ret = 0;
  236358. +
  236359. + if (!priv->first_stream) {
  236360. + priv->first_stream = substream;
  236361. + } else {
  236362. + priv->second_stream = substream;
  236363. +
  236364. + /* We suppose the two substream are using same params */
  236365. + return 0;
  236366. + }
  236367. +
  236368. + dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  236369. + SND_SOC_DAIFMT_CBM_CFM;
  236370. +
  236371. + /* set codec DAI configuration */
  236372. + ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
  236373. + if (ret) {
  236374. + dev_err(dev, "failed to set codec dai fmt: %d\n", ret);
  236375. + return ret;
  236376. + }
  236377. +
  236378. + if (sample_format == SNDRV_PCM_FORMAT_S24_LE)
  236379. + pll_out = sample_rate * 384;
  236380. + else
  236381. + pll_out = sample_rate * 256;
  236382. +
  236383. + ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, WM8962_FLL_MCLK,
  236384. + data->clk_frequency, pll_out);
  236385. + if (ret) {
  236386. + dev_err(dev, "failed to start FLL: %d\n", ret);
  236387. + return ret;
  236388. + }
  236389. +
  236390. + ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_FLL,
  236391. + pll_out, SND_SOC_CLOCK_IN);
  236392. + if (ret) {
  236393. + dev_err(dev, "failed to set SYSCLK: %d\n", ret);
  236394. + return ret;
  236395. + }
  236396. return 0;
  236397. }
  236398. @@ -133,6 +298,89 @@
  236399. return 0;
  236400. }
  236401. +static int imx_wm8962_gpio_init(struct snd_soc_pcm_runtime *rtd)
  236402. +{
  236403. + struct snd_soc_codec *codec = rtd->codec;
  236404. + struct imx_priv *priv = &card_priv;
  236405. +
  236406. + priv->codec = codec;
  236407. +
  236408. + if (gpio_is_valid(priv->hp_gpio)) {
  236409. + imx_hp_jack_gpio.gpio = priv->hp_gpio;
  236410. + imx_hp_jack_gpio.jack_status_check = hpjack_status_check;
  236411. +
  236412. + snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &imx_hp_jack);
  236413. + snd_soc_jack_add_pins(&imx_hp_jack,
  236414. + ARRAY_SIZE(imx_hp_jack_pins), imx_hp_jack_pins);
  236415. + snd_soc_jack_add_gpios(&imx_hp_jack, 1, &imx_hp_jack_gpio);
  236416. + }
  236417. +
  236418. + if (gpio_is_valid(priv->mic_gpio)) {
  236419. + imx_mic_jack_gpio.gpio = priv->mic_gpio;
  236420. + imx_mic_jack_gpio.jack_status_check = micjack_status_check;
  236421. +
  236422. + snd_soc_jack_new(codec, "AMIC", SND_JACK_MICROPHONE, &imx_mic_jack);
  236423. + snd_soc_jack_add_pins(&imx_mic_jack,
  236424. + ARRAY_SIZE(imx_mic_jack_pins), imx_mic_jack_pins);
  236425. + snd_soc_jack_add_gpios(&imx_mic_jack, 1, &imx_mic_jack_gpio);
  236426. + } else if (priv->amic_mono || priv->dmic_mono) {
  236427. + /*
  236428. + * Permanent set monomix bit if only one microphone
  236429. + * is present on the board while it needs monomix.
  236430. + */
  236431. + snd_soc_update_bits(priv->codec, WM8962_THREED1,
  236432. + WM8962_ADC_MONOMIX_MASK, WM8962_ADC_MONOMIX);
  236433. + }
  236434. +
  236435. + return 0;
  236436. +}
  236437. +
  236438. +static ssize_t show_headphone(struct device_driver *dev, char *buf)
  236439. +{
  236440. + struct imx_priv *priv = &card_priv;
  236441. + int hp_status;
  236442. +
  236443. + if (!gpio_is_valid(priv->hp_gpio)) {
  236444. + strcpy(buf, "no detect gpio connected\n");
  236445. + return strlen(buf);
  236446. + }
  236447. +
  236448. + /* Check if headphone is plugged in */
  236449. + hp_status = gpio_get_value(priv->hp_gpio) ? 1 : 0;
  236450. +
  236451. + if (hp_status != priv->hp_active_low)
  236452. + strcpy(buf, "headphone\n");
  236453. + else
  236454. + strcpy(buf, "speaker\n");
  236455. +
  236456. + return strlen(buf);
  236457. +}
  236458. +
  236459. +static DRIVER_ATTR(headphone, S_IRUGO | S_IWUSR, show_headphone, NULL);
  236460. +
  236461. +static ssize_t show_mic(struct device_driver *dev, char *buf)
  236462. +{
  236463. + struct imx_priv *priv = &card_priv;
  236464. + int mic_status;
  236465. +
  236466. + if (!gpio_is_valid(priv->mic_gpio)) {
  236467. + strcpy(buf, "no detect gpio connected\n");
  236468. + return strlen(buf);
  236469. + }
  236470. +
  236471. + /* Check if analog microphone is plugged in */
  236472. + mic_status = gpio_get_value(priv->mic_gpio) ? 1 : 0;
  236473. +
  236474. + if (mic_status != priv->mic_active_low)
  236475. + strcpy(buf, "amic\n");
  236476. + else
  236477. + strcpy(buf, "dmic\n");
  236478. +
  236479. + return strlen(buf);
  236480. +}
  236481. +
  236482. +static DRIVER_ATTR(microphone, S_IRUGO | S_IWUSR, show_mic, NULL);
  236483. +
  236484. static int imx_wm8962_late_probe(struct snd_soc_card *card)
  236485. {
  236486. struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
  236487. @@ -157,6 +405,7 @@
  236488. struct imx_priv *priv = &card_priv;
  236489. struct i2c_client *codec_dev;
  236490. struct imx_wm8962_data *data;
  236491. + struct clk *codec_clk = NULL;
  236492. int int_port, ext_port;
  236493. int ret;
  236494. @@ -219,25 +468,31 @@
  236495. goto fail;
  236496. }
  236497. + priv->first_stream = NULL;
  236498. + priv->second_stream = NULL;
  236499. +
  236500. data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  236501. if (!data) {
  236502. ret = -ENOMEM;
  236503. goto fail;
  236504. }
  236505. - data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  236506. - if (IS_ERR(data->codec_clk)) {
  236507. - ret = PTR_ERR(data->codec_clk);
  236508. + codec_clk = devm_clk_get(&codec_dev->dev, NULL);
  236509. + if (IS_ERR(codec_clk)) {
  236510. + ret = PTR_ERR(codec_clk);
  236511. dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
  236512. goto fail;
  236513. }
  236514. - data->clk_frequency = clk_get_rate(data->codec_clk);
  236515. - ret = clk_prepare_enable(data->codec_clk);
  236516. - if (ret) {
  236517. - dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
  236518. - goto fail;
  236519. - }
  236520. + data->clk_frequency = clk_get_rate(codec_clk);
  236521. +
  236522. + priv->amic_mono = of_property_read_bool(codec_np, "amic-mono");
  236523. + priv->dmic_mono = of_property_read_bool(codec_np, "dmic-mono");
  236524. +
  236525. + priv->hp_gpio = of_get_named_gpio_flags(np, "hp-det-gpios", 0,
  236526. + (enum of_gpio_flags *)&priv->hp_active_low);
  236527. + priv->mic_gpio = of_get_named_gpio_flags(np, "mic-det-gpios", 0,
  236528. + (enum of_gpio_flags *)&priv->mic_active_low);
  236529. data->dai.name = "HiFi";
  236530. data->dai.stream_name = "HiFi";
  236531. @@ -246,23 +501,23 @@
  236532. data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
  236533. data->dai.platform_of_node = ssi_np;
  236534. data->dai.ops = &imx_hifi_ops;
  236535. + data->dai.init = &imx_wm8962_gpio_init;
  236536. data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
  236537. SND_SOC_DAIFMT_CBM_CFM;
  236538. data->card.dev = &pdev->dev;
  236539. ret = snd_soc_of_parse_card_name(&data->card, "model");
  236540. if (ret)
  236541. - goto clk_fail;
  236542. + goto fail;
  236543. ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
  236544. if (ret)
  236545. - goto clk_fail;
  236546. + goto fail;
  236547. data->card.num_links = 1;
  236548. data->card.dai_link = &data->dai;
  236549. data->card.dapm_widgets = imx_wm8962_dapm_widgets;
  236550. data->card.num_dapm_widgets = ARRAY_SIZE(imx_wm8962_dapm_widgets);
  236551. data->card.late_probe = imx_wm8962_late_probe;
  236552. - data->card.set_bias_level = imx_wm8962_set_bias_level;
  236553. platform_set_drvdata(pdev, &data->card);
  236554. snd_soc_card_set_drvdata(&data->card, data);
  236555. @@ -270,16 +525,31 @@
  236556. ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
  236557. if (ret) {
  236558. dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
  236559. - goto clk_fail;
  236560. + goto fail;
  236561. }
  236562. - of_node_put(ssi_np);
  236563. - of_node_put(codec_np);
  236564. + if (gpio_is_valid(priv->hp_gpio)) {
  236565. + ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone);
  236566. + if (ret) {
  236567. + dev_err(&pdev->dev, "create hp attr failed (%d)\n", ret);
  236568. + goto fail_hp;
  236569. + }
  236570. + }
  236571. - return 0;
  236572. + if (gpio_is_valid(priv->mic_gpio)) {
  236573. + ret = driver_create_file(pdev->dev.driver, &driver_attr_microphone);
  236574. + if (ret) {
  236575. + dev_err(&pdev->dev, "create mic attr failed (%d)\n", ret);
  236576. + goto fail_mic;
  236577. + }
  236578. + }
  236579. +
  236580. + goto fail;
  236581. -clk_fail:
  236582. - clk_disable_unprepare(data->codec_clk);
  236583. +fail_mic:
  236584. + driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
  236585. +fail_hp:
  236586. + snd_soc_unregister_card(&data->card);
  236587. fail:
  236588. if (ssi_np)
  236589. of_node_put(ssi_np);
  236590. @@ -291,11 +561,8 @@
  236591. static int imx_wm8962_remove(struct platform_device *pdev)
  236592. {
  236593. - struct snd_soc_card *card = platform_get_drvdata(pdev);
  236594. - struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
  236595. -
  236596. - if (!IS_ERR(data->codec_clk))
  236597. - clk_disable_unprepare(data->codec_clk);
  236598. + driver_remove_file(pdev->dev.driver, &driver_attr_microphone);
  236599. + driver_remove_file(pdev->dev.driver, &driver_attr_headphone);
  236600. return 0;
  236601. }
  236602. diff -Nur linux-3.14.17/sound/soc/fsl/Kconfig linux-imx6-3.14/sound/soc/fsl/Kconfig
  236603. --- linux-3.14.17/sound/soc/fsl/Kconfig 2014-08-14 03:38:34.000000000 +0200
  236604. +++ linux-imx6-3.14/sound/soc/fsl/Kconfig 2014-09-11 18:37:37.616046899 +0200
  236605. @@ -11,6 +11,12 @@
  236606. config SND_SOC_FSL_ESAI
  236607. tristate
  236608. +config SND_SOC_FSL_ASRC
  236609. + tristate
  236610. +
  236611. +config SND_SOC_FSL_HDMI
  236612. + tristate
  236613. +
  236614. config SND_SOC_FSL_UTILS
  236615. tristate
  236616. @@ -126,6 +132,11 @@
  236617. tristate
  236618. select SND_SOC_GENERIC_DMAENGINE_PCM
  236619. +config SND_SOC_IMX_HDMI_DMA
  236620. + tristate
  236621. + select SND_SOC_GENERIC_DMAENGINE_PCM
  236622. + select SND_SOC_IMX_PCM_DMA
  236623. +
  236624. config SND_SOC_IMX_AUDMUX
  236625. tristate
  236626. @@ -178,6 +189,18 @@
  236627. Enable I2S based access to the TLV320AIC23B codec attached
  236628. to the SSI interface
  236629. +config SND_SOC_IMX_CS42888
  236630. + tristate "SoC Audio support for i.MX boards with cs42888"
  236631. + depends on OF && I2C
  236632. + select SND_SOC_CS42888
  236633. + select SND_SOC_IMX_PCM_DMA
  236634. + select SND_SOC_FSL_ESAI
  236635. + select SND_SOC_FSL_UTILS
  236636. + help
  236637. + SoC Audio support for i.MX boards with cs42888
  236638. + Say Y if you want to add support for SoC audio on an i.MX board with
  236639. + a cs42888 codec.
  236640. +
  236641. config SND_SOC_IMX_WM8962
  236642. tristate "SoC Audio support for i.MX boards with wm8962"
  236643. depends on OF && I2C
  236644. @@ -210,6 +233,17 @@
  236645. Say Y if you want to add support for SoC audio on an i.MX board with
  236646. a S/DPDIF.
  236647. +config SND_SOC_IMX_HDMI
  236648. + tristate "SoC Audio support for i.MX boards with HDMI port"
  236649. + depends on MFD_MXC_HDMI
  236650. + select SND_SOC_IMX_HDMI_DMA
  236651. + select SND_SOC_FSL_HDMI
  236652. + select SND_SOC_HDMI_CODEC
  236653. + help
  236654. + SoC Audio support for i.MX boards with HDMI audio
  236655. + Say Y if you want to add support for SoC audio on an i.MX board with
  236656. + IMX HDMI.
  236657. +
  236658. config SND_SOC_IMX_MC13783
  236659. tristate "SoC Audio support for I.MX boards with mc13783"
  236660. depends on MFD_MC13XXX && ARM
  236661. diff -Nur linux-3.14.17/sound/soc/fsl/Makefile linux-imx6-3.14/sound/soc/fsl/Makefile
  236662. --- linux-3.14.17/sound/soc/fsl/Makefile 2014-08-14 03:38:34.000000000 +0200
  236663. +++ linux-imx6-3.14/sound/soc/fsl/Makefile 2014-09-11 18:06:18.690104584 +0200
  236664. @@ -14,13 +14,19 @@
  236665. snd-soc-fsl-sai-objs := fsl_sai.o
  236666. snd-soc-fsl-ssi-objs := fsl_ssi.o
  236667. snd-soc-fsl-spdif-objs := fsl_spdif.o
  236668. +snd-soc-fsl-hdmi-objs := fsl_hdmi.o
  236669. snd-soc-fsl-esai-objs := fsl_esai.o
  236670. +snd-soc-fsl-asrc-pcm-objs := fsl_asrc_pcm.o
  236671. +snd-soc-fsl-asrc-objs := fsl_asrc.o
  236672. snd-soc-fsl-utils-objs := fsl_utils.o
  236673. snd-soc-fsl-dma-objs := fsl_dma.o
  236674. obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
  236675. obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
  236676. obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
  236677. +obj-$(CONFIG_SND_SOC_FSL_HDMI) += snd-soc-fsl-hdmi.o
  236678. obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
  236679. +obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc-pcm.o
  236680. +obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
  236681. obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
  236682. obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
  236683. @@ -41,22 +47,27 @@
  236684. obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
  236685. obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
  236686. +obj-$(CONFIG_SND_SOC_IMX_HDMI_DMA) += imx-hdmi-dma.o
  236687. # i.MX Machine Support
  236688. snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
  236689. snd-soc-phycore-ac97-objs := phycore-ac97.o
  236690. snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
  236691. snd-soc-wm1133-ev1-objs := wm1133-ev1.o
  236692. +snd-soc-imx-cs42888-objs := imx-cs42888.o
  236693. snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
  236694. snd-soc-imx-wm8962-objs := imx-wm8962.o
  236695. snd-soc-imx-spdif-objs := imx-spdif.o
  236696. +snd-soc-imx-hdmi-objs := imx-hdmi.o
  236697. snd-soc-imx-mc13783-objs := imx-mc13783.o
  236698. obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
  236699. obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
  236700. obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
  236701. obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
  236702. +obj-$(CONFIG_SND_SOC_IMX_CS42888) += snd-soc-imx-cs42888.o
  236703. obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
  236704. obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
  236705. obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
  236706. +obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
  236707. obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
  236708. diff -Nur linux-3.14.17/sound/soc/soc-pcm.c linux-imx6-3.14/sound/soc/soc-pcm.c
  236709. --- linux-3.14.17/sound/soc/soc-pcm.c 2014-08-14 03:38:34.000000000 +0200
  236710. +++ linux-imx6-3.14/sound/soc/soc-pcm.c 2014-09-11 18:06:18.754104839 +0200
  236711. @@ -945,7 +945,7 @@
  236712. }
  236713. }
  236714. - dev_err(card->dev, "ASoC: can't get %s BE for %s\n",
  236715. + dev_dbg(card->dev, "ASoC: can't get %s BE for %s\n",
  236716. stream ? "capture" : "playback", widget->name);
  236717. return NULL;
  236718. }
  236719. @@ -1062,7 +1062,7 @@
  236720. /* is there a valid BE rtd for this widget */
  236721. be = dpcm_get_be(card, list->widgets[i], stream);
  236722. if (!be) {
  236723. - dev_err(fe->dev, "ASoC: no BE found for %s\n",
  236724. + dev_dbg(fe->dev, "ASoC: no BE found for %s\n",
  236725. list->widgets[i]->name);
  236726. continue;
  236727. }